From 573a500cdde71aa602b78e8145239f26cf278a5b Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Mon, 13 May 2019 16:45:56 +0200 Subject: [PATCH] Fix event display indexing & availability (#1144) * Fix event display indexing & availability * Key events by when-added key * BlockInfo passes KeyedEvent --- .../app-explorer/src/BlockInfo/Events.tsx | 6 +- packages/app-explorer/src/Events.tsx | 84 ++++++++----------- packages/app-explorer/src/EventsRecent.tsx | 70 ---------------- packages/app-explorer/src/Main.tsx | 11 ++- packages/app-explorer/src/index.tsx | 58 +++++++++++-- packages/app-explorer/src/types.ts | 10 +++ 6 files changed, 109 insertions(+), 130 deletions(-) delete mode 100644 packages/app-explorer/src/EventsRecent.tsx create mode 100644 packages/app-explorer/src/types.ts diff --git a/packages/app-explorer/src/BlockInfo/Events.tsx b/packages/app-explorer/src/BlockInfo/Events.tsx index d77d4e23ba..c853e158fa 100644 --- a/packages/app-explorer/src/BlockInfo/Events.tsx +++ b/packages/app-explorer/src/BlockInfo/Events.tsx @@ -22,13 +22,17 @@ class Events extends React.PureComponent { return null; } + const events = value.map((record, index) => ({ + key: `${index}`, record + })); + return (

{t('events')}

diff --git a/packages/app-explorer/src/Events.tsx b/packages/app-explorer/src/Events.tsx index 567f2c1d44..1bca2b39b3 100644 --- a/packages/app-explorer/src/Events.tsx +++ b/packages/app-explorer/src/Events.tsx @@ -3,49 +3,34 @@ // of the Apache-2.0 license. See the LICENSE file for details. import { I18nProps } from '@polkadot/ui-app/types'; +import { KeyedEvent } from './types'; import React from 'react'; -import { EventRecord } from '@polkadot/types'; import { Event as EventDisplay } from '@polkadot/ui-app'; import { formatNumber } from '@polkadot/util'; import translate from './translate'; type Props = I18nProps & { - value?: Array, emptyLabel?: React.ReactNode, + events: Array, eventClassName?: string, withoutIndex?: boolean }; class Events extends React.PureComponent { render () { - const { emptyLabel, eventClassName, value, t } = this.props; + const { emptyLabel, events, t } = this.props; - if (!value || value.length === 0) { + if (!events || events.length === 0) { return emptyLabel || t('no events available'); } - return value - .filter(({ event }) => event) // event.section !== 'system') - .map((event, index) => { - const rendered = this.renderEvent(event, index); - - return eventClassName - ? ( -
- {rendered} -
- ) - : rendered; - }); + return events.map(this.renderEvent); } - private renderEvent = ({ event, phase }: EventRecord, index: number) => { - const { withoutIndex } = this.props; + private renderEvent = ({ key, record: { event, phase } }: KeyedEvent) => { + const { eventClassName, withoutIndex } = this.props; const extIndex = !withoutIndex && phase.type === 'ApplyExtrinsic' ? phase.asApplyExtrinsic : -1; @@ -55,34 +40,35 @@ class Events extends React.PureComponent { } return ( -
-
-

- {event.section}.{event.method} { - extIndex !== -1 - ? `(#${formatNumber(extIndex)})` - : '' - } -

- -
-
- - { - event.meta && event.meta.documentation - ? event.meta.documentation.join(' ') - : 'Details' - } - - -
-
+
+
+

+ {event.section}.{event.method} { + extIndex !== -1 + ? `(#${formatNumber(extIndex)})` + : '' + } +

+
+
+ + { + event.meta && event.meta.documentation + ? event.meta.documentation.join(' ') + : 'Details' + } + + +
+
+ ); } } diff --git a/packages/app-explorer/src/EventsRecent.tsx b/packages/app-explorer/src/EventsRecent.tsx deleted file mode 100644 index e1b6b7f279..0000000000 --- a/packages/app-explorer/src/EventsRecent.tsx +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2017-2019 @polkadot/app-explorer 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 { I18nProps } from '@polkadot/ui-app/types'; - -import React from 'react'; -import { EventRecord } from '@polkadot/types'; -import { withCalls, withMulti } from '@polkadot/ui-api'; -import { stringToU8a } from '@polkadot/util'; -import { xxhashAsHex } from '@polkadot/util-crypto'; - -import { MAX_ITEMS } from './BlockHeaders'; -import Events from './Events'; -import translate from './translate'; - -type Props = I18nProps & { - system_events?: Array -}; - -type State = { - prevEventHash: string; - recentEvents: Array; -}; - -class EventsRecent extends React.PureComponent { - state: State = { - prevEventHash: '', - recentEvents: [] - }; - - static getDerivedStateFromProps ({ system_events = [] }: Props, prevState: State): State | null { - const prevEventHash = xxhashAsHex(stringToU8a(JSON.stringify(system_events))); - - if (prevEventHash === prevState.prevEventHash) { - return null; - } - - const recentEvents = system_events - .filter(({ event }) => event.section !== 'system') - .concat(prevState.recentEvents) - .filter((_, index) => index < MAX_ITEMS); - - return { - prevEventHash, - recentEvents - }; - } - - render () { - const { t } = this.props; - const { recentEvents } = this.state; - - return ( -
- -
- ); - } -} - -export default withMulti( - EventsRecent, - translate, - withCalls('query.system.events') -); diff --git a/packages/app-explorer/src/Main.tsx b/packages/app-explorer/src/Main.tsx index 8f46662eda..0acd0f6f50 100644 --- a/packages/app-explorer/src/Main.tsx +++ b/packages/app-explorer/src/Main.tsx @@ -3,20 +3,23 @@ // of the Apache-2.0 license. See the LICENSE file for details. import { I18nProps } from '@polkadot/ui-app/types'; +import { KeyedEvent } from './types'; import React from 'react'; import BlockHeaders from './BlockHeaders'; -import EventsRecent from './EventsRecent'; +import Events from './Events'; import Query from './Query'; import Summary from './Summary'; import translate from './translate'; -type Props = I18nProps & {}; +type Props = I18nProps & { + events: Array +}; class Main extends React.PureComponent { render () { - const { t } = this.props; + const { events, t } = this.props; return ( <> @@ -29,7 +32,7 @@ class Main extends React.PureComponent {

{t('recent events')}

- +
diff --git a/packages/app-explorer/src/index.tsx b/packages/app-explorer/src/index.tsx index 79bd01d24f..cba595c610 100644 --- a/packages/app-explorer/src/index.tsx +++ b/packages/app-explorer/src/index.tsx @@ -3,23 +3,33 @@ // of the Apache-2.0 license. See the LICENSE file for details. import { AppProps, BareProps, I18nProps } from '@polkadot/ui-app/types'; +import { KeyedEvent } from './types'; import './index.css'; import React from 'react'; import { Route, Switch } from 'react-router'; +import { EventRecord } from '@polkadot/types'; +import { withCalls, withMulti } from '@polkadot/ui-api'; import Tabs, { TabItem } from '@polkadot/ui-app/Tabs'; import uiSettings from '@polkadot/ui-settings'; -import translate from './translate'; +import { stringToU8a } from '@polkadot/util'; +import { xxhashAsHex } from '@polkadot/util-crypto'; +import { MAX_ITEMS } from './BlockHeaders'; import BlockInfo from './BlockInfo'; import Main from './Main'; import NodeInfo from './NodeInfo'; +import translate from './translate'; -type Props = AppProps & BareProps & I18nProps; +type Props = AppProps & BareProps & I18nProps & { + system_events?: Array +}; type State = { - items: Array + items: Array, + prevEventHash: string; + recentEvents: Array; }; class ExplorerApp extends React.Component { @@ -43,7 +53,31 @@ class ExplorerApp extends React.Component { name: 'node', text: t('Node info') } - ] + ], + prevEventHash: '', + recentEvents: [] + }; + } + + // assign the events on the index - this way we keep a record of these, even when swapping + // tabs withing this app, all the events as received will be shown + static getDerivedStateFromProps ({ system_events = [] }: Props, prevState: State): State | null { + const prevEventHash = xxhashAsHex(stringToU8a(JSON.stringify(system_events))); + + if (prevEventHash === prevState.prevEventHash) { + return null; + } + + const recentEvents = system_events + .filter(({ event }) => event.section !== 'system') + .map((record, index) => ({ key: `${Date.now()}-${index}`, record })) + .concat(prevState.recentEvents) + .filter((_, index) => index < MAX_ITEMS); + + return { + items: prevState.items, + prevEventHash, + recentEvents }; } @@ -67,11 +101,23 @@ class ExplorerApp extends React.Component { - + ); } + + private renderMain = () => { + const { recentEvents } = this.state; + + return ( +
+ ); + } } -export default translate(ExplorerApp); +export default withMulti( + ExplorerApp, + translate, + withCalls('query.system.events') +); diff --git a/packages/app-explorer/src/types.ts b/packages/app-explorer/src/types.ts new file mode 100644 index 0000000000..aee3b06800 --- /dev/null +++ b/packages/app-explorer/src/types.ts @@ -0,0 +1,10 @@ +// Copyright 2017-2019 @polkadot/app-explorer 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 { EventRecord } from '@polkadot/types'; + +export type KeyedEvent = { + key: string, + record: EventRecord +};