Formatting changes for referenda (#8151)
* Formatting changes for referenda * Deposit * Refund deposit * group functionality
This commit is contained in:
parent
29a5cfca0f
commit
3a354ecc32
@ -1,42 +0,0 @@
|
||||
// Copyright 2017-2022 @polkadot/app-referenda authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Option } from '@polkadot/types';
|
||||
import type { PalletReferendaDeposit } from '@polkadot/types/lookup';
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
import { AddressMini } from '@polkadot/react-components';
|
||||
|
||||
interface Props {
|
||||
decision: Option<PalletReferendaDeposit> | null;
|
||||
submit: PalletReferendaDeposit | null;
|
||||
}
|
||||
|
||||
function Deposit ({ decision, submit }: Props): React.ReactElement<Props> {
|
||||
const [first, second] = useMemo(
|
||||
() => [submit, decision && decision.unwrapOr(null)],
|
||||
[decision, submit]
|
||||
);
|
||||
|
||||
return (
|
||||
<td className='address'>
|
||||
{first && (
|
||||
<AddressMini
|
||||
balance={first.amount}
|
||||
value={first.who}
|
||||
withBalance
|
||||
/>
|
||||
)}
|
||||
{second && (
|
||||
<AddressMini
|
||||
balance={second.amount}
|
||||
value={second.who}
|
||||
withBalance
|
||||
/>
|
||||
)}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(Deposit);
|
||||
89
packages/page-referenda/src/Referenda/Deposits/Place.tsx
Normal file
89
packages/page-referenda/src/Referenda/Deposits/Place.tsx
Normal file
@ -0,0 +1,89 @@
|
||||
// Copyright 2017-2022 @polkadot/app-referenda authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { PalletReferendaTrackInfo } from '@polkadot/types/lookup';
|
||||
import type { BN } from '@polkadot/util';
|
||||
import type { PalletReferenda } from '../../types';
|
||||
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { Button, InputAddress, InputBalance, InputNumber, Modal, TxButton } from '@polkadot/react-components';
|
||||
import { useApi, useToggle } from '@polkadot/react-hooks';
|
||||
import { Available } from '@polkadot/react-query';
|
||||
|
||||
import { useTranslation } from '../../translate';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
id: BN;
|
||||
palletReferenda: PalletReferenda;
|
||||
track: PalletReferendaTrackInfo;
|
||||
}
|
||||
|
||||
function Deposit ({ className = '', id, palletReferenda, track }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const [isOpen, toggleOpen] = useToggle();
|
||||
const [accountId, setAccountId] = useState<string | null>(null);
|
||||
|
||||
return (
|
||||
<>
|
||||
{isOpen && (
|
||||
<Modal
|
||||
className={className}
|
||||
header={t<string>('Place decision deposit')}
|
||||
onClose={toggleOpen}
|
||||
size='large'
|
||||
>
|
||||
<Modal.Content>
|
||||
<Modal.Columns hint={t<string>('The deposit will be registered from this account and the balance lock will be applied here.')}>
|
||||
<InputAddress
|
||||
help={t<string>('The account you want to deposit from')}
|
||||
label={t<string>('deposit from account')}
|
||||
labelExtra={
|
||||
<Available
|
||||
label={<span className='label'>{t<string>('transferrable')}</span>}
|
||||
params={accountId}
|
||||
/>
|
||||
}
|
||||
onChange={setAccountId}
|
||||
type='account'
|
||||
/>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns hint={t<string>('The referendum this deposit would apply to.')}>
|
||||
<InputNumber
|
||||
defaultValue={id}
|
||||
isDisabled
|
||||
label={t<string>('referendum id')}
|
||||
/>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns hint={t<string>('The deposit for this proposal will be locked for the referendum duration.')}>
|
||||
<InputBalance
|
||||
defaultValue={track.decisionDeposit}
|
||||
isDisabled
|
||||
label={t<string>('decision deposit')}
|
||||
/>
|
||||
</Modal.Columns>
|
||||
</Modal.Content>
|
||||
<Modal.Actions>
|
||||
<TxButton
|
||||
accountId={accountId}
|
||||
icon='plus'
|
||||
label={t<string>('Place deposit')}
|
||||
onStart={toggleOpen}
|
||||
params={[id]}
|
||||
tx={api.tx[palletReferenda as 'referenda'].placeDecisionDeposit}
|
||||
/>
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
)}
|
||||
<Button
|
||||
icon='plus'
|
||||
label={t<string>('Decision deposit')}
|
||||
onClick={toggleOpen}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(Deposit);
|
||||
73
packages/page-referenda/src/Referenda/Deposits/Refund.tsx
Normal file
73
packages/page-referenda/src/Referenda/Deposits/Refund.tsx
Normal file
@ -0,0 +1,73 @@
|
||||
// Copyright 2017-2022 @polkadot/app-referenda authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { BN } from '@polkadot/util';
|
||||
import type { PalletReferenda } from '../../types';
|
||||
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { Button, InputAddress, InputNumber, Modal, TxButton } from '@polkadot/react-components';
|
||||
import { useApi, useToggle } from '@polkadot/react-hooks';
|
||||
|
||||
import { useTranslation } from '../../translate';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
id: BN;
|
||||
palletReferenda: PalletReferenda;
|
||||
}
|
||||
|
||||
function Refund ({ className = '', id, palletReferenda }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const [isOpen, toggleOpen] = useToggle();
|
||||
const [accountId, setAccountId] = useState<string | null>(null);
|
||||
|
||||
return (
|
||||
<>
|
||||
{isOpen && (
|
||||
<Modal
|
||||
className={className}
|
||||
header={t<string>('Refund decision deposit')}
|
||||
onClose={toggleOpen}
|
||||
size='large'
|
||||
>
|
||||
<Modal.Content>
|
||||
<Modal.Columns hint={t<string>('The transaction will be submitted from this account.')}>
|
||||
<InputAddress
|
||||
help={t<string>('The account you want to refund from')}
|
||||
label={t<string>('refund from account')}
|
||||
onChange={setAccountId}
|
||||
type='account'
|
||||
/>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns hint={t<string>('The referendum this deposit would apply to.')}>
|
||||
<InputNumber
|
||||
defaultValue={id}
|
||||
isDisabled
|
||||
label={t<string>('referendum id')}
|
||||
/>
|
||||
</Modal.Columns>
|
||||
</Modal.Content>
|
||||
<Modal.Actions>
|
||||
<TxButton
|
||||
accountId={accountId}
|
||||
icon='minus'
|
||||
label={t<string>('Refund deposit')}
|
||||
onStart={toggleOpen}
|
||||
params={[id]}
|
||||
tx={api.tx[palletReferenda as 'referenda'].refundDecisionDeposit}
|
||||
/>
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
)}
|
||||
<Button
|
||||
icon='minus'
|
||||
label={t<string>('Refund deposit')}
|
||||
onClick={toggleOpen}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(Refund);
|
||||
68
packages/page-referenda/src/Referenda/Deposits/index.tsx
Normal file
68
packages/page-referenda/src/Referenda/Deposits/index.tsx
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright 2017-2022 @polkadot/app-referenda authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Option } from '@polkadot/types';
|
||||
import type { PalletReferendaDeposit, PalletReferendaTrackInfo } from '@polkadot/types/lookup';
|
||||
import type { BN } from '@polkadot/util';
|
||||
import type { PalletReferenda } from '../../types';
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
import { AddressMini } from '@polkadot/react-components';
|
||||
|
||||
import Place from './Place';
|
||||
import Refund from './Refund';
|
||||
|
||||
interface Props {
|
||||
canDeposit?: boolean;
|
||||
canRefund?: boolean;
|
||||
decision: Option<PalletReferendaDeposit> | null;
|
||||
id: BN;
|
||||
palletReferenda: PalletReferenda;
|
||||
submit: PalletReferendaDeposit | null;
|
||||
track?: PalletReferendaTrackInfo;
|
||||
}
|
||||
|
||||
function Deposits ({ canDeposit, canRefund, decision, id, palletReferenda, submit, track }: Props): React.ReactElement<Props> {
|
||||
const [valSubmit, valDeposit] = useMemo(
|
||||
() => [submit, decision && decision.unwrapOr(null)],
|
||||
[decision, submit]
|
||||
);
|
||||
|
||||
return (
|
||||
<td className='address'>
|
||||
{valSubmit && (
|
||||
<AddressMini
|
||||
balance={valSubmit.amount}
|
||||
value={valSubmit.who}
|
||||
withBalance
|
||||
/>
|
||||
)}
|
||||
{valDeposit
|
||||
? (
|
||||
<AddressMini
|
||||
balance={valDeposit.amount}
|
||||
value={valDeposit.who}
|
||||
withBalance
|
||||
/>
|
||||
)
|
||||
: canDeposit
|
||||
? track && (
|
||||
<Place
|
||||
id={id}
|
||||
palletReferenda={palletReferenda}
|
||||
track={track}
|
||||
/>
|
||||
)
|
||||
: canRefund && (
|
||||
<Refund
|
||||
id={id}
|
||||
palletReferenda={palletReferenda}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(Deposits);
|
||||
@ -10,7 +10,7 @@ import usePreimage from '@polkadot/app-preimages/usePreimage';
|
||||
import { CallExpander, Progress } from '@polkadot/react-components';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
import Deposit from './Deposit';
|
||||
import Deposits from './Deposits';
|
||||
import Vote from './Vote';
|
||||
import Votes from './Votes';
|
||||
|
||||
@ -31,12 +31,14 @@ function expandOngoing (info: Referendum['info']): Expanded {
|
||||
};
|
||||
}
|
||||
|
||||
function Ongoing ({ isMember, members, palletVote, value: { id, info, isConvictionVote } }: Props): React.ReactElement<Props> {
|
||||
function Ongoing ({ isMember, members, palletReferenda, palletVote, value: { id, info, isConvictionVote, track } }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { ongoing: { decisionDeposit, proposalHash, submissionDeposit, tally }, shortHash, tallyTotal } = useMemo(
|
||||
() => expandOngoing(info),
|
||||
[info]
|
||||
);
|
||||
|
||||
const preimage = usePreimage(proposalHash);
|
||||
|
||||
return (
|
||||
@ -53,9 +55,13 @@ function Ongoing ({ isMember, members, palletVote, value: { id, info, isConvicti
|
||||
: t('preimage {{shortHash}}', { replace: { shortHash } })
|
||||
}
|
||||
</td>
|
||||
<Deposit
|
||||
<Deposits
|
||||
canDeposit
|
||||
decision={decisionDeposit}
|
||||
id={id}
|
||||
palletReferenda={palletReferenda}
|
||||
submit={submissionDeposit}
|
||||
track={track}
|
||||
/>
|
||||
<Votes
|
||||
id={id}
|
||||
|
||||
@ -7,7 +7,7 @@ import type { Referendum, ReferendumProps as Props } from '../types';
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
import Deposit from './Deposit';
|
||||
import Deposits from './Deposits';
|
||||
|
||||
interface Expanded {
|
||||
decision: Option<PalletReferendaDeposit> | null;
|
||||
@ -26,22 +26,20 @@ function expandTuple (info: Referendum['info']): Expanded {
|
||||
? info.asTimedOut
|
||||
: null;
|
||||
|
||||
if (!data) {
|
||||
return {
|
||||
return data
|
||||
? {
|
||||
decision: data[2],
|
||||
submit: data[1],
|
||||
when: new Date(data[0].toNumber())
|
||||
}
|
||||
: {
|
||||
decision: null,
|
||||
submit: null,
|
||||
when: null
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
decision: data[2],
|
||||
submit: data[1],
|
||||
when: new Date(data[0].toNumber())
|
||||
};
|
||||
}
|
||||
|
||||
function Tuple ({ value: { info } }: Props): React.ReactElement<Props> {
|
||||
function Tuple ({ palletReferenda, value: { id, info, track } }: Props): React.ReactElement<Props> {
|
||||
const { decision, submit, when } = useMemo(
|
||||
() => expandTuple(info),
|
||||
[info]
|
||||
@ -50,9 +48,13 @@ function Tuple ({ value: { info } }: Props): React.ReactElement<Props> {
|
||||
return (
|
||||
<>
|
||||
<td className='all' />
|
||||
<Deposit
|
||||
<Deposits
|
||||
canRefund
|
||||
decision={decision}
|
||||
id={id}
|
||||
palletReferenda={palletReferenda}
|
||||
submit={submit}
|
||||
track={track}
|
||||
/>
|
||||
<td
|
||||
className='number'
|
||||
|
||||
@ -11,8 +11,8 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { getGovernanceTracks } from '@polkadot/apps-config';
|
||||
import { Dropdown, Input, InputAddress, Modal, TxButton } from '@polkadot/react-components';
|
||||
import { useApi, useBestNumber } from '@polkadot/react-hooks';
|
||||
import { Button, Dropdown, Input, InputAddress, InputBalance, Modal, TxButton } from '@polkadot/react-components';
|
||||
import { useApi, useBestNumber, useToggle } from '@polkadot/react-hooks';
|
||||
import Params from '@polkadot/react-params';
|
||||
import { Available } from '@polkadot/react-query';
|
||||
import { getTypeDef } from '@polkadot/types/create';
|
||||
@ -23,10 +23,10 @@ import { getTrackName } from './util';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
isMember: boolean;
|
||||
members?: string[];
|
||||
onClose: () => void;
|
||||
palletReferenda: PalletReferenda;
|
||||
tracks: [BN, PalletReferendaTrackInfo][];
|
||||
tracks?: [BN, PalletReferendaTrackInfo][];
|
||||
}
|
||||
|
||||
interface HashState {
|
||||
@ -34,28 +34,32 @@ interface HashState {
|
||||
isHashValid: boolean;
|
||||
}
|
||||
|
||||
function getOrigin (api: ApiPromise, specName: string, palletReferenda: string, tracks: [BN, PalletReferendaTrackInfo][], trackId: number): Record<string, string> | undefined {
|
||||
const originMap = getGovernanceTracks(api, specName, palletReferenda);
|
||||
const trackInfo = tracks.find(([id]) => id.eqn(trackId));
|
||||
function getOrigin (api: ApiPromise, specName: string, palletReferenda: string, tracks?: [BN, PalletReferendaTrackInfo][], trackId?: number): Record<string, string> | undefined {
|
||||
let origin: Record<string, string> | undefined;
|
||||
|
||||
if (trackInfo && originMap) {
|
||||
const trackName = trackInfo[1].name.toString();
|
||||
const record = originMap.find(([[id, name]]) =>
|
||||
id === trackId &&
|
||||
name === trackName
|
||||
);
|
||||
if (tracks && trackId !== undefined) {
|
||||
const originMap = getGovernanceTracks(api, specName, palletReferenda);
|
||||
const trackInfo = tracks.find(([id]) => id.eqn(trackId));
|
||||
|
||||
origin = record && record[1];
|
||||
if (trackInfo && originMap) {
|
||||
const trackName = trackInfo[1].name.toString();
|
||||
const record = originMap.find(([[id, name]]) =>
|
||||
id === trackId &&
|
||||
name === trackName
|
||||
);
|
||||
|
||||
origin = record && record[1];
|
||||
}
|
||||
}
|
||||
|
||||
return origin;
|
||||
}
|
||||
|
||||
function Submit ({ className = '', members, onClose, palletReferenda, tracks }: Props): React.ReactElement<Props> | null {
|
||||
function Submit ({ className = '', isMember, members, palletReferenda, tracks }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { api, specName } = useApi();
|
||||
const bestNumber = useBestNumber();
|
||||
const [isSubmitOpen, toggleSubmit] = useToggle();
|
||||
const [accountId, setAccountId] = useState<string | null>(null);
|
||||
const [trackId, setTrack] = useState<number | undefined>();
|
||||
const [origin, setOrigin] = useState<RawParam['value'] | null>(null);
|
||||
@ -73,7 +77,7 @@ function Submit ({ className = '', members, onClose, palletReferenda, tracks }:
|
||||
}, [api, bestNumber]);
|
||||
|
||||
const originParam = useMemo(
|
||||
() => trackId !== undefined && getOrigin(api, specName, palletReferenda, tracks, trackId),
|
||||
() => getOrigin(api, specName, palletReferenda, tracks, trackId),
|
||||
[api, palletReferenda, specName, trackId, tracks]
|
||||
);
|
||||
|
||||
@ -101,7 +105,7 @@ function Submit ({ className = '', members, onClose, palletReferenda, tracks }:
|
||||
);
|
||||
|
||||
const trackOpts = useMemo(
|
||||
() => tracks.map(([id, track]) => ({
|
||||
() => tracks && tracks.map(([id, track]) => ({
|
||||
text: getTrackName(track),
|
||||
value: id.toNumber()
|
||||
})),
|
||||
@ -127,77 +131,94 @@ function Submit ({ className = '', members, onClose, palletReferenda, tracks }:
|
||||
);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
className={className}
|
||||
header={t<string>('Submit proposal')}
|
||||
onClose={onClose}
|
||||
size='large'
|
||||
>
|
||||
<Modal.Content>
|
||||
<Modal.Columns hint={t<string>('The proposal will be registered from this account and the balance lock will be applied here.')}>
|
||||
<InputAddress
|
||||
filter={members}
|
||||
help={t<string>('The account you want to propose from')}
|
||||
label={t<string>('propose from account')}
|
||||
labelExtra={
|
||||
<Available
|
||||
label={<span className='label'>{t<string>('transferrable')}</span>}
|
||||
params={accountId}
|
||||
<>
|
||||
{trackOpts && isSubmitOpen && (
|
||||
<Modal
|
||||
className={className}
|
||||
header={t<string>('Submit proposal')}
|
||||
onClose={toggleSubmit}
|
||||
size='large'
|
||||
>
|
||||
<Modal.Content>
|
||||
<Modal.Columns hint={t<string>('The proposal will be registered from this account and the balance lock will be applied here.')}>
|
||||
<InputAddress
|
||||
filter={members}
|
||||
help={t<string>('The account you want to propose from')}
|
||||
label={t<string>('propose from account')}
|
||||
labelExtra={
|
||||
<Available
|
||||
label={<span className='label'>{t<string>('transferrable')}</span>}
|
||||
params={accountId}
|
||||
/>
|
||||
}
|
||||
onChange={setAccountId}
|
||||
type='account'
|
||||
/>
|
||||
}
|
||||
onChange={setAccountId}
|
||||
type='account'
|
||||
/>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns hint={t<string>('The hash of the preimage for the proposal as previously submitted or intended.')}>
|
||||
<Input
|
||||
autoFocus
|
||||
help={t<string>('The preimage hash of the proposal')}
|
||||
isError={!isHashValid}
|
||||
label={t<string>('preimage hash')}
|
||||
onChange={_onChangeHash}
|
||||
value={hash}
|
||||
/>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns hint={t<string>('The origin (and by extension track) that you wish to submit for, each has a different period, different root and acceptance criteria.')}>
|
||||
<Dropdown
|
||||
defaultValue={trackOpts[0] && trackOpts[0].value}
|
||||
label={t<string>('submission track')}
|
||||
onChange={setTrack}
|
||||
options={trackOpts}
|
||||
/>
|
||||
{!originParam && (
|
||||
<Params
|
||||
className='originSelect'
|
||||
onChange={_onChangeOrigin}
|
||||
params={originType}
|
||||
</Modal.Columns>
|
||||
<Modal.Columns hint={t<string>('The hash of the preimage for the proposal as previously submitted or intended.')}>
|
||||
<Input
|
||||
autoFocus
|
||||
help={t<string>('The preimage hash of the proposal')}
|
||||
isError={!isHashValid}
|
||||
label={t<string>('preimage hash')}
|
||||
onChange={_onChangeHash}
|
||||
value={hash}
|
||||
/>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns hint={t<string>('The origin (and by extension track) that you wish to submit for, each has a different period, different root and acceptance criteria.')}>
|
||||
<Dropdown
|
||||
defaultValue={trackOpts[0] && trackOpts[0].value}
|
||||
label={t<string>('submission track')}
|
||||
onChange={setTrack}
|
||||
options={trackOpts}
|
||||
/>
|
||||
{!originParam && (
|
||||
<Params
|
||||
className='originSelect'
|
||||
onChange={_onChangeOrigin}
|
||||
params={originType}
|
||||
/>
|
||||
)}
|
||||
</Modal.Columns>
|
||||
{bestNumber && defaultAtAfter && (
|
||||
<Modal.Columns hint={t<string>('The moment of enactment, either at a specific block, or after a specific block. Currently at #{{bestNumber}}, the selected block should be after the current best.', { replace: { bestNumber: formatNumber(bestNumber) } })}>
|
||||
<Params
|
||||
className='timeSelect'
|
||||
isError={isInvalidAt}
|
||||
onChange={_onChangeAtAfter}
|
||||
params={atAfterType}
|
||||
values={defaultAtAfter}
|
||||
/>
|
||||
</Modal.Columns>
|
||||
)}
|
||||
<Modal.Columns hint={t<string>('The deposit for this proposal will be locked for the referendum duration.')}>
|
||||
<InputBalance
|
||||
defaultValue={api.consts[palletReferenda as 'referenda'].submissionDeposit}
|
||||
isDisabled
|
||||
label={t<string>('submission deposit')}
|
||||
/>
|
||||
</Modal.Columns>
|
||||
</Modal.Content>
|
||||
<Modal.Actions>
|
||||
<TxButton
|
||||
accountId={accountId}
|
||||
icon='plus'
|
||||
isDisabled={!(originParam || origin) || !atAfter || !isHashValid || !accountId || isInvalidAt}
|
||||
label={t<string>('Submit proposal')}
|
||||
onStart={toggleSubmit}
|
||||
params={[originParam || origin, hash, atAfter]}
|
||||
tx={api.tx[palletReferenda as 'referenda'].submit}
|
||||
/>
|
||||
)}
|
||||
</Modal.Columns>
|
||||
{bestNumber && defaultAtAfter && (
|
||||
<Modal.Columns hint={t<string>('The moment of enactment, either at a specific block, or after a specific block. Currently at #{{bestNumber}}, the selected block should be after the current best.', { replace: { bestNumber: formatNumber(bestNumber) } })}>
|
||||
<Params
|
||||
className='timeSelect'
|
||||
isError={isInvalidAt}
|
||||
onChange={_onChangeAtAfter}
|
||||
params={atAfterType}
|
||||
values={defaultAtAfter}
|
||||
/>
|
||||
</Modal.Columns>
|
||||
)}
|
||||
</Modal.Content>
|
||||
<Modal.Actions>
|
||||
<TxButton
|
||||
accountId={accountId}
|
||||
icon='plus'
|
||||
isDisabled={!(originParam || origin) || !atAfter || !isHashValid || !accountId || isInvalidAt}
|
||||
label={t<string>('Submit proposal')}
|
||||
onStart={onClose}
|
||||
params={[originParam || origin, hash, atAfter]}
|
||||
tx={api.tx[palletReferenda as 'referenda'].submit}
|
||||
/>
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
)}
|
||||
<Button
|
||||
icon='plus'
|
||||
isDisabled={!isMember || !trackOpts}
|
||||
label={t<string>('Submit proposal')}
|
||||
onClick={toggleSubmit}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -25,38 +25,30 @@ function Votes ({ className = '', isConvictionVote, tally }: Props): React.React
|
||||
|
||||
return (
|
||||
<td className={`${className} expand`}>
|
||||
{isConvictionVote
|
||||
? (
|
||||
<>
|
||||
<Expander
|
||||
summary={
|
||||
<>
|
||||
{t<string>('Aye')}
|
||||
<div><FormatBalance value={tally.ayes} /></div>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Expander
|
||||
summary={
|
||||
<>
|
||||
{t<string>('Nay')}
|
||||
<div><FormatBalance value={tally.nays} /></div>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
: (
|
||||
<>
|
||||
<Expander
|
||||
summary={t<string>('Aye {{count}}', { replace: { count: tally.ayes.toNumber() } })}
|
||||
/>
|
||||
<Expander
|
||||
summary={t<string>('Nay {{count}}', { replace: { count: tally.nays.toNumber() } })}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
<Expander
|
||||
summary={
|
||||
isConvictionVote
|
||||
? (
|
||||
<>
|
||||
{t<string>('Aye')}
|
||||
<div><FormatBalance value={tally.ayes} /></div>
|
||||
</>
|
||||
)
|
||||
: t<string>('Aye {{count}}', { replace: { count: tally.ayes.toNumber() } })
|
||||
}
|
||||
/>
|
||||
<Expander
|
||||
summary={
|
||||
isConvictionVote
|
||||
? (
|
||||
<>
|
||||
{t<string>('Nay')}
|
||||
<div><FormatBalance value={tally.nays} /></div>
|
||||
</>
|
||||
)
|
||||
: t<string>('Nay {{count}}', { replace: { count: tally.nays.toNumber() } })
|
||||
}
|
||||
/>
|
||||
</td>
|
||||
);
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import React, { useMemo, useRef } from 'react';
|
||||
|
||||
import AddPreimage from '@polkadot/app-preimages/Preimages/Add';
|
||||
import { Button, Table } from '@polkadot/react-components';
|
||||
import { useAccounts, useToggle } from '@polkadot/react-hooks';
|
||||
import { useAccounts } from '@polkadot/react-hooks';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
import useReferenda from '../useReferenda';
|
||||
@ -30,7 +30,6 @@ function Referenda ({ className, members, palletReferenda, palletVote }: Props):
|
||||
const { allAccounts } = useAccounts();
|
||||
const [referenda, tracks] = useReferenda(palletReferenda);
|
||||
const summary = useSummary(palletReferenda, referenda);
|
||||
const [isSubmitOpen, toggleSubmit] = useToggle();
|
||||
|
||||
const isMember = useMemo(
|
||||
() => !members || allAccounts.some((a) => members.includes(a)),
|
||||
@ -47,24 +46,12 @@ function Referenda ({ className, members, palletReferenda, palletVote }: Props):
|
||||
<Summary summary={summary} />
|
||||
<Button.Group>
|
||||
<AddPreimage />
|
||||
{tracks && (
|
||||
<>
|
||||
<Button
|
||||
icon='plus'
|
||||
isDisabled={!isMember}
|
||||
label={t<string>('Submit proposal')}
|
||||
onClick={toggleSubmit}
|
||||
/>
|
||||
{isSubmitOpen && (
|
||||
<Submit
|
||||
members={members}
|
||||
onClose={toggleSubmit}
|
||||
palletReferenda={palletReferenda}
|
||||
tracks={tracks}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<Submit
|
||||
isMember={isMember}
|
||||
members={members}
|
||||
palletReferenda={palletReferenda}
|
||||
tracks={tracks}
|
||||
/>
|
||||
</Button.Group>
|
||||
<Table
|
||||
className={className}
|
||||
@ -76,6 +63,7 @@ function Referenda ({ className, members, palletReferenda, palletVote }: Props):
|
||||
isMember={isMember}
|
||||
key={r.key}
|
||||
members={members}
|
||||
palletReferenda={palletReferenda}
|
||||
palletVote={palletVote}
|
||||
value={r}
|
||||
/>
|
||||
|
||||
@ -20,6 +20,7 @@ export interface ReferendumProps {
|
||||
className?: string;
|
||||
isMember: boolean;
|
||||
members?: string[];
|
||||
palletReferenda: PalletReferenda;
|
||||
palletVote: PalletVote;
|
||||
value: Referendum;
|
||||
}
|
||||
|
||||
@ -65,8 +65,8 @@ const OPT_MULTI = {
|
||||
withParamsTransform: true
|
||||
};
|
||||
|
||||
function getResult (referenda: Referendum[], tracks?: [BN, PalletReferendaTrackInfo][]): Referendum[] | undefined {
|
||||
if (tracks) {
|
||||
function getResult (referenda?: Referendum[], tracks?: [BN, PalletReferendaTrackInfo][]): Referendum[] | undefined {
|
||||
if (tracks && referenda) {
|
||||
for (let i = 0; i < referenda.length; i++) {
|
||||
if (referenda[i].info.isOngoing) {
|
||||
const track = tracks.find(([id]) => id.eq(referenda[i].info.asOngoing.track));
|
||||
@ -85,15 +85,13 @@ function useReferendaImpl (palletReferenda: PalletReferenda): [Referendum[] | un
|
||||
const { api, isApiReady } = useApi();
|
||||
const ids = useReferendaIds(palletReferenda);
|
||||
const tracks = useTracks(palletReferenda);
|
||||
const referenda = useCall(isApiReady && ids && ids.length !== 0 && api.query[palletReferenda].referendumInfoFor.multi, [ids], OPT_MULTI);
|
||||
const referenda = useCall(isApiReady && ids && ids.length !== 0 && api.query[palletReferenda as 'referenda'].referendumInfoFor.multi, [ids], OPT_MULTI);
|
||||
|
||||
return useMemo(
|
||||
() => [
|
||||
(ids && ids.length === 0)
|
||||
? []
|
||||
: referenda
|
||||
? getResult(referenda, tracks)
|
||||
: undefined,
|
||||
: getResult(referenda, tracks),
|
||||
tracks
|
||||
],
|
||||
[ids, referenda, tracks]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user