From 412bf4ff735c5dc317ecaa20913d4270bcd92b29 Mon Sep 17 00:00:00 2001 From: Jarrod Flesch <30633324+JarrodMFlesch@users.noreply.github.com> Date: Tue, 22 Jul 2025 15:23:02 -0400 Subject: [PATCH] fix(ui): select all should reset when params change, page, filter, etc (#12612) Fixes #11938 Fixes https://github.com/payloadcms/payload/issues/13154 When select-all is checked and you filter or change the page, the selected documents should reset. --- packages/ui/src/providers/Selection/index.tsx | 9 +++++-- test/admin/e2e/list-view/e2e.spec.ts | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/providers/Selection/index.tsx b/packages/ui/src/providers/Selection/index.tsx index 921ae8afa2..079866061b 100644 --- a/packages/ui/src/providers/Selection/index.tsx +++ b/packages/ui/src/providers/Selection/index.tsx @@ -6,6 +6,7 @@ import * as qs from 'qs-esm' import React, { createContext, use, useCallback, useEffect, useRef, useState } from 'react' import { parseSearchParams } from '../../utilities/parseSearchParams.js' +import { useListQuery } from '../ListQuery/index.js' import { useLocale } from '../Locale/index.js' export enum SelectAllStatus { @@ -54,6 +55,7 @@ export const SelectionProvider: React.FC = ({ children, docs = [], totalD const [selectAll, setSelectAll] = useState(SelectAllStatus.None) const [count, setCount] = useState(0) const searchParams = useSearchParams() + const { query } = useListQuery() const toggleAll = useCallback( (allAvailable = false) => { @@ -201,7 +203,11 @@ export const SelectionProvider: React.FC = ({ children, docs = [], totalD setCount(newCount) }, [selectAll, selected, totalDocs]) - // eslint-disable-next-line react-compiler/react-compiler -- TODO: fix + useEffect(() => { + setSelectAll(SelectAllStatus.None) + setSelected(new Map()) + }, [query]) + contextRef.current = { count, getQueryParams, @@ -213,7 +219,6 @@ export const SelectionProvider: React.FC = ({ children, docs = [], totalD totalDocs, } - // eslint-disable-next-line react-compiler/react-compiler -- TODO: fix return {children} } diff --git a/test/admin/e2e/list-view/e2e.spec.ts b/test/admin/e2e/list-view/e2e.spec.ts index bff63dd6fd..2e8ec07ccf 100644 --- a/test/admin/e2e/list-view/e2e.spec.ts +++ b/test/admin/e2e/list-view/e2e.spec.ts @@ -1649,6 +1649,33 @@ describe('List View', () => { 'Custom placeholder', ) }) + + test('should reset list selection when query params change', async () => { + await deleteAllPosts() + await Promise.all(Array.from({ length: 12 }, (_, i) => createPost({ title: `post${i + 1}` }))) + await page.goto(postsUrl.list) + + const pageOneButton = page.locator('.paginator__page', { hasText: '1' }) + await expect(pageOneButton).toBeVisible() + await pageOneButton.click() + + await page.locator('.checkbox-input:has(#select-all)').locator('input').click() + await expect(page.locator('.checkbox-input:has(#select-all)').locator('input')).toBeChecked() + await expect(page.locator('.list-selection')).toContainText('5 selected') + + const pageTwoButton = page.locator('.paginator__page', { hasText: '2' }) + await expect(pageTwoButton).toBeVisible() + await pageTwoButton.click() + + await expect( + page.locator('.checkbox-input:has(#select-all) input:not([checked])'), + ).toBeVisible() + + await page.locator('.row-1 .cell-_select input').check() + await page.locator('.row-2 .cell-_select input').check() + + await expect(page.locator('.list-selection')).toContainText('2 selected') + }) }) async function createPost(overrides?: Partial): Promise {