debian-mirror-gitlab/app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue

374 lines
11 KiB
Vue
Raw Normal View History

2018-12-05 23:21:45 +05:30
<script>
2021-04-29 21:17:54 +05:30
import {
GlToast,
GlModal,
GlTooltipDirective,
GlIcon,
GlFormCheckbox,
GlDropdown,
GlDropdownItem,
2021-11-11 11:23:49 +05:30
GlSafeHtmlDirective,
2021-04-29 21:17:54 +05:30
} from '@gitlab/ui';
2018-12-05 23:21:45 +05:30
import $ from 'jquery';
2021-02-22 17:27:13 +05:30
import Vue from 'vue';
2020-01-01 13:55:28 +05:30
import GfmAutoComplete from 'ee_else_ce/gfm_auto_complete';
2021-03-11 19:13:27 +05:30
import * as Emoji from '~/emoji';
2021-09-04 01:27:46 +05:30
import createFlash from '~/flash';
2021-03-11 19:13:27 +05:30
import { BV_SHOW_MODAL, BV_HIDE_MODAL } from '~/lib/utils/constants';
2021-04-29 21:17:54 +05:30
import { __, s__, sprintf } from '~/locale';
2021-03-08 18:12:59 +05:30
import { updateUserStatus } from '~/rest_api';
2021-04-29 21:17:54 +05:30
import { timeRanges } from '~/vue_shared/constants';
2021-09-04 01:27:46 +05:30
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
2018-12-05 23:21:45 +05:30
import EmojiMenuInModal from './emoji_menu_in_modal';
2021-03-11 19:13:27 +05:30
import { isUserBusy } from './utils';
2018-12-05 23:21:45 +05:30
const emojiMenuClass = 'js-modal-status-emoji-menu';
2021-01-29 00:20:46 +05:30
export const AVAILABILITY_STATUS = {
BUSY: 'busy',
NOT_SET: 'not_set',
};
2018-12-05 23:21:45 +05:30
2021-02-22 17:27:13 +05:30
Vue.use(GlToast);
2021-04-29 21:17:54 +05:30
const statusTimeRanges = [
{
label: __('Never'),
name: 'never',
},
...timeRanges,
];
2018-12-05 23:21:45 +05:30
export default {
components: {
2020-11-24 15:15:51 +05:30
GlIcon,
2018-12-13 13:39:08 +05:30
GlModal,
2021-01-29 00:20:46 +05:30
GlFormCheckbox,
2021-04-29 21:17:54 +05:30
GlDropdown,
GlDropdownItem,
2021-09-04 01:27:46 +05:30
EmojiPicker: () => import('~/emoji/components/picker.vue'),
2018-12-13 13:39:08 +05:30
},
directives: {
GlTooltip: GlTooltipDirective,
2021-11-11 11:23:49 +05:30
SafeHtml: GlSafeHtmlDirective,
2018-12-05 23:21:45 +05:30
},
2021-09-04 01:27:46 +05:30
mixins: [glFeatureFlagsMixin()],
2018-12-05 23:21:45 +05:30
props: {
2021-01-29 00:20:46 +05:30
defaultEmoji: {
type: String,
required: false,
default: '',
},
2018-12-05 23:21:45 +05:30
currentEmoji: {
type: String,
required: true,
},
currentMessage: {
type: String,
required: true,
},
2021-01-29 00:20:46 +05:30
currentAvailability: {
type: String,
required: false,
default: '',
},
2021-04-29 21:17:54 +05:30
currentClearStatusAfter: {
type: String,
required: false,
default: '',
},
2018-12-05 23:21:45 +05:30
},
data() {
return {
defaultEmojiTag: '',
emoji: this.currentEmoji,
emojiMenu: null,
emojiTag: '',
isEmojiMenuVisible: false,
message: this.currentMessage,
modalId: 'set-user-status-modal',
noEmoji: true,
2021-01-29 00:20:46 +05:30
availability: isUserBusy(this.currentAvailability),
2021-04-29 21:17:54 +05:30
clearStatusAfter: statusTimeRanges[0].label,
clearStatusAfterMessage: sprintf(s__('SetStatusModal|Your status resets on %{date}.'), {
date: this.currentClearStatusAfter,
}),
2018-12-05 23:21:45 +05:30
};
},
computed: {
2021-01-29 00:20:46 +05:30
isCustomEmoji() {
return this.emoji !== this.defaultEmoji;
},
2018-12-05 23:21:45 +05:30
isDirty() {
2021-01-29 00:20:46 +05:30
return Boolean(this.message.length || this.isCustomEmoji);
2018-12-05 23:21:45 +05:30
},
},
mounted() {
2021-03-11 19:13:27 +05:30
this.$root.$emit(BV_SHOW_MODAL, this.modalId);
2018-12-05 23:21:45 +05:30
},
beforeDestroy() {
2021-09-04 01:27:46 +05:30
if (this.emojiMenu) {
this.emojiMenu.destroy();
}
2018-12-05 23:21:45 +05:30
},
methods: {
closeModal() {
2021-03-11 19:13:27 +05:30
this.$root.$emit(BV_HIDE_MODAL, this.modalId);
2018-12-05 23:21:45 +05:30
},
setupEmojiListAndAutocomplete() {
const toggleEmojiMenuButtonSelector = '#set-user-status-modal .js-toggle-emoji-menu';
const emojiAutocomplete = new GfmAutoComplete();
emojiAutocomplete.setup($(this.$refs.statusMessageField), { emojis: true });
2020-07-28 23:09:34 +05:30
Emoji.initEmojiMap()
.then(() => {
2018-12-05 23:21:45 +05:30
if (this.emoji) {
this.emojiTag = Emoji.glEmojiTag(this.emoji);
}
this.noEmoji = this.emoji === '';
2021-01-29 00:20:46 +05:30
this.defaultEmojiTag = Emoji.glEmojiTag(this.defaultEmoji);
2018-12-05 23:21:45 +05:30
2021-09-04 01:27:46 +05:30
if (!this.glFeatures.improvedEmojiPicker) {
this.emojiMenu = new EmojiMenuInModal(
Emoji,
toggleEmojiMenuButtonSelector,
emojiMenuClass,
this.setEmoji,
this.$refs.userStatusForm,
);
}
2021-01-29 00:20:46 +05:30
this.setDefaultEmoji();
2018-12-05 23:21:45 +05:30
})
2021-09-04 01:27:46 +05:30
.catch(() =>
createFlash({
message: __('Failed to load emoji list.'),
}),
);
2018-12-05 23:21:45 +05:30
},
2020-06-23 00:09:42 +05:30
showEmojiMenu(e) {
e.stopPropagation();
2018-12-05 23:21:45 +05:30
this.isEmojiMenuVisible = true;
this.emojiMenu.showEmojiMenu($(this.$refs.toggleEmojiMenuButton));
},
hideEmojiMenu() {
if (!this.isEmojiMenuVisible) {
return;
}
this.isEmojiMenuVisible = false;
this.emojiMenu.hideMenuElement($(`.${emojiMenuClass}`));
},
setDefaultEmoji() {
const { emojiTag } = this;
2021-01-29 00:20:46 +05:30
const hasStatusMessage = Boolean(this.message.length);
2018-12-05 23:21:45 +05:30
if (hasStatusMessage && emojiTag) {
return;
}
if (hasStatusMessage) {
this.noEmoji = false;
this.emojiTag = this.defaultEmojiTag;
} else if (emojiTag === this.defaultEmojiTag) {
this.noEmoji = true;
this.clearEmoji();
}
},
setEmoji(emoji, emojiTag) {
this.emoji = emoji;
this.noEmoji = false;
this.clearEmoji();
2021-09-04 01:27:46 +05:30
if (this.glFeatures.improvedEmojiPicker) {
this.emojiTag = Emoji.glEmojiTag(this.emoji);
} else {
this.emojiTag = emojiTag;
}
2018-12-05 23:21:45 +05:30
},
clearEmoji() {
if (this.emojiTag) {
this.emojiTag = '';
}
},
clearStatusInputs() {
this.emoji = '';
this.message = '';
this.noEmoji = true;
this.clearEmoji();
this.hideEmojiMenu();
},
removeStatus() {
2021-01-29 00:20:46 +05:30
this.availability = false;
2018-12-05 23:21:45 +05:30
this.clearStatusInputs();
this.setStatus();
},
setStatus() {
2021-04-29 21:17:54 +05:30
const { emoji, message, availability, clearStatusAfter } = this;
2018-12-05 23:21:45 +05:30
2021-03-08 18:12:59 +05:30
updateUserStatus({
2018-12-05 23:21:45 +05:30
emoji,
message,
2021-01-29 00:20:46 +05:30
availability: availability ? AVAILABILITY_STATUS.BUSY : AVAILABILITY_STATUS.NOT_SET,
2021-04-29 21:17:54 +05:30
clearStatusAfter:
clearStatusAfter === statusTimeRanges[0].label
? null
: clearStatusAfter.replace(' ', '_'),
2018-12-05 23:21:45 +05:30
})
.then(this.onUpdateSuccess)
.catch(this.onUpdateFail);
},
onUpdateSuccess() {
2021-03-08 18:12:59 +05:30
this.$toast.show(s__('SetStatusModal|Status updated'));
2018-12-05 23:21:45 +05:30
this.closeModal();
window.location.reload();
},
onUpdateFail() {
2021-09-04 01:27:46 +05:30
createFlash({
message: s__(
"SetStatusModal|Sorry, we weren't able to set your status. Please try again later.",
),
});
2018-12-05 23:21:45 +05:30
this.closeModal();
},
2021-04-29 21:17:54 +05:30
setClearStatusAfter(after) {
this.clearStatusAfter = after;
},
2018-12-05 23:21:45 +05:30
},
2021-04-29 21:17:54 +05:30
statusTimeRanges,
2021-11-11 11:23:49 +05:30
safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] },
2022-01-26 12:08:38 +05:30
actionPrimary: { text: s__('SetStatusModal|Set status') },
actionSecondary: { text: s__('SetStatusModal|Remove status') },
2018-12-05 23:21:45 +05:30
};
</script>
<template>
2018-12-13 13:39:08 +05:30
<gl-modal
2018-12-05 23:21:45 +05:30
:title="s__('SetStatusModal|Set a status')"
:modal-id="modalId"
2022-01-26 12:08:38 +05:30
:action-primary="$options.actionPrimary"
:action-secondary="$options.actionSecondary"
2019-12-21 20:55:43 +05:30
modal-class="set-user-status-modal"
2018-12-05 23:21:45 +05:30
@shown="setupEmojiListAndAutocomplete"
@hide="hideEmojiMenu"
2022-01-26 12:08:38 +05:30
@primary="setStatus"
@secondary="removeStatus"
2018-12-05 23:21:45 +05:30
>
<div>
<input
v-model="emoji"
class="js-status-emoji-field"
type="hidden"
name="user[status][emoji]"
/>
2019-02-15 15:39:39 +05:30
<div ref="userStatusForm" class="form-group position-relative m-0">
2021-01-29 00:20:46 +05:30
<div class="input-group gl-mb-5">
2019-07-31 22:56:46 +05:30
<span class="input-group-prepend">
2021-09-04 01:27:46 +05:30
<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!"
2022-03-02 08:16:31 +05:30
boundary="viewport"
:right="false"
2021-09-04 01:27:46 +05:30
@click="setEmoji"
>
<template #button-content>
2021-11-11 11:23:49 +05:30
<span v-safe-html:[$options.safeHtmlConfig]="emojiTag"></span>
2021-09-04 01:27:46 +05:30
<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>
2018-12-05 23:21:45 +05:30
<button
2021-09-04 01:27:46 +05:30
v-else
2018-12-05 23:21:45 +05:30
ref="toggleEmojiMenuButton"
2021-01-29 00:20:46 +05:30
v-gl-tooltip.bottom.hover
2018-12-05 23:21:45 +05:30
:title="s__('SetStatusModal|Add status emoji')"
:aria-label="s__('SetStatusModal|Add status emoji')"
name="button"
type="button"
class="js-toggle-emoji-menu emoji-menu-toggle-button btn"
@click="showEmojiMenu"
>
2021-11-11 11:23:49 +05:30
<span v-safe-html:[$options.safeHtmlConfig]="emojiTag"></span>
2018-12-05 23:21:45 +05:30
<span
v-show="noEmoji"
class="js-no-emoji-placeholder no-emoji-placeholder position-relative"
>
2020-11-24 15:15:51 +05:30
<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" />
2018-12-05 23:21:45 +05:30
</span>
</button>
</span>
<input
ref="statusMessageField"
v-model="message"
:placeholder="s__('SetStatusModal|What\'s your status?')"
type="text"
class="form-control form-control input-lg js-status-message-field"
name="user[status][message]"
@keyup="setDefaultEmoji"
@keyup.enter.prevent
@click="hideEmojiMenu"
/>
2019-07-31 22:56:46 +05:30
<span v-show="isDirty" class="input-group-append">
2018-12-05 23:21:45 +05:30
<button
v-gl-tooltip.bottom
:title="s__('SetStatusModal|Clear status')"
:aria-label="s__('SetStatusModal|Clear status')"
name="button"
type="button"
class="js-clear-user-status-button clear-user-status btn"
2019-03-02 22:35:43 +05:30
@click="clearStatusInputs()"
2018-12-05 23:21:45 +05:30
>
2020-11-24 15:15:51 +05:30
<gl-icon name="close" />
2018-12-05 23:21:45 +05:30
</button>
</span>
</div>
2021-06-08 01:23:25 +05:30
<div class="form-group">
2021-01-29 00:20:46 +05:30
<div class="gl-display-flex">
<gl-form-checkbox
v-model="availability"
data-testid="user-availability-checkbox"
class="gl-mb-0"
>
<span class="gl-font-weight-bold">{{ s__('SetStatusModal|Busy') }}</span>
</gl-form-checkbox>
</div>
<div class="gl-display-flex">
<span class="gl-text-gray-600 gl-ml-5">
2021-12-11 22:18:48 +05:30
{{ s__('SetStatusModal|An indicator appears next to your name and avatar') }}
2021-01-29 00:20:46 +05:30
</span>
</div>
</div>
2021-04-29 21:17:54 +05:30
<div class="form-group">
<div class="gl-display-flex gl-align-items-baseline">
<span class="gl-mr-3">{{ s__('SetStatusModal|Clear status after') }}</span>
<gl-dropdown :text="clearStatusAfter" data-testid="clear-status-at-dropdown">
<gl-dropdown-item
v-for="after in $options.statusTimeRanges"
:key="after.name"
:data-testid="after.name"
@click="setClearStatusAfter(after.label)"
>{{ after.label }}</gl-dropdown-item
>
</gl-dropdown>
</div>
<div
v-if="currentClearStatusAfter.length"
class="gl-mt-3 gl-text-gray-400 gl-font-sm"
data-testid="clear-status-at-message"
>
{{ clearStatusAfterMessage }}
</div>
</div>
2018-12-05 23:21:45 +05:30
</div>
</div>
2018-12-13 13:39:08 +05:30
</gl-modal>
2018-12-05 23:21:45 +05:30
</template>