WNS info links
This commit is contained in:
parent
c831181c1d
commit
432c061952
42
packages/console-app/src/components/AppLink.js
Normal file
42
packages/console-app/src/components/AppLink.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2020 DxOS.org.org
|
||||||
|
//
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import Link from '@material-ui/core/Link';
|
||||||
|
|
||||||
|
import { getServiceUrl } from '../util/config';
|
||||||
|
|
||||||
|
const getAppUrl = (config, { name, version, text }) => {
|
||||||
|
const base = getServiceUrl(config, 'app.server');
|
||||||
|
const pathComponents = [base];
|
||||||
|
|
||||||
|
// TODO(burdon): Fix.
|
||||||
|
// `wire app serve` expects the /wrn/ prefix.
|
||||||
|
// That is OK in the production config where we can make it part of the the route,
|
||||||
|
// but in development it must be prepended since we don't want to make it part of services.app.server.
|
||||||
|
if (!base.startsWith(`/${config.services.app.prefix}`) && !base.endsWith(`/${config.services.app.prefix}`)) {
|
||||||
|
pathComponents.push(config.services.app.prefix.substring(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version) {
|
||||||
|
pathComponents.push(`${name}@${version}`);
|
||||||
|
} else {
|
||||||
|
pathComponents.push(name);
|
||||||
|
}
|
||||||
|
return `${pathComponents.join('/')}/`;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render link to record in WNS.
|
||||||
|
* @param {Object} config
|
||||||
|
* @param {string} name
|
||||||
|
* @param {string} [text]
|
||||||
|
* @param {string} [version]
|
||||||
|
*/
|
||||||
|
const AppLink = ({ config, name, version, text }) => {
|
||||||
|
const fullURL = getAppUrl(config, {name, version});
|
||||||
|
return <Link href={fullURL} target={name}>{text || name}</Link>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppLink;
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from '@material-ui/core/Link';
|
import Link from '@material-ui/core/Link';
|
||||||
|
import Menu from '@material-ui/core/Menu';
|
||||||
|
import MenuItem from '@material-ui/core/MenuItem';
|
||||||
|
|
||||||
import { getServiceUrl } from '../util/config';
|
import { getServiceUrl } from '../util/config';
|
||||||
|
|
||||||
@ -12,12 +14,13 @@ import { getServiceUrl } from '../util/config';
|
|||||||
* @param {Object} config
|
* @param {Object} config
|
||||||
* @param {string} [type]
|
* @param {string} [type]
|
||||||
* @param {string} pkg
|
* @param {string} pkg
|
||||||
|
* @param {string} [text]
|
||||||
*/
|
*/
|
||||||
const PackageLink = ({ config, type, pkg }) => {
|
const PackageLink = ({ config, type, pkg, text }) => {
|
||||||
// TODO(burdon): Pass in expected arg types.
|
// TODO(burdon): Pass in expected arg types.
|
||||||
if (typeof pkg === 'string') {
|
if (typeof pkg === 'string') {
|
||||||
const ipfsUrl = getServiceUrl(config, 'ipfs.gateway', { path: `${pkg}` });
|
const ipfsUrl = getServiceUrl(config, 'ipfs.gateway', { path: `${pkg}` });
|
||||||
return <Link href={ipfsUrl} target='ipfs'>{pkg}</Link>;
|
return <Link href={ipfsUrl} target='ipfs'>{text || pkg}</Link>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line default-case
|
// eslint-disable-next-line default-case
|
||||||
@ -28,16 +31,17 @@ const PackageLink = ({ config, type, pkg }) => {
|
|||||||
Object.keys(pkg[platform]).forEach(arch => {
|
Object.keys(pkg[platform]).forEach(arch => {
|
||||||
const cid = pkg[platform][arch];
|
const cid = pkg[platform][arch];
|
||||||
const ipfsUrl = getServiceUrl(config, 'ipfs.gateway', { path: `${cid}` });
|
const ipfsUrl = getServiceUrl(config, 'ipfs.gateway', { path: `${cid}` });
|
||||||
|
|
||||||
packageLinks.push(
|
packageLinks.push(
|
||||||
|
<div>
|
||||||
<Link
|
<Link
|
||||||
key={`${cid}`}
|
key={`${cid}`}
|
||||||
href={ipfsUrl}
|
href={ipfsUrl}
|
||||||
title={cid}
|
title={cid}
|
||||||
target='ipfs'
|
target='ipfs'
|
||||||
>
|
>
|
||||||
{platform}/{arch}: {cid}
|
{platform}/{arch}
|
||||||
</Link>
|
</Link>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
38
packages/console-app/src/components/QueryLink.js
Normal file
38
packages/console-app/src/components/QueryLink.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2020 DxOS.org.org
|
||||||
|
//
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import ExitToApp from '@material-ui/icons/ExitToApp';
|
||||||
|
import Link from '@material-ui/core/Link';
|
||||||
|
|
||||||
|
import { getServiceUrl } from '../util/config';
|
||||||
|
|
||||||
|
const QUERY = `{
|
||||||
|
queryRecords(attributes: [
|
||||||
|
{ key: "name", value: { string: "%NAME%" }}]) {
|
||||||
|
id type name bondId createTime expiryTime owners attributes { key, value { string, json } }
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render link to record in WNS.
|
||||||
|
* @param {Object} config
|
||||||
|
* @param {string} name
|
||||||
|
* @param {string} [text]
|
||||||
|
*/
|
||||||
|
const QueryLink = ({ config, name, text, icon = false}) => {
|
||||||
|
const baseURL = getServiceUrl(config, 'wns.webui');
|
||||||
|
const query = QUERY.replace('%NAME%', name);
|
||||||
|
const fullURL= encodeURI(`${baseURL}?query=${query}`);
|
||||||
|
|
||||||
|
if (icon) {
|
||||||
|
return <Link href={fullURL} target='wns'>
|
||||||
|
<ExitToApp />
|
||||||
|
</Link>
|
||||||
|
}
|
||||||
|
return <Link href={fullURL} target='wns'>{text || name}</Link>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default QueryLink;
|
@ -11,6 +11,12 @@ import { makeStyles } from '@material-ui/core';
|
|||||||
const useStyles = makeStyles(() => ({
|
const useStyles = makeStyles(() => ({
|
||||||
small: {
|
small: {
|
||||||
width: 160
|
width: 160
|
||||||
|
},
|
||||||
|
medium: {
|
||||||
|
width: 220
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
width: 120
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ import { BooleanIcon } from '../../../components/BooleanIcon';
|
|||||||
import Table from '../../../components/Table';
|
import Table from '../../../components/Table';
|
||||||
import TableCell from '../../../components/TableCell';
|
import TableCell from '../../../components/TableCell';
|
||||||
import { getServiceUrl } from '../../../util/config';
|
import { getServiceUrl } from '../../../util/config';
|
||||||
|
import AppLink from "../../../components/AppLink";
|
||||||
|
|
||||||
const AppRecords = () => {
|
const AppRecords = () => {
|
||||||
const { config } = useContext(ConsoleContext);
|
const { config } = useContext(ConsoleContext);
|
||||||
@ -41,27 +42,6 @@ const AppRecords = () => {
|
|||||||
|
|
||||||
const localRefs = new Set(ipfsData.refs.local);
|
const localRefs = new Set(ipfsData.refs.local);
|
||||||
|
|
||||||
// TODO(burdon): Test if app is deployed.
|
|
||||||
const getAppUrl = ({ name, version }) => {
|
|
||||||
const base = getServiceUrl(config, 'app.server');
|
|
||||||
const pathComponents = [base];
|
|
||||||
|
|
||||||
// TODO(burdon): Fix.
|
|
||||||
// `wire app serve` expects the /wrn/ prefix.
|
|
||||||
// That is OK in the production config where we can make it part of the the route,
|
|
||||||
// but in development it must be prepended since we don't want to make it part of services.app.server.
|
|
||||||
if (!base.startsWith(`/${config.services.app.prefix}`) && !base.endsWith(`/${config.services.app.prefix}`)) {
|
|
||||||
pathComponents.push(config.services.app.prefix.substring(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version) {
|
|
||||||
pathComponents.push(`${name}@${version}`);
|
|
||||||
} else {
|
|
||||||
pathComponents.push(name);
|
|
||||||
}
|
|
||||||
return `${pathComponents.join('/')}/`;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Table>
|
<Table>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
@ -70,22 +50,19 @@ const AppRecords = () => {
|
|||||||
<TableCell onClick={sortBy('attributes.displayName')}>Name</TableCell>
|
<TableCell onClick={sortBy('attributes.displayName')}>Name</TableCell>
|
||||||
<TableCell onClick={sortBy('version')} size='small'>Version</TableCell>
|
<TableCell onClick={sortBy('version')} size='small'>Version</TableCell>
|
||||||
<TableCell onClick={sortBy('createTime')} size='small'>Created</TableCell>
|
<TableCell onClick={sortBy('createTime')} size='small'>Created</TableCell>
|
||||||
<TableCell size='small'>Downloaded</TableCell>
|
<TableCell size='icon'>Downloaded</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{appData.sort(sorter).map(({ id, name, version, createTime, attributes: { displayName, publicUrl, package: hash } }) => {
|
{appData.sort(sorter).map(({ id, name, version, createTime, attributes: { displayName, publicUrl, package: hash } }) => {
|
||||||
const verLink = getAppUrl({ id, name, version, publicUrl });
|
|
||||||
const appLink = getAppUrl({ id, name, publicUrl });
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableRow key={id} size='small'>
|
<TableRow key={id} size='small'>
|
||||||
<TableCell monospace>
|
<TableCell monospace>
|
||||||
<Link href={appLink} target={name}>{name}</Link>
|
<AppLink config={config} name={name} />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>{displayName}</TableCell>
|
<TableCell>{displayName}</TableCell>
|
||||||
<TableCell monospace>
|
<TableCell monospace>
|
||||||
<Link href={verLink} target={version}>{version}</Link>
|
<AppLink config={config} name={name} version={version} text={version} />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>{moment.utc(createTime).fromNow()}</TableCell>
|
<TableCell>{moment.utc(createTime).fromNow()}</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
|
@ -122,9 +122,9 @@ const IPFS = () => {
|
|||||||
<Table stickyHeader size='small' className={classes.table}>
|
<Table stickyHeader size='small' className={classes.table}>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell size=''>Identifier</TableCell>
|
<TableCell>Identifier</TableCell>
|
||||||
<TableCell size='small'>Description</TableCell>
|
<TableCell size='medium'>Description</TableCell>
|
||||||
<TableCell size='small'>Connected</TableCell>
|
<TableCell size='icon'>Connected</TableCell>
|
||||||
<TableCell>Address</TableCell>
|
<TableCell>Address</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
@ -11,6 +11,7 @@ import Button from '@material-ui/core/Button';
|
|||||||
import TableHead from '@material-ui/core/TableHead';
|
import TableHead from '@material-ui/core/TableHead';
|
||||||
import TableRow from '@material-ui/core/TableRow';
|
import TableRow from '@material-ui/core/TableRow';
|
||||||
import TableBody from '@material-ui/core/TableBody';
|
import TableBody from '@material-ui/core/TableBody';
|
||||||
|
import Tooltip from '@material-ui/core/Tooltip';
|
||||||
|
|
||||||
import WNS_RECORDS from '../../../gql/wns_records.graphql';
|
import WNS_RECORDS from '../../../gql/wns_records.graphql';
|
||||||
|
|
||||||
@ -20,6 +21,8 @@ import Table from '../../../components/Table';
|
|||||||
import TableCell from '../../../components/TableCell';
|
import TableCell from '../../../components/TableCell';
|
||||||
|
|
||||||
import PackageLink from '../../../components/PackageLink';
|
import PackageLink from '../../../components/PackageLink';
|
||||||
|
import QueryLink from "../../../components/QueryLink";
|
||||||
|
import AppLink from "../../../components/AppLink";
|
||||||
|
|
||||||
const types = [
|
const types = [
|
||||||
{ key: null, label: 'ALL' },
|
{ key: null, label: 'ALL' },
|
||||||
@ -67,14 +70,14 @@ const WNSRecords = ({ type }) => {
|
|||||||
const [sorter, sortBy] = useSorter('createTime', false);
|
const [sorter, sortBy] = useSorter('createTime', false);
|
||||||
const data = useQueryStatusReducer(useQuery(WNS_RECORDS, {
|
const data = useQueryStatusReducer(useQuery(WNS_RECORDS, {
|
||||||
pollInterval: config.api.intervalQuery,
|
pollInterval: config.api.intervalQuery,
|
||||||
variables: { type }
|
variables: { attributes: { type } }
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const records = data.wns_records.json;
|
const records = JSON.parse(data.wns_records.json);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Table>
|
<Table>
|
||||||
@ -82,28 +85,51 @@ const WNSRecords = ({ type }) => {
|
|||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell onClick={sortBy('type')} size='small'>Type</TableCell>
|
<TableCell onClick={sortBy('type')} size='small'>Type</TableCell>
|
||||||
<TableCell onClick={sortBy('name')}>Identifier</TableCell>
|
<TableCell onClick={sortBy('name')}>Identifier</TableCell>
|
||||||
|
<TableCell size='icon'>Query</TableCell>
|
||||||
|
<TableCell onClick={sortBy('attributes.displayName')}>Name</TableCell>
|
||||||
<TableCell onClick={sortBy('version')} size='small'>Version</TableCell>
|
<TableCell onClick={sortBy('version')} size='small'>Version</TableCell>
|
||||||
<TableCell onClick={sortBy('createTime')} size='small'>Created</TableCell>
|
<TableCell onClick={sortBy('createTime')} size='small'>Created</TableCell>
|
||||||
<TableCell onClick={sortBy('attributes.displayName')}>Name</TableCell>
|
<TableCell onClick={sortBy('package')} size='small'>Package</TableCell>
|
||||||
<TableCell onClick={sortBy('attributes.package')}>Package Hash</TableCell>
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{records.sort(sorter)
|
{records.sort(sorter)
|
||||||
.map(({ id, type, name, version, createTime, attributes: { displayName, package: pkg } }) => (
|
.map((record) => {
|
||||||
<TableRow key={id} size='small'>
|
const { id, type, name, version, createTime, attributes: { displayName, description, service, package: pkg } } = record;
|
||||||
|
|
||||||
|
let pkgLink = undefined;
|
||||||
|
let appLink = undefined;
|
||||||
|
let verLink = undefined;
|
||||||
|
|
||||||
|
if (pkg) {
|
||||||
|
pkgLink = (<PackageLink config={config} type={type} pkg={pkg}/>);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'wrn:app') {
|
||||||
|
appLink = (<AppLink config={config} name={name}/>);
|
||||||
|
verLink = (<AppLink config={config} name={name} version={version} text={version}/>);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (<TableRow key={id} size='small'>
|
||||||
<TableCell monospace>{type}</TableCell>
|
<TableCell monospace>{type}</TableCell>
|
||||||
<TableCell monospace>{name}</TableCell>
|
<TableCell monospace>
|
||||||
<TableCell monospace>{version}</TableCell>
|
{appLink && appLink || name}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<QueryLink config={config} name={name} icon={true}/>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>{displayName || service || description}</TableCell>
|
||||||
|
<TableCell monospace>
|
||||||
|
{verLink && verLink || version}
|
||||||
|
</TableCell>
|
||||||
<TableCell>{moment.utc(createTime).fromNow()}</TableCell>
|
<TableCell>{moment.utc(createTime).fromNow()}</TableCell>
|
||||||
<TableCell>{displayName}</TableCell>
|
<TableCell monospace>
|
||||||
<TableCell title={JSON.stringify(pkg)} monospace>
|
{pkgLink}
|
||||||
{pkg && (
|
|
||||||
<PackageLink config={config} type={type} pkg={pkg} />
|
|
||||||
)}
|
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
);
|
||||||
|
}
|
||||||
|
)}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user