diff --git a/frontend/apps/main/src/features/conversation/ReplyBox.vue b/frontend/apps/main/src/features/conversation/ReplyBox.vue
index d1cabbaa..a2cf4218 100644
--- a/frontend/apps/main/src/features/conversation/ReplyBox.vue
+++ b/frontend/apps/main/src/features/conversation/ReplyBox.vue
@@ -13,7 +13,7 @@
{{ $t('globals.messages.cancel') }}
- {{
+ {{
$t('replyBox.sendAnyway')
}}
@@ -30,7 +30,7 @@
{{ $t('globals.messages.cancel') }}
- {{
+ {{
$t('replyBox.sendAnyway')
}}
@@ -103,6 +103,7 @@
v-model:mentions="mentions"
@toggleFullscreen="isEditorFullscreen = !isEditorFullscreen"
@send="processSend"
+ @sendAndSetStatus="processSendAndSetStatus"
@fileUpload="handleFileUpload"
@fileDelete="handleFileDelete"
@filesDropped="uploadFiles"
@@ -137,6 +138,7 @@
v-model:mentions="mentions"
@toggleFullscreen="isEditorFullscreen = !isEditorFullscreen"
@send="processSend"
+ @sendAndSetStatus="processSendAndSetStatus"
@fileUpload="handleFileUpload"
@fileDelete="handleFileDelete"
@filesDropped="uploadFiles"
@@ -247,6 +249,7 @@ const aiPrompts = computed(() => aiPromptStore.prompts)
const replyBoxContentRef = ref(null)
const showContactEmailWarning = ref(false)
const showMissingTagsWarning = ref(false)
+const deferredStatus = ref(null)
const mentions = ref([])
aiPromptStore.fetchPrompts()
@@ -305,10 +308,7 @@ const hasTextContent = computed(() => {
return textContent.value.trim().length > 0
})
-/**
- * Processes the send action.
- */
-const processSend = async (skipContactEmailCheck = false, skipMissingTagsCheck = false) => {
+const processSend = async (skipContactEmailCheck = false, skipMissingTagsCheck = false, statusToSet = null) => {
let hasMessageSendingErrored = false
isEditorFullscreen.value = false
@@ -327,6 +327,7 @@ const processSend = async (skipContactEmailCheck = false, skipMissingTagsCheck =
currentInbox?.prompt_tags_on_reply &&
!(conversationStore.current.tags?.length > 0)
) {
+ deferredStatus.value = statusToSet
showMissingTagsWarning.value = true
return
}
@@ -352,6 +353,7 @@ const processSend = async (skipContactEmailCheck = false, skipMissingTagsCheck =
.map((e) => e.trim())
.includes(contactEmail)
) {
+ deferredStatus.value = statusToSet
showContactEmailWarning.value = true
return
}
@@ -462,10 +464,13 @@ const processSend = async (skipContactEmailCheck = false, skipMissingTagsCheck =
clearMediaFiles()
emailErrors.value = []
mentions.value = []
+ if (statusToSet) conversationStore.updateStatus(statusToSet)
}
isSending.value = false
}
+const processSendAndSetStatus = (status) => processSend(false, false, status)
+
/**
* Watches for changes in the conversation's macro id and update message content.
*/
diff --git a/frontend/apps/main/src/features/conversation/ReplyBoxContent.vue b/frontend/apps/main/src/features/conversation/ReplyBoxContent.vue
index 24b9b6fc..be911978 100644
--- a/frontend/apps/main/src/features/conversation/ReplyBoxContent.vue
+++ b/frontend/apps/main/src/features/conversation/ReplyBoxContent.vue
@@ -130,6 +130,7 @@
:isSending="isSending"
:enableSend="enableSend"
:handleSend="handleSend"
+ :handleSendAndSetStatus="handleSendAndSetStatus"
@emojiSelect="handleEmojiSelect"
/>
@@ -239,6 +240,7 @@ const props = defineProps({
const emit = defineEmits([
'toggleFullscreen',
'send',
+ 'sendAndSetStatus',
'fileUpload',
'inlineImageUpload',
'fileDelete',
@@ -302,21 +304,34 @@ const validateEmails = async () => {
})
}
-/**
- * Send the reply or private note
- */
-const handleSend = async () => {
+const validateBeforeSend = async () => {
await validateEmails()
if (emailErrors.value.length > 0) {
emitter.emit(EMITTER_EVENTS.SHOW_TOAST, {
variant: 'destructive',
description: t('globals.messages.correctEmailErrors')
})
- return
+ return false
}
+ return true
+}
+
+/**
+ * Send the reply or private note
+ */
+const handleSend = async () => {
+ if (!(await validateBeforeSend())) return
emit('send')
}
+/**
+ * Send the reply or private note and set conversation status
+ */
+const handleSendAndSetStatus = async (status) => {
+ if (!(await validateBeforeSend())) return
+ emit('sendAndSetStatus', status)
+}
+
const handleFileUpload = (event) => {
emit('fileUpload', event)
}
diff --git a/frontend/apps/main/src/features/conversation/ReplyBoxMenuBar.vue b/frontend/apps/main/src/features/conversation/ReplyBoxMenuBar.vue
index 593c42d5..53272829 100644
--- a/frontend/apps/main/src/features/conversation/ReplyBoxMenuBar.vue
+++ b/frontend/apps/main/src/features/conversation/ReplyBoxMenuBar.vue
@@ -38,9 +38,37 @@
-
+
+
+
+
+
+
+
+ {{ $t('replyBox.sendAndSetAs') }}
+
+ {{ status.label }}
+
+
+
+
@@ -49,7 +77,16 @@ import { ref, defineAsyncComponent } from 'vue'
import { onClickOutside } from '@vueuse/core'
import { Button } from '@shared-ui/components/ui/button'
import { Toggle } from '@shared-ui/components/ui/toggle'
-import { Paperclip, Smile } from 'lucide-vue-next'
+import { Paperclip, Smile, ChevronDownIcon } from 'lucide-vue-next'
+import {
+ DropdownMenu,
+ DropdownMenuTrigger,
+ DropdownMenuItem,
+ DropdownMenuContent,
+ DropdownMenuLabel
+} from '@shared-ui/components/ui/dropdown-menu'
+import { useConversationStore } from '@main/stores/conversation'
+const conversationStore = useConversationStore()
const EmojiPicker = defineAsyncComponent(async () => {
const [mod] = await Promise.all([
@@ -71,6 +108,7 @@ defineProps({
isSending: Boolean,
enableSend: Boolean,
handleSend: Function,
+ handleSendAndSetStatus: Function,
showSendButton: {
type: Boolean,
default: true
diff --git a/frontend/apps/main/src/stores/conversation.js b/frontend/apps/main/src/stores/conversation.js
index 1dd3727a..ba789803 100644
--- a/frontend/apps/main/src/stores/conversation.js
+++ b/frontend/apps/main/src/stores/conversation.js
@@ -40,7 +40,7 @@ export const useConversationStore = defineStore('conversation', () => {
return statuses.value.map(s => ({ label: s.name, value: s.id }))
})
const statusOptionsNoSnooze = computed(() =>
- statuses.value.filter(s => s.name !== 'Snoozed').map(s => ({
+ statuses.value.filter(s => s.name !== CONVERSATION_DEFAULT_STATUSES.SNOOZED).map(s => ({
label: s.name,
value: s.id
}))
diff --git a/i18n/en-US.json b/i18n/en-US.json
index 92b5a14a..9cca9a20 100644
--- a/i18n/en-US.json
+++ b/i18n/en-US.json
@@ -940,6 +940,7 @@
"replyBox.missingTagsTitle": "No tags on this conversation",
"replyBox.removeBCC": "Remove BCC",
"replyBox.sendAnyway": "Send anyway",
+ "replyBox.sendAndSetAs": "Send and set as",
"replyBox.toRequired": "At least one recipient is required in the To field.",
"report.agentStatus": "Agent Status",
"report.chart.newConversations": "New conversations",