@flusys/ng-iam 9.1.0 → 9.1.2
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/fesm2022/flusys-ng-iam-action-form-page.component-DJ-A1gc2.mjs +685 -0
- package/fesm2022/flusys-ng-iam-action-form-page.component-DJ-A1gc2.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-action-list-page.component-Cf4Dhh5S.mjs → flusys-ng-iam-action-list-page.component-Br0PbgRa.mjs} +369 -166
- package/fesm2022/flusys-ng-iam-action-list-page.component-Br0PbgRa.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam-iam-container.component-CIdxVCSW.mjs +141 -0
- package/fesm2022/flusys-ng-iam-iam-container.component-CIdxVCSW.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam-permission-api.service-C7-Yxvz8.mjs +76 -0
- package/fesm2022/flusys-ng-iam-permission-api.service-C7-Yxvz8.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam-permission-page.component-BlNt83uR.mjs +306 -0
- package/fesm2022/flusys-ng-iam-permission-page.component-BlNt83uR.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam-role-api.service-OwPgmSFc.mjs +33 -0
- package/fesm2022/flusys-ng-iam-role-api.service-OwPgmSFc.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam-role-form-page.component-DnkWkbTF.mjs +427 -0
- package/fesm2022/flusys-ng-iam-role-form-page.component-DnkWkbTF.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam-role-list-page.component-BCO_gQ8k.mjs +685 -0
- package/fesm2022/flusys-ng-iam-role-list-page.component-BCO_gQ8k.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam-tree-utils-B1pBG4At.mjs +110 -0
- package/fesm2022/flusys-ng-iam-tree-utils-B1pBG4At.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam-user-action-selector.component-CAXEmJWx.mjs +4592 -0
- package/fesm2022/flusys-ng-iam-user-action-selector.component-CAXEmJWx.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam.mjs +2051 -2
- package/fesm2022/flusys-ng-iam.mjs.map +1 -1
- package/package.json +5 -5
- package/types/flusys-ng-iam.d.ts +621 -604
- package/fesm2022/flusys-ng-iam-action-form-page.component-Dn0TD1Zu.mjs +0 -509
- package/fesm2022/flusys-ng-iam-action-form-page.component-Dn0TD1Zu.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-action-list-page.component-Cf4Dhh5S.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-flusys-ng-iam-Y7U2lGZk.mjs +0 -5584
- package/fesm2022/flusys-ng-iam-flusys-ng-iam-Y7U2lGZk.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-iam-container.component-XBoIeQ0t.mjs +0 -105
- package/fesm2022/flusys-ng-iam-iam-container.component-XBoIeQ0t.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-permission-page.component-CCAQuZSJ.mjs +0 -204
- package/fesm2022/flusys-ng-iam-permission-page.component-CCAQuZSJ.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-role-form-page.component-EFjxhBRY.mjs +0 -352
- package/fesm2022/flusys-ng-iam-role-form-page.component-EFjxhBRY.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-role-list-page.component-DBfhjdkM.mjs +0 -486
- package/fesm2022/flusys-ng-iam-role-list-page.component-DBfhjdkM.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-iam.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"flusys-ng-iam.mjs","names":[],"sources":["../../../projects/ng-iam/interfaces/action.interface.ts","../../../projects/ng-iam/constants/messages.ts","../../../projects/ng-iam/services/my-permissions-api.service.ts","../../../projects/ng-iam/services/permission-state.service.ts","../../../projects/ng-iam/services/permission-scope-resolver.service.ts","../../../projects/ng-iam/components/logic-builder.component.ts","../../../projects/ng-iam/components/role-permitted-users-dialog.component.ts","../../../projects/ng-iam/components/action-permitted-users-dialog.component.ts","../../../projects/ng-iam/adapters/action-provider.adapter.ts","../../../projects/ng-iam/adapters/profile-permission-provider.adapter.ts","../../../projects/ng-iam/providers/iam-providers.ts","../../../projects/ng-iam/routes/iam.routes.ts"],"sourcesContent":["import { IBaseEntity, ILogicNode } from '@flusys/ng-shared';\n\n/** Must match backend ActionType enum */\nexport enum ActionType {\n BACKEND = 'backend',\n FRONTEND = 'frontend',\n BOTH = 'both',\n}\n\nexport interface IAction extends IBaseEntity {\n readOnly: boolean;\n name: string;\n description: string | null;\n code: string | null;\n actionType: ActionType;\n permissionLogic: ILogicNode | null;\n parentId: string | null;\n serial: number | null;\n isActive: boolean;\n}\n\nexport interface IActionTreeDto extends IAction {\n children: IActionTreeDto[];\n}\n\nexport interface ICreateActionDto {\n name: string;\n description?: string;\n code?: string;\n actionType?: ActionType;\n permissionLogic?: ILogicNode;\n parentId?: string;\n serial?: number;\n isActive?: boolean;\n}\n\nexport interface IUpdateActionDto extends Partial<ICreateActionDto> {\n id: string;\n}\n","export const IAM_MESSAGES: Record<string, string> = {\n // Action CRUD (API keys)\n 'action.create.success': 'Action created successfully',\n 'action.create.many.success': '{{count}} actions created successfully',\n 'action.get.success': 'Action retrieved successfully',\n 'action.get.by.ids.success': 'Actions retrieved successfully by Ids',\n 'action.get.by.filter.success': 'Actions retrieved successfully by filter',\n 'action.get.all.success': 'Actions retrieved successfully',\n 'action.update.success': 'Action updated successfully',\n 'action.update.many.success': '{{count}} actions updated successfully',\n 'action.delete.success': 'Action deleted successfully',\n 'action.restore.success': 'Action restored successfully',\n 'action.readonly.update.forbidden': 'Cannot modify readonly action(s): {{names}}',\n 'action.readonly.delete.forbidden': 'Cannot delete readonly action(s): {{names}}',\n\n // Role CRUD (API keys)\n 'role.create.success': 'Role created successfully',\n 'role.create.many.success': '{{count}} roles created successfully',\n 'role.get.success': 'Role retrieved successfully',\n 'role.get.by.ids.success': 'Roles retrieved successfully by Ids',\n 'role.get.by.filter.success': 'Roles retrieved successfully by filter',\n 'role.get.all.success': 'Roles retrieved successfully',\n 'role.update.success': 'Role updated successfully',\n 'role.update.many.success': '{{count}} roles updated successfully',\n 'role.delete.success': 'Role deleted successfully',\n 'role.restore.success': 'Role restored successfully',\n 'role.readonly.update.forbidden': 'Cannot modify readonly role(s): {{names}}',\n 'role.readonly.delete.forbidden': 'Cannot delete readonly role(s): {{names}}',\n\n // PERMISSION_OPERATION_MESSAGES (API keys)\n 'permission.process.success':\n 'Successfully processed {{total}} items: {{added}} added, {{removed}} removed',\n 'permission.user.required': 'User is required for {{method}}',\n 'permission.already.exists': 'Permission already exists',\n\n // ROLE_PERMISSION_MESSAGES (API keys)\n 'role.permission.actions.success': 'Role actions retrieved successfully',\n 'role.permission.user.roles.success': 'User roles retrieved successfully',\n\n // USER_ACTION_PERMISSION_MESSAGES (API keys)\n 'user.action.permission.get.success':\n 'User action permissions retrieved successfully',\n\n // COMPANY_ACTION_PERMISSION_MESSAGES (API keys)\n 'company.action.permission.get.success':\n 'Company action permissions retrieved successfully',\n\n // MY_PERMISSION_MESSAGES (API keys)\n 'my.permission.get.success': 'Permissions loaded successfully',\n\n // IAM_MODE_MESSAGES (API keys)\n 'iam.direct.mode.unavailable':\n 'Direct permission assignment not available in RBAC-only mode',\n 'iam.rbac.mode.unavailable':\n 'Role-based permission assignment not available in direct-only mode',\n 'iam.role.assignment.unavailable':\n 'Role assignment not available in direct-only mode',\n\n // pages/iam-container/iam-container.component.ts\n 'iam.title': 'Identity & Access Management',\n 'iam.subtitle': 'Manage roles, permissions, and access control',\n 'iam.action.title': 'Actions',\n 'iam.role.title': 'Roles',\n 'iam.permission.title': 'Permissions',\n\n // pages/action/action-list-page.component.ts\n 'iam.action.new': 'New Action',\n 'iam.action.name': 'Action Name',\n 'iam.action.code': 'Action Code',\n 'iam.action.type': 'Type',\n 'iam.action.no.actions': 'No actions found',\n 'iam.action.type.backend': 'Backend',\n 'iam.action.type.frontend': 'Frontend',\n 'iam.action.type.both': 'Both',\n\n // components/role-permitted-users-dialog.component.ts, components/action-permitted-users-dialog.component.ts\n 'iam.permission.view.users': 'View Users',\n 'iam.permission.no.users': 'No users found',\n 'iam.permission.remove': 'Remove Access',\n 'iam.permission.remove.confirm': 'Remove access for {{name}}?',\n 'iam.action.delete.title': 'Delete Action',\n 'iam.company.name': 'Company',\n 'iam.branch.name': 'Branch',\n 'iam.branch.all': 'All branches',\n\n // pages/action/action-form-page.component.ts\n 'iam.action.edit': 'Edit Action',\n 'iam.action.name.placeholder': 'Enter action name',\n 'iam.action.code.placeholder': 'Enter action code',\n 'iam.action.parent': 'Parent Action',\n 'iam.action.select.parent': 'Select Parent Action',\n 'iam.action.type.backend.label': 'Backend Only',\n 'iam.action.type.frontend.label': 'Frontend Only',\n 'iam.action.type.both.label': 'Backend & Frontend',\n 'iam.action.readonly.edit.forbidden': 'This is a system action and cannot be edited',\n\n // pages/role/role-list-page.component.ts\n 'iam.company.title': 'Companies',\n 'iam.role.new': 'New Role',\n 'iam.role.name': 'Role Name',\n 'iam.role.no.roles': 'No roles found',\n 'iam.role.delete.title': 'Delete Role',\n\n // pages/role/role-form-page.component.ts\n 'iam.role.edit': 'Edit Role',\n 'iam.role.name.placeholder': 'Enter role name',\n 'iam.role.readonly.edit.forbidden': 'This is a system role and cannot be edited',\n\n // pages/permission/permission-page.component.ts\n 'iam.permission.subtitle': 'Assign and manage access across roles, users, and companies',\n 'iam.permission.role.actions': 'Role Actions',\n 'iam.permission.user.roles': 'User Roles',\n 'iam.permission.user.actions': 'User Actions',\n 'iam.permission.company.actions': 'Company Actions',\n 'iam.permission.empty.role.actions.title': 'Select a role to get started',\n 'iam.permission.empty.role.actions.description':\n 'Choose a role from the dropdown above to view and manage its assigned actions.',\n 'iam.permission.empty.user.roles.title': 'Select a user to get started',\n 'iam.permission.empty.user.roles.description':\n 'Choose a user above to view and manage their assigned roles.',\n 'iam.permission.empty.user.actions.title': 'Select a user to get started',\n 'iam.permission.empty.user.actions.description':\n 'Choose a user above to view and manage their direct action permissions.',\n 'iam.permission.empty.company.actions.title': 'Select a company to get started',\n 'iam.permission.empty.company.actions.description':\n 'Choose a company from the dropdown above to view and manage its action whitelist.',\n 'iam.permission.unsaved.changes.title': 'Unsaved Changes',\n 'iam.permission.unsaved.changes.message':\n 'You have unsaved permission changes. Switching now will discard them.',\n 'iam.permission.unsaved.changes.discard': 'Discard Changes',\n\n // components/logic-builder.component.ts\n 'iam.logic.title': 'Permission Logic',\n 'iam.logic.add.logic': 'Add Logic',\n 'iam.logic.clear.logic': 'Clear Logic',\n 'iam.logic.description':\n 'Define permission requirements using AND/OR logic with actions',\n 'iam.logic.click.to.toggle': 'Click to toggle',\n 'iam.logic.conditions': '{{count}} conditions',\n 'iam.logic.select.action': 'Select Action...',\n 'iam.logic.actions.available': '{{count}} available',\n 'iam.logic.add.condition': 'Add Condition:',\n 'iam.logic.group': 'Group',\n 'iam.logic.action': 'Action',\n\n // components/role-action-selector.component.ts\n 'iam.permission.select.role': 'Select Role',\n 'iam.permission.select.role.placeholder': 'Search and select a role',\n 'iam.permission.action.permissions': 'Action Permissions',\n 'iam.permission.actions.available': '{{count}} actions available',\n 'iam.validation.warning.title': 'Validation Warning',\n 'iam.validation.unmet.prerequisites.plural':\n '{{count}} selected actions have unmet prerequisites. Fix before saving or use auto-fix on save.',\n 'iam.validation.unmet.prerequisites.singular':\n '{{count}} selected action has unmet prerequisites. Fix before saving or use auto-fix on save.',\n 'iam.permission.requirements': 'Requirements',\n 'iam.validation.unmet.prerequisites.tooltip':\n 'This action has unmet prerequisites and will fail validation on save',\n 'iam.permission.has.prerequisites': 'Has prerequisites',\n 'iam.permission.no.actions.available': 'No actions available',\n 'iam.permission.no.actions.for.role': 'No actions available for this role',\n 'iam.tooltip.remove.action': 'Click to remove',\n 'iam.tooltip.add.action': 'Click to add (auto-selects required)',\n 'iam.tooltip.assigned.to.role': 'Assigned to role',\n 'iam.tooltip.click.to.remove.role': 'Click to remove',\n 'iam.tooltip.click.to.assign.role': 'Click to assign to role',\n\n // components/user-action-selector.component.ts\n 'iam.permission.select.user': 'Select User',\n 'iam.permission.select.user.placeholder': 'Search and select a user',\n 'iam.permission.select.branch': 'Select Branch',\n 'iam.permission.select.branch.placeholder': 'Search and select a branch',\n 'iam.branch.permitted.count.plural':\n '{{count}} permitted branches in current company',\n 'iam.branch.permitted.count': '{{count}} permitted branch in current company',\n 'iam.permission.direct.action.permissions': 'Direct Action Permissions',\n 'iam.permission.no.actions.for.user': 'No actions available for this user',\n 'iam.tooltip.assigned.to.user': 'Assigned to user',\n 'iam.tooltip.click.to.remove.user': 'Click to remove direct permission',\n 'iam.tooltip.click.to.assign.user': 'Click to assign direct permission',\n 'iam.permission.company.required': 'Please select a company first',\n\n // components/company-action-selector.component.ts\n 'iam.permission.select.company': 'Select Company',\n 'iam.permission.select.company.placeholder': 'Search and select a company',\n 'iam.permission.action.whitelist': 'Action Whitelist',\n 'iam.permission.no.actions.for.company':\n 'No actions available for this company',\n 'iam.tooltip.selected': 'Selected',\n 'iam.tooltip.click.to.remove': 'Click to remove from company whitelist',\n 'iam.tooltip.click.to.add': 'Click to add to company whitelist',\n 'iam.permission.requires': 'requires',\n 'iam.permission.prerequisite.validation.failed':\n 'Prerequisite Validation Failed',\n 'iam.permission.prerequisite.error.message':\n 'The following actions have unmet prerequisites:',\n 'iam.permission.auto.select.required': 'Auto-select Required',\n 'iam.permission.actions.selected': 'Actions Selected',\n 'iam.permission.auto.selected.prerequisites':\n 'Required prerequisites have been auto-selected. Click Save to apply changes.',\n 'iam.permission.changes.reverted': 'Changes Reverted',\n 'iam.permission.selection.reverted':\n 'Selection has been reverted to the initial state.',\n\n // components/user-role-selector.component.ts\n 'iam.permission.role.assignments': 'Role Assignments',\n 'iam.permission.roles.available': '{{count}} roles available',\n 'iam.pagination.roles.template':\n 'Showing {first} to {last} of {totalRecords} roles',\n 'iam.permission.no.roles.available': 'No roles available',\n 'iam.permission.no.roles.for.user': 'No roles available for this user',\n 'iam.tooltip.click.to.remove.role.from.user': 'Click to remove role',\n 'iam.tooltip.click.to.assign.role.to.user': 'Click to assign role to user',\n\n // services/action-permission-logic.service.ts\n 'iam.logic.unknown.action': 'Unknown Action',\n 'iam.logic.validation.failed': 'Validation Failed',\n 'iam.logic.validation.failed.message':\n 'The following actions have unmet prerequisites:',\n 'iam.logic.validation.failed.prompt': 'Would you like to:',\n 'iam.logic.auto.fix': 'Auto-fix (Remove Invalid)',\n 'iam.logic.invalid.actions.removed': 'Invalid Actions Removed',\n 'iam.logic.removed.actions.detail':\n 'Removed {{count}} action(s) with unmet prerequisites. You can now save.',\n 'iam.logic.save.cancelled': 'Save Cancelled',\n 'iam.logic.fix.prerequisites.manually':\n 'Please fix the prerequisites manually before saving',\n 'iam.logic.prerequisites.satisfied': '[OK] Prerequisites Satisfied',\n 'iam.logic.all.required.selected':\n 'All required actions are already selected.\\nYou can safely add this action.',\n 'iam.logic.prerequisites.required':\n 'Prerequisites Required ({{count}} missing)',\n 'iam.logic.click.to.auto.select': 'Click to auto-select required actions',\n 'iam.logic.select.action.label': 'Select Action',\n 'iam.logic.auto.select.actions': 'Auto-select Actions',\n 'iam.logic.action.selected.detail':\n 'Action selected successfully (prerequisites already satisfied)',\n 'iam.logic.auto.selected.detail':\n 'Automatically selected {{count}} action(s) including prerequisites',\n 'iam.logic.minimum.required': ' (minimum required)',\n 'iam.logic.auto.select.prompt':\n 'Auto-select will choose {{count}} action(s){{suffix}}.',\n 'iam.logic.missing.prerequisites': 'Missing Prerequisites',\n 'iam.logic.requires.conditions':\n 'requires the following conditions to be satisfied:',\n 'iam.logic.would.you.continue': 'Would you like to continue?',\n 'iam.logic.actions.selected.summary': 'Actions Selected',\n 'iam.logic.selection.cancelled': 'Selection Cancelled',\n 'iam.logic.action.not.added': 'Action not added to whitelist',\n 'iam.logic.required.by.actions': 'is required by the following action(s):',\n 'iam.logic.alternatives.available': 'Alternative options available:',\n 'iam.logic.switch.to.alternatives':\n 'Would you like to automatically switch to alternatives?',\n 'iam.logic.remove.dependents':\n 'Removing this will also remove the dependent action(s).',\n 'iam.logic.dependency.warning': 'Dependency Warning',\n 'iam.logic.use.alternatives': 'Use Alternatives',\n 'iam.logic.remove.all': 'Remove All',\n 'iam.logic.alternatives.applied': 'Alternatives Applied',\n 'iam.logic.switched.to.alternatives':\n 'Automatically switched to alternative action(s)',\n 'iam.logic.actions.removed': 'Actions Removed',\n 'iam.logic.removed.with.dependents':\n 'Removed {{name}} and {{count}} dependent action(s)',\n 'iam.logic.cancelled': 'Cancelled',\n 'iam.logic.no.changes.made': 'No changes made',\n 'iam.logic.satisfied': '(satisfied)',\n 'iam.logic.missing': '(missing)',\n 'iam.logic.invalid.node': 'Invalid logic node',\n 'iam.logic.invalid': '(invalid)',\n};\n","import { HttpClient } from '@angular/common/http';\nimport { inject, Service } from '@angular/core';\nimport { APP_CONFIG, getServiceUrl, IAppConfig } from '@flusys/ng-core';\nimport { ISingleResponse } from '@flusys/ng-shared';\nimport { Observable } from 'rxjs';\nimport { IGetMyPermissionsDto, IMyPermissionsResponseDto } from '../interfaces/permission.interface';\n\n/**\n * My Permissions API Service\n * Get current user's complete permissions\n * Endpoint: POST /iam/permissions/my-permissions\n * Always enabled\n */\n@Service()\nexport class MyPermissionsApiService {\n private readonly http = inject(HttpClient);\n private readonly appConfig = inject<IAppConfig>(APP_CONFIG);\n private readonly baseUrl = `${getServiceUrl(this.appConfig, 'iam')}/permissions`;\n\n /**\n * Get current user's complete permissions\n * POST /iam/permissions/my-permissions\n * Returns menus, frontend actions, and cached endpoint count\n * @param dto Optional filter by parent codes (only affects frontend actions)\n */\n getMyPermissions(dto: IGetMyPermissionsDto = {}): Observable<ISingleResponse<IMyPermissionsResponseDto>> {\n return this.http.post<ISingleResponse<IMyPermissionsResponseDto>>(\n `${this.baseUrl}/my-permissions`,\n dto,\n );\n }\n}\n","import { inject, signal, Service } from '@angular/core';\nimport { PermissionValidatorService } from '@flusys/ng-shared';\nimport { Observable, of } from 'rxjs';\nimport { catchError, map, tap } from 'rxjs/operators';\nimport { IGetMyPermissionsDto, IMyPermissionsResponseDto } from '../interfaces/permission.interface';\nimport { MyPermissionsApiService } from './my-permissions-api.service';\n\n@Service()\nexport class PermissionStateService {\n private readonly permissionApi = inject(MyPermissionsApiService);\n private readonly permissionValidator = inject(PermissionValidatorService);\n\n private readonly _permissions = signal<IMyPermissionsResponseDto | null>(null);\n readonly permissions = this._permissions.asReadonly();\n\n private readonly _isLoading = signal(false);\n readonly isLoading = this._isLoading.asReadonly();\n\n loadPermissions(dto?: IGetMyPermissionsDto): Observable<void> {\n this._isLoading.set(true);\n return this.permissionApi.getMyPermissions(dto).pipe(\n tap((response) => {\n this._permissions.set(response.data ?? null);\n this._isLoading.set(false);\n const actionCodes = response.data?.frontendActions.map((a) => a.code) ?? [];\n this.permissionValidator.setPermissions(actionCodes);\n }),\n catchError(() => {\n this._permissions.set(null);\n this._isLoading.set(false);\n this.permissionValidator.clearPermissions();\n return of(void 0);\n }),\n map(() => void 0),\n );\n }\n\n isLoaded(): boolean {\n return this._permissions() !== null && this.permissionValidator.isLoaded();\n }\n}\n","import { inject, Service } from '@angular/core';\nimport { COMPANY_API_PROVIDER, IBranchBasicInfo, ICompanyBasicInfo } from '@flusys/ng-shared';\nimport { firstValueFrom } from 'rxjs';\n\n/**\n * Shared resolver for the company/branch display info behind an IAM permission\n * grant's scope (`companyId`/`branchId`). Used by the read-only permitted-users\n * dialogs (action and role) to turn scope IDs into display names.\n *\n * Since IAM stays independent of the auth package, company/branch info is\n * resolved via the `COMPANY_API_PROVIDER` injection token rather than a direct\n * join. Both `getCompaniesByIds`/`getBranchesByIds` are optional on\n * `ICompanyApiProvider`, and provider errors are swallowed — callers always get\n * a `Map` (empty when ids are empty, the provider doesn't implement the\n * method, or the request fails) and fall back to displaying the raw ID.\n */\n@Service()\nexport class PermissionScopeResolverService {\n private readonly companyProvider = inject(COMPANY_API_PROVIDER);\n\n async resolveCompanyInfo(companyIds: string[]): Promise<Map<string, ICompanyBasicInfo>> {\n if (companyIds.length === 0 || !this.companyProvider.getCompaniesByIds) {\n return new Map();\n }\n\n try {\n const response = await firstValueFrom(this.companyProvider.getCompaniesByIds(companyIds));\n return new Map((response.data ?? []).map((c) => [c.id, c]));\n } catch {\n return new Map();\n }\n }\n\n async resolveBranchInfo(branchIds: string[]): Promise<Map<string, IBranchBasicInfo>> {\n if (branchIds.length === 0 || !this.companyProvider.getBranchesByIds) {\n return new Map();\n }\n\n try {\n const response = await firstValueFrom(this.companyProvider.getBranchesByIds(branchIds));\n return new Map((response.data ?? []).map((b) => [b.id, b]));\n } catch {\n return new Map();\n }\n }\n}\n","import { Component, effect, input, output, signal } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { ILogicNode, TranslatePipe } from '@flusys/ng-shared';\nimport { FButtonDirective, SelectComponent, TooltipDirective, UiIconComponent } from '@flusys/ng-ui';\n\ninterface IBuilderNode {\n id: string;\n type: 'group' | 'action';\n operator?: 'AND' | 'OR';\n actionId?: string;\n children?: IBuilderNode[];\n}\n\nfunction toLogicNode(node: IBuilderNode): ILogicNode {\n if (node.type === 'action') {\n return { type: 'action', actionId: node.actionId! };\n }\n return {\n type: 'group',\n operator: node.operator!,\n children: node.children?.map(toLogicNode) ?? [],\n };\n}\n\nfunction toBuilderNode(node: ILogicNode): IBuilderNode {\n if (node.type === 'action') {\n return createActionNode(node.actionId);\n }\n return {\n ...createGroupNode(node.operator),\n children: node.children?.map(toBuilderNode) ?? [],\n };\n}\n\nfunction createGroupNode(operator: 'AND' | 'OR' = 'AND'): IBuilderNode {\n return { id: crypto.randomUUID(), type: 'group', operator, children: [] };\n}\n\nfunction createActionNode(actionId = ''): IBuilderNode {\n return { id: crypto.randomUUID(), type: 'action', actionId };\n}\n\n@Component({\n selector: 'lib-logic-builder',\n imports: [\n FormsModule,\n NgTemplateOutlet,\n FButtonDirective,\n SelectComponent,\n TooltipDirective,\n UiIconComponent,\n TranslatePipe,\n ],\n template: `\n <div class=\"logic-builder\">\n <div class=\"flex justify-between items-center mb-3\">\n <h4 class=\"text-sm font-semibold m-0\">\n {{ 'iam.logic.title' | translate }}\n </h4>\n @if (!builderLogic()) {\n <button\n fButton\n size=\"small\"\n (click)=\"initializeLogic()\"\n >\n <ui-icon pButtonIcon name=\"plus\"></ui-icon>\n <span pButtonLabel>{{ 'iam.logic.add.logic' | translate }}</span>\n </button>\n } @else {\n <button\n fButton\n size=\"small\"\n severity=\"danger\"\n [outlined]=\"true\"\n (click)=\"clearLogic()\"\n >\n <ui-icon pButtonIcon name=\"trash\"></ui-icon>\n <span pButtonLabel>{{ 'iam.logic.clear.logic' | translate }}</span>\n </button>\n }\n </div>\n\n @if (builderLogic()) {\n <div class=\"border border-surface rounded p-3 bg-surface-50 dark:bg-surface-800\">\n <div class=\"mb-3 text-sm text-muted-color\">\n {{ 'iam.logic.description' | translate }}\n </div>\n\n <!-- Root Node -->\n <div class=\"text-sm bg-surface-0 dark:bg-surface-900 rounded border border-surface\">\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: builderLogic()!, depth: 0 }\"\n ></ng-container>\n </div>\n </div>\n }\n </div>\n\n <!-- Recursive Node Template -->\n <ng-template #nodeTemplate let-node let-depth=\"depth\">\n <div\n class=\"p-3 border-b border-surface\"\n [class.bg-surface-0]=\"depth % 2 === 0\"\n [class.dark:bg-surface-900]=\"depth % 2 === 0\"\n [class.bg-surface-50]=\"depth % 2 !== 0\"\n [class.dark:bg-surface-800]=\"depth % 2 !== 0\"\n >\n <div class=\"flex items-center gap-3 mb-2\">\n <span\n class=\"node-type\"\n [class.group]=\"node.type === 'group'\"\n [class.action]=\"node.type === 'action'\"\n >{{ node.type.toUpperCase() }}</span\n >\n\n <div class=\"flex-1 flex items-center gap-2\">\n @if (node.type === 'group') {\n <!-- Group: show operator toggle -->\n <span\n class=\"operator-badge\"\n [class.and]=\"node.operator === 'AND'\"\n [class.or]=\"node.operator !== 'AND'\"\n (click)=\"toggleOperator(node.id)\"\n [fTooltip]=\"'iam.logic.click.to.toggle' | translate\"\n >\n {{ node.operator }}\n </span>\n <span class=\"text-muted-color text-xs\"\n >({{\n 'iam.logic.conditions'\n | translate: { count: node.children?.length || 0 }\n }})</span\n >\n }\n\n @if (node.type === 'action') {\n <f-select\n class=\"flex-1\"\n [options]=\"actions()\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [ngModel]=\"node.actionId\"\n (ngModelChange)=\"updateActionId(node.id, $event)\"\n [placeholder]=\"'iam.logic.select.action' | translate\"\n [filter]=\"true\"\n />\n }\n </div>\n\n <div class=\"flex gap-1\">\n <button\n fButton\n [text]=\"true\"\n severity=\"danger\"\n size=\"small\"\n (click)=\"removeNode(node.id)\"\n [fTooltip]=\"'shared.remove' | translate\"\n >\n <ui-icon pButtonIcon name=\"trash\"></ui-icon>\n </button>\n </div>\n </div>\n\n <!-- Children for group nodes -->\n @if (\n node.type === 'group' && node.children && node.children.length > 0\n ) {\n <div class=\"ml-5 mt-2 pl-3 border-l-2 border-surface\">\n @for (child of node.children; track child.id) {\n <ng-container\n [ngTemplateOutlet]=\"nodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: child, depth: depth + 1 }\"\n ></ng-container>\n }\n </div>\n }\n\n <!-- Add child buttons for group nodes -->\n @if (node.type === 'group') {\n <div\n class=\"mt-3 p-3 bg-surface-50 dark:bg-surface-800 rounded border border-dashed border-surface\"\n >\n <div class=\"text-xs font-semibold text-muted-color mb-2\">\n {{ 'iam.logic.add.condition' | translate }}\n </div>\n <div class=\"flex gap-2 flex-wrap\">\n <button\n fButton\n size=\"small\"\n [outlined]=\"true\"\n (click)=\"addChildNode(node.id, 'group')\"\n >\n <ui-icon pButtonIcon name=\"sitemap\"></ui-icon>\n <span pButtonLabel>{{ 'iam.logic.group' | translate }}</span>\n </button>\n <button\n fButton\n size=\"small\"\n severity=\"success\"\n [outlined]=\"true\"\n (click)=\"addChildNode(node.id, 'action')\"\n >\n <ui-icon pButtonIcon name=\"bolt\"></ui-icon>\n <span pButtonLabel>{{ 'iam.logic.action' | translate }}</span>\n </button>\n </div>\n </div>\n }\n </div>\n </ng-template>\n `,\n styles: [\n `\n :host {\n display: block;\n }\n\n /* Node type badges */\n .node-type {\n display: inline-flex;\n align-items: center;\n padding: 0.25rem 0.5rem;\n border-radius: 0.25rem;\n font-weight: 600;\n font-size: 0.75rem;\n text-transform: uppercase;\n }\n\n .node-type.group {\n background-color: var(--f-blue-100, #dbeafe);\n color: var(--f-blue-700, #1e40af);\n }\n\n .node-type.action {\n background-color: var(--f-green-100, #d1fae5);\n color: var(--f-green-700, #065f46);\n }\n\n /* Dark mode node type badges */\n :host-context(.app-dark) .node-type.group {\n background-color: rgba(59, 130, 246, 0.2);\n color: var(--f-blue-400, #60a5fa);\n }\n\n :host-context(.app-dark) .node-type.action {\n background-color: rgba(34, 197, 94, 0.2);\n color: var(--f-green-400, #4ade80);\n }\n\n /* Operator toggle badge */\n .operator-badge {\n display: inline-flex;\n align-items: center;\n padding: 0.125rem 0.5rem;\n border-radius: 9999px;\n font-weight: 600;\n font-size: 0.75rem;\n cursor: pointer;\n transition: opacity 0.2s;\n }\n\n .operator-badge.and {\n background-color: var(--f-yellow-100, #fef3c7);\n color: var(--f-yellow-700, #92400e);\n }\n\n .operator-badge.or {\n background-color: var(--f-indigo-100, #e0e7ff);\n color: var(--f-indigo-700, #3730a3);\n }\n\n /* Dark mode operator badges */\n :host-context(.app-dark) .operator-badge.and {\n background-color: rgba(234, 179, 8, 0.2);\n color: var(--f-yellow-400, #facc15);\n }\n\n :host-context(.app-dark) .operator-badge.or {\n background-color: rgba(99, 102, 241, 0.2);\n color: var(--f-indigo-400, #818cf8);\n }\n\n .operator-badge:hover {\n opacity: 0.8;\n }\n\n /* Action select styling */\n .action-select {\n background-color: var(--f-surface-0, #ffffff);\n color: var(--f-text-color, #1f2937);\n }\n\n :host-context(.app-dark) .action-select {\n background-color: var(--f-surface-900, #1f2937);\n color: var(--f-text-color, #f9fafb);\n }\n\n /* Focus state for select */\n .action-select:focus {\n outline: none;\n border-color: var(--f-primary-color, #3b82f6);\n }\n `,\n ],\n})\nexport class LogicBuilderComponent {\n readonly logic = input<ILogicNode | null>(null);\n readonly actions = input<Array<{ id: string; name: string }>>([]);\n readonly logicChange = output<ILogicNode | null>();\n\n private readonly _builderTree = signal<IBuilderNode | null>(null);\n readonly builderLogic = this._builderTree.asReadonly();\n\n constructor() {\n effect(() => {\n const logic = this.logic();\n if (!logic) {\n this._builderTree.set(null);\n } else if (!this._builderTree()) {\n this._builderTree.set(toBuilderNode(logic));\n }\n });\n }\n\n initializeLogic(): void {\n this.updateTreeAndEmit(createGroupNode());\n }\n\n clearLogic(): void {\n this._builderTree.set(null);\n this.logicChange.emit(null);\n }\n\n toggleOperator(nodeId: string): void {\n this.updateNode(nodeId, (node) => ({\n ...node,\n operator: node.operator === 'AND' ? 'OR' : 'AND',\n }));\n }\n\n addChildNode(parentId: string, type: 'group' | 'action'): void {\n const newNode = type === 'group' ? createGroupNode() : createActionNode();\n this.updateNode(parentId, (node) => ({\n ...node,\n children: [...(node.children || []), newNode],\n }));\n }\n\n removeNode(nodeId: string): void {\n const tree = this._builderTree();\n if (!tree) return;\n\n if (tree.id === nodeId) {\n this.clearLogic();\n return;\n }\n\n this.updateTreeAndEmit(this.removeNodeFromTree(tree, nodeId));\n }\n\n updateActionId(nodeId: string, actionId: string): void {\n this.updateNode(nodeId, (node) => ({ ...node, actionId }));\n }\n\n private updateNode(\n nodeId: string,\n updater: (node: IBuilderNode) => IBuilderNode,\n ): void {\n const tree = this._builderTree();\n if (!tree) return;\n this.updateTreeAndEmit(this.updateNodeInTree(tree, nodeId, updater));\n }\n\n private updateTreeAndEmit(tree: IBuilderNode): void {\n this._builderTree.set(tree);\n this.logicChange.emit(toLogicNode(tree));\n }\n\n private updateNodeInTree(\n node: IBuilderNode,\n targetId: string,\n updater: (node: IBuilderNode) => IBuilderNode,\n ): IBuilderNode {\n if (node.id === targetId) return updater(node);\n if (!node.children) return node;\n return {\n ...node,\n children: node.children.map((child) =>\n this.updateNodeInTree(child, targetId, updater),\n ),\n };\n }\n\n private removeNodeFromTree(\n node: IBuilderNode,\n targetId: string,\n ): IBuilderNode {\n if (!node.children) return node;\n return {\n ...node,\n children: node.children\n .filter((child) => child.id !== targetId)\n .map((child) => this.removeNodeFromTree(child, targetId)),\n };\n }\n}\n","import { Component, effect, inject, input, output, signal } from '@angular/core';\nimport {\n ConfirmationService,\n DialogComponent,\n FButtonDirective,\n MessageService,\n ProgressSpinnerComponent,\n TooltipDirective,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport {\n HasPermissionDirective,\n IUserBasicInfo,\n TranslatePipe,\n TranslateService,\n USER_PROVIDER,\n USER_ROLE_PERMISSIONS,\n} from '@flusys/ng-shared';\nimport { firstValueFrom } from 'rxjs';\nimport { IRole } from '../interfaces/role.interface';\nimport { PermissionApiService } from '../services/permission-api.service';\nimport { PermissionScopeResolverService } from '../services/permission-scope-resolver.service';\n\ninterface RolePermittedUserRow {\n id: string;\n userId: string;\n userName: string;\n userEmail: string;\n companyId: string | null;\n companyName: string | null;\n branchId: string | null;\n branchName: string | null;\n}\n\n/**\n * Read-only viewer for users assigned to a role, with a remove-only action\n * per user. Assigning new users stays on the user-centric\n * `UserRoleSelectorComponent` flow — this dialog intentionally has no \"add\"\n * affordance. Since IAM stays independent of the auth package, user display\n * info is resolved via the `USER_PROVIDER` injection token, and\n * company/branch display info via the shared `PermissionScopeResolverService`\n * (itself backed by `COMPANY_API_PROVIDER`) rather than a direct join.\n *\n * `Role` assignments are global (never scoped to a single company), so the\n * same user can hold several grants for the same role — one per\n * company/branch scope (company+branch null = global, branch null = whole\n * company, both set = a single branch). The company/branch lines are shown\n * only when at least one returned grant carries a `companyId` (i.e. the\n * multi-company feature is enabled) — otherwise they're omitted to avoid a\n * redundant \"-\" column. Removal is scoped to the exact row's\n * `companyId`/`branchId`, not just the user+role pair, since a user can\n * have multiple grants for the same role at different scopes.\n */\n@Component({\n selector: 'flusys-role-permitted-users-dialog',\n imports: [\n DialogComponent,\n FButtonDirective,\n ProgressSpinnerComponent,\n TooltipDirective,\n UiIconComponent,\n HasPermissionDirective,\n TranslatePipe,\n ],\n template: `\n <f-dialog\n [visible]=\"visible()\"\n [modal]=\"true\"\n [closable]=\"true\"\n [breakpoints]=\"{ '960px': '90vw', '640px': '95vw' }\"\n [style]=\"{ width: '50vw', maxWidth: '600px' }\"\n [header]=\"'iam.permission.view.users' | translate\"\n (onHide)=\"onClose()\"\n >\n <div class=\"mb-4\">\n <p class=\"text-sm text-muted-color\">\n {{ 'iam.role.name' | translate }}:\n <strong>{{ role()?.name }}</strong>\n </p>\n </div>\n\n @if (isLoading()) {\n <div class=\"flex justify-center items-center py-8\">\n <f-progressspinner />\n </div>\n } @else {\n <div class=\"flex flex-col gap-3\">\n @for (user of users(); track user.id) {\n <div\n class=\"flex items-center justify-between p-3 border border-surface rounded\"\n >\n <div>\n <div class=\"font-semibold\">{{ user.userName }}</div>\n <div class=\"text-sm text-muted-color\">{{ user.userEmail }}</div>\n @if (showCompanyColumn() && user.companyName) {\n <div class=\"text-xs text-muted-color mt-1\">\n {{ 'iam.company.name' | translate }}: {{ user.companyName }}\n @if (user.branchName) {\n · {{ 'iam.branch.name' | translate }}: {{ user.branchName }}\n } @else {\n · {{ 'iam.branch.all' | translate }}\n }\n </div>\n }\n </div>\n <button\n fButton\n *hasPermission=\"USER_ROLE_PERMISSIONS.ASSIGN\"\n [text]=\"true\"\n severity=\"danger\"\n size=\"small\"\n [disabled]=\"isRemoving()\"\n [fTooltip]=\"'shared.remove' | translate\"\n (click)=\"onRemove(user)\"\n >\n <ui-icon pButtonIcon name=\"trash\"></ui-icon>\n </button>\n </div>\n } @empty {\n <div class=\"text-center py-4 text-muted-color\">\n {{ 'iam.permission.no.users' | translate }}\n </div>\n }\n </div>\n }\n\n <ng-template #footer>\n <button\n fButton\n severity=\"secondary\"\n [outlined]=\"true\"\n (click)=\"onClose()\"\n >\n <span pButtonLabel>{{ 'shared.close' | translate }}</span>\n </button>\n </ng-template>\n </f-dialog>\n `,\n})\nexport class RolePermittedUsersDialogComponent {\n readonly USER_ROLE_PERMISSIONS = USER_ROLE_PERMISSIONS;\n\n private readonly permissionApi = inject(PermissionApiService);\n private readonly userProvider = inject(USER_PROVIDER);\n private readonly scopeResolver = inject(PermissionScopeResolverService);\n private readonly confirmationService = inject(ConfirmationService);\n private readonly messageService = inject(MessageService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n private t(key: string, params?: Record<string, unknown>): string {\n return this.translateAdapter?.translate(key, params) ?? key;\n }\n\n readonly visible = input.required<boolean>();\n readonly role = input.required<IRole | null>();\n readonly closed = output<void>();\n\n readonly isLoading = signal(false);\n readonly isRemoving = signal(false);\n readonly users = signal<RolePermittedUserRow[]>([]);\n readonly showCompanyColumn = signal(false);\n\n constructor() {\n effect(() => {\n if (this.visible() && this.role()) {\n this.loadUsers();\n }\n });\n }\n\n private async loadUsers(): Promise<void> {\n const role = this.role();\n if (!role) return;\n\n this.isLoading.set(true);\n try {\n const response = await firstValueFrom(this.permissionApi.getRoleUsers(role.id));\n const rows = response.data ?? [];\n const userIds = [...new Set(rows.map((r) => r.userId))];\n const companyIds = [...new Set(rows.map((r) => r.companyId).filter((id): id is string => !!id))];\n const branchIds = [...new Set(rows.map((r) => r.branchId).filter((id): id is string => !!id))];\n const [userInfoMap, companyInfoMap, branchInfoMap] = await Promise.all([\n this.resolveUserInfo(userIds),\n this.scopeResolver.resolveCompanyInfo(companyIds),\n this.scopeResolver.resolveBranchInfo(branchIds),\n ]);\n\n this.showCompanyColumn.set(companyIds.length > 0);\n this.users.set(\n rows.map((r) => {\n const info = userInfoMap.get(r.userId);\n return {\n id: r.id,\n userId: r.userId,\n userName: info?.name ?? r.userId,\n userEmail: info?.email ?? '',\n companyId: r.companyId,\n companyName: r.companyId ? (companyInfoMap.get(r.companyId)?.name ?? r.companyId) : null,\n branchId: r.branchId,\n branchName: r.branchId ? (branchInfoMap.get(r.branchId)?.name ?? r.branchId) : null,\n };\n }),\n );\n } catch {\n // Error toast handled by global interceptor\n } finally {\n this.isLoading.set(false);\n }\n }\n\n private async resolveUserInfo(userIds: string[]): Promise<Map<string, IUserBasicInfo>> {\n if (userIds.length === 0 || !this.userProvider.getUsersByIds) {\n return new Map();\n }\n\n try {\n const response = await firstValueFrom(this.userProvider.getUsersByIds(userIds));\n return new Map((response.data ?? []).map((u) => [u.id, u]));\n } catch {\n return new Map();\n }\n }\n\n onRemove(user: RolePermittedUserRow): void {\n const role = this.role();\n if (!role) return;\n\n this.confirmationService.confirm({\n message: this.t('iam.permission.remove.confirm', { name: user.userName }),\n header: this.t('iam.permission.remove'),\n icon: 'exclamation-triangle',\n acceptButtonStyleClass: 'p-button-danger',\n accept: async () => {\n this.isRemoving.set(true);\n try {\n const response = await firstValueFrom(\n this.permissionApi.assignUserRoles({\n userId: user.userId,\n companyId: user.companyId ?? undefined,\n branchId: user.branchId ?? undefined,\n items: [{ id: role.id, action: 'remove' }],\n }),\n );\n\n if (response.success) {\n this.users.update((list) => list.filter((u) => u.id !== user.id));\n this.messageService.add({\n severity: 'success',\n summary: this.t('shared.success'),\n detail: response?.messageKey\n ? this.t(response.messageKey, response.messageVariables)\n : (response?.message ?? ''),\n });\n }\n } catch {\n // Error toast handled by global interceptor\n } finally {\n this.isRemoving.set(false);\n }\n },\n });\n }\n\n onClose(): void {\n this.closed.emit();\n }\n}\n","import { Component, effect, inject, input, output, signal } from '@angular/core';\nimport {\n ConfirmationService,\n DialogComponent,\n FButtonDirective,\n MessageService,\n ProgressSpinnerComponent,\n TooltipDirective,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport {\n HasPermissionDirective,\n IUserBasicInfo,\n TranslatePipe,\n TranslateService,\n USER_ACTION_PERMISSIONS,\n USER_PROVIDER,\n} from '@flusys/ng-shared';\nimport { firstValueFrom } from 'rxjs';\nimport { IAction } from '../interfaces/action.interface';\nimport { PermissionApiService } from '../services/permission-api.service';\nimport { PermissionScopeResolverService } from '../services/permission-scope-resolver.service';\n\ninterface ActionPermittedUserRow {\n id: string;\n userId: string;\n userName: string;\n userEmail: string;\n companyId: string | null;\n companyName: string | null;\n branchId: string | null;\n branchName: string | null;\n}\n\n/**\n * Read-only viewer for users directly assigned an action, with a remove-only\n * action per user. Assigning new users stays on the user-centric\n * `UserActionSelectorComponent` flow — this dialog intentionally has no\n * \"add\" affordance. Since IAM stays independent of the auth package, user\n * display info is resolved via the `USER_PROVIDER` injection token, and\n * company/branch display info via the shared `PermissionScopeResolverService`\n * (itself backed by `COMPANY_API_PROVIDER`) rather than a direct join.\n *\n * `Action` rows are global (never scoped to a single company), so the same\n * user can hold several grants for the same action — one per\n * company/branch scope (company+branch null = global, branch null = whole\n * company, both set = a single branch). The company/branch lines are shown\n * only when at least one returned grant carries a `companyId` (i.e. the\n * multi-company feature is enabled) — otherwise they're omitted to avoid a\n * redundant \"-\" column. Removal is scoped to the exact row's\n * `companyId`/`branchId`, not just the user+action pair, since a user can\n * have multiple grants for the same action at different scopes.\n */\n@Component({\n selector: 'flusys-action-permitted-users-dialog',\n imports: [\n DialogComponent,\n FButtonDirective,\n ProgressSpinnerComponent,\n TooltipDirective,\n UiIconComponent,\n HasPermissionDirective,\n TranslatePipe,\n ],\n template: `\n <f-dialog\n [visible]=\"visible()\"\n [modal]=\"true\"\n [closable]=\"true\"\n [breakpoints]=\"{ '960px': '90vw', '640px': '95vw' }\"\n [style]=\"{ width: '50vw', maxWidth: '600px' }\"\n [header]=\"'iam.permission.view.users' | translate\"\n (onHide)=\"onClose()\"\n >\n <div class=\"mb-4\">\n <p class=\"text-sm text-muted-color\">\n {{ 'iam.action.name' | translate }}:\n <strong>{{ action()?.name }}</strong>\n </p>\n </div>\n\n @if (isLoading()) {\n <div class=\"flex justify-center items-center py-8\">\n <f-progressspinner />\n </div>\n } @else {\n <div class=\"flex flex-col gap-3\">\n @for (user of users(); track user.id) {\n <div\n class=\"flex items-center justify-between p-3 border border-surface rounded\"\n >\n <div>\n <div class=\"font-semibold\">{{ user.userName }}</div>\n <div class=\"text-sm text-muted-color\">{{ user.userEmail }}</div>\n @if (showCompanyColumn() && user.companyName) {\n <div class=\"text-xs text-muted-color mt-1\">\n {{ 'iam.company.name' | translate }}: {{ user.companyName }}\n @if (user.branchName) {\n · {{ 'iam.branch.name' | translate }}: {{ user.branchName }}\n } @else {\n · {{ 'iam.branch.all' | translate }}\n }\n </div>\n }\n </div>\n <button\n fButton\n *hasPermission=\"USER_ACTION_PERMISSIONS.ASSIGN\"\n [text]=\"true\"\n severity=\"danger\"\n size=\"small\"\n [disabled]=\"isRemoving()\"\n [fTooltip]=\"'shared.remove' | translate\"\n (click)=\"onRemove(user)\"\n >\n <ui-icon pButtonIcon name=\"trash\"></ui-icon>\n </button>\n </div>\n } @empty {\n <div class=\"text-center py-4 text-muted-color\">\n {{ 'iam.permission.no.users' | translate }}\n </div>\n }\n </div>\n }\n\n <ng-template #footer>\n <button\n fButton\n severity=\"secondary\"\n [outlined]=\"true\"\n (click)=\"onClose()\"\n >\n <span pButtonLabel>{{ 'shared.close' | translate }}</span>\n </button>\n </ng-template>\n </f-dialog>\n `,\n})\nexport class ActionPermittedUsersDialogComponent {\n readonly USER_ACTION_PERMISSIONS = USER_ACTION_PERMISSIONS;\n\n private readonly permissionApi = inject(PermissionApiService);\n private readonly userProvider = inject(USER_PROVIDER);\n private readonly scopeResolver = inject(PermissionScopeResolverService);\n private readonly confirmationService = inject(ConfirmationService);\n private readonly messageService = inject(MessageService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n private t(key: string, params?: Record<string, unknown>): string {\n return this.translateAdapter?.translate(key, params) ?? key;\n }\n\n readonly visible = input.required<boolean>();\n readonly action = input.required<IAction | null>();\n readonly closed = output<void>();\n\n readonly isLoading = signal(false);\n readonly isRemoving = signal(false);\n readonly users = signal<ActionPermittedUserRow[]>([]);\n readonly showCompanyColumn = signal(false);\n\n constructor() {\n effect(() => {\n if (this.visible() && this.action()) {\n this.loadUsers();\n }\n });\n }\n\n private async loadUsers(): Promise<void> {\n const action = this.action();\n if (!action) return;\n\n this.isLoading.set(true);\n try {\n const response = await firstValueFrom(this.permissionApi.getActionUsers(action.id));\n const rows = response.data ?? [];\n const userIds = [...new Set(rows.map((r) => r.userId))];\n const companyIds = [...new Set(rows.map((r) => r.companyId).filter((id): id is string => !!id))];\n const branchIds = [...new Set(rows.map((r) => r.branchId).filter((id): id is string => !!id))];\n const [userInfoMap, companyInfoMap, branchInfoMap] = await Promise.all([\n this.resolveUserInfo(userIds),\n this.scopeResolver.resolveCompanyInfo(companyIds),\n this.scopeResolver.resolveBranchInfo(branchIds),\n ]);\n\n this.showCompanyColumn.set(companyIds.length > 0);\n this.users.set(\n rows.map((r) => {\n const info = userInfoMap.get(r.userId);\n return {\n id: r.id,\n userId: r.userId,\n userName: info?.name ?? r.userId,\n userEmail: info?.email ?? '',\n companyId: r.companyId,\n companyName: r.companyId ? (companyInfoMap.get(r.companyId)?.name ?? r.companyId) : null,\n branchId: r.branchId,\n branchName: r.branchId ? (branchInfoMap.get(r.branchId)?.name ?? r.branchId) : null,\n };\n }),\n );\n } catch {\n // Error toast handled by global interceptor\n } finally {\n this.isLoading.set(false);\n }\n }\n\n private async resolveUserInfo(userIds: string[]): Promise<Map<string, IUserBasicInfo>> {\n if (userIds.length === 0 || !this.userProvider.getUsersByIds) {\n return new Map();\n }\n\n try {\n const response = await firstValueFrom(this.userProvider.getUsersByIds(userIds));\n return new Map((response.data ?? []).map((u) => [u.id, u]));\n } catch {\n return new Map();\n }\n }\n\n onRemove(user: ActionPermittedUserRow): void {\n const action = this.action();\n if (!action) return;\n\n this.confirmationService.confirm({\n message: this.t('iam.permission.remove.confirm', { name: user.userName }),\n header: this.t('iam.permission.remove'),\n icon: 'exclamation-triangle',\n acceptButtonStyleClass: 'p-button-danger',\n accept: async () => {\n this.isRemoving.set(true);\n try {\n const response = await firstValueFrom(\n this.permissionApi.assignUserActions({\n userId: user.userId,\n companyId: user.companyId ?? undefined,\n branchId: user.branchId ?? undefined,\n items: [{ id: action.id, action: 'remove' }],\n }),\n );\n\n if (response.success) {\n this.users.update((list) => list.filter((u) => u.id !== user.id));\n this.messageService.add({\n severity: 'success',\n summary: this.t('shared.success'),\n detail: response?.messageKey\n ? this.t(response.messageKey, response.messageVariables)\n : (response?.message ?? ''),\n });\n }\n } catch {\n // Error toast handled by global interceptor\n } finally {\n this.isRemoving.set(false);\n }\n },\n });\n }\n\n onClose(): void {\n this.closed.emit();\n }\n}\n","import { inject, Service } from '@angular/core';\nimport { APP_CONFIG, IAppConfig, isServiceEnabled } from '@flusys/ng-core';\nimport { ActionScope, IActionBasicInfo, IActionProvider, ISingleResponse } from '@flusys/ng-shared';\nimport { Observable, map } from 'rxjs';\nimport { IAction, IActionTreeDto } from '../interfaces/action.interface';\nimport { ActionApiService } from '../services/action-api.service';\n\nfunction flatten(nodes: IActionTreeDto[]): IAction[] {\n return nodes.flatMap(({ children, ...action }) => [action, ...flatten(children ?? [])]);\n}\n\n/**\n * Implements ACTION_PROVIDER with active actions (groups included, for the tree) from ng-iam:\n * the company whitelist for the `company` scope, the whole action tree for `all`.\n */\n@Service({ autoProvided: false })\nexport class ActionProviderAdapter implements IActionProvider {\n private readonly actionApi = inject(ActionApiService);\n private readonly appConfig = inject<IAppConfig>(APP_CONFIG);\n\n isAvailable(): boolean {\n return isServiceEnabled(this.appConfig, 'iam');\n }\n\n getActions(scope: ActionScope = 'company'): Observable<ISingleResponse<IActionBasicInfo[]>> {\n const source$: Observable<ISingleResponse<IAction[]>> =\n scope === 'all'\n ? this.actionApi.getTree(undefined, true).pipe(map((response) => ({ ...response, data: flatten(response.data ?? []) })))\n : this.actionApi.getActionsForPermission();\n\n return source$.pipe(\n map((response) => ({\n success: response.success,\n message: response.message,\n data: (response.data ?? [])\n .filter((action) => action.isActive)\n .map((action) => ({\n id: action.id,\n name: action.name,\n code: action.code,\n description: action.description,\n parentId: action.parentId,\n serial: action.serial,\n })),\n })),\n );\n }\n}\n","import { inject, Service } from '@angular/core';\nimport {\n IProfilePermissionProvider,\n IProfileRoleInfo,\n IProfileActionInfo,\n ISingleResponse,\n} from '@flusys/ng-shared';\nimport { Observable, map } from 'rxjs';\nimport { PermissionApiService } from '../services/permission-api.service';\n\n/**\n * Profile Permission Provider Adapter\n *\n * Implements IProfilePermissionProvider using ng-iam's PermissionApiService.\n * Allows ng-auth profile page to display user permissions without\n * depending on ng-iam directly.\n *\n * Uses the self-scoped `my-roles`/`my-actions` endpoints (not the admin\n * `get-user-roles`/`get-user-actions` endpoints): those require the\n * user-role/user-action READ permission and only exact-match the given\n * branchId, so they drop company-wide (branch-independent) assignments.\n * The self-scoped endpoints always resolve the caller's own company/branch\n * from the JWT and merge company-wide + branch-specific grants server-side,\n * so the `userId`/`branchId` args below are accepted for interface\n * compatibility but unused.\n *\n * @example\n * // In app.config.ts\n * providers: [\n * ...provideIamProviders()\n * ]\n *\n * // In profile component\n * private readonly permissionProvider = inject(PROFILE_PERMISSION_PROVIDER, { optional: true });\n */\n@Service({ autoProvided: false })\nexport class ProfilePermissionProviderAdapter\n implements IProfilePermissionProvider\n{\n private readonly permissionApi = inject(PermissionApiService);\n\n getUserRoles(): Observable<ISingleResponse<IProfileRoleInfo[]>> {\n return this.permissionApi.getMyRoles().pipe(\n map((response) => ({\n success: response.success,\n message: response.message,\n data: (response.data ?? []).map((role) => ({\n id: role.roleId,\n name: role.roleName,\n description: null,\n })),\n })),\n );\n }\n\n getUserActions(): Observable<ISingleResponse<IProfileActionInfo[]>> {\n return this.permissionApi.getMyActions().pipe(\n map((response) => ({\n success: response.success,\n message: response.message,\n data: (response.data ?? []).map((action) => ({\n id: action.actionId,\n name: action.actionName,\n code: action.actionCode,\n description: null,\n })),\n })),\n );\n }\n}\n","import { Provider } from '@angular/core';\nimport { ACTION_PROVIDER, PROFILE_PERMISSION_PROVIDER } from '@flusys/ng-shared';\nimport { ActionProviderAdapter } from '../adapters/action-provider.adapter';\nimport { ProfilePermissionProviderAdapter } from '../adapters/profile-permission-provider.adapter';\n\n/** Registers IAM provider adapters for ng-shared interfaces */\nexport function provideIamProviders(): Provider[] {\n return [\n { provide: PROFILE_PERMISSION_PROVIDER, useClass: ProfilePermissionProviderAdapter },\n { provide: ACTION_PROVIDER, useClass: ActionProviderAdapter },\n ];\n}\n","import { inject } from '@angular/core';\nimport { Routes } from '@angular/router';\nimport { APP_CONFIG, getPermissionMode } from '@flusys/ng-core';\nimport {\n ACTION_PERMISSIONS,\n COMPANY_ACTION_PERMISSIONS,\n PermissionValidatorService,\n ROLE_ACTION_PERMISSIONS,\n ROLE_PERMISSIONS,\n SHARED_MESSAGES,\n USER_ACTION_PERMISSIONS,\n USER_ROLE_PERMISSIONS,\n anyPermissionGuard,\n permissionGuard,\n resolveTranslationModule,\n} from '@flusys/ng-shared';\nimport { IAM_MESSAGES } from '../constants/messages';\n\nfunction resolveIamDefaultTab(): string {\n const permissionValidator = inject(PermissionValidatorService);\n const permissionMode = getPermissionMode(inject(APP_CONFIG));\n\n if (permissionValidator.hasPermission(ACTION_PERMISSIONS.READ)) {\n return 'actions';\n }\n\n if (\n permissionValidator.hasPermission(ROLE_PERMISSIONS.READ) &&\n (permissionMode === 'rbac' || permissionMode === 'full')\n ) {\n return 'roles';\n }\n\n if (\n permissionValidator.hasAnyPermission([\n ROLE_ACTION_PERMISSIONS.READ,\n USER_ROLE_PERMISSIONS.READ,\n USER_ACTION_PERMISSIONS.READ,\n COMPANY_ACTION_PERMISSIONS.READ,\n ])\n ) {\n return 'permissions';\n }\n\n return 'actions';\n}\n\n/**\n * IAM Routes Configuration\n *\n * Identity and Access Management routing with permission guards.\n * - Actions: Permission actions management\n * - Roles: Role management (conditional on RBAC/FULL mode)\n * - Permissions: User permission assignments\n */\nexport const IAM_ROUTES: Routes = [\n {\n path: '',\n resolve: {\n translations: resolveTranslationModule({\n modules: ['iam'],\n fallbackMessages: { ...IAM_MESSAGES, ...SHARED_MESSAGES },\n }),\n },\n loadComponent: () =>\n import('../pages/iam-container/iam-container.component').then(\n (m) => m.IamContainerComponent,\n ),\n children: [\n // Actions Management\n {\n path: 'actions',\n canActivate: [permissionGuard(ACTION_PERMISSIONS.READ)],\n children: [\n {\n path: '',\n loadComponent: () =>\n import('../pages/action/action-list-page.component').then(\n (m) => m.ActionListPageComponent,\n ),\n },\n {\n path: 'new',\n loadComponent: () =>\n import('../pages/action/action-form-page.component').then(\n (m) => m.ActionFormPageComponent,\n ),\n },\n {\n path: ':id',\n loadComponent: () =>\n import('../pages/action/action-form-page.component').then(\n (m) => m.ActionFormPageComponent,\n ),\n },\n ],\n },\n\n // Roles Management\n {\n path: 'roles',\n canActivate: [permissionGuard(ROLE_PERMISSIONS.READ)],\n children: [\n {\n path: '',\n loadComponent: () =>\n import('../pages/role/role-list-page.component').then(\n (m) => m.RoleListPageComponent,\n ),\n },\n {\n path: 'new',\n loadComponent: () =>\n import('../pages/role/role-form-page.component').then(\n (m) => m.RoleFormPageComponent,\n ),\n },\n {\n path: ':id',\n loadComponent: () =>\n import('../pages/role/role-form-page.component').then(\n (m) => m.RoleFormPageComponent,\n ),\n },\n ],\n },\n\n // Permissions Management (requires any permission tab access)\n {\n path: 'permissions',\n canActivate: [\n anyPermissionGuard([\n ROLE_ACTION_PERMISSIONS.READ,\n USER_ROLE_PERMISSIONS.READ,\n USER_ACTION_PERMISSIONS.READ,\n COMPANY_ACTION_PERMISSIONS.READ,\n ]),\n ],\n loadComponent: () =>\n import('../pages/permission/permission-page.component').then(\n (m) => m.PermissionPageComponent,\n ),\n },\n\n // Default redirect to the first tab the user has permission to see\n {\n path: '',\n redirectTo: () => resolveIamDefaultTab(),\n pathMatch: 'full',\n },\n ],\n },\n];\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flusys/ng-iam",
|
|
3
|
-
"version": "9.1.
|
|
3
|
+
"version": "9.1.2",
|
|
4
4
|
"description": "Identity and Access Management (IAM) for Angular - Independent from ng-auth through Provider Interface Pattern",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"peerDependencies": {
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
"@angular/core": ">=22.0.0",
|
|
9
9
|
"@angular/forms": ">=22.0.0",
|
|
10
10
|
"@angular/router": ">=22.0.0",
|
|
11
|
-
"@flusys/ng-core": ">=9.1.
|
|
12
|
-
"@flusys/ng-layout": ">=9.1.
|
|
13
|
-
"@flusys/ng-shared": ">=9.1.
|
|
14
|
-
"@flusys/ng-ui": ">=9.1.
|
|
11
|
+
"@flusys/ng-core": ">=9.1.2",
|
|
12
|
+
"@flusys/ng-layout": ">=9.1.2",
|
|
13
|
+
"@flusys/ng-shared": ">=9.1.2",
|
|
14
|
+
"@flusys/ng-ui": ">=9.1.2",
|
|
15
15
|
"rxjs": "^7.8.0"
|
|
16
16
|
},
|
|
17
17
|
"sideEffects": false,
|