fix(ui): link element triggering clicks twice (#11362)
Fixes https://github.com/payloadcms/payload/issues/11359#issuecomment-2678213414 The link element by using startTransitionRoute and manually calling router.push would technically cause links to be clicked twice, by not preventing default browser behaviour. This caused a problem on clicking /create links as it hit the route twice. Added a test making sure Create new doesn't lead to abnormally increased document counts Changes: - Added `e.preventDefault()` in our Link element - Added `preventDefault` as an optional prop to this element so that people can handle it on their own if needed via a custom `onClick`
This commit is contained in:
@@ -23,10 +23,20 @@ function isModifiedEvent(event: React.MouseEvent): boolean {
|
||||
)
|
||||
}
|
||||
|
||||
export const Link: React.FC<Parameters<typeof NextLink>[0]> = ({
|
||||
type Props = {
|
||||
/**
|
||||
* Disable the e.preventDefault() call on click if you want to handle it yourself via onClick
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
preventDefault?: boolean
|
||||
} & Parameters<typeof NextLink>[0]
|
||||
|
||||
export const Link: React.FC<Props> = ({
|
||||
children,
|
||||
href,
|
||||
onClick,
|
||||
preventDefault = true,
|
||||
ref,
|
||||
replace,
|
||||
scroll,
|
||||
@@ -47,6 +57,12 @@ export const Link: React.FC<Parameters<typeof NextLink>[0]> = ({
|
||||
onClick(e)
|
||||
}
|
||||
|
||||
// We need a preventDefault here so that a clicked link doesn't trigger twice,
|
||||
// once for default browser navigation and once for startRouteTransition
|
||||
if (preventDefault) {
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
startRouteTransition(() => {
|
||||
const url = typeof href === 'string' ? href : formatUrl(href)
|
||||
|
||||
|
||||
@@ -438,6 +438,47 @@ describe('Versions', () => {
|
||||
await expect(drawer.locator('.id-label')).toBeVisible()
|
||||
})
|
||||
|
||||
test('collection - autosave - should not create duplicates when clicking Create new', async () => {
|
||||
// This test checks that when we click "Create new" in the list view, it only creates 1 extra document and not more
|
||||
const { totalDocs: initialDocsCount } = await payload.find({
|
||||
collection: autosaveCollectionSlug,
|
||||
draft: true,
|
||||
})
|
||||
|
||||
await page.goto(autosaveURL.create)
|
||||
await page.locator('#field-title').fill('autosave title')
|
||||
await waitForAutoSaveToRunAndComplete(page)
|
||||
await expect(page.locator('#field-title')).toHaveValue('autosave title')
|
||||
|
||||
const { totalDocs: updatedDocsCount } = await payload.find({
|
||||
collection: autosaveCollectionSlug,
|
||||
draft: true,
|
||||
})
|
||||
|
||||
await expect(() => {
|
||||
expect(updatedDocsCount).toBe(initialDocsCount + 1)
|
||||
}).toPass({ timeout: POLL_TOPASS_TIMEOUT, intervals: [100] })
|
||||
|
||||
await page.goto(autosaveURL.list)
|
||||
const createNewButton = page.locator('.list-header .btn:has-text("Create New")')
|
||||
await createNewButton.click()
|
||||
|
||||
await page.waitForURL(`**/${autosaveCollectionSlug}/**`)
|
||||
|
||||
await page.locator('#field-title').fill('autosave title')
|
||||
await waitForAutoSaveToRunAndComplete(page)
|
||||
await expect(page.locator('#field-title')).toHaveValue('autosave title')
|
||||
|
||||
const { totalDocs: latestDocsCount } = await payload.find({
|
||||
collection: autosaveCollectionSlug,
|
||||
draft: true,
|
||||
})
|
||||
|
||||
await expect(() => {
|
||||
expect(latestDocsCount).toBe(updatedDocsCount + 1)
|
||||
}).toPass({ timeout: POLL_TOPASS_TIMEOUT, intervals: [100] })
|
||||
})
|
||||
|
||||
test('collection - should update updatedAt', async () => {
|
||||
await page.goto(url.create)
|
||||
await page.waitForURL(`**/${url.create}`)
|
||||
@@ -757,7 +798,7 @@ describe('Versions', () => {
|
||||
|
||||
// schedule publish should not be available before document has been saved
|
||||
await page.locator('#action-save-popup').click()
|
||||
await expect(page.locator('#schedule-publish')).not.toBeVisible()
|
||||
await expect(page.locator('#schedule-publish')).toBeHidden()
|
||||
|
||||
// save draft then try to schedule publish
|
||||
await saveDocAndAssert(page)
|
||||
|
||||
Reference in New Issue
Block a user