mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
add in all conditional fields
* switch between dataset & algorithm fields * switch between algo privacy & access type fields * switch between docker image & custom docker image fields
This commit is contained in:
parent
5285efd9c0
commit
e79dcf2342
@ -1,111 +0,0 @@
|
||||
{
|
||||
"title": "Publish an Algorithm",
|
||||
"data": [
|
||||
{
|
||||
"name": "name",
|
||||
"label": "Title",
|
||||
"placeholder": "e.g. Shapes of Desert Plants",
|
||||
"help": "Enter a concise title.",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"label": "Description",
|
||||
"help": "Add a thorough description with as much detail as possible. You can use [Markdown](https://daringfireball.net/projects/markdown/basics). You can change the description at any time. If you provide personal data, please note that it will remain in the transaction history. For more information on how personal data is handled within the metadata, please refer to our [privacy policy](/privacy/en).",
|
||||
"type": "textarea",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"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. 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
|
||||
},
|
||||
{
|
||||
"name": "dockerImage",
|
||||
"label": "Docker Image",
|
||||
"placeholder": "e.g. python3.7",
|
||||
"help": "Please select an image to run your algorithm.",
|
||||
"type": "boxSelection",
|
||||
"options": [],
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "image",
|
||||
"label": "Image URL",
|
||||
"placeholder": "e.g. oceanprotocol/algo_dockers or https://example.com/image_path",
|
||||
"help": "Provide the name of a public Docker image or the full url if you have it hosted in a 3rd party repo",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "containerTag",
|
||||
"label": "Docker Image Tag",
|
||||
"placeholder": "e.g. latest",
|
||||
"help": "Provide the tag for your Docker image.",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "timeout",
|
||||
"label": "Timeout",
|
||||
"help": "Define how long buyers should be able to download the algorithm again after the initial purchase.",
|
||||
"placeholder": "Forever",
|
||||
"type": "select",
|
||||
"options": ["Forever", "1 day", "1 week", "1 month", "1 year"],
|
||||
"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",
|
||||
"placeholder": "e.g. python $ALGO",
|
||||
"help": "Provide the entrypoint for your algorithm.",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "algorithmPrivacy",
|
||||
"label": "Algorithm Privacy",
|
||||
"type": "checkbox",
|
||||
"options": ["Keep my algorithm private"],
|
||||
"help": "By default, your algorithm can be downloaded for a fixed or dynamic price in addition to running in compute jobs. Enabling this option will prevent downloading, so your algorithm can only be run as part of a compute job on a data set.",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "author",
|
||||
"label": "Author",
|
||||
"placeholder": "e.g. Jelly McJellyfish",
|
||||
"help": "Give proper attribution for your data set. You are welcome to use a pseudonym, and you can change your author name at any time. Please note that it will remain in the transaction history. For more information on how personal data is handled within the metadata, please refer to our [privacy policy](/privacy/en).",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "tags",
|
||||
"label": "Tags",
|
||||
"placeholder": "e.g. logistics, ai",
|
||||
"help": "Separate tags with comma."
|
||||
},
|
||||
{
|
||||
"name": "providerUri",
|
||||
"label": "Custom Provider URL",
|
||||
"type": "providerUri",
|
||||
"help": "Enter the URL for your custom provider or leave blank to use the default provider. [Learn more](https://github.com/oceanprotocol/provider/).",
|
||||
"placeholder": "https://provider.polygon.oceanprotocol.com/",
|
||||
"advanced": true
|
||||
},
|
||||
{
|
||||
"name": "termsAndConditions",
|
||||
"label": "Terms & Conditions",
|
||||
"type": "terms",
|
||||
"options": ["I agree to these Terms and Conditions"],
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"success": "Algorithm Published!"
|
||||
}
|
@ -2,6 +2,13 @@
|
||||
"metadata": {
|
||||
"title": "Metadata",
|
||||
"fields": [
|
||||
{
|
||||
"name": "type",
|
||||
"label": "Asset Type",
|
||||
"type": "boxSelection",
|
||||
"options": ["Dataset", "Algorithm"],
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"label": "Title",
|
||||
@ -28,6 +35,35 @@
|
||||
"placeholder": "e.g. logistics, ai",
|
||||
"help": "Separate tags with comma."
|
||||
},
|
||||
{
|
||||
"name": "dockerImage",
|
||||
"label": "Docker Image",
|
||||
"help": "Please select an image to run your algorithm.",
|
||||
"type": "boxSelection",
|
||||
"options": ["node:latest", "python:latest", "Custom"],
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "dockerImageCustom",
|
||||
"label": "Docker Image URL",
|
||||
"placeholder": "e.g. oceanprotocol/algo_dockers or https://example.com/image_path",
|
||||
"help": "Provide the name of a public Docker image or the full url if you have it hosted in a 3rd party repo",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "dockerImageCustomTag",
|
||||
"label": "Docker Image Tag",
|
||||
"placeholder": "e.g. latest",
|
||||
"help": "Provide the tag for your Docker image.",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "dockerImageCustomEntrypoint",
|
||||
"label": "Docker Entrypoint",
|
||||
"placeholder": "e.g. python $ALGO",
|
||||
"help": "Provide the entrypoint for your algorithm.",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "termsAndConditions",
|
||||
"label": "Terms & Conditions",
|
||||
@ -40,13 +76,6 @@
|
||||
"services": {
|
||||
"title": "Access",
|
||||
"fields": [
|
||||
{
|
||||
"name": "type",
|
||||
"label": "Asset Type",
|
||||
"type": "boxSelection",
|
||||
"options": ["Dataset", "Algorithm"],
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "dataTokenOptions",
|
||||
"label": "Datatoken Name & Symbol",
|
||||
@ -55,11 +84,11 @@
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "dataTokenOptions",
|
||||
"label": "Datatoken Name & Symbol",
|
||||
"type": "datatoken",
|
||||
"help": "The datatoken for this data set will be created with this name & symbol.",
|
||||
"required": true
|
||||
"name": "providerUrl",
|
||||
"label": "Custom Provider URL",
|
||||
"type": "providerUrl",
|
||||
"help": "Enter the URL for your custom provider or leave blank to use the default provider. [Learn more](https://github.com/oceanprotocol/provider/).",
|
||||
"placeholder": "e.g. https://provider.polygon.oceanprotocol.com/"
|
||||
},
|
||||
{
|
||||
"name": "files",
|
||||
@ -76,6 +105,14 @@
|
||||
"help": "Please enter the URL to a sample of your data set file and click \"ADD FILE\" to validate the data. This file should reveal the data structure of your data set, e.g. by including the header and one line of a CSV file. This file URL will be publicly available after publishing.",
|
||||
"type": "files"
|
||||
},
|
||||
{
|
||||
"name": "algorithmPrivacy",
|
||||
"label": "Algorithm Privacy",
|
||||
"type": "checkbox",
|
||||
"options": ["Keep my algorithm private"],
|
||||
"help": "By default, your algorithm can be downloaded for a fixed or dynamic price in addition to running in compute jobs. Enabling this option will prevent downloading, so your algorithm can only be run as part of a compute job on a data set.",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "access",
|
||||
"label": "Access Type",
|
||||
@ -94,14 +131,6 @@
|
||||
"options": ["Forever", "1 day", "1 week", "1 month", "1 year"],
|
||||
"sortOptions": false,
|
||||
"required": true
|
||||
},
|
||||
|
||||
{
|
||||
"name": "providerUrl",
|
||||
"label": "Custom Provider URL",
|
||||
"type": "providerUrl",
|
||||
"help": "Enter the URL for your custom provider or leave blank to use the default provider. [Learn more](https://github.com/oceanprotocol/provider/).",
|
||||
"placeholder": "e.g. https://provider.polygon.oceanprotocol.com/"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
2
src/@types/DDO/Metadata.d.ts
vendored
2
src/@types/DDO/Metadata.d.ts
vendored
@ -14,7 +14,7 @@ interface Metadata {
|
||||
updated: string
|
||||
name: string
|
||||
description: string
|
||||
type: 'dataset' | 'algorithm'
|
||||
type: 'dataset' | 'algorithm' | string
|
||||
author: string
|
||||
license: string
|
||||
links?: string[]
|
||||
|
@ -7,19 +7,23 @@ import { getFieldContent } from '../_utils'
|
||||
|
||||
const assetTypeOptionsTitles = getFieldContent(
|
||||
'type',
|
||||
content.services.fields
|
||||
content.metadata.fields
|
||||
).options
|
||||
|
||||
const assetTypeOptions = [
|
||||
{
|
||||
name: assetTypeOptionsTitles[0].toLowerCase(),
|
||||
title: assetTypeOptionsTitles[0]
|
||||
},
|
||||
{
|
||||
name: assetTypeOptionsTitles[1].toLowerCase(),
|
||||
title: assetTypeOptionsTitles[1]
|
||||
}
|
||||
]
|
||||
const dockerImageOptionsTitles = getFieldContent(
|
||||
'dockerImage',
|
||||
content.metadata.fields
|
||||
).options
|
||||
|
||||
const assetTypeOptions = assetTypeOptionsTitles.map((title) => ({
|
||||
name: title.toLowerCase(),
|
||||
title
|
||||
}))
|
||||
|
||||
const dockerImageOptions = dockerImageOptionsTitles.map((title) => ({
|
||||
name: title.toLowerCase(),
|
||||
title
|
||||
}))
|
||||
|
||||
export default function MetadataFields(): ReactElement {
|
||||
// connect with Form state, use for conditional field rendering
|
||||
@ -28,9 +32,9 @@ export default function MetadataFields(): ReactElement {
|
||||
return (
|
||||
<>
|
||||
<Field
|
||||
{...getFieldContent('type', content.services.fields)}
|
||||
{...getFieldContent('type', content.metadata.fields)}
|
||||
component={Input}
|
||||
name="type"
|
||||
name="metadata.type"
|
||||
options={assetTypeOptions}
|
||||
/>
|
||||
<Field
|
||||
@ -54,6 +58,45 @@ export default function MetadataFields(): ReactElement {
|
||||
name="metadata.tags"
|
||||
/>
|
||||
|
||||
{values.metadata.type === 'algorithm' && (
|
||||
<>
|
||||
<Field
|
||||
{...getFieldContent('dockerImage', content.metadata.fields)}
|
||||
component={Input}
|
||||
name="metadata.dockerImage"
|
||||
options={dockerImageOptions}
|
||||
/>
|
||||
{values.metadata.dockerImage === 'custom' && (
|
||||
<>
|
||||
<Field
|
||||
{...getFieldContent(
|
||||
'dockerImageCustom',
|
||||
content.metadata.fields
|
||||
)}
|
||||
component={Input}
|
||||
name="metadata.dockerImageCustom"
|
||||
/>
|
||||
<Field
|
||||
{...getFieldContent(
|
||||
'dockerImageCustomTag',
|
||||
content.metadata.fields
|
||||
)}
|
||||
component={Input}
|
||||
name="metadata.dockerImageCustomTag"
|
||||
/>
|
||||
<Field
|
||||
{...getFieldContent(
|
||||
'dockerImageCustomEntrypoint',
|
||||
content.metadata.fields
|
||||
)}
|
||||
component={Input}
|
||||
name="metadata.dockerImageCustomEntrypoint"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<strong>Fancy NFT display</strong>
|
||||
<p>
|
||||
@ -68,15 +111,6 @@ export default function MetadataFields(): ReactElement {
|
||||
component={Input}
|
||||
name="metadata.termsAndConditions"
|
||||
/>
|
||||
|
||||
{/* {content.metadata.fields.map((field: FormFieldContent) => (
|
||||
<Field
|
||||
{...field}
|
||||
key={`metadata-${field.name}`}
|
||||
component={Input}
|
||||
name={`metadata.${field.name}`}
|
||||
/>
|
||||
))} */}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Input from '@shared/Form/Input'
|
||||
import { Field, useFormikContext } from 'formik'
|
||||
import React, { ReactElement } from 'react'
|
||||
import React, { ReactElement, useEffect } from 'react'
|
||||
import IconDownload from '@images/download.svg'
|
||||
import IconCompute from '@images/compute.svg'
|
||||
import content from '../../../../content/publish/form.json'
|
||||
@ -27,10 +27,33 @@ const accessTypeOptions = [
|
||||
|
||||
export default function ServicesFields(): ReactElement {
|
||||
// connect with Form state, use for conditional field rendering
|
||||
const { values } = useFormikContext<FormPublishData>()
|
||||
const { values, setFieldValue } = useFormikContext<FormPublishData>()
|
||||
|
||||
// Auto-change access type based on algo privacy boolean.
|
||||
// Could be also done later in transformPublishFormToDdo().
|
||||
useEffect(() => {
|
||||
setFieldValue(
|
||||
'services[0].access',
|
||||
values.services[0].algorithmPrivacy === true ? 'compute' : 'download'
|
||||
)
|
||||
}, [values.services[0].algorithmPrivacy])
|
||||
|
||||
return (
|
||||
<>
|
||||
{values.metadata.type === 'algorithm' ? (
|
||||
<Field
|
||||
{...getFieldContent('algorithmPrivacy', content.services.fields)}
|
||||
component={Input}
|
||||
name="services[0].algorithmPrivacy"
|
||||
/>
|
||||
) : (
|
||||
<Field
|
||||
{...getFieldContent('access', content.services.fields)}
|
||||
component={Input}
|
||||
name="services[0].access"
|
||||
options={accessTypeOptions}
|
||||
/>
|
||||
)}
|
||||
<Field
|
||||
{...getFieldContent('dataTokenOptions', content.services.fields)}
|
||||
component={Input}
|
||||
@ -51,32 +74,11 @@ export default function ServicesFields(): ReactElement {
|
||||
component={Input}
|
||||
name="services[0].links"
|
||||
/>
|
||||
<Field
|
||||
{...getFieldContent('access', content.services.fields)}
|
||||
component={Input}
|
||||
name="services[0].access"
|
||||
options={accessTypeOptions}
|
||||
/>
|
||||
<Field
|
||||
{...getFieldContent('timeout', content.services.fields)}
|
||||
component={Input}
|
||||
name="services[0].timeout"
|
||||
/>
|
||||
|
||||
{/* {content.services.fields.map(
|
||||
(field: FormFieldContent) =>
|
||||
field.advanced !== true && (
|
||||
<Field
|
||||
{...field}
|
||||
key={`services-${field.name}`}
|
||||
component={Input}
|
||||
name={`services[0].${field.name}`}
|
||||
options={
|
||||
field.name === 'access' ? accessTypeOptions : field.options
|
||||
}
|
||||
/>
|
||||
)
|
||||
)} */}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -36,13 +36,17 @@ export const initialValues: FormPublishData = {
|
||||
chainId: 1,
|
||||
accountId: '',
|
||||
metadata: {
|
||||
type: 'dataset',
|
||||
type: '',
|
||||
name: '',
|
||||
author: '',
|
||||
description: '',
|
||||
tags: '',
|
||||
links: [],
|
||||
termsAndConditions: false
|
||||
termsAndConditions: false,
|
||||
dockerImage: '',
|
||||
dockerImageCustom: '',
|
||||
dockerImageCustomTag: '',
|
||||
dockerImageCustomEntrypoint: ''
|
||||
},
|
||||
services: [
|
||||
{
|
||||
|
@ -6,10 +6,8 @@ export interface FormPublishService {
|
||||
timeout: string
|
||||
dataTokenOptions: DataTokenOptions
|
||||
access: 'Download' | 'Compute' | string
|
||||
image?: string
|
||||
containerTag?: string
|
||||
entrypoint?: string
|
||||
providerUrl?: string
|
||||
algorithmPrivacy?: boolean
|
||||
}
|
||||
|
||||
export interface FormPublishData {
|
||||
@ -17,13 +15,17 @@ export interface FormPublishData {
|
||||
accountId: string
|
||||
chainId: number
|
||||
metadata: {
|
||||
type: 'dataset' | 'algorithm'
|
||||
type: 'Dataset' | 'Algorithm' | string
|
||||
name: string
|
||||
description: string
|
||||
author: string
|
||||
termsAndConditions: boolean
|
||||
tags?: string
|
||||
links?: string[]
|
||||
dockerImage?: string
|
||||
dockerImageCustom?: string
|
||||
dockerImageCustomTag?: string
|
||||
dockerImageCustomEntrypoint?: string
|
||||
}
|
||||
services: FormPublishService[]
|
||||
pricing: PriceOptions
|
||||
|
@ -55,17 +55,19 @@ export async function transformPublishFormToDdo(
|
||||
const { chainId, accountId, metadata, services } = values
|
||||
const did = sha256(`${nftAddress}${chainId}`)
|
||||
const currentTime = dateToStringNoMS(new Date())
|
||||
const { type, name, description, tags, links, author, termsAndConditions } =
|
||||
metadata
|
||||
const {
|
||||
access,
|
||||
files,
|
||||
image,
|
||||
containerTag,
|
||||
entrypoint,
|
||||
providerUrl,
|
||||
timeout
|
||||
} = services[0]
|
||||
type,
|
||||
name,
|
||||
description,
|
||||
tags,
|
||||
links,
|
||||
author,
|
||||
termsAndConditions,
|
||||
dockerImageCustom,
|
||||
dockerImageCustomTag,
|
||||
dockerImageCustomEntrypoint
|
||||
} = metadata
|
||||
const { access, files, providerUrl, timeout } = services[0]
|
||||
|
||||
const filesEncrypted = await getEncryptedFileUrls(
|
||||
files as string[],
|
||||
@ -92,9 +94,9 @@ export async function transformPublishFormToDdo(
|
||||
language: getUrlFileExtension(files[0]),
|
||||
version: '0.1',
|
||||
container: {
|
||||
entrypoint,
|
||||
image,
|
||||
tag: containerTag,
|
||||
entrypoint: dockerImageCustomEntrypoint,
|
||||
image: dockerImageCustom,
|
||||
tag: dockerImageCustomTag,
|
||||
checksum: '' // how to get? Is it user input?
|
||||
}
|
||||
}
|
||||
@ -109,7 +111,7 @@ export async function transformPublishFormToDdo(
|
||||
timeout,
|
||||
...(access === 'compute' && {
|
||||
compute: {
|
||||
namespace: '',
|
||||
namespace: 'ocean-compute',
|
||||
cpu: 1,
|
||||
gpu: 1,
|
||||
gpuType: '',
|
||||
|
Loading…
Reference in New Issue
Block a user