fix: separate collection docs with same ids were excluded in selectable (#6499)
This commit is contained in:
@@ -495,6 +495,11 @@ const RelationshipField: React.FC<RelationshipFieldProps> = (props) => {
|
||||
}}
|
||||
disabled={readOnly || formProcessing || drawerIsOpen}
|
||||
filterOption={enableWordBoundarySearch ? filterOption : undefined}
|
||||
getOptionValue={(option) => {
|
||||
return hasMany && Array.isArray(relationTo)
|
||||
? `${option.relationTo}_${option.value}`
|
||||
: option.value
|
||||
}}
|
||||
isLoading={isLoading}
|
||||
isMulti={hasMany}
|
||||
isSortable={isSortable}
|
||||
|
||||
@@ -9,3 +9,6 @@ export const relationWithTitleSlug = 'relation-with-title'
|
||||
export const relationUpdatedExternallySlug = 'relation-updated-externally'
|
||||
export const collection1Slug = 'collection-1'
|
||||
export const collection2Slug = 'collection-2'
|
||||
export const videoCollectionSlug = 'videos'
|
||||
export const podcastCollectionSlug = 'podcasts'
|
||||
export const mixedMediaCollectionSlug = 'mixed-media'
|
||||
|
||||
@@ -9,6 +9,8 @@ import { PrePopulateFieldUI } from './PrePopulateFieldUI/index.js'
|
||||
import {
|
||||
collection1Slug,
|
||||
collection2Slug,
|
||||
mixedMediaCollectionSlug,
|
||||
podcastCollectionSlug,
|
||||
relationFalseFilterOptionSlug,
|
||||
relationOneSlug,
|
||||
relationRestrictedSlug,
|
||||
@@ -17,6 +19,7 @@ import {
|
||||
relationUpdatedExternallySlug,
|
||||
relationWithTitleSlug,
|
||||
slug,
|
||||
videoCollectionSlug,
|
||||
} from './collectionSlugs.js'
|
||||
|
||||
export interface FieldsRelationship {
|
||||
@@ -325,6 +328,51 @@ export default buildConfigWithDefaults({
|
||||
],
|
||||
slug: collection2Slug,
|
||||
},
|
||||
{
|
||||
slug: videoCollectionSlug,
|
||||
admin: {
|
||||
useAsTitle: 'title',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: podcastCollectionSlug,
|
||||
admin: {
|
||||
useAsTitle: 'title',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: mixedMediaCollectionSlug,
|
||||
fields: [
|
||||
{
|
||||
type: 'relationship',
|
||||
name: 'relatedMedia',
|
||||
relationTo: [videoCollectionSlug, podcastCollectionSlug],
|
||||
hasMany: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
onInit: async (payload) => {
|
||||
await payload.create({
|
||||
@@ -461,5 +509,22 @@ export default buildConfigWithDefaults({
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
for (let i = 0; i < 2; i++) {
|
||||
await payload.create({
|
||||
collection: videoCollectionSlug,
|
||||
data: {
|
||||
id: i,
|
||||
title: `Video ${i}`,
|
||||
},
|
||||
})
|
||||
await payload.create({
|
||||
collection: podcastCollectionSlug,
|
||||
data: {
|
||||
id: i,
|
||||
title: `Podcast ${i}`,
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import type { Page } from '@playwright/test'
|
||||
import type { Payload } from 'payload'
|
||||
|
||||
import { expect, test } from '@playwright/test'
|
||||
import path from 'path'
|
||||
@@ -22,12 +21,12 @@ import {
|
||||
openDocControls,
|
||||
openDocDrawer,
|
||||
saveDocAndAssert,
|
||||
throttleTest,
|
||||
} from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { POLL_TOPASS_TIMEOUT, TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
import {
|
||||
mixedMediaCollectionSlug,
|
||||
relationFalseFilterOptionSlug,
|
||||
relationOneSlug,
|
||||
relationRestrictedSlug,
|
||||
@@ -397,6 +396,26 @@ describe('fields - relationship', () => {
|
||||
await expect(options).toContainText('truth')
|
||||
})
|
||||
|
||||
test('should allow docs with same ID but different collections to be selectable', async () => {
|
||||
const mixedMedia = new AdminUrlUtil(serverURL, mixedMediaCollectionSlug)
|
||||
await page.goto(mixedMedia.create)
|
||||
// wait for relationship options to load
|
||||
const podcastsFilterOptionsReq = page.waitForResponse(/api\/podcasts/)
|
||||
const videosFilterOptionsReq = page.waitForResponse(/api\/videos/)
|
||||
// select relationshipMany field that relies on siblingData field above
|
||||
await page.locator('#field-relatedMedia .rs__control').click()
|
||||
await podcastsFilterOptionsReq
|
||||
await videosFilterOptionsReq
|
||||
|
||||
const options = page.locator('.rs__option')
|
||||
await expect(options).toHaveCount(4) // 4 docs
|
||||
await options.locator(`text=Video 0`).click()
|
||||
|
||||
await page.locator('#field-relatedMedia .rs__control').click()
|
||||
const remainingOptions = page.locator('.rs__option')
|
||||
await expect(remainingOptions).toHaveCount(3) // 3 docs
|
||||
})
|
||||
|
||||
// TODO: Flaky test in CI - fix.
|
||||
test.skip('should open document drawer from read-only relationships', async () => {
|
||||
const editURL = url.edit(docWithExistingRelations.id)
|
||||
|
||||
@@ -18,6 +18,9 @@ export interface Config {
|
||||
'relation-updated-externally': RelationUpdatedExternally;
|
||||
'collection-1': Collection1;
|
||||
'collection-2': Collection2;
|
||||
videos: Video;
|
||||
podcasts: Podcast;
|
||||
mixedMedia: MixedMedia;
|
||||
users: User;
|
||||
'payload-preferences': PayloadPreference;
|
||||
'payload-migrations': PayloadMigration;
|
||||
@@ -192,6 +195,47 @@ export interface Collection2 {
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "videos".
|
||||
*/
|
||||
export interface Video {
|
||||
id: number;
|
||||
title?: string | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "podcasts".
|
||||
*/
|
||||
export interface Podcast {
|
||||
id: number;
|
||||
title?: string | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "mixedMedia".
|
||||
*/
|
||||
export interface MixedMedia {
|
||||
id: string;
|
||||
relatedMedia?:
|
||||
| (
|
||||
| {
|
||||
relationTo: 'videos';
|
||||
value: number | Video;
|
||||
}
|
||||
| {
|
||||
relationTo: 'podcasts';
|
||||
value: number | Podcast;
|
||||
}
|
||||
)[]
|
||||
| null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "users".
|
||||
|
||||
Reference in New Issue
Block a user