Add event status warnings (#6962)
* Add event status warnings * xcmPallet
This commit is contained in:
parent
a1a9fa5c1d
commit
cbcf7ba15c
@ -13,6 +13,7 @@ import { SubmittableResult } from '@polkadot/api';
|
||||
import jsonrpc from '@polkadot/types/interfaces/jsonrpc';
|
||||
|
||||
import { getContractAbi } from '../util';
|
||||
import { isIncompleteEvent } from './checks';
|
||||
import { STATUS_COMPLETE } from './constants';
|
||||
import { QueueProvider } from './Context';
|
||||
|
||||
@ -36,7 +37,10 @@ function mergeStatus (status: ActionStatusPartial[]): ActionStatus[] {
|
||||
|
||||
const initial = status
|
||||
.reduce((result: StatusCount[], status): StatusCount[] => {
|
||||
const prev = result.find(({ status: prev }) => prev.action === status.action && prev.status === status.status);
|
||||
const prev = result.find(({ status: prev }) =>
|
||||
prev.action === status.action &&
|
||||
prev.status === status.status
|
||||
);
|
||||
|
||||
if (prev) {
|
||||
prev.count++;
|
||||
@ -82,8 +86,13 @@ function extractEvents (result?: SubmittableResult): ActionStatus[] {
|
||||
((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 } }): ActionStatusPartial => {
|
||||
.filter((record) =>
|
||||
!!record.event &&
|
||||
record.event.section !== 'democracy'
|
||||
)
|
||||
.map((record): ActionStatusPartial => {
|
||||
const { event: { data, method, section } } = record;
|
||||
|
||||
if (section === 'system' && method === 'ExtrinsicFailed') {
|
||||
const [dispatchError] = data as unknown as ITuple<[DispatchError]>;
|
||||
let message = dispatchError.type;
|
||||
@ -133,6 +142,12 @@ function extractEvents (result?: SubmittableResult): ActionStatus[] {
|
||||
message: 'contract evicted',
|
||||
status: 'error'
|
||||
};
|
||||
} else if (isIncompleteEvent(record)) {
|
||||
return {
|
||||
action: `${section}.${method}`,
|
||||
message: 'imcomplete execution',
|
||||
status: 'eventWarn'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,7 +213,7 @@ function Queue ({ children }: Props): React.ReactElement<Props> {
|
||||
...(status.map((item): QueueStatus => {
|
||||
const id = ++nextId;
|
||||
const removeItem = (): void =>
|
||||
setStQueue([...stRef.current.filter((item): boolean => item.id !== id)]);
|
||||
setStQueue([...stRef.current.filter((item) => item.id !== id)]);
|
||||
|
||||
setTimeout(removeItem, REMOVE_TIMEOUT);
|
||||
|
||||
@ -265,7 +280,7 @@ function Queue ({ children }: Props): React.ReactElement<Props> {
|
||||
|
||||
if (STATUS_COMPLETE.includes(status)) {
|
||||
setTimeout((): void => {
|
||||
const item = txRef.current.find((item): boolean => item.id === id);
|
||||
const item = txRef.current.find((item) => item.id === id);
|
||||
|
||||
item && item.removeItem();
|
||||
}, REMOVE_TIMEOUT);
|
||||
|
||||
60
packages/react-components/src/Status/checks.ts
Normal file
60
packages/react-components/src/Status/checks.ts
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright 2017-2022 @polkadot/react-components authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Result } from '@polkadot/types';
|
||||
import type { Event, EventRecord } from '@polkadot/types/interfaces';
|
||||
import type { XcmV2TraitsOutcome } from '@polkadot/types/lookup';
|
||||
import type { Codec } from '@polkadot/types/types';
|
||||
|
||||
type EventCheck = (event: Event) => boolean;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
function acceptAll (_: Event): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
function dispatchResult ({ data: [result] }: Event): boolean {
|
||||
return !result || (result as Result<Codec, Codec>).isErr;
|
||||
}
|
||||
|
||||
// [approving, timepoint, multisig, callHash, result]
|
||||
function dispatchResultMulti ({ data: [,,,, result] }: Event): boolean {
|
||||
return !result || (result as Result<Codec, Codec>).isErr;
|
||||
}
|
||||
|
||||
function xcmAttempted ({ data: [outcome] }: Event): boolean {
|
||||
return !outcome || (outcome as XcmV2TraitsOutcome).isIncomplete;
|
||||
}
|
||||
|
||||
const xcmPallet: Record<string, EventCheck> = {
|
||||
Attempted: xcmAttempted
|
||||
};
|
||||
|
||||
const CHECKS: Record<string, Record<string, EventCheck>> = {
|
||||
multisig: {
|
||||
MultisigExecuted: dispatchResultMulti
|
||||
},
|
||||
polkadotXcm: xcmPallet,
|
||||
proxy: {
|
||||
ProxyExecuted: dispatchResult
|
||||
},
|
||||
sudo: {
|
||||
Sudid: dispatchResult,
|
||||
SudoAsDone: dispatchResult
|
||||
},
|
||||
utility: {
|
||||
BatchInterrupted: acceptAll,
|
||||
DispatchedAs: dispatchResult
|
||||
},
|
||||
xcmPallet
|
||||
};
|
||||
|
||||
export function isIncompleteEvent ({ event }: EventRecord): boolean {
|
||||
const { method, section } = event;
|
||||
|
||||
return (
|
||||
!!CHECKS[section] &&
|
||||
!!CHECKS[section][method] &&
|
||||
CHECKS[section][method](event)
|
||||
);
|
||||
}
|
||||
@ -25,6 +25,7 @@ function iconName (status: string): IconName {
|
||||
return 'ban';
|
||||
|
||||
case 'event':
|
||||
case 'eventWarn':
|
||||
return 'assistive-listening-systems';
|
||||
|
||||
case 'received':
|
||||
@ -284,6 +285,10 @@ export default React.memo(styled(Status)`
|
||||
background: teal;
|
||||
}
|
||||
|
||||
&.eventWarn > .wraper > .container {
|
||||
background: orange;
|
||||
}
|
||||
|
||||
&.completed,
|
||||
&.finalized,
|
||||
&.inblock,
|
||||
|
||||
@ -12,7 +12,7 @@ export type Actions = 'create' | 'edit' | 'restore' | 'forget' | 'backup' | 'cha
|
||||
export interface ActionStatusBase {
|
||||
account?: AccountId | Address | string;
|
||||
message?: string;
|
||||
status: 'error' | 'event' | 'queued' | 'received' | 'success';
|
||||
status: 'error' | 'event' | 'eventWarn' | 'queued' | 'received' | 'success';
|
||||
}
|
||||
|
||||
export interface ActionStatusPartial extends ActionStatusBase {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user