Skip to content

Commit 531bba9

Browse files
authored
Merge pull request #4059 from Northeastern-Electric-Racing/#3881-create-select-material-to-copy-modal
#3881 create select material to copy modal
2 parents 7dc4bd0 + aa467b1 commit 531bba9

5 files changed

Lines changed: 337 additions & 6 deletions

File tree

src/frontend/src/hooks/bom.hooks.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useMutation, useQuery, useQueryClient } from 'react-query';
2-
import { Assembly, Manufacturer, Material, MaterialType, Unit, WbsNumber, wbsPipe } from 'shared';
2+
import { Assembly, Manufacturer, Material, MaterialType, ProjectPreview, Unit, WbsNumber, wbsPipe } from 'shared';
33
import { useToast } from '../hooks/toasts.hooks';
44
import {
55
assignMaterialToAssembly,
@@ -326,3 +326,33 @@ export const useGetMaterialsForWbsElement = (wbsNum: WbsNumber) => {
326326
return data;
327327
});
328328
};
329+
330+
export const useGetMaterialsForCar = (carNumber: number | null, projects: ProjectPreview[]) => {
331+
const projectsInCar = projects.filter((p) => p.wbsNum.carNumber === carNumber);
332+
333+
return useQuery<Material[], Error>(
334+
['materials', 'car', carNumber ?? 'none'],
335+
async () => {
336+
const results = await Promise.all(
337+
projectsInCar.map(async (p) => {
338+
const { data } = await getMaterialsForWbsElement({
339+
carNumber: p.wbsNum.carNumber,
340+
projectNumber: p.wbsNum.projectNumber,
341+
workPackageNumber: 0
342+
});
343+
return data;
344+
})
345+
);
346+
347+
const flat = results.flat();
348+
const seen = new Set<string>();
349+
return flat.filter((material) => {
350+
const key = `${material.name.toLowerCase()}-${material.assemblyId ?? 'no-assembly'}`;
351+
if (seen.has(key)) return false;
352+
seen.add(key);
353+
return true;
354+
});
355+
},
356+
{ enabled: carNumber !== null && projectsInCar.length > 0 }
357+
);
358+
};

src/frontend/src/pages/ProjectDetailPage/ProjectViewContainer/BOM/BOMTableWrapper.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ const BOMTableWrapper: React.FC<BOMTableWrapperProps> = ({
298298
flex: 1.5,
299299
field: 'name',
300300
headerName: 'Name',
301+
type: 'string',
301302
sortable: false,
302303
filterable: false,
303304
hide: hideColumn[3],

src/frontend/src/pages/ProjectDetailPage/ProjectViewContainer/BOM/MaterialForm/MaterialFormView.tsx

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
Accordion,
33
AccordionDetails,
44
AccordionSummary,
5+
Button,
56
FormControl,
67
FormHelperText,
78
FormLabel,
@@ -14,7 +15,7 @@ import {
1415
} from '@mui/material';
1516
import { Box } from '@mui/system';
1617
import { Control, Controller, FieldErrors, UseFormHandleSubmit, UseFormSetValue, UseFormWatch } from 'react-hook-form';
17-
import { Assembly, Manufacturer, MaterialType, Unit } from 'shared';
18+
import { Assembly, Manufacturer, Material, MaterialType, Unit } from 'shared';
1819
import ReactHookTextField from '../../../../../components/ReactHookTextField';
1920
import { MaterialFormInput } from './MaterialForm';
2021
import NERFormModal from '../../../../../components/NERFormModal';
@@ -26,6 +27,7 @@ import { displayEnum } from '../../../../../utils/pipes';
2627
import { MaterialStatus } from 'shared';
2728
import React, { useState } from 'react';
2829
import { AddCircle } from '@mui/icons-material';
30+
import SelectMaterialToCopyModal from './SelectMaterialToCopyModal';
2931

3032
export interface MaterialFormViewProps {
3133
submitText: 'Add' | 'Edit';
@@ -42,7 +44,6 @@ export interface MaterialFormViewProps {
4244
watch: UseFormWatch<MaterialFormInput>;
4345
createManufacturer: (name: string) => void;
4446
setValue: UseFormSetValue<MaterialFormInput>;
45-
copyFromExistingBomAction?: React.ReactNode;
4647
fromRRForm?: boolean;
4748
}
4849

@@ -77,6 +78,23 @@ const MaterialFormView: React.FC<MaterialFormViewProps> = ({
7778
const price = watch('price');
7879
const subtotal = quantity && price ? quantity * price : 0;
7980

81+
const [copyModalOpen, setCopyModalOpen] = React.useState(false);
82+
83+
const handleCopySelect = (m: Material) => {
84+
setValue('name', m.name ?? '');
85+
setValue('materialTypeName', m.materialTypeName ?? '');
86+
setValue('manufacturerName', m.manufacturerName ?? '');
87+
setValue('manufacturerPartNumber', m.manufacturerPartNumber ?? '');
88+
setValue('pdmFileName', m.pdmFileName ?? '');
89+
setValue('linkUrl', m.linkUrl ?? '');
90+
setValue('quantity', m.quantity != null ? Number(m.quantity) : undefined);
91+
setValue('unitName', m.unitName ?? undefined);
92+
setValue('price', m.price != null ? m.price / 100 : undefined);
93+
setValue('notes', m.notes ?? '');
94+
setValue('assemblyId', undefined);
95+
96+
setCopyModalOpen(false);
97+
};
8098
const optionalFields = (
8199
<Grid container spacing={2}>
82100
<Grid item xs={12}>
@@ -504,7 +522,7 @@ const MaterialFormView: React.FC<MaterialFormViewProps> = ({
504522
)}
505523
</Grid>
506524
</Grid>
507-
{/*submitText === 'Add' && (
525+
{submitText === 'Add' && (
508526
<Grid item xs={12} sx={{ pl: 0, pr: 0 }}>
509527
<Box
510528
sx={{
@@ -514,7 +532,7 @@ const MaterialFormView: React.FC<MaterialFormViewProps> = ({
514532
<Button
515533
variant="contained"
516534
disableElevation
517-
onClick={() => {}}
535+
onClick={() => setCopyModalOpen(true)}
518536
sx={{
519537
mx: 0,
520538
textTransform: 'none',
@@ -527,7 +545,13 @@ const MaterialFormView: React.FC<MaterialFormViewProps> = ({
527545
</Button>
528546
</Box>
529547
</Grid>
530-
)*/}
548+
)}
549+
<SelectMaterialToCopyModal
550+
open={copyModalOpen}
551+
onHide={() => setCopyModalOpen(false)}
552+
onSelect={handleCopySelect}
553+
assemblies={assemblies ?? []}
554+
/>
531555
</NERFormModal>
532556
);
533557
};

0 commit comments

Comments
 (0)