// Libraries import React, { PureComponent } from 'react'; // Utils & Services import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader'; import { connectWithStore } from 'app/core/utils/connectWithReduxStore'; import { StoreState } from 'app/types'; import { updateLocation } from 'app/core/actions'; // Components import { EditorTabBody, EditorToolbarView } from './EditorTabBody'; import { VizTypePicker } from './VizTypePicker'; import { PluginHelp } from 'app/core/components/PluginHelp/PluginHelp'; import { FadeIn } from 'app/core/components/Animations/FadeIn'; // Types import { PanelModel } from '../state'; import { DashboardModel } from '../state'; import { VizPickerSearch } from './VizPickerSearch'; import PluginStateinfo from 'app/features/plugins/PluginStateInfo'; import { PanelPluginMeta } from '@grafana/ui'; interface Props { panel: PanelModel; dashboard: DashboardModel; plugin: PanelPluginMeta; angularPanel?: AngularComponent; onTypeChanged: (newType: PanelPluginMeta) => void; updateLocation: typeof updateLocation; urlOpenVizPicker: boolean; } interface State { isVizPickerOpen: boolean; searchQuery: string; scrollTop: number; hasBeenFocused: boolean; } export class VisualizationTab extends PureComponent { element: HTMLElement; angularOptions: AngularComponent; constructor(props) { super(props); this.state = { isVizPickerOpen: this.props.urlOpenVizPicker, hasBeenFocused: false, searchQuery: '', scrollTop: 0, }; } getReactPanelOptions = () => { const { panel, plugin } = this.props; return panel.getOptions(plugin.panelPlugin.defaults); }; renderPanelOptions() { const { plugin, angularPanel } = this.props; if (angularPanel) { return
(this.element = element)} />; } if (plugin.panelPlugin) { const PanelEditor = plugin.panelPlugin.editor; if (PanelEditor) { return ; } } return

Visualization has no options

; } componentDidMount() { if (this.shouldLoadAngularOptions()) { this.loadAngularOptions(); } } componentDidUpdate(prevProps: Props) { if (this.props.plugin !== prevProps.plugin) { this.cleanUpAngularOptions(); } if (this.shouldLoadAngularOptions()) { this.loadAngularOptions(); } } shouldLoadAngularOptions() { return this.props.angularPanel && this.element && !this.angularOptions; } loadAngularOptions() { const { angularPanel } = this.props; const scope = angularPanel.getScope(); // When full page reloading in edit mode the angular panel has on fully compiled & instantiated yet if (!scope.$$childHead) { setTimeout(() => { this.forceUpdate(); }); return; } const panelCtrl = scope.$$childHead.ctrl; panelCtrl.initEditMode(); let template = ''; for (let i = 0; i < panelCtrl.editorTabs.length; i++) { template += `
` + (i > 0 ? `
{{ctrl.editorTabs[${i}].title}}
` : '') + `
`; } const loader = getAngularLoader(); const scopeProps = { ctrl: panelCtrl }; this.angularOptions = loader.load(this.element, scopeProps, template); } componentWillUnmount() { this.cleanUpAngularOptions(); } cleanUpAngularOptions() { if (this.angularOptions) { this.angularOptions.destroy(); this.angularOptions = null; } } clearQuery = () => { this.setState({ searchQuery: '' }); }; onPanelOptionsChanged = (options: any) => { this.props.panel.updateOptions(options); this.forceUpdate(); }; onOpenVizPicker = () => { this.setState({ isVizPickerOpen: true, scrollTop: 0 }); }; onCloseVizPicker = () => { if (this.props.urlOpenVizPicker) { this.props.updateLocation({ query: { openVizPicker: null }, partial: true }); } this.setState({ isVizPickerOpen: false, hasBeenFocused: false }); }; onSearchQueryChange = (value: string) => { this.setState({ searchQuery: value, }); }; renderToolbar = (): JSX.Element => { const { plugin } = this.props; const { isVizPickerOpen, searchQuery } = this.state; if (isVizPickerOpen) { return ( ); } else { return (
{plugin.name}
); } }; onTypeChanged = (plugin: PanelPluginMeta) => { if (plugin.id === this.props.plugin.id) { this.setState({ isVizPickerOpen: false }); } else { this.props.onTypeChanged(plugin); } }; renderHelp = () => ; setScrollTop = (event: React.MouseEvent) => { const target = event.target as HTMLElement; this.setState({ scrollTop: target.scrollTop }); }; render() { const { plugin } = this.props; const { isVizPickerOpen, searchQuery, scrollTop } = this.state; const pluginHelp: EditorToolbarView = { heading: 'Help', icon: 'fa fa-question', render: this.renderHelp, }; return ( <> {this.renderPanelOptions()} ); } } const mapStateToProps = (state: StoreState) => ({ urlOpenVizPicker: !!state.location.query.openVizPicker, }); const mapDispatchToProps = { updateLocation, }; export default connectWithStore(VisualizationTab, mapStateToProps, mapDispatchToProps);