@@ -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<ProductProcessListProps> = ({
onSelectProcess,
printerCombo,
@@ -191,6 +192,8 @@ const ProductProcessList: React.FC<ProductProcessListProps> = ({
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<ProductProcessListProps> = ({
() => printerOptions[0] ?? null,
);
const printInFlightRef = useRef(false);
const loadSeqRef = useRef(0);
const hasLoadedOnceRef = useRef(false);
const [printingSilId, setPrintingSilId] = useState<number | null>(null);
useEffect(() => {
@@ -328,6 +333,7 @@ const ProductProcessList: React.FC<ProductProcessListProps> = ({
const handleApplySearch = useCallback(
(inputs: Record<SearchParam | `${SearchParam}To`, string>) => {
const selectedProcessType = (inputs.processType || "all") as ProcessFilter;
setListReloadKey((k) => k + 1);
onListPersistedStateChange((prev) => ({
...prev,
filter: selectedProcessType,
@@ -342,6 +348,7 @@ const ProductProcessList: React.FC<ProductProcessListProps> = ({
);
const handleResetSearch = useCallback(() => {
setListReloadKey((k) => k + 1);
onListPersistedStateChange((prev) => ({
...prev,
filter: "all",
@@ -355,8 +362,10 @@ const ProductProcessList: React.FC<ProductProcessListProps> = ({
}, [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<ProductProcessListProps> = ({
}),
]);
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<ProductProcessListProps> = ({
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<ProductProcessListProps> = ({
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<ProductProcessListProps> = ({
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) => {