From e47bfebb7b9a025f9695cc8f2e319dacddb4b8b7 Mon Sep 17 00:00:00 2001 From: Nick Peihl Date: Tue, 10 Dec 2024 16:36:20 -0500 Subject: [PATCH] Add Export flyout to dashboards --- src/plugins/dashboard/common/index.ts | 1 + .../public/dashboard_api/get_dashboard_api.ts | 8 + .../dashboard/public/dashboard_api/types.ts | 7 +- .../dashboard_app/_dashboard_app_strings.ts | 8 + .../top_nav/export/show_export_flyout.tsx | 111 ++++++++++++ .../top_nav/use_dashboard_menu_items.tsx | 50 +++++- .../index.ts | 2 + .../lib/get_dashboard_state.ts | 159 +++++++++++++++++ .../lib/save_dashboard_state.ts | 160 ++---------------- .../types.ts | 12 ++ 10 files changed, 368 insertions(+), 150 deletions(-) create mode 100644 src/plugins/dashboard/public/dashboard_app/top_nav/export/show_export_flyout.tsx create mode 100644 src/plugins/dashboard/public/services/dashboard_content_management_service/lib/get_dashboard_state.ts diff --git a/src/plugins/dashboard/common/index.ts b/src/plugins/dashboard/common/index.ts index be2cedf889e85..c8c988d5c461e 100644 --- a/src/plugins/dashboard/common/index.ts +++ b/src/plugins/dashboard/common/index.ts @@ -32,6 +32,7 @@ export { prefixReferencesFromPanel } from './dashboard_container/persistable_sta export { convertPanelsArrayToPanelMap, convertPanelMapToPanelsArray, + generateNewPanelIds, } from './lib/dashboard_panel_converters'; export const UI_SETTINGS = { diff --git a/src/plugins/dashboard/public/dashboard_api/get_dashboard_api.ts b/src/plugins/dashboard/public/dashboard_api/get_dashboard_api.ts index 02c29968e526d..3a8ee11502b86 100644 --- a/src/plugins/dashboard/public/dashboard_api/get_dashboard_api.ts +++ b/src/plugins/dashboard/public/dashboard_api/get_dashboard_api.ts @@ -172,6 +172,14 @@ export function getDashboardApi({ unifiedSearchManager.internalApi.controlGroupReload$, unifiedSearchManager.internalApi.panelsReload$ ).pipe(debounceTime(0)), + getDashboardState: async () => { + const { controlGroupReferences, dashboardState, panelReferences } = await getState(); + return getDashboardContentManagementService().getDashboardState({ + controlGroupReferences, + currentState: dashboardState, + panelReferences, + }); + }, runInteractiveSave: async () => { trackOverlayApi.clearOverlays(); const saveResult = await openSaveModal({ diff --git a/src/plugins/dashboard/public/dashboard_api/types.ts b/src/plugins/dashboard/public/dashboard_api/types.ts index 2cfe5aa615f3b..b6ec5bb39a306 100644 --- a/src/plugins/dashboard/public/dashboard_api/types.ts +++ b/src/plugins/dashboard/public/dashboard_api/types.ts @@ -53,8 +53,9 @@ import { IKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public'; import { PublishesReload } from '@kbn/presentation-publishing/interfaces/fetch/publishes_reload'; import { PublishesSearchSession } from '@kbn/presentation-publishing/interfaces/fetch/publishes_search_session'; import { LocatorPublic } from '@kbn/share-plugin/common'; +import type { SavedObjectReference } from '@kbn/core-saved-objects-api-server'; import { DashboardPanelMap, DashboardPanelState } from '../../common'; -import type { DashboardOptions } from '../../server/content_management'; +import type { DashboardAttributes, DashboardOptions } from '../../server/content_management'; import { LoadDashboardReturn, SaveDashboardReturn, @@ -153,6 +154,10 @@ export type DashboardApi = CanExpandPanels & focusedPanelId$: PublishingSubject; forceRefresh: () => void; getSettings: () => DashboardStateFromSettingsFlyout; + getDashboardState: () => Promise<{ + attributes: DashboardAttributes; + references: SavedObjectReference[]; + }>; getDashboardPanelFromId: (id: string) => Promise; hasOverlays$: PublishingSubject; hasRunMigrations$: PublishingSubject; diff --git a/src/plugins/dashboard/public/dashboard_app/_dashboard_app_strings.ts b/src/plugins/dashboard/public/dashboard_app/_dashboard_app_strings.ts index 9c6526ce3403e..e533c10bf06b1 100644 --- a/src/plugins/dashboard/public/dashboard_app/_dashboard_app_strings.ts +++ b/src/plugins/dashboard/public/dashboard_app/_dashboard_app_strings.ts @@ -175,6 +175,14 @@ export const topNavStrings = { defaultMessage: 'Switch to edit mode', }), }, + export: { + label: i18n.translate('dashboard.topNav.exportButtonAriaLabel', { + defaultMessage: 'export', + }), + description: i18n.translate('dashboard.topNav.exportConfigDescription', { + defaultMessage: 'Export Dashboard', + }), + }, quickSave: { label: i18n.translate('dashboard.topNave.saveButtonAriaLabel', { defaultMessage: 'save', diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/export/show_export_flyout.tsx b/src/plugins/dashboard/public/dashboard_app/top_nav/export/show_export_flyout.tsx new file mode 100644 index 0000000000000..1b7b7edab9d0c --- /dev/null +++ b/src/plugins/dashboard/public/dashboard_app/top_nav/export/show_export_flyout.tsx @@ -0,0 +1,111 @@ +/* + * 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 React, { useEffect } from 'react'; +import { css } from '@emotion/react'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { + EuiCallOut, + EuiCodeBlock, + EuiEmptyPrompt, + EuiFlyoutBody, + EuiFlyoutHeader, + EuiLoadingChart, + EuiTitle, +} from '@elastic/eui'; +import { DashboardApi } from '../../..'; + +const flyoutBodyCss = css` + height: 100%; + .euiFlyoutBody__overflowContent { + height: 100%; + padding: 0; + } +`; + +export interface DashboardExportFlyoutProps { + close: () => void; + getDashboardState: DashboardApi['getDashboardState']; +} + +export const DashboardExportFlyout: React.FC = ({ + close, + getDashboardState, +}) => { + const [{ data: dashboard, loading, error }, setDashboardState] = React.useState<{ + loading: boolean; + data: Awaited> | null; + error: unknown | null; + }>({ loading: true, data: null, error: null }); + + useEffect(() => { + const loadDashboardState = () => { + getDashboardState() + .then((_dashboard) => + setDashboardState((prevState) => ({ + ...prevState, + loading: false, + data: _dashboard, + })) + ) + .catch((err) => + setDashboardState((prevState) => ({ + ...prevState, + loading: false, + error: err, + })) + ); + }; + + loadDashboardState(); + }, [getDashboardState]); + + return ( + <> + + +

+ +

+
+
+ + {error ? ( + + } + color="danger" + iconType="alert" + /> + ) : ( + <> + {loading ? ( + } + /> + ) : ( + + {JSON.stringify(dashboard, null, 2)} + + )} + + )} + + + ); +}; diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/use_dashboard_menu_items.tsx b/src/plugins/dashboard/public/dashboard_app/top_nav/use_dashboard_menu_items.tsx index 0a96d3d978968..cdd5b637d7873 100644 --- a/src/plugins/dashboard/public/dashboard_app/top_nav/use_dashboard_menu_items.tsx +++ b/src/plugins/dashboard/public/dashboard_app/top_nav/use_dashboard_menu_items.tsx @@ -7,13 +7,14 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { Dispatch, SetStateAction, useCallback, useMemo, useState } from 'react'; +import React, { Dispatch, SetStateAction, useCallback, useMemo, useState } from 'react'; import { ViewMode } from '@kbn/embeddable-plugin/public'; import type { TopNavMenuData } from '@kbn/navigation-plugin/public'; import useMountedState from 'react-use/lib/useMountedState'; import { useBatchedPublishingSubjects } from '@kbn/presentation-publishing'; +import { toMountPoint } from '@kbn/react-kibana-mount'; import { UI_SETTINGS } from '../../../common'; import { useDashboardApi } from '../../dashboard_api/use_dashboard_api'; import { CHANGE_CHECK_DEBOUNCE } from '../../dashboard_constants'; @@ -25,6 +26,7 @@ import { coreServices, shareService } from '../../services/kibana_services'; import { getDashboardCapabilities } from '../../utils/get_dashboard_capabilities'; import { topNavStrings } from '../_dashboard_app_strings'; import { ShowShareModal } from './share/show_share_modal'; +import { DashboardExportFlyout } from './export/show_export_flyout'; export const useDashboardMenuItems = ({ isLabsShown, @@ -70,6 +72,34 @@ export const useDashboardMenuItems = ({ [dashboardTitle, hasUnsavedChanges, lastSavedId, dashboardApi] ); + /** + * Show Export flyout + */ + const showExport = useCallback(() => { + dashboardApi.openOverlay( + coreServices.overlays.openFlyout( + toMountPoint( + dashboardApi.clearOverlays()} + />, + { + i18n: coreServices.i18n, + theme: coreServices.theme, + } + ), + { + size: 'm', + 'data-test-subj': 'dashboardExportFlyout', + onClose: (flyout) => { + dashboardApi.clearOverlays(); + flyout.close(); + }, + } + ) + ); + }, [dashboardApi]); + /** * Save the dashboard without any UI or popups. */ @@ -200,6 +230,14 @@ export const useDashboardMenuItems = ({ run: showShare, } as TopNavMenuData, + export: { + ...topNavStrings.export, + id: 'export', + testId: 'dashboardExportMenuItem', + disableButton: disableTopNav, + run: showExport, + }, + settings: { ...topNavStrings.settings, id: 'settings', @@ -217,6 +255,7 @@ export const useDashboardMenuItems = ({ dashboardInteractiveSave, viewMode, showShare, + showExport, dashboardApi, setIsLabsShown, isLabsShown, @@ -266,6 +305,7 @@ export const useDashboardMenuItems = ({ ...labsMenuItem, menuItems.fullScreen, ...shareMenuItem, + menuItems.export, ...duplicateMenuItem, ...mayberesetChangesMenuItem, ...editMenuItem, @@ -288,7 +328,13 @@ export const useDashboardMenuItems = ({ } else { editModeItems.push(menuItems.switchToViewMode, menuItems.interactiveSave); } - return [...labsMenuItem, menuItems.settings, ...shareMenuItem, ...editModeItems]; + return [ + ...labsMenuItem, + menuItems.settings, + ...shareMenuItem, + menuItems.export, + ...editModeItems, + ]; }, [isLabsEnabled, menuItems, lastSavedId, showResetChange, resetChangesMenuItem]); return { viewModeTopNavConfig, editModeTopNavConfig }; diff --git a/src/plugins/dashboard/public/services/dashboard_content_management_service/index.ts b/src/plugins/dashboard/public/services/dashboard_content_management_service/index.ts index ebc5a414f9f64..1a610a523797a 100644 --- a/src/plugins/dashboard/public/services/dashboard_content_management_service/index.ts +++ b/src/plugins/dashboard/public/services/dashboard_content_management_service/index.ts @@ -16,6 +16,7 @@ import { findDashboardsByIds, searchDashboards, } from './lib/find_dashboards'; +import { getDashboardState } from './lib/get_dashboard_state'; import { loadDashboardState } from './lib/load_dashboard_state'; import { saveDashboardState } from './lib/save_dashboard_state'; import { updateDashboardMeta } from './lib/update_dashboard_meta'; @@ -32,6 +33,7 @@ export const getDashboardContentManagementService = () => { return { loadDashboardState, saveDashboardState, + getDashboardState, findDashboards: { search: searchDashboards, findById: findDashboardById, diff --git a/src/plugins/dashboard/public/services/dashboard_content_management_service/lib/get_dashboard_state.ts b/src/plugins/dashboard/public/services/dashboard_content_management_service/lib/get_dashboard_state.ts new file mode 100644 index 0000000000000..cc4d32c3be9f3 --- /dev/null +++ b/src/plugins/dashboard/public/services/dashboard_content_management_service/lib/get_dashboard_state.ts @@ -0,0 +1,159 @@ +/* + * 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 { pick } from 'lodash'; +import moment, { Moment } from 'moment'; +import { isFilterPinned } from '@kbn/es-query'; +import type { SavedObjectReference } from '@kbn/core/server'; +import { RefreshInterval, extractSearchSourceReferences } from '@kbn/data-plugin/public'; + +import { + convertPanelMapToPanelsArray, + extractReferences, + generateNewPanelIds, +} from '../../../../common'; +import type { DashboardAttributes } from '../../../../server'; + +import { convertDashboardVersionToNumber } from './dashboard_versioning'; +import { DashboardSearchSource, GetDashboardStateProps } from '../types'; +import { dataService, embeddableService, savedObjectsTaggingService } from '../../kibana_services'; +import { LATEST_DASHBOARD_CONTAINER_VERSION } from '../../../dashboard_container'; + +export const convertTimeToUTCString = (time?: string | Moment): undefined | string => { + if (moment(time).isValid()) { + return moment(time).utc().format('YYYY-MM-DDTHH:mm:ss.SSS[Z]'); + } else { + // If it's not a valid moment date, then it should be a string representing a relative time + // like 'now' or 'now-15m'. + return time as string; + } +}; + +export const getDashboardState = async ({ + controlGroupReferences, + generateNewIds, + currentState, + panelReferences, +}: GetDashboardStateProps) => { + const { + search: dataSearchService, + query: { + timefilter: { timefilter }, + }, + } = dataService; + + const { + tags, + query, + title, + filters, + timeRestore, + description, + + // Dashboard options + useMargins, + syncColors, + syncCursor, + syncTooltips, + hidePanelTitles, + controlGroupInput, + } = currentState; + + let { panels } = currentState; + let prefixedPanelReferences = panelReferences; + if (generateNewIds) { + const { panels: newPanels, references: newPanelReferences } = generateNewPanelIds( + panels, + panelReferences + ); + panels = newPanels; + prefixedPanelReferences = newPanelReferences; + // + // do not need to generate new ids for controls. + // ControlGroup Component is keyed on dashboard id so changing dashboard id mounts new ControlGroup Component. + // + } + + const { searchSource, searchSourceReferences } = await (async () => { + const searchSourceFields = await dataSearchService.searchSource.create(); + searchSourceFields.setField( + 'filter', // save only unpinned filters + filters.filter((filter) => !isFilterPinned(filter)) + ); + searchSourceFields.setField('query', query); + + const rawSearchSourceFields = searchSourceFields.getSerializedFields(); + const [fields, references] = extractSearchSourceReferences(rawSearchSourceFields) as [ + DashboardSearchSource, + SavedObjectReference[] + ]; + return { searchSourceReferences: references, searchSource: fields }; + })(); + + const options = { + useMargins, + syncColors, + syncCursor, + syncTooltips, + hidePanelTitles, + }; + const savedPanels = convertPanelMapToPanelsArray(panels, true); + + /** + * Parse global time filter settings + */ + const { from, to } = timefilter.getTime(); + const timeFrom = timeRestore ? convertTimeToUTCString(from) : undefined; + const timeTo = timeRestore ? convertTimeToUTCString(to) : undefined; + const refreshInterval = timeRestore + ? (pick(timefilter.getRefreshInterval(), [ + 'display', + 'pause', + 'section', + 'value', + ]) as RefreshInterval) + : undefined; + + const rawDashboardAttributes: DashboardAttributes = { + version: convertDashboardVersionToNumber(LATEST_DASHBOARD_CONTAINER_VERSION), + controlGroupInput: controlGroupInput as DashboardAttributes['controlGroupInput'], + kibanaSavedObjectMeta: { searchSource }, + description: description ?? '', + refreshInterval, + timeRestore, + options, + panels: savedPanels, + timeFrom, + title, + timeTo, + }; + + /** + * Extract references from raw attributes and tags into the references array. + */ + const { attributes, references: dashboardReferences } = extractReferences( + { + attributes: rawDashboardAttributes, + references: searchSourceReferences, + }, + { embeddablePersistableStateService: embeddableService } + ); + + const savedObjectsTaggingApi = savedObjectsTaggingService?.getTaggingApi(); + const references = savedObjectsTaggingApi?.ui.updateTagsReferences + ? savedObjectsTaggingApi?.ui.updateTagsReferences(dashboardReferences, tags) + : dashboardReferences; + + const allReferences = [ + ...references, + ...(prefixedPanelReferences ?? []), + ...(controlGroupReferences ?? []), + ]; + return { attributes, references: allReferences }; +}; diff --git a/src/plugins/dashboard/public/services/dashboard_content_management_service/lib/save_dashboard_state.ts b/src/plugins/dashboard/public/services/dashboard_content_management_service/lib/save_dashboard_state.ts index 58492f51f4d36..360fbe22f36cf 100644 --- a/src/plugins/dashboard/public/services/dashboard_content_management_service/lib/save_dashboard_state.ts +++ b/src/plugins/dashboard/public/services/dashboard_content_management_service/lib/save_dashboard_state.ts @@ -7,46 +7,19 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { pick } from 'lodash'; -import moment, { Moment } from 'moment'; - -import { extractSearchSourceReferences, RefreshInterval } from '@kbn/data-plugin/public'; -import { isFilterPinned } from '@kbn/es-query'; - -import type { SavedObjectReference } from '@kbn/core/server'; import { getDashboardContentManagementCache } from '..'; -import { convertPanelMapToPanelsArray, extractReferences } from '../../../../common'; import type { - DashboardAttributes, DashboardCreateIn, DashboardCreateOut, DashboardUpdateIn, DashboardUpdateOut, } from '../../../../server/content_management'; -import { generateNewPanelIds } from '../../../../common/lib/dashboard_panel_converters'; import { DASHBOARD_CONTENT_ID } from '../../../dashboard_constants'; -import { LATEST_DASHBOARD_CONTAINER_VERSION } from '../../../dashboard_container'; import { dashboardSaveToastStrings } from '../../../dashboard_container/_dashboard_container_strings'; import { getDashboardBackupService } from '../../dashboard_backup_service'; -import { - contentManagementService, - coreServices, - dataService, - embeddableService, - savedObjectsTaggingService, -} from '../../kibana_services'; -import { DashboardSearchSource, SaveDashboardProps, SaveDashboardReturn } from '../types'; -import { convertDashboardVersionToNumber } from './dashboard_versioning'; - -export const convertTimeToUTCString = (time?: string | Moment): undefined | string => { - if (moment(time).isValid()) { - return moment(time).utc().format('YYYY-MM-DDTHH:mm:ss.SSS[Z]'); - } else { - // If it's not a valid moment date, then it should be a string representing a relative time - // like 'now' or 'now-15m'. - return time as string; - } -}; +import { contentManagementService, coreServices } from '../../kibana_services'; +import { SaveDashboardProps, SaveDashboardReturn } from '../types'; +import { getDashboardState } from './get_dashboard_state'; export const saveDashboardState = async ({ controlGroupReferences, @@ -55,121 +28,14 @@ export const saveDashboardState = async ({ currentState, panelReferences, }: SaveDashboardProps): Promise => { - const { - search: dataSearchService, - query: { - timefilter: { timefilter }, - }, - } = dataService; const dashboardContentManagementCache = getDashboardContentManagementCache(); - const { - tags, - query, - title, - filters, - timeRestore, - description, - - // Dashboard options - useMargins, - syncColors, - syncCursor, - syncTooltips, - hidePanelTitles, - controlGroupInput, - } = currentState; - - let { panels } = currentState; - let prefixedPanelReferences = panelReferences; - if (saveOptions.saveAsCopy) { - const { panels: newPanels, references: newPanelReferences } = generateNewPanelIds( - panels, - panelReferences - ); - panels = newPanels; - prefixedPanelReferences = newPanelReferences; - // - // do not need to generate new ids for controls. - // ControlGroup Component is keyed on dashboard id so changing dashboard id mounts new ControlGroup Component. - // - } - - const { searchSource, searchSourceReferences } = await (async () => { - const searchSourceFields = await dataSearchService.searchSource.create(); - searchSourceFields.setField( - 'filter', // save only unpinned filters - filters.filter((filter) => !isFilterPinned(filter)) - ); - searchSourceFields.setField('query', query); - - const rawSearchSourceFields = searchSourceFields.getSerializedFields(); - const [fields, references] = extractSearchSourceReferences(rawSearchSourceFields) as [ - DashboardSearchSource, - SavedObjectReference[] - ]; - return { searchSourceReferences: references, searchSource: fields }; - })(); - - const options = { - useMargins, - syncColors, - syncCursor, - syncTooltips, - hidePanelTitles, - }; - const savedPanels = convertPanelMapToPanelsArray(panels, true); - - /** - * Parse global time filter settings - */ - const { from, to } = timefilter.getTime(); - const timeFrom = timeRestore ? convertTimeToUTCString(from) : undefined; - const timeTo = timeRestore ? convertTimeToUTCString(to) : undefined; - const refreshInterval = timeRestore - ? (pick(timefilter.getRefreshInterval(), [ - 'display', - 'pause', - 'section', - 'value', - ]) as RefreshInterval) - : undefined; - - const rawDashboardAttributes: DashboardAttributes = { - version: convertDashboardVersionToNumber(LATEST_DASHBOARD_CONTAINER_VERSION), - controlGroupInput: controlGroupInput as DashboardAttributes['controlGroupInput'], - kibanaSavedObjectMeta: { searchSource }, - description: description ?? '', - refreshInterval, - timeRestore, - options, - panels: savedPanels, - timeFrom, - title, - timeTo, - }; - - /** - * Extract references from raw attributes and tags into the references array. - */ - const { attributes, references: dashboardReferences } = extractReferences( - { - attributes: rawDashboardAttributes, - references: searchSourceReferences, - }, - { embeddablePersistableStateService: embeddableService } - ); - - const savedObjectsTaggingApi = savedObjectsTaggingService?.getTaggingApi(); - const references = savedObjectsTaggingApi?.ui.updateTagsReferences - ? savedObjectsTaggingApi?.ui.updateTagsReferences(dashboardReferences, tags) - : dashboardReferences; - - const allReferences = [ - ...references, - ...(prefixedPanelReferences ?? []), - ...(controlGroupReferences ?? []), - ]; + const { attributes, references } = await getDashboardState({ + controlGroupReferences, + generateNewIds: saveOptions.saveAsCopy, + currentState, + panelReferences, + }); /** * Save the saved object using the content management @@ -183,7 +49,7 @@ export const saveDashboardState = async ({ contentTypeId: DASHBOARD_CONTENT_ID, data: attributes, options: { - references: allReferences, + references, /** perform a "full" update instead, where the provided attributes will fully replace the existing ones */ mergeAttributes: false, }, @@ -192,7 +58,7 @@ export const saveDashboardState = async ({ contentTypeId: DASHBOARD_CONTENT_ID, data: attributes, options: { - references: allReferences, + references, }, }); const newId = result.item.id; @@ -209,12 +75,12 @@ export const saveDashboardState = async ({ */ if (newId !== lastSavedId) { getDashboardBackupService().clearState(lastSavedId); - return { redirectRequired: true, id: newId, references: allReferences }; + return { redirectRequired: true, id: newId, references }; } else { dashboardContentManagementCache.deleteDashboard(newId); // something changed in an existing dashboard, so delete it from the cache so that it can be re-fetched } } - return { id: newId, references: allReferences }; + return { id: newId, references }; } catch (error) { coreServices.notifications.toasts.addDanger({ title: dashboardSaveToastStrings.getFailureString(currentState.title, error.message), diff --git a/src/plugins/dashboard/public/services/dashboard_content_management_service/types.ts b/src/plugins/dashboard/public/services/dashboard_content_management_service/types.ts index e7dbcf1d230db..8be9224259282 100644 --- a/src/plugins/dashboard/public/services/dashboard_content_management_service/types.ts +++ b/src/plugins/dashboard/public/services/dashboard_content_management_service/types.ts @@ -25,6 +25,7 @@ import { DashboardState } from '../../dashboard_api/types'; export interface DashboardContentManagementService { findDashboards: FindDashboardsService; deleteDashboards: (ids: string[]) => Promise; + getDashboardState: (props: GetDashboardStateProps) => Promise; loadDashboardState: (props: { id?: string }) => Promise; saveDashboardState: (props: SaveDashboardProps) => Promise; checkForDuplicateDashboardTitle: (meta: DashboardDuplicateTitleCheckProps) => Promise; @@ -81,6 +82,12 @@ export interface LoadDashboardReturn { */ export type SavedDashboardSaveOpts = SavedObjectSaveOpts & { saveAsCopy?: boolean }; +export interface GetDashboardStateProps { + controlGroupReferences?: Reference[]; + generateNewIds?: boolean; + currentState: DashboardState; + panelReferences?: Reference[]; +} export interface SaveDashboardProps { controlGroupReferences?: Reference[]; currentState: DashboardState; @@ -89,6 +96,11 @@ export interface SaveDashboardProps { lastSavedId?: string; } +export interface GetDashboardStateReturn { + attributes: DashboardAttributes; + references: Reference[]; +} + export interface SaveDashboardReturn { id?: string; error?: string;