Rethink Copilot from scratch

This commit is contained in:
Pranav
2025-05-09 00:42:58 -07:00
parent 6766b706c1
commit d1ed7419ac
7 changed files with 41 additions and 90 deletions
@@ -10,6 +10,7 @@ import CopilotAgentMessage from './CopilotAgentMessage.vue';
import CopilotAssistantMessage from './CopilotAssistantMessage.vue';
import ToggleCopilotAssistant from './ToggleCopilotAssistant.vue';
import Icon from '../icon/Icon.vue';
import Button from '../button/Button.vue';
const props = defineProps({
supportAgent: {
@@ -38,7 +39,7 @@ const props = defineProps({
},
});
const emit = defineEmits(['sendMessage', 'reset', 'setAssistant']);
const emit = defineEmits(['sendMessage', 'reset', 'setAssistant', 'close']);
const { t } = useI18n();
@@ -93,6 +94,23 @@ watch(
<template>
<div class="flex flex-col h-full text-sm leading-6 tracking-tight w-full">
<div
class="flex items-center justify-between px-4 py-2 border-b border-n-weak"
>
<div class="flex items-center justify-between gap-2 flex-1">
<span class="font-medium">{{ $t('CAPTAIN.COPILOT.TITLE') }}</span>
<div class="flex items-center">
<Button
v-if="messages.length"
icon="i-lucide-refresh-ccw"
ghost
sm
@click="handleReset"
/>
<Button icon="i-lucide-x" ghost sm @click="$emit('close')" />
</div>
</div>
</div>
<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">
<CopilotAgentMessage
@@ -133,20 +151,12 @@ watch(
<div class="mx-3 mt-px mb-2">
<div class="flex items-center gap-2 justify-between w-full mb-1">
<ToggleCopilotAssistant
v-if="assistants.length"
v-if="assistants.length > 1"
:assistants="assistants"
:active-assistant="activeAssistant"
@set-assistant="$event => emit('setAssistant', $event)"
/>
<div v-else />
<button
v-if="messages.length"
class="text-xs flex items-center gap-1 hover:underline"
@click="handleReset"
>
<i class="i-lucide-refresh-ccw" />
<span>{{ $t('CAPTAIN.COPILOT.RESET') }}</span>
</button>
</div>
<CopilotInput class="mb-1 w-full" @send="sendMessage" />
</div>
@@ -476,9 +476,7 @@ const menuItems = computed(() => {
</script>
<template>
<aside
class="w-[12.5rem] bg-n-solid-2 rtl:border-l ltr:border-r border-n-weak h-screen flex flex-col text-sm pb-1"
>
<aside class="w-[12.5rem] h-screen flex flex-col text-sm pb-1">
<section class="grid gap-2 mt-2 mb-4">
<div class="flex items-center min-w-0 gap-2 px-2">
<div class="grid flex-shrink-0 size-6 place-content-center">
@@ -108,15 +108,17 @@ watchEffect(() => {
</script>
<template>
<Copilot
:messages="messages"
:support-agent="currentUser"
:is-captain-typing="isCaptainTyping"
:conversation-inbox-type="conversationInboxType"
:assistants="assistants"
:active-assistant="activeAssistant"
@set-assistant="setAssistant"
@send-message="sendMessage"
@reset="handleReset"
/>
<div class="border m-1 rounded-lg border-n-weak min-w-[280px]">
<Copilot
:messages="messages"
:support-agent="currentUser"
:is-captain-typing="isCaptainTyping"
:conversation-inbox-type="conversationInboxType"
:assistants="assistants"
:active-assistant="activeAssistant"
@set-assistant="setAssistant"
@send-message="sendMessage"
@reset="handleReset"
/>
</div>
</template>
@@ -97,12 +97,7 @@ export default {
</script>
<template>
<div
class="conversation-details-wrap bg-n-background"
:class="{
'border-l rtl:border-l-0 rtl:border-r border-n-weak': !isOnExpandedLayout,
}"
>
<div class="conversation-details-wrap bg-n-background">
<ConversationHeader
v-if="currentChat.id"
:chat="currentChat"
@@ -1,82 +1,23 @@
<script setup>
import { computed, ref } from 'vue';
import CopilotContainer from '../../copilot/CopilotContainer.vue';
import ContactPanel from 'dashboard/routes/dashboard/conversation/ContactPanel.vue';
import TabBar from 'dashboard/components-next/tabbar/TabBar.vue';
import { useI18n } from 'vue-i18n';
import { useMapGetter } from 'dashboard/composables/store';
import { FEATURE_FLAGS } from '../../../featureFlags';
const props = defineProps({
currentChat: {
required: true,
type: Object,
},
});
const emit = defineEmits(['toggleContactPanel']);
const { t } = useI18n();
const channelType = computed(() => props.currentChat?.meta?.channel || '');
const CONTACT_TABS_OPTIONS = [
{ key: 'CONTACT', value: 'contact' },
{ key: 'COPILOT', value: 'copilot' },
];
const tabs = computed(() => {
return CONTACT_TABS_OPTIONS.map(tab => ({
label: t(`CONVERSATION.SIDEBAR.${tab.key}`),
value: tab.value,
}));
});
const activeTab = ref(0);
const toggleContactPanel = () => {
emit('toggleContactPanel');
};
const handleTabChange = selectedTab => {
activeTab.value = tabs.value.findIndex(
tabItem => tabItem.value === selectedTab.value
);
};
const currentAccountId = useMapGetter('getCurrentAccountId');
const isFeatureEnabledonAccount = useMapGetter(
'accounts/isFeatureEnabledonAccount'
);
const showCopilotTab = computed(() =>
isFeatureEnabledonAccount.value(currentAccountId.value, FEATURE_FLAGS.CAPTAIN)
);
</script>
<template>
<div
class="ltr:border-l rtl:border-r border-n-weak h-full overflow-hidden z-10 w-80 min-w-80 2xl:min-w-96 2xl:w-96 flex flex-col bg-n-background"
>
<div v-if="showCopilotTab" class="p-2">
<TabBar
:tabs="tabs"
:initial-active-tab="activeTab"
class="w-full [&>button]:w-full"
@tab-changed="handleTabChange"
/>
</div>
<div class="flex flex-1 overflow-auto">
<ContactPanel
v-if="!activeTab"
:conversation-id="currentChat.id"
:inbox-id="currentChat.inbox_id"
:on-toggle="toggleContactPanel"
/>
<CopilotContainer
v-else-if="activeTab === 1 && showCopilotTab"
:key="currentChat.id"
:conversation-inbox-type="channelType"
:conversation-id="currentChat.id"
class="flex-1"
/>
</div>
</div>
</template>
@@ -327,6 +327,7 @@
"NAME": "Captain",
"HEADER_KNOW_MORE": "Know more",
"COPILOT": {
"TITLE": "Copilot",
"SEND_MESSAGE": "Send message...",
"EMPTY_MESSAGE": "There was an error generating the response. Please try again.",
"LOADER": "Captain is thinking",
@@ -10,6 +10,7 @@ import { BUS_EVENTS } from 'shared/constants/busEvents';
import CmdBarConversationSnooze from 'dashboard/routes/dashboard/commands/CmdBarConversationSnooze.vue';
import { emitter } from 'shared/helpers/mitt';
import { FEATURE_FLAGS } from 'dashboard/featureFlags';
import CopilotContainer from 'dashboard/components/copilot/CopilotContainer.vue';
export default {
components: {
@@ -17,6 +18,7 @@ export default {
ConversationBox,
PopOverSearch,
CmdBarConversationSnooze,
CopilotContainer,
},
beforeRouteLeave(to, from, next) {
// Clear selected state if navigating away from a conversation to a route without a conversationId to prevent stale data issues
@@ -140,7 +142,7 @@ export default {
const { LAYOUT_TYPES } = wootConstants;
const {
conversation_display_type:
conversationDisplayType = LAYOUT_TYPES.CONDENSED,
conversationDisplayType = LAYOUT_TYPES.CONDENSED,
} = this.uiSettings;
const newViewType =
conversationDisplayType === LAYOUT_TYPES.CONDENSED
@@ -207,6 +209,7 @@ export default {
<template>
<section class="flex w-full h-full">
<ChatList
class="m-1 border border-n-weak rounded-lg"
:show-conversation-list="showConversationList"
:conversation-inbox="inboxId"
:label="label"
@@ -229,6 +232,7 @@ export default {
:is-on-expanded-layout="isOnExpandedLayout"
@contact-panel-toggle="onToggleContactPanel"
/>
<CopilotContainer />
<CmdBarConversationSnooze />
</section>
</template>