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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
- Fixed a bug where pressing <kbd>Ctrl/Cmd</kbd> + <kbd>S</kbd> in a slideout could also save the page behind it. ([#19705](https://github.com/craftcms/cms/pull/19705))
- Fixed a bug where Shift-selecting a shorter range didn’t deselect items outside the new range. ([#19727](https://github.com/craftcms/cms/pull/19727))
- Fixed a bug where select inputs could lose their selected value if their options were loaded asynchronously. ([#19728](https://github.com/craftcms/cms/pull/19728))
- Fixed a bug where reactive controls in element editors didn’t refresh their field layouts, including nested form scopes. ([#19769](https://github.com/craftcms/cms/pull/19769))

### Assets
- Migrated Control Panel uploads to the native Uppy picker and shared upload sessions, including user photos.
Expand Down
2 changes: 2 additions & 0 deletions resources/js/modules/elements/components/ElementEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
renderer,
refreshAfterNestedChange,
refreshForm,
refreshLayout,
save,
sidebarErrors,
sidebarPayload,
Expand Down Expand Up @@ -383,6 +384,7 @@
ref="renderer"
:payload="formPayload"
:errors="errors"
:refresh="formPayload.refreshable ? refreshLayout : undefined"
:modified="autosave.modified.value"
:disabled="workflowReviewLocked"
@update:mutation="onMutation"
Expand Down
29 changes: 25 additions & 4 deletions resources/js/modules/elements/composables/useElementEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,10 +508,14 @@ export function useElementEditor({saveData, root}: Options = {}) {
return;
}

applyingSavedPayload = true;
savedForm.value = response.form;
await nextTick();
applyingSavedPayload = false;
// A nested scope's payload is only that form; the renderer that asked for
// it reconciles it into the layout.
if (JSON.stringify(scope) === JSON.stringify(rootScope)) {
applyingSavedPayload = true;
savedForm.value = response.form;
await nextTick();
applyingSavedPayload = false;
}

if (generation !== refreshGeneration) {
return;
Expand All @@ -522,6 +526,22 @@ export function useElementEditor({saveData, root}: Options = {}) {
return response;
}

/**
* Refreshes the field layout for the renderer's reactive controls.
*/
async function refreshLayout(
_values: FormValues,
scope?: string[]
): Promise<FormPayload> {
const response = await refreshForm(scope);

if (!response) {
throw new Error('A newer refresh superseded this one.');
}

return response.form as FormPayload;
}

// Set for the duration of one submission when an alternate action owns it,
// so the shared save pipeline (elevated sessions, error handling, the
// processing flag) is reused rather than reimplemented per action.
Expand Down Expand Up @@ -899,6 +919,7 @@ export function useElementEditor({saveData, root}: Options = {}) {
renderer,
refreshAfterNestedChange,
refreshForm,
refreshLayout,
save,
sidebarErrors,
sidebarPayload,
Expand Down
Loading