feat(settings): agregar opcion global para habilitar o deshabilitar saludo y selector de rol en dashboard

This commit is contained in:
2026-09-23 20:18:43 -03:00
parent 63511b9311
commit a188c3bd8f
7 changed files with 154 additions and 3 deletions
+4
View File
@@ -1406,6 +1406,9 @@ const handleGlobalSettings = async (req, res) => {
if (settings && settings.moodle) {
settings.moodle.ws_token_masked = settings.moodle.ws_token_masked || settings.moodle.ws_token || '';
}
if (settings) {
settings.ui = settings.ui || { show_role_banner: true };
}
try {
const demoResp = await req.apiClient.get('/settings/demo-mode');
@@ -1503,5 +1506,6 @@ router.post('/settings/moodle', forwardSettingsAction);
router.post('/settings/moodle/test', forwardSettingsAction);
router.post('/settings/moodle/sync', forwardSettingsAction);
router.get('/settings/moodle/stats', forwardSettingsAction);
router.post('/settings/ui', forwardSettingsAction);
module.exports = router;
+6
View File
@@ -266,6 +266,11 @@ router.get('/', async (req, res) => {
{ start_time: '18:30', end_time: '22:30', date_display: '24/09', subject_name: 'Ingeniería de Software', subject_code: 'IS-301', shift: 'Noche', commission: { code: 'COM-3' }, status: 'PENDING', classroom: { code: 'Aula Magna' }, user: { name: 'Ing. Marcos Ruiz' } }
];
let show_role_banner = true;
if (apiData && apiData.ui && apiData.ui.show_role_banner !== undefined) {
show_role_banner = Boolean(apiData.ui.show_role_banner);
}
res.render('dashboard', {
title: role === 'bedelia' ? 'Panel Operativo de Bedelía - Edu-Space Admin' :
role === 'docente' ? 'Panel Docente - Edu-Space Admin' :
@@ -274,6 +279,7 @@ router.get('/', async (req, res) => {
user: req.user,
role,
actual_role,
show_role_banner,
stats,
role_data,
monthly_data,
@@ -83,6 +83,11 @@
<i class="bi bi-mortarboard me-2 text-danger"></i>Moodle 4.1 & Cola de Sync
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="tab-ui-btn" data-bs-toggle="tab" data-bs-target="#tab-ui" type="button" role="tab">
<i class="bi bi-window-desktop me-2 text-primary"></i>Interfaz & Dashboard
</button>
</li>
</ul>
</div>
@@ -495,6 +500,55 @@
</div>
</div>
<!-- ========================================== -->
<!-- PESTAÑA 4: INTERFAZ & DASHBOARD -->
<!-- ========================================== -->
<div class="tab-pane fade" id="tab-ui" role="tabpanel">
<div class="row g-4">
<div class="col-lg-8">
<form id="uiConfigForm" onsubmit="saveUiConfig(event)">
<div class="card border shadow-none bg-body-tertiary p-3 mb-4 rounded-3">
<h6 class="fw-bold mb-3 d-flex align-items-center">
<i class="bi bi-layout-text-window-reverse text-primary me-2"></i>Personalización Visual del Dashboard
</h6>
<div class="form-check form-switch p-0 d-flex align-items-center justify-content-between mb-2 border rounded p-3 bg-body">
<div class="pe-3">
<label class="form-check-label fw-bold mb-1 d-block text-body" for="show_role_banner_switch">
Mostrar banner de saludo y selector de roles en el Dashboard
</label>
<div class="text-muted small">
Habilita el banner superior <code>¡Hola, {Usuario}!</code> junto a la insignia de rol y la barra de cambio de perspectiva de roles (Admin, Bedelía, Docente, Alumno) en el Dashboard.
<div class="text-warning-emphasis small mt-1">
<i class="bi bi-info-circle me-1"></i>Si se desactiva, el dashboard se mostrará directamente con los indicadores operativos del rol del usuario, evitando confusiones.
</div>
</div>
</div>
<input class="form-check-input ms-2 fs-4" type="checkbox" role="switch" id="show_role_banner_switch"
{% if settings.ui and settings.ui.show_role_banner %}checked{% elif not settings.ui or settings.ui.show_role_banner is not defined %}checked{% endif %}>
</div>
</div>
<div class="d-flex justify-content-end">
<button type="submit" class="btn btn-primary btn-sm px-4" id="btnSaveUi">
<i class="bi bi-check2-circle me-1"></i>Guardar Preferencias de Interfaz
</button>
</div>
</form>
</div>
<!-- Panel de Consejos / UX -->
<div class="col-lg-4">
<div class="card border-0 bg-primary-subtle text-primary-emphasis p-3 rounded-3 mb-3">
<h6 class="fw-bold mb-2"><i class="bi bi-lightbulb me-1"></i>Experiencia de Usuario (UX)</h6>
<p class="small mb-0">
El banner de saludo institucional y selector de perspectiva es ideal durante capacitaciones. Al deshabilitarlo para el uso diario institucional, los administradores y usuarios acceden de inmediato a sus módulos de gestión y carteleras sin distracciones ni dudas de rol.
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -1024,6 +1078,37 @@ function escapeHtml(str) {
});
}
// -------------------------------------------------------------
// Guardar Configuración de Interfaz (UI & Dashboard)
// -------------------------------------------------------------
async function saveUiConfig(e) {
e.preventDefault();
const btn = document.getElementById('btnSaveUi');
btn.disabled = true;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>Guardando...';
const showRoleBanner = document.getElementById('show_role_banner_switch').checked;
try {
const res = await fetch('/admin/settings/ui', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ show_role_banner: showRoleBanner })
});
const data = await res.json();
if (res.ok) {
showAlert(data.message || 'Preferencias de interfaz guardadas correctamente.', 'success');
} else {
showAlert(data.message || 'Error al guardar preferencias de interfaz.', 'danger');
}
} catch (err) {
showAlert('Error de comunicación con el servidor: ' + err.message, 'danger');
} finally {
btn.disabled = false;
btn.innerHTML = '<i class="bi bi-check2-circle me-1"></i>Guardar Preferencias de Interfaz';
}
}
// Cargar estadísticas y tareas al iniciar
document.addEventListener('DOMContentLoaded', () => {
refreshQueueStats();
+2
View File
@@ -20,6 +20,7 @@
<!-- ========================================================================= -->
<!-- 1. HEADER & ROLE PERSPECTIVE SWITCHER -->
<!-- ========================================================================= -->
{% if show_role_banner %}
<div class="dashboard-role-banner mb-3 shadow-sm">
<div class="d-flex justify-content-between align-items-center flex-wrap gap-3">
<div>
@@ -78,6 +79,7 @@
{% endif %}
</div>
</div>
{% endif %}
<!-- ========================================================================= -->