Skip to content

Commit 6dcbeef

Browse files
committed
Fix default behavior for surge tables
- Add event and country filter to all surge alerts - Improve styling of readiness section in surge overview
1 parent 77c804b commit 6dcbeef

File tree

14 files changed

+178
-90
lines changed

14 files changed

+178
-90
lines changed

src/components/Table/ColumnShortcuts/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ export function createDateColumn<D, K>(
244244
} = {
245245
id,
246246
title,
247-
columnClassName: options?.columnClassName,
247+
columnClassName: _cs(options?.columnClassName, styles.dateColumn),
248248
headerCellRenderer: HeaderCell,
249249
headerCellRendererClassName: options?.headerCellRendererClassName,
250250
headerContainerClassName: options?.headerContainerClassName,

src/components/Table/ColumnShortcuts/styles.module.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,8 @@
99
.timeline-cell-container {
1010
position: relative;
1111
}
12+
13+
.date-column {
14+
width: 0%;
15+
min-width: 7rem;
16+
}

src/views/AllSurgeAlerts/i18n.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
"strings": {
44
"allSurgeAlertsTitle": "All Surge Alerts",
55
"allSurgeAlertsHeading": "All Surge Alerts ({numSurgeAlerts})",
6+
"eventFilterLabel": "Emergency",
7+
"countryFilterLabel": "Country",
8+
"defaultPlaceholder": "All",
69
"failedToCreateExport": "Failed to generate export.",
710
"surgeAlertDate": "Alert Date",
811
"surgeAlertDuration": "Duration",

src/views/AllSurgeAlerts/index.tsx

Lines changed: 105 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useMemo, useCallback } from 'react';
1+
import { useMemo, useCallback, useState } from 'react';
22
import { isDefined, isNotDefined } from '@togglecorp/fujs';
33
import Papa from 'papaparse';
44
import { saveAs } from 'file-saver';
@@ -13,6 +13,8 @@ import {
1313
createDateColumn,
1414
createLinkColumn,
1515
} from '#components/Table/ColumnShortcuts';
16+
import NumberOutput from '#components/NumberOutput';
17+
import EventSearchSelectInput from '#components/domain/EventSearchSelectInput';
1618
import useTranslation from '#hooks/useTranslation';
1719
import useFilterState from '#hooks/useFilterState';
1820
import { useRequest, type GoApiResponse } from '#utils/restRequest';
@@ -21,15 +23,20 @@ import useAlert from '#hooks/useAlert';
2123
import useRecursiveCsvExport from '#hooks/useRecursiveCsvRequest';
2224
import { numericIdSelector } from '#utils/selectors';
2325
import { getDuration } from '#utils/common';
26+
import CountrySelectInput from '#components/domain/CountrySelectInput';
27+
import useUrlSearchState from '#hooks/useUrlSearchState';
2428

2529
import i18n from './i18n.json';
2630
import styles from './styles.module.css';
2731

2832
type SurgeResponse = GoApiResponse<'/api/v2/surge_alert/'>;
2933
type SurgeListItem = NonNullable<SurgeResponse['results']>[number];
3034

35+
type GetEventResponse = GoApiResponse<'/api/v2/event/mini/'>;
36+
export type EventItem = Pick<NonNullable<GetEventResponse['results']>[number], 'id' | 'name' | 'dtype'>;
37+
3138
type TableKey = number;
32-
const today = new Date().getTime();
39+
const nowTimestamp = new Date().getTime();
3340

3441
function getPositionString(alert: SurgeListItem) {
3542
if (isNotDefined(alert.molnix_id)) {
@@ -60,6 +67,68 @@ export function Component() {
6067
pageSize: 15,
6168
});
6269

70+
const [countryFilter, setCountryFilter] = useUrlSearchState<number | undefined>(
71+
'country',
72+
(searchValue) => {
73+
const potentialValue = isDefined(searchValue) ? Number(searchValue) : undefined;
74+
return potentialValue;
75+
},
76+
(country) => country,
77+
);
78+
79+
const [eventFilter, setEventFilter] = useUrlSearchState<number | undefined>(
80+
'event',
81+
(searchValue) => {
82+
const potentialValue = isDefined(searchValue) ? Number(searchValue) : undefined;
83+
return potentialValue;
84+
},
85+
(country) => country,
86+
);
87+
88+
const [eventOptions, setEventOptions] = useState<
89+
EventItem[] | undefined | null
90+
>([]);
91+
92+
useRequest({
93+
skip: isNotDefined(eventFilter)
94+
|| (!!eventOptions?.find((event) => event.id === eventFilter)),
95+
url: '/api/v2/event/{id}/',
96+
pathVariables: isDefined(eventFilter) ? {
97+
id: eventFilter,
98+
} : undefined,
99+
onSuccess: (response) => {
100+
if (isNotDefined(response)) {
101+
return;
102+
}
103+
104+
const {
105+
id,
106+
dtype,
107+
name,
108+
} = response;
109+
110+
if (isNotDefined(id) || isNotDefined(dtype) || isNotDefined(name)) {
111+
return;
112+
}
113+
114+
const newOption = {
115+
id,
116+
dtype: {
117+
id: dtype,
118+
translation_module_original_language: 'en' as const,
119+
name: undefined,
120+
summary: undefined,
121+
},
122+
name,
123+
};
124+
125+
setEventOptions((prevOptions) => ([
126+
...prevOptions ?? [],
127+
newOption,
128+
]));
129+
},
130+
});
131+
63132
const {
64133
response: surgeResponse,
65134
pending: surgeResponsePending,
@@ -69,6 +138,8 @@ export function Component() {
69138
query: {
70139
limit,
71140
offset,
141+
event: eventFilter,
142+
country: countryFilter,
72143
},
73144
});
74145

@@ -78,8 +149,14 @@ export function Component() {
78149
if (surgeAlert.is_stood_down) {
79150
return strings.surgeAlertStoodDown;
80151
}
81-
const closed = isDefined(surgeAlert.end)
82-
? new Date(surgeAlert.end).getTime() < today : undefined;
152+
const endDate = isDefined(surgeAlert.end)
153+
? new Date(surgeAlert.end)
154+
: undefined;
155+
156+
const closed = isDefined(endDate)
157+
? endDate.getTime() < nowTimestamp
158+
: false;
159+
83160
return closed ? strings.surgeAlertClosed : strings.surgeAlertOpen;
84161
},
85162
[
@@ -216,7 +293,7 @@ export function Component() {
216293

217294
const heading = resolveToComponent(
218295
strings.allSurgeAlertsHeading,
219-
{ numSurgeAlerts: surgeResponse?.count ?? '--' },
296+
{ numSurgeAlerts: <NumberOutput value={surgeResponse?.count} invalidText="--" /> },
220297
);
221298

222299
return (
@@ -226,6 +303,29 @@ export function Component() {
226303
heading={heading}
227304
>
228305
<Container
306+
withHeaderBorder
307+
withGridViewInFilter
308+
filters={(
309+
<>
310+
<CountrySelectInput
311+
name="country"
312+
label={strings.countryFilterLabel}
313+
placeholder={strings.defaultPlaceholder}
314+
value={countryFilter}
315+
onChange={setCountryFilter}
316+
/>
317+
<EventSearchSelectInput
318+
name="event"
319+
label={strings.eventFilterLabel}
320+
placeholder={strings.defaultPlaceholder}
321+
value={eventFilter}
322+
onChange={setEventFilter}
323+
options={eventOptions}
324+
onOptionsChange={setEventOptions}
325+
countryId={countryFilter}
326+
/>
327+
</>
328+
)}
229329
footerActions={(
230330
<Pager
231331
activePage={page}

src/views/EmergencySurge/SurgeTable/i18n.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"surgeAlertOpen": "Open",
1414
"surgeAlertClosed": "Closed",
1515
"surgeAlertStoodDown": "Stood down",
16-
"surgeAlertsViewAll": "View All Surge Alerts",
16+
"surgeAlertsViewAllForCurrentEmergency": "View all Surge Alerts for this Emergency",
1717
"emergencySurgeImmediately": "Immediately"
1818
}
1919
}

src/views/EmergencySurge/SurgeTable/index.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ import i18n from './i18n.json';
2222

2323
type SurgeResponse = GoApiResponse<'/api/v2/surge_alert/'>;
2424
type SurgeListItem = NonNullable<SurgeResponse['results']>[number];
25-
const today = new Date().getTime();
25+
const now = new Date();
26+
const nowTimestamp = now.getTime();
2627

2728
function getPositionString(alert: SurgeListItem) {
2829
if (isNotDefined(alert.molnix_id)) {
@@ -66,6 +67,10 @@ export default function SurgeTable(props: Props) {
6667
event: Number(emergencyId),
6768
limit,
6869
offset,
70+
71+
// NOTE: following filters are required
72+
is_active: true,
73+
end__gte: now.toISOString(),
6974
},
7075
});
7176

@@ -74,7 +79,9 @@ export default function SurgeTable(props: Props) {
7479
if (alert.is_stood_down) {
7580
return strings.surgeAlertStoodDown;
7681
}
77-
const closed = isDefined(alert.end) ? new Date(alert.end).getTime() < today : undefined;
82+
const closed = isDefined(alert.end)
83+
? new Date(alert.end).getTime() < nowTimestamp
84+
: undefined;
7885
return closed ? strings.surgeAlertClosed : strings.surgeAlertOpen;
7986
},
8087
[
@@ -188,8 +195,9 @@ export default function SurgeTable(props: Props) {
188195
to="allSurgeAlerts"
189196
withLinkIcon
190197
withUnderline
198+
urlSearch={isDefined(emergencyId) ? `event=${emergencyId}` : undefined}
191199
>
192-
{strings.surgeAlertsViewAll}
200+
{strings.surgeAlertsViewAllForCurrentEmergency}
193201
</Link>
194202
)}
195203
footerActions={(

src/views/SurgeOverview/PersonnelByEventTable/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function PersonnelByEventTable() {
3232
offset,
3333
} = useFilterState<object>({
3434
filter: {},
35-
pageSize: 25,
35+
pageSize: 6,
3636
});
3737

3838
const strings = useTranslation(i18n);

src/views/SurgeOverview/Readiness/EmergencyResponseUnitOwnerCard/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ function EmergencyResponseUnitOwnerCard(props: Props) {
7171
className={_cs(styles.emergencyResponseUnitOwnerCard, className)}
7272
withInternalPadding
7373
withHeaderBorder
74-
spacing="comfortable"
74+
spacing="default"
7575
heading={(
7676
<Link
7777
to="countriesLayout"

src/views/SurgeOverview/Readiness/EmergencyResponseUnitOwnerCard/styles.module.css

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313

1414
.separator {
1515
flex-shrink: 0;
16-
background-color: var(--go-ui-color-separator);
17-
width: var(--go-ui-width-separator-sm);
16+
border-left: var(--go-ui-width-separator-sm) solid var(--go-ui-color-separator);
1817
}
1918

2019
.figure {
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
{
22
"namespace": "surgeOverview",
33
"strings": {
4-
"eruOwnersTableHeading": "National Societies",
5-
"eruOwnersTableFilterReady": "Filter Ready ERUs",
4+
"readinessTitle": "Ready ERUs by National Society ({count})",
65
"eruOwnersTableFilterClear": "Reset Filters"
76
}
87
}

0 commit comments

Comments
 (0)