tech(search): convert search to typescript

This commit is contained in:
bergquist
2016-01-26 17:54:19 +01:00
parent 92cba94031
commit 09de46e5ac
4 changed files with 161 additions and 19 deletions

View File

@@ -0,0 +1,74 @@
<div class="search-field-wrapper">
<span style="position: relative;">
<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="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="ctrl.tagsMode"></i>
tags
</a>
<span ng-if="ctrl.query.tag.length">
|
<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>
</span>
</span>
</div>
</div>
<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;"
ng-class="{'selected': $index === selectedIndex }"
ng-click="filterByTag(tag.term, $event)">
<a class="search-result-tag label label-tag" tag-color-from-name="tag.term">
<i class="fa fa-tag"></i>
<span>{{tag.term}} &nbsp;({{tag.count}})</span>
</a>
</div>
</div>
</div>
</div>
<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 ctrl.results"
ng-class="{'selected': $index == selectedIndex}" ng-href="{{row.url}}">
<span class="search-result-tags">
<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>
</span>
<span class="search-result-link">
<i class="fa search-result-icon"></i>
<span bo-text="row.title"></span>
</span>
</a>
</div>
<div class="search-button-row">
<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="ctrl.contextSrv.isEditor">
<i class="fa fa-download"></i>
Import
</a>
<div class="clearfix"></div>
</div>

View File

@@ -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);