Commit 935574ed authored by Alfredo Sumaran's avatar Alfredo Sumaran

Merge branch 'fix-visual-tokens' into 'master'

Prevent visual token dropdown from opening the wrong filter dropdown

See merge request !9789
parents 3016e774 86a3dee2
...@@ -80,30 +80,48 @@ ...@@ -80,30 +80,48 @@
} }
// Determines the full search query (visual tokens + input) // Determines the full search query (visual tokens + input)
static getSearchQuery() { static getSearchQuery(untilInput = false) {
const tokensContainer = document.querySelector('.tokens-container'); const tokens = [].slice.call(document.querySelectorAll('.tokens-container li'));
const values = []; const values = [];
[].forEach.call(tokensContainer.querySelectorAll('.js-visual-token'), (token) => { if (untilInput) {
const name = token.querySelector('.name'); const inputIndex = _.findIndex(tokens, t => t.classList.contains('input-token'));
const value = token.querySelector('.value'); // Add one to include input-token to the tokens array
const symbol = value && value.dataset.symbol ? value.dataset.symbol : ''; tokens.splice(inputIndex + 1);
let valueText = ''; }
if (value && value.innerText) { tokens.forEach((token) => {
valueText = value.innerText; if (token.classList.contains('js-visual-token')) {
} const name = token.querySelector('.name');
const value = token.querySelector('.value');
if (token.className.indexOf('filtered-search-token') !== -1) { const symbol = value && value.dataset.symbol ? value.dataset.symbol : '';
values.push(`${name.innerText.toLowerCase()}:${symbol}${valueText}`); let valueText = '';
} else {
values.push(name.innerText); if (value && value.innerText) {
valueText = value.innerText;
}
if (token.className.indexOf('filtered-search-token') !== -1) {
values.push(`${name.innerText.toLowerCase()}:${symbol}${valueText}`);
} else {
values.push(name.innerText);
}
} else if (token.classList.contains('input-token')) {
const { isLastVisualTokenValid } =
gl.FilteredSearchVisualTokens.getLastVisualTokenBeforeInput();
const input = document.querySelector('.filtered-search');
const inputValue = input && input.value;
if (isLastVisualTokenValid) {
values.push(inputValue);
} else {
const previous = values.pop();
values.push(`${previous}${inputValue}`);
}
} }
}); });
const input = document.querySelector('.filtered-search');
values.push(input && input.value);
return values.join(' '); return values.join(' ');
} }
......
...@@ -139,7 +139,7 @@ ...@@ -139,7 +139,7 @@
} }
setDropdown() { setDropdown() {
const query = gl.DropdownUtils.getSearchQuery(); const query = gl.DropdownUtils.getSearchQuery(true);
const { lastToken, searchToken } = this.tokenizer.processTokens(query); const { lastToken, searchToken } = this.tokenizer.processTokens(query);
if (this.currentDropdown) { if (this.currentDropdown) {
......
...@@ -363,10 +363,13 @@ ...@@ -363,10 +363,13 @@
tokenChange() { tokenChange() {
const dropdown = this.dropdownManager.mapping[this.dropdownManager.currentDropdown]; const dropdown = this.dropdownManager.mapping[this.dropdownManager.currentDropdown];
const currentDropdownRef = dropdown.reference;
this.setDropdownWrapper(); if (dropdown) {
currentDropdownRef.dispatchInputEvent(); const currentDropdownRef = dropdown.reference;
this.setDropdownWrapper();
currentDropdownRef.dispatchInputEvent();
}
} }
} }
......
...@@ -242,6 +242,23 @@ describe 'Visual tokens', js: true, feature: true do ...@@ -242,6 +242,23 @@ describe 'Visual tokens', js: true, feature: true do
end end
end end
describe 'editing a search term while editing another filter token' do
before do
input_filtered_search('author assignee:', submit: false)
first('.tokens-container .filtered-search-term').double_click
end
it 'opens hint dropdown' do
expect(page).to have_css('#js-dropdown-hint', visible: true)
end
it 'opens author dropdown' do
find('#js-dropdown-hint .filter-dropdown .filter-dropdown-item', text: 'author').click
expect(page).to have_css('#js-dropdown-author', visible: true)
end
end
describe 'add new token after editing existing token' do describe 'add new token after editing existing token' do
before do before do
input_filtered_search('author:@root assignee:none', submit: false) input_filtered_search('author:@root assignee:none', submit: false)
...@@ -319,4 +336,17 @@ describe 'Visual tokens', js: true, feature: true do ...@@ -319,4 +336,17 @@ describe 'Visual tokens', js: true, feature: true do
expect(token.find('.name').text).to eq('Author') expect(token.find('.name').text).to eq('Author')
end end
end end
describe 'search using incomplete visual tokens' do
before do
input_filtered_search('author:@root assignee:none', extra_space: false)
end
it 'tokenizes the search term to complete visual token' do
expect_tokens([
{ name: 'author', value: '@root' },
{ name: 'assignee', value: 'none' }
])
end
end
end end
...@@ -4,9 +4,14 @@ module FilteredSearchHelpers ...@@ -4,9 +4,14 @@ module FilteredSearchHelpers
end end
# Enables input to be set (similar to copy and paste) # Enables input to be set (similar to copy and paste)
def input_filtered_search(search_term, submit: true) def input_filtered_search(search_term, submit: true, extra_space: true)
# Add an extra space to engage visual tokens search = search_term
filtered_search.set("#{search_term} ") if extra_space
# Add an extra space to engage visual tokens
search = "#{search_term} "
end
filtered_search.set(search)
if submit if submit
filtered_search.send_keys(:enter) filtered_search.send_keys(:enter)
......
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