Rework Vector to use Params (like Struct, Tuple) (#1739)

* Rework Vector to use Params (like Struct, Tuple)

* Cleanup default values
This commit is contained in:
Jaco Greeff 2019-10-21 12:11:09 +02:00 committed by GitHub
parent 558b4730f6
commit c7fa8a0b9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 67 deletions

View File

@ -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<Props> {
export default function Base ({ children, className, isOuter, label, size = 'full', style, withLabel }: Props): React.ReactElement<Props> {
return (
<Bare
className={className}
@ -31,8 +32,9 @@ export default function Base ({ children, className, label, size = 'full', style
withEllipsis
withLabel={withLabel}
>
{children}
{!isOuter && children}
</Labelled>
{isOuter && children}
</Bare>
);
}

View File

@ -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<Props> | null {
const [Component, setComponent] = useState<React.ComponentType<BareProps> | null>(null);
const [stateType, setStateType] = useState<string | null>(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<Props> | null {
const [count, setCount] = useState(0);
const [params, setParams] = useState<ParamDef[]>([]);
const [values, setValues] = useState<RawParam[]>([]);
// 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<BareProps> => 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 (
<Base
className={className}
isOuter
label={label}
style={style}
withLabel={withLabel}
>
{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<bool>' && isDisabled && values[index].value === false
? null
: (
<Component
defaultValue={value}
isDisabled={isDisabled}
key={index}
label={`${index}: ${subType.type}`}
onChange={
(value: RawParam): void =>
setValues(
values.map((svalue, sindex): RawParam =>
(sindex === index)
? value
: svalue
)
)
}
onEnter={onEnter}
type={subType}
withLabel={withLabel}
/>
)
))}
{!isDisabled && (
<div className='ui--Param-Vector-buttons'>
<Button
@ -121,6 +110,12 @@ function Vector ({ className, defaultValue, isDisabled = false, label, onChange,
/>
</div>
)}
<Params
isDisabled={isDisabled}
onChange={setValues}
params={params}
values={values}
/>
</Base>
);
}