From ecb61d02aee7e63b72e935fedb5a0e3e437fb0aa Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Thu, 10 Jan 2019 17:28:49 +0100 Subject: [PATCH] Display balance with calculated SI units (#583) * Display balance with calculated SI units * Unused auto-import * Update tests (format params) --- packages/ui-app/src/InputNumber.tsx | 16 +++++++++++++-- packages/ui-params/src/Param/Balance.tsx | 5 +---- .../src/util/balanceFormat.spec.js | 20 ++++++++++++------- .../ui-react-rx/src/util/balanceFormat.ts | 13 +++++++----- packages/ui-react-rx/src/util/index.ts | 3 ++- 5 files changed, 38 insertions(+), 19 deletions(-) diff --git a/packages/ui-app/src/InputNumber.tsx b/packages/ui-app/src/InputNumber.tsx index dbf56faa97..7ab711c447 100644 --- a/packages/ui-app/src/InputNumber.tsx +++ b/packages/ui-app/src/InputNumber.tsx @@ -6,7 +6,7 @@ import { BareProps, BitLength, I18nProps } from './types'; import BN from 'bn.js'; import React from 'react'; -import { balanceFormat } from '@polkadot/ui-react-rx/util/index'; +import { balanceFormat, calcSi } from '@polkadot/ui-react-rx/util/index'; import classes from './util/classes'; import { BitLengthOption } from './constants'; @@ -29,6 +29,7 @@ type Props = BareProps & I18nProps & { }; type State = { + defaultValue?: string, isPreKeyDown: boolean, isValid: boolean, siOptions: Array<{ value: string, text: string }>, @@ -68,6 +69,17 @@ class InputNumber extends React.PureComponent { InputNumber.units = units; } + static getDerivedStateFromProps ({ isDisabled, isSi, defaultValue = '0' }: Props): Partial | null { + if (!isDisabled || !isSi) { + return null; + } + + return { + defaultValue: balanceFormat(defaultValue, false), + siUnit: calcSi(defaultValue).value + }; + } + render () { const { bitLength = DEFAULT_BITLENGTH, className, defaultValue = '0', isSi, isDisabled, maxLength, style, t } = this.props; const { isValid } = this.state; @@ -80,7 +92,7 @@ class InputNumber extends React.PureComponent { > { render () { const { className, defaultValue: { value }, isDisabled, isError, label, style, withLabel } = this.props; - const defaultValue = isDisabled - ? balanceFormat(value) - : new BN(value as BN || '0').toString(10); + const defaultValue = new BN((value as BN || '0').toString()).toString(10); return ( { it('formats 123,456,789,000 (decimals=15)', () => { expect( - balanceFormat(TESTVAL, 15) + balanceFormat(TESTVAL, true, 15) ).toEqual('123.456ยต'); }); it('formats 123,456,789,000 (decimals=12)', () => { expect( - balanceFormat(TESTVAL, 12) + balanceFormat(TESTVAL, true, 12) ).toEqual('123.456m'); }); + it('formats 123,456,789,000 (decimals=12, no SI)', () => { + expect( + balanceFormat(TESTVAL, false, 12) + ).toEqual('123.456'); + }); + it('formats 123,456,789,000 (decimals=9)', () => { expect( - balanceFormat(TESTVAL, 9) + balanceFormat(TESTVAL, true, 9) ).toEqual('123.456'); }); it('formats 123,456,789,000 (decimals=6)', () => { expect( - balanceFormat(TESTVAL, 6) + balanceFormat(TESTVAL, true, 6) ).toEqual('123.456k'); }); it('formats 123,456,789,000 * 10 (decimals=12)', () => { expect( - balanceFormat(TESTVAL.muln(10), 12) + balanceFormat(TESTVAL.muln(10), true, 12) ).toEqual('1.234'); }); it('formats 123,456,789,000 * 100 (decimals=12)', () => { expect( - balanceFormat(TESTVAL.muln(100), 12) + balanceFormat(TESTVAL.muln(100), true, 12) ).toEqual('12.345'); }); it('formats 123,456,789,000 * 1000 (decimals=12)', () => { expect( - balanceFormat(TESTVAL.muln(1000), 12) + balanceFormat(TESTVAL.muln(1000), true, 12) ).toEqual('123.456'); }); diff --git a/packages/ui-react-rx/src/util/balanceFormat.ts b/packages/ui-react-rx/src/util/balanceFormat.ts index bb19edbe4b..c874dfabc6 100644 --- a/packages/ui-react-rx/src/util/balanceFormat.ts +++ b/packages/ui-react-rx/src/util/balanceFormat.ts @@ -3,7 +3,6 @@ // of the Apache-2.0 license. See the LICENSE file for details. import BN from 'bn.js'; -import { UInt } from '@polkadot/types/codec'; import decimalFormat from './decimalFormat'; @@ -14,7 +13,7 @@ type SiDef = { }; interface BalanceFormatter { - (input: string | BN | UInt, decimals?: number): string; + (input: string | BN, withSi?: boolean, decimals?: number): string; findSi (type: string): SiDef; getDefaultDecimals (): number; getOptions (decimals?: number): Array; @@ -45,8 +44,12 @@ const SI_MID = 8; let defaultDecimals = 0; +export function calcSi (text: string, decimals: number = defaultDecimals): SiDef { + return SI[(SI_MID - 1) + Math.ceil((text.length - decimals) / 3)]; +} + // Formats a string/number with . notation -function _balanceFormat (input: string | BN | UInt, decimals: number = defaultDecimals): string { +function _balanceFormat (input: string | BN, withSi: boolean = true, decimals: number = defaultDecimals): string { const text = (input || '').toString(); if (text.length === 0 || text === '0') { @@ -56,12 +59,12 @@ function _balanceFormat (input: string | BN | UInt, decimals: number = defaultDe // NOTE We start at midpoint (8) minus 1 - this means that values display as // 123.456 instead of 0.123k (so always 6 relevant). Additionally we us ceil // so there are at most 3 decimal before the decimal seperator - const si = SI[(SI_MID - 1) + Math.ceil((text.length - decimals) / 3)]; + const si = calcSi(text, decimals); const mid = text.length - (decimals + si.power); const prefix = text.substr(0, mid); const postfix = `${text.substr(mid)}000`.substr(0, 3); - return `${decimalFormat(prefix || '0')}.${postfix}${si.value === '-' ? '' : si.value}`; + return `${decimalFormat(prefix || '0')}.${postfix}${withSi ? (si.value === '-' ? '' : si.value) : ''}`; } const balanceFormat = _balanceFormat as BalanceFormatter; diff --git a/packages/ui-react-rx/src/util/index.ts b/packages/ui-react-rx/src/util/index.ts index c18c87c5e8..507d07368e 100644 --- a/packages/ui-react-rx/src/util/index.ts +++ b/packages/ui-react-rx/src/util/index.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import balanceFormat from './balanceFormat'; +import balanceFormat, { calcSi } from './balanceFormat'; import decimalFormat from './decimalFormat'; import intervalObservable from './intervalObservable'; import intervalTimer from './intervalTimer'; @@ -13,6 +13,7 @@ import triggerChange from './triggerChange'; export { balanceFormat, + calcSi, decimalFormat, intervalObservable, intervalTimer,