From debb6c12158c29b56a4023cf73a5776e9209162d Mon Sep 17 00:00:00 2001 From: Joe Russack Date: Fri, 3 Apr 2026 16:29:18 -0700 Subject: [PATCH] fix: remove artificial limit on record sets in search dialog (#6971) The Record Sets button in the Search Dialog used usePaginator with a default limit of 10 but never rendered the paginator UI, so users could only see the first 10 record sets. Replace with limit: 0 to fetch all record sets for the current user. --- .../SearchDialog/SelectRecordSet.tsx | 9 +-- .../__tests__/SelectRecordSet.test.ts | 71 +++++++++++++++++++ 2 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 specifyweb/frontend/js_src/lib/components/SearchDialog/__tests__/SelectRecordSet.test.ts diff --git a/specifyweb/frontend/js_src/lib/components/SearchDialog/SelectRecordSet.tsx b/specifyweb/frontend/js_src/lib/components/SearchDialog/SelectRecordSet.tsx index b070b13fae6..53079766e47 100644 --- a/specifyweb/frontend/js_src/lib/components/SearchDialog/SelectRecordSet.tsx +++ b/specifyweb/frontend/js_src/lib/components/SearchDialog/SelectRecordSet.tsx @@ -18,7 +18,6 @@ import type { RecordSet } from '../DataModel/types'; import { softError } from '../Errors/assert'; import { userInformation } from '../InitialContext/userInformation'; import { Dialog, LoadingScreen } from '../Molecules/Dialog'; -import { usePaginator } from '../Molecules/Paginator'; import { TableIcon } from '../Molecules/TableIcon'; export function SelectRecordSets({ @@ -38,21 +37,19 @@ export function SelectRecordSets({ RA >([]); - const { limit, offset } = usePaginator('recordSets'); - const [recordSets] = useAsyncState( React.useCallback( async () => fetchCollection('RecordSet', { specifyUser: userInformation.id, type: 0, - limit, + limit: 0, domainFilter: true, - offset, + offset: 0, dbTableId: table?.tableId, collectionMemberId: schema.domainLevelIds.collection, }), - [table, limit, offset] + [table] ), false ); diff --git a/specifyweb/frontend/js_src/lib/components/SearchDialog/__tests__/SelectRecordSet.test.ts b/specifyweb/frontend/js_src/lib/components/SearchDialog/__tests__/SelectRecordSet.test.ts new file mode 100644 index 00000000000..273815c8ccc --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/SearchDialog/__tests__/SelectRecordSet.test.ts @@ -0,0 +1,71 @@ +import { overrideAjax } from '../../../tests/ajax'; +import { requireContext } from '../../../tests/helpers'; +import { addMissingFields } from '../../DataModel/addMissingFields'; +import { fetchCollection } from '../../DataModel/collection'; +import { getResourceApiUrl } from '../../DataModel/resource'; + +requireContext(); + +/** + * Regression test for issue #6971: + * The Record Sets button in the Search Dialog previously used a paginated + * fetch with a default limit of 10, which meant users with more than 10 + * record sets could only see a subset. The fix uses limit=0 (no limit) + * to fetch all record sets. + * + * This test verifies that a limit=0 fetch returns all record sets rather + * than being capped at 10. + */ +describe('SelectRecordSet record set fetch', () => { + const recordSetCount = 25; + const mockRecordSets = Array.from({ length: recordSetCount }, (_, index) => ({ + resource_uri: getResourceApiUrl('RecordSet', index + 1), + name: `Record Set ${index + 1}`, + dbTableId: 1, + type: 0, + })); + + overrideAjax( + '/api/specify/recordset/?specifyuser=1&type=0&limit=0&offset=0&dbtableid=1&collectionmemberid=4', + { + meta: { + total_count: recordSetCount, + }, + objects: mockRecordSets, + } + ); + + test('fetches all record sets when limit is 0', async () => { + const result = await fetchCollection('RecordSet', { + specifyUser: 1, + type: 0, + limit: 0, + domainFilter: true, + offset: 0, + dbTableId: 1, + collectionMemberId: 4, + }); + + expect(result.totalCount).toBe(recordSetCount); + expect(result.records).toHaveLength(recordSetCount); + expect(result.records).toEqual( + mockRecordSets.map((recordSet) => + addMissingFields('RecordSet', recordSet) + ) + ); + }); + + test('returns more than the old default limit of 10', async () => { + const result = await fetchCollection('RecordSet', { + specifyUser: 1, + type: 0, + limit: 0, + domainFilter: true, + offset: 0, + dbTableId: 1, + collectionMemberId: 4, + }); + + expect(result.records.length).toBeGreaterThan(10); + }); +});