浏览代码

Chore: Typescript no-implicit any fixes progress (#17018)

* Chore: Typescript no-implicit any fixes progress

* Fixed tests

* Updated snapshot
Torkel Ödegaard 6 年之前
父节点
当前提交
f12d47ef52
共有 35 个文件被更改,包括 111 次插入233 次删除
  1. 7 9
      packages/grafana-ui/src/components/Select/Select.tsx
  2. 2 0
      packages/grafana-ui/src/types/navModel.ts
  3. 0 2
      public/app/core/angular_wrappers.ts
  4. 2 2
      public/app/core/components/AppNotifications/AppNotificationItem.tsx
  5. 4 4
      public/app/core/components/AppNotifications/AppNotificationList.tsx
  6. 2 2
      public/app/core/components/OrgActionBar/OrgActionBar.tsx
  7. 2 2
      public/app/core/components/PageHeader/PageHeader.test.tsx
  8. 3 3
      public/app/core/components/PermissionList/AddPermission.tsx
  9. 6 6
      public/app/core/components/PermissionList/PermissionListItem.tsx
  10. 2 1
      public/app/core/components/PluginHelp/PluginHelp.tsx
  11. 3 3
      public/app/core/components/Select/MetricSelect.tsx
  12. 1 0
      public/app/core/components/Select/TeamPicker.test.tsx
  13. 3 3
      public/app/core/components/Select/TeamPicker.tsx
  14. 1 0
      public/app/core/components/Select/UserPicker.test.tsx
  15. 3 3
      public/app/core/components/Select/UserPicker.tsx
  16. 2 2
      public/app/core/components/SharedPreferences/SharedPreferences.tsx
  17. 4 4
      public/app/core/components/code_editor/code_editor.ts
  18. 2 2
      public/app/core/components/colorpicker/spectrum_picker.ts
  19. 0 12
      public/app/core/components/navbar/navbar.html
  20. 0 54
      public/app/core/components/navbar/navbar.ts
  21. 6 6
      public/app/core/components/query_part/query_part.ts
  22. 11 11
      public/app/core/components/query_part/query_part_editor.ts
  23. 2 1
      public/app/core/components/scroll/scroll.ts
  24. 1 0
      public/app/core/components/search/SearchField.tsx
  25. 0 67
      public/app/core/components/search/SearchResult.tsx
  26. 14 11
      public/app/core/components/search/search.ts
  27. 7 7
      public/app/core/components/search/search_results.ts
  28. 5 3
      public/app/core/components/sidemenu/BottomNavLinks.test.tsx
  29. 4 3
      public/app/core/components/sidemenu/BottomNavLinks.tsx
  30. 3 2
      public/app/core/components/sidemenu/BottomSection.tsx
  31. 2 1
      public/app/core/components/sidemenu/SideMenuDropDown.tsx
  32. 3 1
      public/app/core/components/sidemenu/__snapshots__/BottomNavLinks.test.tsx.snap
  33. 0 2
      public/app/core/core.ts
  34. 2 4
      public/app/features/teams/__snapshots__/TeamMemberRow.test.tsx.snap
  35. 2 0
      public/app/types/acl.ts

+ 7 - 9
packages/grafana-ui/src/components/Select/Select.tsx

@@ -55,11 +55,11 @@ export interface CommonProps<T> {
   onCloseMenu?: () => void;
 }
 
-export interface SelectProps<T> {
+export interface SelectProps<T> extends CommonProps<T> {
   options: Array<SelectOptionItem<T>>;
 }
 
-interface AsyncProps<T> {
+interface AsyncProps<T> extends CommonProps<T> {
   defaultOptions: boolean;
   loadOptions: (query: string) => Promise<Array<SelectOptionItem<T>>>;
   loadingMessage?: () => string;
@@ -95,9 +95,8 @@ export const MenuList = (props: any) => {
   );
 };
 
-export class Select<T> extends PureComponent<CommonProps<T> & SelectProps<T>> {
-  static defaultProps = {
-    width: null,
+export class Select<T> extends PureComponent<SelectProps<T>> {
+  static defaultProps: Partial<SelectProps<any>> = {
     className: '',
     isDisabled: false,
     isSearchable: true,
@@ -108,7 +107,7 @@ export class Select<T> extends PureComponent<CommonProps<T> & SelectProps<T>> {
     isLoading: false,
     backspaceRemovesValue: true,
     maxMenuHeight: 300,
-    menuIsOpen: false,
+    isOpen: false,
     components: {
       Option: SelectOption,
       SingleValue,
@@ -201,9 +200,8 @@ export class Select<T> extends PureComponent<CommonProps<T> & SelectProps<T>> {
   }
 }
 
-export class AsyncSelect<T> extends PureComponent<CommonProps<T> & AsyncProps<T>> {
-  static defaultProps = {
-    width: null,
+export class AsyncSelect<T> extends PureComponent<AsyncProps<T>> {
+  static defaultProps: Partial<AsyncProps<any>> = {
     className: '',
     components: {},
     loadingMessage: () => 'Loading...',

+ 2 - 0
packages/grafana-ui/src/types/navModel.ts

@@ -7,11 +7,13 @@ export interface NavModelItem {
   id?: string;
   active?: boolean;
   hideFromTabs?: boolean;
+  hideFromMenu?: boolean;
   divider?: boolean;
   children?: NavModelItem[];
   breadcrumbs?: NavModelBreadcrumb[];
   target?: string;
   parentItem?: NavModelItem;
+  showOrgSwitcher?: boolean;
 }
 
 export interface NavModel {

+ 0 - 2
public/app/core/angular_wrappers.ts

@@ -4,7 +4,6 @@ import { AnnotationQueryEditor as StackdriverAnnotationQueryEditor } from 'app/p
 import { PasswordStrength } from './components/PasswordStrength';
 import PageHeader from './components/PageHeader/PageHeader';
 import EmptyListCTA from './components/EmptyListCTA/EmptyListCTA';
-import { SearchResult } from './components/search/SearchResult';
 import { TagFilter } from './components/TagFilter/TagFilter';
 import { SideMenu } from './components/sidemenu/SideMenu';
 import { MetricSelect } from './components/Select/MetricSelect';
@@ -20,7 +19,6 @@ export function registerAngularDirectives() {
   react2AngularDirective('appNotificationsList', AppNotificationList, []);
   react2AngularDirective('pageHeader', PageHeader, ['model', 'noTabs']);
   react2AngularDirective('emptyListCta', EmptyListCTA, ['model']);
-  react2AngularDirective('searchResult', SearchResult, []);
   react2AngularDirective('searchField', SearchField, [
     'query',
     'autoFocus',

+ 2 - 2
public/app/core/components/AppNotifications/AppNotificationItem.tsx

@@ -4,11 +4,11 @@ import { AlertBox } from '../AlertBox/AlertBox';
 
 interface Props {
   appNotification: AppNotification;
-  onClearNotification: (id) => void;
+  onClearNotification: (id: number) => void;
 }
 
 export default class AppNotificationItem extends Component<Props> {
-  shouldComponentUpdate(nextProps) {
+  shouldComponentUpdate(nextProps: Props) {
     return this.props.appNotification.id !== nextProps.appNotification.id;
   }
 

+ 4 - 4
public/app/core/components/AppNotifications/AppNotificationList.tsx

@@ -20,12 +20,12 @@ export class AppNotificationList extends PureComponent<Props> {
   componentDidMount() {
     const { notifyApp } = this.props;
 
-    appEvents.on('alert-warning', options => notifyApp(createWarningNotification(options[0], options[1])));
-    appEvents.on('alert-success', options => notifyApp(createSuccessNotification(options[0], options[1])));
-    appEvents.on('alert-error', options => notifyApp(createErrorNotification(options[0], options[1])));
+    appEvents.on('alert-warning', (options: string[]) => notifyApp(createWarningNotification(options[0], options[1])));
+    appEvents.on('alert-success', (options: string[]) => notifyApp(createSuccessNotification(options[0], options[1])));
+    appEvents.on('alert-error', (options: string[]) => notifyApp(createErrorNotification(options[0], options[1])));
   }
 
-  onClearAppNotification = id => {
+  onClearAppNotification = (id: number) => {
     this.props.clearAppNotification(id);
   };
 

+ 2 - 2
public/app/core/components/OrgActionBar/OrgActionBar.tsx

@@ -14,10 +14,10 @@ export interface Props {
 export default class OrgActionBar extends PureComponent<Props> {
   render() {
     const { searchQuery, layoutMode, onSetLayoutMode, linkButton, setSearchQuery, target } = this.props;
-    const linkProps = { href: linkButton.href, target: undefined };
+    const linkProps = { href: linkButton.href };
 
     if (target) {
-      linkProps.target = target;
+      (linkProps as any).target = target;
     }
 
     return (

+ 2 - 2
public/app/core/components/PageHeader/PageHeader.test.tsx

@@ -1,9 +1,9 @@
 import React from 'react';
 import PageHeader from './PageHeader';
-import { shallow } from 'enzyme';
+import { shallow, ShallowWrapper } from 'enzyme';
 
 describe('PageHeader', () => {
-  let wrapper;
+  let wrapper: ShallowWrapper<PageHeader>;
 
   describe('when the nav tree has a node with a title', () => {
     beforeAll(() => {

+ 3 - 3
public/app/core/components/PermissionList/AddPermission.tsx

@@ -22,7 +22,7 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> {
     showPermissionLevels: true,
   };
 
-  constructor(props) {
+  constructor(props: Props) {
     super(props);
     this.state = this.getCleanState();
   }
@@ -36,7 +36,7 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> {
     };
   }
 
-  onTypeChanged = evt => {
+  onTypeChanged = (evt: any) => {
     const type = evt.target.value as AclTarget;
 
     switch (type) {
@@ -65,7 +65,7 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> {
     this.setState({ permission: permission.value });
   };
 
-  onSubmit = async evt => {
+  onSubmit = async (evt: React.SyntheticEvent) => {
     evt.preventDefault();
     await this.props.onAddPermission(this.state);
     this.setState(this.getCleanState());

+ 6 - 6
public/app/core/components/PermissionList/PermissionListItem.tsx

@@ -1,13 +1,13 @@
 import React, { PureComponent } from 'react';
-import { Select } from '@grafana/ui';
+import { Select, SelectOptionItem } from '@grafana/ui';
 import { dashboardPermissionLevels, DashboardAcl, PermissionLevel } from 'app/types/acl';
 import { FolderInfo } from 'app/types';
 
-const setClassNameHelper = inherited => {
+const setClassNameHelper = (inherited: boolean) => {
   return inherited ? 'gf-form-disabled' : '';
 };
 
-function ItemAvatar({ item }) {
+function ItemAvatar({ item }: { item: DashboardAcl }) {
   if (item.userAvatarUrl) {
     return <img className="filter-table__avatar" src={item.userAvatarUrl} />;
   }
@@ -21,7 +21,7 @@ function ItemAvatar({ item }) {
   return <i style={{ width: '25px', height: '25px' }} className="gicon gicon-viewer" />;
 }
 
-function ItemDescription({ item }) {
+function ItemDescription({ item }: { item: DashboardAcl }) {
   if (item.userId) {
     return <span className="filter-table__weak-italic">(User)</span>;
   }
@@ -39,8 +39,8 @@ interface Props {
 }
 
 export default class PermissionsListItem extends PureComponent<Props> {
-  onPermissionChanged = option => {
-    this.props.onPermissionChanged(this.props.item, option.value as PermissionLevel);
+  onPermissionChanged = (option: SelectOptionItem<PermissionLevel>) => {
+    this.props.onPermissionChanged(this.props.item, option.value);
   };
 
   onRemoveItem = () => {

+ 2 - 1
public/app/core/components/PluginHelp/PluginHelp.tsx

@@ -1,4 +1,5 @@
 import React, { PureComponent } from 'react';
+// @ts-ignore
 import Remarkable from 'remarkable';
 import { getBackendSrv } from '../../services/backend_srv';
 
@@ -37,7 +38,7 @@ export class PluginHelp extends PureComponent<Props, State> {
 
     getBackendSrv()
       .get(`/api/plugins/${plugin.id}/markdown/${type}`)
-      .then(response => {
+      .then((response: string) => {
         const markdown = new Remarkable();
         const helpHtml = markdown.render(response);
 

+ 3 - 3
public/app/core/components/Select/MetricSelect.tsx

@@ -19,13 +19,13 @@ interface State {
 }
 
 export class MetricSelect extends React.Component<Props, State> {
-  static defaultProps = {
+  static defaultProps: Partial<Props> = {
     variables: [],
     options: [],
     isSearchable: true,
   };
 
-  constructor(props) {
+  constructor(props: Props) {
     super(props);
     this.state = { options: [] };
   }
@@ -45,7 +45,7 @@ export class MetricSelect extends React.Component<Props, State> {
     return nextProps.value !== this.props.value || !_.isEqual(nextOptions, this.state.options);
   }
 
-  buildOptions({ variables = [], options }) {
+  buildOptions({ variables = [], options }: Props) {
     return variables.length > 0 ? [this.getVariablesGroup(), ...options] : options;
   }
 

+ 1 - 0
public/app/core/components/Select/TeamPicker.test.tsx

@@ -1,4 +1,5 @@
 import React from 'react';
+// @ts-ignore
 import renderer from 'react-test-renderer';
 import { TeamPicker } from './TeamPicker';
 

+ 3 - 3
public/app/core/components/Select/TeamPicker.tsx

@@ -23,7 +23,7 @@ export interface State {
 export class TeamPicker extends Component<Props, State> {
   debouncedSearch: any;
 
-  constructor(props) {
+  constructor(props: Props) {
     super(props);
     this.state = { isLoading: false };
     this.search = this.search.bind(this);
@@ -42,8 +42,8 @@ export class TeamPicker extends Component<Props, State> {
       query = '';
     }
 
-    return backendSrv.get(`/api/teams/search?perpage=10&page=1&query=${query}`).then(result => {
-      const teams = result.teams.map(team => {
+    return backendSrv.get(`/api/teams/search?perpage=10&page=1&query=${query}`).then((result: any) => {
+      const teams = result.teams.map((team: any) => {
         return {
           id: team.id,
           value: team.id,

+ 1 - 0
public/app/core/components/Select/UserPicker.test.tsx

@@ -1,4 +1,5 @@
 import React from 'react';
+// @ts-ignore
 import renderer from 'react-test-renderer';
 import { UserPicker } from './UserPicker';
 

+ 3 - 3
public/app/core/components/Select/UserPicker.tsx

@@ -24,7 +24,7 @@ export interface State {
 export class UserPicker extends Component<Props, State> {
   debouncedSearch: any;
 
-  constructor(props) {
+  constructor(props: Props) {
     super(props);
     this.state = { isLoading: false };
     this.search = this.search.bind(this);
@@ -45,8 +45,8 @@ export class UserPicker extends Component<Props, State> {
 
     return backendSrv
       .get(`/api/org/users?query=${query}&limit=10`)
-      .then(result => {
-        return result.map(user => ({
+      .then((result: any) => {
+        return result.map((user: any) => ({
           id: user.userId,
           value: user.userId,
           label: user.login === user.email ? user.login : `${user.login} - ${user.email}`,

+ 2 - 2
public/app/core/components/SharedPreferences/SharedPreferences.tsx

@@ -27,7 +27,7 @@ const timezones = [
 export class SharedPreferences extends PureComponent<Props, State> {
   backendSrv: BackendSrv = getBackendSrv();
 
-  constructor(props) {
+  constructor(props: Props) {
     super(props);
 
     this.state = {
@@ -72,7 +72,7 @@ export class SharedPreferences extends PureComponent<Props, State> {
     });
   }
 
-  onSubmitForm = async event => {
+  onSubmitForm = async (event: React.SyntheticEvent) => {
     event.preventDefault();
 
     const { homeDashboardId, theme, timezone } = this.state;

+ 4 - 4
public/app/core/components/code_editor/code_editor.ts

@@ -55,7 +55,7 @@ const DEFAULT_SNIPPETS = true;
 
 const editorTemplate = `<div></div>`;
 
-function link(scope, elem, attrs) {
+function link(scope: any, elem: any, attrs: any) {
   // Options
   const langMode = attrs.mode || DEFAULT_MODE;
   const maxLines = attrs.maxLines || DEFAULT_MAX_LINES;
@@ -116,7 +116,7 @@ function link(scope, elem, attrs) {
   });
 
   // Sync with outer scope - update editor content if model has been changed from outside of directive.
-  scope.$watch('content', (newValue, oldValue) => {
+  scope.$watch('content', (newValue: any, oldValue: any) => {
     const editorValue = codeEditor.getValue();
     if (newValue !== editorValue && newValue !== oldValue) {
       scope.$$postDigest(() => {
@@ -142,7 +142,7 @@ function link(scope, elem, attrs) {
     },
   });
 
-  function setLangMode(lang) {
+  function setLangMode(lang: string) {
     ace.acequire('ace/ext/language_tools');
     codeEditor.setOptions({
       enableBasicAutocompletion: true,
@@ -170,7 +170,7 @@ function link(scope, elem, attrs) {
     codeEditor.setTheme(theme);
   }
 
-  function setEditorContent(value) {
+  function setEditorContent(value: string) {
     codeEditor.setValue(value);
     codeEditor.clearSelection();
   }

+ 2 - 2
public/app/core/components/colorpicker/spectrum_picker.ts

@@ -13,9 +13,9 @@ export function spectrumPicker() {
     scope: true,
     replace: true,
     template: '<color-picker color="ngModel.$viewValue" onChange="onColorChange"></color-picker>',
-    link: (scope, element, attrs, ngModel) => {
+    link: (scope: any, element: any, attrs: any, ngModel: any) => {
       scope.ngModel = ngModel;
-      scope.onColorChange = color => {
+      scope.onColorChange = (color: string) => {
         ngModel.$setViewValue(color);
       };
     },

+ 0 - 12
public/app/core/components/navbar/navbar.html

@@ -1,12 +0,0 @@
-<div class="page-nav">
-  <div class="page-breadcrumbs">
-    <a class="breadcrumb-item active" href="/">
-      <i class="fa fa-home"></i>
-    </a>
-    <a class="breadcrumb-item" ng-href="{{::item.url}}" ng-repeat="item in ctrl.model.breadcrumbs">
-      {{::item.text}}
-    </a>
-  </div>
-</div>
-
-<dashboard-search></dashboard-search>

+ 0 - 54
public/app/core/components/navbar/navbar.ts

@@ -1,54 +0,0 @@
-import coreModule from '../../core_module';
-import appEvents from 'app/core/app_events';
-import { NavModel } from '@grafana/ui';
-
-export class NavbarCtrl {
-  model: NavModel;
-
-  /** @ngInject */
-  constructor() {}
-
-  showSearch() {
-    appEvents.emit('show-dash-search');
-  }
-
-  navItemClicked(navItem, evt) {
-    if (navItem.clickHandler) {
-      navItem.clickHandler();
-      evt.preventDefault();
-    }
-  }
-}
-
-export function navbarDirective() {
-  return {
-    restrict: 'E',
-    templateUrl: 'public/app/core/components/navbar/navbar.html',
-    controller: NavbarCtrl,
-    bindToController: true,
-    controllerAs: 'ctrl',
-    scope: {
-      model: '=',
-    },
-    link: (scope, elem) => {},
-  };
-}
-
-export function pageH1() {
-  return {
-    restrict: 'E',
-    template: `
-    <h1 class="page-header__title">
-      <i class="page-header__icon {{::model.header.icon}}" ng-if="::model.header.icon"></i>
-      <img class="page-header__img" ng-src="{{::model.header.img}}" ng-if="::model.header.img"></i>
-      {{model.header.text}}
-    </h1>
-    `,
-    scope: {
-      model: '=',
-    },
-  };
-}
-
-coreModule.directive('pageH1', pageH1);
-coreModule.directive('navbar', navbarDirective);

+ 6 - 6
public/app/core/components/query_part/query_part.ts

@@ -40,7 +40,7 @@ export class QueryPart {
     return this.def.renderer(this, innerExpr);
   }
 
-  hasMultipleParamsInString(strValue, index) {
+  hasMultipleParamsInString(strValue: string, index: number) {
     if (strValue.indexOf(',') === -1) {
       return false;
     }
@@ -48,7 +48,7 @@ export class QueryPart {
     return this.def.params[index + 1] && this.def.params[index + 1].optional;
   }
 
-  updateParam(strValue, index) {
+  updateParam(strValue: string, index: number) {
     // handle optional parameters
     // if string contains ',' and next param is optional, split and update both
     if (this.hasMultipleParamsInString(strValue, index)) {
@@ -81,7 +81,7 @@ export class QueryPart {
   }
 }
 
-export function functionRenderer(part, innerExpr) {
+export function functionRenderer(part: any, innerExpr: string) {
   const str = part.def.type + '(';
   const parameters = _.map(part.params, (value, index) => {
     const paramType = part.def.params[index];
@@ -105,14 +105,14 @@ export function functionRenderer(part, innerExpr) {
   return str + parameters.join(', ') + ')';
 }
 
-export function suffixRenderer(part, innerExpr) {
+export function suffixRenderer(part: QueryPartDef, innerExpr: string) {
   return innerExpr + ' ' + part.params[0];
 }
 
-export function identityRenderer(part, innerExpr) {
+export function identityRenderer(part: QueryPartDef, innerExpr: string) {
   return part.params[0];
 }
 
-export function quotedIdentityRenderer(part, innerExpr) {
+export function quotedIdentityRenderer(part: QueryPartDef, innerExpr: string) {
   return '"' + part.params[0] + '"';
 }

+ 11 - 11
public/app/core/components/query_part/query_part_editor.ts

@@ -14,7 +14,7 @@ const template = `
 `;
 
 /** @ngInject */
-export function queryPartEditorDirective($compile, templateSrv) {
+export function queryPartEditorDirective(templateSrv: any) {
   const paramTemplate = '<input type="text" class="hide input-mini tight-form-func-param"></input>';
 
   return {
@@ -25,7 +25,7 @@ export function queryPartEditorDirective($compile, templateSrv) {
       handleEvent: '&',
       debounce: '@',
     },
-    link: function postLink($scope, elem) {
+    link: function postLink($scope: any, elem: any) {
       const part = $scope.part;
       const partDef = part.def;
       const $paramsContainer = elem.find('.query-part-parameters');
@@ -33,7 +33,7 @@ export function queryPartEditorDirective($compile, templateSrv) {
 
       $scope.partActions = [];
 
-      function clickFuncParam(this: any, paramIndex) {
+      function clickFuncParam(this: any, paramIndex: number) {
         /*jshint validthis:true */
         const $link = $(this);
         const $input = $link.next();
@@ -53,7 +53,7 @@ export function queryPartEditorDirective($compile, templateSrv) {
         }
       }
 
-      function inputBlur(this: any, paramIndex) {
+      function inputBlur(this: any, paramIndex: number) {
         /*jshint validthis:true */
         const $input = $(this);
         const $link = $input.prev();
@@ -72,7 +72,7 @@ export function queryPartEditorDirective($compile, templateSrv) {
         $link.show();
       }
 
-      function inputKeyPress(this: any, paramIndex, e) {
+      function inputKeyPress(this: any, paramIndex: number, e: any) {
         /*jshint validthis:true */
         if (e.which === 13) {
           inputBlur.call(this, paramIndex);
@@ -84,12 +84,12 @@ export function queryPartEditorDirective($compile, templateSrv) {
         this.style.width = (3 + this.value.length) * 8 + 'px';
       }
 
-      function addTypeahead($input, param, paramIndex) {
+      function addTypeahead($input: JQuery, param: any, paramIndex: number) {
         if (!param.options && !param.dynamicLookup) {
           return;
         }
 
-        const typeaheadSource = (query, callback) => {
+        const typeaheadSource = (query: string, callback: any) => {
           if (param.options) {
             let options = param.options;
             if (param.type === 'int') {
@@ -101,7 +101,7 @@ export function queryPartEditorDirective($compile, templateSrv) {
           }
 
           $scope.$apply(() => {
-            $scope.handleEvent({ $event: { name: 'get-param-options' } }).then(result => {
+            $scope.handleEvent({ $event: { name: 'get-param-options' } }).then((result: any) => {
               const dynamicOptions = _.map(result, op => {
                 return _.escape(op.value);
               });
@@ -116,7 +116,7 @@ export function queryPartEditorDirective($compile, templateSrv) {
           source: typeaheadSource,
           minLength: 0,
           items: 1000,
-          updater: value => {
+          updater: (value: string) => {
             value = _.unescape(value);
             setTimeout(() => {
               inputBlur.call($input[0], paramIndex);
@@ -138,12 +138,12 @@ export function queryPartEditorDirective($compile, templateSrv) {
       }
 
       $scope.showActionsMenu = () => {
-        $scope.handleEvent({ $event: { name: 'get-part-actions' } }).then(res => {
+        $scope.handleEvent({ $event: { name: 'get-part-actions' } }).then((res: any) => {
           $scope.partActions = res;
         });
       };
 
-      $scope.triggerPartAction = action => {
+      $scope.triggerPartAction = (action: string) => {
         $scope.handleEvent({ $event: { name: 'action', action: action } });
       };
 

+ 2 - 1
public/app/core/components/scroll/scroll.ts

@@ -1,4 +1,5 @@
 import $ from 'jquery';
+// @ts-ignore
 import baron from 'baron';
 import coreModule from 'app/core/core_module';
 
@@ -14,7 +15,7 @@ const scrollerClass = 'baron__scroller';
 export function geminiScrollbar() {
   return {
     restrict: 'A',
-    link: (scope, elem, attrs) => {
+    link: (scope: any, elem: any, attrs: any) => {
       let scrollRoot = elem.parent();
       const scroller = elem;
 

+ 1 - 0
public/app/core/components/search/SearchField.tsx

@@ -1,4 +1,5 @@
 import React, { useContext } from 'react';
+// @ts-ignore
 import tinycolor from 'tinycolor2';
 import { SearchQuery } from './search';
 import { css, cx } from 'emotion';

+ 0 - 67
public/app/core/components/search/SearchResult.tsx

@@ -1,67 +0,0 @@
-import React from 'react';
-import classNames from 'classnames';
-
-export class SearchResult extends React.Component<any, any> {
-  constructor(props) {
-    super(props);
-
-    this.state = {
-      search: '',
-    };
-  }
-
-  render() {
-    return this.state.search.sections.map(section => {
-      return <SearchResultSection section={section} key={section.id} />;
-    });
-  }
-}
-
-export interface SectionProps {
-  section: any;
-}
-
-export class SearchResultSection extends React.Component<SectionProps, any> {
-  constructor(props) {
-    super(props);
-  }
-
-  renderItem(item) {
-    return (
-      <a className="search-item" href={item.url} key={item.id}>
-        <span className="search-item__icon">
-          <i className="fa fa-th-large" />
-        </span>
-        <span className="search-item__body">
-          <div className="search-item__body-title">{item.title}</div>
-        </span>
-      </a>
-    );
-  }
-
-  toggleSection = () => {
-    this.props.section.toggle();
-  };
-
-  render() {
-    const collapseClassNames = classNames({
-      fa: true,
-      'fa-plus': !this.props.section.expanded,
-      'fa-minus': this.props.section.expanded,
-      'search-section__header__toggle': true,
-    });
-
-    return (
-      <div className="search-section" key={this.props.section.id}>
-        <div className="search-section__header">
-          <i className={classNames('search-section__header__icon', this.props.section.icon)} />
-          <span className="search-section__header__text">{this.props.section.title}</span>
-          <i className={collapseClassNames} onClick={this.toggleSection} />
-        </div>
-        {this.props.section.expanded && (
-          <div className="search-section__items">{this.props.section.items.map(this.renderItem)}</div>
-        )}
-      </div>
-    );
-  }
-}

+ 14 - 11
public/app/core/components/search/search.ts

@@ -6,6 +6,7 @@ import { contextSrv } from 'app/core/services/context_srv';
 import appEvents from 'app/core/app_events';
 import { parse, SearchParserOptions, SearchParserResult } from 'search-query-parser';
 import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
+
 export interface SearchQuery {
   query: string;
   parsedQuery: SearchParserResult;
@@ -32,6 +33,11 @@ class SearchQueryParser {
   }
 }
 
+interface SelectedIndicies {
+  dashboardIndex?: number;
+  folderIndex?: number;
+}
+
 export class SearchCtrl {
   isOpen: boolean;
   query: SearchQuery;
@@ -49,7 +55,7 @@ export class SearchCtrl {
   queryParser: SearchQueryParser;
 
   /** @ngInject */
-  constructor($scope, private $location, private $timeout, private searchSrv: SearchSrv) {
+  constructor($scope: any, private $location: any, private $timeout: any, private searchSrv: SearchSrv) {
     appEvents.on('show-dash-search', this.openSearch.bind(this), $scope);
     appEvents.on('hide-dash-search', this.closeSearch.bind(this), $scope);
     appEvents.on('search-query', debounce(this.search.bind(this), 500), $scope);
@@ -88,7 +94,7 @@ export class SearchCtrl {
     appEvents.emit('search-query');
   }
 
-  openSearch(evt, payload) {
+  openSearch(evt: any, payload: any) {
     if (this.isOpen) {
       this.closeSearch();
       return;
@@ -166,7 +172,7 @@ export class SearchCtrl {
     }, 100);
   }
 
-  moveSelection(direction) {
+  moveSelection(direction: number) {
     if (this.results.length === 0) {
       return;
     }
@@ -252,14 +258,14 @@ export class SearchCtrl {
     return query.query === '' && query.starred === false && query.tags.length === 0;
   }
 
-  filterByTag(tag) {
+  filterByTag(tag: string) {
     if (_.indexOf(this.query.tags, tag) === -1) {
       this.query.tags.push(tag);
       this.search();
     }
   }
 
-  removeTag(tag, evt) {
+  removeTag(tag: string, evt: any) {
     this.query.tags = _.without(this.query.tags, tag);
     this.search();
     this.giveSearchFocus = true;
@@ -298,14 +304,11 @@ export class SearchCtrl {
     this.moveSelection(0);
   }
 
-  private getFlattenedResultForNavigation(): Array<{
-    folderIndex: number;
-    dashboardIndex: number;
-  }> {
+  private getFlattenedResultForNavigation(): SelectedIndicies[] {
     let folderIndex = 0;
 
-    return _.flatMap(this.results, s => {
-      let result = [];
+    return _.flatMap(this.results, (s: any) => {
+      let result: SelectedIndicies[] = [];
 
       result.push({
         folderIndex: folderIndex,

+ 7 - 7
public/app/core/components/search/search_results.ts

@@ -10,15 +10,15 @@ export class SearchResultsCtrl {
   editable: boolean;
 
   /** @ngInject */
-  constructor(private $location) {}
+  constructor(private $location: any) {}
 
-  toggleFolderExpand(section) {
+  toggleFolderExpand(section: any) {
     if (section.toggle) {
       if (!section.expanded && this.onFolderExpanding) {
         this.onFolderExpanding();
       }
 
-      section.toggle(section).then(f => {
+      section.toggle(section).then((f: any) => {
         if (this.editable && f.expanded) {
           if (f.items) {
             _.each(f.items, i => {
@@ -34,7 +34,7 @@ export class SearchResultsCtrl {
     }
   }
 
-  navigateToFolder(section, evt) {
+  navigateToFolder(section: any, evt: any) {
     this.$location.path(section.url);
 
     if (evt) {
@@ -43,7 +43,7 @@ export class SearchResultsCtrl {
     }
   }
 
-  toggleSelection(item, evt) {
+  toggleSelection(item: any, evt: any) {
     item.checked = !item.checked;
 
     if (item.items) {
@@ -62,14 +62,14 @@ export class SearchResultsCtrl {
     }
   }
 
-  onItemClick(item) {
+  onItemClick(item: any) {
     //Check if one string can be found in the other
     if (this.$location.path().indexOf(item.url) > -1 || item.url.indexOf(this.$location.path()) > -1) {
       appEvents.emit('hide-dash-search');
     }
   }
 
-  selectTag(tag, evt) {
+  selectTag(tag: any, evt: any) {
     if (this.onTagSelected) {
       this.onTagSelected({ $tag: tag });
     }

+ 5 - 3
public/app/core/components/sidemenu/BottomNavLinks.test.tsx

@@ -10,7 +10,9 @@ jest.mock('../../app_events', () => ({
 const setup = (propOverrides?: object) => {
   const props = Object.assign(
     {
-      link: {},
+      link: {
+        text: 'Hello',
+      },
       user: {
         id: 1,
         isGrafanaAdmin: false,
@@ -87,9 +89,9 @@ describe('Functions', () => {
     const wrapper = setup();
     const mockEvent = { preventDefault: jest.fn() };
     it('should emit show modal event if url matches shortcut', () => {
-      const child = { url: '/shortcuts' };
+      const child = { url: '/shortcuts', text: 'hello' };
       const instance = wrapper.instance() as BottomNavLinks;
-      instance.itemClicked(mockEvent, child);
+      instance.itemClicked(mockEvent as any, child);
 
       expect(appEvents.emit).toHaveBeenCalledWith('show-modal', { templateHtml: '<help-modal></help-modal>' });
     });

+ 4 - 3
public/app/core/components/sidemenu/BottomNavLinks.tsx

@@ -1,14 +1,15 @@
 import React, { PureComponent } from 'react';
 import appEvents from '../../app_events';
 import { User } from '../../services/context_srv';
+import { NavModelItem } from '@grafana/ui';
 
 export interface Props {
-  link: any;
+  link: NavModelItem;
   user: User;
 }
 
 class BottomNavLinks extends PureComponent<Props> {
-  itemClicked = (event, child) => {
+  itemClicked = (event: React.SyntheticEvent, child: NavModelItem) => {
     if (child.url === '/shortcuts') {
       event.preventDefault();
       appEvents.emit('show-modal', {
@@ -57,7 +58,7 @@ class BottomNavLinks extends PureComponent<Props> {
             link.children.map((child, index) => {
               if (!child.hideFromMenu) {
                 return (
-                  <li className={child.divider} key={`${child.text}-${index}`}>
+                  <li key={`${child.text}-${index}`}>
                     <a href={child.url} target={child.target} onClick={event => this.itemClicked(event, child)}>
                       {child.icon && <i className={child.icon} />}
                       {child.text}

+ 3 - 2
public/app/core/components/sidemenu/BottomSection.tsx

@@ -4,10 +4,11 @@ import SignIn from './SignIn';
 import BottomNavLinks from './BottomNavLinks';
 import { contextSrv } from 'app/core/services/context_srv';
 import config from '../../config';
+import { NavModelItem } from '@grafana/ui';
 
 export default function BottomSection() {
-  const navTree: any = _.cloneDeep(config.bootData.navTree);
-  const bottomNav: any = _.filter(navTree, item => item.hideFromMenu);
+  const navTree: NavModelItem[] = _.cloneDeep(config.bootData.navTree);
+  const bottomNav: NavModelItem[] = _.filter(navTree, item => item.hideFromMenu);
   const isSignedIn = contextSrv.isSignedIn;
   const user = contextSrv.user;
 

+ 2 - 1
public/app/core/components/sidemenu/SideMenuDropDown.tsx

@@ -1,8 +1,9 @@
 import React, { FC } from 'react';
 import DropDownChild from './DropDownChild';
+import { NavModelItem } from '@grafana/ui';
 
 interface Props {
-  link: any;
+  link: NavModelItem;
 }
 
 const SideMenuDropDown: FC<Props> = props => {

+ 3 - 1
public/app/core/components/sidemenu/__snapshots__/BottomNavLinks.test.tsx.snap

@@ -67,7 +67,9 @@ exports[`Render should render component 1`] = `
     >
       <span
         className="sidemenu-item-text"
-      />
+      >
+        Hello
+      </span>
     </li>
   </ul>
 </div>

+ 0 - 2
public/app/core/core.ts

@@ -20,7 +20,6 @@ import { colors } from '@grafana/ui/';
 
 import { searchDirective } from './components/search/search';
 import { infoPopover } from './components/info_popover';
-import { navbarDirective } from './components/navbar/navbar';
 import { arrayJoin } from './directives/array_join';
 import { liveSrv } from './live/live_srv';
 import { Emitter } from './utils/emitter';
@@ -56,7 +55,6 @@ export {
   registerAngularDirectives,
   arrayJoin,
   coreModule,
-  navbarDirective,
   searchDirective,
   liveSrv,
   layoutSelector,

+ 2 - 4
public/app/features/teams/__snapshots__/TeamMemberRow.test.tsx.snap

@@ -97,9 +97,9 @@ exports[`Render when feature toggle editorsCanAdmin is turned off should not ren
           isDisabled={false}
           isLoading={false}
           isMulti={false}
+          isOpen={false}
           isSearchable={false}
           maxMenuHeight={300}
-          menuIsOpen={false}
           onChange={[Function]}
           openMenuOnFocus={false}
           options={
@@ -123,7 +123,6 @@ exports[`Render when feature toggle editorsCanAdmin is turned off should not ren
               "value": 0,
             }
           }
-          width={null}
         />
       </div>
     </td>
@@ -183,9 +182,9 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render p
           isDisabled={false}
           isLoading={false}
           isMulti={false}
+          isOpen={false}
           isSearchable={false}
           maxMenuHeight={300}
-          menuIsOpen={false}
           onChange={[Function]}
           openMenuOnFocus={false}
           options={
@@ -209,7 +208,6 @@ exports[`Render when feature toggle editorsCanAdmin is turned on should render p
               "value": 0,
             }
           }
-          width={null}
         />
       </div>
     </td>

+ 2 - 0
public/app/types/acl.ts

@@ -39,6 +39,8 @@ export interface DashboardAcl {
   name?: string;
   inherited?: boolean;
   sortRank?: number;
+  userAvatarUrl?: string;
+  teamAvatarUrl?: string;
 }
 
 export interface DashboardPermissionInfo {