Просмотр исходного кода

tech(search): convert search to typescript

bergquist 10 лет назад
Родитель
Сommit
09de46e5ac

+ 14 - 17
public/app/partials/search.html → public/app/core/components/search/search.html

@@ -1,24 +1,22 @@
-<div ng-controller="SearchCtrl" ng-init="init()" class="search-box">
-
 	<div class="search-field-wrapper">
 	<div class="search-field-wrapper">
 		<span style="position: relative;">
 		<span style="position: relative;">
-			<input  type="text" placeholder="Find dashboards by name" give-focus="giveSearchFocus" tabindex="1"
-			ng-keydown="keyDown($event)" ng-model="query.query" ng-model-options="{ debounce: 500 }" spellcheck='false' ng-change="search()" />
+			<input  type="text" placeholder="Find dashboards by name" give-focus="ctrl.giveSearchFocus" tabindex="1"
+			ng-keydown="ctrl.keyDown($event)" ng-model="ctrl.query.query" ng-model-options="{ debounce: 500 }" spellcheck='false' ng-change="ctrl.search()" />
 		</span>
 		</span>
 		<div class="search-switches">
 		<div class="search-switches">
 			<i class="fa fa-filter"></i>
 			<i class="fa fa-filter"></i>
 			<a class="pointer" href="javascript:void 0;" ng-click="showStarred()" tabindex="2">
 			<a class="pointer" href="javascript:void 0;" ng-click="showStarred()" tabindex="2">
-				<i class="fa fa-remove" ng-show="query.starred"></i>
+				<i class="fa fa-remove" ng-show="ctrl.query.starred"></i>
 				starred
 				starred
 			</a> |
 			</a> |
 			<a class="pointer" href="javascript:void 0;" ng-click="getTags()" tabindex="3">
 			<a class="pointer" href="javascript:void 0;" ng-click="getTags()" tabindex="3">
-				<i class="fa fa-remove" ng-show="tagsMode"></i>
+				<i class="fa fa-remove" ng-show="ctrl.tagsMode"></i>
 				tags
 				tags
 			</a>
 			</a>
-			<span ng-if="query.tag.length">
+			<span ng-if="ctrl.query.tag.length">
 				|
 				|
-				<span ng-repeat="tagName in query.tag">
-					<a ng-click="removeTag(tagName, $event)" tag-color-from-name="tagName" class="label label-tag">
+				<span ng-repeat="tagName in ctrl.query.tag">
+					<a ng-click="ctrl.removeTag(tagName, $event)" tag-color-from-name="ctrl.tagName" class="label label-tag">
 						<i class="fa fa-remove"></i>
 						<i class="fa fa-remove"></i>
 						{{tagName}}
 						{{tagName}}
 					</a>
 					</a>
@@ -27,7 +25,7 @@
 		</div>
 		</div>
 	</div>
 	</div>
 
 
-	<div class="search-results-container" ng-if="tagsMode">
+	<div class="search-results-container" ng-if="ctrl.tagsMode">
 		<div class="row">
 		<div class="row">
 			<div class="span6 offset1">
 			<div class="span6 offset1">
 				<div ng-repeat="tag in results" class="pointer" style="width: 180px; float: left;"
 				<div ng-repeat="tag in results" class="pointer" style="width: 180px; float: left;"
@@ -42,14 +40,14 @@
 		</div>
 		</div>
 	</div>
 	</div>
 
 
-	<div class="search-results-container" ng-if="!tagsMode">
-		<h6 ng-hide="results.length">No dashboards matching your query were found.</h6>
+	<div class="search-results-container" ng-if="!ctrl.tagsMode">
+		<h6 ng-hide="ctrl.results.length">No dashboards matching your query were found.</h6>
 
 
-		<a class="search-item pointer search-item-{{row.type}}" bindonce ng-repeat="row in results"
+		<a class="search-item pointer search-item-{{row.type}}" bindonce ng-repeat="row in ctrl.results"
 			ng-class="{'selected': $index == selectedIndex}" ng-href="{{row.url}}">
 			ng-class="{'selected': $index == selectedIndex}" ng-href="{{row.url}}">
 
 
 			<span class="search-result-tags">
 			<span class="search-result-tags">
-				<span ng-click="filterByTag(tag, $event)" ng-repeat="tag in row.tags" tag-color-from-name="tag"  class="label label-tag">
+				<span ng-click="ctrl.filterByTag(tag, $event)" ng-repeat="tag in ctrl.row.tags" tag-color-from-name="tag"  class="label label-tag">
 					{{tag}}
 					{{tag}}
 				</span>
 				</span>
 				<i class="fa" ng-class="{'fa-star': row.isStarred, 'fa-star-o': !row.isStarred}"></i>
 				<i class="fa" ng-class="{'fa-star': row.isStarred, 'fa-star-o': !row.isStarred}"></i>
@@ -63,15 +61,14 @@
 	</div>
 	</div>
 
 
 	<div class="search-button-row">
 	<div class="search-button-row">
-		<button class="btn btn-inverse pull-left" ng-click="newDashboard()" ng-show="contextSrv.isEditor">
+		<button class="btn btn-inverse pull-left" ng-click="ctrl.newDashboard()" ng-show="ctrl.contextSrv.isEditor">
 			<i class="fa fa-plus"></i>
 			<i class="fa fa-plus"></i>
 			New
 			New
 		</button>
 		</button>
-		<a class="btn btn-inverse pull-left" href="import/dashboard" ng-show="contextSrv.isEditor">
+		<a class="btn btn-inverse pull-left" href="import/dashboard" ng-show="ctrl.contextSrv.isEditor">
 			<i class="fa fa-download"></i>
 			<i class="fa fa-download"></i>
 			Import
 			Import
 		</a>
 		</a>
 		<div class="clearfix"></div>
 		<div class="clearfix"></div>
 	</div>
 	</div>
 
 
-</div>

+ 144 - 0
public/app/core/components/search/search.ts

@@ -0,0 +1,144 @@
+///<reference path="../../../headers/common.d.ts" />
+
+import angular from 'angular';
+import config from 'app/core/config';
+import _ from 'lodash';
+import $ from 'jquery';
+import coreModule from '../../core_module';
+
+export class SearchCtrl {
+  query: any;
+  giveSearchFocus: number;
+  selectedIndex: number;
+  results: any;
+  currentSearchId: number;
+  tagsMode: boolean;
+  showImport: boolean;
+
+  /** @ngInject */
+  constructor(private $scope, private $location, private $timeout, private backendSrv, private contextSrv) {
+    this.giveSearchFocus = 0;
+    this.selectedIndex = -1;
+    this.results = [];
+    this.query = { query: '', tag: [], starred: false };
+    this.currentSearchId = 0;
+
+    $timeout(() => {
+      this.giveSearchFocus = this.giveSearchFocus + 1;
+      this.query.query = '';
+      this.search();
+    }, 100);
+  }
+
+  keyDown(evt) {
+    if (evt.keyCode === 27) {
+      this.$scope.dismiss();
+    }
+    if (evt.keyCode === 40) {
+      this.moveSelection(1);
+    }
+    if (evt.keyCode === 38) {
+      this.moveSelection(-1);
+    }
+    if (evt.keyCode === 13) {
+      if (this.$scope.tagMode) {
+        var tag = this.results[this.selectedIndex];
+        if (tag) {
+          this.filterByTag(tag.term, null);
+        }
+        return;
+      }
+
+      var selectedDash = this.results[this.selectedIndex];
+      if (selectedDash) {
+        this.$location.search({});
+        this.$location.path(selectedDash.url);
+      }
+    }
+  }
+
+  moveSelection(direction) {
+    var max = (this.results || []).length;
+    var newIndex = this.selectedIndex + direction;
+    this.selectedIndex = ((newIndex %= max) < 0) ? newIndex + max : newIndex;
+  }
+
+  searchDashboards() {
+    this.tagsMode = false;
+    this.currentSearchId = this.currentSearchId + 1;
+    var localSearchId = this.currentSearchId;
+
+    return this.backendSrv.search(this.query).then((results) => {
+      if (localSearchId < this.currentSearchId) { return; }
+
+      this.results = _.map(results, function(dash) {
+        dash.url = 'dashboard/' + dash.uri;
+        return dash;
+      });
+
+      if (this.queryHasNoFilters()) {
+        this.results.unshift({ title: 'Home', url: config.appSubUrl + '/', type: 'dash-home' });
+      }
+    });
+  }
+
+  queryHasNoFilters() {
+    var query = this.query;
+    return query.query === '' && query.starred === false && query.tag.length === 0;
+  };
+
+  filterByTag(tag, evt) {
+    this.query.tag.push(tag);
+    this.search();
+    this.giveSearchFocus = this.giveSearchFocus + 1;
+    if (evt) {
+      evt.stopPropagation();
+      evt.preventDefault();
+    }
+  };
+
+  removeTag(tag, evt) {
+    this.query.tag = _.without(this.query.tag, tag);
+    this.search();
+    this.giveSearchFocus = this.giveSearchFocus + 1;
+    evt.stopPropagation();
+    evt.preventDefault();
+  };
+
+  getTags() {
+    return this.backendSrv.get('/api/dashboards/tags').then((results) => {
+      this.tagsMode = true;
+      this.results = results;
+      this.giveSearchFocus = this.giveSearchFocus + 1;
+    });
+  };
+
+  showStarred() {
+    this.query.starred = !this.query.starred;
+    this.giveSearchFocus = this.giveSearchFocus + 1;
+    this.search();
+  };
+
+  search() {
+    this.showImport = false;
+    this.selectedIndex = 0;
+    this.searchDashboards();
+  };
+
+  newDashboard() {
+    this.$location.url('dashboard/new');
+  };
+}
+
+export function searchDirective() {
+  return {
+    restrict: 'E',
+    templateUrl: 'app/core/components/search/search.html',
+    controller: SearchCtrl,
+    bindToController: true,
+    controllerAs: 'ctrl',
+    scope: {},
+  };
+}
+
+coreModule.directive('search', searchDirective);

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

@@ -23,6 +23,7 @@ import './partials';
 
 
 import {grafanaAppDirective} from './components/grafana_app';
 import {grafanaAppDirective} from './components/grafana_app';
 import {sideMenuDirective} from './components/sidemenu/sidemenu';
 import {sideMenuDirective} from './components/sidemenu/sidemenu';
+import {searchDirective} from './components/search/search';
 import {navbarDirective} from './components/navbar/navbar';
 import {navbarDirective} from './components/navbar/navbar';
 import {arrayJoin} from './directives/array_join';
 import {arrayJoin} from './directives/array_join';
 import 'app/core/controllers/all';
 import 'app/core/controllers/all';
@@ -31,4 +32,4 @@ import 'app/core/routes/all';
 import './filters/filters';
 import './filters/filters';
 import coreModule from './core_module';
 import coreModule from './core_module';
 
 
-export {arrayJoin, coreModule, grafanaAppDirective, sideMenuDirective, navbarDirective};
+export {arrayJoin, coreModule, grafanaAppDirective, sideMenuDirective, navbarDirective, searchDirective};

+ 1 - 1
public/app/features/dashboard/directives/dashSearchView.js

@@ -29,7 +29,7 @@ function (angular, $) {
               editorScope = null;
               editorScope = null;
             };
             };
 
 
-            var view = $('<div class="search-container" ng-include="\'app/partials/search.html\'"></div>');
+            var view = $('<search class="search-container"></search>');
 
 
             elem.append(view);
             elem.append(view);
             $compile(elem.contents())(editorScope);
             $compile(elem.contents())(editorScope);