/**
* 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 = ''
+ '
'
+ ''
+ '
'
+ '
'
+ '
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();
}
})();