From 14273b8a7061b9ebb84615363e7153e36637ec8a Mon Sep 17 00:00:00 2001 From: Josako Date: Thu, 27 Nov 2025 11:32:46 +0100 Subject: [PATCH 1/2] - Full implementation of tab bar next to logo in mobile client - Customisation option in Tenant Make - Splitting all controls in the newly created tabs --- common/utils/chat_utils.py | 5 +- .../CHAT_CLIENT_CUSTOMISATION/1.0.0.yaml | 15 + config/static-manifest/manifest.json | 4 +- .../static/assets/vue-components/ChatApp.vue | 281 +++++++++++++++--- .../assets/vue-components/ChatInput.vue | 1 + .../assets/vue-components/ChatMessage.vue | 31 +- .../assets/vue-components/MobileHeader.vue | 71 +---- .../assets/vue-components/MobileTabBar.vue | 113 +++++++ .../vue-components/SideBarMobileSetup.vue | 118 ++++++++ eveai_chat_client/templates/base.html | 5 + nginx/frontend_src/js/chat-client.js | 85 +----- 11 files changed, 524 insertions(+), 205 deletions(-) create mode 100644 eveai_chat_client/static/assets/vue-components/MobileTabBar.vue create mode 100644 eveai_chat_client/static/assets/vue-components/SideBarMobileSetup.vue diff --git a/common/utils/chat_utils.py b/common/utils/chat_utils.py index 2199445..f2a5354 100644 --- a/common/utils/chat_utils.py +++ b/common/utils/chat_utils.py @@ -36,7 +36,10 @@ def get_default_chat_customisation(tenant_customisation=None): 'ai_message_text_color': '#212529', 'human_message_background': '#212529', 'human_message_text_color': '#ffffff', - 'human_message_inactive_text_color': '#808080' + 'human_message_inactive_text_color': '#808080', + 'tab_background': '#0a0a0a', + 'tab_icon_active_color': '#ffffff', + 'tab_icon_inactive_color': '#f0f0f0', } # If no tenant customization is provided, return the defaults diff --git a/config/customisations/globals/CHAT_CLIENT_CUSTOMISATION/1.0.0.yaml b/config/customisations/globals/CHAT_CLIENT_CUSTOMISATION/1.0.0.yaml index 7723c07..701c668 100644 --- a/config/customisations/globals/CHAT_CLIENT_CUSTOMISATION/1.0.0.yaml +++ b/config/customisations/globals/CHAT_CLIENT_CUSTOMISATION/1.0.0.yaml @@ -87,6 +87,21 @@ configuration: description: "Human Message Inactive Text Color" type: "color" required: false + tab_background: + name: "Tab Background Color" + description: "Tab Background Color" + type: "color" + required: false + tab_icon_active_color: + name: "Tab Icon Active Color" + description: "Tab Icon Active Color" + type: "color" + required: false + tab_icon_inactive_color: + name: "Tab Icon Inactive Color" + description: "Tab Icon Inactive Color" + type: "color" + required: false metadata: author: "Josako" date_added: "2024-06-06" diff --git a/config/static-manifest/manifest.json b/config/static-manifest/manifest.json index f2145d6..188b548 100644 --- a/config/static-manifest/manifest.json +++ b/config/static-manifest/manifest.json @@ -1,6 +1,6 @@ { - "dist/chat-client.js": "dist/chat-client.f8ee4d5a.js", - "dist/chat-client.css": "dist/chat-client.2fffefae.css", + "dist/chat-client.js": "dist/chat-client.e8905ecb.js", + "dist/chat-client.css": "dist/chat-client.d344ebba.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/ChatApp.vue b/eveai_chat_client/static/assets/vue-components/ChatApp.vue index 6a4aa45..93d9a74 100644 --- a/eveai_chat_client/static/assets/vue-components/ChatApp.vue +++ b/eveai_chat_client/static/assets/vue-components/ChatApp.vue @@ -1,38 +1,106 @@ active_text_color diff --git a/eveai_chat_client/static/assets/vue-components/SideBarMobileSetup.vue b/eveai_chat_client/static/assets/vue-components/SideBarMobileSetup.vue new file mode 100644 index 0000000..cbdecc2 --- /dev/null +++ b/eveai_chat_client/static/assets/vue-components/SideBarMobileSetup.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/eveai_chat_client/templates/base.html b/eveai_chat_client/templates/base.html index 427df33..c849823 100644 --- a/eveai_chat_client/templates/base.html +++ b/eveai_chat_client/templates/base.html @@ -44,6 +44,11 @@ --human-message-background: {{ customisation.human_message_background|default('#ffffff') }}; --human-message-text-color: {{ customisation.human_message_text_color|default('#212529') }}; + /* Mobe Tab Bar Colors */ + --tab-background: {{ customisation.tab_background|default('#0a0a0a') }}; + --tab-icon-active-color: {{ customisation.tab_icon_active_color|default('#ffffff') }}; + --tab-icon-inactive-color: {{ customisation.tab_icon_inactive_color|default('#f0f0f0') }}; + } diff --git a/nginx/frontend_src/js/chat-client.js b/nginx/frontend_src/js/chat-client.js index 901911f..89bb79c 100644 --- a/nginx/frontend_src/js/chat-client.js +++ b/nginx/frontend_src/js/chat-client.js @@ -30,7 +30,6 @@ import LanguageSelector from '../../../eveai_chat_client/static/assets/vue-compo 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 SideBar from '../../../eveai_chat_client/static/assets/vue-components/SideBar.vue'; -import MobileHeader from '../../../eveai_chat_client/static/assets/vue-components/MobileHeader.vue'; // VueUse-setup voor de chatclient (maakt composables beschikbaar via window.VueUse) import './vueuse-setup.js'; @@ -51,9 +50,6 @@ document.addEventListener('DOMContentLoaded', function() { // Initialiseer sidebar (vervangt fillSidebarExplanation en initializeLanguageSelector) initializeSidebar(); - // Initialiseer mobile header - initializeMobileHeader(); - // Initialiseer chat app (simpel) initializeChatApp(); }); @@ -121,85 +117,8 @@ function initializeSidebar() { } } -/** - * Initialiseert de mobile header component - */ -function initializeMobileHeader() { - const container = document.getElementById('mobile-header-container'); - - if (!container) { - console.error('#mobile-header-container niet gevonden'); - return; - } - - try { - // Maak props voor de component - const props = { - tenantMake: { - name: window.chatConfig.tenantMake?.name || '', - logo_url: window.chatConfig.tenantMake?.logo_url || '', - subtitle: window.chatConfig.tenantMake?.subtitle || '' - }, - initialLanguage: window.chatConfig.language || 'nl', - supportedLanguageDetails: window.chatConfig.supportedLanguageDetails || {}, - allowedLanguages: window.chatConfig.allowedLanguages || ['nl', 'en', 'fr', 'de'], - apiPrefix: window.chatConfig.apiPrefix || '' - }; - - // Mount de component - const app = createApp(MobileHeader, props); - - // Create and provide LanguageProvider for mobile header components - const initialLanguage = window.chatConfig?.language || 'nl'; - const apiPrefix = window.chatConfig?.apiPrefix || ''; - const languageProvider = createLanguageProvider(initialLanguage, apiPrefix); - app.provide(LANGUAGE_PROVIDER_KEY, languageProvider); - - // Error handler - app.config.errorHandler = (err, vm, info) => { - console.error('🚨 [Vue Error in MobileHeader]', err); - console.error('Component:', vm); - console.error('Error Info:', info); - }; - - const mountedApp = app.mount(container); - - // Dynamisch de headerhoogte doorgeven aan CSS - const updateHeaderHeightVar = () => { - const isMobile = window.matchMedia('(max-width: 768px)').matches; - if (!isMobile) { - document.documentElement.style.removeProperty('--mobile-header-height'); - return; - } - const h = container.offsetHeight || 60; // fallback - document.documentElement.style.setProperty('--mobile-header-height', `${h}px`); - }; - - // Initieel instellen en bij gebeurtenissen herberekenen - requestAnimationFrame(updateHeaderHeightVar); - window.addEventListener('resize', updateHeaderHeightVar); - - // Listen to language change events and update the mobile header's language provider - const languageChangeHandler = (event) => { - if (event.detail && event.detail.language) { - console.log('MobileHeader: Received language change event:', event.detail.language); - languageProvider.setLanguage(event.detail.language); - // taalwissel kan headerhoogte veranderen - requestAnimationFrame(updateHeaderHeightVar); - } - }; - document.addEventListener('language-changed', languageChangeHandler); - - // Store the handler for cleanup if needed - mountedApp._languageChangeHandler = languageChangeHandler; - mountedApp._updateHeaderHeightVar = updateHeaderHeightVar; - - console.log('✅ MobileHeader component successfully mounted with LanguageProvider en dynamische headerhoogte'); - return mountedApp; - } catch (error) { - console.error('🚨 [CRITICAL ERROR] Bij initialiseren mobile header:', error); - } -} +// initializeMobileHeader is verwijderd; de mobiele header wordt nu volledig +// binnen ChatApp.vue beheerd. /** * Initialiseert de chat app (Vue component) From b1d8c9a17d0cccdc09867f7ebd31110bf47e8dcb Mon Sep 17 00:00:00 2001 From: Josako Date: Fri, 28 Nov 2025 10:04:31 +0100 Subject: [PATCH 2/2] - Small changes to allow for keyboard input, not finished --- config/static-manifest/manifest.json | 4 +-- eveai_chat_client/static/assets/css/chat.css | 26 +++++++++++++++++-- .../static/assets/vue-components/ChatApp.vue | 24 +++++++++++------ .../assets/vue-components/SafeViewport.vue | 3 +++ 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/config/static-manifest/manifest.json b/config/static-manifest/manifest.json index 188b548..ba22821 100644 --- a/config/static-manifest/manifest.json +++ b/config/static-manifest/manifest.json @@ -1,6 +1,6 @@ { - "dist/chat-client.js": "dist/chat-client.e8905ecb.js", - "dist/chat-client.css": "dist/chat-client.d344ebba.css", + "dist/chat-client.js": "dist/chat-client.5b709f8c.js", + "dist/chat-client.css": "dist/chat-client.cb306abb.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/css/chat.css b/eveai_chat_client/static/assets/css/chat.css index 6bb3633..d662fb7 100644 --- a/eveai_chat_client/static/assets/css/chat.css +++ b/eveai_chat_client/static/assets/css/chat.css @@ -21,7 +21,9 @@ /* App container layout */ .app-container { display: flex; - /* Use visual viewport variable when available */ + /* Op desktop gebruiken we de veilige viewporthoogte direct; op mobiel + laten we html/body de hoogte bepalen en neemt de app-container + eenvoudig 100% daarvan in via de media query verderop. */ min-height: 0; height: calc(var(--safe-vh, var(--vvh, 1vh)) * 100); width: 100%; @@ -93,7 +95,7 @@ display: flex; flex-direction: column; min-height: 0; - height: auto; /* prefer dynamic viewport on desktop */ + height: auto; /* desktop: dynamische hoogte, op mobiel overschreven */ } .chat-container { @@ -103,6 +105,26 @@ min-height: 0; /* laat kinderen (ChatApp) krimpen */ } +/* Op mobiel sluiten we de volledige content-kolom strak aan op de veilige + viewporthoogte zodat alleen de chatcontent zelf kan scrollen en niet de + gehele pagina wanneer het toetsenbord opent. */ +@media (max-width: 768px) { + .app-container { + height: 100%; + } + + .content-area { + height: 100%; + overflow: hidden; + } + + .chat-container { + flex: 1 1 auto; + min-height: 0; + overflow: hidden; + } +} + html, body { height: calc(var(--safe-vh, var(--vvh, 1vh)) * 100); min-height: 0; diff --git a/eveai_chat_client/static/assets/vue-components/ChatApp.vue b/eveai_chat_client/static/assets/vue-components/ChatApp.vue index 93d9a74..deac7c4 100644 --- a/eveai_chat_client/static/assets/vue-components/ChatApp.vue +++ b/eveai_chat_client/static/assets/vue-components/ChatApp.vue @@ -1,7 +1,7 @@ active_text_color