Display parachains proposal list (#3438)
This commit is contained in:
parent
a41bf99f39
commit
7d6719dd20
@ -28,7 +28,7 @@ function Parachains ({ parachains }: Props): React.ReactElement<Props> {
|
||||
|
||||
return (
|
||||
<Table
|
||||
empty={t<string>('There are no registered parachains')}
|
||||
empty={parachains && t<string>('There are no registered parachains')}
|
||||
header={headerRef.current}
|
||||
>
|
||||
{parachains?.map((parachain): React.ReactNode => (
|
||||
|
||||
53
packages/page-parachains/src/Overview/Proposal.tsx
Normal file
53
packages/page-parachains/src/Overview/Proposal.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2017-2020 @polkadot/app-parachains authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ProposalExt } from './types';
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
import { AddressSmall, AddressMini } from '@polkadot/react-components';
|
||||
import { FormatBalance } from '@polkadot/react-query';
|
||||
import { formatNumber } from '@polkadot/util';
|
||||
|
||||
interface Props {
|
||||
proposal: ProposalExt;
|
||||
}
|
||||
|
||||
function Proposal ({ proposal: { id, proposal: { balance, initialHeadState, name, proposer, validationFunction, validators } } }: Props): React.ReactElement<Props> {
|
||||
const initialHex = useMemo(
|
||||
(): string => {
|
||||
const hex = initialHeadState.toHex();
|
||||
|
||||
return `${hex.slice(0, 10)}…${hex.slice(-8)}`;
|
||||
},
|
||||
[initialHeadState]
|
||||
);
|
||||
|
||||
const validationHex = useMemo(
|
||||
(): string => {
|
||||
const hex = validationFunction.toHex();
|
||||
|
||||
return `${hex.slice(0, 10)}…${hex.slice(-8)}`;
|
||||
},
|
||||
[validationFunction]
|
||||
);
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<td className='number'><h1>{formatNumber(id)}</h1></td>
|
||||
<td className='start'>{name.toUtf8()}</td>
|
||||
<td className='address'><AddressSmall value={proposer} /></td>
|
||||
<td className='balance'><FormatBalance value={balance} /></td>
|
||||
<td className='start hash'>{initialHex}</td>
|
||||
<td className='start hash'>{validationHex}</td>
|
||||
<td className='address all'>{validators.map((validatorId) => (
|
||||
<AddressMini
|
||||
key={validatorId.toString()}
|
||||
value={validatorId}
|
||||
/>
|
||||
))}</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(Proposal);
|
||||
44
packages/page-parachains/src/Overview/Proposals.tsx
Normal file
44
packages/page-parachains/src/Overview/Proposals.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2017-2020 @polkadot/app-parachains authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ProposalExt } from './types';
|
||||
|
||||
import React, { useRef } from 'react';
|
||||
import { Table } from '@polkadot/react-components';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
import Proposal from './Proposal';
|
||||
|
||||
interface Props {
|
||||
proposals?: ProposalExt[];
|
||||
}
|
||||
|
||||
function Proposals ({ proposals }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const headerRef = useRef([
|
||||
[t('proposals'), 'start', 2],
|
||||
[t('proposer'), 'address'],
|
||||
[t('balance')],
|
||||
[t('initial state'), 'start'],
|
||||
[t('validation'), 'start'],
|
||||
[t('validators')]
|
||||
]);
|
||||
|
||||
return (
|
||||
<Table
|
||||
empty={proposals && t<string>('There are no pending proposals')}
|
||||
header={headerRef.current}
|
||||
>
|
||||
{proposals?.map((proposal): React.ReactNode => (
|
||||
<Proposal
|
||||
key={proposal.id.toString()}
|
||||
proposal={proposal}
|
||||
/>
|
||||
))}
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(Proposals);
|
||||
@ -13,10 +13,11 @@ import { useTranslation } from '../translate';
|
||||
|
||||
interface Props {
|
||||
parachainCount?: number;
|
||||
proposalCount?: number;
|
||||
nextFreeId?: BN;
|
||||
}
|
||||
|
||||
function Summary ({ nextFreeId, parachainCount }: Props): React.ReactElement<Props> {
|
||||
function Summary ({ nextFreeId, parachainCount, proposalCount }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
|
||||
@ -34,6 +35,11 @@ function Summary ({ nextFreeId, parachainCount }: Props): React.ReactElement<Pro
|
||||
{formatNumber(parachainCount)}
|
||||
</CardSummary>
|
||||
)}
|
||||
{isNumber(proposalCount) && (
|
||||
<CardSummary label={t<string>('proposals')}>
|
||||
{formatNumber(proposalCount)}
|
||||
</CardSummary>
|
||||
)}
|
||||
{api.query.parachains && nextFreeId && (
|
||||
<CardSummary label={t<string>('next id')}>
|
||||
{formatNumber(nextFreeId)}
|
||||
|
||||
@ -3,14 +3,18 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { DeriveParachain } from '@polkadot/api-derive/types';
|
||||
import { ParaId, ParachainProposal } from '@polkadot/types/interfaces';
|
||||
import { ProposalExt } from './types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import React from 'react';
|
||||
import { Button } from '@polkadot/react-components';
|
||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
import { Option } from '@polkadot/types';
|
||||
|
||||
import Transfer from '../Transfer';
|
||||
import Parachains from './Parachains';
|
||||
import Proposals from './Proposals';
|
||||
import Register from './Register';
|
||||
import Summary from './Summary';
|
||||
|
||||
@ -19,9 +23,18 @@ interface Props {
|
||||
sudoKey?: string;
|
||||
}
|
||||
|
||||
const transformProposals = {
|
||||
transform: (entries: [{ args: [ParaId] }, Option<ParachainProposal>][]): ProposalExt[] => {
|
||||
return entries
|
||||
.filter(([, opt]) => opt.isSome)
|
||||
.map(([{ args: [id] }, optProposal]) => ({ id, proposal: optProposal.unwrap() }));
|
||||
}
|
||||
};
|
||||
|
||||
function Overview ({ isMine, sudoKey }: Props): React.ReactElement<Props> {
|
||||
const { api } = useApi();
|
||||
const parachains = useCall<DeriveParachain[]>(api.derive.parachains?.overview);
|
||||
const proposals = useCall<ProposalExt[]>(api.query.proposeParachain?.proposals.entries as any, undefined, transformProposals);
|
||||
const nextFreeId = useCall<BN>(api.query.registrar?.nextFreeId);
|
||||
|
||||
return (
|
||||
@ -29,6 +42,7 @@ function Overview ({ isMine, sudoKey }: Props): React.ReactElement<Props> {
|
||||
<Summary
|
||||
nextFreeId={nextFreeId}
|
||||
parachainCount={parachains?.length}
|
||||
proposalCount={proposals?.length}
|
||||
/>
|
||||
<Button.Group>
|
||||
<Transfer parachains={parachains} />
|
||||
@ -43,6 +57,9 @@ function Overview ({ isMine, sudoKey }: Props): React.ReactElement<Props> {
|
||||
{api.query.parachains && (
|
||||
<Parachains parachains={parachains} />
|
||||
)}
|
||||
{api.query.proposeParachain && (
|
||||
<Proposals proposals={proposals} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
10
packages/page-parachains/src/Overview/types.ts
Normal file
10
packages/page-parachains/src/Overview/types.ts
Normal file
@ -0,0 +1,10 @@
|
||||
// Copyright 2017-2020 @polkadot/app-parachains authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ParaId, ParachainProposal } from '@polkadot/types/interfaces';
|
||||
|
||||
export interface ProposalExt {
|
||||
id: ParaId;
|
||||
proposal: ParachainProposal;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user