Clear emoji search in awards menu after picking emoji
Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/27655
This commit is contained in:
parent
75af8d9232
commit
0370c7c838
|
@ -6,6 +6,7 @@ import { glEmojiTag } from './behaviors/gl_emoji';
|
||||||
import isEmojiNameValid from './behaviors/gl_emoji/is_emoji_name_valid';
|
import isEmojiNameValid from './behaviors/gl_emoji/is_emoji_name_valid';
|
||||||
|
|
||||||
const animationEndEventString = 'animationend webkitAnimationEnd MSAnimationEnd oAnimationEnd';
|
const animationEndEventString = 'animationend webkitAnimationEnd MSAnimationEnd oAnimationEnd';
|
||||||
|
const transitionEndEventString = 'transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd';
|
||||||
const requestAnimationFrame = window.requestAnimationFrame ||
|
const requestAnimationFrame = window.requestAnimationFrame ||
|
||||||
window.webkitRequestAnimationFrame ||
|
window.webkitRequestAnimationFrame ||
|
||||||
window.mozRequestAnimationFrame ||
|
window.mozRequestAnimationFrame ||
|
||||||
|
@ -103,8 +104,9 @@ function AwardsHandler() {
|
||||||
const $glEmojiElement = $target.find('gl-emoji');
|
const $glEmojiElement = $target.find('gl-emoji');
|
||||||
const $spriteIconElement = $target.find('.icon');
|
const $spriteIconElement = $target.find('.icon');
|
||||||
const emoji = ($glEmojiElement.length ? $glEmojiElement : $spriteIconElement).data('name');
|
const emoji = ($glEmojiElement.length ? $glEmojiElement : $spriteIconElement).data('name');
|
||||||
|
|
||||||
$target.closest('.js-awards-block').addClass('current');
|
$target.closest('.js-awards-block').addClass('current');
|
||||||
return this.addAward(this.getVotesBlock(), this.getAwardUrl(), emoji);
|
this.addAward(this.getVotesBlock(), this.getAwardUrl(), emoji);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,12 +130,12 @@ AwardsHandler.prototype.showEmojiMenu = function showEmojiMenu($addBtn) {
|
||||||
if ($menu.is('.is-visible')) {
|
if ($menu.is('.is-visible')) {
|
||||||
$addBtn.removeClass('is-active');
|
$addBtn.removeClass('is-active');
|
||||||
$menu.removeClass('is-visible');
|
$menu.removeClass('is-visible');
|
||||||
$('#emoji_search').blur();
|
$('.js-emoji-menu-search').blur();
|
||||||
} else {
|
} else {
|
||||||
$addBtn.addClass('is-active');
|
$addBtn.addClass('is-active');
|
||||||
this.positionMenu($menu, $addBtn);
|
this.positionMenu($menu, $addBtn);
|
||||||
$menu.addClass('is-visible');
|
$menu.addClass('is-visible');
|
||||||
$('#emoji_search').focus();
|
$('.js-emoji-menu-search').focus();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$addBtn.addClass('is-loading is-active');
|
$addBtn.addClass('is-loading is-active');
|
||||||
|
@ -143,7 +145,7 @@ AwardsHandler.prototype.showEmojiMenu = function showEmojiMenu($addBtn) {
|
||||||
this.positionMenu($createdMenu, $addBtn);
|
this.positionMenu($createdMenu, $addBtn);
|
||||||
return setTimeout(() => {
|
return setTimeout(() => {
|
||||||
$createdMenu.addClass('is-visible');
|
$createdMenu.addClass('is-visible');
|
||||||
$('#emoji_search').focus();
|
$('.js-emoji-menu-search').focus();
|
||||||
}, 200);
|
}, 200);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -174,7 +176,7 @@ AwardsHandler.prototype.createEmojiMenu = function createEmojiMenu(callback) {
|
||||||
|
|
||||||
const emojiMenuMarkup = `
|
const emojiMenuMarkup = `
|
||||||
<div class="emoji-menu">
|
<div class="emoji-menu">
|
||||||
<input type="text" name="emoji_search" id="emoji_search" value="" class="emoji-search search-input form-control" placeholder="Search emoji" />
|
<input type="text" name="emoji-menu-search" value="" class="js-emoji-menu-search emoji-search search-input form-control" placeholder="Search emoji" />
|
||||||
|
|
||||||
<div class="emoji-menu-content">
|
<div class="emoji-menu-content">
|
||||||
${frequentlyUsedCatgegory}
|
${frequentlyUsedCatgegory}
|
||||||
|
@ -474,24 +476,41 @@ AwardsHandler.prototype.getFrequentlyUsedEmojis = function getFrequentlyUsedEmoj
|
||||||
};
|
};
|
||||||
|
|
||||||
AwardsHandler.prototype.setupSearch = function setupSearch() {
|
AwardsHandler.prototype.setupSearch = function setupSearch() {
|
||||||
this.registerEventListener('on', $('input.emoji-search'), 'input', (e) => {
|
const $search = $('.js-emoji-menu-search');
|
||||||
|
|
||||||
|
this.registerEventListener('on', $search, 'input', (e) => {
|
||||||
const term = $(e.target).val().trim();
|
const term = $(e.target).val().trim();
|
||||||
// Clean previous search results
|
this.searchEmojis(term);
|
||||||
$('ul.emoji-menu-search, h5.emoji-search-title').remove();
|
});
|
||||||
if (term.length > 0) {
|
|
||||||
// Generate a search result block
|
const $menu = $('.emoji-menu');
|
||||||
const h5 = $('<h5 class="emoji-search-title"/>').text('Search results');
|
this.registerEventListener('on', $menu, transitionEndEventString, (e) => {
|
||||||
const foundEmojis = this.searchEmojis(term).show();
|
if (e.target === e.currentTarget) {
|
||||||
const ul = $('<ul>').addClass('emoji-menu-list emoji-menu-search').append(foundEmojis);
|
// Clear the search
|
||||||
$('.emoji-menu-content ul, .emoji-menu-content h5').hide();
|
this.searchEmojis('');
|
||||||
$('.emoji-menu-content').append(h5).append(ul);
|
|
||||||
} else {
|
|
||||||
$('.emoji-menu-content').children().show();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
AwardsHandler.prototype.searchEmojis = function searchEmojis(term) {
|
AwardsHandler.prototype.searchEmojis = function searchEmojis(term) {
|
||||||
|
const $search = $('.js-emoji-menu-search');
|
||||||
|
$search.val(term);
|
||||||
|
|
||||||
|
// Clean previous search results
|
||||||
|
$('ul.emoji-menu-search, h5.emoji-search-title').remove();
|
||||||
|
if (term.length > 0) {
|
||||||
|
// Generate a search result block
|
||||||
|
const h5 = $('<h5 class="emoji-search-title"/>').text('Search results');
|
||||||
|
const foundEmojis = this.findMatchingEmojiElements(term).show();
|
||||||
|
const ul = $('<ul>').addClass('emoji-menu-list emoji-menu-search').append(foundEmojis);
|
||||||
|
$('.emoji-menu-content ul, .emoji-menu-content h5').hide();
|
||||||
|
$('.emoji-menu-content').append(h5).append(ul);
|
||||||
|
} else {
|
||||||
|
$('.emoji-menu-content').children().show();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
AwardsHandler.prototype.findMatchingEmojiElements = function findMatchingEmojiElements(term) {
|
||||||
const safeTerm = term.toLowerCase();
|
const safeTerm = term.toLowerCase();
|
||||||
|
|
||||||
const namesMatchingAlias = [];
|
const namesMatchingAlias = [];
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
title: Clear emoji search in awards menu after picking emoji
|
||||||
|
merge_request:
|
||||||
|
author:
|
|
@ -87,7 +87,7 @@ class Spinach::Features::AwardEmoji < Spinach::FeatureSteps
|
||||||
end
|
end
|
||||||
|
|
||||||
step 'I search "hand"' do
|
step 'I search "hand"' do
|
||||||
fill_in 'emoji_search', with: 'hand'
|
fill_in 'emoji-menu-search', with: 'hand'
|
||||||
end
|
end
|
||||||
|
|
||||||
step 'I see search result for "hand"' do
|
step 'I see search result for "hand"' do
|
||||||
|
@ -101,7 +101,7 @@ class Spinach::Features::AwardEmoji < Spinach::FeatureSteps
|
||||||
end
|
end
|
||||||
|
|
||||||
step 'The search field is focused' do
|
step 'The search field is focused' do
|
||||||
expect(page).to have_selector('#emoji_search')
|
expect(page).to have_selector('.js-emoji-menu-search')
|
||||||
expect(page.evaluate_script('document.activeElement.id')).to eq('emoji_search')
|
expect(page.evaluate_script("document.activeElement.classList.contains('js-emoji-menu-search')")).to eq(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -63,7 +63,7 @@ import AwardsHandler from '~/awards_handler';
|
||||||
$emojiMenu = $('.emoji-menu');
|
$emojiMenu = $('.emoji-menu');
|
||||||
expect($emojiMenu.length).toBe(1);
|
expect($emojiMenu.length).toBe(1);
|
||||||
expect($emojiMenu.hasClass('is-visible')).toBe(true);
|
expect($emojiMenu.hasClass('is-visible')).toBe(true);
|
||||||
expect($emojiMenu.find('#emoji_search').length).toBe(1);
|
expect($emojiMenu.find('.js-emoji-menu-search').length).toBe(1);
|
||||||
return expect($('.js-awards-block.current').length).toBe(1);
|
return expect($('.js-awards-block.current').length).toBe(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -194,16 +194,35 @@ import AwardsHandler from '~/awards_handler';
|
||||||
return expect($thumbsUpEmoji.data("original-title")).toBe('sam');
|
return expect($thumbsUpEmoji.data("original-title")).toBe('sam');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('search', function() {
|
describe('::searchEmojis', () => {
|
||||||
return it('should filter the emoji', function(done) {
|
it('should filter the emoji', function(done) {
|
||||||
return openAndWaitForEmojiMenu()
|
return openAndWaitForEmojiMenu()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
expect($('[data-name=angel]').is(':visible')).toBe(true);
|
expect($('[data-name=angel]').is(':visible')).toBe(true);
|
||||||
expect($('[data-name=anger]').is(':visible')).toBe(true);
|
expect($('[data-name=anger]').is(':visible')).toBe(true);
|
||||||
$('#emoji_search').val('ali').trigger('input');
|
awardsHandler.searchEmojis('ali');
|
||||||
expect($('[data-name=angel]').is(':visible')).toBe(false);
|
expect($('[data-name=angel]').is(':visible')).toBe(false);
|
||||||
expect($('[data-name=anger]').is(':visible')).toBe(false);
|
expect($('[data-name=anger]').is(':visible')).toBe(false);
|
||||||
expect($('[data-name=alien]').is(':visible')).toBe(true);
|
expect($('[data-name=alien]').is(':visible')).toBe(true);
|
||||||
|
expect($('.js-emoji-menu-search').val()).toBe('ali');
|
||||||
|
})
|
||||||
|
.then(done)
|
||||||
|
.catch((err) => {
|
||||||
|
done.fail(`Failed to open and build emoji menu: ${err.message}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should clear the search when searching for nothing', function(done) {
|
||||||
|
return openAndWaitForEmojiMenu()
|
||||||
|
.then(() => {
|
||||||
|
awardsHandler.searchEmojis('ali');
|
||||||
|
expect($('[data-name=angel]').is(':visible')).toBe(false);
|
||||||
|
expect($('[data-name=anger]').is(':visible')).toBe(false);
|
||||||
|
expect($('[data-name=alien]').is(':visible')).toBe(true);
|
||||||
|
awardsHandler.searchEmojis('');
|
||||||
|
expect($('[data-name=angel]').is(':visible')).toBe(true);
|
||||||
|
expect($('[data-name=anger]').is(':visible')).toBe(true);
|
||||||
|
expect($('[data-name=alien]').is(':visible')).toBe(true);
|
||||||
|
expect($('.js-emoji-menu-search').val()).toBe('');
|
||||||
})
|
})
|
||||||
.then(done)
|
.then(done)
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
@ -211,6 +230,7 @@ import AwardsHandler from '~/awards_handler';
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('emoji menu', function() {
|
describe('emoji menu', function() {
|
||||||
const emojiSelector = '[data-name="sunglasses"]';
|
const emojiSelector = '[data-name="sunglasses"]';
|
||||||
const openEmojiMenuAndAddEmoji = function() {
|
const openEmojiMenuAndAddEmoji = function() {
|
||||||
|
|
Loading…
Reference in New Issue