Extract state interfaces (#2805)

This commit is contained in:
Jaco Greeff 2020-05-25 10:05:14 +02:00 committed by GitHub
parent 2733c4bb6b
commit e9f7b547fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 96 additions and 16 deletions

View File

@ -12,10 +12,21 @@ import keyring from '@polkadot/ui-keyring';
import { useTranslation } from '../../translate';
interface AddrState {
address: string;
isAddressExisting: boolean;
isAddressValid: boolean;
}
interface NameState {
isNameValid: boolean;
name: string;
}
function Create ({ onClose, onStatusChange }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const [{ isNameValid, name }, setName] = useState<{ isNameValid: boolean; name: string }>({ isNameValid: false, name: '' });
const [{ address, isAddressExisting, isAddressValid }, setAddress] = useState<{ address: string; isAddressExisting: boolean; isAddressValid: boolean }>({ address: '', isAddressExisting: false, isAddressValid: false });
const [{ isNameValid, name }, setName] = useState<NameState>({ isNameValid: false, name: '' });
const [{ address, isAddressExisting, isAddressValid }, setAddress] = useState<AddrState>({ address: '', isAddressExisting: false, isAddressValid: false });
const isValid = isAddressValid && isNameValid;
const _onChangeAddress = useCallback(

View File

@ -17,13 +17,18 @@ interface Props {
members: string[];
}
interface HashState {
hash?: string;
isHashValid: boolean;
}
function ProposeExternal ({ className = '', isMember, members }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const [isVisible, toggleVisible] = useToggle();
const [accountId, setAcountId] = useState<string | null>(null);
const [proposal, setProposal] = useState<SubmittableExtrinsic<'promise'> | null>(null);
const [{ hash, isHashValid }, setHash] = useState<{ hash?: string; isHashValid: boolean }>({ hash: '', isHashValid: false });
const [{ hash, isHashValid }, setHash] = useState<HashState>({ hash: '', isHashValid: false });
const threshold = Math.ceil((members.length || 0) * 0.5);
const _onChangeHash = useCallback(

View File

@ -21,6 +21,11 @@ interface Props {
onClose: () => void;
}
interface HashState {
encodedHash: string;
encodedProposal: string;
}
const ZERO_HASH = blake2AsHex('');
function PreImage ({ className = '', imageHash, isImminent: propsIsImminent, onClose }: Props): React.ReactElement<Props> {
@ -28,7 +33,7 @@ function PreImage ({ className = '', imageHash, isImminent: propsIsImminent, onC
const { apiDefaultTxSudo } = useApi();
const [accountId, setAccountId] = useState<string | null>(null);
const [isImminent, setIsImminent] = useState(propsIsImminent || false);
const [{ encodedHash, encodedProposal }, setHash] = useState<{ encodedHash: string; encodedProposal: string }>({ encodedHash: ZERO_HASH, encodedProposal: '' });
const [{ encodedHash, encodedProposal }, setHash] = useState<HashState>({ encodedHash: ZERO_HASH, encodedProposal: '' });
const [proposal, setProposal] = useState<SubmittableExtrinsic>();
useEffect((): void => {

View File

@ -16,12 +16,17 @@ interface Props {
onClose: () => void;
}
interface HashState {
hash?: string;
isHashValid: boolean;
}
function Propose ({ className = '', onClose }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const [accountId, setAccountId] = useState<string | null>(null);
const [balance, setBalance] = useState<BN | undefined>();
const [{ hash, isHashValid }, setHash] = useState<{ hash?: string; isHashValid: boolean }>({ hash: '', isHashValid: false });
const [{ hash, isHashValid }, setHash] = useState<HashState>({ hash: '', isHashValid: false });
const _onChangeHash = useCallback(
(hash?: string): void => setHash({ hash, isHashValid: isHex(hash, 256) }),

View File

@ -25,13 +25,18 @@ interface Value {
value: TreasuryProposal;
}
interface ParamState {
params: Param[];
values: Value[];
}
function TreasuryCell ({ className = '', value }: Props): React.ReactElement<Props> | null {
const { api } = useApi();
const [proposalId] = useState(value.unwrap());
const proposal = useCall<TreasuryProposal | null>(api.query.treasury.proposals, [proposalId], {
transform: (optProp: Option<TreasuryProposal>) => optProp.unwrapOr(null)
});
const [{ params, values }, setExtracted] = useState<{ params: Param[]; values: Value[] }>({ params: [], values: [] });
const [{ params, values }, setExtracted] = useState<ParamState>({ params: [], values: [] });
useEffect((): void => {
proposal && setExtracted({

View File

@ -18,6 +18,11 @@ interface Props {
onError: (error: string | null, isFatal: boolean) => void;
}
interface ErrorState {
error: string | null;
isFatal: boolean;
}
function ValidateController ({ accountId, controllerId, defaultController, onError }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
const { api } = useApi();
@ -33,7 +38,7 @@ function ValidateController ({ accountId, controllerId, defaultController, onErr
? value.unwrap().stash.toString()
: null
});
const [{ error, isFatal }, setError] = useState<{ error: string | null; isFatal: boolean }>({ error: null, isFatal: false });
const [{ error, isFatal }, setError] = useState<ErrorState>({ error: null, isFatal: false });
useEffect((): void => {
// don't show an error if the selected controller is the default

View File

@ -17,9 +17,14 @@ interface Props {
targets: string[];
}
interface IdState {
controllerId?: string | null;
stashId: string;
}
function Nominate ({ className = '', ownNominators, targets }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const [ids, setIds] = useState<{ controllerId?: string | null; stashId: string } | null>(null);
const [ids, setIds] = useState<IdState | null>(null);
const [filter, setFilter] = useState<string[]>([]);
const [isOpen, toggleOpen] = useToggle();

View File

@ -22,6 +22,11 @@ interface Props {
targets: SortedTargets;
}
interface SortState {
sortBy: TargetSortBy;
sortFromMax: boolean;
}
function sort (sortBy: TargetSortBy, sortFromMax: boolean, validators: ValidatorInfo[]): number[] {
return [...Array(validators.length).keys()]
.sort((a, b) =>
@ -41,7 +46,7 @@ function Targets ({ className = '', ownStashes, targets: { calcWith, lastReward,
const ownNominators = useOwnNominators(ownStashes);
const [selected, setSelected] = useState<string[]>([]);
const [sorted, setSorted] = useState<number[] | undefined>();
const [{ sortBy, sortFromMax }, setSortBy] = useState<{ sortBy: TargetSortBy; sortFromMax: boolean }>({ sortBy: 'rankOverall', sortFromMax: true });
const [{ sortBy, sortFromMax }, setSortBy] = useState<SortState>({ sortBy: 'rankOverall', sortFromMax: true });
useEffect((): void => {
validators && setSorted(

View File

@ -26,17 +26,27 @@ interface AccountState {
isInjected: boolean;
}
interface DataState {
data: string;
isHexData: boolean;
}
interface SignerState {
isUsable: boolean;
signer: Signer | null;
}
function Sign ({ className = '' }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const [currentPair, setCurrentPair] = useState<KeyringPair | null>(keyring.getPairs()[0] || null);
const [{ data, isHexData }, setData] = useState<{ data: string; isHexData: boolean }>({ data: '', isHexData: false });
const [{ data, isHexData }, setData] = useState<DataState>({ data: '', isHexData: false });
const [{ isInjected }, setAccountState] = useState<AccountState>({
isExternal: false,
isHardware: false,
isInjected: false
});
const [isLocked, setIsLocked] = useState(false);
const [{ isUsable, signer }, setSigner] = useState<{ isUsable: boolean; signer: Signer | null }>({ isUsable: true, signer: null });
const [{ isUsable, signer }, setSigner] = useState<SignerState>({ isUsable: true, signer: null });
const [signature, setSignature] = useState('');
const [isUnlockVisible, toggleUnlock] = useToggle();

View File

@ -12,6 +12,11 @@ import { isBoolean } from '@polkadot/util';
import { useTranslation } from '../translate';
interface CouncilInfo {
councilHash: Hash | null;
councilId: ProposalIndex | null;
}
interface Props {
councilProposals: DeriveCollectiveProposal[];
isDisabled?: boolean;
@ -31,7 +36,7 @@ function Voting ({ councilProposals, isDisabled, members }: Props): React.ReactE
const [councilOpts, setCouncilOpts] = useState<Option[]>([]);
const [councilOptId, setCouncilOptId] = useState<number>(0);
const [accountId, setAccountId] = useState<string | null>(null);
const [{ councilHash, councilId }, setCouncilInfo] = useState<{ councilHash: Hash | null; councilId: ProposalIndex | null }>({ councilHash: null, councilId: null });
const [{ councilHash, councilId }, setCouncilInfo] = useState<CouncilInfo>({ councilHash: null, councilId: null });
const [isOpen, toggleOpen] = useToggle();
const [voteValue, setVoteValue] = useState(true);
@ -41,7 +46,7 @@ function Voting ({ councilProposals, isDisabled, members }: Props): React.ReactE
useEffect((): void => {
const available = councilProposals
.filter(({ votes }) => bestNumber && votes?.end.gt(bestNumber))
.filter(({ votes }) => bestNumber && votes && (!votes.end || votes.end.gt(bestNumber)))
.map(({ proposal: { methodName, sectionName }, votes }): Option => ({
text: `Council #${votes?.index.toNumber() || '-'}: ${sectionName}.${methodName} `,
value: votes ? votes?.index.toNumber() : -1

View File

@ -38,9 +38,15 @@ interface Value {
value: Codec;
}
interface Extracted {
hash: Hash | null;
params: Param[];
values: Value[];
}
function Call ({ children, className = '', labelHash, mortality, onError, tip, value, withBorder, withHash }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const [{ hash, params, values }, setExtracted] = useState<{ hash: Hash | null; params: Param[]; values: Value[] }>({ hash: null, params: [], values: [] });
const [{ hash, params, values }, setExtracted] = useState<Extracted>({ hash: null, params: [], values: [] });
useEffect((): void => {
const params = GenericCall.filterOrigin(value.meta).map(({ name, type }): Param => ({

View File

@ -27,6 +27,14 @@ interface Props extends BareProps {
withLabel?: boolean;
}
interface CallState {
fn: SubmittableExtrinsicFunction<'promise'>;
params: {
name: string;
type: TypeDef
}[];
}
function getParams ({ meta }: SubmittableExtrinsicFunction<'promise'>): { name: string; type: TypeDef }[] {
return GenericCall.filterOrigin(meta).map((arg): { name: string; type: TypeDef } => ({
name: arg.name.toString(),
@ -35,7 +43,7 @@ function getParams ({ meta }: SubmittableExtrinsicFunction<'promise'>): { name:
}
function ExtrinsicDisplay ({ defaultValue, isDisabled, isError, isPrivate, label, onChange, onEnter, onEscape, withLabel }: Props): React.ReactElement<Props> {
const [extrinsic, setCall] = useState<{ fn: SubmittableExtrinsicFunction<'promise'>; params: { name: string; type: TypeDef }[] }>({ fn: defaultValue, params: getParams(defaultValue) });
const [extrinsic, setCall] = useState<CallState>({ fn: defaultValue, params: getParams(defaultValue) });
const [values, setValues] = useState<RawParam[]>([]);
useEffect((): void => {

View File

@ -19,11 +19,16 @@ interface Option {
value?: string;
}
interface Options {
options: Option[];
subTypes: TypeDef[];
}
function EnumParam (props: Props): React.ReactElement<Props> {
const { className = '', defaultValue, isDisabled, isError, label, onChange, overrides, type, withLabel } = props;
const [current, setCurrent] = useState<ParamDef[] | null>(null);
const [initialValue, setInitialValue] = useState<string | null>(null);
const [{ options, subTypes }, setOptions] = useState<{ options: Option[]; subTypes: TypeDef[] }>({ options: [], subTypes: [] });
const [{ options, subTypes }, setOptions] = useState<Options>({ options: [], subTypes: [] });
useEffect((): void => {
const rawType = createType(registry, type.type as 'u32').toRawType();