From c77bc752ae3a02206634937284bc0bf8fe391511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Faleiros?= Date: Thu, 27 Aug 2026 20:02:51 -0300 Subject: [PATCH] Improve production order preview selection --- src/pages/Cutting.tsx | 71 ++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/src/pages/Cutting.tsx b/src/pages/Cutting.tsx index a8ce0b2..e1af39a 100644 --- a/src/pages/Cutting.tsx +++ b/src/pages/Cutting.tsx @@ -19,6 +19,7 @@ type CorrectionIssueFilter = CutProductIssue | 'all'; type SettingsSection = 'rules' | 'corrections'; type CuttingView = 'plan' | 'families' | 'issues'; type PreviewStep = 'selection' | 'confirmation'; +type PreviewReviewFilter = 'all' | 'needs_review' | 'complete'; type MaterialReadiness = { status: 'ready' | 'material_ready' | 'blocked' | 'missing'; blockers: string[] }; type CutMaterialRequirement = { key: string; label: string; unit: string; quantity: number }; @@ -167,6 +168,7 @@ const Cutting = () => { const [previewStep, setPreviewStep] = useState('selection'); const [previewPage, setPreviewPage] = useState(1); const [previewItemsPerPage, setPreviewItemsPerPage] = useState(10); + const [previewReviewFilter, setPreviewReviewFilter] = useState('all'); const [selectedPreviewRowIds, setSelectedPreviewRowIds] = useState([]); const [previewQuantityOverrides, setPreviewQuantityOverrides] = useState>({}); const [lotSelections, setLotSelections] = useState>({}); @@ -448,13 +450,17 @@ const Cutting = () => { const previewRowsWithIssues = useMemo(() => ( selectedPreviewRows.filter(row => row.issues.length).length ), [selectedPreviewRows]); - const previewTotalPages = Math.ceil(rowsAvailableForOrder.length / previewItemsPerPage); + const previewRows = useMemo(() => rowsAvailableForOrder.filter(row => { + if (previewReviewFilter === 'needs_review') return row.issues.length > 0; + if (previewReviewFilter === 'complete') return row.issues.length === 0; + return true; + }), [previewReviewFilter, rowsAvailableForOrder]); + const previewTotalPages = Math.ceil(previewRows.length / previewItemsPerPage); const safePreviewPage = Math.min(previewPage, previewTotalPages || 1); const previewStartIndex = (safePreviewPage - 1) * previewItemsPerPage; - const paginatedPreviewRows = rowsAvailableForOrder.slice(previewStartIndex, previewStartIndex + previewItemsPerPage); + const paginatedPreviewRows = previewRows.slice(previewStartIndex, previewStartIndex + previewItemsPerPage); const selectedPreviewRowIdSet = useMemo(() => new Set(selectedPreviewRowIds), [selectedPreviewRowIds]); const areAllPreviewRowsSelected = rowsAvailableForOrder.length > 0 && selectedPreviewRows.length === rowsAvailableForOrder.length; - const areAllPagePreviewRowsSelected = paginatedPreviewRows.length > 0 && paginatedPreviewRows.every(row => selectedPreviewRowIdSet.has(row.id)); const totalPages = Math.ceil(filteredRows.length / itemsPerPage); const safeCurrentPage = Math.min(currentPage, totalPages || 1); @@ -680,6 +686,7 @@ const Cutting = () => { setGenerationMessage(''); setPreviewPage(1); + setPreviewReviewFilter('all'); setSelectedPreviewRowIds(rowsAvailableForOrder.map(row => row.id)); setPreviewQuantityOverrides({}); setLotSelections({}); @@ -692,10 +699,6 @@ const Cutting = () => { setIsOrderPreviewOpen(true); }; - const setPreviewSelection = (rows: CutPlanSkuRow[]) => { - setSelectedPreviewRowIds(rows.map(row => row.id)); - }; - const togglePreviewRow = (productId: string) => { setSelectedPreviewRowIds(current => ( current.includes(productId) @@ -704,16 +707,11 @@ const Cutting = () => { )); }; - const togglePreviewPage = () => { - const pageIds = paginatedPreviewRows.map(row => row.id); + const toggleAllPreviewRows = () => { setSelectedPreviewRowIds(current => { const currentIds = new Set(current); - if (pageIds.every(id => currentIds.has(id))) { - pageIds.forEach(id => currentIds.delete(id)); - } else { - pageIds.forEach(id => currentIds.add(id)); - } - return Array.from(currentIds); + const allRowsSelected = rowsAvailableForOrder.length > 0 && rowsAvailableForOrder.every(row => currentIds.has(row.id)); + return allRowsSelected ? [] : rowsAvailableForOrder.map(row => row.id); }); }; @@ -1022,11 +1020,23 @@ const Cutting = () => { {previewStep === 'selection' && <>
-

Todos os SKUs abaixo estão aptos para gerar OP. A seleção permanece ao trocar de página.

-
- - -
+

A seleção é mantida em todas as páginas. Use a caixa no cabeçalho para marcar ou desmarcar todos os SKUs aptos.

+
@@ -1041,7 +1051,7 @@ const Cutting = () => { - + Produto Cortar agora Demanda @@ -1068,7 +1078,20 @@ const Cutting = () => { {formatNumber(row.suggestedCutQuantity)} un. {formatNumber(row.projectedDemand, 1)} un.
{formatNumber(row.availableQuantity)} un.
{row.openProductionQuantity ?
{formatNumber(row.openProductionQuantity)} em OP
: null} - {renderIssueBadge(row)} + +
+ {renderIssueBadge(row)} + +
+ ))} @@ -1088,7 +1111,7 @@ const Cutting = () => { } {previewStep === 'selection' && { itemLabel="OPs" pageSizeLabel="por página" startIndex={previewStartIndex} - endIndex={Math.min(previewStartIndex + previewItemsPerPage, rowsAvailableForOrder.length)} + endIndex={Math.min(previewStartIndex + previewItemsPerPage, previewRows.length)} onPageChange={setPreviewPage} onPageSizeChange={(pageSize) => { setPreviewItemsPerPage(pageSize); setPreviewPage(1); }} className="border-t border-dark-border px-4 py-3"