mirror of
https://github.com/pezkuwichain/pezkuwi-sdk-ui.git
synced 2026-06-19 06:31:09 +00:00
d949863789
Comprehensive web interface for interacting with Pezkuwi blockchain. Features: - Blockchain explorer - Wallet management - Staking interface - Governance participation - Developer tools Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
134 lines
3.2 KiB
TypeScript
134 lines
3.2 KiB
TypeScript
// Copyright 2017-2026 @pezkuwi/app-explorer authors & contributors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import type { DigestItem } from '@pezkuwi/types/interfaces';
|
|
import type { Codec, TypeDef } from '@pezkuwi/types/types';
|
|
|
|
import React, { useRef } from 'react';
|
|
|
|
import { Expander, Table } from '@pezkuwi/react-components';
|
|
import Params from '@pezkuwi/react-params';
|
|
import { Raw, Struct, Tuple, Vec } from '@pezkuwi/types';
|
|
import { getTypeDef } from '@pezkuwi/types/create';
|
|
|
|
import { useTranslation } from '../translate.js';
|
|
|
|
interface Props {
|
|
value?: DigestItem[];
|
|
}
|
|
|
|
function formatU8a (value: Raw): React.ReactNode {
|
|
return (
|
|
<Params
|
|
isDisabled
|
|
params={[{ type: getTypeDef('Bytes') }]}
|
|
values={[{ isValid: true, value }]}
|
|
withExpander
|
|
/>
|
|
);
|
|
}
|
|
|
|
function formatStruct (struct: Struct): React.ReactNode {
|
|
const params = Object.entries(struct.Type).map(([name, value]): { name: string; type: TypeDef } => ({
|
|
name,
|
|
type: getTypeDef(value)
|
|
}));
|
|
const values = struct.toArray().map((value): { isValid: boolean; value: Codec } => ({
|
|
isValid: true,
|
|
value
|
|
}));
|
|
|
|
return (
|
|
<Params
|
|
isDisabled
|
|
params={params}
|
|
values={values}
|
|
withExpander
|
|
/>
|
|
);
|
|
}
|
|
|
|
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 (
|
|
<Params
|
|
isDisabled
|
|
params={params}
|
|
values={values}
|
|
withExpander
|
|
/>
|
|
);
|
|
}
|
|
|
|
function formatVector (vector: Vec<Codec>): React.ReactNode {
|
|
const type = getTypeDef(vector.Type);
|
|
const values = vector.toArray().map((value): { isValid: boolean; value: Codec } => ({
|
|
isValid: true,
|
|
value
|
|
}));
|
|
const params = values.map((_, index): { name: string; type: TypeDef } => ({
|
|
name: `${index}`,
|
|
type
|
|
}));
|
|
|
|
return (
|
|
<Params
|
|
isDisabled
|
|
params={params}
|
|
values={values}
|
|
withExpander
|
|
/>
|
|
);
|
|
}
|
|
|
|
function formatItem (item: DigestItem): React.ReactNode {
|
|
if (item.value instanceof Struct) {
|
|
return formatStruct(item.value as Struct);
|
|
} else if (item.value instanceof Tuple) {
|
|
return formatTuple(item.value);
|
|
} else if (item.value instanceof Vec) {
|
|
return formatVector(item.value as Vec<Codec>);
|
|
} else if (item.value instanceof Raw) {
|
|
return formatU8a(item.value);
|
|
}
|
|
|
|
return <div>{item.value.toString().split(',').join(', ')}</div>;
|
|
}
|
|
|
|
function Logs ({ value }: Props): React.ReactElement<Props> | null {
|
|
const { t } = useTranslation();
|
|
|
|
const headerRef = useRef<([React.ReactNode?, string?, number?] | false)[]>([
|
|
[t('logs'), 'start']
|
|
]);
|
|
|
|
return (
|
|
<Table
|
|
empty={t('No logs available')}
|
|
header={headerRef.current}
|
|
>
|
|
{value?.map((log, index) => (
|
|
<tr key={`log:${index}`}>
|
|
<td className='overflow'>
|
|
<Expander
|
|
isLeft
|
|
summary={log.type.toString()}
|
|
>
|
|
{formatItem(log)}
|
|
</Expander>
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</Table>
|
|
);
|
|
}
|
|
|
|
export default React.memo(Logs);
|