Add treasury close tip button (#3010)
* Add treasury close tip button * Check square to indicate done * Display close at blocks
This commit is contained in:
parent
7669f63096
commit
b408d68d63
@ -2,26 +2,29 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { OpenTip } from '@polkadot/types/interfaces';
|
||||
import { BlockNumber, OpenTip } from '@polkadot/types/interfaces';
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { AddressSmall, AddressMini, Badge, Expander, Icon } from '@polkadot/react-components';
|
||||
import { AddressSmall, AddressMini, Expander, Icon } from '@polkadot/react-components';
|
||||
import { useAccounts, useApi, useCall } from '@polkadot/react-hooks';
|
||||
import { FormatBalance } from '@polkadot/react-query';
|
||||
import { BlockToTime, FormatBalance } from '@polkadot/react-query';
|
||||
import { Option } from '@polkadot/types';
|
||||
import { formatNumber } from '@polkadot/util';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
import TipClose from './TipClose';
|
||||
import TipEndorse from './TipEndorse';
|
||||
import TipReason from './TipReason';
|
||||
|
||||
interface Props {
|
||||
bestNumber?: BlockNumber;
|
||||
className?: string;
|
||||
hash: string;
|
||||
isMember: boolean;
|
||||
members: string[];
|
||||
}
|
||||
|
||||
function Tip ({ className = '', hash, isMember, members }: Props): React.ReactElement<Props> | null {
|
||||
function Tip ({ bestNumber, className = '', hash, isMember, members }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const { allAccounts } = useAccounts();
|
||||
@ -40,8 +43,9 @@ function Tip ({ className = '', hash, isMember, members }: Props): React.ReactEl
|
||||
return null;
|
||||
}
|
||||
|
||||
const { finder, reason, tips, who } = tip;
|
||||
const { closes, finder, reason, tips, who } = tip;
|
||||
const finderInfo = finder.unwrapOr(null);
|
||||
const closesAt = closes.unwrapOr(null);
|
||||
|
||||
return (
|
||||
<tr className={className}>
|
||||
@ -74,18 +78,34 @@ function Tip ({ className = '', hash, isMember, members }: Props): React.ReactEl
|
||||
)}
|
||||
</td>
|
||||
<td className='button'>
|
||||
<TipEndorse
|
||||
hash={hash}
|
||||
isMember={isMember}
|
||||
members={members}
|
||||
/>
|
||||
{isMember && (
|
||||
<Badge
|
||||
info={<Icon name={isTipper ? 'check' : 'question'} />}
|
||||
isInline
|
||||
type={isTipper ? 'green' : 'gray'}
|
||||
{!closesAt && (
|
||||
<TipEndorse
|
||||
hash={hash}
|
||||
isMember={isMember}
|
||||
members={members}
|
||||
/>
|
||||
)}
|
||||
{bestNumber && closesAt && (
|
||||
closesAt.gt(bestNumber)
|
||||
? (
|
||||
<>
|
||||
<BlockToTime blocks={closesAt.sub(bestNumber)} />
|
||||
#{formatNumber(closesAt)}
|
||||
</>
|
||||
)
|
||||
: (
|
||||
<TipClose
|
||||
hash={hash}
|
||||
isMember={isMember}
|
||||
members={members}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</td>
|
||||
<td className='badge'>
|
||||
{isMember && isTipper && (
|
||||
<Icon name='check square outline' />
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
||||
68
packages/page-treasury/src/Overview/TipClose.tsx
Normal file
68
packages/page-treasury/src/Overview/TipClose.tsx
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright 2017-2020 @polkadot/app-treasury 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 React, { useState } from 'react';
|
||||
import { Button, InputAddress, Modal, TxButton } from '@polkadot/react-components';
|
||||
import { useToggle } from '@polkadot/react-hooks';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
|
||||
interface Props {
|
||||
hash: string;
|
||||
isMember: boolean;
|
||||
members: string[];
|
||||
}
|
||||
|
||||
function TipClose ({ hash, isMember, members }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const [isOpen, toggleOpen] = useToggle();
|
||||
const [accountId, setAccountId] = useState<string | null>(null);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
icon='cancel'
|
||||
isDisabled={!isMember}
|
||||
label={t<string>('Close')}
|
||||
onClick={toggleOpen}
|
||||
/>
|
||||
{isOpen && (
|
||||
<Modal
|
||||
header={t<string>('Close tip')}
|
||||
size='large'
|
||||
>
|
||||
<Modal.Content>
|
||||
<Modal.Columns>
|
||||
<Modal.Column>
|
||||
<InputAddress
|
||||
filter={members}
|
||||
help={t<string>('Select the account you wish to close from.')}
|
||||
label={t<string>('submit with account')}
|
||||
onChange={setAccountId}
|
||||
type='account'
|
||||
withLabel
|
||||
/>
|
||||
</Modal.Column>
|
||||
<Modal.Column>
|
||||
<p>{t<string>('Your close will be applied for this council account.')}</p>
|
||||
</Modal.Column>
|
||||
</Modal.Columns>
|
||||
</Modal.Content>
|
||||
<Modal.Actions onCancel={toggleOpen}>
|
||||
<TxButton
|
||||
accountId={accountId}
|
||||
isDisabled={!accountId}
|
||||
isPrimary
|
||||
onStart={toggleOpen}
|
||||
params={[hash]}
|
||||
tx='treasury.closeTip'
|
||||
/>
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(TipClose);
|
||||
@ -2,8 +2,11 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { BlockNumber } from '@polkadot/types/interfaces';
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
import { Table } from '@polkadot/react-components';
|
||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
import Tip from './Tip';
|
||||
@ -17,6 +20,8 @@ interface Props {
|
||||
|
||||
function Tips ({ className = '', hashes, isMember, members }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []);
|
||||
|
||||
const header = useMemo(() => [
|
||||
[t('tips'), 'start'],
|
||||
@ -24,7 +29,8 @@ function Tips ({ className = '', hashes, isMember, members }: Props): React.Reac
|
||||
[t('fee')],
|
||||
[t('reason'), 'start'],
|
||||
[],
|
||||
[]
|
||||
[],
|
||||
[undefined, 'mini']
|
||||
], [t]);
|
||||
|
||||
return (
|
||||
@ -35,6 +41,7 @@ function Tips ({ className = '', hashes, isMember, members }: Props): React.Reac
|
||||
>
|
||||
{hashes?.map((hash): React.ReactNode => (
|
||||
<Tip
|
||||
bestNumber={bestNumber}
|
||||
hash={hash}
|
||||
isMember={isMember}
|
||||
key={hash}
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { useMemo } from 'react';
|
||||
import { timeToString } from '@polkadot/react-components/util';
|
||||
|
||||
Loading…
Reference in New Issue
Block a user