@flusys/ng-iam 9.2.1 → 9.2.2
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-DJ-A1gc2.mjs → flusys-ng-iam-action-form-page.component-4B2Eue3o.mjs} +5 -5
- package/fesm2022/{flusys-ng-iam-action-form-page.component-DJ-A1gc2.mjs.map → flusys-ng-iam-action-form-page.component-4B2Eue3o.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-iam-action-list-page.component-D4jAQRwR.mjs → flusys-ng-iam-action-list-page.component-CY_gZRy7.mjs} +5 -5
- package/fesm2022/{flusys-ng-iam-action-list-page.component-D4jAQRwR.mjs.map → flusys-ng-iam-action-list-page.component-CY_gZRy7.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-iam-iam-container.component-CIdxVCSW.mjs → flusys-ng-iam-iam-container.component-DXvFhD07.mjs} +4 -4
- package/fesm2022/{flusys-ng-iam-iam-container.component-CIdxVCSW.mjs.map → flusys-ng-iam-iam-container.component-DXvFhD07.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-iam-permission-api.service-C7-Yxvz8.mjs → flusys-ng-iam-permission-api.service-ls0J1lec.mjs} +4 -4
- package/fesm2022/{flusys-ng-iam-permission-api.service-C7-Yxvz8.mjs.map → flusys-ng-iam-permission-api.service-ls0J1lec.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-iam-permission-page.component-DBRetWGs.mjs → flusys-ng-iam-permission-page.component-DvWuxHyU.mjs} +5 -5
- package/fesm2022/{flusys-ng-iam-permission-page.component-DBRetWGs.mjs.map → flusys-ng-iam-permission-page.component-DvWuxHyU.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-iam-role-api.service-OwPgmSFc.mjs → flusys-ng-iam-role-api.service-DVnfR0C1.mjs} +4 -4
- package/fesm2022/{flusys-ng-iam-role-api.service-OwPgmSFc.mjs.map → flusys-ng-iam-role-api.service-DVnfR0C1.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-iam-role-form-page.component-DnkWkbTF.mjs → flusys-ng-iam-role-form-page.component-BO-k7B9J.mjs} +5 -5
- package/fesm2022/{flusys-ng-iam-role-form-page.component-DnkWkbTF.mjs.map → flusys-ng-iam-role-form-page.component-BO-k7B9J.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-iam-role-list-page.component-Dhd0AtOg.mjs → flusys-ng-iam-role-list-page.component-DHrPv5FH.mjs} +5 -5
- package/fesm2022/{flusys-ng-iam-role-list-page.component-Dhd0AtOg.mjs.map → flusys-ng-iam-role-list-page.component-DHrPv5FH.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-iam-tree-utils-B1pBG4At.mjs → flusys-ng-iam-tree-utils-DglBny_Y.mjs} +4 -4
- package/fesm2022/{flusys-ng-iam-tree-utils-B1pBG4At.mjs.map → flusys-ng-iam-tree-utils-DglBny_Y.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-iam-user-action-selector.component-2wdl9Ci6.mjs → flusys-ng-iam-user-action-selector.component-D-vsK7Oz.mjs} +19 -19
- package/fesm2022/{flusys-ng-iam-user-action-selector.component-2wdl9Ci6.mjs.map → flusys-ng-iam-user-action-selector.component-D-vsK7Oz.mjs.map} +1 -1
- package/fesm2022/flusys-ng-iam.mjs +36 -36
- package/package.json +5 -5
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ActionApiService, t as buildActionParentTree } from "./flusys-ng-iam-tree-utils-
|
|
1
|
+
import { a as ActionApiService, t as buildActionParentTree } from "./flusys-ng-iam-tree-utils-DglBny_Y.mjs";
|
|
2
2
|
import { ActionType, LogicBuilderComponent } from "./flusys-ng-iam.mjs";
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
import { Component, computed, effect, inject, signal } from "@angular/core";
|
|
@@ -177,7 +177,7 @@ var ActionFormPageComponent = class ActionFormPageComponent {
|
|
|
177
177
|
}
|
|
178
178
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
179
179
|
minVersion: "12.0.0",
|
|
180
|
-
version: "22.2.
|
|
180
|
+
version: "22.2.2",
|
|
181
181
|
ngImport: i0,
|
|
182
182
|
type: ActionFormPageComponent,
|
|
183
183
|
deps: [],
|
|
@@ -185,7 +185,7 @@ var ActionFormPageComponent = class ActionFormPageComponent {
|
|
|
185
185
|
});
|
|
186
186
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
187
187
|
minVersion: "17.0.0",
|
|
188
|
-
version: "22.2.
|
|
188
|
+
version: "22.2.2",
|
|
189
189
|
type: ActionFormPageComponent,
|
|
190
190
|
isStandalone: true,
|
|
191
191
|
selector: "lib-action-form-page",
|
|
@@ -514,7 +514,7 @@ var ActionFormPageComponent = class ActionFormPageComponent {
|
|
|
514
514
|
};
|
|
515
515
|
i0.ɵɵngDeclareClassMetadata({
|
|
516
516
|
minVersion: "12.0.0",
|
|
517
|
-
version: "22.2.
|
|
517
|
+
version: "22.2.2",
|
|
518
518
|
ngImport: i0,
|
|
519
519
|
type: ActionFormPageComponent,
|
|
520
520
|
decorators: [{
|
|
@@ -682,4 +682,4 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
682
682
|
});
|
|
683
683
|
export { ActionFormPageComponent };
|
|
684
684
|
|
|
685
|
-
//# sourceMappingURL=flusys-ng-iam-action-form-page.component-
|
|
685
|
+
//# sourceMappingURL=flusys-ng-iam-action-form-page.component-4B2Eue3o.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-iam-action-form-page.component-DJ-A1gc2.mjs","names":[],"sources":["../../../projects/ng-iam/pages/action/action-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 {\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n MessageService,\n SelectComponent,\n TreeSelectComponent,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport {\n ILogicNode,\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport { LogicBuilderComponent } from '../../components/logic-builder.component';\nimport { ActionType, IAction } from '../../interfaces/action.interface';\nimport { ActionApiService } from '../../services/action-api.service';\nimport { TreeNode } from '@flusys/ng-ui';\nimport { buildActionParentTree } from '../../utils/tree-utils';\n\ninterface IActionFormModel {\n id: string;\n name: string;\n description: string;\n code: string;\n actionType: ActionType;\n permissionLogic: ILogicNode | null;\n parentId: string | null;\n serial: string;\n isActive: boolean;\n}\n\n@Component({\n selector: 'lib-action-form-page',\n imports: [\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n SelectComponent,\n TreeSelectComponent,\n UiIconComponent,\n FormField,\n LogicBuilderComponent,\n TranslatePipe,\n ],\n template: `\n <div class=\"card\">\n <h3 class=\"text-lg sm:text-xl font-semibold mb-4\">\n {{\n isEditMode()\n ? ('iam.action.edit' | translate)\n : ('iam.action.new' | translate)\n }}\n </h3>\n\n <form\n (submit)=\"onSubmit($event)\"\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.action.name' | translate }} *</label\n >\n <input\n fInputText\n id=\"name\"\n [formField]=\"actionForm.name\"\n [placeholder]=\"'iam.action.name.placeholder' | translate\"\n />\n </div>\n\n <!-- Code -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"code\" class=\"font-medium\">{{\n 'iam.action.code' | translate\n }}</label>\n <input\n fInputText\n id=\"code\"\n [formField]=\"actionForm.code\"\n [placeholder]=\"'iam.action.code.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]=\"actionForm.description\"\n [placeholder]=\"'shared.description.placeholder' | translate\"\n />\n </div>\n\n <!-- Action Type -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"actionType\" class=\"font-medium\"\n >{{ 'iam.action.type' | translate }} *</label\n >\n <f-select\n inputId=\"actionType\"\n [options]=\"actionTypes()\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [formField]=\"actionForm.actionType\"\n [placeholder]=\"'iam.action.type' | translate\"\n />\n </div>\n\n <!-- Parent Action -->\n <div class=\"flex flex-col gap-2\">\n <label class=\"font-medium\">{{\n 'iam.action.parent' | translate\n }}</label>\n <f-treeselect\n [options]=\"parentTreeNodes()\"\n [formField]=\"actionForm.parentId\"\n [placeholder]=\"'iam.action.select.parent' | translate\"\n [filter]=\"true\"\n [showClear]=\"true\"\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]=\"actionForm.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 md:col-span-2\">\n <f-checkbox\n [formField]=\"actionForm.isActive\"\n [binary]=\"true\"\n inputId=\"isActive\"\n />\n <label for=\"isActive\">{{ 'shared.active' | translate }}</label>\n </div>\n\n <!-- Permission Logic Builder -->\n <div class=\"md:col-span-2\">\n <lib-logic-builder\n [logic]=\"formModel().permissionLogic\"\n [actions]=\"allActionsForLogic()\"\n (logicChange)=\"onLogicChange($event)\"\n />\n </div>\n\n <!-- Actions -->\n <div class=\"flex justify-end gap-2 md:col-span-2 pt-4\">\n <button\n fButton\n type=\"button\"\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 ActionFormPageComponent {\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n private readonly actionApi = inject(ActionApiService);\n private readonly messageService = inject(MessageService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\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 existingAction = signal<IAction | null>(null);\n readonly isEditMode = computed(() => !!this.existingAction());\n readonly allActionsForLogic = signal<Array<{ id: string; name: string }>>([]);\n readonly allActions = signal<IAction[]>([]);\n\n readonly parentTreeNodes = computed<TreeNode<IAction>[]>(() =>\n buildActionParentTree(this.allActions(), this.existingAction()?.id),\n );\n\n readonly formModel = signal<IActionFormModel>({\n id: '',\n name: '',\n description: '',\n code: '',\n actionType: ActionType.BACKEND,\n permissionLogic: null,\n parentId: null,\n serial: '',\n isActive: true,\n });\n\n readonly actionTypes = computed(() => [\n {\n label: this.translate('iam.action.type.backend.label'),\n value: ActionType.BACKEND,\n },\n {\n label: this.translate('iam.action.type.frontend.label'),\n value: ActionType.FRONTEND,\n },\n {\n label: this.translate('iam.action.type.both.label'),\n value: ActionType.BOTH,\n },\n ]);\n\n readonly actionForm = form(this.formModel, (f) => {\n required(f.name, {\n message: this.translate('shared.validation.required', {\n field: this.translate('iam.action.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 this.initializeForm(params.get('id'));\n });\n }\n\n private async initializeForm(id: string | null): Promise<void> {\n try {\n const response = await this.actionApi.getAll({\n pagination: { currentPage: 0, pageSize: 10000 },\n select: ['id', 'name', 'code', 'actionType', 'permissionLogic', 'parentId'],\n });\n if (response?.success && response.data) {\n this.allActionsForLogic.set(\n response.data.map((a) => ({\n id: a.id!,\n name: a.name ?? this.translate('shared.unnamed'),\n })),\n );\n this.allActions.set(response.data);\n }\n } catch {\n // Ignored - form will show empty parent dropdown\n }\n\n if (id && id !== 'new') {\n await this.loadAction(id);\n }\n }\n\n async loadAction(id: string): Promise<void> {\n this.isLoading.set(true);\n try {\n const response = await this.actionApi.findById(id, [\n 'id',\n 'name',\n 'description',\n 'code',\n 'actionType',\n 'permissionLogic',\n 'parentId',\n 'serial',\n 'isActive',\n 'readOnly',\n ]);\n\n if (response?.success && response.data) {\n const action = response.data;\n\n if (action.readOnly) {\n this.messageService.add({\n severity: 'error',\n summary: this.translate('shared.error'),\n detail: this.translate('iam.action.readonly.edit.forbidden'),\n });\n this.router.navigate(['/iam/actions']);\n return;\n }\n\n this.existingAction.set(action);\n this.formModel.set({\n id: action.id ?? '',\n name: action.name ?? '',\n description: action.description ?? '',\n code: action.code ?? '',\n actionType: action.actionType ?? ActionType.BACKEND,\n permissionLogic: action.permissionLogic ?? null,\n parentId: action.parentId ?? null,\n serial: action.serial?.toString() ?? '',\n isActive: action.isActive ?? true,\n });\n } else {\n this.router.navigate(['/iam/actions']);\n }\n } catch {\n this.router.navigate(['/iam/actions']);\n } finally {\n this.isLoading.set(false);\n }\n }\n\n async onSubmit(event: Event): Promise<void> {\n event.preventDefault();\n\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 const dto = {\n ...formValue,\n description: formValue.description || undefined,\n code: formValue.code || undefined,\n parentId: formValue.parentId || undefined,\n serial: formValue.serial ? parseInt(formValue.serial, 10) : undefined,\n permissionLogic: formValue.permissionLogic ?? undefined,\n };\n\n const response = this.isEditMode()\n ? await this.actionApi.update(dto)\n : await this.actionApi.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/actions']);\n } catch {\n // Handled by global interceptor\n } finally {\n this.isLoading.set(false);\n }\n }\n\n onBack(): void {\n this.router.navigate(['/iam/actions']);\n }\n\n onLogicChange(logic: ILogicNode | null): void {\n this.formModel.update((model) => ({ ...model, permissionLogic: logic }));\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"flusys-ng-iam-action-form-page.component-4B2Eue3o.mjs","names":[],"sources":["../../../projects/ng-iam/pages/action/action-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 {\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n MessageService,\n SelectComponent,\n TreeSelectComponent,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport {\n ILogicNode,\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport { LogicBuilderComponent } from '../../components/logic-builder.component';\nimport { ActionType, IAction } from '../../interfaces/action.interface';\nimport { ActionApiService } from '../../services/action-api.service';\nimport { TreeNode } from '@flusys/ng-ui';\nimport { buildActionParentTree } from '../../utils/tree-utils';\n\ninterface IActionFormModel {\n id: string;\n name: string;\n description: string;\n code: string;\n actionType: ActionType;\n permissionLogic: ILogicNode | null;\n parentId: string | null;\n serial: string;\n isActive: boolean;\n}\n\n@Component({\n selector: 'lib-action-form-page',\n imports: [\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n SelectComponent,\n TreeSelectComponent,\n UiIconComponent,\n FormField,\n LogicBuilderComponent,\n TranslatePipe,\n ],\n template: `\n <div class=\"card\">\n <h3 class=\"text-lg sm:text-xl font-semibold mb-4\">\n {{\n isEditMode()\n ? ('iam.action.edit' | translate)\n : ('iam.action.new' | translate)\n }}\n </h3>\n\n <form\n (submit)=\"onSubmit($event)\"\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.action.name' | translate }} *</label\n >\n <input\n fInputText\n id=\"name\"\n [formField]=\"actionForm.name\"\n [placeholder]=\"'iam.action.name.placeholder' | translate\"\n />\n </div>\n\n <!-- Code -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"code\" class=\"font-medium\">{{\n 'iam.action.code' | translate\n }}</label>\n <input\n fInputText\n id=\"code\"\n [formField]=\"actionForm.code\"\n [placeholder]=\"'iam.action.code.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]=\"actionForm.description\"\n [placeholder]=\"'shared.description.placeholder' | translate\"\n />\n </div>\n\n <!-- Action Type -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"actionType\" class=\"font-medium\"\n >{{ 'iam.action.type' | translate }} *</label\n >\n <f-select\n inputId=\"actionType\"\n [options]=\"actionTypes()\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [formField]=\"actionForm.actionType\"\n [placeholder]=\"'iam.action.type' | translate\"\n />\n </div>\n\n <!-- Parent Action -->\n <div class=\"flex flex-col gap-2\">\n <label class=\"font-medium\">{{\n 'iam.action.parent' | translate\n }}</label>\n <f-treeselect\n [options]=\"parentTreeNodes()\"\n [formField]=\"actionForm.parentId\"\n [placeholder]=\"'iam.action.select.parent' | translate\"\n [filter]=\"true\"\n [showClear]=\"true\"\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]=\"actionForm.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 md:col-span-2\">\n <f-checkbox\n [formField]=\"actionForm.isActive\"\n [binary]=\"true\"\n inputId=\"isActive\"\n />\n <label for=\"isActive\">{{ 'shared.active' | translate }}</label>\n </div>\n\n <!-- Permission Logic Builder -->\n <div class=\"md:col-span-2\">\n <lib-logic-builder\n [logic]=\"formModel().permissionLogic\"\n [actions]=\"allActionsForLogic()\"\n (logicChange)=\"onLogicChange($event)\"\n />\n </div>\n\n <!-- Actions -->\n <div class=\"flex justify-end gap-2 md:col-span-2 pt-4\">\n <button\n fButton\n type=\"button\"\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 ActionFormPageComponent {\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n private readonly actionApi = inject(ActionApiService);\n private readonly messageService = inject(MessageService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\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 existingAction = signal<IAction | null>(null);\n readonly isEditMode = computed(() => !!this.existingAction());\n readonly allActionsForLogic = signal<Array<{ id: string; name: string }>>([]);\n readonly allActions = signal<IAction[]>([]);\n\n readonly parentTreeNodes = computed<TreeNode<IAction>[]>(() =>\n buildActionParentTree(this.allActions(), this.existingAction()?.id),\n );\n\n readonly formModel = signal<IActionFormModel>({\n id: '',\n name: '',\n description: '',\n code: '',\n actionType: ActionType.BACKEND,\n permissionLogic: null,\n parentId: null,\n serial: '',\n isActive: true,\n });\n\n readonly actionTypes = computed(() => [\n {\n label: this.translate('iam.action.type.backend.label'),\n value: ActionType.BACKEND,\n },\n {\n label: this.translate('iam.action.type.frontend.label'),\n value: ActionType.FRONTEND,\n },\n {\n label: this.translate('iam.action.type.both.label'),\n value: ActionType.BOTH,\n },\n ]);\n\n readonly actionForm = form(this.formModel, (f) => {\n required(f.name, {\n message: this.translate('shared.validation.required', {\n field: this.translate('iam.action.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 this.initializeForm(params.get('id'));\n });\n }\n\n private async initializeForm(id: string | null): Promise<void> {\n try {\n const response = await this.actionApi.getAll({\n pagination: { currentPage: 0, pageSize: 10000 },\n select: ['id', 'name', 'code', 'actionType', 'permissionLogic', 'parentId'],\n });\n if (response?.success && response.data) {\n this.allActionsForLogic.set(\n response.data.map((a) => ({\n id: a.id!,\n name: a.name ?? this.translate('shared.unnamed'),\n })),\n );\n this.allActions.set(response.data);\n }\n } catch {\n // Ignored - form will show empty parent dropdown\n }\n\n if (id && id !== 'new') {\n await this.loadAction(id);\n }\n }\n\n async loadAction(id: string): Promise<void> {\n this.isLoading.set(true);\n try {\n const response = await this.actionApi.findById(id, [\n 'id',\n 'name',\n 'description',\n 'code',\n 'actionType',\n 'permissionLogic',\n 'parentId',\n 'serial',\n 'isActive',\n 'readOnly',\n ]);\n\n if (response?.success && response.data) {\n const action = response.data;\n\n if (action.readOnly) {\n this.messageService.add({\n severity: 'error',\n summary: this.translate('shared.error'),\n detail: this.translate('iam.action.readonly.edit.forbidden'),\n });\n this.router.navigate(['/iam/actions']);\n return;\n }\n\n this.existingAction.set(action);\n this.formModel.set({\n id: action.id ?? '',\n name: action.name ?? '',\n description: action.description ?? '',\n code: action.code ?? '',\n actionType: action.actionType ?? ActionType.BACKEND,\n permissionLogic: action.permissionLogic ?? null,\n parentId: action.parentId ?? null,\n serial: action.serial?.toString() ?? '',\n isActive: action.isActive ?? true,\n });\n } else {\n this.router.navigate(['/iam/actions']);\n }\n } catch {\n this.router.navigate(['/iam/actions']);\n } finally {\n this.isLoading.set(false);\n }\n }\n\n async onSubmit(event: Event): Promise<void> {\n event.preventDefault();\n\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 const dto = {\n ...formValue,\n description: formValue.description || undefined,\n code: formValue.code || undefined,\n parentId: formValue.parentId || undefined,\n serial: formValue.serial ? parseInt(formValue.serial, 10) : undefined,\n permissionLogic: formValue.permissionLogic ?? undefined,\n };\n\n const response = this.isEditMode()\n ? await this.actionApi.update(dto)\n : await this.actionApi.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/actions']);\n } catch {\n // Handled by global interceptor\n } finally {\n this.isLoading.set(false);\n }\n }\n\n onBack(): void {\n this.router.navigate(['/iam/actions']);\n }\n\n onLogicChange(logic: ILogicNode | null): void {\n this.formModel.update((model) => ({ ...model, permissionLogic: logic }));\n }\n}\n"],"mappings":";;;;;;;;;AAkMA,IAAa,0BAAb,MAAa,wBAAuB;CACjB,QAAQ,OAAO,cAAc;CAC7B,SAAS,OAAO,MAAM;CACtB,YAAY,OAAO,gBAAgB;CACnC,iBAAiB,OAAO,cAAc;CACtC,mBAAmB,OAAO,kBAAkB,EAC3D,UAAU,KACX,CAAA;CACgB,cAAc,SAAS,KAAK,MAAM,QAAQ;CACnD,cAAc;CAEd,UACN,KACA,MAAsC;EAEtC,OAAO,KAAK,kBAAkB,UAAU,KAAK,IAAI,KAAK;CACxD;CAES,YAAY,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CACzB,iBAAiB,OAAuB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CAC7C,aAAa,eAAe,CAAC,CAAC,KAAK,eAAc,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CACpD,qBAAqB,OAA4C,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,qBAAA,CAAA,+BAAA,CAAA,CAAA;CACpE,aAAa,OAAkB,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAElC,kBAAkB,eACzB,sBAAsB,KAAK,WAAU,GAAI,KAAK,eAAc,CAAE,EAAE,EAAE,GACnE,GAAA,YAAA,CAAA,EAAA,WAAA,kBAAA,CAAA,+BAAA,CAAA,CAAA;CAEQ,YAAY,OAAyB;EAC5C,IAAI;EACJ,MAAM;EACN,aAAa;EACb,MAAM;EACN,YAAY,WAAW;EACvB,iBAAiB;EACjB,UAAU;EACV,QAAQ;EACR,UAAU;CACX,GAAC,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAEO,cAAc,eAAe;EACpC;GACE,OAAO,KAAK,UAAU,+BAA+B;GACrD,OAAO,WAAW;EACnB;EACD;GACE,OAAO,KAAK,UAAU,gCAAgC;GACtD,OAAO,WAAW;EACnB;EACD;GACE,OAAO,KAAK,UAAU,4BAA4B;GAClD,OAAO,WAAW;EACnB;CACF,GAAC,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAEO,aAAa,KAAK,KAAK,YAAY,MAAK;EAC/C,SAAS,EAAE,MAAM,EACf,SAAS,KAAK,UAAU,8BAA8B,EACpD,OAAO,KAAK,UAAU,iBAAiB,EACxC,CAAA,EACF,CAAA;CACH,CAAC;CAEQ,cAAc,eAAc;EAEnC,OADc,KAAK,UACZ,CAAA,CAAM,KAAK,KAAI,CAAE,CAAC,SAAS;CACpC,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAEF,cAAA;EACE,aAAY;GACV,MAAM,SAAS,KAAK,YAAW;GAC/B,IAAI,CAAC,UAAU,KAAK,aAAa;GAEjC,KAAK,cAAc;GACnB,KAAK,eAAe,OAAO,IAAI,IAAI,CAAC;EACtC,CAAC;CACH;CAEQ,MAAM,eAAe,IAAiB;EAC5C,IAAI;GACF,MAAM,WAAW,MAAM,KAAK,UAAU,OAAO;IAC3C,YAAY;KAAE,aAAa;KAAG,UAAU;IAAK;IAC7C,QAAQ;KAAC;KAAM;KAAQ;KAAQ;KAAc;KAAmB;IAAU;GAC3E,CAAA;GACD,IAAI,UAAU,WAAW,SAAS,MAAM;IACtC,KAAK,mBAAmB,IACtB,SAAS,KAAK,KAAK,OAAO;KACxB,IAAI,EAAE;KACN,MAAM,EAAE,QAAQ,KAAK,UAAU,gBAAgB;IAChD,EAAC,CAAC;IAEL,KAAK,WAAW,IAAI,SAAS,IAAI;GACnC;EACF,QAAQ,CAER;EAEA,IAAI,MAAM,OAAO,OACf,MAAM,KAAK,WAAW,EAAE;CAE5B;CAEA,MAAM,WAAW,IAAU;EACzB,KAAK,UAAU,IAAI,IAAI;EACvB,IAAI;GACF,MAAM,WAAW,MAAM,KAAK,UAAU,SAAS,IAAI;IACjD;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACD,CAAA;GAED,IAAI,UAAU,WAAW,SAAS,MAAM;IACtC,MAAM,SAAS,SAAS;IAExB,IAAI,OAAO,UAAU;KACnB,KAAK,eAAe,IAAI;MACtB,UAAU;MACV,SAAS,KAAK,UAAU,cAAc;MACtC,QAAQ,KAAK,UAAU,oCAAoC;KAC5D,CAAA;KACD,KAAK,OAAO,SAAS,CAAC,cAAc,CAAC;KACrC;IACF;IAEA,KAAK,eAAe,IAAI,MAAM;IAC9B,KAAK,UAAU,IAAI;KACjB,IAAI,OAAO,MAAM;KACjB,MAAM,OAAO,QAAQ;KACrB,aAAa,OAAO,eAAe;KACnC,MAAM,OAAO,QAAQ;KACrB,YAAY,OAAO,cAAc,WAAW;KAC5C,iBAAiB,OAAO,mBAAmB;KAC3C,UAAU,OAAO,YAAY;KAC7B,QAAQ,OAAO,QAAQ,SAAQ,KAAM;KACrC,UAAU,OAAO,YAAY;IAC9B,CAAA;GACH,OACE,KAAK,OAAO,SAAS,CAAC,cAAc,CAAC;EAEzC,QAAQ;GACN,KAAK,OAAO,SAAS,CAAC,cAAc,CAAC;EACvC,UAAU;GACR,KAAK,UAAU,IAAI,KAAK;EAC1B;CACF;CAEA,MAAM,SAAS,OAAY;EACzB,MAAM,eAAc;EAEpB,IAAI,CAAC,KAAK,YAAW,GAAI;GACvB,KAAK,eAAe,IAAI;IACtB,UAAU;IACV,SAAS,KAAK,UAAU,yBAAyB;IACjD,QAAQ,KAAK,UAAU,6BAA6B;GACrD,CAAA;GACD;EACF;EAEA,KAAK,UAAU,IAAI,IAAI;EAEvB,IAAI;GACF,MAAM,YAAY,KAAK,UAAS;GAChC,MAAM,MAAM;IACV,GAAG;IACH,aAAa,UAAU,eAAe;IACtC,MAAM,UAAU,QAAQ;IACxB,UAAU,UAAU,YAAY;IAChC,QAAQ,UAAU,SAAS,SAAS,UAAU,QAAQ,EAAE,IAAI;IAC5D,iBAAiB,UAAU,mBAAmB;GAC/C;GAED,MAAM,WAAW,KAAK,WAAU,IAC5B,MAAM,KAAK,UAAU,OAAO,GAAG,IAC/B,MAAM,KAAK,UAAU,OAAO,GAAG;GAEnC,KAAK,eAAe,IAAI;IACtB,UAAU;IACV,SAAS,KAAK,UAAU,gBAAgB;IACxC,QAAQ,SAAS,aACb,KAAK,UACH,SAAS,YACT,SAAS,gBAAmD,IAE7D,SAAS,WAAW;GAC1B,CAAA;GAED,KAAK,OAAO,SAAS,CAAC,cAAc,CAAC;EACvC,QAAQ,CAER,UAAU;GACR,KAAK,UAAU,IAAI,KAAK;EAC1B;CACF;CAEA,SAAM;EACJ,KAAK,OAAO,SAAS,CAAC,cAAc,CAAC;CACvC;CAEA,cAAc,OAAwB;EACpC,KAAK,UAAU,QAAQ,WAAW;GAAE,GAAG;GAAO,iBAAiB;EAAK,EAAG;CACzE;CA/MW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAuB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAvB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAuB,cAAA;EAAA,UAAA;EAAA,UAAA;EAAA,UAjJxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+IT,UAAA;EAAA,cAAA;GAAA;IAAA,MAAA;IAAA,MAzJC;IAAiB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACjB;IAAgB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAChB;IAAkB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAClB;IAAe,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACf;IAAmB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACnB;IAAe,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACf;IAAS,UAAA;IAAA,QAAA,CAAA,WAAA;IAAA,UAAA,CAAA,WAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACT;IAAqB,UAAA;IAAA,QAAA,CAAA,SAAA,SAAA;IAAA,SAAA,CAAA,aAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACrB;IAAa,MAAA;GAAA;EAAA;CAAA,CAAA;;AAmJJ,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAuB,YAAA,CAAA;EA9JnC,MAAA;EAAU,MAAA,CAAA;GACT,UAAU;GACV,SAAS;IACP;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACD;GACD,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgJX,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ActionApiService, r as convertActionToTreeNode } from "./flusys-ng-iam-tree-utils-
|
|
1
|
+
import { a as ActionApiService, r as convertActionToTreeNode } from "./flusys-ng-iam-tree-utils-DglBny_Y.mjs";
|
|
2
2
|
import { ActionPermittedUsersDialogComponent, ActionType } from "./flusys-ng-iam.mjs";
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
import { Component, computed, effect, inject, signal, untracked } from "@angular/core";
|
|
@@ -119,7 +119,7 @@ var ActionListPageComponent = class ActionListPageComponent {
|
|
|
119
119
|
}
|
|
120
120
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
121
121
|
minVersion: "12.0.0",
|
|
122
|
-
version: "22.2.
|
|
122
|
+
version: "22.2.2",
|
|
123
123
|
ngImport: i0,
|
|
124
124
|
type: ActionListPageComponent,
|
|
125
125
|
deps: [],
|
|
@@ -127,7 +127,7 @@ var ActionListPageComponent = class ActionListPageComponent {
|
|
|
127
127
|
});
|
|
128
128
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
129
129
|
minVersion: "17.0.0",
|
|
130
|
-
version: "22.2.
|
|
130
|
+
version: "22.2.2",
|
|
131
131
|
type: ActionListPageComponent,
|
|
132
132
|
isStandalone: true,
|
|
133
133
|
selector: "lib-action-list-page",
|
|
@@ -488,7 +488,7 @@ var ActionListPageComponent = class ActionListPageComponent {
|
|
|
488
488
|
};
|
|
489
489
|
i0.ɵɵngDeclareClassMetadata({
|
|
490
490
|
minVersion: "12.0.0",
|
|
491
|
-
version: "22.2.
|
|
491
|
+
version: "22.2.2",
|
|
492
492
|
ngImport: i0,
|
|
493
493
|
type: ActionListPageComponent,
|
|
494
494
|
decorators: [{
|
|
@@ -664,4 +664,4 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
664
664
|
});
|
|
665
665
|
export { ActionListPageComponent };
|
|
666
666
|
|
|
667
|
-
//# sourceMappingURL=flusys-ng-iam-action-list-page.component-
|
|
667
|
+
//# sourceMappingURL=flusys-ng-iam-action-list-page.component-CY_gZRy7.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-iam-action-list-page.component-D4jAQRwR.mjs","names":[],"sources":["../../../projects/ng-iam/pages/action/action-list-page.component.ts"],"sourcesContent":["import {\n Component,\n computed,\n effect,\n inject,\n signal,\n untracked,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { Router } from '@angular/router';\nimport { APP_CONFIG, getPermissionMode } from '@flusys/ng-core';\nimport { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';\nimport {\n ACTION_PERMISSIONS,\n HasPermissionDirective,\n TranslatePipe,\n TranslateService,\n USER_ACTION_PERMISSIONS,\n} from '@flusys/ng-shared';\nimport {\n ConfirmationService,\n FButtonDirective,\n IconFieldComponent,\n InputIconComponent,\n InputTextDirective,\n MessageService,\n TagComponent,\n TooltipDirective,\n TreeNode,\n TreeTableComponent,\n TreeTableTogglerComponent,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport { firstValueFrom } from 'rxjs';\nimport { ActionPermittedUsersDialogComponent } from '../../components/action-permitted-users-dialog.component';\nimport {\n ActionType,\n IAction,\n IActionTreeDto,\n} from '../../interfaces/action.interface';\nimport { ActionApiService } from '../../services/action-api.service';\nimport { convertActionToTreeNode } from '../../utils/tree-utils';\n\nfunction filterActionTree(\n nodes: IActionTreeDto[],\n search: string,\n): IActionTreeDto[] {\n const term = search.trim().toLowerCase();\n if (!term) return nodes;\n\n const filter = (items: IActionTreeDto[]): IActionTreeDto[] =>\n items.reduce<IActionTreeDto[]>((acc, node) => {\n const children = filter(node.children ?? []);\n const matches =\n node.name?.toLowerCase().includes(term) ||\n node.code?.toLowerCase().includes(term);\n if (matches || children.length) {\n acc.push({ ...node, children });\n }\n return acc;\n }, []);\n\n return filter(nodes);\n}\n\n@Component({\n selector: 'lib-action-list-page',\n imports: [\n FButtonDirective,\n FormsModule,\n IconFieldComponent,\n InputIconComponent,\n InputTextDirective,\n TagComponent,\n TooltipDirective,\n TreeTableComponent,\n TreeTableTogglerComponent,\n UiIconComponent,\n HasPermissionDirective,\n ActionPermittedUsersDialogComponent,\n TranslatePipe,\n ],\n template: `\n <div class=\"card\">\n <div\n class=\"flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 mb-4\"\n >\n <h3 class=\"text-lg sm:text-xl font-semibold\">\n {{ 'iam.action.title' | translate }}\n </h3>\n <div class=\"flex flex-wrap items-center gap-2 w-full sm:w-auto\">\n <f-iconfield class=\"w-full sm:w-64\">\n <f-inputicon icon=\"search\" />\n <input\n fInputText\n type=\"text\"\n [ngModel]=\"searchTerm()\"\n (ngModelChange)=\"onSearchChange($event)\"\n [placeholder]=\"'shared.search' | translate\"\n class=\"w-full\"\n />\n </f-iconfield>\n <button\n fButton\n *hasPermission=\"ACTION_PERMISSIONS.CREATE\"\n (click)=\"onCreate()\"\n class=\"w-full sm:w-auto\"\n >\n <ui-icon pButtonIcon name=\"plus\"></ui-icon>\n <span pButtonLabel>{{ 'iam.action.new' | translate }}</span>\n </button>\n </div>\n </div>\n\n <div class=\"overflow-x-auto -mx-4 sm:mx-0\">\n <f-treetable\n [value]=\"treeNodes()\"\n [loading]=\"isLoading()\"\n dataKey=\"id\"\n [tableStyle]=\"{ 'min-width': '50rem' }\"\n >\n <ng-template #header>\n <tr>\n <th>{{ 'iam.action.name' | translate }}</th>\n <th class=\"hidden md:table-cell\">\n {{ 'iam.action.code' | translate }}\n </th>\n <th>{{ 'iam.action.type' | translate }}</th>\n <th class=\"hidden sm:table-cell\">\n {{ 'shared.active' | translate }}\n </th>\n <th class=\"hidden lg:table-cell\">\n {{ 'shared.read.only' | translate }}\n </th>\n <th class=\"w-[100px]\">{{ 'shared.actions' | translate }}</th>\n </tr>\n </ng-template>\n <ng-template #body let-rowNode let-rowData=\"rowData\">\n <tr>\n <td>\n <f-treetabletoggler [rowNode]=\"rowNode\" />\n {{ rowData.name }}\n </td>\n <td class=\"hidden md:table-cell\">{{ rowData.code ?? '-' }}</td>\n <td>\n <f-tag\n [value]=\"getActionTypeLabel(rowData.actionType)\"\n [severity]=\"getActionTypeSeverity(rowData.actionType)\"\n />\n </td>\n <td class=\"hidden sm:table-cell\">\n <f-tag\n [value]=\"\n rowData.isActive\n ? ('shared.active' | translate)\n : ('shared.inactive' | translate)\n \"\n [severity]=\"rowData.isActive ? 'success' : 'secondary'\"\n />\n </td>\n <td class=\"hidden lg:table-cell\">\n <f-tag\n [value]=\"\n rowData.readOnly\n ? ('shared.yes' | translate)\n : ('shared.no' | translate)\n \"\n [severity]=\"rowData.readOnly ? 'warn' : 'secondary'\"\n />\n </td>\n <td>\n <div class=\"flex gap-1\">\n <button\n fButton\n *hasPermission=\"ACTION_PERMISSIONS.UPDATE\"\n [text]=\"true\"\n severity=\"secondary\"\n size=\"small\"\n [disabled]=\"rowData.readOnly\"\n [fTooltip]=\"'shared.edit' | translate\"\n (click)=\"onEdit(rowData)\"\n >\n <ui-icon pButtonIcon name=\"pencil\"></ui-icon>\n </button>\n @if (showActionUsers()) {\n <button\n fButton\n *hasPermission=\"USER_ACTION_PERMISSIONS.READ\"\n [text]=\"true\"\n severity=\"secondary\"\n size=\"small\"\n [fTooltip]=\"'iam.permission.view.users' | translate\"\n (click)=\"onViewUsers(rowData)\"\n >\n <ui-icon pButtonIcon name=\"users\"></ui-icon>\n </button>\n }\n <button\n fButton\n *hasPermission=\"ACTION_PERMISSIONS.DELETE\"\n [text]=\"true\"\n severity=\"danger\"\n size=\"small\"\n [fTooltip]=\"'shared.delete' | translate\"\n [disabled]=\"rowData.readOnly\"\n (click)=\"onDelete(rowData)\"\n >\n <ui-icon pButtonIcon name=\"trash\"></ui-icon>\n </button>\n </div>\n </td>\n </tr>\n </ng-template>\n <ng-template #emptymessage>\n <tr>\n <td colspan=\"6\" class=\"text-center py-4 text-muted-color\">\n {{ 'iam.action.no.actions' | translate }}\n </td>\n </tr>\n </ng-template>\n </f-treetable>\n </div>\n </div>\n\n <flusys-action-permitted-users-dialog\n [visible]=\"permittedUsersDialogVisible()\"\n [action]=\"selectedAction()\"\n (closed)=\"permittedUsersDialogVisible.set(false)\"\n />\n `,\n})\nexport class ActionListPageComponent {\n readonly ACTION_PERMISSIONS = ACTION_PERMISSIONS;\n readonly USER_ACTION_PERMISSIONS = USER_ACTION_PERMISSIONS;\n\n private readonly router = inject(Router);\n private readonly appConfig = inject(APP_CONFIG);\n private readonly companyContext = inject(LAYOUT_AUTH_STATE);\n private readonly actionApi = inject(ActionApiService);\n private readonly messageService = inject(MessageService);\n private readonly confirmationService = inject(ConfirmationService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n readonly isLoading = signal(false);\n private readonly rawActions = signal<IActionTreeDto[]>([]);\n private readonly _searchTerm = signal('');\n readonly searchTerm = this._searchTerm.asReadonly();\n readonly treeNodes = computed<TreeNode<IAction>[]>(() =>\n convertActionToTreeNode(\n filterActionTree(this.rawActions(), this._searchTerm()),\n ),\n );\n readonly permittedUsersDialogVisible = signal(false);\n readonly selectedAction = signal<IAction | null>(null);\n readonly showActionUsers = computed(() => {\n const permissionMode = getPermissionMode(this.appConfig);\n return permissionMode === 'direct' || permissionMode === 'full';\n });\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 private static readonly TYPE_SEVERITIES: Record<\n ActionType,\n 'info' | 'success' | 'warn'\n > = {\n [ActionType.BACKEND]: 'info',\n [ActionType.FRONTEND]: 'success',\n [ActionType.BOTH]: 'warn',\n };\n\n private static readonly TYPE_LABEL_KEYS: Record<ActionType, string> = {\n [ActionType.BACKEND]: 'iam.action.type.backend',\n [ActionType.FRONTEND]: 'iam.action.type.frontend',\n [ActionType.BOTH]: 'iam.action.type.both',\n };\n\n constructor() {\n effect(() => {\n this.companyContext.currentCompanyInfo();\n untracked(() => this.loadActions());\n });\n }\n\n private loadSeq = 0;\n\n private async loadActions(): Promise<void> {\n const seq = ++this.loadSeq;\n this.isLoading.set(true);\n try {\n const response = await firstValueFrom(this.actionApi.getTree());\n if (seq !== this.loadSeq) return;\n this.rawActions.set(response?.success ? (response.data ?? []) : []);\n } catch {\n // Handled by global interceptor\n } finally {\n if (seq === this.loadSeq) this.isLoading.set(false);\n }\n }\n\n onSearchChange(value: string): void {\n this._searchTerm.set(value);\n }\n\n getActionTypeLabel(type: ActionType): string {\n const key =\n ActionListPageComponent.TYPE_LABEL_KEYS[type] ?? 'shared.unknown';\n return this.translate(key);\n }\n\n getActionTypeSeverity(type: ActionType): 'info' | 'success' | 'warn' {\n return ActionListPageComponent.TYPE_SEVERITIES[type] ?? 'info';\n }\n\n onCreate(): void {\n this.router.navigate(['/iam/actions/new']);\n }\n\n onEdit(action: IAction): void {\n this.router.navigate(['/iam/actions', action.id]);\n }\n\n onViewUsers(action: IAction): void {\n this.selectedAction.set(action);\n this.permittedUsersDialogVisible.set(true);\n }\n\n onDelete(action: IAction): void {\n if (!action?.id || !action?.name) return;\n\n this.confirmationService.confirm({\n message: this.translate('shared.confirm.delete.item', {\n name: action.name,\n }),\n header: this.translate('iam.action.delete.title'),\n icon: 'exclamation-triangle',\n accept: async () => {\n try {\n const response = await this.actionApi.delete({\n id: action.id,\n type: 'permanent',\n });\n await this.loadActions();\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 } catch {\n // Handled by global interceptor\n }\n },\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"flusys-ng-iam-action-list-page.component-CY_gZRy7.mjs","names":[],"sources":["../../../projects/ng-iam/pages/action/action-list-page.component.ts"],"sourcesContent":["import {\n Component,\n computed,\n effect,\n inject,\n signal,\n untracked,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { Router } from '@angular/router';\nimport { APP_CONFIG, getPermissionMode } from '@flusys/ng-core';\nimport { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';\nimport {\n ACTION_PERMISSIONS,\n HasPermissionDirective,\n TranslatePipe,\n TranslateService,\n USER_ACTION_PERMISSIONS,\n} from '@flusys/ng-shared';\nimport {\n ConfirmationService,\n FButtonDirective,\n IconFieldComponent,\n InputIconComponent,\n InputTextDirective,\n MessageService,\n TagComponent,\n TooltipDirective,\n TreeNode,\n TreeTableComponent,\n TreeTableTogglerComponent,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport { firstValueFrom } from 'rxjs';\nimport { ActionPermittedUsersDialogComponent } from '../../components/action-permitted-users-dialog.component';\nimport {\n ActionType,\n IAction,\n IActionTreeDto,\n} from '../../interfaces/action.interface';\nimport { ActionApiService } from '../../services/action-api.service';\nimport { convertActionToTreeNode } from '../../utils/tree-utils';\n\nfunction filterActionTree(\n nodes: IActionTreeDto[],\n search: string,\n): IActionTreeDto[] {\n const term = search.trim().toLowerCase();\n if (!term) return nodes;\n\n const filter = (items: IActionTreeDto[]): IActionTreeDto[] =>\n items.reduce<IActionTreeDto[]>((acc, node) => {\n const children = filter(node.children ?? []);\n const matches =\n node.name?.toLowerCase().includes(term) ||\n node.code?.toLowerCase().includes(term);\n if (matches || children.length) {\n acc.push({ ...node, children });\n }\n return acc;\n }, []);\n\n return filter(nodes);\n}\n\n@Component({\n selector: 'lib-action-list-page',\n imports: [\n FButtonDirective,\n FormsModule,\n IconFieldComponent,\n InputIconComponent,\n InputTextDirective,\n TagComponent,\n TooltipDirective,\n TreeTableComponent,\n TreeTableTogglerComponent,\n UiIconComponent,\n HasPermissionDirective,\n ActionPermittedUsersDialogComponent,\n TranslatePipe,\n ],\n template: `\n <div class=\"card\">\n <div\n class=\"flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 mb-4\"\n >\n <h3 class=\"text-lg sm:text-xl font-semibold\">\n {{ 'iam.action.title' | translate }}\n </h3>\n <div class=\"flex flex-wrap items-center gap-2 w-full sm:w-auto\">\n <f-iconfield class=\"w-full sm:w-64\">\n <f-inputicon icon=\"search\" />\n <input\n fInputText\n type=\"text\"\n [ngModel]=\"searchTerm()\"\n (ngModelChange)=\"onSearchChange($event)\"\n [placeholder]=\"'shared.search' | translate\"\n class=\"w-full\"\n />\n </f-iconfield>\n <button\n fButton\n *hasPermission=\"ACTION_PERMISSIONS.CREATE\"\n (click)=\"onCreate()\"\n class=\"w-full sm:w-auto\"\n >\n <ui-icon pButtonIcon name=\"plus\"></ui-icon>\n <span pButtonLabel>{{ 'iam.action.new' | translate }}</span>\n </button>\n </div>\n </div>\n\n <div class=\"overflow-x-auto -mx-4 sm:mx-0\">\n <f-treetable\n [value]=\"treeNodes()\"\n [loading]=\"isLoading()\"\n dataKey=\"id\"\n [tableStyle]=\"{ 'min-width': '50rem' }\"\n >\n <ng-template #header>\n <tr>\n <th>{{ 'iam.action.name' | translate }}</th>\n <th class=\"hidden md:table-cell\">\n {{ 'iam.action.code' | translate }}\n </th>\n <th>{{ 'iam.action.type' | translate }}</th>\n <th class=\"hidden sm:table-cell\">\n {{ 'shared.active' | translate }}\n </th>\n <th class=\"hidden lg:table-cell\">\n {{ 'shared.read.only' | translate }}\n </th>\n <th class=\"w-[100px]\">{{ 'shared.actions' | translate }}</th>\n </tr>\n </ng-template>\n <ng-template #body let-rowNode let-rowData=\"rowData\">\n <tr>\n <td>\n <f-treetabletoggler [rowNode]=\"rowNode\" />\n {{ rowData.name }}\n </td>\n <td class=\"hidden md:table-cell\">{{ rowData.code ?? '-' }}</td>\n <td>\n <f-tag\n [value]=\"getActionTypeLabel(rowData.actionType)\"\n [severity]=\"getActionTypeSeverity(rowData.actionType)\"\n />\n </td>\n <td class=\"hidden sm:table-cell\">\n <f-tag\n [value]=\"\n rowData.isActive\n ? ('shared.active' | translate)\n : ('shared.inactive' | translate)\n \"\n [severity]=\"rowData.isActive ? 'success' : 'secondary'\"\n />\n </td>\n <td class=\"hidden lg:table-cell\">\n <f-tag\n [value]=\"\n rowData.readOnly\n ? ('shared.yes' | translate)\n : ('shared.no' | translate)\n \"\n [severity]=\"rowData.readOnly ? 'warn' : 'secondary'\"\n />\n </td>\n <td>\n <div class=\"flex gap-1\">\n <button\n fButton\n *hasPermission=\"ACTION_PERMISSIONS.UPDATE\"\n [text]=\"true\"\n severity=\"secondary\"\n size=\"small\"\n [disabled]=\"rowData.readOnly\"\n [fTooltip]=\"'shared.edit' | translate\"\n (click)=\"onEdit(rowData)\"\n >\n <ui-icon pButtonIcon name=\"pencil\"></ui-icon>\n </button>\n @if (showActionUsers()) {\n <button\n fButton\n *hasPermission=\"USER_ACTION_PERMISSIONS.READ\"\n [text]=\"true\"\n severity=\"secondary\"\n size=\"small\"\n [fTooltip]=\"'iam.permission.view.users' | translate\"\n (click)=\"onViewUsers(rowData)\"\n >\n <ui-icon pButtonIcon name=\"users\"></ui-icon>\n </button>\n }\n <button\n fButton\n *hasPermission=\"ACTION_PERMISSIONS.DELETE\"\n [text]=\"true\"\n severity=\"danger\"\n size=\"small\"\n [fTooltip]=\"'shared.delete' | translate\"\n [disabled]=\"rowData.readOnly\"\n (click)=\"onDelete(rowData)\"\n >\n <ui-icon pButtonIcon name=\"trash\"></ui-icon>\n </button>\n </div>\n </td>\n </tr>\n </ng-template>\n <ng-template #emptymessage>\n <tr>\n <td colspan=\"6\" class=\"text-center py-4 text-muted-color\">\n {{ 'iam.action.no.actions' | translate }}\n </td>\n </tr>\n </ng-template>\n </f-treetable>\n </div>\n </div>\n\n <flusys-action-permitted-users-dialog\n [visible]=\"permittedUsersDialogVisible()\"\n [action]=\"selectedAction()\"\n (closed)=\"permittedUsersDialogVisible.set(false)\"\n />\n `,\n})\nexport class ActionListPageComponent {\n readonly ACTION_PERMISSIONS = ACTION_PERMISSIONS;\n readonly USER_ACTION_PERMISSIONS = USER_ACTION_PERMISSIONS;\n\n private readonly router = inject(Router);\n private readonly appConfig = inject(APP_CONFIG);\n private readonly companyContext = inject(LAYOUT_AUTH_STATE);\n private readonly actionApi = inject(ActionApiService);\n private readonly messageService = inject(MessageService);\n private readonly confirmationService = inject(ConfirmationService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n readonly isLoading = signal(false);\n private readonly rawActions = signal<IActionTreeDto[]>([]);\n private readonly _searchTerm = signal('');\n readonly searchTerm = this._searchTerm.asReadonly();\n readonly treeNodes = computed<TreeNode<IAction>[]>(() =>\n convertActionToTreeNode(\n filterActionTree(this.rawActions(), this._searchTerm()),\n ),\n );\n readonly permittedUsersDialogVisible = signal(false);\n readonly selectedAction = signal<IAction | null>(null);\n readonly showActionUsers = computed(() => {\n const permissionMode = getPermissionMode(this.appConfig);\n return permissionMode === 'direct' || permissionMode === 'full';\n });\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 private static readonly TYPE_SEVERITIES: Record<\n ActionType,\n 'info' | 'success' | 'warn'\n > = {\n [ActionType.BACKEND]: 'info',\n [ActionType.FRONTEND]: 'success',\n [ActionType.BOTH]: 'warn',\n };\n\n private static readonly TYPE_LABEL_KEYS: Record<ActionType, string> = {\n [ActionType.BACKEND]: 'iam.action.type.backend',\n [ActionType.FRONTEND]: 'iam.action.type.frontend',\n [ActionType.BOTH]: 'iam.action.type.both',\n };\n\n constructor() {\n effect(() => {\n this.companyContext.currentCompanyInfo();\n untracked(() => this.loadActions());\n });\n }\n\n private loadSeq = 0;\n\n private async loadActions(): Promise<void> {\n const seq = ++this.loadSeq;\n this.isLoading.set(true);\n try {\n const response = await firstValueFrom(this.actionApi.getTree());\n if (seq !== this.loadSeq) return;\n this.rawActions.set(response?.success ? (response.data ?? []) : []);\n } catch {\n // Handled by global interceptor\n } finally {\n if (seq === this.loadSeq) this.isLoading.set(false);\n }\n }\n\n onSearchChange(value: string): void {\n this._searchTerm.set(value);\n }\n\n getActionTypeLabel(type: ActionType): string {\n const key =\n ActionListPageComponent.TYPE_LABEL_KEYS[type] ?? 'shared.unknown';\n return this.translate(key);\n }\n\n getActionTypeSeverity(type: ActionType): 'info' | 'success' | 'warn' {\n return ActionListPageComponent.TYPE_SEVERITIES[type] ?? 'info';\n }\n\n onCreate(): void {\n this.router.navigate(['/iam/actions/new']);\n }\n\n onEdit(action: IAction): void {\n this.router.navigate(['/iam/actions', action.id]);\n }\n\n onViewUsers(action: IAction): void {\n this.selectedAction.set(action);\n this.permittedUsersDialogVisible.set(true);\n }\n\n onDelete(action: IAction): void {\n if (!action?.id || !action?.name) return;\n\n this.confirmationService.confirm({\n message: this.translate('shared.confirm.delete.item', {\n name: action.name,\n }),\n header: this.translate('iam.action.delete.title'),\n icon: 'exclamation-triangle',\n accept: async () => {\n try {\n const response = await this.actionApi.delete({\n id: action.id,\n type: 'permanent',\n });\n await this.loadActions();\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 } catch {\n // Handled by global interceptor\n }\n },\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -49,7 +49,7 @@ var IamContainerComponent = class IamContainerComponent {
|
|
|
49
49
|
}, ...ngDevMode ? [{ debugName: "visibleTabs" }] : /* istanbul ignore next */ []);
|
|
50
50
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
51
51
|
minVersion: "12.0.0",
|
|
52
|
-
version: "22.2.
|
|
52
|
+
version: "22.2.2",
|
|
53
53
|
ngImport: i0,
|
|
54
54
|
type: IamContainerComponent,
|
|
55
55
|
deps: [],
|
|
@@ -57,7 +57,7 @@ var IamContainerComponent = class IamContainerComponent {
|
|
|
57
57
|
});
|
|
58
58
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
59
59
|
minVersion: "14.0.0",
|
|
60
|
-
version: "22.2.
|
|
60
|
+
version: "22.2.2",
|
|
61
61
|
type: IamContainerComponent,
|
|
62
62
|
isStandalone: true,
|
|
63
63
|
selector: "lib-iam-container",
|
|
@@ -107,7 +107,7 @@ var IamContainerComponent = class IamContainerComponent {
|
|
|
107
107
|
};
|
|
108
108
|
i0.ɵɵngDeclareClassMetadata({
|
|
109
109
|
minVersion: "12.0.0",
|
|
110
|
-
version: "22.2.
|
|
110
|
+
version: "22.2.2",
|
|
111
111
|
ngImport: i0,
|
|
112
112
|
type: IamContainerComponent,
|
|
113
113
|
decorators: [{
|
|
@@ -138,4 +138,4 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
138
138
|
});
|
|
139
139
|
export { IamContainerComponent };
|
|
140
140
|
|
|
141
|
-
//# sourceMappingURL=flusys-ng-iam-iam-container.component-
|
|
141
|
+
//# sourceMappingURL=flusys-ng-iam-iam-container.component-DXvFhD07.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-iam-iam-container.component-
|
|
1
|
+
{"version":3,"file":"flusys-ng-iam-iam-container.component-DXvFhD07.mjs","names":[],"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"],"mappings":";;;;;AAkDA,IAAa,wBAAb,MAAa,sBAAqB;CACf,YAAY,OAAO,UAAU;CAE7B,sBAAsB,OAAO,0BAA0B;CACvD,mBAAmB,OAAO,gBAAgB;CAG1C,UAAkB;EACjC;GACE,IAAI;GACJ,UAAU;GACV,MAAM;GACN,OAAO;GACP,YAAY,CAAC,mBAAmB,IAAI;EACrC;EACD;GACE,IAAI;GACJ,UAAU;GACV,MAAM;GACN,OAAO;GACP,cAAc;GACd,YAAY,CAAC,iBAAiB,IAAI;EACnC;EACD;GACE,IAAI;GACJ,UAAU;GACV,MAAM;GACN,OAAO;GACP,YAAY;IACV,wBAAwB;IACxB,sBAAsB;IACtB,wBAAwB;IACxB,2BAA2B;GAC5B;EACF;CACF;CAGQ,cAAc,eAA+B;EACpD,MAAM,iBAAiB,kBAAkB,KAAK,SAAS;EACvD,OAAO,KAAK,QACT,QAAQ,QAAO;GAId,OAHsB,KAAK,oBAAoB,iBAC7C,IAAI,UAGJ,MACC,CAAC,IAAI,gBACJ,mBAAmB,UACnB,mBAAmB;EAEzB,CAAC,CAAC,CACD,KAAK,SAAS;GACb,IAAI,IAAI;GACR,OAAO,KAAK,iBAAiB,UAAU,IAAI,QAAQ;GACnD,MAAM,IAAI;GACV,OAAO,IAAI;EACZ,EAAC;CACN,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CA1DS,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAqB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAArB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAqB,cAAA;EAAA,UAAA;EAAA,UAAA;EAAA,UAftB;;;;;;;;;;;;;;EAaT,UAAA;EAAA,cAAA;GAAA;IAAA,MAAA;IAAA,MAdS;IAAY,UAAA;IAAA,QAAA,CAAA,QAAA,kBAAA;IAAA,SAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,UAAA,CAAA,QAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAiB;IAAmB,UAAA;IAAA,QAAA,CAAA,MAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAlC;IAAa,MAAA;GAAA;EAAA;CAAA,CAAA;;AAgB1B,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAqB,YAAA,CAAA;EAlBjC,MAAA;EAAU,MAAA,CAAA;GACT,UAAU;GACV,SAAS;IAAC;IAAc;IAAe;GAAmB;GAC1D,UAAU;;;;;;;;;;;;;;EAcX,CAAA"}
|
|
@@ -50,7 +50,7 @@ var PermissionApiService = class PermissionApiService extends BaseApiService {
|
|
|
50
50
|
}
|
|
51
51
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
52
52
|
minVersion: "12.0.0",
|
|
53
|
-
version: "22.2.
|
|
53
|
+
version: "22.2.2",
|
|
54
54
|
ngImport: i0,
|
|
55
55
|
type: PermissionApiService,
|
|
56
56
|
deps: [],
|
|
@@ -58,14 +58,14 @@ var PermissionApiService = class PermissionApiService extends BaseApiService {
|
|
|
58
58
|
});
|
|
59
59
|
static ɵprov = i0.ɵɵngDeclareService({
|
|
60
60
|
minVersion: "22.0.0",
|
|
61
|
-
version: "22.2.
|
|
61
|
+
version: "22.2.2",
|
|
62
62
|
ngImport: i0,
|
|
63
63
|
type: PermissionApiService
|
|
64
64
|
});
|
|
65
65
|
};
|
|
66
66
|
i0.ɵɵngDeclareClassMetadata({
|
|
67
67
|
minVersion: "12.0.0",
|
|
68
|
-
version: "22.2.
|
|
68
|
+
version: "22.2.2",
|
|
69
69
|
ngImport: i0,
|
|
70
70
|
type: PermissionApiService,
|
|
71
71
|
decorators: [{ type: Service }],
|
|
@@ -73,4 +73,4 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
73
73
|
});
|
|
74
74
|
export { PermissionApiService as t };
|
|
75
75
|
|
|
76
|
-
//# sourceMappingURL=flusys-ng-iam-permission-api.service-
|
|
76
|
+
//# sourceMappingURL=flusys-ng-iam-permission-api.service-ls0J1lec.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-iam-permission-api.service-
|
|
1
|
+
{"version":3,"file":"flusys-ng-iam-permission-api.service-ls0J1lec.mjs","names":[],"sources":["../../../projects/ng-iam/services/permission-api.service.ts"],"sourcesContent":["import { Service } from '@angular/core';\nimport { BaseApiService } from '@flusys/ng-core';\nimport { ISingleResponse } from '@flusys/ng-shared';\nimport { Observable } from 'rxjs';\nimport {\n IActionUserResponseDto,\n IAssignCompanyActionsDto,\n IAssignRoleActionsDto,\n IAssignUserActionsDto,\n IAssignUserRolesDto,\n ICompanyActionResponseDto,\n IGetUserActionsDto,\n IGetUserRolesDto,\n IPermissionOperationResultDto,\n IRoleActionResponseDto,\n IRoleUserResponseDto,\n IUserActionResponseDto,\n IUserRoleResponseDto,\n} from '../interfaces/permission.interface';\n\n@Service()\nexport class PermissionApiService extends BaseApiService {\n constructor() {\n super('iam');\n }\n\n assignUserActions(data: IAssignUserActionsDto): Observable<ISingleResponse<IPermissionOperationResultDto>> {\n return this.http.post<ISingleResponse<IPermissionOperationResultDto>>(\n this.getUrl('permissions/user-actions/assign'),\n data,\n );\n }\n\n getUserActions(userId: string, query?: IGetUserActionsDto): Observable<ISingleResponse<IUserActionResponseDto[]>> {\n return this.http.post<ISingleResponse<IUserActionResponseDto[]>>(\n this.getUrl('permissions/get-user-actions'),\n { userId, companyId: query?.companyId, branchId: query?.branchId },\n );\n }\n\n assignUserRoles(data: IAssignUserRolesDto): Observable<ISingleResponse<IPermissionOperationResultDto>> {\n return this.http.post<ISingleResponse<IPermissionOperationResultDto>>(\n this.getUrl('permissions/user-roles/assign'),\n data,\n );\n }\n\n getUserRoles(userId: string, query?: IGetUserRolesDto): Observable<ISingleResponse<IUserRoleResponseDto[]>> {\n return this.http.post<ISingleResponse<IUserRoleResponseDto[]>>(\n this.getUrl('permissions/get-user-roles'),\n { userId, branchId: query?.branchId },\n );\n }\n\n assignRoleActions(data: IAssignRoleActionsDto): Observable<ISingleResponse<IPermissionOperationResultDto>> {\n return this.http.post<ISingleResponse<IPermissionOperationResultDto>>(\n this.getUrl('permissions/role-actions/assign'),\n data,\n );\n }\n\n getRoleActions(roleId: string): Observable<ISingleResponse<IRoleActionResponseDto[]>> {\n return this.http.post<ISingleResponse<IRoleActionResponseDto[]>>(\n this.getUrl('permissions/get-role-actions'),\n { roleId },\n );\n }\n\n /** Reverse lookup: users assigned to a role */\n getRoleUsers(roleId: string): Observable<ISingleResponse<IRoleUserResponseDto[]>> {\n return this.http.post<ISingleResponse<IRoleUserResponseDto[]>>(\n this.getUrl('permissions/get-role-users'),\n { roleId },\n );\n }\n\n /** Reverse lookup: users directly assigned an action */\n getActionUsers(actionId: string): Observable<ISingleResponse<IActionUserResponseDto[]>> {\n return this.http.post<ISingleResponse<IActionUserResponseDto[]>>(\n this.getUrl('permissions/get-action-users'),\n { actionId },\n );\n }\n\n assignCompanyActions(data: IAssignCompanyActionsDto): Observable<ISingleResponse<IPermissionOperationResultDto>> {\n return this.http.post<ISingleResponse<IPermissionOperationResultDto>>(\n this.getUrl('permissions/company-actions/assign'),\n data,\n );\n }\n\n getCompanyActions(companyId: string): Observable<ISingleResponse<ICompanyActionResponseDto[]>> {\n return this.http.post<ISingleResponse<ICompanyActionResponseDto[]>>(\n this.getUrl('permissions/get-company-actions'),\n { companyId },\n );\n }\n\n /** Effective roles for the authenticated user — merges company-wide and login-branch-specific assignments */\n getMyRoles(): Observable<ISingleResponse<IUserRoleResponseDto[]>> {\n return this.http.post<ISingleResponse<IUserRoleResponseDto[]>>(\n this.getUrl('permissions/my-roles'),\n {},\n );\n }\n\n /** Effective direct actions for the authenticated user — merges company-wide and login-branch-specific assignments */\n getMyActions(): Observable<ISingleResponse<IUserActionResponseDto[]>> {\n return this.http.post<ISingleResponse<IUserActionResponseDto[]>>(\n this.getUrl('permissions/my-actions'),\n {},\n );\n }\n}\n"],"mappings":";;;AAqBA,IAAa,uBAAb,MAAa,6BAA6B,eAAc;CACtD,cAAA;EACE,MAAM,KAAK;CACb;CAEA,kBAAkB,MAA2B;EAC3C,OAAO,KAAK,KAAK,KACf,KAAK,OAAO,iCAAiC,GAC7C,IAAI;CAER;CAEA,eAAe,QAAgB,OAA0B;EACvD,OAAO,KAAK,KAAK,KACf,KAAK,OAAO,8BAA8B,GAC1C;GAAE;GAAQ,WAAW,OAAO;GAAW,UAAU,OAAO;EAAQ,CAAE;CAEtE;CAEA,gBAAgB,MAAyB;EACvC,OAAO,KAAK,KAAK,KACf,KAAK,OAAO,+BAA+B,GAC3C,IAAI;CAER;CAEA,aAAa,QAAgB,OAAwB;EACnD,OAAO,KAAK,KAAK,KACf,KAAK,OAAO,4BAA4B,GACxC;GAAE;GAAQ,UAAU,OAAO;EAAQ,CAAE;CAEzC;CAEA,kBAAkB,MAA2B;EAC3C,OAAO,KAAK,KAAK,KACf,KAAK,OAAO,iCAAiC,GAC7C,IAAI;CAER;CAEA,eAAe,QAAc;EAC3B,OAAO,KAAK,KAAK,KACf,KAAK,OAAO,8BAA8B,GAC1C,EAAE,OAAM,CAAE;CAEd;CAGA,aAAa,QAAc;EACzB,OAAO,KAAK,KAAK,KACf,KAAK,OAAO,4BAA4B,GACxC,EAAE,OAAM,CAAE;CAEd;CAGA,eAAe,UAAgB;EAC7B,OAAO,KAAK,KAAK,KACf,KAAK,OAAO,8BAA8B,GAC1C,EAAE,SAAQ,CAAE;CAEhB;CAEA,qBAAqB,MAA8B;EACjD,OAAO,KAAK,KAAK,KACf,KAAK,OAAO,oCAAoC,GAChD,IAAI;CAER;CAEA,kBAAkB,WAAiB;EACjC,OAAO,KAAK,KAAK,KACf,KAAK,OAAO,iCAAiC,GAC7C,EAAE,UAAS,CAAE;CAEjB;CAGA,aAAU;EACR,OAAO,KAAK,KAAK,KACf,KAAK,OAAO,sBAAsB,GAClC,CAAA,CAAE;CAEN;CAGA,eAAY;EACV,OAAO,KAAK,KAAK,KACf,KAAK,OAAO,wBAAwB,GACpC,CAAA,CAAE;CAEN;CA3FW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAoB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAApB,OAAA,QAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;CAAoB,CAAA;;AAApB,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAoB,YAAA,CAAA,EADhC,MAAA,QAAA,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as RoleActionSelectorComponent, n as UserRoleSelectorComponent, r as CompanyActionSelectorComponent, t as UserActionSelectorComponent } from "./flusys-ng-iam-user-action-selector.component-
|
|
1
|
+
import { i as RoleActionSelectorComponent, n as UserRoleSelectorComponent, r as CompanyActionSelectorComponent, t as UserActionSelectorComponent } from "./flusys-ng-iam-user-action-selector.component-D-vsK7Oz.mjs";
|
|
2
2
|
import * as i0 from "@angular/core";
|
|
3
3
|
import { Component, computed, effect, inject, signal, untracked, viewChild } from "@angular/core";
|
|
4
4
|
import { COMPANY_ACTION_PERMISSIONS, HasPermissionDirective, PermissionValidatorService, ROLE_ACTION_PERMISSIONS, TranslatePipe, TranslateService, USER_ACTION_PERMISSIONS, USER_ROLE_PERMISSIONS } from "@flusys/ng-shared";
|
|
@@ -73,7 +73,7 @@ var PermissionPageComponent = class PermissionPageComponent {
|
|
|
73
73
|
}
|
|
74
74
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
75
75
|
minVersion: "12.0.0",
|
|
76
|
-
version: "22.2.
|
|
76
|
+
version: "22.2.2",
|
|
77
77
|
ngImport: i0,
|
|
78
78
|
type: PermissionPageComponent,
|
|
79
79
|
deps: [],
|
|
@@ -81,7 +81,7 @@ var PermissionPageComponent = class PermissionPageComponent {
|
|
|
81
81
|
});
|
|
82
82
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
83
83
|
minVersion: "17.0.0",
|
|
84
|
-
version: "22.2.
|
|
84
|
+
version: "22.2.2",
|
|
85
85
|
type: PermissionPageComponent,
|
|
86
86
|
isStandalone: true,
|
|
87
87
|
selector: "lib-permission-page",
|
|
@@ -222,7 +222,7 @@ var PermissionPageComponent = class PermissionPageComponent {
|
|
|
222
222
|
};
|
|
223
223
|
i0.ɵɵngDeclareClassMetadata({
|
|
224
224
|
minVersion: "12.0.0",
|
|
225
|
-
version: "22.2.
|
|
225
|
+
version: "22.2.2",
|
|
226
226
|
ngImport: i0,
|
|
227
227
|
type: PermissionPageComponent,
|
|
228
228
|
decorators: [{
|
|
@@ -302,4 +302,4 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
302
302
|
});
|
|
303
303
|
export { PermissionPageComponent };
|
|
304
304
|
|
|
305
|
-
//# sourceMappingURL=flusys-ng-iam-permission-page.component-
|
|
305
|
+
//# sourceMappingURL=flusys-ng-iam-permission-page.component-DvWuxHyU.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-iam-permission-page.component-
|
|
1
|
+
{"version":3,"file":"flusys-ng-iam-permission-page.component-DvWuxHyU.mjs","names":[],"sources":["../../../projects/ng-iam/pages/permission/permission-page.component.ts"],"sourcesContent":["import {\n Component,\n computed,\n effect,\n inject,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport {\n HasPermissionDirective,\n PermissionValidatorService,\n ROLE_ACTION_PERMISSIONS,\n USER_ROLE_PERMISSIONS,\n USER_ACTION_PERMISSIONS,\n COMPANY_ACTION_PERMISSIONS,\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport {\n APP_CONFIG,\n getPermissionMode,\n isCompanyFeatureEnabled,\n} 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 {\n ConfirmationService,\n TabComponent,\n TabListComponent,\n TabsComponent,\n UiIconComponent,\n} 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/** Structural shape shared by all four permission selector components */\ninterface IPermissionSelectorRef {\n readonly hasChanges: () => boolean;\n}\n\n/** Main permission management interface with tabs for role/user/company permission assignment */\n@Component({\n selector: 'lib-permission-page',\n imports: [\n TabComponent,\n TabListComponent,\n TabsComponent,\n UiIconComponent,\n HasPermissionDirective,\n TranslatePipe,\n RoleActionSelectorComponent,\n CompanyActionSelectorComponent,\n UserRoleSelectorComponent,\n UserActionSelectorComponent,\n ],\n template: `\n <div class=\"card\">\n <div class=\"mb-5\">\n <h3 class=\"text-xl font-semibold mb-1\">\n {{ 'iam.permission.title' | translate }}\n </h3>\n <p class=\"text-sm text-muted-color m-0\">\n {{ 'iam.permission.subtitle' | translate }}\n </p>\n </div>\n\n <f-tabs\n #tabs\n [value]=\"activeTab()\"\n (valueChange)=\"setActiveTab($event)\"\n [scrollable]=\"true\"\n >\n <f-tablist>\n @for (tab of availableTabs(); track tab.id) {\n <f-tab *hasPermission=\"tab.permission\" [value]=\"tab.id\">\n <ui-icon [name]=\"tab.icon\" class=\"mr-2\"></ui-icon\n >{{ tab.labelKey | translate }}\n </f-tab>\n }\n </f-tablist>\n </f-tabs>\n\n <div class=\"mt-5\">\n @switch (activeTab()) {\n @case ('role-actions') {\n <flusys-role-action-selector #selectorRef />\n }\n @case ('user-roles') {\n <flusys-user-role-selector #selectorRef />\n }\n @case ('user-actions') {\n <flusys-user-action-selector #selectorRef />\n }\n @case ('company-actions') {\n <flusys-company-action-selector #selectorRef />\n }\n }\n </div>\n </div>\n `,\n})\nexport class PermissionPageComponent {\n private readonly appConfig = inject(APP_CONFIG);\n private readonly confirmationService = inject(ConfirmationService);\n private readonly translateService = inject(TranslateService);\n private readonly permissionValidator = inject(PermissionValidatorService);\n\n private readonly tabsRef = viewChild<TabsComponent>('tabs');\n private readonly activeSelectorRef =\n viewChild<IPermissionSelectorRef>('selectorRef');\n\n readonly activeTab = signal<string>('');\n\n /** Available tabs based on permission mode and the user's read permissions */\n readonly availableTabs = computed(() => {\n const permissionMode = getPermissionMode(this.appConfig);\n const tabs: Array<{\n id: string;\n labelKey: string;\n icon: string;\n permission: string;\n }> = [];\n\n if (permissionMode === 'rbac' || permissionMode === 'full') {\n tabs.push(\n {\n id: 'role-actions',\n labelKey: 'iam.permission.role.actions',\n icon: 'shield',\n permission: TAB_PERMISSIONS['role-actions'],\n },\n {\n id: 'user-roles',\n labelKey: 'iam.permission.user.roles',\n icon: 'user',\n permission: TAB_PERMISSIONS['user-roles'],\n },\n );\n }\n\n if (permissionMode === 'direct' || permissionMode === 'full') {\n tabs.push({\n id: 'user-actions',\n labelKey: 'iam.permission.user.actions',\n icon: 'key',\n permission: TAB_PERMISSIONS['user-actions'],\n });\n }\n\n if (isCompanyFeatureEnabled(this.appConfig)) {\n tabs.push({\n id: 'company-actions',\n labelKey: 'iam.permission.company.actions',\n icon: 'building',\n permission: TAB_PERMISSIONS['company-actions'],\n });\n }\n\n return tabs.filter((tab) =>\n this.permissionValidator.hasPermission(tab.permission),\n );\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 this.activeTab.set(tabs[0]?.id ?? '');\n }\n });\n }\n\n setActiveTab(tabId: string | number): void {\n const nextTab = String(tabId);\n const previousTab = this.activeTab();\n if (nextTab === previousTab) return;\n\n if (this.activeSelectorRef()?.hasChanges()) {\n this.confirmationService.confirm({\n header: this.translateService.translate(\n 'iam.permission.unsaved.changes.title',\n ),\n message: this.translateService.translate(\n 'iam.permission.unsaved.changes.message',\n ),\n icon: 'exclamation-triangle',\n acceptLabel: this.translateService.translate(\n 'iam.permission.unsaved.changes.discard',\n ),\n rejectLabel: this.translateService.translate('shared.cancel'),\n accept: () => this.activeTab.set(nextTab),\n reject: () => this.tabsRef()?.value.set(previousTab),\n });\n return;\n }\n\n this.activeTab.set(nextTab);\n }\n}\n"],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@ var RoleApiService = class RoleApiService extends ApiResourceService {
|
|
|
7
7
|
}
|
|
8
8
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
9
9
|
minVersion: "12.0.0",
|
|
10
|
-
version: "22.2.
|
|
10
|
+
version: "22.2.2",
|
|
11
11
|
ngImport: i0,
|
|
12
12
|
type: RoleApiService,
|
|
13
13
|
deps: [],
|
|
@@ -15,14 +15,14 @@ var RoleApiService = class RoleApiService extends ApiResourceService {
|
|
|
15
15
|
});
|
|
16
16
|
static ɵprov = i0.ɵɵngDeclareService({
|
|
17
17
|
minVersion: "22.0.0",
|
|
18
|
-
version: "22.2.
|
|
18
|
+
version: "22.2.2",
|
|
19
19
|
ngImport: i0,
|
|
20
20
|
type: RoleApiService
|
|
21
21
|
});
|
|
22
22
|
};
|
|
23
23
|
i0.ɵɵngDeclareClassMetadata({
|
|
24
24
|
minVersion: "12.0.0",
|
|
25
|
-
version: "22.2.
|
|
25
|
+
version: "22.2.2",
|
|
26
26
|
ngImport: i0,
|
|
27
27
|
type: RoleApiService,
|
|
28
28
|
decorators: [{ type: Service }],
|
|
@@ -30,4 +30,4 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
30
30
|
});
|
|
31
31
|
export { RoleApiService as t };
|
|
32
32
|
|
|
33
|
-
//# sourceMappingURL=flusys-ng-iam-role-api.service-
|
|
33
|
+
//# sourceMappingURL=flusys-ng-iam-role-api.service-DVnfR0C1.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-iam-role-api.service-
|
|
1
|
+
{"version":3,"file":"flusys-ng-iam-role-api.service-DVnfR0C1.mjs","names":[],"sources":["../../../projects/ng-iam/services/role-api.service.ts"],"sourcesContent":["import { Service } from '@angular/core';\nimport { ApiResourceService } from '@flusys/ng-shared';\nimport { IRole, IUpdateRoleDto } from '../interfaces/role.interface';\n\n@Service()\nexport class RoleApiService extends ApiResourceService<IUpdateRoleDto, IRole> {\n constructor() {\n super('roles', 'iam');\n }\n}\n"],"mappings":";;;AAKA,IAAa,iBAAb,MAAa,uBAAuB,mBAAyC;CAC3E,cAAA;EACE,MAAM,SAAS,KAAK;CACtB;CAHW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAc,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAd,OAAA,QAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;CAAc,CAAA;;AAAd,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAc,YAAA,CAAA,EAD1B,MAAA,QAAA,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as RoleApiService } from "./flusys-ng-iam-role-api.service-
|
|
1
|
+
import { t as RoleApiService } from "./flusys-ng-iam-role-api.service-DVnfR0C1.mjs";
|
|
2
2
|
import * as i0 from "@angular/core";
|
|
3
3
|
import { Component, computed, effect, inject, signal } from "@angular/core";
|
|
4
4
|
import { TranslatePipe, TranslateService } from "@flusys/ng-shared";
|
|
@@ -111,7 +111,7 @@ var RoleFormPageComponent = class RoleFormPageComponent {
|
|
|
111
111
|
}
|
|
112
112
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
113
113
|
minVersion: "12.0.0",
|
|
114
|
-
version: "22.2.
|
|
114
|
+
version: "22.2.2",
|
|
115
115
|
ngImport: i0,
|
|
116
116
|
type: RoleFormPageComponent,
|
|
117
117
|
deps: [],
|
|
@@ -119,7 +119,7 @@ var RoleFormPageComponent = class RoleFormPageComponent {
|
|
|
119
119
|
});
|
|
120
120
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
121
121
|
minVersion: "17.0.0",
|
|
122
|
-
version: "22.2.
|
|
122
|
+
version: "22.2.2",
|
|
123
123
|
type: RoleFormPageComponent,
|
|
124
124
|
isStandalone: true,
|
|
125
125
|
selector: "lib-role-form-page",
|
|
@@ -310,7 +310,7 @@ var RoleFormPageComponent = class RoleFormPageComponent {
|
|
|
310
310
|
};
|
|
311
311
|
i0.ɵɵngDeclareClassMetadata({
|
|
312
312
|
minVersion: "12.0.0",
|
|
313
|
-
version: "22.2.
|
|
313
|
+
version: "22.2.2",
|
|
314
314
|
ngImport: i0,
|
|
315
315
|
type: RoleFormPageComponent,
|
|
316
316
|
decorators: [{
|
|
@@ -424,4 +424,4 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
424
424
|
});
|
|
425
425
|
export { RoleFormPageComponent };
|
|
426
426
|
|
|
427
|
-
//# sourceMappingURL=flusys-ng-iam-role-form-page.component-
|
|
427
|
+
//# sourceMappingURL=flusys-ng-iam-role-form-page.component-BO-k7B9J.mjs.map
|