/* ============================================================ rbac.js — Enterprise Role Based Access Control Microsoft Admin Center-style permission matrix ============================================================ */ window.Views = window.Views || {}; window.RBAC = {}; Views.rbac = function () { const state = { roleIdx: 0 }; RBAC._state = state; const html = `

Access Control

Enterprise RBAC — configure permissions for every role and module

`; return { html, onMount() { RBAC._renderRoles(); RBAC._renderDetail(); } }; }; RBAC._renderRoles = function () { const el = document.getElementById('roleList'); el.innerHTML = DB.rbacRoles.map((r, i) => `
${UI.icon('shield')}
${r.name}
${r.users} user${r.users === 1 ? '' : 's'}
`).join(''); el.querySelectorAll('.role-item').forEach(item => item.onclick = () => { RBAC._state.roleIdx = +item.dataset.idx; RBAC._renderRoles(); RBAC._renderDetail(); }); }; RBAC._renderDetail = function () { const r = DB.rbacRoles[RBAC._state.roleIdx]; const el = document.getElementById('rbacDetail'); const matrixRows = DB.rbacModules.map(mod => ` ${mod} ${DB.permTypes.map((pt, pi) => `${UI.icon('check')}`).join('')} `).join(''); el.innerHTML = `
${UI.icon('shield')}

${r.name}

${r.desc}
${r.users} users
${DB.permTypes.map(p => ``).join('')}${matrixRows}
Module${p}
`; el.querySelectorAll('.perm-check').forEach(chk => chk.onclick = () => { const mod = chk.dataset.mod, pi = +chk.dataset.perm; r.matrix[mod][pi] = !r.matrix[mod][pi]; chk.classList.toggle('on'); }); }; RBAC.toggleAll = function (on) { const r = DB.rbacRoles[RBAC._state.roleIdx]; DB.rbacModules.forEach(mod => r.matrix[mod] = r.matrix[mod].map(() => on)); RBAC._renderDetail(); UI.toast(on ? 'All permissions granted for ' + r.name : 'All permissions revoked for ' + r.name, on ? 'success' : 'warning'); }; RBAC.addRole = function () { UI.modal({ title: 'Create Role', subtitle: 'Define a new access role', body: `
Required
`, footer: `` }); }; RBAC._saveRole = function () { const form = document.getElementById('roleForm'); UI.clearErrors(form); const f = Object.fromEntries(new FormData(form)); if (!f.name.trim()) { UI.fieldError(form.querySelector('[name=name]'), 'Required'); return; } const levelMap = { 'View only': 'View', 'Editor': 'Edit', 'Approver': 'Approve', 'Manager': 'Manage', 'Administrator': 'Administrator' }; const level = levelMap[f.template] || 'View'; const idxMap = { 'View': 1, 'Edit': 3, 'Approve': 5, 'Manage': 7, 'Administrator': 8 }; const cutoff = idxMap[level]; const matrix = {}; DB.rbacModules.forEach(mod => matrix[mod] = DB.permTypes.map((p, i) => i < cutoff)); DB.rbacRoles.push({ name: f.name, users: 0, color: f.color, desc: f.desc || 'Custom role', level, matrix }); RBAC._state.roleIdx = DB.rbacRoles.length - 1; UI.closeModal(); RBAC._renderRoles(); RBAC._renderDetail(); UI.toast('Role "' + f.name + '" created', 'success'); };