Skip to content

Commit

Permalink
fix(ui): addFieldRow set modified (#9324)
Browse files Browse the repository at this point in the history
Fixes #9264. When externally updating array or block rows through the
`addFieldRow` or `replaceFieldRow` methods, nested rich text fields
along with any custom components within them are never rendered. This is
because unless the form is explicitly set to modified, as the default
array and blocks fields currently do, the newly generated form-state
will skip the rendering step. Now, the underlying callbacks themselves
automatically set the form to modified to trigger rendering.
  • Loading branch information
jacobsfletch authored Nov 19, 2024
1 parent a50029f commit 0f3f6e7
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 10 deletions.
5 changes: 2 additions & 3 deletions packages/ui/src/fields/Array/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const ArrayFieldComponent: ArrayFieldClientComponent = (props) => {
schemaPath: schemaPathFromProps,
validate,
} = props

const schemaPath = schemaPathFromProps ?? name

const minRows = (minRowsProp ?? required) ? 1 : 0
Expand Down Expand Up @@ -129,13 +130,11 @@ export const ArrayFieldComponent: ArrayFieldClientComponent = (props) => {
schemaPath,
})

setModified(true)

setTimeout(() => {
scrollToID(`${path}-row-${rowIndex}`)
}, 0)
},
[addFieldRow, path, schemaPath, setModified],
[addFieldRow, path, schemaPath],
)

const duplicateRow = useCallback(
Expand Down
4 changes: 1 addition & 3 deletions packages/ui/src/fields/Blocks/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,11 @@ const BlocksFieldComponent: BlocksFieldClientComponent = (props) => {
schemaPath,
})

setModified(true)

setTimeout(() => {
scrollToID(`${path}-row-${rowIndex + 1}`)
}, 0)
},
[addFieldRow, path, schemaPath, setModified],
[addFieldRow, path, schemaPath],
)

const duplicateRow = useCallback(
Expand Down
4 changes: 4 additions & 0 deletions packages/ui/src/forms/Form/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,8 @@ export const Form: React.FC<FormProps> = (props) => {
rowIndex,
subFieldState,
})

setModified(true)
},
[dispatchFields, getDataByPath],
)
Expand All @@ -541,6 +543,8 @@ export const Form: React.FC<FormProps> = (props) => {
rowIndex,
subFieldState,
})

setModified(true)
},
[dispatchFields, getDataByPath],
)
Expand Down
4 changes: 2 additions & 2 deletions test/_community/payload-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ export interface Config {
user: User & {
collection: 'users';
};
jobs?: {
jobs: {
tasks: unknown;
workflows?: unknown;
workflows: unknown;
};
}
export interface UserAuthOperations {
Expand Down
29 changes: 29 additions & 0 deletions test/fields/collections/Array/AddRowButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use client'

import { useForm } from '@payloadcms/ui'

const AddRowButton = () => {
const { addFieldRow } = useForm()

const handleClick = () => {
addFieldRow({
path: 'externallyUpdatedArray',
schemaPath: 'externallyUpdatedArray',
subFieldState: {
text: {
initialValue: 'Hello, world!',
valid: true,
value: 'Hello, world!',
},
},
})
}

return (
<button id="updateArrayExternally" onClick={handleClick} type="button">
Add Row
</button>
)
}

export default AddRowButton
11 changes: 11 additions & 0 deletions test/fields/collections/Array/CustomField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { TextFieldServerComponent } from 'payload'

import { TextField } from '@payloadcms/ui'

export const CustomField: TextFieldServerComponent = ({ clientField, path }) => {
return (
<div id="custom-field">
<TextField field={clientField} path={path as string} />
</div>
)
}
6 changes: 6 additions & 0 deletions test/fields/collections/Array/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,4 +295,10 @@ describe('Array', () => {
'Updated 3 Array Fields successfully.',
)
})

test('should externally update array rows and render custom fields', async () => {
await page.goto(url.create)
await page.locator('#updateArrayExternally').click()
await expect(page.locator('#custom-field')).toBeVisible()
})
})
24 changes: 24 additions & 0 deletions test/fields/collections/Array/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,30 @@ const ArrayFields: CollectionConfig = {
},
],
},
{
name: 'externallyUpdatedArray',
type: 'array',
fields: [
{
name: 'customField',
type: 'ui',
admin: {
components: {
Field: '/collections/Array/CustomField.js#CustomField',
},
},
},
],
},
{
name: 'ui',
type: 'ui',
admin: {
components: {
Field: '/collections/Array/AddRowButton.js',
},
},
},
],
slug: arrayFieldsSlug,
versions: true,
Expand Down
16 changes: 14 additions & 2 deletions test/fields/payload-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,11 @@ export interface ArrayField {
id?: string | null;
}[]
| null;
externallyUpdatedArray?:
| {
id?: string | null;
}[]
| null;
updatedAt: string;
createdAt: string;
}
Expand Down Expand Up @@ -2084,6 +2089,13 @@ export interface ArrayFieldsSelect<T extends boolean = true> {
};
id?: T;
};
externallyUpdatedArray?:
| T
| {
customField?: T;
id?: T;
};
ui?: T;
updatedAt?: T;
createdAt?: T;
}
Expand Down Expand Up @@ -3400,6 +3412,6 @@ export interface Auth {


declare module 'payload' {
// @ts-ignore
// @ts-ignore
export interface GeneratedTypes extends Config {}
}
}

0 comments on commit 0f3f6e7

Please sign in to comment.