IPFS connected status.
This commit is contained in:
parent
dccd61c0c9
commit
c0efe66ec4
@ -24,7 +24,7 @@ const useStyles = makeStyles(theme => ({
|
||||
export const BooleanIcon = ({ yes = false, error = false }) => {
|
||||
const classes = useStyles();
|
||||
return (yes
|
||||
? <YesIcon className={classes.on} />
|
||||
: <NoIcon className={error ? classes.error : classes.off} />
|
||||
? <YesIcon className={classes.on} />
|
||||
: <NoIcon className={error ? classes.error : classes.off} />
|
||||
);
|
||||
};
|
||||
|
@ -27,17 +27,18 @@ const VersionCheck = () => {
|
||||
const classes = useStyles();
|
||||
const [{ current, latest }, setUpgrade] = useState({});
|
||||
const status = useQueryStatusReducer(useQuery(SYSTEM_STATUS));
|
||||
const data = useQueryStatusReducer(useQuery(WNS_RECORDS, {
|
||||
const wnsResponse = useQueryStatusReducer(useQuery(WNS_RECORDS, {
|
||||
pollInterval: CHECK_INTERVAL,
|
||||
variables: { type: 'wrn:resource' }
|
||||
}));
|
||||
|
||||
// Check version.
|
||||
useEffect(() => {
|
||||
if (status && data) {
|
||||
if (status && wnsResponse) {
|
||||
const { dxos: { image: current } } = status.system_status;
|
||||
let latest = current;
|
||||
data.wns_records.json.forEach(({ attributes: { name, version } }) => {
|
||||
const data = JSON.parse(wnsResponse.wns_records.json);
|
||||
data.forEach(({ attributes: { name, version } }) => {
|
||||
// TODO(burdon): Filter by type (WRN?)
|
||||
if (name.startsWith('dxos/xbox:')) {
|
||||
if (compareVersions(version, latest) > 0) {
|
||||
@ -48,7 +49,7 @@ const VersionCheck = () => {
|
||||
|
||||
setUpgrade({ current, latest: latest !== current ? latest : undefined });
|
||||
}
|
||||
}, [status, data]);
|
||||
}, [status, wnsResponse]);
|
||||
|
||||
// TODO(burdon): Link to Github page with upgrade info.
|
||||
return (
|
||||
|
@ -3,29 +3,30 @@
|
||||
//
|
||||
|
||||
import React, { useContext } from 'react';
|
||||
import moment from 'moment';
|
||||
|
||||
import { useQuery } from '@apollo/react-hooks';
|
||||
import Link from '@material-ui/core/Link';
|
||||
import TableHead from '@material-ui/core/TableHead';
|
||||
import TableRow from '@material-ui/core/TableRow';
|
||||
import TableBody from '@material-ui/core/TableBody';
|
||||
import moment from 'moment';
|
||||
|
||||
import IPFS_STATUS from '../../../gql/ipfs_status.graphql';
|
||||
import WNS_RECORDS from '../../../gql/wns_records.graphql';
|
||||
|
||||
import { ConsoleContext, useQueryStatusReducer, useSorter } from '../../../hooks';
|
||||
|
||||
import { BooleanIcon } from '../../../components/BooleanIcon';
|
||||
import Table from '../../../components/Table';
|
||||
import TableCell from '../../../components/TableCell';
|
||||
import { ConsoleContext, useQueryStatusReducer, useSorter } from '../../../hooks';
|
||||
import { getServiceUrl } from '../../../util/config';
|
||||
|
||||
import IPFS_STATUS from '../../../gql/ipfs_status.graphql';
|
||||
import WNS_RECORDS from '../../../gql/wns_records.graphql';
|
||||
|
||||
const AppRecords = () => {
|
||||
const { config } = useContext(ConsoleContext);
|
||||
const [sorter, sortBy] = useSorter('createTime', false);
|
||||
const appResponse = useQueryStatusReducer(useQuery(WNS_RECORDS, {
|
||||
pollInterval: config.api.intervalQuery,
|
||||
variables: { type: 'wrn:app' }
|
||||
variables: { attributes: { type: 'wrn:app' } }
|
||||
}));
|
||||
|
||||
// TODO(telackey): Does this also need an interval?
|
||||
@ -35,7 +36,7 @@ const AppRecords = () => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const appData = appResponse.wns_records.json;
|
||||
const appData = JSON.parse(appResponse.wns_records.json);
|
||||
const ipfsData = JSON.parse(ipfsResponse.ipfs_status.json);
|
||||
|
||||
const localRefs = new Set(ipfsData.refs.local);
|
||||
|
@ -3,29 +3,157 @@
|
||||
//
|
||||
|
||||
import React from 'react';
|
||||
import get from 'lodash.get';
|
||||
|
||||
import { useQuery } from '@apollo/react-hooks';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import TableBody from '@material-ui/core/TableBody';
|
||||
import TableHead from '@material-ui/core/TableHead';
|
||||
import TableRow from '@material-ui/core/TableRow';
|
||||
|
||||
import IPFS_STATUS from '../../../gql/ipfs_status.graphql';
|
||||
import WNS_RECORDS from '../../../gql/wns_records.graphql';
|
||||
|
||||
import { useQueryStatusReducer } from '../../../hooks';
|
||||
|
||||
import Json from '../../../components/Json';
|
||||
import Panel from '../../../components/Panel';
|
||||
import Table from '../../../components/Table';
|
||||
import TableCell from '../../../components/TableCell';
|
||||
import Toolbar from '../../../components/Toolbar';
|
||||
import { BooleanIcon } from '../../../components/BooleanIcon';
|
||||
|
||||
const RECORD_TYPE = 'wrn:service';
|
||||
const SERVICE_TYPE = 'ipfs';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
tableContainer: {
|
||||
flex: 1,
|
||||
overflowY: 'scroll'
|
||||
},
|
||||
|
||||
table: {
|
||||
tableLayout: 'fixed',
|
||||
|
||||
'& th': {
|
||||
fontVariant: 'all-small-caps',
|
||||
fontSize: 18,
|
||||
cursor: 'ns-resize'
|
||||
}
|
||||
},
|
||||
|
||||
connected: {
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
|
||||
disconnected: {
|
||||
fontStyle: 'italic'
|
||||
},
|
||||
|
||||
colShort: {
|
||||
width: '30%'
|
||||
},
|
||||
|
||||
colWide: {},
|
||||
|
||||
colBoolean: {
|
||||
width: '10%'
|
||||
},
|
||||
|
||||
caption: {
|
||||
backgroundColor: theme.palette.primary[500],
|
||||
color: theme.palette.primary.contrastText,
|
||||
paddingLeft: '1em',
|
||||
margin: 0
|
||||
}
|
||||
}));
|
||||
|
||||
const IPFS = () => {
|
||||
const data = useQueryStatusReducer(useQuery(IPFS_STATUS));
|
||||
if (!data) {
|
||||
const classes = useStyles();
|
||||
const ipfsResponse = useQueryStatusReducer(useQuery(IPFS_STATUS));
|
||||
const wnsResponse = useQueryStatusReducer(useQuery(WNS_RECORDS, {
|
||||
variables: { attributes: { type: RECORD_TYPE, service: SERVICE_TYPE } }
|
||||
}));
|
||||
|
||||
if (!wnsResponse || !ipfsResponse) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const ipfsData = JSON.parse(ipfsResponse.ipfs_status.json);
|
||||
const registeredServers = JSON.parse(wnsResponse.wns_records.json);
|
||||
|
||||
const displayServers = registeredServers.map((service) => {
|
||||
console.error(service);
|
||||
const addresses = get(service, 'attributes.ipfs.addresses');
|
||||
let connected = false;
|
||||
for (const address of addresses) {
|
||||
const parts = address.split('/');
|
||||
const nodeId = parts[parts.length - 1];
|
||||
connected = !!ipfsData.swarm.peers.find(({ peer }) => peer === nodeId);
|
||||
if (connected) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
name: get(service, 'name'),
|
||||
version: get(service, 'version'),
|
||||
description: get(service, 'attributes.description'),
|
||||
ipfs: get(service, 'attributes.ipfs'),
|
||||
connected
|
||||
};
|
||||
});
|
||||
|
||||
displayServers.sort((a, b) => {
|
||||
return a.connected && !b.connected ? -1 : b.connected && !a.connected ? 1 : b.name < a.name ? 1 : -1;
|
||||
});
|
||||
|
||||
if (displayServers.length === 0) {
|
||||
displayServers.push({ name: 'None' });
|
||||
}
|
||||
|
||||
return (
|
||||
<Panel
|
||||
toolbar={
|
||||
<Toolbar />
|
||||
}
|
||||
>
|
||||
<Json data={JSON.parse(data.ipfs_status.json)} />
|
||||
<h4 className={classes.caption}>WNS-registered IPFS Servers</h4>
|
||||
<Table stickyHeader size='small' className={classes.table}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell size=''>Identifier</TableCell>
|
||||
<TableCell size='small'>Description</TableCell>
|
||||
<TableCell size='small'>Connected</TableCell>
|
||||
<TableCell>Address</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{displayServers.map(({ name, description, ipfs, connected }) => (
|
||||
<TableRow key={name}>
|
||||
<TableCell>{name}</TableCell>
|
||||
<TableCell>{description}</TableCell>
|
||||
<TableCell>
|
||||
<BooleanIcon yes={connected} />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{ipfs.addresses}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
|
||||
<h4 className={classes.caption}>Local IPFS Server</h4>
|
||||
<Json data={{
|
||||
id: ipfsData.id.id,
|
||||
version: ipfsData.id.agentVersion,
|
||||
addresses: ipfsData.id.addresses,
|
||||
peers: ipfsData.swarm.peers.length,
|
||||
numObjects: ipfsData.repo.stats.numObjects,
|
||||
repoSize: ipfsData.repo.stats.repoSize
|
||||
}}
|
||||
/>
|
||||
</Panel>
|
||||
);
|
||||
};
|
||||
|
@ -1,10 +0,0 @@
|
||||
#
|
||||
# Copyright 2020 DxOS.org
|
||||
#
|
||||
|
||||
mutation ($command: String!) {
|
||||
wns_action(command: $command) {
|
||||
timestamp
|
||||
code
|
||||
}
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
#
|
||||
# Copyright 2020 DxOS.org
|
||||
# Copyright 2019 Wireline, Inc.
|
||||
#
|
||||
|
||||
query ($type: String) {
|
||||
wns_records (type: $type) @client {
|
||||
# TODO(telackey): Object would probably not be legal in general, but does work for a '@client' resolved query.
|
||||
# When we do strong typing across the board we should replace it with something like KeyValueInput.
|
||||
query ($attributes: Object) {
|
||||
wns_records (attributes: $attributes) @client {
|
||||
timestamp
|
||||
json
|
||||
}
|
||||
|
@ -43,16 +43,17 @@ export const createResolvers = config => {
|
||||
};
|
||||
},
|
||||
|
||||
wns_records: async (_, { type }) => {
|
||||
wns_records: async (_, { attributes }) => {
|
||||
console.error(attributes);
|
||||
log('WNS records...');
|
||||
const data = await registry.queryRecords({ type });
|
||||
const data = await registry.queryRecords(attributes);
|
||||
|
||||
return {
|
||||
__typename: 'JSONResult',
|
||||
timestamp: timestamp(),
|
||||
|
||||
// NOTE: Hack since this should be a string according to the schema.
|
||||
json: data
|
||||
json: JSON.stringify(data)
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"build": {
|
||||
"name": "@dxos/console-app",
|
||||
"buildDate": "2020-06-08T18:45:46.717Z",
|
||||
"buildDate": "2020-06-08T23:14:00.921Z",
|
||||
"version": "1.0.0-beta.0"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user