// Shared RBAC form view-model helpers. function normalizeSectionId(value) { return String(value || '').trim().toLowerCase().replace(/[^a-z0-9]+/g, '-'); } function toSortIndex(value) { const number = Number(value); return Number.isFinite(number) ? number : 999; } function buildPermissionSections(permissionGroups) { const sections = []; const sectionIndex = new Map(); const actionDefinitions = [ { key: 'read', label: 'Read' }, { key: 'create', label: 'Create' }, { key: 'update', label: 'Update' }, { key: 'delete', label: 'Delete' }, { key: 'allow', label: 'Allow' } ]; (Array.isArray(permissionGroups) ? permissionGroups : []).forEach(function (group) { const sectionTitle = String(group && group.categoryName || 'Permissions').trim() || 'Permissions'; const sectionKey = normalizeSectionId(sectionTitle) || 'permissions'; if (!sectionIndex.has(sectionKey)) { sectionIndex.set(sectionKey, { id: sectionKey, title: sectionTitle, sourceIndex: toSortIndex(group && group.sectionIndex), sectionOrder: toSortIndex(group && group.sectionOrder), groups: [] }); sections.push(sectionIndex.get(sectionKey)); } const section = sectionIndex.get(sectionKey); const groupPermissions = Array.isArray(group && group.permissions) ? group.permissions.slice() : []; const sectionGroup = Object.assign({}, group, { permissions: groupPermissions }); section.groups.push(sectionGroup); }); sections.forEach(function (section) { section.actions = actionDefinitions.map(function (actionDefinition) { return { key: actionDefinition.key, label: actionDefinition.label }; }); section.groups.sort(function (left, right) { const leftIndex = toSortIndex(left.resourceIndex); const rightIndex = toSortIndex(right.resourceIndex); if (leftIndex !== rightIndex) { return leftIndex - rightIndex; } const leftOrder = toSortIndex(left.resourceOrder); const rightOrder = toSortIndex(right.resourceOrder); if (leftOrder !== rightOrder) { return leftOrder - rightOrder; } return String(left.title || '').localeCompare(String(right.title || '')); }); section.groups.forEach(function (group) { group.cells = section.actions.map(function (action) { return (Array.isArray(group.permissions) ? group.permissions : []).find(function (permission) { return String(permission.actionKey || '').trim().toLowerCase() === action.key; }) || null; }); }); }); sections.sort(function (left, right) { const leftIndex = toSortIndex(left.sourceIndex); const rightIndex = toSortIndex(right.sourceIndex); if (leftIndex !== rightIndex) { return leftIndex - rightIndex; } const leftOrder = toSortIndex(left.sectionOrder); const rightOrder = toSortIndex(right.sectionOrder); if (leftOrder !== rightOrder) { return leftOrder - rightOrder; } return String(left.title || '').localeCompare(String(right.title || '')); }); return sections; } function buildRbacAddViewModel(message, currentUser, formValues, permissionGroups, users, pagination, messageVariant) { return { title: 'Create role', active: 'rbac', isEdit: false, usersPresent: true, formId: 'role-create-form', formAction: '/rbac', footerSaveUrl: '/rbac', footerCancelUrl: '/rbac', footerDeleteUrl: '', footerDeleteDisabled: true, footerDeleteTitle: 'Delete is available after the role has been created.', footerShowDelete: true, message: message, messageVariant: messageVariant || 'primary', currentUser: currentUser || null, formValues: formValues || {}, permissionGroups: permissionGroups || [], permissionSections: buildPermissionSections(permissionGroups), users: users || [], pagination: pagination || null, roleEditBasePath: '/rbac/new', scripts: ['js/rbac-permissions.js'], formAttrs: 'data-async-save data-async-save-close-url="/rbac" data-async-save-new-redirect="response-url" data-async-save-new-url="/rbac/new"' }; } function buildRbacEditViewModel(role, message, currentUser, permissionGroups, users, pagination) { return { title: 'Edit role', active: 'rbac', isEdit: true, usersPresent: true, formId: 'role-edit-form', formAction: '/rbac/' + Number(role && role.id), footerSaveUrl: '/rbac/' + Number(role && role.id), footerCancelUrl: '/rbac', footerDeleteUrl: '/rbac/' + Number(role && role.id) + '/delete', footerDeleteDisabled: Boolean(role && role.inUse), footerDeleteTitle: role && role.inUse ? 'Delete is disabled while this role is assigned to users.' : '', footerShowDelete: true, message: message, currentUser: currentUser || null, role: role, inUse: Boolean(role && role.inUse), permissionGroups: permissionGroups || [], permissionSections: buildPermissionSections(permissionGroups), users: users || [], pagination: pagination || null, roleEditBasePath: '/rbac/' + Number(role && role.id) + '/edit', scripts: ['js/rbac-permissions.js'], formAttrs: 'data-async-save data-async-save-close-url="/rbac" data-async-save-new-url="/rbac/new"' }; } module.exports = { buildRbacAddViewModel: buildRbacAddViewModel, buildRbacEditViewModel: buildRbacEditViewModel, buildPermissionSections: buildPermissionSections };