mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
declarative metadata & services form setup, prepare transformPublishFormToDdo method
This commit is contained in:
parent
cdbe413765
commit
66adc097b6
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"title": "Enter details",
|
"title": "Metadata",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"name": "name",
|
"name": "name",
|
||||||
@ -38,7 +38,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"services": {
|
"services": {
|
||||||
"title": "Create services",
|
"title": "Access",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"name": "dataTokenOptions",
|
"name": "dataTokenOptions",
|
||||||
@ -87,13 +87,12 @@
|
|||||||
"label": "Custom Provider URL",
|
"label": "Custom Provider URL",
|
||||||
"type": "providerUri",
|
"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/).",
|
"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/",
|
"placeholder": "e.g. https://provider.polygon.oceanprotocol.com/"
|
||||||
"advanced": true
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"pricing": {
|
"pricing": {
|
||||||
"title": "Create pricing schema",
|
"title": "Pricing",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"name": "dummy content, as content is defined under 'create' key in ../price.json"
|
"name": "dummy content, as content is defined under 'create' key in ../price.json"
|
||||||
|
16
src/@types/Form.d.ts
vendored
16
src/@types/Form.d.ts
vendored
@ -1,13 +1,8 @@
|
|||||||
import { AssetSelectionAsset } from '@shared/Form/FormFields/AssetSelection'
|
interface FormFieldContent {
|
||||||
|
|
||||||
// declaring into global scope to be able to use this as
|
|
||||||
// ambiant types despite the above imports
|
|
||||||
declare global {
|
|
||||||
interface FormFieldProps {
|
|
||||||
label: string
|
label: string
|
||||||
name: string
|
name: string
|
||||||
type?: string
|
type?: string
|
||||||
options?: string[] | AssetSelectionAsset[]
|
options?: string[]
|
||||||
sortOptions?: boolean
|
sortOptions?: boolean
|
||||||
required?: boolean
|
required?: boolean
|
||||||
multiple?: boolean
|
multiple?: boolean
|
||||||
@ -19,11 +14,10 @@ declare global {
|
|||||||
disclaimer?: string
|
disclaimer?: string
|
||||||
disclaimerValues?: string[]
|
disclaimerValues?: string[]
|
||||||
advanced?: boolean
|
advanced?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FormStepContent {
|
interface FormStepContent {
|
||||||
title: string
|
title: string
|
||||||
description?: string
|
description?: string
|
||||||
fields: FormFieldProps[]
|
fields: FormFieldContent[]
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
5
src/@types/aquarius/MetaData.d.ts
vendored
5
src/@types/aquarius/MetaData.d.ts
vendored
@ -7,6 +7,11 @@ import {
|
|||||||
// declaring into global scope to be able to use this as
|
// declaring into global scope to be able to use this as
|
||||||
// ambiant types despite the above imports
|
// ambiant types despite the above imports
|
||||||
declare global {
|
declare global {
|
||||||
|
interface DdoMarket {
|
||||||
|
metadata: any
|
||||||
|
services: any[]
|
||||||
|
}
|
||||||
|
|
||||||
interface AdditionalInformationMarket extends AdditionalInformation {
|
interface AdditionalInformationMarket extends AdditionalInformation {
|
||||||
termsAndConditions: boolean
|
termsAndConditions: boolean
|
||||||
}
|
}
|
||||||
|
97
src/@utils/ddo.ts
Normal file
97
src/@utils/ddo.ts
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
import axios from 'axios'
|
||||||
|
import { toast } from 'react-toastify'
|
||||||
|
import isUrl from 'is-url-superb'
|
||||||
|
import slugify from 'slugify'
|
||||||
|
import { MetadataAlgorithm, Logger } from '@oceanprotocol/lib'
|
||||||
|
|
||||||
|
export function dateToStringNoMS(date: Date): string {
|
||||||
|
return date.toISOString().replace(/\.[0-9]{3}Z/, 'Z')
|
||||||
|
}
|
||||||
|
|
||||||
|
export function transformTags(value: string): string[] {
|
||||||
|
const originalTags = value?.split(',')
|
||||||
|
const transformedTags = originalTags?.map((tag) => slugify(tag).toLowerCase())
|
||||||
|
return transformedTags
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapTimeoutStringToSeconds(timeout: string): number {
|
||||||
|
switch (timeout) {
|
||||||
|
case 'Forever':
|
||||||
|
return 0
|
||||||
|
case '1 day':
|
||||||
|
return 86400
|
||||||
|
case '1 week':
|
||||||
|
return 604800
|
||||||
|
case '1 month':
|
||||||
|
return 2630000
|
||||||
|
case '1 year':
|
||||||
|
return 31556952
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function numberEnding(number: number): string {
|
||||||
|
return number > 1 ? 's' : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
export function secondsToString(numberOfSeconds: number): string {
|
||||||
|
if (numberOfSeconds === 0) return 'Forever'
|
||||||
|
|
||||||
|
const years = Math.floor(numberOfSeconds / 31536000)
|
||||||
|
const months = Math.floor((numberOfSeconds %= 31536000) / 2630000)
|
||||||
|
const weeks = Math.floor((numberOfSeconds %= 31536000) / 604800)
|
||||||
|
const days = Math.floor((numberOfSeconds %= 604800) / 86400)
|
||||||
|
const hours = Math.floor((numberOfSeconds %= 86400) / 3600)
|
||||||
|
const minutes = Math.floor((numberOfSeconds %= 3600) / 60)
|
||||||
|
const seconds = numberOfSeconds % 60
|
||||||
|
|
||||||
|
return years
|
||||||
|
? `${years} year${numberEnding(years)}`
|
||||||
|
: months
|
||||||
|
? `${months} month${numberEnding(months)}`
|
||||||
|
: weeks
|
||||||
|
? `${weeks} week${numberEnding(weeks)}`
|
||||||
|
: days
|
||||||
|
? `${days} day${numberEnding(days)}`
|
||||||
|
: hours
|
||||||
|
? `${hours} hour${numberEnding(hours)}`
|
||||||
|
: minutes
|
||||||
|
? `${minutes} minute${numberEnding(minutes)}`
|
||||||
|
: seconds
|
||||||
|
? `${seconds} second${numberEnding(seconds)}`
|
||||||
|
: 'less than a second'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function checkIfTimeoutInPredefinedValues(
|
||||||
|
timeout: string,
|
||||||
|
timeoutOptions: string[]
|
||||||
|
): boolean {
|
||||||
|
if (timeoutOptions.indexOf(timeout) > -1) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAlgorithmComponent(
|
||||||
|
image: string,
|
||||||
|
containerTag: string,
|
||||||
|
entrypoint: string,
|
||||||
|
algorithmLanguage: string
|
||||||
|
): MetadataAlgorithm {
|
||||||
|
return {
|
||||||
|
language: algorithmLanguage,
|
||||||
|
format: 'docker-image',
|
||||||
|
version: '0.1',
|
||||||
|
container: {
|
||||||
|
entrypoint: entrypoint,
|
||||||
|
image: image,
|
||||||
|
tag: containerTag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAlgorithmFileExtension(fileUrl: string): string {
|
||||||
|
const splitedFileUrl = fileUrl.split('.')
|
||||||
|
return splitedFileUrl[splitedFileUrl.length - 1]
|
||||||
|
}
|
63
src/@utils/docker.ts
Normal file
63
src/@utils/docker.ts
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import { Logger } from '@oceanprotocol/lib'
|
||||||
|
import axios from 'axios'
|
||||||
|
import isUrl from 'is-url-superb'
|
||||||
|
import { toast } from 'react-toastify'
|
||||||
|
|
||||||
|
async function isDockerHubImageValid(
|
||||||
|
image: string,
|
||||||
|
tag: string
|
||||||
|
): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
const response = await axios.post(
|
||||||
|
`https://dockerhub-proxy.oceanprotocol.com`,
|
||||||
|
{ image, tag }
|
||||||
|
)
|
||||||
|
if (
|
||||||
|
!response ||
|
||||||
|
response.status !== 200 ||
|
||||||
|
response.data.status !== 'success'
|
||||||
|
) {
|
||||||
|
toast.error(
|
||||||
|
'Could not fetch docker hub image info. Please check image name and tag and try again'
|
||||||
|
)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
} catch (error) {
|
||||||
|
Logger.error(error.message)
|
||||||
|
toast.error(
|
||||||
|
'Could not fetch docker hub image info. Please check image name and tag and try again'
|
||||||
|
)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function is3rdPartyImageValid(imageURL: string): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
const response = await axios.head(imageURL)
|
||||||
|
if (!response || response.status !== 200) {
|
||||||
|
toast.error(
|
||||||
|
'Could not fetch docker image info. Please check URL and try again'
|
||||||
|
)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
} catch (error) {
|
||||||
|
Logger.error(error.message)
|
||||||
|
toast.error(
|
||||||
|
'Could not fetch docker image info. Please check URL and try again'
|
||||||
|
)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function validateDockerImage(
|
||||||
|
dockerImage: string,
|
||||||
|
tag: string
|
||||||
|
): Promise<boolean> {
|
||||||
|
const isValid = isUrl(dockerImage)
|
||||||
|
? await is3rdPartyImageValid(dockerImage)
|
||||||
|
: await isDockerHubImageValid(dockerImage, tag)
|
||||||
|
return isValid
|
||||||
|
}
|
@ -1,237 +0,0 @@
|
|||||||
import axios from 'axios'
|
|
||||||
import { toast } from 'react-toastify'
|
|
||||||
import isUrl from 'is-url-superb'
|
|
||||||
import slugify from 'slugify'
|
|
||||||
import { DDO, MetadataAlgorithm, Logger } from '@oceanprotocol/lib'
|
|
||||||
import { FormPublishData } from '../components/Publish/_types'
|
|
||||||
|
|
||||||
export function dateToStringNoMS(date: Date): string {
|
|
||||||
return date.toISOString().replace(/\.[0-9]{3}Z/, 'Z')
|
|
||||||
}
|
|
||||||
|
|
||||||
export function transformTags(value: string): string[] {
|
|
||||||
const originalTags = value?.split(',')
|
|
||||||
const transformedTags = originalTags?.map((tag) => slugify(tag).toLowerCase())
|
|
||||||
return transformedTags
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapTimeoutStringToSeconds(timeout: string): number {
|
|
||||||
switch (timeout) {
|
|
||||||
case 'Forever':
|
|
||||||
return 0
|
|
||||||
case '1 day':
|
|
||||||
return 86400
|
|
||||||
case '1 week':
|
|
||||||
return 604800
|
|
||||||
case '1 month':
|
|
||||||
return 2630000
|
|
||||||
case '1 year':
|
|
||||||
return 31556952
|
|
||||||
default:
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function numberEnding(number: number): string {
|
|
||||||
return number > 1 ? 's' : ''
|
|
||||||
}
|
|
||||||
|
|
||||||
export function secondsToString(numberOfSeconds: number): string {
|
|
||||||
if (numberOfSeconds === 0) return 'Forever'
|
|
||||||
|
|
||||||
const years = Math.floor(numberOfSeconds / 31536000)
|
|
||||||
const months = Math.floor((numberOfSeconds %= 31536000) / 2630000)
|
|
||||||
const weeks = Math.floor((numberOfSeconds %= 31536000) / 604800)
|
|
||||||
const days = Math.floor((numberOfSeconds %= 604800) / 86400)
|
|
||||||
const hours = Math.floor((numberOfSeconds %= 86400) / 3600)
|
|
||||||
const minutes = Math.floor((numberOfSeconds %= 3600) / 60)
|
|
||||||
const seconds = numberOfSeconds % 60
|
|
||||||
|
|
||||||
return years
|
|
||||||
? `${years} year${numberEnding(years)}`
|
|
||||||
: months
|
|
||||||
? `${months} month${numberEnding(months)}`
|
|
||||||
: weeks
|
|
||||||
? `${weeks} week${numberEnding(weeks)}`
|
|
||||||
: days
|
|
||||||
? `${days} day${numberEnding(days)}`
|
|
||||||
: hours
|
|
||||||
? `${hours} hour${numberEnding(hours)}`
|
|
||||||
: minutes
|
|
||||||
? `${minutes} minute${numberEnding(minutes)}`
|
|
||||||
: seconds
|
|
||||||
? `${seconds} second${numberEnding(seconds)}`
|
|
||||||
: 'less than a second'
|
|
||||||
}
|
|
||||||
|
|
||||||
export function checkIfTimeoutInPredefinedValues(
|
|
||||||
timeout: string,
|
|
||||||
timeoutOptions: string[]
|
|
||||||
): boolean {
|
|
||||||
if (timeoutOptions.indexOf(timeout) > -1) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAlgorithmComponent(
|
|
||||||
image: string,
|
|
||||||
containerTag: string,
|
|
||||||
entrypoint: string,
|
|
||||||
algorithmLanguace: string
|
|
||||||
): MetadataAlgorithm {
|
|
||||||
return {
|
|
||||||
language: algorithmLanguace,
|
|
||||||
format: 'docker-image',
|
|
||||||
version: '0.1',
|
|
||||||
container: {
|
|
||||||
entrypoint: entrypoint,
|
|
||||||
image: image,
|
|
||||||
tag: containerTag
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAlgorithmFileExtension(fileUrl: string): string {
|
|
||||||
const splitedFileUrl = fileUrl.split('.')
|
|
||||||
return splitedFileUrl[splitedFileUrl.length - 1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// export function transformPublishFormToMetadata(
|
|
||||||
// {
|
|
||||||
// name,
|
|
||||||
// author,
|
|
||||||
// description,
|
|
||||||
// tags,
|
|
||||||
// links,
|
|
||||||
// termsAndConditions,
|
|
||||||
// files
|
|
||||||
// }: Partial<FormPublishData>,
|
|
||||||
// ddo?: DDO
|
|
||||||
// ): MetadataMarket {
|
|
||||||
// const currentTime = dateToStringNoMS(new Date())
|
|
||||||
|
|
||||||
// const metadata: MetadataMarket = {
|
|
||||||
// main: {
|
|
||||||
// name,
|
|
||||||
// author,
|
|
||||||
// dateCreated: ddo ? ddo.created : currentTime,
|
|
||||||
// datePublished: '',
|
|
||||||
// files: typeof files !== 'string' && files,
|
|
||||||
// license: 'https://market.oceanprotocol.com/terms'
|
|
||||||
// },
|
|
||||||
// additionalInformation: {
|
|
||||||
// description,
|
|
||||||
// tags: transformTags(tags),
|
|
||||||
// links: typeof links !== 'string' ? links : [],
|
|
||||||
// termsAndConditions
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return metadata
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async function isDockerHubImageValid(
|
|
||||||
// image: string,
|
|
||||||
// tag: string
|
|
||||||
// ): Promise<boolean> {
|
|
||||||
// try {
|
|
||||||
// const response = await axios.post(
|
|
||||||
// `https://dockerhub-proxy.oceanprotocol.com`,
|
|
||||||
// {
|
|
||||||
// image,
|
|
||||||
// tag
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
// if (
|
|
||||||
// !response ||
|
|
||||||
// response.status !== 200 ||
|
|
||||||
// response.data.status !== 'success'
|
|
||||||
// ) {
|
|
||||||
// toast.error(
|
|
||||||
// 'Could not fetch docker hub image info. Please check image name and tag and try again'
|
|
||||||
// )
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return true
|
|
||||||
// } catch (error) {
|
|
||||||
// Logger.error(error.message)
|
|
||||||
// toast.error(
|
|
||||||
// 'Could not fetch docker hub image info. Please check image name and tag and try again'
|
|
||||||
// )
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
async function is3rdPartyImageValid(imageURL: string): Promise<boolean> {
|
|
||||||
try {
|
|
||||||
const response = await axios.head(imageURL)
|
|
||||||
if (!response || response.status !== 200) {
|
|
||||||
toast.error(
|
|
||||||
'Could not fetch docker image info. Please check URL and try again'
|
|
||||||
)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
} catch (error) {
|
|
||||||
Logger.error(error.message)
|
|
||||||
toast.error(
|
|
||||||
'Could not fetch docker image info. Please check URL and try again'
|
|
||||||
)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// export async function validateDockerImage(
|
|
||||||
// dockerImage: string,
|
|
||||||
// tag: string
|
|
||||||
// ): Promise<boolean> {
|
|
||||||
// const isValid = isUrl(dockerImage)
|
|
||||||
// ? await is3rdPartyImageValid(dockerImage)
|
|
||||||
// : await isDockerHubImageValid(dockerImage, tag)
|
|
||||||
// return isValid
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export function transformPublishAlgorithmFormToMetadata(
|
|
||||||
// {
|
|
||||||
// name,
|
|
||||||
// author,
|
|
||||||
// description,
|
|
||||||
// tags,
|
|
||||||
// image,
|
|
||||||
// containerTag,
|
|
||||||
// entrypoint,
|
|
||||||
// termsAndConditions,
|
|
||||||
// files
|
|
||||||
// }: Partial<FormPublishData>,
|
|
||||||
// ddo?: DDO
|
|
||||||
// ): MetadataMarket {
|
|
||||||
// const currentTime = dateToStringNoMS(new Date())
|
|
||||||
// const fileUrl = typeof files !== 'string' && files[0].url
|
|
||||||
// const algorithmLanguage = getAlgorithmFileExtension(fileUrl)
|
|
||||||
// const algorithm = getAlgorithmComponent(
|
|
||||||
// image,
|
|
||||||
// containerTag,
|
|
||||||
// entrypoint,
|
|
||||||
// algorithmLanguage
|
|
||||||
// )
|
|
||||||
// const metadata: MetadataMarket = {
|
|
||||||
// main: {
|
|
||||||
// name,
|
|
||||||
// type: 'algorithm',
|
|
||||||
// author,
|
|
||||||
// dateCreated: ddo ? ddo.created : currentTime,
|
|
||||||
// files: typeof files !== 'string' && files,
|
|
||||||
// license: 'https://market.oceanprotocol.com/terms',
|
|
||||||
// algorithm
|
|
||||||
// },
|
|
||||||
// additionalInformation: {
|
|
||||||
// description,
|
|
||||||
// tags: transformTags(tags),
|
|
||||||
// termsAndConditions
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return metadata
|
|
||||||
// }
|
|
@ -8,7 +8,7 @@ export default function AdvancedSettings(prop: {
|
|||||||
content: FormStepContent
|
content: FormStepContent
|
||||||
handleFieldChange: (
|
handleFieldChange: (
|
||||||
e: ChangeEvent<HTMLInputElement>,
|
e: ChangeEvent<HTMLInputElement>,
|
||||||
field: FormFieldProps
|
field: FormFieldContent
|
||||||
) => void
|
) => void
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const [showAdvancedSettings, setShowAdvancedSettings] =
|
const [showAdvancedSettings, setShowAdvancedSettings] =
|
||||||
@ -30,7 +30,7 @@ export default function AdvancedSettings(prop: {
|
|||||||
</Button>
|
</Button>
|
||||||
{showAdvancedSettings &&
|
{showAdvancedSettings &&
|
||||||
prop.content.fields.map(
|
prop.content.fields.map(
|
||||||
(field: FormFieldProps) =>
|
(field: FormFieldContent) =>
|
||||||
field.advanced === true && (
|
field.advanced === true && (
|
||||||
<Field
|
<Field
|
||||||
key={field.name}
|
key={field.name}
|
||||||
|
@ -47,7 +47,7 @@ export default function BoxSelection({
|
|||||||
type="radio"
|
type="radio"
|
||||||
className={styleClassesInput}
|
className={styleClassesInput}
|
||||||
defaultChecked={value.checked}
|
defaultChecked={value.checked}
|
||||||
onChange={(event) => handleChange(event)}
|
// onChange={(event) => handleChange(event)}
|
||||||
{...props}
|
{...props}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
value={value.name}
|
value={value.name}
|
||||||
|
@ -15,10 +15,10 @@ export default function Datatoken(props: InputProps): ReactElement {
|
|||||||
|
|
||||||
// Generate new DT name & symbol on first mount
|
// Generate new DT name & symbol on first mount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (field.value.name !== '') return
|
if (field.value?.name !== '') return
|
||||||
|
|
||||||
generateName()
|
generateName()
|
||||||
}, [field.value.name])
|
}, [field.value?.name])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.datatoken}>
|
<div className={styles.datatoken}>
|
||||||
|
@ -6,7 +6,7 @@ import styles from './Terms.module.css'
|
|||||||
export default function Terms(props: InputProps): ReactElement {
|
export default function Terms(props: InputProps): ReactElement {
|
||||||
const termsProps: InputProps = {
|
const termsProps: InputProps = {
|
||||||
...props,
|
...props,
|
||||||
defaultChecked: props.value.toString() === 'true'
|
defaultChecked: props.value?.toString() === 'true'
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,11 +1,4 @@
|
|||||||
import React, {
|
import React, { ReactElement, ReactNode, useEffect, useState } from 'react'
|
||||||
FormEvent,
|
|
||||||
ChangeEvent,
|
|
||||||
ReactElement,
|
|
||||||
ReactNode,
|
|
||||||
useEffect,
|
|
||||||
useState
|
|
||||||
} from 'react'
|
|
||||||
import InputElement from './InputElement'
|
import InputElement from './InputElement'
|
||||||
import Label from './Label'
|
import Label from './Label'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
@ -17,8 +10,7 @@ import Markdown from '@shared/Markdown'
|
|||||||
|
|
||||||
const cx = classNames.bind(styles)
|
const cx = classNames.bind(styles)
|
||||||
|
|
||||||
export interface InputProps {
|
export interface InputProps extends FieldInputProps<any> {
|
||||||
name: string
|
|
||||||
label?: string | ReactNode
|
label?: string | ReactNode
|
||||||
placeholder?: string
|
placeholder?: string
|
||||||
required?: boolean
|
required?: boolean
|
||||||
@ -28,23 +20,7 @@ export interface InputProps {
|
|||||||
options?: string[]
|
options?: string[]
|
||||||
sortOptions?: boolean
|
sortOptions?: boolean
|
||||||
additionalComponent?: ReactElement
|
additionalComponent?: ReactElement
|
||||||
value?: string
|
|
||||||
onChange?(
|
|
||||||
e:
|
|
||||||
| FormEvent<HTMLInputElement>
|
|
||||||
| ChangeEvent<HTMLInputElement>
|
|
||||||
| ChangeEvent<HTMLSelectElement>
|
|
||||||
| ChangeEvent<HTMLTextAreaElement>
|
|
||||||
): void
|
|
||||||
onKeyPress?(
|
|
||||||
e:
|
|
||||||
| React.KeyboardEvent<HTMLInputElement>
|
|
||||||
| React.KeyboardEvent<HTMLInputElement>
|
|
||||||
| React.KeyboardEvent<HTMLSelectElement>
|
|
||||||
| React.KeyboardEvent<HTMLTextAreaElement>
|
|
||||||
): void
|
|
||||||
rows?: number
|
rows?: number
|
||||||
multiple?: boolean
|
|
||||||
pattern?: string
|
pattern?: string
|
||||||
min?: string
|
min?: string
|
||||||
max?: string
|
max?: string
|
||||||
@ -58,7 +34,6 @@ export interface InputProps {
|
|||||||
defaultChecked?: boolean
|
defaultChecked?: boolean
|
||||||
size?: 'mini' | 'small' | 'large' | 'default'
|
size?: 'mini' | 'small' | 'large' | 'default'
|
||||||
className?: string
|
className?: string
|
||||||
checked?: boolean
|
|
||||||
disclaimer?: string
|
disclaimer?: string
|
||||||
disclaimerValues?: string[]
|
disclaimerValues?: string[]
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ export default function FormStartCompute({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Form className={styles.form}>
|
<Form className={styles.form}>
|
||||||
{content.form.data.map((field: FormFieldProps) => (
|
{content.form.data.map((field: FormFieldContent) => (
|
||||||
<Field
|
<Field
|
||||||
key={field.name}
|
key={field.name}
|
||||||
{...field}
|
{...field}
|
||||||
|
@ -30,9 +30,9 @@ import axios from 'axios'
|
|||||||
import FormStartComputeDataset from './FormComputeDataset'
|
import FormStartComputeDataset from './FormComputeDataset'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import SuccessConfetti from '@shared/SuccessConfetti'
|
import SuccessConfetti from '@shared/SuccessConfetti'
|
||||||
import { secondsToString } from '@utils/metadata'
|
import { secondsToString } from '@utils/ddo'
|
||||||
import { AssetSelectionAsset } from '@shared/Form/FormFields/AssetSelection'
|
import { AssetSelectionAsset } from '@shared/Form/FormFields/AssetSelection'
|
||||||
import AlgorithmDatasetsListForCompute from '../../AssetContent/AlgorithmDatasetsListForCompute'
|
import AlgorithmDatasetsListForCompute from './AlgorithmDatasetsListForCompute'
|
||||||
import { getPreviousOrders, getPrice } from '@utils/subgraph'
|
import { getPreviousOrders, getPrice } from '@utils/subgraph'
|
||||||
import AssetActionHistoryTable from '../AssetActionHistoryTable'
|
import AssetActionHistoryTable from '../AssetActionHistoryTable'
|
||||||
import ComputeJobs from '../../../Profile/History/ComputeJobs'
|
import ComputeJobs from '../../../Profile/History/ComputeJobs'
|
||||||
|
@ -14,8 +14,8 @@ import { useWeb3 } from '@context/Web3'
|
|||||||
import { usePricing } from '@hooks/usePricing'
|
import { usePricing } from '@hooks/usePricing'
|
||||||
import { useConsume } from '@hooks/useConsume'
|
import { useConsume } from '@hooks/useConsume'
|
||||||
import ButtonBuy from '@shared/ButtonBuy'
|
import ButtonBuy from '@shared/ButtonBuy'
|
||||||
import { secondsToString } from '@utils/metadata'
|
import { secondsToString } from '@utils/ddo'
|
||||||
import AlgorithmDatasetsListForCompute from '../AssetContent/AlgorithmDatasetsListForCompute'
|
import AlgorithmDatasetsListForCompute from './Compute/AlgorithmDatasetsListForCompute'
|
||||||
import styles from './Consume.module.css'
|
import styles from './Consume.module.css'
|
||||||
import { useIsMounted } from '@hooks/useIsMounted'
|
import { useIsMounted } from '@hooks/useIsMounted'
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { ReactElement, useEffect, useState } from 'react'
|
import React, { ReactElement, useEffect, useState } from 'react'
|
||||||
import { Field, Form, FormikContextType, useFormikContext } from 'formik'
|
import { Field, Form, FormikContextType, useFormikContext } from 'formik'
|
||||||
import Input from '@shared/Form/Input'
|
import Input, { InputProps } from '@shared/Form/Input'
|
||||||
import { AssetSelectionAsset } from '@shared/Form/FormFields/AssetSelection'
|
import { AssetSelectionAsset } from '@shared/Form/FormFields/AssetSelection'
|
||||||
import stylesIndex from './index.module.css'
|
import stylesIndex from './index.module.css'
|
||||||
import styles from './FormEditMetadata.module.css'
|
import styles from './FormEditMetadata.module.css'
|
||||||
@ -22,7 +22,7 @@ export default function FormEditComputeDataset({
|
|||||||
title,
|
title,
|
||||||
setShowEdit
|
setShowEdit
|
||||||
}: {
|
}: {
|
||||||
data: FormFieldProps[]
|
data: InputProps[]
|
||||||
title: string
|
title: string
|
||||||
setShowEdit: (show: boolean) => void
|
setShowEdit: (show: boolean) => void
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
@ -64,7 +64,7 @@ export default function FormEditComputeDataset({
|
|||||||
return (
|
return (
|
||||||
<Form className={styles.form}>
|
<Form className={styles.form}>
|
||||||
<h3 className={stylesIndex.title}>{title}</h3>
|
<h3 className={stylesIndex.title}>{title}</h3>
|
||||||
{data.map((field: FormFieldProps) => (
|
{data.map((field: InputProps) => (
|
||||||
<Field
|
<Field
|
||||||
key={field.name}
|
key={field.name}
|
||||||
{...field}
|
{...field}
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import React, { ChangeEvent, ReactElement } from 'react'
|
import React, { ChangeEvent, ReactElement } from 'react'
|
||||||
import { Field, Form, FormikContextType, useFormikContext } from 'formik'
|
import { Field, Form, FormikContextType, useFormikContext } from 'formik'
|
||||||
import { useOcean } from '@context/Ocean'
|
import { useOcean } from '@context/Ocean'
|
||||||
import Input from '@shared/Form/Input'
|
import Input, { InputProps } from '@shared/Form/Input'
|
||||||
import { checkIfTimeoutInPredefinedValues } from '@utils/metadata'
|
import { checkIfTimeoutInPredefinedValues } from '@utils/ddo'
|
||||||
import FormActions from './FormActions'
|
import FormActions from './FormActions'
|
||||||
import styles from './FormEditMetadata.module.css'
|
import styles from './FormEditMetadata.module.css'
|
||||||
import { FormPublishData } from '../../../Publish/_types'
|
import { FormPublishData } from '../../../Publish/_types'
|
||||||
|
|
||||||
// function handleTimeoutCustomOption(
|
// function handleTimeoutCustomOption(
|
||||||
// data: FormFieldProps[],
|
// data: FormFieldContent[],
|
||||||
// values: Partial<FormPublishData>
|
// values: Partial<FormPublishData>
|
||||||
// ) {
|
// ) {
|
||||||
// const timeoutFieldContent = data.filter(
|
// const timeoutFieldContent = data.filter(
|
||||||
@ -48,7 +48,7 @@ export default function FormEditMetadata({
|
|||||||
showPrice,
|
showPrice,
|
||||||
isComputeDataset
|
isComputeDataset
|
||||||
}: {
|
}: {
|
||||||
data: FormFieldProps[]
|
data: InputProps[]
|
||||||
setShowEdit: (show: boolean) => void
|
setShowEdit: (show: boolean) => void
|
||||||
setTimeoutStringValue: (value: string) => void
|
setTimeoutStringValue: (value: string) => void
|
||||||
values: Partial<FormPublishData>
|
values: Partial<FormPublishData>
|
||||||
@ -65,7 +65,7 @@ export default function FormEditMetadata({
|
|||||||
// Workaround for default `validateOnChange` not kicking in
|
// Workaround for default `validateOnChange` not kicking in
|
||||||
function handleFieldChange(
|
function handleFieldChange(
|
||||||
e: ChangeEvent<HTMLInputElement>,
|
e: ChangeEvent<HTMLInputElement>,
|
||||||
field: FormFieldProps
|
field: InputProps
|
||||||
) {
|
) {
|
||||||
validateField(field.name)
|
validateField(field.name)
|
||||||
setFieldValue(field.name, e.target.value)
|
setFieldValue(field.name, e.target.value)
|
||||||
@ -89,7 +89,7 @@ export default function FormEditMetadata({
|
|||||||
return (
|
return (
|
||||||
<Form className={styles.form}>
|
<Form className={styles.form}>
|
||||||
{data.map(
|
{data.map(
|
||||||
(field: FormFieldProps) =>
|
(field: InputProps) =>
|
||||||
(!showPrice && field.name === 'price') || (
|
(!showPrice && field.name === 'price') || (
|
||||||
<Field
|
<Field
|
||||||
key={field.name}
|
key={field.name}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { secondsToString } from '@utils/metadata'
|
import { secondsToString } from '@utils/ddo'
|
||||||
import { EditableMetadataLinks } from '@oceanprotocol/lib'
|
import { EditableMetadataLinks } from '@oceanprotocol/lib'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import { useUserPreferences } from '@context/UserPreferences'
|
|||||||
// import Debug from './DebugEditMetadata'
|
// import Debug from './DebugEditMetadata'
|
||||||
import Web3Feedback from '@shared/Web3Feedback'
|
import Web3Feedback from '@shared/Web3Feedback'
|
||||||
import FormEditMetadata from './FormEditMetadata'
|
import FormEditMetadata from './FormEditMetadata'
|
||||||
import { mapTimeoutStringToSeconds } from '@utils/metadata'
|
import { mapTimeoutStringToSeconds } from '@utils/ddo'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import { Logger } from '@oceanprotocol/lib'
|
import { Logger } from '@oceanprotocol/lib'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useWeb3 } from '@context/Web3'
|
||||||
|
@ -8,7 +8,7 @@ import React, {
|
|||||||
// import { useStaticQuery, graphql } from 'gatsby'
|
// import { useStaticQuery, graphql } from 'gatsby'
|
||||||
// import { useFormikContext, Field, Form, FormikContextType } from 'formik'
|
// import { useFormikContext, Field, Form, FormikContextType } from 'formik'
|
||||||
// import Input from '../../atoms/Input'
|
// import Input from '../../atoms/Input'
|
||||||
// import { FormContent, FormFieldProps } from '../../../@types/Form'
|
// import { FormContent, FormFieldContent } from '../../../@types/Form'
|
||||||
// import { MetadataPublishFormAlgorithm } from '../../../@types/MetaData'
|
// import { MetadataPublishFormAlgorithm } from '../../../@types/MetaData'
|
||||||
// import { initialValues as initialValuesAlgorithm } from '../../../@types/FormAlgoPublish'
|
// import { initialValues as initialValuesAlgorithm } from '../../../@types/FormAlgoPublish'
|
||||||
// import AdvancedSettings from '../../molecules/FormFields/AdvancedSettings'
|
// import AdvancedSettings from '../../molecules/FormFields/AdvancedSettings'
|
||||||
@ -116,7 +116,7 @@ import React, {
|
|||||||
// // Workaround for default `validateOnChange` not kicking in
|
// // Workaround for default `validateOnChange` not kicking in
|
||||||
// function handleFieldChange(
|
// function handleFieldChange(
|
||||||
// e: ChangeEvent<HTMLInputElement>,
|
// e: ChangeEvent<HTMLInputElement>,
|
||||||
// field: FormFieldProps
|
// field: InputProps
|
||||||
// ) {
|
// ) {
|
||||||
// const value =
|
// const value =
|
||||||
// field.type === 'checkbox' || field.type === 'terms'
|
// field.type === 'checkbox' || field.type === 'terms'
|
||||||
@ -148,7 +148,7 @@ import React, {
|
|||||||
// <FormTitle title={content.title} />
|
// <FormTitle title={content.title} />
|
||||||
|
|
||||||
// {content.data.map(
|
// {content.data.map(
|
||||||
// (field: FormFieldProps) =>
|
// (field: InputProps) =>
|
||||||
// field.advanced !== true &&
|
// field.advanced !== true &&
|
||||||
// ((field.name !== 'entrypoint' &&
|
// ((field.name !== 'entrypoint' &&
|
||||||
// field.name !== 'image' &&
|
// field.name !== 'image' &&
|
||||||
|
@ -2,18 +2,45 @@ import Input from '@shared/Form/Input'
|
|||||||
import { Field } from 'formik'
|
import { Field } from 'formik'
|
||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import content from '../../../../../content/publish/form.json'
|
import content from '../../../../../content/publish/form.json'
|
||||||
|
import { getFieldContent } from '../../_utils'
|
||||||
|
|
||||||
export default function MetadataFields(): ReactElement {
|
export default function MetadataFields(): ReactElement {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{content.metadata.fields.map((field: FormFieldProps) => (
|
<Field
|
||||||
|
{...getFieldContent('name', content.metadata.fields)}
|
||||||
|
component={Input}
|
||||||
|
name="metadata.name"
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
{...getFieldContent('description', content.metadata.fields)}
|
||||||
|
component={Input}
|
||||||
|
name="metadata.description"
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
{...getFieldContent('author', content.metadata.fields)}
|
||||||
|
component={Input}
|
||||||
|
name="metadata.author"
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
{...getFieldContent('tags', content.metadata.fields)}
|
||||||
|
component={Input}
|
||||||
|
name="metadata.tags"
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
{...getFieldContent('termsAndConditions', content.metadata.fields)}
|
||||||
|
component={Input}
|
||||||
|
name="metadata.termsAndConditions"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* {content.metadata.fields.map((field: FormFieldContent) => (
|
||||||
<Field
|
<Field
|
||||||
{...field}
|
{...field}
|
||||||
key={`metadata-${field.name}`}
|
key={`metadata-${field.name}`}
|
||||||
component={Input}
|
component={Input}
|
||||||
name={`metadata.${field.name}`}
|
name={`metadata.${field.name}`}
|
||||||
/>
|
/>
|
||||||
))}
|
))} */}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import Tags from '@shared/atoms/Tags'
|
|||||||
import MetaItem from '../../../Asset/AssetContent/MetaItem'
|
import MetaItem from '../../../Asset/AssetContent/MetaItem'
|
||||||
import FileIcon from '@shared/FileIcon'
|
import FileIcon from '@shared/FileIcon'
|
||||||
import Button from '@shared/atoms/Button'
|
import Button from '@shared/atoms/Button'
|
||||||
import { transformTags } from '@utils/metadata'
|
import { transformTags } from '@utils/ddo'
|
||||||
import NetworkName from '@shared/NetworkName'
|
import NetworkName from '@shared/NetworkName'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useWeb3 } from '@context/Web3'
|
||||||
import styles from './MetadataPreview.module.css'
|
import styles from './MetadataPreview.module.css'
|
||||||
|
@ -4,6 +4,7 @@ import React, { ReactElement } from 'react'
|
|||||||
import IconDownload from '@images/download.svg'
|
import IconDownload from '@images/download.svg'
|
||||||
import IconCompute from '@images/compute.svg'
|
import IconCompute from '@images/compute.svg'
|
||||||
import content from '../../../../../content/publish/form.json'
|
import content from '../../../../../content/publish/form.json'
|
||||||
|
import { getFieldContent } from '../../_utils'
|
||||||
|
|
||||||
const accessTypeOptions = [
|
const accessTypeOptions = [
|
||||||
{
|
{
|
||||||
@ -21,8 +22,45 @@ const accessTypeOptions = [
|
|||||||
export default function ServicesFields(): ReactElement {
|
export default function ServicesFields(): ReactElement {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{content.services.fields.map(
|
<Field
|
||||||
(field: FormFieldProps) =>
|
{...getFieldContent('dataTokenOptions', content.services.fields)}
|
||||||
|
component={Input}
|
||||||
|
name="services[0].dataTokenOptions"
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
{...getFieldContent('files', content.services.fields)}
|
||||||
|
component={Input}
|
||||||
|
name="services[0].files"
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
{...getFieldContent('links', content.services.fields)}
|
||||||
|
component={Input}
|
||||||
|
name="services[0].links"
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
{...getFieldContent('links', content.services.fields)}
|
||||||
|
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"
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
{...getFieldContent('providerUri', content.services.fields)}
|
||||||
|
component={Input}
|
||||||
|
name="services[0].providerUri"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* {content.services.fields.map(
|
||||||
|
(field: FormFieldContent) =>
|
||||||
field.advanced !== true && (
|
field.advanced !== true && (
|
||||||
<Field
|
<Field
|
||||||
{...field}
|
{...field}
|
||||||
@ -34,7 +72,7 @@ export default function ServicesFields(): ReactElement {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
)}
|
)} */}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { DataTokenOptions } from '@hooks/usePublish'
|
import { DataTokenOptions } from '@hooks/usePublish'
|
||||||
import { EditableMetadataLinks } from '@oceanprotocol/lib'
|
import { EditableMetadataLinks, File } from '@oceanprotocol/lib'
|
||||||
|
|
||||||
export interface FormPublishService {
|
export interface FormPublishService {
|
||||||
files: string | File[]
|
files: string | File[]
|
||||||
@ -7,6 +7,9 @@ export interface FormPublishService {
|
|||||||
timeout: string
|
timeout: string
|
||||||
dataTokenOptions: DataTokenOptions
|
dataTokenOptions: DataTokenOptions
|
||||||
access: 'Download' | 'Compute' | string
|
access: 'Download' | 'Compute' | string
|
||||||
|
image?: string
|
||||||
|
containerTag?: string
|
||||||
|
entrypoint?: string
|
||||||
providerUri?: string
|
providerUri?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
56
src/components/Publish/_utils.ts
Normal file
56
src/components/Publish/_utils.ts
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import {
|
||||||
|
dateToStringNoMS,
|
||||||
|
transformTags,
|
||||||
|
getAlgorithmComponent,
|
||||||
|
getAlgorithmFileExtension
|
||||||
|
} from '@utils/ddo'
|
||||||
|
import { FormPublishData } from './_types'
|
||||||
|
|
||||||
|
export function getFieldContent(
|
||||||
|
fieldName: string,
|
||||||
|
fields: FormFieldContent[]
|
||||||
|
): FormFieldContent {
|
||||||
|
return fields.filter((field: FormFieldContent) => field.name === fieldName)[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function transformPublishFormToDdo(
|
||||||
|
data: Partial<FormPublishData>,
|
||||||
|
ddo?: DdoMarket
|
||||||
|
): DdoMarket {
|
||||||
|
const currentTime = dateToStringNoMS(new Date())
|
||||||
|
const { type } = data
|
||||||
|
const { name, description, tags, author, termsAndConditions } = data.metadata
|
||||||
|
const { files, links, image, containerTag, entrypoint, providerUri } =
|
||||||
|
data.services[0]
|
||||||
|
|
||||||
|
const fileUrl = typeof files !== 'string' && files[0].url
|
||||||
|
const algorithmLanguage = getAlgorithmFileExtension(fileUrl)
|
||||||
|
const algorithm = getAlgorithmComponent(
|
||||||
|
image,
|
||||||
|
containerTag,
|
||||||
|
entrypoint,
|
||||||
|
algorithmLanguage
|
||||||
|
)
|
||||||
|
|
||||||
|
const service = {
|
||||||
|
files: typeof files !== 'string' && files,
|
||||||
|
links: typeof links !== 'string' ? links : [],
|
||||||
|
...(type === 'algorithm' && { ...algorithm })
|
||||||
|
}
|
||||||
|
|
||||||
|
const newDdo: DdoMarket = {
|
||||||
|
metadata: {
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
tags: transformTags(tags),
|
||||||
|
author,
|
||||||
|
dateCreated: ddo ? ddo.metadata.dateCreated : currentTime,
|
||||||
|
datePublished: '',
|
||||||
|
termsAndConditions,
|
||||||
|
license: 'https://market.oceanprotocol.com/terms'
|
||||||
|
},
|
||||||
|
services: [service]
|
||||||
|
}
|
||||||
|
|
||||||
|
return newDdo
|
||||||
|
}
|
@ -2,15 +2,12 @@ import React, { ReactElement, useState, useEffect } from 'react'
|
|||||||
import { Formik, FormikState } from 'formik'
|
import { Formik, FormikState } from 'formik'
|
||||||
import { usePublish } from '@hooks/usePublish'
|
import { usePublish } from '@hooks/usePublish'
|
||||||
import { initialValues, validationSchema } from './_constants'
|
import { initialValues, validationSchema } from './_constants'
|
||||||
// import {
|
import { validateDockerImage } from '@utils/docker'
|
||||||
// transformPublishFormToMetadata,
|
|
||||||
// mapTimeoutStringToSeconds,
|
|
||||||
// validateDockerImage
|
|
||||||
// } from '@utils/metadata'
|
|
||||||
import { Logger, Metadata } from '@oceanprotocol/lib'
|
import { Logger, Metadata } from '@oceanprotocol/lib'
|
||||||
import { useAccountPurgatory } from '@hooks/useAccountPurgatory'
|
import { useAccountPurgatory } from '@hooks/useAccountPurgatory'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useWeb3 } from '@context/Web3'
|
||||||
import { FormPublishData } from './_types'
|
import { FormPublishData } from './_types'
|
||||||
|
import { transformPublishFormToDdo } from './_utils'
|
||||||
import PageHeader from '@shared/Page/PageHeader'
|
import PageHeader from '@shared/Page/PageHeader'
|
||||||
import Title from './Title'
|
import Title from './Title'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
|
Loading…
Reference in New Issue
Block a user