@masterteam/forms 0.0.45 → 0.0.47
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/masterteam-forms-client-form.mjs +105 -31
- package/fesm2022/masterteam-forms-client-form.mjs.map +1 -1
- package/fesm2022/masterteam-forms-dynamic-field.mjs +7 -2
- package/fesm2022/masterteam-forms-dynamic-field.mjs.map +1 -1
- package/fesm2022/masterteam-forms-dynamic-form.mjs +2 -2
- package/fesm2022/masterteam-forms-dynamic-form.mjs.map +1 -1
- package/package.json +2 -2
- package/types/masterteam-forms-client-form.d.ts +17 -7
- package/types/masterteam-forms-dynamic-field.d.ts +1 -0
|
@@ -6,6 +6,7 @@ import { CommonModule } from '@angular/common';
|
|
|
6
6
|
import { Skeleton } from 'primeng/skeleton';
|
|
7
7
|
import * as i2 from 'primeng/stepper';
|
|
8
8
|
import { StepperModule } from 'primeng/stepper';
|
|
9
|
+
import { EntitiesPreview } from '@masterteam/components/entities';
|
|
9
10
|
import { Tabs } from '@masterteam/components/tabs';
|
|
10
11
|
import { DynamicForm } from '@masterteam/forms/dynamic-form';
|
|
11
12
|
import { HttpClient, HttpContext } from '@angular/common/http';
|
|
@@ -136,6 +137,11 @@ const WIDTH_TO_COLSPAN = {
|
|
|
136
137
|
'50': 6,
|
|
137
138
|
'100': 12,
|
|
138
139
|
};
|
|
140
|
+
const WIDTH_TO_ENTITY_SIZE = {
|
|
141
|
+
'25': 6,
|
|
142
|
+
'50': 12,
|
|
143
|
+
'100': 24,
|
|
144
|
+
};
|
|
139
145
|
// ============================================================================
|
|
140
146
|
// Public Mapper Functions
|
|
141
147
|
// ============================================================================
|
|
@@ -159,7 +165,7 @@ function mapToDynamicFormConfig(config, lang = 'en', mode = 'create', lookups =
|
|
|
159
165
|
const visibleFields = section.fields
|
|
160
166
|
.filter((field) => {
|
|
161
167
|
// isRead=false → completely hidden
|
|
162
|
-
if (field.isRead === false)
|
|
168
|
+
if (field.isWrite !== true && field.isRead === false)
|
|
163
169
|
return false;
|
|
164
170
|
if (mode === 'create')
|
|
165
171
|
return !field.hiddenInCreation;
|
|
@@ -234,18 +240,51 @@ function mapFormValueToSubmitValues(formValue, loadResponse) {
|
|
|
234
240
|
})
|
|
235
241
|
.filter((value) => !!value);
|
|
236
242
|
}
|
|
243
|
+
function getPreviewOnlyFieldKeys(config, mode = 'create') {
|
|
244
|
+
return config.sections.flatMap((section) => (section.fields ?? [])
|
|
245
|
+
.filter((field) => isFieldVisible(field, mode) && isPreviewOnlyField(field))
|
|
246
|
+
.map((field) => field.propertyKey));
|
|
247
|
+
}
|
|
248
|
+
function mapPreviewFieldsToEntities(config, values, mode = 'create') {
|
|
249
|
+
const resolvedValues = mapValuesToFormValue(values, config);
|
|
250
|
+
return config.sections
|
|
251
|
+
.slice()
|
|
252
|
+
.sort((a, b) => a.order - b.order)
|
|
253
|
+
.flatMap((section) => (section.fields ?? [])
|
|
254
|
+
.filter((field) => isFieldVisible(field, mode) && isPreviewOnlyField(field))
|
|
255
|
+
.sort((a, b) => a.order - b.order)
|
|
256
|
+
.flatMap((field) => {
|
|
257
|
+
const property = field.propertyMetadata;
|
|
258
|
+
return [
|
|
259
|
+
{
|
|
260
|
+
...property,
|
|
261
|
+
name: property.name?.display,
|
|
262
|
+
key: property.key ?? field.propertyKey,
|
|
263
|
+
value: resolvedValues[field.propertyKey],
|
|
264
|
+
order: section.order * 1000 + field.order,
|
|
265
|
+
configuration: {
|
|
266
|
+
...property.configuration,
|
|
267
|
+
size: WIDTH_TO_ENTITY_SIZE[field.width] ?? 24,
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
];
|
|
271
|
+
}));
|
|
272
|
+
}
|
|
237
273
|
// ============================================================================
|
|
238
274
|
// Internal Helpers
|
|
239
275
|
// ============================================================================
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
return field.
|
|
276
|
+
function isFieldVisible(field, mode) {
|
|
277
|
+
if (field.isWrite !== true && field.isRead === false)
|
|
278
|
+
return false;
|
|
279
|
+
if (mode === 'create')
|
|
280
|
+
return !field.hiddenInCreation;
|
|
281
|
+
return !field.hiddenInEditForm;
|
|
282
|
+
}
|
|
283
|
+
function isPreviewOnlyField(field) {
|
|
284
|
+
return field.isWrite === false && field.isRead !== false;
|
|
246
285
|
}
|
|
247
286
|
function resolveFieldMeta(field) {
|
|
248
|
-
const property =
|
|
287
|
+
const property = field.propertyMetadata;
|
|
249
288
|
return {
|
|
250
289
|
property,
|
|
251
290
|
propertyId: property?.propertyId,
|
|
@@ -254,7 +293,8 @@ function resolveFieldMeta(field) {
|
|
|
254
293
|
}
|
|
255
294
|
function mapFieldToConfig(field, lang, lookups) {
|
|
256
295
|
const { property: prop, viewType } = resolveFieldMeta(field);
|
|
257
|
-
const label =
|
|
296
|
+
const label = prop?.name?.display ??
|
|
297
|
+
field.propertyKey;
|
|
258
298
|
const colSpan = WIDTH_TO_COLSPAN[field.width] ?? 12;
|
|
259
299
|
const base = {
|
|
260
300
|
key: field.propertyKey,
|
|
@@ -382,14 +422,6 @@ function mapValidationRules(config, lang) {
|
|
|
382
422
|
enabled: rule.enabled,
|
|
383
423
|
}));
|
|
384
424
|
}
|
|
385
|
-
function resolvePropertyName(property, lang) {
|
|
386
|
-
if (!property?.name)
|
|
387
|
-
return '';
|
|
388
|
-
if (typeof property.name === 'string')
|
|
389
|
-
return property.name;
|
|
390
|
-
// Prefer display name, then lang-specific, then English fallback
|
|
391
|
-
return (property.name['display'] ?? property.name[lang] ?? property.name['en'] ?? '');
|
|
392
|
-
}
|
|
393
425
|
/**
|
|
394
426
|
* Resolve lookup items for Lookup / LookupMultiSelect viewTypes.
|
|
395
427
|
*
|
|
@@ -465,7 +497,7 @@ function buildFieldValueMap(config) {
|
|
|
465
497
|
field.propertyKey,
|
|
466
498
|
stripTemplatePrefix(field.propertyKey),
|
|
467
499
|
]);
|
|
468
|
-
const property =
|
|
500
|
+
const property = field.propertyMetadata;
|
|
469
501
|
if (property?.key) {
|
|
470
502
|
aliases.add(property.key);
|
|
471
503
|
aliases.add(stripTemplatePrefix(property.key));
|
|
@@ -591,7 +623,7 @@ class ClientForm {
|
|
|
591
623
|
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
|
|
592
624
|
autoLoad = input(true, ...(ngDevMode ? [{ debugName: "autoLoad" }] : []));
|
|
593
625
|
formMode = input('create', ...(ngDevMode ? [{ debugName: "formMode" }] : []));
|
|
594
|
-
renderMode = input(
|
|
626
|
+
renderMode = input(...(ngDevMode ? [undefined, { debugName: "renderMode" }] : []));
|
|
595
627
|
showInternalStepActions = input(true, ...(ngDevMode ? [{ debugName: "showInternalStepActions" }] : []));
|
|
596
628
|
lang = input('en', ...(ngDevMode ? [{ debugName: "lang" }] : []));
|
|
597
629
|
lookups = input([], ...(ngDevMode ? [{ debugName: "lookups" }] : []));
|
|
@@ -621,9 +653,47 @@ class ClientForm {
|
|
|
621
653
|
}, ...(ngDevMode ? [{ debugName: "initialValues" }] : []));
|
|
622
654
|
virtualFields = computed(() => this.state.virtualFields(), ...(ngDevMode ? [{ debugName: "virtualFields" }] : []));
|
|
623
655
|
hasVirtualFields = computed(() => this.virtualFields().length > 0, ...(ngDevMode ? [{ debugName: "hasVirtualFields" }] : []));
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
656
|
+
previewFieldKeys = computed(() => {
|
|
657
|
+
const config = this.state.formConfiguration();
|
|
658
|
+
if (!config)
|
|
659
|
+
return [];
|
|
660
|
+
return getPreviewOnlyFieldKeys(config, this.formMode());
|
|
661
|
+
}, ...(ngDevMode ? [{ debugName: "previewFieldKeys" }] : []));
|
|
662
|
+
previewEntities = computed(() => {
|
|
663
|
+
const config = this.state.formConfiguration();
|
|
664
|
+
if (!config)
|
|
665
|
+
return [];
|
|
666
|
+
return mapPreviewFieldsToEntities(config, this.state.formValues(), this.formMode());
|
|
667
|
+
}, ...(ngDevMode ? [{ debugName: "previewEntities" }] : []));
|
|
668
|
+
editableFormConfig = computed(() => {
|
|
669
|
+
const config = this.formConfig();
|
|
670
|
+
if (!config)
|
|
671
|
+
return null;
|
|
672
|
+
const previewFieldKeys = new Set(this.previewFieldKeys());
|
|
673
|
+
return {
|
|
674
|
+
...config,
|
|
675
|
+
sections: config.sections
|
|
676
|
+
.map((section) => ({
|
|
677
|
+
...section,
|
|
678
|
+
fields: section.fields.filter((field) => !field.key || !previewFieldKeys.has(field.key)),
|
|
679
|
+
}))
|
|
680
|
+
.filter((section) => section.fields.some((field) => field.type !== 'spacer')),
|
|
681
|
+
};
|
|
682
|
+
}, ...(ngDevMode ? [{ debugName: "editableFormConfig" }] : []));
|
|
683
|
+
stepSections = computed(() => this.editableFormConfig()?.sections ?? [], ...(ngDevMode ? [{ debugName: "stepSections" }] : []));
|
|
684
|
+
hasEditableFormSections = computed(() => this.stepSections().length > 0, ...(ngDevMode ? [{ debugName: "hasEditableFormSections" }] : []));
|
|
685
|
+
effectiveRenderMode = computed(() => {
|
|
686
|
+
const explicitRenderMode = this.renderMode();
|
|
687
|
+
if (explicitRenderMode)
|
|
688
|
+
return explicitRenderMode;
|
|
689
|
+
const configRenderMode = this.state.formConfiguration()?.renderMode;
|
|
690
|
+
if (configRenderMode === 'steps' || configRenderMode === 'tabs') {
|
|
691
|
+
return configRenderMode;
|
|
692
|
+
}
|
|
693
|
+
return 'form';
|
|
694
|
+
}, ...(ngDevMode ? [{ debugName: "effectiveRenderMode" }] : []));
|
|
695
|
+
stepsEnabled = computed(() => this.effectiveRenderMode() === 'steps' && this.stepSections().length > 1, ...(ngDevMode ? [{ debugName: "stepsEnabled" }] : []));
|
|
696
|
+
tabsEnabled = computed(() => this.effectiveRenderMode() === 'tabs' && this.stepSections().length > 1, ...(ngDevMode ? [{ debugName: "tabsEnabled" }] : []));
|
|
627
697
|
sectionNavigationEnabled = computed(() => this.stepsEnabled() || this.tabsEnabled(), ...(ngDevMode ? [{ debugName: "sectionNavigationEnabled" }] : []));
|
|
628
698
|
tabOptions = computed(() => this.stepSections().map((section, index) => ({
|
|
629
699
|
label: section.label || `Tab ${index + 1}`,
|
|
@@ -643,13 +713,16 @@ class ClientForm {
|
|
|
643
713
|
return [];
|
|
644
714
|
const sections = this.stepSections();
|
|
645
715
|
const currentIndex = this.currentStep() - 1;
|
|
646
|
-
|
|
716
|
+
const hiddenFieldKeys = new Set();
|
|
717
|
+
sections.forEach((section, index) => {
|
|
647
718
|
if (index === currentIndex)
|
|
648
|
-
return
|
|
649
|
-
|
|
719
|
+
return;
|
|
720
|
+
section.fields
|
|
650
721
|
.map((field) => field.key)
|
|
651
|
-
.filter((key) => !!key)
|
|
722
|
+
.filter((key) => !!key)
|
|
723
|
+
.forEach((key) => hiddenFieldKeys.add(key));
|
|
652
724
|
});
|
|
725
|
+
return [...hiddenFieldKeys];
|
|
653
726
|
}, ...(ngDevMode ? [{ debugName: "forcedHiddenFieldKeys" }] : []));
|
|
654
727
|
// ============================================================================
|
|
655
728
|
// Effects
|
|
@@ -871,8 +944,8 @@ class ClientForm {
|
|
|
871
944
|
const formValue = this.getFormValue();
|
|
872
945
|
const values = mapFormValueToSubmitValues(formValue, loadResponse);
|
|
873
946
|
const req = {
|
|
874
|
-
moduleKey:
|
|
875
|
-
operationKey:
|
|
947
|
+
moduleKey: this.moduleKey() ?? context?.moduleKey,
|
|
948
|
+
operationKey: this.operationKey() ?? context?.operationKey,
|
|
876
949
|
values,
|
|
877
950
|
};
|
|
878
951
|
const moduleId = context?.moduleId ?? this.moduleId();
|
|
@@ -899,18 +972,19 @@ class ClientForm {
|
|
|
899
972
|
return req;
|
|
900
973
|
}
|
|
901
974
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ClientForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
902
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ClientForm, isStandalone: true, selector: "mt-client-form", inputs: { moduleKey: { classPropertyName: "moduleKey", publicName: "moduleKey", isSignal: true, isRequired: true, transformFunction: null }, operationKey: { classPropertyName: "operationKey", publicName: "operationKey", isSignal: true, isRequired: true, transformFunction: null }, moduleId: { classPropertyName: "moduleId", publicName: "moduleId", isSignal: true, isRequired: false, transformFunction: null }, levelId: { classPropertyName: "levelId", publicName: "levelId", isSignal: true, isRequired: false, transformFunction: null }, levelDataId: { classPropertyName: "levelDataId", publicName: "levelDataId", isSignal: true, isRequired: false, transformFunction: null }, moduleDataId: { classPropertyName: "moduleDataId", publicName: "moduleDataId", isSignal: true, isRequired: false, transformFunction: null }, requestSchemaId: { classPropertyName: "requestSchemaId", publicName: "requestSchemaId", isSignal: true, isRequired: false, transformFunction: null }, draftProcessId: { classPropertyName: "draftProcessId", publicName: "draftProcessId", isSignal: true, isRequired: false, transformFunction: null }, preview: { classPropertyName: "preview", publicName: "preview", isSignal: true, isRequired: false, transformFunction: null }, returnUrl: { classPropertyName: "returnUrl", publicName: "returnUrl", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, autoLoad: { classPropertyName: "autoLoad", publicName: "autoLoad", isSignal: true, isRequired: false, transformFunction: null }, formMode: { classPropertyName: "formMode", publicName: "formMode", isSignal: true, isRequired: false, transformFunction: null }, renderMode: { classPropertyName: "renderMode", publicName: "renderMode", isSignal: true, isRequired: false, transformFunction: null }, showInternalStepActions: { classPropertyName: "showInternalStepActions", publicName: "showInternalStepActions", isSignal: true, isRequired: false, transformFunction: null }, lang: { classPropertyName: "lang", publicName: "lang", isSignal: true, isRequired: false, transformFunction: null }, lookups: { classPropertyName: "lookups", publicName: "lookups", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { loaded: "loaded", submitted: "submitted", errored: "errored", modeDetected: "modeDetected", formSourceDetected: "formSourceDetected" }, providers: [ClientFormStateService], ngImport: i0, template: "<!-- Client Form Template \u2014 Render only, NO action buttons -->\n\n<!-- Loading State -->\n@if (state.loading()) {\n <div class=\"flex flex-col gap-6\">\n <!-- Section header skeleton -->\n <div class=\"flex flex-col gap-4\">\n <p-skeleton width=\"30%\" height=\"1.5rem\" />\n <div class=\"grid grid-cols-12 gap-4\">\n <div class=\"col-span-6 flex flex-col gap-2\">\n <p-skeleton width=\"40%\" height=\"0.875rem\" />\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\n </div>\n <div class=\"col-span-6 flex flex-col gap-2\">\n <p-skeleton width=\"40%\" height=\"0.875rem\" />\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\n </div>\n <div class=\"col-span-12 flex flex-col gap-2\">\n <p-skeleton width=\"25%\" height=\"0.875rem\" />\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\n </div>\n <div class=\"col-span-6 flex flex-col gap-2\">\n <p-skeleton width=\"35%\" height=\"0.875rem\" />\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\n </div>\n <div class=\"col-span-6 flex flex-col gap-2\">\n <p-skeleton width=\"45%\" height=\"0.875rem\" />\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\n </div>\n </div>\n </div>\n\n <!-- Second section skeleton -->\n <div class=\"flex flex-col gap-4\">\n <p-skeleton width=\"25%\" height=\"1.5rem\" />\n <div class=\"grid grid-cols-12 gap-4\">\n <div class=\"col-span-6 flex flex-col gap-2\">\n <p-skeleton width=\"35%\" height=\"0.875rem\" />\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\n </div>\n <div class=\"col-span-6 flex flex-col gap-2\">\n <p-skeleton width=\"50%\" height=\"0.875rem\" />\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\n </div>\n <div class=\"col-span-12 flex flex-col gap-2\">\n <p-skeleton width=\"30%\" height=\"0.875rem\" />\n <p-skeleton width=\"100%\" height=\"5rem\" />\n </div>\n </div>\n </div>\n </div>\n}\n\n<!-- Loaded State -->\n@if (state.isLoaded() && !state.loading()) {\n <!-- Dynamic Form -->\n @if (state.requiresForm() && formConfig(); as config) {\n <div class=\"flex flex-col gap-4\">\n @if (runtimeErrors().length > 0 || runtimeWarnings().length > 0) {\n <div class=\"rounded-lg border border-surface-200 p-4 bg-surface-50\">\n @if (runtimeErrors().length > 0) {\n <div class=\"mb-3\">\n <h4 class=\"text-sm font-semibold text-red-600 mb-2\">\n Validation Errors\n </h4>\n <ul class=\"list-disc ps-5 text-sm text-red-600 space-y-1\">\n @for (\n msg of runtimeErrors();\n track msg.ruleId || msg.fieldKey || msg.message\n ) {\n <li>{{ msg.message }}</li>\n }\n </ul>\n </div>\n }\n\n @if (runtimeWarnings().length > 0) {\n <div>\n <h4 class=\"text-sm font-semibold text-amber-600 mb-2\">\n Validation Warnings\n </h4>\n <ul class=\"list-disc ps-5 text-sm text-amber-700 space-y-1\">\n @for (\n msg of runtimeWarnings();\n track msg.ruleId || msg.fieldKey || msg.message\n ) {\n <li>{{ msg.message }}</li>\n }\n </ul>\n </div>\n }\n </div>\n }\n @if (stepsEnabled()) {\n <div class=\"flex flex-col gap-4\">\n <p-stepper\n [value]=\"currentStep()\"\n (valueChange)=\"onStepChange($event)\"\n >\n <p-step-list>\n @for (section of stepSections(); track section.key || $index) {\n <p-step [value]=\"$index + 1\">\n {{ section.label || \"Step \" + ($index + 1) }}\n </p-step>\n }\n </p-step-list>\n </p-stepper>\n\n @if (showInternalStepActions()) {\n <div class=\"flex justify-between gap-2\">\n <button\n type=\"button\"\n class=\"px-3 py-2 rounded border border-surface-300 text-sm\"\n [disabled]=\"currentStep() === 1\"\n (click)=\"goToPreviousStep()\"\n >\n Previous\n </button>\n <button\n type=\"button\"\n class=\"px-3 py-2 rounded border border-surface-300 text-sm\"\n [disabled]=\"currentStep() === stepSections().length\"\n (click)=\"goToNextStep()\"\n >\n Next\n </button>\n </div>\n }\n </div>\n }\n\n @if (tabsEnabled()) {\n <mt-tabs\n [active]=\"currentStep()\"\n (activeChange)=\"onStepChange($event)\"\n [options]=\"tabOptions()\"\n size=\"small\"\n fluid\n />\n }\n\n <mt-dynamic-form\n [formConfig]=\"config\"\n [formControl]=\"formControl\"\n [visibleSectionKeys]=\"visibleSectionKeys()\"\n [forcedHiddenFieldKeys]=\"forcedHiddenFieldKeys()\"\n [preserveForcedHiddenValues]=\"true\"\n (runtimeMessagesChange)=\"onRuntimeMessagesChange($event)\"\n />\n </div>\n } @else if (!state.requiresForm()) {\n <div\n class=\"flex items-center justify-center p-6 rounded-lg bg-surface-50 border border-surface-200 border-dashed\"\n >\n <p class=\"text-sm text-muted-color\">\n No form required for this operation.\n </p>\n </div>\n }\n}\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys"], outputs: ["runtimeMessagesChange"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "size", "fluid", "disabled"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: StepperModule }, { kind: "component", type: i2.Stepper, selector: "p-stepper", inputs: ["value", "linear", "transitionOptions", "motionOptions"], outputs: ["valueChange"] }, { kind: "component", type: i2.StepList, selector: "p-step-list" }, { kind: "component", type: i2.Step, selector: "p-step", inputs: ["value", "disabled"], outputs: ["valueChange"] }] });
|
|
975
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ClientForm, isStandalone: true, selector: "mt-client-form", inputs: { moduleKey: { classPropertyName: "moduleKey", publicName: "moduleKey", isSignal: true, isRequired: true, transformFunction: null }, operationKey: { classPropertyName: "operationKey", publicName: "operationKey", isSignal: true, isRequired: true, transformFunction: null }, moduleId: { classPropertyName: "moduleId", publicName: "moduleId", isSignal: true, isRequired: false, transformFunction: null }, levelId: { classPropertyName: "levelId", publicName: "levelId", isSignal: true, isRequired: false, transformFunction: null }, levelDataId: { classPropertyName: "levelDataId", publicName: "levelDataId", isSignal: true, isRequired: false, transformFunction: null }, moduleDataId: { classPropertyName: "moduleDataId", publicName: "moduleDataId", isSignal: true, isRequired: false, transformFunction: null }, requestSchemaId: { classPropertyName: "requestSchemaId", publicName: "requestSchemaId", isSignal: true, isRequired: false, transformFunction: null }, draftProcessId: { classPropertyName: "draftProcessId", publicName: "draftProcessId", isSignal: true, isRequired: false, transformFunction: null }, preview: { classPropertyName: "preview", publicName: "preview", isSignal: true, isRequired: false, transformFunction: null }, returnUrl: { classPropertyName: "returnUrl", publicName: "returnUrl", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, autoLoad: { classPropertyName: "autoLoad", publicName: "autoLoad", isSignal: true, isRequired: false, transformFunction: null }, formMode: { classPropertyName: "formMode", publicName: "formMode", isSignal: true, isRequired: false, transformFunction: null }, renderMode: { classPropertyName: "renderMode", publicName: "renderMode", isSignal: true, isRequired: false, transformFunction: null }, showInternalStepActions: { classPropertyName: "showInternalStepActions", publicName: "showInternalStepActions", isSignal: true, isRequired: false, transformFunction: null }, lang: { classPropertyName: "lang", publicName: "lang", isSignal: true, isRequired: false, transformFunction: null }, lookups: { classPropertyName: "lookups", publicName: "lookups", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { loaded: "loaded", submitted: "submitted", errored: "errored", modeDetected: "modeDetected", formSourceDetected: "formSourceDetected" }, providers: [ClientFormStateService], ngImport: i0, template: "<!-- Client Form Template \u2014 Render only, NO action buttons -->\r\n\r\n<!-- Loading State -->\r\n@if (state.loading()) {\r\n <div class=\"flex flex-col gap-6\">\r\n <!-- Section header skeleton -->\r\n <div class=\"flex flex-col gap-4\">\r\n <p-skeleton width=\"30%\" height=\"1.5rem\" />\r\n <div class=\"grid grid-cols-12 gap-4\">\r\n <div class=\"col-span-6 flex flex-col gap-2\">\r\n <p-skeleton width=\"40%\" height=\"0.875rem\" />\r\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\r\n </div>\r\n <div class=\"col-span-6 flex flex-col gap-2\">\r\n <p-skeleton width=\"40%\" height=\"0.875rem\" />\r\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\r\n </div>\r\n <div class=\"col-span-12 flex flex-col gap-2\">\r\n <p-skeleton width=\"25%\" height=\"0.875rem\" />\r\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\r\n </div>\r\n <div class=\"col-span-6 flex flex-col gap-2\">\r\n <p-skeleton width=\"35%\" height=\"0.875rem\" />\r\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\r\n </div>\r\n <div class=\"col-span-6 flex flex-col gap-2\">\r\n <p-skeleton width=\"45%\" height=\"0.875rem\" />\r\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Second section skeleton -->\r\n <div class=\"flex flex-col gap-4\">\r\n <p-skeleton width=\"25%\" height=\"1.5rem\" />\r\n <div class=\"grid grid-cols-12 gap-4\">\r\n <div class=\"col-span-6 flex flex-col gap-2\">\r\n <p-skeleton width=\"35%\" height=\"0.875rem\" />\r\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\r\n </div>\r\n <div class=\"col-span-6 flex flex-col gap-2\">\r\n <p-skeleton width=\"50%\" height=\"0.875rem\" />\r\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\r\n </div>\r\n <div class=\"col-span-12 flex flex-col gap-2\">\r\n <p-skeleton width=\"30%\" height=\"0.875rem\" />\r\n <p-skeleton width=\"100%\" height=\"5rem\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n}\r\n\r\n<!-- Loaded State -->\r\n@if (state.isLoaded() && !state.loading()) {\r\n <div class=\"flex flex-col gap-4\">\r\n @if (previewEntities().length > 0) {\r\n <mt-entities-preview [entities]=\"previewEntities()\" />\r\n }\r\n\r\n <!-- Dynamic Form -->\r\n @if (state.requiresForm() && editableFormConfig(); as config) {\r\n @if (hasEditableFormSections()) {\r\n <div class=\"flex flex-col gap-4\">\r\n @if (runtimeErrors().length > 0 || runtimeWarnings().length > 0) {\r\n <div class=\"rounded-lg border border-surface-200 p-4 bg-surface-50\">\r\n @if (runtimeErrors().length > 0) {\r\n <div class=\"mb-3\">\r\n <h4 class=\"text-sm font-semibold text-red-600 mb-2\">\r\n Validation Errors\r\n </h4>\r\n <ul class=\"list-disc ps-5 text-sm text-red-600 space-y-1\">\r\n @for (\r\n msg of runtimeErrors();\r\n track msg.ruleId || msg.fieldKey || msg.message\r\n ) {\r\n <li>{{ msg.message }}</li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n\r\n @if (runtimeWarnings().length > 0) {\r\n <div>\r\n <h4 class=\"text-sm font-semibold text-amber-600 mb-2\">\r\n Validation Warnings\r\n </h4>\r\n <ul class=\"list-disc ps-5 text-sm text-amber-700 space-y-1\">\r\n @for (\r\n msg of runtimeWarnings();\r\n track msg.ruleId || msg.fieldKey || msg.message\r\n ) {\r\n <li>{{ msg.message }}</li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (stepsEnabled()) {\r\n <div class=\"flex flex-col gap-4\">\r\n <p-stepper\r\n [value]=\"currentStep()\"\r\n (valueChange)=\"onStepChange($event)\"\r\n >\r\n <p-step-list>\r\n @for (\r\n section of stepSections();\r\n track section.key || $index\r\n ) {\r\n <p-step [value]=\"$index + 1\">\r\n {{ section.label || \"Step \" + ($index + 1) }}\r\n </p-step>\r\n }\r\n </p-step-list>\r\n </p-stepper>\r\n\r\n @if (showInternalStepActions()) {\r\n <div class=\"flex justify-between gap-2\">\r\n <button\r\n type=\"button\"\r\n class=\"px-3 py-2 rounded border border-surface-300 text-sm\"\r\n [disabled]=\"currentStep() === 1\"\r\n (click)=\"goToPreviousStep()\"\r\n >\r\n Previous\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"px-3 py-2 rounded border border-surface-300 text-sm\"\r\n [disabled]=\"currentStep() === stepSections().length\"\r\n (click)=\"goToNextStep()\"\r\n >\r\n Next\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (tabsEnabled()) {\r\n <mt-tabs\r\n [active]=\"currentStep()\"\r\n (activeChange)=\"onStepChange($event)\"\r\n [options]=\"tabOptions()\"\r\n size=\"small\"\r\n fluid\r\n />\r\n }\r\n <mt-dynamic-form\r\n [formConfig]=\"config\"\r\n [formControl]=\"formControl\"\r\n [visibleSectionKeys]=\"visibleSectionKeys()\"\r\n [forcedHiddenFieldKeys]=\"forcedHiddenFieldKeys()\"\r\n [preserveForcedHiddenValues]=\"true\"\r\n (runtimeMessagesChange)=\"onRuntimeMessagesChange($event)\"\r\n />\r\n </div>\r\n }\r\n } @else if (previewEntities().length === 0) {\r\n <div\r\n class=\"flex items-center justify-center p-6 rounded-lg bg-surface-50 border border-surface-200 border-dashed\"\r\n >\r\n <p class=\"text-sm text-muted-color\">\r\n No form required for this operation.\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n}\r\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: EntitiesPreview, selector: "mt-entities-preview", inputs: ["entities"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys"], outputs: ["runtimeMessagesChange"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "size", "fluid", "disabled"], outputs: ["activeChange", "onChange"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: StepperModule }, { kind: "component", type: i2.Stepper, selector: "p-stepper", inputs: ["value", "linear", "transitionOptions", "motionOptions"], outputs: ["valueChange"] }, { kind: "component", type: i2.StepList, selector: "p-step-list" }, { kind: "component", type: i2.Step, selector: "p-step", inputs: ["value", "disabled"], outputs: ["valueChange"] }] });
|
|
903
976
|
}
|
|
904
977
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ClientForm, decorators: [{
|
|
905
978
|
type: Component,
|
|
906
979
|
args: [{ selector: 'mt-client-form', standalone: true, imports: [
|
|
907
980
|
CommonModule,
|
|
908
981
|
ReactiveFormsModule,
|
|
982
|
+
EntitiesPreview,
|
|
909
983
|
DynamicForm,
|
|
910
984
|
Tabs,
|
|
911
985
|
Skeleton,
|
|
912
986
|
StepperModule,
|
|
913
|
-
], providers: [ClientFormStateService], template: "<!-- Client Form Template \u2014 Render only, NO action buttons -->\n\n<!-- Loading State -->\n@if (state.loading()) {\n <div class=\"flex flex-col gap-6\">\n <!-- Section header skeleton -->\n <div class=\"flex flex-col gap-4\">\n <p-skeleton width=\"30%\" height=\"1.5rem\" />\n <div class=\"grid grid-cols-12 gap-4\">\n <div class=\"col-span-6 flex flex-col gap-2\">\n <p-skeleton width=\"40%\" height=\"0.875rem\" />\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\n </div>\n <div class=\"col-span-6 flex flex-col gap-2\">\n <p-skeleton width=\"40%\" height=\"0.875rem\" />\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\n </div>\n <div class=\"col-span-12 flex flex-col gap-2\">\n <p-skeleton width=\"25%\" height=\"0.875rem\" />\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\n </div>\n <div class=\"col-span-6 flex flex-col gap-2\">\n <p-skeleton width=\"35%\" height=\"0.875rem\" />\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\n </div>\n <div class=\"col-span-6 flex flex-col gap-2\">\n <p-skeleton width=\"45%\" height=\"0.875rem\" />\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\n </div>\n </div>\n </div>\n\n <!-- Second section skeleton -->\n <div class=\"flex flex-col gap-4\">\n <p-skeleton width=\"25%\" height=\"1.5rem\" />\n <div class=\"grid grid-cols-12 gap-4\">\n <div class=\"col-span-6 flex flex-col gap-2\">\n <p-skeleton width=\"35%\" height=\"0.875rem\" />\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\n </div>\n <div class=\"col-span-6 flex flex-col gap-2\">\n <p-skeleton width=\"50%\" height=\"0.875rem\" />\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\n </div>\n <div class=\"col-span-12 flex flex-col gap-2\">\n <p-skeleton width=\"30%\" height=\"0.875rem\" />\n <p-skeleton width=\"100%\" height=\"5rem\" />\n </div>\n </div>\n </div>\n </div>\n}\n\n<!-- Loaded State -->\n@if (state.isLoaded() && !state.loading()) {\n <!-- Dynamic Form -->\n
|
|
987
|
+
], providers: [ClientFormStateService], template: "<!-- Client Form Template \u2014 Render only, NO action buttons -->\r\n\r\n<!-- Loading State -->\r\n@if (state.loading()) {\r\n <div class=\"flex flex-col gap-6\">\r\n <!-- Section header skeleton -->\r\n <div class=\"flex flex-col gap-4\">\r\n <p-skeleton width=\"30%\" height=\"1.5rem\" />\r\n <div class=\"grid grid-cols-12 gap-4\">\r\n <div class=\"col-span-6 flex flex-col gap-2\">\r\n <p-skeleton width=\"40%\" height=\"0.875rem\" />\r\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\r\n </div>\r\n <div class=\"col-span-6 flex flex-col gap-2\">\r\n <p-skeleton width=\"40%\" height=\"0.875rem\" />\r\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\r\n </div>\r\n <div class=\"col-span-12 flex flex-col gap-2\">\r\n <p-skeleton width=\"25%\" height=\"0.875rem\" />\r\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\r\n </div>\r\n <div class=\"col-span-6 flex flex-col gap-2\">\r\n <p-skeleton width=\"35%\" height=\"0.875rem\" />\r\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\r\n </div>\r\n <div class=\"col-span-6 flex flex-col gap-2\">\r\n <p-skeleton width=\"45%\" height=\"0.875rem\" />\r\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Second section skeleton -->\r\n <div class=\"flex flex-col gap-4\">\r\n <p-skeleton width=\"25%\" height=\"1.5rem\" />\r\n <div class=\"grid grid-cols-12 gap-4\">\r\n <div class=\"col-span-6 flex flex-col gap-2\">\r\n <p-skeleton width=\"35%\" height=\"0.875rem\" />\r\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\r\n </div>\r\n <div class=\"col-span-6 flex flex-col gap-2\">\r\n <p-skeleton width=\"50%\" height=\"0.875rem\" />\r\n <p-skeleton width=\"100%\" height=\"2.5rem\" />\r\n </div>\r\n <div class=\"col-span-12 flex flex-col gap-2\">\r\n <p-skeleton width=\"30%\" height=\"0.875rem\" />\r\n <p-skeleton width=\"100%\" height=\"5rem\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n}\r\n\r\n<!-- Loaded State -->\r\n@if (state.isLoaded() && !state.loading()) {\r\n <div class=\"flex flex-col gap-4\">\r\n @if (previewEntities().length > 0) {\r\n <mt-entities-preview [entities]=\"previewEntities()\" />\r\n }\r\n\r\n <!-- Dynamic Form -->\r\n @if (state.requiresForm() && editableFormConfig(); as config) {\r\n @if (hasEditableFormSections()) {\r\n <div class=\"flex flex-col gap-4\">\r\n @if (runtimeErrors().length > 0 || runtimeWarnings().length > 0) {\r\n <div class=\"rounded-lg border border-surface-200 p-4 bg-surface-50\">\r\n @if (runtimeErrors().length > 0) {\r\n <div class=\"mb-3\">\r\n <h4 class=\"text-sm font-semibold text-red-600 mb-2\">\r\n Validation Errors\r\n </h4>\r\n <ul class=\"list-disc ps-5 text-sm text-red-600 space-y-1\">\r\n @for (\r\n msg of runtimeErrors();\r\n track msg.ruleId || msg.fieldKey || msg.message\r\n ) {\r\n <li>{{ msg.message }}</li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n\r\n @if (runtimeWarnings().length > 0) {\r\n <div>\r\n <h4 class=\"text-sm font-semibold text-amber-600 mb-2\">\r\n Validation Warnings\r\n </h4>\r\n <ul class=\"list-disc ps-5 text-sm text-amber-700 space-y-1\">\r\n @for (\r\n msg of runtimeWarnings();\r\n track msg.ruleId || msg.fieldKey || msg.message\r\n ) {\r\n <li>{{ msg.message }}</li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (stepsEnabled()) {\r\n <div class=\"flex flex-col gap-4\">\r\n <p-stepper\r\n [value]=\"currentStep()\"\r\n (valueChange)=\"onStepChange($event)\"\r\n >\r\n <p-step-list>\r\n @for (\r\n section of stepSections();\r\n track section.key || $index\r\n ) {\r\n <p-step [value]=\"$index + 1\">\r\n {{ section.label || \"Step \" + ($index + 1) }}\r\n </p-step>\r\n }\r\n </p-step-list>\r\n </p-stepper>\r\n\r\n @if (showInternalStepActions()) {\r\n <div class=\"flex justify-between gap-2\">\r\n <button\r\n type=\"button\"\r\n class=\"px-3 py-2 rounded border border-surface-300 text-sm\"\r\n [disabled]=\"currentStep() === 1\"\r\n (click)=\"goToPreviousStep()\"\r\n >\r\n Previous\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"px-3 py-2 rounded border border-surface-300 text-sm\"\r\n [disabled]=\"currentStep() === stepSections().length\"\r\n (click)=\"goToNextStep()\"\r\n >\r\n Next\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (tabsEnabled()) {\r\n <mt-tabs\r\n [active]=\"currentStep()\"\r\n (activeChange)=\"onStepChange($event)\"\r\n [options]=\"tabOptions()\"\r\n size=\"small\"\r\n fluid\r\n />\r\n }\r\n <mt-dynamic-form\r\n [formConfig]=\"config\"\r\n [formControl]=\"formControl\"\r\n [visibleSectionKeys]=\"visibleSectionKeys()\"\r\n [forcedHiddenFieldKeys]=\"forcedHiddenFieldKeys()\"\r\n [preserveForcedHiddenValues]=\"true\"\r\n (runtimeMessagesChange)=\"onRuntimeMessagesChange($event)\"\r\n />\r\n </div>\r\n }\r\n } @else if (previewEntities().length === 0) {\r\n <div\r\n class=\"flex items-center justify-center p-6 rounded-lg bg-surface-50 border border-surface-200 border-dashed\"\r\n >\r\n <p class=\"text-sm text-muted-color\">\r\n No form required for this operation.\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n}\r\n", styles: [":host{display:block}\n"] }]
|
|
914
988
|
}], ctorParameters: () => [], propDecorators: { moduleKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "moduleKey", required: true }] }], operationKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "operationKey", required: true }] }], moduleId: [{ type: i0.Input, args: [{ isSignal: true, alias: "moduleId", required: false }] }], levelId: [{ type: i0.Input, args: [{ isSignal: true, alias: "levelId", required: false }] }], levelDataId: [{ type: i0.Input, args: [{ isSignal: true, alias: "levelDataId", required: false }] }], moduleDataId: [{ type: i0.Input, args: [{ isSignal: true, alias: "moduleDataId", required: false }] }], requestSchemaId: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestSchemaId", required: false }] }], draftProcessId: [{ type: i0.Input, args: [{ isSignal: true, alias: "draftProcessId", required: false }] }], preview: [{ type: i0.Input, args: [{ isSignal: true, alias: "preview", required: false }] }], returnUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "returnUrl", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], autoLoad: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoLoad", required: false }] }], formMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "formMode", required: false }] }], renderMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderMode", required: false }] }], showInternalStepActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "showInternalStepActions", required: false }] }], lang: [{ type: i0.Input, args: [{ isSignal: true, alias: "lang", required: false }] }], lookups: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookups", required: false }] }], loaded: [{ type: i0.Output, args: ["loaded"] }], submitted: [{ type: i0.Output, args: ["submitted"] }], errored: [{ type: i0.Output, args: ["errored"] }], modeDetected: [{ type: i0.Output, args: ["modeDetected"] }], formSourceDetected: [{ type: i0.Output, args: ["formSourceDetected"] }] } });
|
|
915
989
|
|
|
916
990
|
// ============================================================================
|
|
@@ -931,5 +1005,5 @@ function isFormRequiredInterception(response) {
|
|
|
931
1005
|
* Generated bundle index. Do not edit.
|
|
932
1006
|
*/
|
|
933
1007
|
|
|
934
|
-
export { ClientForm, ClientFormApiService, ClientFormStateService, isFormRequiredInterception, mapFormValueToSubmitValues, mapToDynamicFormConfig, mapValuesToFormValue };
|
|
1008
|
+
export { ClientForm, ClientFormApiService, ClientFormStateService, getPreviewOnlyFieldKeys, isFormRequiredInterception, mapFormValueToSubmitValues, mapPreviewFieldsToEntities, mapToDynamicFormConfig, mapValuesToFormValue };
|
|
935
1009
|
//# sourceMappingURL=masterteam-forms-client-form.mjs.map
|