Merge branch 'main' of github.com:payloadcms/payload into fix/empty-in-array
This commit is contained in:
@@ -3,63 +3,81 @@ import type { CollectionConfig } from '../../../../packages/payload/src/collecti
|
||||
export const relationshipFieldsSlug = 'relationship-fields'
|
||||
|
||||
const RelationshipFields: CollectionConfig = {
|
||||
slug: relationshipFieldsSlug,
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'relationship',
|
||||
type: 'relationship',
|
||||
relationTo: ['text-fields', 'array-fields'],
|
||||
required: true,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationToSelf',
|
||||
type: 'relationship',
|
||||
relationTo: relationshipFieldsSlug,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationToSelfSelectOnly',
|
||||
type: 'relationship',
|
||||
relationTo: relationshipFieldsSlug,
|
||||
admin: {
|
||||
allowCreate: false,
|
||||
},
|
||||
relationTo: relationshipFieldsSlug,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationWithDynamicDefault',
|
||||
type: 'relationship',
|
||||
defaultValue: ({ user }) => user?.id,
|
||||
relationTo: 'users',
|
||||
defaultValue: ({ user }) => user.id,
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationHasManyWithDynamicDefault',
|
||||
type: 'relationship',
|
||||
defaultValue: ({ user }) =>
|
||||
user
|
||||
? {
|
||||
relationTo: 'users',
|
||||
value: user.id,
|
||||
}
|
||||
: undefined,
|
||||
relationTo: ['users'],
|
||||
defaultValue: ({ user }) => ({
|
||||
relationTo: 'users',
|
||||
value: user.id,
|
||||
}),
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipWithMin',
|
||||
type: 'relationship',
|
||||
relationTo: 'text-fields',
|
||||
hasMany: true,
|
||||
minRows: 2,
|
||||
relationTo: 'text-fields',
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipWithMax',
|
||||
type: 'relationship',
|
||||
relationTo: 'text-fields',
|
||||
hasMany: true,
|
||||
maxRows: 2,
|
||||
relationTo: 'text-fields',
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'relationshipHasMany',
|
||||
type: 'relationship',
|
||||
relationTo: 'text-fields',
|
||||
hasMany: true,
|
||||
relationTo: 'text-fields',
|
||||
type: 'relationship',
|
||||
},
|
||||
{
|
||||
name: 'array',
|
||||
fields: [
|
||||
{
|
||||
name: 'relationship',
|
||||
relationTo: 'text-fields',
|
||||
type: 'relationship',
|
||||
},
|
||||
],
|
||||
type: 'array',
|
||||
},
|
||||
],
|
||||
slug: relationshipFieldsSlug,
|
||||
}
|
||||
|
||||
export default RelationshipFields
|
||||
|
||||
@@ -44,18 +44,18 @@ export default buildConfigWithDefaults({
|
||||
collections: [
|
||||
LexicalFields,
|
||||
{
|
||||
slug: 'users',
|
||||
auth: true,
|
||||
admin: {
|
||||
useAsTitle: 'email',
|
||||
},
|
||||
auth: true,
|
||||
fields: [
|
||||
{
|
||||
name: 'canViewConditionalField',
|
||||
type: 'checkbox',
|
||||
defaultValue: true,
|
||||
type: 'checkbox',
|
||||
},
|
||||
],
|
||||
slug: 'users',
|
||||
},
|
||||
ArrayFields,
|
||||
BlockFields,
|
||||
@@ -81,8 +81,8 @@ export default buildConfigWithDefaults({
|
||||
],
|
||||
localization: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en', 'es'],
|
||||
fallback: true,
|
||||
locales: ['en', 'es'],
|
||||
},
|
||||
onInit: async (payload) => {
|
||||
await payload.create({
|
||||
|
||||
@@ -1093,7 +1093,7 @@ describe('fields', () => {
|
||||
.locator('#field-relationship .relationship-add-new__relation-button--text-fields')
|
||||
.click()
|
||||
|
||||
const textField = page.locator('#field-text')
|
||||
const textField = page.locator('.drawer__content #field-text')
|
||||
const textValue = 'hello'
|
||||
|
||||
await textField.fill(textValue)
|
||||
@@ -1217,7 +1217,7 @@ describe('fields', () => {
|
||||
.locator('#field-relationship .relationship-add-new__relation-button--text-fields')
|
||||
.click()
|
||||
|
||||
await page.locator('#field-text').fill('something')
|
||||
await page.locator('.drawer__content #field-text').fill('something')
|
||||
|
||||
await page.locator('[id^=doc-drawer_text-fields_1_] #action-save').click()
|
||||
await expect(page.locator('.Toastify')).toContainText('successfully')
|
||||
@@ -1290,7 +1290,7 @@ describe('fields', () => {
|
||||
await page.getByRole('button', { name: 'Edit Seeded text document' }).click()
|
||||
|
||||
// Fill 'text' field of 'Seeded text document'
|
||||
await page.locator('#field-text').fill('some updated text value')
|
||||
await page.locator('.drawer__content #field-text').fill('some updated text value')
|
||||
|
||||
// Save drawer (not parent page) with hotkey
|
||||
await saveDocHotkeyAndAssert(page)
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
} from './collections/Group'
|
||||
import { defaultNumber, numberDoc } from './collections/Number'
|
||||
import { pointDoc } from './collections/Point'
|
||||
import { relationshipFieldsSlug } from './collections/Relationship'
|
||||
import { tabsDoc } from './collections/Tabs'
|
||||
import {
|
||||
localizedTextValue,
|
||||
@@ -73,6 +74,122 @@ describe('Fields', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('relationship', () => {
|
||||
let textDoc
|
||||
let otherTextDoc
|
||||
let selfReferencing
|
||||
let parent
|
||||
let child
|
||||
let grandChild
|
||||
let relationshipInArray
|
||||
const textDocText = 'text document'
|
||||
const otherTextDocText = 'alt text'
|
||||
const relationshipText = 'relationship text'
|
||||
|
||||
beforeAll(async () => {
|
||||
textDoc = await payload.create({
|
||||
collection: 'text-fields',
|
||||
data: {
|
||||
text: textDocText,
|
||||
},
|
||||
})
|
||||
otherTextDoc = await payload.create({
|
||||
collection: 'text-fields',
|
||||
data: {
|
||||
text: otherTextDocText,
|
||||
},
|
||||
})
|
||||
const relationship = { relationTo: 'text-fields', value: textDoc.id }
|
||||
parent = await payload.create({
|
||||
collection: relationshipFieldsSlug,
|
||||
data: {
|
||||
relationship,
|
||||
text: relationshipText,
|
||||
},
|
||||
})
|
||||
|
||||
child = await payload.create({
|
||||
collection: relationshipFieldsSlug,
|
||||
data: {
|
||||
relationToSelf: parent.id,
|
||||
relationship,
|
||||
text: relationshipText,
|
||||
},
|
||||
})
|
||||
|
||||
grandChild = await payload.create({
|
||||
collection: relationshipFieldsSlug,
|
||||
data: {
|
||||
relationToSelf: child.id,
|
||||
relationship,
|
||||
text: relationshipText,
|
||||
},
|
||||
})
|
||||
|
||||
selfReferencing = await payload.create({
|
||||
collection: relationshipFieldsSlug,
|
||||
data: {
|
||||
relationship,
|
||||
text: relationshipText,
|
||||
},
|
||||
})
|
||||
|
||||
relationshipInArray = await payload.create({
|
||||
collection: relationshipFieldsSlug,
|
||||
data: {
|
||||
array: [
|
||||
{
|
||||
relationship: otherTextDoc.id,
|
||||
},
|
||||
],
|
||||
relationship,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('should query parent self-reference', async () => {
|
||||
const childResult = await payload.find({
|
||||
collection: relationshipFieldsSlug,
|
||||
where: {
|
||||
relationToSelf: { equals: parent.id },
|
||||
},
|
||||
})
|
||||
|
||||
const grandChildResult = await payload.find({
|
||||
collection: relationshipFieldsSlug,
|
||||
where: {
|
||||
relationToSelf: { equals: child.id },
|
||||
},
|
||||
})
|
||||
|
||||
const anyChildren = await payload.find({
|
||||
collection: relationshipFieldsSlug,
|
||||
})
|
||||
const allChildren = await payload.find({
|
||||
collection: relationshipFieldsSlug,
|
||||
where: {
|
||||
'relationToSelf.text': { equals: relationshipText },
|
||||
},
|
||||
})
|
||||
|
||||
expect(childResult.docs[0].id).toStrictEqual(child.id)
|
||||
expect(grandChildResult.docs[0].id).toStrictEqual(grandChild.id)
|
||||
expect(allChildren.docs).toHaveLength(2)
|
||||
})
|
||||
|
||||
it('should query relationship inside array', async () => {
|
||||
const result = await payload.find({
|
||||
collection: relationshipFieldsSlug,
|
||||
where: {
|
||||
'array.relationship.text': { equals: otherTextDocText },
|
||||
},
|
||||
})
|
||||
|
||||
expect(result.docs).toHaveLength(1)
|
||||
expect(result.docs[0]).toMatchObject(relationshipInArray)
|
||||
})
|
||||
})
|
||||
|
||||
describe('timestamps', () => {
|
||||
const tenMinutesAgo = new Date(Date.now() - 1000 * 60 * 10)
|
||||
let doc
|
||||
|
||||
Reference in New Issue
Block a user