Files
chatwoot/app/javascript/dashboard/modules/conversations/components/MessageContextMenu.vue
Sivin Varghese 79aa5a5d7f feat: Replace alertMixin usage with useAlert (#9793)
# Pull Request Template

## Description

This PR will replace the usage of `alertMixin` from the code base with
the `useAlert` composable.

Fixes
https://linear.app/chatwoot/issue/CW-3462/replace-alertmixin-usage-with-usealert

## Type of change

- [x] Breaking change (fix or feature that would cause existing
functionality not to work as expected)

## How Has This Been Tested?

Please refer this issue description

https://linear.app/chatwoot/issue/CW-3462/replace-alertmixin-usage-with-usealert


## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [ ] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules

---------

Co-authored-by: Sojan Jose <sojan@pepalo.com>
2024-07-23 16:41:11 +05:30

277 lines
7.4 KiB
Vue

<template>
<div class="context-menu">
<!-- Add To Canned Responses -->
<woot-modal
v-if="isCannedResponseModalOpen && enabledOptions['cannedResponse']"
:show.sync="isCannedResponseModalOpen"
:on-close="hideCannedResponseModal"
>
<add-canned-modal
:response-content="plainTextContent"
:on-close="hideCannedResponseModal"
/>
</woot-modal>
<!-- Translate Content -->
<translate-modal
v-if="showTranslateModal"
:content="messageContent"
:content-attributes="contentAttributes"
@close="onCloseTranslateModal"
/>
<!-- Confirm Deletion -->
<woot-delete-modal
v-if="showDeleteModal"
class="context-menu--delete-modal"
:show.sync="showDeleteModal"
:on-close="closeDeleteModal"
:on-confirm="confirmDeletion"
:title="$t('CONVERSATION.CONTEXT_MENU.DELETE_CONFIRMATION.TITLE')"
:message="$t('CONVERSATION.CONTEXT_MENU.DELETE_CONFIRMATION.MESSAGE')"
:confirm-text="$t('CONVERSATION.CONTEXT_MENU.DELETE_CONFIRMATION.DELETE')"
:reject-text="$t('CONVERSATION.CONTEXT_MENU.DELETE_CONFIRMATION.CANCEL')"
/>
<woot-button
icon="more-vertical"
color-scheme="secondary"
variant="clear"
size="small"
@click="handleOpen"
/>
<woot-context-menu
v-if="isOpen && !isCannedResponseModalOpen"
:x="contextMenuPosition.x"
:y="contextMenuPosition.y"
@close="handleClose"
>
<div class="menu-container">
<menu-item
v-if="enabledOptions['replyTo']"
:option="{
icon: 'arrow-reply',
label: $t('CONVERSATION.CONTEXT_MENU.REPLY_TO'),
}"
variant="icon"
@click="handleReplyTo"
/>
<menu-item
v-if="enabledOptions['copy']"
:option="{
icon: 'clipboard',
label: $t('CONVERSATION.CONTEXT_MENU.COPY'),
}"
variant="icon"
@click="handleCopy"
/>
<menu-item
v-if="enabledOptions['copy']"
:option="{
icon: 'translate',
label: $t('CONVERSATION.CONTEXT_MENU.TRANSLATE'),
}"
variant="icon"
@click="handleTranslate"
/>
<hr />
<menu-item
:option="{
icon: 'link',
label: $t('CONVERSATION.CONTEXT_MENU.COPY_PERMALINK'),
}"
variant="icon"
@click="copyLinkToMessage"
/>
<menu-item
v-if="enabledOptions['cannedResponse']"
:option="{
icon: 'comment-add',
label: $t('CONVERSATION.CONTEXT_MENU.CREATE_A_CANNED_RESPONSE'),
}"
variant="icon"
@click="showCannedResponseModal"
/>
<hr v-if="enabledOptions['delete']" />
<menu-item
v-if="enabledOptions['delete']"
:option="{
icon: 'delete',
label: $t('CONVERSATION.CONTEXT_MENU.DELETE'),
}"
variant="icon"
@click="openDeleteModal"
/>
</div>
</woot-context-menu>
</div>
</template>
<script>
import { useAlert } from 'dashboard/composables';
import { mapGetters } from 'vuex';
import messageFormatterMixin from 'shared/mixins/messageFormatterMixin';
import AddCannedModal from 'dashboard/routes/dashboard/settings/canned/AddCanned.vue';
import { copyTextToClipboard } from 'shared/helpers/clipboard';
import { conversationUrl, frontendURL } from '../../../helper/URLHelper';
import {
ACCOUNT_EVENTS,
CONVERSATION_EVENTS,
} from '../../../helper/AnalyticsHelper/events';
import TranslateModal from 'dashboard/components/widgets/conversation/bubble/TranslateModal.vue';
import MenuItem from '../../../components/widgets/conversation/contextMenu/menuItem.vue';
export default {
components: {
AddCannedModal,
TranslateModal,
MenuItem,
},
mixins: [messageFormatterMixin],
props: {
message: {
type: Object,
required: true,
},
isOpen: {
type: Boolean,
default: false,
},
enabledOptions: {
type: Object,
default: () => ({}),
},
contextMenuPosition: {
type: Object,
default: () => ({}),
},
},
data() {
return {
isCannedResponseModalOpen: false,
showTranslateModal: false,
showDeleteModal: false,
};
},
computed: {
...mapGetters({
getAccount: 'accounts/getAccount',
currentAccountId: 'getCurrentAccountId',
}),
plainTextContent() {
return this.getPlainText(this.messageContent);
},
conversationId() {
return this.message.conversation_id;
},
messageId() {
return this.message.id;
},
messageContent() {
return this.message.content;
},
contentAttributes() {
return this.message.content_attributes;
},
},
methods: {
async copyLinkToMessage() {
const fullConversationURL =
window.chatwootConfig.hostURL +
frontendURL(
conversationUrl({
id: this.conversationId,
accountId: this.currentAccountId,
})
);
await copyTextToClipboard(
`${fullConversationURL}?messageId=${this.messageId}`
);
useAlert(this.$t('CONVERSATION.CONTEXT_MENU.LINK_COPIED'));
this.handleClose();
},
async handleCopy() {
await copyTextToClipboard(this.plainTextContent);
useAlert(this.$t('CONTACT_PANEL.COPY_SUCCESSFUL'));
this.handleClose();
},
showCannedResponseModal() {
this.$track(ACCOUNT_EVENTS.ADDED_TO_CANNED_RESPONSE);
this.isCannedResponseModalOpen = true;
},
hideCannedResponseModal() {
this.isCannedResponseModalOpen = false;
this.handleClose();
},
handleOpen(e) {
this.$emit('open', e);
},
handleClose(e) {
this.$emit('close', e);
},
handleTranslate() {
const { locale } = this.getAccount(this.currentAccountId);
this.$store.dispatch('translateMessage', {
conversationId: this.conversationId,
messageId: this.messageId,
targetLanguage: locale || 'en',
});
this.$track(CONVERSATION_EVENTS.TRANSLATE_A_MESSAGE);
this.handleClose();
this.showTranslateModal = true;
},
handleReplyTo() {
this.$emit('replyTo', this.message);
this.handleClose();
},
onCloseTranslateModal() {
this.showTranslateModal = false;
},
openDeleteModal() {
this.handleClose();
this.showDeleteModal = true;
},
async confirmDeletion() {
try {
await this.$store.dispatch('deleteMessage', {
conversationId: this.conversationId,
messageId: this.messageId,
});
useAlert(this.$t('CONVERSATION.SUCCESS_DELETE_MESSAGE'));
this.handleClose();
} catch (error) {
useAlert(this.$t('CONVERSATION.FAIL_DELETE_MESSSAGE'));
}
},
closeDeleteModal() {
this.showDeleteModal = false;
},
},
};
</script>
<style lang="scss" scoped>
.menu-container {
@apply p-1 bg-white dark:bg-slate-900 shadow-xl rounded-md;
hr:first-child {
@apply hidden;
}
hr {
@apply m-1 border-b border-solid border-slate-50 dark:border-slate-800/50;
}
}
.context-menu--delete-modal {
::v-deep {
.modal-container {
@apply max-w-[30rem];
h2 {
@apply font-medium text-base;
}
}
.modal-footer {
@apply pt-4 pb-8 px-8;
}
}
}
</style>