mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Release candidate 09-01-2023 (#1843)
* Avoiding getInitialPaymentCollector failure (#1816) * early return is no web3 or ddo * Creating test for MetaFull * adding test: src/components/Asset/AssetContent/MetaSecondary.test.tsx * Adding test for bookmarks * Adding test for displaying payment collector * Removing comments * Renaming assetAquarius * Renaming assetWithAccessDetails * Ensuring that the payment collector is shown even without a wallet connected * Removing broken test * Using getDummyWeb3 for fetching the payment collector address * google validation (#1835) * Updating validation to exclude any google link * Updating Yup validation * Checking if domain includes google.com * Updating isGoogleUrl function * Moving isGoogleUrl into @utils/url/index file * isGoogleUrl function * Updating tests * Adding additional tests for other google domains * Updating tests * Updating isGoogleUrl file path * Updating pricing message (#1842) * Bump @storybook/addon-essentials from 6.5.13 to 6.5.15 (#1841) Bumps [@storybook/addon-essentials](https://github.com/storybookjs/storybook/tree/HEAD/addons/essentials) from 6.5.13 to 6.5.15. - [Release notes](https://github.com/storybookjs/storybook/releases) - [Changelog](https://github.com/storybookjs/storybook/blob/v6.5.15/CHANGELOG.md) - [Commits](https://github.com/storybookjs/storybook/commits/v6.5.15/addons/essentials) --- updated-dependencies: - dependency-name: "@storybook/addon-essentials" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump @types/jest from 29.2.3 to 29.2.5 (#1840) Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 29.2.3 to 29.2.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) --- updated-dependencies: - dependency-name: "@types/jest" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump prettier from 2.8.0 to 2.8.1 (#1837) Bumps [prettier](https://github.com/prettier/prettier) from 2.8.0 to 2.8.1. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/2.8.0...2.8.1) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump react-select from 5.6.1 to 5.7.0 (#1839) Bumps [react-select](https://github.com/JedWatson/react-select) from 5.6.1 to 5.7.0. - [Release notes](https://github.com/JedWatson/react-select/releases) - [Changelog](https://github.com/JedWatson/react-select/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/JedWatson/react-select/compare/react-select@5.6.1...react-select@5.7.0) --- updated-dependencies: - dependency-name: react-select dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump react-tabs from 5.1.0 to 6.0.0 (#1838) Bumps [react-tabs](https://github.com/reactjs/react-tabs) from 5.1.0 to 6.0.0. - [Release notes](https://github.com/reactjs/react-tabs/releases) - [Commits](https://github.com/reactjs/react-tabs/compare/v5.1.0...v6.0.0) --- updated-dependencies: - dependency-name: react-tabs dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix asset route (#1836) * updating the buy button message for free assets * Updating pricing text for compute and algorithms * Updating tests * Adding a seperate sentence about paying gas fees for network charges with free assets * Fixing tests Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mihaisc <mihai.scarlat@smartcontrol.ro> * Showing hosting type in File Info (#1846) * Bump @storybook/addon-essentials from 6.5.13 to 6.5.15 (#1841) Bumps [@storybook/addon-essentials](https://github.com/storybookjs/storybook/tree/HEAD/addons/essentials) from 6.5.13 to 6.5.15. - [Release notes](https://github.com/storybookjs/storybook/releases) - [Changelog](https://github.com/storybookjs/storybook/blob/v6.5.15/CHANGELOG.md) - [Commits](https://github.com/storybookjs/storybook/commits/v6.5.15/addons/essentials) --- updated-dependencies: - dependency-name: "@storybook/addon-essentials" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump @types/jest from 29.2.3 to 29.2.5 (#1840) Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 29.2.3 to 29.2.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) --- updated-dependencies: - dependency-name: "@types/jest" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump prettier from 2.8.0 to 2.8.1 (#1837) Bumps [prettier](https://github.com/prettier/prettier) from 2.8.0 to 2.8.1. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/2.8.0...2.8.1) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump react-select from 5.6.1 to 5.7.0 (#1839) Bumps [react-select](https://github.com/JedWatson/react-select) from 5.6.1 to 5.7.0. - [Release notes](https://github.com/JedWatson/react-select/releases) - [Changelog](https://github.com/JedWatson/react-select/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/JedWatson/react-select/compare/react-select@5.6.1...react-select@5.7.0) --- updated-dependencies: - dependency-name: react-select dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump react-tabs from 5.1.0 to 6.0.0 (#1838) Bumps [react-tabs](https://github.com/reactjs/react-tabs) from 5.1.0 to 6.0.0. - [Release notes](https://github.com/reactjs/react-tabs/releases) - [Commits](https://github.com/reactjs/react-tabs/compare/v5.1.0...v6.0.0) --- updated-dependencies: - dependency-name: react-tabs dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix asset route (#1836) * Adding hosting type to the file info component * Writting smart contract hosting type across two lines Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mihaisc <mihai.scarlat@smartcontrol.ro> * add initial price value for not supported price assets (#1851) * Fix compute basetoken issue (#1829) * fix lint * add dynamic provider fees * fixes * cleanup and more fixes * bump oceanlib to 2.6.0 * fix 404 styling (#1850) * Fixing the z-index for the tippy component (#1858) * Removing infinite approval (#1857) * Removing infinite approvals * Removing infinite approval content message * Removing infinite approval from default user preferences Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mihaisc <mihai.scarlat@smartcontrol.ro> Co-authored-by: Bogdan Fazakas <bogdan.fazakas@gmail.com> Co-authored-by: EnzoVezzaro <enzo-vezzaro@live.it>
This commit is contained in:
parent
c62abb66bc
commit
d86c45f6bd
91
.jest/__fixtures__/algorithmAquarius.ts
Normal file
91
.jest/__fixtures__/algorithmAquarius.ts
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import { Asset } from '@oceanprotocol/lib'
|
||||||
|
|
||||||
|
export const algorithmAquarius: Asset = {
|
||||||
|
'@context': ['https://w3id.org/did/v1'],
|
||||||
|
id: 'did:op:6654b0793765b269696cec8d2f0d077d9bbcdd3c4f033d941ab9684e8ad06630',
|
||||||
|
nftAddress: '0xbA5BA7B09e2FA1eb0258f647503F81D2Af5cb07d',
|
||||||
|
version: '4.1.0',
|
||||||
|
chainId: 1,
|
||||||
|
metadata: {
|
||||||
|
created: '2022-09-29T11:30:26Z',
|
||||||
|
updated: '2022-09-29T11:30:26Z',
|
||||||
|
type: 'algorithm',
|
||||||
|
name: 'algorithmTestitest',
|
||||||
|
description: 'This is an algorithm test.',
|
||||||
|
links: ['https://www.oceanprotocol.com/sample'],
|
||||||
|
tags: [
|
||||||
|
'trading',
|
||||||
|
'defi',
|
||||||
|
'algorithm',
|
||||||
|
'algorithmic-crypto-trading',
|
||||||
|
'algo-trading',
|
||||||
|
'trading-strategy',
|
||||||
|
'cryptocurrency',
|
||||||
|
'crypto'
|
||||||
|
],
|
||||||
|
author: 'Test User',
|
||||||
|
license: 'https://market.oceanprotocol.com/terms',
|
||||||
|
additionalInformation: {
|
||||||
|
termsAndConditions: true
|
||||||
|
},
|
||||||
|
algorithm: {
|
||||||
|
language: 'json',
|
||||||
|
version: '0.1',
|
||||||
|
container: {
|
||||||
|
entrypoint: 'python $algo',
|
||||||
|
tag: 'latest',
|
||||||
|
image: 'https://docker.com/test.img',
|
||||||
|
checksum: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
services: [
|
||||||
|
{
|
||||||
|
id: 'dbc42f4c62d2452f8731fd023eacfae74e9c7a42fbd12ce84310f13342e4aab1',
|
||||||
|
type: 'access',
|
||||||
|
files:
|
||||||
|
'0x04022ef1afafe340f41b261ef721b8dd55dee094975cc70330803d760beef38871948ce572ff1c533d56cda2665749ed2eb8283e243ec5ee19011f510b6b263b2da0af537e3f1fdff7ddd90fa26c7a4761a6d26928bc1348a302634012aac7998e92c84456ab73e9a847120c44ebda15781787e8c382391b2eaefc8b8d36998f3998d1c4647f4f7bb28f4278093c1d231f66e78f81452049443b9e540aeb42ebbdc1b748c024eb10218532814736e241efa1c2a687685b4e2ea7a877685aa0ea325d1a8cf765d1b423b32d81ec3c3e22fc9c15c6b9b71f2862edaec4e4cf7c3a638ffc0ecb88ede3cabb511d4780543a53c001a95f42de1877796e13c997b57bc671507e92198934b4ea7c2e6554993388421253e8c2f10458dec872a7ebfa71b6e77ed359222c93261ba252028c5da06ccf8defcd529885b2125816325a47e23728b513',
|
||||||
|
datatokenAddress: '0x067e1E6ec580F3F0f6781679A4A5AB07A6464b08',
|
||||||
|
serviceEndpoint: 'https://v4.provider.goerli.oceanprotocol.com',
|
||||||
|
timeout: 604800
|
||||||
|
}
|
||||||
|
],
|
||||||
|
event: {
|
||||||
|
tx: '0x3e07a75c1cc5d4146222a93ab4319144e60ecca3ebfb8b15f1ff339d6f479dc9',
|
||||||
|
block: 7680195,
|
||||||
|
from: '0x903322C7E45A60d7c8C3EA236c5beA9Af86310c7',
|
||||||
|
contract: '0xbA5BA7B09e2FA1eb0258f647503F81D2Af5cb07d',
|
||||||
|
datetime: '2022-09-29T11:31:12'
|
||||||
|
},
|
||||||
|
nft: {
|
||||||
|
address: '0xbA5BA7B09e2FA1eb0258f647503F81D2Af5cb07d',
|
||||||
|
name: 'Ocean Data NFT',
|
||||||
|
symbol: 'OCEAN-NFT',
|
||||||
|
state: 0,
|
||||||
|
tokenURI:
|
||||||
|
'data:application/json;base64,eyJuYW1lIjoiT2NlYW4gRGF0YSBORlQiLCJzeW1ib2wiOiJPQ0VBTi1ORlQiLCJkZXNjcmlwdGlvbiI6IlRoaXMgTkZUIHJlcHJlc2VudHMgYW4gYXNzZXQgaW4gdGhlIE9jZWFuIFByb3RvY29sIHY0IGVjb3N5c3RlbS5cblxuVmlldyBvbiBPY2VhbiBNYXJrZXQ6IGh0dHBzOi8vbWFya2V0Lm9jZWFucHJvdG9jb2wuY29tL2Fzc2V0L2RpZDpvcDo2NjU0YjA3OTM3NjViMjY5Njk2Y2VjOGQyZjBkMDc3ZDliYmNkZDNjNGYwMzNkOTQxYWI5Njg0ZThhZDA2NjMwIiwiZXh0ZXJuYWxfdXJsIjoiaHR0cHM6Ly9tYXJrZXQub2NlYW5wcm90b2NvbC5jb20vYXNzZXQvZGlkOm9wOjY2NTRiMDc5Mzc2NWIyNjk2OTZjZWM4ZDJmMGQwNzdkOWJiY2RkM2M0ZjAzM2Q5NDFhYjk2ODRlOGFkMDY2MzAiLCJiYWNrZ3JvdW5kX2NvbG9yIjoiMTQxNDE0IiwiaW1hZ2VfZGF0YSI6ImRhdGE6aW1hZ2Uvc3ZnK3htbCwlM0Nzdmcgdmlld0JveD0nMCAwIDk5IDk5JyBmaWxsPSd1bmRlZmluZWQnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyclM0UlM0NwYXRoIGZpbGw9JyUyM2ZmNDA5Mjc3JyBkPSdNMCw5OUwwLDI5QzksMjUgMTksMjIgMjksMjFDMzgsMTkgNDksMTkgNjEsMjFDNzIsMjIgODUsMjUgOTksMjlMOTksOTlaJy8lM0UlM0NwYXRoIGZpbGw9JyUyM2ZmNDA5MmJiJyBkPSdNMCw5OUwwLDU1QzgsNDkgMTcsNDQgMjgsNDNDMzgsNDEgNTAsNDIgNjMsNDNDNzUsNDMgODcsNDIgOTksNDJMOTksOTlaJyUzRSUzQy9wYXRoJTNFJTNDcGF0aCBmaWxsPSclMjNmZjQwOTJmZicgZD0nTTAsOTlMMCw2OEMxMSw2NiAyMiw2NSAzMiw2N0M0MSw2OCA1MCw3MyA2MSw3NkM3MSw3OCA4NSw3OCA5OSw3OUw5OSw5OVonJTNFJTNDL3BhdGglM0UlM0Mvc3ZnJTNFIn0=',
|
||||||
|
owner: '0x99840Df5Cb42faBE0Feb8811Aaa4BC99cA6C84e0',
|
||||||
|
created: '2022-09-29T11:31:12'
|
||||||
|
},
|
||||||
|
datatokens: [
|
||||||
|
{
|
||||||
|
address: '0x067e1E6ec580F3F0f6781679A4A5AB07A6464b08',
|
||||||
|
name: 'Stupendous Orca Token',
|
||||||
|
symbol: 'STUORC-59',
|
||||||
|
serviceId:
|
||||||
|
'dbc42f4c62d2452f8731fd023eacfae74e9c7a42fbd12ce84310f13342e4aab1'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
stats: {
|
||||||
|
orders: 22,
|
||||||
|
price: {
|
||||||
|
value: 3231343254,
|
||||||
|
tokenAddress: '0xCfDdA22C9837aE76E0faA845354f33C62E03653a',
|
||||||
|
tokenSymbol: 'OCEAN'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
purgatory: {
|
||||||
|
state: false,
|
||||||
|
reason: ''
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import { Asset } from '@oceanprotocol/lib'
|
import { Asset } from '@oceanprotocol/lib'
|
||||||
|
|
||||||
export const assetAquarius: Asset = {
|
export const datasetAquarius: Asset = {
|
||||||
'@context': ['https://w3id.org/did/v1'],
|
'@context': ['https://w3id.org/did/v1'],
|
||||||
id: 'did:op:6654b0793765b269696cec8d2f0d077d9bbcdd3c4f033d941ab9684e8ad06630',
|
id: 'did:op:6654b0793765b269696cec8d2f0d077d9bbcdd3c4f033d941ab9684e8ad06630',
|
||||||
nftAddress: '0xbA5BA7B09e2FA1eb0258f647503F81D2Af5cb07d',
|
nftAddress: '0xbA5BA7B09e2FA1eb0258f647503F81D2Af5cb07d',
|
||||||
@ -12,7 +12,16 @@ export const assetAquarius: Asset = {
|
|||||||
type: 'dataset',
|
type: 'dataset',
|
||||||
name: 'Testitest',
|
name: 'Testitest',
|
||||||
description: 'This is a test.',
|
description: 'This is a test.',
|
||||||
tags: [],
|
tags: [
|
||||||
|
'trading',
|
||||||
|
'defi',
|
||||||
|
'algorithm',
|
||||||
|
'algorithmic-crypto-trading',
|
||||||
|
'algo-trading',
|
||||||
|
'trading-strategy',
|
||||||
|
'cryptocurrency',
|
||||||
|
'crypto'
|
||||||
|
],
|
||||||
author: 'Test User',
|
author: 'Test User',
|
||||||
license: 'https://market.oceanprotocol.com/terms',
|
license: 'https://market.oceanprotocol.com/terms',
|
||||||
additionalInformation: {
|
additionalInformation: {
|
@ -1,7 +1,7 @@
|
|||||||
import { assetAquarius } from './assetAquarius'
|
import { datasetAquarius } from './datasetAquarius'
|
||||||
|
|
||||||
export const asset: AssetExtended = {
|
export const asset: AssetExtended = {
|
||||||
...assetAquarius,
|
...datasetAquarius,
|
||||||
accessDetails: {
|
accessDetails: {
|
||||||
templateId: 1,
|
templateId: 1,
|
||||||
publisherMarketOrderFee: '0',
|
publisherMarketOrderFee: '0',
|
@ -5,6 +5,5 @@ export default {
|
|||||||
chainIds: [5, 1, 137, 56, 1285, 246],
|
chainIds: [5, 1, 137, 56, 1285, 246],
|
||||||
bookmarks: [],
|
bookmarks: [],
|
||||||
privacyPolicySlug: '/privacy/en',
|
privacyPolicySlug: '/privacy/en',
|
||||||
showPPC: true,
|
showPPC: true
|
||||||
infiniteApproval: false
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
import { assets } from '../../__fixtures__/assetsWithAccessDetails'
|
import { assets } from '../../__fixtures__/datasetsWithAccessDetails'
|
||||||
|
|
||||||
export const getAccessDetailsForAssets = jest.fn().mockResolvedValue(assets)
|
export const getAccessDetailsForAssets = jest.fn().mockResolvedValue(assets)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import marketMetadata from '../__fixtures__/marketMetadata'
|
import marketMetadata from '../__fixtures__/marketMetadata'
|
||||||
import userPreferences from '../__fixtures__/userPreferences'
|
import userPreferences from '../__fixtures__/userPreferences'
|
||||||
import web3 from '../__fixtures__/web3'
|
import web3 from '../__fixtures__/web3'
|
||||||
import { asset } from '../__fixtures__/assetWithAccessDetails'
|
import { asset } from '../__fixtures__/datasetWithAccessDetails'
|
||||||
|
|
||||||
jest.mock('../../src/@context/MarketMetadata', () => ({
|
jest.mock('../../src/@context/MarketMetadata', () => ({
|
||||||
useMarketMetadata: () => marketMetadata
|
useMarketMetadata: () => marketMetadata
|
||||||
|
@ -32,42 +32,45 @@
|
|||||||
"label": "File",
|
"label": "File",
|
||||||
"prominentHelp": false,
|
"prominentHelp": false,
|
||||||
"type": "tabs",
|
"type": "tabs",
|
||||||
"fields": [{
|
"fields": [
|
||||||
"value": "ipfs",
|
{
|
||||||
"title": "IPFS",
|
"value": "ipfs",
|
||||||
"label": "CID",
|
"title": "IPFS",
|
||||||
"placeholder": "e.g. bafkreidgvpkjawlxz6sffxzwgooowe5yt7i6wsyg236mfoks77nywkptdq",
|
"label": "CID",
|
||||||
"help": "This CID will be stored encrypted after publishing.",
|
"placeholder": "e.g. bafkreidgvpkjawlxz6sffxzwgooowe5yt7i6wsyg236mfoks77nywkptdq",
|
||||||
"computeHelp": "For a compute dataset, your file should match the file type required by the algorithm, and should not exceed 1 GB in file size. ",
|
"help": "This CID will be stored encrypted after publishing.",
|
||||||
"prominentHelp": true,
|
"computeHelp": "For a compute dataset, your file should match the file type required by the algorithm, and should not exceed 1 GB in file size. ",
|
||||||
"type": "files",
|
"prominentHelp": true,
|
||||||
"required": true
|
"type": "files",
|
||||||
},
|
"required": true
|
||||||
{
|
},
|
||||||
"value": "arweave",
|
{
|
||||||
"title": "Arweave",
|
"value": "arweave",
|
||||||
"label": "Transaction ID",
|
"title": "Arweave",
|
||||||
"placeholder": "e.g. DBRCL94j3QqdPaUtt4VWRen8rZfJZBb7Ey40iMpXfhtd",
|
"label": "Transaction ID",
|
||||||
"help": "This Transaction ID will be stored encrypted after publishing.",
|
"placeholder": "e.g. DBRCL94j3QqdPaUtt4VWRen8rZfJZBb7Ey40iMpXfhtd",
|
||||||
"computeHelp": "For a compute dataset, your file should match the file type required by the algorithm, and should not exceed 1 GB in file size. ",
|
"help": "This Transaction ID will be stored encrypted after publishing.",
|
||||||
"prominentHelp": true,
|
"computeHelp": "For a compute dataset, your file should match the file type required by the algorithm, and should not exceed 1 GB in file size. ",
|
||||||
"type": "files",
|
"prominentHelp": true,
|
||||||
"required": true
|
"type": "files",
|
||||||
},
|
"required": true
|
||||||
{
|
},
|
||||||
"value": "url",
|
{
|
||||||
"title": "URL",
|
"value": "url",
|
||||||
"label": "File",
|
"title": "URL",
|
||||||
"placeholder": "e.g. https://file.com/file.json",
|
"label": "File",
|
||||||
"help": "This URL will be stored encrypted after publishing. **Please make sure that the endpoint is accessible over the internet and is not protected by a firewall or by credentials.**",
|
"placeholder": "e.g. https://file.com/file.json",
|
||||||
"computeHelp": "For a compute dataset, your file should match the file type required by the algorithm, and should not exceed 1 GB in file size. ",
|
"help": "This URL will be stored encrypted after publishing. **Please make sure that the endpoint is accessible over the internet and is not protected by a firewall or by credentials.**",
|
||||||
"prominentHelp": true,
|
"computeHelp": "For a compute dataset, your file should match the file type required by the algorithm, and should not exceed 1 GB in file size. ",
|
||||||
"type": "files",
|
"prominentHelp": true,
|
||||||
"required": true
|
"type": "files",
|
||||||
}],
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"sortOptions": false,
|
"sortOptions": false,
|
||||||
"required": true
|
"required": true
|
||||||
},{
|
},
|
||||||
|
{
|
||||||
"name": "links",
|
"name": "links",
|
||||||
"label": "Sample file",
|
"label": "Sample file",
|
||||||
"prominentHelp": false,
|
"prominentHelp": false,
|
||||||
@ -83,7 +86,8 @@
|
|||||||
"prominentHelp": true,
|
"prominentHelp": true,
|
||||||
"type": "files",
|
"type": "files",
|
||||||
"required": false
|
"required": false
|
||||||
}],
|
}
|
||||||
|
],
|
||||||
"required": false
|
"required": false
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -24,8 +24,7 @@
|
|||||||
},
|
},
|
||||||
"approval": {
|
"approval": {
|
||||||
"tooltips": {
|
"tooltips": {
|
||||||
"approveSpecific": "Give the smart contract permission to spend your COIN which has to be done for each transaction. You can optionally set this to infinite in your user preferences.",
|
"approveSpecific": "Give the smart contract permission to spend your COIN which has to be done for each transaction. You can optionally set this to infinite in your user preferences."
|
||||||
"approveInfinite": "Give the smart contract permission to spend infinte amounts of your COIN so you have to do this only once. You can disable allowing infinite amounts in your user preferences."
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,58 +106,62 @@
|
|||||||
"label": "File",
|
"label": "File",
|
||||||
"prominentHelp": false,
|
"prominentHelp": false,
|
||||||
"type": "tabs",
|
"type": "tabs",
|
||||||
"fields": [{
|
"fields": [
|
||||||
"value": "ipfs",
|
{
|
||||||
"title": "IPFS",
|
"value": "ipfs",
|
||||||
"label": "CID",
|
"title": "IPFS",
|
||||||
"placeholder": "e.g. bafkreidgvpkjawlxz6sffxzwgooowe5yt7i6wsyg236mfoks77nywkptdq",
|
"label": "CID",
|
||||||
"help": "This CID will be stored encrypted after publishing.",
|
"placeholder": "e.g. bafkreidgvpkjawlxz6sffxzwgooowe5yt7i6wsyg236mfoks77nywkptdq",
|
||||||
"computeHelp": "For a compute dataset, your file should match the file type required by the algorithm, and should not exceed 1 GB in file size. ",
|
"help": "This CID will be stored encrypted after publishing.",
|
||||||
"prominentHelp": true,
|
"computeHelp": "For a compute dataset, your file should match the file type required by the algorithm, and should not exceed 1 GB in file size. ",
|
||||||
"type": "files",
|
"prominentHelp": true,
|
||||||
"required": true
|
"type": "files",
|
||||||
},
|
"required": true
|
||||||
{
|
},
|
||||||
"value": "arweave",
|
{
|
||||||
"title": "Arweave",
|
"value": "arweave",
|
||||||
"label": "Transaction ID",
|
"title": "Arweave",
|
||||||
"placeholder": "e.g. DBRCL94j3QqdPaUtt4VWRen8rZfJZBb7Ey40iMpXfhtd",
|
"label": "Transaction ID",
|
||||||
"help": "This Transaction ID will be stored encrypted after publishing.",
|
"placeholder": "e.g. DBRCL94j3QqdPaUtt4VWRen8rZfJZBb7Ey40iMpXfhtd",
|
||||||
"computeHelp": "For a compute dataset, your file should match the file type required by the algorithm, and should not exceed 1 GB in file size. ",
|
"help": "This Transaction ID will be stored encrypted after publishing.",
|
||||||
"prominentHelp": true,
|
"computeHelp": "For a compute dataset, your file should match the file type required by the algorithm, and should not exceed 1 GB in file size. ",
|
||||||
"type": "files",
|
"prominentHelp": true,
|
||||||
"required": true
|
"type": "files",
|
||||||
},
|
"required": true
|
||||||
{
|
},
|
||||||
"value": "url",
|
{
|
||||||
"title": "URL",
|
"value": "url",
|
||||||
"label": "File",
|
"title": "URL",
|
||||||
"placeholder": "e.g. https://file.com/file.json",
|
"label": "File",
|
||||||
"help": "This URL will be stored encrypted after publishing. **Please make sure that the endpoint is accessible over the internet and is not protected by a firewall or by credentials.**",
|
"placeholder": "e.g. https://file.com/file.json",
|
||||||
"computeHelp": "For a compute dataset, your file should match the file type required by the algorithm, and should not exceed 1 GB in file size. ",
|
"help": "This URL will be stored encrypted after publishing. **Please make sure that the endpoint is accessible over the internet and is not protected by a firewall or by credentials.**",
|
||||||
"prominentHelp": true,
|
"computeHelp": "For a compute dataset, your file should match the file type required by the algorithm, and should not exceed 1 GB in file size. ",
|
||||||
"type": "files",
|
"prominentHelp": true,
|
||||||
"required": true
|
"type": "files",
|
||||||
}],
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"sortOptions": false,
|
"sortOptions": false,
|
||||||
"required": true
|
"required": true
|
||||||
},{
|
},
|
||||||
|
{
|
||||||
"name": "links",
|
"name": "links",
|
||||||
"label": "Sample file",
|
"label": "Sample file",
|
||||||
"prominentHelp": false,
|
"prominentHelp": false,
|
||||||
"type": "tabs",
|
"type": "tabs",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"value": "url",
|
"value": "url",
|
||||||
"title": "URL",
|
"title": "URL",
|
||||||
"label": "File",
|
"label": "File",
|
||||||
"placeholder": "e.g. https://file.com/file.json",
|
"placeholder": "e.g. https://file.com/file.json",
|
||||||
"help": "This URL will be stored encrypted after publishing. **Please make sure that the endpoint is accessible over the internet and is not protected by a firewall or by credentials.**",
|
"help": "This URL will be stored encrypted after publishing. **Please make sure that the endpoint is accessible over the internet and is not protected by a firewall or by credentials.**",
|
||||||
"computeHelp": "For a compute dataset, your file should match the file type required by the algorithm, and should not exceed 1 GB in file size. ",
|
"computeHelp": "For a compute dataset, your file should match the file type required by the algorithm, and should not exceed 1 GB in file size. ",
|
||||||
"prominentHelp": true,
|
"prominentHelp": true,
|
||||||
"type": "files",
|
"type": "files",
|
||||||
"required": false
|
"required": false
|
||||||
}],
|
}
|
||||||
|
],
|
||||||
"required": false
|
"required": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
32
package-lock.json
generated
32
package-lock.json
generated
@ -13,7 +13,7 @@
|
|||||||
"@coingecko/cryptoformat": "^0.5.4",
|
"@coingecko/cryptoformat": "^0.5.4",
|
||||||
"@loadable/component": "^5.15.2",
|
"@loadable/component": "^5.15.2",
|
||||||
"@oceanprotocol/art": "^3.2.0",
|
"@oceanprotocol/art": "^3.2.0",
|
||||||
"@oceanprotocol/lib": "^2.5.2",
|
"@oceanprotocol/lib": "^2.6.0",
|
||||||
"@oceanprotocol/typographies": "^0.1.0",
|
"@oceanprotocol/typographies": "^0.1.0",
|
||||||
"@oceanprotocol/use-dark-mode": "^2.4.3",
|
"@oceanprotocol/use-dark-mode": "^2.4.3",
|
||||||
"@tippyjs/react": "^4.2.6",
|
"@tippyjs/react": "^4.2.6",
|
||||||
@ -4591,18 +4591,18 @@
|
|||||||
"integrity": "sha512-I6xoADZpP/8EyN3VWZ+dLYv24DbJj3xzmSDcYv0FolXeAUF3FluzminL5AgQtAaoyUtlHl1D3ij1B++KupWcQQ=="
|
"integrity": "sha512-I6xoADZpP/8EyN3VWZ+dLYv24DbJj3xzmSDcYv0FolXeAUF3FluzminL5AgQtAaoyUtlHl1D3ij1B++KupWcQQ=="
|
||||||
},
|
},
|
||||||
"node_modules/@oceanprotocol/lib": {
|
"node_modules/@oceanprotocol/lib": {
|
||||||
"version": "2.5.2",
|
"version": "2.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-2.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-2.6.0.tgz",
|
||||||
"integrity": "sha512-hLNTS6go1GhpSJt7un1VPb/6XNNYSwGpYPX/O1E5q2XCRWjaWYodzqwxBcgQKw2ihSQmaH9JsDsFLZiIKqKRLA==",
|
"integrity": "sha512-UMWOdJksJO43wzsmyidOjTyGtARw9OKGde6xbunNuRJDLmeYui4OZ0KTwA5yWBSibsqWk4TVAJgXrxW096NJ5g==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@oceanprotocol/contracts": "^1.1.8",
|
"@oceanprotocol/contracts": "^1.1.8",
|
||||||
"bignumber.js": "^9.1.0",
|
"bignumber.js": "^9.1.0",
|
||||||
"cross-fetch": "^3.1.5",
|
"cross-fetch": "^3.1.5",
|
||||||
"crypto-js": "^4.1.1",
|
"crypto-js": "^4.1.1",
|
||||||
"decimal.js": "^10.4.1",
|
"decimal.js": "^10.4.1",
|
||||||
"web3": "^1.8.0",
|
"web3": "^1.8.1",
|
||||||
"web3-core": "^1.8.0",
|
"web3-core": "^1.8.1",
|
||||||
"web3-eth-contract": "^1.8.0"
|
"web3-eth-contract": "^1.8.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"web3": "^1.8.0"
|
"web3": "^1.8.0"
|
||||||
@ -50186,18 +50186,17 @@
|
|||||||
"integrity": "sha512-I6xoADZpP/8EyN3VWZ+dLYv24DbJj3xzmSDcYv0FolXeAUF3FluzminL5AgQtAaoyUtlHl1D3ij1B++KupWcQQ=="
|
"integrity": "sha512-I6xoADZpP/8EyN3VWZ+dLYv24DbJj3xzmSDcYv0FolXeAUF3FluzminL5AgQtAaoyUtlHl1D3ij1B++KupWcQQ=="
|
||||||
},
|
},
|
||||||
"@oceanprotocol/lib": {
|
"@oceanprotocol/lib": {
|
||||||
"version": "2.5.2",
|
"version": "2.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-2.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-2.6.0.tgz",
|
||||||
"integrity": "sha512-hLNTS6go1GhpSJt7un1VPb/6XNNYSwGpYPX/O1E5q2XCRWjaWYodzqwxBcgQKw2ihSQmaH9JsDsFLZiIKqKRLA==",
|
"integrity": "sha512-UMWOdJksJO43wzsmyidOjTyGtARw9OKGde6xbunNuRJDLmeYui4OZ0KTwA5yWBSibsqWk4TVAJgXrxW096NJ5g==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@oceanprotocol/contracts": "^1.1.8",
|
"@oceanprotocol/contracts": "^1.1.8",
|
||||||
"bignumber.js": "^9.1.0",
|
"bignumber.js": "^9.1.0",
|
||||||
"cross-fetch": "^3.1.5",
|
"cross-fetch": "^3.1.5",
|
||||||
"crypto-js": "^4.1.1",
|
"crypto-js": "^4.1.1",
|
||||||
"decimal.js": "^10.4.1",
|
"decimal.js": "^10.4.1",
|
||||||
"web3": "^1.8.0",
|
"web3-core": "^1.8.1",
|
||||||
"web3-core": "^1.8.0",
|
"web3-eth-contract": "^1.8.1"
|
||||||
"web3-eth-contract": "^1.8.0"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@oceanprotocol/typographies": {
|
"@oceanprotocol/typographies": {
|
||||||
@ -50256,7 +50255,6 @@
|
|||||||
"integrity": "sha512-rmVKYEsKzurfRU0xJz+iHelbi1LGlihIWZ7Qvmb/CBz1EkhL7nOkW4SVXmG2dA5Ce0si2gr88i6q4eBOMRNJ1w==",
|
"integrity": "sha512-rmVKYEsKzurfRU0xJz+iHelbi1LGlihIWZ7Qvmb/CBz1EkhL7nOkW4SVXmG2dA5Ce0si2gr88i6q4eBOMRNJ1w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@oclif/config": "^1.18.2",
|
|
||||||
"@oclif/errors": "^1.3.5",
|
"@oclif/errors": "^1.3.5",
|
||||||
"@oclif/help": "^1.0.1",
|
"@oclif/help": "^1.0.1",
|
||||||
"@oclif/parser": "^3.8.6",
|
"@oclif/parser": "^3.8.6",
|
||||||
@ -61274,7 +61272,7 @@
|
|||||||
"git-url-parse": "11.6.0",
|
"git-url-parse": "11.6.0",
|
||||||
"glob": "8.0.1",
|
"glob": "8.0.1",
|
||||||
"global-agent": "3.0.0",
|
"global-agent": "3.0.0",
|
||||||
"graphql": "15.8.0",
|
"graphql": "14.0.2 - 14.2.0 || ^14.3.1 || ^15.0.0",
|
||||||
"graphql-tag": "2.12.6",
|
"graphql-tag": "2.12.6",
|
||||||
"listr": "0.14.3",
|
"listr": "0.14.3",
|
||||||
"lodash.identity": "3.0.0",
|
"lodash.identity": "3.0.0",
|
||||||
@ -61515,7 +61513,7 @@
|
|||||||
"cosmiconfig": "^7.0.1",
|
"cosmiconfig": "^7.0.1",
|
||||||
"dotenv": "^16.0.0",
|
"dotenv": "^16.0.0",
|
||||||
"glob": "^8.0.0",
|
"glob": "^8.0.0",
|
||||||
"graphql": "15.8.0",
|
"graphql": "14.0.2 - 14.2.0 || ^14.3.1 || ^15.0.0",
|
||||||
"graphql-tag": "^2.10.1",
|
"graphql-tag": "^2.10.1",
|
||||||
"lodash.debounce": "^4.0.8",
|
"lodash.debounce": "^4.0.8",
|
||||||
"lodash.merge": "^4.6.1",
|
"lodash.merge": "^4.6.1",
|
||||||
@ -74394,7 +74392,6 @@
|
|||||||
"integrity": "sha512-uJx9y/1NIqoYTp6ZW1osJ7U5ZrXGAJbOQ/Qzl05BdGYvN1S7Qmbzid6xOirgK0EIT0pJKEEh1s8qbassYZe4cw==",
|
"integrity": "sha512-uJx9y/1NIqoYTp6ZW1osJ7U5ZrXGAJbOQ/Qzl05BdGYvN1S7Qmbzid6xOirgK0EIT0pJKEEh1s8qbassYZe4cw==",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/core": "^7.14.0",
|
|
||||||
"@babel/plugin-proposal-async-generator-functions": "^7.0.0",
|
"@babel/plugin-proposal-async-generator-functions": "^7.0.0",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.0.0",
|
"@babel/plugin-proposal-class-properties": "^7.0.0",
|
||||||
"@babel/plugin-proposal-export-default-from": "^7.0.0",
|
"@babel/plugin-proposal-export-default-from": "^7.0.0",
|
||||||
@ -74449,7 +74446,6 @@
|
|||||||
"integrity": "sha512-Ogst/M6ujYrl/+9mpEWqE3zF7l2mTuftDTy3L8wZYwX1pWUQWQpfU1aJBeWiLxt1XlIq+uriRjKzKoRoIK57EA==",
|
"integrity": "sha512-Ogst/M6ujYrl/+9mpEWqE3zF7l2mTuftDTy3L8wZYwX1pWUQWQpfU1aJBeWiLxt1XlIq+uriRjKzKoRoIK57EA==",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/core": "^7.14.0",
|
|
||||||
"babel-preset-fbjs": "^3.4.0",
|
"babel-preset-fbjs": "^3.4.0",
|
||||||
"hermes-parser": "0.8.0",
|
"hermes-parser": "0.8.0",
|
||||||
"metro-babel-transformer": "0.72.3",
|
"metro-babel-transformer": "0.72.3",
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
"@coingecko/cryptoformat": "^0.5.4",
|
"@coingecko/cryptoformat": "^0.5.4",
|
||||||
"@loadable/component": "^5.15.2",
|
"@loadable/component": "^5.15.2",
|
||||||
"@oceanprotocol/art": "^3.2.0",
|
"@oceanprotocol/art": "^3.2.0",
|
||||||
"@oceanprotocol/lib": "^2.5.2",
|
"@oceanprotocol/lib": "^2.6.0",
|
||||||
"@oceanprotocol/typographies": "^0.1.0",
|
"@oceanprotocol/typographies": "^0.1.0",
|
||||||
"@oceanprotocol/use-dark-mode": "^2.4.3",
|
"@oceanprotocol/use-dark-mode": "^2.4.3",
|
||||||
"@tippyjs/react": "^4.2.6",
|
"@tippyjs/react": "^4.2.6",
|
||||||
|
@ -24,8 +24,6 @@ interface UserPreferencesValue {
|
|||||||
removeBookmark: (did: string) => void
|
removeBookmark: (did: string) => void
|
||||||
setPrivacyPolicySlug: (slug: string) => void
|
setPrivacyPolicySlug: (slug: string) => void
|
||||||
setShowPPC: (value: boolean) => void
|
setShowPPC: (value: boolean) => void
|
||||||
infiniteApproval: boolean
|
|
||||||
setInfiniteApproval: (value: boolean) => void
|
|
||||||
locale: string
|
locale: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,10 +71,6 @@ function UserPreferencesProvider({
|
|||||||
localStorage?.showPPC !== false
|
localStorage?.showPPC !== false
|
||||||
)
|
)
|
||||||
|
|
||||||
const [infiniteApproval, setInfiniteApproval] = useState(
|
|
||||||
localStorage?.infiniteApproval || false
|
|
||||||
)
|
|
||||||
|
|
||||||
// Write values to localStorage on change
|
// Write values to localStorage on change
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLocalStorage({
|
setLocalStorage({
|
||||||
@ -85,18 +79,9 @@ function UserPreferencesProvider({
|
|||||||
currency,
|
currency,
|
||||||
bookmarks,
|
bookmarks,
|
||||||
privacyPolicySlug,
|
privacyPolicySlug,
|
||||||
showPPC,
|
showPPC
|
||||||
infiniteApproval
|
|
||||||
})
|
})
|
||||||
}, [
|
}, [chainIds, debug, currency, bookmarks, privacyPolicySlug, showPPC])
|
||||||
chainIds,
|
|
||||||
debug,
|
|
||||||
currency,
|
|
||||||
bookmarks,
|
|
||||||
privacyPolicySlug,
|
|
||||||
showPPC,
|
|
||||||
infiniteApproval
|
|
||||||
])
|
|
||||||
|
|
||||||
// Set ocean.js log levels, default: Error
|
// Set ocean.js log levels, default: Error
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -152,8 +137,6 @@ function UserPreferencesProvider({
|
|||||||
bookmarks,
|
bookmarks,
|
||||||
privacyPolicySlug,
|
privacyPolicySlug,
|
||||||
showPPC,
|
showPPC,
|
||||||
infiniteApproval,
|
|
||||||
setInfiniteApproval,
|
|
||||||
setChainIds,
|
setChainIds,
|
||||||
setDebug,
|
setDebug,
|
||||||
setCurrency,
|
setCurrency,
|
||||||
|
@ -22,6 +22,7 @@ export function getNetworkType(network: EthereumListsChain): string {
|
|||||||
|
|
||||||
export function getNetworkDisplayName(data: EthereumListsChain): string {
|
export function getNetworkDisplayName(data: EthereumListsChain): string {
|
||||||
let displayName
|
let displayName
|
||||||
|
if (!data) return 'Unknown'
|
||||||
|
|
||||||
switch (data.chainId) {
|
switch (data.chainId) {
|
||||||
case 137:
|
case 137:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { sanitizeUrl } from '.'
|
import { sanitizeUrl, isGoogleUrl } from '.'
|
||||||
|
|
||||||
describe('@utils/url', () => {
|
describe('@utils/url', () => {
|
||||||
test('sanitizeUrl', () => {
|
test('sanitizeUrl', () => {
|
||||||
@ -7,3 +7,20 @@ describe('@utils/url', () => {
|
|||||||
expect(sanitizeUrl('ftp://example.com')).toBe('about:blank')
|
expect(sanitizeUrl('ftp://example.com')).toBe('about:blank')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('isGoogleUrl', () => {
|
||||||
|
it('should return true if the url is a google domain', () => {
|
||||||
|
expect(isGoogleUrl('https://google.com')).toBe(true)
|
||||||
|
expect(isGoogleUrl('https://drive.google.com')).toBe(true)
|
||||||
|
expect(isGoogleUrl('https://docs.google.com')).toBe(true)
|
||||||
|
expect(isGoogleUrl('https://sheets.google.com')).toBe(true)
|
||||||
|
expect(isGoogleUrl('https://meet.google.com')).toBe(true)
|
||||||
|
expect(isGoogleUrl('https://calendar.google.com')).toBe(true)
|
||||||
|
})
|
||||||
|
it('should return false if the url is not a google domain', () => {
|
||||||
|
expect(isGoogleUrl('https://google.test.com')).toBe(false)
|
||||||
|
expect(isGoogleUrl('https://drive.gloogle.com')).toBe(false)
|
||||||
|
expect(isGoogleUrl('https://drive.google.test.com')).toBe(false)
|
||||||
|
expect(isGoogleUrl('https://google.com.test.com')).toBe(false)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
@ -3,3 +3,10 @@ export function sanitizeUrl(url: string) {
|
|||||||
const isAllowedUrlScheme = u.startsWith('http://') || u.startsWith('https://')
|
const isAllowedUrlScheme = u.startsWith('http://') || u.startsWith('https://')
|
||||||
return isAllowedUrlScheme ? url : 'about:blank'
|
return isAllowedUrlScheme ? url : 'about:blank'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if the url is a google domain
|
||||||
|
export const isGoogleUrl = (url: string): boolean => {
|
||||||
|
if (!url) return
|
||||||
|
const googleUrl = new URL(url)
|
||||||
|
return googleUrl.hostname.endsWith('google.com')
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { isCID } from '@utils/ipfs'
|
import { isCID } from '@utils/ipfs'
|
||||||
import isUrl from 'is-url-superb'
|
import isUrl from 'is-url-superb'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
|
import { isGoogleUrl } from './url/index'
|
||||||
|
|
||||||
export function testLinks(isEdit?: boolean) {
|
export function testLinks(isEdit?: boolean) {
|
||||||
return Yup.string().test((value, context) => {
|
return Yup.string().test((value, context) => {
|
||||||
@ -28,7 +29,7 @@ export function testLinks(isEdit?: boolean) {
|
|||||||
validField = true
|
validField = true
|
||||||
}
|
}
|
||||||
// if the url has google drive, we need to block the user from submit
|
// if the url has google drive, we need to block the user from submit
|
||||||
if (value?.toString().includes('drive.google')) {
|
if (isGoogleUrl(value?.toString())) {
|
||||||
validField = false
|
validField = false
|
||||||
errorMessage =
|
errorMessage =
|
||||||
'Google Drive is not a supported hosting service. Please use an alternative.'
|
'Google Drive is not a supported hosting service. Please use an alternative.'
|
||||||
|
@ -3,7 +3,7 @@ import { ComponentStory, ComponentMeta } from '@storybook/react'
|
|||||||
import MarketMetadataProvider from '@context/MarketMetadata'
|
import MarketMetadataProvider from '@context/MarketMetadata'
|
||||||
import { UserPreferencesProvider } from '@context/UserPreferences'
|
import { UserPreferencesProvider } from '@context/UserPreferences'
|
||||||
import AssetList, { AssetListProps } from '.'
|
import AssetList, { AssetListProps } from '.'
|
||||||
import { assets } from '../../../../.jest/__fixtures__/assetsWithAccessDetails'
|
import { assets } from '../../../../.jest/__fixtures__/datasetsWithAccessDetails'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'Component/@shared/AssetList',
|
title: 'Component/@shared/AssetList',
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { render, screen, fireEvent } from '@testing-library/react'
|
import { render, screen, fireEvent } from '@testing-library/react'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import AssetList from './index'
|
import AssetList from './index'
|
||||||
import { assetAquarius } from '../../../../.jest/__fixtures__/assetAquarius'
|
import { datasetAquarius } from '../../../../.jest/__fixtures__/datasetAquarius'
|
||||||
|
|
||||||
describe('@shared/AssetList', () => {
|
describe('@shared/AssetList', () => {
|
||||||
it('renders without crashing', async () => {
|
it('renders without crashing', async () => {
|
||||||
@ -9,7 +9,7 @@ describe('@shared/AssetList', () => {
|
|||||||
|
|
||||||
render(
|
render(
|
||||||
<AssetList
|
<AssetList
|
||||||
assets={[assetAquarius]}
|
assets={[datasetAquarius]}
|
||||||
showPagination
|
showPagination
|
||||||
page={1}
|
page={1}
|
||||||
totalPages={10}
|
totalPages={10}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import testRender from '../../../../.jest/testRender'
|
import testRender from '../../../../.jest/testRender'
|
||||||
import AssetTeaser from './index'
|
import AssetTeaser from './index'
|
||||||
import { asset } from '../../../../.jest/__fixtures__/assetWithAccessDetails'
|
import { asset } from '../../../../.jest/__fixtures__/datasetWithAccessDetails'
|
||||||
|
|
||||||
describe('@shared/AssetTeaser', () => {
|
describe('@shared/AssetTeaser', () => {
|
||||||
testRender(<AssetTeaser asset={asset} />)
|
testRender(<AssetTeaser asset={asset} />)
|
||||||
|
@ -40,6 +40,9 @@ export default function FileIcon({
|
|||||||
? filesize(Number(file.contentLength)).toString()
|
? filesize(Number(file.contentLength)).toString()
|
||||||
: ''}
|
: ''}
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
{file.type === 'smartcontract' ? 'smart\ncontract' : file.type}
|
||||||
|
</li>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<li className={styles.empty}>No file info available</li>
|
<li className={styles.empty}>No file info available</li>
|
||||||
|
@ -6,6 +6,7 @@ import { InputProps } from '@shared/FormInput'
|
|||||||
import { getFileInfo } from '@utils/provider'
|
import { getFileInfo } from '@utils/provider'
|
||||||
import { LoggerInstance } from '@oceanprotocol/lib'
|
import { LoggerInstance } from '@oceanprotocol/lib'
|
||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
|
import { isGoogleUrl } from '@utils/url/index'
|
||||||
|
|
||||||
export default function FilesInput(props: InputProps): ReactElement {
|
export default function FilesInput(props: InputProps): ReactElement {
|
||||||
const [field, meta, helpers] = useField(props.name)
|
const [field, meta, helpers] = useField(props.name)
|
||||||
@ -26,7 +27,7 @@ export default function FilesInput(props: InputProps): ReactElement {
|
|||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
|
|
||||||
// TODO: handled on provider
|
// TODO: handled on provider
|
||||||
if (url.includes('drive.google')) {
|
if (isGoogleUrl(url)) {
|
||||||
throw Error(
|
throw Error(
|
||||||
'Google Drive is not a supported hosting service. Please use an alternative.'
|
'Google Drive is not a supported hosting service. Please use an alternative.'
|
||||||
)
|
)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { render, screen } from '@testing-library/react'
|
import { render, screen } from '@testing-library/react'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Price from './index'
|
import Price from './index'
|
||||||
import { asset } from '../../../../.jest/__fixtures__/assetWithAccessDetails'
|
import { asset } from '../../../../.jest/__fixtures__/datasetWithAccessDetails'
|
||||||
import prices from '../../../../.jest/__fixtures__/prices'
|
import prices from '../../../../.jest/__fixtures__/prices'
|
||||||
|
|
||||||
jest.mock('../../../@context/Prices', () => ({
|
jest.mock('../../../@context/Prices', () => ({
|
||||||
|
@ -43,7 +43,7 @@ export default function Tooltip(props: TippyProps): ReactElement {
|
|||||||
<Tippy
|
<Tippy
|
||||||
interactive
|
interactive
|
||||||
interactiveBorder={5}
|
interactiveBorder={5}
|
||||||
zIndex={1}
|
zIndex={3}
|
||||||
trigger={trigger || 'mouseenter focus'}
|
trigger={trigger || 'mouseenter focus'}
|
||||||
disabled={disabled || null}
|
disabled={disabled || null}
|
||||||
placement={placement || 'auto'}
|
placement={placement || 'auto'}
|
||||||
|
@ -23,14 +23,14 @@ const computeProps: ButtonBuyProps = {
|
|||||||
action: 'compute',
|
action: 'compute',
|
||||||
disabled: false,
|
disabled: false,
|
||||||
hasPreviousOrder: false,
|
hasPreviousOrder: false,
|
||||||
hasDatatoken: true,
|
hasDatatoken: false,
|
||||||
btSymbol: 'btSymbol',
|
btSymbol: 'btSymbol',
|
||||||
dtSymbol: 'dtSymbol',
|
dtSymbol: 'dtSymbol',
|
||||||
dtBalance: '100000000000',
|
dtBalance: '100000000000',
|
||||||
assetTimeout: '1 day',
|
assetTimeout: '1 day',
|
||||||
assetType: 'algorithm',
|
assetType: 'algorithm',
|
||||||
hasPreviousOrderSelectedComputeAsset: false,
|
hasPreviousOrderSelectedComputeAsset: false,
|
||||||
hasDatatokenSelectedComputeAsset: true,
|
hasDatatokenSelectedComputeAsset: false,
|
||||||
dtSymbolSelectedComputeAsset: 'dtSymbol',
|
dtSymbolSelectedComputeAsset: 'dtSymbol',
|
||||||
dtBalanceSelectedComputeAsset: 'dtBalance',
|
dtBalanceSelectedComputeAsset: 'dtBalance',
|
||||||
selectedComputeAssetType: 'selectedComputeAssetType',
|
selectedComputeAssetType: 'selectedComputeAssetType',
|
||||||
@ -78,6 +78,11 @@ describe('Asset/AssetActions/ButtonBuy', () => {
|
|||||||
render(<ButtonBuy {...downloadProps} priceType="free" hasPreviousOrder />)
|
render(<ButtonBuy {...downloadProps} priceType="free" hasPreviousOrder />)
|
||||||
const button = screen.getByText('Download')
|
const button = screen.getByText('Download')
|
||||||
expect(button).toContainHTML('<button')
|
expect(button).toContainHTML('<button')
|
||||||
|
expect(
|
||||||
|
screen.getByText(
|
||||||
|
'This Dataset is free to use. Please note that network gas fees still apply, even when using free assets.'
|
||||||
|
)
|
||||||
|
).toBeInTheDocument()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Renders "Get" button for free assets without crashing', () => {
|
it('Renders "Get" button for free assets without crashing', () => {
|
||||||
@ -105,6 +110,33 @@ describe('Asset/AssetActions/ButtonBuy', () => {
|
|||||||
expect(button).toContainHTML('<button')
|
expect(button).toContainHTML('<button')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Renders correct message for fixed-priced compute asset with free algorithm', () => {
|
||||||
|
render(<ButtonBuy {...computeProps} />)
|
||||||
|
expect(
|
||||||
|
screen.getByText(
|
||||||
|
'To use this algorithm, you will buy 1 dtSymbol and immediately send it back to the publisher. Connect to the correct network to interact with this asset. The C2D resources required to start the job are available, no payment is required for them. Please note that network gas fees still apply, even when using free assets.'
|
||||||
|
)
|
||||||
|
).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Renders correct message for free compute asset with free algorithm', () => {
|
||||||
|
render(<ButtonBuy {...computeProps} priceType="free" />)
|
||||||
|
expect(
|
||||||
|
screen.getByText(
|
||||||
|
'This algorithm is free to use. Connect to the correct network to interact with this asset. The C2D resources required to start the job are available, no payment is required for them. Please note that network gas fees still apply, even when using free assets.'
|
||||||
|
)
|
||||||
|
).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Renders correct message for free compute asset with free algorithm', () => {
|
||||||
|
render(<ButtonBuy {...computeProps} algorithmPriceType="fixed" />)
|
||||||
|
expect(
|
||||||
|
screen.getByText(
|
||||||
|
'To use this algorithm, you will buy 1 dtSymbol and immediately send it back to the publisher. Connect to the correct network to interact with this asset. The C2D resources required to start the job are available, no payment is required for them.'
|
||||||
|
)
|
||||||
|
).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
it('Renders "Buy Compute Job" button for compute without crashing', () => {
|
it('Renders "Buy Compute Job" button for compute without crashing', () => {
|
||||||
render(<ButtonBuy {...computeProps} hasDatatokenSelectedComputeAsset />)
|
render(<ButtonBuy {...computeProps} hasDatatokenSelectedComputeAsset />)
|
||||||
const button = screen.getByText('Buy Compute Job')
|
const button = screen.getByText('Buy Compute Job')
|
||||||
|
@ -46,7 +46,8 @@ function getConsumeHelpText(
|
|||||||
isBalanceSufficient: boolean,
|
isBalanceSufficient: boolean,
|
||||||
consumableFeedback: string,
|
consumableFeedback: string,
|
||||||
isSupportedOceanNetwork: boolean,
|
isSupportedOceanNetwork: boolean,
|
||||||
web3: Web3
|
web3: Web3,
|
||||||
|
priceType: string
|
||||||
) {
|
) {
|
||||||
const text =
|
const text =
|
||||||
isConsumable === false
|
isConsumable === false
|
||||||
@ -57,7 +58,9 @@ function getConsumeHelpText(
|
|||||||
? `You own ${dtBalance} ${dtSymbol} allowing you to use this dataset by spending 1 ${dtSymbol}, but without paying ${btSymbol} again.`
|
? `You own ${dtBalance} ${dtSymbol} allowing you to use this dataset by spending 1 ${dtSymbol}, but without paying ${btSymbol} again.`
|
||||||
: isBalanceSufficient === false
|
: isBalanceSufficient === false
|
||||||
? `You do not have enough ${btSymbol} in your wallet to purchase this asset.`
|
? `You do not have enough ${btSymbol} in your wallet to purchase this asset.`
|
||||||
: `For using this ${assetType}, you will buy 1 ${dtSymbol} and immediately spend it back to the publisher.`
|
: priceType === 'free'
|
||||||
|
? `This ${assetType} is free to use.`
|
||||||
|
: `To use this ${assetType}, you will buy 1 ${dtSymbol} and immediately send it back to the publisher.`
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +74,8 @@ function getAlgoHelpText(
|
|||||||
hasDatatokenSelectedComputeAsset: boolean,
|
hasDatatokenSelectedComputeAsset: boolean,
|
||||||
isBalanceSufficient: boolean,
|
isBalanceSufficient: boolean,
|
||||||
isSupportedOceanNetwork: boolean,
|
isSupportedOceanNetwork: boolean,
|
||||||
web3: Web3
|
web3: Web3,
|
||||||
|
algorithmPriceType: string
|
||||||
) {
|
) {
|
||||||
const text =
|
const text =
|
||||||
(!dtSymbolSelectedComputeAsset && !dtBalanceSelectedComputeAsset) ||
|
(!dtSymbolSelectedComputeAsset && !dtBalanceSelectedComputeAsset) ||
|
||||||
@ -86,7 +90,9 @@ function getAlgoHelpText(
|
|||||||
? `Connect to the correct network to interact with this asset.`
|
? `Connect to the correct network to interact with this asset.`
|
||||||
: isBalanceSufficient === false
|
: isBalanceSufficient === false
|
||||||
? ''
|
? ''
|
||||||
: `Additionally, you will buy 1 ${dtSymbolSelectedComputeAsset} for the ${selectedComputeAssetType} and spend it back to its publisher and pool.`
|
: algorithmPriceType === 'free'
|
||||||
|
? `Additionally, the selected ${selectedComputeAssetType} is free to use.`
|
||||||
|
: `Additionally, you will buy 1 ${dtSymbolSelectedComputeAsset} for the ${selectedComputeAssetType} and send it back to the publisher.`
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,6 +105,8 @@ function getComputeAssetHelpText(
|
|||||||
isConsumable: boolean,
|
isConsumable: boolean,
|
||||||
consumableFeedback: string,
|
consumableFeedback: string,
|
||||||
isBalanceSufficient: boolean,
|
isBalanceSufficient: boolean,
|
||||||
|
algorithmPriceType: string,
|
||||||
|
priceType: string,
|
||||||
hasPreviousOrderSelectedComputeAsset?: boolean,
|
hasPreviousOrderSelectedComputeAsset?: boolean,
|
||||||
hasDatatokenSelectedComputeAsset?: boolean,
|
hasDatatokenSelectedComputeAsset?: boolean,
|
||||||
assetType?: string,
|
assetType?: string,
|
||||||
@ -121,7 +129,8 @@ function getComputeAssetHelpText(
|
|||||||
isBalanceSufficient,
|
isBalanceSufficient,
|
||||||
consumableFeedback,
|
consumableFeedback,
|
||||||
isSupportedOceanNetwork,
|
isSupportedOceanNetwork,
|
||||||
web3
|
web3,
|
||||||
|
priceType
|
||||||
)
|
)
|
||||||
|
|
||||||
const computeAlgoHelpText = getAlgoHelpText(
|
const computeAlgoHelpText = getAlgoHelpText(
|
||||||
@ -134,13 +143,17 @@ function getComputeAssetHelpText(
|
|||||||
hasDatatokenSelectedComputeAsset,
|
hasDatatokenSelectedComputeAsset,
|
||||||
isBalanceSufficient,
|
isBalanceSufficient,
|
||||||
isSupportedOceanNetwork,
|
isSupportedOceanNetwork,
|
||||||
web3
|
web3,
|
||||||
|
algorithmPriceType
|
||||||
)
|
)
|
||||||
|
|
||||||
const providerFeeHelpText = hasProviderFee
|
const providerFeeHelpText = hasProviderFee
|
||||||
? 'In order to start the job you also need to pay the fees for renting the c2d resources.'
|
? 'In order to start the job you also need to pay the fees for renting the c2d resources.'
|
||||||
: 'C2D resources required to start the job are available, no payment required for those fees.'
|
: 'The C2D resources required to start the job are available, no payment is required for them.'
|
||||||
const computeHelpText = `${computeAssetHelpText} ${computeAlgoHelpText} ${providerFeeHelpText}`
|
let computeHelpText = `${computeAssetHelpText} ${computeAlgoHelpText} ${providerFeeHelpText}`
|
||||||
|
|
||||||
|
computeHelpText = computeHelpText.replace(/^\s+/, '')
|
||||||
|
console.log('computeHelpText', computeHelpText)
|
||||||
return computeHelpText
|
return computeHelpText
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,6 +203,53 @@ export default function ButtonBuy({
|
|||||||
? 'Order Compute Job'
|
? 'Order Compute Job'
|
||||||
: `Buy Compute Job`
|
: `Buy Compute Job`
|
||||||
|
|
||||||
|
function message(): string {
|
||||||
|
let message = ''
|
||||||
|
if (action === 'download') {
|
||||||
|
message = getConsumeHelpText(
|
||||||
|
btSymbol,
|
||||||
|
dtBalance,
|
||||||
|
dtSymbol,
|
||||||
|
hasDatatoken,
|
||||||
|
hasPreviousOrder,
|
||||||
|
assetType,
|
||||||
|
isConsumable,
|
||||||
|
isBalanceSufficient,
|
||||||
|
consumableFeedback,
|
||||||
|
isSupportedOceanNetwork,
|
||||||
|
web3,
|
||||||
|
priceType
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
message = getComputeAssetHelpText(
|
||||||
|
hasPreviousOrder,
|
||||||
|
hasDatatoken,
|
||||||
|
btSymbol,
|
||||||
|
dtSymbol,
|
||||||
|
dtBalance,
|
||||||
|
isConsumable,
|
||||||
|
consumableFeedback,
|
||||||
|
isBalanceSufficient,
|
||||||
|
algorithmPriceType,
|
||||||
|
priceType,
|
||||||
|
hasPreviousOrderSelectedComputeAsset,
|
||||||
|
hasDatatokenSelectedComputeAsset,
|
||||||
|
assetType,
|
||||||
|
dtSymbolSelectedComputeAsset,
|
||||||
|
dtBalanceSelectedComputeAsset,
|
||||||
|
selectedComputeAssetType,
|
||||||
|
isAlgorithmConsumable,
|
||||||
|
isSupportedOceanNetwork,
|
||||||
|
web3,
|
||||||
|
hasProviderFee
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (priceType === 'free' || algorithmPriceType === 'free') {
|
||||||
|
message +=
|
||||||
|
' Please note that network gas fees still apply, even when using free assets.'
|
||||||
|
}
|
||||||
|
return message
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div className={styles.actions}>
|
<div className={styles.actions}>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
@ -205,42 +265,7 @@ export default function ButtonBuy({
|
|||||||
>
|
>
|
||||||
{buttonText}
|
{buttonText}
|
||||||
</Button>
|
</Button>
|
||||||
<div className={styles.help}>
|
<div className={styles.help}>{message()}</div>
|
||||||
{action === 'download'
|
|
||||||
? getConsumeHelpText(
|
|
||||||
btSymbol,
|
|
||||||
dtBalance,
|
|
||||||
dtSymbol,
|
|
||||||
hasDatatoken,
|
|
||||||
hasPreviousOrder,
|
|
||||||
assetType,
|
|
||||||
isConsumable,
|
|
||||||
isBalanceSufficient,
|
|
||||||
consumableFeedback,
|
|
||||||
isSupportedOceanNetwork,
|
|
||||||
web3
|
|
||||||
)
|
|
||||||
: getComputeAssetHelpText(
|
|
||||||
hasPreviousOrder,
|
|
||||||
hasDatatoken,
|
|
||||||
btSymbol,
|
|
||||||
dtSymbol,
|
|
||||||
dtBalance,
|
|
||||||
isConsumable,
|
|
||||||
consumableFeedback,
|
|
||||||
isBalanceSufficient,
|
|
||||||
hasPreviousOrderSelectedComputeAsset,
|
|
||||||
hasDatatokenSelectedComputeAsset,
|
|
||||||
assetType,
|
|
||||||
dtSymbolSelectedComputeAsset,
|
|
||||||
dtBalanceSelectedComputeAsset,
|
|
||||||
selectedComputeAssetType,
|
|
||||||
isAlgorithmConsumable,
|
|
||||||
isSupportedOceanNetwork,
|
|
||||||
web3,
|
|
||||||
hasProviderFee
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -33,6 +33,7 @@ export default function FormStartCompute({
|
|||||||
hasDatatokenSelectedComputeAsset,
|
hasDatatokenSelectedComputeAsset,
|
||||||
datasetSymbol,
|
datasetSymbol,
|
||||||
algorithmSymbol,
|
algorithmSymbol,
|
||||||
|
providerFeesSymbol,
|
||||||
dtSymbolSelectedComputeAsset,
|
dtSymbolSelectedComputeAsset,
|
||||||
dtBalanceSelectedComputeAsset,
|
dtBalanceSelectedComputeAsset,
|
||||||
selectedComputeAssetType,
|
selectedComputeAssetType,
|
||||||
@ -61,6 +62,7 @@ export default function FormStartCompute({
|
|||||||
hasDatatokenSelectedComputeAsset?: boolean
|
hasDatatokenSelectedComputeAsset?: boolean
|
||||||
datasetSymbol?: string
|
datasetSymbol?: string
|
||||||
algorithmSymbol?: string
|
algorithmSymbol?: string
|
||||||
|
providerFeesSymbol?: string
|
||||||
dtSymbolSelectedComputeAsset?: string
|
dtSymbolSelectedComputeAsset?: string
|
||||||
dtBalanceSelectedComputeAsset?: string
|
dtBalanceSelectedComputeAsset?: string
|
||||||
selectedComputeAssetType?: string
|
selectedComputeAssetType?: string
|
||||||
@ -145,7 +147,7 @@ export default function FormStartCompute({
|
|||||||
? new Decimal(providerFeeAmount).toDecimalPlaces(MAX_DECIMALS)
|
? new Decimal(providerFeeAmount).toDecimalPlaces(MAX_DECIMALS)
|
||||||
: new Decimal(0)
|
: new Decimal(0)
|
||||||
|
|
||||||
if (algorithmSymbol === 'OCEAN') {
|
if (algorithmSymbol === providerFeesSymbol) {
|
||||||
let sum = providerFees.add(priceAlgo)
|
let sum = providerFees.add(priceAlgo)
|
||||||
totalPrices.push({
|
totalPrices.push({
|
||||||
value: sum.toDecimalPlaces(MAX_DECIMALS).toString(),
|
value: sum.toDecimalPlaces(MAX_DECIMALS).toString(),
|
||||||
@ -161,7 +163,7 @@ export default function FormStartCompute({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (datasetSymbol === 'OCEAN') {
|
if (datasetSymbol === providerFeesSymbol) {
|
||||||
const sum = providerFees.add(priceDataset)
|
const sum = providerFees.add(priceDataset)
|
||||||
totalPrices.push({
|
totalPrices.push({
|
||||||
value: sum.toDecimalPlaces(MAX_DECIMALS).toString(),
|
value: sum.toDecimalPlaces(MAX_DECIMALS).toString(),
|
||||||
@ -179,7 +181,7 @@ export default function FormStartCompute({
|
|||||||
})
|
})
|
||||||
totalPrices.push({
|
totalPrices.push({
|
||||||
value: providerFees.toDecimalPlaces(MAX_DECIMALS).toString(),
|
value: providerFees.toDecimalPlaces(MAX_DECIMALS).toString(),
|
||||||
symbol: 'OCEAN'
|
symbol: providerFeesSymbol
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
totalPrices.push({
|
totalPrices.push({
|
||||||
@ -188,7 +190,7 @@ export default function FormStartCompute({
|
|||||||
})
|
})
|
||||||
totalPrices.push({
|
totalPrices.push({
|
||||||
value: providerFees.toDecimalPlaces(MAX_DECIMALS).toString(),
|
value: providerFees.toDecimalPlaces(MAX_DECIMALS).toString(),
|
||||||
symbol: 'OCEAN'
|
symbol: providerFeesSymbol
|
||||||
})
|
})
|
||||||
totalPrices.push({
|
totalPrices.push({
|
||||||
value: priceAlgo.toDecimalPlaces(MAX_DECIMALS).toString(),
|
value: priceAlgo.toDecimalPlaces(MAX_DECIMALS).toString(),
|
||||||
@ -211,7 +213,8 @@ export default function FormStartCompute({
|
|||||||
datasetOrderPrice,
|
datasetOrderPrice,
|
||||||
algoOrderPrice,
|
algoOrderPrice,
|
||||||
algorithmSymbol,
|
algorithmSymbol,
|
||||||
datasetSymbol
|
datasetSymbol,
|
||||||
|
providerFeesSymbol
|
||||||
])
|
])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -263,6 +266,7 @@ export default function FormStartCompute({
|
|||||||
datasetOrderPrice={datasetOrderPrice}
|
datasetOrderPrice={datasetOrderPrice}
|
||||||
algoOrderPrice={algoOrderPrice}
|
algoOrderPrice={algoOrderPrice}
|
||||||
providerFeeAmount={providerFeeAmount}
|
providerFeeAmount={providerFeeAmount}
|
||||||
|
providerFeesSymbol={providerFeesSymbol}
|
||||||
validUntil={validUntil}
|
validUntil={validUntil}
|
||||||
totalPrices={totalPrices}
|
totalPrices={totalPrices}
|
||||||
/>
|
/>
|
||||||
|
@ -20,6 +20,7 @@ interface PriceOutputProps {
|
|||||||
datasetOrderPrice?: string
|
datasetOrderPrice?: string
|
||||||
algoOrderPrice?: string
|
algoOrderPrice?: string
|
||||||
providerFeeAmount?: string
|
providerFeeAmount?: string
|
||||||
|
providerFeesSymbol?: string
|
||||||
validUntil?: string
|
validUntil?: string
|
||||||
totalPrices?: totalPriceMap[]
|
totalPrices?: totalPriceMap[]
|
||||||
}
|
}
|
||||||
@ -84,6 +85,7 @@ export default function PriceOutput({
|
|||||||
datasetOrderPrice,
|
datasetOrderPrice,
|
||||||
algoOrderPrice,
|
algoOrderPrice,
|
||||||
providerFeeAmount,
|
providerFeeAmount,
|
||||||
|
providerFeesSymbol,
|
||||||
validUntil,
|
validUntil,
|
||||||
totalPrices
|
totalPrices
|
||||||
}: PriceOutputProps): ReactElement {
|
}: PriceOutputProps): ReactElement {
|
||||||
@ -134,7 +136,7 @@ export default function PriceOutput({
|
|||||||
<Row
|
<Row
|
||||||
price={providerFeeAmount} // initializeCompute.provider fee amount
|
price={providerFeeAmount} // initializeCompute.provider fee amount
|
||||||
timeout={`${validUntil} seconds`} // valid until value
|
timeout={`${validUntil} seconds`} // valid until value
|
||||||
symbol={'OCEAN'} // we assume that provider fees will always be in OCEAN token
|
symbol={providerFeesSymbol} // we assume that provider fees will always be in OCEAN token
|
||||||
sign="+"
|
sign="+"
|
||||||
type="C2D RESOURCES"
|
type="C2D RESOURCES"
|
||||||
/>
|
/>
|
||||||
|
@ -12,7 +12,8 @@ import {
|
|||||||
ComputeAlgorithm,
|
ComputeAlgorithm,
|
||||||
ComputeOutput,
|
ComputeOutput,
|
||||||
ProviderComputeInitializeResults,
|
ProviderComputeInitializeResults,
|
||||||
unitsToAmount
|
unitsToAmount,
|
||||||
|
minAbi
|
||||||
} from '@oceanprotocol/lib'
|
} from '@oceanprotocol/lib'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
import Price from '@shared/Price'
|
import Price from '@shared/Price'
|
||||||
@ -61,7 +62,7 @@ export default function Compute({
|
|||||||
fileIsLoading?: boolean
|
fileIsLoading?: boolean
|
||||||
consumableFeedback?: string
|
consumableFeedback?: string
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { accountId, web3, isSupportedOceanNetwork } = useWeb3()
|
const { accountId, web3, isSupportedOceanNetwork, networkId } = useWeb3()
|
||||||
const { chainIds } = useUserPreferences()
|
const { chainIds } = useUserPreferences()
|
||||||
const { isAssetNetwork } = useAsset()
|
const { isAssetNetwork } = useAsset()
|
||||||
|
|
||||||
@ -90,6 +91,7 @@ export default function Compute({
|
|||||||
const [initializedProviderResponse, setInitializedProviderResponse] =
|
const [initializedProviderResponse, setInitializedProviderResponse] =
|
||||||
useState<ProviderComputeInitializeResults>()
|
useState<ProviderComputeInitializeResults>()
|
||||||
const [providerFeeAmount, setProviderFeeAmount] = useState<string>('0')
|
const [providerFeeAmount, setProviderFeeAmount] = useState<string>('0')
|
||||||
|
const [providerFeesSymbol, setProviderFeesSymbol] = useState<string>('OCEAN')
|
||||||
const [computeValidUntil, setComputeValidUntil] = useState<string>('0')
|
const [computeValidUntil, setComputeValidUntil] = useState<string>('0')
|
||||||
const [datasetOrderPriceAndFees, setDatasetOrderPriceAndFees] =
|
const [datasetOrderPriceAndFees, setDatasetOrderPriceAndFees] =
|
||||||
useState<OrderPriceAndFees>()
|
useState<OrderPriceAndFees>()
|
||||||
@ -160,6 +162,18 @@ export default function Compute({
|
|||||||
|
|
||||||
setProviderFeeAmount(feeAmount)
|
setProviderFeeAmount(feeAmount)
|
||||||
|
|
||||||
|
const datatoken = new Datatoken(
|
||||||
|
await getDummyWeb3(asset?.chainId),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
minAbi
|
||||||
|
)
|
||||||
|
setProviderFeesSymbol(
|
||||||
|
await datatoken.getSymbol(
|
||||||
|
initializedProvider?.datasets?.[0]?.providerFee?.providerFeeToken
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
const computeDuration = (
|
const computeDuration = (
|
||||||
parseInt(initializedProvider?.datasets?.[0]?.providerFee?.validUntil) -
|
parseInt(initializedProvider?.datasets?.[0]?.providerFee?.validUntil) -
|
||||||
Math.floor(Date.now() / 1000)
|
Math.floor(Date.now() / 1000)
|
||||||
@ -466,11 +480,15 @@ export default function Compute({
|
|||||||
assetTimeout={secondsToString(asset?.services[0].timeout)}
|
assetTimeout={secondsToString(asset?.services[0].timeout)}
|
||||||
hasPreviousOrderSelectedComputeAsset={!!validAlgorithmOrderTx}
|
hasPreviousOrderSelectedComputeAsset={!!validAlgorithmOrderTx}
|
||||||
hasDatatokenSelectedComputeAsset={hasAlgoAssetDatatoken}
|
hasDatatokenSelectedComputeAsset={hasAlgoAssetDatatoken}
|
||||||
datasetSymbol={asset?.accessDetails?.baseToken?.symbol || 'OCEAN'}
|
datasetSymbol={
|
||||||
|
asset?.accessDetails?.baseToken?.symbol ||
|
||||||
|
(asset?.chainId === 137 ? 'mOCEAN' : 'OCEAN')
|
||||||
|
}
|
||||||
algorithmSymbol={
|
algorithmSymbol={
|
||||||
selectedAlgorithmAsset?.accessDetails?.baseToken?.symbol ||
|
selectedAlgorithmAsset?.accessDetails?.baseToken?.symbol ||
|
||||||
'OCEAN'
|
(selectedAlgorithmAsset?.chainId === 137 ? 'mOCEAN' : 'OCEAN')
|
||||||
}
|
}
|
||||||
|
providerFeesSymbol={providerFeesSymbol}
|
||||||
dtSymbolSelectedComputeAsset={
|
dtSymbolSelectedComputeAsset={
|
||||||
selectedAlgorithmAsset?.datatokens[0]?.symbol
|
selectedAlgorithmAsset?.datatokens[0]?.symbol
|
||||||
}
|
}
|
||||||
|
11
src/components/Asset/AssetContent/Bookmark.test.tsx
Normal file
11
src/components/Asset/AssetContent/Bookmark.test.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { render, screen } from '@testing-library/react'
|
||||||
|
import React from 'react'
|
||||||
|
import Bookmark from './Bookmark'
|
||||||
|
import { datasetAquarius } from '../../../../.jest/__fixtures__/datasetAquarius'
|
||||||
|
|
||||||
|
describe('src/components/Asset/AssetContent/Bookmark.tsx', () => {
|
||||||
|
it('renders Add Bookmark button', () => {
|
||||||
|
render(<Bookmark did={datasetAquarius.id} />)
|
||||||
|
expect(screen.getByTitle('Add Bookmark')).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
})
|
17
src/components/Asset/AssetContent/MetaFull.test.tsx
Normal file
17
src/components/Asset/AssetContent/MetaFull.test.tsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { render, screen } from '@testing-library/react'
|
||||||
|
import React from 'react'
|
||||||
|
import MetaFull from './MetaFull'
|
||||||
|
import { datasetAquarius } from '../../../../.jest/__fixtures__/datasetAquarius'
|
||||||
|
import { algorithmAquarius } from '../../../../.jest/__fixtures__/algorithmAquarius'
|
||||||
|
|
||||||
|
describe('src/components/Asset/AssetContent/MetaFull.tsx', () => {
|
||||||
|
it('renders metadata', () => {
|
||||||
|
render(<MetaFull ddo={datasetAquarius} />)
|
||||||
|
expect(screen.getByText('Owner')).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders metadata for an algorithm', () => {
|
||||||
|
render(<MetaFull ddo={algorithmAquarius} />)
|
||||||
|
expect(screen.getByText('Docker Image')).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
})
|
@ -3,17 +3,20 @@ import MetaItem from './MetaItem'
|
|||||||
import styles from './MetaFull.module.css'
|
import styles from './MetaFull.module.css'
|
||||||
import Publisher from '@shared/Publisher'
|
import Publisher from '@shared/Publisher'
|
||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
import { useWeb3 } from '@context/Web3'
|
// import { useWeb3 } from '@context/Web3'
|
||||||
|
import { getDummyWeb3 } from '@utils/web3'
|
||||||
import { Asset, Datatoken, LoggerInstance } from '@oceanprotocol/lib'
|
import { Asset, Datatoken, LoggerInstance } from '@oceanprotocol/lib'
|
||||||
|
|
||||||
export default function MetaFull({ ddo }: { ddo: Asset }): ReactElement {
|
export default function MetaFull({ ddo }: { ddo: Asset }): ReactElement {
|
||||||
const [paymentCollector, setPaymentCollector] = useState<string>()
|
const [paymentCollector, setPaymentCollector] = useState<string>()
|
||||||
const { isInPurgatory } = useAsset()
|
const { isInPurgatory } = useAsset()
|
||||||
const { web3 } = useWeb3()
|
// const { web3 } = useWeb3()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getInitialPaymentCollector() {
|
async function getInitialPaymentCollector() {
|
||||||
try {
|
try {
|
||||||
|
if (!ddo) return
|
||||||
|
const web3 = await getDummyWeb3(ddo.chainId)
|
||||||
const datatoken = new Datatoken(web3)
|
const datatoken = new Datatoken(web3)
|
||||||
setPaymentCollector(
|
setPaymentCollector(
|
||||||
await datatoken.getPaymentCollector(ddo.datatokens[0].address)
|
await datatoken.getPaymentCollector(ddo.datatokens[0].address)
|
||||||
@ -23,7 +26,7 @@ export default function MetaFull({ ddo }: { ddo: Asset }): ReactElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
getInitialPaymentCollector()
|
getInitialPaymentCollector()
|
||||||
}, [ddo, web3])
|
}, [ddo])
|
||||||
|
|
||||||
function DockerImage() {
|
function DockerImage() {
|
||||||
const containerInfo = ddo?.metadata?.algorithm?.container
|
const containerInfo = ddo?.metadata?.algorithm?.container
|
||||||
|
18
src/components/Asset/AssetContent/MetaSecondary.test.tsx
Normal file
18
src/components/Asset/AssetContent/MetaSecondary.test.tsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { render, screen } from '@testing-library/react'
|
||||||
|
import React from 'react'
|
||||||
|
import MetaSecondary from './MetaSecondary'
|
||||||
|
import { datasetAquarius } from '../../../../.jest/__fixtures__/datasetAquarius'
|
||||||
|
import { algorithmAquarius } from '../../../../.jest/__fixtures__/algorithmAquarius'
|
||||||
|
|
||||||
|
describe('src/components/Asset/AssetContent/MetaSecondary.tsx', () => {
|
||||||
|
it('renders tags', () => {
|
||||||
|
render(<MetaSecondary ddo={datasetAquarius} />)
|
||||||
|
expect(
|
||||||
|
screen.getByText(datasetAquarius.metadata.tags[0])
|
||||||
|
).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
it('renders download sample button', () => {
|
||||||
|
render(<MetaSecondary ddo={algorithmAquarius} />)
|
||||||
|
expect(screen.getByText('Sample Data')).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
})
|
@ -179,7 +179,7 @@ export default function Edit({
|
|||||||
initialValues={getInitialValues(
|
initialValues={getInitialValues(
|
||||||
asset?.metadata,
|
asset?.metadata,
|
||||||
asset?.services[0]?.timeout,
|
asset?.services[0]?.timeout,
|
||||||
asset?.accessDetails?.price,
|
asset?.accessDetails?.price || '0',
|
||||||
paymentCollector
|
paymentCollector
|
||||||
)}
|
)}
|
||||||
validationSchema={validationSchema}
|
validationSchema={validationSchema}
|
||||||
|
@ -6,6 +6,7 @@ import { useAsset } from '@context/Asset'
|
|||||||
import { FormPublishData } from '@components/Publish/_types'
|
import { FormPublishData } from '@components/Publish/_types'
|
||||||
import { getFileInfo } from '@utils/provider'
|
import { getFileInfo } from '@utils/provider'
|
||||||
import { getFieldContent } from '@utils/form'
|
import { getFieldContent } from '@utils/form'
|
||||||
|
import { isGoogleUrl } from '@utils/url'
|
||||||
|
|
||||||
export function checkIfTimeoutInPredefinedValues(
|
export function checkIfTimeoutInPredefinedValues(
|
||||||
timeout: string,
|
timeout: string,
|
||||||
@ -65,7 +66,7 @@ export default function FormEditMetadata({
|
|||||||
getFileInfo(asset.metadata.links[0], providerUrl, 'url').then(
|
getFileInfo(asset.metadata.links[0], providerUrl, 'url').then(
|
||||||
(checkedFile) => {
|
(checkedFile) => {
|
||||||
// set valid false if url is using google drive
|
// set valid false if url is using google drive
|
||||||
if (asset.metadata.links[0].includes('drive.google')) {
|
if (isGoogleUrl(asset.metadata.links[0])) {
|
||||||
setFieldValue('links', [
|
setFieldValue('links', [
|
||||||
{
|
{
|
||||||
url: asset.metadata.links[0],
|
url: asset.metadata.links[0],
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { render, screen } from '@testing-library/react'
|
import { render, screen } from '@testing-library/react'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import RelatedAssets from '.'
|
import RelatedAssets from '.'
|
||||||
import { assets } from '../../../../.jest/__fixtures__/assetsWithAccessDetails'
|
import { assets } from '../../../../.jest/__fixtures__/datasetsWithAccessDetails'
|
||||||
import { queryMetadata } from '../../../@utils/aquarius'
|
import { queryMetadata } from '../../../@utils/aquarius'
|
||||||
// import * as userPreferencesMock from '../../../@context/UserPreferences'
|
// import * as userPreferencesMock from '../../../@context/UserPreferences'
|
||||||
|
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
import React, { ReactElement } from 'react'
|
|
||||||
import { useUserPreferences } from '@context/UserPreferences'
|
|
||||||
import Input from '@shared/FormInput'
|
|
||||||
|
|
||||||
export default function TokenApproval(): ReactElement {
|
|
||||||
const { infiniteApproval, setInfiniteApproval } = useUserPreferences()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<li>
|
|
||||||
<Input
|
|
||||||
label="Token Approvals"
|
|
||||||
help="Use infinite amount when approving tokens in _Use_."
|
|
||||||
name="infiniteApproval"
|
|
||||||
type="checkbox"
|
|
||||||
options={['Allow infinite amount']}
|
|
||||||
defaultChecked={infiniteApproval === true}
|
|
||||||
onChange={() => setInfiniteApproval(!infiniteApproval)}
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
)
|
|
||||||
}
|
|
@ -7,7 +7,6 @@ import Debug from './Debug'
|
|||||||
import Caret from '@images/caret.svg'
|
import Caret from '@images/caret.svg'
|
||||||
import useDarkMode from '@oceanprotocol/use-dark-mode'
|
import useDarkMode from '@oceanprotocol/use-dark-mode'
|
||||||
import Appearance from './Appearance'
|
import Appearance from './Appearance'
|
||||||
import TokenApproval from './TokenApproval'
|
|
||||||
import { useMarketMetadata } from '@context/MarketMetadata'
|
import { useMarketMetadata } from '@context/MarketMetadata'
|
||||||
|
|
||||||
export default function UserPreferences(): ReactElement {
|
export default function UserPreferences(): ReactElement {
|
||||||
@ -20,7 +19,6 @@ export default function UserPreferences(): ReactElement {
|
|||||||
content={
|
content={
|
||||||
<ul className={styles.preferencesDetails}>
|
<ul className={styles.preferencesDetails}>
|
||||||
<Currency />
|
<Currency />
|
||||||
<TokenApproval />
|
|
||||||
<Appearance darkMode={darkMode} />
|
<Appearance darkMode={darkMode} />
|
||||||
<Debug />
|
<Debug />
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -3,7 +3,7 @@ import React from 'react'
|
|||||||
import MostViews from '.'
|
import MostViews from '.'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { queryMetadata } from '@utils/aquarius'
|
import { queryMetadata } from '@utils/aquarius'
|
||||||
import { assetAquarius } from '../../../../.jest/__fixtures__/assetAquarius'
|
import { datasetAquarius } from '../../../../.jest/__fixtures__/datasetAquarius'
|
||||||
|
|
||||||
jest.mock('axios')
|
jest.mock('axios')
|
||||||
jest.mock('@utils/aquarius')
|
jest.mock('@utils/aquarius')
|
||||||
@ -12,7 +12,7 @@ const axiosMock = axios as jest.Mocked<typeof axios>
|
|||||||
const queryMetadataMock = queryMetadata as jest.Mock
|
const queryMetadataMock = queryMetadata as jest.Mock
|
||||||
|
|
||||||
const queryMetadataBaseReturn: PagedAssets = {
|
const queryMetadataBaseReturn: PagedAssets = {
|
||||||
results: [assetAquarius],
|
results: [datasetAquarius],
|
||||||
page: 1,
|
page: 1,
|
||||||
totalPages: 1,
|
totalPages: 1,
|
||||||
totalResults: 1,
|
totalResults: 1,
|
||||||
@ -27,7 +27,7 @@ describe('components/Home/MostViews', () => {
|
|||||||
it('renders without crashing', async () => {
|
it('renders without crashing', async () => {
|
||||||
axiosMock.get.mockImplementation(() =>
|
axiosMock.get.mockImplementation(() =>
|
||||||
Promise.resolve({
|
Promise.resolve({
|
||||||
data: [{ count: 666, did: assetAquarius.id }]
|
data: [{ count: 666, did: datasetAquarius.id }]
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
queryMetadataMock.mockResolvedValue(queryMetadataBaseReturn)
|
queryMetadataMock.mockResolvedValue(queryMetadataBaseReturn)
|
||||||
|
@ -14,25 +14,9 @@ export default function Page404(): ReactElement {
|
|||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<style type="text/css">{`
|
<style type="text/css">{`
|
||||||
body {
|
|
||||||
background: transparent url(${fishfail}) center bottom no-repeat !important;
|
|
||||||
background-size: cover !important;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
header *,
|
|
||||||
footer *,
|
|
||||||
main * {
|
|
||||||
color: var(--brand-white) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
header svg path {
|
|
||||||
fill: var(--brand-white) !important;
|
|
||||||
}
|
|
||||||
`}</style>
|
`}</style>
|
||||||
</Head>
|
</Head>
|
||||||
<Page
|
<Page
|
||||||
|
Loading…
Reference in New Issue
Block a user