Skip to content

Commit 7dc4bd0

Browse files
authored
Merge pull request #4034 from Northeastern-Electric-Racing/#3885-BOM-Copy-Confirm
#3885 - Create Confirmation Modal for Bulk BOM Copy
2 parents d864c9a + c73b4cd commit 7dc4bd0

4 files changed

Lines changed: 95 additions & 17 deletions

File tree

src/frontend/src/pages/ProjectDetailPage/ProjectViewContainer/BOM/CopyBOM/CopyBOMModal.tsx

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,58 @@ import { WbsNumber, wbsPipe } from 'shared';
22
import CopyBOMView from './CopyBOMView';
33
import { useGetAllCars } from '../../../../../hooks/cars.hooks';
44
import { useAllProjects } from '../../../../../hooks/projects.hooks';
5-
import { useCopyMaterialsToProject } from '../../../../../hooks/bom.hooks';
6-
import React from 'react';
5+
import React, { useState } from 'react';
76
import ErrorPage from '../../../../ErrorPage';
87
import LoadingIndicator from '../../../../../components/LoadingIndicator';
8+
import BOMCopyConfirmModal from '../MaterialForm/BOMCopyConfirmModal';
99

1010
export interface CopyBOMModalProps {
1111
open: boolean;
1212
onHide: () => void;
1313
destinationWbsNum: WbsNumber;
14+
currentProjectName: string;
1415
}
1516

16-
const CopyBOMModal: React.FC<CopyBOMModalProps> = ({ open, onHide, destinationWbsNum }) => {
17+
const CopyBOMModal: React.FC<CopyBOMModalProps> = ({ open, onHide, destinationWbsNum, currentProjectName }) => {
1718
const { data: cars, isLoading: isLoadingCars, isError: carsIsError, error: carsError } = useGetAllCars();
1819
const { data: projects, isLoading: isLoadingProjects, isError: projectsIsError, error: projectsError } = useAllProjects();
19-
const { mutateAsync: copyMaterials } = useCopyMaterialsToProject();
20+
const [confirmOpen, setConfirmOpen] = useState(false);
21+
const [confirmedMaterialIds, setConfirmedMaterialIds] = useState<string[]>([]);
22+
const [confirmedSourceProjectName, setConfirmedSourceProjectName] = useState('');
2023

2124
if (isLoadingCars || !cars || isLoadingProjects || !projects) return <LoadingIndicator />;
2225
if (carsIsError) return <ErrorPage message={carsError?.message} />;
2326
if (projectsIsError) return <ErrorPage message={projectsError?.message} />;
2427

25-
const handleCopy = async (materialIds: string[]) => {
26-
await copyMaterials({
27-
materialIds,
28-
destinationWbsNum: wbsPipe(destinationWbsNum)
29-
});
30-
onHide();
31-
};
28+
const destinationWbs = wbsPipe(destinationWbsNum);
3229

33-
return <CopyBOMView open={open} onHide={onHide} cars={cars} projects={projects} onCopy={handleCopy} />;
30+
return (
31+
<>
32+
<CopyBOMView
33+
open={open}
34+
onHide={onHide}
35+
cars={cars}
36+
projects={projects}
37+
onCopy={(materialIds, sourceProjectName) => {
38+
setConfirmedMaterialIds(materialIds);
39+
setConfirmedSourceProjectName(sourceProjectName);
40+
setConfirmOpen(true);
41+
}}
42+
/>
43+
<BOMCopyConfirmModal
44+
open={confirmOpen}
45+
onHide={() => setConfirmOpen(false)}
46+
onSuccess={() => {
47+
onHide();
48+
setConfirmOpen(false);
49+
}}
50+
materialIds={confirmedMaterialIds}
51+
sourceProjectName={confirmedSourceProjectName}
52+
currentProjectName={`${wbsPipe(destinationWbsNum)} - ${currentProjectName}`}
53+
destinationWbsNum={destinationWbs}
54+
/>
55+
</>
56+
);
3457
};
3558

3659
export default CopyBOMModal;

src/frontend/src/pages/ProjectDetailPage/ProjectViewContainer/BOM/CopyBOM/CopyBOMView.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ interface CopyBOMViewProps {
1010
onHide: () => void;
1111
cars: Car[];
1212
projects: ProjectPreview[];
13-
onCopy: (materialIds: string[]) => Promise<void>;
13+
onCopy: (materialIds: string[], sourceProjectName: string) => void;
1414
}
1515

1616
const CopyBOMView: React.FC<CopyBOMViewProps> = ({ open, onHide, cars, projects, onCopy }) => {
@@ -34,7 +34,9 @@ const CopyBOMView: React.FC<CopyBOMViewProps> = ({ open, onHide, cars, projects,
3434
}));
3535

3636
const handleSubmit = async () => {
37-
await onCopy(selectedMaterialIdsRef.current);
37+
if (!selectedProject) return;
38+
const sourceProjectName = `${wbsPipe(selectedProject.wbsNum)} - ${selectedProject.name}`;
39+
onCopy(selectedMaterialIdsRef.current, sourceProjectName);
3840
};
3941

4042
return (
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import NERModal from '../../../../../components/NERModal';
2+
import { useCopyMaterialsToProject } from '../../../../../hooks/bom.hooks';
3+
4+
export interface BOMCopyConfirmModalProps {
5+
open: boolean;
6+
onHide: () => void;
7+
onSuccess: () => void;
8+
materialIds: string[];
9+
sourceProjectName: string;
10+
currentProjectName: string;
11+
destinationWbsNum: string;
12+
}
13+
14+
const BOMCopyConfirmModal = ({
15+
open,
16+
onHide,
17+
onSuccess,
18+
materialIds,
19+
sourceProjectName,
20+
currentProjectName,
21+
destinationWbsNum
22+
}: BOMCopyConfirmModalProps) => {
23+
const copyMaterials = useCopyMaterialsToProject();
24+
25+
const handleConfirm = () => {
26+
copyMaterials.mutate(
27+
{
28+
materialIds,
29+
destinationWbsNum
30+
},
31+
{
32+
onSuccess: () => {
33+
onSuccess();
34+
onHide();
35+
}
36+
}
37+
);
38+
};
39+
40+
const message = `Are you sure you want to copy ${materialIds.length} materials from ${sourceProjectName} to ${currentProjectName}?`;
41+
return (
42+
<NERModal open={open} onHide={onHide} onSubmit={handleConfirm} title="Confirm Copy">
43+
<p>{message}</p>
44+
</NERModal>
45+
);
46+
};
47+
48+
export default BOMCopyConfirmModal;

src/frontend/src/pages/ProjectDetailPage/ProjectViewContainer/BOMTab.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { Box } from '@mui/system';
22
import { MaterialPreview, Project, isGuest } from 'shared';
33
import { NERButton } from '../../../components/NERButton';
44
import WarningIcon from '@mui/icons-material/Warning';
5+
import React, { useState } from 'react';
56
import { Tooltip, useTheme } from '@mui/material';
6-
import { useState } from 'react';
77
import BOMTableWrapper from './BOM/BOMTableWrapper';
88
import CreateMaterialModal from './BOM/MaterialForm/CreateMaterialModal';
99
import CreateAssemblyModal from './BOM/AssemblyForm/CreateAssemblyModal';
@@ -31,8 +31,8 @@ const BOMTab = ({ project }: { project: Project }) => {
3131
const [showAddAssembly, setShowAddAssembly] = useState(false);
3232
const [showCopyBOM, setShowCopyBOM] = useState(false);
3333
const [showImportBOM, setShowImportBOM] = useState(false);
34-
const theme = useTheme();
3534

35+
const theme = useTheme();
3636
const user = useCurrentUser();
3737

3838
const {
@@ -99,7 +99,12 @@ const BOMTab = ({ project }: { project: Project }) => {
9999
allUnits={units}
100100
assemblies={assemblies}
101101
/>
102-
<CopyBOMModal open={showCopyBOM} onHide={() => setShowCopyBOM(false)} destinationWbsNum={project.wbsNum} />
102+
<CopyBOMModal
103+
open={showCopyBOM}
104+
onHide={() => setShowCopyBOM(false)}
105+
destinationWbsNum={project.wbsNum}
106+
currentProjectName={project.name}
107+
/>
103108
<Box sx={{ display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
104109
<BOMTableWrapper
105110
project={project}

0 commit comments

Comments
 (0)