diff --git a/package.json b/package.json index 53bbea8..2cbd794 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@dxos/console", "version": "1.0.0-beta.0", - "description": "Kubenet Console", + "description": "Console", "main": "index.js", "private": true, "scripts": { diff --git a/packages/console-app/config-kube.yml b/packages/console-app/config-kube.yml index 9a00ec6..2dc9efb 100644 --- a/packages/console-app/config-kube.yml +++ b/packages/console-app/config-kube.yml @@ -4,7 +4,7 @@ # app: - title: 'Kubenet Console' + title: 'Console' org': 'DXOS.org' theme: 'dark' website: 'https://dxos.org' @@ -37,4 +37,4 @@ services: gateway: 'https://kube.local/dxos/ipfs/gateway' wellknown: - endpoint: 'https://kube.local/.well-known/dxos' \ No newline at end of file + endpoint: 'https://kube.local/.well-known/dxos' diff --git a/packages/console-app/config-local.yml b/packages/console-app/config-local.yml index f18bbd8..a67a4e3 100644 --- a/packages/console-app/config-local.yml +++ b/packages/console-app/config-local.yml @@ -4,7 +4,7 @@ # app: - title: 'Kubenet Console' + title: 'Console' org': 'DXOS.org' theme: 'dark' website: 'https://dxos.org' @@ -37,4 +37,4 @@ services: gateway: 'http://127.0.0.1:8888/ipfs/' wellknown: - endpoint: 'http://127.0.0.1:9000/.well-known/dxos' \ No newline at end of file + endpoint: 'http://127.0.0.1:9000/.well-known/dxos' diff --git a/packages/console-app/config-production.yml b/packages/console-app/config-production.yml index 5b35391..6824128 100644 --- a/packages/console-app/config-production.yml +++ b/packages/console-app/config-production.yml @@ -4,7 +4,7 @@ # app: - title: 'Kubenet Console' + title: 'Console' org': 'DXOS.org' theme: 'dark' website: 'https://dxos.org' @@ -34,4 +34,4 @@ routes: gateway: '/dxos/ipfs/gateway' wellknown: - endpoint: '/.well-known/dxos' \ No newline at end of file + endpoint: '/.well-known/dxos' diff --git a/packages/console-app/config-testnet.yml b/packages/console-app/config-testnet.yml index bf15843..45ac94c 100644 --- a/packages/console-app/config-testnet.yml +++ b/packages/console-app/config-testnet.yml @@ -4,7 +4,7 @@ # app: - title: 'Kubenet Console' + title: 'Console' org': 'DXOS.org' theme: 'dark' website: 'https://dxos.org' diff --git a/packages/console-app/src/components/AppBar.js b/packages/console-app/src/components/AppBar.js index 5721065..c2aae3e 100644 --- a/packages/console-app/src/components/AppBar.js +++ b/packages/console-app/src/components/AppBar.js @@ -48,7 +48,7 @@ const AppBar = ({ config }) => { return ( <> - +
diff --git a/packages/console-app/src/components/PackageLink.js b/packages/console-app/src/components/PackageLink.js index 1ce67b9..3cc7516 100644 --- a/packages/console-app/src/components/PackageLink.js +++ b/packages/console-app/src/components/PackageLink.js @@ -17,28 +17,49 @@ import { getServiceUrl } from '../util/config'; const PackageLink = ({ config, type, pkg, text }) => { // eslint-disable-next-line default-case switch (type) { + // Apps case 'wrn:app': { const cid = pkg['/']; const ipfsUrl = getServiceUrl(config, 'ipfs.gateway', { path: `${cid}` }); - return {text || cid}; + if (!cid) { + console.warn('Invalid CID', type, pkg); + return; + } + + return ( + + {text || cid} + + ); } + + // Bots case 'wrn:bot': { const packageLinks = []; - Object.keys(pkg).forEach((platform, i) => { + Object.keys(pkg).forEach((platform) => { Object.keys(pkg[platform]).forEach(arch => { const cid = pkg[platform][arch]['/']; const ipfsUrl = getServiceUrl(config, 'ipfs.gateway', { path: `${cid}` }); + if (!cid) { + console.warn('Invalid CID', type, pkg); + return; + } + + const label = `${platform}/${arch}: ${cid}` packageLinks.push( -
- - {platform}/{arch}: {cid} - -
+ + {cid} + ); }); }); diff --git a/packages/console-app/src/components/Table.js b/packages/console-app/src/components/Table.js index 03f16fd..b3fad08 100644 --- a/packages/console-app/src/components/Table.js +++ b/packages/console-app/src/components/Table.js @@ -16,7 +16,7 @@ const useStyles = makeStyles(theme => ({ }, table: { - tableLayout: 'fixed', + // tableLayout: 'fixed', '& th': { fontVariant: 'all-small-caps', diff --git a/packages/console-app/src/components/TableCell.js b/packages/console-app/src/components/TableCell.js index 1f4f199..d274f3d 100644 --- a/packages/console-app/src/components/TableCell.js +++ b/packages/console-app/src/components/TableCell.js @@ -23,7 +23,7 @@ const useStyles = makeStyles(() => ({ } })); -const TableCell = ({ children, size, monospace = false, style, title, ...rest }) => { +const TableCell = ({ children, size, monospace = false, ellipsis = false, style, title, ...rest }) => { const classes = useStyles(); return ( @@ -32,7 +32,7 @@ const TableCell = ({ children, size, monospace = false, style, title, ...rest }) className={clsx(size && classes[size])} style={{ overflow: 'hidden', - textOverflow: 'ellipsis', + textOverflow: ellipsis ? 'ellipsis' : '', whiteSpace: 'nowrap', verticalAlign: 'top', fontFamily: monospace ? 'monospace' : 'inherit', diff --git a/packages/console-app/src/containers/Main.js b/packages/console-app/src/containers/Main.js index 5692903..01688e5 100644 --- a/packages/console-app/src/containers/Main.js +++ b/packages/console-app/src/containers/Main.js @@ -19,14 +19,15 @@ import modules from '../modules'; import Layout from './Layout'; import ConsoleContextProvider from './ConsoleContextProvider'; -import AppRecords from './panels/apps/Apps'; +import Apps from './panels/apps/Apps'; import Bots from './panels/bots/Bots'; +import Kubes from './panels/kubes/Kubes'; import Config from './panels/Config'; import IPFS from './panels/ipfs/IPFS'; import Metadata from './panels/Metadata'; import Signaling from './panels/signal/Signaling'; import System from './panels/system/System'; -import WNS from './panels/wns/WNS'; +import Registry from './panels/registry/Registry'; // Global error handler. const errorHandler = new ErrorHandler(); @@ -46,14 +47,15 @@ const Main = ({ config }) => { - + + + - diff --git a/packages/console-app/src/containers/panels/kubes/KubeRecords.js b/packages/console-app/src/containers/panels/kubes/KubeRecords.js new file mode 100644 index 0000000..95439dd --- /dev/null +++ b/packages/console-app/src/containers/panels/kubes/KubeRecords.js @@ -0,0 +1,67 @@ +// +// Copyright 2020 DXOS.org +// + +import React, { useContext } from 'react'; +import moment from 'moment'; + +import { useQuery } from '@apollo/react-hooks'; +import TableHead from '@material-ui/core/TableHead'; +import TableRow from '@material-ui/core/TableRow'; +import TableBody from '@material-ui/core/TableBody'; + +import WNS_RECORDS from '../../../gql/wns_records.graphql'; + +import { ConsoleContext, useQueryStatusReducer, useSorter } from '../../../hooks'; + +import Table from '../../../components/Table'; +import TableCell from '../../../components/TableCell'; +import AppLink from '../../../components/AppLink'; + +const KubeRecords = () => { + const { config } = useContext(ConsoleContext); + const [sorter, sortBy] = useSorter('names[0]'); + const appResponse = useQueryStatusReducer(useQuery(WNS_RECORDS, { + pollInterval: config.api.intervalQuery, + variables: { attributes: { type: 'wrn:kube' } } + })); + + if (!appResponse) { + return null; + } + + const appData = JSON.parse(appResponse.wns_records.json); + + return ( + + + + Registered Names + Version + Name + Created + + + + {appData.sort(sorter).map(({ id, names, createTime, attributes: { name: displayName, version, package: packageLink } }) => { + return ( + + + {names.map(wrn =>
)} +
+ + {version} + + + {displayName} + + {moment.utc(createTime).fromNow()} +
+ ); + })} +
+
+ ); +}; + +export default KubeRecords; diff --git a/packages/console-app/src/containers/panels/kubes/Kubes.js b/packages/console-app/src/containers/panels/kubes/Kubes.js new file mode 100644 index 0000000..afd4f50 --- /dev/null +++ b/packages/console-app/src/containers/panels/kubes/Kubes.js @@ -0,0 +1,43 @@ +// +// Copyright 2020 DXOS.org +// + +import React, { useState } from 'react'; +import { makeStyles } from '@material-ui/core'; +import Tabs from '@material-ui/core/Tabs'; +import Tab from '@material-ui/core/Tab'; + +import Panel from '../../../components/Panel'; +import Toolbar from '../../../components/Toolbar'; + +import KubeRecords from './KubeRecords'; + +const TAB_RECORDS = 'records'; + +const useStyles = makeStyles(theme => ({ + root: {} +})); + +const Kubes = () => { + // eslint-disable-next-line + const classes = useStyles(); + const [tab, setTab] = useState(TAB_RECORDS); + + return ( + + setTab(value)}> + + + + } + > + {tab === TAB_RECORDS && ( + + )} + + ); +}; + +export default Kubes; diff --git a/packages/console-app/src/containers/panels/wns/WNS.js b/packages/console-app/src/containers/panels/registry/Registry.js similarity index 83% rename from packages/console-app/src/containers/panels/wns/WNS.js rename to packages/console-app/src/containers/panels/registry/Registry.js index c2fe740..72a226a 100644 --- a/packages/console-app/src/containers/panels/wns/WNS.js +++ b/packages/console-app/src/containers/panels/registry/Registry.js @@ -13,9 +13,9 @@ import LogPoller from '../../../components/LogPoller'; import Panel from '../../../components/Panel'; import Toolbar from '../../../components/Toolbar'; -import WNSRecords, { WNSRecordType } from './WNSRecords'; -import WNSStatus from './WNSStatus'; -import WNSLookup from './WNSLookup'; +import RegistryRecords, { RecordType } from './RegistryRecords'; +import RegistryStatus from './RegistryStatus'; +import RegistryLookup from './RegistryLookup'; const TAB_RECORDS = 'records'; const TAB_STATUS = 'status'; @@ -40,7 +40,7 @@ const useStyles = makeStyles(() => ({ } })); -const WNS = () => { +const Registry = () => { const classes = useStyles(); const [tab, setTab] = useState(TAB_RECORDS); const [type, setType] = useState(); @@ -57,7 +57,7 @@ const WNS = () => { {tab === TAB_RECORDS && ( - + )} } @@ -65,20 +65,20 @@ const WNS = () => { {tab === TAB_RECORDS && (
- +
)} {tab === TAB_LOOKUP && (
- +
)} {tab === TAB_STATUS && (
- +
)} @@ -93,4 +93,4 @@ const WNS = () => { ); }; -export default WNS; +export default Registry; diff --git a/packages/console-app/src/containers/panels/wns/WNSLookup.js b/packages/console-app/src/containers/panels/registry/RegistryLookup.js similarity index 57% rename from packages/console-app/src/containers/panels/wns/WNSLookup.js rename to packages/console-app/src/containers/panels/registry/RegistryLookup.js index fb97813..ee78c80 100644 --- a/packages/console-app/src/containers/panels/wns/WNSLookup.js +++ b/packages/console-app/src/containers/panels/registry/RegistryLookup.js @@ -5,22 +5,37 @@ import React, { useContext, useState } from 'react'; import Autocomplete from '@material-ui/lab/Autocomplete'; import Button from '@material-ui/core/Button'; -import NativeSelect from '@material-ui/core/NativeSelect'; -import TableBody from '@material-ui/core/TableBody'; -import TableContainer from '@material-ui/core/TableContainer'; -import TableRow from '@material-ui/core/TableRow'; +import MenuItem from '@material-ui/core/MenuItem'; +import Select from '@material-ui/core/Select'; import TextField from '@material-ui/core/TextField'; +import Toolbar from '@material-ui/core/Toolbar'; +import { makeStyles } from '@material-ui/core'; import { useQuery } from '@apollo/react-hooks'; import Json from '../../../components/Json'; -import Table from '../../../components/Table'; -import TableCell from '../../../components/TableCell'; + import { ConsoleContext, useQueryStatusReducer, useRegistry } from '../../../hooks'; import WNS_RECORDS from '../../../gql/wns_records.graphql'; -const WNSLookup = () => { +const useStyles = makeStyles(theme => ({ + root: { + display: 'flex', + flexDirection: 'column', + flex: 1 + }, + select: { + width: 160, + marginRight: theme.spacing(2) + }, + button: { + marginLeft: theme.spacing(2) + } +})); + +const RegistryLookup = () => { + const classes = useStyles(); const { config } = useContext(ConsoleContext); const { registry } = useRegistry(config); const [result, setResult] = useState({}); @@ -34,6 +49,7 @@ const WNSLookup = () => { if (!data) { return null; } + const records = JSON.parse(data.wns_records.json); const getNames = () => { @@ -44,6 +60,7 @@ const WNSLookup = () => { records.forEach(item => ret.push(...item.names)); break; } + case 'authority': { // Use the known names to come up with a default list of authorities. // TODO(telackey): Should we be able to query WNS for a list of authorities? @@ -57,9 +74,11 @@ const WNSLookup = () => { ret = Array.from(names.values()); break; } + default: throw new Error(`Unrecognized lookup type: ${lookupType}`); } + ret.sort(); return ret; }; @@ -67,6 +86,7 @@ const WNSLookup = () => { const handleSelect = (evt) => { evt.preventDefault(); + // TODO(burdon): Change to controlled component. setLookupType(evt.target.value); }; @@ -83,54 +103,46 @@ const WNSLookup = () => { case 'wrn': result = await registry.lookupNames([inputValue], true); break; + case 'authority': result = await registry.lookupAuthorities([inputValue]); break; + default: throw new Error(`Unrecognized lookup type: ${lookupType}`); } + setResult(result); }; return ( -
-
- - - - - - - - - - - - { - setInputValue(newInputValue); - }} - renderInput={(params) => } - /> - - - - - - -
-
-
+
+ + + + { + setInputValue(newInputValue); + }} + renderInput={(params) => } + /> + + + +
); }; -export default WNSLookup; +export default RegistryLookup; diff --git a/packages/console-app/src/containers/panels/wns/WNSRecords.js b/packages/console-app/src/containers/panels/registry/RegistryRecords.js similarity index 95% rename from packages/console-app/src/containers/panels/wns/WNSRecords.js rename to packages/console-app/src/containers/panels/registry/RegistryRecords.js index e28bc38..e2b6cf3 100644 --- a/packages/console-app/src/containers/panels/wns/WNSRecords.js +++ b/packages/console-app/src/containers/panels/registry/RegistryRecords.js @@ -39,7 +39,7 @@ const useStyles = makeStyles(theme => ({ } })); -export const WNSRecordType = ({ type = types[0].key, onChanged }) => { +export const RecordType = ({ type = types[0].key, onChanged }) => { const classes = useStyles(); return ( @@ -64,7 +64,7 @@ export const WNSRecordType = ({ type = types[0].key, onChanged }) => { ); }; -const WNSRecords = ({ type }) => { +const RegistryRecords = ({ type }) => { const { config } = useContext(ConsoleContext); const [sorter, sortBy] = useSorter('createTime', false); const data = useQueryStatusReducer(useQuery(WNS_RECORDS, { @@ -85,7 +85,7 @@ const WNSRecords = ({ type }) => { Type Registered Names Version - Name + Display Name Created Package @@ -145,4 +145,4 @@ const WNSRecords = ({ type }) => { ); }; -export default WNSRecords; +export default RegistryRecords; diff --git a/packages/console-app/src/containers/panels/wns/WNSStatus.js b/packages/console-app/src/containers/panels/registry/RegistryStatus.js similarity index 89% rename from packages/console-app/src/containers/panels/wns/WNSStatus.js rename to packages/console-app/src/containers/panels/registry/RegistryStatus.js index 8eaa9e1..9cb6937 100644 --- a/packages/console-app/src/containers/panels/wns/WNSStatus.js +++ b/packages/console-app/src/containers/panels/registry/RegistryStatus.js @@ -11,7 +11,7 @@ import { ConsoleContext, useQueryStatusReducer } from '../../../hooks'; import Json from '../../../components/Json'; -const WNSStatus = () => { +const RegistryStatus = () => { const { config } = useContext(ConsoleContext); const data = useQueryStatusReducer(useQuery(WNS_STATUS, { pollInterval: config.api.intervalQuery })); if (!data) { @@ -23,4 +23,4 @@ const WNSStatus = () => { ); }; -export default WNSStatus; +export default RegistryStatus; diff --git a/packages/console-app/src/modules.js b/packages/console-app/src/modules.js index b057bc0..dd88383 100644 --- a/packages/console-app/src/modules.js +++ b/packages/console-app/src/modules.js @@ -9,7 +9,11 @@ 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 KubeIcon from '@material-ui/icons/Dns'; +/** + * Paths should match Main routes. + */ export default { services: [ { @@ -18,10 +22,15 @@ export default { icon: StatsIcon }, { - path: '/wns', - title: 'WNS', + path: '/registry', + title: 'Registry', icon: RegistryIcon }, + { + path: '/kubes', + title: 'KUBE Nodes', + icon: KubeIcon + }, { path: '/apps', title: 'Apps', diff --git a/packages/console-app/src/version.json b/packages/console-app/src/version.json index fef65a6..0437b04 100644 --- a/packages/console-app/src/version.json +++ b/packages/console-app/src/version.json @@ -1,7 +1,7 @@ { "build": { "name": "@dxos/console-app", - "buildDate": "2020-10-19T16:21:30.158Z", - "version": "1.1.0-beta.9" + "buildDate": "2020-10-30T16:31:29.034Z", + "version": "1.1.0-beta.10" } } diff --git a/packages/console-app/webpack.config.js b/packages/console-app/webpack.config.js index ca31e61..4097fab 100644 --- a/packages/console-app/webpack.config.js +++ b/packages/console-app/webpack.config.js @@ -15,7 +15,7 @@ module.exports = merge(commonConfig, { new HtmlWebPackPlugin({ template: './public/index.html', templateParameters: { - title: 'Kubenet Console' + title: 'Console' } }) ] diff --git a/packages/console-server/config-kube.yml b/packages/console-server/config-kube.yml index ae2bf3a..0bbc4ad 100644 --- a/packages/console-server/config-kube.yml +++ b/packages/console-server/config-kube.yml @@ -4,7 +4,7 @@ # app: - title: 'Kubenet Console' + title: 'Console' org': 'DXOS.org' theme: 'dark' website: 'https://dxos.org' diff --git a/packages/console-server/config-testnet.yml b/packages/console-server/config-testnet.yml index ddeb19e..ebe88b0 100644 --- a/packages/console-server/config-testnet.yml +++ b/packages/console-server/config-testnet.yml @@ -4,7 +4,7 @@ # app: - title: 'Kubenet Console' + title: 'Console' org': 'DXOS.org' theme: 'dark' website: 'https://dxos.org' diff --git a/packages/console-server/config.yml b/packages/console-server/config.yml index fc09723..ea1135c 100644 --- a/packages/console-server/config.yml +++ b/packages/console-server/config.yml @@ -4,7 +4,7 @@ # app: - title: 'Kubenet Console' + title: 'Console' org': 'DXOS.org' theme: 'dark' website: 'https://dxos.org' diff --git a/packages/console-server/webpack.config.js b/packages/console-server/webpack.config.js index 5c6b7f5..b77e176 100644 --- a/packages/console-server/webpack.config.js +++ b/packages/console-server/webpack.config.js @@ -67,7 +67,7 @@ module.exports = { new HtmlWebPackPlugin({ template: './public/index.html', templateParameters: { - title: 'Kubenet Console' + title: 'Console' } }),