@bolttech/form-engine-core 1.0.0-beta.9 → 1.0.1-beta.1
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 +278 -205
- 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,16 @@ 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.dataSubject$.next({
|
|
3133
|
+
event: 'ON_FIELD_UNMOUNT',
|
|
3134
|
+
fieldIndex: this.name,
|
|
3135
|
+
formIndex: this.formIndex
|
|
3136
|
+
});
|
|
3137
|
+
!this.fieldEventSubject$.closed && this.fieldEventSubject$.next({
|
|
3138
|
+
event: 'ON_FIELD_UNMOUNT',
|
|
3139
|
+
fieldName: this.name,
|
|
3140
|
+
fieldInstance: this
|
|
3106
3141
|
});
|
|
3107
3142
|
}
|
|
3108
3143
|
/**
|
|
@@ -3112,7 +3147,14 @@ class FormField {
|
|
|
3112
3147
|
* @returns {void}
|
|
3113
3148
|
*/
|
|
3114
3149
|
subscribeState(callback) {
|
|
3115
|
-
|
|
3150
|
+
var _a;
|
|
3151
|
+
this.fieldStateSubscription$ = combineLatest({
|
|
3152
|
+
visibility: this.visibilitySubject$.pipe(startWith(this.visibility)),
|
|
3153
|
+
props: this.propsSubject$.pipe(startWith(this.props)),
|
|
3154
|
+
errors: this.errorSubject$.pipe(startWith(Object.assign({}, ((_a = this.mapper.events) === null || _a === void 0 ? void 0 : _a.setErrorMessage) && {
|
|
3155
|
+
[this.mapper.events.setErrorMessage]: this.errorsString
|
|
3156
|
+
})))
|
|
3157
|
+
}).pipe(debounceTime(this.config.defaultStateRefreshTimeMS)).subscribe({
|
|
3116
3158
|
next: callback
|
|
3117
3159
|
});
|
|
3118
3160
|
}
|
|
@@ -3152,6 +3194,8 @@ class FormCore {
|
|
|
3152
3194
|
this.queuedFieldResetValuesEvents = new Map();
|
|
3153
3195
|
this.queuedFieldResetPropertyEvents = new Map();
|
|
3154
3196
|
this.queuedInitialValues = new Map();
|
|
3197
|
+
this._valid = false;
|
|
3198
|
+
this.index = entry.index;
|
|
3155
3199
|
this.schema = entry.schema;
|
|
3156
3200
|
this.fields = new Map();
|
|
3157
3201
|
this.action = entry.action || ((_a = entry.schema) === null || _a === void 0 ? void 0 : _a.action);
|
|
@@ -3164,15 +3208,20 @@ class FormCore {
|
|
|
3164
3208
|
(_h = entry.mappers) === null || _h === void 0 ? void 0 : _h.map(mapper => {
|
|
3165
3209
|
this.mappers.set(mapper.componentName, mapper);
|
|
3166
3210
|
});
|
|
3211
|
+
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
3212
|
this.schema && FormCore.checkIndexes(this.schema.components);
|
|
3168
3213
|
this.templateSubject$ = new Subject();
|
|
3169
|
-
this.submitSubject$ = new Subject();
|
|
3170
3214
|
this.fieldEventSubject$ = new Subject();
|
|
3171
|
-
this.dataSubject$ = new Subject();
|
|
3172
3215
|
this.mountSubject$ = new Subject();
|
|
3173
|
-
this.
|
|
3216
|
+
this.fieldValidNotification$ = new Subject();
|
|
3217
|
+
this.submitSubject$ = entry.submitSubject$ ? entry.submitSubject$ : new Subject();
|
|
3218
|
+
this.dataSubject$ = entry.dataSubject$ ? entry.dataSubject$ : new Subject();
|
|
3219
|
+
this.formValidSubject$ = entry.formValidSubject$ ? entry.formValidSubject$ : new Subject();
|
|
3174
3220
|
this.subscribedTemplates = [];
|
|
3175
3221
|
this.templateSubscription$ = this.templateSubject$.subscribe(this.refreshTemplates.bind(this));
|
|
3222
|
+
this.fieldValidNotification$.subscribe(() => {
|
|
3223
|
+
this.validateForm();
|
|
3224
|
+
});
|
|
3176
3225
|
this.mountSubject$.subscribe(this.mountActions.bind(this));
|
|
3177
3226
|
this.initialValues = entry.initialValues || ((_j = entry.schema) === null || _j === void 0 ? void 0 : _j.initialValues);
|
|
3178
3227
|
this.iVars = entry.iVars || ((_k = entry.schema) === null || _k === void 0 ? void 0 : _k.iVars) || {};
|
|
@@ -3201,7 +3250,6 @@ class FormCore {
|
|
|
3201
3250
|
key,
|
|
3202
3251
|
status
|
|
3203
3252
|
}) {
|
|
3204
|
-
var _a;
|
|
3205
3253
|
if (status) {
|
|
3206
3254
|
const field = this.fields.get(key);
|
|
3207
3255
|
if (!field) {
|
|
@@ -3209,7 +3257,7 @@ class FormCore {
|
|
|
3209
3257
|
@TODO check a better way to handle nested fields unmounted by visiblity conditions from a parent
|
|
3210
3258
|
since they are dependent on adapter field recycling runtimes
|
|
3211
3259
|
*/
|
|
3212
|
-
this.config.defaultLogVerbose && console.
|
|
3260
|
+
this.config.defaultLogVerbose && console.warn(`field ${key} was mounted but since it's parent has some visibility condition the field was already removed`);
|
|
3213
3261
|
return;
|
|
3214
3262
|
}
|
|
3215
3263
|
this.subscribeTemplates();
|
|
@@ -3221,15 +3269,12 @@ class FormCore {
|
|
|
3221
3269
|
scope: 'iVars',
|
|
3222
3270
|
event: 'ON_IVARS'
|
|
3223
3271
|
});
|
|
3224
|
-
if (!this.queuedInitialValues.has(key)) {
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
event: 'ON_FIELD_MOUNT'
|
|
3231
|
-
});
|
|
3232
|
-
}
|
|
3272
|
+
if (!this.queuedInitialValues.has(key)) field.valuePropName && !field.value ? field.emitValue({
|
|
3273
|
+
event: 'ON_FIELD_MOUNT',
|
|
3274
|
+
value: ''
|
|
3275
|
+
}) : field.emitEvents({
|
|
3276
|
+
event: 'ON_FIELD_MOUNT'
|
|
3277
|
+
});
|
|
3233
3278
|
this.checkFieldEventQueues(key);
|
|
3234
3279
|
}
|
|
3235
3280
|
}
|
|
@@ -3274,16 +3319,30 @@ class FormCore {
|
|
|
3274
3319
|
});
|
|
3275
3320
|
}
|
|
3276
3321
|
/**
|
|
3277
|
-
*
|
|
3322
|
+
* Validates all form fields and sets the form valid flag
|
|
3278
3323
|
*
|
|
3279
|
-
* @returns {boolean} True if the form is valid; otherwise, false.
|
|
3280
3324
|
*/
|
|
3281
|
-
|
|
3282
|
-
if (this.fields.size === 0) return false;
|
|
3325
|
+
validateForm() {
|
|
3326
|
+
if (this.fields.size === 0) return this.valid = false;
|
|
3283
3327
|
for (const [, field] of this.fields) {
|
|
3284
|
-
if (!field.valid) return false;
|
|
3328
|
+
if (!field.valid) return this.valid = false;
|
|
3285
3329
|
}
|
|
3286
|
-
return true;
|
|
3330
|
+
return this.valid = true;
|
|
3331
|
+
}
|
|
3332
|
+
get valid() {
|
|
3333
|
+
return this._valid;
|
|
3334
|
+
}
|
|
3335
|
+
set valid(valid) {
|
|
3336
|
+
if (this._valid === valid) return;
|
|
3337
|
+
this._valid = valid;
|
|
3338
|
+
this.templateSubject$.next({
|
|
3339
|
+
event: 'ON_FORM',
|
|
3340
|
+
scope: 'form'
|
|
3341
|
+
});
|
|
3342
|
+
this.formValidSubject$.next({
|
|
3343
|
+
formIndex: this.index,
|
|
3344
|
+
valid: this.valid
|
|
3345
|
+
});
|
|
3287
3346
|
}
|
|
3288
3347
|
/**
|
|
3289
3348
|
* Subscribes to templates for dynamic updates.
|
|
@@ -3336,6 +3395,11 @@ class FormCore {
|
|
|
3336
3395
|
const value = get(this.iVars, [key, ...(property ? [property] : []), ...path]);
|
|
3337
3396
|
return value;
|
|
3338
3397
|
}
|
|
3398
|
+
case 'form':
|
|
3399
|
+
{
|
|
3400
|
+
const value = get(this, [key, ...(property ? [property] : []), ...path]);
|
|
3401
|
+
return value;
|
|
3402
|
+
}
|
|
3339
3403
|
case 'fields':
|
|
3340
3404
|
{
|
|
3341
3405
|
const field = this.fields.get(key);
|
|
@@ -3620,12 +3684,21 @@ class FormCore {
|
|
|
3620
3684
|
* and trigger the validation when it's visible
|
|
3621
3685
|
*/
|
|
3622
3686
|
if (fieldInstance.visibility) {
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3687
|
+
if (this.queuedInitialValues.has(field)) {
|
|
3688
|
+
fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.emitValue({
|
|
3689
|
+
value: this.queuedInitialValues.get(field) || '',
|
|
3690
|
+
event: 'ON_FIELD_MOUNT'
|
|
3691
|
+
});
|
|
3692
|
+
this.queuedInitialValues.delete(field);
|
|
3693
|
+
} else {
|
|
3694
|
+
fieldInstance.emitEvents({
|
|
3695
|
+
event: 'ON_FIELD_MOUNT'
|
|
3696
|
+
});
|
|
3697
|
+
}
|
|
3628
3698
|
} else {
|
|
3699
|
+
if (fieldInstance.persistValue) {
|
|
3700
|
+
this.queuedInitialValues.set(fieldInstance.name, fieldInstance.value);
|
|
3701
|
+
}
|
|
3629
3702
|
fieldInstance.value = '';
|
|
3630
3703
|
fieldInstance.valid = true;
|
|
3631
3704
|
}
|
|
@@ -3753,7 +3826,7 @@ class FormCore {
|
|
|
3753
3826
|
value
|
|
3754
3827
|
}) {
|
|
3755
3828
|
const field = this.fields.get(key);
|
|
3756
|
-
if (!field
|
|
3829
|
+
if (!field) {
|
|
3757
3830
|
this.queuedFieldResetPropertyEvents.set(key, {
|
|
3758
3831
|
property,
|
|
3759
3832
|
path,
|
|
@@ -3815,15 +3888,23 @@ class FormCore {
|
|
|
3815
3888
|
*/
|
|
3816
3889
|
addField({
|
|
3817
3890
|
fieldSchema,
|
|
3818
|
-
mapperElement
|
|
3891
|
+
mapperElement,
|
|
3892
|
+
path
|
|
3819
3893
|
}) {
|
|
3820
|
-
var _a;
|
|
3894
|
+
var _a, _b, _c, _d;
|
|
3821
3895
|
if (this.fields.has(fieldSchema.name)) {
|
|
3822
3896
|
throw new Error(`field name ${fieldSchema.name} already defined`);
|
|
3823
3897
|
}
|
|
3824
3898
|
const mapper = mapperElement || ((_a = this.mappers) === null || _a === void 0 ? void 0 : _a.get(fieldSchema.component));
|
|
3825
3899
|
if (!mapper) throw new Error(`mapper not found for ${fieldSchema.component}, add it to the mappers configuration`);
|
|
3900
|
+
if ((_b = mapper.events) === null || _b === void 0 ? void 0 : _b.setValue) {
|
|
3901
|
+
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];
|
|
3902
|
+
if (!(typeof initialValue === 'undefined') && !this.queuedInitialValues.has(fieldSchema.name) && !(typeof initialValue === 'string' && initialValue.includes('${'))) {
|
|
3903
|
+
this.queuedInitialValues.set(fieldSchema.name, cloneDeep(initialValue));
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3826
3906
|
this.fields.set(fieldSchema.name, new FormField({
|
|
3907
|
+
formIndex: this.index,
|
|
3827
3908
|
schemaComponent: fieldSchema,
|
|
3828
3909
|
mapper,
|
|
3829
3910
|
children: fieldSchema.children ? fieldSchema.children.map(el => el.name) : [],
|
|
@@ -3834,11 +3915,13 @@ class FormCore {
|
|
|
3834
3915
|
templateSubject$: this.templateSubject$,
|
|
3835
3916
|
fieldEventSubject$: this.fieldEventSubject$,
|
|
3836
3917
|
dataSubject$: this.dataSubject$,
|
|
3837
|
-
|
|
3918
|
+
fieldValidNotification$: this.fieldValidNotification$,
|
|
3838
3919
|
mountSubject$: this.mountSubject$,
|
|
3839
3920
|
config: this.config,
|
|
3840
3921
|
submitEvent: this.submit.bind(this),
|
|
3841
|
-
visibility: fieldSchema.visibility
|
|
3922
|
+
visibility: fieldSchema.visibility,
|
|
3923
|
+
persistValue: fieldSchema.persistValue,
|
|
3924
|
+
path
|
|
3842
3925
|
}));
|
|
3843
3926
|
}
|
|
3844
3927
|
/**
|
|
@@ -3858,6 +3941,7 @@ class FormCore {
|
|
|
3858
3941
|
key,
|
|
3859
3942
|
event: 'ON_FIELDS'
|
|
3860
3943
|
});
|
|
3944
|
+
this.validateForm();
|
|
3861
3945
|
}
|
|
3862
3946
|
/**
|
|
3863
3947
|
* Serializes the schema structure to create form fields.
|
|
@@ -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
|
/**
|
|
@@ -4001,7 +4059,7 @@ class FormCore {
|
|
|
4001
4059
|
subscribeFieldEvent({
|
|
4002
4060
|
callback
|
|
4003
4061
|
}) {
|
|
4004
|
-
const sub = this.fieldEventSubject$.pipe(groupBy(payload => payload.event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS)))).subscribe({
|
|
4062
|
+
const sub = this.fieldEventSubject$.pipe(groupBy(payload => `${payload.event}|${payload.fieldName}`), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS)))).subscribe({
|
|
4005
4063
|
next: callback
|
|
4006
4064
|
});
|
|
4007
4065
|
return sub;
|
|
@@ -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
|
}
|