ngx-dsxlibrary 2.21.69 → 2.21.70

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.
@@ -32,9 +32,6 @@ import { Button, ButtonModule } from 'primeng/button';
32
32
  import moment from 'moment-timezone';
33
33
  import { ToastrService } from 'ngx-toastr';
34
34
  import Swal from 'sweetalert2';
35
- import { AutoComplete, AutoCompleteModule } from 'primeng/autocomplete';
36
- import * as i6 from 'primeng/floatlabel';
37
- import { FloatLabel, FloatLabelModule } from 'primeng/floatlabel';
38
35
  import { FileUpload, FileUploadModule } from 'primeng/fileupload';
39
36
  import { LottieComponent } from 'ngx-lottie';
40
37
  import { createTimeline } from 'animejs';
@@ -44,9 +41,12 @@ import * as i4 from 'primeng/menubar';
44
41
  import { MenubarModule } from 'primeng/menubar';
45
42
  import { JwtHelperService } from '@auth0/angular-jwt';
46
43
  import { CookieService } from 'ngx-cookie-service';
44
+ import * as i6 from 'primeng/floatlabel';
45
+ import { FloatLabelModule, FloatLabel } from 'primeng/floatlabel';
47
46
  import * as i7 from 'primeng/password';
48
47
  import { PasswordModule } from 'primeng/password';
49
48
  import { AccordionModule } from 'primeng/accordion';
49
+ import { AutoCompleteModule, AutoComplete } from 'primeng/autocomplete';
50
50
  import { AutoFocusModule } from 'primeng/autofocus';
51
51
  import { AvatarGroupModule } from 'primeng/avatargroup';
52
52
  import { BadgeModule } from 'primeng/badge';
@@ -4900,162 +4900,6 @@ const ACTION_CONFIG = {
4900
4900
  },
4901
4901
  };
4902
4902
 
4903
- class DsxAutocomplete {
4904
- // Inputs usando Señales
4905
- datasource = input.required(...(ngDevMode ? [{ debugName: "datasource" }] : /* istanbul ignore next */ []));
4906
- optionLabel = input.required(...(ngDevMode ? [{ debugName: "optionLabel" }] : /* istanbul ignore next */ []));
4907
- label = input('Seleccionar', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
4908
- delay = input(100, ...(ngDevMode ? [{ debugName: "delay" }] : /* istanbul ignore next */ []));
4909
- idKey = input.required(...(ngDevMode ? [{ debugName: "idKey" }] : /* istanbul ignore next */ []));
4910
- dataKey = input('', ...(ngDevMode ? [{ debugName: "dataKey" }] : /* istanbul ignore next */ []));
4911
- permitirCrear = input(false, ...(ngDevMode ? [{ debugName: "permitirCrear" }] : /* istanbul ignore next */ []));
4912
- debug = input(false, ...(ngDevMode ? [{ debugName: "debug" }] : /* istanbul ignore next */ []));
4913
- factoryNuevoRegistro = input(...(ngDevMode ? [undefined, { debugName: "factoryNuevoRegistro" }] : /* istanbul ignore next */ []));
4914
- // Estado Interno
4915
- dataFiltrada = signal([], ...(ngDevMode ? [{ debugName: "dataFiltrada" }] : /* istanbul ignore next */ []));
4916
- value = [];
4917
- onChange = () => { };
4918
- onTouched = () => { };
4919
- disabled = false;
4920
- lastLogTime = 0;
4921
- timeoutLimpieza = null;
4922
- logDebug(message, data) {
4923
- if (!this.debug())
4924
- return;
4925
- const now = Date.now();
4926
- if (now - this.lastLogTime < 50)
4927
- return;
4928
- this.lastLogTime = now;
4929
- console.log(`[DsxAutocomplete] ${message}`, data || '');
4930
- }
4931
- searchRequisitos(event) {
4932
- const inicio = performance.now();
4933
- const label = this.optionLabel();
4934
- // FLUJO A: Dropdown (sin texto)
4935
- if (!event.query || event.query.trim() === '') {
4936
- const todoElUniverso = this.datasource();
4937
- this.dataFiltrada.set(todoElUniverso);
4938
- this.logDebug('Modo dropdown activo', {
4939
- registros: todoElUniverso.length,
4940
- });
4941
- return;
4942
- }
4943
- // FLUJO B: Búsqueda
4944
- const palabrasBuscadas = event.query
4945
- .toLowerCase()
4946
- .trim()
4947
- .split(/\s+/)
4948
- .filter((palabra) => palabra.length > 0);
4949
- const filtrados = this.datasource()
4950
- .filter((item) => {
4951
- const textoRegistro = String(item[label] || '').toLowerCase();
4952
- return palabrasBuscadas.every((palabra) => textoRegistro.includes(palabra));
4953
- })
4954
- .slice(0, 10);
4955
- this.dataFiltrada.set(filtrados);
4956
- this.logDebug(`Búsqueda "${event.query}" (${(performance.now() - inicio).toFixed(2)}ms)`, { encontrados: filtrados.length });
4957
- }
4958
- evaluarYAgregar(event) {
4959
- const valorInput = event.target.value?.trim();
4960
- if (!valorInput) {
4961
- this.dataFiltrada.set([]);
4962
- return;
4963
- }
4964
- const sugerencias = this.dataFiltrada();
4965
- const actuales = this.value || [];
4966
- const campoId = this.idKey();
4967
- if (sugerencias.length > 0) {
4968
- const primeraMatch = sugerencias[0];
4969
- const yaExiste = actuales.some((item) => item[campoId] === primeraMatch[campoId]);
4970
- if (!yaExiste) {
4971
- this.actualizarFormulario([...actuales, primeraMatch]);
4972
- this.logDebug('✅ Elemento agregado');
4973
- }
4974
- }
4975
- else if (this.permitirCrear()) {
4976
- let nuevo;
4977
- if (this.factoryNuevoRegistro()) {
4978
- nuevo = this.factoryNuevoRegistro()(valorInput);
4979
- }
4980
- else {
4981
- nuevo = {
4982
- [campoId]: 0,
4983
- [this.optionLabel()]: valorInput.toUpperCase(),
4984
- activo: true,
4985
- };
4986
- }
4987
- this.actualizarFormulario([...actuales, nuevo]);
4988
- this.logDebug('🆕 Nuevo elemento creado', valorInput);
4989
- }
4990
- event.target.value = '';
4991
- this.dataFiltrada.set([]);
4992
- }
4993
- onHide() {
4994
- this.logDebug('Dropdown ocultado - Limpiando estado');
4995
- // Limpiar timeout anterior si existe
4996
- if (this.timeoutLimpieza) {
4997
- clearTimeout(this.timeoutLimpieza);
4998
- this.timeoutLimpieza = null;
4999
- }
5000
- // Limpiar después de un pequeño delay
5001
- this.timeoutLimpieza = setTimeout(() => {
5002
- this.dataFiltrada.set([]);
5003
- this.timeoutLimpieza = null;
5004
- }, 100);
5005
- }
5006
- onShow() {
5007
- this.logDebug('Dropdown mostrado');
5008
- // Limpiar timeout pendiente
5009
- if (this.timeoutLimpieza) {
5010
- clearTimeout(this.timeoutLimpieza);
5011
- this.timeoutLimpieza = null;
5012
- }
5013
- }
5014
- actualizarFormulario(nuevaLista) {
5015
- this.value = nuevaLista;
5016
- this.onChange(this.value);
5017
- this.logDebug('Formulario actualizado', {
5018
- total: nuevaLista.length,
5019
- });
5020
- }
5021
- // --- ControlValueAccessor ---
5022
- writeValue(value) {
5023
- this.value = value || [];
5024
- this.dataFiltrada.set([]);
5025
- if (this.timeoutLimpieza) {
5026
- clearTimeout(this.timeoutLimpieza);
5027
- this.timeoutLimpieza = null;
5028
- }
5029
- }
5030
- registerOnChange(fn) {
5031
- this.onChange = fn;
5032
- }
5033
- registerOnTouched(fn) {
5034
- this.onTouched = fn;
5035
- }
5036
- setDisabledState(isDisabled) {
5037
- this.disabled = isDisabled;
5038
- }
5039
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxAutocomplete, deps: [], target: i0.ɵɵFactoryTarget.Component });
5040
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.17", type: DsxAutocomplete, isStandalone: true, selector: "dsx-autocomplete", inputs: { datasource: { classPropertyName: "datasource", publicName: "datasource", isSignal: true, isRequired: true, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, delay: { classPropertyName: "delay", publicName: "delay", isSignal: true, isRequired: false, transformFunction: null }, idKey: { classPropertyName: "idKey", publicName: "idKey", isSignal: true, isRequired: true, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: true, isRequired: false, transformFunction: null }, permitirCrear: { classPropertyName: "permitirCrear", publicName: "permitirCrear", isSignal: true, isRequired: false, transformFunction: null }, debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null }, factoryNuevoRegistro: { classPropertyName: "factoryNuevoRegistro", publicName: "factoryNuevoRegistro", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
5041
- {
5042
- provide: NG_VALUE_ACCESSOR,
5043
- useExisting: forwardRef(() => DsxAutocomplete),
5044
- multi: true,
5045
- },
5046
- ], ngImport: i0, template: "<p-floatlabel variant=\"on\">\r\n <p-autoComplete\r\n fluid\r\n multiple\r\n [dropdown]=\"true\"\r\n [suggestions]=\"dataFiltrada()\"\r\n (completeMethod)=\"searchRequisitos($event)\"\r\n [(ngModel)]=\"value\"\r\n (ngModelChange)=\"onChange(value)\"\r\n (onBlur)=\"onTouched()\"\r\n (onShow)=\"onShow()\"\r\n (onHide)=\"onHide()\"\r\n [disabled]=\"disabled\"\r\n [optionLabel]=\"optionLabel()\"\r\n [dataKey]=\"dataKey() || idKey()\"\r\n (keyup.enter)=\"evaluarYAgregar($event)\"\r\n [delay]=\"delay()\"\r\n placeholder=\"Ingresa un texto....\"\r\n >\r\n </p-autoComplete>\r\n <label>{{ label() }}</label>\r\n</p-floatlabel>\r\n", styles: [""], dependencies: [{ kind: "component", type: AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "minQueryLength", "delay", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "addOnTab", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "addOnBlur", "separator", "appendTo", "motionOptions"], outputs: ["completeMethod", "onSelect", "onUnselect", "onAdd", "onFocus", "onBlur", "onDropdownClick", "onClear", "onInputKeydown", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }] });
5047
- }
5048
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxAutocomplete, decorators: [{
5049
- type: Component,
5050
- args: [{ selector: 'dsx-autocomplete', imports: [AutoComplete, FormsModule, FloatLabel], providers: [
5051
- {
5052
- provide: NG_VALUE_ACCESSOR,
5053
- useExisting: forwardRef(() => DsxAutocomplete),
5054
- multi: true,
5055
- },
5056
- ], template: "<p-floatlabel variant=\"on\">\r\n <p-autoComplete\r\n fluid\r\n multiple\r\n [dropdown]=\"true\"\r\n [suggestions]=\"dataFiltrada()\"\r\n (completeMethod)=\"searchRequisitos($event)\"\r\n [(ngModel)]=\"value\"\r\n (ngModelChange)=\"onChange(value)\"\r\n (onBlur)=\"onTouched()\"\r\n (onShow)=\"onShow()\"\r\n (onHide)=\"onHide()\"\r\n [disabled]=\"disabled\"\r\n [optionLabel]=\"optionLabel()\"\r\n [dataKey]=\"dataKey() || idKey()\"\r\n (keyup.enter)=\"evaluarYAgregar($event)\"\r\n [delay]=\"delay()\"\r\n placeholder=\"Ingresa un texto....\"\r\n >\r\n </p-autoComplete>\r\n <label>{{ label() }}</label>\r\n</p-floatlabel>\r\n" }]
5057
- }], propDecorators: { datasource: [{ type: i0.Input, args: [{ isSignal: true, alias: "datasource", required: true }] }], optionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionLabel", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], delay: [{ type: i0.Input, args: [{ isSignal: true, alias: "delay", required: false }] }], idKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "idKey", required: true }] }], dataKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataKey", required: false }] }], permitirCrear: [{ type: i0.Input, args: [{ isSignal: true, alias: "permitirCrear", required: false }] }], debug: [{ type: i0.Input, args: [{ isSignal: true, alias: "debug", required: false }] }], factoryNuevoRegistro: [{ type: i0.Input, args: [{ isSignal: true, alias: "factoryNuevoRegistro", required: false }] }] } });
5058
-
5059
4903
  class FileComponent {
5060
4904
  // Inputs
5061
4905
  existingFile = input(null, ...(ngDevMode ? [{ debugName: "existingFile" }] : /* istanbul ignore next */ []));
@@ -8597,7 +8441,7 @@ class DsxdateShort {
8597
8441
  useExisting: forwardRef(() => DsxdateShort),
8598
8442
  multi: true,
8599
8443
  },
8600
- ], ngImport: i0, template: "<!-- dsxdate-short.html -->\r\n<p-floatLabel variant=\"on\">\r\n <p-datepicker\r\n [formControl]=\"fechaControl\"\r\n [fluid]=\"true\"\r\n [showIcon]=\"showIcon()\"\r\n [showOnFocus]=\"showOnFocus()\"\r\n [showButtonBar]=\"showButtonBar()\"\r\n [dateFormat]=\"dateFormat()\"\r\n [placeholder]=\"placeholder()\"\r\n pInputMask=\"99/99/9999\"\r\n />\r\n <label>{{ label() }}</label>\r\n</p-floatLabel>\r\n\r\n<!-- \u2705 SIN CONDICI\u00D3N - IGUAL QUE EL ORIGINAL -->\r\n<dsx-message-error [control]=\"fechaControl\" />\r\n\r\n<!-- Debug info -->\r\n@if (debugEnabled() && isDevMode) {\r\n<div\r\n class=\"debug-info\"\r\n style=\"\r\n font-size: 12px;\r\n color: #666;\r\n margin-top: 4px;\r\n border-top: 1px dashed #ccc;\r\n padding-top: 4px;\r\n \"\r\n>\r\n <small>\r\n <strong>Debug:</strong>\r\n Value: {{ fechaControl.value | json }} | Valid: {{ fechaControl.valid }} |\r\n Invalid: {{ fechaControl.invalid }} | Errors: {{ fechaControl.errors | json\r\n }} | Dirty: {{ fechaControl.dirty }} | Touched: {{ fechaControl.touched }} |\r\n Status: {{ fechaControl.status }}\r\n </small>\r\n</div>\r\n}\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "component", type: DatePicker, selector: "p-datePicker, p-datepicker, p-date-picker", inputs: ["iconDisplay", "styleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "readonlyInput", "shortYearCutoff", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "minDate", "maxDate", "disabledDates", "disabledDays", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "view", "defaultDate", "appendTo", "motionOptions"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: AppMessageErrorComponent, selector: "dsx-message-error", inputs: ["control", "form", "debugMode"] }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }] });
8444
+ ], ngImport: i0, template: "<!-- dsxdate-short.html -->\r\n<p-floatLabel variant=\"on\">\r\n <p-datepicker\r\n appendTo=\"body\"\r\n [formControl]=\"fechaControl\"\r\n [fluid]=\"true\"\r\n [showIcon]=\"showIcon()\"\r\n [showOnFocus]=\"showOnFocus()\"\r\n [showButtonBar]=\"showButtonBar()\"\r\n [dateFormat]=\"dateFormat()\"\r\n [placeholder]=\"placeholder()\"\r\n pInputMask=\"99/99/9999\"\r\n />\r\n <label>{{ label() }}</label>\r\n</p-floatLabel>\r\n\r\n<!-- \u2705 SIN CONDICI\u00D3N - IGUAL QUE EL ORIGINAL -->\r\n<dsx-message-error [control]=\"fechaControl\" />\r\n\r\n<!-- Debug info -->\r\n@if (debugEnabled() && isDevMode) {\r\n<div\r\n class=\"debug-info\"\r\n style=\"\r\n font-size: 12px;\r\n color: #666;\r\n margin-top: 4px;\r\n border-top: 1px dashed #ccc;\r\n padding-top: 4px;\r\n \"\r\n>\r\n <small>\r\n <strong>Debug:</strong>\r\n Value: {{ fechaControl.value | json }} | Valid: {{ fechaControl.valid }} |\r\n Invalid: {{ fechaControl.invalid }} | Errors: {{ fechaControl.errors | json\r\n }} | Dirty: {{ fechaControl.dirty }} | Touched: {{ fechaControl.touched }} |\r\n Status: {{ fechaControl.status }}\r\n </small>\r\n</div>\r\n}\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "component", type: DatePicker, selector: "p-datePicker, p-datepicker, p-date-picker", inputs: ["iconDisplay", "styleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "readonlyInput", "shortYearCutoff", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "minDate", "maxDate", "disabledDates", "disabledDays", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "view", "defaultDate", "appendTo", "motionOptions"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: AppMessageErrorComponent, selector: "dsx-message-error", inputs: ["control", "form", "debugMode"] }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }] });
8601
8445
  }
8602
8446
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxdateShort, decorators: [{
8603
8447
  type: Component,
@@ -8614,7 +8458,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
8614
8458
  useExisting: forwardRef(() => DsxdateShort),
8615
8459
  multi: true,
8616
8460
  },
8617
- ], template: "<!-- dsxdate-short.html -->\r\n<p-floatLabel variant=\"on\">\r\n <p-datepicker\r\n [formControl]=\"fechaControl\"\r\n [fluid]=\"true\"\r\n [showIcon]=\"showIcon()\"\r\n [showOnFocus]=\"showOnFocus()\"\r\n [showButtonBar]=\"showButtonBar()\"\r\n [dateFormat]=\"dateFormat()\"\r\n [placeholder]=\"placeholder()\"\r\n pInputMask=\"99/99/9999\"\r\n />\r\n <label>{{ label() }}</label>\r\n</p-floatLabel>\r\n\r\n<!-- \u2705 SIN CONDICI\u00D3N - IGUAL QUE EL ORIGINAL -->\r\n<dsx-message-error [control]=\"fechaControl\" />\r\n\r\n<!-- Debug info -->\r\n@if (debugEnabled() && isDevMode) {\r\n<div\r\n class=\"debug-info\"\r\n style=\"\r\n font-size: 12px;\r\n color: #666;\r\n margin-top: 4px;\r\n border-top: 1px dashed #ccc;\r\n padding-top: 4px;\r\n \"\r\n>\r\n <small>\r\n <strong>Debug:</strong>\r\n Value: {{ fechaControl.value | json }} | Valid: {{ fechaControl.valid }} |\r\n Invalid: {{ fechaControl.invalid }} | Errors: {{ fechaControl.errors | json\r\n }} | Dirty: {{ fechaControl.dirty }} | Touched: {{ fechaControl.touched }} |\r\n Status: {{ fechaControl.status }}\r\n </small>\r\n</div>\r\n}\r\n" }]
8461
+ ], template: "<!-- dsxdate-short.html -->\r\n<p-floatLabel variant=\"on\">\r\n <p-datepicker\r\n appendTo=\"body\"\r\n [formControl]=\"fechaControl\"\r\n [fluid]=\"true\"\r\n [showIcon]=\"showIcon()\"\r\n [showOnFocus]=\"showOnFocus()\"\r\n [showButtonBar]=\"showButtonBar()\"\r\n [dateFormat]=\"dateFormat()\"\r\n [placeholder]=\"placeholder()\"\r\n pInputMask=\"99/99/9999\"\r\n />\r\n <label>{{ label() }}</label>\r\n</p-floatLabel>\r\n\r\n<!-- \u2705 SIN CONDICI\u00D3N - IGUAL QUE EL ORIGINAL -->\r\n<dsx-message-error [control]=\"fechaControl\" />\r\n\r\n<!-- Debug info -->\r\n@if (debugEnabled() && isDevMode) {\r\n<div\r\n class=\"debug-info\"\r\n style=\"\r\n font-size: 12px;\r\n color: #666;\r\n margin-top: 4px;\r\n border-top: 1px dashed #ccc;\r\n padding-top: 4px;\r\n \"\r\n>\r\n <small>\r\n <strong>Debug:</strong>\r\n Value: {{ fechaControl.value | json }} | Valid: {{ fechaControl.valid }} |\r\n Invalid: {{ fechaControl.invalid }} | Errors: {{ fechaControl.errors | json\r\n }} | Dirty: {{ fechaControl.dirty }} | Touched: {{ fechaControl.touched }} |\r\n Status: {{ fechaControl.status }}\r\n </small>\r\n</div>\r\n}\r\n" }]
8618
8462
  }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], dateFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateFormat", required: false }] }], showIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcon", required: false }] }], showOnFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "showOnFocus", required: false }] }], showButtonBar: [{ type: i0.Input, args: [{ isSignal: true, alias: "showButtonBar", required: false }] }], debug: [{ type: i0.Input, args: [{ isSignal: true, alias: "debug", required: false }] }] } });
8619
8463
 
8620
8464
  // dsx-input-currency.ts
@@ -8852,6 +8696,543 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
8852
8696
  args: [InputNumber]
8853
8697
  }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], currency: [{ type: i0.Input, args: [{ isSignal: true, alias: "currency", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], minFractionDigits: [{ type: i0.Input, args: [{ isSignal: true, alias: "minFractionDigits", required: false }] }], maxFractionDigits: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFractionDigits", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], selectAllOnFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAllOnFocus", required: false }] }], debug: [{ type: i0.Input, args: [{ isSignal: true, alias: "debug", required: false }] }], showError: [{ type: i0.Input, args: [{ isSignal: true, alias: "showError", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], focus: [{ type: i0.Output, args: ["focus"] }], blur: [{ type: i0.Output, args: ["blur"] }] } });
8854
8698
 
8699
+ class DsxAutocomplete {
8700
+ injector = inject(Injector);
8701
+ cdr = inject(ChangeDetectorRef);
8702
+ ngControl = null;
8703
+ isDevModeInternal = isDevMode();
8704
+ controlSignal = signal(null, ...(ngDevMode ? [{ debugName: "controlSignal" }] : /* istanbul ignore next */ []));
8705
+ datasource = input.required(...(ngDevMode ? [{ debugName: "datasource" }] : /* istanbul ignore next */ []));
8706
+ optionLabel = input.required(...(ngDevMode ? [{ debugName: "optionLabel" }] : /* istanbul ignore next */ []));
8707
+ label = input('Seleccionar', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
8708
+ delay = input(100, ...(ngDevMode ? [{ debugName: "delay" }] : /* istanbul ignore next */ []));
8709
+ idKey = input.required(...(ngDevMode ? [{ debugName: "idKey" }] : /* istanbul ignore next */ []));
8710
+ dataKey = input('', ...(ngDevMode ? [{ debugName: "dataKey" }] : /* istanbul ignore next */ []));
8711
+ permitirCrear = input(false, ...(ngDevMode ? [{ debugName: "permitirCrear" }] : /* istanbul ignore next */ []));
8712
+ isMultiple = input(true, ...(ngDevMode ? [{ debugName: "isMultiple" }] : /* istanbul ignore next */ []));
8713
+ debug = input(false, ...(ngDevMode ? [{ debugName: "debug" }] : /* istanbul ignore next */ []));
8714
+ factoryNuevoRegistro = input(...(ngDevMode ? [undefined, { debugName: "factoryNuevoRegistro" }] : /* istanbul ignore next */ []));
8715
+ returnID = input(false, ...(ngDevMode ? [{ debugName: "returnID" }] : /* istanbul ignore next */ []));
8716
+ showError = input(true, ...(ngDevMode ? [{ debugName: "showError" }] : /* istanbul ignore next */ []));
8717
+ errorControl = computed(() => {
8718
+ const control = this.controlSignal();
8719
+ if (!this.showError())
8720
+ return null;
8721
+ return control?.control ?? null;
8722
+ }, ...(ngDevMode ? [{ debugName: "errorControl" }] : /* istanbul ignore next */ []));
8723
+ get isDevMode() {
8724
+ return this.isDevModeInternal;
8725
+ }
8726
+ get formValue() {
8727
+ return this.ngControl?.control?.value;
8728
+ }
8729
+ get controlName() {
8730
+ return this.ngControl?.name || null;
8731
+ }
8732
+ get controlValid() {
8733
+ return this.ngControl?.control?.valid ?? true;
8734
+ }
8735
+ get controlTouched() {
8736
+ return this.ngControl?.control?.touched ?? false;
8737
+ }
8738
+ get controlDirty() {
8739
+ return this.ngControl?.control?.dirty ?? false;
8740
+ }
8741
+ get controlErrors() {
8742
+ return this.ngControl?.control?.errors ?? null;
8743
+ }
8744
+ get controlValue() {
8745
+ return this.ngControl?.control?.value;
8746
+ }
8747
+ get controlStatus() {
8748
+ if (!this.ngControl?.control)
8749
+ return 'sin control';
8750
+ const control = this.ngControl.control;
8751
+ return `valid: ${control.valid}, touched: ${control.touched}, dirty: ${control.dirty}, errors: ${JSON.stringify(control.errors)}`;
8752
+ }
8753
+ dataFiltrada = signal([], ...(ngDevMode ? [{ debugName: "dataFiltrada" }] : /* istanbul ignore next */ []));
8754
+ value = this.isMultiple() ? [] : null;
8755
+ onChange = () => { };
8756
+ onTouched = () => { };
8757
+ disabled = false;
8758
+ lastLogTime = 0;
8759
+ timeoutLimpieza = null;
8760
+ initialValueSet = false;
8761
+ constructor() {
8762
+ effect(() => {
8763
+ this.ngControl = this.injector.get(NgControl, null);
8764
+ this.controlSignal.set(this.ngControl);
8765
+ if (this.shouldDebug() && this.ngControl) {
8766
+ this.logDebug('Inferred from formControlName:', {
8767
+ controlName: this.getFormControlName(),
8768
+ optionLabel: this.optionLabel(),
8769
+ label: this.label(),
8770
+ showError: this.showError(),
8771
+ returnID: this.returnID(),
8772
+ isMultiple: this.isMultiple(),
8773
+ });
8774
+ }
8775
+ });
8776
+ effect(() => {
8777
+ const ds = this.datasource();
8778
+ if (ds.length > 0 && this.initialValueSet) {
8779
+ this.logDebug('📚 Datasource actualizado:', ds.length);
8780
+ if (this.ngControl?.control?.value) {
8781
+ this.logDebug('🔄 Recargando valor con nuevo datasource');
8782
+ this.writeValue(this.ngControl.control.value);
8783
+ }
8784
+ }
8785
+ });
8786
+ effect(() => {
8787
+ const control = this.ngControl?.control;
8788
+ if (control && this.shouldDebug()) {
8789
+ const subscription = control.statusChanges?.subscribe(() => {
8790
+ this.logDebug('📊 Estado del control cambiado:', {
8791
+ controlName: this.getFormControlName(),
8792
+ valid: control.valid,
8793
+ touched: control.touched,
8794
+ dirty: control.dirty,
8795
+ errors: control.errors,
8796
+ value: control.value,
8797
+ });
8798
+ });
8799
+ return () => {
8800
+ if (subscription) {
8801
+ subscription.unsubscribe();
8802
+ }
8803
+ };
8804
+ }
8805
+ return () => { };
8806
+ });
8807
+ }
8808
+ ngOnInit() {
8809
+ this.logDebug('🚀 Componente inicializado');
8810
+ this.value = this.isMultiple() ? [] : null;
8811
+ }
8812
+ ngAfterViewInit() {
8813
+ this.cdr.detectChanges();
8814
+ }
8815
+ shouldDebug() {
8816
+ return this.isDevModeInternal && this.debug();
8817
+ }
8818
+ logDebug(message, data) {
8819
+ if (!this.shouldDebug())
8820
+ return;
8821
+ const now = Date.now();
8822
+ if (now - this.lastLogTime < 50)
8823
+ return;
8824
+ this.lastLogTime = now;
8825
+ console.log(`[DsxAutocomplete] ${message}`, data || '');
8826
+ }
8827
+ searchRequisitos(event) {
8828
+ const inicio = performance.now();
8829
+ const label = this.optionLabel();
8830
+ if (!event.query || event.query.trim() === '') {
8831
+ const todoElUniverso = this.datasource();
8832
+ this.dataFiltrada.set(todoElUniverso);
8833
+ this.logDebug('Modo dropdown activo', {
8834
+ registros: todoElUniverso.length,
8835
+ });
8836
+ return;
8837
+ }
8838
+ const queryNormalizado = this.normalizarTexto(event.query.trim());
8839
+ if (!queryNormalizado) {
8840
+ this.dataFiltrada.set(this.datasource());
8841
+ return;
8842
+ }
8843
+ const palabrasBuscadas = queryNormalizado
8844
+ .toLowerCase()
8845
+ .split(/\s+/)
8846
+ .filter((palabra) => palabra.length > 0);
8847
+ const filtrados = this.datasource()
8848
+ .filter((item) => {
8849
+ const textoRegistro = this.normalizarTexto(String(item[label] || '')).toLowerCase();
8850
+ return palabrasBuscadas.every((palabra) => textoRegistro.includes(palabra));
8851
+ })
8852
+ .slice(0, 10);
8853
+ this.dataFiltrada.set(filtrados);
8854
+ this.logDebug(`Búsqueda "${event.query}" (${(performance.now() - inicio).toFixed(2)}ms)`, { encontrados: filtrados.length });
8855
+ }
8856
+ normalizarTexto(texto) {
8857
+ if (!texto)
8858
+ return '';
8859
+ return texto
8860
+ .normalize('NFD')
8861
+ .replace(/[\u0300-\u036f]/g, '')
8862
+ .replace(/\s+/g, ' ')
8863
+ .trim();
8864
+ }
8865
+ // ✨ CORREGIDO: evaluarYAgregar para manejar valores no encontrados
8866
+ evaluarYAgregar(event) {
8867
+ const valorInput = event.target.value?.trim();
8868
+ if (!valorInput) {
8869
+ this.dataFiltrada.set([]);
8870
+ // Si el input está vacío y hay valor seleccionado, mantenerlo
8871
+ // Si no hay valor, asegurar que el formulario tenga null o []
8872
+ if (this.obtenerArrayValue().length === 0) {
8873
+ this.actualizarFormulario([]);
8874
+ }
8875
+ return;
8876
+ }
8877
+ const sugerencias = this.dataFiltrada();
8878
+ const actuales = this.obtenerArrayValue();
8879
+ const campoId = this.idKey();
8880
+ if (sugerencias.length > 0) {
8881
+ const valorNormalizado = this.normalizarTexto(valorInput).toLowerCase();
8882
+ const primeraMatch = sugerencias.find((item) => {
8883
+ const itemLabel = this.normalizarTexto(String(item[this.optionLabel()] || '')).toLowerCase();
8884
+ return itemLabel === valorNormalizado;
8885
+ }) || sugerencias[0];
8886
+ if (!this.isMultiple()) {
8887
+ this.actualizarFormulario([primeraMatch]);
8888
+ this.logDebug('✅ Elemento reemplazado (modo single)', primeraMatch[this.optionLabel()]);
8889
+ event.target.value = '';
8890
+ this.dataFiltrada.set([]);
8891
+ return;
8892
+ }
8893
+ const yaExiste = actuales.some((item) => item[campoId] === primeraMatch[campoId]);
8894
+ if (!yaExiste) {
8895
+ this.actualizarFormulario([...actuales, primeraMatch]);
8896
+ this.logDebug('✅ Elemento agregado');
8897
+ }
8898
+ else {
8899
+ this.logDebug('⚠️ Elemento ya existe en la selección');
8900
+ event.target.value = '';
8901
+ this.dataFiltrada.set([]);
8902
+ return;
8903
+ }
8904
+ }
8905
+ else if (this.permitirCrear()) {
8906
+ const valorNormalizado = this.normalizarTexto(valorInput).toLowerCase();
8907
+ const yaExisteEnActuales = actuales.some((item) => {
8908
+ const itemLabel = this.normalizarTexto(String(item[this.optionLabel()] || '')).toLowerCase();
8909
+ return itemLabel === valorNormalizado;
8910
+ });
8911
+ if (yaExisteEnActuales) {
8912
+ this.logDebug('⚠️ Elemento ya existe en la selección');
8913
+ event.target.value = '';
8914
+ this.dataFiltrada.set([]);
8915
+ return;
8916
+ }
8917
+ let nuevo;
8918
+ if (this.factoryNuevoRegistro()) {
8919
+ nuevo = this.factoryNuevoRegistro()(valorInput);
8920
+ }
8921
+ else {
8922
+ nuevo = {
8923
+ [campoId]: 0,
8924
+ [this.optionLabel()]: valorInput.toUpperCase(),
8925
+ activo: true,
8926
+ };
8927
+ }
8928
+ this.actualizarFormulario(this.isMultiple() ? [...actuales, nuevo] : [nuevo]);
8929
+ this.logDebug('🆕 Nuevo elemento creado', valorInput);
8930
+ }
8931
+ else {
8932
+ // ✅ NO permite crear: limpiar el valor a null o []
8933
+ this.logDebug('⚠️ No se encontraron coincidencias y no se permite crear', valorInput);
8934
+ // ✨ IMPORTANTE: Limpiar la selección a null o []
8935
+ this.actualizarFormulario([]);
8936
+ // Marcar como touched para mostrar validación
8937
+ if (this.ngControl?.control) {
8938
+ this.ngControl.control.markAsTouched();
8939
+ this.onTouched();
8940
+ }
8941
+ }
8942
+ event.target.value = '';
8943
+ this.dataFiltrada.set([]);
8944
+ }
8945
+ clearSelection() {
8946
+ this.actualizarFormulario([]);
8947
+ this.logDebug('🧹 Selección limpiada');
8948
+ }
8949
+ onNgModelChange(selectedItems) {
8950
+ let items = [];
8951
+ if (selectedItems === null || selectedItems === undefined) {
8952
+ items = [];
8953
+ }
8954
+ else if (Array.isArray(selectedItems)) {
8955
+ items = selectedItems;
8956
+ }
8957
+ else {
8958
+ items = [selectedItems];
8959
+ }
8960
+ this.logDebug('📝 onNgModelChange:', {
8961
+ items: items.length,
8962
+ isMultiple: this.isMultiple(),
8963
+ isArray: Array.isArray(selectedItems),
8964
+ isNull: selectedItems === null,
8965
+ returnID: this.returnID(),
8966
+ });
8967
+ if (this.isMultiple()) {
8968
+ this.value = items;
8969
+ }
8970
+ else {
8971
+ this.value = items.length > 0 ? items[0] : null;
8972
+ }
8973
+ const outputValue = this.getOutputValue(items);
8974
+ this.onChange(outputValue);
8975
+ this.logDebug('📊 Estado del control después de onChange:', {
8976
+ controlName: this.getFormControlName(),
8977
+ status: this.controlStatus,
8978
+ value: outputValue,
8979
+ });
8980
+ if (items.length === 0 && this.ngControl?.control) {
8981
+ this.ngControl.control.markAsTouched();
8982
+ this.onTouched();
8983
+ this.logDebug('📝 Control marcado como touched (selección vacía)', {
8984
+ newStatus: this.controlStatus,
8985
+ });
8986
+ }
8987
+ this.logDebug('📝 Selección actualizada', {
8988
+ returnID: this.returnID(),
8989
+ items: items.length,
8990
+ output: outputValue,
8991
+ });
8992
+ }
8993
+ getOutputValue(items) {
8994
+ if (items.length === 0) {
8995
+ return this.isMultiple() ? [] : null;
8996
+ }
8997
+ if (this.returnID()) {
8998
+ const ids = items.map((item) => Number(item[this.idKey()]));
8999
+ return this.isMultiple() ? ids : ids[0];
9000
+ }
9001
+ return this.isMultiple() ? items : items[0];
9002
+ }
9003
+ obtenerArrayValue() {
9004
+ if (this.isMultiple()) {
9005
+ return Array.isArray(this.value) ? this.value : [];
9006
+ }
9007
+ return this.value ? [this.value] : [];
9008
+ }
9009
+ getValueLength() {
9010
+ if (this.isMultiple()) {
9011
+ return Array.isArray(this.value) ? this.value.length : 0;
9012
+ }
9013
+ return this.value ? 1 : 0;
9014
+ }
9015
+ getValueDisplay(type) {
9016
+ if (!this.value || (Array.isArray(this.value) && this.value.length === 0)) {
9017
+ return 'Ninguno';
9018
+ }
9019
+ const items = Array.isArray(this.value) ? this.value : [this.value];
9020
+ if (type === 'id') {
9021
+ return items.map((item) => item[this.idKey()]).join(', ') || 'Ninguno';
9022
+ }
9023
+ else {
9024
+ return (items.map((item) => item[this.optionLabel()]).join(', ') || 'Ninguno');
9025
+ }
9026
+ }
9027
+ onHide() {
9028
+ this.logDebug('Dropdown ocultado - Limpiando estado');
9029
+ if (this.timeoutLimpieza) {
9030
+ clearTimeout(this.timeoutLimpieza);
9031
+ this.timeoutLimpieza = null;
9032
+ }
9033
+ this.timeoutLimpieza = setTimeout(() => {
9034
+ this.dataFiltrada.set([]);
9035
+ this.timeoutLimpieza = null;
9036
+ }, 100);
9037
+ if (this.ngControl?.control) {
9038
+ const estabaTouched = this.ngControl.control.touched;
9039
+ if (!estabaTouched) {
9040
+ this.ngControl.control.markAsTouched();
9041
+ this.onTouched();
9042
+ this.logDebug('Control marked as touched (onHide)', {
9043
+ controlName: this.getFormControlName(),
9044
+ newStatus: this.controlStatus,
9045
+ });
9046
+ }
9047
+ else {
9048
+ this.logDebug('Control ya estaba touched (onHide)', {
9049
+ controlName: this.getFormControlName(),
9050
+ status: this.controlStatus,
9051
+ });
9052
+ }
9053
+ }
9054
+ }
9055
+ onShow() {
9056
+ this.logDebug('Dropdown mostrado');
9057
+ if (this.timeoutLimpieza) {
9058
+ clearTimeout(this.timeoutLimpieza);
9059
+ this.timeoutLimpieza = null;
9060
+ }
9061
+ }
9062
+ // ✨ MEJORADO: actualizarFormulario para manejar correctamente valores vacíos
9063
+ actualizarFormulario(nuevaLista) {
9064
+ // Si la lista está vacía, siempre enviar null o [] según el modo
9065
+ if (nuevaLista.length === 0) {
9066
+ if (this.isMultiple()) {
9067
+ this.value = [];
9068
+ }
9069
+ else {
9070
+ this.value = null;
9071
+ }
9072
+ const outputValue = this.isMultiple() ? [] : null;
9073
+ this.onChange(outputValue);
9074
+ this.logDebug('Formulario actualizado (vacío)', {
9075
+ isMultiple: this.isMultiple(),
9076
+ output: outputValue,
9077
+ });
9078
+ return;
9079
+ }
9080
+ // Si hay elementos, procesar normalmente
9081
+ if (this.isMultiple()) {
9082
+ this.value = nuevaLista;
9083
+ }
9084
+ else {
9085
+ this.value = nuevaLista.length > 0 ? nuevaLista[0] : null;
9086
+ }
9087
+ const outputValue = this.getOutputValue(nuevaLista);
9088
+ this.onChange(outputValue);
9089
+ this.logDebug('Formulario actualizado', {
9090
+ total: nuevaLista.length,
9091
+ isMultiple: this.isMultiple(),
9092
+ returnID: this.returnID(),
9093
+ output: outputValue,
9094
+ });
9095
+ }
9096
+ getFormControlName() {
9097
+ return this.ngControl?.name || null;
9098
+ }
9099
+ writeValue(value) {
9100
+ const timestamp = new Date().toISOString();
9101
+ this.logDebug(`🔄 writeValue INVOCADO ${timestamp}`, {
9102
+ value,
9103
+ type: value === null
9104
+ ? 'null'
9105
+ : value === undefined
9106
+ ? 'undefined'
9107
+ : Array.isArray(value)
9108
+ ? 'array'
9109
+ : typeof value === 'object'
9110
+ ? 'object'
9111
+ : typeof value,
9112
+ returnID: this.returnID(),
9113
+ isMultiple: this.isMultiple(),
9114
+ hasDatasource: this.datasource().length > 0,
9115
+ datasourceSize: this.datasource().length,
9116
+ });
9117
+ if (value === null || value === undefined) {
9118
+ this.logDebug(`⚠️ Valor null/undefined, limpiando selección`);
9119
+ this.value = this.isMultiple() ? [] : null;
9120
+ this.initialValueSet = true;
9121
+ this.cdr.markForCheck();
9122
+ this.cdr.detectChanges();
9123
+ return;
9124
+ }
9125
+ let items = [];
9126
+ let ids = [];
9127
+ if (Array.isArray(value)) {
9128
+ if (value.length === 0) {
9129
+ this.value = this.isMultiple() ? [] : null;
9130
+ this.initialValueSet = true;
9131
+ this.cdr.markForCheck();
9132
+ this.cdr.detectChanges();
9133
+ return;
9134
+ }
9135
+ if (typeof value[0] === 'number') {
9136
+ ids = value;
9137
+ }
9138
+ else if (typeof value[0] === 'object' && value[0] !== null) {
9139
+ items = value;
9140
+ }
9141
+ }
9142
+ else if (typeof value === 'number') {
9143
+ ids = [value];
9144
+ }
9145
+ else if (typeof value === 'object' && value !== null) {
9146
+ items = [value];
9147
+ }
9148
+ else {
9149
+ this.value = this.isMultiple() ? [] : null;
9150
+ this.initialValueSet = true;
9151
+ this.cdr.markForCheck();
9152
+ this.cdr.detectChanges();
9153
+ return;
9154
+ }
9155
+ const sourceData = this.datasource();
9156
+ if (ids.length > 0) {
9157
+ if (sourceData.length === 0) {
9158
+ this.logDebug(`⚠️ Datasource vacío, guardando IDs para luego`);
9159
+ this.value = this.isMultiple() ? [] : null;
9160
+ this.initialValueSet = true;
9161
+ this.cdr.markForCheck();
9162
+ this.cdr.detectChanges();
9163
+ return;
9164
+ }
9165
+ const objetos = sourceData.filter((item) => ids.includes(Number(item[this.idKey()])));
9166
+ const objetosOrdenados = ids
9167
+ .map((id) => objetos.find((item) => Number(item[this.idKey()]) === id))
9168
+ .filter((item) => item !== undefined);
9169
+ items = objetosOrdenados;
9170
+ this.logDebug(`🔍 Encontrados ${items.length} de ${ids.length} IDs`);
9171
+ }
9172
+ if (items.length > 0 && sourceData.length > 0) {
9173
+ const itemsValidos = items.filter((item) => sourceData.some((s) => s[this.idKey()] === item[this.idKey()]));
9174
+ if (itemsValidos.length !== items.length) {
9175
+ this.logDebug(`⚠️ Algunos objetos no existen en datasource`, {
9176
+ original: items.length,
9177
+ validos: itemsValidos.length,
9178
+ });
9179
+ items = itemsValidos;
9180
+ }
9181
+ }
9182
+ if (this.isMultiple()) {
9183
+ this.value = items;
9184
+ }
9185
+ else {
9186
+ this.value = items.length > 0 ? items[0] : null;
9187
+ }
9188
+ this.initialValueSet = true;
9189
+ this.cdr.detectChanges();
9190
+ this.logDebug(`✅ Vista actualizada con ${items.length} elementos (${this.isMultiple() ? 'multiple' : 'single'})`);
9191
+ }
9192
+ forceReload() {
9193
+ this.logDebug('🔄 Forzando recarga');
9194
+ if (this.ngControl?.control) {
9195
+ const currentValue = this.ngControl.control.value;
9196
+ this.logDebug('🔄 Valor actual del formulario:', currentValue);
9197
+ this.writeValue(currentValue);
9198
+ }
9199
+ }
9200
+ registerOnChange(fn) {
9201
+ this.onChange = fn;
9202
+ }
9203
+ registerOnTouched(fn) {
9204
+ this.onTouched = fn;
9205
+ }
9206
+ setDisabledState(isDisabled) {
9207
+ this.disabled = isDisabled;
9208
+ this.cdr.markForCheck();
9209
+ }
9210
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxAutocomplete, deps: [], target: i0.ɵɵFactoryTarget.Component });
9211
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: DsxAutocomplete, isStandalone: true, selector: "dsx-autocomplete", inputs: { datasource: { classPropertyName: "datasource", publicName: "datasource", isSignal: true, isRequired: true, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, delay: { classPropertyName: "delay", publicName: "delay", isSignal: true, isRequired: false, transformFunction: null }, idKey: { classPropertyName: "idKey", publicName: "idKey", isSignal: true, isRequired: true, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: true, isRequired: false, transformFunction: null }, permitirCrear: { classPropertyName: "permitirCrear", publicName: "permitirCrear", isSignal: true, isRequired: false, transformFunction: null }, isMultiple: { classPropertyName: "isMultiple", publicName: "isMultiple", isSignal: true, isRequired: false, transformFunction: null }, debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null }, factoryNuevoRegistro: { classPropertyName: "factoryNuevoRegistro", publicName: "factoryNuevoRegistro", isSignal: true, isRequired: false, transformFunction: null }, returnID: { classPropertyName: "returnID", publicName: "returnID", isSignal: true, isRequired: false, transformFunction: null }, showError: { classPropertyName: "showError", publicName: "showError", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
9212
+ {
9213
+ provide: NG_VALUE_ACCESSOR,
9214
+ useExisting: forwardRef(() => DsxAutocomplete),
9215
+ multi: true,
9216
+ },
9217
+ ], ngImport: i0, template: "<p-floatlabel variant=\"on\">\r\n <p-autoComplete\r\n fluid\r\n appendTo=\"body\"\r\n [multiple]=\"isMultiple()\"\r\n [dropdown]=\"true\"\r\n [showClear]=\"true\"\r\n [suggestions]=\"dataFiltrada()\"\r\n (completeMethod)=\"searchRequisitos($event)\"\r\n [(ngModel)]=\"value\"\r\n (ngModelChange)=\"onNgModelChange($event)\"\r\n (onBlur)=\"onTouched()\"\r\n (onShow)=\"onShow()\"\r\n (onHide)=\"onHide()\"\r\n [disabled]=\"disabled\"\r\n [optionLabel]=\"optionLabel()\"\r\n [dataKey]=\"dataKey() || idKey()\"\r\n (keyup.enter)=\"evaluarYAgregar($event)\"\r\n [delay]=\"delay()\"\r\n placeholder=\"Ingresa un texto....\"\r\n [inputStyle]=\"{'text-transform': 'uppercase'}\"\r\n >\r\n <ng-template let-item pTemplate=\"selectedItem\">\r\n {{ item[optionLabel()] }}\r\n </ng-template>\r\n\r\n <ng-template let-item pTemplate=\"item\">\r\n {{ item[optionLabel()] }}\r\n </ng-template>\r\n </p-autoComplete>\r\n <label>{{ label() }}</label>\r\n</p-floatlabel>\r\n\r\n<!-- Bot\u00F3n de limpiar para modo single -->\r\n@if (!isMultiple() && value) {\r\n<button\r\n type=\"button\"\r\n (click)=\"clearSelection()\"\r\n style=\"\r\n position: absolute;\r\n right: 10px;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n background: transparent;\r\n border: none;\r\n cursor: pointer;\r\n color: #999;\r\n font-size: 14px;\r\n z-index: 1;\r\n \"\r\n aria-label=\"Limpiar selecci\u00F3n\"\r\n>\r\n \u2715\r\n</button>\r\n}\r\n\r\n<!-- Mensaje de error -->\r\n@if (showError() && errorControl()) {\r\n<dsx-message-error [control]=\"errorControl()\" />\r\n}\r\n\r\n<!-- Panel de Debug -->\r\n@if (debug() && isDevMode) {\r\n<div\r\n style=\"\r\n margin-top: 8px;\r\n font-size: 11px;\r\n color: #666;\r\n background: #f5f5f5;\r\n padding: 6px 10px;\r\n border-radius: 4px;\r\n font-family: monospace;\r\n border: 1px solid #ddd;\r\n \"\r\n>\r\n <div\r\n style=\"\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n gap: 8px;\r\n flex-wrap: wrap;\r\n \"\r\n >\r\n <div>\r\n <strong>\uD83D\uDD0D Debug:</strong>\r\n <span style=\"margin-left: 8px\">Items: {{ getValueLength() }}</span>\r\n <span style=\"margin-left: 8px\">IDs: {{ getValueDisplay('id') }}</span>\r\n <span style=\"margin-left: 8px\"\r\n >Nombres: {{ getValueDisplay('nombre') }}</span\r\n >\r\n <span style=\"margin-left: 8px; color: #888; font-size: 10px\">\r\n | returnID: {{ returnID() ? '\u2705 IDs' : '\u274C Objetos' }} | Multiple: {{\r\n isMultiple() ? '\u2705' : '\u274C' }} | Control: {{ controlName || 'sin nombre'\r\n }}\r\n </span>\r\n </div>\r\n <div\r\n style=\"\r\n font-size: 10px;\r\n color: #333;\r\n background: #e8e8e8;\r\n padding: 2px 8px;\r\n border-radius: 4px;\r\n \"\r\n >\r\n <strong>\uD83D\uDCCA Validaci\u00F3n:</strong>\r\n <span [style.color]=\"controlValid ? 'green' : 'red'\">\r\n {{ controlValid ? '\u2705 V\u00E1lido' : '\u274C Inv\u00E1lido' }}\r\n </span>\r\n <span style=\"margin-left: 4px\">\r\n | Touched: {{ controlTouched ? '\u2705' : '\u274C' }}\r\n </span>\r\n <span style=\"margin-left: 4px\">\r\n | Dirty: {{ controlDirty ? '\u2705' : '\u274C' }}\r\n </span>\r\n @if (controlErrors) {\r\n <span style=\"margin-left: 4px; color: red\">\r\n | Errors: {{ controlErrors | json }}\r\n </span>\r\n }\r\n </div>\r\n <button\r\n (click)=\"forceReload()\"\r\n style=\"\r\n font-size: 10px;\r\n padding: 2px 8px;\r\n border-radius: 4px;\r\n border: 1px solid #ccc;\r\n background: white;\r\n cursor: pointer;\r\n \"\r\n type=\"button\"\r\n >\r\n \uD83D\uDD04 Recargar\r\n </button>\r\n </div>\r\n</div>\r\n}\r\n", styles: [""], dependencies: [{ kind: "component", type: AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "minQueryLength", "delay", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "addOnTab", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "addOnBlur", "separator", "appendTo", "motionOptions"], outputs: ["completeMethod", "onSelect", "onUnselect", "onAdd", "onFocus", "onBlur", "onDropdownClick", "onClear", "onInputKeydown", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "component", type: AppMessageErrorComponent, selector: "dsx-message-error", inputs: ["control", "form", "debugMode"] }, { kind: "pipe", type: JsonPipe, name: "json" }] });
9218
+ }
9219
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxAutocomplete, decorators: [{
9220
+ type: Component,
9221
+ args: [{ selector: 'dsx-autocomplete', imports: [
9222
+ AutoComplete,
9223
+ FormsModule,
9224
+ FloatLabel,
9225
+ JsonPipe,
9226
+ AppMessageErrorComponent,
9227
+ ], providers: [
9228
+ {
9229
+ provide: NG_VALUE_ACCESSOR,
9230
+ useExisting: forwardRef(() => DsxAutocomplete),
9231
+ multi: true,
9232
+ },
9233
+ ], template: "<p-floatlabel variant=\"on\">\r\n <p-autoComplete\r\n fluid\r\n appendTo=\"body\"\r\n [multiple]=\"isMultiple()\"\r\n [dropdown]=\"true\"\r\n [showClear]=\"true\"\r\n [suggestions]=\"dataFiltrada()\"\r\n (completeMethod)=\"searchRequisitos($event)\"\r\n [(ngModel)]=\"value\"\r\n (ngModelChange)=\"onNgModelChange($event)\"\r\n (onBlur)=\"onTouched()\"\r\n (onShow)=\"onShow()\"\r\n (onHide)=\"onHide()\"\r\n [disabled]=\"disabled\"\r\n [optionLabel]=\"optionLabel()\"\r\n [dataKey]=\"dataKey() || idKey()\"\r\n (keyup.enter)=\"evaluarYAgregar($event)\"\r\n [delay]=\"delay()\"\r\n placeholder=\"Ingresa un texto....\"\r\n [inputStyle]=\"{'text-transform': 'uppercase'}\"\r\n >\r\n <ng-template let-item pTemplate=\"selectedItem\">\r\n {{ item[optionLabel()] }}\r\n </ng-template>\r\n\r\n <ng-template let-item pTemplate=\"item\">\r\n {{ item[optionLabel()] }}\r\n </ng-template>\r\n </p-autoComplete>\r\n <label>{{ label() }}</label>\r\n</p-floatlabel>\r\n\r\n<!-- Bot\u00F3n de limpiar para modo single -->\r\n@if (!isMultiple() && value) {\r\n<button\r\n type=\"button\"\r\n (click)=\"clearSelection()\"\r\n style=\"\r\n position: absolute;\r\n right: 10px;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n background: transparent;\r\n border: none;\r\n cursor: pointer;\r\n color: #999;\r\n font-size: 14px;\r\n z-index: 1;\r\n \"\r\n aria-label=\"Limpiar selecci\u00F3n\"\r\n>\r\n \u2715\r\n</button>\r\n}\r\n\r\n<!-- Mensaje de error -->\r\n@if (showError() && errorControl()) {\r\n<dsx-message-error [control]=\"errorControl()\" />\r\n}\r\n\r\n<!-- Panel de Debug -->\r\n@if (debug() && isDevMode) {\r\n<div\r\n style=\"\r\n margin-top: 8px;\r\n font-size: 11px;\r\n color: #666;\r\n background: #f5f5f5;\r\n padding: 6px 10px;\r\n border-radius: 4px;\r\n font-family: monospace;\r\n border: 1px solid #ddd;\r\n \"\r\n>\r\n <div\r\n style=\"\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n gap: 8px;\r\n flex-wrap: wrap;\r\n \"\r\n >\r\n <div>\r\n <strong>\uD83D\uDD0D Debug:</strong>\r\n <span style=\"margin-left: 8px\">Items: {{ getValueLength() }}</span>\r\n <span style=\"margin-left: 8px\">IDs: {{ getValueDisplay('id') }}</span>\r\n <span style=\"margin-left: 8px\"\r\n >Nombres: {{ getValueDisplay('nombre') }}</span\r\n >\r\n <span style=\"margin-left: 8px; color: #888; font-size: 10px\">\r\n | returnID: {{ returnID() ? '\u2705 IDs' : '\u274C Objetos' }} | Multiple: {{\r\n isMultiple() ? '\u2705' : '\u274C' }} | Control: {{ controlName || 'sin nombre'\r\n }}\r\n </span>\r\n </div>\r\n <div\r\n style=\"\r\n font-size: 10px;\r\n color: #333;\r\n background: #e8e8e8;\r\n padding: 2px 8px;\r\n border-radius: 4px;\r\n \"\r\n >\r\n <strong>\uD83D\uDCCA Validaci\u00F3n:</strong>\r\n <span [style.color]=\"controlValid ? 'green' : 'red'\">\r\n {{ controlValid ? '\u2705 V\u00E1lido' : '\u274C Inv\u00E1lido' }}\r\n </span>\r\n <span style=\"margin-left: 4px\">\r\n | Touched: {{ controlTouched ? '\u2705' : '\u274C' }}\r\n </span>\r\n <span style=\"margin-left: 4px\">\r\n | Dirty: {{ controlDirty ? '\u2705' : '\u274C' }}\r\n </span>\r\n @if (controlErrors) {\r\n <span style=\"margin-left: 4px; color: red\">\r\n | Errors: {{ controlErrors | json }}\r\n </span>\r\n }\r\n </div>\r\n <button\r\n (click)=\"forceReload()\"\r\n style=\"\r\n font-size: 10px;\r\n padding: 2px 8px;\r\n border-radius: 4px;\r\n border: 1px solid #ccc;\r\n background: white;\r\n cursor: pointer;\r\n \"\r\n type=\"button\"\r\n >\r\n \uD83D\uDD04 Recargar\r\n </button>\r\n </div>\r\n</div>\r\n}\r\n" }]
9234
+ }], ctorParameters: () => [], propDecorators: { datasource: [{ type: i0.Input, args: [{ isSignal: true, alias: "datasource", required: true }] }], optionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionLabel", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], delay: [{ type: i0.Input, args: [{ isSignal: true, alias: "delay", required: false }] }], idKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "idKey", required: true }] }], dataKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataKey", required: false }] }], permitirCrear: [{ type: i0.Input, args: [{ isSignal: true, alias: "permitirCrear", required: false }] }], isMultiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "isMultiple", required: false }] }], debug: [{ type: i0.Input, args: [{ isSignal: true, alias: "debug", required: false }] }], factoryNuevoRegistro: [{ type: i0.Input, args: [{ isSignal: true, alias: "factoryNuevoRegistro", required: false }] }], returnID: [{ type: i0.Input, args: [{ isSignal: true, alias: "returnID", required: false }] }], showError: [{ type: i0.Input, args: [{ isSignal: true, alias: "showError", required: false }] }] } });
9235
+
8855
9236
  // dsx-select.component.ts
8856
9237
  class DsxSelect {
8857
9238
  injector = inject(Injector);