From ccc1a2afb8b2436222feec2c00fe7787f3244442 Mon Sep 17 00:00:00 2001 From: Josako Date: Wed, 23 Jul 2025 16:02:11 +0200 Subject: [PATCH] - Layout improvements for the Chat client --- common/utils/chat_utils.py | 128 +++++++++++++- common/utils/template_filters.py | 4 + .../CHAT_CLIENT_CUSTOMISATION/1.0.0.yaml | 100 ++++++----- .../static/assets/css/chat-components.css | 55 ++---- .../static/assets/css/chat-input.css | 33 ---- .../static/assets/css/chat-message.css | 10 -- .../static/assets/css/form-message.css | 32 ---- eveai_chat_client/static/assets/css/form.css | 30 ---- .../static/assets/vue-components/ChatApp.vue | 2 +- .../assets/vue-components/ChatInput.vue | 61 ++++--- .../assets/vue-components/ChatMessage.vue | 43 +++-- .../assets/vue-components/DynamicForm.vue | 37 +++- .../assets/vue-components/FormField.vue | 3 +- .../assets/vue-components/FormMessage.vue | 13 -- .../assets/vue-components/MessageHistory.vue | 5 +- .../vue-components/SideBarExplanation.vue | 6 +- eveai_chat_client/templates/base.html | 23 ++- .../TRAICIE_SELECTION_SPECIALIST/1_4.py | 5 +- test_chat_customisation_corrections.py | 159 ++++++++++++++++++ 19 files changed, 472 insertions(+), 277 deletions(-) create mode 100644 test_chat_customisation_corrections.py diff --git a/common/utils/chat_utils.py b/common/utils/chat_utils.py index e881e40..9487703 100644 --- a/common/utils/chat_utils.py +++ b/common/utils/chat_utils.py @@ -1,4 +1,5 @@ import json +import re """ Utility functions for chat customization. @@ -20,18 +21,20 @@ def get_default_chat_customisation(tenant_customisation=None): """ # Default customization options default_customisation = { - 'primary_color': '#007bff', - 'secondary_color': '#6c757d', - 'background_color': '#ffffff', - 'text_color': '#212529', + 'sidebar_markdown': '', 'sidebar_color': '#f8f9fa', 'sidebar_background': '#2c3e50', - 'gradient_start_color': '#f5f7fa', - 'gradient_end_color': '#c3cfe2', 'markdown_background_color': 'transparent', 'markdown_text_color': '#ffffff', - 'sidebar_markdown': '', - 'progress_tracker_insights': 'No Information' + 'gradient_start_color': '#f5f7fa', + 'gradient_end_color': '#c3cfe2', + 'progress_tracker_insights': 'No Information', + 'active_background_color': '#ffffff', + 'active_text_color': '#212529', + 'history_background': 10, + 'history_user_message_background': -10, + 'history_ai_message_background': 0, + 'history_message_text_color': '#212529', } # If no tenant customization is provided, return the defaults @@ -56,3 +59,112 @@ def get_default_chat_customisation(tenant_customisation=None): customisation[key] = value return customisation + + +def hex_to_rgb(hex_color): + """ + Convert hex color to RGB tuple. + + Args: + hex_color (str): Hex color string (e.g., '#ffffff' or 'ffffff') + + Returns: + tuple: RGB values as (r, g, b) + """ + # Remove # if present + hex_color = hex_color.lstrip('#') + + # Handle 3-character hex codes + if len(hex_color) == 3: + hex_color = ''.join([c*2 for c in hex_color]) + + # Convert to RGB + try: + return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4)) + except ValueError: + # Return white as fallback + return (255, 255, 255) + + +def adjust_color_alpha(percentage): + """ + Convert percentage to RGBA color with appropriate base color and alpha. + + Args: + percentage (int): Percentage (-50 to 50) + Positive = white base (lighten) + Negative = black base (darken) + Zero = transparent + + Returns: + str: RGBA color string for CSS + """ + if percentage == 0: + return 'rgba(255, 255, 255, 0)' # Volledig transparant + + # Bepaal basis kleur + if percentage > 0: + # Positief = wit voor verheldering + base_color = (255, 255, 255) + else: + # Negatief = zwart voor verdonkering + base_color = (0, 0, 0) + + # Bereken alpha op basis van percentage (max 50 = alpha 1.0) + alpha = abs(percentage) / 50.0 + alpha = max(0.0, min(1.0, alpha)) # Zorg voor 0.0-1.0 range + + return f'rgba({base_color[0]}, {base_color[1]}, {base_color[2]}, {alpha})' + + +def adjust_color_brightness(hex_color, percentage): + """ + Adjust the brightness of a hex color by a percentage. + + Args: + hex_color (str): Hex color string (e.g., '#ffffff') + percentage (int): Percentage to adjust (-100 to 100) + Positive = lighter, Negative = darker + + Returns: + str: RGBA color string for CSS (e.g., 'rgba(255, 255, 255, 0.9)') + """ + if not hex_color or not isinstance(hex_color, str): + return 'rgba(255, 255, 255, 0.1)' + + # Get RGB values + r, g, b = hex_to_rgb(hex_color) + + # Calculate adjustment factor + if percentage > 0: + # Lighten: move towards white + factor = percentage / 100.0 + r = int(r + (255 - r) * factor) + g = int(g + (255 - g) * factor) + b = int(b + (255 - b) * factor) + else: + # Darken: move towards black + factor = abs(percentage) / 100.0 + r = int(r * (1 - factor)) + g = int(g * (1 - factor)) + b = int(b * (1 - factor)) + + # Ensure values are within 0-255 range + r = max(0, min(255, r)) + g = max(0, min(255, g)) + b = max(0, min(255, b)) + + # Return as rgba with slight transparency for better blending + return f'rgba({r}, {g}, {b}, 0.9)' + + +def get_base_background_color(): + """ + Get the base background color for history adjustments. + This should be the main chat background color. + + Returns: + str: Hex color string + """ + # Use a neutral base color that works well with adjustments + return '#f8f9fa' diff --git a/common/utils/template_filters.py b/common/utils/template_filters.py index 049179a..bbc4e8a 100644 --- a/common/utils/template_filters.py +++ b/common/utils/template_filters.py @@ -5,6 +5,7 @@ import markdown from markupsafe import Markup from datetime import datetime from common.utils.nginx_utils import prefixed_url_for as puf +from common.utils.chat_utils import adjust_color_brightness, adjust_color_alpha, get_base_background_color from flask import current_app, url_for @@ -116,7 +117,10 @@ def register_filters(app): app.jinja_env.filters['prefixed_url_for'] = prefixed_url_for app.jinja_env.filters['markdown'] = render_markdown app.jinja_env.filters['clean_markdown'] = clean_markdown + app.jinja_env.filters['adjust_color_brightness'] = adjust_color_brightness + app.jinja_env.filters['adjust_color_alpha'] = adjust_color_alpha app.jinja_env.globals['prefixed_url_for'] = prefixed_url_for app.jinja_env.globals['get_pagination_html'] = get_pagination_html + app.jinja_env.globals['get_base_background_color'] = get_base_background_color 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 2e1da15..8390cbe 100644 --- a/config/customisations/globals/CHAT_CLIENT_CUSTOMISATION/1.0.0.yaml +++ b/config/customisations/globals/CHAT_CLIENT_CUSTOMISATION/1.0.0.yaml @@ -1,66 +1,82 @@ version: "1.0.0" name: "Chat Client Customisation" configuration: - "sidebar_markdown": + sidebar_markdown: name: "Sidebar Markdown" description: "Sidebar Markdown-formatted Text" type: "text" required: false - "progress_tracker_insights": - name: "Progress Tracker Insights" + sidebar_color: + name: "Sidebar Text Color" + description: "Sidebar Color" + type: "color" + required: false + sidebar_background: + name: "Sidebar Background Color" + description: "Sidebar Background Color" + type: "color" + required: false + markdown_background_color: + name: "Markdown Background Color" + description: "Markdown Background Color" + type: "color" + required: false + markdown_text_color: + name: "Markdown Text Color" + description: "Markdown Text Color" + type: "color" + required: false + gradient_start_color: + name: "Chat Gradient Background Start Color" + description: "Start Color for the gradient in the Chat Area" + type: "color" + required: false + gradient_end_color: + name: "Chat Gradient Background End Color" + description: "End Color for the gradient in the Chat Area" + type: "color" + required: false + progress_tracker_insights: + name: "Progress Tracker Insights Level" description: "Level of information shown by the Progress Tracker" type: "enum" allowed_values: ["No Information", "Active Interaction Only", "All Interactions"] default: "No Information" required: true - "primary_color": - name: "Primary Color" + active_background_color: + name: "Active Interaction Background Color" description: "Primary Color" type: "color" required: false - "secondary_color": - name: "Secondary Color" + active_text_color: + name: "Active Interaction Text Color" description: "Secondary Color" type: "color" required: false - "background_color": - name: "Background Color" - description: "Background Color" - type: "color" + history_background: + name: "History Background" + description: "Percentage to lighten (+) / darken (-) the user message background" + type: "integer" + min_value: -50 + max_value: 50 required: false - "text_color": - name: "Text Color" - description: "Text Color" - type: "color" + history_user_message_background: + name: "History User Message Background" + description: "Percentage to lighten (+) / darken (-) the user message background" + type: "integer" + min_value: -50 + max_value: 50 required: false - "sidebar_color": - name: "Sidebar Color" - description: "Sidebar Color" - type: "color" + history_ai_message_background: + name: "History AI Message Background" + description: "Percentage to lighten (+) / darken (-) the AI message background" + type: "integer" + min_value: -50 + max_value: 50 required: false - "sidebar_background": - name: "Sidebar Background" - description: "Sidebar Background Color" - type: "color" - required: false - "markdown_background_color": - name: "Markdown Background" - description: "Markdown Background Color" - type: "color" - required: false - "markdown_text_color": - name: "Markdown Text" - description: "Markdown Text Color" - type: "color" - required: false - "gradient_start_color": - name: "Gradient Start Color" - description: "Start Color for the gradient in the Chat Area" - type: "color" - required: false - "gradient_end_color": - name: "Gradient End Color" - description: "End Color for the gradient in the Chat Area" + history_message_text_color: + name: "History Text Color" + description: "History Message Text Color" type: "color" required: false metadata: diff --git a/eveai_chat_client/static/assets/css/chat-components.css b/eveai_chat_client/static/assets/css/chat-components.css index 2724eda..3c97298 100644 --- a/eveai_chat_client/static/assets/css/chat-components.css +++ b/eveai_chat_client/static/assets/css/chat-components.css @@ -30,7 +30,7 @@ min-height: 0; /* Belangrijk voor nested flexbox */ margin-bottom: 20px; /* Ruimte tussen messages en input */ border-radius: 15px; - background: rgba(255,255,255,0.1); + background: var(--history-background); backdrop-filter: blur(10px); box-shadow: 0 4px 20px rgba(0,0,0,0.1); width: 100%; @@ -94,7 +94,8 @@ align-items: flex-end; gap: 12px; padding: 20px; - background: white; + background: var(--active-background-color); + color: var(--active-text-color); border-radius: 15px; box-shadow: 0 2px 15px rgba(0,0,0,0.1); border: 1px solid rgba(0,0,0,0.05); @@ -105,32 +106,6 @@ position: relative; } -.message-input { - width: 100%; - min-height: 45px; - max-height: 120px; - padding: 12px 18px; - border: 1px solid #ddd; - border-radius: 25px; - resize: none; - font-family: inherit; - font-size: 14px; - line-height: 1.4; - outline: none; - transition: all 0.2s ease; - box-sizing: border-box; -} - -.message-input:focus { - border-color: var(--primary-color); - box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.1); -} - -.message-input.over-limit { - border-color: #dc3545; - background-color: rgba(220, 53, 69, 0.05); -} - .input-actions { display: flex; @@ -143,8 +118,8 @@ height: 45px; border: none; border-radius: 50%; - background: var(--primary-color); - color: white; + background: var(--active-background-color); + color: var(--active-text-color); cursor: pointer; display: flex; align-items: center; @@ -155,7 +130,8 @@ } .send-btn:hover:not(:disabled) { - background: var(--secondary-color); + background: var(--active-text-color); + color: var(--active-background-color); transform: scale(1.05); box-shadow: 0 4px 15px rgba(0,0,0,0.2); } @@ -230,12 +206,6 @@ font-size: 16px; } - .message-input { - font-size: 16px; /* Voorkomt zoom op iOS */ - padding: 10px 15px; - min-height: 40px; - } - .chat-component-container { max-width: 100%; /* Op mobiel volledige breedte gebruiken */ } @@ -261,9 +231,6 @@ } /* Loading states */ -.chat-input.loading .message-input { - opacity: 0.7; -} .chat-input.loading .action-btn { animation: pulse 1.5s infinite; @@ -376,16 +343,16 @@ /* User message bubble styling */ .message.user .message-content { - background: rgba(0, 0, 0, 0.1); - color: white; + background: var(--history-user-message-background); + color: var(--history-message-text-color); border-bottom-right-radius: 4px; } /* AI/Bot message bubble styling */ .message.ai .message-content, .message.bot .message-content { - background: rgba(255, 255, 255, 0.1); - color: #212529; + background: var(--history-ai-message-background); + color: var(--history-message-text-color); border-bottom-left-radius: 4px; margin-right: 60px; } diff --git a/eveai_chat_client/static/assets/css/chat-input.css b/eveai_chat_client/static/assets/css/chat-input.css index 7eb4b3b..9a4e060 100644 --- a/eveai_chat_client/static/assets/css/chat-input.css +++ b/eveai_chat_client/static/assets/css/chat-input.css @@ -22,27 +22,6 @@ position: relative; } -.message-input { - width: 100%; - min-height: 40px; - padding: 10px 40px 10px 15px; - border: 1px solid #ddd; - border-radius: 20px; - resize: none; - outline: none; - transition: border-color 0.2s; - font-family: Arial, sans-serif; - font-size: 14px; -} - -.message-input:focus { - border-color: #0084ff; -} - -.message-input.over-limit { - border-color: #ff4d4f; -} - /* Character counter */ .character-counter { position: absolute; @@ -106,15 +85,3 @@ 100% { transform: rotate(360deg); } } -/* Formulier in chat input */ -.dynamic-form-container { - margin-bottom: 10px; - border: 1px solid #ddd; - border-radius: 8px; - padding: 15px 15px 5px 15px; - position: relative; - background-color: #f9f9f9; - box-shadow: 0 2px 4px rgba(0,0,0,0.05); - font-family: Arial, sans-serif; - font-size: 14px; -} diff --git a/eveai_chat_client/static/assets/css/chat-message.css b/eveai_chat_client/static/assets/css/chat-message.css index 6302c93..c1e4671 100644 --- a/eveai_chat_client/static/assets/css/chat-message.css +++ b/eveai_chat_client/static/assets/css/chat-message.css @@ -21,16 +21,6 @@ font-size: 14px; } -/* Formulier styling */ -.form-display { - margin: 15px 0; - border-radius: 8px; - background-color: rgba(245, 245, 245, 0.7); - padding: 15px; - border: 1px solid #e0e0e0; - font-family: inherit; -} - /* Tabel styling voor formulieren */ .form-result-table { width: 100%; diff --git a/eveai_chat_client/static/assets/css/form-message.css b/eveai_chat_client/static/assets/css/form-message.css index 90220ba..a82cbf9 100644 --- a/eveai_chat_client/static/assets/css/form-message.css +++ b/eveai_chat_client/static/assets/css/form-message.css @@ -1,33 +1,3 @@ -/* Styling voor formulier in berichten */ -.message .form-display { - margin-bottom: 12px; - border-radius: 8px; - background-color: rgba(245, 245, 245, 0.7); - padding: 12px; - border: 1px solid #e0e0e0; -} - -.message.user .form-display { - background-color: rgba(255, 255, 255, 0.1); -} - -.message.ai .form-display { - background-color: rgba(245, 245, 250, 0.7); -} -/* Styling voor formulieren in berichten */ - -.form-display { - margin-bottom: 10px; - border-radius: 8px; - padding: 12px; - background-color: rgba(0, 0, 0, 0.03); - border: 1px solid rgba(0, 0, 0, 0.1); -} - -.user-form-values { - background-color: rgba(0, 123, 255, 0.05); -} - /* Speciale styling voor read-only formulieren in user messages */ .user-form .form-field { margin-bottom: 6px !important; @@ -35,7 +5,6 @@ .user-form .field-label { font-weight: 500 !important; - color: #555 !important; padding: 2px 0 !important; } @@ -69,7 +38,6 @@ .form-readonly .field-label { font-weight: 500; - color: #555; } .form-readonly .field-value { diff --git a/eveai_chat_client/static/assets/css/form.css b/eveai_chat_client/static/assets/css/form.css index d899de5..ade61ce 100644 --- a/eveai_chat_client/static/assets/css/form.css +++ b/eveai_chat_client/static/assets/css/form.css @@ -1,11 +1,4 @@ /* Dynamisch formulier stijlen */ -.dynamic-form-container { - margin-bottom: 15px; - border: 1px solid #e0e0e0; - border-radius: 8px; - overflow: hidden; - background-color: #f9f9f9; -} .dynamic-form { padding: 15px; @@ -19,22 +12,6 @@ border-bottom: 1px solid #e0e0e0; } -.form-icon { - margin-right: 10px; - width: 24px; - height: 24px; - display: flex; - align-items: center; - justify-content: center; - color: #555; -} - -.form-title { - font-size: 1.2rem; - font-weight: 600; - color: #333; -} - .form-fields { display: grid; grid-template-columns: 1fr; @@ -152,13 +129,6 @@ border-bottom: 1px solid #eee; } -.field-label { - flex: 0 0 30%; - font-weight: 500; - color: #555; - padding-right: 10px; -} - .field-value { flex: 1; word-break: break-word; diff --git a/eveai_chat_client/static/assets/vue-components/ChatApp.vue b/eveai_chat_client/static/assets/vue-components/ChatApp.vue index 22d8f3c..9f9d4c3 100644 --- a/eveai_chat_client/static/assets/vue-components/ChatApp.vue +++ b/eveai_chat_client/static/assets/vue-components/ChatApp.vue @@ -1,4 +1,4 @@ -