Files
pulse-signage/src/web/routes/settings/rbac/form-view-model.js
T
2026-08-08 15:11:11 +01:00

157 lines
5.4 KiB
JavaScript

// 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
};