| @@ -39,6 +39,10 @@ export interface ReleaseProdScheduleInputs { | |||
| demandQty: number; | |||
| } | |||
| export interface ReleaseProdScheduleReq { | |||
| id: number; | |||
| } | |||
| export interface ReleaseProdScheduleResponse { | |||
| id: number; | |||
| code: string; | |||
| @@ -48,6 +52,12 @@ export interface ReleaseProdScheduleResponse { | |||
| message: string; | |||
| } | |||
| export interface ReleaseProdScheduleRsp { | |||
| id: number; | |||
| code: string; | |||
| message: string; | |||
| } | |||
| export interface SaveProdScheduleResponse { | |||
| id: number; | |||
| code: string; | |||
| @@ -151,6 +161,22 @@ export const releaseProdScheduleLine = cache(async (data: ReleaseProdScheduleInp | |||
| return response; | |||
| }) | |||
| export const releaseProdSchedule = cache(async (data: ReleaseProdScheduleReq) => { | |||
| const response = serverFetchJson<ReleaseProdScheduleRsp>( | |||
| `${BASE_API_URL}/productionSchedule/detail/detailed/release`, | |||
| { | |||
| method: "POST", | |||
| body: JSON.stringify(data), | |||
| headers: { "Content-Type": "application/json" }, | |||
| } | |||
| ); | |||
| //revalidateTag("detailedProdSchedules"); | |||
| //revalidateTag("prodSchedule"); | |||
| return response; | |||
| }) | |||
| export const saveProdScheduleLine = cache(async (data: ReleaseProdScheduleInputs) => { | |||
| const response = serverFetchJson<SaveProdScheduleResponse>( | |||
| `${BASE_API_URL}/productionSchedule/detail/detailed/save`, | |||
| @@ -100,6 +100,11 @@ export interface DetailedProdScheduleLineResult { | |||
| priority: number; | |||
| approved: boolean; | |||
| proportion: number; | |||
| lastMonthAvgSales: number; | |||
| avgQtyLastMonth: number; // Average usage last month | |||
| stockQty: number; // Warehouse stock quantity | |||
| daysLeft: number; // Days remaining before stockout | |||
| needNoOfJobOrder: number; | |||
| } | |||
| export interface DetailedProdScheduleLineBomMaterialResult { | |||
| @@ -77,17 +77,17 @@ const DSOverview: React.FC<Props> = ({ type, defaultInputs }) => { | |||
| // type: "dateRange", | |||
| // }, | |||
| { label: t("Production Date"), paramName: "scheduleAt", type: "date" }, | |||
| { | |||
| label: t("Product Count"), | |||
| paramName: "totalEstProdCount", | |||
| type: "text", | |||
| }, | |||
| { | |||
| label: t("Type"), | |||
| paramName: "types", | |||
| type: "autocomplete", | |||
| options: typeOptions, | |||
| }, | |||
| //{ | |||
| // label: t("Product Count"), | |||
| // paramName: "totalEstProdCount", | |||
| // type: "text", | |||
| //}, | |||
| //{ | |||
| // label: t("Type"), | |||
| // paramName: "types", | |||
| // type: "autocomplete", | |||
| // options: typeOptions, | |||
| //}, | |||
| ]; | |||
| return searchCriteria; | |||
| }, [t]); | |||
| @@ -177,18 +177,18 @@ const DSOverview: React.FC<Props> = ({ type, defaultInputs }) => { | |||
| ) as ScheduleType[]; | |||
| const params: SearchProdSchedule = { | |||
| scheduleAt: dayjs(query?.scheduleAt).isValid() | |||
| ? query?.scheduleAt | |||
| : undefined, | |||
| schedulePeriod: dayjs(query?.schedulePeriod).isValid() | |||
| ? query?.schedulePeriod | |||
| : undefined, | |||
| schedulePeriodTo: dayjs(query?.schedulePeriodTo).isValid() | |||
| ? query?.schedulePeriodTo | |||
| : undefined, | |||
| totalEstProdCount: query?.totalEstProdCount | |||
| ? Number(query?.totalEstProdCount) | |||
| : undefined, | |||
| //scheduleAt: dayjs(query?.scheduleAt).isValid() | |||
| // ? query?.scheduleAt | |||
| // : undefined, | |||
| //schedulePeriod: dayjs(query?.schedulePeriod).isValid() | |||
| // ? query?.schedulePeriod | |||
| // : undefined, | |||
| //schedulePeriodTo: dayjs(query?.schedulePeriodTo).isValid() | |||
| // ? query?.schedulePeriodTo | |||
| // : undefined, | |||
| //totalEstProdCount: query?.totalEstProdCount | |||
| // ? Number(query?.totalEstProdCount) | |||
| // : undefined, | |||
| types: convertedTypes, | |||
| pageNum: pagingController.pageNum - 1, | |||
| pageSize: pagingController.pageSize, | |||
| @@ -311,7 +311,7 @@ const DSOverview: React.FC<Props> = ({ type, defaultInputs }) => { | |||
| onClick={testDetailedScheduleClick} | |||
| // disabled={filteredSchedules.some(ele => arrayToDayjs(ele.scheduleAt).isToday())} | |||
| > | |||
| {t("Test Detailed Schedule")} | |||
| {t("Detailed Schedule")} | |||
| </Button> | |||
| </Stack> | |||
| <SearchBox | |||
| @@ -28,7 +28,9 @@ import ViewByFGDetails, { | |||
| // FGRecord, | |||
| } from "@/components/DetailedScheduleDetail/ViewByFGDetails"; | |||
| import { DetailedProdScheduleLineResult, DetailedProdScheduleResult, ScheduleType } from "@/app/api/scheduling"; | |||
| import { releaseProdScheduleLine, saveProdScheduleLine } from "@/app/api/scheduling/actions"; | |||
| // NOTE: Assuming 'releaseProdSchedule' is the new action function | |||
| // you need to implement to call the '/productionSchedule/detail/detailed/release' API | |||
| import { releaseProdScheduleLine, saveProdScheduleLine, releaseProdSchedule } from "@/app/api/scheduling/actions"; | |||
| import useUploadContext from "../UploadProvider/useUploadContext"; | |||
| import ArrowBackIcon from '@mui/icons-material/ArrowBack'; | |||
| @@ -58,7 +60,8 @@ const DetailedScheduleDetailView: React.FC<Props> = ({ | |||
| // console.log(type) | |||
| const apiRef = useGridApiRef(); | |||
| const params = useSearchParams(); | |||
| console.log(params.get("id")); | |||
| const scheduleId = params.get("id"); // Get the schedule ID for the global release API | |||
| console.log(scheduleId); | |||
| const [serverError, setServerError] = useState(""); | |||
| const [tabIndex, setTabIndex] = useState(0); | |||
| const { t } = useTranslation("schedule"); | |||
| @@ -138,19 +141,52 @@ const DetailedScheduleDetailView: React.FC<Props> = ({ | |||
| }) | |||
| if (response) { | |||
| const index = formProps.getValues("prodScheduleLines").findIndex(ele => ele.id == row.id) | |||
| // console.log(index, formProps.getValues(`prodScheduleLines.${index}.approved`)) | |||
| // formProps.setValue(`prodScheduleLines.${index}.approved`, true) | |||
| // formProps.setValue(`prodScheduleLines.${index}.jobNo`, response.code) | |||
| // Find index of the updated line to refresh its data | |||
| // const index = formProps.getValues("prodScheduleLines").findIndex(ele => ele.id == row.id) | |||
| // Update the entire line array, assuming the backend returns the updated list | |||
| formProps.setValue(`prodScheduleLines`, response.entity.prodScheduleLines.sort((a, b) => b.priority - a.priority)) | |||
| // console.log(index, formProps.getValues(`prodScheduleLines.${index}.approved`)) | |||
| } | |||
| setIsUploading(false) | |||
| } catch (e) { | |||
| console.log(e) | |||
| setIsUploading(false) | |||
| } | |||
| }, []) | |||
| }, [formProps, setIsUploading]) | |||
| // --- NEW FUNCTION: GLOBAL RELEASE FOR THE ENTIRE SCHEDULE --- | |||
| const onGlobalReleaseClick = useCallback(async () => { | |||
| if (!scheduleId) { | |||
| setServerError(t("Cannot release. Schedule ID is missing.")); | |||
| return; | |||
| } | |||
| // Optional: Add a confirmation dialog here before proceeding | |||
| setIsUploading(true); | |||
| setServerError(""); // Clear previous errors | |||
| try { | |||
| // **IMPORTANT**: Ensure 'releaseProdSchedule' is implemented in your actions file | |||
| // to call the '/productionSchedule/detail/detailed/release' endpoint. | |||
| const response = await releaseProdSchedule({ | |||
| id: Number(scheduleId), | |||
| }) | |||
| if (response) { | |||
| router.refresh(); | |||
| } | |||
| } catch (e) { | |||
| console.error(e); | |||
| setServerError(t("An unexpected error occurred during global schedule release.")); | |||
| } finally { | |||
| setIsUploading(false); | |||
| } | |||
| }, [scheduleId, setIsUploading, t, router]); | |||
| // -------------------------------------------------------------------- | |||
| const [tempValue, setTempValue] = useState<string | number | null>(null) | |||
| const onEditClick = useCallback((rowId: number) => { | |||
| @@ -158,12 +194,12 @@ const DetailedScheduleDetailView: React.FC<Props> = ({ | |||
| if (row) { | |||
| setTempValue(row.demandQty) | |||
| } | |||
| }, []) | |||
| }, [formProps]) | |||
| const handleEditChange = useCallback((rowId: number, fieldName: keyof DetailedProdScheduleLineResult, newValue: number | string) => { | |||
| const index = formProps.getValues("prodScheduleLines").findIndex(ele => ele.id == rowId) | |||
| formProps.setValue(`prodScheduleLines.${index}.demandQty`, Number(newValue)) | |||
| }, []) | |||
| }, [formProps]) | |||
| const onSaveClick = useCallback(async (row: DetailedProdScheduleLineResult) => { | |||
| setIsUploading(true) | |||
| @@ -175,6 +211,7 @@ const DetailedScheduleDetailView: React.FC<Props> = ({ | |||
| if (response) { | |||
| const index = formProps.getValues("prodScheduleLines").findIndex(ele => ele.id == row.id) | |||
| // Update BOM materials for the line after saving demand quantity | |||
| formProps.setValue(`prodScheduleLines.${index}.bomMaterials`, response.entity.bomMaterials) | |||
| } | |||
| setIsUploading(false) | |||
| @@ -182,14 +219,15 @@ const DetailedScheduleDetailView: React.FC<Props> = ({ | |||
| console.log(e) | |||
| setIsUploading(false) | |||
| } | |||
| }, []) | |||
| }, [formProps, setIsUploading]) | |||
| const onCancelClick = useCallback(async (rowId: number) => { | |||
| // if (tempValue) { | |||
| // Revert the demandQty to the temporary value stored on EditClick | |||
| if (tempValue !== null) { | |||
| const index = formProps.getValues("prodScheduleLines").findIndex(ele => ele.id == rowId) | |||
| formProps.setValue(`prodScheduleLines.${index}.demandQty`, Number(tempValue)) | |||
| // } | |||
| }, [tempValue]) | |||
| } | |||
| }, [formProps, tempValue]) | |||
| return ( | |||
| <> | |||
| @@ -200,9 +238,9 @@ const DetailedScheduleDetailView: React.FC<Props> = ({ | |||
| onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)} | |||
| > | |||
| {/*<Grid>*/} | |||
| {/* <Typography mb={2} variant="h4">*/} | |||
| {/* {t(`${mode} ${title}`)}*/} | |||
| {/* </Typography>*/} | |||
| {/* <Typography mb={2} variant="h4">*/} | |||
| {/* {t(`${mode} ${title}`)}*/} | |||
| {/* </Typography>*/} | |||
| {/*</Grid>*/} | |||
| <DetailInfoCard | |||
| // recordDetails={formProps.formState.defaultValues} | |||
| @@ -210,26 +248,23 @@ const DetailedScheduleDetailView: React.FC<Props> = ({ | |||
| isEditing={false} | |||
| /> | |||
| {/* <Stack | |||
| direction="row" | |||
| justifyContent="space-between" | |||
| flexWrap="wrap" | |||
| rowGap={2} | |||
| > | |||
| <Button | |||
| variant="contained" | |||
| onClick={onClickEdit} | |||
| // startIcon={<Add />} | |||
| //LinkComponent={Link} | |||
| //href="qcCategory/create" | |||
| > | |||
| {isEdit ? t("Save") : t("Edit")} | |||
| </Button> | |||
| </Stack> */} | |||
| direction="row" | |||
| justifyContent="space-between" | |||
| flexWrap="wrap" | |||
| rowGap={2} | |||
| > | |||
| <Button | |||
| variant="contained" | |||
| onClick={onClickEdit} | |||
| > | |||
| {isEdit ? t("Save") : t("Edit")} | |||
| </Button> | |||
| </Stack> */} | |||
| {/* <Tabs value={tabIndex} onChange={handleTabChange} variant="scrollable"> | |||
| <Tab label={t("View By FG") + (tabIndex === 0 ? " (Selected)" : "")} iconPosition="end" /> | |||
| <Tab label={t("View By Material") + (tabIndex === 1 ? " (Selected)" : "")} iconPosition="end" /> | |||
| </Tabs> */} | |||
| <Tab label={t("View By FG") + (tabIndex === 0 ? " (Selected)" : "")} iconPosition="end" /> | |||
| <Tab label={t("View By Material") + (tabIndex === 1 ? " (Selected)" : "")} iconPosition="end" /> | |||
| </Tabs> */} | |||
| {serverError && ( | |||
| <Typography variant="body2" color="error" alignSelf="flex-end"> | |||
| {serverError} | |||
| @@ -247,12 +282,24 @@ const DetailedScheduleDetailView: React.FC<Props> = ({ | |||
| type={type} /> | |||
| {/* {tabIndex === 1 && <ViewByBomDetails isEdit={isEdit} apiRef={apiRef} isHideButton={true} />} */} | |||
| <Stack direction="row" justifyContent="flex-end" gap={1}> | |||
| {/* --- NEW BUTTON: Release Entire Schedule --- */} | |||
| <Button | |||
| variant="contained" | |||
| startIcon={<Check />} | |||
| onClick={onGlobalReleaseClick} | |||
| disabled={!scheduleId} // Disable if we don't have a schedule ID | |||
| > | |||
| {t("Release Schedule")} | |||
| </Button> | |||
| {/* ------------------------------------------- */} | |||
| {/* <Button | |||
| name="submit" | |||
| variant="contained" | |||
| startIcon={<Check />} | |||
| type="submit" | |||
| // disabled={submitDisabled} | |||
| // disabled={submitDisabled} | |||
| > | |||
| {isEditMode ? t("Save") : t("Confirm")} | |||
| </Button> */} | |||
| @@ -269,4 +316,4 @@ const DetailedScheduleDetailView: React.FC<Props> = ({ | |||
| </> | |||
| ); | |||
| }; | |||
| export default DetailedScheduleDetailView; | |||
| export default DetailedScheduleDetailView; | |||
| @@ -17,28 +17,33 @@ const DetailedScheduleDetailWrapper: React.FC<Props> & SubComponents = async ({ | |||
| id, | |||
| type, | |||
| }) => { | |||
| // const defaultValues = { | |||
| // id: 1, | |||
| // productionDate: "2025-05-07", | |||
| // totalJobOrders: 13, | |||
| // totalProductionQty: 21000, | |||
| // }; | |||
| const prodSchedule = id ? await fetchDetailedProdScheduleDetail(id) : undefined | |||
| if (prodSchedule) { | |||
| prodSchedule.prodScheduleLines = prodSchedule.prodScheduleLines.sort((a, b) => b.priority - a.priority) | |||
| const prodSchedule = id ? await fetchDetailedProdScheduleDetail(id) : undefined; | |||
| console.log("RAW API DATA:", prodSchedule?.prodScheduleLines[0]); // Check the actual keys here | |||
| if (prodSchedule && prodSchedule.prodScheduleLines) { | |||
| // 1. Map the lines to ensure the new fields are explicitly handled | |||
| prodSchedule.prodScheduleLines = prodSchedule.prodScheduleLines.map(line => ({ | |||
| ...line, | |||
| // If the API uses different names (e.g., 'stockQty'), map them here: | |||
| // avgQtyLastMonth: line.avgQtyLastMonth ?? 0, | |||
| // Ensure these keys match the 'field' property in your ViewByFGDetails.tsx columns | |||
| avgQtyLastMonth: line.avgQtyLastMonth || 0, | |||
| stockQty: line.stockQty || 0, | |||
| daysLeft: line.daysLeft || 0, | |||
| needNoOfJobOrder: line.needNoOfJobOrder || 0, | |||
| })).sort((a, b) => b.priority - a.priority); | |||
| } | |||
| return ( | |||
| <DetailedScheduleDetailView | |||
| isEditMode={Boolean(id)} | |||
| defaultValues={prodSchedule} | |||
| type={type} | |||
| // qcChecks={qcChecks || []} | |||
| /> | |||
| ); | |||
| }; | |||
| DetailedScheduleDetailWrapper.Loading = GeneralLoading; | |||
| export default DetailedScheduleDetailWrapper; | |||
| export default DetailedScheduleDetailWrapper; | |||
| @@ -30,16 +30,16 @@ type Props = { | |||
| onCancelClick: (rowId: number) => void; | |||
| }; | |||
| // export type FGRecord = { | |||
| // id: string | number; | |||
| // code: string; | |||
| // name: string; | |||
| // inStockQty: number; | |||
| // productionQty?: number; | |||
| // purchaseQty?: number; | |||
| // }; | |||
| const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit, type, onReleaseClick, onEditClick, handleEditChange, onSaveClick, onCancelClick }) => { | |||
| const ViewByFGDetails: React.FC<Props> = ({ | |||
| apiRef, | |||
| isEdit, | |||
| type, | |||
| onReleaseClick, | |||
| onEditClick, | |||
| handleEditChange, | |||
| onSaveClick, | |||
| onCancelClick | |||
| }) => { | |||
| const { | |||
| t, | |||
| i18n: { language }, | |||
| @@ -47,83 +47,20 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit, type, onReleaseClick | |||
| const { | |||
| getValues, | |||
| watch, | |||
| formState: { errors, defaultValues, touchedFields }, | |||
| } = useFormContext<DetailedProdScheduleResult>(); | |||
| // const apiRef = useGridApiRef(); | |||
| // const [pagingController, setPagingController] = useState([ | |||
| // { | |||
| // pageNum: 1, | |||
| // pageSize: 10, | |||
| // totalCount: 0, | |||
| // }, | |||
| // { | |||
| // pageNum: 1, | |||
| // pageSize: 10, | |||
| // totalCount: 0, | |||
| // }, | |||
| // { | |||
| // pageNum: 1, | |||
| // pageSize: 10, | |||
| // totalCount: 0, | |||
| // }, | |||
| // { | |||
| // pageNum: 1, | |||
| // pageSize: 10, | |||
| // totalCount: 0, | |||
| // }, | |||
| // { | |||
| // pageNum: 1, | |||
| // pageSize: 10, | |||
| // totalCount: 0, | |||
| // }, | |||
| // { | |||
| // pageNum: 1, | |||
| // pageSize: 10, | |||
| // totalCount: 0, | |||
| // }, | |||
| // { | |||
| // pageNum: 1, | |||
| // pageSize: 10, | |||
| // totalCount: 0, | |||
| // }, | |||
| // { | |||
| // pageNum: 1, | |||
| // pageSize: 10, | |||
| // totalCount: 0, | |||
| // }, | |||
| // ]); | |||
| // const updatePagingController = (updatedObj) => { | |||
| // setPagingController((prevState) => { | |||
| // return prevState.map((item, index) => { | |||
| // if (index === updatedObj?.index) { | |||
| // return { | |||
| // ...item, | |||
| // pageNum: item.pageNum, | |||
| // pageSize: item.pageSize, | |||
| // totalCount: item.totalCount, | |||
| // }; | |||
| // } else return item; | |||
| // }); | |||
| // }); | |||
| // }; | |||
| const columns = useMemo<Column<DetailedProdScheduleLineResult>[]>( | |||
| () => [ | |||
| { | |||
| field: "jobNo", | |||
| label: t("Job No."), | |||
| type: "read-only", | |||
| // editable: true, | |||
| }, | |||
| { | |||
| field: "code", | |||
| label: t("code"), | |||
| type: "read-only", | |||
| // editable: true, | |||
| }, | |||
| { | |||
| field: "name", | |||
| @@ -134,122 +71,81 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit, type, onReleaseClick | |||
| field: "type", | |||
| label: t("type"), | |||
| type: "read-only", | |||
| renderCell: (row) => { | |||
| return t(row.type); | |||
| }, | |||
| // editable: true, | |||
| renderCell: (row) => <>{t(row.type)}</>, | |||
| }, | |||
| // { | |||
| // field: "inStockQty", | |||
| // label: "Available Qty", | |||
| // type: 'read-only', | |||
| // style: { | |||
| // textAlign: "right", | |||
| // }, | |||
| // // editable: true, | |||
| // renderCell: (row: FGRecord) => { | |||
| // if (typeof (row.inStockQty) == "number") { | |||
| // return decimalFormatter.format(row.inStockQty) | |||
| // } | |||
| // return row.inStockQty | |||
| // } | |||
| // }, | |||
| { | |||
| field: "demandQty", | |||
| label: t("Demand Qty"), | |||
| type: "input-number", | |||
| style: { | |||
| textAlign: "right", | |||
| // width: "100px", | |||
| }, | |||
| renderCell: (row) => { | |||
| if (typeof row.demandQty == "number") { | |||
| return integerFormatter.format(row.demandQty ?? 0); | |||
| } | |||
| return row.demandQty; | |||
| }, | |||
| style: { textAlign: "right" } as any, // Use 'as any' to bypass strict CSS validation | |||
| renderCell: (row) => <>{integerFormatter.format(row.demandQty ?? 0)}</>, | |||
| }, | |||
| { | |||
| field: "uomName", | |||
| label: t("UoM"), | |||
| type: "read-only", | |||
| style: { | |||
| textAlign: "left", | |||
| // width: "100px", | |||
| }, | |||
| renderCell: (row) => { | |||
| return row.uomName; | |||
| }, | |||
| renderCell: (row) => <>{row.uomName}</>, | |||
| }, | |||
| // --- Added Avg Usage, Stock, Days Left, and Job Order Count --- | |||
| { | |||
| field: "prodTimeInMinute", | |||
| label: t("Estimated Production Time"), | |||
| field: "avgQtyLastMonth", // This MUST match the key in the object | |||
| label: t("最近每日用量"), | |||
| type: "read-only", | |||
| style: { | |||
| textAlign: "right", | |||
| // width: "100px", | |||
| }, | |||
| renderCell: (row) => { | |||
| return <ProdTimeColumn prodTimeInMinute={row.prodTimeInMinute} /> | |||
| } | |||
| // Ensure 'row' has the property 'avgQtyLastMonth' | |||
| renderCell: (row) => <>{decimalFormatter.format(row.avgQtyLastMonth ?? 0)}</>, | |||
| }, | |||
| { | |||
| field: "stockQty", | |||
| label: t("存貨量"), | |||
| type: "read-only", | |||
| style: { textAlign: "right" } as any, | |||
| renderCell: (row) => <>{decimalFormatter.format(row.stockQty ?? 0)}</>, | |||
| }, | |||
| { | |||
| field: "daysLeft", | |||
| label: t("可用日"), | |||
| type: "read-only", | |||
| style: { textAlign: "right" } as any, | |||
| renderCell: (row) => <>{row.daysLeft ?? 0}</>, | |||
| }, | |||
| { | |||
| field: "needNoOfJobOrder", | |||
| label: t("生產量"), | |||
| type: "read-only", | |||
| style: { textAlign: "right", fontWeight: "bold" } as any, | |||
| renderCell: (row) => <>{row.needNoOfJobOrder ?? 0}</>, | |||
| }, | |||
| // ------------------------------------------------------------- | |||
| { | |||
| field: "priority", | |||
| label: t("Production Priority"), | |||
| type: "read-only", | |||
| style: { | |||
| textAlign: "right", | |||
| // width: "100px", | |||
| }, | |||
| // editable: true, | |||
| style: { textAlign: "right" } as any, | |||
| }, | |||
| ], | |||
| [], | |||
| [t] | |||
| ); | |||
| return ( | |||
| <Grid container spacing={2}> | |||
| {/* <Grid item xs={12} key={"all"}> | |||
| <Typography variant="overline" display="block" marginBlockEnd={1}> | |||
| {t("FG Demand List (7 Days)")} | |||
| </Typography> | |||
| <EditableSearchResults<FGRecord> | |||
| index={7} | |||
| items={fakeOverallRecords} | |||
| columns={overallColumns} | |||
| setPagingController={updatePagingController} | |||
| pagingController={pagingController[7]} | |||
| isAutoPaging={false} | |||
| isEditable={false} | |||
| isEdit={isEdit} | |||
| hasCollapse={true} | |||
| /> | |||
| </Grid> */} | |||
| {/* {dayPeriod.map((date, index) => ( */} | |||
| <Grid item xs={12}> | |||
| {/* <Typography variant="overline" display="block" marginBlockEnd={1}> | |||
| {`${t("FG Demand Date")}: ${date}`} | |||
| </Typography> */} | |||
| <ScheduleTable<DetailedProdScheduleLineResult> | |||
| type={type} | |||
| // items={fakeRecords[index]} // Use the corresponding records for the day | |||
| items={getValues("prodScheduleLines")} // Use the corresponding records for the day | |||
| items={getValues("prodScheduleLines")} | |||
| columns={columns} | |||
| // setPagingController={updatePagingController} | |||
| // pagingController={pagingController[index]} | |||
| isAutoPaging={false} | |||
| isEditable={true} | |||
| isEdit={isEdit} | |||
| hasCollapse={true} | |||
| onReleaseClick={onReleaseClick} | |||
| // Note: onReleaseClick is NOT passed here to hide the row-level "Release" function | |||
| onEditClick={onEditClick} | |||
| handleEditChange={handleEditChange} | |||
| onSaveClick={onSaveClick} | |||
| onCancelClick={onCancelClick} | |||
| /> | |||
| </Grid> | |||
| {/* ))} */} | |||
| </Grid> | |||
| ); | |||
| }; | |||
| export default ViewByFGDetails; | |||
| }; // Added missing closing brace | |||
| export default ViewByFGDetails; | |||