SaveDashboard: Allow editing provisioned dashboard JSON and add confirmation when JSON is copied to dashboard (#24680)

This commit is contained in:
Dominik Prokop 2020-05-14 13:45:26 +02:00 committed by GitHub
parent 660f2b4e99
commit cfac591234
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 28 deletions

View File

@ -20,6 +20,17 @@ export class CopyToClipboard extends PureComponent<Props> {
} }
componentDidMount() { componentDidMount() {
this.initClipboardJS();
}
componentDidUpdate() {
if (this.clipboardjs) {
this.clipboardjs.destroy();
}
this.initClipboardJS();
}
initClipboardJS = () => {
const { text, onSuccess, onError } = this.props; const { text, onSuccess, onError } = this.props;
this.clipboardjs = new ClipboardJS(this.myRef.current, { this.clipboardjs = new ClipboardJS(this.myRef.current, {
@ -40,7 +51,7 @@ export class CopyToClipboard extends PureComponent<Props> {
onError(evt); onError(evt);
}); });
} }
} };
componentWillUnmount() { componentWillUnmount() {
if (this.clipboardjs) { if (this.clipboardjs) {

View File

@ -1,37 +1,31 @@
import React, { useCallback, useMemo } from 'react'; import React, { useCallback, useState } from 'react';
import { css } from 'emotion'; import { css } from 'emotion';
import { saveAs } from 'file-saver'; import { saveAs } from 'file-saver';
import { import { Button, HorizontalGroup, stylesFactory, TextArea, useTheme, VerticalGroup } from '@grafana/ui';
CustomScrollbar,
Button,
HorizontalGroup,
JSONFormatter,
VerticalGroup,
useTheme,
stylesFactory,
} from '@grafana/ui';
import { CopyToClipboard } from 'app/core/components/CopyToClipboard/CopyToClipboard'; import { CopyToClipboard } from 'app/core/components/CopyToClipboard/CopyToClipboard';
import { SaveDashboardFormProps } from '../types'; import { SaveDashboardFormProps } from '../types';
import { GrafanaTheme } from '@grafana/data'; import { AppEvents, GrafanaTheme } from '@grafana/data';
import appEvents from '../../../../../core/app_events';
export const SaveProvisionedDashboardForm: React.FC<SaveDashboardFormProps> = ({ dashboard, onCancel }) => { export const SaveProvisionedDashboardForm: React.FC<SaveDashboardFormProps> = ({ dashboard, onCancel }) => {
const theme = useTheme(); const theme = useTheme();
const dashboardJSON = useMemo(() => { const [dashboardJSON, setDashboardJson] = useState(() => {
const clone = dashboard.getSaveModelClone(); const clone = dashboard.getSaveModelClone();
delete clone.id; delete clone.id;
return clone; return JSON.stringify(clone, null, 2);
}, [dashboard]); });
const getClipboardText = useCallback(() => {
return JSON.stringify(dashboardJSON, null, 2);
}, [dashboard]);
const saveToFile = useCallback(() => { const saveToFile = useCallback(() => {
const blob = new Blob([JSON.stringify(dashboardJSON, null, 2)], { const blob = new Blob([dashboardJSON], {
type: 'application/json;charset=utf-8', type: 'application/json;charset=utf-8',
}); });
saveAs(blob, dashboard.title + '-' + new Date().getTime() + '.json'); saveAs(blob, dashboard.title + '-' + new Date().getTime() + '.json');
}, [dashboardJSON]); }, [dashboardJSON]);
const onCopyToClipboardSuccess = useCallback(() => {
appEvents.emit(AppEvents.alertSuccess, ['Dashboard JSON copied to clipboard']);
}, []);
const styles = getStyles(theme); const styles = getStyles(theme);
return ( return (
<> <>
@ -55,13 +49,16 @@ export const SaveProvisionedDashboardForm: React.FC<SaveDashboardFormProps> = ({
<div> <div>
<strong>File path: </strong> {dashboard.meta.provisionedExternalId} <strong>File path: </strong> {dashboard.meta.provisionedExternalId}
</div> </div>
<div className={styles.json}> <TextArea
<CustomScrollbar> spellCheck={false}
<JSONFormatter json={dashboardJSON} open={1} /> value={dashboardJSON}
</CustomScrollbar> onChange={e => {
</div> setDashboardJson(e.currentTarget.value);
}}
className={styles.json}
/>
<HorizontalGroup> <HorizontalGroup>
<CopyToClipboard text={getClipboardText} elType={Button}> <CopyToClipboard text={() => dashboardJSON} elType={Button} onSuccess={onCopyToClipboardSuccess}>
Copy JSON to clipboard Copy JSON to clipboard
</CopyToClipboard> </CopyToClipboard>
<Button onClick={saveToFile}>Save JSON to file</Button> <Button onClick={saveToFile}>Save JSON to file</Button>
@ -77,10 +74,11 @@ export const SaveProvisionedDashboardForm: React.FC<SaveDashboardFormProps> = ({
const getStyles = stylesFactory((theme: GrafanaTheme) => { const getStyles = stylesFactory((theme: GrafanaTheme) => {
return { return {
json: css` json: css`
background: ${theme.isLight ? theme.palette.gray7 : theme.palette.black};
padding: ${theme.spacing.sm} 0 ${theme.spacing.sm} ${theme.spacing.md};
height: 400px; height: 400px;
width: 100%; width: 100%;
overflow: auto;
resize: none;
font-family: monospace;
`, `,
}; };
}); });