@solcre-org/core-ui 2.15.31 → 2.15.32

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.
@@ -4984,9 +4984,11 @@ class MultiEntryFieldComponent {
4984
4984
  valueChange = output();
4985
4985
  onBlurEvent = output();
4986
4986
  onEnterEvent = output();
4987
+ hasErrors = output();
4987
4988
  ModalMode = ModalMode;
4988
4989
  entries = signal([]);
4989
4990
  fieldValues = signal([]);
4991
+ entryErrors = signal(new Map());
4990
4992
  isSyncingFromInput = signal(false);
4991
4993
  lastInputSignature = null;
4992
4994
  lastEmittedSignature = null;
@@ -5087,6 +5089,11 @@ class MultiEntryFieldComponent {
5087
5089
  if (matchesLastEmitted) {
5088
5090
  this.lastEmittedSignature = signature;
5089
5091
  }
5092
+ newEntries.forEach((entry, index) => {
5093
+ if (entry.value !== null && entry.value !== undefined && entry.value !== '') {
5094
+ this.validateEntry(entry.value, index);
5095
+ }
5096
+ });
5090
5097
  }
5091
5098
  finally {
5092
5099
  this.isSyncingFromInput.set(false);
@@ -5116,6 +5123,18 @@ class MultiEntryFieldComponent {
5116
5123
  const newValues = currentValues.filter((_, i) => i !== index);
5117
5124
  this.entries.set(newEntries);
5118
5125
  this.fieldValues.set(newValues);
5126
+ const currentErrors = new Map(this.entryErrors());
5127
+ const newErrors = new Map();
5128
+ currentErrors.forEach((errors, idx) => {
5129
+ if (idx < index) {
5130
+ newErrors.set(idx, errors);
5131
+ }
5132
+ else if (idx > index) {
5133
+ newErrors.set(idx - 1, errors);
5134
+ }
5135
+ });
5136
+ this.entryErrors.set(newErrors);
5137
+ this.hasErrors.emit(newErrors.size > 0);
5119
5138
  }
5120
5139
  }
5121
5140
  onFieldValueChange(value, index) {
@@ -5125,6 +5144,43 @@ class MultiEntryFieldComponent {
5125
5144
  const currentEntries = [...this.entries()];
5126
5145
  currentEntries[index].value = value;
5127
5146
  this.entries.set(currentEntries);
5147
+ this.validateEntry(value, index);
5148
+ }
5149
+ validateEntry(value, index) {
5150
+ const validators = this.getCurrentValidators();
5151
+ const errors = [];
5152
+ for (const validator of validators) {
5153
+ const control = { value };
5154
+ const validationResult = validator(control);
5155
+ if (validationResult) {
5156
+ const errorKeys = Object.keys(validationResult);
5157
+ const baseField = this.field();
5158
+ for (const errorKey of errorKeys) {
5159
+ const errorMessage = baseField.errorMessages?.[errorKey];
5160
+ if (errorMessage) {
5161
+ errors.push(errorMessage);
5162
+ }
5163
+ else {
5164
+ errors.push(`Validation error: ${errorKey}`);
5165
+ }
5166
+ }
5167
+ }
5168
+ }
5169
+ const currentErrors = new Map(this.entryErrors());
5170
+ if (errors.length > 0) {
5171
+ currentErrors.set(index, errors);
5172
+ }
5173
+ else {
5174
+ currentErrors.delete(index);
5175
+ }
5176
+ this.entryErrors.set(currentErrors);
5177
+ this.hasErrors.emit(currentErrors.size > 0);
5178
+ }
5179
+ getEntryErrors(index) {
5180
+ return this.entryErrors().get(index) || [];
5181
+ }
5182
+ hasAnyErrors() {
5183
+ return this.entryErrors().size > 0;
5128
5184
  }
5129
5185
  onFieldBlur(fieldKey) {
5130
5186
  this.onBlurEvent.emit(fieldKey);
@@ -5217,7 +5273,7 @@ class MultiEntryFieldComponent {
5217
5273
  }
5218
5274
  }
5219
5275
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: MultiEntryFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5220
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: MultiEntryFieldComponent, isStandalone: true, selector: "core-multi-entry-field", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: true, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, rowData: { classPropertyName: "rowData", publicName: "rowData", isSignal: true, isRequired: false, transformFunction: null }, formValue: { classPropertyName: "formValue", publicName: "formValue", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", onBlurEvent: "onBlurEvent", onEnterEvent: "onEnterEvent" }, hostDirectives: [{ directive: CoreHostDirective }], ngImport: i0, template: "<div class=\"c-entry-group\">\n @for (entry of entries(); track entry.id; let index = $index) {\n <div class=\"c-entry-item\">\n <!-- Campo din\u00E1mico para cada entrada -->\n <div\n coreDynamicField\n [field]=\"createFieldConfigForEntry(index)\"\n [value]=\"entry.value\"\n [mode]=\"mode()\"\n [errors]=\"errors()\"\n [rowData]=\"rowData()\"\n [formValue]=\"formValue()\"\n (valueChange)=\"onFieldValueChange($event, index)\"\n (onBlurEvent)=\"onFieldBlur($event)\"\n (onEnterEvent)=\"onFieldEnter($event)\">\n </div>\n\n <!-- Botones de acci\u00F3n (agregar/eliminar) -->\n @if (shouldShowActions(index)) {\n <div class=\"c-entry-actions\">\n @if (shouldShowAddButton(index)) {\n <button \n type=\"button\"\n class=\"c-entry-action c-entry-action--add\"\n (click)=\"addEntry()\"\n [disabled]=\"isDisabled()\"\n [title]=\"addLabel() | translate\"\n [attr.aria-label]=\"addLabel() | translate\">\n <span class=\"icon-counter-up\"></span>\n {{ addLabel() | translate }}\n </button>\n }\n \n @if (shouldShowRemoveButton(index)) {\n <button \n type=\"button\"\n class=\"c-entry-action c-entry-action--remove\"\n (click)=\"removeEntry(index)\"\n [disabled]=\"isDisabled()\"\n [title]=\"removeLabel() | translate\"\n [attr.aria-label]=\"removeLabel() | translate\">\n <span class=\"icon-counter-down\"></span>\n {{ removeLabel() | translate }}\n </button>\n }\n </div>\n }\n </div>\n }\n\n <!-- Errores del campo principal -->\n @if (errors().length > 0) {\n <core-field-errors [errors]=\"errors()\"></core-field-errors>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "directive", type: DynamicFieldDirective, selector: "[coreDynamicField]", inputs: ["field", "value", "mode", "errors", "rowData", "formValue"], outputs: ["valueChange", "onBlurEvent", "onEnterEvent", "selectionChange"] }, { kind: "component", type: FieldErrorsComponent, selector: "core-field-errors", inputs: ["errors"] }] });
5276
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: MultiEntryFieldComponent, isStandalone: true, selector: "core-multi-entry-field", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: true, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, rowData: { classPropertyName: "rowData", publicName: "rowData", isSignal: true, isRequired: false, transformFunction: null }, formValue: { classPropertyName: "formValue", publicName: "formValue", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", onBlurEvent: "onBlurEvent", onEnterEvent: "onEnterEvent", hasErrors: "hasErrors" }, hostDirectives: [{ directive: CoreHostDirective }], ngImport: i0, template: "<div class=\"c-entry-group\">\n @for (entry of entries(); track entry.id; let index = $index) {\n <div class=\"c-entry-item\">\n <!-- Campo din\u00E1mico para cada entrada -->\n <div\n coreDynamicField\n [field]=\"createFieldConfigForEntry(index)\"\n [value]=\"entry.value\"\n [mode]=\"mode()\"\n [errors]=\"getEntryErrors(index)\"\n [rowData]=\"rowData()\"\n [formValue]=\"formValue()\"\n (valueChange)=\"onFieldValueChange($event, index)\"\n (onBlurEvent)=\"onFieldBlur($event)\"\n (onEnterEvent)=\"onFieldEnter($event)\">\n </div>\n\n <!-- Botones de acci\u00F3n (agregar/eliminar) -->\n @if (shouldShowActions(index)) {\n <div class=\"c-entry-actions\">\n @if (shouldShowAddButton(index)) {\n <button \n type=\"button\"\n class=\"c-entry-action c-entry-action--add\"\n (click)=\"addEntry()\"\n [disabled]=\"isDisabled()\"\n [title]=\"addLabel() | translate\"\n [attr.aria-label]=\"addLabel() | translate\">\n <span class=\"icon-counter-up\"></span>\n {{ addLabel() | translate }}\n </button>\n }\n \n @if (shouldShowRemoveButton(index)) {\n <button \n type=\"button\"\n class=\"c-entry-action c-entry-action--remove\"\n (click)=\"removeEntry(index)\"\n [disabled]=\"isDisabled()\"\n [title]=\"removeLabel() | translate\"\n [attr.aria-label]=\"removeLabel() | translate\">\n <span class=\"icon-counter-down\"></span>\n {{ removeLabel() | translate }}\n </button>\n }\n </div>\n }\n </div>\n }\n\n <!-- Errores del campo principal (solo si hay errores globales) -->\n @if (errors().length > 0) {\n <core-field-errors [errors]=\"errors()\"></core-field-errors>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "directive", type: DynamicFieldDirective, selector: "[coreDynamicField]", inputs: ["field", "value", "mode", "errors", "rowData", "formValue"], outputs: ["valueChange", "onBlurEvent", "onEnterEvent", "selectionChange"] }, { kind: "component", type: FieldErrorsComponent, selector: "core-field-errors", inputs: ["errors"] }] });
5221
5277
  }
5222
5278
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: MultiEntryFieldComponent, decorators: [{
5223
5279
  type: Component,
@@ -5228,7 +5284,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
5228
5284
  TranslateModule,
5229
5285
  DynamicFieldDirective,
5230
5286
  FieldErrorsComponent
5231
- ], hostDirectives: [CoreHostDirective], template: "<div class=\"c-entry-group\">\n @for (entry of entries(); track entry.id; let index = $index) {\n <div class=\"c-entry-item\">\n <!-- Campo din\u00E1mico para cada entrada -->\n <div\n coreDynamicField\n [field]=\"createFieldConfigForEntry(index)\"\n [value]=\"entry.value\"\n [mode]=\"mode()\"\n [errors]=\"errors()\"\n [rowData]=\"rowData()\"\n [formValue]=\"formValue()\"\n (valueChange)=\"onFieldValueChange($event, index)\"\n (onBlurEvent)=\"onFieldBlur($event)\"\n (onEnterEvent)=\"onFieldEnter($event)\">\n </div>\n\n <!-- Botones de acci\u00F3n (agregar/eliminar) -->\n @if (shouldShowActions(index)) {\n <div class=\"c-entry-actions\">\n @if (shouldShowAddButton(index)) {\n <button \n type=\"button\"\n class=\"c-entry-action c-entry-action--add\"\n (click)=\"addEntry()\"\n [disabled]=\"isDisabled()\"\n [title]=\"addLabel() | translate\"\n [attr.aria-label]=\"addLabel() | translate\">\n <span class=\"icon-counter-up\"></span>\n {{ addLabel() | translate }}\n </button>\n }\n \n @if (shouldShowRemoveButton(index)) {\n <button \n type=\"button\"\n class=\"c-entry-action c-entry-action--remove\"\n (click)=\"removeEntry(index)\"\n [disabled]=\"isDisabled()\"\n [title]=\"removeLabel() | translate\"\n [attr.aria-label]=\"removeLabel() | translate\">\n <span class=\"icon-counter-down\"></span>\n {{ removeLabel() | translate }}\n </button>\n }\n </div>\n }\n </div>\n }\n\n <!-- Errores del campo principal -->\n @if (errors().length > 0) {\n <core-field-errors [errors]=\"errors()\"></core-field-errors>\n }\n</div>\n" }]
5287
+ ], hostDirectives: [CoreHostDirective], template: "<div class=\"c-entry-group\">\n @for (entry of entries(); track entry.id; let index = $index) {\n <div class=\"c-entry-item\">\n <!-- Campo din\u00E1mico para cada entrada -->\n <div\n coreDynamicField\n [field]=\"createFieldConfigForEntry(index)\"\n [value]=\"entry.value\"\n [mode]=\"mode()\"\n [errors]=\"getEntryErrors(index)\"\n [rowData]=\"rowData()\"\n [formValue]=\"formValue()\"\n (valueChange)=\"onFieldValueChange($event, index)\"\n (onBlurEvent)=\"onFieldBlur($event)\"\n (onEnterEvent)=\"onFieldEnter($event)\">\n </div>\n\n <!-- Botones de acci\u00F3n (agregar/eliminar) -->\n @if (shouldShowActions(index)) {\n <div class=\"c-entry-actions\">\n @if (shouldShowAddButton(index)) {\n <button \n type=\"button\"\n class=\"c-entry-action c-entry-action--add\"\n (click)=\"addEntry()\"\n [disabled]=\"isDisabled()\"\n [title]=\"addLabel() | translate\"\n [attr.aria-label]=\"addLabel() | translate\">\n <span class=\"icon-counter-up\"></span>\n {{ addLabel() | translate }}\n </button>\n }\n \n @if (shouldShowRemoveButton(index)) {\n <button \n type=\"button\"\n class=\"c-entry-action c-entry-action--remove\"\n (click)=\"removeEntry(index)\"\n [disabled]=\"isDisabled()\"\n [title]=\"removeLabel() | translate\"\n [attr.aria-label]=\"removeLabel() | translate\">\n <span class=\"icon-counter-down\"></span>\n {{ removeLabel() | translate }}\n </button>\n }\n </div>\n }\n </div>\n }\n\n <!-- Errores del campo principal (solo si hay errores globales) -->\n @if (errors().length > 0) {\n <core-field-errors [errors]=\"errors()\"></core-field-errors>\n }\n</div>\n" }]
5232
5288
  }], ctorParameters: () => [] });
5233
5289
 
5234
5290
  class SmartFieldComponent {
@@ -5276,7 +5332,7 @@ class SmartFieldComponent {
5276
5332
  (selectionChange)="selectionChange.emit($event)">
5277
5333
  </div>
5278
5334
  }
5279
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "directive", type: DynamicFieldDirective, selector: "[coreDynamicField]", inputs: ["field", "value", "mode", "errors", "rowData", "formValue"], outputs: ["valueChange", "onBlurEvent", "onEnterEvent", "selectionChange"] }, { kind: "component", type: MultiEntryFieldComponent, selector: "core-multi-entry-field", inputs: ["field", "value", "mode", "errors", "rowData", "formValue"], outputs: ["valueChange", "onBlurEvent", "onEnterEvent"] }] });
5335
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "directive", type: DynamicFieldDirective, selector: "[coreDynamicField]", inputs: ["field", "value", "mode", "errors", "rowData", "formValue"], outputs: ["valueChange", "onBlurEvent", "onEnterEvent", "selectionChange"] }, { kind: "component", type: MultiEntryFieldComponent, selector: "core-multi-entry-field", inputs: ["field", "value", "mode", "errors", "rowData", "formValue"], outputs: ["valueChange", "onBlurEvent", "onEnterEvent", "hasErrors"] }] });
5280
5336
  }
5281
5337
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SmartFieldComponent, decorators: [{
5282
5338
  type: Component,
@@ -16141,12 +16197,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
16141
16197
  // Este archivo es generado automáticamente por scripts/update-version.js
16142
16198
  // No edites manualmente este archivo
16143
16199
  const VERSION = {
16144
- full: '2.15.31',
16200
+ full: '2.15.32',
16145
16201
  major: 2,
16146
16202
  minor: 15,
16147
- patch: 31,
16148
- timestamp: '2025-11-07T14:57:10.870Z',
16149
- buildDate: '7/11/2025'
16203
+ patch: 32,
16204
+ timestamp: '2025-11-10T15:59:54.714Z',
16205
+ buildDate: '10/11/2025'
16150
16206
  };
16151
16207
 
16152
16208
  class MainNavComponent {