fix: join field does not show validation error (#11170)

### What?

Assuming you have a hook in your collection that is looking for certain
conditions to be met related to the join field. The way you would
prevent it is to throw a `new ValidationError()` with errors containing
the path of the field. Previously, the error message for the field would
not show in the admin UI at all.

### Why?

Users need to be able to see any custom error messages for joins field
in the UI so they can address the issue.

### How?

Adds an error class and display the FieldError in the Join field in the
UI component.
This commit is contained in:
Dan Ribbens
2025-02-13 23:09:04 -05:00
committed by GitHub
parent 12f51bad5f
commit dd28959916
4 changed files with 63 additions and 8 deletions

View File

@@ -1,5 +1,7 @@
import type { CollectionConfig } from 'payload'
import { ValidationError } from 'payload'
import { categoriesSlug, hiddenPostsSlug, postsSlug } from '../shared.js'
import { singularSlug } from './Singular.js'
@@ -160,5 +162,33 @@ export const Categories: CollectionConfig = {
isFiltered: { not_equals: true },
},
},
{
name: 'joinWithError',
type: 'join',
collection: postsSlug,
on: 'category',
hooks: {
beforeValidate: [
({ data }) => {
if (data?.enableErrorOnJoin) {
throw new ValidationError({
collection: 'categories',
errors: [
{
message: 'enableErrorOnJoin is true',
path: 'joinWithError',
},
],
})
}
},
],
},
},
{
name: 'enableErrorOnJoin',
type: 'checkbox',
defaultValue: false,
},
],
}

View File

@@ -18,10 +18,10 @@ import {
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
import { navigateToDoc } from '../helpers/e2e/navigateToDoc.js'
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
import { EXPECT_TIMEOUT, TEST_TIMEOUT_LONG } from '../playwright.config.js'
import { categoriesJoinRestrictedSlug, categoriesSlug, postsSlug, uploadsSlug } from './shared.js'
import { reInitializeDB } from '../helpers/reInitializeDB.js'
import { RESTClient } from '../helpers/rest.js'
import { EXPECT_TIMEOUT, TEST_TIMEOUT_LONG } from '../playwright.config.js'
import { categoriesJoinRestrictedSlug, categoriesSlug, postsSlug, uploadsSlug } from './shared.js'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
@@ -37,7 +37,7 @@ describe('Join Field', () => {
let categoriesURL: AdminUrlUtil
let uploadsURL: AdminUrlUtil
let categoriesJoinRestrictedURL: AdminUrlUtil
let categoryID: string | number
let categoryID: number | string
beforeAll(async ({ browser }, testInfo) => {
testInfo.setTimeout(TEST_TIMEOUT_LONG)
@@ -474,4 +474,13 @@ describe('Join Field', () => {
await page.goto(url.admin + '/create-first-user')
await expect(page.locator('.field-type.join')).toBeHidden()
})
test('should render error message when ValidationError is thrown', async () => {
await navigateToDoc(page, categoriesURL)
await page.locator('#field-enableErrorOnJoin').click()
await page.locator('#action-save').click()
await expect(page.locator('#field-joinWithError')).toContainText('enableErrorOnJoin is true')
})
})

View File

@@ -51,6 +51,7 @@ export interface Config {
localizedPolymorphic: 'posts';
localizedPolymorphics: 'posts';
filtered: 'posts';
joinWithError: 'posts';
hiddenPosts: 'hidden-posts';
singulars: 'singular';
};
@@ -336,6 +337,11 @@ export interface Category {
docs?: (string | Post)[] | null;
hasNextPage?: boolean | null;
} | null;
joinWithError?: {
docs?: (string | Post)[] | null;
hasNextPage?: boolean | null;
} | null;
enableErrorOnJoin?: boolean | null;
updatedAt: string;
createdAt: string;
}
@@ -730,6 +736,8 @@ export interface CategoriesSelect<T extends boolean = true> {
localizedPolymorphics?: T;
singulars?: T;
filtered?: T;
joinWithError?: T;
enableErrorOnJoin?: T;
updatedAt?: T;
createdAt?: T;
}