Annotations: Fixes issues loading angular annotation query editors and updating annotation query model (#32903)

* style(dashboardsettings): disable eslint react hooks exhaustive deps warning

* Unrelated fix

* Fix annotation angular loading issues

* Fixing update issue

Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
This commit is contained in:
Jack Westbrook
2021-04-13 13:16:56 +02:00
committed by GitHub
parent 4b7bb418da
commit 4178ebc0a1
3 changed files with 59 additions and 40 deletions

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useRef, useState } from 'react';
import React from 'react';
import { AnnotationQuery, DataSourceApi } from '@grafana/data';
import { AngularComponent, getAngularLoader } from '@grafana/runtime';
@@ -8,41 +8,56 @@ export interface Props {
onChange: (annotation: AnnotationQuery) => void;
}
export const AngularEditorLoader: React.FC<Props> = React.memo(({ annotation, datasource, onChange }) => {
const ref = useRef<HTMLDivElement>(null);
const [angularComponent, setAngularComponent] = useState<AngularComponent | null>(null);
export class AngularEditorLoader extends React.PureComponent<Props> {
ref: HTMLDivElement | null = null;
angularComponent: AngularComponent;
useEffect(() => {
return () => {
if (angularComponent) {
angularComponent.destroy();
}
};
}, [angularComponent]);
useEffect(() => {
if (ref.current) {
const loader = getAngularLoader();
const template = `<plugin-component ng-if="!ctrl.currentDatasource.annotations" type="annotations-query-ctrl"> </plugin-component>`;
const scopeProps = {
ctrl: {
currentDatasource: datasource,
currentAnnotation: annotation,
},
};
const component = loader.load(ref.current, scopeProps, template);
component.digest();
component.getScope().$watch(() => {
onChange({
...annotation,
});
});
setAngularComponent(component);
componentWillUnmount() {
if (this.angularComponent) {
this.angularComponent.destroy();
}
}, [ref]);
}
return <div ref={ref} />;
});
AngularEditorLoader.displayName = 'AngularEditorLoader';
componentDidMount() {
if (this.ref) {
this.loadAngular();
}
}
componentDidUpdate(prevProps: Props) {
if (prevProps.datasource !== this.props.datasource) {
this.loadAngular();
}
if (this.angularComponent && prevProps.annotation !== this.props.annotation) {
this.angularComponent.getScope().ctrl.currentAnnotation = this.props.annotation;
}
}
loadAngular() {
if (this.angularComponent) {
this.angularComponent.destroy();
}
const loader = getAngularLoader();
const template = `<plugin-component ng-if="!ctrl.currentDatasource.annotations" type="annotations-query-ctrl"> </plugin-component>`;
const scopeProps = {
ctrl: {
currentDatasource: this.props.datasource,
currentAnnotation: this.props.annotation,
},
};
this.angularComponent = loader.load(this.ref, scopeProps, template);
this.angularComponent.digest();
this.angularComponent.getScope().$watch(() => {
this.props.onChange({
...scopeProps.ctrl.currentAnnotation,
});
});
}
render() {
return <div ref={(element) => (this.ref = element)} />;
}
}