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:
parent
558b4730f6
commit
c7fa8a0b9e
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user