mirror of https://github.com/grafana/grafana
Dashboard: Migrating dashboard settings to react (#27561)
* Dashboard: Started migrating dashboard settings * Restore general settings from angular * Use react permissions component * feat(dashboard): add react LinksSettings wrapper for dash-links-editor * feat(dashboard): add react VersionsSettings wrapper for gf-dashboard-history * refactor(dashboard): replace DashboardPermissions connectWithStore with connect * chore(dashboard): folderInfo as undefined * feat(dashboard): initial commit of dashboard settings json editor * feat(dashboard): introduce save json functionality * chore(dashboard): delete obsolete imports * feat(dashboard): add save and save as buttons to settings nav * feat(dashboard): add react wrapper for annotations settings * chore(dashboard): put back canDelete for general settings delete button * Make editable * Remove makeEditable from SettingsCtrl * feat(dashboard): show json editor save button if canSave * refactor(dashboard): move hasUnsavedFolderChange to dashboard.meta * feat(dashboard): render hasUnsavedFolderChange view in permissions settings * feat(dashboard): reset hasUnsavedFolderChange on settingg save success * feat(dashboard): refresh route on sucessful settings save * test(dashboard): update snapshots * refactor(dashboard): automatically infer connected props for dashboard permissions * refactor(dashboard): give dashboard versions checkboxes some padding * Update public/app/types/folders.ts Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com> Co-authored-by: Jack Westbrook <jack.westbrook@gmail.com> Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com>pull/29911/head
parent
0561c941af
commit
d066da42f8
@ -0,0 +1,30 @@ |
||||
import React, { PureComponent } from 'react'; |
||||
import { DashboardModel } from '../../state/DashboardModel'; |
||||
import { AngularComponent, getAngularLoader } from '@grafana/runtime'; |
||||
|
||||
interface Props { |
||||
dashboard: DashboardModel; |
||||
} |
||||
|
||||
export class AnnotationsSettings extends PureComponent<Props> { |
||||
element?: HTMLElement | null; |
||||
angularCmp?: AngularComponent; |
||||
|
||||
componentDidMount() { |
||||
const loader = getAngularLoader(); |
||||
|
||||
const template = '<div ng-include="\'public/app/features/annotations/partials/editor.html\'" />'; |
||||
const scopeProps = { dashboard: this.props.dashboard }; |
||||
this.angularCmp = loader.load(this.element, scopeProps, template); |
||||
} |
||||
|
||||
componentWillUnmount() { |
||||
if (this.angularCmp) { |
||||
this.angularCmp.destroy(); |
||||
} |
||||
} |
||||
|
||||
render() { |
||||
return <div ref={ref => (this.element = ref)} />; |
||||
} |
||||
} |
@ -0,0 +1,30 @@ |
||||
import React, { PureComponent } from 'react'; |
||||
import { DashboardModel } from '../../state/DashboardModel'; |
||||
import { AngularComponent, getAngularLoader } from '@grafana/runtime'; |
||||
|
||||
interface Props { |
||||
dashboard: DashboardModel; |
||||
} |
||||
|
||||
export class GeneralSettings extends PureComponent<Props> { |
||||
element?: HTMLElement | null; |
||||
angularCmp?: AngularComponent; |
||||
|
||||
componentDidMount() { |
||||
const loader = getAngularLoader(); |
||||
|
||||
const template = '<dashboard-settings dashboard="dashboard" />'; |
||||
const scopeProps = { dashboard: this.props.dashboard }; |
||||
this.angularCmp = loader.load(this.element, scopeProps, template); |
||||
} |
||||
|
||||
componentWillUnmount() { |
||||
if (this.angularCmp) { |
||||
this.angularCmp.destroy(); |
||||
} |
||||
} |
||||
|
||||
render() { |
||||
return <div ref={ref => (this.element = ref)} />; |
||||
} |
||||
} |
@ -0,0 +1,54 @@ |
||||
import React, { useState } from 'react'; |
||||
import AutoSizer from 'react-virtualized-auto-sizer'; |
||||
import { Button, CodeEditor } from '@grafana/ui'; |
||||
import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher'; |
||||
import { getDashboardSrv } from '../../services/DashboardSrv'; |
||||
import { DashboardModel } from '../../state/DashboardModel'; |
||||
|
||||
interface Props { |
||||
dashboard: DashboardModel; |
||||
} |
||||
|
||||
export const JsonEditorSettings: React.FC<Props> = ({ dashboard }) => { |
||||
const [dashboardJson, setDashboardJson] = useState<string>(JSON.stringify(dashboard.getSaveModelClone(), null, 2)); |
||||
const onBlur = (value: string) => { |
||||
setDashboardJson(value); |
||||
}; |
||||
const onClick = () => { |
||||
getDashboardSrv() |
||||
.saveJSONDashboard(dashboardJson) |
||||
.then(() => { |
||||
dashboardWatcher.reloadPage(); |
||||
}); |
||||
}; |
||||
|
||||
return ( |
||||
<> |
||||
<h3 className="dashboard-settings__header">JSON Model</h3> |
||||
<div className="dashboard-settings__subheader"> |
||||
The JSON Model below is data structure that defines the dashboard. Including settings, panel settings & layout, |
||||
queries etc. |
||||
</div> |
||||
|
||||
<div> |
||||
<AutoSizer disableHeight> |
||||
{({ width }) => ( |
||||
<CodeEditor |
||||
value={dashboardJson} |
||||
language="json" |
||||
width={width} |
||||
height="500px" |
||||
showMiniMap={false} |
||||
onBlur={onBlur} |
||||
/> |
||||
)} |
||||
</AutoSizer> |
||||
</div> |
||||
{dashboard.meta.canSave && ( |
||||
<Button className="m-t-3" onClick={onClick}> |
||||
Save Changes |
||||
</Button> |
||||
)} |
||||
</> |
||||
); |
||||
}; |
@ -0,0 +1,30 @@ |
||||
import React, { PureComponent } from 'react'; |
||||
import { DashboardModel } from '../../state/DashboardModel'; |
||||
import { AngularComponent, getAngularLoader } from '@grafana/runtime'; |
||||
|
||||
interface Props { |
||||
dashboard: DashboardModel; |
||||
} |
||||
|
||||
export class LinksSettings extends PureComponent<Props> { |
||||
element?: HTMLElement | null; |
||||
angularCmp?: AngularComponent; |
||||
|
||||
componentDidMount() { |
||||
const loader = getAngularLoader(); |
||||
|
||||
const template = '<dash-links-editor dashboard="dashboard" />'; |
||||
const scopeProps = { dashboard: this.props.dashboard }; |
||||
this.angularCmp = loader.load(this.element, scopeProps, template); |
||||
} |
||||
|
||||
componentWillUnmount() { |
||||
if (this.angularCmp) { |
||||
this.angularCmp.destroy(); |
||||
} |
||||
} |
||||
|
||||
render() { |
||||
return <div ref={ref => (this.element = ref)} />; |
||||
} |
||||
} |
@ -0,0 +1,30 @@ |
||||
import React, { PureComponent } from 'react'; |
||||
import { DashboardModel } from '../../state/DashboardModel'; |
||||
import { AngularComponent, getAngularLoader } from '@grafana/runtime'; |
||||
|
||||
interface Props { |
||||
dashboard: DashboardModel; |
||||
} |
||||
|
||||
export class VersionsSettings extends PureComponent<Props> { |
||||
element?: HTMLElement | null; |
||||
angularCmp?: AngularComponent; |
||||
|
||||
componentDidMount() { |
||||
const loader = getAngularLoader(); |
||||
|
||||
const template = '<gf-dashboard-history dashboard="dashboard" />'; |
||||
const scopeProps = { dashboard: this.props.dashboard }; |
||||
this.angularCmp = loader.load(this.element, scopeProps, template); |
||||
} |
||||
|
||||
componentWillUnmount() { |
||||
if (this.angularCmp) { |
||||
this.angularCmp.destroy(); |
||||
} |
||||
} |
||||
|
||||
render() { |
||||
return <div ref={ref => (this.element = ref)} />; |
||||
} |
||||
} |
Loading…
Reference in new issue