@flusys/ng-iam 3.0.1 → 4.0.0-lts
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/fesm2022/{flusys-ng-iam-action-form-page.component-eXpZNJ_H.mjs → flusys-ng-iam-action-form-page.component-BQx9yset.mjs} +62 -50
- package/fesm2022/flusys-ng-iam-action-form-page.component-BQx9yset.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-action-list-page.component-BtJlGcTj.mjs → flusys-ng-iam-action-list-page.component-BrpZujxk.mjs} +51 -42
- package/fesm2022/flusys-ng-iam-action-list-page.component-BrpZujxk.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-flusys-ng-iam-CJAQT60K.mjs → flusys-ng-iam-flusys-ng-iam-Co4ot9My.mjs} +641 -341
- package/fesm2022/flusys-ng-iam-flusys-ng-iam-Co4ot9My.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-iam-container.component-UYJjqYV9.mjs → flusys-ng-iam-iam-container.component-CQA2B6cU.mjs} +14 -13
- package/fesm2022/flusys-ng-iam-iam-container.component-CQA2B6cU.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-permission-page.component-DcgT7L3_.mjs → flusys-ng-iam-permission-page.component-Dpk90y72.mjs} +14 -13
- package/fesm2022/flusys-ng-iam-permission-page.component-Dpk90y72.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-role-form-page.component-D_AAEay2.mjs → flusys-ng-iam-role-form-page.component-CVfRQpoa.mjs} +38 -35
- package/fesm2022/flusys-ng-iam-role-form-page.component-CVfRQpoa.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-role-list-page.component-D4J1by6Q.mjs → flusys-ng-iam-role-list-page.component-BHB8X5r7.mjs} +41 -38
- package/fesm2022/flusys-ng-iam-role-list-page.component-BHB8X5r7.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam.mjs +1 -1
- package/package.json +7 -5
- package/types/flusys-ng-iam.d.ts +13 -5
- package/fesm2022/flusys-ng-iam-action-form-page.component-eXpZNJ_H.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-action-list-page.component-BtJlGcTj.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-flusys-ng-iam-CJAQT60K.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-iam-container.component-UYJjqYV9.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-permission-page.component-DcgT7L3_.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-role-form-page.component-D_AAEay2.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-role-list-page.component-D4J1by6Q.mjs.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { HttpClient } from '@angular/common/http';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { inject, Injectable, signal, input, output, effect,
|
|
4
|
-
import { ApiResourceService, PermissionValidatorService, AngularModule, PrimeModule, ROLE_ACTION_PERMISSIONS, HasPermissionDirective, COMPANY_ACTION_PERMISSIONS, COMPANY_API_PROVIDER, USER_ROLE_PERMISSIONS, USER_PERMISSION_PROVIDER, UserSelectComponent, USER_ACTION_PERMISSIONS, PROFILE_PERMISSION_PROVIDER, permissionGuard, ACTION_PERMISSIONS, ROLE_PERMISSIONS, anyPermissionGuard } from '@flusys/ng-shared';
|
|
5
|
-
import { APP_CONFIG, getServiceUrl, BaseApiService, isCompanyFeatureEnabled } from '@flusys/ng-core';
|
|
3
|
+
import { inject, Injectable, signal, input, output, effect, Component, DestroyRef, computed } from '@angular/core';
|
|
4
|
+
import { ApiResourceService, PermissionValidatorService, AngularModule, PrimeModule, TranslatePipe, ROLE_ACTION_PERMISSIONS, HasPermissionDirective, COMPANY_ACTION_PERMISSIONS, COMPANY_API_PROVIDER, USER_ROLE_PERMISSIONS, USER_PERMISSION_PROVIDER, UserSelectComponent, USER_ACTION_PERMISSIONS, PROFILE_PERMISSION_PROVIDER, permissionGuard, ACTION_PERMISSIONS, ROLE_PERMISSIONS, anyPermissionGuard, resolveTranslationModule, SHARED_MESSAGES } from '@flusys/ng-shared';
|
|
5
|
+
import { APP_CONFIG, getServiceUrl, TRANSLATE_ADAPTER, BaseApiService, isCompanyFeatureEnabled } from '@flusys/ng-core';
|
|
6
6
|
import { ConfirmationService, MessageService } from 'primeng/api';
|
|
7
7
|
import { of, firstValueFrom, map as map$1 } from 'rxjs';
|
|
8
8
|
import { tap, catchError, map } from 'rxjs/operators';
|
|
@@ -32,6 +32,322 @@ var ActionType;
|
|
|
32
32
|
/** Maximum items for dropdown lists (companies, roles, users, branches) */
|
|
33
33
|
const MAX_DROPDOWN_ITEMS = 100;
|
|
34
34
|
|
|
35
|
+
const IAM_MESSAGES = {
|
|
36
|
+
// Container page
|
|
37
|
+
'iam.title': 'Identity & Access Management',
|
|
38
|
+
'iam.subtitle': 'Manage roles, permissions, and access control',
|
|
39
|
+
// Tabs
|
|
40
|
+
'iam.tabs.roles': 'Roles',
|
|
41
|
+
'iam.tabs.actions': 'Actions',
|
|
42
|
+
'iam.tabs.permissions': 'Permissions',
|
|
43
|
+
// Administration
|
|
44
|
+
'iam.administration.title': 'Administration',
|
|
45
|
+
'iam.administration.subtitle': 'Manage users, companies, and branches',
|
|
46
|
+
// Users
|
|
47
|
+
'iam.user.title': 'Users',
|
|
48
|
+
'iam.user.add': 'Add User',
|
|
49
|
+
'iam.user.new': 'New User',
|
|
50
|
+
'iam.user.create': 'Create User',
|
|
51
|
+
'iam.user.edit': 'Edit User',
|
|
52
|
+
'iam.user.name': 'Name',
|
|
53
|
+
'iam.user.email': 'Email',
|
|
54
|
+
'iam.user.phone': 'Phone',
|
|
55
|
+
'iam.user.password': 'Password',
|
|
56
|
+
'iam.user.password.optional': 'Password (leave blank to keep current)',
|
|
57
|
+
'iam.user.password.placeholder': 'Enter password',
|
|
58
|
+
'iam.user.name.placeholder': 'Enter full name',
|
|
59
|
+
'iam.user.email.placeholder': 'Enter email address',
|
|
60
|
+
'iam.user.phone.placeholder': 'Enter phone number',
|
|
61
|
+
'iam.user.email.verified': 'Email Verified',
|
|
62
|
+
'iam.user.no.users': 'No users found',
|
|
63
|
+
'iam.user.details': 'User Details',
|
|
64
|
+
'iam.user.auto.assign.to': 'Auto-assign to',
|
|
65
|
+
'iam.user.assign.role': 'Assign Role',
|
|
66
|
+
'iam.user.remove.role': 'Remove Role',
|
|
67
|
+
'iam.user.activate': 'Activate User',
|
|
68
|
+
'iam.user.deactivate': 'Deactivate User',
|
|
69
|
+
'iam.user.reset.password': 'Reset Password',
|
|
70
|
+
'iam.user.assign.branch': 'Assign Branch',
|
|
71
|
+
'iam.user.delete.title': 'Delete User',
|
|
72
|
+
'iam.user.delete.success': 'User deleted successfully',
|
|
73
|
+
// Roles
|
|
74
|
+
'iam.role.title': 'Roles',
|
|
75
|
+
'iam.role.new': 'New Role',
|
|
76
|
+
'iam.role.create': 'Create Role',
|
|
77
|
+
'iam.role.edit': 'Edit Role',
|
|
78
|
+
'iam.role.name': 'Role Name',
|
|
79
|
+
'iam.role.name.placeholder': 'Enter role name',
|
|
80
|
+
'iam.role.description': 'Role Description',
|
|
81
|
+
'iam.role.description.placeholder': 'Enter role description',
|
|
82
|
+
'iam.role.permissions': 'Permissions',
|
|
83
|
+
'iam.role.assigned.users': 'Assigned Users',
|
|
84
|
+
'iam.role.no.roles': 'No roles found',
|
|
85
|
+
'iam.role.no.roles.assigned': 'No roles assigned',
|
|
86
|
+
'iam.role.delete.title': 'Delete Role',
|
|
87
|
+
'iam.role.delete.success': 'Role deleted successfully',
|
|
88
|
+
'iam.role.create.success': 'Role created successfully',
|
|
89
|
+
'iam.role.update.success': 'Role updated successfully',
|
|
90
|
+
'role.create.success': 'Role created successfully',
|
|
91
|
+
'role.update.success': 'Role updated successfully',
|
|
92
|
+
'role.delete.success': 'Role deleted successfully',
|
|
93
|
+
'role.get.success': 'Role retrieved successfully',
|
|
94
|
+
'role.get.all.success': 'Roles retrieved successfully',
|
|
95
|
+
// Actions
|
|
96
|
+
'iam.action.title': 'Actions',
|
|
97
|
+
'iam.action.new': 'New Action',
|
|
98
|
+
'iam.action.create': 'Create Action',
|
|
99
|
+
'iam.action.edit': 'Edit Action',
|
|
100
|
+
'iam.action.name': 'Action Name',
|
|
101
|
+
'iam.action.name.placeholder': 'Enter action name',
|
|
102
|
+
'iam.action.code': 'Action Code',
|
|
103
|
+
'iam.action.code.placeholder': 'Enter action code',
|
|
104
|
+
'iam.action.type': 'Type',
|
|
105
|
+
'iam.action.no.actions': 'No actions found',
|
|
106
|
+
'iam.action.no.actions.assigned': 'No actions assigned',
|
|
107
|
+
'iam.action.direct.actions': 'Direct Actions',
|
|
108
|
+
'iam.action.type.backend': 'Backend',
|
|
109
|
+
'iam.action.type.frontend': 'Frontend',
|
|
110
|
+
'iam.action.type.both': 'Both',
|
|
111
|
+
'iam.action.type.backend.label': 'Backend Only',
|
|
112
|
+
'iam.action.type.frontend.label': 'Frontend Only',
|
|
113
|
+
'iam.action.type.both.label': 'Backend & Frontend',
|
|
114
|
+
'iam.action.delete.title': 'Delete Action',
|
|
115
|
+
'iam.action.delete.success': 'Action deleted successfully',
|
|
116
|
+
'iam.action.create.success': 'Action created successfully',
|
|
117
|
+
'iam.action.update.success': 'Action updated successfully',
|
|
118
|
+
'iam.action.parent': 'Parent Action',
|
|
119
|
+
'iam.action.select.parent': 'Select Parent Action',
|
|
120
|
+
// Permissions
|
|
121
|
+
'iam.permission.title': 'Permissions',
|
|
122
|
+
'iam.permission.create': 'Create Permission',
|
|
123
|
+
'iam.permission.edit': 'Edit Permission',
|
|
124
|
+
'iam.permission.name': 'Permission Name',
|
|
125
|
+
'iam.permission.code': 'Permission Code',
|
|
126
|
+
'iam.permission.module': 'Module',
|
|
127
|
+
'iam.permission.action': 'Action',
|
|
128
|
+
'iam.permission.description': 'Description',
|
|
129
|
+
'iam.permission.role.actions': 'Role Actions',
|
|
130
|
+
'iam.permission.user.roles': 'User Roles',
|
|
131
|
+
'iam.permission.user.actions': 'User Actions',
|
|
132
|
+
'iam.permission.company.actions': 'Company Actions',
|
|
133
|
+
'iam.permission.company.permissions': 'Company Permissions',
|
|
134
|
+
'iam.permission.branch.permissions': 'Branch Permissions',
|
|
135
|
+
'iam.permission.my.permissions': 'My Permissions',
|
|
136
|
+
'iam.permission.select.company': 'Select Company',
|
|
137
|
+
'iam.permission.select.company.placeholder': 'Search and select a company',
|
|
138
|
+
'iam.permission.select.role': 'Select Role',
|
|
139
|
+
'iam.permission.select.role.placeholder': 'Search and select a role',
|
|
140
|
+
'iam.permission.select.user': 'Select User',
|
|
141
|
+
'iam.permission.select.user.placeholder': 'Search and select a user',
|
|
142
|
+
'iam.permission.select.branch': 'Select Branch',
|
|
143
|
+
'iam.permission.select.branch.placeholder': 'Search and select a branch',
|
|
144
|
+
'iam.permission.action.whitelist': 'Action Whitelist',
|
|
145
|
+
'iam.permission.action.permissions': 'Action Permissions',
|
|
146
|
+
'iam.permission.direct.action.permissions': 'Direct Action Permissions',
|
|
147
|
+
'iam.permission.role.assignments': 'Role Assignments',
|
|
148
|
+
'iam.permission.actions.available': '{{count}} actions available',
|
|
149
|
+
'iam.permission.roles.available': '{{count}} roles available',
|
|
150
|
+
'iam.permission.no.actions.available': 'No actions available',
|
|
151
|
+
'iam.permission.no.roles.available': 'No roles available',
|
|
152
|
+
'iam.permission.no.actions.for.company': 'No actions available for this company',
|
|
153
|
+
'iam.permission.no.actions.for.role': 'No actions available for this role',
|
|
154
|
+
'iam.permission.no.actions.for.user': 'No actions available for this user',
|
|
155
|
+
'iam.permission.no.roles.for.user': 'No roles available for this user',
|
|
156
|
+
'iam.permission.company.required': 'Please select a company first',
|
|
157
|
+
'iam.permission.has.prerequisites': 'Has prerequisites',
|
|
158
|
+
'iam.permission.requirements': 'Requirements',
|
|
159
|
+
'iam.permission.company.actions.updated': 'Company actions updated successfully',
|
|
160
|
+
'iam.permission.role.permissions.updated': 'Role permissions updated successfully',
|
|
161
|
+
'iam.permission.user.actions.updated': 'User actions updated successfully',
|
|
162
|
+
'iam.permission.user.roles.updated': 'User roles updated successfully',
|
|
163
|
+
'iam.permission.requires': 'requires',
|
|
164
|
+
'iam.permission.prerequisite.validation.failed': 'Prerequisite Validation Failed',
|
|
165
|
+
'iam.permission.prerequisite.error.message': 'The following actions have unmet prerequisites:',
|
|
166
|
+
'iam.permission.auto.select.prompt': 'Would you like to auto-select the required actions?',
|
|
167
|
+
'iam.permission.auto.select.required': 'Auto-select Required',
|
|
168
|
+
'iam.permission.actions.selected': 'Actions Selected',
|
|
169
|
+
'iam.permission.auto.selected.prerequisites': 'Required prerequisites have been auto-selected. Click Save to apply changes.',
|
|
170
|
+
'iam.permission.changes.reverted': 'Changes Reverted',
|
|
171
|
+
'iam.permission.selection.reverted': 'Selection has been reverted to the initial state.',
|
|
172
|
+
'permission.create.success': 'Permission created successfully',
|
|
173
|
+
'permission.update.success': 'Permission updated successfully',
|
|
174
|
+
'permission.delete.success': 'Permission deleted successfully',
|
|
175
|
+
'permission.get.success': 'Permission retrieved successfully',
|
|
176
|
+
'permission.get.all.success': 'Permissions retrieved successfully',
|
|
177
|
+
'permission.process.success': 'Successfully processed {{total}} items: {{added}} added, {{removed}} removed',
|
|
178
|
+
'permission.user.required': 'User is required for {{method}}',
|
|
179
|
+
'permission.already.exists': 'Permission already exists',
|
|
180
|
+
// Access control
|
|
181
|
+
'iam.access.denied': 'Access Denied',
|
|
182
|
+
'iam.no.permission': 'You do not have permission to perform this action.',
|
|
183
|
+
'iam.contact.admin': 'Please contact your administrator for access.',
|
|
184
|
+
'iam.insufficient.permissions': 'Insufficient permissions',
|
|
185
|
+
// Company
|
|
186
|
+
'iam.company.title': 'Companies',
|
|
187
|
+
'iam.company.add': 'Add Company',
|
|
188
|
+
'iam.company.new': 'New Company',
|
|
189
|
+
'iam.company.create': 'Create Company',
|
|
190
|
+
'iam.company.edit': 'Edit Company',
|
|
191
|
+
'iam.company.select': 'Select Company',
|
|
192
|
+
'iam.company.name': 'Company Name',
|
|
193
|
+
'iam.company.name.placeholder': 'Enter company name',
|
|
194
|
+
'iam.company.slug': 'Company Slug',
|
|
195
|
+
'iam.company.slug.placeholder': 'Enter company slug',
|
|
196
|
+
'iam.company.code': 'Company Code',
|
|
197
|
+
'iam.company.code.placeholder': 'Enter company code',
|
|
198
|
+
'iam.company.details': 'Company Details',
|
|
199
|
+
'iam.company.address': 'Address',
|
|
200
|
+
'iam.company.address.placeholder': 'Enter company address',
|
|
201
|
+
'iam.company.phone': 'Phone',
|
|
202
|
+
'iam.company.phone.placeholder': 'Enter phone number',
|
|
203
|
+
'iam.company.email': 'Email',
|
|
204
|
+
'iam.company.email.placeholder': 'Enter email address',
|
|
205
|
+
'iam.company.website': 'Website',
|
|
206
|
+
'iam.company.website.placeholder': 'Enter website URL',
|
|
207
|
+
'iam.company.no.companies': 'No companies found',
|
|
208
|
+
'iam.company.delete.title': 'Delete Company',
|
|
209
|
+
'iam.company.delete.success': 'Company deleted successfully',
|
|
210
|
+
'iam.company.slug.required': 'Company slug is required',
|
|
211
|
+
// Branch
|
|
212
|
+
'iam.branch.title': 'Branches',
|
|
213
|
+
'iam.branch.add': 'Add Branch',
|
|
214
|
+
'iam.branch.new': 'New Branch',
|
|
215
|
+
'iam.branch.create': 'Create Branch',
|
|
216
|
+
'iam.branch.edit': 'Edit Branch',
|
|
217
|
+
'iam.branch.name': 'Branch Name',
|
|
218
|
+
'iam.branch.name.placeholder': 'Enter branch name',
|
|
219
|
+
'iam.branch.slug': 'Branch Slug',
|
|
220
|
+
'iam.branch.slug.placeholder': 'Enter branch slug',
|
|
221
|
+
'iam.branch.code': 'Branch Code',
|
|
222
|
+
'iam.branch.code.placeholder': 'Enter branch code',
|
|
223
|
+
'iam.branch.company': 'Company',
|
|
224
|
+
'iam.branch.no.branches': 'No branches found',
|
|
225
|
+
'iam.branch.select.company.first': 'Please select a company first',
|
|
226
|
+
'iam.branch.view.branches': 'View Branches',
|
|
227
|
+
'iam.branch.delete.title': 'Delete Branch',
|
|
228
|
+
'iam.branch.delete.success': 'Branch deleted successfully',
|
|
229
|
+
'iam.branch.slug.required': 'Branch slug is required',
|
|
230
|
+
// Action CRUD messages (API keys)
|
|
231
|
+
'action.create.success': 'Action created successfully',
|
|
232
|
+
'action.create.many.success': '{{count}} actions created successfully',
|
|
233
|
+
'action.get.success': 'Action retrieved successfully',
|
|
234
|
+
'action.get.all.success': 'Actions retrieved successfully',
|
|
235
|
+
'action.update.success': 'Action updated successfully',
|
|
236
|
+
'action.update.many.success': '{{count}} actions updated successfully',
|
|
237
|
+
'action.delete.success': 'Action deleted successfully',
|
|
238
|
+
'action.restore.success': 'Action restored successfully',
|
|
239
|
+
'action.not.found': 'Action not found',
|
|
240
|
+
// Role CRUD messages (API keys)
|
|
241
|
+
'role.create.many.success': '{{count}} roles created successfully',
|
|
242
|
+
'role.update.many.success': '{{count}} roles updated successfully',
|
|
243
|
+
'role.restore.success': 'Role restored successfully',
|
|
244
|
+
'role.not.found': 'Role not found',
|
|
245
|
+
// Role permission messages (API keys)
|
|
246
|
+
'role.permission.get.success': 'Role permissions retrieved successfully',
|
|
247
|
+
'role.permission.assign.success': 'Role permissions assigned successfully',
|
|
248
|
+
'role.permission.actions.success': 'Role actions retrieved successfully',
|
|
249
|
+
'role.permission.users.success': 'Role users retrieved successfully',
|
|
250
|
+
'role.permission.user.roles.success': 'User roles retrieved successfully',
|
|
251
|
+
// User action permission messages (API keys)
|
|
252
|
+
'user.action.permission.get.success': 'User action permissions retrieved successfully',
|
|
253
|
+
'user.action.permission.assign.success': 'User action permissions assigned successfully',
|
|
254
|
+
'user.action.permission.revoke.success': 'User action permissions revoked successfully',
|
|
255
|
+
// Company action permission messages (API keys)
|
|
256
|
+
'company.action.permission.get.success': 'Company action permissions retrieved successfully',
|
|
257
|
+
'company.action.permission.assign.success': 'Company action permissions assigned successfully',
|
|
258
|
+
'company.action.permission.revoke.success': 'Company action permissions revoked successfully',
|
|
259
|
+
// My permission messages (API keys)
|
|
260
|
+
'my.permission.get.success': 'Permissions loaded successfully',
|
|
261
|
+
// IAM mode messages (API keys)
|
|
262
|
+
'iam.direct.mode.unavailable': 'Direct permission assignment not available in RBAC-only mode',
|
|
263
|
+
'iam.rbac.mode.unavailable': 'Role-based permission assignment not available in direct-only mode',
|
|
264
|
+
'iam.role.assignment.unavailable': 'Role assignment not available in direct-only mode',
|
|
265
|
+
// Validation warnings
|
|
266
|
+
'iam.validation.warning.title': 'Validation Warning',
|
|
267
|
+
'iam.validation.unmet.prerequisites.singular': '{{count}} selected action has unmet prerequisites. Fix before saving or use auto-fix on save.',
|
|
268
|
+
'iam.validation.unmet.prerequisites.plural': '{{count}} selected actions have unmet prerequisites. Fix before saving or use auto-fix on save.',
|
|
269
|
+
'iam.validation.unmet.prerequisites.tooltip': 'This action has unmet prerequisites and will fail validation on save',
|
|
270
|
+
// Branch selector
|
|
271
|
+
'iam.branch.permitted.count': '{{count}} permitted branch in current company',
|
|
272
|
+
'iam.branch.permitted.count.plural': '{{count}} permitted branches in current company',
|
|
273
|
+
// Tooltips
|
|
274
|
+
'iam.tooltip.remove.action': 'Click to remove',
|
|
275
|
+
'iam.tooltip.add.action': 'Click to add (auto-selects required)',
|
|
276
|
+
'iam.tooltip.selected': 'Selected',
|
|
277
|
+
'iam.tooltip.click.to.remove': 'Click to remove from company whitelist',
|
|
278
|
+
'iam.tooltip.click.to.add': 'Click to add to company whitelist',
|
|
279
|
+
'iam.tooltip.assigned.to.role': 'Assigned to role',
|
|
280
|
+
'iam.tooltip.click.to.remove.role': 'Click to remove',
|
|
281
|
+
'iam.tooltip.click.to.assign.role': 'Click to assign to role',
|
|
282
|
+
'iam.tooltip.assigned.to.user': 'Assigned to user',
|
|
283
|
+
'iam.tooltip.click.to.remove.user': 'Click to remove direct permission',
|
|
284
|
+
'iam.tooltip.click.to.assign.user': 'Click to assign direct permission',
|
|
285
|
+
'iam.tooltip.click.to.remove.role.from.user': 'Click to remove role',
|
|
286
|
+
'iam.tooltip.click.to.assign.role.to.user': 'Click to assign role to user',
|
|
287
|
+
// Logic builder
|
|
288
|
+
'iam.logic.title': 'Permission Logic',
|
|
289
|
+
'iam.logic.add.logic': 'Add Logic',
|
|
290
|
+
'iam.logic.clear.logic': 'Clear Logic',
|
|
291
|
+
'iam.logic.description': 'Define permission requirements using AND/OR logic with actions',
|
|
292
|
+
'iam.logic.conditions': '{{count}} conditions',
|
|
293
|
+
'iam.logic.select.action': 'Select Action...',
|
|
294
|
+
'iam.logic.actions.available': '{{count}} available',
|
|
295
|
+
'iam.logic.remove': 'Remove',
|
|
296
|
+
'iam.logic.add.condition': 'Add Condition:',
|
|
297
|
+
'iam.logic.group': 'Group',
|
|
298
|
+
'iam.logic.action': 'Action',
|
|
299
|
+
// Permission logic dialogs
|
|
300
|
+
'iam.logic.validation.failed': 'Validation Failed',
|
|
301
|
+
'iam.logic.validation.failed.message': 'The following actions have unmet prerequisites:',
|
|
302
|
+
'iam.logic.validation.failed.prompt': 'Would you like to:',
|
|
303
|
+
'iam.logic.auto.fix': 'Auto-fix (Remove Invalid)',
|
|
304
|
+
'iam.logic.invalid.actions.removed': 'Invalid Actions Removed',
|
|
305
|
+
'iam.logic.removed.actions.detail': 'Removed {{count}} action(s) with unmet prerequisites. You can now save.',
|
|
306
|
+
'iam.logic.save.cancelled': 'Save Cancelled',
|
|
307
|
+
'iam.logic.fix.prerequisites.manually': 'Please fix the prerequisites manually before saving',
|
|
308
|
+
'iam.logic.missing.prerequisites': 'Missing Prerequisites',
|
|
309
|
+
'iam.logic.requires.conditions': 'requires the following conditions to be satisfied:',
|
|
310
|
+
'iam.logic.auto.select.prompt': 'Auto-select will choose {{count}} action(s){{suffix}}.',
|
|
311
|
+
'iam.logic.minimum.required': ' (minimum required)',
|
|
312
|
+
'iam.logic.would.you.continue': 'Would you like to continue?',
|
|
313
|
+
'iam.logic.select.action.label': 'Select Action',
|
|
314
|
+
'iam.logic.auto.select.actions': 'Auto-select Actions',
|
|
315
|
+
'iam.logic.actions.selected.summary': 'Actions Selected',
|
|
316
|
+
'iam.logic.action.selected.detail': 'Action selected successfully (prerequisites already satisfied)',
|
|
317
|
+
'iam.logic.auto.selected.detail': 'Automatically selected {{count}} action(s) including prerequisites',
|
|
318
|
+
'iam.logic.selection.cancelled': 'Selection Cancelled',
|
|
319
|
+
'iam.logic.action.not.added': 'Action not added to whitelist',
|
|
320
|
+
'iam.logic.dependency.warning': 'Dependency Warning',
|
|
321
|
+
'iam.logic.required.by.actions': 'is required by the following action(s):',
|
|
322
|
+
'iam.logic.alternatives.available': 'Alternative options available:',
|
|
323
|
+
'iam.logic.switch.to.alternatives': 'Would you like to automatically switch to alternatives?',
|
|
324
|
+
'iam.logic.remove.dependents': 'Removing this will also remove the dependent action(s).',
|
|
325
|
+
'iam.logic.use.alternatives': 'Use Alternatives',
|
|
326
|
+
'iam.logic.remove.all': 'Remove All',
|
|
327
|
+
'iam.logic.alternatives.applied': 'Alternatives Applied',
|
|
328
|
+
'iam.logic.switched.to.alternatives': 'Switched to alternative actions to maintain dependencies',
|
|
329
|
+
'iam.logic.actions.removed': 'Actions Removed',
|
|
330
|
+
'iam.logic.removed.with.dependents': 'Removed {{name}} and {{count}} dependent action(s)',
|
|
331
|
+
'iam.logic.cancelled': 'Cancelled',
|
|
332
|
+
'iam.logic.no.changes.made': 'No changes made',
|
|
333
|
+
'iam.logic.prerequisites.satisfied': '[OK] Prerequisites Satisfied',
|
|
334
|
+
'iam.logic.all.required.selected': 'All required actions are already selected.\nYou can safely add this action.',
|
|
335
|
+
'iam.logic.prerequisites.required': 'Prerequisites Required ({{count}} missing)',
|
|
336
|
+
'iam.logic.click.to.auto.select': 'Click to auto-select required actions',
|
|
337
|
+
'iam.logic.satisfied': '(satisfied)',
|
|
338
|
+
'iam.logic.missing': '(missing)',
|
|
339
|
+
'iam.logic.unknown.action': 'Unknown Action',
|
|
340
|
+
'iam.logic.invalid.node': 'Invalid logic node',
|
|
341
|
+
'iam.logic.invalid': '(invalid)',
|
|
342
|
+
'iam.logic.click.to.toggle': 'Click to toggle',
|
|
343
|
+
// Pagination templates
|
|
344
|
+
'iam.pagination.roles.template': 'Showing {first} to {last} of {totalRecords} roles',
|
|
345
|
+
'iam.pagination.actions.template': 'Showing {first} to {last} of {totalRecords} actions',
|
|
346
|
+
'iam.pagination.users.template': 'Showing {first} to {last} of {totalRecords} users',
|
|
347
|
+
'iam.pagination.companies.template': 'Showing {first} to {last} of {totalRecords} companies',
|
|
348
|
+
'iam.pagination.branches.template': 'Showing {first} to {last} of {totalRecords} branches',
|
|
349
|
+
};
|
|
350
|
+
|
|
35
351
|
class RoleApiService extends ApiResourceService {
|
|
36
352
|
constructor() {
|
|
37
353
|
super('roles', inject(HttpClient), 'iam');
|
|
@@ -136,6 +452,10 @@ function evaluateLogicNodeWithMissing(node, selectedActionIds) {
|
|
|
136
452
|
class ActionPermissionLogicService {
|
|
137
453
|
confirmationService = inject(ConfirmationService);
|
|
138
454
|
messageService = inject(MessageService);
|
|
455
|
+
translateAdapter = inject(TRANSLATE_ADAPTER, { optional: true });
|
|
456
|
+
t(key, variables) {
|
|
457
|
+
return this.translateAdapter?.translate(key, variables) ?? key;
|
|
458
|
+
}
|
|
139
459
|
/** Handle checking an action with prerequisite validation (recursive deep scan) */
|
|
140
460
|
handleCheck(action, currentSelection, allActions, onUpdate, onCancel) {
|
|
141
461
|
// Validate prerequisites with RECURSIVE DEEP SCAN
|
|
@@ -196,19 +516,19 @@ class ActionPermissionLogicService {
|
|
|
196
516
|
const selectedActionIds = this.getSelectedIds(currentSelection);
|
|
197
517
|
selectedActionIds.delete(action.id);
|
|
198
518
|
const validationResult = validateActionPrerequisites(action, selectedActionIds, allActions);
|
|
199
|
-
const sanitizedActionName = this.sanitizeHtml(action.name ?? '
|
|
519
|
+
const sanitizedActionName = this.sanitizeHtml(action.name ?? this.t('iam.logic.unknown.action'));
|
|
200
520
|
const missingNames = validationResult.missingActions
|
|
201
|
-
.map((a) => this.sanitizeHtml(a.name ?? '
|
|
521
|
+
.map((a) => this.sanitizeHtml(a.name ?? this.t('iam.logic.unknown.action')))
|
|
202
522
|
.join(', ');
|
|
203
523
|
return `<li><strong>${sanitizedActionName}</strong> requires: ${missingNames}</li>`;
|
|
204
524
|
})
|
|
205
525
|
.join('');
|
|
206
526
|
this.confirmationService.confirm({
|
|
207
|
-
header: '
|
|
208
|
-
message:
|
|
527
|
+
header: this.t('iam.logic.validation.failed'),
|
|
528
|
+
message: `${this.t('iam.logic.validation.failed.message')}<br/><br/><ul class="pl-4">${errorList}</ul><br/>${this.t('iam.logic.validation.failed.prompt')}`,
|
|
209
529
|
icon: 'pi pi-exclamation-triangle',
|
|
210
|
-
acceptLabel: '
|
|
211
|
-
rejectLabel: '
|
|
530
|
+
acceptLabel: this.t('iam.logic.auto.fix'),
|
|
531
|
+
rejectLabel: this.t('shared.cancel'),
|
|
212
532
|
acceptIcon: 'pi pi-trash',
|
|
213
533
|
rejectIcon: 'pi pi-times',
|
|
214
534
|
acceptButtonStyleClass: 'p-button-warning',
|
|
@@ -223,15 +543,15 @@ class ActionPermissionLogicService {
|
|
|
223
543
|
onUpdate(selMap);
|
|
224
544
|
this.messageService.add({
|
|
225
545
|
severity: 'warning',
|
|
226
|
-
summary: '
|
|
227
|
-
detail:
|
|
546
|
+
summary: this.t('iam.logic.invalid.actions.removed'),
|
|
547
|
+
detail: this.t('iam.logic.removed.actions.detail', { count: invalidActions.length }),
|
|
228
548
|
});
|
|
229
549
|
},
|
|
230
550
|
reject: () => {
|
|
231
551
|
this.messageService.add({
|
|
232
552
|
severity: 'info',
|
|
233
|
-
summary: '
|
|
234
|
-
detail: '
|
|
553
|
+
summary: this.t('iam.logic.save.cancelled'),
|
|
554
|
+
detail: this.t('iam.logic.fix.prerequisites.manually'),
|
|
235
555
|
});
|
|
236
556
|
},
|
|
237
557
|
});
|
|
@@ -244,13 +564,13 @@ class ActionPermissionLogicService {
|
|
|
244
564
|
const selectedActionIds = this.getSelectedIds(currentSelection);
|
|
245
565
|
const validationResult = validateActionPrerequisites(action, selectedActionIds, allActions);
|
|
246
566
|
if (validationResult.valid) {
|
|
247
|
-
return '
|
|
567
|
+
return `${this.t('iam.logic.prerequisites.satisfied')}\n\n${this.t('iam.logic.all.required.selected')}`;
|
|
248
568
|
}
|
|
249
569
|
const allMissingActions = this.getAllMissingPrerequisitesRecursive(action, currentSelection, allActions);
|
|
250
570
|
const logicTree = this.buildTooltipLogicTree(action.permissionLogic, currentSelection, allActions, 0);
|
|
251
571
|
const missingCount = allMissingActions.length;
|
|
252
|
-
const header = `⚠
|
|
253
|
-
const hint =
|
|
572
|
+
const header = `⚠ ${this.t('iam.logic.prerequisites.required', { count: missingCount })}`;
|
|
573
|
+
const hint = `\n\n💡 ${this.t('iam.logic.click.to.auto.select')}`;
|
|
254
574
|
return `${header}\n\n${logicTree}${hint}`;
|
|
255
575
|
}
|
|
256
576
|
/** Build dynamic logic tree message with AND/OR operators and nesting */
|
|
@@ -314,17 +634,19 @@ class ActionPermissionLogicService {
|
|
|
314
634
|
? this.calculateSmartSelection(action.permissionLogic, missingActions, currentSelection, allActions)
|
|
315
635
|
: missingActions;
|
|
316
636
|
const selectionCount = actionsToSelect.length;
|
|
317
|
-
const sanitizedActionName = this.sanitizeHtml(action.name ?? '
|
|
318
|
-
const acceptLabel = selectionCount === 0 ? '
|
|
637
|
+
const sanitizedActionName = this.sanitizeHtml(action.name ?? this.t('iam.logic.unknown.action'));
|
|
638
|
+
const acceptLabel = selectionCount === 0 ? this.t('iam.logic.select.action.label') : this.t('iam.logic.auto.select.actions');
|
|
319
639
|
const detailMessage = selectionCount === 0
|
|
320
|
-
? '
|
|
321
|
-
:
|
|
640
|
+
? this.t('iam.logic.action.selected.detail')
|
|
641
|
+
: this.t('iam.logic.auto.selected.detail', { count: selectionCount });
|
|
642
|
+
const suffix = selectionCount < missingActions.length ? this.t('iam.logic.minimum.required') : '';
|
|
643
|
+
const autoSelectPrompt = this.t('iam.logic.auto.select.prompt', { count: selectionCount, suffix });
|
|
322
644
|
this.confirmationService.confirm({
|
|
323
|
-
header: '
|
|
324
|
-
message: `<strong>${sanitizedActionName}</strong> requires
|
|
645
|
+
header: this.t('iam.logic.missing.prerequisites'),
|
|
646
|
+
message: `<strong>${sanitizedActionName}</strong> ${this.t('iam.logic.requires.conditions')}<br/><br/>${logicMessage}<br/><br/><strong>${autoSelectPrompt}</strong><br/>${this.t('iam.logic.would.you.continue')}`,
|
|
325
647
|
icon: 'pi pi-exclamation-triangle',
|
|
326
648
|
acceptLabel,
|
|
327
|
-
rejectLabel: '
|
|
649
|
+
rejectLabel: this.t('shared.cancel'),
|
|
328
650
|
acceptIcon: 'pi pi-check',
|
|
329
651
|
rejectIcon: 'pi pi-times',
|
|
330
652
|
closeOnEscape: false,
|
|
@@ -338,7 +660,7 @@ class ActionPermissionLogicService {
|
|
|
338
660
|
onUpdate(selMap);
|
|
339
661
|
this.messageService.add({
|
|
340
662
|
severity: 'info',
|
|
341
|
-
summary: '
|
|
663
|
+
summary: this.t('iam.logic.actions.selected.summary'),
|
|
342
664
|
detail: detailMessage,
|
|
343
665
|
});
|
|
344
666
|
},
|
|
@@ -346,8 +668,8 @@ class ActionPermissionLogicService {
|
|
|
346
668
|
onCancel(previousState);
|
|
347
669
|
this.messageService.add({
|
|
348
670
|
severity: 'info',
|
|
349
|
-
summary: '
|
|
350
|
-
detail: '
|
|
671
|
+
summary: this.t('iam.logic.selection.cancelled'),
|
|
672
|
+
detail: this.t('iam.logic.action.not.added'),
|
|
351
673
|
});
|
|
352
674
|
},
|
|
353
675
|
});
|
|
@@ -356,29 +678,27 @@ class ActionPermissionLogicService {
|
|
|
356
678
|
if (!action.id)
|
|
357
679
|
return;
|
|
358
680
|
const alternatives = this.findAlternatives(action.id, affectedActions, currentSelection);
|
|
359
|
-
const sanitizedActionName = this.sanitizeHtml(action.name ?? '
|
|
360
|
-
let message = `<strong>${sanitizedActionName}</strong>
|
|
681
|
+
const sanitizedActionName = this.sanitizeHtml(action.name ?? this.t('iam.logic.unknown.action'));
|
|
682
|
+
let message = `<strong>${sanitizedActionName}</strong> ${this.t('iam.logic.required.by.actions')}<br/><br/><ul class="pl-4">`;
|
|
361
683
|
affectedActions.forEach((a) => {
|
|
362
|
-
const sanitizedName = this.sanitizeHtml(a.name ?? '
|
|
684
|
+
const sanitizedName = this.sanitizeHtml(a.name ?? this.t('iam.logic.unknown.action'));
|
|
363
685
|
message += `<li>${sanitizedName}</li>`;
|
|
364
686
|
});
|
|
365
687
|
message += '</ul><br/>';
|
|
366
688
|
if (alternatives.length > 0) {
|
|
367
|
-
message += '
|
|
368
|
-
message +=
|
|
369
|
-
'<em>Would you like to automatically switch to alternatives?</em>';
|
|
689
|
+
message += `<strong>${this.t('iam.logic.alternatives.available')}</strong><br/><br/>`;
|
|
690
|
+
message += `<em>${this.t('iam.logic.switch.to.alternatives')}</em>`;
|
|
370
691
|
}
|
|
371
692
|
else {
|
|
372
|
-
message +=
|
|
373
|
-
|
|
374
|
-
message += 'Would you like to continue?';
|
|
693
|
+
message += `<em>${this.t('iam.logic.remove.dependents')}</em><br/><br/>`;
|
|
694
|
+
message += this.t('iam.logic.would.you.continue');
|
|
375
695
|
}
|
|
376
696
|
this.confirmationService.confirm({
|
|
377
|
-
header: '
|
|
697
|
+
header: this.t('iam.logic.dependency.warning'),
|
|
378
698
|
message,
|
|
379
699
|
icon: 'pi pi-exclamation-triangle',
|
|
380
|
-
acceptLabel: alternatives.length > 0 ? '
|
|
381
|
-
rejectLabel: '
|
|
700
|
+
acceptLabel: alternatives.length > 0 ? this.t('iam.logic.use.alternatives') : this.t('iam.logic.remove.all'),
|
|
701
|
+
rejectLabel: this.t('shared.cancel'),
|
|
382
702
|
acceptIcon: 'pi pi-check',
|
|
383
703
|
rejectIcon: 'pi pi-times',
|
|
384
704
|
closeOnEscape: false,
|
|
@@ -393,8 +713,8 @@ class ActionPermissionLogicService {
|
|
|
393
713
|
selMap[action.id] = false;
|
|
394
714
|
this.messageService.add({
|
|
395
715
|
severity: 'success',
|
|
396
|
-
summary: '
|
|
397
|
-
detail: '
|
|
716
|
+
summary: this.t('iam.logic.alternatives.applied'),
|
|
717
|
+
detail: this.t('iam.logic.switched.to.alternatives'),
|
|
398
718
|
});
|
|
399
719
|
}
|
|
400
720
|
else {
|
|
@@ -405,8 +725,8 @@ class ActionPermissionLogicService {
|
|
|
405
725
|
});
|
|
406
726
|
this.messageService.add({
|
|
407
727
|
severity: 'warn',
|
|
408
|
-
summary: '
|
|
409
|
-
detail:
|
|
728
|
+
summary: this.t('iam.logic.actions.removed'),
|
|
729
|
+
detail: this.t('iam.logic.removed.with.dependents', { name: action.name ?? '', count: affectedActions.length }),
|
|
410
730
|
});
|
|
411
731
|
}
|
|
412
732
|
onUpdate(selMap);
|
|
@@ -414,8 +734,8 @@ class ActionPermissionLogicService {
|
|
|
414
734
|
reject: () => {
|
|
415
735
|
this.messageService.add({
|
|
416
736
|
severity: 'info',
|
|
417
|
-
summary: '
|
|
418
|
-
detail: '
|
|
737
|
+
summary: this.t('iam.logic.cancelled'),
|
|
738
|
+
detail: this.t('iam.logic.no.changes.made'),
|
|
419
739
|
});
|
|
420
740
|
},
|
|
421
741
|
});
|
|
@@ -517,19 +837,19 @@ class ActionPermissionLogicService {
|
|
|
517
837
|
return new Set();
|
|
518
838
|
}
|
|
519
839
|
buildSimpleMessage(missingActions) {
|
|
520
|
-
return `<ul class="pl-4">${missingActions.map((a) => `<li>${this.sanitizeHtml(a.name ?? '
|
|
840
|
+
return `<ul class="pl-4">${missingActions.map((a) => `<li>${this.sanitizeHtml(a.name ?? this.t('iam.logic.unknown.action'))}</li>`).join('')}</ul>`;
|
|
521
841
|
}
|
|
522
842
|
formatLogicNode(node, selectedIds, actionMap, depth) {
|
|
523
843
|
const indent = ' '.repeat(depth);
|
|
524
844
|
if (node.type === 'action' && node.actionId) {
|
|
525
845
|
const action = actionMap.get(node.actionId);
|
|
526
|
-
const actionName = this.sanitizeHtml(action?.name || '
|
|
846
|
+
const actionName = this.sanitizeHtml(action?.name || this.t('iam.logic.unknown.action'));
|
|
527
847
|
const isSelected = selectedIds.has(node.actionId);
|
|
528
848
|
if (isSelected) {
|
|
529
|
-
return `${indent}<span style="color: #10b981; font-weight: 500;">✓ ${actionName}</span> <em style="color: #059669;"
|
|
849
|
+
return `${indent}<span style="color: #10b981; font-weight: 500;">✓ ${actionName}</span> <em style="color: #059669;">${this.t('iam.logic.satisfied')}</em>`;
|
|
530
850
|
}
|
|
531
851
|
else {
|
|
532
|
-
return `${indent}<span style="color: #ef4444;">✗ ${actionName}</span> <em style="color: #dc2626;"
|
|
852
|
+
return `${indent}<span style="color: #ef4444;">✗ ${actionName}</span> <em style="color: #dc2626;">${this.t('iam.logic.missing')}</em>`;
|
|
533
853
|
}
|
|
534
854
|
}
|
|
535
855
|
if (node.type === 'group' && node.children) {
|
|
@@ -546,7 +866,7 @@ class ActionPermissionLogicService {
|
|
|
546
866
|
});
|
|
547
867
|
return lines.join('<br/>');
|
|
548
868
|
}
|
|
549
|
-
return `${indent}<em style="color: #9ca3af;"
|
|
869
|
+
return `${indent}<em style="color: #9ca3af;">${this.t('iam.logic.invalid.node')}</em>`;
|
|
550
870
|
}
|
|
551
871
|
/** Build clean text-based logic tree for tooltips */
|
|
552
872
|
buildTooltipLogicTree(node, currentSelection, allActions, depth) {
|
|
@@ -555,7 +875,7 @@ class ActionPermissionLogicService {
|
|
|
555
875
|
const actionMap = new Map(allActions.map((a) => [a.id, a]));
|
|
556
876
|
if (node.type === 'action' && node.actionId) {
|
|
557
877
|
const action = actionMap.get(node.actionId);
|
|
558
|
-
const actionName = action?.name || '
|
|
878
|
+
const actionName = action?.name || this.t('iam.logic.unknown.action');
|
|
559
879
|
const isSelected = selectedIds.has(node.actionId);
|
|
560
880
|
if (isSelected) {
|
|
561
881
|
return `${indent}✓ ${actionName}`;
|
|
@@ -579,7 +899,7 @@ class ActionPermissionLogicService {
|
|
|
579
899
|
});
|
|
580
900
|
return lines.join('\n');
|
|
581
901
|
}
|
|
582
|
-
return `${indent}(invalid)`;
|
|
902
|
+
return `${indent}${this.t('iam.logic.invalid')}`;
|
|
583
903
|
}
|
|
584
904
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ActionPermissionLogicService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
585
905
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ActionPermissionLogicService, providedIn: 'root' });
|
|
@@ -801,16 +1121,16 @@ class LogicBuilderComponent {
|
|
|
801
1121
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: LogicBuilderComponent, isStandalone: true, selector: "lib-logic-builder", inputs: { logic: { classPropertyName: "logic", publicName: "logic", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { logicChange: "logicChange" }, ngImport: i0, template: `
|
|
802
1122
|
<div class="logic-builder">
|
|
803
1123
|
<div class="flex justify-between items-center mb-3">
|
|
804
|
-
<h4 class="text-sm font-semibold m-0">
|
|
1124
|
+
<h4 class="text-sm font-semibold m-0">{{ 'iam.logic.title' | translate }}</h4>
|
|
805
1125
|
@if (!builderLogic()) {
|
|
806
1126
|
<p-button
|
|
807
|
-
label="
|
|
1127
|
+
[label]="'iam.logic.add.logic' | translate"
|
|
808
1128
|
icon="pi pi-plus"
|
|
809
1129
|
size="small"
|
|
810
1130
|
(onClick)="initializeLogic()" />
|
|
811
1131
|
} @else {
|
|
812
1132
|
<p-button
|
|
813
|
-
label="
|
|
1133
|
+
[label]="'iam.logic.clear.logic' | translate"
|
|
814
1134
|
icon="pi pi-trash"
|
|
815
1135
|
size="small"
|
|
816
1136
|
severity="danger"
|
|
@@ -822,7 +1142,7 @@ class LogicBuilderComponent {
|
|
|
822
1142
|
@if (builderLogic()) {
|
|
823
1143
|
<div class="border border-surface rounded p-3 bg-surface-50">
|
|
824
1144
|
<div class="mb-3 text-sm text-muted-color">
|
|
825
|
-
|
|
1145
|
+
{{ 'iam.logic.description' | translate }}
|
|
826
1146
|
</div>
|
|
827
1147
|
|
|
828
1148
|
<!-- Root Node -->
|
|
@@ -846,10 +1166,10 @@ class LogicBuilderComponent {
|
|
|
846
1166
|
class="operator-badge"
|
|
847
1167
|
[ngClass]="node.operator === 'AND' ? 'and' : 'or'"
|
|
848
1168
|
(click)="toggleOperator(node.id)"
|
|
849
|
-
title="
|
|
1169
|
+
[title]="'iam.logic.click.to.toggle' | translate">
|
|
850
1170
|
{{ node.operator }}
|
|
851
1171
|
</span>
|
|
852
|
-
<span class="text-muted-color text-xs">({{ node.children?.length || 0 }}
|
|
1172
|
+
<span class="text-muted-color text-xs">({{ 'iam.logic.conditions' | translate: { count: node.children?.length || 0 } }})</span>
|
|
853
1173
|
}
|
|
854
1174
|
|
|
855
1175
|
@if (node.type === 'action') {
|
|
@@ -858,7 +1178,7 @@ class LogicBuilderComponent {
|
|
|
858
1178
|
class="action-select flex-1 p-2 border border-surface rounded text-sm"
|
|
859
1179
|
[ngModel]="node.actionId"
|
|
860
1180
|
(ngModelChange)="updateActionId(node.id, $event)">
|
|
861
|
-
<option [value]="null">
|
|
1181
|
+
<option [value]="null">{{ 'iam.logic.select.action' | translate }} ({{ 'iam.logic.actions.available' | translate: { count: actions().length } }})</option>
|
|
862
1182
|
@for (action of actions(); track action.id) {
|
|
863
1183
|
<option [ngValue]="action.id">{{ action.name }}</option>
|
|
864
1184
|
}
|
|
@@ -873,7 +1193,7 @@ class LogicBuilderComponent {
|
|
|
873
1193
|
severity="danger"
|
|
874
1194
|
size="small"
|
|
875
1195
|
(onClick)="removeNode(node.id)"
|
|
876
|
-
[pTooltip]="'
|
|
1196
|
+
[pTooltip]="'iam.logic.remove' | translate" />
|
|
877
1197
|
</div>
|
|
878
1198
|
</div>
|
|
879
1199
|
|
|
@@ -889,16 +1209,16 @@ class LogicBuilderComponent {
|
|
|
889
1209
|
<!-- Add child buttons for group nodes -->
|
|
890
1210
|
@if (node.type === 'group') {
|
|
891
1211
|
<div class="mt-3 p-3 bg-surface-50 rounded border border-dashed border-surface">
|
|
892
|
-
<div class="text-xs font-semibold text-muted-color mb-2">
|
|
1212
|
+
<div class="text-xs font-semibold text-muted-color mb-2">{{ 'iam.logic.add.condition' | translate }}</div>
|
|
893
1213
|
<div class="flex gap-2 flex-wrap">
|
|
894
1214
|
<p-button
|
|
895
|
-
label="
|
|
1215
|
+
[label]="'iam.logic.group' | translate"
|
|
896
1216
|
icon="pi pi-sitemap"
|
|
897
1217
|
size="small"
|
|
898
1218
|
[outlined]="true"
|
|
899
1219
|
(onClick)="addChildNode(node.id, 'group')" />
|
|
900
1220
|
<p-button
|
|
901
|
-
label="
|
|
1221
|
+
[label]="'iam.logic.action' | translate"
|
|
902
1222
|
icon="pi pi-bolt"
|
|
903
1223
|
size="small"
|
|
904
1224
|
severity="success"
|
|
@@ -909,23 +1229,23 @@ class LogicBuilderComponent {
|
|
|
909
1229
|
}
|
|
910
1230
|
</div>
|
|
911
1231
|
</ng-template>
|
|
912
|
-
`, isInline: true, styles: [":host{display:block}.node-type{display:inline-flex;align-items:center;padding:.25rem .5rem;border-radius:.25rem;font-weight:600;font-size:.75rem;text-transform:uppercase}.node-type.group{background-color:var(--p-blue-100, #dbeafe);color:var(--p-blue-700, #1e40af)}.node-type.action{background-color:var(--p-green-100, #d1fae5);color:var(--p-green-700, #065f46)}:host-context(.p-dark) .node-type.group{background-color:#3b82f633;color:var(--p-blue-400, #60a5fa)}:host-context(.p-dark) .node-type.action{background-color:#22c55e33;color:var(--p-green-400, #4ade80)}.operator-badge{display:inline-flex;align-items:center;padding:.125rem .5rem;border-radius:9999px;font-weight:600;font-size:.75rem;cursor:pointer;transition:opacity .2s}.operator-badge.and{background-color:var(--p-yellow-100, #fef3c7);color:var(--p-yellow-700, #92400e)}.operator-badge.or{background-color:var(--p-indigo-100, #e0e7ff);color:var(--p-indigo-700, #3730a3)}:host-context(.p-dark) .operator-badge.and{background-color:#eab30833;color:var(--p-yellow-400, #facc15)}:host-context(.p-dark) .operator-badge.or{background-color:#6366f133;color:var(--p-indigo-400, #818cf8)}.operator-badge:hover{opacity:.8}.action-select{background-color:var(--p-surface-0, #ffffff);color:var(--p-text-color, #1f2937)}:host-context(.p-dark) .action-select{background-color:var(--p-surface-900, #1f2937);color:var(--p-text-color, #f9fafb)}.action-select:focus{outline:none;border-color:var(--p-primary-color, #3b82f6)}\n"], dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }
|
|
1232
|
+
`, isInline: true, styles: [":host{display:block}.node-type{display:inline-flex;align-items:center;padding:.25rem .5rem;border-radius:.25rem;font-weight:600;font-size:.75rem;text-transform:uppercase}.node-type.group{background-color:var(--p-blue-100, #dbeafe);color:var(--p-blue-700, #1e40af)}.node-type.action{background-color:var(--p-green-100, #d1fae5);color:var(--p-green-700, #065f46)}:host-context(.p-dark) .node-type.group{background-color:#3b82f633;color:var(--p-blue-400, #60a5fa)}:host-context(.p-dark) .node-type.action{background-color:#22c55e33;color:var(--p-green-400, #4ade80)}.operator-badge{display:inline-flex;align-items:center;padding:.125rem .5rem;border-radius:9999px;font-weight:600;font-size:.75rem;cursor:pointer;transition:opacity .2s}.operator-badge.and{background-color:var(--p-yellow-100, #fef3c7);color:var(--p-yellow-700, #92400e)}.operator-badge.or{background-color:var(--p-indigo-100, #e0e7ff);color:var(--p-indigo-700, #3730a3)}:host-context(.p-dark) .operator-badge.and{background-color:#eab30833;color:var(--p-yellow-400, #facc15)}:host-context(.p-dark) .operator-badge.or{background-color:#6366f133;color:var(--p-indigo-400, #818cf8)}.operator-badge:hover{opacity:.8}.action-select{background-color:var(--p-surface-0, #ffffff);color:var(--p-text-color, #1f2937)}:host-context(.p-dark) .action-select{background-color:var(--p-surface-900, #1f2937);color:var(--p-text-color, #f9fafb)}.action-select:focus{outline:none;border-color:var(--p-primary-color, #3b82f6)}\n"], dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
913
1233
|
}
|
|
914
1234
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: LogicBuilderComponent, decorators: [{
|
|
915
1235
|
type: Component,
|
|
916
|
-
args: [{ selector: 'lib-logic-builder', imports: [AngularModule, PrimeModule
|
|
1236
|
+
args: [{ selector: 'lib-logic-builder', imports: [AngularModule, PrimeModule, TranslatePipe], template: `
|
|
917
1237
|
<div class="logic-builder">
|
|
918
1238
|
<div class="flex justify-between items-center mb-3">
|
|
919
|
-
<h4 class="text-sm font-semibold m-0">
|
|
1239
|
+
<h4 class="text-sm font-semibold m-0">{{ 'iam.logic.title' | translate }}</h4>
|
|
920
1240
|
@if (!builderLogic()) {
|
|
921
1241
|
<p-button
|
|
922
|
-
label="
|
|
1242
|
+
[label]="'iam.logic.add.logic' | translate"
|
|
923
1243
|
icon="pi pi-plus"
|
|
924
1244
|
size="small"
|
|
925
1245
|
(onClick)="initializeLogic()" />
|
|
926
1246
|
} @else {
|
|
927
1247
|
<p-button
|
|
928
|
-
label="
|
|
1248
|
+
[label]="'iam.logic.clear.logic' | translate"
|
|
929
1249
|
icon="pi pi-trash"
|
|
930
1250
|
size="small"
|
|
931
1251
|
severity="danger"
|
|
@@ -937,7 +1257,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
937
1257
|
@if (builderLogic()) {
|
|
938
1258
|
<div class="border border-surface rounded p-3 bg-surface-50">
|
|
939
1259
|
<div class="mb-3 text-sm text-muted-color">
|
|
940
|
-
|
|
1260
|
+
{{ 'iam.logic.description' | translate }}
|
|
941
1261
|
</div>
|
|
942
1262
|
|
|
943
1263
|
<!-- Root Node -->
|
|
@@ -961,10 +1281,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
961
1281
|
class="operator-badge"
|
|
962
1282
|
[ngClass]="node.operator === 'AND' ? 'and' : 'or'"
|
|
963
1283
|
(click)="toggleOperator(node.id)"
|
|
964
|
-
title="
|
|
1284
|
+
[title]="'iam.logic.click.to.toggle' | translate">
|
|
965
1285
|
{{ node.operator }}
|
|
966
1286
|
</span>
|
|
967
|
-
<span class="text-muted-color text-xs">({{ node.children?.length || 0 }}
|
|
1287
|
+
<span class="text-muted-color text-xs">({{ 'iam.logic.conditions' | translate: { count: node.children?.length || 0 } }})</span>
|
|
968
1288
|
}
|
|
969
1289
|
|
|
970
1290
|
@if (node.type === 'action') {
|
|
@@ -973,7 +1293,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
973
1293
|
class="action-select flex-1 p-2 border border-surface rounded text-sm"
|
|
974
1294
|
[ngModel]="node.actionId"
|
|
975
1295
|
(ngModelChange)="updateActionId(node.id, $event)">
|
|
976
|
-
<option [value]="null">
|
|
1296
|
+
<option [value]="null">{{ 'iam.logic.select.action' | translate }} ({{ 'iam.logic.actions.available' | translate: { count: actions().length } }})</option>
|
|
977
1297
|
@for (action of actions(); track action.id) {
|
|
978
1298
|
<option [ngValue]="action.id">{{ action.name }}</option>
|
|
979
1299
|
}
|
|
@@ -988,7 +1308,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
988
1308
|
severity="danger"
|
|
989
1309
|
size="small"
|
|
990
1310
|
(onClick)="removeNode(node.id)"
|
|
991
|
-
[pTooltip]="'
|
|
1311
|
+
[pTooltip]="'iam.logic.remove' | translate" />
|
|
992
1312
|
</div>
|
|
993
1313
|
</div>
|
|
994
1314
|
|
|
@@ -1004,16 +1324,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1004
1324
|
<!-- Add child buttons for group nodes -->
|
|
1005
1325
|
@if (node.type === 'group') {
|
|
1006
1326
|
<div class="mt-3 p-3 bg-surface-50 rounded border border-dashed border-surface">
|
|
1007
|
-
<div class="text-xs font-semibold text-muted-color mb-2">
|
|
1327
|
+
<div class="text-xs font-semibold text-muted-color mb-2">{{ 'iam.logic.add.condition' | translate }}</div>
|
|
1008
1328
|
<div class="flex gap-2 flex-wrap">
|
|
1009
1329
|
<p-button
|
|
1010
|
-
label="
|
|
1330
|
+
[label]="'iam.logic.group' | translate"
|
|
1011
1331
|
icon="pi pi-sitemap"
|
|
1012
1332
|
size="small"
|
|
1013
1333
|
[outlined]="true"
|
|
1014
1334
|
(onClick)="addChildNode(node.id, 'group')" />
|
|
1015
1335
|
<p-button
|
|
1016
|
-
label="
|
|
1336
|
+
[label]="'iam.logic.action' | translate"
|
|
1017
1337
|
icon="pi pi-bolt"
|
|
1018
1338
|
size="small"
|
|
1019
1339
|
severity="success"
|
|
@@ -1110,7 +1430,6 @@ function convertActionToTreeNode(actions) {
|
|
|
1110
1430
|
* - Pre-save validation with auto-fix
|
|
1111
1431
|
*
|
|
1112
1432
|
* **Performance:**
|
|
1113
|
-
* - OnPush change detection
|
|
1114
1433
|
* - Computed signals for reactive updates
|
|
1115
1434
|
* - Memoized prerequisite validation
|
|
1116
1435
|
* - AbortController for request cancellation
|
|
@@ -1130,6 +1449,10 @@ class RoleActionSelectorComponent {
|
|
|
1130
1449
|
permissionApi = inject(PermissionApiService);
|
|
1131
1450
|
messageService = inject(MessageService);
|
|
1132
1451
|
permissionLogic = inject(ActionPermissionLogicService);
|
|
1452
|
+
translateAdapter = inject(TRANSLATE_ADAPTER, { optional: true });
|
|
1453
|
+
translate(key, vars) {
|
|
1454
|
+
return this.translateAdapter?.translate(key, vars) ?? key;
|
|
1455
|
+
}
|
|
1133
1456
|
// State - Role Selection
|
|
1134
1457
|
selectedRoleId = signal(undefined, ...(ngDevMode ? [{ debugName: "selectedRoleId" }] : []));
|
|
1135
1458
|
roles = signal([], ...(ngDevMode ? [{ debugName: "roles" }] : []));
|
|
@@ -1288,15 +1611,15 @@ class RoleActionSelectorComponent {
|
|
|
1288
1611
|
const prerequisiteInfo = this.permissionLogic.getPrerequisiteTooltip(action, selMap, this.actions());
|
|
1289
1612
|
if (prerequisiteInfo) {
|
|
1290
1613
|
const actionHint = isCurrentlySelected
|
|
1291
|
-
?
|
|
1292
|
-
:
|
|
1614
|
+
? `\n\n---\n[${this.translate('shared.remove')}] ${this.translate('iam.tooltip.remove.action')}`
|
|
1615
|
+
: `\n\n---\n[${this.translate('shared.add')}] ${this.translate('iam.tooltip.add.action')}`;
|
|
1293
1616
|
return `${prerequisiteInfo}${actionHint}`;
|
|
1294
1617
|
}
|
|
1295
1618
|
}
|
|
1296
1619
|
if (isCurrentlySelected) {
|
|
1297
|
-
return '
|
|
1620
|
+
return `[${this.translate('shared.assigned')}] ${this.translate('iam.tooltip.assigned.to.role')}\n\n[${this.translate('shared.remove')}] ${this.translate('iam.tooltip.click.to.remove.role')}`;
|
|
1298
1621
|
}
|
|
1299
|
-
return '
|
|
1622
|
+
return `[${this.translate('shared.add')}] ${this.translate('iam.tooltip.click.to.assign.role')}`;
|
|
1300
1623
|
}
|
|
1301
1624
|
/**
|
|
1302
1625
|
* Check if action has unmet prerequisites
|
|
@@ -1360,8 +1683,8 @@ class RoleActionSelectorComponent {
|
|
|
1360
1683
|
}));
|
|
1361
1684
|
this.messageService.add({
|
|
1362
1685
|
severity: 'success',
|
|
1363
|
-
summary: '
|
|
1364
|
-
detail: response?.data?.message || '
|
|
1686
|
+
summary: this.translate('shared.success'),
|
|
1687
|
+
detail: response?.data?.message || this.translate('iam.permission.role.permissions.updated'),
|
|
1365
1688
|
});
|
|
1366
1689
|
// Update baseline
|
|
1367
1690
|
this._initialSelection.set({ ...this.selectionMap() });
|
|
@@ -1400,14 +1723,14 @@ class RoleActionSelectorComponent {
|
|
|
1400
1723
|
<div class="mb-4">
|
|
1401
1724
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
1402
1725
|
<div>
|
|
1403
|
-
<label class="block font-semibold mb-2">
|
|
1726
|
+
<label class="block font-semibold mb-2">{{ 'iam.permission.select.role' | translate }}</label>
|
|
1404
1727
|
<p-select
|
|
1405
1728
|
[ngModel]="selectedRoleId()"
|
|
1406
1729
|
(ngModelChange)="selectedRoleId.set($event)"
|
|
1407
1730
|
[options]="roles()"
|
|
1408
1731
|
optionLabel="name"
|
|
1409
1732
|
optionValue="id"
|
|
1410
|
-
placeholder="
|
|
1733
|
+
[placeholder]="'iam.permission.select.role.placeholder' | translate"
|
|
1411
1734
|
[showClear]="true"
|
|
1412
1735
|
[filter]="true"
|
|
1413
1736
|
styleClass="w-full"
|
|
@@ -1433,14 +1756,14 @@ class RoleActionSelectorComponent {
|
|
|
1433
1756
|
class="flex flex-col md:flex-row justify-between items-start md:items-center gap-3 mb-4"
|
|
1434
1757
|
>
|
|
1435
1758
|
<div>
|
|
1436
|
-
<h5 class="m-0 mb-1">
|
|
1759
|
+
<h5 class="m-0 mb-1">{{ 'iam.permission.action.permissions' | translate }}</h5>
|
|
1437
1760
|
<p class="text-sm text-muted-color m-0">
|
|
1438
|
-
{{ actions().length }}
|
|
1761
|
+
{{ 'iam.permission.actions.available' | translate: { count: actions().length } }}
|
|
1439
1762
|
</p>
|
|
1440
1763
|
</div>
|
|
1441
1764
|
<div class="flex flex-wrap gap-2">
|
|
1442
1765
|
<p-button
|
|
1443
|
-
label="
|
|
1766
|
+
[label]="'shared.select.all' | translate"
|
|
1444
1767
|
icon="pi pi-check"
|
|
1445
1768
|
[outlined]="true"
|
|
1446
1769
|
size="small"
|
|
@@ -1448,7 +1771,7 @@ class RoleActionSelectorComponent {
|
|
|
1448
1771
|
(onClick)="selectAll()"
|
|
1449
1772
|
/>
|
|
1450
1773
|
<p-button
|
|
1451
|
-
label="
|
|
1774
|
+
[label]="'shared.deselect.all' | translate"
|
|
1452
1775
|
icon="pi pi-times"
|
|
1453
1776
|
[outlined]="true"
|
|
1454
1777
|
size="small"
|
|
@@ -1457,7 +1780,7 @@ class RoleActionSelectorComponent {
|
|
|
1457
1780
|
/>
|
|
1458
1781
|
<p-button
|
|
1459
1782
|
*hasPermission="ROLE_ACTION_PERMISSIONS.ASSIGN"
|
|
1460
|
-
label="
|
|
1783
|
+
[label]="'shared.save.changes' | translate"
|
|
1461
1784
|
icon="pi pi-save"
|
|
1462
1785
|
[disabled]="!canSave()"
|
|
1463
1786
|
[loading]="saving()"
|
|
@@ -1474,12 +1797,9 @@ class RoleActionSelectorComponent {
|
|
|
1474
1797
|
<div class="flex items-start gap-2">
|
|
1475
1798
|
<i class="pi pi-exclamation-triangle text-xl"></i>
|
|
1476
1799
|
<div class="flex-1">
|
|
1477
|
-
<span class="font-semibold">
|
|
1800
|
+
<span class="font-semibold">{{ 'iam.validation.warning.title' | translate }}:</span>
|
|
1478
1801
|
<p class="text-sm mt-1 mb-0">
|
|
1479
|
-
{{ invalidActionsCount() }}
|
|
1480
|
-
action{{ invalidActionsCount() > 1 ? 's have' : ' has' }}
|
|
1481
|
-
unmet prerequisites. Fix before saving or use auto-fix on
|
|
1482
|
-
save.
|
|
1802
|
+
{{ (invalidActionsCount() > 1 ? 'iam.validation.unmet.prerequisites.plural' : 'iam.validation.unmet.prerequisites.singular') | translate: { count: invalidActionsCount() } }}
|
|
1483
1803
|
</p>
|
|
1484
1804
|
</div>
|
|
1485
1805
|
</div>
|
|
@@ -1501,14 +1821,14 @@ class RoleActionSelectorComponent {
|
|
|
1501
1821
|
[ngModel]="allSelected()"
|
|
1502
1822
|
[binary]="true"
|
|
1503
1823
|
(ngModelChange)="toggleAll()"
|
|
1504
|
-
pTooltip="
|
|
1824
|
+
[pTooltip]="'shared.select.deselect.all' | translate"
|
|
1505
1825
|
tooltipPosition="top"
|
|
1506
1826
|
/>
|
|
1507
1827
|
</th>
|
|
1508
|
-
<th>
|
|
1509
|
-
<th class="hidden md:table-cell">
|
|
1510
|
-
<th>
|
|
1511
|
-
<th class="hidden lg:table-cell">
|
|
1828
|
+
<th>{{ 'shared.name' | translate }}</th>
|
|
1829
|
+
<th class="hidden md:table-cell">{{ 'shared.code' | translate }}</th>
|
|
1830
|
+
<th>{{ 'iam.action.type' | translate }}</th>
|
|
1831
|
+
<th class="hidden lg:table-cell">{{ 'iam.permission.requirements' | translate }}</th>
|
|
1512
1832
|
</tr>
|
|
1513
1833
|
</ng-template>
|
|
1514
1834
|
<ng-template #body let-rowNode let-rowData="rowData">
|
|
@@ -1529,7 +1849,7 @@ class RoleActionSelectorComponent {
|
|
|
1529
1849
|
@if (hasUnmetPrerequisites(rowData)) {
|
|
1530
1850
|
<i
|
|
1531
1851
|
class="pi pi-exclamation-triangle text-orange-500"
|
|
1532
|
-
pTooltip="
|
|
1852
|
+
[pTooltip]="'iam.validation.unmet.prerequisites.tooltip' | translate"
|
|
1533
1853
|
tooltipPosition="top"
|
|
1534
1854
|
></i>
|
|
1535
1855
|
}
|
|
@@ -1546,7 +1866,7 @@ class RoleActionSelectorComponent {
|
|
|
1546
1866
|
</td>
|
|
1547
1867
|
<td class="hidden lg:table-cell">
|
|
1548
1868
|
@if (rowData.permissionLogic) {
|
|
1549
|
-
<span class="text-sm text-muted-color">
|
|
1869
|
+
<span class="text-sm text-muted-color">{{ 'iam.permission.has.prerequisites' | translate }}</span>
|
|
1550
1870
|
} @else {
|
|
1551
1871
|
<span class="text-muted-color">-</span>
|
|
1552
1872
|
}
|
|
@@ -1557,8 +1877,8 @@ class RoleActionSelectorComponent {
|
|
|
1557
1877
|
<tr>
|
|
1558
1878
|
<td colspan="5" class="text-center p-4 text-muted-color">
|
|
1559
1879
|
@if (loading()) {
|
|
1560
|
-
<i class="pi pi-spin pi-spinner"></i>
|
|
1561
|
-
} @else {
|
|
1880
|
+
<i class="pi pi-spin pi-spinner"></i> {{ 'shared.loading.actions' | translate }}
|
|
1881
|
+
} @else { {{ 'iam.permission.no.actions.available' | translate }} }
|
|
1562
1882
|
</td>
|
|
1563
1883
|
</tr>
|
|
1564
1884
|
</ng-template>
|
|
@@ -1571,14 +1891,14 @@ class RoleActionSelectorComponent {
|
|
|
1571
1891
|
<div class="border border-surface rounded-border p-3 mt-4">
|
|
1572
1892
|
<div class="flex items-center gap-2 mb-3">
|
|
1573
1893
|
<i class="pi pi-info-circle text-primary"></i>
|
|
1574
|
-
<span class="font-bold">
|
|
1894
|
+
<span class="font-bold">{{ 'shared.pending.changes' | translate }}</span>
|
|
1575
1895
|
</div>
|
|
1576
1896
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
1577
1897
|
@if (pendingAdd().length > 0) {
|
|
1578
1898
|
<div>
|
|
1579
1899
|
<div class="flex items-center gap-2 mb-2">
|
|
1580
1900
|
<i class="pi pi-plus-circle text-green-500"></i>
|
|
1581
|
-
<strong class="text-sm">
|
|
1901
|
+
<strong class="text-sm">{{ 'shared.to.add' | translate }} ({{ pendingAdd().length }})</strong>
|
|
1582
1902
|
</div>
|
|
1583
1903
|
<ul class="list-none p-0 m-0 pl-4">
|
|
1584
1904
|
@for (action of pendingAdd(); track action.id) {
|
|
@@ -1591,7 +1911,7 @@ class RoleActionSelectorComponent {
|
|
|
1591
1911
|
<div>
|
|
1592
1912
|
<div class="flex items-center gap-2 mb-2">
|
|
1593
1913
|
<i class="pi pi-minus-circle text-red-500"></i>
|
|
1594
|
-
<strong class="text-sm">
|
|
1914
|
+
<strong class="text-sm">{{ 'shared.to.remove' | translate }} ({{ pendingRemove().length }})</strong>
|
|
1595
1915
|
</div>
|
|
1596
1916
|
<ul class="list-none p-0 m-0 pl-4">
|
|
1597
1917
|
@for (action of pendingRemove(); track action.id) {
|
|
@@ -1609,30 +1929,30 @@ class RoleActionSelectorComponent {
|
|
|
1609
1929
|
<div class="surface-card p-5 rounded-border shadow-sm text-center">
|
|
1610
1930
|
<i class="pi pi-info-circle text-muted-color mb-3 block text-5xl"></i>
|
|
1611
1931
|
<p class="text-muted-color m-0">
|
|
1612
|
-
|
|
1932
|
+
{{ 'iam.permission.no.actions.for.role' | translate }}
|
|
1613
1933
|
</p>
|
|
1614
1934
|
</div>
|
|
1615
1935
|
}
|
|
1616
1936
|
}
|
|
1617
1937
|
</div>
|
|
1618
|
-
`, isInline: true, styles: [":host{display:block}.validation-warning{background-color:var(--p-yellow-50, #fefce8);border-left:4px solid var(--p-yellow-500, #eab308);color:var(--p-yellow-700, #a16207)}:host-context(.p-dark) .validation-warning{background-color:#eab3081a;color:var(--p-yellow-400, #facc15)}:host ::ng-deep tr.highlight-warning{background-color:var(--p-red-50, rgba(239, 68, 68, .1))!important}:host-context(.p-dark) ::ng-deep tr.highlight-warning{background-color:#ef444426!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "component", type: i4.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i5.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: i7.TreeTable, selector: "p-treeTable, p-treetable, p-tree-table", inputs: ["columns", "styleClass", "tableStyle", "tableStyleClass", "autoLayout", "lazy", "lazyLoadOnInit", "paginator", "rows", "first", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "customSort", "selectionMode", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "compareSelectionBy", "rowHover", "loading", "loadingIcon", "showLoader", "scrollable", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "frozenColumns", "resizableColumns", "columnResizeMode", "reorderableColumns", "contextMenu", "rowTrackBy", "filters", "globalFilterFields", "filterDelay", "filterMode", "filterLocale", "paginatorLocale", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "value", "virtualRowHeight", "selectionKeys", "showGridlines"], outputs: ["selectionChange", "contextMenuSelectionChange", "onFilter", "onNodeExpand", "onNodeCollapse", "onPage", "onSort", "onLazyLoad", "sortFunction", "onColResize", "onColReorder", "onNodeSelect", "onNodeUnselect", "onContextMenuSelect", "onHeaderCheckboxToggle", "onEditInit", "onEditComplete", "onEditCancel", "selectionKeysChange"] }, { kind: "component", type: i7.TreeTableToggler, selector: "p-treeTableToggler, p-treetabletoggler, p-treetable-toggler", inputs: ["rowNode"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }
|
|
1938
|
+
`, isInline: true, styles: [":host{display:block}.validation-warning{background-color:var(--p-yellow-50, #fefce8);border-left:4px solid var(--p-yellow-500, #eab308);color:var(--p-yellow-700, #a16207)}:host-context(.p-dark) .validation-warning{background-color:#eab3081a;color:var(--p-yellow-400, #facc15)}:host ::ng-deep tr.highlight-warning{background-color:var(--p-red-50, rgba(239, 68, 68, .1))!important}:host-context(.p-dark) ::ng-deep tr.highlight-warning{background-color:#ef444426!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "component", type: i4.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i5.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: i7.TreeTable, selector: "p-treeTable, p-treetable, p-tree-table", inputs: ["columns", "styleClass", "tableStyle", "tableStyleClass", "autoLayout", "lazy", "lazyLoadOnInit", "paginator", "rows", "first", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "customSort", "selectionMode", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "compareSelectionBy", "rowHover", "loading", "loadingIcon", "showLoader", "scrollable", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "frozenColumns", "resizableColumns", "columnResizeMode", "reorderableColumns", "contextMenu", "rowTrackBy", "filters", "globalFilterFields", "filterDelay", "filterMode", "filterLocale", "paginatorLocale", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "value", "virtualRowHeight", "selectionKeys", "showGridlines"], outputs: ["selectionChange", "contextMenuSelectionChange", "onFilter", "onNodeExpand", "onNodeCollapse", "onPage", "onSort", "onLazyLoad", "sortFunction", "onColResize", "onColReorder", "onNodeSelect", "onNodeUnselect", "onContextMenuSelect", "onHeaderCheckboxToggle", "onEditInit", "onEditComplete", "onEditCancel", "selectionKeysChange"] }, { kind: "component", type: i7.TreeTableToggler, selector: "p-treeTableToggler, p-treetabletoggler, p-treetable-toggler", inputs: ["rowNode"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
1619
1939
|
}
|
|
1620
1940
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: RoleActionSelectorComponent, decorators: [{
|
|
1621
1941
|
type: Component,
|
|
1622
|
-
args: [{ selector: 'flusys-role-action-selector',
|
|
1942
|
+
args: [{ selector: 'flusys-role-action-selector', imports: [CommonModule, FormsModule, PrimeModule, HasPermissionDirective, TranslatePipe], template: `
|
|
1623
1943
|
<div class="role-action-selector">
|
|
1624
1944
|
<!-- Role Selector -->
|
|
1625
1945
|
<div class="mb-4">
|
|
1626
1946
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
1627
1947
|
<div>
|
|
1628
|
-
<label class="block font-semibold mb-2">
|
|
1948
|
+
<label class="block font-semibold mb-2">{{ 'iam.permission.select.role' | translate }}</label>
|
|
1629
1949
|
<p-select
|
|
1630
1950
|
[ngModel]="selectedRoleId()"
|
|
1631
1951
|
(ngModelChange)="selectedRoleId.set($event)"
|
|
1632
1952
|
[options]="roles()"
|
|
1633
1953
|
optionLabel="name"
|
|
1634
1954
|
optionValue="id"
|
|
1635
|
-
placeholder="
|
|
1955
|
+
[placeholder]="'iam.permission.select.role.placeholder' | translate"
|
|
1636
1956
|
[showClear]="true"
|
|
1637
1957
|
[filter]="true"
|
|
1638
1958
|
styleClass="w-full"
|
|
@@ -1658,14 +1978,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1658
1978
|
class="flex flex-col md:flex-row justify-between items-start md:items-center gap-3 mb-4"
|
|
1659
1979
|
>
|
|
1660
1980
|
<div>
|
|
1661
|
-
<h5 class="m-0 mb-1">
|
|
1981
|
+
<h5 class="m-0 mb-1">{{ 'iam.permission.action.permissions' | translate }}</h5>
|
|
1662
1982
|
<p class="text-sm text-muted-color m-0">
|
|
1663
|
-
{{ actions().length }}
|
|
1983
|
+
{{ 'iam.permission.actions.available' | translate: { count: actions().length } }}
|
|
1664
1984
|
</p>
|
|
1665
1985
|
</div>
|
|
1666
1986
|
<div class="flex flex-wrap gap-2">
|
|
1667
1987
|
<p-button
|
|
1668
|
-
label="
|
|
1988
|
+
[label]="'shared.select.all' | translate"
|
|
1669
1989
|
icon="pi pi-check"
|
|
1670
1990
|
[outlined]="true"
|
|
1671
1991
|
size="small"
|
|
@@ -1673,7 +1993,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1673
1993
|
(onClick)="selectAll()"
|
|
1674
1994
|
/>
|
|
1675
1995
|
<p-button
|
|
1676
|
-
label="
|
|
1996
|
+
[label]="'shared.deselect.all' | translate"
|
|
1677
1997
|
icon="pi pi-times"
|
|
1678
1998
|
[outlined]="true"
|
|
1679
1999
|
size="small"
|
|
@@ -1682,7 +2002,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1682
2002
|
/>
|
|
1683
2003
|
<p-button
|
|
1684
2004
|
*hasPermission="ROLE_ACTION_PERMISSIONS.ASSIGN"
|
|
1685
|
-
label="
|
|
2005
|
+
[label]="'shared.save.changes' | translate"
|
|
1686
2006
|
icon="pi pi-save"
|
|
1687
2007
|
[disabled]="!canSave()"
|
|
1688
2008
|
[loading]="saving()"
|
|
@@ -1699,12 +2019,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1699
2019
|
<div class="flex items-start gap-2">
|
|
1700
2020
|
<i class="pi pi-exclamation-triangle text-xl"></i>
|
|
1701
2021
|
<div class="flex-1">
|
|
1702
|
-
<span class="font-semibold">
|
|
2022
|
+
<span class="font-semibold">{{ 'iam.validation.warning.title' | translate }}:</span>
|
|
1703
2023
|
<p class="text-sm mt-1 mb-0">
|
|
1704
|
-
{{ invalidActionsCount() }}
|
|
1705
|
-
action{{ invalidActionsCount() > 1 ? 's have' : ' has' }}
|
|
1706
|
-
unmet prerequisites. Fix before saving or use auto-fix on
|
|
1707
|
-
save.
|
|
2024
|
+
{{ (invalidActionsCount() > 1 ? 'iam.validation.unmet.prerequisites.plural' : 'iam.validation.unmet.prerequisites.singular') | translate: { count: invalidActionsCount() } }}
|
|
1708
2025
|
</p>
|
|
1709
2026
|
</div>
|
|
1710
2027
|
</div>
|
|
@@ -1726,14 +2043,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1726
2043
|
[ngModel]="allSelected()"
|
|
1727
2044
|
[binary]="true"
|
|
1728
2045
|
(ngModelChange)="toggleAll()"
|
|
1729
|
-
pTooltip="
|
|
2046
|
+
[pTooltip]="'shared.select.deselect.all' | translate"
|
|
1730
2047
|
tooltipPosition="top"
|
|
1731
2048
|
/>
|
|
1732
2049
|
</th>
|
|
1733
|
-
<th>
|
|
1734
|
-
<th class="hidden md:table-cell">
|
|
1735
|
-
<th>
|
|
1736
|
-
<th class="hidden lg:table-cell">
|
|
2050
|
+
<th>{{ 'shared.name' | translate }}</th>
|
|
2051
|
+
<th class="hidden md:table-cell">{{ 'shared.code' | translate }}</th>
|
|
2052
|
+
<th>{{ 'iam.action.type' | translate }}</th>
|
|
2053
|
+
<th class="hidden lg:table-cell">{{ 'iam.permission.requirements' | translate }}</th>
|
|
1737
2054
|
</tr>
|
|
1738
2055
|
</ng-template>
|
|
1739
2056
|
<ng-template #body let-rowNode let-rowData="rowData">
|
|
@@ -1754,7 +2071,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1754
2071
|
@if (hasUnmetPrerequisites(rowData)) {
|
|
1755
2072
|
<i
|
|
1756
2073
|
class="pi pi-exclamation-triangle text-orange-500"
|
|
1757
|
-
pTooltip="
|
|
2074
|
+
[pTooltip]="'iam.validation.unmet.prerequisites.tooltip' | translate"
|
|
1758
2075
|
tooltipPosition="top"
|
|
1759
2076
|
></i>
|
|
1760
2077
|
}
|
|
@@ -1771,7 +2088,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1771
2088
|
</td>
|
|
1772
2089
|
<td class="hidden lg:table-cell">
|
|
1773
2090
|
@if (rowData.permissionLogic) {
|
|
1774
|
-
<span class="text-sm text-muted-color">
|
|
2091
|
+
<span class="text-sm text-muted-color">{{ 'iam.permission.has.prerequisites' | translate }}</span>
|
|
1775
2092
|
} @else {
|
|
1776
2093
|
<span class="text-muted-color">-</span>
|
|
1777
2094
|
}
|
|
@@ -1782,8 +2099,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1782
2099
|
<tr>
|
|
1783
2100
|
<td colspan="5" class="text-center p-4 text-muted-color">
|
|
1784
2101
|
@if (loading()) {
|
|
1785
|
-
<i class="pi pi-spin pi-spinner"></i>
|
|
1786
|
-
} @else {
|
|
2102
|
+
<i class="pi pi-spin pi-spinner"></i> {{ 'shared.loading.actions' | translate }}
|
|
2103
|
+
} @else { {{ 'iam.permission.no.actions.available' | translate }} }
|
|
1787
2104
|
</td>
|
|
1788
2105
|
</tr>
|
|
1789
2106
|
</ng-template>
|
|
@@ -1796,14 +2113,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1796
2113
|
<div class="border border-surface rounded-border p-3 mt-4">
|
|
1797
2114
|
<div class="flex items-center gap-2 mb-3">
|
|
1798
2115
|
<i class="pi pi-info-circle text-primary"></i>
|
|
1799
|
-
<span class="font-bold">
|
|
2116
|
+
<span class="font-bold">{{ 'shared.pending.changes' | translate }}</span>
|
|
1800
2117
|
</div>
|
|
1801
2118
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
1802
2119
|
@if (pendingAdd().length > 0) {
|
|
1803
2120
|
<div>
|
|
1804
2121
|
<div class="flex items-center gap-2 mb-2">
|
|
1805
2122
|
<i class="pi pi-plus-circle text-green-500"></i>
|
|
1806
|
-
<strong class="text-sm">
|
|
2123
|
+
<strong class="text-sm">{{ 'shared.to.add' | translate }} ({{ pendingAdd().length }})</strong>
|
|
1807
2124
|
</div>
|
|
1808
2125
|
<ul class="list-none p-0 m-0 pl-4">
|
|
1809
2126
|
@for (action of pendingAdd(); track action.id) {
|
|
@@ -1816,7 +2133,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1816
2133
|
<div>
|
|
1817
2134
|
<div class="flex items-center gap-2 mb-2">
|
|
1818
2135
|
<i class="pi pi-minus-circle text-red-500"></i>
|
|
1819
|
-
<strong class="text-sm">
|
|
2136
|
+
<strong class="text-sm">{{ 'shared.to.remove' | translate }} ({{ pendingRemove().length }})</strong>
|
|
1820
2137
|
</div>
|
|
1821
2138
|
<ul class="list-none p-0 m-0 pl-4">
|
|
1822
2139
|
@for (action of pendingRemove(); track action.id) {
|
|
@@ -1834,7 +2151,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1834
2151
|
<div class="surface-card p-5 rounded-border shadow-sm text-center">
|
|
1835
2152
|
<i class="pi pi-info-circle text-muted-color mb-3 block text-5xl"></i>
|
|
1836
2153
|
<p class="text-muted-color m-0">
|
|
1837
|
-
|
|
2154
|
+
{{ 'iam.permission.no.actions.for.role' | translate }}
|
|
1838
2155
|
</p>
|
|
1839
2156
|
</div>
|
|
1840
2157
|
}
|
|
@@ -1867,7 +2184,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
1867
2184
|
* - Pre-save validation with auto-fix
|
|
1868
2185
|
*
|
|
1869
2186
|
* **Performance:**
|
|
1870
|
-
* - OnPush change detection
|
|
1871
2187
|
* - Computed signals for reactive updates
|
|
1872
2188
|
* - Memoized prerequisite validation
|
|
1873
2189
|
* - AbortController for request cancellation
|
|
@@ -1888,6 +2204,10 @@ class CompanyActionSelectorComponent {
|
|
|
1888
2204
|
confirmationService = inject(ConfirmationService);
|
|
1889
2205
|
permissionLogic = inject(ActionPermissionLogicService);
|
|
1890
2206
|
destroyRef = inject(DestroyRef);
|
|
2207
|
+
translateAdapter = inject(TRANSLATE_ADAPTER, { optional: true });
|
|
2208
|
+
translate(key, vars) {
|
|
2209
|
+
return this.translateAdapter?.translate(key, vars) ?? key;
|
|
2210
|
+
}
|
|
1891
2211
|
// State - Company Selection
|
|
1892
2212
|
selectedCompanyId = signal(undefined, ...(ngDevMode ? [{ debugName: "selectedCompanyId" }] : []));
|
|
1893
2213
|
companies = signal([], ...(ngDevMode ? [{ debugName: "companies" }] : []));
|
|
@@ -2050,15 +2370,15 @@ class CompanyActionSelectorComponent {
|
|
|
2050
2370
|
const prerequisiteInfo = this.permissionLogic.getPrerequisiteTooltip(action, selMap, this.actions());
|
|
2051
2371
|
if (prerequisiteInfo) {
|
|
2052
2372
|
const actionHint = isCurrentlySelected
|
|
2053
|
-
?
|
|
2054
|
-
:
|
|
2373
|
+
? `\n\n---\n[${this.translate('shared.remove')}] ${this.translate('iam.tooltip.remove.action')}`
|
|
2374
|
+
: `\n\n---\n[${this.translate('shared.add')}] ${this.translate('iam.tooltip.add.action')}`;
|
|
2055
2375
|
return `${prerequisiteInfo}${actionHint}`;
|
|
2056
2376
|
}
|
|
2057
2377
|
}
|
|
2058
2378
|
if (isCurrentlySelected) {
|
|
2059
|
-
return '
|
|
2379
|
+
return `[${this.translate('iam.tooltip.selected')}] ${this.translate('iam.tooltip.selected')}\n\n[${this.translate('shared.remove')}] ${this.translate('iam.tooltip.click.to.remove')}`;
|
|
2060
2380
|
}
|
|
2061
|
-
return '
|
|
2381
|
+
return `[${this.translate('shared.add')}] ${this.translate('iam.tooltip.click.to.add')}`;
|
|
2062
2382
|
}
|
|
2063
2383
|
/**
|
|
2064
2384
|
* Handle action checkbox toggle
|
|
@@ -2115,9 +2435,8 @@ class CompanyActionSelectorComponent {
|
|
|
2115
2435
|
}
|
|
2116
2436
|
this.messageService.add({
|
|
2117
2437
|
severity: 'success',
|
|
2118
|
-
summary: '
|
|
2119
|
-
detail: response?.data?.message ||
|
|
2120
|
-
'Company action whitelist updated successfully',
|
|
2438
|
+
summary: this.translate('shared.success'),
|
|
2439
|
+
detail: response?.data?.message || this.translate('iam.permission.company.actions.updated'),
|
|
2121
2440
|
});
|
|
2122
2441
|
// Update baseline
|
|
2123
2442
|
this._initialSelection.set({ ...this.selectionMap() });
|
|
@@ -2139,15 +2458,15 @@ class CompanyActionSelectorComponent {
|
|
|
2139
2458
|
const requiredNames = error.requiredActions
|
|
2140
2459
|
.map((a) => a.actionName)
|
|
2141
2460
|
.join(', ');
|
|
2142
|
-
return
|
|
2461
|
+
return `${error.actionName} ${this.translate('iam.permission.requires')}: ${requiredNames}`;
|
|
2143
2462
|
})
|
|
2144
2463
|
.join('\n');
|
|
2145
2464
|
this.confirmationService.confirm({
|
|
2146
|
-
header: '
|
|
2147
|
-
message:
|
|
2465
|
+
header: this.translate('iam.permission.prerequisite.validation.failed'),
|
|
2466
|
+
message: `${this.translate('iam.permission.prerequisite.error.message')}\n\n${errorList}\n\n${this.translate('iam.permission.auto.select.prompt')}`,
|
|
2148
2467
|
icon: 'pi pi-exclamation-triangle',
|
|
2149
|
-
acceptLabel: '
|
|
2150
|
-
rejectLabel: '
|
|
2468
|
+
acceptLabel: this.translate('iam.permission.auto.select.required'),
|
|
2469
|
+
rejectLabel: this.translate('shared.cancel'),
|
|
2151
2470
|
acceptIcon: 'pi pi-check',
|
|
2152
2471
|
rejectIcon: 'pi pi-times',
|
|
2153
2472
|
accept: () => {
|
|
@@ -2161,8 +2480,8 @@ class CompanyActionSelectorComponent {
|
|
|
2161
2480
|
this._selectionMap.set(selMap);
|
|
2162
2481
|
this.messageService.add({
|
|
2163
2482
|
severity: 'info',
|
|
2164
|
-
summary: '
|
|
2165
|
-
detail: '
|
|
2483
|
+
summary: this.translate('iam.permission.actions.selected'),
|
|
2484
|
+
detail: this.translate('iam.permission.auto.selected.prerequisites'),
|
|
2166
2485
|
});
|
|
2167
2486
|
},
|
|
2168
2487
|
reject: () => {
|
|
@@ -2170,8 +2489,8 @@ class CompanyActionSelectorComponent {
|
|
|
2170
2489
|
this._selectionMap.set({ ...this.initialSelection() });
|
|
2171
2490
|
this.messageService.add({
|
|
2172
2491
|
severity: 'info',
|
|
2173
|
-
summary: '
|
|
2174
|
-
detail: '
|
|
2492
|
+
summary: this.translate('iam.permission.changes.reverted'),
|
|
2493
|
+
detail: this.translate('iam.permission.selection.reverted'),
|
|
2175
2494
|
});
|
|
2176
2495
|
},
|
|
2177
2496
|
});
|
|
@@ -2206,14 +2525,14 @@ class CompanyActionSelectorComponent {
|
|
|
2206
2525
|
<div class="mb-4">
|
|
2207
2526
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
2208
2527
|
<div>
|
|
2209
|
-
<label class="block font-semibold mb-2">
|
|
2528
|
+
<label class="block font-semibold mb-2">{{ 'iam.permission.select.company' | translate }}</label>
|
|
2210
2529
|
<p-select
|
|
2211
2530
|
[ngModel]="selectedCompanyId()"
|
|
2212
2531
|
(ngModelChange)="selectedCompanyId.set($event)"
|
|
2213
2532
|
[options]="companies()"
|
|
2214
2533
|
optionLabel="name"
|
|
2215
2534
|
optionValue="id"
|
|
2216
|
-
placeholder="
|
|
2535
|
+
[placeholder]="'iam.permission.select.company.placeholder' | translate"
|
|
2217
2536
|
[showClear]="true"
|
|
2218
2537
|
[filter]="true"
|
|
2219
2538
|
styleClass="w-full"
|
|
@@ -2239,14 +2558,14 @@ class CompanyActionSelectorComponent {
|
|
|
2239
2558
|
class="flex flex-col md:flex-row justify-between items-start md:items-center gap-3 mb-4"
|
|
2240
2559
|
>
|
|
2241
2560
|
<div>
|
|
2242
|
-
<h5 class="m-0 mb-1">
|
|
2561
|
+
<h5 class="m-0 mb-1">{{ 'iam.permission.action.whitelist' | translate }}</h5>
|
|
2243
2562
|
<p class="text-sm text-muted-color m-0">
|
|
2244
|
-
{{ actions().length }}
|
|
2563
|
+
{{ 'iam.permission.actions.available' | translate: { count: actions().length } }}
|
|
2245
2564
|
</p>
|
|
2246
2565
|
</div>
|
|
2247
2566
|
<div class="flex flex-wrap gap-2">
|
|
2248
2567
|
<p-button
|
|
2249
|
-
label="
|
|
2568
|
+
[label]="'shared.select.all' | translate"
|
|
2250
2569
|
icon="pi pi-check"
|
|
2251
2570
|
[outlined]="true"
|
|
2252
2571
|
size="small"
|
|
@@ -2254,7 +2573,7 @@ class CompanyActionSelectorComponent {
|
|
|
2254
2573
|
(onClick)="selectAll()"
|
|
2255
2574
|
/>
|
|
2256
2575
|
<p-button
|
|
2257
|
-
label="
|
|
2576
|
+
[label]="'shared.deselect.all' | translate"
|
|
2258
2577
|
icon="pi pi-times"
|
|
2259
2578
|
[outlined]="true"
|
|
2260
2579
|
size="small"
|
|
@@ -2263,7 +2582,7 @@ class CompanyActionSelectorComponent {
|
|
|
2263
2582
|
/>
|
|
2264
2583
|
<p-button
|
|
2265
2584
|
*hasPermission="COMPANY_ACTION_PERMISSIONS.ASSIGN"
|
|
2266
|
-
label="
|
|
2585
|
+
[label]="'shared.save.changes' | translate"
|
|
2267
2586
|
icon="pi pi-save"
|
|
2268
2587
|
[disabled]="!canSave()"
|
|
2269
2588
|
[loading]="saving()"
|
|
@@ -2280,12 +2599,9 @@ class CompanyActionSelectorComponent {
|
|
|
2280
2599
|
<div class="flex items-start gap-2">
|
|
2281
2600
|
<i class="pi pi-exclamation-triangle text-xl"></i>
|
|
2282
2601
|
<div class="flex-1">
|
|
2283
|
-
<span class="font-semibold">
|
|
2602
|
+
<span class="font-semibold">{{ 'iam.validation.warning.title' | translate }}:</span>
|
|
2284
2603
|
<p class="text-sm mt-1 mb-0">
|
|
2285
|
-
{{ invalidActionsCount() }}
|
|
2286
|
-
action{{ invalidActionsCount() > 1 ? 's have' : ' has' }}
|
|
2287
|
-
unmet prerequisites. Fix before saving or use auto-fix on
|
|
2288
|
-
save.
|
|
2604
|
+
{{ (invalidActionsCount() > 1 ? 'iam.validation.unmet.prerequisites.plural' : 'iam.validation.unmet.prerequisites.singular') | translate: { count: invalidActionsCount() } }}
|
|
2289
2605
|
</p>
|
|
2290
2606
|
</div>
|
|
2291
2607
|
</div>
|
|
@@ -2307,14 +2623,14 @@ class CompanyActionSelectorComponent {
|
|
|
2307
2623
|
[ngModel]="allSelected()"
|
|
2308
2624
|
[binary]="true"
|
|
2309
2625
|
(ngModelChange)="toggleAll()"
|
|
2310
|
-
pTooltip="
|
|
2626
|
+
[pTooltip]="'shared.select.deselect.all' | translate"
|
|
2311
2627
|
tooltipPosition="top"
|
|
2312
2628
|
/>
|
|
2313
2629
|
</th>
|
|
2314
|
-
<th>
|
|
2315
|
-
<th class="hidden md:table-cell">
|
|
2316
|
-
<th>
|
|
2317
|
-
<th class="hidden lg:table-cell">
|
|
2630
|
+
<th>{{ 'shared.name' | translate }}</th>
|
|
2631
|
+
<th class="hidden md:table-cell">{{ 'shared.code' | translate }}</th>
|
|
2632
|
+
<th>{{ 'iam.action.type' | translate }}</th>
|
|
2633
|
+
<th class="hidden lg:table-cell">{{ 'shared.description' | translate }}</th>
|
|
2318
2634
|
</tr>
|
|
2319
2635
|
</ng-template>
|
|
2320
2636
|
<ng-template #body let-rowNode let-rowData="rowData">
|
|
@@ -2335,7 +2651,7 @@ class CompanyActionSelectorComponent {
|
|
|
2335
2651
|
@if (hasUnmetPrerequisites(rowData)) {
|
|
2336
2652
|
<i
|
|
2337
2653
|
class="pi pi-exclamation-triangle text-orange-500"
|
|
2338
|
-
pTooltip="
|
|
2654
|
+
[pTooltip]="'iam.validation.unmet.prerequisites.tooltip' | translate"
|
|
2339
2655
|
tooltipPosition="top"
|
|
2340
2656
|
></i>
|
|
2341
2657
|
}
|
|
@@ -2357,8 +2673,8 @@ class CompanyActionSelectorComponent {
|
|
|
2357
2673
|
<tr>
|
|
2358
2674
|
<td colspan="5" class="text-center p-4 text-muted-color">
|
|
2359
2675
|
@if (loading()) {
|
|
2360
|
-
<i class="pi pi-spin pi-spinner"></i>
|
|
2361
|
-
} @else {
|
|
2676
|
+
<i class="pi pi-spin pi-spinner"></i> {{ 'shared.loading.actions' | translate }}
|
|
2677
|
+
} @else { {{ 'iam.permission.no.actions.available' | translate }} }
|
|
2362
2678
|
</td>
|
|
2363
2679
|
</tr>
|
|
2364
2680
|
</ng-template>
|
|
@@ -2371,14 +2687,14 @@ class CompanyActionSelectorComponent {
|
|
|
2371
2687
|
<div class="border border-surface rounded-border p-3 mt-4">
|
|
2372
2688
|
<div class="flex items-center gap-2 mb-3">
|
|
2373
2689
|
<i class="pi pi-info-circle text-primary"></i>
|
|
2374
|
-
<span class="font-bold">
|
|
2690
|
+
<span class="font-bold">{{ 'shared.pending.changes' | translate }}</span>
|
|
2375
2691
|
</div>
|
|
2376
2692
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
2377
2693
|
@if (pendingAdd().length > 0) {
|
|
2378
2694
|
<div>
|
|
2379
2695
|
<div class="flex items-center gap-2 mb-2">
|
|
2380
2696
|
<i class="pi pi-plus-circle text-green-500"></i>
|
|
2381
|
-
<strong class="text-sm">
|
|
2697
|
+
<strong class="text-sm">{{ 'shared.to.whitelist' | translate }} ({{ pendingAdd().length }})</strong>
|
|
2382
2698
|
</div>
|
|
2383
2699
|
<ul class="list-none p-0 m-0 pl-4">
|
|
2384
2700
|
@for (action of pendingAdd(); track action.id) {
|
|
@@ -2391,7 +2707,7 @@ class CompanyActionSelectorComponent {
|
|
|
2391
2707
|
<div>
|
|
2392
2708
|
<div class="flex items-center gap-2 mb-2">
|
|
2393
2709
|
<i class="pi pi-minus-circle text-red-500"></i>
|
|
2394
|
-
<strong class="text-sm">
|
|
2710
|
+
<strong class="text-sm">{{ 'shared.to.remove' | translate }} ({{ pendingRemove().length }})</strong>
|
|
2395
2711
|
</div>
|
|
2396
2712
|
<ul class="list-none p-0 m-0 pl-4">
|
|
2397
2713
|
@for (action of pendingRemove(); track action.id) {
|
|
@@ -2409,30 +2725,30 @@ class CompanyActionSelectorComponent {
|
|
|
2409
2725
|
<div class="surface-card p-5 rounded-border shadow-sm text-center">
|
|
2410
2726
|
<i class="pi pi-info-circle text-muted-color mb-3 block text-5xl"></i>
|
|
2411
2727
|
<p class="text-muted-color m-0">
|
|
2412
|
-
|
|
2728
|
+
{{ 'iam.permission.no.actions.for.company' | translate }}
|
|
2413
2729
|
</p>
|
|
2414
2730
|
</div>
|
|
2415
2731
|
}
|
|
2416
2732
|
}
|
|
2417
2733
|
</div>
|
|
2418
|
-
`, isInline: true, styles: [":host{display:block}.validation-warning{background-color:var(--p-yellow-50, #fefce8);border-left:4px solid var(--p-yellow-500, #eab308);color:var(--p-yellow-700, #a16207)}:host-context(.p-dark) .validation-warning{background-color:#eab3081a;color:var(--p-yellow-400, #facc15)}:host ::ng-deep tr.highlight-warning{background-color:var(--p-red-50, rgba(239, 68, 68, .1))!important}:host-context(.p-dark) ::ng-deep tr.highlight-warning{background-color:#ef444426!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "component", type: i4.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i5.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: i7.TreeTable, selector: "p-treeTable, p-treetable, p-tree-table", inputs: ["columns", "styleClass", "tableStyle", "tableStyleClass", "autoLayout", "lazy", "lazyLoadOnInit", "paginator", "rows", "first", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "customSort", "selectionMode", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "compareSelectionBy", "rowHover", "loading", "loadingIcon", "showLoader", "scrollable", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "frozenColumns", "resizableColumns", "columnResizeMode", "reorderableColumns", "contextMenu", "rowTrackBy", "filters", "globalFilterFields", "filterDelay", "filterMode", "filterLocale", "paginatorLocale", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "value", "virtualRowHeight", "selectionKeys", "showGridlines"], outputs: ["selectionChange", "contextMenuSelectionChange", "onFilter", "onNodeExpand", "onNodeCollapse", "onPage", "onSort", "onLazyLoad", "sortFunction", "onColResize", "onColReorder", "onNodeSelect", "onNodeUnselect", "onContextMenuSelect", "onHeaderCheckboxToggle", "onEditInit", "onEditComplete", "onEditCancel", "selectionKeysChange"] }, { kind: "component", type: i7.TreeTableToggler, selector: "p-treeTableToggler, p-treetabletoggler, p-treetable-toggler", inputs: ["rowNode"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }
|
|
2734
|
+
`, isInline: true, styles: [":host{display:block}.validation-warning{background-color:var(--p-yellow-50, #fefce8);border-left:4px solid var(--p-yellow-500, #eab308);color:var(--p-yellow-700, #a16207)}:host-context(.p-dark) .validation-warning{background-color:#eab3081a;color:var(--p-yellow-400, #facc15)}:host ::ng-deep tr.highlight-warning{background-color:var(--p-red-50, rgba(239, 68, 68, .1))!important}:host-context(.p-dark) ::ng-deep tr.highlight-warning{background-color:#ef444426!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "component", type: i4.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i5.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: i7.TreeTable, selector: "p-treeTable, p-treetable, p-tree-table", inputs: ["columns", "styleClass", "tableStyle", "tableStyleClass", "autoLayout", "lazy", "lazyLoadOnInit", "paginator", "rows", "first", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "customSort", "selectionMode", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "compareSelectionBy", "rowHover", "loading", "loadingIcon", "showLoader", "scrollable", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "frozenColumns", "resizableColumns", "columnResizeMode", "reorderableColumns", "contextMenu", "rowTrackBy", "filters", "globalFilterFields", "filterDelay", "filterMode", "filterLocale", "paginatorLocale", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "value", "virtualRowHeight", "selectionKeys", "showGridlines"], outputs: ["selectionChange", "contextMenuSelectionChange", "onFilter", "onNodeExpand", "onNodeCollapse", "onPage", "onSort", "onLazyLoad", "sortFunction", "onColResize", "onColReorder", "onNodeSelect", "onNodeUnselect", "onContextMenuSelect", "onHeaderCheckboxToggle", "onEditInit", "onEditComplete", "onEditCancel", "selectionKeysChange"] }, { kind: "component", type: i7.TreeTableToggler, selector: "p-treeTableToggler, p-treetabletoggler, p-treetable-toggler", inputs: ["rowNode"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
2419
2735
|
}
|
|
2420
2736
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CompanyActionSelectorComponent, decorators: [{
|
|
2421
2737
|
type: Component,
|
|
2422
|
-
args: [{ selector: 'flusys-company-action-selector',
|
|
2738
|
+
args: [{ selector: 'flusys-company-action-selector', imports: [CommonModule, FormsModule, PrimeModule, HasPermissionDirective, TranslatePipe], template: `
|
|
2423
2739
|
<div class="company-action-selector">
|
|
2424
2740
|
<!-- Company Selector -->
|
|
2425
2741
|
<div class="mb-4">
|
|
2426
2742
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
2427
2743
|
<div>
|
|
2428
|
-
<label class="block font-semibold mb-2">
|
|
2744
|
+
<label class="block font-semibold mb-2">{{ 'iam.permission.select.company' | translate }}</label>
|
|
2429
2745
|
<p-select
|
|
2430
2746
|
[ngModel]="selectedCompanyId()"
|
|
2431
2747
|
(ngModelChange)="selectedCompanyId.set($event)"
|
|
2432
2748
|
[options]="companies()"
|
|
2433
2749
|
optionLabel="name"
|
|
2434
2750
|
optionValue="id"
|
|
2435
|
-
placeholder="
|
|
2751
|
+
[placeholder]="'iam.permission.select.company.placeholder' | translate"
|
|
2436
2752
|
[showClear]="true"
|
|
2437
2753
|
[filter]="true"
|
|
2438
2754
|
styleClass="w-full"
|
|
@@ -2458,14 +2774,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
2458
2774
|
class="flex flex-col md:flex-row justify-between items-start md:items-center gap-3 mb-4"
|
|
2459
2775
|
>
|
|
2460
2776
|
<div>
|
|
2461
|
-
<h5 class="m-0 mb-1">
|
|
2777
|
+
<h5 class="m-0 mb-1">{{ 'iam.permission.action.whitelist' | translate }}</h5>
|
|
2462
2778
|
<p class="text-sm text-muted-color m-0">
|
|
2463
|
-
{{ actions().length }}
|
|
2779
|
+
{{ 'iam.permission.actions.available' | translate: { count: actions().length } }}
|
|
2464
2780
|
</p>
|
|
2465
2781
|
</div>
|
|
2466
2782
|
<div class="flex flex-wrap gap-2">
|
|
2467
2783
|
<p-button
|
|
2468
|
-
label="
|
|
2784
|
+
[label]="'shared.select.all' | translate"
|
|
2469
2785
|
icon="pi pi-check"
|
|
2470
2786
|
[outlined]="true"
|
|
2471
2787
|
size="small"
|
|
@@ -2473,7 +2789,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
2473
2789
|
(onClick)="selectAll()"
|
|
2474
2790
|
/>
|
|
2475
2791
|
<p-button
|
|
2476
|
-
label="
|
|
2792
|
+
[label]="'shared.deselect.all' | translate"
|
|
2477
2793
|
icon="pi pi-times"
|
|
2478
2794
|
[outlined]="true"
|
|
2479
2795
|
size="small"
|
|
@@ -2482,7 +2798,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
2482
2798
|
/>
|
|
2483
2799
|
<p-button
|
|
2484
2800
|
*hasPermission="COMPANY_ACTION_PERMISSIONS.ASSIGN"
|
|
2485
|
-
label="
|
|
2801
|
+
[label]="'shared.save.changes' | translate"
|
|
2486
2802
|
icon="pi pi-save"
|
|
2487
2803
|
[disabled]="!canSave()"
|
|
2488
2804
|
[loading]="saving()"
|
|
@@ -2499,12 +2815,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
2499
2815
|
<div class="flex items-start gap-2">
|
|
2500
2816
|
<i class="pi pi-exclamation-triangle text-xl"></i>
|
|
2501
2817
|
<div class="flex-1">
|
|
2502
|
-
<span class="font-semibold">
|
|
2818
|
+
<span class="font-semibold">{{ 'iam.validation.warning.title' | translate }}:</span>
|
|
2503
2819
|
<p class="text-sm mt-1 mb-0">
|
|
2504
|
-
{{ invalidActionsCount() }}
|
|
2505
|
-
action{{ invalidActionsCount() > 1 ? 's have' : ' has' }}
|
|
2506
|
-
unmet prerequisites. Fix before saving or use auto-fix on
|
|
2507
|
-
save.
|
|
2820
|
+
{{ (invalidActionsCount() > 1 ? 'iam.validation.unmet.prerequisites.plural' : 'iam.validation.unmet.prerequisites.singular') | translate: { count: invalidActionsCount() } }}
|
|
2508
2821
|
</p>
|
|
2509
2822
|
</div>
|
|
2510
2823
|
</div>
|
|
@@ -2526,14 +2839,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
2526
2839
|
[ngModel]="allSelected()"
|
|
2527
2840
|
[binary]="true"
|
|
2528
2841
|
(ngModelChange)="toggleAll()"
|
|
2529
|
-
pTooltip="
|
|
2842
|
+
[pTooltip]="'shared.select.deselect.all' | translate"
|
|
2530
2843
|
tooltipPosition="top"
|
|
2531
2844
|
/>
|
|
2532
2845
|
</th>
|
|
2533
|
-
<th>
|
|
2534
|
-
<th class="hidden md:table-cell">
|
|
2535
|
-
<th>
|
|
2536
|
-
<th class="hidden lg:table-cell">
|
|
2846
|
+
<th>{{ 'shared.name' | translate }}</th>
|
|
2847
|
+
<th class="hidden md:table-cell">{{ 'shared.code' | translate }}</th>
|
|
2848
|
+
<th>{{ 'iam.action.type' | translate }}</th>
|
|
2849
|
+
<th class="hidden lg:table-cell">{{ 'shared.description' | translate }}</th>
|
|
2537
2850
|
</tr>
|
|
2538
2851
|
</ng-template>
|
|
2539
2852
|
<ng-template #body let-rowNode let-rowData="rowData">
|
|
@@ -2554,7 +2867,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
2554
2867
|
@if (hasUnmetPrerequisites(rowData)) {
|
|
2555
2868
|
<i
|
|
2556
2869
|
class="pi pi-exclamation-triangle text-orange-500"
|
|
2557
|
-
pTooltip="
|
|
2870
|
+
[pTooltip]="'iam.validation.unmet.prerequisites.tooltip' | translate"
|
|
2558
2871
|
tooltipPosition="top"
|
|
2559
2872
|
></i>
|
|
2560
2873
|
}
|
|
@@ -2576,8 +2889,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
2576
2889
|
<tr>
|
|
2577
2890
|
<td colspan="5" class="text-center p-4 text-muted-color">
|
|
2578
2891
|
@if (loading()) {
|
|
2579
|
-
<i class="pi pi-spin pi-spinner"></i>
|
|
2580
|
-
} @else {
|
|
2892
|
+
<i class="pi pi-spin pi-spinner"></i> {{ 'shared.loading.actions' | translate }}
|
|
2893
|
+
} @else { {{ 'iam.permission.no.actions.available' | translate }} }
|
|
2581
2894
|
</td>
|
|
2582
2895
|
</tr>
|
|
2583
2896
|
</ng-template>
|
|
@@ -2590,14 +2903,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
2590
2903
|
<div class="border border-surface rounded-border p-3 mt-4">
|
|
2591
2904
|
<div class="flex items-center gap-2 mb-3">
|
|
2592
2905
|
<i class="pi pi-info-circle text-primary"></i>
|
|
2593
|
-
<span class="font-bold">
|
|
2906
|
+
<span class="font-bold">{{ 'shared.pending.changes' | translate }}</span>
|
|
2594
2907
|
</div>
|
|
2595
2908
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
2596
2909
|
@if (pendingAdd().length > 0) {
|
|
2597
2910
|
<div>
|
|
2598
2911
|
<div class="flex items-center gap-2 mb-2">
|
|
2599
2912
|
<i class="pi pi-plus-circle text-green-500"></i>
|
|
2600
|
-
<strong class="text-sm">
|
|
2913
|
+
<strong class="text-sm">{{ 'shared.to.whitelist' | translate }} ({{ pendingAdd().length }})</strong>
|
|
2601
2914
|
</div>
|
|
2602
2915
|
<ul class="list-none p-0 m-0 pl-4">
|
|
2603
2916
|
@for (action of pendingAdd(); track action.id) {
|
|
@@ -2610,7 +2923,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
2610
2923
|
<div>
|
|
2611
2924
|
<div class="flex items-center gap-2 mb-2">
|
|
2612
2925
|
<i class="pi pi-minus-circle text-red-500"></i>
|
|
2613
|
-
<strong class="text-sm">
|
|
2926
|
+
<strong class="text-sm">{{ 'shared.to.remove' | translate }} ({{ pendingRemove().length }})</strong>
|
|
2614
2927
|
</div>
|
|
2615
2928
|
<ul class="list-none p-0 m-0 pl-4">
|
|
2616
2929
|
@for (action of pendingRemove(); track action.id) {
|
|
@@ -2628,7 +2941,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
2628
2941
|
<div class="surface-card p-5 rounded-border shadow-sm text-center">
|
|
2629
2942
|
<i class="pi pi-info-circle text-muted-color mb-3 block text-5xl"></i>
|
|
2630
2943
|
<p class="text-muted-color m-0">
|
|
2631
|
-
|
|
2944
|
+
{{ 'iam.permission.no.actions.for.company' | translate }}
|
|
2632
2945
|
</p>
|
|
2633
2946
|
</div>
|
|
2634
2947
|
}
|
|
@@ -2658,7 +2971,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
2658
2971
|
* - Branch-specific: branchId = selected value
|
|
2659
2972
|
*
|
|
2660
2973
|
* **Performance:**
|
|
2661
|
-
* - OnPush change detection
|
|
2662
2974
|
* - Computed signals for reactive updates
|
|
2663
2975
|
* - Branch filtering on company context change
|
|
2664
2976
|
*
|
|
@@ -2677,6 +2989,10 @@ class UserRoleSelectorComponent {
|
|
|
2677
2989
|
roleApi = inject(RoleApiService);
|
|
2678
2990
|
permissionApi = inject(PermissionApiService);
|
|
2679
2991
|
messageService = inject(MessageService);
|
|
2992
|
+
translateAdapter = inject(TRANSLATE_ADAPTER, { optional: true });
|
|
2993
|
+
translate(key, vars) {
|
|
2994
|
+
return this.translateAdapter?.translate(key, vars) ?? key;
|
|
2995
|
+
}
|
|
2680
2996
|
// State - User/Branch Selection
|
|
2681
2997
|
selectedUserId = signal(null, ...(ngDevMode ? [{ debugName: "selectedUserId" }] : []));
|
|
2682
2998
|
selectedBranchId = signal(undefined, ...(ngDevMode ? [{ debugName: "selectedBranchId" }] : []));
|
|
@@ -2829,9 +3145,9 @@ class UserRoleSelectorComponent {
|
|
|
2829
3145
|
const selMap = this.selectionMap();
|
|
2830
3146
|
const isCurrentlySelected = selMap[role.id];
|
|
2831
3147
|
if (isCurrentlySelected) {
|
|
2832
|
-
return '
|
|
3148
|
+
return `[${this.translate('shared.assigned')}] ${this.translate('iam.tooltip.assigned.to.user')}\n\n[${this.translate('shared.remove')}] ${this.translate('iam.tooltip.click.to.remove.role.from.user')}`;
|
|
2833
3149
|
}
|
|
2834
|
-
return '
|
|
3150
|
+
return `[${this.translate('shared.add')}] ${this.translate('iam.tooltip.click.to.assign.role.to.user')}`;
|
|
2835
3151
|
}
|
|
2836
3152
|
/**
|
|
2837
3153
|
* Handle role checkbox toggle
|
|
@@ -2882,8 +3198,8 @@ class UserRoleSelectorComponent {
|
|
|
2882
3198
|
if (isCompanyFeatureEnabled(this.appConfig) && !companyId) {
|
|
2883
3199
|
this.messageService.add({
|
|
2884
3200
|
severity: 'warn',
|
|
2885
|
-
summary: '
|
|
2886
|
-
detail: '
|
|
3201
|
+
summary: this.translate('shared.warning'),
|
|
3202
|
+
detail: this.translate('iam.permission.company.required'),
|
|
2887
3203
|
});
|
|
2888
3204
|
return;
|
|
2889
3205
|
}
|
|
@@ -2911,9 +3227,8 @@ class UserRoleSelectorComponent {
|
|
|
2911
3227
|
const response = await firstValueFrom(this.permissionApi.assignUserRoles(payload));
|
|
2912
3228
|
this.messageService.add({
|
|
2913
3229
|
severity: 'success',
|
|
2914
|
-
summary: '
|
|
2915
|
-
detail: response?.data?.message ||
|
|
2916
|
-
'User role assignments updated successfully',
|
|
3230
|
+
summary: this.translate('shared.success'),
|
|
3231
|
+
detail: response?.data?.message || this.translate('iam.permission.user.roles.updated'),
|
|
2917
3232
|
});
|
|
2918
3233
|
// Update baseline
|
|
2919
3234
|
this._initialSelection.set({ ...this.selectionMap() });
|
|
@@ -2942,13 +3257,13 @@ class UserRoleSelectorComponent {
|
|
|
2942
3257
|
<div>
|
|
2943
3258
|
<label class="block font-semibold mb-2">
|
|
2944
3259
|
<i class="pi pi-user mr-2 text-primary"></i>
|
|
2945
|
-
|
|
3260
|
+
{{ 'iam.permission.select.user' | translate }}
|
|
2946
3261
|
</label>
|
|
2947
3262
|
<lib-user-select
|
|
2948
3263
|
[value]="selectedUserId()"
|
|
2949
3264
|
(valueChange)="selectedUserId.set($event)"
|
|
2950
3265
|
[isEditMode]="true"
|
|
2951
|
-
placeHolder="
|
|
3266
|
+
[placeHolder]="'iam.permission.select.user.placeholder' | translate"
|
|
2952
3267
|
/>
|
|
2953
3268
|
</div>
|
|
2954
3269
|
|
|
@@ -2956,7 +3271,7 @@ class UserRoleSelectorComponent {
|
|
|
2956
3271
|
<div>
|
|
2957
3272
|
<label class="block font-semibold mb-2">
|
|
2958
3273
|
<i class="pi pi-building mr-2 text-primary"></i>
|
|
2959
|
-
|
|
3274
|
+
{{ 'iam.permission.select.branch' | translate }}
|
|
2960
3275
|
</label>
|
|
2961
3276
|
<p-select
|
|
2962
3277
|
[ngModel]="selectedBranchId()"
|
|
@@ -2964,7 +3279,7 @@ class UserRoleSelectorComponent {
|
|
|
2964
3279
|
[options]="filteredBranches()"
|
|
2965
3280
|
optionLabel="name"
|
|
2966
3281
|
optionValue="id"
|
|
2967
|
-
placeholder="
|
|
3282
|
+
[placeholder]="'iam.permission.select.branch.placeholder' | translate"
|
|
2968
3283
|
[showClear]="true"
|
|
2969
3284
|
[filter]="true"
|
|
2970
3285
|
styleClass="w-full"
|
|
@@ -2985,10 +3300,7 @@ class UserRoleSelectorComponent {
|
|
|
2985
3300
|
</ng-template>
|
|
2986
3301
|
</p-select>
|
|
2987
3302
|
<small class="text-muted-color block mt-1">
|
|
2988
|
-
{{ filteredBranches().length
|
|
2989
|
-
filteredBranches().length !== 1 ? 'es' : ''
|
|
2990
|
-
}}
|
|
2991
|
-
in current company
|
|
3303
|
+
{{ (filteredBranches().length !== 1 ? 'iam.branch.permitted.count.plural' : 'iam.branch.permitted.count') | translate: { count: filteredBranches().length } }}
|
|
2992
3304
|
</small>
|
|
2993
3305
|
</div>
|
|
2994
3306
|
}
|
|
@@ -3012,14 +3324,14 @@ class UserRoleSelectorComponent {
|
|
|
3012
3324
|
class="flex flex-col md:flex-row justify-between items-start md:items-center gap-3 mb-4"
|
|
3013
3325
|
>
|
|
3014
3326
|
<div>
|
|
3015
|
-
<h5 class="m-0 mb-1">
|
|
3327
|
+
<h5 class="m-0 mb-1">{{ 'iam.permission.role.assignments' | translate }}</h5>
|
|
3016
3328
|
<p class="text-sm text-muted-color m-0">
|
|
3017
|
-
{{ roles().length }}
|
|
3329
|
+
{{ 'iam.permission.roles.available' | translate: { count: roles().length } }}
|
|
3018
3330
|
</p>
|
|
3019
3331
|
</div>
|
|
3020
3332
|
<div class="flex flex-wrap gap-2">
|
|
3021
3333
|
<p-button
|
|
3022
|
-
label="
|
|
3334
|
+
[label]="'shared.select.all' | translate"
|
|
3023
3335
|
icon="pi pi-check"
|
|
3024
3336
|
[outlined]="true"
|
|
3025
3337
|
size="small"
|
|
@@ -3027,7 +3339,7 @@ class UserRoleSelectorComponent {
|
|
|
3027
3339
|
(onClick)="selectAll()"
|
|
3028
3340
|
/>
|
|
3029
3341
|
<p-button
|
|
3030
|
-
label="
|
|
3342
|
+
[label]="'shared.deselect.all' | translate"
|
|
3031
3343
|
icon="pi pi-times"
|
|
3032
3344
|
[outlined]="true"
|
|
3033
3345
|
size="small"
|
|
@@ -3036,7 +3348,7 @@ class UserRoleSelectorComponent {
|
|
|
3036
3348
|
/>
|
|
3037
3349
|
<p-button
|
|
3038
3350
|
*hasPermission="USER_ROLE_PERMISSIONS.ASSIGN"
|
|
3039
|
-
label="
|
|
3351
|
+
[label]="'shared.save.changes' | translate"
|
|
3040
3352
|
icon="pi pi-save"
|
|
3041
3353
|
[disabled]="!canSave()"
|
|
3042
3354
|
[loading]="saving()"
|
|
@@ -3056,7 +3368,7 @@ class UserRoleSelectorComponent {
|
|
|
3056
3368
|
[rowsPerPageOptions]="[10, 20, 50]"
|
|
3057
3369
|
[globalFilterFields]="['name', 'code', 'description']"
|
|
3058
3370
|
[showCurrentPageReport]="true"
|
|
3059
|
-
currentPageReportTemplate="
|
|
3371
|
+
[currentPageReportTemplate]="'iam.pagination.roles.template' | translate"
|
|
3060
3372
|
styleClass="p-datatable-sm"
|
|
3061
3373
|
[tableStyle]="{ 'min-width': '35rem' }"
|
|
3062
3374
|
>
|
|
@@ -3067,13 +3379,13 @@ class UserRoleSelectorComponent {
|
|
|
3067
3379
|
[ngModel]="allSelected()"
|
|
3068
3380
|
[binary]="true"
|
|
3069
3381
|
(ngModelChange)="toggleAll()"
|
|
3070
|
-
pTooltip="
|
|
3382
|
+
[pTooltip]="'shared.select.deselect.all' | translate"
|
|
3071
3383
|
tooltipPosition="top"
|
|
3072
3384
|
/>
|
|
3073
3385
|
</th>
|
|
3074
|
-
<th>
|
|
3075
|
-
<th class="hidden sm:table-cell">
|
|
3076
|
-
<th class="hidden md:table-cell">
|
|
3386
|
+
<th>{{ 'shared.name' | translate }}</th>
|
|
3387
|
+
<th class="hidden sm:table-cell">{{ 'shared.code' | translate }}</th>
|
|
3388
|
+
<th class="hidden md:table-cell">{{ 'shared.description' | translate }}</th>
|
|
3077
3389
|
</tr>
|
|
3078
3390
|
</ng-template>
|
|
3079
3391
|
<ng-template #body let-role>
|
|
@@ -3096,9 +3408,9 @@ class UserRoleSelectorComponent {
|
|
|
3096
3408
|
<tr>
|
|
3097
3409
|
<td colspan="4" class="text-center p-4 text-muted-color">
|
|
3098
3410
|
@if (loading()) {
|
|
3099
|
-
<i class="pi pi-spin pi-spinner"></i>
|
|
3411
|
+
<i class="pi pi-spin pi-spinner"></i> {{ 'shared.loading.roles' | translate }}
|
|
3100
3412
|
} @else {
|
|
3101
|
-
|
|
3413
|
+
{{ 'iam.permission.no.roles.available' | translate }}
|
|
3102
3414
|
}
|
|
3103
3415
|
</td>
|
|
3104
3416
|
</tr>
|
|
@@ -3112,14 +3424,14 @@ class UserRoleSelectorComponent {
|
|
|
3112
3424
|
<div class="border border-surface rounded-border p-3 mt-4">
|
|
3113
3425
|
<div class="flex items-center gap-2 mb-3">
|
|
3114
3426
|
<i class="pi pi-info-circle text-primary"></i>
|
|
3115
|
-
<span class="font-bold">
|
|
3427
|
+
<span class="font-bold">{{ 'shared.pending.changes' | translate }}</span>
|
|
3116
3428
|
</div>
|
|
3117
3429
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
3118
3430
|
@if (pendingAdd().length > 0) {
|
|
3119
3431
|
<div>
|
|
3120
3432
|
<div class="flex items-center gap-2 mb-2">
|
|
3121
3433
|
<i class="pi pi-plus-circle text-green-500"></i>
|
|
3122
|
-
<strong class="text-sm">
|
|
3434
|
+
<strong class="text-sm">{{ 'shared.to.assign' | translate }} ({{ pendingAdd().length }})</strong>
|
|
3123
3435
|
</div>
|
|
3124
3436
|
<ul class="list-none p-0 m-0 pl-4">
|
|
3125
3437
|
@for (role of pendingAdd(); track role.id) {
|
|
@@ -3132,7 +3444,7 @@ class UserRoleSelectorComponent {
|
|
|
3132
3444
|
<div>
|
|
3133
3445
|
<div class="flex items-center gap-2 mb-2">
|
|
3134
3446
|
<i class="pi pi-minus-circle text-red-500"></i>
|
|
3135
|
-
<strong class="text-sm">
|
|
3447
|
+
<strong class="text-sm">{{ 'shared.to.remove' | translate }} ({{ pendingRemove().length }})</strong>
|
|
3136
3448
|
</div>
|
|
3137
3449
|
<ul class="list-none p-0 m-0 pl-4">
|
|
3138
3450
|
@for (role of pendingRemove(); track role.id) {
|
|
@@ -3150,17 +3462,17 @@ class UserRoleSelectorComponent {
|
|
|
3150
3462
|
<div class="surface-card p-5 rounded-border shadow-sm text-center">
|
|
3151
3463
|
<i class="pi pi-info-circle text-muted-color mb-3 block text-5xl"></i>
|
|
3152
3464
|
<p class="text-muted-color m-0">
|
|
3153
|
-
|
|
3465
|
+
{{ 'iam.permission.no.roles.for.user' | translate }}
|
|
3154
3466
|
</p>
|
|
3155
3467
|
</div>
|
|
3156
3468
|
}
|
|
3157
3469
|
}
|
|
3158
3470
|
</div>
|
|
3159
|
-
`, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "component", type: i4.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i5$1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "component", type: UserSelectComponent, selector: "lib-user-select", inputs: ["value"], outputs: ["valueChange", "userSelected"] }
|
|
3471
|
+
`, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "component", type: i4.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i5$1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "component", type: UserSelectComponent, selector: "lib-user-select", inputs: ["value"], outputs: ["valueChange", "userSelected"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
3160
3472
|
}
|
|
3161
3473
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: UserRoleSelectorComponent, decorators: [{
|
|
3162
3474
|
type: Component,
|
|
3163
|
-
args: [{ selector: 'flusys-user-role-selector',
|
|
3475
|
+
args: [{ selector: 'flusys-user-role-selector', imports: [CommonModule, FormsModule, PrimeModule, HasPermissionDirective, UserSelectComponent, TranslatePipe], template: `
|
|
3164
3476
|
<div class="user-role-selector">
|
|
3165
3477
|
<!-- User and Branch Selectors -->
|
|
3166
3478
|
<div class="surface-card p-4 rounded-border mb-4 shadow-sm">
|
|
@@ -3168,13 +3480,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3168
3480
|
<div>
|
|
3169
3481
|
<label class="block font-semibold mb-2">
|
|
3170
3482
|
<i class="pi pi-user mr-2 text-primary"></i>
|
|
3171
|
-
|
|
3483
|
+
{{ 'iam.permission.select.user' | translate }}
|
|
3172
3484
|
</label>
|
|
3173
3485
|
<lib-user-select
|
|
3174
3486
|
[value]="selectedUserId()"
|
|
3175
3487
|
(valueChange)="selectedUserId.set($event)"
|
|
3176
3488
|
[isEditMode]="true"
|
|
3177
|
-
placeHolder="
|
|
3489
|
+
[placeHolder]="'iam.permission.select.user.placeholder' | translate"
|
|
3178
3490
|
/>
|
|
3179
3491
|
</div>
|
|
3180
3492
|
|
|
@@ -3182,7 +3494,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3182
3494
|
<div>
|
|
3183
3495
|
<label class="block font-semibold mb-2">
|
|
3184
3496
|
<i class="pi pi-building mr-2 text-primary"></i>
|
|
3185
|
-
|
|
3497
|
+
{{ 'iam.permission.select.branch' | translate }}
|
|
3186
3498
|
</label>
|
|
3187
3499
|
<p-select
|
|
3188
3500
|
[ngModel]="selectedBranchId()"
|
|
@@ -3190,7 +3502,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3190
3502
|
[options]="filteredBranches()"
|
|
3191
3503
|
optionLabel="name"
|
|
3192
3504
|
optionValue="id"
|
|
3193
|
-
placeholder="
|
|
3505
|
+
[placeholder]="'iam.permission.select.branch.placeholder' | translate"
|
|
3194
3506
|
[showClear]="true"
|
|
3195
3507
|
[filter]="true"
|
|
3196
3508
|
styleClass="w-full"
|
|
@@ -3211,10 +3523,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3211
3523
|
</ng-template>
|
|
3212
3524
|
</p-select>
|
|
3213
3525
|
<small class="text-muted-color block mt-1">
|
|
3214
|
-
{{ filteredBranches().length
|
|
3215
|
-
filteredBranches().length !== 1 ? 'es' : ''
|
|
3216
|
-
}}
|
|
3217
|
-
in current company
|
|
3526
|
+
{{ (filteredBranches().length !== 1 ? 'iam.branch.permitted.count.plural' : 'iam.branch.permitted.count') | translate: { count: filteredBranches().length } }}
|
|
3218
3527
|
</small>
|
|
3219
3528
|
</div>
|
|
3220
3529
|
}
|
|
@@ -3238,14 +3547,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3238
3547
|
class="flex flex-col md:flex-row justify-between items-start md:items-center gap-3 mb-4"
|
|
3239
3548
|
>
|
|
3240
3549
|
<div>
|
|
3241
|
-
<h5 class="m-0 mb-1">
|
|
3550
|
+
<h5 class="m-0 mb-1">{{ 'iam.permission.role.assignments' | translate }}</h5>
|
|
3242
3551
|
<p class="text-sm text-muted-color m-0">
|
|
3243
|
-
{{ roles().length }}
|
|
3552
|
+
{{ 'iam.permission.roles.available' | translate: { count: roles().length } }}
|
|
3244
3553
|
</p>
|
|
3245
3554
|
</div>
|
|
3246
3555
|
<div class="flex flex-wrap gap-2">
|
|
3247
3556
|
<p-button
|
|
3248
|
-
label="
|
|
3557
|
+
[label]="'shared.select.all' | translate"
|
|
3249
3558
|
icon="pi pi-check"
|
|
3250
3559
|
[outlined]="true"
|
|
3251
3560
|
size="small"
|
|
@@ -3253,7 +3562,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3253
3562
|
(onClick)="selectAll()"
|
|
3254
3563
|
/>
|
|
3255
3564
|
<p-button
|
|
3256
|
-
label="
|
|
3565
|
+
[label]="'shared.deselect.all' | translate"
|
|
3257
3566
|
icon="pi pi-times"
|
|
3258
3567
|
[outlined]="true"
|
|
3259
3568
|
size="small"
|
|
@@ -3262,7 +3571,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3262
3571
|
/>
|
|
3263
3572
|
<p-button
|
|
3264
3573
|
*hasPermission="USER_ROLE_PERMISSIONS.ASSIGN"
|
|
3265
|
-
label="
|
|
3574
|
+
[label]="'shared.save.changes' | translate"
|
|
3266
3575
|
icon="pi pi-save"
|
|
3267
3576
|
[disabled]="!canSave()"
|
|
3268
3577
|
[loading]="saving()"
|
|
@@ -3282,7 +3591,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3282
3591
|
[rowsPerPageOptions]="[10, 20, 50]"
|
|
3283
3592
|
[globalFilterFields]="['name', 'code', 'description']"
|
|
3284
3593
|
[showCurrentPageReport]="true"
|
|
3285
|
-
currentPageReportTemplate="
|
|
3594
|
+
[currentPageReportTemplate]="'iam.pagination.roles.template' | translate"
|
|
3286
3595
|
styleClass="p-datatable-sm"
|
|
3287
3596
|
[tableStyle]="{ 'min-width': '35rem' }"
|
|
3288
3597
|
>
|
|
@@ -3293,13 +3602,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3293
3602
|
[ngModel]="allSelected()"
|
|
3294
3603
|
[binary]="true"
|
|
3295
3604
|
(ngModelChange)="toggleAll()"
|
|
3296
|
-
pTooltip="
|
|
3605
|
+
[pTooltip]="'shared.select.deselect.all' | translate"
|
|
3297
3606
|
tooltipPosition="top"
|
|
3298
3607
|
/>
|
|
3299
3608
|
</th>
|
|
3300
|
-
<th>
|
|
3301
|
-
<th class="hidden sm:table-cell">
|
|
3302
|
-
<th class="hidden md:table-cell">
|
|
3609
|
+
<th>{{ 'shared.name' | translate }}</th>
|
|
3610
|
+
<th class="hidden sm:table-cell">{{ 'shared.code' | translate }}</th>
|
|
3611
|
+
<th class="hidden md:table-cell">{{ 'shared.description' | translate }}</th>
|
|
3303
3612
|
</tr>
|
|
3304
3613
|
</ng-template>
|
|
3305
3614
|
<ng-template #body let-role>
|
|
@@ -3322,9 +3631,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3322
3631
|
<tr>
|
|
3323
3632
|
<td colspan="4" class="text-center p-4 text-muted-color">
|
|
3324
3633
|
@if (loading()) {
|
|
3325
|
-
<i class="pi pi-spin pi-spinner"></i>
|
|
3634
|
+
<i class="pi pi-spin pi-spinner"></i> {{ 'shared.loading.roles' | translate }}
|
|
3326
3635
|
} @else {
|
|
3327
|
-
|
|
3636
|
+
{{ 'iam.permission.no.roles.available' | translate }}
|
|
3328
3637
|
}
|
|
3329
3638
|
</td>
|
|
3330
3639
|
</tr>
|
|
@@ -3338,14 +3647,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3338
3647
|
<div class="border border-surface rounded-border p-3 mt-4">
|
|
3339
3648
|
<div class="flex items-center gap-2 mb-3">
|
|
3340
3649
|
<i class="pi pi-info-circle text-primary"></i>
|
|
3341
|
-
<span class="font-bold">
|
|
3650
|
+
<span class="font-bold">{{ 'shared.pending.changes' | translate }}</span>
|
|
3342
3651
|
</div>
|
|
3343
3652
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
3344
3653
|
@if (pendingAdd().length > 0) {
|
|
3345
3654
|
<div>
|
|
3346
3655
|
<div class="flex items-center gap-2 mb-2">
|
|
3347
3656
|
<i class="pi pi-plus-circle text-green-500"></i>
|
|
3348
|
-
<strong class="text-sm">
|
|
3657
|
+
<strong class="text-sm">{{ 'shared.to.assign' | translate }} ({{ pendingAdd().length }})</strong>
|
|
3349
3658
|
</div>
|
|
3350
3659
|
<ul class="list-none p-0 m-0 pl-4">
|
|
3351
3660
|
@for (role of pendingAdd(); track role.id) {
|
|
@@ -3358,7 +3667,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3358
3667
|
<div>
|
|
3359
3668
|
<div class="flex items-center gap-2 mb-2">
|
|
3360
3669
|
<i class="pi pi-minus-circle text-red-500"></i>
|
|
3361
|
-
<strong class="text-sm">
|
|
3670
|
+
<strong class="text-sm">{{ 'shared.to.remove' | translate }} ({{ pendingRemove().length }})</strong>
|
|
3362
3671
|
</div>
|
|
3363
3672
|
<ul class="list-none p-0 m-0 pl-4">
|
|
3364
3673
|
@for (role of pendingRemove(); track role.id) {
|
|
@@ -3376,7 +3685,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3376
3685
|
<div class="surface-card p-5 rounded-border shadow-sm text-center">
|
|
3377
3686
|
<i class="pi pi-info-circle text-muted-color mb-3 block text-5xl"></i>
|
|
3378
3687
|
<p class="text-muted-color m-0">
|
|
3379
|
-
|
|
3688
|
+
{{ 'iam.permission.no.roles.for.user' | translate }}
|
|
3380
3689
|
</p>
|
|
3381
3690
|
</div>
|
|
3382
3691
|
}
|
|
@@ -3407,7 +3716,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3407
3716
|
* - Branch-specific: branchId = selected value
|
|
3408
3717
|
*
|
|
3409
3718
|
* **Performance:**
|
|
3410
|
-
* - OnPush change detection
|
|
3411
3719
|
* - Computed signals for reactive updates
|
|
3412
3720
|
* - Branch filtering on company context change
|
|
3413
3721
|
*
|
|
@@ -3427,6 +3735,10 @@ class UserActionSelectorComponent {
|
|
|
3427
3735
|
permissionApi = inject(PermissionApiService);
|
|
3428
3736
|
permissionLogic = inject(ActionPermissionLogicService);
|
|
3429
3737
|
messageService = inject(MessageService);
|
|
3738
|
+
translateAdapter = inject(TRANSLATE_ADAPTER, { optional: true });
|
|
3739
|
+
translate(key, vars) {
|
|
3740
|
+
return this.translateAdapter?.translate(key, vars) ?? key;
|
|
3741
|
+
}
|
|
3430
3742
|
// State - User/Branch Selection
|
|
3431
3743
|
selectedUserId = signal(null, ...(ngDevMode ? [{ debugName: "selectedUserId" }] : []));
|
|
3432
3744
|
selectedBranchId = signal(undefined, ...(ngDevMode ? [{ debugName: "selectedBranchId" }] : []));
|
|
@@ -3595,15 +3907,15 @@ class UserActionSelectorComponent {
|
|
|
3595
3907
|
const prerequisiteInfo = this.permissionLogic.getPrerequisiteTooltip(action, selMap, this.actions());
|
|
3596
3908
|
if (prerequisiteInfo) {
|
|
3597
3909
|
const actionHint = isCurrentlySelected
|
|
3598
|
-
?
|
|
3599
|
-
:
|
|
3910
|
+
? `\n\n---\n[${this.translate('shared.remove')}] ${this.translate('iam.tooltip.remove.action')}`
|
|
3911
|
+
: `\n\n---\n[${this.translate('shared.add')}] ${this.translate('iam.tooltip.add.action')}`;
|
|
3600
3912
|
return `${prerequisiteInfo}${actionHint}`;
|
|
3601
3913
|
}
|
|
3602
3914
|
}
|
|
3603
3915
|
if (isCurrentlySelected) {
|
|
3604
|
-
return '
|
|
3916
|
+
return `[${this.translate('shared.assigned')}] ${this.translate('iam.tooltip.assigned.to.user')}\n\n[${this.translate('shared.remove')}] ${this.translate('iam.tooltip.click.to.remove.user')}`;
|
|
3605
3917
|
}
|
|
3606
|
-
return '
|
|
3918
|
+
return `[${this.translate('shared.add')}] ${this.translate('iam.tooltip.click.to.assign.user')}`;
|
|
3607
3919
|
}
|
|
3608
3920
|
/**
|
|
3609
3921
|
* Check if action has unmet prerequisites
|
|
@@ -3647,8 +3959,8 @@ class UserActionSelectorComponent {
|
|
|
3647
3959
|
if (this.isCompanyFeatureActive() && !companyId) {
|
|
3648
3960
|
this.messageService.add({
|
|
3649
3961
|
severity: 'warn',
|
|
3650
|
-
summary: '
|
|
3651
|
-
detail: '
|
|
3962
|
+
summary: this.translate('shared.warning'),
|
|
3963
|
+
detail: this.translate('iam.permission.company.required'),
|
|
3652
3964
|
});
|
|
3653
3965
|
return;
|
|
3654
3966
|
}
|
|
@@ -3672,9 +3984,8 @@ class UserActionSelectorComponent {
|
|
|
3672
3984
|
const response = await firstValueFrom(this.permissionApi.assignUserActions(payload));
|
|
3673
3985
|
this.messageService.add({
|
|
3674
3986
|
severity: 'success',
|
|
3675
|
-
summary: '
|
|
3676
|
-
detail: response?.data?.message ||
|
|
3677
|
-
'User action permissions updated successfully',
|
|
3987
|
+
summary: this.translate('shared.success'),
|
|
3988
|
+
detail: response?.data?.message || this.translate('iam.permission.user.actions.updated'),
|
|
3678
3989
|
});
|
|
3679
3990
|
this._initialSelection.set({ ...this.selectionMap() });
|
|
3680
3991
|
}
|
|
@@ -3717,13 +4028,13 @@ class UserActionSelectorComponent {
|
|
|
3717
4028
|
<div>
|
|
3718
4029
|
<label class="block font-semibold mb-2">
|
|
3719
4030
|
<i class="pi pi-user mr-2 text-primary"></i>
|
|
3720
|
-
|
|
4031
|
+
{{ 'iam.permission.select.user' | translate }}
|
|
3721
4032
|
</label>
|
|
3722
4033
|
<lib-user-select
|
|
3723
4034
|
[value]="selectedUserId()"
|
|
3724
4035
|
(valueChange)="selectedUserId.set($event)"
|
|
3725
4036
|
[isEditMode]="true"
|
|
3726
|
-
placeHolder="
|
|
4037
|
+
[placeHolder]="'iam.permission.select.user.placeholder' | translate"
|
|
3727
4038
|
/>
|
|
3728
4039
|
</div>
|
|
3729
4040
|
|
|
@@ -3731,7 +4042,7 @@ class UserActionSelectorComponent {
|
|
|
3731
4042
|
<div>
|
|
3732
4043
|
<label class="block font-semibold mb-2">
|
|
3733
4044
|
<i class="pi pi-building mr-2 text-primary"></i>
|
|
3734
|
-
|
|
4045
|
+
{{ 'iam.permission.select.branch' | translate }}
|
|
3735
4046
|
</label>
|
|
3736
4047
|
<p-select
|
|
3737
4048
|
[ngModel]="selectedBranchId()"
|
|
@@ -3739,7 +4050,7 @@ class UserActionSelectorComponent {
|
|
|
3739
4050
|
[options]="filteredBranches()"
|
|
3740
4051
|
optionLabel="name"
|
|
3741
4052
|
optionValue="id"
|
|
3742
|
-
placeholder="
|
|
4053
|
+
[placeholder]="'iam.permission.select.branch.placeholder' | translate"
|
|
3743
4054
|
[showClear]="true"
|
|
3744
4055
|
[filter]="true"
|
|
3745
4056
|
styleClass="w-full"
|
|
@@ -3760,10 +4071,7 @@ class UserActionSelectorComponent {
|
|
|
3760
4071
|
</ng-template>
|
|
3761
4072
|
</p-select>
|
|
3762
4073
|
<small class="text-muted-color block mt-1">
|
|
3763
|
-
{{ filteredBranches().length
|
|
3764
|
-
filteredBranches().length !== 1 ? 'es' : ''
|
|
3765
|
-
}}
|
|
3766
|
-
in current company
|
|
4074
|
+
{{ (filteredBranches().length !== 1 ? 'iam.branch.permitted.count.plural' : 'iam.branch.permitted.count') | translate: { count: filteredBranches().length } }}
|
|
3767
4075
|
</small>
|
|
3768
4076
|
</div>
|
|
3769
4077
|
}
|
|
@@ -3785,14 +4093,14 @@ class UserActionSelectorComponent {
|
|
|
3785
4093
|
class="flex flex-col md:flex-row justify-between items-start md:items-center gap-3 mb-4"
|
|
3786
4094
|
>
|
|
3787
4095
|
<div>
|
|
3788
|
-
<h5 class="m-0 mb-1">
|
|
4096
|
+
<h5 class="m-0 mb-1">{{ 'iam.permission.direct.action.permissions' | translate }}</h5>
|
|
3789
4097
|
<p class="text-sm text-muted-color m-0">
|
|
3790
|
-
{{ actions().length }}
|
|
4098
|
+
{{ 'iam.permission.actions.available' | translate: { count: actions().length } }}
|
|
3791
4099
|
</p>
|
|
3792
4100
|
</div>
|
|
3793
4101
|
<div class="flex flex-wrap gap-2">
|
|
3794
4102
|
<p-button
|
|
3795
|
-
label="
|
|
4103
|
+
[label]="'shared.select.all' | translate"
|
|
3796
4104
|
icon="pi pi-check"
|
|
3797
4105
|
[outlined]="true"
|
|
3798
4106
|
size="small"
|
|
@@ -3800,7 +4108,7 @@ class UserActionSelectorComponent {
|
|
|
3800
4108
|
(onClick)="selectAll()"
|
|
3801
4109
|
/>
|
|
3802
4110
|
<p-button
|
|
3803
|
-
label="
|
|
4111
|
+
[label]="'shared.deselect.all' | translate"
|
|
3804
4112
|
icon="pi pi-times"
|
|
3805
4113
|
[outlined]="true"
|
|
3806
4114
|
size="small"
|
|
@@ -3809,7 +4117,7 @@ class UserActionSelectorComponent {
|
|
|
3809
4117
|
/>
|
|
3810
4118
|
<p-button
|
|
3811
4119
|
*hasPermission="USER_ACTION_PERMISSIONS.ASSIGN"
|
|
3812
|
-
label="
|
|
4120
|
+
[label]="'shared.save.changes' | translate"
|
|
3813
4121
|
icon="pi pi-save"
|
|
3814
4122
|
[disabled]="!canSave()"
|
|
3815
4123
|
[loading]="saving()"
|
|
@@ -3826,12 +4134,9 @@ class UserActionSelectorComponent {
|
|
|
3826
4134
|
<div class="flex items-start gap-2">
|
|
3827
4135
|
<i class="pi pi-exclamation-triangle text-xl"></i>
|
|
3828
4136
|
<div class="flex-1">
|
|
3829
|
-
<span class="font-semibold">
|
|
4137
|
+
<span class="font-semibold">{{ 'iam.validation.warning.title' | translate }}:</span>
|
|
3830
4138
|
<p class="text-sm mt-1 mb-0">
|
|
3831
|
-
{{ invalidActionsCount() }}
|
|
3832
|
-
action{{ invalidActionsCount() > 1 ? 's have' : ' has' }}
|
|
3833
|
-
unmet prerequisites. Fix before saving or use auto-fix on
|
|
3834
|
-
save.
|
|
4139
|
+
{{ (invalidActionsCount() > 1 ? 'iam.validation.unmet.prerequisites.plural' : 'iam.validation.unmet.prerequisites.singular') | translate: { count: invalidActionsCount() } }}
|
|
3835
4140
|
</p>
|
|
3836
4141
|
</div>
|
|
3837
4142
|
</div>
|
|
@@ -3853,14 +4158,14 @@ class UserActionSelectorComponent {
|
|
|
3853
4158
|
[ngModel]="allSelected()"
|
|
3854
4159
|
[binary]="true"
|
|
3855
4160
|
(ngModelChange)="toggleAll()"
|
|
3856
|
-
pTooltip="
|
|
4161
|
+
[pTooltip]="'shared.select.deselect.all' | translate"
|
|
3857
4162
|
tooltipPosition="top"
|
|
3858
4163
|
/>
|
|
3859
4164
|
</th>
|
|
3860
|
-
<th>
|
|
3861
|
-
<th class="hidden md:table-cell">
|
|
3862
|
-
<th>
|
|
3863
|
-
<th class="hidden lg:table-cell">
|
|
4165
|
+
<th>{{ 'shared.name' | translate }}</th>
|
|
4166
|
+
<th class="hidden md:table-cell">{{ 'shared.code' | translate }}</th>
|
|
4167
|
+
<th>{{ 'iam.action.type' | translate }}</th>
|
|
4168
|
+
<th class="hidden lg:table-cell">{{ 'shared.description' | translate }}</th>
|
|
3864
4169
|
</tr>
|
|
3865
4170
|
</ng-template>
|
|
3866
4171
|
<ng-template #body let-rowNode let-rowData="rowData">
|
|
@@ -3881,7 +4186,7 @@ class UserActionSelectorComponent {
|
|
|
3881
4186
|
@if (hasUnmetPrerequisites(rowData)) {
|
|
3882
4187
|
<i
|
|
3883
4188
|
class="pi pi-exclamation-triangle text-orange-500"
|
|
3884
|
-
pTooltip="
|
|
4189
|
+
[pTooltip]="'iam.validation.unmet.prerequisites.tooltip' | translate"
|
|
3885
4190
|
tooltipPosition="top"
|
|
3886
4191
|
></i>
|
|
3887
4192
|
}
|
|
@@ -3903,9 +4208,9 @@ class UserActionSelectorComponent {
|
|
|
3903
4208
|
<tr>
|
|
3904
4209
|
<td colspan="5" class="text-center p-4 text-muted-color">
|
|
3905
4210
|
@if (loading()) {
|
|
3906
|
-
<i class="pi pi-spin pi-spinner"></i>
|
|
4211
|
+
<i class="pi pi-spin pi-spinner"></i> {{ 'shared.loading.actions' | translate }}
|
|
3907
4212
|
} @else {
|
|
3908
|
-
|
|
4213
|
+
{{ 'iam.permission.no.actions.available' | translate }}
|
|
3909
4214
|
}
|
|
3910
4215
|
</td>
|
|
3911
4216
|
</tr>
|
|
@@ -3919,14 +4224,14 @@ class UserActionSelectorComponent {
|
|
|
3919
4224
|
<div class="border border-surface rounded-border p-3 mt-4">
|
|
3920
4225
|
<div class="flex items-center gap-2 mb-3">
|
|
3921
4226
|
<i class="pi pi-info-circle text-primary"></i>
|
|
3922
|
-
<span class="font-bold">
|
|
4227
|
+
<span class="font-bold">{{ 'shared.pending.changes' | translate }}</span>
|
|
3923
4228
|
</div>
|
|
3924
4229
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
3925
4230
|
@if (pendingAdd().length > 0) {
|
|
3926
4231
|
<div>
|
|
3927
4232
|
<div class="flex items-center gap-2 mb-2">
|
|
3928
4233
|
<i class="pi pi-plus-circle text-green-500"></i>
|
|
3929
|
-
<strong class="text-sm">
|
|
4234
|
+
<strong class="text-sm">{{ 'shared.to.assign' | translate }} ({{ pendingAdd().length }})</strong>
|
|
3930
4235
|
</div>
|
|
3931
4236
|
<ul class="list-none p-0 m-0 pl-4">
|
|
3932
4237
|
@for (action of pendingAdd(); track action.id) {
|
|
@@ -3939,7 +4244,7 @@ class UserActionSelectorComponent {
|
|
|
3939
4244
|
<div>
|
|
3940
4245
|
<div class="flex items-center gap-2 mb-2">
|
|
3941
4246
|
<i class="pi pi-minus-circle text-red-500"></i>
|
|
3942
|
-
<strong class="text-sm">
|
|
4247
|
+
<strong class="text-sm">{{ 'shared.to.remove' | translate }} ({{ pendingRemove().length }})</strong>
|
|
3943
4248
|
</div>
|
|
3944
4249
|
<ul class="list-none p-0 m-0 pl-4">
|
|
3945
4250
|
@for (action of pendingRemove(); track action.id) {
|
|
@@ -3957,17 +4262,17 @@ class UserActionSelectorComponent {
|
|
|
3957
4262
|
<div class="surface-card p-5 rounded-border shadow-sm text-center">
|
|
3958
4263
|
<i class="pi pi-info-circle text-muted-color mb-3 block text-5xl"></i>
|
|
3959
4264
|
<p class="text-muted-color m-0">
|
|
3960
|
-
|
|
4265
|
+
{{ 'iam.permission.no.actions.for.user' | translate }}
|
|
3961
4266
|
</p>
|
|
3962
4267
|
</div>
|
|
3963
4268
|
}
|
|
3964
4269
|
}
|
|
3965
4270
|
</div>
|
|
3966
|
-
`, isInline: true, styles: [":host{display:block}.validation-warning{background-color:var(--p-yellow-50, #fefce8);border-left:4px solid var(--p-yellow-500, #eab308);color:var(--p-yellow-700, #a16207)}:host-context(.p-dark) .validation-warning{background-color:#eab3081a;color:var(--p-yellow-400, #facc15)}:host ::ng-deep tr.highlight-warning{background-color:var(--p-red-50, rgba(239, 68, 68, .1))!important}:host-context(.p-dark) ::ng-deep tr.highlight-warning{background-color:#ef444426!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "component", type: i4.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i5.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: i7.TreeTable, selector: "p-treeTable, p-treetable, p-tree-table", inputs: ["columns", "styleClass", "tableStyle", "tableStyleClass", "autoLayout", "lazy", "lazyLoadOnInit", "paginator", "rows", "first", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "customSort", "selectionMode", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "compareSelectionBy", "rowHover", "loading", "loadingIcon", "showLoader", "scrollable", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "frozenColumns", "resizableColumns", "columnResizeMode", "reorderableColumns", "contextMenu", "rowTrackBy", "filters", "globalFilterFields", "filterDelay", "filterMode", "filterLocale", "paginatorLocale", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "value", "virtualRowHeight", "selectionKeys", "showGridlines"], outputs: ["selectionChange", "contextMenuSelectionChange", "onFilter", "onNodeExpand", "onNodeCollapse", "onPage", "onSort", "onLazyLoad", "sortFunction", "onColResize", "onColReorder", "onNodeSelect", "onNodeUnselect", "onContextMenuSelect", "onHeaderCheckboxToggle", "onEditInit", "onEditComplete", "onEditCancel", "selectionKeysChange"] }, { kind: "component", type: i7.TreeTableToggler, selector: "p-treeTableToggler, p-treetabletoggler, p-treetable-toggler", inputs: ["rowNode"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "component", type: UserSelectComponent, selector: "lib-user-select", inputs: ["value"], outputs: ["valueChange", "userSelected"] }
|
|
4271
|
+
`, isInline: true, styles: [":host{display:block}.validation-warning{background-color:var(--p-yellow-50, #fefce8);border-left:4px solid var(--p-yellow-500, #eab308);color:var(--p-yellow-700, #a16207)}:host-context(.p-dark) .validation-warning{background-color:#eab3081a;color:var(--p-yellow-400, #facc15)}:host ::ng-deep tr.highlight-warning{background-color:var(--p-red-50, rgba(239, 68, 68, .1))!important}:host-context(.p-dark) ::ng-deep tr.highlight-warning{background-color:#ef444426!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "component", type: i4.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i5.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: i7.TreeTable, selector: "p-treeTable, p-treetable, p-tree-table", inputs: ["columns", "styleClass", "tableStyle", "tableStyleClass", "autoLayout", "lazy", "lazyLoadOnInit", "paginator", "rows", "first", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "customSort", "selectionMode", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "compareSelectionBy", "rowHover", "loading", "loadingIcon", "showLoader", "scrollable", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "frozenColumns", "resizableColumns", "columnResizeMode", "reorderableColumns", "contextMenu", "rowTrackBy", "filters", "globalFilterFields", "filterDelay", "filterMode", "filterLocale", "paginatorLocale", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "value", "virtualRowHeight", "selectionKeys", "showGridlines"], outputs: ["selectionChange", "contextMenuSelectionChange", "onFilter", "onNodeExpand", "onNodeCollapse", "onPage", "onSort", "onLazyLoad", "sortFunction", "onColResize", "onColReorder", "onNodeSelect", "onNodeUnselect", "onContextMenuSelect", "onHeaderCheckboxToggle", "onEditInit", "onEditComplete", "onEditCancel", "selectionKeysChange"] }, { kind: "component", type: i7.TreeTableToggler, selector: "p-treeTableToggler, p-treetabletoggler, p-treetable-toggler", inputs: ["rowNode"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "component", type: UserSelectComponent, selector: "lib-user-select", inputs: ["value"], outputs: ["valueChange", "userSelected"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
3967
4272
|
}
|
|
3968
4273
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: UserActionSelectorComponent, decorators: [{
|
|
3969
4274
|
type: Component,
|
|
3970
|
-
args: [{ selector: 'flusys-user-action-selector',
|
|
4275
|
+
args: [{ selector: 'flusys-user-action-selector', imports: [CommonModule, FormsModule, PrimeModule, HasPermissionDirective, UserSelectComponent, TranslatePipe], template: `
|
|
3971
4276
|
<div class="user-action-selector">
|
|
3972
4277
|
<!-- User and Branch Selectors -->
|
|
3973
4278
|
<div class="surface-card p-4 rounded-border mb-4 shadow-sm">
|
|
@@ -3975,13 +4280,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3975
4280
|
<div>
|
|
3976
4281
|
<label class="block font-semibold mb-2">
|
|
3977
4282
|
<i class="pi pi-user mr-2 text-primary"></i>
|
|
3978
|
-
|
|
4283
|
+
{{ 'iam.permission.select.user' | translate }}
|
|
3979
4284
|
</label>
|
|
3980
4285
|
<lib-user-select
|
|
3981
4286
|
[value]="selectedUserId()"
|
|
3982
4287
|
(valueChange)="selectedUserId.set($event)"
|
|
3983
4288
|
[isEditMode]="true"
|
|
3984
|
-
placeHolder="
|
|
4289
|
+
[placeHolder]="'iam.permission.select.user.placeholder' | translate"
|
|
3985
4290
|
/>
|
|
3986
4291
|
</div>
|
|
3987
4292
|
|
|
@@ -3989,7 +4294,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3989
4294
|
<div>
|
|
3990
4295
|
<label class="block font-semibold mb-2">
|
|
3991
4296
|
<i class="pi pi-building mr-2 text-primary"></i>
|
|
3992
|
-
|
|
4297
|
+
{{ 'iam.permission.select.branch' | translate }}
|
|
3993
4298
|
</label>
|
|
3994
4299
|
<p-select
|
|
3995
4300
|
[ngModel]="selectedBranchId()"
|
|
@@ -3997,7 +4302,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
3997
4302
|
[options]="filteredBranches()"
|
|
3998
4303
|
optionLabel="name"
|
|
3999
4304
|
optionValue="id"
|
|
4000
|
-
placeholder="
|
|
4305
|
+
[placeholder]="'iam.permission.select.branch.placeholder' | translate"
|
|
4001
4306
|
[showClear]="true"
|
|
4002
4307
|
[filter]="true"
|
|
4003
4308
|
styleClass="w-full"
|
|
@@ -4018,10 +4323,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
4018
4323
|
</ng-template>
|
|
4019
4324
|
</p-select>
|
|
4020
4325
|
<small class="text-muted-color block mt-1">
|
|
4021
|
-
{{ filteredBranches().length
|
|
4022
|
-
filteredBranches().length !== 1 ? 'es' : ''
|
|
4023
|
-
}}
|
|
4024
|
-
in current company
|
|
4326
|
+
{{ (filteredBranches().length !== 1 ? 'iam.branch.permitted.count.plural' : 'iam.branch.permitted.count') | translate: { count: filteredBranches().length } }}
|
|
4025
4327
|
</small>
|
|
4026
4328
|
</div>
|
|
4027
4329
|
}
|
|
@@ -4043,14 +4345,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
4043
4345
|
class="flex flex-col md:flex-row justify-between items-start md:items-center gap-3 mb-4"
|
|
4044
4346
|
>
|
|
4045
4347
|
<div>
|
|
4046
|
-
<h5 class="m-0 mb-1">
|
|
4348
|
+
<h5 class="m-0 mb-1">{{ 'iam.permission.direct.action.permissions' | translate }}</h5>
|
|
4047
4349
|
<p class="text-sm text-muted-color m-0">
|
|
4048
|
-
{{ actions().length }}
|
|
4350
|
+
{{ 'iam.permission.actions.available' | translate: { count: actions().length } }}
|
|
4049
4351
|
</p>
|
|
4050
4352
|
</div>
|
|
4051
4353
|
<div class="flex flex-wrap gap-2">
|
|
4052
4354
|
<p-button
|
|
4053
|
-
label="
|
|
4355
|
+
[label]="'shared.select.all' | translate"
|
|
4054
4356
|
icon="pi pi-check"
|
|
4055
4357
|
[outlined]="true"
|
|
4056
4358
|
size="small"
|
|
@@ -4058,7 +4360,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
4058
4360
|
(onClick)="selectAll()"
|
|
4059
4361
|
/>
|
|
4060
4362
|
<p-button
|
|
4061
|
-
label="
|
|
4363
|
+
[label]="'shared.deselect.all' | translate"
|
|
4062
4364
|
icon="pi pi-times"
|
|
4063
4365
|
[outlined]="true"
|
|
4064
4366
|
size="small"
|
|
@@ -4067,7 +4369,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
4067
4369
|
/>
|
|
4068
4370
|
<p-button
|
|
4069
4371
|
*hasPermission="USER_ACTION_PERMISSIONS.ASSIGN"
|
|
4070
|
-
label="
|
|
4372
|
+
[label]="'shared.save.changes' | translate"
|
|
4071
4373
|
icon="pi pi-save"
|
|
4072
4374
|
[disabled]="!canSave()"
|
|
4073
4375
|
[loading]="saving()"
|
|
@@ -4084,12 +4386,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
4084
4386
|
<div class="flex items-start gap-2">
|
|
4085
4387
|
<i class="pi pi-exclamation-triangle text-xl"></i>
|
|
4086
4388
|
<div class="flex-1">
|
|
4087
|
-
<span class="font-semibold">
|
|
4389
|
+
<span class="font-semibold">{{ 'iam.validation.warning.title' | translate }}:</span>
|
|
4088
4390
|
<p class="text-sm mt-1 mb-0">
|
|
4089
|
-
{{ invalidActionsCount() }}
|
|
4090
|
-
action{{ invalidActionsCount() > 1 ? 's have' : ' has' }}
|
|
4091
|
-
unmet prerequisites. Fix before saving or use auto-fix on
|
|
4092
|
-
save.
|
|
4391
|
+
{{ (invalidActionsCount() > 1 ? 'iam.validation.unmet.prerequisites.plural' : 'iam.validation.unmet.prerequisites.singular') | translate: { count: invalidActionsCount() } }}
|
|
4093
4392
|
</p>
|
|
4094
4393
|
</div>
|
|
4095
4394
|
</div>
|
|
@@ -4111,14 +4410,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
4111
4410
|
[ngModel]="allSelected()"
|
|
4112
4411
|
[binary]="true"
|
|
4113
4412
|
(ngModelChange)="toggleAll()"
|
|
4114
|
-
pTooltip="
|
|
4413
|
+
[pTooltip]="'shared.select.deselect.all' | translate"
|
|
4115
4414
|
tooltipPosition="top"
|
|
4116
4415
|
/>
|
|
4117
4416
|
</th>
|
|
4118
|
-
<th>
|
|
4119
|
-
<th class="hidden md:table-cell">
|
|
4120
|
-
<th>
|
|
4121
|
-
<th class="hidden lg:table-cell">
|
|
4417
|
+
<th>{{ 'shared.name' | translate }}</th>
|
|
4418
|
+
<th class="hidden md:table-cell">{{ 'shared.code' | translate }}</th>
|
|
4419
|
+
<th>{{ 'iam.action.type' | translate }}</th>
|
|
4420
|
+
<th class="hidden lg:table-cell">{{ 'shared.description' | translate }}</th>
|
|
4122
4421
|
</tr>
|
|
4123
4422
|
</ng-template>
|
|
4124
4423
|
<ng-template #body let-rowNode let-rowData="rowData">
|
|
@@ -4139,7 +4438,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
4139
4438
|
@if (hasUnmetPrerequisites(rowData)) {
|
|
4140
4439
|
<i
|
|
4141
4440
|
class="pi pi-exclamation-triangle text-orange-500"
|
|
4142
|
-
pTooltip="
|
|
4441
|
+
[pTooltip]="'iam.validation.unmet.prerequisites.tooltip' | translate"
|
|
4143
4442
|
tooltipPosition="top"
|
|
4144
4443
|
></i>
|
|
4145
4444
|
}
|
|
@@ -4161,9 +4460,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
4161
4460
|
<tr>
|
|
4162
4461
|
<td colspan="5" class="text-center p-4 text-muted-color">
|
|
4163
4462
|
@if (loading()) {
|
|
4164
|
-
<i class="pi pi-spin pi-spinner"></i>
|
|
4463
|
+
<i class="pi pi-spin pi-spinner"></i> {{ 'shared.loading.actions' | translate }}
|
|
4165
4464
|
} @else {
|
|
4166
|
-
|
|
4465
|
+
{{ 'iam.permission.no.actions.available' | translate }}
|
|
4167
4466
|
}
|
|
4168
4467
|
</td>
|
|
4169
4468
|
</tr>
|
|
@@ -4177,14 +4476,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
4177
4476
|
<div class="border border-surface rounded-border p-3 mt-4">
|
|
4178
4477
|
<div class="flex items-center gap-2 mb-3">
|
|
4179
4478
|
<i class="pi pi-info-circle text-primary"></i>
|
|
4180
|
-
<span class="font-bold">
|
|
4479
|
+
<span class="font-bold">{{ 'shared.pending.changes' | translate }}</span>
|
|
4181
4480
|
</div>
|
|
4182
4481
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
4183
4482
|
@if (pendingAdd().length > 0) {
|
|
4184
4483
|
<div>
|
|
4185
4484
|
<div class="flex items-center gap-2 mb-2">
|
|
4186
4485
|
<i class="pi pi-plus-circle text-green-500"></i>
|
|
4187
|
-
<strong class="text-sm">
|
|
4486
|
+
<strong class="text-sm">{{ 'shared.to.assign' | translate }} ({{ pendingAdd().length }})</strong>
|
|
4188
4487
|
</div>
|
|
4189
4488
|
<ul class="list-none p-0 m-0 pl-4">
|
|
4190
4489
|
@for (action of pendingAdd(); track action.id) {
|
|
@@ -4197,7 +4496,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
4197
4496
|
<div>
|
|
4198
4497
|
<div class="flex items-center gap-2 mb-2">
|
|
4199
4498
|
<i class="pi pi-minus-circle text-red-500"></i>
|
|
4200
|
-
<strong class="text-sm">
|
|
4499
|
+
<strong class="text-sm">{{ 'shared.to.remove' | translate }} ({{ pendingRemove().length }})</strong>
|
|
4201
4500
|
</div>
|
|
4202
4501
|
<ul class="list-none p-0 m-0 pl-4">
|
|
4203
4502
|
@for (action of pendingRemove(); track action.id) {
|
|
@@ -4215,7 +4514,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
4215
4514
|
<div class="surface-card p-5 rounded-border shadow-sm text-center">
|
|
4216
4515
|
<i class="pi pi-info-circle text-muted-color mb-3 block text-5xl"></i>
|
|
4217
4516
|
<p class="text-muted-color m-0">
|
|
4218
|
-
|
|
4517
|
+
{{ 'iam.permission.no.actions.for.user' | translate }}
|
|
4219
4518
|
</p>
|
|
4220
4519
|
</div>
|
|
4221
4520
|
}
|
|
@@ -4296,7 +4595,8 @@ function provideIamProviders() {
|
|
|
4296
4595
|
const IAM_ROUTES = [
|
|
4297
4596
|
{
|
|
4298
4597
|
path: '',
|
|
4299
|
-
|
|
4598
|
+
resolve: { translations: resolveTranslationModule({ modules: ['iam'], fallbackMessages: { ...IAM_MESSAGES, ...SHARED_MESSAGES } }) },
|
|
4599
|
+
loadComponent: () => import('./flusys-ng-iam-iam-container.component-CQA2B6cU.mjs').then((m) => m.IamContainerComponent),
|
|
4300
4600
|
children: [
|
|
4301
4601
|
// Actions Management
|
|
4302
4602
|
{
|
|
@@ -4305,15 +4605,15 @@ const IAM_ROUTES = [
|
|
|
4305
4605
|
children: [
|
|
4306
4606
|
{
|
|
4307
4607
|
path: '',
|
|
4308
|
-
loadComponent: () => import('./flusys-ng-iam-action-list-page.component-
|
|
4608
|
+
loadComponent: () => import('./flusys-ng-iam-action-list-page.component-BrpZujxk.mjs').then((m) => m.ActionListPageComponent),
|
|
4309
4609
|
},
|
|
4310
4610
|
{
|
|
4311
4611
|
path: 'new',
|
|
4312
|
-
loadComponent: () => import('./flusys-ng-iam-action-form-page.component-
|
|
4612
|
+
loadComponent: () => import('./flusys-ng-iam-action-form-page.component-BQx9yset.mjs').then((m) => m.ActionFormPageComponent),
|
|
4313
4613
|
},
|
|
4314
4614
|
{
|
|
4315
4615
|
path: ':id',
|
|
4316
|
-
loadComponent: () => import('./flusys-ng-iam-action-form-page.component-
|
|
4616
|
+
loadComponent: () => import('./flusys-ng-iam-action-form-page.component-BQx9yset.mjs').then((m) => m.ActionFormPageComponent),
|
|
4317
4617
|
},
|
|
4318
4618
|
],
|
|
4319
4619
|
},
|
|
@@ -4324,15 +4624,15 @@ const IAM_ROUTES = [
|
|
|
4324
4624
|
children: [
|
|
4325
4625
|
{
|
|
4326
4626
|
path: '',
|
|
4327
|
-
loadComponent: () => import('./flusys-ng-iam-role-list-page.component-
|
|
4627
|
+
loadComponent: () => import('./flusys-ng-iam-role-list-page.component-BHB8X5r7.mjs').then((m) => m.RoleListPageComponent),
|
|
4328
4628
|
},
|
|
4329
4629
|
{
|
|
4330
4630
|
path: 'new',
|
|
4331
|
-
loadComponent: () => import('./flusys-ng-iam-role-form-page.component-
|
|
4631
|
+
loadComponent: () => import('./flusys-ng-iam-role-form-page.component-CVfRQpoa.mjs').then((m) => m.RoleFormPageComponent),
|
|
4332
4632
|
},
|
|
4333
4633
|
{
|
|
4334
4634
|
path: ':id',
|
|
4335
|
-
loadComponent: () => import('./flusys-ng-iam-role-form-page.component-
|
|
4635
|
+
loadComponent: () => import('./flusys-ng-iam-role-form-page.component-CVfRQpoa.mjs').then((m) => m.RoleFormPageComponent),
|
|
4336
4636
|
},
|
|
4337
4637
|
],
|
|
4338
4638
|
},
|
|
@@ -4347,7 +4647,7 @@ const IAM_ROUTES = [
|
|
|
4347
4647
|
COMPANY_ACTION_PERMISSIONS.READ,
|
|
4348
4648
|
]),
|
|
4349
4649
|
],
|
|
4350
|
-
loadComponent: () => import('./flusys-ng-iam-permission-page.component-
|
|
4650
|
+
loadComponent: () => import('./flusys-ng-iam-permission-page.component-Dpk90y72.mjs').then((m) => m.PermissionPageComponent),
|
|
4351
4651
|
},
|
|
4352
4652
|
// Default redirect to actions
|
|
4353
4653
|
{
|
|
@@ -4365,5 +4665,5 @@ const IAM_ROUTES = [
|
|
|
4365
4665
|
* Generated bundle index. Do not edit.
|
|
4366
4666
|
*/
|
|
4367
4667
|
|
|
4368
|
-
export { ActionApiService as A, CompanyActionSelectorComponent as C,
|
|
4369
|
-
//# sourceMappingURL=flusys-ng-iam-flusys-ng-iam-
|
|
4668
|
+
export { ActionApiService as A, CompanyActionSelectorComponent as C, IAM_MESSAGES as I, LogicBuilderComponent as L, MAX_DROPDOWN_ITEMS as M, PermissionApiService as P, RoleApiService as R, UserRoleSelectorComponent as U, ActionType as a, RoleActionSelectorComponent as b, convertActionToTreeNode as c, UserActionSelectorComponent as d, ActionPermissionLogicService as e, IAM_ROUTES as f, MyPermissionsApiService as g, PermissionStateService as h, ProfilePermissionProviderAdapter as i, provideIamProviders as p };
|
|
4669
|
+
//# sourceMappingURL=flusys-ng-iam-flusys-ng-iam-Co4ot9My.mjs.map
|