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:
Matthias Kretschmann 2021-11-15 12:44:27 +00:00
parent 5285efd9c0
commit e79dcf2342
Signed by: m
GPG Key ID: 606EEEF3C479A91F
8 changed files with 159 additions and 197 deletions

View File

@ -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!"
}

View File

@ -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/"
}
]
},

View File

@ -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[]

View File

@ -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}`}
/>
))} */}
</>
)
}

View File

@ -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
}
/>
)
)} */}
</>
)
}

View File

@ -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: [
{

View File

@ -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

View File

@ -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: '',