mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
file input validation fixes
This commit is contained in:
parent
c484a5b40c
commit
a313f39494
@ -92,10 +92,11 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "providerUrl",
|
"name": "providerUrl",
|
||||||
"label": "Custom Provider URL",
|
"label": "Provider URL",
|
||||||
"type": "providerUrl",
|
"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/).",
|
"help": "Enter the URL for your custom [provider](https://github.com/oceanprotocol/provider/) or leave as is to use the default one. If you change your provider URL after adding your file, please add & validate your file again.",
|
||||||
"placeholder": "e.g. https://provider.polygon.oceanprotocol.com/"
|
"placeholder": "e.g. https://provider.oceanprotocol.com/",
|
||||||
|
"required": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "files",
|
"name": "files",
|
||||||
|
@ -2,7 +2,7 @@ import React, { ReactElement, useState, useEffect } from 'react'
|
|||||||
import { useField } from 'formik'
|
import { useField } from 'formik'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
import FileInfo from './Info'
|
import FileInfo from './Info'
|
||||||
import CustomInput from '../URLInput/Input'
|
import UrlInput from '../URLInput/Input'
|
||||||
import { InputProps } from '@shared/FormInput'
|
import { InputProps } from '@shared/FormInput'
|
||||||
import { getFileInfo } from '@utils/provider'
|
import { getFileInfo } from '@utils/provider'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useWeb3 } from '@context/Web3'
|
||||||
@ -61,13 +61,15 @@ export default function FilesInput(props: InputProps): ReactElement {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{field?.value && field.value[0] && typeof field.value === 'object' ? (
|
{field?.value && field.value[0].url !== '' && field.value[0].valid ? (
|
||||||
<FileInfo name={props.name} file={field.value[0]} />
|
<FileInfo name={props.name} file={field.value[0]} />
|
||||||
) : (
|
) : (
|
||||||
<CustomInput
|
<UrlInput
|
||||||
submitText="Add File"
|
submitText="Add File"
|
||||||
{...props}
|
{...props}
|
||||||
{...field}
|
{...field}
|
||||||
|
name={`${props.name}[0].url`}
|
||||||
|
value={field?.value && field.value[0].url}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
handleButtonClick={handleButtonClick}
|
handleButtonClick={handleButtonClick}
|
||||||
/>
|
/>
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
.input {
|
.input {
|
||||||
composes: input from '@shared/FormInput/InputElement.module.css';
|
composes: input from '@shared/FormInput/InputElement.module.css';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hasError {
|
||||||
|
color: var(--brand-alert-red);
|
||||||
|
border-color: var(--brand-alert-red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
composes: error from '@shared/FormInput/index.module.css';
|
||||||
|
}
|
||||||
|
@ -1,40 +1,59 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import Button from '@shared/atoms/Button'
|
import Button from '@shared/atoms/Button'
|
||||||
import { FieldInputProps, useField } from 'formik'
|
import { ErrorMessage, FieldInputProps, useField } from 'formik'
|
||||||
import Loader from '@shared/atoms/Loader'
|
import Loader from '@shared/atoms/Loader'
|
||||||
import styles from './Input.module.css'
|
import styles from './Input.module.css'
|
||||||
import InputGroup from '@shared/FormInput/InputGroup'
|
import InputGroup from '@shared/FormInput/InputGroup'
|
||||||
|
import InputElement from '@shared/FormInput/InputElement'
|
||||||
|
|
||||||
export default function URLInput({
|
export default function URLInput({
|
||||||
submitText,
|
submitText,
|
||||||
handleButtonClick,
|
handleButtonClick,
|
||||||
isLoading,
|
isLoading,
|
||||||
|
name,
|
||||||
|
value,
|
||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
submitText: string
|
submitText: string
|
||||||
handleButtonClick(e: React.SyntheticEvent, data: string): void
|
handleButtonClick(e: React.SyntheticEvent, data: string): void
|
||||||
isLoading: boolean
|
isLoading: boolean
|
||||||
|
name: string
|
||||||
|
value: string
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const [field, meta] = useField(props as FieldInputProps<any>)
|
const [field, meta] = useField(name)
|
||||||
const isButtonDisabled =
|
const isButtonDisabled =
|
||||||
!field.value || field.value.length === 0 || field.value === ''
|
!field.value || field.value.length === 0 || field.value === ''
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<input
|
<InputElement
|
||||||
className={styles.input}
|
className={`${styles.input} ${
|
||||||
|
meta.touched && meta.error ? styles.hasError : ''
|
||||||
|
}`}
|
||||||
{...props}
|
{...props}
|
||||||
|
name={name}
|
||||||
|
value={value}
|
||||||
type="url"
|
type="url"
|
||||||
onBlur={(e: React.SyntheticEvent) => handleButtonClick(e, field.value)}
|
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
style="primary"
|
style="primary"
|
||||||
size="small"
|
size="small"
|
||||||
onClick={(e: React.SyntheticEvent) => e.preventDefault()}
|
onClick={(e: React.SyntheticEvent) => {
|
||||||
|
e.preventDefault()
|
||||||
|
handleButtonClick(e, field.value)
|
||||||
|
}}
|
||||||
disabled={isButtonDisabled}
|
disabled={isButtonDisabled}
|
||||||
>
|
>
|
||||||
{isLoading ? <Loader /> : submitText}
|
{isLoading ? <Loader /> : submitText}
|
||||||
</Button>
|
</Button>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
|
||||||
|
{meta.touched && meta.error && (
|
||||||
|
<div className={styles.error}>
|
||||||
|
<ErrorMessage name={field.name} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,6 @@ export const initialValues: FormPublishData = {
|
|||||||
author: '',
|
author: '',
|
||||||
description: '',
|
description: '',
|
||||||
tags: '',
|
tags: '',
|
||||||
links: [],
|
|
||||||
termsAndConditions: false,
|
termsAndConditions: false,
|
||||||
dockerImage: '',
|
dockerImage: '',
|
||||||
dockerImageCustom: '',
|
dockerImageCustom: '',
|
||||||
@ -53,7 +52,8 @@ export const initialValues: FormPublishData = {
|
|||||||
},
|
},
|
||||||
services: [
|
services: [
|
||||||
{
|
{
|
||||||
files: undefined,
|
files: [{ url: '' }],
|
||||||
|
links: [{ url: '' }],
|
||||||
dataTokenOptions: { name: '', symbol: '' },
|
dataTokenOptions: { name: '', symbol: '' },
|
||||||
timeout: '',
|
timeout: '',
|
||||||
access: '',
|
access: '',
|
||||||
@ -94,10 +94,23 @@ const validationMetadata = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const validationService = {
|
const validationService = {
|
||||||
files: Yup.array<string[]>()
|
files: Yup.array<{ url: string; valid: boolean }[]>()
|
||||||
.required('Enter a valid URL and click "ADD FILE"')
|
.of(
|
||||||
|
Yup.object().shape({
|
||||||
|
url: Yup.string().required('Required'),
|
||||||
|
valid: Yup.boolean().isTrue().required('File must be valid.')
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.min(1, (param) => `At least one file is required`)
|
||||||
|
.required('Enter a valid URL and click "ADD FILE"'),
|
||||||
|
links: Yup.array<{ url: string; valid: boolean }[]>()
|
||||||
|
.of(
|
||||||
|
Yup.object().shape({
|
||||||
|
url: Yup.string().required('Required'),
|
||||||
|
valid: Yup.boolean().isTrue().required('File must be valid.')
|
||||||
|
})
|
||||||
|
)
|
||||||
.nullable(),
|
.nullable(),
|
||||||
links: Yup.array<string[]>().nullable(),
|
|
||||||
dataTokenOptions: Yup.object().shape({
|
dataTokenOptions: Yup.object().shape({
|
||||||
name: Yup.string(),
|
name: Yup.string(),
|
||||||
symbol: Yup.string()
|
symbol: Yup.string()
|
||||||
|
@ -2,13 +2,16 @@ import { DataTokenOptions } from '@utils/datatokens'
|
|||||||
import { NftOptions } from '@utils/nft'
|
import { NftOptions } from '@utils/nft'
|
||||||
import { ReactElement } from 'react'
|
import { ReactElement } from 'react'
|
||||||
|
|
||||||
export interface FormPublishService {
|
interface FileMetadata {
|
||||||
files: {
|
|
||||||
url: string
|
url: string
|
||||||
valid: boolean
|
valid?: boolean
|
||||||
contentLength: string
|
contentLength?: string
|
||||||
contentType: string
|
contentType?: string
|
||||||
}[]
|
}
|
||||||
|
|
||||||
|
export interface FormPublishService {
|
||||||
|
files: FileMetadata[]
|
||||||
|
links?: FileMetadata[]
|
||||||
timeout: string
|
timeout: string
|
||||||
dataTokenOptions: DataTokenOptions
|
dataTokenOptions: DataTokenOptions
|
||||||
access: 'Download' | 'Compute' | string
|
access: 'Download' | 'Compute' | string
|
||||||
@ -30,7 +33,6 @@ export interface FormPublishData {
|
|||||||
author: string
|
author: string
|
||||||
termsAndConditions: boolean
|
termsAndConditions: boolean
|
||||||
tags?: string
|
tags?: string
|
||||||
links?: string[]
|
|
||||||
dockerImage?: string
|
dockerImage?: string
|
||||||
dockerImageCustom?: string
|
dockerImageCustom?: string
|
||||||
dockerImageCustomTag?: string
|
dockerImageCustomTag?: string
|
||||||
|
@ -42,21 +42,17 @@ export async function transformPublishFormToDdo(
|
|||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
tags,
|
tags,
|
||||||
links,
|
|
||||||
author,
|
author,
|
||||||
termsAndConditions,
|
termsAndConditions,
|
||||||
dockerImageCustom,
|
dockerImageCustom,
|
||||||
dockerImageCustomTag,
|
dockerImageCustomTag,
|
||||||
dockerImageCustomEntrypoint
|
dockerImageCustomEntrypoint
|
||||||
} = metadata
|
} = metadata
|
||||||
const { access, files, providerUrl, timeout } = services[0]
|
const { access, files, links, providerUrl, timeout } = services[0]
|
||||||
|
|
||||||
const filesTransformed = files?.length && files[0].valid && [...files[0].url]
|
// Transform from files[0].url to string[] assuming only 1 file
|
||||||
|
const filesTransformed = files?.length && files[0].valid && [files[0].url]
|
||||||
const filesEncrypted =
|
const linksTransformed = links?.length && links[0].valid && [links[0].url]
|
||||||
files?.length &&
|
|
||||||
files[0].valid &&
|
|
||||||
(await getEncryptedFileUrls(filesTransformed, providerUrl, did, accountId))
|
|
||||||
|
|
||||||
const newMetadata: Metadata = {
|
const newMetadata: Metadata = {
|
||||||
created: currentTime,
|
created: currentTime,
|
||||||
@ -67,7 +63,7 @@ export async function transformPublishFormToDdo(
|
|||||||
tags: transformTags(tags),
|
tags: transformTags(tags),
|
||||||
author,
|
author,
|
||||||
license: 'https://market.oceanprotocol.com/terms',
|
license: 'https://market.oceanprotocol.com/terms',
|
||||||
links,
|
links: linksTransformed,
|
||||||
additionalInformation: {
|
additionalInformation: {
|
||||||
termsAndConditions
|
termsAndConditions
|
||||||
},
|
},
|
||||||
@ -85,9 +81,15 @@ export async function transformPublishFormToDdo(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encypt just created string[] of urls
|
||||||
|
const filesEncrypted =
|
||||||
|
files?.length &&
|
||||||
|
files[0].valid &&
|
||||||
|
(await getEncryptedFileUrls(filesTransformed, providerUrl, did, accountId))
|
||||||
|
|
||||||
const newService: Service = {
|
const newService: Service = {
|
||||||
type: access,
|
type: access,
|
||||||
files: filesEncrypted,
|
files: filesEncrypted || '',
|
||||||
datatokenAddress,
|
datatokenAddress,
|
||||||
serviceEndpoint: providerUrl,
|
serviceEndpoint: providerUrl,
|
||||||
timeout: mapTimeoutStringToSeconds(timeout),
|
timeout: mapTimeoutStringToSeconds(timeout),
|
||||||
|
Loading…
Reference in New Issue
Block a user