From 9b86a220b182e5f92b7fc231fe6f787a7ad26070 Mon Sep 17 00:00:00 2001 From: Josako Date: Mon, 1 Dec 2025 14:07:16 +0100 Subject: [PATCH] - Introduction of Shells for Mobile client and Desktop client. Extensible with additional shells in the future --- config/static-manifest/manifest.json | 4 +- .../assets/vue-components/ChatInput.vue | 25 +- .../static/assets/vue-components/ChatRoot.vue | 47 +- .../assets/vue-components/CoreChatApp.vue | 501 ++++++++++++++++++ .../vue-components/DesktopChatShell.vue | 172 ++++++ .../assets/vue-components/MessageHistory.vue | 13 +- .../assets/vue-components/MobileChatShell.vue | 278 ++++++++++ nginx/frontend_src/js/chat-client.js | 34 +- 8 files changed, 1049 insertions(+), 25 deletions(-) create mode 100644 eveai_chat_client/static/assets/vue-components/CoreChatApp.vue create mode 100644 eveai_chat_client/static/assets/vue-components/DesktopChatShell.vue create mode 100644 eveai_chat_client/static/assets/vue-components/MobileChatShell.vue diff --git a/config/static-manifest/manifest.json b/config/static-manifest/manifest.json index ba22821..3145502 100644 --- a/config/static-manifest/manifest.json +++ b/config/static-manifest/manifest.json @@ -1,6 +1,6 @@ { - "dist/chat-client.js": "dist/chat-client.5b709f8c.js", - "dist/chat-client.css": "dist/chat-client.cb306abb.css", + "dist/chat-client.js": "dist/chat-client.be407684.js", + "dist/chat-client.css": "dist/chat-client.00145e73.css", "dist/main.js": "dist/main.6a617099.js", "dist/main.css": "dist/main.7182aac3.css" } \ No newline at end of file diff --git a/eveai_chat_client/static/assets/vue-components/ChatInput.vue b/eveai_chat_client/static/assets/vue-components/ChatInput.vue index f22d08f..7919e32 100644 --- a/eveai_chat_client/static/assets/vue-components/ChatInput.vue +++ b/eveai_chat_client/static/assets/vue-components/ChatInput.vue @@ -11,8 +11,8 @@ :is-latest-ai-message="true" :is-in-input-area="true" @image-loaded="handleImageLoaded" - @specialist-complete="$emit('specialist-complete', $event)" - @specialist-error="$emit('specialist-error', $event)" + @specialist-complete="handleSpecialistCompleteFromActiveMessage" + @specialist-error="handleSpecialistErrorFromActiveMessage" > @@ -183,22 +183,22 @@ export default { watch: { formData: { handler(newFormData, oldFormData) { - console.log('ChatInput formData changed:', newFormData); + console.log('🧐 [ChatInput] formData changed:', newFormData); if (!newFormData) { - console.log('FormData is null of undefined'); + console.log('🧐 [ChatInput] formData is null of undefined'); this.formValues = {}; return; } // Controleer of velden aanwezig zijn if (!newFormData.fields) { - console.error('FormData bevat geen velden!', newFormData); + console.error('🧐 [ChatInput] formData bevat geen velden!', newFormData); return; } - console.log('Velden in formData:', newFormData.fields); - console.log('Aantal velden:', Array.isArray(newFormData.fields) + console.log('🧐 [ChatInput] velden in formData:', newFormData.fields); + console.log('🧐 [ChatInput] aantal velden:', Array.isArray(newFormData.fields) ? newFormData.fields.length : Object.keys(newFormData.fields).length); @@ -206,7 +206,7 @@ export default { this.initFormValues(); // Log de geïnitialiseerde waarden - console.log('Formulierwaarden geïnitialiseerd:', this.formValues); + console.log('🧐 [ChatInput] formulierwaarden geïnitialiseerd:', this.formValues); }, immediate: true, deep: true @@ -251,6 +251,15 @@ export default { window.removeEventListener('resize', this.autoResize); }, methods: { + handleSpecialistCompleteFromActiveMessage(eventData) { + console.log('🧐 [ChatInput] specialist-complete ontvangen van actieve ChatMessage, bubbelt naar parent:', eventData); + this.$emit('specialist-complete', eventData); + }, + + handleSpecialistErrorFromActiveMessage(eventData) { + console.log('🧐 [ChatInput] specialist-error ontvangen van actieve ChatMessage, bubbelt naar parent:', eventData); + this.$emit('specialist-error', eventData); + }, handleLanguageChange(event) { if (event.detail && event.detail.language) { this.translatePlaceholder(event.detail.language); diff --git a/eveai_chat_client/static/assets/vue-components/ChatRoot.vue b/eveai_chat_client/static/assets/vue-components/ChatRoot.vue index ab3e903..c986d71 100644 --- a/eveai_chat_client/static/assets/vue-components/ChatRoot.vue +++ b/eveai_chat_client/static/assets/vue-components/ChatRoot.vue @@ -1,13 +1,50 @@ diff --git a/eveai_chat_client/static/assets/vue-components/CoreChatApp.vue b/eveai_chat_client/static/assets/vue-components/CoreChatApp.vue new file mode 100644 index 0000000..d3ba7be --- /dev/null +++ b/eveai_chat_client/static/assets/vue-components/CoreChatApp.vue @@ -0,0 +1,501 @@ + + + + + diff --git a/eveai_chat_client/static/assets/vue-components/DesktopChatShell.vue b/eveai_chat_client/static/assets/vue-components/DesktopChatShell.vue new file mode 100644 index 0000000..e9d872b --- /dev/null +++ b/eveai_chat_client/static/assets/vue-components/DesktopChatShell.vue @@ -0,0 +1,172 @@ + + + + + diff --git a/eveai_chat_client/static/assets/vue-components/MessageHistory.vue b/eveai_chat_client/static/assets/vue-components/MessageHistory.vue index 66b510a..bb5e165 100644 --- a/eveai_chat_client/static/assets/vue-components/MessageHistory.vue +++ b/eveai_chat_client/static/assets/vue-components/MessageHistory.vue @@ -20,8 +20,8 @@ :api-prefix="apiPrefix" :is-latest-ai-message="isLatestAiMessage(message)" @image-loaded="handleImageLoaded" - @specialist-complete="$emit('specialist-complete', $event)" - @specialist-error="$emit('specialist-error', $event)" + @specialist-complete="handleSpecialistCompleteFromMessage" + @specialist-error="handleSpecialistErrorFromMessage" > @@ -173,6 +173,15 @@ export default { if (this._resizeObserver) this._resizeObserver.disconnect(); }, methods: { + handleSpecialistCompleteFromMessage(eventData) { + console.log('🧐 [MessageHistory] specialist-complete ontvangen van ChatMessage, bubbelt naar parent:', eventData); + this.$emit('specialist-complete', eventData); + }, + + handleSpecialistErrorFromMessage(eventData) { + console.log('🧐 [MessageHistory] specialist-error ontvangen van ChatMessage, bubbelt naar parent:', eventData); + this.$emit('specialist-error', eventData); + }, async handleLanguageChange(event) { // Controleer of dit het eerste bericht is in een gesprek met maar één bericht if (this.messages.length === 1 && this.messages[0].sender === 'ai') { diff --git a/eveai_chat_client/static/assets/vue-components/MobileChatShell.vue b/eveai_chat_client/static/assets/vue-components/MobileChatShell.vue new file mode 100644 index 0000000..fc1f3b7 --- /dev/null +++ b/eveai_chat_client/static/assets/vue-components/MobileChatShell.vue @@ -0,0 +1,278 @@ + + + + + diff --git a/nginx/frontend_src/js/chat-client.js b/nginx/frontend_src/js/chat-client.js index 89bb79c..30e56f4 100644 --- a/nginx/frontend_src/js/chat-client.js +++ b/nginx/frontend_src/js/chat-client.js @@ -27,8 +27,10 @@ console.log('Components loaded:', Object.keys(Components)); // Import specifieke componenten import LanguageSelector from '../../../eveai_chat_client/static/assets/vue-components/LanguageSelector.vue'; -import ChatApp from '../../../eveai_chat_client/static/assets/vue-components/ChatApp.vue'; +// import ChatApp from '../../../eveai_chat_client/static/assets/vue-components/ChatApp.vue'; import ChatRoot from '../../../eveai_chat_client/static/assets/vue-components/ChatRoot.vue'; +import DesktopChatShell from '../../../eveai_chat_client/static/assets/vue-components/DesktopChatShell.vue'; +import MobileChatShell from '../../../eveai_chat_client/static/assets/vue-components/MobileChatShell.vue'; import SideBar from '../../../eveai_chat_client/static/assets/vue-components/SideBar.vue'; // VueUse-setup voor de chatclient (maakt composables beschikbaar via window.VueUse) @@ -131,27 +133,43 @@ function initializeChatApp() { } try { - if (!ChatApp) { - throw new Error('🚨 [CRITICAL ERROR] ChatApp component niet gevonden'); - } - // Extra verificatie dat alle sub-componenten beschikbaar zijn if (!Components.MessageHistory || !Components.ChatInput || !Components.TypingIndicator || !Components.ChatMessage) { console.warn('⚠️ [WARN] Niet alle benodigde sub-componenten zijn geladen!'); } - // Maak props voor de component - const props = { + // Maak props voor de shells / CoreChatApp + const baseProps = { apiPrefix: window.chatConfig.apiPrefix || '', conversationId: window.chatConfig.conversationId || 'default', userId: window.chatConfig.userId || null, userName: window.chatConfig.userName || '', initialLanguage: window.chatConfig.language || 'nl', supportedLanguageDetails: window.chatConfig.supportedLanguageDetails || {}, - allowedLanguages: window.chatConfig.allowedLanguages || ['nl', 'en', 'fr', 'de'] + allowedLanguages: window.chatConfig.allowedLanguages || ['nl', 'en', 'fr', 'de'], + tenantName: (window.chatConfig.tenantMake && window.chatConfig.tenantMake.name) || 'EveAI', + tenantSubtitle: (window.chatConfig.tenantMake && window.chatConfig.tenantMake.subtitle) || '', + tenantLogoUrl: (window.chatConfig.tenantMake && window.chatConfig.tenantMake.logo_url) || '', + explanationText: window.chatConfig.explanation || '', + settings: window.chatConfig.settings || {} }; + // Bepaal shell-type: expliciete config heeft voorrang, anders breakpoint + const layoutMode = window.chatConfig.layoutMode || 'auto'; + const isMobileBreakpoint = window.innerWidth <= 768; + let ShellComponent; + + if (layoutMode === 'desktop') { + ShellComponent = DesktopChatShell; + } else if (layoutMode === 'mobile') { + ShellComponent = MobileChatShell; + } else { + ShellComponent = isMobileBreakpoint ? MobileChatShell : DesktopChatShell; + } + + const props = { shellComponent: ShellComponent, shellProps: baseProps }; + // Mount de component via ChatRoot zodat SafeViewport de layout kan beheren const app = createApp(ChatRoot, props);