Merge branch 'develop' into feat/add_last_snoozed_option
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue';
|
||||
import { useAlert } from 'dashboard/composables';
|
||||
import { useStore } from 'dashboard/composables/store';
|
||||
import Copilot from 'dashboard/components-next/copilot/Copilot.vue';
|
||||
import { useMapGetter } from 'dashboard/composables/store';
|
||||
@@ -100,20 +101,24 @@ const handleReset = () => {
|
||||
};
|
||||
|
||||
const sendMessage = async message => {
|
||||
if (selectedCopilotThreadId.value) {
|
||||
await store.dispatch('copilotMessages/create', {
|
||||
assistant_id: activeAssistant.value.id,
|
||||
conversation_id: currentChat.value?.id,
|
||||
threadId: selectedCopilotThreadId.value,
|
||||
message,
|
||||
});
|
||||
} else {
|
||||
const response = await store.dispatch('copilotThreads/create', {
|
||||
assistant_id: activeAssistant.value.id,
|
||||
conversation_id: currentChat.value?.id,
|
||||
message,
|
||||
});
|
||||
selectedCopilotThreadId.value = response.id;
|
||||
try {
|
||||
if (selectedCopilotThreadId.value) {
|
||||
await store.dispatch('copilotMessages/create', {
|
||||
assistant_id: activeAssistant.value.id,
|
||||
conversation_id: currentChat.value?.id,
|
||||
threadId: selectedCopilotThreadId.value,
|
||||
message,
|
||||
});
|
||||
} else {
|
||||
const response = await store.dispatch('copilotThreads/create', {
|
||||
assistant_id: activeAssistant.value.id,
|
||||
conversation_id: currentChat.value?.id,
|
||||
message,
|
||||
});
|
||||
selectedCopilotThreadId.value = response.id;
|
||||
}
|
||||
} catch (error) {
|
||||
useAlert(error.message);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -6,15 +6,12 @@ import FileUpload from 'vue-upload-component';
|
||||
import * as ActiveStorage from 'activestorage';
|
||||
import inboxMixin from 'shared/mixins/inboxMixin';
|
||||
import { FEATURE_FLAGS } from 'dashboard/featureFlags';
|
||||
import {
|
||||
ALLOWED_FILE_TYPES,
|
||||
ALLOWED_FILE_TYPES_FOR_TWILIO_WHATSAPP,
|
||||
ALLOWED_FILE_TYPES_FOR_LINE,
|
||||
ALLOWED_FILE_TYPES_FOR_INSTAGRAM,
|
||||
} from 'shared/constants/messages';
|
||||
import { getAllowedFileTypesByChannel } from '@chatwoot/utils';
|
||||
import { ALLOWED_FILE_TYPES } from 'shared/constants/messages';
|
||||
import VideoCallButton from '../VideoCallButton.vue';
|
||||
import AIAssistanceButton from '../AIAssistanceButton.vue';
|
||||
import { REPLY_EDITOR_MODES } from './constants';
|
||||
import { INBOX_TYPES } from 'dashboard/helper/inbox';
|
||||
import { mapGetters } from 'vuex';
|
||||
import NextButton from 'dashboard/components-next/button/Button.vue';
|
||||
|
||||
@@ -155,6 +152,11 @@ export default {
|
||||
uploadRef,
|
||||
};
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ALLOWED_FILE_TYPES,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
accountId: 'getCurrentAccountId',
|
||||
@@ -196,17 +198,21 @@ export default {
|
||||
return this.conversationType === 'instagram_direct_message';
|
||||
},
|
||||
allowedFileTypes() {
|
||||
if (this.isATwilioWhatsAppChannel) {
|
||||
return ALLOWED_FILE_TYPES_FOR_TWILIO_WHATSAPP;
|
||||
}
|
||||
if (this.isALineChannel) {
|
||||
return ALLOWED_FILE_TYPES_FOR_LINE;
|
||||
}
|
||||
if (this.isAnInstagramChannel || this.isInstagramDM) {
|
||||
return ALLOWED_FILE_TYPES_FOR_INSTAGRAM;
|
||||
// Use default file types for private notes
|
||||
if (this.isOnPrivateNote) {
|
||||
return this.ALLOWED_FILE_TYPES;
|
||||
}
|
||||
|
||||
return ALLOWED_FILE_TYPES;
|
||||
let channelType = this.channelType || this.inbox?.channel_type;
|
||||
|
||||
if (this.isAnInstagramChannel || this.isInstagramDM) {
|
||||
channelType = INBOX_TYPES.INSTAGRAM;
|
||||
}
|
||||
|
||||
return getAllowedFileTypesByChannel({
|
||||
channelType,
|
||||
medium: this.inbox?.medium,
|
||||
});
|
||||
},
|
||||
enableDragAndDrop() {
|
||||
return !this.newConversationModalActive;
|
||||
|
||||
@@ -793,6 +793,10 @@ export default {
|
||||
}, 100);
|
||||
},
|
||||
setReplyMode(mode = REPLY_EDITOR_MODES.REPLY) {
|
||||
// Clear attachments when switching between private note and reply modes
|
||||
// This is to prevent from breaking the upload rules
|
||||
if (this.attachedFiles.length > 0) this.attachedFiles = [];
|
||||
|
||||
const { can_reply: canReply } = this.currentChat;
|
||||
this.$store.dispatch('draftMessages/setReplyEditorMode', {
|
||||
mode,
|
||||
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
<script>
|
||||
import TemplatesPicker from './TemplatesPicker.vue';
|
||||
import TemplateParser from './TemplateParser.vue';
|
||||
import WhatsAppTemplateReply from './WhatsAppTemplateReply.vue';
|
||||
export default {
|
||||
components: {
|
||||
TemplatesPicker,
|
||||
TemplateParser,
|
||||
WhatsAppTemplateReply,
|
||||
},
|
||||
props: {
|
||||
show: {
|
||||
@@ -68,7 +68,7 @@ export default {
|
||||
:inbox-id="inboxId"
|
||||
@on-select="pickTemplate"
|
||||
/>
|
||||
<TemplateParser
|
||||
<WhatsAppTemplateReply
|
||||
v-else
|
||||
:template="selectedWaTemplate"
|
||||
@reset-template="onResetTemplate"
|
||||
|
||||
-9
@@ -1,13 +1,4 @@
|
||||
<script setup>
|
||||
/**
|
||||
* This component handles parsing and sending WhatsApp message templates.
|
||||
* It works as follows:
|
||||
* 1. Displays the template text with variable placeholders.
|
||||
* 2. Generates input fields for each variable in the template.
|
||||
* 3. Validates that all variables are filled before sending.
|
||||
* 4. Replaces placeholders with user-provided values.
|
||||
* 5. Emits events to send the processed message or reset the template.
|
||||
*/
|
||||
import WhatsAppTemplateParser from 'dashboard/components-next/whatsapp/WhatsAppTemplateParser.vue';
|
||||
import NextButton from 'dashboard/components-next/button/Button.vue';
|
||||
|
||||
Reference in New Issue
Block a user