mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Merge branch 'main' into fix/issue497-fetch-price-subgraph, fixed merge conflicts
This commit is contained in:
commit
ff1d987b5d
@ -1,5 +1,5 @@
|
||||
# Default network, possible values:
|
||||
# "development", "ropsten", "rinkeby", "mainnet", "polygon"
|
||||
# "development", "ropsten", "rinkeby", "mainnet", "polygon", "moonbeamalpha"
|
||||
GATSBY_NETWORK="rinkeby"
|
||||
|
||||
#GATSBY_INFURA_PROJECT_ID="xxx"
|
||||
|
@ -20,6 +20,15 @@
|
||||
"rows": 10,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "price",
|
||||
"label": "New Price",
|
||||
"type": "number",
|
||||
"min": "1",
|
||||
"placeholder": "0",
|
||||
"help": "Enter a new price.",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "links",
|
||||
"label": "Sample file",
|
||||
|
@ -6,13 +6,6 @@
|
||||
"successAction": "Close",
|
||||
"error": "Updating DDO failed.",
|
||||
"data": [
|
||||
{
|
||||
"name": "allowAllPublishedAlgorithms",
|
||||
"label": "All Algorithms",
|
||||
"help": "Allow any published algorithm to run on this data set.",
|
||||
"type": "checkbox",
|
||||
"options": ["Allow any published algorithm"]
|
||||
},
|
||||
{
|
||||
"name": "publisherTrustedAlgorithms",
|
||||
"label": "Selected Algorithms",
|
||||
@ -21,6 +14,13 @@
|
||||
"multiple": true,
|
||||
"options": [],
|
||||
"sortOptions": false
|
||||
},
|
||||
{
|
||||
"name": "allowAllPublishedAlgorithms",
|
||||
"label": "All Algorithms",
|
||||
"help": "Allow any published algorithm to run on this data set.",
|
||||
"type": "checkbox",
|
||||
"options": ["Allow any published algorithm"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
{
|
||||
"title": "History",
|
||||
"description": "Find the data sets and jobs that you previously accessed."
|
||||
"description": "Find the data sets and jobs that you previously accessed.",
|
||||
"compute": {
|
||||
"storage": "Results are stored for 30 days."
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
"name": "files",
|
||||
"label": "File",
|
||||
"placeholder": "e.g. https://file.com/file.json",
|
||||
"help": "Please enter the URL to your algorithm file and click \"ADD FILE\" to validate the data. This URL will be stored encrypted after publishing.",
|
||||
"help": "Please enter the URL to your algorithm file and click \"ADD FILE\" to validate the data. This URL will be stored encrypted after publishing. Some restrictions apply:\n\n- max. running time: 1 min.\n- [Writing Algorithms for Compute to Data](https://docs.oceanprotocol.com/tutorials/compute-to-data-algorithms/)",
|
||||
"type": "files",
|
||||
"required": true
|
||||
},
|
||||
@ -56,6 +56,13 @@
|
||||
"sortOptions": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "dataTokenOptions",
|
||||
"label": "Datatoken Name & Symbol",
|
||||
"type": "datatoken",
|
||||
"help": "The datatoken for this algorithm will be created with this name & symbol.",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "entrypoint",
|
||||
"label": "Entrypoint",
|
||||
|
@ -19,7 +19,7 @@
|
||||
"name": "files",
|
||||
"label": "File",
|
||||
"placeholder": "e.g. https://file.com/file.json",
|
||||
"help": "Please enter the URL to your data set file and click \"ADD FILE\" to validate the data. This URL will be stored encrypted after publishing.",
|
||||
"help": "Please enter the URL to your data set file and click \"ADD FILE\" to validate the data. This URL will be stored encrypted after publishing. For a compute data set, your file should match the file type required by the algorithm, and should not exceed 1 GB in file size.",
|
||||
"type": "files",
|
||||
"required": true
|
||||
},
|
||||
|
36
package-lock.json
generated
36
package-lock.json
generated
@ -1573,16 +1573,16 @@
|
||||
}
|
||||
},
|
||||
"@ethereum-navigator/atlas": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@ethereum-navigator/atlas/-/atlas-0.7.1.tgz",
|
||||
"integrity": "sha512-YV7tMVwpRcJbc+Kj/Rr0RzNV/2hHBEEM1/tMWDVLB15dGJfoQuRfPJpFt6uq+Ji6s3EkldIt9kZylEeG5ALKAA=="
|
||||
"version": "0.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@ethereum-navigator/atlas/-/atlas-0.7.3.tgz",
|
||||
"integrity": "sha512-kCyV/8wOqSU/gn+H7uSaR/Xc+ZogXrW2QmF5MfZL2+NUS4+y0emlfBphTGwP5bOB0Cg2goJTcI7Y6+0LNcJYzg=="
|
||||
},
|
||||
"@ethereum-navigator/navigator": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ethereum-navigator/navigator/-/navigator-0.5.2.tgz",
|
||||
"integrity": "sha512-agSE2xzLxOKKid8QiS4v8jPhnFXW5uSXsICZ4JmS437aCZ8L3SUAy3cDQKikHb2PPZ3AazJO05k8m8i6u77peQ==",
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@ethereum-navigator/navigator/-/navigator-0.5.3.tgz",
|
||||
"integrity": "sha512-AOhS1EXPrVeWbLvW3fVbw5AZ2mPYXDKOqMojgVz602U/tEjRXAsw/Gwa+oSOssAyU37SNKBaIorEhBiEY+RYdA==",
|
||||
"requires": {
|
||||
"@ethereum-navigator/atlas": "^0.7.1",
|
||||
"@ethereum-navigator/atlas": "^0.7.2",
|
||||
"web3": "^1.2.7"
|
||||
}
|
||||
},
|
||||
@ -3622,24 +3622,24 @@
|
||||
"integrity": "sha512-j4PEZSVtKSqxDYMVh/hd5vk088Bg6a6QkrUMTXN9Q6OIFAMfHM235f1AxaakNrEyK0FKMD908KuJEdfFLRn9Hw=="
|
||||
},
|
||||
"@oceanprotocol/contracts": {
|
||||
"version": "0.5.15",
|
||||
"resolved": "https://registry.npmjs.org/@oceanprotocol/contracts/-/contracts-0.5.15.tgz",
|
||||
"integrity": "sha512-16edzNeO2v5WLW9ClsZ9VvMH1w24fZZutCmDhZWPirCAIdojGWRHraompfICjY1fovDljnZ5MpJpffuQ6kgxOA=="
|
||||
"version": "0.5.16",
|
||||
"resolved": "https://registry.npmjs.org/@oceanprotocol/contracts/-/contracts-0.5.16.tgz",
|
||||
"integrity": "sha512-p7aFIUT8RVoMzdPP7ML8G08BnQ09syywKjOT16hqJm0GmofunEuVffUXbryG4EkQ+qRbf/zeoxSmesi79kQXlA=="
|
||||
},
|
||||
"@oceanprotocol/lib": {
|
||||
"version": "0.14.4",
|
||||
"resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-0.14.4.tgz",
|
||||
"integrity": "sha512-f6Wj6FLpYmuFSGtnDw0lex0Vru1tGgvZqtwrdBYtMD+hW6Bn3B51+F/9ACVYAiSRDADrqPTDZiZetT2Ji3QY7Q==",
|
||||
"version": "0.14.8",
|
||||
"resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-0.14.8.tgz",
|
||||
"integrity": "sha512-eqab5iEgowyIM/LcDDs6xhZo/KToOmVw0betjXLG0+g70zS8R6XL2RHzCpFyutSdf/cH0w/ltPUfR8ZBElIyhQ==",
|
||||
"requires": {
|
||||
"@ethereum-navigator/navigator": "^0.5.2",
|
||||
"@oceanprotocol/contracts": "^0.5.10",
|
||||
"@oceanprotocol/contracts": "0.5.16",
|
||||
"@types/crypto-js": "^4.0.1",
|
||||
"cross-fetch": "^3.1.2",
|
||||
"crypto-js": "^4.0.0",
|
||||
"decimal.js": "^10.2.1",
|
||||
"fs": "0.0.1-security",
|
||||
"lzma": "^2.3.2",
|
||||
"node-abort-controller": "^1.2.0",
|
||||
"node-abort-controller": "^2.0.0",
|
||||
"save-file": "^2.3.1",
|
||||
"uuid": "^8.3.2",
|
||||
"web3": "^1.3.5",
|
||||
@ -28882,9 +28882,9 @@
|
||||
}
|
||||
},
|
||||
"node-abort-controller": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-1.2.1.tgz",
|
||||
"integrity": "sha512-79PYeJuj6S9+yOHirR0JBLFOgjB6sQCir10uN6xRx25iD+ZD4ULqgRn3MwWBRaQGB0vEgReJzWwJo42T1R6YbQ=="
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-2.0.0.tgz",
|
||||
"integrity": "sha512-L8RfEgjBTHAISTuagw51PprVAqNZoG6KSB6LQ6H1bskMVkFs5E71IyjauLBv3XbuomJlguWF/VnRHdJ1gqiAqA=="
|
||||
},
|
||||
"node-addon-api": {
|
||||
"version": "2.0.2",
|
||||
|
@ -27,7 +27,7 @@
|
||||
"@coingecko/cryptoformat": "^0.4.2",
|
||||
"@loadable/component": "^5.14.1",
|
||||
"@oceanprotocol/art": "^3.0.0",
|
||||
"@oceanprotocol/lib": "^0.14.4",
|
||||
"@oceanprotocol/lib": "^0.14.8",
|
||||
"@oceanprotocol/typographies": "^0.1.0",
|
||||
"@portis/web3": "^3.0.3",
|
||||
"@sindresorhus/slugify": "^1.0.0",
|
||||
|
2
src/@types/MetaData.d.ts
vendored
2
src/@types/MetaData.d.ts
vendored
@ -49,6 +49,7 @@ export interface MetadataPublishFormAlgorithm {
|
||||
dockerImage: string
|
||||
algorithmPrivacy: boolean
|
||||
timeout: string
|
||||
dataTokenOptions: DataTokenOptions
|
||||
termsAndConditions: boolean
|
||||
// ---- optional fields ----
|
||||
image: string
|
||||
@ -61,6 +62,7 @@ export interface MetadataEditForm {
|
||||
name: string
|
||||
description: string
|
||||
timeout: string
|
||||
price?: number
|
||||
links?: string | EditableMetadataLinks[]
|
||||
}
|
||||
|
||||
|
@ -91,6 +91,7 @@ export default function InputElement({
|
||||
id={slugify(option)}
|
||||
type={type}
|
||||
name={name}
|
||||
checked={props.defaultChecked}
|
||||
{...props}
|
||||
/>
|
||||
<label className={styles.radioLabel} htmlFor={slugify(option)}>
|
||||
|
@ -107,7 +107,9 @@
|
||||
|
||||
.did {
|
||||
padding: 0;
|
||||
font-size: var(--font-size-mini);
|
||||
/* font-size: var(--font-size-mini); */
|
||||
/* hack to make DotDotDot clamp work in Safari*/
|
||||
font-size: 0.63rem;
|
||||
display: block;
|
||||
text-align: left;
|
||||
color: var(--color-secondary);
|
||||
|
@ -27,7 +27,7 @@ export default function FileInput({
|
||||
<Button
|
||||
style="primary"
|
||||
size="small"
|
||||
onClick={(e: React.SyntheticEvent) => handleButtonClick(e, field.value)}
|
||||
onClick={(e: React.SyntheticEvent) => e.preventDefault()}
|
||||
disabled={!field.value}
|
||||
>
|
||||
{isLoading ? <Loader /> : 'Add File'}
|
||||
|
@ -14,7 +14,7 @@ export default function FilesInput(props: InputProps): ReactElement {
|
||||
const [fileUrl, setFileUrl] = useState<string>()
|
||||
const { config } = useOcean()
|
||||
|
||||
useEffect(() => {
|
||||
function loadFileInfo() {
|
||||
const source = axios.CancelToken.source()
|
||||
|
||||
async function validateUrl() {
|
||||
@ -33,11 +33,16 @@ export default function FilesInput(props: InputProps): ReactElement {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
fileUrl && validateUrl()
|
||||
|
||||
return () => {
|
||||
source.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
loadFileInfo()
|
||||
}, [fileUrl, config.providerUri])
|
||||
|
||||
async function handleButtonClick(e: React.SyntheticEvent, url: string) {
|
||||
@ -48,6 +53,11 @@ export default function FilesInput(props: InputProps): ReactElement {
|
||||
// File example 'https://oceanprotocol.com/tech-whitepaper.pdf'
|
||||
e.preventDefault()
|
||||
|
||||
// In the case when the user re-add the same URL after it was removed (by accident or intentionally)
|
||||
if (fileUrl === url) {
|
||||
loadFileInfo()
|
||||
}
|
||||
|
||||
setFileUrl(url)
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,10 @@ const query = graphql`
|
||||
|
||||
export default function Terms(props: InputProps): ReactElement {
|
||||
const data = useStaticQuery(query)
|
||||
const termsProps: InputProps = {
|
||||
...props,
|
||||
defaultChecked: props.value.toString() === 'true'
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -21,7 +25,7 @@ export default function Terms(props: InputProps): ReactElement {
|
||||
className={styles.terms}
|
||||
dangerouslySetInnerHTML={{ __html: data.terms.html }}
|
||||
/>
|
||||
<InputElement {...props} type="checkbox" />
|
||||
<InputElement {...termsProps} type="checkbox" />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -135,6 +135,11 @@ export function MetadataAlgorithmPreview({
|
||||
<h2 className={styles.previewTitle}>Preview</h2>
|
||||
<header>
|
||||
{values.name && <h3 className={styles.title}>{values.name}</h3>}
|
||||
{values.dataTokenOptions?.name && (
|
||||
<p
|
||||
className={styles.datatoken}
|
||||
>{`${values.dataTokenOptions.name} — ${values.dataTokenOptions.symbol}`}</p>
|
||||
)}
|
||||
{values.description && <Description description={values.description} />}
|
||||
|
||||
<div className={styles.asset}>
|
||||
|
@ -17,20 +17,30 @@ export default function SearchBar({
|
||||
filters?: boolean
|
||||
size?: 'small' | 'large'
|
||||
}): ReactElement {
|
||||
const [value, setValue] = useState(initialValue || '')
|
||||
|
||||
function handleChange(e: ChangeEvent<HTMLInputElement>) {
|
||||
setValue(e.target.value)
|
||||
}
|
||||
let [value, setValue] = useState(initialValue || '')
|
||||
|
||||
async function startSearch(e: FormEvent<HTMLButtonElement>) {
|
||||
e.preventDefault()
|
||||
if (value === '') return
|
||||
if (value === '') value = ' '
|
||||
const urlEncodedValue = encodeURIComponent(value)
|
||||
const url = await addExistingParamsToUrl(location, 'text')
|
||||
navigate(`${url}&text=${urlEncodedValue}`)
|
||||
}
|
||||
|
||||
async function emptySearch() {
|
||||
const searchParams = new URLSearchParams(window.location.href)
|
||||
const text = searchParams.get('text')
|
||||
if (text !== ('' || undefined || null)) {
|
||||
const url = await addExistingParamsToUrl(location, 'text')
|
||||
navigate(`${url}&text=%20`)
|
||||
}
|
||||
}
|
||||
|
||||
function handleChange(e: ChangeEvent<HTMLInputElement>) {
|
||||
setValue(e.target.value)
|
||||
e.target.value === '' && emptySearch()
|
||||
}
|
||||
|
||||
return (
|
||||
<form className={styles.form}>
|
||||
<InputGroup>
|
||||
|
@ -1,14 +1,13 @@
|
||||
.buttons {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
display: grid;
|
||||
gap: calc(var(--spacer) / 4);
|
||||
grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr));
|
||||
padding-bottom: calc(var(--spacer) / 8);
|
||||
}
|
||||
|
||||
.button {
|
||||
display: block;
|
||||
flex: 0 0 48%;
|
||||
padding: calc(var(--spacer) / 3) calc(var(--spacer) / 2)
|
||||
calc(var(--spacer) / 4) calc(var(--spacer) / 2) !important;
|
||||
width: auto;
|
||||
padding: calc(var(--spacer) / 3) calc(var(--spacer) / 4) !important;
|
||||
border-radius: var(--border-radius);
|
||||
text-transform: none;
|
||||
}
|
||||
|
@ -18,8 +18,9 @@ export default function Chain(): ReactElement {
|
||||
}
|
||||
|
||||
const chains = [
|
||||
{ name: 'ETH', oceanConfig: 'mainnet' },
|
||||
{ name: 'Polygon/Matic', oceanConfig: 'polygon' }
|
||||
{ name: 'ETH', oceanConfig: 'mainnet', label: 'Mainnet' },
|
||||
{ name: 'Polygon/Matic', oceanConfig: 'polygon', label: 'Mainnet' },
|
||||
{ name: 'Moonbase Alpha', oceanConfig: 'moonbeamalpha', label: 'Testnet' }
|
||||
]
|
||||
|
||||
// TODO: to fully solve https://github.com/oceanprotocol/market/issues/432
|
||||
@ -42,7 +43,7 @@ export default function Chain(): ReactElement {
|
||||
onClick={() => connectOcean(button.oceanConfig)}
|
||||
>
|
||||
{button.name}
|
||||
<span>Mainnet</span>
|
||||
<span>{button.label}</span>
|
||||
</Button>
|
||||
)
|
||||
})}
|
||||
|
@ -25,7 +25,10 @@ import {
|
||||
getInitialValues,
|
||||
validationSchema
|
||||
} from '../../../../models/FormStartComputeDataset'
|
||||
import { ComputeAlgorithm } from '@oceanprotocol/lib/dist/node/ocean/interfaces/Compute'
|
||||
import {
|
||||
ComputeAlgorithm,
|
||||
ComputeOutput
|
||||
} from '@oceanprotocol/lib/dist/node/ocean/interfaces/Compute'
|
||||
import { AssetSelectionAsset } from '../../../molecules/FormFields/AssetSelection'
|
||||
import { SearchQuery } from '@oceanprotocol/lib/dist/node/metadatacache/MetadataCache'
|
||||
import axios from 'axios'
|
||||
@ -190,26 +193,30 @@ export default function Compute({
|
||||
}, [ocean, ddo, accountId])
|
||||
|
||||
useEffect(() => {
|
||||
if (!ocean || !accountId || !selectedAlgorithmAsset) return
|
||||
if (!selectedAlgorithmAsset) return
|
||||
|
||||
if (selectedAlgorithmAsset.findServiceByType('access')) {
|
||||
checkPreviousOrders(selectedAlgorithmAsset).then(() => {
|
||||
if (
|
||||
!hasPreviousAlgorithmOrder &&
|
||||
selectedAlgorithmAsset.findServiceByType('compute')
|
||||
) {
|
||||
checkPreviousOrders(selectedAlgorithmAsset)
|
||||
}
|
||||
})
|
||||
} else if (selectedAlgorithmAsset.findServiceByType('compute')) {
|
||||
checkPreviousOrders(selectedAlgorithmAsset)
|
||||
}
|
||||
checkAssetDTBalance(selectedAlgorithmAsset)
|
||||
initMetadata(selectedAlgorithmAsset)
|
||||
|
||||
const { timeout } = (
|
||||
ddo.findServiceByType('access') || ddo.findServiceByType('compute')
|
||||
).attributes.main
|
||||
setAlgorithmTimeout(secondsToString(timeout))
|
||||
|
||||
if (accountId) {
|
||||
if (selectedAlgorithmAsset.findServiceByType('access')) {
|
||||
checkPreviousOrders(selectedAlgorithmAsset).then(() => {
|
||||
if (
|
||||
!hasPreviousAlgorithmOrder &&
|
||||
selectedAlgorithmAsset.findServiceByType('compute')
|
||||
) {
|
||||
checkPreviousOrders(selectedAlgorithmAsset)
|
||||
}
|
||||
})
|
||||
} else if (selectedAlgorithmAsset.findServiceByType('compute')) {
|
||||
checkPreviousOrders(selectedAlgorithmAsset)
|
||||
}
|
||||
}
|
||||
ocean && checkAssetDTBalance(selectedAlgorithmAsset)
|
||||
}, [selectedAlgorithmAsset, ocean, accountId, hasPreviousAlgorithmOrder])
|
||||
|
||||
// Output errors in toast UI
|
||||
@ -330,7 +337,10 @@ export default function Compute({
|
||||
computeAlgorithm.transferTxId = algorithmAssetOrderId
|
||||
Logger.log('[compute] Starting compute job.')
|
||||
|
||||
const output = {}
|
||||
const output: ComputeOutput = {
|
||||
publishAlgorithmLog: true,
|
||||
publishOutput: true
|
||||
}
|
||||
const response = await ocean.compute.start(
|
||||
ddo.id,
|
||||
assetOrderId,
|
||||
@ -410,7 +420,9 @@ export default function Compute({
|
||||
action={<SuccessAction />}
|
||||
/>
|
||||
)}
|
||||
<Web3Feedback isBalanceSufficient={isBalanceSufficient} />
|
||||
{type !== 'algorithm' && (
|
||||
<Web3Feedback isBalanceSufficient={isBalanceSufficient} />
|
||||
)}
|
||||
</footer>
|
||||
</>
|
||||
)
|
||||
|
@ -47,15 +47,17 @@ export default function FormEditMetadata({
|
||||
data,
|
||||
setShowEdit,
|
||||
setTimeoutStringValue,
|
||||
values
|
||||
values,
|
||||
showPrice
|
||||
}: {
|
||||
data: FormFieldProps[]
|
||||
setShowEdit: (show: boolean) => void
|
||||
setTimeoutStringValue: (value: string) => void
|
||||
values: Partial<MetadataPublishFormDataset>
|
||||
showPrice: boolean
|
||||
}): ReactElement {
|
||||
const { accountId } = useWeb3()
|
||||
const { ocean } = useOcean()
|
||||
const { ocean, config } = useOcean()
|
||||
const {
|
||||
isValid,
|
||||
validateField,
|
||||
@ -79,16 +81,20 @@ export default function FormEditMetadata({
|
||||
|
||||
return (
|
||||
<Form className={styles.form}>
|
||||
{data.map((field: FormFieldProps) => (
|
||||
<Field
|
||||
key={field.name}
|
||||
{...field}
|
||||
component={Input}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||
handleFieldChange(e, field)
|
||||
}
|
||||
/>
|
||||
))}
|
||||
{data.map(
|
||||
(field: FormFieldProps) =>
|
||||
(!showPrice && field.name === 'price') || (
|
||||
<Field
|
||||
key={field.name}
|
||||
{...field}
|
||||
component={Input}
|
||||
prefix={field.name === 'price' && config.oceanTokenSymbol}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||
handleFieldChange(e, field)
|
||||
}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
|
||||
<footer className={styles.actions}>
|
||||
<Button
|
||||
|
@ -36,6 +36,7 @@ const contentQuery = graphql`
|
||||
label
|
||||
help
|
||||
type
|
||||
min
|
||||
required
|
||||
sortOptions
|
||||
options
|
||||
@ -60,7 +61,7 @@ export default function Edit({
|
||||
const { debug } = useUserPreferences()
|
||||
const { accountId } = useWeb3()
|
||||
const { ocean } = useOcean()
|
||||
const { metadata, ddo, refreshDdo } = useAsset()
|
||||
const { metadata, ddo, refreshDdo, price } = useAsset()
|
||||
const [success, setSuccess] = useState<string>()
|
||||
const [error, setError] = useState<string>()
|
||||
const [timeoutStringValue, setTimeoutStringValue] = useState<string>()
|
||||
@ -70,6 +71,18 @@ export default function Edit({
|
||||
|
||||
const hasFeedback = error || success
|
||||
|
||||
async function updateFixedPrice(newPrice: number) {
|
||||
const setPriceResp = await ocean.fixedRateExchange.setRate(
|
||||
price.address,
|
||||
newPrice,
|
||||
accountId
|
||||
)
|
||||
if (!setPriceResp) {
|
||||
setError(content.form.error)
|
||||
Logger.error(content.form.error)
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSubmit(
|
||||
values: Partial<MetadataEditForm>,
|
||||
resetForm: () => void
|
||||
@ -82,6 +95,10 @@ export default function Edit({
|
||||
links: typeof values.links !== 'string' ? values.links : []
|
||||
})
|
||||
|
||||
price.type === 'exchange' &&
|
||||
values.price !== price.value &&
|
||||
(await updateFixedPrice(values.price))
|
||||
|
||||
if (!ddoEditedMetdata) {
|
||||
setError(content.form.error)
|
||||
Logger.error(content.form.error)
|
||||
@ -127,7 +144,7 @@ export default function Edit({
|
||||
|
||||
return (
|
||||
<Formik
|
||||
initialValues={getInitialValues(metadata, timeout)}
|
||||
initialValues={getInitialValues(metadata, timeout, price.value)}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={async (values, { resetForm }) => {
|
||||
// move user's focus to top of screen
|
||||
@ -160,6 +177,7 @@ export default function Edit({
|
||||
setShowEdit={setShowEdit}
|
||||
setTimeoutStringValue={setTimeoutStringValue}
|
||||
values={initialValues}
|
||||
showPrice={price.type === 'exchange'}
|
||||
/>
|
||||
|
||||
<aside>
|
||||
|
@ -174,7 +174,7 @@ export default function Add({
|
||||
) : (
|
||||
<Alert
|
||||
className={styles.warning}
|
||||
text={content.warning.main}
|
||||
text={content.warning}
|
||||
state="info"
|
||||
action={{
|
||||
name: 'I understand',
|
||||
|
@ -21,6 +21,7 @@ import UserLiquidity from '../../../atoms/UserLiquidity'
|
||||
import InputElement from '../../../atoms/Input/InputElement'
|
||||
import { useOcean } from '../../../../providers/Ocean'
|
||||
import { useWeb3 } from '../../../../providers/Web3'
|
||||
import Decimal from 'decimal.js'
|
||||
|
||||
const contentQuery = graphql`
|
||||
query PoolRemoveQuery {
|
||||
@ -155,14 +156,6 @@ export default function Remove({
|
||||
totalPoolTokens
|
||||
])
|
||||
|
||||
async function calculateAmountOfOceansRemoved(amountPoolShares: string) {
|
||||
const oceanAmount = await ocean.pool.getOceanRemovedforPoolShares(
|
||||
poolAddress,
|
||||
amountPoolShares
|
||||
)
|
||||
setAmountOcean(oceanAmount)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const minOceanAmount =
|
||||
(Number(amountOcean) * (100 - Number(slippage))) / 100
|
||||
@ -177,19 +170,24 @@ export default function Remove({
|
||||
setAmountPercent(e.target.value)
|
||||
if (!poolTokens) return
|
||||
|
||||
const amountPoolShares = (Number(e.target.value) / 100) * Number(poolTokens)
|
||||
const amountPoolShares = new Decimal(e.target.value)
|
||||
.dividedBy(100)
|
||||
.mul(new Decimal(poolTokens))
|
||||
.toPrecision(18) // in some cases the returned value contain more than 18 digits which break conversion to wei
|
||||
|
||||
setAmountPoolShares(`${amountPoolShares}`)
|
||||
calculateAmountOfOceansRemoved(`${amountPoolShares}`)
|
||||
}
|
||||
|
||||
function handleMaxButton(e: ChangeEvent<HTMLInputElement>) {
|
||||
e.preventDefault()
|
||||
setAmountPercent(amountMaxPercent)
|
||||
|
||||
const amountPoolShares =
|
||||
(Number(amountMaxPercent) / 100) * Number(poolTokens)
|
||||
const amountPoolShares = new Decimal(amountMaxPercent)
|
||||
.dividedBy(100)
|
||||
.mul(new Decimal(poolTokens))
|
||||
.toPrecision(18)
|
||||
|
||||
setAmountPoolShares(`${amountPoolShares}`)
|
||||
calculateAmountOfOceansRemoved(`${amountPoolShares}`)
|
||||
}
|
||||
|
||||
function handleAdvancedButton(e: FormEvent<HTMLButtonElement>) {
|
||||
|
@ -44,6 +44,7 @@ const poolLiquidityQuery = gql`
|
||||
id
|
||||
totalShares
|
||||
swapFee
|
||||
spotPrice
|
||||
tokens {
|
||||
tokenAddress
|
||||
balance
|
||||
@ -141,7 +142,8 @@ export default function Pool(): ReactElement {
|
||||
setCreatorLiquidity(creatorLiquidity)
|
||||
|
||||
const totalCreatorLiquidityInOcean =
|
||||
creatorLiquidity?.ocean + creatorLiquidity?.datatoken * price?.value
|
||||
creatorLiquidity?.ocean +
|
||||
creatorLiquidity?.datatoken * dataLiquidity.pool.spotPrice
|
||||
setCreatorTotalLiquidityInOcean(totalCreatorLiquidityInOcean)
|
||||
const creatorPoolShare =
|
||||
price?.ocean &&
|
||||
@ -250,7 +252,7 @@ export default function Pool(): ReactElement {
|
||||
<ExplorerLink
|
||||
networkId={networkId}
|
||||
path={
|
||||
networkId === 137
|
||||
networkId === 137 || networkId === 1287
|
||||
? `tokens/${ddo.dataToken}`
|
||||
: `token/${ddo.dataToken}`
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
.bookmark {
|
||||
position: absolute;
|
||||
top: -10px;
|
||||
right: calc(var(--spacer) / 4);
|
||||
right: calc(var(--spacer) / 8);
|
||||
appearance: none;
|
||||
background: none;
|
||||
border: none;
|
||||
|
@ -4,12 +4,30 @@
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
|
||||
.meta p {
|
||||
margin-bottom: 0;
|
||||
.asset {
|
||||
margin-left: -2rem;
|
||||
margin-right: -2rem;
|
||||
padding-left: 2rem;
|
||||
padding-right: 3rem;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
margin-bottom: calc(var(--spacer) / 1.5);
|
||||
padding-bottom: calc(var(--spacer) / 1.75);
|
||||
}
|
||||
|
||||
.published {
|
||||
margin-top: calc(var(--spacer) / 2);
|
||||
@media (min-width: 40rem) {
|
||||
.asset {
|
||||
margin-top: -0.65rem;
|
||||
}
|
||||
}
|
||||
|
||||
.assetType {
|
||||
display: inline-block;
|
||||
border-right: 1px solid var(--border-color);
|
||||
padding-right: calc(var(--spacer) / 3.5);
|
||||
margin-right: calc(var(--spacer) / 4);
|
||||
}
|
||||
|
||||
.byline {
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
|
||||
|
@ -15,21 +15,25 @@ export default function MetaMain(): ReactElement {
|
||||
|
||||
return (
|
||||
<aside className={styles.meta}>
|
||||
<AssetType type={type} accessType={accessType} />
|
||||
<p>
|
||||
<header className={styles.asset}>
|
||||
<AssetType
|
||||
type={type}
|
||||
accessType={accessType}
|
||||
className={styles.assetType}
|
||||
/>
|
||||
<ExplorerLink
|
||||
networkId={networkId}
|
||||
path={
|
||||
networkId === 137
|
||||
networkId === 137 || networkId === 1287
|
||||
? `tokens/${ddo?.dataToken}`
|
||||
: `token/${ddo?.dataToken}`
|
||||
}
|
||||
>
|
||||
{`${ddo?.dataTokenInfo.name} — ${ddo?.dataTokenInfo.symbol}`}
|
||||
</ExplorerLink>
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div className={styles.published}>
|
||||
<div className={styles.byline}>
|
||||
Published By <Publisher account={owner} />
|
||||
<p>
|
||||
<Time date={ddo?.created} relative />
|
||||
|
@ -48,14 +48,16 @@ export default function AssetContent(props: AssetContentProps): ReactElement {
|
||||
const [showPricing, setShowPricing] = useState(false)
|
||||
const [showEdit, setShowEdit] = useState<boolean>()
|
||||
const [showEditCompute, setShowEditCompute] = useState<boolean>()
|
||||
const { ddo, price, metadata } = useAsset()
|
||||
|
||||
const isOwner = accountId === owner
|
||||
const [isOwner, setIsOwner] = useState(false)
|
||||
const { ddo, price, metadata, type } = useAsset()
|
||||
|
||||
useEffect(() => {
|
||||
if (!price) return
|
||||
if (!accountId || !owner) return
|
||||
|
||||
const isOwner = accountId.toLowerCase() === owner.toLowerCase()
|
||||
setIsOwner(isOwner)
|
||||
setShowPricing(isOwner && price.type === '')
|
||||
}, [isOwner, price])
|
||||
}, [accountId, price, owner])
|
||||
|
||||
function handleEditButton() {
|
||||
// move user's focus to top of screen
|
||||
@ -101,7 +103,7 @@ export default function AssetContent(props: AssetContentProps): ReactElement {
|
||||
<Button style="text" size="small" onClick={handleEditButton}>
|
||||
Edit Metadata
|
||||
</Button>
|
||||
{ddo.findServiceByType('compute') && (
|
||||
{ddo.findServiceByType('compute') && type === 'dataset' && (
|
||||
<>
|
||||
<span className={styles.separator}>|</span>
|
||||
<Button
|
||||
|
@ -2,3 +2,7 @@
|
||||
composes: asset from './Details.module.css';
|
||||
border-bottom-left-radius: var(--border-radius) !important;
|
||||
}
|
||||
|
||||
.help {
|
||||
margin-top: calc(var(--spacer) / 3);
|
||||
}
|
||||
|
@ -6,12 +6,33 @@ import { ListItem } from '../../../atoms/Lists'
|
||||
import Button from '../../../atoms/Button'
|
||||
import { useOcean } from '../../../../providers/Ocean'
|
||||
import styles from './Results.module.css'
|
||||
import FormHelp from '../../../atoms/Input/Help'
|
||||
import { graphql, useStaticQuery } from 'gatsby'
|
||||
|
||||
export const contentQuery = graphql`
|
||||
query HistoryPageComputeResultsQuery {
|
||||
content: allFile(filter: { relativePath: { eq: "pages/history.json" } }) {
|
||||
edges {
|
||||
node {
|
||||
childPagesJson {
|
||||
compute {
|
||||
storage
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export default function Results({
|
||||
job
|
||||
}: {
|
||||
job: ComputeJobMetaData
|
||||
}): ReactElement {
|
||||
const data = useStaticQuery(contentQuery)
|
||||
const content = data.content.edges[0].node.childPagesJson
|
||||
|
||||
const { ocean, account } = useOcean()
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [hasFetched, setHasFetched] = useState(false)
|
||||
@ -85,6 +106,7 @@ export default function Results({
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
<FormHelp className={styles.help}>{content.compute.storage}</FormHelp>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -62,12 +62,11 @@ export default function FormPublish(): ReactElement {
|
||||
const [selectedDockerImage, setSelectedDockerImage] = useState<string>(
|
||||
initialValues.dockerImage
|
||||
)
|
||||
|
||||
// reset form validation on every mount
|
||||
useEffect(() => {
|
||||
setErrors({})
|
||||
setTouched({})
|
||||
|
||||
// setSubmitting(false)
|
||||
}, [setErrors, setTouched])
|
||||
|
||||
function handleImageSelectChange(imageSelected: string) {
|
||||
|
@ -67,8 +67,11 @@ export default function FormPublish(): ReactElement {
|
||||
e: ChangeEvent<HTMLInputElement>,
|
||||
field: FormFieldProps
|
||||
) {
|
||||
const value =
|
||||
field.type === 'terms' ? !JSON.parse(e.target.value) : e.target.value
|
||||
|
||||
validateField(field.name)
|
||||
setFieldValue(field.name, e.target.value)
|
||||
setFieldValue(field.name, value)
|
||||
}
|
||||
|
||||
const resetFormAndClearStorage = (e: FormEvent<Element>) => {
|
||||
|
@ -95,9 +95,22 @@ export default function PublishPage({
|
||||
const [publishType, setPublishType] = useState<MetadataMain['type']>(
|
||||
'dataset'
|
||||
)
|
||||
|
||||
const hasFeedback = isLoading || error || success
|
||||
|
||||
const emptyAlgoDT = Object.values(algoInitialValues.dataTokenOptions).every(
|
||||
(value) => value === ''
|
||||
)
|
||||
const emptyDatasetDT = Object.values(
|
||||
datasetInitialValues.dataTokenOptions
|
||||
).every((value) => value === '')
|
||||
|
||||
if (emptyAlgoDT) {
|
||||
algoInitialValues.dataTokenOptions = datasetInitialValues.dataTokenOptions
|
||||
} else {
|
||||
if (emptyDatasetDT)
|
||||
datasetInitialValues.dataTokenOptions = algoInitialValues.dataTokenOptions
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
publishType === 'dataset'
|
||||
? setTitle('Publishing Data Set')
|
||||
@ -160,18 +173,22 @@ export default function PublishPage({
|
||||
): Promise<void> {
|
||||
const metadata = transformPublishAlgorithmFormToMetadata(values)
|
||||
const timeout = mapTimeoutStringToSeconds(values.timeout)
|
||||
const validDockerImage =
|
||||
values.dockerImage === 'custom image'
|
||||
? await validateDockerImage(values.image, values.containerTag)
|
||||
: true
|
||||
|
||||
// TODO: put back check once #572 is resolved
|
||||
// https://github.com/oceanprotocol/market/issues/572
|
||||
const validDockerImage = true
|
||||
// const validDockerImage =
|
||||
// values.dockerImage === 'custom image'
|
||||
// ? await validateDockerImage(values.image, values.containerTag)
|
||||
// : true
|
||||
try {
|
||||
if (validDockerImage) {
|
||||
Logger.log('Publish Algorithm with ', metadata)
|
||||
Logger.log('Publish algorithm with ', metadata, values.dataTokenOptions)
|
||||
|
||||
const ddo = await publish(
|
||||
(metadata as unknown) as Metadata,
|
||||
values.algorithmPrivacy === true ? 'compute' : 'access',
|
||||
undefined,
|
||||
values.dataTokenOptions,
|
||||
timeout
|
||||
)
|
||||
|
||||
@ -248,7 +265,9 @@ export default function PublishPage({
|
||||
loading={publishStepText}
|
||||
setError={setError}
|
||||
successAction={{
|
||||
name: 'Go to data set →',
|
||||
name: `Go to ${
|
||||
publishType === 'dataset' ? 'data set' : 'algorithm'
|
||||
} →`,
|
||||
to: `/asset/${did}`
|
||||
}}
|
||||
/>
|
||||
|
@ -1,160 +0,0 @@
|
||||
import { useState } from 'react'
|
||||
import { Logger, ServiceCompute } from '@oceanprotocol/lib'
|
||||
import { MetadataAlgorithm } from '@oceanprotocol/lib/dist/node/ddo/interfaces/MetadataAlgorithm'
|
||||
import {
|
||||
ComputeJob,
|
||||
ComputeAlgorithm
|
||||
} from '@oceanprotocol/lib/dist/node/ocean/interfaces/Compute'
|
||||
import { computeFeedback } from '../utils/feedback'
|
||||
import { useOcean } from '../providers/Ocean'
|
||||
import { useWeb3 } from '../providers/Web3'
|
||||
|
||||
interface ComputeValue {
|
||||
entrypoint: string
|
||||
image: string
|
||||
tag: string
|
||||
}
|
||||
interface ComputeOption {
|
||||
name: string
|
||||
value: ComputeValue
|
||||
}
|
||||
|
||||
const computeOptions: ComputeOption[] = [
|
||||
{
|
||||
name: 'nodejs',
|
||||
value: {
|
||||
entrypoint: 'node $ALGO',
|
||||
image: 'node',
|
||||
tag: '10'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'python3.7',
|
||||
value: {
|
||||
entrypoint: 'python $ALGO',
|
||||
image: 'oceanprotocol/algo_dockers',
|
||||
tag: 'python-panda'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
interface UseCompute {
|
||||
compute: (
|
||||
did: string,
|
||||
computeService: ServiceCompute,
|
||||
dataTokenAddress: string,
|
||||
algorithmRawCode: string,
|
||||
computeContainer: ComputeValue,
|
||||
marketFeeAddress?: string,
|
||||
orderId?: string
|
||||
) => Promise<ComputeJob | void>
|
||||
computeStep?: number
|
||||
computeStepText?: string
|
||||
computeError?: string
|
||||
isLoading: boolean
|
||||
}
|
||||
|
||||
const rawAlgorithmMeta: MetadataAlgorithm = {
|
||||
rawcode: `console.log('Hello world'!)`,
|
||||
format: 'docker-image',
|
||||
version: '0.1',
|
||||
container: {
|
||||
entrypoint: '',
|
||||
image: '',
|
||||
tag: ''
|
||||
}
|
||||
}
|
||||
|
||||
function useCompute(): UseCompute {
|
||||
const { accountId } = useWeb3()
|
||||
const { ocean, account } = useOcean()
|
||||
const [computeStep, setComputeStep] = useState<number | undefined>()
|
||||
const [computeStepText, setComputeStepText] = useState<string | undefined>()
|
||||
const [computeError, setComputeError] = useState<string | undefined>()
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
|
||||
function setStep(index?: number) {
|
||||
if (!index) {
|
||||
setComputeStep(undefined)
|
||||
setComputeStepText(undefined)
|
||||
return
|
||||
}
|
||||
|
||||
setComputeStep(index)
|
||||
setComputeStepText(computeFeedback[index])
|
||||
}
|
||||
|
||||
async function compute(
|
||||
did: string,
|
||||
computeService: ServiceCompute,
|
||||
dataTokenAddress: string,
|
||||
algorithmRawCode: string,
|
||||
computeContainer: ComputeValue,
|
||||
marketFeeAddress?: string,
|
||||
orderId?: string
|
||||
): Promise<ComputeJob | void> {
|
||||
if (!ocean || !account) return
|
||||
setComputeError(undefined)
|
||||
try {
|
||||
setIsLoading(true)
|
||||
setStep(0)
|
||||
rawAlgorithmMeta.container = computeContainer
|
||||
rawAlgorithmMeta.rawcode = algorithmRawCode
|
||||
const computeAlgorithm: ComputeAlgorithm = {
|
||||
meta: rawAlgorithmMeta
|
||||
}
|
||||
const output = {}
|
||||
if (!orderId) {
|
||||
const userOwnedTokens = await ocean.accounts.getTokenBalance(
|
||||
dataTokenAddress,
|
||||
account
|
||||
)
|
||||
if (parseFloat(userOwnedTokens) < 1) {
|
||||
setComputeError('Not enough datatokens')
|
||||
} else {
|
||||
Logger.log(
|
||||
'compute order',
|
||||
accountId,
|
||||
did,
|
||||
computeService,
|
||||
rawAlgorithmMeta,
|
||||
marketFeeAddress
|
||||
)
|
||||
orderId = await ocean.compute.orderAsset(
|
||||
accountId,
|
||||
did,
|
||||
computeService.index,
|
||||
computeAlgorithm,
|
||||
marketFeeAddress
|
||||
)
|
||||
setStep(1)
|
||||
}
|
||||
}
|
||||
setStep(2)
|
||||
if (orderId) {
|
||||
const response = await ocean.compute.start(
|
||||
did,
|
||||
orderId,
|
||||
dataTokenAddress,
|
||||
account,
|
||||
computeAlgorithm,
|
||||
output,
|
||||
`${computeService.index}`,
|
||||
computeService.type
|
||||
)
|
||||
return response
|
||||
}
|
||||
} catch (error) {
|
||||
Logger.error(error)
|
||||
setComputeError(error.message)
|
||||
} finally {
|
||||
setStep(undefined)
|
||||
setIsLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
return { compute, computeStep, computeStepText, computeError, isLoading }
|
||||
}
|
||||
|
||||
export { useCompute, UseCompute, ComputeValue, ComputeOption, computeOptions }
|
||||
export default UseCompute
|
@ -77,6 +77,7 @@ export function useGraphSyncStatus(): UseGraphSyncStatus {
|
||||
// Get and set subgraph block
|
||||
useEffect(() => {
|
||||
if (!config || !config.subgraphUri) return
|
||||
|
||||
async function initBlockSubgraph() {
|
||||
setSubgraphLoading(true)
|
||||
const blockGraph = await getBlockSubgraph(config.subgraphUri)
|
||||
@ -98,7 +99,7 @@ export function useGraphSyncStatus(): UseGraphSyncStatus {
|
||||
return
|
||||
}
|
||||
setIsGraphSynced(true)
|
||||
}, [blockGraph, blockHead])
|
||||
}, [blockGraph, blockHead, web3Loading, subgraphLoading])
|
||||
|
||||
return { blockHead, blockGraph, isGraphSynced }
|
||||
}
|
||||
|
@ -82,36 +82,7 @@ function usePublish(): UsePublish {
|
||||
}
|
||||
case 'compute': {
|
||||
if (!timeout) timeout = 3600
|
||||
const cluster = ocean.compute.createClusterAttributes(
|
||||
'Kubernetes',
|
||||
'http://10.0.0.17/xxx'
|
||||
)
|
||||
const servers = [
|
||||
ocean.compute.createServerAttributes(
|
||||
'1',
|
||||
'xlsize',
|
||||
'50',
|
||||
'16',
|
||||
'0',
|
||||
'128gb',
|
||||
'160gb',
|
||||
timeout
|
||||
)
|
||||
]
|
||||
const containers = [
|
||||
ocean.compute.createContainerAttributes(
|
||||
'tensorflow/tensorflow',
|
||||
'latest',
|
||||
'sha256:cb57ecfa6ebbefd8ffc7f75c0f00e57a7fa739578a429b6f72a0df19315deadc'
|
||||
)
|
||||
]
|
||||
const provider = ocean.compute.createProviderAttributes(
|
||||
'Azure',
|
||||
'Compute service with 16gb ram for each node.',
|
||||
cluster,
|
||||
containers,
|
||||
servers
|
||||
)
|
||||
const provider = {}
|
||||
const origComputePrivacy: ServiceComputePrivacy = {
|
||||
allowRawAlgorithm: false,
|
||||
allowNetworkAccess: false,
|
||||
|
@ -11,6 +11,12 @@ export const validationSchema: Yup.SchemaOf<MetadataPublishFormAlgorithm> = Yup.
|
||||
description: Yup.string().min(10).required('Required'),
|
||||
files: Yup.array<FileMetadata>().required('Required').nullable(),
|
||||
timeout: Yup.string().required('Required'),
|
||||
dataTokenOptions: Yup.object()
|
||||
.shape({
|
||||
name: Yup.string(),
|
||||
symbol: Yup.string()
|
||||
})
|
||||
.required('Required'),
|
||||
dockerImage: Yup.string()
|
||||
.matches(/node:latest|python:latest|custom image/g, {
|
||||
excludeEmptyString: true
|
||||
@ -31,6 +37,10 @@ export const validationSchema: Yup.SchemaOf<MetadataPublishFormAlgorithm> = Yup.
|
||||
export const initialValues: Partial<MetadataPublishFormAlgorithm> = {
|
||||
name: '',
|
||||
author: '',
|
||||
dataTokenOptions: {
|
||||
name: '',
|
||||
symbol: ''
|
||||
},
|
||||
dockerImage: 'node:latest',
|
||||
image: 'node',
|
||||
containerTag: 'latest',
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { MetadataMarket, MetadataPublishFormDataset } from '../@types/MetaData'
|
||||
import { MetadataMarket, MetadataEditForm } from '../@types/MetaData'
|
||||
import { secondsToString } from '../utils/metadata'
|
||||
import { EditableMetadataLinks } from '@oceanprotocol/lib'
|
||||
import * as Yup from 'yup'
|
||||
@ -8,17 +8,20 @@ export const validationSchema = Yup.object().shape({
|
||||
.min(4, (param) => `Title must be at least ${param.min} characters`)
|
||||
.required('Required'),
|
||||
description: Yup.string().required('Required').min(10),
|
||||
price: Yup.number().required('Required'),
|
||||
links: Yup.array<EditableMetadataLinks[]>().nullable(),
|
||||
timeout: Yup.string().required('Required')
|
||||
})
|
||||
|
||||
export function getInitialValues(
|
||||
metadata: MetadataMarket,
|
||||
timeout: number
|
||||
): Partial<MetadataPublishFormDataset> {
|
||||
timeout: number,
|
||||
price: number
|
||||
): Partial<MetadataEditForm> {
|
||||
return {
|
||||
name: metadata.main.name,
|
||||
description: metadata.additionalInformation.description,
|
||||
price,
|
||||
links: metadata.additionalInformation.links,
|
||||
timeout: secondsToString(timeout)
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ export default function PageGatsbySearch(props: PageProps): ReactElement {
|
||||
? `Published by ${accountTruncate(owner as string)}`
|
||||
: `${
|
||||
totalResults !== undefined
|
||||
? searchValue
|
||||
? searchValue && searchValue !== ' '
|
||||
? totalResults === 0
|
||||
? 'No results'
|
||||
: totalResults +
|
||||
|
@ -16,7 +16,10 @@ export function getOceanConfig(
|
||||
): ConfigHelperConfig {
|
||||
return new ConfigHelper().getConfig(
|
||||
network,
|
||||
network === 'polygon' || network === 137
|
||||
network === 'polygon' ||
|
||||
network === 137 ||
|
||||
network === 'moonbeamalpha' ||
|
||||
network === 1287
|
||||
? undefined
|
||||
: process.env.GATSBY_INFURA_PROJECT_ID
|
||||
) as ConfigHelperConfig
|
||||
|
@ -35,7 +35,7 @@ export async function fileinfo(
|
||||
return
|
||||
} else {
|
||||
toast.dismiss() // Remove any existing error message
|
||||
toast.success('Great! That dataset looks good 🐳', {
|
||||
toast.success('Great! That file looks good. 🐳', {
|
||||
position: 'bottom-right',
|
||||
autoClose: 5000,
|
||||
hideProgressBar: false,
|
||||
|
Loading…
Reference in New Issue
Block a user