Add ParaLink component (#4625)

This commit is contained in:
Jaco Greeff 2021-02-06 16:00:52 +01:00 committed by GitHub
parent 6e485f8370
commit d7cdfecc18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 82 additions and 79 deletions

View File

@ -6,7 +6,7 @@ import type { FundIndex, FundInfo } from '@polkadot/types/interfaces';
import React, { useMemo } from 'react';
import { AddressMini } from '@polkadot/react-components';
import { AddressMini, ParaLink } from '@polkadot/react-components';
import { BlockToTime, FormatBalance } from '@polkadot/react-query';
import { formatNumber } from '@polkadot/util';
@ -17,12 +17,13 @@ interface Props {
info: FundInfo;
}
function Fund ({ bestNumber, className, id, info: { cap, end, owner, raised } }: Props): React.ReactElement<Props> {
function Fund ({ bestNumber, className, info: { cap, end, owner, parachain, raised } }: Props): React.ReactElement<Props> {
const remaining = useMemo(() => bestNumber && end.sub(bestNumber), [bestNumber, end]);
return (
<tr className={className}>
<td className='number'><h1>{id}</h1></td>
<td className='number'><h1>{parachain}</h1></td>
<td><ParaLink id={parachain} /></td>
<td className='address'><AddressMini value={owner} /></td>
<td className='number'><FormatBalance value={raised} /></td>
<td className='number'><FormatBalance value={cap} /></td>

View File

@ -31,7 +31,7 @@ function Funds ({ bestNumber, className, fundIndexes }: Props): React.ReactEleme
const [funds, setFunds] = useState<Fund[] | undefined>();
const headerRef = useRef([
[t('campaigns'), 'start', 2],
[t('campaigns'), 'start', 3],
[t('raised'), 'number'],
[t('cap'), 'number'],
[t('end'), 'number']

View File

@ -8,12 +8,12 @@ import type { Codec } from '@polkadot/types/types';
import BN from 'bn.js';
import React, { useMemo } from 'react';
import { Badge } from '@polkadot/react-components';
import { Badge, ParaLink } from '@polkadot/react-components';
import { useApi, useCall, useCallMulti, useParaApi } from '@polkadot/react-hooks';
import { BlockToTime } from '@polkadot/react-query';
import { BN_ONE, formatNumber } from '@polkadot/util';
import { getChainLink, sliceHex } from '../util';
import { sliceHex } from '../util';
interface Props {
bestNumber?: BN;
@ -65,7 +65,7 @@ const optionsMulti = {
function Parachain ({ bestNumber, className = '', id, isScheduled, lastBacked, lastInclusion }: Props): React.ReactElement<Props> {
const { api } = useApi();
const { api: paraApi, endpoints } = useParaApi(id);
const { api: paraApi } = useParaApi(id);
const paraBest = useCall<BlockNumber>(paraApi?.rpc.chain.subscribeNewHeads, undefined, transformHeader);
const lastRelayNumber = useCall<BN>(lastInclusion && api.rpc.chain.getHeader, [lastInclusion && lastInclusion[1]], transformHeader);
const paraInfo = useCallMulti<QueryState>([
@ -89,11 +89,6 @@ function Parachain ({ bestNumber, className = '', id, isScheduled, lastBacked, l
[bestNumber, lastRelayNumber, paraInfo]
);
const chainLink = useMemo(
() => getChainLink(endpoints),
[endpoints]
);
return (
<tr className={className}>
<td className='number'><h1>{formatNumber(id)}</h1></td>
@ -103,7 +98,7 @@ function Parachain ({ bestNumber, className = '', id, isScheduled, lastBacked, l
icon='clock'
/>
)}</td>
<td className='badge together'>{chainLink}</td>
<td className='badge together'><ParaLink id={id} /></td>
<td className='all start together hash'>{paraInfo.headHex}</td>
<td className='number'>{blockDelay && <BlockToTime blocks={blockDelay} />}</td>
<td className='number'>

View File

@ -4,13 +4,14 @@
import type { Option } from '@polkadot/types';
import type { ParaGenesisArgs, ParaId } from '@polkadot/types/interfaces';
import React, { useMemo } from 'react';
import React from 'react';
import { useApi, useCall, useParaEndpoints } from '@polkadot/react-hooks';
import { ParaLink } from '@polkadot/react-components';
import { useApi, useCall } from '@polkadot/react-hooks';
import { formatNumber } from '@polkadot/util';
import { useTranslation } from '../translate';
import { getChainLink, sliceHex } from '../util';
import { sliceHex } from '../util';
interface Props {
id: ParaId;
@ -24,17 +25,11 @@ function Upcoming ({ id }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const info = useCall<ParaGenesisArgs | null>(api.query.paras.upcomingParasGenesis, [id], transformGenesis);
const endpoints = useParaEndpoints(id);
const chainLink = useMemo(
() => getChainLink(endpoints),
[endpoints]
);
return (
<tr key={id.toString()}>
<td className='number'><h1>{formatNumber(id)}</h1></td>
<td className='badge together'>{chainLink}</td>
<td className='badge together'><ParaLink id={id} /></td>
<td className='all start together hash'>
{info && (
sliceHex(info.genesisHead, 8)

View File

@ -6,13 +6,13 @@ import type { ScheduledProposals } from '../types';
import React, { useMemo } from 'react';
import { AddressMini, AddressSmall, Badge, TxButton } from '@polkadot/react-components';
import { useAccounts, useApi, useParaEndpoints, useSudo } from '@polkadot/react-hooks';
import { AddressMini, AddressSmall, Badge, ParaLink, TxButton } from '@polkadot/react-components';
import { useAccounts, useApi, useSudo } from '@polkadot/react-hooks';
import { FormatBalance } from '@polkadot/react-query';
import { formatNumber } from '@polkadot/util';
import { useTranslation } from '../translate';
import { getChainLink, sliceHex } from '../util';
import { sliceHex } from '../util';
import { useProposal } from './useProposals';
interface Props {
@ -27,12 +27,6 @@ function Proposal ({ approvedIds, id, scheduled }: Props): React.ReactElement<Pr
const { allAccounts } = useAccounts();
const { hasSudoKey, sudoKey } = useSudo();
const proposal = useProposal(id, approvedIds, scheduled);
const endpoints = useParaEndpoints(id);
const chainLink = useMemo(
() => getChainLink(endpoints),
[endpoints]
);
const cancelTx = useMemo(
() => api.tx.sudo && hasSudoKey
@ -64,7 +58,7 @@ function Proposal ({ approvedIds, id, scheduled }: Props): React.ReactElement<Pr
/>
)}
</td>
<td className='badge together'>{chainLink}</td>
<td className='badge together'><ParaLink id={id} /></td>
<td className='start together'>{proposal.proposal?.name.toUtf8()}</td>
<td className='address'>{proposal.proposal && <AddressSmall value={proposal.proposal.proposer} />}</td>
<td className='number media--1100'>{proposal.proposal && <FormatBalance value={proposal.proposal.balance} />}</td>

View File

@ -62,11 +62,4 @@ export default React.memo(styled(ParachainsApp)`
.parachains--hidden {
display: none;
}
a.chainAlign {
display: inline-block;
height: 24px;
line-height: 24px;
vertical-align: middle;
}
`);

View File

@ -0,0 +1,12 @@
// Copyright 2017-2021 @polkadot/app-parachains authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { Codec } from '@polkadot/types/types';
export function sliceHex (value: Codec, max: number): string {
const hex = value.toHex();
return hex.length > ((2 * max) + 2)
? `${hex.slice(0, max + 2)}…${hex.slice(-max)}`
: hex;
}

View File

@ -1,39 +0,0 @@
// Copyright 2017-2021 @polkadot/app-parachains authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { LinkOption } from '@polkadot/apps-config/settings/types';
import type { Codec } from '@polkadot/types/types';
import React from 'react';
import { ChainImg } from '@polkadot/react-components';
export function sliceHex (value: Codec, max: number): string {
const hex = value.toHex();
return hex.length > ((2 * max) + 2)
? `${hex.slice(0, max + 2)}…${hex.slice(-max)}`
: hex;
}
export function getChainLink (endpoints: LinkOption[]): React.ReactNode {
if (!endpoints.length) {
return null;
}
const { info, text, value } = endpoints[endpoints.length - 1];
return (
<>
<ChainImg
isInline
logo={info || 'empty'}
withoutHl
/>
<a
className='chainAlign'
href={`${window.location.origin}${window.location.pathname}?rpc=${encodeURIComponent(value)}`}
>{text}</a>
</>
);
}

View File

@ -0,0 +1,51 @@
// Copyright 2017-2021 @polkadot/app-staking authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type BN from 'bn.js';
import React from 'react';
import styled from 'styled-components';
import { useParaEndpoints } from '@polkadot/react-hooks';
import ChainImg from './ChainImg';
interface Props {
className?: string;
id: BN;
}
function ParaLink ({ className, id }: Props): React.ReactElement<Props> | null {
const endpoints = useParaEndpoints(id);
if (!endpoints.length) {
return null;
}
const { info, text, value } = endpoints[endpoints.length - 1];
return (
<div className={className}>
<ChainImg
isInline
logo={info || 'empty'}
withoutHl
/>
<a
className='chainAlign'
href={`${window.location.origin}${window.location.pathname}?rpc=${encodeURIComponent(value)}`}
>{text}</a>
</div>
);
}
export default React.memo(styled(ParaLink)`
vertical-align: middle;
a.chainAlign {
display: inline-block;
height: 24px;
line-height: 24px;
vertical-align: middle;
}
`);

View File

@ -71,6 +71,7 @@ export { default as Nonce } from './Nonce';
export { default as Output } from './Output';
export { default as Password } from './Password';
export { default as PasswordStrength } from './PasswordStrength';
export { default as ParaLink } from './ParaLink';
export { default as Popup } from './Popup';
export { default as Progress } from './Progress';
export { default as ProposedAction } from './ProposedAction';