@messaia/cdk 21.1.0-rc.32 → 21.1.0-rc.33

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.
@@ -3969,31 +3969,31 @@ function getNestedOptions(controlName, options) {
3969
3969
  }
3970
3970
 
3971
3971
  /**
3972
- * Function to provide an instance of a given function with optional entity object.
3972
+ * Provides an instance container for a given model function and optional entity object.
3973
3973
  * @param instanceFunc The function to provide an instance of.
3974
3974
  * @param entityObject Optional entity object.
3975
3975
  * @returns An instance container.
3976
3976
  */
3977
3977
  function instanceProvider(instanceFunc, entityObject) {
3978
- /* Getting an instance from the defaultContainer */
3978
+ /* Get the instance container from defaultContainer */
3979
3979
  let instance = defaultContainer.get(instanceFunc);
3980
- /* Setting the prototype based on the entityObject or instanceFunc */
3980
+ /* Determine the prototype from entityObject or a temporary instance */
3981
3981
  let prototype = entityObject ? entityObject.__proto__ : getInstance(instanceFunc, []).__proto__;
3982
- /* Checking if prototype's prototype exists */
3982
+ /* Continue while parent prototypes exist */
3983
3983
  if (prototype.__proto__) {
3984
- /* Initializing loop flag */
3984
+ /* Initialize loop flag */
3985
3985
  let isLoop = false;
3986
3986
  do {
3987
- /* Checking if prototype's prototype is not Object */
3987
+ /* Continue until Object is reached in the prototype chain */
3988
3988
  isLoop = prototype.__proto__.constructor != Object;
3989
3989
  if (isLoop) {
3990
- /* Getting extendClassInstance from defaultContainer */
3990
+ /* Get parent class instance container from defaultContainer */
3991
3991
  let extendClassInstance = defaultContainer.get(prototype.__proto__.constructor);
3992
- /* Cloning instance */
3992
+ /* Clone current instance */
3993
3993
  var instanceClone = clone(instance);
3994
- /* Cloning extendClassInstance */
3994
+ /* Clone parent instance */
3995
3995
  var extendClassInstanceClone = clone(extendClassInstance);
3996
- /* Start: Removing properties from extendClassInstanceClone.properties that exist in instanceClone.properties */
3996
+ /* Remove duplicated properties already defined in the child instance */
3997
3997
  instanceClone.properties?.forEach((property) => {
3998
3998
  /* Find the index of the property in extendClassInstanceClone */
3999
3999
  const index = extendClassInstanceClone.properties?.findIndex((p) => p.name === property.name);
@@ -4002,7 +4002,7 @@ function instanceProvider(instanceFunc, entityObject) {
4002
4002
  extendClassInstanceClone.properties?.splice(index, 1);
4003
4003
  }
4004
4004
  });
4005
- /* Merge instanceClone with modified extendClassInstanceClone */
4005
+ /* Merge child and filtered parent instance containers */
4006
4006
  instance = merge(instanceClone, extendClassInstanceClone);
4007
4007
  prototype = prototype.__proto__;
4008
4008
  }
@@ -4011,7 +4011,7 @@ function instanceProvider(instanceFunc, entityObject) {
4011
4011
  return instance;
4012
4012
  }
4013
4013
  /**
4014
- * Function to get an instance of a model with object arguments.
4014
+ * Creates an instance of a model using the provided constructor arguments.
4015
4015
  * @param model The model to instantiate.
4016
4016
  * @param objectArguments Arguments for the model instantiation.
4017
4017
  * @returns The instantiated class instance.
@@ -10100,7 +10100,38 @@ class RxFormBuilder extends BaseFormBuilder {
10100
10100
  */
10101
10101
  isNestedBinding = false;
10102
10102
  /**
10103
- * Private method: Gets the instance container based on the instance function and entity object.
10103
+ * Private method: Resolves effective validators for a property.
10104
+ *
10105
+ * If the same annotation type appears multiple times (for example, inherited + overridden),
10106
+ * only the first occurrence is kept and later duplicates are ignored.
10107
+ *
10108
+ * @param propertyValidators The complete list of validator decorator configurations.
10109
+ * @param isAsync Indicates whether async or sync validators should be resolved.
10110
+ * @returns The effective validator decorator configurations for the requested validator kind.
10111
+ */
10112
+ getEffectivePropertyValidators(propertyValidators, isAsync) {
10113
+ /* Initialize result containers for effective validators and seen annotation types */
10114
+ const effectiveValidators = [];
10115
+ const seenAnnotationTypes = new Set();
10116
+ /* Iterate through the provided property validators */
10117
+ for (const propertyValidator of propertyValidators ?? []) {
10118
+ /* Skip validators that do not match the requested async/sync kind */
10119
+ if (!!propertyValidator.isAsync !== isAsync) {
10120
+ continue;
10121
+ }
10122
+ /* Skip duplicate annotation types, keeping only the first occurrence */
10123
+ const annotationType = propertyValidator.annotationType;
10124
+ if (seenAnnotationTypes.has(annotationType)) {
10125
+ continue;
10126
+ }
10127
+ /* Mark the annotation type as seen and keep the validator */
10128
+ seenAnnotationTypes.add(annotationType);
10129
+ effectiveValidators.push(propertyValidator);
10130
+ }
10131
+ return effectiveValidators;
10132
+ }
10133
+ /**
10134
+ * Private method: Gets the instance container for the given instance function and entity object.
10104
10135
  *
10105
10136
  * @param instanceFunc The function to provide an instance from.
10106
10137
  * @param entityObject The entity object to use.
@@ -10123,7 +10154,7 @@ class RxFormBuilder extends BaseFormBuilder {
10123
10154
  if (formBuilderConfiguration && formBuilderConfiguration.dynamicValidation) {
10124
10155
  for (var property in formBuilderConfiguration.dynamicValidation) {
10125
10156
  for (var decorator in formBuilderConfiguration.dynamicValidation[property]) {
10126
- /* Checks if a conditional expression exists for the current decorator */
10157
+ /* Checks whether a conditional expression exists for the current decorator */
10127
10158
  if (formBuilderConfiguration.dynamicValidation[property][decorator].conditionalExpression) {
10128
10159
  /* Extract columns from the conditional expression */
10129
10160
  let columns = Linq.expressionColumns(formBuilderConfiguration.dynamicValidation[property][decorator].conditionalExpression);
@@ -10144,16 +10175,13 @@ class RxFormBuilder extends BaseFormBuilder {
10144
10175
  * @returns An array of async validators.
10145
10176
  */
10146
10177
  addAsyncValidation(property, propertyValidators, propValidationConfig) {
10147
- /* Collects async validators from property validators and validation configuration */
10178
+ /* Collect async validators from property validators and validation configuration */
10148
10179
  let asyncValidators = [];
10149
10180
  if (propertyValidators) {
10150
- /* Iterate through property validators */
10151
- for (let propertyValidator of propertyValidators) {
10152
- /* Check if the validator is async */
10153
- if (propertyValidator.isAsync) {
10154
- /* Push each async validator into the asyncValidators array */
10155
- propertyValidator.config.forEach((t) => { asyncValidators.push(t); });
10156
- }
10181
+ /* Iterate through effective async property validators */
10182
+ for (let propertyValidator of this.getEffectivePropertyValidators(propertyValidators, true)) {
10183
+ /* Push each async validator into the asyncValidators array */
10184
+ propertyValidator.config.forEach((t) => { asyncValidators.push(t); });
10157
10185
  }
10158
10186
  }
10159
10187
  if (propValidationConfig && propValidationConfig[ASYNC]) {
@@ -10175,30 +10203,30 @@ class RxFormBuilder extends BaseFormBuilder {
10175
10203
  addFormControl(property, propertyValidators, propValidationConfig, instance, entity) {
10176
10204
  let validators = [];
10177
10205
  let columns = [];
10178
- /* Check if conditional validation props are defined either in instance or conditionalValidationInstance */
10206
+ /* Check whether conditional validation properties exist in either source */
10179
10207
  if ((instance.conditionalValidationProps && instance.conditionalValidationProps[property.name]) || (this.conditionalValidationInstance.conditionalValidationProps && this.conditionalValidationInstance.conditionalValidationProps[property.name])) {
10180
- /* Collects conditional validation properties from instance and conditionalValidationInstance and adds conditional change validator */
10208
+ /* Collect conditional validation properties and add a conditional change validator */
10181
10209
  let props = [];
10182
- /* Check if conditionalValidationProps are defined in instance for the property */
10210
+ /* Check whether instance has conditionalValidationProps for the property */
10183
10211
  if ((instance.conditionalValidationProps && instance.conditionalValidationProps[property.name])) {
10184
10212
  instance.conditionalValidationProps[property.name].forEach(t => props.push(t));
10185
10213
  }
10186
- /* Check if conditionalValidationProps are defined in conditionalValidationInstance for the property */
10214
+ /* Check whether conditionalValidationInstance has conditionalValidationProps for the property */
10187
10215
  if (this.conditionalValidationInstance.conditionalValidationProps && this.conditionalValidationInstance.conditionalValidationProps[property.name]) {
10188
10216
  this.conditionalValidationInstance.conditionalValidationProps[property.name].forEach((t) => props.push(t));
10189
10217
  }
10190
10218
  /* Add conditional change validator */
10191
10219
  validators.push(conditionalChangeValidator(props));
10192
10220
  }
10193
- /* Check if conditionalObjectProps or builderConfigurationConditionalObjectProps are defined */
10221
+ /* Check whether conditional object properties are present */
10194
10222
  if (this.conditionalObjectProps.length > 0 || this.builderConfigurationConditionalObjectProps.length > 0) {
10195
10223
  let propConditions = [];
10196
- /* Check if conditionalObjectProps is defined */
10224
+ /* Check whether conditionalObjectProps is defined */
10197
10225
  if (this.conditionalObjectProps) {
10198
10226
  /* Filter conditionalObjectProps for properties matching the current property name */
10199
10227
  propConditions = this.conditionalObjectProps.filter(t => t.propName == property.name);
10200
10228
  }
10201
- /* Check if builderConfigurationConditionalObjectProps is defined */
10229
+ /* Check whether builderConfigurationConditionalObjectProps is defined */
10202
10230
  if (this.builderConfigurationConditionalObjectProps) {
10203
10231
  /* Filter builderConfigurationConditionalObjectProps for properties matching the current property name */
10204
10232
  this.builderConfigurationConditionalObjectProps.filter(t => t.propName == property.name).forEach(t => propConditions.push(t));
@@ -10214,25 +10242,23 @@ class RxFormBuilder extends BaseFormBuilder {
10214
10242
  validators.push(conditionalChangeValidator(columns));
10215
10243
  }
10216
10244
  }
10217
- /* Iterate through property validators */
10218
- for (let propertyValidator of propertyValidators) {
10219
- if (!propertyValidator.isAsync) {
10220
- switch (propertyValidator.annotationType) {
10221
- /* Add rule validator */
10222
- case AnnotationTypes["rule"]:
10223
- validators.push(APP_VALIDATORS[propertyValidator.annotationType](propertyValidator.config, entity));
10224
- break;
10225
- /* Add logical validator */
10226
- case AnnotationTypes["and"]:
10227
- case AnnotationTypes["or"]:
10228
- case AnnotationTypes["not"]:
10229
- validators.push(LOGICAL_VALIDATORS[propertyValidator.annotationType](propertyValidator.config));
10230
- break;
10231
- /* Add custom validator */
10232
- default:
10233
- validators.push(APP_VALIDATORS[propertyValidator.annotationType](propertyValidator.config));
10234
- break;
10235
- }
10245
+ /* Iterate through effective sync property validators */
10246
+ for (let propertyValidator of this.getEffectivePropertyValidators(propertyValidators, false)) {
10247
+ switch (propertyValidator.annotationType) {
10248
+ /* Add rule validator */
10249
+ case AnnotationTypes["rule"]:
10250
+ validators.push(APP_VALIDATORS[propertyValidator.annotationType](propertyValidator.config, entity));
10251
+ break;
10252
+ /* Add logical validator */
10253
+ case AnnotationTypes["and"]:
10254
+ case AnnotationTypes["or"]:
10255
+ case AnnotationTypes["not"]:
10256
+ validators.push(LOGICAL_VALIDATORS[propertyValidator.annotationType](propertyValidator.config));
10257
+ break;
10258
+ /* Add custom validator */
10259
+ default:
10260
+ validators.push(APP_VALIDATORS[propertyValidator.annotationType](propertyValidator.config));
10261
+ break;
10236
10262
  }
10237
10263
  }
10238
10264
  /* Additional validation from propValidationConfig */
@@ -10253,12 +10279,12 @@ class RxFormBuilder extends BaseFormBuilder {
10253
10279
  */
10254
10280
  additionalValidation(validations, propValidationConfig) {
10255
10281
  for (var col in AnnotationTypes) {
10256
- /* Check if the validation configuration for the current annotation type exists and it's not a custom validator */
10282
+ /* Check whether the validation configuration for the current annotation type exists and is not a custom validator */
10257
10283
  if (propValidationConfig[AnnotationTypes[col]] && col != "custom") {
10258
10284
  /* Add validator from APP_VALIDATORS */
10259
10285
  validations.push(APP_VALIDATORS[AnnotationTypes[col]](propValidationConfig[AnnotationTypes[col]]));
10260
10286
  }
10261
- /* Check if the current annotation type is custom and the custom validator exists in the validation configuration */
10287
+ /* Check whether the current annotation type is custom and exists in the validation configuration */
10262
10288
  else if (col == AnnotationTypes["custom"] && propValidationConfig[AnnotationTypes[col]]) {
10263
10289
  /* Add custom validator */
10264
10290
  validations.push(propValidationConfig[col]);
@@ -10275,7 +10301,7 @@ class RxFormBuilder extends BaseFormBuilder {
10275
10301
  * @returns The entity type.
10276
10302
  */
10277
10303
  getEntity(object, formBuilderConfiguration, propertyName, isSameObjectConstructor = false) {
10278
- /* Check if the entity type is defined in the form builder configuration */
10304
+ /* Check whether the entity type is defined in the form builder configuration */
10279
10305
  if (formBuilderConfiguration && formBuilderConfiguration.genericEntities && formBuilderConfiguration.genericEntities[propertyName]) {
10280
10306
  /* Return the entity type from formBuilderConfiguration if available */
10281
10307
  return formBuilderConfiguration.genericEntities[propertyName];
@@ -10292,12 +10318,12 @@ class RxFormBuilder extends BaseFormBuilder {
10292
10318
  * @returns The constructor of the object property instance.
10293
10319
  */
10294
10320
  getObjectPropertyInstance(object, propertyInfo, formBuilderConfiguration) {
10295
- /* Check if the property type is OBJECT_PROPERTY and the property exists in the object */
10321
+ /* Check whether the property type is OBJECT_PROPERTY and the property exists in the object */
10296
10322
  if (propertyInfo.propertyType == OBJECT_PROPERTY && object[propertyInfo.name]) {
10297
10323
  /* Return the constructor of the object property if it exists */
10298
10324
  return object[propertyInfo.name].constructor;
10299
10325
  }
10300
- /* Check if the property type is ARRAY_PROPERTY and the property exists and contains items in the object */
10326
+ /* Check whether the property type is ARRAY_PROPERTY and the property exists and contains items in the object */
10301
10327
  else if (propertyInfo.propertyType == ARRAY_PROPERTY && object[propertyInfo.name] && object[propertyInfo.name].length > 0) {
10302
10328
  /* Return the constructor of the first item in the array property if it exists */
10303
10329
  return object[propertyInfo.name][0].constructor;
@@ -10323,7 +10349,7 @@ class RxFormBuilder extends BaseFormBuilder {
10323
10349
  entity = this.getObjectPropertyInstance(object, t, formBuilderConfiguration);
10324
10350
  if (entity) {
10325
10351
  let instance = this.getInstanceContainer(entity, null);
10326
- /* Check if instance exists and has conditional validation properties */
10352
+ /* Check whether the instance exists and has conditional validation properties */
10327
10353
  if (instance && instance.conditionalValidationProps) {
10328
10354
  for (var key in instance.conditionalValidationProps) {
10329
10355
  var prop = instanceContainer.properties?.filter(t => t.name == key)[0];
@@ -10359,24 +10385,24 @@ class RxFormBuilder extends BaseFormBuilder {
10359
10385
  getObject(model, entityObject, formBuilderConfiguration) {
10360
10386
  /* Initializes an empty object to store the JSON representation */
10361
10387
  let json = {};
10362
- /* Checks if the model is a function */
10388
+ /* Checks whether the model is a function */
10363
10389
  if (typeof model == FUNCTION_STRING) {
10364
10390
  json["model"] = model;
10365
10391
  }
10366
- /* Checks if the model is a function and entityObject is an instance of FormBuilderConfiguration */
10392
+ /* Checks whether the model is a function and entityObject is an instance of FormBuilderConfiguration */
10367
10393
  if (typeof model == FUNCTION_STRING && (entityObject instanceof FormBuilderConfiguration)) {
10368
10394
  /* Creates the entity object using createClassObject method */
10369
10395
  json["entityObject"] = this.createClassObject(json["model"], entityObject);
10370
10396
  }
10371
- /* Checks if entityObject exists and is not an instance of FormBuilderConfiguration */
10397
+ /* Checks whether entityObject exists and is not an instance of FormBuilderConfiguration */
10372
10398
  if (entityObject && !(entityObject instanceof FormBuilderConfiguration)) {
10373
10399
  json["entityObject"] = entityObject;
10374
10400
  }
10375
- /* Checks if entityObject is an instance of FormBuilderConfiguration and formBuilderConfiguration is not provided */
10401
+ /* Checks whether entityObject is an instance of FormBuilderConfiguration and formBuilderConfiguration is not provided */
10376
10402
  if (entityObject instanceof FormBuilderConfiguration && !formBuilderConfiguration) {
10377
10403
  json["formBuilderConfiguration"] = entityObject;
10378
10404
  }
10379
- /* Checks if entityObject is not an instance of FormBuilderConfiguration and formBuilderConfiguration is provided */
10405
+ /* Checks whether entityObject is not an instance of FormBuilderConfiguration and formBuilderConfiguration is provided */
10380
10406
  else if (!(entityObject instanceof FormBuilderConfiguration) && formBuilderConfiguration) {
10381
10407
  /* Sets the formBuilderConfiguration in the JSON */
10382
10408
  json["formBuilderConfiguration"] = formBuilderConfiguration;
@@ -10385,7 +10411,7 @@ class RxFormBuilder extends BaseFormBuilder {
10385
10411
  }
10386
10412
  /* If entityObject does not exist */
10387
10413
  if (!entityObject) {
10388
- /* Checks if the model is an object */
10414
+ /* Checks whether the model is an object */
10389
10415
  if (typeof model == OBJECT_STRING) {
10390
10416
  /* Stores the constructor of the model */
10391
10417
  json["model"] = model.constructor;
@@ -10472,19 +10498,19 @@ class RxFormBuilder extends BaseFormBuilder {
10472
10498
  * @param modelInstance The instance of the model.
10473
10499
  */
10474
10500
  applyAllPropValidator(propName, validatorConfig, modelInstance) {
10475
- /* Check if the validator configuration and applyAllProps array exist */
10501
+ /* Check whether the validator configuration and applyAllProps array exist */
10476
10502
  if (validatorConfig && validatorConfig.applyAllProps) {
10477
- /* Check if the excludeProps array exists and if the propName is not in the excludeProps array */
10503
+ /* Check whether the excludeProps array exists and propName should be included */
10478
10504
  if (!(validatorConfig.excludeProps && validatorConfig.excludeProps.length > 0 && validatorConfig.excludeProps.indexOf(propName) == -1)) {
10479
10505
  /* Iterate through each item in the applyAllProps array */
10480
10506
  validatorConfig.applyAllProps.forEach((t) => {
10481
- /* Check if the validator function is an RxWeb validator */
10507
+ /* Check whether the validator function is an RxWeb validator */
10482
10508
  if (t.name == RX_WEB_VALIDATOR) {
10483
10509
  /* Apply RxWeb validator to the propName with the modelInstance */
10484
10510
  t(propName, modelInstance);
10485
10511
  }
10486
10512
  else {
10487
- /* Check if the currentFormGroupPropOtherValidator has an entry for the propName */
10513
+ /* Check whether currentFormGroupPropOtherValidator has an entry for propName */
10488
10514
  if (!this.currentFormGroupPropOtherValidator[propName]) {
10489
10515
  /* If not, create an empty array for the propName */
10490
10516
  this.currentFormGroupPropOtherValidator[propName] = [];
@@ -10497,7 +10523,7 @@ class RxFormBuilder extends BaseFormBuilder {
10497
10523
  }
10498
10524
  }
10499
10525
  /**
10500
- * Checks if dynamic validation should be applied to a property.
10526
+ * Checks whether dynamic validation should be applied to a property.
10501
10527
  *
10502
10528
  * @param propName The name of the property to check.
10503
10529
  * @param validatorConfig The configuration for property validation.
@@ -10507,7 +10533,7 @@ class RxFormBuilder extends BaseFormBuilder {
10507
10533
  return (validatorConfig == undefined) ? true : (!validatorConfig.dynamicValidationConfigurationPropertyName) ? true : validatorConfig.dynamicValidationConfigurationPropertyName == propName ? false : true;
10508
10534
  }
10509
10535
  /**
10510
- * Checks if the given value is not an object.
10536
+ * Checks whether the given value is not an object.
10511
10537
  *
10512
10538
  * @param value The value to check.
10513
10539
  * @returns A boolean indicating whether the value is not an object.
@@ -10527,7 +10553,7 @@ class RxFormBuilder extends BaseFormBuilder {
10527
10553
  /* Iterates over each property in the groupObject to create form controls and apply validators. */
10528
10554
  for (var propName in groupObject) {
10529
10555
  var prop = groupObject[propName];
10530
- /* Check if the property is an array and needs validation */
10556
+ /* Check whether the property is an array and needs validation */
10531
10557
  if (prop instanceof Array && prop.length > 0 && this.isNotObject(prop[0])) {
10532
10558
  let propValidators = (prop.length > 1 && prop[1] instanceof Array) ? prop[1] : (prop.length == 2) ? [prop[1]] : [];
10533
10559
  let propertyAdded = false;
@@ -10615,7 +10641,7 @@ class RxFormBuilder extends BaseFormBuilder {
10615
10641
  entityObject[propName] = {};
10616
10642
  entityObject[propName].constructor = propModelInstance.constructor;
10617
10643
  defaultContainer.initPropertyObject(propName, OBJECT_PROPERTY, entityObject[propName].constructor, modelInstance.constructor == Function ? { constructor: modelInstance } : modelInstance);
10618
- /* Get the validation configuration for the property */
10644
+ /* Retrieve the validation configuration for the property */
10619
10645
  let objectValidationConfig = this.getValidatorConfig(validatorConfig, groupObject, propName + ".");
10620
10646
  /* Recursively create the validator form group for the property */
10621
10647
  this.createValidatorFormGroup(groupObject[propName], entityObject[propName], entityObject[propName].constructor, objectValidationConfig);
@@ -10658,7 +10684,7 @@ class RxFormBuilder extends BaseFormBuilder {
10658
10684
  let excludeProps = [];
10659
10685
  let includeProps = [];
10660
10686
  let ignoreUndefinedProps = [];
10661
- /* Check if the validatorConfig exists */
10687
+ /* Check whether validatorConfig exists */
10662
10688
  if (!validatorConfig)
10663
10689
  return {};
10664
10690
  /* Retrieve validation properties and abstract control options */
@@ -10728,7 +10754,7 @@ class RxFormBuilder extends BaseFormBuilder {
10728
10754
  let props = [];
10729
10755
  /* Iterate through the properties */
10730
10756
  for (let prop of properties) {
10731
- /* Check if the property contains the rootPropertyName */
10757
+ /* Check whether the property contains rootPropertyName */
10732
10758
  if (prop.indexOf(rootPropertyName) != -1) {
10733
10759
  let splitProps = prop.split(".");
10734
10760
  /* If the property has two parts, add the second part to the props array */
@@ -10762,7 +10788,7 @@ class RxFormBuilder extends BaseFormBuilder {
10762
10788
  model = json["model"];
10763
10789
  entityObject = json["entityObject"];
10764
10790
  /*
10765
- * If the entity object's constructor differs from the model's constructor and formGroup is not previously called,
10791
+ * If the entity object's constructor differs from the model's constructor and formGroup was not called previously,
10766
10792
  * update the entity object to match the model.
10767
10793
  */
10768
10794
  if (entityObject.constructor != model && !this.isGroupCalled) {
@@ -10773,7 +10799,7 @@ class RxFormBuilder extends BaseFormBuilder {
10773
10799
  if (formBuilderConfiguration) {
10774
10800
  this.extractExpressions(formBuilderConfiguration);
10775
10801
  }
10776
- /* Get the container for instances based on the model and entity object. */
10802
+ /* Retrieve the instance container based on the model and entity object. */
10777
10803
  let instanceContainer = this.getInstanceContainer(model, entityObject);
10778
10804
  /* Check and apply additional validation for object properties. */
10779
10805
  this.checkObjectPropAdditionalValidation(instanceContainer, entityObject, formBuilderConfiguration);
@@ -10784,21 +10810,21 @@ class RxFormBuilder extends BaseFormBuilder {
10784
10810
  /* Iterate through properties defined in the instance container. */
10785
10811
  instanceContainer.properties?.forEach(property => {
10786
10812
  let isIncludeProp = true;
10787
- /* Check if the property should be included based on form builder configuration. */
10813
+ /* Check whether the property should be included based on form builder configuration. */
10788
10814
  if (formBuilderConfiguration) {
10789
- /* Check if the property should be excluded based on form builder configuration. */
10815
+ /* Check whether the property should be excluded based on form builder configuration. */
10790
10816
  if (formBuilderConfiguration.excludeProps && formBuilderConfiguration.excludeProps.length > 0) {
10791
10817
  isIncludeProp = formBuilderConfiguration.excludeProps.indexOf(property.name) == -1;
10792
10818
  }
10793
- /* Check if dynamic validation is provided in the form builder configuration. */
10819
+ /* Check whether dynamic validation is provided in the form builder configuration. */
10794
10820
  if (formBuilderConfiguration.dynamicValidation) {
10795
10821
  additionalValidations = formBuilderConfiguration.dynamicValidation;
10796
10822
  }
10797
- /* Check if the property should be included based on form builder configuration. */
10823
+ /* Check whether the property should be included based on form builder configuration. */
10798
10824
  if (formBuilderConfiguration.includeProps && formBuilderConfiguration.includeProps.length > 0) {
10799
10825
  isIncludeProp = formBuilderConfiguration.includeProps.indexOf(property.name) != -1;
10800
10826
  }
10801
- /* Check if undefined properties should be ignored based on form builder configuration. */
10827
+ /* Check whether undefined properties should be ignored based on form builder configuration. */
10802
10828
  if (formBuilderConfiguration.ignoreUndefinedProps && formBuilderConfiguration.ignoreUndefinedProps.length > 0) {
10803
10829
  isIncludeProp = !(property.propertyType == PROPERTY &&
10804
10830
  !RegexValidator.isNotBlank(json["entityObject"][property.name]) &&
@@ -10976,7 +11002,7 @@ class RxFormBuilder extends BaseFormBuilder {
10976
11002
  json["entityObject"]["formGroup"] = formGroup;
10977
11003
  this.overrideProperties(formGroup, json["entityObject"], extendedProperties);
10978
11004
  }
10979
- /* If not in nested binding mode and formGroup is not previously called, refresh disable status of the form group. */
11005
+ /* If not in nested binding mode and formGroup was not called previously, refresh disable status of the form group. */
10980
11006
  if (!this.isNestedBinding && !this.isGroupCalled) {
10981
11007
  formGroup.refreshDisable();
10982
11008
  }
@@ -11004,7 +11030,7 @@ class RxFormBuilder extends BaseFormBuilder {
11004
11030
  if (formBuilderConfiguration && formBuilderConfiguration.abstractControlOptions && formBuilderConfiguration.abstractControlOptions[name]) {
11005
11031
  abstractControlOptions.updateOn = formBuilderConfiguration.abstractControlOptions[name];
11006
11032
  }
11007
- /* Check if controlOptions are defined in formBuilderConfiguration */
11033
+ /* Check whether controlOptions are defined in formBuilderConfiguration */
11008
11034
  const controlOptions = formBuilderConfiguration ? formBuilderConfiguration.baseAbstractControlOptions : null;
11009
11035
  if (controlOptions && controlOptions[name]) {
11010
11036
  /* Update updateOn option from controlOptions if defined */
@@ -11044,7 +11070,7 @@ class RxFormBuilder extends BaseFormBuilder {
11044
11070
  * @param formGroup The RxFormGroup associated with the entity object.
11045
11071
  */
11046
11072
  overrideProp(entityObject, propName, formGroup) {
11047
- /* Get the property descriptor and current value */
11073
+ /* Retrieve the property descriptor and current value */
11048
11074
  let descriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(entityObject), propName);
11049
11075
  let value = entityObject[propName];
11050
11076
  let oldValue = null;
@@ -11055,7 +11081,7 @@ class RxFormBuilder extends BaseFormBuilder {
11055
11081
  /* Custom setter */
11056
11082
  set: (v) => {
11057
11083
  value = v;
11058
- /* Check if value has changed */
11084
+ /* Check whether the value has changed */
11059
11085
  if (oldValue != v) {
11060
11086
  /* Call the original setter if defined */
11061
11087
  if (descriptor) {
@@ -12403,9 +12429,10 @@ var Salutation;
12403
12429
  })(Salutation || (Salutation = {}));
12404
12430
 
12405
12431
  /**
12406
- * Property decorator to add display name to a property
12407
- * @param name
12408
- * @returns
12432
+ * Property decorator to define a display name for a class property.
12433
+ * This decorator can be applied to a class property to specify its display name, which can be used in UI components or other contexts.
12434
+ * @param name The display name to associate with the property.
12435
+ * @returns A property decorator function.
12409
12436
  */
12410
12437
  function Display(name) {
12411
12438
  return function (target, propertyKey) {
@@ -12413,9 +12440,10 @@ function Display(name) {
12413
12440
  };
12414
12441
  }
12415
12442
  /**
12416
- * Class decorator to add endpoint to an entity
12417
- * @param endpoint
12418
- * @returns
12443
+ * Class decorator to define an API endpoint for a given class.
12444
+ * This decorator can be applied to a class to specify the API endpoint associated with it, which can be used for data retrieval or other operations.
12445
+ * @param endpoint The API endpoint to associate with the class.
12446
+ * @returns A class decorator function.
12419
12447
  */
12420
12448
  function Api(endpoint) {
12421
12449
  return function (target) {
@@ -22076,8 +22104,13 @@ class VdChipsComponent extends AbstractMatFormField {
22076
22104
  set params(params) {
22077
22105
  /* Remove empty parameters */
22078
22106
  Utils.cleanObject(params);
22107
+ /* Update parameters if they have changed */
22079
22108
  if (!Utils.equals(this._params, params)) {
22080
22109
  this._params = params;
22110
+ /* Clear the current chips and reset the control state */
22111
+ if (this._params?.projection) {
22112
+ this._params.projection = parseProjectionString(this._params.projection);
22113
+ }
22081
22114
  }
22082
22115
  }
22083
22116
  /**
@@ -22089,7 +22122,7 @@ class VdChipsComponent extends AbstractMatFormField {
22089
22122
  */
22090
22123
  get projection() { return this._projection; }
22091
22124
  set projection(projection) {
22092
- this._projection = projection;
22125
+ this._projection = parseProjectionString(projection);
22093
22126
  this.clear();
22094
22127
  }
22095
22128
  /**
@@ -24180,7 +24213,7 @@ class VdGenericFormComponent {
24180
24213
  }
24181
24214
  };
24182
24215
  /* Update dynamic properties for each field and subscribe to form value changes */
24183
- this.fields?.forEach(x => {
24216
+ fields?.forEach(x => {
24184
24217
  const orgField = this.fields?.find(y => y.name == x.name);
24185
24218
  if (orgField) {
24186
24219
  updateFormField(orgField, x);
@@ -25273,9 +25306,95 @@ class FormFieldDefinition {
25273
25306
 
25274
25307
  const unwarppedFormFields = [FormFieldType.Checkbox, FormFieldType.Editor, FormFieldType.Code, FormFieldType.File, FormFieldType.Custom];
25275
25308
  /**
25276
- * Class decorator to create a form
25277
- * @param formDefinition
25278
- * @returns
25309
+ * Creates a form field definition based on the provided target, property key, and arguments.
25310
+ * @param target The target object containing the property.
25311
+ * @param propertyKey The key of the property for which the form field is being defined.
25312
+ * @param args Partial arguments to customize the form field definition.
25313
+ * @returns A FormFieldDefinition object representing the form field.
25314
+ */
25315
+ function createFormFieldDefinition(target, propertyKey, args) {
25316
+ /* Get property type */
25317
+ var propertyType = Reflect.getMetadata("design:type", target, propertyKey)?.name;
25318
+ /* Get label from args, metadata, or property key */
25319
+ var label = args.label || Reflect.getMetadata(headerMetadataKey, target, propertyKey) || propertyKey;
25320
+ /* Create table column */
25321
+ var formField = new FormFieldDefinition(Object.assign(args, {
25322
+ name: args.name || propertyKey,
25323
+ label: label,
25324
+ autocompleteTemplate: args.autocompleteTemplate || ((option) => option[formField.autocompleteText ?? '']),
25325
+ chipTemplate: args.chipTemplate || ((chip) => (args.customValue ? chip : chip[formField.chipText ?? '']))
25326
+ }));
25327
+ /* Type enum */
25328
+ if (formField.enumType) {
25329
+ formField.type ||= FormFieldType.Enum;
25330
+ }
25331
+ /* Type VdSelect */
25332
+ else if (formField.endpoint) {
25333
+ formField.type ||= FormFieldType.VdSelect;
25334
+ }
25335
+ /* Type Select */
25336
+ else if (formField.options) {
25337
+ formField.type ||= FormFieldType.Select;
25338
+ }
25339
+ /* Type TextArea */
25340
+ else if (formField.rows) {
25341
+ formField.type ||= FormFieldType.TextArea;
25342
+ }
25343
+ /* Type File */
25344
+ else if (formField.filePath) {
25345
+ formField.type ||= FormFieldType.File;
25346
+ }
25347
+ /* Other types */
25348
+ else {
25349
+ switch (propertyType?.toLowerCase()) {
25350
+ case 'number':
25351
+ formField.type ||= FormFieldType.Text;
25352
+ formField.inputType ||= 'number';
25353
+ break;
25354
+ case 'date':
25355
+ formField.type ||= FormFieldType.Date;
25356
+ break;
25357
+ case 'boolean':
25358
+ formField.type ||= FormFieldType.Checkbox;
25359
+ break;
25360
+ default:
25361
+ formField.type ||= FormFieldType.Text;
25362
+ break;
25363
+ }
25364
+ }
25365
+ /* Set wrapped to false, if the field cant be wrapped in the <mat-form-field> */
25366
+ if (formField.type && unwarppedFormFields?.includes(formField.type)) {
25367
+ formField.wrapped = false;
25368
+ }
25369
+ /* Add class multiline to the form field */
25370
+ if (formField.multiline) {
25371
+ formField.cssClass += ' multiline';
25372
+ formField.cssClass = formField.cssClass?.trim();
25373
+ }
25374
+ /**
25375
+ * If the 'numbersOnly' flag is set to true and no custom pattern is defined,
25376
+ * set the pattern to allow only numbers after the optional prefix.
25377
+ */
25378
+ if (formField.numbersOnly && !formField.pattern) {
25379
+ /* Get the prefix */
25380
+ const prefix = formField.prefix ?? '';
25381
+ /* Set pattern to allow only numbers after the prefix */
25382
+ if (prefix) {
25383
+ formField.pattern = new RegExp(`^${prefix}[0-9]*$`);
25384
+ }
25385
+ /* No prefix case */
25386
+ else {
25387
+ formField.pattern = /^[0-9]*$/;
25388
+ }
25389
+ }
25390
+ return formField;
25391
+ }
25392
+
25393
+ /**
25394
+ * Class decorator to define a form definition for a given class.
25395
+ * This decorator can be applied to a class to specify its form configuration, including endpoint, projection, actions, and field groups.
25396
+ * @param formDefinition Optional partial configuration to customize the resulting FormDefinition.
25397
+ * @returns A class decorator function.
25279
25398
  */
25280
25399
  function Form(formDefinition) {
25281
25400
  return function (target) {
@@ -25284,88 +25403,26 @@ function Form(formDefinition) {
25284
25403
  };
25285
25404
  }
25286
25405
  /**
25287
- * Property decorator to create form fields
25288
- * @param args
25289
- * @returns
25406
+ * Property decorator to create and register form fields.
25407
+ * This decorator can be applied to a class property to automatically generate and register form fields based on the provided arguments.
25408
+ * @param args Partial arguments to customize the resulting FormFieldDefinition.
25409
+ * @returns A property decorator function.
25290
25410
  */
25291
25411
  function FormField(args) {
25292
25412
  return function (target, propertyKey) {
25293
25413
  /* Get property name */
25294
25414
  var propertyName = args.name || propertyKey;
25295
- /* Get property type */
25296
- var propertyType = Reflect.getMetadata("design:type", target, propertyKey)?.name;
25297
- /* Create table column */
25298
- var formField = new FormFieldDefinition(Object.assign(args, {
25299
- name: args.name || propertyKey,
25300
- label: args.label || Reflect.getMetadata(headerMetadataKey, target, propertyKey) || propertyName,
25301
- autocompleteTemplate: args.autocompleteTemplate || ((option) => option[formField.autocompleteText ?? '']),
25302
- chipTemplate: args.chipTemplate || ((chip) => (args.customValue ? chip : chip[formField.chipText ?? '']))
25303
- }));
25304
- /* Type enum */
25305
- if (formField.enumType) {
25306
- formField.type ||= FormFieldType.Enum;
25307
- }
25308
- /* Type VdSelect */
25309
- else if (formField.endpoint) {
25310
- formField.type ||= FormFieldType.VdSelect;
25311
- }
25312
- /* Type Select */
25313
- else if (formField.options) {
25314
- formField.type ||= FormFieldType.Select;
25315
- }
25316
- /* Type TextArea */
25317
- else if (formField.rows) {
25318
- formField.type ||= FormFieldType.TextArea;
25319
- }
25320
- /* Type File */
25321
- else if (formField.filePath) {
25322
- formField.type ||= FormFieldType.File;
25323
- }
25324
- /* Other types */
25325
- else {
25326
- switch (propertyType?.toLowerCase()) {
25327
- case 'number':
25328
- formField.type ||= FormFieldType.Text;
25329
- formField.inputType ||= 'number';
25330
- break;
25331
- case 'date':
25332
- formField.type ||= FormFieldType.Date;
25333
- break;
25334
- case 'boolean':
25335
- formField.type ||= FormFieldType.Checkbox;
25336
- break;
25337
- default:
25338
- formField.type ||= FormFieldType.Text;
25339
- break;
25340
- }
25341
- }
25342
- /* Set wrapped to false, if the field cant be wrapped in the <mat-form-field> */
25343
- if (formField.type && unwarppedFormFields?.includes(formField.type)) {
25344
- formField.wrapped = false;
25345
- }
25346
- /* Add class multiline to the form field */
25347
- if (formField.multiline) {
25348
- formField.cssClass += ' multiline';
25349
- formField.cssClass = formField.cssClass?.trim();
25350
- }
25351
- /**
25352
- * If the 'numbersOnly' flag is set to true and no custom pattern is defined,
25353
- * set the pattern to allow only numbers after the optional prefix.
25354
- */
25355
- if (formField.numbersOnly && !formField.pattern) {
25356
- /* Get the prefix */
25357
- const prefix = formField.prefix ?? '';
25358
- /* Set pattern to allow only numbers after the prefix */
25359
- if (prefix) {
25360
- formField.pattern = new RegExp(`^${prefix}[0-9]*$`);
25361
- }
25362
- /* No prefix case */
25363
- else {
25364
- formField.pattern = /^[0-9]*$/;
25365
- }
25366
- }
25367
25415
  /* Get old form fields */
25368
25416
  let previousFormFields = Reflect.getMetadata(formFieldsMetadataKey, target);
25417
+ /* Override the field with the args, if exists */
25418
+ const previousFormField = previousFormFields?.find(x => x.name == propertyName);
25419
+ const formFieldArgs = previousFormField
25420
+ ? Object.assign({}, previousFormField, args, {
25421
+ label: args.label || Reflect.getMetadata(headerMetadataKey, target, propertyKey) || propertyKey
25422
+ })
25423
+ : args;
25424
+ /* Create a new form field definition */
25425
+ var formField = createFormFieldDefinition(target, propertyKey, formFieldArgs);
25369
25426
  /* Override the field, if exists */
25370
25427
  previousFormFields = previousFormFields?.filter(x => x.name != formField.name);
25371
25428
  /* Create a copy of the result */
@@ -25387,8 +25444,6 @@ function FormField(args) {
25387
25444
  */
25388
25445
  function FormFieldGroup(type, args, context) {
25389
25446
  return function (target, propertyKey) {
25390
- /* Create an instance of the group object */
25391
- var instance = Reflect.construct(type, []);
25392
25447
  /* Retrieve form groups from the type, passing args and context */
25393
25448
  var groups = getFormGroups(undefined, type, args, context);
25394
25449
  /* Get the header of the groups or create one using the property name */