forked from cerc-io/laconic-console
Layout with sidebar.
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
{
|
||||
"server": "http://localhost",
|
||||
"publicUrl": "/app",
|
||||
"port": 4000,
|
||||
"path": "/api"
|
||||
"path": "/api",
|
||||
"app": {
|
||||
"org": "DxOS",
|
||||
"theme": "dark",
|
||||
"title": "Console",
|
||||
"website": "https://dxos.org"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,13 @@
|
||||
"dependencies": {
|
||||
"@apollo/react-hooks": "^3.1.5",
|
||||
"@babel/runtime": "^7.8.7",
|
||||
"apollo-boost": "^0.4.9",
|
||||
"@dxos/gem-core": "^1.0.0-beta.11",
|
||||
"@material-ui/core": "^4.10.0",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"apollo-cache-inmemory": "^1.6.6",
|
||||
"apollo-client": "^2.6.10",
|
||||
"apollo-link-http": "^1.5.17",
|
||||
"clsx": "^1.1.0",
|
||||
"debug": "^4.1.1",
|
||||
"graphql-tag": "^2.10.3",
|
||||
"lodash.defaultsdeep": "^4.6.1",
|
||||
@@ -52,9 +58,10 @@
|
||||
"babel-plugin-inline-import": "^3.0.0",
|
||||
"dotenv-webpack": "^1.8.0",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-loader": "^3.0.3",
|
||||
"eslint-config-semistandard": "^15.0.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-config-standard-jsx": "^8.1.0",
|
||||
"eslint-loader": "^3.0.3",
|
||||
"eslint-plugin-babel": "^5.3.0",
|
||||
"eslint-plugin-import": "^2.18.2",
|
||||
"eslint-plugin-jest": "^23.13.1",
|
||||
@@ -79,7 +86,8 @@
|
||||
"parser": "babel-eslint",
|
||||
"extends": [
|
||||
"plugin:jest/recommended",
|
||||
"semistandard"
|
||||
"semistandard",
|
||||
"standard-jsx"
|
||||
],
|
||||
"plugins": [
|
||||
"babel"
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// Copyright 2020 DxOS
|
||||
//
|
||||
|
||||
import { ApolloClient } from 'apollo-client';
|
||||
import { createHttpLink } from 'apollo-link-http';
|
||||
import { InMemoryCache } from 'apollo-cache-inmemory';
|
||||
|
||||
import config from '../config.json';
|
||||
|
||||
const defaultServer = `${window.location.protocol}//${window.location.hostname}`;
|
||||
|
||||
const { server = defaultServer, port = 80, path = '/graphql' } = config;
|
||||
|
||||
// TODO(burdon): Authentication: send signed message to server (from client wallet).
|
||||
// https://www.apollographql.com/docs/react/networking/authentication/
|
||||
|
||||
// https://www.apollographql.com/docs/link/
|
||||
const link = createHttpLink({
|
||||
uri: `${server}:${port}${path}`
|
||||
});
|
||||
|
||||
// https://www.apollographql.com/docs/react/api/apollo-client/
|
||||
export const client = new ApolloClient({
|
||||
cache: new InMemoryCache(),
|
||||
link
|
||||
});
|
||||
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// Copyright 2020 DxOS
|
||||
//
|
||||
|
||||
import React from 'react';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import MuiAppBar from '@material-ui/core/AppBar';
|
||||
import MuiLink from '@material-ui/core/Link';
|
||||
import Toolbar from '@material-ui/core/Toolbar';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import blueGrey from '@material-ui/core/colors/blueGrey';
|
||||
import PublicIcon from '@material-ui/icons/Public';
|
||||
|
||||
import DxOSIcon from '../icons/DXOS';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
offset: theme.mixins.denseToolbar,
|
||||
|
||||
logo: {
|
||||
paddingBottom: 2,
|
||||
marginTop: 4,
|
||||
marginRight: theme.spacing(2),
|
||||
color: '#333',
|
||||
|
||||
'& svg': {
|
||||
width: 64,
|
||||
height: 32
|
||||
}
|
||||
},
|
||||
|
||||
title: {
|
||||
display: 'flex',
|
||||
flex: 1
|
||||
},
|
||||
|
||||
link: {
|
||||
color: blueGrey[900]
|
||||
}
|
||||
}));
|
||||
|
||||
const AppBar = ({ config }) => {
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<>
|
||||
<MuiAppBar position="fixed">
|
||||
<Toolbar variant="dense">
|
||||
<MuiLink href="/console">
|
||||
<div className={classes.logo}>
|
||||
<DxOSIcon />
|
||||
</div>
|
||||
</MuiLink>
|
||||
<div className={classes.title}>
|
||||
<Typography variant="h6">{config.app.title}</Typography>
|
||||
</div>
|
||||
<div>
|
||||
<MuiLink href={config.app.website} className={classes.link} rel="noreferrer" target="_blank">
|
||||
<PublicIcon />
|
||||
</MuiLink>
|
||||
</div>
|
||||
</Toolbar>
|
||||
</MuiAppBar>
|
||||
|
||||
<div className={classes.offset} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AppBar;
|
||||
@@ -2,42 +2,66 @@
|
||||
// Copyright 2020 DxOS
|
||||
//
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
|
||||
import { useStatusReducer } from '../hooks';
|
||||
import { FullScreen } from '@dxos/gem-core';
|
||||
|
||||
import config from '../../config.json';
|
||||
import StatusBar from '../containers/StatusBar';
|
||||
import AppBar from './AppBar';
|
||||
import Sidebar from './Sidebar';
|
||||
import { ConsoleContext } from '../hooks';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flex: 1
|
||||
},
|
||||
container: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flex: 1
|
||||
},
|
||||
sidebar: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flexShrink: 0,
|
||||
width: 200,
|
||||
borderRight: `1px solid ${theme.palette.primary.dark}`
|
||||
},
|
||||
main: {
|
||||
display: 'flex',
|
||||
flex: 1
|
||||
},
|
||||
cooter: {
|
||||
display: 'flex',
|
||||
flexShrink: 0
|
||||
}
|
||||
}));
|
||||
|
||||
// TODO(burdon): Factor out LoadingIndicator.
|
||||
const Layout = ({ children }) => {
|
||||
const [{ loading, error = '' }] = useStatusReducer();
|
||||
const [isLoading, setLoading] = useState(loading);
|
||||
|
||||
useEffect(() => {
|
||||
let t;
|
||||
if (loading) {
|
||||
setLoading(loading);
|
||||
t = setTimeout(() => {
|
||||
setLoading(false);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
return () => clearTimeout(t);
|
||||
}, [loading]);
|
||||
const classes = useStyles();
|
||||
const { modules } = useContext(ConsoleContext);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
{children}
|
||||
<FullScreen>
|
||||
<div className={classes.root}>
|
||||
<AppBar config={config} />
|
||||
<div className={classes.container}>
|
||||
<div className={classes.sidebar}>
|
||||
<Sidebar modules={modules} />
|
||||
</div>
|
||||
<div className={classes.main}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.footer}>
|
||||
<StatusBar />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{error && (
|
||||
<span>{String(error)}</span>
|
||||
)}
|
||||
{isLoading && (
|
||||
<span>Loading</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</FullScreen>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
//
|
||||
// Copyright 2020 DxOS
|
||||
//
|
||||
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import List from '@material-ui/core/List';
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
||||
import ListItemText from '@material-ui/core/ListItemText';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
root: {
|
||||
display: 'flex',
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'space-between'
|
||||
},
|
||||
|
||||
list: {
|
||||
padding: 0
|
||||
},
|
||||
|
||||
icon: {
|
||||
color: theme.palette.grey[500]
|
||||
},
|
||||
|
||||
selected: {
|
||||
color: theme.palette.primary.main
|
||||
}
|
||||
}));
|
||||
|
||||
const Sidebar = ({ modules: { services, settings } }) => {
|
||||
const classes = useStyles();
|
||||
|
||||
// TODO(burdon): Change.
|
||||
const router = {};
|
||||
|
||||
const Modules = ({ modules }) => (
|
||||
<List aria-label="items" className={classes.list}>
|
||||
{modules.map(({ path, title, icon: Icon }) => (
|
||||
<ListItem button selected={path === router.pathname} key={path} onClick={() => router.push(path)}>
|
||||
<ListItemIcon classes={{ root: classes.icon }}>
|
||||
<Icon className={clsx(classes.icon, path === router.pathname && classes.selected)} />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={title} />
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<Modules modules={services} />
|
||||
<Modules modules={settings} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Sidebar;
|
||||
@@ -7,9 +7,7 @@ import defaultsDeep from 'lodash.defaultsdeep';
|
||||
|
||||
import ErrorBoundary from '../components/ErrorBoundary';
|
||||
|
||||
import { statusReducer, SET_STATUS } from '../hooks/status';
|
||||
|
||||
import { ConsoleContext } from '../hooks';
|
||||
import { ConsoleContext, statusReducer, SET_STATUS } from '../hooks';
|
||||
|
||||
const defaultState = {};
|
||||
|
||||
@@ -29,11 +27,12 @@ const appReducer = (state, action) => ({
|
||||
* Wraps children with a React ErrorBoundary component, which catches runtime errors and enables reset.
|
||||
*
|
||||
* @param {function} children
|
||||
* @param {function} modules
|
||||
* @param {Object} [initialState]
|
||||
* @param {function} [errorHandler]
|
||||
* @returns {function}
|
||||
*/
|
||||
const ConsoleContextProvider = ({ children, initialState = {}, errorHandler }) => {
|
||||
const ConsoleContextProvider = ({ children, modules, initialState = {}, errorHandler }) => {
|
||||
const [state, dispatch] = useReducer(appReducer, defaultsDeep({}, initialState, defaultState));
|
||||
|
||||
const { errors: { exceptions = [] } = {} } = state[SET_STATUS] || {};
|
||||
@@ -53,7 +52,7 @@ const ConsoleContextProvider = ({ children, initialState = {}, errorHandler }) =
|
||||
}
|
||||
|
||||
return (
|
||||
<ConsoleContext.Provider value={{ state, dispatch }}>
|
||||
<ConsoleContext.Provider value={{ modules, state, dispatch }}>
|
||||
<ErrorBoundary>
|
||||
{children}
|
||||
</ErrorBoundary>
|
||||
|
||||
@@ -2,34 +2,32 @@
|
||||
// Copyright 2020 DxOS
|
||||
//
|
||||
|
||||
import { ApolloProvider } from '@apollo/react-hooks';
|
||||
import ApolloClient from 'apollo-boost';
|
||||
import React from 'react';
|
||||
import { ApolloProvider } from '@apollo/react-hooks';
|
||||
import { ThemeProvider } from '@material-ui/core/styles';
|
||||
import CssBaseline from '@material-ui/core/CssBaseline';
|
||||
|
||||
import config from '../../config.json';
|
||||
|
||||
import { createTheme } from '../theme';
|
||||
import { client } from '../client';
|
||||
import modules from '../modules';
|
||||
|
||||
import Status from './Status';
|
||||
|
||||
import config from '../../config.json';
|
||||
import Layout from '../components/Layout';
|
||||
import ConsoleContextProvider from './ConsoleContextProvider';
|
||||
|
||||
const { server, port = 80, path } = config;
|
||||
|
||||
// TODO(burdon): Authentication:
|
||||
// https://www.apollographql.com/docs/react/networking/authentication/
|
||||
|
||||
// TODO(burdon): Configure from server.
|
||||
// TODO(burdon): Configure error handling for server errors.
|
||||
const client = new ApolloClient({
|
||||
uri: `${server}:${port}${path}`
|
||||
});
|
||||
|
||||
const Main = () => {
|
||||
return (
|
||||
<ApolloProvider client={client}>
|
||||
<ConsoleContextProvider>
|
||||
<Layout>
|
||||
<Status />
|
||||
</Layout>
|
||||
<ConsoleContextProvider modules={modules}>
|
||||
<ThemeProvider theme={createTheme(config.app.theme)}>
|
||||
<CssBaseline />
|
||||
<Layout>
|
||||
<Status />
|
||||
</Layout>
|
||||
</ThemeProvider>
|
||||
</ConsoleContextProvider>
|
||||
</ApolloProvider>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
//
|
||||
// Copyright 2020 DxOS
|
||||
//
|
||||
|
||||
import clsx from 'clsx';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import ErrorIcon from '@material-ui/icons/Error';
|
||||
import LoadingIcon from '@material-ui/icons/Wifi';
|
||||
import RunningIcon from '@material-ui/icons/CheckCircle';
|
||||
import grey from '@material-ui/core/colors/grey';
|
||||
import green from '@material-ui/core/colors/green';
|
||||
import red from '@material-ui/core/colors/red';
|
||||
|
||||
import config from '../../config.json';
|
||||
import { version } from '../../package.json';
|
||||
import { useStatusReducer } from '../hooks';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flex: 1,
|
||||
justifyContent: 'space-around',
|
||||
backgroundColor: grey[900],
|
||||
color: '#EEE',
|
||||
height: 32,
|
||||
padding: 4
|
||||
},
|
||||
left: {
|
||||
width: 160
|
||||
},
|
||||
right: {
|
||||
width: 160,
|
||||
textAlign: 'right'
|
||||
},
|
||||
center: {
|
||||
flex: 1,
|
||||
textAlign: 'center'
|
||||
},
|
||||
icon: {
|
||||
margin: '0 2px'
|
||||
},
|
||||
error: {
|
||||
color: red[500]
|
||||
},
|
||||
running: {
|
||||
color: green[500]
|
||||
},
|
||||
loading:{
|
||||
color: theme.palette.primary.dark
|
||||
}
|
||||
}));
|
||||
|
||||
const StatusBar = () => {
|
||||
const classes = useStyles();
|
||||
const [{ loading, error }] = useStatusReducer();
|
||||
const [isLoading, setLoading] = useState(loading);
|
||||
|
||||
useEffect(() => {
|
||||
let t;
|
||||
if (loading) {
|
||||
setLoading(loading);
|
||||
t = setTimeout(() => {
|
||||
setLoading(false);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
return () => clearTimeout(t);
|
||||
}, [loading]);
|
||||
|
||||
const StatusIcon = ({ error }) => {
|
||||
if (error) {
|
||||
return (
|
||||
<ErrorIcon className={clsx(classes.icon, classes.error)} title={String(error)} />
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<RunningIcon className={clsx(classes.icon, classes.running)} />
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<div className={classes.left} />
|
||||
<div className={classes.center}>(c) {config.app.org} {version}</div>
|
||||
<div className={classes.right}>
|
||||
<LoadingIcon className={clsx(classes.icon, isLoading && classes.loading)} />
|
||||
<StatusIcon error={error} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default StatusBar;
|
||||
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// Copyright 2020 DxOS
|
||||
//
|
||||
|
||||
import React from 'react';
|
||||
import SvgIcon from '@material-ui/core/SvgIcon';
|
||||
|
||||
const Icon = (props) => (
|
||||
<SvgIcon {...props} viewBox="0 0 512 256">
|
||||
<g transform="matrix(1,0,0,1,-187.374,-7.5)">
|
||||
<g transform="matrix(0.936373,0,0,0.906495,295.947,135.5)">
|
||||
<path
|
||||
d="M0,-0.233C0,-27.435 -16.74,-48.591 -48.359,-48.591L-76.722,-48.591L-76.722,48.358L-48.59,48.358C-17.902,48.358 0,26.271 0,-0.233M-109.736,77.419L-109.736,-77.652L-48.59,-77.652C0,-77.652 33.711,-46.731 33.711,-0.233C33.711,46.73 0,77.419 -48.359,77.419L-109.736,77.419Z"
|
||||
/>
|
||||
</g>
|
||||
<g transform="matrix(0.936373,0,0,0.906495,530.058,135.499)">
|
||||
<path
|
||||
d="M0,0.002C0,-29.06 -18.367,-50.914 -46.964,-50.914C-75.793,-50.914 -94.16,-29.06 -94.16,0.002C-94.16,28.83 -75.793,50.917 -46.964,50.917C-18.367,50.917 0,28.83 0,0.002M-128.104,0.002C-128.104,-46.729 -93.927,-80.208 -46.964,-80.208C-0.233,-80.208 33.942,-46.729 33.942,0.002C33.942,46.731 -0.233,80.21 -46.964,80.21C-93.927,80.21 -128.104,46.731 -128.104,0.002"
|
||||
/>
|
||||
</g>
|
||||
<g transform="matrix(0.936373,0,0,0.906495,573.603,85.3412)">
|
||||
<path
|
||||
d="M0,110.898L18.134,85.092C29.062,96.484 46.034,106.249 67.422,106.249C85.789,106.249 94.392,98.111 94.392,89.044C94.392,62.075 5.115,80.907 5.115,22.551C5.115,-3.255 27.434,-24.644 63.935,-24.644C88.579,-24.644 109.039,-17.204 124.383,-3.022L106.017,21.622C93.462,9.997 76.723,4.65 60.913,4.65C46.964,4.65 39.059,10.695 39.059,19.994C39.059,44.406 128.103,27.898 128.103,85.789C128.103,114.153 107.644,135.542 66.028,135.542C36.036,135.542 14.648,125.544 0,110.898"
|
||||
/>
|
||||
</g>
|
||||
<g transform="matrix(0.936373,0,0,0.906495,368.158,65.109)">
|
||||
<path
|
||||
d="M0,56.844L-36.496,0L36.496,0L0,56.844Z"
|
||||
/>
|
||||
</g>
|
||||
<g transform="matrix(0.936373,0,0,0.906495,368.158,205.681)">
|
||||
<path
|
||||
d="M0,-56.845L-36.496,0L36.496,0L0,-56.845Z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</SvgIcon>
|
||||
);
|
||||
|
||||
export default Icon;
|
||||
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// Copyright 2020 DxOS
|
||||
//
|
||||
|
||||
import React from 'react';
|
||||
import SvgIcon from '@material-ui/core/SvgIcon';
|
||||
|
||||
// TODO(burdon): Fixed color?
|
||||
|
||||
const Icon = (props) => (
|
||||
<SvgIcon {...props} viewBox="0 0 256 256">
|
||||
<g transform="matrix(1,0,0,1,-160,-124)">
|
||||
<path
|
||||
d="M282.254,147.134L195.254,194.589C191.399,196.692 189,200.732 189,205.124L189,298.876C189,303.268 191.399,307.308 195.254,309.411L282.254,356.866C285.836,358.819 290.164,358.819 293.746,356.866L380.746,309.411C384.601,307.308 387,303.268 387,298.876L387,205.124C387,200.732 384.601,196.692 380.746,194.589L293.746,147.134C290.164,145.181 285.836,145.181 282.254,147.134Z"
|
||||
style={{ fill: 'none', fillRule: 'nonzero', stroke: 'rgb(0,68,121)', strokeWidth: '12px' }}
|
||||
/>
|
||||
<path
|
||||
d="M288,252L216,216"
|
||||
style={{ fill: 'none', fillRule: 'nonzero', stroke: 'rgb(0,68,121)', strokeWidth: '8px', strokeLinejoin: 'round' }}
|
||||
/>
|
||||
<path
|
||||
d="M216,288L288,252"
|
||||
style={{ fill: 'none', fillRule: 'nonzero', stroke: 'rgb(0,68,121)', strokeWidth: '8px', strokeLinejoin: 'round' }}
|
||||
/>
|
||||
<path
|
||||
d="M360,288L288,252"
|
||||
style={{ fill: 'none', fillRule: 'nonzero', stroke: 'rgb(0,68,121)', strokeWidth: '8px', strokeLinejoin: 'round' }}
|
||||
/>
|
||||
<path
|
||||
d="M360,216L288,252"
|
||||
style={{ fill: 'none', fillRule: 'nonzero', stroke: 'rgb(0,68,121)', strokeWidth: '8px', strokeLinejoin: 'round' }}
|
||||
/>
|
||||
</g>
|
||||
</SvgIcon>
|
||||
);
|
||||
|
||||
export default Icon;
|
||||
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// Copyright 2020 DxOS
|
||||
//
|
||||
|
||||
import AppsIcon from '@material-ui/icons/Apps';
|
||||
import BotsIcon from '@material-ui/icons/Android';
|
||||
import StatsIcon from '@material-ui/icons/Equalizer';
|
||||
import RegistryIcon from '@material-ui/icons/Language';
|
||||
import IPFSIcon from '@material-ui/icons/GraphicEq';
|
||||
import ConfigIcon from '@material-ui/icons/Settings';
|
||||
import SignalIcon from '@material-ui/icons/Traffic';
|
||||
import ServicesIcon from '@material-ui/icons/Storage';
|
||||
|
||||
export default {
|
||||
services: [
|
||||
{
|
||||
path: '/console/status',
|
||||
title: 'Status',
|
||||
icon: StatsIcon
|
||||
},
|
||||
{
|
||||
path: '/console/wns',
|
||||
title: 'WNS',
|
||||
icon: RegistryIcon
|
||||
},
|
||||
{
|
||||
path: '/console/apps',
|
||||
title: 'Apps',
|
||||
icon: AppsIcon
|
||||
},
|
||||
{
|
||||
path: '/console/bots',
|
||||
title: 'Bots',
|
||||
icon: BotsIcon
|
||||
},
|
||||
{
|
||||
path: '/console/signal',
|
||||
title: 'Signal Server',
|
||||
icon: SignalIcon
|
||||
},
|
||||
{
|
||||
path: '/console/ipfs',
|
||||
title: 'IPFS',
|
||||
icon: IPFSIcon
|
||||
}
|
||||
],
|
||||
|
||||
settings: [
|
||||
{
|
||||
path: '/console/metadata',
|
||||
title: 'Metadata',
|
||||
icon: ServicesIcon
|
||||
},
|
||||
{
|
||||
path: '/console/config',
|
||||
title: 'Config',
|
||||
icon: ConfigIcon
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// Copyright 2019 DxOS
|
||||
//
|
||||
|
||||
import { createMuiTheme } from '@material-ui/core/styles';
|
||||
import teal from '@material-ui/core/colors/teal';
|
||||
import orange from '@material-ui/core/colors/orange';
|
||||
|
||||
export const createTheme = (theme) => createMuiTheme({
|
||||
|
||||
// https://stackoverflow.com/questions/60567673/reactjs-material-ui-theme-mixins-toolbar-offset-is-not-adapting-when-toolbar
|
||||
mixins: {
|
||||
denseToolbar: {
|
||||
minHeight: 48
|
||||
}
|
||||
},
|
||||
|
||||
// https://material-ui.com/customization/globals/#default-props
|
||||
props: {
|
||||
MuiButtonBase: {
|
||||
disableRipple: true
|
||||
}
|
||||
},
|
||||
|
||||
// https://material-ui.com/customization/palette/
|
||||
palette: theme === 'dark' ? {
|
||||
type: 'dark',
|
||||
primary: orange
|
||||
} : {
|
||||
primary: teal
|
||||
},
|
||||
|
||||
// https://material-ui.com/customization/theming/#theme-configuration-variables
|
||||
|
||||
// https://material-ui.com/customization/globals/
|
||||
overrides: {
|
||||
MuiCssBaseline: {
|
||||
'@global': {
|
||||
body: {
|
||||
margin: 0,
|
||||
overflow: 'hidden'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"build": {
|
||||
"name": "@dxos/console-client",
|
||||
"buildDate": "2020-05-23T20:00:53.818Z",
|
||||
"buildDate": "2020-05-23T22:14:40.153Z",
|
||||
"version": "1.0.0-beta.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,10 +46,8 @@ module.exports = {
|
||||
cacheGroups: {
|
||||
vendor: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
// name: 'vendor',
|
||||
name(module) {
|
||||
name (module) {
|
||||
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
|
||||
// return `vendor-${packageName.replace('@', '')}`;
|
||||
|
||||
if (packageName.startsWith('@dxos')) {
|
||||
return 'dxos';
|
||||
|
||||
@@ -16,7 +16,7 @@ module.exports = merge(commonConfig, {
|
||||
new HtmlWebPackPlugin({
|
||||
template: './public/index.html',
|
||||
templateParameters: {
|
||||
title: 'Planner'
|
||||
title: 'DxOS Console'
|
||||
}
|
||||
})
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user