fix: dedicated save button for categories + preserve all extra DB keys
- 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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
ae5b7266d4
commit
601169525e
@@ -2917,7 +2917,7 @@ HTML;
|
||||
<div style="font-weight:700;font-size:13px;color:#0b3d91;margin-bottom:12px">{$label}</div>
|
||||
<div class="form-group" style="margin-bottom:0">
|
||||
<label>Menú de bienvenida (greeting menu)</label>
|
||||
<select name="per_type_menu[{$cat}]" onchange="savePerType()" style="width:100%;padding:9px 12px;border:1px solid #e2e5ea;border-radius:8px;font-size:13px">
|
||||
<select name="per_type_menu[{$cat}]" style="width:100%;padding:9px 12px;border:1px solid #e2e5ea;border-radius:8px;font-size:13px">
|
||||
{$opts}
|
||||
</select>
|
||||
<div style="font-size:11px;color:#7a8291;margin-top:4px">Menú que se muestra cuando el usuario escribe por primera vez o sin contexto activo</div>
|
||||
@@ -3347,6 +3347,7 @@ HTML;
|
||||
<div class="card-h">👥 Configuración por Categoría</div>
|
||||
<p style="font-size:12px;color:#7a8291;margin-bottom:16px">Define qué menú de bienvenida ve cada categoría de usuario cuando escribe por primera vez o sin contexto activo.</p>
|
||||
{$categoryTabHtml}
|
||||
<button type="button" id="savePerTypeBtn" onclick="savePerType()" class="btn-primary" style="margin-top:8px">💾 Guardar categorías</button>
|
||||
</div>
|
||||
|
||||
<!-- ─── AI ───────────────────────────────────────────────────────────── -->
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+15
-4
@@ -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)]);
|
||||
|
||||
Reference in New Issue
Block a user