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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/README.md +225 -24
  2. package/fesm2022/{flusys-ng-iam-action-form-page.component-0b9GwJqa.mjs → flusys-ng-iam-action-form-page.component-C_BRrrWW.mjs} +175 -203
  3. package/fesm2022/flusys-ng-iam-action-form-page.component-C_BRrrWW.mjs.map +1 -0
  4. package/fesm2022/flusys-ng-iam-action-list-page.component-Daf93zpS.mjs +289 -0
  5. package/fesm2022/flusys-ng-iam-action-list-page.component-Daf93zpS.mjs.map +1 -0
  6. package/fesm2022/{flusys-ng-iam-flusys-ng-iam-C-MQjakK.mjs → flusys-ng-iam-flusys-ng-iam-BPIpfrjN.mjs} +892 -818
  7. package/fesm2022/flusys-ng-iam-flusys-ng-iam-BPIpfrjN.mjs.map +1 -0
  8. package/fesm2022/flusys-ng-iam-iam-container.component-Bn4kQtxW.mjs +92 -0
  9. package/fesm2022/flusys-ng-iam-iam-container.component-Bn4kQtxW.mjs.map +1 -0
  10. package/fesm2022/{flusys-ng-iam-permission-page.component-e_RX5mky.mjs → flusys-ng-iam-permission-page.component-CmxOBJPu.mjs} +42 -13
  11. package/fesm2022/flusys-ng-iam-permission-page.component-CmxOBJPu.mjs.map +1 -0
  12. package/fesm2022/{flusys-ng-iam-role-form-page.component-eZM1EPps.mjs → flusys-ng-iam-role-form-page.component-ByNueI1a.mjs} +107 -135
  13. package/fesm2022/flusys-ng-iam-role-form-page.component-ByNueI1a.mjs.map +1 -0
  14. package/fesm2022/flusys-ng-iam-role-list-page.component-CFly5KnH.mjs +316 -0
  15. package/fesm2022/flusys-ng-iam-role-list-page.component-CFly5KnH.mjs.map +1 -0
  16. package/fesm2022/flusys-ng-iam.mjs +1 -1
  17. package/package.json +5 -5
  18. package/types/flusys-ng-iam.d.ts +87 -23
  19. package/fesm2022/flusys-ng-iam-action-form-page.component-0b9GwJqa.mjs.map +0 -1
  20. package/fesm2022/flusys-ng-iam-action-list-page.component-BpvewEGL.mjs +0 -281
  21. package/fesm2022/flusys-ng-iam-action-list-page.component-BpvewEGL.mjs.map +0 -1
  22. package/fesm2022/flusys-ng-iam-flusys-ng-iam-C-MQjakK.mjs.map +0 -1
  23. package/fesm2022/flusys-ng-iam-iam-container.component-Chl5MDkV.mjs +0 -97
  24. package/fesm2022/flusys-ng-iam-iam-container.component-Chl5MDkV.mjs.map +0 -1
  25. package/fesm2022/flusys-ng-iam-permission-page.component-e_RX5mky.mjs.map +0 -1
  26. package/fesm2022/flusys-ng-iam-role-form-page.component-eZM1EPps.mjs.map +0 -1
  27. package/fesm2022/flusys-ng-iam-role-list-page.component-BgzxmHjk.mjs +0 -266
  28. package/fesm2022/flusys-ng-iam-role-list-page.component-BgzxmHjk.mjs.map +0 -1
@@ -0,0 +1,92 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, computed, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { RouterOutlet, RouterLink, RouterLinkActive } from '@angular/router';
4
+ import { APP_CONFIG, getPermissionMode } from '@flusys/ng-core';
5
+
6
+ /**
7
+ * IAM Container Component
8
+ *
9
+ * Main container for IAM module with tab navigation
10
+ * Routes: Actions | Roles (conditional) | Users (permission assignment)
11
+ */
12
+ class IamContainerComponent {
13
+ appConfig = inject(APP_CONFIG);
14
+ /** All available tabs */
15
+ allTabs = [
16
+ {
17
+ id: 'actions',
18
+ label: 'Actions',
19
+ icon: 'pi pi-bolt',
20
+ route: 'actions',
21
+ },
22
+ {
23
+ id: 'roles',
24
+ label: 'Roles',
25
+ icon: 'pi pi-shield',
26
+ route: 'roles',
27
+ requiresRBAC: true,
28
+ },
29
+ {
30
+ id: 'permissions',
31
+ label: 'Permissions',
32
+ icon: 'pi pi-key',
33
+ route: 'permissions',
34
+ },
35
+ ];
36
+ /** Visible tabs based on permission mode */
37
+ visibleTabs = computed(() => {
38
+ const permissionMode = getPermissionMode(this.appConfig);
39
+ return this.allTabs.filter((tab) => !tab.requiresRBAC || permissionMode === 'rbac' || permissionMode === 'full');
40
+ }, ...(ngDevMode ? [{ debugName: "visibleTabs" }] : []));
41
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: IamContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
42
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: IamContainerComponent, isStandalone: true, selector: "lib-iam-container", ngImport: i0, template: `
43
+ <div class="p-4">
44
+ <div class="mb-4">
45
+ <h1 class="text-xl sm:text-2xl font-bold m-0">Identity & Access Management</h1>
46
+ <p class="text-muted-color mt-1">Manage actions, roles, and user permissions</p>
47
+ </div>
48
+
49
+ <div class="scrollbar-hide flex gap-1 mb-4 border-b border-surface overflow-x-auto flex-nowrap">
50
+ @for (tab of visibleTabs(); track tab.id) {
51
+ <a
52
+ [routerLink]="tab.route"
53
+ routerLinkActive="tab-active"
54
+ class="flex items-center gap-2 px-4 py-2 rounded-t-lg cursor-pointer transition-colors text-muted-color no-underline border-b-2 border-transparent -mb-px hover:bg-surface-hover [&.tab-active]:text-primary [&.tab-active]:border-primary [&.tab-active]:bg-surface-ground whitespace-nowrap shrink-0">
55
+ <i [class]="tab.icon"></i>
56
+ <span>{{ tab.label }}</span>
57
+ </a>
58
+ }
59
+ </div>
60
+
61
+ <router-outlet />
62
+ </div>
63
+ `, isInline: true, styles: [".scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-hide::-webkit-scrollbar{display:none}\n"], dependencies: [{ 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
64
+ }
65
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: IamContainerComponent, decorators: [{
66
+ type: Component,
67
+ args: [{ selector: 'lib-iam-container', standalone: true, imports: [RouterOutlet, RouterLink, RouterLinkActive], changeDetection: ChangeDetectionStrategy.OnPush, template: `
68
+ <div class="p-4">
69
+ <div class="mb-4">
70
+ <h1 class="text-xl sm:text-2xl font-bold m-0">Identity & Access Management</h1>
71
+ <p class="text-muted-color mt-1">Manage actions, roles, and user permissions</p>
72
+ </div>
73
+
74
+ <div class="scrollbar-hide flex gap-1 mb-4 border-b border-surface overflow-x-auto flex-nowrap">
75
+ @for (tab of visibleTabs(); track tab.id) {
76
+ <a
77
+ [routerLink]="tab.route"
78
+ routerLinkActive="tab-active"
79
+ class="flex items-center gap-2 px-4 py-2 rounded-t-lg cursor-pointer transition-colors text-muted-color no-underline border-b-2 border-transparent -mb-px hover:bg-surface-hover [&.tab-active]:text-primary [&.tab-active]:border-primary [&.tab-active]:bg-surface-ground whitespace-nowrap shrink-0">
80
+ <i [class]="tab.icon"></i>
81
+ <span>{{ tab.label }}</span>
82
+ </a>
83
+ }
84
+ </div>
85
+
86
+ <router-outlet />
87
+ </div>
88
+ `, styles: [".scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-hide::-webkit-scrollbar{display:none}\n"] }]
89
+ }] });
90
+
91
+ export { IamContainerComponent };
92
+ //# sourceMappingURL=flusys-ng-iam-iam-container.component-Bn4kQtxW.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flusys-ng-iam-iam-container.component-Bn4kQtxW.mjs","sources":["../../../projects/ng-iam/pages/iam-container/iam-container.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';\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: [RouterOutlet, RouterLink, RouterLinkActive],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: `\n .scrollbar-hide {\n -ms-overflow-style: none;\n scrollbar-width: none;\n &::-webkit-scrollbar { display: none; }\n }\n `,\n template: `\n <div class=\"p-4\">\n <div class=\"mb-4\">\n <h1 class=\"text-xl sm: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=\"scrollbar-hide flex gap-1 mb-4 border-b border-surface overflow-x-auto flex-nowrap\">\n @for (tab of visibleTabs(); track tab.id) {\n <a\n [routerLink]=\"tab.route\"\n routerLinkActive=\"tab-active\"\n class=\"flex items-center gap-2 px-4 py-2 rounded-t-lg cursor-pointer transition-colors text-muted-color no-underline border-b-2 border-transparent -mb-px hover:bg-surface-hover [&.tab-active]:text-primary [&.tab-active]:border-primary [&.tab-active]:bg-surface-ground whitespace-nowrap shrink-0\">\n <i [class]=\"tab.icon\"></i>\n <span>{{ tab.label }}</span>\n </a>\n }\n </div>\n\n <router-outlet />\n </div>\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":"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"}
@@ -1,12 +1,19 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, signal, computed, Component } from '@angular/core';
3
- import { AngularModule, PrimeModule } from '@flusys/ng-shared';
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';
4
4
  import { APP_CONFIG, getPermissionMode, isCompanyFeatureEnabled } from '@flusys/ng-core';
5
- import * as i3 from 'primeng/button';
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-C-MQjakK.mjs';
8
+ import { b as RoleActionSelectorComponent, C as CompanyActionSelectorComponent, U as UserRoleSelectorComponent, d as UserActionSelectorComponent } from './flusys-ng-iam-flusys-ng-iam-BPIpfrjN.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
+ };
10
17
  /**
11
18
  * Permission Page Component
12
19
  *
@@ -18,9 +25,9 @@ import { b as RoleActionSelectorComponent, C as CompanyActionSelectorComponent,
18
25
  */
19
26
  class PermissionPageComponent {
20
27
  appConfig = inject(APP_CONFIG);
21
- activeTab = signal('role-actions', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
28
+ activeTab = signal('', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
22
29
  /**
23
- * Available tabs based on configuration
30
+ * All possible tabs based on permission mode (directive handles action permissions)
24
31
  */
25
32
  availableTabs = computed(() => {
26
33
  const permissionMode = getPermissionMode(this.appConfig);
@@ -31,10 +38,12 @@ class PermissionPageComponent {
31
38
  id: 'role-actions',
32
39
  label: 'Role-Actions',
33
40
  icon: 'pi pi-shield',
41
+ permission: TAB_PERMISSIONS['role-actions'],
34
42
  }, {
35
43
  id: 'user-roles',
36
44
  label: 'User-Roles',
37
45
  icon: 'pi pi-user',
46
+ permission: TAB_PERMISSIONS['user-roles'],
38
47
  });
39
48
  }
40
49
  // User-Action direct assignment (DIRECT or FULL mode)
@@ -43,6 +52,7 @@ class PermissionPageComponent {
43
52
  id: 'user-actions',
44
53
  label: 'User-Actions',
45
54
  icon: 'pi pi-key',
55
+ permission: TAB_PERMISSIONS['user-actions'],
46
56
  });
47
57
  }
48
58
  // Company-Action whitelist (if company feature enabled)
@@ -51,10 +61,24 @@ class PermissionPageComponent {
51
61
  id: 'company-actions',
52
62
  label: 'Company-Actions',
53
63
  icon: 'pi pi-building',
64
+ permission: TAB_PERMISSIONS['company-actions'],
54
65
  });
55
66
  }
56
67
  return tabs;
57
68
  }, ...(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
+ }
58
82
  setActiveTab(tabId) {
59
83
  this.activeTab.set(tabId);
60
84
  }
@@ -63,13 +87,15 @@ class PermissionPageComponent {
63
87
  <div class="card">
64
88
  <h3 class="text-xl font-semibold mb-4">Permission Management</h3>
65
89
 
66
- <div class="flex gap-2 mb-4">
90
+ <div class="scrollbar-hide flex gap-2 mb-4 overflow-x-auto flex-nowrap">
67
91
  @for (tab of availableTabs(); track tab.id) {
68
92
  <p-button
93
+ *hasPermission="tab.permission"
69
94
  [label]="tab.label"
70
95
  [icon]="tab.icon"
71
96
  [outlined]="activeTab() !== tab.id"
72
97
  size="small"
98
+ styleClass="shrink-0"
73
99
  (onClick)="setActiveTab(tab.id)" />
74
100
  }
75
101
  </div>
@@ -91,15 +117,16 @@ class PermissionPageComponent {
91
117
  }
92
118
  </div>
93
119
  </div>
94
- `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "ngmodule", type: PrimeModule }, { 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: "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" }] });
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 });
95
121
  }
96
122
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: PermissionPageComponent, decorators: [{
97
123
  type: Component,
98
- args: [{ selector: 'lib-permission-page', standalone: true, imports: [
124
+ args: [{ selector: 'lib-permission-page', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
99
125
  AngularModule,
100
126
  PrimeModule,
101
127
  ButtonModule,
102
128
  TabsModule,
129
+ HasPermissionDirective,
103
130
  RoleActionSelectorComponent,
104
131
  CompanyActionSelectorComponent,
105
132
  UserRoleSelectorComponent,
@@ -108,13 +135,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
108
135
  <div class="card">
109
136
  <h3 class="text-xl font-semibold mb-4">Permission Management</h3>
110
137
 
111
- <div class="flex gap-2 mb-4">
138
+ <div class="scrollbar-hide flex gap-2 mb-4 overflow-x-auto flex-nowrap">
112
139
  @for (tab of availableTabs(); track tab.id) {
113
140
  <p-button
141
+ *hasPermission="tab.permission"
114
142
  [label]="tab.label"
115
143
  [icon]="tab.icon"
116
144
  [outlined]="activeTab() !== tab.id"
117
145
  size="small"
146
+ styleClass="shrink-0"
118
147
  (onClick)="setActiveTab(tab.id)" />
119
148
  }
120
149
  </div>
@@ -136,8 +165,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
136
165
  }
137
166
  </div>
138
167
  </div>
139
- `, styles: [":host{display:block}\n"] }]
140
- }] });
168
+ `, styles: [".scrollbar-hide{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-hide::-webkit-scrollbar{display:none}\n"] }]
169
+ }], ctorParameters: () => [] });
141
170
 
142
171
  export { PermissionPageComponent };
143
- //# sourceMappingURL=flusys-ng-iam-permission-page.component-e_RX5mky.mjs.map
172
+ //# sourceMappingURL=flusys-ng-iam-permission-page.component-CmxOBJPu.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flusys-ng-iam-permission-page.component-CmxOBJPu.mjs","sources":["../../../projects/ng-iam/pages/permission/permission-page.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, effect, inject, signal, untracked } from '@angular/core';\nimport {\n AngularModule,\n HasPermissionDirective,\n PrimeModule,\n ROLE_ACTION_PERMISSIONS,\n USER_ROLE_PERMISSIONS,\n USER_ACTION_PERMISSIONS,\n COMPANY_ACTION_PERMISSIONS,\n} 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/** Permission codes for each tab */\nconst TAB_PERMISSIONS = {\n 'role-actions': ROLE_ACTION_PERMISSIONS.READ,\n 'user-roles': USER_ROLE_PERMISSIONS.READ,\n 'user-actions': USER_ACTION_PERMISSIONS.READ,\n 'company-actions': COMPANY_ACTION_PERMISSIONS.READ,\n} as const;\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 changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n AngularModule,\n PrimeModule,\n ButtonModule,\n TabsModule,\n HasPermissionDirective,\n RoleActionSelectorComponent,\n CompanyActionSelectorComponent,\n UserRoleSelectorComponent,\n UserActionSelectorComponent\n ],\n styles: `\n .scrollbar-hide {\n -ms-overflow-style: none;\n scrollbar-width: none;\n &::-webkit-scrollbar { display: none; }\n }\n `,\n template: `\n <div class=\"card\">\n <h3 class=\"text-xl font-semibold mb-4\">Permission Management</h3>\n\n <div class=\"scrollbar-hide flex gap-2 mb-4 overflow-x-auto flex-nowrap\">\n @for (tab of availableTabs(); track tab.id) {\n <p-button\n *hasPermission=\"tab.permission\"\n [label]=\"tab.label\"\n [icon]=\"tab.icon\"\n [outlined]=\"activeTab() !== tab.id\"\n size=\"small\"\n styleClass=\"shrink-0\"\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})\nexport class PermissionPageComponent {\n private readonly appConfig = inject(APP_CONFIG);\n\n readonly activeTab = signal<string>('');\n\n /**\n * All possible tabs based on permission mode (directive handles action permissions)\n */\n readonly availableTabs = computed(() => {\n const permissionMode = getPermissionMode(this.appConfig);\n const tabs: Array<{ id: string; label: string; icon: string; permission: 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 permission: TAB_PERMISSIONS['role-actions'],\n },\n {\n id: 'user-roles',\n label: 'User-Roles',\n icon: 'pi pi-user',\n permission: TAB_PERMISSIONS['user-roles'],\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 permission: TAB_PERMISSIONS['user-actions'],\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 permission: TAB_PERMISSIONS['company-actions'],\n });\n }\n\n return tabs;\n });\n\n constructor() {\n // Set default tab to first available tab\n effect(() => {\n const tabs = this.availableTabs();\n const currentTab = untracked(() => this.activeTab());\n\n // Only set if no active tab or current tab is not in available tabs\n if (!currentTab || !tabs.some((t) => t.id === currentTab)) {\n if (tabs.length > 0) {\n this.activeTab.set(tabs[0].id);\n }\n }\n });\n }\n\n setActiveTab(tabId: string): void {\n this.activeTab.set(tabId);\n }\n}\n"],"names":["i1"],"mappings":";;;;;;;;;AAkBA;AACA,MAAM,eAAe,GAAG;IACtB,cAAc,EAAE,uBAAuB,CAAC,IAAI;IAC5C,YAAY,EAAE,qBAAqB,CAAC,IAAI;IACxC,cAAc,EAAE,uBAAuB,CAAC,IAAI;IAC5C,iBAAiB,EAAE,0BAA0B,CAAC,IAAI;CAC1C;AAEV;;;;;;;;AAQG;MA2DU,uBAAuB,CAAA;AACjB,IAAA,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC;AAEtC,IAAA,SAAS,GAAG,MAAM,CAAS,EAAE,qDAAC;AAEvC;;AAEG;AACM,IAAA,aAAa,GAAG,QAAQ,CAAC,MAAK;QACrC,MAAM,cAAc,GAAG,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC;QACxD,MAAM,IAAI,GAA2E,EAAE;;QAGvF,IAAI,cAAc,KAAK,MAAM,IAAI,cAAc,KAAK,MAAM,EAAE;YAC1D,IAAI,CAAC,IAAI,CACP;AACE,gBAAA,EAAE,EAAE,cAAc;AAClB,gBAAA,KAAK,EAAE,cAAc;AACrB,gBAAA,IAAI,EAAE,cAAc;AACpB,gBAAA,UAAU,EAAE,eAAe,CAAC,cAAc,CAAC;aAC5C,EACD;AACE,gBAAA,EAAE,EAAE,YAAY;AAChB,gBAAA,KAAK,EAAE,YAAY;AACnB,gBAAA,IAAI,EAAE,YAAY;AAClB,gBAAA,UAAU,EAAE,eAAe,CAAC,YAAY,CAAC;AAC1C,aAAA,CACF;QACH;;QAGA,IAAI,cAAc,KAAK,QAAQ,IAAI,cAAc,KAAK,MAAM,EAAE;YAC5D,IAAI,CAAC,IAAI,CAAC;AACR,gBAAA,EAAE,EAAE,cAAc;AAClB,gBAAA,KAAK,EAAE,cAAc;AACrB,gBAAA,IAAI,EAAE,WAAW;AACjB,gBAAA,UAAU,EAAE,eAAe,CAAC,cAAc,CAAC;AAC5C,aAAA,CAAC;QACJ;;AAGA,QAAA,IAAI,uBAAuB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;YAC3C,IAAI,CAAC,IAAI,CAAC;AACR,gBAAA,EAAE,EAAE,iBAAiB;AACrB,gBAAA,KAAK,EAAE,iBAAiB;AACxB,gBAAA,IAAI,EAAE,gBAAgB;AACtB,gBAAA,UAAU,EAAE,eAAe,CAAC,iBAAiB,CAAC;AAC/C,aAAA,CAAC;QACJ;AAEA,QAAA,OAAO,IAAI;AACb,IAAA,CAAC,yDAAC;AAEF,IAAA,WAAA,GAAA;;QAEE,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE;AACjC,YAAA,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;;YAGpD,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC,EAAE;AACzD,gBAAA,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;AACnB,oBAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChC;YACF;AACF,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,YAAY,CAAC,KAAa,EAAA;AACxB,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;IAC3B;uGAtEW,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,qBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EApCxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,iHAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAnDC,aAAa,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACb,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,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,UAAA,EAAA,IAAA,EACX,YAAY,8BACZ,UAAU,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACV,sBAAsB,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACtB,2BAA2B,EAAA,QAAA,EAAA,6BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAC3B,8BAA8B,EAAA,QAAA,EAAA,gCAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAC9B,yBAAyB,sEACzB,2BAA2B,EAAA,QAAA,EAAA,6BAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FA6ClB,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBA1DnC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,qBAAqB,cACnB,IAAI,EAAA,eAAA,EACC,uBAAuB,CAAC,MAAM,EAAA,OAAA,EACtC;wBACP,aAAa;wBACb,WAAW;wBACX,YAAY;wBACZ,UAAU;wBACV,sBAAsB;wBACtB,2BAA2B;wBAC3B,8BAA8B;wBAC9B,yBAAyB;wBACzB;qBACD,EAAA,QAAA,EAQS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,iHAAA,CAAA,EAAA;;;;;"}
@@ -1,5 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, signal, computed, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { inject, signal, computed, effect, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { toSignal } from '@angular/core/rxjs-interop';
3
4
  import { form, required, FormField } from '@angular/forms/signals';
4
5
  import { ActivatedRoute, Router } from '@angular/router';
5
6
  import { APP_CONFIG, isCompanyFeatureEnabled } from '@flusys/ng-core';
@@ -7,10 +8,11 @@ import { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';
7
8
  import { AngularModule, PrimeModule } from '@flusys/ng-shared';
8
9
  import { MessageService } from 'primeng/api';
9
10
  import { firstValueFrom } from 'rxjs';
10
- import { R as RoleApiService } from './flusys-ng-iam-flusys-ng-iam-C-MQjakK.mjs';
11
+ import { R as RoleApiService } from './flusys-ng-iam-flusys-ng-iam-BPIpfrjN.mjs';
11
12
  import * as i1 from '@angular/forms';
12
- import * as i2 from 'primeng/inputtext';
13
- import * as i3 from 'primeng/button';
13
+ import * as i2 from 'primeng/button';
14
+ import * as i3 from 'primeng/checkbox';
15
+ import * as i4 from 'primeng/inputtext';
14
16
 
15
17
  /**
16
18
  * Role Form Page Component
@@ -23,6 +25,8 @@ class RoleFormPageComponent {
23
25
  companyContext = inject(LAYOUT_AUTH_STATE);
24
26
  roleApi = inject(RoleApiService);
25
27
  messageService = inject(MessageService);
28
+ routeParams = toSignal(this.route.paramMap);
29
+ initialized = false;
26
30
  /** Loading state */
27
31
  isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
28
32
  /** Existing role data when editing */
@@ -49,11 +53,17 @@ class RoleFormPageComponent {
49
53
  const model = this.formModel();
50
54
  return model.name.trim().length > 0;
51
55
  }, ...(ngDevMode ? [{ debugName: "isFormValid" }] : []));
52
- ngOnInit() {
53
- const id = this.route.snapshot.paramMap.get('id');
54
- if (id && id !== 'new') {
55
- this.loadRole(id);
56
- }
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
+ });
57
67
  }
58
68
  async loadRole(id) {
59
69
  this.isLoading.set(true);
@@ -71,20 +81,12 @@ class RoleFormPageComponent {
71
81
  });
72
82
  }
73
83
  else {
74
- this.messageService.add({
75
- severity: 'error',
76
- summary: 'Error',
77
- detail: 'Role not found.',
78
- });
84
+ // Error toast handled by global interceptor
79
85
  this.router.navigate(['/iam/roles']);
80
86
  }
81
87
  }
82
- catch (error) {
83
- this.messageService.add({
84
- severity: 'error',
85
- summary: 'Error',
86
- detail: 'Failed to load role.',
87
- });
88
+ catch {
89
+ // Error toast handled by global interceptor
88
90
  this.router.navigate(['/iam/roles']);
89
91
  }
90
92
  finally {
@@ -132,12 +134,8 @@ class RoleFormPageComponent {
132
134
  }
133
135
  this.router.navigate(['/iam/roles']);
134
136
  }
135
- catch (error) {
136
- this.messageService.add({
137
- severity: 'error',
138
- summary: 'Error',
139
- detail: error.message || 'Failed to save role.',
140
- });
137
+ catch {
138
+ // Error toast handled by global interceptor
141
139
  }
142
140
  finally {
143
141
  this.isLoading.set(false);
@@ -149,66 +147,53 @@ class RoleFormPageComponent {
149
147
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: RoleFormPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
150
148
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.3", type: RoleFormPageComponent, isStandalone: true, selector: "lib-role-form-page", ngImport: i0, template: `
151
149
  <div class="card">
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>
150
+ <h3 class="text-lg sm:text-xl font-semibold mb-4">
151
+ {{ isEditMode() ? 'Edit Role' : 'New Role' }}
152
+ </h3>
162
153
 
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>
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>
175
164
 
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>
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>
186
174
 
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>
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>
198
185
 
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>
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>
208
193
  </div>
209
194
 
210
195
  <!-- Actions -->
211
- <div class="flex justify-end gap-2 mt-6">
196
+ <div class="flex justify-end gap-2 md:col-span-2 pt-4">
212
197
  <p-button
213
198
  label="Cancel"
214
199
  severity="secondary"
@@ -222,7 +207,7 @@ class RoleFormPageComponent {
222
207
  </div>
223
208
  </form>
224
209
  </div>
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: "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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
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 });
226
211
  }
227
212
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: RoleFormPageComponent, decorators: [{
228
213
  type: Component,
@@ -233,66 +218,53 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
233
218
  changeDetection: ChangeDetectionStrategy.OnPush,
234
219
  template: `
235
220
  <div class="card">
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>
221
+ <h3 class="text-lg sm:text-xl font-semibold mb-4">
222
+ {{ isEditMode() ? 'Edit Role' : 'New Role' }}
223
+ </h3>
246
224
 
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>
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>
259
235
 
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>
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>
270
245
 
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>
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>
282
256
 
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>
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>
292
264
  </div>
293
265
 
294
266
  <!-- Actions -->
295
- <div class="flex justify-end gap-2 mt-6">
267
+ <div class="flex justify-end gap-2 md:col-span-2 pt-4">
296
268
  <p-button
297
269
  label="Cancel"
298
270
  severity="secondary"
@@ -308,7 +280,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
308
280
  </div>
309
281
  `,
310
282
  }]
311
- }] });
283
+ }], ctorParameters: () => [] });
312
284
 
313
285
  export { RoleFormPageComponent };
314
- //# sourceMappingURL=flusys-ng-iam-role-form-page.component-eZM1EPps.mjs.map
286
+ //# sourceMappingURL=flusys-ng-iam-role-form-page.component-ByNueI1a.mjs.map