@flusys/ng-iam 8.1.2 → 8.1.3
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-DunIW6W4.mjs → flusys-ng-iam-action-form-page.component-WXFLmq16.mjs} +2 -2
- package/fesm2022/{flusys-ng-iam-action-form-page.component-DunIW6W4.mjs.map → flusys-ng-iam-action-form-page.component-WXFLmq16.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-iam-action-list-page.component-CgoLgAqd.mjs → flusys-ng-iam-action-list-page.component-CFZ5F_vQ.mjs} +2 -2
- package/fesm2022/{flusys-ng-iam-action-list-page.component-CgoLgAqd.mjs.map → flusys-ng-iam-action-list-page.component-CFZ5F_vQ.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-iam-flusys-ng-iam-CJC610eS.mjs → flusys-ng-iam-flusys-ng-iam-yNMJXm89.mjs} +160 -18
- package/fesm2022/flusys-ng-iam-flusys-ng-iam-yNMJXm89.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-permission-page.component-y86NW53S.mjs → flusys-ng-iam-permission-page.component-C_eWwf0e.mjs} +2 -2
- package/fesm2022/{flusys-ng-iam-permission-page.component-y86NW53S.mjs.map → flusys-ng-iam-permission-page.component-C_eWwf0e.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-iam-role-form-page.component-H3qpNn3J.mjs → flusys-ng-iam-role-form-page.component-Dvn3yFxQ.mjs} +2 -2
- package/fesm2022/{flusys-ng-iam-role-form-page.component-H3qpNn3J.mjs.map → flusys-ng-iam-role-form-page.component-Dvn3yFxQ.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-iam-role-list-page.component-BoKQbhu5.mjs → flusys-ng-iam-role-list-page.component-DmIkc8YG.mjs} +2 -2
- package/fesm2022/{flusys-ng-iam-role-list-page.component-BoKQbhu5.mjs.map → flusys-ng-iam-role-list-page.component-DmIkc8YG.mjs.map} +1 -1
- package/fesm2022/flusys-ng-iam.mjs +1 -1
- package/package.json +5 -5
- package/types/flusys-ng-iam.d.ts +64 -6
- package/fesm2022/flusys-ng-iam-flusys-ng-iam-CJC610eS.mjs.map +0 -1
|
@@ -5,7 +5,7 @@ import { form, required, FormField } from '@angular/forms/signals';
|
|
|
5
5
|
import { ActivatedRoute, Router } from '@angular/router';
|
|
6
6
|
import { MessageService, CheckboxComponent, FButtonDirective, InputTextDirective, SelectComponent, TreeSelectComponent, UiIconComponent } from '@flusys/ng-ui';
|
|
7
7
|
import { TranslateService, TranslatePipe } from '@flusys/ng-shared';
|
|
8
|
-
import { A as ActionApiService, d as buildActionParentTree, a as ActionType, L as LogicBuilderComponent } from './flusys-ng-iam-flusys-ng-iam-
|
|
8
|
+
import { A as ActionApiService, d as buildActionParentTree, a as ActionType, L as LogicBuilderComponent } from './flusys-ng-iam-flusys-ng-iam-yNMJXm89.mjs';
|
|
9
9
|
|
|
10
10
|
class ActionFormPageComponent {
|
|
11
11
|
route = inject(ActivatedRoute);
|
|
@@ -506,4 +506,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImpor
|
|
|
506
506
|
}], ctorParameters: () => [] });
|
|
507
507
|
|
|
508
508
|
export { ActionFormPageComponent };
|
|
509
|
-
//# sourceMappingURL=flusys-ng-iam-action-form-page.component-
|
|
509
|
+
//# sourceMappingURL=flusys-ng-iam-action-form-page.component-WXFLmq16.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-iam-action-form-page.component-DunIW6W4.mjs","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"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"flusys-ng-iam-action-form-page.component-WXFLmq16.mjs","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"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ import { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';
|
|
|
8
8
|
import { ACTION_PERMISSIONS, USER_ACTION_PERMISSIONS, TranslateService, HasPermissionDirective, TranslatePipe } from '@flusys/ng-shared';
|
|
9
9
|
import { MessageService, ConfirmationService, FButtonDirective, IconFieldComponent, InputIconComponent, InputTextDirective, TagComponent, TooltipDirective, TreeTableComponent, TreeTableTogglerComponent, UiIconComponent } from '@flusys/ng-ui';
|
|
10
10
|
import { firstValueFrom } from 'rxjs';
|
|
11
|
-
import { A as ActionApiService, c as convertActionToTreeNode, a as ActionType, b as ActionPermittedUsersDialogComponent } from './flusys-ng-iam-flusys-ng-iam-
|
|
11
|
+
import { A as ActionApiService, c as convertActionToTreeNode, a as ActionType, b as ActionPermittedUsersDialogComponent } from './flusys-ng-iam-flusys-ng-iam-yNMJXm89.mjs';
|
|
12
12
|
|
|
13
13
|
function filterActionTree(nodes, search) {
|
|
14
14
|
const term = search.trim().toLowerCase();
|
|
@@ -462,4 +462,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImpor
|
|
|
462
462
|
}], ctorParameters: () => [] });
|
|
463
463
|
|
|
464
464
|
export { ActionListPageComponent };
|
|
465
|
-
//# sourceMappingURL=flusys-ng-iam-action-list-page.component-
|
|
465
|
+
//# sourceMappingURL=flusys-ng-iam-action-list-page.component-CFZ5F_vQ.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-iam-action-list-page.component-CgoLgAqd.mjs","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\n ><ui-icon name=\"search\" class=\"text-sm\"></ui-icon\n ></f-inputicon>\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 async loadActions(): Promise<void> {\n this.isLoading.set(true);\n try {\n const response = await firstValueFrom(this.actionApi.getTree());\n this.rawActions.set(response?.success ? (response.data ?? []) : []);\n } catch {\n // Handled by global interceptor\n } finally {\n 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"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"flusys-ng-iam-action-list-page.component-CFZ5F_vQ.mjs","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\n ><ui-icon name=\"search\" class=\"text-sm\"></ui-icon\n ></f-inputicon>\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 async loadActions(): Promise<void> {\n this.isLoading.set(true);\n try {\n const response = await firstValueFrom(this.actionApi.getTree());\n this.rawActions.set(response?.success ? (response.data ?? []) : []);\n } catch {\n // Handled by global interceptor\n } finally {\n 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"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { Service, inject, signal, input, output, effect, Component, computed, DestroyRef, viewChild } from '@angular/core';
|
|
3
|
-
import { ApiResourceService, TranslateService, PermissionValidatorService, TranslatePipe, ROLE_ACTION_PERMISSIONS, HasPermissionDirective, COMPANY_ACTION_PERMISSIONS,
|
|
3
|
+
import { ApiResourceService, TranslateService, PermissionValidatorService, COMPANY_API_PROVIDER, TranslatePipe, ROLE_ACTION_PERMISSIONS, HasPermissionDirective, COMPANY_ACTION_PERMISSIONS, USER_ROLE_PERMISSIONS, USER_PERMISSION_PROVIDER, UserSelectComponent, USER_ACTION_PERMISSIONS, USER_PROVIDER, PROFILE_PERMISSION_PROVIDER, ACTION_PERMISSIONS, ROLE_PERMISSIONS, permissionGuard, anyPermissionGuard, resolveTranslationModule, SHARED_MESSAGES } from '@flusys/ng-shared';
|
|
4
4
|
import { APP_CONFIG, getServiceUrl, BaseApiService, isCompanyFeatureEnabled, getPermissionMode } from '@flusys/ng-core';
|
|
5
5
|
import { ConfirmationService, MessageService, FButtonDirective, SelectComponent, TooltipDirective, UiIconComponent, CheckboxComponent, TagComponent, TreeTableComponent, TreeTableTogglerComponent, TableComponent, DialogComponent, ProgressSpinnerComponent } from '@flusys/ng-ui';
|
|
6
6
|
import { HttpClient } from '@angular/common/http';
|
|
@@ -89,6 +89,9 @@ const IAM_MESSAGES = {
|
|
|
89
89
|
'iam.permission.remove': 'Remove Access',
|
|
90
90
|
'iam.permission.remove.confirm': 'Remove access for {{name}}?',
|
|
91
91
|
'iam.action.delete.title': 'Delete Action',
|
|
92
|
+
'iam.company.name': 'Company',
|
|
93
|
+
'iam.branch.name': 'Branch',
|
|
94
|
+
'iam.branch.all': 'All branches',
|
|
92
95
|
// pages/action/action-form-page.component.ts
|
|
93
96
|
'iam.action.edit': 'Edit Action',
|
|
94
97
|
'iam.action.name.placeholder': 'Enter action name',
|
|
@@ -924,6 +927,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImpor
|
|
|
924
927
|
type: Service
|
|
925
928
|
}] });
|
|
926
929
|
|
|
930
|
+
/**
|
|
931
|
+
* Shared resolver for the company/branch display info behind an IAM permission
|
|
932
|
+
* grant's scope (`companyId`/`branchId`). Used by the read-only permitted-users
|
|
933
|
+
* dialogs (action and role) to turn scope IDs into display names.
|
|
934
|
+
*
|
|
935
|
+
* Since IAM stays independent of the auth package, company/branch info is
|
|
936
|
+
* resolved via the `COMPANY_API_PROVIDER` injection token rather than a direct
|
|
937
|
+
* join. Both `getCompaniesByIds`/`getBranchesByIds` are optional on
|
|
938
|
+
* `ICompanyApiProvider`, and provider errors are swallowed — callers always get
|
|
939
|
+
* a `Map` (empty when ids are empty, the provider doesn't implement the
|
|
940
|
+
* method, or the request fails) and fall back to displaying the raw ID.
|
|
941
|
+
*/
|
|
942
|
+
class PermissionScopeResolverService {
|
|
943
|
+
companyProvider = inject(COMPANY_API_PROVIDER);
|
|
944
|
+
async resolveCompanyInfo(companyIds) {
|
|
945
|
+
if (companyIds.length === 0 || !this.companyProvider.getCompaniesByIds) {
|
|
946
|
+
return new Map();
|
|
947
|
+
}
|
|
948
|
+
try {
|
|
949
|
+
const response = await firstValueFrom(this.companyProvider.getCompaniesByIds(companyIds));
|
|
950
|
+
return new Map((response.data ?? []).map((c) => [c.id, c]));
|
|
951
|
+
}
|
|
952
|
+
catch {
|
|
953
|
+
return new Map();
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
async resolveBranchInfo(branchIds) {
|
|
957
|
+
if (branchIds.length === 0 || !this.companyProvider.getBranchesByIds) {
|
|
958
|
+
return new Map();
|
|
959
|
+
}
|
|
960
|
+
try {
|
|
961
|
+
const response = await firstValueFrom(this.companyProvider.getBranchesByIds(branchIds));
|
|
962
|
+
return new Map((response.data ?? []).map((b) => [b.id, b]));
|
|
963
|
+
}
|
|
964
|
+
catch {
|
|
965
|
+
return new Map();
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: PermissionScopeResolverService, deps: [], target: i0.ɵɵFactoryTarget.Service });
|
|
969
|
+
static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.5", ngImport: i0, type: PermissionScopeResolverService });
|
|
970
|
+
}
|
|
971
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: PermissionScopeResolverService, decorators: [{
|
|
972
|
+
type: Service
|
|
973
|
+
}] });
|
|
974
|
+
|
|
927
975
|
// Role services
|
|
928
976
|
|
|
929
977
|
function toLogicNode(node) {
|
|
@@ -4714,13 +4762,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImpor
|
|
|
4714
4762
|
* per user. Assigning new users stays on the user-centric
|
|
4715
4763
|
* `UserRoleSelectorComponent` flow — this dialog intentionally has no "add"
|
|
4716
4764
|
* affordance. Since IAM stays independent of the auth package, user display
|
|
4717
|
-
* info is resolved via the `USER_PROVIDER` injection token
|
|
4718
|
-
*
|
|
4765
|
+
* info is resolved via the `USER_PROVIDER` injection token, and
|
|
4766
|
+
* company/branch display info via the shared `PermissionScopeResolverService`
|
|
4767
|
+
* (itself backed by `COMPANY_API_PROVIDER`) rather than a direct join.
|
|
4768
|
+
*
|
|
4769
|
+
* `Role` assignments are global (never scoped to a single company), so the
|
|
4770
|
+
* same user can hold several grants for the same role — one per
|
|
4771
|
+
* company/branch scope (company+branch null = global, branch null = whole
|
|
4772
|
+
* company, both set = a single branch). The company/branch lines are shown
|
|
4773
|
+
* only when at least one returned grant carries a `companyId` (i.e. the
|
|
4774
|
+
* multi-company feature is enabled) — otherwise they're omitted to avoid a
|
|
4775
|
+
* redundant "-" column. Removal is scoped to the exact row's
|
|
4776
|
+
* `companyId`/`branchId`, not just the user+role pair, since a user can
|
|
4777
|
+
* have multiple grants for the same role at different scopes.
|
|
4719
4778
|
*/
|
|
4720
4779
|
class RolePermittedUsersDialogComponent {
|
|
4721
4780
|
USER_ROLE_PERMISSIONS = USER_ROLE_PERMISSIONS;
|
|
4722
4781
|
permissionApi = inject(PermissionApiService);
|
|
4723
4782
|
userProvider = inject(USER_PROVIDER);
|
|
4783
|
+
scopeResolver = inject(PermissionScopeResolverService);
|
|
4724
4784
|
confirmationService = inject(ConfirmationService);
|
|
4725
4785
|
messageService = inject(MessageService);
|
|
4726
4786
|
translateAdapter = inject(TranslateService, {
|
|
@@ -4740,6 +4800,8 @@ class RolePermittedUsersDialogComponent {
|
|
|
4740
4800
|
...(ngDevMode ? [{ debugName: "isRemoving" }] : /* istanbul ignore next */ []));
|
|
4741
4801
|
users = signal([], /* @ts-ignore */
|
|
4742
4802
|
...(ngDevMode ? [{ debugName: "users" }] : /* istanbul ignore next */ []));
|
|
4803
|
+
showCompanyColumn = signal(false, /* @ts-ignore */
|
|
4804
|
+
...(ngDevMode ? [{ debugName: "showCompanyColumn" }] : /* istanbul ignore next */ []));
|
|
4743
4805
|
constructor() {
|
|
4744
4806
|
effect(() => {
|
|
4745
4807
|
if (this.visible() && this.role()) {
|
|
@@ -4755,8 +4817,15 @@ class RolePermittedUsersDialogComponent {
|
|
|
4755
4817
|
try {
|
|
4756
4818
|
const response = await firstValueFrom(this.permissionApi.getRoleUsers(role.id));
|
|
4757
4819
|
const rows = response.data ?? [];
|
|
4758
|
-
const userIds = rows.map((r) => r.userId);
|
|
4759
|
-
const
|
|
4820
|
+
const userIds = [...new Set(rows.map((r) => r.userId))];
|
|
4821
|
+
const companyIds = [...new Set(rows.map((r) => r.companyId).filter((id) => !!id))];
|
|
4822
|
+
const branchIds = [...new Set(rows.map((r) => r.branchId).filter((id) => !!id))];
|
|
4823
|
+
const [userInfoMap, companyInfoMap, branchInfoMap] = await Promise.all([
|
|
4824
|
+
this.resolveUserInfo(userIds),
|
|
4825
|
+
this.scopeResolver.resolveCompanyInfo(companyIds),
|
|
4826
|
+
this.scopeResolver.resolveBranchInfo(branchIds),
|
|
4827
|
+
]);
|
|
4828
|
+
this.showCompanyColumn.set(companyIds.length > 0);
|
|
4760
4829
|
this.users.set(rows.map((r) => {
|
|
4761
4830
|
const info = userInfoMap.get(r.userId);
|
|
4762
4831
|
return {
|
|
@@ -4764,6 +4833,10 @@ class RolePermittedUsersDialogComponent {
|
|
|
4764
4833
|
userId: r.userId,
|
|
4765
4834
|
userName: info?.name ?? r.userId,
|
|
4766
4835
|
userEmail: info?.email ?? '',
|
|
4836
|
+
companyId: r.companyId,
|
|
4837
|
+
companyName: r.companyId ? (companyInfoMap.get(r.companyId)?.name ?? r.companyId) : null,
|
|
4838
|
+
branchId: r.branchId,
|
|
4839
|
+
branchName: r.branchId ? (branchInfoMap.get(r.branchId)?.name ?? r.branchId) : null,
|
|
4767
4840
|
};
|
|
4768
4841
|
}));
|
|
4769
4842
|
}
|
|
@@ -4800,6 +4873,8 @@ class RolePermittedUsersDialogComponent {
|
|
|
4800
4873
|
try {
|
|
4801
4874
|
const response = await firstValueFrom(this.permissionApi.assignUserRoles({
|
|
4802
4875
|
userId: user.userId,
|
|
4876
|
+
companyId: user.companyId ?? undefined,
|
|
4877
|
+
branchId: user.branchId ?? undefined,
|
|
4803
4878
|
items: [{ id: role.id, action: 'remove' }],
|
|
4804
4879
|
}));
|
|
4805
4880
|
if (response.success) {
|
|
@@ -4856,6 +4931,16 @@ class RolePermittedUsersDialogComponent {
|
|
|
4856
4931
|
<div>
|
|
4857
4932
|
<div class="font-semibold">{{ user.userName }}</div>
|
|
4858
4933
|
<div class="text-sm text-muted-color">{{ user.userEmail }}</div>
|
|
4934
|
+
@if (showCompanyColumn() && user.companyName) {
|
|
4935
|
+
<div class="text-xs text-muted-color mt-1">
|
|
4936
|
+
{{ 'iam.company.name' | translate }}: {{ user.companyName }}
|
|
4937
|
+
@if (user.branchName) {
|
|
4938
|
+
· {{ 'iam.branch.name' | translate }}: {{ user.branchName }}
|
|
4939
|
+
} @else {
|
|
4940
|
+
· {{ 'iam.branch.all' | translate }}
|
|
4941
|
+
}
|
|
4942
|
+
</div>
|
|
4943
|
+
}
|
|
4859
4944
|
</div>
|
|
4860
4945
|
<button
|
|
4861
4946
|
fButton
|
|
@@ -4934,6 +5019,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImpor
|
|
|
4934
5019
|
<div>
|
|
4935
5020
|
<div class="font-semibold">{{ user.userName }}</div>
|
|
4936
5021
|
<div class="text-sm text-muted-color">{{ user.userEmail }}</div>
|
|
5022
|
+
@if (showCompanyColumn() && user.companyName) {
|
|
5023
|
+
<div class="text-xs text-muted-color mt-1">
|
|
5024
|
+
{{ 'iam.company.name' | translate }}: {{ user.companyName }}
|
|
5025
|
+
@if (user.branchName) {
|
|
5026
|
+
· {{ 'iam.branch.name' | translate }}: {{ user.branchName }}
|
|
5027
|
+
} @else {
|
|
5028
|
+
· {{ 'iam.branch.all' | translate }}
|
|
5029
|
+
}
|
|
5030
|
+
</div>
|
|
5031
|
+
}
|
|
4937
5032
|
</div>
|
|
4938
5033
|
<button
|
|
4939
5034
|
fButton
|
|
@@ -4976,13 +5071,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImpor
|
|
|
4976
5071
|
* action per user. Assigning new users stays on the user-centric
|
|
4977
5072
|
* `UserActionSelectorComponent` flow — this dialog intentionally has no
|
|
4978
5073
|
* "add" affordance. Since IAM stays independent of the auth package, user
|
|
4979
|
-
* display info is resolved via the `USER_PROVIDER` injection token
|
|
4980
|
-
*
|
|
5074
|
+
* display info is resolved via the `USER_PROVIDER` injection token, and
|
|
5075
|
+
* company/branch display info via the shared `PermissionScopeResolverService`
|
|
5076
|
+
* (itself backed by `COMPANY_API_PROVIDER`) rather than a direct join.
|
|
5077
|
+
*
|
|
5078
|
+
* `Action` rows are global (never scoped to a single company), so the same
|
|
5079
|
+
* user can hold several grants for the same action — one per
|
|
5080
|
+
* company/branch scope (company+branch null = global, branch null = whole
|
|
5081
|
+
* company, both set = a single branch). The company/branch lines are shown
|
|
5082
|
+
* only when at least one returned grant carries a `companyId` (i.e. the
|
|
5083
|
+
* multi-company feature is enabled) — otherwise they're omitted to avoid a
|
|
5084
|
+
* redundant "-" column. Removal is scoped to the exact row's
|
|
5085
|
+
* `companyId`/`branchId`, not just the user+action pair, since a user can
|
|
5086
|
+
* have multiple grants for the same action at different scopes.
|
|
4981
5087
|
*/
|
|
4982
5088
|
class ActionPermittedUsersDialogComponent {
|
|
4983
5089
|
USER_ACTION_PERMISSIONS = USER_ACTION_PERMISSIONS;
|
|
4984
5090
|
permissionApi = inject(PermissionApiService);
|
|
4985
5091
|
userProvider = inject(USER_PROVIDER);
|
|
5092
|
+
scopeResolver = inject(PermissionScopeResolverService);
|
|
4986
5093
|
confirmationService = inject(ConfirmationService);
|
|
4987
5094
|
messageService = inject(MessageService);
|
|
4988
5095
|
translateAdapter = inject(TranslateService, {
|
|
@@ -5002,6 +5109,8 @@ class ActionPermittedUsersDialogComponent {
|
|
|
5002
5109
|
...(ngDevMode ? [{ debugName: "isRemoving" }] : /* istanbul ignore next */ []));
|
|
5003
5110
|
users = signal([], /* @ts-ignore */
|
|
5004
5111
|
...(ngDevMode ? [{ debugName: "users" }] : /* istanbul ignore next */ []));
|
|
5112
|
+
showCompanyColumn = signal(false, /* @ts-ignore */
|
|
5113
|
+
...(ngDevMode ? [{ debugName: "showCompanyColumn" }] : /* istanbul ignore next */ []));
|
|
5005
5114
|
constructor() {
|
|
5006
5115
|
effect(() => {
|
|
5007
5116
|
if (this.visible() && this.action()) {
|
|
@@ -5017,8 +5126,15 @@ class ActionPermittedUsersDialogComponent {
|
|
|
5017
5126
|
try {
|
|
5018
5127
|
const response = await firstValueFrom(this.permissionApi.getActionUsers(action.id));
|
|
5019
5128
|
const rows = response.data ?? [];
|
|
5020
|
-
const userIds = rows.map((r) => r.userId);
|
|
5021
|
-
const
|
|
5129
|
+
const userIds = [...new Set(rows.map((r) => r.userId))];
|
|
5130
|
+
const companyIds = [...new Set(rows.map((r) => r.companyId).filter((id) => !!id))];
|
|
5131
|
+
const branchIds = [...new Set(rows.map((r) => r.branchId).filter((id) => !!id))];
|
|
5132
|
+
const [userInfoMap, companyInfoMap, branchInfoMap] = await Promise.all([
|
|
5133
|
+
this.resolveUserInfo(userIds),
|
|
5134
|
+
this.scopeResolver.resolveCompanyInfo(companyIds),
|
|
5135
|
+
this.scopeResolver.resolveBranchInfo(branchIds),
|
|
5136
|
+
]);
|
|
5137
|
+
this.showCompanyColumn.set(companyIds.length > 0);
|
|
5022
5138
|
this.users.set(rows.map((r) => {
|
|
5023
5139
|
const info = userInfoMap.get(r.userId);
|
|
5024
5140
|
return {
|
|
@@ -5026,6 +5142,10 @@ class ActionPermittedUsersDialogComponent {
|
|
|
5026
5142
|
userId: r.userId,
|
|
5027
5143
|
userName: info?.name ?? r.userId,
|
|
5028
5144
|
userEmail: info?.email ?? '',
|
|
5145
|
+
companyId: r.companyId,
|
|
5146
|
+
companyName: r.companyId ? (companyInfoMap.get(r.companyId)?.name ?? r.companyId) : null,
|
|
5147
|
+
branchId: r.branchId,
|
|
5148
|
+
branchName: r.branchId ? (branchInfoMap.get(r.branchId)?.name ?? r.branchId) : null,
|
|
5029
5149
|
};
|
|
5030
5150
|
}));
|
|
5031
5151
|
}
|
|
@@ -5062,6 +5182,8 @@ class ActionPermittedUsersDialogComponent {
|
|
|
5062
5182
|
try {
|
|
5063
5183
|
const response = await firstValueFrom(this.permissionApi.assignUserActions({
|
|
5064
5184
|
userId: user.userId,
|
|
5185
|
+
companyId: user.companyId ?? undefined,
|
|
5186
|
+
branchId: user.branchId ?? undefined,
|
|
5065
5187
|
items: [{ id: action.id, action: 'remove' }],
|
|
5066
5188
|
}));
|
|
5067
5189
|
if (response.success) {
|
|
@@ -5118,6 +5240,16 @@ class ActionPermittedUsersDialogComponent {
|
|
|
5118
5240
|
<div>
|
|
5119
5241
|
<div class="font-semibold">{{ user.userName }}</div>
|
|
5120
5242
|
<div class="text-sm text-muted-color">{{ user.userEmail }}</div>
|
|
5243
|
+
@if (showCompanyColumn() && user.companyName) {
|
|
5244
|
+
<div class="text-xs text-muted-color mt-1">
|
|
5245
|
+
{{ 'iam.company.name' | translate }}: {{ user.companyName }}
|
|
5246
|
+
@if (user.branchName) {
|
|
5247
|
+
· {{ 'iam.branch.name' | translate }}: {{ user.branchName }}
|
|
5248
|
+
} @else {
|
|
5249
|
+
· {{ 'iam.branch.all' | translate }}
|
|
5250
|
+
}
|
|
5251
|
+
</div>
|
|
5252
|
+
}
|
|
5121
5253
|
</div>
|
|
5122
5254
|
<button
|
|
5123
5255
|
fButton
|
|
@@ -5196,6 +5328,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImpor
|
|
|
5196
5328
|
<div>
|
|
5197
5329
|
<div class="font-semibold">{{ user.userName }}</div>
|
|
5198
5330
|
<div class="text-sm text-muted-color">{{ user.userEmail }}</div>
|
|
5331
|
+
@if (showCompanyColumn() && user.companyName) {
|
|
5332
|
+
<div class="text-xs text-muted-color mt-1">
|
|
5333
|
+
{{ 'iam.company.name' | translate }}: {{ user.companyName }}
|
|
5334
|
+
@if (user.branchName) {
|
|
5335
|
+
· {{ 'iam.branch.name' | translate }}: {{ user.branchName }}
|
|
5336
|
+
} @else {
|
|
5337
|
+
· {{ 'iam.branch.all' | translate }}
|
|
5338
|
+
}
|
|
5339
|
+
</div>
|
|
5340
|
+
}
|
|
5199
5341
|
</div>
|
|
5200
5342
|
<button
|
|
5201
5343
|
fButton
|
|
@@ -5346,15 +5488,15 @@ const IAM_ROUTES = [
|
|
|
5346
5488
|
children: [
|
|
5347
5489
|
{
|
|
5348
5490
|
path: '',
|
|
5349
|
-
loadComponent: () => import('./flusys-ng-iam-action-list-page.component-
|
|
5491
|
+
loadComponent: () => import('./flusys-ng-iam-action-list-page.component-CFZ5F_vQ.mjs').then((m) => m.ActionListPageComponent),
|
|
5350
5492
|
},
|
|
5351
5493
|
{
|
|
5352
5494
|
path: 'new',
|
|
5353
|
-
loadComponent: () => import('./flusys-ng-iam-action-form-page.component-
|
|
5495
|
+
loadComponent: () => import('./flusys-ng-iam-action-form-page.component-WXFLmq16.mjs').then((m) => m.ActionFormPageComponent),
|
|
5354
5496
|
},
|
|
5355
5497
|
{
|
|
5356
5498
|
path: ':id',
|
|
5357
|
-
loadComponent: () => import('./flusys-ng-iam-action-form-page.component-
|
|
5499
|
+
loadComponent: () => import('./flusys-ng-iam-action-form-page.component-WXFLmq16.mjs').then((m) => m.ActionFormPageComponent),
|
|
5358
5500
|
},
|
|
5359
5501
|
],
|
|
5360
5502
|
},
|
|
@@ -5365,15 +5507,15 @@ const IAM_ROUTES = [
|
|
|
5365
5507
|
children: [
|
|
5366
5508
|
{
|
|
5367
5509
|
path: '',
|
|
5368
|
-
loadComponent: () => import('./flusys-ng-iam-role-list-page.component-
|
|
5510
|
+
loadComponent: () => import('./flusys-ng-iam-role-list-page.component-DmIkc8YG.mjs').then((m) => m.RoleListPageComponent),
|
|
5369
5511
|
},
|
|
5370
5512
|
{
|
|
5371
5513
|
path: 'new',
|
|
5372
|
-
loadComponent: () => import('./flusys-ng-iam-role-form-page.component-
|
|
5514
|
+
loadComponent: () => import('./flusys-ng-iam-role-form-page.component-Dvn3yFxQ.mjs').then((m) => m.RoleFormPageComponent),
|
|
5373
5515
|
},
|
|
5374
5516
|
{
|
|
5375
5517
|
path: ':id',
|
|
5376
|
-
loadComponent: () => import('./flusys-ng-iam-role-form-page.component-
|
|
5518
|
+
loadComponent: () => import('./flusys-ng-iam-role-form-page.component-Dvn3yFxQ.mjs').then((m) => m.RoleFormPageComponent),
|
|
5377
5519
|
},
|
|
5378
5520
|
],
|
|
5379
5521
|
},
|
|
@@ -5388,7 +5530,7 @@ const IAM_ROUTES = [
|
|
|
5388
5530
|
COMPANY_ACTION_PERMISSIONS.READ,
|
|
5389
5531
|
]),
|
|
5390
5532
|
],
|
|
5391
|
-
loadComponent: () => import('./flusys-ng-iam-permission-page.component-
|
|
5533
|
+
loadComponent: () => import('./flusys-ng-iam-permission-page.component-C_eWwf0e.mjs').then((m) => m.PermissionPageComponent),
|
|
5392
5534
|
},
|
|
5393
5535
|
// Default redirect to the first tab the user has permission to see
|
|
5394
5536
|
{
|
|
@@ -5406,5 +5548,5 @@ const IAM_ROUTES = [
|
|
|
5406
5548
|
* Generated bundle index. Do not edit.
|
|
5407
5549
|
*/
|
|
5408
5550
|
|
|
5409
|
-
export { ActionApiService as A, CompanyActionSelectorComponent as C, IAM_MESSAGES as I, LogicBuilderComponent as L, MAX_DROPDOWN_ITEMS as M, PermissionApiService as P, RoleApiService as R, UserRoleSelectorComponent as U, ActionType as a, ActionPermittedUsersDialogComponent as b, convertActionToTreeNode as c, buildActionParentTree as d, RolePermittedUsersDialogComponent as e, RoleActionSelectorComponent as f, UserActionSelectorComponent as g, ActionPermissionLogicService as h, IAM_ROUTES as i, MyPermissionsApiService as j,
|
|
5410
|
-
//# sourceMappingURL=flusys-ng-iam-flusys-ng-iam-
|
|
5551
|
+
export { ActionApiService as A, CompanyActionSelectorComponent as C, IAM_MESSAGES as I, LogicBuilderComponent as L, MAX_DROPDOWN_ITEMS as M, PermissionApiService as P, RoleApiService as R, UserRoleSelectorComponent as U, ActionType as a, ActionPermittedUsersDialogComponent as b, convertActionToTreeNode as c, buildActionParentTree as d, RolePermittedUsersDialogComponent as e, RoleActionSelectorComponent as f, UserActionSelectorComponent as g, ActionPermissionLogicService as h, IAM_ROUTES as i, MyPermissionsApiService as j, PermissionScopeResolverService as k, PermissionStateService as l, ProfilePermissionProviderAdapter as m, provideIamProviders as p };
|
|
5552
|
+
//# sourceMappingURL=flusys-ng-iam-flusys-ng-iam-yNMJXm89.mjs.map
|