Browse Source

Chore: Fixed no implicit any Typescript errors (#16799)

Torkel Ödegaard 6 years ago
parent
commit
a4f5c54871
32 changed files with 196 additions and 188 deletions
  1. 1 1
      public/app/core/controllers/error_ctrl.ts
  2. 2 2
      public/app/core/controllers/invited_ctrl.ts
  3. 1 1
      public/app/core/controllers/json_editor_ctrl.ts
  4. 5 6
      public/app/core/controllers/login_ctrl.ts
  5. 2 2
      public/app/core/controllers/reset_password_ctrl.ts
  6. 3 3
      public/app/core/directives/array_join.ts
  7. 1 1
      public/app/core/directives/autofill_event_fix.ts
  8. 4 4
      public/app/core/directives/diff-view.ts
  9. 11 11
      public/app/core/directives/dropdown_typeahead.ts
  10. 3 3
      public/app/core/directives/give_focus.ts
  11. 15 14
      public/app/core/directives/metric_segment.ts
  12. 15 15
      public/app/core/directives/misc.ts
  13. 5 5
      public/app/core/directives/ng_model_on_blur.ts
  14. 8 8
      public/app/core/directives/rebuild_on_change.ts
  15. 5 5
      public/app/core/directives/tags.ts
  16. 12 12
      public/app/core/directives/value_select_dropdown.ts
  17. 8 22
      public/app/core/filters/filters.ts
  18. 13 13
      public/app/core/live/live_srv.ts
  19. 1 1
      public/app/core/reducers/navModel.ts
  20. 3 2
      public/app/core/selectors/location.ts
  21. 5 5
      public/app/core/services/AngularLoader.ts
  22. 2 2
      public/app/core/services/analytics.ts
  23. 10 3
      public/app/core/services/bridge_srv.ts
  24. 1 1
      public/app/core/services/context_srv.ts
  25. 6 6
      public/app/core/services/dynamic_directive_srv.ts
  26. 4 4
      public/app/core/services/impression_srv.ts
  27. 13 12
      public/app/core/services/keybindingSrv.ts
  28. 5 4
      public/app/core/services/timer.ts
  29. 9 8
      public/app/features/dashboard/services/TimeSrv.test.ts
  30. 20 11
      public/app/features/dashboard/services/TimeSrv.ts
  31. 1 1
      public/app/features/teams/TeamPages.tsx
  32. 2 0
      public/test/specs/helpers.ts

+ 1 - 1
public/app/core/controllers/error_ctrl.ts

@@ -4,7 +4,7 @@ import appEvents from 'app/core/app_events';
 
 export class ErrorCtrl {
   /** @ngInject */
-  constructor($scope, contextSrv, navModelSrv) {
+  constructor($scope: any, contextSrv: any, navModelSrv: any) {
     $scope.navModel = navModelSrv.getNotFoundNav();
     $scope.appSubUrl = config.appSubUrl;
 

+ 2 - 2
public/app/core/controllers/invited_ctrl.ts

@@ -3,7 +3,7 @@ import config from 'app/core/config';
 
 export class InvitedCtrl {
   /** @ngInject */
-  constructor($scope, $routeParams, contextSrv, backendSrv) {
+  constructor($scope: any, $routeParams: any, contextSrv: any, backendSrv: any) {
     contextSrv.sidemenu = false;
     $scope.formModel = {};
 
@@ -17,7 +17,7 @@ export class InvitedCtrl {
     };
 
     $scope.init = () => {
-      backendSrv.get('/api/user/invite/' + $routeParams.code).then(invite => {
+      backendSrv.get('/api/user/invite/' + $routeParams.code).then((invite: any) => {
         $scope.formModel.name = invite.name;
         $scope.formModel.email = invite.email;
         $scope.formModel.username = invite.email;

+ 1 - 1
public/app/core/controllers/json_editor_ctrl.ts

@@ -3,7 +3,7 @@ import coreModule from '../core_module';
 
 export class JsonEditorCtrl {
   /** @ngInject */
-  constructor($scope) {
+  constructor($scope: any) {
     $scope.json = angular.toJson($scope.model.object, true);
     $scope.canUpdate = $scope.model.updateHandler !== void 0 && $scope.model.canUpdate;
     $scope.canCopy = $scope.model.enableCopy;

+ 5 - 6
public/app/core/controllers/login_ctrl.ts

@@ -1,10 +1,11 @@
 import _ from 'lodash';
 import coreModule from '../core_module';
 import config from 'app/core/config';
+import { BackendSrv } from '../services/backend_srv';
 
 export class LoginCtrl {
   /** @ngInject */
-  constructor($scope, backendSrv, contextSrv, $location) {
+  constructor($scope: any, backendSrv: BackendSrv, $location: any) {
     $scope.formModel = {
       user: '',
       email: '',
@@ -15,8 +16,6 @@ export class LoginCtrl {
     $scope.result = '';
     $scope.loggingIn = false;
 
-    contextSrv.sidemenu = false;
-
     $scope.oauth = config.oauth;
     $scope.oauthEnabled = _.keys(config.oauth).length > 0;
     $scope.ldapEnabled = config.ldapEnabled;
@@ -83,7 +82,7 @@ export class LoginCtrl {
       $scope.toGrafana();
     };
 
-    $scope.loginModeChanged = newValue => {
+    $scope.loginModeChanged = (newValue: boolean) => {
       $scope.submitBtnText = newValue ? 'Log in' : 'Sign up';
     };
 
@@ -92,7 +91,7 @@ export class LoginCtrl {
         return;
       }
 
-      backendSrv.post('/api/user/signup', $scope.formModel).then(result => {
+      backendSrv.post('/api/user/signup', $scope.formModel).then((result: any) => {
         if (result.status === 'SignUpCreated') {
           $location.path('/signup').search({ email: $scope.formModel.email });
         } else {
@@ -111,7 +110,7 @@ export class LoginCtrl {
 
       backendSrv
         .post('/login', $scope.formModel)
-        .then(result => {
+        .then((result: any) => {
           $scope.result = result;
 
           if ($scope.formModel.password !== 'admin' || $scope.ldapEnabled || $scope.authProxyEnabled) {

+ 2 - 2
public/app/core/controllers/reset_password_ctrl.ts

@@ -1,10 +1,10 @@
 import coreModule from '../core_module';
 import config from 'app/core/config';
+import { BackendSrv } from '../services/backend_srv';
 
 export class ResetPasswordCtrl {
   /** @ngInject */
-  constructor($scope, contextSrv, backendSrv, $location) {
-    contextSrv.sidemenu = false;
+  constructor($scope: any, backendSrv: BackendSrv, $location: any) {
     $scope.formModel = {};
     $scope.mode = 'send';
     $scope.ldapEnabled = config.ldapEnabled;

+ 3 - 3
public/app/core/directives/array_join.ts

@@ -7,12 +7,12 @@ export function arrayJoin() {
   return {
     restrict: 'A',
     require: 'ngModel',
-    link: (scope, element, attr, ngModel) => {
-      function split_array(text) {
+    link: (scope: any, element: any, attr: any, ngModel: any) => {
+      function split_array(text: string) {
         return (text || '').split(',');
       }
 
-      function join_array(text) {
+      function join_array(text: string) {
         if (_.isArray(text)) {
           return ((text || '') as any).join(',');
         } else {

+ 1 - 1
public/app/core/directives/autofill_event_fix.ts

@@ -1,7 +1,7 @@
 import coreModule from '../core_module';
 
 /** @ngInject */
-export function autofillEventFix($compile) {
+export function autofillEventFix($compile: any) {
   return {
     link: ($scope: any, elem: any) => {
       const input = elem[0];

+ 4 - 4
public/app/core/directives/diff-view.ts

@@ -5,8 +5,8 @@ export class DeltaCtrl {
   observer: any;
 
   /** @ngInject */
-  constructor(private $rootScope) {
-    const waitForCompile = mutations => {
+  constructor(private $rootScope: any) {
+    const waitForCompile = (mutations: any) => {
       if (mutations.length === 1) {
         this.$rootScope.appEvent('json-diff-ready');
       }
@@ -42,10 +42,10 @@ coreModule.directive('diffDelta', delta);
 // Link to JSON line number
 export class LinkJSONCtrl {
   /** @ngInject */
-  constructor(private $scope, private $rootScope, private $anchorScroll) {}
+  constructor(private $scope: any, private $rootScope: any, private $anchorScroll: any) {}
 
   goToLine(line: number) {
-    let unbind;
+    let unbind: () => void;
 
     const scroll = () => {
       this.$anchorScroll(`l${line}`);

+ 11 - 11
public/app/core/directives/dropdown_typeahead.ts

@@ -3,7 +3,7 @@ import $ from 'jquery';
 import coreModule from '../core_module';
 
 /** @ngInject */
-export function dropdownTypeahead($compile) {
+export function dropdownTypeahead($compile: any) {
   const inputTemplate =
     '<input type="text"' +
     ' class="gf-form-input input-medium tight-form-input"' +
@@ -20,7 +20,7 @@ export function dropdownTypeahead($compile) {
       dropdownTypeaheadOnSelect: '&dropdownTypeaheadOnSelect',
       model: '=ngModel',
     },
-    link: ($scope, elem, attrs) => {
+    link: ($scope: any, elem: any, attrs: any) => {
       const $input = $(inputTemplate);
       const $button = $(buttonTemplate);
       $input.appendTo(elem);
@@ -31,7 +31,7 @@ export function dropdownTypeahead($compile) {
       }
 
       if (attrs.ngModel) {
-        $scope.$watch('model', newValue => {
+        $scope.$watch('model', (newValue: any) => {
           _.each($scope.menuItems, item => {
             _.each(item.submenu, subItem => {
               if (subItem.value === newValue) {
@@ -59,7 +59,7 @@ export function dropdownTypeahead($compile) {
         []
       );
 
-      $scope.menuItemSelected = (index, subIndex) => {
+      $scope.menuItemSelected = (index: number, subIndex: number) => {
         const menuItem = $scope.menuItems[index];
         const payload: any = { $item: menuItem };
         if (menuItem.submenu && subIndex !== void 0) {
@@ -73,7 +73,7 @@ export function dropdownTypeahead($compile) {
         source: typeaheadValues,
         minLength: 1,
         items: 10,
-        updater: value => {
+        updater: (value: string) => {
           const result: any = {};
           _.each($scope.menuItems, menuItem => {
             _.each(menuItem.submenu, submenuItem => {
@@ -123,7 +123,7 @@ export function dropdownTypeahead($compile) {
 }
 
 /** @ngInject */
-export function dropdownTypeahead2($compile) {
+export function dropdownTypeahead2($compile: any) {
   const inputTemplate =
     '<input type="text"' + ' class="gf-form-input"' + ' spellcheck="false" style="display:none"></input>';
 
@@ -139,7 +139,7 @@ export function dropdownTypeahead2($compile) {
       model: '=ngModel',
       buttonTemplateClass: '@',
     },
-    link: ($scope, elem, attrs) => {
+    link: ($scope: any, elem: any, attrs: any) => {
       const $input = $(inputTemplate);
 
       if (!$scope.buttonTemplateClass) {
@@ -148,7 +148,7 @@ export function dropdownTypeahead2($compile) {
 
       const $button = $(buttonTemplate);
       const timeoutId = {
-        blur: null,
+        blur: null as any,
       };
       $input.appendTo(elem);
       $button.appendTo(elem);
@@ -158,7 +158,7 @@ export function dropdownTypeahead2($compile) {
       }
 
       if (attrs.ngModel) {
-        $scope.$watch('model', newValue => {
+        $scope.$watch('model', (newValue: any) => {
           _.each($scope.menuItems, item => {
             _.each(item.submenu, subItem => {
               if (subItem.value === newValue) {
@@ -194,7 +194,7 @@ export function dropdownTypeahead2($compile) {
         elem.removeClass('open');
       };
 
-      $scope.menuItemSelected = (index, subIndex) => {
+      $scope.menuItemSelected = (index: number, subIndex: number) => {
         const menuItem = $scope.menuItems[index];
         const payload: any = { $item: menuItem };
         if (menuItem.submenu && subIndex !== void 0) {
@@ -209,7 +209,7 @@ export function dropdownTypeahead2($compile) {
         source: typeaheadValues,
         minLength: 1,
         items: 10,
-        updater: value => {
+        updater: (value: string) => {
           const result: any = {};
           _.each($scope.menuItems, menuItem => {
             _.each(menuItem.submenu, submenuItem => {

+ 3 - 3
public/app/core/directives/give_focus.ts

@@ -1,14 +1,14 @@
 import coreModule from '../core_module';
 
 coreModule.directive('giveFocus', () => {
-  return (scope, element, attrs) => {
-    element.click(e => {
+  return (scope: any, element: any, attrs: any) => {
+    element.click((e: any) => {
       e.stopPropagation();
     });
 
     scope.$watch(
       attrs.giveFocus,
-      newValue => {
+      (newValue: any) => {
         if (!newValue) {
           return;
         }

+ 15 - 14
public/app/core/directives/metric_segment.ts

@@ -1,9 +1,10 @@
 import _ from 'lodash';
 import $ from 'jquery';
 import coreModule from '../core_module';
+import { TemplateSrv } from 'app/features/templating/template_srv';
 
 /** @ngInject */
-export function metricSegment($compile, $sce, templateSrv) {
+export function metricSegment($compile: any, $sce: any, templateSrv: TemplateSrv) {
   const inputTemplate =
     '<input type="text" data-provide="typeahead" ' +
     ' class="gf-form-input input-medium"' +
@@ -24,19 +25,19 @@ export function metricSegment($compile, $sce, templateSrv) {
       onChange: '&',
       debounce: '@',
     },
-    link: ($scope, elem) => {
+    link: ($scope: any, elem: any) => {
       const $input = $(inputTemplate);
       const segment = $scope.segment;
       const $button = $(segment.selectMode ? selectTemplate : linkTemplate);
       let options = null;
-      let cancelBlur = null;
+      let cancelBlur: any = null;
       let linkMode = true;
       const debounceLookup = $scope.debounce;
 
       $input.appendTo(elem);
       $button.appendTo(elem);
 
-      $scope.updateVariableValue = value => {
+      $scope.updateVariableValue = (value: string) => {
         if (value === '' || segment.value === value) {
           return;
         }
@@ -63,7 +64,7 @@ export function metricSegment($compile, $sce, templateSrv) {
         });
       };
 
-      $scope.switchToLink = fromClick => {
+      $scope.switchToLink = (fromClick: boolean) => {
         if (linkMode && !fromClick) {
           return;
         }
@@ -82,9 +83,9 @@ export function metricSegment($compile, $sce, templateSrv) {
         cancelBlur = setTimeout($scope.switchToLink, 200);
       };
 
-      $scope.source = (query, callback) => {
+      $scope.source = (query: string, callback: any) => {
         $scope.$apply(() => {
-          $scope.getOptions({ $query: query }).then(altSegments => {
+          $scope.getOptions({ $query: query }).then((altSegments: any) => {
             $scope.altSegments = altSegments;
             options = _.map($scope.altSegments, alt => {
               return _.escape(alt.value);
@@ -102,7 +103,7 @@ export function metricSegment($compile, $sce, templateSrv) {
         });
       };
 
-      $scope.updater = value => {
+      $scope.updater = (value: string) => {
         value = _.unescape(value);
         if (value === segment.value) {
           clearTimeout(cancelBlur);
@@ -116,7 +117,7 @@ export function metricSegment($compile, $sce, templateSrv) {
         return value;
       };
 
-      $scope.matcher = function(item) {
+      $scope.matcher = function(item: string) {
         if (linkMode) {
           return false;
         }
@@ -186,7 +187,7 @@ export function metricSegment($compile, $sce, templateSrv) {
 }
 
 /** @ngInject */
-export function metricSegmentModel(uiSegmentSrv, $q) {
+export function metricSegmentModel(uiSegmentSrv: any, $q: any) {
   return {
     template:
       '<metric-segment segment="segment" get-options="getOptionsInternal()" on-change="onSegmentChange()"></metric-segment>',
@@ -198,10 +199,10 @@ export function metricSegmentModel(uiSegmentSrv, $q) {
       onChange: '&',
     },
     link: {
-      pre: function postLink($scope, elem, attrs) {
-        let cachedOptions;
+      pre: function postLink($scope: any, elem: any, attrs: any) {
+        let cachedOptions: any;
 
-        $scope.valueToSegment = value => {
+        $scope.valueToSegment = (value: any) => {
           const option: any = _.find($scope.options, { value: value });
           const segment = {
             cssClass: attrs.cssClass,
@@ -222,7 +223,7 @@ export function metricSegmentModel(uiSegmentSrv, $q) {
               })
             );
           } else {
-            return $scope.getOptions().then(options => {
+            return $scope.getOptions().then((options: any) => {
               cachedOptions = options;
               return _.map(options, option => {
                 if (option.html) {

+ 15 - 15
public/app/core/directives/misc.ts

@@ -5,10 +5,10 @@ import kbn from 'app/core/utils/kbn';
 import { appEvents } from 'app/core/core';
 
 /** @ngInject */
-function tip($compile) {
+function tip($compile: any) {
   return {
     restrict: 'E',
-    link: (scope, elem, attrs) => {
+    link: (scope: any, elem: any, attrs: any) => {
       let _t =
         '<i class="grafana-tip fa fa-' +
         (attrs.icon || 'question-circle') +
@@ -26,7 +26,7 @@ function clipboardButton() {
     scope: {
       getText: '&clipboardButton',
     },
-    link: (scope, elem) => {
+    link: (scope: any, elem: any) => {
       scope.clipboard = new Clipboard(elem[0], {
         text: () => {
           return scope.getText();
@@ -47,15 +47,15 @@ function clipboardButton() {
 }
 
 /** @ngInject */
-function compile($compile) {
+function compile($compile: any) {
   return {
     restrict: 'A',
-    link: (scope, element, attrs) => {
+    link: (scope: any, element: any, attrs: any) => {
       scope.$watch(
-        scope => {
+        (scope: any) => {
           return scope.$eval(attrs.compile);
         },
-        value => {
+        (value: any) => {
           element.html(value);
           $compile(element.contents())(scope);
         }
@@ -67,7 +67,7 @@ function compile($compile) {
 function watchChange() {
   return {
     scope: { onchange: '&watchChange' },
-    link: (scope, element) => {
+    link: (scope: any, element: any) => {
       element.on('input', () => {
         scope.$apply(() => {
           scope.onchange({ inputValue: element.val() });
@@ -78,10 +78,10 @@ function watchChange() {
 }
 
 /** @ngInject */
-function editorOptBool($compile) {
+function editorOptBool($compile: any) {
   return {
     restrict: 'E',
-    link: (scope, elem, attrs) => {
+    link: (scope: any, elem: any, attrs: any) => {
       const ngchange = attrs.change ? ' ng-change="' + attrs.change + '"' : '';
       const tip = attrs.tip ? ' <tip>' + attrs.tip + '</tip>' : '';
       const showIf = attrs.showIf ? ' ng-show="' + attrs.showIf + '" ' : '';
@@ -115,10 +115,10 @@ function editorOptBool($compile) {
 }
 
 /** @ngInject */
-function editorCheckbox($compile, $interpolate) {
+function editorCheckbox($compile: any, $interpolate: any) {
   return {
     restrict: 'E',
-    link: (scope, elem, attrs) => {
+    link: (scope: any, elem: any, attrs: any) => {
       const text = $interpolate(attrs.text)(scope);
       const model = $interpolate(attrs.model)(scope);
       const ngchange = attrs.change ? ' ng-change="' + attrs.change + '"' : '';
@@ -150,8 +150,8 @@ function editorCheckbox($compile, $interpolate) {
 }
 
 /** @ngInject */
-function gfDropdown($parse, $compile, $timeout) {
-  function buildTemplate(items, placement?) {
+function gfDropdown($parse: any, $compile: any, $timeout: any) {
+  function buildTemplate(items: any, placement?: any) {
     const upclass = placement === 'top' ? 'dropup' : '';
     const ul = ['<ul class="dropdown-menu ' + upclass + '" role="menu" aria-labelledby="drop1">', '</ul>'];
 
@@ -191,7 +191,7 @@ function gfDropdown($parse, $compile, $timeout) {
   return {
     restrict: 'EA',
     scope: true,
-    link: function postLink(scope, iElement, iAttrs) {
+    link: function postLink(scope: any, iElement: any, iAttrs: any) {
       const getter = $parse(iAttrs.gfDropdown),
         items = getter(scope);
       $timeout(() => {

+ 5 - 5
public/app/core/directives/ng_model_on_blur.ts

@@ -6,7 +6,7 @@ function ngModelOnBlur() {
     restrict: 'A',
     priority: 1,
     require: 'ngModel',
-    link: (scope, elm, attr, ngModelCtrl) => {
+    link: (scope: any, elm: any, attr: any, ngModelCtrl: any) => {
       if (attr.type === 'radio' || attr.type === 'checkbox') {
         return;
       }
@@ -25,8 +25,8 @@ function emptyToNull() {
   return {
     restrict: 'A',
     require: 'ngModel',
-    link: (scope, elm, attrs, ctrl) => {
-      ctrl.$parsers.push(viewValue => {
+    link: (scope: any, elm: any, attrs: any, ctrl: any) => {
+      ctrl.$parsers.push((viewValue: any) => {
         if (viewValue === '') {
           return null;
         }
@@ -39,8 +39,8 @@ function emptyToNull() {
 function validTimeSpan() {
   return {
     require: 'ngModel',
-    link: (scope, elm, attrs, ctrl) => {
-      ctrl.$validators.integer = (modelValue, viewValue) => {
+    link: (scope: any, elm: any, attrs: any, ctrl: any) => {
+      ctrl.$validators.integer = (modelValue: any, viewValue: any) => {
         if (ctrl.$isEmpty(modelValue)) {
           return true;
         }

+ 8 - 8
public/app/core/directives/rebuild_on_change.ts

@@ -1,16 +1,16 @@
 import $ from 'jquery';
 import coreModule from '../core_module';
 
-function getBlockNodes(nodes) {
+function getBlockNodes(nodes: any[]) {
   let node = nodes[0];
   const endNode = nodes[nodes.length - 1];
-  let blockNodes;
+  let blockNodes: any[];
   node = node.nextSibling;
 
   for (let i = 1; node !== endNode && node; i++) {
     if (blockNodes || nodes[i] !== node) {
       if (!blockNodes) {
-        blockNodes = $([].slice.call(nodes, 0, i));
+        blockNodes = $([].slice.call(nodes, 0, i)) as any;
       }
       blockNodes.push(node);
     }
@@ -21,15 +21,15 @@ function getBlockNodes(nodes) {
 }
 
 /** @ngInject */
-function rebuildOnChange($animate) {
+function rebuildOnChange($animate: any) {
   return {
     multiElement: true,
     terminal: true,
     transclude: true,
     priority: 600,
     restrict: 'E',
-    link: (scope, elem, attrs, ctrl, transclude) => {
-      let block, childScope, previousElements;
+    link: (scope: any, elem: any, attrs: any, ctrl: any, transclude: any) => {
+      let block: any, childScope: any, previousElements: any;
 
       function cleanUp() {
         if (previousElements) {
@@ -49,13 +49,13 @@ function rebuildOnChange($animate) {
         }
       }
 
-      scope.$watch(attrs.property, function rebuildOnChangeAction(value, oldValue) {
+      scope.$watch(attrs.property, function rebuildOnChangeAction(value: any, oldValue: any) {
         if (childScope && value !== oldValue) {
           cleanUp();
         }
 
         if (!childScope && (value || attrs.showNull)) {
-          transclude((clone, newScope) => {
+          transclude((clone: any, newScope: any) => {
             childScope = newScope;
             clone[clone.length++] = document.createComment(' end rebuild on change ');
             block = { clone: clone };

+ 5 - 5
public/app/core/directives/tags.ts

@@ -4,7 +4,7 @@ import coreModule from '../core_module';
 import tags from 'app/core/utils/tags';
 import 'vendor/tagsinput/bootstrap-tagsinput.js';
 
-function setColor(name, element) {
+function setColor(name: string, element: JQuery) {
   const { color, borderColor } = tags.getTagColorsFromName(name);
   element.css('background-color', color);
   element.css('border-color', borderColor);
@@ -13,14 +13,14 @@ function setColor(name, element) {
 function tagColorFromName() {
   return {
     scope: { tagColorFromName: '=' },
-    link: (scope, element) => {
+    link: (scope: any, element: any) => {
       setColor(scope.tagColorFromName, element);
     },
   };
 }
 
 function bootstrapTagsinput() {
-  function getItemProperty(scope, property) {
+  function getItemProperty(scope: any, property: any) {
     if (!property) {
       return undefined;
     }
@@ -29,7 +29,7 @@ function bootstrapTagsinput() {
       return scope.$parent[property];
     }
 
-    return item => {
+    return (item: any) => {
       return item[property];
     };
   }
@@ -42,7 +42,7 @@ function bootstrapTagsinput() {
     },
     template: '<select multiple></select>',
     replace: false,
-    link: function(scope, element, attrs) {
+    link: function(scope: any, element: any, attrs: any) {
       if (!angular.isArray(scope.model)) {
         scope.model = [];
       }

+ 12 - 12
public/app/core/directives/value_select_dropdown.ts

@@ -18,7 +18,7 @@ export class ValueSelectDropdownCtrl {
   onUpdated: any;
 
   /** @ngInject */
-  constructor(private $q) {}
+  constructor(private $q: any) {}
 
   show() {
     this.oldVariableText = this.variable.current.text;
@@ -84,7 +84,7 @@ export class ValueSelectDropdownCtrl {
     this.selectionsChanged(false);
   }
 
-  selectTag(tag) {
+  selectTag(tag: any) {
     tag.selected = !tag.selected;
     let tagValuesPromise;
     if (!tag.values) {
@@ -93,7 +93,7 @@ export class ValueSelectDropdownCtrl {
       tagValuesPromise = this.$q.when(tag.values);
     }
 
-    return tagValuesPromise.then(values => {
+    return tagValuesPromise.then((values: any) => {
       tag.values = values;
       tag.valuesText = values.join(' + ');
       _.each(this.options, option => {
@@ -106,7 +106,7 @@ export class ValueSelectDropdownCtrl {
     });
   }
 
-  keyDown(evt) {
+  keyDown(evt: any) {
     if (evt.keyCode === 27) {
       this.hide();
     }
@@ -128,11 +128,11 @@ export class ValueSelectDropdownCtrl {
     }
   }
 
-  moveHighlight(direction) {
+  moveHighlight(direction: number) {
     this.highlightIndex = (this.highlightIndex + direction) % this.search.options.length;
   }
 
-  selectValue(option, event, commitChange?, excludeOthers?) {
+  selectValue(option: any, event: any, commitChange?: boolean, excludeOthers?: boolean) {
     if (!option) {
       return;
     }
@@ -142,7 +142,7 @@ export class ValueSelectDropdownCtrl {
     commitChange = commitChange || false;
     excludeOthers = excludeOthers || false;
 
-    const setAllExceptCurrentTo = newValue => {
+    const setAllExceptCurrentTo = (newValue: any) => {
       _.each(this.options, other => {
         if (option !== other) {
           other.selected = newValue;
@@ -169,7 +169,7 @@ export class ValueSelectDropdownCtrl {
     this.selectionsChanged(commitChange);
   }
 
-  selectionsChanged(commitChange) {
+  selectionsChanged(commitChange: boolean) {
     this.selectedValues = _.filter(this.options, { selected: true });
 
     if (this.selectedValues.length > 1) {
@@ -238,14 +238,14 @@ export class ValueSelectDropdownCtrl {
 }
 
 /** @ngInject */
-export function valueSelectDropdown($compile, $window, $timeout, $rootScope) {
+export function valueSelectDropdown($compile: any, $window: any, $timeout: any, $rootScope: any) {
   return {
     scope: { dashboard: '=', variable: '=', onUpdated: '&' },
     templateUrl: 'public/app/partials/valueSelectDropdown.html',
     controller: 'ValueSelectDropdownCtrl',
     controllerAs: 'vm',
     bindToController: true,
-    link: (scope, elem) => {
+    link: (scope: any, elem: any) => {
       const bodyEl = angular.element($window.document.body);
       const linkEl = elem.find('.variable-value-link');
       const inputEl = elem.find('input');
@@ -272,7 +272,7 @@ export function valueSelectDropdown($compile, $window, $timeout, $rootScope) {
         bodyEl.off('click', bodyOnClick);
       }
 
-      function bodyOnClick(e) {
+      function bodyOnClick(e: any) {
         if (elem.has(e.target).length === 0) {
           scope.$apply(() => {
             scope.vm.commitChanges();
@@ -280,7 +280,7 @@ export function valueSelectDropdown($compile, $window, $timeout, $rootScope) {
         }
       }
 
-      scope.$watch('vm.dropdownVisible', newValue => {
+      scope.$watch('vm.dropdownVisible', (newValue: any) => {
         if (newValue) {
           openDropdown();
         } else {

+ 8 - 22
public/app/core/filters/filters.ts

@@ -2,23 +2,25 @@ import _ from 'lodash';
 import angular from 'angular';
 import moment from 'moment';
 import coreModule from '../core_module';
+import { TemplateSrv } from 'app/features/templating/template_srv';
 
 coreModule.filter('stringSort', () => {
-  return input => {
+  return (input: any) => {
     return input.sort();
   };
 });
 
 coreModule.filter('slice', () => {
-  return (arr, start, end) => {
+  return (arr: any[], start: any, end: any) => {
     if (!_.isUndefined(arr)) {
       return arr.slice(start, end);
     }
+    return arr;
   };
 });
 
 coreModule.filter('stringify', () => {
-  return arr => {
+  return (arr: any[]) => {
     if (_.isObject(arr) && !_.isArray(arr)) {
       return angular.toJson(arr);
     } else {
@@ -28,7 +30,7 @@ coreModule.filter('stringify', () => {
 });
 
 coreModule.filter('moment', () => {
-  return (date, mode) => {
+  return (date: string, mode: string) => {
     switch (mode) {
       case 'ago':
         return moment(date).fromNow();
@@ -37,25 +39,9 @@ coreModule.filter('moment', () => {
   };
 });
 
-coreModule.filter('noXml', () => {
-  const noXml = text => {
-    return _.isString(text)
-      ? text
-          .replace(/&/g, '&amp;')
-          .replace(/</g, '&lt;')
-          .replace(/>/g, '&gt;')
-          .replace(/'/g, '&#39;')
-          .replace(/"/g, '&quot;')
-      : text;
-  };
-  return text => {
-    return _.isArray(text) ? _.map(text, noXml) : noXml(text);
-  };
-});
-
 /** @ngInject */
-function interpolateTemplateVars(templateSrv) {
-  const filterFunc: any = (text, scope) => {
+function interpolateTemplateVars(templateSrv: TemplateSrv) {
+  const filterFunc: any = (text: string, scope: any) => {
     let scopedVars;
     if (scope.ctrl) {
       scopedVars = (scope.ctrl.panel || scope.ctrl.row).scopedVars;

+ 13 - 13
public/app/core/live/live_srv.ts

@@ -30,7 +30,7 @@ export class LiveSrv {
       console.log('Live: connecting...');
       this.conn = new WebSocket(this.getWebSocketUrl());
 
-      this.conn.onclose = evt => {
+      this.conn.onclose = (evt: any) => {
         console.log('Live: websocket onclose', evt);
         reject({ message: 'Connection closed' });
 
@@ -38,17 +38,17 @@ export class LiveSrv {
         setTimeout(this.reconnect.bind(this), 2000);
       };
 
-      this.conn.onmessage = evt => {
+      this.conn.onmessage = (evt: any) => {
         this.handleMessage(evt.data);
       };
 
-      this.conn.onerror = evt => {
+      this.conn.onerror = (evt: any) => {
         this.initPromise = null;
         reject({ message: 'Connection error' });
         console.log('Live: websocket error', evt);
       };
 
-      this.conn.onopen = evt => {
+      this.conn.onopen = (evt: any) => {
         console.log('opened');
         this.initPromise = null;
         resolve(this.conn);
@@ -58,7 +58,7 @@ export class LiveSrv {
     return this.initPromise;
   }
 
-  handleMessage(message) {
+  handleMessage(message: any) {
     message = JSON.parse(message);
 
     if (!message.stream) {
@@ -83,38 +83,38 @@ export class LiveSrv {
 
     console.log('LiveSrv: Reconnecting');
 
-    this.getConnection().then(conn => {
+    this.getConnection().then((conn: any) => {
       _.each(this.observers, (value, key) => {
         this.send({ action: 'subscribe', stream: key });
       });
     });
   }
 
-  send(data) {
+  send(data: any) {
     this.conn.send(JSON.stringify(data));
   }
 
-  addObserver(stream, observer) {
+  addObserver(stream: any, observer: any) {
     this.observers[stream] = observer;
 
-    this.getConnection().then(conn => {
+    this.getConnection().then((conn: any) => {
       this.send({ action: 'subscribe', stream: stream });
     });
   }
 
-  removeObserver(stream, observer) {
+  removeObserver(stream: any, observer: any) {
     console.log('unsubscribe', stream);
     delete this.observers[stream];
 
-    this.getConnection().then(conn => {
+    this.getConnection().then((conn: any) => {
       this.send({ action: 'unsubscribe', stream: stream });
     });
   }
 
-  subscribe(streamName) {
+  subscribe(streamName: string) {
     console.log('LiveSrv.subscribe: ' + streamName);
 
-    return Observable.create(observer => {
+    return Observable.create((observer: any) => {
       this.addObserver(streamName, observer);
 
       return () => {

+ 1 - 1
public/app/core/reducers/navModel.ts

@@ -27,7 +27,7 @@ export const initialState: NavIndex = buildInitialState();
 export const navIndexReducer = (state = initialState, action: Action): NavIndex => {
   switch (action.type) {
     case ActionTypes.UpdateNavIndex:
-      const newPages = {};
+      const newPages: NavIndex = {};
       const payload = action.payload;
 
       for (const node of payload.children) {

+ 3 - 2
public/app/core/selectors/location.ts

@@ -1,3 +1,4 @@
-export const getRouteParamsId = state => state.routeParams.id;
+import { LocationState } from 'app/types';
 
-export const getRouteParamsPage = state => state.routeParams.page;
+export const getRouteParamsId = (state: LocationState) => state.routeParams.id;
+export const getRouteParamsPage = (state: LocationState) => state.routeParams.page;

+ 5 - 5
public/app/core/services/AngularLoader.ts

@@ -3,16 +3,16 @@ import coreModule from 'app/core/core_module';
 import _ from 'lodash';
 
 export interface AngularComponent {
-  destroy();
-  digest();
-  getScope();
+  destroy(): void;
+  digest(): void;
+  getScope(): any;
 }
 
 export class AngularLoader {
   /** @ngInject */
-  constructor(private $compile, private $rootScope) {}
+  constructor(private $compile: any, private $rootScope: any) {}
 
-  load(elem, scopeProps, template): AngularComponent {
+  load(elem: any, scopeProps: any, template: string): AngularComponent {
     const scope = this.$rootScope.$new();
 
     _.assign(scope, scopeProps);

+ 2 - 2
public/app/core/services/analytics.ts

@@ -4,7 +4,7 @@ import config from 'app/core/config';
 
 export class Analytics {
   /** @ngInject */
-  constructor(private $rootScope, private $location) {}
+  constructor(private $rootScope: any, private $location: any) {}
 
   gaInit() {
     $.ajax({
@@ -35,7 +35,7 @@ export class Analytics {
 }
 
 /** @ngInject */
-function startAnalytics(googleAnalyticsSrv) {
+function startAnalytics(googleAnalyticsSrv: Analytics) {
   if ((config as any).googleAnalyticsId) {
     googleAnalyticsSrv.init();
   }

+ 10 - 3
public/app/core/services/bridge_srv.ts

@@ -3,13 +3,20 @@ import appEvents from 'app/core/app_events';
 import { store } from 'app/store/store';
 import locationUtil from 'app/core/utils/location_util';
 import { updateLocation } from 'app/core/actions';
+import { ITimeoutService, ILocationService, IWindowService, IRootScopeService } from 'angular';
 
 // Services that handles angular -> redux store sync & other react <-> angular sync
 export class BridgeSrv {
-  private fullPageReloadRoutes;
+  private fullPageReloadRoutes: string[];
 
   /** @ngInject */
-  constructor(private $location, private $timeout, private $window, private $rootScope, private $route) {
+  constructor(
+    private $location: ILocationService,
+    private $timeout: ITimeoutService,
+    private $window: IWindowService,
+    private $rootScope: IRootScopeService,
+    private $route: any
+  ) {
     this.fullPageReloadRoutes = ['/logout'];
   }
 
@@ -55,7 +62,7 @@ export class BridgeSrv {
       }
     });
 
-    appEvents.on('location-change', payload => {
+    appEvents.on('location-change', (payload: any) => {
       const urlWithoutBase = locationUtil.stripBaseFromUrl(payload.href);
       if (this.fullPageReloadRoutes.indexOf(urlWithoutBase) > -1) {
         this.$window.location.href = payload.href;

+ 1 - 1
public/app/core/services/context_srv.ts

@@ -44,7 +44,7 @@ export class ContextSrv {
     this.hasEditPermissionInFolders = this.user.hasEditPermissionInFolders;
   }
 
-  hasRole(role) {
+  hasRole(role: string) {
     return this.user.orgRole === role;
   }
 

+ 6 - 6
public/app/core/services/dynamic_directive_srv.ts

@@ -3,9 +3,9 @@ import coreModule from '../core_module';
 
 class DynamicDirectiveSrv {
   /** @ngInject */
-  constructor(private $compile) {}
+  constructor(private $compile: angular.ICompileService) {}
 
-  addDirective(element, name, scope) {
+  addDirective(element: any, name: string, scope: any) {
     const child = angular.element(document.createElement(name));
     this.$compile(child)(scope);
 
@@ -13,7 +13,7 @@ class DynamicDirectiveSrv {
     element.append(child);
   }
 
-  link(scope, elem, attrs, options) {
+  link(scope: any, elem: JQLite, attrs: any, options: any) {
     const directiveInfo = options.directive(scope);
     if (!directiveInfo || !directiveInfo.fn) {
       elem.empty();
@@ -28,13 +28,13 @@ class DynamicDirectiveSrv {
     this.addDirective(elem, directiveInfo.name, scope);
   }
 
-  create(options) {
+  create(options: any) {
     const directiveDef = {
       restrict: 'E',
       scope: options.scope,
-      link: (scope, elem, attrs) => {
+      link: (scope: any, elem: JQLite, attrs: any) => {
         if (options.watchPath) {
-          let childScope = null;
+          let childScope: any = null;
           scope.$watch(options.watchPath, () => {
             if (childScope) {
               childScope.$destroy();

+ 4 - 4
public/app/core/services/impression_srv.ts

@@ -5,8 +5,8 @@ import config from 'app/core/config';
 export class ImpressionSrv {
   constructor() {}
 
-  addDashboardImpression(dashboardId) {
-    const impressionsKey = this.impressionKey(config);
+  addDashboardImpression(dashboardId: number) {
+    const impressionsKey = this.impressionKey();
     let impressions = [];
     if (store.exists(impressionsKey)) {
       impressions = JSON.parse(store.get(impressionsKey));
@@ -28,7 +28,7 @@ export class ImpressionSrv {
   }
 
   getDashboardOpened() {
-    let impressions = store.get(this.impressionKey(config)) || '[]';
+    let impressions = store.get(this.impressionKey()) || '[]';
 
     impressions = JSON.parse(impressions);
 
@@ -39,7 +39,7 @@ export class ImpressionSrv {
     return impressions;
   }
 
-  impressionKey(config) {
+  impressionKey() {
     return 'dashboard_impressions-' + config.bootData.user.orgId;
   }
 }

+ 13 - 12
public/app/core/services/keybindingSrv.ts

@@ -9,6 +9,7 @@ import { store } from 'app/store/store';
 import Mousetrap from 'mousetrap';
 import 'mousetrap-global-bind';
 import { ContextSrv } from './context_srv';
+import { ILocationService, ITimeoutService } from 'angular';
 
 export class KeybindingSrv {
   helpModal: boolean;
@@ -17,11 +18,11 @@ export class KeybindingSrv {
 
   /** @ngInject */
   constructor(
-    private $rootScope,
-    private $location,
-    private $timeout,
-    private datasourceSrv,
-    private timeSrv,
+    private $rootScope: any,
+    private $location: ILocationService,
+    private $timeout: ITimeoutService,
+    private datasourceSrv: any,
+    private timeSrv: any,
     private contextSrv: ContextSrv
   ) {
     // clear out all shortcuts on route change
@@ -114,10 +115,10 @@ export class KeybindingSrv {
     }
   }
 
-  bind(keyArg, fn) {
+  bind(keyArg: string | string[], fn: () => void) {
     Mousetrap.bind(
       keyArg,
-      evt => {
+      (evt: any) => {
         evt.preventDefault();
         evt.stopPropagation();
         evt.returnValue = false;
@@ -127,10 +128,10 @@ export class KeybindingSrv {
     );
   }
 
-  bindGlobal(keyArg, fn) {
+  bindGlobal(keyArg: string, fn: () => void) {
     Mousetrap.bindGlobal(
       keyArg,
-      evt => {
+      (evt: any) => {
         evt.preventDefault();
         evt.stopPropagation();
         evt.returnValue = false;
@@ -149,14 +150,14 @@ export class KeybindingSrv {
     this.$location.search(search);
   }
 
-  setupDashboardBindings(scope, dashboard) {
+  setupDashboardBindings(scope: any, dashboard: any) {
     this.bind('mod+o', () => {
       dashboard.graphTooltip = (dashboard.graphTooltip + 1) % 3;
       appEvents.emit('graph-hover-clear');
       dashboard.startRefresh();
     });
 
-    this.bind('mod+s', e => {
+    this.bind('mod+s', () => {
       scope.appEvent('save-dashboard');
     });
 
@@ -272,7 +273,7 @@ export class KeybindingSrv {
       dashboard.expandRows();
     });
 
-    this.bind('d n', e => {
+    this.bind('d n', () => {
       this.$location.url('/dashboard/new');
     });
 

+ 5 - 4
public/app/core/services/timer.ts

@@ -1,20 +1,21 @@
 import _ from 'lodash';
 import coreModule from 'app/core/core_module';
+import { ITimeoutService } from 'angular';
 
 // This service really just tracks a list of $timeout promises to give us a
 // method for canceling them all when we need to
 export class Timer {
-  timers = [];
+  timers: Array<angular.IPromise<any>> = [];
 
   /** @ngInject */
-  constructor(private $timeout) {}
+  constructor(private $timeout: ITimeoutService) {}
 
-  register(promise) {
+  register(promise: angular.IPromise<any>) {
     this.timers.push(promise);
     return promise;
   }
 
-  cancel(promise) {
+  cancel(promise: angular.IPromise<any>) {
     this.timers = _.without(this.timers, promise);
     this.$timeout.cancel(promise);
   }

+ 9 - 8
public/app/features/dashboard/services/TimeSrv.test.ts

@@ -1,5 +1,6 @@
-import { TimeSrv } from './TimeSrv';
 import moment from 'moment';
+import { TimeSrv } from './TimeSrv';
+import { ContextSrvStub } from 'test/specs/helpers';
 
 describe('timeSrv', () => {
   const rootScope = {
@@ -26,7 +27,7 @@ describe('timeSrv', () => {
   };
 
   beforeEach(() => {
-    timeSrv = new TimeSrv(rootScope, jest.fn(), location, timer, { isGrafanaVisibile: jest.fn() });
+    timeSrv = new TimeSrv(rootScope as any, jest.fn() as any, location as any, timer, new ContextSrvStub() as any);
     timeSrv.init(_dashboard);
     _dashboard.refresh = false;
   });
@@ -56,7 +57,7 @@ describe('timeSrv', () => {
         })),
       };
 
-      timeSrv = new TimeSrv(rootScope, jest.fn(), location, timer, { isGrafanaVisibile: jest.fn() });
+      timeSrv = new TimeSrv(rootScope as any, jest.fn() as any, location as any, timer, new ContextSrvStub() as any);
       timeSrv.init(_dashboard);
       const time = timeSrv.timeRange();
       expect(time.raw.from).toBe('now-2d');
@@ -71,7 +72,7 @@ describe('timeSrv', () => {
         })),
       };
 
-      timeSrv = new TimeSrv(rootScope, jest.fn(), location, timer, { isGrafanaVisibile: jest.fn() });
+      timeSrv = new TimeSrv(rootScope as any, jest.fn() as any, location as any, timer, new ContextSrvStub() as any);
 
       timeSrv.init(_dashboard);
       const time = timeSrv.timeRange();
@@ -87,7 +88,7 @@ describe('timeSrv', () => {
         })),
       };
 
-      timeSrv = new TimeSrv(rootScope, jest.fn(), location, timer, { isGrafanaVisibile: jest.fn() });
+      timeSrv = new TimeSrv(rootScope as any, jest.fn() as any, location as any, timer, new ContextSrvStub() as any);
 
       // dashboard saved with refresh on
       _dashboard.refresh = true;
@@ -104,7 +105,7 @@ describe('timeSrv', () => {
         })),
       };
 
-      timeSrv = new TimeSrv(rootScope, jest.fn(), location, timer, { isGrafanaVisibile: jest.fn() });
+      timeSrv = new TimeSrv(rootScope as any, jest.fn() as any, location as any, timer, new ContextSrvStub() as any);
 
       timeSrv.init(_dashboard);
       const time = timeSrv.timeRange();
@@ -120,7 +121,7 @@ describe('timeSrv', () => {
         })),
       };
 
-      timeSrv = new TimeSrv(rootScope, jest.fn(), location, timer, { isGrafanaVisibile: jest.fn() });
+      timeSrv = new TimeSrv(rootScope as any, jest.fn() as any, location as any, timer, new ContextSrvStub() as any);
 
       timeSrv.init(_dashboard);
       const time = timeSrv.timeRange();
@@ -136,7 +137,7 @@ describe('timeSrv', () => {
         })),
       };
 
-      timeSrv = new TimeSrv(rootScope, jest.fn(), location, timer, { isGrafanaVisibile: jest.fn() });
+      timeSrv = new TimeSrv(rootScope as any, jest.fn() as any, location as any, timer, new ContextSrvStub() as any);
 
       _dashboard.time.from = 'now-6h';
       timeSrv.init(_dashboard);

+ 20 - 11
public/app/features/dashboard/services/TimeSrv.ts

@@ -8,19 +8,28 @@ import coreModule from 'app/core/core_module';
 import * as dateMath from 'app/core/utils/datemath';
 
 // Types
-import { TimeRange } from '@grafana/ui';
+import { TimeRange, RawTimeRange } from '@grafana/ui';
+import { ITimeoutService, ILocationService } from 'angular';
+import { ContextSrv } from 'app/core/services/context_srv';
+import { DashboardModel } from '../state/DashboardModel';
 
 export class TimeSrv {
   time: any;
   refreshTimer: any;
-  refresh: boolean;
+  refresh: any;
   oldRefresh: boolean;
-  dashboard: any;
+  dashboard: Partial<DashboardModel>;
   timeAtLoad: any;
   private autoRefreshBlocked: boolean;
 
   /** @ngInject */
-  constructor($rootScope, private $timeout, private $location, private timer, private contextSrv) {
+  constructor(
+    $rootScope: any,
+    private $timeout: ITimeoutService,
+    private $location: ILocationService,
+    private timer: any,
+    private contextSrv: ContextSrv
+  ) {
     // default time
     this.time = { from: '6h', to: 'now' };
 
@@ -35,7 +44,7 @@ export class TimeSrv {
     });
   }
 
-  init(dashboard) {
+  init(dashboard: Partial<DashboardModel>) {
     this.timer.cancelAll();
 
     this.dashboard = dashboard;
@@ -63,7 +72,7 @@ export class TimeSrv {
     }
   }
 
-  private parseUrlParam(value) {
+  private parseUrlParam(value: any) {
     if (value.indexOf('now') !== -1) {
       return value;
     }
@@ -121,7 +130,7 @@ export class TimeSrv {
     return this.timeAtLoad && (this.timeAtLoad.from !== this.time.from || this.timeAtLoad.to !== this.time.to);
   }
 
-  setAutoRefresh(interval) {
+  setAutoRefresh(interval: any) {
     this.dashboard.refresh = interval;
     this.cancelNextRefresh();
 
@@ -153,7 +162,7 @@ export class TimeSrv {
     this.dashboard.timeRangeUpdated(this.timeRange());
   }
 
-  private startNextRefreshTimer(afterMs) {
+  private startNextRefreshTimer(afterMs: number) {
     this.cancelNextRefresh();
     this.refreshTimer = this.timer.register(
       this.$timeout(() => {
@@ -171,7 +180,7 @@ export class TimeSrv {
     this.timer.cancel(this.refreshTimer);
   }
 
-  setTime(time, fromRouteUpdate?) {
+  setTime(time: RawTimeRange, fromRouteUpdate?: boolean) {
     _.extend(this.time, time);
 
     // disable refresh if zoom in or zoom out
@@ -224,7 +233,7 @@ export class TimeSrv {
     };
   }
 
-  zoomOut(e, factor) {
+  zoomOut(e: any, factor: number) {
     const range = this.timeRange();
 
     const timespan = range.to.valueOf() - range.from.valueOf();
@@ -237,7 +246,7 @@ export class TimeSrv {
   }
 }
 
-let singleton;
+let singleton: TimeSrv;
 
 export function setTimeSrv(srv: TimeSrv) {
   singleton = srv;

+ 1 - 1
public/app/features/teams/TeamPages.tsx

@@ -126,7 +126,7 @@ export class TeamPages extends PureComponent<Props, State> {
 function mapStateToProps(state) {
   const teamId = getRouteParamsId(state.location);
   const pageName = getRouteParamsPage(state.location) || 'members';
-  const teamLoadingNav = getTeamLoadingNav(pageName);
+  const teamLoadingNav = getTeamLoadingNav(pageName as string);
   const navModel = getNavModel(state.navIndex, `team-${pageName}-${teamId}`, teamLoadingNav);
   const team = getTeam(state.team, teamId);
   const members = getTeamMembers(state.team);

+ 2 - 0
public/test/specs/helpers.ts

@@ -172,6 +172,8 @@ export class TimeSrvStub {
 }
 
 export class ContextSrvStub {
+  isGrafanaVisibile = jest.fn();
+
   hasRole() {
     return true;
   }