From 601169525e06bad433ab9cc696d5607191ac60db Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Tue, 30 Jun 2026 19:16:36 -0500 Subject: [PATCH] fix: dedicated save button for categories + preserve all extra DB keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace onchange+AJAX with explicit button 'đź’ľ Guardar categorĂ­as' that shows alert on success/error for clear feedback - Get company_id from DOM (not COMPANY_ID JS const from another script block) - Main form save now preserves welcome_menu and per_type from DB even if POST is truncated by max_input_vars - Restore welcome_menu='welcome_msg' in DB (was wiped by a previous save) Co-Authored-By: Claude Sonnet 4.6 --- admin/DashboardController.php | 32 +++++++++++++++++--------------- public/index.php | 19 +++++++++++++++---- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/admin/DashboardController.php b/admin/DashboardController.php index efdf6b3..8a60c5a 100644 --- a/admin/DashboardController.php +++ b/admin/DashboardController.php @@ -2917,7 +2917,7 @@ HTML;
{$label}
- {$opts}
MenĂş que se muestra cuando el usuario escribe por primera vez o sin contexto activo
@@ -3347,6 +3347,7 @@ HTML;
👥 Configuración por Categoría

Define qué menú de bienvenida ve cada categoría de usuario cuando escribe por primera vez o sin contexto activo.

{$categoryTabHtml} +
@@ -3492,23 +3493,24 @@ const CONFIG = {$botConfigJson}; const ENDPOINTS = {$botEndpointsJson}; function savePerType() { - const fd = new FormData(); - fd.set('company_id', COMPANY_ID); - [1, 2, 3].forEach(cat => { - const sel = document.querySelector('select[name="per_type_menu[' + cat + ']"]'); + const cid = document.querySelector('input[name="company_id"]').value; + const fd = new FormData(); + fd.set('company_id', cid); + [1, 2, 3].forEach(function(cat) { + var sel = document.querySelector('[name="per_type_menu[' + cat + ']"]'); if (sel) fd.append('per_type_menu[' + cat + ']', sel.value); }); + var btn = document.getElementById('savePerTypeBtn'); + if (btn) { btn.textContent = 'Guardando...'; btn.disabled = true; } fetch('/admin/bot-config/save-per-type', { method: 'POST', body: fd }) - .then(r => r.json()) - .then(d => { - if (d.ok) { - const t = document.createElement('div'); - t.className = 'toast toast-success'; - t.textContent = '✅ Categorías guardadas'; - t.style.cssText = 'position:fixed;bottom:24px;right:24px;z-index:9999;padding:10px 18px;border-radius:8px;background:#166534;color:#fff;font-size:13px;font-weight:600'; - document.body.appendChild(t); - setTimeout(() => t.remove(), 2500); - } + .then(function(r) { return r.json(); }) + .then(function(d) { + if (btn) { btn.textContent = '💾 Guardar categorías'; btn.disabled = false; } + alert(d.ok ? '✅ Categorías guardadas correctamente.' : '❌ Error al guardar: ' + JSON.stringify(d)); + }) + .catch(function(e) { + if (btn) { btn.textContent = '💾 Guardar categorías'; btn.disabled = false; } + alert('❌ Error de red: ' + e.message); }); } diff --git a/public/index.php b/public/index.php index 907f682..c747627 100644 --- a/public/index.php +++ b/public/index.php @@ -557,10 +557,21 @@ $routes = [ $approvalWebhook = trim($_POST['approval_webhook'] ?? ''); if ($approvalWebhook !== '') $config['approval_webhook'] = $approvalWebhook; $welcomeMenu = trim($_POST['welcome_menu'] ?? ''); - if ($welcomeMenu !== '') { - $config['welcome_menu'] = $welcomeMenu; - } elseif (!empty($existingConfig['welcome_menu'])) { - $config['welcome_menu'] = $existingConfig['welcome_menu']; + if ($welcomeMenu !== '') $config['welcome_menu'] = $welcomeMenu; + + // Preserve any DB keys the form doesn't explicitly manage (welcome_menu, per_type, etc.) + $formManagedKeys = ['commands', 'menus', 'flows', 'ai_prompt', 'ai_model', 'ai_temperature', + 'ai_provider', 'openai_api_key', 'gemini_api_key', 'gemini_model', + 'ai_for_media', 'greeting', 'fallback', 'approval_webhook', + 'ignore_prefixes', 'welcome_menu', 'per_type']; + foreach ($existingConfig as $k => $v) { + if (!in_array($k, $formManagedKeys, true) && !isset($config[$k])) { + $config[$k] = $v; + } + // Also preserve managed keys that POST didn't provide (e.g. truncated by max_input_vars) + if (in_array($k, ['welcome_menu', 'per_type'], true) && !isset($config[$k])) { + $config[$k] = $v; + } } CompanyRepository::save(['id' => $companyId, 'config_json' => json_encode($config, JSON_UNESCAPED_UNICODE)]);