Commit d4387d88 authored by Alexis Reigel's avatar Alexis Reigel

make FilteredSearchTokenKeys generic

for the current usage for the issues search bar a specific instance of
FilteredSearchTokenKeys is created, which contains the config for that
case.
parent 0a0350be
......@@ -3,10 +3,10 @@ import {
getParameterByName,
getUrlParamsArray,
} from '~/lib/utils/common_utils';
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
import { visitUrl } from '../lib/utils/url_utility';
import Flash from '../flash';
import FilteredSearchContainer from './container';
import FilteredSearchTokenKeys from './filtered_search_token_keys';
import RecentSearchesRoot from './recent_searches_root';
import RecentSearchesStore from './stores/recent_searches_store';
import RecentSearchesService from './services/recent_searches_service';
......@@ -23,7 +23,7 @@ export default class FilteredSearchManager {
isGroup = false,
isGroupAncestor = true,
isGroupDecendent = false,
filteredSearchTokenKeys = FilteredSearchTokenKeys,
filteredSearchTokenKeys = IssuesFilteredSearchTokenKeys,
stateFiltersSelector = '.issues-state-filters',
}) {
this.isGroup = isGroup;
......
const tokenKeys = [{
key: 'author',
type: 'string',
param: 'username',
symbol: '@',
icon: 'pencil',
tag: '@author',
}, {
key: 'assignee',
type: 'string',
param: 'username',
symbol: '@',
icon: 'user',
tag: '@assignee',
}, {
key: 'milestone',
type: 'string',
param: 'title',
symbol: '%',
icon: 'clock-o',
tag: '%milestone',
}, {
key: 'label',
type: 'array',
param: 'name[]',
symbol: '~',
icon: 'tag',
tag: '~label',
}];
if (gon.current_user_id) {
// Appending tokenkeys only logged-in
tokenKeys.push({
key: 'my-reaction',
type: 'string',
param: 'emoji',
symbol: '',
icon: 'thumbs-up',
tag: 'emoji',
});
}
const alternativeTokenKeys = [{
key: 'label',
type: 'string',
param: 'name',
symbol: '~',
}];
const tokenKeysWithAlternative = tokenKeys.concat(alternativeTokenKeys);
export default class FilteredSearchTokenKeys {
constructor(tokenKeys, alternativeTokenKeys, conditions) {
this.tokenKeys = tokenKeys || [];
this.alternativeTokenKeys = alternativeTokenKeys || [];
this.conditions = conditions || [];
const conditions = [{
url: 'assignee_id=0',
tokenKey: 'assignee',
value: 'none',
}, {
url: 'milestone_title=No+Milestone',
tokenKey: 'milestone',
value: 'none',
}, {
url: 'milestone_title=%23upcoming',
tokenKey: 'milestone',
value: 'upcoming',
}, {
url: 'milestone_title=%23started',
tokenKey: 'milestone',
value: 'started',
}, {
url: 'label_name[]=No+Label',
tokenKey: 'label',
value: 'none',
}];
this.tokenKeysWithAlternative = this.tokenKeys.concat(this.alternativeTokenKeys);
}
export default class FilteredSearchTokenKeys {
static get() {
return tokenKeys;
get() {
return this.tokenKeys;
}
static getKeys() {
return tokenKeys.map(i => i.key);
getKeys() {
return this.tokenKeys.map(i => i.key);
}
static getAlternatives() {
return alternativeTokenKeys;
getAlternatives() {
return this.alternativeTokenKeys;
}
static getConditions() {
return conditions;
getConditions() {
return this.conditions;
}
static searchByKey(key) {
return tokenKeys.find(tokenKey => tokenKey.key === key) || null;
searchByKey(key) {
return this.tokenKeys.find(tokenKey => tokenKey.key === key) || null;
}
static searchBySymbol(symbol) {
return tokenKeys.find(tokenKey => tokenKey.symbol === symbol) || null;
searchBySymbol(symbol) {
return this.tokenKeys.find(tokenKey => tokenKey.symbol === symbol) || null;
}
static searchByKeyParam(keyParam) {
return tokenKeysWithAlternative.find((tokenKey) => {
searchByKeyParam(keyParam) {
return this.tokenKeysWithAlternative.find((tokenKey) => {
let tokenKeyParam = tokenKey.key;
// Replace hyphen with underscore to compare keyParam with tokenKeyParam
......@@ -112,12 +47,12 @@ export default class FilteredSearchTokenKeys {
}) || null;
}
static searchByConditionUrl(url) {
return conditions.find(condition => condition.url === url) || null;
searchByConditionUrl(url) {
return this.conditions.find(condition => condition.url === url) || null;
}
static searchByConditionKeyValue(key, value) {
return conditions
searchByConditionKeyValue(key, value) {
return this.conditions
.find(condition => condition.tokenKey === key && condition.value === value) || null;
}
}
import FilteredSearchTokenKeys from './filtered_search_token_keys';
const tokenKeys = [{
key: 'author',
type: 'string',
param: 'username',
symbol: '@',
icon: 'pencil',
tag: '@author',
}, {
key: 'assignee',
type: 'string',
param: 'username',
symbol: '@',
icon: 'user',
tag: '@assignee',
}, {
key: 'milestone',
type: 'string',
param: 'title',
symbol: '%',
icon: 'clock-o',
tag: '%milestone',
}, {
key: 'label',
type: 'array',
param: 'name[]',
symbol: '~',
icon: 'tag',
tag: '~label',
}];
if (gon.current_user_id) {
// Appending tokenkeys only logged-in
tokenKeys.push({
key: 'my-reaction',
type: 'string',
param: 'emoji',
symbol: '',
icon: 'thumbs-up',
tag: 'emoji',
});
}
const alternativeTokenKeys = [{
key: 'label',
type: 'string',
param: 'name',
symbol: '~',
}];
const conditions = [{
url: 'assignee_id=0',
tokenKey: 'assignee',
value: 'none',
}, {
url: 'milestone_title=No+Milestone',
tokenKey: 'milestone',
value: 'none',
}, {
url: 'milestone_title=%23upcoming',
tokenKey: 'milestone',
value: 'upcoming',
}, {
url: 'milestone_title=%23started',
tokenKey: 'milestone',
value: 'started',
}, {
url: 'label_name[]=No+Label',
tokenKey: 'label',
value: 'none',
}];
const IssuesFilteredSearchTokenKeys =
new FilteredSearchTokenKeys(tokenKeys, alternativeTokenKeys, conditions);
export default IssuesFilteredSearchTokenKeys;
import projectSelect from '~/project_select';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import { FILTERED_SEARCH } from '~/pages/constants';
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
document.addEventListener('DOMContentLoaded', () => {
initFilteredSearch({
page: FILTERED_SEARCH.ISSUES,
isGroupDecendent: true,
filteredSearchTokenKeys: IssuesFilteredSearchTokenKeys,
});
projectSelect();
});
import projectSelect from '~/project_select';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
import { FILTERED_SEARCH } from '~/pages/constants';
document.addEventListener('DOMContentLoaded', () => {
initFilteredSearch({
page: FILTERED_SEARCH.MERGE_REQUESTS,
isGroupDecendent: true,
filteredSearchTokenKeys: IssuesFilteredSearchTokenKeys,
});
projectSelect();
});
......@@ -4,12 +4,14 @@ import IssuableIndex from '~/issuable_index';
import ShortcutsNavigation from '~/shortcuts_navigation';
import UsersSelect from '~/users_select';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
import { FILTERED_SEARCH } from '~/pages/constants';
import { ISSUABLE_INDEX } from '~/pages/projects/constants';
document.addEventListener('DOMContentLoaded', () => {
initFilteredSearch({
page: FILTERED_SEARCH.ISSUES,
filteredSearchTokenKeys: IssuesFilteredSearchTokenKeys,
});
new IssuableIndex(ISSUABLE_INDEX.ISSUE);
......
......@@ -2,12 +2,14 @@ import IssuableIndex from '~/issuable_index';
import ShortcutsNavigation from '~/shortcuts_navigation';
import UsersSelect from '~/users_select';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
import { FILTERED_SEARCH } from '~/pages/constants';
import { ISSUABLE_INDEX } from '~/pages/projects/constants';
document.addEventListener('DOMContentLoaded', () => {
initFilteredSearch({
page: FILTERED_SEARCH.MERGE_REQUESTS,
filteredSearchTokenKeys: IssuesFilteredSearchTokenKeys,
});
new IssuableIndex(ISSUABLE_INDEX.MERGE_REQUEST); // eslint-disable-line no-new
new ShortcutsNavigation(); // eslint-disable-line no-new
......
import Vue from 'vue';
import eventHub from '~/filtered_search/event_hub';
import RecentSearchesDropdownContent from '~/filtered_search/components/recent_searches_dropdown_content.vue';
import FilteredSearchTokenKeys from '~/filtered_search/filtered_search_token_keys';
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
const createComponent = (propsData) => {
const Component = Vue.extend(RecentSearchesDropdownContent);
......@@ -18,14 +18,14 @@ const trimMarkupWhitespace = text => text.replace(/(\n|\s)+/gm, ' ').trim();
describe('RecentSearchesDropdownContent', () => {
const propsDataWithoutItems = {
items: [],
allowedKeys: FilteredSearchTokenKeys.getKeys(),
allowedKeys: IssuesFilteredSearchTokenKeys.getKeys(),
};
const propsDataWithItems = {
items: [
'foo',
'author:@root label:~foo bar',
],
allowedKeys: FilteredSearchTokenKeys.getKeys(),
allowedKeys: IssuesFilteredSearchTokenKeys.getKeys(),
};
let vm;
......
import DropdownUtils from '~/filtered_search/dropdown_utils';
import DropdownUser from '~/filtered_search/dropdown_user';
import FilteredSearchTokenizer from '~/filtered_search/filtered_search_tokenizer';
import FilteredSearchTokenKeys from '~/filtered_search/filtered_search_token_keys';
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
describe('Dropdown User', () => {
describe('getSearchInput', () => {
......@@ -14,7 +14,7 @@ describe('Dropdown User', () => {
spyOn(DropdownUtils, 'getSearchInput').and.callFake(() => {});
dropdownUser = new DropdownUser({
tokenKeys: FilteredSearchTokenKeys,
tokenKeys: IssuesFilteredSearchTokenKeys,
});
});
......
import DropdownUtils from '~/filtered_search/dropdown_utils';
import FilteredSearchDropdownManager from '~/filtered_search/filtered_search_dropdown_manager';
import FilteredSearchTokenKeys from '~/filtered_search/filtered_search_token_keys';
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
import FilteredSearchSpecHelper from '../helpers/filtered_search_spec_helper';
describe('Dropdown Utils', () => {
......@@ -137,7 +137,7 @@ describe('Dropdown Utils', () => {
`);
input = document.getElementById('test');
allowedKeys = FilteredSearchTokenKeys.getKeys();
allowedKeys = IssuesFilteredSearchTokenKeys.getKeys();
});
function config() {
......
import RecentSearchesService from '~/filtered_search/services/recent_searches_service';
import RecentSearchesServiceError from '~/filtered_search/services/recent_searches_service_error';
import RecentSearchesRoot from '~/filtered_search/recent_searches_root';
import FilteredSearchTokenKeys from '~/filtered_search/filtered_search_token_keys';
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
import '~/lib/utils/common_utils';
import DropdownUtils from '~/filtered_search/dropdown_utils';
import FilteredSearchVisualTokens from '~/filtered_search/filtered_search_visual_tokens';
......@@ -86,7 +86,7 @@ describe('Filtered Search Manager', function () {
expect(RecentSearchesService.isAvailable).toHaveBeenCalled();
expect(RecentSearchesStoreSpy).toHaveBeenCalledWith({
isLocalStorageAvailable,
allowedKeys: FilteredSearchTokenKeys.getKeys(),
allowedKeys: IssuesFilteredSearchTokenKeys.getKeys(),
});
});
});
......
import FilteredSearchTokenKeys from '~/filtered_search/filtered_search_token_keys';
describe('Filtered Search Token Keys', () => {
describe('get', () => {
let tokenKeys;
const tokenKeys = [{
key: 'author',
type: 'string',
param: 'username',
symbol: '@',
icon: 'pencil',
tag: '@author',
}];
const conditions = [{
url: 'assignee_id=0',
tokenKey: 'assignee',
value: 'none',
}];
beforeEach(() => {
tokenKeys = FilteredSearchTokenKeys.get();
});
describe('get', () => {
it('should return tokenKeys', () => {
expect(tokenKeys !== null).toBe(true);
expect(new FilteredSearchTokenKeys().get() !== null).toBe(true);
});
it('should return tokenKeys as an array', () => {
expect(tokenKeys instanceof Array).toBe(true);
expect(new FilteredSearchTokenKeys().get() instanceof Array).toBe(true);
});
});
describe('getKeys', () => {
it('should return keys', () => {
const getKeys = FilteredSearchTokenKeys.getKeys();
const keys = FilteredSearchTokenKeys.get().map(i => i.key);
const getKeys = new FilteredSearchTokenKeys(tokenKeys).getKeys();
const keys = new FilteredSearchTokenKeys(tokenKeys).get().map(i => i.key);
keys.forEach((key, i) => {
expect(key).toEqual(getKeys[i]);
......@@ -29,88 +39,78 @@ describe('Filtered Search Token Keys', () => {
});
describe('getConditions', () => {
let conditions;
beforeEach(() => {
conditions = FilteredSearchTokenKeys.getConditions();
});
it('should return conditions', () => {
expect(conditions !== null).toBe(true);
expect(new FilteredSearchTokenKeys().getConditions() !== null).toBe(true);
});
it('should return conditions as an array', () => {
expect(conditions instanceof Array).toBe(true);
expect(new FilteredSearchTokenKeys().getConditions() instanceof Array).toBe(true);
});
});
describe('searchByKey', () => {
it('should return null when key not found', () => {
const tokenKey = FilteredSearchTokenKeys.searchByKey('notakey');
const tokenKey = new FilteredSearchTokenKeys(tokenKeys).searchByKey('notakey');
expect(tokenKey === null).toBe(true);
});
it('should return tokenKey when found by key', () => {
const tokenKeys = FilteredSearchTokenKeys.get();
const result = FilteredSearchTokenKeys.searchByKey(tokenKeys[0].key);
const result = new FilteredSearchTokenKeys(tokenKeys).searchByKey(tokenKeys[0].key);
expect(result).toEqual(tokenKeys[0]);
});
});
describe('searchBySymbol', () => {
it('should return null when symbol not found', () => {
const tokenKey = FilteredSearchTokenKeys.searchBySymbol('notasymbol');
const tokenKey = new FilteredSearchTokenKeys(tokenKeys).searchBySymbol('notasymbol');
expect(tokenKey === null).toBe(true);
});
it('should return tokenKey when found by symbol', () => {
const tokenKeys = FilteredSearchTokenKeys.get();
const result = FilteredSearchTokenKeys.searchBySymbol(tokenKeys[0].symbol);
const result = new FilteredSearchTokenKeys(tokenKeys).searchBySymbol(tokenKeys[0].symbol);
expect(result).toEqual(tokenKeys[0]);
});
});
describe('searchByKeyParam', () => {
it('should return null when key param not found', () => {
const tokenKey = FilteredSearchTokenKeys.searchByKeyParam('notakeyparam');
const tokenKey = new FilteredSearchTokenKeys(tokenKeys).searchByKeyParam('notakeyparam');
expect(tokenKey === null).toBe(true);
});
it('should return tokenKey when found by key param', () => {
const tokenKeys = FilteredSearchTokenKeys.get();
const result = FilteredSearchTokenKeys.searchByKeyParam(`${tokenKeys[0].key}_${tokenKeys[0].param}`);
const result = new FilteredSearchTokenKeys(tokenKeys).searchByKeyParam(`${tokenKeys[0].key}_${tokenKeys[0].param}`);
expect(result).toEqual(tokenKeys[0]);
});
it('should return alternative tokenKey when found by key param', () => {
const tokenKeys = FilteredSearchTokenKeys.getAlternatives();
const result = FilteredSearchTokenKeys.searchByKeyParam(`${tokenKeys[0].key}_${tokenKeys[0].param}`);
const result = new FilteredSearchTokenKeys(tokenKeys).searchByKeyParam(`${tokenKeys[0].key}_${tokenKeys[0].param}`);
expect(result).toEqual(tokenKeys[0]);
});
});
describe('searchByConditionUrl', () => {
it('should return null when condition url not found', () => {
const condition = FilteredSearchTokenKeys.searchByConditionUrl(null);
const condition = new FilteredSearchTokenKeys([], [], conditions).searchByConditionUrl(null);
expect(condition === null).toBe(true);
});
it('should return condition when found by url', () => {
const conditions = FilteredSearchTokenKeys.getConditions();
const result = FilteredSearchTokenKeys.searchByConditionUrl(conditions[0].url);
const result = new FilteredSearchTokenKeys([], [], conditions)
.searchByConditionUrl(conditions[0].url);
expect(result).toBe(conditions[0]);
});
});
describe('searchByConditionKeyValue', () => {
it('should return null when condition tokenKey and value not found', () => {
const condition = FilteredSearchTokenKeys.searchByConditionKeyValue(null, null);
const condition = new FilteredSearchTokenKeys([], [], conditions)
.searchByConditionKeyValue(null, null);
expect(condition === null).toBe(true);
});
it('should return condition when found by tokenKey and value', () => {
const conditions = FilteredSearchTokenKeys.getConditions();
const result = FilteredSearchTokenKeys
const result = new FilteredSearchTokenKeys([], [], conditions)
.searchByConditionKeyValue(conditions[0].tokenKey, conditions[0].value);
expect(result).toEqual(conditions[0]);
});
......
import FilteredSearchTokenKeys from '~/filtered_search/filtered_search_token_keys';
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
import FilteredSearchTokenizer from '~/filtered_search/filtered_search_tokenizer';
describe('Filtered Search Tokenizer', () => {
const allowedKeys = FilteredSearchTokenKeys.getKeys();
const allowedKeys = IssuesFilteredSearchTokenKeys.getKeys();
describe('processTokens', () => {
it('returns for input containing only search value', () => {
......
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