- Mobile client changes.
This commit is contained in:
@@ -497,6 +497,17 @@ export default {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Verberg character counter op mobile */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.character-counter {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-input {
|
||||||
|
padding-right: 15px; /* Verminder van 60px naar 15px omdat counter weg is */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Input actions */
|
/* Input actions */
|
||||||
.input-actions {
|
.input-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
<!-- MobileHeader.vue -->
|
|
||||||
<template>
|
<template>
|
||||||
<div class="mobile-header">
|
<div class="mobile-header">
|
||||||
<SideBarLogo
|
<SideBarLogo
|
||||||
:logo-url="tenantMake.logo_url"
|
:logo-url="tenantMake.logo_url"
|
||||||
:make-name="tenantMake.name"
|
:make-name="tenantMake.name"
|
||||||
class="mobile-logo"
|
class="mobile-logo"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<LanguageSelector
|
<LanguageSelector
|
||||||
:initial-language="initialLanguage"
|
:initial-language="initialLanguage"
|
||||||
:current-language="currentLanguage"
|
:current-language="currentLanguage"
|
||||||
@@ -56,21 +55,21 @@ const currentLanguage = ref(props.initialLanguage);
|
|||||||
|
|
||||||
const handleLanguageChange = (newLanguage) => {
|
const handleLanguageChange = (newLanguage) => {
|
||||||
currentLanguage.value = newLanguage;
|
currentLanguage.value = newLanguage;
|
||||||
|
|
||||||
// Emit to parent
|
// Emit to parent
|
||||||
emit('language-changed', newLanguage);
|
emit('language-changed', newLanguage);
|
||||||
|
|
||||||
// Global event for backward compatibility
|
// Global event for backward compatibility
|
||||||
const globalEvent = new CustomEvent('language-changed', {
|
const globalEvent = new CustomEvent('language-changed', {
|
||||||
detail: { language: newLanguage }
|
detail: { language: newLanguage }
|
||||||
});
|
});
|
||||||
document.dispatchEvent(globalEvent);
|
document.dispatchEvent(globalEvent);
|
||||||
|
|
||||||
// Update chatConfig
|
// Update chatConfig
|
||||||
if (window.chatConfig) {
|
if (window.chatConfig) {
|
||||||
window.chatConfig.language = newLanguage;
|
window.chatConfig.language = newLanguage;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save preference
|
// Save preference
|
||||||
localStorage.setItem('preferredLanguage', newLanguage);
|
localStorage.setItem('preferredLanguage', newLanguage);
|
||||||
};
|
};
|
||||||
@@ -88,56 +87,72 @@ const handleLanguageChange = (newLanguage) => {
|
|||||||
min-height: 60px;
|
min-height: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mobile logo styling - compact version */
|
/* Mobile logo container - meer specifieke styling */
|
||||||
.mobile-header :deep(.mobile-logo) {
|
.mobile-logo {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
height: 50px; /* Vaste hoogte voor consistentie */
|
||||||
|
min-width: 120px; /* Minimale breedte */
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-header :deep(.mobile-logo .sidebar-logo) {
|
/* Diepere styling voor het logo component */
|
||||||
padding: 0;
|
.mobile-logo :deep(.sidebar-logo) {
|
||||||
margin-right: 15px;
|
padding: 0 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
justify-content: flex-start !important;
|
||||||
|
height: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-header :deep(.mobile-logo .logo-image) {
|
.mobile-logo :deep(.logo-image) {
|
||||||
max-height: 40px;
|
max-height: 40px !important;
|
||||||
max-width: 120px;
|
max-width: 120px !important;
|
||||||
|
height: auto !important;
|
||||||
|
width: auto !important;
|
||||||
|
object-fit: contain !important;
|
||||||
|
display: block !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-header :deep(.mobile-logo .logo-placeholder) {
|
.mobile-logo :deep(.logo-placeholder) {
|
||||||
width: 40px;
|
width: 40px !important;
|
||||||
height: 40px;
|
height: 40px !important;
|
||||||
font-size: 1rem;
|
font-size: 1rem !important;
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
justify-content: center !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mobile language selector styling - compact horizontal version */
|
/* Mobile language selector styling */
|
||||||
.mobile-header :deep(.mobile-language-selector) {
|
.mobile-language-selector {
|
||||||
flex-shrink: 0;
|
flex-shrink: 1;
|
||||||
min-width: 140px;
|
min-width: 140px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-header :deep(.mobile-language-selector .language-selector) {
|
.mobile-language-selector :deep(.language-selector) {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-header :deep(.mobile-language-selector label) {
|
.mobile-language-selector :deep(label) {
|
||||||
display: none; /* Hide label in mobile header */
|
display: none; /* Hide label in mobile header */
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-header :deep(.mobile-language-selector .language-select) {
|
.mobile-language-selector :deep(.language-select) {
|
||||||
padding: 6px 10px;
|
padding: 6px 10px;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
min-width: 120px;
|
min-width: 120px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Show mobile header on mobile */
|
/* Media queries voor responsiviteit */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.mobile-header {
|
.mobile-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hide mobile header on desktop */
|
|
||||||
@media (min-width: 769px) {
|
@media (min-width: 769px) {
|
||||||
.mobile-header {
|
.mobile-header {
|
||||||
display: none;
|
display: none;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
86
eveai_chat_client/static/dist/chat-client.js
vendored
86
eveai_chat_client/static/dist/chat-client.js
vendored
File diff suppressed because one or more lines are too long
@@ -30,6 +30,7 @@ console.log('Components loaded:', Object.keys(Components));
|
|||||||
import LanguageSelector from '../../../eveai_chat_client/static/assets/vue-components/LanguageSelector.vue';
|
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 SideBar from '../../../eveai_chat_client/static/assets/vue-components/SideBar.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';
|
||||||
|
|
||||||
// Globale Vue error tracking
|
// Globale Vue error tracking
|
||||||
window.addEventListener('error', function(event) {
|
window.addEventListener('error', function(event) {
|
||||||
@@ -47,6 +48,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
// Initialiseer sidebar (vervangt fillSidebarExplanation en initializeLanguageSelector)
|
// Initialiseer sidebar (vervangt fillSidebarExplanation en initializeLanguageSelector)
|
||||||
initializeSidebar();
|
initializeSidebar();
|
||||||
|
|
||||||
|
// Initialiseer mobile header
|
||||||
|
initializeMobileHeader();
|
||||||
|
|
||||||
// Initialiseer chat app (simpel)
|
// Initialiseer chat app (simpel)
|
||||||
initializeChatApp();
|
initializeChatApp();
|
||||||
});
|
});
|
||||||
@@ -114,6 +118,68 @@ 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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
document.addEventListener('language-changed', languageChangeHandler);
|
||||||
|
|
||||||
|
// Store the handler for cleanup if needed
|
||||||
|
mountedApp._languageChangeHandler = languageChangeHandler;
|
||||||
|
|
||||||
|
console.log('✅ MobileHeader component successfully mounted with LanguageProvider');
|
||||||
|
return mountedApp;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('🚨 [CRITICAL ERROR] Bij initialiseren mobile header:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialiseert de chat app (Vue component)
|
* Initialiseert de chat app (Vue component)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,206 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Test script to verify mobile header visibility fix for eveai_chat_client
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import re
|
|
||||||
|
|
||||||
def test_mobile_header_css_fix():
|
|
||||||
"""Test that MobileHeader component has correct CSS media queries"""
|
|
||||||
print("Testing MobileHeader CSS fix...")
|
|
||||||
|
|
||||||
mobile_header_path = 'eveai_chat_client/static/assets/vue-components/MobileHeader.vue'
|
|
||||||
|
|
||||||
if not os.path.exists(mobile_header_path):
|
|
||||||
print(f"❌ MobileHeader.vue not found at {mobile_header_path}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
with open(mobile_header_path, 'r') as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
# Check for mobile media query (show on mobile)
|
|
||||||
mobile_show_pattern = r'@media\s*\(\s*max-width:\s*768px\s*\)\s*\{[^}]*\.mobile-header\s*\{[^}]*display:\s*flex'
|
|
||||||
mobile_show_match = re.search(mobile_show_pattern, content, re.DOTALL)
|
|
||||||
|
|
||||||
if not mobile_show_match:
|
|
||||||
print("❌ Missing mobile media query to show mobile header")
|
|
||||||
print(" Expected: @media (max-width: 768px) with .mobile-header { display: flex }")
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
print("✓ Found mobile media query to show header on mobile devices")
|
|
||||||
|
|
||||||
# Check for desktop media query (hide on desktop)
|
|
||||||
desktop_hide_pattern = r'@media\s*\(\s*min-width:\s*769px\s*\)\s*\{[^}]*\.mobile-header\s*\{[^}]*display:\s*none'
|
|
||||||
desktop_hide_match = re.search(desktop_hide_pattern, content, re.DOTALL)
|
|
||||||
|
|
||||||
if not desktop_hide_match:
|
|
||||||
print("❌ Missing desktop media query to hide mobile header")
|
|
||||||
print(" Expected: @media (min-width: 769px) with .mobile-header { display: none }")
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
print("✓ Found desktop media query to hide header on desktop devices")
|
|
||||||
|
|
||||||
# Check that both media queries exist in correct order
|
|
||||||
mobile_pos = content.find('@media (max-width: 768px)')
|
|
||||||
desktop_pos = content.find('@media (min-width: 769px)')
|
|
||||||
|
|
||||||
if mobile_pos == -1 or desktop_pos == -1:
|
|
||||||
print("❌ Media queries not found in expected format")
|
|
||||||
return False
|
|
||||||
|
|
||||||
if mobile_pos > desktop_pos:
|
|
||||||
print("⚠️ Warning: Mobile media query comes after desktop query (may cause specificity issues)")
|
|
||||||
|
|
||||||
print("✅ MobileHeader CSS fix is correctly implemented")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def test_global_css_rules():
|
|
||||||
"""Test that global CSS rules for mobile-header-container are correct"""
|
|
||||||
print("\nTesting global CSS rules...")
|
|
||||||
|
|
||||||
css_path = 'eveai_chat_client/static/assets/css/chat.css'
|
|
||||||
|
|
||||||
if not os.path.exists(css_path):
|
|
||||||
print(f"❌ chat.css not found at {css_path}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
with open(css_path, 'r') as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
# Check default hidden state
|
|
||||||
if '#mobile-header-container' not in content or 'display: none' not in content:
|
|
||||||
print("❌ Missing default hidden state for mobile-header-container")
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
print("✓ Found default hidden state for mobile-header-container")
|
|
||||||
|
|
||||||
# Check mobile media query shows container
|
|
||||||
# Look for the media query and then check if mobile-header-container is set to display: block within it
|
|
||||||
media_query_start = content.find('@media (max-width: 768px)')
|
|
||||||
if media_query_start == -1:
|
|
||||||
print("❌ Missing @media (max-width: 768px) query")
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Find the closing brace of this media query
|
|
||||||
brace_count = 0
|
|
||||||
media_query_end = media_query_start
|
|
||||||
for i, char in enumerate(content[media_query_start:]):
|
|
||||||
if char == '{':
|
|
||||||
brace_count += 1
|
|
||||||
elif char == '}':
|
|
||||||
brace_count -= 1
|
|
||||||
if brace_count == 0:
|
|
||||||
media_query_end = media_query_start + i
|
|
||||||
break
|
|
||||||
|
|
||||||
media_query_content = content[media_query_start:media_query_end + 1]
|
|
||||||
|
|
||||||
if '#mobile-header-container' in media_query_content and 'display: block' in media_query_content:
|
|
||||||
print("✓ Found mobile media query to show mobile-header-container")
|
|
||||||
else:
|
|
||||||
print("❌ Mobile media query doesn't properly show mobile-header-container")
|
|
||||||
return False
|
|
||||||
|
|
||||||
print("✅ Global CSS rules are correct")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def test_built_assets():
|
|
||||||
"""Test that built assets exist and are recent"""
|
|
||||||
print("\nTesting built assets...")
|
|
||||||
|
|
||||||
assets_to_check = [
|
|
||||||
'eveai_chat_client/static/dist/chat-client.js',
|
|
||||||
'eveai_chat_client/static/dist/chat-client.css'
|
|
||||||
]
|
|
||||||
|
|
||||||
for asset_path in assets_to_check:
|
|
||||||
if not os.path.exists(asset_path):
|
|
||||||
print(f"❌ Built asset not found: {asset_path}")
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
# Check file size to ensure it's not empty
|
|
||||||
size = os.path.getsize(asset_path)
|
|
||||||
if size == 0:
|
|
||||||
print(f"❌ Built asset is empty: {asset_path}")
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
print(f"✓ Built asset exists and has content: {asset_path} ({size} bytes)")
|
|
||||||
|
|
||||||
print("✅ Built assets are present and valid")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def test_component_structure():
|
|
||||||
"""Test that MobileHeader component structure is intact"""
|
|
||||||
print("\nTesting MobileHeader component structure...")
|
|
||||||
|
|
||||||
mobile_header_path = 'eveai_chat_client/static/assets/vue-components/MobileHeader.vue'
|
|
||||||
|
|
||||||
with open(mobile_header_path, 'r') as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
required_elements = [
|
|
||||||
'class="mobile-header"',
|
|
||||||
'SideBarLogo',
|
|
||||||
'LanguageSelector',
|
|
||||||
'justify-content: space-between',
|
|
||||||
'align-items: center'
|
|
||||||
]
|
|
||||||
|
|
||||||
missing_elements = []
|
|
||||||
for element in required_elements:
|
|
||||||
if element not in content:
|
|
||||||
missing_elements.append(element)
|
|
||||||
else:
|
|
||||||
print(f"✓ Found: {element}")
|
|
||||||
|
|
||||||
if missing_elements:
|
|
||||||
print(f"❌ Missing elements in MobileHeader:")
|
|
||||||
for element in missing_elements:
|
|
||||||
print(f" - {element}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
print("✅ MobileHeader component structure is intact")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def main():
|
|
||||||
"""Run all tests"""
|
|
||||||
print("🔧 Testing Mobile Header Visibility Fix")
|
|
||||||
print("=" * 50)
|
|
||||||
|
|
||||||
tests = [
|
|
||||||
test_mobile_header_css_fix,
|
|
||||||
test_global_css_rules,
|
|
||||||
test_built_assets,
|
|
||||||
test_component_structure
|
|
||||||
]
|
|
||||||
|
|
||||||
passed = 0
|
|
||||||
failed = 0
|
|
||||||
|
|
||||||
for test in tests:
|
|
||||||
try:
|
|
||||||
if test():
|
|
||||||
passed += 1
|
|
||||||
else:
|
|
||||||
failed += 1
|
|
||||||
except Exception as e:
|
|
||||||
print(f"❌ Test failed with error: {e}")
|
|
||||||
failed += 1
|
|
||||||
print()
|
|
||||||
|
|
||||||
print("=" * 50)
|
|
||||||
print(f"📊 Test Results: {passed} passed, {failed} failed")
|
|
||||||
|
|
||||||
if failed == 0:
|
|
||||||
print("🎉 Mobile header visibility fix is complete!")
|
|
||||||
print("📱 The MobileHeader should now be visible when switching to mobile mode.")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print("⚠️ Some tests failed. Please review the implementation.")
|
|
||||||
return False
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
success = main()
|
|
||||||
sys.exit(0 if success else 1)
|
|
||||||
@@ -1,257 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Test script to verify mobile responsive functionality for eveai_chat_client
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
def test_files_exist():
|
|
||||||
"""Test that all required files exist"""
|
|
||||||
print("Testing file existence...")
|
|
||||||
|
|
||||||
files_to_check = [
|
|
||||||
# Vue components
|
|
||||||
'eveai_chat_client/static/assets/vue-components/MobileHeader.vue',
|
|
||||||
'eveai_chat_client/static/assets/vue-components/SideBar.vue',
|
|
||||||
'eveai_chat_client/static/assets/vue-components/index.js',
|
|
||||||
|
|
||||||
# Templates
|
|
||||||
'eveai_chat_client/templates/base.html',
|
|
||||||
'eveai_chat_client/templates/scripts.html',
|
|
||||||
|
|
||||||
# CSS
|
|
||||||
'eveai_chat_client/static/assets/css/chat.css',
|
|
||||||
|
|
||||||
# Source files
|
|
||||||
'frontend_src/js/chat-client.js',
|
|
||||||
|
|
||||||
# Built files
|
|
||||||
'eveai_chat_client/static/dist/chat-client.js',
|
|
||||||
'eveai_chat_client/static/dist/chat-client.css',
|
|
||||||
]
|
|
||||||
|
|
||||||
missing_files = []
|
|
||||||
for file_path in files_to_check:
|
|
||||||
if not os.path.exists(file_path):
|
|
||||||
missing_files.append(file_path)
|
|
||||||
else:
|
|
||||||
print(f"✓ {file_path}")
|
|
||||||
|
|
||||||
if missing_files:
|
|
||||||
print(f"\n❌ Missing files:")
|
|
||||||
for file_path in missing_files:
|
|
||||||
print(f" - {file_path}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
print("✅ All required files exist")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def test_mobile_header_component():
|
|
||||||
"""Test MobileHeader component structure"""
|
|
||||||
print("\nTesting MobileHeader component...")
|
|
||||||
|
|
||||||
mobile_header_path = 'eveai_chat_client/static/assets/vue-components/MobileHeader.vue'
|
|
||||||
|
|
||||||
with open(mobile_header_path, 'r') as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
# Check for required elements
|
|
||||||
required_elements = [
|
|
||||||
'class="mobile-header"',
|
|
||||||
'SideBarLogo',
|
|
||||||
'LanguageSelector',
|
|
||||||
'@media (min-width: 769px)',
|
|
||||||
'display: none'
|
|
||||||
]
|
|
||||||
|
|
||||||
missing_elements = []
|
|
||||||
for element in required_elements:
|
|
||||||
if element not in content:
|
|
||||||
missing_elements.append(element)
|
|
||||||
else:
|
|
||||||
print(f"✓ Found: {element}")
|
|
||||||
|
|
||||||
if missing_elements:
|
|
||||||
print(f"❌ Missing elements in MobileHeader:")
|
|
||||||
for element in missing_elements:
|
|
||||||
print(f" - {element}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
print("✅ MobileHeader component structure is correct")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def test_css_responsive_rules():
|
|
||||||
"""Test CSS responsive rules"""
|
|
||||||
print("\nTesting CSS responsive rules...")
|
|
||||||
|
|
||||||
css_path = 'eveai_chat_client/static/assets/css/chat.css'
|
|
||||||
|
|
||||||
with open(css_path, 'r') as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
# Check for required CSS rules
|
|
||||||
required_rules = [
|
|
||||||
'#mobile-header-container',
|
|
||||||
'#sidebar-container',
|
|
||||||
'@media (max-width: 768px)',
|
|
||||||
'flex-direction: column',
|
|
||||||
'display: none',
|
|
||||||
'display: block'
|
|
||||||
]
|
|
||||||
|
|
||||||
missing_rules = []
|
|
||||||
for rule in required_rules:
|
|
||||||
if rule not in content:
|
|
||||||
missing_rules.append(rule)
|
|
||||||
else:
|
|
||||||
print(f"✓ Found: {rule}")
|
|
||||||
|
|
||||||
if missing_rules:
|
|
||||||
print(f"❌ Missing CSS rules:")
|
|
||||||
for rule in missing_rules:
|
|
||||||
print(f" - {rule}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
print("✅ CSS responsive rules are correct")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def test_base_html_structure():
|
|
||||||
"""Test base.html structure"""
|
|
||||||
print("\nTesting base.html structure...")
|
|
||||||
|
|
||||||
base_html_path = 'eveai_chat_client/templates/base.html'
|
|
||||||
|
|
||||||
with open(base_html_path, 'r') as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
# Check for required elements
|
|
||||||
required_elements = [
|
|
||||||
'id="mobile-header-container"',
|
|
||||||
'id="sidebar-container"',
|
|
||||||
'class="content-area"'
|
|
||||||
]
|
|
||||||
|
|
||||||
missing_elements = []
|
|
||||||
for element in required_elements:
|
|
||||||
if element not in content:
|
|
||||||
missing_elements.append(element)
|
|
||||||
else:
|
|
||||||
print(f"✓ Found: {element}")
|
|
||||||
|
|
||||||
if missing_elements:
|
|
||||||
print(f"❌ Missing elements in base.html:")
|
|
||||||
for element in missing_elements:
|
|
||||||
print(f" - {element}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
print("✅ base.html structure is correct")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def test_component_exports():
|
|
||||||
"""Test component exports"""
|
|
||||||
print("\nTesting component exports...")
|
|
||||||
|
|
||||||
index_js_path = 'eveai_chat_client/static/assets/vue-components/index.js'
|
|
||||||
|
|
||||||
with open(index_js_path, 'r') as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
# Check for required exports
|
|
||||||
required_exports = [
|
|
||||||
'export { default as SideBar }',
|
|
||||||
'export { default as MobileHeader }'
|
|
||||||
]
|
|
||||||
|
|
||||||
missing_exports = []
|
|
||||||
for export in required_exports:
|
|
||||||
if export not in content:
|
|
||||||
missing_exports.append(export)
|
|
||||||
else:
|
|
||||||
print(f"✓ Found: {export}")
|
|
||||||
|
|
||||||
if missing_exports:
|
|
||||||
print(f"❌ Missing exports:")
|
|
||||||
for export in missing_exports:
|
|
||||||
print(f" - {export}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
print("✅ Component exports are correct")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def test_chat_client_js():
|
|
||||||
"""Test chat-client.js mounting logic"""
|
|
||||||
print("\nTesting chat-client.js mounting logic...")
|
|
||||||
|
|
||||||
chat_client_path = 'frontend_src/js/chat-client.js'
|
|
||||||
|
|
||||||
with open(chat_client_path, 'r') as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
# Check for required mounting logic
|
|
||||||
required_elements = [
|
|
||||||
'getElementById(\'sidebar-container\')',
|
|
||||||
'getElementById(\'mobile-header-container\')',
|
|
||||||
'Components.SideBar',
|
|
||||||
'Components.MobileHeader',
|
|
||||||
'mount(\'#sidebar-container\')',
|
|
||||||
'mount(\'#mobile-header-container\')'
|
|
||||||
]
|
|
||||||
|
|
||||||
missing_elements = []
|
|
||||||
for element in required_elements:
|
|
||||||
if element not in content:
|
|
||||||
missing_elements.append(element)
|
|
||||||
else:
|
|
||||||
print(f"✓ Found: {element}")
|
|
||||||
|
|
||||||
if missing_elements:
|
|
||||||
print(f"❌ Missing elements in chat-client.js:")
|
|
||||||
for element in missing_elements:
|
|
||||||
print(f" - {element}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
print("✅ chat-client.js mounting logic is correct")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def main():
|
|
||||||
"""Run all tests"""
|
|
||||||
print("🧪 Testing Mobile Responsive Implementation")
|
|
||||||
print("=" * 50)
|
|
||||||
|
|
||||||
tests = [
|
|
||||||
test_files_exist,
|
|
||||||
test_mobile_header_component,
|
|
||||||
test_css_responsive_rules,
|
|
||||||
test_base_html_structure,
|
|
||||||
test_component_exports,
|
|
||||||
test_chat_client_js
|
|
||||||
]
|
|
||||||
|
|
||||||
passed = 0
|
|
||||||
failed = 0
|
|
||||||
|
|
||||||
for test in tests:
|
|
||||||
try:
|
|
||||||
if test():
|
|
||||||
passed += 1
|
|
||||||
else:
|
|
||||||
failed += 1
|
|
||||||
except Exception as e:
|
|
||||||
print(f"❌ Test failed with error: {e}")
|
|
||||||
failed += 1
|
|
||||||
print()
|
|
||||||
|
|
||||||
print("=" * 50)
|
|
||||||
print(f"📊 Test Results: {passed} passed, {failed} failed")
|
|
||||||
|
|
||||||
if failed == 0:
|
|
||||||
print("🎉 All tests passed! Mobile responsive implementation is complete.")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print("⚠️ Some tests failed. Please review the implementation.")
|
|
||||||
return False
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
success = main()
|
|
||||||
sys.exit(0 if success else 1)
|
|
||||||
Reference in New Issue
Block a user