@flusys/ng-iam 1.0.0-rc → 1.1.1-beta
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 +24 -175
- package/fesm2022/{flusys-ng-iam-action-form-page.component-C_BRrrWW.mjs → flusys-ng-iam-action-form-page.component-C1j10Qhw.mjs} +202 -174
- package/fesm2022/flusys-ng-iam-action-form-page.component-C1j10Qhw.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam-action-list-page.component-BCzSardO.mjs +281 -0
- package/fesm2022/flusys-ng-iam-action-list-page.component-BCzSardO.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-flusys-ng-iam-BPIpfrjN.mjs → flusys-ng-iam-flusys-ng-iam-DISrddPh.mjs} +829 -822
- package/fesm2022/flusys-ng-iam-flusys-ng-iam-DISrddPh.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam-iam-container.component-BkhqmzLi.mjs +97 -0
- package/fesm2022/flusys-ng-iam-iam-container.component-BkhqmzLi.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-permission-page.component-CmxOBJPu.mjs → flusys-ng-iam-permission-page.component-BSQFPt_N.mjs} +12 -41
- package/fesm2022/flusys-ng-iam-permission-page.component-BSQFPt_N.mjs.map +1 -0
- package/fesm2022/{flusys-ng-iam-role-form-page.component-ByNueI1a.mjs → flusys-ng-iam-role-form-page.component-Cqziu_BM.mjs} +134 -106
- package/fesm2022/flusys-ng-iam-role-form-page.component-Cqziu_BM.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam-role-list-page.component-BObCxHiB.mjs +266 -0
- package/fesm2022/flusys-ng-iam-role-list-page.component-BObCxHiB.mjs.map +1 -0
- package/fesm2022/flusys-ng-iam.mjs +1 -1
- package/package.json +2 -2
- package/types/flusys-ng-iam.d.ts +21 -40
- package/fesm2022/flusys-ng-iam-action-form-page.component-C_BRrrWW.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-action-list-page.component-Daf93zpS.mjs +0 -289
- package/fesm2022/flusys-ng-iam-action-list-page.component-Daf93zpS.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-flusys-ng-iam-BPIpfrjN.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-iam-container.component-Bn4kQtxW.mjs +0 -92
- package/fesm2022/flusys-ng-iam-iam-container.component-Bn4kQtxW.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-permission-page.component-CmxOBJPu.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-role-form-page.component-ByNueI1a.mjs.map +0 -1
- package/fesm2022/flusys-ng-iam-role-list-page.component-CFly5KnH.mjs +0 -316
- package/fesm2022/flusys-ng-iam-role-list-page.component-CFly5KnH.mjs.map +0 -1
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, signal, computed,
|
|
3
|
-
import { toSignal } from '@angular/core/rxjs-interop';
|
|
2
|
+
import { inject, signal, computed, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
3
|
import { form, required, FormField } from '@angular/forms/signals';
|
|
5
4
|
import { ActivatedRoute, Router } from '@angular/router';
|
|
6
5
|
import { AngularModule, PrimeModule } from '@flusys/ng-shared';
|
|
7
6
|
import { MessageService } from 'primeng/api';
|
|
8
7
|
import { firstValueFrom } from 'rxjs';
|
|
9
|
-
import { A as ActionApiService, a as ActionType, L as LogicBuilderComponent } from './flusys-ng-iam-flusys-ng-iam-
|
|
8
|
+
import { A as ActionApiService, a as ActionType, L as LogicBuilderComponent } from './flusys-ng-iam-flusys-ng-iam-DISrddPh.mjs';
|
|
10
9
|
import * as i1 from '@angular/forms';
|
|
11
10
|
import * as i2 from 'primeng/button';
|
|
12
|
-
import * as i3 from 'primeng/
|
|
13
|
-
import * as i4 from 'primeng/inputtext';
|
|
11
|
+
import * as i3 from 'primeng/inputtext';
|
|
14
12
|
|
|
15
13
|
/**
|
|
16
14
|
* Action Form Page Component
|
|
@@ -21,8 +19,6 @@ class ActionFormPageComponent {
|
|
|
21
19
|
router = inject(Router);
|
|
22
20
|
actionApi = inject(ActionApiService);
|
|
23
21
|
messageService = inject(MessageService);
|
|
24
|
-
routeParams = toSignal(this.route.paramMap);
|
|
25
|
-
initialized = false;
|
|
26
22
|
/** Loading state */
|
|
27
23
|
isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
28
24
|
/** Existing action data when editing */
|
|
@@ -70,16 +66,8 @@ class ActionFormPageComponent {
|
|
|
70
66
|
const model = this.formModel();
|
|
71
67
|
return model.name.trim().length > 0;
|
|
72
68
|
}, ...(ngDevMode ? [{ debugName: "isFormValid" }] : []));
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const params = this.routeParams();
|
|
76
|
-
if (!params || this.initialized)
|
|
77
|
-
return;
|
|
78
|
-
this.initialized = true;
|
|
79
|
-
this.initializeForm(params.get('id'));
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
async initializeForm(id) {
|
|
69
|
+
async ngOnInit() {
|
|
70
|
+
const id = this.route.snapshot.paramMap.get('id');
|
|
83
71
|
// Load ALL actions FIRST - critical for LogicBuilder to display action names
|
|
84
72
|
try {
|
|
85
73
|
const response = await firstValueFrom(this.actionApi.getAll('', {
|
|
@@ -136,12 +124,20 @@ class ActionFormPageComponent {
|
|
|
136
124
|
});
|
|
137
125
|
}
|
|
138
126
|
else {
|
|
139
|
-
|
|
127
|
+
this.messageService.add({
|
|
128
|
+
severity: 'error',
|
|
129
|
+
summary: 'Error',
|
|
130
|
+
detail: 'Action not found.',
|
|
131
|
+
});
|
|
140
132
|
this.router.navigate(['/iam/actions']);
|
|
141
133
|
}
|
|
142
134
|
}
|
|
143
135
|
catch {
|
|
144
|
-
|
|
136
|
+
this.messageService.add({
|
|
137
|
+
severity: 'error',
|
|
138
|
+
summary: 'Error',
|
|
139
|
+
detail: 'Failed to load action.',
|
|
140
|
+
});
|
|
145
141
|
this.router.navigate(['/iam/actions']);
|
|
146
142
|
}
|
|
147
143
|
finally {
|
|
@@ -188,8 +184,12 @@ class ActionFormPageComponent {
|
|
|
188
184
|
}
|
|
189
185
|
this.router.navigate(['/iam/actions']);
|
|
190
186
|
}
|
|
191
|
-
catch {
|
|
192
|
-
|
|
187
|
+
catch (error) {
|
|
188
|
+
this.messageService.add({
|
|
189
|
+
severity: 'error',
|
|
190
|
+
summary: 'Error',
|
|
191
|
+
detail: error.message || 'Failed to save action.',
|
|
192
|
+
});
|
|
193
193
|
}
|
|
194
194
|
finally {
|
|
195
195
|
this.isLoading.set(false);
|
|
@@ -210,90 +210,104 @@ class ActionFormPageComponent {
|
|
|
210
210
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ActionFormPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
211
211
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ActionFormPageComponent, isStandalone: true, selector: "lib-action-form-page", ngImport: i0, template: `
|
|
212
212
|
<div class="card">
|
|
213
|
-
<
|
|
214
|
-
|
|
215
|
-
|
|
213
|
+
<div class="flex justify-between items-center mb-4">
|
|
214
|
+
<h3 class="text-xl font-semibold">
|
|
215
|
+
{{ isEditMode() ? 'Edit Action' : 'New Action' }}
|
|
216
|
+
</h3>
|
|
217
|
+
<p-button
|
|
218
|
+
label="Back"
|
|
219
|
+
icon="pi pi-arrow-left"
|
|
220
|
+
[outlined]="true"
|
|
221
|
+
(onClick)="onBack()" />
|
|
222
|
+
</div>
|
|
216
223
|
|
|
217
|
-
<form (ngSubmit)="onSubmit()"
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
<
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
224
|
+
<form (ngSubmit)="onSubmit()">
|
|
225
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
226
|
+
<!-- Name -->
|
|
227
|
+
<div>
|
|
228
|
+
<label for="name" class="block font-medium mb-2">Name *</label>
|
|
229
|
+
<input
|
|
230
|
+
pInputText
|
|
231
|
+
id="name"
|
|
232
|
+
[formField]="actionForm.name"
|
|
233
|
+
class="w-full"
|
|
234
|
+
placeholder="Enter action name" />
|
|
235
|
+
</div>
|
|
227
236
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
+
<!-- Code -->
|
|
238
|
+
<div>
|
|
239
|
+
<label for="code" class="block font-medium mb-2">Code</label>
|
|
240
|
+
<input
|
|
241
|
+
pInputText
|
|
242
|
+
id="code"
|
|
243
|
+
[formField]="actionForm.code"
|
|
244
|
+
class="w-full"
|
|
245
|
+
placeholder="Enter action code" />
|
|
246
|
+
</div>
|
|
237
247
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
248
|
+
<!-- Description -->
|
|
249
|
+
<div class="md:col-span-2">
|
|
250
|
+
<label for="description" class="block font-medium mb-2">Description</label>
|
|
251
|
+
<input
|
|
252
|
+
pInputText
|
|
253
|
+
id="description"
|
|
254
|
+
[formField]="actionForm.description"
|
|
255
|
+
class="w-full"
|
|
256
|
+
placeholder="Enter description" />
|
|
257
|
+
</div>
|
|
247
258
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
259
|
+
<!-- Action Type -->
|
|
260
|
+
<div>
|
|
261
|
+
<label for="actionType" class="block font-medium mb-2">Action Type *</label>
|
|
262
|
+
<select
|
|
263
|
+
id="actionType"
|
|
264
|
+
class="p-select-native"
|
|
265
|
+
[formField]="actionForm.actionType">
|
|
266
|
+
@for (type of actionTypes; track type.value) {
|
|
267
|
+
<option [value]="type.value">{{ type.label }}</option>
|
|
268
|
+
}
|
|
269
|
+
</select>
|
|
270
|
+
</div>
|
|
260
271
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
272
|
+
<!-- Parent Action -->
|
|
273
|
+
<div>
|
|
274
|
+
<label for="parentId" class="block font-medium mb-2">Parent Action</label>
|
|
275
|
+
<select
|
|
276
|
+
id="parentId"
|
|
277
|
+
class="p-select-native"
|
|
278
|
+
[formField]="actionForm.parentId">
|
|
279
|
+
<option value="">Select parent action</option>
|
|
280
|
+
@for (action of availableActions(); track action.id) {
|
|
281
|
+
<option [value]="action.id">{{ action.name }}</option>
|
|
282
|
+
}
|
|
283
|
+
</select>
|
|
284
|
+
</div>
|
|
274
285
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
286
|
+
<!-- Order -->
|
|
287
|
+
<div>
|
|
288
|
+
<label for="serial" class="block font-medium mb-2">Display Order</label>
|
|
289
|
+
<input
|
|
290
|
+
pInputText
|
|
291
|
+
id="serial"
|
|
292
|
+
type="number"
|
|
293
|
+
[formField]="actionForm.serial"
|
|
294
|
+
class="w-full"
|
|
295
|
+
placeholder="Enter display order" />
|
|
296
|
+
</div>
|
|
285
297
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
298
|
+
<!-- Is Active -->
|
|
299
|
+
<div class="flex items-center pt-6">
|
|
300
|
+
<label class="p-checkbox-native">
|
|
301
|
+
<input
|
|
302
|
+
type="checkbox"
|
|
303
|
+
[formField]="actionForm.isActive" />
|
|
304
|
+
<span>Active</span>
|
|
305
|
+
</label>
|
|
306
|
+
</div>
|
|
293
307
|
</div>
|
|
294
308
|
|
|
295
309
|
<!-- Permission Logic Builder -->
|
|
296
|
-
<div class="
|
|
310
|
+
<div class="mt-6">
|
|
297
311
|
<lib-logic-builder
|
|
298
312
|
[logic]="formModel().permissionLogic"
|
|
299
313
|
[actions]="allActionsForLogic()"
|
|
@@ -301,7 +315,7 @@ class ActionFormPageComponent {
|
|
|
301
315
|
</div>
|
|
302
316
|
|
|
303
317
|
<!-- Actions -->
|
|
304
|
-
<div class="flex justify-end gap-2
|
|
318
|
+
<div class="flex justify-end gap-2 mt-6">
|
|
305
319
|
<p-button
|
|
306
320
|
label="Cancel"
|
|
307
321
|
severity="secondary"
|
|
@@ -315,7 +329,7 @@ class ActionFormPageComponent {
|
|
|
315
329
|
</div>
|
|
316
330
|
</form>
|
|
317
331
|
</div>
|
|
318
|
-
`, 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: "
|
|
332
|
+
`, 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: "directive", type: i3.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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
319
333
|
}
|
|
320
334
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ActionFormPageComponent, decorators: [{
|
|
321
335
|
type: Component,
|
|
@@ -326,90 +340,104 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
326
340
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
327
341
|
template: `
|
|
328
342
|
<div class="card">
|
|
329
|
-
<
|
|
330
|
-
|
|
331
|
-
|
|
343
|
+
<div class="flex justify-between items-center mb-4">
|
|
344
|
+
<h3 class="text-xl font-semibold">
|
|
345
|
+
{{ isEditMode() ? 'Edit Action' : 'New Action' }}
|
|
346
|
+
</h3>
|
|
347
|
+
<p-button
|
|
348
|
+
label="Back"
|
|
349
|
+
icon="pi pi-arrow-left"
|
|
350
|
+
[outlined]="true"
|
|
351
|
+
(onClick)="onBack()" />
|
|
352
|
+
</div>
|
|
332
353
|
|
|
333
|
-
<form (ngSubmit)="onSubmit()"
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
<
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
354
|
+
<form (ngSubmit)="onSubmit()">
|
|
355
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
356
|
+
<!-- Name -->
|
|
357
|
+
<div>
|
|
358
|
+
<label for="name" class="block font-medium mb-2">Name *</label>
|
|
359
|
+
<input
|
|
360
|
+
pInputText
|
|
361
|
+
id="name"
|
|
362
|
+
[formField]="actionForm.name"
|
|
363
|
+
class="w-full"
|
|
364
|
+
placeholder="Enter action name" />
|
|
365
|
+
</div>
|
|
343
366
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
367
|
+
<!-- Code -->
|
|
368
|
+
<div>
|
|
369
|
+
<label for="code" class="block font-medium mb-2">Code</label>
|
|
370
|
+
<input
|
|
371
|
+
pInputText
|
|
372
|
+
id="code"
|
|
373
|
+
[formField]="actionForm.code"
|
|
374
|
+
class="w-full"
|
|
375
|
+
placeholder="Enter action code" />
|
|
376
|
+
</div>
|
|
353
377
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
378
|
+
<!-- Description -->
|
|
379
|
+
<div class="md:col-span-2">
|
|
380
|
+
<label for="description" class="block font-medium mb-2">Description</label>
|
|
381
|
+
<input
|
|
382
|
+
pInputText
|
|
383
|
+
id="description"
|
|
384
|
+
[formField]="actionForm.description"
|
|
385
|
+
class="w-full"
|
|
386
|
+
placeholder="Enter description" />
|
|
387
|
+
</div>
|
|
363
388
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
389
|
+
<!-- Action Type -->
|
|
390
|
+
<div>
|
|
391
|
+
<label for="actionType" class="block font-medium mb-2">Action Type *</label>
|
|
392
|
+
<select
|
|
393
|
+
id="actionType"
|
|
394
|
+
class="p-select-native"
|
|
395
|
+
[formField]="actionForm.actionType">
|
|
396
|
+
@for (type of actionTypes; track type.value) {
|
|
397
|
+
<option [value]="type.value">{{ type.label }}</option>
|
|
398
|
+
}
|
|
399
|
+
</select>
|
|
400
|
+
</div>
|
|
376
401
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
402
|
+
<!-- Parent Action -->
|
|
403
|
+
<div>
|
|
404
|
+
<label for="parentId" class="block font-medium mb-2">Parent Action</label>
|
|
405
|
+
<select
|
|
406
|
+
id="parentId"
|
|
407
|
+
class="p-select-native"
|
|
408
|
+
[formField]="actionForm.parentId">
|
|
409
|
+
<option value="">Select parent action</option>
|
|
410
|
+
@for (action of availableActions(); track action.id) {
|
|
411
|
+
<option [value]="action.id">{{ action.name }}</option>
|
|
412
|
+
}
|
|
413
|
+
</select>
|
|
414
|
+
</div>
|
|
390
415
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
416
|
+
<!-- Order -->
|
|
417
|
+
<div>
|
|
418
|
+
<label for="serial" class="block font-medium mb-2">Display Order</label>
|
|
419
|
+
<input
|
|
420
|
+
pInputText
|
|
421
|
+
id="serial"
|
|
422
|
+
type="number"
|
|
423
|
+
[formField]="actionForm.serial"
|
|
424
|
+
class="w-full"
|
|
425
|
+
placeholder="Enter display order" />
|
|
426
|
+
</div>
|
|
401
427
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
428
|
+
<!-- Is Active -->
|
|
429
|
+
<div class="flex items-center pt-6">
|
|
430
|
+
<label class="p-checkbox-native">
|
|
431
|
+
<input
|
|
432
|
+
type="checkbox"
|
|
433
|
+
[formField]="actionForm.isActive" />
|
|
434
|
+
<span>Active</span>
|
|
435
|
+
</label>
|
|
436
|
+
</div>
|
|
409
437
|
</div>
|
|
410
438
|
|
|
411
439
|
<!-- Permission Logic Builder -->
|
|
412
|
-
<div class="
|
|
440
|
+
<div class="mt-6">
|
|
413
441
|
<lib-logic-builder
|
|
414
442
|
[logic]="formModel().permissionLogic"
|
|
415
443
|
[actions]="allActionsForLogic()"
|
|
@@ -417,7 +445,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
417
445
|
</div>
|
|
418
446
|
|
|
419
447
|
<!-- Actions -->
|
|
420
|
-
<div class="flex justify-end gap-2
|
|
448
|
+
<div class="flex justify-end gap-2 mt-6">
|
|
421
449
|
<p-button
|
|
422
450
|
label="Cancel"
|
|
423
451
|
severity="secondary"
|
|
@@ -433,7 +461,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
433
461
|
</div>
|
|
434
462
|
`,
|
|
435
463
|
}]
|
|
436
|
-
}]
|
|
464
|
+
}] });
|
|
437
465
|
|
|
438
466
|
export { ActionFormPageComponent };
|
|
439
|
-
//# sourceMappingURL=flusys-ng-iam-action-form-page.component-
|
|
467
|
+
//# sourceMappingURL=flusys-ng-iam-action-form-page.component-C1j10Qhw.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flusys-ng-iam-action-form-page.component-C1j10Qhw.mjs","sources":["../../../projects/ng-iam/pages/action/action-form-page.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, inject, OnInit, signal } from '@angular/core';\nimport { form, FormField, required } from '@angular/forms/signals';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { AngularModule, ILogicNode, PrimeModule } from '@flusys/ng-shared';\nimport { MessageService } from 'primeng/api';\nimport { firstValueFrom } from 'rxjs';\nimport { ActionApiService } from '../../services/action-api.service';\nimport { IAction, ActionType } from '../../interfaces/action.interface';\nimport { LogicBuilderComponent } from '../../components/logic-builder.component';\n\n/** Action form model interface */\ninterface IActionFormModel {\n id: string;\n name: string;\n description: string;\n code: string;\n actionType: ActionType;\n permissionLogic: any | null;\n parentId: string;\n serial: string;\n isActive: boolean;\n metadata: any | null;\n}\n\n/**\n * Action Form Page Component\n * Create/Edit action with signal-based form pattern (matches ng-auth)\n */\n@Component({\n selector: 'lib-action-form-page',\n standalone: true,\n imports: [AngularModule, PrimeModule, FormField, LogicBuilderComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"card\">\n <div class=\"flex justify-between items-center mb-4\">\n <h3 class=\"text-xl font-semibold\">\n {{ isEditMode() ? 'Edit Action' : 'New Action' }}\n </h3>\n <p-button\n label=\"Back\"\n icon=\"pi pi-arrow-left\"\n [outlined]=\"true\"\n (onClick)=\"onBack()\" />\n </div>\n\n <form (ngSubmit)=\"onSubmit()\">\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <!-- Name -->\n <div>\n <label for=\"name\" class=\"block font-medium mb-2\">Name *</label>\n <input\n pInputText\n id=\"name\"\n [formField]=\"actionForm.name\"\n class=\"w-full\"\n placeholder=\"Enter action name\" />\n </div>\n\n <!-- Code -->\n <div>\n <label for=\"code\" class=\"block font-medium mb-2\">Code</label>\n <input\n pInputText\n id=\"code\"\n [formField]=\"actionForm.code\"\n class=\"w-full\"\n placeholder=\"Enter action code\" />\n </div>\n\n <!-- Description -->\n <div class=\"md:col-span-2\">\n <label for=\"description\" class=\"block font-medium mb-2\">Description</label>\n <input\n pInputText\n id=\"description\"\n [formField]=\"actionForm.description\"\n class=\"w-full\"\n placeholder=\"Enter description\" />\n </div>\n\n <!-- Action Type -->\n <div>\n <label for=\"actionType\" class=\"block font-medium mb-2\">Action Type *</label>\n <select\n id=\"actionType\"\n class=\"p-select-native\"\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>\n <label for=\"parentId\" class=\"block font-medium mb-2\">Parent Action</label>\n <select\n id=\"parentId\"\n class=\"p-select-native\"\n [formField]=\"actionForm.parentId\">\n <option value=\"\">Select parent action</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>\n <label for=\"serial\" class=\"block font-medium mb-2\">Display Order</label>\n <input\n pInputText\n id=\"serial\"\n type=\"number\"\n [formField]=\"actionForm.serial\"\n class=\"w-full\"\n placeholder=\"Enter display order\" />\n </div>\n\n <!-- Is Active -->\n <div class=\"flex items-center pt-6\">\n <label class=\"p-checkbox-native\">\n <input\n type=\"checkbox\"\n [formField]=\"actionForm.isActive\" />\n <span>Active</span>\n </label>\n </div>\n </div>\n\n <!-- Permission Logic Builder -->\n <div class=\"mt-6\">\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 mt-6\">\n <p-button\n label=\"Cancel\"\n severity=\"secondary\"\n [outlined]=\"true\"\n (onClick)=\"onBack()\" />\n <p-button\n [label]=\"isEditMode() ? 'Update' : 'Create'\"\n type=\"submit\"\n [loading]=\"isLoading()\"\n [disabled]=\"!isFormValid() || isLoading()\" />\n </div>\n </form>\n </div>\n `,\n})\nexport class ActionFormPageComponent implements OnInit {\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\n /** Loading state */\n readonly isLoading = signal(false);\n\n /** Existing action data when editing */\n readonly existingAction = signal<IAction | null>(null);\n\n /** Whether in edit mode */\n readonly isEditMode = computed(() => !!this.existingAction());\n\n /** All actions for LogicBuilder */\n readonly allActionsForLogic = signal<Array<{ id: string; name: string }>>([]);\n\n /** All loaded actions for parent dropdown */\n readonly allActions = signal<IAction[]>([]);\n\n /** Available actions for parent dropdown (excludes current action to prevent circular reference) */\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 // ============================================\n // Form (Signal Forms)\n // ============================================\n\n /** Form model */\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 /** Available action types for dropdown */\n readonly actionTypes = [\n { label: 'Backend (API Endpoints)', value: ActionType.BACKEND },\n { label: 'Frontend (UI Features)', value: ActionType.FRONTEND },\n { label: 'Both (Backend + Frontend)', value: ActionType.BOTH },\n ];\n\n /** Form with validation schema */\n readonly actionForm = form(this.formModel, (f) => {\n required(f.name, { message: 'Name is required' });\n });\n\n /** Check if form is valid */\n readonly isFormValid = computed(() => {\n const model = this.formModel();\n return model.name.trim().length > 0;\n });\n\n async ngOnInit(): Promise<void> {\n const id = this.route.snapshot.paramMap.get('id');\n\n // Load ALL actions FIRST - critical for LogicBuilder to display action names\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\n if (response?.success && response.data) {\n // Set actions for LogicBuilder dropdown\n this.allActionsForLogic.set(\n response.data.map(a => ({ id: a.id!, name: a.name ?? 'Unnamed' }))\n );\n\n // Store loaded actions locally for parent dropdown\n this.allActions.set(response.data);\n }\n } catch {\n // Actions load failed - form will show empty parent dropdown\n }\n\n // THEN load the specific action (ensures actions are loaded before setting permissionLogic)\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 // Load fresh data from API to ensure permissionLogic is included\n const response = await this.actionApi.findByIdAsync(id, [\n 'id',\n 'name',\n 'description',\n 'code',\n 'actionType',\n 'permissionLogic',\n 'parentId',\n 'serial',\n 'isActive',\n 'metadata',\n ]);\n\n if (response?.success && response.data) {\n const action = response.data;\n\n // Set existing action for reference\n this.existingAction.set(action);\n\n // Populate form with action data\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.messageService.add({\n severity: 'error',\n summary: 'Error',\n detail: 'Action not found.',\n });\n this.router.navigate(['/iam/actions']);\n }\n } catch {\n this.messageService.add({\n severity: 'error',\n summary: 'Error',\n detail: 'Failed to load action.',\n });\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: 'Validation Error',\n detail: 'Please fill in all required fields.',\n });\n return;\n }\n\n this.isLoading.set(true);\n\n try {\n const formValue = this.formModel();\n\n // Convert empty strings to undefined for DTO compatibility\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: 'Success',\n detail: 'Action updated successfully.',\n });\n } else {\n await this.actionApi.insertAsync(dto);\n this.messageService.add({\n severity: 'success',\n summary: 'Success',\n detail: 'Action created successfully.',\n });\n }\n\n this.router.navigate(['/iam/actions']);\n } catch (error: any) {\n this.messageService.add({\n severity: 'error',\n summary: 'Error',\n detail: error.message || 'Failed to save action.',\n });\n } finally {\n this.isLoading.set(false);\n }\n }\n\n onBack(): void {\n this.router.navigate(['/iam/actions']);\n }\n\n /**\n * Handle permission logic changes from LogicBuilder\n */\n onLogicChange(logic: ILogicNode | null): void {\n this.formModel.update(model => ({\n ...model,\n permissionLogic: logic\n }));\n }\n}\n"],"names":[],"mappings":"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"}
|