forked from cerc-io/laconic-console
Tabs.
This commit is contained in:
parent
5476d9fce8
commit
9fbdd0625a
@ -34,6 +34,7 @@
|
|||||||
"@dxos/react-ux": "^1.0.0-beta.20",
|
"@dxos/react-ux": "^1.0.0-beta.20",
|
||||||
"@material-ui/core": "^4.10.0",
|
"@material-ui/core": "^4.10.0",
|
||||||
"@material-ui/icons": "^4.9.1",
|
"@material-ui/icons": "^4.9.1",
|
||||||
|
"@material-ui/lab": "^4.0.0-alpha.54",
|
||||||
"@wirelineio/registry-client": "^0.4.8",
|
"@wirelineio/registry-client": "^0.4.8",
|
||||||
"apollo-cache-inmemory": "^1.6.6",
|
"apollo-cache-inmemory": "^1.6.6",
|
||||||
"apollo-client": "^2.6.10",
|
"apollo-client": "^2.6.10",
|
||||||
@ -45,6 +46,7 @@
|
|||||||
"lodash.isobject": "^3.0.2",
|
"lodash.isobject": "^3.0.2",
|
||||||
"lodash.omit": "^4.5.0",
|
"lodash.omit": "^4.5.0",
|
||||||
"lodash.transform": "^4.6.0",
|
"lodash.transform": "^4.6.0",
|
||||||
|
"moment": "^2.26.0",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
"react-router": "^5.2.0",
|
"react-router": "^5.2.0",
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright 2020 DxOS
|
|
||||||
//
|
|
||||||
|
|
||||||
import React, { useContext } from 'react';
|
|
||||||
|
|
||||||
import { JsonTreeView } from '@dxos/react-ux';
|
|
||||||
|
|
||||||
import { ConsoleContext } from '../hooks';
|
|
||||||
|
|
||||||
const Config = () => {
|
|
||||||
const { config } = useContext(ConsoleContext);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<JsonTreeView data={config} />
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Config;
|
|
35
packages/console-client/src/components/ControlButtons.js
Normal file
35
packages/console-client/src/components/ControlButtons.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2020 DxOS
|
||||||
|
//
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import OpenIcon from '@material-ui/icons/OpenInBrowser';
|
||||||
|
import StartIcon from '@material-ui/icons/PlayCircleOutline';
|
||||||
|
import StopIcon from '@material-ui/icons/HighlightOff';
|
||||||
|
import IconButton from '@material-ui/core/IconButton';
|
||||||
|
|
||||||
|
const ControlButtons = ({ onStart, onStop, onOpen }) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{onStart && (
|
||||||
|
<IconButton onClick={onStart} title="Restart">
|
||||||
|
<StartIcon />
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{onStop && (
|
||||||
|
<IconButton onClick={onStop} title="Stop">
|
||||||
|
<StopIcon />
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{onOpen && (
|
||||||
|
<IconButton onClick={onOpen} title="Open console">
|
||||||
|
<OpenIcon />
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ControlButtons;
|
42
packages/console-client/src/components/Error.js
Normal file
42
packages/console-client/src/components/Error.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2020 DxOS
|
||||||
|
//
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { makeStyles } from '@material-ui/core/styles';
|
||||||
|
import Alert from '@material-ui/lab/Alert';
|
||||||
|
import AlertTitle from '@material-ui/lab/AlertTitle';
|
||||||
|
import Snackbar from '@material-ui/core/Snackbar';
|
||||||
|
|
||||||
|
const useStyles = makeStyles(() => ({
|
||||||
|
root: {
|
||||||
|
marginBottom: 60
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
const Error = ({ message, ...rest }) => {
|
||||||
|
const classes = useStyles();
|
||||||
|
if (!message) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const messages = Array.isArray(message) ? message : [message];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Snackbar
|
||||||
|
className={classes.root}
|
||||||
|
open={Boolean(message)}
|
||||||
|
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
|
||||||
|
TransitionProps={{ exit: false }}
|
||||||
|
>
|
||||||
|
<Alert severity="error" {...rest}>
|
||||||
|
<AlertTitle>Error</AlertTitle>
|
||||||
|
{messages.map((message, i) => (
|
||||||
|
<div key={i}>{message}</div>
|
||||||
|
))}
|
||||||
|
</Alert>
|
||||||
|
</Snackbar>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Error;
|
@ -4,14 +4,14 @@
|
|||||||
|
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import { makeStyles } from '@material-ui/core';
|
import { makeStyles } from '@material-ui/core';
|
||||||
import Paper from '@material-ui/core/Paper';
|
|
||||||
|
|
||||||
import { FullScreen } from '@dxos/gem-core';
|
import { FullScreen } from '@dxos/gem-core';
|
||||||
|
|
||||||
import StatusBar from '../containers/StatusBar';
|
import { ConsoleContext } from '../hooks';
|
||||||
|
|
||||||
import AppBar from './AppBar';
|
import AppBar from './AppBar';
|
||||||
import Sidebar from './Sidebar';
|
import Sidebar from './Sidebar';
|
||||||
import { ConsoleContext } from '../hooks';
|
import StatusBar from './StatusBar';
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
root: {
|
root: {
|
||||||
@ -56,9 +56,9 @@ const Layout = ({ children }) => {
|
|||||||
<div className={classes.sidebar}>
|
<div className={classes.sidebar}>
|
||||||
<Sidebar modules={modules} />
|
<Sidebar modules={modules} />
|
||||||
</div>
|
</div>
|
||||||
<Paper className={classes.main}>
|
<div className={classes.main}>
|
||||||
{children}
|
{children}
|
||||||
</Paper>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.footer}>
|
<div className={classes.footer}>
|
||||||
<StatusBar />
|
<StatusBar />
|
||||||
|
120
packages/console-client/src/components/Log.js
Normal file
120
packages/console-client/src/components/Log.js
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2020 DxOS
|
||||||
|
//
|
||||||
|
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import moment from 'moment';
|
||||||
|
import React, { Fragment } from 'react';
|
||||||
|
import { makeStyles } from '@material-ui/core/styles';
|
||||||
|
|
||||||
|
const useStyles = makeStyles(theme => ({
|
||||||
|
root: {
|
||||||
|
display: 'flex',
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'column'
|
||||||
|
},
|
||||||
|
|
||||||
|
container: {
|
||||||
|
display: 'flex',
|
||||||
|
flex: 1,
|
||||||
|
overflowX: 'scroll',
|
||||||
|
overflowY: 'scroll'
|
||||||
|
},
|
||||||
|
|
||||||
|
log: {
|
||||||
|
padding: theme.spacing(1),
|
||||||
|
fontSize: 16,
|
||||||
|
// fontFamily: 'monospace',
|
||||||
|
whiteSpace: 'nowrap'
|
||||||
|
},
|
||||||
|
|
||||||
|
level: {
|
||||||
|
display: 'inline-block',
|
||||||
|
width: 48,
|
||||||
|
marginRight: 8,
|
||||||
|
color: theme.palette.grey[500]
|
||||||
|
},
|
||||||
|
level_warn: {
|
||||||
|
color: theme.palette.warning.main
|
||||||
|
},
|
||||||
|
level_error: {
|
||||||
|
color: theme.palette.error.main
|
||||||
|
},
|
||||||
|
|
||||||
|
ts: {
|
||||||
|
marginRight: 8,
|
||||||
|
color: theme.palette.primary[500]
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
const Log = ({ log = [], onClear }) => {
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
|
const levels = {
|
||||||
|
'I': { label: 'INFO', className: classes.level_info },
|
||||||
|
'W': { label: 'WARN', className: classes.level_warn },
|
||||||
|
'E': { label: 'ERROR', className: classes.level_error }
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO(burdon): Parse in backend and normalize numbers.
|
||||||
|
const Line = ({ message }) => {
|
||||||
|
// https://regex101.com/
|
||||||
|
const patterns = [
|
||||||
|
{
|
||||||
|
// 2020-03-30T18:02:43.189Z bot-factory
|
||||||
|
pattern: /()(.+Z)\s+(.+)/,
|
||||||
|
transform: ([datetime]) => moment(datetime)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// I[2020-03-30|15:29:05.436] Executed block module=state height=11533 validTxs=0 invalidTxs=0
|
||||||
|
pattern: /(.)\[(.+)\|(.+)]\s+(.+)/,
|
||||||
|
transform: ([date, time]) => moment(`${date} ${time}`)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// [cors] 2020/03/30 15:28:53 Handler: Actual request
|
||||||
|
pattern: /\[(\w+)] (\S+) (\S+)\s+(.+)/,
|
||||||
|
transform: ([date, time]) => moment(`${date.replace(/\//g, '-')} ${time}`)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
patterns.some(({ pattern, transform }) => {
|
||||||
|
const match = message.match(pattern);
|
||||||
|
if (match) {
|
||||||
|
const [, level = 'I', ...rest] = match;
|
||||||
|
const datetime = transform(rest).format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
const text = match[match.length - 1];
|
||||||
|
|
||||||
|
const { label, className } = levels[level] || levels['I'];
|
||||||
|
const pkg = levels[level] ? '' : `[${level}]: `;
|
||||||
|
|
||||||
|
message = (
|
||||||
|
<Fragment>
|
||||||
|
<span className={classes.ts}>{datetime}</span>
|
||||||
|
<span className={clsx(classes.level, className)}>{label || level}</span>
|
||||||
|
<span>{pkg}{text}</span>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>{message}</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classes.root}>
|
||||||
|
<div className={classes.container}>
|
||||||
|
<div className={classes.log}>
|
||||||
|
{log.reverse().map((line, i) => <Line key={i} message={line} />)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Log;
|
38
packages/console-client/src/components/Panel.js
Normal file
38
packages/console-client/src/components/Panel.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2020 DxOS.org
|
||||||
|
//
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { makeStyles } from '@material-ui/core';
|
||||||
|
import Paper from '@material-ui/core/Paper';
|
||||||
|
|
||||||
|
const useStyles = makeStyles(theme => ({
|
||||||
|
root: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
flex: 1,
|
||||||
|
overflow: 'hidden'
|
||||||
|
},
|
||||||
|
|
||||||
|
container: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
flex: 1,
|
||||||
|
overflowY: 'scroll'
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
const Panel = ({ toolbar, children }) => {
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classes.root}>
|
||||||
|
{toolbar}
|
||||||
|
<Paper className={classes.container}>
|
||||||
|
{children}
|
||||||
|
</Paper>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Panel;
|
28
packages/console-client/src/components/TableCell.js
Normal file
28
packages/console-client/src/components/TableCell.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2020 DxOS
|
||||||
|
//
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import MuiTableCell from '@material-ui/core/TableCell';
|
||||||
|
|
||||||
|
// TODO(burdon): Size for header.
|
||||||
|
// TODO(burdon): Standardize table.
|
||||||
|
|
||||||
|
const TableCell = ({ children, monospace = false, title, ...rest }) => (
|
||||||
|
<MuiTableCell
|
||||||
|
{...rest}
|
||||||
|
style={{
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
fontFamily: monospace ? 'monospace' : 'inherit',
|
||||||
|
fontSize: monospace ? 14 : 'inherit'
|
||||||
|
}}
|
||||||
|
title={title}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</MuiTableCell>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default TableCell;
|
30
packages/console-client/src/components/Toolbar.js
Normal file
30
packages/console-client/src/components/Toolbar.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2020 DxOS
|
||||||
|
//
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { makeStyles } from '@material-ui/core';
|
||||||
|
import MuiToolbar from '@material-ui/core/Toolbar';
|
||||||
|
|
||||||
|
const useStyles = makeStyles(theme => ({
|
||||||
|
toolbar: {
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
|
||||||
|
'& > button': {
|
||||||
|
margin: theme.spacing(0.5),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
const Toolbar = ({ children }) => {
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MuiToolbar variant="dense" disableGutters className={classes.toolbar}>
|
||||||
|
{children}
|
||||||
|
</MuiToolbar>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Toolbar;
|
@ -1,25 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright 2020 DxOS
|
|
||||||
//
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import { useQuery } from '@apollo/react-hooks';
|
|
||||||
|
|
||||||
import Json from '../components/Json';
|
|
||||||
|
|
||||||
import { useQueryStatusReducer } from '../hooks';
|
|
||||||
|
|
||||||
import IPFS_STATUS from '../../gql/ipfs_status.graphql';
|
|
||||||
|
|
||||||
const IPFS = () => {
|
|
||||||
const data = useQueryStatusReducer(useQuery(IPFS_STATUS));
|
|
||||||
if (!data) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Json data={JSON.parse(data.ipfs_status.json)} />
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default IPFS;
|
|
@ -10,19 +10,17 @@ import { ThemeProvider } from '@material-ui/core/styles';
|
|||||||
import CssBaseline from '@material-ui/core/CssBaseline';
|
import CssBaseline from '@material-ui/core/CssBaseline';
|
||||||
|
|
||||||
import config from '../../config.yml';
|
import config from '../../config.yml';
|
||||||
|
|
||||||
import { createTheme } from '../theme';
|
import { createTheme } from '../theme';
|
||||||
import { clientFactory } from '../client';
|
import { clientFactory } from '../client';
|
||||||
import modules from '../modules';
|
import modules from '../modules';
|
||||||
|
|
||||||
import Config from '../components/Config';
|
|
||||||
import Layout from '../components/Layout';
|
import Layout from '../components/Layout';
|
||||||
|
|
||||||
import ConsoleContextProvider from './ConsoleContextProvider';
|
import ConsoleContextProvider from './ConsoleContextProvider';
|
||||||
|
|
||||||
import IPFS from './IPFS';
|
import Config from './panels/Config';
|
||||||
import Status from './Status';
|
import IPFS from './panels/IPFS';
|
||||||
import WNS from './WNS';
|
import Status from './panels/Status';
|
||||||
|
import WNS from './panels/WNS';
|
||||||
|
|
||||||
debug.enable(config.system.debug);
|
debug.enable(config.system.debug);
|
||||||
|
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright 2020 DxOS
|
|
||||||
//
|
|
||||||
|
|
||||||
import React, { useContext } from 'react';
|
|
||||||
import { useQuery } from '@apollo/react-hooks';
|
|
||||||
import { Mutation } from '@apollo/react-components';
|
|
||||||
import { makeStyles } from '@material-ui/core';
|
|
||||||
import Button from '@material-ui/core/Button';
|
|
||||||
|
|
||||||
import Json from '../components/Json';
|
|
||||||
|
|
||||||
import { ConsoleContext, useQueryStatusReducer } from '../hooks';
|
|
||||||
|
|
||||||
import WNS_STATUS from '../../gql/wns_status.graphql';
|
|
||||||
import WNS_ACTION from '../../gql/wns_action.graphql';
|
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
|
||||||
root: {
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
flex: 1,
|
|
||||||
overflowY: 'scroll'
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
const WNS = () => {
|
|
||||||
const classes = useStyles();
|
|
||||||
const { config } = useContext(ConsoleContext);
|
|
||||||
const data = useQueryStatusReducer(useQuery(WNS_STATUS, { pollInterval: config.api.pollInterval }));
|
|
||||||
if (!data) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={classes.root}>
|
|
||||||
<Mutation mutation={WNS_ACTION}>
|
|
||||||
{(action, { data }) => (
|
|
||||||
<div>
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
action({ variables: { command: 'test' } });
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Test
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<pre>Result: {JSON.stringify(data)}</pre>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Mutation>
|
|
||||||
|
|
||||||
<Json data={JSON.parse(data.wns_status.json)} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default WNS;
|
|
27
packages/console-client/src/containers/panels/Config.js
Normal file
27
packages/console-client/src/containers/panels/Config.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2020 DxOS
|
||||||
|
//
|
||||||
|
|
||||||
|
import React, { useContext } from 'react';
|
||||||
|
|
||||||
|
import { ConsoleContext } from '../../hooks';
|
||||||
|
|
||||||
|
import Panel from '../../components/Panel';
|
||||||
|
import Toolbar from '../../components/Toolbar';
|
||||||
|
import Json from '../../components/Json';
|
||||||
|
|
||||||
|
const Config = () => {
|
||||||
|
const { config } = useContext(ConsoleContext);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Panel
|
||||||
|
toolbar={
|
||||||
|
<Toolbar />
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Json data={config} />
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Config;
|
33
packages/console-client/src/containers/panels/IPFS.js
Normal file
33
packages/console-client/src/containers/panels/IPFS.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2020 DxOS
|
||||||
|
//
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { useQuery } from '@apollo/react-hooks';
|
||||||
|
|
||||||
|
import IPFS_STATUS from '../../../gql/ipfs_status.graphql';
|
||||||
|
|
||||||
|
import { useQueryStatusReducer } from '../../hooks';
|
||||||
|
|
||||||
|
import Json from '../../components/Json';
|
||||||
|
import Panel from '../../components/Panel';
|
||||||
|
import Toolbar from '../../components/Toolbar';
|
||||||
|
|
||||||
|
const IPFS = () => {
|
||||||
|
const data = useQueryStatusReducer(useQuery(IPFS_STATUS));
|
||||||
|
if (!data) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Panel
|
||||||
|
toolbar={
|
||||||
|
<Toolbar />
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Json data={JSON.parse(data.ipfs_status.json)} />
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default IPFS;
|
@ -5,11 +5,14 @@
|
|||||||
import React, { useContext } 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 { ConsoleContext, useQueryStatusReducer } from '../hooks';
|
import SYSTEM_STATUS from '../../../gql/system_status.graphql';
|
||||||
|
|
||||||
import SYSTEM_STATUS from '../../gql/system_status.graphql';
|
import { ConsoleContext, useQueryStatusReducer } from '../../hooks';
|
||||||
|
|
||||||
|
import Panel from '../../components/Panel';
|
||||||
|
import Toolbar from '../../components/Toolbar';
|
||||||
|
|
||||||
const Status = () => {
|
const Status = () => {
|
||||||
const { config } = useContext(ConsoleContext);
|
const { config } = useContext(ConsoleContext);
|
||||||
@ -19,7 +22,13 @@ const Status = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Json data={data.system_status} />
|
<Panel
|
||||||
|
toolbar={
|
||||||
|
<Toolbar />
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Json data={data.system_status} />
|
||||||
|
</Panel>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
123
packages/console-client/src/containers/panels/WNS.js
Normal file
123
packages/console-client/src/containers/panels/WNS.js
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2020 DxOS
|
||||||
|
//
|
||||||
|
|
||||||
|
import React, { useContext, useState } from 'react';
|
||||||
|
import { useQuery } from '@apollo/react-hooks';
|
||||||
|
import { Mutation } from '@apollo/react-components';
|
||||||
|
import { makeStyles } from '@material-ui/core';
|
||||||
|
import Button from '@material-ui/core/Button';
|
||||||
|
import ButtonGroup from '@material-ui/core/ButtonGroup';
|
||||||
|
import Tab from '@material-ui/core/Tab';
|
||||||
|
import Tabs from '@material-ui/core/Tabs';
|
||||||
|
import TabContext from '@material-ui/lab/TabContext';
|
||||||
|
import TabPanel from '@material-ui/lab/TabPanel';
|
||||||
|
|
||||||
|
import ControlButtons from '../../components/ControlButtons';
|
||||||
|
import Json from '../../components/Json';
|
||||||
|
import Log from '../../components/Log';
|
||||||
|
import Panel from '../../components/Panel';
|
||||||
|
import Toolbar from '../../components/Toolbar';
|
||||||
|
|
||||||
|
import { ConsoleContext, useQueryStatusReducer } from '../../hooks';
|
||||||
|
|
||||||
|
import WNS_STATUS from '../../../gql/wns_status.graphql';
|
||||||
|
import WNS_ACTION from '../../../gql/wns_action.graphql';
|
||||||
|
|
||||||
|
const types = [
|
||||||
|
{ key: null, label: 'ALL' },
|
||||||
|
{ key: 'wrn:xbox', label: 'XBox' },
|
||||||
|
{ key: 'wrn:resource', label: 'Resource' },
|
||||||
|
{ key: 'wrn:app', label: 'App' },
|
||||||
|
{ key: 'wrn:bot', label: 'Bot' },
|
||||||
|
{ key: 'wrn:type', label: 'Type' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const TAB_RECORDS = 'records';
|
||||||
|
const TAB_LOG = 'log';
|
||||||
|
const TAB_EXPLORER = 'explorer';
|
||||||
|
|
||||||
|
const useStyles = makeStyles(() => ({
|
||||||
|
expand: {
|
||||||
|
flex: 1
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
const WNS = () => {
|
||||||
|
const classes = useStyles();
|
||||||
|
const { config } = useContext(ConsoleContext);
|
||||||
|
const [type, setType] = useState(types[0].key);
|
||||||
|
const [tab, setTab] = useState(TAB_RECORDS);
|
||||||
|
const data = useQueryStatusReducer(useQuery(WNS_STATUS, { pollInterval: config.api.pollInterval }));
|
||||||
|
if (!data) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Panel
|
||||||
|
toolbar={
|
||||||
|
<Toolbar>
|
||||||
|
<Tabs value={tab} onChange={(_, value) => setTab(value)}>
|
||||||
|
<Tab value={TAB_RECORDS} label="Records"/>
|
||||||
|
<Tab value={TAB_EXPLORER} label="Explorer"/>
|
||||||
|
<Tab value={TAB_LOG} label="Log"/>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
{tab === TAB_RECORDS && (
|
||||||
|
<ButtonGroup
|
||||||
|
className={classes.buttons}
|
||||||
|
disableRipple
|
||||||
|
disableFocusRipple
|
||||||
|
variant="outlined"
|
||||||
|
color="primary"
|
||||||
|
size="small"
|
||||||
|
aria-label="text primary button group"
|
||||||
|
>
|
||||||
|
{types.map(t => (
|
||||||
|
<Button
|
||||||
|
key={t.key}
|
||||||
|
className={t.key === type && classes.selected}
|
||||||
|
onClick={() => setType(t.key)}
|
||||||
|
>
|
||||||
|
{t.label}
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</ButtonGroup>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className={classes.expand} />
|
||||||
|
|
||||||
|
<Mutation mutation={WNS_ACTION}>
|
||||||
|
{(action, { data }) => (
|
||||||
|
<div>
|
||||||
|
<ControlButtons
|
||||||
|
onStart={() => {
|
||||||
|
action({ variables: { command: 'start' } });
|
||||||
|
}}
|
||||||
|
onStop={() => {
|
||||||
|
action({ variables: { command: 'stop' } });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Mutation>
|
||||||
|
</Toolbar>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<TabContext value={tab}>
|
||||||
|
<TabPanel value={TAB_RECORDS}>
|
||||||
|
<Json data={JSON.parse(data.wns_status.json)} />
|
||||||
|
</TabPanel>
|
||||||
|
|
||||||
|
<TabPanel value={TAB_EXPLORER}>
|
||||||
|
</TabPanel>
|
||||||
|
|
||||||
|
<TabPanel value={TAB_LOG}>
|
||||||
|
<Log />
|
||||||
|
</TabPanel>
|
||||||
|
</TabContext>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default WNS;
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"build": {
|
"build": {
|
||||||
"name": "@dxos/console-client",
|
"name": "@dxos/console-client",
|
||||||
"buildDate": "2020-05-24T13:13:49.317Z",
|
"buildDate": "2020-05-25T02:29:08.942Z",
|
||||||
"version": "1.0.0-beta.0"
|
"version": "1.0.0-beta.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,8 @@ export const createResolvers = config => ({
|
|||||||
// WNS
|
// WNS
|
||||||
//
|
//
|
||||||
|
|
||||||
wns_action: async (_, __, { action }) => {
|
wns_action: async (_, { command }) => {
|
||||||
log(`WNS action: ${action}`);
|
log(`WNS action: ${command}`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
timestamp: timestamp(),
|
timestamp: timestamp(),
|
||||||
|
@ -2178,7 +2178,7 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.4.4"
|
"@babel/runtime" "^7.4.4"
|
||||||
|
|
||||||
"@material-ui/lab@^4.0.0-alpha.42":
|
"@material-ui/lab@^4.0.0-alpha.42", "@material-ui/lab@^4.0.0-alpha.54":
|
||||||
version "4.0.0-alpha.54"
|
version "4.0.0-alpha.54"
|
||||||
resolved "https://registry.yarnpkg.com/@material-ui/lab/-/lab-4.0.0-alpha.54.tgz#f359fac05667549353e5e21e631ae22cb2c22996"
|
resolved "https://registry.yarnpkg.com/@material-ui/lab/-/lab-4.0.0-alpha.54.tgz#f359fac05667549353e5e21e631ae22cb2c22996"
|
||||||
integrity sha512-BK/z+8xGPQoMtG6gWKyagCdYO1/2DzkBchvvXs2bbTVh3sbi/QQLIqWV6UA1KtMVydYVt22NwV3xltgPkaPKLg==
|
integrity sha512-BK/z+8xGPQoMtG6gWKyagCdYO1/2DzkBchvvXs2bbTVh3sbi/QQLIqWV6UA1KtMVydYVt22NwV3xltgPkaPKLg==
|
||||||
@ -11379,6 +11379,11 @@ modify-values@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
|
resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
|
||||||
integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==
|
integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==
|
||||||
|
|
||||||
|
moment@^2.26.0:
|
||||||
|
version "2.26.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/moment/-/moment-2.26.0.tgz#5e1f82c6bafca6e83e808b30c8705eed0dcbd39a"
|
||||||
|
integrity sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw==
|
||||||
|
|
||||||
move-concurrently@^1.0.1:
|
move-concurrently@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
|
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
|
||||||
|
Loading…
Reference in New Issue
Block a user