[Embeddable Rebuild] Fix panel title sync with saved object when using defaultTitle (#225237)

## Summary

Bug description (also the bug video below):
The bug occurred in the Customize Panel Editor, where the
PanelTitle—even when matching the defaultTitle from the central Saved
Object—was not always properly synchronized with that object. This led
to situations where the title was incorrectly stored as a custom
override, breaking the link to the saved object. There were two specific
cases where this happened:

Adding a panel from the library, then opening Customize Panel and
clicking Apply without making changes
After adding a panel from the library, the user opens the Customize
Panel Editor via the settings icon. Without making any changes to the
title, they exit the editor by clicking the Apply button instead of the
close icon. This causes the defaultTitle to be unnecessarily written
into the title field of the API object, which then treats it as a custom
title—breaking future synchronization with the saved object.

Resetting the title to default after a change
The user changes the panel title in the Customize Panel Editor and
clicks Apply. Later, they reopen the editor and click Reset to default.
This correctly restores the title from the central saved object, but it
is again written into the title field of the API object. Although the
value matches the current defaultTitle, it is now treated as custom. If
the central title changes later, the panel title will no longer
update—breaking synchronization again.

Fix:
The logic was updated to correctly detect when the panel title matches
the defaultTitle. In such cases, it clears the title field in the API
(by setting it to undefined) to indicate that the panel should inherit
the title from the saved object. This ensures proper synchronization:
any future updates to the saved object's title will be reflected
automatically in the panel.


Closes #188858

Below the bug video:


https://github.com/user-attachments/assets/f784679c-8eaa-47b4-942d-e3802faee076
This commit is contained in:
Ola Pawlus 2025-06-26 14:22:53 +02:00 committed by GitHub
parent 75ba373fbd
commit cead1a7821
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 18 additions and 1 deletions

View file

@ -89,6 +89,17 @@ describe('customize panel editor', () => {
expect(titleInput).toHaveValue('Default title');
});
// Even if the input value matches defaultTitle on apply, we expect setTitle(undefined) to be called, meaning the title is treated as "not customized".
it('should not set panel custom title if it matches default title on apply', async () => {
api.defaultTitle$ = new BehaviorSubject<string | undefined>('Default title');
renderPanelEditor();
const titleInput = screen.getByTestId('customEmbeddablePanelTitleInput');
expect(titleInput).toHaveValue('Default title');
await userEvent.click(screen.getByTestId('saveCustomizePanelButton'));
expect(setTitle).toHaveBeenCalledWith(undefined);
expect(api.title$?.getValue()).toBeUndefined();
});
it('should use title even when empty string', () => {
api.defaultTitle$ = new BehaviorSubject<string | undefined>('Default title');
setTitle('');

View file

@ -99,7 +99,13 @@ export const CustomizePanelEditor = ({
const dateFormat = useMemo(() => core.uiSettings.get<string>(UI_SETTINGS.DATE_FORMAT), []);
const save = () => {
if (panelTitle !== api.title$?.value) api.setTitle?.(panelTitle);
// If the panel title matches the default title, we set api.title to undefined to indicate there's no custom title.
// This ensures the panel stays in sync with the centrally saved object's title and reflects any updates to its title.
if (panelTitle === api?.defaultTitle$?.value) {
api.setTitle?.(undefined);
} else if (panelTitle !== api.title$?.value) {
api.setTitle?.(panelTitle);
}
if (hideTitle !== api.hideTitle$?.value) api.setHideTitle?.(hideTitle);
if (panelDescription !== api.description$?.value) api.setDescription?.(panelDescription);