Commit 4579d439 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'ph/addImprovedEmojiPickerToSetStatus' into 'master'

Adds the improved emoji picker to the set status modal

See merge request gitlab-org/gitlab!56370
parents 9fcb7398 b4666c87
...@@ -23,6 +23,11 @@ export default { ...@@ -23,6 +23,11 @@ export default {
required: false, required: false,
default: () => [], default: () => [],
}, },
dropdownClass: {
type: [Array, String, Object],
required: false,
default: () => [],
},
}, },
data() { data() {
return { return {
...@@ -78,6 +83,7 @@ export default { ...@@ -78,6 +83,7 @@ export default {
ref="dropdown" ref="dropdown"
:toggle-class="toggleClass" :toggle-class="toggleClass"
:boundary="getBoundaryElement()" :boundary="getBoundaryElement()"
:class="dropdownClass"
menu-class="dropdown-extended-height" menu-class="dropdown-extended-height"
category="tertiary" category="tertiary"
no-flip no-flip
......
...@@ -18,6 +18,7 @@ import { BV_SHOW_MODAL, BV_HIDE_MODAL } from '~/lib/utils/constants'; ...@@ -18,6 +18,7 @@ import { BV_SHOW_MODAL, BV_HIDE_MODAL } from '~/lib/utils/constants';
import { __, s__, sprintf } from '~/locale'; import { __, s__, sprintf } from '~/locale';
import { updateUserStatus } from '~/rest_api'; import { updateUserStatus } from '~/rest_api';
import { timeRanges } from '~/vue_shared/constants'; import { timeRanges } from '~/vue_shared/constants';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import EmojiMenuInModal from './emoji_menu_in_modal'; import EmojiMenuInModal from './emoji_menu_in_modal';
import { isUserBusy } from './utils'; import { isUserBusy } from './utils';
...@@ -44,10 +45,12 @@ export default { ...@@ -44,10 +45,12 @@ export default {
GlFormCheckbox, GlFormCheckbox,
GlDropdown, GlDropdown,
GlDropdownItem, GlDropdownItem,
EmojiPicker: () => import('~/emoji/components/picker.vue'),
}, },
directives: { directives: {
GlTooltip: GlTooltipDirective, GlTooltip: GlTooltipDirective,
}, },
mixins: [glFeatureFlagsMixin()],
props: { props: {
defaultEmoji: { defaultEmoji: {
type: String, type: String,
...@@ -102,7 +105,9 @@ export default { ...@@ -102,7 +105,9 @@ export default {
this.$root.$emit(BV_SHOW_MODAL, this.modalId); this.$root.$emit(BV_SHOW_MODAL, this.modalId);
}, },
beforeDestroy() { beforeDestroy() {
this.emojiMenu.destroy(); if (this.emojiMenu) {
this.emojiMenu.destroy();
}
}, },
methods: { methods: {
closeModal() { closeModal() {
...@@ -121,13 +126,16 @@ export default { ...@@ -121,13 +126,16 @@ export default {
this.noEmoji = this.emoji === ''; this.noEmoji = this.emoji === '';
this.defaultEmojiTag = Emoji.glEmojiTag(this.defaultEmoji); this.defaultEmojiTag = Emoji.glEmojiTag(this.defaultEmoji);
this.emojiMenu = new EmojiMenuInModal( if (!this.glFeatures.improvedEmojiPicker) {
Emoji, this.emojiMenu = new EmojiMenuInModal(
toggleEmojiMenuButtonSelector, Emoji,
emojiMenuClass, toggleEmojiMenuButtonSelector,
this.setEmoji, emojiMenuClass,
this.$refs.userStatusForm, this.setEmoji,
); this.$refs.userStatusForm,
);
}
this.setDefaultEmoji(); this.setDefaultEmoji();
}) })
.catch(() => createFlash(__('Failed to load emoji list.'))); .catch(() => createFlash(__('Failed to load emoji list.')));
...@@ -164,7 +172,12 @@ export default { ...@@ -164,7 +172,12 @@ export default {
this.emoji = emoji; this.emoji = emoji;
this.noEmoji = false; this.noEmoji = false;
this.clearEmoji(); this.clearEmoji();
this.emojiTag = emojiTag;
if (this.glFeatures.improvedEmojiPicker) {
this.emojiTag = Emoji.glEmojiTag(this.emoji);
} else {
this.emojiTag = emojiTag;
}
}, },
clearEmoji() { clearEmoji() {
if (this.emojiTag) { if (this.emojiTag) {
...@@ -241,7 +254,26 @@ export default { ...@@ -241,7 +254,26 @@ export default {
<div ref="userStatusForm" class="form-group position-relative m-0"> <div ref="userStatusForm" class="form-group position-relative m-0">
<div class="input-group gl-mb-5"> <div class="input-group gl-mb-5">
<span class="input-group-prepend"> <span class="input-group-prepend">
<emoji-picker
v-if="glFeatures.improvedEmojiPicker"
dropdown-class="gl-h-full"
toggle-class="btn emoji-menu-toggle-button gl-px-4! gl-rounded-top-right-none! gl-rounded-bottom-right-none!"
@click="setEmoji"
>
<template #button-content>
<span v-html="emojiTag"></span>
<span
v-show="noEmoji"
class="js-no-emoji-placeholder no-emoji-placeholder position-relative"
>
<gl-icon name="slight-smile" class="award-control-icon-neutral" />
<gl-icon name="smiley" class="award-control-icon-positive" />
<gl-icon name="smile" class="award-control-icon-super-positive" />
</span>
</template>
</emoji-picker>
<button <button
v-else
ref="toggleEmojiMenuButton" ref="toggleEmojiMenuButton"
v-gl-tooltip.bottom.hover v-gl-tooltip.bottom.hover
:title="s__('SetStatusModal|Add status emoji')" :title="s__('SetStatusModal|Add status emoji')"
......
...@@ -47,6 +47,7 @@ module Gitlab ...@@ -47,6 +47,7 @@ module Gitlab
push_frontend_feature_flag(:snippets_binary_blob, default_enabled: false) push_frontend_feature_flag(:snippets_binary_blob, default_enabled: false)
push_frontend_feature_flag(:usage_data_api, type: :ops, default_enabled: :yaml) push_frontend_feature_flag(:usage_data_api, type: :ops, default_enabled: :yaml)
push_frontend_feature_flag(:security_auto_fix, default_enabled: false) push_frontend_feature_flag(:security_auto_fix, default_enabled: false)
push_frontend_feature_flag(:improved_emoji_picker, default_enabled: :yaml)
end end
# Exposes the state of a feature flag to the frontend code. # Exposes the state of a feature flag to the frontend code.
......
...@@ -8,6 +8,8 @@ RSpec.describe 'User edit profile' do ...@@ -8,6 +8,8 @@ RSpec.describe 'User edit profile' do
let(:user) { create(:user) } let(:user) { create(:user) }
before do before do
stub_feature_flags(improved_emoji_picker: false)
sign_in(user) sign_in(user)
visit(profile_path) visit(profile_path)
end end
......
...@@ -2,6 +2,7 @@ import { GlModal, GlFormCheckbox } from '@gitlab/ui'; ...@@ -2,6 +2,7 @@ import { GlModal, GlFormCheckbox } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { initEmojiMock } from 'helpers/emoji'; import { initEmojiMock } from 'helpers/emoji';
import * as UserApi from '~/api/user_api'; import * as UserApi from '~/api/user_api';
import EmojiPicker from '~/emoji/components/picker.vue';
import { deprecatedCreateFlash as createFlash } from '~/flash'; import { deprecatedCreateFlash as createFlash } from '~/flash';
import SetStatusModalWrapper, { import SetStatusModalWrapper, {
AVAILABILITY_STATUS, AVAILABILITY_STATUS,
...@@ -25,7 +26,7 @@ describe('SetStatusModalWrapper', () => { ...@@ -25,7 +26,7 @@ describe('SetStatusModalWrapper', () => {
defaultEmoji, defaultEmoji,
}; };
const createComponent = (props = {}) => { const createComponent = (props = {}, improvedEmojiPicker = false) => {
return shallowMount(SetStatusModalWrapper, { return shallowMount(SetStatusModalWrapper, {
propsData: { propsData: {
...defaultProps, ...defaultProps,
...@@ -34,6 +35,9 @@ describe('SetStatusModalWrapper', () => { ...@@ -34,6 +35,9 @@ describe('SetStatusModalWrapper', () => {
mocks: { mocks: {
$toast, $toast,
}, },
provide: {
glFeatures: { improvedEmojiPicker },
},
}); });
}; };
...@@ -106,6 +110,20 @@ describe('SetStatusModalWrapper', () => { ...@@ -106,6 +110,20 @@ describe('SetStatusModalWrapper', () => {
}); });
}); });
describe('improvedEmojiPicker is true', () => {
beforeEach(async () => {
mockEmoji = await initEmojiMock();
wrapper = createComponent({}, true);
return initModal();
});
it('sets emojiTag when clicking in emoji picker', async () => {
await wrapper.findComponent(EmojiPicker).vm.$emit('click', 'thumbsup');
expect(wrapper.vm.emojiTag).toContain('data-name="thumbsup"');
});
});
describe('with no currentMessage set', () => { describe('with no currentMessage set', () => {
beforeEach(async () => { beforeEach(async () => {
mockEmoji = await initEmojiMock(); mockEmoji = await initEmojiMock();
......
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