Skip to content

Commit 9a84b89

Browse files
feat: 1887 purity screen activity results table returning user (#2015)
Co-authored-by: DustyD <xiao_peng0202@hotmail.com>
1 parent e728e8a commit 9a84b89

File tree

29 files changed

+735
-566
lines changed

29 files changed

+735
-566
lines changed

frontend/src/api-service/ApiConfig.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ const ApiConfig = {
5959

6060
seedlotFromOracleDbBySeedlotNumber: `${oracleServerHost}/api/seedlot/{seedlotNumber}`,
6161

62-
moistureContent: `${oracleServerHost}/api/moisture-content-cone`
62+
moistureContent: `${oracleServerHost}/api/moisture-content-cone`,
63+
64+
purityTest: `${oracleServerHost}/api/purity-tests`
6365
};
6466

6567
export default ApiConfig;

frontend/src/api-service/moistureContentAPI.ts

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,5 @@
11
import ApiConfig from './ApiConfig';
22
import api from './api';
3-
import { ReplicateType } from '../types/consep/TestingActivityType';
4-
5-
export const getMccByRiaKey = (riaKey: string) => {
6-
const url = `${ApiConfig.moistureContent}/${riaKey}`;
7-
return api.get(url).then((res) => res.data);
8-
};
9-
10-
export const updateReplicates = (riaKey: number, replicates: ReplicateType[]) => {
11-
const url = `${ApiConfig.moistureContent}/replicate/${riaKey}`;
12-
return api.patch(url, replicates);
13-
};
14-
15-
export const deleteReplicate = (riaKey: number, replicateNumber: number) => {
16-
const url = `${ApiConfig.moistureContent}/${riaKey}/${replicateNumber}`;
17-
return api.delete(url);
18-
};
19-
20-
export const deleteReplicates = (riaKey: number, replicateNumbers: number[]) => {
21-
const url = `${ApiConfig.moistureContent}/${riaKey}/replicates`;
22-
return api.post(url, replicateNumbers);
23-
};
24-
25-
export const updateActivityRecord = (riaKey: number, activityRecord: any) => {
26-
const url = `${ApiConfig.moistureContent}/${riaKey}`;
27-
return api.patch(url, activityRecord);
28-
};
29-
30-
export const validateResult = (riaKey: string) => {
31-
const url = `${ApiConfig.moistureContent}/validate/${riaKey}`;
32-
return api.get(url);
33-
};
34-
35-
export const acceptResult = (riaKey: string) => {
36-
const url = `${ApiConfig.moistureContent}/accept/${riaKey}`;
37-
return api.get(url);
38-
};
393

404
export const calculateAverage = (riaKey: string, mcValues: number[]) => {
415
const url = `${ApiConfig.moistureContent}/${riaKey}/calculate-average`;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import ApiConfig from './ApiConfig';
2+
import api from './api';
3+
import { ReplicateType, TestingTypes } from '../types/consep/TestingActivityType';
4+
5+
type TestingParams = Record<string, any>;
6+
7+
type TestingActivitiesApiType =
8+
| 'getDataByRiaKey'
9+
| 'updateMultipleReplicates'
10+
| 'deleteSingleReplicate'
11+
| 'deleteMultipleReplicates'
12+
| 'updateActivityRecord'
13+
| 'validateTestResult'
14+
| 'acceptResult';
15+
16+
const testingActivitiesAPI = async (
17+
testType: TestingTypes,
18+
fn: TestingActivitiesApiType,
19+
params: TestingParams
20+
): Promise<any> => {
21+
let url = '';
22+
23+
switch (testType) {
24+
case 'moistureTest':
25+
url = ApiConfig.moistureContent;
26+
break;
27+
case 'purityTest':
28+
url = ApiConfig.purityTest;
29+
break;
30+
default:
31+
throw new Error('Invalid test type');
32+
}
33+
34+
const testingApiFn: Record<TestingActivitiesApiType, (...args: any[]) => Promise<any>> = {
35+
getDataByRiaKey: (riaKey: string) => api.get(`${url}/${riaKey}`).then((res) => res.data),
36+
updateMultipleReplicates: (riaKey: string, replicates: ReplicateType[]) => api.patch(`${url}/replicate/${riaKey}`, replicates),
37+
deleteSingleReplicate: (riaKey: string, replicateNumber: number) => api.delete(`${url}/${riaKey}/${replicateNumber}`),
38+
deleteMultipleReplicates: (riaKey: string, replicateNumbers: number[]) => api.post(`${url}/${riaKey}/replicates`, replicateNumbers),
39+
updateActivityRecord: (riaKey: string, activityRecord: any) => api.patch(`${url}/${riaKey}`, activityRecord),
40+
validateTestResult: (riaKey: string) => api.get(`${url}/validate/${riaKey}`),
41+
acceptResult: (riaKey: string) => api.get(`${url}/accept/${riaKey}`)
42+
};
43+
44+
const calledFn = testingApiFn[fn];
45+
46+
return calledFn(...Object.values(params));
47+
};
48+
49+
export default testingActivitiesAPI;

frontend/src/components/CONSEP/ActivitySummary/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
RadioButtonSkeleton
66
} from '@carbon/react';
77

8-
import { ActivitySummaryType } from '../../../types/ActivitySummaryType';
8+
import { ActivitySummaryType } from '../../../types/consep/TestingActivityType';
99

1010
import './styles.scss';
1111

frontend/src/routes/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const ROUTES = {
3939
MAINTAIN_STAT_HOLIDAYS: '/consep/maintain-stat-holidays',
4040
MAINTAIN_WORK_PLANS: '/consep/maintain-work-plans',
4141
MANUAL_MOISTURE_CONTENT: '/consep/manual-moisture-content/:riaKey',
42-
MANUAL_PURITY_CONTENT: '/consep/manual-purity-content',
42+
MANUAL_PURITY_CONTENT: '/consep/manual-purity-content/:riaKey',
4343
PROCESSING_ACTIVITIES: '/consep/processing-activities',
4444
RECORD_STOCK_COUNT_RESULTS: '/consep/record-stock-count-results',
4545
REQUEST_CHANGES_REPORT: '/consep/request-changes-report',

frontend/src/types/ActivitySummaryType.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.

frontend/src/types/consep/TestingActivityType.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,34 @@
1-
export type ReplicateType = {
1+
export type TestingTypes = 'moistureTest' | 'purityTest';
2+
3+
type DefaultReplicateFieldsType = {
24
riaKey: number;
35
replicateNumber: number;
46
replicateAccInd: number;
7+
overrideReason?: string;
8+
}
9+
10+
export type PurityReplicateType = DefaultReplicateFieldsType &
11+
{
12+
pureSeedWeight?: number;
13+
otherSeedWeight?: number;
14+
inertMttrWeight?: number;
15+
};
16+
17+
export type MccReplicateType = DefaultReplicateFieldsType &
18+
{
519
containerId?: string;
620
containerWeight?: number;
721
freshSeed?: number;
822
containerAndDryWeight?: number;
923
dryWeight?: number;
1024
mcValue?: number;
1125
replicateComment?: string;
12-
overrideReason?: string;
1326
};
1427

28+
export type ReplicateType = PurityReplicateType | MccReplicateType;
29+
30+
export type ReplicateKeys = keyof PurityReplicateType | keyof MccReplicateType;
31+
1532
export type ActivityRecordType = {
1633
testCategoryCode?: string;
1734
riaComment?: string;
@@ -30,3 +47,11 @@ export type TestingActivityType = ActivityRecordType & {
3047
activityType: string;
3148
replicatesList: ReplicateType[];
3249
};
50+
51+
export type ActivitySummaryType = {
52+
activity: string;
53+
seedlotNumber: string;
54+
requestId: string;
55+
speciesAndClass: string;
56+
testResult: string;
57+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* This function creates a new empty replicate list for
3+
* testing activities
4+
*
5+
* @param {string} activityRiaKey the activity riakey to generate the list
6+
* @returns {any} a list of empty rows
7+
*/
8+
export const initReplicatesList = (activityRiaKey: string): any => {
9+
const emptyRows = [];
10+
for (let i = 0; i < 4; i += 1) {
11+
emptyRows.push({
12+
riaKey: activityRiaKey,
13+
replicateNumber: i + 1,
14+
replicateAccInd: 1
15+
});
16+
}
17+
return emptyRows;
18+
};

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

Lines changed: 105 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@ import React from 'react';
33
import { MRT_ColumnDef } from 'material-react-table';
44
import { Checkbox } from '@mui/material';
55
import * as Icons from '@carbon/icons-react';
6-
import { ReplicateType } from '../../../../types/consep/TestingActivityType';
6+
import { ReplicateKeys, ReplicateType } from '../../../../types/consep/TestingActivityType';
7+
8+
export const TABLE_TITLE = 'Activity results per replicate';
79

810
const alignRight = {
911
muiTableHeadCellProps: { align: 'right' as const },
1012
muiTableBodyCellProps: { align: 'right' as const }
1113
};
1214

1315
const createEditableNumberColumn = (
14-
accessorKey: keyof ReplicateType,
16+
accessorKey: ReplicateKeys,
1517
header: string,
1618
validationMsg: string,
1719
updateRow: (row: ReplicateType) => void,
@@ -22,7 +24,7 @@ const createEditableNumberColumn = (
2224
header,
2325
size: 120,
2426
muiEditTextFieldProps: ({ cell, row }) => {
25-
const value = row.original[accessorKey] ?? '';
27+
const value = row.original[accessorKey as keyof typeof row.original] ?? '';
2628
return {
2729
type: 'number',
2830
value,
@@ -60,7 +62,7 @@ const createEditableNumberColumn = (
6062
});
6163

6264
const createEditableTextColumn = (
63-
accessorKey: keyof ReplicateType,
65+
accessorKey: ReplicateKeys,
6466
header: string,
6567
maxLength: number,
6668
validationMsg: string,
@@ -72,7 +74,7 @@ const createEditableTextColumn = (
7274
header,
7375
size: 80,
7476
muiEditTextFieldProps: ({ cell, row }) => {
75-
const value = row.original[accessorKey] ?? '';
77+
const value = row.original[accessorKey as keyof typeof row.original] ?? '';
7678
return {
7779
type: 'text',
7880
value,
@@ -96,7 +98,7 @@ const createEditableTextColumn = (
9698
...alignRight
9799
});
98100

99-
export const getColumns = (
101+
export const getMccColumns = (
100102
disableEditing: boolean,
101103
handleClearOne: (replicateNumber: number) => void,
102104
updateRow: (row: ReplicateType) => void,
@@ -153,7 +155,7 @@ export const getColumns = (
153155
enableEditing: false,
154156
muiEditTextFieldProps: ({ row }) => ({
155157
type: 'text',
156-
value: row.original.dryWeight ?? ''
158+
value: 'dryWeight' in row.original ? row.original.dryWeight : ''
157159
})
158160
},
159161
{
@@ -162,7 +164,7 @@ export const getColumns = (
162164
size: 80,
163165
muiEditTextFieldProps: ({ row }) => ({
164166
type: 'text',
165-
value: row.original.mcValue ?? ''
167+
value: 'mcValue' in row.original ? row.original.mcValue : ''
166168
}),
167169
enableEditing: false,
168170
...alignRight
@@ -193,7 +195,7 @@ export const getColumns = (
193195
size: 300,
194196
muiEditTextFieldProps: ({ row }) => ({
195197
type: 'text',
196-
value: row.original.replicateComment ?? '',
198+
value: 'replicateComment' in row.original ? row.original.replicateComment : '',
197199
onChange: (event) => {
198200
updateRow({
199201
...row.original,
@@ -217,3 +219,97 @@ export const getColumns = (
217219
...alignRight
218220
}
219221
];
222+
223+
export const getPurityColumns = (
224+
disableEditing: boolean,
225+
handleClearOne: (replicateNumber: number) => void,
226+
updateRow: (row: ReplicateType) => void,
227+
validationErrors: Record<string, string | undefined>,
228+
setValidationErrors: React.Dispatch<React.SetStateAction<Record<string, string | undefined>>>
229+
): MRT_ColumnDef<ReplicateType>[] => [
230+
{
231+
accessorKey: 'replicateNumber',
232+
header: 'Replicate',
233+
size: 40,
234+
enableEditing: false,
235+
...alignRight
236+
},
237+
createEditableNumberColumn(
238+
'pureSeedWeight',
239+
'Pure seed weight (g)',
240+
'Pure Seed Weight must be greater than or equal to 0 and less than 1,000',
241+
updateRow,
242+
validationErrors,
243+
setValidationErrors
244+
),
245+
createEditableNumberColumn(
246+
'inertMttrWeight',
247+
'Inert matter weight (g)',
248+
'Inert Matter Weight must be greater than or equal to 0 and less than 1,000',
249+
updateRow,
250+
validationErrors,
251+
setValidationErrors
252+
),
253+
createEditableNumberColumn(
254+
'otherSeedWeight',
255+
'Other seed weight (g)',
256+
'Other Seed Weight must be greater than or equal to 0 and less than 1,000',
257+
updateRow,
258+
validationErrors,
259+
setValidationErrors
260+
),
261+
{
262+
accessorKey: 'purityValue',
263+
header: 'Purity',
264+
size: 80,
265+
...alignRight
266+
},
267+
{
268+
accessorKey: 'replicateAccInd',
269+
header: 'Acc',
270+
Cell: ({ row }: { row: { original: ReplicateType } }) => (
271+
<Checkbox
272+
checked={!!row.original.replicateAccInd}
273+
disabled={disableEditing}
274+
onClick={() => {
275+
updateRow({
276+
...row.original,
277+
replicateAccInd: row.original.replicateAccInd === 1 ? 0 : 1
278+
});
279+
}}
280+
/>
281+
),
282+
size: 40,
283+
muiTableHeadCellProps: { align: 'center' },
284+
muiTableBodyCellProps: { align: 'center' },
285+
enableEditing: false
286+
},
287+
{
288+
accessorKey: 'overrideReason',
289+
header: 'Comments',
290+
size: 300,
291+
muiEditTextFieldProps: ({ row }) => ({
292+
type: 'text',
293+
onChange: (event) => {
294+
updateRow({
295+
...row.original,
296+
replicateComment: event.currentTarget.value
297+
});
298+
}
299+
})
300+
},
301+
{
302+
accessorKey: 'actions',
303+
header: '',
304+
Cell: ({ row }: { row: { original: ReplicateType } }) => (
305+
<Icons.TrashCan
306+
size={15}
307+
style={{ cursor: 'pointer' }}
308+
onClick={() => handleClearOne(row.original.replicateNumber)}
309+
/>
310+
),
311+
enableEditing: false,
312+
size: 40,
313+
...alignRight
314+
}
315+
];

0 commit comments

Comments
 (0)