/** * stenchatbot.js - Floating chat widget for Sten ERP Engine */ (function() { 'use strict'; var chatUrl = (typeof DOL_URL_ROOT !== 'undefined' ? DOL_URL_ROOT : '/erp/engine') + '/custom/stenchatbot/chat.php'; var currentConvId = 0; var isOpen = false; var isProcessing = false; function init() { createWidget(); bindEvents(); } function createWidget() { // FAB button var fab = document.createElement('button'); fab.id = 'stenchatbot-fab'; fab.innerHTML = ''; fab.title = 'Asistente'; document.body.appendChild(fab); // Panel var panel = document.createElement('div'); panel.id = 'stenchatbot-panel'; panel.innerHTML = '' + '
' + '
Asistente
' + '
' + '' + '' + '
' + '
' + '
' + '
' + '
' + '
Hola! Soy tu asistente de Sten ERP Engine.
Puedo consultarte facturas, clientes, pedidos, cuentas bancarias y más.
' + '
' + '
' + '
' + '
' + '' + '' + '
'; document.body.appendChild(panel); } function bindEvents() { document.getElementById('stenchatbot-fab').addEventListener('click', togglePanel); document.getElementById('scb-close').addEventListener('click', closePanel); document.getElementById('scb-new-chat').addEventListener('click', newChat); document.getElementById('scb-send').addEventListener('click', sendMessage); document.getElementById('scb-input').addEventListener('keydown', function(e) { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); } }); } function togglePanel() { var panel = document.getElementById('stenchatbot-panel'); isOpen = !isOpen; if (isOpen) { panel.classList.add('open'); document.getElementById('scb-input').focus(); } else { panel.classList.remove('open'); } } function closePanel() { isOpen = false; document.getElementById('stenchatbot-panel').classList.remove('open'); } function newChat() { currentConvId = 0; var messages = document.getElementById('scb-messages'); messages.innerHTML = '' + '
' + '
' + '
Hola! Soy tu asistente de Sten ERP Engine.
Puedo consultarte facturas, clientes, pedidos, cuentas bancarias y más.
' + '
'; } function sendMessage() { var input = document.getElementById('scb-input'); var message = input.value.trim(); if (!message || isProcessing) return; isProcessing = true; input.value = ''; document.getElementById('scb-send').disabled = true; // Remove welcome if present var welcome = document.querySelector('.scb-welcome'); if (welcome) welcome.remove(); // Add user message appendMessage('user', message); // Show typing document.getElementById('scb-typing').classList.add('active'); scrollToBottom(); // Send to backend var xhr = new XMLHttpRequest(); xhr.open('POST', chatUrl + '?action=send', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.onload = function() { document.getElementById('scb-typing').classList.remove('active'); isProcessing = false; document.getElementById('scb-send').disabled = false; if (xhr.status === 200) { try { var data = JSON.parse(xhr.responseText); if (data.error) { appendMessage('system', 'Error: ' + data.error); } else { currentConvId = data.conversation_id; if (data.tool_calls && data.tool_calls.length > 0) { data.tool_calls.forEach(function(tc) { appendMessage('tool', tc.name + ': ' + tc.result.substring(0, 200)); }); } appendMessage('assistant', data.response); } } catch(e) { appendMessage('system', 'Error al procesar respuesta'); } } else { appendMessage('system', 'Error de conexión (' + xhr.status + ')'); } scrollToBottom(); }; xhr.onerror = function() { document.getElementById('scb-typing').classList.remove('active'); isProcessing = false; document.getElementById('scb-send').disabled = false; appendMessage('system', 'Error de red'); }; xhr.send('message=' + encodeURIComponent(message) + '&conversation_id=' + currentConvId); } function appendMessage(role, content) { var messages = document.getElementById('scb-messages'); var div = document.createElement('div'); div.className = 'scb-msg scb-msg-' + role; div.textContent = content; messages.appendChild(div); } function scrollToBottom() { var messages = document.getElementById('scb-messages'); messages.scrollTop = messages.scrollHeight; } // Auto-init if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();