@flusys/ng-iam 1.0.0-rc → 1.1.1-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 (28) hide show
  1. package/README.md +24 -175
  2. package/fesm2022/{flusys-ng-iam-action-form-page.component-C_BRrrWW.mjs → flusys-ng-iam-action-form-page.component-C1j10Qhw.mjs} +202 -174
  3. package/fesm2022/flusys-ng-iam-action-form-page.component-C1j10Qhw.mjs.map +1 -0
  4. package/fesm2022/flusys-ng-iam-action-list-page.component-BCzSardO.mjs +281 -0
  5. package/fesm2022/flusys-ng-iam-action-list-page.component-BCzSardO.mjs.map +1 -0
  6. package/fesm2022/{flusys-ng-iam-flusys-ng-iam-BPIpfrjN.mjs → flusys-ng-iam-flusys-ng-iam-DISrddPh.mjs} +829 -822
  7. package/fesm2022/flusys-ng-iam-flusys-ng-iam-DISrddPh.mjs.map +1 -0
  8. package/fesm2022/flusys-ng-iam-iam-container.component-BkhqmzLi.mjs +97 -0
  9. package/fesm2022/flusys-ng-iam-iam-container.component-BkhqmzLi.mjs.map +1 -0
  10. package/fesm2022/{flusys-ng-iam-permission-page.component-CmxOBJPu.mjs → flusys-ng-iam-permission-page.component-BSQFPt_N.mjs} +12 -41
  11. package/fesm2022/flusys-ng-iam-permission-page.component-BSQFPt_N.mjs.map +1 -0
  12. package/fesm2022/{flusys-ng-iam-role-form-page.component-ByNueI1a.mjs → flusys-ng-iam-role-form-page.component-Cqziu_BM.mjs} +134 -106
  13. package/fesm2022/flusys-ng-iam-role-form-page.component-Cqziu_BM.mjs.map +1 -0
  14. package/fesm2022/flusys-ng-iam-role-list-page.component-BObCxHiB.mjs +266 -0
  15. package/fesm2022/flusys-ng-iam-role-list-page.component-BObCxHiB.mjs.map +1 -0
  16. package/fesm2022/flusys-ng-iam.mjs +1 -1
  17. package/package.json +2 -2
  18. package/types/flusys-ng-iam.d.ts +21 -40
  19. package/fesm2022/flusys-ng-iam-action-form-page.component-C_BRrrWW.mjs.map +0 -1
  20. package/fesm2022/flusys-ng-iam-action-list-page.component-Daf93zpS.mjs +0 -289
  21. package/fesm2022/flusys-ng-iam-action-list-page.component-Daf93zpS.mjs.map +0 -1
  22. package/fesm2022/flusys-ng-iam-flusys-ng-iam-BPIpfrjN.mjs.map +0 -1
  23. package/fesm2022/flusys-ng-iam-iam-container.component-Bn4kQtxW.mjs +0 -92
  24. package/fesm2022/flusys-ng-iam-iam-container.component-Bn4kQtxW.mjs.map +0 -1
  25. package/fesm2022/flusys-ng-iam-permission-page.component-CmxOBJPu.mjs.map +0 -1
  26. package/fesm2022/flusys-ng-iam-role-form-page.component-ByNueI1a.mjs.map +0 -1
  27. package/fesm2022/flusys-ng-iam-role-list-page.component-CFly5KnH.mjs +0 -316
  28. package/fesm2022/flusys-ng-iam-role-list-page.component-CFly5KnH.mjs.map +0 -1
@@ -0,0 +1,97 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, computed, Component } from '@angular/core';
3
+ import { CommonModule } from '@angular/common';
4
+ import { RouterOutlet, RouterLink, RouterLinkActive } from '@angular/router';
5
+ import { APP_CONFIG, getPermissionMode } from '@flusys/ng-core';
6
+
7
+ /**
8
+ * IAM Container Component
9
+ *
10
+ * Main container for IAM module with tab navigation
11
+ * Routes: Actions | Roles (conditional) | Users (permission assignment)
12
+ */
13
+ class IamContainerComponent {
14
+ appConfig = inject(APP_CONFIG);
15
+ /** All available tabs */
16
+ allTabs = [
17
+ {
18
+ id: 'actions',
19
+ label: 'Actions',
20
+ icon: 'pi pi-bolt',
21
+ route: 'actions',
22
+ },
23
+ {
24
+ id: 'roles',
25
+ label: 'Roles',
26
+ icon: 'pi pi-shield',
27
+ route: 'roles',
28
+ requiresRBAC: true,
29
+ },
30
+ {
31
+ id: 'permissions',
32
+ label: 'Permissions',
33
+ icon: 'pi pi-key',
34
+ route: 'permissions',
35
+ },
36
+ ];
37
+ /** Visible tabs based on permission mode */
38
+ visibleTabs = computed(() => {
39
+ const permissionMode = getPermissionMode(this.appConfig);
40
+ return this.allTabs.filter((tab) => !tab.requiresRBAC || permissionMode === 'rbac' || permissionMode === 'full');
41
+ }, ...(ngDevMode ? [{ debugName: "visibleTabs" }] : []));
42
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: IamContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
43
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: IamContainerComponent, isStandalone: true, selector: "lib-iam-container", ngImport: i0, template: `
44
+ <div class="iam-page p-4">
45
+ <div class="iam-header mb-4">
46
+ <h1 class="text-2xl font-bold m-0">Identity & Access Management</h1>
47
+ <p class="text-muted-color mt-1">Manage actions, roles, and user permissions</p>
48
+ </div>
49
+
50
+ <div class="iam-tabs flex gap-1 mb-4 border-b border-surface-200">
51
+ @for (tab of visibleTabs(); track tab.id) {
52
+ <a
53
+ [routerLink]="tab.route"
54
+ routerLinkActive="active"
55
+ class="tab-link flex items-center gap-2 px-4 py-2 rounded-t-lg cursor-pointer transition-colors">
56
+ <i [class]="tab.icon"></i>
57
+ <span>{{ tab.label }}</span>
58
+ </a>
59
+ }
60
+ </div>
61
+
62
+ <div class="iam-content">
63
+ <router-outlet />
64
+ </div>
65
+ </div>
66
+ `, isInline: true, styles: [".tab-link{color:var(--text-color-secondary, #6b7280);text-decoration:none;border-bottom:2px solid transparent;margin-bottom:-1px}.tab-link.active{color:var(--primary-color, #3b82f6);border-bottom-color:var(--primary-color, #3b82f6);background-color:var(--surface-ground, #f9fafb)}.tab-link:hover:not(.active){background-color:var(--surface-hover, #f3f4f6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] });
67
+ }
68
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: IamContainerComponent, decorators: [{
69
+ type: Component,
70
+ args: [{ selector: 'lib-iam-container', standalone: true, imports: [CommonModule, RouterOutlet, RouterLink, RouterLinkActive], template: `
71
+ <div class="iam-page p-4">
72
+ <div class="iam-header mb-4">
73
+ <h1 class="text-2xl font-bold m-0">Identity & Access Management</h1>
74
+ <p class="text-muted-color mt-1">Manage actions, roles, and user permissions</p>
75
+ </div>
76
+
77
+ <div class="iam-tabs flex gap-1 mb-4 border-b border-surface-200">
78
+ @for (tab of visibleTabs(); track tab.id) {
79
+ <a
80
+ [routerLink]="tab.route"
81
+ routerLinkActive="active"
82
+ class="tab-link flex items-center gap-2 px-4 py-2 rounded-t-lg cursor-pointer transition-colors">
83
+ <i [class]="tab.icon"></i>
84
+ <span>{{ tab.label }}</span>
85
+ </a>
86
+ }
87
+ </div>
88
+
89
+ <div class="iam-content">
90
+ <router-outlet />
91
+ </div>
92
+ </div>
93
+ `, styles: [".tab-link{color:var(--text-color-secondary, #6b7280);text-decoration:none;border-bottom:2px solid transparent;margin-bottom:-1px}.tab-link.active{color:var(--primary-color, #3b82f6);border-bottom-color:var(--primary-color, #3b82f6);background-color:var(--surface-ground, #f9fafb)}.tab-link:hover:not(.active){background-color:var(--surface-hover, #f3f4f6)}\n"] }]
94
+ }] });
95
+
96
+ export { IamContainerComponent };
97
+ //# sourceMappingURL=flusys-ng-iam-iam-container.component-BkhqmzLi.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flusys-ng-iam-iam-container.component-BkhqmzLi.mjs","sources":["../../../projects/ng-iam/pages/iam-container/iam-container.component.ts"],"sourcesContent":["import { Component, computed, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { RouterLink, RouterLinkActive, RouterOutlet } from '@angular/router';\nimport { APP_CONFIG, getPermissionMode } from '@flusys/ng-core';\n\ninterface ITab {\n id: string;\n label: string;\n icon: string;\n route: string;\n requiresRBAC?: boolean;\n}\n\n/**\n * IAM Container Component\n *\n * Main container for IAM module with tab navigation\n * Routes: Actions | Roles (conditional) | Users (permission assignment)\n */\n@Component({\n selector: 'lib-iam-container',\n standalone: true,\n imports: [CommonModule, RouterOutlet, RouterLink, RouterLinkActive],\n template: `\n <div class=\"iam-page p-4\">\n <div class=\"iam-header mb-4\">\n <h1 class=\"text-2xl font-bold m-0\">Identity & Access Management</h1>\n <p class=\"text-muted-color mt-1\">Manage actions, roles, and user permissions</p>\n </div>\n\n <div class=\"iam-tabs flex gap-1 mb-4 border-b border-surface-200\">\n @for (tab of visibleTabs(); track tab.id) {\n <a\n [routerLink]=\"tab.route\"\n routerLinkActive=\"active\"\n class=\"tab-link flex items-center gap-2 px-4 py-2 rounded-t-lg cursor-pointer transition-colors\">\n <i [class]=\"tab.icon\"></i>\n <span>{{ tab.label }}</span>\n </a>\n }\n </div>\n\n <div class=\"iam-content\">\n <router-outlet />\n </div>\n </div>\n `,\n styles: [\n `\n .tab-link {\n color: var(--text-color-secondary, #6b7280);\n text-decoration: none;\n border-bottom: 2px solid transparent;\n margin-bottom: -1px;\n }\n .tab-link.active {\n color: var(--primary-color, #3b82f6);\n border-bottom-color: var(--primary-color, #3b82f6);\n background-color: var(--surface-ground, #f9fafb);\n }\n .tab-link:hover:not(.active) {\n background-color: var(--surface-hover, #f3f4f6);\n }\n `,\n ],\n})\nexport class IamContainerComponent {\n private readonly appConfig = inject(APP_CONFIG);\n\n /** All available tabs */\n private readonly allTabs: ITab[] = [\n {\n id: 'actions',\n label: 'Actions',\n icon: 'pi pi-bolt',\n route: 'actions',\n },\n {\n id: 'roles',\n label: 'Roles',\n icon: 'pi pi-shield',\n route: 'roles',\n requiresRBAC: true,\n },\n {\n id: 'permissions',\n label: 'Permissions',\n icon: 'pi pi-key',\n route: 'permissions',\n },\n ];\n\n /** Visible tabs based on permission mode */\n readonly visibleTabs = computed(() => {\n const permissionMode = getPermissionMode(this.appConfig);\n return this.allTabs.filter(\n (tab) => !tab.requiresRBAC || permissionMode === 'rbac' || permissionMode === 'full'\n );\n });\n}\n"],"names":[],"mappings":";;;;;;AAaA;;;;;AAKG;MAgDU,qBAAqB,CAAA;AACf,IAAA,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC;;AAG9B,IAAA,OAAO,GAAW;AACjC,QAAA;AACE,YAAA,EAAE,EAAE,SAAS;AACb,YAAA,KAAK,EAAE,SAAS;AAChB,YAAA,IAAI,EAAE,YAAY;AAClB,YAAA,KAAK,EAAE,SAAS;AACjB,SAAA;AACD,QAAA;AACE,YAAA,EAAE,EAAE,OAAO;AACX,YAAA,KAAK,EAAE,OAAO;AACd,YAAA,IAAI,EAAE,cAAc;AACpB,YAAA,KAAK,EAAE,OAAO;AACd,YAAA,YAAY,EAAE,IAAI;AACnB,SAAA;AACD,QAAA;AACE,YAAA,EAAE,EAAE,aAAa;AACjB,YAAA,KAAK,EAAE,aAAa;AACpB,YAAA,IAAI,EAAE,WAAW;AACjB,YAAA,KAAK,EAAE,aAAa;AACrB,SAAA;KACF;;AAGQ,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAK;QACnC,MAAM,cAAc,GAAG,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC;QACxD,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CACxB,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,IAAI,cAAc,KAAK,MAAM,IAAI,cAAc,KAAK,MAAM,CACrF;AACH,IAAA,CAAC,uDAAC;uGAhCS,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAArB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,qBAAqB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA3CtB;;;;;;;;;;;;;;;;;;;;;;;AAuBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,wWAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAxBS,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,YAAY,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,kBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,QAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,UAAU,oOAAE,gBAAgB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,yBAAA,EAAA,uBAAA,EAAA,kBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FA4CvD,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBA/CjC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,mBAAmB,EAAA,UAAA,EACjB,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,CAAC,EAAA,QAAA,EACzD;;;;;;;;;;;;;;;;;;;;;;;AAuBT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,wWAAA,CAAA,EAAA;;;;;"}
@@ -1,19 +1,12 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, signal, computed, effect, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
3
- import { COMPANY_ACTION_PERMISSIONS, USER_ACTION_PERMISSIONS, USER_ROLE_PERMISSIONS, ROLE_ACTION_PERMISSIONS, AngularModule, PrimeModule, HasPermissionDirective } from '@flusys/ng-shared';
2
+ import { inject, signal, computed, Component } from '@angular/core';
3
+ import { AngularModule, PrimeModule } from '@flusys/ng-shared';
4
4
  import { APP_CONFIG, getPermissionMode, isCompanyFeatureEnabled } from '@flusys/ng-core';
5
5
  import * as i2 from 'primeng/button';
6
6
  import { ButtonModule } from 'primeng/button';
7
7
  import { TabsModule } from 'primeng/tabs';
8
- import { b as RoleActionSelectorComponent, C as CompanyActionSelectorComponent, U as UserRoleSelectorComponent, d as UserActionSelectorComponent } from './flusys-ng-iam-flusys-ng-iam-BPIpfrjN.mjs';
8
+ import { b as RoleActionSelectorComponent, C as CompanyActionSelectorComponent, U as UserRoleSelectorComponent, d as UserActionSelectorComponent } from './flusys-ng-iam-flusys-ng-iam-DISrddPh.mjs';
9
9
 
10
- /** Permission codes for each tab */
11
- const TAB_PERMISSIONS = {
12
- 'role-actions': ROLE_ACTION_PERMISSIONS.READ,
13
- 'user-roles': USER_ROLE_PERMISSIONS.READ,
14
- 'user-actions': USER_ACTION_PERMISSIONS.READ,
15
- 'company-actions': COMPANY_ACTION_PERMISSIONS.READ,
16
- };
17
10
  /**
18
11
  * Permission Page Component
19
12
  *
@@ -25,9 +18,9 @@ const TAB_PERMISSIONS = {
25
18
  */
26
19
  class PermissionPageComponent {
27
20
  appConfig = inject(APP_CONFIG);
28
- activeTab = signal('', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
21
+ activeTab = signal('role-actions', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
29
22
  /**
30
- * All possible tabs based on permission mode (directive handles action permissions)
23
+ * Available tabs based on configuration
31
24
  */
32
25
  availableTabs = computed(() => {
33
26
  const permissionMode = getPermissionMode(this.appConfig);
@@ -38,12 +31,10 @@ class PermissionPageComponent {
38
31
  id: 'role-actions',
39
32
  label: 'Role-Actions',
40
33
  icon: 'pi pi-shield',
41
- permission: TAB_PERMISSIONS['role-actions'],
42
34
  }, {
43
35
  id: 'user-roles',
44
36
  label: 'User-Roles',
45
37
  icon: 'pi pi-user',
46
- permission: TAB_PERMISSIONS['user-roles'],
47
38
  });
48
39
  }
49
40
  // User-Action direct assignment (DIRECT or FULL mode)
@@ -52,7 +43,6 @@ class PermissionPageComponent {
52
43
  id: 'user-actions',
53
44
  label: 'User-Actions',
54
45
  icon: 'pi pi-key',
55
- permission: TAB_PERMISSIONS['user-actions'],
56
46
  });
57
47
  }
58
48
  // Company-Action whitelist (if company feature enabled)
@@ -61,24 +51,10 @@ class PermissionPageComponent {
61
51
  id: 'company-actions',
62
52
  label: 'Company-Actions',
63
53
  icon: 'pi pi-building',
64
- permission: TAB_PERMISSIONS['company-actions'],
65
54
  });
66
55
  }
67
56
  return tabs;
68
57
  }, ...(ngDevMode ? [{ debugName: "availableTabs" }] : []));
69
- constructor() {
70
- // Set default tab to first available tab
71
- effect(() => {
72
- const tabs = this.availableTabs();
73
- const currentTab = untracked(() => this.activeTab());
74
- // Only set if no active tab or current tab is not in available tabs
75
- if (!currentTab || !tabs.some((t) => t.id === currentTab)) {
76
- if (tabs.length > 0) {
77
- this.activeTab.set(tabs[0].id);
78
- }
79
- }
80
- });
81
- }
82
58
  setActiveTab(tabId) {
83
59
  this.activeTab.set(tabId);
84
60
  }
@@ -87,15 +63,13 @@ class PermissionPageComponent {
87
63
  <div class="card">
88
64
  <h3 class="text-xl font-semibold mb-4">Permission Management</h3>
89
65
 
90
- <div class="scrollbar-hide flex gap-2 mb-4 overflow-x-auto flex-nowrap">
66
+ <div class="flex gap-2 mb-4">
91
67
  @for (tab of availableTabs(); track tab.id) {
92
68
  <p-button
93
- *hasPermission="tab.permission"
94
69
  [label]="tab.label"
95
70
  [icon]="tab.icon"
96
71
  [outlined]="activeTab() !== tab.id"
97
72
  size="small"
98
- styleClass="shrink-0"
99
73
  (onClick)="setActiveTab(tab.id)" />
100
74
  }
101
75
  </div>
@@ -117,16 +91,15 @@ class PermissionPageComponent {
117
91
  }
118
92
  </div>
119
93
  </div>
120
- `, isInline: true, styles: [".scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-hide::-webkit-scrollbar{display:none}\n"], dependencies: [{ kind: "ngmodule", type: AngularModule }, { 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: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: TabsModule }, { kind: "directive", type: HasPermissionDirective, selector: "[hasPermission]", inputs: ["hasPermission"] }, { kind: "component", type: RoleActionSelectorComponent, selector: "flusys-role-action-selector" }, { kind: "component", type: CompanyActionSelectorComponent, selector: "flusys-company-action-selector" }, { kind: "component", type: UserRoleSelectorComponent, selector: "flusys-user-role-selector" }, { kind: "component", type: UserActionSelectorComponent, selector: "flusys-user-action-selector" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
94
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: AngularModule }, { 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: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: TabsModule }, { kind: "component", type: RoleActionSelectorComponent, selector: "flusys-role-action-selector" }, { kind: "component", type: CompanyActionSelectorComponent, selector: "flusys-company-action-selector" }, { kind: "component", type: UserRoleSelectorComponent, selector: "flusys-user-role-selector" }, { kind: "component", type: UserActionSelectorComponent, selector: "flusys-user-action-selector" }] });
121
95
  }
122
96
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: PermissionPageComponent, decorators: [{
123
97
  type: Component,
124
- args: [{ selector: 'lib-permission-page', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
98
+ args: [{ selector: 'lib-permission-page', standalone: true, imports: [
125
99
  AngularModule,
126
100
  PrimeModule,
127
101
  ButtonModule,
128
102
  TabsModule,
129
- HasPermissionDirective,
130
103
  RoleActionSelectorComponent,
131
104
  CompanyActionSelectorComponent,
132
105
  UserRoleSelectorComponent,
@@ -135,15 +108,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
135
108
  <div class="card">
136
109
  <h3 class="text-xl font-semibold mb-4">Permission Management</h3>
137
110
 
138
- <div class="scrollbar-hide flex gap-2 mb-4 overflow-x-auto flex-nowrap">
111
+ <div class="flex gap-2 mb-4">
139
112
  @for (tab of availableTabs(); track tab.id) {
140
113
  <p-button
141
- *hasPermission="tab.permission"
142
114
  [label]="tab.label"
143
115
  [icon]="tab.icon"
144
116
  [outlined]="activeTab() !== tab.id"
145
117
  size="small"
146
- styleClass="shrink-0"
147
118
  (onClick)="setActiveTab(tab.id)" />
148
119
  }
149
120
  </div>
@@ -165,8 +136,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
165
136
  }
166
137
  </div>
167
138
  </div>
168
- `, styles: [".scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-hide::-webkit-scrollbar{display:none}\n"] }]
169
- }], ctorParameters: () => [] });
139
+ `, styles: [":host{display:block}\n"] }]
140
+ }] });
170
141
 
171
142
  export { PermissionPageComponent };
172
- //# sourceMappingURL=flusys-ng-iam-permission-page.component-CmxOBJPu.mjs.map
143
+ //# sourceMappingURL=flusys-ng-iam-permission-page.component-BSQFPt_N.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flusys-ng-iam-permission-page.component-BSQFPt_N.mjs","sources":["../../../projects/ng-iam/pages/permission/permission-page.component.ts"],"sourcesContent":["import { Component, computed, inject, signal } from '@angular/core';\nimport { AngularModule, PrimeModule } from '@flusys/ng-shared';\nimport { APP_CONFIG, getPermissionMode, isCompanyFeatureEnabled } from '@flusys/ng-core';\nimport { ButtonModule } from 'primeng/button';\nimport { TabsModule } from 'primeng/tabs';\nimport { RoleActionSelectorComponent } from '../../components/role-action-selector.component';\nimport { CompanyActionSelectorComponent } from '../../components/company-action-selector.component';\nimport { UserRoleSelectorComponent } from '../../components/user-role-selector.component';\nimport { UserActionSelectorComponent } from '../../components/user-action-selector.component';\n\n/**\n * Permission Page Component\n *\n * Main permission management interface with tabs for:\n * - Role-Action Assignment (RBAC/FULL mode) - WITH LOGIC BUILDER\n * - User-Role Assignment (RBAC/FULL mode)\n * - User-Action Assignment (DIRECT/FULL mode)\n * - Company-Action Whitelist (if company feature enabled)\n */\n@Component({\n selector: 'lib-permission-page',\n standalone: true,\n imports: [\n AngularModule,\n PrimeModule,\n ButtonModule,\n TabsModule,\n RoleActionSelectorComponent,\n CompanyActionSelectorComponent,\n UserRoleSelectorComponent,\n UserActionSelectorComponent\n ],\n template: `\n <div class=\"card\">\n <h3 class=\"text-xl font-semibold mb-4\">Permission Management</h3>\n\n <div class=\"flex gap-2 mb-4\">\n @for (tab of availableTabs(); track tab.id) {\n <p-button\n [label]=\"tab.label\"\n [icon]=\"tab.icon\"\n [outlined]=\"activeTab() !== tab.id\"\n size=\"small\"\n (onClick)=\"setActiveTab(tab.id)\" />\n }\n </div>\n\n <div class=\"mt-4\">\n @switch (activeTab()) {\n @case ('role-actions') {\n <flusys-role-action-selector />\n }\n @case ('user-roles') {\n <flusys-user-role-selector />\n }\n @case ('user-actions') {\n <flusys-user-action-selector />\n }\n @case ('company-actions') {\n <flusys-company-action-selector />\n }\n }\n </div>\n </div>\n `,\n styles: [`\n :host {\n display: block;\n }\n `]\n})\nexport class PermissionPageComponent {\n private readonly appConfig = inject(APP_CONFIG);\n\n readonly activeTab = signal<string>('role-actions');\n\n /**\n * Available tabs based on configuration\n */\n readonly availableTabs = computed(() => {\n const permissionMode = getPermissionMode(this.appConfig);\n const tabs: Array<{ id: string; label: string; icon: string }> = [];\n\n // Role-Action assignment (RBAC or FULL mode)\n if (permissionMode === 'rbac' || permissionMode === 'full') {\n tabs.push(\n {\n id: 'role-actions',\n label: 'Role-Actions',\n icon: 'pi pi-shield',\n },\n {\n id: 'user-roles',\n label: 'User-Roles',\n icon: 'pi pi-user',\n }\n );\n }\n\n // User-Action direct assignment (DIRECT or FULL mode)\n if (permissionMode === 'direct' || permissionMode === 'full') {\n tabs.push({\n id: 'user-actions',\n label: 'User-Actions',\n icon: 'pi pi-key',\n });\n }\n\n // Company-Action whitelist (if company feature enabled)\n if (isCompanyFeatureEnabled(this.appConfig)) {\n tabs.push({\n id: 'company-actions',\n label: 'Company-Actions',\n icon: 'pi pi-building',\n });\n }\n\n return tabs;\n });\n\n setActiveTab(tabId: string): void {\n this.activeTab.set(tabId);\n }\n}\n"],"names":["i1"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, signal, computed, effect, ChangeDetectionStrategy, Component } from '@angular/core';
3
- import { toSignal } from '@angular/core/rxjs-interop';
2
+ import { inject, signal, computed, ChangeDetectionStrategy, Component } from '@angular/core';
4
3
  import { form, required, FormField } from '@angular/forms/signals';
5
4
  import { ActivatedRoute, Router } from '@angular/router';
6
5
  import { APP_CONFIG, isCompanyFeatureEnabled } from '@flusys/ng-core';
@@ -8,11 +7,10 @@ import { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';
8
7
  import { AngularModule, PrimeModule } from '@flusys/ng-shared';
9
8
  import { MessageService } from 'primeng/api';
10
9
  import { firstValueFrom } from 'rxjs';
11
- import { R as RoleApiService } from './flusys-ng-iam-flusys-ng-iam-BPIpfrjN.mjs';
10
+ import { R as RoleApiService } from './flusys-ng-iam-flusys-ng-iam-DISrddPh.mjs';
12
11
  import * as i1 from '@angular/forms';
13
12
  import * as i2 from 'primeng/button';
14
- import * as i3 from 'primeng/checkbox';
15
- import * as i4 from 'primeng/inputtext';
13
+ import * as i3 from 'primeng/inputtext';
16
14
 
17
15
  /**
18
16
  * Role Form Page Component
@@ -25,8 +23,6 @@ class RoleFormPageComponent {
25
23
  companyContext = inject(LAYOUT_AUTH_STATE);
26
24
  roleApi = inject(RoleApiService);
27
25
  messageService = inject(MessageService);
28
- routeParams = toSignal(this.route.paramMap);
29
- initialized = false;
30
26
  /** Loading state */
31
27
  isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
32
28
  /** Existing role data when editing */
@@ -53,17 +49,11 @@ class RoleFormPageComponent {
53
49
  const model = this.formModel();
54
50
  return model.name.trim().length > 0;
55
51
  }, ...(ngDevMode ? [{ debugName: "isFormValid" }] : []));
56
- constructor() {
57
- effect(() => {
58
- const params = this.routeParams();
59
- if (!params || this.initialized)
60
- return;
61
- this.initialized = true;
62
- const id = params.get('id');
63
- if (id && id !== 'new') {
64
- this.loadRole(id);
65
- }
66
- });
52
+ ngOnInit() {
53
+ const id = this.route.snapshot.paramMap.get('id');
54
+ if (id && id !== 'new') {
55
+ this.loadRole(id);
56
+ }
67
57
  }
68
58
  async loadRole(id) {
69
59
  this.isLoading.set(true);
@@ -81,12 +71,20 @@ class RoleFormPageComponent {
81
71
  });
82
72
  }
83
73
  else {
84
- // Error toast handled by global interceptor
74
+ this.messageService.add({
75
+ severity: 'error',
76
+ summary: 'Error',
77
+ detail: 'Role not found.',
78
+ });
85
79
  this.router.navigate(['/iam/roles']);
86
80
  }
87
81
  }
88
- catch {
89
- // Error toast handled by global interceptor
82
+ catch (error) {
83
+ this.messageService.add({
84
+ severity: 'error',
85
+ summary: 'Error',
86
+ detail: 'Failed to load role.',
87
+ });
90
88
  this.router.navigate(['/iam/roles']);
91
89
  }
92
90
  finally {
@@ -134,8 +132,12 @@ class RoleFormPageComponent {
134
132
  }
135
133
  this.router.navigate(['/iam/roles']);
136
134
  }
137
- catch {
138
- // Error toast handled by global interceptor
135
+ catch (error) {
136
+ this.messageService.add({
137
+ severity: 'error',
138
+ summary: 'Error',
139
+ detail: error.message || 'Failed to save role.',
140
+ });
139
141
  }
140
142
  finally {
141
143
  this.isLoading.set(false);
@@ -147,53 +149,66 @@ class RoleFormPageComponent {
147
149
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: RoleFormPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
148
150
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.3", type: RoleFormPageComponent, isStandalone: true, selector: "lib-role-form-page", ngImport: i0, template: `
149
151
  <div class="card">
150
- <h3 class="text-lg sm:text-xl font-semibold mb-4">
151
- {{ isEditMode() ? 'Edit Role' : 'New Role' }}
152
- </h3>
152
+ <div class="flex justify-between items-center mb-4">
153
+ <h3 class="text-xl font-semibold">
154
+ {{ isEditMode() ? 'Edit Role' : 'New Role' }}
155
+ </h3>
156
+ <p-button
157
+ label="Back"
158
+ icon="pi pi-arrow-left"
159
+ [outlined]="true"
160
+ (onClick)="onBack()" />
161
+ </div>
153
162
 
154
- <form (ngSubmit)="onSubmit()" class="grid grid-cols-1 md:grid-cols-2 gap-4">
155
- <!-- Name -->
156
- <div class="flex flex-col gap-2">
157
- <label for="name" class="font-medium">Name *</label>
158
- <input
159
- pInputText
160
- id="name"
161
- [formField]="roleForm.name"
162
- placeholder="Enter role name" />
163
- </div>
163
+ <form (ngSubmit)="onSubmit()">
164
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
165
+ <!-- Name -->
166
+ <div class="md:col-span-2">
167
+ <label for="name" class="block font-medium mb-2">Name *</label>
168
+ <input
169
+ pInputText
170
+ id="name"
171
+ [formField]="roleForm.name"
172
+ class="w-full"
173
+ placeholder="Enter role name" />
174
+ </div>
164
175
 
165
- <!-- Description -->
166
- <div class="flex flex-col gap-2">
167
- <label for="description" class="font-medium">Description</label>
168
- <input
169
- pInputText
170
- id="description"
171
- [formField]="roleForm.description"
172
- placeholder="Enter description" />
173
- </div>
176
+ <!-- Description -->
177
+ <div class="md:col-span-2">
178
+ <label for="description" class="block font-medium mb-2">Description</label>
179
+ <input
180
+ pInputText
181
+ id="description"
182
+ [formField]="roleForm.description"
183
+ class="w-full"
184
+ placeholder="Enter description" />
185
+ </div>
174
186
 
175
- <!-- Order -->
176
- <div class="flex flex-col gap-2">
177
- <label for="serial" class="font-medium">Display Order</label>
178
- <input
179
- pInputText
180
- id="serial"
181
- type="number"
182
- [formField]="roleForm.serial"
183
- placeholder="Enter display order" />
184
- </div>
187
+ <!-- Order -->
188
+ <div>
189
+ <label for="serial" class="block font-medium mb-2">Display Order</label>
190
+ <input
191
+ pInputText
192
+ id="serial"
193
+ type="number"
194
+ [formField]="roleForm.serial"
195
+ class="w-full"
196
+ placeholder="Enter display order" />
197
+ </div>
185
198
 
186
- <!-- Is Active -->
187
- <div class="flex items-end gap-2 pb-1">
188
- <p-checkbox
189
- [formField]="roleForm.isActive"
190
- [binary]="true"
191
- inputId="isActive" />
192
- <label for="isActive">Active</label>
199
+ <!-- Is Active -->
200
+ <div class="flex items-center pt-6">
201
+ <label class="p-checkbox-native">
202
+ <input
203
+ type="checkbox"
204
+ [formField]="roleForm.isActive" />
205
+ <span>Active</span>
206
+ </label>
207
+ </div>
193
208
  </div>
194
209
 
195
210
  <!-- Actions -->
196
- <div class="flex justify-end gap-2 md:col-span-2 pt-4">
211
+ <div class="flex justify-end gap-2 mt-6">
197
212
  <p-button
198
213
  label="Cancel"
199
214
  severity="secondary"
@@ -207,7 +222,7 @@ class RoleFormPageComponent {
207
222
  </div>
208
223
  </form>
209
224
  </div>
210
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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: "component", type: i3.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
225
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
211
226
  }
212
227
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: RoleFormPageComponent, decorators: [{
213
228
  type: Component,
@@ -218,53 +233,66 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
218
233
  changeDetection: ChangeDetectionStrategy.OnPush,
219
234
  template: `
220
235
  <div class="card">
221
- <h3 class="text-lg sm:text-xl font-semibold mb-4">
222
- {{ isEditMode() ? 'Edit Role' : 'New Role' }}
223
- </h3>
236
+ <div class="flex justify-between items-center mb-4">
237
+ <h3 class="text-xl font-semibold">
238
+ {{ isEditMode() ? 'Edit Role' : 'New Role' }}
239
+ </h3>
240
+ <p-button
241
+ label="Back"
242
+ icon="pi pi-arrow-left"
243
+ [outlined]="true"
244
+ (onClick)="onBack()" />
245
+ </div>
224
246
 
225
- <form (ngSubmit)="onSubmit()" class="grid grid-cols-1 md:grid-cols-2 gap-4">
226
- <!-- Name -->
227
- <div class="flex flex-col gap-2">
228
- <label for="name" class="font-medium">Name *</label>
229
- <input
230
- pInputText
231
- id="name"
232
- [formField]="roleForm.name"
233
- placeholder="Enter role name" />
234
- </div>
247
+ <form (ngSubmit)="onSubmit()">
248
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
249
+ <!-- Name -->
250
+ <div class="md:col-span-2">
251
+ <label for="name" class="block font-medium mb-2">Name *</label>
252
+ <input
253
+ pInputText
254
+ id="name"
255
+ [formField]="roleForm.name"
256
+ class="w-full"
257
+ placeholder="Enter role name" />
258
+ </div>
235
259
 
236
- <!-- Description -->
237
- <div class="flex flex-col gap-2">
238
- <label for="description" class="font-medium">Description</label>
239
- <input
240
- pInputText
241
- id="description"
242
- [formField]="roleForm.description"
243
- placeholder="Enter description" />
244
- </div>
260
+ <!-- Description -->
261
+ <div class="md:col-span-2">
262
+ <label for="description" class="block font-medium mb-2">Description</label>
263
+ <input
264
+ pInputText
265
+ id="description"
266
+ [formField]="roleForm.description"
267
+ class="w-full"
268
+ placeholder="Enter description" />
269
+ </div>
245
270
 
246
- <!-- Order -->
247
- <div class="flex flex-col gap-2">
248
- <label for="serial" class="font-medium">Display Order</label>
249
- <input
250
- pInputText
251
- id="serial"
252
- type="number"
253
- [formField]="roleForm.serial"
254
- placeholder="Enter display order" />
255
- </div>
271
+ <!-- Order -->
272
+ <div>
273
+ <label for="serial" class="block font-medium mb-2">Display Order</label>
274
+ <input
275
+ pInputText
276
+ id="serial"
277
+ type="number"
278
+ [formField]="roleForm.serial"
279
+ class="w-full"
280
+ placeholder="Enter display order" />
281
+ </div>
256
282
 
257
- <!-- Is Active -->
258
- <div class="flex items-end gap-2 pb-1">
259
- <p-checkbox
260
- [formField]="roleForm.isActive"
261
- [binary]="true"
262
- inputId="isActive" />
263
- <label for="isActive">Active</label>
283
+ <!-- Is Active -->
284
+ <div class="flex items-center pt-6">
285
+ <label class="p-checkbox-native">
286
+ <input
287
+ type="checkbox"
288
+ [formField]="roleForm.isActive" />
289
+ <span>Active</span>
290
+ </label>
291
+ </div>
264
292
  </div>
265
293
 
266
294
  <!-- Actions -->
267
- <div class="flex justify-end gap-2 md:col-span-2 pt-4">
295
+ <div class="flex justify-end gap-2 mt-6">
268
296
  <p-button
269
297
  label="Cancel"
270
298
  severity="secondary"
@@ -280,7 +308,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
280
308
  </div>
281
309
  `,
282
310
  }]
283
- }], ctorParameters: () => [] });
311
+ }] });
284
312
 
285
313
  export { RoleFormPageComponent };
286
- //# sourceMappingURL=flusys-ng-iam-role-form-page.component-ByNueI1a.mjs.map
314
+ //# sourceMappingURL=flusys-ng-iam-role-form-page.component-Cqziu_BM.mjs.map