diff --git a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/DocumentBulkDownload.tsx b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/DocumentBulkDownload.tsx index d1961656..5b8bf746 100644 --- a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/DocumentBulkDownload.tsx +++ b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/DocumentBulkDownload.tsx @@ -178,7 +178,8 @@ export default function DocumentBulkDownload({ {selectedIds.size} selected - Tick the properties to include, or use the header box to select all. + Tick properties, or use the header box to select the page (then “select + all across pages”). {overCap && ( diff --git a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/DocumentTable.tsx b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/DocumentTable.tsx index 0c61f8ca..ec50d043 100644 --- a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/DocumentTable.tsx +++ b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/DocumentTable.tsx @@ -119,21 +119,23 @@ export default function DocumentTable({ data, onOpenDrawer, docStatusMap, portfo enableSorting: false, enableGlobalFilter: false, header: ({ table }) => { - const ids = table - .getFilteredRowModel() + // Header ticks the current page; the banner below offers all pages. + const pageIds = table + .getRowModel() .rows.map((r) => r.original.landlordPropertyId) .filter((id): id is string => !!id); - const allSelected = ids.length > 0 && ids.every((id) => selection.selectedIds.has(id)); - const someSelected = ids.some((id) => selection.selectedIds.has(id)); + const allSelected = + pageIds.length > 0 && pageIds.every((id) => selection.selectedIds.has(id)); + const someSelected = pageIds.some((id) => selection.selectedIds.has(id)); return ( { if (el) el.indeterminate = someSelected && !allSelected; }} - onChange={() => selection.onSetMany(ids, !allSelected)} + onChange={() => selection.onSetMany(pageIds, !allSelected)} className="h-4 w-4 accent-brandblue align-middle" /> ); @@ -217,6 +219,31 @@ export default function DocumentTable({ data, onOpenDrawer, docStatusMap, portfo const currentPage = table.getState().pagination.pageIndex + 1; const totalFiltered = table.getFilteredRowModel().rows.length; + // "Select all across pages" banner: shown when the whole current page is + // ticked and there are more filtered rows than fit on it (Gmail-style). + const pageSelectableIds = selection + ? table + .getRowModel() + .rows.map((r) => r.original.landlordPropertyId) + .filter((id): id is string => !!id) + : []; + const filteredSelectableIds = selection + ? table + .getFilteredRowModel() + .rows.map((r) => r.original.landlordPropertyId) + .filter((id): id is string => !!id) + : []; + const pageFullySelected = + pageSelectableIds.length > 0 && + pageSelectableIds.every((id) => selection!.selectedIds.has(id)); + const allFilteredSelected = + filteredSelectableIds.length > 0 && + filteredSelectableIds.every((id) => selection!.selectedIds.has(id)); + const showSelectAllBanner = + !!selection && + pageFullySelected && + filteredSelectableIds.length > pageSelectableIds.length; + const retroAssessmentLabel: Record = { all: "All retrofit statuses", none: "No Retrofit Docs", @@ -314,6 +341,40 @@ export default function DocumentTable({ data, onOpenDrawer, docStatusMap, portfo propert{totalFiltered === 1 ? "y" : "ies"}

+ {/* Select-all-across-pages banner */} + {showSelectAllBanner && ( +
+ {allFilteredSelected ? ( + <> + + All {filteredSelectableIds.length}{" "} + matching propert{filteredSelectableIds.length === 1 ? "y is" : "ies are"}{" "} + selected. + + + + ) : ( + <> + + All {pageSelectableIds.length} on this + page selected. + + + + )} +
+ )} + {/* Table */}