@bolttech/form-engine-core 1.0.0-beta.11 → 1.0.0-beta.13
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 +95 -43
- package/package.json +1 -1
- package/src/constants/constants.d.ts +1 -1
- package/src/managers/field.d.ts +16 -6
- 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
|
@@ -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
|
/**
|
|
@@ -2576,9 +2579,6 @@ class FormField {
|
|
|
2576
2579
|
if (!this.visibilitySubject$ || this.visibilitySubject$.closed) {
|
|
2577
2580
|
this.visibilitySubject$ = new SafeSubject(() => this.mounted);
|
|
2578
2581
|
}
|
|
2579
|
-
if (!this.apiSubject$ || this.apiSubject$.closed) {
|
|
2580
|
-
this.apiSubject$ = new SafeSubject(() => this.mounted);
|
|
2581
|
-
}
|
|
2582
2582
|
if (!this.propsSubject$ || this.propsSubject$.closed) {
|
|
2583
2583
|
this.propsSubject$ = new SafeSubject(() => this.mounted);
|
|
2584
2584
|
}
|
|
@@ -2590,7 +2590,7 @@ class FormField {
|
|
|
2590
2590
|
}
|
|
2591
2591
|
!this.apiEventQueueSubject$.observed && this.apiEventQueueSubject$.pipe(groupBy(({
|
|
2592
2592
|
event
|
|
2593
|
-
}) => 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 => {
|
|
2594
2594
|
this.apiRequest(payload);
|
|
2595
2595
|
});
|
|
2596
2596
|
}
|
|
@@ -2731,12 +2731,9 @@ class FormField {
|
|
|
2731
2731
|
* sets valid field state and notifies form instance via formValidNotification$
|
|
2732
2732
|
*/
|
|
2733
2733
|
set valid(valid) {
|
|
2734
|
-
if (this.
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
fieldTrigger: this.name
|
|
2738
|
-
});
|
|
2739
|
-
}
|
|
2734
|
+
if (typeof valid !== 'boolean' && this.valid === valid) return;
|
|
2735
|
+
this._valid = valid;
|
|
2736
|
+
this.triggerFieldValidNotification();
|
|
2740
2737
|
}
|
|
2741
2738
|
/**
|
|
2742
2739
|
* Retrieves the validity status of the form field.
|
|
@@ -2746,6 +2743,18 @@ class FormField {
|
|
|
2746
2743
|
get valid() {
|
|
2747
2744
|
return this._valid;
|
|
2748
2745
|
}
|
|
2746
|
+
/**
|
|
2747
|
+
* triggers field valid notification to handle the form instance valid notification
|
|
2748
|
+
*
|
|
2749
|
+
* Note: since form unmount can occur before field unmount, this subject might already be closed by form instance
|
|
2750
|
+
* quick workaround is to check if the subject is already closed before emitting
|
|
2751
|
+
* if form instance onValid or template form.valid doesn't work properly, might be due to this workaround
|
|
2752
|
+
*/
|
|
2753
|
+
triggerFieldValidNotification() {
|
|
2754
|
+
!this.fieldValidNotification$.closed && this.fieldValidNotification$.next({
|
|
2755
|
+
fieldTrigger: this.name
|
|
2756
|
+
});
|
|
2757
|
+
}
|
|
2749
2758
|
/**
|
|
2750
2759
|
* Retrieves the error messages associated with the form field.
|
|
2751
2760
|
*
|
|
@@ -2791,13 +2800,12 @@ class FormField {
|
|
|
2791
2800
|
* @param {TApiResponse} response - The new API response data to be set.
|
|
2792
2801
|
*/
|
|
2793
2802
|
set api(response) {
|
|
2794
|
-
if (typeof response === 'undefined'
|
|
2803
|
+
if (typeof response === 'undefined') return;
|
|
2795
2804
|
this._api = response;
|
|
2796
|
-
this.apiSubject$.next(this.api);
|
|
2797
2805
|
this.templateSubject$.next({
|
|
2798
2806
|
scope: 'fields',
|
|
2799
2807
|
key: this.name,
|
|
2800
|
-
event: '
|
|
2808
|
+
event: 'ON_API_RESPONSE'
|
|
2801
2809
|
});
|
|
2802
2810
|
// this.apiResponseSubject$.next({ key: this.name });
|
|
2803
2811
|
this.emitEvents({
|
|
@@ -2805,7 +2813,20 @@ class FormField {
|
|
|
2805
2813
|
});
|
|
2806
2814
|
}
|
|
2807
2815
|
/**
|
|
2808
|
-
*
|
|
2816
|
+
* notifies templates and event binded field configurations that a request starts it's processing
|
|
2817
|
+
*/
|
|
2818
|
+
notifyApiRequest() {
|
|
2819
|
+
this._api.apiState.loading = true;
|
|
2820
|
+
this.templateSubject$.next({
|
|
2821
|
+
scope: 'fields',
|
|
2822
|
+
key: this.name,
|
|
2823
|
+
event: 'ON_API_REQUEST'
|
|
2824
|
+
});
|
|
2825
|
+
this.emitEvents({
|
|
2826
|
+
event: 'ON_API_FIELD_REQUEST'
|
|
2827
|
+
});
|
|
2828
|
+
}
|
|
2829
|
+
/** Retrieves the mounted status of the field.
|
|
2809
2830
|
*
|
|
2810
2831
|
* @returns {boolean} - the mounted status of the field.
|
|
2811
2832
|
*/
|
|
@@ -3001,6 +3022,7 @@ class FormField {
|
|
|
3001
3022
|
}) {
|
|
3002
3023
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
3003
3024
|
return __awaiter(this, void 0, void 0, function* () {
|
|
3025
|
+
let requestMadeOnce = false;
|
|
3004
3026
|
const configRequest = config => __awaiter(this, void 0, void 0, function* () {
|
|
3005
3027
|
var _k;
|
|
3006
3028
|
try {
|
|
@@ -3026,20 +3048,23 @@ class FormField {
|
|
|
3026
3048
|
};
|
|
3027
3049
|
}
|
|
3028
3050
|
});
|
|
3029
|
-
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 => {
|
|
3051
|
+
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 => {
|
|
3030
3052
|
var _a, _b;
|
|
3031
3053
|
return (_b = (_a = this.apiSchema) === null || _a === void 0 ? void 0 : _a.configs) === null || _b === void 0 ? void 0 : _b[key].events.includes(event);
|
|
3032
3054
|
}))) return;
|
|
3033
3055
|
const responses = {
|
|
3034
3056
|
default: Object.assign({}, this.api.default),
|
|
3035
|
-
named: Object.assign({}, this.api.named)
|
|
3057
|
+
named: Object.assign({}, this.api.named),
|
|
3058
|
+
apiState: Object.assign({}, this.api.apiState)
|
|
3036
3059
|
};
|
|
3037
3060
|
const config = (_e = this.apiSchema.defaultConfig) === null || _e === void 0 ? void 0 : _e.config;
|
|
3038
3061
|
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)) {
|
|
3062
|
+
!requestMadeOnce && this.notifyApiRequest();
|
|
3039
3063
|
const {
|
|
3040
3064
|
response,
|
|
3041
3065
|
status
|
|
3042
3066
|
} = yield configRequest(config);
|
|
3067
|
+
requestMadeOnce = true;
|
|
3043
3068
|
responses.default = {
|
|
3044
3069
|
response,
|
|
3045
3070
|
status
|
|
@@ -3057,10 +3082,12 @@ class FormField {
|
|
|
3057
3082
|
var _l, _m, _o, _p;
|
|
3058
3083
|
const config = (_m = (_l = this.apiSchema) === null || _l === void 0 ? void 0 : _l.configs) === null || _m === void 0 ? void 0 : _m[configKey].config;
|
|
3059
3084
|
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)) {
|
|
3085
|
+
!requestMadeOnce && this.notifyApiRequest();
|
|
3060
3086
|
const {
|
|
3061
3087
|
response,
|
|
3062
3088
|
status
|
|
3063
3089
|
} = yield configRequest(config);
|
|
3090
|
+
requestMadeOnce = true;
|
|
3064
3091
|
return {
|
|
3065
3092
|
name: configKey,
|
|
3066
3093
|
result: {
|
|
@@ -3076,7 +3103,11 @@ class FormField {
|
|
|
3076
3103
|
});
|
|
3077
3104
|
}
|
|
3078
3105
|
}
|
|
3079
|
-
|
|
3106
|
+
if (requestMadeOnce) {
|
|
3107
|
+
responses.apiState.lastEvent = event;
|
|
3108
|
+
responses.apiState.loading = false;
|
|
3109
|
+
this.api = responses;
|
|
3110
|
+
}
|
|
3080
3111
|
});
|
|
3081
3112
|
}
|
|
3082
3113
|
/**
|
|
@@ -3091,11 +3122,8 @@ class FormField {
|
|
|
3091
3122
|
this.fieldStateSubscription$.unsubscribe();
|
|
3092
3123
|
this.propsSubject$.unsubscribe();
|
|
3093
3124
|
this.errorSubject$.unsubscribe();
|
|
3094
|
-
this.apiSubject$.unsubscribe();
|
|
3095
3125
|
this.apiEventQueueSubject$.unsubscribe();
|
|
3096
|
-
|
|
3097
|
-
fieldTrigger: this.name
|
|
3098
|
-
});
|
|
3126
|
+
this.triggerFieldValidNotification();
|
|
3099
3127
|
}
|
|
3100
3128
|
/**
|
|
3101
3129
|
* Subscribes to changes in the field state and executes the provided callback function.
|
|
@@ -3151,6 +3179,8 @@ class FormCore {
|
|
|
3151
3179
|
this.queuedFieldResetValuesEvents = new Map();
|
|
3152
3180
|
this.queuedFieldResetPropertyEvents = new Map();
|
|
3153
3181
|
this.queuedInitialValues = new Map();
|
|
3182
|
+
this._valid = false;
|
|
3183
|
+
this.index = entry.index;
|
|
3154
3184
|
this.schema = entry.schema;
|
|
3155
3185
|
this.fields = new Map();
|
|
3156
3186
|
this.action = entry.action || ((_a = entry.schema) === null || _a === void 0 ? void 0 : _a.action);
|
|
@@ -3169,9 +3199,13 @@ class FormCore {
|
|
|
3169
3199
|
this.fieldEventSubject$ = new Subject();
|
|
3170
3200
|
this.dataSubject$ = new Subject();
|
|
3171
3201
|
this.mountSubject$ = new Subject();
|
|
3202
|
+
this.fieldValidNotification$ = new Subject();
|
|
3172
3203
|
this.formValidNotification$ = new Subject();
|
|
3173
3204
|
this.subscribedTemplates = [];
|
|
3174
3205
|
this.templateSubscription$ = this.templateSubject$.subscribe(this.refreshTemplates.bind(this));
|
|
3206
|
+
this.fieldValidNotification$.subscribe(() => {
|
|
3207
|
+
this.validateForm();
|
|
3208
|
+
});
|
|
3175
3209
|
this.mountSubject$.subscribe(this.mountActions.bind(this));
|
|
3176
3210
|
this.initialValues = entry.initialValues || ((_j = entry.schema) === null || _j === void 0 ? void 0 : _j.initialValues);
|
|
3177
3211
|
this.iVars = entry.iVars || ((_k = entry.schema) === null || _k === void 0 ? void 0 : _k.iVars) || {};
|
|
@@ -3273,16 +3307,30 @@ class FormCore {
|
|
|
3273
3307
|
});
|
|
3274
3308
|
}
|
|
3275
3309
|
/**
|
|
3276
|
-
*
|
|
3310
|
+
* Validates all form fields and sets the form valid flag
|
|
3277
3311
|
*
|
|
3278
|
-
* @returns {boolean} True if the form is valid; otherwise, false.
|
|
3279
3312
|
*/
|
|
3280
|
-
|
|
3281
|
-
if (this.fields.size === 0) return false;
|
|
3313
|
+
validateForm() {
|
|
3314
|
+
if (this.fields.size === 0) return this.valid = false;
|
|
3282
3315
|
for (const [, field] of this.fields) {
|
|
3283
|
-
if (!field.valid) return false;
|
|
3316
|
+
if (!field.valid) return this.valid = false;
|
|
3284
3317
|
}
|
|
3285
|
-
return true;
|
|
3318
|
+
return this.valid = true;
|
|
3319
|
+
}
|
|
3320
|
+
get valid() {
|
|
3321
|
+
return this._valid;
|
|
3322
|
+
}
|
|
3323
|
+
set valid(valid) {
|
|
3324
|
+
if (this._valid === valid) return;
|
|
3325
|
+
this._valid = valid;
|
|
3326
|
+
this.templateSubject$.next({
|
|
3327
|
+
event: 'ON_FORM',
|
|
3328
|
+
scope: 'form'
|
|
3329
|
+
});
|
|
3330
|
+
this.formValidNotification$.next({
|
|
3331
|
+
formIndex: this.index,
|
|
3332
|
+
valid: this.valid
|
|
3333
|
+
});
|
|
3286
3334
|
}
|
|
3287
3335
|
/**
|
|
3288
3336
|
* Subscribes to templates for dynamic updates.
|
|
@@ -3335,6 +3383,11 @@ class FormCore {
|
|
|
3335
3383
|
const value = get(this.iVars, [key, ...(property ? [property] : []), ...path]);
|
|
3336
3384
|
return value;
|
|
3337
3385
|
}
|
|
3386
|
+
case 'form':
|
|
3387
|
+
{
|
|
3388
|
+
const value = get(this, [key, ...(property ? [property] : []), ...path]);
|
|
3389
|
+
return value;
|
|
3390
|
+
}
|
|
3338
3391
|
case 'fields':
|
|
3339
3392
|
{
|
|
3340
3393
|
const field = this.fields.get(key);
|
|
@@ -3833,7 +3886,7 @@ class FormCore {
|
|
|
3833
3886
|
templateSubject$: this.templateSubject$,
|
|
3834
3887
|
fieldEventSubject$: this.fieldEventSubject$,
|
|
3835
3888
|
dataSubject$: this.dataSubject$,
|
|
3836
|
-
|
|
3889
|
+
fieldValidNotification$: this.fieldValidNotification$,
|
|
3837
3890
|
mountSubject$: this.mountSubject$,
|
|
3838
3891
|
config: this.config,
|
|
3839
3892
|
submitEvent: this.submit.bind(this),
|
|
@@ -3888,7 +3941,7 @@ class FormCore {
|
|
|
3888
3941
|
templateSubject$: this.templateSubject$,
|
|
3889
3942
|
fieldEventSubject$: this.fieldEventSubject$,
|
|
3890
3943
|
dataSubject$: this.dataSubject$,
|
|
3891
|
-
|
|
3944
|
+
fieldValidNotification$: this.fieldValidNotification$,
|
|
3892
3945
|
mountSubject$: this.mountSubject$,
|
|
3893
3946
|
config: this.config,
|
|
3894
3947
|
getFormValues: this.getFormValues.bind(this),
|
|
@@ -3988,7 +4041,7 @@ class FormCore {
|
|
|
3988
4041
|
values,
|
|
3989
4042
|
metadata,
|
|
3990
4043
|
erroredFields,
|
|
3991
|
-
isValid: this.
|
|
4044
|
+
isValid: this.valid
|
|
3992
4045
|
};
|
|
3993
4046
|
}
|
|
3994
4047
|
/**
|
|
@@ -4049,11 +4102,9 @@ class FormCore {
|
|
|
4049
4102
|
* @param {(payload: TFormValidationPayload) => void} callback callback function to call onValid
|
|
4050
4103
|
*/
|
|
4051
4104
|
subscribeFormValidation(callback) {
|
|
4052
|
-
const sub = this.formValidNotification$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS), map(({
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
fieldTrigger,
|
|
4056
|
-
valid: this.isValid
|
|
4105
|
+
const sub = this.formValidNotification$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS), map(() => ({
|
|
4106
|
+
formIndex: this.index,
|
|
4107
|
+
valid: this.valid
|
|
4057
4108
|
})), distinctUntilKeyChanged('valid')).subscribe({
|
|
4058
4109
|
next: callback
|
|
4059
4110
|
});
|
|
@@ -4068,7 +4119,7 @@ class FormCore {
|
|
|
4068
4119
|
event: 'ON_FIELD_VALIDATION'
|
|
4069
4120
|
});
|
|
4070
4121
|
});
|
|
4071
|
-
if (!this.
|
|
4122
|
+
if (!this.valid) return;
|
|
4072
4123
|
const values = this.getFormValues();
|
|
4073
4124
|
this.submitSubject$.next(values);
|
|
4074
4125
|
}
|
|
@@ -4081,6 +4132,7 @@ class FormCore {
|
|
|
4081
4132
|
this.fieldEventSubject$.unsubscribe();
|
|
4082
4133
|
this.dataSubject$.unsubscribe();
|
|
4083
4134
|
this.formValidNotification$.unsubscribe();
|
|
4135
|
+
this.fieldValidNotification$.unsubscribe();
|
|
4084
4136
|
this.fields.forEach(field => field.destroyField());
|
|
4085
4137
|
}
|
|
4086
4138
|
}
|
|
@@ -4297,11 +4349,11 @@ class FormGroup {
|
|
|
4297
4349
|
}) {
|
|
4298
4350
|
const subs = ids.reduce((acc, formId) => {
|
|
4299
4351
|
var _a;
|
|
4300
|
-
const sub = (_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.formValidNotification$.pipe(groupBy(payload => `${formId}.${payload.
|
|
4352
|
+
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({
|
|
4301
4353
|
fieldTrigger: null
|
|
4302
4354
|
}), map(() => {
|
|
4303
4355
|
var _a;
|
|
4304
|
-
return ((_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.
|
|
4356
|
+
return ((_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.valid) === false ? false : true;
|
|
4305
4357
|
}), distinctUntilChanged());
|
|
4306
4358
|
if (sub) {
|
|
4307
4359
|
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
|
@@ -2,7 +2,7 @@ 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,7 +44,6 @@ 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;
|
|
@@ -55,7 +54,7 @@ declare class FormField {
|
|
|
55
54
|
key: string;
|
|
56
55
|
event: TEvents;
|
|
57
56
|
}>;
|
|
58
|
-
|
|
57
|
+
fieldValidNotification$: Subject<TFieldValidationPayload>;
|
|
59
58
|
mountSubject$: Subject<{
|
|
60
59
|
key: string;
|
|
61
60
|
status: boolean;
|
|
@@ -93,7 +92,7 @@ declare class FormField {
|
|
|
93
92
|
* @param {TMapper<unknown>} options.mapper, - component generic mapper containing render parameters for adapters
|
|
94
93
|
* @param {() => TFormValues<unknown>} options.getFormValues, - form instance function that builds onData parameter payload from fields
|
|
95
94
|
*/
|
|
96
|
-
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, }: {
|
|
97
96
|
schemaComponent: IComponentSchema;
|
|
98
97
|
config?: TSchemaFormConfig;
|
|
99
98
|
path?: string;
|
|
@@ -117,7 +116,7 @@ declare class FormField {
|
|
|
117
116
|
key: string;
|
|
118
117
|
event: TEvents;
|
|
119
118
|
}>;
|
|
120
|
-
|
|
119
|
+
fieldValidNotification$: Subject<TFieldValidationPayload>;
|
|
121
120
|
mountSubject$: Subject<{
|
|
122
121
|
key: string;
|
|
123
122
|
status: boolean;
|
|
@@ -192,6 +191,14 @@ declare class FormField {
|
|
|
192
191
|
* @returns {boolean} - The validity status of the form field.
|
|
193
192
|
*/
|
|
194
193
|
get valid(): boolean;
|
|
194
|
+
/**
|
|
195
|
+
* triggers field valid notification to handle the form instance valid notification
|
|
196
|
+
*
|
|
197
|
+
* Note: since form unmount can occur before field unmount, this subject might already be closed by form instance
|
|
198
|
+
* quick workaround is to check if the subject is already closed before emitting
|
|
199
|
+
* if form instance onValid or template form.valid doesn't work properly, might be due to this workaround
|
|
200
|
+
*/
|
|
201
|
+
triggerFieldValidNotification(): void;
|
|
195
202
|
/**
|
|
196
203
|
* Retrieves the error messages associated with the form field.
|
|
197
204
|
*
|
|
@@ -217,7 +224,10 @@ declare class FormField {
|
|
|
217
224
|
*/
|
|
218
225
|
set api(response: TApiResponse);
|
|
219
226
|
/**
|
|
220
|
-
*
|
|
227
|
+
* notifies templates and event binded field configurations that a request starts it's processing
|
|
228
|
+
*/
|
|
229
|
+
notifyApiRequest(): void;
|
|
230
|
+
/** Retrieves the mounted status of the field.
|
|
221
231
|
*
|
|
222
232
|
* @returns {boolean} - the mounted status of the field.
|
|
223
233
|
*/
|
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
|