feat: module toggles in POS config and Instance Manager

- Add GET/PUT /pos/api/config/modules endpoints in POS config_bp.py
- Update sidebar.js to filter nav items based on enabled modules
- Add Modules section to POS config.html with toggles for WhatsApp, Marketplace, MercadoLibre
- Add module load/save logic to POS config.js
- Preload modules in app-init.js for sidebar caching

- Add tenant module management to Instance Manager
  - get_tenant_modules / update_tenant_modules in tenant_service.py
  - GET/PUT /api/tenants/<id>/modules endpoints in tenants_bp.py
  - Add modules modal to manager index.html
  - Add module editing UI and logic to manager.js
  - Add toggle-switch CSS to manager.css
This commit is contained in:
2026-05-28 00:21:52 +00:00
parent 999591e248
commit 718fa06888
26 changed files with 2614 additions and 429 deletions

View File

@@ -689,6 +689,53 @@ const Config = (() => {
}
}
// -------------------------------------------------------------------------
// Modules / Integrations
// -------------------------------------------------------------------------
async function loadModules() {
try {
var res = await fetch(API + '/modules', { headers: headers() });
if (!res.ok) return;
var data = await res.json();
var cbWa = document.getElementById('cfg-module-whatsapp');
var cbMp = document.getElementById('cfg-module-marketplace');
var cbMeli = document.getElementById('cfg-module-meli');
if (cbWa) cbWa.checked = data.whatsapp !== false;
if (cbMp) cbMp.checked = data.marketplace !== false;
if (cbMeli) cbMeli.checked = data.meli !== false;
localStorage.setItem('pos_modules', JSON.stringify(data));
} catch (e) {
console.error('Config.loadModules:', e);
}
}
async function saveModules() {
var btn = event.target;
if (btn) { btn.disabled = true; btn.textContent = 'Guardando...'; }
try {
var data = {
whatsapp: document.getElementById('cfg-module-whatsapp').checked,
marketplace: document.getElementById('cfg-module-marketplace').checked,
meli: document.getElementById('cfg-module-meli').checked,
};
var res = await fetch(API + '/modules', {
method: 'PUT',
headers: headers(),
body: JSON.stringify(data)
});
if (!res.ok) {
var err = await res.json().catch(function() { return { error: res.statusText }; });
throw new Error(err.error || 'Save failed');
}
localStorage.setItem('pos_modules', JSON.stringify(data));
toast('Módulos actualizados');
} catch (e) {
toast(e.message, 'error');
} finally {
if (btn) { btn.disabled = false; btn.textContent = 'Guardar módulos'; }
}
}
// -------------------------------------------------------------------------
// Init
// -------------------------------------------------------------------------
@@ -744,6 +791,7 @@ const Config = (() => {
loadCurrency();
loadVehicleCompatSource();
loadAllowedBrands();
loadModules();
}
document.addEventListener('DOMContentLoaded', init);
@@ -753,6 +801,7 @@ const Config = (() => {
loadBranches, loadEmployees, saveBranch, saveEmployee, editEmployee,
loadBusiness, saveBusiness, saveTaxParams,
loadCurrency, saveCurrency,
loadModules, saveModules,
openModal, closeModal
};
// Register Cmd+K items