@bolttech/form-engine-core 1.0.0-beta.8 → 1.0.1-beta.0
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/index.esm.js +292 -211
- package/package.json +1 -1
- package/src/constants/constants.d.ts +1 -1
- package/src/interfaces/schema.d.ts +6 -1
- package/src/managers/field.d.ts +28 -22
- package/src/managers/form.d.ts +13 -11
- package/src/managers/formGroup.d.ts +8 -4
- package/src/types/event.d.ts +28 -4
- package/src/types/form.d.ts +8 -0
- package/src/types/schema.d.ts +5 -1
package/index.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Subject, Subscription,
|
|
1
|
+
import { Subject, Subscription, groupBy, mergeMap, debounceTime, filter, combineLatest, startWith, map, distinctUntilKeyChanged } from 'rxjs';
|
|
2
2
|
import creditCardType from 'credit-card-type';
|
|
3
|
-
import { isNumber as isNumber$1, isFunction, cloneDeep,
|
|
3
|
+
import { isNumber as isNumber$1, isFunction, cloneDeep, isEqual, get, isNil, set } from 'lodash';
|
|
4
4
|
import { getCurrencySymbol } from '@gaignoux/currency';
|
|
5
5
|
|
|
6
6
|
var TMutationEnum;
|
|
@@ -48,9 +48,9 @@ const DEFAULT_API_DEBOUNCE_TIME = 1000;
|
|
|
48
48
|
const DEFAULT_STATE_REFRESH_TIME = 100;
|
|
49
49
|
const TEMPLATE_REGEX_STRING_CONCATENATION_DETECTOR = /^\$\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\}$/;
|
|
50
50
|
const TEMPLATE_REGEX_DELIMITATOR = /\$\{((?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*)\}/g;
|
|
51
|
-
const TEMPLATE_REGEX_OPERATOR_SPLITTER = /\s*(
|
|
52
|
-
const TEMPLATE_REGEX_OPERATOR_MATCHER =
|
|
53
|
-
const TEMPLATE_AVALIABLE_SCOPES = ['fields', 'iVars'];
|
|
51
|
+
const TEMPLATE_REGEX_OPERATOR_SPLITTER = /\s*(\|\||&&|!+)\s*/g;
|
|
52
|
+
const TEMPLATE_REGEX_OPERATOR_MATCHER = /^\|\||&&|!+$/;
|
|
53
|
+
const TEMPLATE_AVALIABLE_SCOPES = ['fields', 'iVars', 'form'];
|
|
54
54
|
const ALLOWED_RESET_PROPS_MUTATIONS = ['api', 'apiSchema', 'props', 'validations', 'visibilityConditions', 'resetValues'];
|
|
55
55
|
const DEFAULT_LOG_VERBOSE = false;
|
|
56
56
|
|
|
@@ -72,11 +72,12 @@ function makeRequest(method, url, headers, body, queryParams) {
|
|
|
72
72
|
return new Promise(function (resolve, reject) {
|
|
73
73
|
const xhr = new XMLHttpRequest();
|
|
74
74
|
if (queryParams) {
|
|
75
|
-
const
|
|
75
|
+
const [baseUrl, existingParamsString] = url.split('?');
|
|
76
|
+
const searchParams = new URLSearchParams(existingParamsString);
|
|
76
77
|
Object.keys(queryParams).forEach(param => {
|
|
77
|
-
|
|
78
|
+
searchParams.append(param, queryParams[param]);
|
|
78
79
|
});
|
|
79
|
-
url =
|
|
80
|
+
url = `${baseUrl}?${searchParams.toString()}`;
|
|
80
81
|
}
|
|
81
82
|
xhr.open(method, url, true);
|
|
82
83
|
if (headers) {
|
|
@@ -577,7 +578,7 @@ const formatters = {
|
|
|
577
578
|
* console.log(maskedValue); // Output: 'ab***gh###'
|
|
578
579
|
* ```
|
|
579
580
|
*/
|
|
580
|
-
var generic = (
|
|
581
|
+
var generic = (value, masks) => {
|
|
581
582
|
if (!(masks === null || masks === void 0 ? void 0 : masks.generic)) return value;
|
|
582
583
|
let masked = value;
|
|
583
584
|
masks.generic.forEach(item => {
|
|
@@ -596,7 +597,7 @@ var generic = ((value, masks) => {
|
|
|
596
597
|
masked = masked.slice(0, from - 1) + maskedPortion + masked.slice(to);
|
|
597
598
|
});
|
|
598
599
|
return masked;
|
|
599
|
-
}
|
|
600
|
+
};
|
|
600
601
|
|
|
601
602
|
/**
|
|
602
603
|
* Replaces all characters in a string with a specified replacement string or character.
|
|
@@ -881,7 +882,7 @@ const masks = {
|
|
|
881
882
|
* console.log(isValid); // Output: true or false based on validation
|
|
882
883
|
* ```
|
|
883
884
|
*/
|
|
884
|
-
var length = (
|
|
885
|
+
var length = (value, validations) => {
|
|
885
886
|
if (!validations.length || !value) return false;
|
|
886
887
|
let targetValue = value;
|
|
887
888
|
// We want length even if it is a numeric
|
|
@@ -897,7 +898,7 @@ var length = ((value, validations) => {
|
|
|
897
898
|
greaterOrEqual: targetValue.length < validations.length.target
|
|
898
899
|
};
|
|
899
900
|
return condition[validations.length.rule];
|
|
900
|
-
}
|
|
901
|
+
};
|
|
901
902
|
|
|
902
903
|
/**
|
|
903
904
|
* Validates a Spanish NIF (Número de Identificación Fiscal).
|
|
@@ -1135,7 +1136,7 @@ const CIF = value => {
|
|
|
1135
1136
|
* console.log(isValid); // Output: true or false based on validation
|
|
1136
1137
|
* ```
|
|
1137
1138
|
*/
|
|
1138
|
-
var document = (
|
|
1139
|
+
var document = (value, validations) => {
|
|
1139
1140
|
if (!value || !validations.document) return true;
|
|
1140
1141
|
const validation = {
|
|
1141
1142
|
NIF: (value, locale) => NIF(value, locale),
|
|
@@ -1144,7 +1145,7 @@ var document = ((value, validations) => {
|
|
|
1144
1145
|
IBAN: value => IBAN(value)
|
|
1145
1146
|
};
|
|
1146
1147
|
return validation[validations.document.type](value, validations.document.locale);
|
|
1147
|
-
}
|
|
1148
|
+
};
|
|
1148
1149
|
|
|
1149
1150
|
/**
|
|
1150
1151
|
* Validates if a value exceeds the maximum allowed value.
|
|
@@ -2262,10 +2263,10 @@ function run$1(value, handlers, validations) {
|
|
|
2262
2263
|
* const isValid = validateValue(value, methods);
|
|
2263
2264
|
* console.log(isValid); // Output: true
|
|
2264
2265
|
*/
|
|
2265
|
-
var namedRule = (
|
|
2266
|
+
var namedRule = (value, methods, validations) => {
|
|
2266
2267
|
if (!methods) return false;
|
|
2267
2268
|
return run$1(value, methods, validations).some(validation => validation);
|
|
2268
|
-
}
|
|
2269
|
+
};
|
|
2269
2270
|
|
|
2270
2271
|
/**
|
|
2271
2272
|
* @internal
|
|
@@ -2485,6 +2486,7 @@ class FormField {
|
|
|
2485
2486
|
* @param {() => TFormValues<unknown>} options.getFormValues, - form instance function that builds onData parameter payload from fields
|
|
2486
2487
|
*/
|
|
2487
2488
|
constructor({
|
|
2489
|
+
formIndex,
|
|
2488
2490
|
schemaComponent,
|
|
2489
2491
|
config,
|
|
2490
2492
|
path,
|
|
@@ -2495,16 +2497,18 @@ class FormField {
|
|
|
2495
2497
|
templateSubject$,
|
|
2496
2498
|
fieldEventSubject$,
|
|
2497
2499
|
dataSubject$,
|
|
2498
|
-
|
|
2500
|
+
fieldValidNotification$,
|
|
2499
2501
|
mountSubject$,
|
|
2500
2502
|
mapper,
|
|
2501
2503
|
getFormValues,
|
|
2502
2504
|
submitEvent,
|
|
2503
|
-
visibility
|
|
2505
|
+
visibility,
|
|
2506
|
+
persistValue
|
|
2504
2507
|
}) {
|
|
2505
|
-
var _a, _b, _c, _d, _e, _f
|
|
2508
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2506
2509
|
this.valueSubscription$ = new Subscription();
|
|
2507
2510
|
this.fieldStateSubscription$ = new Subscription();
|
|
2511
|
+
this.formIndex = formIndex;
|
|
2508
2512
|
this.originalSchema = cloneDeep(schemaComponent);
|
|
2509
2513
|
this.config = {
|
|
2510
2514
|
defaultAPIdebounceTimeMS: Number(config === null || config === void 0 ? void 0 : config.defaultAPIdebounceTimeMS) ? Number(config === null || config === void 0 ? void 0 : config.defaultAPIdebounceTimeMS) : DEFAULT_API_DEBOUNCE_TIME,
|
|
@@ -2517,7 +2521,6 @@ class FormField {
|
|
|
2517
2521
|
this.path = path;
|
|
2518
2522
|
this.children = children;
|
|
2519
2523
|
this.validations = cloneDeep(schemaComponent.validations);
|
|
2520
|
-
this.errorMessages = cloneDeep((_a = schemaComponent.validations) === null || _a === void 0 ? void 0 : _a.messages);
|
|
2521
2524
|
this.visibilityConditions = cloneDeep(schemaComponent.visibilityConditions);
|
|
2522
2525
|
this.resetValues = cloneDeep(schemaComponent.resetValues);
|
|
2523
2526
|
this.resetPropertyValues = cloneDeep(schemaComponent.resetPropertyValues);
|
|
@@ -2525,7 +2528,7 @@ class FormField {
|
|
|
2525
2528
|
this.formatters = cloneDeep(schemaComponent.formatters);
|
|
2526
2529
|
this.masks = cloneDeep(schemaComponent.masks);
|
|
2527
2530
|
if (mapper.valueChangeEvent) this.valueChangeEvent = mapper.valueChangeEvent;
|
|
2528
|
-
if ((
|
|
2531
|
+
if ((_a = mapper.events) === null || _a === void 0 ? void 0 : _a.setValue) this.valuePropName = mapper.events.setValue;
|
|
2529
2532
|
this.mapper = mapper;
|
|
2530
2533
|
this.validateVisibility = validateVisibility;
|
|
2531
2534
|
this.resetValue = resetValue;
|
|
@@ -2535,7 +2538,7 @@ class FormField {
|
|
|
2535
2538
|
this.templateSubject$ = templateSubject$;
|
|
2536
2539
|
this.fieldEventSubject$ = fieldEventSubject$;
|
|
2537
2540
|
this.dataSubject$ = dataSubject$;
|
|
2538
|
-
this.
|
|
2541
|
+
this.fieldValidNotification$ = fieldValidNotification$;
|
|
2539
2542
|
this.mountSubject$ = mountSubject$;
|
|
2540
2543
|
this._props = FormField.filterProps(cloneDeep(schemaComponent.props || {}));
|
|
2541
2544
|
this._metadata = '';
|
|
@@ -2544,21 +2547,25 @@ class FormField {
|
|
|
2544
2547
|
this._visibility = typeof visibility === 'boolean' ? visibility : true;
|
|
2545
2548
|
this._api = {
|
|
2546
2549
|
default: {
|
|
2547
|
-
response: ((
|
|
2550
|
+
response: ((_d = (_c = (_b = this.apiSchema) === null || _b === void 0 ? void 0 : _b.defaultConfig) === null || _c === void 0 ? void 0 : _c.config) === null || _d === void 0 ? void 0 : _d.fallbackValue) || '',
|
|
2548
2551
|
status: null
|
|
2549
2552
|
},
|
|
2550
|
-
named: ((
|
|
2553
|
+
named: ((_e = this.apiSchema) === null || _e === void 0 ? void 0 : _e.configs) && Object.keys((_f = this.apiSchema) === null || _f === void 0 ? void 0 : _f.configs).reduce((acc, curr) => {
|
|
2551
2554
|
var _a, _b;
|
|
2552
2555
|
acc[curr] = {
|
|
2553
2556
|
response: ((_b = (_a = this.apiSchema) === null || _a === void 0 ? void 0 : _a.configs) === null || _b === void 0 ? void 0 : _b[curr].config.fallbackValue) || '',
|
|
2554
2557
|
status: null
|
|
2555
2558
|
};
|
|
2556
2559
|
return acc;
|
|
2557
|
-
}, {})
|
|
2560
|
+
}, {}),
|
|
2561
|
+
apiState: {
|
|
2562
|
+
loading: false
|
|
2563
|
+
}
|
|
2558
2564
|
};
|
|
2559
2565
|
this._errors = {};
|
|
2560
2566
|
this._mounted = false;
|
|
2561
|
-
this.
|
|
2567
|
+
this.valid = true;
|
|
2568
|
+
this.persistValue = persistValue;
|
|
2562
2569
|
this.initializeObservers();
|
|
2563
2570
|
}
|
|
2564
2571
|
/**
|
|
@@ -2567,7 +2574,6 @@ class FormField {
|
|
|
2567
2574
|
* emissions to unsubscribed fields
|
|
2568
2575
|
*/
|
|
2569
2576
|
initializeObservers() {
|
|
2570
|
-
var _a;
|
|
2571
2577
|
if (!this.valueSubject$ || this.valueSubject$.closed) {
|
|
2572
2578
|
this.valueSubject$ = new SafeSubject(() => this.mounted);
|
|
2573
2579
|
}
|
|
@@ -2577,9 +2583,6 @@ class FormField {
|
|
|
2577
2583
|
if (!this.visibilitySubject$ || this.visibilitySubject$.closed) {
|
|
2578
2584
|
this.visibilitySubject$ = new SafeSubject(() => this.mounted);
|
|
2579
2585
|
}
|
|
2580
|
-
if (!this.apiSubject$ || this.apiSubject$.closed) {
|
|
2581
|
-
this.apiSubject$ = new SafeSubject(() => this.mounted);
|
|
2582
|
-
}
|
|
2583
2586
|
if (!this.propsSubject$ || this.propsSubject$.closed) {
|
|
2584
2587
|
this.propsSubject$ = new SafeSubject(() => this.mounted);
|
|
2585
2588
|
}
|
|
@@ -2589,16 +2592,9 @@ class FormField {
|
|
|
2589
2592
|
if (!this.apiEventQueueSubject$ || this.apiEventQueueSubject$.closed) {
|
|
2590
2593
|
this.apiEventQueueSubject$ = new SafeSubject(() => this.mounted);
|
|
2591
2594
|
}
|
|
2592
|
-
this.fieldState$ = combineLatest({
|
|
2593
|
-
visibility: this.visibilitySubject$.pipe(startWith(this._visibility)),
|
|
2594
|
-
props: this.propsSubject$.pipe(startWith(this._props)),
|
|
2595
|
-
errors: this.errorSubject$.pipe(startWith(Object.assign({}, ((_a = this.mapper.events) === null || _a === void 0 ? void 0 : _a.setErrorMessage) && {
|
|
2596
|
-
[this.mapper.events.setErrorMessage]: this.errorsString
|
|
2597
|
-
})))
|
|
2598
|
-
});
|
|
2599
2595
|
!this.apiEventQueueSubject$.observed && this.apiEventQueueSubject$.pipe(groupBy(({
|
|
2600
2596
|
event
|
|
2601
|
-
}) => event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultAPIdebounceTimeMS))), filter(() => this.
|
|
2597
|
+
}) => event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultAPIdebounceTimeMS))), filter(() => this.apiEventQueueSubject$ && !this.apiEventQueueSubject$.closed)).subscribe(payload => {
|
|
2602
2598
|
this.apiRequest(payload);
|
|
2603
2599
|
});
|
|
2604
2600
|
}
|
|
@@ -2616,9 +2612,8 @@ class FormField {
|
|
|
2616
2612
|
* @param {Record<string, unknown>} props - The new properties to be set.
|
|
2617
2613
|
*/
|
|
2618
2614
|
set props(props) {
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
this._props = diffProps;
|
|
2615
|
+
if (typeof props === 'undefined' || isEqual(props, this.props)) return;
|
|
2616
|
+
this._props = props;
|
|
2622
2617
|
this.propsSubject$.next(this.props);
|
|
2623
2618
|
this.templateSubject$.next({
|
|
2624
2619
|
scope: 'fields',
|
|
@@ -2627,16 +2622,17 @@ class FormField {
|
|
|
2627
2622
|
});
|
|
2628
2623
|
}
|
|
2629
2624
|
/**
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2625
|
+
* Static function to remove templates form the component props that will be shown when
|
|
2626
|
+
* the field mounts and the template routine executes, to be used on the adapter
|
|
2627
|
+
*
|
|
2628
|
+
* @param {unknown} props - the properties from the adapter components.
|
|
2629
|
+
*/
|
|
2635
2630
|
static filterProps(props) {
|
|
2636
2631
|
if (Array.isArray(props)) {
|
|
2637
2632
|
return props.filter(el => typeof el === 'string' && el.includes('${') ? false : true).map(el => FormField.filterProps(el));
|
|
2638
2633
|
}
|
|
2639
2634
|
if (typeof props === 'object' && props !== null) {
|
|
2635
|
+
if (props instanceof Date) return props;
|
|
2640
2636
|
return Object.keys(props).reduce((acc, curr) => {
|
|
2641
2637
|
const propValue = props[curr];
|
|
2642
2638
|
if (typeof propValue === 'string' && propValue.includes('${')) {
|
|
@@ -2739,12 +2735,9 @@ class FormField {
|
|
|
2739
2735
|
* sets valid field state and notifies form instance via formValidNotification$
|
|
2740
2736
|
*/
|
|
2741
2737
|
set valid(valid) {
|
|
2742
|
-
if (this.
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
fieldTrigger: this.name
|
|
2746
|
-
});
|
|
2747
|
-
}
|
|
2738
|
+
if (typeof valid !== 'boolean' && this.valid === valid) return;
|
|
2739
|
+
this._valid = valid;
|
|
2740
|
+
this.triggerFieldValidNotification();
|
|
2748
2741
|
}
|
|
2749
2742
|
/**
|
|
2750
2743
|
* Retrieves the validity status of the form field.
|
|
@@ -2754,6 +2747,18 @@ class FormField {
|
|
|
2754
2747
|
get valid() {
|
|
2755
2748
|
return this._valid;
|
|
2756
2749
|
}
|
|
2750
|
+
/**
|
|
2751
|
+
* triggers field valid notification to handle the form instance valid notification
|
|
2752
|
+
*
|
|
2753
|
+
* Note: since form unmount can occur before field unmount, this subject might already be closed by form instance
|
|
2754
|
+
* quick workaround is to check if the subject is already closed before emitting
|
|
2755
|
+
* if form instance onValid or template form.valid doesn't work properly, might be due to this workaround
|
|
2756
|
+
*/
|
|
2757
|
+
triggerFieldValidNotification() {
|
|
2758
|
+
!this.fieldValidNotification$.closed && this.fieldValidNotification$.next({
|
|
2759
|
+
fieldTrigger: this.name
|
|
2760
|
+
});
|
|
2761
|
+
}
|
|
2757
2762
|
/**
|
|
2758
2763
|
* Retrieves the error messages associated with the form field.
|
|
2759
2764
|
*
|
|
@@ -2799,13 +2804,12 @@ class FormField {
|
|
|
2799
2804
|
* @param {TApiResponse} response - The new API response data to be set.
|
|
2800
2805
|
*/
|
|
2801
2806
|
set api(response) {
|
|
2802
|
-
if (typeof response === 'undefined'
|
|
2807
|
+
if (typeof response === 'undefined') return;
|
|
2803
2808
|
this._api = response;
|
|
2804
|
-
this.apiSubject$.next(this.api);
|
|
2805
2809
|
this.templateSubject$.next({
|
|
2806
2810
|
scope: 'fields',
|
|
2807
2811
|
key: this.name,
|
|
2808
|
-
event: '
|
|
2812
|
+
event: 'ON_API_RESPONSE'
|
|
2809
2813
|
});
|
|
2810
2814
|
// this.apiResponseSubject$.next({ key: this.name });
|
|
2811
2815
|
this.emitEvents({
|
|
@@ -2813,7 +2817,20 @@ class FormField {
|
|
|
2813
2817
|
});
|
|
2814
2818
|
}
|
|
2815
2819
|
/**
|
|
2816
|
-
*
|
|
2820
|
+
* notifies templates and event binded field configurations that a request starts it's processing
|
|
2821
|
+
*/
|
|
2822
|
+
notifyApiRequest() {
|
|
2823
|
+
this._api.apiState.loading = true;
|
|
2824
|
+
this.templateSubject$.next({
|
|
2825
|
+
scope: 'fields',
|
|
2826
|
+
key: this.name,
|
|
2827
|
+
event: 'ON_API_REQUEST'
|
|
2828
|
+
});
|
|
2829
|
+
this.emitEvents({
|
|
2830
|
+
event: 'ON_API_FIELD_REQUEST'
|
|
2831
|
+
});
|
|
2832
|
+
}
|
|
2833
|
+
/** Retrieves the mounted status of the field.
|
|
2817
2834
|
*
|
|
2818
2835
|
* @returns {boolean} - the mounted status of the field.
|
|
2819
2836
|
*/
|
|
@@ -2829,6 +2846,7 @@ class FormField {
|
|
|
2829
2846
|
set mounted(mountedStatus) {
|
|
2830
2847
|
if (typeof mountedStatus === 'undefined' || mountedStatus === this.mounted) return;
|
|
2831
2848
|
this._mounted = mountedStatus;
|
|
2849
|
+
this.initializeObservers();
|
|
2832
2850
|
this.mountSubject$.next({
|
|
2833
2851
|
key: this.name,
|
|
2834
2852
|
status: this.mounted
|
|
@@ -2846,9 +2864,9 @@ class FormField {
|
|
|
2846
2864
|
valueSubscription,
|
|
2847
2865
|
propsSubscription
|
|
2848
2866
|
}) {
|
|
2867
|
+
this.mounted = true;
|
|
2849
2868
|
this.subscribeValue(valueSubscription);
|
|
2850
2869
|
this.subscribeState(propsSubscription);
|
|
2851
|
-
this.mounted = true;
|
|
2852
2870
|
this.valueSubject$.next(this.stateValue);
|
|
2853
2871
|
this.propsSubject$.next(this.props);
|
|
2854
2872
|
this.visibilitySubject$.next(this.visibility);
|
|
@@ -2866,11 +2884,12 @@ class FormField {
|
|
|
2866
2884
|
emitValue(prop) {
|
|
2867
2885
|
if (!this.visibility || !this.mounted) return;
|
|
2868
2886
|
this.value = prop.value;
|
|
2869
|
-
this.emitEvents({
|
|
2870
|
-
event: prop.event
|
|
2871
|
-
});
|
|
2872
2887
|
this.dataSubject$.next({
|
|
2873
|
-
|
|
2888
|
+
event: prop.event,
|
|
2889
|
+
fieldIndex: this.name,
|
|
2890
|
+
formIndex: this.formIndex
|
|
2891
|
+
});
|
|
2892
|
+
this.emitEvents({
|
|
2874
2893
|
event: prop.event
|
|
2875
2894
|
});
|
|
2876
2895
|
}
|
|
@@ -2929,16 +2948,17 @@ class FormField {
|
|
|
2929
2948
|
const errors = {};
|
|
2930
2949
|
const schemaValidations = (_a = this.validations) === null || _a === void 0 ? void 0 : _a.methods;
|
|
2931
2950
|
schemaValidations && Object.keys(schemaValidations).forEach(validationKey => {
|
|
2951
|
+
var _a;
|
|
2932
2952
|
const error = handleValidation(this.value, schemaValidations, validations, validationKey);
|
|
2933
2953
|
// setting valid flag
|
|
2934
2954
|
valid = !error && valid;
|
|
2935
2955
|
// setting error messages
|
|
2936
|
-
if (error && this.
|
|
2937
|
-
if (validationKey in this.
|
|
2938
|
-
const messages = this.
|
|
2956
|
+
if (error && ((_a = this.validations) === null || _a === void 0 ? void 0 : _a.messages)) {
|
|
2957
|
+
if (validationKey in this.validations.messages) {
|
|
2958
|
+
const messages = this.validations.messages;
|
|
2939
2959
|
errors[validationKey] = messages[validationKey];
|
|
2940
|
-
} else if ('default' in this.
|
|
2941
|
-
errors[validationKey] = this.
|
|
2960
|
+
} else if ('default' in this.validations.messages) {
|
|
2961
|
+
errors[validationKey] = this.validations.messages.default;
|
|
2942
2962
|
}
|
|
2943
2963
|
} else {
|
|
2944
2964
|
delete errors[validationKey];
|
|
@@ -3008,6 +3028,7 @@ class FormField {
|
|
|
3008
3028
|
}) {
|
|
3009
3029
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
3010
3030
|
return __awaiter(this, void 0, void 0, function* () {
|
|
3031
|
+
let requestMadeOnce = false;
|
|
3011
3032
|
const configRequest = config => __awaiter(this, void 0, void 0, function* () {
|
|
3012
3033
|
var _k;
|
|
3013
3034
|
try {
|
|
@@ -3033,20 +3054,23 @@ class FormField {
|
|
|
3033
3054
|
};
|
|
3034
3055
|
}
|
|
3035
3056
|
});
|
|
3036
|
-
if (!((_b = (_a = this.apiSchema) === null || _a === void 0 ? void 0 : _a.defaultConfig) === null || _b === void 0 ? void 0 : _b.events.includes(event)) && !(((_c = this.apiSchema) === null || _c === void 0 ? void 0 : _c.configs) && Object.keys((_d = this.apiSchema) === null || _d === void 0 ? void 0 : _d.configs).some(key => {
|
|
3057
|
+
if (this.api.apiState.lastEvent === 'ON_API_FIELD_RESPONSE' && event === 'ON_API_FIELD_RESPONSE' || !((_b = (_a = this.apiSchema) === null || _a === void 0 ? void 0 : _a.defaultConfig) === null || _b === void 0 ? void 0 : _b.events.includes(event)) && !(((_c = this.apiSchema) === null || _c === void 0 ? void 0 : _c.configs) && Object.keys((_d = this.apiSchema) === null || _d === void 0 ? void 0 : _d.configs).some(key => {
|
|
3037
3058
|
var _a, _b;
|
|
3038
3059
|
return (_b = (_a = this.apiSchema) === null || _a === void 0 ? void 0 : _a.configs) === null || _b === void 0 ? void 0 : _b[key].events.includes(event);
|
|
3039
3060
|
}))) return;
|
|
3040
3061
|
const responses = {
|
|
3041
3062
|
default: Object.assign({}, this.api.default),
|
|
3042
|
-
named: Object.assign({}, this.api.named)
|
|
3063
|
+
named: Object.assign({}, this.api.named),
|
|
3064
|
+
apiState: Object.assign({}, this.api.apiState)
|
|
3043
3065
|
};
|
|
3044
3066
|
const config = (_e = this.apiSchema.defaultConfig) === null || _e === void 0 ? void 0 : _e.config;
|
|
3045
3067
|
if (config && ((_g = (_f = this.apiSchema) === null || _f === void 0 ? void 0 : _f.defaultConfig) === null || _g === void 0 ? void 0 : _g.events.includes(event)) && this.checkApiRequestValidations(config)) {
|
|
3068
|
+
!requestMadeOnce && this.notifyApiRequest();
|
|
3046
3069
|
const {
|
|
3047
3070
|
response,
|
|
3048
3071
|
status
|
|
3049
3072
|
} = yield configRequest(config);
|
|
3073
|
+
requestMadeOnce = true;
|
|
3050
3074
|
responses.default = {
|
|
3051
3075
|
response,
|
|
3052
3076
|
status
|
|
@@ -3064,10 +3088,12 @@ class FormField {
|
|
|
3064
3088
|
var _l, _m, _o, _p;
|
|
3065
3089
|
const config = (_m = (_l = this.apiSchema) === null || _l === void 0 ? void 0 : _l.configs) === null || _m === void 0 ? void 0 : _m[configKey].config;
|
|
3066
3090
|
if (config && ((_p = (_o = this.apiSchema) === null || _o === void 0 ? void 0 : _o.configs) === null || _p === void 0 ? void 0 : _p[configKey].events.includes(event)) && this.checkApiRequestValidations(config)) {
|
|
3091
|
+
!requestMadeOnce && this.notifyApiRequest();
|
|
3067
3092
|
const {
|
|
3068
3093
|
response,
|
|
3069
3094
|
status
|
|
3070
3095
|
} = yield configRequest(config);
|
|
3096
|
+
requestMadeOnce = true;
|
|
3071
3097
|
return {
|
|
3072
3098
|
name: configKey,
|
|
3073
3099
|
result: {
|
|
@@ -3083,7 +3109,11 @@ class FormField {
|
|
|
3083
3109
|
});
|
|
3084
3110
|
}
|
|
3085
3111
|
}
|
|
3086
|
-
|
|
3112
|
+
if (requestMadeOnce) {
|
|
3113
|
+
responses.apiState.lastEvent = event;
|
|
3114
|
+
responses.apiState.loading = false;
|
|
3115
|
+
this.api = responses;
|
|
3116
|
+
}
|
|
3087
3117
|
});
|
|
3088
3118
|
}
|
|
3089
3119
|
/**
|
|
@@ -3098,10 +3128,17 @@ class FormField {
|
|
|
3098
3128
|
this.fieldStateSubscription$.unsubscribe();
|
|
3099
3129
|
this.propsSubject$.unsubscribe();
|
|
3100
3130
|
this.errorSubject$.unsubscribe();
|
|
3101
|
-
this.apiSubject$.unsubscribe();
|
|
3102
3131
|
this.apiEventQueueSubject$.unsubscribe();
|
|
3103
|
-
|
|
3104
|
-
|
|
3132
|
+
this.triggerFieldValidNotification();
|
|
3133
|
+
this.dataSubject$.next({
|
|
3134
|
+
event: 'ON_FIELD_UNMOUNT',
|
|
3135
|
+
fieldIndex: this.name,
|
|
3136
|
+
formIndex: this.formIndex
|
|
3137
|
+
});
|
|
3138
|
+
!this.fieldEventSubject$.closed && this.fieldEventSubject$.next({
|
|
3139
|
+
event: 'ON_FIELD_UNMOUNT',
|
|
3140
|
+
fieldName: this.name,
|
|
3141
|
+
fieldInstance: this
|
|
3105
3142
|
});
|
|
3106
3143
|
}
|
|
3107
3144
|
/**
|
|
@@ -3111,7 +3148,14 @@ class FormField {
|
|
|
3111
3148
|
* @returns {void}
|
|
3112
3149
|
*/
|
|
3113
3150
|
subscribeState(callback) {
|
|
3114
|
-
|
|
3151
|
+
var _a;
|
|
3152
|
+
this.fieldStateSubscription$ = combineLatest({
|
|
3153
|
+
visibility: this.visibilitySubject$.pipe(startWith(this.visibility)),
|
|
3154
|
+
props: this.propsSubject$.pipe(startWith(this.props)),
|
|
3155
|
+
errors: this.errorSubject$.pipe(startWith(Object.assign({}, ((_a = this.mapper.events) === null || _a === void 0 ? void 0 : _a.setErrorMessage) && {
|
|
3156
|
+
[this.mapper.events.setErrorMessage]: this.errorsString
|
|
3157
|
+
})))
|
|
3158
|
+
}).pipe(debounceTime(this.config.defaultStateRefreshTimeMS)).subscribe({
|
|
3115
3159
|
next: callback
|
|
3116
3160
|
});
|
|
3117
3161
|
}
|
|
@@ -3151,6 +3195,8 @@ class FormCore {
|
|
|
3151
3195
|
this.queuedFieldResetValuesEvents = new Map();
|
|
3152
3196
|
this.queuedFieldResetPropertyEvents = new Map();
|
|
3153
3197
|
this.queuedInitialValues = new Map();
|
|
3198
|
+
this._valid = false;
|
|
3199
|
+
this.index = entry.index;
|
|
3154
3200
|
this.schema = entry.schema;
|
|
3155
3201
|
this.fields = new Map();
|
|
3156
3202
|
this.action = entry.action || ((_a = entry.schema) === null || _a === void 0 ? void 0 : _a.action);
|
|
@@ -3163,15 +3209,20 @@ class FormCore {
|
|
|
3163
3209
|
(_h = entry.mappers) === null || _h === void 0 ? void 0 : _h.map(mapper => {
|
|
3164
3210
|
this.mappers.set(mapper.componentName, mapper);
|
|
3165
3211
|
});
|
|
3212
|
+
if ((!entry.submitSubject$ || !entry.dataSubject$ || !entry.formValidSubject$) && this.config.defaultLogVerbose) console.warn(`some formGroup events are not properly instanciated, any onData, onValid, onSubmit events managed by formGroup won't trigger on form: ${this.index}`);
|
|
3166
3213
|
this.schema && FormCore.checkIndexes(this.schema.components);
|
|
3167
3214
|
this.templateSubject$ = new Subject();
|
|
3168
|
-
this.submitSubject$ = new Subject();
|
|
3169
3215
|
this.fieldEventSubject$ = new Subject();
|
|
3170
|
-
this.dataSubject$ = new Subject();
|
|
3171
3216
|
this.mountSubject$ = new Subject();
|
|
3172
|
-
this.
|
|
3217
|
+
this.fieldValidNotification$ = new Subject();
|
|
3218
|
+
this.submitSubject$ = entry.submitSubject$ ? entry.submitSubject$ : new Subject();
|
|
3219
|
+
this.dataSubject$ = entry.dataSubject$ ? entry.dataSubject$ : new Subject();
|
|
3220
|
+
this.formValidSubject$ = entry.formValidSubject$ ? entry.formValidSubject$ : new Subject();
|
|
3173
3221
|
this.subscribedTemplates = [];
|
|
3174
3222
|
this.templateSubscription$ = this.templateSubject$.subscribe(this.refreshTemplates.bind(this));
|
|
3223
|
+
this.fieldValidNotification$.subscribe(() => {
|
|
3224
|
+
this.validateForm();
|
|
3225
|
+
});
|
|
3175
3226
|
this.mountSubject$.subscribe(this.mountActions.bind(this));
|
|
3176
3227
|
this.initialValues = entry.initialValues || ((_j = entry.schema) === null || _j === void 0 ? void 0 : _j.initialValues);
|
|
3177
3228
|
this.iVars = entry.iVars || ((_k = entry.schema) === null || _k === void 0 ? void 0 : _k.iVars) || {};
|
|
@@ -3200,8 +3251,16 @@ class FormCore {
|
|
|
3200
3251
|
key,
|
|
3201
3252
|
status
|
|
3202
3253
|
}) {
|
|
3203
|
-
var _a;
|
|
3204
3254
|
if (status) {
|
|
3255
|
+
const field = this.fields.get(key);
|
|
3256
|
+
if (!field) {
|
|
3257
|
+
/*
|
|
3258
|
+
@TODO check a better way to handle nested fields unmounted by visiblity conditions from a parent
|
|
3259
|
+
since they are dependent on adapter field recycling runtimes
|
|
3260
|
+
*/
|
|
3261
|
+
this.config.defaultLogVerbose && console.warn(`field ${key} was mounted but since it's parent has some visibility condition the field was already removed`);
|
|
3262
|
+
return;
|
|
3263
|
+
}
|
|
3205
3264
|
this.subscribeTemplates();
|
|
3206
3265
|
this.refreshTemplates({
|
|
3207
3266
|
scope: 'fields',
|
|
@@ -3211,16 +3270,12 @@ class FormCore {
|
|
|
3211
3270
|
scope: 'iVars',
|
|
3212
3271
|
event: 'ON_IVARS'
|
|
3213
3272
|
});
|
|
3214
|
-
if (!this.queuedInitialValues.has(key)) {
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
}) : field.emitEvents({
|
|
3221
|
-
event: 'ON_FIELD_MOUNT'
|
|
3222
|
-
});
|
|
3223
|
-
}
|
|
3273
|
+
if (!this.queuedInitialValues.has(key)) field.valuePropName && !field.value ? field.emitValue({
|
|
3274
|
+
event: 'ON_FIELD_MOUNT',
|
|
3275
|
+
value: ''
|
|
3276
|
+
}) : field.emitEvents({
|
|
3277
|
+
event: 'ON_FIELD_MOUNT'
|
|
3278
|
+
});
|
|
3224
3279
|
this.checkFieldEventQueues(key);
|
|
3225
3280
|
}
|
|
3226
3281
|
}
|
|
@@ -3265,16 +3320,30 @@ class FormCore {
|
|
|
3265
3320
|
});
|
|
3266
3321
|
}
|
|
3267
3322
|
/**
|
|
3268
|
-
*
|
|
3323
|
+
* Validates all form fields and sets the form valid flag
|
|
3269
3324
|
*
|
|
3270
|
-
* @returns {boolean} True if the form is valid; otherwise, false.
|
|
3271
3325
|
*/
|
|
3272
|
-
|
|
3273
|
-
if (this.fields.size === 0) return false;
|
|
3326
|
+
validateForm() {
|
|
3327
|
+
if (this.fields.size === 0) return this.valid = false;
|
|
3274
3328
|
for (const [, field] of this.fields) {
|
|
3275
|
-
if (!field.valid) return false;
|
|
3329
|
+
if (!field.valid) return this.valid = false;
|
|
3276
3330
|
}
|
|
3277
|
-
return true;
|
|
3331
|
+
return this.valid = true;
|
|
3332
|
+
}
|
|
3333
|
+
get valid() {
|
|
3334
|
+
return this._valid;
|
|
3335
|
+
}
|
|
3336
|
+
set valid(valid) {
|
|
3337
|
+
if (this._valid === valid) return;
|
|
3338
|
+
this._valid = valid;
|
|
3339
|
+
this.templateSubject$.next({
|
|
3340
|
+
event: 'ON_FORM',
|
|
3341
|
+
scope: 'form'
|
|
3342
|
+
});
|
|
3343
|
+
this.formValidSubject$.next({
|
|
3344
|
+
formIndex: this.index,
|
|
3345
|
+
valid: this.valid
|
|
3346
|
+
});
|
|
3278
3347
|
}
|
|
3279
3348
|
/**
|
|
3280
3349
|
* Subscribes to templates for dynamic updates.
|
|
@@ -3327,6 +3396,11 @@ class FormCore {
|
|
|
3327
3396
|
const value = get(this.iVars, [key, ...(property ? [property] : []), ...path]);
|
|
3328
3397
|
return value;
|
|
3329
3398
|
}
|
|
3399
|
+
case 'form':
|
|
3400
|
+
{
|
|
3401
|
+
const value = get(this, [key, ...(property ? [property] : []), ...path]);
|
|
3402
|
+
return value;
|
|
3403
|
+
}
|
|
3330
3404
|
case 'fields':
|
|
3331
3405
|
{
|
|
3332
3406
|
const field = this.fields.get(key);
|
|
@@ -3611,12 +3685,21 @@ class FormCore {
|
|
|
3611
3685
|
* and trigger the validation when it's visible
|
|
3612
3686
|
*/
|
|
3613
3687
|
if (fieldInstance.visibility) {
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3688
|
+
if (this.queuedInitialValues.has(field)) {
|
|
3689
|
+
fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.emitValue({
|
|
3690
|
+
value: this.queuedInitialValues.get(field) || '',
|
|
3691
|
+
event: 'ON_FIELD_MOUNT'
|
|
3692
|
+
});
|
|
3693
|
+
this.queuedInitialValues.delete(field);
|
|
3694
|
+
} else {
|
|
3695
|
+
fieldInstance.emitEvents({
|
|
3696
|
+
event: 'ON_FIELD_MOUNT'
|
|
3697
|
+
});
|
|
3698
|
+
}
|
|
3619
3699
|
} else {
|
|
3700
|
+
if (fieldInstance.persistValue) {
|
|
3701
|
+
this.queuedInitialValues.set(fieldInstance.name, fieldInstance.value);
|
|
3702
|
+
}
|
|
3620
3703
|
fieldInstance.value = '';
|
|
3621
3704
|
fieldInstance.valid = true;
|
|
3622
3705
|
}
|
|
@@ -3744,7 +3827,7 @@ class FormCore {
|
|
|
3744
3827
|
value
|
|
3745
3828
|
}) {
|
|
3746
3829
|
const field = this.fields.get(key);
|
|
3747
|
-
if (!field
|
|
3830
|
+
if (!field) {
|
|
3748
3831
|
this.queuedFieldResetPropertyEvents.set(key, {
|
|
3749
3832
|
property,
|
|
3750
3833
|
path,
|
|
@@ -3806,15 +3889,23 @@ class FormCore {
|
|
|
3806
3889
|
*/
|
|
3807
3890
|
addField({
|
|
3808
3891
|
fieldSchema,
|
|
3809
|
-
mapperElement
|
|
3892
|
+
mapperElement,
|
|
3893
|
+
path
|
|
3810
3894
|
}) {
|
|
3811
|
-
var _a;
|
|
3895
|
+
var _a, _b, _c, _d;
|
|
3812
3896
|
if (this.fields.has(fieldSchema.name)) {
|
|
3813
3897
|
throw new Error(`field name ${fieldSchema.name} already defined`);
|
|
3814
3898
|
}
|
|
3815
3899
|
const mapper = mapperElement || ((_a = this.mappers) === null || _a === void 0 ? void 0 : _a.get(fieldSchema.component));
|
|
3816
3900
|
if (!mapper) throw new Error(`mapper not found for ${fieldSchema.component}, add it to the mappers configuration`);
|
|
3901
|
+
if ((_b = mapper.events) === null || _b === void 0 ? void 0 : _b.setValue) {
|
|
3902
|
+
const initialValue = (_c = fieldSchema === null || fieldSchema === void 0 ? void 0 : fieldSchema.props) === null || _c === void 0 ? void 0 : _c[(_d = mapper === null || mapper === void 0 ? void 0 : mapper.events) === null || _d === void 0 ? void 0 : _d.setValue];
|
|
3903
|
+
if (!(typeof initialValue === 'undefined') && !this.queuedInitialValues.has(fieldSchema.name) && !(typeof initialValue === 'string' && initialValue.includes('${'))) {
|
|
3904
|
+
this.queuedInitialValues.set(fieldSchema.name, cloneDeep(initialValue));
|
|
3905
|
+
}
|
|
3906
|
+
}
|
|
3817
3907
|
this.fields.set(fieldSchema.name, new FormField({
|
|
3908
|
+
formIndex: this.index,
|
|
3818
3909
|
schemaComponent: fieldSchema,
|
|
3819
3910
|
mapper,
|
|
3820
3911
|
children: fieldSchema.children ? fieldSchema.children.map(el => el.name) : [],
|
|
@@ -3825,11 +3916,13 @@ class FormCore {
|
|
|
3825
3916
|
templateSubject$: this.templateSubject$,
|
|
3826
3917
|
fieldEventSubject$: this.fieldEventSubject$,
|
|
3827
3918
|
dataSubject$: this.dataSubject$,
|
|
3828
|
-
|
|
3919
|
+
fieldValidNotification$: this.fieldValidNotification$,
|
|
3829
3920
|
mountSubject$: this.mountSubject$,
|
|
3830
3921
|
config: this.config,
|
|
3831
3922
|
submitEvent: this.submit.bind(this),
|
|
3832
|
-
visibility: fieldSchema.visibility
|
|
3923
|
+
visibility: fieldSchema.visibility,
|
|
3924
|
+
persistValue: fieldSchema.persistValue,
|
|
3925
|
+
path
|
|
3833
3926
|
}));
|
|
3834
3927
|
}
|
|
3835
3928
|
/**
|
|
@@ -3859,36 +3952,16 @@ class FormCore {
|
|
|
3859
3952
|
serializeStructure(struct, path) {
|
|
3860
3953
|
if (!struct) return;
|
|
3861
3954
|
struct.forEach(structElement => {
|
|
3862
|
-
var _a
|
|
3955
|
+
var _a;
|
|
3863
3956
|
const currField = this.fields.get(structElement.name);
|
|
3864
3957
|
if (!currField) {
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
}
|
|
3871
|
-
if (!mapper) throw new Error(`mapper not found for ${structElement.component}, add it to the mappers configuration`);
|
|
3872
|
-
this.fields.set(structElement.name, new FormField({
|
|
3873
|
-
schemaComponent: structElement,
|
|
3874
|
-
mapper,
|
|
3875
|
-
path,
|
|
3876
|
-
children: structElement.children ? structElement.children.map(el => el.name) : [],
|
|
3877
|
-
validateVisibility: this.validateVisibility.bind(this),
|
|
3878
|
-
resetValue: this.resetValue.bind(this),
|
|
3879
|
-
resetProperty: this.resetProperty.bind(this),
|
|
3880
|
-
templateSubject$: this.templateSubject$,
|
|
3881
|
-
fieldEventSubject$: this.fieldEventSubject$,
|
|
3882
|
-
dataSubject$: this.dataSubject$,
|
|
3883
|
-
formValidNotification$: this.formValidNotification$,
|
|
3884
|
-
mountSubject$: this.mountSubject$,
|
|
3885
|
-
config: this.config,
|
|
3886
|
-
getFormValues: this.getFormValues.bind(this),
|
|
3887
|
-
submitEvent: this.submit.bind(this),
|
|
3888
|
-
visibility: structElement.visibility
|
|
3889
|
-
}));
|
|
3958
|
+
this.addField({
|
|
3959
|
+
fieldSchema: structElement,
|
|
3960
|
+
mapperElement: structElement.mapper,
|
|
3961
|
+
path
|
|
3962
|
+
});
|
|
3890
3963
|
} else {
|
|
3891
|
-
currField.children = ((
|
|
3964
|
+
currField.children = ((_a = structElement === null || structElement === void 0 ? void 0 : structElement.children) === null || _a === void 0 ? void 0 : _a.map(el => el.name)) || (currField === null || currField === void 0 ? void 0 : currField.children) || [];
|
|
3892
3965
|
currField.path = path;
|
|
3893
3966
|
currField.originalSchema = structElement;
|
|
3894
3967
|
currField.templateSubject$ = this.templateSubject$;
|
|
@@ -3950,13 +4023,7 @@ class FormCore {
|
|
|
3950
4023
|
* Prints the current values of all form fields.
|
|
3951
4024
|
*/
|
|
3952
4025
|
printValues() {
|
|
3953
|
-
|
|
3954
|
-
this.fields.forEach((val, key) => {
|
|
3955
|
-
if (val.value) {
|
|
3956
|
-
set(values, val.nameToSubmit || key, val.value);
|
|
3957
|
-
}
|
|
3958
|
-
});
|
|
3959
|
-
console.table(values);
|
|
4026
|
+
console.table(this.getFormValues().values);
|
|
3960
4027
|
}
|
|
3961
4028
|
/**
|
|
3962
4029
|
* Gets the current values of all form fields.
|
|
@@ -3968,7 +4035,7 @@ class FormCore {
|
|
|
3968
4035
|
const metadata = {};
|
|
3969
4036
|
const erroredFields = [];
|
|
3970
4037
|
this.fields.forEach((val, key) => {
|
|
3971
|
-
if (val.value) {
|
|
4038
|
+
if (!(typeof val.value === 'string' && val.value.length === 0) && typeof val.value !== 'undefined' && val.value !== null) {
|
|
3972
4039
|
set(values, val.nameToSubmit || key, val.value);
|
|
3973
4040
|
metadata[key] = val.metadata;
|
|
3974
4041
|
}
|
|
@@ -3980,7 +4047,7 @@ class FormCore {
|
|
|
3980
4047
|
values,
|
|
3981
4048
|
metadata,
|
|
3982
4049
|
erroredFields,
|
|
3983
|
-
isValid: this.
|
|
4050
|
+
isValid: this.valid
|
|
3984
4051
|
};
|
|
3985
4052
|
}
|
|
3986
4053
|
/**
|
|
@@ -4014,10 +4081,12 @@ class FormCore {
|
|
|
4014
4081
|
* @param {(payload: { field: string; data: TFormValues }) => void} callback callback function to call onData
|
|
4015
4082
|
*/
|
|
4016
4083
|
subscribeData(callback) {
|
|
4017
|
-
const sub = this.dataSubject$.pipe(
|
|
4018
|
-
|
|
4084
|
+
const sub = this.dataSubject$.pipe(filter(({
|
|
4085
|
+
formIndex
|
|
4086
|
+
}) => this.index === formIndex), groupBy(payload => payload.event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(({
|
|
4087
|
+
fieldIndex
|
|
4019
4088
|
}) => ({
|
|
4020
|
-
field:
|
|
4089
|
+
field: fieldIndex,
|
|
4021
4090
|
data: this.getFormValues()
|
|
4022
4091
|
}))).subscribe({
|
|
4023
4092
|
next: callback
|
|
@@ -4030,7 +4099,11 @@ class FormCore {
|
|
|
4030
4099
|
* @param {(payload: TFormValues<T>) => void} callback callback function to call when the submit action occurs
|
|
4031
4100
|
*/
|
|
4032
4101
|
subscribeOnSubmit(callback) {
|
|
4033
|
-
const sub = this.submitSubject$.
|
|
4102
|
+
const sub = this.submitSubject$.pipe(filter(({
|
|
4103
|
+
formIndex
|
|
4104
|
+
}) => formIndex === this.index), map(({
|
|
4105
|
+
values
|
|
4106
|
+
}) => values)).subscribe({
|
|
4034
4107
|
next: callback
|
|
4035
4108
|
});
|
|
4036
4109
|
return sub;
|
|
@@ -4041,12 +4114,15 @@ class FormCore {
|
|
|
4041
4114
|
* @param {(payload: TFormValidationPayload) => void} callback callback function to call onValid
|
|
4042
4115
|
*/
|
|
4043
4116
|
subscribeFormValidation(callback) {
|
|
4044
|
-
const sub = this.
|
|
4045
|
-
|
|
4046
|
-
}) => ({
|
|
4047
|
-
|
|
4048
|
-
valid: this.
|
|
4049
|
-
})), distinctUntilKeyChanged('valid')
|
|
4117
|
+
const sub = this.formValidSubject$.pipe(filter(({
|
|
4118
|
+
formIndex
|
|
4119
|
+
}) => this.index === formIndex), debounceTime(this.config.defaultStateRefreshTimeMS), map(() => ({
|
|
4120
|
+
formIndex: this.index,
|
|
4121
|
+
valid: this.valid
|
|
4122
|
+
})), distinctUntilKeyChanged('valid'), startWith({
|
|
4123
|
+
formIndex: this.index,
|
|
4124
|
+
valid: this.valid
|
|
4125
|
+
})).subscribe({
|
|
4050
4126
|
next: callback
|
|
4051
4127
|
});
|
|
4052
4128
|
return sub;
|
|
@@ -4059,21 +4135,21 @@ class FormCore {
|
|
|
4059
4135
|
field.emitEvents({
|
|
4060
4136
|
event: 'ON_FIELD_VALIDATION'
|
|
4061
4137
|
});
|
|
4062
|
-
console.log(`${field.name} is ${field.valid}`);
|
|
4063
4138
|
});
|
|
4064
|
-
if (!this.
|
|
4139
|
+
if (!this.valid) return;
|
|
4065
4140
|
const values = this.getFormValues();
|
|
4066
|
-
this.submitSubject$.next(
|
|
4141
|
+
this.submitSubject$.next({
|
|
4142
|
+
formIndex: this.index,
|
|
4143
|
+
values
|
|
4144
|
+
});
|
|
4067
4145
|
}
|
|
4068
4146
|
/**
|
|
4069
4147
|
* recycles all the Suscriptions, to be called from the adapter when the form leaves the page
|
|
4070
4148
|
*/
|
|
4071
4149
|
destroy() {
|
|
4072
|
-
this.submitSubject$.unsubscribe();
|
|
4073
4150
|
this.templateSubscription$.unsubscribe();
|
|
4074
4151
|
this.fieldEventSubject$.unsubscribe();
|
|
4075
|
-
this.
|
|
4076
|
-
this.formValidNotification$.unsubscribe();
|
|
4152
|
+
this.fieldValidNotification$.unsubscribe();
|
|
4077
4153
|
this.fields.forEach(field => field.destroyField());
|
|
4078
4154
|
}
|
|
4079
4155
|
}
|
|
@@ -4116,6 +4192,9 @@ class FormGroup {
|
|
|
4116
4192
|
var _a, _b, _c, _d, _e;
|
|
4117
4193
|
this.destroy = () => {
|
|
4118
4194
|
this.forms.forEach(form => form.destroy());
|
|
4195
|
+
this.dataSubject$.unsubscribe();
|
|
4196
|
+
this.formValidSubject$.unsubscribe();
|
|
4197
|
+
this.submitSubject$.unsubscribe();
|
|
4119
4198
|
};
|
|
4120
4199
|
this.forms = new Map();
|
|
4121
4200
|
this.config = {
|
|
@@ -4123,6 +4202,9 @@ class FormGroup {
|
|
|
4123
4202
|
defaultStateRefreshTimeMS: Number((_c = entry === null || entry === void 0 ? void 0 : entry.config) === null || _c === void 0 ? void 0 : _c.defaultStateRefreshTimeMS) ? Number((_d = entry === null || entry === void 0 ? void 0 : entry.config) === null || _d === void 0 ? void 0 : _d.defaultStateRefreshTimeMS) : DEFAULT_STATE_REFRESH_TIME,
|
|
4124
4203
|
defaultLogVerbose: ((_e = entry === null || entry === void 0 ? void 0 : entry.config) === null || _e === void 0 ? void 0 : _e.defaultLogVerbose) ? entry.config.defaultLogVerbose : DEFAULT_LOG_VERBOSE
|
|
4125
4204
|
};
|
|
4205
|
+
this.dataSubject$ = new Subject();
|
|
4206
|
+
this.formValidSubject$ = new Subject();
|
|
4207
|
+
this.submitSubject$ = new Subject();
|
|
4126
4208
|
}
|
|
4127
4209
|
/**
|
|
4128
4210
|
* Creates an empty form with given index
|
|
@@ -4134,14 +4216,13 @@ class FormGroup {
|
|
|
4134
4216
|
index,
|
|
4135
4217
|
mappers
|
|
4136
4218
|
}) {
|
|
4137
|
-
const formInstance = new FormCore({
|
|
4138
|
-
index,
|
|
4139
|
-
mappers,
|
|
4140
|
-
config: this.config
|
|
4141
|
-
});
|
|
4142
4219
|
this.addForm({
|
|
4143
4220
|
key: index,
|
|
4144
|
-
|
|
4221
|
+
params: {
|
|
4222
|
+
index,
|
|
4223
|
+
mappers,
|
|
4224
|
+
config: this.config
|
|
4225
|
+
}
|
|
4145
4226
|
});
|
|
4146
4227
|
}
|
|
4147
4228
|
/**
|
|
@@ -4153,11 +4234,16 @@ class FormGroup {
|
|
|
4153
4234
|
*/
|
|
4154
4235
|
addForm({
|
|
4155
4236
|
key,
|
|
4156
|
-
|
|
4237
|
+
params
|
|
4157
4238
|
}) {
|
|
4158
4239
|
this.checkIndexes({
|
|
4159
|
-
key
|
|
4240
|
+
key: key
|
|
4160
4241
|
});
|
|
4242
|
+
const formInstance = new FormCore(Object.assign(Object.assign({}, params), {
|
|
4243
|
+
dataSubject$: this.dataSubject$,
|
|
4244
|
+
formValidSubject$: this.formValidSubject$,
|
|
4245
|
+
submitSubject$: this.submitSubject$
|
|
4246
|
+
}));
|
|
4161
4247
|
if (!formInstance.config) {
|
|
4162
4248
|
formInstance.config = this.config;
|
|
4163
4249
|
}
|
|
@@ -4199,10 +4285,10 @@ class FormGroup {
|
|
|
4199
4285
|
formIndex,
|
|
4200
4286
|
fieldIndex
|
|
4201
4287
|
}) {
|
|
4202
|
-
var _a;
|
|
4203
4288
|
const form = this.forms.get(formIndex);
|
|
4204
|
-
|
|
4205
|
-
|
|
4289
|
+
form === null || form === void 0 ? void 0 : form.removeField({
|
|
4290
|
+
key: fieldIndex
|
|
4291
|
+
});
|
|
4206
4292
|
if ((form === null || form === void 0 ? void 0 : form.fields.size) === 0) {
|
|
4207
4293
|
this.removeForm({
|
|
4208
4294
|
key: formIndex
|
|
@@ -4260,52 +4346,49 @@ class FormGroup {
|
|
|
4260
4346
|
ids,
|
|
4261
4347
|
callback
|
|
4262
4348
|
}) {
|
|
4263
|
-
const
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4349
|
+
const sub = this.dataSubject$.pipe(filter(({
|
|
4350
|
+
formIndex
|
|
4351
|
+
}) => ids.includes(formIndex)), groupBy(({
|
|
4352
|
+
event,
|
|
4353
|
+
formIndex
|
|
4354
|
+
}) => `${event}.${formIndex}`), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(({
|
|
4355
|
+
fieldIndex,
|
|
4356
|
+
formIndex
|
|
4357
|
+
}) => ids.reduce((acc, curr) => {
|
|
4358
|
+
const formInstance = this.forms.get(curr);
|
|
4359
|
+
if (formInstance) {
|
|
4360
|
+
acc[curr] = {
|
|
4361
|
+
formId: formIndex,
|
|
4362
|
+
formField: fieldIndex,
|
|
4363
|
+
values: formInstance.getFormValues()
|
|
4272
4364
|
};
|
|
4273
|
-
}), startWith({
|
|
4274
|
-
formField: null,
|
|
4275
|
-
values: (_b = this.forms.get(formId)) === null || _b === void 0 ? void 0 : _b.getFormValues()
|
|
4276
|
-
}));
|
|
4277
|
-
if (sub) {
|
|
4278
|
-
acc[formId] = sub;
|
|
4279
|
-
} else {
|
|
4280
|
-
this.config.defaultLogVerbose && console.warn(`failed to register form id ${formId}`);
|
|
4281
4365
|
}
|
|
4282
4366
|
return acc;
|
|
4283
|
-
}, {});
|
|
4284
|
-
const sub = combineLatest(subs).subscribe(callback);
|
|
4367
|
+
}, {}))).subscribe(callback);
|
|
4285
4368
|
return sub;
|
|
4286
4369
|
}
|
|
4287
4370
|
onValidSubscription({
|
|
4288
4371
|
ids,
|
|
4289
4372
|
callback
|
|
4290
4373
|
}) {
|
|
4291
|
-
const
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4374
|
+
const sub = this.formValidSubject$.pipe(filter(({
|
|
4375
|
+
formIndex
|
|
4376
|
+
}) => ids.includes(formIndex)), groupBy(({
|
|
4377
|
+
formIndex
|
|
4378
|
+
}) => formIndex), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), startWith({
|
|
4379
|
+
fieldTrigger: null
|
|
4380
|
+
}), map(() => ({
|
|
4381
|
+
groupValid: ids.every(id => {
|
|
4296
4382
|
var _a;
|
|
4297
|
-
return ((_a = this.forms.get(
|
|
4298
|
-
}),
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
const sub = combineLatest(subs).pipe(map(forms => ({
|
|
4307
|
-
groupValid: Object.keys(forms).every(formId => forms[formId]),
|
|
4308
|
-
forms
|
|
4383
|
+
return !this.forms.get(id) || ((_a = this.forms.get(id)) === null || _a === void 0 ? void 0 : _a.valid);
|
|
4384
|
+
}),
|
|
4385
|
+
forms: ids.reduce((acc, curr) => {
|
|
4386
|
+
const formInstance = this.forms.get(curr);
|
|
4387
|
+
if (formInstance) {
|
|
4388
|
+
acc[curr] = formInstance.valid;
|
|
4389
|
+
}
|
|
4390
|
+
return acc;
|
|
4391
|
+
}, {})
|
|
4309
4392
|
}))).subscribe(callback);
|
|
4310
4393
|
return sub;
|
|
4311
4394
|
}
|
|
@@ -4313,17 +4396,15 @@ class FormGroup {
|
|
|
4313
4396
|
ids,
|
|
4314
4397
|
callback
|
|
4315
4398
|
}) {
|
|
4316
|
-
const
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
this.config.defaultLogVerbose && console.warn(`failed to register form id ${formId}`);
|
|
4399
|
+
const sub = this.submitSubject$.pipe(filter(({
|
|
4400
|
+
formIndex
|
|
4401
|
+
}) => ids.includes(formIndex)), map(() => ids.reduce((acc, curr) => {
|
|
4402
|
+
const formInstance = this.forms.get(curr);
|
|
4403
|
+
if (formInstance) {
|
|
4404
|
+
acc[curr] = formInstance.getFormValues();
|
|
4323
4405
|
}
|
|
4324
4406
|
return acc;
|
|
4325
|
-
}, {});
|
|
4326
|
-
const sub = combineLatest(subs).pipe(skip(1)).subscribe(callback);
|
|
4407
|
+
}, {}))).subscribe(callback);
|
|
4327
4408
|
return sub;
|
|
4328
4409
|
}
|
|
4329
4410
|
}
|