@masterteam/forms 0.0.38 → 0.0.40
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/assets/forms.css +1 -1
- package/fesm2022/masterteam-forms-client-form.mjs +208 -6
- package/fesm2022/masterteam-forms-client-form.mjs.map +1 -1
- package/fesm2022/masterteam-forms-dynamic-form.mjs +91 -7
- package/fesm2022/masterteam-forms-dynamic-form.mjs.map +1 -1
- package/package.json +2 -2
- package/types/masterteam-forms-client-form.d.ts +27 -2
- package/types/masterteam-forms-dynamic-form.d.ts +11 -2
package/assets/forms.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */
|
|
2
|
-
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-font-weight:initial;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-gray-200:oklch(92.8% .006 264.531);--spacing:.25rem;--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-semibold:600;--radius-lg:.5rem;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.\@container{container-type:inline-size}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.col-span-6{grid-column:span 6/span 6}.col-span-12{grid-column:span 12/span 12}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.flex{display:flex}.grid{display:grid}.hidden{display:none}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.flex-col{flex-direction:column}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing) * 1)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.rounded-lg{border-radius:var(--radius-lg)}.border{border-style:var(--tw-border-style);border-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-gray-200{border-color:var(--color-gray-200)}.border-surface-200{border-color:var(--p-surface-200)}@supports (color:color-mix(in lab, red, red)){.border-surface-200{border-color:color-mix(in srgb, var(--p-surface-200) calc(100% * 1), transparent)}}.bg-surface-50{background-color:var(--p-surface-50)}@supports (color:color-mix(in lab, red, red)){.bg-surface-50{background-color:color-mix(in srgb, var(--p-surface-50) calc(100% * 1), transparent)}}.p-6{padding:calc(var(--spacing) * 6)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-color{color:var(--p-text-color)}.text-muted-color{color:var(--p-text-muted-color)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}}@keyframes enter{0%{opacity:var(--p-enter-opacity,1);transform:translate3d(var(--p-enter-translate-x,0), var(--p-enter-translate-y,0), 0) scale3d(var(--p-enter-scale,1), var(--p-enter-scale,1), var(--p-enter-scale,1)) rotate(var(--p-enter-rotate,0))}}@keyframes leave{to{opacity:var(--p-leave-opacity,1);transform:translate3d(var(--p-leave-translate-x,0), var(--p-leave-translate-y,0), 0) scale3d(var(--p-leave-scale,1), var(--p-leave-scale,1), var(--p-leave-scale,1)) rotate(var(--p-leave-rotate,0))}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-600:oklch(57.7% .245 27.325);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-gray-200:oklch(92.8% .006 264.531);--spacing:.25rem;--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-semibold:600;--radius-lg:.5rem;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.\@container{container-type:inline-size}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.col-span-6{grid-column:span 6/span 6}.col-span-12{grid-column:span 12/span 12}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.flex{display:flex}.grid{display:grid}.hidden{display:none}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.list-disc{list-style-type:disc}.grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.flex-col{flex-direction:column}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing) * 1)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}.rounded{border-radius:.25rem}.rounded-lg{border-radius:var(--radius-lg)}.border{border-style:var(--tw-border-style);border-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-gray-200{border-color:var(--color-gray-200)}.border-surface-200{border-color:var(--p-surface-200)}@supports (color:color-mix(in lab, red, red)){.border-surface-200{border-color:color-mix(in srgb, var(--p-surface-200) calc(100% * 1), transparent)}}.border-surface-300{border-color:var(--p-surface-300)}@supports (color:color-mix(in lab, red, red)){.border-surface-300{border-color:color-mix(in srgb, var(--p-surface-300) calc(100% * 1), transparent)}}.bg-surface-50{background-color:var(--p-surface-50)}@supports (color:color-mix(in lab, red, red)){.bg-surface-50{background-color:color-mix(in srgb, var(--p-surface-50) calc(100% * 1), transparent)}}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.px-3{padding-inline:calc(var(--spacing) * 3)}.py-2{padding-block:calc(var(--spacing) * 2)}.ps-5{padding-inline-start:calc(var(--spacing) * 5)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-amber-600{color:var(--color-amber-600)}.text-amber-700{color:var(--color-amber-700)}.text-color{color:var(--p-text-color)}.text-muted-color{color:var(--p-text-muted-color)}.text-red-600{color:var(--color-red-600)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}}@keyframes enter{0%{opacity:var(--p-enter-opacity,1);transform:translate3d(var(--p-enter-translate-x,0), var(--p-enter-translate-y,0), 0) scale3d(var(--p-enter-scale,1), var(--p-enter-scale,1), var(--p-enter-scale,1)) rotate(var(--p-enter-rotate,0))}}@keyframes leave{to{opacity:var(--p-leave-opacity,1);transform:translate3d(var(--p-leave-translate-x,0), var(--p-leave-translate-y,0), 0) scale3d(var(--p-leave-scale,1), var(--p-leave-scale,1), var(--p-leave-scale,1)) rotate(var(--p-leave-rotate,0))}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}
|
|
@@ -4,6 +4,8 @@ import * as i1 from '@angular/forms';
|
|
|
4
4
|
import { FormControl, ReactiveFormsModule } from '@angular/forms';
|
|
5
5
|
import { CommonModule } from '@angular/common';
|
|
6
6
|
import { Skeleton } from 'primeng/skeleton';
|
|
7
|
+
import * as i2 from 'primeng/stepper';
|
|
8
|
+
import { StepperModule } from 'primeng/stepper';
|
|
7
9
|
import { DynamicForm } from '@masterteam/forms/dynamic-form';
|
|
8
10
|
import { HttpClient, HttpContext } from '@angular/common/http';
|
|
9
11
|
import { ValidatorConfig, TextFieldConfig, SchemaConnectionFieldConfig, SelectFieldConfig, MultiSelectFieldConfig, UserSearchFieldConfig, REQUEST_CONTEXT, UploadFileFieldConfig, ToggleFieldConfig, DateFieldConfig, SliderFieldConfig, NumberFieldConfig, EditorFieldConfig } from '@masterteam/components';
|
|
@@ -146,6 +148,7 @@ const WIDTH_TO_COLSPAN = {
|
|
|
146
148
|
* @param lookups Available lookup definitions for resolving Lookup/LookupMultiSelect options
|
|
147
149
|
*/
|
|
148
150
|
function mapToDynamicFormConfig(config, lang = 'en', mode = 'create', lookups = []) {
|
|
151
|
+
const validationRules = mapValidationRules(config, lang);
|
|
149
152
|
return {
|
|
150
153
|
sections: config.sections
|
|
151
154
|
.slice()
|
|
@@ -172,6 +175,7 @@ function mapToDynamicFormConfig(config, lang = 'en', mode = 'create', lookups =
|
|
|
172
175
|
};
|
|
173
176
|
})
|
|
174
177
|
.filter((section) => section.fields.length > 0),
|
|
178
|
+
validationRules,
|
|
175
179
|
};
|
|
176
180
|
}
|
|
177
181
|
/**
|
|
@@ -201,6 +205,7 @@ function mapFormValueToSubmitValues(formValue, loadResponse) {
|
|
|
201
205
|
if (v.metadata) {
|
|
202
206
|
metadataByKey.set(v.propertyKey, {
|
|
203
207
|
propertyId: v.metadata.propertyId,
|
|
208
|
+
viewType: v.metadata.viewType,
|
|
204
209
|
});
|
|
205
210
|
}
|
|
206
211
|
}
|
|
@@ -208,12 +213,20 @@ function mapFormValueToSubmitValues(formValue, loadResponse) {
|
|
|
208
213
|
.filter(([, value]) => value !== undefined && value !== null)
|
|
209
214
|
.map(([propertyKey, value]) => {
|
|
210
215
|
const meta = metadataByKey.get(propertyKey);
|
|
211
|
-
const
|
|
216
|
+
const normalizedValue = normalizeSubmitValue(value, meta?.viewType);
|
|
217
|
+
if (normalizedValue === undefined || normalizedValue === null) {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
const submitValue = {
|
|
221
|
+
propertyKey,
|
|
222
|
+
value: normalizedValue,
|
|
223
|
+
};
|
|
212
224
|
if (meta?.propertyId) {
|
|
213
225
|
submitValue.requestPropertyId = meta.propertyId;
|
|
214
226
|
}
|
|
215
227
|
return submitValue;
|
|
216
|
-
})
|
|
228
|
+
})
|
|
229
|
+
.filter((value) => !!value);
|
|
217
230
|
}
|
|
218
231
|
// ============================================================================
|
|
219
232
|
// Internal Helpers
|
|
@@ -241,6 +254,7 @@ function mapFieldToConfig(field, lang, lookups) {
|
|
|
241
254
|
validators: field.isRequired
|
|
242
255
|
? [ValidatorConfig.required(`${label} is required`)]
|
|
243
256
|
: [],
|
|
257
|
+
formulaCondition: buildFormulaCondition(field),
|
|
244
258
|
};
|
|
245
259
|
switch (viewType) {
|
|
246
260
|
// ── Text-like ──────────────────────────────────────────────
|
|
@@ -330,6 +344,31 @@ function mapFieldToConfig(field, lang, lookups) {
|
|
|
330
344
|
return new TextFieldConfig(base);
|
|
331
345
|
}
|
|
332
346
|
}
|
|
347
|
+
function buildFormulaCondition(field) {
|
|
348
|
+
if (!field.showConditionalDisplayFormula)
|
|
349
|
+
return undefined;
|
|
350
|
+
const formulaTokens = (field.conditionalDisplayFormula ?? '').trim();
|
|
351
|
+
if (!formulaTokens)
|
|
352
|
+
return undefined;
|
|
353
|
+
return {
|
|
354
|
+
formulaTokens,
|
|
355
|
+
formulaText: field.conditionalDisplayFormula ?? '',
|
|
356
|
+
mode: 'auto',
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
function mapValidationRules(config, lang) {
|
|
360
|
+
return (config.validations ?? []).map((rule) => ({
|
|
361
|
+
id: rule.id,
|
|
362
|
+
formulaTokens: rule.formulaTokens,
|
|
363
|
+
formulaText: rule.formulaText,
|
|
364
|
+
message: rule.message?.[lang] ??
|
|
365
|
+
rule.message?.en ??
|
|
366
|
+
rule.message?.ar ??
|
|
367
|
+
'Validation rule failed',
|
|
368
|
+
severity: rule.severity,
|
|
369
|
+
enabled: rule.enabled,
|
|
370
|
+
}));
|
|
371
|
+
}
|
|
333
372
|
function resolvePropertyName(property, lang) {
|
|
334
373
|
if (!property?.name)
|
|
335
374
|
return '';
|
|
@@ -380,6 +419,35 @@ function extractOptionsFromProperty(property) {
|
|
|
380
419
|
}
|
|
381
420
|
return null;
|
|
382
421
|
}
|
|
422
|
+
function normalizeSubmitValue(value, viewType) {
|
|
423
|
+
if (viewType !== 'User') {
|
|
424
|
+
return value;
|
|
425
|
+
}
|
|
426
|
+
if (Array.isArray(value)) {
|
|
427
|
+
return value
|
|
428
|
+
.map((item) => extractUserId(item))
|
|
429
|
+
.filter((id) => id !== null)
|
|
430
|
+
.map((id) => String(id));
|
|
431
|
+
}
|
|
432
|
+
const userId = extractUserId(value);
|
|
433
|
+
if (userId === null)
|
|
434
|
+
return value;
|
|
435
|
+
return String(userId);
|
|
436
|
+
}
|
|
437
|
+
function extractUserId(value) {
|
|
438
|
+
if (value === null || value === undefined)
|
|
439
|
+
return null;
|
|
440
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
441
|
+
return value;
|
|
442
|
+
}
|
|
443
|
+
if (typeof value !== 'object')
|
|
444
|
+
return null;
|
|
445
|
+
const userId = value['userId'] ?? value['id'] ?? value['value'];
|
|
446
|
+
if (typeof userId === 'string' || typeof userId === 'number') {
|
|
447
|
+
return userId;
|
|
448
|
+
}
|
|
449
|
+
return null;
|
|
450
|
+
}
|
|
383
451
|
|
|
384
452
|
/**
|
|
385
453
|
* Client Form — Runtime process form component.
|
|
@@ -407,6 +475,7 @@ class ClientForm {
|
|
|
407
475
|
state = inject(ClientFormStateService);
|
|
408
476
|
loadSub;
|
|
409
477
|
submitSub;
|
|
478
|
+
runtimeMessages = signal([], ...(ngDevMode ? [{ debugName: "runtimeMessages" }] : []));
|
|
410
479
|
// ============================================================================
|
|
411
480
|
// Public State Signals (for parent access via viewChild)
|
|
412
481
|
// ============================================================================
|
|
@@ -417,6 +486,9 @@ class ClientForm {
|
|
|
417
486
|
isExecuted = computed(() => this.state.isExecuted(), ...(ngDevMode ? [{ debugName: "isExecuted" }] : []));
|
|
418
487
|
isLoaded = computed(() => this.state.isLoaded(), ...(ngDevMode ? [{ debugName: "isLoaded" }] : []));
|
|
419
488
|
loading = computed(() => this.state.loading(), ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
489
|
+
runtimeErrors = computed(() => this.runtimeMessages().filter((msg) => msg.severity === 'error'), ...(ngDevMode ? [{ debugName: "runtimeErrors" }] : []));
|
|
490
|
+
runtimeWarnings = computed(() => this.runtimeMessages().filter((msg) => msg.severity === 'warning'), ...(ngDevMode ? [{ debugName: "runtimeWarnings" }] : []));
|
|
491
|
+
currentStep = signal(1, ...(ngDevMode ? [{ debugName: "currentStep" }] : []));
|
|
420
492
|
// ============================================================================
|
|
421
493
|
// Inputs — Required Context
|
|
422
494
|
// ============================================================================
|
|
@@ -439,6 +511,8 @@ class ClientForm {
|
|
|
439
511
|
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
|
|
440
512
|
autoLoad = input(true, ...(ngDevMode ? [{ debugName: "autoLoad" }] : []));
|
|
441
513
|
formMode = input('create', ...(ngDevMode ? [{ debugName: "formMode" }] : []));
|
|
514
|
+
renderMode = input('form', ...(ngDevMode ? [{ debugName: "renderMode" }] : []));
|
|
515
|
+
showInternalStepActions = input(true, ...(ngDevMode ? [{ debugName: "showInternalStepActions" }] : []));
|
|
442
516
|
lang = input('en', ...(ngDevMode ? [{ debugName: "lang" }] : []));
|
|
443
517
|
lookups = input([], ...(ngDevMode ? [{ debugName: "lookups" }] : []));
|
|
444
518
|
// ============================================================================
|
|
@@ -467,6 +541,21 @@ class ClientForm {
|
|
|
467
541
|
}, ...(ngDevMode ? [{ debugName: "initialValues" }] : []));
|
|
468
542
|
virtualFields = computed(() => this.state.virtualFields(), ...(ngDevMode ? [{ debugName: "virtualFields" }] : []));
|
|
469
543
|
hasVirtualFields = computed(() => this.virtualFields().length > 0, ...(ngDevMode ? [{ debugName: "hasVirtualFields" }] : []));
|
|
544
|
+
stepSections = computed(() => this.formConfig()?.sections ?? [], ...(ngDevMode ? [{ debugName: "stepSections" }] : []));
|
|
545
|
+
stepsEnabled = computed(() => this.renderMode() === 'steps' && this.stepSections().length > 1, ...(ngDevMode ? [{ debugName: "stepsEnabled" }] : []));
|
|
546
|
+
forcedHiddenFieldKeys = computed(() => {
|
|
547
|
+
if (!this.stepsEnabled())
|
|
548
|
+
return [];
|
|
549
|
+
const sections = this.stepSections();
|
|
550
|
+
const currentIndex = this.currentStep() - 1;
|
|
551
|
+
return sections.flatMap((section, index) => {
|
|
552
|
+
if (index === currentIndex)
|
|
553
|
+
return [];
|
|
554
|
+
return section.fields
|
|
555
|
+
.map((field) => field.key)
|
|
556
|
+
.filter((key) => !!key);
|
|
557
|
+
});
|
|
558
|
+
}, ...(ngDevMode ? [{ debugName: "forcedHiddenFieldKeys" }] : []));
|
|
470
559
|
// ============================================================================
|
|
471
560
|
// Effects
|
|
472
561
|
// ============================================================================
|
|
@@ -490,6 +579,18 @@ class ClientForm {
|
|
|
490
579
|
});
|
|
491
580
|
}
|
|
492
581
|
});
|
|
582
|
+
effect(() => {
|
|
583
|
+
const count = this.stepSections().length;
|
|
584
|
+
const current = this.currentStep();
|
|
585
|
+
if (count === 0) {
|
|
586
|
+
if (current !== 1)
|
|
587
|
+
this.currentStep.set(1);
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
if (current < 1 || current > count) {
|
|
591
|
+
this.currentStep.set(1);
|
|
592
|
+
}
|
|
593
|
+
});
|
|
493
594
|
}
|
|
494
595
|
// ============================================================================
|
|
495
596
|
// Public API (accessed via viewChild)
|
|
@@ -502,6 +603,7 @@ class ClientForm {
|
|
|
502
603
|
if (this.state.loading())
|
|
503
604
|
return;
|
|
504
605
|
this.loadSub?.unsubscribe();
|
|
606
|
+
this.runtimeMessages.set([]);
|
|
505
607
|
this.state.loading.set(true);
|
|
506
608
|
this.state.error.set(null);
|
|
507
609
|
this.state.submitResponse.set(null);
|
|
@@ -591,8 +693,39 @@ class ClientForm {
|
|
|
591
693
|
this.loadSub?.unsubscribe();
|
|
592
694
|
this.submitSub?.unsubscribe();
|
|
593
695
|
this.formControl.reset({});
|
|
696
|
+
this.runtimeMessages.set([]);
|
|
594
697
|
this.state.reset();
|
|
595
698
|
}
|
|
699
|
+
onRuntimeMessagesChange(messages) {
|
|
700
|
+
this.runtimeMessages.set(messages ?? []);
|
|
701
|
+
}
|
|
702
|
+
onStepChange(value) {
|
|
703
|
+
const count = this.stepSections().length;
|
|
704
|
+
if (value < 1 || value > count)
|
|
705
|
+
return;
|
|
706
|
+
this.currentStep.set(value);
|
|
707
|
+
}
|
|
708
|
+
goToPreviousStep() {
|
|
709
|
+
this.onStepChange(this.currentStep() - 1);
|
|
710
|
+
}
|
|
711
|
+
goToNextStep() {
|
|
712
|
+
this.onStepChange(this.currentStep() + 1);
|
|
713
|
+
}
|
|
714
|
+
canGoToPreviousStep() {
|
|
715
|
+
return this.stepsEnabled() && this.currentStep() > 1;
|
|
716
|
+
}
|
|
717
|
+
canGoToNextStep() {
|
|
718
|
+
return this.stepsEnabled() && this.currentStep() < this.stepSections().length;
|
|
719
|
+
}
|
|
720
|
+
getCurrentStep() {
|
|
721
|
+
return this.currentStep();
|
|
722
|
+
}
|
|
723
|
+
getStepCount() {
|
|
724
|
+
return this.stepSections().length;
|
|
725
|
+
}
|
|
726
|
+
isStepNavigationEnabled() {
|
|
727
|
+
return this.stepsEnabled();
|
|
728
|
+
}
|
|
596
729
|
// ============================================================================
|
|
597
730
|
// Lifecycle
|
|
598
731
|
// ============================================================================
|
|
@@ -639,7 +772,10 @@ class ClientForm {
|
|
|
639
772
|
? mapFormValueToSubmitValues(formValue, loadResponse)
|
|
640
773
|
: Object.entries(formValue)
|
|
641
774
|
.filter(([, v]) => v !== undefined && v !== null)
|
|
642
|
-
.map(([propertyKey, value]) => ({
|
|
775
|
+
.map(([propertyKey, value]) => ({
|
|
776
|
+
propertyKey,
|
|
777
|
+
value: this.normalizeFallbackSubmitValue(propertyKey, value),
|
|
778
|
+
}));
|
|
643
779
|
const req = {
|
|
644
780
|
moduleKey: context?.moduleKey ?? this.moduleKey(),
|
|
645
781
|
operationKey: context?.operationKey ?? this.operationKey(),
|
|
@@ -668,13 +804,79 @@ class ClientForm {
|
|
|
668
804
|
req.returnUrl = returnUrl;
|
|
669
805
|
return req;
|
|
670
806
|
}
|
|
807
|
+
normalizeFallbackSubmitValue(propertyKey, value) {
|
|
808
|
+
const viewType = this.resolveFieldViewType(propertyKey);
|
|
809
|
+
switch (viewType) {
|
|
810
|
+
case 'User':
|
|
811
|
+
return this.normalizeUserValue(value);
|
|
812
|
+
case 'Lookup':
|
|
813
|
+
return this.normalizeLookupSingleValue(value);
|
|
814
|
+
case 'LookupMultiSelect':
|
|
815
|
+
return this.normalizeLookupMultiValue(value);
|
|
816
|
+
default:
|
|
817
|
+
return value;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
resolveFieldViewType(propertyKey) {
|
|
821
|
+
const config = this.state.formConfiguration();
|
|
822
|
+
if (!config)
|
|
823
|
+
return null;
|
|
824
|
+
for (const section of config.sections ?? []) {
|
|
825
|
+
const field = section.fields?.find((f) => f.propertyKey === propertyKey);
|
|
826
|
+
if (!field)
|
|
827
|
+
continue;
|
|
828
|
+
const property = field.property ?? field.propertyMetadata;
|
|
829
|
+
return property?.viewType ?? null;
|
|
830
|
+
}
|
|
831
|
+
return null;
|
|
832
|
+
}
|
|
833
|
+
normalizeUserValue(value) {
|
|
834
|
+
if (Array.isArray(value)) {
|
|
835
|
+
return value
|
|
836
|
+
.map((item) => this.extractIdFromObject(item))
|
|
837
|
+
.filter((id) => id !== null)
|
|
838
|
+
.map((id) => String(id));
|
|
839
|
+
}
|
|
840
|
+
const id = this.extractIdFromObject(value);
|
|
841
|
+
if (id === null)
|
|
842
|
+
return value;
|
|
843
|
+
return String(id);
|
|
844
|
+
}
|
|
845
|
+
normalizeLookupSingleValue(value) {
|
|
846
|
+
const id = this.extractIdFromObject(value);
|
|
847
|
+
return id === null ? value : id;
|
|
848
|
+
}
|
|
849
|
+
normalizeLookupMultiValue(value) {
|
|
850
|
+
if (!Array.isArray(value))
|
|
851
|
+
return value;
|
|
852
|
+
return value
|
|
853
|
+
.map((item) => this.extractIdFromObject(item))
|
|
854
|
+
.filter((id) => id !== null);
|
|
855
|
+
}
|
|
856
|
+
extractIdFromObject(value) {
|
|
857
|
+
if (value === null || value === undefined)
|
|
858
|
+
return null;
|
|
859
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
860
|
+
return value;
|
|
861
|
+
}
|
|
862
|
+
if (typeof value !== 'object')
|
|
863
|
+
return null;
|
|
864
|
+
const id = value['userId'] ?? value['id'] ?? value['value'];
|
|
865
|
+
return typeof id === 'string' || typeof id === 'number' ? id : null;
|
|
866
|
+
}
|
|
671
867
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ClientForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
672
|
-
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 }, 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 <!-- Dynamic Form -->\r\n @if (state.requiresForm() && formConfig(); as config) {\r\n <mt-dynamic-form
|
|
868
|
+
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 <!-- Dynamic Form -->\r\n @if (state.requiresForm() && formConfig(); as config) {\r\n <div class=\"flex flex-col gap-4\">\r\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) {\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>\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 <mt-dynamic-form\n [formConfig]=\"config\"\n [formControl]=\"formControl\"\n [forcedHiddenFieldKeys]=\"forcedHiddenFieldKeys()\"\n [preserveForcedHiddenValues]=\"true\"\n (runtimeMessagesChange)=\"onRuntimeMessagesChange($event)\"\n />\n </div>\n } @else if (!state.requiresForm()) {\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}\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: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues"], outputs: ["runtimeMessagesChange"] }, { 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"] }] });
|
|
673
869
|
}
|
|
674
870
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ClientForm, decorators: [{
|
|
675
871
|
type: Component,
|
|
676
|
-
args: [{ selector: 'mt-client-form', standalone: true, imports: [
|
|
677
|
-
|
|
872
|
+
args: [{ selector: 'mt-client-form', standalone: true, imports: [
|
|
873
|
+
CommonModule,
|
|
874
|
+
ReactiveFormsModule,
|
|
875
|
+
DynamicForm,
|
|
876
|
+
Skeleton,
|
|
877
|
+
StepperModule,
|
|
878
|
+
], 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 <!-- Dynamic Form -->\r\n @if (state.requiresForm() && formConfig(); as config) {\r\n <div class=\"flex flex-col gap-4\">\r\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) {\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>\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 <mt-dynamic-form\n [formConfig]=\"config\"\n [formControl]=\"formControl\"\n [forcedHiddenFieldKeys]=\"forcedHiddenFieldKeys()\"\n [preserveForcedHiddenValues]=\"true\"\n (runtimeMessagesChange)=\"onRuntimeMessagesChange($event)\"\n />\n </div>\n } @else if (!state.requiresForm()) {\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}\r\n", styles: [":host{display:block}\n"] }]
|
|
879
|
+
}], 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"] }] } });
|
|
678
880
|
|
|
679
881
|
// ============================================================================
|
|
680
882
|
// API Response Wrapper
|