// frontend/static/js/main.js // Estado global let currentProfile = null; let currentGroup = null; // Estilos comunes const STYLES = { editableInput: "mt-1 block w-full rounded-md border-2 border-gray-300 bg-green-50 px-3 py-2 shadow-sm focus:border-indigo-500 focus:ring-indigo-500", readonlyInput: "mt-1 block w-full rounded-md border-2 border-gray-200 bg-gray-100 px-3 py-2 shadow-sm", button: "px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600", buttonSecondary: "px-4 py-2 bg-gray-200 text-gray-800 rounded-md hover:bg-gray-300" }; // Inicialización de la aplicación async function initializeApp() { try { console.log('Initializing application...'); // Cargar perfiles const profiles = await apiRequest('/profiles'); console.log('Profiles loaded:', profiles); // Obtener último perfil usado const lastProfileId = localStorage.getItem('lastProfileId') || 'default'; console.log('Last profile ID:', lastProfileId); // Actualizar selector de perfiles updateProfileSelector(profiles); // Seleccionar el último perfil usado const selectedProfile = profiles.find(p => p.id === lastProfileId) || profiles[0]; if (selectedProfile) { console.log('Selecting profile:', selectedProfile.id); await selectProfile(selectedProfile.id); } // Restaurar último estado await restoreLastState(); } catch (error) { console.error('Error initializing application:', error); showError('Error initializing application'); } } // Funciones de API async function apiRequest(endpoint, options = {}) { try { const response = await fetch(`/api${endpoint}`, { ...options, headers: { 'Content-Type': 'application/json', ...options.headers } }); if (!response.ok) { const error = await response.json(); throw new Error(error.error || 'API request error'); } return await response.json(); } catch (error) { console.error('API Error:', error); showError(error.message); throw error; } } // Funciones de gestión de perfiles async function selectProfile(profileId) { try { console.log('Selecting profile:', profileId); // Cargar perfil currentProfile = await apiRequest(`/profiles/${profileId}`); // Guardar en localStorage localStorage.setItem('lastProfileId', profileId); console.log('Profile ID saved:', profileId); // Actualizar UI updateProfileSelector([currentProfile]); updateProfileDisplay(); return currentProfile; } catch (error) { console.error('Error selecting profile:', error); showError('Error loading profile'); throw error; } } function updateProfileSelector(profiles) { const select = document.getElementById('profileSelect'); if (!select) return; const lastProfileId = localStorage.getItem('lastProfileId') || 'default'; select.innerHTML = profiles.map(profile => ` <option value="${profile.id}" ${profile.id === lastProfileId ? 'selected' : ''}> ${profile.name} </option> `).join(''); } function updateProfileDisplay() { const container = document.getElementById('profileConfig'); if (!container || !currentProfile) return; container.innerHTML = ` <div class="space-y-4"> <div class="grid grid-cols-2 gap-4"> <div> <label class="block text-sm font-medium text-gray-700">Profile ID</label> <input type="text" value="${currentProfile.id}" readonly class="${STYLES.readonlyInput}"> </div> <div> <label class="block text-sm font-medium text-gray-700">Name</label> <input type="text" value="${currentProfile.name}" readonly class="${STYLES.readonlyInput}"> </div> </div> <div class="grid grid-cols-2 gap-4"> <div> <label class="block text-sm font-medium text-gray-700">Model</label> <input type="text" value="${currentProfile.llm_settings?.model || ''}" readonly class="${STYLES.readonlyInput}"> </div> <div> <label class="block text-sm font-medium text-gray-700">Temperature</label> <input type="text" value="${currentProfile.llm_settings?.temperature || ''}" readonly class="${STYLES.readonlyInput}"> </div> </div> </div> `; } // Funciones de estado async function restoreLastState() { try { // Restaurar último grupo seleccionado const lastGroupId = localStorage.getItem('lastGroupId'); if (lastGroupId) { const groupSelect = document.getElementById('groupSelect'); if (groupSelect) { groupSelect.value = lastGroupId; await handleGroupChange({ target: { value: lastGroupId } }); } } } catch (error) { console.error('Error restoring state:', error); } } // Funciones de utilidad UI function showError(message) { const output = document.getElementById('outputArea'); if (!output) return; const timestamp = new Date().toLocaleTimeString(); output.innerHTML += `\n[${timestamp}] ERROR: ${message}`; output.scrollTop = output.scrollHeight; } function showSuccess(message) { const output = document.getElementById('outputArea'); if (!output) return; const timestamp = new Date().toLocaleTimeString(); output.innerHTML += `\n[${timestamp}] SUCCESS: ${message}`; output.scrollTop = output.scrollHeight; } function clearOutput() { const output = document.getElementById('outputArea'); if (output) { output.innerHTML = ''; } } // Event Handlers async function handleProfileChange(event) { const profileId = event.target.value; if (profileId) { await selectProfile(profileId); } } async function handleGroupChange(event) { const groupId = event.target.value; if (groupId) { localStorage.setItem('lastGroupId', groupId); await selectGroup(groupId); } else { localStorage.removeItem('lastGroupId'); currentGroup = null; updateGroupDisplay(); } } // Modal Helpers function closeModal(button) { const modal = button.closest('.modal'); if (modal) { modal.remove(); } } // Error Handler Global window.addEventListener('unhandledrejection', function(event) { console.error('Unhandled promise rejection:', event.reason); showError('An unexpected error occurred'); }); // Exportar funciones globales window.showError = showError; window.showSuccess = showSuccess; window.closeModal = closeModal; window.STYLES = STYLES; // Inicializar cuando la página carga document.addEventListener('DOMContentLoaded', initializeApp);