Files
grafana/public/app/features/dashboard/dashgrid/VisualizationTab.tsx

185 lines
4.6 KiB
TypeScript
Raw Normal View History

// Libraries
import React, { PureComponent } from 'react';
// Utils & Services
import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader';
// Components
import { EditorTabBody } from './EditorTabBody';
import { VizTypePicker } from './VizTypePicker';
// Types
import { PanelModel } from '../panel_model';
import { DashboardModel } from '../dashboard_model';
2018-11-10 17:27:25 +01:00
import { PanelPlugin } from 'app/types/plugins';
interface Props {
panel: PanelModel;
dashboard: DashboardModel;
2018-11-10 17:27:25 +01:00
plugin: PanelPlugin;
angularPanel?: AngularComponent;
onTypeChanged: (newType: PanelPlugin) => void;
}
2018-12-12 09:51:17 +01:00
interface State {
isVizPickerOpen: boolean;
searchQuery: string;
}
export class VisualizationTab extends PureComponent<Props, State> {
element: HTMLElement;
angularOptions: AngularComponent;
2018-12-12 09:51:17 +01:00
searchInput: HTMLElement;
constructor(props) {
super(props);
this.state = {
isVizPickerOpen: false,
};
}
2018-12-03 15:02:41 +01:00
getPanelDefaultOptions = () => {
2018-12-03 13:33:17 +01:00
const { panel, plugin } = this.props;
if (plugin.exports.PanelDefaults) {
return panel.getOptions(plugin.exports.PanelDefaults.options);
}
return panel.getOptions(plugin.exports.PanelDefaults);
2018-12-03 15:02:41 +01:00
};
2018-12-03 13:33:17 +01:00
renderPanelOptions() {
const { plugin, angularPanel } = this.props;
2018-11-13 08:40:42 +01:00
const { PanelOptions } = plugin.exports;
if (angularPanel) {
return <div ref={element => (this.element = element)} />;
}
2018-11-13 08:40:42 +01:00
if (PanelOptions) {
2018-12-03 13:33:17 +01:00
return <PanelOptions options={this.getPanelDefaultOptions()} onChange={this.onPanelOptionsChanged} />;
} else {
return <p>Visualization has no options</p>;
}
}
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;
let template = '';
for (let i = 0; i < panelCtrl.editorTabs.length; i++) {
2018-12-11 10:33:09 +01:00
template +=
`
<div class="form-section" ng-cloak>` +
(i > 0 ? `<div class="form-section__header">{{ctrl.editorTabs[${i}].title}}</div>` : '') +
`<div class="form-section__body">
2018-11-20 11:06:36 +01:00
<panel-editor-tab editor-tab="ctrl.editorTabs[${i}]" ctrl="ctrl"></panel-editor-tab>
</div>
</div>
`;
}
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;
}
}
onPanelOptionsChanged = (options: any) => {
this.props.panel.updateOptions(options);
this.forceUpdate();
};
2018-12-12 09:51:17 +01:00
onOpenVizPicker = () => {
this.setState({ isVizPickerOpen: true });
};
renderToolbar = () => {
const { plugin } = this.props;
2018-12-12 09:51:17 +01:00
if (this.state.isVizPickerOpen) {
return (
<label className="gf-form--has-input-icon">
<input
type="text"
className="gf-form-input width-13"
placeholder=""
ref={elem => (this.searchInput = elem)}
/>
<i className="gf-form-input-icon fa fa-search" />
</label>
);
} else {
return (
<div className="toolbar__main" onClick={this.onOpenVizPicker}>
<img className="toolbar__main-image" src={plugin.info.logos.small} />
<div className="toolbar__main-name">{plugin.name}</div>
<i className="fa fa-caret-down" />
</div>
);
}
};
render() {
const { plugin, onTypeChanged } = this.props;
const { isVizPickerOpen } = this.state;
2018-11-22 11:41:33 +01:00
const panelHelp = {
title: '',
icon: 'fa fa-question',
render: () => <h2>Help</h2>,
};
return (
2018-12-12 09:51:17 +01:00
<EditorTabBody heading="Visualization" renderToolbar={this.renderToolbar} toolbarItems={[panelHelp]}>
{isVizPickerOpen && <VizTypePicker current={plugin} onTypeChanged={onTypeChanged} />}
{this.renderPanelOptions()}
</EditorTabBody>
);
}
}