Merge pull request #5268 from jbudz/filter-alias
[filter bar] Add aliasing. Closes #5194
This commit is contained in:
commit
e26353139e
7 changed files with 74 additions and 27 deletions
|
@ -39,26 +39,51 @@ describe('update filters', function () {
|
||||||
|
|
||||||
describe('updating', function () {
|
describe('updating', function () {
|
||||||
var currentFilter;
|
var currentFilter;
|
||||||
|
var newFilter;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
currentFilter = {query: { match: { extension: { query: 'jpg', type: 'phrase' } } } };
|
newFilter = _.cloneDeep({
|
||||||
|
query: {
|
||||||
|
match: {
|
||||||
|
extension: {
|
||||||
|
query: 'jpg',
|
||||||
|
type: 'phrase'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
currentFilter = _.assign(_.cloneDeep(newFilter), {
|
||||||
|
meta: {}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to update a filter', function () {
|
it('should be able to update a filter', function () {
|
||||||
var newFilter = _.cloneDeep(currentFilter);
|
|
||||||
newFilter.query.match.extension.query = 'png';
|
newFilter.query.match.extension.query = 'png';
|
||||||
|
|
||||||
expect(currentFilter.query.match.extension.query).to.be('jpg');
|
expect(currentFilter.query.match.extension.query).to.be('jpg');
|
||||||
queryFilter.updateFilter({
|
queryFilter.updateFilter({
|
||||||
source: currentFilter,
|
source: currentFilter,
|
||||||
model: newFilter
|
model: newFilter,
|
||||||
|
type: 'query'
|
||||||
});
|
});
|
||||||
$rootScope.$digest();
|
$rootScope.$digest();
|
||||||
expect(currentFilter.query.match.extension.query).to.be('png');
|
expect(currentFilter.query.match.extension.query).to.be('png');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should set an alias in the meta object', function () {
|
||||||
|
|
||||||
|
queryFilter.updateFilter({
|
||||||
|
source: currentFilter,
|
||||||
|
model: newFilter,
|
||||||
|
type: 'query',
|
||||||
|
alias: 'foo'
|
||||||
|
});
|
||||||
|
$rootScope.$digest();
|
||||||
|
expect(currentFilter.meta.alias).to.be('foo');
|
||||||
|
});
|
||||||
|
|
||||||
it('should replace the filter type if it is changed', function () {
|
it('should replace the filter type if it is changed', function () {
|
||||||
var newFilter = {
|
newFilter = {
|
||||||
'range': {
|
'range': {
|
||||||
'bytes': {
|
'bytes': {
|
||||||
'gte': 0,
|
'gte': 0,
|
||||||
|
|
|
@ -55,6 +55,7 @@ describe('Filter Bar Directive', function () {
|
||||||
{ meta: { index: 'logstash-*' }, query: { match: { '_type': { query: 'nginx' } } } },
|
{ meta: { index: 'logstash-*' }, query: { match: { '_type': { query: 'nginx' } } } },
|
||||||
{ meta: { index: 'logstash-*' }, exists: { field: '@timestamp' } },
|
{ meta: { index: 'logstash-*' }, exists: { field: '@timestamp' } },
|
||||||
{ meta: { index: 'logstash-*' }, missing: { field: 'host' }, disabled: true },
|
{ meta: { index: 'logstash-*' }, missing: { field: 'host' }, disabled: true },
|
||||||
|
{ meta: { index: 'logstash-*', alias: 'foo' }, query: { match: { '_type': { query: 'nginx' } } } },
|
||||||
];
|
];
|
||||||
|
|
||||||
Promise.map(filters, mapFilter).then(function (filters) {
|
Promise.map(filters, mapFilter).then(function (filters) {
|
||||||
|
@ -75,7 +76,7 @@ describe('Filter Bar Directive', function () {
|
||||||
|
|
||||||
it('should render all the filters in state', function () {
|
it('should render all the filters in state', function () {
|
||||||
var filters = $el.find('.filter');
|
var filters = $el.find('.filter');
|
||||||
expect(filters).to.have.length(4);
|
expect(filters).to.have.length(5);
|
||||||
expect($(filters[0]).find('span')[0].innerHTML).to.equal('_type:');
|
expect($(filters[0]).find('span')[0].innerHTML).to.equal('_type:');
|
||||||
expect($(filters[0]).find('span')[1].innerHTML).to.equal('"apache"');
|
expect($(filters[0]).find('span')[1].innerHTML).to.equal('"apache"');
|
||||||
expect($(filters[1]).find('span')[0].innerHTML).to.equal('_type:');
|
expect($(filters[1]).find('span')[0].innerHTML).to.equal('_type:');
|
||||||
|
@ -86,6 +87,11 @@ describe('Filter Bar Directive', function () {
|
||||||
expect($(filters[3]).find('span')[1].innerHTML).to.equal('"host"');
|
expect($(filters[3]).find('span')[1].innerHTML).to.equal('"host"');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be able to set an alias', function () {
|
||||||
|
var filter = $el.find('.filter')[4];
|
||||||
|
expect($(filter).find('span')[0].innerHTML).to.equal('foo');
|
||||||
|
});
|
||||||
|
|
||||||
describe('editing filters', function () {
|
describe('editing filters', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
$scope.startEditingFilter(appState.filters[3]);
|
$scope.startEditingFilter(appState.filters[3]);
|
||||||
|
|
|
@ -13,8 +13,9 @@
|
||||||
<div class="filter" ng-class="{ negate: filter.meta.negate, disabled: filter.meta.disabled }" ng-repeat="filter in filters">
|
<div class="filter" ng-class="{ negate: filter.meta.negate, disabled: filter.meta.disabled }" ng-repeat="filter in filters">
|
||||||
<div class="filter-description">
|
<div class="filter-description">
|
||||||
<span ng-if="filter.$state.store == 'globalState'"><i class="fa fa-fw fa-thumb-tack pinned"></i></span>
|
<span ng-if="filter.$state.store == 'globalState'"><i class="fa fa-fw fa-thumb-tack pinned"></i></span>
|
||||||
<span>{{ filter.meta.key }}:</span>
|
<span ng-if="filter.meta.alias">{{ filter.meta.alias }}</span>
|
||||||
<span>"{{ filter.meta.value }}"</span>
|
<span ng-if="!filter.meta.alias">{{ filter.meta.key }}:</span>
|
||||||
|
<span ng-if="!filter.meta.alias">"{{ filter.meta.value }}"</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-actions">
|
<div class="filter-actions">
|
||||||
<a class="action filter-toggle" ng-click="toggleFilter(filter)">
|
<a class="action filter-toggle" ng-click="toggleFilter(filter)">
|
||||||
|
@ -40,6 +41,15 @@
|
||||||
|
|
||||||
<div class="filter-edit-container" ng-if="editingFilter">
|
<div class="filter-edit-container" ng-if="editingFilter">
|
||||||
<form role="form" name="editFilterForm" ng-submit="editDone()">
|
<form role="form" name="editFilterForm" ng-submit="editDone()">
|
||||||
|
<div class="form-group filter-edit-alias">
|
||||||
|
<label>Filter Alias
|
||||||
|
<small>(optional)</small>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
ng-model="editingFilter.alias"
|
||||||
|
type="text"
|
||||||
|
class="form-control">
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
json-input
|
json-input
|
||||||
require-keys="true"
|
require-keys="true"
|
||||||
|
|
|
@ -15,6 +15,7 @@ define(function (require) {
|
||||||
var filterAppliedAndUnwrap = require('ui/filter_bar/lib/filterAppliedAndUnwrap');
|
var filterAppliedAndUnwrap = require('ui/filter_bar/lib/filterAppliedAndUnwrap');
|
||||||
var changeTimeFilter = Private(require('ui/filter_bar/lib/changeTimeFilter'));
|
var changeTimeFilter = Private(require('ui/filter_bar/lib/changeTimeFilter'));
|
||||||
var queryFilter = Private(require('ui/filter_bar/query_filter'));
|
var queryFilter = Private(require('ui/filter_bar/query_filter'));
|
||||||
|
var privateFilterFieldRegex = /(^\$|meta)/;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
|
@ -57,24 +58,14 @@ define(function (require) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var privateFieldRegexp = /(^\$|meta)/;
|
|
||||||
$scope.startEditingFilter = function (source) {
|
$scope.startEditingFilter = function (source) {
|
||||||
var model = _.cloneDeep(source);
|
return $scope.editingFilter = {
|
||||||
var filterType;
|
|
||||||
|
|
||||||
//Hide private properties and figure out what type of filter this is
|
|
||||||
_.each(model, function (value, key) {
|
|
||||||
if (key.match(privateFieldRegexp)) {
|
|
||||||
delete model[key];
|
|
||||||
} else {
|
|
||||||
filterType = key;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$scope.editingFilter = {
|
|
||||||
source: source,
|
source: source,
|
||||||
type: filterType,
|
type: _.findKey(source, function (val, key) {
|
||||||
model: model
|
return !key.match(privateFilterFieldRegex);
|
||||||
|
}),
|
||||||
|
model: convertToEditableFilter(source),
|
||||||
|
alias: source.meta.alias
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -137,6 +128,12 @@ define(function (require) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function convertToEditableFilter(filter) {
|
||||||
|
return _.omit(_.cloneDeep(filter), function (val, key) {
|
||||||
|
return key.match(privateFilterFieldRegex);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function updateFilters() {
|
function updateFilters() {
|
||||||
var filters = queryFilter.getFilters();
|
var filters = queryFilter.getFilters();
|
||||||
mapAndFlattenFilters(filters).then(function (results) {
|
mapAndFlattenFilters(filters).then(function (results) {
|
||||||
|
|
|
@ -28,7 +28,10 @@ filter-bar .confirm {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
min-width: 140px;
|
// Number of filter icons multiplied by icon width
|
||||||
|
// Escaped to prevent less math
|
||||||
|
min-width: ~"calc(5*(1.414em + 13px))";
|
||||||
|
|
||||||
|
|
||||||
font-size: @font-size-small;
|
font-size: @font-size-small;
|
||||||
background-color: @filter-bar-confirm-filter-bg;
|
background-color: @filter-bar-confirm-filter-bg;
|
||||||
|
@ -60,6 +63,10 @@ filter-bar .bar {
|
||||||
margin: 15px 0;
|
margin: 15px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.filter-edit-alias {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
.filter-link {
|
.filter-link {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -77,8 +84,9 @@ filter-bar .bar {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
min-width: 140px;
|
// Number of filter icons multiplied by icon width
|
||||||
|
// Escaped to prevent less math
|
||||||
|
min-width: ~"calc(5*(1.414em + 13px))";
|
||||||
font-size: @font-size-small;
|
font-size: @font-size-small;
|
||||||
background-color: @filter-bar-bar-filter-bg;
|
background-color: @filter-bar-bar-filter-bg;
|
||||||
color: @filter-bar-bar-filter-color;
|
color: @filter-bar-bar-filter-color;
|
||||||
|
|
|
@ -57,6 +57,7 @@ define(function (require) {
|
||||||
filter.meta.value = result.value;
|
filter.meta.value = result.value;
|
||||||
filter.meta.disabled = !!(filter.meta.disabled);
|
filter.meta.disabled = !!(filter.meta.disabled);
|
||||||
filter.meta.negate = !!(filter.meta.negate);
|
filter.meta.negate = !!(filter.meta.negate);
|
||||||
|
filter.meta.alias = filter.meta.alias || null;
|
||||||
return filter;
|
return filter;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -92,7 +92,7 @@ define(function (require) {
|
||||||
*/
|
*/
|
||||||
queryFilter.updateFilter = function (filter) {
|
queryFilter.updateFilter = function (filter) {
|
||||||
var mergedFilter = _.assign({}, filter.source, filter.model);
|
var mergedFilter = _.assign({}, filter.source, filter.model);
|
||||||
|
mergedFilter.meta.alias = filter.alias;
|
||||||
//If the filter type is changed we want to discard the old type
|
//If the filter type is changed we want to discard the old type
|
||||||
//when merging changes back in
|
//when merging changes back in
|
||||||
var filterTypeReplaced = filter.model[filter.type] !== mergedFilter[filter.type];
|
var filterTypeReplaced = filter.model[filter.type] !== mergedFilter[filter.type];
|
||||||
|
|
Loading…
Reference in a new issue