mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(playlist): basic UI support for tags
This commit is contained in:
parent
12dfee544f
commit
a7de2ceae4
@ -1,5 +1,6 @@
|
||||
define([
|
||||
'./playlists_ctrl',
|
||||
'./playlist_search',
|
||||
'./playlist_srv',
|
||||
'./playlist_edit_ctrl',
|
||||
'./playlist_routes'
|
||||
|
@ -39,34 +39,24 @@
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<h4>Add dashboards</h4>
|
||||
|
||||
<div style="display: inline-block">
|
||||
<div class="tight-form last">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item">
|
||||
Search
|
||||
</li>
|
||||
<li>
|
||||
<input type="text"
|
||||
class="tight-form-input input-xlarge last"
|
||||
ng-model="ctrl.searchQuery"
|
||||
placeholder="dashboard search term"
|
||||
ng-trim="true"
|
||||
ng-change="ctrl.search()">
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="span5 pull-left">
|
||||
<h5>Search results ({{ctrl.filteredPlaylistItems.length}})</h5>
|
||||
<h5>Add dashboards</h5>
|
||||
<div style="">
|
||||
<playlist-search class="playlist-search-container" search-started="ctrl.searchStarted(promise)"></playlist-search>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="span5 pull-left" ng-if="ctrl.filteredDashboards.length > 0">
|
||||
<h5>Search results ({{ctrl.filteredDashboards.length}})</h5>
|
||||
<table class="grafana-options-table">
|
||||
<tr ng-repeat="playlistItem in ctrl.filteredPlaylistItems">
|
||||
<tr ng-repeat="playlistItem in ctrl.filteredDashboards">
|
||||
<td style="white-space: nowrap;">
|
||||
{{playlistItem.title}}
|
||||
</td>
|
||||
@ -77,13 +67,22 @@
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-if="ctrl.isSearchResultsEmpty()">
|
||||
<td colspan="2">
|
||||
<i class="fa fa-warning"></i> Search results empty
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="playlist-search-results-container" ng-if="ctrl.filteredTags.length > 0">
|
||||
<div class="row">
|
||||
<div class="span6 offset1">
|
||||
<div ng-repeat="tag in ctrl.filteredTags" class="pointer" style="width: 180px; float: left;"
|
||||
ng-class="{'selected': $index === selectedIndex }"
|
||||
ng-click="ctrl.addTagPlaylistItem(tag, $event)">
|
||||
<a class="search-result-tag label label-tag" tag-color-from-name="tag.term">
|
||||
<i class="fa fa-tag"></i>
|
||||
<span>{{tag.term}} ({{tag.count}})</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="span5 pull-left">
|
||||
<h5>Added dashboards</h5>
|
||||
<table class="grafana-options-table">
|
||||
|
26
public/app/features/playlist/partials/playlist_search.html
Normal file
26
public/app/features/playlist/partials/playlist_search.html
Normal file
@ -0,0 +1,26 @@
|
||||
<div class="playlist-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.searchDashboards()" />
|
||||
</span>
|
||||
<div class="playlist-search-switches">
|
||||
<i class="fa fa-filter"></i>
|
||||
<a class="pointer" href="javascript:void 0;" ng-click="ctrl.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="ctrl.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>
|
@ -6,14 +6,16 @@ import coreModule from '../../core/core_module';
|
||||
import config from 'app/core/config';
|
||||
|
||||
export class PlaylistEditCtrl {
|
||||
filteredPlaylistItems: any = [];
|
||||
foundPlaylistItems: any = [];
|
||||
filteredDashboards: any = [];
|
||||
filteredTags: any = [];
|
||||
searchQuery: string = '';
|
||||
loading: boolean = false;
|
||||
playlist: any = {
|
||||
interval: '10m',
|
||||
};
|
||||
playlistItems: any = [];
|
||||
dashboardresult: any = [];
|
||||
tagresult: any = [];
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private playlistSrv, private backendSrv, private $location, private $route) {
|
||||
@ -30,35 +32,18 @@ export class PlaylistEditCtrl {
|
||||
this.playlistItems = result;
|
||||
});
|
||||
}
|
||||
|
||||
this.search();
|
||||
}
|
||||
|
||||
search() {
|
||||
var query: any = {limit: 10};
|
||||
|
||||
if (this.searchQuery) {
|
||||
query.query = this.searchQuery;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
|
||||
this.backendSrv.search(query)
|
||||
.then((results) => {
|
||||
this.foundPlaylistItems = results;
|
||||
this.filterFoundPlaylistItems();
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
filterFoundPlaylistItems() {
|
||||
this.filteredPlaylistItems = _.reject(this.foundPlaylistItems, (playlistItem) => {
|
||||
console.log('filter !');
|
||||
console.log(this.dashboardresult);
|
||||
this.filteredDashboards = _.reject(this.dashboardresult, (playlistItem) => {
|
||||
return _.findWhere(this.playlistItems, (listPlaylistItem) => {
|
||||
return parseInt(listPlaylistItem.value) === playlistItem.id;
|
||||
});
|
||||
});
|
||||
|
||||
this.filteredTags = this.tagresult;
|
||||
};
|
||||
|
||||
addPlaylistItem(playlistItem) {
|
||||
@ -70,6 +55,20 @@ export class PlaylistEditCtrl {
|
||||
this.filterFoundPlaylistItems();
|
||||
};
|
||||
|
||||
addTagPlaylistItem(tag) {
|
||||
console.log(tag);
|
||||
|
||||
var playlistItem: any = {
|
||||
value: tag.term,
|
||||
type: 'dashboard_by_tag',
|
||||
order: this.playlistItems.length + 1,
|
||||
title: tag.term
|
||||
};
|
||||
|
||||
this.playlistItems.push(playlistItem);
|
||||
this.filterFoundPlaylistItems();
|
||||
}
|
||||
|
||||
removePlaylistItem(playlistItem) {
|
||||
_.remove(this.playlistItems, (listedPlaylistItem) => {
|
||||
return playlistItem === listedPlaylistItem;
|
||||
@ -104,7 +103,7 @@ export class PlaylistEditCtrl {
|
||||
};
|
||||
|
||||
isSearchResultsEmpty() {
|
||||
return !this.foundPlaylistItems.length;
|
||||
return !this.dashboardresult.length;
|
||||
};
|
||||
|
||||
isSearchQueryEmpty() {
|
||||
@ -119,6 +118,16 @@ export class PlaylistEditCtrl {
|
||||
return this.loading;
|
||||
};
|
||||
|
||||
searchStarted(promise) {
|
||||
promise.then((data) => {
|
||||
console.log('searchStarted: ', data);
|
||||
|
||||
this.dashboardresult = data.dashboardResult;
|
||||
this.tagresult = data.tagResult;
|
||||
this.filterFoundPlaylistItems();
|
||||
});
|
||||
};
|
||||
|
||||
movePlaylistItem(playlistItem, offset) {
|
||||
var currentPosition = this.playlistItems.indexOf(playlistItem);
|
||||
var newPosition = currentPosition + offset;
|
||||
|
95
public/app/features/playlist/playlist_search.ts
Normal file
95
public/app/features/playlist/playlist_search.ts
Normal file
@ -0,0 +1,95 @@
|
||||
///<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/core_module';
|
||||
|
||||
export class PlaylistSearchCtrl {
|
||||
query: any;
|
||||
tagsMode: boolean;
|
||||
|
||||
searchStarted: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private $location, private $timeout, private backendSrv, private contextSrv) {
|
||||
this.query = { query: '', tag: [], starred: false };
|
||||
|
||||
$timeout(() => {
|
||||
this.query.query = '';
|
||||
this.searchDashboards();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
searchDashboards() {
|
||||
this.tagsMode = false;
|
||||
var prom: any = {};
|
||||
|
||||
/*
|
||||
prom.promise = this.backendSrv.search(this.query).then((results) => {
|
||||
console.log('playlist_search_ctrl: ', results);
|
||||
return results;
|
||||
});
|
||||
*/
|
||||
prom.promise = this.backendSrv.search(this.query).then((result) => {
|
||||
return {
|
||||
dashboardResult: result,
|
||||
tagResult: []
|
||||
};
|
||||
});
|
||||
|
||||
this.searchStarted(prom);
|
||||
}
|
||||
|
||||
queryHasNoFilters() {
|
||||
return this.query.query === '' && this.query.starred === false && this.query.tag.length === 0;
|
||||
};
|
||||
|
||||
filterByTag(tag, evt) {
|
||||
this.query.tag.push(tag);
|
||||
this.searchDashboards();
|
||||
if (evt) {
|
||||
evt.stopPropagation();
|
||||
evt.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
getTags() {
|
||||
var prom: any = {};
|
||||
prom.promise = this.backendSrv.get('/api/dashboards/tags').then((result) => {
|
||||
console.log('getTags: result', result);
|
||||
return {
|
||||
dashboardResult: [],
|
||||
tagResult: result
|
||||
};
|
||||
});
|
||||
|
||||
this.searchStarted(prom);
|
||||
/*
|
||||
this.searchStarted(prom);
|
||||
|
||||
return this.backendSrv.get('/api/dashboards/tags').then((results) => {
|
||||
this.tagsMode = true;
|
||||
|
||||
|
||||
console.log(results);
|
||||
});
|
||||
*/
|
||||
};
|
||||
}
|
||||
|
||||
export function playlistSearchDirective() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
templateUrl: 'app/features/playlist/partials/playlist_search.html',
|
||||
controller: PlaylistSearchCtrl,
|
||||
bindToController: true,
|
||||
controllerAs: 'ctrl',
|
||||
scope: {
|
||||
searchStarted: '&'
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
coreModule.directive('playlistSearch', playlistSearchDirective);
|
@ -8,6 +8,7 @@
|
||||
@import "bootstrap-tagsinput.less";
|
||||
@import "tables_lists.less";
|
||||
@import "search.less";
|
||||
@import "playlist.less";
|
||||
@import "panel.less";
|
||||
@import "forms.less";
|
||||
@import "tightform.less";
|
||||
|
99
public/less/playlist.less
Normal file
99
public/less/playlist.less
Normal file
@ -0,0 +1,99 @@
|
||||
.playlist-search-container {
|
||||
//left: 59px;
|
||||
//top: 39px;
|
||||
margin: 15px;
|
||||
z-index: 1000;
|
||||
//position: relative;
|
||||
position: relative;
|
||||
width: 700px;
|
||||
box-shadow: 0px 0px 55px 0px black;
|
||||
//padding: 10px;
|
||||
background-color: @grafanaPanelBackground;
|
||||
//border: 1px solid @grafanaTargetFuncBackground;
|
||||
|
||||
.label-tag {
|
||||
margin-left: 6px;
|
||||
font-size: 11px;
|
||||
padding: 2px 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.playlist-search-switches {
|
||||
position: relative;
|
||||
top: -39px;
|
||||
right: -268px;
|
||||
}
|
||||
|
||||
.playlist-search-field-wrapper {
|
||||
//padding-bottom: 10px;
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 8px 8px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
button {
|
||||
margin: 0 4px 0 0;
|
||||
}
|
||||
> span {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.playlist-search-results-container {
|
||||
min-height: 100px;
|
||||
overflow: auto;
|
||||
display: block;
|
||||
line-height: 28px;
|
||||
|
||||
.search-item:hover, .search-item.selected {
|
||||
background-color: @grafanaListHighlight;
|
||||
}
|
||||
|
||||
.selected {
|
||||
.search-result-tag {
|
||||
opacity: 0.70;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.fa-star, .fa-star-o {
|
||||
padding-left: 13px;
|
||||
}
|
||||
|
||||
.fa-star {
|
||||
color: @orange;
|
||||
}
|
||||
|
||||
.search-result-link {
|
||||
color: @grafanaListMainLinkColor;
|
||||
.fa {
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.search-item {
|
||||
display: block;
|
||||
padding: 3px 10px;
|
||||
white-space: nowrap;
|
||||
background-color: @grafanaListBackground;
|
||||
margin-bottom: 4px;
|
||||
.search-result-icon:before {
|
||||
content: "\f009";
|
||||
}
|
||||
|
||||
&.search-item-dash-home .search-result-icon:before {
|
||||
content: "\f015";
|
||||
}
|
||||
}
|
||||
|
||||
.search-result-tags {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.search-result-actions {
|
||||
float: right;
|
||||
padding-left: 20px;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user