Merge branch 'develop' into fix/idb-cache-cleanup
This commit is contained in:
@@ -830,7 +830,13 @@ useEmitter(BUS_EVENTS.INSERT_INTO_RICH_EDITOR, insertContentIntoEditor);
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div ref="editorRoot" class="relative w-full">
|
<div
|
||||||
|
ref="editorRoot"
|
||||||
|
class="relative w-full"
|
||||||
|
:class="{
|
||||||
|
'opacity-50 cursor-not-allowed pointer-events-none': disabled,
|
||||||
|
}"
|
||||||
|
>
|
||||||
<TagAgents
|
<TagAgents
|
||||||
v-if="showUserMentions && isPrivate"
|
v-if="showUserMentions && isPrivate"
|
||||||
:search-key="mentionSearchKey"
|
:search-key="mentionSearchKey"
|
||||||
|
|||||||
@@ -122,6 +122,10 @@ export default {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
isEditorDisabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
emits: [
|
emits: [
|
||||||
'replaceText',
|
'replaceText',
|
||||||
@@ -130,7 +134,7 @@ export default {
|
|||||||
'selectContentTemplate',
|
'selectContentTemplate',
|
||||||
'toggleQuotedReply',
|
'toggleQuotedReply',
|
||||||
],
|
],
|
||||||
setup() {
|
setup(props) {
|
||||||
const { setSignatureFlagForInbox, fetchSignatureFlagFromUISettings } =
|
const { setSignatureFlagForInbox, fetchSignatureFlagFromUISettings } =
|
||||||
useUISettings();
|
useUISettings();
|
||||||
|
|
||||||
@@ -139,6 +143,9 @@ export default {
|
|||||||
const keyboardEvents = {
|
const keyboardEvents = {
|
||||||
'$mod+Alt+KeyA': {
|
'$mod+Alt+KeyA': {
|
||||||
action: () => {
|
action: () => {
|
||||||
|
// Skip if editor is disabled (e.g., WhatsApp 24-hour window expired)
|
||||||
|
if (props.isEditorDisabled) return;
|
||||||
|
|
||||||
// TODO: This is really hacky, we need to replace the file picker component with
|
// TODO: This is really hacky, we need to replace the file picker component with
|
||||||
// a custom one, where the logic and the component markup is isolated.
|
// a custom one, where the logic and the component markup is isolated.
|
||||||
// Once we have the custom component, we can remove the hacky logic below.
|
// Once we have the custom component, we can remove the hacky logic below.
|
||||||
@@ -146,7 +153,7 @@ export default {
|
|||||||
const uploadTriggerButton = document.querySelector(
|
const uploadTriggerButton = document.querySelector(
|
||||||
'#conversationAttachment'
|
'#conversationAttachment'
|
||||||
);
|
);
|
||||||
uploadTriggerButton.click();
|
if (uploadTriggerButton) uploadTriggerButton.click();
|
||||||
},
|
},
|
||||||
allowOnFocusedInput: true,
|
allowOnFocusedInput: true,
|
||||||
},
|
},
|
||||||
@@ -177,9 +184,11 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
showAttachButton() {
|
showAttachButton() {
|
||||||
|
if (this.isEditorDisabled) return false;
|
||||||
return this.showFileUpload || this.isNote;
|
return this.showFileUpload || this.isNote;
|
||||||
},
|
},
|
||||||
showAudioRecorderButton() {
|
showAudioRecorderButton() {
|
||||||
|
if (this.isEditorDisabled) return false;
|
||||||
if (this.isALineChannel) {
|
if (this.isALineChannel) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -197,6 +206,7 @@ export default {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
showAudioPlayStopButton() {
|
showAudioPlayStopButton() {
|
||||||
|
if (this.isEditorDisabled) return false;
|
||||||
return this.showAudioRecorder && this.isRecordingAudio;
|
return this.showAudioRecorder && this.isRecordingAudio;
|
||||||
},
|
},
|
||||||
isInstagramDM() {
|
isInstagramDM() {
|
||||||
@@ -236,6 +246,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
showMessageSignatureButton() {
|
showMessageSignatureButton() {
|
||||||
|
if (this.isEditorDisabled) return false;
|
||||||
return !this.isOnPrivateNote;
|
return !this.isOnPrivateNote;
|
||||||
},
|
},
|
||||||
sendWithSignature() {
|
sendWithSignature() {
|
||||||
@@ -280,6 +291,7 @@ export default {
|
|||||||
<div class="flex justify-between p-3" :class="wrapClass">
|
<div class="flex justify-between p-3" :class="wrapClass">
|
||||||
<div class="left-wrap">
|
<div class="left-wrap">
|
||||||
<NextButton
|
<NextButton
|
||||||
|
v-if="!isEditorDisabled"
|
||||||
v-tooltip.top-end="$t('CONVERSATION.REPLYBOX.TIP_EMOJI_ICON')"
|
v-tooltip.top-end="$t('CONVERSATION.REPLYBOX.TIP_EMOJI_ICON')"
|
||||||
icon="i-ph-smiley-sticker"
|
icon="i-ph-smiley-sticker"
|
||||||
slate
|
slate
|
||||||
@@ -288,6 +300,7 @@ export default {
|
|||||||
@click="toggleEmojiPicker"
|
@click="toggleEmojiPicker"
|
||||||
/>
|
/>
|
||||||
<FileUpload
|
<FileUpload
|
||||||
|
v-if="showAttachButton"
|
||||||
ref="uploadRef"
|
ref="uploadRef"
|
||||||
v-tooltip.top-end="$t('CONVERSATION.REPLYBOX.TIP_ATTACH_ICON')"
|
v-tooltip.top-end="$t('CONVERSATION.REPLYBOX.TIP_ATTACH_ICON')"
|
||||||
input-id="conversationAttachment"
|
input-id="conversationAttachment"
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ export default {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
isEditorDisabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
conversationId: {
|
conversationId: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: null,
|
default: null,
|
||||||
@@ -157,7 +161,7 @@ export default {
|
|||||||
<div class="relative">
|
<div class="relative">
|
||||||
<NextButton
|
<NextButton
|
||||||
ghost
|
ghost
|
||||||
:disabled="disabled"
|
:disabled="disabled || isEditorDisabled"
|
||||||
:class="{
|
:class="{
|
||||||
'text-n-violet-9 hover:enabled:!bg-n-violet-3': !showCopilotMenu,
|
'text-n-violet-9 hover:enabled:!bg-n-violet-3': !showCopilotMenu,
|
||||||
'text-n-violet-9 bg-n-violet-3': showCopilotMenu,
|
'text-n-violet-9 bg-n-violet-3': showCopilotMenu,
|
||||||
|
|||||||
@@ -199,6 +199,11 @@ export default {
|
|||||||
return this.$store.getters['inboxes/getInbox'](this.inboxId);
|
return this.$store.getters['inboxes/getInbox'](this.inboxId);
|
||||||
},
|
},
|
||||||
messagePlaceHolder() {
|
messagePlaceHolder() {
|
||||||
|
if (this.isEditorDisabled) {
|
||||||
|
return this.isAWhatsAppChannel
|
||||||
|
? this.$t('CONVERSATION.FOOTER.MESSAGING_RESTRICTED_WHATSAPP')
|
||||||
|
: this.$t('CONVERSATION.FOOTER.MESSAGING_RESTRICTED');
|
||||||
|
}
|
||||||
return this.isPrivate
|
return this.isPrivate
|
||||||
? this.$t('CONVERSATION.FOOTER.PRIVATE_MSG_INPUT')
|
? this.$t('CONVERSATION.FOOTER.PRIVATE_MSG_INPUT')
|
||||||
: this.$t('CONVERSATION.FOOTER.MSG_INPUT');
|
: this.$t('CONVERSATION.FOOTER.MSG_INPUT');
|
||||||
@@ -210,6 +215,7 @@ export default {
|
|||||||
return this.maxLength - this.message.length;
|
return this.maxLength - this.message.length;
|
||||||
},
|
},
|
||||||
isReplyButtonDisabled() {
|
isReplyButtonDisabled() {
|
||||||
|
if (this.isEditorDisabled) return true;
|
||||||
if (this.isATwitterInbox) return true;
|
if (this.isATwitterInbox) return true;
|
||||||
if (this.hasAttachments || this.hasRecordedAudio) return false;
|
if (this.hasAttachments || this.hasRecordedAudio) return false;
|
||||||
|
|
||||||
@@ -418,6 +424,13 @@ export default {
|
|||||||
isDefaultEditorMode() {
|
isDefaultEditorMode() {
|
||||||
return !this.showAudioRecorderEditor && !this.copilot.isActive.value;
|
return !this.showAudioRecorderEditor && !this.copilot.isActive.value;
|
||||||
},
|
},
|
||||||
|
isEditorDisabled() {
|
||||||
|
return (
|
||||||
|
this.isAWhatsAppChannel &&
|
||||||
|
!this.isOnPrivateNote &&
|
||||||
|
!this.currentChat.can_reply
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
currentChat(conversation, oldConversation) {
|
currentChat(conversation, oldConversation) {
|
||||||
@@ -677,6 +690,9 @@ export default {
|
|||||||
// Don't handle paste if compose new conversation modal is open
|
// Don't handle paste if compose new conversation modal is open
|
||||||
if (this.newConversationModalActive) return;
|
if (this.newConversationModalActive) return;
|
||||||
|
|
||||||
|
// Don't handle paste if editor is disabled
|
||||||
|
if (this.isEditorDisabled) return;
|
||||||
|
|
||||||
// Filter valid files (non-zero size)
|
// Filter valid files (non-zero size)
|
||||||
Array.from(e.clipboardData.files)
|
Array.from(e.clipboardData.files)
|
||||||
.filter(file => file.size > 0)
|
.filter(file => file.size > 0)
|
||||||
@@ -1216,6 +1232,7 @@ export default {
|
|||||||
(copilot.isActive.value && copilot.isButtonDisabled.value) ||
|
(copilot.isActive.value && copilot.isButtonDisabled.value) ||
|
||||||
showAudioRecorderEditor
|
showAudioRecorderEditor
|
||||||
"
|
"
|
||||||
|
:is-editor-disabled="isEditorDisabled"
|
||||||
:is-message-length-reaching-threshold="isMessageLengthReachingThreshold"
|
:is-message-length-reaching-threshold="isMessageLengthReachingThreshold"
|
||||||
:characters-remaining="charactersRemaining"
|
:characters-remaining="charactersRemaining"
|
||||||
:popout-reply-box="popOutReplyBox"
|
:popout-reply-box="popOutReplyBox"
|
||||||
@@ -1292,6 +1309,7 @@ export default {
|
|||||||
:placeholder="messagePlaceHolder"
|
:placeholder="messagePlaceHolder"
|
||||||
:update-selection-with="updateEditorSelectionWith"
|
:update-selection-with="updateEditorSelectionWith"
|
||||||
:min-height="4"
|
:min-height="4"
|
||||||
|
:disabled="isEditorDisabled"
|
||||||
enable-variables
|
enable-variables
|
||||||
:variables="messageVariables"
|
:variables="messageVariables"
|
||||||
:signature="messageSignature"
|
:signature="messageSignature"
|
||||||
@@ -1367,6 +1385,7 @@ export default {
|
|||||||
:is-recording-audio="isRecordingAudio"
|
:is-recording-audio="isRecordingAudio"
|
||||||
:is-send-disabled="isReplyButtonDisabled"
|
:is-send-disabled="isReplyButtonDisabled"
|
||||||
:is-note="isPrivate"
|
:is-note="isPrivate"
|
||||||
|
:is-editor-disabled="isEditorDisabled"
|
||||||
:on-file-upload="onFileUpload"
|
:on-file-upload="onFileUpload"
|
||||||
:on-send="onSendReply"
|
:on-send="onSendReply"
|
||||||
:conversation-type="conversationType"
|
:conversation-type="conversationType"
|
||||||
|
|||||||
@@ -190,6 +190,8 @@
|
|||||||
"DISABLE_SIGN_TOOLTIP": "Disable signature",
|
"DISABLE_SIGN_TOOLTIP": "Disable signature",
|
||||||
"MSG_INPUT": "Shift + enter for new line. Start with '/' to select a Canned Response.",
|
"MSG_INPUT": "Shift + enter for new line. Start with '/' to select a Canned Response.",
|
||||||
"PRIVATE_MSG_INPUT": "Shift + enter for new line. This will be visible only to Agents",
|
"PRIVATE_MSG_INPUT": "Shift + enter for new line. This will be visible only to Agents",
|
||||||
|
"MESSAGING_RESTRICTED": "You cannot reply to this conversation",
|
||||||
|
"MESSAGING_RESTRICTED_WHATSAPP": "You can only reply using a template message due to 24-hour message window restriction",
|
||||||
"MESSAGE_SIGNATURE_NOT_CONFIGURED": "Message signature is not configured, please configure it in profile settings.",
|
"MESSAGE_SIGNATURE_NOT_CONFIGURED": "Message signature is not configured, please configure it in profile settings.",
|
||||||
"COPILOT_MSG_INPUT": "Give copilot additional prompts, or ask anything else... Press enter to send follow-up",
|
"COPILOT_MSG_INPUT": "Give copilot additional prompts, or ask anything else... Press enter to send follow-up",
|
||||||
"CLICK_HERE": "Click here to update",
|
"CLICK_HERE": "Click here to update",
|
||||||
|
|||||||
Reference in New Issue
Block a user