diff --git a/src/@types/MetaData.d.ts b/src/@types/MetaData.d.ts index 023101e30..ee7f94ae9 100644 --- a/src/@types/MetaData.d.ts +++ b/src/@types/MetaData.d.ts @@ -19,6 +19,10 @@ export interface MetadataMarket extends Metadata { additionalInformation?: AdditionalInformationMarket } +export interface PriceOptionsMarket extends PriceOptions { + liquidityProviderFee: number +} + export interface MetadataPublishForm { // ---- required fields ---- name: string @@ -26,7 +30,7 @@ export interface MetadataPublishForm { files: string | File[] author: string license: string - price: PriceOptions + price: PriceOptionsMarket access: 'Download' | 'Compute' | string termsAndConditions: boolean // ---- optional fields ---- diff --git a/src/components/atoms/Input/InputElement.module.css b/src/components/atoms/Input/InputElement.module.css index 37045d189..902d55ef7 100644 --- a/src/components/atoms/Input/InputElement.module.css +++ b/src/components/atoms/Input/InputElement.module.css @@ -38,6 +38,15 @@ color: var(--brand-grey-light); cursor: not-allowed; pointer-events: none; + /* for hiding spin buttons in Firefox */ + -moz-appearance: textfield; +} + +.input[readonly]::-webkit-inner-spin-button, +.input[disabled]::-webkit-inner-spin-button, +.input[readonly]::-webkit-outer-spin-button, +.input[disabled]::-webkit-outer-spin-button { + display: none; } .select { diff --git a/src/components/molecules/FormFields/Price/Coin.tsx b/src/components/molecules/FormFields/Price/Coin.tsx index 10d055b3a..f5bff2d2d 100644 --- a/src/components/molecules/FormFields/Price/Coin.tsx +++ b/src/components/molecules/FormFields/Price/Coin.tsx @@ -1,6 +1,7 @@ import React, { ReactElement } from 'react' import stylesIndex from './index.module.css' import styles from './Coin.module.css' +import stylesInput from '../../../atoms/Input/index.module.css' import InputElement from '../../../atoms/Input/InputElement' import { ReactComponent as Logo } from '../../../../images/logo.svg' import Conversion from '../../../atoms/Price/Conversion' @@ -21,7 +22,7 @@ export default function Coin({ generateName?: () => void readOnly?: boolean }): ReactElement { - const [field] = useField(name) + const [field, meta] = useField(name) return (
@@ -50,6 +51,9 @@ export default function Coin({ {datatokenOptions?.symbol === 'OCEAN' && ( )} + {meta.error && meta.touched && ( +
{meta.error}
+ )}
) diff --git a/src/components/molecules/FormFields/Price/Dynamic.tsx b/src/components/molecules/FormFields/Price/Dynamic.tsx index a89a45ece..fc5b52d89 100644 --- a/src/components/molecules/FormFields/Price/Dynamic.tsx +++ b/src/components/molecules/FormFields/Price/Dynamic.tsx @@ -1,15 +1,16 @@ -import React, { ReactElement, useState, ChangeEvent, useEffect } from 'react' +import React, { ReactElement, useState, useEffect } from 'react' import stylesIndex from './index.module.css' import styles from './Dynamic.module.css' import FormHelp from '../../../atoms/Input/Help' import Wallet from '../../Wallet' -import { DataTokenOptions, PriceOptions, useOcean } from '@oceanprotocol/react' +import { DataTokenOptions, useOcean } from '@oceanprotocol/react' import Alert from '../../../atoms/Alert' import Coin from './Coin' import { isCorrectNetwork } from '../../../../utils/wallet' import { useSiteMetadata } from '../../../../hooks/useSiteMetadata' import Tooltip from '../../../atoms/Tooltip' import Fees from './Fees' +import { PriceOptionsMarket } from '../../../../@types/MetaData' export default function Dynamic({ ocean, @@ -19,7 +20,7 @@ export default function Dynamic({ content }: { ocean: number - priceOptions: PriceOptions + priceOptions: PriceOptionsMarket datatokenOptions: DataTokenOptions generateName: () => void content: any diff --git a/src/components/molecules/FormFields/Price/Fees.module.css b/src/components/molecules/FormFields/Price/Fees.module.css index 2105e187a..9bfaf2ba7 100644 --- a/src/components/molecules/FormFields/Price/Fees.module.css +++ b/src/components/molecules/FormFields/Price/Fees.module.css @@ -9,7 +9,6 @@ padding: var(--spacer); padding-top: 0; - align-items: center; border-bottom: 1px solid var(--brand-grey-lighter); } diff --git a/src/components/molecules/FormFields/Price/Fees.tsx b/src/components/molecules/FormFields/Price/Fees.tsx index 063cb3fb9..256f89872 100644 --- a/src/components/molecules/FormFields/Price/Fees.tsx +++ b/src/components/molecules/FormFields/Price/Fees.tsx @@ -1,6 +1,7 @@ import React, { ReactElement } from 'react' import Tooltip from '../../../atoms/Tooltip' import styles from './Fees.module.css' +import stylesInput from '../../../atoms/Input/index.module.css' import { useSiteMetadata } from '../../../../hooks/useSiteMetadata' import { useField } from 'formik' import Input from '../../../atoms/Input' @@ -31,7 +32,10 @@ export default function Fees({ small {...field} additionalComponent={ - meta.error && meta.touched &&
{meta.error}
+ meta.error && + meta.touched && ( +
{meta.error}
+ ) } /> diff --git a/src/components/molecules/FormFields/Price/Fixed.module.css b/src/components/molecules/FormFields/Price/Fixed.module.css index 4eef6bea7..9d7ca5a15 100644 --- a/src/components/molecules/FormFields/Price/Fixed.module.css +++ b/src/components/molecules/FormFields/Price/Fixed.module.css @@ -2,6 +2,10 @@ composes: content from './index.module.css'; } +.form { + position: relative; +} + @media (min-width: 55rem) { .form { max-width: 12rem; diff --git a/src/components/molecules/FormFields/Price/Fixed.tsx b/src/components/molecules/FormFields/Price/Fixed.tsx index 979333340..ffd3aef71 100644 --- a/src/components/molecules/FormFields/Price/Fixed.tsx +++ b/src/components/molecules/FormFields/Price/Fixed.tsx @@ -1,6 +1,7 @@ import React, { ReactElement } from 'react' import stylesIndex from './index.module.css' import styles from './Fixed.module.css' +import stylesInput from '../../../atoms/Input/index.module.css' import FormHelp from '../../../atoms/Input/Help' import Conversion from '../../../atoms/Price/Conversion' import { DataTokenOptions } from '@oceanprotocol/react' @@ -32,10 +33,18 @@ export default function Fixed({ type="number" prefix="OCEAN" {...field} + additionalComponent={ + + } /> - + {meta.error && meta.touched && ( +
{meta.error}
+ )} - {meta.error && meta.touched &&
{meta.error}
} + {datatokenOptions && (

diff --git a/src/components/molecules/FormFields/Price/index.module.css b/src/components/molecules/FormFields/Price/index.module.css index 7655b3bbc..22182cdad 100644 --- a/src/components/molecules/FormFields/Price/index.module.css +++ b/src/components/molecules/FormFields/Price/index.module.css @@ -20,6 +20,11 @@ margin-bottom: 0; } +.content [class*='error'] { + text-align: left; + top: 100%; +} + .conversion { width: 100%; display: block; diff --git a/src/components/molecules/FormFields/Price/index.tsx b/src/components/molecules/FormFields/Price/index.tsx index e1b51fe33..6e0e7395a 100644 --- a/src/components/molecules/FormFields/Price/index.tsx +++ b/src/components/molecules/FormFields/Price/index.tsx @@ -8,6 +8,7 @@ import Dynamic from './Dynamic' import { useField } from 'formik' import { useUserPreferences } from '../../../../providers/UserPreferences' import { DataTokenOptions, PriceOptions, useOcean } from '@oceanprotocol/react' +import { PriceOptionsMarket } from '../../../../@types/MetaData' const query = graphql` query PriceFieldQuery { @@ -45,7 +46,7 @@ export default function Price(props: InputProps): ReactElement { const { ocean } = useOcean() const [field, meta, helpers] = useField(props.name) - const { price }: PriceOptions = field.value + const { price }: PriceOptionsMarket = field.value const [tokensToMint, setTokensToMint] = useState() const [datatokenOptions, setDatatokenOptions] = useState() diff --git a/src/models/FormPublish.ts b/src/models/FormPublish.ts index a3b8afb8a..b6fb6796a 100644 --- a/src/models/FormPublish.ts +++ b/src/models/FormPublish.ts @@ -8,17 +8,15 @@ export const validationSchema = Yup.object().shape({ author: Yup.string().required('Required'), price: Yup.object() .shape({ - price: Yup.number() - .min(1, 'Must be greater than 0') - .positive() - .required('Required'), + price: Yup.number().min(1, 'Must be greater than 0').required('Required'), tokensToMint: Yup.number().positive().required('Required'), type: Yup.string() .matches(/fixed|dynamic/g) .required('Required'), weightOnDataToken: Yup.string().required('Required'), - liquidityProviderFee: Yup.string() - .matches(/0.[0-9]/, 'Only values between 0.1 - 0.9 are allowed') + liquidityProviderFee: Yup.number() + .min(0.1, 'Must be more or equal to 0.1') + .max(0.9, 'Must be less or equal to 0.9') .required('Required') }) .required('Required'), @@ -44,8 +42,7 @@ export const initialValues: MetadataPublishForm = { type: 'fixed', tokensToMint: 1, weightOnDataToken: '9', // 90% on data token - liquidityProviderFee: '0.1', // in % - price: 1 + liquidityProviderFee: 0.1 // in % }, files: '', description: '',