mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
276 lines
8.1 KiB
TypeScript
276 lines
8.1 KiB
TypeScript
import React, { ReactElement, useState, useEffect } from 'react'
|
|
import { Formik, FormikState } from 'formik'
|
|
import { usePublish, useOcean } from '@oceanprotocol/react'
|
|
import styles from './index.module.css'
|
|
import FormPublish from './FormPublish'
|
|
import FormAlgoPublish from './FormAlgoPublish'
|
|
import Web3Feedback from '../../molecules/Wallet/Feedback'
|
|
import Tabs from '../../atoms/Tabs'
|
|
import { initialValues, validationSchema } from '../../../models/FormPublish'
|
|
import {
|
|
initialValues as initialValuesAlgorithm,
|
|
validationSchema as validationSchemaAlgorithm
|
|
} from '../../../models/FormAlgoPublish'
|
|
import {
|
|
transformPublishFormToMetadata,
|
|
transformPublishAlgorithmFormToMetadata,
|
|
mapTimeoutStringToSeconds,
|
|
validateDockerImage
|
|
} from '../../../utils/metadata'
|
|
import {
|
|
MetadataPreview,
|
|
MetadataAlgorithmPreview
|
|
} from '../../molecules/MetadataPreview'
|
|
import {
|
|
MetadataPublishFormDataset,
|
|
MetadataPublishFormAlgorithm
|
|
} from '../../../@types/MetaData'
|
|
import { useUserPreferences } from '../../../providers/UserPreferences'
|
|
import { Logger, Metadata, MetadataMain } from '@oceanprotocol/lib'
|
|
import { Persist } from '../../atoms/FormikPersist'
|
|
import Debug from './Debug'
|
|
import Alert from '../../atoms/Alert'
|
|
import MetadataFeedback from '../../molecules/MetadataFeedback'
|
|
|
|
const formNameDatasets = 'ocean-publish-form-datasets'
|
|
const formNameAlgorithms = 'ocean-publish-form-algorithms'
|
|
|
|
function TabContent({
|
|
publishType,
|
|
values
|
|
}: {
|
|
publishType: MetadataMain['type']
|
|
values: Partial<MetadataPublishFormAlgorithm | MetadataPublishFormDataset>
|
|
}) {
|
|
return (
|
|
<article className={styles.grid}>
|
|
{publishType === 'dataset' ? <FormPublish /> : <FormAlgoPublish />}
|
|
|
|
<aside>
|
|
<div className={styles.sticky}>
|
|
{publishType === 'dataset' ? (
|
|
<MetadataPreview values={values} />
|
|
) : (
|
|
<MetadataAlgorithmPreview values={values} />
|
|
)}
|
|
|
|
<Web3Feedback />
|
|
</div>
|
|
</aside>
|
|
</article>
|
|
)
|
|
}
|
|
|
|
export default function PublishPage({
|
|
content
|
|
}: {
|
|
content: { warning: string }
|
|
}): ReactElement {
|
|
const { debug } = useUserPreferences()
|
|
const { publish, publishError, isLoading, publishStepText } = usePublish()
|
|
const { isInPurgatory, purgatoryData } = useOcean()
|
|
const [success, setSuccess] = useState<string>()
|
|
const [error, setError] = useState<string>()
|
|
const [title, setTitle] = useState<string>()
|
|
const [did, setDid] = useState<string>()
|
|
const [algoInitialValues, setAlgoInitialValues] = useState<
|
|
Partial<MetadataPublishFormAlgorithm>
|
|
>(
|
|
(localStorage.getItem('ocean-publish-form-algorithms') &&
|
|
(JSON.parse(localStorage.getItem('ocean-publish-form-algorithms'))
|
|
.initialValues as MetadataPublishFormAlgorithm)) ||
|
|
initialValuesAlgorithm
|
|
)
|
|
const [datasetInitialValues, setdatasetInitialValues] = useState<
|
|
Partial<MetadataPublishFormDataset>
|
|
>(
|
|
(localStorage.getItem('ocean-publish-form-datasets') &&
|
|
(JSON.parse(localStorage.getItem('ocean-publish-form-datasets'))
|
|
.initialValues as MetadataPublishFormDataset)) ||
|
|
initialValues
|
|
)
|
|
const [publishType, setPublishType] = useState<MetadataMain['type']>(
|
|
'dataset'
|
|
)
|
|
|
|
const hasFeedback = isLoading || error || success
|
|
|
|
useEffect(() => {
|
|
publishType === 'dataset'
|
|
? setTitle('Publishing Data Set')
|
|
: setTitle('Publishing Algorithm')
|
|
}, [publishType])
|
|
|
|
async function handleSubmit(
|
|
values: Partial<MetadataPublishFormDataset>,
|
|
resetForm: (
|
|
nextState?: Partial<FormikState<Partial<MetadataPublishFormDataset>>>
|
|
) => void
|
|
): Promise<void> {
|
|
const metadata = transformPublishFormToMetadata(values)
|
|
const timeout = mapTimeoutStringToSeconds(values.timeout)
|
|
|
|
const serviceType = values.access === 'Download' ? 'access' : 'compute'
|
|
|
|
try {
|
|
Logger.log(
|
|
'Publish with ',
|
|
metadata,
|
|
serviceType,
|
|
values.dataTokenOptions
|
|
)
|
|
|
|
const ddo = await publish(
|
|
(metadata as unknown) as Metadata,
|
|
serviceType,
|
|
values.dataTokenOptions,
|
|
timeout
|
|
)
|
|
|
|
// 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 on your data set.'
|
|
)
|
|
resetForm({
|
|
values: initialValues as MetadataPublishFormDataset,
|
|
status: 'empty'
|
|
})
|
|
} catch (error) {
|
|
setError(error.message)
|
|
Logger.error(error.message)
|
|
}
|
|
}
|
|
|
|
async function handleAlgorithmSubmit(
|
|
values: Partial<MetadataPublishFormAlgorithm>,
|
|
resetForm: (
|
|
nextState?: Partial<FormikState<Partial<MetadataPublishFormAlgorithm>>>
|
|
) => void
|
|
): Promise<void> {
|
|
const metadata = transformPublishAlgorithmFormToMetadata(values)
|
|
try {
|
|
Logger.log('Publish Algorithm with ', metadata)
|
|
|
|
const validImage = await validateDockerImage(
|
|
values.image,
|
|
values.containerTag
|
|
)
|
|
|
|
const ddo = await publish(
|
|
(metadata as unknown) as Metadata,
|
|
values.algorithmPrivacy === true ? 'compute' : '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({
|
|
values: initialValuesAlgorithm as MetadataPublishFormAlgorithm,
|
|
status: 'empty'
|
|
})
|
|
} catch (error) {
|
|
setError(error.message)
|
|
Logger.error(error.message)
|
|
}
|
|
}
|
|
|
|
return isInPurgatory && purgatoryData ? null : (
|
|
<Formik
|
|
initialValues={
|
|
publishType === 'dataset' ? datasetInitialValues : algoInitialValues
|
|
}
|
|
initialStatus="empty"
|
|
validationSchema={
|
|
publishType === 'dataset' ? validationSchema : validationSchemaAlgorithm
|
|
}
|
|
onSubmit={async (values, { resetForm }) => {
|
|
// move user's focus to top of screen
|
|
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
|
|
// kick off publishing
|
|
publishType === 'dataset'
|
|
? await handleSubmit(values, resetForm)
|
|
: await handleAlgorithmSubmit(values, resetForm)
|
|
}}
|
|
enableReinitialize
|
|
>
|
|
{({ values }) => {
|
|
const tabs = [
|
|
{
|
|
title: 'Data Set',
|
|
content: <TabContent values={values} publishType={publishType} />
|
|
},
|
|
{
|
|
title: 'Algorithm',
|
|
content: <TabContent values={values} publishType={publishType} />
|
|
}
|
|
]
|
|
|
|
return (
|
|
<>
|
|
<Persist
|
|
name={
|
|
publishType === 'dataset'
|
|
? formNameDatasets
|
|
: formNameAlgorithms
|
|
}
|
|
ignoreFields={['isSubmitting']}
|
|
/>
|
|
|
|
{hasFeedback ? (
|
|
<MetadataFeedback
|
|
title={title}
|
|
error={error}
|
|
success={success}
|
|
loading={publishStepText}
|
|
setError={setError}
|
|
successAction={{
|
|
name: 'Go to data set →',
|
|
to: `/asset/${did}`
|
|
}}
|
|
/>
|
|
) : (
|
|
<>
|
|
<Alert
|
|
text={content.warning}
|
|
state="info"
|
|
className={styles.alert}
|
|
/>
|
|
|
|
<Tabs
|
|
className={styles.tabs}
|
|
items={tabs}
|
|
handleTabChange={(title) => {
|
|
setPublishType(title.toLowerCase().replace(' ', '') as any)
|
|
title === 'Algorithm'
|
|
? setdatasetInitialValues(values)
|
|
: setAlgoInitialValues(values)
|
|
}}
|
|
/>
|
|
</>
|
|
)}
|
|
|
|
{debug === true && <Debug values={values} />}
|
|
</>
|
|
)
|
|
}}
|
|
</Formik>
|
|
)
|
|
}
|