Combine status event types (#2478)
* Combine status event types * Adjust some tables * Adjust targets
This commit is contained in:
parent
4f9794ed12
commit
3dfaf17ca8
@ -51,7 +51,7 @@ function Motion ({ className, isMember, members, motion: { hash, proposal, votes
|
||||
</>
|
||||
)}
|
||||
</td>
|
||||
<td className='number'>
|
||||
<td className='address'>
|
||||
{ayes.map((address, index): React.ReactNode => (
|
||||
<AddressMini
|
||||
key={`${index}:${address}`}
|
||||
@ -60,7 +60,7 @@ function Motion ({ className, isMember, members, motion: { hash, proposal, votes
|
||||
/>
|
||||
))}
|
||||
</td>
|
||||
<td className='number'>
|
||||
<td className='address'>
|
||||
{nays.map((address, index): React.ReactNode => (
|
||||
<AddressMini
|
||||
key={`${index}:${address}`}
|
||||
@ -78,10 +78,13 @@ function Motion ({ className, isMember, members, motion: { hash, proposal, votes
|
||||
prime={prime}
|
||||
proposal={proposal}
|
||||
/>
|
||||
</td>
|
||||
<td className='mini'>
|
||||
<LinkExternal
|
||||
data={index}
|
||||
hash={hash.toString()}
|
||||
type='council'
|
||||
withShort
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@ -51,9 +51,9 @@ function Proposals ({ className, motions, prime }: Props): React.ReactElement<Pr
|
||||
<th colSpan={2}> </th>
|
||||
<th>{t('threshold')}</th>
|
||||
<th>{t('voting end')}</th>
|
||||
<th>{t('aye')}</th>
|
||||
<th>{t('nay')}</th>
|
||||
<th> </th>
|
||||
<th className='address'>{t('aye')}</th>
|
||||
<th className='address'>{t('nay')}</th>
|
||||
<th colSpan={2}> </th>
|
||||
</Table.Head>
|
||||
<Table.Body>
|
||||
{motions?.map((motion: DeriveCollectiveProposal): React.ReactNode => (
|
||||
|
||||
@ -32,7 +32,7 @@ function Validator ({ info: { accountId, bondOther, bondOwn, bondTotal, commissi
|
||||
toggleFavorite={toggleFavorite}
|
||||
/>
|
||||
<td className='number'>{formatNumber(rankOverall)}</td>
|
||||
<td className='address'>
|
||||
<td className='address all'>
|
||||
<AddressSmall value={accountId} />
|
||||
</td>
|
||||
<td className='number'>
|
||||
|
||||
@ -41,7 +41,7 @@ function Proposal ({ className, imageHash, prime }: Props): React.ReactElement<P
|
||||
<td className='number'>
|
||||
{formatNumber(ayes.length)}/{formatNumber(threshold)}
|
||||
</td>
|
||||
<td className='number'>
|
||||
<td className='address'>
|
||||
{ayes.map((address, index): React.ReactNode => (
|
||||
<AddressMini
|
||||
key={`${index}:${address}`}
|
||||
@ -50,7 +50,7 @@ function Proposal ({ className, imageHash, prime }: Props): React.ReactElement<P
|
||||
/>
|
||||
))}
|
||||
</td>
|
||||
<td className='number'>
|
||||
<td className='address'>
|
||||
{nays.map((address, index): React.ReactNode => (
|
||||
<AddressMini
|
||||
key={`${index}:${address}`}
|
||||
|
||||
@ -33,10 +33,14 @@ function Propose ({ isMember, members }: Props): React.ReactElement<Props> {
|
||||
[members]
|
||||
);
|
||||
|
||||
const _onChangeExtrinsic = (method?: SubmittableExtrinsic<'promise'>): void =>
|
||||
setProposal(() => method || null);
|
||||
const _onChangeThreshold = (threshold?: BN): void =>
|
||||
setThreshold([threshold || null, _hasThreshold(threshold)]);
|
||||
const _onChangeExtrinsic = useCallback(
|
||||
(method?: SubmittableExtrinsic<'promise'>): void => setProposal(() => method || null),
|
||||
[]
|
||||
);
|
||||
const _onChangeThreshold = useCallback(
|
||||
(threshold?: BN): void => setThreshold([threshold || null, _hasThreshold(threshold)]),
|
||||
[_hasThreshold]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@ -29,13 +29,13 @@ function Proposals ({ className, isMember, members, prime, proposals }: Props):
|
||||
<Table>
|
||||
<Table.Head>
|
||||
<th colSpan={2}> </th>
|
||||
<td>{t('threshold')}</td>
|
||||
<td>{t('aye')}</td>
|
||||
<td>{t('nay')}</td>
|
||||
<th>{t('threshold')}</th>
|
||||
<th className='address'>{t('aye')}</th>
|
||||
<th className='address'>{t('nay')}</th>
|
||||
<th> </th>
|
||||
</Table.Head>
|
||||
<Table.Body>
|
||||
{proposals?.map((hash: Hash): React.ReactNode => (
|
||||
{proposals.map((hash: Hash): React.ReactNode => (
|
||||
<Proposal
|
||||
imageHash={hash.toHex()}
|
||||
key={hash.toHex()}
|
||||
|
||||
@ -26,18 +26,18 @@ function ProposalDisplay ({ className, isMember, proposal: { council, id, propos
|
||||
<td className='number'>
|
||||
<h1>{formatNumber(id)}</h1>
|
||||
</td>
|
||||
<td className='address'>
|
||||
<td className='address all'>
|
||||
<AddressSmall value={proposal.proposer} />
|
||||
</td>
|
||||
<td className='number'>
|
||||
<FormatBalance value={proposal.bond} />
|
||||
</td>
|
||||
<td className='address'>
|
||||
<AddressMini value={proposal.beneficiary} />
|
||||
</td>
|
||||
<td>
|
||||
<td className='number'>
|
||||
<FormatBalance value={proposal.value} />
|
||||
</td>
|
||||
<td className='number'>
|
||||
<FormatBalance value={proposal.bond} />
|
||||
</td>
|
||||
<td className='button'>
|
||||
{withSend && (
|
||||
<>
|
||||
@ -52,9 +52,12 @@ function ProposalDisplay ({ className, isMember, proposal: { council, id, propos
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</td>
|
||||
<td className='mini'>
|
||||
<LinkExternal
|
||||
data={id}
|
||||
type='treasury'
|
||||
withShort
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@ -48,10 +48,10 @@ function ProposalsBase ({ className, isApprovals, proposals }: Props): React.Rea
|
||||
<Table>
|
||||
<Table.Head>
|
||||
<th colSpan={2}> </th>
|
||||
<td>{t('bond')}</td>
|
||||
<td className='address'>{t('beneficiary')}</td>
|
||||
<td>{t('value')}</td>
|
||||
<th> </th>
|
||||
<th className='address'>{t('beneficiary')}</th>
|
||||
<th>{t('payment')}</th>
|
||||
<th>{t('bond')}</th>
|
||||
<th colSpan={2}> </th>
|
||||
</Table.Head>
|
||||
<Table.Body>
|
||||
{proposals.map((proposal): React.ReactNode => (
|
||||
|
||||
@ -35,6 +35,10 @@ const Memo = React.memo(styled(ButtonGroup)`
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
> .ui.buttons {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
&.centered {
|
||||
margin-bottom: 0.5rem;
|
||||
text-align: center;
|
||||
|
||||
@ -8,7 +8,7 @@ import { ITuple, SignerPayloadJSON } from '@polkadot/types/types';
|
||||
import { BareProps } from '../types';
|
||||
import { ActionStatus, PartialQueueTxExtrinsic, PartialQueueTxRpc, QueueStatus, QueueTx, QueueTxExtrinsic, QueueTxRpc, QueueTxStatus, SignerCallback } from './types';
|
||||
|
||||
import React, { useRef, useState } from 'react';
|
||||
import React, { useCallback, useRef, useState } from 'react';
|
||||
import { SubmittableResult } from '@polkadot/api';
|
||||
import { registry } from '@polkadot/react-api';
|
||||
import jsonrpc from '@polkadot/types/interfaces/jsonrpc';
|
||||
@ -21,153 +21,195 @@ export interface Props extends BareProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
interface StatusCount {
|
||||
count: number;
|
||||
status: ActionStatus;
|
||||
}
|
||||
|
||||
let nextId = 0;
|
||||
|
||||
const REMOVE_TIMEOUT = 7500;
|
||||
const SUBMIT_RPC = jsonrpc.author.submitAndWatchExtrinsic;
|
||||
|
||||
function Queue ({ children }: Props): React.ReactElement<Props> {
|
||||
const [_stqueue, _setStQueue] = useState<QueueStatus[]>([]);
|
||||
const [_txqueue, _setTxQueue] = useState<QueueTx[]>([]);
|
||||
const stRef = useRef(_stqueue);
|
||||
const txRef = useRef(_txqueue);
|
||||
function mergeStatus (status: ActionStatus[]): ActionStatus[] {
|
||||
return status
|
||||
.reduce((result: StatusCount[], status): StatusCount[] => {
|
||||
const prev = result.find(({ status: prev }) => prev.action === status.action && prev.status === status.status);
|
||||
|
||||
const setStQueue = (st: QueueStatus[]): void => {
|
||||
stRef.current = st;
|
||||
_setStQueue(st);
|
||||
};
|
||||
const setTxQueue = (tx: QueueTx[]): void => {
|
||||
txRef.current = tx;
|
||||
_setTxQueue(tx);
|
||||
};
|
||||
if (prev) {
|
||||
prev.count++;
|
||||
} else {
|
||||
result.push({ count: 1, status });
|
||||
}
|
||||
|
||||
const addToTxQueue = (value: QueueTxExtrinsic | QueueTxRpc | QueueTx): void => {
|
||||
const id = ++nextId;
|
||||
const removeItem = (): void =>
|
||||
setTxQueue([...txRef.current.map((item): QueueTx =>
|
||||
item.id === id
|
||||
? { ...item, status: 'completed' }
|
||||
: item
|
||||
)]);
|
||||
return result;
|
||||
}, [])
|
||||
.map(({ count, status }): ActionStatus =>
|
||||
count === 1
|
||||
? status
|
||||
: { ...status, action: `${status.action} (x${count})` }
|
||||
);
|
||||
}
|
||||
|
||||
setTxQueue([...txRef.current, {
|
||||
...value,
|
||||
id,
|
||||
removeItem,
|
||||
rpc: (value as QueueTxRpc).rpc || SUBMIT_RPC,
|
||||
status: 'queued'
|
||||
}]);
|
||||
};
|
||||
function extractEvents (result?: SubmittableResult): ActionStatus[] {
|
||||
return mergeStatus(
|
||||
((result && result.events) || [])
|
||||
// filter events handled globally, or those we are not interested in, these are
|
||||
// handled by the global overview, so don't add them here
|
||||
.filter((record): boolean => !!record.event && record.event.section !== 'democracy')
|
||||
.map(({ event: { data, method, section } }): ActionStatus => {
|
||||
if (section === 'system' && method === 'ExtrinsicFailed') {
|
||||
const [dispatchError] = data as unknown as ITuple<[DispatchError]>;
|
||||
let message = dispatchError.type;
|
||||
|
||||
const queueAction = (status: ActionStatus | ActionStatus[]): void => {
|
||||
const _status = Array.isArray(status) ? status : [status];
|
||||
if (dispatchError.isModule) {
|
||||
try {
|
||||
const mod = dispatchError.asModule;
|
||||
const error = registry.findMetaError(new Uint8Array([mod.index.toNumber(), mod.error.toNumber()]));
|
||||
|
||||
if (_status.length) {
|
||||
setStQueue([...stRef.current, ...(_status.map((item): QueueStatus => {
|
||||
const id = ++nextId;
|
||||
const removeItem = (): void =>
|
||||
setStQueue([...stRef.current.filter((item): boolean => item.id !== id)]);
|
||||
|
||||
setTimeout(removeItem, REMOVE_TIMEOUT);
|
||||
|
||||
return {
|
||||
...item,
|
||||
id,
|
||||
isCompleted: false,
|
||||
removeItem
|
||||
};
|
||||
}))]);
|
||||
}
|
||||
};
|
||||
const queueExtrinsic = ({ accountId, extrinsic, txFailedCb, txSuccessCb, txStartCb, txUpdateCb, isUnsigned }: PartialQueueTxExtrinsic): void =>
|
||||
addToTxQueue({
|
||||
accountId,
|
||||
extrinsic,
|
||||
isUnsigned,
|
||||
txFailedCb,
|
||||
txSuccessCb,
|
||||
txStartCb,
|
||||
txUpdateCb
|
||||
});
|
||||
const queuePayload = (payload: SignerPayloadJSON, signerCb: SignerCallback): void =>
|
||||
addToTxQueue({
|
||||
accountId: payload.address,
|
||||
// this is not great, but the Extrinsic we don't need a submittable
|
||||
extrinsic: createType(registry, 'Extrinsic',
|
||||
{ method: createType(registry, 'Call', payload.method) },
|
||||
{ version: payload.version }
|
||||
) as unknown as SubmittableExtrinsic,
|
||||
payload,
|
||||
signerCb
|
||||
});
|
||||
const queueRpc = ({ accountId, rpc, values }: PartialQueueTxRpc): void =>
|
||||
addToTxQueue({
|
||||
accountId,
|
||||
rpc,
|
||||
values
|
||||
});
|
||||
const queueSetTxStatus = (id: number, status: QueueTxStatus, result?: SubmittableResult, error?: Error): void => {
|
||||
setTxQueue([...txRef.current.map((item): QueueTx =>
|
||||
item.id === id
|
||||
? {
|
||||
...item,
|
||||
error: error === undefined
|
||||
? item.error
|
||||
: error,
|
||||
result: result === undefined
|
||||
? item.result
|
||||
: result,
|
||||
status: item.status === 'completed'
|
||||
? item.status
|
||||
: status
|
||||
}
|
||||
: item
|
||||
)]);
|
||||
|
||||
queueAction(
|
||||
((result && result.events) || [])
|
||||
// filter events handled globally, or those we are not interested in, these are
|
||||
// handled by the global overview, so don't add them here
|
||||
.filter((record): boolean => !!record.event && record.event.section !== 'democracy')
|
||||
.map(({ event: { data, method, section } }): ActionStatus => {
|
||||
if (section === 'system' && method === 'ExtrinsicFailed') {
|
||||
const [dispatchError] = data as unknown as ITuple<[DispatchError]>;
|
||||
let message = dispatchError.type;
|
||||
|
||||
if (dispatchError.isModule) {
|
||||
try {
|
||||
const mod = dispatchError.asModule;
|
||||
const error = registry.findMetaError(new Uint8Array([mod.index.toNumber(), mod.error.toNumber()]));
|
||||
|
||||
message = `${error.section}.${error.name}`;
|
||||
} catch (error) {
|
||||
// swallow
|
||||
}
|
||||
message = `${error.section}.${error.name}`;
|
||||
} catch (error) {
|
||||
// swallow
|
||||
}
|
||||
|
||||
return {
|
||||
action: `${section}.${method}`,
|
||||
status: 'error',
|
||||
message
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
action: `${section}.${method}`,
|
||||
status: 'event',
|
||||
message: 'extrinsic event'
|
||||
status: 'error',
|
||||
message
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (STATUS_COMPLETE.includes(status)) {
|
||||
setTimeout((): void => {
|
||||
const item = txRef.current.find((item): boolean => item.id === id);
|
||||
return {
|
||||
action: `${section}.${method}`,
|
||||
status: 'event',
|
||||
message: 'extrinsic event'
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
item && item.removeItem();
|
||||
}, REMOVE_TIMEOUT);
|
||||
}
|
||||
};
|
||||
function Queue ({ children }: Props): React.ReactElement<Props> {
|
||||
const [stqueue, _setStQueue] = useState<QueueStatus[]>([]);
|
||||
const [txqueue, _setTxQueue] = useState<QueueTx[]>([]);
|
||||
const stRef = useRef(stqueue);
|
||||
const txRef = useRef(txqueue);
|
||||
|
||||
const setStQueue = useCallback(
|
||||
(st: QueueStatus[]): void => {
|
||||
stRef.current = st;
|
||||
_setStQueue(st);
|
||||
},
|
||||
[]
|
||||
);
|
||||
const setTxQueue = useCallback(
|
||||
(tx: QueueTx[]): void => {
|
||||
txRef.current = tx;
|
||||
_setTxQueue(tx);
|
||||
},
|
||||
[]
|
||||
);
|
||||
const addToTxQueue = useCallback(
|
||||
(value: QueueTxExtrinsic | QueueTxRpc | QueueTx): void => {
|
||||
const id = ++nextId;
|
||||
const removeItem = (): void =>
|
||||
setTxQueue([...txRef.current.map((item): QueueTx =>
|
||||
item.id === id
|
||||
? { ...item, status: 'completed' }
|
||||
: item
|
||||
)]);
|
||||
|
||||
setTxQueue([...txRef.current, {
|
||||
...value,
|
||||
id,
|
||||
removeItem,
|
||||
rpc: (value as QueueTxRpc).rpc || SUBMIT_RPC,
|
||||
status: 'queued'
|
||||
}]);
|
||||
},
|
||||
[setTxQueue]
|
||||
);
|
||||
const queueAction = useCallback(
|
||||
(_status: ActionStatus | ActionStatus[]): void => {
|
||||
const status = Array.isArray(_status) ? _status : [_status];
|
||||
|
||||
status.length && setStQueue([
|
||||
...stRef.current,
|
||||
...(status.map((item): QueueStatus => {
|
||||
const id = ++nextId;
|
||||
const removeItem = (): void =>
|
||||
setStQueue([...stRef.current.filter((item): boolean => item.id !== id)]);
|
||||
|
||||
setTimeout(removeItem, REMOVE_TIMEOUT);
|
||||
|
||||
return {
|
||||
...item,
|
||||
id,
|
||||
isCompleted: false,
|
||||
removeItem
|
||||
};
|
||||
}))
|
||||
]);
|
||||
},
|
||||
[setStQueue]
|
||||
);
|
||||
const queueExtrinsic = useCallback(
|
||||
(value: PartialQueueTxExtrinsic): void =>
|
||||
addToTxQueue({ ...value }),
|
||||
[addToTxQueue]
|
||||
);
|
||||
const queuePayload = useCallback(
|
||||
(payload: SignerPayloadJSON, signerCb: SignerCallback): void =>
|
||||
addToTxQueue({
|
||||
accountId: payload.address,
|
||||
// this is not great, but the Extrinsic we don't need a submittable
|
||||
extrinsic: createType(registry, 'Extrinsic',
|
||||
{ method: createType(registry, 'Call', payload.method) },
|
||||
{ version: payload.version }
|
||||
) as unknown as SubmittableExtrinsic,
|
||||
payload,
|
||||
signerCb
|
||||
}),
|
||||
[addToTxQueue]
|
||||
);
|
||||
const queueRpc = useCallback(
|
||||
(value: PartialQueueTxRpc): void =>
|
||||
addToTxQueue({ ...value }),
|
||||
[addToTxQueue]
|
||||
);
|
||||
const queueSetTxStatus = useCallback(
|
||||
(id: number, status: QueueTxStatus, result?: SubmittableResult, error?: Error): void => {
|
||||
setTxQueue([...txRef.current.map((item): QueueTx =>
|
||||
item.id === id
|
||||
? {
|
||||
...item,
|
||||
error: error === undefined
|
||||
? item.error
|
||||
: error,
|
||||
result: result === undefined
|
||||
? item.result
|
||||
: result,
|
||||
status: item.status === 'completed'
|
||||
? item.status
|
||||
: status
|
||||
}
|
||||
: item
|
||||
)]);
|
||||
|
||||
queueAction(
|
||||
extractEvents(result)
|
||||
);
|
||||
|
||||
if (STATUS_COMPLETE.includes(status)) {
|
||||
setTimeout((): void => {
|
||||
const item = txRef.current.find((item): boolean => item.id === id);
|
||||
|
||||
item && item.removeItem();
|
||||
}, REMOVE_TIMEOUT);
|
||||
}
|
||||
},
|
||||
[queueAction, setTxQueue]
|
||||
);
|
||||
|
||||
return (
|
||||
<QueueProvider value={{
|
||||
@ -176,8 +218,8 @@ function Queue ({ children }: Props): React.ReactElement<Props> {
|
||||
queuePayload,
|
||||
queueRpc,
|
||||
queueSetTxStatus,
|
||||
stqueue: _stqueue,
|
||||
txqueue: _txqueue
|
||||
stqueue,
|
||||
txqueue
|
||||
}}>
|
||||
{children}
|
||||
</QueueProvider>
|
||||
|
||||
@ -61,7 +61,7 @@ const Memo = React.memo(styled(Table)`
|
||||
width: 100%;
|
||||
|
||||
thead tr {
|
||||
background: #fafafa;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
tbody tr {
|
||||
@ -130,14 +130,11 @@ const Memo = React.memo(styled(Table)`
|
||||
}
|
||||
|
||||
&.address {
|
||||
min-width: 11rem;
|
||||
padding: 0.85rem 1rem;
|
||||
|
||||
> .ui--AddressMini,
|
||||
> .ui--AddressMini.padded {
|
||||
padding: 0;
|
||||
margin-bottom: -0.85rem;
|
||||
margin-top: -0.25rem;
|
||||
|
||||
label.ui--AddressMini-label {
|
||||
margin-bottom: -0.3rem;
|
||||
}
|
||||
@ -169,9 +166,9 @@ const Memo = React.memo(styled(Table)`
|
||||
}
|
||||
|
||||
th {
|
||||
color: #999;
|
||||
color: #888;
|
||||
font-family: sans-serif;
|
||||
font-weight: 500;
|
||||
font-weight: 400;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
|
||||
|
||||
@ -29,8 +29,7 @@ export default function useAccounts (): UseAccounts {
|
||||
return (): void => {
|
||||
setTimeout(() => subscription.unsubscribe(), 0);
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
}, [mountedRef]);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -29,8 +29,7 @@ export default function useAccounts (): UseAccounts {
|
||||
return (): void => {
|
||||
setTimeout(() => subscription.unsubscribe(), 0);
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
}, [mountedRef]);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -14,17 +14,17 @@ interface Result {
|
||||
|
||||
export default function useMembers (collective: 'council' | 'technicalCommittee'): Result {
|
||||
const { api } = useApi();
|
||||
const { allAccounts } = useAccounts();
|
||||
const { allAccounts, hasAccounts } = useAccounts();
|
||||
const [state, setState] = useState<Result>({ isMember: false, members: [] });
|
||||
const retrieved = (
|
||||
collective === 'council'
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
? useCall<string[]>(api.query.electionsPhragmen?.members || api.query.elections.members, [], {
|
||||
? useCall<string[]>(hasAccounts && (api.query.electionsPhragmen?.members || api.query.elections.members), [], {
|
||||
transform: (accounts: [AccountId, Balance][]): string[] =>
|
||||
accounts.map(([accountId]) => accountId.toString())
|
||||
})
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
: useCall<string[]>(api.query.technicalCommittee.members, [], {
|
||||
: useCall<string[]>(hasAccounts && api.query.technicalCommittee.members, [], {
|
||||
transform: (accounts: AccountId[]): string[] =>
|
||||
accounts.map((accountId) => accountId.toString())
|
||||
})
|
||||
|
||||
@ -33,15 +33,15 @@ function getStashes (allAccounts: string[], ownBonded: Option<AccountId>[], ownL
|
||||
}
|
||||
|
||||
export default function useOwnStashes (): [string, IsInKeyring][] | undefined {
|
||||
const { allAccounts } = useAccounts();
|
||||
const { allAccounts, hasAccounts } = useAccounts();
|
||||
const mountedRef = useIsMountedRef();
|
||||
const { api } = useApi();
|
||||
const ownBonded = useCall<Option<AccountId>[]>(api.query.staking?.bonded.multi as any, [allAccounts]);
|
||||
const ownLedger = useCall<Option<StakingLedger>[]>(api.query.staking?.ledger.multi as any, [allAccounts]);
|
||||
const ownBonded = useCall<Option<AccountId>[]>(hasAccounts && api.query.staking?.bonded.multi as any, [allAccounts]);
|
||||
const ownLedger = useCall<Option<StakingLedger>[]>(hasAccounts && api.query.staking?.ledger.multi as any, [allAccounts]);
|
||||
const [state, setState] = useState<[string, IsInKeyring][] | undefined>();
|
||||
|
||||
useEffect((): void => {
|
||||
mountedRef.current && allAccounts && ownBonded && ownLedger && setState(
|
||||
mountedRef.current && ownBonded && ownLedger && setState(
|
||||
getStashes(allAccounts, ownBonded, ownLedger)
|
||||
);
|
||||
}, [allAccounts, mountedRef, ownBonded, ownLedger]);
|
||||
|
||||
@ -18,8 +18,8 @@ interface State {
|
||||
|
||||
export default function useRegistrars (): State {
|
||||
const { api } = useApi();
|
||||
const { allAccounts } = useAccounts();
|
||||
const query = useCall<Option<RegistrarInfo>[]>(api.query.identity?.registrars, []);
|
||||
const { allAccounts, hasAccounts } = useAccounts();
|
||||
const query = useCall<Option<RegistrarInfo>[]>(hasAccounts && api.query.identity?.registrars, []);
|
||||
const [state, setState] = useState<State>({ isRegistrar: false, registrars: [] });
|
||||
|
||||
// determine if we have a registrar or not - registrars are allowed to approve
|
||||
|
||||
@ -12,8 +12,8 @@ import useCall from './useCall';
|
||||
|
||||
export default function useSudo (): UseSudo {
|
||||
const { api } = useApi();
|
||||
const { allAccounts } = useAccounts();
|
||||
const sudoKey = useCall<string>(api.query.sudo?.key, [], {
|
||||
const { allAccounts, hasAccounts } = useAccounts();
|
||||
const sudoKey = useCall<string>(hasAccounts && api.query.sudo?.key, [], {
|
||||
transform: (k): string =>
|
||||
k.toString()
|
||||
});
|
||||
|
||||
@ -192,7 +192,11 @@ class Signer extends React.PureComponent<Props, State> {
|
||||
const { isExternal, isHardware, hardwareType } = extractExternal(currentItem.accountId);
|
||||
|
||||
return (
|
||||
<Modal.Actions cancelLabel={signedTx ? t('Close') : undefined} withOr={!signedTx} onCancel={isQrVisible ? this.onCancelQr : signedTx ? this.onCancelSign : this.onCancel}>
|
||||
<Modal.Actions
|
||||
cancelLabel={signedTx ? t('Close') : undefined}
|
||||
withOr={!signedTx}
|
||||
onCancel={isQrVisible ? this.onCancelQr : signedTx ? this.onCancelSign : this.onCancel}
|
||||
>
|
||||
{!isRenderError && (!isQrVisible || !isQrScanning) && !signedTx && (
|
||||
<>
|
||||
{!currentItem.isUnsigned && this.renderSignToggle()}
|
||||
@ -239,15 +243,22 @@ class Signer extends React.PureComponent<Props, State> {
|
||||
tip={tip}
|
||||
value={currentItem}
|
||||
>
|
||||
{isQrVisible ? (
|
||||
<Qr address={qrAddress} isScanning={isQrScanning} onSignature={this.addQrSignature} payload={qrPayload} />
|
||||
) : (
|
||||
<>
|
||||
{this.renderTip()}
|
||||
{this.renderUnlock()}
|
||||
{!isSubmit && this.renderSignFields()}
|
||||
</>
|
||||
)}
|
||||
{isQrVisible
|
||||
? (
|
||||
<Qr
|
||||
address={qrAddress}
|
||||
isScanning={isQrScanning}
|
||||
onSignature={this.addQrSignature}
|
||||
payload={qrPayload}
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<>
|
||||
{this.renderTip()}
|
||||
{this.renderUnlock()}
|
||||
{!isSubmit && this.renderSignFields()}
|
||||
</>
|
||||
)}
|
||||
</Transaction>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user