FPSMS-frontend
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

785 line
22 KiB

  1. "use client";
  2. import {
  3. FooterPropsOverrides,
  4. GridActionsCellItem,
  5. GridCellParams,
  6. GridRowId,
  7. GridRowIdGetter,
  8. GridRowModel,
  9. GridRowModes,
  10. GridRowModesModel,
  11. GridToolbarContainer,
  12. useGridApiRef,
  13. } from "@mui/x-data-grid";
  14. import {
  15. Dispatch,
  16. MutableRefObject,
  17. SetStateAction,
  18. useCallback,
  19. useEffect,
  20. useMemo,
  21. useState,
  22. } from "react";
  23. import StyledDataGrid from "../StyledDataGrid";
  24. import { GridColDef } from "@mui/x-data-grid";
  25. import { Box, Button, Grid, Typography } from "@mui/material";
  26. import { useTranslation } from "react-i18next";
  27. import { Add } from "@mui/icons-material";
  28. import SaveIcon from "@mui/icons-material/Save";
  29. import DeleteIcon from "@mui/icons-material/Delete";
  30. import CancelIcon from "@mui/icons-material/Cancel";
  31. import FactCheckIcon from "@mui/icons-material/FactCheck";
  32. import ShoppingCartIcon from "@mui/icons-material/ShoppingCart";
  33. import { QcItemWithChecks } from "src/app/api/qc";
  34. import PlayArrowIcon from "@mui/icons-material/PlayArrow";
  35. import { PurchaseOrderLine, StockInLine } from "@/app/api/po";
  36. import { createStockInLine, PurchaseQcResult } from "@/app/api/po/actions";
  37. import { useSearchParams } from "next/navigation";
  38. import {
  39. returnWeightUnit,
  40. calculateWeight,
  41. stockInLineStatusMap,
  42. } from "@/app/utils/formatUtil";
  43. // import PoQcStockInModal from "./PoQcStockInModal";
  44. import NotificationImportantIcon from "@mui/icons-material/NotificationImportant";
  45. import { WarehouseResult } from "@/app/api/warehouse";
  46. import LooksOneIcon from "@mui/icons-material/LooksOne";
  47. import LooksTwoIcon from "@mui/icons-material/LooksTwo";
  48. import Looks3Icon from "@mui/icons-material/Looks3";
  49. import axiosInstance from "@/app/(main)/axios/axiosInstance";
  50. // import axios, { AxiosRequestConfig } from "axios";
  51. import { BASE_API_URL, NEXT_PUBLIC_API_URL } from "@/config/api";
  52. import qs from "qs";
  53. import QrCodeIcon from "@mui/icons-material/QrCode";
  54. import { downloadFile } from "@/app/utils/commonUtil";
  55. import { fetchPoQrcode } from "@/app/api/pdf/actions";
  56. import { fetchQcResult } from "@/app/api/qc/actions";
  57. import PoQcStockInModal from "./PoQcStockInModal"
  58. import DoDisturbIcon from "@mui/icons-material/DoDisturb";
  59. interface ResultWithId {
  60. id: number;
  61. }
  62. interface Props {
  63. qc: QcItemWithChecks[];
  64. setRows: Dispatch<SetStateAction<PurchaseOrderLine[]>>;
  65. setStockInLine: Dispatch<SetStateAction<StockInLine[]>>;
  66. setProcessedQty: Dispatch<SetStateAction<number>>;
  67. itemDetail: PurchaseOrderLine;
  68. stockInLine: StockInLine[];
  69. warehouse: WarehouseResult[];
  70. }
  71. export type StockInLineEntryError = {
  72. [field in keyof StockInLine]?: string;
  73. };
  74. export type StockInLineRow = Partial<
  75. StockInLine & {
  76. isActive: boolean | undefined;
  77. _isNew: boolean;
  78. _error: StockInLineEntryError;
  79. } & ResultWithId
  80. >;
  81. class ProcessRowUpdateError extends Error {
  82. public readonly row: StockInLineRow;
  83. public readonly errors: StockInLineEntryError | undefined;
  84. constructor(
  85. row: StockInLineRow,
  86. message?: string,
  87. errors?: StockInLineEntryError
  88. ) {
  89. super(message);
  90. this.row = row;
  91. this.errors = errors;
  92. Object.setPrototypeOf(this, ProcessRowUpdateError.prototype);
  93. }
  94. }
  95. function PoInputGrid({
  96. qc,
  97. setRows,
  98. setStockInLine,
  99. setProcessedQty,
  100. itemDetail,
  101. stockInLine,
  102. warehouse,
  103. }: Props) {
  104. console.log(itemDetail);
  105. const { t } = useTranslation("home");
  106. const apiRef = useGridApiRef();
  107. const [rowModesModel, setRowModesModel] = useState<GridRowModesModel>({});
  108. const getRowId = useCallback<GridRowIdGetter<StockInLineRow>>(
  109. (row) => row.id as number,
  110. []
  111. );
  112. console.log(stockInLine);
  113. const [entries, setEntries] = useState<StockInLineRow[]>(stockInLine || []);
  114. const [modalInfo, setModalInfo] = useState<
  115. StockInLine & { qcResult?: PurchaseQcResult[] }
  116. >();
  117. const [qcOpen, setQcOpen] = useState(false);
  118. const [escalOpen, setEscalOpen] = useState(false);
  119. const [stockInOpen, setStockInOpen] = useState(false);
  120. const [putAwayOpen, setPutAwayOpen] = useState(false);
  121. const [rejectOpen, setRejectOpen] = useState(false);
  122. const [btnIsLoading, setBtnIsLoading] = useState(false);
  123. const [currQty, setCurrQty] = useState(() => {
  124. const total = entries.reduce(
  125. (acc, curr) => acc + (curr.acceptedQty || 0),
  126. 0
  127. );
  128. return total;
  129. });
  130. useEffect(() => {
  131. const completedList = entries.filter((e) => e.status === "completed");
  132. const processedQty = completedList.reduce(
  133. (acc, curr) => acc + (curr.acceptedQty || 0),
  134. 0
  135. );
  136. setProcessedQty(processedQty);
  137. }, [entries]);
  138. const handleDelete = useCallback(
  139. (id: GridRowId) => () => {
  140. setEntries((es) => es.filter((e) => getRowId(e) !== id));
  141. },
  142. [getRowId]
  143. );
  144. const handleStart = useCallback(
  145. (id: GridRowId, params: any) => () => {
  146. setBtnIsLoading(true);
  147. setRowModesModel((prev) => ({
  148. ...prev,
  149. [id]: { mode: GridRowModes.View },
  150. }));
  151. setTimeout(async () => {
  152. // post stock in line
  153. const oldId = params.row.id;
  154. const postData = {
  155. itemId: params.row.itemId,
  156. itemNo: params.row.itemNo,
  157. itemName: params.row.itemName,
  158. purchaseOrderId: params.row.purchaseOrderId,
  159. purchaseOrderLineId: params.row.purchaseOrderLineId,
  160. acceptedQty: params.row.acceptedQty,
  161. };
  162. const res = await createStockInLine(postData);
  163. console.log(res);
  164. setEntries((prev) =>
  165. prev.map((p) => (p.id === oldId ? (res.entity as StockInLine) : p))
  166. );
  167. setStockInLine(
  168. (prev) =>
  169. prev.map((p) =>
  170. p.id === oldId ? (res.entity as StockInLine) : p
  171. ) as StockInLine[]
  172. );
  173. setBtnIsLoading(false);
  174. // do post directly to test
  175. // openStartModal();
  176. }, 200);
  177. },
  178. [createStockInLine]
  179. );
  180. const fetchQcDefaultValue = useCallback(async (stockInLineId: GridRowId) => {
  181. return await fetchQcResult(stockInLineId as number);
  182. }, []);
  183. const handleQC = useCallback(
  184. (id: GridRowId, params: any) => async () => {
  185. setBtnIsLoading(true);
  186. setRowModesModel((prev) => ({
  187. ...prev,
  188. [id]: { mode: GridRowModes.View },
  189. }));
  190. const qcResult = await fetchQcDefaultValue(id);
  191. console.log(params.row);
  192. console.log(qcResult);
  193. setModalInfo({
  194. ...params.row,
  195. qcResult: qcResult,
  196. });
  197. // set default values
  198. setTimeout(() => {
  199. // open qc modal
  200. console.log("delayed");
  201. openQcModal();
  202. setBtnIsLoading(false);
  203. }, 200);
  204. },
  205. [fetchQcDefaultValue]
  206. );
  207. const handleEscalation = useCallback(
  208. (id: GridRowId, params: any) => () => {
  209. // setBtnIsLoading(true);
  210. setRowModesModel((prev) => ({
  211. ...prev,
  212. [id]: { mode: GridRowModes.View },
  213. }));
  214. setModalInfo(params.row);
  215. setTimeout(() => {
  216. // open qc modal
  217. console.log("delayed");
  218. openEscalationModal();
  219. // setBtnIsLoading(false);
  220. }, 200);
  221. },
  222. []
  223. );
  224. const handleReject = useCallback(
  225. (id: GridRowId, params: any) => () => {
  226. setRowModesModel((prev) => ({
  227. ...prev,
  228. [id]: { mode: GridRowModes.View },
  229. }));
  230. setModalInfo(params.row);
  231. setTimeout(() => {
  232. // open stock in modal
  233. // openPutAwayModal();
  234. // return the record with its status as pending
  235. // update layout
  236. console.log("delayed");
  237. openRejectModal();
  238. // printQrcode(params.row);
  239. }, 200);
  240. },
  241. []
  242. );
  243. const handleStockIn = useCallback(
  244. (id: GridRowId, params: any) => () => {
  245. // setBtnIsLoading(true);
  246. setRowModesModel((prev) => ({
  247. ...prev,
  248. [id]: { mode: GridRowModes.View },
  249. }));
  250. setModalInfo(params.row);
  251. setTimeout(() => {
  252. // open stock in modal
  253. openStockInModal();
  254. // return the record with its status as pending
  255. // update layout
  256. console.log("delayed");
  257. // setBtnIsLoading(false);
  258. }, 200);
  259. },
  260. []
  261. );
  262. const handlePutAway = useCallback(
  263. (id: GridRowId, params: any) => () => {
  264. // setBtnIsLoading(true);
  265. setRowModesModel((prev) => ({
  266. ...prev,
  267. [id]: { mode: GridRowModes.View },
  268. }));
  269. setModalInfo(params.row);
  270. setTimeout(() => {
  271. // open stock in modal
  272. openPutAwayModal();
  273. // return the record with its status as pending
  274. // update layout
  275. console.log("delayed");
  276. // setBtnIsLoading(false);
  277. }, 200);
  278. },
  279. []
  280. );
  281. const printQrcode = useCallback(
  282. async (row: any) => {
  283. setBtnIsLoading(true);
  284. console.log(row.id);
  285. const postData = { stockInLineIds: [row.id] };
  286. // const postData = { stockInLineIds: [42,43,44] };
  287. const response = await fetchPoQrcode(postData);
  288. if (response) {
  289. console.log(response);
  290. downloadFile(new Uint8Array(response.blobValue), response.filename!!);
  291. }
  292. setBtnIsLoading(false);
  293. },
  294. [fetchPoQrcode, downloadFile]
  295. );
  296. const handleQrCode = useCallback(
  297. (id: GridRowId, params: any) => () => {
  298. setRowModesModel((prev) => ({
  299. ...prev,
  300. [id]: { mode: GridRowModes.View },
  301. }));
  302. setModalInfo(params.row);
  303. setTimeout(() => {
  304. // open stock in modal
  305. // openPutAwayModal();
  306. // return the record with its status as pending
  307. // update layout
  308. console.log("delayed");
  309. printQrcode(params.row);
  310. }, 200);
  311. },
  312. []
  313. );
  314. const closeQcModal = useCallback(() => {
  315. setQcOpen(false);
  316. }, []);
  317. const openQcModal = useCallback(() => {
  318. setQcOpen(true);
  319. }, []);
  320. const closeStockInModal = useCallback(() => {
  321. setStockInOpen(false);
  322. }, []);
  323. const openStockInModal = useCallback(() => {
  324. setStockInOpen(true);
  325. }, []);
  326. const closePutAwayModal = useCallback(() => {
  327. setPutAwayOpen(false);
  328. }, []);
  329. const openPutAwayModal = useCallback(() => {
  330. setPutAwayOpen(true);
  331. }, []);
  332. const closeEscalationModal = useCallback(() => {
  333. setEscalOpen(false);
  334. }, []);
  335. const openEscalationModal = useCallback(() => {
  336. setEscalOpen(true);
  337. }, []);
  338. const closeRejectModal = useCallback(() => {
  339. setRejectOpen(false);
  340. }, []);
  341. const openRejectModal = useCallback(() => {
  342. setRejectOpen(true);
  343. }, []);
  344. const columns = useMemo<GridColDef[]>(
  345. () => [
  346. {
  347. field: "itemNo",
  348. flex: 0.4,
  349. },
  350. {
  351. field: "itemName",
  352. flex: 0.6,
  353. },
  354. {
  355. field: "acceptedQty",
  356. headerName: "qty",
  357. flex: 0.5,
  358. type: "number",
  359. editable: true,
  360. // replace with tooltip + content
  361. },
  362. {
  363. field: "uom",
  364. headerName: "uom",
  365. flex: 0.5,
  366. renderCell: (params) => {
  367. return params.row.uom.code;
  368. },
  369. },
  370. {
  371. field: "weight",
  372. headerName: "weight",
  373. flex: 0.5,
  374. renderCell: (params) => {
  375. const weight = calculateWeight(
  376. params.row.acceptedQty,
  377. params.row.uom
  378. );
  379. const weightUnit = returnWeightUnit(params.row.uom);
  380. return `${weight} ${weightUnit}`;
  381. },
  382. },
  383. {
  384. field: "status",
  385. flex: 0.5,
  386. // editable: true,
  387. },
  388. {
  389. field: "actions",
  390. type: "actions",
  391. headerName: "start | qc | escalation | stock in | putaway | delete",
  392. flex: 1.5,
  393. cellClassName: "actions",
  394. getActions: (params) => {
  395. console.log(params.row.status);
  396. const status = params.row.status.toLowerCase();
  397. return [
  398. <GridActionsCellItem
  399. icon={<PlayArrowIcon />}
  400. label="start"
  401. sx={{
  402. color: "primary.main",
  403. // marginRight: 1,
  404. }}
  405. disabled={!(stockInLineStatusMap[status] === 0)}
  406. // set _isNew to false after posting
  407. // or check status
  408. onClick={handleStart(params.row.id, params)}
  409. color="inherit"
  410. key="edit"
  411. />,
  412. <GridActionsCellItem
  413. icon={<FactCheckIcon />}
  414. label="qc"
  415. sx={{
  416. color: "primary.main",
  417. // marginRight: 1,
  418. }}
  419. disabled={
  420. // stockInLineStatusMap[status] === 9 ||
  421. stockInLineStatusMap[status] < 1
  422. }
  423. // set _isNew to false after posting
  424. // or check status
  425. onClick={handleQC(params.row.id, params)}
  426. color="inherit"
  427. key="edit"
  428. />,
  429. <GridActionsCellItem
  430. icon={<NotificationImportantIcon />}
  431. label="escalation"
  432. sx={{
  433. color: "primary.main",
  434. // marginRight: 1,
  435. }}
  436. disabled={
  437. stockInLineStatusMap[status] === 9 ||
  438. stockInLineStatusMap[status] <= 0 ||
  439. stockInLineStatusMap[status] >= 5
  440. }
  441. // set _isNew to false after posting
  442. // or check status
  443. onClick={handleEscalation(params.row.id, params)}
  444. color="inherit"
  445. key="edit"
  446. />,
  447. <GridActionsCellItem
  448. icon={<ShoppingCartIcon />}
  449. label="stockin"
  450. sx={{
  451. color: "primary.main",
  452. // marginRight: 1,
  453. }}
  454. disabled={
  455. stockInLineStatusMap[status] === 9 ||
  456. stockInLineStatusMap[status] <= 2 ||
  457. stockInLineStatusMap[status] >= 7
  458. }
  459. // set _isNew to false after posting
  460. // or check status
  461. onClick={handleStockIn(params.row.id, params)}
  462. color="inherit"
  463. key="edit"
  464. />,
  465. <GridActionsCellItem
  466. icon={<ShoppingCartIcon />}
  467. label="putaway"
  468. sx={{
  469. color: "primary.main",
  470. // marginRight: 1,
  471. }}
  472. disabled={stockInLineStatusMap[status] === 9 || stockInLineStatusMap[status] < 7}
  473. // set _isNew to false after posting
  474. // or check status
  475. onClick={handlePutAway(params.row.id, params)}
  476. color="inherit"
  477. key="edit"
  478. />,
  479. <GridActionsCellItem
  480. icon={<QrCodeIcon />}
  481. label="putaway"
  482. sx={{
  483. color: "primary.main",
  484. // marginRight: 1,
  485. }}
  486. disabled={stockInLineStatusMap[status] === 9 || stockInLineStatusMap[status] !== 8}
  487. // set _isNew to false after posting
  488. // or check status
  489. onClick={handleQrCode(params.row.id, params)}
  490. color="inherit"
  491. key="edit"
  492. />,
  493. <GridActionsCellItem
  494. icon={
  495. stockInLineStatusMap[status] >= 1 ? (
  496. <DoDisturbIcon />
  497. ) : (
  498. <DeleteIcon />
  499. )
  500. }
  501. label="Delete"
  502. sx={{
  503. color: "error.main",
  504. }}
  505. disabled={
  506. stockInLineStatusMap[status] >= 7 &&
  507. stockInLineStatusMap[status] <= 9
  508. }
  509. onClick={
  510. stockInLineStatusMap[status] === 0
  511. ? handleDelete(params.row.id)
  512. : handleReject(params.row.id, params)
  513. }
  514. color="inherit"
  515. key="edit"
  516. />,
  517. ];
  518. },
  519. },
  520. ],
  521. [stockInLineStatusMap, btnIsLoading, handleQrCode, handleReject]
  522. );
  523. const addRow = useCallback(() => {
  524. console.log(itemDetail);
  525. const newEntry = {
  526. id: Date.now(),
  527. _isNew: true,
  528. itemId: itemDetail.itemId,
  529. purchaseOrderId: itemDetail.purchaseOrderId,
  530. purchaseOrderLineId: itemDetail.id,
  531. itemNo: itemDetail.itemNo,
  532. itemName: itemDetail.itemName,
  533. acceptedQty: itemDetail.qty - currQty, // this bug
  534. uom: itemDetail.uom,
  535. status: "draft",
  536. };
  537. setEntries((e) => [...e, newEntry]);
  538. setRowModesModel((model) => ({
  539. ...model,
  540. [getRowId(newEntry)]: {
  541. mode: GridRowModes.Edit,
  542. // fieldToFocus: "projectId",
  543. },
  544. }));
  545. }, [currQty, getRowId]);
  546. const validation = useCallback(
  547. (
  548. newRow: GridRowModel<StockInLineRow>
  549. // rowModel: GridRowSelectionModel
  550. ): StockInLineEntryError | undefined => {
  551. const error: StockInLineEntryError = {};
  552. console.log(newRow);
  553. console.log(currQty);
  554. if (newRow.acceptedQty && newRow.acceptedQty > itemDetail.qty) {
  555. error["acceptedQty"] = "qty cannot be greater than remaining qty";
  556. }
  557. return Object.keys(error).length > 0 ? error : undefined;
  558. },
  559. [currQty]
  560. );
  561. const processRowUpdate = useCallback(
  562. (
  563. newRow: GridRowModel<StockInLineRow>,
  564. originalRow: GridRowModel<StockInLineRow>
  565. ) => {
  566. const errors = validation(newRow); // change to validation
  567. if (errors) {
  568. throw new ProcessRowUpdateError(
  569. originalRow,
  570. "validation error",
  571. errors
  572. );
  573. }
  574. const { _isNew, _error, ...updatedRow } = newRow;
  575. const rowToSave = {
  576. ...updatedRow,
  577. } satisfies StockInLineRow;
  578. const newEntries = entries.map((e) =>
  579. getRowId(e) === getRowId(originalRow) ? rowToSave : e
  580. );
  581. setStockInLine(newEntries as StockInLine[]);
  582. console.log("triggered");
  583. setEntries(newEntries);
  584. //update remaining qty
  585. const total = newEntries.reduce(
  586. (acc, curr) => acc + (curr.acceptedQty || 0),
  587. 0
  588. );
  589. setCurrQty(total);
  590. return rowToSave;
  591. },
  592. [getRowId, entries]
  593. );
  594. const onProcessRowUpdateError = useCallback(
  595. (updateError: ProcessRowUpdateError) => {
  596. const errors = updateError.errors;
  597. const oldRow = updateError.row;
  598. apiRef.current.updateRows([{ ...oldRow, _error: errors }]);
  599. },
  600. [apiRef]
  601. );
  602. const footer = (
  603. <Box display="flex" gap={2} alignItems="center">
  604. <Button
  605. disableRipple
  606. variant="outlined"
  607. startIcon={<Add />}
  608. disabled={itemDetail.qty - currQty <= 0}
  609. onClick={addRow}
  610. size="small"
  611. >
  612. {t("Record pol")}
  613. </Button>
  614. </Box>
  615. );
  616. return (
  617. <>
  618. <StyledDataGrid
  619. getRowId={getRowId}
  620. apiRef={apiRef}
  621. autoHeight
  622. sx={{
  623. "--DataGrid-overlayHeight": "100px",
  624. ".MuiDataGrid-row .MuiDataGrid-cell.hasError": {
  625. border: "1px solid",
  626. borderColor: "error.main",
  627. },
  628. ".MuiDataGrid-row .MuiDataGrid-cell.hasWarning": {
  629. border: "1px solid",
  630. borderColor: "warning.main",
  631. },
  632. }}
  633. disableColumnMenu
  634. editMode="row"
  635. rows={entries}
  636. rowModesModel={rowModesModel}
  637. onRowModesModelChange={setRowModesModel}
  638. processRowUpdate={processRowUpdate}
  639. onProcessRowUpdateError={onProcessRowUpdateError}
  640. columns={columns}
  641. isCellEditable={(params) => {
  642. const status = params.row.status.toLowerCase();
  643. return (
  644. stockInLineStatusMap[status] >= 0 ||
  645. stockInLineStatusMap[status] <= 1
  646. );
  647. }}
  648. getCellClassName={(params: GridCellParams<StockInLineRow>) => {
  649. let classname = "";
  650. if (params.row._error) {
  651. classname = "hasError";
  652. }
  653. return classname;
  654. }}
  655. slots={{
  656. footer: FooterToolbar,
  657. noRowsOverlay: NoRowsOverlay,
  658. }}
  659. slotProps={{
  660. footer: { child: footer },
  661. }}
  662. />
  663. {modalInfo !== undefined && (
  664. <>
  665. <PoQcStockInModal
  666. type={"qc"}
  667. // setRows={setRows}
  668. setEntries={setEntries}
  669. setStockInLine={setStockInLine}
  670. setItemDetail={setModalInfo}
  671. qc={qc}
  672. open={qcOpen}
  673. onClose={closeQcModal}
  674. itemDetail={modalInfo}
  675. />
  676. </>
  677. )}
  678. {modalInfo !== undefined && (
  679. <>
  680. <PoQcStockInModal
  681. type={"escalation"}
  682. // setRows={setRows}
  683. setEntries={setEntries}
  684. setStockInLine={setStockInLine}
  685. setItemDetail={setModalInfo}
  686. // qc={qc}
  687. open={escalOpen}
  688. onClose={closeEscalationModal}
  689. itemDetail={modalInfo}
  690. />
  691. </>
  692. )}
  693. {modalInfo !== undefined && (
  694. <>
  695. <PoQcStockInModal
  696. type={"reject"}
  697. // setRows={setRows}
  698. setEntries={setEntries}
  699. setStockInLine={setStockInLine}
  700. setItemDetail={setModalInfo}
  701. // qc={qc}
  702. open={rejectOpen}
  703. onClose={closeRejectModal}
  704. itemDetail={modalInfo}
  705. />
  706. </>
  707. )}
  708. {modalInfo !== undefined && (
  709. <>
  710. <PoQcStockInModal
  711. type={"stockIn"}
  712. // setRows={setRows}
  713. setEntries={setEntries}
  714. setStockInLine={setStockInLine}
  715. // qc={qc}
  716. setItemDetail={setModalInfo}
  717. open={stockInOpen}
  718. onClose={closeStockInModal}
  719. itemDetail={modalInfo}
  720. />
  721. </>
  722. )}
  723. {modalInfo !== undefined && (
  724. <>
  725. <PoQcStockInModal
  726. type={"putaway"}
  727. // setRows={setRows}
  728. setEntries={setEntries}
  729. setStockInLine={setStockInLine}
  730. setItemDetail={setModalInfo}
  731. open={putAwayOpen}
  732. warehouse={warehouse}
  733. onClose={closePutAwayModal}
  734. itemDetail={modalInfo}
  735. />
  736. </>
  737. )}
  738. </>
  739. );
  740. }
  741. const NoRowsOverlay: React.FC = () => {
  742. const { t } = useTranslation("home");
  743. return (
  744. <Box
  745. display="flex"
  746. justifyContent="center"
  747. alignItems="center"
  748. height="100%"
  749. >
  750. <Typography variant="caption">{t("Add some entries!")}</Typography>
  751. </Box>
  752. );
  753. };
  754. const FooterToolbar: React.FC<FooterPropsOverrides> = ({ child }) => {
  755. return <GridToolbarContainer sx={{ p: 2 }}>{child}</GridToolbarContainer>;
  756. };
  757. export default PoInputGrid;