Skip to content

Commit

Permalink
PP-13510: add option to remove non-success events
Browse files Browse the repository at this point in the history
  • Loading branch information
sfount authored and katstevens committed Jan 16, 2025
1 parent f46c03b commit 09815d5
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 12 deletions.
73 changes: 66 additions & 7 deletions browser/src/dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ interface DashboardState {
fetchedServices: boolean,

// move to sync: status property similar to connection rather than top level
sync?: AggregateSyncStatus
sync?: AggregateSyncStatus,
showAllEvents: boolean
}

export interface AggregateSyncStatus {
Expand Down Expand Up @@ -120,7 +121,8 @@ export class Dashboard extends React.Component<DashboardProps, DashboardState> {
},
lastSystemTick: Date.now(),
lastConnectionTick: Date.now(),
fetchedServices: false
fetchedServices: false,
showAllEvents: false
}
this.setWatchObserver = this.setWatchObserver.bind(this)
this.init()
Expand Down Expand Up @@ -375,6 +377,7 @@ export class Dashboard extends React.Component<DashboardProps, DashboardState> {
processQueuedEvents(cursor: number) {
const filtered: Event[] = []
const staging: Event[] = []
const ignored: Event[] = []

const stagingAggregateCompletedVolumes = { ...this.state.aggregateCompletedVolumes }
const stagingAggregateAllVolumes = { ...this.state.aggregateAllVolumes }
Expand Down Expand Up @@ -407,7 +410,14 @@ export class Dashboard extends React.Component<DashboardProps, DashboardState> {
if (eventsErrored.includes(event.event_type)) {
updateStagingGraphNode(stagingTransactionVolumesByHour, event, 0)
}
staging.push(event)

// this line here actually lines up the event to be shown -- if the configuration option is not set to verbose it could only do this for successful events
// once we've processed the event we should make sure it doesn't go into the "filtered" list as it shouldn't be picked back up
if (this.state.showAllEvents || eventsActiveSuccess.includes(event.event_type)) {
staging.push(event)
} else {
ignored.push(event)
}
} else {
filtered.push(event)
}
Expand All @@ -416,7 +426,7 @@ export class Dashboard extends React.Component<DashboardProps, DashboardState> {
}
})

if (staging.length) {
if (staging.length || ignored.length) {
this.setState({
queuedEvents: filtered,
activeEvents: [
Expand All @@ -441,15 +451,21 @@ export class Dashboard extends React.Component<DashboardProps, DashboardState> {
resizeObserver.observe(element)
}

setDisplayOptionEventTicker(e: React.FormEvent<HTMLInputElement>) {
this.setState({
showAllEvents: e.currentTarget.value === "true"
})
}

render() {
const headerStatusColourMap: { [key in ConnectionStatus]?: string } = {
[ConnectionStatus.CONNECTED]: '#1d70b8',
[ConnectionStatus.DISCONNECTED]: '#b1b4b6',
[ConnectionStatus.FAILED]: '#d4351c'
}

return (
<div>

<div className="govuk-grid-row govuk-body govuk-!-margin-bottom-5">
<div className="govuk-grid-column-full">
<header>
Expand Down Expand Up @@ -484,7 +500,7 @@ export class Dashboard extends React.Component<DashboardProps, DashboardState> {
{/* @TODO(sfount) bottom shadow (without factoring in column padding) is needed for parity */}
{/* Non-zero min-height to maintain width without content (a loading or syncing icon should be used) */}
<div style={{ maxHeight: this.state.statsHeight, overflowY: 'hidden', minHeight: 5 }} className="govuk-grid-column-one-half">
<EventListPanel events={this.state.activeEvents} sync={this.state.sync} numberOfAggregateSyncs={this.state.numberOfAggregateSyncs} fetchedServices={this.state.fetchedServices} isFetching={this.state.connection.isFetching} />
<EventListPanel events={this.state.activeEvents} sync={this.state.sync} numberOfAggregateSyncs={this.state.numberOfAggregateSyncs} fetchedServices={this.state.fetchedServices} isFetching={this.state.connection.isFetching} showAllEvents={this.state.showAllEvents} />
</div>
<div className="govuk-grid-column-one-half">
<StatsPanel
Expand All @@ -494,7 +510,7 @@ export class Dashboard extends React.Component<DashboardProps, DashboardState> {
/>
</div>
</div>
<div className="govuk-grid-row">
<div className="govuk-grid-row govuk-!-margin-bottom-4">
<div className="govuk-grid-column-full">
<ChartVolumePanel
data={this.state.transactionVolumesByHour}
Expand All @@ -504,6 +520,49 @@ export class Dashboard extends React.Component<DashboardProps, DashboardState> {
/>
</div>
</div>
<div className="govuk-grid-row">
<div className="govuk-grid-column-full govuk-body">
<details className="govuk-details" data-module="govuk-details">
<summary className="govuk-details__summary">
<span className="govuk-details__summary-text">
Display options
</span>
</summary>
<div className="govuk-details__text">
<div className="govuk-form-group">
<fieldset className="govuk-fieldset">
<legend className="govuk-fieldset__legend govuk-fieldset__legend--m">
<h1 className="govuk-fieldset__heading">
Live payment events feed
</h1>
</legend>
<div className="govuk-radios govuk-radios--small" data-module="govuk-radios">
<div className="govuk-radios__item">
<input className="govuk-radios__input" id="changed-name" name="changed-name" type="radio" value="false" checked={ !this.state.showAllEvents } onChange={ this.setDisplayOptionEventTicker.bind(this) }></input>
<label className="govuk-label govuk-radios__label">
Only show payment succeeded events
</label>
<div id="sign-in-item-hint" className="govuk-hint govuk-radios__hint">
Show a card in the events feed when a payment has been successfully processed.
</div>
</div>
<div className="govuk-radios__item">
<input className="govuk-radios__input" id="changed-name-2" name="changed-name" type="radio" value="true" checked={ this.state.showAllEvents } onChange={ this.setDisplayOptionEventTicker.bind(this) }></input>
<label className="govuk-label govuk-radios__label">
Show all events
</label>
<div id="sign-in-item-hint-two" className="govuk-hint govuk-radios__hint">
Show cards for all payments events including when payments are created, when card details are provided and when a payment has been successfully processed.
</div>

</div>
</div>
</fieldset>
</div>
</div>
</details>
</div>
</div>
</div>
)
}
Expand Down
9 changes: 6 additions & 3 deletions browser/src/dashboard/EventCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,21 @@ const profileMap: { [key: string]: CardProfile } = {
}

interface EventCardProps {
event: Event
event: Event,
showAllEvents: boolean
}

export class EventCard extends React.Component<EventCardProps, {}> {
render() {
const profile = profileMap[this.props.event.event_type] || DefaultProfile
const profile = this.props.showAllEvents ? (profileMap[this.props.event.event_type] || DefaultProfile) : DefaultProfile
const paymentTypeIcon = paymentTypeMap[this.props.event.card_brand] || UnknownIcon
const paymentProviderIcon = providerLogoMap[this.props.event.payment_provider]

let statusIcon: string

if (this.props.event.event_type === 'PAYMENT_DETAILS_ENTERED') {
if (!this.props.showAllEvents) {
statusIcon = paymentTypeIcon
} else if (this.props.event.event_type === 'PAYMENT_DETAILS_ENTERED') {
statusIcon = paymentTypeIcon
} else if (eventsActiveSuccess.includes(this.props.event.event_type)) {
statusIcon = StatusSuccessIcon
Expand Down
5 changes: 3 additions & 2 deletions browser/src/dashboard/EventListPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ interface EventListPanelProps {
numberOfAggregateSyncs: number,
events: Event[],
fetchedServices: boolean,
isFetching: boolean
isFetching: boolean,
showAllEvents: boolean
}

function LoadingCard(props: any): JSX.Element {
Expand All @@ -23,7 +24,7 @@ function LoadingCard(props: any): JSX.Element {
export class EventListPanel extends React.Component<EventListPanelProps, {}> {
render() {
let syncStatus
const events = this.props.events.map((event, index) => <EventCard key={event.key} event={event} />)
const events = this.props.events.map((event, index) => <EventCard key={event.key} event={event} showAllEvents={this.props.showAllEvents} />)

if(this.props.sync && this.props.sync.pending && this.props.numberOfAggregateSyncs <= 1) {
syncStatus = <LoadingCard>Sync</LoadingCard>
Expand Down
7 changes: 7 additions & 0 deletions browser/src/dashboard/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ const eventsSuccess = [

// only include the first salient successful event - this will mitigate background processes capturing old payments from
// impacting optimistic numbers

// notes: ideally user approved for capture await service approval would show up on the events feed and "service approved for capture" would change the stats
// there's an existing behaviour

// (note notes) if we've increased the aggregate amounts for the "awaiting service approval" event we _shouldn't_ then update it for the service approved for capture, if we haven't then we should but shouldn't show it(?)

// this should probably be done as a separate PR, we have similar mechanisms to avoid double counting it can just updated for this scenario
export const eventsActiveSuccess = [
'USER_APPROVED_FOR_CAPTURE_AWAITING_SERVICE_APPROVAL',
'USER_APPROVED_FOR_CAPTURE',
Expand Down

0 comments on commit 09815d5

Please sign in to comment.