From b35d4e1e8eadfab66ab44b51971f556759dac5d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 3 Nov 2020 13:18:10 +0100 Subject: [PATCH] Dependencies: Update angularjs to 1.8.2 (#28736) * Angular: Update to angukar v1.8 with backward compatability monkey patches * Update fix * Updated * Updated * Fixes * Update wording * Update --- CHANGELOG.md | 11 +++- package.json | 6 +-- public/app/app.ts | 10 ++-- public/app/core/injectorMonkeyPatch.ts | 50 +++++++++++++++++++ public/app/features/panel/query_editor_row.ts | 2 +- .../plugins/wrappers/AppConfigWrapper.tsx | 8 ++- yarn.lock | 24 ++++----- 7 files changed, 88 insertions(+), 23 deletions(-) create mode 100644 public/app/core/injectorMonkeyPatch.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a6d5e6a4e4..7e906deb153 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# 7.4.0 (unreleased) + +### Breaking changes + +We have upgraded AngularJS from version 1.6.6 to 1.8.2. Due to this upgrade some old angular plugins might stop working and will require an small update. This is due to the deprecation and removal of pre-assigned bindings. So if your custom angular controllers expect component bindings in the controller constructor you need to move this code to an `$onInit` function. For more details on how to migrate AngularJS code open the [migration guide](https://docs.angularjs.org/guide/migration) and search for **pre-assigning bindings**. + +In order not to break all angular panel plugins and data sources we have some custom [angular inject behavior](https://github.com/grafana/grafana/blob/master/public/app/core/injectorMonkeyPatch.ts) that makes sure that bindings for these controllers are still set before constructor is called so many old angular panels and data source plugins will still work. + + # 7.3.1 (2020-10-30) ### Bug Fixes @@ -15,7 +24,7 @@ * **AzureMonitor**: Support decimal (as float64) type in analytics/logs. [#28480](https://github.com/grafana/grafana/pull/28480), [@kylebrandt](https://github.com/kylebrandt) * **Plugins signing**: UI information. [#28469](https://github.com/grafana/grafana/pull/28469), [@dprokop](https://github.com/dprokop) * **Short URL**: Update last seen at when visiting a short URL. [#28565](https://github.com/grafana/grafana/pull/28565), [@marefr](https://github.com/marefr) - + ### Bug Fixes * **Alerting**: Log warnings for obsolete notifiers when extracting alerts and remove frequent error log messages. [#28162](https://github.com/grafana/grafana/pull/28162), [@papagian](https://github.com/papagian) * **Auth**: Fix SigV4 request verification step for Amazon Elasticsearch Service. [#28481](https://github.com/grafana/grafana/pull/28481), [@wbrowne](https://github.com/wbrowne) diff --git a/package.json b/package.json index f268d670a13..70873b3a4f7 100644 --- a/package.json +++ b/package.json @@ -220,10 +220,10 @@ "@types/uuid": "8.3.0", "@welldone-software/why-did-you-render": "4.0.6", "abortcontroller-polyfill": "1.4.0", - "angular": "1.6.9", + "angular": "1.8.2", "angular-bindonce": "0.3.1", - "angular-route": "1.6.6", - "angular-sanitize": "1.6.6", + "angular-route": "1.8.2", + "angular-sanitize": "1.8.2", "antlr4": "^4.8.0", "baron": "3.0.3", "brace": "0.11.1", diff --git a/public/app/app.ts b/public/app/app.ts index 63cea265981..0acb94941f2 100644 --- a/public/app/app.ts +++ b/public/app/app.ts @@ -50,6 +50,7 @@ import { getStandardFieldConfigs, getStandardOptionEditors, getScrollbarWidth } import { getDefaultVariableAdapters, variableAdapters } from './features/variables/adapters'; import { initDevFeatures } from './dev'; import { getStandardTransformers } from 'app/core/utils/standardTransformers'; +import { monkeyPatchInjectorWithPreAssignedBindings } from './core/injectorMonkeyPatch'; // add move to lodash for backward compatabiltiy // @ts-ignore @@ -112,9 +113,6 @@ export class GrafanaApp { $httpProvider: angular.IHttpProvider, $provide: angular.auto.IProvideService ) => { - // pre assign bindings before constructor calls - $compileProvider.preAssignBindingsEnabled(true); - if (config.buildInfo.env !== 'development') { $compileProvider.debugInfoEnabled(false); } @@ -170,7 +168,9 @@ export class GrafanaApp { $.fn.tooltip.defaults.animation = false; // bootstrap the app - angular.bootstrap(document, this.ngModuleDependencies).invoke(() => { + const injector: any = angular.bootstrap(document, this.ngModuleDependencies); + + injector.invoke(() => { _.each(this.preBootModules, (module: angular.IModule) => { _.extend(module, this.registerFunctions); }); @@ -187,6 +187,8 @@ export class GrafanaApp { } }); + monkeyPatchInjectorWithPreAssignedBindings(injector); + // Preload selected app plugins for (const modulePath of config.pluginsToPreload) { importPluginModule(modulePath); diff --git a/public/app/core/injectorMonkeyPatch.ts b/public/app/core/injectorMonkeyPatch.ts new file mode 100644 index 00000000000..ba486ad9ea2 --- /dev/null +++ b/public/app/core/injectorMonkeyPatch.ts @@ -0,0 +1,50 @@ +export function monkeyPatchInjectorWithPreAssignedBindings(injector: any) { + injector.oldInvoke = injector.invoke; + injector.invoke = (fn: any, self: any, locals: any, serviceName: any) => { + const parentScope = locals?.$scope?.$parent; + + if (parentScope) { + // PanelCtrl + if (parentScope.panel) { + self.panel = parentScope.panel; + } + + // Panels & dashboard SettingsCtrl + if (parentScope.dashboard) { + self.dashboard = parentScope.dashboard; + } + + // Query editors + if (parentScope.ctrl?.target) { + self.panelCtrl = parentScope.ctrl; + self.datasource = parentScope.ctrl.datasource; + self.target = parentScope.ctrl.target; + } + + // Data source ConfigCtrl + if (parentScope.ctrl?.datasourceMeta) { + self.meta = parentScope.ctrl.datasourceMeta; + self.current = parentScope.ctrl.current; + } + + // Data source AnnotationsQueryCtrl + if (parentScope.ctrl?.currentAnnotation) { + self.annotation = parentScope.ctrl.currentAnnotation; + self.datasource = parentScope.ctrl.currentDatasource; + } + + // App config ctrl + if (parentScope.isAppConfigCtrl) { + self.appEditCtrl = parentScope.ctrl; + self.appModel = parentScope.ctrl.model; + } + + // App page ctrl + if (parentScope.$parent?.$parent?.ctrl?.appModel) { + self.appModel = parentScope.$parent?.$parent?.ctrl?.appModel; + } + } + + return injector.oldInvoke(fn, self, locals, serviceName); + }; +} diff --git a/public/app/features/panel/query_editor_row.ts b/public/app/features/panel/query_editor_row.ts index 3c44fab4db3..325dac6564f 100644 --- a/public/app/features/panel/query_editor_row.ts +++ b/public/app/features/panel/query_editor_row.ts @@ -9,7 +9,7 @@ export class QueryRowCtrl { panel: any; hasTextEditMode: boolean; - constructor() { + $onInit() { this.panelCtrl = this.queryCtrl.panelCtrl; this.target = this.queryCtrl.target; this.panel = this.panelCtrl.panel; diff --git a/public/app/features/plugins/wrappers/AppConfigWrapper.tsx b/public/app/features/plugins/wrappers/AppConfigWrapper.tsx index 0387ac94c2f..fd0f511c243 100644 --- a/public/app/features/plugins/wrappers/AppConfigWrapper.tsx +++ b/public/app/features/plugins/wrappers/AppConfigWrapper.tsx @@ -20,11 +20,11 @@ interface State { export class AppConfigCtrlWrapper extends PureComponent { element: HTMLElement | null = null; + model: PluginMeta; // Needed for angular scope preUpdateHook = () => Promise.resolve(); postUpdateHook = () => Promise.resolve(); - model: PluginMeta; constructor(props: Props) { super(props); @@ -51,7 +51,11 @@ export class AppConfigCtrlWrapper extends PureComponent { const loader = getAngularLoader(); const template = ''; - const scopeProps = { ctrl: this }; + const scopeProps = { + ctrl: this, + // used by angular injectorMonkeyPatch to detect this scenario + isAppConfigCtrl: true, + }; const angularCtrl = loader.load(this.element, scopeProps, template); this.setState({ angularCtrl }); diff --git a/yarn.lock b/yarn.lock index 17cd1dbaba3..77255f0bc53 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7746,20 +7746,20 @@ angular-mocks@1.6.6: resolved "https://registry.yarnpkg.com/angular-mocks/-/angular-mocks-1.6.6.tgz#c93018e7838c6dc5ceaf1a6bcf9be13c830ea515" integrity sha1-yTAY54OMbcXOrxprz5vhPIMOpRU= -angular-route@1.6.6: - version "1.6.6" - resolved "https://registry.yarnpkg.com/angular-route/-/angular-route-1.6.6.tgz#8c11748aa195c717b1b615a7e746442bfc7c61f4" - integrity sha1-jBF0iqGVxxexthWn50ZEK/x8YfQ= +angular-route@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/angular-route/-/angular-route-1.8.2.tgz#d482bf05a8c9e448300acd8f9989c635d31b5077" + integrity sha512-49LJYxuaQ/ZDiu9dD2xo1LkazqObkGjw0a7dUF7UKCT8EELgBsMd6QrI6aEVGtI62ppkiFkxqmiV8fcwYdXpug== -angular-sanitize@1.6.6: - version "1.6.6" - resolved "https://registry.yarnpkg.com/angular-sanitize/-/angular-sanitize-1.6.6.tgz#0fd065a19931517fbece66596d325d72b6e06041" - integrity sha1-D9BloZkxUX++zmZZbTJdcrbgYEE= +angular-sanitize@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/angular-sanitize/-/angular-sanitize-1.8.2.tgz#ae78040f00c5e2ce1c63780bcc47fa14a1698296" + integrity sha512-OB6Goa+QN3byf5asQ7XRl7DKZejm/F/ZOqa9z1skqYVOWA2hoBxoCmt9E7+i7T/TbxZP5zYzKxNZVVJNu860Hg== -angular@1.6.9: - version "1.6.9" - resolved "https://registry.yarnpkg.com/angular/-/angular-1.6.9.tgz#bc812932e18909038412d594a5990f4bb66c0619" - integrity sha512-6igWH2GIsxV+J38wNWCh8oyjaZsrIPIDO35twloIUyjlF2Yit6UyLAWujHP05ma/LFxTsx4NtYibRoMNBXPR1A== +angular@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/angular/-/angular-1.8.2.tgz#5983bbb5a9fa63e213cb7749199e0d352de3a2f1" + integrity sha512-IauMOej2xEe7/7Ennahkbb5qd/HFADiNuLSESz9Q27inmi32zB0lnAsFeLEWcox3Gd1F6YhNd1CP7/9IukJ0Gw== ansi-align@^2.0.0: version "2.0.0"