@masterteam/forms 0.0.10 → 0.0.11
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/dynamic-form/index.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ declare class DynamicForm implements OnDestroy, ControlValueAccessor, Validator
|
|
|
7
7
|
private fb;
|
|
8
8
|
readonly formConfig: _angular_core.InputSignal<DynamicFormConfig>;
|
|
9
9
|
form: FormGroup<{}>;
|
|
10
|
+
private formBuilt;
|
|
11
|
+
private initValue;
|
|
10
12
|
private onChange;
|
|
11
13
|
private onTouched;
|
|
12
14
|
private onValidatorChange;
|
|
@@ -20,8 +22,17 @@ declare class DynamicForm implements OnDestroy, ControlValueAccessor, Validator
|
|
|
20
22
|
private buildForm;
|
|
21
23
|
writeValue(value: any): void;
|
|
22
24
|
validate(_control: AbstractControl): ValidationErrors | null;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Calculate default field state based on relations
|
|
27
|
+
* If field has 'show' action → start hidden (opposite)
|
|
28
|
+
* If field has 'enable' action → start disabled (opposite)
|
|
29
|
+
*/
|
|
30
|
+
private getDefaultFieldState;
|
|
31
|
+
/**
|
|
32
|
+
* Evaluate all relations - runs on every form change
|
|
33
|
+
* Simple: if dependency matches → apply action, else apply opposite
|
|
34
|
+
*/
|
|
35
|
+
private evaluateRelations;
|
|
25
36
|
private doesRelationMatch;
|
|
26
37
|
private buildValidators;
|
|
27
38
|
ngOnDestroy(): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, input, signal, computed, effect,
|
|
2
|
+
import { inject, input, signal, computed, effect, untracked, forwardRef, Component } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/forms';
|
|
4
4
|
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule, NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
|
|
5
5
|
import { CommonModule } from '@angular/common';
|
|
@@ -11,6 +11,8 @@ class DynamicForm {
|
|
|
11
11
|
fb = inject(FormBuilder);
|
|
12
12
|
formConfig = input.required(...(ngDevMode ? [{ debugName: "formConfig" }] : []));
|
|
13
13
|
form = new FormGroup({});
|
|
14
|
+
formBuilt = signal(false, ...(ngDevMode ? [{ debugName: "formBuilt" }] : []));
|
|
15
|
+
initValue = signal({}, ...(ngDevMode ? [{ debugName: "initValue" }] : []));
|
|
14
16
|
// ControlValueAccessor implementation
|
|
15
17
|
onChange = (_value) => { };
|
|
16
18
|
onTouched = () => { };
|
|
@@ -30,6 +32,14 @@ class DynamicForm {
|
|
|
30
32
|
// Effect to rebuild form when config changes
|
|
31
33
|
effect(() => {
|
|
32
34
|
this.buildForm();
|
|
35
|
+
this.formBuilt.set(true);
|
|
36
|
+
const initValue = untracked(() => this.initValue());
|
|
37
|
+
if (initValue) {
|
|
38
|
+
this.form.patchValue(initValue, { emitEvent: false });
|
|
39
|
+
this.initValue.set(null);
|
|
40
|
+
this.evaluateRelations();
|
|
41
|
+
this.onChange(this.form.getRawValue());
|
|
42
|
+
}
|
|
33
43
|
});
|
|
34
44
|
}
|
|
35
45
|
registerOnValidatorChange(fn) {
|
|
@@ -50,13 +60,11 @@ class DynamicForm {
|
|
|
50
60
|
this.formConfig().sections.forEach((section) => {
|
|
51
61
|
section.fields.forEach((field) => {
|
|
52
62
|
if (field.key) {
|
|
53
|
-
|
|
54
|
-
const
|
|
63
|
+
// Calculate default state from relations
|
|
64
|
+
const defaultState = this.getDefaultFieldState(field);
|
|
55
65
|
fieldStateMap[field.key] = {
|
|
56
|
-
hidden,
|
|
57
|
-
disabled,
|
|
58
|
-
initialHidden: hidden,
|
|
59
|
-
initialDisabled: disabled,
|
|
66
|
+
hidden: defaultState.hidden,
|
|
67
|
+
disabled: defaultState.disabled,
|
|
60
68
|
};
|
|
61
69
|
const validators = this.buildValidators(field.validators || []);
|
|
62
70
|
// Check if field key contains dot notation (e.g., "name.ar", "name.en")
|
|
@@ -69,16 +77,16 @@ class DynamicForm {
|
|
|
69
77
|
const parentGroup = formControls[parentKey];
|
|
70
78
|
// Add the child control to the parent group
|
|
71
79
|
const control = this.fb.control({
|
|
72
|
-
value:
|
|
73
|
-
disabled:
|
|
80
|
+
value: null,
|
|
81
|
+
disabled: defaultState.disabled,
|
|
74
82
|
}, validators);
|
|
75
83
|
parentGroup.addControl(childKey, control);
|
|
76
84
|
}
|
|
77
85
|
else {
|
|
78
86
|
// Regular field without nesting
|
|
79
87
|
const control = this.fb.control({
|
|
80
|
-
value:
|
|
81
|
-
disabled:
|
|
88
|
+
value: null,
|
|
89
|
+
disabled: defaultState.disabled,
|
|
82
90
|
}, validators);
|
|
83
91
|
formControls[field.key] = control;
|
|
84
92
|
}
|
|
@@ -89,19 +97,25 @@ class DynamicForm {
|
|
|
89
97
|
this.fieldStates.set(fieldStateMap);
|
|
90
98
|
// Subscribe to form value changes and evaluate all relations
|
|
91
99
|
this.formSubscription = this.form.valueChanges.subscribe(() => {
|
|
92
|
-
this.
|
|
93
|
-
this.onChange(this.form.
|
|
100
|
+
this.evaluateRelations();
|
|
101
|
+
this.onChange(this.form.getRawValue());
|
|
94
102
|
});
|
|
95
103
|
// Evaluate initial relations state
|
|
96
|
-
this.
|
|
104
|
+
this.evaluateRelations();
|
|
97
105
|
// Trigger initial validation state
|
|
98
106
|
this.onValidatorChange();
|
|
107
|
+
this.onChange(this.form.getRawValue());
|
|
99
108
|
}
|
|
100
109
|
// ControlValueAccessor implementation
|
|
101
110
|
writeValue(value) {
|
|
102
|
-
if (value && this.form) {
|
|
111
|
+
if (value && this.form && this.formBuilt()) {
|
|
103
112
|
this.form.patchValue(value, { emitEvent: false });
|
|
104
|
-
this.
|
|
113
|
+
this.evaluateRelations();
|
|
114
|
+
this.onChange(this.form.getRawValue());
|
|
115
|
+
}
|
|
116
|
+
else if (value && !this.formBuilt()) {
|
|
117
|
+
debugger;
|
|
118
|
+
this.initValue.set(value);
|
|
105
119
|
}
|
|
106
120
|
}
|
|
107
121
|
validate(_control) {
|
|
@@ -111,80 +125,103 @@ class DynamicForm {
|
|
|
111
125
|
// Return the form's errors if invalid, null if valid
|
|
112
126
|
return this.form.valid ? null : { invalidForm: true };
|
|
113
127
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
128
|
+
/**
|
|
129
|
+
* Calculate default field state based on relations
|
|
130
|
+
* If field has 'show' action → start hidden (opposite)
|
|
131
|
+
* If field has 'enable' action → start disabled (opposite)
|
|
132
|
+
*/
|
|
133
|
+
getDefaultFieldState(field) {
|
|
134
|
+
let hidden = !!field.hidden;
|
|
135
|
+
let disabled = !!field.disabled;
|
|
136
|
+
// If has relations, set opposite state
|
|
137
|
+
if (field.relations?.length) {
|
|
138
|
+
field.relations.forEach((relation) => {
|
|
139
|
+
if (relation.action === 'show') {
|
|
140
|
+
hidden = true;
|
|
141
|
+
}
|
|
142
|
+
else if (relation.action === 'hide') {
|
|
143
|
+
hidden = false;
|
|
144
|
+
}
|
|
145
|
+
else if (relation.action === 'enable') {
|
|
146
|
+
disabled = true;
|
|
147
|
+
}
|
|
148
|
+
else if (relation.action === 'disable') {
|
|
149
|
+
disabled = false;
|
|
150
|
+
}
|
|
125
151
|
});
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
|
|
152
|
+
}
|
|
153
|
+
return { hidden, disabled };
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Evaluate all relations - runs on every form change
|
|
157
|
+
* Simple: if dependency matches → apply action, else apply opposite
|
|
158
|
+
*/
|
|
159
|
+
evaluateRelations() {
|
|
160
|
+
const newStates = {};
|
|
161
|
+
// Process all fields with relations
|
|
129
162
|
this.formConfig().sections.forEach((section) => {
|
|
130
163
|
section.fields.forEach((field) => {
|
|
131
|
-
if (!field.key
|
|
164
|
+
if (!field.key) {
|
|
132
165
|
return;
|
|
133
166
|
}
|
|
134
|
-
//
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
167
|
+
// Calculate default state
|
|
168
|
+
const defaultState = this.getDefaultFieldState(field);
|
|
169
|
+
// Start with default
|
|
170
|
+
newStates[field.key] = {
|
|
171
|
+
hidden: defaultState.hidden,
|
|
172
|
+
disabled: defaultState.disabled,
|
|
173
|
+
};
|
|
174
|
+
// If has relations, check and apply
|
|
175
|
+
if (field.relations?.length) {
|
|
176
|
+
field.relations.forEach((relation) => {
|
|
177
|
+
const dependencyControl = this.form.get(relation.key);
|
|
178
|
+
if (!dependencyControl) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const matches = this.doesRelationMatch(dependencyControl.value, relation.value);
|
|
182
|
+
// If matches, apply the action
|
|
183
|
+
if (matches) {
|
|
184
|
+
const state = newStates[field.key];
|
|
185
|
+
switch (relation.action) {
|
|
186
|
+
case 'show':
|
|
187
|
+
state.hidden = false;
|
|
188
|
+
break;
|
|
189
|
+
case 'hide':
|
|
190
|
+
state.hidden = true;
|
|
191
|
+
break;
|
|
192
|
+
case 'enable':
|
|
193
|
+
state.disabled = false;
|
|
194
|
+
break;
|
|
195
|
+
case 'disable':
|
|
196
|
+
state.disabled = true;
|
|
197
|
+
break;
|
|
153
198
|
}
|
|
154
199
|
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
157
202
|
});
|
|
158
203
|
});
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
disabled = true;
|
|
176
|
-
break;
|
|
177
|
-
case 'enable':
|
|
178
|
-
disabled = false;
|
|
179
|
-
break;
|
|
204
|
+
// Update states
|
|
205
|
+
this.fieldStates.set(newStates);
|
|
206
|
+
// Sync form controls and clear values when disabled/hidden
|
|
207
|
+
Object.keys(newStates).forEach((key) => {
|
|
208
|
+
const control = this.form.get(key);
|
|
209
|
+
if (!control) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const state = newStates[key];
|
|
213
|
+
// Handle disabled state changes
|
|
214
|
+
if (state.disabled && !control.disabled) {
|
|
215
|
+
control.disable({ emitEvent: false });
|
|
216
|
+
control.reset(undefined, { emitEvent: false }); // Clear value when disabled
|
|
217
|
+
}
|
|
218
|
+
else if (!state.disabled && control.disabled) {
|
|
219
|
+
control.enable({ emitEvent: false });
|
|
180
220
|
}
|
|
181
|
-
|
|
182
|
-
|
|
221
|
+
// Clear value when hidden
|
|
222
|
+
if (state.hidden && control.value) {
|
|
223
|
+
control.reset(undefined, { emitEvent: false }); // Clear value when hidden
|
|
183
224
|
}
|
|
184
|
-
return {
|
|
185
|
-
...current,
|
|
186
|
-
[fieldKey]: { ...state, hidden, disabled },
|
|
187
|
-
};
|
|
188
225
|
});
|
|
189
226
|
}
|
|
190
227
|
doesRelationMatch(sourceValue, targetValue) {
|
|
@@ -265,11 +302,11 @@ class DynamicForm {
|
|
|
265
302
|
useExisting: forwardRef(() => DynamicForm),
|
|
266
303
|
multi: true,
|
|
267
304
|
},
|
|
268
|
-
], ngImport: i0, template: "<form [formGroup]=\"form\">\n <div\n class=\"flex flex-col gap-6 max-w-4xl mx-auto p-4\"\n [class]=\"formConfig().layout?.containerClass\"\n >\n @for (\n section of formConfig().sections | sort: \"order\";\n track section.key || $index\n ) {\n <div\n [class]=\"\n section.cssClass ||\n formConfig().layout?.sectionClass ||\n 'flex flex-col gap-4'\n \"\n >\n @if (section.type === \"header\" && section.label) {\n <h3\n [class]=\"\n section?.headerClass ||\n 'text-xl font-semibold text-gray-800 border-b-2 border-gray-200 pb-2 mb-4'\n \"\n >\n {{ section.label }}\n </h3>\n }\n\n <div\n [class]=\"\n section?.bodyClass ||\n 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 items-start'\n \"\n >\n @for (field of section.fields | sort: \"order\"; track field.key) {\n <div\n [class]=\"\n field.cssClass ||\n formConfig().layout?.fieldClass ||\n 'flex flex-col gap-1'\n \"\n [hidden]=\"hiddenFields()[field.key!]\"\n >\n @if (field.key!.includes(\".\")) {\n <!-- Handle nested fields (e.g., name.ar, name.en) -->\n @let parentKey = field.key!.split(\".\")[0];\n @let childKey = field.key!.split(\".\")[1];\n <form [formGroup]=\"form.get(parentKey)\">\n <mt-dynamic-field\n [fieldConfig]=\"field\"\n [fieldName]=\"childKey\"\n />\n </form>\n } @else {\n <!-- Handle regular fields -->\n <mt-dynamic-field\n [fieldConfig]=\"field\"\n [fieldName]=\"field.key!\"\n />\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n</form>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: DynamicField, selector: "mt-dynamic-field", inputs: ["fieldConfig", "fieldName"] }, { kind: "pipe", type: SortPipe, name: "sort" }]
|
|
305
|
+
], ngImport: i0, template: "<form [formGroup]=\"form\">\n <div\n class=\"flex flex-col gap-6 max-w-4xl mx-auto p-4\"\n [class]=\"formConfig().layout?.containerClass\"\n >\n @for (\n section of formConfig().sections | sort: \"order\";\n track section.key || $index\n ) {\n <div\n [class]=\"\n section.cssClass ||\n formConfig().layout?.sectionClass ||\n 'flex flex-col gap-4'\n \"\n >\n @if (section.type === \"header\" && section.label) {\n <h3\n [class]=\"\n section?.headerClass ||\n 'text-xl font-semibold text-gray-800 border-b-2 border-gray-200 pb-2 mb-4'\n \"\n >\n {{ section.label }}\n </h3>\n }\n\n <div\n [class]=\"\n section?.bodyClass ||\n 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 items-start'\n \"\n >\n @for (field of section.fields | sort: \"order\"; track field.key) {\n <div\n [class]=\"\n field.cssClass ||\n formConfig().layout?.fieldClass ||\n 'flex flex-col gap-1'\n \"\n [hidden]=\"hiddenFields()[field.key!]\"\n >\n @if (field.key!.includes(\".\")) {\n <!-- Handle nested fields (e.g., name.ar, name.en) -->\n @let parentKey = field.key!.split(\".\")[0];\n @let childKey = field.key!.split(\".\")[1];\n <form [formGroup]=\"form.get(parentKey)\">\n <mt-dynamic-field\n [fieldConfig]=\"field\"\n [fieldName]=\"childKey\"\n />\n </form>\n } @else {\n <!-- Handle regular fields -->\n <mt-dynamic-field\n [fieldConfig]=\"field\"\n [fieldName]=\"field.key!\"\n />\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n</form>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: DynamicField, selector: "mt-dynamic-field", inputs: ["fieldConfig", "fieldName"] }, { kind: "pipe", type: SortPipe, name: "sort" }] });
|
|
269
306
|
}
|
|
270
307
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: DynamicForm, decorators: [{
|
|
271
308
|
type: Component,
|
|
272
|
-
args: [{ selector: 'mt-dynamic-form', standalone: true, imports: [CommonModule, ReactiveFormsModule, DynamicField, SortPipe],
|
|
309
|
+
args: [{ selector: 'mt-dynamic-form', standalone: true, imports: [CommonModule, ReactiveFormsModule, DynamicField, SortPipe], providers: [
|
|
273
310
|
{
|
|
274
311
|
provide: NG_VALUE_ACCESSOR,
|
|
275
312
|
useExisting: forwardRef(() => DynamicForm),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"masterteam-forms-dynamic-form.mjs","sources":["../../../../packages/masterteam/forms/dynamic-form/dynamic-form.ts","../../../../packages/masterteam/forms/dynamic-form/dynamic-form.html","../../../../packages/masterteam/forms/dynamic-form/masterteam-forms-dynamic-form.ts"],"sourcesContent":["import {\n Component,\n input,\n effect,\n ChangeDetectionStrategy,\n OnDestroy,\n forwardRef,\n inject,\n signal,\n computed,\n} from '@angular/core';\nimport {\n FormBuilder,\n FormGroup,\n ReactiveFormsModule,\n Validators,\n AbstractControl,\n ValidatorFn,\n ControlValueAccessor,\n NG_VALUE_ACCESSOR,\n Validator,\n ValidationErrors,\n NG_VALIDATORS,\n} from '@angular/forms';\nimport { CommonModule } from '@angular/common';\nimport { DynamicField } from '@masterteam/forms/dynamic-field';\nimport { SortPipe } from '@masterteam/forms/pipes';\n// import { SortPipe } from '../pipes/sort.pipe';\nimport {\n DynamicFormConfig,\n ValidatorConfig,\n createCustomValidator,\n wrapValidatorWithMessage,\n FieldRelationAction,\n FieldState,\n} from '@masterteam/components';\nimport { Subscription } from 'rxjs';\n\n@Component({\n selector: 'mt-dynamic-form',\n standalone: true,\n imports: [CommonModule, ReactiveFormsModule, DynamicField, SortPipe],\n templateUrl: './dynamic-form.html',\n styleUrls: ['./dynamic-form.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => DynamicForm),\n multi: true,\n },\n {\n provide: NG_VALIDATORS,\n useExisting: forwardRef(() => DynamicForm),\n multi: true,\n },\n ],\n})\nexport class DynamicForm implements OnDestroy, ControlValueAccessor, Validator {\n private fb = inject(FormBuilder);\n\n readonly formConfig = input.required<DynamicFormConfig>();\n\n form = new FormGroup({});\n\n // ControlValueAccessor implementation\n private onChange = (_value: any) => {};\n private onTouched = () => {};\n private onValidatorChange = () => {};\n private formSubscription?: Subscription;\n private fieldStates = signal<Record<string, FieldState>>({});\n\n // Computed signal for field visibility - better performance\n readonly hiddenFields = computed(() => {\n const states = this.fieldStates();\n const hidden: Record<string, boolean> = {};\n Object.keys(states).forEach((key) => {\n hidden[key] = states[key].hidden;\n });\n return hidden;\n });\n\n constructor() {\n // Effect to rebuild form when config changes\n effect(() => {\n this.buildForm();\n });\n }\n\n registerOnValidatorChange(fn: () => void): void {\n this.onValidatorChange = fn;\n }\n registerOnChange(fn: (value: any) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n private buildForm() {\n if (this.formSubscription) {\n this.formSubscription.unsubscribe();\n }\n\n const formControls: { [key: string]: AbstractControl } = {};\n const fieldStateMap: Record<string, FieldState> = {};\n\n this.formConfig().sections.forEach((section) => {\n section.fields.forEach((field) => {\n if (field.key) {\n const hidden = !!field.hidden;\n const disabled = !!field.disabled;\n fieldStateMap[field.key] = {\n hidden,\n disabled,\n initialHidden: hidden,\n initialDisabled: disabled,\n };\n const validators = this.buildValidators(field.validators || []);\n\n // Check if field key contains dot notation (e.g., \"name.ar\", \"name.en\")\n if (field.key.includes('.')) {\n const [parentKey, childKey] = field.key.split('.');\n\n // Create or get the parent FormGroup\n if (!formControls[parentKey]) {\n formControls[parentKey] = this.fb.group({});\n }\n\n const parentGroup = formControls[parentKey] as FormGroup;\n\n // Add the child control to the parent group\n const control = this.fb.control(\n {\n value: field.defaultValue,\n disabled: field.disabled || false,\n },\n validators,\n );\n\n parentGroup.addControl(childKey, control);\n } else {\n // Regular field without nesting\n const control = this.fb.control(\n {\n value: field.defaultValue,\n disabled: field.disabled || false,\n },\n validators,\n );\n formControls[field.key] = control;\n }\n }\n });\n });\n\n this.form = this.fb.group(formControls);\n this.fieldStates.set(fieldStateMap);\n\n // Subscribe to form value changes and evaluate all relations\n this.formSubscription = this.form.valueChanges.subscribe(() => {\n this.evaluateAllRelations();\n this.onChange(this.form.value);\n });\n\n // Evaluate initial relations state\n this.evaluateAllRelations();\n\n // Trigger initial validation state\n this.onValidatorChange();\n }\n\n // ControlValueAccessor implementation\n writeValue(value: any): void {\n if (value && this.form) {\n this.form.patchValue(value, { emitEvent: false });\n this.evaluateAllRelations();\n }\n }\n\n validate(_control: AbstractControl): ValidationErrors | null {\n if (!this.form) {\n return null;\n }\n // Return the form's errors if invalid, null if valid\n return this.form.valid ? null : { invalidForm: true };\n }\n\n private evaluateAllRelations() {\n // Reset all fields to initial state\n this.fieldStates.update((current) => {\n const resetState: Record<string, FieldState> = {};\n Object.keys(current).forEach((key) => {\n const state = current[key];\n resetState[key] = {\n ...state,\n hidden: state.initialHidden,\n disabled: state.initialDisabled,\n };\n });\n return resetState;\n });\n\n // Evaluate all field relations\n this.formConfig().sections.forEach((section) => {\n section.fields.forEach((field) => {\n if (!field.key || !field.relations?.length) {\n return;\n }\n\n // Check each relation\n field.relations.forEach((relation) => {\n const dependencyControl = this.form.get(relation.key);\n if (!dependencyControl) {\n return;\n }\n\n // If relation matches, apply the action\n if (this.doesRelationMatch(dependencyControl.value, relation.value)) {\n this.applyFieldState(field.key!, relation.action);\n\n // Handle form control enable/disable\n if (relation.action === 'disable' || relation.action === 'enable') {\n const control = this.form.get(field.key!);\n if (control) {\n if (relation.action === 'disable') {\n control.disable({ emitEvent: false });\n } else {\n control.enable({ emitEvent: false });\n }\n }\n }\n }\n });\n });\n });\n }\n\n private applyFieldState(fieldKey: string, action: FieldRelationAction) {\n this.fieldStates.update((current) => {\n const state = current[fieldKey];\n if (!state) return current;\n\n let hidden = state.hidden;\n let disabled = state.disabled;\n\n switch (action) {\n case 'hide':\n hidden = true;\n break;\n case 'show':\n hidden = false;\n break;\n case 'disable':\n disabled = true;\n break;\n case 'enable':\n disabled = false;\n break;\n }\n\n if (state.hidden === hidden && state.disabled === disabled) {\n return current;\n }\n\n return {\n ...current,\n [fieldKey]: { ...state, hidden, disabled },\n };\n });\n }\n\n private doesRelationMatch(sourceValue: any, targetValue: any): boolean {\n if (Array.isArray(sourceValue)) {\n if (Array.isArray(targetValue)) {\n return targetValue.every((value) => sourceValue.includes(value));\n }\n return sourceValue.includes(targetValue);\n }\n return sourceValue === targetValue;\n }\n\n private buildValidators(validatorConfigs: ValidatorConfig[]): ValidatorFn[] {\n const validators: ValidatorFn[] = [];\n\n validatorConfigs.forEach((config) => {\n let validator: ValidatorFn | null = null;\n\n switch (config.type) {\n case 'required':\n validator = Validators.required;\n break;\n case 'email':\n validator = Validators.email;\n break;\n case 'minLength':\n if (config.value) {\n validator = Validators.minLength(config.value);\n }\n break;\n case 'maxLength':\n if (config.value) {\n validator = Validators.maxLength(config.value);\n }\n break;\n case 'min':\n if (config.value !== undefined) {\n validator = Validators.min(config.value);\n }\n break;\n case 'max':\n if (config.value !== undefined) {\n validator = Validators.max(config.value);\n }\n break;\n case 'pattern':\n if (config.value) {\n validator = Validators.pattern(config.value);\n }\n break;\n case 'custom':\n if (config.customValidator) {\n validators.push(\n createCustomValidator(config.customValidator, config.message),\n );\n }\n break;\n }\n\n // If we have a validator and a custom message, wrap it\n if (validator && config.message) {\n validators.push(\n wrapValidatorWithMessage(validator, config.type, config.message),\n );\n } else if (validator) {\n validators.push(validator);\n }\n });\n\n return validators;\n }\n\n ngOnDestroy(): void {\n if (this.formSubscription) {\n this.formSubscription.unsubscribe();\n }\n }\n}\n","<form [formGroup]=\"form\">\n <div\n class=\"flex flex-col gap-6 max-w-4xl mx-auto p-4\"\n [class]=\"formConfig().layout?.containerClass\"\n >\n @for (\n section of formConfig().sections | sort: \"order\";\n track section.key || $index\n ) {\n <div\n [class]=\"\n section.cssClass ||\n formConfig().layout?.sectionClass ||\n 'flex flex-col gap-4'\n \"\n >\n @if (section.type === \"header\" && section.label) {\n <h3\n [class]=\"\n section?.headerClass ||\n 'text-xl font-semibold text-gray-800 border-b-2 border-gray-200 pb-2 mb-4'\n \"\n >\n {{ section.label }}\n </h3>\n }\n\n <div\n [class]=\"\n section?.bodyClass ||\n 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 items-start'\n \"\n >\n @for (field of section.fields | sort: \"order\"; track field.key) {\n <div\n [class]=\"\n field.cssClass ||\n formConfig().layout?.fieldClass ||\n 'flex flex-col gap-1'\n \"\n [hidden]=\"hiddenFields()[field.key!]\"\n >\n @if (field.key!.includes(\".\")) {\n <!-- Handle nested fields (e.g., name.ar, name.en) -->\n @let parentKey = field.key!.split(\".\")[0];\n @let childKey = field.key!.split(\".\")[1];\n <form [formGroup]=\"form.get(parentKey)\">\n <mt-dynamic-field\n [fieldConfig]=\"field\"\n [fieldName]=\"childKey\"\n />\n </form>\n } @else {\n <!-- Handle regular fields -->\n <mt-dynamic-field\n [fieldConfig]=\"field\"\n [fieldName]=\"field.key!\"\n />\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n</form>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"masterteam-forms-dynamic-form.mjs","sources":["../../../../packages/masterteam/forms/dynamic-form/dynamic-form.ts","../../../../packages/masterteam/forms/dynamic-form/dynamic-form.html","../../../../packages/masterteam/forms/dynamic-form/masterteam-forms-dynamic-form.ts"],"sourcesContent":["import {\n Component,\n input,\n effect,\n OnDestroy,\n forwardRef,\n inject,\n signal,\n computed,\n untracked,\n} from '@angular/core';\nimport {\n FormBuilder,\n FormGroup,\n ReactiveFormsModule,\n Validators,\n AbstractControl,\n ValidatorFn,\n ControlValueAccessor,\n NG_VALUE_ACCESSOR,\n Validator,\n ValidationErrors,\n NG_VALIDATORS,\n} from '@angular/forms';\nimport { CommonModule } from '@angular/common';\nimport { DynamicField } from '@masterteam/forms/dynamic-field';\nimport { SortPipe } from '@masterteam/forms/pipes';\n// import { SortPipe } from '../pipes/sort.pipe';\nimport {\n DynamicFormConfig,\n ValidatorConfig,\n createCustomValidator,\n wrapValidatorWithMessage,\n FieldState,\n} from '@masterteam/components';\nimport { Subscription } from 'rxjs';\n\n@Component({\n selector: 'mt-dynamic-form',\n standalone: true,\n imports: [CommonModule, ReactiveFormsModule, DynamicField, SortPipe],\n templateUrl: './dynamic-form.html',\n styleUrls: ['./dynamic-form.scss'],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => DynamicForm),\n multi: true,\n },\n {\n provide: NG_VALIDATORS,\n useExisting: forwardRef(() => DynamicForm),\n multi: true,\n },\n ],\n})\nexport class DynamicForm implements OnDestroy, ControlValueAccessor, Validator {\n private fb = inject(FormBuilder);\n\n readonly formConfig = input.required<DynamicFormConfig>();\n\n form = new FormGroup({});\n private formBuilt = signal(false);\n private initValue = signal<any>({});\n\n // ControlValueAccessor implementation\n private onChange = (_value: any) => {};\n private onTouched = () => {};\n private onValidatorChange = () => {};\n private formSubscription?: Subscription;\n private fieldStates = signal<Record<string, FieldState>>({});\n\n // Computed signal for field visibility - better performance\n readonly hiddenFields = computed(() => {\n const states = this.fieldStates();\n const hidden: Record<string, boolean> = {};\n Object.keys(states).forEach((key) => {\n hidden[key] = states[key].hidden;\n });\n return hidden;\n });\n\n constructor() {\n // Effect to rebuild form when config changes\n effect(() => {\n this.buildForm();\n this.formBuilt.set(true);\n const initValue = untracked(() => this.initValue());\n if (initValue) {\n this.form.patchValue(initValue, { emitEvent: false });\n this.initValue.set(null);\n this.evaluateRelations();\n this.onChange(this.form.getRawValue());\n }\n });\n }\n\n registerOnValidatorChange(fn: () => void): void {\n this.onValidatorChange = fn;\n }\n registerOnChange(fn: (value: any) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n private buildForm() {\n if (this.formSubscription) {\n this.formSubscription.unsubscribe();\n }\n\n const formControls: { [key: string]: AbstractControl } = {};\n const fieldStateMap: Record<string, FieldState> = {};\n\n this.formConfig().sections.forEach((section) => {\n section.fields.forEach((field) => {\n if (field.key) {\n // Calculate default state from relations\n const defaultState = this.getDefaultFieldState(field);\n\n fieldStateMap[field.key] = {\n hidden: defaultState.hidden,\n disabled: defaultState.disabled,\n };\n\n const validators = this.buildValidators(field.validators || []);\n\n // Check if field key contains dot notation (e.g., \"name.ar\", \"name.en\")\n if (field.key.includes('.')) {\n const [parentKey, childKey] = field.key.split('.');\n\n // Create or get the parent FormGroup\n if (!formControls[parentKey]) {\n formControls[parentKey] = this.fb.group({});\n }\n\n const parentGroup = formControls[parentKey] as FormGroup;\n\n // Add the child control to the parent group\n const control = this.fb.control(\n {\n value: null,\n disabled: defaultState.disabled,\n },\n validators,\n );\n\n parentGroup.addControl(childKey, control);\n } else {\n // Regular field without nesting\n const control = this.fb.control(\n {\n value: null,\n disabled: defaultState.disabled,\n },\n validators,\n );\n formControls[field.key] = control;\n }\n }\n });\n });\n\n this.form = this.fb.group(formControls);\n this.fieldStates.set(fieldStateMap);\n\n // Subscribe to form value changes and evaluate all relations\n this.formSubscription = this.form.valueChanges.subscribe(() => {\n this.evaluateRelations();\n this.onChange(this.form.getRawValue());\n });\n\n // Evaluate initial relations state\n this.evaluateRelations();\n\n // Trigger initial validation state\n this.onValidatorChange();\n this.onChange(this.form.getRawValue());\n }\n\n // ControlValueAccessor implementation\n writeValue(value: any): void {\n if (value && this.form && this.formBuilt()) {\n this.form.patchValue(value, { emitEvent: false });\n this.evaluateRelations();\n this.onChange(this.form.getRawValue());\n } else if (value && !this.formBuilt()) {\n debugger;\n this.initValue.set(value);\n }\n }\n\n validate(_control: AbstractControl): ValidationErrors | null {\n if (!this.form) {\n return null;\n }\n // Return the form's errors if invalid, null if valid\n return this.form.valid ? null : { invalidForm: true };\n }\n\n /**\n * Calculate default field state based on relations\n * If field has 'show' action → start hidden (opposite)\n * If field has 'enable' action → start disabled (opposite)\n */\n private getDefaultFieldState(field: any): {\n hidden: boolean;\n disabled: boolean;\n } {\n let hidden = !!field.hidden;\n let disabled = !!field.disabled;\n\n // If has relations, set opposite state\n if (field.relations?.length) {\n field.relations.forEach((relation: any) => {\n if (relation.action === 'show') {\n hidden = true;\n } else if (relation.action === 'hide') {\n hidden = false;\n } else if (relation.action === 'enable') {\n disabled = true;\n } else if (relation.action === 'disable') {\n disabled = false;\n }\n });\n }\n\n return { hidden, disabled };\n }\n\n /**\n * Evaluate all relations - runs on every form change\n * Simple: if dependency matches → apply action, else apply opposite\n */\n private evaluateRelations() {\n const newStates: Record<string, FieldState> = {};\n\n // Process all fields with relations\n this.formConfig().sections.forEach((section) => {\n section.fields.forEach((field) => {\n if (!field.key) {\n return;\n }\n\n // Calculate default state\n const defaultState = this.getDefaultFieldState(field);\n\n // Start with default\n newStates[field.key] = {\n hidden: defaultState.hidden,\n disabled: defaultState.disabled,\n };\n\n // If has relations, check and apply\n if (field.relations?.length) {\n field.relations.forEach((relation) => {\n const dependencyControl = this.form.get(relation.key);\n if (!dependencyControl) {\n return;\n }\n\n const matches = this.doesRelationMatch(\n dependencyControl.value,\n relation.value,\n );\n\n // If matches, apply the action\n if (matches) {\n const state = newStates[field.key!];\n switch (relation.action) {\n case 'show':\n state.hidden = false;\n break;\n case 'hide':\n state.hidden = true;\n break;\n case 'enable':\n state.disabled = false;\n break;\n case 'disable':\n state.disabled = true;\n break;\n }\n }\n });\n }\n });\n });\n\n // Update states\n this.fieldStates.set(newStates);\n\n // Sync form controls and clear values when disabled/hidden\n Object.keys(newStates).forEach((key) => {\n const control = this.form.get(key);\n if (!control) {\n return;\n }\n\n const state = newStates[key];\n\n // Handle disabled state changes\n if (state.disabled && !control.disabled) {\n control.disable({ emitEvent: false });\n control.reset(undefined, { emitEvent: false }); // Clear value when disabled\n } else if (!state.disabled && control.disabled) {\n control.enable({ emitEvent: false });\n }\n\n // Clear value when hidden\n if (state.hidden && control.value) {\n control.reset(undefined, { emitEvent: false }); // Clear value when hidden\n }\n });\n }\n\n private doesRelationMatch(sourceValue: any, targetValue: any): boolean {\n if (Array.isArray(sourceValue)) {\n if (Array.isArray(targetValue)) {\n return targetValue.every((value) => sourceValue.includes(value));\n }\n return sourceValue.includes(targetValue);\n }\n return sourceValue === targetValue;\n }\n\n private buildValidators(validatorConfigs: ValidatorConfig[]): ValidatorFn[] {\n const validators: ValidatorFn[] = [];\n\n validatorConfigs.forEach((config) => {\n let validator: ValidatorFn | null = null;\n\n switch (config.type) {\n case 'required':\n validator = Validators.required;\n break;\n case 'email':\n validator = Validators.email;\n break;\n case 'minLength':\n if (config.value) {\n validator = Validators.minLength(config.value);\n }\n break;\n case 'maxLength':\n if (config.value) {\n validator = Validators.maxLength(config.value);\n }\n break;\n case 'min':\n if (config.value !== undefined) {\n validator = Validators.min(config.value);\n }\n break;\n case 'max':\n if (config.value !== undefined) {\n validator = Validators.max(config.value);\n }\n break;\n case 'pattern':\n if (config.value) {\n validator = Validators.pattern(config.value);\n }\n break;\n case 'custom':\n if (config.customValidator) {\n validators.push(\n createCustomValidator(config.customValidator, config.message),\n );\n }\n break;\n }\n\n // If we have a validator and a custom message, wrap it\n if (validator && config.message) {\n validators.push(\n wrapValidatorWithMessage(validator, config.type, config.message),\n );\n } else if (validator) {\n validators.push(validator);\n }\n });\n\n return validators;\n }\n\n ngOnDestroy(): void {\n if (this.formSubscription) {\n this.formSubscription.unsubscribe();\n }\n }\n}\n","<form [formGroup]=\"form\">\n <div\n class=\"flex flex-col gap-6 max-w-4xl mx-auto p-4\"\n [class]=\"formConfig().layout?.containerClass\"\n >\n @for (\n section of formConfig().sections | sort: \"order\";\n track section.key || $index\n ) {\n <div\n [class]=\"\n section.cssClass ||\n formConfig().layout?.sectionClass ||\n 'flex flex-col gap-4'\n \"\n >\n @if (section.type === \"header\" && section.label) {\n <h3\n [class]=\"\n section?.headerClass ||\n 'text-xl font-semibold text-gray-800 border-b-2 border-gray-200 pb-2 mb-4'\n \"\n >\n {{ section.label }}\n </h3>\n }\n\n <div\n [class]=\"\n section?.bodyClass ||\n 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 items-start'\n \"\n >\n @for (field of section.fields | sort: \"order\"; track field.key) {\n <div\n [class]=\"\n field.cssClass ||\n formConfig().layout?.fieldClass ||\n 'flex flex-col gap-1'\n \"\n [hidden]=\"hiddenFields()[field.key!]\"\n >\n @if (field.key!.includes(\".\")) {\n <!-- Handle nested fields (e.g., name.ar, name.en) -->\n @let parentKey = field.key!.split(\".\")[0];\n @let childKey = field.key!.split(\".\")[1];\n <form [formGroup]=\"form.get(parentKey)\">\n <mt-dynamic-field\n [fieldConfig]=\"field\"\n [fieldName]=\"childKey\"\n />\n </form>\n } @else {\n <!-- Handle regular fields -->\n <mt-dynamic-field\n [fieldConfig]=\"field\"\n [fieldName]=\"field.key!\"\n />\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n</form>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@masterteam/forms",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"directory": ".",
|
|
6
6
|
"linkDirectory": false,
|
|
@@ -33,14 +33,14 @@
|
|
|
33
33
|
"types": "./index.d.ts",
|
|
34
34
|
"default": "./fesm2022/masterteam-forms.mjs"
|
|
35
35
|
},
|
|
36
|
-
"./dynamic-form": {
|
|
37
|
-
"types": "./dynamic-form/index.d.ts",
|
|
38
|
-
"default": "./fesm2022/masterteam-forms-dynamic-form.mjs"
|
|
39
|
-
},
|
|
40
36
|
"./dynamic-field": {
|
|
41
37
|
"types": "./dynamic-field/index.d.ts",
|
|
42
38
|
"default": "./fesm2022/masterteam-forms-dynamic-field.mjs"
|
|
43
39
|
},
|
|
40
|
+
"./dynamic-form": {
|
|
41
|
+
"types": "./dynamic-form/index.d.ts",
|
|
42
|
+
"default": "./fesm2022/masterteam-forms-dynamic-form.mjs"
|
|
43
|
+
},
|
|
44
44
|
"./pipes": {
|
|
45
45
|
"types": "./pipes/index.d.ts",
|
|
46
46
|
"default": "./fesm2022/masterteam-forms-pipes.mjs"
|