Skip to content

Commit c385f02

Browse files
authored
feat: 2262 fix for export data (#2279)
1 parent d6016d7 commit c385f02

File tree

3 files changed

+76
-47
lines changed

3 files changed

+76
-47
lines changed

frontend/src/views/CONSEP/TestingActivities/TestSearch/constants.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,10 @@ export const testRanks: string[] = [
8282
'A', 'B', 'C', 'P'
8383
];
8484

85-
const getResultValue = (row: TestingSearchResponseType) => {
85+
const getResultValue = (
86+
row: TestingSearchResponseType,
87+
defaultValue: string | number | null = null
88+
) => {
8689
if (row.activityId && row.activityId.startsWith('M')) {
8790
return row.moisturePct;
8891
}
@@ -94,7 +97,7 @@ const getResultValue = (row: TestingSearchResponseType) => {
9497
case 'PUR':
9598
return row.purityPct;
9699
default:
97-
return null;
100+
return defaultValue;
98101
}
99102
};
100103

@@ -317,7 +320,7 @@ export const formatExportData = {
317320
},
318321
Result: {
319322
header: 'Result',
320-
value: (row: TestingSearchResponseType) => getResultValue(row)
323+
value: (row: TestingSearchResponseType) => getResultValue(row, '')
321324
},
322325
pv: {
323326
header: 'PV',

frontend/src/views/CONSEP/TestingActivities/TestSearch/definitions.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,13 @@ export type Sorting = {
4646
id: string;
4747
desc: boolean;
4848
};
49+
50+
export interface ExportMutationVariables {
51+
filter: ActivitySearchRequest;
52+
sortBy?: string;
53+
sortDirection?: 'asc' | 'desc';
54+
}
55+
56+
export interface VisibilityConfig {
57+
[key: string]: boolean;
58+
}

frontend/src/views/CONSEP/TestingActivities/TestSearch/index.tsx

Lines changed: 60 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,13 @@ import {
4141
formatExportData, columnVisibilityLocalStorageKey
4242
} from './constants';
4343
import { THREE_HALF_HOURS, THREE_HOURS } from '../../../../config/TimeUnits';
44-
import { ActivitySearchRequest, ActivitySearchValidation, Sorting } from './definitions';
44+
import {
45+
ActivitySearchRequest,
46+
ActivitySearchValidation,
47+
Sorting,
48+
ExportMutationVariables,
49+
VisibilityConfig
50+
} from './definitions';
4551
import './styles.scss';
4652

4753
const csvConfig = mkConfig({
@@ -114,64 +120,69 @@ const TestSearch = () => {
114120
pageSize: data.pageSize
115121
});
116122
},
117-
onError: (error) => {
123+
onError: (error: unknown) => {
124+
let errorMessage = 'Search failed.';
125+
if (error instanceof Error && error.message) {
126+
errorMessage = `Search failed with the error: ${error.message}`;
127+
} else if (typeof error === 'string') {
128+
errorMessage = `Search failed with the error: ${error}`;
129+
}
118130
setAlert({
119131
status: 'error',
120-
message: `Search failed with the error: ${error.message}`
132+
message: errorMessage
121133
});
122134
}
123135
});
124136

125137
const exportMutation = useMutation({
126-
mutationFn: (filter:
127-
ActivitySearchRequest) => searchTestingActivities(filter, undefined, undefined, true, 0, 0),
138+
mutationFn: ({
139+
filter,
140+
sortBy,
141+
sortDirection
142+
}: ExportMutationVariables) => searchTestingActivities(
143+
filter,
144+
sortBy,
145+
sortDirection,
146+
true,
147+
0,
148+
0
149+
),
128150

129-
onSuccess: (data) => {
130-
const visibilityConfig = JSON.parse(
151+
onSuccess: (data: PaginatedTestingSearchResponseType) => {
152+
const visibilityConfig: VisibilityConfig = JSON.parse(
131153
localStorage.getItem(columnVisibilityLocalStorageKey) || '{}'
132154
);
133155

134156
const isVisible = (key: string) => visibilityConfig[key] !== false;
135157

136-
type FilteredRow = Record<
137-
keyof TestingSearchResponseType,
138-
TestingSearchResponseType[keyof TestingSearchResponseType] | undefined
139-
>;
140-
141-
const filterItem = (item: TestingSearchResponseType): FilteredRow => Object
142-
.keys(item).reduce((acc, key) => {
143-
if (!isVisible(key)) return acc;
144-
if (!Object.hasOwnProperty.call(formatExportData, key)) return acc;
145-
146-
const k = key as keyof TestingSearchResponseType;
147-
acc[k] = item[k];
148-
return acc;
149-
}, {} as FilteredRow);
150-
151-
const formatItem = (item: FilteredRow) => Object.entries(item).reduce((acc, [key]) => {
152-
const config = formatExportData[key as keyof typeof formatExportData];
153-
154-
if (config) {
155-
acc[config.header] = config.value(item as TestingSearchResponseType);
156-
}
157-
158-
if (key === 'Result') {
159-
acc.Result = formatExportData.Result.value(item as TestingSearchResponseType);
160-
}
161-
162-
return acc;
163-
}, {} as Record<string, any>);
164-
165-
const filteredContent: FilteredRow[] = data.content.map(filterItem);
166-
const formattedContent = filteredContent.map(formatItem);
158+
const formattedContent = data.content.map(
159+
(row: TestingSearchResponseType) => {
160+
const out: Record<string, string | number | null> = {};
161+
(
162+
Object.entries(formatExportData) as Array<
163+
[
164+
keyof typeof formatExportData,
165+
(typeof formatExportData)[keyof typeof formatExportData]
166+
]
167+
>
168+
).forEach(([key, cfg]) => {
169+
if (!isVisible(String(key))) return;
170+
out[cfg.header] = cfg.value(row);
171+
});
172+
return out;
173+
}
174+
);
167175

168-
const csv = generateCsv(csvConfig)(formattedContent);
169-
download(csvConfig)(csv);
176+
const csv = generateCsv(csvConfig)(formattedContent);
177+
download(csvConfig)(csv);
170178
},
171-
onError: (error) => {
179+
onError: (error: unknown) => {
180+
const message = error instanceof Error && error.message
181+
? error.message
182+
: 'Unknown error';
172183
setAlert({
173184
status: 'error',
174-
message: `Failed to export data: ${error?.message || 'Unknown error'}`
185+
message: `Failed to export data: ${message}`
175186
});
176187
}
177188
});
@@ -190,7 +201,12 @@ const TestSearch = () => {
190201
};
191202

192203
const handleExportData = () => {
193-
exportMutation.mutate(searchParams);
204+
const sort = sorting[0];
205+
exportMutation.mutate({
206+
filter: searchParams,
207+
sortBy: sort?.id,
208+
sortDirection: sort?.desc ? 'desc' : 'asc'
209+
});
194210
};
195211

196212
const testTypeQuery = useQuery({
@@ -221,7 +237,7 @@ const TestSearch = () => {
221237
sortDirection: sort?.desc ? 'desc' : 'asc'
222238
},
223239
{
224-
onSuccess: (data) => {
240+
onSuccess: (data: PaginatedTestingSearchResponseType) => {
225241
setSearchResults(data.content);
226242
setPaginationInfo({
227243
totalElements: data.totalElements,

0 commit comments

Comments
 (0)