| @@ -1,5 +1,5 @@ | |||||
| "use client"; | "use client"; | ||||
| import React, { useState, useEffect, useCallback, useRef } from "react"; | |||||
| import React, { useState, useEffect, useCallback, useMemo, useRef } from "react"; | |||||
| import { | import { | ||||
| Box, | Box, | ||||
| Typography, | Typography, | ||||
| @@ -209,12 +209,32 @@ const DrinkProductionQtyDashboard: React.FC = () => { | |||||
| }); | }); | ||||
| }; | }; | ||||
| const filterJobOrders = ( | |||||
| jobOrders: DrinkProductionQtyJobOrderDetail[], | |||||
| ): DrinkProductionQtyJobOrderDetail[] => { | |||||
| if (!joStatusFilter) return jobOrders; | |||||
| return jobOrders.filter((jo) => jo.jobOrderStatus === joStatusFilter); | |||||
| }; | |||||
| const filteredItemRows = useMemo(() => { | |||||
| const rows: Array<{ | |||||
| row: DrinkProductionQtyResponse; | |||||
| jobOrders: DrinkProductionQtyJobOrderDetail[]; | |||||
| totalReqQty: number; | |||||
| totalQty: number; | |||||
| }> = []; | |||||
| for (const row of data) { | |||||
| const allJobOrders = row.jobOrders ?? []; | |||||
| const jobOrders = joStatusFilter | |||||
| ? allJobOrders.filter((jo) => jo.jobOrderStatus === joStatusFilter) | |||||
| : allJobOrders; | |||||
| if (joStatusFilter && jobOrders.length === 0) continue; | |||||
| rows.push({ | |||||
| row, | |||||
| jobOrders, | |||||
| totalReqQty: joStatusFilter | |||||
| ? jobOrders.reduce((sum, jo) => sum + (jo.reqQty ?? 0), 0) | |||||
| : row.totalReqQty, | |||||
| totalQty: joStatusFilter | |||||
| ? jobOrders.reduce((sum, jo) => sum + (jo.productionQty ?? 0), 0) | |||||
| : row.totalQty, | |||||
| }); | |||||
| } | |||||
| return rows; | |||||
| }, [data, joStatusFilter]); | |||||
| const renderActualEnd = (jo: DrinkProductionQtyJobOrderDetail) => { | const renderActualEnd = (jo: DrinkProductionQtyJobOrderDetail) => { | ||||
| const start = parseProcessTime(jo.startTime); | const start = parseProcessTime(jo.startTime); | ||||
| @@ -611,7 +631,7 @@ const DrinkProductionQtyDashboard: React.FC = () => { | |||||
| ); | ); | ||||
| }) | }) | ||||
| ) | ) | ||||
| ) : data.length === 0 ? ( | |||||
| ) : filteredItemRows.length === 0 ? ( | |||||
| <TableRow> | <TableRow> | ||||
| <TableCell colSpan={6} align="center"> | <TableCell colSpan={6} align="center"> | ||||
| <Typography | <Typography | ||||
| @@ -623,14 +643,10 @@ const DrinkProductionQtyDashboard: React.FC = () => { | |||||
| </TableCell> | </TableCell> | ||||
| </TableRow> | </TableRow> | ||||
| ) : ( | ) : ( | ||||
| data.map((row, idx) => { | |||||
| filteredItemRows.map(({ row, jobOrders, totalReqQty, totalQty }, idx) => { | |||||
| const rowKey = getRowKey(row, idx); | const rowKey = getRowKey(row, idx); | ||||
| const allJobOrders = row.jobOrders ?? []; | |||||
| const jobOrders = filterJobOrders(allJobOrders); | |||||
| const isExpanded = expandedRowKeys.has(rowKey); | const isExpanded = expandedRowKeys.has(rowKey); | ||||
| const hasExpandable = | |||||
| allJobOrders.length > 0 && | |||||
| (joStatusFilter === "" || jobOrders.length > 0); | |||||
| const hasExpandable = jobOrders.length > 0; | |||||
| return ( | return ( | ||||
| <React.Fragment key={rowKey}> | <React.Fragment key={rowKey}> | ||||
| @@ -671,12 +687,12 @@ const DrinkProductionQtyDashboard: React.FC = () => { | |||||
| </TableCell> | </TableCell> | ||||
| <TableCell align="right"> | <TableCell align="right"> | ||||
| <Typography variant="body2"> | <Typography variant="body2"> | ||||
| {formatQty(row.totalReqQty)} | |||||
| {formatQty(totalReqQty)} | |||||
| </Typography> | </Typography> | ||||
| </TableCell> | </TableCell> | ||||
| <TableCell align="right"> | <TableCell align="right"> | ||||
| <Typography variant="body2"> | <Typography variant="body2"> | ||||
| {formatQty(row.totalQty)} | |||||
| {formatQty(totalQty)} | |||||
| </Typography> | </Typography> | ||||
| </TableCell> | </TableCell> | ||||
| </TableRow> | </TableRow> | ||||