mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
more fields, more custom onChange handler removals
This commit is contained in:
parent
66adc097b6
commit
778abc8aeb
@ -31,7 +31,7 @@
|
|||||||
{
|
{
|
||||||
"name": "termsAndConditions",
|
"name": "termsAndConditions",
|
||||||
"label": "Terms & Conditions",
|
"label": "Terms & Conditions",
|
||||||
"type": "terms",
|
"type": "checkbox",
|
||||||
"options": ["I agree to these Terms and Conditions"],
|
"options": ["I agree to these Terms and Conditions"],
|
||||||
"required": true
|
"required": true
|
||||||
}
|
}
|
||||||
@ -40,6 +40,20 @@
|
|||||||
"services": {
|
"services": {
|
||||||
"title": "Access",
|
"title": "Access",
|
||||||
"fields": [
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "type",
|
||||||
|
"label": "Asset Type",
|
||||||
|
"type": "boxSelection",
|
||||||
|
"options": ["Dataset", "Algorithm"],
|
||||||
|
"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": "dataTokenOptions",
|
"name": "dataTokenOptions",
|
||||||
"label": "Datatoken Name & Symbol",
|
"label": "Datatoken Name & Symbol",
|
||||||
@ -95,8 +109,11 @@
|
|||||||
"title": "Pricing",
|
"title": "Pricing",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"name": "dummy content, as content is defined under 'create' key in ../price.json"
|
"name": "dummy content, actual content is defined under 'create' key in ../price.json"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"preview": {
|
||||||
|
"title": "Preview"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,27 +40,27 @@ export default function BoxSelection({
|
|||||||
{!options ? (
|
{!options ? (
|
||||||
<Loader />
|
<Loader />
|
||||||
) : (
|
) : (
|
||||||
options.map((value: BoxSelectionOption) => (
|
options.map((option: BoxSelectionOption) => (
|
||||||
<div key={value.name}>
|
<div key={option.name}>
|
||||||
<input
|
<input
|
||||||
id={value.name}
|
id={option.name}
|
||||||
type="radio"
|
type="radio"
|
||||||
className={styleClassesInput}
|
className={styleClassesInput}
|
||||||
defaultChecked={value.checked}
|
defaultChecked={option.checked}
|
||||||
// onChange={(event) => handleChange(event)}
|
onChange={(event) => handleChange(event)}
|
||||||
{...props}
|
{...props}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
value={value.name}
|
value={option.name}
|
||||||
name={name}
|
name={name}
|
||||||
/>
|
/>
|
||||||
<label
|
<label
|
||||||
className={`${styles.boxSelection} ${styles.label}`}
|
className={`${styles.boxSelection} ${styles.label}`}
|
||||||
htmlFor={value.name}
|
htmlFor={option.name}
|
||||||
title={value.name}
|
title={option.name}
|
||||||
>
|
>
|
||||||
{value.icon}
|
{option.icon}
|
||||||
<span className={styles.title}>{value.title}</span>
|
<span className={styles.title}>{option.title}</span>
|
||||||
{value.text}
|
{option.text}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
.terms {
|
|
||||||
composes: content from '@shared/Page/PageMarkdown.module.css';
|
|
||||||
|
|
||||||
padding: calc(var(--spacer) / 2);
|
|
||||||
border: 1px solid var(--border-color);
|
|
||||||
background-color: var(--background-highlight);
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
margin-bottom: calc(var(--spacer) / 2);
|
|
||||||
font-size: var(--font-size-small);
|
|
||||||
|
|
||||||
max-height: 250px;
|
|
||||||
/* smooth overflow scrolling for pre-iOS 13 */
|
|
||||||
overflow: auto;
|
|
||||||
-webkit-overflow-scrolling: touch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.terms h1 {
|
|
||||||
font-size: var(--font-size-base);
|
|
||||||
margin-bottom: calc(var(--spacer) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.terms h2 {
|
|
||||||
font-size: var(--font-size-small);
|
|
||||||
margin-bottom: calc(var(--spacer) / 2);
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
import React, { ReactElement } from 'react'
|
|
||||||
import { InputProps } from '@shared/Form/Input'
|
|
||||||
import InputElement from '@shared/Form/Input/InputElement'
|
|
||||||
import styles from './Terms.module.css'
|
|
||||||
|
|
||||||
export default function Terms(props: InputProps): ReactElement {
|
|
||||||
const termsProps: InputProps = {
|
|
||||||
...props,
|
|
||||||
defaultChecked: props.value?.toString() === 'true'
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<InputElement {...termsProps} type="checkbox" />
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
@ -4,7 +4,6 @@ import styles from './InputElement.module.css'
|
|||||||
import { InputProps } from '.'
|
import { InputProps } from '.'
|
||||||
import FilesInput from '../FormFields/FilesInput'
|
import FilesInput from '../FormFields/FilesInput'
|
||||||
import CustomProvider from '../FormFields/CustomProvider'
|
import CustomProvider from '../FormFields/CustomProvider'
|
||||||
import Terms from '../FormFields/Terms'
|
|
||||||
import BoxSelection, { BoxSelectionOption } from '../FormFields/BoxSelection'
|
import BoxSelection, { BoxSelectionOption } from '../FormFields/BoxSelection'
|
||||||
import Datatoken from '../FormFields/Datatoken'
|
import Datatoken from '../FormFields/Datatoken'
|
||||||
import classNames from 'classnames/bind'
|
import classNames from 'classnames/bind'
|
||||||
@ -54,7 +53,9 @@ export default function InputElement({
|
|||||||
const sortedOptions =
|
const sortedOptions =
|
||||||
!sortOptions && sortOptions === false
|
!sortOptions && sortOptions === false
|
||||||
? options
|
? options
|
||||||
: options.sort((a: string, b: string) => a.localeCompare(b))
|
: (options as string[]).sort((a: string, b: string) =>
|
||||||
|
a.localeCompare(b)
|
||||||
|
)
|
||||||
return (
|
return (
|
||||||
<select
|
<select
|
||||||
id={name}
|
id={name}
|
||||||
@ -67,7 +68,7 @@ export default function InputElement({
|
|||||||
<option value="">---</option>
|
<option value="">---</option>
|
||||||
)}
|
)}
|
||||||
{sortedOptions &&
|
{sortedOptions &&
|
||||||
sortedOptions.map((option: string, index: number) => (
|
(sortedOptions as string[]).map((option: string, index: number) => (
|
||||||
<option key={index} value={option}>
|
<option key={index} value={option}>
|
||||||
{option} {postfix}
|
{option} {postfix}
|
||||||
</option>
|
</option>
|
||||||
@ -89,7 +90,7 @@ export default function InputElement({
|
|||||||
return (
|
return (
|
||||||
<div className={styles.radioGroup}>
|
<div className={styles.radioGroup}>
|
||||||
{options &&
|
{options &&
|
||||||
options.map((option: string, index: number) => (
|
(options as string[]).map((option: string, index: number) => (
|
||||||
<div className={styles.radioWrap} key={index}>
|
<div className={styles.radioWrap} key={index}>
|
||||||
<input
|
<input
|
||||||
className={styles[type]}
|
className={styles[type]}
|
||||||
@ -133,8 +134,6 @@ export default function InputElement({
|
|||||||
return <CustomProvider name={name} {...field} {...props} />
|
return <CustomProvider name={name} {...field} {...props} />
|
||||||
case 'datatoken':
|
case 'datatoken':
|
||||||
return <Datatoken name={name} {...field} {...props} />
|
return <Datatoken name={name} {...field} {...props} />
|
||||||
case 'terms':
|
|
||||||
return <Terms name={name} options={options} {...field} {...props} />
|
|
||||||
case 'boxSelection':
|
case 'boxSelection':
|
||||||
return (
|
return (
|
||||||
<BoxSelection
|
<BoxSelection
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
import React, { ReactElement, ReactNode, useEffect, useState } from 'react'
|
import React, {
|
||||||
|
ChangeEvent,
|
||||||
|
FormEvent,
|
||||||
|
KeyboardEvent,
|
||||||
|
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'
|
||||||
@ -10,7 +18,8 @@ import Markdown from '@shared/Markdown'
|
|||||||
|
|
||||||
const cx = classNames.bind(styles)
|
const cx = classNames.bind(styles)
|
||||||
|
|
||||||
export interface InputProps extends FieldInputProps<any> {
|
export interface InputProps {
|
||||||
|
name: string
|
||||||
label?: string | ReactNode
|
label?: string | ReactNode
|
||||||
placeholder?: string
|
placeholder?: string
|
||||||
required?: boolean
|
required?: boolean
|
||||||
@ -20,7 +29,23 @@ export interface InputProps extends FieldInputProps<any> {
|
|||||||
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:
|
||||||
|
| KeyboardEvent<HTMLInputElement>
|
||||||
|
| KeyboardEvent<HTMLInputElement>
|
||||||
|
| KeyboardEvent<HTMLSelectElement>
|
||||||
|
| KeyboardEvent<HTMLTextAreaElement>
|
||||||
|
): void
|
||||||
rows?: number
|
rows?: number
|
||||||
|
multiple?: boolean
|
||||||
pattern?: string
|
pattern?: string
|
||||||
min?: string
|
min?: string
|
||||||
max?: string
|
max?: string
|
||||||
@ -34,6 +59,7 @@ export interface InputProps extends FieldInputProps<any> {
|
|||||||
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[]
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
import Input from '@shared/Form/Input'
|
import Input from '@shared/Form/Input'
|
||||||
import { Field } from 'formik'
|
import { Field, useFormikContext } 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 { FormPublishData } from '../../_types'
|
||||||
import { getFieldContent } from '../../_utils'
|
import { getFieldContent } from '../../_utils'
|
||||||
|
|
||||||
export default function MetadataFields(): ReactElement {
|
export default function MetadataFields(): ReactElement {
|
||||||
|
// connect with Form state, use for conditional field rendering
|
||||||
|
const { values } = useFormikContext<FormPublishData>()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Field
|
<Field
|
||||||
@ -27,6 +31,16 @@ export default function MetadataFields(): ReactElement {
|
|||||||
component={Input}
|
component={Input}
|
||||||
name="metadata.tags"
|
name="metadata.tags"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<strong>Fancy NFT display</strong>
|
||||||
|
<p>
|
||||||
|
Place to show that metadata becomes part of a NFT. Plan is to
|
||||||
|
autogenerate some graphic, display it here, and pass that graphic to
|
||||||
|
the publish methods.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Field
|
<Field
|
||||||
{...getFieldContent('termsAndConditions', content.metadata.fields)}
|
{...getFieldContent('termsAndConditions', content.metadata.fields)}
|
||||||
component={Input}
|
component={Input}
|
||||||
|
@ -8,10 +8,11 @@ import Button from '@shared/atoms/Button'
|
|||||||
import { transformTags } from '@utils/ddo'
|
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 './index.module.css'
|
||||||
import Web3Feedback from '@shared/Web3Feedback'
|
import Web3Feedback from '@shared/Web3Feedback'
|
||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
import { FormPublishData } from '../../_types'
|
import { FormPublishData } from '../../_types'
|
||||||
|
import { useFormikContext } from 'formik'
|
||||||
|
|
||||||
function Description({ description }: { description: string }) {
|
function Description({ description }: { description: string }) {
|
||||||
const [fullDescription, setFullDescription] = useState<boolean>(false)
|
const [fullDescription, setFullDescription] = useState<boolean>(false)
|
||||||
@ -87,13 +88,10 @@ function Sample({ url }: { url: string }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function MetadataPreview({
|
export default function Preview(): ReactElement {
|
||||||
values
|
|
||||||
}: {
|
|
||||||
values: Partial<FormPublishData>
|
|
||||||
}): ReactElement {
|
|
||||||
const { networkId } = useWeb3()
|
const { networkId } = useWeb3()
|
||||||
const { isAssetNetwork } = useAsset()
|
const { isAssetNetwork } = useAsset()
|
||||||
|
const { values } = useFormikContext<FormPublishData>()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.preview}>
|
<div className={styles.preview}>
|
||||||
|
@ -1,27 +1,58 @@
|
|||||||
import Input from '@shared/Form/Input'
|
import Input from '@shared/Form/Input'
|
||||||
import { Field } from 'formik'
|
import { Field, useFormikContext } from 'formik'
|
||||||
import React, { ReactElement } from 'react'
|
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'
|
import { getFieldContent } from '../../_utils'
|
||||||
|
import { FormPublishData } from '../../_types'
|
||||||
|
|
||||||
|
const accessTypeOptionsTitles = getFieldContent(
|
||||||
|
'access',
|
||||||
|
content.services.fields
|
||||||
|
).options
|
||||||
|
|
||||||
const accessTypeOptions = [
|
const accessTypeOptions = [
|
||||||
{
|
{
|
||||||
name: 'Download',
|
name: accessTypeOptionsTitles[0].toLowerCase(),
|
||||||
title: 'Download',
|
title: accessTypeOptionsTitles[0],
|
||||||
icon: <IconDownload />
|
icon: <IconDownload />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Compute',
|
name: accessTypeOptionsTitles[1].toLowerCase(),
|
||||||
title: 'Compute',
|
title: accessTypeOptionsTitles[1],
|
||||||
icon: <IconCompute />
|
icon: <IconCompute />
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const assetTypeOptionsTitles = getFieldContent(
|
||||||
|
'type',
|
||||||
|
content.services.fields
|
||||||
|
).options
|
||||||
|
|
||||||
|
const assetTypeOptions = [
|
||||||
|
{
|
||||||
|
name: assetTypeOptionsTitles[0].toLowerCase(),
|
||||||
|
title: assetTypeOptionsTitles[0]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: assetTypeOptionsTitles[1].toLowerCase(),
|
||||||
|
title: assetTypeOptionsTitles[1]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
export default function ServicesFields(): ReactElement {
|
export default function ServicesFields(): ReactElement {
|
||||||
|
// connect with Form state, use for conditional field rendering
|
||||||
|
const { values } = useFormikContext<FormPublishData>()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<Field
|
||||||
|
{...getFieldContent('type', content.services.fields)}
|
||||||
|
component={Input}
|
||||||
|
name="type"
|
||||||
|
options={assetTypeOptions}
|
||||||
|
/>
|
||||||
<Field
|
<Field
|
||||||
{...getFieldContent('dataTokenOptions', content.services.fields)}
|
{...getFieldContent('dataTokenOptions', content.services.fields)}
|
||||||
component={Input}
|
component={Input}
|
||||||
|
@ -10,6 +10,7 @@ import Debug from '../Debug'
|
|||||||
import MetadataFields from './Metadata'
|
import MetadataFields from './Metadata'
|
||||||
import ServicesFields from './Services'
|
import ServicesFields from './Services'
|
||||||
import content from '../../../../content/publish/form.json'
|
import content from '../../../../content/publish/form.json'
|
||||||
|
import Preview from './Preview'
|
||||||
|
|
||||||
export default function FormPublish(): ReactElement {
|
export default function FormPublish(): ReactElement {
|
||||||
const { isValid, values, resetForm }: FormikContextType<FormPublishData> =
|
const { isValid, values, resetForm }: FormikContextType<FormPublishData> =
|
||||||
@ -68,6 +69,18 @@ export default function FormPublish(): ReactElement {
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: content.preview.title,
|
||||||
|
content: (
|
||||||
|
<>
|
||||||
|
<Preview />
|
||||||
|
<FormActions
|
||||||
|
isValid={isValid}
|
||||||
|
resetFormAndClearStorage={resetFormAndClearStorage}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { File as FileMetadata } from '@oceanprotocol/lib'
|
import { File as FileMetadata } from '@oceanprotocol/lib'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
import { allowDynamicPricing, allowFixedPricing } from '../../../app.config'
|
import { allowDynamicPricing, allowFixedPricing } from '../../../app.config.js'
|
||||||
import { FormPublishData } from './_types'
|
import { FormPublishData } from './_types'
|
||||||
|
|
||||||
export const initialValues: Partial<FormPublishData> = {
|
export const initialValues: Partial<FormPublishData> = {
|
||||||
|
type: 'dataset',
|
||||||
metadata: {
|
metadata: {
|
||||||
name: '',
|
name: '',
|
||||||
author: '',
|
author: '',
|
||||||
|
Loading…
Reference in New Issue
Block a user