mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Merge pull request #30 from oceanprotocol/feature/v3
Remove the old, add the new Ocean
This commit is contained in:
commit
74e2f95444
37
.env.example
37
.env.example
@ -1,26 +1,15 @@
|
|||||||
#Spree config
|
GATSBY_INFURA_PROJECT_ID="xxx"
|
||||||
NODE_URI='http://localhost:8545'
|
|
||||||
AQUARIUS_URI='http://aquarius:5000'
|
|
||||||
BRIZO_URI='http://localhost:8030'
|
|
||||||
BRIZO_ADDRESS='0x068ed00cf0441e4829d9784fcbe7b9e26d4bd8d0'
|
|
||||||
SECRET_STORE_URI='http://localhost:12001'
|
|
||||||
FAUCET_URI='https://localhost:3001'
|
|
||||||
RATING_URI='http://localhost:8000'
|
|
||||||
|
|
||||||
#Nile market
|
# Local config
|
||||||
#NODE_URI='https://nile.dev-ocean.com'
|
GATSBY_NODE_URI='http://localhost:8545'
|
||||||
#AQUARIUS_URI='https://aquarius.nile.market.dev-ocean.com'
|
GATSBY_METADATA_STORE_URI='http://aquarius:5000'
|
||||||
#BRIZO_URI='https://brizo.nile.market.dev-ocean.com'
|
GATSBY_PROVIDER_URI='http://localhost:8030'
|
||||||
#BRIZO_ADDRESS='0xeD792C5FcC8bF3322a6ba89A6e51eF0B6fB3C530'
|
GATSBY_FACTORY_ADDRESS='0xxxx'
|
||||||
#SECRET_STORE_URI='https://secret-store.nile.dev-ocean.com'
|
#GATSBY_OCEAN_TOKEN_ADDRESS='0xxxx'
|
||||||
#FAUCET_URI='https://faucet.nile.dev-ocean.com'
|
|
||||||
#RATING_URI='https://rating.nile.market.dev-ocean.com'
|
|
||||||
|
|
||||||
#Pacific market
|
# Rinkeby
|
||||||
#NODE_URI='https://pacific.oceanprotocol.com'
|
#GATSBY_NODE_URI='https://rinkeby.infura.io/v3/GATSBY_INFURA_PROJECT_ID'
|
||||||
#AQUARIUS_URI='https://aquarius.pacific.market.dev-ocean.com'
|
#GATSBY_METADATA_STORE_URI='https://aquarius.rinkeby.v3.dev-ocean.com'
|
||||||
#BRIZO_URI='https://brizo.pacific.market.dev-ocean.com'
|
#GATSBY_PROVIDER_URI='https://provider.rinkeby.v3.dev-ocean.com'
|
||||||
#BRIZO_ADDRESS='0xeD792C5FcC8bF3322a6ba89A6e51eF0B6fB3C530'
|
#GATSBY_FACTORY_ADDRESS='0xB9d406D24B310A7D821D0b782a36909e8c925471'
|
||||||
#SECRET_STORE_URI='https://secret-store.oceanprotocol.com'
|
#GATSBY_OCEAN_TOKEN_ADDRESS='0xf6AE724aD6e6Fa89B6aBc9710C5eb692b7F57139'
|
||||||
#FAUCET_URI='https://faucet.oceanprotocol.com'
|
|
||||||
#RATING_URI='https://rating.pacific.market.dev-ocean.com'
|
|
||||||
|
11
README.md
11
README.md
@ -174,13 +174,12 @@ vercel alias
|
|||||||
|
|
||||||
## 🏗 Ocean Protocol Infrastructure
|
## 🏗 Ocean Protocol Infrastructure
|
||||||
|
|
||||||
The following Aquarius & Brizo instances specifically for marketplace are deployed in Ocean Protocol's AWS K8:
|
The following Metadata Store & Provider instances specifically for marketplace are deployed in Ocean Protocol's AWS K8:
|
||||||
|
|
||||||
**Nile (Staging)**
|
**Rinkeby (Staging)**
|
||||||
|
|
||||||
- K8 namespace: `market-nile`
|
- `[aquarius.rinkeby.v3.dev-ocean.com](https://aquarius.rinkeby.v3.dev-ocean.com)`
|
||||||
- `aquarius.nile.market.dev-ocean.com`
|
- `[provider.rinkeby.v3.dev-ocean.com](https://provider.rinkeby.v3.dev-ocean.com)`
|
||||||
- `brizo.nile.market.dev-ocean.com`
|
|
||||||
|
|
||||||
Edit command with `kubectl`, e.g.:
|
Edit command with `kubectl`, e.g.:
|
||||||
|
|
||||||
@ -188,7 +187,7 @@ Edit command with `kubectl`, e.g.:
|
|||||||
kubectl edit deployment -n market-nile aquarius
|
kubectl edit deployment -n market-nile aquarius
|
||||||
```
|
```
|
||||||
|
|
||||||
**Pacific (Production)**
|
**Main (Production)**
|
||||||
|
|
||||||
- K8 namespace: `market-pacific`
|
- K8 namespace: `market-pacific`
|
||||||
- `aquarius.pacific.market.dev-ocean.com`
|
- `aquarius.pacific.market.dev-ocean.com`
|
||||||
|
@ -1,19 +1,24 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
oceanConfig: {
|
oceanConfig: {
|
||||||
nodeUri: process.env.NODE_URI || 'https://pacific.oceanprotocol.com',
|
nodeUri:
|
||||||
aquariusUri:
|
process.env.GATSBY_NODE_URI ||
|
||||||
process.env.AQUARIUS_URI ||
|
`https://rinkeby.infura.io/${process.env.GATSBY_INFURA_PROJECT_ID}`,
|
||||||
'https://aquarius.marketplace.oceanprotocol.com',
|
metadataStoreUri:
|
||||||
brizoUri:
|
process.env.GATSBY_METADATA_STORE_URI ||
|
||||||
process.env.BRIZO_URI || 'https://brizo.marketplace.oceanprotocol.com',
|
'https://aquarius.rinkeby.v3.dev-ocean.com',
|
||||||
brizoAddress:
|
providerUri:
|
||||||
process.env.BRIZO_ADDRESS || '0x00c6A0BC5cD0078d6Cd0b659E8061B404cfa5704',
|
process.env.GATSBY_PROVIDER_URI ||
|
||||||
secretStoreUri:
|
'https://provider.rinkeby.v3.dev-ocean.com',
|
||||||
process.env.SECRET_STORE_URI || 'https://secret-store.oceanprotocol.com',
|
factoryAddress:
|
||||||
faucetUri: process.env.FAUCET_URI || 'https://faucet.oceanprotocol.com',
|
process.env.GATSBY_FACTORY_ADDRESS ||
|
||||||
ratingUri:
|
'0xB9d406D24B310A7D821D0b782a36909e8c925471',
|
||||||
process.env.RATING_URI ||
|
oceanTokenAddress:
|
||||||
'https://rating.pacific.marketplace.dev-ocean.com',
|
process.env.GATSBY_OCEAN_TOKEN_ADDRESS ||
|
||||||
|
'0xf6AE724aD6e6Fa89B6aBc9710C5eb692b7F57139',
|
||||||
verbose: 3
|
verbose: 3
|
||||||
}
|
},
|
||||||
|
// Main, Rinkeby, Kovan
|
||||||
|
// networks: [1, 4, 42],
|
||||||
|
networks: [4],
|
||||||
|
infuraProjectId: process.env.GATSBY_INFURA_PROJECT_ID || 'xxx'
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"site": {
|
"site": {
|
||||||
"siteTitle": "Ocean Market",
|
"siteTitle": "Ocean Market",
|
||||||
"siteTagline": "A marketplace to find and publish open data sets in the Ocean Network.",
|
"siteTagline": "A marketplace to find, publish and trade data sets in the Ocean Network.",
|
||||||
"siteUrl": "https://market.oceanprotocol.now.sh",
|
"siteUrl": "https://market.oceanprotocol.now.sh",
|
||||||
"siteIcon": "node_modules/@oceanprotocol/art/logo/favicon-white.png",
|
"siteIcon": "node_modules/@oceanprotocol/art/logo/favicon-white.png",
|
||||||
"siteImage": "../src/images/share.png",
|
"siteImage": "../src/images/share.png",
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
|
||||||
const siteContent = require('./content/site.json')
|
const siteContent = require('./content/site.json')
|
||||||
const { oceanConfig } = require('./app.config')
|
const appConfig = require('./app.config')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
siteMetadata: {
|
siteMetadata: {
|
||||||
...siteContent.site
|
...siteContent.site,
|
||||||
|
appConfig: {
|
||||||
|
...appConfig
|
||||||
|
}
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
{
|
{
|
||||||
@ -29,12 +32,6 @@ module.exports = {
|
|||||||
path: `${__dirname}/node_modules/@oceanprotocol/art/`
|
path: `${__dirname}/node_modules/@oceanprotocol/art/`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
resolve: 'gatsby-source-ocean',
|
|
||||||
options: {
|
|
||||||
aquariusUri: oceanConfig.aquariusUri
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
resolve: 'gatsby-plugin-sharp',
|
resolve: 'gatsby-plugin-sharp',
|
||||||
options: {
|
options: {
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
const path = require('path')
|
|
||||||
|
|
||||||
exports.onCreateWebpackConfig = ({ actions }) => {
|
exports.onCreateWebpackConfig = ({ actions }) => {
|
||||||
actions.setWebpackConfig({
|
actions.setWebpackConfig({
|
||||||
node: {
|
node: {
|
||||||
@ -9,60 +7,6 @@ exports.onCreateWebpackConfig = ({ actions }) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.createPages = async ({ graphql, actions }) => {
|
|
||||||
const { createPage } = actions
|
|
||||||
|
|
||||||
// Create pages for all assets
|
|
||||||
const assetDetailsTemplate = path.resolve(
|
|
||||||
'src/components/templates/AssetDetails.tsx'
|
|
||||||
)
|
|
||||||
|
|
||||||
const result = await graphql(`
|
|
||||||
query {
|
|
||||||
allOceanAsset {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
did
|
|
||||||
main {
|
|
||||||
type
|
|
||||||
name
|
|
||||||
dateCreated
|
|
||||||
author
|
|
||||||
license
|
|
||||||
price
|
|
||||||
datePublished
|
|
||||||
files {
|
|
||||||
contentType
|
|
||||||
index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
additionalInformation {
|
|
||||||
description
|
|
||||||
deliveryType
|
|
||||||
termsAndConditions
|
|
||||||
access
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
|
|
||||||
if (result.errors) {
|
|
||||||
throw result.errors
|
|
||||||
}
|
|
||||||
|
|
||||||
await result.data.allOceanAsset.edges.forEach(({ node }) => {
|
|
||||||
const path = `/asset/${node.did}`
|
|
||||||
|
|
||||||
createPage({
|
|
||||||
path,
|
|
||||||
component: assetDetailsTemplate,
|
|
||||||
context: { did: node.did }
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.onCreatePage = async ({ page, actions }) => {
|
exports.onCreatePage = async ({ page, actions }) => {
|
||||||
const { createPage } = actions
|
const { createPage } = actions
|
||||||
// page.matchPath is a special key that's used for matching pages
|
// page.matchPath is a special key that's used for matching pages
|
||||||
|
1106
package-lock.json
generated
1106
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
32
package.json
32
package.json
@ -22,20 +22,21 @@
|
|||||||
"@loadable/component": "^5.13.1",
|
"@loadable/component": "^5.13.1",
|
||||||
"@now/node": "^1.7.2",
|
"@now/node": "^1.7.2",
|
||||||
"@oceanprotocol/art": "^3.0.0",
|
"@oceanprotocol/art": "^3.0.0",
|
||||||
"@oceanprotocol/react": "0.0.11",
|
"@oceanprotocol/lib": "^0.1.4",
|
||||||
"@oceanprotocol/squid": "^2.2.0",
|
"@oceanprotocol/react": "^0.0.12",
|
||||||
"@oceanprotocol/typographies": "^0.1.0",
|
"@oceanprotocol/typographies": "^0.1.0",
|
||||||
"@sindresorhus/slugify": "^1.0.0",
|
"@sindresorhus/slugify": "^1.0.0",
|
||||||
"@tippyjs/react": "^4.1.0",
|
"@tippyjs/react": "^4.1.0",
|
||||||
"@types/classnames": "^2.2.10",
|
"@types/classnames": "^2.2.10",
|
||||||
|
"@walletconnect/web3-provider": "^1.0.15",
|
||||||
"axios": "^0.19.2",
|
"axios": "^0.19.2",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"date-fns": "^2.14.0",
|
"date-fns": "^2.14.0",
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"ethereum-blockies": "github:MyEtherWallet/blockies",
|
"ethereum-blockies": "github:MyEtherWallet/blockies",
|
||||||
"filesize": "^6.1.0",
|
"filesize": "^6.1.0",
|
||||||
"formik": "^2.1.4",
|
"formik": "^2.1.5",
|
||||||
"gatsby": "^2.24.2",
|
"gatsby": "^2.24.3",
|
||||||
"gatsby-image": "^2.4.13",
|
"gatsby-image": "^2.4.13",
|
||||||
"gatsby-plugin-manifest": "^2.4.18",
|
"gatsby-plugin-manifest": "^2.4.18",
|
||||||
"gatsby-plugin-react-helmet": "^3.3.10",
|
"gatsby-plugin-react-helmet": "^3.3.10",
|
||||||
@ -53,15 +54,14 @@
|
|||||||
"numeral": "^2.0.6",
|
"numeral": "^2.0.6",
|
||||||
"query-string": "^6.13.1",
|
"query-string": "^6.13.1",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-data-table-component": "^6.9.6",
|
"react-data-table-component": "^6.9.7",
|
||||||
"react-datepicker": "^3.1.3",
|
"react-datepicker": "^3.1.3",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
"react-dotdotdot": "^1.3.1",
|
"react-dotdotdot": "^1.3.1",
|
||||||
"react-dropzone": "^11.0.1",
|
"react-dropzone": "^11.0.2",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-markdown": "^4.3.1",
|
"react-markdown": "^4.3.1",
|
||||||
"react-paginate": "^6.3.2",
|
"react-paginate": "^6.3.2",
|
||||||
"react-rating": "^2.0.5",
|
|
||||||
"react-responsive-modal": "^5.0.2",
|
"react-responsive-modal": "^5.0.2",
|
||||||
"react-spring": "^8.0.27",
|
"react-spring": "^8.0.27",
|
||||||
"react-tabs": "^3.1.1",
|
"react-tabs": "^3.1.1",
|
||||||
@ -73,17 +73,17 @@
|
|||||||
"yup": "^0.29.1"
|
"yup": "^0.29.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.10.3",
|
"@babel/core": "^7.10.5",
|
||||||
"@babel/preset-typescript": "^7.10.1",
|
"@babel/preset-typescript": "^7.10.1",
|
||||||
"@storybook/addon-actions": "^6.0.0-rc.3",
|
"@storybook/addon-actions": "^6.0.0-rc.5",
|
||||||
"@storybook/addon-storyshots": "^6.0.0-rc.3",
|
"@storybook/addon-storyshots": "^6.0.0-rc.5",
|
||||||
"@storybook/react": "^6.0.0-rc.3",
|
"@storybook/react": "^6.0.0-rc.5",
|
||||||
"@svgr/webpack": "^5.4.0",
|
"@svgr/webpack": "^5.4.0",
|
||||||
"@testing-library/jest-dom": "^5.11.0",
|
"@testing-library/jest-dom": "^5.11.1",
|
||||||
"@testing-library/react": "^10.4.5",
|
"@testing-library/react": "^10.4.7",
|
||||||
"@types/jest": "^26.0.4",
|
"@types/jest": "^26.0.4",
|
||||||
"@types/loadable__component": "^5.13.0",
|
"@types/loadable__component": "^5.13.0",
|
||||||
"@types/node": "^14.0.22",
|
"@types/node": "^14.0.23",
|
||||||
"@types/numeral": "^0.0.28",
|
"@types/numeral": "^0.0.28",
|
||||||
"@types/react": "^16.9.43",
|
"@types/react": "^16.9.43",
|
||||||
"@types/react-datepicker": "^3.0.2",
|
"@types/react-datepicker": "^3.0.2",
|
||||||
@ -92,8 +92,8 @@
|
|||||||
"@types/react-tabs": "^2.3.2",
|
"@types/react-tabs": "^2.3.2",
|
||||||
"@types/shortid": "0.0.29",
|
"@types/shortid": "0.0.29",
|
||||||
"@types/yup": "^0.29.3",
|
"@types/yup": "^0.29.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^3.6.0",
|
"@typescript-eslint/eslint-plugin": "^3.6.1",
|
||||||
"@typescript-eslint/parser": "^3.6.0",
|
"@typescript-eslint/parser": "^3.6.1",
|
||||||
"babel-loader": "^8.1.0",
|
"babel-loader": "^8.1.0",
|
||||||
"babel-preset-react-app": "^9.1.2",
|
"babel-preset-react-app": "^9.1.2",
|
||||||
"electron": "^9.1.0",
|
"electron": "^9.1.0",
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
const axios = require('axios')
|
|
||||||
|
|
||||||
exports.sourceNodes = async (
|
|
||||||
{ actions, createNodeId, createContentDigest },
|
|
||||||
{ aquariusUri }
|
|
||||||
) => {
|
|
||||||
const { createNode } = actions
|
|
||||||
|
|
||||||
// Query for all assets to use in creating pages.
|
|
||||||
const result = await axios(`${aquariusUri}/api/v1/aquarius/assets`)
|
|
||||||
|
|
||||||
for (let i = 0; i < result.data.ids.length; i++) {
|
|
||||||
const did = result.data.ids[i]
|
|
||||||
|
|
||||||
const metadataResult = await axios(
|
|
||||||
`${aquariusUri}/api/v1/aquarius/assets/metadata/${did}`
|
|
||||||
)
|
|
||||||
|
|
||||||
const metadata = {
|
|
||||||
did,
|
|
||||||
...metadataResult.data.attributes
|
|
||||||
}
|
|
||||||
|
|
||||||
const nodeMeta = {
|
|
||||||
id: createNodeId(did),
|
|
||||||
parent: null,
|
|
||||||
children: [],
|
|
||||||
internal: {
|
|
||||||
type: 'OceanAsset',
|
|
||||||
contentDigest: createContentDigest(metadata),
|
|
||||||
description: `All data sets queried from ${aquariusUri}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const node = {
|
|
||||||
...metadata,
|
|
||||||
...nodeMeta
|
|
||||||
}
|
|
||||||
|
|
||||||
await createNode(node)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "gatsby-source-ocean"
|
|
||||||
}
|
|
9
src/@types/MetaData.d.ts
vendored
9
src/@types/MetaData.d.ts
vendored
@ -1,5 +1,5 @@
|
|||||||
import { File, MetaData, AdditionalInformation } from '@oceanprotocol/squid'
|
import { File, MetaData, AdditionalInformation } from '@oceanprotocol/lib'
|
||||||
import { ServiceMetadata } from '@oceanprotocol/squid/dist/node/ddo/Service'
|
import { ServiceMetadata } from '@oceanprotocol/lib/dist/node/ddo/Service'
|
||||||
|
|
||||||
export declare type AccessType = 'Download' | 'Compute'
|
export declare type AccessType = 'Download' | 'Compute'
|
||||||
|
|
||||||
@ -34,8 +34,3 @@ export interface MetaDataPublishForm {
|
|||||||
export interface ServiceMetaDataMarket extends ServiceMetadata {
|
export interface ServiceMetaDataMarket extends ServiceMetadata {
|
||||||
attributes: MetaDataMarket
|
attributes: MetaDataMarket
|
||||||
}
|
}
|
||||||
|
|
||||||
// type for assets pulled into GraphQL
|
|
||||||
export interface OceanAsset extends MetaDataMarket {
|
|
||||||
did: DID
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
.app {
|
.app {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
background: url('../../node_modules/@oceanprotocol/art/waves/waves.svg')
|
||||||
|
no-repeat center 10rem;
|
||||||
|
|
||||||
/* sticky footer technique */
|
/* sticky footer technique */
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -12,6 +12,7 @@ export interface LayoutProps {
|
|||||||
uri: string
|
uri: string
|
||||||
description?: string
|
description?: string
|
||||||
noPageHeader?: boolean
|
noPageHeader?: boolean
|
||||||
|
headerCenter?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Layout({
|
export default function Layout({
|
||||||
@ -19,7 +20,8 @@ export default function Layout({
|
|||||||
title,
|
title,
|
||||||
uri,
|
uri,
|
||||||
description,
|
description,
|
||||||
noPageHeader
|
noPageHeader,
|
||||||
|
headerCenter
|
||||||
}: LayoutProps): ReactElement {
|
}: LayoutProps): ReactElement {
|
||||||
return (
|
return (
|
||||||
<div className={styles.app}>
|
<div className={styles.app}>
|
||||||
@ -29,7 +31,11 @@ export default function Layout({
|
|||||||
<main className={styles.main}>
|
<main className={styles.main}>
|
||||||
<Container>
|
<Container>
|
||||||
{title && !noPageHeader && (
|
{title && !noPageHeader && (
|
||||||
<PageHeader title={title} description={description} />
|
<PageHeader
|
||||||
|
title={title}
|
||||||
|
description={description}
|
||||||
|
center={headerCenter}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
{children}
|
{children}
|
||||||
</Container>
|
</Container>
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
import React, { ReactElement, ReactNode } from 'react'
|
import React, { ReactElement, ReactNode } from 'react'
|
||||||
|
import classNames from 'classnames/bind'
|
||||||
import styles from './Container.module.css'
|
import styles from './Container.module.css'
|
||||||
|
|
||||||
|
const cx = classNames.bind(styles)
|
||||||
|
|
||||||
export default function Container({
|
export default function Container({
|
||||||
children,
|
children,
|
||||||
narrow,
|
narrow,
|
||||||
@ -10,13 +13,11 @@ export default function Container({
|
|||||||
narrow?: boolean
|
narrow?: boolean
|
||||||
className?: string
|
className?: string
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
return (
|
const styleClasses = cx({
|
||||||
<div
|
container: true,
|
||||||
className={`${styles.container} ${narrow && styles.narrow} ${
|
narrow: narrow,
|
||||||
className && className
|
[className]: className
|
||||||
}`}
|
})
|
||||||
>
|
|
||||||
{children}
|
return <div className={styleClasses}>{children}</div>
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import { File as FileMetaData } from '@oceanprotocol/squid'
|
import { File as FileMetaData } from '@oceanprotocol/lib'
|
||||||
import filesize from 'filesize'
|
import filesize from 'filesize'
|
||||||
import cleanupContentType from '../../utils/cleanupContentType'
|
import cleanupContentType from '../../utils/cleanupContentType'
|
||||||
import styles from './File.module.css'
|
import styles from './File.module.css'
|
||||||
|
@ -1,57 +0,0 @@
|
|||||||
.ratings {
|
|
||||||
display: flex;
|
|
||||||
margin-left: calc(var(--spacer) / -8);
|
|
||||||
font-weight: var(--font-weight-base);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle half stars our own way */
|
|
||||||
.ratings [style*='width:'] {
|
|
||||||
width: 100% !important;
|
|
||||||
clip-path: polygon(0 0, 60% 0, 60% 100%, 0% 100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ratings [style*='width:100%'],
|
|
||||||
.ratings [style*='width: 100%'] {
|
|
||||||
width: 100% !important;
|
|
||||||
clip-path: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ratings [style*='width:0%'],
|
|
||||||
.ratings [style*='width: 0%'] {
|
|
||||||
width: 0 !important;
|
|
||||||
clip-path: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.star {
|
|
||||||
margin-left: calc(var(--spacer) / 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
.star svg {
|
|
||||||
fill: none;
|
|
||||||
stroke: var(--brand-grey);
|
|
||||||
}
|
|
||||||
|
|
||||||
.full {
|
|
||||||
composes: star;
|
|
||||||
}
|
|
||||||
|
|
||||||
.full svg {
|
|
||||||
fill: var(--color-primary);
|
|
||||||
stroke: var(--color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ratingVotes {
|
|
||||||
display: inline-block;
|
|
||||||
font-size: var(--font-size-small);
|
|
||||||
padding-left: 5px;
|
|
||||||
color: var(--brand-grey);
|
|
||||||
}
|
|
||||||
|
|
||||||
.readonly {
|
|
||||||
composes: ratings;
|
|
||||||
}
|
|
||||||
|
|
||||||
.readonly .full svg {
|
|
||||||
fill: var(--color-secondary);
|
|
||||||
stroke: var(--color-secondary);
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import Rating from './Rating'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'Atoms/Rating'
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Normal = () => (
|
|
||||||
<Rating
|
|
||||||
readonly
|
|
||||||
curation={{
|
|
||||||
rating: 3,
|
|
||||||
numVotes: 300
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
|
|
||||||
export const WithFraction = () => (
|
|
||||||
<Rating
|
|
||||||
readonly
|
|
||||||
curation={{
|
|
||||||
rating: 3.3,
|
|
||||||
numVotes: 300
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
|
|
||||||
export const Interactive = () => (
|
|
||||||
<Rating
|
|
||||||
onClick={(value: any) => null}
|
|
||||||
curation={{
|
|
||||||
rating: 3.3,
|
|
||||||
numVotes: 300
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
@ -1,51 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import ReactRating from 'react-rating'
|
|
||||||
import Star from '../../images/star.svg'
|
|
||||||
import { Curation } from '@oceanprotocol/squid'
|
|
||||||
import styles from './Rating.module.css'
|
|
||||||
|
|
||||||
export default function Rating({
|
|
||||||
curation,
|
|
||||||
readonly,
|
|
||||||
isLoading,
|
|
||||||
onClick
|
|
||||||
}: {
|
|
||||||
curation: Curation | undefined
|
|
||||||
readonly?: boolean
|
|
||||||
isLoading?: boolean
|
|
||||||
onClick?: (value: any) => void
|
|
||||||
}) {
|
|
||||||
let numVotes = 0
|
|
||||||
let rating = 0
|
|
||||||
|
|
||||||
if (!curation) return null
|
|
||||||
;({ numVotes, rating } = curation)
|
|
||||||
|
|
||||||
// if it's readonly then the fraction is 10 to show the average rating proper. When you select the rating you select from 1 to 5
|
|
||||||
const fractions = readonly ? 2 : 1
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={`${readonly ? styles.readonly : styles.ratings}`}>
|
|
||||||
<ReactRating
|
|
||||||
emptySymbol={
|
|
||||||
<div className={styles.star}>
|
|
||||||
<Star />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
fullSymbol={
|
|
||||||
<div className={styles.full}>
|
|
||||||
<Star />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
initialRating={rating}
|
|
||||||
readonly={readonly || isLoading || false}
|
|
||||||
onClick={onClick}
|
|
||||||
fractions={fractions}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<span className={styles.ratingVotes}>
|
|
||||||
{rating} {readonly ? `(${numVotes})` : ''}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -7,14 +7,13 @@
|
|||||||
.tag {
|
.tag {
|
||||||
color: var(--color-secondary);
|
color: var(--color-secondary);
|
||||||
font-size: var(--font-size-small);
|
font-size: var(--font-size-small);
|
||||||
font-weight: var(--font-weight-bold);
|
padding: 0.1rem 1.2rem 0.1rem 1.2rem;
|
||||||
padding: 0.2rem 1.2rem 0.2rem 1.2rem;
|
margin-left: calc(var(--spacer) / 8);
|
||||||
margin-left: calc(var(--spacer) / 16);
|
margin-right: calc(var(--spacer) / 8);
|
||||||
margin-right: calc(var(--spacer) / 16);
|
margin-bottom: calc(var(--spacer) / 4);
|
||||||
margin-bottom: calc(var(--spacer) / 8);
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
border: 1px solid var(--brand-grey-light);
|
border: 1px solid var(--brand-grey-lighter);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
@ -25,10 +24,6 @@
|
|||||||
color: var(--color-primary);
|
color: var(--color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag:first-of-type {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.more {
|
.more {
|
||||||
font-size: var(--font-size-mini);
|
font-size: var(--font-size-mini);
|
||||||
margin-left: calc(var(--spacer) / 8);
|
margin-left: calc(var(--spacer) / 8);
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
.foot {
|
.foot {
|
||||||
font-weight: var(--font-weight-bold);
|
font-weight: var(--font-weight-bold);
|
||||||
|
margin-top: calc(var(--spacer) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.foot p {
|
.foot p {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import AssetTeaser from '../molecules/AssetTeaser'
|
import AssetTeaser from '../molecules/AssetTeaser'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { DDO } from '@oceanprotocol/squid'
|
import { DDO } from '@oceanprotocol/lib'
|
||||||
import ddo from '../../../tests/unit/__fixtures__/ddo'
|
import ddo from '../../../tests/unit/__fixtures__/ddo'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -2,10 +2,8 @@ import React from 'react'
|
|||||||
import { Link } from 'gatsby'
|
import { Link } from 'gatsby'
|
||||||
import Dotdotdot from 'react-dotdotdot'
|
import Dotdotdot from 'react-dotdotdot'
|
||||||
import { MetaDataMarket } from '../../@types/MetaData'
|
import { MetaDataMarket } from '../../@types/MetaData'
|
||||||
import Tags from '../atoms/Tags'
|
|
||||||
import Price from '../atoms/Price'
|
import Price from '../atoms/Price'
|
||||||
import styles from './AssetTeaser.module.css'
|
import styles from './AssetTeaser.module.css'
|
||||||
import Rating from '../atoms/Rating'
|
|
||||||
|
|
||||||
declare type AssetTeaserProps = {
|
declare type AssetTeaserProps = {
|
||||||
did: string
|
did: string
|
||||||
@ -16,17 +14,10 @@ const AssetTeaser: React.FC<AssetTeaserProps> = ({
|
|||||||
did,
|
did,
|
||||||
metadata
|
metadata
|
||||||
}: AssetTeaserProps) => {
|
}: AssetTeaserProps) => {
|
||||||
|
if (!metadata.additionalInformation) return null
|
||||||
|
|
||||||
const { name, price } = metadata.main
|
const { name, price } = metadata.main
|
||||||
|
const { description, access } = metadata.additionalInformation
|
||||||
const {
|
|
||||||
description,
|
|
||||||
copyrightHolder,
|
|
||||||
tags,
|
|
||||||
categories,
|
|
||||||
access
|
|
||||||
} = metadata.additionalInformation
|
|
||||||
|
|
||||||
const { curation } = metadata
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<article className={styles.teaser}>
|
<article className={styles.teaser}>
|
||||||
@ -35,20 +26,15 @@ const AssetTeaser: React.FC<AssetTeaserProps> = ({
|
|||||||
{access === 'Compute' && (
|
{access === 'Compute' && (
|
||||||
<div className={styles.accessLabel}>{access}</div>
|
<div className={styles.accessLabel}>{access}</div>
|
||||||
)}
|
)}
|
||||||
<Rating curation={curation} readonly />
|
|
||||||
|
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
<Dotdotdot tagName="p" clamp={3}>
|
<Dotdotdot tagName="p" clamp={3}>
|
||||||
{description || ''}
|
{description || ''}
|
||||||
</Dotdotdot>
|
</Dotdotdot>
|
||||||
|
|
||||||
{tags && (
|
|
||||||
<Tags className={styles.tags} items={tags} max={3} noLinks />
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer className={styles.foot}>
|
<footer className={styles.foot}>
|
||||||
<Price price={price} small />
|
<Price price={price} />
|
||||||
</footer>
|
</footer>
|
||||||
</Link>
|
</Link>
|
||||||
</article>
|
</article>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState, useEffect } from 'react'
|
||||||
import { useNavigate } from '@reach/router'
|
import { useNavigate } from '@reach/router'
|
||||||
import { DDO } from '@oceanprotocol/squid'
|
import { DDO } from '@oceanprotocol/lib'
|
||||||
import { redeploy } from '../../utils'
|
import { redeploy } from '../../utils'
|
||||||
import Button from '../atoms/Button'
|
import Button from '../atoms/Button'
|
||||||
import BaseDialog from '../atoms/BaseDialog'
|
import BaseDialog from '../atoms/BaseDialog'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import { File } from '@oceanprotocol/squid'
|
import { File } from '@oceanprotocol/lib'
|
||||||
import { prettySize } from '../../../utils'
|
import { prettySize } from '../../../utils'
|
||||||
import cleanupContentType from '../../../utils/cleanupContentType'
|
import cleanupContentType from '../../../utils/cleanupContentType'
|
||||||
import styles from './Info.module.css'
|
import styles from './Info.module.css'
|
||||||
|
@ -14,3 +14,9 @@
|
|||||||
margin-top: calc(var(--spacer) / 4);
|
margin-top: calc(var(--spacer) / 4);
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
@ -6,14 +6,16 @@ const cx = classNames.bind(styles)
|
|||||||
|
|
||||||
export default function PageHeader({
|
export default function PageHeader({
|
||||||
title,
|
title,
|
||||||
description
|
description,
|
||||||
|
center
|
||||||
}: {
|
}: {
|
||||||
title: string
|
title: string
|
||||||
description?: string
|
description?: string
|
||||||
center?: boolean
|
center?: boolean
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const styleClasses = cx({
|
const styleClasses = cx({
|
||||||
header: true
|
header: true,
|
||||||
|
center: center
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
margin-top: -1px;
|
margin-top: -1px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: 1px solid var(--brand-grey-light);
|
border: 1px solid var(--brand-grey-lighter);
|
||||||
min-width: 3.5rem;
|
min-width: 3.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState, useEffect, ReactElement } from 'react'
|
||||||
import ReactPaginate from 'react-paginate'
|
import ReactPaginate from 'react-paginate'
|
||||||
import styles from './Pagination.module.css'
|
import styles from './Pagination.module.css'
|
||||||
|
|
||||||
@ -14,7 +14,9 @@ export default function Pagination({
|
|||||||
currentPage,
|
currentPage,
|
||||||
hrefBuilder,
|
hrefBuilder,
|
||||||
onPageChange
|
onPageChange
|
||||||
}: PaginationProps) {
|
}: PaginationProps): ReactElement {
|
||||||
|
if (!totalPages || totalPages < 2) return null
|
||||||
|
|
||||||
const [smallViewport, setSmallViewport] = useState(true)
|
const [smallViewport, setSmallViewport] = useState(true)
|
||||||
|
|
||||||
function viewportChange(mq: { matches: boolean }) {
|
function viewportChange(mq: { matches: boolean }) {
|
||||||
@ -31,7 +33,7 @@ export default function Pagination({
|
|||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return totalPages > 1 ? (
|
return (
|
||||||
<ReactPaginate
|
<ReactPaginate
|
||||||
pageCount={totalPages}
|
pageCount={totalPages}
|
||||||
// react-pagination starts counting at 0, we start at 1
|
// react-pagination starts counting at 0, we start at 1
|
||||||
@ -53,5 +55,5 @@ export default function Pagination({
|
|||||||
disabledClassName={styles.prevNextDisabled}
|
disabledClassName={styles.prevNextDisabled}
|
||||||
breakLinkClassName={styles.break}
|
breakLinkClassName={styles.break}
|
||||||
/>
|
/>
|
||||||
) : null
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React, { useState, ChangeEvent, FormEvent, ReactElement } from 'react'
|
import React, { useState, ChangeEvent, FormEvent, ReactElement } from 'react'
|
||||||
import { useNavigate } from '@reach/router'
|
import { useNavigate } from '@reach/router'
|
||||||
import styles from './SearchBar.module.css'
|
import styles from './SearchBar.module.css'
|
||||||
import Loader from '../atoms/Loader'
|
|
||||||
import Button from '../atoms/Button'
|
import Button from '../atoms/Button'
|
||||||
import Input from '../atoms/Input'
|
import Input from '../atoms/Input'
|
||||||
import InputGroup from '../atoms/Input/InputGroup'
|
import InputGroup from '../atoms/Input/InputGroup'
|
||||||
@ -19,7 +18,6 @@ export default function SearchBar({
|
|||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const [value, setValue] = useState(initialValue || '')
|
const [value, setValue] = useState(initialValue || '')
|
||||||
const [searchStarted, setSearchStarted] = useState(false)
|
|
||||||
|
|
||||||
function handleChange(e: ChangeEvent<HTMLInputElement>) {
|
function handleChange(e: ChangeEvent<HTMLInputElement>) {
|
||||||
setValue(e.target.value)
|
setValue(e.target.value)
|
||||||
@ -27,10 +25,7 @@ export default function SearchBar({
|
|||||||
|
|
||||||
function startSearch(e: FormEvent<HTMLButtonElement>) {
|
function startSearch(e: FormEvent<HTMLButtonElement>) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
if (value === '') return
|
if (value === '') return
|
||||||
|
|
||||||
setSearchStarted(true)
|
|
||||||
navigate(`/search?text=${value}`)
|
navigate(`/search?text=${value}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +41,7 @@ export default function SearchBar({
|
|||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<Button onClick={(e: FormEvent<HTMLButtonElement>) => startSearch(e)}>
|
<Button onClick={(e: FormEvent<HTMLButtonElement>) => startSearch(e)}>
|
||||||
{searchStarted ? <Loader /> : 'Search'}
|
Search
|
||||||
</Button>
|
</Button>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import styles from './Account.module.css'
|
import styles from './Account.module.css'
|
||||||
import { useWeb3, useOcean } from '@oceanprotocol/react'
|
import { useOcean } from '@oceanprotocol/react'
|
||||||
import { toDataUrl } from 'ethereum-blockies'
|
import { toDataUrl } from 'ethereum-blockies'
|
||||||
import { ReactComponent as Caret } from '../../../images/caret.svg'
|
import { ReactComponent as Caret } from '../../../images/caret.svg'
|
||||||
import Status from '../../atoms/Status'
|
import Status from '../../atoms/Status'
|
||||||
|
import {
|
||||||
function accountTruncate(account: string) {
|
accountTruncate,
|
||||||
const middle = account.substring(6, 38)
|
connectWallet,
|
||||||
const truncated = account.replace(middle, '…')
|
isCorrectNetwork
|
||||||
return truncated
|
} from '../../../utils/wallet'
|
||||||
}
|
|
||||||
|
|
||||||
const Blockies = ({ account }: { account: string | undefined }) => {
|
const Blockies = ({ account }: { account: string | undefined }) => {
|
||||||
if (!account) return null
|
if (!account) return null
|
||||||
@ -28,15 +27,14 @@ const Blockies = ({ account }: { account: string | undefined }) => {
|
|||||||
// Forward ref for Tippy.js
|
// Forward ref for Tippy.js
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
const Account = React.forwardRef((props, ref: any) => {
|
const Account = React.forwardRef((props, ref: any) => {
|
||||||
const { account, web3Connect, ethProviderStatus } = useWeb3()
|
const { accountId, status, connect, chainId } = useOcean()
|
||||||
const { status } = useOcean()
|
const hasSuccess = status === 1 && isCorrectNetwork(chainId)
|
||||||
const hasSuccess = ethProviderStatus === 1 && status === 1
|
|
||||||
|
|
||||||
return account ? (
|
return accountId ? (
|
||||||
<button className={styles.button} aria-label="Account" ref={ref}>
|
<button className={styles.button} aria-label="Account" ref={ref}>
|
||||||
<Blockies account={account} />
|
<Blockies account={accountId} />
|
||||||
<span className={styles.address} title={account}>
|
<span className={styles.address} title={accountId}>
|
||||||
{accountTruncate(account)}
|
{accountTruncate(accountId)}
|
||||||
</span>
|
</span>
|
||||||
{!hasSuccess && (
|
{!hasSuccess && (
|
||||||
<Status className={styles.status} state="warning" aria-hidden />
|
<Status className={styles.status} state="warning" aria-hidden />
|
||||||
@ -46,7 +44,7 @@ const Account = React.forwardRef((props, ref: any) => {
|
|||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
className={styles.button}
|
className={styles.button}
|
||||||
onClick={() => web3Connect.connect()}
|
onClick={async () => await connectWallet(connect)}
|
||||||
// Need the `ref` here although we do not want
|
// Need the `ref` here although we do not want
|
||||||
// the Tippy to show in this state.
|
// the Tippy to show in this state.
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
@ -5,21 +5,31 @@
|
|||||||
max-width: 25rem;
|
max-width: 25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.details > ul {
|
|
||||||
margin-bottom: calc(var(--spacer) / 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.balance {
|
.balance {
|
||||||
|
font-size: var(--font-size-base);
|
||||||
|
font-weight: var(--font-weight-bold);
|
||||||
color: var(--color-secondary);
|
color: var(--color-secondary);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
font-size: var(--font-size-small);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.balance span {
|
.balance span {
|
||||||
font-size: var(--font-size-base);
|
width: 20%;
|
||||||
font-weight: var(--font-weight-bold);
|
text-align: right;
|
||||||
|
font-weight: var(--font-weight-base);
|
||||||
|
font-size: var(--font-size-small);
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-left: 0.1rem;
|
margin-right: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
border-top: 1px solid var(--brand-grey-lighter);
|
||||||
|
margin-top: calc(var(--spacer) / 2);
|
||||||
|
padding-top: calc(var(--spacer) / 2);
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
font-size: var(--font-size-small);
|
||||||
|
color: var(--color-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.arrow,
|
.arrow,
|
||||||
|
@ -1,30 +1,49 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement, useEffect, useState } from 'react'
|
||||||
import Button from '../../atoms/Button'
|
import Button from '../../atoms/Button'
|
||||||
import styles from './Details.module.css'
|
import styles from './Details.module.css'
|
||||||
import { useWeb3, useOcean } from '@oceanprotocol/react'
|
import { useOcean } from '@oceanprotocol/react'
|
||||||
import Web3Feedback from './Feedback'
|
import Web3Feedback from './Feedback'
|
||||||
import { formatNumber } from '../../../utils'
|
import { formatNumber } from '../../../utils'
|
||||||
|
import { connectWallet, getNetworkName } from '../../../utils/wallet'
|
||||||
|
import { getInjectedProviderName } from 'web3modal'
|
||||||
|
|
||||||
export default function Details({ attrs }: { attrs: any }): ReactElement {
|
export default function Details({ attrs }: { attrs: any }): ReactElement {
|
||||||
const { balance, web3Connect } = useWeb3()
|
const { ocean, balance, connect, logout, chainId } = useOcean()
|
||||||
const { balanceInOcean } = useOcean()
|
const [balanceOcean, setBalanceOcean] = useState('0')
|
||||||
const ethBalanceText = formatNumber(Number(balance))
|
|
||||||
const oceanBalanceText = formatNumber(Number(balanceInOcean))
|
useEffect(() => {
|
||||||
|
async function init() {
|
||||||
|
if (!ocean) return
|
||||||
|
|
||||||
|
const accounts = await ocean.accounts.list()
|
||||||
|
const newBalanceOcean = await accounts[0].getOceanBalance()
|
||||||
|
newBalanceOcean && setBalanceOcean(newBalanceOcean)
|
||||||
|
}
|
||||||
|
init()
|
||||||
|
}, [ocean])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.details} {...attrs}>
|
<div className={styles.details} {...attrs}>
|
||||||
<ul>
|
<ul>
|
||||||
<li className={styles.balance}>
|
<li className={styles.balance}>
|
||||||
OCEAN <span>{oceanBalanceText}</span>
|
<span>OCEAN</span> {balanceOcean}
|
||||||
</li>
|
</li>
|
||||||
<li className={styles.balance}>
|
<li className={styles.balance}>
|
||||||
ETH <span>{ethBalanceText}</span>
|
<span>ETH</span> {formatNumber(Number(balance))}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li className={styles.actions}>
|
||||||
|
<span title="Connected provider">
|
||||||
|
{getInjectedProviderName()}
|
||||||
|
<br />
|
||||||
|
{getNetworkName(chainId)}
|
||||||
|
</span>
|
||||||
<Button
|
<Button
|
||||||
style="text"
|
style="text"
|
||||||
size="small"
|
size="small"
|
||||||
onClick={() => web3Connect.toggleModal()}
|
onClick={() => {
|
||||||
|
logout()
|
||||||
|
connectWallet(connect)
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Switch Wallet
|
Switch Wallet
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import Status from '../../atoms/Status'
|
import Status from '../../atoms/Status'
|
||||||
import styles from './Feedback.module.css'
|
import styles from './Feedback.module.css'
|
||||||
import { useWeb3, useOcean } from '@oceanprotocol/react'
|
import { useOcean } from '@oceanprotocol/react'
|
||||||
|
import { isCorrectNetwork, getNetworkName } from '../../../utils/wallet'
|
||||||
|
import { useSiteMetadata } from '../../../hooks/useSiteMetadata'
|
||||||
|
|
||||||
export declare type Web3Error = {
|
export declare type Web3Error = {
|
||||||
status: 'error' | 'warning' | 'success'
|
status: 'error' | 'warning' | 'success'
|
||||||
@ -14,47 +16,46 @@ export default function Web3Feedback({
|
|||||||
}: {
|
}: {
|
||||||
isBalanceInsufficient?: boolean
|
isBalanceInsufficient?: boolean
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { ethProviderStatus } = useWeb3()
|
const { appConfig } = useSiteMetadata()
|
||||||
const { status } = useOcean()
|
const { account, status, chainId } = useOcean()
|
||||||
const isEthProviderAbsent = ethProviderStatus === -1
|
|
||||||
const isEthProviderDisconnected = ethProviderStatus === 0
|
|
||||||
const isOceanDisconnected = status === 0
|
|
||||||
const isOceanConnectionError = status === -1
|
const isOceanConnectionError = status === -1
|
||||||
const hasSuccess = ethProviderStatus === 1 && status === 1
|
const correctNetwork = isCorrectNetwork(chainId)
|
||||||
|
const showFeedback = !account || isOceanConnectionError || !correctNetwork
|
||||||
|
const allowedNetworkNames = appConfig.networks.map((network: number) =>
|
||||||
|
getNetworkName(network)
|
||||||
|
)
|
||||||
|
|
||||||
const state = isEthProviderAbsent
|
const state = !account
|
||||||
? 'error'
|
? 'error'
|
||||||
: hasSuccess && !isBalanceInsufficient
|
: !correctNetwork
|
||||||
|
? 'warning'
|
||||||
|
: account && !isBalanceInsufficient
|
||||||
? 'success'
|
? 'success'
|
||||||
: 'warning'
|
: 'warning'
|
||||||
|
|
||||||
const title = isEthProviderAbsent
|
const title = !account
|
||||||
? 'No Web3 Browser'
|
|
||||||
: isEthProviderDisconnected
|
|
||||||
? 'No account connected'
|
? 'No account connected'
|
||||||
: isOceanDisconnected
|
|
||||||
? 'Not connected to Pacific network'
|
|
||||||
: isOceanConnectionError
|
: isOceanConnectionError
|
||||||
? 'Error connecting to Ocean'
|
? 'Error connecting to Ocean'
|
||||||
: hasSuccess
|
: !correctNetwork
|
||||||
|
? 'Wrong Network'
|
||||||
|
: account
|
||||||
? isBalanceInsufficient === true
|
? isBalanceInsufficient === true
|
||||||
? 'Insufficient balance'
|
? 'Insufficient balance'
|
||||||
: 'Connected to Ocean'
|
: 'Connected to Ocean'
|
||||||
: 'Something went wrong'
|
: 'Something went wrong'
|
||||||
|
|
||||||
const message = isEthProviderAbsent
|
const message = !account
|
||||||
? 'To download data sets you need a browser with Web3 capabilties, like Firefox with MetaMask installed.'
|
|
||||||
: isEthProviderDisconnected
|
|
||||||
? 'Please connect your Web3 wallet.'
|
? 'Please connect your Web3 wallet.'
|
||||||
: isOceanDisconnected
|
|
||||||
? 'Please connect in MetaMask to custom RPC https://pacific.oceanprotocol.com.'
|
|
||||||
: isOceanConnectionError
|
: isOceanConnectionError
|
||||||
? 'Try again.'
|
? 'Please try again.'
|
||||||
|
: !correctNetwork
|
||||||
|
? `Please connect to ${allowedNetworkNames}.`
|
||||||
: isBalanceInsufficient === true
|
: isBalanceInsufficient === true
|
||||||
? 'You do not have enough OCEAN in your wallet to purchase this asset.'
|
? 'You do not have enough OCEAN in your wallet to purchase this asset.'
|
||||||
: 'Something went wrong.'
|
: 'Something went wrong.'
|
||||||
|
|
||||||
return !hasSuccess ? (
|
return showFeedback ? (
|
||||||
<section className={styles.feedback}>
|
<section className={styles.feedback}>
|
||||||
<Status state={state} aria-hidden />
|
<Status state={state} aria-hidden />
|
||||||
<h3 className={styles.title}>{title}</h3>
|
<h3 className={styles.title}>{title}</h3>
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import loadable from '@loadable/component'
|
import loadable from '@loadable/component'
|
||||||
import { useSpring, animated } from 'react-spring'
|
import { useSpring, animated } from 'react-spring'
|
||||||
import { useWeb3 } from '@oceanprotocol/react'
|
|
||||||
import Account from './Account'
|
import Account from './Account'
|
||||||
import Details from './Details'
|
import Details from './Details'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
|
import { useOcean } from '@oceanprotocol/react'
|
||||||
|
|
||||||
const Tippy = loadable(() => import('@tippyjs/react/headless'))
|
const Tippy = loadable(() => import('@tippyjs/react/headless'))
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ const animation = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function Wallet(): ReactElement {
|
export default function Wallet(): ReactElement {
|
||||||
const { account, ethProviderStatus } = useWeb3()
|
const { accountId } = useOcean()
|
||||||
const [props, setSpring] = useSpring(() => animation.from)
|
const [props, setSpring] = useSpring(() => animation.from)
|
||||||
|
|
||||||
function onMount() {
|
function onMount() {
|
||||||
@ -34,14 +34,12 @@ export default function Wallet(): ReactElement {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const isEthProviderAbsent = ethProviderStatus === -1
|
|
||||||
if (isEthProviderAbsent) return null
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tippy
|
<Tippy
|
||||||
interactive
|
interactive
|
||||||
interactiveBorder={30}
|
interactiveBorder={30}
|
||||||
trigger="click focus"
|
trigger="click focus"
|
||||||
|
zIndex={1}
|
||||||
render={(attrs: any) => (
|
render={(attrs: any) => (
|
||||||
<animated.div style={props}>
|
<animated.div style={props}>
|
||||||
<Details attrs={attrs} />
|
<Details attrs={attrs} />
|
||||||
@ -53,7 +51,7 @@ export default function Wallet(): ReactElement {
|
|||||||
animation
|
animation
|
||||||
onMount={onMount}
|
onMount={onMount}
|
||||||
onHide={onHide}
|
onHide={onHide}
|
||||||
disabled={!account}
|
disabled={!accountId}
|
||||||
fallback={<Account />}
|
fallback={<Account />}
|
||||||
>
|
>
|
||||||
<Account />
|
<Account />
|
||||||
|
@ -2,7 +2,7 @@ import React, { ReactElement } from 'react'
|
|||||||
import Compute from './Compute'
|
import Compute from './Compute'
|
||||||
import ddo from '../../../../tests/unit/__fixtures__/ddo'
|
import ddo from '../../../../tests/unit/__fixtures__/ddo'
|
||||||
import web3Mock from '../../../../tests/unit/__mocks__/web3'
|
import web3Mock from '../../../../tests/unit/__mocks__/web3'
|
||||||
import squidMock from '../../../../tests/unit/__mocks__/@oceanprotocol/squid'
|
import squidMock from '../../../../tests/unit/__mocks__/@oceanprotocol/lib'
|
||||||
import { context } from '../../../../tests/unit/__mocks__/web3provider'
|
import { context } from '../../../../tests/unit/__mocks__/web3provider'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect, ReactElement } from 'react'
|
import React, { useState, useEffect, ReactElement } from 'react'
|
||||||
import { Ocean } from '@oceanprotocol/squid'
|
import { Ocean } from '@oceanprotocol/lib'
|
||||||
import { fromWei } from 'web3-utils'
|
import { fromWei } from 'web3-utils'
|
||||||
import compareAsBN, { Comparisson } from '../../../utils/compareAsBN'
|
import compareAsBN, { Comparisson } from '../../../utils/compareAsBN'
|
||||||
import Loader from '../../atoms/Loader'
|
import Loader from '../../atoms/Loader'
|
||||||
|
@ -13,7 +13,7 @@ export default function AssetActions({
|
|||||||
metadata: MetaDataMarket
|
metadata: MetaDataMarket
|
||||||
did: string
|
did: string
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { ocean, balanceInOcean } = useOcean()
|
// const { ocean, balanceInOcean } = useOcean()
|
||||||
const { access } = metadata.additionalInformation
|
const { access } = metadata.additionalInformation
|
||||||
const isCompute = access && access === 'Compute'
|
const isCompute = access && access === 'Compute'
|
||||||
|
|
||||||
@ -26,12 +26,13 @@ export default function AssetActions({
|
|||||||
<div className={styles.tabContent}>
|
<div className={styles.tabContent}>
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
{isCompute ? (
|
{isCompute ? (
|
||||||
<Compute
|
// <Compute
|
||||||
did={did}
|
// did={did}
|
||||||
metadata={metadata}
|
// metadata={metadata}
|
||||||
ocean={ocean}
|
// ocean={ocean}
|
||||||
balance={balanceInOcean}
|
// balance={balanceInOcean}
|
||||||
/>
|
// />
|
||||||
|
'Compute Me'
|
||||||
) : (
|
) : (
|
||||||
<Consume did={did} metadata={metadata} />
|
<Consume did={did} metadata={metadata} />
|
||||||
)}
|
)}
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
.metaFull {
|
.metaFull {
|
||||||
margin-top: calc(var(--spacer) * 2);
|
margin-top: calc(var(--spacer) * 2);
|
||||||
font-size: var(--font-size-small);
|
font-size: var(--font-size-small);
|
||||||
padding: var(--spacer);
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
background: var(--brand-grey-dimmed);
|
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: var(--spacer);
|
gap: var(--spacer);
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
|
@ -12,35 +12,14 @@ export default function MetaFull({
|
|||||||
metadata: MetaDataMarket
|
metadata: MetaDataMarket
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { dateCreated, datePublished, author, license } = metadata.main
|
const { dateCreated, datePublished, author, license } = metadata.main
|
||||||
let dateRange
|
const { categories } = metadata.additionalInformation
|
||||||
if (metadata && metadata.additionalInformation) {
|
|
||||||
;({ dateRange } = metadata.additionalInformation)
|
|
||||||
}
|
|
||||||
|
|
||||||
// In practice dateRange will always be defined, but in the rare case it isn't
|
|
||||||
// we put something to prevent errors
|
|
||||||
if (!dateRange) {
|
|
||||||
dateRange = [dateCreated, dateCreated]
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.metaFull}>
|
<div className={styles.metaFull}>
|
||||||
<MetaItem title="Author" content={author} />
|
<MetaItem title="Author" content={author} />
|
||||||
<MetaItem title="License" content={license} />
|
<MetaItem title="License" content={license} />
|
||||||
<MetaItem
|
<MetaItem title="Category" content={categories[0]} />
|
||||||
title="Data Created"
|
<MetaItem title="Data Created" content={<Time date={dateCreated} />} />
|
||||||
content={
|
|
||||||
dateRange && dateRange[0] !== dateRange[1] ? (
|
|
||||||
<>
|
|
||||||
<Time date={dateRange[0]} />
|
|
||||||
{' – '}
|
|
||||||
<Time date={dateRange[1]} />
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<Time date={dateRange[0]} />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<MetaItem
|
<MetaItem
|
||||||
title="Data Published"
|
title="Data Published"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement, ReactNode } from 'react'
|
||||||
import styles from './MetaItem.module.css'
|
import styles from './MetaItem.module.css'
|
||||||
|
|
||||||
export default function MetaItem({
|
export default function MetaItem({
|
||||||
@ -6,7 +6,7 @@ export default function MetaItem({
|
|||||||
content
|
content
|
||||||
}: {
|
}: {
|
||||||
title: string
|
title: string
|
||||||
content: any
|
content: ReactNode
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
return (
|
return (
|
||||||
<div className={styles.metaItem}>
|
<div className={styles.metaItem}>
|
||||||
|
@ -12,6 +12,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.samples {
|
.samples {
|
||||||
composes: box from '../../atoms/Box.module.css';
|
|
||||||
margin-top: calc(var(--spacer) / 2);
|
margin-top: calc(var(--spacer) / 2);
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,14 @@ import { ListItem } from '../../atoms/Lists'
|
|||||||
import MetaItem from './MetaItem'
|
import MetaItem from './MetaItem'
|
||||||
import styles from './MetaSecondary.module.css'
|
import styles from './MetaSecondary.module.css'
|
||||||
import { MetaDataMarket } from '../../../@types/MetaData'
|
import { MetaDataMarket } from '../../../@types/MetaData'
|
||||||
|
import Tags from '../../atoms/Tags'
|
||||||
|
|
||||||
export default function MetaSecondary({
|
export default function MetaSecondary({
|
||||||
metadata
|
metadata
|
||||||
}: {
|
}: {
|
||||||
metadata: MetaDataMarket
|
metadata: MetaDataMarket
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
let links
|
const { links, tags } = metadata.additionalInformation
|
||||||
if (metadata && metadata.additionalInformation) {
|
|
||||||
;({ links } = metadata.additionalInformation)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<aside className={styles.metaSecondary}>
|
<aside className={styles.metaSecondary}>
|
||||||
@ -33,6 +31,8 @@ export default function MetaSecondary({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{tags && tags.length > 0 && <Tags items={tags} />}
|
||||||
</aside>
|
</aside>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
.rating {
|
|
||||||
composes: box from '../../atoms/Box.module.css';
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
flex-direction: column;
|
|
||||||
margin-top: 5px;
|
|
||||||
padding: 20px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rating svg {
|
|
||||||
width: var(--font-size-h3);
|
|
||||||
height: var(--font-size-h3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: var(--font-size-large);
|
|
||||||
}
|
|
||||||
|
|
||||||
.success {
|
|
||||||
background-color: var(--green);
|
|
||||||
}
|
|
||||||
|
|
||||||
.error {
|
|
||||||
background-color: var(--red);
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
import React, { useState, useEffect, ReactElement } from 'react'
|
|
||||||
import { toast } from 'react-toastify'
|
|
||||||
import Rating from '../../atoms/Rating'
|
|
||||||
import rateAsset from '../../../utils/rateAsset'
|
|
||||||
import { DID } from '@oceanprotocol/squid'
|
|
||||||
import styles from './RatingAction.module.css'
|
|
||||||
import getAssetRating from '../../../utils/getAssetRating'
|
|
||||||
import Loader from '../../atoms/Loader'
|
|
||||||
import { useWeb3 } from '@oceanprotocol/react'
|
|
||||||
export default function RatingAction({
|
|
||||||
did,
|
|
||||||
onVote
|
|
||||||
}: {
|
|
||||||
did: DID | string
|
|
||||||
onVote: () => void
|
|
||||||
}): ReactElement {
|
|
||||||
const { web3, account } = useWeb3()
|
|
||||||
const [rating, setRating] = useState<number>(0)
|
|
||||||
const [isloading, setIsLoading] = useState(false)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
async function getOwnRating() {
|
|
||||||
if (!account) return
|
|
||||||
const currentRating = await getAssetRating(did, account)
|
|
||||||
currentRating && setRating(currentRating.vote)
|
|
||||||
}
|
|
||||||
getOwnRating()
|
|
||||||
}, [account])
|
|
||||||
|
|
||||||
async function handleRatingClick(value: number) {
|
|
||||||
if (!web3) return
|
|
||||||
setIsLoading(true)
|
|
||||||
try {
|
|
||||||
const response = await rateAsset(did, web3, value)
|
|
||||||
if (!response) return
|
|
||||||
|
|
||||||
onVote()
|
|
||||||
setRating(value)
|
|
||||||
toast.success('Thank you for rating!', {
|
|
||||||
className: styles.success
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
toast.error(`There was an error: ${error.message}`, {
|
|
||||||
className: styles.error
|
|
||||||
})
|
|
||||||
}
|
|
||||||
setIsLoading(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
return account ? (
|
|
||||||
<aside className={styles.rating}>
|
|
||||||
<h3 className={styles.title}>Review this data</h3>
|
|
||||||
|
|
||||||
{isloading ? (
|
|
||||||
<Loader />
|
|
||||||
) : (
|
|
||||||
<Rating
|
|
||||||
curation={{ rating: rating, numVotes: 0 }}
|
|
||||||
isLoading={isloading}
|
|
||||||
onClick={handleRatingClick}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</aside>
|
|
||||||
) : null
|
|
||||||
}
|
|
@ -1,13 +1,17 @@
|
|||||||
.grid {
|
.grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: calc(var(--spacer) * 1.5);
|
gap: calc(var(--spacer) * 2);
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-top: -1.5rem;
|
margin-top: -1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
composes: box from '../../atoms/Box.module.css';
|
||||||
|
margin-top: var(--spacer);
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: 60rem) {
|
@media (min-width: 60rem) {
|
||||||
.grid {
|
.grid {
|
||||||
gap: calc(var(--spacer) * 3);
|
|
||||||
/* lazy golden ratio */
|
/* lazy golden ratio */
|
||||||
grid-template-columns: 1.618fr minmax(0, 1fr);
|
grid-template-columns: 1.618fr minmax(0, 1fr);
|
||||||
}
|
}
|
||||||
@ -15,7 +19,7 @@
|
|||||||
.sticky {
|
.sticky {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: calc(var(--spacer) / 2);
|
top: calc(var(--spacer) / 2);
|
||||||
margin-top: calc(var(--spacer) * 1.5);
|
margin-top: var(--spacer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import { MetaDataMarket } from '../../../@types/MetaData'
|
import { MetaDataMarket } from '../../../@types/MetaData'
|
||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import { useOcean } from '@oceanprotocol/react'
|
|
||||||
import Time from '../../atoms/Time'
|
import Time from '../../atoms/Time'
|
||||||
import { Link } from 'gatsby'
|
import { Link } from 'gatsby'
|
||||||
import Markdown from '../../atoms/Markdown'
|
import Markdown from '../../atoms/Markdown'
|
||||||
import Tags from '../../atoms/Tags'
|
|
||||||
import MetaFull from './MetaFull'
|
import MetaFull from './MetaFull'
|
||||||
import MetaSecondary from './MetaSecondary'
|
import MetaSecondary from './MetaSecondary'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
@ -21,42 +19,24 @@ export default function AssetContent({
|
|||||||
did
|
did
|
||||||
}: AssetContentProps): ReactElement {
|
}: AssetContentProps): ReactElement {
|
||||||
const { datePublished } = metadata.main
|
const { datePublished } = metadata.main
|
||||||
const { description, categories, tags } = metadata.additionalInformation
|
const { description, categories } = metadata.additionalInformation
|
||||||
|
|
||||||
// const { curation } = metadata
|
|
||||||
|
|
||||||
// const { getCuration } = useMetadata()
|
|
||||||
// const [rating, setRating] = useState<number>(curation ? curation.rating : 0)
|
|
||||||
// const [numVotes, setNumVotes] = useState<number>(
|
|
||||||
// curation ? curation.numVotes : 0
|
|
||||||
// )
|
|
||||||
|
|
||||||
// const onVoteUpdate = async () => {
|
|
||||||
// const { rating, numVotes } = await getCuration(did)
|
|
||||||
|
|
||||||
// setRating(rating)
|
|
||||||
// setNumVotes(numVotes)
|
|
||||||
// }
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<article className={styles.grid}>
|
<article className={styles.grid}>
|
||||||
<div>
|
<div className={styles.content}>
|
||||||
<aside className={styles.meta}>
|
<aside className={styles.meta}>
|
||||||
<p>{datePublished && <Time date={datePublished} />}</p>
|
<p>{datePublished && <Time date={datePublished} />}</p>
|
||||||
{categories && (
|
{categories && (
|
||||||
<p>
|
<p>
|
||||||
<Link to={`/search?categories=["${categories[0]}"]`}>
|
<Link to={`/search?categories=["${categories[0]}"]`}>
|
||||||
<a>{categories[0]}</a>
|
{categories[0]}
|
||||||
</Link>
|
</Link>
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
{/* <Rating curation={{ rating, numVotes }} readonly /> */}
|
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<Markdown text={description || ''} />
|
<Markdown text={description || ''} />
|
||||||
|
|
||||||
{tags && tags.length > 0 && <Tags items={tags} />}
|
|
||||||
|
|
||||||
<MetaSecondary metadata={metadata} />
|
<MetaSecondary metadata={metadata} />
|
||||||
|
|
||||||
<MetaFull did={did} metadata={metadata} />
|
<MetaFull did={did} metadata={metadata} />
|
||||||
@ -74,8 +54,6 @@ export default function AssetContent({
|
|||||||
<div>
|
<div>
|
||||||
<div className={styles.sticky}>
|
<div className={styles.sticky}>
|
||||||
<AssetActions metadata={metadata} did={did} />
|
<AssetActions metadata={metadata} did={did} />
|
||||||
|
|
||||||
{/* <RatingAction did={did} onVote={onVoteUpdate} /> */}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
@ -10,3 +10,9 @@
|
|||||||
gap: var(--spacer);
|
gap: var(--spacer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.empty {
|
||||||
|
color: var(--color-secondary);
|
||||||
|
font-size: var(--font-size-small);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { DDO } from '@oceanprotocol/squid'
|
import { DDO } from '@oceanprotocol/lib'
|
||||||
import AssetList from './AssetList'
|
import AssetList from './AssetList'
|
||||||
import asset from '../../../tests/unit/__fixtures__/ddo'
|
import asset from '../../../tests/unit/__fixtures__/ddo'
|
||||||
|
|
||||||
|
@ -1,64 +1,77 @@
|
|||||||
import AssetTeaser from '../molecules/AssetTeaser'
|
import AssetTeaser from '../molecules/AssetTeaser'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { QueryResult } from '@oceanprotocol/squid/dist/node/aquarius/Aquarius'
|
import { QueryResult } from '@oceanprotocol/lib/dist/node/metadatastore/MetadataStore'
|
||||||
import shortid from 'shortid'
|
import { useLocation, useNavigate } from '@reach/router'
|
||||||
import Pagination from '../molecules/Pagination'
|
import Pagination from '../molecules/Pagination'
|
||||||
import { updateQueryStringParameter } from '../../utils'
|
import { updateQueryStringParameter } from '../../utils'
|
||||||
import styles from './AssetList.module.css'
|
import styles from './AssetList.module.css'
|
||||||
import { MetaDataMarket } from '../../@types/MetaData'
|
import { MetaDataMarket } from '../../@types/MetaData'
|
||||||
import { DDO } from '@oceanprotocol/squid'
|
import { DDO } from '@oceanprotocol/lib'
|
||||||
|
import { useSiteMetadata } from '../../hooks/useSiteMetadata'
|
||||||
|
|
||||||
declare type AssetListProps = {
|
declare type AssetListProps = {
|
||||||
queryResult: QueryResult
|
queryResult: QueryResult
|
||||||
}
|
}
|
||||||
|
|
||||||
const AssetList: React.FC<AssetListProps> = ({ queryResult }) => {
|
const AssetList: React.FC<AssetListProps> = ({ queryResult }) => {
|
||||||
|
const { appConfig } = useSiteMetadata()
|
||||||
|
const location = useLocation()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
// Construct the urls on the pagination links. This is only for UX,
|
// Construct the urls on the pagination links. This is only for UX,
|
||||||
// since the links are no <Link> they will not work by itself.
|
// since the links are no <Link> they will not work by itself.
|
||||||
// function hrefBuilder(pageIndex: number) {
|
function hrefBuilder(pageIndex: number) {
|
||||||
// const newUrl = updateQueryStringParameter(
|
const newUrl = updateQueryStringParameter(
|
||||||
// router.asPath,
|
location.pathname + location.search,
|
||||||
// 'page',
|
'page',
|
||||||
// `${pageIndex}`
|
`${pageIndex}`
|
||||||
// )
|
)
|
||||||
// return newUrl
|
return newUrl
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // This is what iniitates a new search with new `page`
|
// // This is what iniitates a new search with new `page`
|
||||||
// // url parameter
|
// // url parameter
|
||||||
// function onPageChange(selected: number) {
|
function onPageChange(selected: number) {
|
||||||
// const newUrl = updateQueryStringParameter(
|
const newUrl = updateQueryStringParameter(
|
||||||
// router.asPath,
|
location.pathname + location.search,
|
||||||
// 'page',
|
'page',
|
||||||
// `${selected + 1}`
|
`${selected + 1}`
|
||||||
// )
|
)
|
||||||
// return router.push(newUrl)
|
return navigate(newUrl)
|
||||||
// }
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={styles.assetList}>
|
<div className={styles.assetList}>
|
||||||
{queryResult &&
|
{queryResult && queryResult.totalResults > 0 ? (
|
||||||
queryResult.results.map((ddo: DDO) => {
|
queryResult.results.map((ddo: DDO) => {
|
||||||
const { attributes }: MetaDataMarket = new DDO(
|
const { attributes }: MetaDataMarket = ddo.findServiceByType(
|
||||||
ddo
|
'metadata'
|
||||||
).findServiceByType('metadata')
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AssetTeaser
|
<AssetTeaser did={ddo.id} metadata={attributes} key={ddo.id} />
|
||||||
did={ddo.id}
|
|
||||||
metadata={attributes}
|
|
||||||
key={shortid.generate()}
|
|
||||||
/>
|
|
||||||
)
|
)
|
||||||
})}
|
})
|
||||||
|
) : (
|
||||||
|
<div className={styles.empty}>
|
||||||
|
No results found in {appConfig.oceanConfig.metadataStoreUri}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{/* <Pagination
|
|
||||||
totalPages={queryResult.totalPages}
|
{/*
|
||||||
currentPage={queryResult.page}
|
Little hack cause the pagination navigation only works
|
||||||
hrefBuilder={hrefBuilder}
|
on the search page right now.
|
||||||
onPageChange={onPageChange}
|
*/}
|
||||||
/> */}
|
{location.pathname === '/search' && queryResult && (
|
||||||
|
<Pagination
|
||||||
|
totalPages={queryResult.totalPages}
|
||||||
|
currentPage={queryResult.page}
|
||||||
|
hrefBuilder={hrefBuilder}
|
||||||
|
onPageChange={onPageChange}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import Price from '../atoms/Price'
|
|||||||
import { fromWei } from 'web3-utils'
|
import { fromWei } from 'web3-utils'
|
||||||
import DateCell from '../atoms/Table/DateCell'
|
import DateCell from '../atoms/Table/DateCell'
|
||||||
import DdoLinkCell from '../atoms/Table/DdoLinkCell'
|
import DdoLinkCell from '../atoms/Table/DdoLinkCell'
|
||||||
import { MetaDataMain } from '@oceanprotocol/squid'
|
import { MetaDataMain } from '@oceanprotocol/lib'
|
||||||
|
|
||||||
const consumedColumns = [
|
const consumedColumns = [
|
||||||
{
|
{
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
.header {
|
.header {
|
||||||
background-color: var(--brand-white);
|
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import Price from '../atoms/Price'
|
|||||||
import { fromWei } from 'web3-utils'
|
import { fromWei } from 'web3-utils'
|
||||||
import Table from '../atoms/Table'
|
import Table from '../atoms/Table'
|
||||||
import Button from '../atoms/Button'
|
import Button from '../atoms/Button'
|
||||||
import { MetaDataMain, Logger } from '@oceanprotocol/squid'
|
import { MetaDataMain, Logger } from '@oceanprotocol/lib'
|
||||||
import DateCell from '../atoms/Table/DateCell'
|
import DateCell from '../atoms/Table/DateCell'
|
||||||
import DdoLinkCell from '../atoms/Table/DdoLinkCell'
|
import DdoLinkCell from '../atoms/Table/DdoLinkCell'
|
||||||
import shortid from 'shortid'
|
import shortid from 'shortid'
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { useEffect, useState, ReactElement } from 'react'
|
import React, { useEffect, useState, ReactElement } from 'react'
|
||||||
import Loader from '../atoms/Loader'
|
import Loader from '../atoms/Loader'
|
||||||
import { MetaDataMain } from '@oceanprotocol/squid'
|
import { MetaDataMain } from '@oceanprotocol/lib'
|
||||||
import {
|
import {
|
||||||
useOcean,
|
useOcean,
|
||||||
OceanConnectionStatus,
|
OceanConnectionStatus,
|
||||||
|
@ -15,3 +15,8 @@
|
|||||||
top: var(--spacer);
|
top: var(--spacer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
composes: box from '../atoms/Box.module.css';
|
||||||
|
margin-top: var(--spacer);
|
||||||
|
}
|
||||||
|
@ -8,15 +8,15 @@ import JobsList from '../organisms/JobsList'
|
|||||||
const sections = [
|
const sections = [
|
||||||
{
|
{
|
||||||
title: 'Published',
|
title: 'Published',
|
||||||
component: <PublishedList />
|
component: 'Coming Soon...'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Downloaded',
|
title: 'Downloaded',
|
||||||
component: <ConsumedList />
|
component: 'Coming Soon...'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Compute Jobs',
|
title: 'Compute Jobs',
|
||||||
component: <JobsList />
|
component: 'Coming Soon...'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ const Section = ({ title, component }: { title: string; component: any }) => {
|
|||||||
const HistoryPage: React.FC = () => {
|
const HistoryPage: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<article className={styles.grid}>
|
<article className={styles.grid}>
|
||||||
<div>
|
<div className={styles.content}>
|
||||||
{sections.map((section) => {
|
{sections.map((section) => {
|
||||||
const { title, component } = section
|
const { title, component } = section
|
||||||
return <Section key={title} title={title} component={component} />
|
return <Section key={title} title={title} component={component} />
|
||||||
|
@ -1,3 +1,14 @@
|
|||||||
.grid {
|
.searchWrap {
|
||||||
composes: assetList from '../organisms/AssetList.module.css';
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: calc(var(--spacer) * var(--line-height));
|
||||||
|
}
|
||||||
|
|
||||||
|
.latest {
|
||||||
|
margin-top: calc(var(--spacer) * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.latest h3 {
|
||||||
|
font-size: var(--font-size-large);
|
||||||
|
color: var(--color-secondary);
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,60 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement, useEffect, useState } from 'react'
|
||||||
import SearchBar from '../molecules/SearchBar'
|
import SearchBar from '../molecules/SearchBar'
|
||||||
import shortid from 'shortid'
|
|
||||||
import { OceanAsset } from '../../@types/MetaData'
|
|
||||||
import AssetTeaser from '../molecules/AssetTeaser'
|
|
||||||
import styles from './Home.module.css'
|
import styles from './Home.module.css'
|
||||||
|
import { MetadataStore, Logger } from '@oceanprotocol/lib'
|
||||||
|
import AssetList from '../organisms/AssetList'
|
||||||
|
import { QueryResult } from '@oceanprotocol/lib/dist/node/metadatastore/MetadataStore'
|
||||||
|
import Container from '../atoms/Container'
|
||||||
|
import Loader from '../atoms/Loader'
|
||||||
|
import { useSiteMetadata } from '../../hooks/useSiteMetadata'
|
||||||
|
|
||||||
|
async function getLatestAssets(metadataStoreUri: string) {
|
||||||
|
try {
|
||||||
|
const metadataStore = new MetadataStore(metadataStoreUri, Logger)
|
||||||
|
|
||||||
|
const result = await metadataStore.queryMetadata({
|
||||||
|
page: 1,
|
||||||
|
offset: 10,
|
||||||
|
query: {},
|
||||||
|
sort: { created: -1 }
|
||||||
|
})
|
||||||
|
|
||||||
|
return result
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function HomePage(): ReactElement {
|
||||||
|
const { appConfig } = useSiteMetadata()
|
||||||
|
const [queryResult, setQueryResult] = useState<QueryResult>()
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function init() {
|
||||||
|
const results = await getLatestAssets(
|
||||||
|
appConfig.oceanConfig.metadataStoreUri
|
||||||
|
)
|
||||||
|
setQueryResult(results)
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
init()
|
||||||
|
}, [])
|
||||||
|
|
||||||
export default function HomePage({
|
|
||||||
assets
|
|
||||||
}: {
|
|
||||||
assets: {
|
|
||||||
node: OceanAsset
|
|
||||||
}[]
|
|
||||||
}): ReactElement {
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SearchBar large />
|
<Container narrow className={styles.searchWrap}>
|
||||||
{assets && (
|
<SearchBar large />
|
||||||
<div className={styles.grid}>
|
</Container>
|
||||||
{assets.map(({ node }: { node: OceanAsset }) => (
|
|
||||||
<AssetTeaser
|
<section className={styles.latest}>
|
||||||
key={shortid.generate()}
|
<h3>Latest Data Sets</h3>
|
||||||
did={node.did}
|
{loading ? (
|
||||||
metadata={node}
|
<Loader />
|
||||||
/>
|
) : (
|
||||||
))}
|
queryResult && <AssetList queryResult={queryResult} />
|
||||||
</div>
|
)}
|
||||||
)}
|
</section>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import { useOcean } from '@oceanprotocol/react'
|
|||||||
import {
|
import {
|
||||||
Service,
|
Service,
|
||||||
ServiceCompute
|
ServiceCompute
|
||||||
} from '@oceanprotocol/squid/dist/node/ddo/Service'
|
} from '@oceanprotocol/lib/dist/node/ddo/Service'
|
||||||
import { Formik, Form as FormFormik, Field } from 'formik'
|
import { Formik, Form as FormFormik, Field } from 'formik'
|
||||||
import Input from '../../atoms/Input'
|
import Input from '../../atoms/Input'
|
||||||
import Button from '../../atoms/Button'
|
import Button from '../../atoms/Button'
|
||||||
@ -15,7 +15,7 @@ import { transformPublishFormToMetadata } from './utils'
|
|||||||
import { FormContent, FormFieldProps } from '../../../@types/Form'
|
import { FormContent, FormFieldProps } from '../../../@types/Form'
|
||||||
import { MetaDataPublishForm } from '../../../@types/MetaData'
|
import { MetaDataPublishForm } from '../../../@types/MetaData'
|
||||||
import AssetModel from '../../../models/Asset'
|
import AssetModel from '../../../models/Asset'
|
||||||
import { File } from '@oceanprotocol/squid'
|
import { File } from '@oceanprotocol/lib'
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape<MetaDataPublishForm>({
|
const validationSchema = Yup.object().shape<MetaDataPublishForm>({
|
||||||
// ---- required fields ----
|
// ---- required fields ----
|
||||||
@ -81,7 +81,7 @@ export default function PublishForm({
|
|||||||
// account,
|
// account,
|
||||||
// metadata.main.price,
|
// metadata.main.price,
|
||||||
// // Note: a hack without consequences.
|
// // Note: a hack without consequences.
|
||||||
// // Will make metadata.main.datePublished (automatically created by Aquarius)
|
// // Will make metadata.main.datePublished (automatically created by MetadataStore)
|
||||||
// // go out of sync with this service.main.datePublished.
|
// // go out of sync with this service.main.datePublished.
|
||||||
// toStringNoMS(new Date(Date.now()))
|
// toStringNoMS(new Date(Date.now()))
|
||||||
// )
|
// )
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
import React, { ReactElement } from 'react'
|
|
||||||
import { PageProps, graphql } from 'gatsby'
|
|
||||||
import Layout from '../Layout'
|
|
||||||
import AssetContent from '../organisms/AssetContent'
|
|
||||||
|
|
||||||
export default function AssetDetailsTemplate(props: PageProps): ReactElement {
|
|
||||||
const { oceanAsset } = props.data as any
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Layout title={oceanAsset.main.name} uri={props.path}>
|
|
||||||
<AssetContent did={oceanAsset.did} metadata={oceanAsset} />
|
|
||||||
</Layout>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const templateQuery = graphql`
|
|
||||||
query OceanAssetByDid($did: String!) {
|
|
||||||
oceanAsset(did: { eq: $did }) {
|
|
||||||
did
|
|
||||||
main {
|
|
||||||
type
|
|
||||||
name
|
|
||||||
dateCreated
|
|
||||||
author
|
|
||||||
license
|
|
||||||
price
|
|
||||||
datePublished
|
|
||||||
files {
|
|
||||||
index
|
|
||||||
contentType
|
|
||||||
}
|
|
||||||
}
|
|
||||||
additionalInformation {
|
|
||||||
description
|
|
||||||
deliveryType
|
|
||||||
termsAndConditions
|
|
||||||
access
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
@ -1,8 +1,3 @@
|
|||||||
.empty {
|
|
||||||
color: var(--color-secondary);
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid {
|
.grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
}
|
}
|
||||||
@ -10,17 +5,21 @@
|
|||||||
@media (min-width: 55rem) {
|
@media (min-width: 55rem) {
|
||||||
.grid {
|
.grid {
|
||||||
grid-column-gap: calc(var(--spacer) * 3);
|
grid-column-gap: calc(var(--spacer) * 3);
|
||||||
grid-template-columns: minmax(0, 1fr) 3fr;
|
grid-template-columns: minmax(0, 3fr) 1fr;
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
'side search'
|
'search side'
|
||||||
'side results';
|
'results side';
|
||||||
}
|
}
|
||||||
|
|
||||||
.search {
|
.search {
|
||||||
grid-area: search;
|
grid-area: search;
|
||||||
}
|
}
|
||||||
|
|
||||||
.side {
|
.side {
|
||||||
grid-area: side;
|
grid-area: side;
|
||||||
|
margin-top: calc(var(--spacer) * 2.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.results {
|
.results {
|
||||||
grid-area: results;
|
grid-area: results;
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import React, { ReactElement, useState, useEffect } from 'react'
|
import React, { ReactElement, useState, useEffect } from 'react'
|
||||||
import { QueryResult } from '@oceanprotocol/squid/dist/node/aquarius/Aquarius'
|
import { QueryResult } from '@oceanprotocol/lib/dist/node/metadatastore/MetadataStore'
|
||||||
import SearchBar from '../../molecules/SearchBar'
|
import SearchBar from '../../molecules/SearchBar'
|
||||||
import AssetList from '../../organisms/AssetList'
|
import AssetList from '../../organisms/AssetList'
|
||||||
import { SearchPriceFilter } from '../../molecules/SearchPriceFilter'
|
import { SearchPriceFilter } from '../../molecules/SearchPriceFilter'
|
||||||
|
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import queryString from 'query-string'
|
import queryString from 'query-string'
|
||||||
import { getResults } from './utils'
|
import { getResults } from './utils'
|
||||||
|
import Loader from '../../atoms/Loader'
|
||||||
|
|
||||||
export declare type SearchPageProps = {
|
export declare type SearchPageProps = {
|
||||||
text: string | string[]
|
text: string | string[]
|
||||||
@ -20,16 +20,19 @@ export default function SearchPage({
|
|||||||
location: Location
|
location: Location
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const parsed = queryString.parse(location.search)
|
const parsed = queryString.parse(location.search)
|
||||||
const { text, tag } = parsed
|
const { text, tag, page } = parsed
|
||||||
const [queryResult, setQueryResult] = useState<QueryResult>()
|
const [queryResult, setQueryResult] = useState<QueryResult>()
|
||||||
|
const [loading, setLoading] = useState<boolean>()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function initSearch() {
|
async function initSearch() {
|
||||||
|
setLoading(true)
|
||||||
const queryResult = await getResults(parsed)
|
const queryResult = await getResults(parsed)
|
||||||
setQueryResult(queryResult)
|
setQueryResult(queryResult)
|
||||||
|
setLoading(false)
|
||||||
}
|
}
|
||||||
initSearch()
|
initSearch()
|
||||||
}, [parsed])
|
}, [text, tag, page])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={styles.grid}>
|
<section className={styles.grid}>
|
||||||
@ -42,11 +45,7 @@ export default function SearchPage({
|
|||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<div className={styles.results}>
|
<div className={styles.results}>
|
||||||
{queryResult && queryResult.results.length > 0 ? (
|
{loading ? <Loader /> : <AssetList queryResult={queryResult} />}
|
||||||
<AssetList queryResult={queryResult} />
|
|
||||||
) : (
|
|
||||||
<div className={styles.empty}>No results found.</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import {
|
import {
|
||||||
SearchQuery,
|
SearchQuery,
|
||||||
QueryResult
|
QueryResult
|
||||||
} from '@oceanprotocol/squid/dist/node/aquarius/Aquarius'
|
} from '@oceanprotocol/lib/dist/node/metadatastore/MetadataStore'
|
||||||
import { priceQueryParamToWei } from '../../../utils'
|
import { priceQueryParamToWei } from '../../../utils'
|
||||||
import { Aquarius, Logger } from '@oceanprotocol/squid'
|
import { MetadataStore, Logger } from '@oceanprotocol/lib'
|
||||||
import { oceanConfig } from '../../../../app.config'
|
import { oceanConfig } from '../../../../app.config'
|
||||||
|
|
||||||
export function getSearchQuery(
|
export function getSearchQuery(
|
||||||
@ -52,8 +52,8 @@ export async function getResults(params: any): Promise<QueryResult> {
|
|||||||
])
|
])
|
||||||
: undefined
|
: undefined
|
||||||
|
|
||||||
const aquarius = new Aquarius(oceanConfig.aquariusUri, Logger)
|
const metadataStore = new MetadataStore(oceanConfig.metadataStoreUri, Logger)
|
||||||
const queryResult = await aquarius.queryMetadata(
|
const queryResult = await metadataStore.queryMetadata(
|
||||||
getSearchQuery(page, offset, text, tag, priceQuery)
|
getSearchQuery(page, offset, text, tag, priceQuery)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ import { ToastContainer } from 'react-toastify'
|
|||||||
|
|
||||||
import '@oceanprotocol/typographies/css/ocean-typo.css'
|
import '@oceanprotocol/typographies/css/ocean-typo.css'
|
||||||
import '../global/styles.css'
|
import '../global/styles.css'
|
||||||
import 'react-toastify/dist/ReactToastify.css'
|
|
||||||
|
|
||||||
export default function Styles({
|
export default function Styles({
|
||||||
children
|
children
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
@import '../../node_modules/react-toastify/dist/ReactToastify.css';
|
||||||
|
|
||||||
div.Toastify__toast {
|
div.Toastify__toast {
|
||||||
font-family: var(--font-family-base);
|
font-family: var(--font-family-base);
|
||||||
font-size: var(--font-size-small);
|
font-size: var(--font-size-small);
|
||||||
|
68
src/global/_web3modal.css
Normal file
68
src/global/_web3modal.css
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
div.web3modal-modal-lightbox {
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
backdrop-filter: blur(3px);
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
animation: fadeIn 0.2s ease-out backwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.web3modal-modal-card {
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
padding: var(--spacer);
|
||||||
|
margin: var(--spacer) auto;
|
||||||
|
max-width: var(--break-point--small);
|
||||||
|
border: 1px solid var(--brand-grey-lighter);
|
||||||
|
box-shadow: 0 6px 15px 0 rgba(0, 0, 0, 0.05);
|
||||||
|
animation: moveUp 0.2s ease-out backwards;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
div.web3modal-provider-wrapper {
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.web3modal-provider-container {
|
||||||
|
padding: var(--spacer);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.web3modal-provider-icon {
|
||||||
|
filter: grayscale(1) contrast(150%);
|
||||||
|
transition: filter 0.2s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.web3modal-provider-wrapper:hover div.web3modal-provider-icon {
|
||||||
|
filter: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.web3modal-provider-name {
|
||||||
|
font-size: var(--font-size-large);
|
||||||
|
font-weight: var(--font-weight-bold);
|
||||||
|
font-family: var(--font-family-title);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.web3modal-provider-description {
|
||||||
|
font-size: var(--font-size-base);
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes moveUp {
|
||||||
|
from {
|
||||||
|
transform: translate3d(0, 1rem, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
@ -134,3 +134,4 @@ fieldset {
|
|||||||
|
|
||||||
@import '_code.css';
|
@import '_code.css';
|
||||||
@import '_toast.css';
|
@import '_toast.css';
|
||||||
|
@import '_web3modal.css';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import { Web3Provider, OceanProvider, Config } from '@oceanprotocol/react'
|
import { OceanProvider } from '@oceanprotocol/react'
|
||||||
import { oceanConfig } from '../../app.config'
|
import { oceanConfig } from '../../app.config'
|
||||||
|
|
||||||
const wrapRootElement = ({
|
const wrapRootElement = ({
|
||||||
@ -7,9 +7,7 @@ const wrapRootElement = ({
|
|||||||
}: {
|
}: {
|
||||||
element: ReactElement
|
element: ReactElement
|
||||||
}): ReactElement => (
|
}): ReactElement => (
|
||||||
<Web3Provider>
|
<OceanProvider config={oceanConfig}>{element}</OceanProvider>
|
||||||
<OceanProvider config={oceanConfig as Config}>{element}</OceanProvider>
|
|
||||||
</Web3Provider>
|
|
||||||
)
|
)
|
||||||
|
|
||||||
export default wrapRootElement
|
export default wrapRootElement
|
||||||
|
@ -2,15 +2,36 @@ import { useStaticQuery, graphql } from 'gatsby'
|
|||||||
|
|
||||||
const query = graphql`
|
const query = graphql`
|
||||||
query {
|
query {
|
||||||
siteMetadata: allFile(filter: { relativePath: { eq: "site.json" } }) {
|
site {
|
||||||
|
siteMetadata {
|
||||||
|
siteTitle
|
||||||
|
siteTagline
|
||||||
|
siteUrl
|
||||||
|
siteIcon
|
||||||
|
copyright
|
||||||
|
menu {
|
||||||
|
name
|
||||||
|
link
|
||||||
|
}
|
||||||
|
appConfig {
|
||||||
|
infuraProjectId
|
||||||
|
networks
|
||||||
|
oceanConfig {
|
||||||
|
factoryAddress
|
||||||
|
metadataStoreUri
|
||||||
|
nodeUri
|
||||||
|
providerUri
|
||||||
|
verbose
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
siteImage: allFile(filter: { relativePath: { eq: "site.json" } }) {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
childContentJson {
|
childContentJson {
|
||||||
site {
|
site {
|
||||||
siteTitle
|
|
||||||
siteTagline
|
|
||||||
siteUrl
|
|
||||||
siteIcon
|
|
||||||
siteImage {
|
siteImage {
|
||||||
childImageSharp {
|
childImageSharp {
|
||||||
original {
|
original {
|
||||||
@ -18,11 +39,6 @@ const query = graphql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
copyright
|
|
||||||
menu {
|
|
||||||
name
|
|
||||||
link
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -33,5 +49,11 @@ const query = graphql`
|
|||||||
|
|
||||||
export function useSiteMetadata() {
|
export function useSiteMetadata() {
|
||||||
const data = useStaticQuery(query)
|
const data = useStaticQuery(query)
|
||||||
return data.siteMetadata.edges[0].node.childContentJson.site
|
|
||||||
|
const siteMeta = {
|
||||||
|
...data.siteImage.edges[0].node.childContentJson.site,
|
||||||
|
...data.site.siteMetadata
|
||||||
|
}
|
||||||
|
|
||||||
|
return siteMeta
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,13 @@ import AssetContent from '../../components/organisms/AssetContent'
|
|||||||
import Layout from '../../components/Layout'
|
import Layout from '../../components/Layout'
|
||||||
import { PageProps } from 'gatsby'
|
import { PageProps } from 'gatsby'
|
||||||
import { MetaDataMarket, ServiceMetaDataMarket } from '../../@types/MetaData'
|
import { MetaDataMarket, ServiceMetaDataMarket } from '../../@types/MetaData'
|
||||||
import { Aquarius, Logger } from '@oceanprotocol/squid'
|
import { MetadataStore, Logger } from '@oceanprotocol/lib'
|
||||||
import { oceanConfig } from '../../../app.config'
|
|
||||||
import Alert from '../../components/atoms/Alert'
|
import Alert from '../../components/atoms/Alert'
|
||||||
|
import Loader from '../../components/atoms/Loader'
|
||||||
|
import { useSiteMetadata } from '../../hooks/useSiteMetadata'
|
||||||
|
|
||||||
export default function AssetRoute(props: PageProps): ReactElement {
|
export default function AssetRoute(props: PageProps): ReactElement {
|
||||||
|
const { appConfig } = useSiteMetadata()
|
||||||
const [metadata, setMetadata] = useState<MetaDataMarket>()
|
const [metadata, setMetadata] = useState<MetaDataMarket>()
|
||||||
const [title, setTitle] = useState<string>()
|
const [title, setTitle] = useState<string>()
|
||||||
const [error, setError] = useState<string>()
|
const [error, setError] = useState<string>()
|
||||||
@ -18,12 +20,15 @@ export default function AssetRoute(props: PageProps): ReactElement {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function init() {
|
async function init() {
|
||||||
try {
|
try {
|
||||||
const aquarius = new Aquarius(oceanConfig.aquariusUri, Logger)
|
const metadataStore = new MetadataStore(
|
||||||
const ddo = await aquarius.retrieveDDO(did)
|
appConfig.oceanConfig.metadataStoreUri,
|
||||||
|
Logger
|
||||||
|
)
|
||||||
|
const ddo = await metadataStore.retrieveDDO(did)
|
||||||
|
|
||||||
if (!ddo) {
|
if (!ddo) {
|
||||||
setTitle('Could not retrieve asset')
|
setTitle('Could not retrieve asset')
|
||||||
setError('The DDO was not found in Aquarius.')
|
setError('The DDO was not found in MetadataStore.')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,21 +44,25 @@ export default function AssetRoute(props: PageProps): ReactElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
init()
|
init()
|
||||||
}, [])
|
}, [did])
|
||||||
|
|
||||||
return error ? (
|
return did && metadata ? (
|
||||||
|
<Layout title={title} uri={props.location.pathname}>
|
||||||
|
<Router basepath="/asset">
|
||||||
|
<AssetContent
|
||||||
|
did={did}
|
||||||
|
metadata={metadata as MetaDataMarket}
|
||||||
|
path=":did"
|
||||||
|
/>
|
||||||
|
</Router>
|
||||||
|
</Layout>
|
||||||
|
) : error ? (
|
||||||
<Layout title={title} noPageHeader uri={props.location.pathname}>
|
<Layout title={title} noPageHeader uri={props.location.pathname}>
|
||||||
<Alert title={title} text={error} state="error" />
|
<Alert title={title} text={error} state="error" />
|
||||||
</Layout>
|
</Layout>
|
||||||
) : did && metadata ? (
|
|
||||||
<Layout title={title} uri={props.location.pathname}>
|
|
||||||
<Router basepath="/asset">
|
|
||||||
<AssetContent did={did} metadata={metadata} path="/asset/:did" />
|
|
||||||
</Router>
|
|
||||||
</Layout>
|
|
||||||
) : (
|
) : (
|
||||||
<Layout title="Loading..." uri={props.location.pathname}>
|
<Layout title="Loading..." uri={props.location.pathname}>
|
||||||
Loading...
|
<Loader />
|
||||||
</Layout>
|
</Layout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,40 +1,20 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import { PageProps, graphql } from 'gatsby'
|
import { PageProps } from 'gatsby'
|
||||||
import PageHome from '../components/pages/Home'
|
import PageHome from '../components/pages/Home'
|
||||||
import { useSiteMetadata } from '../hooks/useSiteMetadata'
|
import { useSiteMetadata } from '../hooks/useSiteMetadata'
|
||||||
import Layout from '../components/Layout'
|
import Layout from '../components/Layout'
|
||||||
|
|
||||||
export default function PageGatsbyHome(props: PageProps): ReactElement {
|
export default function PageGatsbyHome(props: PageProps): ReactElement {
|
||||||
const { siteTitle, siteTagline } = useSiteMetadata()
|
const { siteTitle, siteTagline } = useSiteMetadata()
|
||||||
const assets = (props.data as any).allOceanAsset.edges
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout title={siteTitle} description={siteTagline} uri={props.uri}>
|
<Layout
|
||||||
<PageHome assets={assets} />
|
title={siteTitle}
|
||||||
|
description={siteTagline}
|
||||||
|
uri={props.uri}
|
||||||
|
headerCenter
|
||||||
|
>
|
||||||
|
<PageHome />
|
||||||
</Layout>
|
</Layout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const pageQuery = graphql`
|
|
||||||
query PageHomeQuery {
|
|
||||||
allOceanAsset {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
did
|
|
||||||
main {
|
|
||||||
type
|
|
||||||
name
|
|
||||||
dateCreated
|
|
||||||
author
|
|
||||||
price
|
|
||||||
datePublished
|
|
||||||
}
|
|
||||||
additionalInformation {
|
|
||||||
description
|
|
||||||
access
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
import axios from 'axios'
|
|
||||||
import { DID } from '@oceanprotocol/squid'
|
|
||||||
import { oceanConfig } from '../../app.config'
|
|
||||||
|
|
||||||
export declare type GetRatingResponse = {
|
|
||||||
comment: string
|
|
||||||
datePublished: string
|
|
||||||
vote: number
|
|
||||||
}
|
|
||||||
|
|
||||||
const url = oceanConfig.ratingUri + '/api/v1/rating'
|
|
||||||
|
|
||||||
export default async function getAssetRating(
|
|
||||||
did: DID | string,
|
|
||||||
account: string
|
|
||||||
): Promise<GetRatingResponse | undefined> {
|
|
||||||
try {
|
|
||||||
if (!account) return
|
|
||||||
|
|
||||||
const response = await axios.get(url, {
|
|
||||||
params: {
|
|
||||||
did: did,
|
|
||||||
address: account
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const votesLength = response.data.length
|
|
||||||
|
|
||||||
if (votesLength > 0) {
|
|
||||||
return response.data[votesLength - 1]
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error.message)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
import axios, { AxiosResponse } from 'axios'
|
import axios, { AxiosResponse } from 'axios'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
import { File } from '@oceanprotocol/squid'
|
import { File } from '@oceanprotocol/lib'
|
||||||
import numeral from 'numeral'
|
import numeral from 'numeral'
|
||||||
import web3Utils from 'web3-utils'
|
import web3Utils from 'web3-utils'
|
||||||
|
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
import axios, { AxiosResponse } from 'axios'
|
|
||||||
import Web3 from 'web3'
|
|
||||||
import { DID } from '@oceanprotocol/squid'
|
|
||||||
import { oceanConfig } from '../../app.config'
|
|
||||||
|
|
||||||
export declare type RatingResponse = [string, number]
|
|
||||||
|
|
||||||
const url = oceanConfig.ratingUri + '/api/v1/rating'
|
|
||||||
|
|
||||||
export function gethash(message: string) {
|
|
||||||
let hex = ''
|
|
||||||
for (let i = 0; i < message.length; i++) {
|
|
||||||
hex += '' + message.charCodeAt(i).toString(16)
|
|
||||||
}
|
|
||||||
const hexMessage = '0x' + hex
|
|
||||||
return hexMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
export default async function rateAsset(
|
|
||||||
did: DID | string,
|
|
||||||
web3: Web3,
|
|
||||||
value: number
|
|
||||||
): Promise<RatingResponse | string> {
|
|
||||||
try {
|
|
||||||
const timestamp = Math.floor(+new Date() / 1000)
|
|
||||||
const accounts = await web3.eth.getAccounts()
|
|
||||||
const signature = await web3.eth.personal.sign(
|
|
||||||
gethash(`${timestamp}`),
|
|
||||||
accounts ? accounts[0] : '',
|
|
||||||
''
|
|
||||||
)
|
|
||||||
|
|
||||||
const ratingBody = {
|
|
||||||
did,
|
|
||||||
vote: value,
|
|
||||||
comment: '',
|
|
||||||
address: accounts[0],
|
|
||||||
timestamp: timestamp,
|
|
||||||
signature: signature
|
|
||||||
}
|
|
||||||
|
|
||||||
const response: AxiosResponse = await axios.post(url, ratingBody)
|
|
||||||
if (!response) return 'No Response'
|
|
||||||
return response.data
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error.message)
|
|
||||||
return `Error: ${error.message}`
|
|
||||||
}
|
|
||||||
}
|
|
55
src/utils/wallet.ts
Normal file
55
src/utils/wallet.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { OceanProviderValue } from '@oceanprotocol/react'
|
||||||
|
import atlas from '@ethereum-navigator/atlas'
|
||||||
|
import { networks, infuraProjectId } from '../../app.config'
|
||||||
|
|
||||||
|
const web3ModalTheme = {
|
||||||
|
background: 'var(--brand-white)',
|
||||||
|
main: 'var(--brand-black)',
|
||||||
|
secondary: 'var(--brand-grey-light)',
|
||||||
|
border: 'var(--brand-grey-lighter)',
|
||||||
|
hover: 'var(--brand-grey-dimmed)'
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function connectWallet(
|
||||||
|
connect: OceanProviderValue['connect']
|
||||||
|
): Promise<void> {
|
||||||
|
const { default: WalletConnectProvider } = await import(
|
||||||
|
'@walletconnect/web3-provider'
|
||||||
|
)
|
||||||
|
|
||||||
|
const providerOptions = {
|
||||||
|
/* See Provider Options Section */
|
||||||
|
walletconnect: {
|
||||||
|
package: WalletConnectProvider, // required
|
||||||
|
options: {
|
||||||
|
infuraId: infuraProjectId // required
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await connect({ cacheProvider: true, providerOptions, theme: web3ModalTheme })
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isCorrectNetwork(chainId: number): boolean {
|
||||||
|
const allowedIds = networks
|
||||||
|
return allowedIds.includes(chainId)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function accountTruncate(account: string): string {
|
||||||
|
const middle = account.substring(6, 38)
|
||||||
|
const truncated = account.replace(middle, '…')
|
||||||
|
return truncated
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getNetworkName(chainId: number): string {
|
||||||
|
switch (chainId) {
|
||||||
|
case 1:
|
||||||
|
return 'Main'
|
||||||
|
case 4:
|
||||||
|
return 'Rinkeby'
|
||||||
|
case 42:
|
||||||
|
return 'Kovan'
|
||||||
|
default:
|
||||||
|
return 'Unknown'
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { DDO } from '@oceanprotocol/squid'
|
import { DDO } from '@oceanprotocol/lib'
|
||||||
import { MetaDataMarket } from '../../../src/@types/MetaData'
|
import { MetaDataMarket } from '../../../src/@types/MetaData'
|
||||||
|
|
||||||
const ddo: Partial<DDO> = {
|
const ddo: Partial<DDO> = {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ComputeJob } from '@oceanprotocol/squid'
|
import { ComputeJob } from '@oceanprotocol/lib'
|
||||||
|
|
||||||
// ComputeJob need to be updated in squid
|
// ComputeJob need to be updated in squid
|
||||||
const job: Partial<ComputeJob> = {
|
const job: Partial<ComputeJob> = {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import ddo from '../../__fixtures__/ddo'
|
import ddo from '../../__fixtures__/ddo'
|
||||||
import job from '../../__fixtures__/job'
|
import job from '../../__fixtures__/job'
|
||||||
|
|
||||||
const aquarius = {
|
const metadataStore = {
|
||||||
queryMetadata: () => {
|
queryMetadata: () => {
|
||||||
return {
|
return {
|
||||||
results: [] as any[],
|
results: [] as any[],
|
||||||
@ -12,13 +12,13 @@ const aquarius = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const squidMock = {
|
const squidMock = {
|
||||||
Aquarius: () => aquarius,
|
MetadataStore: () => metadataStore,
|
||||||
DDO: () => ddo,
|
DDO: () => ddo,
|
||||||
ocean: {
|
ocean: {
|
||||||
accounts: {
|
accounts: {
|
||||||
list: () => ['xxx', 'xxx']
|
list: () => ['xxx', 'xxx']
|
||||||
},
|
},
|
||||||
aquarius,
|
metadataStore,
|
||||||
compute: {
|
compute: {
|
||||||
status: (account: string) => {
|
status: (account: string) => {
|
||||||
return [job]
|
return [job]
|
||||||
@ -69,13 +69,13 @@ const squidMock = {
|
|||||||
name: 'Squid-js',
|
name: 'Squid-js',
|
||||||
status: 'Working'
|
status: 'Working'
|
||||||
},
|
},
|
||||||
aquarius: {
|
metadataStore: {
|
||||||
name: 'Aquarius',
|
name: 'MetadataStore',
|
||||||
status: 'Working'
|
status: 'Working'
|
||||||
},
|
},
|
||||||
brizo: {
|
provider: {
|
||||||
name: 'Brizo',
|
name: 'Provider',
|
||||||
network: 'Nile',
|
network: 'Rinkeby',
|
||||||
status: 'Working',
|
status: 'Working',
|
||||||
contracts: {
|
contracts: {
|
||||||
hello: 'hello',
|
hello: 'hello',
|
@ -1,5 +1,5 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import squidMock from './squid'
|
import libMock from './lib'
|
||||||
import web3ProviderMock from '../web3provider'
|
import web3ProviderMock from '../web3provider'
|
||||||
|
|
||||||
const reactMock = {
|
const reactMock = {
|
||||||
@ -19,7 +19,7 @@ const reactMock = {
|
|||||||
},
|
},
|
||||||
useOcean: () => {
|
useOcean: () => {
|
||||||
return {
|
return {
|
||||||
ocean: squidMock.ocean
|
ocean: libMock.ocean
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
useWeb3: () => {
|
useWeb3: () => {
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import { render } from '@testing-library/react'
|
|
||||||
import { Web3Provider } from '@oceanprotocol/react'
|
|
||||||
|
|
||||||
describe('Web3Provider', () => {
|
|
||||||
it('renders without crashing', () => {
|
|
||||||
const { container } = render(<Web3Provider>Children</Web3Provider>)
|
|
||||||
expect(container).toHaveTextContent('Children')
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,23 +0,0 @@
|
|||||||
import axios, { AxiosResponse } from 'axios'
|
|
||||||
import getAssetRating, {
|
|
||||||
GetRatingResponse
|
|
||||||
} from '../../../src/utils/getAssetRating'
|
|
||||||
|
|
||||||
jest.mock('axios')
|
|
||||||
|
|
||||||
describe('getAssetRating()', () => {
|
|
||||||
it('success', async () => {
|
|
||||||
const ratingResponse: GetRatingResponse = {
|
|
||||||
comment: '',
|
|
||||||
datePublished: '',
|
|
||||||
vote: 5
|
|
||||||
}
|
|
||||||
|
|
||||||
;(axios.get as any).mockResolvedValueOnce({
|
|
||||||
data: [ratingResponse, ratingResponse]
|
|
||||||
} as AxiosResponse)
|
|
||||||
|
|
||||||
const response = await getAssetRating('0x00', '0x00')
|
|
||||||
expect(response && response.vote).toBe(5)
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,38 +0,0 @@
|
|||||||
import axios, { AxiosResponse } from 'axios'
|
|
||||||
import rateAsset, { RatingResponse } from '../../../src/utils/rateAsset'
|
|
||||||
import web3 from '../__mocks__/web3'
|
|
||||||
|
|
||||||
jest.mock('axios')
|
|
||||||
|
|
||||||
describe('rateAsset()', () => {
|
|
||||||
it('success', async () => {
|
|
||||||
;(axios.post as any).mockResolvedValueOnce({
|
|
||||||
data: ['4.0', 1]
|
|
||||||
} as AxiosResponse)
|
|
||||||
|
|
||||||
const response: RatingResponse | string = await rateAsset('0x00', web3, 5)
|
|
||||||
expect(response && response[0]).toBe('4.0')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('string return', async () => {
|
|
||||||
;(axios.post as any).mockResolvedValueOnce({
|
|
||||||
data: 'Missing signature'
|
|
||||||
} as AxiosResponse)
|
|
||||||
|
|
||||||
const response: RatingResponse | string = await rateAsset('0x00', web3, 5)
|
|
||||||
expect(response && response).toBe('Missing signature')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('error catch', async () => {
|
|
||||||
;(axios.post as any).mockResolvedValueOnce({
|
|
||||||
data: {}
|
|
||||||
} as AxiosResponse)
|
|
||||||
|
|
||||||
const response: RatingResponse | string = await rateAsset(
|
|
||||||
'0x00',
|
|
||||||
{} as any,
|
|
||||||
5
|
|
||||||
)
|
|
||||||
expect(response && response).toContain('Error: ')
|
|
||||||
})
|
|
||||||
})
|
|
Loading…
x
Reference in New Issue
Block a user