Просмотр исходного кода

Fixes for the tag filtering in the search #13425

Johannes Schill 7 лет назад
Родитель
Сommit
e20fa1ba70

+ 9 - 43
public/app/core/components/TagFilter/TagFilter.tsx

@@ -1,7 +1,5 @@
-import _ from 'lodash';
 import React from 'react';
 import AsyncSelect from 'react-select/lib/Async';
-import { TagValue } from './TagValue';
 import { TagOption } from './TagOption';
 import { TagBadge } from './TagBadge';
 import IndicatorsContainer from 'app/core/components/Picker/IndicatorsContainer';
@@ -23,7 +21,6 @@ export class TagFilter extends React.Component<Props, any> {
 
     this.searchTags = this.searchTags.bind(this);
     this.onChange = this.onChange.bind(this);
-    this.onTagRemove = this.onTagRemove.bind(this);
   }
 
   searchTags(query) {
@@ -40,14 +37,6 @@ export class TagFilter extends React.Component<Props, any> {
     this.props.onSelect(newTags);
   }
 
-  onTagRemove(tag) {
-    let newTags = _.without(this.props.tags, tag.label);
-    newTags = _.map(newTags, tag => {
-      return { value: tag };
-    });
-    this.props.onSelect(newTags);
-  }
-
   render() {
     const selectOptions = {
       classNamePrefix: 'gf-form-select2',
@@ -61,50 +50,27 @@ export class TagFilter extends React.Component<Props, any> {
       noOptionsMessage: () => 'No tags found',
       getOptionValue: i => i.value,
       getOptionLabel: i => i.label,
+      value: this.props.tags,
       styles: ResetStyles,
       components: {
         Option: TagOption,
         IndicatorsContainer,
         NoOptionsMessage,
-        MultiValueContainer: props => {
+        MultiValueLabel: () => {
+          return null; // We want the whole tag to be clickable so we use MultiValueRemove instead
+        },
+        MultiValueRemove: props => {
           const { data } = props;
+
           return (
-            <components.MultiValueContainer {...props}>
-              <TagBadge label={data.label} removeIcon={true} count={data.count} />
-            </components.MultiValueContainer>
+            <components.MultiValueRemove {...props}>
+              <TagBadge key={data.label} label={data.label} removeIcon={true} count={data.count} />
+            </components.MultiValueRemove>
           );
         },
-        MultiValueRemove: props => {
-          return <components.MultiValueRemove {...props}>X</components.MultiValueRemove>;
-        },
       },
     };
 
-    // <AsyncSelect
-    // classNamePrefix={`gf-form-select2`}
-    // isMulti={false}
-    // isLoading={isLoading}
-    // defaultOptions={true}
-    // loadOptions={this.debouncedSearch}
-    // onChange={onSelected}
-    // className={`gf-form-input gf-form-input--form-dropdown ${className || ''}`}
-    // styles={ResetStyles}
-    // components={{
-    //   Option: PickerOption,
-    //   IndicatorsContainer,
-    //   NoOptionsMessage,
-    // }}
-    // placeholder="Select user"
-    // filterOption={(option: { label: string }, searchText?: string) => {
-    //   return option.label.includes(searchText);
-    // }}
-    // loadingMessage={() => 'Loading...'}
-    // noOptionsMessage={() => 'No users found'}
-    // getOptionValue={i => i.id}
-    // getOptionLabel={i => i.label}
-
-    selectOptions['valueComponent'] = TagValue;
-
     return (
       <div className="gf-form gf-form--has-input-icon gf-form--grow">
         <div className="tag-filter">

+ 1 - 1
public/app/core/components/TagFilter/TagOption.tsx

@@ -13,7 +13,7 @@ export const TagOption = (props: ExtendedOptionProps) => {
   return (
     <components.Option {...props}>
       <div className={`tag-filter-option btn btn-link ${className || ''}`}>
-        <TagBadge label={label} removeIcon={true} count={data.count} />
+        <TagBadge label={label} removeIcon={false} count={data.count} />
       </div>
     </components.Option>
   );

+ 6 - 2
public/app/core/components/search/search.ts

@@ -160,8 +160,12 @@ export class SearchCtrl {
   searchDashboards() {
     this.currentSearchId = this.currentSearchId + 1;
     const localSearchId = this.currentSearchId;
+    const query = {
+      ...this.query,
+      tag: this.query.tag.map(i => i.value),
+    };
 
-    return this.searchSrv.search(this.query).then(results => {
+    return this.searchSrv.search(query).then(results => {
       if (localSearchId < this.currentSearchId) {
         return;
       }
@@ -196,7 +200,7 @@ export class SearchCtrl {
   }
 
   onTagSelect(newTags) {
-    this.query.tag = _.map(newTags, tag => tag.value);
+    this.query.tag = newTags;
     this.search();
   }
 

+ 8 - 7
public/sass/components/_form_select_box.scss

@@ -46,19 +46,13 @@ $select-input-bg-disabled: $input-bg-disabled;
 }
 
 .gf-form-select2__input {
-  position: absolute;
-  z-index: 1;
-  top: 0;
-  left: 0;
-  right: 0;
-  padding: 8px 10px;
+  padding-left: 5px;
 }
 
 .gf-form-select2__menu {
   background: $select-input-bg-disabled;
   position: absolute;
   z-index: 2;
-  width: 100%;
 }
 
 .tag-filter .gf-form-select2__menu {
@@ -83,9 +77,16 @@ $select-input-bg-disabled: $input-bg-disabled;
   }
 }
 
+.gf-form-select2__control--is-focused .gf-form-select2__placeholder {
+  display: none;
+}
+
 .gf-form-select2__value-container {
   display: table-cell;
   padding: 8px 10px;
+  > div {
+    display: inline-block;
+  }
 }
 
 .gf-form-select2__indicators {