@flusys/ng-iam 3.0.0 → 4.0.0-lts
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/README.md +2 -2
- package/fesm2022/{flusys-ng-iam-action-form-page.component-eXpZNJ_H.mjs → flusys-ng-iam-action-form-page.component-BQx9yset.mjs} +62 -50
- package/fesm2022/flusys-ng-iam-action-form-page.component-BQx9yset.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-action-list-page.component-BtJlGcTj.mjs → flusys-ng-iam-action-list-page.component-BrpZujxk.mjs} +51 -42
- package/fesm2022/flusys-ng-iam-action-list-page.component-BrpZujxk.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-flusys-ng-iam-CJAQT60K.mjs → flusys-ng-iam-flusys-ng-iam-Co4ot9My.mjs} +641 -341
- package/fesm2022/flusys-ng-iam-flusys-ng-iam-Co4ot9My.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-iam-container.component-UYJjqYV9.mjs → flusys-ng-iam-iam-container.component-CQA2B6cU.mjs} +14 -13
- package/fesm2022/flusys-ng-iam-iam-container.component-CQA2B6cU.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-permission-page.component-DcgT7L3_.mjs → flusys-ng-iam-permission-page.component-Dpk90y72.mjs} +14 -13
- package/fesm2022/flusys-ng-iam-permission-page.component-Dpk90y72.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-role-form-page.component-D_AAEay2.mjs → flusys-ng-iam-role-form-page.component-CVfRQpoa.mjs} +38 -35
- package/fesm2022/flusys-ng-iam-role-form-page.component-CVfRQpoa.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-role-list-page.component-D4J1by6Q.mjs → flusys-ng-iam-role-list-page.component-BHB8X5r7.mjs} +41 -38
- package/fesm2022/flusys-ng-iam-role-list-page.component-BHB8X5r7.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam.mjs +1 -1
- package/package.json +7 -5
- package/types/flusys-ng-iam.d.ts +13 -5
- package/fesm2022/flusys-ng-iam-action-form-page.component-eXpZNJ_H.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-action-list-page.component-BtJlGcTj.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-flusys-ng-iam-CJAQT60K.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-iam-container.component-UYJjqYV9.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-permission-page.component-DcgT7L3_.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-role-form-page.component-D_AAEay2.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-role-list-page.component-D4J1by6Q.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
| Item | Value |
|
|
10
10
|
|------|-------|
|
|
11
11
|
| Package | `@flusys/ng-iam` |
|
|
12
|
-
| Version |
|
|
12
|
+
| Version | 4.0.0-rc |
|
|
13
13
|
| Dependencies | ng-core, ng-shared, ng-layout (IMenuItem only) |
|
|
14
14
|
| CSS Framework | Tailwind CSS (not PrimeFlex) |
|
|
15
15
|
| Build | `npm run build:ng-iam` |
|
|
@@ -604,5 +604,5 @@ Registers `PROFILE_PERMISSION_PROVIDER` with `ProfilePermissionProviderAdapter`.
|
|
|
604
604
|
---
|
|
605
605
|
|
|
606
606
|
**Last Updated:** 2026-02-25
|
|
607
|
-
**Version:** 3.0.
|
|
607
|
+
**Version:** 3.0.1
|
|
608
608
|
**Angular Version:** 21
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, signal, computed, effect,
|
|
2
|
+
import { inject, signal, computed, effect, Component } from '@angular/core';
|
|
3
3
|
import { toSignal } from '@angular/core/rxjs-interop';
|
|
4
4
|
import { form, required, FormField } from '@angular/forms/signals';
|
|
5
5
|
import { ActivatedRoute, Router } from '@angular/router';
|
|
6
|
-
import {
|
|
6
|
+
import { TRANSLATE_ADAPTER } from '@flusys/ng-core';
|
|
7
|
+
import { AngularModule, PrimeModule, TranslatePipe } from '@flusys/ng-shared';
|
|
7
8
|
import { MessageService } from 'primeng/api';
|
|
8
9
|
import { firstValueFrom } from 'rxjs';
|
|
9
|
-
import { A as ActionApiService, a as ActionType, L as LogicBuilderComponent } from './flusys-ng-iam-flusys-ng-iam-
|
|
10
|
+
import { A as ActionApiService, a as ActionType, L as LogicBuilderComponent } from './flusys-ng-iam-flusys-ng-iam-Co4ot9My.mjs';
|
|
10
11
|
import * as i1 from '@angular/forms';
|
|
11
12
|
import * as i2 from 'primeng/button';
|
|
12
13
|
import * as i3 from 'primeng/checkbox';
|
|
@@ -17,8 +18,12 @@ class ActionFormPageComponent {
|
|
|
17
18
|
router = inject(Router);
|
|
18
19
|
actionApi = inject(ActionApiService);
|
|
19
20
|
messageService = inject(MessageService);
|
|
21
|
+
translateAdapter = inject(TRANSLATE_ADAPTER, { optional: true });
|
|
20
22
|
routeParams = toSignal(this.route.paramMap);
|
|
21
23
|
initialized = false;
|
|
24
|
+
translate(key, vars) {
|
|
25
|
+
return this.translateAdapter?.translate(key, vars) ?? key;
|
|
26
|
+
}
|
|
22
27
|
isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
23
28
|
existingAction = signal(null, ...(ngDevMode ? [{ debugName: "existingAction" }] : []));
|
|
24
29
|
isEditMode = computed(() => !!this.existingAction(), ...(ngDevMode ? [{ debugName: "isEditMode" }] : []));
|
|
@@ -41,13 +46,13 @@ class ActionFormPageComponent {
|
|
|
41
46
|
isActive: true,
|
|
42
47
|
metadata: null,
|
|
43
48
|
}, ...(ngDevMode ? [{ debugName: "formModel" }] : []));
|
|
44
|
-
actionTypes = [
|
|
45
|
-
{ label: '
|
|
46
|
-
{ label: '
|
|
47
|
-
{ label: '
|
|
48
|
-
];
|
|
49
|
+
actionTypes = computed(() => [
|
|
50
|
+
{ label: this.translate('iam.action.type.backend.label'), value: ActionType.BACKEND },
|
|
51
|
+
{ label: this.translate('iam.action.type.frontend.label'), value: ActionType.FRONTEND },
|
|
52
|
+
{ label: this.translate('iam.action.type.both.label'), value: ActionType.BOTH },
|
|
53
|
+
], ...(ngDevMode ? [{ debugName: "actionTypes" }] : []));
|
|
49
54
|
actionForm = form(this.formModel, (f) => {
|
|
50
|
-
required(f.name, { message: '
|
|
55
|
+
required(f.name, { message: this.translate('shared.validation.required', { field: this.translate('iam.action.name') }) });
|
|
51
56
|
});
|
|
52
57
|
isFormValid = computed(() => {
|
|
53
58
|
const model = this.formModel();
|
|
@@ -69,7 +74,7 @@ class ActionFormPageComponent {
|
|
|
69
74
|
select: ['id', 'name', 'code', 'actionType', 'permissionLogic'],
|
|
70
75
|
}));
|
|
71
76
|
if (response?.success && response.data) {
|
|
72
|
-
this.allActionsForLogic.set(response.data.map((a) => ({ id: a.id, name: a.name ?? '
|
|
77
|
+
this.allActionsForLogic.set(response.data.map((a) => ({ id: a.id, name: a.name ?? this.translate('shared.unnamed') })));
|
|
73
78
|
this.allActions.set(response.data);
|
|
74
79
|
}
|
|
75
80
|
}
|
|
@@ -118,8 +123,8 @@ class ActionFormPageComponent {
|
|
|
118
123
|
if (!this.isFormValid()) {
|
|
119
124
|
this.messageService.add({
|
|
120
125
|
severity: 'error',
|
|
121
|
-
summary: '
|
|
122
|
-
detail: '
|
|
126
|
+
summary: this.translate('shared.validation.error'),
|
|
127
|
+
detail: this.translate('shared.fill.required.fields'),
|
|
123
128
|
});
|
|
124
129
|
return;
|
|
125
130
|
}
|
|
@@ -137,11 +142,19 @@ class ActionFormPageComponent {
|
|
|
137
142
|
};
|
|
138
143
|
if (this.isEditMode()) {
|
|
139
144
|
await this.actionApi.updateAsync(dto);
|
|
140
|
-
this.messageService.add({
|
|
145
|
+
this.messageService.add({
|
|
146
|
+
severity: 'success',
|
|
147
|
+
summary: this.translate('shared.success'),
|
|
148
|
+
detail: this.translate('iam.action.update.success'),
|
|
149
|
+
});
|
|
141
150
|
}
|
|
142
151
|
else {
|
|
143
152
|
await this.actionApi.insertAsync(dto);
|
|
144
|
-
this.messageService.add({
|
|
153
|
+
this.messageService.add({
|
|
154
|
+
severity: 'success',
|
|
155
|
+
summary: this.translate('shared.success'),
|
|
156
|
+
detail: this.translate('iam.action.create.success'),
|
|
157
|
+
});
|
|
145
158
|
}
|
|
146
159
|
this.router.navigate(['/iam/actions']);
|
|
147
160
|
}
|
|
@@ -162,48 +175,48 @@ class ActionFormPageComponent {
|
|
|
162
175
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: ActionFormPageComponent, isStandalone: true, selector: "lib-action-form-page", ngImport: i0, template: `
|
|
163
176
|
<div class="card">
|
|
164
177
|
<h3 class="text-lg sm:text-xl font-semibold mb-4">
|
|
165
|
-
{{ isEditMode() ? '
|
|
178
|
+
{{ isEditMode() ? ('iam.action.edit' | translate) : ('iam.action.new' | translate) }}
|
|
166
179
|
</h3>
|
|
167
180
|
|
|
168
181
|
<form (ngSubmit)="onSubmit()" class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
169
182
|
<!-- Name -->
|
|
170
183
|
<div class="flex flex-col gap-2">
|
|
171
|
-
<label for="name" class="font-medium">
|
|
184
|
+
<label for="name" class="font-medium">{{ 'iam.action.name' | translate }} *</label>
|
|
172
185
|
<input
|
|
173
186
|
pInputText
|
|
174
187
|
id="name"
|
|
175
188
|
[formField]="actionForm.name"
|
|
176
|
-
placeholder="
|
|
189
|
+
[placeholder]="'iam.action.name.placeholder' | translate" />
|
|
177
190
|
</div>
|
|
178
191
|
|
|
179
192
|
<!-- Code -->
|
|
180
193
|
<div class="flex flex-col gap-2">
|
|
181
|
-
<label for="code" class="font-medium">
|
|
194
|
+
<label for="code" class="font-medium">{{ 'iam.action.code' | translate }}</label>
|
|
182
195
|
<input
|
|
183
196
|
pInputText
|
|
184
197
|
id="code"
|
|
185
198
|
[formField]="actionForm.code"
|
|
186
|
-
placeholder="
|
|
199
|
+
[placeholder]="'iam.action.code.placeholder' | translate" />
|
|
187
200
|
</div>
|
|
188
201
|
|
|
189
202
|
<!-- Description -->
|
|
190
203
|
<div class="flex flex-col gap-2">
|
|
191
|
-
<label for="description" class="font-medium">
|
|
204
|
+
<label for="description" class="font-medium">{{ 'shared.description' | translate }}</label>
|
|
192
205
|
<input
|
|
193
206
|
pInputText
|
|
194
207
|
id="description"
|
|
195
208
|
[formField]="actionForm.description"
|
|
196
|
-
placeholder="
|
|
209
|
+
[placeholder]="'shared.description.placeholder' | translate" />
|
|
197
210
|
</div>
|
|
198
211
|
|
|
199
212
|
<!-- Action Type -->
|
|
200
213
|
<div class="flex flex-col gap-2">
|
|
201
|
-
<label for="actionType" class="font-medium">
|
|
214
|
+
<label for="actionType" class="font-medium">{{ 'iam.action.type' | translate }} *</label>
|
|
202
215
|
<select
|
|
203
216
|
id="actionType"
|
|
204
217
|
class="p-inputtext w-full"
|
|
205
218
|
[formField]="actionForm.actionType">
|
|
206
|
-
@for (type of actionTypes; track type.value) {
|
|
219
|
+
@for (type of actionTypes(); track type.value) {
|
|
207
220
|
<option [value]="type.value">{{ type.label }}</option>
|
|
208
221
|
}
|
|
209
222
|
</select>
|
|
@@ -211,12 +224,12 @@ class ActionFormPageComponent {
|
|
|
211
224
|
|
|
212
225
|
<!-- Parent Action -->
|
|
213
226
|
<div class="flex flex-col gap-2">
|
|
214
|
-
<label for="parentId" class="font-medium">
|
|
227
|
+
<label for="parentId" class="font-medium">{{ 'iam.action.parent' | translate }}</label>
|
|
215
228
|
<select
|
|
216
229
|
id="parentId"
|
|
217
230
|
class="p-inputtext w-full"
|
|
218
231
|
[formField]="actionForm.parentId">
|
|
219
|
-
<option value="">
|
|
232
|
+
<option value="">{{ 'iam.action.select.parent' | translate }}</option>
|
|
220
233
|
@for (action of availableActions(); track action.id) {
|
|
221
234
|
<option [value]="action.id">{{ action.name }}</option>
|
|
222
235
|
}
|
|
@@ -225,13 +238,13 @@ class ActionFormPageComponent {
|
|
|
225
238
|
|
|
226
239
|
<!-- Order -->
|
|
227
240
|
<div class="flex flex-col gap-2">
|
|
228
|
-
<label for="serial" class="font-medium">
|
|
241
|
+
<label for="serial" class="font-medium">{{ 'shared.display.order' | translate }}</label>
|
|
229
242
|
<input
|
|
230
243
|
pInputText
|
|
231
244
|
id="serial"
|
|
232
245
|
type="number"
|
|
233
246
|
[formField]="actionForm.serial"
|
|
234
|
-
placeholder="
|
|
247
|
+
[placeholder]="'shared.display.order.placeholder' | translate" />
|
|
235
248
|
</div>
|
|
236
249
|
|
|
237
250
|
<!-- Is Active -->
|
|
@@ -240,7 +253,7 @@ class ActionFormPageComponent {
|
|
|
240
253
|
[formField]="actionForm.isActive"
|
|
241
254
|
[binary]="true"
|
|
242
255
|
inputId="isActive" />
|
|
243
|
-
<label for="isActive">
|
|
256
|
+
<label for="isActive">{{ 'shared.active' | translate }}</label>
|
|
244
257
|
</div>
|
|
245
258
|
|
|
246
259
|
<!-- Permission Logic Builder -->
|
|
@@ -254,71 +267,70 @@ class ActionFormPageComponent {
|
|
|
254
267
|
<!-- Actions -->
|
|
255
268
|
<div class="flex justify-end gap-2 md:col-span-2 pt-4">
|
|
256
269
|
<p-button
|
|
257
|
-
label="
|
|
270
|
+
[label]="'shared.cancel' | translate"
|
|
258
271
|
severity="secondary"
|
|
259
272
|
[outlined]="true"
|
|
260
273
|
(onClick)="onBack()" />
|
|
261
274
|
<p-button
|
|
262
|
-
[label]="isEditMode() ? '
|
|
275
|
+
[label]="isEditMode() ? ('shared.update' | translate) : ('shared.create' | translate)"
|
|
263
276
|
type="submit"
|
|
264
277
|
[loading]="isLoading()"
|
|
265
278
|
[disabled]="!isFormValid() || isLoading()" />
|
|
266
279
|
</div>
|
|
267
280
|
</form>
|
|
268
281
|
</div>
|
|
269
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "component", type: LogicBuilderComponent, selector: "lib-logic-builder", inputs: ["logic", "actions"], outputs: ["logicChange"] }
|
|
282
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i3.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "component", type: LogicBuilderComponent, selector: "lib-logic-builder", inputs: ["logic", "actions"], outputs: ["logicChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
270
283
|
}
|
|
271
284
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ActionFormPageComponent, decorators: [{
|
|
272
285
|
type: Component,
|
|
273
286
|
args: [{
|
|
274
287
|
selector: 'lib-action-form-page',
|
|
275
|
-
imports: [AngularModule, PrimeModule, FormField, LogicBuilderComponent],
|
|
276
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
288
|
+
imports: [AngularModule, PrimeModule, FormField, LogicBuilderComponent, TranslatePipe],
|
|
277
289
|
template: `
|
|
278
290
|
<div class="card">
|
|
279
291
|
<h3 class="text-lg sm:text-xl font-semibold mb-4">
|
|
280
|
-
{{ isEditMode() ? '
|
|
292
|
+
{{ isEditMode() ? ('iam.action.edit' | translate) : ('iam.action.new' | translate) }}
|
|
281
293
|
</h3>
|
|
282
294
|
|
|
283
295
|
<form (ngSubmit)="onSubmit()" class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
284
296
|
<!-- Name -->
|
|
285
297
|
<div class="flex flex-col gap-2">
|
|
286
|
-
<label for="name" class="font-medium">
|
|
298
|
+
<label for="name" class="font-medium">{{ 'iam.action.name' | translate }} *</label>
|
|
287
299
|
<input
|
|
288
300
|
pInputText
|
|
289
301
|
id="name"
|
|
290
302
|
[formField]="actionForm.name"
|
|
291
|
-
placeholder="
|
|
303
|
+
[placeholder]="'iam.action.name.placeholder' | translate" />
|
|
292
304
|
</div>
|
|
293
305
|
|
|
294
306
|
<!-- Code -->
|
|
295
307
|
<div class="flex flex-col gap-2">
|
|
296
|
-
<label for="code" class="font-medium">
|
|
308
|
+
<label for="code" class="font-medium">{{ 'iam.action.code' | translate }}</label>
|
|
297
309
|
<input
|
|
298
310
|
pInputText
|
|
299
311
|
id="code"
|
|
300
312
|
[formField]="actionForm.code"
|
|
301
|
-
placeholder="
|
|
313
|
+
[placeholder]="'iam.action.code.placeholder' | translate" />
|
|
302
314
|
</div>
|
|
303
315
|
|
|
304
316
|
<!-- Description -->
|
|
305
317
|
<div class="flex flex-col gap-2">
|
|
306
|
-
<label for="description" class="font-medium">
|
|
318
|
+
<label for="description" class="font-medium">{{ 'shared.description' | translate }}</label>
|
|
307
319
|
<input
|
|
308
320
|
pInputText
|
|
309
321
|
id="description"
|
|
310
322
|
[formField]="actionForm.description"
|
|
311
|
-
placeholder="
|
|
323
|
+
[placeholder]="'shared.description.placeholder' | translate" />
|
|
312
324
|
</div>
|
|
313
325
|
|
|
314
326
|
<!-- Action Type -->
|
|
315
327
|
<div class="flex flex-col gap-2">
|
|
316
|
-
<label for="actionType" class="font-medium">
|
|
328
|
+
<label for="actionType" class="font-medium">{{ 'iam.action.type' | translate }} *</label>
|
|
317
329
|
<select
|
|
318
330
|
id="actionType"
|
|
319
331
|
class="p-inputtext w-full"
|
|
320
332
|
[formField]="actionForm.actionType">
|
|
321
|
-
@for (type of actionTypes; track type.value) {
|
|
333
|
+
@for (type of actionTypes(); track type.value) {
|
|
322
334
|
<option [value]="type.value">{{ type.label }}</option>
|
|
323
335
|
}
|
|
324
336
|
</select>
|
|
@@ -326,12 +338,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
326
338
|
|
|
327
339
|
<!-- Parent Action -->
|
|
328
340
|
<div class="flex flex-col gap-2">
|
|
329
|
-
<label for="parentId" class="font-medium">
|
|
341
|
+
<label for="parentId" class="font-medium">{{ 'iam.action.parent' | translate }}</label>
|
|
330
342
|
<select
|
|
331
343
|
id="parentId"
|
|
332
344
|
class="p-inputtext w-full"
|
|
333
345
|
[formField]="actionForm.parentId">
|
|
334
|
-
<option value="">
|
|
346
|
+
<option value="">{{ 'iam.action.select.parent' | translate }}</option>
|
|
335
347
|
@for (action of availableActions(); track action.id) {
|
|
336
348
|
<option [value]="action.id">{{ action.name }}</option>
|
|
337
349
|
}
|
|
@@ -340,13 +352,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
340
352
|
|
|
341
353
|
<!-- Order -->
|
|
342
354
|
<div class="flex flex-col gap-2">
|
|
343
|
-
<label for="serial" class="font-medium">
|
|
355
|
+
<label for="serial" class="font-medium">{{ 'shared.display.order' | translate }}</label>
|
|
344
356
|
<input
|
|
345
357
|
pInputText
|
|
346
358
|
id="serial"
|
|
347
359
|
type="number"
|
|
348
360
|
[formField]="actionForm.serial"
|
|
349
|
-
placeholder="
|
|
361
|
+
[placeholder]="'shared.display.order.placeholder' | translate" />
|
|
350
362
|
</div>
|
|
351
363
|
|
|
352
364
|
<!-- Is Active -->
|
|
@@ -355,7 +367,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
355
367
|
[formField]="actionForm.isActive"
|
|
356
368
|
[binary]="true"
|
|
357
369
|
inputId="isActive" />
|
|
358
|
-
<label for="isActive">
|
|
370
|
+
<label for="isActive">{{ 'shared.active' | translate }}</label>
|
|
359
371
|
</div>
|
|
360
372
|
|
|
361
373
|
<!-- Permission Logic Builder -->
|
|
@@ -369,12 +381,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
369
381
|
<!-- Actions -->
|
|
370
382
|
<div class="flex justify-end gap-2 md:col-span-2 pt-4">
|
|
371
383
|
<p-button
|
|
372
|
-
label="
|
|
384
|
+
[label]="'shared.cancel' | translate"
|
|
373
385
|
severity="secondary"
|
|
374
386
|
[outlined]="true"
|
|
375
387
|
(onClick)="onBack()" />
|
|
376
388
|
<p-button
|
|
377
|
-
[label]="isEditMode() ? '
|
|
389
|
+
[label]="isEditMode() ? ('shared.update' | translate) : ('shared.create' | translate)"
|
|
378
390
|
type="submit"
|
|
379
391
|
[loading]="isLoading()"
|
|
380
392
|
[disabled]="!isFormValid() || isLoading()" />
|
|
@@ -386,4 +398,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
386
398
|
}], ctorParameters: () => [] });
|
|
387
399
|
|
|
388
400
|
export { ActionFormPageComponent };
|
|
389
|
-
//# sourceMappingURL=flusys-ng-iam-action-form-page.component-
|
|
401
|
+
//# sourceMappingURL=flusys-ng-iam-action-form-page.component-BQx9yset.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flusys-ng-iam-action-form-page.component-BQx9yset.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 { TRANSLATE_ADAPTER } from '@flusys/ng-core';\nimport { AngularModule, ILogicNode, PrimeModule, TranslatePipe } from '@flusys/ng-shared';\nimport { MessageService } from 'primeng/api';\nimport { firstValueFrom } from 'rxjs';\nimport { LogicBuilderComponent } from '../../components/logic-builder.component';\nimport { ActionType, IAction } from '../../interfaces/action.interface';\nimport { ActionApiService } from '../../services/action-api.service';\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;\n serial: string;\n isActive: boolean;\n metadata: Record<string, unknown> | null;\n}\n\n@Component({\n selector: 'lib-action-form-page',\n imports: [AngularModule, PrimeModule, FormField, LogicBuilderComponent, TranslatePipe],\n template: `\n <div class=\"card\">\n <h3 class=\"text-lg sm:text-xl font-semibold mb-4\">\n {{ isEditMode() ? ('iam.action.edit' | translate) : ('iam.action.new' | translate) }}\n </h3>\n\n <form (ngSubmit)=\"onSubmit()\" class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <!-- Name -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"name\" class=\"font-medium\">{{ 'iam.action.name' | translate }} *</label>\n <input\n pInputText\n id=\"name\"\n [formField]=\"actionForm.name\"\n [placeholder]=\"'iam.action.name.placeholder' | translate\" />\n </div>\n\n <!-- Code -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"code\" class=\"font-medium\">{{ 'iam.action.code' | translate }}</label>\n <input\n pInputText\n id=\"code\"\n [formField]=\"actionForm.code\"\n [placeholder]=\"'iam.action.code.placeholder' | translate\" />\n </div>\n\n <!-- Description -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"description\" class=\"font-medium\">{{ 'shared.description' | translate }}</label>\n <input\n pInputText\n id=\"description\"\n [formField]=\"actionForm.description\"\n [placeholder]=\"'shared.description.placeholder' | translate\" />\n </div>\n\n <!-- Action Type -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"actionType\" class=\"font-medium\">{{ 'iam.action.type' | translate }} *</label>\n <select\n id=\"actionType\"\n class=\"p-inputtext w-full\"\n [formField]=\"actionForm.actionType\">\n @for (type of actionTypes(); track type.value) {\n <option [value]=\"type.value\">{{ type.label }}</option>\n }\n </select>\n </div>\n\n <!-- Parent Action -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"parentId\" class=\"font-medium\">{{ 'iam.action.parent' | translate }}</label>\n <select\n id=\"parentId\"\n class=\"p-inputtext w-full\"\n [formField]=\"actionForm.parentId\">\n <option value=\"\">{{ 'iam.action.select.parent' | translate }}</option>\n @for (action of availableActions(); track action.id) {\n <option [value]=\"action.id\">{{ action.name }}</option>\n }\n </select>\n </div>\n\n <!-- Order -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"serial\" class=\"font-medium\">{{ 'shared.display.order' | translate }}</label>\n <input\n pInputText\n id=\"serial\"\n type=\"number\"\n [formField]=\"actionForm.serial\"\n [placeholder]=\"'shared.display.order.placeholder' | translate\" />\n </div>\n\n <!-- Is Active -->\n <div class=\"flex items-end gap-2 pb-1 md:col-span-2\">\n <p-checkbox\n [formField]=\"actionForm.isActive\"\n [binary]=\"true\"\n inputId=\"isActive\" />\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 </div>\n\n <!-- Actions -->\n <div class=\"flex justify-end gap-2 md:col-span-2 pt-4\">\n <p-button\n [label]=\"'shared.cancel' | translate\"\n severity=\"secondary\"\n [outlined]=\"true\"\n (onClick)=\"onBack()\" />\n <p-button\n [label]=\"isEditMode() ? ('shared.update' | translate) : ('shared.create' | translate)\"\n type=\"submit\"\n [loading]=\"isLoading()\"\n [disabled]=\"!isFormValid() || isLoading()\" />\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(TRANSLATE_ADAPTER, { optional: true });\n private readonly routeParams = toSignal(this.route.paramMap);\n private initialized = false;\n\n private translate(key: string, vars?: Record<string, string | number>): 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 availableActions = computed(() => {\n const actions = this.allActions();\n const currentId = this.existingAction()?.id;\n return currentId ? actions.filter((a) => a.id !== currentId) : actions;\n });\n\n readonly formModel = signal<IActionFormModel>({\n id: '',\n name: '',\n description: '',\n code: '',\n actionType: ActionType.BACKEND,\n permissionLogic: null,\n parentId: '',\n serial: '',\n isActive: true,\n metadata: null,\n });\n\n readonly actionTypes = computed(() => [\n { label: this.translate('iam.action.type.backend.label'), value: ActionType.BACKEND },\n { label: this.translate('iam.action.type.frontend.label'), value: ActionType.FRONTEND },\n { label: this.translate('iam.action.type.both.label'), value: ActionType.BOTH },\n ]);\n\n readonly actionForm = form(this.formModel, (f) => {\n required(f.name, { message: this.translate('shared.validation.required', { field: this.translate('iam.action.name') }) });\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 firstValueFrom(\n this.actionApi.getAll('', {\n pagination: { currentPage: 0, pageSize: 10000 },\n select: ['id', 'name', 'code', 'actionType', 'permissionLogic'],\n }),\n );\n if (response?.success && response.data) {\n this.allActionsForLogic.set(response.data.map((a) => ({ id: a.id!, name: a.name ?? this.translate('shared.unnamed') })));\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.findByIdAsync(id, [\n 'id', 'name', 'description', 'code', 'actionType',\n 'permissionLogic', 'parentId', 'serial', 'isActive', 'metadata',\n ]);\n\n if (response?.success && response.data) {\n const action = response.data;\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 ?? '',\n serial: action.serial?.toString() ?? '',\n isActive: action.isActive ?? true,\n metadata: action.metadata ?? null,\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(): Promise<void> {\n if (!this.isFormValid()) {\n this.messageService.add({\n severity: 'error',\n summary: this.translate('shared.validation.error'),\n detail: this.translate('shared.fill.required.fields'),\n });\n return;\n }\n\n this.isLoading.set(true);\n\n try {\n const formValue = this.formModel();\n 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 metadata: formValue.metadata ?? undefined,\n permissionLogic: formValue.permissionLogic ?? undefined,\n };\n\n if (this.isEditMode()) {\n await this.actionApi.updateAsync(dto);\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: this.translate('iam.action.update.success'),\n });\n } else {\n await this.actionApi.insertAsync(dto);\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: this.translate('iam.action.create.success'),\n });\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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"}
|