Commit 01a18396 authored by Phil Hughes's avatar Phil Hughes

Merge branch '1967-search-issues-multiple-assignees' into 'master'

Allow multiple assignees to be chosen from dropdown filters

Closes #1967

See merge request !1494
parents 4e2209f1 1a9c7d3f
......@@ -10,4 +10,4 @@ import './filtered_search_tokenizer';
import './filtered_search_visual_tokens';
// EE-only
import './filtered_search_token_keys_with_weights';
import './filtered_search_token_keys_issues_ee';
......@@ -11,7 +11,7 @@ class FilteredSearchDropdownManager {
this.page = page;
if (this.page === 'issues' || this.page === 'boards') {
this.filteredSearchTokenKeys = gl.FilteredSearchTokenKeysWithWeights;
this.filteredSearchTokenKeys = gl.FilteredSearchTokenKeysIssuesEE;
}
this.setupMapping();
......
......@@ -14,7 +14,7 @@ class FilteredSearchManager {
this.filteredSearchTokenKeys = gl.FilteredSearchTokenKeys;
if (page === 'issues' || page === 'boards') {
this.filteredSearchTokenKeys = gl.FilteredSearchTokenKeysWithWeights;
this.filteredSearchTokenKeys = gl.FilteredSearchTokenKeysIssuesEE;
}
this.recentSearchesStore = new RecentSearchesStore({
......
......@@ -18,15 +18,20 @@ const weightConditions = [{
value: 'any',
}];
class FilteredSearchTokenKeysWithWeights extends gl.FilteredSearchTokenKeys {
class FilteredSearchTokenKeysIssuesEE extends gl.FilteredSearchTokenKeys {
static get() {
const tokenKeys = Array.from(super.get());
// Enable multiple assignees
const assigneeTokenKey = tokenKeys.find(tk => tk.key === 'assignee');
assigneeTokenKey.type = 'array';
tokenKeys.push(weightTokenKey);
return tokenKeys;
}
static getKeys() {
const tokenKeys = FilteredSearchTokenKeysWithWeights.get();
const tokenKeys = FilteredSearchTokenKeysIssuesEE.get();
return tokenKeys.map(i => i.key);
}
......@@ -40,18 +45,18 @@ class FilteredSearchTokenKeysWithWeights extends gl.FilteredSearchTokenKeys {
}
static searchByKey(key) {
const tokenKeys = FilteredSearchTokenKeysWithWeights.get();
const tokenKeys = FilteredSearchTokenKeysIssuesEE.get();
return tokenKeys.find(tokenKey => tokenKey.key === key) || null;
}
static searchBySymbol(symbol) {
const tokenKeys = FilteredSearchTokenKeysWithWeights.get();
const tokenKeys = FilteredSearchTokenKeysIssuesEE.get();
return tokenKeys.find(tokenKey => tokenKey.symbol === symbol) || null;
}
static searchByKeyParam(keyParam) {
const tokenKeys = FilteredSearchTokenKeysWithWeights.get();
const alternativeTokenKeys = FilteredSearchTokenKeysWithWeights.getAlternatives();
const tokenKeys = FilteredSearchTokenKeysIssuesEE.get();
const alternativeTokenKeys = FilteredSearchTokenKeysIssuesEE.getAlternatives();
const tokenKeysWithAlternative = tokenKeys.concat(alternativeTokenKeys);
return tokenKeysWithAlternative.find((tokenKey) => {
......@@ -66,16 +71,16 @@ class FilteredSearchTokenKeysWithWeights extends gl.FilteredSearchTokenKeys {
}
static searchByConditionUrl(url) {
const conditions = FilteredSearchTokenKeysWithWeights.getConditions();
const conditions = FilteredSearchTokenKeysIssuesEE.getConditions();
return conditions.find(condition => condition.url === url) || null;
}
static searchByConditionKeyValue(key, value) {
const conditions = FilteredSearchTokenKeysWithWeights.getConditions();
const conditions = FilteredSearchTokenKeysIssuesEE.getConditions();
return conditions
.find(condition => condition.tokenKey === key && condition.value === value) || null;
}
}
window.gl = window.gl || {};
gl.FilteredSearchTokenKeysWithWeights = FilteredSearchTokenKeysWithWeights;
gl.FilteredSearchTokenKeysIssuesEE = FilteredSearchTokenKeysIssuesEE;
import '~/extensions/array';
import '~/filtered_search/filtered_search_token_keys_with_weights';
import '~/filtered_search/filtered_search_token_keys_issues_ee';
(() => {
describe('Filtered Search Token Keys With Weights', () => {
describe('Filtered Search Token Keys (Issues EE)', () => {
const weightTokenKey = {
key: 'weight',
type: 'string',
......@@ -15,7 +15,7 @@ import '~/filtered_search/filtered_search_token_keys_with_weights';
let tokenKeys;
beforeEach(() => {
tokenKeys = gl.FilteredSearchTokenKeysWithWeights.get();
tokenKeys = gl.FilteredSearchTokenKeysIssuesEE.get();
});
it('should return tokenKeys', () => {
......@@ -32,16 +32,21 @@ import '~/filtered_search/filtered_search_token_keys_with_weights';
});
it('should always return the same array', () => {
const tokenKeys2 = gl.FilteredSearchTokenKeysWithWeights.get();
const tokenKeys2 = gl.FilteredSearchTokenKeysIssuesEE.get();
expect(tokenKeys).toEqual(tokenKeys2);
});
it('should return assignee as an array', () => {
const assignee = tokenKeys.find(tokenKey => tokenKey.key === 'assignee');
expect(assignee.type).toEqual('array');
});
});
describe('getKeys', () => {
it('should return keys', () => {
const getKeys = gl.FilteredSearchTokenKeysWithWeights.getKeys();
const keys = gl.FilteredSearchTokenKeysWithWeights.get().map(i => i.key);
const getKeys = gl.FilteredSearchTokenKeysIssuesEE.getKeys();
const keys = gl.FilteredSearchTokenKeysIssuesEE.get().map(i => i.key);
keys.forEach((key, i) => {
expect(key).toEqual(getKeys[i]);
......@@ -53,7 +58,7 @@ import '~/filtered_search/filtered_search_token_keys_with_weights';
let conditions;
beforeEach(() => {
conditions = gl.FilteredSearchTokenKeysWithWeights.getConditions();
conditions = gl.FilteredSearchTokenKeysIssuesEE.getConditions();
});
it('should return conditions', () => {
......@@ -72,89 +77,89 @@ import '~/filtered_search/filtered_search_token_keys_with_weights';
describe('searchByKey', () => {
it('should return null when key not found', () => {
const tokenKey = gl.FilteredSearchTokenKeysWithWeights.searchByKey('notakey');
const tokenKey = gl.FilteredSearchTokenKeysIssuesEE.searchByKey('notakey');
expect(tokenKey === null).toBe(true);
});
it('should return tokenKey when found by key', () => {
const tokenKeys = gl.FilteredSearchTokenKeysWithWeights.get();
const result = gl.FilteredSearchTokenKeysWithWeights.searchByKey(tokenKeys[0].key);
const tokenKeys = gl.FilteredSearchTokenKeysIssuesEE.get();
const result = gl.FilteredSearchTokenKeysIssuesEE.searchByKey(tokenKeys[0].key);
expect(result).toEqual(tokenKeys[0]);
});
it('should return weight tokenKey when found by weight key', () => {
const tokenKeys = gl.FilteredSearchTokenKeysWithWeights.get();
const tokenKeys = gl.FilteredSearchTokenKeysIssuesEE.get();
const match = tokenKeys.find(tk => tk.key === weightTokenKey.key);
const result = gl.FilteredSearchTokenKeysWithWeights.searchByKey(weightTokenKey.key);
const result = gl.FilteredSearchTokenKeysIssuesEE.searchByKey(weightTokenKey.key);
expect(result).toEqual(match);
});
});
describe('searchBySymbol', () => {
it('should return null when symbol not found', () => {
const tokenKey = gl.FilteredSearchTokenKeysWithWeights.searchBySymbol('notasymbol');
const tokenKey = gl.FilteredSearchTokenKeysIssuesEE.searchBySymbol('notasymbol');
expect(tokenKey === null).toBe(true);
});
it('should return tokenKey when found by symbol', () => {
const tokenKeys = gl.FilteredSearchTokenKeysWithWeights.get();
const result = gl.FilteredSearchTokenKeysWithWeights.searchBySymbol(tokenKeys[0].symbol);
const tokenKeys = gl.FilteredSearchTokenKeysIssuesEE.get();
const result = gl.FilteredSearchTokenKeysIssuesEE.searchBySymbol(tokenKeys[0].symbol);
expect(result).toEqual(tokenKeys[0]);
});
it('should return weight tokenKey when found by weight symbol', () => {
const tokenKeys = gl.FilteredSearchTokenKeysWithWeights.get();
const tokenKeys = gl.FilteredSearchTokenKeysIssuesEE.get();
const match = tokenKeys.find(tk => tk.key === weightTokenKey.key);
const result = gl.FilteredSearchTokenKeysWithWeights.searchBySymbol(weightTokenKey.symbol);
const result = gl.FilteredSearchTokenKeysIssuesEE.searchBySymbol(weightTokenKey.symbol);
expect(result).toEqual(match);
});
});
describe('searchByKeyParam', () => {
it('should return null when key param not found', () => {
const tokenKey = gl.FilteredSearchTokenKeysWithWeights.searchByKeyParam('notakeyparam');
const tokenKey = gl.FilteredSearchTokenKeysIssuesEE.searchByKeyParam('notakeyparam');
expect(tokenKey === null).toBe(true);
});
it('should return tokenKey when found by key param', () => {
const tokenKeys = gl.FilteredSearchTokenKeysWithWeights.get();
const result = gl.FilteredSearchTokenKeysWithWeights
const tokenKeys = gl.FilteredSearchTokenKeysIssuesEE.get();
const result = gl.FilteredSearchTokenKeysIssuesEE
.searchByKeyParam(`${tokenKeys[0].key}_${tokenKeys[0].param}`);
expect(result).toEqual(tokenKeys[0]);
});
it('should return alternative tokenKey when found by key param', () => {
const tokenKeys = gl.FilteredSearchTokenKeysWithWeights.getAlternatives();
const result = gl.FilteredSearchTokenKeysWithWeights
const tokenKeys = gl.FilteredSearchTokenKeysIssuesEE.getAlternatives();
const result = gl.FilteredSearchTokenKeysIssuesEE
.searchByKeyParam(`${tokenKeys[0].key}_${tokenKeys[0].param}`);
expect(result).toEqual(tokenKeys[0]);
});
it('should return weight tokenKey when found by weight key param', () => {
const tokenKeys = gl.FilteredSearchTokenKeysWithWeights.get();
const tokenKeys = gl.FilteredSearchTokenKeysIssuesEE.get();
const match = tokenKeys.find(tk => tk.key === weightTokenKey.key);
const result = gl.FilteredSearchTokenKeysWithWeights.searchByKeyParam(weightTokenKey.key);
const result = gl.FilteredSearchTokenKeysIssuesEE.searchByKeyParam(weightTokenKey.key);
expect(result).toEqual(match);
});
});
describe('searchByConditionUrl', () => {
it('should return null when condition url not found', () => {
const condition = gl.FilteredSearchTokenKeysWithWeights.searchByConditionUrl(null);
const condition = gl.FilteredSearchTokenKeysIssuesEE.searchByConditionUrl(null);
expect(condition === null).toBe(true);
});
it('should return condition when found by url', () => {
const conditions = gl.FilteredSearchTokenKeysWithWeights.getConditions();
const result = gl.FilteredSearchTokenKeysWithWeights
const conditions = gl.FilteredSearchTokenKeysIssuesEE.getConditions();
const result = gl.FilteredSearchTokenKeysIssuesEE
.searchByConditionUrl(conditions[0].url);
expect(result).toBe(conditions[0]);
});
it('should return weight condition when found by weight url', () => {
const conditions = gl.FilteredSearchTokenKeysWithWeights.getConditions();
const conditions = gl.FilteredSearchTokenKeysIssuesEE.getConditions();
const weightConditions = conditions.filter(c => c.tokenKey === 'weight');
const result = gl.FilteredSearchTokenKeysWithWeights
const result = gl.FilteredSearchTokenKeysIssuesEE
.searchByConditionUrl(weightConditions[0].url);
expect(result).toBe(weightConditions[0]);
});
......@@ -162,22 +167,22 @@ import '~/filtered_search/filtered_search_token_keys_with_weights';
describe('searchByConditionKeyValue', () => {
it('should return null when condition tokenKey and value not found', () => {
const condition = gl.FilteredSearchTokenKeysWithWeights
const condition = gl.FilteredSearchTokenKeysIssuesEE
.searchByConditionKeyValue(null, null);
expect(condition === null).toBe(true);
});
it('should return condition when found by tokenKey and value', () => {
const conditions = gl.FilteredSearchTokenKeysWithWeights.getConditions();
const result = gl.FilteredSearchTokenKeysWithWeights
const conditions = gl.FilteredSearchTokenKeysIssuesEE.getConditions();
const result = gl.FilteredSearchTokenKeysIssuesEE
.searchByConditionKeyValue(conditions[0].tokenKey, conditions[0].value);
expect(result).toEqual(conditions[0]);
});
it('should return weight condition when found by weight tokenKey and value', () => {
const conditions = gl.FilteredSearchTokenKeysWithWeights.getConditions();
const conditions = gl.FilteredSearchTokenKeysIssuesEE.getConditions();
const weightConditions = conditions.filter(c => c.tokenKey === 'weight');
const result = gl.FilteredSearchTokenKeysWithWeights
const result = gl.FilteredSearchTokenKeysIssuesEE
.searchByConditionKeyValue(weightConditions[0].tokenKey, weightConditions[0].value);
expect(result).toEqual(weightConditions[0]);
});
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment