@flusys/ng-iam 1.0.0-beta → 1.1.0-beta

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 (17) hide show
  1. package/README.md +51 -1
  2. package/fesm2022/{flusys-ng-iam-action-form-page.component-0b9GwJqa.mjs → flusys-ng-iam-action-form-page.component-DBJzC5GS.mjs} +5 -5
  3. package/fesm2022/{flusys-ng-iam-action-form-page.component-0b9GwJqa.mjs.map → flusys-ng-iam-action-form-page.component-DBJzC5GS.mjs.map} +1 -1
  4. package/fesm2022/{flusys-ng-iam-action-list-page.component-BpvewEGL.mjs → flusys-ng-iam-action-list-page.component-Dfts0JCt.mjs} +6 -6
  5. package/fesm2022/{flusys-ng-iam-action-list-page.component-BpvewEGL.mjs.map → flusys-ng-iam-action-list-page.component-Dfts0JCt.mjs.map} +1 -1
  6. package/fesm2022/{flusys-ng-iam-flusys-ng-iam-C-MQjakK.mjs → flusys-ng-iam-flusys-ng-iam-BjdM-Vgz.mjs} +103 -22
  7. package/fesm2022/flusys-ng-iam-flusys-ng-iam-BjdM-Vgz.mjs.map +1 -0
  8. package/fesm2022/{flusys-ng-iam-permission-page.component-e_RX5mky.mjs → flusys-ng-iam-permission-page.component-cDrwUAQ_.mjs} +4 -4
  9. package/fesm2022/{flusys-ng-iam-permission-page.component-e_RX5mky.mjs.map → flusys-ng-iam-permission-page.component-cDrwUAQ_.mjs.map} +1 -1
  10. package/fesm2022/{flusys-ng-iam-role-form-page.component-eZM1EPps.mjs → flusys-ng-iam-role-form-page.component-Ctigzpon.mjs} +5 -5
  11. package/fesm2022/{flusys-ng-iam-role-form-page.component-eZM1EPps.mjs.map → flusys-ng-iam-role-form-page.component-Ctigzpon.mjs.map} +1 -1
  12. package/fesm2022/{flusys-ng-iam-role-list-page.component-BgzxmHjk.mjs → flusys-ng-iam-role-list-page.component-BF-Z_TQK.mjs} +6 -6
  13. package/fesm2022/{flusys-ng-iam-role-list-page.component-BgzxmHjk.mjs.map → flusys-ng-iam-role-list-page.component-BF-Z_TQK.mjs.map} +1 -1
  14. package/fesm2022/flusys-ng-iam.mjs +1 -1
  15. package/package.json +4 -4
  16. package/types/flusys-ng-iam.d.ts +48 -3
  17. package/fesm2022/flusys-ng-iam-flusys-ng-iam-C-MQjakK.mjs.map +0 -1
package/README.md CHANGED
@@ -1015,6 +1015,56 @@ IAM_PERMISSION_MODE=FULL # DIRECT, RBAC, or FULL
1015
1015
 
1016
1016
  ---
1017
1017
 
1018
+ ## Provider Functions
1019
+
1020
+ ### provideIamProviders()
1021
+
1022
+ Registers provider adapters that enable other packages (ng-auth) to access IAM functionality without direct dependencies.
1023
+
1024
+ ```typescript
1025
+ import { provideIamProviders } from '@flusys/ng-iam';
1026
+
1027
+ // app.config.ts
1028
+ export const appConfig: ApplicationConfig = {
1029
+ providers: [
1030
+ ...provideIamProviders(), // Register IAM providers
1031
+ ],
1032
+ };
1033
+ ```
1034
+
1035
+ **Registers:**
1036
+
1037
+ | Token | Adapter | Purpose |
1038
+ |-------|---------|---------|
1039
+ | `PROFILE_PERMISSION_PROVIDER` | `ProfilePermissionProviderAdapter` | User roles/actions for profile page |
1040
+
1041
+ ### ProfilePermissionProviderAdapter
1042
+
1043
+ Implements `IProfilePermissionProvider` from ng-shared. Enables ng-auth's profile page to display user permissions.
1044
+
1045
+ ```typescript
1046
+ interface IProfilePermissionProvider {
1047
+ getUserRoles(userId: string, branchId?: string): Observable<ISingleResponse<IProfileRoleInfo[]>>;
1048
+ getUserActions(userId: string, branchId?: string): Observable<ISingleResponse<IProfileActionInfo[]>>;
1049
+ }
1050
+ ```
1051
+
1052
+ **Usage in ng-auth profile page:**
1053
+
1054
+ ```typescript
1055
+ // Optional injection - graceful degradation when IAM disabled
1056
+ private readonly permissionProvider = inject(PROFILE_PERMISSION_PROVIDER, { optional: true });
1057
+
1058
+ // Load user permissions
1059
+ if (this.permissionProvider) {
1060
+ this.permissionProvider.getUserRoles(userId, branchId).subscribe(response => {
1061
+ this.roles.set(response.data ?? []);
1062
+ });
1063
+ }
1064
+ ```
1065
+
1066
+ ---
1067
+
1018
1068
  ## See Also
1019
1069
 
1020
1070
  - **[CORE-GUIDE.md](./CORE-GUIDE.md)** - Configuration system (APP_CONFIG)
@@ -1024,5 +1074,5 @@ IAM_PERMISSION_MODE=FULL # DIRECT, RBAC, or FULL
1024
1074
 
1025
1075
  ---
1026
1076
 
1027
- **Last Updated:** 2026-02-15
1077
+ **Last Updated:** 2026-02-16
1028
1078
  **Angular Version:** 21
@@ -5,10 +5,10 @@ import { ActivatedRoute, Router } from '@angular/router';
5
5
  import { AngularModule, PrimeModule } from '@flusys/ng-shared';
6
6
  import { MessageService } from 'primeng/api';
7
7
  import { firstValueFrom } from 'rxjs';
8
- import { A as ActionApiService, a as ActionType, L as LogicBuilderComponent } from './flusys-ng-iam-flusys-ng-iam-C-MQjakK.mjs';
8
+ import { A as ActionApiService, a as ActionType, L as LogicBuilderComponent } from './flusys-ng-iam-flusys-ng-iam-BjdM-Vgz.mjs';
9
9
  import * as i1 from '@angular/forms';
10
- import * as i2 from 'primeng/inputtext';
11
- import * as i3 from 'primeng/button';
10
+ import * as i2 from 'primeng/button';
11
+ import * as i3 from 'primeng/inputtext';
12
12
 
13
13
  /**
14
14
  * Action Form Page Component
@@ -329,7 +329,7 @@ class ActionFormPageComponent {
329
329
  </div>
330
330
  </form>
331
331
  </div>
332
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "directive", type: i2.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: i3.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "component", type: LogicBuilderComponent, selector: "lib-logic-builder", inputs: ["logic", "actions"], outputs: ["logicChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
332
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "component", type: LogicBuilderComponent, selector: "lib-logic-builder", inputs: ["logic", "actions"], outputs: ["logicChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
333
333
  }
334
334
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ActionFormPageComponent, decorators: [{
335
335
  type: Component,
@@ -464,4 +464,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
464
464
  }] });
465
465
 
466
466
  export { ActionFormPageComponent };
467
- //# sourceMappingURL=flusys-ng-iam-action-form-page.component-0b9GwJqa.mjs.map
467
+ //# sourceMappingURL=flusys-ng-iam-action-form-page.component-DBJzC5GS.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"flusys-ng-iam-action-form-page.component-0b9GwJqa.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 {\n // Actions load failed - form will show empty parent dropdown\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 {\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":";;;;;;;;;;;;AAwBA;;;AAGG;MAiIU,uBAAuB,CAAA;AACjB,IAAA,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC;AAC9B,IAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AACvB,IAAA,SAAS,GAAG,MAAM,CAAC,gBAAgB,CAAC;AACpC,IAAA,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC;;AAG/C,IAAA,SAAS,GAAG,MAAM,CAAC,KAAK,qDAAC;;AAGzB,IAAA,cAAc,GAAG,MAAM,CAAiB,IAAI,0DAAC;;AAG7C,IAAA,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,sDAAC;;AAGpD,IAAA,kBAAkB,GAAG,MAAM,CAAsC,EAAE,8DAAC;;AAGpE,IAAA,UAAU,GAAG,MAAM,CAAY,EAAE,sDAAC;;AAGlC,IAAA,gBAAgB,GAAG,QAAQ,CAAC,MAAK;AACxC,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE;QACjC,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,EAAE,EAAE,EAAE;QAC3C,OAAO,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,GAAG,OAAO;AACtE,IAAA,CAAC,4DAAC;;;;;IAOO,SAAS,GAAG,MAAM,CAAmB;AAC5C,QAAA,EAAE,EAAE,EAAE;AACN,QAAA,IAAI,EAAE,EAAE;AACR,QAAA,WAAW,EAAE,EAAE;AACf,QAAA,IAAI,EAAE,EAAE;QACR,UAAU,EAAE,UAAU,CAAC,OAAO;AAC9B,QAAA,eAAe,EAAE,IAAI;AACrB,QAAA,QAAQ,EAAE,EAAE;AACZ,QAAA,MAAM,EAAE,EAAE;AACV,QAAA,QAAQ,EAAE,IAAI;AACd,QAAA,QAAQ,EAAE,IAAI;AACf,KAAA,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,WAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAC;;AAGO,IAAA,WAAW,GAAG;QACrB,EAAE,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,UAAU,CAAC,OAAO,EAAE;QAC/D,EAAE,KAAK,EAAE,wBAAwB,EAAE,KAAK,EAAE,UAAU,CAAC,QAAQ,EAAE;QAC/D,EAAE,KAAK,EAAE,2BAA2B,EAAE,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE;KAC/D;;IAGQ,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,KAAI;QAC/C,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC;AACnD,IAAA,CAAC,CAAC;;AAGO,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAK;AACnC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE;QAC9B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;AACrC,IAAA,CAAC,uDAAC;AAEF,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;;AAGjD,QAAA,IAAI;AACF,YAAA,MAAM,QAAQ,GAAG,MAAM,cAAc,CACnC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE;gBACxB,UAAU,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAC/C,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,iBAAiB,CAAC;AAChE,aAAA,CAAC,CACH;YAED,IAAI,QAAQ,EAAE,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;;AAEtC,gBAAA,IAAI,CAAC,kBAAkB,CAAC,GAAG,CACzB,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,EAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,SAAS,EAAE,CAAC,CAAC,CACnE;;gBAGD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;YACpC;QACF;AAAE,QAAA,MAAM;;QAER;;AAGA,QAAA,IAAI,EAAE,IAAI,EAAE,KAAK,KAAK,EAAE;AACtB,YAAA,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B;IACF;IAEA,MAAM,UAAU,CAAC,EAAU,EAAA;AACzB,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;AACxB,QAAA,IAAI;;YAEF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,EAAE;gBACtD,IAAI;gBACJ,MAAM;gBACN,aAAa;gBACb,MAAM;gBACN,YAAY;gBACZ,iBAAiB;gBACjB,UAAU;gBACV,QAAQ;gBACR,UAAU;gBACV,UAAU;AACX,aAAA,CAAC;YAEF,IAAI,QAAQ,EAAE,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;AACtC,gBAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI;;AAG5B,gBAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC;;AAG/B,gBAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;AACjB,oBAAA,EAAE,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE;AACnB,oBAAA,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE;AACvB,oBAAA,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE;AACrC,oBAAA,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE;AACvB,oBAAA,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,UAAU,CAAC,OAAO;AACnD,oBAAA,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,IAAI;AAC/C,oBAAA,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE;oBAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;AACvC,oBAAA,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,IAAI;AACjC,oBAAA,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,IAAI;AAClC,iBAAA,CAAC;YACJ;iBAAO;AACL,gBAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC;AACtB,oBAAA,QAAQ,EAAE,OAAO;AACjB,oBAAA,OAAO,EAAE,OAAO;AAChB,oBAAA,MAAM,EAAE,mBAAmB;AAC5B,iBAAA,CAAC;gBACF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,CAAC;YACxC;QACF;AAAE,QAAA,MAAM;AACN,YAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC;AACtB,gBAAA,QAAQ,EAAE,OAAO;AACjB,gBAAA,OAAO,EAAE,OAAO;AAChB,gBAAA,MAAM,EAAE,wBAAwB;AACjC,aAAA,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,CAAC;QACxC;gBAAU;AACR,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;QAC3B;IACF;AAEA,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE;AACvB,YAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC;AACtB,gBAAA,QAAQ,EAAE,OAAO;AACjB,gBAAA,OAAO,EAAE,kBAAkB;AAC3B,gBAAA,MAAM,EAAE,qCAAqC;AAC9C,aAAA,CAAC;YACF;QACF;AAEA,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;AAExB,QAAA,IAAI;AACF,YAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE;;AAGlC,YAAA,MAAM,GAAG,GAAG;AACV,gBAAA,GAAG,SAAS;AACZ,gBAAA,WAAW,EAAE,SAAS,CAAC,WAAW,IAAI,SAAS;AAC/C,gBAAA,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,SAAS;AACjC,gBAAA,QAAQ,EAAE,SAAS,CAAC,QAAQ,IAAI,SAAS;AACzC,gBAAA,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,SAAS;AACrE,gBAAA,QAAQ,EAAE,SAAS,CAAC,QAAQ,IAAI,SAAS;AACzC,gBAAA,eAAe,EAAE,SAAS,CAAC,eAAe,IAAI,SAAS;aACxD;AAED,YAAA,IAAI,IAAI,CAAC,UAAU,EAAE,EAAE;gBACrB,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC;AACrC,gBAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC;AACtB,oBAAA,QAAQ,EAAE,SAAS;AACnB,oBAAA,OAAO,EAAE,SAAS;AAClB,oBAAA,MAAM,EAAE,8BAA8B;AACvC,iBAAA,CAAC;YACJ;iBAAO;gBACL,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC;AACrC,gBAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC;AACtB,oBAAA,QAAQ,EAAE,SAAS;AACnB,oBAAA,OAAO,EAAE,SAAS;AAClB,oBAAA,MAAM,EAAE,8BAA8B;AACvC,iBAAA,CAAC;YACJ;YAEA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,CAAC;QACxC;QAAE,OAAO,KAAU,EAAE;AACnB,YAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC;AACtB,gBAAA,QAAQ,EAAE,OAAO;AACjB,gBAAA,OAAO,EAAE,OAAO;AAChB,gBAAA,MAAM,EAAE,KAAK,CAAC,OAAO,IAAI,wBAAwB;AAClD,aAAA,CAAC;QACJ;gBAAU;AACR,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;QAC3B;IACF;IAEA,MAAM,GAAA;QACJ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,CAAC;IACxC;AAEA;;AAEG;AACH,IAAA,aAAa,CAAC,KAAwB,EAAA;QACpC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,KAAK;AAC9B,YAAA,GAAG,KAAK;AACR,YAAA,eAAe,EAAE;AAClB,SAAA,CAAC,CAAC;IACL;uGAzNW,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAvB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,uBAAuB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA3HxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyHT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EA3HS,aAAa,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,8CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,sGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,QAAA,EAAA,yEAAA,EAAA,MAAA,EAAA,CAAA,eAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,SAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,aAAA,EAAA,cAAA,EAAA,oBAAA,EAAA,OAAA,EAAA,SAAA,EAAA,OAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,MAAA,EAAA,OAAA,EAAA,UAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,OAAA,EAAA,UAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,SAAA,EAAA,OAAA,EAAA,YAAA,EAAA,YAAA,EAAA,eAAA,EAAA,WAAA,EAAA,WAAA,EAAA,SAAA,EAAA,MAAA,EAAA,OAAA,EAAA,SAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,OAAA,CAAA,EAAA,OAAA,EAAA,CAAA,SAAA,EAAA,SAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,SAAS,+EAAE,qBAAqB,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,aAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FA6H3D,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBAhInC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,sBAAsB;AAChC,oBAAA,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,qBAAqB,CAAC;oBACvE,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyHT,EAAA,CAAA;AACF,iBAAA;;;;;"}
1
+ {"version":3,"file":"flusys-ng-iam-action-form-page.component-DBJzC5GS.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 {\n // Actions load failed - form will show empty parent dropdown\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 {\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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"}
@@ -3,13 +3,13 @@ import { inject, signal, effect, untracked, ChangeDetectionStrategy, Component }
3
3
  import { Router } from '@angular/router';
4
4
  import { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';
5
5
  import { AngularModule, PrimeModule } from '@flusys/ng-shared';
6
- import * as i3 from 'primeng/api';
6
+ import * as i2 from 'primeng/api';
7
7
  import { MessageService, ConfirmationService } from 'primeng/api';
8
- import * as i2 from 'primeng/tag';
8
+ import * as i6 from 'primeng/tag';
9
9
  import { TagModule } from 'primeng/tag';
10
10
  import { firstValueFrom } from 'rxjs';
11
- import { A as ActionApiService, c as convertActionToTreeNode, a as ActionType } from './flusys-ng-iam-flusys-ng-iam-C-MQjakK.mjs';
12
- import * as i3$1 from 'primeng/button';
11
+ import { A as ActionApiService, c as convertActionToTreeNode, a as ActionType } from './flusys-ng-iam-flusys-ng-iam-BjdM-Vgz.mjs';
12
+ import * as i2$1 from 'primeng/button';
13
13
  import * as i8 from 'primeng/treetable';
14
14
 
15
15
  /**
@@ -189,7 +189,7 @@ class ActionListPageComponent {
189
189
  </ng-template>
190
190
  </p-treeTable>
191
191
  </div>
192
- `, 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 });
192
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "ngmodule", type: PrimeModule }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i2$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: i6.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { 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 });
193
193
  }
194
194
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ActionListPageComponent, decorators: [{
195
195
  type: Component,
@@ -278,4 +278,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
278
278
  }], ctorParameters: () => [] });
279
279
 
280
280
  export { ActionListPageComponent };
281
- //# sourceMappingURL=flusys-ng-iam-action-list-page.component-BpvewEGL.mjs.map
281
+ //# sourceMappingURL=flusys-ng-iam-action-list-page.component-Dfts0JCt.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"flusys-ng-iam-action-list-page.component-BpvewEGL.mjs","sources":["../../../projects/ng-iam/pages/action/action-list-page.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, effect, inject, signal, untracked } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';\nimport { AngularModule, PrimeModule } from '@flusys/ng-shared';\nimport { MessageService, ConfirmationService, TreeNode } from 'primeng/api';\nimport { TagModule } from 'primeng/tag';\nimport { firstValueFrom } from 'rxjs';\nimport { ActionApiService } from '../../services/action-api.service';\nimport { ActionType, IAction } from '../../interfaces/action.interface';\nimport { convertActionToTreeNode } from '../../utils/tree-utils';\n\n/**\n * Action List Page Component\n *\n * Displays hierarchical tree of actions with search, filter, and CRUD operations\n */\n@Component({\n selector: 'lib-action-list-page',\n standalone: true,\n imports: [AngularModule, PrimeModule, TagModule],\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\">Actions</h3>\n <p-button\n label=\"New Action\"\n icon=\"pi pi-plus\"\n (onClick)=\"onCreate()\" />\n </div>\n\n <p-treeTable\n [value]=\"treeNodes()\"\n [loading]=\"isLoading()\"\n [scrollable]=\"true\"\n scrollHeight=\"flex\"\n dataKey=\"id\"\n styleClass=\"p-treetable-sm\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th>Name</th>\n <th>Code</th>\n <th>Action Type</th>\n <th>Active</th>\n <th>Read Only</th>\n <th style=\"width: 150px\">Actions</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-rowNode let-rowData=\"rowData\">\n <tr>\n <td>\n <p-treeTableToggler [rowNode]=\"rowNode\" />\n {{ rowData.name }}\n </td>\n <td>{{ rowData.code ?? '-' }}</td>\n <td>\n <p-tag\n [value]=\"getActionTypeLabel(rowData.actionType)\"\n [severity]=\"getActionTypeSeverity(rowData.actionType)\" />\n </td>\n <td>\n <p-tag\n [value]=\"rowData.isActive ? 'Active' : 'Inactive'\"\n [severity]=\"rowData.isActive ? 'success' : 'secondary'\" />\n </td>\n <td>\n <p-tag\n [value]=\"rowData.readOnly ? 'Yes' : 'No'\"\n [severity]=\"rowData.readOnly ? 'warn' : 'secondary'\" />\n </td>\n <td>\n <div class=\"flex gap-2\">\n <p-button\n icon=\"pi pi-pencil\"\n [outlined]=\"true\"\n severity=\"info\"\n size=\"small\"\n (onClick)=\"onEdit(rowData)\" />\n <p-button\n icon=\"pi pi-trash\"\n [outlined]=\"true\"\n severity=\"danger\"\n size=\"small\"\n [disabled]=\"rowData.readOnly\"\n (onClick)=\"onDelete(rowData)\" />\n </div>\n </td>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"emptymessage\">\n <tr>\n <td colspan=\"6\" class=\"text-center\">No actions found.</td>\n </tr>\n </ng-template>\n </p-treeTable>\n </div>\n `,\n})\nexport class ActionListPageComponent {\n private readonly router = inject(Router);\n private readonly companyContext = inject(LAYOUT_AUTH_STATE);\n private readonly actionApi = inject(ActionApiService);\n private readonly messageService = inject(MessageService);\n private readonly confirmationService = inject(ConfirmationService);\n\n readonly isLoading = signal(false);\n readonly treeNodes = signal<TreeNode<IAction>[]>([]);\n\n constructor() {\n effect(() => {\n this.companyContext.currentCompanyInfo();\n untracked(() => this.loadActions());\n });\n }\n\n private async loadActions(): Promise<void> {\n this.isLoading.set(true);\n try {\n const response = await firstValueFrom(this.actionApi.getTree());\n const tree = response?.success ? response.data ?? [] : [];\n this.treeNodes.set(convertActionToTreeNode(tree));\n } catch {\n this.messageService.add({\n severity: 'error',\n summary: 'Error',\n detail: 'Failed to load actions',\n });\n } finally {\n this.isLoading.set(false);\n }\n }\n\n /**\n * Get action type label\n */\n getActionTypeLabel(type: ActionType): string {\n switch (type) {\n case ActionType.BACKEND:\n return 'Backend';\n case ActionType.FRONTEND:\n return 'Frontend';\n case ActionType.BOTH:\n return 'Both';\n default:\n return 'Unknown';\n }\n }\n\n /**\n * Get action type severity for tag styling\n */\n getActionTypeSeverity(type: ActionType): 'info' | 'success' | 'warn' {\n switch (type) {\n case ActionType.BACKEND:\n return 'info';\n case ActionType.FRONTEND:\n return 'success';\n case ActionType.BOTH:\n return 'warn';\n default:\n return 'info';\n }\n }\n\n onCreate(): void {\n this.router.navigate(['/iam/actions/new']);\n }\n\n onEdit(action: IAction): void {\n this.router.navigate(['/iam/actions', action.id]);\n }\n\n onDelete(action: IAction): void {\n if (!action?.id || !action?.name) {\n return;\n }\n\n this.confirmationService.confirm({\n message: `Are you sure you want to delete action \"${action.name}\"?`,\n header: 'Confirm Delete',\n icon: 'pi pi-exclamation-triangle',\n accept: async () => {\n try {\n await this.actionApi.deleteAsync({ id: action.id, type: 'delete' });\n await this.loadActions();\n this.messageService.add({\n severity: 'success',\n summary: 'Success',\n detail: 'Action deleted successfully',\n });\n } catch (error) {\n this.messageService.add({\n severity: 'error',\n summary: 'Error',\n detail: error instanceof Error ? error.message : 'Failed to delete action',\n });\n }\n },\n });\n }\n}\n"],"names":["i1","i2","i3","i4"],"mappings":"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"}
1
+ {"version":3,"file":"flusys-ng-iam-action-list-page.component-Dfts0JCt.mjs","sources":["../../../projects/ng-iam/pages/action/action-list-page.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, effect, inject, signal, untracked } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';\nimport { AngularModule, PrimeModule } from '@flusys/ng-shared';\nimport { MessageService, ConfirmationService, TreeNode } from 'primeng/api';\nimport { TagModule } from 'primeng/tag';\nimport { firstValueFrom } from 'rxjs';\nimport { ActionApiService } from '../../services/action-api.service';\nimport { ActionType, IAction } from '../../interfaces/action.interface';\nimport { convertActionToTreeNode } from '../../utils/tree-utils';\n\n/**\n * Action List Page Component\n *\n * Displays hierarchical tree of actions with search, filter, and CRUD operations\n */\n@Component({\n selector: 'lib-action-list-page',\n standalone: true,\n imports: [AngularModule, PrimeModule, TagModule],\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\">Actions</h3>\n <p-button\n label=\"New Action\"\n icon=\"pi pi-plus\"\n (onClick)=\"onCreate()\" />\n </div>\n\n <p-treeTable\n [value]=\"treeNodes()\"\n [loading]=\"isLoading()\"\n [scrollable]=\"true\"\n scrollHeight=\"flex\"\n dataKey=\"id\"\n styleClass=\"p-treetable-sm\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th>Name</th>\n <th>Code</th>\n <th>Action Type</th>\n <th>Active</th>\n <th>Read Only</th>\n <th style=\"width: 150px\">Actions</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-rowNode let-rowData=\"rowData\">\n <tr>\n <td>\n <p-treeTableToggler [rowNode]=\"rowNode\" />\n {{ rowData.name }}\n </td>\n <td>{{ rowData.code ?? '-' }}</td>\n <td>\n <p-tag\n [value]=\"getActionTypeLabel(rowData.actionType)\"\n [severity]=\"getActionTypeSeverity(rowData.actionType)\" />\n </td>\n <td>\n <p-tag\n [value]=\"rowData.isActive ? 'Active' : 'Inactive'\"\n [severity]=\"rowData.isActive ? 'success' : 'secondary'\" />\n </td>\n <td>\n <p-tag\n [value]=\"rowData.readOnly ? 'Yes' : 'No'\"\n [severity]=\"rowData.readOnly ? 'warn' : 'secondary'\" />\n </td>\n <td>\n <div class=\"flex gap-2\">\n <p-button\n icon=\"pi pi-pencil\"\n [outlined]=\"true\"\n severity=\"info\"\n size=\"small\"\n (onClick)=\"onEdit(rowData)\" />\n <p-button\n icon=\"pi pi-trash\"\n [outlined]=\"true\"\n severity=\"danger\"\n size=\"small\"\n [disabled]=\"rowData.readOnly\"\n (onClick)=\"onDelete(rowData)\" />\n </div>\n </td>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"emptymessage\">\n <tr>\n <td colspan=\"6\" class=\"text-center\">No actions found.</td>\n </tr>\n </ng-template>\n </p-treeTable>\n </div>\n `,\n})\nexport class ActionListPageComponent {\n private readonly router = inject(Router);\n private readonly companyContext = inject(LAYOUT_AUTH_STATE);\n private readonly actionApi = inject(ActionApiService);\n private readonly messageService = inject(MessageService);\n private readonly confirmationService = inject(ConfirmationService);\n\n readonly isLoading = signal(false);\n readonly treeNodes = signal<TreeNode<IAction>[]>([]);\n\n constructor() {\n effect(() => {\n this.companyContext.currentCompanyInfo();\n untracked(() => this.loadActions());\n });\n }\n\n private async loadActions(): Promise<void> {\n this.isLoading.set(true);\n try {\n const response = await firstValueFrom(this.actionApi.getTree());\n const tree = response?.success ? response.data ?? [] : [];\n this.treeNodes.set(convertActionToTreeNode(tree));\n } catch {\n this.messageService.add({\n severity: 'error',\n summary: 'Error',\n detail: 'Failed to load actions',\n });\n } finally {\n this.isLoading.set(false);\n }\n }\n\n /**\n * Get action type label\n */\n getActionTypeLabel(type: ActionType): string {\n switch (type) {\n case ActionType.BACKEND:\n return 'Backend';\n case ActionType.FRONTEND:\n return 'Frontend';\n case ActionType.BOTH:\n return 'Both';\n default:\n return 'Unknown';\n }\n }\n\n /**\n * Get action type severity for tag styling\n */\n getActionTypeSeverity(type: ActionType): 'info' | 'success' | 'warn' {\n switch (type) {\n case ActionType.BACKEND:\n return 'info';\n case ActionType.FRONTEND:\n return 'success';\n case ActionType.BOTH:\n return 'warn';\n default:\n return 'info';\n }\n }\n\n onCreate(): void {\n this.router.navigate(['/iam/actions/new']);\n }\n\n onEdit(action: IAction): void {\n this.router.navigate(['/iam/actions', action.id]);\n }\n\n onDelete(action: IAction): void {\n if (!action?.id || !action?.name) {\n return;\n }\n\n this.confirmationService.confirm({\n message: `Are you sure you want to delete action \"${action.name}\"?`,\n header: 'Confirm Delete',\n icon: 'pi pi-exclamation-triangle',\n accept: async () => {\n try {\n await this.actionApi.deleteAsync({ id: action.id, type: 'delete' });\n await this.loadActions();\n this.messageService.add({\n severity: 'success',\n summary: 'Success',\n detail: 'Action deleted successfully',\n });\n } catch (error) {\n this.messageService.add({\n severity: 'error',\n summary: 'Error',\n detail: error instanceof Error ? error.message : 'Failed to delete action',\n });\n }\n },\n });\n }\n}\n"],"names":["i1","i2","i3","i4"],"mappings":"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"}