| @@ -21,6 +21,7 @@ import { | |||||
| GridRowModel, | GridRowModel, | ||||
| GridRowModes, | GridRowModes, | ||||
| GridRowModesModel, | GridRowModesModel, | ||||
| GridRowParams, | |||||
| GridRowSelectionModel, | GridRowSelectionModel, | ||||
| GridToolbarContainer, | GridToolbarContainer, | ||||
| GridValidRowModel, | GridValidRowModel, | ||||
| @@ -63,6 +64,7 @@ export type TableRow<V, E> = Partial< | |||||
| isActive: boolean | undefined; | isActive: boolean | undefined; | ||||
| _isNew: boolean; | _isNew: boolean; | ||||
| _error: E; | _error: E; | ||||
| _disableDelete: boolean; | |||||
| } & ResultWithId | } & ResultWithId | ||||
| >; | >; | ||||
| @@ -76,6 +78,7 @@ export interface InputDataGridProps<T, V, E> { | |||||
| showRemoveBtn?: boolean; | showRemoveBtn?: boolean; | ||||
| addRowDefaultValue?: Partial<V>; | addRowDefaultValue?: Partial<V>; | ||||
| _setRowModesModel?: Dispatch<SetStateAction<GridRowModesModel>>; | _setRowModesModel?: Dispatch<SetStateAction<GridRowModesModel>>; | ||||
| _setRowSelectionModel?: Dispatch<SetStateAction<GridRowSelectionModel>>; | |||||
| } | } | ||||
| export interface SelectionInputDataGridProps<T, V, E> { | export interface SelectionInputDataGridProps<T, V, E> { | ||||
| @@ -89,6 +92,7 @@ export interface SelectionInputDataGridProps<T, V, E> { | |||||
| showRemoveBtn?: boolean; | showRemoveBtn?: boolean; | ||||
| addRowDefaultValue?: Partial<V>; | addRowDefaultValue?: Partial<V>; | ||||
| _setRowModesModel?: Dispatch<SetStateAction<GridRowModesModel>>; | _setRowModesModel?: Dispatch<SetStateAction<GridRowModesModel>>; | ||||
| _setRowSelectionModel?: Dispatch<SetStateAction<GridRowSelectionModel>>; | |||||
| } | } | ||||
| export type Props<T, V, E> = | export type Props<T, V, E> = | ||||
| @@ -118,6 +122,7 @@ function InputDataGrid<T, V, E>({ | |||||
| showRemoveBtn = true, | showRemoveBtn = true, | ||||
| addRowDefaultValue = {}, | addRowDefaultValue = {}, | ||||
| _setRowModesModel = undefined, | _setRowModesModel = undefined, | ||||
| _setRowSelectionModel = undefined, | |||||
| }: Props<T, V, E>) { | }: Props<T, V, E>) { | ||||
| const { | const { | ||||
| t, | t, | ||||
| @@ -157,9 +162,15 @@ function InputDataGrid<T, V, E>({ | |||||
| `${formKey}_active`, | `${formKey}_active`, | ||||
| ) as GridRowSelectionModel; | ) as GridRowSelectionModel; | ||||
| // console.log(rowModel); | // console.log(rowModel); | ||||
| return rowModel; | |||||
| return rowModel ?? []; | |||||
| }); | }); | ||||
| useEffect(() => { | |||||
| if (_setRowSelectionModel) { | |||||
| _setRowSelectionModel(rowSelectionModel) | |||||
| } | |||||
| }, [rowSelectionModel]) | |||||
| const handleSave = useCallback( | const handleSave = useCallback( | ||||
| (id: GridRowId) => () => { | (id: GridRowId) => () => { | ||||
| setRowModesModel((prevRowModesModel) => ({ | setRowModesModel((prevRowModesModel) => ({ | ||||
| @@ -259,7 +270,9 @@ function InputDataGrid<T, V, E>({ | |||||
| headerName: "", | headerName: "", | ||||
| flex: 0.5, | flex: 0.5, | ||||
| cellClassName: "actions", | cellClassName: "actions", | ||||
| getActions: ({ id }: { id: GridRowId }) => { | |||||
| getActions: (params: GridRowParams<TableRow<V, E>>) => { | |||||
| const id = params.id | |||||
| const _disableDelete = Boolean(params.row._disableDelete) | |||||
| const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit; | const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit; | ||||
| if (isInEditMode) { | if (isInEditMode) { | ||||
| return [ | return [ | ||||
| @@ -284,6 +297,7 @@ function InputDataGrid<T, V, E>({ | |||||
| <GridActionsCellItem | <GridActionsCellItem | ||||
| icon={<DeleteIcon />} | icon={<DeleteIcon />} | ||||
| label="Delete" | label="Delete" | ||||
| disabled={_disableDelete} | |||||
| sx={{ | sx={{ | ||||
| color: "error.main", | color: "error.main", | ||||
| }} | }} | ||||
| @@ -349,7 +363,8 @@ function InputDataGrid<T, V, E>({ | |||||
| rowSelectionModel={rowSelectionModel} | rowSelectionModel={rowSelectionModel} | ||||
| apiRef={apiRef} | apiRef={apiRef} | ||||
| rows={rows} | rows={rows} | ||||
| columns={!checkboxSelection ? _columns : columns} | |||||
| // columns={!checkboxSelection ? _columns : columns} | |||||
| columns={_columns} | |||||
| editMode="row" | editMode="row" | ||||
| autoHeight | autoHeight | ||||
| sx={{ | sx={{ | ||||
| @@ -377,15 +392,17 @@ function InputDataGrid<T, V, E>({ | |||||
| return classname; | return classname; | ||||
| }} | }} | ||||
| slots={ | slots={ | ||||
| !checkboxSelection | |||||
| ? { | |||||
| // !checkboxSelection | |||||
| // ? | |||||
| { | |||||
| footer: FooterToolbar, | footer: FooterToolbar, | ||||
| noRowsOverlay: NoRowsOverlay, | noRowsOverlay: NoRowsOverlay, | ||||
| } | } | ||||
| : undefined | |||||
| // : undefined | |||||
| } | } | ||||
| slotProps={ | slotProps={ | ||||
| !checkboxSelection && Boolean(needAdd) | |||||
| // !checkboxSelection && Boolean(needAdd) | |||||
| Boolean(needAdd) | |||||
| ? { | ? { | ||||
| footer: { child: footer }, | footer: { child: footer }, | ||||
| } | } | ||||
| @@ -28,6 +28,7 @@ import { | |||||
| GridRenderCellParams, | GridRenderCellParams, | ||||
| GridRenderEditCellParams, | GridRenderEditCellParams, | ||||
| useGridApiRef, | useGridApiRef, | ||||
| GridRowSelectionModel, | |||||
| } from "@mui/x-data-grid"; | } from "@mui/x-data-grid"; | ||||
| import InputDataGrid from "../InputDataGrid"; | import InputDataGrid from "../InputDataGrid"; | ||||
| import { TableRow } from "../InputDataGrid/InputDataGrid"; | import { TableRow } from "../InputDataGrid/InputDataGrid"; | ||||
| @@ -60,6 +61,7 @@ interface Props { | |||||
| disabled: boolean; | disabled: boolean; | ||||
| // qc: QcItemWithChecks[]; | // qc: QcItemWithChecks[]; | ||||
| setRowModesModel: Dispatch<SetStateAction<GridRowModesModel>>; | setRowModesModel: Dispatch<SetStateAction<GridRowModesModel>>; | ||||
| setRowSelectionModel: Dispatch<SetStateAction<GridRowSelectionModel>>; | |||||
| } | } | ||||
| type EntryError = | type EntryError = | ||||
| | { | | { | ||||
| @@ -81,7 +83,7 @@ const style = { | |||||
| width: "auto", | width: "auto", | ||||
| }; | }; | ||||
| const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled, setRowModesModel }) => { | |||||
| const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled, setRowModesModel, setRowSelectionModel }) => { | |||||
| const { t } = useTranslation("purchaseOrder"); | const { t } = useTranslation("purchaseOrder"); | ||||
| const apiRef = useGridApiRef(); | const apiRef = useGridApiRef(); | ||||
| const { | const { | ||||
| @@ -534,7 +536,7 @@ const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled, setRowM | |||||
| {/* <QrCode content={qrContent} sx={{ width: 200, height: 200 }} /> */} | {/* <QrCode content={qrContent} sx={{ width: 200, height: 200 }} /> */} | ||||
| <InputDataGrid<PutAwayInput, PutAwayLine, EntryError> | <InputDataGrid<PutAwayInput, PutAwayLine, EntryError> | ||||
| apiRef={apiRef} | apiRef={apiRef} | ||||
| checkboxSelection={false} | |||||
| checkboxSelection={true} | |||||
| _formKey={"putAwayLines"} | _formKey={"putAwayLines"} | ||||
| columns={columns} | columns={columns} | ||||
| validateRow={validation} | validateRow={validation} | ||||
| @@ -542,6 +544,7 @@ const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled, setRowM | |||||
| showRemoveBtn={false} | showRemoveBtn={false} | ||||
| addRowDefaultValue={addRowDefaultValue} | addRowDefaultValue={addRowDefaultValue} | ||||
| _setRowModesModel={setRowModesModel} | _setRowModesModel={setRowModesModel} | ||||
| _setRowSelectionModel={setRowSelectionModel} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| @@ -21,7 +21,7 @@ import StockInFormVer2 from "./StockInFormVer2"; | |||||
| import QcComponent from "./QcComponent"; | import QcComponent from "./QcComponent"; | ||||
| import { dummyPutAwayLine, dummyQCData } from "./dummyQcTemplate"; | import { dummyPutAwayLine, dummyQCData } from "./dummyQcTemplate"; | ||||
| import PutAwayForm from "./PutAwayForm"; | import PutAwayForm from "./PutAwayForm"; | ||||
| import { GridRowModes, useGridApiRef } from "@mui/x-data-grid"; | |||||
| import { GridRowModes, GridRowSelectionModel, useGridApiRef } from "@mui/x-data-grid"; | |||||
| import {submitDialogWithWarning} from "../Swal/CustomAlerts"; | import {submitDialogWithWarning} from "../Swal/CustomAlerts"; | ||||
| import { INPUT_DATE_FORMAT, arrayToDateString, dayjsToInputDateString } from "@/app/utils/formatUtil"; | import { INPUT_DATE_FORMAT, arrayToDateString, dayjsToInputDateString } from "@/app/utils/formatUtil"; | ||||
| import dayjs from "dayjs"; | import dayjs from "dayjs"; | ||||
| @@ -33,6 +33,7 @@ import { SessionWithTokens } from "@/config/authConfig"; | |||||
| import { GridRowModesModel } from "@mui/x-data-grid"; | import { GridRowModesModel } from "@mui/x-data-grid"; | ||||
| import { isEmpty } from "lodash"; | import { isEmpty } from "lodash"; | ||||
| import { EscalationCombo } from "@/app/api/user"; | import { EscalationCombo } from "@/app/api/user"; | ||||
| import { truncateSync } from "fs"; | |||||
| const style = { | const style = { | ||||
| @@ -103,7 +104,7 @@ const defaultNewValue = useMemo(() => { | |||||
| dnDate: arrayToDateString(itemDetail.dnDate, "input")?? dayjsToInputDateString(dayjs()), | dnDate: arrayToDateString(itemDetail.dnDate, "input")?? dayjsToInputDateString(dayjs()), | ||||
| // putAwayLines: dummyPutAwayLine, | // putAwayLines: dummyPutAwayLine, | ||||
| // putAwayLines: itemDetail.putAwayLines.map((line) => (return {...line, printQty: 1})) ?? [], | // putAwayLines: itemDetail.putAwayLines.map((line) => (return {...line, printQty: 1})) ?? [], | ||||
| putAwayLines: itemDetail.putAwayLines?.map((line) => ({...line, printQty: 1, _isNew: false})) ?? [], | |||||
| putAwayLines: itemDetail.putAwayLines?.map((line) => ({...line, printQty: 1, _isNew: false, _disableDelete: true})) ?? [], | |||||
| // qcResult: (itemDetail.qcResult && itemDetail.qcResult?.length > 0) ? itemDetail.qcResult : [],//[...dummyQCData], | // qcResult: (itemDetail.qcResult && itemDetail.qcResult?.length > 0) ? itemDetail.qcResult : [],//[...dummyQCData], | ||||
| escResult: (itemDetail.escResult && itemDetail.escResult?.length > 0) ? itemDetail.escResult : [], | escResult: (itemDetail.escResult && itemDetail.escResult?.length > 0) ? itemDetail.escResult : [], | ||||
| productionDate: itemDetail.productionDate ? arrayToDateString(itemDetail.productionDate, "input") : undefined, | productionDate: itemDetail.productionDate ? arrayToDateString(itemDetail.productionDate, "input") : undefined, | ||||
| @@ -366,6 +367,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| // Put away model | // Put away model | ||||
| const [pafRowModesModel, setPafRowModesModel] = useState<GridRowModesModel>({}) | const [pafRowModesModel, setPafRowModesModel] = useState<GridRowModesModel>({}) | ||||
| const [pafRowSelectionModel, setPafRowSelectionModel] = useState<GridRowSelectionModel>([]) | |||||
| const pafSubmitDisable = useMemo(() => { | const pafSubmitDisable = useMemo(() => { | ||||
| // console.log("%c mode: ", "background:#90EE90; color:red", Object.entries(pafRowModesModel)) | // console.log("%c mode: ", "background:#90EE90; color:red", Object.entries(pafRowModesModel)) | ||||
| // console.log("%c mode: ", "background:pink; color:#87CEEB", Object.entries(pafRowModesModel)) | // console.log("%c mode: ", "background:pink; color:#87CEEB", Object.entries(pafRowModesModel)) | ||||
| @@ -441,11 +443,14 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| alert("列印數量不正確!"); | alert("列印數量不正確!"); | ||||
| return; | return; | ||||
| } | } | ||||
| // console.log(pafRowSelectionModel) | |||||
| const printList = formProps.watch("putAwayLines")?.filter((line) => ((pafRowSelectionModel ?? []).some((model) => model === line.id))) ?? [] | |||||
| const printQty = printList.reduce((acc, cur) => acc + cur.printQty, 0) | |||||
| // console.log(printQty) | |||||
| const data: PrintQrCodeForSilRequest = { | const data: PrintQrCodeForSilRequest = { | ||||
| stockInLineId: itemDetail.id, | stockInLineId: itemDetail.id, | ||||
| printerId: selectedPrinter.id, | printerId: selectedPrinter.id, | ||||
| printQty: formProps.watch("putAwayLines")?.reduce((acc, cur) => acc + cur.printQty, 0) | |||||
| printQty: printQty | |||||
| } | } | ||||
| const response = await printQrCodeForSil(data); | const response = await printQrCodeForSil(data); | ||||
| if (response) { | if (response) { | ||||
| @@ -454,7 +459,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| } finally { | } finally { | ||||
| setIsPrinting(() => false) | setIsPrinting(() => false) | ||||
| } | } | ||||
| }, [itemDetail.id]); | |||||
| }, [itemDetail.id, pafRowSelectionModel]); | |||||
| const acceptQty = formProps.watch("acceptedQty") | const acceptQty = formProps.watch("acceptedQty") | ||||
| @@ -499,6 +504,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| warehouse={warehouse!} | warehouse={warehouse!} | ||||
| disabled={viewOnly} | disabled={viewOnly} | ||||
| setRowModesModel={setPafRowModesModel} | setRowModesModel={setPafRowModesModel} | ||||
| setRowSelectionModel={setPafRowSelectionModel} | |||||
| /> | /> | ||||
| <Stack direction="row" justifyContent="flex-end" gap={1}> | <Stack direction="row" justifyContent="flex-end" gap={1}> | ||||
| <Autocomplete | <Autocomplete | ||||
| @@ -524,7 +530,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| color="primary" | color="primary" | ||||
| sx={{ mt: 1 }} | sx={{ mt: 1 }} | ||||
| onClick={handlePrint} | onClick={handlePrint} | ||||
| disabled={isPrinting || printerCombo.length <= 0} | |||||
| disabled={isPrinting || printerCombo.length <= 0 || pafSubmitDisable} | |||||
| > | > | ||||
| {isPrinting ? t("Printing") : t("print")} | {isPrinting ? t("Printing") : t("print")} | ||||
| </Button> | </Button> | ||||