Przeglądaj źródła

ux: search filter box

Torkel Ödegaard 8 lat temu
rodzic
commit
3d2d789ca2

+ 62 - 67
public/app/core/components/search/search.html

@@ -15,79 +15,74 @@
 						ng-blur="ctrl.searchInputBlur()"
 						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 class="search-field-spacer"></div>
 	</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}} &nbsp;({{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>
 </div>
 
 

+ 3 - 22
public/app/core/components/search/search.ts

@@ -9,16 +9,18 @@ export class SearchCtrl {
   selectedIndex: number;
   selectedIndex: number;
   results: any;
   results: any;
   currentSearchId: number;
   currentSearchId: number;
-  tagsMode: boolean;
   showImport: boolean;
   showImport: boolean;
   dismiss: any;
   dismiss: any;
   ignoreClose: any;
   ignoreClose: any;
   isLoading: boolean;
   isLoading: boolean;
+  initialFolderFilterTitle: string;
 
 
   /** @ngInject */
   /** @ngInject */
   constructor($scope, private $location, private $timeout, private searchSrv: SearchSrv, $rootScope) {
   constructor($scope, private $location, private $timeout, private searchSrv: SearchSrv, $rootScope) {
     $rootScope.onAppEvent('show-dash-search', this.openSearch.bind(this), $scope);
     $rootScope.onAppEvent('show-dash-search', this.openSearch.bind(this), $scope);
     $rootScope.onAppEvent('hide-dash-search', this.closeSearch.bind(this), $scope);
     $rootScope.onAppEvent('hide-dash-search', this.closeSearch.bind(this), $scope);
+
+    this.initialFolderFilterTitle = "All";
   }
   }
 
 
   closeSearch() {
   closeSearch() {
@@ -44,14 +46,6 @@ export class SearchCtrl {
       this.query.starred = true;
       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.$timeout(() => {
       this.ignoreClose = false;
       this.ignoreClose = false;
       this.giveSearchFocus = this.giveSearchFocus + 1;
       this.giveSearchFocus = this.giveSearchFocus + 1;
@@ -70,14 +64,6 @@ export class SearchCtrl {
       this.moveSelection(-1);
       this.moveSelection(-1);
     }
     }
     if (evt.keyCode === 13) {
     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];
       var selectedDash = this.results[this.selectedIndex];
       if (selectedDash) {
       if (selectedDash) {
         this.$location.search({});
         this.$location.search({});
@@ -93,7 +79,6 @@ export class SearchCtrl {
   }
   }
 
 
   searchDashboards() {
   searchDashboards() {
-    this.tagsMode = false;
     this.currentSearchId = this.currentSearchId + 1;
     this.currentSearchId = this.currentSearchId + 1;
     var localSearchId = this.currentSearchId;
     var localSearchId = this.currentSearchId;
 
 
@@ -129,12 +114,8 @@ export class SearchCtrl {
 
 
   getTags() {
   getTags() {
     return this.searchSrv.getDashboardTags().then((results) => {
     return this.searchSrv.getDashboardTags().then((results) => {
-      this.tagsMode = !this.tagsMode;
       this.results = results;
       this.results = results;
       this.giveSearchFocus = this.giveSearchFocus + 1;
       this.giveSearchFocus = this.giveSearchFocus + 1;
-      if ( !this.tagsMode ) {
-        this.search();
-      }
     });
     });
   }
   }
 
 

+ 1 - 0
public/sass/_variables.dark.scss

@@ -180,6 +180,7 @@ $input-invalid-border-color:     lighten($red, 5%);
 
 
 // Search
 // Search
 $search-shadow: 0 0 35px 0 $body-bg;
 $search-shadow: 0 0 35px 0 $body-bg;
+$search-filter-box-bg: $gray-blue;
 
 
 // Dropdowns
 // Dropdowns
 // -------------------------
 // -------------------------

+ 1 - 0
public/sass/_variables.light.scss

@@ -205,6 +205,7 @@ $breadcrumb-hover-hl:       #d9dadd;
 
 
 // search
 // search
 $search-shadow: 0 5px 30px 0 $gray-4;
 $search-shadow: 0 5px 30px 0 $gray-4;
+$search-filter-box-bg: $gray-4;
 
 
 // Dropdowns
 // Dropdowns
 // -------------------------
 // -------------------------

+ 2 - 2
public/sass/_variables.scss

@@ -89,8 +89,8 @@ $font-size-root: 14px !default;
 $font-size-base: 13px !default;
 $font-size-base: 13px !default;
 
 
 $font-size-lg:   18px !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;
 $line-height-base: 1.5 !default;
 $font-weight-semi-bold: 500;
 $font-weight-semi-bold: 500;

+ 9 - 0
public/sass/components/_gf-form.scss

@@ -21,6 +21,15 @@ $input-border: 1px solid $input-border-color;
   &--flex-end {
   &--flex-end {
     justify-content: flex-end;
     justify-content: flex-end;
   }
   }
+
+  &--alt {
+    flex-direction: column;
+    align-items: flex-start;
+
+    .gf-form-label {
+      padding: 4px 0;
+    }
+  }
 }
 }
 
 
 .gf-form-disabled {
 .gf-form-disabled {

+ 30 - 10
public/sass/components/_search.scss

@@ -6,7 +6,7 @@
   top: $navbarHeight;
   top: $navbarHeight;
   z-index: $zindex-modal-backdrop;
   z-index: $zindex-modal-backdrop;
   background-color: $black;
   background-color: $black;
-  @include opacity(70);
+  @include opacity(75);
 }
 }
 
 
 .search-container {
 .search-container {
@@ -44,12 +44,6 @@
   flex-grow: 1;
   flex-grow: 1;
 }
 }
 
 
-.search-switches {
-  flex-grow: 1;
-  padding: 1rem 1rem 0.75rem 1rem;
-  white-space: nowrap;
-}
-
 .search-field-icon {
 .search-field-icon {
   font-size: $font-size-lg;
   font-size: $font-size-lg;
   padding: 1rem 1rem 0.75rem 1.5rem;
   padding: 1rem 1rem 0.75rem 1.5rem;
@@ -57,12 +51,38 @@
 
 
 .search-dropdown {
 .search-dropdown {
   display: flex;
   display: flex;
-  flex-direction: column;
-  max-width: 800px;
-  background: $page-bg;
+  flex-direction: row;
   height: calc(100% - #{$navbarHeight});
   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 {
 .search-results-container {
   height: 100%;
   height: 100%;
   display: block;
   display: block;