mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
WIP publish algorithm
This commit is contained in:
parent
e4a826cc7e
commit
18cd6b6f01
62
content/pages/publishAlgo.json
Normal file
62
content/pages/publishAlgo.json
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"title": "Publish",
|
||||||
|
"description": "Highlight the important features of your algorith to make it more discoverable and catch the interest of data consumers.",
|
||||||
|
"warning": "Given the beta status, publishing on Ropsten or Rinkeby first is strongly recommended. Please familiarize yourself with [the market](https://oceanprotocol.com/technology/marketplaces), [the risks](https://blog.oceanprotocol.com/on-staking-on-data-in-ocean-market-3d8e09eb0a13), and the [Terms of Use](/terms).",
|
||||||
|
"form": {
|
||||||
|
"title": "Publish",
|
||||||
|
"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).",
|
||||||
|
"type": "textarea",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "files",
|
||||||
|
"label": "File",
|
||||||
|
"placeholder": "e.g. https://file.com/file.json",
|
||||||
|
"help": "Please provide a URL to your algorith file. This URL will be stored encrypted after publishing.",
|
||||||
|
"type": "files",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dockerImage",
|
||||||
|
"label": "Docker Image",
|
||||||
|
"placeholder": "e.g. python3.7",
|
||||||
|
"help": "Please select a predefined image to run your algorithm.",
|
||||||
|
"type": "select",
|
||||||
|
"options": ["NodeJS", "Python 3.7"],
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "author",
|
||||||
|
"label": "Author",
|
||||||
|
"placeholder": "e.g. Jelly McJellyfish",
|
||||||
|
"help": "Give proper attribution for your algorith.",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "tags",
|
||||||
|
"label": "Tags",
|
||||||
|
"placeholder": "e.g. logistics, ai",
|
||||||
|
"help": "Separate tags with comma."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "termsAndConditions",
|
||||||
|
"label": "Terms & Conditions",
|
||||||
|
"type": "terms",
|
||||||
|
"options": ["I agree to these Terms and Conditions"],
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"success": "Algorithm Published!"
|
||||||
|
}
|
||||||
|
}
|
12
src/@types/MetaData.d.ts
vendored
12
src/@types/MetaData.d.ts
vendored
@ -39,6 +39,18 @@ export interface MetadataPublishForm {
|
|||||||
links?: string | File[]
|
links?: string | File[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AlgorithmPublishForm {
|
||||||
|
// ---- required fields ----
|
||||||
|
name: string
|
||||||
|
description: string
|
||||||
|
files: string | File[]
|
||||||
|
author: string
|
||||||
|
dockerImage: string
|
||||||
|
termsAndConditions: boolean
|
||||||
|
// ---- optional fields ----
|
||||||
|
tags?: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface ServiceMetadataMarket extends ServiceMetadata {
|
export interface ServiceMetadataMarket extends ServiceMetadata {
|
||||||
attributes: MetadataMarket
|
attributes: MetadataMarket
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,10 @@ import Tags from '../atoms/Tags'
|
|||||||
import MetaItem from '../organisms/AssetContent/MetaItem'
|
import MetaItem from '../organisms/AssetContent/MetaItem'
|
||||||
import styles from './MetadataPreview.module.css'
|
import styles from './MetadataPreview.module.css'
|
||||||
import File from '../atoms/File'
|
import File from '../atoms/File'
|
||||||
import { MetadataPublishForm } from '../../@types/MetaData'
|
import {
|
||||||
|
MetadataPublishForm,
|
||||||
|
AlgorithmPublishForm
|
||||||
|
} from '../../@types/MetaData'
|
||||||
import Button from '../atoms/Button'
|
import Button from '../atoms/Button'
|
||||||
import { transformTags } from '../../utils/metadata'
|
import { transformTags } from '../../utils/metadata'
|
||||||
|
|
||||||
@ -82,7 +85,7 @@ function Sample({ url }: { url: string }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function MetadataPreview({
|
export function MetadataPreview({
|
||||||
values
|
values
|
||||||
}: {
|
}: {
|
||||||
values: Partial<MetadataPublishForm>
|
values: Partial<MetadataPublishForm>
|
||||||
@ -119,3 +122,32 @@ export default function MetadataPreview({
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function MetadataAlgorithmPreview({
|
||||||
|
values
|
||||||
|
}: {
|
||||||
|
values: Partial<AlgorithmPublishForm>
|
||||||
|
}): ReactElement {
|
||||||
|
return (
|
||||||
|
<div className={styles.preview}>
|
||||||
|
<h2 className={styles.previewTitle}>Preview</h2>
|
||||||
|
<header>
|
||||||
|
{values.name && <h3 className={styles.title}>{values.name}</h3>}
|
||||||
|
{values.description && <Description description={values.description} />}
|
||||||
|
|
||||||
|
<div className={styles.asset}>
|
||||||
|
{values.files?.length > 0 && typeof values.files !== 'string' && (
|
||||||
|
<File
|
||||||
|
file={values.files[0] as FileMetadata}
|
||||||
|
className={styles.file}
|
||||||
|
small
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{values.tags && <Tags items={transformTags(values.tags)} />}
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<MetaFull values={values} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
} from '../../../../models/FormEditMetadata'
|
} from '../../../../models/FormEditMetadata'
|
||||||
import { useAsset } from '../../../../providers/Asset'
|
import { useAsset } from '../../../../providers/Asset'
|
||||||
import { useUserPreferences } from '../../../../providers/UserPreferences'
|
import { useUserPreferences } from '../../../../providers/UserPreferences'
|
||||||
import MetadataPreview from '../../../molecules/MetadataPreview'
|
import { MetadataPreview } from '../../../molecules/MetadataPreview'
|
||||||
import Debug from './Debug'
|
import Debug from './Debug'
|
||||||
import Web3Feedback from '../../../molecules/Wallet/Feedback'
|
import Web3Feedback from '../../../molecules/Wallet/Feedback'
|
||||||
import FormEditMetadata from './FormEditMetadata'
|
import FormEditMetadata from './FormEditMetadata'
|
||||||
|
86
src/components/pages/Publish/FormAlgoPublish.tsx
Normal file
86
src/components/pages/Publish/FormAlgoPublish.tsx
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import React, { ReactElement, useEffect, FormEvent, ChangeEvent } from 'react'
|
||||||
|
import styles from './FormPublish.module.css'
|
||||||
|
import { useOcean } from '@oceanprotocol/react'
|
||||||
|
import { useFormikContext, Field, Form, FormikContextType } from 'formik'
|
||||||
|
import Input from '../../atoms/Input'
|
||||||
|
import Button from '../../atoms/Button'
|
||||||
|
import { FormContent, FormFieldProps } from '../../../@types/Form'
|
||||||
|
import { AlgorithmPublishForm } from '../../../@types/MetaData'
|
||||||
|
|
||||||
|
export default function FormPublish({
|
||||||
|
content
|
||||||
|
}: {
|
||||||
|
content: FormContent
|
||||||
|
}): ReactElement {
|
||||||
|
const { ocean, account } = useOcean()
|
||||||
|
const {
|
||||||
|
status,
|
||||||
|
setStatus,
|
||||||
|
isValid,
|
||||||
|
setErrors,
|
||||||
|
setTouched,
|
||||||
|
resetForm,
|
||||||
|
initialValues,
|
||||||
|
validateField,
|
||||||
|
setFieldValue
|
||||||
|
}: FormikContextType<AlgorithmPublishForm> = useFormikContext()
|
||||||
|
|
||||||
|
// reset form validation on every mount
|
||||||
|
useEffect(() => {
|
||||||
|
setErrors({})
|
||||||
|
setTouched({})
|
||||||
|
resetForm({ values: initialValues, status: 'empty' })
|
||||||
|
// setSubmitting(false)
|
||||||
|
}, [setErrors, setTouched])
|
||||||
|
|
||||||
|
// Manually handle change events instead of using `handleChange` from Formik.
|
||||||
|
// Workaround for default `validateOnChange` not kicking in
|
||||||
|
function handleFieldChange(
|
||||||
|
e: ChangeEvent<HTMLInputElement>,
|
||||||
|
field: FormFieldProps
|
||||||
|
) {
|
||||||
|
validateField(field.name)
|
||||||
|
setFieldValue(field.name, e.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const resetFormAndClearStorage = (e: FormEvent<Element>) => {
|
||||||
|
e.preventDefault()
|
||||||
|
resetForm({ values: initialValues, status: 'empty' })
|
||||||
|
setStatus('empty')
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form
|
||||||
|
className={styles.form}
|
||||||
|
// do we need this?
|
||||||
|
onChange={() => status === 'empty' && setStatus(null)}
|
||||||
|
>
|
||||||
|
{content.data.map((field: FormFieldProps) => (
|
||||||
|
<Field
|
||||||
|
key={field.name}
|
||||||
|
{...field}
|
||||||
|
component={Input}
|
||||||
|
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||||
|
handleFieldChange(e, field)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<footer className={styles.actions}>
|
||||||
|
<Button
|
||||||
|
style="primary"
|
||||||
|
type="submit"
|
||||||
|
disabled={!ocean || !account || !isValid || status === 'empty'}
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
{status !== 'empty' && (
|
||||||
|
<Button style="text" size="small" onClick={resetFormAndClearStorage}>
|
||||||
|
Reset Form
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</footer>
|
||||||
|
</Form>
|
||||||
|
)
|
||||||
|
}
|
@ -1,18 +1,31 @@
|
|||||||
import React, { ReactElement, useState } from 'react'
|
import React, { ReactElement, useState, useEffect } from 'react'
|
||||||
import { Formik } from 'formik'
|
import { Formik } from 'formik'
|
||||||
import { usePublish, useOcean } from '@oceanprotocol/react'
|
import { usePublish, useOcean } from '@oceanprotocol/react'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import FormPublish from './FormPublish'
|
import FormPublish from './FormPublish'
|
||||||
|
import FormAlgoPublish from './FormAlgoPublish'
|
||||||
import PublishType from './PublishType'
|
import PublishType from './PublishType'
|
||||||
import Web3Feedback from '../../molecules/Wallet/Feedback'
|
import Web3Feedback from '../../molecules/Wallet/Feedback'
|
||||||
import { FormContent } from '../../../@types/Form'
|
import { FormContent } from '../../../@types/Form'
|
||||||
import { initialValues, validationSchema } from '../../../models/FormPublish'
|
import { initialValues, validationSchema } from '../../../models/FormPublish'
|
||||||
|
import {
|
||||||
|
initialValues as initialValuesAlgorithm,
|
||||||
|
validationSchema as validationSchemaAlgorithm
|
||||||
|
} from '../../../models/FormAlgoPublish'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
transformPublishFormToMetadata,
|
transformPublishFormToMetadata,
|
||||||
|
transformPublishAlgorithmFormToMetadata,
|
||||||
mapTimeoutStringToSeconds
|
mapTimeoutStringToSeconds
|
||||||
} from '../../../utils/metadata'
|
} from '../../../utils/metadata'
|
||||||
import MetadataPreview from '../../molecules/MetadataPreview'
|
import {
|
||||||
import { MetadataPublishForm } from '../../../@types/MetaData'
|
MetadataPreview,
|
||||||
|
MetadataAlgorithmPreview
|
||||||
|
} from '../../molecules/MetadataPreview'
|
||||||
|
import {
|
||||||
|
MetadataPublishForm,
|
||||||
|
AlgorithmPublishForm
|
||||||
|
} from '../../../@types/MetaData'
|
||||||
import { useUserPreferences } from '../../../providers/UserPreferences'
|
import { useUserPreferences } from '../../../providers/UserPreferences'
|
||||||
import { Logger, Metadata } from '@oceanprotocol/lib'
|
import { Logger, Metadata } from '@oceanprotocol/lib'
|
||||||
import { Persist } from '../../atoms/FormikPersist'
|
import { Persist } from '../../atoms/FormikPersist'
|
||||||
@ -24,20 +37,29 @@ import Button from '../../atoms/Button'
|
|||||||
const formName = 'ocean-publish-form'
|
const formName = 'ocean-publish-form'
|
||||||
|
|
||||||
export default function PublishPage({
|
export default function PublishPage({
|
||||||
content
|
content,
|
||||||
|
contentAlgoPublish
|
||||||
}: {
|
}: {
|
||||||
content: { warning: string; form: FormContent }
|
content: { warning: string; form: FormContent }
|
||||||
|
contentAlgoPublish: { warning: string; form: FormContent }
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { debug } = useUserPreferences()
|
const { debug } = useUserPreferences()
|
||||||
const { publish, publishError, isLoading, publishStepText } = usePublish()
|
const { publish, publishError, isLoading, publishStepText } = usePublish()
|
||||||
const { isInPurgatory, purgatoryData } = useOcean()
|
const { isInPurgatory, purgatoryData } = useOcean()
|
||||||
const [success, setSuccess] = useState<string>()
|
const [success, setSuccess] = useState<string>()
|
||||||
const [error, setError] = useState<string>()
|
const [error, setError] = useState<string>()
|
||||||
|
const [title, setTitle] = useState<string>()
|
||||||
const [did, setDid] = useState<string>()
|
const [did, setDid] = useState<string>()
|
||||||
const [publishType, setPublishType] = useState<string>()
|
const [publishType, setPublishType] = useState<string>()
|
||||||
|
|
||||||
const hasFeedback = isLoading || error || success
|
const hasFeedback = isLoading || error || success
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
publishType === 'data'
|
||||||
|
? setTitle('Publishing Data Set')
|
||||||
|
: setTitle('Publishing Algorithm')
|
||||||
|
}, [publishType])
|
||||||
|
|
||||||
async function handleSubmit(
|
async function handleSubmit(
|
||||||
values: Partial<MetadataPublishForm>,
|
values: Partial<MetadataPublishForm>,
|
||||||
resetForm: () => void
|
resetForm: () => void
|
||||||
@ -81,16 +103,52 @@ export default function PublishPage({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleAlgorithmSubmit(
|
||||||
|
values: Partial<AlgorithmPublishForm>,
|
||||||
|
resetForm: () => void
|
||||||
|
): Promise<void> {
|
||||||
|
const metadata = transformPublishAlgorithmFormToMetadata(values)
|
||||||
|
|
||||||
|
try {
|
||||||
|
Logger.log('Publish Algorithm with ', metadata)
|
||||||
|
|
||||||
|
const ddo = await publish((metadata as unknown) as Metadata, 'access')
|
||||||
|
|
||||||
|
// Publish failed
|
||||||
|
if (!ddo || publishError) {
|
||||||
|
setError(publishError || 'Publishing DDO failed.')
|
||||||
|
Logger.error(publishError || 'Publishing DDO failed.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Publish succeeded
|
||||||
|
setDid(ddo.id)
|
||||||
|
setSuccess(
|
||||||
|
'🎉 Successfully published. 🎉 Now create a price for your algorithm.'
|
||||||
|
)
|
||||||
|
resetForm()
|
||||||
|
} catch (error) {
|
||||||
|
setError(error.message)
|
||||||
|
Logger.error(error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return isInPurgatory && purgatoryData ? null : (
|
return isInPurgatory && purgatoryData ? null : (
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={initialValues}
|
initialValues={
|
||||||
|
publishType === 'data' ? initialValues : initialValuesAlgorithm
|
||||||
|
}
|
||||||
initialStatus="empty"
|
initialStatus="empty"
|
||||||
validationSchema={validationSchema}
|
validationSchema={
|
||||||
|
publishType === 'data' ? validationSchema : validationSchemaAlgorithm
|
||||||
|
}
|
||||||
onSubmit={async (values, { resetForm }) => {
|
onSubmit={async (values, { resetForm }) => {
|
||||||
// move user's focus to top of screen
|
// move user's focus to top of screen
|
||||||
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
|
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
|
||||||
// kick off publishing
|
// kick off publishing
|
||||||
await handleSubmit(values, resetForm)
|
publishType === 'data'
|
||||||
|
? await handleSubmit(values, resetForm)
|
||||||
|
: await handleAlgorithmSubmit(values, resetForm)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ values }) => (
|
{({ values }) => (
|
||||||
@ -99,7 +157,7 @@ export default function PublishPage({
|
|||||||
|
|
||||||
{hasFeedback ? (
|
{hasFeedback ? (
|
||||||
<MetadataFeedback
|
<MetadataFeedback
|
||||||
title="Publishing Data Set"
|
title={title}
|
||||||
error={error}
|
error={error}
|
||||||
success={success}
|
success={success}
|
||||||
loading={publishStepText}
|
loading={publishStepText}
|
||||||
@ -111,21 +169,26 @@ export default function PublishPage({
|
|||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<PublishType
|
<PublishType type={publishType} setType={setPublishType} />
|
||||||
type={publishType}
|
|
||||||
setType={setPublishType}
|
|
||||||
></PublishType>
|
|
||||||
<Alert
|
<Alert
|
||||||
text={content.warning}
|
text={content.warning}
|
||||||
state="info"
|
state="info"
|
||||||
className={styles.alert}
|
className={styles.alert}
|
||||||
/>
|
/>
|
||||||
<article className={styles.grid}>
|
<article className={styles.grid}>
|
||||||
<FormPublish content={content.form} />
|
{publishType === 'data' ? (
|
||||||
|
<FormPublish content={content.form} />
|
||||||
|
) : (
|
||||||
|
<FormAlgoPublish content={contentAlgoPublish.form} />
|
||||||
|
)}
|
||||||
|
|
||||||
<aside>
|
<aside>
|
||||||
<div className={styles.sticky}>
|
<div className={styles.sticky}>
|
||||||
<MetadataPreview values={values} />
|
{publishType === 'data' ? (
|
||||||
|
<MetadataPreview values={values} />
|
||||||
|
) : (
|
||||||
|
<MetadataAlgorithmPreview values={values} />
|
||||||
|
)}
|
||||||
<Web3Feedback />
|
<Web3Feedback />
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
32
src/models/FormAlgoPublish.ts
Normal file
32
src/models/FormAlgoPublish.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { AlgorithmPublishForm } from '../@types/MetaData'
|
||||||
|
import { File as FileMetadata } from '@oceanprotocol/lib'
|
||||||
|
import * as Yup from 'yup'
|
||||||
|
|
||||||
|
export const validationSchema: Yup.SchemaOf<AlgorithmPublishForm> = Yup.object()
|
||||||
|
.shape({
|
||||||
|
// ---- required fields ----
|
||||||
|
name: Yup.string()
|
||||||
|
.min(4, (param) => `Title must be at least ${param.min} characters`)
|
||||||
|
.required('Required'),
|
||||||
|
description: Yup.string().min(10).required('Required'),
|
||||||
|
files: Yup.array<FileMetadata>().required('Required').nullable(),
|
||||||
|
dockerImage: Yup.string()
|
||||||
|
.matches(/NodeJS|Python 3.7/g, { excludeEmptyString: true })
|
||||||
|
.required('Required'),
|
||||||
|
author: Yup.string().required('Required'),
|
||||||
|
termsAndConditions: Yup.boolean().required('Required'),
|
||||||
|
// ---- optional fields ----
|
||||||
|
tags: Yup.string().nullable(),
|
||||||
|
links: Yup.array<FileMetadata[]>().nullable()
|
||||||
|
})
|
||||||
|
.defined()
|
||||||
|
|
||||||
|
export const initialValues: Partial<AlgorithmPublishForm> = {
|
||||||
|
name: '',
|
||||||
|
author: '',
|
||||||
|
dockerImage: '',
|
||||||
|
files: '',
|
||||||
|
description: '',
|
||||||
|
termsAndConditions: false,
|
||||||
|
tags: ''
|
||||||
|
}
|
@ -5,11 +5,13 @@ import { graphql, PageProps } from 'gatsby'
|
|||||||
|
|
||||||
export default function PageGatsbyPublish(props: PageProps): ReactElement {
|
export default function PageGatsbyPublish(props: PageProps): ReactElement {
|
||||||
const content = (props.data as any).content.edges[0].node.childPagesJson
|
const content = (props.data as any).content.edges[0].node.childPagesJson
|
||||||
|
const contentAlgoPublish = (props.data as any).contentAlgoPublish.edges[0]
|
||||||
|
.node.childPagesJson
|
||||||
const { title, description } = content
|
const { title, description } = content
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page title={title} description={description} uri={props.uri}>
|
<Page title={title} description={description} uri={props.uri}>
|
||||||
<PagePublish content={content} />
|
<PagePublish content={content} contentAlgoPublish={contentAlgoPublish} />
|
||||||
</Page>
|
</Page>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -41,5 +43,32 @@ export const contentQuery = graphql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
contentAlgoPublish: allFile(
|
||||||
|
filter: { relativePath: { eq: "pages/publishAlgo.json" } }
|
||||||
|
) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
childPagesJson {
|
||||||
|
title
|
||||||
|
description
|
||||||
|
warning
|
||||||
|
form {
|
||||||
|
title
|
||||||
|
data {
|
||||||
|
name
|
||||||
|
placeholder
|
||||||
|
label
|
||||||
|
help
|
||||||
|
type
|
||||||
|
required
|
||||||
|
sortOptions
|
||||||
|
options
|
||||||
|
}
|
||||||
|
success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
import { MetadataMarket, MetadataPublishForm } from '../@types/MetaData'
|
import {
|
||||||
|
MetadataMarket,
|
||||||
|
MetadataPublishForm,
|
||||||
|
AlgorithmPublishForm
|
||||||
|
} from '../@types/MetaData'
|
||||||
import { toStringNoMS } from '.'
|
import { toStringNoMS } from '.'
|
||||||
import AssetModel from '../models/Asset'
|
import AssetModel from '../models/Asset'
|
||||||
import slugify from '@sindresorhus/slugify'
|
import slugify from '@sindresorhus/slugify'
|
||||||
import { DDO } from '@oceanprotocol/lib'
|
import { DDO, MetadataAlgorithm } from '@oceanprotocol/lib'
|
||||||
|
|
||||||
export function transformTags(value: string): string[] {
|
export function transformTags(value: string): string[] {
|
||||||
const originalTags = value?.split(',')
|
const originalTags = value?.split(',')
|
||||||
@ -66,6 +70,21 @@ export function checkIfTimeoutInPredefinedValues(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAlgoithComponent(selectedAlgorithm: string): MetadataAlgorithm {
|
||||||
|
return {
|
||||||
|
language: selectedAlgorithm === 'NodeJS' ? 'js' : 'py',
|
||||||
|
format: 'docker-image',
|
||||||
|
version: '0.1',
|
||||||
|
container: {
|
||||||
|
entrypoint:
|
||||||
|
selectedAlgorithm === 'NodeJS' ? 'node $ALGO' : 'python $ALGO',
|
||||||
|
image:
|
||||||
|
selectedAlgorithm === 'NodeJS' ? 'node' : 'oceanprotocol/algo_dockers',
|
||||||
|
tag: selectedAlgorithm === 'NodeJS' ? '10' : 'python-panda'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function transformPublishFormToMetadata(
|
export function transformPublishFormToMetadata(
|
||||||
{
|
{
|
||||||
name,
|
name,
|
||||||
@ -100,3 +119,39 @@ export function transformPublishFormToMetadata(
|
|||||||
|
|
||||||
return metadata
|
return metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function transformPublishAlgorithmFormToMetadata(
|
||||||
|
{
|
||||||
|
name,
|
||||||
|
author,
|
||||||
|
description,
|
||||||
|
tags,
|
||||||
|
dockerImage,
|
||||||
|
termsAndConditions,
|
||||||
|
files
|
||||||
|
}: Partial<AlgorithmPublishForm>,
|
||||||
|
ddo?: DDO
|
||||||
|
): MetadataMarket {
|
||||||
|
const currentTime = toStringNoMS(new Date())
|
||||||
|
const algorithm = getAlgoithComponent(dockerImage)
|
||||||
|
const metadata: MetadataMarket = {
|
||||||
|
main: {
|
||||||
|
...AssetModel.main,
|
||||||
|
name,
|
||||||
|
type: 'algorithm',
|
||||||
|
author,
|
||||||
|
dateCreated: ddo ? ddo.created : currentTime,
|
||||||
|
files: typeof files !== 'string' && files,
|
||||||
|
license: 'https://market.oceanprotocol.com/terms',
|
||||||
|
algorithm: algorithm
|
||||||
|
},
|
||||||
|
additionalInformation: {
|
||||||
|
...AssetModel.additionalInformation,
|
||||||
|
description,
|
||||||
|
tags: transformTags(tags),
|
||||||
|
termsAndConditions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return metadata
|
||||||
|
}
|
||||||
|
@ -2,10 +2,13 @@ import React from 'react'
|
|||||||
import { render } from '@testing-library/react'
|
import { render } from '@testing-library/react'
|
||||||
import Publish from '../../../src/components/pages/Publish'
|
import Publish from '../../../src/components/pages/Publish'
|
||||||
import content from '../../../content/pages/publish.json'
|
import content from '../../../content/pages/publish.json'
|
||||||
|
import contentAlgo from '../../../content/pages/publishAlgo.json'
|
||||||
|
|
||||||
describe('Home', () => {
|
describe('Home', () => {
|
||||||
it('renders without crashing', () => {
|
it('renders without crashing', () => {
|
||||||
const { container } = render(<Publish content={content} />)
|
const { container } = render(
|
||||||
|
<Publish content={content} contentAlgoPublish={contentAlgo} />
|
||||||
|
)
|
||||||
expect(container.firstChild).toBeInTheDocument()
|
expect(container.firstChild).toBeInTheDocument()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user