@bolttech/form-engine-core 1.0.0-beta.9 → 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 +277 -204
- 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 +23 -17
- 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',
|
|
@@ -2637,6 +2632,7 @@ class FormField {
|
|
|
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
|
*/
|
|
@@ -2867,11 +2884,12 @@ class FormField {
|
|
|
2867
2884
|
emitValue(prop) {
|
|
2868
2885
|
if (!this.visibility || !this.mounted) return;
|
|
2869
2886
|
this.value = prop.value;
|
|
2870
|
-
this.emitEvents({
|
|
2871
|
-
event: prop.event
|
|
2872
|
-
});
|
|
2873
2887
|
this.dataSubject$.next({
|
|
2874
|
-
|
|
2888
|
+
event: prop.event,
|
|
2889
|
+
fieldIndex: this.name,
|
|
2890
|
+
formIndex: this.formIndex
|
|
2891
|
+
});
|
|
2892
|
+
this.emitEvents({
|
|
2875
2893
|
event: prop.event
|
|
2876
2894
|
});
|
|
2877
2895
|
}
|
|
@@ -2930,16 +2948,17 @@ class FormField {
|
|
|
2930
2948
|
const errors = {};
|
|
2931
2949
|
const schemaValidations = (_a = this.validations) === null || _a === void 0 ? void 0 : _a.methods;
|
|
2932
2950
|
schemaValidations && Object.keys(schemaValidations).forEach(validationKey => {
|
|
2951
|
+
var _a;
|
|
2933
2952
|
const error = handleValidation(this.value, schemaValidations, validations, validationKey);
|
|
2934
2953
|
// setting valid flag
|
|
2935
2954
|
valid = !error && valid;
|
|
2936
2955
|
// setting error messages
|
|
2937
|
-
if (error && this.
|
|
2938
|
-
if (validationKey in this.
|
|
2939
|
-
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;
|
|
2940
2959
|
errors[validationKey] = messages[validationKey];
|
|
2941
|
-
} else if ('default' in this.
|
|
2942
|
-
errors[validationKey] = this.
|
|
2960
|
+
} else if ('default' in this.validations.messages) {
|
|
2961
|
+
errors[validationKey] = this.validations.messages.default;
|
|
2943
2962
|
}
|
|
2944
2963
|
} else {
|
|
2945
2964
|
delete errors[validationKey];
|
|
@@ -3009,6 +3028,7 @@ class FormField {
|
|
|
3009
3028
|
}) {
|
|
3010
3029
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
3011
3030
|
return __awaiter(this, void 0, void 0, function* () {
|
|
3031
|
+
let requestMadeOnce = false;
|
|
3012
3032
|
const configRequest = config => __awaiter(this, void 0, void 0, function* () {
|
|
3013
3033
|
var _k;
|
|
3014
3034
|
try {
|
|
@@ -3034,20 +3054,23 @@ class FormField {
|
|
|
3034
3054
|
};
|
|
3035
3055
|
}
|
|
3036
3056
|
});
|
|
3037
|
-
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 => {
|
|
3038
3058
|
var _a, _b;
|
|
3039
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);
|
|
3040
3060
|
}))) return;
|
|
3041
3061
|
const responses = {
|
|
3042
3062
|
default: Object.assign({}, this.api.default),
|
|
3043
|
-
named: Object.assign({}, this.api.named)
|
|
3063
|
+
named: Object.assign({}, this.api.named),
|
|
3064
|
+
apiState: Object.assign({}, this.api.apiState)
|
|
3044
3065
|
};
|
|
3045
3066
|
const config = (_e = this.apiSchema.defaultConfig) === null || _e === void 0 ? void 0 : _e.config;
|
|
3046
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();
|
|
3047
3069
|
const {
|
|
3048
3070
|
response,
|
|
3049
3071
|
status
|
|
3050
3072
|
} = yield configRequest(config);
|
|
3073
|
+
requestMadeOnce = true;
|
|
3051
3074
|
responses.default = {
|
|
3052
3075
|
response,
|
|
3053
3076
|
status
|
|
@@ -3065,10 +3088,12 @@ class FormField {
|
|
|
3065
3088
|
var _l, _m, _o, _p;
|
|
3066
3089
|
const config = (_m = (_l = this.apiSchema) === null || _l === void 0 ? void 0 : _l.configs) === null || _m === void 0 ? void 0 : _m[configKey].config;
|
|
3067
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();
|
|
3068
3092
|
const {
|
|
3069
3093
|
response,
|
|
3070
3094
|
status
|
|
3071
3095
|
} = yield configRequest(config);
|
|
3096
|
+
requestMadeOnce = true;
|
|
3072
3097
|
return {
|
|
3073
3098
|
name: configKey,
|
|
3074
3099
|
result: {
|
|
@@ -3084,7 +3109,11 @@ class FormField {
|
|
|
3084
3109
|
});
|
|
3085
3110
|
}
|
|
3086
3111
|
}
|
|
3087
|
-
|
|
3112
|
+
if (requestMadeOnce) {
|
|
3113
|
+
responses.apiState.lastEvent = event;
|
|
3114
|
+
responses.apiState.loading = false;
|
|
3115
|
+
this.api = responses;
|
|
3116
|
+
}
|
|
3088
3117
|
});
|
|
3089
3118
|
}
|
|
3090
3119
|
/**
|
|
@@ -3099,10 +3128,17 @@ class FormField {
|
|
|
3099
3128
|
this.fieldStateSubscription$.unsubscribe();
|
|
3100
3129
|
this.propsSubject$.unsubscribe();
|
|
3101
3130
|
this.errorSubject$.unsubscribe();
|
|
3102
|
-
this.apiSubject$.unsubscribe();
|
|
3103
3131
|
this.apiEventQueueSubject$.unsubscribe();
|
|
3104
|
-
|
|
3105
|
-
|
|
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
|
|
3106
3142
|
});
|
|
3107
3143
|
}
|
|
3108
3144
|
/**
|
|
@@ -3112,7 +3148,14 @@ class FormField {
|
|
|
3112
3148
|
* @returns {void}
|
|
3113
3149
|
*/
|
|
3114
3150
|
subscribeState(callback) {
|
|
3115
|
-
|
|
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({
|
|
3116
3159
|
next: callback
|
|
3117
3160
|
});
|
|
3118
3161
|
}
|
|
@@ -3152,6 +3195,8 @@ class FormCore {
|
|
|
3152
3195
|
this.queuedFieldResetValuesEvents = new Map();
|
|
3153
3196
|
this.queuedFieldResetPropertyEvents = new Map();
|
|
3154
3197
|
this.queuedInitialValues = new Map();
|
|
3198
|
+
this._valid = false;
|
|
3199
|
+
this.index = entry.index;
|
|
3155
3200
|
this.schema = entry.schema;
|
|
3156
3201
|
this.fields = new Map();
|
|
3157
3202
|
this.action = entry.action || ((_a = entry.schema) === null || _a === void 0 ? void 0 : _a.action);
|
|
@@ -3164,15 +3209,20 @@ class FormCore {
|
|
|
3164
3209
|
(_h = entry.mappers) === null || _h === void 0 ? void 0 : _h.map(mapper => {
|
|
3165
3210
|
this.mappers.set(mapper.componentName, mapper);
|
|
3166
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}`);
|
|
3167
3213
|
this.schema && FormCore.checkIndexes(this.schema.components);
|
|
3168
3214
|
this.templateSubject$ = new Subject();
|
|
3169
|
-
this.submitSubject$ = new Subject();
|
|
3170
3215
|
this.fieldEventSubject$ = new Subject();
|
|
3171
|
-
this.dataSubject$ = new Subject();
|
|
3172
3216
|
this.mountSubject$ = new Subject();
|
|
3173
|
-
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();
|
|
3174
3221
|
this.subscribedTemplates = [];
|
|
3175
3222
|
this.templateSubscription$ = this.templateSubject$.subscribe(this.refreshTemplates.bind(this));
|
|
3223
|
+
this.fieldValidNotification$.subscribe(() => {
|
|
3224
|
+
this.validateForm();
|
|
3225
|
+
});
|
|
3176
3226
|
this.mountSubject$.subscribe(this.mountActions.bind(this));
|
|
3177
3227
|
this.initialValues = entry.initialValues || ((_j = entry.schema) === null || _j === void 0 ? void 0 : _j.initialValues);
|
|
3178
3228
|
this.iVars = entry.iVars || ((_k = entry.schema) === null || _k === void 0 ? void 0 : _k.iVars) || {};
|
|
@@ -3201,7 +3251,6 @@ class FormCore {
|
|
|
3201
3251
|
key,
|
|
3202
3252
|
status
|
|
3203
3253
|
}) {
|
|
3204
|
-
var _a;
|
|
3205
3254
|
if (status) {
|
|
3206
3255
|
const field = this.fields.get(key);
|
|
3207
3256
|
if (!field) {
|
|
@@ -3209,7 +3258,7 @@ class FormCore {
|
|
|
3209
3258
|
@TODO check a better way to handle nested fields unmounted by visiblity conditions from a parent
|
|
3210
3259
|
since they are dependent on adapter field recycling runtimes
|
|
3211
3260
|
*/
|
|
3212
|
-
this.config.defaultLogVerbose && console.
|
|
3261
|
+
this.config.defaultLogVerbose && console.warn(`field ${key} was mounted but since it's parent has some visibility condition the field was already removed`);
|
|
3213
3262
|
return;
|
|
3214
3263
|
}
|
|
3215
3264
|
this.subscribeTemplates();
|
|
@@ -3221,15 +3270,12 @@ class FormCore {
|
|
|
3221
3270
|
scope: 'iVars',
|
|
3222
3271
|
event: 'ON_IVARS'
|
|
3223
3272
|
});
|
|
3224
|
-
if (!this.queuedInitialValues.has(key)) {
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
event: 'ON_FIELD_MOUNT'
|
|
3231
|
-
});
|
|
3232
|
-
}
|
|
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
|
+
});
|
|
3233
3279
|
this.checkFieldEventQueues(key);
|
|
3234
3280
|
}
|
|
3235
3281
|
}
|
|
@@ -3274,16 +3320,30 @@ class FormCore {
|
|
|
3274
3320
|
});
|
|
3275
3321
|
}
|
|
3276
3322
|
/**
|
|
3277
|
-
*
|
|
3323
|
+
* Validates all form fields and sets the form valid flag
|
|
3278
3324
|
*
|
|
3279
|
-
* @returns {boolean} True if the form is valid; otherwise, false.
|
|
3280
3325
|
*/
|
|
3281
|
-
|
|
3282
|
-
if (this.fields.size === 0) return false;
|
|
3326
|
+
validateForm() {
|
|
3327
|
+
if (this.fields.size === 0) return this.valid = false;
|
|
3283
3328
|
for (const [, field] of this.fields) {
|
|
3284
|
-
if (!field.valid) return false;
|
|
3329
|
+
if (!field.valid) return this.valid = false;
|
|
3285
3330
|
}
|
|
3286
|
-
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
|
+
});
|
|
3287
3347
|
}
|
|
3288
3348
|
/**
|
|
3289
3349
|
* Subscribes to templates for dynamic updates.
|
|
@@ -3336,6 +3396,11 @@ class FormCore {
|
|
|
3336
3396
|
const value = get(this.iVars, [key, ...(property ? [property] : []), ...path]);
|
|
3337
3397
|
return value;
|
|
3338
3398
|
}
|
|
3399
|
+
case 'form':
|
|
3400
|
+
{
|
|
3401
|
+
const value = get(this, [key, ...(property ? [property] : []), ...path]);
|
|
3402
|
+
return value;
|
|
3403
|
+
}
|
|
3339
3404
|
case 'fields':
|
|
3340
3405
|
{
|
|
3341
3406
|
const field = this.fields.get(key);
|
|
@@ -3620,12 +3685,21 @@ class FormCore {
|
|
|
3620
3685
|
* and trigger the validation when it's visible
|
|
3621
3686
|
*/
|
|
3622
3687
|
if (fieldInstance.visibility) {
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
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
|
+
}
|
|
3628
3699
|
} else {
|
|
3700
|
+
if (fieldInstance.persistValue) {
|
|
3701
|
+
this.queuedInitialValues.set(fieldInstance.name, fieldInstance.value);
|
|
3702
|
+
}
|
|
3629
3703
|
fieldInstance.value = '';
|
|
3630
3704
|
fieldInstance.valid = true;
|
|
3631
3705
|
}
|
|
@@ -3753,7 +3827,7 @@ class FormCore {
|
|
|
3753
3827
|
value
|
|
3754
3828
|
}) {
|
|
3755
3829
|
const field = this.fields.get(key);
|
|
3756
|
-
if (!field
|
|
3830
|
+
if (!field) {
|
|
3757
3831
|
this.queuedFieldResetPropertyEvents.set(key, {
|
|
3758
3832
|
property,
|
|
3759
3833
|
path,
|
|
@@ -3815,15 +3889,23 @@ class FormCore {
|
|
|
3815
3889
|
*/
|
|
3816
3890
|
addField({
|
|
3817
3891
|
fieldSchema,
|
|
3818
|
-
mapperElement
|
|
3892
|
+
mapperElement,
|
|
3893
|
+
path
|
|
3819
3894
|
}) {
|
|
3820
|
-
var _a;
|
|
3895
|
+
var _a, _b, _c, _d;
|
|
3821
3896
|
if (this.fields.has(fieldSchema.name)) {
|
|
3822
3897
|
throw new Error(`field name ${fieldSchema.name} already defined`);
|
|
3823
3898
|
}
|
|
3824
3899
|
const mapper = mapperElement || ((_a = this.mappers) === null || _a === void 0 ? void 0 : _a.get(fieldSchema.component));
|
|
3825
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
|
+
}
|
|
3826
3907
|
this.fields.set(fieldSchema.name, new FormField({
|
|
3908
|
+
formIndex: this.index,
|
|
3827
3909
|
schemaComponent: fieldSchema,
|
|
3828
3910
|
mapper,
|
|
3829
3911
|
children: fieldSchema.children ? fieldSchema.children.map(el => el.name) : [],
|
|
@@ -3834,11 +3916,13 @@ class FormCore {
|
|
|
3834
3916
|
templateSubject$: this.templateSubject$,
|
|
3835
3917
|
fieldEventSubject$: this.fieldEventSubject$,
|
|
3836
3918
|
dataSubject$: this.dataSubject$,
|
|
3837
|
-
|
|
3919
|
+
fieldValidNotification$: this.fieldValidNotification$,
|
|
3838
3920
|
mountSubject$: this.mountSubject$,
|
|
3839
3921
|
config: this.config,
|
|
3840
3922
|
submitEvent: this.submit.bind(this),
|
|
3841
|
-
visibility: fieldSchema.visibility
|
|
3923
|
+
visibility: fieldSchema.visibility,
|
|
3924
|
+
persistValue: fieldSchema.persistValue,
|
|
3925
|
+
path
|
|
3842
3926
|
}));
|
|
3843
3927
|
}
|
|
3844
3928
|
/**
|
|
@@ -3868,36 +3952,16 @@ class FormCore {
|
|
|
3868
3952
|
serializeStructure(struct, path) {
|
|
3869
3953
|
if (!struct) return;
|
|
3870
3954
|
struct.forEach(structElement => {
|
|
3871
|
-
var _a
|
|
3955
|
+
var _a;
|
|
3872
3956
|
const currField = this.fields.get(structElement.name);
|
|
3873
3957
|
if (!currField) {
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
}
|
|
3880
|
-
if (!mapper) throw new Error(`mapper not found for ${structElement.component}, add it to the mappers configuration`);
|
|
3881
|
-
this.fields.set(structElement.name, new FormField({
|
|
3882
|
-
schemaComponent: structElement,
|
|
3883
|
-
mapper,
|
|
3884
|
-
path,
|
|
3885
|
-
children: structElement.children ? structElement.children.map(el => el.name) : [],
|
|
3886
|
-
validateVisibility: this.validateVisibility.bind(this),
|
|
3887
|
-
resetValue: this.resetValue.bind(this),
|
|
3888
|
-
resetProperty: this.resetProperty.bind(this),
|
|
3889
|
-
templateSubject$: this.templateSubject$,
|
|
3890
|
-
fieldEventSubject$: this.fieldEventSubject$,
|
|
3891
|
-
dataSubject$: this.dataSubject$,
|
|
3892
|
-
formValidNotification$: this.formValidNotification$,
|
|
3893
|
-
mountSubject$: this.mountSubject$,
|
|
3894
|
-
config: this.config,
|
|
3895
|
-
getFormValues: this.getFormValues.bind(this),
|
|
3896
|
-
submitEvent: this.submit.bind(this),
|
|
3897
|
-
visibility: structElement.visibility
|
|
3898
|
-
}));
|
|
3958
|
+
this.addField({
|
|
3959
|
+
fieldSchema: structElement,
|
|
3960
|
+
mapperElement: structElement.mapper,
|
|
3961
|
+
path
|
|
3962
|
+
});
|
|
3899
3963
|
} else {
|
|
3900
|
-
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) || [];
|
|
3901
3965
|
currField.path = path;
|
|
3902
3966
|
currField.originalSchema = structElement;
|
|
3903
3967
|
currField.templateSubject$ = this.templateSubject$;
|
|
@@ -3959,13 +4023,7 @@ class FormCore {
|
|
|
3959
4023
|
* Prints the current values of all form fields.
|
|
3960
4024
|
*/
|
|
3961
4025
|
printValues() {
|
|
3962
|
-
|
|
3963
|
-
this.fields.forEach((val, key) => {
|
|
3964
|
-
if (val.value) {
|
|
3965
|
-
set(values, val.nameToSubmit || key, val.value);
|
|
3966
|
-
}
|
|
3967
|
-
});
|
|
3968
|
-
console.table(values);
|
|
4026
|
+
console.table(this.getFormValues().values);
|
|
3969
4027
|
}
|
|
3970
4028
|
/**
|
|
3971
4029
|
* Gets the current values of all form fields.
|
|
@@ -3977,7 +4035,7 @@ class FormCore {
|
|
|
3977
4035
|
const metadata = {};
|
|
3978
4036
|
const erroredFields = [];
|
|
3979
4037
|
this.fields.forEach((val, key) => {
|
|
3980
|
-
if (val.value) {
|
|
4038
|
+
if (!(typeof val.value === 'string' && val.value.length === 0) && typeof val.value !== 'undefined' && val.value !== null) {
|
|
3981
4039
|
set(values, val.nameToSubmit || key, val.value);
|
|
3982
4040
|
metadata[key] = val.metadata;
|
|
3983
4041
|
}
|
|
@@ -3989,7 +4047,7 @@ class FormCore {
|
|
|
3989
4047
|
values,
|
|
3990
4048
|
metadata,
|
|
3991
4049
|
erroredFields,
|
|
3992
|
-
isValid: this.
|
|
4050
|
+
isValid: this.valid
|
|
3993
4051
|
};
|
|
3994
4052
|
}
|
|
3995
4053
|
/**
|
|
@@ -4023,10 +4081,12 @@ class FormCore {
|
|
|
4023
4081
|
* @param {(payload: { field: string; data: TFormValues }) => void} callback callback function to call onData
|
|
4024
4082
|
*/
|
|
4025
4083
|
subscribeData(callback) {
|
|
4026
|
-
const sub = this.dataSubject$.pipe(
|
|
4027
|
-
|
|
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
|
|
4028
4088
|
}) => ({
|
|
4029
|
-
field:
|
|
4089
|
+
field: fieldIndex,
|
|
4030
4090
|
data: this.getFormValues()
|
|
4031
4091
|
}))).subscribe({
|
|
4032
4092
|
next: callback
|
|
@@ -4039,7 +4099,11 @@ class FormCore {
|
|
|
4039
4099
|
* @param {(payload: TFormValues<T>) => void} callback callback function to call when the submit action occurs
|
|
4040
4100
|
*/
|
|
4041
4101
|
subscribeOnSubmit(callback) {
|
|
4042
|
-
const sub = this.submitSubject$.
|
|
4102
|
+
const sub = this.submitSubject$.pipe(filter(({
|
|
4103
|
+
formIndex
|
|
4104
|
+
}) => formIndex === this.index), map(({
|
|
4105
|
+
values
|
|
4106
|
+
}) => values)).subscribe({
|
|
4043
4107
|
next: callback
|
|
4044
4108
|
});
|
|
4045
4109
|
return sub;
|
|
@@ -4050,12 +4114,15 @@ class FormCore {
|
|
|
4050
4114
|
* @param {(payload: TFormValidationPayload) => void} callback callback function to call onValid
|
|
4051
4115
|
*/
|
|
4052
4116
|
subscribeFormValidation(callback) {
|
|
4053
|
-
const sub = this.
|
|
4054
|
-
|
|
4055
|
-
}) => ({
|
|
4056
|
-
|
|
4057
|
-
valid: this.
|
|
4058
|
-
})), 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({
|
|
4059
4126
|
next: callback
|
|
4060
4127
|
});
|
|
4061
4128
|
return sub;
|
|
@@ -4069,19 +4136,20 @@ class FormCore {
|
|
|
4069
4136
|
event: 'ON_FIELD_VALIDATION'
|
|
4070
4137
|
});
|
|
4071
4138
|
});
|
|
4072
|
-
if (!this.
|
|
4139
|
+
if (!this.valid) return;
|
|
4073
4140
|
const values = this.getFormValues();
|
|
4074
|
-
this.submitSubject$.next(
|
|
4141
|
+
this.submitSubject$.next({
|
|
4142
|
+
formIndex: this.index,
|
|
4143
|
+
values
|
|
4144
|
+
});
|
|
4075
4145
|
}
|
|
4076
4146
|
/**
|
|
4077
4147
|
* recycles all the Suscriptions, to be called from the adapter when the form leaves the page
|
|
4078
4148
|
*/
|
|
4079
4149
|
destroy() {
|
|
4080
|
-
this.submitSubject$.unsubscribe();
|
|
4081
4150
|
this.templateSubscription$.unsubscribe();
|
|
4082
4151
|
this.fieldEventSubject$.unsubscribe();
|
|
4083
|
-
this.
|
|
4084
|
-
this.formValidNotification$.unsubscribe();
|
|
4152
|
+
this.fieldValidNotification$.unsubscribe();
|
|
4085
4153
|
this.fields.forEach(field => field.destroyField());
|
|
4086
4154
|
}
|
|
4087
4155
|
}
|
|
@@ -4124,6 +4192,9 @@ class FormGroup {
|
|
|
4124
4192
|
var _a, _b, _c, _d, _e;
|
|
4125
4193
|
this.destroy = () => {
|
|
4126
4194
|
this.forms.forEach(form => form.destroy());
|
|
4195
|
+
this.dataSubject$.unsubscribe();
|
|
4196
|
+
this.formValidSubject$.unsubscribe();
|
|
4197
|
+
this.submitSubject$.unsubscribe();
|
|
4127
4198
|
};
|
|
4128
4199
|
this.forms = new Map();
|
|
4129
4200
|
this.config = {
|
|
@@ -4131,6 +4202,9 @@ class FormGroup {
|
|
|
4131
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,
|
|
4132
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
|
|
4133
4204
|
};
|
|
4205
|
+
this.dataSubject$ = new Subject();
|
|
4206
|
+
this.formValidSubject$ = new Subject();
|
|
4207
|
+
this.submitSubject$ = new Subject();
|
|
4134
4208
|
}
|
|
4135
4209
|
/**
|
|
4136
4210
|
* Creates an empty form with given index
|
|
@@ -4142,14 +4216,13 @@ class FormGroup {
|
|
|
4142
4216
|
index,
|
|
4143
4217
|
mappers
|
|
4144
4218
|
}) {
|
|
4145
|
-
const formInstance = new FormCore({
|
|
4146
|
-
index,
|
|
4147
|
-
mappers,
|
|
4148
|
-
config: this.config
|
|
4149
|
-
});
|
|
4150
4219
|
this.addForm({
|
|
4151
4220
|
key: index,
|
|
4152
|
-
|
|
4221
|
+
params: {
|
|
4222
|
+
index,
|
|
4223
|
+
mappers,
|
|
4224
|
+
config: this.config
|
|
4225
|
+
}
|
|
4153
4226
|
});
|
|
4154
4227
|
}
|
|
4155
4228
|
/**
|
|
@@ -4161,11 +4234,16 @@ class FormGroup {
|
|
|
4161
4234
|
*/
|
|
4162
4235
|
addForm({
|
|
4163
4236
|
key,
|
|
4164
|
-
|
|
4237
|
+
params
|
|
4165
4238
|
}) {
|
|
4166
4239
|
this.checkIndexes({
|
|
4167
|
-
key
|
|
4240
|
+
key: key
|
|
4168
4241
|
});
|
|
4242
|
+
const formInstance = new FormCore(Object.assign(Object.assign({}, params), {
|
|
4243
|
+
dataSubject$: this.dataSubject$,
|
|
4244
|
+
formValidSubject$: this.formValidSubject$,
|
|
4245
|
+
submitSubject$: this.submitSubject$
|
|
4246
|
+
}));
|
|
4169
4247
|
if (!formInstance.config) {
|
|
4170
4248
|
formInstance.config = this.config;
|
|
4171
4249
|
}
|
|
@@ -4207,10 +4285,10 @@ class FormGroup {
|
|
|
4207
4285
|
formIndex,
|
|
4208
4286
|
fieldIndex
|
|
4209
4287
|
}) {
|
|
4210
|
-
var _a;
|
|
4211
4288
|
const form = this.forms.get(formIndex);
|
|
4212
|
-
|
|
4213
|
-
|
|
4289
|
+
form === null || form === void 0 ? void 0 : form.removeField({
|
|
4290
|
+
key: fieldIndex
|
|
4291
|
+
});
|
|
4214
4292
|
if ((form === null || form === void 0 ? void 0 : form.fields.size) === 0) {
|
|
4215
4293
|
this.removeForm({
|
|
4216
4294
|
key: formIndex
|
|
@@ -4268,52 +4346,49 @@ class FormGroup {
|
|
|
4268
4346
|
ids,
|
|
4269
4347
|
callback
|
|
4270
4348
|
}) {
|
|
4271
|
-
const
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
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()
|
|
4280
4364
|
};
|
|
4281
|
-
}), startWith({
|
|
4282
|
-
formField: null,
|
|
4283
|
-
values: (_b = this.forms.get(formId)) === null || _b === void 0 ? void 0 : _b.getFormValues()
|
|
4284
|
-
}));
|
|
4285
|
-
if (sub) {
|
|
4286
|
-
acc[formId] = sub;
|
|
4287
|
-
} else {
|
|
4288
|
-
this.config.defaultLogVerbose && console.warn(`failed to register form id ${formId}`);
|
|
4289
4365
|
}
|
|
4290
4366
|
return acc;
|
|
4291
|
-
}, {});
|
|
4292
|
-
const sub = combineLatest(subs).subscribe(callback);
|
|
4367
|
+
}, {}))).subscribe(callback);
|
|
4293
4368
|
return sub;
|
|
4294
4369
|
}
|
|
4295
4370
|
onValidSubscription({
|
|
4296
4371
|
ids,
|
|
4297
4372
|
callback
|
|
4298
4373
|
}) {
|
|
4299
|
-
const
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
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 => {
|
|
4304
4382
|
var _a;
|
|
4305
|
-
return ((_a = this.forms.get(
|
|
4306
|
-
}),
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
const sub = combineLatest(subs).pipe(map(forms => ({
|
|
4315
|
-
groupValid: Object.keys(forms).every(formId => forms[formId]),
|
|
4316
|
-
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
|
+
}, {})
|
|
4317
4392
|
}))).subscribe(callback);
|
|
4318
4393
|
return sub;
|
|
4319
4394
|
}
|
|
@@ -4321,17 +4396,15 @@ class FormGroup {
|
|
|
4321
4396
|
ids,
|
|
4322
4397
|
callback
|
|
4323
4398
|
}) {
|
|
4324
|
-
const
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
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();
|
|
4331
4405
|
}
|
|
4332
4406
|
return acc;
|
|
4333
|
-
}, {});
|
|
4334
|
-
const sub = combineLatest(subs).pipe(skip(1)).subscribe(callback);
|
|
4407
|
+
}, {}))).subscribe(callback);
|
|
4335
4408
|
return sub;
|
|
4336
4409
|
}
|
|
4337
4410
|
}
|