Re-add unclosed proposals (#2594)
* Re-add unclosed proposals * Treasury checks end
This commit is contained in:
parent
f1ef7da3ec
commit
1e69ed13c7
@ -5,7 +5,6 @@
|
||||
import { AccountId, BlockNumber } from '@polkadot/types/interfaces';
|
||||
import { DeriveCollectiveProposal } from '@polkadot/api-derive/types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import React from 'react';
|
||||
import ProposalCell from '@polkadot/app-democracy/Overview/ProposalCell';
|
||||
import { LinkExternal } from '@polkadot/react-components';
|
||||
@ -26,7 +25,7 @@ interface Props {
|
||||
|
||||
function Motion ({ className, isMember, members, motion: { hash, proposal, votes }, prime }: Props): React.ReactElement<Props> | null {
|
||||
const { api } = useApi();
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []) || new BN(0);
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []);
|
||||
|
||||
if (!votes) {
|
||||
return null;
|
||||
@ -45,7 +44,7 @@ function Motion ({ className, isMember, members, motion: { hash, proposal, votes
|
||||
{formatNumber(ayes.length)}/{formatNumber(threshold)}
|
||||
</td>
|
||||
<td className='number together'>
|
||||
{end && (
|
||||
{bestNumber && end && (
|
||||
<>
|
||||
<BlockToTime blocks={end.sub(bestNumber)} />
|
||||
#{formatNumber(end)}
|
||||
@ -55,14 +54,16 @@ function Motion ({ className, isMember, members, motion: { hash, proposal, votes
|
||||
<Votes votes={ayes} />
|
||||
<Votes votes={nays} />
|
||||
<td className='button'>
|
||||
<Voting
|
||||
hash={hash}
|
||||
idNumber={index}
|
||||
isDisabled={!isMember}
|
||||
members={members}
|
||||
prime={prime}
|
||||
proposal={proposal}
|
||||
/>
|
||||
{bestNumber && end.gt(bestNumber) && (
|
||||
<Voting
|
||||
hash={hash}
|
||||
idNumber={index}
|
||||
isDisabled={!isMember}
|
||||
members={members}
|
||||
prime={prime}
|
||||
proposal={proposal}
|
||||
/>
|
||||
)}
|
||||
</td>
|
||||
<td className='mini'>
|
||||
<LinkExternal
|
||||
|
||||
@ -3,11 +3,11 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { DeriveCollectiveProposals, DeriveCollectiveProposal } from '@polkadot/api-derive/types';
|
||||
import { BlockNumber, AccountId } from '@polkadot/types/interfaces';
|
||||
import { AccountId } from '@polkadot/types/interfaces';
|
||||
|
||||
import React from 'react';
|
||||
import { Button, Table } from '@polkadot/react-components';
|
||||
import { useApi, useCall, useMembers } from '@polkadot/react-hooks';
|
||||
import { useMembers } from '@polkadot/react-hooks';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
import Motion from './Motion';
|
||||
@ -23,10 +23,7 @@ interface Props {
|
||||
|
||||
function Proposals ({ className, motions, prime }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []);
|
||||
const { isMember, members } = useMembers();
|
||||
const filtered = bestNumber && motions?.filter(({ votes }) => votes?.end.gt(bestNumber));
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
@ -47,7 +44,7 @@ function Proposals ({ className, motions, prime }: Props): React.ReactElement<Pr
|
||||
/>
|
||||
</Button.Group>
|
||||
<Table
|
||||
empty={filtered && t('No council motions')}
|
||||
empty={motions && t('No council motions')}
|
||||
header={[
|
||||
[t('motions'), 'start', 2],
|
||||
[t('threshold')],
|
||||
@ -57,7 +54,7 @@ function Proposals ({ className, motions, prime }: Props): React.ReactElement<Pr
|
||||
[undefined, undefined, 2]
|
||||
]}
|
||||
>
|
||||
{filtered?.map((motion: DeriveCollectiveProposal): React.ReactNode => (
|
||||
{motions?.map((motion: DeriveCollectiveProposal): React.ReactNode => (
|
||||
<Motion
|
||||
isMember={isMember}
|
||||
key={motion.hash.toHex()}
|
||||
|
||||
@ -3,26 +3,18 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { DeriveCollectiveProposals } from '@polkadot/api-derive/types';
|
||||
import { BlockNumber } from '@polkadot/types/interfaces';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
|
||||
function transform (motions: DeriveCollectiveProposals): number {
|
||||
return motions.filter(({ votes }): boolean => !!votes).length;
|
||||
}
|
||||
|
||||
export default function useCounter (): number {
|
||||
const { api, isApiReady } = useApi();
|
||||
const [counter, setCounter] = useState(0);
|
||||
const bestNumber = useCall<BlockNumber>(isApiReady && api.derive.chain.bestNumber, []);
|
||||
const proposals = useCall<DeriveCollectiveProposals>(isApiReady && api.derive.council?.proposals, []);
|
||||
|
||||
useEffect((): void => {
|
||||
bestNumber && proposals && setCounter((prev: number): number => {
|
||||
const filtered = proposals.filter(({ votes }) => votes?.end.gt(bestNumber));
|
||||
|
||||
return filtered.length !== prev
|
||||
? filtered.length
|
||||
: prev;
|
||||
});
|
||||
}, [bestNumber, proposals]);
|
||||
const counter = useCall<number>(isApiReady && api.derive.council?.proposals, [], {
|
||||
transform
|
||||
}) || 0;
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
@ -3,11 +3,11 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { DeriveCollectiveProposal } from '@polkadot/api-derive/types';
|
||||
import { ProposalIndex, Hash } from '@polkadot/types/interfaces';
|
||||
import { BlockNumber, Hash, ProposalIndex } from '@polkadot/types/interfaces';
|
||||
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { Button, Dropdown, Input, Modal, VoteAccount, VoteActions, VoteToggle } from '@polkadot/react-components';
|
||||
import { useAccounts, useToggle } from '@polkadot/react-hooks';
|
||||
import { useAccounts, useApi, useCall, useToggle } from '@polkadot/react-hooks';
|
||||
import { isBoolean } from '@polkadot/util';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
@ -25,6 +25,8 @@ interface Option {
|
||||
function Voting ({ councilProposals, isDisabled }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { hasAccounts } = useAccounts();
|
||||
const { api } = useApi();
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []);
|
||||
const [councilOpts, setCouncilOpts] = useState<Option[]>([]);
|
||||
const [councilOptId, setCouncilOptId] = useState<number>(0);
|
||||
const [accountId, setAccountId] = useState<string | null>(null);
|
||||
@ -38,15 +40,16 @@ function Voting ({ councilProposals, isDisabled }: Props): React.ReactElement<Pr
|
||||
|
||||
useEffect((): void => {
|
||||
const available = councilProposals
|
||||
.filter(({ votes }) => bestNumber && votes?.end.gt(bestNumber))
|
||||
.map(({ proposal: { methodName, sectionName }, votes }): Option => ({
|
||||
text: `Council #${votes?.index.toNumber()}: ${sectionName}.${methodName} `,
|
||||
value: votes ? votes?.index.toNumber() : -1
|
||||
}))
|
||||
.filter(({ value }): boolean => value !== -1);
|
||||
.filter(({ value }) => value !== -1);
|
||||
|
||||
setCouncilOptId(available.length ? available[0].value : 0);
|
||||
setCouncilOpts(available);
|
||||
}, [councilProposals]);
|
||||
}, [bestNumber, councilProposals]);
|
||||
|
||||
const _onChangeVote = useCallback(
|
||||
(vote?: boolean) => setVoteValue(isBoolean(vote) ? vote : true),
|
||||
@ -55,7 +58,7 @@ function Voting ({ councilProposals, isDisabled }: Props): React.ReactElement<Pr
|
||||
|
||||
const _onChangeProposal = useCallback(
|
||||
(optionId: number): void => {
|
||||
const councilProp = councilProposals.find(({ votes }): boolean => !!(votes?.index.eq(optionId)));
|
||||
const councilProp = councilProposals.find(({ votes }) => votes?.index.eq(optionId));
|
||||
|
||||
if (councilProp && councilProp.votes) {
|
||||
setCouncilInfo({ councilHash: councilProp.hash, councilId: councilProp.votes.index });
|
||||
|
||||
@ -54,7 +54,7 @@ function extractTime (value?: number): Time {
|
||||
return addTime([round, 0, 0, 0], extractTime(value - (round * DAY)));
|
||||
}
|
||||
|
||||
function BlockToTime ({ blocks, children, className, label, style }: Props): React.ReactElement<Props> {
|
||||
function BlockToTime ({ blocks, children, className, label, style }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const time = useMemo((): string => {
|
||||
@ -73,6 +73,10 @@ function BlockToTime ({ blocks, children, className, label, style }: Props): Rea
|
||||
].filter((value): value is string => !!value).slice(0, 2).join(' ');
|
||||
}, [api, blocks, t]);
|
||||
|
||||
if (blocks?.ltn(0)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={className}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user