From 2b6c6f16c497c7464382f9f09dbced008f0d8616 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Tue, 23 Mar 2021 13:25:42 +0100 Subject: [PATCH] Display justifications (#4876) --- .../page-explorer/src/BlockInfo/ByHash.tsx | 2 + .../src/BlockInfo/Justifications.tsx | 67 +++++++++++++++++++ packages/page-explorer/src/BlockInfo/Logs.tsx | 11 ++- 3 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 packages/page-explorer/src/BlockInfo/Justifications.tsx diff --git a/packages/page-explorer/src/BlockInfo/ByHash.tsx b/packages/page-explorer/src/BlockInfo/ByHash.tsx index 445adb2735..f006feff43 100644 --- a/packages/page-explorer/src/BlockInfo/ByHash.tsx +++ b/packages/page-explorer/src/BlockInfo/ByHash.tsx @@ -15,6 +15,7 @@ import { formatNumber } from '@polkadot/util'; import Events from '../Events'; import { useTranslation } from '../translate'; import Extrinsics from './Extrinsics'; +import Justifications from './Justifications'; import Logs from './Logs'; interface Props { @@ -122,6 +123,7 @@ function BlockByHash ({ className = '', error, value }: Props): React.ReactEleme + diff --git a/packages/page-explorer/src/BlockInfo/Justifications.tsx b/packages/page-explorer/src/BlockInfo/Justifications.tsx new file mode 100644 index 0000000000..d4a2832467 --- /dev/null +++ b/packages/page-explorer/src/BlockInfo/Justifications.tsx @@ -0,0 +1,67 @@ +// Copyright 2017-2021 @polkadot/app-explorer authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { Option, Tuple } from '@polkadot/types'; +import type { Justifications } from '@polkadot/types/interfaces'; +import type { Codec, TypeDef } from '@polkadot/types/types'; + +import React, { useRef } from 'react'; + +import { Expander, Table } from '@polkadot/react-components'; +import Params from '@polkadot/react-params'; +import { getTypeDef } from '@polkadot/types/create'; + +import { useTranslation } from '../translate'; + +interface Props { + value: Option; +} + +function formatTuple (tuple: Tuple): React.ReactNode { + const params = tuple.Types.map((type): { type: TypeDef } => ({ + type: getTypeDef(type) + })); + const values = tuple.toArray().map((value): { isValid: boolean; value: Codec } => ({ + isValid: true, + value + })); + + return ( + + ); +} + +function JustificationList ({ value }: Props): React.ReactElement | null { + const { t } = useTranslation(); + + const headerRef = useRef([[t('justifications'), 'start']]); + + const justifications = value.unwrapOr(null); + + if (!justifications) { + return null; + } + + return ( + ('No justifications available')} + header={headerRef.current} + > + {justifications?.map((justification, index) => ( + + + + ))} +
+ + {formatTuple(justification as unknown as Tuple)} + +
+ ); +} + +export default React.memo(JustificationList); diff --git a/packages/page-explorer/src/BlockInfo/Logs.tsx b/packages/page-explorer/src/BlockInfo/Logs.tsx index d07a5e2d95..b9f8852baf 100644 --- a/packages/page-explorer/src/BlockInfo/Logs.tsx +++ b/packages/page-explorer/src/BlockInfo/Logs.tsx @@ -28,10 +28,9 @@ function formatU8a (value: Raw): React.ReactNode { } function formatStruct (struct: Struct): React.ReactNode { - const types: Record = struct.Type; - const params = Object.keys(types).map((name): { name: string; type: TypeDef } => ({ + const params = Object.entries(struct.Type).map(([name, value]): { name: string; type: TypeDef } => ({ name, - type: getTypeDef(types[name]) + type: getTypeDef(value) })); const values = struct.toArray().map((value): { isValid: boolean; value: Codec } => ({ isValid: true, @@ -48,8 +47,7 @@ function formatStruct (struct: Struct): React.ReactNode { } function formatTuple (tuple: Tuple): React.ReactNode { - const types = tuple.Types; - const params = types.map((type): { type: TypeDef } => ({ + const params = tuple.Types.map((type): { type: TypeDef } => ({ type: getTypeDef(type) })); const values = tuple.toArray().map((value): { isValid: boolean; value: Codec } => ({ @@ -100,8 +98,7 @@ function formatItem (item: DigestItem): React.ReactNode { return
{item.value.toString().split(',').join(', ')}
; } -function Logs (props: Props): React.ReactElement | null { - const { value } = props; +function Logs ({ value }: Props): React.ReactElement | null { const { t } = useTranslation(); const headerRef = useRef([[t('logs'), 'start']]);