1
0
mirror of https://github.com/oceanprotocol/commons.git synced 2023-03-15 18:03:00 +01:00

Merge pull request #160 from oceanprotocol/feature/versions-squid-js

Refactor VersionNumbers to be sourced from squid-js
This commit is contained in:
Matthias Kretschmann 2019-06-19 15:45:46 +02:00 committed by GitHub
commit 18f7ab7ddc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 596 additions and 328 deletions

View File

@ -31,6 +31,34 @@ const oceanMock = {
}
}
}
},
versions: {
get: jest.fn(() =>
Promise.resolve({
squid: {
name: 'Squid-js',
status: 'Working'
},
aquarius: {
name: 'Aquarius',
status: 'Working'
},
brizo: {
name: 'Brizo',
network: 'Nile',
status: 'Working',
contracts: {
hello: 'hello',
hello2: 'hello2'
}
},
status: {
ok: true,
network: true,
contracts: true
}
})
)
}
}
}

View File

@ -1296,14 +1296,14 @@
"integrity": "sha512-nOpbSE/BG+tQBfLXZ/EqSOvUPzOuot84vHxjAfEU8K3v4eOnqFJVo+oyB7KlcF87wBJXDmi/Ir9qHY4c0Saipg=="
},
"@oceanprotocol/squid": {
"version": "0.5.14",
"resolved": "https://registry.npmjs.org/@oceanprotocol/squid/-/squid-0.5.14.tgz",
"integrity": "sha512-LyJ9Dv3kJD/th7bqk5iTqDNlQfidy4j5bTcLbzCIFvzFqPztTCWRON01G52z1A1jCYXBhtncX2jzwaOZDdmxsg==",
"version": "0.5.17",
"resolved": "https://registry.npmjs.org/@oceanprotocol/squid/-/squid-0.5.17.tgz",
"integrity": "sha512-yoZCKQ/QoOxgnhTHZFdeMknTRCktPZxSe/2ooDkf7ICaqwbVXMYspkMO+SDLQ+PAYncP4IZYVjr513ZkbQBYZw==",
"requires": {
"@oceanprotocol/keeper-contracts": "^0.9.7",
"bignumber.js": "^8.1.1",
"deprecated-decorator": "^0.1.6",
"node-fetch": "^2.3.0",
"node-fetch": "^2.6.0",
"save-file": "^2.3.1",
"uuid": "^3.3.2",
"web3": "1.0.0-beta.37",
@ -12892,7 +12892,6 @@
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
"integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
"dev": true,
"requires": {
"performance-now": "^2.1.0"
}
@ -12982,6 +12981,15 @@
}
}
},
"react-collapsed": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/react-collapsed/-/react-collapsed-2.0.1.tgz",
"integrity": "sha512-ullymRST/C5iy0szhxpYmIaLUhi+IC8EpFySmUjttoc+ErotaKAx+z1ff0d2PCJF7ksW8crTiOrIwGtFqYw3Tg==",
"requires": {
"@babel/runtime": "^7.3.1",
"raf": "^3.4.0"
}
},
"react-datepicker": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-2.6.0.tgz",

View File

@ -13,7 +13,7 @@
},
"dependencies": {
"@oceanprotocol/art": "^2.2.0",
"@oceanprotocol/squid": "^0.5.14",
"@oceanprotocol/squid": "^0.5.17",
"@oceanprotocol/typographies": "^0.1.0",
"@sindresorhus/slugify": "^0.9.1",
"axios": "^0.19.0",
@ -25,6 +25,7 @@
"moment": "^2.24.0",
"query-string": "^6.5.0",
"react": "^16.8.6",
"react-collapsed": "^2.0.1",
"react-datepicker": "^2.5.0",
"react-dom": "^16.8.6",
"react-dotdotdot": "^1.3.0",

View File

@ -0,0 +1 @@
declare module 'react-collapsed'

View File

@ -0,0 +1,22 @@
@import '../../../styles/variables';
.spinner {
composes: spinner, small from '../../atoms/Spinner.module.scss';
margin-right: $spacer;
}
.commit {
margin-left: $spacer / 8;
code {
color: $brand-grey-light;
font-size: $font-size-mini;
}
}
.network {
color: $brand-grey-light;
text-transform: capitalize;
margin-left: $spacer / 8;
font-size: $font-size-mini;
}

View File

@ -0,0 +1,23 @@
import React from 'react'
import { render } from '@testing-library/react'
import VersionNumber from './VersionNumber'
describe('VersionNumber', () => {
it('renders without crashing', () => {
const { container } = render(<VersionNumber name="Commons" />)
expect(container.firstChild).toBeInTheDocument()
})
it('renders with all props set', () => {
const { container } = render(
<VersionNumber
name="Commons"
version="6.6.6"
network="Nile"
commit="xxxxxxxxxxx"
/>
)
expect(container.firstChild).toBeInTheDocument()
expect(container.firstChild).toHaveTextContent('6.6.6')
})
})

View File

@ -0,0 +1,53 @@
import React from 'react'
import { OceanPlatformTechStatus } from '@oceanprotocol/squid'
import slugify from '@sindresorhus/slugify'
import Spinner from '../../atoms/Spinner'
import styles from './VersionNumber.module.scss'
const VersionNumber = ({
name,
version,
network,
status,
commit
}: {
name: string
version?: string
network?: string
status?: OceanPlatformTechStatus
commit?: string
}) =>
version ? (
<>
<a
href={`https://github.com/oceanprotocol/${slugify(
name
)}/releases/tag/v${version}`}
title="Go to release on GitHub"
>
<code>v{version}</code>
</a>
{commit && (
<a
href={`https://github.com/oceanprotocol/${slugify(
name
)}/commit/${commit}`}
className={styles.commit}
title={`Go to commit ${commit} on GitHub`}
>
<code>{commit.substring(0, 7)}</code>
</a>
)}
{network && <span className={styles.network}>{` ${network}`}</span>}
</>
) : (
<span>
{status === OceanPlatformTechStatus.Loading ? (
<Spinner className={styles.spinner} small />
) : (
status || 'Could not get version'
)}
</span>
)
export default VersionNumber

View File

@ -0,0 +1,37 @@
@import '../../../styles/variables';
.status {
text-align: center;
padding-top: $spacer / 2;
padding-bottom: $spacer;
display: flex;
justify-content: space-between;
}
.element {
display: inline-block;
margin-left: $spacer / 2;
margin-right: $spacer / 2;
text-align: center;
}
.indicator,
.indicatorActive {
display: inline-block;
margin-right: $spacer / 4;
margin-bottom: -.1rem;
}
.indicator {
composes: statusIndicator from '../AccountStatus/Indicator.module.scss';
}
.indicatorActive {
composes: statusIndicatorActive from '../AccountStatus/Indicator.module.scss';
}
.indicatorLabel {
font-family: $font-family-title;
color: $brand-grey;
text-transform: capitalize;
}

View File

@ -0,0 +1,23 @@
import React from 'react'
import { render } from '@testing-library/react'
import VersionStatus from './VersionStatus'
describe('VersionStatus', () => {
it('renders without crashing', () => {
const { container } = render(
<VersionStatus
status={{ ok: false, contracts: false, network: false }}
/>
)
expect(container.firstChild).toBeInTheDocument()
})
it('renders true states', () => {
const { container } = render(
<VersionStatus
status={{ ok: true, contracts: false, network: false }}
/>
)
expect(container.firstChild).toBeInTheDocument()
})
})

View File

@ -0,0 +1,41 @@
import React from 'react'
import styles from './VersionStatus.module.scss'
const statusInfo: { [key: string]: string } = {
ok: 'Shows if connection to all component endpoints can be established.',
network: 'Shows if all components are on the same network.',
contracts: 'Shows if contracts loaded by components are the same version.'
}
const VersionStatus = ({
status
}: {
status: { ok: boolean; network: boolean; contracts: boolean }
}) => {
return (
<div className={styles.status}>
{Object.entries(status).map(([key, value]) => (
<div
className={styles.element}
key={key}
title={statusInfo[key]}
>
<span
className={
value === true
? styles.indicatorActive
: styles.indicator
}
>
{value}
</span>
<span className={styles.indicatorLabel}>
{key === 'ok' ? 'components' : key}
</span>
</div>
))}
</div>
)
}
export default VersionStatus

View File

@ -7,11 +7,9 @@
}
.table {
display: table;
border-top: 1px solid $brand-grey-lighter;
table {
display: table;
margin-left: $spacer;
width: calc(100% - #{$spacer});
margin-bottom: -1px;
@ -29,6 +27,7 @@
td {
padding: $spacer / 4 $spacer / 2;
vertical-align: top;
&:last-child {
text-align: right;
@ -53,7 +52,6 @@
}
}
.spinner {
composes: spinner, small from '../../atoms/Spinner.module.scss';
margin-right: $spacer;
.label {
min-width: 15rem;
}

View File

@ -0,0 +1,40 @@
import React from 'react'
import { render } from '@testing-library/react'
import { VersionTableContracts } from './VersionTable'
describe('VersionTableContracts', () => {
it('renders without crashing', () => {
const { container } = render(
<VersionTableContracts
contracts={{ hello: 'hello', hello2: 'hello2' }}
network="nile"
keeperVersion="6.6.6"
/>
)
expect(container.firstChild).toBeInTheDocument()
})
it('renders correct Submarine links', () => {
const { container, rerender } = render(
<VersionTableContracts
contracts={{ hello: 'hello', hello2: 'hello2' }}
network="duero"
keeperVersion="6.6.6"
/>
)
expect(container.querySelector('tr:last-child a').href).toMatch(
/submarine.duero.dev-ocean/
)
rerender(
<VersionTableContracts
contracts={{ hello: 'hello', hello2: 'hello2' }}
network="pacific"
keeperVersion="6.6.6"
/>
)
expect(container.querySelector('tr:last-child a').href).toMatch(
/submarine.pacific.dev-ocean/
)
})
})

View File

@ -1,116 +1,114 @@
import React, { Fragment } from 'react'
import { VersionNumbersState as VersionTableProps } from '.'
import React from 'react'
import { VersionNumbersState } from '.'
import VersionTableRow from './VersionTableRow'
import styles from './VersionTable.module.scss'
import slugify from '@sindresorhus/slugify'
import Spinner from '../../atoms/Spinner'
import VersionNumber from './VersionNumber'
const VersionTableContracts = ({
import {
serviceUri,
nodeUri,
aquariusUri,
brizoUri,
brizoAddress,
secretStoreUri,
faucetUri
} from '../../../config'
const commonsConfig = {
serviceUri,
nodeUri,
aquariusUri,
brizoUri,
brizoAddress,
secretStoreUri,
faucetUri
}
export const VersionTableContracts = ({
contracts,
network
network,
keeperVersion
}: {
contracts: any
contracts: {
[contractName: string]: string
}
network: string
keeperVersion?: string
}) => (
<table>
<tbody>
<tr>
<td>
<strong>Keeper Contracts</strong>
</td>
<td>
<VersionNumber
name={'Keeper Contracts'}
version={keeperVersion}
/>
</td>
</tr>
{contracts &&
Object.keys(contracts).map(key => {
const submarineLink = `https://submarine${
network === 'duero'
? '.duero'
: network === 'pacific'
? '.pacific'
: ''
}.dev-ocean.com/address/${contracts[key]}`
Object.keys(contracts)
// sort alphabetically
.sort((a, b) => a.localeCompare(b))
.map(key => {
const submarineLink = `https://submarine${
network === 'duero'
? '.duero'
: network === 'pacific'
? '.pacific'
: ''
}.dev-ocean.com/address/${contracts[key]}`
return (
<tr key={key}>
<td>
<span className={styles.label}>{key}</span>
</td>
<td>
<a href={submarineLink}>
<code>{contracts[key]}</code>
</a>
</td>
</tr>
)
})}
return (
<tr key={key}>
<td>
<code className={styles.label}>{key}</code>
</td>
<td>
<a href={submarineLink}>
<code>{contracts[key]}</code>
</a>
</td>
</tr>
)
})}
</tbody>
</table>
)
const VersionNumber = ({
isLoading,
software,
version,
network
}: {
isLoading: boolean
software: string
version: string
network: string
}) =>
isLoading ? (
<Spinner small className={styles.spinner} />
) : version ? (
<>
<a
href={`https://github.com/oceanprotocol/${slugify(
software
)}/releases/tag/v${version}`}
>
<code>v{version}</code>
</a>
{network && `(${network})`}
</>
) : (
<span>Could not get version</span>
)
const VersionTable = ({ data }: { data: VersionTableProps }) => (
<div className={styles.tableWrap}>
<table className={styles.table}>
<tbody>
{Object.entries(data).map(([key, value]) => (
<Fragment key={key}>
<tr key={key}>
<td>
<a
href={
value.software &&
`https://github.com/oceanprotocol/${slugify(
value.software
)}`
}
>
<strong>{value.software}</strong>
</a>
</td>
<td>
<VersionNumber
isLoading={value.isLoading}
software={value.software}
version={value.version}
network={value.network}
/>
</td>
</tr>
{key === 'keeperContracts' && data.brizo.contracts && (
<tr>
<td colSpan={2}>
<VersionTableContracts
contracts={data.brizo.contracts}
network={data.brizo.network}
/>
</td>
</tr>
)}
</Fragment>
))}
</tbody>
</table>
</div>
export const VersionTableCommons = () => (
<table>
<tbody>
{Object.entries(commonsConfig).map(([key, value]) => (
<tr key={key}>
<td>
<code className={styles.label}>{key}</code>
</td>
<td>
<code>{value}</code>
</td>
</tr>
))}
</tbody>
</table>
)
const VersionTable = ({ data }: { data: VersionNumbersState }) => {
return (
<div className={styles.tableWrap}>
<table className={styles.table}>
<tbody>
{Object.entries(data)
.filter(([key]) => key !== 'status')
.map(([key, value]) => (
<VersionTableRow key={key} value={value} />
))}
</tbody>
</table>
</div>
)
}
export default VersionTable

View File

@ -0,0 +1,15 @@
@import '../../../styles/variables';
.handle {
display: inline-block;
border: 0;
background: none;
box-shadow: none;
padding: 0;
margin: 0;
margin-left: -1rem;
margin-top: -.1rem;
padding-right: .5rem;
cursor: pointer;
color: $brand-grey-light;
}

View File

@ -0,0 +1,76 @@
import React from 'react'
import useCollapse from 'react-collapsed'
import slugify from '@sindresorhus/slugify'
import styles from './VersionTableRow.module.scss'
import { VersionTableContracts, VersionTableCommons } from './VersionTable'
import VersionNumber from './VersionNumber'
const VersionTableRow = ({ value }: { value: any }) => {
const collapseStyles = {
transitionDuration: '0.01s'
}
const expandStyles = {
transitionDuration: '0.01s',
transitionTimingFunction: 'ease-out'
}
const { getCollapseProps, getToggleProps, isOpen } = useCollapse({
collapseStyles,
expandStyles
})
return (
<>
<tr>
<td>
{(value.name === 'Commons' || value.contracts) && (
<button className={styles.handle} {...getToggleProps()}>
{isOpen ? (
<span>&#9660;</span>
) : (
<span>&#9658;</span>
)}
</button>
)}
<a
href={`https://github.com/oceanprotocol/${slugify(
value.name || value.software
)}`}
>
<strong>{value.name || value.software}</strong>
</a>
</td>
<td>
<VersionNumber
name={value.name || value.software}
version={value.version}
status={value.status}
network={value.network}
commit={value.commit}
/>
</td>
</tr>
{value.name === 'Commons' && (
<tr {...getCollapseProps()}>
<td colSpan={2}>
<VersionTableCommons />
</td>
</tr>
)}
{value.contracts && (
<tr {...getCollapseProps()}>
<td colSpan={2}>
<VersionTableContracts
contracts={value.contracts}
network={value.network || ''}
keeperVersion={value.keeperVersion}
/>
</td>
</tr>
)}
</>
)
}
export default VersionTableRow

View File

@ -1,90 +1,52 @@
import React from 'react'
import { render, waitForElement } from '@testing-library/react'
import { render } from '@testing-library/react'
import mockAxios from 'jest-mock-axios'
import { StateMock } from '@react-mock/state'
import { version as versionSquid } from '@oceanprotocol/squid/package.json'
import VersionNumbers, { commonsVersion } from '.'
import VersionNumbers from '.'
import { User } from '../../../context'
import { userMockConnected } from '../../../../__mocks__/user-mock'
afterEach(() => {
mockAxios.reset()
})
const stateMock = {
commons: { software: 'Commons', version: commonsVersion },
squidJs: {
software: 'Squid-js',
version: versionSquid
},
aquarius: {
isLoading: false,
software: 'Aquarius',
version: ''
},
brizo: {
isLoading: false,
software: 'Brizo',
version: '',
contracts: {},
network: '',
'keeper-version': '0.0.0',
'keeper-url': ''
},
keeperContracts: {
isLoading: false,
software: 'Keeper Contracts',
version: '',
contracts: {},
network: ''
},
faucet: {
isLoading: false,
software: 'Faucet',
version: ''
}
}
const stateMockIncomplete = {
commons: { software: 'Commons', version: commonsVersion },
squidJs: {
software: 'Squid-js',
version: versionSquid
commons: {
name: 'Commons',
version: undefined
},
squid: {
name: 'Squid-js',
version: undefined
},
aquarius: {
isLoading: false,
software: 'Aquarius',
name: 'Aquarius',
version: undefined
},
brizo: {
isLoading: false,
software: 'Brizo',
name: 'Brizo',
version: undefined,
contracts: undefined,
network: undefined,
'keeper-version': undefined,
'keeper-url': undefined
},
keeperContracts: {
isLoading: false,
software: 'Keeper Contracts',
version: undefined,
contracts: undefined,
network: undefined
keeperVersion: undefined,
keeperUrl: undefined
},
faucet: {
isLoading: false,
software: 'Faucet',
name: 'Faucet',
version: undefined
},
status: {
ok: false,
network: false,
contracts: false
}
}
const mockResponse = {
data: {
software: 'Brizo',
version: '6.6.6',
contracts: { Hello: 'Hello', Another: 'Hello' },
network: 'hello',
'keeper-url': 'https://squid.com',
'keeper-version': '6.6.6'
software: 'Faucet',
version: '6.6.6'
}
}
@ -97,9 +59,9 @@ const mockResponseFaulty = {
describe('VersionNumbers', () => {
it('renders without crashing', () => {
const { container } = render(
<StateMock state={stateMock}>
<User.Provider value={userMockConnected}>
<VersionNumbers />
</StateMock>
</User.Provider>
)
mockAxios.mockResponse(mockResponse)
expect(mockAxios.get).toHaveBeenCalled()
@ -108,9 +70,11 @@ describe('VersionNumbers', () => {
it('renders without proper component response', () => {
const { container } = render(
<StateMock state={stateMockIncomplete}>
<VersionNumbers />
</StateMock>
<User.Provider value={userMockConnected}>
<StateMock state={stateMockIncomplete}>
<VersionNumbers />
</StateMock>
</User.Provider>
)
mockAxios.mockResponse(mockResponseFaulty)
expect(mockAxios.get).toHaveBeenCalled()

View File

@ -1,56 +1,40 @@
import React, { PureComponent } from 'react'
import { Logger } from '@oceanprotocol/squid'
import {
OceanPlatformVersions,
OceanPlatformTechStatus,
Logger
} from '@oceanprotocol/squid'
import axios from 'axios'
import { version } from '../../../../package.json'
import { version as versionSquid } from '@oceanprotocol/squid/package.json'
import styles from './index.module.scss'
import { aquariusUri, brizoUri, faucetUri } from '../../../config'
import { nodeUri, faucetUri } from '../../../config'
import { User } from '../../../context'
import VersionTable from './VersionTable'
import { isJsonString } from './utils'
import VersionStatus from './VersionStatus'
// construct values which are not part of any response
export const commonsVersion =
process.env.NODE_ENV === 'production' ? version : `${version}-dev`
const commonsNetwork = new URL(nodeUri).hostname.split('.')[0]
const faucetNetwork = new URL(faucetUri).hostname.split('.')[1]
interface VersionNumbersProps {
minimal?: boolean
}
export interface VersionNumbersState {
export interface VersionNumbersState extends OceanPlatformVersions {
commons: {
software: string
version: string
}
squidJs: {
software: string
version: string
}
aquarius: {
isLoading: boolean
software: string
version: string
}
brizo: {
isLoading: boolean
software: string
name: string
version: string
network: string
'keeper-version': string
'keeper-url': string
contracts: any
}
keeperContracts: {
isLoading: boolean
software: string
version: string
network: string
contracts: any
}
faucet: {
isLoading: boolean
software?: string
version?: string
name: string
version: string
network: string
status: OceanPlatformTechStatus
}
}
@ -58,104 +42,72 @@ export default class VersionNumbers extends PureComponent<
VersionNumbersProps,
VersionNumbersState
> {
public state = {
commons: { software: 'Commons', version: commonsVersion },
squidJs: {
software: 'Squid-js',
version: versionSquid
public static contextType = User
// define a minimal default state to fill UI
public state: VersionNumbersState = {
commons: {
name: 'Commons',
network: commonsNetwork,
version: commonsVersion
},
squid: {
name: 'Squid-js',
status: OceanPlatformTechStatus.Loading
},
aquarius: {
isLoading: true,
software: 'Aquarius',
version: ''
name: 'Aquarius',
status: OceanPlatformTechStatus.Loading
},
brizo: {
isLoading: true,
software: 'Brizo',
version: '',
contracts: {} as any,
network: '',
'keeper-version': '0.0.0',
'keeper-url': ''
},
keeperContracts: {
isLoading: true,
software: 'Keeper Contracts',
version: '',
contracts: {} as any,
network: ''
name: 'Brizo',
status: OceanPlatformTechStatus.Loading
},
faucet: {
isLoading: true,
software: 'Faucet',
version: ''
name: 'Faucet',
version: '',
network: faucetNetwork,
status: OceanPlatformTechStatus.Loading
},
status: {
ok: false,
network: false,
contracts: false
}
}
// for canceling axios requests
public signal = axios.CancelToken.source()
public componentWillMount() {
this.setAquarius()
this.setBrizoAndKeeper()
this.setFaucet()
public async componentDidMount() {
this.getOceanVersions()
this.getFaucetVersion()
}
public componentWillUnmount() {
this.signal.cancel()
}
private async setAquarius() {
const aquarius = await this.getData(aquariusUri)
aquarius &&
aquarius.version !== undefined &&
this.setState({ aquarius: { isLoading: false, ...aquarius } })
private async getOceanVersions() {
const { ocean } = this.context
// wait until ocean object is properly populated
if (ocean.versions === undefined) return
const response = await ocean.versions.get()
const { squid, brizo, aquarius, status } = response
this.setState({
...this.state,
squid,
brizo,
aquarius,
status
})
}
private async setBrizoAndKeeper() {
const brizo = await this.getData(brizoUri)
const keeperVersion =
brizo['keeper-version'] && brizo['keeper-version'].replace('v', '')
const keeperNetwork =
brizo['keeper-url'] &&
new URL(brizo['keeper-url']).hostname.split('.')[0]
brizo &&
brizo.version !== undefined &&
this.setState({
brizo: {
isLoading: false,
...brizo
},
keeperContracts: {
...this.state.keeperContracts,
isLoading: false,
version: keeperVersion,
contracts: brizo.contracts,
network: keeperNetwork
}
})
}
private async setFaucet() {
const faucet = await this.getData(faucetUri)
// backwards compatibility
isJsonString(faucet) === false &&
this.setState({
faucet: { ...this.state.faucet, isLoading: false }
})
// the new thing
faucet &&
faucet.version !== undefined &&
this.setState({ faucet: { isLoading: false, ...faucet } })
}
private async getData(uri: string) {
private async getFaucetVersion() {
try {
const response = await axios.get(uri, {
const response = await axios.get(faucetUri, {
headers: { Accept: 'application/json' },
cancelToken: this.signal.token
})
@ -163,35 +115,47 @@ export default class VersionNumbers extends PureComponent<
// fail silently
if (response.status !== 200) return
return response.data
this.setState({
...this.state,
faucet: {
...this.state.faucet,
version: response.data.version,
status: OceanPlatformTechStatus.Working
}
})
} catch (error) {
!axios.isCancel(error) && Logger.error(error.message)
}
}
public render() {
const { minimal } = this.props
const { commons, squidJs, brizo, aquarius, faucet } = this.state
private MinimalOutput = () => {
const { commons, squid, brizo, aquarius } = this.state
const mimimalOutput = `${squidJs.software} v${squidJs.version} \n${
brizo.software
} v${brizo.version} \n${aquarius.software} v${
aquarius.version
} \nKeeper Contracts ${brizo['keeper-version']} \n${faucet.software} v${
faucet.version
}`
return minimal ? (
return (
<p className={styles.versionsMinimal}>
<a title={mimimalOutput} href={'/about'}>
v{commons.version} {brizo.network && `(${brizo.network})`}
<a
title={`${squid.name} v${squid.version}\n${brizo.name} v${
brizo.version
}\n${aquarius.name} v${aquarius.version}`}
href={'/about'}
>
v{commons.version} {squid.network && `(${squid.network})`}
</a>
</p>
)
}
public render() {
const { minimal } = this.props
return minimal ? (
<this.MinimalOutput />
) : (
<div className={styles.versions} id="#oceanversions">
<h2 className={styles.versionsTitle}>
Ocean Components in use
Ocean Components Status
</h2>
<VersionStatus status={this.state.status} />
<VersionTable data={this.state} />
</div>
)

View File

@ -1,11 +0,0 @@
import { isJsonString } from './utils'
describe('isJsonString', () => {
it('detects json correctly', () => {
const testJson = isJsonString('{ "hello": "squid" }')
expect(testJson).toBeTruthy()
const testNonJson = isJsonString('<strong>')
expect(testNonJson).toBeFalsy()
})
})

View File

@ -1,8 +0,0 @@
export function isJsonString(str: string) {
try {
JSON.parse(str)
} catch (e) {
return false
}
return true
}

View File

@ -239,11 +239,6 @@ table {
width: 100%;
margin-bottom: $spacer * $line-height;
border-collapse: collapse;
display: block;
// make 'em scrollable
overflow: auto;
-webkit-overflow-scrolling: touch;
th,
td {

View File

@ -19,7 +19,7 @@
},
{
"name": "squid-js",
"version": "~0.5.14"
"version": "~0.5.17"
},
{
"name": "faucet",