diff --git a/packages/app-council/src/Overview/VoteValue.tsx b/packages/app-council/src/Overview/VoteValue.tsx index 031450de0c99..238cd831b6d2 100644 --- a/packages/app-council/src/Overview/VoteValue.tsx +++ b/packages/app-council/src/Overview/VoteValue.tsx @@ -6,9 +6,11 @@ import { DerivedBalances } from '@polkadot/api-derive/types'; import { I18nProps } from '@polkadot/react-components/types'; import BN from 'bn.js'; -import React from 'react'; +import React, { useEffect, useState } from 'react'; +import { withCalls } from '@polkadot/react-api'; import { InputBalance } from '@polkadot/react-components'; import { BalanceVoting } from '@polkadot/react-query'; +import { formatBalance, isBn } from '@polkadot/util'; import translate from '../translate'; @@ -18,21 +20,60 @@ interface Props extends I18nProps { onChange: (value: BN) => void; } -const ZERO = new BN(0); +interface ValueState { + selectedId?: string | null; + value?: BN | string; +} + +function VoteValue ({ accountId, allBalances, onChange, t }: Props): React.ReactElement | null { + const [{ selectedId, value }, setValue] = useState({}); + + // TODO This may be useful elsewhere, so figure out a way to make this a utility + useEffect((): void => { + // if the set accountId changes and the new balances is for that id, set it + if (accountId !== selectedId && allBalances?.accountId.eq(accountId)) { + // format, removing ',' separators + const formatted = formatBalance(allBalances.lockedBalance, { forceUnit: '-', withSi: false }).replace(',', ''); + // format the balance + // - if > 0 just take the significant portion + // - if == 0, just display 0 + // - if < 0, display the 3 decimal formatted value + const value = allBalances.lockedBalance.gtn(0) + ? formatted.split('.')[0] + // if = + : allBalances.lockedBalance.eqn(0) + ? '0' + : formatted; + + // set both the selected id (for future checks) and the formatted value + setValue({ selectedId: accountId, value }); + } + }, [accountId, selectedId, allBalances]); + + // only do onChange to parent when the BN value comes in, not our formatted version + useEffect((): void => { + isBn(value) && onChange(value); + }, [value]); -function VoteValue ({ accountId, onChange, t }: Props): React.ReactElement { - const _setVoteValue = (value?: BN): void => { - onChange(value || ZERO); - }; + const _setValue = (value?: BN): void => setValue({ selectedId, value }); return ( {t('voting balance')}} params={accountId} />} - onChange={_setVoteValue} + maxValue={allBalances?.votingBalance} + onChange={_setValue} + value={value} /> ); } -export default translate(VoteValue); +export default translate( + withCalls( + ['derive.balances.all', { + paramName: 'accountId', + propName: 'allBalances' + }] + )(VoteValue) +); diff --git a/packages/react-components/src/InputBalance.tsx b/packages/react-components/src/InputBalance.tsx index 3a036da9ba3f..b2175534f800 100644 --- a/packages/react-components/src/InputBalance.tsx +++ b/packages/react-components/src/InputBalance.tsx @@ -32,13 +32,17 @@ interface Props extends BareProps { const DEFAULT_BITLENGTH = BitLengthOption.CHAIN_SPEC as BitLength; -function InputBalance ({ autoFocus, className, defaultValue, help, isDisabled, isError, isZeroable, label, labelExtra, maxValue, onChange, onEnter, placeholder, style, value, withEllipsis, withLabel, withMax }: Props): React.ReactElement { +function InputBalance ({ autoFocus, className, defaultValue: inDefault, help, isDisabled, isError, isZeroable, label, labelExtra, maxValue, onChange, onEnter, placeholder, style, value, withEllipsis, withLabel, withMax }: Props): React.ReactElement { + const defaultValue = inDefault + ? formatBalance(value, { forceUnit: '-', withSi: false }) + : inDefault; + return ( than allowed max !bn.lt(getGlobalMaxValue(bitLength)) || + // check if 0 and it should be a value (!isZeroable && bn.eq(ZERO)) || + // check that the bitlengths fit bn.bitLength() > (bitLength || DEFAULT_BITLENGTH) || + // cannot be > max (if specified) (maxValue && maxValue.gtn(0) && bn.gt(maxValue)) ) { return false; @@ -197,7 +202,7 @@ function InputNumber (props: Props): React.ReactElement { ); useEffect((): void => { - if (!!propsValue && isNewPropsValue(propsValue, value, valueBn)) { + if (propsValue && isNewPropsValue(propsValue, value, valueBn)) { setValues(getValues(propsValue, si, props)); } }, [propsValue]); @@ -225,7 +230,6 @@ function InputNumber (props: Props): React.ReactElement { const newValue = `${value.substring(0, i || 0)}${event.key}${value.substring(j || 0)}`; if (!getRegex(isDecimal || !!si).test(newValue)) { - console.log(newValue, getRegex(isDecimal || !!si)); event.preventDefault(); } }