mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
# Backport This will backport the following commits from `main` to `8.x`: - [[dashboard] Do not reset panel to undefined or empty last saved state (#203158)](https://github.com/elastic/kibana/pull/203158) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Nathan Reese","email":"reese.nathan@elastic.co"},"sourceCommit":{"committedDate":"2024-12-10T03:04:15Z","message":"[dashboard] Do not reset panel to undefined or empty last saved state (#203158)\n\nPart of https://github.com/elastic/kibana/issues/201627\r\n\r\nThis is a short term fix for serverless and 8.x branches (long term fix\r\nis an architectural change that will only be merged into 9.0 and 8.18\r\nbranches).\r\n\r\nFix prevents users from reseting a panel edited via embeddable transfer\r\nservice. This prevents panel from getting into an invalid state.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>\r\nCo-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>","sha":"e103a253d9b756605dbeb92955ff517597055970","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:Presentation","v9.0.0","project:embeddableRebuild","backport:version","v8.18.0","v8.16.2","v8.15.6","v8.17.1"],"title":"[dashboard] Do not reset panel to undefined or empty last saved state","number":203158,"url":"https://github.com/elastic/kibana/pull/203158","mergeCommit":{"message":"[dashboard] Do not reset panel to undefined or empty last saved state (#203158)\n\nPart of https://github.com/elastic/kibana/issues/201627\r\n\r\nThis is a short term fix for serverless and 8.x branches (long term fix\r\nis an architectural change that will only be merged into 9.0 and 8.18\r\nbranches).\r\n\r\nFix prevents users from reseting a panel edited via embeddable transfer\r\nservice. This prevents panel from getting into an invalid state.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>\r\nCo-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>","sha":"e103a253d9b756605dbeb92955ff517597055970"}},"sourceBranch":"main","suggestedTargetBranches":["8.x","8.16","8.15","8.17"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/203158","number":203158,"mergeCommit":{"message":"[dashboard] Do not reset panel to undefined or empty last saved state (#203158)\n\nPart of https://github.com/elastic/kibana/issues/201627\r\n\r\nThis is a short term fix for serverless and 8.x branches (long term fix\r\nis an architectural change that will only be merged into 9.0 and 8.18\r\nbranches).\r\n\r\nFix prevents users from reseting a panel edited via embeddable transfer\r\nservice. This prevents panel from getting into an invalid state.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>\r\nCo-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>","sha":"e103a253d9b756605dbeb92955ff517597055970"}},{"branch":"8.x","label":"v8.18.0","branchLabelMappingKey":"^v8.18.0$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.16","label":"v8.16.2","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.15","label":"v8.15.6","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.17","label":"v8.17.1","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Nathan Reese <reese.nathan@elastic.co>
This commit is contained in:
parent
58421bf361
commit
b935f644f1
7 changed files with 31 additions and 7 deletions
|
@ -250,6 +250,7 @@ export function getPageApi() {
|
|||
children$.next(children);
|
||||
}
|
||||
newPanels = {};
|
||||
return true;
|
||||
},
|
||||
timeRange$,
|
||||
unsavedChanges: unsavedChanges$ as PublishingSubject<object | undefined>,
|
||||
|
|
|
@ -14,11 +14,11 @@ import { waitFor } from '@testing-library/react';
|
|||
describe('childrenUnsavedChanges$', () => {
|
||||
const child1Api = {
|
||||
unsavedChanges: new BehaviorSubject<object | undefined>(undefined),
|
||||
resetUnsavedChanges: () => undefined,
|
||||
resetUnsavedChanges: () => true,
|
||||
};
|
||||
const child2Api = {
|
||||
unsavedChanges: new BehaviorSubject<object | undefined>(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<object | undefined>({ key1: 'modified value' }),
|
||||
resetUnsavedChanges: () => undefined,
|
||||
resetUnsavedChanges: () => true,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -95,10 +95,19 @@ export const initializeUnsavedChanges = <RuntimeState extends {} = {}>(
|
|||
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<RuntimeState> & HasSnapshottableState<RuntimeState>,
|
||||
|
|
|
@ -11,7 +11,7 @@ import { PublishingSubject } from '../publishing_subject';
|
|||
|
||||
export interface PublishesUnsavedChanges<Runtime extends object = object> {
|
||||
unsavedChanges: PublishingSubject<Partial<Runtime> | undefined>;
|
||||
resetUnsavedChanges: () => void;
|
||||
resetUnsavedChanges: () => boolean;
|
||||
}
|
||||
|
||||
export const apiPublishesUnsavedChanges = (api: unknown): api is PublishesUnsavedChanges => {
|
||||
|
|
|
@ -43,7 +43,9 @@ export const getMockedBuildApi =
|
|||
uuid,
|
||||
parentApi: controlGroupApi ?? getMockedControlGroupApi(),
|
||||
unsavedChanges: new BehaviorSubject<Partial<StateType> | undefined>(undefined),
|
||||
resetUnsavedChanges: () => {},
|
||||
resetUnsavedChanges: () => {
|
||||
return true;
|
||||
},
|
||||
type: factory.type,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -48,7 +48,9 @@ describe('TimesliderControlApi', () => {
|
|||
uuid,
|
||||
parentApi: controlGroupApi,
|
||||
unsavedChanges: new BehaviorSubject<Partial<TimesliderControlState> | undefined>(undefined),
|
||||
resetUnsavedChanges: () => {},
|
||||
resetUnsavedChanges: () => {
|
||||
return true;
|
||||
},
|
||||
type: factory.type,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
|
|||
import { LocatorPublic } from '@kbn/share-plugin/common';
|
||||
import { ExitFullScreenButtonKibanaProvider } from '@kbn/shared-ux-button-exit-full-screen';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { DASHBOARD_CONTAINER_TYPE, DashboardApi, DashboardLocatorParams } from '../..';
|
||||
import type { DashboardAttributes } from '../../../server/content_management';
|
||||
import { DashboardContainerInput, DashboardPanelMap, DashboardPanelState } from '../../../common';
|
||||
|
@ -957,7 +958,16 @@ 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];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue