Add logic for dynamically selecting which dropdown to load [skip ci]
This commit is contained in:
parent
44187782bf
commit
64d46a3e80
3 changed files with 72 additions and 20 deletions
|
@ -77,42 +77,77 @@
|
|||
}
|
||||
}
|
||||
|
||||
let dropdownHint;
|
||||
|
||||
class FilteredSearchManager {
|
||||
constructor() {
|
||||
this.tokenizer = gl.FilteredSearchTokenizer;
|
||||
this.bindEvents();
|
||||
loadSearchParamsFromURL();
|
||||
this.setDropdown();
|
||||
}
|
||||
|
||||
static fillInWord(word) {
|
||||
const originalValue = document.querySelector('.filtered-search').value;
|
||||
document.querySelector('.filtered-search').value = `${originalValue} ${word.trim()}`;
|
||||
static addWordToInput(word, addSpace) {
|
||||
const hasExistingValue = document.querySelector('.filtered-search').value.length !== 0;
|
||||
document.querySelector('.filtered-search').value += hasExistingValue && addSpace ? ` ${word}` : word;
|
||||
}
|
||||
|
||||
static loadDropdown(dropdownName) {
|
||||
loadDropdown(dropdownName = '') {
|
||||
dropdownName = dropdownName.toLowerCase();
|
||||
|
||||
const match = gl.FilteredSearchTokenKeys.get().filter(value => value.key === dropdownName)[0];
|
||||
|
||||
if (match) {
|
||||
if (match && this.currentDropdown !== match.key) {
|
||||
console.log(`🦄 load ${match.key} dropdown`);
|
||||
this.currentDropdown = match.key;
|
||||
} else if (!match && this.currentDropdown !== 'hint') {
|
||||
console.log('🦄 load hint dropdown');
|
||||
this.currentDropdown = 'hint';
|
||||
|
||||
if (!dropdownHint) {
|
||||
dropdownHint = new gl.DropdownHint(document.querySelector('#js-dropdown-hint'), document.querySelector('.filtered-search'))
|
||||
}
|
||||
|
||||
dropdownHint.render();
|
||||
}
|
||||
}
|
||||
|
||||
setDropdown() {
|
||||
const { lastToken } = this.tokenizer.processTokens(document.querySelector('.filtered-search').value);
|
||||
|
||||
if (typeof lastToken === 'string') {
|
||||
// Token is not fully initialized yet
|
||||
// because it has no value
|
||||
// Eg. token = 'label:'
|
||||
const { tokenKey } = this.tokenizer.parseToken(lastToken);
|
||||
this.loadDropdown(tokenKey);
|
||||
} else if (lastToken.hasOwnProperty('key')) {
|
||||
// Token has been initialized into an object
|
||||
// because it has a value
|
||||
this.loadDropdown(lastToken.key);
|
||||
} else {
|
||||
this.loadDropdown('hint');
|
||||
}
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
const filteredSearchInput = document.querySelector('.filtered-search');
|
||||
|
||||
filteredSearchInput.addEventListener('input', this.processInput.bind(this));
|
||||
filteredSearchInput.addEventListener('input', this.setDropdown.bind(this));
|
||||
filteredSearchInput.addEventListener('input', toggleClearSearchButton);
|
||||
filteredSearchInput.addEventListener('keydown', this.checkForEnter.bind(this));
|
||||
|
||||
document.querySelector('.clear-search').addEventListener('click', clearSearch);
|
||||
}
|
||||
|
||||
// TODO: This is only used for testing, remove when going to PRO
|
||||
processInput(e) {
|
||||
checkDropdownToken(e) {
|
||||
const input = e.target.value;
|
||||
this.tokenizer.processTokens(input);
|
||||
const { lastToken } = this.tokenizer.processTokens(input);
|
||||
|
||||
// Check for dropdown token
|
||||
if (lastToken[lastToken.length - 1] === ':') {
|
||||
const token = lastToken.slice(0, -1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
checkForEnter(e) {
|
||||
|
|
|
@ -3,11 +3,30 @@
|
|||
class FilteredSearchTokenizer {
|
||||
// TODO: Remove when going to pro
|
||||
static printTokens(tokens, searchToken, lastToken) {
|
||||
console.log('tokens:');
|
||||
tokens.forEach(token => console.log(token));
|
||||
console.log(`search: ${searchToken}`);
|
||||
console.log('last token:');
|
||||
console.log(lastToken);
|
||||
// console.log('tokens:');
|
||||
// tokens.forEach(token => console.log(token));
|
||||
// console.log(`search: ${searchToken}`);
|
||||
// console.log('last token:');
|
||||
// console.log(lastToken);
|
||||
}
|
||||
|
||||
static parseToken(input) {
|
||||
const colonIndex = input.indexOf(':');
|
||||
let tokenKey;
|
||||
let tokenValue;
|
||||
let tokenSymbol;
|
||||
|
||||
if (colonIndex !== -1) {
|
||||
tokenKey = input.slice(0, colonIndex).toLowerCase();
|
||||
tokenValue = input.slice(colonIndex + 1);
|
||||
tokenSymbol = tokenValue[0];
|
||||
}
|
||||
|
||||
return {
|
||||
tokenKey,
|
||||
tokenValue,
|
||||
tokenSymbol,
|
||||
}
|
||||
}
|
||||
|
||||
static processTokens(input) {
|
||||
|
@ -43,10 +62,8 @@
|
|||
const colonIndex = i.indexOf(':');
|
||||
|
||||
if (colonIndex !== -1) {
|
||||
const tokenKey = i.slice(0, colonIndex).toLowerCase();
|
||||
const tokenValue = i.slice(colonIndex + 1);
|
||||
const tokenSymbol = tokenValue[0];
|
||||
console.log(tokenSymbol)
|
||||
const { tokenKey, tokenValue, tokenSymbol } = gl.FilteredSearchTokenizer.parseToken(i);
|
||||
|
||||
const keyMatch = validTokenKeys.filter(v => v.key === tokenKey)[0];
|
||||
const symbolMatch = validTokenKeys.filter(v => v.symbol === tokenSymbol)[0];
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
class: "check_all_issues left"
|
||||
.issues-other-filters.filtered-search-container
|
||||
.filtered-search-input-container
|
||||
%input.form-control.filtered-search{ placeholder: 'Search or filter results...' }
|
||||
%input.form-control.filtered-search{ placeholder: 'Search or filter results...', 'data-id' => 'filtered-search' }
|
||||
= icon('filter')
|
||||
%button.clear-search.hidden{ type: 'button' }
|
||||
= icon('times')
|
||||
|
|
Loading…
Reference in a new issue