@flusys/ng-iam 5.4.1 → 6.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/{flusys-ng-iam-action-form-page.component-BQJkl9pU.mjs → flusys-ng-iam-action-form-page.component-DTJT8Dc-.mjs} +102 -91
- package/fesm2022/flusys-ng-iam-action-form-page.component-DTJT8Dc-.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-action-list-page.component-BJ-tu6vu.mjs → flusys-ng-iam-action-list-page.component-B1hUE4lD.mjs} +71 -64
- package/fesm2022/flusys-ng-iam-action-list-page.component-B1hUE4lD.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-flusys-ng-iam-Bb39q1Bu.mjs → flusys-ng-iam-flusys-ng-iam-DzIO0zsO.mjs} +632 -547
- package/fesm2022/flusys-ng-iam-flusys-ng-iam-DzIO0zsO.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam-iam-container.component-D0m8u6nu.mjs +105 -0
- package/fesm2022/flusys-ng-iam-iam-container.component-D0m8u6nu.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-permission-page.component-D4IHueFW.mjs → flusys-ng-iam-permission-page.component-rcijgKmE.mjs} +33 -28
- package/fesm2022/flusys-ng-iam-permission-page.component-rcijgKmE.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-role-form-page.component-CX8LxsdO.mjs → flusys-ng-iam-role-form-page.component-DrUQ0taO.mjs} +62 -47
- package/fesm2022/flusys-ng-iam-role-form-page.component-DrUQ0taO.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-role-list-page.component-CNOsO-gH.mjs → flusys-ng-iam-role-list-page.component-BcS9_ysT.mjs} +77 -65
- package/fesm2022/flusys-ng-iam-role-list-page.component-BcS9_ysT.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam.mjs +1 -1
- package/package.json +10 -11
- package/types/flusys-ng-iam.d.ts +2 -2
- package/fesm2022/flusys-ng-iam-action-form-page.component-BQJkl9pU.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-action-list-page.component-BJ-tu6vu.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-flusys-ng-iam-Bb39q1Bu.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-iam-container.component-DAiS1Mtk.mjs +0 -118
- package/fesm2022/flusys-ng-iam-iam-container.component-DAiS1Mtk.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-permission-page.component-D4IHueFW.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-role-form-page.component-CX8LxsdO.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-role-list-page.component-CNOsO-gH.mjs.map +0 -1
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, computed, Component } from '@angular/core';
|
|
3
|
+
import { RouterOutlet } from '@angular/router';
|
|
4
|
+
import { APP_CONFIG, getPermissionMode } from '@flusys/ng-core';
|
|
5
|
+
import { PermissionValidatorService, TranslateService, ACTION_PERMISSIONS, ROLE_PERMISSIONS, ROLE_ACTION_PERMISSIONS, USER_ROLE_PERMISSIONS, USER_ACTION_PERMISSIONS, COMPANY_ACTION_PERMISSIONS, RouterTabsComponent, TranslatePipe } from '@flusys/ng-shared';
|
|
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
|
+
permissionValidator = inject(PermissionValidatorService);
|
|
16
|
+
translateService = inject(TranslateService);
|
|
17
|
+
/** All available tabs */
|
|
18
|
+
allTabs = [
|
|
19
|
+
{
|
|
20
|
+
id: 'actions',
|
|
21
|
+
labelKey: 'iam.action.title',
|
|
22
|
+
icon: 'bolt',
|
|
23
|
+
route: 'actions',
|
|
24
|
+
permission: [ACTION_PERMISSIONS.READ],
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: 'roles',
|
|
28
|
+
labelKey: 'iam.role.title',
|
|
29
|
+
icon: 'shield',
|
|
30
|
+
route: 'roles',
|
|
31
|
+
requiresRBAC: true,
|
|
32
|
+
permission: [ROLE_PERMISSIONS.READ],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'permissions',
|
|
36
|
+
labelKey: 'iam.permission.title',
|
|
37
|
+
icon: 'key',
|
|
38
|
+
route: 'permissions',
|
|
39
|
+
permission: [
|
|
40
|
+
ROLE_ACTION_PERMISSIONS.READ,
|
|
41
|
+
USER_ROLE_PERMISSIONS.READ,
|
|
42
|
+
USER_ACTION_PERMISSIONS.READ,
|
|
43
|
+
COMPANY_ACTION_PERMISSIONS.READ,
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
/** Visible tabs based on permission mode */
|
|
48
|
+
visibleTabs = computed(() => {
|
|
49
|
+
const permissionMode = getPermissionMode(this.appConfig);
|
|
50
|
+
return this.allTabs
|
|
51
|
+
.filter((tab) => {
|
|
52
|
+
const hasPermission = this.permissionValidator.hasAnyPermission(tab.permission);
|
|
53
|
+
return (hasPermission &&
|
|
54
|
+
(!tab.requiresRBAC ||
|
|
55
|
+
permissionMode === 'rbac' ||
|
|
56
|
+
permissionMode === 'full'));
|
|
57
|
+
})
|
|
58
|
+
.map((tab) => ({
|
|
59
|
+
id: tab.id,
|
|
60
|
+
label: this.translateService.translate(tab.labelKey),
|
|
61
|
+
icon: tab.icon,
|
|
62
|
+
route: tab.route,
|
|
63
|
+
}));
|
|
64
|
+
}, /* @ts-ignore */
|
|
65
|
+
...(ngDevMode ? [{ debugName: "visibleTabs" }] : /* istanbul ignore next */ []));
|
|
66
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: IamContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
67
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: IamContainerComponent, isStandalone: true, selector: "lib-iam-container", ngImport: i0, template: `
|
|
68
|
+
<div class="p-4">
|
|
69
|
+
<div class="mb-4">
|
|
70
|
+
<h1 class="text-xl sm:text-2xl font-bold m-0">
|
|
71
|
+
{{ 'iam.title' | translate }}
|
|
72
|
+
</h1>
|
|
73
|
+
<p class="text-muted-color mt-1">{{ 'iam.subtitle' | translate }}</p>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<lib-router-tabs [tabs]="visibleTabs()" class="mb-4" />
|
|
77
|
+
|
|
78
|
+
<router-outlet />
|
|
79
|
+
</div>
|
|
80
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: RouterTabsComponent, selector: "lib-router-tabs", inputs: ["tabs"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
81
|
+
}
|
|
82
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: IamContainerComponent, decorators: [{
|
|
83
|
+
type: Component,
|
|
84
|
+
args: [{
|
|
85
|
+
selector: 'lib-iam-container',
|
|
86
|
+
imports: [RouterOutlet, TranslatePipe, RouterTabsComponent],
|
|
87
|
+
template: `
|
|
88
|
+
<div class="p-4">
|
|
89
|
+
<div class="mb-4">
|
|
90
|
+
<h1 class="text-xl sm:text-2xl font-bold m-0">
|
|
91
|
+
{{ 'iam.title' | translate }}
|
|
92
|
+
</h1>
|
|
93
|
+
<p class="text-muted-color mt-1">{{ 'iam.subtitle' | translate }}</p>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<lib-router-tabs [tabs]="visibleTabs()" class="mb-4" />
|
|
97
|
+
|
|
98
|
+
<router-outlet />
|
|
99
|
+
</div>
|
|
100
|
+
`,
|
|
101
|
+
}]
|
|
102
|
+
}] });
|
|
103
|
+
|
|
104
|
+
export { IamContainerComponent };
|
|
105
|
+
//# sourceMappingURL=flusys-ng-iam-iam-container.component-D0m8u6nu.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flusys-ng-iam-iam-container.component-D0m8u6nu.mjs","sources":["../../../projects/ng-iam/pages/iam-container/iam-container.component.ts"],"sourcesContent":["import { Component, computed, inject } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\nimport { APP_CONFIG, getPermissionMode } from '@flusys/ng-core';\nimport {\n ACTION_PERMISSIONS,\n COMPANY_ACTION_PERMISSIONS,\n PermissionValidatorService,\n ROLE_ACTION_PERMISSIONS,\n ROLE_PERMISSIONS,\n RouterTabItem,\n RouterTabsComponent,\n TranslatePipe,\n TranslateService,\n USER_ACTION_PERMISSIONS,\n USER_ROLE_PERMISSIONS,\n} from '@flusys/ng-shared';\n\ninterface ITab {\n id: string;\n labelKey: string;\n icon: string;\n route: string;\n requiresRBAC?: boolean;\n permission: string[];\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 imports: [RouterOutlet, TranslatePipe, RouterTabsComponent],\n template: `\n <div class=\"p-4\">\n <div class=\"mb-4\">\n <h1 class=\"text-xl sm:text-2xl font-bold m-0\">\n {{ 'iam.title' | translate }}\n </h1>\n <p class=\"text-muted-color mt-1\">{{ 'iam.subtitle' | translate }}</p>\n </div>\n\n <lib-router-tabs [tabs]=\"visibleTabs()\" class=\"mb-4\" />\n\n <router-outlet />\n </div>\n `,\n})\nexport class IamContainerComponent {\n private readonly appConfig = inject(APP_CONFIG);\n\n private readonly permissionValidator = inject(PermissionValidatorService);\n private readonly translateService = inject(TranslateService);\n\n /** All available tabs */\n private readonly allTabs: ITab[] = [\n {\n id: 'actions',\n labelKey: 'iam.action.title',\n icon: 'bolt',\n route: 'actions',\n permission: [ACTION_PERMISSIONS.READ],\n },\n {\n id: 'roles',\n labelKey: 'iam.role.title',\n icon: 'shield',\n route: 'roles',\n requiresRBAC: true,\n permission: [ROLE_PERMISSIONS.READ],\n },\n {\n id: 'permissions',\n labelKey: 'iam.permission.title',\n icon: 'key',\n route: 'permissions',\n permission: [\n ROLE_ACTION_PERMISSIONS.READ,\n USER_ROLE_PERMISSIONS.READ,\n USER_ACTION_PERMISSIONS.READ,\n COMPANY_ACTION_PERMISSIONS.READ,\n ],\n },\n ];\n\n /** Visible tabs based on permission mode */\n readonly visibleTabs = computed<RouterTabItem[]>(() => {\n const permissionMode = getPermissionMode(this.appConfig);\n return this.allTabs\n .filter((tab) => {\n const hasPermission = this.permissionValidator.hasAnyPermission(\n tab.permission,\n );\n return (\n hasPermission &&\n (!tab.requiresRBAC ||\n permissionMode === 'rbac' ||\n permissionMode === 'full')\n );\n })\n .map((tab) => ({\n id: tab.id,\n label: this.translateService.translate(tab.labelKey),\n icon: tab.icon,\n route: tab.route,\n }));\n });\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { inject, signal, computed, effect, untracked, Component } from '@angular/core';
|
|
3
|
-
import { COMPANY_ACTION_PERMISSIONS, USER_ACTION_PERMISSIONS, USER_ROLE_PERMISSIONS, ROLE_ACTION_PERMISSIONS, AngularModule,
|
|
3
|
+
import { COMPANY_ACTION_PERMISSIONS, USER_ACTION_PERMISSIONS, USER_ROLE_PERMISSIONS, ROLE_ACTION_PERMISSIONS, AngularModule, HasPermissionDirective, TranslatePipe } from '@flusys/ng-shared';
|
|
4
4
|
import { APP_CONFIG, getPermissionMode, isCompanyFeatureEnabled } from '@flusys/ng-core';
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import { b as RoleActionSelectorComponent, C as CompanyActionSelectorComponent, U as UserRoleSelectorComponent, d as UserActionSelectorComponent } from './flusys-ng-iam-flusys-ng-iam-Bb39q1Bu.mjs';
|
|
5
|
+
import { b as RoleActionSelectorComponent, C as CompanyActionSelectorComponent, U as UserRoleSelectorComponent, d as UserActionSelectorComponent } from './flusys-ng-iam-flusys-ng-iam-DzIO0zsO.mjs';
|
|
6
|
+
import * as i2 from '@flusys/ng-ui';
|
|
7
|
+
import { UiModule } from '@flusys/ng-ui';
|
|
9
8
|
|
|
10
9
|
/** Permission codes for each tab */
|
|
11
10
|
const TAB_PERMISSIONS = {
|
|
@@ -17,22 +16,24 @@ const TAB_PERMISSIONS = {
|
|
|
17
16
|
/** Main permission management interface with tabs for role/user/company permission assignment */
|
|
18
17
|
class PermissionPageComponent {
|
|
19
18
|
appConfig = inject(APP_CONFIG);
|
|
20
|
-
activeTab = signal('',
|
|
19
|
+
activeTab = signal('', /* @ts-ignore */
|
|
20
|
+
...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
|
|
21
21
|
/** Available tabs based on permission mode */
|
|
22
22
|
availableTabs = computed(() => {
|
|
23
23
|
const permissionMode = getPermissionMode(this.appConfig);
|
|
24
24
|
const tabs = [];
|
|
25
25
|
if (permissionMode === 'rbac' || permissionMode === 'full') {
|
|
26
|
-
tabs.push({ id: 'role-actions', labelKey: 'iam.permission.role.actions', icon: '
|
|
26
|
+
tabs.push({ id: 'role-actions', labelKey: 'iam.permission.role.actions', icon: 'shield', permission: TAB_PERMISSIONS['role-actions'] }, { id: 'user-roles', labelKey: 'iam.permission.user.roles', icon: 'user', permission: TAB_PERMISSIONS['user-roles'] });
|
|
27
27
|
}
|
|
28
28
|
if (permissionMode === 'direct' || permissionMode === 'full') {
|
|
29
|
-
tabs.push({ id: 'user-actions', labelKey: 'iam.permission.user.actions', icon: '
|
|
29
|
+
tabs.push({ id: 'user-actions', labelKey: 'iam.permission.user.actions', icon: 'key', permission: TAB_PERMISSIONS['user-actions'] });
|
|
30
30
|
}
|
|
31
31
|
if (isCompanyFeatureEnabled(this.appConfig)) {
|
|
32
|
-
tabs.push({ id: 'company-actions', labelKey: 'iam.permission.company.actions', icon: '
|
|
32
|
+
tabs.push({ id: 'company-actions', labelKey: 'iam.permission.company.actions', icon: 'building', permission: TAB_PERMISSIONS['company-actions'] });
|
|
33
33
|
}
|
|
34
34
|
return tabs;
|
|
35
|
-
},
|
|
35
|
+
}, /* @ts-ignore */
|
|
36
|
+
...(ngDevMode ? [{ debugName: "availableTabs" }] : /* istanbul ignore next */ []));
|
|
36
37
|
constructor() {
|
|
37
38
|
effect(() => {
|
|
38
39
|
const tabs = this.availableTabs();
|
|
@@ -47,21 +48,24 @@ class PermissionPageComponent {
|
|
|
47
48
|
setActiveTab(tabId) {
|
|
48
49
|
this.activeTab.set(tabId);
|
|
49
50
|
}
|
|
50
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
51
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
51
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PermissionPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
52
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: PermissionPageComponent, isStandalone: true, selector: "lib-permission-page", ngImport: i0, template: `
|
|
52
53
|
<div class="card">
|
|
53
54
|
<h3 class="text-xl font-semibold mb-4">{{ 'iam.permission.title' | translate }}</h3>
|
|
54
55
|
|
|
55
56
|
<div class="scrollbar-hide flex gap-2 mb-4 overflow-x-auto flex-nowrap">
|
|
56
57
|
@for (tab of availableTabs(); track tab.id) {
|
|
57
|
-
<
|
|
58
|
+
<button
|
|
59
|
+
fButton
|
|
58
60
|
*hasPermission="tab.permission"
|
|
59
|
-
[label]="tab.labelKey | translate"
|
|
60
|
-
[icon]="tab.icon"
|
|
61
61
|
[outlined]="activeTab() !== tab.id"
|
|
62
62
|
size="small"
|
|
63
|
-
|
|
64
|
-
(
|
|
63
|
+
class="shrink-0"
|
|
64
|
+
(click)="setActiveTab(tab.id)"
|
|
65
|
+
>
|
|
66
|
+
<ui-icon pButtonIcon [name]="tab.icon"></ui-icon>
|
|
67
|
+
<span pButtonLabel>{{ tab.labelKey | translate }}</span>
|
|
68
|
+
</button>
|
|
65
69
|
}
|
|
66
70
|
</div>
|
|
67
71
|
|
|
@@ -82,15 +86,13 @@ class PermissionPageComponent {
|
|
|
82
86
|
}
|
|
83
87
|
</div>
|
|
84
88
|
</div>
|
|
85
|
-
`, 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:
|
|
89
|
+
`, 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: UiModule }, { kind: "directive", type: i2.FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "rounded", "raised", "fluid", "disabled", "loading", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: i2.UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill"] }, { 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" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
86
90
|
}
|
|
87
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
91
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PermissionPageComponent, decorators: [{
|
|
88
92
|
type: Component,
|
|
89
93
|
args: [{ selector: 'lib-permission-page', imports: [
|
|
90
94
|
AngularModule,
|
|
91
|
-
|
|
92
|
-
ButtonModule,
|
|
93
|
-
TabsModule,
|
|
95
|
+
UiModule,
|
|
94
96
|
HasPermissionDirective,
|
|
95
97
|
TranslatePipe,
|
|
96
98
|
RoleActionSelectorComponent,
|
|
@@ -103,14 +105,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
103
105
|
|
|
104
106
|
<div class="scrollbar-hide flex gap-2 mb-4 overflow-x-auto flex-nowrap">
|
|
105
107
|
@for (tab of availableTabs(); track tab.id) {
|
|
106
|
-
<
|
|
108
|
+
<button
|
|
109
|
+
fButton
|
|
107
110
|
*hasPermission="tab.permission"
|
|
108
|
-
[label]="tab.labelKey | translate"
|
|
109
|
-
[icon]="tab.icon"
|
|
110
111
|
[outlined]="activeTab() !== tab.id"
|
|
111
112
|
size="small"
|
|
112
|
-
|
|
113
|
-
(
|
|
113
|
+
class="shrink-0"
|
|
114
|
+
(click)="setActiveTab(tab.id)"
|
|
115
|
+
>
|
|
116
|
+
<ui-icon pButtonIcon [name]="tab.icon"></ui-icon>
|
|
117
|
+
<span pButtonLabel>{{ tab.labelKey | translate }}</span>
|
|
118
|
+
</button>
|
|
114
119
|
}
|
|
115
120
|
</div>
|
|
116
121
|
|
|
@@ -135,4 +140,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
135
140
|
}], ctorParameters: () => [] });
|
|
136
141
|
|
|
137
142
|
export { PermissionPageComponent };
|
|
138
|
-
//# sourceMappingURL=flusys-ng-iam-permission-page.component-
|
|
143
|
+
//# sourceMappingURL=flusys-ng-iam-permission-page.component-rcijgKmE.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flusys-ng-iam-permission-page.component-rcijgKmE.mjs","sources":["../../../projects/ng-iam/pages/permission/permission-page.component.ts"],"sourcesContent":["import { Component, computed, effect, inject, signal, untracked } from '@angular/core';\nimport {\n AngularModule,\n HasPermissionDirective,\n ROLE_ACTION_PERMISSIONS,\n USER_ROLE_PERMISSIONS,\n USER_ACTION_PERMISSIONS,\n COMPANY_ACTION_PERMISSIONS,\n TranslatePipe,\n} from '@flusys/ng-shared';\nimport { APP_CONFIG, getPermissionMode, isCompanyFeatureEnabled } from '@flusys/ng-core';\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';\nimport { UiModule } from '@flusys/ng-ui';\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/** Main permission management interface with tabs for role/user/company permission assignment */\n@Component({\n selector: 'lib-permission-page',\n imports: [\n AngularModule,\n UiModule,\n HasPermissionDirective,\n TranslatePipe,\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\">{{ 'iam.permission.title' | translate }}</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 <button\n fButton\n *hasPermission=\"tab.permission\"\n [outlined]=\"activeTab() !== tab.id\"\n size=\"small\"\n class=\"shrink-0\"\n (click)=\"setActiveTab(tab.id)\"\n >\n <ui-icon pButtonIcon [name]=\"tab.icon\"></ui-icon>\n <span pButtonLabel>{{ tab.labelKey | translate }}</span>\n </button>\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 /** Available tabs based on permission mode */\n readonly availableTabs = computed(() => {\n const permissionMode = getPermissionMode(this.appConfig);\n const tabs: Array<{ id: string; labelKey: string; icon: string; permission: string }> = [];\n\n if (permissionMode === 'rbac' || permissionMode === 'full') {\n tabs.push(\n { id: 'role-actions', labelKey: 'iam.permission.role.actions', icon: 'shield', permission: TAB_PERMISSIONS['role-actions'] },\n { id: 'user-roles', labelKey: 'iam.permission.user.roles', icon: 'user', permission: TAB_PERMISSIONS['user-roles'] }\n );\n }\n\n if (permissionMode === 'direct' || permissionMode === 'full') {\n tabs.push({ id: 'user-actions', labelKey: 'iam.permission.user.actions', icon: 'key', permission: TAB_PERMISSIONS['user-actions'] });\n }\n\n if (isCompanyFeatureEnabled(this.appConfig)) {\n tabs.push({ id: 'company-actions', labelKey: 'iam.permission.company.actions', icon: 'building', permission: TAB_PERMISSIONS['company-actions'] });\n }\n\n return tabs;\n });\n\n constructor() {\n effect(() => {\n const tabs = this.availableTabs();\n const currentTab = untracked(() => this.activeTab());\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":"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"}
|
|
@@ -5,13 +5,11 @@ import { form, required, FormField } from '@angular/forms/signals';
|
|
|
5
5
|
import { ActivatedRoute, Router } from '@angular/router';
|
|
6
6
|
import { APP_CONFIG, isCompanyFeatureEnabled } from '@flusys/ng-core';
|
|
7
7
|
import { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';
|
|
8
|
-
import
|
|
9
|
-
import { MessageService } from '
|
|
10
|
-
import {
|
|
8
|
+
import * as i2 from '@flusys/ng-ui';
|
|
9
|
+
import { MessageService, UiModule } from '@flusys/ng-ui';
|
|
10
|
+
import { TranslateService, AngularModule, TranslatePipe } from '@flusys/ng-shared';
|
|
11
|
+
import { R as RoleApiService } from './flusys-ng-iam-flusys-ng-iam-DzIO0zsO.mjs';
|
|
11
12
|
import * as i1 from '@angular/forms';
|
|
12
|
-
import * as i2 from 'primeng/button';
|
|
13
|
-
import * as i3 from 'primeng/checkbox';
|
|
14
|
-
import * as i4 from 'primeng/inputtext';
|
|
15
13
|
|
|
16
14
|
class RoleFormPageComponent {
|
|
17
15
|
route = inject(ActivatedRoute);
|
|
@@ -28,16 +26,20 @@ class RoleFormPageComponent {
|
|
|
28
26
|
translate(key, vars) {
|
|
29
27
|
return this.translateAdapter?.translate(key, vars) ?? key;
|
|
30
28
|
}
|
|
31
|
-
isLoading = signal(false,
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
isLoading = signal(false, /* @ts-ignore */
|
|
30
|
+
...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
|
|
31
|
+
existingRole = signal(null, /* @ts-ignore */
|
|
32
|
+
...(ngDevMode ? [{ debugName: "existingRole" }] : /* istanbul ignore next */ []));
|
|
33
|
+
isEditMode = computed(() => !!this.existingRole(), /* @ts-ignore */
|
|
34
|
+
...(ngDevMode ? [{ debugName: "isEditMode" }] : /* istanbul ignore next */ []));
|
|
34
35
|
formModel = signal({
|
|
35
36
|
id: '',
|
|
36
37
|
name: '',
|
|
37
38
|
description: '',
|
|
38
39
|
serial: '',
|
|
39
40
|
isActive: true,
|
|
40
|
-
},
|
|
41
|
+
}, /* @ts-ignore */
|
|
42
|
+
...(ngDevMode ? [{ debugName: "formModel" }] : /* istanbul ignore next */ []));
|
|
41
43
|
roleForm = form(this.formModel, (f) => {
|
|
42
44
|
required(f.name, {
|
|
43
45
|
message: this.translate('shared.validation.required', {
|
|
@@ -48,7 +50,8 @@ class RoleFormPageComponent {
|
|
|
48
50
|
isFormValid = computed(() => {
|
|
49
51
|
const model = this.formModel();
|
|
50
52
|
return model.name.trim().length > 0;
|
|
51
|
-
},
|
|
53
|
+
}, /* @ts-ignore */
|
|
54
|
+
...(ngDevMode ? [{ debugName: "isFormValid" }] : /* istanbul ignore next */ []));
|
|
52
55
|
constructor() {
|
|
53
56
|
effect(() => {
|
|
54
57
|
const params = this.routeParams();
|
|
@@ -134,8 +137,8 @@ class RoleFormPageComponent {
|
|
|
134
137
|
onBack() {
|
|
135
138
|
this.router.navigate(['/iam/roles']);
|
|
136
139
|
}
|
|
137
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
138
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
140
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: RoleFormPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
141
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: RoleFormPageComponent, isStandalone: true, selector: "lib-role-form-page", ngImport: i0, template: `
|
|
139
142
|
<div class="card">
|
|
140
143
|
<h3 class="text-lg sm:text-xl font-semibold mb-4">
|
|
141
144
|
{{
|
|
@@ -155,7 +158,7 @@ class RoleFormPageComponent {
|
|
|
155
158
|
>{{ 'iam.role.name' | translate }} *</label
|
|
156
159
|
>
|
|
157
160
|
<input
|
|
158
|
-
|
|
161
|
+
fInputText
|
|
159
162
|
id="name"
|
|
160
163
|
[formField]="roleForm.name"
|
|
161
164
|
[placeholder]="'iam.role.name.placeholder' | translate"
|
|
@@ -168,7 +171,7 @@ class RoleFormPageComponent {
|
|
|
168
171
|
'shared.description' | translate
|
|
169
172
|
}}</label>
|
|
170
173
|
<input
|
|
171
|
-
|
|
174
|
+
fInputText
|
|
172
175
|
id="description"
|
|
173
176
|
[formField]="roleForm.description"
|
|
174
177
|
[placeholder]="'shared.description.placeholder' | translate"
|
|
@@ -181,7 +184,7 @@ class RoleFormPageComponent {
|
|
|
181
184
|
'shared.display.order' | translate
|
|
182
185
|
}}</label>
|
|
183
186
|
<input
|
|
184
|
-
|
|
187
|
+
fInputText
|
|
185
188
|
id="serial"
|
|
186
189
|
type="number"
|
|
187
190
|
[formField]="roleForm.serial"
|
|
@@ -191,7 +194,7 @@ class RoleFormPageComponent {
|
|
|
191
194
|
|
|
192
195
|
<!-- Is Active -->
|
|
193
196
|
<div class="flex items-end gap-2 pb-1">
|
|
194
|
-
<
|
|
197
|
+
<f-checkbox
|
|
195
198
|
[formField]="roleForm.isActive"
|
|
196
199
|
[binary]="true"
|
|
197
200
|
inputId="isActive"
|
|
@@ -201,32 +204,38 @@ class RoleFormPageComponent {
|
|
|
201
204
|
|
|
202
205
|
<!-- Actions -->
|
|
203
206
|
<div class="flex justify-end gap-2 md:col-span-2 pt-4">
|
|
204
|
-
<
|
|
205
|
-
|
|
207
|
+
<button
|
|
208
|
+
fButton
|
|
206
209
|
severity="secondary"
|
|
207
210
|
[outlined]="true"
|
|
208
|
-
(
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
211
|
+
(click)="onBack()"
|
|
212
|
+
>
|
|
213
|
+
<span pButtonLabel>{{ 'shared.cancel' | translate }}</span>
|
|
214
|
+
</button>
|
|
215
|
+
<button
|
|
216
|
+
fButton
|
|
217
|
+
type="submit"
|
|
218
|
+
[disabled]="!isFormValid() || isLoading()"
|
|
219
|
+
>
|
|
220
|
+
@if (isLoading()) {
|
|
221
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
222
|
+
}
|
|
223
|
+
<span pButtonLabel>{{
|
|
212
224
|
isEditMode()
|
|
213
225
|
? ('shared.update' | translate)
|
|
214
226
|
: ('shared.create' | translate)
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
[loading]="isLoading()"
|
|
218
|
-
[disabled]="!isFormValid() || isLoading()"
|
|
219
|
-
/>
|
|
227
|
+
}}</span>
|
|
228
|
+
</button>
|
|
220
229
|
</div>
|
|
221
230
|
</form>
|
|
222
231
|
</div>
|
|
223
|
-
`, 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:
|
|
232
|
+
`, 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: UiModule }, { kind: "directive", type: i2.FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "rounded", "raised", "fluid", "disabled", "loading", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: i2.CheckboxComponent, selector: "f-checkbox", inputs: ["label", "binary", "disabled", "inputId", "invalid", "indeterminate", "touched", "styleClass", "checked"], outputs: ["onChange", "onBlur", "touch", "checkedChange"] }, { kind: "directive", type: i2.InputTextDirective, selector: "[fInputText]", inputs: ["invalid", "touched"] }, { kind: "component", type: i2.UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
224
233
|
}
|
|
225
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
234
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: RoleFormPageComponent, decorators: [{
|
|
226
235
|
type: Component,
|
|
227
236
|
args: [{
|
|
228
237
|
selector: 'lib-role-form-page',
|
|
229
|
-
imports: [AngularModule,
|
|
238
|
+
imports: [AngularModule, UiModule, FormField, TranslatePipe],
|
|
230
239
|
template: `
|
|
231
240
|
<div class="card">
|
|
232
241
|
<h3 class="text-lg sm:text-xl font-semibold mb-4">
|
|
@@ -247,7 +256,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
247
256
|
>{{ 'iam.role.name' | translate }} *</label
|
|
248
257
|
>
|
|
249
258
|
<input
|
|
250
|
-
|
|
259
|
+
fInputText
|
|
251
260
|
id="name"
|
|
252
261
|
[formField]="roleForm.name"
|
|
253
262
|
[placeholder]="'iam.role.name.placeholder' | translate"
|
|
@@ -260,7 +269,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
260
269
|
'shared.description' | translate
|
|
261
270
|
}}</label>
|
|
262
271
|
<input
|
|
263
|
-
|
|
272
|
+
fInputText
|
|
264
273
|
id="description"
|
|
265
274
|
[formField]="roleForm.description"
|
|
266
275
|
[placeholder]="'shared.description.placeholder' | translate"
|
|
@@ -273,7 +282,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
273
282
|
'shared.display.order' | translate
|
|
274
283
|
}}</label>
|
|
275
284
|
<input
|
|
276
|
-
|
|
285
|
+
fInputText
|
|
277
286
|
id="serial"
|
|
278
287
|
type="number"
|
|
279
288
|
[formField]="roleForm.serial"
|
|
@@ -283,7 +292,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
283
292
|
|
|
284
293
|
<!-- Is Active -->
|
|
285
294
|
<div class="flex items-end gap-2 pb-1">
|
|
286
|
-
<
|
|
295
|
+
<f-checkbox
|
|
287
296
|
[formField]="roleForm.isActive"
|
|
288
297
|
[binary]="true"
|
|
289
298
|
inputId="isActive"
|
|
@@ -293,22 +302,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
293
302
|
|
|
294
303
|
<!-- Actions -->
|
|
295
304
|
<div class="flex justify-end gap-2 md:col-span-2 pt-4">
|
|
296
|
-
<
|
|
297
|
-
|
|
305
|
+
<button
|
|
306
|
+
fButton
|
|
298
307
|
severity="secondary"
|
|
299
308
|
[outlined]="true"
|
|
300
|
-
(
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
309
|
+
(click)="onBack()"
|
|
310
|
+
>
|
|
311
|
+
<span pButtonLabel>{{ 'shared.cancel' | translate }}</span>
|
|
312
|
+
</button>
|
|
313
|
+
<button
|
|
314
|
+
fButton
|
|
315
|
+
type="submit"
|
|
316
|
+
[disabled]="!isFormValid() || isLoading()"
|
|
317
|
+
>
|
|
318
|
+
@if (isLoading()) {
|
|
319
|
+
<ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
|
|
320
|
+
}
|
|
321
|
+
<span pButtonLabel>{{
|
|
304
322
|
isEditMode()
|
|
305
323
|
? ('shared.update' | translate)
|
|
306
324
|
: ('shared.create' | translate)
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
[loading]="isLoading()"
|
|
310
|
-
[disabled]="!isFormValid() || isLoading()"
|
|
311
|
-
/>
|
|
325
|
+
}}</span>
|
|
326
|
+
</button>
|
|
312
327
|
</div>
|
|
313
328
|
</form>
|
|
314
329
|
</div>
|
|
@@ -317,4 +332,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
317
332
|
}], ctorParameters: () => [] });
|
|
318
333
|
|
|
319
334
|
export { RoleFormPageComponent };
|
|
320
|
-
//# sourceMappingURL=flusys-ng-iam-role-form-page.component-
|
|
335
|
+
//# sourceMappingURL=flusys-ng-iam-role-form-page.component-DrUQ0taO.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flusys-ng-iam-role-form-page.component-DrUQ0taO.mjs","sources":["../../../projects/ng-iam/pages/role/role-form-page.component.ts"],"sourcesContent":["import { Component, computed, effect, inject, signal } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { form, FormField, required } from '@angular/forms/signals';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { APP_CONFIG, isCompanyFeatureEnabled } from '@flusys/ng-core';\nimport { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';\nimport { MessageService } from '@flusys/ng-ui';\nimport {\n AngularModule,\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport { IRole } from '../../interfaces/role.interface';\nimport { RoleApiService } from '../../services/role-api.service';\nimport { UiModule } from '@flusys/ng-ui';\n\ninterface IRoleFormModel {\n id: string;\n name: string;\n description: string;\n serial: string;\n isActive: boolean;\n}\n\n@Component({\n selector: 'lib-role-form-page',\n imports: [AngularModule, UiModule, FormField, TranslatePipe],\n template: `\n <div class=\"card\">\n <h3 class=\"text-lg sm:text-xl font-semibold mb-4\">\n {{\n isEditMode()\n ? ('iam.role.edit' | translate)\n : ('iam.role.new' | translate)\n }}\n </h3>\n\n <form\n (ngSubmit)=\"onSubmit()\"\n class=\"grid grid-cols-1 md:grid-cols-2 gap-4\"\n >\n <!-- Name -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"name\" class=\"font-medium\"\n >{{ 'iam.role.name' | translate }} *</label\n >\n <input\n fInputText\n id=\"name\"\n [formField]=\"roleForm.name\"\n [placeholder]=\"'iam.role.name.placeholder' | translate\"\n />\n </div>\n\n <!-- Description -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"description\" class=\"font-medium\">{{\n 'shared.description' | translate\n }}</label>\n <input\n fInputText\n id=\"description\"\n [formField]=\"roleForm.description\"\n [placeholder]=\"'shared.description.placeholder' | translate\"\n />\n </div>\n\n <!-- Order -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"serial\" class=\"font-medium\">{{\n 'shared.display.order' | translate\n }}</label>\n <input\n fInputText\n id=\"serial\"\n type=\"number\"\n [formField]=\"roleForm.serial\"\n [placeholder]=\"'shared.display.order.placeholder' | translate\"\n />\n </div>\n\n <!-- Is Active -->\n <div class=\"flex items-end gap-2 pb-1\">\n <f-checkbox\n [formField]=\"roleForm.isActive\"\n [binary]=\"true\"\n inputId=\"isActive\"\n />\n <label for=\"isActive\">{{ 'shared.active' | translate }}</label>\n </div>\n\n <!-- Actions -->\n <div class=\"flex justify-end gap-2 md:col-span-2 pt-4\">\n <button\n fButton\n severity=\"secondary\"\n [outlined]=\"true\"\n (click)=\"onBack()\"\n >\n <span pButtonLabel>{{ 'shared.cancel' | translate }}</span>\n </button>\n <button\n fButton\n type=\"submit\"\n [disabled]=\"!isFormValid() || isLoading()\"\n >\n @if (isLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{ \n isEditMode()\n ? ('shared.update' | translate)\n : ('shared.create' | translate)\n }}</span>\n </button>\n </div>\n </form>\n </div>\n `,\n})\nexport class RoleFormPageComponent {\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n private readonly appConfig = inject(APP_CONFIG);\n private readonly companyContext = inject(LAYOUT_AUTH_STATE);\n private readonly roleApi = inject(RoleApiService);\n private readonly messageService = inject(MessageService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n private readonly routeParams = toSignal(this.route.paramMap);\n private initialized = false;\n\n private translate(\n key: string,\n vars?: Record<string, string | number>,\n ): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n\n readonly isLoading = signal(false);\n readonly existingRole = signal<IRole | null>(null);\n readonly isEditMode = computed(() => !!this.existingRole());\n\n readonly formModel = signal<IRoleFormModel>({\n id: '',\n name: '',\n description: '',\n serial: '',\n isActive: true,\n });\n\n readonly roleForm = form(this.formModel, (f) => {\n required(f.name, {\n message: this.translate('shared.validation.required', {\n field: this.translate('iam.role.name'),\n }),\n });\n });\n\n readonly isFormValid = computed(() => {\n const model = this.formModel();\n return model.name.trim().length > 0;\n });\n\n constructor() {\n effect(() => {\n const params = this.routeParams();\n if (!params || this.initialized) return;\n\n this.initialized = true;\n const id = params.get('id');\n if (id && id !== 'new') {\n this.loadRole(id);\n }\n });\n }\n\n async loadRole(id: string): Promise<void> {\n this.isLoading.set(true);\n try {\n const response = await this.roleApi.findById(id);\n const role = response?.data;\n\n if (role) {\n this.existingRole.set(role);\n this.formModel.set({\n id: role.id,\n name: role.name,\n description: role.description ?? '',\n serial: role.serial?.toString() ?? '',\n isActive: role.isActive,\n });\n } else {\n // Error toast handled by global interceptor\n this.router.navigate(['/iam/roles']);\n }\n } catch {\n // Error toast handled by global interceptor\n this.router.navigate(['/iam/roles']);\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: this.translate('shared.validation.error'),\n detail: this.translate('shared.fill.required.fields'),\n });\n return;\n }\n\n this.isLoading.set(true);\n\n try {\n const formValue = this.formModel();\n\n // Get company context if feature enabled\n const companyId = isCompanyFeatureEnabled(this.appConfig)\n ? this.companyContext.currentCompanyInfo()?.id || undefined\n : undefined;\n\n // Convert empty strings to undefined for DTO compatibility\n const dto = {\n ...formValue,\n description: formValue.description || undefined,\n serial: formValue.serial ? parseInt(formValue.serial, 10) : undefined,\n companyId: this.isEditMode() ? undefined : companyId,\n };\n\n const response = this.isEditMode()\n ? await this.roleApi.update(dto)\n : await this.roleApi.insert(dto);\n\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response.messageKey\n ? this.translate(\n response.messageKey,\n response.messageVariables as Record<string, string | number>,\n )\n : (response.message ?? ''),\n });\n\n this.router.navigate(['/iam/roles']);\n } catch {\n // Error toast handled by global interceptor\n } finally {\n this.isLoading.set(false);\n }\n }\n\n onBack(): void {\n this.router.navigate(['/iam/roles']);\n }\n}\n"],"names":[],"mappings":"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"}
|