mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-02 03:57:52 +00:00
# Pull Request Template ## Description ### Issue The Community Edition (CE) dashboard was making API requests to enterprise-only endpoints, causing 404 errors: * `/enterprise/api/v1/accounts/1/limits` * `/api/v1/accounts/1/captain/assistants?page=1` ### Solution 1. Added conditional checks to prevent these calls. 2. Remove unused component `app/javascript/dashboard/components/app/UpgradeBanner.vue` Fixes [CW-4695](https://linear.app/chatwoot/issue/CW-4695/440-ce-dashboard-calls-enterprise-urls), https://github.com/chatwoot/chatwoot/issues/12023 ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Pranav <pranavrajs@gmail.com>
152 lines
4.7 KiB
Vue
152 lines
4.7 KiB
Vue
<script setup>
|
|
import { ref, computed, onMounted } from 'vue';
|
|
import { useStore } from 'dashboard/composables/store';
|
|
import Copilot from 'dashboard/components-next/copilot/Copilot.vue';
|
|
import { useMapGetter } from 'dashboard/composables/store';
|
|
import { useUISettings } from 'dashboard/composables/useUISettings';
|
|
import { useConfig } from 'dashboard/composables/useConfig';
|
|
import { useWindowSize } from '@vueuse/core';
|
|
import { vOnClickOutside } from '@vueuse/components';
|
|
import { FEATURE_FLAGS } from 'dashboard/featureFlags';
|
|
import wootConstants from 'dashboard/constants/globals';
|
|
|
|
defineProps({
|
|
conversationInboxType: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
});
|
|
|
|
const store = useStore();
|
|
const { uiSettings, updateUISettings } = useUISettings();
|
|
const { isEnterprise } = useConfig();
|
|
const { width: windowWidth } = useWindowSize();
|
|
|
|
const currentUser = useMapGetter('getCurrentUser');
|
|
const assistants = useMapGetter('captainAssistants/getRecords');
|
|
const uiFlags = useMapGetter('captainAssistants/getUIFlags');
|
|
const inboxAssistant = useMapGetter('getCopilotAssistant');
|
|
const currentChat = useMapGetter('getSelectedChat');
|
|
|
|
const isSmallScreen = computed(
|
|
() => windowWidth.value < wootConstants.SMALL_SCREEN_BREAKPOINT
|
|
);
|
|
|
|
const selectedCopilotThreadId = ref(null);
|
|
const messages = computed(() =>
|
|
store.getters['copilotMessages/getMessagesByThreadId'](
|
|
selectedCopilotThreadId.value
|
|
)
|
|
);
|
|
|
|
const currentAccountId = useMapGetter('getCurrentAccountId');
|
|
const isFeatureEnabledonAccount = useMapGetter(
|
|
'accounts/isFeatureEnabledonAccount'
|
|
);
|
|
|
|
const selectedAssistantId = ref(null);
|
|
|
|
const activeAssistant = computed(() => {
|
|
const preferredId = uiSettings.value.preferred_captain_assistant_id;
|
|
|
|
// If the user has selected a specific assistant, it takes first preference for Copilot.
|
|
if (preferredId) {
|
|
const preferredAssistant = assistants.value.find(a => a.id === preferredId);
|
|
// Return the preferred assistant if found, otherwise continue to next cases
|
|
if (preferredAssistant) return preferredAssistant;
|
|
}
|
|
|
|
// If the above is not available, the assistant connected to the inbox takes preference.
|
|
if (inboxAssistant.value) {
|
|
const inboxMatchedAssistant = assistants.value.find(
|
|
a => a.id === inboxAssistant.value.id
|
|
);
|
|
if (inboxMatchedAssistant) return inboxMatchedAssistant;
|
|
}
|
|
// If neither of the above is available, the first assistant in the account takes preference.
|
|
return assistants.value[0];
|
|
});
|
|
|
|
const closeCopilotPanel = () => {
|
|
if (isSmallScreen.value && uiSettings.value?.is_copilot_panel_open) {
|
|
updateUISettings({
|
|
is_contact_sidebar_open: false,
|
|
is_copilot_panel_open: false,
|
|
});
|
|
}
|
|
};
|
|
|
|
const setAssistant = async assistant => {
|
|
selectedAssistantId.value = assistant.id;
|
|
await updateUISettings({
|
|
preferred_captain_assistant_id: assistant.id,
|
|
});
|
|
};
|
|
|
|
const shouldShowCopilotPanel = computed(() => {
|
|
if (!isEnterprise) {
|
|
return false;
|
|
}
|
|
const isCaptainEnabled = isFeatureEnabledonAccount.value(
|
|
currentAccountId.value,
|
|
FEATURE_FLAGS.CAPTAIN
|
|
);
|
|
const { is_copilot_panel_open: isCopilotPanelOpen } = uiSettings.value;
|
|
return isCaptainEnabled && isCopilotPanelOpen && !uiFlags.value.fetchingList;
|
|
});
|
|
|
|
const handleReset = () => {
|
|
selectedCopilotThreadId.value = null;
|
|
};
|
|
|
|
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;
|
|
}
|
|
};
|
|
|
|
onMounted(() => {
|
|
if (isEnterprise) {
|
|
store.dispatch('captainAssistants/get');
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
v-if="shouldShowCopilotPanel"
|
|
v-on-click-outside="() => closeCopilotPanel()"
|
|
class="bg-n-background h-full overflow-hidden flex-col fixed top-0 ltr:right-0 rtl:left-0 z-40 w-full max-w-sm transition-transform duration-300 ease-in-out md:static md:w-[320px] md:min-w-[320px] ltr:border-l rtl:border-r border-n-weak 2xl:min-w-[360px] 2xl:w-[360px] shadow-lg md:shadow-none"
|
|
:class="[
|
|
{
|
|
'md:flex': shouldShowCopilotPanel,
|
|
'md:hidden': !shouldShowCopilotPanel,
|
|
},
|
|
]"
|
|
>
|
|
<Copilot
|
|
:messages="messages"
|
|
:support-agent="currentUser"
|
|
:conversation-inbox-type="conversationInboxType"
|
|
:assistants="assistants"
|
|
:active-assistant="activeAssistant"
|
|
@set-assistant="setAssistant"
|
|
@send-message="sendMessage"
|
|
@reset="handleReset"
|
|
/>
|
|
</div>
|
|
<template v-else />
|
|
</template>
|