diff --git a/src/platform/plugins/shared/dashboard/jest_setup.ts b/src/platform/plugins/shared/dashboard/jest_setup.ts
index a1f15dfeb3a31..666a836c7334f 100644
--- a/src/platform/plugins/shared/dashboard/jest_setup.ts
+++ b/src/platform/plugins/shared/dashboard/jest_setup.ts
@@ -24,9 +24,10 @@ setStubLogger();
// Start the kibana services with stubs
setStubKibanaServices();
-jest.mock('./public/services/dashboard_backup_service', () => {
+jest.mock('./public/services/dashboard_api_services', () => {
return {
getDashboardBackupService: () => mockDashboardBackupService,
+ initializeDashboardApiServices: () => jest.fn(),
};
});
diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_api/load_dashboard_api/load_dashboard_api.test.ts b/src/platform/plugins/shared/dashboard/public/dashboard_api/load_dashboard_api/load_dashboard_api.test.ts
index 12d7f1c86e7b8..e755aa997ae9d 100644
--- a/src/platform/plugins/shared/dashboard/public/dashboard_api/load_dashboard_api/load_dashboard_api.test.ts
+++ b/src/platform/plugins/shared/dashboard/public/dashboard_api/load_dashboard_api/load_dashboard_api.test.ts
@@ -55,7 +55,7 @@ describe('loadDashboardApi', () => {
});
// eslint-disable-next-line @typescript-eslint/no-var-requires
- require('../../services/dashboard_backup_service').getDashboardBackupService = () => ({
+ require('../../services/dashboard_api_services').getDashboardBackupService = () => ({
getState: () => ({
query: lastSavedQuery,
}),
diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_api/load_dashboard_api/load_dashboard_api.ts b/src/platform/plugins/shared/dashboard/public/dashboard_api/load_dashboard_api/load_dashboard_api.ts
index 7886179e0e87c..0b781ceb218e3 100644
--- a/src/platform/plugins/shared/dashboard/public/dashboard_api/load_dashboard_api/load_dashboard_api.ts
+++ b/src/platform/plugins/shared/dashboard/public/dashboard_api/load_dashboard_api/load_dashboard_api.ts
@@ -12,7 +12,6 @@ import { dashboardClient } from '../../dashboard_client';
import { getPanelSettings } from '../../panel_placement/get_panel_placement_settings';
import { DEFAULT_PANEL_PLACEMENT_SETTINGS } from '../../plugin_constants';
import { getAccessControlClient } from '../../services/access_control_service';
-import { getDashboardBackupService } from '../../services/dashboard_backup_service';
import { coreServices } from '../../services/kibana_services';
import { logger } from '../../services/logger';
import { getLastSavedState } from '../default_dashboard_state';
@@ -22,6 +21,10 @@ import { startQueryPerformanceTracking } from '../performance/query_performance_
import type { DashboardCreationOptions } from '../types';
import { getUserAccessControlData } from './get_user_access_control_data';
import { transformPanels } from './transform_panels';
+import {
+ getDashboardBackupService,
+ initializeDashboardApiServices,
+} from '../../services/dashboard_api_services';
export async function loadDashboardApi({
getCreationOptions,
@@ -65,6 +68,7 @@ export async function loadDashboardApi({
return;
}
+ await initializeDashboardApiServices();
const unsavedChanges = creationOptions?.useSessionStorageIntegration
? getDashboardBackupService().getState(savedObjectId)
: undefined;
diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_api/save_modal/save_dashboard.ts b/src/platform/plugins/shared/dashboard/public/dashboard_api/save_modal/save_dashboard.ts
index bc3910313947f..9bf1072325b23 100644
--- a/src/platform/plugins/shared/dashboard/public/dashboard_api/save_modal/save_dashboard.ts
+++ b/src/platform/plugins/shared/dashboard/public/dashboard_api/save_modal/save_dashboard.ts
@@ -8,7 +8,7 @@
*/
import { i18n } from '@kbn/i18n';
-import { getDashboardBackupService } from '../../services/dashboard_backup_service';
+import { getDashboardBackupService } from '../../services/dashboard_api_services';
import { coreServices } from '../../services/kibana_services';
import { dashboardClient } from '../../dashboard_client';
import type { SaveDashboardProps, SaveDashboardReturn } from './types';
diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_api/unsaved_changes_manager.test.ts b/src/platform/plugins/shared/dashboard/public/dashboard_api/unsaved_changes_manager.test.ts
index 5e9ea7e5d4b72..01f9c01bf6f13 100644
--- a/src/platform/plugins/shared/dashboard/public/dashboard_api/unsaved_changes_manager.test.ts
+++ b/src/platform/plugins/shared/dashboard/public/dashboard_api/unsaved_changes_manager.test.ts
@@ -22,8 +22,6 @@ import type { initializeProjectRoutingManager } from './project_routing_manager'
import type { DashboardPanel } from '../../server';
import { getSampleDashboardState } from '../mocks';
-jest.mock('../services/dashboard_backup_service', () => ({}));
-
const setStateMock = () => {};
const layoutUnsavedChanges$ = new BehaviorSubject<{ panels?: DashboardState['panels'] }>({});
@@ -81,7 +79,7 @@ describe('unsavedChangesManager', () => {
layoutUnsavedChanges$.next({});
// eslint-disable-next-line @typescript-eslint/no-var-requires
- require('../services/dashboard_backup_service').getDashboardBackupService = () => ({
+ require('../services/dashboard_api_services').getDashboardBackupService = () => ({
setState: setBackupStateMock,
});
});
diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_api/unsaved_changes_manager.ts b/src/platform/plugins/shared/dashboard/public/dashboard_api/unsaved_changes_manager.ts
index e80fb228d35e6..afed86e5a1a7e 100644
--- a/src/platform/plugins/shared/dashboard/public/dashboard_api/unsaved_changes_manager.ts
+++ b/src/platform/plugins/shared/dashboard/public/dashboard_api/unsaved_changes_manager.ts
@@ -18,10 +18,8 @@ import type {
import { of } from 'rxjs';
import type { DashboardState } from '../../common';
-import {
- getDashboardBackupService,
- type DashboardBackupState,
-} from '../services/dashboard_backup_service';
+import { type DashboardBackupState } from '../services/dashboard_backup_service';
+import { getDashboardBackupService } from '../services/dashboard_api_services';
import type { initializeLayoutManager } from './layout_manager';
import type { initializeProjectRoutingManager } from './project_routing_manager';
import type { initializeSettingsManager } from './settings_manager';
diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_api/view_mode_manager.ts b/src/platform/plugins/shared/dashboard/public/dashboard_api/view_mode_manager.ts
index 362520d88cf97..b7f96cea0f848 100644
--- a/src/platform/plugins/shared/dashboard/public/dashboard_api/view_mode_manager.ts
+++ b/src/platform/plugins/shared/dashboard/public/dashboard_api/view_mode_manager.ts
@@ -13,7 +13,7 @@ import { BehaviorSubject } from 'rxjs';
import type { SavedObjectAccessControl } from '@kbn/core-saved-objects-common';
import type { DashboardUser } from './types';
import { getAccessControlClient } from '../services/access_control_service';
-import { getDashboardBackupService } from '../services/dashboard_backup_service';
+import { getDashboardBackupService } from '../services/dashboard_api_services';
import { getDashboardCapabilities } from '../utils/get_dashboard_capabilities';
export function initializeViewModeManager({
diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_app/no_data/dashboard_app_no_data.tsx b/src/platform/plugins/shared/dashboard/public/dashboard_app/no_data/dashboard_app_no_data.tsx
index 4a5eb253eaa3c..5626ae8e7ebb3 100644
--- a/src/platform/plugins/shared/dashboard/public/dashboard_app/no_data/dashboard_app_no_data.tsx
+++ b/src/platform/plugins/shared/dashboard/public/dashboard_app/no_data/dashboard_app_no_data.tsx
@@ -29,7 +29,7 @@ import {
shareService,
lensService,
} from '../../services/kibana_services';
-import { getDashboardBackupService } from '../../services/dashboard_backup_service';
+import { getDashboardBackupService } from '../../services/dashboard_api_services';
import { dashboardClient } from '../../dashboard_client';
export const DashboardAppNoDataPage = ({
diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_app/top_nav/share/share_options_utils.ts b/src/platform/plugins/shared/dashboard/public/dashboard_app/top_nav/share/share_options_utils.ts
index 9d8b8ea8e3df1..7b9a0282d4225 100644
--- a/src/platform/plugins/shared/dashboard/public/dashboard_app/top_nav/share/share_options_utils.ts
+++ b/src/platform/plugins/shared/dashboard/public/dashboard_app/top_nav/share/share_options_utils.ts
@@ -17,7 +17,7 @@ import type { LocatorPublic } from '@kbn/share-plugin/common';
import { toStoredFilters } from '@kbn/as-code-filters-transforms';
import { topNavStrings } from '../../_dashboard_app_strings';
import type { DashboardLocatorParams } from '../../../../common';
-import { getDashboardBackupService } from '../../../services/dashboard_backup_service';
+import { getDashboardBackupService } from '../../../services/dashboard_api_services';
import { dataService, shareService } from '../../../services/kibana_services';
import { logger } from '../../../services/logger';
import { getDashboardCapabilities } from '../../../utils/get_dashboard_capabilities';
diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_app/top_nav/share/show_share_modal.test.tsx b/src/platform/plugins/shared/dashboard/public/dashboard_app/top_nav/share/show_share_modal.test.tsx
index 37dc24587bff9..f70381d229543 100644
--- a/src/platform/plugins/shared/dashboard/public/dashboard_app/top_nav/share/show_share_modal.test.tsx
+++ b/src/platform/plugins/shared/dashboard/public/dashboard_app/top_nav/share/show_share_modal.test.tsx
@@ -9,7 +9,7 @@
import type { Capabilities } from '@kbn/core/public';
import type { DashboardLocatorParams, DashboardState } from '../../../../common/types';
-import { getDashboardBackupService } from '../../../services/dashboard_backup_service';
+import { getDashboardBackupService } from '../../../services/dashboard_api_services';
import { shareService } from '../../../services/kibana_services';
import { showPublicUrlSwitch, ShowShareModal } from './show_share_modal';
import type { AccessControlClient } from '@kbn/content-management-access-control-public';
diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_app/top_nav/use_dashboard_menu_items.tsx b/src/platform/plugins/shared/dashboard/public/dashboard_app/top_nav/use_dashboard_menu_items.tsx
index 5287ecf1c4b20..667e44fa5c3c2 100644
--- a/src/platform/plugins/shared/dashboard/public/dashboard_app/top_nav/use_dashboard_menu_items.tsx
+++ b/src/platform/plugins/shared/dashboard/public/dashboard_app/top_nav/use_dashboard_menu_items.tsx
@@ -26,7 +26,7 @@ import { UI_SETTINGS } from '../../../common/constants';
import { useDashboardApi } from '../../dashboard_api/use_dashboard_api';
import { confirmDiscardUnsavedChanges } from '../../dashboard_listing/confirm_overlays';
import { openSettingsFlyout } from '../../dashboard_renderer/settings/open_settings_flyout';
-import { getDashboardBackupService } from '../../services/dashboard_backup_service';
+import { getDashboardBackupService } from '../../services/dashboard_api_services';
import type { SaveDashboardReturn } from '../../dashboard_api/save_modal/types';
import { coreServices, shareService, dataService } from '../../services/kibana_services';
import { getDashboardCapabilities } from '../../utils/get_dashboard_capabilities';
diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_listing/dashboard_listing_empty_prompt.tsx b/src/platform/plugins/shared/dashboard/public/dashboard_listing/dashboard_listing_empty_prompt.tsx
index 2a30de55c64b9..2872456453284 100644
--- a/src/platform/plugins/shared/dashboard/public/dashboard_listing/dashboard_listing_empty_prompt.tsx
+++ b/src/platform/plugins/shared/dashboard/public/dashboard_listing/dashboard_listing_empty_prompt.tsx
@@ -17,11 +17,8 @@ import {
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import React, { useCallback, useMemo } from 'react';
-
-import {
- DASHBOARD_PANELS_UNSAVED_ID,
- getDashboardBackupService,
-} from '../services/dashboard_backup_service';
+import { DASHBOARD_PANELS_UNSAVED_ID } from '../services/dashboard_backup_service';
+import { getDashboardBackupService } from '../services/dashboard_api_services';
import { coreServices } from '../services/kibana_services';
import { getDashboardCapabilities } from '../utils/get_dashboard_capabilities';
import {
diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_listing/dashboard_unsaved_listing.test.tsx b/src/platform/plugins/shared/dashboard/public/dashboard_listing/dashboard_unsaved_listing.test.tsx
index efd9ca1cf0d2a..c2ba730719349 100644
--- a/src/platform/plugins/shared/dashboard/public/dashboard_listing/dashboard_unsaved_listing.test.tsx
+++ b/src/platform/plugins/shared/dashboard/public/dashboard_listing/dashboard_unsaved_listing.test.tsx
@@ -13,10 +13,8 @@ import { I18nProvider } from '@kbn/i18n-react';
import { render, waitFor, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import {
- DASHBOARD_PANELS_UNSAVED_ID,
- getDashboardBackupService,
-} from '../services/dashboard_backup_service';
+import { DASHBOARD_PANELS_UNSAVED_ID } from '../services/dashboard_backup_service';
+import { getDashboardBackupService } from '../services/dashboard_api_services';
import { coreServices } from '../services/kibana_services';
import type { DashboardUnsavedListingProps } from './dashboard_unsaved_listing';
import { DashboardUnsavedListing } from './dashboard_unsaved_listing';
diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_listing/dashboard_unsaved_listing.tsx b/src/platform/plugins/shared/dashboard/public/dashboard_listing/dashboard_unsaved_listing.tsx
index 15764457e43a4..037e94429ec45 100644
--- a/src/platform/plugins/shared/dashboard/public/dashboard_listing/dashboard_unsaved_listing.tsx
+++ b/src/platform/plugins/shared/dashboard/public/dashboard_listing/dashboard_unsaved_listing.tsx
@@ -18,19 +18,17 @@ import {
EuiTitle,
euiBreakpoint,
} from '@elastic/eui';
-import React, { useCallback, useEffect, useMemo, useState } from 'react';
+import React, { useCallback, useEffect, useState } from 'react';
import type { ViewMode } from '@kbn/presentation-publishing';
import { css } from '@emotion/react';
import { useMemoCss } from '@kbn/css-utils/public/use_memo_css';
import type { DashboardState } from '../../server';
-import {
- DASHBOARD_PANELS_UNSAVED_ID,
- getDashboardBackupService,
-} from '../services/dashboard_backup_service';
+import { DASHBOARD_PANELS_UNSAVED_ID } from '../services/dashboard_backup_service';
import { dashboardUnsavedListingStrings, getNewDashboardTitle } from './_dashboard_listing_strings';
import { confirmDiscardUnsavedChanges } from './confirm_overlays';
import { findService } from '../dashboard_client';
+import { getDashboardBackupService } from '../services/dashboard_api_services';
const unsavedItemStyles = {
item: (euiThemeContext: UseEuiTheme) =>
@@ -82,7 +80,12 @@ const DashboardUnsavedItem = ({
-
+
@@ -145,7 +148,6 @@ export const DashboardUnsavedListing = ({
refreshUnsavedDashboards,
}: DashboardUnsavedListingProps) => {
const [items, setItems] = useState({});
- const dashboardBackupService = useMemo(() => getDashboardBackupService(), []);
const onOpen = useCallback(
(id?: string) => {
@@ -157,11 +159,11 @@ export const DashboardUnsavedListing = ({
const onDiscard = useCallback(
(id?: string) => {
confirmDiscardUnsavedChanges(() => {
- dashboardBackupService.clearState(id);
+ getDashboardBackupService().clearState(id);
refreshUnsavedDashboards();
});
},
- [dashboardBackupService, refreshUnsavedDashboards]
+ [refreshUnsavedDashboards]
);
useEffect(() => {
@@ -183,7 +185,7 @@ export const DashboardUnsavedListing = ({
hasError = true;
if (result.error && result.notFound) {
// Save object not found error
- dashboardBackupService.clearState(result.id);
+ getDashboardBackupService().clearState(result.id);
}
return map;
}
@@ -202,7 +204,7 @@ export const DashboardUnsavedListing = ({
return () => {
canceled = true;
};
- }, [dashboardBackupService, refreshUnsavedDashboards, unsavedDashboardIds]);
+ }, [refreshUnsavedDashboards, unsavedDashboardIds]);
return unsavedDashboardIds.length === 0 ? null : (
<>
diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.test.tsx b/src/platform/plugins/shared/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.test.tsx
index 1499721d7955f..0ac8b2ff3eb66 100644
--- a/src/platform/plugins/shared/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.test.tsx
+++ b/src/platform/plugins/shared/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.test.tsx
@@ -8,12 +8,11 @@
*/
import { renderHook, act } from '@testing-library/react';
-
-import { getDashboardBackupService } from '../../services/dashboard_backup_service';
import { coreServices } from '../../services/kibana_services';
import { confirmCreateWithUnsaved } from '../confirm_overlays';
import type { DashboardSavedObjectUserContent } from '../types';
import { useDashboardListingTable } from './use_dashboard_listing_table';
+import { getDashboardBackupService } from '../../services/dashboard_api_services';
const clearStateMock = jest.fn();
const getDashboardUrl = jest.fn();
diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.tsx b/src/platform/plugins/shared/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.tsx
index 57b1938b839b5..d8f488243cfb1 100644
--- a/src/platform/plugins/shared/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.tsx
+++ b/src/platform/plugins/shared/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.tsx
@@ -25,7 +25,6 @@ import {
findService,
} from '../../dashboard_client';
import { getAccessControlClient } from '../../services/access_control_service';
-import { getDashboardBackupService } from '../../services/dashboard_backup_service';
import { getDashboardRecentlyAccessedService } from '../../services/dashboard_recently_accessed_service';
import { coreServices, savedObjectsTaggingService } from '../../services/kibana_services';
import { logger } from '../../services/logger';
@@ -41,6 +40,7 @@ import {
import { confirmCreateWithUnsaved } from '../confirm_overlays';
import { DashboardListingEmptyPrompt } from '../dashboard_listing_empty_prompt';
import type { DashboardSavedObjectUserContent } from '../types';
+import { getDashboardBackupService } from '../../services/dashboard_api_services';
type GetDetailViewLink =
TableListViewTableProps['getDetailViewLink'];
@@ -90,10 +90,8 @@ export const useDashboardListingTable = ({
const [pageDataTestSubject, setPageDataTestSubject] = useState();
const [hasInitialFetchReturned, setHasInitialFetchReturned] = useState(false);
- const dashboardBackupService = useMemo(() => getDashboardBackupService(), []);
-
const [unsavedDashboardIds, setUnsavedDashboardIds] = useState(
- dashboardBackupService.getDashboardIdsWithUnsavedChanges()
+ getDashboardBackupService().getDashboardIdsWithUnsavedChanges()
);
const accessControlClient = getAccessControlClient();
@@ -102,15 +100,15 @@ export const useDashboardListingTable = ({
const initialPageSize = coreServices.uiSettings.get(SAVED_OBJECTS_PER_PAGE_SETTING);
const createItem = useCallback(() => {
- if (useSessionStorageIntegration && dashboardBackupService.dashboardHasUnsavedEdits()) {
+ if (useSessionStorageIntegration && getDashboardBackupService().dashboardHasUnsavedEdits()) {
confirmCreateWithUnsaved(() => {
- dashboardBackupService.clearState();
+ getDashboardBackupService().clearState();
goToDashboard();
}, goToDashboard);
return;
}
goToDashboard();
- }, [dashboardBackupService, goToDashboard, useSessionStorageIntegration]);
+ }, [goToDashboard, useSessionStorageIntegration]);
const updateItemMeta = useCallback(
async ({ id, ...updatedState }: Parameters['onSave']>[0]) => {
@@ -123,9 +121,9 @@ export const useDashboardListingTable = ({
...updatedState,
});
- setUnsavedDashboardIds(dashboardBackupService.getDashboardIdsWithUnsavedChanges());
+ setUnsavedDashboardIds(getDashboardBackupService().getDashboardIdsWithUnsavedChanges());
},
- [dashboardBackupService]
+ []
);
const contentEditorValidators: OpenContentEditorParams['customValidators'] = useMemo(
@@ -263,35 +261,32 @@ export const useDashboardListingTable = ({
[listingLimit, accessControlClient]
);
- const deleteItems = useCallback(
- async (dashboardsToDelete: Array<{ id: string }>) => {
- try {
- const deleteStartTime = window.performance.now();
+ const deleteItems = useCallback(async (dashboardsToDelete: Array<{ id: string }>) => {
+ try {
+ const deleteStartTime = window.performance.now();
- await asyncMap(dashboardsToDelete, async ({ id }) => {
- await dashboardClient.delete(id);
- dashboardBackupService.clearState(id);
- });
+ await asyncMap(dashboardsToDelete, async ({ id }) => {
+ await dashboardClient.delete(id);
+ getDashboardBackupService().clearState(id);
+ });
- const deleteDuration = window.performance.now() - deleteStartTime;
- reportPerformanceMetricEvent(coreServices.analytics, {
- eventName: SAVED_OBJECT_DELETE_TIME,
- duration: deleteDuration,
- meta: {
- saved_object_type: DASHBOARD_SAVED_OBJECT_TYPE,
- total: dashboardsToDelete.length,
- },
- });
- } catch (error) {
- coreServices.notifications.toasts.addError(error, {
- title: dashboardListingErrorStrings.getErrorDeletingDashboardToast(),
- });
- }
+ const deleteDuration = window.performance.now() - deleteStartTime;
+ reportPerformanceMetricEvent(coreServices.analytics, {
+ eventName: SAVED_OBJECT_DELETE_TIME,
+ duration: deleteDuration,
+ meta: {
+ saved_object_type: DASHBOARD_SAVED_OBJECT_TYPE,
+ total: dashboardsToDelete.length,
+ },
+ });
+ } catch (error) {
+ coreServices.notifications.toasts.addError(error, {
+ title: dashboardListingErrorStrings.getErrorDeletingDashboardToast(),
+ });
+ }
- setUnsavedDashboardIds(dashboardBackupService.getDashboardIdsWithUnsavedChanges());
- },
- [dashboardBackupService]
- );
+ setUnsavedDashboardIds(getDashboardBackupService().getDashboardIdsWithUnsavedChanges());
+ }, []);
const editItem = useCallback(
({ id }: { id: string | undefined }) => goToDashboard(id, 'edit'),
diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_listing/index.tsx b/src/platform/plugins/shared/dashboard/public/dashboard_listing/index.tsx
index d9f7e7b2e5796..753e69e249604 100644
--- a/src/platform/plugins/shared/dashboard/public/dashboard_listing/index.tsx
+++ b/src/platform/plugins/shared/dashboard/public/dashboard_listing/index.tsx
@@ -18,10 +18,11 @@ const ListingTableLoadingIndicator = () => {
};
const LazyDashboardListing = React.lazy(async () => {
- const [{ DashboardListingTable }] = await Promise.all([
+ const [{ DashboardListingTable, initializeDashboardApiServices }] = await Promise.all([
import('../dashboard_renderer/dashboard_module'),
untilPluginStartServicesReady(),
]);
+ await initializeDashboardApiServices();
return { default: DashboardListingTable };
});
diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_renderer/dashboard_module.ts b/src/platform/plugins/shared/dashboard/public/dashboard_renderer/dashboard_module.ts
index 941380f3119e3..d2caed58260b2 100644
--- a/src/platform/plugins/shared/dashboard/public/dashboard_renderer/dashboard_module.ts
+++ b/src/platform/plugins/shared/dashboard/public/dashboard_renderer/dashboard_module.ts
@@ -20,3 +20,4 @@ export { UnlinkFromLibraryAction } from '../dashboard_actions/library_unlink_act
export { CopyToDashboardAction } from '../dashboard_actions/copy_to_dashboard_action';
export { AddSectionAction } from '../dashboard_actions/add_section_action';
export { dashboardDrilldown } from '../dashboard_drilldown/dashboard_drilldown';
+export { initializeDashboardApiServices } from '../services/dashboard_api_services';
diff --git a/src/platform/plugins/shared/dashboard/public/plugin.tsx b/src/platform/plugins/shared/dashboard/public/plugin.tsx
index fa20e5395d10b..47b918a9adb96 100644
--- a/src/platform/plugins/shared/dashboard/public/plugin.tsx
+++ b/src/platform/plugins/shared/dashboard/public/plugin.tsx
@@ -73,7 +73,7 @@ import {
LANDING_PAGE_PATH,
SEARCH_SESSION_ID,
} from '../common/page_bundle_constants';
-import { setKibanaServices, untilPluginStartServicesReady } from './services/kibana_services';
+import { untilPluginStartServicesReady, setKibanaServices } from './services/kibana_services';
import { setLogger } from './services/logger';
import { registerActions } from './dashboard_actions/register_actions';
import { setupUrlForwarding } from './dashboard_app/url/setup_url_forwarding';
@@ -256,14 +256,17 @@ export class DashboardPlugin
performance.mark(DASHBOARD_DURATION_START_MARK);
this.currentHistory = params.history;
params.element.classList.add(APP_WRAPPER_CLASS);
- const [{ mountApp }] = await Promise.all([
+ const [{ mountApp }, { initializeDashboardApiServices }] = await Promise.all([
import('./dashboard_app/dashboard_router'),
import('./dashboard_renderer/dashboard_module'),
untilPluginStartServicesReady(),
]);
appMounted();
- const [coreStart] = await core.getStartServices();
+ const [[coreStart], _] = await Promise.all([
+ core.getStartServices(),
+ initializeDashboardApiServices(),
+ ]);
const mountContext: DashboardMountContextProps = {
restorePreviousUrl,
diff --git a/src/platform/plugins/shared/dashboard/public/services/dashboard_api_services.ts b/src/platform/plugins/shared/dashboard/public/services/dashboard_api_services.ts
new file mode 100644
index 0000000000000..d62177dd13884
--- /dev/null
+++ b/src/platform/plugins/shared/dashboard/public/services/dashboard_api_services.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the "Elastic License
+ * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
+ * Public License v 1"; you may not use this file except in compliance with, at
+ * your election, the "Elastic License 2.0", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+import {
+ type DashboardBackupService,
+ createDashboardBackupService,
+} from './dashboard_backup_service';
+import { spacesService } from './kibana_services';
+
+let backupService: DashboardBackupService | undefined;
+let servicesAvailablePromise: Promise | undefined;
+
+export const getDashboardBackupService = () => {
+ if (!backupService)
+ throw new Error(
+ 'Ensure initialize Dashboard app services is called before trying to access one of its services'
+ );
+ return backupService;
+};
+
+/**
+ * Initializes Dashboard API service singletons if they haven't been initialized already.
+ */
+export const initializeDashboardApiServices = async () => {
+ if (backupService) return;
+ if (servicesAvailablePromise) return servicesAvailablePromise;
+ servicesAvailablePromise = (async () => {
+ backupService = await createDashboardBackupService(spacesService);
+ })();
+ return servicesAvailablePromise;
+};
diff --git a/src/platform/plugins/shared/dashboard/public/services/dashboard_backup_service.ts b/src/platform/plugins/shared/dashboard/public/services/dashboard_backup_service.ts
index 32c9449f2b134..400d299ba6680 100644
--- a/src/platform/plugins/shared/dashboard/public/services/dashboard_backup_service.ts
+++ b/src/platform/plugins/shared/dashboard/public/services/dashboard_backup_service.ts
@@ -7,34 +7,23 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
-import { isEqual } from 'lodash';
-import { firstValueFrom } from 'rxjs';
-
-import { i18n } from '@kbn/i18n';
import { Storage } from '@kbn/kibana-utils-plugin/public';
-import { set } from '@kbn/safer-lodash-set';
-
import type { ViewMode } from '@kbn/presentation-publishing';
-import { coreServices, spacesService } from './kibana_services';
+import { set } from '@kbn/safer-lodash-set';
+import type { SpacesApi } from '@kbn/spaces-plugin/public';
+import { isEqual } from 'lodash';
+import { firstValueFrom } from 'rxjs';
import type { DashboardState } from '../../common';
export const DASHBOARD_PANELS_UNSAVED_ID = 'unsavedDashboard';
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';
-const getPanelsGetError = (message: string) =>
- i18n.translate('dashboard.panelStorageError.getError', {
- defaultMessage: 'Error encountered while fetching unsaved changes: {message}',
- values: { message },
- });
-
export type DashboardBackupState = Partial & {
viewMode?: ViewMode;
};
-interface DashboardBackupServiceType {
+export interface DashboardBackupService {
clearState: (id?: string) => void;
getState: (id: string | undefined) => DashboardBackupState | undefined;
setState: (id: string | undefined, backupState: DashboardBackupState) => void;
@@ -44,129 +33,6 @@ interface DashboardBackupServiceType {
dashboardHasUnsavedEdits: (id?: string) => boolean;
}
-class DashboardBackupService implements DashboardBackupServiceType {
- private activeSpaceId: string;
- private sessionStorage: Storage;
- private localStorage: Storage;
- private prevDashboardIdsWithUnsavedChanges: string[] = [];
-
- constructor() {
- this.sessionStorage = new Storage(sessionStorage);
- this.localStorage = new Storage(localStorage);
-
- this.activeSpaceId = 'default';
- if (spacesService) {
- firstValueFrom(spacesService.getActiveSpace$()).then((space) => {
- this.activeSpaceId = space.id;
- });
- }
- }
-
- public getViewMode = (): ViewMode => {
- return this.localStorage.get(DASHBOARD_VIEWMODE_LOCAL_KEY) ?? 'view';
- };
-
- public storeViewMode = (viewMode: ViewMode) => {
- try {
- this.localStorage.set(DASHBOARD_VIEWMODE_LOCAL_KEY, viewMode);
- } catch (e) {
- coreServices.notifications.toasts.addDanger({
- title: i18n.translate('dashboard.viewmodeBackup.error', {
- defaultMessage: 'Error encountered while backing up view mode: {message}',
- values: { message: e.message },
- }),
- 'data-test-subj': 'dashboardViewmodeBackupFailure',
- });
- }
- };
-
- public clearState(id = DASHBOARD_PANELS_UNSAVED_ID) {
- try {
- const allSpaces = this.sessionStorage.get(DASHBOARD_STATE_SESSION_KEY) ?? {};
- const dashboards = this.getDashboards();
- if (dashboards[id]) {
- delete dashboards[id];
- this.sessionStorage.set(DASHBOARD_STATE_SESSION_KEY, {
- ...allSpaces,
- [this.activeSpaceId]: dashboards,
- });
- }
- } catch (e) {
- coreServices.notifications.toasts.addDanger({
- title: i18n.translate('dashboard.panelStorageError.clearError', {
- defaultMessage: 'Error encountered while clearing unsaved changes: {message}',
- values: { message: e.message },
- }),
- 'data-test-subj': 'dashboardPanelsClearFailure',
- });
- }
- }
-
- public getState(id = DASHBOARD_PANELS_UNSAVED_ID) {
- try {
- const dashboards = this.getDashboards();
- return dashboards[id];
- } catch (e) {
- coreServices.notifications.toasts.addDanger({
- title: getPanelsGetError(e.message),
- 'data-test-subj': 'dashboardPanelsGetFailure',
- });
- }
- }
-
- public setState(id = DASHBOARD_PANELS_UNSAVED_ID, backupState: DashboardBackupState) {
- try {
- const allSpaces = this.sessionStorage.get(DASHBOARD_STATE_SESSION_KEY) ?? {};
- set(allSpaces, [this.activeSpaceId, id], backupState);
- this.sessionStorage.set(DASHBOARD_STATE_SESSION_KEY, allSpaces);
- } 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 getDashboardIdsWithUnsavedChanges() {
- try {
- const dashboards = this.getDashboards();
-
- const dashboardIdsWithUnsavedChanges = Object.keys(dashboards).filter((dashboardId) => {
- return hasUnsavedEdits(dashboards[dashboardId]);
- });
-
- /**
- * Because we are storing these unsaved dashboard IDs in React component state, we only want things to be re-rendered
- * if the **contents** change, not if the array reference changes
- */
- if (isEqual(this.prevDashboardIdsWithUnsavedChanges, dashboardIdsWithUnsavedChanges)) {
- return this.prevDashboardIdsWithUnsavedChanges;
- }
-
- this.prevDashboardIdsWithUnsavedChanges = dashboardIdsWithUnsavedChanges;
- return dashboardIdsWithUnsavedChanges;
- } catch (e) {
- coreServices.notifications.toasts.addDanger({
- title: getPanelsGetError(e.message),
- 'data-test-subj': 'dashboardPanelsGetFailure',
- });
- return [];
- }
- }
-
- public dashboardHasUnsavedEdits(id = DASHBOARD_PANELS_UNSAVED_ID) {
- const dashboards = this.getDashboards();
- return hasUnsavedEdits(dashboards[id]);
- }
-
- private getDashboards(): { [key: string]: DashboardBackupState } {
- return this.sessionStorage.get(DASHBOARD_STATE_SESSION_KEY)?.[this.activeSpaceId] ?? {};
- }
-}
-
function hasUnsavedEdits(backupState?: DashboardBackupState) {
return backupState
? backupState.viewMode === 'edit' &&
@@ -176,11 +42,80 @@ function hasUnsavedEdits(backupState?: DashboardBackupState) {
: false;
}
-let dashboardBackupService: DashboardBackupService;
+export const createDashboardBackupService = async (
+ spacesService?: SpacesApi
+): Promise => {
+ const sessionStore = new Storage(sessionStorage);
+ const localStore = new Storage(localStorage);
+
+ const activeSpaceId = await (async () => {
+ if (spacesService) return (await firstValueFrom(spacesService.getActiveSpace$())).id;
+ return 'default';
+ })();
+
+ let dashboardIDsWithUnsavedChanges: string[] = [];
+ const getUnsavedDashboardChanges = (): { [key: string]: DashboardBackupState } =>
+ sessionStore.get(DASHBOARD_STATE_SESSION_KEY)?.[activeSpaceId] ?? {};
+
+ /**
+ * The backup service is a non path-critical service that interacts with browser capabilities.
+ * There is potential for errors, and when an error is encountered we want to swallow the error
+ * semi-silently and log a warning instead.
+ */
+ const warnOnErrors = (
+ attemptFunction: () => ReturnType
+ ): ReturnType | undefined => {
+ try {
+ return attemptFunction();
+ } catch (e) {
+ // eslint-disable-next-line no-console
+ console.warn('Error encountered in Dashboard backup service', e);
+ }
+ };
-export const getDashboardBackupService = () => {
- if (!dashboardBackupService) {
- dashboardBackupService = new DashboardBackupService();
- }
- return dashboardBackupService;
+ return {
+ getViewMode: () => localStore.get(DASHBOARD_VIEWMODE_LOCAL_KEY) ?? 'view',
+ storeViewMode: (viewMode: ViewMode) => {
+ warnOnErrors(() => localStore.set(DASHBOARD_VIEWMODE_LOCAL_KEY, viewMode));
+ },
+ clearState: (dashboardId = DASHBOARD_PANELS_UNSAVED_ID) => {
+ warnOnErrors(() => {
+ const allSpaces = sessionStore.get(DASHBOARD_STATE_SESSION_KEY) ?? {};
+ const dashboards = getUnsavedDashboardChanges();
+ if (dashboards[dashboardId]) {
+ delete dashboards[dashboardId];
+ sessionStore.set(DASHBOARD_STATE_SESSION_KEY, {
+ ...allSpaces,
+ [activeSpaceId]: dashboards,
+ });
+ }
+ });
+ },
+ getState: (dashboardId = DASHBOARD_PANELS_UNSAVED_ID) => {
+ return warnOnErrors(() => getUnsavedDashboardChanges()[dashboardId]);
+ },
+ setState: (dashboardId = DASHBOARD_PANELS_UNSAVED_ID, backupState: DashboardBackupState) => {
+ return warnOnErrors(() => {
+ const allSpaces = sessionStore.get(DASHBOARD_STATE_SESSION_KEY) ?? {};
+ set(allSpaces, [activeSpaceId, dashboardId], backupState);
+ sessionStore.set(DASHBOARD_STATE_SESSION_KEY, allSpaces);
+ });
+ },
+ getDashboardIdsWithUnsavedChanges: () => {
+ return (
+ warnOnErrors(() => {
+ const unsavedDashboards = getUnsavedDashboardChanges();
+ const nextDashboardIdsWithUnsavedChanges = Object.keys(unsavedDashboards).filter((id) =>
+ hasUnsavedEdits(unsavedDashboards[id])
+ );
+ if (!isEqual(nextDashboardIdsWithUnsavedChanges, dashboardIDsWithUnsavedChanges)) {
+ dashboardIDsWithUnsavedChanges = nextDashboardIdsWithUnsavedChanges;
+ }
+ return dashboardIDsWithUnsavedChanges;
+ }) ?? []
+ );
+ },
+ dashboardHasUnsavedEdits: (id = DASHBOARD_PANELS_UNSAVED_ID) =>
+ warnOnErrors(() => hasUnsavedEdits(getUnsavedDashboardChanges()[id])) ?? false,
+ };
};
diff --git a/src/platform/plugins/shared/dashboard/public/services/kibana_services.ts b/src/platform/plugins/shared/dashboard/public/services/kibana_services.ts
index 7411dda44da87..a6854bb8513dc 100644
--- a/src/platform/plugins/shared/dashboard/public/services/kibana_services.ts
+++ b/src/platform/plugins/shared/dashboard/public/services/kibana_services.ts
@@ -8,17 +8,17 @@
*/
import { BehaviorSubject } from 'rxjs';
-
import type { ContentManagementPublicStart } from '@kbn/content-management-plugin/public';
import type { CoreStart } from '@kbn/core/public';
+import type { CPSPluginStart } from '@kbn/cps/public';
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
import type { DataViewEditorStart } from '@kbn/data-view-editor-plugin/public';
import type { EmbeddableStart } from '@kbn/embeddable-plugin/public';
import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public/plugin';
+import type { LensPublicStart } from '@kbn/lens-plugin/public';
import type { NavigationPublicPluginStart } from '@kbn/navigation-plugin/public';
import type { NoDataPagePluginStart } from '@kbn/no-data-page-plugin/public';
import type { ObservabilityAIAssistantPublicStart } from '@kbn/observability-ai-assistant-plugin/public';
-import type { LensPublicStart } from '@kbn/lens-plugin/public';
import type { PresentationUtilPluginStart } from '@kbn/presentation-util-plugin/public';
import type { SavedObjectTaggingOssPluginStart } from '@kbn/saved-objects-tagging-oss-plugin/public';
import type { ScreenshotModePluginStart } from '@kbn/screenshot-mode-plugin/public';
@@ -26,11 +26,9 @@ import type { ServerlessPluginStart } from '@kbn/serverless/public';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import type { SpacesApi } from '@kbn/spaces-plugin/public';
import type { UiActionsPublicStart } from '@kbn/ui-actions-plugin/public/plugin';
+import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
import type { UrlForwardingStart } from '@kbn/url-forwarding-plugin/public';
import type { UsageCollectionStart } from '@kbn/usage-collection-plugin/public';
-import type { CPSPluginStart } from '@kbn/cps/public';
-import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
-
import type { DashboardStartDependencies } from '../plugin';
export let coreServices: CoreStart;
@@ -57,6 +55,9 @@ export let usageCollectionService: UsageCollectionStart | undefined;
const servicesReady$ = new BehaviorSubject(false);
+/**
+ * Allows module-level access to all of the Dashboard plugin's dependencies.
+ */
export const setKibanaServices = (kibanaCore: CoreStart, deps: DashboardStartDependencies) => {
coreServices = kibanaCore;
cpsService = deps.cps;
diff --git a/x-pack/platform/plugins/private/translations/translations/de-DE.json b/x-pack/platform/plugins/private/translations/translations/de-DE.json
index 8d4b1e32b128a..e927fab08ac07 100644
--- a/x-pack/platform/plugins/private/translations/translations/de-DE.json
+++ b/x-pack/platform/plugins/private/translations/translations/de-DE.json
@@ -1457,9 +1457,6 @@
"dashboard.panel.unlinkFromLibrary.failureMessage": "Beim Aufheben der Verknüpfung von {panelTitle} aus der Bibliothek ist ein Fehler aufgetreten.",
"dashboard.panel.unlinkFromLibrary.successMessage": "Panel {panelTitle} ist nicht mehr mit der Bibliothek verbunden.",
"dashboard.panelPlacement.unknownStrategyError": "Unbekannte Strategie zur Panelplatzierung: {strategy}",
- "dashboard.panelStorageError.clearError": "Beim Löschen ungespeicherter Änderungen ist ein Fehler aufgetreten: {message}",
- "dashboard.panelStorageError.getError": "Fehler beim Abrufen der ungespeicherten Änderungen: {message}",
- "dashboard.panelStorageError.setError": "Beim Festlegen ungespeicherter Änderungen ist ein Fehler aufgetreten: {message}",
"dashboard.renderer.404Action": "Verfügbare Dashboards anzeigen",
"dashboard.renderer.404Body": "Leider kann das gesuchte Dashboard nicht gefunden werden. Es könnte entfernt oder umbenannt worden sein, oder vielleicht hat es nie existiert.",
"dashboard.renderer.404Title": "Dashboard nicht gefunden",
@@ -1507,7 +1504,6 @@
"dashboard.topNave.viewModeInteractiveSaveConfigDescription": "Erstellen Sie eine Kopie Ihres Dashboards.",
"dashboard.unsavedChangesBadge": "Nicht gespeicherte Änderungen",
"dashboard.unsavedChangesBadgeToolTipContent": "Sie haben ungespeicherte Änderungen in diesem Dashboard. Um dieses Label zu entfernen, speichern Sie das Dashboard.",
- "dashboard.viewmodeBackup.error": "Fehler beim Sichern des Ansichtsmodus: {message}",
"data.advancedSettings.autocompleteIgnoreTimerange": "Zeitbereich verwenden",
"data.advancedSettings.autocompleteIgnoreTimerangeText": "Deaktivieren Sie diese Eigenschaften, um Vorschläge für die automatische Vervollständigung aus Ihren gesamten Datensätzen und nicht aus dem aktuellen Zeitbereich zu erhalten. {learnMoreLink}",
"data.advancedSettings.autocompleteValueSuggestionMethod": "Methode für automatische Vervollständigung mit Vorschlägen",
diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json
index af63f5ded18ef..22023e2c6f7b6 100644
--- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json
+++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json
@@ -1476,9 +1476,6 @@
"dashboard.panel.unlinkFromLibrary.failureMessage": "Une erreur s'est produite lors de la dissociation du panneau {panelTitle} de la bibliothèque.",
"dashboard.panel.unlinkFromLibrary.successMessage": "Le panneau {panelTitle} n'est plus connecté à la bibliothèque.",
"dashboard.panelPlacement.unknownStrategyError": "Stratégie de placement de panneau inconnue : {strategy}",
- "dashboard.panelStorageError.clearError": "Une erreur s'est produite lors de la suppression des modifications non enregistrées : {message}.",
- "dashboard.panelStorageError.getError": "Une erreur s'est produite lors de la récupération des modifications non enregistrées : {message}.",
- "dashboard.panelStorageError.setError": "Une erreur s'est produite lors de la définition des modifications non enregistrées : {message}.",
"dashboard.renderer.404Action": "Voir les tableaux de bord disponibles",
"dashboard.renderer.404Body": "Désolé, le tableau de bord que vous recherchez est introuvable. Elle a peut-être été retirée ou renommée, ou peut-être qu'elle n'a jamais existé.",
"dashboard.renderer.404Title": "Tableau de bord introuvable",
@@ -1526,7 +1523,6 @@
"dashboard.topNave.viewModeInteractiveSaveConfigDescription": "Créer une copie du tableau de bord",
"dashboard.unsavedChangesBadge": "Modifications non enregistrées",
"dashboard.unsavedChangesBadgeToolTipContent": "Vous avez des modifications non enregistrées dans ce tableau de bord. Pour supprimer cette étiquette, enregistrez le tableau de bord.",
- "dashboard.viewmodeBackup.error": "Une erreur s'est produite lors de la sauvegarde du mode d'affichage : {message}",
"data.advancedSettings.autocompleteIgnoreTimerange": "Utiliser la plage temporelle",
"data.advancedSettings.autocompleteIgnoreTimerangeText": "Désactivez cette propriété pour obtenir des suggestions de saisie semi-automatique depuis l’intégralité de l’ensemble de données plutôt que depuis la plage temporelle définie. {learnMoreLink}",
"data.advancedSettings.autocompleteValueSuggestionMethod": "Méthode de suggestion de saisie semi-automatique",
diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json
index 2d6c0c4916a9c..1693afea4ebf3 100644
--- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json
+++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json
@@ -1477,9 +1477,6 @@
"dashboard.panel.unlinkFromLibrary.failureMessage": "\"{panelTitle}\"をライブラリからリンク解除しているときにエラーが発生しました。",
"dashboard.panel.unlinkFromLibrary.successMessage": "パネル\"{panelTitle}\"はライブラリに接続されていません。",
"dashboard.panelPlacement.unknownStrategyError": "不明なパネル配置ストラテジ:{strategy}",
- "dashboard.panelStorageError.clearError": "保存されていない変更の消去中にエラーが発生しました。{message}",
- "dashboard.panelStorageError.getError": "保存されていない変更の取得中にエラーが発生しました。{message}",
- "dashboard.panelStorageError.setError": "保存されていない変更の設定中にエラーが発生しました。{message}",
"dashboard.renderer.404Action": "使用可能なダッシュボードを表示",
"dashboard.renderer.404Body": "申し訳ございません。お探しのダッシュボードは見つかりませんでした。削除または名前変更されたか、そもそも存在していなかった可能性があります。",
"dashboard.renderer.404Title": "ダッシュボードが見つかりません",
@@ -1527,7 +1524,6 @@
"dashboard.topNave.viewModeInteractiveSaveConfigDescription": "ダッシュボードのコピーを作成します",
"dashboard.unsavedChangesBadge": "保存されていない変更",
"dashboard.unsavedChangesBadgeToolTipContent": "このダッシュボードには保存されていない変更があります。このラベルを削除するには、ダッシュボードを保存します。",
- "dashboard.viewmodeBackup.error": "表示モードのバックアップ中にエラーが発生しました:{message}",
"data.advancedSettings.autocompleteIgnoreTimerange": "時間範囲を使用",
"data.advancedSettings.autocompleteIgnoreTimerangeText": "このプロパティを無効にすると、現在の時間範囲からではなく、データセットからオートコンプリートの候補を取得します。{learnMoreLink}",
"data.advancedSettings.autocompleteValueSuggestionMethod": "自動入力値候補の提案方法",
diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json
index 4e53ef225ee5a..9d3eed03e0c74 100644
--- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json
+++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json
@@ -1471,9 +1471,6 @@
"dashboard.panel.unlinkFromLibrary.failureMessage": "从该库中取消链接 {panelTitle} 时出错。",
"dashboard.panel.unlinkFromLibrary.successMessage": "面板 {panelTitle} 不再与该库连接。",
"dashboard.panelPlacement.unknownStrategyError": "未知面板位置策略:{strategy}",
- "dashboard.panelStorageError.clearError": "清除未保存更改时遇到错误:{message}",
- "dashboard.panelStorageError.getError": "获取未保存更改时遇到错误:{message}",
- "dashboard.panelStorageError.setError": "设置未保存更改时遇到错误:{message}",
"dashboard.renderer.404Action": "查看可用仪表板",
"dashboard.renderer.404Body": "抱歉,找不到您要查找的仪表板。该页面可能已移除、重命名,或可能根本不存在。",
"dashboard.renderer.404Title": "找不到仪表板",
@@ -1521,7 +1518,6 @@
"dashboard.topNave.viewModeInteractiveSaveConfigDescription": "创建仪表板的副本",
"dashboard.unsavedChangesBadge": "未保存的更改",
"dashboard.unsavedChangesBadgeToolTipContent": "在此仪表板中有未保存更改。要移除此标签,请保存该仪表板。",
- "dashboard.viewmodeBackup.error": "备份视图模式时出错:{message}",
"data.advancedSettings.autocompleteIgnoreTimerange": "使用时间范围",
"data.advancedSettings.autocompleteIgnoreTimerangeText": "禁用此属性可从您的完全数据集中获取自动完成建议,而非从当前时间范围。{learnMoreLink}",
"data.advancedSettings.autocompleteValueSuggestionMethod": "自动填充值建议方法",