Paginate production plan confirmation
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 37s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 37s
This commit is contained in:
@@ -168,6 +168,8 @@ const Cutting = () => {
|
|||||||
const [previewStep, setPreviewStep] = useState<PreviewStep>('selection');
|
const [previewStep, setPreviewStep] = useState<PreviewStep>('selection');
|
||||||
const [previewPage, setPreviewPage] = useState(1);
|
const [previewPage, setPreviewPage] = useState(1);
|
||||||
const [previewItemsPerPage, setPreviewItemsPerPage] = useState(10);
|
const [previewItemsPerPage, setPreviewItemsPerPage] = useState(10);
|
||||||
|
const [confirmationPage, setConfirmationPage] = useState(1);
|
||||||
|
const [confirmationItemsPerPage, setConfirmationItemsPerPage] = useState(10);
|
||||||
const [previewReviewFilter, setPreviewReviewFilter] = useState<PreviewReviewFilter>('all');
|
const [previewReviewFilter, setPreviewReviewFilter] = useState<PreviewReviewFilter>('all');
|
||||||
const [selectedPreviewRowIds, setSelectedPreviewRowIds] = useState<string[]>([]);
|
const [selectedPreviewRowIds, setSelectedPreviewRowIds] = useState<string[]>([]);
|
||||||
const [previewQuantityOverrides, setPreviewQuantityOverrides] = useState<Record<string, string>>({});
|
const [previewQuantityOverrides, setPreviewQuantityOverrides] = useState<Record<string, string>>({});
|
||||||
@@ -403,6 +405,10 @@ const Cutting = () => {
|
|||||||
const selectedIds = new Set(selectedPreviewRowIds);
|
const selectedIds = new Set(selectedPreviewRowIds);
|
||||||
return rowsAvailableForOrder.filter(row => selectedIds.has(row.id));
|
return rowsAvailableForOrder.filter(row => selectedIds.has(row.id));
|
||||||
}, [rowsAvailableForOrder, selectedPreviewRowIds]);
|
}, [rowsAvailableForOrder, selectedPreviewRowIds]);
|
||||||
|
const confirmationTotalPages = Math.ceil(selectedPreviewRows.length / confirmationItemsPerPage);
|
||||||
|
const safeConfirmationPage = Math.min(confirmationPage, confirmationTotalPages || 1);
|
||||||
|
const confirmationStartIndex = (safeConfirmationPage - 1) * confirmationItemsPerPage;
|
||||||
|
const paginatedConfirmationRows = selectedPreviewRows.slice(confirmationStartIndex, confirmationStartIndex + confirmationItemsPerPage);
|
||||||
const orderPreviewTotalUnits = useMemo(() => (
|
const orderPreviewTotalUnits = useMemo(() => (
|
||||||
selectedPreviewRows.reduce((total, row) => total + getPreviewQuantity(row), 0)
|
selectedPreviewRows.reduce((total, row) => total + getPreviewQuantity(row), 0)
|
||||||
), [getPreviewQuantity, selectedPreviewRows]);
|
), [getPreviewQuantity, selectedPreviewRows]);
|
||||||
@@ -686,6 +692,7 @@ const Cutting = () => {
|
|||||||
|
|
||||||
setGenerationMessage('');
|
setGenerationMessage('');
|
||||||
setPreviewPage(1);
|
setPreviewPage(1);
|
||||||
|
setConfirmationPage(1);
|
||||||
setPreviewReviewFilter('all');
|
setPreviewReviewFilter('all');
|
||||||
setSelectedPreviewRowIds(rowsAvailableForOrder.map(row => row.id));
|
setSelectedPreviewRowIds(rowsAvailableForOrder.map(row => row.id));
|
||||||
setPreviewQuantityOverrides({});
|
setPreviewQuantityOverrides({});
|
||||||
@@ -997,7 +1004,7 @@ const Cutting = () => {
|
|||||||
{previewRowsWithIssues > 0 && <span className="text-xs font-bold text-amber-300">{formatNumber(previewRowsWithIssues)} para revisar</span>}
|
{previewRowsWithIssues > 0 && <span className="text-xs font-bold text-amber-300">{formatNumber(previewRowsWithIssues)} para revisar</span>}
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-3 divide-y divide-dark-border overflow-hidden rounded-lg border border-dark-border bg-dark-card">
|
<div className="mt-3 divide-y divide-dark-border overflow-hidden rounded-lg border border-dark-border bg-dark-card">
|
||||||
{selectedPreviewRows.map(row => (
|
{paginatedConfirmationRows.map(row => (
|
||||||
<div key={row.id} className="grid gap-3 px-3 py-3 lg:grid-cols-[minmax(0,1fr)_100px] lg:items-center">
|
<div key={row.id} className="grid gap-3 px-3 py-3 lg:grid-cols-[minmax(0,1fr)_100px] lg:items-center">
|
||||||
<div className="min-w-0">
|
<div className="min-w-0">
|
||||||
<p className="truncate text-sm font-bold text-dark-text" title={row.name}>{row.name}</p>
|
<p className="truncate text-sm font-bold text-dark-text" title={row.name}>{row.name}</p>
|
||||||
@@ -1014,6 +1021,20 @@ const Cutting = () => {
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
<PaginationControls
|
||||||
|
totalItems={selectedPreviewRows.length}
|
||||||
|
currentPage={safeConfirmationPage}
|
||||||
|
totalPages={confirmationTotalPages}
|
||||||
|
pageSize={confirmationItemsPerPage}
|
||||||
|
pageSizeOptions={[10, 20, 50]}
|
||||||
|
itemLabel="OPs"
|
||||||
|
pageSizeLabel="por página"
|
||||||
|
startIndex={confirmationStartIndex}
|
||||||
|
endIndex={Math.min(confirmationStartIndex + confirmationItemsPerPage, selectedPreviewRows.length)}
|
||||||
|
onPageChange={setConfirmationPage}
|
||||||
|
onPageSizeChange={(pageSize) => { setConfirmationItemsPerPage(pageSize); setConfirmationPage(1); }}
|
||||||
|
className="mt-3 border-t border-dark-border pt-3"
|
||||||
|
/>
|
||||||
<p className="mt-3 text-xs font-semibold text-dark-muted">A quantidade sugerida vem da cobertura. Ajustes manuais ficam marcados na OP, e o resultado real é confirmado durante a execução.</p>
|
<p className="mt-3 text-xs font-semibold text-dark-muted">A quantidade sugerida vem da cobertura. Ajustes manuais ficam marcados na OP, e o resultado real é confirmado durante a execução.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>}
|
</div>}
|
||||||
@@ -1079,7 +1100,7 @@ const Cutting = () => {
|
|||||||
<td className="px-4 py-3 font-bold whitespace-nowrap text-dark-text">{formatNumber(row.projectedDemand, 1)} un.</td>
|
<td className="px-4 py-3 font-bold whitespace-nowrap text-dark-text">{formatNumber(row.projectedDemand, 1)} un.</td>
|
||||||
<td className="px-4 py-3 whitespace-nowrap"><div className="font-bold text-dark-text">{formatNumber(row.availableQuantity)} un.</div>{row.openProductionQuantity ? <div className="mt-1 text-[10px] font-semibold text-dark-muted">{formatNumber(row.openProductionQuantity)} em OP</div> : null}</td>
|
<td className="px-4 py-3 whitespace-nowrap"><div className="font-bold text-dark-text">{formatNumber(row.availableQuantity)} un.</div>{row.openProductionQuantity ? <div className="mt-1 text-[10px] font-semibold text-dark-muted">{formatNumber(row.openProductionQuantity)} em OP</div> : null}</td>
|
||||||
<td className="px-4 py-3">
|
<td className="px-4 py-3">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-3">
|
||||||
{renderIssueBadge(row)}
|
{renderIssueBadge(row)}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -1141,7 +1162,7 @@ const Cutting = () => {
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => previewStep === 'selection' ? setPreviewStep('confirmation') : void generateProductionOrders()}
|
onClick={() => previewStep === 'selection' ? (setConfirmationPage(1), setPreviewStep('confirmation')) : void generateProductionOrders()}
|
||||||
disabled={isGeneratingOrders || !selectedPreviewRows.length}
|
disabled={isGeneratingOrders || !selectedPreviewRows.length}
|
||||||
className="inline-flex items-center justify-center gap-2 rounded-xl border border-brand-primary/30 bg-brand-primary/15 px-4 py-2 text-sm font-bold text-brand-primary transition-colors hover:border-brand-primary disabled:cursor-not-allowed disabled:opacity-50 cursor-pointer"
|
className="inline-flex items-center justify-center gap-2 rounded-xl border border-brand-primary/30 bg-brand-primary/15 px-4 py-2 text-sm font-bold text-brand-primary transition-colors hover:border-brand-primary disabled:cursor-not-allowed disabled:opacity-50 cursor-pointer"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user