From c176c91e89beccf90afa0a21954afab35baad2c9 Mon Sep 17 00:00:00 2001 From: Alexis Date: Mon, 1 Jun 2026 13:42:49 +0200 Subject: [PATCH] =?UTF-8?q?feat(ui):=20actualizar=20l=C3=B3gica=20de=20sel?= =?UTF-8?q?ecci=C3=B3n=20en=20PublicationsTable=20para=20manejar=20solo=20?= =?UTF-8?q?la=20p=C3=A1gina=20actual?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Se modifica el comportamiento del checkbox maestro para que solo seleccione las filas visibles en la página actual, en lugar de toda la colección filtrada. Además, se actualizan las estadísticas de selección para reflejar esta nueva lógica y se renombra la función correspondiente para mayor claridad. --- .../dashboard/PublicationsTable.jsx | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/frontend/src/components/dashboard/PublicationsTable.jsx b/frontend/src/components/dashboard/PublicationsTable.jsx index 3aeaec6..3f7191e 100644 --- a/frontend/src/components/dashboard/PublicationsTable.jsx +++ b/frontend/src/components/dashboard/PublicationsTable.jsx @@ -71,11 +71,9 @@ function TriStateCheckbox({ checked, indeterminate = false, onChange, ariaLabel * retries and toasts can be handled in one place. * * Selection semantics: - * - The master checkbox toggles the WHOLE currently-filtered set (not - * just the visible page). This matches the user mental model of - * "filtrar por 2024 → marcar todas de 2024". - * - Selection survives filter changes: the stored IDs remain even if - * those rows are no longer visible. + * - The master checkbox toggles only the rows on the current page. + * - Selection is stored by ID in the parent and persists across pages, + * filters and sorts so the user can select page by page. */ export function PublicationsTable({ publications, @@ -152,20 +150,19 @@ export function PublicationsTable({ return filtered.slice(start, start + PAGE_SIZE); }, [filtered, currentPage]); - const selectionStats = useMemo(() => { - if (filtered.length === 0) { - return { allChecked: false, anyChecked: false, selectedInFiltered: 0 }; + const pageSelectionStats = useMemo(() => { + if (pageRows.length === 0) { + return { allChecked: false, anyChecked: false }; } let count = 0; - for (const pub of filtered) { + for (const pub of pageRows) { if (selectedIds.has(pub.id)) count += 1; } return { - allChecked: count === filtered.length, + allChecked: count === pageRows.length, anyChecked: count > 0, - selectedInFiltered: count, }; - }, [filtered, selectedIds]); + }, [pageRows, selectedIds]); function toggleSort(key) { if (sortKey === key) { @@ -189,12 +186,12 @@ export function PublicationsTable({ emit(next); } - function toggleAllFiltered() { + function toggleCurrentPage() { const next = new Set(selectedIds); - if (selectionStats.allChecked) { - for (const pub of filtered) next.delete(pub.id); + if (pageSelectionStats.allChecked) { + for (const pub of pageRows) next.delete(pub.id); } else { - for (const pub of filtered) next.add(pub.id); + for (const pub of pageRows) next.add(pub.id); } emit(next); } @@ -378,10 +375,10 @@ export function PublicationsTable({ onClick={(e) => e.stopPropagation()} > {COLUMNS.map((col) => (