@masterteam/forms 0.0.63 → 0.0.64
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/assets/i18n/ar.json +8 -8
- package/assets/i18n/en.json +8 -8
- package/fesm2022/masterteam-forms-client-form.mjs +129 -97
- package/fesm2022/masterteam-forms-client-form.mjs.map +1 -1
- package/fesm2022/masterteam-forms-dynamic-field.mjs +8 -8
- package/fesm2022/masterteam-forms-dynamic-field.mjs.map +1 -1
- package/fesm2022/masterteam-forms-dynamic-form.mjs +19 -19
- package/fesm2022/masterteam-forms-dynamic-form.mjs.map +1 -1
- package/fesm2022/masterteam-forms-pipes.mjs +3 -3
- package/package.json +11 -10
- package/types/masterteam-forms-client-form.d.ts +2 -1
|
@@ -44,10 +44,10 @@ class ClientFormApiService {
|
|
|
44
44
|
validate(request) {
|
|
45
45
|
return this.http.post('process-submit/validate', request);
|
|
46
46
|
}
|
|
47
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
48
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.
|
|
47
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ClientFormApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
48
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ClientFormApiService, providedIn: 'root' });
|
|
49
49
|
}
|
|
50
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
50
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ClientFormApiService, decorators: [{
|
|
51
51
|
type: Injectable,
|
|
52
52
|
args: [{ providedIn: 'root' }]
|
|
53
53
|
}] });
|
|
@@ -63,43 +63,43 @@ class ClientFormStateService {
|
|
|
63
63
|
// ============================================================================
|
|
64
64
|
// Core State Signals
|
|
65
65
|
// ============================================================================
|
|
66
|
-
loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
67
|
-
submitting = signal(false, ...(ngDevMode ? [{ debugName: "submitting" }] : []));
|
|
68
|
-
error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
|
|
69
|
-
submitError = signal(null, ...(ngDevMode ? [{ debugName: "submitError" }] : []));
|
|
70
|
-
loadResponse = signal(null, ...(ngDevMode ? [{ debugName: "loadResponse" }] : []));
|
|
71
|
-
submitResponse = signal(null, ...(ngDevMode ? [{ debugName: "submitResponse" }] : []));
|
|
66
|
+
loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
67
|
+
submitting = signal(false, ...(ngDevMode ? [{ debugName: "submitting" }] : /* istanbul ignore next */ []));
|
|
68
|
+
error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
|
|
69
|
+
submitError = signal(null, ...(ngDevMode ? [{ debugName: "submitError" }] : /* istanbul ignore next */ []));
|
|
70
|
+
loadResponse = signal(null, ...(ngDevMode ? [{ debugName: "loadResponse" }] : /* istanbul ignore next */ []));
|
|
71
|
+
submitResponse = signal(null, ...(ngDevMode ? [{ debugName: "submitResponse" }] : /* istanbul ignore next */ []));
|
|
72
72
|
// ============================================================================
|
|
73
73
|
// Derived Computeds — Load Response
|
|
74
74
|
// ============================================================================
|
|
75
|
-
isLoaded = computed(() => !!this.loadResponse(), ...(ngDevMode ? [{ debugName: "isLoaded" }] : []));
|
|
76
|
-
mode = computed(() => this.loadResponse()?.mode ?? null, ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
77
|
-
isApproval = computed(() => this.mode() === 'Approval', ...(ngDevMode ? [{ debugName: "isApproval" }] : []));
|
|
78
|
-
isDirect = computed(() => this.mode() === 'Direct', ...(ngDevMode ? [{ debugName: "isDirect" }] : []));
|
|
79
|
-
formSource = computed(() => this.loadResponse()?.formSource ?? null, ...(ngDevMode ? [{ debugName: "formSource" }] : []));
|
|
80
|
-
requiresForm = computed(() => this.loadResponse()?.requiresForm ?? false, ...(ngDevMode ? [{ debugName: "requiresForm" }] : []));
|
|
81
|
-
formConfiguration = computed(() => this.loadResponse()?.formConfiguration ?? null, ...(ngDevMode ? [{ debugName: "formConfiguration" }] : []));
|
|
82
|
-
values = computed(() => this.loadResponse()?.values ?? [], ...(ngDevMode ? [{ debugName: "values" }] : []));
|
|
83
|
-
context = computed(() => this.loadResponse()?.context ?? null, ...(ngDevMode ? [{ debugName: "context" }] : []));
|
|
84
|
-
stepName = computed(() => this.loadResponse()?.stepName ?? null, ...(ngDevMode ? [{ debugName: "stepName" }] : []));
|
|
85
|
-
requestSchemaId = computed(() => this.loadResponse()?.requestSchemaId ?? null, ...(ngDevMode ? [{ debugName: "requestSchemaId" }] : []));
|
|
86
|
-
requestId = computed(() => this.loadResponse()?.requestId ?? null, ...(ngDevMode ? [{ debugName: "requestId" }] : []));
|
|
87
|
-
stepId = computed(() => this.loadResponse()?.stepId ?? null, ...(ngDevMode ? [{ debugName: "stepId" }] : []));
|
|
88
|
-
stepSchemaId = computed(() => this.loadResponse()?.stepSchemaId ?? null, ...(ngDevMode ? [{ debugName: "stepSchemaId" }] : []));
|
|
75
|
+
isLoaded = computed(() => !!this.loadResponse(), ...(ngDevMode ? [{ debugName: "isLoaded" }] : /* istanbul ignore next */ []));
|
|
76
|
+
mode = computed(() => this.loadResponse()?.mode ?? null, ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
|
|
77
|
+
isApproval = computed(() => this.mode() === 'Approval', ...(ngDevMode ? [{ debugName: "isApproval" }] : /* istanbul ignore next */ []));
|
|
78
|
+
isDirect = computed(() => this.mode() === 'Direct', ...(ngDevMode ? [{ debugName: "isDirect" }] : /* istanbul ignore next */ []));
|
|
79
|
+
formSource = computed(() => this.loadResponse()?.formSource ?? null, ...(ngDevMode ? [{ debugName: "formSource" }] : /* istanbul ignore next */ []));
|
|
80
|
+
requiresForm = computed(() => this.loadResponse()?.requiresForm ?? false, ...(ngDevMode ? [{ debugName: "requiresForm" }] : /* istanbul ignore next */ []));
|
|
81
|
+
formConfiguration = computed(() => this.loadResponse()?.formConfiguration ?? null, ...(ngDevMode ? [{ debugName: "formConfiguration" }] : /* istanbul ignore next */ []));
|
|
82
|
+
values = computed(() => this.loadResponse()?.values ?? [], ...(ngDevMode ? [{ debugName: "values" }] : /* istanbul ignore next */ []));
|
|
83
|
+
context = computed(() => this.loadResponse()?.context ?? null, ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
|
|
84
|
+
stepName = computed(() => this.loadResponse()?.stepName ?? null, ...(ngDevMode ? [{ debugName: "stepName" }] : /* istanbul ignore next */ []));
|
|
85
|
+
requestSchemaId = computed(() => this.loadResponse()?.requestSchemaId ?? null, ...(ngDevMode ? [{ debugName: "requestSchemaId" }] : /* istanbul ignore next */ []));
|
|
86
|
+
requestId = computed(() => this.loadResponse()?.requestId ?? null, ...(ngDevMode ? [{ debugName: "requestId" }] : /* istanbul ignore next */ []));
|
|
87
|
+
stepId = computed(() => this.loadResponse()?.stepId ?? null, ...(ngDevMode ? [{ debugName: "stepId" }] : /* istanbul ignore next */ []));
|
|
88
|
+
stepSchemaId = computed(() => this.loadResponse()?.stepSchemaId ?? null, ...(ngDevMode ? [{ debugName: "stepSchemaId" }] : /* istanbul ignore next */ []));
|
|
89
89
|
// ============================================================================
|
|
90
90
|
// Derived Computeds — Value Categories
|
|
91
91
|
// ============================================================================
|
|
92
92
|
/** Process virtual fields (Request_Date, Step_Name, etc.) — read-only display */
|
|
93
|
-
virtualFields = computed(() => this.values().filter((v) => v.metadata?.source === 'ProcessVirtual'), ...(ngDevMode ? [{ debugName: "virtualFields" }] : []));
|
|
93
|
+
virtualFields = computed(() => this.values().filter((v) => v.metadata?.source === 'ProcessVirtual'), ...(ngDevMode ? [{ debugName: "virtualFields" }] : /* istanbul ignore next */ []));
|
|
94
94
|
/** Editable form values (non-virtual) */
|
|
95
|
-
formValues = computed(() => this.values().filter((v) => v.metadata?.source !== 'ProcessVirtual'), ...(ngDevMode ? [{ debugName: "formValues" }] : []));
|
|
95
|
+
formValues = computed(() => this.values().filter((v) => v.metadata?.source !== 'ProcessVirtual'), ...(ngDevMode ? [{ debugName: "formValues" }] : /* istanbul ignore next */ []));
|
|
96
96
|
// ============================================================================
|
|
97
97
|
// Derived Computeds — Submit Response
|
|
98
98
|
// ============================================================================
|
|
99
|
-
isSubmitted = computed(() => !!this.submitResponse(), ...(ngDevMode ? [{ debugName: "isSubmitted" }] : []));
|
|
100
|
-
submitStatus = computed(() => this.submitResponse()?.status ?? null, ...(ngDevMode ? [{ debugName: "submitStatus" }] : []));
|
|
101
|
-
isPendingApproval = computed(() => this.submitStatus() === 'PendingApproval', ...(ngDevMode ? [{ debugName: "isPendingApproval" }] : []));
|
|
102
|
-
isExecuted = computed(() => this.submitStatus() === 'Executed', ...(ngDevMode ? [{ debugName: "isExecuted" }] : []));
|
|
99
|
+
isSubmitted = computed(() => !!this.submitResponse(), ...(ngDevMode ? [{ debugName: "isSubmitted" }] : /* istanbul ignore next */ []));
|
|
100
|
+
submitStatus = computed(() => this.submitResponse()?.status ?? null, ...(ngDevMode ? [{ debugName: "submitStatus" }] : /* istanbul ignore next */ []));
|
|
101
|
+
isPendingApproval = computed(() => this.submitStatus() === 'PendingApproval', ...(ngDevMode ? [{ debugName: "isPendingApproval" }] : /* istanbul ignore next */ []));
|
|
102
|
+
isExecuted = computed(() => this.submitStatus() === 'Executed', ...(ngDevMode ? [{ debugName: "isExecuted" }] : /* istanbul ignore next */ []));
|
|
103
103
|
// ============================================================================
|
|
104
104
|
// State Mutations
|
|
105
105
|
// ============================================================================
|
|
@@ -127,10 +127,10 @@ class ClientFormStateService {
|
|
|
127
127
|
this.loadResponse.set(null);
|
|
128
128
|
this.submitResponse.set(null);
|
|
129
129
|
}
|
|
130
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
131
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.
|
|
130
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ClientFormStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
131
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ClientFormStateService });
|
|
132
132
|
}
|
|
133
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
133
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ClientFormStateService, decorators: [{
|
|
134
134
|
type: Injectable
|
|
135
135
|
}] });
|
|
136
136
|
|
|
@@ -374,8 +374,13 @@ function mapFieldToConfig(field, lang, lookups, context, readonly = false) {
|
|
|
374
374
|
case 'Checkbox':
|
|
375
375
|
return new ToggleFieldConfig(base);
|
|
376
376
|
// ── File ──────────────────────────────────────────────────
|
|
377
|
-
case 'Attachment':
|
|
378
|
-
|
|
377
|
+
case 'Attachment': {
|
|
378
|
+
const isMultiple = prop?.configuration?.['IsMulitple'] ?? false;
|
|
379
|
+
return new UploadFileFieldConfig({
|
|
380
|
+
...base,
|
|
381
|
+
multiple: isMultiple,
|
|
382
|
+
});
|
|
383
|
+
}
|
|
379
384
|
// ── User Search ───────────────────────────────────────────
|
|
380
385
|
case 'User':
|
|
381
386
|
return new UserSearchFieldConfig({
|
|
@@ -385,6 +390,15 @@ function mapFieldToConfig(field, lang, lookups, context, readonly = false) {
|
|
|
385
390
|
useBaseUrl: false,
|
|
386
391
|
}),
|
|
387
392
|
});
|
|
393
|
+
case 'MultiUser':
|
|
394
|
+
return new UserSearchFieldConfig({
|
|
395
|
+
...base,
|
|
396
|
+
apiUrl: 'Identity/users',
|
|
397
|
+
isMultiple: true,
|
|
398
|
+
context: new HttpContext().set(REQUEST_CONTEXT, {
|
|
399
|
+
useBaseUrl: false,
|
|
400
|
+
}),
|
|
401
|
+
});
|
|
388
402
|
// ── Lookup (single select) ────────────────────────────────
|
|
389
403
|
case 'Lookup': {
|
|
390
404
|
const items = resolveLookupOptions(prop, lookups);
|
|
@@ -570,6 +584,19 @@ function normalizeSubmitValue(value, viewType) {
|
|
|
570
584
|
return value['id'] ?? value;
|
|
571
585
|
}
|
|
572
586
|
return value;
|
|
587
|
+
case 'MultiUser':
|
|
588
|
+
if (Array.isArray(value)) {
|
|
589
|
+
return value.map((v) => v && typeof v === 'object' ? (v['id'] ?? v) : v);
|
|
590
|
+
}
|
|
591
|
+
return value;
|
|
592
|
+
case 'Attachment':
|
|
593
|
+
if (Array.isArray(value)) {
|
|
594
|
+
return value.map((v) => v && typeof v === 'object' ? (v['id'] ?? v) : v);
|
|
595
|
+
}
|
|
596
|
+
if (value && typeof value === 'object') {
|
|
597
|
+
return value['id'] ?? value;
|
|
598
|
+
}
|
|
599
|
+
return value;
|
|
573
600
|
default:
|
|
574
601
|
return value;
|
|
575
602
|
}
|
|
@@ -710,61 +737,62 @@ function stripTemplatePrefix(value) {
|
|
|
710
737
|
class ClientForm {
|
|
711
738
|
api = inject(ClientFormApiService);
|
|
712
739
|
state = inject(ClientFormStateService);
|
|
713
|
-
validationSummary = viewChild('validationSummary', ...(ngDevMode ? [{ debugName: "validationSummary" }] : []));
|
|
740
|
+
validationSummary = viewChild('validationSummary', ...(ngDevMode ? [{ debugName: "validationSummary" }] : /* istanbul ignore next */ []));
|
|
714
741
|
loadSub;
|
|
715
742
|
submitSub;
|
|
716
743
|
formValueSub;
|
|
717
|
-
hasStartedLoad = signal(false, ...(ngDevMode ? [{ debugName: "hasStartedLoad" }] : []));
|
|
718
|
-
formRuntimeMessages = signal([], ...(ngDevMode ? [{ debugName: "formRuntimeMessages" }] : []));
|
|
719
|
-
submitValidationMessages = signal([], ...(ngDevMode ? [{ debugName: "submitValidationMessages" }] : []));
|
|
744
|
+
hasStartedLoad = signal(false, ...(ngDevMode ? [{ debugName: "hasStartedLoad" }] : /* istanbul ignore next */ []));
|
|
745
|
+
formRuntimeMessages = signal([], ...(ngDevMode ? [{ debugName: "formRuntimeMessages" }] : /* istanbul ignore next */ []));
|
|
746
|
+
submitValidationMessages = signal([], ...(ngDevMode ? [{ debugName: "submitValidationMessages" }] : /* istanbul ignore next */ []));
|
|
720
747
|
runtimeMessages = computed(() => [
|
|
721
748
|
...this.formRuntimeMessages(),
|
|
722
749
|
...this.submitValidationMessages(),
|
|
723
|
-
], ...(ngDevMode ? [{ debugName: "runtimeMessages" }] : []));
|
|
750
|
+
], ...(ngDevMode ? [{ debugName: "runtimeMessages" }] : /* istanbul ignore next */ []));
|
|
724
751
|
translocoService = inject(TranslocoService);
|
|
725
752
|
// ============================================================================
|
|
726
753
|
// Public State Signals (for parent access via viewChild)
|
|
727
754
|
// ============================================================================
|
|
728
|
-
submitting = computed(() => this.state.submitting(), ...(ngDevMode ? [{ debugName: "submitting" }] : []));
|
|
729
|
-
submitError = computed(() => this.state.submitError(), ...(ngDevMode ? [{ debugName: "submitError" }] : []));
|
|
730
|
-
isSubmitted = computed(() => this.state.isSubmitted(), ...(ngDevMode ? [{ debugName: "isSubmitted" }] : []));
|
|
731
|
-
isPendingApproval = computed(() => this.state.isPendingApproval(), ...(ngDevMode ? [{ debugName: "isPendingApproval" }] : []));
|
|
732
|
-
isExecuted = computed(() => this.state.isExecuted(), ...(ngDevMode ? [{ debugName: "isExecuted" }] : []));
|
|
733
|
-
isLoaded = computed(() => this.state.isLoaded(), ...(ngDevMode ? [{ debugName: "isLoaded" }] : []));
|
|
734
|
-
loading = computed(() => this.state.loading(), ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
735
|
-
runtimeErrors = computed(() => this.runtimeMessages().filter((msg) => msg.severity === 'error'), ...(ngDevMode ? [{ debugName: "runtimeErrors" }] : []));
|
|
736
|
-
runtimeWarnings = computed(() => this.runtimeMessages().filter((msg) => msg.severity === 'warning'), ...(ngDevMode ? [{ debugName: "runtimeWarnings" }] : []));
|
|
737
|
-
currentStep = signal(1, ...(ngDevMode ? [{ debugName: "currentStep" }] : []));
|
|
755
|
+
submitting = computed(() => this.state.submitting(), ...(ngDevMode ? [{ debugName: "submitting" }] : /* istanbul ignore next */ []));
|
|
756
|
+
submitError = computed(() => this.state.submitError(), ...(ngDevMode ? [{ debugName: "submitError" }] : /* istanbul ignore next */ []));
|
|
757
|
+
isSubmitted = computed(() => this.state.isSubmitted(), ...(ngDevMode ? [{ debugName: "isSubmitted" }] : /* istanbul ignore next */ []));
|
|
758
|
+
isPendingApproval = computed(() => this.state.isPendingApproval(), ...(ngDevMode ? [{ debugName: "isPendingApproval" }] : /* istanbul ignore next */ []));
|
|
759
|
+
isExecuted = computed(() => this.state.isExecuted(), ...(ngDevMode ? [{ debugName: "isExecuted" }] : /* istanbul ignore next */ []));
|
|
760
|
+
isLoaded = computed(() => this.state.isLoaded(), ...(ngDevMode ? [{ debugName: "isLoaded" }] : /* istanbul ignore next */ []));
|
|
761
|
+
loading = computed(() => this.state.loading(), ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
762
|
+
runtimeErrors = computed(() => this.runtimeMessages().filter((msg) => msg.severity === 'error'), ...(ngDevMode ? [{ debugName: "runtimeErrors" }] : /* istanbul ignore next */ []));
|
|
763
|
+
runtimeWarnings = computed(() => this.runtimeMessages().filter((msg) => msg.severity === 'warning'), ...(ngDevMode ? [{ debugName: "runtimeWarnings" }] : /* istanbul ignore next */ []));
|
|
764
|
+
currentStep = signal(1, ...(ngDevMode ? [{ debugName: "currentStep" }] : /* istanbul ignore next */ []));
|
|
738
765
|
// ============================================================================
|
|
739
766
|
// Inputs — Required Context
|
|
740
767
|
// ============================================================================
|
|
741
|
-
moduleKey = input.required(...(ngDevMode ? [{ debugName: "moduleKey" }] : []));
|
|
742
|
-
operationKey = input.required(...(ngDevMode ? [{ debugName: "operationKey" }] : []));
|
|
768
|
+
moduleKey = input.required(...(ngDevMode ? [{ debugName: "moduleKey" }] : /* istanbul ignore next */ []));
|
|
769
|
+
operationKey = input.required(...(ngDevMode ? [{ debugName: "operationKey" }] : /* istanbul ignore next */ []));
|
|
743
770
|
// ============================================================================
|
|
744
771
|
// Inputs — Optional Context
|
|
745
772
|
// ============================================================================
|
|
746
|
-
moduleId = input(...(ngDevMode ? [undefined, { debugName: "moduleId" }] : []));
|
|
747
|
-
levelId = input(...(ngDevMode ? [undefined, { debugName: "levelId" }] : []));
|
|
748
|
-
levelDataId = input(...(ngDevMode ? [undefined, { debugName: "levelDataId" }] : []));
|
|
749
|
-
moduleDataId = input(...(ngDevMode ? [undefined, { debugName: "moduleDataId" }] : []));
|
|
750
|
-
requestSchemaId = input(...(ngDevMode ? [undefined, { debugName: "requestSchemaId" }] : []));
|
|
751
|
-
draftProcessId = input(...(ngDevMode ? [undefined, { debugName: "draftProcessId" }] : []));
|
|
752
|
-
preview = input(false, ...(ngDevMode ? [{ debugName: "preview" }] : []));
|
|
753
|
-
returnUrl = input(...(ngDevMode ? [undefined, { debugName: "returnUrl" }] : []));
|
|
754
|
-
|
|
773
|
+
moduleId = input(...(ngDevMode ? [undefined, { debugName: "moduleId" }] : /* istanbul ignore next */ []));
|
|
774
|
+
levelId = input(...(ngDevMode ? [undefined, { debugName: "levelId" }] : /* istanbul ignore next */ []));
|
|
775
|
+
levelDataId = input(...(ngDevMode ? [undefined, { debugName: "levelDataId" }] : /* istanbul ignore next */ []));
|
|
776
|
+
moduleDataId = input(...(ngDevMode ? [undefined, { debugName: "moduleDataId" }] : /* istanbul ignore next */ []));
|
|
777
|
+
requestSchemaId = input(...(ngDevMode ? [undefined, { debugName: "requestSchemaId" }] : /* istanbul ignore next */ []));
|
|
778
|
+
draftProcessId = input(...(ngDevMode ? [undefined, { debugName: "draftProcessId" }] : /* istanbul ignore next */ []));
|
|
779
|
+
preview = input(false, ...(ngDevMode ? [{ debugName: "preview" }] : /* istanbul ignore next */ []));
|
|
780
|
+
returnUrl = input(...(ngDevMode ? [undefined, { debugName: "returnUrl" }] : /* istanbul ignore next */ []));
|
|
781
|
+
defaultValues = input(null, ...(ngDevMode ? [{ debugName: "defaultValues" }] : /* istanbul ignore next */ []));
|
|
782
|
+
submitRequestMapper = input(null, ...(ngDevMode ? [{ debugName: "submitRequestMapper" }] : /* istanbul ignore next */ []));
|
|
755
783
|
// ============================================================================
|
|
756
784
|
// Inputs — UI Configuration
|
|
757
785
|
// ============================================================================
|
|
758
|
-
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
|
|
759
|
-
autoLoad = input(true, ...(ngDevMode ? [{ debugName: "autoLoad" }] : []));
|
|
760
|
-
formMode = input('create', ...(ngDevMode ? [{ debugName: "formMode" }] : []));
|
|
761
|
-
renderMode = input(...(ngDevMode ? [undefined, { debugName: "renderMode" }] : []));
|
|
786
|
+
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
787
|
+
autoLoad = input(true, ...(ngDevMode ? [{ debugName: "autoLoad" }] : /* istanbul ignore next */ []));
|
|
788
|
+
formMode = input('create', ...(ngDevMode ? [{ debugName: "formMode" }] : /* istanbul ignore next */ []));
|
|
789
|
+
renderMode = input(...(ngDevMode ? [undefined, { debugName: "renderMode" }] : /* istanbul ignore next */ []));
|
|
762
790
|
// Hide the built-in previous/next buttons when step actions are rendered by the parent.
|
|
763
|
-
showInternalStepActions = input(true, ...(ngDevMode ? [{ debugName: "showInternalStepActions" }] : []));
|
|
764
|
-
lang = signal(this.translocoService.getActiveLang(), ...(ngDevMode ? [{ debugName: "lang" }] : []));
|
|
765
|
-
lookups = input([], ...(ngDevMode ? [{ debugName: "lookups" }] : []));
|
|
766
|
-
ignoredFieldKeys = input([], ...(ngDevMode ? [{ debugName: "ignoredFieldKeys" }] : []));
|
|
767
|
-
rtl = computed(() => this.lang() === 'ar', ...(ngDevMode ? [{ debugName: "rtl" }] : []));
|
|
791
|
+
showInternalStepActions = input(true, ...(ngDevMode ? [{ debugName: "showInternalStepActions" }] : /* istanbul ignore next */ []));
|
|
792
|
+
lang = signal(this.translocoService.getActiveLang(), ...(ngDevMode ? [{ debugName: "lang" }] : /* istanbul ignore next */ []));
|
|
793
|
+
lookups = input([], ...(ngDevMode ? [{ debugName: "lookups" }] : /* istanbul ignore next */ []));
|
|
794
|
+
ignoredFieldKeys = input([], ...(ngDevMode ? [{ debugName: "ignoredFieldKeys" }] : /* istanbul ignore next */ []));
|
|
795
|
+
rtl = computed(() => this.lang() === 'ar', ...(ngDevMode ? [{ debugName: "rtl" }] : /* istanbul ignore next */ []));
|
|
768
796
|
// ============================================================================
|
|
769
797
|
// Outputs
|
|
770
798
|
// ============================================================================
|
|
@@ -786,12 +814,16 @@ class ClientForm {
|
|
|
786
814
|
if (!config)
|
|
787
815
|
return null;
|
|
788
816
|
return mapToDynamicFormConfig(config, this.lang(), this.formMode(), this.lookups(), this.state.context(), this.readonly());
|
|
789
|
-
}, ...(ngDevMode ? [{ debugName: "formConfig" }] : []));
|
|
817
|
+
}, ...(ngDevMode ? [{ debugName: "formConfig" }] : /* istanbul ignore next */ []));
|
|
790
818
|
initialValues = computed(() => {
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
819
|
+
const mappedValues = mapValuesToFormValue(this.state.formValues(), this.state.formConfiguration());
|
|
820
|
+
return {
|
|
821
|
+
...(this.defaultValues() ?? {}),
|
|
822
|
+
...mappedValues,
|
|
823
|
+
};
|
|
824
|
+
}, ...(ngDevMode ? [{ debugName: "initialValues" }] : /* istanbul ignore next */ []));
|
|
825
|
+
virtualFields = computed(() => this.state.virtualFields(), ...(ngDevMode ? [{ debugName: "virtualFields" }] : /* istanbul ignore next */ []));
|
|
826
|
+
hasVirtualFields = computed(() => this.virtualFields().length > 0, ...(ngDevMode ? [{ debugName: "hasVirtualFields" }] : /* istanbul ignore next */ []));
|
|
795
827
|
previewFieldKeys = computed(() => {
|
|
796
828
|
const config = this.state.formConfiguration();
|
|
797
829
|
if (!config)
|
|
@@ -802,7 +834,7 @@ class ClientForm {
|
|
|
802
834
|
...this.ignoredFieldKeys(),
|
|
803
835
|
]),
|
|
804
836
|
];
|
|
805
|
-
}, ...(ngDevMode ? [{ debugName: "previewFieldKeys" }] : []));
|
|
837
|
+
}, ...(ngDevMode ? [{ debugName: "previewFieldKeys" }] : /* istanbul ignore next */ []));
|
|
806
838
|
previewEntitySections = computed(() => {
|
|
807
839
|
const config = this.state.formConfiguration();
|
|
808
840
|
if (!config)
|
|
@@ -814,7 +846,7 @@ class ClientForm {
|
|
|
814
846
|
entities: section.entities.filter((entity) => !entity.key || !ignoredFieldKeys.has(entity.key)),
|
|
815
847
|
}))
|
|
816
848
|
.filter((section) => section.entities.length > 0);
|
|
817
|
-
}, ...(ngDevMode ? [{ debugName: "previewEntitySections" }] : []));
|
|
849
|
+
}, ...(ngDevMode ? [{ debugName: "previewEntitySections" }] : /* istanbul ignore next */ []));
|
|
818
850
|
editableFormConfig = computed(() => {
|
|
819
851
|
if (this.readonly()) {
|
|
820
852
|
return null;
|
|
@@ -832,9 +864,9 @@ class ClientForm {
|
|
|
832
864
|
}))
|
|
833
865
|
.filter((section) => section.fields.some((field) => field.type !== 'spacer')),
|
|
834
866
|
};
|
|
835
|
-
}, ...(ngDevMode ? [{ debugName: "editableFormConfig" }] : []));
|
|
836
|
-
stepSections = computed(() => this.editableFormConfig()?.sections ?? [], ...(ngDevMode ? [{ debugName: "stepSections" }] : []));
|
|
837
|
-
hasEditableFormSections = computed(() => this.stepSections().length > 0, ...(ngDevMode ? [{ debugName: "hasEditableFormSections" }] : []));
|
|
867
|
+
}, ...(ngDevMode ? [{ debugName: "editableFormConfig" }] : /* istanbul ignore next */ []));
|
|
868
|
+
stepSections = computed(() => this.editableFormConfig()?.sections ?? [], ...(ngDevMode ? [{ debugName: "stepSections" }] : /* istanbul ignore next */ []));
|
|
869
|
+
hasEditableFormSections = computed(() => this.stepSections().length > 0, ...(ngDevMode ? [{ debugName: "hasEditableFormSections" }] : /* istanbul ignore next */ []));
|
|
838
870
|
effectiveRenderMode = computed(() => {
|
|
839
871
|
const explicitRenderMode = this.renderMode();
|
|
840
872
|
if (explicitRenderMode)
|
|
@@ -846,10 +878,10 @@ class ClientForm {
|
|
|
846
878
|
return configRenderMode;
|
|
847
879
|
}
|
|
848
880
|
return 'form';
|
|
849
|
-
}, ...(ngDevMode ? [{ debugName: "effectiveRenderMode" }] : []));
|
|
850
|
-
stepsEnabled = computed(() => this.effectiveRenderMode() === 'steps' && this.stepSections().length > 1, ...(ngDevMode ? [{ debugName: "stepsEnabled" }] : []));
|
|
851
|
-
tabsEnabled = computed(() => this.effectiveRenderMode() === 'tabs' && this.stepSections().length > 1, ...(ngDevMode ? [{ debugName: "tabsEnabled" }] : []));
|
|
852
|
-
wizardEnabled = computed(() => this.effectiveRenderMode() === 'wizard' && this.stepSections().length > 1, ...(ngDevMode ? [{ debugName: "wizardEnabled" }] : []));
|
|
881
|
+
}, ...(ngDevMode ? [{ debugName: "effectiveRenderMode" }] : /* istanbul ignore next */ []));
|
|
882
|
+
stepsEnabled = computed(() => this.effectiveRenderMode() === 'steps' && this.stepSections().length > 1, ...(ngDevMode ? [{ debugName: "stepsEnabled" }] : /* istanbul ignore next */ []));
|
|
883
|
+
tabsEnabled = computed(() => this.effectiveRenderMode() === 'tabs' && this.stepSections().length > 1, ...(ngDevMode ? [{ debugName: "tabsEnabled" }] : /* istanbul ignore next */ []));
|
|
884
|
+
wizardEnabled = computed(() => this.effectiveRenderMode() === 'wizard' && this.stepSections().length > 1, ...(ngDevMode ? [{ debugName: "wizardEnabled" }] : /* istanbul ignore next */ []));
|
|
853
885
|
wizardFormConfig = computed(() => {
|
|
854
886
|
const config = this.editableFormConfig();
|
|
855
887
|
if (!config)
|
|
@@ -858,12 +890,12 @@ class ClientForm {
|
|
|
858
890
|
...config,
|
|
859
891
|
sections: config.sections.map((s) => ({ ...s, label: undefined })),
|
|
860
892
|
};
|
|
861
|
-
}, ...(ngDevMode ? [{ debugName: "wizardFormConfig" }] : []));
|
|
862
|
-
sectionNavigationEnabled = computed(() => this.stepsEnabled() || this.tabsEnabled() || this.wizardEnabled(), ...(ngDevMode ? [{ debugName: "sectionNavigationEnabled" }] : []));
|
|
893
|
+
}, ...(ngDevMode ? [{ debugName: "wizardFormConfig" }] : /* istanbul ignore next */ []));
|
|
894
|
+
sectionNavigationEnabled = computed(() => this.stepsEnabled() || this.tabsEnabled() || this.wizardEnabled(), ...(ngDevMode ? [{ debugName: "sectionNavigationEnabled" }] : /* istanbul ignore next */ []));
|
|
863
895
|
tabOptions = computed(() => this.stepSections().map((section, index) => ({
|
|
864
896
|
label: section.label || `Tab ${index + 1}`,
|
|
865
897
|
value: index + 1,
|
|
866
|
-
})), ...(ngDevMode ? [{ debugName: "tabOptions" }] : []));
|
|
898
|
+
})), ...(ngDevMode ? [{ debugName: "tabOptions" }] : /* istanbul ignore next */ []));
|
|
867
899
|
stepTimeline = computed(() => {
|
|
868
900
|
const sections = this.stepSections();
|
|
869
901
|
const currentStep = this.currentStep();
|
|
@@ -880,7 +912,7 @@ class ClientForm {
|
|
|
880
912
|
afterLineActive: index < sections.length - 1 && value < currentStep,
|
|
881
913
|
};
|
|
882
914
|
});
|
|
883
|
-
}, ...(ngDevMode ? [{ debugName: "stepTimeline" }] : []));
|
|
915
|
+
}, ...(ngDevMode ? [{ debugName: "stepTimeline" }] : /* istanbul ignore next */ []));
|
|
884
916
|
visibleSectionKeys = computed(() => {
|
|
885
917
|
if (!this.sectionNavigationEnabled())
|
|
886
918
|
return null;
|
|
@@ -889,7 +921,7 @@ class ClientForm {
|
|
|
889
921
|
if (!activeSection)
|
|
890
922
|
return null;
|
|
891
923
|
return [activeSection.key || `section-${currentIndex}`];
|
|
892
|
-
}, ...(ngDevMode ? [{ debugName: "visibleSectionKeys" }] : []));
|
|
924
|
+
}, ...(ngDevMode ? [{ debugName: "visibleSectionKeys" }] : /* istanbul ignore next */ []));
|
|
893
925
|
forcedHiddenFieldKeys = computed(() => {
|
|
894
926
|
if (!this.sectionNavigationEnabled())
|
|
895
927
|
return [];
|
|
@@ -905,19 +937,19 @@ class ClientForm {
|
|
|
905
937
|
.forEach((key) => hiddenFieldKeys.add(key));
|
|
906
938
|
});
|
|
907
939
|
return [...hiddenFieldKeys];
|
|
908
|
-
}, ...(ngDevMode ? [{ debugName: "forcedHiddenFieldKeys" }] : []));
|
|
940
|
+
}, ...(ngDevMode ? [{ debugName: "forcedHiddenFieldKeys" }] : /* istanbul ignore next */ []));
|
|
909
941
|
effectiveForcedHiddenFieldKeys = computed(() => {
|
|
910
942
|
return [
|
|
911
943
|
...new Set([...this.forcedHiddenFieldKeys(), ...this.ignoredFieldKeys()]),
|
|
912
944
|
];
|
|
913
|
-
}, ...(ngDevMode ? [{ debugName: "effectiveForcedHiddenFieldKeys" }] : []));
|
|
945
|
+
}, ...(ngDevMode ? [{ debugName: "effectiveForcedHiddenFieldKeys" }] : /* istanbul ignore next */ []));
|
|
914
946
|
footerLoading = computed(() => {
|
|
915
947
|
return (this.state.loading() ||
|
|
916
948
|
(this.autoLoad() &&
|
|
917
949
|
!this.hasStartedLoad() &&
|
|
918
950
|
!this.state.isLoaded() &&
|
|
919
951
|
!this.state.error()));
|
|
920
|
-
}, ...(ngDevMode ? [{ debugName: "footerLoading" }] : []));
|
|
952
|
+
}, ...(ngDevMode ? [{ debugName: "footerLoading" }] : /* istanbul ignore next */ []));
|
|
921
953
|
footerState = computed(() => {
|
|
922
954
|
const loading = this.footerLoading();
|
|
923
955
|
const isLoaded = this.state.isLoaded();
|
|
@@ -947,7 +979,7 @@ class ClientForm {
|
|
|
947
979
|
showNextStep: stepNavigationEnabled && canGoToNextStep,
|
|
948
980
|
showSubmit: isLoaded && !loading && (!stepNavigationEnabled || !canGoToNextStep),
|
|
949
981
|
};
|
|
950
|
-
}, ...(ngDevMode ? [{ debugName: "footerState" }] : []));
|
|
982
|
+
}, ...(ngDevMode ? [{ debugName: "footerState" }] : /* istanbul ignore next */ []));
|
|
951
983
|
// ============================================================================
|
|
952
984
|
// Effects
|
|
953
985
|
// ============================================================================
|
|
@@ -1327,10 +1359,10 @@ class ClientForm {
|
|
|
1327
1359
|
}
|
|
1328
1360
|
return 'upcoming';
|
|
1329
1361
|
}
|
|
1330
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
1331
|
-
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 }, submitRequestMapper: { classPropertyName: "submitRequestMapper", publicName: "submitRequestMapper", 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 }, lookups: { classPropertyName: "lookups", publicName: "lookups", isSignal: true, isRequired: false, transformFunction: null }, ignoredFieldKeys: { classPropertyName: "ignoredFieldKeys", publicName: "ignoredFieldKeys", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { loaded: "loaded", submitted: "submitted", errored: "errored", modeDetected: "modeDetected", formSourceDetected: "formSourceDetected", footerStateChanged: "footerStateChanged" }, providers: [ClientFormStateService], viewQueries: [{ propertyName: "validationSummary", first: true, predicate: ["validationSummary"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Client Form Template - render only; step navigation buttons are optional -->\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\" *transloco=\"let t; prefix: 'clientForm'\">\r\n @if (previewEntitySections().length > 0) {\r\n <div class=\"flex flex-col gap-3\">\r\n @for (section of previewEntitySections(); track section.key) {\r\n <div class=\"flex flex-col gap-3\">\r\n @if (section.label) {\r\n <h3\r\n class=\"text-lg font-semibold text-color border-b-2 border-gray-200 pb-2 mb-3\"\r\n >\r\n {{ section.label }}\r\n </h3>\r\n }\r\n <mt-entities-preview [entities]=\"section.entities\" />\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Dynamic Form -->\r\n @if (state.requiresForm() && editableFormConfig(); as config) {\r\n @if (hasEditableFormSections()) {\r\n @if (wizardEnabled()) {\r\n <!-- Wizard Mode: vertical stepper left + form right -->\r\n <div class=\"flex gap-0 min-h-0\">\r\n <!-- Vertical Stepper -->\r\n <div class=\"w-[30%] shrink-0 flex flex-col py-4 px-6\">\r\n @for (\r\n step of stepTimeline();\r\n track step.key;\r\n let first = $first;\r\n let last = $last\r\n ) {\r\n @if (!first) {\r\n <div\r\n class=\"ms-6 w-0.5 h-5 shrink-0\"\r\n [ngClass]=\"\r\n step.beforeLineActive ? 'bg-primary' : 'bg-surface-300'\r\n \"\r\n ></div>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"flex items-center cursor-pointer gap-3 text-left focus-visible:outline-none\"\r\n [attr.aria-pressed]=\"step.selected\"\r\n [attr.aria-current]=\"step.state === 'current' ? 'step' : null\"\r\n (click)=\"onStepChange(step.value)\"\r\n >\r\n <span\r\n class=\"flex h-12 w-12 shrink-0 items-center justify-center rounded text-base font-semibold transition-all duration-200\"\r\n [class]=\"\r\n step.state === 'current'\r\n ? 'ring-2 ring-primary/20 bg-primary text-white '\r\n : step.state === 'completed'\r\n ? 'text-primary bg-primary-100 '\r\n : step.state === 'upcoming'\r\n ? 'bg-primary-100 text-white'\r\n : ''\r\n \"\r\n >\r\n @if (step.state === \"completed\") {\r\n <mt-icon icon=\"general.check\" class=\"text-xl\" />\r\n } @else {\r\n {{ step.value }}\r\n }\r\n </span>\r\n <span\r\n class=\"text-sm leading-5 truncate transition-colors duration-200\"\r\n [ngClass]=\"{\r\n 'font-semibold text-primary': step.state === 'current',\r\n 'font-medium text-surface-700':\r\n step.state === 'completed',\r\n 'font-medium text-surface-400': step.state === 'upcoming',\r\n }\"\r\n dir=\"auto\"\r\n >\r\n {{ step.label }}\r\n </span>\r\n </button>\r\n @if (!last) {\r\n <div\r\n class=\"ms-6 w-0.5 h-5 shrink-0\"\r\n [ngClass]=\"\r\n step.afterLineActive ? 'bg-primary' : 'bg-surface-300'\r\n \"\r\n ></div>\r\n }\r\n }\r\n </div>\r\n <!-- Form Content + Buttons -->\n <div class=\"flex-1 flex flex-col gap-4 min-w-0 ps-6\">\n @if (runtimeErrors().length > 0 || runtimeWarnings().length > 0) {\n <div #validationSummary class=\"flex flex-col gap-3 scroll-mt-4\">\n @if (runtimeErrors().length > 0) {\n <section class=\"flex flex-col gap-2\">\n <p\n class=\"m-0 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500\"\n >\n {{ t(\"validation-errors\") }}\n </p>\n @for (\n msg of runtimeErrors();\n track msg.ruleId || msg.fieldKey || msg.message\n ) {\n <p-message\n severity=\"error\"\n styleClass=\"w-full\"\n [text]=\"msg.message\"\n />\n }\n </section>\n }\n\n @if (runtimeWarnings().length > 0) {\n <section class=\"flex flex-col gap-2\">\n <p\n class=\"m-0 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500\"\n >\n {{ t(\"validation-warnings\") }}\n </p>\n @for (\n msg of runtimeWarnings();\n track msg.ruleId || msg.fieldKey || msg.message\n ) {\n <p-message\n severity=\"warn\"\n styleClass=\"w-full\"\n [text]=\"msg.message\"\n />\n }\n </section>\n }\n </div>\n }\n <mt-dynamic-form\r\n [formConfig]=\"wizardFormConfig() ?? config\"\r\n [formControl]=\"formControl\"\r\n [visibleSectionKeys]=\"visibleSectionKeys()\"\r\n [forcedHiddenFieldKeys]=\"effectiveForcedHiddenFieldKeys()\"\r\n [preserveForcedHiddenValues]=\"true\"\r\n (runtimeMessagesChange)=\"onRuntimeMessagesChange($event)\"\r\n />\r\n @if (showInternalStepActions()) {\r\n <div class=\"flex justify-end gap-2 pt-4 mt-auto\">\r\n <mt-button\r\n [label]=\"t('previous')\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [disabled]=\"currentStep() === 1\"\r\n (onClick)=\"goToPreviousStep()\"\r\n />\r\n <mt-button\r\n [label]=\"t('next')\"\r\n severity=\"primary\"\r\n variant=\"outlined\"\r\n [disabled]=\"currentStep() === stepSections().length\"\r\n (onClick)=\"goToNextStep()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n } @else {\n <div class=\"flex flex-col gap-4\">\n @if (runtimeErrors().length > 0 || runtimeWarnings().length > 0) {\n <div #validationSummary class=\"flex flex-col gap-3 scroll-mt-4\">\n @if (runtimeErrors().length > 0) {\n <section class=\"flex flex-col gap-2\">\n <p\n class=\"m-0 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500\"\n >\n {{ t(\"validation-errors\") }}\n </p>\n @for (\n msg of runtimeErrors();\n track msg.ruleId || msg.fieldKey || msg.message\n ) {\n <p-message\n severity=\"error\"\n styleClass=\"w-full\"\n [text]=\"msg.message\"\n />\n }\n </section>\n }\n\n @if (runtimeWarnings().length > 0) {\n <section class=\"flex flex-col gap-2\">\n <p\n class=\"m-0 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500\"\n >\n {{ t(\"validation-warnings\") }}\n </p>\n @for (\n msg of runtimeWarnings();\n track msg.ruleId || msg.fieldKey || msg.message\n ) {\n <p-message\n severity=\"warn\"\n styleClass=\"w-full\"\n [text]=\"msg.message\"\n />\n }\n </section>\n }\n </div>\n }\n\r\n @if (stepsEnabled()) {\r\n <div class=\"flex flex-col gap-4\">\r\n <div class=\"overflow-x-auto pb-2\">\r\n <div class=\"flex min-w-[36rem] items-start\">\r\n @for (\r\n step of stepTimeline();\r\n track step.key;\r\n let first = $first;\r\n let last = $last\r\n ) {\r\n <div\r\n class=\"relative flex min-w-[8rem] flex-1 justify-center\"\r\n >\r\n @if (!rtl() && !first) {\r\n <span\r\n class=\"absolute top-5 left-0 right-1/2 h-0.5\"\r\n [ngClass]=\"\r\n step.beforeLineActive\r\n ? 'bg-primary'\r\n : 'bg-surface-300'\r\n \"\r\n ></span>\r\n }\r\n @if (!rtl() && !last) {\r\n <span\r\n class=\"absolute top-5 left-1/2 right-0 h-0.5\"\r\n [ngClass]=\"\r\n step.afterLineActive\r\n ? 'bg-primary'\r\n : 'bg-surface-300'\r\n \"\r\n ></span>\r\n }\r\n @if (rtl() && !last) {\r\n <span\r\n class=\"absolute top-5 left-0 right-1/2 h-0.5\"\r\n [ngClass]=\"\r\n step.afterLineActive\r\n ? 'bg-primary'\r\n : 'bg-surface-300'\r\n \"\r\n ></span>\r\n }\r\n @if (rtl() && !first) {\r\n <span\r\n class=\"absolute top-5 left-1/2 right-0 h-0.5\"\r\n [ngClass]=\"\r\n step.beforeLineActive\r\n ? 'bg-primary'\r\n : 'bg-surface-300'\r\n \"\r\n ></span>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n class=\"relative z-10 flex w-full flex-col items-center gap-3 px-2 text-center focus-visible:outline-none\"\r\n [attr.aria-pressed]=\"step.selected\"\r\n [attr.aria-current]=\"\r\n step.state === 'current' ? 'step' : null\r\n \"\r\n [attr.title]=\"step.label\"\r\n (click)=\"onStepChange(step.value)\"\r\n >\r\n <span\r\n class=\"flex h-10 w-10 cursor-pointer items-center justify-center rounded-full border text-sm font-semibold transition-all duration-200\"\r\n [ngClass]=\"{\r\n 'border-primary bg-primary text-surface-0 ring-4 ring-primary/10':\r\n step.state === 'completed' ||\r\n step.state === 'current',\r\n\r\n 'border-surface-300 bg-white text-surface-500':\r\n step.state === 'upcoming',\r\n }\"\r\n >\r\n {{ step.value }}\r\n </span>\r\n <span\r\n class=\"max-w-[8rem] text-center text-sm leading-5 transition-colors duration-200\"\r\n [ngClass]=\"{\r\n 'font-semibold text-primary':\r\n step.selected || step.state === 'current',\r\n 'font-medium text-surface-700':\r\n step.state === 'completed' && !step.selected,\r\n 'font-medium text-surface-500':\r\n step.state === 'upcoming',\r\n }\"\r\n dir=\"auto\"\r\n >\r\n {{ step.label }}\r\n </span>\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (showInternalStepActions()) {\r\n <div class=\"flex justify-between gap-2\">\r\n <mt-button\r\n [label]=\"t('previous')\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [disabled]=\"currentStep() === 1\"\r\n (onClick)=\"goToPreviousStep()\"\r\n />\r\n <mt-button\r\n [label]=\"t('next')\"\r\n severity=\"primary\"\r\n variant=\"outlined\"\r\n [disabled]=\"currentStep() === stepSections().length\"\r\n (onClick)=\"goToNextStep()\"\r\n />\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]=\"effectiveForcedHiddenFieldKeys()\"\r\n [preserveForcedHiddenValues]=\"true\"\r\n (runtimeMessagesChange)=\"onRuntimeMessagesChange($event)\"\r\n />\r\n </div>\r\n }\r\n }\r\n } @else if (previewEntitySections().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: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: EntitiesPreview, selector: "mt-entities-preview", inputs: ["entities", "attachmentShape"] }, { 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: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant", "motionOptions"], outputs: ["onClose"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }] });
|
|
1362
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ClientForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1363
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", 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 }, defaultValues: { classPropertyName: "defaultValues", publicName: "defaultValues", isSignal: true, isRequired: false, transformFunction: null }, submitRequestMapper: { classPropertyName: "submitRequestMapper", publicName: "submitRequestMapper", 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 }, lookups: { classPropertyName: "lookups", publicName: "lookups", isSignal: true, isRequired: false, transformFunction: null }, ignoredFieldKeys: { classPropertyName: "ignoredFieldKeys", publicName: "ignoredFieldKeys", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { loaded: "loaded", submitted: "submitted", errored: "errored", modeDetected: "modeDetected", formSourceDetected: "formSourceDetected", footerStateChanged: "footerStateChanged" }, providers: [ClientFormStateService], viewQueries: [{ propertyName: "validationSummary", first: true, predicate: ["validationSummary"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Client Form Template - render only; step navigation buttons are optional -->\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\" *transloco=\"let t; prefix: 'clientForm'\">\r\n @if (previewEntitySections().length > 0) {\r\n <div class=\"flex flex-col gap-3\">\r\n @for (section of previewEntitySections(); track section.key) {\r\n <div class=\"flex flex-col gap-3\">\r\n @if (section.label) {\r\n <h3\r\n class=\"text-lg font-semibold text-color border-b-2 border-gray-200 pb-2 mb-3\"\r\n >\r\n {{ section.label }}\r\n </h3>\r\n }\r\n <mt-entities-preview [entities]=\"section.entities\" />\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Dynamic Form -->\r\n @if (state.requiresForm() && editableFormConfig(); as config) {\r\n @if (hasEditableFormSections()) {\r\n @if (wizardEnabled()) {\r\n <!-- Wizard Mode: vertical stepper left + form right -->\r\n <div class=\"flex gap-0 min-h-0\">\r\n <!-- Vertical Stepper -->\r\n <div class=\"w-[30%] shrink-0 flex flex-col py-4 px-6\">\r\n @for (\r\n step of stepTimeline();\r\n track step.key;\r\n let first = $first;\r\n let last = $last\r\n ) {\r\n @if (!first) {\r\n <div\r\n class=\"ms-6 w-0.5 h-5 shrink-0\"\r\n [ngClass]=\"\r\n step.beforeLineActive ? 'bg-primary' : 'bg-surface-300'\r\n \"\r\n ></div>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"flex items-center cursor-pointer gap-3 text-left focus-visible:outline-none\"\r\n [attr.aria-pressed]=\"step.selected\"\r\n [attr.aria-current]=\"step.state === 'current' ? 'step' : null\"\r\n (click)=\"onStepChange(step.value)\"\r\n >\r\n <span\r\n class=\"flex h-12 w-12 shrink-0 items-center justify-center rounded text-base font-semibold transition-all duration-200\"\r\n [class]=\"\r\n step.state === 'current'\r\n ? 'ring-2 ring-primary/20 bg-primary text-white '\r\n : step.state === 'completed'\r\n ? 'text-primary bg-primary-100 '\r\n : step.state === 'upcoming'\r\n ? 'bg-primary-100 text-white'\r\n : ''\r\n \"\r\n >\r\n @if (step.state === \"completed\") {\r\n <mt-icon icon=\"general.check\" class=\"text-xl\" />\r\n } @else {\r\n {{ step.value }}\r\n }\r\n </span>\r\n <span\r\n class=\"text-sm leading-5 truncate transition-colors duration-200\"\r\n [ngClass]=\"{\r\n 'font-semibold text-primary': step.state === 'current',\r\n 'font-medium text-surface-700':\r\n step.state === 'completed',\r\n 'font-medium text-surface-400': step.state === 'upcoming',\r\n }\"\r\n dir=\"auto\"\r\n >\r\n {{ step.label }}\r\n </span>\r\n </button>\r\n @if (!last) {\r\n <div\r\n class=\"ms-6 w-0.5 h-5 shrink-0\"\r\n [ngClass]=\"\r\n step.afterLineActive ? 'bg-primary' : 'bg-surface-300'\r\n \"\r\n ></div>\r\n }\r\n }\r\n </div>\r\n <!-- Form Content + Buttons -->\r\n <div class=\"flex-1 flex flex-col gap-4 min-w-0 ps-6\">\r\n @if (runtimeErrors().length > 0 || runtimeWarnings().length > 0) {\r\n <div #validationSummary class=\"flex flex-col gap-3 scroll-mt-4\">\r\n @if (runtimeErrors().length > 0) {\r\n <section class=\"flex flex-col gap-2\">\r\n <p\r\n class=\"m-0 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500\"\r\n >\r\n {{ t(\"validation-errors\") }}\r\n </p>\r\n @for (\r\n msg of runtimeErrors();\r\n track msg.ruleId || msg.fieldKey || msg.message\r\n ) {\r\n <p-message\r\n severity=\"error\"\r\n styleClass=\"w-full\"\r\n [text]=\"msg.message\"\r\n />\r\n }\r\n </section>\r\n }\r\n\r\n @if (runtimeWarnings().length > 0) {\r\n <section class=\"flex flex-col gap-2\">\r\n <p\r\n class=\"m-0 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500\"\r\n >\r\n {{ t(\"validation-warnings\") }}\r\n </p>\r\n @for (\r\n msg of runtimeWarnings();\r\n track msg.ruleId || msg.fieldKey || msg.message\r\n ) {\r\n <p-message\r\n severity=\"warn\"\r\n styleClass=\"w-full\"\r\n [text]=\"msg.message\"\r\n />\r\n }\r\n </section>\r\n }\r\n </div>\r\n }\r\n <mt-dynamic-form\r\n [formConfig]=\"wizardFormConfig() ?? config\"\r\n [formControl]=\"formControl\"\r\n [visibleSectionKeys]=\"visibleSectionKeys()\"\r\n [forcedHiddenFieldKeys]=\"effectiveForcedHiddenFieldKeys()\"\r\n [preserveForcedHiddenValues]=\"true\"\r\n (runtimeMessagesChange)=\"onRuntimeMessagesChange($event)\"\r\n />\r\n @if (showInternalStepActions()) {\r\n <div class=\"flex justify-end gap-2 pt-4 mt-auto\">\r\n <mt-button\r\n [label]=\"t('previous')\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [disabled]=\"currentStep() === 1\"\r\n (onClick)=\"goToPreviousStep()\"\r\n />\r\n <mt-button\r\n [label]=\"t('next')\"\r\n severity=\"primary\"\r\n variant=\"outlined\"\r\n [disabled]=\"currentStep() === stepSections().length\"\r\n (onClick)=\"goToNextStep()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-4\">\r\n @if (runtimeErrors().length > 0 || runtimeWarnings().length > 0) {\r\n <div #validationSummary class=\"flex flex-col gap-3 scroll-mt-4\">\r\n @if (runtimeErrors().length > 0) {\r\n <section class=\"flex flex-col gap-2\">\r\n <p\r\n class=\"m-0 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500\"\r\n >\r\n {{ t(\"validation-errors\") }}\r\n </p>\r\n @for (\r\n msg of runtimeErrors();\r\n track msg.ruleId || msg.fieldKey || msg.message\r\n ) {\r\n <p-message\r\n severity=\"error\"\r\n styleClass=\"w-full\"\r\n [text]=\"msg.message\"\r\n />\r\n }\r\n </section>\r\n }\r\n\r\n @if (runtimeWarnings().length > 0) {\r\n <section class=\"flex flex-col gap-2\">\r\n <p\r\n class=\"m-0 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500\"\r\n >\r\n {{ t(\"validation-warnings\") }}\r\n </p>\r\n @for (\r\n msg of runtimeWarnings();\r\n track msg.ruleId || msg.fieldKey || msg.message\r\n ) {\r\n <p-message\r\n severity=\"warn\"\r\n styleClass=\"w-full\"\r\n [text]=\"msg.message\"\r\n />\r\n }\r\n </section>\r\n }\r\n </div>\r\n }\r\n\r\n @if (stepsEnabled()) {\r\n <div class=\"flex flex-col gap-4\">\r\n <div class=\"overflow-x-auto pb-2\">\r\n <div class=\"flex min-w-[36rem] items-start\">\r\n @for (\r\n step of stepTimeline();\r\n track step.key;\r\n let first = $first;\r\n let last = $last\r\n ) {\r\n <div\r\n class=\"relative flex min-w-[8rem] flex-1 justify-center\"\r\n >\r\n @if (!rtl() && !first) {\r\n <span\r\n class=\"absolute top-5 left-0 right-1/2 h-0.5\"\r\n [ngClass]=\"\r\n step.beforeLineActive\r\n ? 'bg-primary'\r\n : 'bg-surface-300'\r\n \"\r\n ></span>\r\n }\r\n @if (!rtl() && !last) {\r\n <span\r\n class=\"absolute top-5 left-1/2 right-0 h-0.5\"\r\n [ngClass]=\"\r\n step.afterLineActive\r\n ? 'bg-primary'\r\n : 'bg-surface-300'\r\n \"\r\n ></span>\r\n }\r\n @if (rtl() && !last) {\r\n <span\r\n class=\"absolute top-5 left-0 right-1/2 h-0.5\"\r\n [ngClass]=\"\r\n step.afterLineActive\r\n ? 'bg-primary'\r\n : 'bg-surface-300'\r\n \"\r\n ></span>\r\n }\r\n @if (rtl() && !first) {\r\n <span\r\n class=\"absolute top-5 left-1/2 right-0 h-0.5\"\r\n [ngClass]=\"\r\n step.beforeLineActive\r\n ? 'bg-primary'\r\n : 'bg-surface-300'\r\n \"\r\n ></span>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n class=\"relative z-10 flex w-full flex-col items-center gap-3 px-2 text-center focus-visible:outline-none\"\r\n [attr.aria-pressed]=\"step.selected\"\r\n [attr.aria-current]=\"\r\n step.state === 'current' ? 'step' : null\r\n \"\r\n [attr.title]=\"step.label\"\r\n (click)=\"onStepChange(step.value)\"\r\n >\r\n <span\r\n class=\"flex h-10 w-10 cursor-pointer items-center justify-center rounded-full border text-sm font-semibold transition-all duration-200\"\r\n [ngClass]=\"{\r\n 'border-primary bg-primary text-surface-0 ring-4 ring-primary/10':\r\n step.state === 'completed' ||\r\n step.state === 'current',\r\n\r\n 'border-surface-300 bg-white text-surface-500':\r\n step.state === 'upcoming',\r\n }\"\r\n >\r\n {{ step.value }}\r\n </span>\r\n <span\r\n class=\"max-w-[8rem] text-center text-sm leading-5 transition-colors duration-200\"\r\n [ngClass]=\"{\r\n 'font-semibold text-primary':\r\n step.selected || step.state === 'current',\r\n 'font-medium text-surface-700':\r\n step.state === 'completed' && !step.selected,\r\n 'font-medium text-surface-500':\r\n step.state === 'upcoming',\r\n }\"\r\n dir=\"auto\"\r\n >\r\n {{ step.label }}\r\n </span>\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (showInternalStepActions()) {\r\n <div class=\"flex justify-between gap-2\">\r\n <mt-button\r\n [label]=\"t('previous')\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [disabled]=\"currentStep() === 1\"\r\n (onClick)=\"goToPreviousStep()\"\r\n />\r\n <mt-button\r\n [label]=\"t('next')\"\r\n severity=\"primary\"\r\n variant=\"outlined\"\r\n [disabled]=\"currentStep() === stepSections().length\"\r\n (onClick)=\"goToNextStep()\"\r\n />\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]=\"effectiveForcedHiddenFieldKeys()\"\r\n [preserveForcedHiddenValues]=\"true\"\r\n (runtimeMessagesChange)=\"onRuntimeMessagesChange($event)\"\r\n />\r\n </div>\r\n }\r\n }\r\n } @else if (previewEntitySections().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: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: EntitiesPreview, selector: "mt-entities-preview", inputs: ["entities", "attachmentShape"] }, { 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: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "component", type: Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant", "motionOptions"], outputs: ["onClose"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }] });
|
|
1332
1364
|
}
|
|
1333
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
1365
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ClientForm, decorators: [{
|
|
1334
1366
|
type: Component,
|
|
1335
1367
|
args: [{ selector: 'mt-client-form', standalone: true, imports: [
|
|
1336
1368
|
CommonModule,
|
|
@@ -1343,8 +1375,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
1343
1375
|
Icon,
|
|
1344
1376
|
Message,
|
|
1345
1377
|
TranslocoDirective,
|
|
1346
|
-
], providers: [ClientFormStateService], template: "<!-- Client Form Template - render only; step navigation buttons are optional -->\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\" *transloco=\"let t; prefix: 'clientForm'\">\r\n @if (previewEntitySections().length > 0) {\r\n <div class=\"flex flex-col gap-3\">\r\n @for (section of previewEntitySections(); track section.key) {\r\n <div class=\"flex flex-col gap-3\">\r\n @if (section.label) {\r\n <h3\r\n class=\"text-lg font-semibold text-color border-b-2 border-gray-200 pb-2 mb-3\"\r\n >\r\n {{ section.label }}\r\n </h3>\r\n }\r\n <mt-entities-preview [entities]=\"section.entities\" />\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Dynamic Form -->\r\n @if (state.requiresForm() && editableFormConfig(); as config) {\r\n @if (hasEditableFormSections()) {\r\n @if (wizardEnabled()) {\r\n <!-- Wizard Mode: vertical stepper left + form right -->\r\n <div class=\"flex gap-0 min-h-0\">\r\n <!-- Vertical Stepper -->\r\n <div class=\"w-[30%] shrink-0 flex flex-col py-4 px-6\">\r\n @for (\r\n step of stepTimeline();\r\n track step.key;\r\n let first = $first;\r\n let last = $last\r\n ) {\r\n @if (!first) {\r\n <div\r\n class=\"ms-6 w-0.5 h-5 shrink-0\"\r\n [ngClass]=\"\r\n step.beforeLineActive ? 'bg-primary' : 'bg-surface-300'\r\n \"\r\n ></div>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"flex items-center cursor-pointer gap-3 text-left focus-visible:outline-none\"\r\n [attr.aria-pressed]=\"step.selected\"\r\n [attr.aria-current]=\"step.state === 'current' ? 'step' : null\"\r\n (click)=\"onStepChange(step.value)\"\r\n >\r\n <span\r\n class=\"flex h-12 w-12 shrink-0 items-center justify-center rounded text-base font-semibold transition-all duration-200\"\r\n [class]=\"\r\n step.state === 'current'\r\n ? 'ring-2 ring-primary/20 bg-primary text-white '\r\n : step.state === 'completed'\r\n ? 'text-primary bg-primary-100 '\r\n : step.state === 'upcoming'\r\n ? 'bg-primary-100 text-white'\r\n : ''\r\n \"\r\n >\r\n @if (step.state === \"completed\") {\r\n <mt-icon icon=\"general.check\" class=\"text-xl\" />\r\n } @else {\r\n {{ step.value }}\r\n }\r\n </span>\r\n <span\r\n class=\"text-sm leading-5 truncate transition-colors duration-200\"\r\n [ngClass]=\"{\r\n 'font-semibold text-primary': step.state === 'current',\r\n 'font-medium text-surface-700':\r\n step.state === 'completed',\r\n 'font-medium text-surface-400': step.state === 'upcoming',\r\n }\"\r\n dir=\"auto\"\r\n >\r\n {{ step.label }}\r\n </span>\r\n </button>\r\n @if (!last) {\r\n <div\r\n class=\"ms-6 w-0.5 h-5 shrink-0\"\r\n [ngClass]=\"\r\n step.afterLineActive ? 'bg-primary' : 'bg-surface-300'\r\n \"\r\n ></div>\r\n }\r\n }\r\n </div>\r\n <!-- Form Content + Buttons -->\n <div class=\"flex-1 flex flex-col gap-4 min-w-0 ps-6\">\n @if (runtimeErrors().length > 0 || runtimeWarnings().length > 0) {\n <div #validationSummary class=\"flex flex-col gap-3 scroll-mt-4\">\n @if (runtimeErrors().length > 0) {\n <section class=\"flex flex-col gap-2\">\n <p\n class=\"m-0 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500\"\n >\n {{ t(\"validation-errors\") }}\n </p>\n @for (\n msg of runtimeErrors();\n track msg.ruleId || msg.fieldKey || msg.message\n ) {\n <p-message\n severity=\"error\"\n styleClass=\"w-full\"\n [text]=\"msg.message\"\n />\n }\n </section>\n }\n\n @if (runtimeWarnings().length > 0) {\n <section class=\"flex flex-col gap-2\">\n <p\n class=\"m-0 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500\"\n >\n {{ t(\"validation-warnings\") }}\n </p>\n @for (\n msg of runtimeWarnings();\n track msg.ruleId || msg.fieldKey || msg.message\n ) {\n <p-message\n severity=\"warn\"\n styleClass=\"w-full\"\n [text]=\"msg.message\"\n />\n }\n </section>\n }\n </div>\n }\n <mt-dynamic-form\r\n [formConfig]=\"wizardFormConfig() ?? config\"\r\n [formControl]=\"formControl\"\r\n [visibleSectionKeys]=\"visibleSectionKeys()\"\r\n [forcedHiddenFieldKeys]=\"effectiveForcedHiddenFieldKeys()\"\r\n [preserveForcedHiddenValues]=\"true\"\r\n (runtimeMessagesChange)=\"onRuntimeMessagesChange($event)\"\r\n />\r\n @if (showInternalStepActions()) {\r\n <div class=\"flex justify-end gap-2 pt-4 mt-auto\">\r\n <mt-button\r\n [label]=\"t('previous')\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [disabled]=\"currentStep() === 1\"\r\n (onClick)=\"goToPreviousStep()\"\r\n />\r\n <mt-button\r\n [label]=\"t('next')\"\r\n severity=\"primary\"\r\n variant=\"outlined\"\r\n [disabled]=\"currentStep() === stepSections().length\"\r\n (onClick)=\"goToNextStep()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n } @else {\n <div class=\"flex flex-col gap-4\">\n @if (runtimeErrors().length > 0 || runtimeWarnings().length > 0) {\n <div #validationSummary class=\"flex flex-col gap-3 scroll-mt-4\">\n @if (runtimeErrors().length > 0) {\n <section class=\"flex flex-col gap-2\">\n <p\n class=\"m-0 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500\"\n >\n {{ t(\"validation-errors\") }}\n </p>\n @for (\n msg of runtimeErrors();\n track msg.ruleId || msg.fieldKey || msg.message\n ) {\n <p-message\n severity=\"error\"\n styleClass=\"w-full\"\n [text]=\"msg.message\"\n />\n }\n </section>\n }\n\n @if (runtimeWarnings().length > 0) {\n <section class=\"flex flex-col gap-2\">\n <p\n class=\"m-0 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500\"\n >\n {{ t(\"validation-warnings\") }}\n </p>\n @for (\n msg of runtimeWarnings();\n track msg.ruleId || msg.fieldKey || msg.message\n ) {\n <p-message\n severity=\"warn\"\n styleClass=\"w-full\"\n [text]=\"msg.message\"\n />\n }\n </section>\n }\n </div>\n }\n\r\n @if (stepsEnabled()) {\r\n <div class=\"flex flex-col gap-4\">\r\n <div class=\"overflow-x-auto pb-2\">\r\n <div class=\"flex min-w-[36rem] items-start\">\r\n @for (\r\n step of stepTimeline();\r\n track step.key;\r\n let first = $first;\r\n let last = $last\r\n ) {\r\n <div\r\n class=\"relative flex min-w-[8rem] flex-1 justify-center\"\r\n >\r\n @if (!rtl() && !first) {\r\n <span\r\n class=\"absolute top-5 left-0 right-1/2 h-0.5\"\r\n [ngClass]=\"\r\n step.beforeLineActive\r\n ? 'bg-primary'\r\n : 'bg-surface-300'\r\n \"\r\n ></span>\r\n }\r\n @if (!rtl() && !last) {\r\n <span\r\n class=\"absolute top-5 left-1/2 right-0 h-0.5\"\r\n [ngClass]=\"\r\n step.afterLineActive\r\n ? 'bg-primary'\r\n : 'bg-surface-300'\r\n \"\r\n ></span>\r\n }\r\n @if (rtl() && !last) {\r\n <span\r\n class=\"absolute top-5 left-0 right-1/2 h-0.5\"\r\n [ngClass]=\"\r\n step.afterLineActive\r\n ? 'bg-primary'\r\n : 'bg-surface-300'\r\n \"\r\n ></span>\r\n }\r\n @if (rtl() && !first) {\r\n <span\r\n class=\"absolute top-5 left-1/2 right-0 h-0.5\"\r\n [ngClass]=\"\r\n step.beforeLineActive\r\n ? 'bg-primary'\r\n : 'bg-surface-300'\r\n \"\r\n ></span>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n class=\"relative z-10 flex w-full flex-col items-center gap-3 px-2 text-center focus-visible:outline-none\"\r\n [attr.aria-pressed]=\"step.selected\"\r\n [attr.aria-current]=\"\r\n step.state === 'current' ? 'step' : null\r\n \"\r\n [attr.title]=\"step.label\"\r\n (click)=\"onStepChange(step.value)\"\r\n >\r\n <span\r\n class=\"flex h-10 w-10 cursor-pointer items-center justify-center rounded-full border text-sm font-semibold transition-all duration-200\"\r\n [ngClass]=\"{\r\n 'border-primary bg-primary text-surface-0 ring-4 ring-primary/10':\r\n step.state === 'completed' ||\r\n step.state === 'current',\r\n\r\n 'border-surface-300 bg-white text-surface-500':\r\n step.state === 'upcoming',\r\n }\"\r\n >\r\n {{ step.value }}\r\n </span>\r\n <span\r\n class=\"max-w-[8rem] text-center text-sm leading-5 transition-colors duration-200\"\r\n [ngClass]=\"{\r\n 'font-semibold text-primary':\r\n step.selected || step.state === 'current',\r\n 'font-medium text-surface-700':\r\n step.state === 'completed' && !step.selected,\r\n 'font-medium text-surface-500':\r\n step.state === 'upcoming',\r\n }\"\r\n dir=\"auto\"\r\n >\r\n {{ step.label }}\r\n </span>\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (showInternalStepActions()) {\r\n <div class=\"flex justify-between gap-2\">\r\n <mt-button\r\n [label]=\"t('previous')\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [disabled]=\"currentStep() === 1\"\r\n (onClick)=\"goToPreviousStep()\"\r\n />\r\n <mt-button\r\n [label]=\"t('next')\"\r\n severity=\"primary\"\r\n variant=\"outlined\"\r\n [disabled]=\"currentStep() === stepSections().length\"\r\n (onClick)=\"goToNextStep()\"\r\n />\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]=\"effectiveForcedHiddenFieldKeys()\"\r\n [preserveForcedHiddenValues]=\"true\"\r\n (runtimeMessagesChange)=\"onRuntimeMessagesChange($event)\"\r\n />\r\n </div>\r\n }\r\n }\r\n } @else if (previewEntitySections().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"] }]
|
|
1347
|
-
}], ctorParameters: () => [], propDecorators: { validationSummary: [{ type: i0.ViewChild, args: ['validationSummary', { isSignal: true }] }], 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 }] }], submitRequestMapper: [{ type: i0.Input, args: [{ isSignal: true, alias: "submitRequestMapper", 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 }] }], lookups: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookups", required: false }] }], ignoredFieldKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "ignoredFieldKeys", 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"] }], footerStateChanged: [{ type: i0.Output, args: ["footerStateChanged"] }] } });
|
|
1378
|
+
], providers: [ClientFormStateService], template: "<!-- Client Form Template - render only; step navigation buttons are optional -->\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\" *transloco=\"let t; prefix: 'clientForm'\">\r\n @if (previewEntitySections().length > 0) {\r\n <div class=\"flex flex-col gap-3\">\r\n @for (section of previewEntitySections(); track section.key) {\r\n <div class=\"flex flex-col gap-3\">\r\n @if (section.label) {\r\n <h3\r\n class=\"text-lg font-semibold text-color border-b-2 border-gray-200 pb-2 mb-3\"\r\n >\r\n {{ section.label }}\r\n </h3>\r\n }\r\n <mt-entities-preview [entities]=\"section.entities\" />\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Dynamic Form -->\r\n @if (state.requiresForm() && editableFormConfig(); as config) {\r\n @if (hasEditableFormSections()) {\r\n @if (wizardEnabled()) {\r\n <!-- Wizard Mode: vertical stepper left + form right -->\r\n <div class=\"flex gap-0 min-h-0\">\r\n <!-- Vertical Stepper -->\r\n <div class=\"w-[30%] shrink-0 flex flex-col py-4 px-6\">\r\n @for (\r\n step of stepTimeline();\r\n track step.key;\r\n let first = $first;\r\n let last = $last\r\n ) {\r\n @if (!first) {\r\n <div\r\n class=\"ms-6 w-0.5 h-5 shrink-0\"\r\n [ngClass]=\"\r\n step.beforeLineActive ? 'bg-primary' : 'bg-surface-300'\r\n \"\r\n ></div>\r\n }\r\n <button\r\n type=\"button\"\r\n class=\"flex items-center cursor-pointer gap-3 text-left focus-visible:outline-none\"\r\n [attr.aria-pressed]=\"step.selected\"\r\n [attr.aria-current]=\"step.state === 'current' ? 'step' : null\"\r\n (click)=\"onStepChange(step.value)\"\r\n >\r\n <span\r\n class=\"flex h-12 w-12 shrink-0 items-center justify-center rounded text-base font-semibold transition-all duration-200\"\r\n [class]=\"\r\n step.state === 'current'\r\n ? 'ring-2 ring-primary/20 bg-primary text-white '\r\n : step.state === 'completed'\r\n ? 'text-primary bg-primary-100 '\r\n : step.state === 'upcoming'\r\n ? 'bg-primary-100 text-white'\r\n : ''\r\n \"\r\n >\r\n @if (step.state === \"completed\") {\r\n <mt-icon icon=\"general.check\" class=\"text-xl\" />\r\n } @else {\r\n {{ step.value }}\r\n }\r\n </span>\r\n <span\r\n class=\"text-sm leading-5 truncate transition-colors duration-200\"\r\n [ngClass]=\"{\r\n 'font-semibold text-primary': step.state === 'current',\r\n 'font-medium text-surface-700':\r\n step.state === 'completed',\r\n 'font-medium text-surface-400': step.state === 'upcoming',\r\n }\"\r\n dir=\"auto\"\r\n >\r\n {{ step.label }}\r\n </span>\r\n </button>\r\n @if (!last) {\r\n <div\r\n class=\"ms-6 w-0.5 h-5 shrink-0\"\r\n [ngClass]=\"\r\n step.afterLineActive ? 'bg-primary' : 'bg-surface-300'\r\n \"\r\n ></div>\r\n }\r\n }\r\n </div>\r\n <!-- Form Content + Buttons -->\r\n <div class=\"flex-1 flex flex-col gap-4 min-w-0 ps-6\">\r\n @if (runtimeErrors().length > 0 || runtimeWarnings().length > 0) {\r\n <div #validationSummary class=\"flex flex-col gap-3 scroll-mt-4\">\r\n @if (runtimeErrors().length > 0) {\r\n <section class=\"flex flex-col gap-2\">\r\n <p\r\n class=\"m-0 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500\"\r\n >\r\n {{ t(\"validation-errors\") }}\r\n </p>\r\n @for (\r\n msg of runtimeErrors();\r\n track msg.ruleId || msg.fieldKey || msg.message\r\n ) {\r\n <p-message\r\n severity=\"error\"\r\n styleClass=\"w-full\"\r\n [text]=\"msg.message\"\r\n />\r\n }\r\n </section>\r\n }\r\n\r\n @if (runtimeWarnings().length > 0) {\r\n <section class=\"flex flex-col gap-2\">\r\n <p\r\n class=\"m-0 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500\"\r\n >\r\n {{ t(\"validation-warnings\") }}\r\n </p>\r\n @for (\r\n msg of runtimeWarnings();\r\n track msg.ruleId || msg.fieldKey || msg.message\r\n ) {\r\n <p-message\r\n severity=\"warn\"\r\n styleClass=\"w-full\"\r\n [text]=\"msg.message\"\r\n />\r\n }\r\n </section>\r\n }\r\n </div>\r\n }\r\n <mt-dynamic-form\r\n [formConfig]=\"wizardFormConfig() ?? config\"\r\n [formControl]=\"formControl\"\r\n [visibleSectionKeys]=\"visibleSectionKeys()\"\r\n [forcedHiddenFieldKeys]=\"effectiveForcedHiddenFieldKeys()\"\r\n [preserveForcedHiddenValues]=\"true\"\r\n (runtimeMessagesChange)=\"onRuntimeMessagesChange($event)\"\r\n />\r\n @if (showInternalStepActions()) {\r\n <div class=\"flex justify-end gap-2 pt-4 mt-auto\">\r\n <mt-button\r\n [label]=\"t('previous')\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [disabled]=\"currentStep() === 1\"\r\n (onClick)=\"goToPreviousStep()\"\r\n />\r\n <mt-button\r\n [label]=\"t('next')\"\r\n severity=\"primary\"\r\n variant=\"outlined\"\r\n [disabled]=\"currentStep() === stepSections().length\"\r\n (onClick)=\"goToNextStep()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-4\">\r\n @if (runtimeErrors().length > 0 || runtimeWarnings().length > 0) {\r\n <div #validationSummary class=\"flex flex-col gap-3 scroll-mt-4\">\r\n @if (runtimeErrors().length > 0) {\r\n <section class=\"flex flex-col gap-2\">\r\n <p\r\n class=\"m-0 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500\"\r\n >\r\n {{ t(\"validation-errors\") }}\r\n </p>\r\n @for (\r\n msg of runtimeErrors();\r\n track msg.ruleId || msg.fieldKey || msg.message\r\n ) {\r\n <p-message\r\n severity=\"error\"\r\n styleClass=\"w-full\"\r\n [text]=\"msg.message\"\r\n />\r\n }\r\n </section>\r\n }\r\n\r\n @if (runtimeWarnings().length > 0) {\r\n <section class=\"flex flex-col gap-2\">\r\n <p\r\n class=\"m-0 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500\"\r\n >\r\n {{ t(\"validation-warnings\") }}\r\n </p>\r\n @for (\r\n msg of runtimeWarnings();\r\n track msg.ruleId || msg.fieldKey || msg.message\r\n ) {\r\n <p-message\r\n severity=\"warn\"\r\n styleClass=\"w-full\"\r\n [text]=\"msg.message\"\r\n />\r\n }\r\n </section>\r\n }\r\n </div>\r\n }\r\n\r\n @if (stepsEnabled()) {\r\n <div class=\"flex flex-col gap-4\">\r\n <div class=\"overflow-x-auto pb-2\">\r\n <div class=\"flex min-w-[36rem] items-start\">\r\n @for (\r\n step of stepTimeline();\r\n track step.key;\r\n let first = $first;\r\n let last = $last\r\n ) {\r\n <div\r\n class=\"relative flex min-w-[8rem] flex-1 justify-center\"\r\n >\r\n @if (!rtl() && !first) {\r\n <span\r\n class=\"absolute top-5 left-0 right-1/2 h-0.5\"\r\n [ngClass]=\"\r\n step.beforeLineActive\r\n ? 'bg-primary'\r\n : 'bg-surface-300'\r\n \"\r\n ></span>\r\n }\r\n @if (!rtl() && !last) {\r\n <span\r\n class=\"absolute top-5 left-1/2 right-0 h-0.5\"\r\n [ngClass]=\"\r\n step.afterLineActive\r\n ? 'bg-primary'\r\n : 'bg-surface-300'\r\n \"\r\n ></span>\r\n }\r\n @if (rtl() && !last) {\r\n <span\r\n class=\"absolute top-5 left-0 right-1/2 h-0.5\"\r\n [ngClass]=\"\r\n step.afterLineActive\r\n ? 'bg-primary'\r\n : 'bg-surface-300'\r\n \"\r\n ></span>\r\n }\r\n @if (rtl() && !first) {\r\n <span\r\n class=\"absolute top-5 left-1/2 right-0 h-0.5\"\r\n [ngClass]=\"\r\n step.beforeLineActive\r\n ? 'bg-primary'\r\n : 'bg-surface-300'\r\n \"\r\n ></span>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n class=\"relative z-10 flex w-full flex-col items-center gap-3 px-2 text-center focus-visible:outline-none\"\r\n [attr.aria-pressed]=\"step.selected\"\r\n [attr.aria-current]=\"\r\n step.state === 'current' ? 'step' : null\r\n \"\r\n [attr.title]=\"step.label\"\r\n (click)=\"onStepChange(step.value)\"\r\n >\r\n <span\r\n class=\"flex h-10 w-10 cursor-pointer items-center justify-center rounded-full border text-sm font-semibold transition-all duration-200\"\r\n [ngClass]=\"{\r\n 'border-primary bg-primary text-surface-0 ring-4 ring-primary/10':\r\n step.state === 'completed' ||\r\n step.state === 'current',\r\n\r\n 'border-surface-300 bg-white text-surface-500':\r\n step.state === 'upcoming',\r\n }\"\r\n >\r\n {{ step.value }}\r\n </span>\r\n <span\r\n class=\"max-w-[8rem] text-center text-sm leading-5 transition-colors duration-200\"\r\n [ngClass]=\"{\r\n 'font-semibold text-primary':\r\n step.selected || step.state === 'current',\r\n 'font-medium text-surface-700':\r\n step.state === 'completed' && !step.selected,\r\n 'font-medium text-surface-500':\r\n step.state === 'upcoming',\r\n }\"\r\n dir=\"auto\"\r\n >\r\n {{ step.label }}\r\n </span>\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (showInternalStepActions()) {\r\n <div class=\"flex justify-between gap-2\">\r\n <mt-button\r\n [label]=\"t('previous')\"\r\n severity=\"secondary\"\r\n variant=\"outlined\"\r\n [disabled]=\"currentStep() === 1\"\r\n (onClick)=\"goToPreviousStep()\"\r\n />\r\n <mt-button\r\n [label]=\"t('next')\"\r\n severity=\"primary\"\r\n variant=\"outlined\"\r\n [disabled]=\"currentStep() === stepSections().length\"\r\n (onClick)=\"goToNextStep()\"\r\n />\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]=\"effectiveForcedHiddenFieldKeys()\"\r\n [preserveForcedHiddenValues]=\"true\"\r\n (runtimeMessagesChange)=\"onRuntimeMessagesChange($event)\"\r\n />\r\n </div>\r\n }\r\n }\r\n } @else if (previewEntitySections().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"] }]
|
|
1379
|
+
}], ctorParameters: () => [], propDecorators: { validationSummary: [{ type: i0.ViewChild, args: ['validationSummary', { isSignal: true }] }], 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 }] }], defaultValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValues", required: false }] }], submitRequestMapper: [{ type: i0.Input, args: [{ isSignal: true, alias: "submitRequestMapper", 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 }] }], lookups: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookups", required: false }] }], ignoredFieldKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "ignoredFieldKeys", 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"] }], footerStateChanged: [{ type: i0.Output, args: ["footerStateChanged"] }] } });
|
|
1348
1380
|
|
|
1349
1381
|
// ============================================================================
|
|
1350
1382
|
// API Response Wrapper
|