@flusys/ng-iam 0.1.0-beta.3 → 1.0.0-rc

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 (28) hide show
  1. package/README.md +225 -25
  2. package/fesm2022/{flusys-ng-iam-action-form-page.component-BVWZMlLU.mjs → flusys-ng-iam-action-form-page.component-C_BRrrWW.mjs} +181 -210
  3. package/fesm2022/flusys-ng-iam-action-form-page.component-C_BRrrWW.mjs.map +1 -0
  4. package/fesm2022/flusys-ng-iam-action-list-page.component-Daf93zpS.mjs +289 -0
  5. package/fesm2022/flusys-ng-iam-action-list-page.component-Daf93zpS.mjs.map +1 -0
  6. package/fesm2022/{flusys-ng-iam-flusys-ng-iam-D_i24Gub.mjs → flusys-ng-iam-flusys-ng-iam-BPIpfrjN.mjs} +967 -1087
  7. package/fesm2022/flusys-ng-iam-flusys-ng-iam-BPIpfrjN.mjs.map +1 -0
  8. package/fesm2022/flusys-ng-iam-iam-container.component-Bn4kQtxW.mjs +92 -0
  9. package/fesm2022/flusys-ng-iam-iam-container.component-Bn4kQtxW.mjs.map +1 -0
  10. package/fesm2022/{flusys-ng-iam-permission-page.component-C0yLMdW5.mjs → flusys-ng-iam-permission-page.component-CmxOBJPu.mjs} +45 -16
  11. package/fesm2022/flusys-ng-iam-permission-page.component-CmxOBJPu.mjs.map +1 -0
  12. package/fesm2022/{flusys-ng-iam-role-form-page.component-Co6bbHik.mjs → flusys-ng-iam-role-form-page.component-ByNueI1a.mjs} +110 -138
  13. package/fesm2022/flusys-ng-iam-role-form-page.component-ByNueI1a.mjs.map +1 -0
  14. package/fesm2022/flusys-ng-iam-role-list-page.component-CFly5KnH.mjs +316 -0
  15. package/fesm2022/flusys-ng-iam-role-list-page.component-CFly5KnH.mjs.map +1 -0
  16. package/fesm2022/flusys-ng-iam.mjs +1 -1
  17. package/package.json +5 -5
  18. package/types/flusys-ng-iam.d.ts +89 -37
  19. package/fesm2022/flusys-ng-iam-action-form-page.component-BVWZMlLU.mjs.map +0 -1
  20. package/fesm2022/flusys-ng-iam-action-list-page.component-CCp7M7xo.mjs +0 -282
  21. package/fesm2022/flusys-ng-iam-action-list-page.component-CCp7M7xo.mjs.map +0 -1
  22. package/fesm2022/flusys-ng-iam-flusys-ng-iam-D_i24Gub.mjs.map +0 -1
  23. package/fesm2022/flusys-ng-iam-iam-container.component-BFKoNtdz.mjs +0 -97
  24. package/fesm2022/flusys-ng-iam-iam-container.component-BFKoNtdz.mjs.map +0 -1
  25. package/fesm2022/flusys-ng-iam-permission-page.component-C0yLMdW5.mjs.map +0 -1
  26. package/fesm2022/flusys-ng-iam-role-form-page.component-Co6bbHik.mjs.map +0 -1
  27. package/fesm2022/flusys-ng-iam-role-list-page.component-KJUVOrf0.mjs +0 -267
  28. package/fesm2022/flusys-ng-iam-role-list-page.component-KJUVOrf0.mjs.map +0 -1
@@ -1,8 +1,9 @@
1
- import { IBaseEntity, ILogicNode, ApiResourceService, ISingleResponse } from '@flusys/ng-shared';
1
+ import { IBaseEntity, ILogicNode, ApiResourceService, ISingleResponse, IProfilePermissionProvider, IProfileRoleInfo, IProfileActionInfo } from '@flusys/ng-shared';
2
2
  import * as _angular_core from '@angular/core';
3
- import { Signal, OnDestroy } from '@angular/core';
3
+ import { Signal, Provider } from '@angular/core';
4
4
  import { Observable } from 'rxjs';
5
5
  import { BaseApiService } from '@flusys/ng-core';
6
+ export { PermissionMode } from '@flusys/ng-core';
6
7
  import * as primeng_api from 'primeng/api';
7
8
  import { Routes } from '@angular/router';
8
9
 
@@ -46,7 +47,7 @@ interface IRole extends IBaseEntity {
46
47
  companyId: string | null;
47
48
  isActive: boolean;
48
49
  serial: number | null;
49
- metadata: Record<string, any> | null;
50
+ metadata: Record<string, unknown> | null;
50
51
  }
51
52
  /**
52
53
  * Create Role DTO
@@ -58,7 +59,7 @@ interface ICreateRoleDto {
58
59
  companyId?: string;
59
60
  isActive?: boolean;
60
61
  serial?: number;
61
- metadata?: Record<string, any>;
62
+ metadata?: Record<string, unknown>;
62
63
  }
63
64
  /**
64
65
  * Update Role DTO
@@ -99,7 +100,7 @@ interface IAction extends IBaseEntity {
99
100
  parentId: string | null;
100
101
  serial: number | null;
101
102
  isActive: boolean;
102
- metadata: Record<string, any> | null;
103
+ metadata: Record<string, unknown> | null;
103
104
  }
104
105
  /**
105
106
  * Action Tree DTO
@@ -121,7 +122,7 @@ interface ICreateActionDto {
121
122
  parentId?: string;
122
123
  serial?: number;
123
124
  isActive?: boolean;
124
- metadata?: Record<string, any>;
125
+ metadata?: Record<string, unknown>;
125
126
  }
126
127
  /**
127
128
  * Update Action DTO
@@ -135,10 +136,6 @@ interface IUpdateActionDto extends Partial<ICreateActionDto> {
135
136
  * Permission Action - 'add' or 'remove'
136
137
  */
137
138
  type PermissionAction = 'add' | 'remove';
138
- /**
139
- * Permission Mode - matches backend IAMPermissionMode
140
- */
141
- type PermissionMode = 'rbac' | 'direct' | 'full';
142
139
  /**
143
140
  * Permission Item DTO
144
141
  * Used in all assignment operations
@@ -364,7 +361,7 @@ declare class ActionApiService extends ApiResourceService<IUpdateActionDto, IAct
364
361
  constructor();
365
362
  /**
366
363
  * Get actions for permission assignment
367
- * GET /iam/actions/tree-for-permission
364
+ * POST /iam/actions/tree-for-permission
368
365
  * Returns actions filtered by company whitelist if enabled
369
366
  */
370
367
  getActionsForPermission(): Observable<ISingleResponse<IActionTreeDto[]>>;
@@ -551,7 +548,7 @@ declare class PermissionApiService extends BaseApiService {
551
548
  assignUserActions(data: IAssignUserActionsDto): Observable<ISingleResponse<IPermissionOperationResultDto>>;
552
549
  /**
553
550
  * Get user's direct action permissions
554
- * GET /permissions/user-actions/:userId
551
+ * POST /iam/permissions/get-user-actions
555
552
  */
556
553
  getUserActions(userId: string, query?: IGetUserActionsDto): Observable<ISingleResponse<IUserActionResponseDto[]>>;
557
554
  /**
@@ -561,7 +558,7 @@ declare class PermissionApiService extends BaseApiService {
561
558
  assignUserRoles(data: IAssignUserRolesDto): Observable<ISingleResponse<IPermissionOperationResultDto>>;
562
559
  /**
563
560
  * Get user's role assignments
564
- * GET /permissions/user-roles/:userId
561
+ * POST /iam/permissions/get-user-roles
565
562
  */
566
563
  getUserRoles(userId: string, query?: IGetUserRolesDto): Observable<ISingleResponse<IUserRoleResponseDto[]>>;
567
564
  /**
@@ -571,7 +568,7 @@ declare class PermissionApiService extends BaseApiService {
571
568
  assignRoleActions(data: IAssignRoleActionsDto): Observable<ISingleResponse<IPermissionOperationResultDto>>;
572
569
  /**
573
570
  * Get role's action permissions
574
- * GET /permissions/role-actions/:roleId
571
+ * POST /iam/permissions/get-role-actions
575
572
  */
576
573
  getRoleActions(roleId: string, query?: IGetRoleActionsDto): Observable<ISingleResponse<IRoleActionResponseDto[]>>;
577
574
  /**
@@ -581,7 +578,7 @@ declare class PermissionApiService extends BaseApiService {
581
578
  assignCompanyActions(data: IAssignCompanyActionsDto): Observable<ISingleResponse<IPermissionOperationResultDto>>;
582
579
  /**
583
580
  * Get company's whitelisted actions
584
- * GET /permissions/company-actions/:companyId
581
+ * POST /iam/permissions/get-company-actions
585
582
  */
586
583
  getCompanyActions(companyId: string): Observable<ISingleResponse<ICompanyActionResponseDto[]>>;
587
584
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<PermissionApiService, never>;
@@ -674,8 +671,10 @@ declare class LogicBuilderComponent {
674
671
  id: string;
675
672
  name: string;
676
673
  }[]>;
677
- private builderTree;
674
+ /** Internal builder tree state (private writable + public readonly pattern) */
675
+ private readonly _builderTree;
678
676
  readonly builderLogic: _angular_core.Signal<IBuilderNode | null>;
677
+ constructor();
679
678
  initializeLogic(): void;
680
679
  clearLogic(): void;
681
680
  toggleOperator(nodeId: string): void;
@@ -723,7 +722,12 @@ declare class LogicBuilderComponent {
723
722
  * <flusys-role-action-selector />
724
723
  * ```
725
724
  */
726
- declare class RoleActionSelectorComponent implements OnDestroy {
725
+ declare class RoleActionSelectorComponent {
726
+ readonly ROLE_ACTION_PERMISSIONS: {
727
+ readonly READ: "role-action.read";
728
+ readonly ASSIGN: "role-action.assign";
729
+ };
730
+ private readonly destroyRef;
727
731
  private readonly roleApi;
728
732
  private readonly actionApi;
729
733
  private readonly permissionApi;
@@ -751,7 +755,6 @@ declare class RoleActionSelectorComponent implements OnDestroy {
751
755
  readonly canSave: _angular_core.Signal<boolean>;
752
756
  private loadDataAbortController;
753
757
  constructor();
754
- ngOnDestroy(): void;
755
758
  /**
756
759
  * Load roles from API
757
760
  */
@@ -830,13 +833,18 @@ declare class RoleActionSelectorComponent implements OnDestroy {
830
833
  * <flusys-company-action-selector />
831
834
  * ```
832
835
  */
833
- declare class CompanyActionSelectorComponent implements OnDestroy {
836
+ declare class CompanyActionSelectorComponent {
837
+ readonly COMPANY_ACTION_PERMISSIONS: {
838
+ readonly READ: "company-action.read";
839
+ readonly ASSIGN: "company-action.assign";
840
+ };
834
841
  private readonly companyApiProvider;
835
842
  private readonly actionApi;
836
843
  private readonly permissionApi;
837
844
  private readonly messageService;
838
845
  private readonly confirmationService;
839
846
  private readonly permissionLogic;
847
+ private readonly destroyRef;
840
848
  readonly selectedCompanyId: _angular_core.WritableSignal<string | undefined>;
841
849
  readonly companies: _angular_core.WritableSignal<ICompany[]>;
842
850
  readonly loading: _angular_core.WritableSignal<boolean>;
@@ -859,7 +867,6 @@ declare class CompanyActionSelectorComponent implements OnDestroy {
859
867
  readonly canSave: _angular_core.Signal<boolean>;
860
868
  private loadDataAbortController;
861
869
  constructor();
862
- ngOnDestroy(): void;
863
870
  /**
864
871
  * Load companies from API
865
872
  */
@@ -940,16 +947,20 @@ declare class CompanyActionSelectorComponent implements OnDestroy {
940
947
  * ```
941
948
  */
942
949
  declare class UserRoleSelectorComponent {
950
+ readonly USER_ROLE_PERMISSIONS: {
951
+ readonly READ: "user-role.read";
952
+ readonly ASSIGN: "user-role.assign";
953
+ };
943
954
  private readonly appConfig;
944
955
  private readonly companyContext;
945
- private readonly userProvider;
946
956
  private readonly userPermissionProvider;
947
957
  private readonly roleApi;
948
958
  private readonly permissionApi;
949
959
  private readonly messageService;
950
- readonly selectedUserId: _angular_core.WritableSignal<string | undefined>;
960
+ private readonly destroyRef;
961
+ private loadDataAbortController;
962
+ readonly selectedUserId: _angular_core.WritableSignal<string | null>;
951
963
  readonly selectedBranchId: _angular_core.WritableSignal<string | undefined>;
952
- readonly users: _angular_core.WritableSignal<IUser[]>;
953
964
  readonly branches: _angular_core.WritableSignal<IBranch[]>;
954
965
  readonly loading: _angular_core.WritableSignal<boolean>;
955
966
  readonly saving: _angular_core.WritableSignal<boolean>;
@@ -967,10 +978,6 @@ declare class UserRoleSelectorComponent {
967
978
  readonly pendingRemove: _angular_core.Signal<IRole[]>;
968
979
  readonly canSave: _angular_core.Signal<boolean>;
969
980
  constructor();
970
- /**
971
- * Load users from provider
972
- */
973
- private loadUsers;
974
981
  /**
975
982
  * Load user's permitted branches
976
983
  */
@@ -1043,17 +1050,21 @@ declare class UserRoleSelectorComponent {
1043
1050
  * ```
1044
1051
  */
1045
1052
  declare class UserActionSelectorComponent {
1053
+ readonly USER_ACTION_PERMISSIONS: {
1054
+ readonly READ: "user-action.read";
1055
+ readonly ASSIGN: "user-action.assign";
1056
+ };
1046
1057
  private readonly appConfig;
1047
1058
  private readonly companyContext;
1048
- private readonly userProvider;
1049
1059
  private readonly userPermissionProvider;
1050
1060
  private readonly actionApi;
1051
1061
  private readonly permissionApi;
1052
1062
  private readonly permissionLogic;
1053
1063
  private readonly messageService;
1054
- readonly selectedUserId: _angular_core.WritableSignal<string | undefined>;
1064
+ private readonly destroyRef;
1065
+ private loadDataAbortController;
1066
+ readonly selectedUserId: _angular_core.WritableSignal<string | null>;
1055
1067
  readonly selectedBranchId: _angular_core.WritableSignal<string | undefined>;
1056
- readonly users: _angular_core.WritableSignal<IUser[]>;
1057
1068
  readonly branches: _angular_core.WritableSignal<IBranch[]>;
1058
1069
  readonly loading: _angular_core.WritableSignal<boolean>;
1059
1070
  readonly saving: _angular_core.WritableSignal<boolean>;
@@ -1076,10 +1087,6 @@ declare class UserActionSelectorComponent {
1076
1087
  readonly pendingRemove: _angular_core.Signal<IAction[]>;
1077
1088
  readonly canSave: _angular_core.Signal<boolean>;
1078
1089
  constructor();
1079
- /**
1080
- * Load users from provider
1081
- */
1082
- private loadUsers;
1083
1090
  /**
1084
1091
  * Load user's permitted branches
1085
1092
  */
@@ -1097,7 +1104,7 @@ declare class UserActionSelectorComponent {
1097
1104
  */
1098
1105
  hasUnmetPrerequisites(action: IAction): boolean;
1099
1106
  /**
1100
- * Handle action checkbox toggle
1107
+ * Handle action toggle with dependency management
1101
1108
  */
1102
1109
  onActionToggle(action: IAction, newValue: boolean): void;
1103
1110
  /**
@@ -1124,6 +1131,51 @@ declare class UserActionSelectorComponent {
1124
1131
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<UserActionSelectorComponent, "flusys-user-action-selector", never, {}, {}, never, never, true, never>;
1125
1132
  }
1126
1133
 
1134
+ /**
1135
+ * Profile Permission Provider Adapter
1136
+ *
1137
+ * Implements IProfilePermissionProvider using ng-iam's PermissionApiService.
1138
+ * Allows ng-auth profile page to display user permissions without
1139
+ * depending on ng-iam directly.
1140
+ *
1141
+ * @example
1142
+ * // In app.config.ts
1143
+ * providers: [
1144
+ * ...provideIamProviders()
1145
+ * ]
1146
+ *
1147
+ * // In profile component
1148
+ * private readonly permissionProvider = inject(PROFILE_PERMISSION_PROVIDER, { optional: true });
1149
+ */
1150
+ declare class ProfilePermissionProviderAdapter implements IProfilePermissionProvider {
1151
+ private readonly permissionApi;
1152
+ getUserRoles(userId: string, branchId?: string): Observable<ISingleResponse<IProfileRoleInfo[]>>;
1153
+ getUserActions(userId: string, branchId?: string): Observable<ISingleResponse<IProfileActionInfo[]>>;
1154
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ProfilePermissionProviderAdapter, never>;
1155
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<ProfilePermissionProviderAdapter>;
1156
+ }
1157
+
1158
+ /**
1159
+ * Provide IAM Provider Adapters
1160
+ *
1161
+ * Registers IAM implementations for provider interfaces from ng-shared.
1162
+ * This allows ng-auth profile page to display permissions without direct dependencies.
1163
+ *
1164
+ * @example
1165
+ * // In app.config.ts
1166
+ * import { provideIamProviders } from '@flusys/ng-iam';
1167
+ *
1168
+ * export const appConfig: ApplicationConfig = {
1169
+ * providers: [
1170
+ * ...provideIamProviders(),
1171
+ * // ... other providers
1172
+ * ]
1173
+ * };
1174
+ *
1175
+ * @returns Array of Angular providers
1176
+ */
1177
+ declare function provideIamProviders(): Provider[];
1178
+
1127
1179
  /**
1128
1180
  * IAM Routes Configuration
1129
1181
  *
@@ -1136,5 +1188,5 @@ declare class UserActionSelectorComponent {
1136
1188
  */
1137
1189
  declare const IAM_ROUTES: Routes;
1138
1190
 
1139
- export { ActionApiService, ActionPermissionLogicService, ActionType, CompanyActionSelectorComponent, IAM_ROUTES, LogicBuilderComponent, MAX_DROPDOWN_ITEMS, MyPermissionsApiService, PermissionApiService, PermissionStateService, RoleActionSelectorComponent, RoleApiService, UserActionSelectorComponent, UserRoleSelectorComponent };
1140
- export type { IAction, IActionTreeDto, IAssignCompanyActionsDto, IAssignRoleActionsDto, IAssignUserActionsDto, IAssignUserRolesDto, IBranch, ICompany, ICompanyActionResponseDto, ICreateActionDto, ICreateRoleDto, IGetMyPermissionsDto, IGetRoleActionsDto, IGetUserActionsDto, IGetUserRolesDto, IMenuAction, IMyPermissionsResponseDto, IPermissionItemDto, IPermissionOperationResultDto, IPrerequisiteActionDto, IPrerequisiteValidationError, IRole, IRoleActionResponseDto, IRoleQueryDto, IUpdateActionDto, IUpdateRoleDto, IUser, IUserActionResponseDto, IUserRoleResponseDto, PermissionAction, PermissionMode };
1191
+ export { ActionApiService, ActionPermissionLogicService, ActionType, CompanyActionSelectorComponent, IAM_ROUTES, LogicBuilderComponent, MAX_DROPDOWN_ITEMS, MyPermissionsApiService, PermissionApiService, PermissionStateService, ProfilePermissionProviderAdapter, RoleActionSelectorComponent, RoleApiService, UserActionSelectorComponent, UserRoleSelectorComponent, provideIamProviders };
1192
+ export type { IAction, IActionTreeDto, IAssignCompanyActionsDto, IAssignRoleActionsDto, IAssignUserActionsDto, IAssignUserRolesDto, IBranch, ICompany, ICompanyActionResponseDto, ICreateActionDto, ICreateRoleDto, IGetMyPermissionsDto, IGetRoleActionsDto, IGetUserActionsDto, IGetUserRolesDto, IMenuAction, IMyPermissionsResponseDto, IPermissionItemDto, IPermissionOperationResultDto, IPrerequisiteActionDto, IPrerequisiteValidationError, IRole, IRoleActionResponseDto, IRoleQueryDto, IUpdateActionDto, IUpdateRoleDto, IUser, IUserActionResponseDto, IUserRoleResponseDto, PermissionAction };
@@ -1 +0,0 @@
1
- {"version":3,"file":"flusys-ng-iam-action-form-page.component-BVWZMlLU.mjs","sources":["../../../projects/ng-iam/pages/action/action-form-page.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, inject, OnInit, signal } from '@angular/core';\nimport { form, FormField, required } from '@angular/forms/signals';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { AngularModule, ILogicNode, PrimeModule } from '@flusys/ng-shared';\nimport { MessageService } from 'primeng/api';\nimport { firstValueFrom } from 'rxjs';\nimport { ActionApiService } from '../../services/action-api.service';\nimport { IAction, ActionType } from '../../interfaces/action.interface';\nimport { LogicBuilderComponent } from '../../components/logic-builder.component';\n\n/** Action form model interface */\ninterface IActionFormModel {\n id: string;\n name: string;\n description: string;\n code: string;\n actionType: ActionType;\n permissionLogic: any | null;\n parentId: string;\n serial: string;\n isActive: boolean;\n metadata: any | null;\n}\n\n/**\n * Action Form Page Component\n * Create/Edit action with signal-based form pattern (matches ng-auth)\n */\n@Component({\n selector: 'lib-action-form-page',\n standalone: true,\n imports: [AngularModule, PrimeModule, FormField, LogicBuilderComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"card\">\n <div class=\"flex justify-between items-center mb-4\">\n <h3 class=\"text-xl font-semibold\">\n {{ isEditMode() ? 'Edit Action' : 'New Action' }}\n </h3>\n <p-button\n label=\"Back\"\n icon=\"pi pi-arrow-left\"\n [outlined]=\"true\"\n (onClick)=\"onBack()\" />\n </div>\n\n <form (ngSubmit)=\"onSubmit()\">\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <!-- Name -->\n <div>\n <label for=\"name\" class=\"block font-medium mb-2\">Name *</label>\n <input\n pInputText\n id=\"name\"\n [formField]=\"actionForm.name\"\n class=\"w-full\"\n placeholder=\"Enter action name\" />\n </div>\n\n <!-- Code -->\n <div>\n <label for=\"code\" class=\"block font-medium mb-2\">Code</label>\n <input\n pInputText\n id=\"code\"\n [formField]=\"actionForm.code\"\n class=\"w-full\"\n placeholder=\"Enter action code\" />\n </div>\n\n <!-- Description -->\n <div class=\"md:col-span-2\">\n <label for=\"description\" class=\"block font-medium mb-2\">Description</label>\n <input\n pInputText\n id=\"description\"\n [formField]=\"actionForm.description\"\n class=\"w-full\"\n placeholder=\"Enter description\" />\n </div>\n\n <!-- Action Type -->\n <div>\n <label for=\"actionType\" class=\"block font-medium mb-2\">Action Type *</label>\n <select\n id=\"actionType\"\n class=\"p-select-native\"\n [formField]=\"actionForm.actionType\">\n @for (type of actionTypes; track type.value) {\n <option [value]=\"type.value\">{{ type.label }}</option>\n }\n </select>\n </div>\n\n <!-- Parent Action -->\n <div>\n <label for=\"parentId\" class=\"block font-medium mb-2\">Parent Action</label>\n <select\n id=\"parentId\"\n class=\"p-select-native\"\n [formField]=\"actionForm.parentId\">\n <option value=\"\">Select parent action</option>\n @for (action of availableActions(); track action.id) {\n <option [value]=\"action.id\">{{ action.name }}</option>\n }\n </select>\n </div>\n\n <!-- Order -->\n <div>\n <label for=\"serial\" class=\"block font-medium mb-2\">Display Order</label>\n <input\n pInputText\n id=\"serial\"\n type=\"number\"\n [formField]=\"actionForm.serial\"\n class=\"w-full\"\n placeholder=\"Enter display order\" />\n </div>\n\n <!-- Is Active -->\n <div class=\"flex items-center pt-6\">\n <label class=\"p-checkbox-native\">\n <input\n type=\"checkbox\"\n [formField]=\"actionForm.isActive\" />\n <span>Active</span>\n </label>\n </div>\n </div>\n\n <!-- Permission Logic Builder -->\n <div class=\"mt-6\">\n <lib-logic-builder\n [logic]=\"formModel().permissionLogic\"\n [actions]=\"allActionsForLogic()\"\n (logicChange)=\"onLogicChange($event)\" />\n </div>\n\n <!-- Actions -->\n <div class=\"flex justify-end gap-2 mt-6\">\n <p-button\n label=\"Cancel\"\n severity=\"secondary\"\n [outlined]=\"true\"\n (onClick)=\"onBack()\" />\n <p-button\n [label]=\"isEditMode() ? 'Update' : 'Create'\"\n type=\"submit\"\n [loading]=\"isLoading()\"\n [disabled]=\"!isFormValid() || isLoading()\" />\n </div>\n </form>\n </div>\n `,\n})\nexport class ActionFormPageComponent implements OnInit {\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n private readonly actionApi = inject(ActionApiService);\n private readonly messageService = inject(MessageService);\n\n /** Loading state */\n readonly isLoading = signal(false);\n\n /** Existing action data when editing */\n readonly existingAction = signal<IAction | null>(null);\n\n /** Whether in edit mode */\n readonly isEditMode = computed(() => !!this.existingAction());\n\n /** All actions for LogicBuilder */\n readonly allActionsForLogic = signal<Array<{ id: string; name: string }>>([]);\n\n /** All loaded actions for parent dropdown */\n readonly allActions = signal<IAction[]>([]);\n\n /** Available actions for parent dropdown (excludes current action to prevent circular reference) */\n readonly availableActions = computed(() => {\n const actions = this.allActions();\n const currentId = this.existingAction()?.id;\n return currentId ? actions.filter(a => a.id !== currentId) : actions;\n });\n\n // ============================================\n // Form (Signal Forms)\n // ============================================\n\n /** Form model */\n readonly formModel = signal<IActionFormModel>({\n id: '',\n name: '',\n description: '',\n code: '',\n actionType: ActionType.BACKEND,\n permissionLogic: null,\n parentId: '',\n serial: '',\n isActive: true,\n metadata: null,\n });\n\n /** Available action types for dropdown */\n readonly actionTypes = [\n { label: 'Backend (API Endpoints)', value: ActionType.BACKEND },\n { label: 'Frontend (UI Features)', value: ActionType.FRONTEND },\n { label: 'Both (Backend + Frontend)', value: ActionType.BOTH },\n ];\n\n /** Form with validation schema */\n readonly actionForm = form(this.formModel, (f) => {\n required(f.name, { message: 'Name is required' });\n });\n\n /** Check if form is valid */\n readonly isFormValid = computed(() => {\n const model = this.formModel();\n return model.name.trim().length > 0;\n });\n\n async ngOnInit(): Promise<void> {\n const id = this.route.snapshot.paramMap.get('id');\n\n // Load ALL actions FIRST - critical for LogicBuilder to display action names\n try {\n const response = await firstValueFrom(\n this.actionApi.getAll('', {\n pagination: { currentPage: 0, pageSize: 10000 },\n select: ['id', 'name', 'code', 'actionType', 'permissionLogic'],\n })\n );\n\n if (response?.success && response.data) {\n // Set actions for LogicBuilder dropdown\n this.allActionsForLogic.set(\n response.data.map(a => ({ id: a.id!, name: a.name ?? 'Unnamed' }))\n );\n\n // Store loaded actions locally for parent dropdown\n this.allActions.set(response.data);\n }\n } catch (error) {\n console.error('[ActionFormPage] Failed to load actions:', error);\n }\n\n // THEN load the specific action (ensures actions are loaded before setting permissionLogic)\n if (id && id !== 'new') {\n await this.loadAction(id);\n }\n }\n\n async loadAction(id: string): Promise<void> {\n this.isLoading.set(true);\n try {\n // Load fresh data from API to ensure permissionLogic is included\n const response = await this.actionApi.findByIdAsync(id, [\n 'id',\n 'name',\n 'description',\n 'code',\n 'actionType',\n 'permissionLogic',\n 'parentId',\n 'serial',\n 'isActive',\n 'metadata',\n ]);\n\n if (response?.success && response.data) {\n const action = response.data;\n\n // Set existing action for reference\n this.existingAction.set(action);\n\n // Populate form with action data\n this.formModel.set({\n id: action.id ?? '',\n name: action.name ?? '',\n description: action.description ?? '',\n code: action.code ?? '',\n actionType: action.actionType ?? ActionType.BACKEND,\n permissionLogic: action.permissionLogic ?? null,\n parentId: action.parentId ?? '',\n serial: action.serial?.toString() ?? '',\n isActive: action.isActive ?? true,\n metadata: action.metadata ?? null,\n });\n } else {\n this.messageService.add({\n severity: 'error',\n summary: 'Error',\n detail: 'Action not found.',\n });\n this.router.navigate(['/iam/actions']);\n }\n } catch (error) {\n console.error('[ActionFormPage] Failed to load action:', error);\n this.messageService.add({\n severity: 'error',\n summary: 'Error',\n detail: 'Failed to load action.',\n });\n this.router.navigate(['/iam/actions']);\n } finally {\n this.isLoading.set(false);\n }\n }\n\n async onSubmit(): Promise<void> {\n if (!this.isFormValid()) {\n this.messageService.add({\n severity: 'error',\n summary: 'Validation Error',\n detail: 'Please fill in all required fields.',\n });\n return;\n }\n\n this.isLoading.set(true);\n\n try {\n const formValue = this.formModel();\n\n // Convert empty strings to undefined for DTO compatibility\n const dto = {\n ...formValue,\n description: formValue.description || undefined,\n code: formValue.code || undefined,\n parentId: formValue.parentId || undefined,\n serial: formValue.serial ? parseInt(formValue.serial, 10) : undefined,\n metadata: formValue.metadata ?? undefined,\n permissionLogic: formValue.permissionLogic ?? undefined,\n };\n\n if (this.isEditMode()) {\n await this.actionApi.updateAsync(dto);\n this.messageService.add({\n severity: 'success',\n summary: 'Success',\n detail: 'Action updated successfully.',\n });\n } else {\n await this.actionApi.insertAsync(dto);\n this.messageService.add({\n severity: 'success',\n summary: 'Success',\n detail: 'Action created successfully.',\n });\n }\n\n this.router.navigate(['/iam/actions']);\n } catch (error: any) {\n this.messageService.add({\n severity: 'error',\n summary: 'Error',\n detail: error.message || 'Failed to save action.',\n });\n } finally {\n this.isLoading.set(false);\n }\n }\n\n onBack(): void {\n this.router.navigate(['/iam/actions']);\n }\n\n /**\n * Handle permission logic changes from LogicBuilder\n */\n onLogicChange(logic: ILogicNode | null): void {\n this.formModel.update(model => ({\n ...model,\n permissionLogic: logic\n }));\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,282 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { inject, signal, effect, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
3
- import { Router } from '@angular/router';
4
- import { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';
5
- import { AngularModule, PrimeModule } from '@flusys/ng-shared';
6
- import * as i3 from 'primeng/api';
7
- import { MessageService, ConfirmationService } from 'primeng/api';
8
- import * as i2 from 'primeng/tag';
9
- import { TagModule } from 'primeng/tag';
10
- import { firstValueFrom } from 'rxjs';
11
- import { A as ActionApiService, c as convertActionToTreeNode, a as ActionType } from './flusys-ng-iam-flusys-ng-iam-D_i24Gub.mjs';
12
- import * as i3$1 from 'primeng/button';
13
- import * as i8 from 'primeng/treetable';
14
-
15
- /**
16
- * Action List Page Component
17
- *
18
- * Displays hierarchical tree of actions with search, filter, and CRUD operations
19
- */
20
- class ActionListPageComponent {
21
- router = inject(Router);
22
- companyContext = inject(LAYOUT_AUTH_STATE);
23
- actionApi = inject(ActionApiService);
24
- messageService = inject(MessageService);
25
- confirmationService = inject(ConfirmationService);
26
- isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
27
- treeNodes = signal([], ...(ngDevMode ? [{ debugName: "treeNodes" }] : []));
28
- constructor() {
29
- effect(() => {
30
- this.companyContext.currentCompanyInfo();
31
- untracked(() => this.loadActions());
32
- });
33
- }
34
- async loadActions() {
35
- this.isLoading.set(true);
36
- try {
37
- const response = await firstValueFrom(this.actionApi.getTree());
38
- const tree = response?.success ? response.data ?? [] : [];
39
- this.treeNodes.set(convertActionToTreeNode(tree));
40
- }
41
- catch (error) {
42
- console.error('[ActionListPage] Failed to load actions:', error);
43
- this.messageService.add({
44
- severity: 'error',
45
- summary: 'Error',
46
- detail: 'Failed to load actions',
47
- });
48
- }
49
- finally {
50
- this.isLoading.set(false);
51
- }
52
- }
53
- /**
54
- * Get action type label
55
- */
56
- getActionTypeLabel(type) {
57
- switch (type) {
58
- case ActionType.BACKEND:
59
- return 'Backend';
60
- case ActionType.FRONTEND:
61
- return 'Frontend';
62
- case ActionType.BOTH:
63
- return 'Both';
64
- default:
65
- return 'Unknown';
66
- }
67
- }
68
- /**
69
- * Get action type severity for tag styling
70
- */
71
- getActionTypeSeverity(type) {
72
- switch (type) {
73
- case ActionType.BACKEND:
74
- return 'info';
75
- case ActionType.FRONTEND:
76
- return 'success';
77
- case ActionType.BOTH:
78
- return 'warn';
79
- default:
80
- return 'info';
81
- }
82
- }
83
- onCreate() {
84
- this.router.navigate(['/iam/actions/new']);
85
- }
86
- onEdit(action) {
87
- this.router.navigate(['/iam/actions', action.id]);
88
- }
89
- onDelete(action) {
90
- if (!action?.id || !action?.name) {
91
- return;
92
- }
93
- this.confirmationService.confirm({
94
- message: `Are you sure you want to delete action "${action.name}"?`,
95
- header: 'Confirm Delete',
96
- icon: 'pi pi-exclamation-triangle',
97
- accept: async () => {
98
- try {
99
- await this.actionApi.deleteAsync({ id: action.id, type: 'delete' });
100
- await this.loadActions();
101
- this.messageService.add({
102
- severity: 'success',
103
- summary: 'Success',
104
- detail: 'Action deleted successfully',
105
- });
106
- }
107
- catch (error) {
108
- this.messageService.add({
109
- severity: 'error',
110
- summary: 'Error',
111
- detail: error instanceof Error ? error.message : 'Failed to delete action',
112
- });
113
- }
114
- },
115
- });
116
- }
117
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ActionListPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
118
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.0", type: ActionListPageComponent, isStandalone: true, selector: "lib-action-list-page", ngImport: i0, template: `
119
- <div class="card">
120
- <div class="flex justify-between items-center mb-4">
121
- <h3 class="text-xl font-semibold">Actions</h3>
122
- <p-button
123
- label="New Action"
124
- icon="pi pi-plus"
125
- (onClick)="onCreate()" />
126
- </div>
127
-
128
- <p-treeTable
129
- [value]="treeNodes()"
130
- [loading]="isLoading()"
131
- [scrollable]="true"
132
- scrollHeight="flex"
133
- dataKey="id"
134
- styleClass="p-treetable-sm">
135
- <ng-template pTemplate="header">
136
- <tr>
137
- <th>Name</th>
138
- <th>Code</th>
139
- <th>Action Type</th>
140
- <th>Active</th>
141
- <th>Read Only</th>
142
- <th style="width: 150px">Actions</th>
143
- </tr>
144
- </ng-template>
145
- <ng-template pTemplate="body" let-rowNode let-rowData="rowData">
146
- <tr>
147
- <td>
148
- <p-treeTableToggler [rowNode]="rowNode" />
149
- {{ rowData.name }}
150
- </td>
151
- <td>{{ rowData.code ?? '-' }}</td>
152
- <td>
153
- <p-tag
154
- [value]="getActionTypeLabel(rowData.actionType)"
155
- [severity]="getActionTypeSeverity(rowData.actionType)" />
156
- </td>
157
- <td>
158
- <p-tag
159
- [value]="rowData.isActive ? 'Active' : 'Inactive'"
160
- [severity]="rowData.isActive ? 'success' : 'secondary'" />
161
- </td>
162
- <td>
163
- <p-tag
164
- [value]="rowData.readOnly ? 'Yes' : 'No'"
165
- [severity]="rowData.readOnly ? 'warn' : 'secondary'" />
166
- </td>
167
- <td>
168
- <div class="flex gap-2">
169
- <p-button
170
- icon="pi pi-pencil"
171
- [outlined]="true"
172
- severity="info"
173
- size="small"
174
- (onClick)="onEdit(rowData)" />
175
- <p-button
176
- icon="pi pi-trash"
177
- [outlined]="true"
178
- severity="danger"
179
- size="small"
180
- [disabled]="rowData.readOnly"
181
- (onClick)="onDelete(rowData)" />
182
- </div>
183
- </td>
184
- </tr>
185
- </ng-template>
186
- <ng-template pTemplate="emptymessage">
187
- <tr>
188
- <td colspan="6" class="text-center">No actions found.</td>
189
- </tr>
190
- </ng-template>
191
- </p-treeTable>
192
- </div>
193
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i3$1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i8.TreeTable, selector: "p-treeTable, p-treetable, p-tree-table", inputs: ["columns", "styleClass", "tableStyle", "tableStyleClass", "autoLayout", "lazy", "lazyLoadOnInit", "paginator", "rows", "first", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "customSort", "selectionMode", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "compareSelectionBy", "rowHover", "loading", "loadingIcon", "showLoader", "scrollable", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "frozenColumns", "resizableColumns", "columnResizeMode", "reorderableColumns", "contextMenu", "rowTrackBy", "filters", "globalFilterFields", "filterDelay", "filterMode", "filterLocale", "paginatorLocale", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "value", "virtualRowHeight", "selectionKeys", "showGridlines"], outputs: ["selectionChange", "contextMenuSelectionChange", "onFilter", "onNodeExpand", "onNodeCollapse", "onPage", "onSort", "onLazyLoad", "sortFunction", "onColResize", "onColReorder", "onNodeSelect", "onNodeUnselect", "onContextMenuSelect", "onHeaderCheckboxToggle", "onEditInit", "onEditComplete", "onEditCancel", "selectionKeysChange"] }, { kind: "component", type: i8.TreeTableToggler, selector: "p-treeTableToggler, p-treetabletoggler, p-treetable-toggler", inputs: ["rowNode"] }, { kind: "ngmodule", type: TagModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
194
- }
195
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ActionListPageComponent, decorators: [{
196
- type: Component,
197
- args: [{
198
- selector: 'lib-action-list-page',
199
- standalone: true,
200
- imports: [AngularModule, PrimeModule, TagModule],
201
- changeDetection: ChangeDetectionStrategy.OnPush,
202
- template: `
203
- <div class="card">
204
- <div class="flex justify-between items-center mb-4">
205
- <h3 class="text-xl font-semibold">Actions</h3>
206
- <p-button
207
- label="New Action"
208
- icon="pi pi-plus"
209
- (onClick)="onCreate()" />
210
- </div>
211
-
212
- <p-treeTable
213
- [value]="treeNodes()"
214
- [loading]="isLoading()"
215
- [scrollable]="true"
216
- scrollHeight="flex"
217
- dataKey="id"
218
- styleClass="p-treetable-sm">
219
- <ng-template pTemplate="header">
220
- <tr>
221
- <th>Name</th>
222
- <th>Code</th>
223
- <th>Action Type</th>
224
- <th>Active</th>
225
- <th>Read Only</th>
226
- <th style="width: 150px">Actions</th>
227
- </tr>
228
- </ng-template>
229
- <ng-template pTemplate="body" let-rowNode let-rowData="rowData">
230
- <tr>
231
- <td>
232
- <p-treeTableToggler [rowNode]="rowNode" />
233
- {{ rowData.name }}
234
- </td>
235
- <td>{{ rowData.code ?? '-' }}</td>
236
- <td>
237
- <p-tag
238
- [value]="getActionTypeLabel(rowData.actionType)"
239
- [severity]="getActionTypeSeverity(rowData.actionType)" />
240
- </td>
241
- <td>
242
- <p-tag
243
- [value]="rowData.isActive ? 'Active' : 'Inactive'"
244
- [severity]="rowData.isActive ? 'success' : 'secondary'" />
245
- </td>
246
- <td>
247
- <p-tag
248
- [value]="rowData.readOnly ? 'Yes' : 'No'"
249
- [severity]="rowData.readOnly ? 'warn' : 'secondary'" />
250
- </td>
251
- <td>
252
- <div class="flex gap-2">
253
- <p-button
254
- icon="pi pi-pencil"
255
- [outlined]="true"
256
- severity="info"
257
- size="small"
258
- (onClick)="onEdit(rowData)" />
259
- <p-button
260
- icon="pi pi-trash"
261
- [outlined]="true"
262
- severity="danger"
263
- size="small"
264
- [disabled]="rowData.readOnly"
265
- (onClick)="onDelete(rowData)" />
266
- </div>
267
- </td>
268
- </tr>
269
- </ng-template>
270
- <ng-template pTemplate="emptymessage">
271
- <tr>
272
- <td colspan="6" class="text-center">No actions found.</td>
273
- </tr>
274
- </ng-template>
275
- </p-treeTable>
276
- </div>
277
- `,
278
- }]
279
- }], ctorParameters: () => [] });
280
-
281
- export { ActionListPageComponent };
282
- //# sourceMappingURL=flusys-ng-iam-action-list-page.component-CCp7M7xo.mjs.map