[Dashboard] Fix explicitInput removal (#215580)

Temporarily adds a serializedStateBackup to Dashboard
This commit is contained in:
Devon Thomson 2025-03-27 16:02:22 -04:00 committed by GitHub
parent 2cbfe8641c
commit 62f2daf32e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 68 additions and 5 deletions

View file

@ -90,7 +90,8 @@ export function getDashboardApi({
initialPanelsRuntimeState ?? {},
trackPanel,
getPanelReferences,
pushPanelReferences
pushPanelReferences,
savedObjectId
);
const dataLoadingManager = initializeDataLoadingManager(panelsManager.api.children$);
const dataViewsManager = initializeDataViewsManager(

View file

@ -41,6 +41,7 @@ import { arePanelLayoutsEqual } from './are_panel_layouts_equal';
import { dashboardClonePanelActionStrings } from '../dashboard_actions/_dashboard_actions_strings';
import { placeClonePanel } from '../panel_placement/place_clone_panel_strategy';
import { PanelPlacementStrategy } from '../plugin_constants';
import { getDashboardBackupService } from '../services/dashboard_backup_service';
export function initializePanelsManager(
incomingEmbeddable: EmbeddablePackageState | undefined,
@ -48,7 +49,8 @@ export function initializePanelsManager(
initialPanelsRuntimeState: UnsavedPanelState,
trackPanel: ReturnType<typeof initializeTrackPanel>,
getReferencesForPanelId: (id: string) => Reference[],
pushReferences: (references: Reference[]) => void
pushReferences: (references: Reference[]) => void,
dashboardId?: string
) {
const children$ = new BehaviorSubject<{
[key: string]: unknown;
@ -386,7 +388,10 @@ export function initializePanelsManager(
const childApi = children$.value[id];
const serializeResult = apiHasSerializableState(childApi)
? childApi.serializeState()
: { rawState: {} };
: getDashboardBackupService().getSerializedPanelBackup(id, dashboardId) ?? {
rawState: panels$.value[id].explicitInput ?? {},
references: getReferencesForPanelId(id),
};
acc[id] = { ...panels$.value[id], explicitInput: { ...serializeResult.rawState, id } };
references.push(...prefixReferencesFromPanel(id, serializeResult.references ?? []));

View file

@ -12,7 +12,9 @@ import { childrenUnsavedChanges$, initializeUnsavedChanges } from '@kbn/presenta
import {
PublishesSavedObjectId,
PublishingSubject,
SerializedPanelState,
StateComparators,
apiHasSerializableState,
} from '@kbn/presentation-publishing';
import { omit } from 'lodash';
import { BehaviorSubject, Subject, combineLatest, debounceTime, skipWhile, switchMap } from 'rxjs';
@ -93,17 +95,34 @@ export function initializeUnsavedChangesManager({
// backup unsaved changes if configured to do so
if (creationOptions?.useSessionStorageIntegration) {
const dashboardBackupService = getDashboardBackupService();
// Current behaviour expects time range not to be backed up. Revisit this?
const dashboardStateToBackup = omit(dashboardChanges ?? {}, [
'timeRange',
'refreshInterval',
]);
// TEMPORARY - back up serialized state for all panels with changes
if (unsavedPanelState) {
const serializedPanelBackup: { [key: string]: SerializedPanelState<object> } = {};
for (const uuid of Object.keys(unsavedPanelState)) {
const childApi = panelsManager.api.children$.value[uuid];
if (!apiHasSerializableState(childApi)) continue;
serializedPanelBackup[uuid] = childApi.serializeState();
}
dashboardBackupService.setSerializedPanelsBackups(
serializedPanelBackup,
savedObjectId$.value
);
}
const reactEmbeddableChanges = unsavedPanelState ? { ...unsavedPanelState } : {};
if (controlGroupChanges) {
reactEmbeddableChanges[PANELS_CONTROL_GROUP_KEY] = controlGroupChanges;
}
getDashboardBackupService().setState(
dashboardBackupService.setState(
savedObjectId$.value,
dashboardStateToBackup,
reactEmbeddableChanges

View file

@ -14,7 +14,7 @@ import { i18n } from '@kbn/i18n';
import { Storage } from '@kbn/kibana-utils-plugin/public';
import { set } from '@kbn/safer-lodash-set';
import { ViewMode } from '@kbn/presentation-publishing';
import { SerializedPanelState, ViewMode } from '@kbn/presentation-publishing';
import { coreServices, spacesService } from './kibana_services';
import { DashboardState, UnsavedPanelState } from '../dashboard_api/types';
import { DEFAULT_DASHBOARD_STATE } from '../dashboard_api/default_dashboard_state';
@ -27,6 +27,9 @@ const DASHBOARD_VIEWMODE_LOCAL_KEY = 'dashboardViewMode';
// this key is named `panels` for BWC reasons, but actually contains the entire dashboard state
const DASHBOARD_STATE_SESSION_KEY = 'dashboardStateManagerPanels';
// Temporary key for Dashboard to back up serialized state of all its panels
const DASHBOARD_SERIALIZED_PANEL_BACKUP_KEY = 'dashboardSerializedPanelBackup';
const getPanelsGetError = (message: string) =>
i18n.translate('dashboard.panelStorageError.getError', {
defaultMessage: 'Error encountered while fetching unsaved changes: {message}',
@ -108,6 +111,15 @@ class DashboardBackupService implements DashboardBackupServiceType {
[this.activeSpaceId]: panelsStorage,
});
}
const serializedBackups =
this.sessionStorage.get(DASHBOARD_SERIALIZED_PANEL_BACKUP_KEY)?.[this.activeSpaceId] ?? {};
if (serializedBackups[id]) {
delete serializedBackups[id];
this.sessionStorage.set(DASHBOARD_SERIALIZED_PANEL_BACKUP_KEY, {
[this.activeSpaceId]: serializedBackups,
});
}
} catch (e) {
coreServices.notifications.toasts.addDanger({
title: i18n.translate('dashboard.panelStorageError.clearError', {
@ -119,6 +131,32 @@ class DashboardBackupService implements DashboardBackupServiceType {
}
}
public getSerializedPanelBackup(panelId: string, dashboardId = DASHBOARD_PANELS_UNSAVED_ID) {
return this.sessionStorage.get(DASHBOARD_SERIALIZED_PANEL_BACKUP_KEY)?.[this.activeSpaceId]?.[
dashboardId
]?.[panelId] as SerializedPanelState<object> | undefined;
}
public setSerializedPanelsBackups(
serializedPanels: { [key: string]: SerializedPanelState<object> },
dashboardId = DASHBOARD_PANELS_UNSAVED_ID
) {
try {
const serializedPanelsBackup =
this.sessionStorage.get(DASHBOARD_SERIALIZED_PANEL_BACKUP_KEY) ?? {};
set(serializedPanelsBackup, [this.activeSpaceId, dashboardId], serializedPanels);
this.sessionStorage.set(DASHBOARD_SERIALIZED_PANEL_BACKUP_KEY, serializedPanelsBackup);
} catch (e) {
coreServices.notifications.toasts.addDanger({
title: i18n.translate('dashboard.panelStorageError.setError', {
defaultMessage: 'Error encountered while setting unsaved changes: {message}',
values: { message: e.message },
}),
'data-test-subj': 'dashboardPanelsSetFailure',
});
}
}
public getState(id = DASHBOARD_PANELS_UNSAVED_ID) {
try {
const dashboardState = this.sessionStorage.get(DASHBOARD_STATE_SESSION_KEY)?.[