Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions packages/payload/src/fields/hooks/afterChange/promise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ export const promise = async ({
const indexPathSegments = indexPath ? indexPath.split('-').filter(Boolean)?.map(Number) : []
const getNestedValue = (data: JsonObject, path: string[]) =>
path.reduce((acc, key) => (acc && acc[key] !== undefined ? acc[key] : undefined), data)
const previousValData =
previousSiblingDoc && Object.keys(previousSiblingDoc).length > 0
? previousSiblingDoc
: previousDoc

if (fieldAffectsData(field)) {
// Execute hooks
Expand All @@ -90,7 +94,8 @@ export const promise = async ({
path: pathSegments,
previousDoc,
previousSiblingDoc,
previousValue: getNestedValue(previousDoc, pathSegments) ?? previousDoc?.[field.name],
previousValue:
getNestedValue(previousValData, pathSegments) ?? previousValData?.[field.name],
req,
schemaPath: schemaPathSegments,
siblingData,
Expand Down Expand Up @@ -172,7 +177,7 @@ export const promise = async ({
parentPath: path + '.' + rowIndex,
parentSchemaPath: schemaPath + '.' + block.slug,
previousDoc,
previousSiblingDoc: previousDoc?.[field.name]?.[rowIndex] || ({} as JsonObject),
previousSiblingDoc: previousValData?.[field.name]?.[rowIndex] || ({} as JsonObject),
req,
siblingData: siblingData?.[field.name]?.[rowIndex] || {},
siblingDoc: row ? { ...row } : {},
Expand Down
65 changes: 64 additions & 1 deletion test/hooks/collections/NestedAfterChangeHook/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import type { CollectionConfig } from 'payload'

import { BlocksFeature, lexicalEditor, LinkFeature } from '@payloadcms/richtext-lexical'
export const nestedAfterChangeHooksSlug = 'nested-after-change-hooks'

const NestedAfterChangeHooks: CollectionConfig = {
Expand All @@ -22,7 +24,6 @@ const NestedAfterChangeHooks: CollectionConfig = {
hooks: {
afterChange: [
({ previousValue, operation }) => {
console.log(previousValue)
if (operation === 'update' && typeof previousValue === 'undefined') {
throw new Error('previousValue is missing in nested beforeChange hook')
}
Expand All @@ -34,6 +35,68 @@ const NestedAfterChangeHooks: CollectionConfig = {
},
],
},
{
name: 'lexical',
type: 'richText',
editor: lexicalEditor({
features: ({ defaultFeatures }) => [
...defaultFeatures,
BlocksFeature({
blocks: [
{
slug: 'nestedBlock',
fields: [
{
type: 'text',
name: 'nestedAfterChange',
hooks: {
afterChange: [
({ previousValue, operation }) => {
if (operation === 'update' && typeof previousValue === 'undefined') {
throw new Error('previousValue is missing in nested beforeChange hook')
}
},
],
},
},
],
},
],
}),
LinkFeature({
fields: [
{
type: 'blocks',
name: 'linkBlocks',
blocks: [
{
slug: 'nestedLinkBlock',
fields: [
{
name: 'nestedRelationship',
type: 'relationship',
relationTo: 'relations',
hooks: {
afterChange: [
({ previousValue, operation }) => {
if (operation === 'update' && typeof previousValue === 'undefined') {
throw new Error(
'previousValue is missing in nested beforeChange hook',
)
}
},
],
},
},
],
},
],
},
],
}),
],
}),
},
],
}

Expand Down
105 changes: 105 additions & 0 deletions test/hooks/int.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,111 @@ describe('Hooks', () => {

expect(updatedDoc).toBeDefined()
})

it('should populate previousValue in Lexical nested afterChange hooks', async () => {
const relationID = await payload.create({
collection: 'relations',
data: {
title: 'Relation for nested afterChange',
},
})

// this collection will throw an error if previousValue is not defined in nested afterChange hook
const nestedAfterChangeDoc = await payload.create({
collection: nestedAfterChangeHooksSlug,
data: {
text: 'initial',
group: {
array: [
{
nestedAfterChange: 'initial',
},
],
},
lexical: {
root: {
children: [
{
children: [
{
children: [
{
detail: 0,
format: 0,
mode: 'normal',
style: '',
text: 'link',
type: 'text',
version: 1,
},
],
direction: null,
format: '',
indent: 0,
type: 'link',
version: 3,
fields: {
linkBlocks: [
{
id: '693ade72068ea07ba13edcab',
blockType: 'nestedLinkBlock',
nestedRelationship: relationID.id,
},
],
},
id: '693ade70068ea07ba13edca9',
},
],
direction: null,
format: '',
indent: 0,
type: 'paragraph',
version: 1,
textFormat: 0,
textStyle: '',
},
{
type: 'block',
version: 2,
format: '',
fields: {
id: '693adf3c068ea07ba13edcae',
blockName: '',
nestedAfterChange: 'test',
blockType: 'nestedBlock',
},
},
{
children: [],
direction: null,
format: '',
indent: 0,
type: 'paragraph',
version: 1,
textFormat: 0,
textStyle: '',
},
],
direction: null,
format: '',
indent: 0,
type: 'root',
version: 1,
},
},
},
})

await expect(
payload.update({
collection: 'nested-after-change-hooks',
id: nestedAfterChangeDoc.id,
data: {
text: 'updated',
},
}),
).resolves.not.toThrow()
})
})

describe('auth collection hooks', () => {
Expand Down
16 changes: 16 additions & 0 deletions test/hooks/payload-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,21 @@ export interface NestedAfterChangeHook {
}[]
| null;
};
lexical?: {
root: {
type: string;
children: {
type: any;
version: number;
[k: string]: unknown;
}[];
direction: ('ltr' | 'rtl') | null;
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
indent: number;
version: number;
};
[k: string]: unknown;
} | null;
updatedAt: string;
createdAt: string;
}
Expand Down Expand Up @@ -943,6 +958,7 @@ export interface NestedAfterChangeHooksSelect<T extends boolean = true> {
id?: T;
};
};
lexical?: T;
updatedAt?: T;
createdAt?: T;
}
Expand Down