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