@bolttech/form-engine-core 1.0.0-beta.10 → 1.0.0-beta.12
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 +94 -52
- package/package.json +1 -1
- package/src/constants/constants.d.ts +1 -1
- package/src/managers/field.d.ts +9 -8
- package/src/managers/form.d.ts +13 -6
- package/src/types/event.d.ts +11 -4
- package/src/types/schema.d.ts +5 -1
package/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Subject, Subscription,
|
|
1
|
+
import { Subject, Subscription, groupBy, mergeMap, debounceTime, filter, combineLatest, startWith, map, distinctUntilKeyChanged, distinctUntilChanged, skip } from 'rxjs';
|
|
2
2
|
import creditCardType from 'credit-card-type';
|
|
3
3
|
import { isNumber as isNumber$1, isFunction, cloneDeep, merge, isEqual, get, isNil, set } from 'lodash';
|
|
4
4
|
import { getCurrencySymbol } from '@gaignoux/currency';
|
|
@@ -50,7 +50,7 @@ const TEMPLATE_REGEX_STRING_CONCATENATION_DETECTOR = /^\$\{(?:[^{}]|\{(?:[^{}]|\
|
|
|
50
50
|
const TEMPLATE_REGEX_DELIMITATOR = /\$\{((?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*)\}/g;
|
|
51
51
|
const TEMPLATE_REGEX_OPERATOR_SPLITTER = /\s*(\|\||&&|!)\s*/g;
|
|
52
52
|
const TEMPLATE_REGEX_OPERATOR_MATCHER = /^\|\||&&|!$/;
|
|
53
|
-
const TEMPLATE_AVALIABLE_SCOPES = ['fields', 'iVars'];
|
|
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
|
|
|
@@ -2495,7 +2495,7 @@ class FormField {
|
|
|
2495
2495
|
templateSubject$,
|
|
2496
2496
|
fieldEventSubject$,
|
|
2497
2497
|
dataSubject$,
|
|
2498
|
-
|
|
2498
|
+
fieldValidNotification$,
|
|
2499
2499
|
mountSubject$,
|
|
2500
2500
|
mapper,
|
|
2501
2501
|
getFormValues,
|
|
@@ -2535,7 +2535,7 @@ class FormField {
|
|
|
2535
2535
|
this.templateSubject$ = templateSubject$;
|
|
2536
2536
|
this.fieldEventSubject$ = fieldEventSubject$;
|
|
2537
2537
|
this.dataSubject$ = dataSubject$;
|
|
2538
|
-
this.
|
|
2538
|
+
this.fieldValidNotification$ = fieldValidNotification$;
|
|
2539
2539
|
this.mountSubject$ = mountSubject$;
|
|
2540
2540
|
this._props = FormField.filterProps(cloneDeep(schemaComponent.props || {}));
|
|
2541
2541
|
this._metadata = '';
|
|
@@ -2554,11 +2554,14 @@ class FormField {
|
|
|
2554
2554
|
status: null
|
|
2555
2555
|
};
|
|
2556
2556
|
return acc;
|
|
2557
|
-
}, {})
|
|
2557
|
+
}, {}),
|
|
2558
|
+
apiState: {
|
|
2559
|
+
loading: false
|
|
2560
|
+
}
|
|
2558
2561
|
};
|
|
2559
2562
|
this._errors = {};
|
|
2560
2563
|
this._mounted = false;
|
|
2561
|
-
this.
|
|
2564
|
+
this.valid = true;
|
|
2562
2565
|
this.initializeObservers();
|
|
2563
2566
|
}
|
|
2564
2567
|
/**
|
|
@@ -2567,7 +2570,6 @@ class FormField {
|
|
|
2567
2570
|
* emissions to unsubscribed fields
|
|
2568
2571
|
*/
|
|
2569
2572
|
initializeObservers() {
|
|
2570
|
-
var _a;
|
|
2571
2573
|
if (!this.valueSubject$ || this.valueSubject$.closed) {
|
|
2572
2574
|
this.valueSubject$ = new SafeSubject(() => this.mounted);
|
|
2573
2575
|
}
|
|
@@ -2577,9 +2579,6 @@ class FormField {
|
|
|
2577
2579
|
if (!this.visibilitySubject$ || this.visibilitySubject$.closed) {
|
|
2578
2580
|
this.visibilitySubject$ = new SafeSubject(() => this.mounted);
|
|
2579
2581
|
}
|
|
2580
|
-
if (!this.apiSubject$ || this.apiSubject$.closed) {
|
|
2581
|
-
this.apiSubject$ = new SafeSubject(() => this.mounted);
|
|
2582
|
-
}
|
|
2583
2582
|
if (!this.propsSubject$ || this.propsSubject$.closed) {
|
|
2584
2583
|
this.propsSubject$ = new SafeSubject(() => this.mounted);
|
|
2585
2584
|
}
|
|
@@ -2589,16 +2588,9 @@ class FormField {
|
|
|
2589
2588
|
if (!this.apiEventQueueSubject$ || this.apiEventQueueSubject$.closed) {
|
|
2590
2589
|
this.apiEventQueueSubject$ = new SafeSubject(() => this.mounted);
|
|
2591
2590
|
}
|
|
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
2591
|
!this.apiEventQueueSubject$.observed && this.apiEventQueueSubject$.pipe(groupBy(({
|
|
2600
2592
|
event
|
|
2601
|
-
}) => event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultAPIdebounceTimeMS))), filter(() => this.
|
|
2593
|
+
}) => event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultAPIdebounceTimeMS))), filter(() => this.apiEventQueueSubject$ && !this.apiEventQueueSubject$.closed)).subscribe(payload => {
|
|
2602
2594
|
this.apiRequest(payload);
|
|
2603
2595
|
});
|
|
2604
2596
|
}
|
|
@@ -2739,12 +2731,11 @@ class FormField {
|
|
|
2739
2731
|
* sets valid field state and notifies form instance via formValidNotification$
|
|
2740
2732
|
*/
|
|
2741
2733
|
set valid(valid) {
|
|
2742
|
-
if (this.
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
}
|
|
2734
|
+
if (typeof valid !== 'boolean' && this.valid === valid) return;
|
|
2735
|
+
this._valid = valid;
|
|
2736
|
+
this.fieldValidNotification$.next({
|
|
2737
|
+
fieldTrigger: this.name
|
|
2738
|
+
});
|
|
2748
2739
|
}
|
|
2749
2740
|
/**
|
|
2750
2741
|
* Retrieves the validity status of the form field.
|
|
@@ -2799,13 +2790,12 @@ class FormField {
|
|
|
2799
2790
|
* @param {TApiResponse} response - The new API response data to be set.
|
|
2800
2791
|
*/
|
|
2801
2792
|
set api(response) {
|
|
2802
|
-
if (typeof response === 'undefined'
|
|
2793
|
+
if (typeof response === 'undefined') return;
|
|
2803
2794
|
this._api = response;
|
|
2804
|
-
this.apiSubject$.next(this.api);
|
|
2805
2795
|
this.templateSubject$.next({
|
|
2806
2796
|
scope: 'fields',
|
|
2807
2797
|
key: this.name,
|
|
2808
|
-
event: '
|
|
2798
|
+
event: 'ON_API_RESPONSE'
|
|
2809
2799
|
});
|
|
2810
2800
|
// this.apiResponseSubject$.next({ key: this.name });
|
|
2811
2801
|
this.emitEvents({
|
|
@@ -2813,7 +2803,20 @@ class FormField {
|
|
|
2813
2803
|
});
|
|
2814
2804
|
}
|
|
2815
2805
|
/**
|
|
2816
|
-
*
|
|
2806
|
+
* notifies templates and event binded field configurations that a request starts it's processing
|
|
2807
|
+
*/
|
|
2808
|
+
notifyApiRequest() {
|
|
2809
|
+
this._api.apiState.loading = true;
|
|
2810
|
+
this.templateSubject$.next({
|
|
2811
|
+
scope: 'fields',
|
|
2812
|
+
key: this.name,
|
|
2813
|
+
event: 'ON_API_REQUEST'
|
|
2814
|
+
});
|
|
2815
|
+
this.emitEvents({
|
|
2816
|
+
event: 'ON_API_FIELD_REQUEST'
|
|
2817
|
+
});
|
|
2818
|
+
}
|
|
2819
|
+
/** Retrieves the mounted status of the field.
|
|
2817
2820
|
*
|
|
2818
2821
|
* @returns {boolean} - the mounted status of the field.
|
|
2819
2822
|
*/
|
|
@@ -3009,6 +3012,7 @@ class FormField {
|
|
|
3009
3012
|
}) {
|
|
3010
3013
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
3011
3014
|
return __awaiter(this, void 0, void 0, function* () {
|
|
3015
|
+
let requestMadeOnce = false;
|
|
3012
3016
|
const configRequest = config => __awaiter(this, void 0, void 0, function* () {
|
|
3013
3017
|
var _k;
|
|
3014
3018
|
try {
|
|
@@ -3034,20 +3038,23 @@ class FormField {
|
|
|
3034
3038
|
};
|
|
3035
3039
|
}
|
|
3036
3040
|
});
|
|
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 => {
|
|
3041
|
+
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
3042
|
var _a, _b;
|
|
3039
3043
|
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
3044
|
}))) return;
|
|
3041
3045
|
const responses = {
|
|
3042
3046
|
default: Object.assign({}, this.api.default),
|
|
3043
|
-
named: Object.assign({}, this.api.named)
|
|
3047
|
+
named: Object.assign({}, this.api.named),
|
|
3048
|
+
apiState: Object.assign({}, this.api.apiState)
|
|
3044
3049
|
};
|
|
3045
3050
|
const config = (_e = this.apiSchema.defaultConfig) === null || _e === void 0 ? void 0 : _e.config;
|
|
3046
3051
|
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)) {
|
|
3052
|
+
!requestMadeOnce && this.notifyApiRequest();
|
|
3047
3053
|
const {
|
|
3048
3054
|
response,
|
|
3049
3055
|
status
|
|
3050
3056
|
} = yield configRequest(config);
|
|
3057
|
+
requestMadeOnce = true;
|
|
3051
3058
|
responses.default = {
|
|
3052
3059
|
response,
|
|
3053
3060
|
status
|
|
@@ -3065,10 +3072,12 @@ class FormField {
|
|
|
3065
3072
|
var _l, _m, _o, _p;
|
|
3066
3073
|
const config = (_m = (_l = this.apiSchema) === null || _l === void 0 ? void 0 : _l.configs) === null || _m === void 0 ? void 0 : _m[configKey].config;
|
|
3067
3074
|
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)) {
|
|
3075
|
+
!requestMadeOnce && this.notifyApiRequest();
|
|
3068
3076
|
const {
|
|
3069
3077
|
response,
|
|
3070
3078
|
status
|
|
3071
3079
|
} = yield configRequest(config);
|
|
3080
|
+
requestMadeOnce = true;
|
|
3072
3081
|
return {
|
|
3073
3082
|
name: configKey,
|
|
3074
3083
|
result: {
|
|
@@ -3084,7 +3093,11 @@ class FormField {
|
|
|
3084
3093
|
});
|
|
3085
3094
|
}
|
|
3086
3095
|
}
|
|
3087
|
-
|
|
3096
|
+
if (requestMadeOnce) {
|
|
3097
|
+
responses.apiState.lastEvent = event;
|
|
3098
|
+
responses.apiState.loading = false;
|
|
3099
|
+
this.api = responses;
|
|
3100
|
+
}
|
|
3088
3101
|
});
|
|
3089
3102
|
}
|
|
3090
3103
|
/**
|
|
@@ -3099,9 +3112,8 @@ class FormField {
|
|
|
3099
3112
|
this.fieldStateSubscription$.unsubscribe();
|
|
3100
3113
|
this.propsSubject$.unsubscribe();
|
|
3101
3114
|
this.errorSubject$.unsubscribe();
|
|
3102
|
-
this.apiSubject$.unsubscribe();
|
|
3103
3115
|
this.apiEventQueueSubject$.unsubscribe();
|
|
3104
|
-
!this.
|
|
3116
|
+
!this.fieldValidNotification$.closed && this.fieldValidNotification$.next({
|
|
3105
3117
|
fieldTrigger: this.name
|
|
3106
3118
|
});
|
|
3107
3119
|
}
|
|
@@ -3112,7 +3124,14 @@ class FormField {
|
|
|
3112
3124
|
* @returns {void}
|
|
3113
3125
|
*/
|
|
3114
3126
|
subscribeState(callback) {
|
|
3115
|
-
|
|
3127
|
+
var _a;
|
|
3128
|
+
this.fieldStateSubscription$ = combineLatest({
|
|
3129
|
+
visibility: this.visibilitySubject$.pipe(startWith(this.visibility)),
|
|
3130
|
+
props: this.propsSubject$.pipe(startWith(this.props)),
|
|
3131
|
+
errors: this.errorSubject$.pipe(startWith(Object.assign({}, ((_a = this.mapper.events) === null || _a === void 0 ? void 0 : _a.setErrorMessage) && {
|
|
3132
|
+
[this.mapper.events.setErrorMessage]: this.errorsString
|
|
3133
|
+
})))
|
|
3134
|
+
}).pipe(debounceTime(this.config.defaultStateRefreshTimeMS)).subscribe({
|
|
3116
3135
|
next: callback
|
|
3117
3136
|
});
|
|
3118
3137
|
}
|
|
@@ -3152,6 +3171,8 @@ class FormCore {
|
|
|
3152
3171
|
this.queuedFieldResetValuesEvents = new Map();
|
|
3153
3172
|
this.queuedFieldResetPropertyEvents = new Map();
|
|
3154
3173
|
this.queuedInitialValues = new Map();
|
|
3174
|
+
this._valid = false;
|
|
3175
|
+
this.index = entry.index;
|
|
3155
3176
|
this.schema = entry.schema;
|
|
3156
3177
|
this.fields = new Map();
|
|
3157
3178
|
this.action = entry.action || ((_a = entry.schema) === null || _a === void 0 ? void 0 : _a.action);
|
|
@@ -3170,9 +3191,13 @@ class FormCore {
|
|
|
3170
3191
|
this.fieldEventSubject$ = new Subject();
|
|
3171
3192
|
this.dataSubject$ = new Subject();
|
|
3172
3193
|
this.mountSubject$ = new Subject();
|
|
3194
|
+
this.fieldValidNotification$ = new Subject();
|
|
3173
3195
|
this.formValidNotification$ = new Subject();
|
|
3174
3196
|
this.subscribedTemplates = [];
|
|
3175
3197
|
this.templateSubscription$ = this.templateSubject$.subscribe(this.refreshTemplates.bind(this));
|
|
3198
|
+
this.fieldValidNotification$.subscribe(() => {
|
|
3199
|
+
this.validateForm();
|
|
3200
|
+
});
|
|
3176
3201
|
this.mountSubject$.subscribe(this.mountActions.bind(this));
|
|
3177
3202
|
this.initialValues = entry.initialValues || ((_j = entry.schema) === null || _j === void 0 ? void 0 : _j.initialValues);
|
|
3178
3203
|
this.iVars = entry.iVars || ((_k = entry.schema) === null || _k === void 0 ? void 0 : _k.iVars) || {};
|
|
@@ -3274,16 +3299,30 @@ class FormCore {
|
|
|
3274
3299
|
});
|
|
3275
3300
|
}
|
|
3276
3301
|
/**
|
|
3277
|
-
*
|
|
3302
|
+
* Validates all form fields and sets the form valid flag
|
|
3278
3303
|
*
|
|
3279
|
-
* @returns {boolean} True if the form is valid; otherwise, false.
|
|
3280
3304
|
*/
|
|
3281
|
-
|
|
3282
|
-
if (this.fields.size === 0) return false;
|
|
3305
|
+
validateForm() {
|
|
3306
|
+
if (this.fields.size === 0) return this.valid = false;
|
|
3283
3307
|
for (const [, field] of this.fields) {
|
|
3284
|
-
if (!field.valid) return false;
|
|
3308
|
+
if (!field.valid) return this.valid = false;
|
|
3285
3309
|
}
|
|
3286
|
-
return true;
|
|
3310
|
+
return this.valid = true;
|
|
3311
|
+
}
|
|
3312
|
+
get valid() {
|
|
3313
|
+
return this._valid;
|
|
3314
|
+
}
|
|
3315
|
+
set valid(valid) {
|
|
3316
|
+
if (this._valid === valid) return;
|
|
3317
|
+
this._valid = valid;
|
|
3318
|
+
this.templateSubject$.next({
|
|
3319
|
+
event: 'ON_FORM',
|
|
3320
|
+
scope: 'form'
|
|
3321
|
+
});
|
|
3322
|
+
this.formValidNotification$.next({
|
|
3323
|
+
formIndex: this.index,
|
|
3324
|
+
valid: this.valid
|
|
3325
|
+
});
|
|
3287
3326
|
}
|
|
3288
3327
|
/**
|
|
3289
3328
|
* Subscribes to templates for dynamic updates.
|
|
@@ -3336,6 +3375,11 @@ class FormCore {
|
|
|
3336
3375
|
const value = get(this.iVars, [key, ...(property ? [property] : []), ...path]);
|
|
3337
3376
|
return value;
|
|
3338
3377
|
}
|
|
3378
|
+
case 'form':
|
|
3379
|
+
{
|
|
3380
|
+
const value = get(this, [key, ...(property ? [property] : []), ...path]);
|
|
3381
|
+
return value;
|
|
3382
|
+
}
|
|
3339
3383
|
case 'fields':
|
|
3340
3384
|
{
|
|
3341
3385
|
const field = this.fields.get(key);
|
|
@@ -3834,7 +3878,7 @@ class FormCore {
|
|
|
3834
3878
|
templateSubject$: this.templateSubject$,
|
|
3835
3879
|
fieldEventSubject$: this.fieldEventSubject$,
|
|
3836
3880
|
dataSubject$: this.dataSubject$,
|
|
3837
|
-
|
|
3881
|
+
fieldValidNotification$: this.fieldValidNotification$,
|
|
3838
3882
|
mountSubject$: this.mountSubject$,
|
|
3839
3883
|
config: this.config,
|
|
3840
3884
|
submitEvent: this.submit.bind(this),
|
|
@@ -3889,7 +3933,7 @@ class FormCore {
|
|
|
3889
3933
|
templateSubject$: this.templateSubject$,
|
|
3890
3934
|
fieldEventSubject$: this.fieldEventSubject$,
|
|
3891
3935
|
dataSubject$: this.dataSubject$,
|
|
3892
|
-
|
|
3936
|
+
fieldValidNotification$: this.fieldValidNotification$,
|
|
3893
3937
|
mountSubject$: this.mountSubject$,
|
|
3894
3938
|
config: this.config,
|
|
3895
3939
|
getFormValues: this.getFormValues.bind(this),
|
|
@@ -3989,7 +4033,7 @@ class FormCore {
|
|
|
3989
4033
|
values,
|
|
3990
4034
|
metadata,
|
|
3991
4035
|
erroredFields,
|
|
3992
|
-
isValid: this.
|
|
4036
|
+
isValid: this.valid
|
|
3993
4037
|
};
|
|
3994
4038
|
}
|
|
3995
4039
|
/**
|
|
@@ -4050,11 +4094,9 @@ class FormCore {
|
|
|
4050
4094
|
* @param {(payload: TFormValidationPayload) => void} callback callback function to call onValid
|
|
4051
4095
|
*/
|
|
4052
4096
|
subscribeFormValidation(callback) {
|
|
4053
|
-
const sub = this.formValidNotification$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS), map(({
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
fieldTrigger,
|
|
4057
|
-
valid: this.isValid
|
|
4097
|
+
const sub = this.formValidNotification$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS), map(() => ({
|
|
4098
|
+
formIndex: this.index,
|
|
4099
|
+
valid: this.valid
|
|
4058
4100
|
})), distinctUntilKeyChanged('valid')).subscribe({
|
|
4059
4101
|
next: callback
|
|
4060
4102
|
});
|
|
@@ -4069,7 +4111,7 @@ class FormCore {
|
|
|
4069
4111
|
event: 'ON_FIELD_VALIDATION'
|
|
4070
4112
|
});
|
|
4071
4113
|
});
|
|
4072
|
-
if (!this.
|
|
4114
|
+
if (!this.valid) return;
|
|
4073
4115
|
const values = this.getFormValues();
|
|
4074
4116
|
this.submitSubject$.next(values);
|
|
4075
4117
|
}
|
|
@@ -4081,7 +4123,7 @@ class FormCore {
|
|
|
4081
4123
|
this.templateSubscription$.unsubscribe();
|
|
4082
4124
|
this.fieldEventSubject$.unsubscribe();
|
|
4083
4125
|
this.dataSubject$.unsubscribe();
|
|
4084
|
-
this.
|
|
4126
|
+
this.fieldValidNotification$.unsubscribe();
|
|
4085
4127
|
this.fields.forEach(field => field.destroyField());
|
|
4086
4128
|
}
|
|
4087
4129
|
}
|
|
@@ -4298,11 +4340,11 @@ class FormGroup {
|
|
|
4298
4340
|
}) {
|
|
4299
4341
|
const subs = ids.reduce((acc, formId) => {
|
|
4300
4342
|
var _a;
|
|
4301
|
-
const sub = (_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.formValidNotification$.pipe(groupBy(payload => `${formId}.${payload.
|
|
4343
|
+
const sub = (_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.formValidNotification$.pipe(groupBy(payload => `${formId}.${payload.formIndex}`), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), startWith({
|
|
4302
4344
|
fieldTrigger: null
|
|
4303
4345
|
}), map(() => {
|
|
4304
4346
|
var _a;
|
|
4305
|
-
return ((_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.
|
|
4347
|
+
return ((_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.valid) === false ? false : true;
|
|
4306
4348
|
}), distinctUntilChanged());
|
|
4307
4349
|
if (sub) {
|
|
4308
4350
|
acc[formId] = sub;
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@ declare const TEMPLATE_REGEX_STRING_CONCATENATION_DETECTOR: RegExp;
|
|
|
4
4
|
declare const TEMPLATE_REGEX_DELIMITATOR: RegExp;
|
|
5
5
|
declare const TEMPLATE_REGEX_OPERATOR_SPLITTER: RegExp;
|
|
6
6
|
declare const TEMPLATE_REGEX_OPERATOR_MATCHER: RegExp;
|
|
7
|
-
declare const TEMPLATE_AVALIABLE_SCOPES: readonly ["fields", "iVars"];
|
|
7
|
+
declare const TEMPLATE_AVALIABLE_SCOPES: readonly ["fields", "iVars", "form"];
|
|
8
8
|
declare const ALLOWED_RESET_PROPS_MUTATIONS: ("api" | "apiSchema" | "props" | "validations" | "visibilityConditions" | "resetValues")[];
|
|
9
9
|
declare const DEFAULT_LOG_VERBOSE = false;
|
|
10
10
|
export { DEFAULT_API_DEBOUNCE_TIME, DEFAULT_STATE_REFRESH_TIME, DEFAULT_LOG_VERBOSE, TEMPLATE_REGEX_STRING_CONCATENATION_DETECTOR, TEMPLATE_REGEX_DELIMITATOR, TEMPLATE_REGEX_OPERATOR_SPLITTER, TEMPLATE_REGEX_OPERATOR_MATCHER, TEMPLATE_AVALIABLE_SCOPES, ALLOWED_RESET_PROPS_MUTATIONS, };
|
package/src/managers/field.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Subject, Subscription } from 'rxjs';
|
|
2
2
|
import { TApiConfig, TApiEvent, TApiResponse, TErrorMessages, TFormatters, TMasks, TResetPathMethods, TResetValueMethods, TSchemaFormConfig, TValidations, TVisibility } from '../types/schema';
|
|
3
3
|
import { IComponentSchema, IComponentSchemaAsFormField } from '../interfaces/schema';
|
|
4
4
|
import { IState } from '../interfaces/state';
|
|
5
|
-
import { TEvents, TFieldEvent,
|
|
5
|
+
import { TEvents, TFieldEvent, TFieldValidationPayload, TValueChangeEvent } from '../types/event';
|
|
6
6
|
import { TMapper } from '../types/mapper';
|
|
7
7
|
import { SafeSubject } from '../helpers/SafeSubject';
|
|
8
8
|
import { TTemplateEvent } from '../types/template';
|
|
@@ -44,19 +44,17 @@ declare class FormField {
|
|
|
44
44
|
valueSubject$: SafeSubject<Record<string, unknown>>;
|
|
45
45
|
valueSubscription$: Subscription;
|
|
46
46
|
visibilitySubject$: SafeSubject<boolean>;
|
|
47
|
-
apiSubject$: SafeSubject<TApiResponse>;
|
|
48
47
|
fieldEventSubject$: Subject<TFieldEvent>;
|
|
49
48
|
apiEventQueueSubject$: SafeSubject<{
|
|
50
49
|
event: TEvents;
|
|
51
50
|
}>;
|
|
52
|
-
fieldState$: Observable<IState>;
|
|
53
51
|
fieldStateSubscription$: Subscription;
|
|
54
52
|
templateSubject$: Subject<TTemplateEvent>;
|
|
55
53
|
dataSubject$: Subject<{
|
|
56
54
|
key: string;
|
|
57
55
|
event: TEvents;
|
|
58
56
|
}>;
|
|
59
|
-
|
|
57
|
+
fieldValidNotification$: Subject<TFieldValidationPayload>;
|
|
60
58
|
mountSubject$: Subject<{
|
|
61
59
|
key: string;
|
|
62
60
|
status: boolean;
|
|
@@ -94,7 +92,7 @@ declare class FormField {
|
|
|
94
92
|
* @param {TMapper<unknown>} options.mapper, - component generic mapper containing render parameters for adapters
|
|
95
93
|
* @param {() => TFormValues<unknown>} options.getFormValues, - form instance function that builds onData parameter payload from fields
|
|
96
94
|
*/
|
|
97
|
-
constructor({ schemaComponent, config, path, children, validateVisibility, resetValue, resetProperty, templateSubject$, fieldEventSubject$, dataSubject$,
|
|
95
|
+
constructor({ schemaComponent, config, path, children, validateVisibility, resetValue, resetProperty, templateSubject$, fieldEventSubject$, dataSubject$, fieldValidNotification$, mountSubject$, mapper, getFormValues, submitEvent, visibility, }: {
|
|
98
96
|
schemaComponent: IComponentSchema;
|
|
99
97
|
config?: TSchemaFormConfig;
|
|
100
98
|
path?: string;
|
|
@@ -118,7 +116,7 @@ declare class FormField {
|
|
|
118
116
|
key: string;
|
|
119
117
|
event: TEvents;
|
|
120
118
|
}>;
|
|
121
|
-
|
|
119
|
+
fieldValidNotification$: Subject<TFieldValidationPayload>;
|
|
122
120
|
mountSubject$: Subject<{
|
|
123
121
|
key: string;
|
|
124
122
|
status: boolean;
|
|
@@ -218,7 +216,10 @@ declare class FormField {
|
|
|
218
216
|
*/
|
|
219
217
|
set api(response: TApiResponse);
|
|
220
218
|
/**
|
|
221
|
-
*
|
|
219
|
+
* notifies templates and event binded field configurations that a request starts it's processing
|
|
220
|
+
*/
|
|
221
|
+
notifyApiRequest(): void;
|
|
222
|
+
/** Retrieves the mounted status of the field.
|
|
222
223
|
*
|
|
223
224
|
* @returns {boolean} - the mounted status of the field.
|
|
224
225
|
*/
|
package/src/managers/form.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Subject, Subscription } from 'rxjs';
|
|
|
3
3
|
import { IComponentSchema, IComponentSchemaAsFormField, IFormSchema } from '../interfaces/schema';
|
|
4
4
|
import { TSchemaFormConfig } from '../types/schema';
|
|
5
5
|
import { TSubscribedTemplates, TTemplateEvent } from '../types/template';
|
|
6
|
-
import { TEvents, TFieldEvent, TFormValidationPayload, TMutationEvents } from '../types/event';
|
|
6
|
+
import { TEvents, TFieldEvent, TFieldValidationPayload, TFormValidationPayload, TMutationEvents } from '../types/event';
|
|
7
7
|
import { TFormEntry, TFormValues } from '../types/form';
|
|
8
8
|
import { TMapper } from '../types/mapper';
|
|
9
9
|
import { TEMPLATE_AVALIABLE_SCOPES } from '../constants/constants';
|
|
@@ -11,6 +11,7 @@ import { TEMPLATE_AVALIABLE_SCOPES } from '../constants/constants';
|
|
|
11
11
|
* Represents the core logic for managing a form, including field management, validation, and submission.
|
|
12
12
|
*/
|
|
13
13
|
declare class FormCore {
|
|
14
|
+
index: string;
|
|
14
15
|
schema?: IFormSchema;
|
|
15
16
|
fields: Map<string, IFormField>;
|
|
16
17
|
private _iVars;
|
|
@@ -26,7 +27,8 @@ declare class FormCore {
|
|
|
26
27
|
key: string;
|
|
27
28
|
event: TEvents;
|
|
28
29
|
}>;
|
|
29
|
-
formValidNotification$: Subject<
|
|
30
|
+
formValidNotification$: Subject<TFormValidationPayload>;
|
|
31
|
+
fieldValidNotification$: Subject<TFieldValidationPayload>;
|
|
30
32
|
subscribedTemplates: TSubscribedTemplates[];
|
|
31
33
|
action?: string;
|
|
32
34
|
method?: string;
|
|
@@ -45,6 +47,7 @@ declare class FormCore {
|
|
|
45
47
|
value: unknown;
|
|
46
48
|
}>;
|
|
47
49
|
queuedInitialValues: Map<string, unknown>;
|
|
50
|
+
_valid: boolean;
|
|
48
51
|
/**
|
|
49
52
|
* Creates an instance of FormCore.
|
|
50
53
|
*
|
|
@@ -92,11 +95,12 @@ declare class FormCore {
|
|
|
92
95
|
*/
|
|
93
96
|
set iVars(payload: Record<string, unknown>);
|
|
94
97
|
/**
|
|
95
|
-
*
|
|
98
|
+
* Validates all form fields and sets the form valid flag
|
|
96
99
|
*
|
|
97
|
-
* @returns {boolean} True if the form is valid; otherwise, false.
|
|
98
100
|
*/
|
|
99
|
-
|
|
101
|
+
validateForm(): boolean;
|
|
102
|
+
get valid(): boolean;
|
|
103
|
+
set valid(valid: boolean);
|
|
100
104
|
/**
|
|
101
105
|
* Subscribes to templates for dynamic updates.
|
|
102
106
|
*/
|
|
@@ -330,7 +334,10 @@ declare class FormCore {
|
|
|
330
334
|
*
|
|
331
335
|
* @param {(payload: TFormValidationPayload) => void} callback callback function to call onValid
|
|
332
336
|
*/
|
|
333
|
-
subscribeFormValidation(callback: (payload:
|
|
337
|
+
subscribeFormValidation(callback: (payload: {
|
|
338
|
+
formIndex: string;
|
|
339
|
+
valid: boolean;
|
|
340
|
+
}) => void): Subscription;
|
|
334
341
|
/**
|
|
335
342
|
* Submits the form by triggering form field events and invoking the onSubmit callback.
|
|
336
343
|
*/
|
package/src/types/event.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { TFormValues } from './form';
|
|
|
9
9
|
* const event: TEvents = 'ON_FIELD_CHANGE';
|
|
10
10
|
* ```
|
|
11
11
|
*/
|
|
12
|
-
type TEvents = 'ON_FIELD_MOUNT' | 'ON_FIELD_CHANGE' | 'ON_FIELD_BLUR' | 'ON_FIELD_FOCUS' | 'ON_FIELD_CLICK' | 'ON_FIELD_KEYUP' | 'ON_FIELD_KEYDOWN' | 'ON_FIELD_CLEARED' | 'ON_FORM_SUBMIT' | 'ON_FIELD_VALIDATION' | 'ON_FORM_MOUNT' | 'ON_API_FIELD_RESPONSE';
|
|
12
|
+
type TEvents = 'ON_FIELD_MOUNT' | 'ON_FIELD_CHANGE' | 'ON_FIELD_BLUR' | 'ON_FIELD_FOCUS' | 'ON_FIELD_CLICK' | 'ON_FIELD_KEYUP' | 'ON_FIELD_KEYDOWN' | 'ON_FIELD_CLEARED' | 'ON_FORM_SUBMIT' | 'ON_FIELD_VALIDATION' | 'ON_FORM_MOUNT' | 'ON_API_FIELD_REQUEST' | 'ON_API_FIELD_RESPONSE';
|
|
13
13
|
/**
|
|
14
14
|
* @type TMutationEvents
|
|
15
15
|
* Represents the different types of events that can occur internally that triggers templating.
|
|
@@ -19,7 +19,7 @@ type TEvents = 'ON_FIELD_MOUNT' | 'ON_FIELD_CHANGE' | 'ON_FIELD_BLUR' | 'ON_FIEL
|
|
|
19
19
|
* const event: TMutationEvents = 'ON_VALUE';
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
|
-
type TMutationEvents = 'ON_VALUE' | 'ON_PROPS' | 'ON_VISIBILITY' | '
|
|
22
|
+
type TMutationEvents = 'ON_VALUE' | 'ON_PROPS' | 'ON_VISIBILITY' | 'ON_API_REQUEST' | 'ON_API_RESPONSE' | 'ON_IVARS' | 'ON_FIELDS' | 'ON_RESET' | 'ON_FORM';
|
|
23
23
|
declare enum TMutationEnum {
|
|
24
24
|
ON_VALUE = "value",
|
|
25
25
|
ON_PROPS = "props",
|
|
@@ -56,9 +56,16 @@ type TFieldEvent = {
|
|
|
56
56
|
* Form onValid event emmited payload on callback function parameter
|
|
57
57
|
*/
|
|
58
58
|
type TFormValidationPayload = {
|
|
59
|
-
|
|
59
|
+
formIndex: string;
|
|
60
60
|
valid: boolean;
|
|
61
61
|
};
|
|
62
|
+
/**
|
|
63
|
+
* @type TFieldValidationPayload
|
|
64
|
+
* field event emmited payload on field validation
|
|
65
|
+
*/
|
|
66
|
+
type TFieldValidationPayload = {
|
|
67
|
+
fieldTrigger: string;
|
|
68
|
+
};
|
|
62
69
|
/**
|
|
63
70
|
* @type TFormGroupOnDataEventPayload
|
|
64
71
|
* Form Group onData event emitted payload on callback function parameter
|
|
@@ -81,4 +88,4 @@ type TFormGroupOnValidEventPayload = {
|
|
|
81
88
|
* Form Group onSubmit event emitted payload on callback function parameter
|
|
82
89
|
*/
|
|
83
90
|
type TFormGroupOnSubmitEventPayload<T> = Record<string, TFormValues<T> | undefined>;
|
|
84
|
-
export { TEvents, TMutationEvents, TMutationEnum, TValueChangeEvent, TFieldEvent, TFormGroupOnDataEventPayload, TFormGroupOnValidEventPayload, TFormGroupOnSubmitEventPayload, TFormValidationPayload, };
|
|
91
|
+
export { TEvents, TMutationEvents, TMutationEnum, TValueChangeEvent, TFieldEvent, TFormGroupOnDataEventPayload, TFormGroupOnValidEventPayload, TFormGroupOnSubmitEventPayload, TFormValidationPayload, TFieldValidationPayload, };
|
package/src/types/schema.d.ts
CHANGED
|
@@ -667,7 +667,7 @@ type TResetValueMethods = Omit<TVisibility, 'showOnlyIfTrue' | 'validations'> &
|
|
|
667
667
|
validations?: TSchemaValidation;
|
|
668
668
|
};
|
|
669
669
|
type TResetPathMethods = {
|
|
670
|
-
property: typeof ALLOWED_RESET_PROPS_MUTATIONS[number];
|
|
670
|
+
property: (typeof ALLOWED_RESET_PROPS_MUTATIONS)[number];
|
|
671
671
|
path: string;
|
|
672
672
|
field: string;
|
|
673
673
|
resettledValue: unknown;
|
|
@@ -816,6 +816,10 @@ type TApiResponsePayload = {
|
|
|
816
816
|
type TApiResponse = {
|
|
817
817
|
default: TApiResponsePayload;
|
|
818
818
|
named?: Record<string, TApiResponsePayload>;
|
|
819
|
+
apiState: {
|
|
820
|
+
loading: boolean;
|
|
821
|
+
lastEvent?: TEvents;
|
|
822
|
+
};
|
|
819
823
|
};
|
|
820
824
|
/**
|
|
821
825
|
* Represents the schema config structure
|