1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00

price validation ui fixes

This commit is contained in:
Matthias Kretschmann 2020-09-21 15:28:13 +02:00
parent 9008ad2018
commit 83d791cf1b
Signed by: m
GPG Key ID: 606EEEF3C479A91F
11 changed files with 55 additions and 18 deletions

View File

@ -19,6 +19,10 @@ export interface MetadataMarket extends Metadata {
additionalInformation?: AdditionalInformationMarket additionalInformation?: AdditionalInformationMarket
} }
export interface PriceOptionsMarket extends PriceOptions {
liquidityProviderFee: number
}
export interface MetadataPublishForm { export interface MetadataPublishForm {
// ---- required fields ---- // ---- required fields ----
name: string name: string
@ -26,7 +30,7 @@ export interface MetadataPublishForm {
files: string | File[] files: string | File[]
author: string author: string
license: string license: string
price: PriceOptions price: PriceOptionsMarket
access: 'Download' | 'Compute' | string access: 'Download' | 'Compute' | string
termsAndConditions: boolean termsAndConditions: boolean
// ---- optional fields ---- // ---- optional fields ----

View File

@ -38,6 +38,15 @@
color: var(--brand-grey-light); color: var(--brand-grey-light);
cursor: not-allowed; cursor: not-allowed;
pointer-events: none; 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 { .select {

View File

@ -1,6 +1,7 @@
import React, { ReactElement } from 'react' import React, { ReactElement } from 'react'
import stylesIndex from './index.module.css' import stylesIndex from './index.module.css'
import styles from './Coin.module.css' import styles from './Coin.module.css'
import stylesInput from '../../../atoms/Input/index.module.css'
import InputElement from '../../../atoms/Input/InputElement' import InputElement from '../../../atoms/Input/InputElement'
import { ReactComponent as Logo } from '../../../../images/logo.svg' import { ReactComponent as Logo } from '../../../../images/logo.svg'
import Conversion from '../../../atoms/Price/Conversion' import Conversion from '../../../atoms/Price/Conversion'
@ -21,7 +22,7 @@ export default function Coin({
generateName?: () => void generateName?: () => void
readOnly?: boolean readOnly?: boolean
}): ReactElement { }): ReactElement {
const [field] = useField(name) const [field, meta] = useField(name)
return ( return (
<div className={styles.coin}> <div className={styles.coin}>
@ -50,6 +51,9 @@ export default function Coin({
{datatokenOptions?.symbol === 'OCEAN' && ( {datatokenOptions?.symbol === 'OCEAN' && (
<Conversion price={field.value} className={stylesIndex.conversion} /> <Conversion price={field.value} className={stylesIndex.conversion} />
)} )}
{meta.error && meta.touched && (
<div className={stylesInput.error}>{meta.error}</div>
)}
</div> </div>
</div> </div>
) )

View File

@ -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 stylesIndex from './index.module.css'
import styles from './Dynamic.module.css' import styles from './Dynamic.module.css'
import FormHelp from '../../../atoms/Input/Help' import FormHelp from '../../../atoms/Input/Help'
import Wallet from '../../Wallet' import Wallet from '../../Wallet'
import { DataTokenOptions, PriceOptions, useOcean } from '@oceanprotocol/react' import { DataTokenOptions, useOcean } from '@oceanprotocol/react'
import Alert from '../../../atoms/Alert' import Alert from '../../../atoms/Alert'
import Coin from './Coin' import Coin from './Coin'
import { isCorrectNetwork } from '../../../../utils/wallet' import { isCorrectNetwork } from '../../../../utils/wallet'
import { useSiteMetadata } from '../../../../hooks/useSiteMetadata' import { useSiteMetadata } from '../../../../hooks/useSiteMetadata'
import Tooltip from '../../../atoms/Tooltip' import Tooltip from '../../../atoms/Tooltip'
import Fees from './Fees' import Fees from './Fees'
import { PriceOptionsMarket } from '../../../../@types/MetaData'
export default function Dynamic({ export default function Dynamic({
ocean, ocean,
@ -19,7 +20,7 @@ export default function Dynamic({
content content
}: { }: {
ocean: number ocean: number
priceOptions: PriceOptions priceOptions: PriceOptionsMarket
datatokenOptions: DataTokenOptions datatokenOptions: DataTokenOptions
generateName: () => void generateName: () => void
content: any content: any

View File

@ -9,7 +9,6 @@
padding: var(--spacer); padding: var(--spacer);
padding-top: 0; padding-top: 0;
align-items: center;
border-bottom: 1px solid var(--brand-grey-lighter); border-bottom: 1px solid var(--brand-grey-lighter);
} }

View File

@ -1,6 +1,7 @@
import React, { ReactElement } from 'react' import React, { ReactElement } from 'react'
import Tooltip from '../../../atoms/Tooltip' import Tooltip from '../../../atoms/Tooltip'
import styles from './Fees.module.css' import styles from './Fees.module.css'
import stylesInput from '../../../atoms/Input/index.module.css'
import { useSiteMetadata } from '../../../../hooks/useSiteMetadata' import { useSiteMetadata } from '../../../../hooks/useSiteMetadata'
import { useField } from 'formik' import { useField } from 'formik'
import Input from '../../../atoms/Input' import Input from '../../../atoms/Input'
@ -31,7 +32,10 @@ export default function Fees({
small small
{...field} {...field}
additionalComponent={ additionalComponent={
meta.error && meta.touched && <div>{meta.error}</div> meta.error &&
meta.touched && (
<div className={stylesInput.error}>{meta.error}</div>
)
} }
/> />

View File

@ -2,6 +2,10 @@
composes: content from './index.module.css'; composes: content from './index.module.css';
} }
.form {
position: relative;
}
@media (min-width: 55rem) { @media (min-width: 55rem) {
.form { .form {
max-width: 12rem; max-width: 12rem;

View File

@ -1,6 +1,7 @@
import React, { ReactElement } from 'react' import React, { ReactElement } from 'react'
import stylesIndex from './index.module.css' import stylesIndex from './index.module.css'
import styles from './Fixed.module.css' import styles from './Fixed.module.css'
import stylesInput from '../../../atoms/Input/index.module.css'
import FormHelp from '../../../atoms/Input/Help' import FormHelp from '../../../atoms/Input/Help'
import Conversion from '../../../atoms/Price/Conversion' import Conversion from '../../../atoms/Price/Conversion'
import { DataTokenOptions } from '@oceanprotocol/react' import { DataTokenOptions } from '@oceanprotocol/react'
@ -32,10 +33,18 @@ export default function Fixed({
type="number" type="number"
prefix="OCEAN" prefix="OCEAN"
{...field} {...field}
additionalComponent={
<Conversion
price={field.value}
className={stylesIndex.conversion}
/>
}
/> />
<Conversion price={field.value} className={stylesIndex.conversion} /> {meta.error && meta.touched && (
<div className={stylesInput.error}>{meta.error}</div>
)}
</div> </div>
{meta.error && meta.touched && <div>{meta.error}</div>}
{datatokenOptions && ( {datatokenOptions && (
<div className={styles.datatoken}> <div className={styles.datatoken}>
<h4> <h4>

View File

@ -20,6 +20,11 @@
margin-bottom: 0; margin-bottom: 0;
} }
.content [class*='error'] {
text-align: left;
top: 100%;
}
.conversion { .conversion {
width: 100%; width: 100%;
display: block; display: block;

View File

@ -8,6 +8,7 @@ import Dynamic from './Dynamic'
import { useField } from 'formik' import { useField } from 'formik'
import { useUserPreferences } from '../../../../providers/UserPreferences' import { useUserPreferences } from '../../../../providers/UserPreferences'
import { DataTokenOptions, PriceOptions, useOcean } from '@oceanprotocol/react' import { DataTokenOptions, PriceOptions, useOcean } from '@oceanprotocol/react'
import { PriceOptionsMarket } from '../../../../@types/MetaData'
const query = graphql` const query = graphql`
query PriceFieldQuery { query PriceFieldQuery {
@ -45,7 +46,7 @@ export default function Price(props: InputProps): ReactElement {
const { ocean } = useOcean() const { ocean } = useOcean()
const [field, meta, helpers] = useField(props.name) const [field, meta, helpers] = useField(props.name)
const { price }: PriceOptions = field.value const { price }: PriceOptionsMarket = field.value
const [tokensToMint, setTokensToMint] = useState<number>() const [tokensToMint, setTokensToMint] = useState<number>()
const [datatokenOptions, setDatatokenOptions] = useState<DataTokenOptions>() const [datatokenOptions, setDatatokenOptions] = useState<DataTokenOptions>()

View File

@ -8,17 +8,15 @@ export const validationSchema = Yup.object().shape<MetadataPublishForm>({
author: Yup.string().required('Required'), author: Yup.string().required('Required'),
price: Yup.object() price: Yup.object()
.shape({ .shape({
price: Yup.number() price: Yup.number().min(1, 'Must be greater than 0').required('Required'),
.min(1, 'Must be greater than 0')
.positive()
.required('Required'),
tokensToMint: Yup.number().positive().required('Required'), tokensToMint: Yup.number().positive().required('Required'),
type: Yup.string() type: Yup.string()
.matches(/fixed|dynamic/g) .matches(/fixed|dynamic/g)
.required('Required'), .required('Required'),
weightOnDataToken: Yup.string().required('Required'), weightOnDataToken: Yup.string().required('Required'),
liquidityProviderFee: Yup.string() liquidityProviderFee: Yup.number()
.matches(/0.[0-9]/, 'Only values between 0.1 - 0.9 are allowed') .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')
}) })
.required('Required'), .required('Required'),
@ -44,8 +42,7 @@ export const initialValues: MetadataPublishForm = {
type: 'fixed', type: 'fixed',
tokensToMint: 1, tokensToMint: 1,
weightOnDataToken: '9', // 90% on data token weightOnDataToken: '9', // 90% on data token
liquidityProviderFee: '0.1', // in % liquidityProviderFee: 0.1 // in %
price: 1
}, },
files: '', files: '',
description: '', description: '',