Skip to content

Commit bbdfdb8

Browse files
authored
fix(ui): prevent NaN page parameter in polymorphic relationship pagination (#14795)
### What Fixed pagination bug in polymorphic relationship fields where the second collection type would fail to load additional pages due to sending `page=NaN` in the request. ### Why When paginating through a polymorphic relationship dropdown, `lastLoadedPageArg[relation]` was `undefined` for collections that hadn't been loaded yet. This caused the page parameter to become `NaN` (`undefined + 1 = NaN`), breaking pagination for subsequent collection types. ### How Added a fallback to default to `0` when the relation hasn't been paginated yet: ```typescript lastLoadedPageToUse = (lastLoadedPageArg[relation] || 0) + 1 ``` Fixes #14754
1 parent 61f5aee commit bbdfdb8

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

packages/ui/src/fields/Relationship/Input.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ export const RelationshipInput: React.FC<RelationshipInputProps> = (props) => {
227227
if (search !== searchArg) {
228228
lastLoadedPageToUse = 1
229229
} else {
230-
lastLoadedPageToUse = lastLoadedPageArg[relation] + 1
230+
lastLoadedPageToUse = (lastLoadedPageArg[relation] || 0) + 1
231231
}
232232
await priorRelation
233233

test/fields-relationship/e2e.spec.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,63 @@ describe('Relationship Field', () => {
284284
await expect(values).toHaveText([relationOneDoc.id, relationTwoDoc.id])
285285
})
286286

287+
test('should paginate polymorphic relationship correctly and not send NaN page parameter', async () => {
288+
const relationOneIDs: string[] = []
289+
const relationTwoIDs: string[] = []
290+
291+
// Create 15 relationOne docs to simulate pagination in the dropdown
292+
for (let i = 0; i < 15; i++) {
293+
const doc = await payload.create({
294+
collection: relationOneSlug,
295+
data: {
296+
name: `relation-one-${i}`,
297+
},
298+
})
299+
relationOneIDs.push(doc.id)
300+
}
301+
302+
// Create 15 relationOne docs to simulate pagination in the dropdown
303+
for (let i = 0; i < 15; i++) {
304+
const doc = await payload.create({
305+
collection: relationTwoSlug,
306+
data: {
307+
name: `relation-two-${i}`,
308+
},
309+
})
310+
relationTwoIDs.push(doc.id)
311+
}
312+
313+
await loadCreatePage()
314+
315+
const field = page.locator('#field-relationshipHasManyMultiple')
316+
317+
await field.click({ delay: 100 })
318+
319+
const menu = page.locator('.rs__menu-list')
320+
await expect(menu).toBeVisible()
321+
await wait(300)
322+
323+
const options = page.locator('.rs__option')
324+
await expect(options.first()).toBeVisible()
325+
326+
// Hover over the menu and use mouse wheel to scroll and trigger pagination
327+
await menu.hover()
328+
329+
// Scroll down multiple times using mouse wheel to trigger onMenuScrollToBottom
330+
for (let i = 0; i < 5; i++) {
331+
await menu.hover()
332+
await page.mouse.wheel(0, 500)
333+
await wait(300)
334+
}
335+
336+
// Check that we can see the 14th doc from relationTwo (which would be on page 2)
337+
// Before the fix, page 2 of relationTwo wouldn't load because page parameter was NaN
338+
const fourteenthRelationTwoDoc = relationTwoIDs[13] // Index 13 = 14th doc (page 2, item 4)
339+
340+
// The 14th relationTwo doc should be visible in the dropdown
341+
await expect(options.locator(`text=${fourteenthRelationTwoDoc}`)).toBeVisible()
342+
})
343+
287344
test('should duplicate document with relationships', async () => {
288345
await page.goto(url.edit(docWithExistingRelations.id))
289346
await wait(300)

0 commit comments

Comments
 (0)