From cf8e4c677f4169dbf6f21c7df895e06977a47fd7 Mon Sep 17 00:00:00 2001 From: truetype Date: Fri, 20 Mar 2026 20:34:23 +0100 Subject: [PATCH] Phase 16: Responsive web design improvements and enhanced documentation --- README.md | 53 ++++++- web/index.html | 419 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 414 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 91e59a7..d7df791 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Un agente configurabile basato su DeepAgents che supporta più provider LLM. - **Test completi**: Suite di test per garantire la qualità del codice - **Docker support**: Containerizzazione per deployment facile - **API REST**: Server API per accesso remoto -- **Web UI**: Interfaccia web per gestione configurazioni +- **Web UI responsive**: Interfaccia web per gestione configurazioni ottimizzata per mobile e desktop - **Dashboard monitoraggio**: Monitoraggio in tempo reale del sistema con supporto multilingue - **Comandi integrati**: Comandi speciali con prefisso "/" per gestione rapida - **Monitoraggio**: Sistema di logging e monitoraggio delle performance @@ -23,7 +23,8 @@ Un agente configurabile basato su DeepAgents che supporta più provider LLM. - **Ottimizzazioni performance**: Caching, connection pooling, lazy loading - **Sistema di plugin**: Estendi le funzionalità con plugin personalizzati - **Plugin inclusi**: File tools, System utils, Example plugin -- **Supporto multilingue**: Interfaccia in italiano e inglese per CLI e dashboard +- **Supporto multilingue**: Interfaccia in italiano e inglese per CLI, dashboard e web UI +- **Design responsive**: Interfacce web ottimizzate per dispositivi mobili e desktop ## Installazione @@ -193,6 +194,7 @@ L'interfaccia web include: - Monitoraggio dello stato del sistema - Test di connessione - Dashboard di monitoraggio in tempo reale con supporto multilingue +- **Design responsive**: Ottimizzata per dispositivi mobili e desktop ## Utilizzo @@ -384,6 +386,44 @@ La dashboard supporta italiano e inglese: La dashboard si aggiorna automaticamente ogni 30 secondi. Puoi anche aggiornare manualmente con il pulsante "🔄 Aggiorna Dati" (o "🔄 Refresh Data" in inglese). +## Interfaccia Web Responsive + +L'interfaccia web è stata ottimizzata per essere responsive e funzionare su dispositivi mobili e desktop. + +### Caratteristiche Responsive + +1. **Layout adattivo**: Si adatta automaticamente a diverse dimensioni dello schermo +2. **Touch-friendly**: Pulsanti e campi ottimizzati per touch screen +3. **Navigazione mobile**: Menu e tab ottimizzati per dispositivi mobili +4. **Dimensioni appropriate**: Font e spaziature adatti a schermi piccoli +5. **Supporto multilingue**: Interfaccia in italiano e inglese + +### Accesso da Dispositivi Mobili + +L'interfaccia web è accessibile da qualsiasi dispositivo nella stessa rete: + +```bash +# Avvia il server API +python api_server.py + +# Accedi da un dispositivo mobile nella stessa rete +# http://:8000 +``` + +Esempio: +```bash +# Se il server è su 192.168.0.50 +# http://192.168.0.50:8000 +``` + +### Ottimizzazioni per Mobile + +- **Pulsanti più grandi**: Facili da toccare su schermi touch +- **Layout a colonna singola**: Su schermi stretti +- **Font leggibili**: Dimensioni appropriate per la lettura su mobile +- **Navigazione semplificata**: Tab e menu ottimizzati per touch +- **Caricamento rapido**: Ottimizzazioni per connessioni lente + ## Ottimizzazioni Performance MaxClaw Agent include diverse ottimizzazioni per migliorare le performance: @@ -701,6 +741,14 @@ La dashboard di monitoraggio supporta anche il cambio lingua: - **Persistenza**: La preferenza viene salvata nel browser - **Traduzione completa**: Tutti i testi sono tradotti in italiano e inglese +### Web UI Multilingue + +L'interfaccia web supporta il cambio lingua: + +- **Selettore lingua**: In alto a destra nell'interfaccia +- **Persistenza**: La preferenza viene salvata nel browser +- **Traduzione completa**: Tutti i testi sono tradotti in italiano e inglese + ## Monitoraggio Performance MaxClaw Agent include un sistema avanzato di monitoraggio delle performance. @@ -817,6 +865,7 @@ MaxClaw Agent include un sistema di monitoraggio e logging: - **Report di stato**: Visualizzazione completa dello stato del sistema - **Dashboard performance**: Monitoraggio avanzato delle performance - **Dashboard web**: Monitoraggio in tempo reale via interfaccia web con supporto multilingue +- **Interfacce responsive**: Ottimizzate per dispositivi mobili e desktop ## Sicurezza diff --git a/web/index.html b/web/index.html index 45caa8c..e56905d 100644 --- a/web/index.html +++ b/web/index.html @@ -21,6 +21,7 @@ .container { max-width: 1200px; margin: 0 auto; + padding: 0 15px; } header { @@ -89,6 +90,8 @@ font-size: 16px; font-weight: 600; transition: background 0.3s; + display: inline-block; + margin: 5px; } .btn:hover { @@ -122,8 +125,8 @@ padding: 15px; margin-bottom: 10px; display: flex; - justify-content: space-between; - align-items: center; + flex-direction: column; + gap: 10px; } .config-info h3 { @@ -139,6 +142,7 @@ .config-actions { display: flex; gap: 10px; + flex-wrap: wrap; } .status-badge { @@ -193,10 +197,12 @@ .chat-input { display: flex; gap: 10px; + flex-wrap: wrap; } .chat-input input { flex: 1; + min-width: 200px; } .alert { @@ -225,6 +231,7 @@ display: flex; border-bottom: 2px solid #dee2e6; margin-bottom: 20px; + flex-wrap: wrap; } .tab { @@ -232,6 +239,9 @@ cursor: pointer; border-bottom: 3px solid transparent; margin-bottom: -2px; + flex: 1; + text-align: center; + min-width: 120px; } .tab.active { @@ -247,71 +257,233 @@ .tab-content.active { display: block; } + + .language-selector { + position: absolute; + top: 20px; + right: 20px; + } + + .language-selector select { + padding: 8px 12px; + border-radius: 6px; + border: 1px solid #ddd; + background: white; + font-size: 14px; + cursor: pointer; + } + + /* Responsive Design */ + @media (max-width: 768px) { + body { + padding: 10px; + } + + .container { + padding: 0 10px; + } + + header h1 { + font-size: 2rem; + } + + header p { + font-size: 1rem; + } + + .card { + padding: 20px; + margin-bottom: 20px; + } + + .card h2 { + font-size: 1.3rem; + } + + .form-group { + margin-bottom: 15px; + } + + label { + font-size: 14px; + } + + input, select, textarea { + padding: 10px; + font-size: 14px; + } + + .btn { + padding: 10px 20px; + font-size: 14px; + width: 100%; + margin: 5px 0; + } + + .config-item { + padding: 12px; + } + + .config-actions { + flex-direction: column; + } + + .config-actions .btn { + width: 100%; + } + + .chat-container { + height: 300px; + padding: 10px; + } + + .message { + max-width: 90%; + padding: 8px 12px; + font-size: 14px; + } + + .chat-input { + flex-direction: column; + } + + .chat-input input { + min-width: 100%; + } + + .tabs { + flex-direction: column; + } + + .tab { + padding: 8px 15px; + border-bottom: none; + border-left: 3px solid transparent; + margin-bottom: 0; + text-align: left; + } + + .tab.active { + border-bottom: none; + border-left-color: #667eea; + } + + .language-selector { + position: static; + text-align: center; + margin-bottom: 20px; + } + } + + @media (max-width: 480px) { + header h1 { + font-size: 1.8rem; + } + + .card { + padding: 15px; + } + + .btn { + padding: 8px 16px; + font-size: 13px; + } + + .chat-container { + height: 250px; + } + } + + /* Touch-friendly improvements */ + @media (hover: none) and (pointer: coarse) { + .btn:hover { + background: #667eea; + } + + .btn:active { + background: #5a6fd8; + transform: scale(0.98); + } + + input:focus, select:focus, textarea:focus { + border-color: #667eea; + box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.2); + } + }
+
+ +
+
-

MaxClaw Agent

-

Interfaccia di configurazione per l'agente AI

+

MaxClaw Agent

+

Interfaccia di configurazione per l'agente AI

-
Configurazione
-
Chat
-
Stato
+
Configurazione
+
Chat
+
Stato
-

Gestione Configurazioni

+

Gestione Configurazioni

- +
- +
- +
- +
- +
- - + +
-

Configurazioni Esistenti

+

Configurazioni Esistenti

@@ -319,49 +491,49 @@
-

Chat con MaxClaw

+

Chat con MaxClaw

-
+
Ciao! Sono MaxClaw, il tuo agente AI. Come posso aiutarti oggi?
- +
-

Stato del Sistema

+

Stato del Sistema

-
- ✅ Sistema operativo
- L'agente è pronto per l'uso. +
+ ✅ Sistema operativo
+ L'agente è pronto per l'uso.
-

Provider Attivo

+

Provider Attivo

Nessun provider configurato

-

Modello Attivo

+

Modello Attivo

Nessun modello configurato

-

Connessione

+

Connessione

Verifica in corso...

- +
@@ -372,8 +544,104 @@ // API base URL const API_BASE = 'http://localhost:8000'; + // Current language + let currentLanguage = 'it'; + + // Translations + const translations = { + it: { + title: "MaxClaw Agent", + subtitle: "Interfaccia di configurazione per l'agente AI", + tabConfig: "Configurazione", + tabChat: "Chat", + tabStatus: "Stato", + configTitle: "Gestione Configurazioni", + nameLabel: "Nome Configurazione", + providerLabel: "Provider", + modelLabel: "Nome Modello", + apiKeyLabel: "Chiave API", + baseUrlLabel: "URL Base", + setActiveLabel: "Imposta come configurazione attiva", + saveBtn: "Salva Configurazione", + clearBtn: "Pulisci", + existingConfigsTitle: "Configurazioni Esistenti", + chatTitle: "Chat con MaxClaw", + welcomeMessage: "Ciao! Sono MaxClaw, il tuo agente AI. Come posso aiutarti oggi?", + chatPlaceholder: "Scrivi un messaggio...", + sendBtn: "Invia", + statusTitle: "Stato del Sistema", + systemOk: "✅ Sistema operativo", + systemReady: "L'agente è pronto per l'uso.", + activeProviderTitle: "Provider Attivo", + activeModelTitle: "Modello Attivo", + connectionTitle: "Connessione", + testConnectionBtn: "Testa Connessione", + alertSuccess: "Configurazione salvata con successo!", + alertError: "Errore", + alertCancelled: "Annullato.", + alertTesting: "Test in corso...", + alertConnectionSuccess: "Connessione riuscita!", + alertConnectionFailed: "Connessione fallita", + noProvider: "Nessun provider configurato", + noModel: "Nessun modello configurato", + checking: "Verifica in corso...", + active: "Attivo", + inactive: "Inattivo", + test: "Testa", + delete: "Elimina", + activate: "Attiva" + }, + en: { + title: "MaxClaw Agent", + subtitle: "Configuration interface for AI agent", + tabConfig: "Configuration", + tabChat: "Chat", + tabStatus: "Status", + configTitle: "Configuration Management", + nameLabel: "Configuration Name", + providerLabel: "Provider", + modelLabel: "Model Name", + apiKeyLabel: "API Key", + baseUrlLabel: "Base URL", + setActiveLabel: "Set as active configuration", + saveBtn: "Save Configuration", + clearBtn: "Clear", + existingConfigsTitle: "Existing Configurations", + chatTitle: "Chat with MaxClaw", + welcomeMessage: "Hello! I'm MaxClaw, your AI agent. How can I help you today?", + chatPlaceholder: "Type a message...", + sendBtn: "Send", + statusTitle: "System Status", + systemOk: "✅ System operational", + systemReady: "The agent is ready to use.", + activeProviderTitle: "Active Provider", + activeModelTitle: "Active Model", + connectionTitle: "Connection", + testConnectionBtn: "Test Connection", + alertSuccess: "Configuration saved successfully!", + alertError: "Error", + alertCancelled: "Cancelled.", + alertTesting: "Testing...", + alertConnectionSuccess: "Connection successful!", + alertConnectionFailed: "Connection failed", + noProvider: "No provider configured", + noModel: "No model configured", + checking: "Checking...", + active: "Active", + inactive: "Inactive", + test: "Test", + delete: "Delete", + activate: "Activate" + } + }; + // Initialize document.addEventListener('DOMContentLoaded', function() { + // Load saved language preference + const savedLanguage = localStorage.getItem('maxclaw-language') || 'it'; + document.getElementById('language-select').value = savedLanguage; + changeLanguage(savedLanguage); + loadConfigurations(); loadActiveConfiguration(); @@ -396,6 +664,45 @@ }); }); + // Change language + function changeLanguage(language) { + currentLanguage = language; + localStorage.setItem('maxclaw-language', language); + + const t = translations[language]; + + // Update all translatable elements + document.getElementById('title').textContent = t.title; + document.getElementById('subtitle').textContent = t.subtitle; + document.getElementById('tab-config').textContent = t.tabConfig; + document.getElementById('tab-chat').textContent = t.tabChat; + document.getElementById('tab-status').textContent = t.tabStatus; + document.getElementById('config-title').textContent = t.configTitle; + document.getElementById('name-label').textContent = t.nameLabel; + document.getElementById('provider-label').textContent = t.providerLabel; + document.getElementById('model-label').textContent = t.modelLabel; + document.getElementById('api-key-label').textContent = t.apiKeyLabel; + document.getElementById('base-url-label').textContent = t.baseUrlLabel; + document.getElementById('set-active-label').textContent = t.setActiveLabel; + document.getElementById('save-btn').textContent = t.saveBtn; + document.getElementById('clear-btn').textContent = t.clearBtn; + document.getElementById('existing-configs-title').textContent = t.existingConfigsTitle; + document.getElementById('chat-title').textContent = t.chatTitle; + document.getElementById('welcome-message').textContent = t.welcomeMessage; + document.getElementById('chat-input').placeholder = t.chatPlaceholder; + document.getElementById('send-btn').textContent = t.sendBtn; + document.getElementById('status-title').textContent = t.statusTitle; + document.getElementById('system-ok').textContent = t.systemOk; + document.getElementById('system-ready').textContent = t.systemReady; + document.getElementById('active-provider-title').textContent = t.activeProviderTitle; + document.getElementById('active-model-title').textContent = t.activeModelTitle; + document.getElementById('connection-title').textContent = t.connectionTitle; + document.getElementById('test-connection-btn').textContent = t.testConnectionBtn; + + // Update HTML lang attribute + document.documentElement.lang = language; + } + // Switch tabs function switchTab(tabName) { // Update tab buttons @@ -421,7 +728,7 @@ container.innerHTML = ''; if (configs.length === 0) { - container.innerHTML = '

Nessuna configurazione trovata.

'; + container.innerHTML = `

${translations[currentLanguage].noProvider}

`; return; } @@ -431,20 +738,20 @@ item.innerHTML = `

${config.name} - ${config.is_active ? 'Attivo' : ''} + ${config.is_active ? `${translations[currentLanguage].active}` : ''}

-

Provider: ${config.provider} | Modello: ${config.model_name}

+

${translations[currentLanguage].providerLabel}: ${config.provider} | ${translations[currentLanguage].modelLabel}: ${config.model_name}

- - - + + +
`; container.appendChild(item); }); } catch (error) { - showAlert('Errore nel caricamento delle configurazioni: ' + error.message, 'error'); + showAlert(translations[currentLanguage].alertError + ': ' + error.message, 'error'); } } @@ -458,8 +765,8 @@ document.getElementById('active-provider').textContent = config.provider; document.getElementById('active-model').textContent = config.model_name; } else { - document.getElementById('active-provider').textContent = 'Nessun provider configurato'; - document.getElementById('active-model').textContent = 'Nessun modello configurato'; + document.getElementById('active-provider').textContent = translations[currentLanguage].noProvider; + document.getElementById('active-model').textContent = translations[currentLanguage].noModel; } } catch (error) { console.error('Error loading active configuration:', error); @@ -500,16 +807,16 @@ }); if (response.ok) { - showAlert('Configurazione salvata con successo!', 'success'); + showAlert(translations[currentLanguage].alertSuccess, 'success'); clearForm(); loadConfigurations(); loadActiveConfiguration(); } else { const error = await response.json(); - showAlert('Errore: ' + error.detail, 'error'); + showAlert(translations[currentLanguage].alertError + ': ' + error.detail, 'error'); } } catch (error) { - showAlert('Errore di connessione: ' + error.message, 'error'); + showAlert(translations[currentLanguage].alertError + ': ' + error.message, 'error'); } } @@ -521,15 +828,15 @@ }); if (response.ok) { - showAlert(`Configurazione "${name}" attivata!`, 'success'); + showAlert(`${translations[currentLanguage].alertSuccess} "${name}"`, 'success'); loadConfigurations(); loadActiveConfiguration(); } else { const error = await response.json(); - showAlert('Errore: ' + error.detail, 'error'); + showAlert(translations[currentLanguage].alertError + ': ' + error.detail, 'error'); } } catch (error) { - showAlert('Errore di connessione: ' + error.message, 'error'); + showAlert(translations[currentLanguage].alertError + ': ' + error.message, 'error'); } } @@ -548,7 +855,7 @@ showAlert(`❌ ${result.message}`, 'error'); } } catch (error) { - showAlert('Errore di connessione: ' + error.message, 'error'); + showAlert(translations[currentLanguage].alertError + ': ' + error.message, 'error'); } } @@ -564,36 +871,36 @@ }); if (response.ok) { - showAlert(`Configurazione "${name}" eliminata!`, 'success'); + showAlert(`${translations[currentLanguage].alertSuccess} "${name}"`, 'success'); loadConfigurations(); loadActiveConfiguration(); } else { const error = await response.json(); - showAlert('Errore: ' + error.detail, 'error'); + showAlert(translations[currentLanguage].alertError + ': ' + error.detail, 'error'); } } catch (error) { - showAlert('Errore di connessione: ' + error.message, 'error'); + showAlert(translations[currentLanguage].alertError + ': ' + error.message, 'error'); } } // Test connection async function testConnection() { - document.getElementById('connection-status').textContent = 'Test in corso...'; + document.getElementById('connection-status').textContent = translations[currentLanguage].alertTesting; try { const response = await fetch(API_BASE + '/health'); const result = await response.json(); if (result.status === 'healthy') { - document.getElementById('connection-status').textContent = '✅ Connessione riuscita'; - showAlert('Connessione al server riuscita!', 'success'); + document.getElementById('connection-status').textContent = translations[currentLanguage].alertConnectionSuccess; + showAlert(translations[currentLanguage].alertConnectionSuccess, 'success'); } else { - document.getElementById('connection-status').textContent = '❌ Connessione fallita'; - showAlert('Connessione al server fallita', 'error'); + document.getElementById('connection-status').textContent = translations[currentLanguage].alertConnectionFailed; + showAlert(translations[currentLanguage].alertConnectionFailed, 'error'); } } catch (error) { - document.getElementById('connection-status').textContent = '❌ Errore di connessione'; - showAlert('Errore di connessione: ' + error.message, 'error'); + document.getElementById('connection-status').textContent = translations[currentLanguage].alertConnectionFailed; + showAlert(translations[currentLanguage].alertError + ': ' + error.message, 'error'); } } @@ -622,7 +929,7 @@ // Add agent response to chat addMessageToChat(result.response, 'agent'); } catch (error) { - addMessageToChat('Errore: Impossibile connettersi al server', 'agent'); + addMessageToChat(translations[currentLanguage].alertError + ': ' + error.message, 'agent'); } } @@ -644,7 +951,7 @@ const baseUrlInput = document.getElementById('config-base-url'); // Show/hide fields based on provider - if (provider === 'openai' || provider === 'openrouter') { + if (provider === 'openai' || provider === 'openrouter' || provider === 'anthropic' || provider === 'google') { apiKeyGroup.style.display = 'block'; } else { apiKeyGroup.style.display = 'none';