Fix AI tab save: dedicated AJAX endpoint /save-ai
Instead of relying on the native HTML form (which couldn't reliably isolate AI fields), the IA tab now uses an AJAX call identical to save-per-type. The new /admin/bot-config/save-ai endpoint only reads and merges AI fields into config_json, preserving menus/flows. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
5afa846b4e
commit
bb4b5dab10
@@ -3747,7 +3747,7 @@ HTML;
|
||||
<strong>Requiere bot_type = hybrid y proveedor de IA configurado.</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top:14px"><button type="submit" class="btn-primary">💾 Guardar IA</button></div>
|
||||
<div style="margin-top:14px"><button type="button" id="saveAiBtn" onclick="saveAiConfig()" class="btn-primary">💾 Guardar IA</button></div>
|
||||
</div>
|
||||
|
||||
<!-- ─── GENERAL ──────────────────────────────────────────────────────── -->
|
||||
@@ -3842,6 +3842,41 @@ function savePerType() {
|
||||
});
|
||||
}
|
||||
|
||||
function saveAiConfig() {
|
||||
const cid = document.querySelector('input[name="company_id"]').value;
|
||||
const fd = new FormData();
|
||||
fd.set('company_id', cid);
|
||||
const qs = sel => document.querySelector(sel);
|
||||
fd.set('ai_provider', qs('select[name="ai_provider"]')?.value || '');
|
||||
fd.set('ai_model', qs('select[name="ai_model"]')?.value || 'gpt-4o-mini');
|
||||
fd.set('ai_temperature', qs('input[name="ai_temperature"]')?.value || '0.7');
|
||||
fd.set('ai_prompt', qs('textarea[name="ai_prompt"]')?.value || '');
|
||||
fd.set('gemini_model', qs('select[name="gemini_model"]')?.value || '');
|
||||
fd.set('claude_model', qs('select[name="claude_model"]')?.value || '');
|
||||
const oKey = qs('input[name="openai_api_key"]')?.value || '';
|
||||
const gKey = qs('input[name="gemini_api_key"]')?.value || '';
|
||||
const cKey = qs('input[name="claude_api_key"]')?.value || '';
|
||||
if (oKey) fd.set('openai_api_key', oKey);
|
||||
if (gKey) fd.set('gemini_api_key', gKey);
|
||||
if (cKey) fd.set('claude_api_key', cKey);
|
||||
if (qs('input[name="ai_for_media"]')?.checked) fd.set('ai_for_media', '1');
|
||||
if (qs('input[name="nlu"]')?.checked) fd.set('nlu', '1');
|
||||
|
||||
const btn = document.getElementById('saveAiBtn');
|
||||
if (btn) { btn.textContent = 'Guardando...'; btn.disabled = true; }
|
||||
fetch('/admin/bot-config/save-ai', { method: 'POST', body: fd })
|
||||
.then(r => r.json())
|
||||
.then(d => {
|
||||
if (btn) { btn.textContent = '💾 Guardar IA'; btn.disabled = false; }
|
||||
if (d.ok) { btn.textContent = '✅ Guardado'; setTimeout(() => { btn.textContent = '💾 Guardar IA'; }, 2000); }
|
||||
else alert('❌ Error al guardar: ' + JSON.stringify(d));
|
||||
})
|
||||
.catch(e => {
|
||||
if (btn) { btn.textContent = '💾 Guardar IA'; btn.disabled = false; }
|
||||
alert('❌ Error de red: ' + e.message);
|
||||
});
|
||||
}
|
||||
|
||||
function switchTab(tab, btn) {
|
||||
document.querySelectorAll('.tab-content').forEach(t => t.classList.remove('active'));
|
||||
document.querySelectorAll('.tab-btn').forEach(t => t.classList.remove('active'));
|
||||
|
||||
Reference in New Issue
Block a user