From 4178ebc0a11a24a6ba85a9b995a501e680618134 Mon Sep 17 00:00:00 2001 From: Jack Westbrook Date: Tue, 13 Apr 2021 13:16:56 +0200 Subject: [PATCH] Annotations: Fixes issues loading angular annotation query editors and updating annotation query model (#32903) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * style(dashboardsettings): disable eslint react hooks exhaustive deps warning * Unrelated fix * Fix annotation angular loading issues * Fixing update issue Co-authored-by: Torkel Ödegaard --- .../AngularEditorLoader.tsx | 87 +++++++++++-------- .../cloudwatch/annotations_query_ctrl.ts | 6 +- .../datasource/grafana/annotation_ctrl.ts | 6 +- 3 files changed, 59 insertions(+), 40 deletions(-) diff --git a/public/app/features/dashboard/components/AnnotationSettings/AngularEditorLoader.tsx b/public/app/features/dashboard/components/AnnotationSettings/AngularEditorLoader.tsx index 3511a5d96b4..baf70dad5f6 100644 --- a/public/app/features/dashboard/components/AnnotationSettings/AngularEditorLoader.tsx +++ b/public/app/features/dashboard/components/AnnotationSettings/AngularEditorLoader.tsx @@ -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 = React.memo(({ annotation, datasource, onChange }) => { - const ref = useRef(null); - const [angularComponent, setAngularComponent] = useState(null); +export class AngularEditorLoader extends React.PureComponent { + ref: HTMLDivElement | null = null; + angularComponent: AngularComponent; - useEffect(() => { - return () => { - if (angularComponent) { - angularComponent.destroy(); - } - }; - }, [angularComponent]); - - useEffect(() => { - if (ref.current) { - const loader = getAngularLoader(); - const template = ` `; - 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
; -}); -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 = ` `; + 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
(this.ref = element)} />; + } +} diff --git a/public/app/plugins/datasource/cloudwatch/annotations_query_ctrl.ts b/public/app/plugins/datasource/cloudwatch/annotations_query_ctrl.ts index 34fc5cfbfa6..d8d0b07dd11 100644 --- a/public/app/plugins/datasource/cloudwatch/annotations_query_ctrl.ts +++ b/public/app/plugins/datasource/cloudwatch/annotations_query_ctrl.ts @@ -3,10 +3,12 @@ import { AnnotationQuery } from './types'; export class CloudWatchAnnotationsQueryCtrl { static templateUrl = 'partials/annotations.editor.html'; - annotation: any; + declare annotation: any; /** @ngInject */ - constructor() { + constructor($scope: any) { + this.annotation = $scope.ctrl.annotation; + _.defaultsDeep(this.annotation, { namespace: '', metricName: '', diff --git a/public/app/plugins/datasource/grafana/annotation_ctrl.ts b/public/app/plugins/datasource/grafana/annotation_ctrl.ts index 8876ddfb660..7dd200f4a9d 100644 --- a/public/app/plugins/datasource/grafana/annotation_ctrl.ts +++ b/public/app/plugins/datasource/grafana/annotation_ctrl.ts @@ -7,11 +7,13 @@ export const annotationTypes: Array> = [ ]; export class GrafanaAnnotationsQueryCtrl { - annotation: any; + declare annotation: any; types = annotationTypes; - constructor() { + /** @ngInject */ + constructor($scope: any) { + this.annotation = $scope.ctrl.annotation; this.annotation.type = this.annotation.type || GrafanaAnnotationType.Tags; this.annotation.limit = this.annotation.limit || 100; }