diff --git a/packages/page-explorer/src/BlockInfo/ByHash.tsx b/packages/page-explorer/src/BlockInfo/ByHash.tsx index 649364f6f7..59f0778165 100644 --- a/packages/page-explorer/src/BlockInfo/ByHash.tsx +++ b/packages/page-explorer/src/BlockInfo/ByHash.tsx @@ -3,6 +3,7 @@ // of the Apache-2.0 license. See the LICENSE file for details. import { EventRecord, SignedBlock } from '@polkadot/types/interfaces'; +import { KeyedEvent } from '../types'; import React from 'react'; import { Link } from 'react-router-dom'; @@ -24,7 +25,14 @@ interface Props { function BlockByHash ({ className, value }: Props): React.ReactElement { const { t } = useTranslation(); const { api } = useApi(); - const events = useCall(api.query.system.events.at, [value], { isSingle: true }); + const events = useCall(api.query.system.events.at, [value], { + isSingle: true, + transform: (events: EventRecord[]): KeyedEvent[] => + events.map((record) => ({ + key: `${Date.now()}-${record.hash.toHex()}`, + record + })) + }); const getBlock = useCall(api.rpc.chain.getBlock, [value], { isSingle: true }); const getHeader = useCall(api.derive.chain.getHeader, [value]); @@ -79,7 +87,7 @@ function BlockByHash ({ className, value }: Props): React.ReactElement { !phase.isApplyExtrinsic)} + events={events} label={t('system events')} /> diff --git a/packages/page-explorer/src/BlockInfo/Extrinsic.tsx b/packages/page-explorer/src/BlockInfo/Extrinsic.tsx index 1a4fedcdba..14a6be4342 100644 --- a/packages/page-explorer/src/BlockInfo/Extrinsic.tsx +++ b/packages/page-explorer/src/BlockInfo/Extrinsic.tsx @@ -2,7 +2,8 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { BlockNumber, EventRecord, Extrinsic } from '@polkadot/types/interfaces'; +import { BlockNumber, Extrinsic } from '@polkadot/types/interfaces'; +import { KeyedEvent } from '../types'; import React from 'react'; import styled from 'styled-components'; @@ -16,7 +17,7 @@ import Event from '../Event'; interface Props { blockNumber?: BlockNumber; className?: string; - events?: EventRecord[]; + events?: KeyedEvent[]; index: number; value: Extrinsic; } @@ -31,8 +32,8 @@ function getEra ({ era }: Extrinsic, blockNumber?: BlockNumber): [number, number return null; } -function filterEvents (index: number, events: EventRecord[] = []): EventRecord[] { - return events.filter(({ phase }) => phase.isApplyExtrinsic && phase.asApplyExtrinsic.eq(index)); +function filterEvents (index: number, events: KeyedEvent[] = []): KeyedEvent[] { + return events.filter(({ record: { phase } }) => phase.isApplyExtrinsic && phase.asApplyExtrinsic.eq(index)); } function ExtrinsicDisplay ({ blockNumber, className, events, index, value }: Props): React.ReactElement { @@ -76,11 +77,11 @@ function ExtrinsicDisplay ({ blockNumber, className, events, index, value }: Pro className='top' colSpan={2} > - {thisEvents.map((event, index) => + {thisEvents.map(({ key, record }) => )} diff --git a/packages/page-explorer/src/BlockInfo/Extrinsics.tsx b/packages/page-explorer/src/BlockInfo/Extrinsics.tsx index 757d3fa263..7fcc52e768 100644 --- a/packages/page-explorer/src/BlockInfo/Extrinsics.tsx +++ b/packages/page-explorer/src/BlockInfo/Extrinsics.tsx @@ -2,7 +2,8 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { BlockNumber, EventRecord, Extrinsic } from '@polkadot/types/interfaces'; +import { BlockNumber, Extrinsic } from '@polkadot/types/interfaces'; +import { KeyedEvent } from '../types'; import React, { useMemo } from 'react'; import { Table } from '@polkadot/react-components'; @@ -13,7 +14,7 @@ import ExtrinsicDisplay from './Extrinsic'; interface Props { blockNumber?: BlockNumber; className?: string; - events?: EventRecord[]; + events?: KeyedEvent[]; label?: React.ReactNode; value?: Extrinsic[] | null; } diff --git a/packages/page-explorer/src/Events.tsx b/packages/page-explorer/src/Events.tsx index ee64bff87e..4efbf7facb 100644 --- a/packages/page-explorer/src/Events.tsx +++ b/packages/page-explorer/src/Events.tsx @@ -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 { EventRecord } from '@polkadot/types/interfaces'; +import { KeyedEvent } from './types'; import React, { useMemo } from 'react'; import { Table } from '@polkadot/react-components'; @@ -12,7 +12,7 @@ import { useTranslation } from './translate'; interface Props { emptyLabel?: React.ReactNode; - events: EventRecord[]; + events?: KeyedEvent[]; eventClassName?: string; label?: React.ReactNode; } @@ -29,15 +29,15 @@ function Events ({ emptyLabel, eventClassName, events, label }: Props): React.Re empty={emptyLabel || t('No events available')} header={header} > - {events - .filter(({ event: { method, section } }): boolean => !!method && !!section) - .map((event: EventRecord, index): React.ReactNode => ( + {events && events + .filter(({ record: { event: { method, section } } }) => !!method && !!section) + .map(({ key, record }): React.ReactNode => ( - + )) diff --git a/packages/page-explorer/src/Main.tsx b/packages/page-explorer/src/Main.tsx index c87a7e6c2f..e7737b0137 100644 --- a/packages/page-explorer/src/Main.tsx +++ b/packages/page-explorer/src/Main.tsx @@ -28,7 +28,7 @@ function Main ({ events, headers }: Props): React.ReactElement { - record)} /> + diff --git a/packages/react-params/src/Param/Account.tsx b/packages/react-params/src/Param/Account.tsx index 1f4f8f9054..34f2a75e65 100644 --- a/packages/react-params/src/Param/Account.tsx +++ b/packages/react-params/src/Param/Account.tsx @@ -4,36 +4,36 @@ import { Props } from '../types'; -import React from 'react'; +import React, { useCallback, useState } from 'react'; import { InputAddress } from '@polkadot/react-components'; import keyring from '@polkadot/ui-keyring'; import Bare from './Bare'; -function onChange ({ onChange }: Props): (_?: string | null) => void { - return (value?: string | null): void => { - let isValid = false; +function Account ({ className, defaultValue: { value }, isDisabled, isError, label, onChange, style, withLabel }: Props): React.ReactElement { + const [defaultValue] = useState(value?.toString()); - if (value) { - try { - keyring.decodeAddress(value); + const _onChange = useCallback( + (value?: string | null): void => { + let isValid = false; - isValid = true; - } catch (err) { - console.error(err); + if (value) { + try { + keyring.decodeAddress(value); + + isValid = true; + } catch (err) { + console.error(err); + } } - } - onChange && onChange({ - isValid, - value - }); - }; -} - -function Account (props: Props): React.ReactElement { - const { className, defaultValue: { value }, isDisabled, isError, label, style, withLabel } = props; - const defaultValue = value && value.toString(); + onChange && onChange({ + isValid, + value + }); + }, + [onChange] + ); return ( { isError={isError} isInput label={label} - onChange={onChange(props)} + onChange={_onChange} placeholder='5...' type='allPlus' withEllipsis diff --git a/packages/react-params/src/Param/Amount.tsx b/packages/react-params/src/Param/Amount.tsx index 2baaa821ea..81792f0b5c 100644 --- a/packages/react-params/src/Param/Amount.tsx +++ b/packages/react-params/src/Param/Amount.tsx @@ -5,7 +5,7 @@ import { Props } from '../types'; import BN from 'bn.js'; -import React from 'react'; +import React, { useCallback, useState } from 'react'; import { registry } from '@polkadot/react-api'; import { Input } from '@polkadot/react-components'; import { ClassOf } from '@polkadot/types'; @@ -13,24 +13,25 @@ import { bnToBn, formatNumber } from '@polkadot/util'; import Bare from './Bare'; -function onChange ({ onChange }: Props): (_: string) => void { - return function (value: string): void { - onChange && onChange({ - isValid: true, - value: new BN(value || 0) - }); - }; -} +function Amount ({ className, defaultValue: { value }, isDisabled, isError, label, onChange, onEnter, style, withLabel }: Props): React.ReactElement { + const [defaultValue] = useState( + isDisabled + ? ( + value instanceof ClassOf(registry, 'AccountIndex') + ? value.toString() + : formatNumber(value) + ) + : bnToBn((value as number) || 0).toString() + ); -function Amount (props: Props): React.ReactElement { - const { className, defaultValue: { value }, isDisabled, isError, label, onEnter, style, withLabel } = props; - const defaultValue = isDisabled - ? ( - value instanceof ClassOf(registry, 'AccountIndex') - ? value.toString() - : formatNumber(value) - ) - : bnToBn((value as number) || 0).toString(); + const _onChange = useCallback( + (value: string) => + onChange && onChange({ + isValid: true, + value: new BN(value || 0) + }), + [onChange] + ); return ( { isError={isError} label={label} min={0} - onChange={onChange(props)} + onChange={_onChange} onEnter={onEnter} type={ isDisabled diff --git a/packages/react-params/src/Param/BaseBytes.tsx b/packages/react-params/src/Param/BaseBytes.tsx index 8348bf107e..530446636a 100644 --- a/packages/react-params/src/Param/BaseBytes.tsx +++ b/packages/react-params/src/Param/BaseBytes.tsx @@ -43,6 +43,13 @@ function convertInput (value: string): [boolean, Uint8Array] { } function BaseBytes ({ asHex, children, className, defaultValue: { value }, isDisabled, isError, label, length = -1, onChange, onEnter, onEscape, size = 'full', style, validate = defaultValidate, withLabel, withLength }: Props): React.ReactElement { + const [defaultValue] = useState( + value + ? isHex(value) + ? value + : u8aToHex(value as Uint8Array, isDisabled ? 256 : -1) + : undefined + ); const [isValid, setIsValid] = useState(false); useEffect((): void => { @@ -83,14 +90,6 @@ function BaseBytes ({ asHex, children, className, defaultValue: { value }, isDis [asHex, length, onChange, validate, withLength] ); - const defaultValue = value - ? ( - isHex(value) - ? value - : u8aToHex(value as Uint8Array, isDisabled ? 256 : -1) - ) - : undefined; - return ( { + const { t } = useTranslation(); + const [defaultValue] = useState( + value instanceof Boolean + ? value.valueOf() + : value as boolean + ); -function onChange ({ onChange }: Props): (_: boolean) => void { - return function (value: boolean): void { - onChange && onChange({ - isValid: true, - value - }); - }; -} + const options = useMemo( + () => [ + { text: t('No'), value: false }, + { text: t('Yes'), value: true } + ], + [t] + ); -function BoolParam (props: Props): React.ReactElement { - const { className, defaultValue: { value }, isDisabled, isError, label, style, withLabel } = props; - const defaultValue = value instanceof Boolean - ? value.valueOf() - : value as boolean; + const _onChange = useCallback( + (value: boolean) => + onChange && onChange({ + isValid: true, + value + }), + [onChange] + ); return ( { isDisabled={isDisabled} isError={isError} label={label} - onChange={onChange(props)} + onChange={_onChange} options={options} withEllipsis withLabel={withLabel} diff --git a/packages/react-params/src/Param/Code.tsx b/packages/react-params/src/Param/Code.tsx index a960456934..dfddb03c6a 100644 --- a/packages/react-params/src/Param/Code.tsx +++ b/packages/react-params/src/Param/Code.tsx @@ -4,45 +4,35 @@ import { Props } from '../types'; -import React from 'react'; +import React, { useCallback } from 'react'; import Bytes from './Bytes'; import BytesFile from './File'; -function renderDisabled ({ className, defaultValue, isError, label, onEnter, onEscape, style, type, withLabel }: Props): React.ReactNode { - return ( - +function Code ({ className, defaultValue, isDisabled, isError, label, onChange, onEnter, onEscape, style, type, withLabel }: Props): React.ReactElement { + // TODO: Validate that we have actual proper WASM code + const _onChange = useCallback( + (value: Uint8Array) => + onChange && onChange({ + isValid: value.length !== 0, + value + }), + [onChange] ); -} - -// TODO: Validate that we have actual proper WASM code -function onChange ({ onChange }: Props): (_: Uint8Array) => void { - return function (value: Uint8Array): void { - onChange && onChange({ - isValid: value.length !== 0, - value - }); - }; -} - -function Code (props: Props): React.ReactElement { - const { className, defaultValue, isDisabled, isError, label, style, withLabel } = props; if (isDisabled) { return ( - <> - {renderDisabled(props)} - + ); } @@ -52,7 +42,7 @@ function Code (props: Props): React.ReactElement { defaultValue={defaultValue} isError={isError} label={label} - onChange={onChange(props)} + onChange={_onChange} style={style} withLabel={withLabel} /> diff --git a/packages/react-params/src/Param/Moment.tsx b/packages/react-params/src/Param/Moment.tsx index 74a4a41532..386286020a 100644 --- a/packages/react-params/src/Param/Moment.tsx +++ b/packages/react-params/src/Param/Moment.tsx @@ -4,43 +4,32 @@ import { Props, RawParamOnChangeValue } from '../types'; -import React from 'react'; +import React, { useCallback } from 'react'; import { Static } from '@polkadot/react-components'; import Amount from './Amount'; -function renderDisabled ({ className, defaultValue, isError, label, style, withLabel }: Props): React.ReactNode { - return ( - +function Moment ({ className, defaultValue, isDisabled, isError, label, onChange, onEnter, onEscape, style, type, withLabel }: Props): React.ReactElement { + const _onChange = useCallback( + (value: RawParamOnChangeValue) => + onChange && onChange(value), + [onChange] ); -} - -// TODO: Validate that we have actual proper WASM code -function onChange ({ onChange }: Props): (_: RawParamOnChangeValue) => void { - return function (value: RawParamOnChangeValue): void { - onChange && onChange(value); - }; -} - -function Moment (props: Props): React.ReactElement { - const { className, defaultValue, isDisabled, isError, label, onEnter, onEscape, style, type, withLabel } = props; if (isDisabled) { return ( - <> - {renderDisabled(props)} - + ); } @@ -51,7 +40,7 @@ function Moment (props: Props): React.ReactElement { isDisabled={isDisabled} isError={isError} label={label} - onChange={onChange(props)} + onChange={_onChange} onEnter={onEnter} onEscape={onEscape} style={style} diff --git a/packages/react-params/src/Param/Raw.tsx b/packages/react-params/src/Param/Raw.tsx index 56b3577ea8..20b21623cb 100644 --- a/packages/react-params/src/Param/Raw.tsx +++ b/packages/react-params/src/Param/Raw.tsx @@ -4,24 +4,24 @@ import { Props } from '../types'; -import React from 'react'; +import React, { useCallback } from 'react'; import { Input } from '@polkadot/react-components'; import Bare from './Bare'; -function onChange ({ onChange }: Props): (_: string) => void { - return function (value: string): void { - const isValid = value.length !== 0; +function Raw ({ className, defaultValue: { value }, isDisabled, isError, label, onChange, onEnter, onEscape, style, withLabel }: Props): React.ReactElement { + const _onChange = useCallback( + (value: string): void => { + const isValid = value.length !== 0; - onChange && onChange({ - isValid, - value - }); - }; -} + onChange && onChange({ + isValid, + value + }); + }, + [onChange] + ); -function Raw (props: Props): React.ReactElement { - const { className, defaultValue: { value }, isDisabled, isError, label, onEnter, onEscape, style, withLabel } = props; const defaultValue = value ? (value.toHex ? value.toHex() : value) : ''; @@ -37,7 +37,7 @@ function Raw (props: Props): React.ReactElement { isDisabled={isDisabled} isError={isError} label={label} - onChange={onChange(props)} + onChange={_onChange} onEnter={onEnter} onEscape={onEscape} placeholder='Hex data' diff --git a/packages/react-params/src/Param/Text.tsx b/packages/react-params/src/Param/Text.tsx index 61e58e0a57..8b182090b2 100644 --- a/packages/react-params/src/Param/Text.tsx +++ b/packages/react-params/src/Param/Text.tsx @@ -4,24 +4,21 @@ import { Props } from '../types'; -import React from 'react'; +import React, { useCallback } from 'react'; import { Input } from '@polkadot/react-components'; import Bare from './Bare'; -function onChange ({ onChange }: Props): (_: string) => void { - return function (value: string): void { - const isValid = value.length !== 0; +function Text ({ className, defaultValue: { value }, isDisabled, isError, label, onChange, onEnter, onEscape, style, withLabel }: Props): React.ReactElement { + const _onChange = useCallback( + (value: string) => + onChange && onChange({ + isValid: value.length !== 0, + value + }), + [onChange] + ); - onChange && onChange({ - isValid, - value - }); - }; -} - -function Text (props: Props): React.ReactElement { - const { className, defaultValue: { value }, isDisabled, isError, label, onEnter, onEscape, style, withLabel } = props; const defaultValue = (value || '').toString(); return ( @@ -35,7 +32,7 @@ function Text (props: Props): React.ReactElement { isDisabled={isDisabled} isError={isError} label={label} - onChange={onChange(props)} + onChange={_onChange} onEnter={onEnter} onEscape={onEscape} placeholder='' diff --git a/packages/react-params/src/Param/VoteThreshold.tsx b/packages/react-params/src/Param/VoteThreshold.tsx index 2f40a9f05c..2ee7426743 100644 --- a/packages/react-params/src/Param/VoteThreshold.tsx +++ b/packages/react-params/src/Param/VoteThreshold.tsx @@ -4,7 +4,7 @@ import { Props } from '../types'; -import React from 'react'; +import React, { useCallback } from 'react'; import { ClassOf } from '@polkadot/types'; import { registry } from '@polkadot/react-api'; import { Dropdown } from '@polkadot/react-components'; @@ -26,17 +26,16 @@ export const textMap = options.reduce((textMap, { text, value }): TextMap => { return textMap; }, {} as unknown as TextMap); -function onChange ({ onChange }: Props): (_: number) => void { - return function (value: number): void { - onChange && onChange({ - isValid: true, - value - }); - }; -} +function VoteThresholdParam ({ className, defaultValue: { value }, isDisabled, isError, label, onChange, style, withLabel }: Props): React.ReactElement { + const _onChange = useCallback( + (value: number) => + onChange && onChange({ + isValid: true, + value + }), + [onChange] + ); -function VoteThresholdParam (props: Props): React.ReactElement { - const { className, defaultValue: { value }, isDisabled, isError, label, style, withLabel } = props; const defaultValue = value instanceof ClassOf(registry, 'VoteThreshold') ? value.toNumber() : bnToBn(value as number).toNumber(); @@ -52,7 +51,7 @@ function VoteThresholdParam (props: Props): React.ReactElement { isDisabled={isDisabled} isError={isError} label={label} - onChange={onChange(props)} + onChange={_onChange} options={options} withLabel={withLabel} />