@flusys/ng-iam 7.1.0 → 8.0.0

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.
Files changed (23) hide show
  1. package/fesm2022/{flusys-ng-iam-action-form-page.component-Ci56tFEu.mjs → flusys-ng-iam-action-form-page.component-CF_ixS-r.mjs} +18 -15
  2. package/fesm2022/flusys-ng-iam-action-form-page.component-CF_ixS-r.mjs.map +1 -0
  3. package/fesm2022/{flusys-ng-iam-action-list-page.component-BRi_CpGl.mjs → flusys-ng-iam-action-list-page.component-BveT0xT6.mjs} +62 -10
  4. package/fesm2022/flusys-ng-iam-action-list-page.component-BveT0xT6.mjs.map +1 -0
  5. package/fesm2022/{flusys-ng-iam-flusys-ng-iam-BEAhj9ma.mjs → flusys-ng-iam-flusys-ng-iam-CjLr3bfY.mjs} +661 -169
  6. package/fesm2022/flusys-ng-iam-flusys-ng-iam-CjLr3bfY.mjs.map +1 -0
  7. package/fesm2022/{flusys-ng-iam-iam-container.component-D0m8u6nu.mjs → flusys-ng-iam-iam-container.component-XBoIeQ0t.mjs} +4 -4
  8. package/fesm2022/{flusys-ng-iam-iam-container.component-D0m8u6nu.mjs.map → flusys-ng-iam-iam-container.component-XBoIeQ0t.mjs.map} +1 -1
  9. package/fesm2022/{flusys-ng-iam-permission-page.component-CVaxwwcS.mjs → flusys-ng-iam-permission-page.component-CGtj1EiO.mjs} +12 -11
  10. package/fesm2022/flusys-ng-iam-permission-page.component-CGtj1EiO.mjs.map +1 -0
  11. package/fesm2022/{flusys-ng-iam-role-form-page.component-ByMbnQ53.mjs → flusys-ng-iam-role-form-page.component-Cfc8za3D.mjs} +20 -14
  12. package/fesm2022/flusys-ng-iam-role-form-page.component-Cfc8za3D.mjs.map +1 -0
  13. package/fesm2022/{flusys-ng-iam-role-list-page.component-BCtoWvFQ.mjs → flusys-ng-iam-role-list-page.component-vFHxd3Q-.mjs} +61 -10
  14. package/fesm2022/flusys-ng-iam-role-list-page.component-vFHxd3Q-.mjs.map +1 -0
  15. package/fesm2022/flusys-ng-iam.mjs +1 -1
  16. package/package.json +5 -5
  17. package/types/flusys-ng-iam.d.ts +99 -72
  18. package/fesm2022/flusys-ng-iam-action-form-page.component-Ci56tFEu.mjs.map +0 -1
  19. package/fesm2022/flusys-ng-iam-action-list-page.component-BRi_CpGl.mjs.map +0 -1
  20. package/fesm2022/flusys-ng-iam-flusys-ng-iam-BEAhj9ma.mjs.map +0 -1
  21. package/fesm2022/flusys-ng-iam-permission-page.component-CVaxwwcS.mjs.map +0 -1
  22. package/fesm2022/flusys-ng-iam-role-form-page.component-ByMbnQ53.mjs.map +0 -1
  23. package/fesm2022/flusys-ng-iam-role-list-page.component-BCtoWvFQ.mjs.map +0 -1
@@ -1,15 +1,13 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, inject, signal, input, output, effect, Component, computed, DestroyRef, viewChild } from '@angular/core';
3
- import { ApiResourceService, TranslateService, PermissionValidatorService, AngularModule, TranslatePipe, ROLE_ACTION_PERMISSIONS, HasPermissionDirective, COMPANY_ACTION_PERMISSIONS, COMPANY_API_PROVIDER, USER_ROLE_PERMISSIONS, USER_PERMISSION_PROVIDER, UserSelectComponent, USER_ACTION_PERMISSIONS, PROFILE_PERMISSION_PROVIDER, ACTION_PERMISSIONS, ROLE_PERMISSIONS, permissionGuard, anyPermissionGuard, resolveTranslationModule, SHARED_MESSAGES } from '@flusys/ng-shared';
2
+ import { Service, inject, signal, input, output, effect, Component, computed, DestroyRef, viewChild } from '@angular/core';
3
+ import { ApiResourceService, TranslateService, PermissionValidatorService, TranslatePipe, ROLE_ACTION_PERMISSIONS, HasPermissionDirective, COMPANY_ACTION_PERMISSIONS, COMPANY_API_PROVIDER, USER_ROLE_PERMISSIONS, USER_PERMISSION_PROVIDER, UserSelectComponent, USER_ACTION_PERMISSIONS, USER_PROVIDER, PROFILE_PERMISSION_PROVIDER, ACTION_PERMISSIONS, ROLE_PERMISSIONS, permissionGuard, anyPermissionGuard, resolveTranslationModule, SHARED_MESSAGES } from '@flusys/ng-shared';
4
4
  import { APP_CONFIG, getServiceUrl, BaseApiService, isCompanyFeatureEnabled, getPermissionMode } from '@flusys/ng-core';
5
- import * as i2 from '@flusys/ng-ui';
6
- import { ConfirmationService, MessageService, UiModule } from '@flusys/ng-ui';
5
+ import { ConfirmationService, MessageService, FButtonDirective, SelectComponent, TooltipDirective, UiIconComponent, CheckboxComponent, TagComponent, TreeTableComponent, TreeTableTogglerComponent, TableComponent, DialogComponent, ProgressSpinnerComponent } from '@flusys/ng-ui';
7
6
  import { HttpClient } from '@angular/common/http';
8
7
  import { of, firstValueFrom, map as map$1 } from 'rxjs';
9
8
  import { tap, catchError, map } from 'rxjs/operators';
10
- import * as i1 from '@angular/common';
11
- import { CommonModule } from '@angular/common';
12
- import * as i1$1 from '@angular/forms';
9
+ import { NgTemplateOutlet } from '@angular/common';
10
+ import * as i1 from '@angular/forms';
13
11
  import { FormsModule } from '@angular/forms';
14
12
  import { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';
15
13
 
@@ -85,6 +83,11 @@ const IAM_MESSAGES = {
85
83
  'iam.action.type.backend': 'Backend',
86
84
  'iam.action.type.frontend': 'Frontend',
87
85
  'iam.action.type.both': 'Both',
86
+ // components/role-permitted-users-dialog.component.ts, components/action-permitted-users-dialog.component.ts
87
+ 'iam.permission.view.users': 'View Users',
88
+ 'iam.permission.no.users': 'No users found',
89
+ 'iam.permission.remove': 'Remove Access',
90
+ 'iam.permission.remove.confirm': 'Remove access for {{name}}?',
88
91
  'iam.action.delete.title': 'Delete Action',
89
92
  // pages/action/action-form-page.component.ts
90
93
  'iam.action.edit': 'Edit Action',
@@ -239,12 +242,11 @@ class RoleApiService extends ApiResourceService {
239
242
  constructor() {
240
243
  super('roles', 'iam');
241
244
  }
242
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: RoleApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
243
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: RoleApiService, providedIn: 'root' });
245
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: RoleApiService, deps: [], target: i0.ɵɵFactoryTarget.Service });
246
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.5", ngImport: i0, type: RoleApiService });
244
247
  }
245
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: RoleApiService, decorators: [{
246
- type: Injectable,
247
- args: [{ providedIn: 'root' }]
248
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: RoleApiService, decorators: [{
249
+ type: Service
248
250
  }], ctorParameters: () => [] });
249
251
 
250
252
  class ActionApiService extends ApiResourceService {
@@ -269,12 +271,11 @@ class ActionApiService extends ApiResourceService {
269
271
  const iamBaseUrl = getServiceUrl(this.appConfig, 'iam');
270
272
  return this.http.post(`${iamBaseUrl}/actions/tree`, body);
271
273
  }
272
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ActionApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
273
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ActionApiService, providedIn: 'root' });
274
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: ActionApiService, deps: [], target: i0.ɵɵFactoryTarget.Service });
275
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.5", ngImport: i0, type: ActionApiService });
274
276
  }
275
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ActionApiService, decorators: [{
276
- type: Injectable,
277
- args: [{ providedIn: 'root' }]
277
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: ActionApiService, decorators: [{
278
+ type: Service
278
279
  }], ctorParameters: () => [] });
279
280
 
280
281
  function extractRequiredActionIds(logic) {
@@ -806,12 +807,11 @@ class ActionPermissionLogicService {
806
807
  }
807
808
  return `${indent}${this.t('iam.logic.invalid')}`;
808
809
  }
809
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ActionPermissionLogicService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
810
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ActionPermissionLogicService, providedIn: 'root' });
810
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: ActionPermissionLogicService, deps: [], target: i0.ɵɵFactoryTarget.Service });
811
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.5", ngImport: i0, type: ActionPermissionLogicService });
811
812
  }
812
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ActionPermissionLogicService, decorators: [{
813
- type: Injectable,
814
- args: [{ providedIn: 'root' }]
813
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: ActionPermissionLogicService, decorators: [{
814
+ type: Service
815
815
  }] });
816
816
 
817
817
  class PermissionApiService extends BaseApiService {
@@ -836,6 +836,14 @@ class PermissionApiService extends BaseApiService {
836
836
  getRoleActions(roleId) {
837
837
  return this.http.post(this.getUrl('permissions/get-role-actions'), { roleId });
838
838
  }
839
+ /** Reverse lookup: users assigned to a role */
840
+ getRoleUsers(roleId) {
841
+ return this.http.post(this.getUrl('permissions/get-role-users'), { roleId });
842
+ }
843
+ /** Reverse lookup: users directly assigned an action */
844
+ getActionUsers(actionId) {
845
+ return this.http.post(this.getUrl('permissions/get-action-users'), { actionId });
846
+ }
839
847
  assignCompanyActions(data) {
840
848
  return this.http.post(this.getUrl('permissions/company-actions/assign'), data);
841
849
  }
@@ -850,12 +858,11 @@ class PermissionApiService extends BaseApiService {
850
858
  getMyActions() {
851
859
  return this.http.post(this.getUrl('permissions/my-actions'), {});
852
860
  }
853
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PermissionApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
854
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PermissionApiService, providedIn: 'root' });
861
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: PermissionApiService, deps: [], target: i0.ɵɵFactoryTarget.Service });
862
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.5", ngImport: i0, type: PermissionApiService });
855
863
  }
856
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PermissionApiService, decorators: [{
857
- type: Injectable,
858
- args: [{ providedIn: 'root' }]
864
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: PermissionApiService, decorators: [{
865
+ type: Service
859
866
  }], ctorParameters: () => [] });
860
867
 
861
868
  /**
@@ -877,14 +884,11 @@ class MyPermissionsApiService {
877
884
  getMyPermissions(dto = {}) {
878
885
  return this.http.post(`${this.baseUrl}/my-permissions`, dto);
879
886
  }
880
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MyPermissionsApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
881
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MyPermissionsApiService, providedIn: 'root' });
887
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: MyPermissionsApiService, deps: [], target: i0.ɵɵFactoryTarget.Service });
888
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.5", ngImport: i0, type: MyPermissionsApiService });
882
889
  }
883
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MyPermissionsApiService, decorators: [{
884
- type: Injectable,
885
- args: [{
886
- providedIn: 'root',
887
- }]
890
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: MyPermissionsApiService, decorators: [{
891
+ type: Service
888
892
  }] });
889
893
 
890
894
  class PermissionStateService {
@@ -913,12 +917,11 @@ class PermissionStateService {
913
917
  isLoaded() {
914
918
  return this._permissions() !== null && this.permissionValidator.isLoaded();
915
919
  }
916
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PermissionStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
917
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PermissionStateService, providedIn: 'root' });
920
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: PermissionStateService, deps: [], target: i0.ɵɵFactoryTarget.Service });
921
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.5", ngImport: i0, type: PermissionStateService });
918
922
  }
919
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PermissionStateService, decorators: [{
920
- type: Injectable,
921
- args: [{ providedIn: 'root' }]
923
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: PermissionStateService, decorators: [{
924
+ type: Service
922
925
  }] });
923
926
 
924
927
  // Role services
@@ -948,14 +951,12 @@ function createGroupNode(operator = 'AND') {
948
951
  function createActionNode(actionId = '') {
949
952
  return { id: crypto.randomUUID(), type: 'action', actionId };
950
953
  }
951
- /** Visual builder for AND/OR permission logic trees */
952
954
  class LogicBuilderComponent {
953
955
  logic = input(null, /* @ts-ignore */
954
956
  ...(ngDevMode ? [{ debugName: "logic" }] : /* istanbul ignore next */ []));
955
957
  actions = input([], /* @ts-ignore */
956
958
  ...(ngDevMode ? [{ debugName: "actions" }] : /* istanbul ignore next */ []));
957
959
  logicChange = output();
958
- /** Internal builder tree state (private writable + public readonly pattern) */
959
960
  _builderTree = signal(null, /* @ts-ignore */
960
961
  ...(ngDevMode ? [{ debugName: "_builderTree" }] : /* istanbul ignore next */ []));
961
962
  builderLogic = this._builderTree.asReadonly();
@@ -1003,14 +1004,12 @@ class LogicBuilderComponent {
1003
1004
  updateActionId(nodeId, actionId) {
1004
1005
  this.updateNode(nodeId, (node) => ({ ...node, actionId }));
1005
1006
  }
1006
- /** Updates a node in the tree and emits the change */
1007
1007
  updateNode(nodeId, updater) {
1008
1008
  const tree = this._builderTree();
1009
1009
  if (!tree)
1010
1010
  return;
1011
1011
  this.updateTreeAndEmit(this.updateNodeInTree(tree, nodeId, updater));
1012
1012
  }
1013
- /** Sets the tree and emits the change */
1014
1013
  updateTreeAndEmit(tree) {
1015
1014
  this._builderTree.set(tree);
1016
1015
  this.logicChange.emit(toLogicNode(tree));
@@ -1035,8 +1034,8 @@ class LogicBuilderComponent {
1035
1034
  .map((child) => this.removeNodeFromTree(child, targetId)),
1036
1035
  };
1037
1036
  }
1038
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: LogicBuilderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1039
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", 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: `
1037
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: LogicBuilderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1038
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.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: `
1040
1039
  <div class="logic-builder">
1041
1040
  <div class="flex justify-between items-center mb-3">
1042
1041
  <h4 class="text-sm font-semibold m-0">
@@ -1074,10 +1073,8 @@ class LogicBuilderComponent {
1074
1073
  <!-- Root Node -->
1075
1074
  <div class="text-sm bg-surface-0 dark:bg-surface-900 rounded border border-surface">
1076
1075
  <ng-container
1077
- *ngTemplateOutlet="
1078
- nodeTemplate;
1079
- context: { $implicit: builderLogic()!, depth: 0 }
1080
- "
1076
+ [ngTemplateOutlet]="nodeTemplate"
1077
+ [ngTemplateOutletContext]="{ $implicit: builderLogic()!, depth: 0 }"
1081
1078
  ></ng-container>
1082
1079
  </div>
1083
1080
  </div>
@@ -1156,10 +1153,8 @@ class LogicBuilderComponent {
1156
1153
  <div class="ml-5 mt-2 pl-3 border-l-2 border-surface">
1157
1154
  @for (child of node.children; track child.id) {
1158
1155
  <ng-container
1159
- *ngTemplateOutlet="
1160
- nodeTemplate;
1161
- context: { $implicit: child, depth: depth + 1 }
1162
- "
1156
+ [ngTemplateOutlet]="nodeTemplate"
1157
+ [ngTemplateOutletContext]="{ $implicit: child, depth: depth + 1 }"
1163
1158
  ></ng-container>
1164
1159
  }
1165
1160
  </div>
@@ -1198,11 +1193,19 @@ class LogicBuilderComponent {
1198
1193
  }
1199
1194
  </div>
1200
1195
  </ng-template>
1201
- `, 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(--f-blue-100, #dbeafe);color:var(--f-blue-700, #1e40af)}.node-type.action{background-color:var(--f-green-100, #d1fae5);color:var(--f-green-700, #065f46)}:host-context(.app-dark) .node-type.group{background-color:#3b82f633;color:var(--f-blue-400, #60a5fa)}:host-context(.app-dark) .node-type.action{background-color:#22c55e33;color:var(--f-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(--f-yellow-100, #fef3c7);color:var(--f-yellow-700, #92400e)}.operator-badge.or{background-color:var(--f-indigo-100, #e0e7ff);color:var(--f-indigo-700, #3730a3)}:host-context(.app-dark) .operator-badge.and{background-color:#eab30833;color:var(--f-yellow-400, #facc15)}:host-context(.app-dark) .operator-badge.or{background-color:#6366f133;color:var(--f-indigo-400, #818cf8)}.operator-badge:hover{opacity:.8}.action-select{background-color:var(--f-surface-0, #ffffff);color:var(--f-text-color, #1f2937)}:host-context(.app-dark) .action-select{background-color:var(--f-surface-900, #1f2937);color:var(--f-text-color, #f9fafb)}.action-select:focus{outline:none;border-color:var(--f-primary-color, #3b82f6)}\n"], dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { 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: UiModule }, { kind: "directive", type: i2.FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "variant", "rounded", "raised", "fluid", "disabled", "loading", "loadingIcon", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: i2.SelectComponent, selector: "f-select", inputs: ["options", "optionLabel", "optionValue", "placeholder", "disabled", "filter", "filterBy", "filterMatchMode", "filterLocale", "filterPlaceholder", "resetFilterOnHide", "autofocusFilter", "emptyMessage", "emptyFilterMessage", "showClear", "loading", "loadingIcon", "dropdownIcon", "clearIcon", "inputId", "invalid", "touched", "styleClass", "style", "appendTo", "editable", "readonly", "autofocus", "checkmark", "group", "optionGroupLabel", "optionGroupChildren", "virtualScroll", "virtualScrollItemSize", "lazy"], outputs: ["onFilter", "onChange", "onShow", "onHide", "onBlur", "onFocus", "onClear", "onLazyLoad"] }, { kind: "directive", type: i2.TooltipDirective, selector: "[fTooltip]", inputs: ["fTooltip", "tooltipPosition", "positionStyle", "tooltipStyleClass", "disabled", "tooltipEvent", "showDelay", "hideDelay", "life", "autoHide", "positionTop", "positionLeft", "escape"] }, { kind: "component", type: i2.UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill", "severity"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1196
+ `, 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(--f-blue-100, #dbeafe);color:var(--f-blue-700, #1e40af)}.node-type.action{background-color:var(--f-green-100, #d1fae5);color:var(--f-green-700, #065f46)}:host-context(.app-dark) .node-type.group{background-color:#3b82f633;color:var(--f-blue-400, #60a5fa)}:host-context(.app-dark) .node-type.action{background-color:#22c55e33;color:var(--f-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(--f-yellow-100, #fef3c7);color:var(--f-yellow-700, #92400e)}.operator-badge.or{background-color:var(--f-indigo-100, #e0e7ff);color:var(--f-indigo-700, #3730a3)}:host-context(.app-dark) .operator-badge.and{background-color:#eab30833;color:var(--f-yellow-400, #facc15)}:host-context(.app-dark) .operator-badge.or{background-color:#6366f133;color:var(--f-indigo-400, #818cf8)}.operator-badge:hover{opacity:.8}.action-select{background-color:var(--f-surface-0, #ffffff);color:var(--f-text-color, #1f2937)}:host-context(.app-dark) .action-select{background-color:var(--f-surface-900, #1f2937);color:var(--f-text-color, #f9fafb)}.action-select:focus{outline:none;border-color:var(--f-primary-color, #3b82f6)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "variant", "rounded", "raised", "fluid", "disabled", "loading", "loadingIcon", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: SelectComponent, selector: "f-select", inputs: ["options", "optionLabel", "optionValue", "placeholder", "disabled", "filter", "filterBy", "filterMatchMode", "filterLocale", "filterPlaceholder", "resetFilterOnHide", "autofocusFilter", "emptyMessage", "emptyFilterMessage", "showClear", "loading", "loadingIcon", "dropdownIcon", "clearIcon", "inputId", "invalid", "touched", "styleClass", "style", "appendTo", "editable", "readonly", "autofocus", "checkmark", "group", "optionGroupLabel", "optionGroupChildren", "virtualScroll", "virtualScrollItemSize", "lazy"], outputs: ["onFilter", "onChange", "onShow", "onHide", "onBlur", "onFocus", "onClear", "onLazyLoad"] }, { kind: "directive", type: TooltipDirective, selector: "[fTooltip]", inputs: ["fTooltip", "tooltipPosition", "positionStyle", "tooltipStyleClass", "disabled", "tooltipEvent", "showDelay", "hideDelay", "life", "autoHide", "positionTop", "positionLeft", "escape"] }, { kind: "component", type: UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill", "severity"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1202
1197
  }
1203
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: LogicBuilderComponent, decorators: [{
1198
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: LogicBuilderComponent, decorators: [{
1204
1199
  type: Component,
1205
- args: [{ selector: 'lib-logic-builder', imports: [AngularModule, UiModule, TranslatePipe], template: `
1200
+ args: [{ selector: 'lib-logic-builder', imports: [
1201
+ FormsModule,
1202
+ NgTemplateOutlet,
1203
+ FButtonDirective,
1204
+ SelectComponent,
1205
+ TooltipDirective,
1206
+ UiIconComponent,
1207
+ TranslatePipe,
1208
+ ], template: `
1206
1209
  <div class="logic-builder">
1207
1210
  <div class="flex justify-between items-center mb-3">
1208
1211
  <h4 class="text-sm font-semibold m-0">
@@ -1240,10 +1243,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
1240
1243
  <!-- Root Node -->
1241
1244
  <div class="text-sm bg-surface-0 dark:bg-surface-900 rounded border border-surface">
1242
1245
  <ng-container
1243
- *ngTemplateOutlet="
1244
- nodeTemplate;
1245
- context: { $implicit: builderLogic()!, depth: 0 }
1246
- "
1246
+ [ngTemplateOutlet]="nodeTemplate"
1247
+ [ngTemplateOutletContext]="{ $implicit: builderLogic()!, depth: 0 }"
1247
1248
  ></ng-container>
1248
1249
  </div>
1249
1250
  </div>
@@ -1322,10 +1323,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
1322
1323
  <div class="ml-5 mt-2 pl-3 border-l-2 border-surface">
1323
1324
  @for (child of node.children; track child.id) {
1324
1325
  <ng-container
1325
- *ngTemplateOutlet="
1326
- nodeTemplate;
1327
- context: { $implicit: child, depth: depth + 1 }
1328
- "
1326
+ [ngTemplateOutlet]="nodeTemplate"
1327
+ [ngTemplateOutletContext]="{ $implicit: child, depth: depth + 1 }"
1329
1328
  ></ng-container>
1330
1329
  }
1331
1330
  </div>
@@ -1705,8 +1704,8 @@ class RoleActionSelectorComponent extends BaseActionSelectorComponent {
1705
1704
  this.saving.set(false);
1706
1705
  }
1707
1706
  }
1708
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: RoleActionSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1709
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: RoleActionSelectorComponent, isStandalone: true, selector: "flusys-role-action-selector", viewQueries: [{ propertyName: "roleSelectRef", first: true, predicate: ["roleSelect"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
1707
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: RoleActionSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1708
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: RoleActionSelectorComponent, isStandalone: true, selector: "flusys-role-action-selector", viewQueries: [{ propertyName: "roleSelectRef", first: true, predicate: ["roleSelect"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
1710
1709
  <div class="role-action-selector">
1711
1710
  <div class="surface-card p-4 rounded-border mb-4 shadow-sm">
1712
1711
  <div class="grid grid-cols-1 sm:grid-cols-2 gap-5">
@@ -1980,11 +1979,23 @@ class RoleActionSelectorComponent extends BaseActionSelectorComponent {
1980
1979
  }
1981
1980
  }
1982
1981
  </div>
1983
- `, isInline: true, styles: [":host{display:block}.empty-state-icon{width:3rem;height:3rem;border-radius:9999px;display:flex;align-items:center;justify-content:center;background-color:var(--f-primary-50, rgba(59, 130, 246, .08))}:host-context(.app-dark) .empty-state-icon{background-color:#60a5fa1f}.validation-warning{background-color:var(--f-yellow-50, #fefce8);border-left:4px solid var(--f-yellow-500, #eab308);color:var(--f-yellow-700, #a16207)}:host-context(.app-dark) .validation-warning{background-color:#eab3081a;color:var(--f-yellow-400, #facc15)}:host ::ng-deep tr.highlight-warning{background-color:var(--f-red-50, rgba(239, 68, 68, .1))!important}:host-context(.app-dark) ::ng-deep tr.highlight-warning{background-color:#ef444426!important}\n"], dependencies: [{ 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: UiModule }, { kind: "directive", type: i2.FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "variant", "rounded", "raised", "fluid", "disabled", "loading", "loadingIcon", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: i2.TagComponent, selector: "f-tag", inputs: ["value", "severity", "icon", "rounded", "color", "styleClass", "style"] }, { kind: "component", type: i2.CheckboxComponent, selector: "f-checkbox", inputs: ["label", "binary", "disabled", "readonly", "inputId", "invalid", "indeterminate", "variant", "size", "touched", "styleClass", "style", "checked"], outputs: ["onChange", "onBlur", "touch", "checkedChange"] }, { kind: "component", type: i2.SelectComponent, selector: "f-select", inputs: ["options", "optionLabel", "optionValue", "placeholder", "disabled", "filter", "filterBy", "filterMatchMode", "filterLocale", "filterPlaceholder", "resetFilterOnHide", "autofocusFilter", "emptyMessage", "emptyFilterMessage", "showClear", "loading", "loadingIcon", "dropdownIcon", "clearIcon", "inputId", "invalid", "touched", "styleClass", "style", "appendTo", "editable", "readonly", "autofocus", "checkmark", "group", "optionGroupLabel", "optionGroupChildren", "virtualScroll", "virtualScrollItemSize", "lazy"], outputs: ["onFilter", "onChange", "onShow", "onHide", "onBlur", "onFocus", "onClear", "onLazyLoad"] }, { kind: "directive", type: i2.TooltipDirective, selector: "[fTooltip]", inputs: ["fTooltip", "tooltipPosition", "positionStyle", "tooltipStyleClass", "disabled", "tooltipEvent", "showDelay", "hideDelay", "life", "autoHide", "positionTop", "positionLeft", "escape"] }, { kind: "component", type: i2.TreeTableComponent, selector: "f-treetable", inputs: ["value", "loading", "dataKey", "styleClass", "tableStyle", "scrollable", "scrollHeight", "resizableColumns", "lazy", "totalRecords", "paginator", "first", "rows", "rowsPerPageOptions", "showCurrentPageReport", "currentPageReportTemplate", "globalFilterFields", "filterDelay", "selectionMode", "sortMode", "virtualScroll", "virtualScrollItemSize", "sortField", "sortOrder", "multiSortMeta", "filters", "selection", "contextMenuSelection"], outputs: ["sortFieldChange", "sortOrderChange", "multiSortMetaChange", "filtersChange", "selectionChange", "contextMenuSelectionChange", "onLazyLoad", "onSort", "onFilter", "onNodeExpand", "onNodeCollapse", "onNodeSelect", "onNodeUnselect", "onRowContextMenu"] }, { kind: "component", type: i2.TreeTableTogglerComponent, selector: "f-treetabletoggler", inputs: ["rowNode"] }, { kind: "component", type: i2.UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill", "severity"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1982
+ `, isInline: true, styles: [":host{display:block}.empty-state-icon{width:3rem;height:3rem;border-radius:9999px;display:flex;align-items:center;justify-content:center;background-color:var(--f-primary-50, rgba(59, 130, 246, .08))}:host-context(.app-dark) .empty-state-icon{background-color:#60a5fa1f}.validation-warning{background-color:var(--f-yellow-50, #fefce8);border-left:4px solid var(--f-yellow-500, #eab308);color:var(--f-yellow-700, #a16207)}:host-context(.app-dark) .validation-warning{background-color:#eab3081a;color:var(--f-yellow-400, #facc15)}:host ::ng-deep tr.highlight-warning{background-color:var(--f-red-50, rgba(239, 68, 68, .1))!important}:host-context(.app-dark) ::ng-deep tr.highlight-warning{background-color:#ef444426!important}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CheckboxComponent, selector: "f-checkbox", inputs: ["label", "binary", "disabled", "readonly", "inputId", "invalid", "indeterminate", "variant", "size", "touched", "styleClass", "style", "checked"], outputs: ["onChange", "onBlur", "touch", "checkedChange"] }, { kind: "directive", type: FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "variant", "rounded", "raised", "fluid", "disabled", "loading", "loadingIcon", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: SelectComponent, selector: "f-select", inputs: ["options", "optionLabel", "optionValue", "placeholder", "disabled", "filter", "filterBy", "filterMatchMode", "filterLocale", "filterPlaceholder", "resetFilterOnHide", "autofocusFilter", "emptyMessage", "emptyFilterMessage", "showClear", "loading", "loadingIcon", "dropdownIcon", "clearIcon", "inputId", "invalid", "touched", "styleClass", "style", "appendTo", "editable", "readonly", "autofocus", "checkmark", "group", "optionGroupLabel", "optionGroupChildren", "virtualScroll", "virtualScrollItemSize", "lazy"], outputs: ["onFilter", "onChange", "onShow", "onHide", "onBlur", "onFocus", "onClear", "onLazyLoad"] }, { kind: "component", type: TagComponent, selector: "f-tag", inputs: ["value", "severity", "icon", "rounded", "color", "styleClass", "style"] }, { kind: "directive", type: TooltipDirective, selector: "[fTooltip]", inputs: ["fTooltip", "tooltipPosition", "positionStyle", "tooltipStyleClass", "disabled", "tooltipEvent", "showDelay", "hideDelay", "life", "autoHide", "positionTop", "positionLeft", "escape"] }, { kind: "component", type: TreeTableComponent, selector: "f-treetable", inputs: ["value", "loading", "dataKey", "styleClass", "tableStyle", "scrollable", "scrollHeight", "resizableColumns", "lazy", "totalRecords", "paginator", "first", "rows", "rowsPerPageOptions", "showCurrentPageReport", "currentPageReportTemplate", "globalFilterFields", "filterDelay", "selectionMode", "sortMode", "virtualScroll", "virtualScrollItemSize", "sortField", "sortOrder", "multiSortMeta", "filters", "selection", "contextMenuSelection"], outputs: ["sortFieldChange", "sortOrderChange", "multiSortMetaChange", "filtersChange", "selectionChange", "contextMenuSelectionChange", "onLazyLoad", "onSort", "onFilter", "onNodeExpand", "onNodeCollapse", "onNodeSelect", "onNodeUnselect", "onRowContextMenu"] }, { kind: "component", type: TreeTableTogglerComponent, selector: "f-treetabletoggler", inputs: ["rowNode"] }, { kind: "component", type: UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill", "severity"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1984
1983
  }
1985
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: RoleActionSelectorComponent, decorators: [{
1984
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: RoleActionSelectorComponent, decorators: [{
1986
1985
  type: Component,
1987
- args: [{ selector: 'flusys-role-action-selector', imports: [FormsModule, UiModule, HasPermissionDirective, TranslatePipe], template: `
1986
+ args: [{ selector: 'flusys-role-action-selector', imports: [
1987
+ FormsModule,
1988
+ CheckboxComponent,
1989
+ FButtonDirective,
1990
+ SelectComponent,
1991
+ TagComponent,
1992
+ TooltipDirective,
1993
+ TreeTableComponent,
1994
+ TreeTableTogglerComponent,
1995
+ UiIconComponent,
1996
+ HasPermissionDirective,
1997
+ TranslatePipe,
1998
+ ], template: `
1988
1999
  <div class="role-action-selector">
1989
2000
  <div class="surface-card p-4 rounded-border mb-4 shadow-sm">
1990
2001
  <div class="grid grid-cols-1 sm:grid-cols-2 gap-5">
@@ -2422,8 +2433,8 @@ class CompanyActionSelectorComponent extends BaseActionSelectorComponent {
2422
2433
  },
2423
2434
  });
2424
2435
  }
2425
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CompanyActionSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2426
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: CompanyActionSelectorComponent, isStandalone: true, selector: "flusys-company-action-selector", viewQueries: [{ propertyName: "companySelectRef", first: true, predicate: ["companySelect"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
2436
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: CompanyActionSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2437
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: CompanyActionSelectorComponent, isStandalone: true, selector: "flusys-company-action-selector", viewQueries: [{ propertyName: "companySelectRef", first: true, predicate: ["companySelect"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
2427
2438
  <div class="company-action-selector">
2428
2439
  <div class="surface-card p-4 rounded-border mb-4 shadow-sm">
2429
2440
  <div class="grid grid-cols-1 sm:grid-cols-2 gap-5">
@@ -2690,11 +2701,23 @@ class CompanyActionSelectorComponent extends BaseActionSelectorComponent {
2690
2701
  }
2691
2702
  }
2692
2703
  </div>
2693
- `, isInline: true, styles: [":host{display:block}.empty-state-icon{width:3rem;height:3rem;border-radius:9999px;display:flex;align-items:center;justify-content:center;background-color:var(--f-primary-50, rgba(59, 130, 246, .08))}:host-context(.app-dark) .empty-state-icon{background-color:#60a5fa1f}.validation-warning{background-color:var(--f-yellow-50, #fefce8);border-left:4px solid var(--f-yellow-500, #eab308);color:var(--f-yellow-700, #a16207)}:host-context(.app-dark) .validation-warning{background-color:#eab3081a;color:var(--f-yellow-400, #facc15)}:host ::ng-deep tr.highlight-warning{background-color:var(--f-red-50, rgba(239, 68, 68, .1))!important}:host-context(.app-dark) ::ng-deep tr.highlight-warning{background-color:#ef444426!important}\n"], dependencies: [{ kind: "ngmodule", type: UiModule }, { kind: "directive", type: i2.FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "variant", "rounded", "raised", "fluid", "disabled", "loading", "loadingIcon", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: i2.TagComponent, selector: "f-tag", inputs: ["value", "severity", "icon", "rounded", "color", "styleClass", "style"] }, { kind: "component", type: i2.CheckboxComponent, selector: "f-checkbox", inputs: ["label", "binary", "disabled", "readonly", "inputId", "invalid", "indeterminate", "variant", "size", "touched", "styleClass", "style", "checked"], outputs: ["onChange", "onBlur", "touch", "checkedChange"] }, { kind: "component", type: i2.SelectComponent, selector: "f-select", inputs: ["options", "optionLabel", "optionValue", "placeholder", "disabled", "filter", "filterBy", "filterMatchMode", "filterLocale", "filterPlaceholder", "resetFilterOnHide", "autofocusFilter", "emptyMessage", "emptyFilterMessage", "showClear", "loading", "loadingIcon", "dropdownIcon", "clearIcon", "inputId", "invalid", "touched", "styleClass", "style", "appendTo", "editable", "readonly", "autofocus", "checkmark", "group", "optionGroupLabel", "optionGroupChildren", "virtualScroll", "virtualScrollItemSize", "lazy"], outputs: ["onFilter", "onChange", "onShow", "onHide", "onBlur", "onFocus", "onClear", "onLazyLoad"] }, { kind: "directive", type: i2.TooltipDirective, selector: "[fTooltip]", inputs: ["fTooltip", "tooltipPosition", "positionStyle", "tooltipStyleClass", "disabled", "tooltipEvent", "showDelay", "hideDelay", "life", "autoHide", "positionTop", "positionLeft", "escape"] }, { kind: "component", type: i2.TreeTableComponent, selector: "f-treetable", inputs: ["value", "loading", "dataKey", "styleClass", "tableStyle", "scrollable", "scrollHeight", "resizableColumns", "lazy", "totalRecords", "paginator", "first", "rows", "rowsPerPageOptions", "showCurrentPageReport", "currentPageReportTemplate", "globalFilterFields", "filterDelay", "selectionMode", "sortMode", "virtualScroll", "virtualScrollItemSize", "sortField", "sortOrder", "multiSortMeta", "filters", "selection", "contextMenuSelection"], outputs: ["sortFieldChange", "sortOrderChange", "multiSortMetaChange", "filtersChange", "selectionChange", "contextMenuSelectionChange", "onLazyLoad", "onSort", "onFilter", "onNodeExpand", "onNodeCollapse", "onNodeSelect", "onNodeUnselect", "onRowContextMenu"] }, { kind: "component", type: i2.TreeTableTogglerComponent, selector: "f-treetabletoggler", inputs: ["rowNode"] }, { kind: "component", type: i2.UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill", "severity"] }, { 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: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
2704
+ `, isInline: true, styles: [":host{display:block}.empty-state-icon{width:3rem;height:3rem;border-radius:9999px;display:flex;align-items:center;justify-content:center;background-color:var(--f-primary-50, rgba(59, 130, 246, .08))}:host-context(.app-dark) .empty-state-icon{background-color:#60a5fa1f}.validation-warning{background-color:var(--f-yellow-50, #fefce8);border-left:4px solid var(--f-yellow-500, #eab308);color:var(--f-yellow-700, #a16207)}:host-context(.app-dark) .validation-warning{background-color:#eab3081a;color:var(--f-yellow-400, #facc15)}:host ::ng-deep tr.highlight-warning{background-color:var(--f-red-50, rgba(239, 68, 68, .1))!important}:host-context(.app-dark) ::ng-deep tr.highlight-warning{background-color:#ef444426!important}\n"], dependencies: [{ kind: "component", type: CheckboxComponent, selector: "f-checkbox", inputs: ["label", "binary", "disabled", "readonly", "inputId", "invalid", "indeterminate", "variant", "size", "touched", "styleClass", "style", "checked"], outputs: ["onChange", "onBlur", "touch", "checkedChange"] }, { kind: "directive", type: FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "variant", "rounded", "raised", "fluid", "disabled", "loading", "loadingIcon", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: SelectComponent, selector: "f-select", inputs: ["options", "optionLabel", "optionValue", "placeholder", "disabled", "filter", "filterBy", "filterMatchMode", "filterLocale", "filterPlaceholder", "resetFilterOnHide", "autofocusFilter", "emptyMessage", "emptyFilterMessage", "showClear", "loading", "loadingIcon", "dropdownIcon", "clearIcon", "inputId", "invalid", "touched", "styleClass", "style", "appendTo", "editable", "readonly", "autofocus", "checkmark", "group", "optionGroupLabel", "optionGroupChildren", "virtualScroll", "virtualScrollItemSize", "lazy"], outputs: ["onFilter", "onChange", "onShow", "onHide", "onBlur", "onFocus", "onClear", "onLazyLoad"] }, { kind: "component", type: TagComponent, selector: "f-tag", inputs: ["value", "severity", "icon", "rounded", "color", "styleClass", "style"] }, { kind: "directive", type: TooltipDirective, selector: "[fTooltip]", inputs: ["fTooltip", "tooltipPosition", "positionStyle", "tooltipStyleClass", "disabled", "tooltipEvent", "showDelay", "hideDelay", "life", "autoHide", "positionTop", "positionLeft", "escape"] }, { kind: "component", type: TreeTableComponent, selector: "f-treetable", inputs: ["value", "loading", "dataKey", "styleClass", "tableStyle", "scrollable", "scrollHeight", "resizableColumns", "lazy", "totalRecords", "paginator", "first", "rows", "rowsPerPageOptions", "showCurrentPageReport", "currentPageReportTemplate", "globalFilterFields", "filterDelay", "selectionMode", "sortMode", "virtualScroll", "virtualScrollItemSize", "sortField", "sortOrder", "multiSortMeta", "filters", "selection", "contextMenuSelection"], outputs: ["sortFieldChange", "sortOrderChange", "multiSortMetaChange", "filtersChange", "selectionChange", "contextMenuSelectionChange", "onLazyLoad", "onSort", "onFilter", "onNodeExpand", "onNodeCollapse", "onNodeSelect", "onNodeUnselect", "onRowContextMenu"] }, { kind: "component", type: TreeTableTogglerComponent, selector: "f-treetabletoggler", inputs: ["rowNode"] }, { kind: "component", type: UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill", "severity"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
2694
2705
  }
2695
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: CompanyActionSelectorComponent, decorators: [{
2706
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: CompanyActionSelectorComponent, decorators: [{
2696
2707
  type: Component,
2697
- args: [{ selector: 'flusys-company-action-selector', imports: [UiModule, FormsModule, HasPermissionDirective, TranslatePipe], template: `
2708
+ args: [{ selector: 'flusys-company-action-selector', imports: [
2709
+ CheckboxComponent,
2710
+ FButtonDirective,
2711
+ SelectComponent,
2712
+ TagComponent,
2713
+ TooltipDirective,
2714
+ TreeTableComponent,
2715
+ TreeTableTogglerComponent,
2716
+ UiIconComponent,
2717
+ FormsModule,
2718
+ HasPermissionDirective,
2719
+ TranslatePipe,
2720
+ ], template: `
2698
2721
  <div class="company-action-selector">
2699
2722
  <div class="surface-card p-4 rounded-border mb-4 shadow-sm">
2700
2723
  <div class="grid grid-cols-1 sm:grid-cols-2 gap-5">
@@ -2965,38 +2988,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
2965
2988
  }], ctorParameters: () => [], propDecorators: { companySelectRef: [{ type: i0.ViewChild, args: ['companySelect', { isSignal: true }] }] } });
2966
2989
 
2967
2990
  /**
2968
- * User-Role Selector Component
2969
- *
2970
- * Manages user role assignments with branch-level granularity.
2971
- *
2972
- * **Architecture:**
2973
- * - Presentation: DataTable for role list
2974
- * - Business Logic: Role assignment without dependency validation
2975
- * - State: Signals with computed dependencies
2976
- *
2977
- * **Core Features:**
2978
- * - User dropdown with async loading
2979
- * - Branch selector (if company feature enabled)
2980
- * - Role assignment management (add/remove)
2981
- * - Real-time change tracking
2982
- *
2983
- * **Granularity:**
2984
- * - Company-wide: branchId = undefined
2985
- * - Branch-specific: branchId = selected value
2986
- *
2987
- * **Performance:**
2988
- * - Computed signals for reactive updates
2989
- * - Branch filtering on company context change
2990
- *
2991
- * @example
2992
- * ```html
2993
- * <flusys-user-role-selector />
2994
- * ```
2991
+ * Manages user role assignments with branch-level granularity:
2992
+ * `branchId === undefined` means a company-wide assignment, a set value
2993
+ * scopes the assignment to that specific branch.
2995
2994
  */
2996
2995
  class UserRoleSelectorComponent {
2997
- // Permission constants for template
2998
2996
  USER_ROLE_PERMISSIONS = USER_ROLE_PERMISSIONS;
2999
- // Dependencies
3000
2997
  appConfig = inject(APP_CONFIG);
3001
2998
  companyContext = inject(LAYOUT_AUTH_STATE);
3002
2999
  userPermissionProvider = inject(USER_PERMISSION_PROVIDER);
@@ -3030,30 +3027,25 @@ class UserRoleSelectorComponent {
3030
3027
  }
3031
3028
  this.selectedUserId.set(userId);
3032
3029
  }
3033
- // State - User/Branch Selection
3034
3030
  selectedUserId = signal(null, /* @ts-ignore */
3035
3031
  ...(ngDevMode ? [{ debugName: "selectedUserId" }] : /* istanbul ignore next */ []));
3036
3032
  selectedBranchId = signal(undefined, /* @ts-ignore */
3037
3033
  ...(ngDevMode ? [{ debugName: "selectedBranchId" }] : /* istanbul ignore next */ []));
3038
3034
  branches = signal([], /* @ts-ignore */
3039
3035
  ...(ngDevMode ? [{ debugName: "branches" }] : /* istanbul ignore next */ []));
3040
- // State - Loading/Saving
3041
3036
  loading = signal(false, /* @ts-ignore */
3042
3037
  ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
3043
3038
  saving = signal(false, /* @ts-ignore */
3044
3039
  ...(ngDevMode ? [{ debugName: "saving" }] : /* istanbul ignore next */ []));
3045
- // State - Roles (Business Logic)
3046
3040
  _roles = signal([], /* @ts-ignore */
3047
3041
  ...(ngDevMode ? [{ debugName: "_roles" }] : /* istanbul ignore next */ []));
3048
3042
  roles = this._roles.asReadonly();
3049
- // State - Selection
3050
3043
  _selectionMap = signal({}, /* @ts-ignore */
3051
3044
  ...(ngDevMode ? [{ debugName: "_selectionMap" }] : /* istanbul ignore next */ []));
3052
3045
  selectionMap = this._selectionMap.asReadonly();
3053
3046
  _initialSelection = signal({}, /* @ts-ignore */
3054
3047
  ...(ngDevMode ? [{ debugName: "_initialSelection" }] : /* istanbul ignore next */ []));
3055
3048
  initialSelection = this._initialSelection.asReadonly();
3056
- // Computed - UI Flags
3057
3049
  showBranchSelector = computed(() => isCompanyFeatureEnabled(this.appConfig) === true, /* @ts-ignore */
3058
3050
  ...(ngDevMode ? [{ debugName: "showBranchSelector" }] : /* istanbul ignore next */ []));
3059
3051
  filteredBranches = computed(() => {
@@ -3063,7 +3055,6 @@ class UserRoleSelectorComponent {
3063
3055
  return this.branches().filter((b) => b.companyId === currentCompanyId);
3064
3056
  }, /* @ts-ignore */
3065
3057
  ...(ngDevMode ? [{ debugName: "filteredBranches" }] : /* istanbul ignore next */ []));
3066
- // Computed - Selection State
3067
3058
  allSelected = computed(() => {
3068
3059
  const selMap = this.selectionMap();
3069
3060
  const total = this.roles().length;
@@ -3073,7 +3064,6 @@ class UserRoleSelectorComponent {
3073
3064
  return selected === total;
3074
3065
  }, /* @ts-ignore */
3075
3066
  ...(ngDevMode ? [{ debugName: "allSelected" }] : /* istanbul ignore next */ []));
3076
- // Computed - Change Detection
3077
3067
  hasChanges = computed(() => {
3078
3068
  const current = this.selectionMap();
3079
3069
  const initial = this.initialSelection();
@@ -3084,7 +3074,6 @@ class UserRoleSelectorComponent {
3084
3074
  return currentKeys.some((key) => current[key] !== initial[key]);
3085
3075
  }, /* @ts-ignore */
3086
3076
  ...(ngDevMode ? [{ debugName: "hasChanges" }] : /* istanbul ignore next */ []));
3087
- // Computed - Pending Changes
3088
3077
  pendingAdd = computed(() => {
3089
3078
  const current = this.selectionMap();
3090
3079
  const initial = this.initialSelection();
@@ -3099,13 +3088,11 @@ class UserRoleSelectorComponent {
3099
3088
  return allRoles.filter((role) => !current[role.id] && initial[role.id]);
3100
3089
  }, /* @ts-ignore */
3101
3090
  ...(ngDevMode ? [{ debugName: "pendingRemove" }] : /* istanbul ignore next */ []));
3102
- // Computed - Save Button State
3103
3091
  canSave = computed(() => {
3104
3092
  return this.hasChanges() && !this.saving();
3105
3093
  }, /* @ts-ignore */
3106
3094
  ...(ngDevMode ? [{ debugName: "canSave" }] : /* istanbul ignore next */ []));
3107
3095
  constructor() {
3108
- // Effect: Load user branches and data when user changes
3109
3096
  effect(() => {
3110
3097
  const userId = this.selectedUserId();
3111
3098
  if (userId) {
@@ -3120,7 +3107,6 @@ class UserRoleSelectorComponent {
3120
3107
  this.resetState();
3121
3108
  }
3122
3109
  });
3123
- // Effect: Reload data when branch changes
3124
3110
  effect(() => {
3125
3111
  const userId = this.selectedUserId();
3126
3112
  const branchId = this.selectedBranchId();
@@ -3131,9 +3117,6 @@ class UserRoleSelectorComponent {
3131
3117
  }
3132
3118
  });
3133
3119
  }
3134
- /**
3135
- * Load user's permitted branches
3136
- */
3137
3120
  async loadUserBranches(userId) {
3138
3121
  try {
3139
3122
  const companyId = this.companyContext.currentCompanyInfo()?.id || undefined;
@@ -3153,9 +3136,6 @@ class UserRoleSelectorComponent {
3153
3136
  // Error toast handled by global interceptor
3154
3137
  }
3155
3138
  }
3156
- /**
3157
- * Load roles and assignments for selected user
3158
- */
3159
3139
  async loadData() {
3160
3140
  const userId = this.selectedUserId();
3161
3141
  if (!userId)
@@ -3163,19 +3143,16 @@ class UserRoleSelectorComponent {
3163
3143
  const branchId = this.selectedBranchId();
3164
3144
  this.loading.set(true);
3165
3145
  try {
3166
- // Load all roles
3167
3146
  const rolesResponse = await this.roleApi.getAll({
3168
3147
  pagination: { currentPage: 0, pageSize: MAX_DROPDOWN_ITEMS },
3169
3148
  });
3170
3149
  const rolesList = rolesResponse?.data ?? [];
3171
3150
  this._roles.set(rolesList);
3172
- // Load existing user-role assignments
3173
3151
  const query = isCompanyFeatureEnabled(this.appConfig) && branchId
3174
3152
  ? { branchId }
3175
3153
  : undefined;
3176
3154
  const assignedResponse = await firstValueFrom(this.permissionApi.getUserRoles(userId, query));
3177
3155
  const assignedIds = new Set((assignedResponse?.data || []).map((r) => r.roleId));
3178
- // Build selection map
3179
3156
  const selMap = {};
3180
3157
  rolesList.forEach((role) => {
3181
3158
  selMap[role.id] = assignedIds.has(role.id);
@@ -3190,9 +3167,6 @@ class UserRoleSelectorComponent {
3190
3167
  this.loading.set(false);
3191
3168
  }
3192
3169
  }
3193
- /**
3194
- * Get tooltip for role checkbox
3195
- */
3196
3170
  getTooltip(role) {
3197
3171
  const selMap = this.selectionMap();
3198
3172
  const isCurrentlySelected = selMap[role.id];
@@ -3201,23 +3175,14 @@ class UserRoleSelectorComponent {
3201
3175
  }
3202
3176
  return `[${this.translate('shared.add')}] ${this.translate('iam.tooltip.click.to.assign.role.to.user')}`;
3203
3177
  }
3204
- /**
3205
- * Handle role checkbox toggle
3206
- */
3207
3178
  onRoleToggle(role, newValue) {
3208
3179
  const selMap = { ...this.selectionMap() };
3209
3180
  selMap[role.id] = newValue;
3210
3181
  this._selectionMap.set(selMap);
3211
3182
  }
3212
- /**
3213
- * Toggle all roles
3214
- */
3215
3183
  toggleAll() {
3216
3184
  this.setAllSelections(!this.allSelected());
3217
3185
  }
3218
- /**
3219
- * Set all role selections to a given value
3220
- */
3221
3186
  setAllSelections(value) {
3222
3187
  const selMap = {};
3223
3188
  this.roles().forEach((role) => {
@@ -3225,16 +3190,12 @@ class UserRoleSelectorComponent {
3225
3190
  });
3226
3191
  this._selectionMap.set(selMap);
3227
3192
  }
3228
- /**
3229
- * Save changes to backend
3230
- */
3231
3193
  async saveChanges() {
3232
3194
  const userId = this.selectedUserId();
3233
3195
  if (!userId)
3234
3196
  return;
3235
3197
  const branchId = this.selectedBranchId();
3236
3198
  const companyId = this.companyContext.currentCompanyInfo()?.id || undefined;
3237
- // Validate company context if feature enabled
3238
3199
  if (isCompanyFeatureEnabled(this.appConfig) && !companyId) {
3239
3200
  this.messageService.add({
3240
3201
  severity: 'warn',
@@ -3243,7 +3204,6 @@ class UserRoleSelectorComponent {
3243
3204
  });
3244
3205
  return;
3245
3206
  }
3246
- // Build payload
3247
3207
  const items = [];
3248
3208
  this.pendingAdd().forEach((role) => {
3249
3209
  items.push({ id: role.id, action: 'add' });
@@ -3272,7 +3232,6 @@ class UserRoleSelectorComponent {
3272
3232
  ? this.translate(response.messageKey, response.messageVariables)
3273
3233
  : response?.message,
3274
3234
  });
3275
- // Update baseline
3276
3235
  this._initialSelection.set({ ...this.selectionMap() });
3277
3236
  }
3278
3237
  catch {
@@ -3282,16 +3241,13 @@ class UserRoleSelectorComponent {
3282
3241
  this.saving.set(false);
3283
3242
  }
3284
3243
  }
3285
- /**
3286
- * Reset component state
3287
- */
3288
3244
  resetState() {
3289
3245
  this._roles.set([]);
3290
3246
  this._selectionMap.set({});
3291
3247
  this._initialSelection.set({});
3292
3248
  }
3293
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: UserRoleSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3294
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: UserRoleSelectorComponent, isStandalone: true, selector: "flusys-user-role-selector", viewQueries: [{ propertyName: "userSelectRef", first: true, predicate: ["userSelect"], descendants: true, isSignal: true }], ngImport: i0, template: `
3249
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: UserRoleSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3250
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: UserRoleSelectorComponent, isStandalone: true, selector: "flusys-user-role-selector", viewQueries: [{ propertyName: "userSelectRef", first: true, predicate: ["userSelect"], descendants: true, isSignal: true }], ngImport: i0, template: `
3295
3251
  <div class="user-role-selector">
3296
3252
  <!-- User and Branch Selectors -->
3297
3253
  <div class="surface-card p-4 rounded-border mb-4 shadow-sm">
@@ -3565,14 +3521,18 @@ class UserRoleSelectorComponent {
3565
3521
  }
3566
3522
  }
3567
3523
  </div>
3568
- `, isInline: true, styles: [":host{display:block}.empty-state-icon{width:3rem;height:3rem;border-radius:9999px;display:flex;align-items:center;justify-content:center;background-color:var(--f-primary-50, rgba(59, 130, 246, .08))}:host-context(.app-dark) .empty-state-icon{background-color:#60a5fa1f}\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: UiModule }, { kind: "directive", type: i2.FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "variant", "rounded", "raised", "fluid", "disabled", "loading", "loadingIcon", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: i2.CheckboxComponent, selector: "f-checkbox", inputs: ["label", "binary", "disabled", "readonly", "inputId", "invalid", "indeterminate", "variant", "size", "touched", "styleClass", "style", "checked"], outputs: ["onChange", "onBlur", "touch", "checkedChange"] }, { kind: "component", type: i2.SelectComponent, selector: "f-select", inputs: ["options", "optionLabel", "optionValue", "placeholder", "disabled", "filter", "filterBy", "filterMatchMode", "filterLocale", "filterPlaceholder", "resetFilterOnHide", "autofocusFilter", "emptyMessage", "emptyFilterMessage", "showClear", "loading", "loadingIcon", "dropdownIcon", "clearIcon", "inputId", "invalid", "touched", "styleClass", "style", "appendTo", "editable", "readonly", "autofocus", "checkmark", "group", "optionGroupLabel", "optionGroupChildren", "virtualScroll", "virtualScrollItemSize", "lazy"], outputs: ["onFilter", "onChange", "onShow", "onHide", "onBlur", "onFocus", "onClear", "onLazyLoad"] }, { kind: "component", type: i2.TableComponent, selector: "f-table", inputs: ["value", "lazy", "loading", "rows", "totalRecords", "rowHover", "dataKey", "scrollable", "scrollHeight", "paginator", "first", "rowsPerPageOptions", "showCurrentPageReport", "currentPageReportTemplate", "tableStyle", "styleClass", "globalFilterFields", "filterDelay", "responsiveLayout", "selectionMode", "sortMode", "rowExpandMode", "resizableColumns", "rowStyleClass", "virtualScroll", "virtualScrollItemSize", "sortField", "sortOrder", "multiSortMeta", "filters", "selection", "expandedRowKeys", "contextMenuSelection"], outputs: ["sortFieldChange", "sortOrderChange", "multiSortMetaChange", "filtersChange", "selectionChange", "expandedRowKeysChange", "contextMenuSelectionChange", "onLazyLoad", "onSort", "onFilter", "onRowSelect", "onRowUnselect", "onSelectAllChange", "onRowExpand", "onRowCollapse", "onColResize", "onRowContextMenu"] }, { kind: "directive", type: i2.TooltipDirective, selector: "[fTooltip]", inputs: ["fTooltip", "tooltipPosition", "positionStyle", "tooltipStyleClass", "disabled", "tooltipEvent", "showDelay", "hideDelay", "life", "autoHide", "positionTop", "positionLeft", "escape"] }, { kind: "component", type: i2.UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill", "severity"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "component", type: UserSelectComponent, selector: "lib-user-select", inputs: ["showClear", "value"], outputs: ["valueChange", "userSelected"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
3524
+ `, isInline: true, styles: [":host{display:block}.empty-state-icon{width:3rem;height:3rem;border-radius:9999px;display:flex;align-items:center;justify-content:center;background-color:var(--f-primary-50, rgba(59, 130, 246, .08))}:host-context(.app-dark) .empty-state-icon{background-color:#60a5fa1f}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CheckboxComponent, selector: "f-checkbox", inputs: ["label", "binary", "disabled", "readonly", "inputId", "invalid", "indeterminate", "variant", "size", "touched", "styleClass", "style", "checked"], outputs: ["onChange", "onBlur", "touch", "checkedChange"] }, { kind: "directive", type: FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "variant", "rounded", "raised", "fluid", "disabled", "loading", "loadingIcon", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: SelectComponent, selector: "f-select", inputs: ["options", "optionLabel", "optionValue", "placeholder", "disabled", "filter", "filterBy", "filterMatchMode", "filterLocale", "filterPlaceholder", "resetFilterOnHide", "autofocusFilter", "emptyMessage", "emptyFilterMessage", "showClear", "loading", "loadingIcon", "dropdownIcon", "clearIcon", "inputId", "invalid", "touched", "styleClass", "style", "appendTo", "editable", "readonly", "autofocus", "checkmark", "group", "optionGroupLabel", "optionGroupChildren", "virtualScroll", "virtualScrollItemSize", "lazy"], outputs: ["onFilter", "onChange", "onShow", "onHide", "onBlur", "onFocus", "onClear", "onLazyLoad"] }, { kind: "component", type: TableComponent, selector: "f-table", inputs: ["value", "lazy", "loading", "rows", "totalRecords", "rowHover", "dataKey", "scrollable", "scrollHeight", "paginator", "first", "rowsPerPageOptions", "showCurrentPageReport", "currentPageReportTemplate", "tableStyle", "styleClass", "globalFilterFields", "filterDelay", "responsiveLayout", "selectionMode", "sortMode", "rowExpandMode", "resizableColumns", "rowStyleClass", "virtualScroll", "virtualScrollItemSize", "sortField", "sortOrder", "multiSortMeta", "filters", "selection", "expandedRowKeys", "contextMenuSelection"], outputs: ["sortFieldChange", "sortOrderChange", "multiSortMetaChange", "filtersChange", "selectionChange", "expandedRowKeysChange", "contextMenuSelectionChange", "onLazyLoad", "onSort", "onFilter", "onRowSelect", "onRowUnselect", "onSelectAllChange", "onRowExpand", "onRowCollapse", "onColResize", "onRowContextMenu"] }, { kind: "directive", type: TooltipDirective, selector: "[fTooltip]", inputs: ["fTooltip", "tooltipPosition", "positionStyle", "tooltipStyleClass", "disabled", "tooltipEvent", "showDelay", "hideDelay", "life", "autoHide", "positionTop", "positionLeft", "escape"] }, { kind: "component", type: UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill", "severity"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "component", type: UserSelectComponent, selector: "lib-user-select", inputs: ["showClear", "value"], outputs: ["valueChange", "userSelected"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
3569
3525
  }
3570
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: UserRoleSelectorComponent, decorators: [{
3526
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: UserRoleSelectorComponent, decorators: [{
3571
3527
  type: Component,
3572
3528
  args: [{ selector: 'flusys-user-role-selector', imports: [
3573
- CommonModule,
3574
3529
  FormsModule,
3575
- UiModule,
3530
+ CheckboxComponent,
3531
+ FButtonDirective,
3532
+ SelectComponent,
3533
+ TableComponent,
3534
+ TooltipDirective,
3535
+ UiIconComponent,
3576
3536
  HasPermissionDirective,
3577
3537
  UserSelectComponent,
3578
3538
  TranslatePipe,
@@ -4066,8 +4026,8 @@ class UserActionSelectorComponent extends BaseActionSelectorComponent {
4066
4026
  this.saving.set(false);
4067
4027
  }
4068
4028
  }
4069
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: UserActionSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4070
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: UserActionSelectorComponent, isStandalone: true, selector: "flusys-user-action-selector", viewQueries: [{ propertyName: "userSelectRef", first: true, predicate: ["userSelect"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
4029
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: UserActionSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4030
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: UserActionSelectorComponent, isStandalone: true, selector: "flusys-user-action-selector", viewQueries: [{ propertyName: "userSelectRef", first: true, predicate: ["userSelect"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
4071
4031
  <div class="user-action-selector">
4072
4032
  <div class="surface-card p-4 rounded-border mb-4 shadow-sm">
4073
4033
  <div
@@ -4398,13 +4358,20 @@ class UserActionSelectorComponent extends BaseActionSelectorComponent {
4398
4358
  }
4399
4359
  }
4400
4360
  </div>
4401
- `, isInline: true, styles: [":host{display:block}.empty-state-icon{width:3rem;height:3rem;border-radius:9999px;display:flex;align-items:center;justify-content:center;background-color:var(--f-primary-50, rgba(59, 130, 246, .08))}:host-context(.app-dark) .empty-state-icon{background-color:#60a5fa1f}.validation-warning{background-color:var(--f-yellow-50, #fefce8);border-left:4px solid var(--f-yellow-500, #eab308);color:var(--f-yellow-700, #a16207)}:host-context(.app-dark) .validation-warning{background-color:#eab3081a;color:var(--f-yellow-400, #facc15)}:host ::ng-deep tr.highlight-warning{background-color:var(--f-red-50, rgba(239, 68, 68, .1))!important}:host-context(.app-dark) ::ng-deep tr.highlight-warning{background-color:#ef444426!important}\n"], dependencies: [{ 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: UiModule }, { kind: "directive", type: i2.FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "variant", "rounded", "raised", "fluid", "disabled", "loading", "loadingIcon", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: i2.TagComponent, selector: "f-tag", inputs: ["value", "severity", "icon", "rounded", "color", "styleClass", "style"] }, { kind: "component", type: i2.CheckboxComponent, selector: "f-checkbox", inputs: ["label", "binary", "disabled", "readonly", "inputId", "invalid", "indeterminate", "variant", "size", "touched", "styleClass", "style", "checked"], outputs: ["onChange", "onBlur", "touch", "checkedChange"] }, { kind: "component", type: i2.SelectComponent, selector: "f-select", inputs: ["options", "optionLabel", "optionValue", "placeholder", "disabled", "filter", "filterBy", "filterMatchMode", "filterLocale", "filterPlaceholder", "resetFilterOnHide", "autofocusFilter", "emptyMessage", "emptyFilterMessage", "showClear", "loading", "loadingIcon", "dropdownIcon", "clearIcon", "inputId", "invalid", "touched", "styleClass", "style", "appendTo", "editable", "readonly", "autofocus", "checkmark", "group", "optionGroupLabel", "optionGroupChildren", "virtualScroll", "virtualScrollItemSize", "lazy"], outputs: ["onFilter", "onChange", "onShow", "onHide", "onBlur", "onFocus", "onClear", "onLazyLoad"] }, { kind: "directive", type: i2.TooltipDirective, selector: "[fTooltip]", inputs: ["fTooltip", "tooltipPosition", "positionStyle", "tooltipStyleClass", "disabled", "tooltipEvent", "showDelay", "hideDelay", "life", "autoHide", "positionTop", "positionLeft", "escape"] }, { kind: "component", type: i2.TreeTableComponent, selector: "f-treetable", inputs: ["value", "loading", "dataKey", "styleClass", "tableStyle", "scrollable", "scrollHeight", "resizableColumns", "lazy", "totalRecords", "paginator", "first", "rows", "rowsPerPageOptions", "showCurrentPageReport", "currentPageReportTemplate", "globalFilterFields", "filterDelay", "selectionMode", "sortMode", "virtualScroll", "virtualScrollItemSize", "sortField", "sortOrder", "multiSortMeta", "filters", "selection", "contextMenuSelection"], outputs: ["sortFieldChange", "sortOrderChange", "multiSortMetaChange", "filtersChange", "selectionChange", "contextMenuSelectionChange", "onLazyLoad", "onSort", "onFilter", "onNodeExpand", "onNodeCollapse", "onNodeSelect", "onNodeUnselect", "onRowContextMenu"] }, { kind: "component", type: i2.TreeTableTogglerComponent, selector: "f-treetabletoggler", inputs: ["rowNode"] }, { kind: "component", type: i2.UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill", "severity"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "component", type: UserSelectComponent, selector: "lib-user-select", inputs: ["showClear", "value"], outputs: ["valueChange", "userSelected"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
4361
+ `, isInline: true, styles: [":host{display:block}.empty-state-icon{width:3rem;height:3rem;border-radius:9999px;display:flex;align-items:center;justify-content:center;background-color:var(--f-primary-50, rgba(59, 130, 246, .08))}:host-context(.app-dark) .empty-state-icon{background-color:#60a5fa1f}.validation-warning{background-color:var(--f-yellow-50, #fefce8);border-left:4px solid var(--f-yellow-500, #eab308);color:var(--f-yellow-700, #a16207)}:host-context(.app-dark) .validation-warning{background-color:#eab3081a;color:var(--f-yellow-400, #facc15)}:host ::ng-deep tr.highlight-warning{background-color:var(--f-red-50, rgba(239, 68, 68, .1))!important}:host-context(.app-dark) ::ng-deep tr.highlight-warning{background-color:#ef444426!important}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CheckboxComponent, selector: "f-checkbox", inputs: ["label", "binary", "disabled", "readonly", "inputId", "invalid", "indeterminate", "variant", "size", "touched", "styleClass", "style", "checked"], outputs: ["onChange", "onBlur", "touch", "checkedChange"] }, { kind: "directive", type: FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "variant", "rounded", "raised", "fluid", "disabled", "loading", "loadingIcon", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: SelectComponent, selector: "f-select", inputs: ["options", "optionLabel", "optionValue", "placeholder", "disabled", "filter", "filterBy", "filterMatchMode", "filterLocale", "filterPlaceholder", "resetFilterOnHide", "autofocusFilter", "emptyMessage", "emptyFilterMessage", "showClear", "loading", "loadingIcon", "dropdownIcon", "clearIcon", "inputId", "invalid", "touched", "styleClass", "style", "appendTo", "editable", "readonly", "autofocus", "checkmark", "group", "optionGroupLabel", "optionGroupChildren", "virtualScroll", "virtualScrollItemSize", "lazy"], outputs: ["onFilter", "onChange", "onShow", "onHide", "onBlur", "onFocus", "onClear", "onLazyLoad"] }, { kind: "component", type: TagComponent, selector: "f-tag", inputs: ["value", "severity", "icon", "rounded", "color", "styleClass", "style"] }, { kind: "directive", type: TooltipDirective, selector: "[fTooltip]", inputs: ["fTooltip", "tooltipPosition", "positionStyle", "tooltipStyleClass", "disabled", "tooltipEvent", "showDelay", "hideDelay", "life", "autoHide", "positionTop", "positionLeft", "escape"] }, { kind: "component", type: TreeTableComponent, selector: "f-treetable", inputs: ["value", "loading", "dataKey", "styleClass", "tableStyle", "scrollable", "scrollHeight", "resizableColumns", "lazy", "totalRecords", "paginator", "first", "rows", "rowsPerPageOptions", "showCurrentPageReport", "currentPageReportTemplate", "globalFilterFields", "filterDelay", "selectionMode", "sortMode", "virtualScroll", "virtualScrollItemSize", "sortField", "sortOrder", "multiSortMeta", "filters", "selection", "contextMenuSelection"], outputs: ["sortFieldChange", "sortOrderChange", "multiSortMetaChange", "filtersChange", "selectionChange", "contextMenuSelectionChange", "onLazyLoad", "onSort", "onFilter", "onNodeExpand", "onNodeCollapse", "onNodeSelect", "onNodeUnselect", "onRowContextMenu"] }, { kind: "component", type: TreeTableTogglerComponent, selector: "f-treetabletoggler", inputs: ["rowNode"] }, { kind: "component", type: UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill", "severity"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "component", type: UserSelectComponent, selector: "lib-user-select", inputs: ["showClear", "value"], outputs: ["valueChange", "userSelected"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
4402
4362
  }
4403
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: UserActionSelectorComponent, decorators: [{
4363
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: UserActionSelectorComponent, decorators: [{
4404
4364
  type: Component,
4405
4365
  args: [{ selector: 'flusys-user-action-selector', imports: [
4406
4366
  FormsModule,
4407
- UiModule,
4367
+ CheckboxComponent,
4368
+ FButtonDirective,
4369
+ SelectComponent,
4370
+ TagComponent,
4371
+ TooltipDirective,
4372
+ TreeTableComponent,
4373
+ TreeTableTogglerComponent,
4374
+ UiIconComponent,
4408
4375
  HasPermissionDirective,
4409
4376
  UserSelectComponent,
4410
4377
  TranslatePipe,
@@ -4742,6 +4709,530 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
4742
4709
  `, styles: [":host{display:block}.empty-state-icon{width:3rem;height:3rem;border-radius:9999px;display:flex;align-items:center;justify-content:center;background-color:var(--f-primary-50, rgba(59, 130, 246, .08))}:host-context(.app-dark) .empty-state-icon{background-color:#60a5fa1f}.validation-warning{background-color:var(--f-yellow-50, #fefce8);border-left:4px solid var(--f-yellow-500, #eab308);color:var(--f-yellow-700, #a16207)}:host-context(.app-dark) .validation-warning{background-color:#eab3081a;color:var(--f-yellow-400, #facc15)}:host ::ng-deep tr.highlight-warning{background-color:var(--f-red-50, rgba(239, 68, 68, .1))!important}:host-context(.app-dark) ::ng-deep tr.highlight-warning{background-color:#ef444426!important}\n"] }]
4743
4710
  }], ctorParameters: () => [], propDecorators: { userSelectRef: [{ type: i0.ViewChild, args: ['userSelect', { isSignal: true }] }] } });
4744
4711
 
4712
+ /**
4713
+ * Read-only viewer for users assigned to a role, with a remove-only action
4714
+ * per user. Assigning new users stays on the user-centric
4715
+ * `UserRoleSelectorComponent` flow — this dialog intentionally has no "add"
4716
+ * affordance. Since IAM stays independent of the auth package, user display
4717
+ * info is resolved via the `USER_PROVIDER` injection token rather than a
4718
+ * direct join.
4719
+ */
4720
+ class RolePermittedUsersDialogComponent {
4721
+ USER_ROLE_PERMISSIONS = USER_ROLE_PERMISSIONS;
4722
+ permissionApi = inject(PermissionApiService);
4723
+ userProvider = inject(USER_PROVIDER);
4724
+ confirmationService = inject(ConfirmationService);
4725
+ messageService = inject(MessageService);
4726
+ translateAdapter = inject(TranslateService, {
4727
+ optional: true,
4728
+ });
4729
+ t(key, params) {
4730
+ return this.translateAdapter?.translate(key, params) ?? key;
4731
+ }
4732
+ visible = input.required(/* @ts-ignore */
4733
+ ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
4734
+ role = input.required(/* @ts-ignore */
4735
+ ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
4736
+ closed = output();
4737
+ isLoading = signal(false, /* @ts-ignore */
4738
+ ...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
4739
+ isRemoving = signal(false, /* @ts-ignore */
4740
+ ...(ngDevMode ? [{ debugName: "isRemoving" }] : /* istanbul ignore next */ []));
4741
+ users = signal([], /* @ts-ignore */
4742
+ ...(ngDevMode ? [{ debugName: "users" }] : /* istanbul ignore next */ []));
4743
+ constructor() {
4744
+ effect(() => {
4745
+ if (this.visible() && this.role()) {
4746
+ this.loadUsers();
4747
+ }
4748
+ });
4749
+ }
4750
+ async loadUsers() {
4751
+ const role = this.role();
4752
+ if (!role)
4753
+ return;
4754
+ this.isLoading.set(true);
4755
+ try {
4756
+ const response = await firstValueFrom(this.permissionApi.getRoleUsers(role.id));
4757
+ const rows = response.data ?? [];
4758
+ const userIds = rows.map((r) => r.userId);
4759
+ const userInfoMap = await this.resolveUserInfo(userIds);
4760
+ this.users.set(rows.map((r) => {
4761
+ const info = userInfoMap.get(r.userId);
4762
+ return {
4763
+ id: r.id,
4764
+ userId: r.userId,
4765
+ userName: info?.name ?? r.userId,
4766
+ userEmail: info?.email ?? '',
4767
+ };
4768
+ }));
4769
+ }
4770
+ catch {
4771
+ // Error toast handled by global interceptor
4772
+ }
4773
+ finally {
4774
+ this.isLoading.set(false);
4775
+ }
4776
+ }
4777
+ async resolveUserInfo(userIds) {
4778
+ if (userIds.length === 0 || !this.userProvider.getUsersByIds) {
4779
+ return new Map();
4780
+ }
4781
+ try {
4782
+ const response = await firstValueFrom(this.userProvider.getUsersByIds(userIds));
4783
+ return new Map((response.data ?? []).map((u) => [u.id, u]));
4784
+ }
4785
+ catch {
4786
+ return new Map();
4787
+ }
4788
+ }
4789
+ onRemove(user) {
4790
+ const role = this.role();
4791
+ if (!role)
4792
+ return;
4793
+ this.confirmationService.confirm({
4794
+ message: this.t('iam.permission.remove.confirm', { name: user.userName }),
4795
+ header: this.t('iam.permission.remove'),
4796
+ icon: 'exclamation-triangle',
4797
+ acceptButtonStyleClass: 'p-button-danger',
4798
+ accept: async () => {
4799
+ this.isRemoving.set(true);
4800
+ try {
4801
+ const response = await firstValueFrom(this.permissionApi.assignUserRoles({
4802
+ userId: user.userId,
4803
+ items: [{ id: role.id, action: 'remove' }],
4804
+ }));
4805
+ if (response.success) {
4806
+ this.users.update((list) => list.filter((u) => u.id !== user.id));
4807
+ this.messageService.add({
4808
+ severity: 'success',
4809
+ summary: this.t('shared.success'),
4810
+ detail: response?.messageKey
4811
+ ? this.t(response.messageKey, response.messageVariables)
4812
+ : (response?.message ?? ''),
4813
+ });
4814
+ }
4815
+ }
4816
+ catch {
4817
+ // Error toast handled by global interceptor
4818
+ }
4819
+ finally {
4820
+ this.isRemoving.set(false);
4821
+ }
4822
+ },
4823
+ });
4824
+ }
4825
+ onClose() {
4826
+ this.closed.emit();
4827
+ }
4828
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: RolePermittedUsersDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4829
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: RolePermittedUsersDialogComponent, isStandalone: true, selector: "flusys-role-permitted-users-dialog", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: true, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { closed: "closed" }, ngImport: i0, template: `
4830
+ <f-dialog
4831
+ [visible]="visible()"
4832
+ [modal]="true"
4833
+ [closable]="true"
4834
+ [breakpoints]="{ '960px': '90vw', '640px': '95vw' }"
4835
+ [style]="{ width: '50vw', maxWidth: '600px' }"
4836
+ [header]="'iam.permission.view.users' | translate"
4837
+ (onHide)="onClose()"
4838
+ >
4839
+ <div class="mb-4">
4840
+ <p class="text-sm text-muted-color">
4841
+ {{ 'iam.role.name' | translate }}:
4842
+ <strong>{{ role()?.name }}</strong>
4843
+ </p>
4844
+ </div>
4845
+
4846
+ @if (isLoading()) {
4847
+ <div class="flex justify-center items-center py-8">
4848
+ <f-progressspinner />
4849
+ </div>
4850
+ } @else {
4851
+ <div class="flex flex-col gap-3">
4852
+ @for (user of users(); track user.id) {
4853
+ <div
4854
+ class="flex items-center justify-between p-3 border border-surface rounded"
4855
+ >
4856
+ <div>
4857
+ <div class="font-semibold">{{ user.userName }}</div>
4858
+ <div class="text-sm text-muted-color">{{ user.userEmail }}</div>
4859
+ </div>
4860
+ <button
4861
+ fButton
4862
+ *hasPermission="USER_ROLE_PERMISSIONS.ASSIGN"
4863
+ [text]="true"
4864
+ severity="danger"
4865
+ size="small"
4866
+ [disabled]="isRemoving()"
4867
+ [fTooltip]="'shared.remove' | translate"
4868
+ (click)="onRemove(user)"
4869
+ >
4870
+ <ui-icon pButtonIcon name="trash"></ui-icon>
4871
+ </button>
4872
+ </div>
4873
+ } @empty {
4874
+ <div class="text-center py-4 text-muted-color">
4875
+ {{ 'iam.permission.no.users' | translate }}
4876
+ </div>
4877
+ }
4878
+ </div>
4879
+ }
4880
+
4881
+ <ng-template #footer>
4882
+ <button
4883
+ fButton
4884
+ severity="secondary"
4885
+ [outlined]="true"
4886
+ (click)="onClose()"
4887
+ >
4888
+ <span pButtonLabel>{{ 'shared.close' | translate }}</span>
4889
+ </button>
4890
+ </ng-template>
4891
+ </f-dialog>
4892
+ `, isInline: true, dependencies: [{ kind: "component", type: DialogComponent, selector: "f-dialog", inputs: ["header", "visible", "modal", "closable", "closeOnEscape", "dismissableMask", "resizable", "draggable", "maximizable", "blockScroll", "returnFocusOnClose", "position", "style", "styleClass", "breakpoints"], outputs: ["visibleChange", "onShow", "onHide", "onMaximize"] }, { kind: "directive", type: FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "variant", "rounded", "raised", "fluid", "disabled", "loading", "loadingIcon", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: ProgressSpinnerComponent, selector: "f-progressspinner", inputs: ["size", "strokeWidth", "animationDuration", "styleClass", "ariaLabel"] }, { kind: "directive", type: TooltipDirective, selector: "[fTooltip]", inputs: ["fTooltip", "tooltipPosition", "positionStyle", "tooltipStyleClass", "disabled", "tooltipEvent", "showDelay", "hideDelay", "life", "autoHide", "positionTop", "positionLeft", "escape"] }, { kind: "component", type: UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill", "severity"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
4893
+ }
4894
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: RolePermittedUsersDialogComponent, decorators: [{
4895
+ type: Component,
4896
+ args: [{
4897
+ selector: 'flusys-role-permitted-users-dialog',
4898
+ imports: [
4899
+ DialogComponent,
4900
+ FButtonDirective,
4901
+ ProgressSpinnerComponent,
4902
+ TooltipDirective,
4903
+ UiIconComponent,
4904
+ HasPermissionDirective,
4905
+ TranslatePipe,
4906
+ ],
4907
+ template: `
4908
+ <f-dialog
4909
+ [visible]="visible()"
4910
+ [modal]="true"
4911
+ [closable]="true"
4912
+ [breakpoints]="{ '960px': '90vw', '640px': '95vw' }"
4913
+ [style]="{ width: '50vw', maxWidth: '600px' }"
4914
+ [header]="'iam.permission.view.users' | translate"
4915
+ (onHide)="onClose()"
4916
+ >
4917
+ <div class="mb-4">
4918
+ <p class="text-sm text-muted-color">
4919
+ {{ 'iam.role.name' | translate }}:
4920
+ <strong>{{ role()?.name }}</strong>
4921
+ </p>
4922
+ </div>
4923
+
4924
+ @if (isLoading()) {
4925
+ <div class="flex justify-center items-center py-8">
4926
+ <f-progressspinner />
4927
+ </div>
4928
+ } @else {
4929
+ <div class="flex flex-col gap-3">
4930
+ @for (user of users(); track user.id) {
4931
+ <div
4932
+ class="flex items-center justify-between p-3 border border-surface rounded"
4933
+ >
4934
+ <div>
4935
+ <div class="font-semibold">{{ user.userName }}</div>
4936
+ <div class="text-sm text-muted-color">{{ user.userEmail }}</div>
4937
+ </div>
4938
+ <button
4939
+ fButton
4940
+ *hasPermission="USER_ROLE_PERMISSIONS.ASSIGN"
4941
+ [text]="true"
4942
+ severity="danger"
4943
+ size="small"
4944
+ [disabled]="isRemoving()"
4945
+ [fTooltip]="'shared.remove' | translate"
4946
+ (click)="onRemove(user)"
4947
+ >
4948
+ <ui-icon pButtonIcon name="trash"></ui-icon>
4949
+ </button>
4950
+ </div>
4951
+ } @empty {
4952
+ <div class="text-center py-4 text-muted-color">
4953
+ {{ 'iam.permission.no.users' | translate }}
4954
+ </div>
4955
+ }
4956
+ </div>
4957
+ }
4958
+
4959
+ <ng-template #footer>
4960
+ <button
4961
+ fButton
4962
+ severity="secondary"
4963
+ [outlined]="true"
4964
+ (click)="onClose()"
4965
+ >
4966
+ <span pButtonLabel>{{ 'shared.close' | translate }}</span>
4967
+ </button>
4968
+ </ng-template>
4969
+ </f-dialog>
4970
+ `,
4971
+ }]
4972
+ }], ctorParameters: () => [], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: true }] }], role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: true }] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
4973
+
4974
+ /**
4975
+ * Read-only viewer for users directly assigned an action, with a remove-only
4976
+ * action per user. Assigning new users stays on the user-centric
4977
+ * `UserActionSelectorComponent` flow — this dialog intentionally has no
4978
+ * "add" affordance. Since IAM stays independent of the auth package, user
4979
+ * display info is resolved via the `USER_PROVIDER` injection token rather
4980
+ * than a direct join.
4981
+ */
4982
+ class ActionPermittedUsersDialogComponent {
4983
+ USER_ACTION_PERMISSIONS = USER_ACTION_PERMISSIONS;
4984
+ permissionApi = inject(PermissionApiService);
4985
+ userProvider = inject(USER_PROVIDER);
4986
+ confirmationService = inject(ConfirmationService);
4987
+ messageService = inject(MessageService);
4988
+ translateAdapter = inject(TranslateService, {
4989
+ optional: true,
4990
+ });
4991
+ t(key, params) {
4992
+ return this.translateAdapter?.translate(key, params) ?? key;
4993
+ }
4994
+ visible = input.required(/* @ts-ignore */
4995
+ ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
4996
+ action = input.required(/* @ts-ignore */
4997
+ ...(ngDevMode ? [{ debugName: "action" }] : /* istanbul ignore next */ []));
4998
+ closed = output();
4999
+ isLoading = signal(false, /* @ts-ignore */
5000
+ ...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
5001
+ isRemoving = signal(false, /* @ts-ignore */
5002
+ ...(ngDevMode ? [{ debugName: "isRemoving" }] : /* istanbul ignore next */ []));
5003
+ users = signal([], /* @ts-ignore */
5004
+ ...(ngDevMode ? [{ debugName: "users" }] : /* istanbul ignore next */ []));
5005
+ constructor() {
5006
+ effect(() => {
5007
+ if (this.visible() && this.action()) {
5008
+ this.loadUsers();
5009
+ }
5010
+ });
5011
+ }
5012
+ async loadUsers() {
5013
+ const action = this.action();
5014
+ if (!action)
5015
+ return;
5016
+ this.isLoading.set(true);
5017
+ try {
5018
+ const response = await firstValueFrom(this.permissionApi.getActionUsers(action.id));
5019
+ const rows = response.data ?? [];
5020
+ const userIds = rows.map((r) => r.userId);
5021
+ const userInfoMap = await this.resolveUserInfo(userIds);
5022
+ this.users.set(rows.map((r) => {
5023
+ const info = userInfoMap.get(r.userId);
5024
+ return {
5025
+ id: r.id,
5026
+ userId: r.userId,
5027
+ userName: info?.name ?? r.userId,
5028
+ userEmail: info?.email ?? '',
5029
+ };
5030
+ }));
5031
+ }
5032
+ catch {
5033
+ // Error toast handled by global interceptor
5034
+ }
5035
+ finally {
5036
+ this.isLoading.set(false);
5037
+ }
5038
+ }
5039
+ async resolveUserInfo(userIds) {
5040
+ if (userIds.length === 0 || !this.userProvider.getUsersByIds) {
5041
+ return new Map();
5042
+ }
5043
+ try {
5044
+ const response = await firstValueFrom(this.userProvider.getUsersByIds(userIds));
5045
+ return new Map((response.data ?? []).map((u) => [u.id, u]));
5046
+ }
5047
+ catch {
5048
+ return new Map();
5049
+ }
5050
+ }
5051
+ onRemove(user) {
5052
+ const action = this.action();
5053
+ if (!action)
5054
+ return;
5055
+ this.confirmationService.confirm({
5056
+ message: this.t('iam.permission.remove.confirm', { name: user.userName }),
5057
+ header: this.t('iam.permission.remove'),
5058
+ icon: 'exclamation-triangle',
5059
+ acceptButtonStyleClass: 'p-button-danger',
5060
+ accept: async () => {
5061
+ this.isRemoving.set(true);
5062
+ try {
5063
+ const response = await firstValueFrom(this.permissionApi.assignUserActions({
5064
+ userId: user.userId,
5065
+ items: [{ id: action.id, action: 'remove' }],
5066
+ }));
5067
+ if (response.success) {
5068
+ this.users.update((list) => list.filter((u) => u.id !== user.id));
5069
+ this.messageService.add({
5070
+ severity: 'success',
5071
+ summary: this.t('shared.success'),
5072
+ detail: response?.messageKey
5073
+ ? this.t(response.messageKey, response.messageVariables)
5074
+ : (response?.message ?? ''),
5075
+ });
5076
+ }
5077
+ }
5078
+ catch {
5079
+ // Error toast handled by global interceptor
5080
+ }
5081
+ finally {
5082
+ this.isRemoving.set(false);
5083
+ }
5084
+ },
5085
+ });
5086
+ }
5087
+ onClose() {
5088
+ this.closed.emit();
5089
+ }
5090
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: ActionPermittedUsersDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5091
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: ActionPermittedUsersDialogComponent, isStandalone: true, selector: "flusys-action-permitted-users-dialog", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: true, transformFunction: null }, action: { classPropertyName: "action", publicName: "action", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { closed: "closed" }, ngImport: i0, template: `
5092
+ <f-dialog
5093
+ [visible]="visible()"
5094
+ [modal]="true"
5095
+ [closable]="true"
5096
+ [breakpoints]="{ '960px': '90vw', '640px': '95vw' }"
5097
+ [style]="{ width: '50vw', maxWidth: '600px' }"
5098
+ [header]="'iam.permission.view.users' | translate"
5099
+ (onHide)="onClose()"
5100
+ >
5101
+ <div class="mb-4">
5102
+ <p class="text-sm text-muted-color">
5103
+ {{ 'iam.action.name' | translate }}:
5104
+ <strong>{{ action()?.name }}</strong>
5105
+ </p>
5106
+ </div>
5107
+
5108
+ @if (isLoading()) {
5109
+ <div class="flex justify-center items-center py-8">
5110
+ <f-progressspinner />
5111
+ </div>
5112
+ } @else {
5113
+ <div class="flex flex-col gap-3">
5114
+ @for (user of users(); track user.id) {
5115
+ <div
5116
+ class="flex items-center justify-between p-3 border border-surface rounded"
5117
+ >
5118
+ <div>
5119
+ <div class="font-semibold">{{ user.userName }}</div>
5120
+ <div class="text-sm text-muted-color">{{ user.userEmail }}</div>
5121
+ </div>
5122
+ <button
5123
+ fButton
5124
+ *hasPermission="USER_ACTION_PERMISSIONS.ASSIGN"
5125
+ [text]="true"
5126
+ severity="danger"
5127
+ size="small"
5128
+ [disabled]="isRemoving()"
5129
+ [fTooltip]="'shared.remove' | translate"
5130
+ (click)="onRemove(user)"
5131
+ >
5132
+ <ui-icon pButtonIcon name="trash"></ui-icon>
5133
+ </button>
5134
+ </div>
5135
+ } @empty {
5136
+ <div class="text-center py-4 text-muted-color">
5137
+ {{ 'iam.permission.no.users' | translate }}
5138
+ </div>
5139
+ }
5140
+ </div>
5141
+ }
5142
+
5143
+ <ng-template #footer>
5144
+ <button
5145
+ fButton
5146
+ severity="secondary"
5147
+ [outlined]="true"
5148
+ (click)="onClose()"
5149
+ >
5150
+ <span pButtonLabel>{{ 'shared.close' | translate }}</span>
5151
+ </button>
5152
+ </ng-template>
5153
+ </f-dialog>
5154
+ `, isInline: true, dependencies: [{ kind: "component", type: DialogComponent, selector: "f-dialog", inputs: ["header", "visible", "modal", "closable", "closeOnEscape", "dismissableMask", "resizable", "draggable", "maximizable", "blockScroll", "returnFocusOnClose", "position", "style", "styleClass", "breakpoints"], outputs: ["visibleChange", "onShow", "onHide", "onMaximize"] }, { kind: "directive", type: FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "variant", "rounded", "raised", "fluid", "disabled", "loading", "loadingIcon", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: ProgressSpinnerComponent, selector: "f-progressspinner", inputs: ["size", "strokeWidth", "animationDuration", "styleClass", "ariaLabel"] }, { kind: "directive", type: TooltipDirective, selector: "[fTooltip]", inputs: ["fTooltip", "tooltipPosition", "positionStyle", "tooltipStyleClass", "disabled", "tooltipEvent", "showDelay", "hideDelay", "life", "autoHide", "positionTop", "positionLeft", "escape"] }, { kind: "component", type: UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill", "severity"] }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
5155
+ }
5156
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: ActionPermittedUsersDialogComponent, decorators: [{
5157
+ type: Component,
5158
+ args: [{
5159
+ selector: 'flusys-action-permitted-users-dialog',
5160
+ imports: [
5161
+ DialogComponent,
5162
+ FButtonDirective,
5163
+ ProgressSpinnerComponent,
5164
+ TooltipDirective,
5165
+ UiIconComponent,
5166
+ HasPermissionDirective,
5167
+ TranslatePipe,
5168
+ ],
5169
+ template: `
5170
+ <f-dialog
5171
+ [visible]="visible()"
5172
+ [modal]="true"
5173
+ [closable]="true"
5174
+ [breakpoints]="{ '960px': '90vw', '640px': '95vw' }"
5175
+ [style]="{ width: '50vw', maxWidth: '600px' }"
5176
+ [header]="'iam.permission.view.users' | translate"
5177
+ (onHide)="onClose()"
5178
+ >
5179
+ <div class="mb-4">
5180
+ <p class="text-sm text-muted-color">
5181
+ {{ 'iam.action.name' | translate }}:
5182
+ <strong>{{ action()?.name }}</strong>
5183
+ </p>
5184
+ </div>
5185
+
5186
+ @if (isLoading()) {
5187
+ <div class="flex justify-center items-center py-8">
5188
+ <f-progressspinner />
5189
+ </div>
5190
+ } @else {
5191
+ <div class="flex flex-col gap-3">
5192
+ @for (user of users(); track user.id) {
5193
+ <div
5194
+ class="flex items-center justify-between p-3 border border-surface rounded"
5195
+ >
5196
+ <div>
5197
+ <div class="font-semibold">{{ user.userName }}</div>
5198
+ <div class="text-sm text-muted-color">{{ user.userEmail }}</div>
5199
+ </div>
5200
+ <button
5201
+ fButton
5202
+ *hasPermission="USER_ACTION_PERMISSIONS.ASSIGN"
5203
+ [text]="true"
5204
+ severity="danger"
5205
+ size="small"
5206
+ [disabled]="isRemoving()"
5207
+ [fTooltip]="'shared.remove' | translate"
5208
+ (click)="onRemove(user)"
5209
+ >
5210
+ <ui-icon pButtonIcon name="trash"></ui-icon>
5211
+ </button>
5212
+ </div>
5213
+ } @empty {
5214
+ <div class="text-center py-4 text-muted-color">
5215
+ {{ 'iam.permission.no.users' | translate }}
5216
+ </div>
5217
+ }
5218
+ </div>
5219
+ }
5220
+
5221
+ <ng-template #footer>
5222
+ <button
5223
+ fButton
5224
+ severity="secondary"
5225
+ [outlined]="true"
5226
+ (click)="onClose()"
5227
+ >
5228
+ <span pButtonLabel>{{ 'shared.close' | translate }}</span>
5229
+ </button>
5230
+ </ng-template>
5231
+ </f-dialog>
5232
+ `,
5233
+ }]
5234
+ }], ctorParameters: () => [], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: true }] }], action: [{ type: i0.Input, args: [{ isSignal: true, alias: "action", required: true }] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
5235
+
4745
5236
  // Logic Builder Component
4746
5237
 
4747
5238
  /**
@@ -4794,11 +5285,12 @@ class ProfilePermissionProviderAdapter {
4794
5285
  })),
4795
5286
  })));
4796
5287
  }
4797
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ProfilePermissionProviderAdapter, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4798
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ProfilePermissionProviderAdapter });
5288
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: ProfilePermissionProviderAdapter, deps: [], target: i0.ɵɵFactoryTarget.Service });
5289
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.5", ngImport: i0, type: ProfilePermissionProviderAdapter, autoProvided: false });
4799
5290
  }
4800
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ProfilePermissionProviderAdapter, decorators: [{
4801
- type: Injectable
5291
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: ProfilePermissionProviderAdapter, decorators: [{
5292
+ type: Service,
5293
+ args: [{ autoProvided: false }]
4802
5294
  }] });
4803
5295
 
4804
5296
  /** Registers IAM provider adapters for ng-shared interfaces */
@@ -4845,7 +5337,7 @@ const IAM_ROUTES = [
4845
5337
  fallbackMessages: { ...IAM_MESSAGES, ...SHARED_MESSAGES },
4846
5338
  }),
4847
5339
  },
4848
- loadComponent: () => import('./flusys-ng-iam-iam-container.component-D0m8u6nu.mjs').then((m) => m.IamContainerComponent),
5340
+ loadComponent: () => import('./flusys-ng-iam-iam-container.component-XBoIeQ0t.mjs').then((m) => m.IamContainerComponent),
4849
5341
  children: [
4850
5342
  // Actions Management
4851
5343
  {
@@ -4854,15 +5346,15 @@ const IAM_ROUTES = [
4854
5346
  children: [
4855
5347
  {
4856
5348
  path: '',
4857
- loadComponent: () => import('./flusys-ng-iam-action-list-page.component-BRi_CpGl.mjs').then((m) => m.ActionListPageComponent),
5349
+ loadComponent: () => import('./flusys-ng-iam-action-list-page.component-BveT0xT6.mjs').then((m) => m.ActionListPageComponent),
4858
5350
  },
4859
5351
  {
4860
5352
  path: 'new',
4861
- loadComponent: () => import('./flusys-ng-iam-action-form-page.component-Ci56tFEu.mjs').then((m) => m.ActionFormPageComponent),
5353
+ loadComponent: () => import('./flusys-ng-iam-action-form-page.component-CF_ixS-r.mjs').then((m) => m.ActionFormPageComponent),
4862
5354
  },
4863
5355
  {
4864
5356
  path: ':id',
4865
- loadComponent: () => import('./flusys-ng-iam-action-form-page.component-Ci56tFEu.mjs').then((m) => m.ActionFormPageComponent),
5357
+ loadComponent: () => import('./flusys-ng-iam-action-form-page.component-CF_ixS-r.mjs').then((m) => m.ActionFormPageComponent),
4866
5358
  },
4867
5359
  ],
4868
5360
  },
@@ -4873,15 +5365,15 @@ const IAM_ROUTES = [
4873
5365
  children: [
4874
5366
  {
4875
5367
  path: '',
4876
- loadComponent: () => import('./flusys-ng-iam-role-list-page.component-BCtoWvFQ.mjs').then((m) => m.RoleListPageComponent),
5368
+ loadComponent: () => import('./flusys-ng-iam-role-list-page.component-vFHxd3Q-.mjs').then((m) => m.RoleListPageComponent),
4877
5369
  },
4878
5370
  {
4879
5371
  path: 'new',
4880
- loadComponent: () => import('./flusys-ng-iam-role-form-page.component-ByMbnQ53.mjs').then((m) => m.RoleFormPageComponent),
5372
+ loadComponent: () => import('./flusys-ng-iam-role-form-page.component-Cfc8za3D.mjs').then((m) => m.RoleFormPageComponent),
4881
5373
  },
4882
5374
  {
4883
5375
  path: ':id',
4884
- loadComponent: () => import('./flusys-ng-iam-role-form-page.component-ByMbnQ53.mjs').then((m) => m.RoleFormPageComponent),
5376
+ loadComponent: () => import('./flusys-ng-iam-role-form-page.component-Cfc8za3D.mjs').then((m) => m.RoleFormPageComponent),
4885
5377
  },
4886
5378
  ],
4887
5379
  },
@@ -4896,7 +5388,7 @@ const IAM_ROUTES = [
4896
5388
  COMPANY_ACTION_PERMISSIONS.READ,
4897
5389
  ]),
4898
5390
  ],
4899
- loadComponent: () => import('./flusys-ng-iam-permission-page.component-CVaxwwcS.mjs').then((m) => m.PermissionPageComponent),
5391
+ loadComponent: () => import('./flusys-ng-iam-permission-page.component-CGtj1EiO.mjs').then((m) => m.PermissionPageComponent),
4900
5392
  },
4901
5393
  // Default redirect to the first tab the user has permission to see
4902
5394
  {
@@ -4914,5 +5406,5 @@ const IAM_ROUTES = [
4914
5406
  * Generated bundle index. Do not edit.
4915
5407
  */
4916
5408
 
4917
- 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, buildActionParentTree as b, convertActionToTreeNode as c, RoleActionSelectorComponent as d, UserActionSelectorComponent as e, ActionPermissionLogicService as f, IAM_ROUTES as g, MyPermissionsApiService as h, PermissionStateService as i, ProfilePermissionProviderAdapter as j, provideIamProviders as p };
4918
- //# sourceMappingURL=flusys-ng-iam-flusys-ng-iam-BEAhj9ma.mjs.map
5409
+ 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, ActionPermittedUsersDialogComponent as b, convertActionToTreeNode as c, buildActionParentTree as d, RolePermittedUsersDialogComponent as e, RoleActionSelectorComponent as f, UserActionSelectorComponent as g, ActionPermissionLogicService as h, IAM_ROUTES as i, MyPermissionsApiService as j, PermissionStateService as k, ProfilePermissionProviderAdapter as l, provideIamProviders as p };
5410
+ //# sourceMappingURL=flusys-ng-iam-flusys-ng-iam-CjLr3bfY.mjs.map