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 @@
}
// Determines the full search query (visual tokens + input)
static getSearchQuery() {
const tokensContainer = document.querySelector('.tokens-container');
static getSearchQuery(untilInput = false) {
const tokens = [].slice.call(document.querySelectorAll('.tokens-container li'));
const values = [];
[].forEach.call(tokensContainer.querySelectorAll('.js-visual-token'), (token) => {
const name = token.querySelector('.name');
const value = token.querySelector('.value');
const symbol = value && value.dataset.symbol ? value.dataset.symbol : '';
let valueText = '';
if (untilInput) {
const inputIndex = _.findIndex(tokens, t => t.classList.contains('input-token'));
// Add one to include input-token to the tokens array
tokens.splice(inputIndex + 1);
}
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);
tokens.forEach((token) => {
if (token.classList.contains('js-visual-token')) {
const name = token.querySelector('.name');
const value = token.querySelector('.value');
const symbol = value && value.dataset.symbol ? value.dataset.symbol : '';
let valueText = '';
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(' ');
}
......
......@@ -139,7 +139,7 @@
}
setDropdown() {
const query = gl.DropdownUtils.getSearchQuery();
const query = gl.DropdownUtils.getSearchQuery(true);
const { lastToken, searchToken } = this.tokenizer.processTokens(query);
if (this.currentDropdown) {
......
......@@ -363,10 +363,13 @@
tokenChange() {
const dropdown = this.dropdownManager.mapping[this.dropdownManager.currentDropdown];
const currentDropdownRef = dropdown.reference;
this.setDropdownWrapper();
currentDropdownRef.dispatchInputEvent();
if (dropdown) {
const currentDropdownRef = dropdown.reference;
this.setDropdownWrapper();
currentDropdownRef.dispatchInputEvent();
}
}
}
......
......@@ -242,6 +242,23 @@ describe 'Visual tokens', js: true, feature: true do
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
before do
input_filtered_search('author:@root assignee:none', submit: false)
......@@ -319,4 +336,17 @@ describe 'Visual tokens', js: true, feature: true do
expect(token.find('.name').text).to eq('Author')
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
......@@ -4,9 +4,14 @@ module FilteredSearchHelpers
end
# Enables input to be set (similar to copy and paste)
def input_filtered_search(search_term, submit: true)
# Add an extra space to engage visual tokens
filtered_search.set("#{search_term} ")
def input_filtered_search(search_term, submit: true, extra_space: true)
search = search_term
if extra_space
# Add an extra space to engage visual tokens
search = "#{search_term} "
end
filtered_search.set(search)
if submit
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