Router.
This commit is contained in:
parent
9eb1d0de16
commit
b24fdfc57c
@ -1,11 +1,14 @@
|
|||||||
{
|
{
|
||||||
"publicUrl": "/app",
|
|
||||||
"port": 4000,
|
|
||||||
"path": "/api",
|
|
||||||
"app": {
|
"app": {
|
||||||
"org": "DxOS",
|
"org": "DxOS",
|
||||||
"theme": "dark",
|
"theme": "dark",
|
||||||
"title": "Console",
|
"title": "Console",
|
||||||
"website": "https://dxos.org"
|
"website": "https://dxos.org",
|
||||||
|
"publicUrl": "/console"
|
||||||
|
},
|
||||||
|
"graphql": {
|
||||||
|
"path": "/api",
|
||||||
|
"port": 4000,
|
||||||
|
"pollInterval": 10000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
"analyzer": "webpack --config webpack-analyzer.config.js",
|
"analyzer": "webpack --config webpack-analyzer.config.js",
|
||||||
"build": "npm run clean && npm run build:module && npm run build:production",
|
"build": "npm run clean && npm run build:module && npm run build:production",
|
||||||
"build:module": "babel ./src --out-dir ./dist/es --ignore \"**/*.test.js\" --source-maps inline",
|
"build:module": "babel ./src --out-dir ./dist/es --ignore \"**/*.test.js\" --source-maps inline",
|
||||||
"build:production": "PUBLIC_URL=/app webpack --mode production",
|
"build:production": "PUBLIC_URL=/console webpack --mode production",
|
||||||
"clean": "rm -rf dist",
|
"clean": "rm -rf dist",
|
||||||
"lint": "semistandard 'src/**/*.js'",
|
"lint": "semistandard 'src/**/*.js'",
|
||||||
"start": "VERBOSE=true webpack-dev-server --mode development",
|
"start": "VERBOSE=true webpack-dev-server --mode development",
|
||||||
|
@ -8,16 +8,20 @@ import { InMemoryCache } from 'apollo-cache-inmemory';
|
|||||||
|
|
||||||
const defaultServer = `${window.location.protocol}//${window.location.hostname}`;
|
const defaultServer = `${window.location.protocol}//${window.location.hostname}`;
|
||||||
|
|
||||||
|
export const graphqlApi = config => {
|
||||||
|
const { graphql: { server = defaultServer, port = 80, path = '/graphql' } } = config;
|
||||||
|
|
||||||
|
return `${server}:${port}${path}`;
|
||||||
|
};
|
||||||
|
|
||||||
// https://www.apollographql.com/docs/react/api/apollo-client/
|
// https://www.apollographql.com/docs/react/api/apollo-client/
|
||||||
export const clientFactory = config => {
|
export const clientFactory = config => {
|
||||||
const { server = defaultServer, port = 80, path = '/graphql' } = config;
|
|
||||||
|
|
||||||
// TODO(burdon): Authentication: send signed message to server (from client wallet).
|
// TODO(burdon): Authentication: send signed message to server (from client wallet).
|
||||||
// https://www.apollographql.com/docs/react/networking/authentication/
|
// https://www.apollographql.com/docs/react/networking/authentication/
|
||||||
|
|
||||||
// https://www.apollographql.com/docs/link/
|
// https://www.apollographql.com/docs/link/
|
||||||
const link = createHttpLink({
|
const link = createHttpLink({
|
||||||
uri: `${server}:${port}${path}`
|
uri: graphqlApi(config)
|
||||||
});
|
});
|
||||||
|
|
||||||
return new ApolloClient({
|
return new ApolloClient({
|
||||||
|
@ -5,13 +5,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { makeStyles } from '@material-ui/core';
|
import { makeStyles } from '@material-ui/core';
|
||||||
import MuiAppBar from '@material-ui/core/AppBar';
|
import MuiAppBar from '@material-ui/core/AppBar';
|
||||||
import MuiLink from '@material-ui/core/Link';
|
import Link from '@material-ui/core/Link';
|
||||||
import Toolbar from '@material-ui/core/Toolbar';
|
import Toolbar from '@material-ui/core/Toolbar';
|
||||||
import Typography from '@material-ui/core/Typography';
|
import Typography from '@material-ui/core/Typography';
|
||||||
import blueGrey from '@material-ui/core/colors/blueGrey';
|
import blueGrey from '@material-ui/core/colors/blueGrey';
|
||||||
import PublicIcon from '@material-ui/icons/Public';
|
import GraphQLIcon from '@material-ui/icons/Adb';
|
||||||
|
|
||||||
import DxOSIcon from '../icons/DXOS';
|
import DxOSIcon from '../icons/DXOS';
|
||||||
|
import { graphqlApi } from '../client';
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
offset: theme.mixins.denseToolbar,
|
offset: theme.mixins.denseToolbar,
|
||||||
@ -45,18 +46,24 @@ const AppBar = ({ config }) => {
|
|||||||
<>
|
<>
|
||||||
<MuiAppBar position="fixed">
|
<MuiAppBar position="fixed">
|
||||||
<Toolbar variant="dense">
|
<Toolbar variant="dense">
|
||||||
<MuiLink href="/">
|
<Link href="/">
|
||||||
<div className={classes.logo}>
|
<div className={classes.logo}>
|
||||||
<DxOSIcon />
|
<DxOSIcon />
|
||||||
</div>
|
</div>
|
||||||
</MuiLink>
|
</Link>
|
||||||
<div className={classes.title}>
|
<div className={classes.title}>
|
||||||
<Typography variant="h6">{config.app.title}</Typography>
|
<Typography variant="h6">{config.app.title}</Typography>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<MuiLink href={config.app.website} className={classes.link} rel="noreferrer" target="_blank">
|
<Link
|
||||||
<PublicIcon />
|
className={classes.link}
|
||||||
</MuiLink>
|
href={graphqlApi(config)}
|
||||||
|
rel="noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
title="Console GraphQL"
|
||||||
|
>
|
||||||
|
<GraphQLIcon />
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
</MuiAppBar>
|
</MuiAppBar>
|
||||||
|
@ -5,12 +5,12 @@
|
|||||||
import isObject from 'lodash.isobject';
|
import isObject from 'lodash.isobject';
|
||||||
import omit from 'lodash.omit';
|
import omit from 'lodash.omit';
|
||||||
import transform from 'lodash.transform';
|
import transform from 'lodash.transform';
|
||||||
import React from 'react';
|
import React, { useContext } from 'react';
|
||||||
import { useQuery } from '@apollo/react-hooks';
|
import { useQuery } from '@apollo/react-hooks';
|
||||||
|
|
||||||
import Json from '../components/Json';
|
import Json from '../components/Json';
|
||||||
|
|
||||||
import { useQueryStatusReducer } from '../hooks';
|
import { ConsoleContext, useQueryStatusReducer } from '../hooks';
|
||||||
|
|
||||||
import QUERY_STATUS from '../../gql/status.graphql';
|
import QUERY_STATUS from '../../gql/status.graphql';
|
||||||
|
|
||||||
@ -19,7 +19,9 @@ const removeTypename = data => transform(data, (result, value, key) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const Status = () => {
|
const Status = () => {
|
||||||
const data = useQueryStatusReducer(useQuery(QUERY_STATUS, { pollInterval: 5000 }));
|
const { config } = useContext(ConsoleContext);
|
||||||
|
|
||||||
|
const data = useQueryStatusReducer(useQuery(QUERY_STATUS, { pollInterval: config.graphql.pollInterval }));
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,12 @@
|
|||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { useContext, useEffect, useState } from 'react';
|
import React, { useContext, useEffect, useState } from 'react';
|
||||||
import { makeStyles } from '@material-ui/core';
|
import { makeStyles } from '@material-ui/core';
|
||||||
|
import Link from '@material-ui/core/Link';
|
||||||
|
import Toolbar from '@material-ui/core/Toolbar';
|
||||||
import ErrorIcon from '@material-ui/icons/Error';
|
import ErrorIcon from '@material-ui/icons/Error';
|
||||||
import LoadingIcon from '@material-ui/icons/Wifi';
|
import LoadingIcon from '@material-ui/icons/Wifi';
|
||||||
import RunningIcon from '@material-ui/icons/CheckCircle';
|
import RunningIcon from '@material-ui/icons/CheckCircle';
|
||||||
|
import PublicIcon from '@material-ui/icons/Public';
|
||||||
import grey from '@material-ui/core/colors/grey';
|
import grey from '@material-ui/core/colors/grey';
|
||||||
import green from '@material-ui/core/colors/green';
|
import green from '@material-ui/core/colors/green';
|
||||||
import red from '@material-ui/core/colors/red';
|
import red from '@material-ui/core/colors/red';
|
||||||
@ -22,9 +25,7 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'space-around',
|
justifyContent: 'space-around',
|
||||||
backgroundColor: grey[900],
|
backgroundColor: grey[900],
|
||||||
color: '#EEE',
|
color: grey[400]
|
||||||
height: 32,
|
|
||||||
padding: 4
|
|
||||||
},
|
},
|
||||||
left: {
|
left: {
|
||||||
width: 160
|
width: 160
|
||||||
@ -40,6 +41,9 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
icon: {
|
icon: {
|
||||||
margin: '0 2px'
|
margin: '0 2px'
|
||||||
},
|
},
|
||||||
|
link: {
|
||||||
|
color: grey[400]
|
||||||
|
},
|
||||||
error: {
|
error: {
|
||||||
color: red[500]
|
color: red[500]
|
||||||
},
|
},
|
||||||
@ -82,14 +86,18 @@ const StatusBar = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.root}>
|
<Toolbar variant="dense" className={classes.root}>
|
||||||
<div className={classes.left} />
|
<div className={classes.left}>
|
||||||
|
<Link className={classes.link} href={config.app.website} rel="noreferrer" target="_blank">
|
||||||
|
<PublicIcon />
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
<div className={classes.center}>(c) {config.app.org} {version}</div>
|
<div className={classes.center}>(c) {config.app.org} {version}</div>
|
||||||
<div className={classes.right}>
|
<div className={classes.right}>
|
||||||
<LoadingIcon className={clsx(classes.icon, isLoading && classes.loading)} />
|
<LoadingIcon className={clsx(classes.icon, isLoading && classes.loading)} />
|
||||||
<StatusIcon error={error} />
|
<StatusIcon error={error} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Toolbar>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"build": {
|
"build": {
|
||||||
"name": "@dxos/console-client",
|
"name": "@dxos/console-client",
|
||||||
"buildDate": "2020-05-23T23:08:59.032Z",
|
"buildDate": "2020-05-24T00:17:36.206Z",
|
||||||
"version": "1.0.0-beta.0"
|
"version": "1.0.0-beta.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,12 +42,11 @@ const app = express();
|
|||||||
// React app
|
// React app
|
||||||
//
|
//
|
||||||
|
|
||||||
const { publicUrl } = config;
|
const { app: { publicUrl } } = config;
|
||||||
|
|
||||||
app.get(`${publicUrl}(/:filePath)?`, (req, res) => {
|
app.get(`${publicUrl}(/:filePath)?`, (req, res) => {
|
||||||
const { filePath = 'index.html' } = req.params;
|
const { filePath = 'index.html' } = req.params;
|
||||||
const file = path.join(__dirname, '../../../node_modules/@dxos/console-client/dist/production', filePath);
|
const file = path.join(__dirname, '../../../node_modules/@dxos/console-client/dist/production', filePath);
|
||||||
console.log(__dirname, file);
|
|
||||||
res.sendFile(file);
|
res.sendFile(file);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -69,7 +68,8 @@ const server = new ApolloServer({
|
|||||||
},
|
},
|
||||||
tabs: [
|
tabs: [
|
||||||
{
|
{
|
||||||
endpoint: config.path,
|
name: 'Status',
|
||||||
|
endpoint: config.graphql.path,
|
||||||
query: print(gql(QUERY_STATUS))
|
query: print(gql(QUERY_STATUS))
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -83,13 +83,13 @@ const server = new ApolloServer({
|
|||||||
|
|
||||||
server.applyMiddleware({
|
server.applyMiddleware({
|
||||||
app,
|
app,
|
||||||
path: config.path
|
path: config.graphql.path
|
||||||
});
|
});
|
||||||
|
|
||||||
//
|
//
|
||||||
// Start server
|
// Start server
|
||||||
//
|
//
|
||||||
|
|
||||||
app.listen({ port: config.port }, () => {
|
app.listen({ port: config.graphql.port }, () => {
|
||||||
log(`Running: http://localhost:${config.port}`);
|
log(`Running: http://localhost:${config.graphql.port}`);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user