1import React, { useState } from 'react';
2import { css } from '@emotion/css';
3import AutoSizer from 'react-virtualized-auto-sizer';
4import { Button, CodeEditor, HorizontalGroup, useStyles2 } from '@grafana/ui';
5import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher';
6import { getDashboardSrv } from '../../services/DashboardSrv';
7import { DashboardModel } from '../../state/DashboardModel';
8import { GrafanaTheme2 } from '@grafana/data';
9
10interface Props {
11  dashboard: DashboardModel;
12}
13
14export const JsonEditorSettings: React.FC<Props> = ({ dashboard }) => {
15  const [dashboardJson, setDashboardJson] = useState<string>(JSON.stringify(dashboard.getSaveModelClone(), null, 2));
16  const onBlur = (value: string) => {
17    setDashboardJson(value);
18  };
19  const onClick = () => {
20    getDashboardSrv()
21      .saveJSONDashboard(dashboardJson)
22      .then(() => {
23        dashboardWatcher.reloadPage();
24      });
25  };
26  const styles = useStyles2(getStyles);
27
28  return (
29    <div>
30      <h3 className="dashboard-settings__header">JSON Model</h3>
31      <div className="dashboard-settings__subheader">
32        The JSON model below is the data structure that defines the dashboard. This includes dashboard settings, panel
33        settings, layout, queries, and so on.
34      </div>
35
36      <div className={styles.editWrapper}>
37        <AutoSizer>
38          {({ width, height }) => (
39            <CodeEditor
40              value={dashboardJson}
41              language="json"
42              width={width}
43              height={height}
44              showMiniMap={true}
45              showLineNumbers={true}
46              onBlur={onBlur}
47            />
48          )}
49        </AutoSizer>
50      </div>
51      {dashboard.meta.canSave && (
52        <HorizontalGroup>
53          <Button onClick={onClick}>Save changes</Button>
54        </HorizontalGroup>
55      )}
56    </div>
57  );
58};
59
60const getStyles = (theme: GrafanaTheme2) => ({
61  editWrapper: css`
62    height: calc(100vh - 250px);
63    margin-bottom: 10px;
64  `,
65});
66