Merge branch '27174-filter-filters' into 'master'

prevent filtering Issues by multiple milestones, authors, or assignees

Closes #27174

See merge request !9406
This commit is contained in:
Clement Ho 2017-03-15 17:20:09 +00:00
commit 53d4cad1c9
5 changed files with 52 additions and 15 deletions

View File

@ -57,13 +57,15 @@ require('./filtered_search_dropdown');
const dropdownData = [];
[].forEach.call(this.input.closest('.filtered-search-input-container').querySelectorAll('.dropdown-menu'), (dropdownMenu) => {
const { icon, hint, tag } = dropdownMenu.dataset;
const { icon, hint, tag, type } = dropdownMenu.dataset;
if (icon && hint && tag) {
dropdownData.push({
icon: `fa-${icon}`,
hint,
tag: `<${tag}>`,
});
dropdownData.push(
Object.assign({
icon: `fa-${icon}`,
hint,
tag: `<${tag}>`,
}, type && { type }),
);
}
});

View File

@ -51,14 +51,18 @@
static filterHint(input, item) {
const updatedItem = item;
const searchInput = gl.DropdownUtils.getSearchInput(input);
let { lastToken } = gl.FilteredSearchTokenizer.processTokens(searchInput);
lastToken = lastToken.key || lastToken || '';
const searchInput = gl.DropdownUtils.getSearchQuery(input);
const { lastToken, tokens } = gl.FilteredSearchTokenizer.processTokens(searchInput);
const lastKey = lastToken.key || lastToken || '';
const allowMultiple = item.type === 'array';
const itemInExistingTokens = tokens.some(t => t.key === item.hint);
if (!lastToken || searchInput.split('').last() === ' ') {
if (!allowMultiple && itemInExistingTokens) {
updatedItem.droplab_hidden = true;
} else if (!lastKey || searchInput.split('').last() === ' ') {
updatedItem.droplab_hidden = false;
} else if (lastToken) {
const split = lastToken.split(':');
} else if (lastKey) {
const split = lastKey.split(':');
const tokenName = split[0].split(' ').last();
const match = updatedItem.hint.indexOf(tokenName.toLowerCase()) === -1;

View File

@ -73,7 +73,7 @@
%li.filter-dropdown-item
%button.btn.btn-link.js-data-value
{{title}}
#js-dropdown-label.dropdown-menu{ data: { icon: 'tag', hint: 'label', tag: '~label' } }
#js-dropdown-label.dropdown-menu{ data: { icon: 'tag', hint: 'label', tag: '~label', type: 'array' } }
%ul{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { value: 'none' } }
%button.btn.btn-link

View File

@ -0,0 +1,4 @@
---
title: Prevent filtering issues by multiple Milestones or Authors
merge_request:
author:

View File

@ -126,7 +126,11 @@ require('~/filtered_search/filtered_search_dropdown_manager');
beforeEach(() => {
setFixtures(`
<input type="text" id="test" />
<ul class="tokens-container">
<li class="input-token">
<input class="filtered-search" type="text" id="test" />
</li>
</ul>
`);
input = document.getElementById('test');
@ -142,7 +146,7 @@ require('~/filtered_search/filtered_search_dropdown_manager');
input.value = 'o';
updatedItem = gl.DropdownUtils.filterHint(input, {
hint: 'label',
}, 'o');
});
expect(updatedItem.droplab_hidden).toBe(true);
});
@ -150,6 +154,29 @@ require('~/filtered_search/filtered_search_dropdown_manager');
const updatedItem = gl.DropdownUtils.filterHint(input, {}, '');
expect(updatedItem.droplab_hidden).toBe(false);
});
it('should allow multiple if item.type is array', () => {
input.value = 'label:~first la';
const updatedItem = gl.DropdownUtils.filterHint(input, {
hint: 'label',
type: 'array',
});
expect(updatedItem.droplab_hidden).toBe(false);
});
it('should prevent multiple if item.type is not array', () => {
input.value = 'milestone:~first mile';
let updatedItem = gl.DropdownUtils.filterHint(input, {
hint: 'milestone',
});
expect(updatedItem.droplab_hidden).toBe(true);
updatedItem = gl.DropdownUtils.filterHint(input, {
hint: 'milestone',
type: 'string',
});
expect(updatedItem.droplab_hidden).toBe(true);
});
});
describe('setDataValueIfSelected', () => {