@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.
- package/README.md +225 -25
- package/fesm2022/{flusys-ng-iam-action-form-page.component-BVWZMlLU.mjs → flusys-ng-iam-action-form-page.component-C_BRrrWW.mjs} +181 -210
- package/fesm2022/flusys-ng-iam-action-form-page.component-C_BRrrWW.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam-action-list-page.component-Daf93zpS.mjs +289 -0
- package/fesm2022/flusys-ng-iam-action-list-page.component-Daf93zpS.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-flusys-ng-iam-D_i24Gub.mjs → flusys-ng-iam-flusys-ng-iam-BPIpfrjN.mjs} +967 -1087
- package/fesm2022/flusys-ng-iam-flusys-ng-iam-BPIpfrjN.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam-iam-container.component-Bn4kQtxW.mjs +92 -0
- package/fesm2022/flusys-ng-iam-iam-container.component-Bn4kQtxW.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-permission-page.component-C0yLMdW5.mjs → flusys-ng-iam-permission-page.component-CmxOBJPu.mjs} +45 -16
- package/fesm2022/flusys-ng-iam-permission-page.component-CmxOBJPu.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-role-form-page.component-Co6bbHik.mjs → flusys-ng-iam-role-form-page.component-ByNueI1a.mjs} +110 -138
- package/fesm2022/flusys-ng-iam-role-form-page.component-ByNueI1a.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam-role-list-page.component-CFly5KnH.mjs +316 -0
- package/fesm2022/flusys-ng-iam-role-list-page.component-CFly5KnH.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam.mjs +1 -1
- package/package.json +5 -5
- package/types/flusys-ng-iam.d.ts +89 -37
- package/fesm2022/flusys-ng-iam-action-form-page.component-BVWZMlLU.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-action-list-page.component-CCp7M7xo.mjs +0 -282
- package/fesm2022/flusys-ng-iam-action-list-page.component-CCp7M7xo.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-flusys-ng-iam-D_i24Gub.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-iam-container.component-BFKoNtdz.mjs +0 -97
- package/fesm2022/flusys-ng-iam-iam-container.component-BFKoNtdz.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-permission-page.component-C0yLMdW5.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-role-form-page.component-Co6bbHik.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-role-list-page.component-KJUVOrf0.mjs +0 -267
- package/fesm2022/flusys-ng-iam-role-list-page.component-KJUVOrf0.mjs.map +0 -1
package/types/flusys-ng-iam.d.ts
CHANGED
|
@@ -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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|