// Libraries import React, { PureComponent } from 'react'; import { connect, MapStateToProps, MapDispatchToProps } from 'react-redux'; // Utils and services import { AngularComponent, getAngularLoader } from '@grafana/runtime'; // Types import { PanelModel, DashboardModel } from '../../state'; import { PanelPlugin, PanelPluginMeta } from '@grafana/data'; import { changePanelPlugin } from '../../state/actions'; import { StoreState } from 'app/types'; import { getSectionOpenState, saveSectionOpenState } from './state/utils'; import { PanelCtrl } from 'app/features/panel/panel_ctrl'; interface OwnProps { panel: PanelModel; dashboard: DashboardModel; plugin: PanelPlugin; } interface ConnectedProps { angularPanelComponent?: AngularComponent | null; } interface DispatchProps { changePanelPlugin: typeof changePanelPlugin; } type Props = OwnProps & ConnectedProps & DispatchProps; export class AngularPanelOptionsUnconnected extends PureComponent { element?: HTMLElement | null; angularOptions?: AngularComponent | null; constructor(props: Props) { super(props); } componentDidMount() { this.loadAngularOptions(); } componentDidUpdate(prevProps: Props) { if (this.props.plugin !== prevProps.plugin) { this.cleanUpAngularOptions(); } this.loadAngularOptions(); } componentWillUnmount() { this.cleanUpAngularOptions(); } cleanUpAngularOptions() { if (this.angularOptions) { this.angularOptions.destroy(); this.angularOptions = null; } } loadAngularOptions() { const { panel, angularPanelComponent, changePanelPlugin } = this.props; if (!this.element || !angularPanelComponent || this.angularOptions) { return; } const scope = angularPanelComponent.getScope(); // When full page reloading in edit mode the angular panel has on fully compiled and instantiated yet if (!scope.$$childHead) { setTimeout(() => { this.forceUpdate(); }); return; } const panelCtrl: PanelCtrl = scope.$$childHead.ctrl; panelCtrl.initEditMode(); panelCtrl.onPluginTypeChange = (plugin: PanelPluginMeta) => { changePanelPlugin(panel, plugin.id); }; let template = ''; for (let i = 0; i < panelCtrl.editorTabs.length; i++) { const tab = panelCtrl.editorTabs[i]; tab.isOpen = getSectionOpenState(tab.title, i === 0); template += `
${tab.title}
`; } const loader = getAngularLoader(); const scopeProps = { ctrl: panelCtrl, toggleOptionGroup: (index: number) => { const tab = panelCtrl.editorTabs[index]; tab.isOpen = !tab.isOpen; saveSectionOpenState(tab.title, tab.isOpen as boolean); }, }; this.angularOptions = loader.load(this.element, scopeProps, template); this.angularOptions.digest(); } render() { return
(this.element = elem)} />; } } const mapStateToProps: MapStateToProps = (state, props) => { return { angularPanelComponent: state.dashboard.panels[props.panel.id].angularComponent, }; }; const mapDispatchToProps: MapDispatchToProps = { changePanelPlugin }; export const AngularPanelOptions = connect(mapStateToProps, mapDispatchToProps)(AngularPanelOptionsUnconnected);