Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 };
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Props, State> {
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 (
<>
<EuiFlyoutHeader hasBorder>
<EuiTitle size="m">
<h2>
<FormattedMessage
id="dashboard.embeddableApi.showSource.flyout.title"
defaultMessage="Show Source"
/>
</h2>
</EuiTitle>
</EuiFlyoutHeader>
<EuiFlyoutBody>{dashboardCode}</EuiFlyoutBody>
<EuiFlyoutFooter>
<EuiFlexGroup justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<EuiButtonEmpty
flush="left"
data-test-subj="cancelShowSourceButton"
onClick={this.props.onClose}
>
<FormattedMessage
id="dashboard.embeddableApi.showSource.flyout.cancelButtonTitle"
defaultMessage="Cancel"
/>
</EuiButtonEmpty>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlyoutFooter>
</>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ export async function runQuickSave(this: DashboardContainer) {
this.setLastSavedInput(dashboardStateToSave);
this.saveNotification$.next();

console.log('save result', saveResult);

return saveResult;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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';
Expand Down Expand Up @@ -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[];
Expand Down Expand Up @@ -966,4 +970,28 @@ export class DashboardContainer
}
if (resetChangedPanelCount) this.children$.next(currentChildren);
};

public showSource() {
const flyout = coreServices.overlays.openFlyout(
toMountPoint(
<ShowSourceFlyout
onClose={() => {
this.clearOverlays();
}}
dashboardApi={this}
/>,
coreServices
),
{
size: 'm',
'data-test-subj': 'dashboardShowSourceFlyout',
onClose: (flyout) => {
this.clearOverlays();
flyout.close();
},
}
);

this.openOverlay(flyout);
}
}