ligbox-ops-platform/projects/ops-desk/frontend/assets/topnav.js
Ligbox Spec Hub a1e4f43dbb chore(desk): processo staging modern UI — topnav + servicos merge (sem prod)
Adiciona index.staging.html, topnav.js, desk-modern.css, app.staging.js,
snapshot VM122, script deploy-staging-only e checklist antes de cutover prod.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-26 21:20:21 +00:00

128 lines
4.1 KiB
JavaScript

/** Desk chrome nav — tabs planas por zona + sidebar contextual (v0.11). */
const TOPNAV_VIEW_GROUP = {
'agentic-ops': 'operacoes',
dashboard: 'operacoes',
tickets: 'operacoes',
events: 'operacoes',
'overview-home': 'comercial',
leads: 'comercial',
infra: 'infra',
infra2: 'infra',
'email-migration': 'infra',
overview: 'sistema',
account: 'sistema',
messages: 'sistema',
admin: 'sistema',
'access-matrix': 'sistema',
modules: 'sistema',
};
const CONTEXT_TOOLBARS = {
tickets: { title: 'Tickets', host: '#view-tickets', label: 'Filas' },
events: { title: 'Eventos', host: '#view-events', label: 'Vistas' },
};
function initTopnavDropdowns() {
/* v0.11 — tabs planas; sem dropdowns */
}
function parkContextToolbars() {
Object.values(CONTEXT_TOOLBARS).forEach(({ host }) => {
const view = document.querySelector(host);
const toolbar = view?.querySelector('.toolbar');
if (toolbar && view && toolbar.parentElement !== view) {
view.insertBefore(toolbar, view.firstChild);
}
});
const matrixRoleNav = document.getElementById('context-matrix-roles');
if (matrixRoleNav && matrixRoleNav.dataset.parkedFrom) {
const slot = document.querySelector(matrixRoleNav.dataset.parkedFrom);
if (slot) slot.appendChild(matrixRoleNav);
delete matrixRoleNav.dataset.parkedFrom;
}
const adminHost = document.getElementById('context-admin-tabs');
if (adminHost) adminHost.innerHTML = '';
}
function updateTopnavActive(view) {
document.querySelectorAll('[data-desk-nav]').forEach((btn) => {
const active = btn.dataset.view === view;
btn.classList.toggle('active', active);
if (active) btn.setAttribute('aria-current', 'page');
else btn.removeAttribute('aria-current');
});
document.querySelectorAll('.nav-zone[data-topnav-group]').forEach((zone) => {
zone.classList.toggle('active', TOPNAV_VIEW_GROUP[view] === zone.dataset.topnavGroup);
});
}
function mountMatrixRoleSidebar() {
const roleNav = document.querySelector('#access-matrix-content .am-role-list');
if (!roleNav) return false;
const nav = document.getElementById('context-nav');
if (!nav) return false;
roleNav.dataset.parkedFrom = '#access-matrix-content .am-layout';
nav.appendChild(roleNav);
return true;
}
function updateContextSidebar(view) {
const shell = document.querySelector('.shell');
const sidebar = document.getElementById('context-sidebar');
const nav = document.getElementById('context-nav');
const titleEl = document.getElementById('context-sidebar-title');
const labelEl = document.getElementById('context-sidebar-label');
if (!shell || !sidebar || !nav) return;
parkContextToolbars();
nav.innerHTML = '';
if (view === 'admin' && typeof renderAdminTabs === 'function') {
sidebar.hidden = false;
shell.classList.remove('shell--no-context');
if (titleEl) titleEl.textContent = 'Administradores';
if (labelEl) labelEl.textContent = 'Secções';
nav.innerHTML = `<div id="context-admin-tabs">${renderAdminTabs()}</div>`;
if (typeof bindAdminTabs === 'function') bindAdminTabs();
return;
}
if (view === 'access-matrix') {
sidebar.hidden = false;
shell.classList.remove('shell--no-context');
if (titleEl) titleEl.textContent = 'Matriz de Acesso';
if (labelEl) labelEl.textContent = 'Funções';
requestAnimationFrame(() => mountMatrixRoleSidebar());
return;
}
const cfg = CONTEXT_TOOLBARS[view];
if (!cfg) {
sidebar.hidden = true;
shell.classList.add('shell--no-context');
return;
}
const viewEl = document.querySelector(cfg.host);
const toolbar = viewEl?.querySelector('.toolbar');
if (!toolbar) {
sidebar.hidden = true;
shell.classList.add('shell--no-context');
return;
}
sidebar.hidden = false;
shell.classList.remove('shell--no-context');
if (titleEl) titleEl.textContent = cfg.title;
if (labelEl) labelEl.textContent = cfg.label;
toolbar.classList.add('context-toolbar');
nav.appendChild(toolbar);
}
window.DeskTopnav = {
initTopnavDropdowns,
updateTopnavActive,
updateContextSidebar,
remountMatrixRoles: mountMatrixRoleSidebar,
};