import saveAs from 'file-saver'; import { useAsync } from 'react-use'; import AutoSizer from 'react-virtualized-auto-sizer'; import { SceneComponentProps, SceneObjectBase } from '@grafana/scenes'; import { Button, ClipboardButton, CodeEditor, Field, Modal, Stack, Switch } from '@grafana/ui'; import { t, Trans } from 'app/core/internationalization'; import { DashboardExporter } from 'app/features/dashboard/components/DashExportModal'; import { shareDashboardType } from 'app/features/dashboard/components/ShareModal/utils'; import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; import { transformSceneToSaveModel } from '../serialization/transformSceneToSaveModel'; import { getVariablesCompatibility } from '../utils/getVariablesCompatibility'; import { DashboardInteractions } from '../utils/interactions'; import { getDashboardSceneFor } from '../utils/utils'; import { SceneShareTabState, ShareView } from './types'; export interface ShareExportTabState extends SceneShareTabState { isSharingExternally?: boolean; isViewingJSON?: boolean; } export class ShareExportTab extends SceneObjectBase implements ShareView { public tabId = shareDashboardType.export; static Component = ShareExportTabRenderer; private _exporter = new DashboardExporter(); constructor(state: Omit) { super({ isSharingExternally: false, isViewingJSON: false, ...state, }); } public getTabLabel() { return t('share-modal.tab-title.export', 'Export'); } public onShareExternallyChange = () => { this.setState({ isSharingExternally: !this.state.isSharingExternally, }); }; public onViewJSON = () => { this.setState({ isViewingJSON: !this.state.isViewingJSON, }); }; public getClipboardText() { return; } public getExportableDashboardJson = async () => { const { isSharingExternally } = this.state; const saveModel = transformSceneToSaveModel(getDashboardSceneFor(this)); const exportable = isSharingExternally ? await this._exporter.makeExportable( new DashboardModel(saveModel, undefined, { getVariablesFromState: () => { return getVariablesCompatibility(window.__grafanaSceneContext); }, }) ) : saveModel; return exportable; }; public onSaveAsFile = async () => { const dashboardJson = await this.getExportableDashboardJson(); const dashboardJsonPretty = JSON.stringify(dashboardJson, null, 2); const { isSharingExternally } = this.state; const blob = new Blob([dashboardJsonPretty], { type: 'application/json;charset=utf-8', }); const time = new Date().getTime(); let title = 'dashboard'; if ('title' in dashboardJson && dashboardJson.title) { title = dashboardJson.title; } saveAs(blob, `${title}-${time}.json`); DashboardInteractions.exportDownloadJsonClicked({ externally: isSharingExternally, }); }; } function ShareExportTabRenderer({ model }: SceneComponentProps) { const { isSharingExternally, isViewingJSON, modalRef } = model.useState(); const dashboardJson = useAsync(async () => { if (isViewingJSON) { const json = await model.getExportableDashboardJson(); return JSON.stringify(json, null, 2); } return ''; }, [isViewingJSON]); const exportExternallyTranslation = t('share-modal.export.share-externally-label', `Export for sharing externally`); return ( <> {!isViewingJSON && ( <>

Export this dashboard.

)} {isViewingJSON && ( <> {({ width }) => { if (dashboardJson.value) { return ( ); } if (dashboardJson.loading) { return (
{' '} Loading...
); } return null; }}
dashboardJson.value ?? ''} > Copy to Clipboard )} ); }