From f5b6dd571bde99f5d1ebc59e4d0f22aaee2bb524 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 5 Dec 2024 10:46:22 -0700 Subject: [PATCH] [dashboard] Do not reset panel to undefined or empty last saved state --- .../unsaved_changes/children_unsaved_changes.test.ts | 6 +++--- .../unsaved_changes/initialize_unsaved_changes.ts | 9 +++++++++ .../interfaces/publishes_unsaved_changes.ts | 2 +- .../embeddable/dashboard_container.tsx | 10 +++++++++- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/packages/presentation/presentation_containers/interfaces/unsaved_changes/children_unsaved_changes.test.ts b/packages/presentation/presentation_containers/interfaces/unsaved_changes/children_unsaved_changes.test.ts index fd708d14d97be..cd03db5431bcc 100644 --- a/packages/presentation/presentation_containers/interfaces/unsaved_changes/children_unsaved_changes.test.ts +++ b/packages/presentation/presentation_containers/interfaces/unsaved_changes/children_unsaved_changes.test.ts @@ -14,11 +14,11 @@ import { waitFor } from '@testing-library/react'; describe('childrenUnsavedChanges$', () => { const child1Api = { unsavedChanges: new BehaviorSubject(undefined), - resetUnsavedChanges: () => undefined, + resetUnsavedChanges: () => true, }; const child2Api = { unsavedChanges: new BehaviorSubject(undefined), - resetUnsavedChanges: () => undefined, + resetUnsavedChanges: () => true, }; const children$ = new BehaviorSubject<{ [key: string]: unknown }>({}); const onFireMock = jest.fn(); @@ -99,7 +99,7 @@ describe('childrenUnsavedChanges$', () => { ...children$.value, child3: { unsavedChanges: new BehaviorSubject({ key1: 'modified value' }), - resetUnsavedChanges: () => undefined, + resetUnsavedChanges: () => true, }, }); diff --git a/packages/presentation/presentation_containers/interfaces/unsaved_changes/initialize_unsaved_changes.ts b/packages/presentation/presentation_containers/interfaces/unsaved_changes/initialize_unsaved_changes.ts index 70085b88e1a8b..fb767fb11cffd 100644 --- a/packages/presentation/presentation_containers/interfaces/unsaved_changes/initialize_unsaved_changes.ts +++ b/packages/presentation/presentation_containers/interfaces/unsaved_changes/initialize_unsaved_changes.ts @@ -95,10 +95,19 @@ export const initializeUnsavedChanges = ( unsavedChanges, resetUnsavedChanges: () => { const lastSaved = lastSavedState$.getValue(); + + // Do not reset to undefined or empty last saved state + // Temporary fix for https://github.com/elastic/kibana/issues/201627 + // TODO remove when architecture fix resolves issue. + if (comparatorKeys.length && (!lastSaved || Object.keys(lastSaved).length === 0)) { + return false; + } + for (const key of comparatorKeys) { const setter = comparators[key][1]; // setter function is the 1st element of the tuple setter(lastSaved?.[key] as RuntimeState[typeof key]); } + return true; }, snapshotRuntimeState, } as PublishesUnsavedChanges & HasSnapshottableState, diff --git a/packages/presentation/presentation_publishing/interfaces/publishes_unsaved_changes.ts b/packages/presentation/presentation_publishing/interfaces/publishes_unsaved_changes.ts index 90a01d5bc736e..e9b4adbec5384 100644 --- a/packages/presentation/presentation_publishing/interfaces/publishes_unsaved_changes.ts +++ b/packages/presentation/presentation_publishing/interfaces/publishes_unsaved_changes.ts @@ -11,7 +11,7 @@ import { PublishingSubject } from '../publishing_subject'; export interface PublishesUnsavedChanges { unsavedChanges: PublishingSubject | undefined>; - resetUnsavedChanges: () => void; + resetUnsavedChanges: () => boolean; } export const apiPublishesUnsavedChanges = (api: unknown): api is PublishesUnsavedChanges => { diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx index 99f4fb7c2fa90..3b556b3668e1c 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx @@ -113,6 +113,7 @@ import { } from './dashboard_container_factory'; import { InitialComponentState, getDashboardApi } from '../../dashboard_api/get_dashboard_api'; import type { DashboardCreationOptions } from '../..'; +import { i18n } from '@kbn/i18n'; export interface InheritedChildInput { filters: Filter[]; @@ -957,7 +958,14 @@ export class DashboardContainer for (const panelId of Object.keys(currentChildren)) { if (this.getInput().panels[panelId]) { const child = currentChildren[panelId]; - if (apiPublishesUnsavedChanges(child)) child.resetUnsavedChanges(); + if (apiPublishesUnsavedChanges(child)) { + const success = child.resetUnsavedChanges(); + if (!success) { + coreServices.notifications.toasts.addWarning(i18n.translate('dashboard.reset.panelError', { + defaultMessage: 'Unable to reset panel changes', + })); + } + } } else { // if reset resulted in panel removal, we need to update the list of children delete currentChildren[panelId];