From c7fa8a0b9eeb110700378a322401dcf61b4d60a1 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Mon, 21 Oct 2019 12:11:09 +0200 Subject: [PATCH] Rework Vector to use Params (like Struct, Tuple) (#1739) * Rework Vector to use Params (like Struct, Tuple) * Cleanup default values --- packages/react-params/src/Param/Base.tsx | 6 +- packages/react-params/src/Param/Vector.tsx | 125 ++++++++++----------- 2 files changed, 64 insertions(+), 67 deletions(-) diff --git a/packages/react-params/src/Param/Base.tsx b/packages/react-params/src/Param/Base.tsx index 27545183ad..9363e1ae82 100644 --- a/packages/react-params/src/Param/Base.tsx +++ b/packages/react-params/src/Param/Base.tsx @@ -13,12 +13,13 @@ import Bare from './Bare'; interface Props extends BareProps { children?: React.ReactNode; isDisabled?: boolean; + isOuter?: boolean; label?: React.ReactNode; size?: Size; withLabel?: boolean; } -export default function Base ({ children, className, label, size = 'full', style, withLabel }: Props): React.ReactElement { +export default function Base ({ children, className, isOuter, label, size = 'full', style, withLabel }: Props): React.ReactElement { return ( - {children} + {!isOuter && children} + {isOuter && children} ); } diff --git a/packages/react-params/src/Param/Vector.tsx b/packages/react-params/src/Param/Vector.tsx index 30e5e22a1c..32230ef038 100644 --- a/packages/react-params/src/Param/Vector.tsx +++ b/packages/react-params/src/Param/Vector.tsx @@ -4,7 +4,7 @@ import { WithTranslation } from 'react-i18next'; import { TypeDef } from '@polkadot/types/types'; -import { Props as BareProps, RawParam } from '../types'; +import { ParamDef, Props as BareProps, RawParam } from '../types'; import React, { useEffect, useState } from 'react'; import { Button } from '@polkadot/react-components'; @@ -12,39 +12,69 @@ import { isUndefined } from '@polkadot/util'; import translate from '../translate'; import getInitValue from '../initValue'; +import Params from '../'; import Base from './Base'; -import findComponent from './findComponent'; interface Props extends BareProps, WithTranslation {} -function Vector ({ className, defaultValue, isDisabled = false, label, onChange, onEnter, style, t, type, withLabel }: Props): React.ReactElement | null { - const [Component, setComponent] = useState | null>(null); - const [stateType, setStateType] = useState(null); +function generateParam (type: TypeDef, index: number): ParamDef { + return { + name: `${index}: ${type.type}`, + type + }; +} + +function Vector ({ className, defaultValue, isDisabled = false, label, onChange, style, t, type, withLabel }: Props): React.ReactElement | null { + const [count, setCount] = useState(0); + const [params, setParams] = useState([]); const [values, setValues] = useState([]); + // when !isDisable, generating an input & params based on count useEffect((): void => { - const value = defaultValue.value || []; + if (!isDisabled) { + const subType = type.sub as TypeDef; + const params: ParamDef[] = []; - if (stateType === type.type) { - return; + for (let index = 0; index < count; index++) { + params.push(generateParam(subType, index)); + } + + setParams(params); + + if (values.length !== count) { + while (values.length < count) { + const value = getInitValue(type.sub as TypeDef); + + values.push({ isValid: !isUndefined(value), value }); + } + + setValues(values.slice(0, count)); + } } + }, [count, isDisabled, type, values]); - setStateType(type.type); - setComponent((): React.ComponentType => findComponent(type.sub as TypeDef)); - setValues( - isDisabled || values.length === 0 - ? value.map((value: any): RawParam => ( + // when isDisabled, set the params & values based on the defaultValue input + useEffect((): void => { + if (isDisabled) { + const subType = type.sub as TypeDef; + const params: ParamDef[] = []; + const values: RawParam[] = []; + + (defaultValue.value || []).forEach((value: RawParam, index: number): void => { + values.push( isUndefined(value) || isUndefined(value.isValid) - ? { - isValid: !isUndefined(value), - value - } + ? { isValid: !isUndefined(value), value } : value - )) - : values - ); - }, [type]); + ); + params.push(generateParam(subType, index)); + }); + setParams(params); + setValues(values); + } + }, [defaultValue, isDisabled, type]); + + // when our values has changed, alert upstream useEffect((): void => { onChange && onChange({ isValid: values.reduce((result: boolean, { isValid }): boolean => result && isValid, true), @@ -52,58 +82,17 @@ function Vector ({ className, defaultValue, isDisabled = false, label, onChange, }); }, [values]); - if (!Component) { - return null; - } - - const subType = type.sub as TypeDef; - - const _rowAdd = (): void => { - const value = getInitValue(subType); - - setValues([...values, { - isValid: !isUndefined(value), - value - }]); - }; - const _rowRemove = (): void => { - setValues(values.slice(0, values.length - 1)); - }; + const _rowAdd = (): void => setCount(count + 1); + const _rowRemove = (): void => setCount(count - 1); return ( - {values.map((value, index): React.ReactNode => ( - // FIXME? This doesn't look quite right - this means that any bool would disappear - // when set to false? At the very least need an explanation here - type.type === 'Vec' && isDisabled && values[index].value === false - ? null - : ( - - setValues( - values.map((svalue, sindex): RawParam => - (sindex === index) - ? value - : svalue - ) - ) - } - onEnter={onEnter} - type={subType} - withLabel={withLabel} - /> - ) - ))} {!isDisabled && (
)} + ); }