Skip to content

Commit 962e711

Browse files
wip
1 parent 1cc8eaa commit 962e711

File tree

4 files changed

+113
-85
lines changed

4 files changed

+113
-85
lines changed

ui/components/app/alert-system/multiple-alert-modal/multiple-alert-modal.test.tsx

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,20 @@ describe('MultipleAlertModal', () => {
159159
expect(onAcknowledgeClickMock).toHaveBeenCalledTimes(1);
160160
});
161161

162-
it('renders the next alert when the "Got it" button is clicked', () => {
163-
const { getByTestId, getByText } = renderWithProvider(
162+
it('does not change the alert when the "Got it" button is clicked', () => {
163+
onAcknowledgeClickMock.mockReset();
164+
const { getByTestId, getByText, queryByText } = renderWithProvider(
164165
<MultipleAlertModal {...defaultProps} alertKey={DATA_ALERT_KEY_MOCK} />,
165166
mockStoreAcknowledgeAlerts,
166167
);
167168

169+
expect(getByText(alertsMock[1].message)).toBeInTheDocument();
170+
168171
fireEvent.click(getByTestId('alert-modal-button'));
169172

173+
expect(onAcknowledgeClickMock).toHaveBeenCalledTimes(1);
170174
expect(getByText(alertsMock[1].message)).toBeInTheDocument();
175+
expect(queryByText(alertsMock[2].message)).not.toBeInTheDocument();
171176
});
172177

173178
it('closes modal when the "Got it" button is clicked', () => {
@@ -186,20 +191,6 @@ describe('MultipleAlertModal', () => {
186191
expect(onAcknowledgeClickMock).toHaveBeenCalledTimes(1);
187192
});
188193

189-
it('resets to the first alert if there are unconfirmed alerts and the final alert is acknowledged', () => {
190-
const { getByTestId, getByText } = renderWithProvider(
191-
<MultipleAlertModal
192-
{...defaultProps}
193-
alertKey={CONTRACT_ALERT_KEY_MOCK}
194-
/>,
195-
mockStore,
196-
);
197-
198-
fireEvent.click(getByTestId('alert-modal-button'));
199-
200-
expect(getByText(alertsMock[0].message)).toBeInTheDocument();
201-
});
202-
203194
describe('FieldAlerts not present', () => {
204195
const alertsMockWithoutField = [
205196
{
@@ -280,7 +271,7 @@ describe('MultipleAlertModal', () => {
280271

281272
fireEvent.click(getByTestId('alert-modal-back-button'));
282273

283-
expect(getByText(alertsMock[1].message)).toBeInTheDocument();
274+
expect(getByText(alertsMock[0].message)).toBeInTheDocument();
284275
});
285276
});
286277

ui/components/app/alert-system/multiple-alert-modal/multiple-alert-modal.tsx

Lines changed: 79 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useCallback, useState } from 'react';
1+
import React, { useCallback, useEffect, useRef, useState } from 'react';
22
import {
33
Box,
44
ButtonIcon,
@@ -12,14 +12,12 @@ import {
1212
BorderRadius,
1313
Display,
1414
IconColor,
15-
Severity,
1615
TextColor,
1716
TextVariant,
1817
} from '../../../../helpers/constants/design-system';
1918
import { useI18nContext } from '../../../../hooks/useI18nContext';
2019
import useAlerts from '../../../../hooks/useAlerts';
2120
import { AlertModal } from '../alert-modal';
22-
import { Alert } from '../../../../ducks/confirm-alerts/confirm-alerts';
2321

2422
export type MultipleAlertModalProps = {
2523
/** The key of the initial alert to display. */
@@ -168,7 +166,6 @@ export function MultipleAlertModal({
168166
const {
169167
alerts: alertsFromHook,
170168
fieldAlerts: fieldAlertsFromHook,
171-
isAlertConfirmed,
172169
navigableAlerts: navigableAlertsFromHook,
173170
navigableFieldAlerts: navigableFieldAlertsFromHook,
174171
} = useAlerts(ownerId);
@@ -192,6 +189,82 @@ export function MultipleAlertModal({
192189
initialAlertKey,
193190
);
194191

192+
const previousAlertKeyRef = useRef<string | undefined>();
193+
const pendingAlertKeyRef = useRef<string | undefined>();
194+
195+
useEffect(() => {
196+
const alertKeyExists = alertKey
197+
? alertsToDisplay.some((alert) => alert.key === alertKey)
198+
: false;
199+
200+
if (alertKey === previousAlertKeyRef.current) {
201+
return;
202+
}
203+
204+
previousAlertKeyRef.current = alertKey;
205+
206+
if (alertKeyExists && alertKey) {
207+
if (alertKey !== currentAlertKey) {
208+
setCurrentAlertKey(alertKey);
209+
}
210+
pendingAlertKeyRef.current = undefined;
211+
} else {
212+
pendingAlertKeyRef.current = alertKey ?? undefined;
213+
}
214+
}, [alertKey, alertsToDisplay, currentAlertKey]);
215+
216+
useEffect(() => {
217+
const pendingAlertKey = pendingAlertKeyRef.current;
218+
219+
if (!pendingAlertKey) {
220+
return;
221+
}
222+
223+
const pendingAlertExists = alertsToDisplay.some(
224+
(alert) => alert.key === pendingAlertKey,
225+
);
226+
227+
if (!pendingAlertExists) {
228+
return;
229+
}
230+
231+
if (pendingAlertKey !== currentAlertKey) {
232+
setCurrentAlertKey(pendingAlertKey);
233+
}
234+
pendingAlertKeyRef.current = undefined;
235+
}, [alertsToDisplay, currentAlertKey]);
236+
237+
useEffect(() => {
238+
const currentAlertStillExists = currentAlertKey
239+
? alertsToDisplay.some((alert) => alert.key === currentAlertKey)
240+
: false;
241+
const alertKeyExists = alertKey
242+
? alertsToDisplay.some((alert) => alert.key === alertKey)
243+
: false;
244+
const pendingAlertKey = pendingAlertKeyRef.current;
245+
const pendingAlertExists = pendingAlertKey
246+
? alertsToDisplay.some((alert) => alert.key === pendingAlertKey)
247+
: false;
248+
249+
if (currentAlertStillExists) {
250+
return;
251+
}
252+
253+
const fallbackKey =
254+
(alertKeyExists && alertKey) ??
255+
(pendingAlertExists && pendingAlertKey) ??
256+
navigableAlertsToDisplay[0]?.key ??
257+
alertsToDisplay[0]?.key;
258+
259+
if (fallbackKey !== currentAlertKey) {
260+
setCurrentAlertKey(fallbackKey);
261+
}
262+
263+
if (pendingAlertExists && fallbackKey === pendingAlertKey) {
264+
pendingAlertKeyRef.current = undefined;
265+
}
266+
}, [alertKey, alertsToDisplay, navigableAlertsToDisplay, currentAlertKey]);
267+
195268
const selectedAlert =
196269
alertsToDisplay.find((alert) => alert.key === currentAlertKey) ??
197270
alertsToDisplay[0];
@@ -200,11 +273,6 @@ export function MultipleAlertModal({
200273
(alert) => alert.key === (selectedAlert?.key ?? currentAlertKey),
201274
);
202275

203-
const hasUnconfirmedAlerts = alerts.some(
204-
(alert: Alert) =>
205-
!isAlertConfirmed(alert.key) && alert.severity === Severity.Danger,
206-
);
207-
208276
const handleBackButtonClick = useCallback(() => {
209277
const activeAlertKey = selectedAlert?.key ?? currentAlertKey;
210278
const newIndex = navigableAlertsToDisplay.findIndex(
@@ -232,58 +300,8 @@ export function MultipleAlertModal({
232300
}, [currentAlertKey, navigableAlertsToDisplay, selectedAlert]);
233301

234302
const handleAcknowledgeClick = useCallback(() => {
235-
const activeAlertKey = selectedAlert?.key ?? currentAlertKey;
236-
const activeAlertHidesNavigation =
237-
selectedAlert?.hideFromAlertNavigation === true;
238-
239-
if (skipAlertNavigation || !activeAlertKey) {
240-
onFinalAcknowledgeClick();
241-
return;
242-
}
243-
244-
if (activeAlertHidesNavigation) {
245-
onFinalAcknowledgeClick();
246-
return;
247-
}
248-
249-
const navigableIndex = navigableAlertsToDisplay.findIndex(
250-
(alert) => alert.key === activeAlertKey,
251-
);
252-
253-
if (navigableIndex === -1) {
254-
onFinalAcknowledgeClick();
255-
return;
256-
}
257-
258-
const isLastNavigableAlert =
259-
navigableIndex === navigableAlertsToDisplay.length - 1;
260-
261-
if (isLastNavigableAlert) {
262-
if (!hasUnconfirmedAlerts) {
263-
onFinalAcknowledgeClick();
264-
return;
265-
}
266-
267-
const firstNavigableKey = navigableAlertsToDisplay[0]?.key;
268-
if (firstNavigableKey) {
269-
setCurrentAlertKey(firstNavigableKey);
270-
}
271-
onFinalAcknowledgeClick();
272-
return;
273-
}
274-
275-
const nextAlertKey = navigableAlertsToDisplay[navigableIndex + 1]?.key;
276-
if (nextAlertKey) {
277-
setCurrentAlertKey(nextAlertKey);
278-
}
279-
}, [
280-
currentAlertKey,
281-
onFinalAcknowledgeClick,
282-
hasUnconfirmedAlerts,
283-
navigableAlertsToDisplay,
284-
selectedAlert,
285-
skipAlertNavigation,
286-
]);
303+
onFinalAcknowledgeClick();
304+
}, [onFinalAcknowledgeClick]);
287305

288306
const showNavigationButtons =
289307
!skipAlertNavigation &&

ui/hooks/useAlerts.test.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,24 @@ describe('useAlerts', () => {
6464
return renderHookUseAlert(ownerId, state).result;
6565
};
6666

67+
const sortBySeverityDesc = (alerts: Alert[]) => {
68+
const severityOrder = {
69+
[Severity.Danger]: 3,
70+
[Severity.Warning]: 2,
71+
[Severity.Info]: 1,
72+
[Severity.Success]: 0,
73+
};
74+
75+
return [...alerts].sort(
76+
(a, b) => severityOrder[b.severity] - severityOrder[a.severity],
77+
);
78+
};
79+
6780
describe('alerts', () => {
6881
it('returns all alerts', () => {
6982
const result = renderAndReturnResult();
70-
expect(result.current.alerts).toEqual(alertsMock);
83+
const expectedAlerts = sortBySeverityDesc(alertsMock);
84+
expect(result.current.alerts).toEqual(expectedAlerts);
7185
expect(result.current.hasAlerts).toEqual(true);
7286
expect(result.current.hasDangerAlerts).toEqual(true);
7387
expect(result.current.hasUnconfirmedDangerAlerts).toEqual(false);
@@ -200,7 +214,10 @@ describe('useAlerts', () => {
200214
},
201215
});
202216

203-
expect(result.current.generalAlerts).toEqual(expectedGeneralAlerts);
217+
const expectedSortedGeneralAlerts = sortBySeverityDesc(
218+
expectedGeneralAlerts,
219+
);
220+
expect(result.current.generalAlerts).toEqual(expectedSortedGeneralAlerts);
204221
});
205222
});
206223

@@ -229,10 +246,12 @@ describe('useAlerts', () => {
229246
describe('fieldAlerts', () => {
230247
it('returns all alerts with field property', () => {
231248
const result = renderAndReturnResult();
232-
expect(result.current.fieldAlerts).toEqual([
233-
alertsMock[0],
234-
alertsMock[2],
235-
]);
249+
const expectedFieldAlerts = sortBySeverityDesc(
250+
[alertsMock[0], alertsMock[2]].filter(
251+
(alert) => typeof alert !== 'undefined',
252+
) as Alert[],
253+
);
254+
expect(result.current.fieldAlerts).toEqual(expectedFieldAlerts);
236255
});
237256

238257
it('returns empty array if no alerts with field property', () => {

ui/hooks/useAlerts.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ function sortAlertsBySeverity(alerts: Alert[]): Alert[] {
129129
[Severity.Success]: 0,
130130
};
131131

132-
return alerts.sort(
132+
return [...alerts].sort(
133133
(a, b) => severityOrder[b.severity] - severityOrder[a.severity],
134134
);
135135
}

0 commit comments

Comments
 (0)