ngx-dsxlibrary 2.21.67 → 2.21.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ngx-dsxlibrary-src-lib-primengdsx.mjs +169 -26
- package/fesm2022/ngx-dsxlibrary-src-lib-primengdsx.mjs.map +1 -1
- package/fesm2022/ngx-dsxlibrary.mjs +1174 -174
- package/fesm2022/ngx-dsxlibrary.mjs.map +1 -1
- package/ngx-dsxlibrary-2.21.69.tgz +0 -0
- package/package.json +1 -1
- package/src/assets/css/primeng_dsx_table.css +1 -1
- package/types/ngx-dsxlibrary-src-lib-primengdsx.d.ts +33 -5
- package/types/ngx-dsxlibrary.d.ts +336 -52
- package/ngx-dsxlibrary-2.21.67.tgz +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, forwardRef, Component, EventEmitter, effect, Output, viewChild, signal, Input, model, inject, computed, Injectable, isDevMode, InjectionToken, output, HostBinding, ChangeDetectorRef, untracked, Pipe, ViewEncapsulation, HostListener, Directive, NgZone, ElementRef, NgModule, Injector } from '@angular/core';
|
|
2
|
+
import { input, forwardRef, Component, EventEmitter, effect, Output, viewChild, signal, Input, model, inject, computed, Injectable, isDevMode, InjectionToken, output, HostBinding, ChangeDetectorRef, untracked, Pipe, ViewEncapsulation, HostListener, Directive, NgZone, ElementRef, ChangeDetectionStrategy, NgModule, Injector, ViewChild } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/forms';
|
|
4
|
-
import { FormsModule, NG_VALUE_ACCESSOR, FormControl, NG_VALIDATORS, FormBuilder, Validators, ReactiveFormsModule, NgControl, FormGroup } from '@angular/forms';
|
|
4
|
+
import { FormsModule, NG_VALUE_ACCESSOR, AbstractControl, FormControl, NG_VALIDATORS, FormBuilder, Validators, ReactiveFormsModule, NgControl, FormGroup } from '@angular/forms';
|
|
5
5
|
import * as i2 from 'primeng/togglebutton';
|
|
6
6
|
import { ToggleButtonModule } from 'primeng/togglebutton';
|
|
7
7
|
import * as i1$1 from '@angular/common';
|
|
8
|
-
import { CommonModule, AsyncPipe, DecimalPipe, Location } from '@angular/common';
|
|
8
|
+
import { CommonModule, AsyncPipe, DecimalPipe, Location, JsonPipe } from '@angular/common';
|
|
9
9
|
import * as i2$1 from 'primeng/tree';
|
|
10
10
|
import { TreeModule } from 'primeng/tree';
|
|
11
11
|
import * as i3 from 'primeng/api';
|
|
@@ -54,14 +54,14 @@ import { CardModule } from 'primeng/card';
|
|
|
54
54
|
import { CheckboxModule } from 'primeng/checkbox';
|
|
55
55
|
import { ContextMenuModule } from 'primeng/contextmenu';
|
|
56
56
|
import { DataViewModule } from 'primeng/dataview';
|
|
57
|
-
import { DatePickerModule } from 'primeng/datepicker';
|
|
57
|
+
import { DatePickerModule, DatePicker } from 'primeng/datepicker';
|
|
58
58
|
import { DividerModule } from 'primeng/divider';
|
|
59
59
|
import { DrawerModule } from 'primeng/drawer';
|
|
60
60
|
import { FieldsetModule } from 'primeng/fieldset';
|
|
61
61
|
import { IconFieldModule } from 'primeng/iconfield';
|
|
62
62
|
import { InputIconModule } from 'primeng/inputicon';
|
|
63
63
|
import { InputMaskModule } from 'primeng/inputmask';
|
|
64
|
-
import { InputNumberModule } from 'primeng/inputnumber';
|
|
64
|
+
import { InputNumberModule, InputNumber } from 'primeng/inputnumber';
|
|
65
65
|
import { InputTextModule } from 'primeng/inputtext';
|
|
66
66
|
import { KeyFilterModule } from 'primeng/keyfilter';
|
|
67
67
|
import { KnobModule } from 'primeng/knob';
|
|
@@ -1079,7 +1079,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
1079
1079
|
args: [{ selector: 'icon-dsx', imports: [AsyncPipe], template: "<span class=\"dsx-icon\" [innerHTML]=\"svg$ | async\"></span>\r\n", styles: [":host{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;width:1em;height:1em;font-size:24px;line-height:1;flex-shrink:0}.dsx-icon{display:inline-flex;align-items:center;justify-content:center;width:100%;height:100%}:host ::ng-deep .dsx-icon svg{width:100%;height:100%;fill:currentColor;shape-rendering:geometricPrecision;stroke:currentColor;stroke-width:4px;stroke-linejoin:round;stroke-linecap:round;overflow:visible;transition:fill .2s ease,stroke .2s ease}\n"] }]
|
|
1080
1080
|
}], ctorParameters: () => [{ type: IconDsxService }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], style: [{ type: i0.Input, args: [{ isSignal: true, alias: "style", required: false }] }], debug: [{ type: i0.Input, args: [{ isSignal: true, alias: "debug", required: false }] }] } });
|
|
1081
1081
|
|
|
1082
|
-
// app-message-error.component.ts
|
|
1082
|
+
// app-message-error.component.ts
|
|
1083
1083
|
class AppMessageErrorComponent {
|
|
1084
1084
|
elementRef;
|
|
1085
1085
|
renderer;
|
|
@@ -1107,7 +1107,7 @@ class AppMessageErrorComponent {
|
|
|
1107
1107
|
this.lastErrorsCount = nuevoControl.errors
|
|
1108
1108
|
? Object.keys(nuevoControl.errors).length
|
|
1109
1109
|
: 0;
|
|
1110
|
-
if (this.debugMode) {
|
|
1110
|
+
if (this.isDevelopmentMode() && this.debugMode) {
|
|
1111
1111
|
console.log('[ERROR-COMPONENT] Control asignado:', {
|
|
1112
1112
|
status: nuevoControl.status,
|
|
1113
1113
|
errors: nuevoControl.errors,
|
|
@@ -1128,27 +1128,26 @@ class AppMessageErrorComponent {
|
|
|
1128
1128
|
this.renderer = renderer;
|
|
1129
1129
|
}
|
|
1130
1130
|
ngAfterViewInit() {
|
|
1131
|
-
// Intentar encontrar el floatLabel padre
|
|
1132
1131
|
this.floatLabelElement = this.elementRef.nativeElement.closest('.p-floatlabel');
|
|
1133
1132
|
if (this.floatLabelElement) {
|
|
1134
1133
|
this.previousInlineMarginBottom =
|
|
1135
1134
|
this.floatLabelElement.style.marginBottom;
|
|
1136
|
-
if (this.debugMode) {
|
|
1135
|
+
if (this.isDevelopmentMode() && this.debugMode) {
|
|
1137
1136
|
console.log('[ERROR-COMPONENT] FloatLabel encontrado, modo absoluto');
|
|
1138
1137
|
}
|
|
1139
1138
|
}
|
|
1140
1139
|
else {
|
|
1141
|
-
if (this.debugMode) {
|
|
1140
|
+
if (this.isDevelopmentMode() && this.debugMode) {
|
|
1142
1141
|
console.log('[ERROR-COMPONENT] No hay FloatLabel, modo estático');
|
|
1143
1142
|
}
|
|
1144
1143
|
}
|
|
1145
|
-
// Observador de visibilidad
|
|
1146
1144
|
if (typeof window !== 'undefined' && 'IntersectionObserver' in window) {
|
|
1147
1145
|
this.observer = new IntersectionObserver((entries) => {
|
|
1148
1146
|
entries.forEach((entry) => {
|
|
1149
1147
|
const wasVisible = this.isElementAttachedAndVisible;
|
|
1150
1148
|
this.isElementAttachedAndVisible = entry.isIntersecting;
|
|
1151
|
-
if (this.
|
|
1149
|
+
if (this.isDevelopmentMode() &&
|
|
1150
|
+
this.debugMode &&
|
|
1152
1151
|
wasVisible !== this.isElementAttachedAndVisible) {
|
|
1153
1152
|
console.log('[ERROR-COMPONENT] Visibilidad:', this.isElementAttachedAndVisible);
|
|
1154
1153
|
}
|
|
@@ -1173,7 +1172,7 @@ class AppMessageErrorComponent {
|
|
|
1173
1172
|
this.control.touched !== this.lastControlTouched ||
|
|
1174
1173
|
this.control.dirty !== this.lastControlDirty ||
|
|
1175
1174
|
currentErrorsCount !== this.lastErrorsCount) {
|
|
1176
|
-
if (this.debugMode) {
|
|
1175
|
+
if (this.isDevelopmentMode() && this.debugMode) {
|
|
1177
1176
|
console.log('[ERROR-COMPONENT] Cambio detectado:', {
|
|
1178
1177
|
invalid: this.control.invalid,
|
|
1179
1178
|
touched: this.control.touched,
|
|
@@ -1191,7 +1190,6 @@ class AppMessageErrorComponent {
|
|
|
1191
1190
|
if (this.observer) {
|
|
1192
1191
|
this.observer.disconnect();
|
|
1193
1192
|
}
|
|
1194
|
-
// Restaurar margen solo si existe floatLabelElement
|
|
1195
1193
|
if (this.floatLabelElement) {
|
|
1196
1194
|
if (this.previousInlineMarginBottom) {
|
|
1197
1195
|
this.renderer.setStyle(this.floatLabelElement, 'margin-bottom', this.previousInlineMarginBottom);
|
|
@@ -1202,11 +1200,7 @@ class AppMessageErrorComponent {
|
|
|
1202
1200
|
}
|
|
1203
1201
|
}
|
|
1204
1202
|
syncFloatLabelSpacing() {
|
|
1205
|
-
|
|
1206
|
-
if (!this.floatLabelElement) {
|
|
1207
|
-
return;
|
|
1208
|
-
}
|
|
1209
|
-
if (!this.isElementAttachedAndVisible)
|
|
1203
|
+
if (!this.floatLabelElement || !this.isElementAttachedAndVisible)
|
|
1210
1204
|
return;
|
|
1211
1205
|
const isVisible = this.isControlErrorVisible();
|
|
1212
1206
|
const desiredSpace = this.getFloatLabelErrorSpace();
|
|
@@ -1228,11 +1222,9 @@ class AppMessageErrorComponent {
|
|
|
1228
1222
|
this.renderer.removeStyle(this.floatLabelElement, 'margin-bottom');
|
|
1229
1223
|
}
|
|
1230
1224
|
isControlErrorVisible() {
|
|
1231
|
-
// ✅ La condición base es la misma para ambos contextos
|
|
1232
1225
|
if (!this.control || !this.control.invalid) {
|
|
1233
1226
|
return false;
|
|
1234
1227
|
}
|
|
1235
|
-
// Solo mostrar si el usuario ha interactuado
|
|
1236
1228
|
return !!(this.control.touched || this.control.dirty);
|
|
1237
1229
|
}
|
|
1238
1230
|
getFloatLabelErrorSpace() {
|
|
@@ -1251,18 +1243,140 @@ class AppMessageErrorComponent {
|
|
|
1251
1243
|
}
|
|
1252
1244
|
return this.defaultFloatLabelErrorSpace;
|
|
1253
1245
|
}
|
|
1254
|
-
|
|
1246
|
+
/**
|
|
1247
|
+
* Obtiene el mensaje de error de un error específico del control
|
|
1248
|
+
* @param errorKey - La clave del error
|
|
1249
|
+
* @returns El mensaje de error o un string vacío
|
|
1250
|
+
*/
|
|
1251
|
+
getErrorMessage(errorKey) {
|
|
1252
|
+
if (!this.control || !this.control.errors) {
|
|
1253
|
+
return '';
|
|
1254
|
+
}
|
|
1255
|
+
const error = this.control.errors[errorKey];
|
|
1256
|
+
if (!error) {
|
|
1257
|
+
return '';
|
|
1258
|
+
}
|
|
1259
|
+
if (typeof error === 'object' && error !== null && 'message' in error) {
|
|
1260
|
+
return error.message;
|
|
1261
|
+
}
|
|
1262
|
+
return '';
|
|
1263
|
+
}
|
|
1264
|
+
/**
|
|
1265
|
+
* Obtiene el valor de un error específico del control
|
|
1266
|
+
* @param errorKey - La clave del error
|
|
1267
|
+
* @param propertyKey - La propiedad del error a obtener
|
|
1268
|
+
* @returns El valor de la propiedad o undefined
|
|
1269
|
+
*/
|
|
1270
|
+
getErrorValue(errorKey, propertyKey) {
|
|
1271
|
+
if (!this.control || !this.control.errors) {
|
|
1272
|
+
return undefined;
|
|
1273
|
+
}
|
|
1274
|
+
const error = this.control.errors[errorKey];
|
|
1275
|
+
if (!error || typeof error !== 'object') {
|
|
1276
|
+
return undefined;
|
|
1277
|
+
}
|
|
1278
|
+
return error[propertyKey];
|
|
1279
|
+
}
|
|
1280
|
+
/**
|
|
1281
|
+
* Obtiene los detalles de un error de template
|
|
1282
|
+
* @param errorKey - La clave del error (invalidTemplateVariables o invalidTemplateStructure)
|
|
1283
|
+
* @returns El array de detalles o un array vacío
|
|
1284
|
+
*/
|
|
1285
|
+
getTemplateErrorDetails(errorKey) {
|
|
1286
|
+
if (!this.control || !this.control.errors) {
|
|
1287
|
+
return [];
|
|
1288
|
+
}
|
|
1289
|
+
const error = this.control.errors[errorKey];
|
|
1290
|
+
if (!error || typeof error !== 'object' || !('details' in error)) {
|
|
1291
|
+
return [];
|
|
1292
|
+
}
|
|
1293
|
+
const details = error.details;
|
|
1294
|
+
return Array.isArray(details) ? details : [];
|
|
1295
|
+
}
|
|
1296
|
+
/**
|
|
1297
|
+
* Obtiene el primer detalle de un error de template
|
|
1298
|
+
* @param errorKey - La clave del error
|
|
1299
|
+
* @returns El primer detalle o string vacío
|
|
1300
|
+
*/
|
|
1301
|
+
getFirstTemplateErrorDetail(errorKey) {
|
|
1302
|
+
const details = this.getTemplateErrorDetails(errorKey);
|
|
1303
|
+
return details.length > 0 ? details[0] : '';
|
|
1304
|
+
}
|
|
1305
|
+
/**
|
|
1306
|
+
* Obtiene el mensaje completo para similitud detectada
|
|
1307
|
+
* @returns El mensaje formateado
|
|
1308
|
+
*/
|
|
1309
|
+
getSimilitudMessage() {
|
|
1310
|
+
if (!this.control || !this.control.errors) {
|
|
1311
|
+
return '';
|
|
1312
|
+
}
|
|
1313
|
+
const error = this.control.errors['similitudDetectada'];
|
|
1314
|
+
if (!error || typeof error !== 'object' || !('sugerencia' in error)) {
|
|
1315
|
+
return '';
|
|
1316
|
+
}
|
|
1317
|
+
return `Ya existe un registro muy similar en el sistema: "${error.sugerencia}".`;
|
|
1318
|
+
}
|
|
1319
|
+
/**
|
|
1320
|
+
* Obtiene el mensaje de error de un error específico del formulario
|
|
1321
|
+
* @param errorKey - La clave del error
|
|
1322
|
+
* @returns El mensaje de error o un mensaje por defecto
|
|
1323
|
+
*/
|
|
1324
|
+
getFormError(errorKey) {
|
|
1325
|
+
if (!this.form) {
|
|
1326
|
+
return '';
|
|
1327
|
+
}
|
|
1328
|
+
const error = this.form.getError(errorKey);
|
|
1329
|
+
if (error && typeof error === 'object' && 'message' in error) {
|
|
1330
|
+
return error.message;
|
|
1331
|
+
}
|
|
1332
|
+
// Mensaje por defecto según el tipo de error
|
|
1333
|
+
switch (errorKey) {
|
|
1334
|
+
case 'atLeastOneRequired':
|
|
1335
|
+
return 'Al menos un campo es requerido';
|
|
1336
|
+
default:
|
|
1337
|
+
return 'Error en el formulario';
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
/**
|
|
1341
|
+
* Formatea un número con separadores de miles (coma) y decimales (punto)
|
|
1342
|
+
* @param value - El valor a formatear (puede ser número o string)
|
|
1343
|
+
* @param showDecimals - Si se deben mostrar siempre los decimales
|
|
1344
|
+
* @returns String formateado con separadores de miles
|
|
1345
|
+
*/
|
|
1346
|
+
formatNumber(value, showDecimals = false) {
|
|
1347
|
+
// Si es null o undefined, retornar string vacío
|
|
1348
|
+
if (value === null || value === undefined) {
|
|
1349
|
+
return '';
|
|
1350
|
+
}
|
|
1351
|
+
// Convertir a número
|
|
1255
1352
|
const num = Number(value);
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1353
|
+
// Si no es un número válido, retornar el valor original como string
|
|
1354
|
+
if (isNaN(num)) {
|
|
1355
|
+
return String(value);
|
|
1356
|
+
}
|
|
1357
|
+
// Si es un número entero y no se piden decimales, mostrar solo enteros
|
|
1358
|
+
if (num % 1 === 0 && !showDecimals) {
|
|
1359
|
+
// Formatear con separadores de miles usando coma
|
|
1360
|
+
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
1361
|
+
}
|
|
1362
|
+
// Para números con decimales, usar formato personalizado
|
|
1363
|
+
const parts = num.toFixed(2).split('.');
|
|
1364
|
+
const integerPart = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
1365
|
+
const decimalPart = parts[1];
|
|
1366
|
+
return `${integerPart}.${decimalPart}`;
|
|
1367
|
+
}
|
|
1368
|
+
/**
|
|
1369
|
+
* Verifica si estamos en modo desarrollo
|
|
1370
|
+
*/
|
|
1371
|
+
isDevelopmentMode() {
|
|
1372
|
+
return typeof window !== 'undefined' && window.ngDevMode !== false;
|
|
1259
1373
|
}
|
|
1260
1374
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: AppMessageErrorComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
|
1261
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: AppMessageErrorComponent, isStandalone: true, selector: "
|
|
1375
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: AppMessageErrorComponent, isStandalone: true, selector: "dsx-message-error", inputs: { control: "control", form: "form", debugMode: "debugMode" }, ngImport: i0, template: "<div class=\"dsx-error-slot\" [class.is-visible]=\"isControlErrorVisible()\">\r\n <div class=\"dsx-error-message\">\r\n <div class=\"dsx-error-message-content\">\r\n <icon-dsx name=\"warning\"></icon-dsx>\r\n\r\n <!-- Usamos control.errors en lugar de control?.errors -->\r\n @if (control && control.errors && control.errors[\"required\"]) {\r\n El campo <strong>es requerido.</strong>\r\n } @else if (control && control.errors && control.errors[\"invalidNIT\"]) {\r\n <strong>{{ getErrorMessage(\"invalidNIT\") }}</strong>\r\n } @else if (control && control.errors && control.errors[\"invalidCUI\"]) {\r\n <strong>{{ getErrorMessage(\"invalidCUI\") }}</strong>\r\n } @else if (\r\n control && control.errors && control.errors[\"invalidDateRange\"]\r\n ) {\r\n <strong>{{ getErrorMessage(\"invalidDateRange\") }}</strong>\r\n } @else if (control && control.errors && control.errors[\"dateNotRange\"]) {\r\n <strong>{{ getErrorMessage(\"dateNotRange\") }}</strong>\r\n } @else if (control && control.errors && control.errors[\"invalidDate\"]) {\r\n <strong>{{ getErrorMessage(\"invalidDate\") }}</strong>\r\n } @else if (control && control.errors && control.errors[\"minimumAge\"]) {\r\n <strong>{{ getErrorMessage(\"minimumAge\") }}</strong>\r\n } @else if (control && control.errors && control.errors[\"minlength\"]) {\r\n Debe tener al menos\r\n <strong>{{\r\n formatNumber(getErrorValue(\"minlength\", \"requiredLength\"), false)\r\n }}</strong>\r\n caracteres.\r\n } @else if (control && control.errors && control.errors[\"maxlength\"]) {\r\n Debe tener como m\u00E1ximo\r\n <strong>{{\r\n formatNumber(getErrorValue(\"maxlength\", \"requiredLength\"), false)\r\n }}</strong>\r\n caracteres.\r\n } @else if (control && control.errors && control.errors[\"min\"]) {\r\n El valor m\u00EDnimo permitido es\r\n <strong>{{ formatNumber(getErrorValue(\"min\", \"min\"), true) }}</strong>\r\n } @else if (control && control.errors && control.errors[\"max\"]) {\r\n El valor m\u00E1ximo permitido es\r\n <strong>{{ formatNumber(getErrorValue(\"max\", \"max\"), true) }}</strong>\r\n } @else if (control && control.errors && control.errors[\"email\"]) {\r\n Debe ser una direcci\u00F3n de correo v\u00E1lida.\r\n } @else if (control && control.errors && control.errors[\"pattern\"]) {\r\n El campo no tiene el formato requerido.\r\n } @else if (\r\n control && control.errors && control.errors[\"alreadyValueExists\"]\r\n ) {\r\n <strong>{{ getErrorMessage(\"alreadyValueExists\") }}</strong>\r\n } @else if (\r\n control && control.errors && control.errors[\"invalidTemplateVariables\"]\r\n ) {\r\n <div class=\"dsx-template-error\">\r\n <strong>{{ getErrorMessage(\"invalidTemplateVariables\") }}</strong>\r\n @if (getTemplateErrorDetails(\"invalidTemplateVariables\").length) {\r\n <span class=\"dsx-template-error-detail\">\r\n {{ getFirstTemplateErrorDetail(\"invalidTemplateVariables\") }}\r\n </span>\r\n }\r\n </div>\r\n } @else if (\r\n control && control.errors && control.errors[\"invalidTemplateStructure\"]\r\n ) {\r\n <div class=\"dsx-template-error\">\r\n <strong>{{ getErrorMessage(\"invalidTemplateStructure\") }}</strong>\r\n @if (getTemplateErrorDetails(\"invalidTemplateStructure\").length) {\r\n <span class=\"dsx-template-error-detail\">\r\n {{ getFirstTemplateErrorDetail(\"invalidTemplateStructure\") }}\r\n </span>\r\n }\r\n </div>\r\n } @else if (\r\n control && control.errors && control.errors[\"similitudDetectada\"]\r\n ) {\r\n <strong>{{ getSimilitudMessage() }}</strong>\r\n } @else {\r\n Existe un error a\u00FAn no identificado.\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Mensaje para formulario en general -->\r\n@if (form && form.invalid && form.dirty) {\r\n <div class=\"mt-2 mb-2\">\r\n @if (form.errors && form.errors[\"atLeastOneRequired\"]) {\r\n <p-tag severity=\"danger\" [rounded]=\"true\">\r\n {{ getFormError(\"atLeastOneRequired\") }}\r\n </p-tag>\r\n }\r\n </div>\r\n}\r\n", styles: [".dsx-error-slot{display:block;max-height:0;overflow:hidden;opacity:0;transform:translateY(-4px) scale(.98);transition:max-height .3s cubic-bezier(.4,0,.2,1),opacity .25s cubic-bezier(.4,0,.2,1),transform .25s cubic-bezier(.4,0,.2,1),margin .25s cubic-bezier(.4,0,.2,1)}.dsx-error-slot.is-visible{max-height:60px;opacity:1;transform:translateY(0) scale(1)}.dsx-error-message{display:block;width:100%}.dsx-error-message-content{display:flex;align-items:center;gap:.4rem;width:100%;box-sizing:border-box;padding:.25rem .6rem;font-size:.82rem;background:var(--dsx-error-bg, #fff2f0)!important;color:var(--dsx-error-color, #b42318)!important;border-left:3px solid var(--dsx-error-color, #b42318)!important;border-radius:.3rem;box-shadow:0 1px 2px #0000000f;line-height:1.3;animation:errorSlideIn .25s cubic-bezier(.4,0,.2,1)}.dsx-error-icon{flex:0 0 auto;line-height:1;display:inline-flex;align-items:center;justify-content:center}.dsx-error-icon icon-dsx{transform:scale(.85);transition:transform .2s ease}.dsx-error-slot.is-visible .dsx-error-icon icon-dsx{transform:scale(1)}.dsx-error-message-content icon-dsx,.dsx-error-message-content icon-dsx svg,.dsx-error-message-content icon-dsx svg path{color:var(--dsx-error-color, #ff5a4e)!important;fill:var(--dsx-error-color, #e45036)!important}@keyframes errorSlideIn{0%{opacity:0;transform:translateY(-6px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes errorPulse{0%{box-shadow:0 1px 2px #0000000f}50%{box-shadow:0 2px 8px #b4231826}to{box-shadow:0 1px 2px #0000000f}}.dsx-error-slot.is-visible .dsx-error-message-content{animation:errorSlideIn .25s cubic-bezier(.4,0,.2,1),errorPulse .4s ease .15s}:host-context(.p-floatlabel){position:absolute;top:100%;left:0;width:100%;z-index:10;pointer-events:none}:host-context(.p-floatlabel) .dsx-error-slot.is-visible{margin-top:.08rem}:host-context(.p-floatlabel) .dsx-error-message-content{padding:.2rem .6rem .2rem .4rem}:host-context(:not(.p-floatlabel)){display:block;width:100%}:host-context(:not(.p-floatlabel)) .dsx-error-slot.is-visible{margin-top:.15rem;margin-bottom:0}:host-context(:not(.p-floatlabel)) .dsx-error-message-content{padding:.2rem .6rem}@media(max-width:640px){.dsx-error-message-content{padding:.15rem .5rem;font-size:.75rem;gap:.3rem}.dsx-error-icon icon-dsx{transform:scale(.8)}.dsx-error-slot{transition:max-height .25s cubic-bezier(.4,0,.2,1),opacity .2s cubic-bezier(.4,0,.2,1),transform .2s cubic-bezier(.4,0,.2,1)}@keyframes errorSlideIn{0%{opacity:0;transform:translateY(-4px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}:host-context(.p-floatlabel) .dsx-error-slot.is-visible{margin-top:.05rem}:host-context(:not(.p-floatlabel)) .dsx-error-slot.is-visible{margin-top:.1rem}}@media(prefers-color-scheme:dark){.dsx-error-message-content{background:#2d1a1a;border-left-color:#ef4444;color:#fca5a5}.dsx-error-message-content icon-dsx,.dsx-error-message-content icon-dsx svg,.dsx-error-message-content icon-dsx svg path{color:#ef4444!important;fill:#ef4444!important}@keyframes errorPulse{0%{box-shadow:0 1px 2px #0000004d}50%{box-shadow:0 2px 8px #ef444433}to{box-shadow:0 1px 2px #0000004d}}}\n"], dependencies: [{ kind: "ngmodule", type: TagModule }, { kind: "component", type: i1$2.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "component", type: IconDsxComponent, selector: "icon-dsx", inputs: ["name", "style", "debug"] }] });
|
|
1262
1376
|
}
|
|
1263
1377
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: AppMessageErrorComponent, decorators: [{
|
|
1264
1378
|
type: Component,
|
|
1265
|
-
args: [{ selector: '
|
|
1379
|
+
args: [{ selector: 'dsx-message-error', standalone: true, imports: [TagModule, IconDsxComponent], template: "<div class=\"dsx-error-slot\" [class.is-visible]=\"isControlErrorVisible()\">\r\n <div class=\"dsx-error-message\">\r\n <div class=\"dsx-error-message-content\">\r\n <icon-dsx name=\"warning\"></icon-dsx>\r\n\r\n <!-- Usamos control.errors en lugar de control?.errors -->\r\n @if (control && control.errors && control.errors[\"required\"]) {\r\n El campo <strong>es requerido.</strong>\r\n } @else if (control && control.errors && control.errors[\"invalidNIT\"]) {\r\n <strong>{{ getErrorMessage(\"invalidNIT\") }}</strong>\r\n } @else if (control && control.errors && control.errors[\"invalidCUI\"]) {\r\n <strong>{{ getErrorMessage(\"invalidCUI\") }}</strong>\r\n } @else if (\r\n control && control.errors && control.errors[\"invalidDateRange\"]\r\n ) {\r\n <strong>{{ getErrorMessage(\"invalidDateRange\") }}</strong>\r\n } @else if (control && control.errors && control.errors[\"dateNotRange\"]) {\r\n <strong>{{ getErrorMessage(\"dateNotRange\") }}</strong>\r\n } @else if (control && control.errors && control.errors[\"invalidDate\"]) {\r\n <strong>{{ getErrorMessage(\"invalidDate\") }}</strong>\r\n } @else if (control && control.errors && control.errors[\"minimumAge\"]) {\r\n <strong>{{ getErrorMessage(\"minimumAge\") }}</strong>\r\n } @else if (control && control.errors && control.errors[\"minlength\"]) {\r\n Debe tener al menos\r\n <strong>{{\r\n formatNumber(getErrorValue(\"minlength\", \"requiredLength\"), false)\r\n }}</strong>\r\n caracteres.\r\n } @else if (control && control.errors && control.errors[\"maxlength\"]) {\r\n Debe tener como m\u00E1ximo\r\n <strong>{{\r\n formatNumber(getErrorValue(\"maxlength\", \"requiredLength\"), false)\r\n }}</strong>\r\n caracteres.\r\n } @else if (control && control.errors && control.errors[\"min\"]) {\r\n El valor m\u00EDnimo permitido es\r\n <strong>{{ formatNumber(getErrorValue(\"min\", \"min\"), true) }}</strong>\r\n } @else if (control && control.errors && control.errors[\"max\"]) {\r\n El valor m\u00E1ximo permitido es\r\n <strong>{{ formatNumber(getErrorValue(\"max\", \"max\"), true) }}</strong>\r\n } @else if (control && control.errors && control.errors[\"email\"]) {\r\n Debe ser una direcci\u00F3n de correo v\u00E1lida.\r\n } @else if (control && control.errors && control.errors[\"pattern\"]) {\r\n El campo no tiene el formato requerido.\r\n } @else if (\r\n control && control.errors && control.errors[\"alreadyValueExists\"]\r\n ) {\r\n <strong>{{ getErrorMessage(\"alreadyValueExists\") }}</strong>\r\n } @else if (\r\n control && control.errors && control.errors[\"invalidTemplateVariables\"]\r\n ) {\r\n <div class=\"dsx-template-error\">\r\n <strong>{{ getErrorMessage(\"invalidTemplateVariables\") }}</strong>\r\n @if (getTemplateErrorDetails(\"invalidTemplateVariables\").length) {\r\n <span class=\"dsx-template-error-detail\">\r\n {{ getFirstTemplateErrorDetail(\"invalidTemplateVariables\") }}\r\n </span>\r\n }\r\n </div>\r\n } @else if (\r\n control && control.errors && control.errors[\"invalidTemplateStructure\"]\r\n ) {\r\n <div class=\"dsx-template-error\">\r\n <strong>{{ getErrorMessage(\"invalidTemplateStructure\") }}</strong>\r\n @if (getTemplateErrorDetails(\"invalidTemplateStructure\").length) {\r\n <span class=\"dsx-template-error-detail\">\r\n {{ getFirstTemplateErrorDetail(\"invalidTemplateStructure\") }}\r\n </span>\r\n }\r\n </div>\r\n } @else if (\r\n control && control.errors && control.errors[\"similitudDetectada\"]\r\n ) {\r\n <strong>{{ getSimilitudMessage() }}</strong>\r\n } @else {\r\n Existe un error a\u00FAn no identificado.\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Mensaje para formulario en general -->\r\n@if (form && form.invalid && form.dirty) {\r\n <div class=\"mt-2 mb-2\">\r\n @if (form.errors && form.errors[\"atLeastOneRequired\"]) {\r\n <p-tag severity=\"danger\" [rounded]=\"true\">\r\n {{ getFormError(\"atLeastOneRequired\") }}\r\n </p-tag>\r\n }\r\n </div>\r\n}\r\n", styles: [".dsx-error-slot{display:block;max-height:0;overflow:hidden;opacity:0;transform:translateY(-4px) scale(.98);transition:max-height .3s cubic-bezier(.4,0,.2,1),opacity .25s cubic-bezier(.4,0,.2,1),transform .25s cubic-bezier(.4,0,.2,1),margin .25s cubic-bezier(.4,0,.2,1)}.dsx-error-slot.is-visible{max-height:60px;opacity:1;transform:translateY(0) scale(1)}.dsx-error-message{display:block;width:100%}.dsx-error-message-content{display:flex;align-items:center;gap:.4rem;width:100%;box-sizing:border-box;padding:.25rem .6rem;font-size:.82rem;background:var(--dsx-error-bg, #fff2f0)!important;color:var(--dsx-error-color, #b42318)!important;border-left:3px solid var(--dsx-error-color, #b42318)!important;border-radius:.3rem;box-shadow:0 1px 2px #0000000f;line-height:1.3;animation:errorSlideIn .25s cubic-bezier(.4,0,.2,1)}.dsx-error-icon{flex:0 0 auto;line-height:1;display:inline-flex;align-items:center;justify-content:center}.dsx-error-icon icon-dsx{transform:scale(.85);transition:transform .2s ease}.dsx-error-slot.is-visible .dsx-error-icon icon-dsx{transform:scale(1)}.dsx-error-message-content icon-dsx,.dsx-error-message-content icon-dsx svg,.dsx-error-message-content icon-dsx svg path{color:var(--dsx-error-color, #ff5a4e)!important;fill:var(--dsx-error-color, #e45036)!important}@keyframes errorSlideIn{0%{opacity:0;transform:translateY(-6px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes errorPulse{0%{box-shadow:0 1px 2px #0000000f}50%{box-shadow:0 2px 8px #b4231826}to{box-shadow:0 1px 2px #0000000f}}.dsx-error-slot.is-visible .dsx-error-message-content{animation:errorSlideIn .25s cubic-bezier(.4,0,.2,1),errorPulse .4s ease .15s}:host-context(.p-floatlabel){position:absolute;top:100%;left:0;width:100%;z-index:10;pointer-events:none}:host-context(.p-floatlabel) .dsx-error-slot.is-visible{margin-top:.08rem}:host-context(.p-floatlabel) .dsx-error-message-content{padding:.2rem .6rem .2rem .4rem}:host-context(:not(.p-floatlabel)){display:block;width:100%}:host-context(:not(.p-floatlabel)) .dsx-error-slot.is-visible{margin-top:.15rem;margin-bottom:0}:host-context(:not(.p-floatlabel)) .dsx-error-message-content{padding:.2rem .6rem}@media(max-width:640px){.dsx-error-message-content{padding:.15rem .5rem;font-size:.75rem;gap:.3rem}.dsx-error-icon icon-dsx{transform:scale(.8)}.dsx-error-slot{transition:max-height .25s cubic-bezier(.4,0,.2,1),opacity .2s cubic-bezier(.4,0,.2,1),transform .2s cubic-bezier(.4,0,.2,1)}@keyframes errorSlideIn{0%{opacity:0;transform:translateY(-4px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}:host-context(.p-floatlabel) .dsx-error-slot.is-visible{margin-top:.05rem}:host-context(:not(.p-floatlabel)) .dsx-error-slot.is-visible{margin-top:.1rem}}@media(prefers-color-scheme:dark){.dsx-error-message-content{background:#2d1a1a;border-left-color:#ef4444;color:#fca5a5}.dsx-error-message-content icon-dsx,.dsx-error-message-content icon-dsx svg,.dsx-error-message-content icon-dsx svg path{color:#ef4444!important;fill:#ef4444!important}@keyframes errorPulse{0%{box-shadow:0 1px 2px #0000004d}50%{box-shadow:0 2px 8px #ef444433}to{box-shadow:0 1px 2px #0000004d}}}\n"] }]
|
|
1266
1380
|
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { control: [{
|
|
1267
1381
|
type: Input
|
|
1268
1382
|
}], form: [{
|
|
@@ -2671,11 +2785,18 @@ class UtilityAddService {
|
|
|
2671
2785
|
const resolvedOptions = Array.isArray(groupValidatorsOrOptions)
|
|
2672
2786
|
? options
|
|
2673
2787
|
: (groupValidatorsOrOptions ?? options);
|
|
2788
|
+
// IMPORTANTE: Cambiamos el tipado a AbstractControl para permitir meter FormArrays o FormGroups
|
|
2674
2789
|
const formGroup = {};
|
|
2675
|
-
// Crear controles de formulario individuales
|
|
2790
|
+
// Crear controles de formulario individuales o inyectar estructuras abstractas
|
|
2676
2791
|
for (const key in config) {
|
|
2677
2792
|
if (Object.prototype.hasOwnProperty.call(config, key)) {
|
|
2678
2793
|
const fieldConfig = config[key];
|
|
2794
|
+
// ¡EL CAMBIO MÁGICO!: Si ya pasaste un FormArray o FormGroup pre-construido, lo asignamos directo
|
|
2795
|
+
if (fieldConfig instanceof AbstractControl) {
|
|
2796
|
+
formGroup[key] = fieldConfig;
|
|
2797
|
+
continue; // Saltamos a la siguiente iteración
|
|
2798
|
+
}
|
|
2799
|
+
// Tu lógica intacta original para los FormControl estándar
|
|
2679
2800
|
const { value, validators = [], asyncValidators = [], } = fieldConfig;
|
|
2680
2801
|
const hasAssignedDisabled = Object.prototype.hasOwnProperty.call(fieldConfig, 'disabled');
|
|
2681
2802
|
const disabled = hasAssignedDisabled
|
|
@@ -4210,6 +4331,8 @@ class DsxButtonComponent {
|
|
|
4210
4331
|
renderCount = 0;
|
|
4211
4332
|
_paramService = inject((ParameterValuesService));
|
|
4212
4333
|
_router = inject(Router);
|
|
4334
|
+
// Agrega un input para el tamaño
|
|
4335
|
+
size = input(undefined, ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
4213
4336
|
_environment = inject(ENVIRONMENT, {
|
|
4214
4337
|
optional: true,
|
|
4215
4338
|
});
|
|
@@ -4395,8 +4518,18 @@ class DsxButtonComponent {
|
|
|
4395
4518
|
get buttonLabel() {
|
|
4396
4519
|
return this.iconOnly() ? undefined : this.label;
|
|
4397
4520
|
}
|
|
4521
|
+
// Y modifica el getter buttonSize
|
|
4398
4522
|
get buttonSize() {
|
|
4399
|
-
|
|
4523
|
+
// Si el usuario especificó un tamaño, úsalo
|
|
4524
|
+
if (this.size()) {
|
|
4525
|
+
return this.size();
|
|
4526
|
+
}
|
|
4527
|
+
// Si es compacto, siempre small
|
|
4528
|
+
if (this.isCompactIconButton) {
|
|
4529
|
+
return 'small';
|
|
4530
|
+
}
|
|
4531
|
+
// Por defecto, small para todos los botones
|
|
4532
|
+
return 'small';
|
|
4400
4533
|
}
|
|
4401
4534
|
get buttonStyleClass() {
|
|
4402
4535
|
return this.isCompactIconButton ? 'dsx-button-compact' : undefined;
|
|
@@ -4638,12 +4771,12 @@ class DsxButtonComponent {
|
|
|
4638
4771
|
console.timeEnd(`[dsx-button:${this.type()}] ${label}`);
|
|
4639
4772
|
}
|
|
4640
4773
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4641
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: DsxButtonComponent, isStandalone: true, selector: "dsx-button", inputs: { debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, routerLink: { classPropertyName: "routerLink", publicName: "routerLink", isSignal: true, isRequired: false, transformFunction: null }, routerPath: { classPropertyName: "routerPath", publicName: "routerPath", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, iconOnly: { classPropertyName: "iconOnly", publicName: "iconOnly", isSignal: true, isRequired: false, transformFunction: null }, iconOnlyWidth: { classPropertyName: "iconOnlyWidth", publicName: "iconOnlyWidth", isSignal: true, isRequired: false, transformFunction: null }, raised: { classPropertyName: "raised", publicName: "raised", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, parameterName: { classPropertyName: "parameterName", publicName: "parameterName", isSignal: true, isRequired: false, transformFunction: null }, parameterExpectedValue: { classPropertyName: "parameterExpectedValue", publicName: "parameterExpectedValue", isSignal: true, isRequired: false, transformFunction: null }, parameterIndex: { classPropertyName: "parameterIndex", publicName: "parameterIndex", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, requireIdInput: { classPropertyName: "requireIdInput", publicName: "requireIdInput", isSignal: true, isRequired: false, transformFunction: null }, requiresIdGreaterThanZero: { classPropertyName: "requiresIdGreaterThanZero", publicName: "requiresIdGreaterThanZero", isSignal: true, isRequired: false, transformFunction: null }, labelOverride: { classPropertyName: "labelOverride", publicName: "labelOverride", isSignal: true, isRequired: false, transformFunction: null }, tooltipOverride: { classPropertyName: "tooltipOverride", publicName: "tooltipOverride", isSignal: true, isRequired: false, transformFunction: null }, iconOverride: { classPropertyName: "iconOverride", publicName: "iconOverride", isSignal: true, isRequired: false, transformFunction: null }, primeIconOverride: { classPropertyName: "primeIconOverride", publicName: "primeIconOverride", isSignal: true, isRequired: false, transformFunction: null }, colorOverride: { classPropertyName: "colorOverride", publicName: "colorOverride", isSignal: true, isRequired: false, transformFunction: null }, outlinedOverride: { classPropertyName: "outlinedOverride", publicName: "outlinedOverride", isSignal: true, isRequired: false, transformFunction: null }, showValidateButtonOverride: { classPropertyName: "showValidateButtonOverride", publicName: "showValidateButtonOverride", isSignal: true, isRequired: false, transformFunction: null }, showRestoreButtonOverride: { classPropertyName: "showRestoreButtonOverride", publicName: "showRestoreButtonOverride", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, host: { properties: { "class.dsx-button-compact-host": "this.compactHostClass" } }, ngImport: i0, template: "<!--Bot\u00F3n con las configuraciones din\u00E1micas para CRUD -->\r\n@if (visible()) {\r\n<p-button\r\n [label]=\"buttonLabel\"\r\n [style]=\"buttonStyleComputed()\"\r\n [styleClass]=\"buttonStyleClass\"\r\n [pTooltip]=\"tooltip()\"\r\n [tooltipDisabled]=\"disabled()\"\r\n tooltipPosition=\"top\"\r\n [rounded]=\"rounded()\"\r\n [text]=\"isCompactIconButton\"\r\n [size]=\"buttonSize\"\r\n severity=\"secondary\"\r\n [disabled]=\"disabled()\"\r\n [icon]=\"iconOnly() ? primeIcon : undefined\"\r\n (click)=\"onButtonClick()\"\r\n>\r\n @if (!iconOnly()) {\r\n <span class=\"material-symbols-outlined dsx-button-icon-small\"\r\n >{{ materialIcon }}</span\r\n >\r\n }\r\n</p-button>\r\n}\r\n", styles: [".dsx-button-icon-small{font-size:1.25rem;vertical-align:middle}:host{display:inline-flex;margin-bottom:.25rem}:host.dsx-button-compact-host{margin-bottom:0}:host ::ng-deep .p-button
|
|
4774
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: DsxButtonComponent, isStandalone: true, selector: "dsx-button", inputs: { debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, routerLink: { classPropertyName: "routerLink", publicName: "routerLink", isSignal: true, isRequired: false, transformFunction: null }, routerPath: { classPropertyName: "routerPath", publicName: "routerPath", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, iconOnly: { classPropertyName: "iconOnly", publicName: "iconOnly", isSignal: true, isRequired: false, transformFunction: null }, iconOnlyWidth: { classPropertyName: "iconOnlyWidth", publicName: "iconOnlyWidth", isSignal: true, isRequired: false, transformFunction: null }, raised: { classPropertyName: "raised", publicName: "raised", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, parameterName: { classPropertyName: "parameterName", publicName: "parameterName", isSignal: true, isRequired: false, transformFunction: null }, parameterExpectedValue: { classPropertyName: "parameterExpectedValue", publicName: "parameterExpectedValue", isSignal: true, isRequired: false, transformFunction: null }, parameterIndex: { classPropertyName: "parameterIndex", publicName: "parameterIndex", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, requireIdInput: { classPropertyName: "requireIdInput", publicName: "requireIdInput", isSignal: true, isRequired: false, transformFunction: null }, requiresIdGreaterThanZero: { classPropertyName: "requiresIdGreaterThanZero", publicName: "requiresIdGreaterThanZero", isSignal: true, isRequired: false, transformFunction: null }, labelOverride: { classPropertyName: "labelOverride", publicName: "labelOverride", isSignal: true, isRequired: false, transformFunction: null }, tooltipOverride: { classPropertyName: "tooltipOverride", publicName: "tooltipOverride", isSignal: true, isRequired: false, transformFunction: null }, iconOverride: { classPropertyName: "iconOverride", publicName: "iconOverride", isSignal: true, isRequired: false, transformFunction: null }, primeIconOverride: { classPropertyName: "primeIconOverride", publicName: "primeIconOverride", isSignal: true, isRequired: false, transformFunction: null }, colorOverride: { classPropertyName: "colorOverride", publicName: "colorOverride", isSignal: true, isRequired: false, transformFunction: null }, outlinedOverride: { classPropertyName: "outlinedOverride", publicName: "outlinedOverride", isSignal: true, isRequired: false, transformFunction: null }, showValidateButtonOverride: { classPropertyName: "showValidateButtonOverride", publicName: "showValidateButtonOverride", isSignal: true, isRequired: false, transformFunction: null }, showRestoreButtonOverride: { classPropertyName: "showRestoreButtonOverride", publicName: "showRestoreButtonOverride", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, host: { properties: { "class.dsx-button-compact-host": "this.compactHostClass" } }, ngImport: i0, template: "<!--Bot\u00F3n con las configuraciones din\u00E1micas para CRUD -->\r\n@if (visible()) {\r\n<p-button\r\n [label]=\"buttonLabel\"\r\n [style]=\"buttonStyleComputed()\"\r\n [styleClass]=\"buttonStyleClass\"\r\n [pTooltip]=\"tooltip()\"\r\n [tooltipDisabled]=\"disabled()\"\r\n tooltipPosition=\"top\"\r\n [rounded]=\"rounded()\"\r\n [text]=\"isCompactIconButton\"\r\n [size]=\"buttonSize\"\r\n severity=\"secondary\"\r\n [disabled]=\"disabled()\"\r\n [icon]=\"iconOnly() ? primeIcon : undefined\"\r\n (click)=\"onButtonClick()\"\r\n>\r\n @if (!iconOnly()) {\r\n <span class=\"material-symbols-outlined dsx-button-icon-small\"\r\n >{{ materialIcon }}</span\r\n >\r\n }\r\n</p-button>\r\n}\r\n", styles: [".dsx-button-icon-small{font-size:1.25rem;vertical-align:middle}:host{display:inline-flex;margin-bottom:.25rem}:host.dsx-button-compact-host{margin-bottom:0}:host ::ng-deep .p-button.dsx-button-compact{min-height:2rem;padding-block:.2rem}:host ::ng-deep .p-button .material-symbols-outlined.p-button-icon{line-height:1;vertical-align:middle}:host ::ng-deep .p-button.dsx-button-compact .p-button-icon{margin:0;font-size:1.2rem;line-height:1}:host ::ng-deep .p-button.dsx-button-compact .material-symbols-outlined.p-button-icon{font-variation-settings:\"FILL\" 1,\"wght\" 500,\"GRAD\" 0,\"opsz\" 24}:host ::ng-deep .p-button:disabled,:host ::ng-deep .p-button.p-disabled{cursor:not-allowed!important;opacity:.45!important;filter:grayscale(.2) saturate(.75)}:host ::ng-deep .p-button:disabled *,:host ::ng-deep .p-button.p-disabled *{cursor:not-allowed!important}.p-button.dsx-button-outlined-neutral,.p-button.dsx-button-outlined-info{background:#f5f7fa!important;border:1.5px solid #0066cc!important;color:#06c!important}.p-button.dsx-button-outlined-neutral:disabled,.p-button.dsx-button-outlined-info:disabled{background:#f5f7fa!important;border:1.5px solid #b0bec5!important;color:#b0bec5!important}\n"], dependencies: [{ kind: "component", type: Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1$3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }] });
|
|
4642
4775
|
}
|
|
4643
4776
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxButtonComponent, decorators: [{
|
|
4644
4777
|
type: Component,
|
|
4645
|
-
args: [{ selector: 'dsx-button', imports: [Button, TooltipModule], template: "<!--Bot\u00F3n con las configuraciones din\u00E1micas para CRUD -->\r\n@if (visible()) {\r\n<p-button\r\n [label]=\"buttonLabel\"\r\n [style]=\"buttonStyleComputed()\"\r\n [styleClass]=\"buttonStyleClass\"\r\n [pTooltip]=\"tooltip()\"\r\n [tooltipDisabled]=\"disabled()\"\r\n tooltipPosition=\"top\"\r\n [rounded]=\"rounded()\"\r\n [text]=\"isCompactIconButton\"\r\n [size]=\"buttonSize\"\r\n severity=\"secondary\"\r\n [disabled]=\"disabled()\"\r\n [icon]=\"iconOnly() ? primeIcon : undefined\"\r\n (click)=\"onButtonClick()\"\r\n>\r\n @if (!iconOnly()) {\r\n <span class=\"material-symbols-outlined dsx-button-icon-small\"\r\n >{{ materialIcon }}</span\r\n >\r\n }\r\n</p-button>\r\n}\r\n", styles: [".dsx-button-icon-small{font-size:1.25rem;vertical-align:middle}:host{display:inline-flex;margin-bottom:.25rem}:host.dsx-button-compact-host{margin-bottom:0}:host ::ng-deep .p-button
|
|
4646
|
-
}], ctorParameters: () => [], propDecorators: { debug: [{ type: i0.Input, args: [{ isSignal: true, alias: "debug", required: false }] }], compactHostClass: [{
|
|
4778
|
+
args: [{ selector: 'dsx-button', imports: [Button, TooltipModule], template: "<!--Bot\u00F3n con las configuraciones din\u00E1micas para CRUD -->\r\n@if (visible()) {\r\n<p-button\r\n [label]=\"buttonLabel\"\r\n [style]=\"buttonStyleComputed()\"\r\n [styleClass]=\"buttonStyleClass\"\r\n [pTooltip]=\"tooltip()\"\r\n [tooltipDisabled]=\"disabled()\"\r\n tooltipPosition=\"top\"\r\n [rounded]=\"rounded()\"\r\n [text]=\"isCompactIconButton\"\r\n [size]=\"buttonSize\"\r\n severity=\"secondary\"\r\n [disabled]=\"disabled()\"\r\n [icon]=\"iconOnly() ? primeIcon : undefined\"\r\n (click)=\"onButtonClick()\"\r\n>\r\n @if (!iconOnly()) {\r\n <span class=\"material-symbols-outlined dsx-button-icon-small\"\r\n >{{ materialIcon }}</span\r\n >\r\n }\r\n</p-button>\r\n}\r\n", styles: [".dsx-button-icon-small{font-size:1.25rem;vertical-align:middle}:host{display:inline-flex;margin-bottom:.25rem}:host.dsx-button-compact-host{margin-bottom:0}:host ::ng-deep .p-button.dsx-button-compact{min-height:2rem;padding-block:.2rem}:host ::ng-deep .p-button .material-symbols-outlined.p-button-icon{line-height:1;vertical-align:middle}:host ::ng-deep .p-button.dsx-button-compact .p-button-icon{margin:0;font-size:1.2rem;line-height:1}:host ::ng-deep .p-button.dsx-button-compact .material-symbols-outlined.p-button-icon{font-variation-settings:\"FILL\" 1,\"wght\" 500,\"GRAD\" 0,\"opsz\" 24}:host ::ng-deep .p-button:disabled,:host ::ng-deep .p-button.p-disabled{cursor:not-allowed!important;opacity:.45!important;filter:grayscale(.2) saturate(.75)}:host ::ng-deep .p-button:disabled *,:host ::ng-deep .p-button.p-disabled *{cursor:not-allowed!important}.p-button.dsx-button-outlined-neutral,.p-button.dsx-button-outlined-info{background:#f5f7fa!important;border:1.5px solid #0066cc!important;color:#06c!important}.p-button.dsx-button-outlined-neutral:disabled,.p-button.dsx-button-outlined-info:disabled{background:#f5f7fa!important;border:1.5px solid #b0bec5!important;color:#b0bec5!important}\n"] }]
|
|
4779
|
+
}], ctorParameters: () => [], propDecorators: { debug: [{ type: i0.Input, args: [{ isSignal: true, alias: "debug", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], compactHostClass: [{
|
|
4647
4780
|
type: HostBinding,
|
|
4648
4781
|
args: ['class.dsx-button-compact-host']
|
|
4649
4782
|
}], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], routerLink: [{ type: i0.Input, args: [{ isSignal: true, alias: "routerLink", required: false }] }], routerPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "routerPath", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], iconOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnly", required: false }] }], iconOnlyWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnlyWidth", required: false }] }], raised: [{ type: i0.Input, args: [{ isSignal: true, alias: "raised", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], parameterName: [{ type: i0.Input, args: [{ isSignal: true, alias: "parameterName", required: false }] }], parameterExpectedValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "parameterExpectedValue", required: false }] }], parameterIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "parameterIndex", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], requireIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "requireIdInput", required: false }] }], requiresIdGreaterThanZero: [{ type: i0.Input, args: [{ isSignal: true, alias: "requiresIdGreaterThanZero", required: false }] }], labelOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelOverride", required: false }] }], tooltipOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipOverride", required: false }] }], iconOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOverride", required: false }] }], primeIconOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "primeIconOverride", required: false }] }], colorOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorOverride", required: false }] }], outlinedOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "outlinedOverride", required: false }] }], showValidateButtonOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "showValidateButtonOverride", required: false }] }], showRestoreButtonOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRestoreButtonOverride", required: false }] }], action: [{ type: i0.Output, args: ["action"] }] } });
|
|
@@ -4726,7 +4859,7 @@ const ACTION_CONFIG = {
|
|
|
4726
4859
|
details: {
|
|
4727
4860
|
label: 'Detalles',
|
|
4728
4861
|
icon: 'list',
|
|
4729
|
-
primeIcon: '
|
|
4862
|
+
primeIcon: 'fa-solid fa-list-ol',
|
|
4730
4863
|
colorToken: 'details',
|
|
4731
4864
|
tooltip: 'Detalle de registro',
|
|
4732
4865
|
},
|
|
@@ -4771,13 +4904,9 @@ class DsxAutocomplete {
|
|
|
4771
4904
|
// Inputs usando Señales
|
|
4772
4905
|
datasource = input.required(...(ngDevMode ? [{ debugName: "datasource" }] : /* istanbul ignore next */ []));
|
|
4773
4906
|
optionLabel = input.required(...(ngDevMode ? [{ debugName: "optionLabel" }] : /* istanbul ignore next */ []));
|
|
4774
|
-
// Label del input (ej: 'Requisitos')
|
|
4775
4907
|
label = input('Seleccionar', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
4776
|
-
//Delay por defecto
|
|
4777
4908
|
delay = input(100, ...(ngDevMode ? [{ debugName: "delay" }] : /* istanbul ignore next */ []));
|
|
4778
|
-
// OBLIGATORIO para la creación automática: nombre de la propiedad ID (ej: 'requisitoId')
|
|
4779
4909
|
idKey = input.required(...(ngDevMode ? [{ debugName: "idKey" }] : /* istanbul ignore next */ []));
|
|
4780
|
-
// Opcional para PrimeNG (por defecto toma el valor de idKey para identificar duplicados)
|
|
4781
4910
|
dataKey = input('', ...(ngDevMode ? [{ debugName: "dataKey" }] : /* istanbul ignore next */ []));
|
|
4782
4911
|
permitirCrear = input(false, ...(ngDevMode ? [{ debugName: "permitirCrear" }] : /* istanbul ignore next */ []));
|
|
4783
4912
|
debug = input(false, ...(ngDevMode ? [{ debugName: "debug" }] : /* istanbul ignore next */ []));
|
|
@@ -4788,20 +4917,30 @@ class DsxAutocomplete {
|
|
|
4788
4917
|
onChange = () => { };
|
|
4789
4918
|
onTouched = () => { };
|
|
4790
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
|
+
}
|
|
4791
4931
|
searchRequisitos(event) {
|
|
4792
4932
|
const inicio = performance.now();
|
|
4793
4933
|
const label = this.optionLabel();
|
|
4794
|
-
// FLUJO A:
|
|
4934
|
+
// FLUJO A: Dropdown (sin texto)
|
|
4795
4935
|
if (!event.query || event.query.trim() === '') {
|
|
4796
|
-
// Cargamos TODO el universo de datos para que el usuario pueda navegar libremente
|
|
4797
4936
|
const todoElUniverso = this.datasource();
|
|
4798
4937
|
this.dataFiltrada.set(todoElUniverso);
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
}
|
|
4938
|
+
this.logDebug('Modo dropdown activo', {
|
|
4939
|
+
registros: todoElUniverso.length,
|
|
4940
|
+
});
|
|
4802
4941
|
return;
|
|
4803
4942
|
}
|
|
4804
|
-
// FLUJO B:
|
|
4943
|
+
// FLUJO B: Búsqueda
|
|
4805
4944
|
const palabrasBuscadas = event.query
|
|
4806
4945
|
.toLowerCase()
|
|
4807
4946
|
.trim()
|
|
@@ -4812,25 +4951,26 @@ class DsxAutocomplete {
|
|
|
4812
4951
|
const textoRegistro = String(item[label] || '').toLowerCase();
|
|
4813
4952
|
return palabrasBuscadas.every((palabra) => textoRegistro.includes(palabra));
|
|
4814
4953
|
})
|
|
4815
|
-
.slice(0, 10);
|
|
4954
|
+
.slice(0, 10);
|
|
4816
4955
|
this.dataFiltrada.set(filtrados);
|
|
4817
|
-
|
|
4818
|
-
console.log(`[DsxAutocomplete] Búsqueda inteligente para "${event.query}" tardó ${(performance.now() - inicio).toFixed(2)}ms. Encontrados:`, filtrados.length);
|
|
4819
|
-
}
|
|
4956
|
+
this.logDebug(`Búsqueda "${event.query}" (${(performance.now() - inicio).toFixed(2)}ms)`, { encontrados: filtrados.length });
|
|
4820
4957
|
}
|
|
4821
4958
|
evaluarYAgregar(event) {
|
|
4822
4959
|
const valorInput = event.target.value?.trim();
|
|
4823
|
-
if (!valorInput)
|
|
4960
|
+
if (!valorInput) {
|
|
4961
|
+
this.dataFiltrada.set([]);
|
|
4824
4962
|
return;
|
|
4963
|
+
}
|
|
4825
4964
|
const sugerencias = this.dataFiltrada();
|
|
4826
4965
|
const actuales = this.value || [];
|
|
4827
|
-
const campoId = this.idKey();
|
|
4966
|
+
const campoId = this.idKey();
|
|
4828
4967
|
if (sugerencias.length > 0) {
|
|
4829
4968
|
const primeraMatch = sugerencias[0];
|
|
4830
|
-
// Comparamos identidades usando el campoId dinámico
|
|
4831
4969
|
const yaExiste = actuales.some((item) => item[campoId] === primeraMatch[campoId]);
|
|
4832
|
-
if (!yaExiste)
|
|
4970
|
+
if (!yaExiste) {
|
|
4833
4971
|
this.actualizarFormulario([...actuales, primeraMatch]);
|
|
4972
|
+
this.logDebug('✅ Elemento agregado');
|
|
4973
|
+
}
|
|
4834
4974
|
}
|
|
4835
4975
|
else if (this.permitirCrear()) {
|
|
4836
4976
|
let nuevo;
|
|
@@ -4838,7 +4978,6 @@ class DsxAutocomplete {
|
|
|
4838
4978
|
nuevo = this.factoryNuevoRegistro()(valorInput);
|
|
4839
4979
|
}
|
|
4840
4980
|
else {
|
|
4841
|
-
// Al estructurar el objeto usando [campoId], garantizamos que viaje con el nombre correcto de tu entidad
|
|
4842
4981
|
nuevo = {
|
|
4843
4982
|
[campoId]: 0,
|
|
4844
4983
|
[this.optionLabel()]: valorInput.toUpperCase(),
|
|
@@ -4846,19 +4985,47 @@ class DsxAutocomplete {
|
|
|
4846
4985
|
};
|
|
4847
4986
|
}
|
|
4848
4987
|
this.actualizarFormulario([...actuales, nuevo]);
|
|
4988
|
+
this.logDebug('🆕 Nuevo elemento creado', valorInput);
|
|
4849
4989
|
}
|
|
4850
4990
|
event.target.value = '';
|
|
4851
4991
|
this.dataFiltrada.set([]);
|
|
4852
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
|
+
}
|
|
4853
5014
|
actualizarFormulario(nuevaLista) {
|
|
4854
5015
|
this.value = nuevaLista;
|
|
4855
5016
|
this.onChange(this.value);
|
|
4856
|
-
|
|
4857
|
-
|
|
5017
|
+
this.logDebug('Formulario actualizado', {
|
|
5018
|
+
total: nuevaLista.length,
|
|
5019
|
+
});
|
|
4858
5020
|
}
|
|
4859
5021
|
// --- ControlValueAccessor ---
|
|
4860
5022
|
writeValue(value) {
|
|
4861
5023
|
this.value = value || [];
|
|
5024
|
+
this.dataFiltrada.set([]);
|
|
5025
|
+
if (this.timeoutLimpieza) {
|
|
5026
|
+
clearTimeout(this.timeoutLimpieza);
|
|
5027
|
+
this.timeoutLimpieza = null;
|
|
5028
|
+
}
|
|
4862
5029
|
}
|
|
4863
5030
|
registerOnChange(fn) {
|
|
4864
5031
|
this.onChange = fn;
|
|
@@ -4876,7 +5043,7 @@ class DsxAutocomplete {
|
|
|
4876
5043
|
useExisting: forwardRef(() => DsxAutocomplete),
|
|
4877
5044
|
multi: true,
|
|
4878
5045
|
},
|
|
4879
|
-
], 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 [disabled]=\"disabled\"\r\n [optionLabel]=\"optionLabel()\"\r\n [dataKey]=\"dataKey() || idKey()\"\r\n (keyup.enter)=\"evaluarYAgregar($event)\"\r\n [delay]=\"delay()\"\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"] }] });
|
|
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"] }] });
|
|
4880
5047
|
}
|
|
4881
5048
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxAutocomplete, decorators: [{
|
|
4882
5049
|
type: Component,
|
|
@@ -4886,13 +5053,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
4886
5053
|
useExisting: forwardRef(() => DsxAutocomplete),
|
|
4887
5054
|
multi: true,
|
|
4888
5055
|
},
|
|
4889
|
-
], 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 [disabled]=\"disabled\"\r\n [optionLabel]=\"optionLabel()\"\r\n [dataKey]=\"dataKey() || idKey()\"\r\n (keyup.enter)=\"evaluarYAgregar($event)\"\r\n [delay]=\"delay()\"\r\n >\r\n </p-autoComplete>\r\n <label>{{ label() }}</label>\r\n</p-floatlabel>\r\n" }]
|
|
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" }]
|
|
4890
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 }] }] } });
|
|
4891
5058
|
|
|
4892
5059
|
class FileComponent {
|
|
4893
5060
|
// Inputs
|
|
4894
5061
|
existingFile = input(null, ...(ngDevMode ? [{ debugName: "existingFile" }] : /* istanbul ignore next */ []));
|
|
4895
5062
|
existingFileName = input(null, ...(ngDevMode ? [{ debugName: "existingFileName" }] : /* istanbul ignore next */ []));
|
|
5063
|
+
overrideFileName = input(null, ...(ngDevMode ? [{ debugName: "overrideFileName" }] : /* istanbul ignore next */ []));
|
|
4896
5064
|
debug = input(false, ...(ngDevMode ? [{ debugName: "debug" }] : /* istanbul ignore next */ []));
|
|
4897
5065
|
required = input(true, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
4898
5066
|
accept = input('.xls,.xlsx', ...(ngDevMode ? [{ debugName: "accept" }] : /* istanbul ignore next */ []));
|
|
@@ -5101,7 +5269,7 @@ class FileComponent {
|
|
|
5101
5269
|
console.log(`[FileComponent] ${method}`, data || '');
|
|
5102
5270
|
}
|
|
5103
5271
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: FileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5104
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: FileComponent, isStandalone: true, selector: "dsx-file-upload", inputs: { existingFile: { classPropertyName: "existingFile", publicName: "existingFile", isSignal: true, isRequired: false, transformFunction: null }, existingFileName: { classPropertyName: "existingFileName", publicName: "existingFileName", isSignal: true, isRequired: false, transformFunction: null }, debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, pTooltipOverride: { classPropertyName: "pTooltipOverride", publicName: "pTooltipOverride", isSignal: true, isRequired: false, transformFunction: null }, tooltipPositionOverride: { classPropertyName: "tooltipPositionOverride", publicName: "tooltipPositionOverride", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, invalidSummary: { classPropertyName: "invalidSummary", publicName: "invalidSummary", isSignal: true, isRequired: false, transformFunction: null }, invalidDetail: { classPropertyName: "invalidDetail", publicName: "invalidDetail", isSignal: true, isRequired: false, transformFunction: null }, invalidSizeSummary: { classPropertyName: "invalidSizeSummary", publicName: "invalidSizeSummary", isSignal: true, isRequired: false, transformFunction: null }, invalidSizeDetail: { classPropertyName: "invalidSizeDetail", publicName: "invalidSizeDetail", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
5272
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: FileComponent, isStandalone: true, selector: "dsx-file-upload", inputs: { existingFile: { classPropertyName: "existingFile", publicName: "existingFile", isSignal: true, isRequired: false, transformFunction: null }, existingFileName: { classPropertyName: "existingFileName", publicName: "existingFileName", isSignal: true, isRequired: false, transformFunction: null }, overrideFileName: { classPropertyName: "overrideFileName", publicName: "overrideFileName", isSignal: true, isRequired: false, transformFunction: null }, debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, pTooltipOverride: { classPropertyName: "pTooltipOverride", publicName: "pTooltipOverride", isSignal: true, isRequired: false, transformFunction: null }, tooltipPositionOverride: { classPropertyName: "tooltipPositionOverride", publicName: "tooltipPositionOverride", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, invalidSummary: { classPropertyName: "invalidSummary", publicName: "invalidSummary", isSignal: true, isRequired: false, transformFunction: null }, invalidDetail: { classPropertyName: "invalidDetail", publicName: "invalidDetail", isSignal: true, isRequired: false, transformFunction: null }, invalidSizeSummary: { classPropertyName: "invalidSizeSummary", publicName: "invalidSizeSummary", isSignal: true, isRequired: false, transformFunction: null }, invalidSizeDetail: { classPropertyName: "invalidSizeDetail", publicName: "invalidSizeDetail", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
5105
5273
|
{
|
|
5106
5274
|
provide: NG_VALUE_ACCESSOR,
|
|
5107
5275
|
useExisting: forwardRef(() => FileComponent),
|
|
@@ -5112,7 +5280,7 @@ class FileComponent {
|
|
|
5112
5280
|
useExisting: forwardRef(() => FileComponent),
|
|
5113
5281
|
multi: true,
|
|
5114
5282
|
},
|
|
5115
|
-
], viewQueries: [{ propertyName: "fileUpload", first: true, predicate: ["fileUpload"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (showExistingFile() && !existingFile()) {\r\n <div class=\"flex items-center gap-2\">\r\n <span class=\"file-name\"
|
|
5283
|
+
], viewQueries: [{ propertyName: "fileUpload", first: true, predicate: ["fileUpload"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (showExistingFile() && !existingFile()) {\r\n <div class=\"flex items-center gap-2\">\r\n <span class=\"file-name\">\r\n \uD83D\uDCC4 {{ overrideFileName() ?? existingFileName() }}\r\n </span>\r\n\r\n <p-button\r\n icon=\"pi pi-cloud-upload\"\r\n [rounded]=\"true\"\r\n severity=\"info\"\r\n (click)=\"startReplace()\"\r\n [disabled]=\"isReplaceButtonDisabled()\"\r\n pTooltip=\"Reemplazar archivo\"\r\n tooltipPosition=\"top\"\r\n />\r\n </div>\r\n} @else {\r\n <div class=\"flex items-center gap-2\">\r\n <p-fileUpload\r\n #fileUpload\r\n mode=\"basic\"\r\n [accept]=\"accept()\"\r\n [maxFileSize]=\"maxFileSize() * 1024 * 1024\"\r\n [invalidFileTypeMessageSummary]=\"invalidSummary()\"\r\n [invalidFileTypeMessageDetail]=\"invalidDetail()\"\r\n [invalidFileSizeMessageSummary]=\"invalidSizeSummary()\"\r\n [invalidFileSizeMessageDetail]=\"invalidSizeDetail()\"\r\n (onSelect)=\"onSelect($event)\"\r\n [disabled]=\"!isFileUploadEnabled()\"\r\n [pTooltip]=\"pTooltipOverride()\"\r\n [tooltipPosition]=\"tooltipPositionOverride()\"\r\n />\r\n\r\n @if (isReplacing() || existingFile()) {\r\n <p-button\r\n icon=\"pi pi-times\"\r\n [rounded]=\"true\"\r\n severity=\"secondary\"\r\n (click)=\"cancelReplace()\"\r\n [disabled]=\"disabled()\"\r\n pTooltip=\"Cancelar reemplazo\"\r\n tooltipPosition=\"top\"\r\n />\r\n }\r\n </div>\r\n}\r\n", styles: [".file-name{display:inline-block;font-size:clamp(.85rem,1vw + .5rem,1.4rem);font-weight:500;color:#2c3e50;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}\n"], dependencies: [{ kind: "component", type: FileUpload, selector: "p-fileupload, p-fileUpload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "uploadStyleClass", "cancelStyleClass", "removeStyleClass", "chooseStyleClass", "chooseButtonProps", "uploadButtonProps", "cancelButtonProps", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler", "onImageError", "onRemoveUploadedFile"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }] });
|
|
5116
5284
|
}
|
|
5117
5285
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: FileComponent, decorators: [{
|
|
5118
5286
|
type: Component,
|
|
@@ -5127,8 +5295,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
5127
5295
|
useExisting: forwardRef(() => FileComponent),
|
|
5128
5296
|
multi: true,
|
|
5129
5297
|
},
|
|
5130
|
-
], template: "@if (showExistingFile() && !existingFile()) {\r\n <div class=\"flex items-center gap-2\">\r\n <span class=\"file-name\"
|
|
5131
|
-
}], ctorParameters: () => [], propDecorators: { existingFile: [{ type: i0.Input, args: [{ isSignal: true, alias: "existingFile", required: false }] }], existingFileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "existingFileName", required: false }] }], debug: [{ type: i0.Input, args: [{ isSignal: true, alias: "debug", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], pTooltipOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "pTooltipOverride", required: false }] }], tooltipPositionOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipPositionOverride", required: false }] }], maxFileSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFileSize", required: false }] }], invalidSummary: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalidSummary", required: false }] }], invalidDetail: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalidDetail", required: false }] }], invalidSizeSummary: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalidSizeSummary", required: false }] }], invalidSizeDetail: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalidSizeDetail", required: false }] }], fileUpload: [{ type: i0.ViewChild, args: ['fileUpload', { isSignal: true }] }] } });
|
|
5298
|
+
], template: "@if (showExistingFile() && !existingFile()) {\r\n <div class=\"flex items-center gap-2\">\r\n <span class=\"file-name\">\r\n \uD83D\uDCC4 {{ overrideFileName() ?? existingFileName() }}\r\n </span>\r\n\r\n <p-button\r\n icon=\"pi pi-cloud-upload\"\r\n [rounded]=\"true\"\r\n severity=\"info\"\r\n (click)=\"startReplace()\"\r\n [disabled]=\"isReplaceButtonDisabled()\"\r\n pTooltip=\"Reemplazar archivo\"\r\n tooltipPosition=\"top\"\r\n />\r\n </div>\r\n} @else {\r\n <div class=\"flex items-center gap-2\">\r\n <p-fileUpload\r\n #fileUpload\r\n mode=\"basic\"\r\n [accept]=\"accept()\"\r\n [maxFileSize]=\"maxFileSize() * 1024 * 1024\"\r\n [invalidFileTypeMessageSummary]=\"invalidSummary()\"\r\n [invalidFileTypeMessageDetail]=\"invalidDetail()\"\r\n [invalidFileSizeMessageSummary]=\"invalidSizeSummary()\"\r\n [invalidFileSizeMessageDetail]=\"invalidSizeDetail()\"\r\n (onSelect)=\"onSelect($event)\"\r\n [disabled]=\"!isFileUploadEnabled()\"\r\n [pTooltip]=\"pTooltipOverride()\"\r\n [tooltipPosition]=\"tooltipPositionOverride()\"\r\n />\r\n\r\n @if (isReplacing() || existingFile()) {\r\n <p-button\r\n icon=\"pi pi-times\"\r\n [rounded]=\"true\"\r\n severity=\"secondary\"\r\n (click)=\"cancelReplace()\"\r\n [disabled]=\"disabled()\"\r\n pTooltip=\"Cancelar reemplazo\"\r\n tooltipPosition=\"top\"\r\n />\r\n }\r\n </div>\r\n}\r\n", styles: [".file-name{display:inline-block;font-size:clamp(.85rem,1vw + .5rem,1.4rem);font-weight:500;color:#2c3e50;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}\n"] }]
|
|
5299
|
+
}], ctorParameters: () => [], propDecorators: { existingFile: [{ type: i0.Input, args: [{ isSignal: true, alias: "existingFile", required: false }] }], existingFileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "existingFileName", required: false }] }], overrideFileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "overrideFileName", required: false }] }], debug: [{ type: i0.Input, args: [{ isSignal: true, alias: "debug", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], pTooltipOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "pTooltipOverride", required: false }] }], tooltipPositionOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipPositionOverride", required: false }] }], maxFileSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFileSize", required: false }] }], invalidSummary: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalidSummary", required: false }] }], invalidDetail: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalidDetail", required: false }] }], invalidSizeSummary: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalidSizeSummary", required: false }] }], invalidSizeDetail: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalidSizeDetail", required: false }] }], fileUpload: [{ type: i0.ViewChild, args: ['fileUpload', { isSignal: true }] }] } });
|
|
5132
5300
|
|
|
5133
5301
|
class JsonHighlightPipe {
|
|
5134
5302
|
/**
|
|
@@ -5302,11 +5470,11 @@ class JsonValuesDebujComponent {
|
|
|
5302
5470
|
}
|
|
5303
5471
|
}
|
|
5304
5472
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JsonValuesDebujComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5305
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JsonValuesDebujComponent, isStandalone: true, selector: "app-json-values-debuj", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (form() && shouldShowVisual) {\r\n <div class=\"custom-container\">\r\n <pre class=\"custom-pre\" [innerHTML]=\"debugValue() | jsonHighlight\"></pre>\r\n </div>\r\n}\r\n", styles: [".custom-container{width:100%;overflow:auto;max-height:700px;background:#1e1e1e;border:1px solid #333;border-radius:8px;box-shadow:0 4px 12px #0000004d;padding:1.25rem;margin-bottom:1.25rem}.custom-pre{margin:0;white-space:pre-wrap;word-break:break-word;word-wrap:break-word;font-family:Segoe UI,Fira Code,JetBrains Mono,Consolas,Monaco,Courier New,monospace;font-size:15px;line-height:1.65;color:#d4d4d4;font-weight:400}.json-key{color:#9cdcfe;font-weight:600;font-size:15px}.json-string{color:#ce9178;font-size:15px}.json-number{color:#b5cea8;font-weight:600;font-size:15px}.json-boolean{color:#569cd6;font-weight:700;font-size:15px}.json-null{color:gray;font-style:italic;font-size:15px}.json-bracket{color:gold;font-weight:700;font-size:16px}.json-colon{color:#d4d4d4;font-weight:500}.json-comma{color:gray;font-size:14px}.json-date-part{color:#4fc1ff;font-weight:600;font-size:15px}.json-date-sep{color:gray}.json-date-time{color:#c586c0;font-size:15px}.custom-container::-webkit-scrollbar{width:12px;height:12px}.custom-container::-webkit-scrollbar-track{background:#252526;border-radius:6px}.custom-container::-webkit-scrollbar-thumb{background:#555;border-radius:6px;transition:background .2s ease}.custom-container::-webkit-scrollbar-thumb:hover{background:#777}.custom-container::-webkit-scrollbar-corner{background:#1e1e1e}.custom-container{font-smooth:antialiased;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.
|
|
5473
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JsonValuesDebujComponent, isStandalone: true, selector: "app-json-values-debuj", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (form() && shouldShowVisual) {\r\n <div class=\"custom-container\">\r\n <pre class=\"custom-pre\" [innerHTML]=\"debugValue() | jsonHighlight\"></pre>\r\n </div>\r\n}\r\n", styles: [".custom-container{width:100%;overflow:auto;max-height:700px;background:#1e1e1e;border:1px solid #333;border-radius:8px;box-shadow:0 4px 12px #0000004d;padding:1.25rem;margin-bottom:1.25rem}.custom-pre{margin:0;white-space:pre-wrap;word-break:break-word;word-wrap:break-word;font-family:Segoe UI,Fira Code,JetBrains Mono,Consolas,Monaco,Courier New,monospace;font-size:15px;line-height:1.65;color:#d4d4d4;font-weight:400}.json-key{color:#9cdcfe;font-weight:600;font-size:15px}.json-string{color:#ce9178;font-size:15px}.json-number{color:#b5cea8;font-weight:600;font-size:15px}.json-boolean{color:#569cd6;font-weight:700;font-size:15px}.json-null{color:gray;font-style:italic;font-size:15px}.json-bracket{color:gold;font-weight:700;font-size:16px}.json-colon{color:#d4d4d4;font-weight:500}.json-comma{color:gray;font-size:14px}.json-date-part{color:#4fc1ff;font-weight:600;font-size:15px}.json-date-sep{color:gray}.json-date-time{color:#c586c0;font-size:15px}.custom-container::-webkit-scrollbar{width:12px;height:12px}.custom-container::-webkit-scrollbar-track{background:#252526;border-radius:6px}.custom-container::-webkit-scrollbar-thumb{background:#555;border-radius:6px;transition:background .2s ease}.custom-container::-webkit-scrollbar-thumb:hover{background:#777}.custom-container::-webkit-scrollbar-corner{background:#1e1e1e}.custom-container{font-smooth:antialiased;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.json-null,.json-undefined{color:#f48771;font-style:italic;opacity:.8}.json-empty{color:gray;font-style:italic}.json-comma+br{margin-bottom:2px}\n"], dependencies: [{ kind: "pipe", type: JsonHighlightPipe, name: "jsonHighlight" }], encapsulation: i0.ViewEncapsulation.None });
|
|
5306
5474
|
}
|
|
5307
5475
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JsonValuesDebujComponent, decorators: [{
|
|
5308
5476
|
type: Component,
|
|
5309
|
-
args: [{ selector: 'app-json-values-debuj', standalone: true, imports: [JsonHighlightPipe], encapsulation: ViewEncapsulation.None, template: "@if (form() && shouldShowVisual) {\r\n <div class=\"custom-container\">\r\n <pre class=\"custom-pre\" [innerHTML]=\"debugValue() | jsonHighlight\"></pre>\r\n </div>\r\n}\r\n", styles: [".custom-container{width:100%;overflow:auto;max-height:700px;background:#1e1e1e;border:1px solid #333;border-radius:8px;box-shadow:0 4px 12px #0000004d;padding:1.25rem;margin-bottom:1.25rem}.custom-pre{margin:0;white-space:pre-wrap;word-break:break-word;word-wrap:break-word;font-family:Segoe UI,Fira Code,JetBrains Mono,Consolas,Monaco,Courier New,monospace;font-size:15px;line-height:1.65;color:#d4d4d4;font-weight:400}.json-key{color:#9cdcfe;font-weight:600;font-size:15px}.json-string{color:#ce9178;font-size:15px}.json-number{color:#b5cea8;font-weight:600;font-size:15px}.json-boolean{color:#569cd6;font-weight:700;font-size:15px}.json-null{color:gray;font-style:italic;font-size:15px}.json-bracket{color:gold;font-weight:700;font-size:16px}.json-colon{color:#d4d4d4;font-weight:500}.json-comma{color:gray;font-size:14px}.json-date-part{color:#4fc1ff;font-weight:600;font-size:15px}.json-date-sep{color:gray}.json-date-time{color:#c586c0;font-size:15px}.custom-container::-webkit-scrollbar{width:12px;height:12px}.custom-container::-webkit-scrollbar-track{background:#252526;border-radius:6px}.custom-container::-webkit-scrollbar-thumb{background:#555;border-radius:6px;transition:background .2s ease}.custom-container::-webkit-scrollbar-thumb:hover{background:#777}.custom-container::-webkit-scrollbar-corner{background:#1e1e1e}.custom-container{font-smooth:antialiased;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.
|
|
5477
|
+
args: [{ selector: 'app-json-values-debuj', standalone: true, imports: [JsonHighlightPipe], encapsulation: ViewEncapsulation.None, template: "@if (form() && shouldShowVisual) {\r\n <div class=\"custom-container\">\r\n <pre class=\"custom-pre\" [innerHTML]=\"debugValue() | jsonHighlight\"></pre>\r\n </div>\r\n}\r\n", styles: [".custom-container{width:100%;overflow:auto;max-height:700px;background:#1e1e1e;border:1px solid #333;border-radius:8px;box-shadow:0 4px 12px #0000004d;padding:1.25rem;margin-bottom:1.25rem}.custom-pre{margin:0;white-space:pre-wrap;word-break:break-word;word-wrap:break-word;font-family:Segoe UI,Fira Code,JetBrains Mono,Consolas,Monaco,Courier New,monospace;font-size:15px;line-height:1.65;color:#d4d4d4;font-weight:400}.json-key{color:#9cdcfe;font-weight:600;font-size:15px}.json-string{color:#ce9178;font-size:15px}.json-number{color:#b5cea8;font-weight:600;font-size:15px}.json-boolean{color:#569cd6;font-weight:700;font-size:15px}.json-null{color:gray;font-style:italic;font-size:15px}.json-bracket{color:gold;font-weight:700;font-size:16px}.json-colon{color:#d4d4d4;font-weight:500}.json-comma{color:gray;font-size:14px}.json-date-part{color:#4fc1ff;font-weight:600;font-size:15px}.json-date-sep{color:gray}.json-date-time{color:#c586c0;font-size:15px}.custom-container::-webkit-scrollbar{width:12px;height:12px}.custom-container::-webkit-scrollbar-track{background:#252526;border-radius:6px}.custom-container::-webkit-scrollbar-thumb{background:#555;border-radius:6px;transition:background .2s ease}.custom-container::-webkit-scrollbar-thumb:hover{background:#777}.custom-container::-webkit-scrollbar-corner{background:#1e1e1e}.custom-container{font-smooth:antialiased;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.json-null,.json-undefined{color:#f48771;font-style:italic;opacity:.8}.json-empty{color:gray;font-style:italic}.json-comma+br{margin-bottom:2px}\n"] }]
|
|
5310
5478
|
}], ctorParameters: () => [], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: false }] }], debug: [{ type: i0.Input, args: [{ isSignal: true, alias: "debug", required: false }] }] } });
|
|
5311
5479
|
|
|
5312
5480
|
class IcoLabel {
|
|
@@ -7712,54 +7880,197 @@ function createInitialCache(cacheKeys) {
|
|
|
7712
7880
|
}
|
|
7713
7881
|
|
|
7714
7882
|
class HeaderDsx {
|
|
7883
|
+
// Inputs
|
|
7715
7884
|
id = input(null, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
7716
7885
|
etiqueta = input.required(...(ngDevMode ? [{ debugName: "etiqueta" }] : /* istanbul ignore next */ []));
|
|
7717
7886
|
defaultPNG = input('icon/folder_001.png', ...(ngDevMode ? [{ debugName: "defaultPNG" }] : /* istanbul ignore next */ []));
|
|
7718
7887
|
defaultGIF = input('gif/file.gif', ...(ngDevMode ? [{ debugName: "defaultGIF" }] : /* istanbul ignore next */ []));
|
|
7719
7888
|
icoPNG = input(null, ...(ngDevMode ? [{ debugName: "icoPNG" }] : /* istanbul ignore next */ []));
|
|
7720
7889
|
icoGIF = input(null, ...(ngDevMode ? [{ debugName: "icoGIF" }] : /* istanbul ignore next */ []));
|
|
7721
|
-
icono = null;
|
|
7722
|
-
textoEncabezado = null;
|
|
7723
7890
|
subTitulo = input(null, ...(ngDevMode ? [{ debugName: "subTitulo" }] : /* istanbul ignore next */ []));
|
|
7891
|
+
debug = input(false, ...(ngDevMode ? [{ debugName: "debug" }] : /* istanbul ignore next */ []));
|
|
7892
|
+
// Signals
|
|
7893
|
+
icono = signal(null, ...(ngDevMode ? [{ debugName: "icono" }] : /* istanbul ignore next */ []));
|
|
7894
|
+
textoEncabezado = signal(null, ...(ngDevMode ? [{ debugName: "textoEncabezado" }] : /* istanbul ignore next */ []));
|
|
7895
|
+
// Métricas de performance públicas
|
|
7896
|
+
performanceMetrics = {
|
|
7897
|
+
renderCount: 0,
|
|
7898
|
+
lastRenderTime: 0,
|
|
7899
|
+
totalRenderTime: 0,
|
|
7900
|
+
averageRenderTime: 0,
|
|
7901
|
+
lastUpdateTimestamp: 0,
|
|
7902
|
+
};
|
|
7903
|
+
// Computed
|
|
7904
|
+
modo = computed(() => {
|
|
7905
|
+
const id = this.id();
|
|
7906
|
+
if (id === null)
|
|
7907
|
+
return 'Lista';
|
|
7908
|
+
if (id === 0)
|
|
7909
|
+
return 'Registro';
|
|
7910
|
+
if (id > 0)
|
|
7911
|
+
return 'Edición';
|
|
7912
|
+
return 'Desconocido';
|
|
7913
|
+
}, ...(ngDevMode ? [{ debugName: "modo" }] : /* istanbul ignore next */ []));
|
|
7914
|
+
// Control de producción
|
|
7915
|
+
isProduction = !isDevMode();
|
|
7916
|
+
constructor() {
|
|
7917
|
+
effect(() => {
|
|
7918
|
+
if (this.debug() && !this.isProduction) {
|
|
7919
|
+
this.logPerformance('Debug mode activado');
|
|
7920
|
+
}
|
|
7921
|
+
});
|
|
7922
|
+
}
|
|
7724
7923
|
ngOnInit() {
|
|
7924
|
+
const startTime = performance.now();
|
|
7725
7925
|
this.definirTexto();
|
|
7726
|
-
|
|
7926
|
+
this.performanceMetrics.lastUpdateTimestamp = Date.now();
|
|
7927
|
+
this.logPerformance('Componente inicializado');
|
|
7928
|
+
const endTime = performance.now();
|
|
7929
|
+
this.logPerformance(`Tiempo de inicialización: ${(endTime - startTime).toFixed(2)}ms`);
|
|
7930
|
+
}
|
|
7931
|
+
ngOnChanges(changes) {
|
|
7932
|
+
const startTime = performance.now();
|
|
7933
|
+
this.performanceMetrics.renderCount++;
|
|
7934
|
+
// Solo procesar si hay cambios relevantes
|
|
7935
|
+
if (this.tieneCambiosRelevantes(changes)) {
|
|
7936
|
+
this.logPerformance('Detectado cambio en inputs', {
|
|
7937
|
+
cambios: Object.keys(changes),
|
|
7938
|
+
idActual: this.id(),
|
|
7939
|
+
idAnterior: changes['id']?.previousValue,
|
|
7940
|
+
idNuevo: changes['id']?.currentValue,
|
|
7941
|
+
});
|
|
7942
|
+
this.definirTexto();
|
|
7943
|
+
}
|
|
7944
|
+
const endTime = performance.now();
|
|
7945
|
+
const renderTime = endTime - startTime;
|
|
7946
|
+
this.performanceMetrics.lastRenderTime = renderTime;
|
|
7947
|
+
this.performanceMetrics.totalRenderTime += renderTime;
|
|
7948
|
+
this.performanceMetrics.averageRenderTime =
|
|
7949
|
+
this.performanceMetrics.totalRenderTime /
|
|
7950
|
+
this.performanceMetrics.renderCount;
|
|
7951
|
+
this.logPerformance('Cambio procesado', {
|
|
7952
|
+
renderTime: renderTime.toFixed(2) + 'ms',
|
|
7953
|
+
renderCount: this.performanceMetrics.renderCount,
|
|
7954
|
+
avgRenderTime: this.performanceMetrics.averageRenderTime.toFixed(2) + 'ms',
|
|
7955
|
+
});
|
|
7956
|
+
}
|
|
7957
|
+
tieneCambiosRelevantes(changes) {
|
|
7958
|
+
const relevantKeys = ['id', 'etiqueta', 'icoPNG', 'icoGIF', 'subTitulo'];
|
|
7959
|
+
for (const key of relevantKeys) {
|
|
7960
|
+
if (changes[key] &&
|
|
7961
|
+
changes[key].currentValue !== changes[key].previousValue) {
|
|
7962
|
+
return true;
|
|
7963
|
+
}
|
|
7964
|
+
}
|
|
7965
|
+
return false;
|
|
7727
7966
|
}
|
|
7728
7967
|
definirTexto() {
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
if (this.
|
|
7732
|
-
|
|
7968
|
+
const startTime = performance.now();
|
|
7969
|
+
const idActual = this.id();
|
|
7970
|
+
if (this.debug() && !this.isProduction) {
|
|
7971
|
+
console.group(`🔍 HeaderDsx - Definiendo texto para ID: ${idActual}`);
|
|
7972
|
+
}
|
|
7973
|
+
let nuevoTexto;
|
|
7974
|
+
let nuevoIcono = null;
|
|
7975
|
+
// Determinar texto
|
|
7976
|
+
if (idActual === null) {
|
|
7977
|
+
nuevoTexto = this.etiqueta();
|
|
7978
|
+
this.logDebug('Caso 1: ID null - Modo lista');
|
|
7979
|
+
}
|
|
7980
|
+
else if (idActual === 0) {
|
|
7981
|
+
nuevoTexto = `Registrar ${this.etiqueta()}`;
|
|
7982
|
+
this.logDebug('Caso 2: ID = 0 - Modo registro');
|
|
7983
|
+
}
|
|
7984
|
+
else if (idActual > 0) {
|
|
7985
|
+
nuevoTexto = `Editar ${this.etiqueta()}`;
|
|
7986
|
+
this.logDebug('Caso 3: ID > 0 - Modo edición', {
|
|
7987
|
+
id: idActual,
|
|
7988
|
+
texto: nuevoTexto,
|
|
7989
|
+
});
|
|
7733
7990
|
}
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
this.
|
|
7991
|
+
else {
|
|
7992
|
+
nuevoTexto = this.etiqueta();
|
|
7993
|
+
this.logDebug('Caso desconocido', { id: idActual });
|
|
7737
7994
|
}
|
|
7738
|
-
//
|
|
7739
|
-
|
|
7740
|
-
|
|
7995
|
+
// Determinar icono
|
|
7996
|
+
if (this.icoPNG() !== null) {
|
|
7997
|
+
nuevoIcono = this.icoPNG();
|
|
7998
|
+
this.logDebug('Icono: Usando PNG personalizado', { icono: nuevoIcono });
|
|
7741
7999
|
}
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
|
|
7745
|
-
this.icono = this.defaultPNG();
|
|
8000
|
+
else if (this.icoGIF() !== null) {
|
|
8001
|
+
nuevoIcono = this.icoGIF();
|
|
8002
|
+
this.logDebug('Icono: Usando GIF personalizado', { icono: nuevoIcono });
|
|
7746
8003
|
}
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
this.icono
|
|
8004
|
+
else {
|
|
8005
|
+
nuevoIcono = this.defaultPNG();
|
|
8006
|
+
this.logDebug('Icono: Usando default', { icono: nuevoIcono });
|
|
7750
8007
|
}
|
|
7751
|
-
//
|
|
7752
|
-
|
|
7753
|
-
this.
|
|
8008
|
+
// Actualizar solo si hay cambios
|
|
8009
|
+
if (this.textoEncabezado() !== nuevoTexto) {
|
|
8010
|
+
this.textoEncabezado.set(nuevoTexto);
|
|
8011
|
+
}
|
|
8012
|
+
if (this.icono() !== nuevoIcono) {
|
|
8013
|
+
this.icono.set(nuevoIcono);
|
|
8014
|
+
}
|
|
8015
|
+
this.logDebug('Estado final actualizado', {
|
|
8016
|
+
texto: nuevoTexto,
|
|
8017
|
+
icono: nuevoIcono,
|
|
8018
|
+
id: idActual,
|
|
8019
|
+
modo: this.modo(),
|
|
8020
|
+
});
|
|
8021
|
+
if (this.debug() && !this.isProduction) {
|
|
8022
|
+
console.groupEnd();
|
|
8023
|
+
}
|
|
8024
|
+
const endTime = performance.now();
|
|
8025
|
+
this.logPerformance(`Tiempo de definición de texto: ${(endTime - startTime).toFixed(2)}ms`);
|
|
8026
|
+
}
|
|
8027
|
+
logDebug(message, data) {
|
|
8028
|
+
if (this.debug() && !this.isProduction) {
|
|
8029
|
+
console.log(`[HeaderDsx Debug] ${message}`, data ? data : '');
|
|
8030
|
+
}
|
|
8031
|
+
}
|
|
8032
|
+
logPerformance(message, data) {
|
|
8033
|
+
if (this.debug() && !this.isProduction) {
|
|
8034
|
+
console.log(`⚡ [HeaderDsx Performance] ${message}`, data ? data : '');
|
|
8035
|
+
}
|
|
8036
|
+
}
|
|
8037
|
+
// Métodos públicos
|
|
8038
|
+
getPerformanceMetrics() {
|
|
8039
|
+
return {
|
|
8040
|
+
...this.performanceMetrics,
|
|
8041
|
+
currentMode: this.modo(),
|
|
8042
|
+
currentText: this.textoEncabezado(),
|
|
8043
|
+
currentIcon: this.icono(),
|
|
8044
|
+
currentId: this.id(),
|
|
8045
|
+
};
|
|
8046
|
+
}
|
|
8047
|
+
getPerformanceSummary() {
|
|
8048
|
+
const metrics = this.performanceMetrics;
|
|
8049
|
+
return `📊 Renders: ${metrics.renderCount} | Promedio: ${metrics.averageRenderTime.toFixed(2)}ms | Último: ${metrics.lastRenderTime.toFixed(2)}ms`;
|
|
8050
|
+
}
|
|
8051
|
+
debugInfo() {
|
|
8052
|
+
if (this.debug() && !this.isProduction) {
|
|
8053
|
+
console.group('=== HeaderDsx Debug Info ===');
|
|
8054
|
+
console.log('ID:', this.id());
|
|
8055
|
+
console.log('Etiqueta:', this.etiqueta());
|
|
8056
|
+
console.log('Texto Encabezado:', this.textoEncabezado());
|
|
8057
|
+
console.log('Icono:', this.icono());
|
|
8058
|
+
console.log('Subtítulo:', this.subTitulo());
|
|
8059
|
+
console.log('Modo:', this.modo());
|
|
8060
|
+
console.log('Debug Mode:', this.debug());
|
|
8061
|
+
console.log('Performance Metrics:', this.getPerformanceMetrics());
|
|
8062
|
+
console.log('Performance Summary:', this.getPerformanceSummary());
|
|
8063
|
+
console.log('===============================');
|
|
8064
|
+
console.groupEnd();
|
|
7754
8065
|
}
|
|
7755
8066
|
}
|
|
7756
8067
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: HeaderDsx, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7757
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: HeaderDsx, isStandalone: true, selector: "header-dsx", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, etiqueta: { classPropertyName: "etiqueta", publicName: "etiqueta", isSignal: true, isRequired: true, transformFunction: null }, defaultPNG: { classPropertyName: "defaultPNG", publicName: "defaultPNG", isSignal: true, isRequired: false, transformFunction: null }, defaultGIF: { classPropertyName: "defaultGIF", publicName: "defaultGIF", isSignal: true, isRequired: false, transformFunction: null }, icoPNG: { classPropertyName: "icoPNG", publicName: "icoPNG", isSignal: true, isRequired: false, transformFunction: null }, icoGIF: { classPropertyName: "icoGIF", publicName: "icoGIF", isSignal: true, isRequired: false, transformFunction: null }, subTitulo: { classPropertyName: "subTitulo", publicName: "subTitulo", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"area-fieldset-header flex items-center gap-2 px-2\">\r\n <p-avatar [image]=\"icono!\"></p-avatar>\r\n <div class=\"flex flex-col\">\r\n <h3>{{ textoEncabezado }}</h3>\r\n @if(subTitulo() !== null ){\r\n <
|
|
8068
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: HeaderDsx, isStandalone: true, selector: "header-dsx", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, etiqueta: { classPropertyName: "etiqueta", publicName: "etiqueta", isSignal: true, isRequired: true, transformFunction: null }, defaultPNG: { classPropertyName: "defaultPNG", publicName: "defaultPNG", isSignal: true, isRequired: false, transformFunction: null }, defaultGIF: { classPropertyName: "defaultGIF", publicName: "defaultGIF", isSignal: true, isRequired: false, transformFunction: null }, icoPNG: { classPropertyName: "icoPNG", publicName: "icoPNG", isSignal: true, isRequired: false, transformFunction: null }, icoGIF: { classPropertyName: "icoGIF", publicName: "icoGIF", isSignal: true, isRequired: false, transformFunction: null }, subTitulo: { classPropertyName: "subTitulo", publicName: "subTitulo", isSignal: true, isRequired: false, transformFunction: null }, debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"area-fieldset-header flex items-center gap-2 px-2\">\r\n <p-avatar [image]=\"icono()!\"></p-avatar>\r\n <div class=\"flex flex-col\">\r\n <h3>{{ textoEncabezado() }}</h3>\r\n @if(subTitulo() !== null ){\r\n <span class=\"text-xs text-gray-600\">{{ subTitulo() }}</span>\r\n }\r\n <!-- Debug info con m\u00E9tricas de performance -->\r\n @if(debug()){\r\n <div\r\n class=\"text-xs mt-1 px-2 py-1 rounded flex flex-wrap items-center gap-1\"\r\n [class]=\"id() === 0 ? 'bg-blue-50 text-blue-700' : \r\n id() !== null && id()! > 0 ? 'bg-green-50 text-green-700' : \r\n 'bg-gray-50 text-gray-700'\"\r\n >\r\n <span>\uD83D\uDD0D</span>\r\n <span>ID: {{ id() }}</span>\r\n <span>|</span>\r\n <span>Modo: <strong>{{ modo() }}</strong></span>\r\n <span>|</span>\r\n <span>Texto: {{ textoEncabezado() }}</span>\r\n @if(id() !== null && id()! > 0){\r\n <span class=\"ml-1 text-xs\">(Editando ID {{ id() }})</span>\r\n }\r\n <!-- M\u00E9tricas de performance -->\r\n <span class=\"ml-1 text-xs text-gray-400\">\r\n | Render: {{ performanceMetrics.renderCount }} | Avg: {{\r\n performanceMetrics.averageRenderTime.toFixed(1) }}ms\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i2$3.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
7758
8069
|
}
|
|
7759
8070
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: HeaderDsx, decorators: [{
|
|
7760
8071
|
type: Component,
|
|
7761
|
-
args: [{ selector: 'header-dsx', imports: [AvatarModule], template: "<div class=\"area-fieldset-header flex items-center gap-2 px-2\">\r\n <p-avatar [image]=\"icono!\"></p-avatar>\r\n <div class=\"flex flex-col\">\r\n <h3>{{ textoEncabezado }}</h3>\r\n @if(subTitulo() !== null ){\r\n <
|
|
7762
|
-
}], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], etiqueta: [{ type: i0.Input, args: [{ isSignal: true, alias: "etiqueta", required: true }] }], defaultPNG: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultPNG", required: false }] }], defaultGIF: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultGIF", required: false }] }], icoPNG: [{ type: i0.Input, args: [{ isSignal: true, alias: "icoPNG", required: false }] }], icoGIF: [{ type: i0.Input, args: [{ isSignal: true, alias: "icoGIF", required: false }] }], subTitulo: [{ type: i0.Input, args: [{ isSignal: true, alias: "subTitulo", required: false }] }] } });
|
|
8072
|
+
args: [{ selector: 'header-dsx', imports: [AvatarModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"area-fieldset-header flex items-center gap-2 px-2\">\r\n <p-avatar [image]=\"icono()!\"></p-avatar>\r\n <div class=\"flex flex-col\">\r\n <h3>{{ textoEncabezado() }}</h3>\r\n @if(subTitulo() !== null ){\r\n <span class=\"text-xs text-gray-600\">{{ subTitulo() }}</span>\r\n }\r\n <!-- Debug info con m\u00E9tricas de performance -->\r\n @if(debug()){\r\n <div\r\n class=\"text-xs mt-1 px-2 py-1 rounded flex flex-wrap items-center gap-1\"\r\n [class]=\"id() === 0 ? 'bg-blue-50 text-blue-700' : \r\n id() !== null && id()! > 0 ? 'bg-green-50 text-green-700' : \r\n 'bg-gray-50 text-gray-700'\"\r\n >\r\n <span>\uD83D\uDD0D</span>\r\n <span>ID: {{ id() }}</span>\r\n <span>|</span>\r\n <span>Modo: <strong>{{ modo() }}</strong></span>\r\n <span>|</span>\r\n <span>Texto: {{ textoEncabezado() }}</span>\r\n @if(id() !== null && id()! > 0){\r\n <span class=\"ml-1 text-xs\">(Editando ID {{ id() }})</span>\r\n }\r\n <!-- M\u00E9tricas de performance -->\r\n <span class=\"ml-1 text-xs text-gray-400\">\r\n | Render: {{ performanceMetrics.renderCount }} | Avg: {{\r\n performanceMetrics.averageRenderTime.toFixed(1) }}ms\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n" }]
|
|
8073
|
+
}], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], etiqueta: [{ type: i0.Input, args: [{ isSignal: true, alias: "etiqueta", required: true }] }], defaultPNG: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultPNG", required: false }] }], defaultGIF: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultGIF", required: false }] }], icoPNG: [{ type: i0.Input, args: [{ isSignal: true, alias: "icoPNG", required: false }] }], icoGIF: [{ type: i0.Input, args: [{ isSignal: true, alias: "icoGIF", required: false }] }], subTitulo: [{ type: i0.Input, args: [{ isSignal: true, alias: "subTitulo", required: false }] }], debug: [{ type: i0.Input, args: [{ isSignal: true, alias: "debug", required: false }] }] } });
|
|
7763
8074
|
|
|
7764
8075
|
class DsxAddToolsModule {
|
|
7765
8076
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxAddToolsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
@@ -8091,6 +8402,456 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
8091
8402
|
}]
|
|
8092
8403
|
}] });
|
|
8093
8404
|
|
|
8405
|
+
// dsxdate-short.ts
|
|
8406
|
+
class DsxdateShort {
|
|
8407
|
+
injector = inject(Injector);
|
|
8408
|
+
// ✅ Exponer isDevMode como propiedad pública
|
|
8409
|
+
isDevMode = isDevMode();
|
|
8410
|
+
// === INPUTS CONFIGURABLES ===
|
|
8411
|
+
label = input.required(...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
8412
|
+
placeholder = input('dd/mm/yyyy', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
8413
|
+
dateFormat = input('dd/mm/yy', ...(ngDevMode ? [{ debugName: "dateFormat" }] : /* istanbul ignore next */ []));
|
|
8414
|
+
showIcon = input(true, ...(ngDevMode ? [{ debugName: "showIcon" }] : /* istanbul ignore next */ []));
|
|
8415
|
+
showOnFocus = input(false, ...(ngDevMode ? [{ debugName: "showOnFocus" }] : /* istanbul ignore next */ []));
|
|
8416
|
+
showButtonBar = input(true, ...(ngDevMode ? [{ debugName: "showButtonBar" }] : /* istanbul ignore next */ []));
|
|
8417
|
+
debug = input(false, ...(ngDevMode ? [{ debugName: "debug" }] : /* istanbul ignore next */ []));
|
|
8418
|
+
// === STATE ===
|
|
8419
|
+
debugEnabled = signal(false, ...(ngDevMode ? [{ debugName: "debugEnabled" }] : /* istanbul ignore next */ []));
|
|
8420
|
+
// === OBTENER EL CONTROL PADRE ===
|
|
8421
|
+
ngControl = computed(() => {
|
|
8422
|
+
try {
|
|
8423
|
+
return this.injector.get(NgControl);
|
|
8424
|
+
}
|
|
8425
|
+
catch {
|
|
8426
|
+
return null;
|
|
8427
|
+
}
|
|
8428
|
+
}, ...(ngDevMode ? [{ debugName: "ngControl" }] : /* istanbul ignore next */ []));
|
|
8429
|
+
// === CONTROL PADRE PARA ERRORES ===
|
|
8430
|
+
parentControl = computed(() => {
|
|
8431
|
+
const control = this.ngControl();
|
|
8432
|
+
return control?.control || null;
|
|
8433
|
+
}, ...(ngDevMode ? [{ debugName: "parentControl" }] : /* istanbul ignore next */ []));
|
|
8434
|
+
// === CONTROL INTERNO (para el template) ===
|
|
8435
|
+
fechaControl = new FormControl(null);
|
|
8436
|
+
// === CONTROL VALUE ACCESSOR ===
|
|
8437
|
+
onChange = () => { };
|
|
8438
|
+
onTouched = () => { };
|
|
8439
|
+
constructor() {
|
|
8440
|
+
// Debug effect
|
|
8441
|
+
effect(() => {
|
|
8442
|
+
const isDebug = this.debug() && this.isDevMode;
|
|
8443
|
+
this.debugEnabled.set(isDebug);
|
|
8444
|
+
if (isDebug) {
|
|
8445
|
+
console.log('[dsxdate-short] === DEBUG MODE ACTIVADO ===');
|
|
8446
|
+
console.log('[dsxdate-short] Configuración:', {
|
|
8447
|
+
label: this.label(),
|
|
8448
|
+
placeholder: this.placeholder(),
|
|
8449
|
+
dateFormat: this.dateFormat(),
|
|
8450
|
+
showIcon: this.showIcon(),
|
|
8451
|
+
showOnFocus: this.showOnFocus(),
|
|
8452
|
+
showButtonBar: this.showButtonBar(),
|
|
8453
|
+
});
|
|
8454
|
+
console.log('[dsxdate-short] Control padre:', this.parentControl());
|
|
8455
|
+
}
|
|
8456
|
+
});
|
|
8457
|
+
// ✅ SINCRONIZAR VALIDADORES DEL PADRE AL CONTROL INTERNO
|
|
8458
|
+
effect(() => {
|
|
8459
|
+
const parentCtrl = this.parentControl();
|
|
8460
|
+
if (parentCtrl) {
|
|
8461
|
+
// Copiar validadores del padre al control interno
|
|
8462
|
+
const validators = parentCtrl.validator;
|
|
8463
|
+
const asyncValidators = parentCtrl.asyncValidator;
|
|
8464
|
+
if (this.debugEnabled()) {
|
|
8465
|
+
console.log('[dsxdate-short] 🔄 Sincronizando validadores del padre');
|
|
8466
|
+
console.log('[dsxdate-short] Validadores del padre:', validators);
|
|
8467
|
+
}
|
|
8468
|
+
this.fechaControl.setValidators(validators ? [validators] : []);
|
|
8469
|
+
this.fechaControl.setAsyncValidators(asyncValidators ? [asyncValidators] : []);
|
|
8470
|
+
this.fechaControl.updateValueAndValidity({ emitEvent: false });
|
|
8471
|
+
if (this.debugEnabled()) {
|
|
8472
|
+
console.log('[dsxdate-short] ✅ Validadores sincronizados');
|
|
8473
|
+
console.log('[dsxdate-short] Estado del control interno:', {
|
|
8474
|
+
valid: this.fechaControl.valid,
|
|
8475
|
+
invalid: this.fechaControl.invalid,
|
|
8476
|
+
errors: this.fechaControl.errors,
|
|
8477
|
+
});
|
|
8478
|
+
}
|
|
8479
|
+
}
|
|
8480
|
+
});
|
|
8481
|
+
// Monitorear cambios del control padre
|
|
8482
|
+
effect(() => {
|
|
8483
|
+
if (this.debugEnabled()) {
|
|
8484
|
+
const parentCtrl = this.parentControl();
|
|
8485
|
+
console.log('[dsxdate-short] 📊 Parent Control state:', {
|
|
8486
|
+
value: parentCtrl?.value,
|
|
8487
|
+
status: parentCtrl?.status,
|
|
8488
|
+
errors: parentCtrl?.errors,
|
|
8489
|
+
valid: parentCtrl?.valid,
|
|
8490
|
+
invalid: parentCtrl?.invalid,
|
|
8491
|
+
touched: parentCtrl?.touched,
|
|
8492
|
+
dirty: parentCtrl?.dirty,
|
|
8493
|
+
});
|
|
8494
|
+
}
|
|
8495
|
+
});
|
|
8496
|
+
// Sincronizar cambios del control interno al padre
|
|
8497
|
+
this.fechaControl.valueChanges.subscribe((value) => {
|
|
8498
|
+
if (this.debugEnabled()) {
|
|
8499
|
+
console.log('[dsxdate-short] 🔄 valueChanges - Nuevo valor:', value);
|
|
8500
|
+
}
|
|
8501
|
+
this.onChange(value);
|
|
8502
|
+
});
|
|
8503
|
+
// Sincronizar touched
|
|
8504
|
+
this.fechaControl.statusChanges.subscribe(() => {
|
|
8505
|
+
if (this.debugEnabled()) {
|
|
8506
|
+
console.log('[dsxdate-short] 📊 statusChanges - Estado:', this.fechaControl.status);
|
|
8507
|
+
}
|
|
8508
|
+
this.onTouched();
|
|
8509
|
+
});
|
|
8510
|
+
}
|
|
8511
|
+
// === MÉTODOS DE DEBUG ===
|
|
8512
|
+
log(message, data) {
|
|
8513
|
+
if (this.debugEnabled() && this.isDevMode) {
|
|
8514
|
+
if (data !== undefined) {
|
|
8515
|
+
console.log(`[dsxdate-short] ${message}`, data);
|
|
8516
|
+
}
|
|
8517
|
+
else {
|
|
8518
|
+
console.log(`[dsxdate-short] ${message}`);
|
|
8519
|
+
}
|
|
8520
|
+
}
|
|
8521
|
+
}
|
|
8522
|
+
/**
|
|
8523
|
+
* Convierte cualquier fecha (string ISO, Date, moment) a Date válido
|
|
8524
|
+
*/
|
|
8525
|
+
convertirFechaADate(fecha) {
|
|
8526
|
+
if (this.debugEnabled()) {
|
|
8527
|
+
this.log('🔄 convertirFechaADate - entrada:', fecha);
|
|
8528
|
+
}
|
|
8529
|
+
if (!fecha) {
|
|
8530
|
+
this.log('convertirFechaADate - fecha vacía, retornando null');
|
|
8531
|
+
return null;
|
|
8532
|
+
}
|
|
8533
|
+
if (fecha instanceof Date && !isNaN(fecha.getTime())) {
|
|
8534
|
+
this.log('✅ convertirFechaADate - es Date válido:', fecha);
|
|
8535
|
+
return fecha;
|
|
8536
|
+
}
|
|
8537
|
+
if (typeof fecha === 'string') {
|
|
8538
|
+
this.log('📝 convertirFechaADate - procesando string:', fecha);
|
|
8539
|
+
const momentDate = moment(fecha);
|
|
8540
|
+
if (momentDate.isValid()) {
|
|
8541
|
+
const result = momentDate.toDate();
|
|
8542
|
+
this.log('✅ convertirFechaADate - string convertido a Date:', result);
|
|
8543
|
+
return result;
|
|
8544
|
+
}
|
|
8545
|
+
this.log('❌ convertirFechaADate - string inválido para moment');
|
|
8546
|
+
}
|
|
8547
|
+
if (moment.isMoment(fecha)) {
|
|
8548
|
+
this.log('✅ convertirFechaADate - es objeto moment');
|
|
8549
|
+
return fecha.toDate();
|
|
8550
|
+
}
|
|
8551
|
+
const parsed = new Date(fecha);
|
|
8552
|
+
if (!isNaN(parsed.getTime())) {
|
|
8553
|
+
this.log('✅ convertirFechaADate - parseo directo exitoso:', parsed);
|
|
8554
|
+
return parsed;
|
|
8555
|
+
}
|
|
8556
|
+
this.log('❌ convertirFechaADate - no se pudo convertir, retornando null');
|
|
8557
|
+
return null;
|
|
8558
|
+
}
|
|
8559
|
+
// === CONTROL VALUE ACCESSOR IMPLEMENTATION ===
|
|
8560
|
+
writeValue(value) {
|
|
8561
|
+
if (this.debugEnabled()) {
|
|
8562
|
+
this.log('📥 writeValue - Valor recibido:', value);
|
|
8563
|
+
}
|
|
8564
|
+
const fechaConvertida = this.convertirFechaADate(value);
|
|
8565
|
+
if (this.debugEnabled()) {
|
|
8566
|
+
this.log('📥 writeValue - Valor convertido:', fechaConvertida);
|
|
8567
|
+
}
|
|
8568
|
+
this.fechaControl.setValue(fechaConvertida, { emitEvent: false });
|
|
8569
|
+
}
|
|
8570
|
+
registerOnChange(fn) {
|
|
8571
|
+
if (this.debugEnabled()) {
|
|
8572
|
+
this.log('📞 registerOnChange - Callback registrado');
|
|
8573
|
+
}
|
|
8574
|
+
this.onChange = fn;
|
|
8575
|
+
}
|
|
8576
|
+
registerOnTouched(fn) {
|
|
8577
|
+
if (this.debugEnabled()) {
|
|
8578
|
+
this.log('📞 registerOnTouched - Callback registrado');
|
|
8579
|
+
}
|
|
8580
|
+
this.onTouched = fn;
|
|
8581
|
+
}
|
|
8582
|
+
setDisabledState(isDisabled) {
|
|
8583
|
+
if (this.debugEnabled()) {
|
|
8584
|
+
this.log(`🚫 setDisabledState - Deshabilitado: ${isDisabled}`);
|
|
8585
|
+
}
|
|
8586
|
+
if (isDisabled) {
|
|
8587
|
+
this.fechaControl.disable({ emitEvent: false });
|
|
8588
|
+
}
|
|
8589
|
+
else {
|
|
8590
|
+
this.fechaControl.enable({ emitEvent: false });
|
|
8591
|
+
}
|
|
8592
|
+
}
|
|
8593
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxdateShort, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8594
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: DsxdateShort, isStandalone: true, selector: "dsxdate-short", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, dateFormat: { classPropertyName: "dateFormat", publicName: "dateFormat", isSignal: true, isRequired: false, transformFunction: null }, showIcon: { classPropertyName: "showIcon", publicName: "showIcon", isSignal: true, isRequired: false, transformFunction: null }, showOnFocus: { classPropertyName: "showOnFocus", publicName: "showOnFocus", isSignal: true, isRequired: false, transformFunction: null }, showButtonBar: { classPropertyName: "showButtonBar", publicName: "showButtonBar", isSignal: true, isRequired: false, transformFunction: null }, debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
8595
|
+
{
|
|
8596
|
+
provide: NG_VALUE_ACCESSOR,
|
|
8597
|
+
useExisting: forwardRef(() => DsxdateShort),
|
|
8598
|
+
multi: true,
|
|
8599
|
+
},
|
|
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" }] });
|
|
8601
|
+
}
|
|
8602
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxdateShort, decorators: [{
|
|
8603
|
+
type: Component,
|
|
8604
|
+
args: [{ selector: 'dsxdate-short', imports: [
|
|
8605
|
+
CommonModule,
|
|
8606
|
+
FloatLabel,
|
|
8607
|
+
DatePicker,
|
|
8608
|
+
ReactiveFormsModule,
|
|
8609
|
+
AppMessageErrorComponent,
|
|
8610
|
+
JsonPipe,
|
|
8611
|
+
], providers: [
|
|
8612
|
+
{
|
|
8613
|
+
provide: NG_VALUE_ACCESSOR,
|
|
8614
|
+
useExisting: forwardRef(() => DsxdateShort),
|
|
8615
|
+
multi: true,
|
|
8616
|
+
},
|
|
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" }]
|
|
8618
|
+
}], 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
|
+
|
|
8620
|
+
// dsx-input-currency.ts
|
|
8621
|
+
class DsxInputCurrency {
|
|
8622
|
+
inputNumber;
|
|
8623
|
+
injector = inject(Injector);
|
|
8624
|
+
// === INPUTS CONFIGURABLES ===
|
|
8625
|
+
label = input('Saldo Actual', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
8626
|
+
currency = input('GTQ', ...(ngDevMode ? [{ debugName: "currency" }] : /* istanbul ignore next */ []));
|
|
8627
|
+
locale = input('es-GT', ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
|
|
8628
|
+
minFractionDigits = input(2, ...(ngDevMode ? [{ debugName: "minFractionDigits" }] : /* istanbul ignore next */ []));
|
|
8629
|
+
maxFractionDigits = input(2, ...(ngDevMode ? [{ debugName: "maxFractionDigits" }] : /* istanbul ignore next */ []));
|
|
8630
|
+
placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
8631
|
+
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
8632
|
+
selectAllOnFocus = input(true, ...(ngDevMode ? [{ debugName: "selectAllOnFocus" }] : /* istanbul ignore next */ []));
|
|
8633
|
+
debug = input(false, ...(ngDevMode ? [{ debugName: "debug" }] : /* istanbul ignore next */ []));
|
|
8634
|
+
showError = input(true, ...(ngDevMode ? [{ debugName: "showError" }] : /* istanbul ignore next */ []));
|
|
8635
|
+
// === OUTPUTS ===
|
|
8636
|
+
valueChange = output();
|
|
8637
|
+
focus = output();
|
|
8638
|
+
blur = output();
|
|
8639
|
+
// === STATE ===
|
|
8640
|
+
valueSignal = signal(null, ...(ngDevMode ? [{ debugName: "valueSignal" }] : /* istanbul ignore next */ []));
|
|
8641
|
+
touched = signal(false, ...(ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []));
|
|
8642
|
+
debugEnabled = signal(false, ...(ngDevMode ? [{ debugName: "debugEnabled" }] : /* istanbul ignore next */ []));
|
|
8643
|
+
// === COMPUTED ===
|
|
8644
|
+
resolvedLabel = computed(() => this.label(), ...(ngDevMode ? [{ debugName: "resolvedLabel" }] : /* istanbul ignore next */ []));
|
|
8645
|
+
resolvedCurrency = computed(() => this.currency(), ...(ngDevMode ? [{ debugName: "resolvedCurrency" }] : /* istanbul ignore next */ []));
|
|
8646
|
+
resolvedLocale = computed(() => this.locale(), ...(ngDevMode ? [{ debugName: "resolvedLocale" }] : /* istanbul ignore next */ []));
|
|
8647
|
+
// === OBTENER EL CONTROL PADRE ===
|
|
8648
|
+
ngControl = computed(() => {
|
|
8649
|
+
try {
|
|
8650
|
+
return this.injector.get(NgControl);
|
|
8651
|
+
}
|
|
8652
|
+
catch {
|
|
8653
|
+
return null;
|
|
8654
|
+
}
|
|
8655
|
+
}, ...(ngDevMode ? [{ debugName: "ngControl" }] : /* istanbul ignore next */ []));
|
|
8656
|
+
// === CONTROL PADRE PARA ERRORES ===
|
|
8657
|
+
parentControl = computed(() => {
|
|
8658
|
+
const control = this.ngControl();
|
|
8659
|
+
return control?.control || null;
|
|
8660
|
+
}, ...(ngDevMode ? [{ debugName: "parentControl" }] : /* istanbul ignore next */ []));
|
|
8661
|
+
// === CONTROL INTERNO (para el template) ===
|
|
8662
|
+
control = new FormControl();
|
|
8663
|
+
// === CONTROL VALUE ACCESSOR ===
|
|
8664
|
+
onChange = () => { };
|
|
8665
|
+
onTouched = () => { };
|
|
8666
|
+
constructor() {
|
|
8667
|
+
// Debug effect
|
|
8668
|
+
effect(() => {
|
|
8669
|
+
const isDebug = this.debug() && isDevMode();
|
|
8670
|
+
this.debugEnabled.set(isDebug);
|
|
8671
|
+
if (isDebug) {
|
|
8672
|
+
console.log('[dsx-input-currency] === DEBUG MODE ACTIVADO ===');
|
|
8673
|
+
console.log('[dsx-input-currency] Configuración:', {
|
|
8674
|
+
label: this.label(),
|
|
8675
|
+
currency: this.currency(),
|
|
8676
|
+
locale: this.locale(),
|
|
8677
|
+
minFractionDigits: this.minFractionDigits(),
|
|
8678
|
+
maxFractionDigits: this.maxFractionDigits(),
|
|
8679
|
+
placeholder: this.placeholder(),
|
|
8680
|
+
readonly: this.readonly(),
|
|
8681
|
+
selectAllOnFocus: this.selectAllOnFocus(),
|
|
8682
|
+
});
|
|
8683
|
+
console.log('[dsx-input-currency] Control padre:', this.parentControl());
|
|
8684
|
+
}
|
|
8685
|
+
});
|
|
8686
|
+
// Monitorear cambios del control padre
|
|
8687
|
+
effect(() => {
|
|
8688
|
+
if (this.debugEnabled()) {
|
|
8689
|
+
const parentCtrl = this.parentControl();
|
|
8690
|
+
console.log('[dsx-input-currency] 📊 Parent Control state:', {
|
|
8691
|
+
value: parentCtrl?.value,
|
|
8692
|
+
status: parentCtrl?.status,
|
|
8693
|
+
errors: parentCtrl?.errors,
|
|
8694
|
+
valid: parentCtrl?.valid,
|
|
8695
|
+
invalid: parentCtrl?.invalid,
|
|
8696
|
+
touched: parentCtrl?.touched,
|
|
8697
|
+
dirty: parentCtrl?.dirty,
|
|
8698
|
+
});
|
|
8699
|
+
}
|
|
8700
|
+
});
|
|
8701
|
+
}
|
|
8702
|
+
ngAfterViewInit() {
|
|
8703
|
+
if (this.debugEnabled()) {
|
|
8704
|
+
console.log('[dsx-input-currency] ngAfterViewInit - Vista inicializada');
|
|
8705
|
+
}
|
|
8706
|
+
// Sincronizar el control padre con el interno
|
|
8707
|
+
const parentCtrl = this.parentControl();
|
|
8708
|
+
if (parentCtrl) {
|
|
8709
|
+
this.control.setValue(parentCtrl.value, { emitEvent: false });
|
|
8710
|
+
}
|
|
8711
|
+
if (this.inputNumber && this.selectAllOnFocus()) {
|
|
8712
|
+
const inputElement = this.inputNumber.input
|
|
8713
|
+
.nativeElement;
|
|
8714
|
+
if (this.debugEnabled()) {
|
|
8715
|
+
console.log('[dsx-input-currency] Input element encontrado');
|
|
8716
|
+
}
|
|
8717
|
+
const originalFocus = inputElement.focus.bind(inputElement);
|
|
8718
|
+
const enhancedFocus = function () {
|
|
8719
|
+
originalFocus();
|
|
8720
|
+
setTimeout(() => this.select(), 0);
|
|
8721
|
+
};
|
|
8722
|
+
inputElement.focus = enhancedFocus;
|
|
8723
|
+
}
|
|
8724
|
+
}
|
|
8725
|
+
// === MÉTODOS PÚBLICOS ===
|
|
8726
|
+
onValueChange(value) {
|
|
8727
|
+
// ✅ Solo procesar si es un número válido
|
|
8728
|
+
if (value === null || value === undefined || isNaN(value)) {
|
|
8729
|
+
return;
|
|
8730
|
+
}
|
|
8731
|
+
if (this.debugEnabled()) {
|
|
8732
|
+
console.log(`[dsx-input-currency] 📝 onValueChange - Valor: ${value}`);
|
|
8733
|
+
}
|
|
8734
|
+
this.valueSignal.set(value);
|
|
8735
|
+
this.onChange(value);
|
|
8736
|
+
this.valueChange.emit(value);
|
|
8737
|
+
const parentCtrl = this.parentControl();
|
|
8738
|
+
if (parentCtrl) {
|
|
8739
|
+
parentCtrl.setValue(value, { emitEvent: true });
|
|
8740
|
+
}
|
|
8741
|
+
}
|
|
8742
|
+
onFocus() {
|
|
8743
|
+
if (this.debugEnabled()) {
|
|
8744
|
+
console.log(`[dsx-input-currency] 🔍 onFocus - Evento focus emitido`);
|
|
8745
|
+
}
|
|
8746
|
+
if (this.selectAllOnFocus() && this.inputNumber) {
|
|
8747
|
+
const inputElement = this.inputNumber.input
|
|
8748
|
+
.nativeElement;
|
|
8749
|
+
if (inputElement && typeof inputElement.select === 'function') {
|
|
8750
|
+
setTimeout(() => {
|
|
8751
|
+
inputElement.select();
|
|
8752
|
+
if (this.debugEnabled()) {
|
|
8753
|
+
console.log('[dsx-input-currency] ✅ Input seleccionado completamente');
|
|
8754
|
+
}
|
|
8755
|
+
}, 0);
|
|
8756
|
+
}
|
|
8757
|
+
}
|
|
8758
|
+
this.focus.emit();
|
|
8759
|
+
}
|
|
8760
|
+
onBlur() {
|
|
8761
|
+
const wasTouched = this.touched();
|
|
8762
|
+
this.touched.set(true);
|
|
8763
|
+
this.control.markAsTouched();
|
|
8764
|
+
const parentCtrl = this.parentControl();
|
|
8765
|
+
if (parentCtrl) {
|
|
8766
|
+
parentCtrl.markAsTouched();
|
|
8767
|
+
}
|
|
8768
|
+
if (this.debugEnabled()) {
|
|
8769
|
+
console.log(`[dsx-input-currency] 👋 onBlur - touched: ${!wasTouched ? 'Primera vez' : 'Ya estaba touched'}`);
|
|
8770
|
+
}
|
|
8771
|
+
this.blur.emit();
|
|
8772
|
+
}
|
|
8773
|
+
// === MÉTODOS DE DEBUG ===
|
|
8774
|
+
log(message, data) {
|
|
8775
|
+
if (this.debugEnabled() && isDevMode()) {
|
|
8776
|
+
if (data !== undefined) {
|
|
8777
|
+
console.log(`[dsx-input-currency] ${message}`, data);
|
|
8778
|
+
}
|
|
8779
|
+
else {
|
|
8780
|
+
console.log(`[dsx-input-currency] ${message}`);
|
|
8781
|
+
}
|
|
8782
|
+
}
|
|
8783
|
+
}
|
|
8784
|
+
// === CONTROL VALUE ACCESSOR IMPLEMENTATION ===
|
|
8785
|
+
writeValue(value) {
|
|
8786
|
+
if (this.debugEnabled()) {
|
|
8787
|
+
console.log(`[dsx-input-currency] 📥 writeValue - Valor recibido: ${value}`);
|
|
8788
|
+
}
|
|
8789
|
+
this.valueSignal.set(value);
|
|
8790
|
+
this.control.setValue(value, { emitEvent: false });
|
|
8791
|
+
}
|
|
8792
|
+
registerOnChange(fn) {
|
|
8793
|
+
if (this.debugEnabled()) {
|
|
8794
|
+
console.log('[dsx-input-currency] 📞 registerOnChange - Callback registrado');
|
|
8795
|
+
}
|
|
8796
|
+
this.onChange = fn;
|
|
8797
|
+
this.control.valueChanges.subscribe((val) => {
|
|
8798
|
+
if (this.debugEnabled()) {
|
|
8799
|
+
console.log(`[dsx-input-currency] 🔄 valueChanges - Nuevo valor: ${val}`);
|
|
8800
|
+
}
|
|
8801
|
+
this.onChange(val);
|
|
8802
|
+
});
|
|
8803
|
+
}
|
|
8804
|
+
registerOnTouched(fn) {
|
|
8805
|
+
if (this.debugEnabled()) {
|
|
8806
|
+
console.log('[dsx-input-currency] 📞 registerOnTouched - Callback registrado');
|
|
8807
|
+
}
|
|
8808
|
+
this.onTouched = fn;
|
|
8809
|
+
this.control.statusChanges.subscribe(() => {
|
|
8810
|
+
if (this.debugEnabled()) {
|
|
8811
|
+
console.log(`[dsx-input-currency] 📊 statusChanges - Estado: ${this.control.status}`);
|
|
8812
|
+
}
|
|
8813
|
+
this.onTouched();
|
|
8814
|
+
});
|
|
8815
|
+
}
|
|
8816
|
+
setDisabledState(isDisabled) {
|
|
8817
|
+
if (this.debugEnabled()) {
|
|
8818
|
+
console.log(`[dsx-input-currency] 🚫 setDisabledState - Deshabilitado: ${isDisabled}`);
|
|
8819
|
+
}
|
|
8820
|
+
if (isDisabled) {
|
|
8821
|
+
this.control.disable({ emitEvent: false });
|
|
8822
|
+
}
|
|
8823
|
+
else {
|
|
8824
|
+
this.control.enable({ emitEvent: false });
|
|
8825
|
+
}
|
|
8826
|
+
}
|
|
8827
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxInputCurrency, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8828
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: DsxInputCurrency, isStandalone: true, selector: "dsx-input-currency", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, currency: { classPropertyName: "currency", publicName: "currency", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, minFractionDigits: { classPropertyName: "minFractionDigits", publicName: "minFractionDigits", isSignal: true, isRequired: false, transformFunction: null }, maxFractionDigits: { classPropertyName: "maxFractionDigits", publicName: "maxFractionDigits", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, selectAllOnFocus: { classPropertyName: "selectAllOnFocus", publicName: "selectAllOnFocus", isSignal: true, isRequired: false, transformFunction: null }, debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null }, showError: { classPropertyName: "showError", publicName: "showError", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", focus: "focus", blur: "blur" }, providers: [
|
|
8829
|
+
{
|
|
8830
|
+
provide: NG_VALUE_ACCESSOR,
|
|
8831
|
+
useExisting: forwardRef(() => DsxInputCurrency),
|
|
8832
|
+
multi: true,
|
|
8833
|
+
},
|
|
8834
|
+
], viewQueries: [{ propertyName: "inputNumber", first: true, predicate: InputNumber, descendants: true }], ngImport: i0, template: "<!-- dsx-input-currency.html -->\r\n<p-floatLabel [variant]=\"'on'\">\r\n <p-inputNumber\r\n #inputNumber\r\n fluid\r\n [mode]=\"'currency'\"\r\n [currency]=\"resolvedCurrency()\"\r\n [locale]=\"resolvedLocale()\"\r\n [minFractionDigits]=\"minFractionDigits()\"\r\n [maxFractionDigits]=\"maxFractionDigits()\"\r\n [placeholder]=\"placeholder()\"\r\n [autocomplete]=\"'off'\"\r\n [formControl]=\"control\"\r\n [readonly]=\"readonly()\"\r\n (onFocus)=\"onFocus()\"\r\n (onBlur)=\"onBlur()\"\r\n (onInput)=\"onValueChange($event.value)\"\r\n />\r\n <label>{{ resolvedLabel() }}</label>\r\n</p-floatLabel>\r\n\r\n<!-- Mensaje de error usando el control padre -->\r\n@if (showError() && parentControl()) {\r\n<!-- [debugMode]=\"true\" -->\r\n<dsx-message-error [control]=\"parentControl()\" />\r\n}\r\n", styles: [":host ::ng-deep .p-inputnumber-input{text-align:right}\n"], dependencies: [{ kind: "component", type: FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "component", type: InputNumber, selector: "p-inputNumber, p-inputnumber, p-input-number", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "placeholder", "tabindex", "title", "ariaLabelledBy", "ariaDescribedBy", "ariaLabel", "ariaRequired", "autocomplete", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "component", type: AppMessageErrorComponent, selector: "dsx-message-error", inputs: ["control", "form", "debugMode"] }, { 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"] }] });
|
|
8835
|
+
}
|
|
8836
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxInputCurrency, decorators: [{
|
|
8837
|
+
type: Component,
|
|
8838
|
+
args: [{ selector: 'dsx-input-currency', imports: [
|
|
8839
|
+
FloatLabel,
|
|
8840
|
+
InputNumber,
|
|
8841
|
+
AppMessageErrorComponent,
|
|
8842
|
+
ReactiveFormsModule,
|
|
8843
|
+
], providers: [
|
|
8844
|
+
{
|
|
8845
|
+
provide: NG_VALUE_ACCESSOR,
|
|
8846
|
+
useExisting: forwardRef(() => DsxInputCurrency),
|
|
8847
|
+
multi: true,
|
|
8848
|
+
},
|
|
8849
|
+
], template: "<!-- dsx-input-currency.html -->\r\n<p-floatLabel [variant]=\"'on'\">\r\n <p-inputNumber\r\n #inputNumber\r\n fluid\r\n [mode]=\"'currency'\"\r\n [currency]=\"resolvedCurrency()\"\r\n [locale]=\"resolvedLocale()\"\r\n [minFractionDigits]=\"minFractionDigits()\"\r\n [maxFractionDigits]=\"maxFractionDigits()\"\r\n [placeholder]=\"placeholder()\"\r\n [autocomplete]=\"'off'\"\r\n [formControl]=\"control\"\r\n [readonly]=\"readonly()\"\r\n (onFocus)=\"onFocus()\"\r\n (onBlur)=\"onBlur()\"\r\n (onInput)=\"onValueChange($event.value)\"\r\n />\r\n <label>{{ resolvedLabel() }}</label>\r\n</p-floatLabel>\r\n\r\n<!-- Mensaje de error usando el control padre -->\r\n@if (showError() && parentControl()) {\r\n<!-- [debugMode]=\"true\" -->\r\n<dsx-message-error [control]=\"parentControl()\" />\r\n}\r\n", styles: [":host ::ng-deep .p-inputnumber-input{text-align:right}\n"] }]
|
|
8850
|
+
}], ctorParameters: () => [], propDecorators: { inputNumber: [{
|
|
8851
|
+
type: ViewChild,
|
|
8852
|
+
args: [InputNumber]
|
|
8853
|
+
}], 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
|
+
|
|
8094
8855
|
// dsx-select.component.ts
|
|
8095
8856
|
class DsxSelect {
|
|
8096
8857
|
injector = inject(Injector);
|
|
@@ -8105,22 +8866,28 @@ class DsxSelect {
|
|
|
8105
8866
|
dataList = input.required(...(ngDevMode ? [{ debugName: "dataList" }] : /* istanbul ignore next */ []));
|
|
8106
8867
|
variant = input('on', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
8107
8868
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
8108
|
-
filterPlaceholder = input('Buscar ...', ...(ngDevMode ? [{ debugName: "filterPlaceholder" }] : /* istanbul ignore next */ []));
|
|
8869
|
+
filterPlaceholder = input('Buscar item...', ...(ngDevMode ? [{ debugName: "filterPlaceholder" }] : /* istanbul ignore next */ []));
|
|
8109
8870
|
showClear = input(true, ...(ngDevMode ? [{ debugName: "showClear" }] : /* istanbul ignore next */ []));
|
|
8110
8871
|
// Override opcional (solo cuando la convención no aplica)
|
|
8111
8872
|
optionLabel = input(undefined, ...(ngDevMode ? [{ debugName: "optionLabel" }] : /* istanbul ignore next */ []));
|
|
8112
8873
|
optionValue = input(undefined, ...(ngDevMode ? [{ debugName: "optionValue" }] : /* istanbul ignore next */ []));
|
|
8874
|
+
// ✨ NUEVO: Campo secundario opcional (para mostrar información adicional)
|
|
8875
|
+
secondaryField = input(undefined, ...(ngDevMode ? [{ debugName: "secondaryField" }] : /* istanbul ignore next */ []));
|
|
8876
|
+
showSecondaryField = computed(() => !!this.secondaryField(), ...(ngDevMode ? [{ debugName: "showSecondaryField" }] : /* istanbul ignore next */ []));
|
|
8877
|
+
// ✨ NUEVO: Virtual Scroll (por defecto desactivado)
|
|
8878
|
+
virtualScroll = input(false, ...(ngDevMode ? [{ debugName: "virtualScroll" }] : /* istanbul ignore next */ []));
|
|
8879
|
+
virtualScrollItemSize = input(40, ...(ngDevMode ? [{ debugName: "virtualScrollItemSize" }] : /* istanbul ignore next */ []));
|
|
8113
8880
|
// Iconos
|
|
8114
8881
|
useIcon = input(true, ...(ngDevMode ? [{ debugName: "useIcon" }] : /* istanbul ignore next */ []));
|
|
8115
|
-
itemIcon = input('
|
|
8882
|
+
itemIcon = input('keyboard_arrow_right', ...(ngDevMode ? [{ debugName: "itemIcon" }] : /* istanbul ignore next */ []));
|
|
8116
8883
|
selectedIcon = input('done_outline', ...(ngDevMode ? [{ debugName: "selectedIcon" }] : /* istanbul ignore next */ []));
|
|
8117
8884
|
// Debug solo consola
|
|
8118
8885
|
debug = input(false, ...(ngDevMode ? [{ debugName: "debug" }] : /* istanbul ignore next */ []));
|
|
8119
|
-
//
|
|
8886
|
+
// Mostrar mensajes de error (por defecto true)
|
|
8120
8887
|
showError = input(true, ...(ngDevMode ? [{ debugName: "showError" }] : /* istanbul ignore next */ []));
|
|
8121
8888
|
// Signal model para two-way binding
|
|
8122
8889
|
selectedValue = model(null, ...(ngDevMode ? [{ debugName: "selectedValue" }] : /* istanbul ignore next */ []));
|
|
8123
|
-
// Computed: OptionValue inferido automáticamente
|
|
8890
|
+
// Computed: OptionValue inferido automáticamente
|
|
8124
8891
|
resolvedOptionValue = computed(() => {
|
|
8125
8892
|
if (this.optionValue()) {
|
|
8126
8893
|
return this.optionValue();
|
|
@@ -8134,7 +8901,7 @@ class DsxSelect {
|
|
|
8134
8901
|
}
|
|
8135
8902
|
return 'id';
|
|
8136
8903
|
}, ...(ngDevMode ? [{ debugName: "resolvedOptionValue" }] : /* istanbul ignore next */ []));
|
|
8137
|
-
// Computed: OptionLabel inferido automáticamente
|
|
8904
|
+
// Computed: OptionLabel inferido automáticamente
|
|
8138
8905
|
resolvedOptionLabel = computed(() => {
|
|
8139
8906
|
if (this.optionLabel()) {
|
|
8140
8907
|
return this.optionLabel();
|
|
@@ -8148,7 +8915,7 @@ class DsxSelect {
|
|
|
8148
8915
|
}
|
|
8149
8916
|
return 'nombre';
|
|
8150
8917
|
}, ...(ngDevMode ? [{ debugName: "resolvedOptionLabel" }] : /* istanbul ignore next */ []));
|
|
8151
|
-
// Computed: Label inferido automáticamente
|
|
8918
|
+
// Computed: Label inferido automáticamente
|
|
8152
8919
|
resolvedLabel = computed(() => {
|
|
8153
8920
|
if (this.label()) {
|
|
8154
8921
|
return this.label();
|
|
@@ -8161,7 +8928,7 @@ class DsxSelect {
|
|
|
8161
8928
|
}
|
|
8162
8929
|
return 'Campo';
|
|
8163
8930
|
}, ...(ngDevMode ? [{ debugName: "resolvedLabel" }] : /* istanbul ignore next */ []));
|
|
8164
|
-
//
|
|
8931
|
+
// Computed: Obtener el control para errores
|
|
8165
8932
|
errorControl = computed(() => {
|
|
8166
8933
|
if (!this.showError())
|
|
8167
8934
|
return null;
|
|
@@ -8183,6 +8950,8 @@ class DsxSelect {
|
|
|
8183
8950
|
optionLabel: this.resolvedOptionLabel(),
|
|
8184
8951
|
label: this.resolvedLabel(),
|
|
8185
8952
|
showError: this.showError(),
|
|
8953
|
+
virtualScroll: this.virtualScroll(),
|
|
8954
|
+
secondaryField: this.secondaryField(),
|
|
8186
8955
|
});
|
|
8187
8956
|
}
|
|
8188
8957
|
});
|
|
@@ -8196,14 +8965,22 @@ class DsxSelect {
|
|
|
8196
8965
|
console.log(`Control: ${this.getFormControlName()}`);
|
|
8197
8966
|
console.log(`Items: ${dataList.length}`);
|
|
8198
8967
|
console.log(`Using: optionValue="${this.resolvedOptionValue()}", optionLabel="${this.resolvedOptionLabel()}"`);
|
|
8968
|
+
if (this.secondaryField()) {
|
|
8969
|
+
console.log(`Secondary field: "${this.secondaryField()}"`);
|
|
8970
|
+
}
|
|
8199
8971
|
console.log(`Time since last update: ${(currentTime - this.lastChangeTimestamp).toFixed(2)}ms`);
|
|
8200
8972
|
if (dataList.length > 0 && this.debug()) {
|
|
8201
8973
|
console.log(`Sample:`, dataList[0]);
|
|
8202
8974
|
console.log(`Value sample:`, dataList[0][this.resolvedOptionValue()]);
|
|
8203
8975
|
console.log(`Label sample:`, dataList[0][this.resolvedOptionLabel()]);
|
|
8976
|
+
if (this.secondaryField()) {
|
|
8977
|
+
const secondary = this.secondaryField();
|
|
8978
|
+
console.log(`Secondary sample:`, dataList[0][secondary]);
|
|
8979
|
+
}
|
|
8204
8980
|
}
|
|
8205
8981
|
if (dataList.length > 500) {
|
|
8206
8982
|
console.warn(`⚠️ Large dataset: ${dataList.length} items`);
|
|
8983
|
+
console.log(`💡 Consider enabling virtualScroll="true"`);
|
|
8207
8984
|
}
|
|
8208
8985
|
console.groupEnd();
|
|
8209
8986
|
}
|
|
@@ -8270,14 +9047,41 @@ class DsxSelect {
|
|
|
8270
9047
|
console.groupEnd();
|
|
8271
9048
|
}
|
|
8272
9049
|
}
|
|
9050
|
+
// dsx-select.component.ts - Agregar estos métodos
|
|
9051
|
+
/**
|
|
9052
|
+
* Cuando el select recibe foco
|
|
9053
|
+
*/
|
|
9054
|
+
onFocus() {
|
|
9055
|
+
if (this.debug()) {
|
|
9056
|
+
console.log('[DsxSelect] onFocus');
|
|
9057
|
+
}
|
|
9058
|
+
}
|
|
9059
|
+
/**
|
|
9060
|
+
* Cuando el panel de opciones se cierra (el usuario ha interactuado)
|
|
9061
|
+
* Este es el evento clave que marca el control como touched
|
|
9062
|
+
*/
|
|
9063
|
+
onHide() {
|
|
9064
|
+
if (this.debug()) {
|
|
9065
|
+
console.log('[DsxSelect] onHide - dropdown closed');
|
|
9066
|
+
}
|
|
9067
|
+
// Marcar como touched cuando el usuario cierra el dropdown
|
|
9068
|
+
// Esto incluye: seleccionar un valor O hacer clic fuera
|
|
9069
|
+
if (this.ngControl?.control && !this.ngControl.control.touched) {
|
|
9070
|
+
this.ngControl.control.markAsTouched();
|
|
9071
|
+
this.onTouched();
|
|
9072
|
+
if (this.debug()) {
|
|
9073
|
+
console.log('[DsxSelect] Control marked as touched (onHide)');
|
|
9074
|
+
}
|
|
9075
|
+
}
|
|
9076
|
+
}
|
|
8273
9077
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxSelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8274
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: DsxSelect, isStandalone: true, selector: "dsx-select", inputs: { dataList: { classPropertyName: "dataList", publicName: "dataList", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, filterPlaceholder: { classPropertyName: "filterPlaceholder", publicName: "filterPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: false, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", isSignal: true, isRequired: false, transformFunction: null }, useIcon: { classPropertyName: "useIcon", publicName: "useIcon", isSignal: true, isRequired: false, transformFunction: null }, itemIcon: { classPropertyName: "itemIcon", publicName: "itemIcon", isSignal: true, isRequired: false, transformFunction: null }, selectedIcon: { classPropertyName: "selectedIcon", publicName: "selectedIcon", isSignal: true, isRequired: false, transformFunction: null }, debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null }, showError: { classPropertyName: "showError", publicName: "showError", isSignal: true, isRequired: false, transformFunction: null }, selectedValue: { classPropertyName: "selectedValue", publicName: "selectedValue", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedValue: "selectedValueChange" }, providers: [
|
|
9078
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: DsxSelect, isStandalone: true, selector: "dsx-select", inputs: { dataList: { classPropertyName: "dataList", publicName: "dataList", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, filterPlaceholder: { classPropertyName: "filterPlaceholder", publicName: "filterPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: false, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", isSignal: true, isRequired: false, transformFunction: null }, secondaryField: { classPropertyName: "secondaryField", publicName: "secondaryField", isSignal: true, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollItemSize: { classPropertyName: "virtualScrollItemSize", publicName: "virtualScrollItemSize", isSignal: true, isRequired: false, transformFunction: null }, useIcon: { classPropertyName: "useIcon", publicName: "useIcon", isSignal: true, isRequired: false, transformFunction: null }, itemIcon: { classPropertyName: "itemIcon", publicName: "itemIcon", isSignal: true, isRequired: false, transformFunction: null }, selectedIcon: { classPropertyName: "selectedIcon", publicName: "selectedIcon", isSignal: true, isRequired: false, transformFunction: null }, debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null }, showError: { classPropertyName: "showError", publicName: "showError", isSignal: true, isRequired: false, transformFunction: null }, selectedValue: { classPropertyName: "selectedValue", publicName: "selectedValue", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedValue: "selectedValueChange" }, providers: [
|
|
8275
9079
|
{
|
|
8276
9080
|
provide: NG_VALUE_ACCESSOR,
|
|
8277
9081
|
useExisting: forwardRef(() => DsxSelect),
|
|
8278
9082
|
multi: true,
|
|
8279
9083
|
},
|
|
8280
|
-
], ngImport: i0, template: "<!-- dsx-select.html -->\r\n<p-floatLabel [variant]=\"variant()\">\r\n <p-select\r\n fluid\r\n [options]=\"dataList()\"\r\n [filter]=\"true\"\r\n [filterPlaceholder]=\"filterPlaceholder()\"\r\n [showClear]=\"showClear()\"\r\n [disabled]=\"disabled\"\r\n [optionLabel]=\"resolvedOptionLabel()\"\r\n [optionValue]=\"resolvedOptionValue()\"\r\n [(ngModel)]=\"value\"\r\n (ngModelChange)=\"onValueChange($event)\"\r\n >\r\n <ng-template let-item #item>\r\n <div class=\"flex align-items-center\">\r\n @if (useIcon()) {\r\n <icon-dsx [name]=\"itemIcon()\" class=\"text-cyan-500! mr-1\"></icon-dsx>\r\n } {{ item[resolvedOptionLabel()] }}\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #selectedItem let-selectedOptions>\r\n <div class=\"flex align-items-center\">\r\n @if (useIcon()) {\r\n <icon-dsx
|
|
9084
|
+
], ngImport: i0, template: "<!-- dsx-select.html -->\r\n<p-floatLabel [variant]=\"variant()\">\r\n <p-select\r\n fluid\r\n appendTo=\"body\"\r\n [options]=\"dataList()\"\r\n [filter]=\"true\"\r\n [filterPlaceholder]=\"filterPlaceholder()\"\r\n [showClear]=\"showClear()\"\r\n [disabled]=\"disabled\"\r\n [optionLabel]=\"resolvedOptionLabel()\"\r\n [optionValue]=\"resolvedOptionValue()\"\r\n [virtualScroll]=\"virtualScroll()\"\r\n [virtualScrollItemSize]=\"virtualScrollItemSize()\"\r\n [(ngModel)]=\"value\"\r\n (ngModelChange)=\"onValueChange($event)\"\r\n (onFocus)=\"onFocus()\"\r\n (onHide)=\"onHide()\"\r\n >\r\n <!-- Item template -->\r\n <ng-template let-item #item>\r\n <div class=\"flex align-items-center gap-2\">\r\n @if (useIcon()) {\r\n <icon-dsx [name]=\"itemIcon()\" class=\"text-cyan-500! mr-1\"></icon-dsx>\r\n } @if (showSecondaryField()) {\r\n <div class=\"flex flex-col\">\r\n <span class=\"font-semibold text-sky-800\">\r\n {{ item[resolvedOptionLabel()] }}\r\n </span>\r\n <span class=\"text-xs text-gray-400\">\r\n {{ item[secondaryField()!] }}\r\n </span>\r\n </div>\r\n } @else { {{ item[resolvedOptionLabel()] }} }\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Selected item template -->\r\n <ng-template #selectedItem let-selectedOptions>\r\n <div class=\"flex align-items-center gap-2\">\r\n @if (useIcon()) {\r\n <icon-dsx [name]=\"selectedIcon()\" class=\"text-green-600!\"></icon-dsx>\r\n } @if (showSecondaryField() && selectedOptions) {\r\n <div class=\"flex gap-x-2\">\r\n <span class=\"font-semibold text-sky-700\">\r\n {{ selectedOptions[resolvedOptionLabel()] }}\r\n </span>\r\n <span class=\"text-gray-400\">\r\n {{ selectedOptions[secondaryField()!] }}\r\n </span>\r\n </div>\r\n } @else { {{ selectedOptions?.[resolvedOptionLabel()] }} }\r\n </div>\r\n </ng-template>\r\n </p-select>\r\n <label>{{ resolvedLabel() }}</label>\r\n</p-floatLabel>\r\n\r\n<!-- Mensaje de error condicional -->\r\n@if (showError() && errorControl()) {\r\n<dsx-message-error [control]=\"errorControl()\" />\r\n}\r\n", styles: ["icon-dsx{font-size:1.5em}\n"], dependencies: [{ 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: Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "component", type: IconDsxComponent, selector: "icon-dsx", inputs: ["name", "style", "debug"] }, { kind: "component", type: AppMessageErrorComponent, selector: "dsx-message-error", inputs: ["control", "form", "debugMode"] }] });
|
|
8281
9085
|
}
|
|
8282
9086
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxSelect, decorators: [{
|
|
8283
9087
|
type: Component,
|
|
@@ -8293,8 +9097,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
8293
9097
|
useExisting: forwardRef(() => DsxSelect),
|
|
8294
9098
|
multi: true,
|
|
8295
9099
|
},
|
|
8296
|
-
], template: "<!-- dsx-select.html -->\r\n<p-floatLabel [variant]=\"variant()\">\r\n <p-select\r\n fluid\r\n [options]=\"dataList()\"\r\n [filter]=\"true\"\r\n [filterPlaceholder]=\"filterPlaceholder()\"\r\n [showClear]=\"showClear()\"\r\n [disabled]=\"disabled\"\r\n [optionLabel]=\"resolvedOptionLabel()\"\r\n [optionValue]=\"resolvedOptionValue()\"\r\n [(ngModel)]=\"value\"\r\n (ngModelChange)=\"onValueChange($event)\"\r\n >\r\n <ng-template let-item #item>\r\n <div class=\"flex align-items-center\">\r\n @if (useIcon()) {\r\n <icon-dsx [name]=\"itemIcon()\" class=\"text-cyan-500! mr-1\"></icon-dsx>\r\n } {{ item[resolvedOptionLabel()] }}\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #selectedItem let-selectedOptions>\r\n <div class=\"flex align-items-center\">\r\n @if (useIcon()) {\r\n <icon-dsx
|
|
8297
|
-
}], ctorParameters: () => [], propDecorators: { dataList: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataList", required: true }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], filterPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterPlaceholder", required: false }] }], showClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClear", required: false }] }], optionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionLabel", required: false }] }], optionValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionValue", required: false }] }], useIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "useIcon", required: false }] }], itemIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemIcon", required: false }] }], selectedIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIcon", required: false }] }], debug: [{ type: i0.Input, args: [{ isSignal: true, alias: "debug", required: false }] }], showError: [{ type: i0.Input, args: [{ isSignal: true, alias: "showError", required: false }] }], selectedValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedValue", required: false }] }, { type: i0.Output, args: ["selectedValueChange"] }] } });
|
|
9100
|
+
], template: "<!-- dsx-select.html -->\r\n<p-floatLabel [variant]=\"variant()\">\r\n <p-select\r\n fluid\r\n appendTo=\"body\"\r\n [options]=\"dataList()\"\r\n [filter]=\"true\"\r\n [filterPlaceholder]=\"filterPlaceholder()\"\r\n [showClear]=\"showClear()\"\r\n [disabled]=\"disabled\"\r\n [optionLabel]=\"resolvedOptionLabel()\"\r\n [optionValue]=\"resolvedOptionValue()\"\r\n [virtualScroll]=\"virtualScroll()\"\r\n [virtualScrollItemSize]=\"virtualScrollItemSize()\"\r\n [(ngModel)]=\"value\"\r\n (ngModelChange)=\"onValueChange($event)\"\r\n (onFocus)=\"onFocus()\"\r\n (onHide)=\"onHide()\"\r\n >\r\n <!-- Item template -->\r\n <ng-template let-item #item>\r\n <div class=\"flex align-items-center gap-2\">\r\n @if (useIcon()) {\r\n <icon-dsx [name]=\"itemIcon()\" class=\"text-cyan-500! mr-1\"></icon-dsx>\r\n } @if (showSecondaryField()) {\r\n <div class=\"flex flex-col\">\r\n <span class=\"font-semibold text-sky-800\">\r\n {{ item[resolvedOptionLabel()] }}\r\n </span>\r\n <span class=\"text-xs text-gray-400\">\r\n {{ item[secondaryField()!] }}\r\n </span>\r\n </div>\r\n } @else { {{ item[resolvedOptionLabel()] }} }\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Selected item template -->\r\n <ng-template #selectedItem let-selectedOptions>\r\n <div class=\"flex align-items-center gap-2\">\r\n @if (useIcon()) {\r\n <icon-dsx [name]=\"selectedIcon()\" class=\"text-green-600!\"></icon-dsx>\r\n } @if (showSecondaryField() && selectedOptions) {\r\n <div class=\"flex gap-x-2\">\r\n <span class=\"font-semibold text-sky-700\">\r\n {{ selectedOptions[resolvedOptionLabel()] }}\r\n </span>\r\n <span class=\"text-gray-400\">\r\n {{ selectedOptions[secondaryField()!] }}\r\n </span>\r\n </div>\r\n } @else { {{ selectedOptions?.[resolvedOptionLabel()] }} }\r\n </div>\r\n </ng-template>\r\n </p-select>\r\n <label>{{ resolvedLabel() }}</label>\r\n</p-floatLabel>\r\n\r\n<!-- Mensaje de error condicional -->\r\n@if (showError() && errorControl()) {\r\n<dsx-message-error [control]=\"errorControl()\" />\r\n}\r\n", styles: ["icon-dsx{font-size:1.5em}\n"] }]
|
|
9101
|
+
}], ctorParameters: () => [], propDecorators: { dataList: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataList", required: true }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], filterPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterPlaceholder", required: false }] }], showClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClear", required: false }] }], optionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionLabel", required: false }] }], optionValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionValue", required: false }] }], secondaryField: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryField", required: false }] }], virtualScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualScroll", required: false }] }], virtualScrollItemSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualScrollItemSize", required: false }] }], useIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "useIcon", required: false }] }], itemIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemIcon", required: false }] }], selectedIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIcon", required: false }] }], debug: [{ type: i0.Input, args: [{ isSignal: true, alias: "debug", required: false }] }], showError: [{ type: i0.Input, args: [{ isSignal: true, alias: "showError", required: false }] }], selectedValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedValue", required: false }] }, { type: i0.Output, args: ["selectedValueChange"] }] } });
|
|
8298
9102
|
|
|
8299
9103
|
/**
|
|
8300
9104
|
* Servicio genérico para consumir endpoints REST de la API.
|
|
@@ -9551,44 +10355,98 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
9551
10355
|
|
|
9552
10356
|
// form-preview.service.ts
|
|
9553
10357
|
class FormPreviewService {
|
|
10358
|
+
environment;
|
|
10359
|
+
constructor() {
|
|
10360
|
+
// Inyectar el token en el constructor
|
|
10361
|
+
this.environment = inject(ENVIRONMENT);
|
|
10362
|
+
}
|
|
9554
10363
|
/**
|
|
9555
|
-
*
|
|
9556
|
-
* @param data - Objeto con los datos
|
|
9557
|
-
* @param fields -
|
|
9558
|
-
* @param options - Opciones
|
|
10364
|
+
* Construye el HTML para el preview de un objeto
|
|
10365
|
+
* @param data - Objeto con los datos a mostrar
|
|
10366
|
+
* @param fields - Configuración de los campos a mostrar
|
|
10367
|
+
* @param options - Opciones de configuración
|
|
10368
|
+
* @returns String con el HTML generado
|
|
10369
|
+
*
|
|
10370
|
+
* @example
|
|
10371
|
+
* ```typescript
|
|
10372
|
+
* const data = {
|
|
10373
|
+
* usuario: {
|
|
10374
|
+
* nombre: 'Juan Pérez',
|
|
10375
|
+
* email: 'juan@email.com'
|
|
10376
|
+
* },
|
|
10377
|
+
* estado: 1
|
|
10378
|
+
* };
|
|
10379
|
+
*
|
|
10380
|
+
* const fields = [
|
|
10381
|
+
* { key: 'usuario.nombre', label: 'Nombre' },
|
|
10382
|
+
* { key: 'usuario.email', label: 'Email' },
|
|
10383
|
+
* {
|
|
10384
|
+
* key: 'estado',
|
|
10385
|
+
* label: 'Estado',
|
|
10386
|
+
* referenceMap: new Map([[1, 'Activo'], [2, 'Inactivo']])
|
|
10387
|
+
* }
|
|
10388
|
+
* ];
|
|
10389
|
+
*
|
|
10390
|
+
* const html = this.formPreviewService.buildObjectSummaryHtml(data, fields, {
|
|
10391
|
+
* title: 'Datos del Usuario',
|
|
10392
|
+
* showEmpty: false,
|
|
10393
|
+
* compact: true,
|
|
10394
|
+
* debug: false
|
|
10395
|
+
* });
|
|
10396
|
+
* ```
|
|
9559
10397
|
*/
|
|
9560
10398
|
buildObjectSummaryHtml(data, fields, options) {
|
|
9561
10399
|
const debug = options?.debug ?? false;
|
|
9562
|
-
|
|
9563
|
-
|
|
10400
|
+
const isDev = !this.environment.production;
|
|
10401
|
+
// Solo ejecutar logs si estamos en desarrollo y debug está activado
|
|
10402
|
+
if (debug && isDev) {
|
|
9564
10403
|
this.debugInputData(data, fields, options);
|
|
9565
10404
|
}
|
|
10405
|
+
// Logs de error siempre se muestran en desarrollo si debug está activado
|
|
9566
10406
|
if (!data) {
|
|
9567
|
-
if (debug)
|
|
10407
|
+
if (debug && isDev) {
|
|
9568
10408
|
console.error('❌ FormPreview: data es null o undefined');
|
|
10409
|
+
}
|
|
9569
10410
|
return '';
|
|
9570
10411
|
}
|
|
9571
10412
|
if (!fields || fields.length === 0) {
|
|
9572
|
-
if (debug)
|
|
10413
|
+
if (debug && isDev) {
|
|
9573
10414
|
console.error('❌ FormPreview: fields está vacío');
|
|
10415
|
+
}
|
|
9574
10416
|
return '';
|
|
9575
10417
|
}
|
|
9576
10418
|
const showEmpty = options?.showEmpty ?? false;
|
|
9577
10419
|
const compact = options?.compact ?? true;
|
|
9578
|
-
const title = options?.title || 'Datos
|
|
10420
|
+
const title = options?.title || '📋 Datos a guardar';
|
|
9579
10421
|
const cells = [];
|
|
9580
10422
|
const propiedadesNoEncontradas = [];
|
|
9581
10423
|
for (const field of fields) {
|
|
9582
|
-
|
|
9583
|
-
|
|
10424
|
+
let value = this.getNestedValue(data, field.key);
|
|
10425
|
+
// Resolver referencia si existe
|
|
10426
|
+
if (field.referenceMap && value !== undefined && value !== null) {
|
|
10427
|
+
const originalValue = value;
|
|
10428
|
+
value = this.resolveReferenceValue(value, field);
|
|
10429
|
+
// Logs de depuración solo en desarrollo
|
|
10430
|
+
if (debug && isDev) {
|
|
10431
|
+
console.log(`🔍 Resolviendo referencia para "${field.key}":`, {
|
|
10432
|
+
original: originalValue,
|
|
10433
|
+
resuelto: value,
|
|
10434
|
+
tipoMapa: Array.isArray(field.referenceMap)
|
|
10435
|
+
? 'Array'
|
|
10436
|
+
: field.referenceMap instanceof Map
|
|
10437
|
+
? 'Map'
|
|
10438
|
+
: typeof field.referenceMap === 'function'
|
|
10439
|
+
? 'Función'
|
|
10440
|
+
: 'Objeto',
|
|
10441
|
+
});
|
|
10442
|
+
}
|
|
10443
|
+
}
|
|
9584
10444
|
const valueText = field.format
|
|
9585
10445
|
? field.format(value)
|
|
9586
10446
|
: this.formatValue(value);
|
|
9587
|
-
// Registrar si no se encontró la propiedad
|
|
9588
10447
|
if (value === undefined) {
|
|
9589
10448
|
propiedadesNoEncontradas.push(field.key);
|
|
9590
10449
|
}
|
|
9591
|
-
// Filtrar vacíos
|
|
9592
10450
|
if (!showEmpty && !valueText)
|
|
9593
10451
|
continue;
|
|
9594
10452
|
cells.push({
|
|
@@ -9596,8 +10454,8 @@ class FormPreviewService {
|
|
|
9596
10454
|
value: valueText || '—',
|
|
9597
10455
|
});
|
|
9598
10456
|
}
|
|
9599
|
-
//
|
|
9600
|
-
if (debug) {
|
|
10457
|
+
// Logs de depuración solo en desarrollo
|
|
10458
|
+
if (debug && isDev) {
|
|
9601
10459
|
if (propiedadesNoEncontradas.length > 0) {
|
|
9602
10460
|
console.warn('⚠️ FormPreview: Propiedades no encontradas:', propiedadesNoEncontradas);
|
|
9603
10461
|
console.warn('📋 Propiedades disponibles en data:', Object.keys(data));
|
|
@@ -9616,15 +10474,55 @@ class FormPreviewService {
|
|
|
9616
10474
|
return '';
|
|
9617
10475
|
return this.generateHtml(title, cells, compact);
|
|
9618
10476
|
}
|
|
10477
|
+
resolveReferenceValue(value, field) {
|
|
10478
|
+
if (Array.isArray(value)) {
|
|
10479
|
+
return value.map((item) => this.resolveSingleReference(item, field));
|
|
10480
|
+
}
|
|
10481
|
+
return this.resolveSingleReference(value, field);
|
|
10482
|
+
}
|
|
10483
|
+
resolveSingleReference(value, field) {
|
|
10484
|
+
if (!value)
|
|
10485
|
+
return value;
|
|
10486
|
+
if (typeof value === 'object' && value !== null)
|
|
10487
|
+
return value;
|
|
10488
|
+
const map = field.referenceMap;
|
|
10489
|
+
if (!map)
|
|
10490
|
+
return value;
|
|
10491
|
+
let referencedItem = null;
|
|
10492
|
+
if (typeof map === 'function') {
|
|
10493
|
+
referencedItem = map(value);
|
|
10494
|
+
}
|
|
10495
|
+
else if (map instanceof Map) {
|
|
10496
|
+
referencedItem = map.get(value);
|
|
10497
|
+
}
|
|
10498
|
+
else if (Array.isArray(map)) {
|
|
10499
|
+
const idKey = field.referenceId || 'id';
|
|
10500
|
+
referencedItem = map.find((item) => item[idKey] === value);
|
|
10501
|
+
}
|
|
10502
|
+
else if (typeof map === 'object') {
|
|
10503
|
+
referencedItem = map[String(value)];
|
|
10504
|
+
}
|
|
10505
|
+
if (referencedItem) {
|
|
10506
|
+
const labelProp = field.referenceLabel || 'nombre';
|
|
10507
|
+
if (typeof referencedItem === 'object' && referencedItem !== null) {
|
|
10508
|
+
if (referencedItem[labelProp] !== undefined &&
|
|
10509
|
+
referencedItem[labelProp] !== null) {
|
|
10510
|
+
return referencedItem[labelProp];
|
|
10511
|
+
}
|
|
10512
|
+
return referencedItem;
|
|
10513
|
+
}
|
|
10514
|
+
return referencedItem;
|
|
10515
|
+
}
|
|
10516
|
+
return value;
|
|
10517
|
+
}
|
|
9619
10518
|
getNestedValue(obj, path) {
|
|
9620
10519
|
if (!obj || !path)
|
|
9621
10520
|
return undefined;
|
|
9622
10521
|
const parts = path.split('.');
|
|
9623
10522
|
let result = obj;
|
|
9624
10523
|
for (const part of parts) {
|
|
9625
|
-
if (result === null || result === undefined)
|
|
10524
|
+
if (result === null || result === undefined)
|
|
9626
10525
|
return undefined;
|
|
9627
|
-
}
|
|
9628
10526
|
result = result[part];
|
|
9629
10527
|
}
|
|
9630
10528
|
return result;
|
|
@@ -9635,24 +10533,47 @@ class FormPreviewService {
|
|
|
9635
10533
|
if (value instanceof Date)
|
|
9636
10534
|
return value.toLocaleDateString();
|
|
9637
10535
|
if (typeof value === 'object') {
|
|
9638
|
-
|
|
9639
|
-
|
|
9640
|
-
|
|
9641
|
-
|
|
9642
|
-
|
|
9643
|
-
if (value.name)
|
|
9644
|
-
return String(value.name);
|
|
9645
|
-
if (value.value)
|
|
9646
|
-
return String(value.value);
|
|
9647
|
-
try {
|
|
9648
|
-
return JSON.stringify(value);
|
|
9649
|
-
}
|
|
9650
|
-
catch {
|
|
9651
|
-
return String(value);
|
|
10536
|
+
if (Array.isArray(value)) {
|
|
10537
|
+
return value
|
|
10538
|
+
.map((item) => this.formatSingleValue(item))
|
|
10539
|
+
.filter((v) => v)
|
|
10540
|
+
.join(', ');
|
|
9652
10541
|
}
|
|
10542
|
+
return this.formatSingleValue(value);
|
|
9653
10543
|
}
|
|
9654
10544
|
return String(value);
|
|
9655
10545
|
}
|
|
10546
|
+
formatSingleValue(value) {
|
|
10547
|
+
if (!value || typeof value !== 'object')
|
|
10548
|
+
return String(value);
|
|
10549
|
+
const props = [
|
|
10550
|
+
'label',
|
|
10551
|
+
'nombre',
|
|
10552
|
+
'name',
|
|
10553
|
+
'empresaNombre',
|
|
10554
|
+
'descripcion',
|
|
10555
|
+
'description',
|
|
10556
|
+
'text',
|
|
10557
|
+
'value',
|
|
10558
|
+
];
|
|
10559
|
+
for (const prop of props) {
|
|
10560
|
+
if (value[prop] !== undefined &&
|
|
10561
|
+
value[prop] !== null &&
|
|
10562
|
+
value[prop] !== '') {
|
|
10563
|
+
return String(value[prop]);
|
|
10564
|
+
}
|
|
10565
|
+
}
|
|
10566
|
+
if (value.id !== undefined && value.id !== null) {
|
|
10567
|
+
return `ID: ${value.id}`;
|
|
10568
|
+
}
|
|
10569
|
+
try {
|
|
10570
|
+
const json = JSON.stringify(value);
|
|
10571
|
+
return json.length > 50 ? json.substring(0, 50) + '...' : json;
|
|
10572
|
+
}
|
|
10573
|
+
catch {
|
|
10574
|
+
return '[Objeto]';
|
|
10575
|
+
}
|
|
10576
|
+
}
|
|
9656
10577
|
generateHtml(title, cells, compact) {
|
|
9657
10578
|
if (compact) {
|
|
9658
10579
|
return `
|
|
@@ -9679,7 +10600,6 @@ class FormPreviewService {
|
|
|
9679
10600
|
</div>
|
|
9680
10601
|
`;
|
|
9681
10602
|
}
|
|
9682
|
-
// Versión no compacta (con más padding)
|
|
9683
10603
|
return `
|
|
9684
10604
|
<div style="margin: 12px 0; border: 1px solid #dee2e6; border-radius: 8px; overflow: hidden; background: #ffffff;">
|
|
9685
10605
|
<div style="padding: 12px; background: #f8f9fa; border-bottom: 1px solid #dee2e6; font-weight: 600; color: #495057;">
|
|
@@ -9705,19 +10625,20 @@ class FormPreviewService {
|
|
|
9705
10625
|
`;
|
|
9706
10626
|
}
|
|
9707
10627
|
debugInputData(data, fields, options) {
|
|
10628
|
+
const isDev = !this.environment.production;
|
|
10629
|
+
if (!isDev)
|
|
10630
|
+
return;
|
|
9708
10631
|
console.group('🔍 FormPreview Debug');
|
|
9709
10632
|
console.log('📊 Data:', data);
|
|
9710
10633
|
console.log('📋 Propiedades disponibles:', data ? Object.keys(data) : 'data es null');
|
|
9711
10634
|
console.log('🎯 Fields solicitados:', fields);
|
|
9712
10635
|
console.log('⚙️ Options:', options);
|
|
9713
|
-
// Verificar cada campo
|
|
9714
10636
|
if (data) {
|
|
9715
10637
|
for (const field of fields) {
|
|
9716
10638
|
const value = this.getNestedValue(data, field.key);
|
|
9717
10639
|
const existe = value !== undefined;
|
|
9718
10640
|
if (!existe) {
|
|
9719
10641
|
console.warn(`❌ Campo "${field.key}" NO existe en data`);
|
|
9720
|
-
// Sugerir propiedades similares
|
|
9721
10642
|
const similares = this.findSimilarProperties(field.key, Object.keys(data));
|
|
9722
10643
|
if (similares.length > 0) {
|
|
9723
10644
|
console.warn(`💡 Quizás quisiste decir: ${similares.join(', ')}`);
|
|
@@ -9757,13 +10678,17 @@ class FormPreviewService {
|
|
|
9757
10678
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: FormPreviewService, decorators: [{
|
|
9758
10679
|
type: Injectable,
|
|
9759
10680
|
args: [{ providedIn: 'root' }]
|
|
9760
|
-
}] });
|
|
10681
|
+
}], ctorParameters: () => [] });
|
|
9761
10682
|
|
|
9762
10683
|
// table-preview.service.ts
|
|
9763
10684
|
class TablePreviewService {
|
|
10685
|
+
environment = inject(ENVIRONMENT);
|
|
10686
|
+
isProduction = this.environment?.production ?? false;
|
|
9764
10687
|
buildSingleRowSummaryHtml(row, columns, options) {
|
|
9765
|
-
const debug = options?.debug ?? false;
|
|
9766
|
-
|
|
10688
|
+
const debug = !this.isProduction && (options?.debug ?? false);
|
|
10689
|
+
const showRowId = options?.showRowId ?? false;
|
|
10690
|
+
const title = options?.title || '🗑️ Datos a eliminar';
|
|
10691
|
+
const icon = options?.icon || '';
|
|
9767
10692
|
if (debug) {
|
|
9768
10693
|
this.debugInputData(row, columns, options);
|
|
9769
10694
|
}
|
|
@@ -9783,33 +10708,50 @@ class TablePreviewService {
|
|
|
9783
10708
|
const rowId = options?.rowId?.trim() || '1';
|
|
9784
10709
|
const cells = [];
|
|
9785
10710
|
const propiedadesNoEncontradas = [];
|
|
10711
|
+
// Si showRowId está activo, agregamos una fila con el ID
|
|
10712
|
+
if (showRowId) {
|
|
10713
|
+
cells.push({ label: 'ID', value: rowId });
|
|
10714
|
+
}
|
|
9786
10715
|
for (const col of columns) {
|
|
9787
|
-
// Obtener key
|
|
9788
10716
|
const key = typeof col === 'string' ? col : col.key;
|
|
9789
|
-
|
|
10717
|
+
const formatFn = typeof col === 'object' ? col.format : undefined;
|
|
9790
10718
|
const value = this.getNestedValue(row, key);
|
|
9791
|
-
|
|
9792
|
-
|
|
10719
|
+
let valueText;
|
|
10720
|
+
if (formatFn && typeof formatFn === 'function') {
|
|
10721
|
+
try {
|
|
10722
|
+
valueText = formatFn(value, row) ?? '';
|
|
10723
|
+
}
|
|
10724
|
+
catch (error) {
|
|
10725
|
+
if (debug) {
|
|
10726
|
+
console.error(`❌ Error al formatear "${key}":`, error);
|
|
10727
|
+
}
|
|
10728
|
+
valueText = this.formatValue(value);
|
|
10729
|
+
}
|
|
10730
|
+
}
|
|
10731
|
+
else {
|
|
10732
|
+
valueText = this.formatValue(value);
|
|
10733
|
+
}
|
|
9793
10734
|
if (value === undefined) {
|
|
9794
10735
|
propiedadesNoEncontradas.push(key);
|
|
9795
10736
|
}
|
|
9796
|
-
|
|
9797
|
-
|
|
10737
|
+
const isEmpty = value === null ||
|
|
10738
|
+
value === undefined ||
|
|
10739
|
+
value === '' ||
|
|
10740
|
+
(Array.isArray(value) && value.length === 0);
|
|
10741
|
+
if (!includeEmpty && isEmpty)
|
|
9798
10742
|
continue;
|
|
9799
|
-
// Obtener label
|
|
9800
10743
|
let label = headerMap[key];
|
|
9801
10744
|
if (!label && typeof col === 'object' && col.label)
|
|
9802
10745
|
label = col.label;
|
|
9803
10746
|
if (!label)
|
|
9804
10747
|
label = this.humanizeKey(key);
|
|
9805
|
-
|
|
10748
|
+
const displayValue = isEmpty ? '—' : valueText;
|
|
10749
|
+
cells.push({ label, value: displayValue });
|
|
9806
10750
|
}
|
|
9807
|
-
// Solo mostrar logs si debug está activado
|
|
9808
10751
|
if (debug) {
|
|
9809
10752
|
if (propiedadesNoEncontradas.length > 0) {
|
|
9810
10753
|
console.warn('⚠️ TablePreview: Propiedades no encontradas:', propiedadesNoEncontradas);
|
|
9811
10754
|
console.warn('📋 Propiedades disponibles en rowData:', Object.keys(row));
|
|
9812
|
-
console.warn('💡 Sugerencia: Verifica que los nombres coincidan exactamente');
|
|
9813
10755
|
}
|
|
9814
10756
|
if (cells.length === 0) {
|
|
9815
10757
|
console.error('❌ TablePreview: No se generaron celdas. Verifica tus columnas y datos.');
|
|
@@ -9822,7 +10764,7 @@ class TablePreviewService {
|
|
|
9822
10764
|
}
|
|
9823
10765
|
if (!cells.length)
|
|
9824
10766
|
return '';
|
|
9825
|
-
return this.generateCompactHtml(
|
|
10767
|
+
return this.generateCompactHtml(cells, showLabel, title, icon);
|
|
9826
10768
|
}
|
|
9827
10769
|
getNestedValue(obj, path) {
|
|
9828
10770
|
if (!obj || !path)
|
|
@@ -9840,6 +10782,8 @@ class TablePreviewService {
|
|
|
9840
10782
|
formatValue(value) {
|
|
9841
10783
|
if (value === null || value === undefined)
|
|
9842
10784
|
return '';
|
|
10785
|
+
if (typeof value === 'number')
|
|
10786
|
+
return String(value);
|
|
9843
10787
|
if (value instanceof Date)
|
|
9844
10788
|
return value.toLocaleDateString();
|
|
9845
10789
|
if (typeof value === 'object') {
|
|
@@ -9861,30 +10805,29 @@ class TablePreviewService {
|
|
|
9861
10805
|
.map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())
|
|
9862
10806
|
.join(' ');
|
|
9863
10807
|
}
|
|
9864
|
-
generateCompactHtml(
|
|
9865
|
-
const rowIdWidth = Math.min(Math.max(rowId.length, 1), 3);
|
|
10808
|
+
generateCompactHtml(cells, showLabel, title, icon) {
|
|
9866
10809
|
return `
|
|
9867
10810
|
<div style="margin: 8px 0; border: 1px solid #e9ecef; border-radius: 6px; overflow: hidden; background: #ffffff; font-size: 13px;">
|
|
10811
|
+
<!-- Encabezado con título e ícono -->
|
|
10812
|
+
<div style="padding: 10px 12px; background: #f8f9fa; border-bottom: 1px solid #e9ecef; font-weight: 600; color: #212529; text-align: center; font-size: 14px;">
|
|
10813
|
+
${icon ? `<span style="margin-right: 8px; font-size: 18px;">${icon}</span>` : ''}
|
|
10814
|
+
${this.escapeHtml(title)}
|
|
10815
|
+
</div>
|
|
10816
|
+
|
|
10817
|
+
<!-- Tabla de datos -->
|
|
9868
10818
|
<table style="width: 100%; border-collapse: collapse; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;">
|
|
9869
10819
|
<tbody>
|
|
9870
10820
|
${cells
|
|
9871
10821
|
.map((cell, i) => `
|
|
9872
10822
|
<tr style="border-bottom: ${i < cells.length - 1 ? '0.5px solid #f1f3f5' : 'none'}">
|
|
9873
|
-
${i === 0
|
|
9874
|
-
? `
|
|
9875
|
-
<td style="padding: 6px 8px; background: #f8f9fa; font-weight: 600; color: #6c757d; border-right: 0.5px solid #f1f3f5; vertical-align: top;">
|
|
9876
|
-
${this.escapeHtml(rowId)}
|
|
9877
|
-
</td>
|
|
9878
|
-
`
|
|
9879
|
-
: ''}
|
|
9880
10823
|
${showLabel
|
|
9881
10824
|
? `
|
|
9882
|
-
<td style="padding:
|
|
10825
|
+
<td style="padding: 8px 12px; background: #f8f9fa; text-transform: uppercase; width: 40%; color: #6c757d; border-right: 0.5px solid #f1f3f5; font-weight: 600; font-size: 11px; letter-spacing: 0.3px;">
|
|
9883
10826
|
${this.escapeHtml(cell.label)}
|
|
9884
10827
|
</td>
|
|
9885
10828
|
`
|
|
9886
10829
|
: ''}
|
|
9887
|
-
<td style="padding:
|
|
10830
|
+
<td style="padding: 8px 12px; color: #212529; font-weight: 500;">
|
|
9888
10831
|
${this.escapeHtml(cell.value)}
|
|
9889
10832
|
</td>
|
|
9890
10833
|
</tr>
|
|
@@ -9901,7 +10844,6 @@ class TablePreviewService {
|
|
|
9901
10844
|
console.log('📋 Propiedades disponibles:', row ? Object.keys(row) : 'row es null');
|
|
9902
10845
|
console.log('🎯 Columns solicitadas:', columns);
|
|
9903
10846
|
console.log('⚙️ Options:', options);
|
|
9904
|
-
// Verificar cada columna
|
|
9905
10847
|
if (row) {
|
|
9906
10848
|
for (const col of columns) {
|
|
9907
10849
|
const key = typeof col === 'string' ? col : col.key;
|
|
@@ -9909,7 +10851,6 @@ class TablePreviewService {
|
|
|
9909
10851
|
const existe = value !== undefined;
|
|
9910
10852
|
if (!existe) {
|
|
9911
10853
|
console.warn(`❌ Propiedad "${key}" NO existe en rowData`);
|
|
9912
|
-
// Sugerir propiedades similares
|
|
9913
10854
|
const similares = this.findSimilarProperties(key, Object.keys(row));
|
|
9914
10855
|
if (similares.length > 0) {
|
|
9915
10856
|
console.warn(`💡 Quizás quisiste decir: ${similares.join(', ')}`);
|
|
@@ -9927,16 +10868,14 @@ class TablePreviewService {
|
|
|
9927
10868
|
const searchLower = search.toLowerCase();
|
|
9928
10869
|
for (const prop of properties) {
|
|
9929
10870
|
const propLower = prop.toLowerCase();
|
|
9930
|
-
// Buscar similitudes (contiene o es similar)
|
|
9931
10871
|
if (propLower.includes(searchLower) || searchLower.includes(propLower)) {
|
|
9932
10872
|
similares.push(prop);
|
|
9933
10873
|
}
|
|
9934
|
-
// Distancia de Levenshtein simple (máximo 3 caracteres de diferencia)
|
|
9935
10874
|
else if (this.levenshteinDistance(searchLower, propLower) <= 3) {
|
|
9936
10875
|
similares.push(prop);
|
|
9937
10876
|
}
|
|
9938
10877
|
}
|
|
9939
|
-
return similares.slice(0, 3);
|
|
10878
|
+
return similares.slice(0, 3);
|
|
9940
10879
|
}
|
|
9941
10880
|
levenshteinDistance(a, b) {
|
|
9942
10881
|
if (a.length === 0)
|
|
@@ -10376,7 +11315,7 @@ function buildAlreadyExistsMessage(control, options) {
|
|
|
10376
11315
|
* Validador asíncrono que verifica si un valor ya existe mediante una llamada a un servicio.
|
|
10377
11316
|
* Útil para validar unicidad de campos como nombres de usuario, correos electrónicos, etc.
|
|
10378
11317
|
*
|
|
10379
|
-
* Aplica `debounceTime(
|
|
11318
|
+
* Aplica `debounceTime(800)` y `distinctUntilChanged()` para evitar llamadas innecesarias
|
|
10380
11319
|
* al servicio mientras el usuario escribe.
|
|
10381
11320
|
*
|
|
10382
11321
|
* @template T Tipo del valor del control a validar.
|
|
@@ -10384,39 +11323,93 @@ function buildAlreadyExistsMessage(control, options) {
|
|
|
10384
11323
|
* el identificador del registro actual. Debe retornar un `Observable<boolean>`
|
|
10385
11324
|
* emitiendo `true` si el valor ya existe (en otro registro), `false` en caso contrario.
|
|
10386
11325
|
* @param options Opciones del validador:
|
|
10387
|
-
* - `currentId`: Id
|
|
11326
|
+
* - `currentId`: Id fijo del registro en edición para excluirlo en backend.
|
|
11327
|
+
* ⚠️ Útil cuando el ID no cambia durante la vida del validador.
|
|
11328
|
+
* - `getCurrentId`: Función que obtiene el ID en tiempo real.
|
|
11329
|
+
* ✅ **RECOMENDADO** cuando el ID puede cambiar (ej: signals, componentes reactivos).
|
|
11330
|
+
* Si se proporciona, tiene prioridad sobre `currentId`.
|
|
10388
11331
|
* - `fieldName`: Nombre del campo para construir el mensaje dinámico
|
|
10389
11332
|
* (si se omite, se intenta inferir del control).
|
|
10390
11333
|
* - `errorMessage`: Mensaje personalizado (si se omite y se resuelve nombre
|
|
10391
11334
|
* de campo, se usa `El valor {campo} ya existe`).
|
|
11335
|
+
* - `debug`: Si es `true`, muestra logs en consola para depuración.
|
|
10392
11336
|
* @returns Un `AsyncValidatorFn` que emite `null` si el valor no existe o el control está vacío,
|
|
10393
11337
|
* o un objeto `ValidationErrors` con la clave fija `alreadyValueExists` si el valor ya existe.
|
|
10394
11338
|
*
|
|
10395
11339
|
* @example
|
|
10396
11340
|
* ```ts
|
|
10397
|
-
* // Creación
|
|
11341
|
+
* // EJEMPLO 1: Creación (ID fijo o sin ID)
|
|
10398
11342
|
* email: ['', [], asyncExistsValidator(
|
|
10399
11343
|
* (value, id) => this.userService.emailExists({ value, id: Number(id) })
|
|
10400
11344
|
* )]
|
|
10401
11345
|
*
|
|
10402
|
-
* // Edición (
|
|
11346
|
+
* // EJEMPLO 2: Edición con ID fijo (cuando el ID no cambia)
|
|
11347
|
+
* email: ['', [], asyncExistsValidator(
|
|
11348
|
+
* (value, id) => this.userService.emailExists(value, id),
|
|
11349
|
+
* { currentId: this.userId, fieldName: 'email' }
|
|
11350
|
+
* )]
|
|
11351
|
+
*
|
|
11352
|
+
* // EJEMPLO 3: Edición con ID dinámico (RECOMENDADO con signals)
|
|
10403
11353
|
* email: ['', [], asyncExistsValidator(
|
|
10404
11354
|
* (value, id) => this.userService.emailExists(value, id),
|
|
10405
|
-
* {
|
|
11355
|
+
* {
|
|
11356
|
+
* getCurrentId: () => this.id(), // ✅ Obtiene el ID en tiempo real
|
|
11357
|
+
* fieldName: 'email',
|
|
11358
|
+
* debug: true // Para depuración
|
|
11359
|
+
* }
|
|
11360
|
+
* )]
|
|
11361
|
+
*
|
|
11362
|
+
* // EJEMPLO 4: Con mensaje personalizado
|
|
11363
|
+
* codigo: ['', [], asyncExistsValidator(
|
|
11364
|
+
* (value, id) => this.productService.codigoExists(value, id),
|
|
11365
|
+
* {
|
|
11366
|
+
* getCurrentId: () => this.productId(),
|
|
11367
|
+
* errorMessage: 'El código de producto ya está registrado',
|
|
11368
|
+
* fieldName: 'código de producto'
|
|
11369
|
+
* }
|
|
10406
11370
|
* )]
|
|
10407
11371
|
* ```
|
|
10408
11372
|
*/
|
|
10409
11373
|
function asyncExistsValidator(serviceMethod, options = {}) {
|
|
10410
|
-
const { currentId = null, fieldName, errorMessage } = options;
|
|
11374
|
+
const { currentId = null, fieldName, errorMessage, debug = false, getCurrentId, } = options;
|
|
10411
11375
|
const errorKey = 'alreadyValueExists';
|
|
10412
11376
|
return (control) => {
|
|
10413
|
-
if (!control.value)
|
|
11377
|
+
if (!control.value) {
|
|
11378
|
+
if (debug)
|
|
11379
|
+
console.log('[AsyncExistsValidator] Control value is empty, returning null');
|
|
10414
11380
|
return of(null);
|
|
11381
|
+
}
|
|
11382
|
+
// Obtener el ID: prioridad a getCurrentId, luego currentId, luego 0
|
|
11383
|
+
const resolvedId = getCurrentId ? getCurrentId() : currentId;
|
|
11384
|
+
const finalId = resolvedId ?? 0;
|
|
11385
|
+
if (debug) {
|
|
11386
|
+
console.log('[AsyncExistsValidator] Starting validation for:', {
|
|
11387
|
+
value: control.value,
|
|
11388
|
+
currentId: finalId,
|
|
11389
|
+
fieldName,
|
|
11390
|
+
errorMessage,
|
|
11391
|
+
debug,
|
|
11392
|
+
usingGetCurrentId: !!getCurrentId,
|
|
11393
|
+
});
|
|
11394
|
+
}
|
|
10415
11395
|
return of(control.value).pipe(debounceTime$1(800), distinctUntilChanged$1(), switchMap$1((value) => {
|
|
10416
|
-
|
|
10417
|
-
|
|
11396
|
+
if (debug) {
|
|
11397
|
+
console.log('[AsyncExistsValidator] Calling service method with:', {
|
|
11398
|
+
value: value,
|
|
11399
|
+
resolvedId: finalId,
|
|
11400
|
+
});
|
|
11401
|
+
}
|
|
11402
|
+
return serviceMethod(value, finalId);
|
|
10418
11403
|
}), map((exists) => {
|
|
11404
|
+
if (debug) {
|
|
11405
|
+
console.log('[AsyncExistsValidator] Service response:', {
|
|
11406
|
+
exists,
|
|
11407
|
+
value: control.value,
|
|
11408
|
+
});
|
|
11409
|
+
}
|
|
10419
11410
|
if (exists) {
|
|
11411
|
+
if (debug)
|
|
11412
|
+
console.log('[AsyncExistsValidator] Validation failed - value already exists');
|
|
10420
11413
|
return {
|
|
10421
11414
|
[errorKey]: {
|
|
10422
11415
|
message: buildAlreadyExistsMessage(control, {
|
|
@@ -10427,8 +11420,15 @@ function asyncExistsValidator(serviceMethod, options = {}) {
|
|
|
10427
11420
|
},
|
|
10428
11421
|
};
|
|
10429
11422
|
}
|
|
11423
|
+
if (debug)
|
|
11424
|
+
console.log('[AsyncExistsValidator] Validation passed - value is available');
|
|
10430
11425
|
return null;
|
|
10431
|
-
}), catchError(() =>
|
|
11426
|
+
}), catchError((error) => {
|
|
11427
|
+
if (debug) {
|
|
11428
|
+
console.error('[AsyncExistsValidator] Error occurred:', error);
|
|
11429
|
+
}
|
|
11430
|
+
return of(null);
|
|
11431
|
+
}));
|
|
10432
11432
|
};
|
|
10433
11433
|
}
|
|
10434
11434
|
function templateVariablesValidator(allowedKeys) {
|
|
@@ -10599,5 +11599,5 @@ function sorensenDiceValidator(dataSource, key, umbral = 0.7) {
|
|
|
10599
11599
|
* Generated bundle index. Do not edit.
|
|
10600
11600
|
*/
|
|
10601
11601
|
|
|
10602
|
-
export { ACTION_TYPES, AlertaService, AppMessageErrorComponent, AppMessageHelpComponent, ArrowNavigationDirective, AuthorizeService, AutoScrollHeightDirective, BaseCRUDService, CACHE_KEYS, CacheService, CssV2Component, DSX_PALETTE, DateIndicator, DocxPreviewComponent, DsxAddToolsModule, DsxAutocomplete, DsxButtonComponent, DsxEnableDisable, DsxMessagesService, DsxSelect, DsxStatusToggle, DteService, ENVIRONMENT, EndpointService, ErrorHandlerService, FileComponent, FormPreviewService, GTQFormatter, HeaderDsx, HelpersService, HttpHelpersService, INITIAL_PARAMETERS, IcoLabel, IconDsxComponent, JoinByPipe, JsonHighlightPipe, JsonValuesDebujComponent, JsonViewerComponent, KpicardComponent, LoadingComponent, LoadingLottieComponent, LogoDsxComponent, MasterDetailChangeService, NavbarDsxComponent, NetworkStatusComponent, OnlyRangoPatternDirective, ParameterValuesService, PdfPreviewComponent, PrimeNgModule, QrGenerator, ResultFileService, SWEET_ALERT_THEMES, ScreenInspector, SecurityService, SelectAllOnFocusDirective, SpinnerLoadingService, SweetAlert2DialogService, TablePreviewService, TemplateHighlight, TokenPurposeLogin, TruncatePipe, UtilityAddService, asyncExistsValidator, atLeastOneFieldRequiredValidator, chainControlGroups, createCurrencyFormatter, createInitialCache, createTypedCacheProvider, cuiValidator, dateMinMaxValidator, dateRangeValidator, dateRangeValidatorFromTo, developmentEnvironment, getActionMessageConfig, getZeroBasedRolIndex, guardTokenPurposeGuard, httpAuthorizeInterceptor, minimumAgeValidator, nitValidator, productionEnvironment, provideEnvironment, sorensenDiceValidator, templateStructureValidator, templateVariablesValidator, validateEnvironmentConfig };
|
|
11602
|
+
export { ACTION_TYPES, AlertaService, AppMessageErrorComponent, AppMessageHelpComponent, ArrowNavigationDirective, AuthorizeService, AutoScrollHeightDirective, BaseCRUDService, CACHE_KEYS, CacheService, CssV2Component, DSX_PALETTE, DateIndicator, DocxPreviewComponent, DsxAddToolsModule, DsxAutocomplete, DsxButtonComponent, DsxEnableDisable, DsxInputCurrency, DsxMessagesService, DsxSelect, DsxStatusToggle, DsxdateShort, DteService, ENVIRONMENT, EndpointService, ErrorHandlerService, FileComponent, FormPreviewService, GTQFormatter, HeaderDsx, HelpersService, HttpHelpersService, INITIAL_PARAMETERS, IcoLabel, IconDsxComponent, JoinByPipe, JsonHighlightPipe, JsonValuesDebujComponent, JsonViewerComponent, KpicardComponent, LoadingComponent, LoadingLottieComponent, LogoDsxComponent, MasterDetailChangeService, NavbarDsxComponent, NetworkStatusComponent, OnlyRangoPatternDirective, ParameterValuesService, PdfPreviewComponent, PrimeNgModule, QrGenerator, ResultFileService, SWEET_ALERT_THEMES, ScreenInspector, SecurityService, SelectAllOnFocusDirective, SpinnerLoadingService, SweetAlert2DialogService, TablePreviewService, TemplateHighlight, TokenPurposeLogin, TruncatePipe, UtilityAddService, asyncExistsValidator, atLeastOneFieldRequiredValidator, chainControlGroups, createCurrencyFormatter, createInitialCache, createTypedCacheProvider, cuiValidator, dateMinMaxValidator, dateRangeValidator, dateRangeValidatorFromTo, developmentEnvironment, getActionMessageConfig, getZeroBasedRolIndex, guardTokenPurposeGuard, httpAuthorizeInterceptor, minimumAgeValidator, nitValidator, productionEnvironment, provideEnvironment, sorensenDiceValidator, templateStructureValidator, templateVariablesValidator, validateEnvironmentConfig };
|
|
10603
11603
|
//# sourceMappingURL=ngx-dsxlibrary.mjs.map
|