diff --git a/src/components/ProductionProcess/ProductionProcessList.tsx b/src/components/ProductionProcess/ProductionProcessList.tsx index 665d6ba9..38667525 100644 --- a/src/components/ProductionProcess/ProductionProcessList.tsx +++ b/src/components/ProductionProcess/ProductionProcessList.tsx @@ -29,6 +29,7 @@ import { import ChevronLeft from "@mui/icons-material/ChevronLeft"; import ChevronRight from "@mui/icons-material/ChevronRight"; import { useTranslation } from "react-i18next"; +import type { StockInLine } from "@/app/api/stockIn"; import { fetchItemForPutAway } from "@/app/api/stockIn/actions"; import QcStockInModal from "../Qc/QcStockInModal"; import { useSession } from "next-auth/react"; @@ -178,7 +179,7 @@ function isWaitingQcPutAway( return s !== "completed" && s !== "rejected"; } -/** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.9 | 2026-08-10 */ +/** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.10 | 2026-10-15 */ const ProductProcessList: React.FC = ({ onSelectProcess, printerCombo, @@ -191,6 +192,8 @@ const ProductProcessList: React.FC = ({ const { data: session } = useSession() as { data: SessionWithTokens | null }; const sessionToken = session as SessionWithTokens | null; const [loading, setLoading] = useState(false); + /** Bumps on Search/Reset so the same criteria still refetch. */ + const [listReloadKey, setListReloadKey] = useState(0); const [productionCache, setProductionCache] = useState< AllJoborderProductProcessInfoResponse[] >([]); @@ -234,6 +237,8 @@ const ProductProcessList: React.FC = ({ () => printerOptions[0] ?? null, ); const printInFlightRef = useRef(false); + const loadSeqRef = useRef(0); + const hasLoadedOnceRef = useRef(false); const [printingSilId, setPrintingSilId] = useState(null); useEffect(() => { @@ -328,6 +333,7 @@ const ProductProcessList: React.FC = ({ const handleApplySearch = useCallback( (inputs: Record) => { const selectedProcessType = (inputs.processType || "all") as ProcessFilter; + setListReloadKey((k) => k + 1); onListPersistedStateChange((prev) => ({ ...prev, filter: selectedProcessType, @@ -342,6 +348,7 @@ const ProductProcessList: React.FC = ({ ); const handleResetSearch = useCallback(() => { + setListReloadKey((k) => k + 1); onListPersistedStateChange((prev) => ({ ...prev, filter: "all", @@ -355,8 +362,10 @@ const ProductProcessList: React.FC = ({ }, [disableDateFilter, onListPersistedStateChange]); /** Load all tab datasets once per search; tab switches use cache only. */ - const loadAllCaches = useCallback(async () => { - setLoading(true); + const loadAllCaches = useCallback(async (options?: { silent?: boolean }) => { + const silent = options?.silent === true; + const seq = ++loadSeqRef.current; + if (!silent) setLoading(true); try { const typeParam = filter === "all" ? undefined : filter; const base = { @@ -391,6 +400,8 @@ const ProductProcessList: React.FC = ({ }), ]); + if (seq !== loadSeqRef.current) return; + const prodContent = (prod?.content || []).filter((p) => !isPutawayCompleted(p)); const qcContent = (pendingQc?.content || []).filter((p) => !isPutawayCompleted(p)); const putawayContent = putawayed?.content || []; @@ -405,6 +416,7 @@ const ProductProcessList: React.FC = ({ setCarriedOverCount(prod?.carriedOverCount ?? 0); } catch (e) { console.error(e); + if (seq !== loadSeqRef.current || silent) return; setProductionCache([]); setPendingQcCache([]); setPutawayedCache([]); @@ -413,12 +425,14 @@ const ProductProcessList: React.FC = ({ setPutawayedCount(0); setCarriedOverCount(0); } finally { - setLoading(false); + if (seq === loadSeqRef.current) setLoading(false); } - }, [appliedSearch, disableDateFilter, filter]); + }, [appliedSearch, disableDateFilter, filter, listReloadKey]); useEffect(() => { - void loadAllCaches(); + const silent = hasLoadedOnceRef.current; + hasLoadedOnceRef.current = true; + void loadAllCaches(silent ? { silent: true } : undefined); }, [loadAllCaches]); const offPlanRows = useMemo(() => { @@ -670,9 +684,12 @@ const ProductProcessList: React.FC = ({ closeConfirm(); } }, [pendingConfirmAction, closeConfirm]); - const closeNewModal = useCallback(() => { + const closeNewModal = useCallback((updatedStockInLine?: StockInLine) => { setOpenModal(false); - }, []); + if (updatedStockInLine) { + void loadAllCaches({ silent: true }); + } + }, [loadAllCaches]); const handlePrintLabel = useCallback( async (process: AllJoborderProductProcessInfoResponse) => { diff --git a/src/components/Qc/QcStockInModal.tsx b/src/components/Qc/QcStockInModal.tsx index b38d37dd..719cf04e 100644 --- a/src/components/Qc/QcStockInModal.tsx +++ b/src/components/Qc/QcStockInModal.tsx @@ -583,10 +583,10 @@ const QcStockInModal: React.FC = ({ } - closeWithResult(qcRes); + closeWithResult(qcRes ?? stockInLineInfo); // setTabIndex(1); // Need to go Putaway tab? } else { - closeWithResult(qcRes); + closeWithResult(qcRes ?? stockInLineInfo); } setIsSubmitting(false); qcSubmitInFlightRef.current = false; @@ -666,11 +666,12 @@ const QcStockInModal: React.FC = ({ // Handle putaway submission logic here const res = await postStockInLine(putawayData); console.log("result ", res); - - // Close modal after successful putaway - closeHandler({}, "backdropClick"); + const updated = Array.isArray(res.entity) ? res.entity[0] : res.entity; + + // Close modal after successful putaway and tell the parent to refresh. + closeWithResult(updated ?? stockInLineInfo); }, - [closeHandler], + [closeWithResult, postStockInLine, stockInLineInfo], ); // Print handler useEffect(() => {