poc: handling panel edit mode in react even for angular panels poc

This commit is contained in:
Torkel Ödegaard
2018-11-15 09:46:21 +01:00
parent 487fd12d66
commit 911646f913
6 changed files with 103 additions and 84 deletions

View File

@@ -23,11 +23,11 @@ export interface Props {
export interface State {
plugin: PanelPlugin;
angularPanel: AngularComponent;
}
export class DashboardPanel extends PureComponent<Props, State> {
element: any;
angularPanel: AngularComponent;
element: HTMLElement;
specialPanels = {};
constructor(props) {
@@ -35,6 +35,7 @@ export class DashboardPanel extends PureComponent<Props, State> {
this.state = {
plugin: null,
angularPanel: null,
};
this.specialPanels['row'] = this.renderRow.bind(this);
@@ -96,25 +97,30 @@ export class DashboardPanel extends PureComponent<Props, State> {
this.loadPlugin();
// handle angular plugin loading
if (!this.element || this.angularPanel) {
if (!this.element || this.state.angularPanel) {
return;
}
const loader = getAngularLoader();
const template = '<plugin-component type="panel" class="panel-height-helper"></plugin-component>';
const scopeProps = { panel: this.props.panel, dashboard: this.props.dashboard };
this.angularPanel = loader.load(this.element, scopeProps, template);
const angularPanel = loader.load(this.element, scopeProps, template);
this.setState({ angularPanel });
}
cleanUpAngularPanel() {
if (this.angularPanel) {
this.angularPanel.destroy();
this.angularPanel = null;
cleanUpAngularPanel(unmounted?: boolean) {
if (this.state.angularPanel) {
this.state.angularPanel.destroy();
if (!unmounted) {
this.setState({ angularPanel: null });
}
}
}
componentWillUnmount() {
this.cleanUpAngularPanel();
this.cleanUpAngularPanel(true);
}
onMouseEnter = () => {
@@ -129,25 +135,16 @@ export class DashboardPanel extends PureComponent<Props, State> {
const { dashboard, panel } = this.props;
const { plugin } = this.state;
const containerClass = this.props.isEditing ? 'panel-editor-container' : 'panel-height-helper';
const panelWrapperClass = this.props.isEditing ? 'panel-editor-container__panel' : 'panel-height-helper';
// this might look strange with these classes that change when edit, but
// I want to try to keep markup (parents) for panel the same in edit mode to avoide unmount / new mount of panel
return (
<div className={containerClass}>
<div className={panelWrapperClass} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
<PanelChrome component={plugin.exports.Panel} panel={panel} dashboard={dashboard} />
</div>
{panel.isEditing && (
<PanelEditor panel={panel} plugin={plugin} dashboard={dashboard} onTypeChanged={this.onPluginTypeChanged} />
)}
</div>
);
return <PanelChrome component={plugin.exports.Panel} panel={panel} dashboard={dashboard} />;
}
renderAngularPanel() {
return <div ref={element => (this.element = element)} className="panel-height-helper" />;
}
render() {
const { panel } = this.props;
const { plugin } = this.state;
const { panel, dashboard } = this.props;
const { plugin, angularPanel } = this.state;
if (this.isSpecial()) {
return this.specialPanels[panel.type]();
@@ -158,19 +155,27 @@ export class DashboardPanel extends PureComponent<Props, State> {
return null;
}
// if exporting PanelComponent it must be a react panel
if (plugin.exports.Panel) {
return this.renderReactPanel();
}
console.log('DashboardPanel.render()');
const containerClass = this.props.isEditing ? 'panel-editor-container' : 'panel-height-helper';
const panelWrapperClass = this.props.isEditing ? 'panel-editor-container__panel' : 'panel-height-helper';
// legacy angular rendering
return (
<div
ref={element => (this.element = element)}
className="panel-height-helper"
onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave}
/>
<div className={containerClass}>
<div className={panelWrapperClass} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
{plugin.exports.Panel && this.renderReactPanel()}
{plugin.exports.PanelCtrl && this.renderAngularPanel()}
</div>
{panel.isEditing && (
<PanelEditor
panel={panel}
plugin={plugin}
dashboard={dashboard}
angularPanel={angularPanel}
onTypeChanged={this.onPluginTypeChanged}
/>
)}
</div>
);
}
}