mirror of
https://github.com/grafana/grafana.git
synced 2025-01-15 19:22:34 -06:00
ux: search filter box
This commit is contained in:
parent
8141987303
commit
3d2d789ca2
@ -15,79 +15,74 @@
|
||||
ng-blur="ctrl.searchInputBlur()"
|
||||
/>
|
||||
|
||||
<div class="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="tagName" class="label label-tag">
|
||||
<i class="fa fa-remove"></i>
|
||||
{{tagName}}
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="search-field-spacer"></div>
|
||||
</div>
|
||||
|
||||
<div class="search-dropdown" ng-class="{'search-dropdown--fade-in': ctrl.openCompleted}">
|
||||
<div class="search-results-container" ng-if="ctrl.tagsMode">
|
||||
<div ng-repeat="tag in ctrl.results" class="pointer" style="width: 180px; float: left;"
|
||||
ng-class="{'selected': $index === ctrl.selectedIndex }"
|
||||
ng-click="ctrl.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}} ({{tag.count}})</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-dropdown">
|
||||
<div class="search-dropdown__col_1">
|
||||
<div class="search-results-container" grafana-scrollbar>
|
||||
<h6 ng-show="!ctrl.isLoading && results.length">No dashboards matching your query were found.</h6>
|
||||
|
||||
<div class="search-results-container" ng-if="!ctrl.tagsMode" grafana-scrollbar>
|
||||
<h6 ng-show="!ctrl.isLoading && results.length">No dashboards matching your query were found.</h6>
|
||||
<div ng-repeat="section in ctrl.results" class="search-section">
|
||||
<a class="search-section__header pointer" ng-hide="section.hideHeader" ng-click="ctrl.toggleFolder(section)">
|
||||
<i class="search-section__header__icon" ng-class="section.icon"></i>
|
||||
<span class="search-section__header__text">{{::section.title}}</span>
|
||||
<i class="fa fa-minus search-section__header__toggle" ng-show="section.expanded"></i>
|
||||
<i class="fa fa-plus search-section__header__toggle" ng-hide="section.expanded"></i>
|
||||
</a>
|
||||
|
||||
<div ng-repeat="section in ctrl.results" class="search-section">
|
||||
<a class="search-section__header pointer" ng-hide="section.hideHeader" ng-click="ctrl.toggleFolder(section)">
|
||||
<i class="search-section__header__icon" ng-class="section.icon"></i>
|
||||
<span class="search-section__header__text">{{::section.title}}</span>
|
||||
<i class="fa fa-minus search-section__header__toggle" ng-show="section.expanded"></i>
|
||||
<i class="fa fa-plus search-section__header__toggle" ng-hide="section.expanded"></i>
|
||||
</a>
|
||||
<div ng-if="section.expanded">
|
||||
<a ng-repeat="item in section.items" class="search-item" ng-class="{'selected': item.selected}" ng-href="{{::item.url}}">
|
||||
<span class="search-item__icon">
|
||||
<i class="fa fa-th-large"></i>
|
||||
</span>
|
||||
<span class="search-item__body">
|
||||
<div class="search-item__body-title">{{::item.title}}</div>
|
||||
<div class="search-item__body-sub-title" ng-show="item.folderTitle && section.hideHeader">
|
||||
{{::item.folderTitle}}
|
||||
</div>
|
||||
</span>
|
||||
<span class="search-item__tags">
|
||||
<span ng-click="ctrl.filterByTag(tag, $event)" ng-repeat="tag in item.tags" tag-color-from-name="tag" class="label label-tag">
|
||||
{{tag}}
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="section.expanded">
|
||||
<a ng-repeat="item in section.items" class="search-item" ng-class="{'selected': item.selected}" ng-href="{{::item.url}}">
|
||||
<span class="search-item__icon">
|
||||
<i class="fa fa-th-large"></i>
|
||||
</span>
|
||||
<span class="search-item__body">
|
||||
<div class="search-item__body-title">{{::item.title}}</div>
|
||||
<div class="search-item__body-sub-title" ng-show="item.folderTitle && section.hideHeader">
|
||||
{{::item.folderTitle}}
|
||||
</div>
|
||||
</span>
|
||||
<span class="search-item__tags">
|
||||
<span ng-click="ctrl.filterByTag(tag, $event)" ng-repeat="tag in item.tags" tag-color-from-name="tag" class="label label-tag">
|
||||
{{tag}}
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-dropdown__col_2">
|
||||
<div class="search-filter-box">
|
||||
<div class="search-filter-box__header">
|
||||
<i class="fa fa-filter"></i>
|
||||
Filter by:
|
||||
<a class="pointer pull-right small">
|
||||
<i class="fa fa-remove"></i> Clear
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="search-button-row">
|
||||
<a class="search-button-row-explore-link" target="_blank" href="https://grafana.com/dashboards?utm_source=grafana_search">
|
||||
Find <img src="public/img/icn-dashboard-tiny.svg" width="14" /> dashboards on Grafana.com
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<folder-picker initial-title="ctrl.initialFolderFilterTitle"
|
||||
on-change="ctrl.onFolderChange($folder)"
|
||||
label-class="width-4">
|
||||
</folder-picker>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-4">Tags</label>
|
||||
<bootstrap-tagsinput ng-model="ctrl.dashboard.tags" tagclass="label label-tag" placeholder="add tags">
|
||||
</bootstrap-tagsinput>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="search-filter-box">
|
||||
<a class="search-button-row-explore-link" target="_blank" href="https://grafana.com/dashboards?utm_source=grafana_search">
|
||||
<img src="public/img/icn-dashboard-tiny.svg" width="20" /> Find dashboards on Grafana.com
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -9,16 +9,18 @@ export class SearchCtrl {
|
||||
selectedIndex: number;
|
||||
results: any;
|
||||
currentSearchId: number;
|
||||
tagsMode: boolean;
|
||||
showImport: boolean;
|
||||
dismiss: any;
|
||||
ignoreClose: any;
|
||||
isLoading: boolean;
|
||||
initialFolderFilterTitle: string;
|
||||
|
||||
/** @ngInject */
|
||||
constructor($scope, private $location, private $timeout, private searchSrv: SearchSrv, $rootScope) {
|
||||
$rootScope.onAppEvent('show-dash-search', this.openSearch.bind(this), $scope);
|
||||
$rootScope.onAppEvent('hide-dash-search', this.closeSearch.bind(this), $scope);
|
||||
|
||||
this.initialFolderFilterTitle = "All";
|
||||
}
|
||||
|
||||
closeSearch() {
|
||||
@ -44,14 +46,6 @@ export class SearchCtrl {
|
||||
this.query.starred = true;
|
||||
}
|
||||
|
||||
if (payload && payload.tagsMode) {
|
||||
return this.$timeout(() => {
|
||||
this.ignoreClose = false;
|
||||
this.giveSearchFocus = this.giveSearchFocus + 1;
|
||||
this.getTags();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
this.$timeout(() => {
|
||||
this.ignoreClose = false;
|
||||
this.giveSearchFocus = this.giveSearchFocus + 1;
|
||||
@ -70,14 +64,6 @@ export class SearchCtrl {
|
||||
this.moveSelection(-1);
|
||||
}
|
||||
if (evt.keyCode === 13) {
|
||||
if (this.tagsMode) {
|
||||
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({});
|
||||
@ -93,7 +79,6 @@ export class SearchCtrl {
|
||||
}
|
||||
|
||||
searchDashboards() {
|
||||
this.tagsMode = false;
|
||||
this.currentSearchId = this.currentSearchId + 1;
|
||||
var localSearchId = this.currentSearchId;
|
||||
|
||||
@ -129,12 +114,8 @@ export class SearchCtrl {
|
||||
|
||||
getTags() {
|
||||
return this.searchSrv.getDashboardTags().then((results) => {
|
||||
this.tagsMode = !this.tagsMode;
|
||||
this.results = results;
|
||||
this.giveSearchFocus = this.giveSearchFocus + 1;
|
||||
if ( !this.tagsMode ) {
|
||||
this.search();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -180,6 +180,7 @@ $input-invalid-border-color: lighten($red, 5%);
|
||||
|
||||
// Search
|
||||
$search-shadow: 0 0 35px 0 $body-bg;
|
||||
$search-filter-box-bg: $gray-blue;
|
||||
|
||||
// Dropdowns
|
||||
// -------------------------
|
||||
|
@ -205,6 +205,7 @@ $breadcrumb-hover-hl: #d9dadd;
|
||||
|
||||
// search
|
||||
$search-shadow: 0 5px 30px 0 $gray-4;
|
||||
$search-filter-box-bg: $gray-4;
|
||||
|
||||
// Dropdowns
|
||||
// -------------------------
|
||||
|
@ -89,8 +89,8 @@ $font-size-root: 14px !default;
|
||||
$font-size-base: 13px !default;
|
||||
|
||||
$font-size-lg: 18px !default;
|
||||
$font-size-sm: 12px !default;
|
||||
$font-size-xs: 10px !default;
|
||||
$font-size-sm: 11px !default;
|
||||
$font-size-xs: 9px !default;
|
||||
|
||||
$line-height-base: 1.5 !default;
|
||||
$font-weight-semi-bold: 500;
|
||||
|
@ -21,6 +21,15 @@ $input-border: 1px solid $input-border-color;
|
||||
&--flex-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
&--alt {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
|
||||
.gf-form-label {
|
||||
padding: 4px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.gf-form-disabled {
|
||||
|
@ -6,7 +6,7 @@
|
||||
top: $navbarHeight;
|
||||
z-index: $zindex-modal-backdrop;
|
||||
background-color: $black;
|
||||
@include opacity(70);
|
||||
@include opacity(75);
|
||||
}
|
||||
|
||||
.search-container {
|
||||
@ -44,12 +44,6 @@
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.search-switches {
|
||||
flex-grow: 1;
|
||||
padding: 1rem 1rem 0.75rem 1rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.search-field-icon {
|
||||
font-size: $font-size-lg;
|
||||
padding: 1rem 1rem 0.75rem 1.5rem;
|
||||
@ -57,12 +51,38 @@
|
||||
|
||||
.search-dropdown {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 800px;
|
||||
background: $page-bg;
|
||||
flex-direction: row;
|
||||
height: calc(100% - #{$navbarHeight});
|
||||
}
|
||||
|
||||
.search-dropdown__col_1 {
|
||||
background: $page-bg;
|
||||
max-width: 700px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.search-dropdown__col_2 {
|
||||
flex-grow: 1;
|
||||
height: 100%;
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
.search-filter-box {
|
||||
background: $search-filter-box-bg;
|
||||
border-radius: 2px;
|
||||
padding: $spacer*1.5;
|
||||
max-width: 340px;
|
||||
margin-bottom: $spacer * 1.5;
|
||||
margin-left: $spacer * 1.5;
|
||||
}
|
||||
|
||||
.search-filter-box__header {
|
||||
border-bottom: 1px solid $dark-5;
|
||||
margin-bottom: $spacer * 1.5;
|
||||
}
|
||||
|
||||
.search-results-container {
|
||||
height: 100%;
|
||||
display: block;
|
||||
|
Loading…
Reference in New Issue
Block a user