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:
Jaco Greeff 2020-06-21 09:38:30 +02:00 committed by GitHub
parent 7669f63096
commit b408d68d63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 111 additions and 18 deletions

View File

@ -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>
);

View 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);

View File

@ -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}

View File

@ -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';