From a9ad7c771e9c3e6c56760512dfddecdbb0dfbeab Mon Sep 17 00:00:00 2001
From: Jarrod Flesch <30633324+JarrodMFlesch@users.noreply.github.com>
Date: Tue, 1 Jul 2025 15:23:11 -0400
Subject: [PATCH] fix(ui): bulk upload redirecting to relationship documents
when added (#13001)
Fixes https://github.com/payloadcms/payload/issues/12786
---
packages/ui/src/elements/BulkUpload/index.tsx | 5 +-
test/uploads/collections/BulkUploads/index.ts | 23 ++++++
.../collections/SimpleRelationship/index.ts | 14 ++++
test/uploads/config.ts | 4 +
test/uploads/e2e.spec.ts | 23 ++++++
test/uploads/payload-types.ts | 73 +++++++++++++++++++
test/uploads/shared.ts | 1 +
7 files changed, 142 insertions(+), 1 deletion(-)
create mode 100644 test/uploads/collections/BulkUploads/index.ts
create mode 100644 test/uploads/collections/SimpleRelationship/index.ts
diff --git a/packages/ui/src/elements/BulkUpload/index.tsx b/packages/ui/src/elements/BulkUpload/index.tsx
index 3bd36075e..1fba50a5c 100644
--- a/packages/ui/src/elements/BulkUpload/index.tsx
+++ b/packages/ui/src/elements/BulkUpload/index.tsx
@@ -8,6 +8,7 @@ import React from 'react'
import { toast } from 'sonner'
import { useConfig } from '../../providers/Config/index.js'
+import { EditDepthProvider } from '../../providers/EditDepth/index.js'
import { useTranslation } from '../../providers/Translation/index.js'
import { UploadControlsProvider } from '../../providers/UploadControls/index.js'
import { Drawer, useDrawerDepth } from '../Drawer/index.js'
@@ -77,7 +78,9 @@ export function BulkUploadDrawer() {
-
+
+
+
diff --git a/test/uploads/collections/BulkUploads/index.ts b/test/uploads/collections/BulkUploads/index.ts
new file mode 100644
index 000000000..2b1f9ea5c
--- /dev/null
+++ b/test/uploads/collections/BulkUploads/index.ts
@@ -0,0 +1,23 @@
+import type { CollectionConfig } from 'payload'
+
+import { bulkUploadsSlug } from '../../shared.js'
+
+export const BulkUploadsCollection: CollectionConfig = {
+ slug: bulkUploadsSlug,
+ upload: true,
+ admin: {
+ useAsTitle: 'title',
+ },
+ fields: [
+ {
+ type: 'text',
+ name: 'title',
+ required: true,
+ },
+ {
+ name: 'relationship',
+ type: 'relationship',
+ relationTo: ['simple-relationship'],
+ },
+ ],
+}
diff --git a/test/uploads/collections/SimpleRelationship/index.ts b/test/uploads/collections/SimpleRelationship/index.ts
new file mode 100644
index 000000000..a0533ff00
--- /dev/null
+++ b/test/uploads/collections/SimpleRelationship/index.ts
@@ -0,0 +1,14 @@
+import type { CollectionConfig } from 'payload'
+
+export const SimpleRelationshipCollection: CollectionConfig = {
+ slug: 'simple-relationship',
+ admin: {
+ useAsTitle: 'title',
+ },
+ fields: [
+ {
+ type: 'text',
+ name: 'title',
+ },
+ ],
+}
diff --git a/test/uploads/config.ts b/test/uploads/config.ts
index 5c5efe5d1..04b8c34ff 100644
--- a/test/uploads/config.ts
+++ b/test/uploads/config.ts
@@ -11,7 +11,9 @@ import { AdminThumbnailFunction } from './collections/AdminThumbnailFunction/ind
import { AdminThumbnailSize } from './collections/AdminThumbnailSize/index.js'
import { AdminThumbnailWithSearchQueries } from './collections/AdminThumbnailWithSearchQueries/index.js'
import { AdminUploadControl } from './collections/AdminUploadControl/index.js'
+import { BulkUploadsCollection } from './collections/BulkUploads/index.js'
import { CustomUploadFieldCollection } from './collections/CustomUploadField/index.js'
+import { SimpleRelationshipCollection } from './collections/SimpleRelationship/index.js'
import { Uploads1 } from './collections/Upload1/index.js'
import { Uploads2 } from './collections/Upload2/index.js'
import {
@@ -880,6 +882,8 @@ export default buildConfigWithDefaults({
staticDir: path.resolve(dirname, './media'),
},
},
+ BulkUploadsCollection,
+ SimpleRelationshipCollection,
],
onInit: async (payload) => {
const uploadsDir = path.resolve(dirname, './media')
diff --git a/test/uploads/e2e.spec.ts b/test/uploads/e2e.spec.ts
index 9daf36475..cb0bc1a16 100644
--- a/test/uploads/e2e.spec.ts
+++ b/test/uploads/e2e.spec.ts
@@ -28,6 +28,7 @@ import {
adminUploadControlSlug,
animatedTypeMedia,
audioSlug,
+ bulkUploadsSlug,
constructorOptionsSlug,
customFileNameMediaSlug,
customUploadFieldSlug,
@@ -82,6 +83,7 @@ let constructorOptionsURL: AdminUrlUtil
let consoleErrorsFromPage: string[] = []
let collectErrorsFromPage: () => boolean
let stopCollectingErrorsFromPage: () => boolean
+let bulkUploadsURL: AdminUrlUtil
describe('Uploads', () => {
let page: Page
@@ -119,6 +121,7 @@ describe('Uploads', () => {
withoutEnlargementResizeOptionsURL = new AdminUrlUtil(serverURL, withoutEnlargeSlug)
threeDimensionalURL = new AdminUrlUtil(serverURL, threeDimensionalSlug)
constructorOptionsURL = new AdminUrlUtil(serverURL, constructorOptionsSlug)
+ bulkUploadsURL = new AdminUrlUtil(serverURL, bulkUploadsSlug)
const context = await browser.newContext()
page = await context.newPage()
@@ -1193,6 +1196,26 @@ describe('Uploads', () => {
// ensure the prefix field is still filled with the original value
await expect(page.locator('#field-prefix')).toHaveValue('should-preserve')
})
+
+ test('should not redirect to created relationship document inside the bulk upload drawer', async () => {
+ await page.goto(bulkUploadsURL.list)
+ await page.locator('.list-header__title-actions button', { hasText: 'Bulk Upload' }).click()
+ await page.setInputFiles('.dropzone input[type="file"]', path.resolve(dirname, './image.png'))
+
+ await page.locator('#field-title').fill('Upload title 1')
+ const bulkUploadForm = page.locator('.bulk-upload--file-manager')
+ const relationshipField = bulkUploadForm.locator('#field-relationship')
+ await relationshipField.locator('.relationship-add-new__add-button').click()
+
+ const collectionForm = page.locator('.collection-edit')
+ await collectionForm.locator('#field-title').fill('Related Document Title')
+ await saveDocAndAssert(page)
+ await collectionForm.locator('.doc-drawer__header-close').click()
+
+ await expect(bulkUploadForm.locator('.relationship--single-value__text')).toHaveText(
+ 'Related Document Title',
+ )
+ })
})
describe('remote url fetching', () => {
diff --git a/test/uploads/payload-types.ts b/test/uploads/payload-types.ts
index 67d1536d5..fcccd753d 100644
--- a/test/uploads/payload-types.ts
+++ b/test/uploads/payload-types.ts
@@ -111,6 +111,8 @@ export interface Config {
'list-view-preview': ListViewPreview;
'three-dimensional': ThreeDimensional;
'constructor-options': ConstructorOption;
+ 'bulk-uploads': BulkUpload;
+ 'simple-relationship': SimpleRelationship;
users: User;
'payload-locked-documents': PayloadLockedDocument;
'payload-preferences': PayloadPreference;
@@ -162,6 +164,8 @@ export interface Config {
'list-view-preview': ListViewPreviewSelect | ListViewPreviewSelect;
'three-dimensional': ThreeDimensionalSelect | ThreeDimensionalSelect;
'constructor-options': ConstructorOptionsSelect | ConstructorOptionsSelect;
+ 'bulk-uploads': BulkUploadsSelect | BulkUploadsSelect;
+ 'simple-relationship': SimpleRelationshipSelect | SimpleRelationshipSelect;
users: UsersSelect | UsersSelect;
'payload-locked-documents': PayloadLockedDocumentsSelect | PayloadLockedDocumentsSelect;
'payload-preferences': PayloadPreferencesSelect | PayloadPreferencesSelect;
@@ -1465,6 +1469,39 @@ export interface ConstructorOption {
focalX?: number | null;
focalY?: number | null;
}
+/**
+ * This interface was referenced by `Config`'s JSON-Schema
+ * via the `definition` "bulk-uploads".
+ */
+export interface BulkUpload {
+ id: string;
+ title: string;
+ relationship?: {
+ relationTo: 'simple-relationship';
+ value: string | SimpleRelationship;
+ } | null;
+ updatedAt: string;
+ createdAt: string;
+ url?: string | null;
+ thumbnailURL?: string | null;
+ filename?: string | null;
+ mimeType?: string | null;
+ filesize?: number | null;
+ width?: number | null;
+ height?: number | null;
+ focalX?: number | null;
+ focalY?: number | null;
+}
+/**
+ * This interface was referenced by `Config`'s JSON-Schema
+ * via the `definition` "simple-relationship".
+ */
+export interface SimpleRelationship {
+ id: string;
+ title?: string | null;
+ updatedAt: string;
+ createdAt: string;
+}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "users".
@@ -1672,6 +1709,14 @@ export interface PayloadLockedDocument {
relationTo: 'constructor-options';
value: string | ConstructorOption;
} | null)
+ | ({
+ relationTo: 'bulk-uploads';
+ value: string | BulkUpload;
+ } | null)
+ | ({
+ relationTo: 'simple-relationship';
+ value: string | SimpleRelationship;
+ } | null)
| ({
relationTo: 'users';
value: string | User;
@@ -3065,6 +3110,34 @@ export interface ConstructorOptionsSelect {
focalX?: T;
focalY?: T;
}
+/**
+ * This interface was referenced by `Config`'s JSON-Schema
+ * via the `definition` "bulk-uploads_select".
+ */
+export interface BulkUploadsSelect {
+ title?: T;
+ relationship?: T;
+ updatedAt?: T;
+ createdAt?: T;
+ url?: T;
+ thumbnailURL?: T;
+ filename?: T;
+ mimeType?: T;
+ filesize?: T;
+ width?: T;
+ height?: T;
+ focalX?: T;
+ focalY?: T;
+}
+/**
+ * This interface was referenced by `Config`'s JSON-Schema
+ * via the `definition` "simple-relationship_select".
+ */
+export interface SimpleRelationshipSelect {
+ title?: T;
+ updatedAt?: T;
+ createdAt?: T;
+}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "users_select".
diff --git a/test/uploads/shared.ts b/test/uploads/shared.ts
index 3e8944e84..f33d5663a 100644
--- a/test/uploads/shared.ts
+++ b/test/uploads/shared.ts
@@ -31,3 +31,4 @@ export const skipAllowListSafeFetchMediaSlug = 'skip-allow-list-safe-fetch-media
export const listViewPreviewSlug = 'list-view-preview'
export const threeDimensionalSlug = 'three-dimensional'
export const constructorOptionsSlug = 'constructor-options'
+export const bulkUploadsSlug = 'bulk-uploads'