mirror of
https://github.com/grafana/grafana.git
synced 2025-09-26 16:23:48 +08:00
Fixes for the tag filtering in the search #13425
This commit is contained in:
@ -1,7 +1,5 @@
|
|||||||
import _ from 'lodash';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import AsyncSelect from 'react-select/lib/Async';
|
import AsyncSelect from 'react-select/lib/Async';
|
||||||
import { TagValue } from './TagValue';
|
|
||||||
import { TagOption } from './TagOption';
|
import { TagOption } from './TagOption';
|
||||||
import { TagBadge } from './TagBadge';
|
import { TagBadge } from './TagBadge';
|
||||||
import IndicatorsContainer from 'app/core/components/Picker/IndicatorsContainer';
|
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.searchTags = this.searchTags.bind(this);
|
||||||
this.onChange = this.onChange.bind(this);
|
this.onChange = this.onChange.bind(this);
|
||||||
this.onTagRemove = this.onTagRemove.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
searchTags(query) {
|
searchTags(query) {
|
||||||
@ -40,14 +37,6 @@ export class TagFilter extends React.Component<Props, any> {
|
|||||||
this.props.onSelect(newTags);
|
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() {
|
render() {
|
||||||
const selectOptions = {
|
const selectOptions = {
|
||||||
classNamePrefix: 'gf-form-select2',
|
classNamePrefix: 'gf-form-select2',
|
||||||
@ -61,50 +50,27 @@ export class TagFilter extends React.Component<Props, any> {
|
|||||||
noOptionsMessage: () => 'No tags found',
|
noOptionsMessage: () => 'No tags found',
|
||||||
getOptionValue: i => i.value,
|
getOptionValue: i => i.value,
|
||||||
getOptionLabel: i => i.label,
|
getOptionLabel: i => i.label,
|
||||||
|
value: this.props.tags,
|
||||||
styles: ResetStyles,
|
styles: ResetStyles,
|
||||||
components: {
|
components: {
|
||||||
Option: TagOption,
|
Option: TagOption,
|
||||||
IndicatorsContainer,
|
IndicatorsContainer,
|
||||||
NoOptionsMessage,
|
NoOptionsMessage,
|
||||||
MultiValueContainer: props => {
|
MultiValueLabel: () => {
|
||||||
const { data } = props;
|
return null; // We want the whole tag to be clickable so we use MultiValueRemove instead
|
||||||
return (
|
|
||||||
<components.MultiValueContainer {...props}>
|
|
||||||
<TagBadge label={data.label} removeIcon={true} count={data.count} />
|
|
||||||
</components.MultiValueContainer>
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
MultiValueRemove: props => {
|
MultiValueRemove: props => {
|
||||||
return <components.MultiValueRemove {...props}>X</components.MultiValueRemove>;
|
const { data } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<components.MultiValueRemove {...props}>
|
||||||
|
<TagBadge key={data.label} label={data.label} removeIcon={true} count={data.count} />
|
||||||
|
</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 (
|
return (
|
||||||
<div className="gf-form gf-form--has-input-icon gf-form--grow">
|
<div className="gf-form gf-form--has-input-icon gf-form--grow">
|
||||||
<div className="tag-filter">
|
<div className="tag-filter">
|
||||||
|
@ -13,7 +13,7 @@ export const TagOption = (props: ExtendedOptionProps) => {
|
|||||||
return (
|
return (
|
||||||
<components.Option {...props}>
|
<components.Option {...props}>
|
||||||
<div className={`tag-filter-option btn btn-link ${className || ''}`}>
|
<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>
|
</div>
|
||||||
</components.Option>
|
</components.Option>
|
||||||
);
|
);
|
||||||
|
@ -160,8 +160,12 @@ export class SearchCtrl {
|
|||||||
searchDashboards() {
|
searchDashboards() {
|
||||||
this.currentSearchId = this.currentSearchId + 1;
|
this.currentSearchId = this.currentSearchId + 1;
|
||||||
const localSearchId = this.currentSearchId;
|
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) {
|
if (localSearchId < this.currentSearchId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -196,7 +200,7 @@ export class SearchCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onTagSelect(newTags) {
|
onTagSelect(newTags) {
|
||||||
this.query.tag = _.map(newTags, tag => tag.value);
|
this.query.tag = newTags;
|
||||||
this.search();
|
this.search();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,19 +46,13 @@ $select-input-bg-disabled: $input-bg-disabled;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.gf-form-select2__input {
|
.gf-form-select2__input {
|
||||||
position: absolute;
|
padding-left: 5px;
|
||||||
z-index: 1;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
padding: 8px 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.gf-form-select2__menu {
|
.gf-form-select2__menu {
|
||||||
background: $select-input-bg-disabled;
|
background: $select-input-bg-disabled;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag-filter .gf-form-select2__menu {
|
.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 {
|
.gf-form-select2__value-container {
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
padding: 8px 10px;
|
padding: 8px 10px;
|
||||||
|
> div {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.gf-form-select2__indicators {
|
.gf-form-select2__indicators {
|
||||||
|
Reference in New Issue
Block a user