Commit 09de46e5 by bergquist

tech(search): convert search to typescript

parent 92cba940
<div ng-controller="SearchCtrl" ng-init="init()" class="search-box">
<div class="search-field-wrapper">
<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>
<div class="search-switches">
<i class="fa fa-filter"></i>
<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
</a> |
<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
</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>
{{tagName}}
</a>
......@@ -27,7 +25,7 @@
</div>
</div>
<div class="search-results-container" ng-if="tagsMode">
<div class="search-results-container" ng-if="ctrl.tagsMode">
<div class="row">
<div class="span6 offset1">
<div ng-repeat="tag in results" class="pointer" style="width: 180px; float: left;"
......@@ -42,14 +40,14 @@
</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}}">
<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}}
</span>
<i class="fa" ng-class="{'fa-star': row.isStarred, 'fa-star-o': !row.isStarred}"></i>
......@@ -63,15 +61,14 @@
</div>
<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>
New
</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>
Import
</a>
<div class="clearfix"></div>
</div>
</div>
///<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);
......@@ -23,6 +23,7 @@ import './partials';
import {grafanaAppDirective} from './components/grafana_app';
import {sideMenuDirective} from './components/sidemenu/sidemenu';
import {searchDirective} from './components/search/search';
import {navbarDirective} from './components/navbar/navbar';
import {arrayJoin} from './directives/array_join';
import 'app/core/controllers/all';
......@@ -31,4 +32,4 @@ import 'app/core/routes/all';
import './filters/filters';
import coreModule from './core_module';
export {arrayJoin, coreModule, grafanaAppDirective, sideMenuDirective, navbarDirective};
export {arrayJoin, coreModule, grafanaAppDirective, sideMenuDirective, navbarDirective, searchDirective};
......@@ -29,7 +29,7 @@ function (angular, $) {
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);
$compile(elem.contents())(editorScope);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment