feat: Insert captain response to reply editor (#10581)

This commit is contained in:
Sivin Varghese
2024-12-13 15:13:16 +05:30
committed by GitHub
parent 19ff5bdd5e
commit 9220afce6e
7 changed files with 57 additions and 7 deletions

View File

@@ -18,6 +18,10 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: false, default: false,
}, },
conversationInboxType: {
type: String,
required: true,
},
}); });
const emit = defineEmits(['sendMessage']); const emit = defineEmits(['sendMessage']);
@@ -47,7 +51,7 @@ watch(
<template> <template>
<div class="flex flex-col ]mx-auto h-full text-sm leading-6 tracking-tight"> <div class="flex flex-col ]mx-auto h-full text-sm leading-6 tracking-tight">
<div ref="chatContainer" class="flex-1 overflow-y-auto py-4 space-y-6 px-4"> <div ref="chatContainer" class="flex-1 px-4 py-4 space-y-6 overflow-y-auto">
<template v-for="message in messages" :key="message.id"> <template v-for="message in messages" :key="message.id">
<CopilotAgentMessage <CopilotAgentMessage
v-if="message.role === 'user'" v-if="message.role === 'user'"
@@ -57,12 +61,13 @@ watch(
<CopilotAssistantMessage <CopilotAssistantMessage
v-else-if="COPILOT_USER_ROLES.includes(message.role)" v-else-if="COPILOT_USER_ROLES.includes(message.role)"
:message="message" :message="message"
:conversation-inbox-type="conversationInboxType"
/> />
</template> </template>
<CopilotLoader v-if="isCaptainTyping" /> <CopilotLoader v-if="isCaptainTyping" />
</div> </div>
<CopilotInput class="mx-3 mb-4 mt-px" @send="sendMessage" /> <CopilotInput class="mx-3 mt-px mb-4" @send="sendMessage" />
</div> </div>
</template> </template>

View File

@@ -1,12 +1,36 @@
<script setup> <script setup>
import { computed } from 'vue';
import { emitter } from 'shared/helpers/mitt';
import { BUS_EVENTS } from 'shared/constants/busEvents';
import { INBOX_TYPES } from 'dashboard/helper/inbox';
import Button from 'dashboard/components-next/button/Button.vue';
import Avatar from '../avatar/Avatar.vue'; import Avatar from '../avatar/Avatar.vue';
defineProps({ const props = defineProps({
message: { message: {
type: Object, type: Object,
required: true, required: true,
}, },
conversationInboxType: {
type: String,
required: true,
},
}); });
const insertIntoRichEditor = computed(() => {
return [INBOX_TYPES.WEB, INBOX_TYPES.EMAIL].includes(
props.conversationInboxType
);
});
const useCopilotResponse = () => {
if (insertIntoRichEditor.value) {
emitter.emit(BUS_EVENTS.INSERT_INTO_RICH_EDITOR, props.message?.content);
} else {
emitter.emit(BUS_EVENTS.INSERT_INTO_NORMAL_EDITOR, props.message?.content);
}
};
</script> </script>
<template> <template>
@@ -22,6 +46,15 @@ defineProps({
<div class="break-words"> <div class="break-words">
{{ message.content }} {{ message.content }}
</div> </div>
<div class="flex flex-row mt-1">
<Button
:label="$t('CAPTAIN.COPILOT.USE')"
faded
sm
slate
@click="useCopilotResponse"
/>
</div>
</div> </div>
</div> </div>
</template> </template>

View File

@@ -8,6 +8,10 @@ const props = defineProps({
type: [Number, String], type: [Number, String],
required: true, required: true,
}, },
conversationInboxType: {
type: String,
required: true,
},
}); });
const currentUser = useMapGetter('getCurrentUser'); const currentUser = useMapGetter('getCurrentUser');
const messages = ref([]); const messages = ref([]);
@@ -53,6 +57,7 @@ const sendMessage = async message => {
:messages="messages" :messages="messages"
:support-agent="currentUser" :support-agent="currentUser"
:is-captain-typing="isCaptainTyping" :is-captain-typing="isCaptainTyping"
:conversation-inbox-type="conversationInboxType"
@send-message="sendMessage" @send-message="sendMessage"
/> />
</template> </template>

View File

@@ -6,7 +6,7 @@ import ContactPanel from 'dashboard/routes/dashboard/conversation/ContactPanel.v
import TabBar from 'dashboard/components-next/tabbar/TabBar.vue'; import TabBar from 'dashboard/components-next/tabbar/TabBar.vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
defineProps({ const props = defineProps({
currentChat: { currentChat: {
required: true, required: true,
type: Object, type: Object,
@@ -16,11 +16,13 @@ defineProps({
const emit = defineEmits(['toggleContactPanel']); const emit = defineEmits(['toggleContactPanel']);
const getters = useStoreGetters(); const getters = useStoreGetters();
const { t } = useI18n();
const captainIntegration = computed(() => const captainIntegration = computed(() =>
getters['integrations/getIntegration'].value('captain', null) getters['integrations/getIntegration'].value('captain', null)
); );
const { t } = useI18n();
const channelType = computed(() => props.currentChat?.meta?.channel || '');
const CONTACT_TABS_OPTIONS = [ const CONTACT_TABS_OPTIONS = [
{ key: 'CONTACT', value: 'contact' }, { key: 'CONTACT', value: 'contact' },
@@ -61,7 +63,7 @@ const showCopilotTab = computed(() => {
@tab-changed="handleTabChange" @tab-changed="handleTabChange"
/> />
</div> </div>
<div class="overflow-auto flex flex-1"> <div class="flex flex-1 overflow-auto">
<ContactPanel <ContactPanel
v-if="!activeTab" v-if="!activeTab"
:conversation-id="currentChat.id" :conversation-id="currentChat.id"
@@ -71,6 +73,7 @@ const showCopilotTab = computed(() => {
<CopilotContainer <CopilotContainer
v-else-if="activeTab === 1 && showCopilotTab" v-else-if="activeTab === 1 && showCopilotTab"
:key="currentChat.id" :key="currentChat.id"
:conversation-inbox-type="channelType"
:conversation-id="currentChat.id" :conversation-id="currentChat.id"
class="flex-1" class="flex-1"
/> />

View File

@@ -459,11 +459,13 @@ export default {
BUS_EVENTS.NEW_CONVERSATION_MODAL, BUS_EVENTS.NEW_CONVERSATION_MODAL,
this.onNewConversationModalActive this.onNewConversationModalActive
); );
emitter.on(BUS_EVENTS.INSERT_INTO_NORMAL_EDITOR, this.addIntoEditor);
}, },
unmounted() { unmounted() {
document.removeEventListener('paste', this.onPaste); document.removeEventListener('paste', this.onPaste);
document.removeEventListener('keydown', this.handleKeyEvents); document.removeEventListener('keydown', this.handleKeyEvents);
emitter.off(BUS_EVENTS.TOGGLE_REPLY_TO_MESSAGE, this.fetchAndSetReplyTo); emitter.off(BUS_EVENTS.TOGGLE_REPLY_TO_MESSAGE, this.fetchAndSetReplyTo);
emitter.off(BUS_EVENTS.INSERT_INTO_NORMAL_EDITOR, this.addIntoEditor);
emitter.off( emitter.off(
BUS_EVENTS.NEW_CONVERSATION_MODAL, BUS_EVENTS.NEW_CONVERSATION_MODAL,
this.onNewConversationModalActive this.onNewConversationModalActive

View File

@@ -305,7 +305,8 @@
"COPILOT": { "COPILOT": {
"SEND_MESSAGE": "Send message...", "SEND_MESSAGE": "Send message...",
"LOADER": "Captain is thinking", "LOADER": "Captain is thinking",
"YOU": "You" "YOU": "You",
"USE": "Use this"
} }
} }
} }

View File

@@ -14,4 +14,5 @@ export const BUS_EVENTS = {
SHOW_TOAST: 'newToastMessage', SHOW_TOAST: 'newToastMessage',
NEW_CONVERSATION_MODAL: 'newConversationModal', NEW_CONVERSATION_MODAL: 'newConversationModal',
INSERT_INTO_RICH_EDITOR: 'insertIntoRichEditor', INSERT_INTO_RICH_EDITOR: 'insertIntoRichEditor',
INSERT_INTO_NORMAL_EDITOR: 'insertIntoNormalEditor',
}; };