Tip hash hook (#4917)
This commit is contained in:
parent
03cd109faa
commit
75b24956e7
@ -23,7 +23,6 @@ interface Props {
|
||||
hash: string;
|
||||
isMember: boolean;
|
||||
members: string[];
|
||||
onRefresh: () => void;
|
||||
onSelect: (hash: string, isSelected: boolean, value: BN) => void;
|
||||
onlyUntipped: boolean;
|
||||
tip: OpenTip | OpenTipTo225;
|
||||
@ -77,7 +76,7 @@ function extractTipState (tip: OpenTip | OpenTipTo225, allAccounts: string[]): T
|
||||
};
|
||||
}
|
||||
|
||||
function Tip ({ bestNumber, className = '', defaultId, hash, isMember, members, onRefresh, onSelect, onlyUntipped, tip }: Props): React.ReactElement<Props> | null {
|
||||
function Tip ({ bestNumber, className = '', defaultId, hash, isMember, members, onSelect, onlyUntipped, tip }: Props): React.ReactElement<Props> | null {
|
||||
const { api } = useApi();
|
||||
const { t } = useTranslation();
|
||||
const { allAccounts } = useAccounts();
|
||||
@ -152,7 +151,6 @@ function Tip ({ bestNumber, className = '', defaultId, hash, isMember, members,
|
||||
className='media--1400'
|
||||
icon='times'
|
||||
label={t('Cancel')}
|
||||
onSuccess={onRefresh}
|
||||
params={[hash]}
|
||||
tx={(api.tx.tips || api.tx.treasury).retractTip}
|
||||
/>
|
||||
@ -174,7 +172,6 @@ function Tip ({ bestNumber, className = '', defaultId, hash, isMember, members,
|
||||
accountId={councilId}
|
||||
icon='times'
|
||||
label={t<string>('Close')}
|
||||
onSuccess={onRefresh}
|
||||
params={[hash]}
|
||||
tx={(api.tx.tips || api.tx.treasury).closeTip}
|
||||
/>
|
||||
|
||||
@ -11,13 +11,12 @@ import { useTranslation } from '../translate';
|
||||
|
||||
interface Props {
|
||||
members: string[];
|
||||
refresh: () => void;
|
||||
}
|
||||
|
||||
const MAX_REASON_LEN = 128;
|
||||
const MIN_REASON_LEN = 5;
|
||||
|
||||
function TipCreate ({ members, refresh }: Props): React.ReactElement<Props> {
|
||||
function TipCreate ({ members }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const [isOpen, toggleOpen] = useToggle();
|
||||
@ -90,7 +89,6 @@ function TipCreate ({ members, refresh }: Props): React.ReactElement<Props> {
|
||||
isDisabled={!accountId || (isMember && !hasValue) || !hasReason}
|
||||
label={t<string>('Propose tip')}
|
||||
onStart={toggleOpen}
|
||||
onSuccess={refresh}
|
||||
params={
|
||||
isMember
|
||||
? [reason, beneficiary, value]
|
||||
|
||||
@ -20,7 +20,6 @@ interface Props {
|
||||
hashes?: string[] | null;
|
||||
isMember: boolean;
|
||||
members: string[];
|
||||
onRefresh: () => void;
|
||||
onSelectTip: (hash: string, isSelected: boolean, value: BN) => void,
|
||||
}
|
||||
|
||||
@ -49,7 +48,7 @@ function extractTips (tipsWithHashes?: [[string[]], Option<OpenTip>[]], inHashes
|
||||
);
|
||||
}
|
||||
|
||||
function Tips ({ className = '', defaultId, hashes, isMember, members, onRefresh, onSelectTip }: Props): React.ReactElement<Props> {
|
||||
function Tips ({ className = '', defaultId, hashes, isMember, members, onSelectTip }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const [onlyUntipped, setOnlyUntipped] = useState(false);
|
||||
@ -95,7 +94,6 @@ function Tips ({ className = '', defaultId, hashes, isMember, members, onRefresh
|
||||
isMember={isMember}
|
||||
key={hash}
|
||||
members={members}
|
||||
onRefresh={onRefresh}
|
||||
onSelect={onSelectTip}
|
||||
onlyUntipped={onlyUntipped}
|
||||
tip={tip}
|
||||
|
||||
@ -18,7 +18,6 @@ interface Props {
|
||||
hashes?: string[] | null;
|
||||
isMember: boolean;
|
||||
members: string[];
|
||||
trigger: () => void;
|
||||
}
|
||||
|
||||
interface QuickTipsState {
|
||||
@ -26,7 +25,7 @@ interface QuickTipsState {
|
||||
quickTx: SubmittableExtrinsic<'promise'> | null;
|
||||
}
|
||||
|
||||
function TipsEntry ({ className, hashes, isMember, members, trigger }: Props): React.ReactElement<Props> {
|
||||
function TipsEntry ({ className, hashes, isMember, members }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { allAccounts } = useAccounts();
|
||||
const { api } = useApi();
|
||||
@ -61,10 +60,7 @@ function TipsEntry ({ className, hashes, isMember, members, trigger }: Props): R
|
||||
return (
|
||||
<div className={className}>
|
||||
<Button.Group>
|
||||
<TipCreate
|
||||
members={members}
|
||||
refresh={trigger}
|
||||
/>
|
||||
<TipCreate members={members} />
|
||||
<TxButton
|
||||
accountId={defaultId}
|
||||
extrinsic={quickTx}
|
||||
@ -78,7 +74,6 @@ function TipsEntry ({ className, hashes, isMember, members, trigger }: Props): R
|
||||
hashes={hashes}
|
||||
isMember={isMember}
|
||||
members={members}
|
||||
onRefresh={trigger}
|
||||
onSelectTip={_selectTip}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -1,16 +1,18 @@
|
||||
// Copyright 2017-2021 @polkadot/app-treasury authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { Route, Switch } from 'react-router';
|
||||
|
||||
import { HelpOverlay, Tabs } from '@polkadot/react-components';
|
||||
import { useApi, useIncrement, useIsMountedRef, useMembers } from '@polkadot/react-hooks';
|
||||
import { useApi, useMembers } from '@polkadot/react-hooks';
|
||||
import { isFunction } from '@polkadot/util';
|
||||
|
||||
import basicMd from './md/basic.md';
|
||||
import Overview from './Overview';
|
||||
import Tips from './Tips';
|
||||
import { useTranslation } from './translate';
|
||||
import useTipHashes from './useTipHashes';
|
||||
|
||||
export { default as useCounter } from './useCounter';
|
||||
|
||||
@ -18,23 +20,18 @@ interface Props {
|
||||
basePath: string;
|
||||
}
|
||||
|
||||
interface TabItem {
|
||||
count?: number;
|
||||
isRoot?: boolean;
|
||||
name: string;
|
||||
text: string;
|
||||
}
|
||||
|
||||
function TreasuryApp ({ basePath }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const mountedRef = useIsMountedRef();
|
||||
const [tipHashTrigger, triggerTipHashes] = useIncrement();
|
||||
const { isMember, members } = useMembers();
|
||||
const [tipHashes, setTipHashes] = useState<string[] | null>(null);
|
||||
|
||||
useEffect((): void => {
|
||||
if (tipHashTrigger && mountedRef.current) {
|
||||
(api.query.tips || api.query.treasury).tips.keys().then((keys) =>
|
||||
mountedRef.current && setTipHashes(
|
||||
keys.map((key) => key.args[0].toHex())
|
||||
)
|
||||
).catch(console.error);
|
||||
}
|
||||
}, [api, tipHashTrigger, mountedRef]);
|
||||
const tipHashes = useTipHashes();
|
||||
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
@ -42,12 +39,12 @@ function TreasuryApp ({ basePath }: Props): React.ReactElement<Props> {
|
||||
name: 'overview',
|
||||
text: t<string>('Treasury overview')
|
||||
},
|
||||
{
|
||||
isFunction((api.query.tips || api.query.treasury)?.tips) && {
|
||||
count: tipHashes?.length,
|
||||
name: 'tips',
|
||||
text: t<string>('Tips')
|
||||
}
|
||||
], [t, tipHashes]);
|
||||
].filter((t: TabItem | false): t is TabItem => !!t), [api, t, tipHashes]);
|
||||
|
||||
return (
|
||||
<main className='treasury--App'>
|
||||
@ -62,7 +59,6 @@ function TreasuryApp ({ basePath }: Props): React.ReactElement<Props> {
|
||||
hashes={tipHashes}
|
||||
isMember={isMember}
|
||||
members={members}
|
||||
trigger={triggerTipHashes}
|
||||
/>
|
||||
</Route>
|
||||
<Route>
|
||||
|
||||
30
packages/page-treasury/src/useTipHashes.ts
Normal file
30
packages/page-treasury/src/useTipHashes.ts
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2017-2021 @polkadot/app-treasury authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { useApi, useEventTrigger } from '@polkadot/react-hooks';
|
||||
|
||||
export default function useTipHashes (): string[] | undefined {
|
||||
const { api } = useApi();
|
||||
const trigger = useEventTrigger([api.events.tips?.NewTip, api.events.tips?.TipClosed, api.events.tips?.TipRetracted]);
|
||||
const [state, setState] = useState<string[]>();
|
||||
|
||||
useEffect((): void => {
|
||||
// while we don't trigger on the previous-gen treasury tips, we can still query them
|
||||
const query = (api.query.tips || api.query.treasury)?.tips;
|
||||
|
||||
if (trigger && query) {
|
||||
query
|
||||
.keys()
|
||||
.then((keys) => setState(
|
||||
keys.map(({ args: [hash] }) => hash.toHex())
|
||||
))
|
||||
.catch(console.error);
|
||||
} else {
|
||||
setState([]);
|
||||
}
|
||||
}, [api, trigger]);
|
||||
|
||||
return state;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user