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..bad56a433502c 100644 --- a/src/plugins/dashboard/public/dashboard_app/_dashboard_app_strings.ts +++ b/src/plugins/dashboard/public/dashboard_app/_dashboard_app_strings.ts @@ -223,6 +223,14 @@ export const topNavStrings = { defaultMessage: 'Open dashboard settings', }), }, + showSource: { + label: i18n.translate('dashboard.topNave.showSourceAreaLabel', { + defaultMessage: 'Show Source', + }), + description: i18n.translate('dashboard.topNave.showSourceDescription', { + defaultMessage: 'Show dashboard source', + }), + }, viewModeInteractiveSave: { label: i18n.translate('dashboard.topNave.viewModeInteractiveSaveButtonAriaLabel', { defaultMessage: 'duplicate', 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 ca58d3c74bd3f..46be27abed6b9 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 @@ -14,6 +14,7 @@ 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 { UI_SETTINGS } from '../../../common'; import { useDashboardApi } from '../../dashboard_api/use_dashboard_api'; @@ -27,6 +28,8 @@ import { getDashboardCapabilities } from '../../utils/get_dashboard_capabilities import { topNavStrings } from '../_dashboard_app_strings'; import { ShowShareModal } from './share/show_share_modal'; + + export const useDashboardMenuItems = ({ isLabsShown, setIsLabsShown, @@ -221,6 +224,16 @@ export const useDashboardMenuItems = ({ disableButton: disableTopNav, run: () => openSettingsFlyout(dashboardApi), }, + + showSource: { + ...topNavStrings.showSource, + id: 'showSource', + testId: 'dashboardShowSourceButton', + disableButton: disableTopNav, + run: () => { + dashboardApi.showSource(); + }, + }, }; }, [ disableTopNav, @@ -302,7 +315,13 @@ export const useDashboardMenuItems = ({ } else { editModeItems.push(menuItems.switchToViewMode, menuItems.interactiveSave); } - return [...labsMenuItem, menuItems.settings, ...shareMenuItem, ...editModeItems]; + return [ + ...labsMenuItem, + menuItems.settings, + menuItems.showSource, + ...shareMenuItem, + ...editModeItems, + ]; }, [isLabsEnabled, menuItems, lastSavedId, showResetChange, resetChangesMenuItem]); return { viewModeTopNavConfig, editModeTopNavConfig }; diff --git a/src/plugins/dashboard/public/dashboard_container/component/showsource/show_source_flyout.tsx b/src/plugins/dashboard/public/dashboard_container/component/showsource/show_source_flyout.tsx new file mode 100644 index 0000000000000..8d00abfa138e9 --- /dev/null +++ b/src/plugins/dashboard/public/dashboard_container/component/showsource/show_source_flyout.tsx @@ -0,0 +1,84 @@ +/* + * 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 from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { + EuiFormRow, + EuiFieldText, + EuiTextArea, + EuiForm, + EuiButton, + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiFlyoutHeader, + EuiTitle, +} from '@elastic/eui'; + +import type { DashboardContainer } from '../../embeddable/dashboard_container'; + +interface Props { + onClose: () => void; + dashboardApi: DashboardContainer; +} + +interface State {} + +export class ShowSourceFlyout extends React.Component { + private _isMounted = false; + state: State = {}; + + componentDidMount() { + this._isMounted = true; + } + + componentWillUnmount() { + this._isMounted = false; + } + + render() { + const dashboardCode = 'Should get dashboard-json here from props.dashboardApi object'; + + return ( + <> + + +

+ +

+
+
+ {dashboardCode} + + + + + + + + + + + ); + } +} diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/api/run_save_functions.tsx b/src/plugins/dashboard/public/dashboard_container/embeddable/api/run_save_functions.tsx index e5355bdb2988c..123a4078657c9 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/api/run_save_functions.tsx +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/api/run_save_functions.tsx @@ -115,6 +115,8 @@ export async function runQuickSave(this: DashboardContainer) { this.setLastSavedInput(dashboardStateToSave); this.saveNotification$.next(); + console.log('save result', saveResult); + return saveResult; } 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..df28598ae2b2e 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx @@ -11,6 +11,7 @@ import deepEqual from 'fast-deep-equal'; import { omit } from 'lodash'; import React from 'react'; import ReactDOM from 'react-dom'; + import { BehaviorSubject, Subject, @@ -68,6 +69,8 @@ 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 { core } from '@kbn/embeddable-plugin/public/kibana_services'; +import { toMountPoint } from '@kbn/react-kibana-mount'; import { DASHBOARD_CONTAINER_TYPE, DashboardApi, DashboardLocatorParams } from '../..'; import type { DashboardAttributes } from '../../../server/content_management'; import { DashboardContainerInput, DashboardPanelMap, DashboardPanelState } from '../../../common'; @@ -113,6 +116,7 @@ import { } from './dashboard_container_factory'; import { InitialComponentState, getDashboardApi } from '../../dashboard_api/get_dashboard_api'; import type { DashboardCreationOptions } from '../..'; +import { ShowSourceFlyout } from '../component/showsource/show_source_flyout'; export interface InheritedChildInput { filters: Filter[]; @@ -966,4 +970,28 @@ export class DashboardContainer } if (resetChangedPanelCount) this.children$.next(currentChildren); }; + + public showSource() { + const flyout = coreServices.overlays.openFlyout( + toMountPoint( + { + this.clearOverlays(); + }} + dashboardApi={this} + />, + coreServices + ), + { + size: 'm', + 'data-test-subj': 'dashboardShowSourceFlyout', + onClose: (flyout) => { + this.clearOverlays(); + flyout.close(); + }, + } + ); + + this.openOverlay(flyout); + } }