Skip to content

Commit 97f966a

Browse files
committed
#4008 all misc changes
1 parent 330c379 commit 97f966a

9 files changed

Lines changed: 488 additions & 373 deletions

File tree

src/frontend/src/pages/FinancePage/ReimbursementRequestDetailPage/ReimbursementProductsView.tsx

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { Box, Table, TableBody, TableCell, TableHead, TableRow, Typography } from '@mui/material';
1+
import { Box, Link, Table, TableBody, TableCell, TableHead, TableRow, Typography } from '@mui/material';
22
import { getUniqueWbsElementsWithProductsFromReimbursementRequest } from '../../../utils/reimbursement-request.utils';
33
import { ReimbursementRequest } from 'shared';
44
import { centsToDollar } from '../../../utils/pipes';
5+
import { routes } from '../../../utils/routes';
56

67
interface ReimbursementRequestProductsViewProps {
78
reimbursementRequest: ReimbursementRequest;
@@ -21,7 +22,6 @@ const ReimbursementProductsView: React.FC<ReimbursementRequestProductsViewProps>
2122
(product) => product.refundSources.length > 1
2223
);
2324

24-
// put all the refund source names in a set to avoid duplicate names
2525
const refundSourceNames: string[] = Array.from(
2626
new Set(
2727
reimbursementRequest.reimbursementProducts.flatMap((product) => product.refundSources.map((rs) => rs.indexCode.name))
@@ -58,16 +58,26 @@ const ReimbursementProductsView: React.FC<ReimbursementRequestProductsViewProps>
5858
return (
5959
<TableRow key={key}>
6060
<TableCell>
61-
<Box
62-
sx={{
63-
maxWidth: '64ch',
64-
overflowWrap: 'anywhere',
65-
whiteSpace: 'normal'
66-
}}
67-
>
68-
{uniqueWbsElementsWithProducts.get(key)?.map((product, index) => (
69-
<div key={index}>{product.name}</div>
70-
))}
61+
<Box sx={{ maxWidth: '64ch', overflowWrap: 'anywhere', whiteSpace: 'normal' }}>
62+
{uniqueWbsElementsWithProducts.get(key)?.map((product, index) => {
63+
const bomUrl = (() => {
64+
if (!product.materialId) return undefined;
65+
const reason = product.reimbursementProductReason;
66+
if (!('wbsNum' in reason)) return undefined;
67+
return `${routes.PROJECTS}/${reason.wbsNum.carNumber}.${reason.wbsNum.projectNumber}.${reason.wbsNum.workPackageNumber}/bom`;
68+
})();
69+
return (
70+
<div key={index}>
71+
{bomUrl ? (
72+
<Link href={bomUrl} underline="hover">
73+
{product.name}
74+
</Link>
75+
) : (
76+
product.name
77+
)}
78+
</div>
79+
);
80+
})}
7181
</Box>
7282
</TableCell>
7383
{!allKeysAreSame && <TableCell>{key}</TableCell>}

src/frontend/src/pages/FinancePage/ReimbursementRequestForm/ReimbursementProductTable.tsx

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import { ReimbursementRequestFormInput } from './ReimbursementRequestForm';
3636
import { useTheme } from '@mui/system';
3737
import { useEffect, useState, useRef, useMemo } from 'react';
3838
import { useGetAllOtherProductReason } from '../../../hooks/finance.hooks';
39-
import { useGetMaterialsForWbsElement, useGetAssembliesForWbsElement } from '../../../hooks/bom.hooks';
39+
import { useGetMaterialsForWbsElement } from '../../../hooks/bom.hooks';
4040
import LoadingIndicator from '../../../components/LoadingIndicator';
4141
import ErrorPage from '../../ErrorPage';
4242
import { formatReasonName } from '../../../utils/reimbursement-request.utils';
@@ -174,13 +174,6 @@ const ReimbursementProductTable: React.FC<ReimbursementProductTableProps> = ({
174174
const [currentProject, setCurrentProject] = useState<ProjectPreview | null>(null);
175175
const [pendingMaterialIndices, setPendingMaterialIndices] = useState<Set<number>>(new Set());
176176

177-
const {
178-
data: assemblies,
179-
isLoading: assembliesLoading,
180-
isError: assembliesIsError,
181-
error: assembliesError
182-
} = useGetAssembliesForWbsElement(currentProject?.wbsNum || { carNumber: 0, projectNumber: 0, workPackageNumber: 0 });
183-
184177
const onCostBlurHandler = (value: number, index: number) => {
185178
setValue(`reimbursementProducts.${index}.cost`, parseFloat(value.toFixed(2)));
186179

@@ -337,9 +330,6 @@ const ReimbursementProductTable: React.FC<ReimbursementProductTableProps> = ({
337330
if (otherReasonIsError) {
338331
return <ErrorPage message={otherReasonError.message} />;
339332
}
340-
if (assembliesIsError) {
341-
return <ErrorPage message={assembliesError?.message || 'Failed to load assemblies'} />;
342-
}
343333

344334
return (
345335
<>
@@ -864,13 +854,13 @@ const ReimbursementProductTable: React.FC<ReimbursementProductTableProps> = ({
864854
</Table>
865855
</TableContainer>
866856

867-
{currentProject && !assembliesLoading && assemblies && (
857+
{currentProject && (
868858
<CreateMaterialModal
869859
open={showCreateMaterialModal}
870860
onHide={handleCloseCreateMaterial}
871861
wbsElement={currentProject}
872-
assemblies={assemblies}
873862
onSuccess={handleMaterialCreated}
863+
fromRRForm
874864
/>
875865
)}
876866
</>

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

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
1-
import { Assembly, WbsElementPreview } from 'shared';
1+
import { WbsElementPreview } from 'shared';
22
import MaterialForm, { MaterialDataSubmission } from './MaterialForm';
33
import LoadingIndicator from '../../../../../components/LoadingIndicator';
44
import { useToast } from '../../../../../hooks/toasts.hooks';
5-
import { useCreateMaterial } from '../../../../../hooks/bom.hooks';
5+
import { useCreateMaterial, useGetAssembliesForWbsElement } from '../../../../../hooks/bom.hooks';
66
import ErrorPage from '../../../../ErrorPage';
77

88
export interface CreateMaterialModalProps {
99
open: boolean;
1010
onHide: () => void;
1111
wbsElement: WbsElementPreview;
12-
assemblies: Assembly[];
1312
onSuccess?: (materialName: string) => void;
13+
fromRRForm?: boolean;
1414
}
1515

16-
const CreateMaterialModal: React.FC<CreateMaterialModalProps> = ({ open, onHide, assemblies, wbsElement, onSuccess }) => {
16+
const CreateMaterialModal: React.FC<CreateMaterialModalProps> = ({
17+
open,
18+
onHide,
19+
wbsElement,
20+
onSuccess,
21+
fromRRForm = false
22+
}) => {
1723
const { mutateAsync: createMaterial, isLoading, isError, error } = useCreateMaterial(wbsElement.wbsNum);
24+
const { data: assemblies, isLoading: assembliesLoading } = useGetAssembliesForWbsElement(wbsElement.wbsNum);
1825
const toast = useToast();
1926

2027
if (isLoading) return <LoadingIndicator />;
@@ -37,7 +44,17 @@ const CreateMaterialModal: React.FC<CreateMaterialModalProps> = ({ open, onHide,
3744
}
3845
};
3946

40-
return <MaterialForm submitText="Add" onSubmit={onSubmit} assemblies={assemblies} onHide={onHide} open={open} />;
47+
return (
48+
<MaterialForm
49+
submitText="Add"
50+
onSubmit={onSubmit}
51+
assemblies={assemblies ?? []}
52+
assembliesLoading={assembliesLoading}
53+
onHide={onHide}
54+
open={open}
55+
fromRRForm={fromRRForm}
56+
/>
57+
);
4158
};
4259

4360
export default CreateMaterialModal;

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,16 @@ export interface MaterialAdminWrapperProps {
1717
allMaterialTypes: MaterialType[];
1818
allUnits: Unit[];
1919
allManufacturers: Manufacturer[];
20+
manufacturersLoading?: boolean;
21+
materialTypesLoading?: boolean;
22+
unitsLoading?: boolean;
2023
assemblies: Assembly[];
24+
assembliesLoading?: boolean;
2125
open: boolean;
2226
watch: UseFormWatch<MaterialFormInput>;
2327
createManufacturer: (name: string) => void;
2428
setValue: UseFormSetValue<MaterialFormInput>;
29+
fromRRForm?: boolean;
2530
}
2631

2732
const MaterialAdminWrapper: React.FC<MaterialAdminWrapperProps> = ({
@@ -32,13 +37,18 @@ const MaterialAdminWrapper: React.FC<MaterialAdminWrapperProps> = ({
3237
control,
3338
errors,
3439
allMaterialTypes,
40+
materialTypesLoading,
3541
allUnits,
42+
unitsLoading,
3643
allManufacturers,
44+
manufacturersLoading,
3745
assemblies,
46+
assembliesLoading,
3847
open,
3948
watch,
4049
createManufacturer,
41-
setValue
50+
setValue,
51+
fromRRForm = false
4252
}) => {
4353
const {
4454
data: reimbursementRequests,
@@ -53,9 +63,13 @@ const MaterialAdminWrapper: React.FC<MaterialAdminWrapperProps> = ({
5363
return (
5464
<MaterialFormView
5565
assemblies={assemblies}
66+
assembliesLoading={assembliesLoading}
5667
allManufacturers={allManufacturers}
68+
manufacturersLoading={manufacturersLoading}
5769
allMaterialTypes={allMaterialTypes}
70+
materialTypesLoading={materialTypesLoading}
5871
allUnits={allUnits}
72+
unitsLoading={unitsLoading}
5973
onSubmit={onSubmit}
6074
handleSubmit={handleSubmit}
6175
submitText={submitText}
@@ -67,6 +81,7 @@ const MaterialAdminWrapper: React.FC<MaterialAdminWrapperProps> = ({
6781
watch={watch}
6882
createManufacturer={createManufacturer}
6983
setValue={setValue}
84+
fromRRForm={fromRRForm}
7085
/>
7186
);
7287
};

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

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { yupResolver } from '@hookform/resolvers/yup';
33
import { useForm } from 'react-hook-form';
44
import { Assembly, MaterialStatus, RoleEnum } from 'shared';
55
import * as yup from 'yup';
6-
import LoadingIndicator from '../../../../../components/LoadingIndicator';
76
import {
87
useCreateManufacturer,
98
useGetAllManufacturers,
@@ -16,6 +15,7 @@ import { useCurrentUser } from '../../../../../hooks/users.hooks';
1615
import MaterialAdminWrapper from './MaterialAdminWrapper';
1716
import MaterialHeadWrapper from './MaterialHeadWrapper';
1817
import MaterialMemberWrapper from './MaterialMemberWrapper';
18+
import LoadingIndicator from '../../../../../components/LoadingIndicator';
1919

2020
const schema = yup.object().shape({
2121
name: yup.string().required('Enter a name!'),
@@ -73,9 +73,20 @@ export interface MaterialFormProps {
7373
onHide: () => void;
7474
open: boolean;
7575
assemblies: Assembly[];
76+
assembliesLoading?: boolean;
77+
fromRRForm?: boolean;
7678
}
7779

78-
const MaterialForm: React.FC<MaterialFormProps> = ({ submitText, assemblies, onSubmit, defaultValues, onHide, open }) => {
80+
const MaterialForm: React.FC<MaterialFormProps> = ({
81+
submitText,
82+
assemblies,
83+
assembliesLoading,
84+
onSubmit,
85+
defaultValues,
86+
onHide,
87+
open,
88+
fromRRForm = false
89+
}) => {
7990
const {
8091
handleSubmit,
8192
control,
@@ -85,10 +96,10 @@ const MaterialForm: React.FC<MaterialFormProps> = ({ submitText, assemblies, onS
8596
} = useForm<MaterialFormInput>({
8697
defaultValues: {
8798
name: defaultValues?.name ?? '',
88-
status: defaultValues?.status ?? MaterialStatus.NotReadyToOrder,
99+
status: defaultValues?.status ?? (fromRRForm ? MaterialStatus.ReadyToOrder : MaterialStatus.NotReadyToOrder),
89100
materialTypeName: defaultValues?.materialTypeName ?? '',
90101
manufacturerPartNumber: defaultValues?.manufacturerPartNumber ?? '',
91-
quantity: defaultValues?.quantity ?? 0,
102+
quantity: defaultValues?.quantity ?? 1,
92103
manufacturerName: defaultValues?.manufacturerName ?? '',
93104
pdmFileName: defaultValues?.pdmFileName,
94105
price: defaultValues?.price ?? 0,
@@ -125,15 +136,7 @@ const MaterialForm: React.FC<MaterialFormProps> = ({ submitText, assemblies, onS
125136
if (unitsIsError) return <ErrorPage message={unitsError.message} />;
126137
if (manufacturersIsError) return <ErrorPage message={manufacturersError.message} />;
127138

128-
if (
129-
isLoadingManufactuers ||
130-
isLoadingMaterialTypes ||
131-
isLoadingUnits ||
132-
!materialTypes ||
133-
!units ||
134-
!manufactuers ||
135-
isLoadingCreateManufacturer
136-
) {
139+
if (isLoadingCreateManufacturer) {
137140
return <LoadingIndicator />;
138141
}
139142

@@ -160,9 +163,13 @@ const MaterialForm: React.FC<MaterialFormProps> = ({ submitText, assemblies, onS
160163

161164
const sharedProps = {
162165
assemblies,
163-
allManufacturers: manufactuers,
164-
allMaterialTypes: materialTypes,
165-
allUnits: units,
166+
assembliesLoading,
167+
allManufacturers: manufactuers ?? [],
168+
allMaterialTypes: materialTypes ?? [],
169+
allUnits: units ?? [],
170+
manufacturersLoading: isLoadingManufactuers,
171+
materialTypesLoading: isLoadingMaterialTypes,
172+
unitsLoading: isLoadingUnits,
166173
onSubmit: onSubmitWrapper,
167174
handleSubmit,
168175
submitText,
@@ -172,7 +179,8 @@ const MaterialForm: React.FC<MaterialFormProps> = ({ submitText, assemblies, onS
172179
open,
173180
watch,
174181
createManufacturer: createManufacturerWrapper,
175-
setValue
182+
setValue,
183+
fromRRForm
176184
};
177185

178186
if (user.role === RoleEnum.APP_ADMIN || user.role === RoleEnum.ADMIN) {

0 commit comments

Comments
 (0)