1
0
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:
Matthias Kretschmann 2021-10-28 11:33:29 +01:00
parent 66adc097b6
commit 778abc8aeb
Signed by: m
GPG Key ID: 606EEEF3C479A91F
11 changed files with 133 additions and 76 deletions

View File

@ -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"
} }
} }

View File

@ -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>
)) ))

View File

@ -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);
}

View File

@ -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" />
</>
)
}

View File

@ -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

View File

@ -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[]
} }

View File

@ -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}

View File

@ -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}>

View File

@ -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}

View File

@ -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}
/>
</>
)
} }
] ]

View File

@ -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: '',