|
| 1 | +import { IntlShape } from '@edx/frontend-platform/i18n'; |
1 | 2 | import { actionKeys } from '@src/authz-module/components/RoleCard/constants'; |
2 | 3 | import actionMessages from '../components/RoleCard/messages'; |
| 4 | +import { PermissionMetadata, ResourceMetadata, Role } from 'types'; |
| 5 | + |
| 6 | +function getPermissionMetadata( |
| 7 | + permission: PermissionMetadata, |
| 8 | + intl: IntlShape, |
| 9 | +): { label: string; actionKey: string | undefined } { |
| 10 | + const actionKey = actionKeys.find(action => permission.key.includes(action)); |
| 11 | + let messageKey = `authz.permissions.actions.${actionKey}`; |
| 12 | + let messageResource = ''; |
| 13 | + |
| 14 | + if (actionKey === 'tag' || actionKey === 'team') { |
| 15 | + messageKey = 'authz.permissions.actions.manage'; |
| 16 | + messageResource = actionKey === 'tag' ? 'Tags' : ''; |
| 17 | + } |
| 18 | + |
| 19 | + const label = permission.label || intl.formatMessage(actionMessages[messageKey], { resource: messageResource }); |
| 20 | + |
| 21 | + return { label, actionKey }; |
| 22 | +} |
| 23 | + |
3 | 24 |
|
4 | 25 | const buildPermissionsByRoleMatrix = ({ |
5 | | - rolePermissions, permissions, resources, intl, |
| 26 | + rolePermissions, |
| 27 | + permissions, |
| 28 | + resources, |
| 29 | + intl, |
6 | 30 | }) => { |
7 | 31 | const permissionsMatrix = {}; |
8 | 32 | const allowedPermissions = new Set(rolePermissions); |
9 | 33 |
|
10 | 34 | permissions.forEach((permission) => { |
11 | | - const resourceLabel = resources.find(r => r.key === permission.resource)?.label || permission.resource; |
12 | | - const actionKey = actionKeys.find(action => permission.key.includes(action)); |
13 | | - let messageKey = `authz.permissions.actions.${actionKey}`; |
14 | | - let messageResource = ''; |
| 35 | + const resourceLabel = |
| 36 | + resources.find((r) => r.key === permission.resource)?.label || |
| 37 | + permission.resource; |
| 38 | + |
| 39 | + const { label, actionKey } = getPermissionMetadata(permission, intl); |
15 | 40 |
|
16 | | - permissionsMatrix[permission.resource] = permissionsMatrix[permission.resource] |
17 | | - || { key: permission.resource, label: resourceLabel, actions: [] }; |
| 41 | + if (!actionKey) return; // Skip unknown actions |
18 | 42 |
|
19 | | - if (actionKey === 'tag' || actionKey === 'team') { |
20 | | - messageKey = 'authz.permissions.actions.manage'; |
21 | | - messageResource = actionKey === 'tag' ? 'Tags' : messageResource; |
| 43 | + // Initialize resource group if not already present |
| 44 | + if (!permissionsMatrix[permission.resource]) { |
| 45 | + permissionsMatrix[permission.resource] = { |
| 46 | + key: permission.resource, |
| 47 | + label: resourceLabel, |
| 48 | + actions: [], |
| 49 | + }; |
22 | 50 | } |
23 | 51 |
|
24 | 52 | permissionsMatrix[permission.resource].actions.push({ |
25 | 53 | key: actionKey, |
26 | | - label: permission.label || intl.formatMessage(actionMessages[messageKey], { resource: messageResource }), |
| 54 | + label, |
27 | 55 | disabled: !allowedPermissions.has(permission.key), |
28 | 56 | }); |
29 | 57 | }); |
| 58 | + |
30 | 59 | return Object.values(permissionsMatrix); |
31 | 60 | }; |
32 | 61 |
|
| 62 | + |
| 63 | + |
| 64 | + |
| 65 | +type PermissionMatrix = { |
| 66 | + resource: string; |
| 67 | + resourceLabel: string; |
| 68 | + permissions: { |
| 69 | + key: string; |
| 70 | + label: string; |
| 71 | + roles: Record<string, boolean>; |
| 72 | + }[]; |
| 73 | +}[]; |
| 74 | + |
| 75 | +export function buildPermissionMatrix( |
| 76 | + roles: Role[], |
| 77 | + permissions: PermissionMetadata[], |
| 78 | + resources: ResourceMetadata[], |
| 79 | + intl: IntlShape, |
| 80 | +): PermissionMatrix { |
| 81 | + const permissionsByResource = permissions.reduce<Record<string, PermissionMetadata[]>>((acc, perm) => { |
| 82 | + if (!acc[perm.resource]) acc[perm.resource] = []; |
| 83 | + acc[perm.resource].push(perm); |
| 84 | + return acc; |
| 85 | + }, {}); |
| 86 | + |
| 87 | + const matrix: PermissionMatrix = resources.map(resource => { |
| 88 | + const resourcePermissions = permissionsByResource[resource.key] || []; |
| 89 | + |
| 90 | + const permissionRows = resourcePermissions.map(permission => { |
| 91 | + const rolesMap: Record<string, boolean> = {}; |
| 92 | + |
| 93 | + roles.forEach(role => { |
| 94 | + rolesMap[role.name] = role.permissions.includes(permission.key); |
| 95 | + }); |
| 96 | + |
| 97 | + const { label, actionKey } = getPermissionMetadata(permission, intl); |
| 98 | + |
| 99 | + return { |
| 100 | + key: permission.key, |
| 101 | + actionKey, // Important for icon mapping |
| 102 | + label, |
| 103 | + roles: rolesMap, |
| 104 | + }; |
| 105 | + }); |
| 106 | + |
| 107 | + return { |
| 108 | + resource: resource.key, |
| 109 | + resourceLabel: resource.label, |
| 110 | + permissions: permissionRows, |
| 111 | + }; |
| 112 | + }); |
| 113 | + |
| 114 | + return matrix; |
| 115 | +} |
| 116 | + |
| 117 | + |
33 | 118 | export { buildPermissionsByRoleMatrix }; |
0 commit comments