ngx-dsxlibrary 2.21.74 → 2.21.76
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-components.mjs +105 -8
- package/fesm2022/ngx-dsxlibrary-src-lib-components.mjs.map +1 -1
- package/fesm2022/ngx-dsxlibrary-src-lib-utils.mjs +94 -1
- package/fesm2022/ngx-dsxlibrary-src-lib-utils.mjs.map +1 -1
- package/fesm2022/ngx-dsxlibrary.mjs +994 -121
- package/fesm2022/ngx-dsxlibrary.mjs.map +1 -1
- package/ngx-dsxlibrary-2.21.76.tgz +0 -0
- package/package.json +1 -1
- package/types/ngx-dsxlibrary-src-lib-components.d.ts +19 -1
- package/types/ngx-dsxlibrary-src-lib-models.d.ts +6 -1
- package/types/ngx-dsxlibrary-src-lib-utils.d.ts +22 -1
- package/types/ngx-dsxlibrary.d.ts +367 -90
- package/ngx-dsxlibrary-2.21.74.tgz +0 -0
|
@@ -5,7 +5,7 @@ import { FormsModule, NG_VALUE_ACCESSOR, AbstractControl, FormControl, NG_VALIDA
|
|
|
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, JsonPipe, DecimalPipe,
|
|
8
|
+
import { CommonModule, AsyncPipe, JsonPipe, DecimalPipe, Location } 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';
|
|
@@ -18,6 +18,8 @@ import * as i2$3 from 'primeng/avatar';
|
|
|
18
18
|
import { AvatarModule, Avatar } from 'primeng/avatar';
|
|
19
19
|
import * as i2$2 from 'primeng/dialog';
|
|
20
20
|
import { DialogModule } from 'primeng/dialog';
|
|
21
|
+
import * as i4 from 'primeng/button';
|
|
22
|
+
import { ButtonModule, Button } from 'primeng/button';
|
|
21
23
|
import * as i1$4 from '@angular/platform-browser';
|
|
22
24
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
23
25
|
import * as i1$5 from 'primeng/tabs';
|
|
@@ -27,8 +29,6 @@ import * as i1$6 from '@angular/common/http';
|
|
|
27
29
|
import { HttpClient, HttpHeaders, HttpParams, HttpErrorResponse, HttpStatusCode } from '@angular/common/http';
|
|
28
30
|
import { debounceTime, distinctUntilChanged, switchMap, shareReplay as shareReplay$1, map as map$1, take as take$1 } from 'rxjs/operators';
|
|
29
31
|
import { Router, RouterLink } from '@angular/router';
|
|
30
|
-
import * as i1$7 from 'primeng/button';
|
|
31
|
-
import { Button, ButtonModule } from 'primeng/button';
|
|
32
32
|
import moment from 'moment-timezone';
|
|
33
33
|
import { ToastrService } from 'ngx-toastr';
|
|
34
34
|
import Swal from 'sweetalert2';
|
|
@@ -37,7 +37,7 @@ import { LottieComponent } from 'ngx-lottie';
|
|
|
37
37
|
import { createTimeline } from 'animejs';
|
|
38
38
|
import * as i3$1 from 'primeng/image';
|
|
39
39
|
import { ImageModule } from 'primeng/image';
|
|
40
|
-
import * as i4 from 'primeng/menubar';
|
|
40
|
+
import * as i4$1 from 'primeng/menubar';
|
|
41
41
|
import { MenubarModule } from 'primeng/menubar';
|
|
42
42
|
import { JwtHelperService } from '@auth0/angular-jwt';
|
|
43
43
|
import { CookieService } from 'ngx-cookie-service';
|
|
@@ -52,6 +52,7 @@ import { AvatarGroupModule } from 'primeng/avatargroup';
|
|
|
52
52
|
import { BadgeModule } from 'primeng/badge';
|
|
53
53
|
import { CardModule } from 'primeng/card';
|
|
54
54
|
import { CheckboxModule } from 'primeng/checkbox';
|
|
55
|
+
import { ChipModule } from 'primeng/chip';
|
|
55
56
|
import { ContextMenuModule } from 'primeng/contextmenu';
|
|
56
57
|
import { DataViewModule } from 'primeng/dataview';
|
|
57
58
|
import { DatePickerModule, DatePicker } from 'primeng/datepicker';
|
|
@@ -60,7 +61,7 @@ import { DrawerModule } from 'primeng/drawer';
|
|
|
60
61
|
import { FieldsetModule } from 'primeng/fieldset';
|
|
61
62
|
import { IconFieldModule } from 'primeng/iconfield';
|
|
62
63
|
import { InputIconModule } from 'primeng/inputicon';
|
|
63
|
-
import * as i1$
|
|
64
|
+
import * as i1$7 from 'primeng/inputmask';
|
|
64
65
|
import { InputMaskModule } from 'primeng/inputmask';
|
|
65
66
|
import { InputNumberModule, InputNumber } from 'primeng/inputnumber';
|
|
66
67
|
import { InputTextModule } from 'primeng/inputtext';
|
|
@@ -833,7 +834,33 @@ class PdfPreviewComponent {
|
|
|
833
834
|
visible = model(false, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
834
835
|
blob = input(null, ...(ngDevMode ? [{ debugName: "blob" }] : /* istanbul ignore next */ []));
|
|
835
836
|
objectUrl = null;
|
|
836
|
-
|
|
837
|
+
fileUrl = null;
|
|
838
|
+
fileType = null;
|
|
839
|
+
fileName = '';
|
|
840
|
+
fileSize = '';
|
|
841
|
+
rawBlob = null;
|
|
842
|
+
mimeTypeMap = {
|
|
843
|
+
'application/pdf': 'PDF',
|
|
844
|
+
'image/jpeg': 'JPEG',
|
|
845
|
+
'image/png': 'PNG',
|
|
846
|
+
'image/gif': 'GIF',
|
|
847
|
+
'image/webp': 'WebP',
|
|
848
|
+
};
|
|
849
|
+
supportedTypes = [
|
|
850
|
+
'application/pdf',
|
|
851
|
+
'image/jpeg',
|
|
852
|
+
'image/png',
|
|
853
|
+
'image/gif',
|
|
854
|
+
'image/webp',
|
|
855
|
+
];
|
|
856
|
+
// Mapeo de iconos por tipo
|
|
857
|
+
iconMap = {
|
|
858
|
+
'application/pdf': 'pi pi-file-pdf',
|
|
859
|
+
'image/jpeg': 'pi pi-image',
|
|
860
|
+
'image/png': 'pi pi-image',
|
|
861
|
+
'image/gif': 'pi pi-image',
|
|
862
|
+
'image/webp': 'pi pi-image',
|
|
863
|
+
};
|
|
837
864
|
constructor(sanitizer) {
|
|
838
865
|
this.sanitizer = sanitizer;
|
|
839
866
|
effect((onCleanup) => {
|
|
@@ -841,43 +868,112 @@ class PdfPreviewComponent {
|
|
|
841
868
|
const isVisible = this.visible();
|
|
842
869
|
if (!isVisible || file === null) {
|
|
843
870
|
this.limpiarUrlAnterior();
|
|
871
|
+
this.fileName = '';
|
|
872
|
+
this.fileSize = '';
|
|
873
|
+
this.fileType = null;
|
|
874
|
+
this.rawBlob = null;
|
|
844
875
|
return;
|
|
845
876
|
}
|
|
846
|
-
if (file
|
|
877
|
+
if (!this.isFileSupported(file)) {
|
|
847
878
|
this.limpiarUrlAnterior();
|
|
848
|
-
console.warn('
|
|
879
|
+
console.warn('Tipo de archivo no soportado:', file.type);
|
|
880
|
+
this.fileType = null;
|
|
881
|
+
this.rawBlob = null;
|
|
849
882
|
return;
|
|
850
883
|
}
|
|
884
|
+
this.rawBlob = file;
|
|
885
|
+
this.fileType = file.type;
|
|
886
|
+
this.fileName = this.getFileNameFromBlob(file);
|
|
887
|
+
this.fileSize = this.formatFileSize(file.size);
|
|
851
888
|
this.limpiarUrlAnterior();
|
|
852
889
|
const currentObjectUrl = URL.createObjectURL(file);
|
|
853
890
|
this.objectUrl = currentObjectUrl;
|
|
854
|
-
this.
|
|
891
|
+
this.fileUrl =
|
|
855
892
|
this.sanitizer.bypassSecurityTrustResourceUrl(currentObjectUrl);
|
|
856
893
|
onCleanup(() => {
|
|
857
894
|
URL.revokeObjectURL(currentObjectUrl);
|
|
858
895
|
if (this.objectUrl === currentObjectUrl) {
|
|
859
896
|
this.objectUrl = null;
|
|
860
|
-
this.
|
|
897
|
+
this.fileUrl = null;
|
|
861
898
|
}
|
|
862
899
|
});
|
|
863
900
|
});
|
|
864
901
|
}
|
|
902
|
+
isFileSupported(file) {
|
|
903
|
+
return this.supportedTypes.includes(file.type);
|
|
904
|
+
}
|
|
905
|
+
getFileNameFromBlob(blob) {
|
|
906
|
+
if (blob.name) {
|
|
907
|
+
return blob.name;
|
|
908
|
+
}
|
|
909
|
+
const extension = this.mimeTypeMap[blob.type] || 'archivo';
|
|
910
|
+
return `documento_soporte.${extension.toLowerCase()}`;
|
|
911
|
+
}
|
|
912
|
+
formatFileSize(bytes) {
|
|
913
|
+
if (bytes === 0)
|
|
914
|
+
return '0 Bytes';
|
|
915
|
+
const k = 1024;
|
|
916
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
917
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
918
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
919
|
+
}
|
|
865
920
|
limpiarUrlAnterior() {
|
|
866
921
|
if (this.objectUrl) {
|
|
867
922
|
URL.revokeObjectURL(this.objectUrl);
|
|
868
923
|
this.objectUrl = null;
|
|
869
924
|
}
|
|
870
|
-
this.
|
|
925
|
+
this.fileUrl = null;
|
|
926
|
+
}
|
|
927
|
+
// Getters para el template
|
|
928
|
+
get isPdf() {
|
|
929
|
+
return this.fileType === 'application/pdf';
|
|
930
|
+
}
|
|
931
|
+
get isImage() {
|
|
932
|
+
return this.fileType?.startsWith('image/') || false;
|
|
933
|
+
}
|
|
934
|
+
get fileTypeLabel() {
|
|
935
|
+
return this.fileType
|
|
936
|
+
? this.mimeTypeMap[this.fileType] || this.fileType
|
|
937
|
+
: '';
|
|
938
|
+
}
|
|
939
|
+
getFileIcon() {
|
|
940
|
+
if (!this.fileType)
|
|
941
|
+
return 'pi pi-file';
|
|
942
|
+
return this.iconMap[this.fileType] || 'pi pi-file';
|
|
943
|
+
}
|
|
944
|
+
// Descargar archivo
|
|
945
|
+
downloadFile() {
|
|
946
|
+
if (!this.rawBlob || !this.fileName) {
|
|
947
|
+
console.warn('No hay archivo para descargar');
|
|
948
|
+
return;
|
|
949
|
+
}
|
|
950
|
+
const link = document.createElement('a');
|
|
951
|
+
link.href = URL.createObjectURL(this.rawBlob);
|
|
952
|
+
link.download = this.fileName;
|
|
953
|
+
document.body.appendChild(link);
|
|
954
|
+
link.click();
|
|
955
|
+
document.body.removeChild(link);
|
|
956
|
+
// Limpiar URL creada para la descarga
|
|
957
|
+
setTimeout(() => {
|
|
958
|
+
URL.revokeObjectURL(link.href);
|
|
959
|
+
}, 100);
|
|
960
|
+
}
|
|
961
|
+
// Eventos de imagen
|
|
962
|
+
onImageLoad() {
|
|
963
|
+
console.log('Imagen cargada correctamente');
|
|
964
|
+
}
|
|
965
|
+
onImageError() {
|
|
966
|
+
console.warn('Error al cargar la imagen');
|
|
871
967
|
}
|
|
872
968
|
ngOnDestroy() {
|
|
873
969
|
this.limpiarUrlAnterior();
|
|
874
970
|
}
|
|
875
971
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: PdfPreviewComponent, deps: [{ token: i1$4.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
|
|
876
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: PdfPreviewComponent, isStandalone: true, selector: "app-pdf-preview", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, blob: { classPropertyName: "blob", publicName: "blob", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange" }, ngImport: i0, template: "<p-dialog\r\n
|
|
972
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: PdfPreviewComponent, isStandalone: true, selector: "app-pdf-preview", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, blob: { classPropertyName: "blob", publicName: "blob", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange" }, ngImport: i0, template: "<p-dialog\r\n [(visible)]=\"visible\"\r\n [style]=\"{ width: '80vw', height: '90vh' }\"\r\n [closable]=\"true\"\r\n [maximizable]=\"true\"\r\n [modal]=\"true\"\r\n>\r\n <!-- Header personalizado -->\r\n <ng-template pTemplate=\"header\">\r\n <div class=\"dialog-header\">\r\n <div class=\"header-left\">\r\n <i [class]=\"getFileIcon()\" class=\"file-icon\"></i>\r\n <div class=\"header-info\">\r\n <span class=\"header-title\"\r\n >Vista previa del documento de soporte</span\r\n >\r\n @if (fileName) {\r\n <div class=\"header-details\">\r\n <span class=\"file-name\">{{ fileName }}</span>\r\n <span class=\"file-meta\">\r\n <span class=\"file-type\">{{ fileTypeLabel }}</span>\r\n <span class=\"file-size\">{{ fileSize }}</span>\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n <div class=\"header-actions\">\r\n @if (fileUrl) {\r\n <button\r\n pButton\r\n type=\"button\"\r\n icon=\"pi pi-download\"\r\n class=\"p-button-rounded p-button-text p-button-sm\"\r\n (click)=\"downloadFile()\"\r\n pTooltip=\"Descargar archivo\"\r\n tooltipPosition=\"top\"\r\n ></button>\r\n }\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Contenido -->\r\n <div class=\"preview-wrapper\">\r\n <!-- Caso: Sin archivo -->\r\n @if (!fileUrl) {\r\n <div class=\"empty-state\">\r\n <i class=\"pi pi-file\"></i>\r\n <p>No hay archivo seleccionado</p>\r\n </div>\r\n }\r\n <!-- Caso: PDF -->\r\n @else if (isPdf) {\r\n <iframe\r\n [src]=\"fileUrl\"\r\n width=\"100%\"\r\n height=\"100%\"\r\n style=\"border: none\"\r\n class=\"pdf-iframe\"\r\n ></iframe>\r\n }\r\n <!-- Caso: Imagen -->\r\n @else if (isImage) {\r\n <div class=\"image-container\">\r\n <img\r\n [src]=\"fileUrl\"\r\n [alt]=\"fileName || 'Vista previa de imagen'\"\r\n class=\"preview-image\"\r\n (load)=\"onImageLoad()\"\r\n (error)=\"onImageError()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n</p-dialog>\r\n", styles: [".dialog-header{display:flex;align-items:center;justify-content:space-between;width:100%;padding:.5rem 0;gap:1rem}.header-left{display:flex;align-items:center;gap:.75rem;min-width:0;flex:1}.file-icon{font-size:1.5rem;color:var(--primary-color, #3b82f6);flex-shrink:0}.header-info{display:flex;flex-direction:column;gap:.125rem;min-width:0}.header-title{font-size:1rem;font-weight:600;color:var(--text-color, #333);line-height:1.3}.header-details{display:flex;align-items:center;gap:.75rem;font-size:.8rem;color:var(--text-color-secondary, #666);flex-wrap:wrap}.file-name{font-weight:500;color:var(--text-color, #333);max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-meta{display:flex;align-items:center;gap:.5rem}.file-type{background:var(--surface-hover, #f0f0f0);padding:.0625rem .5rem;border-radius:12px;font-size:.7rem;font-weight:500;color:var(--text-color-secondary, #666)}.file-size{font-size:.75rem;color:var(--text-color-secondary, #666)}.header-actions{display:flex;align-items:center;gap:.5rem;flex-shrink:0}.header-actions ::ng-deep .p-button.p-button-text{color:var(--text-color-secondary, #666)}.header-actions ::ng-deep .p-button.p-button-text:hover{color:var(--primary-color, #3b82f6);background:var(--surface-hover, #f0f0f0)}.preview-wrapper{width:100%;height:calc(100% - 10px);min-height:400px;position:relative;background:var(--surface-ground, #f8f9fa);border-radius:4px;overflow:hidden}.pdf-iframe{width:100%;height:100%;border:none;background:#fff}.image-container{width:100%;height:100%;display:flex;align-items:center;justify-content:center;padding:1rem;background:var(--surface-ground, #f8f9fa)}.preview-image{max-width:100%;max-height:100%;object-fit:contain;border-radius:4px;box-shadow:0 2px 8px #0000001a;transition:transform .2s}.preview-image:hover{transform:scale(1.02)}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1rem;color:var(--text-color-secondary, #666);height:100%;min-height:400px}.empty-state i{font-size:4rem;opacity:.4;color:var(--text-color-secondary, #666)}.empty-state p{margin:0;font-size:1rem;font-weight:400}@media(max-width:768px){.dialog-header{flex-direction:column;align-items:stretch;gap:.5rem;padding:.25rem 0}.header-left{gap:.5rem}.file-icon{font-size:1.25rem}.header-title{font-size:.9rem}.header-details{font-size:.7rem;gap:.5rem}.file-name{max-width:150px}.header-actions{justify-content:flex-end;padding-top:.25rem;border-top:1px solid var(--surface-border, #e0e0e0)}.preview-wrapper{min-height:300px}.preview-image{max-height:70vh}}@media(max-width:480px){.file-name{max-width:100px}.header-details{flex-wrap:wrap}}\n"], dependencies: [{ kind: "ngmodule", type: DialogModule }, { kind: "component", type: i2$2.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { 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"] }] });
|
|
877
973
|
}
|
|
878
974
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: PdfPreviewComponent, decorators: [{
|
|
879
975
|
type: Component,
|
|
880
|
-
args: [{ selector: 'app-pdf-preview', imports: [DialogModule], template: "<p-dialog\r\n
|
|
976
|
+
args: [{ selector: 'app-pdf-preview', imports: [DialogModule, ButtonModule, TooltipModule], template: "<p-dialog\r\n [(visible)]=\"visible\"\r\n [style]=\"{ width: '80vw', height: '90vh' }\"\r\n [closable]=\"true\"\r\n [maximizable]=\"true\"\r\n [modal]=\"true\"\r\n>\r\n <!-- Header personalizado -->\r\n <ng-template pTemplate=\"header\">\r\n <div class=\"dialog-header\">\r\n <div class=\"header-left\">\r\n <i [class]=\"getFileIcon()\" class=\"file-icon\"></i>\r\n <div class=\"header-info\">\r\n <span class=\"header-title\"\r\n >Vista previa del documento de soporte</span\r\n >\r\n @if (fileName) {\r\n <div class=\"header-details\">\r\n <span class=\"file-name\">{{ fileName }}</span>\r\n <span class=\"file-meta\">\r\n <span class=\"file-type\">{{ fileTypeLabel }}</span>\r\n <span class=\"file-size\">{{ fileSize }}</span>\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n <div class=\"header-actions\">\r\n @if (fileUrl) {\r\n <button\r\n pButton\r\n type=\"button\"\r\n icon=\"pi pi-download\"\r\n class=\"p-button-rounded p-button-text p-button-sm\"\r\n (click)=\"downloadFile()\"\r\n pTooltip=\"Descargar archivo\"\r\n tooltipPosition=\"top\"\r\n ></button>\r\n }\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Contenido -->\r\n <div class=\"preview-wrapper\">\r\n <!-- Caso: Sin archivo -->\r\n @if (!fileUrl) {\r\n <div class=\"empty-state\">\r\n <i class=\"pi pi-file\"></i>\r\n <p>No hay archivo seleccionado</p>\r\n </div>\r\n }\r\n <!-- Caso: PDF -->\r\n @else if (isPdf) {\r\n <iframe\r\n [src]=\"fileUrl\"\r\n width=\"100%\"\r\n height=\"100%\"\r\n style=\"border: none\"\r\n class=\"pdf-iframe\"\r\n ></iframe>\r\n }\r\n <!-- Caso: Imagen -->\r\n @else if (isImage) {\r\n <div class=\"image-container\">\r\n <img\r\n [src]=\"fileUrl\"\r\n [alt]=\"fileName || 'Vista previa de imagen'\"\r\n class=\"preview-image\"\r\n (load)=\"onImageLoad()\"\r\n (error)=\"onImageError()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n</p-dialog>\r\n", styles: [".dialog-header{display:flex;align-items:center;justify-content:space-between;width:100%;padding:.5rem 0;gap:1rem}.header-left{display:flex;align-items:center;gap:.75rem;min-width:0;flex:1}.file-icon{font-size:1.5rem;color:var(--primary-color, #3b82f6);flex-shrink:0}.header-info{display:flex;flex-direction:column;gap:.125rem;min-width:0}.header-title{font-size:1rem;font-weight:600;color:var(--text-color, #333);line-height:1.3}.header-details{display:flex;align-items:center;gap:.75rem;font-size:.8rem;color:var(--text-color-secondary, #666);flex-wrap:wrap}.file-name{font-weight:500;color:var(--text-color, #333);max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-meta{display:flex;align-items:center;gap:.5rem}.file-type{background:var(--surface-hover, #f0f0f0);padding:.0625rem .5rem;border-radius:12px;font-size:.7rem;font-weight:500;color:var(--text-color-secondary, #666)}.file-size{font-size:.75rem;color:var(--text-color-secondary, #666)}.header-actions{display:flex;align-items:center;gap:.5rem;flex-shrink:0}.header-actions ::ng-deep .p-button.p-button-text{color:var(--text-color-secondary, #666)}.header-actions ::ng-deep .p-button.p-button-text:hover{color:var(--primary-color, #3b82f6);background:var(--surface-hover, #f0f0f0)}.preview-wrapper{width:100%;height:calc(100% - 10px);min-height:400px;position:relative;background:var(--surface-ground, #f8f9fa);border-radius:4px;overflow:hidden}.pdf-iframe{width:100%;height:100%;border:none;background:#fff}.image-container{width:100%;height:100%;display:flex;align-items:center;justify-content:center;padding:1rem;background:var(--surface-ground, #f8f9fa)}.preview-image{max-width:100%;max-height:100%;object-fit:contain;border-radius:4px;box-shadow:0 2px 8px #0000001a;transition:transform .2s}.preview-image:hover{transform:scale(1.02)}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1rem;color:var(--text-color-secondary, #666);height:100%;min-height:400px}.empty-state i{font-size:4rem;opacity:.4;color:var(--text-color-secondary, #666)}.empty-state p{margin:0;font-size:1rem;font-weight:400}@media(max-width:768px){.dialog-header{flex-direction:column;align-items:stretch;gap:.5rem;padding:.25rem 0}.header-left{gap:.5rem}.file-icon{font-size:1.25rem}.header-title{font-size:.9rem}.header-details{font-size:.7rem;gap:.5rem}.file-name{max-width:150px}.header-actions{justify-content:flex-end;padding-top:.25rem;border-top:1px solid var(--surface-border, #e0e0e0)}.preview-wrapper{min-height:300px}.preview-image{max-height:70vh}}@media(max-width:480px){.file-name{max-width:100px}.header-details{flex-wrap:wrap}}\n"] }]
|
|
881
977
|
}], ctorParameters: () => [{ type: i1$4.DomSanitizer }], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }, { type: i0.Output, args: ["visibleChange"] }], blob: [{ type: i0.Input, args: [{ isSignal: true, alias: "blob", required: false }] }] } });
|
|
882
978
|
|
|
883
979
|
class TemplateHighlight {
|
|
@@ -1792,11 +1888,11 @@ class AppMessageHelpComponent {
|
|
|
1792
1888
|
return null;
|
|
1793
1889
|
}
|
|
1794
1890
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: AppMessageHelpComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
|
1795
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: AppMessageHelpComponent, isStandalone: true, selector: "dsx-message-help", inputs: { control: "control", currentIdControl: "currentIdControl", helperFunction: "helperFunction", dataSource: "dataSource", key: "key", umbral: "umbral", debugMode: "debugMode", idFieldName: "idFieldName", maxSugerencias: "maxSugerencias" }, ngImport: i0, template: "<div class=\"dsx-help-slot\" [class.is-visible]=\"isHelpVisible()\">\r\n @if (isHelpVisible()) {\r\n <div\r\n class=\"dsx-help-message\"\r\n [class.is-warning]=\"helperFunction === 'similarity'\"\r\n >\r\n
|
|
1891
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: AppMessageHelpComponent, isStandalone: true, selector: "dsx-message-help", inputs: { control: "control", currentIdControl: "currentIdControl", helperFunction: "helperFunction", dataSource: "dataSource", key: "key", umbral: "umbral", debugMode: "debugMode", idFieldName: "idFieldName", maxSugerencias: "maxSugerencias" }, ngImport: i0, template: "<div class=\"dsx-help-slot\" [class.is-visible]=\"isHelpVisible()\">\r\n @if (isHelpVisible()) {\r\n <div\r\n class=\"dsx-help-message\"\r\n [class.is-warning]=\"helperFunction === 'similarity'\"\r\n >\r\n <span>{{ getHelpMessage() }}</span>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block;width:100%}.dsx-help-slot{max-height:0;margin-top:0;overflow:hidden;opacity:0;transition:max-height .22s ease,margin-top .22s ease,opacity .18s ease}.dsx-help-slot.is-visible{max-height:4rem;margin-top:.15rem;opacity:1}.dsx-help-message{--dsx-help-color: #059669;color:var(--dsx-help-color);font-family:Roboto,Montserrat,sans-serif;font-size:clamp(.7rem,.68rem + .08vw,.75rem);font-weight:400;line-height:1.4;letter-spacing:.01em;padding:.1rem 0;border:none;background:transparent;box-shadow:none;width:100%;max-width:100%;white-space:normal;word-break:break-word;box-sizing:border-box}.dsx-help-message.is-warning{--dsx-help-color: #d97706}.dsx-help-message span{display:block;word-break:break-word;color:var(--dsx-help-color)}.dsx-help-slot.is-visible .dsx-help-message{animation:fadeInHelp .2s ease}@keyframes fadeInHelp{0%{opacity:0;transform:translateY(-2px)}to{opacity:1;transform:translateY(0)}}@media(max-width:640px){.dsx-help-slot.is-visible{max-height:5rem}.dsx-help-message{font-size:clamp(.6rem,.55rem + .15vw,.65rem);padding:.05rem 0}}:host-context(.p-floatlabel){position:absolute;top:100%;left:0;width:100%;z-index:3;pointer-events:none}:host-context(.p-floatlabel) .dsx-help-slot{max-height:none;margin-top:.1rem;overflow:visible;opacity:0;transform:translateY(-2px);transition:opacity .16s ease,transform .18s ease}:host-context(.p-floatlabel) .dsx-help-slot.is-visible{opacity:1;transform:translateY(0)}:host-context(.p-floatlabel) .dsx-help-message{width:100%;max-width:100%;padding:.05rem 0;box-sizing:border-box}\n"] });
|
|
1796
1892
|
}
|
|
1797
1893
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: AppMessageHelpComponent, decorators: [{
|
|
1798
1894
|
type: Component,
|
|
1799
|
-
args: [{ selector: 'dsx-message-help', imports: [IconDsxComponent], template: "<div class=\"dsx-help-slot\" [class.is-visible]=\"isHelpVisible()\">\r\n @if (isHelpVisible()) {\r\n <div\r\n class=\"dsx-help-message\"\r\n [class.is-warning]=\"helperFunction === 'similarity'\"\r\n >\r\n
|
|
1895
|
+
args: [{ selector: 'dsx-message-help', imports: [IconDsxComponent], template: "<div class=\"dsx-help-slot\" [class.is-visible]=\"isHelpVisible()\">\r\n @if (isHelpVisible()) {\r\n <div\r\n class=\"dsx-help-message\"\r\n [class.is-warning]=\"helperFunction === 'similarity'\"\r\n >\r\n <span>{{ getHelpMessage() }}</span>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block;width:100%}.dsx-help-slot{max-height:0;margin-top:0;overflow:hidden;opacity:0;transition:max-height .22s ease,margin-top .22s ease,opacity .18s ease}.dsx-help-slot.is-visible{max-height:4rem;margin-top:.15rem;opacity:1}.dsx-help-message{--dsx-help-color: #059669;color:var(--dsx-help-color);font-family:Roboto,Montserrat,sans-serif;font-size:clamp(.7rem,.68rem + .08vw,.75rem);font-weight:400;line-height:1.4;letter-spacing:.01em;padding:.1rem 0;border:none;background:transparent;box-shadow:none;width:100%;max-width:100%;white-space:normal;word-break:break-word;box-sizing:border-box}.dsx-help-message.is-warning{--dsx-help-color: #d97706}.dsx-help-message span{display:block;word-break:break-word;color:var(--dsx-help-color)}.dsx-help-slot.is-visible .dsx-help-message{animation:fadeInHelp .2s ease}@keyframes fadeInHelp{0%{opacity:0;transform:translateY(-2px)}to{opacity:1;transform:translateY(0)}}@media(max-width:640px){.dsx-help-slot.is-visible{max-height:5rem}.dsx-help-message{font-size:clamp(.6rem,.55rem + .15vw,.65rem);padding:.05rem 0}}:host-context(.p-floatlabel){position:absolute;top:100%;left:0;width:100%;z-index:3;pointer-events:none}:host-context(.p-floatlabel) .dsx-help-slot{max-height:none;margin-top:.1rem;overflow:visible;opacity:0;transform:translateY(-2px);transition:opacity .16s ease,transform .18s ease}:host-context(.p-floatlabel) .dsx-help-slot.is-visible{opacity:1;transform:translateY(0)}:host-context(.p-floatlabel) .dsx-help-message{width:100%;max-width:100%;padding:.05rem 0;box-sizing:border-box}\n"] }]
|
|
1800
1896
|
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { control: [{
|
|
1801
1897
|
type: Input
|
|
1802
1898
|
}], currentIdControl: [{
|
|
@@ -2235,22 +2331,23 @@ function provideEnvironment(environment) {
|
|
|
2235
2331
|
* - `import` → Importar datos desde archivo (azul acero)
|
|
2236
2332
|
*/
|
|
2237
2333
|
const ACTION_TYPES = {
|
|
2334
|
+
cancel: 'cancel',
|
|
2335
|
+
create: 'create',
|
|
2336
|
+
details: 'details',
|
|
2337
|
+
download: 'download',
|
|
2338
|
+
edit: 'edit',
|
|
2339
|
+
export: 'export',
|
|
2238
2340
|
hardDelete: 'hardDelete',
|
|
2239
|
-
softDelete: 'softDelete',
|
|
2240
|
-
return: 'return',
|
|
2241
2341
|
home: 'home',
|
|
2242
|
-
|
|
2342
|
+
import: 'import',
|
|
2343
|
+
refresh: 'refresh',
|
|
2243
2344
|
restore: 'restore',
|
|
2244
|
-
|
|
2245
|
-
create: 'create',
|
|
2345
|
+
return: 'return',
|
|
2246
2346
|
save: 'save',
|
|
2347
|
+
softDelete: 'softDelete',
|
|
2247
2348
|
update: 'update',
|
|
2248
|
-
|
|
2249
|
-
details: 'details',
|
|
2349
|
+
validate: 'validate',
|
|
2250
2350
|
view: 'view',
|
|
2251
|
-
export: 'export',
|
|
2252
|
-
download: 'download',
|
|
2253
|
-
import: 'import',
|
|
2254
2351
|
};
|
|
2255
2352
|
function getActionMessageConfig(action, secondArg, thirdArg) {
|
|
2256
2353
|
const isActive = action === 'softDelete' || action === 'hardDelete'
|
|
@@ -4913,14 +5010,14 @@ const ACTION_CONFIG = {
|
|
|
4913
5010
|
icon: 'save',
|
|
4914
5011
|
primeIcon: 'pi pi-save',
|
|
4915
5012
|
colorToken: 'success',
|
|
4916
|
-
tooltip: 'Guardar
|
|
5013
|
+
tooltip: 'Guardar registro',
|
|
4917
5014
|
},
|
|
4918
5015
|
update: {
|
|
4919
5016
|
label: 'Actualizar',
|
|
4920
5017
|
icon: 'edit_note',
|
|
4921
5018
|
primeIcon: 'pi pi-save',
|
|
4922
5019
|
colorToken: 'primary',
|
|
4923
|
-
tooltip: 'Actualizar registro
|
|
5020
|
+
tooltip: 'Actualizar registro',
|
|
4924
5021
|
},
|
|
4925
5022
|
refresh: {
|
|
4926
5023
|
label: 'Refrescar',
|
|
@@ -4972,8 +5069,444 @@ const ACTION_CONFIG = {
|
|
|
4972
5069
|
colorToken: 'import',
|
|
4973
5070
|
tooltip: 'Importar desde archivo',
|
|
4974
5071
|
},
|
|
5072
|
+
cancel: {
|
|
5073
|
+
label: 'Cancelar',
|
|
5074
|
+
icon: 'cancel',
|
|
5075
|
+
primeIcon: 'pi pi-times',
|
|
5076
|
+
colorToken: 'danger',
|
|
5077
|
+
tooltip: 'Cancelar operación',
|
|
5078
|
+
},
|
|
4975
5079
|
};
|
|
4976
5080
|
|
|
5081
|
+
// dsx-calendar-view.component.ts - VERSIÓN CON isDevMode()
|
|
5082
|
+
class DsxCalendarView {
|
|
5083
|
+
// ============================================
|
|
5084
|
+
// INPUTS
|
|
5085
|
+
// ============================================
|
|
5086
|
+
// Two-way binding
|
|
5087
|
+
startDate = model(null, ...(ngDevMode ? [{ debugName: "startDate" }] : /* istanbul ignore next */ []));
|
|
5088
|
+
endDate = model(null, ...(ngDevMode ? [{ debugName: "endDate" }] : /* istanbul ignore next */ []));
|
|
5089
|
+
excludeSundays = model(false, ...(ngDevMode ? [{ debugName: "excludeSundays" }] : /* istanbul ignore next */ []));
|
|
5090
|
+
// Configuración
|
|
5091
|
+
holidays = input([], ...(ngDevMode ? [{ debugName: "holidays" }] : /* istanbul ignore next */ []));
|
|
5092
|
+
compactMode = input(true, ...(ngDevMode ? [{ debugName: "compactMode" }] : /* istanbul ignore next */ []));
|
|
5093
|
+
showKPI = input(true, ...(ngDevMode ? [{ debugName: "showKPI" }] : /* istanbul ignore next */ []));
|
|
5094
|
+
debugMode = input(false, ...(ngDevMode ? [{ debugName: "debugMode" }] : /* istanbul ignore next */ []));
|
|
5095
|
+
isEdit = input(false, ...(ngDevMode ? [{ debugName: "isEdit" }] : /* istanbul ignore next */ []));
|
|
5096
|
+
showControls = input(true, ...(ngDevMode ? [{ debugName: "showControls" }] : /* istanbul ignore next */ []));
|
|
5097
|
+
// Output
|
|
5098
|
+
rangeChanged = output();
|
|
5099
|
+
// ============================================
|
|
5100
|
+
// STATE
|
|
5101
|
+
// ============================================
|
|
5102
|
+
startDateStr = signal('', ...(ngDevMode ? [{ debugName: "startDateStr" }] : /* istanbul ignore next */ []));
|
|
5103
|
+
endDateStr = signal('', ...(ngDevMode ? [{ debugName: "endDateStr" }] : /* istanbul ignore next */ []));
|
|
5104
|
+
// ✅ Exponer isDevMode como propiedad pública para el template si es necesario
|
|
5105
|
+
isDevMode = isDevMode();
|
|
5106
|
+
// ============================================
|
|
5107
|
+
// COMPUTED
|
|
5108
|
+
// ============================================
|
|
5109
|
+
shouldShowControls = computed(() => {
|
|
5110
|
+
return this.isEdit() || this.showControls();
|
|
5111
|
+
}, ...(ngDevMode ? [{ debugName: "shouldShowControls" }] : /* istanbul ignore next */ []));
|
|
5112
|
+
months = computed(() => {
|
|
5113
|
+
const perfStart = this.shouldLog() ? performance.now() : 0;
|
|
5114
|
+
const start = this.startDateStr();
|
|
5115
|
+
const end = this.endDateStr();
|
|
5116
|
+
if (!start || !end) {
|
|
5117
|
+
this.logPerformance('months', perfStart);
|
|
5118
|
+
return [];
|
|
5119
|
+
}
|
|
5120
|
+
const zonaHoraria = 'America/Guatemala';
|
|
5121
|
+
const startDate = moment(start).tz(zonaHoraria).toDate();
|
|
5122
|
+
const endDate = moment(end).tz(zonaHoraria).toDate();
|
|
5123
|
+
if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
|
|
5124
|
+
this.logDebug('Fechas inválidas:', { start, end });
|
|
5125
|
+
this.logPerformance('months', perfStart);
|
|
5126
|
+
return [];
|
|
5127
|
+
}
|
|
5128
|
+
this.logDebug('fecha inicio: ', startDate);
|
|
5129
|
+
this.logDebug('fecha final: ', endDate);
|
|
5130
|
+
const startMonth = new Date(startDate.getFullYear(), startDate.getMonth(), 1);
|
|
5131
|
+
const endMonth = new Date(endDate.getFullYear(), endDate.getMonth(), 1);
|
|
5132
|
+
const monthsToShow = [];
|
|
5133
|
+
monthsToShow.push(this.generateMonth(startMonth, startDate, endDate));
|
|
5134
|
+
if (startMonth.getTime() !== endMonth.getTime()) {
|
|
5135
|
+
monthsToShow.push(this.generateMonth(endMonth, startDate, endDate));
|
|
5136
|
+
}
|
|
5137
|
+
this.logPerformance('months', perfStart);
|
|
5138
|
+
return monthsToShow;
|
|
5139
|
+
}, ...(ngDevMode ? [{ debugName: "months" }] : /* istanbul ignore next */ []));
|
|
5140
|
+
formattedHolidays = computed(() => {
|
|
5141
|
+
const perfStart = this.shouldLog() ? performance.now() : 0;
|
|
5142
|
+
const holidays = this.kpi()?.holidaysList || [];
|
|
5143
|
+
const result = holidays.map((h) => ({
|
|
5144
|
+
date: this.normalizeDateToString(h.dateHoliday),
|
|
5145
|
+
label: h.labelHoliday,
|
|
5146
|
+
}));
|
|
5147
|
+
this.logPerformance('formattedHolidays', perfStart);
|
|
5148
|
+
return result;
|
|
5149
|
+
}, ...(ngDevMode ? [{ debugName: "formattedHolidays" }] : /* istanbul ignore next */ []));
|
|
5150
|
+
// ============================================
|
|
5151
|
+
// KPI: Estadísticas del rango (CORREGIDO)
|
|
5152
|
+
// ============================================
|
|
5153
|
+
kpi = computed(() => {
|
|
5154
|
+
const perfStart = this.shouldLog() ? performance.now() : 0;
|
|
5155
|
+
const start = this.startDateStr();
|
|
5156
|
+
const end = this.endDateStr();
|
|
5157
|
+
if (!start || !end) {
|
|
5158
|
+
this.logPerformance('kpi', perfStart);
|
|
5159
|
+
return null;
|
|
5160
|
+
}
|
|
5161
|
+
const startDate = new Date(start);
|
|
5162
|
+
const endDate = new Date(end);
|
|
5163
|
+
if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
|
|
5164
|
+
this.logPerformance('kpi', perfStart);
|
|
5165
|
+
return null;
|
|
5166
|
+
}
|
|
5167
|
+
const holidays = this.holidays();
|
|
5168
|
+
const excludeSun = this.excludeSundays();
|
|
5169
|
+
// 1. Calcular días totales
|
|
5170
|
+
const totalDays = this.getDaysBetween(startDate, endDate);
|
|
5171
|
+
// 2. Calcular domingos en el rango
|
|
5172
|
+
let sundays = 0;
|
|
5173
|
+
const current = new Date(startDate);
|
|
5174
|
+
while (current <= endDate) {
|
|
5175
|
+
if (current.getDay() === 0) {
|
|
5176
|
+
sundays++;
|
|
5177
|
+
}
|
|
5178
|
+
current.setDate(current.getDate() + 1);
|
|
5179
|
+
}
|
|
5180
|
+
// 3. 🔥 Calcular feriados en el rango
|
|
5181
|
+
const holidaysInRange = holidays.filter((h) => {
|
|
5182
|
+
const hStr = this.normalizeDateToString(h.dateHoliday);
|
|
5183
|
+
return hStr >= start && hStr <= end;
|
|
5184
|
+
});
|
|
5185
|
+
// 4. 🔥 Días hábiles = total - domingos - feriados
|
|
5186
|
+
let businessDays = totalDays;
|
|
5187
|
+
if (excludeSun) {
|
|
5188
|
+
businessDays = totalDays - sundays;
|
|
5189
|
+
}
|
|
5190
|
+
// 🔥 CORRECCIÓN: Restar feriados independientemente de excludeSun
|
|
5191
|
+
businessDays = businessDays - holidaysInRange.length;
|
|
5192
|
+
const kpiResult = {
|
|
5193
|
+
totalDays,
|
|
5194
|
+
businessDays,
|
|
5195
|
+
holidays: holidaysInRange.length,
|
|
5196
|
+
sundays: excludeSun ? sundays : 0,
|
|
5197
|
+
holidaysList: holidaysInRange,
|
|
5198
|
+
startDate: start,
|
|
5199
|
+
endDate: end,
|
|
5200
|
+
};
|
|
5201
|
+
this.logDebug('KPI calculado:', kpiResult);
|
|
5202
|
+
this.logPerformance('kpi', perfStart);
|
|
5203
|
+
return kpiResult;
|
|
5204
|
+
}, ...(ngDevMode ? [{ debugName: "kpi" }] : /* istanbul ignore next */ []));
|
|
5205
|
+
// ============================================
|
|
5206
|
+
// EFFECTS
|
|
5207
|
+
// ============================================
|
|
5208
|
+
constructor() {
|
|
5209
|
+
effect(() => {
|
|
5210
|
+
const perfStart = this.shouldLog() ? performance.now() : 0;
|
|
5211
|
+
const value = this.startDate();
|
|
5212
|
+
const formatted = this.formatInputDate(value);
|
|
5213
|
+
this.startDateStr.set(formatted);
|
|
5214
|
+
this.logDebug('startDate actualizado:', { value, formatted });
|
|
5215
|
+
this.emitRangeChange();
|
|
5216
|
+
this.logPerformance('startDate effect', perfStart);
|
|
5217
|
+
});
|
|
5218
|
+
effect(() => {
|
|
5219
|
+
const perfStart = this.shouldLog() ? performance.now() : 0;
|
|
5220
|
+
const value = this.endDate();
|
|
5221
|
+
const formatted = this.formatInputDate(value);
|
|
5222
|
+
this.endDateStr.set(formatted);
|
|
5223
|
+
this.logDebug('endDate actualizado:', { value, formatted });
|
|
5224
|
+
this.emitRangeChange();
|
|
5225
|
+
this.logPerformance('endDate effect', perfStart);
|
|
5226
|
+
});
|
|
5227
|
+
effect(() => {
|
|
5228
|
+
this.logDebug('excludeSundays actualizado:', this.excludeSundays());
|
|
5229
|
+
});
|
|
5230
|
+
}
|
|
5231
|
+
// ============================================
|
|
5232
|
+
// PRIVATE METHODS
|
|
5233
|
+
// ============================================
|
|
5234
|
+
normalizeDateToString(date) {
|
|
5235
|
+
const perfStart = this.shouldLog() ? performance.now() : 0;
|
|
5236
|
+
let result = '';
|
|
5237
|
+
if (!date) {
|
|
5238
|
+
this.logPerformance('normalizeDateToString', perfStart);
|
|
5239
|
+
return result;
|
|
5240
|
+
}
|
|
5241
|
+
if (date instanceof Date) {
|
|
5242
|
+
if (isNaN(date.getTime())) {
|
|
5243
|
+
this.logPerformance('normalizeDateToString', perfStart);
|
|
5244
|
+
return result;
|
|
5245
|
+
}
|
|
5246
|
+
result = this.formatDate(date);
|
|
5247
|
+
}
|
|
5248
|
+
if (typeof date === 'string') {
|
|
5249
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
5250
|
+
result = date;
|
|
5251
|
+
}
|
|
5252
|
+
else {
|
|
5253
|
+
const parsed = new Date(date);
|
|
5254
|
+
if (!isNaN(parsed.getTime())) {
|
|
5255
|
+
result = this.formatDate(parsed);
|
|
5256
|
+
}
|
|
5257
|
+
}
|
|
5258
|
+
}
|
|
5259
|
+
this.logPerformance('normalizeDateToString', perfStart);
|
|
5260
|
+
return result;
|
|
5261
|
+
}
|
|
5262
|
+
formatInputDate(value) {
|
|
5263
|
+
if (!value)
|
|
5264
|
+
return '';
|
|
5265
|
+
if (value instanceof Date) {
|
|
5266
|
+
if (isNaN(value.getTime()))
|
|
5267
|
+
return '';
|
|
5268
|
+
return this.formatDate(value);
|
|
5269
|
+
}
|
|
5270
|
+
if (typeof value === 'string') {
|
|
5271
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
5272
|
+
return value;
|
|
5273
|
+
}
|
|
5274
|
+
const date = new Date(value);
|
|
5275
|
+
if (!isNaN(date.getTime())) {
|
|
5276
|
+
return this.formatDate(date);
|
|
5277
|
+
}
|
|
5278
|
+
return '';
|
|
5279
|
+
}
|
|
5280
|
+
return '';
|
|
5281
|
+
}
|
|
5282
|
+
emitRangeChange() {
|
|
5283
|
+
const start = this.startDateStr();
|
|
5284
|
+
const end = this.endDateStr();
|
|
5285
|
+
if (start && end) {
|
|
5286
|
+
this.logDebug('Emitiendo rangeChanged:', { start, end });
|
|
5287
|
+
this.rangeChanged.emit({ start, end });
|
|
5288
|
+
}
|
|
5289
|
+
}
|
|
5290
|
+
// ============================================
|
|
5291
|
+
// PUBLIC METHODS (Template)
|
|
5292
|
+
// ============================================
|
|
5293
|
+
onStartDateChange(event) {
|
|
5294
|
+
if (!this.isEdit())
|
|
5295
|
+
return;
|
|
5296
|
+
const perfStart = this.shouldLog() ? performance.now() : 0;
|
|
5297
|
+
const value = event.target.value;
|
|
5298
|
+
this.startDate.set(value);
|
|
5299
|
+
this.logDebug('onStartDateChange:', value);
|
|
5300
|
+
this.logPerformance('onStartDateChange', perfStart);
|
|
5301
|
+
}
|
|
5302
|
+
onEndDateChange(event) {
|
|
5303
|
+
if (!this.isEdit())
|
|
5304
|
+
return;
|
|
5305
|
+
const perfStart = this.shouldLog() ? performance.now() : 0;
|
|
5306
|
+
const value = event.target.value;
|
|
5307
|
+
this.endDate.set(value);
|
|
5308
|
+
this.logDebug('onEndDateChange:', value);
|
|
5309
|
+
this.logPerformance('onEndDateChange', perfStart);
|
|
5310
|
+
}
|
|
5311
|
+
onToggleSundays(event) {
|
|
5312
|
+
if (!this.isEdit())
|
|
5313
|
+
return;
|
|
5314
|
+
const perfStart = this.shouldLog() ? performance.now() : 0;
|
|
5315
|
+
const checked = event.target.checked;
|
|
5316
|
+
this.excludeSundays.set(checked);
|
|
5317
|
+
this.logDebug('onToggleSundays:', checked);
|
|
5318
|
+
this.logPerformance('onToggleSundays', perfStart);
|
|
5319
|
+
}
|
|
5320
|
+
// ============================================
|
|
5321
|
+
// GENERATE MONTH
|
|
5322
|
+
// ============================================
|
|
5323
|
+
generateMonth(monthDate, rangeStart, rangeEnd) {
|
|
5324
|
+
const perfStart = this.shouldLog() ? performance.now() : 0;
|
|
5325
|
+
const year = monthDate.getFullYear();
|
|
5326
|
+
const month = monthDate.getMonth();
|
|
5327
|
+
const firstDay = new Date(year, month, 1);
|
|
5328
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
5329
|
+
const startDayOfWeek = firstDay.getDay();
|
|
5330
|
+
const days = [];
|
|
5331
|
+
const holidays = this.holidays();
|
|
5332
|
+
const totalRangeDays = this.getDaysBetween(rangeStart, rangeEnd);
|
|
5333
|
+
// Días anteriores
|
|
5334
|
+
const prevMonthLastDay = new Date(year, month, 0).getDate();
|
|
5335
|
+
for (let i = startDayOfWeek - 1; i >= 0; i--) {
|
|
5336
|
+
const d = new Date(year, month, -i);
|
|
5337
|
+
days.push({
|
|
5338
|
+
date: d,
|
|
5339
|
+
day: prevMonthLastDay - i,
|
|
5340
|
+
isCurrentMonth: false,
|
|
5341
|
+
isSunday: d.getDay() === 0,
|
|
5342
|
+
isInRange: false,
|
|
5343
|
+
isStart: false,
|
|
5344
|
+
isEnd: false,
|
|
5345
|
+
isHoliday: false,
|
|
5346
|
+
disabled: false,
|
|
5347
|
+
});
|
|
5348
|
+
}
|
|
5349
|
+
// Días del mes actual
|
|
5350
|
+
for (let i = 1; i <= daysInMonth; i++) {
|
|
5351
|
+
const d = new Date(year, month, i);
|
|
5352
|
+
const dateStr = this.formatDate(d);
|
|
5353
|
+
const holiday = holidays.find((h) => {
|
|
5354
|
+
const hStr = this.normalizeDateToString(h.dateHoliday);
|
|
5355
|
+
return hStr === dateStr;
|
|
5356
|
+
});
|
|
5357
|
+
const isSunday = d.getDay() === 0;
|
|
5358
|
+
const isInRange = this.isDateInRange(d, rangeStart, rangeEnd);
|
|
5359
|
+
const isStart = this.isSameDay(d, rangeStart);
|
|
5360
|
+
const isEnd = this.isSameDay(d, rangeEnd);
|
|
5361
|
+
const disabled = this.excludeSundays() && isSunday;
|
|
5362
|
+
let rangePosition = 0;
|
|
5363
|
+
if (isInRange && !disabled) {
|
|
5364
|
+
const dayDiff = this.getDaysBetween(rangeStart, d) - 1;
|
|
5365
|
+
rangePosition = totalRangeDays > 1 ? dayDiff / (totalRangeDays - 1) : 0;
|
|
5366
|
+
}
|
|
5367
|
+
days.push({
|
|
5368
|
+
date: d,
|
|
5369
|
+
day: i,
|
|
5370
|
+
isCurrentMonth: true,
|
|
5371
|
+
isSunday,
|
|
5372
|
+
isInRange,
|
|
5373
|
+
isStart,
|
|
5374
|
+
isEnd,
|
|
5375
|
+
isHoliday: !!holiday,
|
|
5376
|
+
holidayLabel: holiday?.labelHoliday,
|
|
5377
|
+
disabled,
|
|
5378
|
+
rangePosition,
|
|
5379
|
+
});
|
|
5380
|
+
}
|
|
5381
|
+
// Días siguientes
|
|
5382
|
+
const totalCells = Math.ceil((startDayOfWeek + daysInMonth) / 7) * 7;
|
|
5383
|
+
const remaining = totalCells - days.length;
|
|
5384
|
+
for (let i = 1; i <= remaining; i++) {
|
|
5385
|
+
const d = new Date(year, month + 1, i);
|
|
5386
|
+
days.push({
|
|
5387
|
+
date: d,
|
|
5388
|
+
day: i,
|
|
5389
|
+
isCurrentMonth: false,
|
|
5390
|
+
isSunday: d.getDay() === 0,
|
|
5391
|
+
isInRange: false,
|
|
5392
|
+
isStart: false,
|
|
5393
|
+
isEnd: false,
|
|
5394
|
+
isHoliday: false,
|
|
5395
|
+
disabled: false,
|
|
5396
|
+
});
|
|
5397
|
+
}
|
|
5398
|
+
// Recalcular para días del mes actual
|
|
5399
|
+
for (const day of days) {
|
|
5400
|
+
if (day.isCurrentMonth) {
|
|
5401
|
+
const d = day.date;
|
|
5402
|
+
day.isInRange = this.isDateInRange(d, rangeStart, rangeEnd);
|
|
5403
|
+
day.isStart = this.isSameDay(d, rangeStart);
|
|
5404
|
+
day.isEnd = this.isSameDay(d, rangeEnd);
|
|
5405
|
+
day.disabled = this.excludeSundays() && day.isSunday;
|
|
5406
|
+
if (day.isInRange && !day.disabled) {
|
|
5407
|
+
const dayDiff = this.getDaysBetween(rangeStart, d) - 1;
|
|
5408
|
+
day.rangePosition =
|
|
5409
|
+
totalRangeDays > 1 ? dayDiff / (totalRangeDays - 1) : 0;
|
|
5410
|
+
}
|
|
5411
|
+
}
|
|
5412
|
+
}
|
|
5413
|
+
const monthNames = [
|
|
5414
|
+
'Enero',
|
|
5415
|
+
'Febrero',
|
|
5416
|
+
'Marzo',
|
|
5417
|
+
'Abril',
|
|
5418
|
+
'Mayo',
|
|
5419
|
+
'Junio',
|
|
5420
|
+
'Julio',
|
|
5421
|
+
'Agosto',
|
|
5422
|
+
'Septiembre',
|
|
5423
|
+
'Octubre',
|
|
5424
|
+
'Noviembre',
|
|
5425
|
+
'Diciembre',
|
|
5426
|
+
];
|
|
5427
|
+
this.logPerformance('generateMonth', perfStart);
|
|
5428
|
+
return {
|
|
5429
|
+
label: `${monthNames[month]} ${year}`,
|
|
5430
|
+
days,
|
|
5431
|
+
};
|
|
5432
|
+
}
|
|
5433
|
+
// ============================================
|
|
5434
|
+
// HELPERS
|
|
5435
|
+
// ============================================
|
|
5436
|
+
getDaysBetween(start, end) {
|
|
5437
|
+
const s = new Date(start.getFullYear(), start.getMonth(), start.getDate());
|
|
5438
|
+
const e = new Date(end.getFullYear(), end.getMonth(), end.getDate());
|
|
5439
|
+
const diffTime = Math.abs(e.getTime() - s.getTime());
|
|
5440
|
+
return Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1;
|
|
5441
|
+
}
|
|
5442
|
+
isDateInRange(date, start, end) {
|
|
5443
|
+
const d = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
5444
|
+
const s = new Date(start.getFullYear(), start.getMonth(), start.getDate());
|
|
5445
|
+
const e = new Date(end.getFullYear(), end.getMonth(), end.getDate());
|
|
5446
|
+
return d >= s && d <= e;
|
|
5447
|
+
}
|
|
5448
|
+
isSameDay(d1, d2) {
|
|
5449
|
+
if (!d2)
|
|
5450
|
+
return false;
|
|
5451
|
+
return (d1.getFullYear() === d2.getFullYear() &&
|
|
5452
|
+
d1.getMonth() === d2.getMonth() &&
|
|
5453
|
+
d1.getDate() === d2.getDate());
|
|
5454
|
+
}
|
|
5455
|
+
formatDate(date) {
|
|
5456
|
+
const y = date.getFullYear();
|
|
5457
|
+
const m = String(date.getMonth() + 1).padStart(2, '0');
|
|
5458
|
+
const d = String(date.getDate()).padStart(2, '0');
|
|
5459
|
+
return `${y}-${m}-${d}`;
|
|
5460
|
+
}
|
|
5461
|
+
// ============================================
|
|
5462
|
+
// LOGGING - SIMPLE Y SEGURO
|
|
5463
|
+
// ============================================
|
|
5464
|
+
/**
|
|
5465
|
+
* Verifica si debemos mostrar logs
|
|
5466
|
+
* ✅ Usa isDevMode() de Angular - simple y confiable
|
|
5467
|
+
*/
|
|
5468
|
+
shouldLog() {
|
|
5469
|
+
return isDevMode() && this.debugMode();
|
|
5470
|
+
}
|
|
5471
|
+
/**
|
|
5472
|
+
* Log de depuración - Solo visible en desarrollo con debugMode=true
|
|
5473
|
+
* 🔥 NUNCA se ejecuta en producción
|
|
5474
|
+
*/
|
|
5475
|
+
logDebug(...args) {
|
|
5476
|
+
if (this.shouldLog()) {
|
|
5477
|
+
console.log('[DsxCalendarView]', ...args);
|
|
5478
|
+
}
|
|
5479
|
+
}
|
|
5480
|
+
/**
|
|
5481
|
+
* Log de rendimiento - Mide tiempos de ejecución
|
|
5482
|
+
* 🔥 NUNCA se ejecuta en producción
|
|
5483
|
+
*/
|
|
5484
|
+
logPerformance(method, startTime) {
|
|
5485
|
+
if (this.shouldLog() && startTime > 0) {
|
|
5486
|
+
const elapsed = (performance.now() - startTime).toFixed(2);
|
|
5487
|
+
if (Number(elapsed) > 0.1) {
|
|
5488
|
+
console.log(`[DsxCalendarView] ⚡ ${method} - ${elapsed}ms`);
|
|
5489
|
+
}
|
|
5490
|
+
}
|
|
5491
|
+
}
|
|
5492
|
+
// ============================================
|
|
5493
|
+
// TEMPLATE HELPERS
|
|
5494
|
+
// ============================================
|
|
5495
|
+
chunk(arr, size) {
|
|
5496
|
+
const result = [];
|
|
5497
|
+
for (let i = 0; i < arr.length; i += size) {
|
|
5498
|
+
result.push(arr.slice(i, i + size));
|
|
5499
|
+
}
|
|
5500
|
+
return result;
|
|
5501
|
+
}
|
|
5502
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxCalendarView, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5503
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: DsxCalendarView, isStandalone: true, selector: "dsx-calendar-view", inputs: { startDate: { classPropertyName: "startDate", publicName: "startDate", isSignal: true, isRequired: false, transformFunction: null }, endDate: { classPropertyName: "endDate", publicName: "endDate", isSignal: true, isRequired: false, transformFunction: null }, excludeSundays: { classPropertyName: "excludeSundays", publicName: "excludeSundays", isSignal: true, isRequired: false, transformFunction: null }, holidays: { classPropertyName: "holidays", publicName: "holidays", isSignal: true, isRequired: false, transformFunction: null }, compactMode: { classPropertyName: "compactMode", publicName: "compactMode", isSignal: true, isRequired: false, transformFunction: null }, showKPI: { classPropertyName: "showKPI", publicName: "showKPI", isSignal: true, isRequired: false, transformFunction: null }, debugMode: { classPropertyName: "debugMode", publicName: "debugMode", isSignal: true, isRequired: false, transformFunction: null }, isEdit: { classPropertyName: "isEdit", publicName: "isEdit", isSignal: true, isRequired: false, transformFunction: null }, showControls: { classPropertyName: "showControls", publicName: "showControls", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { startDate: "startDateChange", endDate: "endDateChange", excludeSundays: "excludeSundaysChange", rangeChanged: "rangeChanged" }, ngImport: i0, template: "<!-- dsx-calendar-view.html - ACTUALIZADO CON showControls -->\r\n\r\n<div class=\"calendar-range\" [class.compact]=\"compactMode()\">\r\n <!-- ==========================================\r\n CONTROLES - Ocultables con showControls\r\n ========================================== -->\r\n @if (shouldShowControls()) {\r\n <div class=\"controls\">\r\n <div class=\"control-group\">\r\n <label>Fecha Inicio</label>\r\n <input\r\n type=\"date\"\r\n [value]=\"startDateStr()\"\r\n (input)=\"onStartDateChange($event)\"\r\n [disabled]=\"!isEdit()\"\r\n />\r\n </div>\r\n <div class=\"control-group\">\r\n <label>Fecha Fin</label>\r\n <input\r\n type=\"date\"\r\n [value]=\"endDateStr()\"\r\n (input)=\"onEndDateChange($event)\"\r\n [disabled]=\"!isEdit()\"\r\n />\r\n </div>\r\n <div class=\"control-group checkbox\">\r\n <label>\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"excludeSundays()\"\r\n (change)=\"onToggleSundays($event)\"\r\n [disabled]=\"!isEdit()\"\r\n />\r\n Excluir Domingos\r\n </label>\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- ==========================================\r\n KPIs\r\n ========================================== -->\r\n @if (showKPI() && kpi()) {\r\n <div class=\"kpi-container\">\r\n <div class=\"kpi-item\">\r\n <span class=\"kpi-label\">\r\n <i class=\"fa-regular fa-calendar-days\"></i>\r\n D\u00EDas calendario\r\n </span>\r\n <span class=\"kpi-value\">{{ kpi()?.totalDays }}</span>\r\n </div>\r\n <div class=\"kpi-item\">\r\n <span class=\"kpi-label\">\r\n <i class=\"fa-regular fa-circle-check\"></i>\r\n D\u00EDas h\u00E1biles\r\n </span>\r\n <span class=\"kpi-value\">{{ kpi()?.businessDays }}</span>\r\n </div>\r\n <div class=\"kpi-item\">\r\n <span class=\"kpi-label\">\r\n <i class=\"fa-solid fa-not-equal\"></i>\r\n Feriados\r\n </span>\r\n <span class=\"kpi-value\">{{ kpi()?.holidays }}</span>\r\n </div>\r\n @if (excludeSundays()) {\r\n <div class=\"kpi-item\">\r\n <span class=\"kpi-label\">\r\n <i class=\"fa-solid fa-calendar-day\"></i>\r\n Domingos\r\n </span>\r\n <span class=\"kpi-value\">{{ kpi()?.sundays }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- ==========================================\r\n CALENDARIO\r\n ========================================== -->\r\n <div class=\"months-grid\">\r\n @for (month of months(); track month.label) {\r\n <div class=\"month-card\">\r\n <div class=\"month-title\">{{ month.label }}</div>\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n @for (dia of ['Do','Lu','Ma','Mi','Ju','Vi','Sa']; track dia) {\r\n <th>{{ dia }}</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of chunk(month.days, 7); track $index) {\r\n <tr>\r\n @for (day of row; track day.date) {\r\n <td\r\n [class.other-month]=\"!day.isCurrentMonth\"\r\n [class.sunday]=\"day.isSunday && !day.disabled && day.isCurrentMonth\"\r\n [class.disabled-sunday]=\"day.disabled\"\r\n [class.in-range]=\"day.isInRange && day.isCurrentMonth\"\r\n [class.start-date]=\"day.isStart && day.isCurrentMonth\"\r\n [class.end-date]=\"day.isEnd && day.isCurrentMonth\"\r\n [class.holiday]=\"day.isHoliday && day.isCurrentMonth\"\r\n [class.same-day]=\"day.isStart && day.isEnd\"\r\n [style.--range-position]=\"day.rangePosition\"\r\n [title]=\"day.isHoliday ? day.holidayLabel : ''\"\r\n >\r\n <span class=\"day-number\">{{ day.day }}</span>\r\n @if (day.isHoliday && day.isCurrentMonth) {\r\n <span class=\"holiday-label\">{{ day.holidayLabel }}</span>\r\n }\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- ==========================================\r\n FERIADOS DETALLE\r\n ========================================== -->\r\n @if (kpi()?.holidays && formattedHolidays().length) {\r\n <div class=\"holidays-detail\">\r\n <div class=\"holidays-detail-title\">\r\n <i class=\"fa-solid fa-calendar-day\"></i>\r\n Feriados en el per\u00EDodo\r\n </div>\r\n <div class=\"holidays-detail-list\">\r\n @for (h of formattedHolidays(); track h.date) {\r\n <span class=\"holiday-detail-tag\">\r\n <i class=\"fa-regular fa-calendar\"></i>\r\n {{ h.date }} - {{ h.label }}\r\n </span>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".calendar-range{font-family:system-ui,-apple-system,sans-serif;max-width:100%;padding:8px}.calendar-range.compact{max-width:750px;margin:0 auto}.controls{display:flex;flex-wrap:wrap;gap:16px 24px;margin-bottom:12px;padding:10px 16px;background:#f8f9fa;border-radius:6px;border:1px solid #e9ecef;align-items:center;justify-content:center}.control-group{display:flex;align-items:center;gap:8px}.control-group label{font-size:.8rem;font-weight:600;color:#495057;white-space:nowrap}.control-group input[type=date]{padding:4px 8px;border:1px solid #ced4da;border-radius:4px;font-size:.8rem;background:#fff;min-width:130px}.control-group.checkbox{margin-left:0;padding-left:8px;border-left:1px solid #dee2e6}.control-group.checkbox label{font-weight:400;font-size:.75rem;cursor:pointer;display:flex;align-items:center;gap:4px}.kpi-container{display:flex;flex-wrap:wrap;gap:20px 32px;padding:10px 20px;margin-bottom:12px;background:linear-gradient(135deg,#f8f9fa,#e9ecef);border-radius:8px;border:1px solid #dee2e6;justify-content:center;align-items:center}.kpi-item{display:flex;align-items:center;gap:6px;font-size:.85rem}.kpi-label{color:#6c757d;font-weight:500}.kpi-value{font-weight:700;color:#212529;font-size:1.1rem;min-width:24px;text-align:center;background:#fff;padding:0 8px;border-radius:4px}.kpi-holidays{display:none}.months-grid{display:flex;gap:16px;justify-content:center;flex-wrap:wrap}.month-card{flex:1 1 auto;min-width:230px;max-width:300px;background:#fff;border:1px solid #dee2e6;border-radius:6px;padding:6px 4px 4px}.month-title{text-align:center;font-size:.85rem;font-weight:600;color:#212529;margin-bottom:4px;padding:2px 0}.calendar-table{width:100%;border-collapse:collapse;font-size:.7rem;table-layout:fixed}.calendar-table th{text-align:center;font-weight:600;color:#6c757d;padding:2px 0;font-size:.65rem}.calendar-table td{text-align:center;padding:2px 0;border-radius:3px;height:28px;vertical-align:middle;font-size:.7rem;transition:background .1s;position:relative}.other-month{color:#ced4da;background:transparent}.sunday{background:#ffe0e0}.disabled-sunday{background:#f1f3f5!important;color:#adb5bd!important;cursor:default}.in-range{background:#c4eeff}.start-date{background:#28a745!important;color:#fff!important;border-radius:3px 0 0 3px;font-weight:700}.end-date{background:#d17015!important;color:#fff!important;border-radius:0 3px 3px 0;font-weight:700}.same-day{background:#28a745!important;color:#fff!important;border-radius:3px}.day-number{display:block;font-size:.75rem;line-height:1.2}.holiday:not(.other-month){background:#e8f0fe!important;border:2px solid #1a5a8c!important;border-radius:4px!important;position:relative;z-index:1}.holiday .day-number{font-weight:700!important;color:#1a3a5c!important}.holiday-label{display:block;font-size:.45rem;line-height:1.2;color:#1a3a5c;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:95%;margin:0 auto;background:#1a5a8c1a;border-radius:2px;padding:0 2px;font-weight:600}.holiday:hover .holiday-label{white-space:normal;overflow:visible;position:absolute;bottom:100%;left:50%;transform:translate(-50%);background:#1a3a5c;color:#fff;padding:4px 10px;border-radius:4px;font-size:.6rem;z-index:10;box-shadow:0 2px 8px #0003;max-width:180px;white-space:nowrap}.holidays-detail{margin-top:12px;padding:10px 16px;background:#f0f4f8;border:1px solid #1a5a8c;border-radius:8px;border-left:4px solid #1a5a8c}.holidays-detail-title{font-size:.8rem;font-weight:600;color:#1a3a5c;margin-bottom:6px;display:flex;align-items:center;gap:6px}.holidays-detail-title i{color:#1a5a8c}.holidays-detail-list{display:flex;flex-wrap:wrap;gap:6px 12px}.holiday-detail-tag{font-size:.7rem;color:#1a3a5c;background:#e8f0fe;padding:2px 12px;border-radius:12px;border:1px solid #b3cfe5;display:inline-flex;align-items:center;gap:4px;white-space:nowrap}.holiday-detail-tag i{font-size:.6rem;color:#1a5a8c}.control-group input:disabled,.control-group input[disabled]{background:#f1f3f5!important;color:#6c757d!important;cursor:not-allowed;opacity:.7}.control-group input[type=checkbox]:disabled{cursor:not-allowed;opacity:.6}.control-group.checkbox label:has(input:disabled){color:#6c757d;cursor:not-allowed}@media(max-width:600px){.month-card{min-width:180px;max-width:100%}.controls{gap:10px;padding:8px 12px;flex-direction:column;align-items:stretch}.control-group{justify-content:space-between}.control-group input[type=date]{min-width:100px;flex:1}.control-group.checkbox{border-left:none;padding-left:0;justify-content:center}.kpi-container{gap:10px 16px;padding:8px 12px;justify-content:center}.kpi-item{font-size:.75rem}.kpi-value{font-size:.9rem;min-width:20px;padding:0 4px}.holidays-detail{padding:8px 12px}.holiday-detail-tag{font-size:.6rem;padding:2px 8px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
|
|
5504
|
+
}
|
|
5505
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxCalendarView, decorators: [{
|
|
5506
|
+
type: Component,
|
|
5507
|
+
args: [{ selector: 'dsx-calendar-view', standalone: true, imports: [CommonModule, FormsModule], template: "<!-- dsx-calendar-view.html - ACTUALIZADO CON showControls -->\r\n\r\n<div class=\"calendar-range\" [class.compact]=\"compactMode()\">\r\n <!-- ==========================================\r\n CONTROLES - Ocultables con showControls\r\n ========================================== -->\r\n @if (shouldShowControls()) {\r\n <div class=\"controls\">\r\n <div class=\"control-group\">\r\n <label>Fecha Inicio</label>\r\n <input\r\n type=\"date\"\r\n [value]=\"startDateStr()\"\r\n (input)=\"onStartDateChange($event)\"\r\n [disabled]=\"!isEdit()\"\r\n />\r\n </div>\r\n <div class=\"control-group\">\r\n <label>Fecha Fin</label>\r\n <input\r\n type=\"date\"\r\n [value]=\"endDateStr()\"\r\n (input)=\"onEndDateChange($event)\"\r\n [disabled]=\"!isEdit()\"\r\n />\r\n </div>\r\n <div class=\"control-group checkbox\">\r\n <label>\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"excludeSundays()\"\r\n (change)=\"onToggleSundays($event)\"\r\n [disabled]=\"!isEdit()\"\r\n />\r\n Excluir Domingos\r\n </label>\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- ==========================================\r\n KPIs\r\n ========================================== -->\r\n @if (showKPI() && kpi()) {\r\n <div class=\"kpi-container\">\r\n <div class=\"kpi-item\">\r\n <span class=\"kpi-label\">\r\n <i class=\"fa-regular fa-calendar-days\"></i>\r\n D\u00EDas calendario\r\n </span>\r\n <span class=\"kpi-value\">{{ kpi()?.totalDays }}</span>\r\n </div>\r\n <div class=\"kpi-item\">\r\n <span class=\"kpi-label\">\r\n <i class=\"fa-regular fa-circle-check\"></i>\r\n D\u00EDas h\u00E1biles\r\n </span>\r\n <span class=\"kpi-value\">{{ kpi()?.businessDays }}</span>\r\n </div>\r\n <div class=\"kpi-item\">\r\n <span class=\"kpi-label\">\r\n <i class=\"fa-solid fa-not-equal\"></i>\r\n Feriados\r\n </span>\r\n <span class=\"kpi-value\">{{ kpi()?.holidays }}</span>\r\n </div>\r\n @if (excludeSundays()) {\r\n <div class=\"kpi-item\">\r\n <span class=\"kpi-label\">\r\n <i class=\"fa-solid fa-calendar-day\"></i>\r\n Domingos\r\n </span>\r\n <span class=\"kpi-value\">{{ kpi()?.sundays }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- ==========================================\r\n CALENDARIO\r\n ========================================== -->\r\n <div class=\"months-grid\">\r\n @for (month of months(); track month.label) {\r\n <div class=\"month-card\">\r\n <div class=\"month-title\">{{ month.label }}</div>\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n @for (dia of ['Do','Lu','Ma','Mi','Ju','Vi','Sa']; track dia) {\r\n <th>{{ dia }}</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of chunk(month.days, 7); track $index) {\r\n <tr>\r\n @for (day of row; track day.date) {\r\n <td\r\n [class.other-month]=\"!day.isCurrentMonth\"\r\n [class.sunday]=\"day.isSunday && !day.disabled && day.isCurrentMonth\"\r\n [class.disabled-sunday]=\"day.disabled\"\r\n [class.in-range]=\"day.isInRange && day.isCurrentMonth\"\r\n [class.start-date]=\"day.isStart && day.isCurrentMonth\"\r\n [class.end-date]=\"day.isEnd && day.isCurrentMonth\"\r\n [class.holiday]=\"day.isHoliday && day.isCurrentMonth\"\r\n [class.same-day]=\"day.isStart && day.isEnd\"\r\n [style.--range-position]=\"day.rangePosition\"\r\n [title]=\"day.isHoliday ? day.holidayLabel : ''\"\r\n >\r\n <span class=\"day-number\">{{ day.day }}</span>\r\n @if (day.isHoliday && day.isCurrentMonth) {\r\n <span class=\"holiday-label\">{{ day.holidayLabel }}</span>\r\n }\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- ==========================================\r\n FERIADOS DETALLE\r\n ========================================== -->\r\n @if (kpi()?.holidays && formattedHolidays().length) {\r\n <div class=\"holidays-detail\">\r\n <div class=\"holidays-detail-title\">\r\n <i class=\"fa-solid fa-calendar-day\"></i>\r\n Feriados en el per\u00EDodo\r\n </div>\r\n <div class=\"holidays-detail-list\">\r\n @for (h of formattedHolidays(); track h.date) {\r\n <span class=\"holiday-detail-tag\">\r\n <i class=\"fa-regular fa-calendar\"></i>\r\n {{ h.date }} - {{ h.label }}\r\n </span>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".calendar-range{font-family:system-ui,-apple-system,sans-serif;max-width:100%;padding:8px}.calendar-range.compact{max-width:750px;margin:0 auto}.controls{display:flex;flex-wrap:wrap;gap:16px 24px;margin-bottom:12px;padding:10px 16px;background:#f8f9fa;border-radius:6px;border:1px solid #e9ecef;align-items:center;justify-content:center}.control-group{display:flex;align-items:center;gap:8px}.control-group label{font-size:.8rem;font-weight:600;color:#495057;white-space:nowrap}.control-group input[type=date]{padding:4px 8px;border:1px solid #ced4da;border-radius:4px;font-size:.8rem;background:#fff;min-width:130px}.control-group.checkbox{margin-left:0;padding-left:8px;border-left:1px solid #dee2e6}.control-group.checkbox label{font-weight:400;font-size:.75rem;cursor:pointer;display:flex;align-items:center;gap:4px}.kpi-container{display:flex;flex-wrap:wrap;gap:20px 32px;padding:10px 20px;margin-bottom:12px;background:linear-gradient(135deg,#f8f9fa,#e9ecef);border-radius:8px;border:1px solid #dee2e6;justify-content:center;align-items:center}.kpi-item{display:flex;align-items:center;gap:6px;font-size:.85rem}.kpi-label{color:#6c757d;font-weight:500}.kpi-value{font-weight:700;color:#212529;font-size:1.1rem;min-width:24px;text-align:center;background:#fff;padding:0 8px;border-radius:4px}.kpi-holidays{display:none}.months-grid{display:flex;gap:16px;justify-content:center;flex-wrap:wrap}.month-card{flex:1 1 auto;min-width:230px;max-width:300px;background:#fff;border:1px solid #dee2e6;border-radius:6px;padding:6px 4px 4px}.month-title{text-align:center;font-size:.85rem;font-weight:600;color:#212529;margin-bottom:4px;padding:2px 0}.calendar-table{width:100%;border-collapse:collapse;font-size:.7rem;table-layout:fixed}.calendar-table th{text-align:center;font-weight:600;color:#6c757d;padding:2px 0;font-size:.65rem}.calendar-table td{text-align:center;padding:2px 0;border-radius:3px;height:28px;vertical-align:middle;font-size:.7rem;transition:background .1s;position:relative}.other-month{color:#ced4da;background:transparent}.sunday{background:#ffe0e0}.disabled-sunday{background:#f1f3f5!important;color:#adb5bd!important;cursor:default}.in-range{background:#c4eeff}.start-date{background:#28a745!important;color:#fff!important;border-radius:3px 0 0 3px;font-weight:700}.end-date{background:#d17015!important;color:#fff!important;border-radius:0 3px 3px 0;font-weight:700}.same-day{background:#28a745!important;color:#fff!important;border-radius:3px}.day-number{display:block;font-size:.75rem;line-height:1.2}.holiday:not(.other-month){background:#e8f0fe!important;border:2px solid #1a5a8c!important;border-radius:4px!important;position:relative;z-index:1}.holiday .day-number{font-weight:700!important;color:#1a3a5c!important}.holiday-label{display:block;font-size:.45rem;line-height:1.2;color:#1a3a5c;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:95%;margin:0 auto;background:#1a5a8c1a;border-radius:2px;padding:0 2px;font-weight:600}.holiday:hover .holiday-label{white-space:normal;overflow:visible;position:absolute;bottom:100%;left:50%;transform:translate(-50%);background:#1a3a5c;color:#fff;padding:4px 10px;border-radius:4px;font-size:.6rem;z-index:10;box-shadow:0 2px 8px #0003;max-width:180px;white-space:nowrap}.holidays-detail{margin-top:12px;padding:10px 16px;background:#f0f4f8;border:1px solid #1a5a8c;border-radius:8px;border-left:4px solid #1a5a8c}.holidays-detail-title{font-size:.8rem;font-weight:600;color:#1a3a5c;margin-bottom:6px;display:flex;align-items:center;gap:6px}.holidays-detail-title i{color:#1a5a8c}.holidays-detail-list{display:flex;flex-wrap:wrap;gap:6px 12px}.holiday-detail-tag{font-size:.7rem;color:#1a3a5c;background:#e8f0fe;padding:2px 12px;border-radius:12px;border:1px solid #b3cfe5;display:inline-flex;align-items:center;gap:4px;white-space:nowrap}.holiday-detail-tag i{font-size:.6rem;color:#1a5a8c}.control-group input:disabled,.control-group input[disabled]{background:#f1f3f5!important;color:#6c757d!important;cursor:not-allowed;opacity:.7}.control-group input[type=checkbox]:disabled{cursor:not-allowed;opacity:.6}.control-group.checkbox label:has(input:disabled){color:#6c757d;cursor:not-allowed}@media(max-width:600px){.month-card{min-width:180px;max-width:100%}.controls{gap:10px;padding:8px 12px;flex-direction:column;align-items:stretch}.control-group{justify-content:space-between}.control-group input[type=date]{min-width:100px;flex:1}.control-group.checkbox{border-left:none;padding-left:0;justify-content:center}.kpi-container{gap:10px 16px;padding:8px 12px;justify-content:center}.kpi-item{font-size:.75rem}.kpi-value{font-size:.9rem;min-width:20px;padding:0 4px}.holidays-detail{padding:8px 12px}.holiday-detail-tag{font-size:.6rem;padding:2px 8px}}\n"] }]
|
|
5508
|
+
}], ctorParameters: () => [], propDecorators: { startDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "startDate", required: false }] }, { type: i0.Output, args: ["startDateChange"] }], endDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "endDate", required: false }] }, { type: i0.Output, args: ["endDateChange"] }], excludeSundays: [{ type: i0.Input, args: [{ isSignal: true, alias: "excludeSundays", required: false }] }, { type: i0.Output, args: ["excludeSundaysChange"] }], holidays: [{ type: i0.Input, args: [{ isSignal: true, alias: "holidays", required: false }] }], compactMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "compactMode", required: false }] }], showKPI: [{ type: i0.Input, args: [{ isSignal: true, alias: "showKPI", required: false }] }], debugMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "debugMode", required: false }] }], isEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "isEdit", required: false }] }], showControls: [{ type: i0.Input, args: [{ isSignal: true, alias: "showControls", required: false }] }], rangeChanged: [{ type: i0.Output, args: ["rangeChanged"] }] } });
|
|
5509
|
+
|
|
4977
5510
|
class FileComponent {
|
|
4978
5511
|
// Inputs
|
|
4979
5512
|
existingFile = input(null, ...(ngDevMode ? [{ debugName: "existingFile" }] : /* istanbul ignore next */ []));
|
|
@@ -5073,15 +5606,18 @@ class FileComponent {
|
|
|
5073
5606
|
const acceptStr = this.accept();
|
|
5074
5607
|
if (!acceptStr)
|
|
5075
5608
|
return 'archivo';
|
|
5076
|
-
const
|
|
5077
|
-
|
|
5078
|
-
.map((ext) => ext.replace('.', '').toUpperCase())
|
|
5609
|
+
const cleanExtensions = acceptStr
|
|
5610
|
+
.split(',')
|
|
5611
|
+
.map((ext) => ext.trim().replace('.', '').toUpperCase())
|
|
5079
5612
|
.filter((ext) => ext.length > 0);
|
|
5080
5613
|
if (cleanExtensions.length === 0)
|
|
5081
5614
|
return 'archivo';
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5615
|
+
// Formateador nativo en español para listas disyuntivas ("o")
|
|
5616
|
+
const formatter = new Intl.ListFormat('es', {
|
|
5617
|
+
style: 'long',
|
|
5618
|
+
type: 'disjunction',
|
|
5619
|
+
});
|
|
5620
|
+
return formatter.format(cleanExtensions);
|
|
5085
5621
|
}, ...(ngDevMode ? [{ debugName: "allowedFileTypeLabel" }] : /* istanbul ignore next */ []));
|
|
5086
5622
|
// --- Constructor ---
|
|
5087
5623
|
constructor() {
|
|
@@ -5412,7 +5948,7 @@ class FileComponent {
|
|
|
5412
5948
|
useExisting: forwardRef(() => FileComponent),
|
|
5413
5949
|
multi: true,
|
|
5414
5950
|
},
|
|
5415
|
-
], 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 flex-col gap-1\">\r\n <div class=\"flex items-center gap-2\">\r\n <p-fileUpload\r\n fluid\r\n #fileUpload\r\n chooseIcon=\"fa-solid fa-file-arrow-up\"\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()} ${allowedFileTypeLabel()}`\"\r\n [tooltipPosition]=\"tooltipPositionOverride()\"\r\n >\r\n <ng-template\r\n #header\r\n let-files\r\n let-chooseCallback=\"chooseCallback\"\r\n let-clearCallback=\"clearCallback\"\r\n >\r\n <!-- Mostrar el bot\u00F3n de upload SOLO si NO hay archivo seleccionado -->\r\n @if (!files || files.length === 0) {\r\n <p-button\r\n (onClick)=\"choose($event, chooseCallback)\"\r\n icon=\"fa-solid fa-cloud-arrow-up\"\r\n [rounded]=\"true\"\r\n [outlined]=\"true\"\r\n [disabled]=\"!isFileUploadEnabled()\"\r\n />\r\n }\r\n\r\n <span class=\"file-upload-placeholder\">\r\n <i class=\"fa-regular fa-file-lines placeholder-icon\"></i>\r\n <span class=\"placeholder-text\">\r\n @if (files && files.length > 0) {\r\n <span class=\"file-selected\">\r\n <i class=\"fa-regular fa-file-pdf file-icon\"></i>\r\n {{ files[0]?.name }}\r\n <span class=\"file-size\"\r\n >({{ formatFileSize(files[0]?.size) }})</span\r\n >\r\n </span>\r\n } @else if (allowedFileTypeLabel() !== \"archivo\") {\r\n <span class=\"empty-warning\">Ning\u00FAn</span>\r\n <span class=\"file-type empty-warning-type\">{{\r\n allowedFileTypeLabel()\r\n }}</span>\r\n <span class=\"empty-warning\">seleccionado</span>\r\n } @else {\r\n <span class=\"empty-warning\">Ning\u00FAn archivo seleccionado</span>\r\n }\r\n </span>\r\n </span>\r\n\r\n <!-- Mostrar bot\u00F3n de limpiar SOLO si hay archivo seleccionado -->\r\n @if (files && files.length > 0) {\r\n <p-button\r\n icon=\"fa-solid fa-xmark\"\r\n [rounded]=\"true\"\r\n [outlined]=\"true\"\r\n (onClick)=\"clear()\"\r\n [disabled]=\"!isFileUploadEnabled()\"\r\n styleClass=\"clear-button\"\r\n />\r\n }\r\n </ng-template>\r\n <!-- Ocultar la vista previa por defecto -->\r\n <ng-template #content></ng-template>\r\n <ng-template #file></ng-template>\r\n </p-fileUpload>\r\n\r\n <!-- Bot\u00F3n para cancelar remplazo -->\r\n @if (isReplacing()) {\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 <!-- Mensajes de error (validaci\u00F3n de PrimeNG) -->\r\n @if (errorMessage()) {\r\n <div class=\"file-error-message\">\r\n <i class=\"pi pi-exclamation-circle\"></i>\r\n {{ errorMessage() }}\r\n </div>\r\n }\r\n\r\n <!-- Mensaje de error del formulario (dsx-message-error) -->\r\n @if (showError() && errorControl()) {\r\n <dsx-message-error [control]=\"errorControl()\" />\r\n }\r\n </div>\r\n}\r\n\r\n<!-- Panel de Debug -->\r\n@if (debug() && isDevMode) {\r\n <div class=\"debug-panel\">\r\n <div class=\"debug-header\">\r\n <div class=\"debug-info\">\r\n <strong>\uD83D\uDD0D Debug File Upload:</strong>\r\n <span class=\"debug-item\"\r\n >Archivo: {{ value ? value.name : \"Ninguno\" }}</span\r\n >\r\n <span class=\"debug-item\"\r\n >Tama\u00F1o: {{ value ? formatFileSize(value.size) : \"-\" }}</span\r\n >\r\n <span class=\"debug-item\">Tipo: {{ value ? value.type : \"-\" }}</span>\r\n <span\r\n class=\"debug-item\"\r\n [style.color]=\"controlValid() ? '#10b981' : '#ef4444'\"\r\n >\r\n {{ controlValid() ? \"\u2705 V\u00E1lido\" : \"\u274C Inv\u00E1lido\" }}\r\n </span>\r\n <span class=\"debug-item\"\r\n >Required: {{ isRequired() ? \"\u2705\" : \"\u274C\" }}</span\r\n >\r\n <span class=\"debug-item\"\r\n >Reemplazando: {{ isReplacing() ? \"\u2705\" : \"\u274C\" }}</span\r\n >\r\n <!-- === ESTADOS ADICIONALES PARA DEBUG === -->\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA hasExistingFile: {{ hasExistingFile() ? \"\u2705\" : \"\u274C\" }}\r\n </span>\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA existingFileName: {{ existingFileName() || \"null\" }}\r\n </span>\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA isFileUploadEnabled: {{ isFileUploadEnabled() ? \"\u2705\" : \"\u274C\" }}\r\n </span>\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA showExistingFile: {{ showExistingFile() ? \"\u2705\" : \"\u274C\" }}\r\n </span>\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA value: {{ value ? value.name : \"null\" }}\r\n </span>\r\n </div>\r\n <div class=\"debug-actions\">\r\n <button (click)=\"forceReload()\" class=\"debug-btn\" type=\"button\">\r\n \uD83D\uDD04 Recargar\r\n </button>\r\n <button (click)=\"clear()\" class=\"debug-btn\" type=\"button\">\r\n \uD83E\uDDF9 Limpiar\r\n </button>\r\n <button (click)=\"diagnoseState()\" class=\"debug-btn\" type=\"button\">\r\n \uD83D\uDCCA Diagn\u00F3stico\r\n </button>\r\n </div>\r\n </div>\r\n @if (errorMessage()) {\r\n <div class=\"debug-error\">\r\n <strong>\u26A0\uFE0F Error activo:</strong> {{ errorMessage() }}\r\n </div>\r\n }\r\n @if (controlErrors()) {\r\n <div class=\"debug-errors\">\r\n <strong>\u274C Errores del formulario:</strong>\r\n <pre>{{ controlErrors() | json }}</pre>\r\n </div>\r\n }\r\n </div>\r\n}\r\n", styles: [".file-name{display:inline-block;font-weight:500;color:#1d8678;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}::ng-deep .p-fileupload .p-fileupload-header{display:flex!important;align-items:center!important;gap:.75rem!important;padding:0!important;border:none!important;background:transparent!important}::ng-deep .p-fileupload .p-fileupload-header .p-button{background:transparent!important;border:2px dashed #d1d5db!important;border-radius:8px!important;padding:.5rem 1rem!important;margin:.5rem!important;min-height:40px!important;min-width:40px!important;transition:all .25s ease!important;color:#6b7280!important}::ng-deep .p-fileupload .p-fileupload-header .p-button:not(:disabled):hover{border-color:#3b82f6!important;background:#eff6ff!important;box-shadow:0 0 0 3px #3b82f61a!important;color:#3b82f6!important}::ng-deep .p-fileupload .p-fileupload-header .p-button:disabled{opacity:.5!important;cursor:not-allowed!important;border-color:#e5e7eb!important;color:#9ca3af!important}::ng-deep .p-fileupload .p-fileupload-header .p-button .p-button-icon{font-size:1.2rem!important;transition:color .25s ease!important}.file-upload-placeholder{display:flex;align-items:center;gap:.75rem;pointer-events:none;white-space:nowrap;padding:0 .5rem}.placeholder-icon{font-size:1.35rem;color:#94a3b8;transition:all .3s ease}.placeholder-text{color:#94a3b8;font-size:.875rem;font-weight:400;transition:all .3s ease;letter-spacing:.01em}.placeholder-text .file-type{color:#64748b;font-size:.8rem;font-weight:600;transition:all .3s ease;letter-spacing:.03em;text-transform:uppercase;background:#f1f5f9;padding:.1rem .4rem;border-radius:4px;margin:0 .1rem}.placeholder-text .empty-warning{color:#d97706;font-weight:500;transition:color .3s ease}.placeholder-text .file-type.empty-warning-type{color:#b45309;background:#fef3c7;font-weight:600}.file-selected{display:flex;align-items:center;gap:.5rem;color:#1f2937;font-weight:500;font-size:.85rem}.file-selected .file-icon{font-size:1.2rem;color:#22994a}.file-selected .file-size{color:#9ca3af;font-weight:400;font-size:.75rem;margin-left:.25rem}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .placeholder-icon{color:#3b82f6}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .placeholder-text{color:#1f2937}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .file-type{color:#2563eb;background:#dbeafe}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .placeholder-text .empty-warning{color:#2563eb}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .file-type.empty-warning-type{color:#2563eb;background:#dbeafe}::ng-deep .p-fileupload .p-fileupload-buttonbar{display:none!important}::ng-deep .p-fileupload .p-fileupload-content{padding:0!important;border:none!important;background:transparent!important}::ng-deep .p-button.clear-button{background:transparent!important;border:none!important;border-radius:8px!important;padding:.5rem!important;min-width:40px!important;height:40px!important;transition:all .25s ease!important;display:flex!important;align-items:center!important;justify-content:center!important;box-shadow:none!important}::ng-deep .p-fileupload .p-fileupload-header .p-button.clear-button:not(:disabled):hover{background:none!important;border:none!important;box-shadow:none!important;transform:scale(1.05)!important}::ng-deep .p-button.clear-button .p-button-icon{color:#6b7280!important;font-size:1.1rem!important;transition:all .25s ease!important}::ng-deep .p-button.clear-button:not(:disabled):hover .p-button-icon{color:#ef4444!important}::ng-deep .p-button.clear-button:disabled{opacity:.5!important;cursor:not-allowed!important}.file-error-message{display:flex;align-items:center;gap:.5rem;color:#dc2626;font-size:.875rem;font-weight:400;padding:.25rem .75rem;background:#fef2f2;border-radius:6px;border:1px solid #fecaca;animation:slideDown .3s ease}.file-error-message i{font-size:1rem;color:#dc2626;flex-shrink:0}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.debug-panel{margin-top:8px;font-size:11px;color:#374151;background:#f8fafc;padding:8px 12px;border-radius:6px;font-family:monospace;border:1px solid #e2e8f0;width:100%}.debug-header{display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap}.debug-info{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.debug-item{font-size:11px;color:#475569}.debug-item strong{color:#1e293b}.debug-actions{display:flex;gap:6px}.debug-btn{font-size:10px;padding:2px 10px;border-radius:4px;border:1px solid #cbd5e1;background:#fff;cursor:pointer;transition:all .2s ease;color:#475569;font-family:monospace}.debug-btn:hover{background:#f1f5f9;border-color:#94a3b8}.debug-error,.debug-errors{margin-top:6px;padding:4px 8px;background:#fef2f2;border-radius:4px;color:#dc2626;font-size:11px;border:1px solid #fecaca}.debug-errors pre{margin:4px 0 0;font-size:10px;color:#991b1b;white-space:pre-wrap;word-break:break-all}@media(max-width:640px){.placeholder-icon{font-size:1.1rem!important}.placeholder-text{font-size:.75rem!important}.placeholder-text .file-type{font-size:.7rem!important;padding:.05rem .3rem!important}.file-selected{font-size:.75rem!important}.file-selected .file-icon{font-size:1rem!important}.file-selected .file-size{font-size:.65rem!important}::ng-deep .p-fileupload .p-fileupload-header .p-button{padding:.4rem .75rem!important;min-height:34px!important;min-width:34px!important}::ng-deep .p-button.clear-button{min-width:34px!important;height:34px!important}.file-error-message{font-size:.75rem!important;padding:.2rem .5rem!important}.debug-panel{font-size:10px;padding:6px 8px}.debug-item{font-size:10px}.debug-btn{font-size:9px;padding:2px 6px}}\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"] }, { kind: "component", type: AppMessageErrorComponent, selector: "dsx-message-error", inputs: ["control", "form", "debugMode"] }, { kind: "pipe", type: JsonPipe, name: "json" }] });
|
|
5951
|
+
], 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 flex-col gap-1\">\r\n <div class=\"flex items-center gap-2\">\r\n <p-fileUpload\r\n fluid\r\n #fileUpload\r\n chooseIcon=\"fa-solid fa-file-arrow-up\"\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()} ${allowedFileTypeLabel()}`\"\r\n [tooltipPosition]=\"tooltipPositionOverride()\"\r\n >\r\n <ng-template\r\n #header\r\n let-files\r\n let-chooseCallback=\"chooseCallback\"\r\n let-clearCallback=\"clearCallback\"\r\n >\r\n <!-- Mostrar el bot\u00F3n de upload SOLO si NO hay archivo seleccionado -->\r\n @if (!files || files.length === 0) {\r\n <p-button\r\n (onClick)=\"choose($event, chooseCallback)\"\r\n icon=\"fa-solid fa-cloud-arrow-up\"\r\n [rounded]=\"true\"\r\n [outlined]=\"true\"\r\n [disabled]=\"!isFileUploadEnabled()\"\r\n />\r\n }\r\n\r\n <span class=\"file-upload-placeholder\">\r\n <span class=\"placeholder-text\">\r\n @if (files && files.length > 0) {\r\n <span class=\"file-selected\">\r\n <i class=\"fa-solid fa-paperclip file-icon\"></i>\r\n {{ files[0]?.name }}\r\n <span class=\"file-size\"\r\n >({{ formatFileSize(files[0]?.size) }})</span\r\n >\r\n </span>\r\n } @else if (allowedFileTypeLabel() !== \"archivo\") {\r\n <i\r\n class=\"fa-regular fa-file-lines fa-fade placeholder-icon\"\r\n ></i>\r\n <span class=\"empty-warning\">Ning\u00FAn</span>\r\n <span class=\"file-type empty-warning-type\">{{\r\n allowedFileTypeLabel()\r\n }}</span>\r\n <span class=\"empty-warning\">seleccionado.</span>\r\n } @else {\r\n <span class=\"empty-warning\">Ning\u00FAn archivo seleccionado.</span>\r\n }\r\n </span>\r\n </span>\r\n\r\n <!-- Mostrar bot\u00F3n de limpiar SOLO si hay archivo seleccionado -->\r\n @if (files && files.length > 0) {\r\n <p-button\r\n icon=\"fa-solid fa-xmark\"\r\n [rounded]=\"true\"\r\n [outlined]=\"true\"\r\n (onClick)=\"clear()\"\r\n [disabled]=\"!isFileUploadEnabled()\"\r\n styleClass=\"clear-button\"\r\n />\r\n }\r\n </ng-template>\r\n <!-- Ocultar la vista previa por defecto -->\r\n <ng-template #content></ng-template>\r\n <ng-template #file></ng-template>\r\n </p-fileUpload>\r\n\r\n <!-- Bot\u00F3n para cancelar remplazo -->\r\n @if (isReplacing()) {\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 <!-- Mensajes de error (validaci\u00F3n de PrimeNG) -->\r\n @if (errorMessage()) {\r\n <div class=\"file-error-message\">\r\n <i class=\"pi pi-exclamation-circle\"></i>\r\n {{ errorMessage() }}\r\n </div>\r\n }\r\n\r\n <!-- Mensaje de error del formulario (dsx-message-error) -->\r\n @if (showError() && errorControl()) {\r\n <dsx-message-error [control]=\"errorControl()\" />\r\n }\r\n </div>\r\n}\r\n\r\n<!-- Panel de Debug -->\r\n@if (debug() && isDevMode) {\r\n <div class=\"debug-panel\">\r\n <div class=\"debug-header\">\r\n <div class=\"debug-info\">\r\n <strong>\uD83D\uDD0D Debug File Upload:</strong>\r\n <span class=\"debug-item\"\r\n >Archivo: {{ value ? value.name : \"Ninguno\" }}</span\r\n >\r\n <span class=\"debug-item\"\r\n >Tama\u00F1o: {{ value ? formatFileSize(value.size) : \"-\" }}</span\r\n >\r\n <span class=\"debug-item\">Tipo: {{ value ? value.type : \"-\" }}</span>\r\n <span\r\n class=\"debug-item\"\r\n [style.color]=\"controlValid() ? '#10b981' : '#ef4444'\"\r\n >\r\n {{ controlValid() ? \"\u2705 V\u00E1lido\" : \"\u274C Inv\u00E1lido\" }}\r\n </span>\r\n <span class=\"debug-item\"\r\n >Required: {{ isRequired() ? \"\u2705\" : \"\u274C\" }}</span\r\n >\r\n <span class=\"debug-item\"\r\n >Reemplazando: {{ isReplacing() ? \"\u2705\" : \"\u274C\" }}</span\r\n >\r\n <!-- === ESTADOS ADICIONALES PARA DEBUG === -->\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA hasExistingFile: {{ hasExistingFile() ? \"\u2705\" : \"\u274C\" }}\r\n </span>\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA existingFileName: {{ existingFileName() || \"null\" }}\r\n </span>\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA isFileUploadEnabled: {{ isFileUploadEnabled() ? \"\u2705\" : \"\u274C\" }}\r\n </span>\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA showExistingFile: {{ showExistingFile() ? \"\u2705\" : \"\u274C\" }}\r\n </span>\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA value: {{ value ? value.name : \"null\" }}\r\n </span>\r\n </div>\r\n <div class=\"debug-actions\">\r\n <button (click)=\"forceReload()\" class=\"debug-btn\" type=\"button\">\r\n \uD83D\uDD04 Recargar\r\n </button>\r\n <button (click)=\"clear()\" class=\"debug-btn\" type=\"button\">\r\n \uD83E\uDDF9 Limpiar\r\n </button>\r\n <button (click)=\"diagnoseState()\" class=\"debug-btn\" type=\"button\">\r\n \uD83D\uDCCA Diagn\u00F3stico\r\n </button>\r\n </div>\r\n </div>\r\n @if (errorMessage()) {\r\n <div class=\"debug-error\">\r\n <strong>\u26A0\uFE0F Error activo:</strong> {{ errorMessage() }}\r\n </div>\r\n }\r\n @if (controlErrors()) {\r\n <div class=\"debug-errors\">\r\n <strong>\u274C Errores del formulario:</strong>\r\n <pre>{{ controlErrors() | json }}</pre>\r\n </div>\r\n }\r\n </div>\r\n}\r\n", styles: [".file-name{display:inline-block;font-weight:500;color:#1d8678;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}::ng-deep .p-fileupload .p-fileupload-header{display:flex!important;align-items:center!important;gap:.75rem!important;padding:0!important;border:none!important;background:transparent!important}::ng-deep .p-fileupload .p-fileupload-header .p-button{background:transparent!important;border:2px dashed #d1d5db!important;border-radius:8px!important;padding:.5rem 1rem!important;margin:.5rem!important;min-height:40px!important;min-width:40px!important;transition:all .25s ease!important;color:#6b7280!important}::ng-deep .p-fileupload .p-fileupload-header .p-button:not(:disabled):hover{border-color:#3b82f6!important;background:#eff6ff!important;box-shadow:0 0 0 3px #3b82f61a!important;color:#3b82f6!important}::ng-deep .p-fileupload .p-fileupload-header .p-button:disabled{opacity:.5!important;cursor:not-allowed!important;border-color:#e5e7eb!important;color:#9ca3af!important}::ng-deep .p-fileupload .p-fileupload-header .p-button .p-button-icon{font-size:1.2rem!important;transition:color .25s ease!important}.file-upload-placeholder{display:flex;align-items:center;gap:.75rem;pointer-events:none;white-space:nowrap;padding:0 .5rem}.placeholder-icon{font-size:1.35rem;color:#94a3b8;transition:all .3s ease}.placeholder-text{color:#94a3b8;font-size:.875rem;font-weight:400;transition:all .3s ease;letter-spacing:.01em}.placeholder-text .file-type{color:#64748b;font-size:.8rem;font-weight:600;transition:all .3s ease;letter-spacing:.03em;text-transform:uppercase;background:#f1f5f9;padding:.1rem .4rem;border-radius:4px;margin:0 .1rem}.placeholder-text .empty-warning{color:#d97706;font-weight:500;transition:color .3s ease}.placeholder-text .file-type.empty-warning-type{color:#3f3e37;background:#dfc800;font-weight:600}.file-selected{display:flex;align-items:center;gap:.5rem;color:#1f2937;font-weight:500;font-size:.85rem}.file-selected .file-icon{font-size:1.2rem;color:#3ad46d}.file-selected .file-size{color:#9ca3af;font-weight:400;font-size:.75rem;margin-left:.25rem}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .placeholder-icon{color:#3b82f6}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .placeholder-text{color:#1f2937}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .file-type{color:#2563eb;background:#dbeafe}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .placeholder-text .empty-warning{color:#2563eb}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .file-type.empty-warning-type{color:#2563eb;background:#dbeafe}::ng-deep .p-fileupload .p-fileupload-buttonbar{display:none!important}::ng-deep .p-fileupload .p-fileupload-content{padding:0!important;border:none!important;background:transparent!important}::ng-deep .p-button.clear-button{background:transparent!important;border:none!important;border-radius:8px!important;padding:.5rem!important;min-width:40px!important;height:40px!important;transition:all .25s ease!important;display:flex!important;align-items:center!important;justify-content:center!important;box-shadow:none!important}::ng-deep .p-fileupload .p-fileupload-header .p-button.clear-button:not(:disabled):hover{background:none!important;border:none!important;box-shadow:none!important;transform:scale(1.05)!important}::ng-deep .p-button.clear-button .p-button-icon{color:#6b7280!important;font-size:1.1rem!important;transition:all .25s ease!important}::ng-deep .p-button.clear-button:not(:disabled):hover .p-button-icon{color:#ef4444!important}::ng-deep .p-button.clear-button:disabled{opacity:.5!important;cursor:not-allowed!important}.file-error-message{display:flex;align-items:center;gap:.5rem;color:#dc2626;font-size:.875rem;font-weight:400;padding:.25rem .75rem;background:#fef2f2;border-radius:6px;border:1px solid #fecaca;animation:slideDown .3s ease}.file-error-message i{font-size:1rem;color:#dc2626;flex-shrink:0}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.debug-panel{margin-top:8px;font-size:11px;color:#374151;background:#f8fafc;padding:8px 12px;border-radius:6px;font-family:monospace;border:1px solid #e2e8f0;width:100%}.debug-header{display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap}.debug-info{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.debug-item{font-size:11px;color:#475569}.debug-item strong{color:#1e293b}.debug-actions{display:flex;gap:6px}.debug-btn{font-size:10px;padding:2px 10px;border-radius:4px;border:1px solid #cbd5e1;background:#fff;cursor:pointer;transition:all .2s ease;color:#475569;font-family:monospace}.debug-btn:hover{background:#f1f5f9;border-color:#94a3b8}.debug-error,.debug-errors{margin-top:6px;padding:4px 8px;background:#fef2f2;border-radius:4px;color:#dc2626;font-size:11px;border:1px solid #fecaca}.debug-errors pre{margin:4px 0 0;font-size:10px;color:#991b1b;white-space:pre-wrap;word-break:break-all}@media(max-width:640px){.placeholder-icon{font-size:1.1rem!important}.placeholder-text{font-size:.75rem!important}.placeholder-text .file-type{font-size:.7rem!important;padding:.05rem .3rem!important}.file-selected{font-size:.75rem!important}.file-selected .file-icon{font-size:1rem!important}.file-selected .file-size{font-size:.65rem!important}::ng-deep .p-fileupload .p-fileupload-header .p-button{padding:.4rem .75rem!important;min-height:34px!important;min-width:34px!important}::ng-deep .p-button.clear-button{min-width:34px!important;height:34px!important}.file-error-message{font-size:.75rem!important;padding:.2rem .5rem!important}.debug-panel{font-size:10px;padding:6px 8px}.debug-item{font-size:10px}.debug-btn{font-size:9px;padding:2px 6px}}\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"] }, { kind: "component", type: AppMessageErrorComponent, selector: "dsx-message-error", inputs: ["control", "form", "debugMode"] }, { kind: "pipe", type: JsonPipe, name: "json" }] });
|
|
5416
5952
|
}
|
|
5417
5953
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: FileComponent, decorators: [{
|
|
5418
5954
|
type: Component,
|
|
@@ -5427,7 +5963,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
5427
5963
|
useExisting: forwardRef(() => FileComponent),
|
|
5428
5964
|
multi: true,
|
|
5429
5965
|
},
|
|
5430
|
-
], 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 flex-col gap-1\">\r\n <div class=\"flex items-center gap-2\">\r\n <p-fileUpload\r\n fluid\r\n #fileUpload\r\n chooseIcon=\"fa-solid fa-file-arrow-up\"\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()} ${allowedFileTypeLabel()}`\"\r\n [tooltipPosition]=\"tooltipPositionOverride()\"\r\n >\r\n <ng-template\r\n #header\r\n let-files\r\n let-chooseCallback=\"chooseCallback\"\r\n let-clearCallback=\"clearCallback\"\r\n >\r\n <!-- Mostrar el bot\u00F3n de upload SOLO si NO hay archivo seleccionado -->\r\n @if (!files || files.length === 0) {\r\n <p-button\r\n (onClick)=\"choose($event, chooseCallback)\"\r\n icon=\"fa-solid fa-cloud-arrow-up\"\r\n [rounded]=\"true\"\r\n [outlined]=\"true\"\r\n [disabled]=\"!isFileUploadEnabled()\"\r\n />\r\n }\r\n\r\n <span class=\"file-upload-placeholder\">\r\n <i class=\"fa-regular fa-file-lines placeholder-icon\"></i>\r\n <span class=\"placeholder-text\">\r\n @if (files && files.length > 0) {\r\n <span class=\"file-selected\">\r\n <i class=\"fa-regular fa-file-pdf file-icon\"></i>\r\n {{ files[0]?.name }}\r\n <span class=\"file-size\"\r\n >({{ formatFileSize(files[0]?.size) }})</span\r\n >\r\n </span>\r\n } @else if (allowedFileTypeLabel() !== \"archivo\") {\r\n <span class=\"empty-warning\">Ning\u00FAn</span>\r\n <span class=\"file-type empty-warning-type\">{{\r\n allowedFileTypeLabel()\r\n }}</span>\r\n <span class=\"empty-warning\">seleccionado</span>\r\n } @else {\r\n <span class=\"empty-warning\">Ning\u00FAn archivo seleccionado</span>\r\n }\r\n </span>\r\n </span>\r\n\r\n <!-- Mostrar bot\u00F3n de limpiar SOLO si hay archivo seleccionado -->\r\n @if (files && files.length > 0) {\r\n <p-button\r\n icon=\"fa-solid fa-xmark\"\r\n [rounded]=\"true\"\r\n [outlined]=\"true\"\r\n (onClick)=\"clear()\"\r\n [disabled]=\"!isFileUploadEnabled()\"\r\n styleClass=\"clear-button\"\r\n />\r\n }\r\n </ng-template>\r\n <!-- Ocultar la vista previa por defecto -->\r\n <ng-template #content></ng-template>\r\n <ng-template #file></ng-template>\r\n </p-fileUpload>\r\n\r\n <!-- Bot\u00F3n para cancelar remplazo -->\r\n @if (isReplacing()) {\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 <!-- Mensajes de error (validaci\u00F3n de PrimeNG) -->\r\n @if (errorMessage()) {\r\n <div class=\"file-error-message\">\r\n <i class=\"pi pi-exclamation-circle\"></i>\r\n {{ errorMessage() }}\r\n </div>\r\n }\r\n\r\n <!-- Mensaje de error del formulario (dsx-message-error) -->\r\n @if (showError() && errorControl()) {\r\n <dsx-message-error [control]=\"errorControl()\" />\r\n }\r\n </div>\r\n}\r\n\r\n<!-- Panel de Debug -->\r\n@if (debug() && isDevMode) {\r\n <div class=\"debug-panel\">\r\n <div class=\"debug-header\">\r\n <div class=\"debug-info\">\r\n <strong>\uD83D\uDD0D Debug File Upload:</strong>\r\n <span class=\"debug-item\"\r\n >Archivo: {{ value ? value.name : \"Ninguno\" }}</span\r\n >\r\n <span class=\"debug-item\"\r\n >Tama\u00F1o: {{ value ? formatFileSize(value.size) : \"-\" }}</span\r\n >\r\n <span class=\"debug-item\">Tipo: {{ value ? value.type : \"-\" }}</span>\r\n <span\r\n class=\"debug-item\"\r\n [style.color]=\"controlValid() ? '#10b981' : '#ef4444'\"\r\n >\r\n {{ controlValid() ? \"\u2705 V\u00E1lido\" : \"\u274C Inv\u00E1lido\" }}\r\n </span>\r\n <span class=\"debug-item\"\r\n >Required: {{ isRequired() ? \"\u2705\" : \"\u274C\" }}</span\r\n >\r\n <span class=\"debug-item\"\r\n >Reemplazando: {{ isReplacing() ? \"\u2705\" : \"\u274C\" }}</span\r\n >\r\n <!-- === ESTADOS ADICIONALES PARA DEBUG === -->\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA hasExistingFile: {{ hasExistingFile() ? \"\u2705\" : \"\u274C\" }}\r\n </span>\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA existingFileName: {{ existingFileName() || \"null\" }}\r\n </span>\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA isFileUploadEnabled: {{ isFileUploadEnabled() ? \"\u2705\" : \"\u274C\" }}\r\n </span>\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA showExistingFile: {{ showExistingFile() ? \"\u2705\" : \"\u274C\" }}\r\n </span>\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA value: {{ value ? value.name : \"null\" }}\r\n </span>\r\n </div>\r\n <div class=\"debug-actions\">\r\n <button (click)=\"forceReload()\" class=\"debug-btn\" type=\"button\">\r\n \uD83D\uDD04 Recargar\r\n </button>\r\n <button (click)=\"clear()\" class=\"debug-btn\" type=\"button\">\r\n \uD83E\uDDF9 Limpiar\r\n </button>\r\n <button (click)=\"diagnoseState()\" class=\"debug-btn\" type=\"button\">\r\n \uD83D\uDCCA Diagn\u00F3stico\r\n </button>\r\n </div>\r\n </div>\r\n @if (errorMessage()) {\r\n <div class=\"debug-error\">\r\n <strong>\u26A0\uFE0F Error activo:</strong> {{ errorMessage() }}\r\n </div>\r\n }\r\n @if (controlErrors()) {\r\n <div class=\"debug-errors\">\r\n <strong>\u274C Errores del formulario:</strong>\r\n <pre>{{ controlErrors() | json }}</pre>\r\n </div>\r\n }\r\n </div>\r\n}\r\n", styles: [".file-name{display:inline-block;font-weight:500;color:#1d8678;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}::ng-deep .p-fileupload .p-fileupload-header{display:flex!important;align-items:center!important;gap:.75rem!important;padding:0!important;border:none!important;background:transparent!important}::ng-deep .p-fileupload .p-fileupload-header .p-button{background:transparent!important;border:2px dashed #d1d5db!important;border-radius:8px!important;padding:.5rem 1rem!important;margin:.5rem!important;min-height:40px!important;min-width:40px!important;transition:all .25s ease!important;color:#6b7280!important}::ng-deep .p-fileupload .p-fileupload-header .p-button:not(:disabled):hover{border-color:#3b82f6!important;background:#eff6ff!important;box-shadow:0 0 0 3px #3b82f61a!important;color:#3b82f6!important}::ng-deep .p-fileupload .p-fileupload-header .p-button:disabled{opacity:.5!important;cursor:not-allowed!important;border-color:#e5e7eb!important;color:#9ca3af!important}::ng-deep .p-fileupload .p-fileupload-header .p-button .p-button-icon{font-size:1.2rem!important;transition:color .25s ease!important}.file-upload-placeholder{display:flex;align-items:center;gap:.75rem;pointer-events:none;white-space:nowrap;padding:0 .5rem}.placeholder-icon{font-size:1.35rem;color:#94a3b8;transition:all .3s ease}.placeholder-text{color:#94a3b8;font-size:.875rem;font-weight:400;transition:all .3s ease;letter-spacing:.01em}.placeholder-text .file-type{color:#64748b;font-size:.8rem;font-weight:600;transition:all .3s ease;letter-spacing:.03em;text-transform:uppercase;background:#f1f5f9;padding:.1rem .4rem;border-radius:4px;margin:0 .1rem}.placeholder-text .empty-warning{color:#d97706;font-weight:500;transition:color .3s ease}.placeholder-text .file-type.empty-warning-type{color:#b45309;background:#fef3c7;font-weight:600}.file-selected{display:flex;align-items:center;gap:.5rem;color:#1f2937;font-weight:500;font-size:.85rem}.file-selected .file-icon{font-size:1.2rem;color:#22994a}.file-selected .file-size{color:#9ca3af;font-weight:400;font-size:.75rem;margin-left:.25rem}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .placeholder-icon{color:#3b82f6}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .placeholder-text{color:#1f2937}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .file-type{color:#2563eb;background:#dbeafe}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .placeholder-text .empty-warning{color:#2563eb}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .file-type.empty-warning-type{color:#2563eb;background:#dbeafe}::ng-deep .p-fileupload .p-fileupload-buttonbar{display:none!important}::ng-deep .p-fileupload .p-fileupload-content{padding:0!important;border:none!important;background:transparent!important}::ng-deep .p-button.clear-button{background:transparent!important;border:none!important;border-radius:8px!important;padding:.5rem!important;min-width:40px!important;height:40px!important;transition:all .25s ease!important;display:flex!important;align-items:center!important;justify-content:center!important;box-shadow:none!important}::ng-deep .p-fileupload .p-fileupload-header .p-button.clear-button:not(:disabled):hover{background:none!important;border:none!important;box-shadow:none!important;transform:scale(1.05)!important}::ng-deep .p-button.clear-button .p-button-icon{color:#6b7280!important;font-size:1.1rem!important;transition:all .25s ease!important}::ng-deep .p-button.clear-button:not(:disabled):hover .p-button-icon{color:#ef4444!important}::ng-deep .p-button.clear-button:disabled{opacity:.5!important;cursor:not-allowed!important}.file-error-message{display:flex;align-items:center;gap:.5rem;color:#dc2626;font-size:.875rem;font-weight:400;padding:.25rem .75rem;background:#fef2f2;border-radius:6px;border:1px solid #fecaca;animation:slideDown .3s ease}.file-error-message i{font-size:1rem;color:#dc2626;flex-shrink:0}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.debug-panel{margin-top:8px;font-size:11px;color:#374151;background:#f8fafc;padding:8px 12px;border-radius:6px;font-family:monospace;border:1px solid #e2e8f0;width:100%}.debug-header{display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap}.debug-info{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.debug-item{font-size:11px;color:#475569}.debug-item strong{color:#1e293b}.debug-actions{display:flex;gap:6px}.debug-btn{font-size:10px;padding:2px 10px;border-radius:4px;border:1px solid #cbd5e1;background:#fff;cursor:pointer;transition:all .2s ease;color:#475569;font-family:monospace}.debug-btn:hover{background:#f1f5f9;border-color:#94a3b8}.debug-error,.debug-errors{margin-top:6px;padding:4px 8px;background:#fef2f2;border-radius:4px;color:#dc2626;font-size:11px;border:1px solid #fecaca}.debug-errors pre{margin:4px 0 0;font-size:10px;color:#991b1b;white-space:pre-wrap;word-break:break-all}@media(max-width:640px){.placeholder-icon{font-size:1.1rem!important}.placeholder-text{font-size:.75rem!important}.placeholder-text .file-type{font-size:.7rem!important;padding:.05rem .3rem!important}.file-selected{font-size:.75rem!important}.file-selected .file-icon{font-size:1rem!important}.file-selected .file-size{font-size:.65rem!important}::ng-deep .p-fileupload .p-fileupload-header .p-button{padding:.4rem .75rem!important;min-height:34px!important;min-width:34px!important}::ng-deep .p-button.clear-button{min-width:34px!important;height:34px!important}.file-error-message{font-size:.75rem!important;padding:.2rem .5rem!important}.debug-panel{font-size:10px;padding:6px 8px}.debug-item{font-size:10px}.debug-btn{font-size:9px;padding:2px 6px}}\n"] }]
|
|
5966
|
+
], 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 flex-col gap-1\">\r\n <div class=\"flex items-center gap-2\">\r\n <p-fileUpload\r\n fluid\r\n #fileUpload\r\n chooseIcon=\"fa-solid fa-file-arrow-up\"\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()} ${allowedFileTypeLabel()}`\"\r\n [tooltipPosition]=\"tooltipPositionOverride()\"\r\n >\r\n <ng-template\r\n #header\r\n let-files\r\n let-chooseCallback=\"chooseCallback\"\r\n let-clearCallback=\"clearCallback\"\r\n >\r\n <!-- Mostrar el bot\u00F3n de upload SOLO si NO hay archivo seleccionado -->\r\n @if (!files || files.length === 0) {\r\n <p-button\r\n (onClick)=\"choose($event, chooseCallback)\"\r\n icon=\"fa-solid fa-cloud-arrow-up\"\r\n [rounded]=\"true\"\r\n [outlined]=\"true\"\r\n [disabled]=\"!isFileUploadEnabled()\"\r\n />\r\n }\r\n\r\n <span class=\"file-upload-placeholder\">\r\n <span class=\"placeholder-text\">\r\n @if (files && files.length > 0) {\r\n <span class=\"file-selected\">\r\n <i class=\"fa-solid fa-paperclip file-icon\"></i>\r\n {{ files[0]?.name }}\r\n <span class=\"file-size\"\r\n >({{ formatFileSize(files[0]?.size) }})</span\r\n >\r\n </span>\r\n } @else if (allowedFileTypeLabel() !== \"archivo\") {\r\n <i\r\n class=\"fa-regular fa-file-lines fa-fade placeholder-icon\"\r\n ></i>\r\n <span class=\"empty-warning\">Ning\u00FAn</span>\r\n <span class=\"file-type empty-warning-type\">{{\r\n allowedFileTypeLabel()\r\n }}</span>\r\n <span class=\"empty-warning\">seleccionado.</span>\r\n } @else {\r\n <span class=\"empty-warning\">Ning\u00FAn archivo seleccionado.</span>\r\n }\r\n </span>\r\n </span>\r\n\r\n <!-- Mostrar bot\u00F3n de limpiar SOLO si hay archivo seleccionado -->\r\n @if (files && files.length > 0) {\r\n <p-button\r\n icon=\"fa-solid fa-xmark\"\r\n [rounded]=\"true\"\r\n [outlined]=\"true\"\r\n (onClick)=\"clear()\"\r\n [disabled]=\"!isFileUploadEnabled()\"\r\n styleClass=\"clear-button\"\r\n />\r\n }\r\n </ng-template>\r\n <!-- Ocultar la vista previa por defecto -->\r\n <ng-template #content></ng-template>\r\n <ng-template #file></ng-template>\r\n </p-fileUpload>\r\n\r\n <!-- Bot\u00F3n para cancelar remplazo -->\r\n @if (isReplacing()) {\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 <!-- Mensajes de error (validaci\u00F3n de PrimeNG) -->\r\n @if (errorMessage()) {\r\n <div class=\"file-error-message\">\r\n <i class=\"pi pi-exclamation-circle\"></i>\r\n {{ errorMessage() }}\r\n </div>\r\n }\r\n\r\n <!-- Mensaje de error del formulario (dsx-message-error) -->\r\n @if (showError() && errorControl()) {\r\n <dsx-message-error [control]=\"errorControl()\" />\r\n }\r\n </div>\r\n}\r\n\r\n<!-- Panel de Debug -->\r\n@if (debug() && isDevMode) {\r\n <div class=\"debug-panel\">\r\n <div class=\"debug-header\">\r\n <div class=\"debug-info\">\r\n <strong>\uD83D\uDD0D Debug File Upload:</strong>\r\n <span class=\"debug-item\"\r\n >Archivo: {{ value ? value.name : \"Ninguno\" }}</span\r\n >\r\n <span class=\"debug-item\"\r\n >Tama\u00F1o: {{ value ? formatFileSize(value.size) : \"-\" }}</span\r\n >\r\n <span class=\"debug-item\">Tipo: {{ value ? value.type : \"-\" }}</span>\r\n <span\r\n class=\"debug-item\"\r\n [style.color]=\"controlValid() ? '#10b981' : '#ef4444'\"\r\n >\r\n {{ controlValid() ? \"\u2705 V\u00E1lido\" : \"\u274C Inv\u00E1lido\" }}\r\n </span>\r\n <span class=\"debug-item\"\r\n >Required: {{ isRequired() ? \"\u2705\" : \"\u274C\" }}</span\r\n >\r\n <span class=\"debug-item\"\r\n >Reemplazando: {{ isReplacing() ? \"\u2705\" : \"\u274C\" }}</span\r\n >\r\n <!-- === ESTADOS ADICIONALES PARA DEBUG === -->\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA hasExistingFile: {{ hasExistingFile() ? \"\u2705\" : \"\u274C\" }}\r\n </span>\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA existingFileName: {{ existingFileName() || \"null\" }}\r\n </span>\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA isFileUploadEnabled: {{ isFileUploadEnabled() ? \"\u2705\" : \"\u274C\" }}\r\n </span>\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA showExistingFile: {{ showExistingFile() ? \"\u2705\" : \"\u274C\" }}\r\n </span>\r\n <span\r\n class=\"debug-item\"\r\n style=\"background: #f0f0f0; padding: 0 6px; border-radius: 4px\"\r\n >\r\n \uD83D\uDCCA value: {{ value ? value.name : \"null\" }}\r\n </span>\r\n </div>\r\n <div class=\"debug-actions\">\r\n <button (click)=\"forceReload()\" class=\"debug-btn\" type=\"button\">\r\n \uD83D\uDD04 Recargar\r\n </button>\r\n <button (click)=\"clear()\" class=\"debug-btn\" type=\"button\">\r\n \uD83E\uDDF9 Limpiar\r\n </button>\r\n <button (click)=\"diagnoseState()\" class=\"debug-btn\" type=\"button\">\r\n \uD83D\uDCCA Diagn\u00F3stico\r\n </button>\r\n </div>\r\n </div>\r\n @if (errorMessage()) {\r\n <div class=\"debug-error\">\r\n <strong>\u26A0\uFE0F Error activo:</strong> {{ errorMessage() }}\r\n </div>\r\n }\r\n @if (controlErrors()) {\r\n <div class=\"debug-errors\">\r\n <strong>\u274C Errores del formulario:</strong>\r\n <pre>{{ controlErrors() | json }}</pre>\r\n </div>\r\n }\r\n </div>\r\n}\r\n", styles: [".file-name{display:inline-block;font-weight:500;color:#1d8678;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}::ng-deep .p-fileupload .p-fileupload-header{display:flex!important;align-items:center!important;gap:.75rem!important;padding:0!important;border:none!important;background:transparent!important}::ng-deep .p-fileupload .p-fileupload-header .p-button{background:transparent!important;border:2px dashed #d1d5db!important;border-radius:8px!important;padding:.5rem 1rem!important;margin:.5rem!important;min-height:40px!important;min-width:40px!important;transition:all .25s ease!important;color:#6b7280!important}::ng-deep .p-fileupload .p-fileupload-header .p-button:not(:disabled):hover{border-color:#3b82f6!important;background:#eff6ff!important;box-shadow:0 0 0 3px #3b82f61a!important;color:#3b82f6!important}::ng-deep .p-fileupload .p-fileupload-header .p-button:disabled{opacity:.5!important;cursor:not-allowed!important;border-color:#e5e7eb!important;color:#9ca3af!important}::ng-deep .p-fileupload .p-fileupload-header .p-button .p-button-icon{font-size:1.2rem!important;transition:color .25s ease!important}.file-upload-placeholder{display:flex;align-items:center;gap:.75rem;pointer-events:none;white-space:nowrap;padding:0 .5rem}.placeholder-icon{font-size:1.35rem;color:#94a3b8;transition:all .3s ease}.placeholder-text{color:#94a3b8;font-size:.875rem;font-weight:400;transition:all .3s ease;letter-spacing:.01em}.placeholder-text .file-type{color:#64748b;font-size:.8rem;font-weight:600;transition:all .3s ease;letter-spacing:.03em;text-transform:uppercase;background:#f1f5f9;padding:.1rem .4rem;border-radius:4px;margin:0 .1rem}.placeholder-text .empty-warning{color:#d97706;font-weight:500;transition:color .3s ease}.placeholder-text .file-type.empty-warning-type{color:#3f3e37;background:#dfc800;font-weight:600}.file-selected{display:flex;align-items:center;gap:.5rem;color:#1f2937;font-weight:500;font-size:.85rem}.file-selected .file-icon{font-size:1.2rem;color:#3ad46d}.file-selected .file-size{color:#9ca3af;font-weight:400;font-size:.75rem;margin-left:.25rem}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .placeholder-icon{color:#3b82f6}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .placeholder-text{color:#1f2937}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .file-type{color:#2563eb;background:#dbeafe}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .placeholder-text .empty-warning{color:#2563eb}::ng-deep .p-fileupload .p-fileupload-header:has(.p-button:not(:disabled):hover) .file-type.empty-warning-type{color:#2563eb;background:#dbeafe}::ng-deep .p-fileupload .p-fileupload-buttonbar{display:none!important}::ng-deep .p-fileupload .p-fileupload-content{padding:0!important;border:none!important;background:transparent!important}::ng-deep .p-button.clear-button{background:transparent!important;border:none!important;border-radius:8px!important;padding:.5rem!important;min-width:40px!important;height:40px!important;transition:all .25s ease!important;display:flex!important;align-items:center!important;justify-content:center!important;box-shadow:none!important}::ng-deep .p-fileupload .p-fileupload-header .p-button.clear-button:not(:disabled):hover{background:none!important;border:none!important;box-shadow:none!important;transform:scale(1.05)!important}::ng-deep .p-button.clear-button .p-button-icon{color:#6b7280!important;font-size:1.1rem!important;transition:all .25s ease!important}::ng-deep .p-button.clear-button:not(:disabled):hover .p-button-icon{color:#ef4444!important}::ng-deep .p-button.clear-button:disabled{opacity:.5!important;cursor:not-allowed!important}.file-error-message{display:flex;align-items:center;gap:.5rem;color:#dc2626;font-size:.875rem;font-weight:400;padding:.25rem .75rem;background:#fef2f2;border-radius:6px;border:1px solid #fecaca;animation:slideDown .3s ease}.file-error-message i{font-size:1rem;color:#dc2626;flex-shrink:0}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.debug-panel{margin-top:8px;font-size:11px;color:#374151;background:#f8fafc;padding:8px 12px;border-radius:6px;font-family:monospace;border:1px solid #e2e8f0;width:100%}.debug-header{display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap}.debug-info{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.debug-item{font-size:11px;color:#475569}.debug-item strong{color:#1e293b}.debug-actions{display:flex;gap:6px}.debug-btn{font-size:10px;padding:2px 10px;border-radius:4px;border:1px solid #cbd5e1;background:#fff;cursor:pointer;transition:all .2s ease;color:#475569;font-family:monospace}.debug-btn:hover{background:#f1f5f9;border-color:#94a3b8}.debug-error,.debug-errors{margin-top:6px;padding:4px 8px;background:#fef2f2;border-radius:4px;color:#dc2626;font-size:11px;border:1px solid #fecaca}.debug-errors pre{margin:4px 0 0;font-size:10px;color:#991b1b;white-space:pre-wrap;word-break:break-all}@media(max-width:640px){.placeholder-icon{font-size:1.1rem!important}.placeholder-text{font-size:.75rem!important}.placeholder-text .file-type{font-size:.7rem!important;padding:.05rem .3rem!important}.file-selected{font-size:.75rem!important}.file-selected .file-icon{font-size:1rem!important}.file-selected .file-size{font-size:.65rem!important}::ng-deep .p-fileupload .p-fileupload-header .p-button{padding:.4rem .75rem!important;min-height:34px!important;min-width:34px!important}::ng-deep .p-button.clear-button{min-width:34px!important;height:34px!important}.file-error-message{font-size:.75rem!important;padding:.2rem .5rem!important}.debug-panel{font-size:10px;padding:6px 8px}.debug-item{font-size:10px}.debug-btn{font-size:9px;padding:2px 6px}}\n"] }]
|
|
5431
5967
|
}], 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 }] }], 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 }] }] } });
|
|
5432
5968
|
|
|
5433
5969
|
function uid() {
|
|
@@ -5626,64 +6162,91 @@ class JsonValuesDebujComponent {
|
|
|
5626
6162
|
}
|
|
5627
6163
|
return files;
|
|
5628
6164
|
}
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
6165
|
+
// ✅ Método para serializar cualquier valor (incluyendo fechas)
|
|
6166
|
+
serializeValue(value) {
|
|
6167
|
+
// Si es null o undefined
|
|
6168
|
+
if (value === null || value === undefined) {
|
|
6169
|
+
return null;
|
|
5633
6170
|
}
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
this.serializedValue.set(JSON.stringify(copy, null, 2));
|
|
6171
|
+
// ✅ Si es un objeto Date, convertirlo a string ISO
|
|
6172
|
+
if (value instanceof Date) {
|
|
6173
|
+
return value.toISOString();
|
|
5638
6174
|
}
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
console.error('[JsonDebug] Error serializing value:', error);
|
|
5643
|
-
}
|
|
6175
|
+
// ✅ Si es un objeto moment (si usas moment.js)
|
|
6176
|
+
if (value && typeof value === 'object' && value._isAMomentObject) {
|
|
6177
|
+
return value.toISOString();
|
|
5644
6178
|
}
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
6179
|
+
// ✅ Si es un objeto dayjs (si usas dayjs)
|
|
6180
|
+
if (value &&
|
|
6181
|
+
typeof value === 'object' &&
|
|
6182
|
+
value.$d &&
|
|
6183
|
+
value.$d instanceof Date) {
|
|
6184
|
+
return value.toISOString();
|
|
6185
|
+
}
|
|
6186
|
+
// ✅ Si es un objeto con propiedades de fecha (como { year, month, day })
|
|
6187
|
+
if (value &&
|
|
6188
|
+
typeof value === 'object' &&
|
|
6189
|
+
value.year !== undefined &&
|
|
6190
|
+
value.month !== undefined &&
|
|
6191
|
+
value.day !== undefined) {
|
|
6192
|
+
try {
|
|
6193
|
+
const date = new Date(value.year, value.month - 1, value.day);
|
|
6194
|
+
return date.toISOString();
|
|
6195
|
+
}
|
|
6196
|
+
catch (e) {
|
|
6197
|
+
return value;
|
|
6198
|
+
}
|
|
5650
6199
|
}
|
|
5651
6200
|
// Si es un File o Blob, extraer sus propiedades
|
|
5652
|
-
if (
|
|
6201
|
+
if (value instanceof File || value instanceof Blob) {
|
|
5653
6202
|
const fileProps = {
|
|
5654
|
-
__type:
|
|
6203
|
+
__type: value instanceof File ? 'File' : 'Blob',
|
|
5655
6204
|
};
|
|
5656
|
-
if ('name' in
|
|
5657
|
-
fileProps.name =
|
|
6205
|
+
if ('name' in value && value.name !== undefined) {
|
|
6206
|
+
fileProps.name = value.name;
|
|
5658
6207
|
}
|
|
5659
|
-
if ('size' in
|
|
5660
|
-
fileProps.size =
|
|
6208
|
+
if ('size' in value && value.size !== undefined) {
|
|
6209
|
+
fileProps.size = value.size;
|
|
5661
6210
|
}
|
|
5662
|
-
if ('type' in
|
|
5663
|
-
fileProps.type =
|
|
6211
|
+
if ('type' in value && value.type !== undefined) {
|
|
6212
|
+
fileProps.type = value.type;
|
|
5664
6213
|
}
|
|
5665
|
-
if ('lastModified' in
|
|
5666
|
-
fileProps.lastModified =
|
|
6214
|
+
if ('lastModified' in value && value.lastModified !== undefined) {
|
|
6215
|
+
fileProps.lastModified = value.lastModified;
|
|
5667
6216
|
}
|
|
5668
6217
|
return fileProps;
|
|
5669
6218
|
}
|
|
5670
6219
|
// Si es un array, procesar cada elemento
|
|
5671
|
-
if (Array.isArray(
|
|
5672
|
-
return
|
|
6220
|
+
if (Array.isArray(value)) {
|
|
6221
|
+
return value.map((item) => this.serializeValue(item));
|
|
5673
6222
|
}
|
|
5674
6223
|
// Si es un objeto, procesar cada propiedad
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
6224
|
+
if (typeof value === 'object') {
|
|
6225
|
+
const result = {};
|
|
6226
|
+
Object.keys(value).forEach((key) => {
|
|
6227
|
+
result[key] = this.serializeValue(value[key]);
|
|
6228
|
+
});
|
|
6229
|
+
return result;
|
|
6230
|
+
}
|
|
6231
|
+
// Primitivos (string, number, boolean)
|
|
6232
|
+
return value;
|
|
6233
|
+
}
|
|
6234
|
+
updateSerializedValue(value) {
|
|
6235
|
+
if (!value) {
|
|
6236
|
+
this.serializedValue.set('');
|
|
6237
|
+
return;
|
|
6238
|
+
}
|
|
6239
|
+
try {
|
|
6240
|
+
// ✅ Serializar todo el objeto (incluyendo fechas)
|
|
6241
|
+
const serialized = this.serializeValue(value);
|
|
6242
|
+
this.serializedValue.set(JSON.stringify(serialized, null, 2));
|
|
6243
|
+
}
|
|
6244
|
+
catch (error) {
|
|
6245
|
+
this.serializedValue.set('Error al serializar: ' + error);
|
|
6246
|
+
if (this.shouldShowLogs()) {
|
|
6247
|
+
console.error('[JsonDebug] Error serializing value:', error);
|
|
5684
6248
|
}
|
|
5685
|
-
}
|
|
5686
|
-
return result;
|
|
6249
|
+
}
|
|
5687
6250
|
}
|
|
5688
6251
|
updateFileInfo(value) {
|
|
5689
6252
|
if (!value) {
|
|
@@ -5691,7 +6254,7 @@ class JsonValuesDebujComponent {
|
|
|
5691
6254
|
this.filesSummary.set('');
|
|
5692
6255
|
return;
|
|
5693
6256
|
}
|
|
5694
|
-
//
|
|
6257
|
+
// Buscar todos los archivos en la estructura
|
|
5695
6258
|
const files = this.findFilesInObject(value);
|
|
5696
6259
|
if (files.length === 0) {
|
|
5697
6260
|
this.fileInfo.set({
|
|
@@ -5703,7 +6266,7 @@ class JsonValuesDebujComponent {
|
|
|
5703
6266
|
this.filesSummary.set('📭 Sin archivos');
|
|
5704
6267
|
return;
|
|
5705
6268
|
}
|
|
5706
|
-
//
|
|
6269
|
+
// Resumir información de archivos
|
|
5707
6270
|
const summary = files
|
|
5708
6271
|
.map((f) => {
|
|
5709
6272
|
const name = f.file?.name || 'sin nombre';
|
|
@@ -5713,7 +6276,7 @@ class JsonValuesDebujComponent {
|
|
|
5713
6276
|
})
|
|
5714
6277
|
.join('; ');
|
|
5715
6278
|
this.filesSummary.set(`📁 ${files.length} archivo(s): ${summary}`);
|
|
5716
|
-
//
|
|
6279
|
+
// Información detallada
|
|
5717
6280
|
const info = {
|
|
5718
6281
|
exists: true,
|
|
5719
6282
|
count: files.length,
|
|
@@ -5731,7 +6294,6 @@ class JsonValuesDebujComponent {
|
|
|
5731
6294
|
const value = this.debugValue();
|
|
5732
6295
|
if (!value)
|
|
5733
6296
|
return false;
|
|
5734
|
-
// ✅ Buscar archivos en toda la estructura
|
|
5735
6297
|
const files = this.findFilesInObject(value);
|
|
5736
6298
|
return files.length > 0;
|
|
5737
6299
|
}
|
|
@@ -5758,7 +6320,7 @@ class JsonValuesDebujComponent {
|
|
|
5758
6320
|
}
|
|
5759
6321
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JsonValuesDebujComponent, decorators: [{
|
|
5760
6322
|
type: Component,
|
|
5761
|
-
args: [{ selector: 'app-json-values-debuj', standalone: true, imports: [
|
|
6323
|
+
args: [{ selector: 'app-json-values-debuj', standalone: true, imports: [DecimalPipe], encapsulation: ViewEncapsulation.None, template: "<!-- json-values-debuj.component.html -->\r\n@if (shouldShowVisual()) {\r\n <div class=\"json-debug-container\">\r\n <div class=\"json-debug-header\">\r\n <span class=\"json-debug-id\">\uD83D\uDD0D Debug #{{ id }}</span>\r\n <span class=\"json-debug-info\">\r\n @if (debugValue()) {\r\n <span class=\"badge badge-success\">\u2713 Formulario activo</span>\r\n } @else {\r\n <span class=\"badge badge-danger\">\u2717 Sin formulario</span>\r\n }\r\n </span>\r\n </div>\r\n\r\n @if (debugValue()) {\r\n <div class=\"json-debug-content\">\r\n <!-- \u2705 Informaci\u00F3n de archivos encontrados en toda la estructura -->\r\n @if (hasFileProperty()) {\r\n <div class=\"file-info-box\">\r\n <div class=\"file-info-header\">\r\n \uD83D\uDCC1 Archivos encontrados ({{ getFileInfo()?.count || 0 }})\r\n </div>\r\n <div class=\"file-info-grid\">\r\n @for (file of getFileInfo()?.files || []; track file.path) {\r\n <div class=\"file-info-item file-item\">\r\n <div class=\"file-path\">\uD83D\uDCC4 {{ file.path }}</div>\r\n <div class=\"file-details\">\r\n <span class=\"label\">Nombre:</span>\r\n <span class=\"value\">{{ file.name }}</span>\r\n </div>\r\n <div class=\"file-details\">\r\n <span class=\"label\">Tama\u00F1o:</span>\r\n <span class=\"value\"\r\n >{{ file.size / 1024 | number: \"1.1-1\" }} KB</span\r\n >\r\n </div>\r\n <div class=\"file-details\">\r\n <span class=\"label\">Tipo:</span>\r\n <span class=\"value\">{{ file.type || \"Desconocido\" }}</span>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"file-info-box file-empty\">\r\n <div class=\"file-info-header\">\uD83D\uDCED Sin archivos seleccionados</div>\r\n </div>\r\n }\r\n\r\n <!-- JSON -->\r\n <div class=\"json-display\">\r\n <pre class=\"json-colored\">{{ serializedValue() }}</pre>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n}\r\n", styles: [".json-debug-container{margin:10px 0;border:1px solid #dee2e6;border-radius:8px;background-color:#f8f9fa;font-family:Consolas,Monaco,Courier New,monospace;font-size:13px;box-shadow:0 2px 8px #0000001a}.json-debug-header{display:flex;justify-content:space-between;align-items:center;padding:12px 20px;background:linear-gradient(135deg,#667eea,#764ba2);border-radius:8px 8px 0 0;color:#fff}.json-debug-id{font-weight:700;font-size:14px;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.2)}.badge{padding:4px 14px;border-radius:20px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.badge-success{background-color:#10b981;color:#fff;box-shadow:0 2px 4px #10b9814d}.badge-danger{background-color:#ef4444;color:#fff;box-shadow:0 2px 4px #ef44444d}.json-debug-content{padding:16px 20px}.file-info-box{background:linear-gradient(135deg,#f0f9ff,#e0f2fe);border:1px solid #bae6fd;border-radius:6px;padding:12px 16px;margin-bottom:16px}.file-info-header{font-weight:600;color:#0369a1;font-size:13px;margin-bottom:8px}.file-info-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:6px}.file-info-item{padding:4px 8px;background-color:#fff;border-radius:4px;border:1px solid #e5e7eb}.file-info-item .label{font-weight:600;color:#6b7280;margin-right:8px;font-size:12px}.file-info-item .value{color:#0369a1;font-family:Consolas,Monaco,Courier New,monospace;font-size:12px}.json-display{margin-top:0}.json-colored{margin:0;padding:16px 20px;background-color:#1e1e1e;border-radius:6px;overflow:auto;font-size:13px;line-height:1.7;color:#d4d4d4;min-height:50px;max-height:500px;font-family:Consolas,Monaco,Courier New,monospace;white-space:pre}.json-colored::-webkit-scrollbar{width:10px;height:10px}.json-colored::-webkit-scrollbar-track{background:#2d2d2d;border-radius:4px}.json-colored::-webkit-scrollbar-thumb{background:#666;border-radius:4px}.json-colored::-webkit-scrollbar-thumb:hover{background:#888}@media(max-width:768px){.json-debug-header{flex-direction:column;gap:8px;padding:10px 16px}.json-debug-content{padding:12px 16px}.file-info-grid{grid-template-columns:1fr}.json-colored{font-size:11px;padding:12px 14px;max-height:300px}}\n"] }]
|
|
5762
6324
|
}], ctorParameters: () => [], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: false }] }], debug: [{ type: i0.Input, args: [{ isSignal: true, alias: "debug", required: false }] }], debounceTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "debounceTime", required: false }] }] } });
|
|
5763
6325
|
|
|
5764
6326
|
class IcoLabel {
|
|
@@ -6643,7 +7205,7 @@ class NavbarDsxComponent {
|
|
|
6643
7205
|
});
|
|
6644
7206
|
}
|
|
6645
7207
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NavbarDsxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6646
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.17", type: NavbarDsxComponent, isStandalone: true, selector: "app-navbar-dsx", inputs: { appVersion: { classPropertyName: "appVersion", publicName: "appVersion", isSignal: true, isRequired: false, transformFunction: null }, logoWidth: { classPropertyName: "logoWidth", publicName: "logoWidth", isSignal: true, isRequired: false, transformFunction: null }, urlLogo: { classPropertyName: "urlLogo", publicName: "urlLogo", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<p-menubar>\r\n <ng-template #start>\r\n <p-image\r\n class=\"ms-15\"\r\n [src]=\"urlLogo()\"\r\n alt=\"Image\"\r\n [width]=\"logoWidth()\"\r\n />\r\n <span class=\"version-text\">{{ appVersion() }}</span>\r\n </ng-template>\r\n <ng-template #end>\r\n <div>\r\n <!-- Datos del usuario -->\r\n <div class=\"navbar-user-info\">\r\n <icon-dsx name=\"verified_user\" class=\"navbar-user-icon\"></icon-dsx>\r\n <div class=\"navbar-user-text\">\r\n <span class=\"navbar-user-name\">\r\n {{ _authorizeService.getTokenValues.userName }}\r\n </span>\r\n <span class=\"navbar-user-role\">\r\n {{ currentRole }}\r\n </span>\r\n </div>\r\n </div>\r\n\r\n <!-- Componente de estado de red -->\r\n <app-network-status></app-network-status>\r\n\r\n <!-- Actualizaci\u00F3n de permisos -->\r\n <p-button\r\n size=\"small\"\r\n class=\"ml-2 mr-2\"\r\n label=\"Permisos\"\r\n variant=\"text\"\r\n severity=\"secondary\"\r\n (click)=\"actualizarSeguridadIT()\"\r\n >\r\n <span class=\"material-symbols-outlined mr-1\">local_police</span>\r\n </p-button>\r\n\r\n <label class=\"ui-switch\">\r\n <input\r\n type=\"checkbox\"\r\n [(ngModel)]=\"checked\"\r\n (click)=\"onThemeChange(!checked ? true : false)\"\r\n />\r\n <div class=\"slider\">\r\n <div class=\"circle\"></div>\r\n </div>\r\n </label>\r\n <!-- <p-inputSwitch\r\n [(ngModel)]=\"checked\"\r\n (onChange)=\"onThemeChange($event.checked)\"\r\n ></p-inputSwitch> -->\r\n </div>\r\n </ng-template>\r\n</p-menubar>\r\n", styles: [":host ::ng-deep .p-menubar{display:flex;align-items:center!important;padding:.25rem 1.5rem!important;border-radius:999px;border:1px solid rgba(255,255,255,.25);background:#ffffff73!important;backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);box-shadow:0 10px 30px #0f172a14;margin-left:4rem;margin-right:2.5rem}:host ::ng-deep .p-menubar-end>*{display:flex;align-items:center}.version-text{font-size:1.3rem;font-family:Montserrat,sans-serif!important;margin-left:.5rem;font-weight:600;background-image:linear-gradient(to right,#38bdf8,#630cb4);-webkit-background-clip:text;background-clip:text;color:transparent;text-shadow:0 2px 4px rgba(0,0,0,.1);padding:.2rem 0}.navbar-user-info{display:flex;align-items:center;gap:.35rem;padding:0 .75rem;border-radius:999px;background-color:#00000005}.navbar-user-icon{font-size:1.5rem;color:#374151}.navbar-user-name{font-size:.8rem;font-weight:500;color:#374151;white-space:nowrap}.navbar-user-text{display:flex;flex-direction:column;line-height:1.1}.navbar-user-role{font-size:.7rem;color:#6b7280;white-space:nowrap}.ui-switch{--switch-bg: rgb(135, 150, 165);--switch-width: 48px;--switch-height: 20px;--circle-diameter: 32px;--circle-bg: rgb(232, 89, 15);--circle-inset: calc((var(--circle-diameter) - var(--switch-height)) / 2)}.ui-switch input{display:none}.slider{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:var(--switch-width);height:var(--switch-height);background:var(--switch-bg);border-radius:999px;position:relative;cursor:pointer}.slider .circle{top:calc(var(--circle-inset) * -1);left:0;width:var(--circle-diameter);height:var(--circle-diameter);position:absolute;background:var(--circle-bg);border-radius:inherit;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjAiIHdpZHRoPSIyMCIgdmlld0JveD0iMCAwIDIwIDIwIj4KICAgIDxwYXRoIGZpbGw9IiNmZmYiCiAgICAgICAgZD0iTTkuMzA1IDEuNjY3VjMuNzVoMS4zODlWMS42NjdoLTEuMzl6bS00LjcwNyAxLjk1bC0uOTgyLjk4Mkw1LjA5IDYuMDcybC45ODItLjk4Mi0xLjQ3My0xLjQ3M3ptMTAuODAyIDBMMTMuOTI3IDUuMDlsLjk4Mi45ODIgMS40NzMtMS40NzMtLjk4Mi0uOTgyek0xMCA1LjEzOWE0Ljg3MiA0Ljg3MiAwIDAwLTQuODYyIDQuODZBNC44NzIgNC44NzIgMCAwMDEwIDE0Ljg2MiA0Ljg3MiA0Ljg3MiAwIDAwMTQuODYgMTAgNC44NzIgNC44NzIgMCAwMDEwIDUuMTM5em0wIDEuMzg5QTMuNDYyIDMuNDYyIDAgMDExMy40NzEgMTBhMy40NjIgMy40NjIgMCAwMS0zLjQ3MyAzLjQ3MkEzLjQ2MiAzLjQ2MiAwIDAxNi41MjcgMTAgMy40NjIgMy40NjIgMCAwMTEwIDYuNTI4ek0xLjY2NSA5LjMwNXYxLjM5aDIuMDgzdi0xLjM5SDEuNjY2em0xNC41ODMgMHYxLjM5aDIuMDg0di0xLjM5aC0yLjA4NHpNNS4wOSAxMy45MjhMMy42MTYgMTUuNGwuOTgyLjk4MiAxLjQ3My0xLjQ3My0uOTgyLS45ODJ6bTkuODIgMGwtLjk4Mi45ODIgMS40NzMgMS40NzMuOTgyLS45ODItMS40NzMtMS40NzN6TTkuMzA1IDE2LjI1djIuMDgzaDEuMzg5VjE2LjI1aC0xLjM5eiIgLz4KPC9zdmc+);background-repeat:no-repeat;background-position:center center;transition:left .15s cubic-bezier(.4,0,.2,1) 0ms;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 1px -1px #0003,0 1px 1px #00000024,0 1px 3px #0000001f}.slider .circle:before{content:\"\";position:absolute;width:100%;height:100%;background:#ffffffbf;border-radius:inherit;transition:all .5s;opacity:0}.ui-switch input:checked+.slider .circle{left:calc(100% - var(--circle-diameter));background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjAiIHdpZHRoPSIyMCIgdmlld0JveD0iMCAwIDIwIDIwIj4KICAgIDxwYXRoIGZpbGw9IiNmZmYiCiAgICAgICAgZD0iTTQuMiAyLjVsLS43IDEuOC0xLjguNyAxLjguNy43IDEuOC42LTEuOEw2LjcgNWwtMS45LS43LS42LTEuOHptMTUgOC4zYTYuNyA2LjcgMCAxMS02LjYtNi42IDUuOCA1LjggMCAwMDYuNiA2LjZ6IiAvPgo8L3N2Zz4=);background-color:#003892}.ui-switch input:active+.slider .circle:before{transition:0s;opacity:1;width:0;height:0}.navbar-user-info,.ui-switch .slider,.version-text{cursor:pointer}.navbar-user-info:active{transform:scale(.98);transition:transform .05s ease}.ui-switch:active .slider .circle{transform:scale(.95);transition:transform .05s ease}[data-title]{position:relative}[data-title]:hover:after{content:attr(data-title);position:absolute;bottom:125%;left:50%;transform:translate(-50%);background:#000c;color:#fff;font-size:.7rem;padding:.25rem .5rem;border-radius:.25rem;white-space:nowrap;z-index:1000;pointer-events:none;font-family:sans-serif}.navbar-user-info:focus-visible,.ui-switch .slider:focus-visible{outline:2px solid #38bdf8;outline-offset:2px}@media(prefers-reduced-motion:reduce){.navbar-user-info:active,.ui-switch:active .slider .circle{transform:none}}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type:
|
|
7208
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.17", type: NavbarDsxComponent, isStandalone: true, selector: "app-navbar-dsx", inputs: { appVersion: { classPropertyName: "appVersion", publicName: "appVersion", isSignal: true, isRequired: false, transformFunction: null }, logoWidth: { classPropertyName: "logoWidth", publicName: "logoWidth", isSignal: true, isRequired: false, transformFunction: null }, urlLogo: { classPropertyName: "urlLogo", publicName: "urlLogo", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<p-menubar>\r\n <ng-template #start>\r\n <p-image\r\n class=\"ms-15\"\r\n [src]=\"urlLogo()\"\r\n alt=\"Image\"\r\n [width]=\"logoWidth()\"\r\n />\r\n <span class=\"version-text\">{{ appVersion() }}</span>\r\n </ng-template>\r\n <ng-template #end>\r\n <div>\r\n <!-- Datos del usuario -->\r\n <div class=\"navbar-user-info\">\r\n <icon-dsx name=\"verified_user\" class=\"navbar-user-icon\"></icon-dsx>\r\n <div class=\"navbar-user-text\">\r\n <span class=\"navbar-user-name\">\r\n {{ _authorizeService.getTokenValues.userName }}\r\n </span>\r\n <span class=\"navbar-user-role\">\r\n {{ currentRole }}\r\n </span>\r\n </div>\r\n </div>\r\n\r\n <!-- Componente de estado de red -->\r\n <app-network-status></app-network-status>\r\n\r\n <!-- Actualizaci\u00F3n de permisos -->\r\n <p-button\r\n size=\"small\"\r\n class=\"ml-2 mr-2\"\r\n label=\"Permisos\"\r\n variant=\"text\"\r\n severity=\"secondary\"\r\n (click)=\"actualizarSeguridadIT()\"\r\n >\r\n <span class=\"material-symbols-outlined mr-1\">local_police</span>\r\n </p-button>\r\n\r\n <label class=\"ui-switch\">\r\n <input\r\n type=\"checkbox\"\r\n [(ngModel)]=\"checked\"\r\n (click)=\"onThemeChange(!checked ? true : false)\"\r\n />\r\n <div class=\"slider\">\r\n <div class=\"circle\"></div>\r\n </div>\r\n </label>\r\n <!-- <p-inputSwitch\r\n [(ngModel)]=\"checked\"\r\n (onChange)=\"onThemeChange($event.checked)\"\r\n ></p-inputSwitch> -->\r\n </div>\r\n </ng-template>\r\n</p-menubar>\r\n", styles: [":host ::ng-deep .p-menubar{display:flex;align-items:center!important;padding:.25rem 1.5rem!important;border-radius:999px;border:1px solid rgba(255,255,255,.25);background:#ffffff73!important;backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);box-shadow:0 10px 30px #0f172a14;margin-left:4rem;margin-right:2.5rem}:host ::ng-deep .p-menubar-end>*{display:flex;align-items:center}.version-text{font-size:1.3rem;font-family:Montserrat,sans-serif!important;margin-left:.5rem;font-weight:600;background-image:linear-gradient(to right,#38bdf8,#630cb4);-webkit-background-clip:text;background-clip:text;color:transparent;text-shadow:0 2px 4px rgba(0,0,0,.1);padding:.2rem 0}.navbar-user-info{display:flex;align-items:center;gap:.35rem;padding:0 .75rem;border-radius:999px;background-color:#00000005}.navbar-user-icon{font-size:1.5rem;color:#374151}.navbar-user-name{font-size:.8rem;font-weight:500;color:#374151;white-space:nowrap}.navbar-user-text{display:flex;flex-direction:column;line-height:1.1}.navbar-user-role{font-size:.7rem;color:#6b7280;white-space:nowrap}.ui-switch{--switch-bg: rgb(135, 150, 165);--switch-width: 48px;--switch-height: 20px;--circle-diameter: 32px;--circle-bg: rgb(232, 89, 15);--circle-inset: calc((var(--circle-diameter) - var(--switch-height)) / 2)}.ui-switch input{display:none}.slider{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:var(--switch-width);height:var(--switch-height);background:var(--switch-bg);border-radius:999px;position:relative;cursor:pointer}.slider .circle{top:calc(var(--circle-inset) * -1);left:0;width:var(--circle-diameter);height:var(--circle-diameter);position:absolute;background:var(--circle-bg);border-radius:inherit;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjAiIHdpZHRoPSIyMCIgdmlld0JveD0iMCAwIDIwIDIwIj4KICAgIDxwYXRoIGZpbGw9IiNmZmYiCiAgICAgICAgZD0iTTkuMzA1IDEuNjY3VjMuNzVoMS4zODlWMS42NjdoLTEuMzl6bS00LjcwNyAxLjk1bC0uOTgyLjk4Mkw1LjA5IDYuMDcybC45ODItLjk4Mi0xLjQ3My0xLjQ3M3ptMTAuODAyIDBMMTMuOTI3IDUuMDlsLjk4Mi45ODIgMS40NzMtMS40NzMtLjk4Mi0uOTgyek0xMCA1LjEzOWE0Ljg3MiA0Ljg3MiAwIDAwLTQuODYyIDQuODZBNC44NzIgNC44NzIgMCAwMDEwIDE0Ljg2MiA0Ljg3MiA0Ljg3MiAwIDAwMTQuODYgMTAgNC44NzIgNC44NzIgMCAwMDEwIDUuMTM5em0wIDEuMzg5QTMuNDYyIDMuNDYyIDAgMDExMy40NzEgMTBhMy40NjIgMy40NjIgMCAwMS0zLjQ3MyAzLjQ3MkEzLjQ2MiAzLjQ2MiAwIDAxNi41MjcgMTAgMy40NjIgMy40NjIgMCAwMTEwIDYuNTI4ek0xLjY2NSA5LjMwNXYxLjM5aDIuMDgzdi0xLjM5SDEuNjY2em0xNC41ODMgMHYxLjM5aDIuMDg0di0xLjM5aC0yLjA4NHpNNS4wOSAxMy45MjhMMy42MTYgMTUuNGwuOTgyLjk4MiAxLjQ3My0xLjQ3My0uOTgyLS45ODJ6bTkuODIgMGwtLjk4Mi45ODIgMS40NzMgMS40NzMuOTgyLS45ODItMS40NzMtMS40NzN6TTkuMzA1IDE2LjI1djIuMDgzaDEuMzg5VjE2LjI1aC0xLjM5eiIgLz4KPC9zdmc+);background-repeat:no-repeat;background-position:center center;transition:left .15s cubic-bezier(.4,0,.2,1) 0ms;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 1px -1px #0003,0 1px 1px #00000024,0 1px 3px #0000001f}.slider .circle:before{content:\"\";position:absolute;width:100%;height:100%;background:#ffffffbf;border-radius:inherit;transition:all .5s;opacity:0}.ui-switch input:checked+.slider .circle{left:calc(100% - var(--circle-diameter));background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjAiIHdpZHRoPSIyMCIgdmlld0JveD0iMCAwIDIwIDIwIj4KICAgIDxwYXRoIGZpbGw9IiNmZmYiCiAgICAgICAgZD0iTTQuMiAyLjVsLS43IDEuOC0xLjguNyAxLjguNy43IDEuOC42LTEuOEw2LjcgNWwtMS45LS43LS42LTEuOHptMTUgOC4zYTYuNyA2LjcgMCAxMS02LjYtNi42IDUuOCA1LjggMCAwMDYuNiA2LjZ6IiAvPgo8L3N2Zz4=);background-color:#003892}.ui-switch input:active+.slider .circle:before{transition:0s;opacity:1;width:0;height:0}.navbar-user-info,.ui-switch .slider,.version-text{cursor:pointer}.navbar-user-info:active{transform:scale(.98);transition:transform .05s ease}.ui-switch:active .slider .circle{transform:scale(.95);transition:transform .05s ease}[data-title]{position:relative}[data-title]:hover:after{content:attr(data-title);position:absolute;bottom:125%;left:50%;transform:translate(-50%);background:#000c;color:#fff;font-size:.7rem;padding:.25rem .5rem;border-radius:.25rem;white-space:nowrap;z-index:1000;pointer-events:none;font-family:sans-serif}.navbar-user-info:focus-visible,.ui-switch .slider:focus-visible{outline:2px solid #38bdf8;outline-offset:2px}@media(prefers-reduced-motion:reduce){.navbar-user-info:active,.ui-switch:active .slider .circle{transform:none}}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i4.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: FormsModule }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { 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: IconDsxComponent, selector: "icon-dsx", inputs: ["name", "style", "debug"] }, { kind: "ngmodule", type: ImageModule }, { kind: "component", type: i3$1.Image, selector: "p-image", inputs: ["imageClass", "imageStyle", "styleClass", "src", "srcSet", "sizes", "previewImageSrc", "previewImageSrcSet", "previewImageSizes", "alt", "width", "height", "loading", "preview", "showTransitionOptions", "hideTransitionOptions", "modalEnterAnimation", "modalLeaveAnimation", "appendTo", "maskMotionOptions", "motionOptions"], outputs: ["onShow", "onHide", "onImageError"] }, { kind: "ngmodule", type: MenubarModule }, { kind: "component", type: i4$1.Menubar, selector: "p-menubar", inputs: ["model", "styleClass", "autoZIndex", "baseZIndex", "autoDisplay", "autoHide", "breakpoint", "autoHideDelay", "id", "ariaLabel", "ariaLabelledBy"], outputs: ["onFocus", "onBlur"] }, { kind: "component", type: NetworkStatusComponent, selector: "app-network-status" }] });
|
|
6647
7209
|
}
|
|
6648
7210
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NavbarDsxComponent, decorators: [{
|
|
6649
7211
|
type: Component,
|
|
@@ -7023,7 +7585,7 @@ class TokenPurposeLogin {
|
|
|
7023
7585
|
}
|
|
7024
7586
|
}
|
|
7025
7587
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TokenPurposeLogin, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7026
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: TokenPurposeLogin, isStandalone: true, selector: "app-token-purpose-login", ngImport: i0, template: "<div class=\"flex\">\r\n <p-button\r\n (click)=\"showDialog()\"\r\n label=\"Generar Token\"\r\n pTooltip=\"Ingrese sus credenciales para generar un token de acceso.\"\r\n tooltipPosition=\"top\"\r\n severity=\"secondary\"\r\n icon=\"pi pi-lock\"\r\n [rounded]=\"true\"\r\n [raised]=\"true\"\r\n />\r\n</div>\r\n<form [formGroup]=\"form\">\r\n <p-dialog [(visible)]=\"visible\" [modal]=\"true\" [style]=\"{ width: '30rem' }\">\r\n <ng-template #header>\r\n <div class=\"flex items-center gap-2 px-2\">\r\n <p-avatar image=\"icon/folder.png\" size=\"large\" />\r\n <h5>Token de Seguridad</h5>\r\n </div>\r\n </ng-template>\r\n <span class=\"text-surface-500 dark:text-surface-400 block\"\r\n >Ingrese sus credenciales para generar un token de acceso.</span\r\n >\r\n <div class=\"mt-3\">\r\n <p-floatLabel variant=\"in\">\r\n <p-password\r\n formControlName=\"password\"\r\n [invalid]=\"form.get('password')?.invalid && (form.get('password')?.dirty || form.get('password')?.touched)\"\r\n [feedback]=\"false\"\r\n [toggleMask]=\"true\"\r\n fluid\r\n />\r\n <label>Contrase\u00F1a</label>\r\n </p-floatLabel>\r\n @if (form.get('password')?.invalid && (form.get('password')?.dirty ||\r\n form.get('password')?.touched)) {\r\n <small class=\"text-red-500\">La contrase\u00F1a es obligatoria.</small>\r\n }\r\n </div>\r\n <ng-template #footer>\r\n <p-button\r\n label=\"Cancelar\"\r\n variant=\"outlined\"\r\n [rounded]=\"true\"\r\n icon=\"pi pi-times\"\r\n severity=\"danger\"\r\n (click)=\"visible = false\"\r\n />\r\n <p-button\r\n label=\"Generar\"\r\n variant=\"outlined\"\r\n [rounded]=\"true\"\r\n icon=\"pi pi-unlock\"\r\n severity=\"success\"\r\n [disabled]=\"!form.valid\"\r\n (click)=\"generarTokenPurpose()\"\r\n />\r\n </ng-template>\r\n </p-dialog>\r\n</form>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i2$2.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i2$3.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type:
|
|
7588
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: TokenPurposeLogin, isStandalone: true, selector: "app-token-purpose-login", ngImport: i0, template: "<div class=\"flex\">\r\n <p-button\r\n (click)=\"showDialog()\"\r\n label=\"Generar Token\"\r\n pTooltip=\"Ingrese sus credenciales para generar un token de acceso.\"\r\n tooltipPosition=\"top\"\r\n severity=\"secondary\"\r\n icon=\"pi pi-lock\"\r\n [rounded]=\"true\"\r\n [raised]=\"true\"\r\n />\r\n</div>\r\n<form [formGroup]=\"form\">\r\n <p-dialog [(visible)]=\"visible\" [modal]=\"true\" [style]=\"{ width: '30rem' }\">\r\n <ng-template #header>\r\n <div class=\"flex items-center gap-2 px-2\">\r\n <p-avatar image=\"icon/folder.png\" size=\"large\" />\r\n <h5>Token de Seguridad</h5>\r\n </div>\r\n </ng-template>\r\n <span class=\"text-surface-500 dark:text-surface-400 block\"\r\n >Ingrese sus credenciales para generar un token de acceso.</span\r\n >\r\n <div class=\"mt-3\">\r\n <p-floatLabel variant=\"in\">\r\n <p-password\r\n formControlName=\"password\"\r\n [invalid]=\"form.get('password')?.invalid && (form.get('password')?.dirty || form.get('password')?.touched)\"\r\n [feedback]=\"false\"\r\n [toggleMask]=\"true\"\r\n fluid\r\n />\r\n <label>Contrase\u00F1a</label>\r\n </p-floatLabel>\r\n @if (form.get('password')?.invalid && (form.get('password')?.dirty ||\r\n form.get('password')?.touched)) {\r\n <small class=\"text-red-500\">La contrase\u00F1a es obligatoria.</small>\r\n }\r\n </div>\r\n <ng-template #footer>\r\n <p-button\r\n label=\"Cancelar\"\r\n variant=\"outlined\"\r\n [rounded]=\"true\"\r\n icon=\"pi pi-times\"\r\n severity=\"danger\"\r\n (click)=\"visible = false\"\r\n />\r\n <p-button\r\n label=\"Generar\"\r\n variant=\"outlined\"\r\n [rounded]=\"true\"\r\n icon=\"pi pi-unlock\"\r\n severity=\"success\"\r\n [disabled]=\"!form.valid\"\r\n (click)=\"generarTokenPurpose()\"\r\n />\r\n </ng-template>\r\n </p-dialog>\r\n</form>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i2$2.Dialog, selector: "p-dialog", inputs: ["hostName", "header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "maskMotionOptions", "motionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i2$3.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i4.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"] }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: i6.FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "ngmodule", type: PasswordModule }, { kind: "component", type: i7.Password, selector: "p-password", inputs: ["ariaLabel", "ariaLabelledBy", "label", "promptLabel", "mediumRegex", "strongRegex", "weakLabel", "mediumLabel", "maxLength", "strongLabel", "inputId", "feedback", "toggleMask", "inputStyleClass", "styleClass", "inputStyle", "showTransitionOptions", "hideTransitionOptions", "autocomplete", "placeholder", "showClear", "autofocus", "tabindex", "appendTo", "motionOptions", "overlayOptions"], outputs: ["onFocus", "onBlur", "onClear"] }] });
|
|
7027
7589
|
}
|
|
7028
7590
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TokenPurposeLogin, decorators: [{
|
|
7029
7591
|
type: Component,
|
|
@@ -8419,6 +8981,7 @@ const PRIME_NG_MODULES = [
|
|
|
8419
8981
|
ButtonModule,
|
|
8420
8982
|
CardModule,
|
|
8421
8983
|
CheckboxModule,
|
|
8984
|
+
ChipModule,
|
|
8422
8985
|
ContextMenuModule,
|
|
8423
8986
|
DataViewModule,
|
|
8424
8987
|
DatePickerModule,
|
|
@@ -8478,6 +9041,7 @@ class PrimeNgModule {
|
|
|
8478
9041
|
ButtonModule,
|
|
8479
9042
|
CardModule,
|
|
8480
9043
|
CheckboxModule,
|
|
9044
|
+
ChipModule,
|
|
8481
9045
|
ContextMenuModule,
|
|
8482
9046
|
DataViewModule,
|
|
8483
9047
|
DatePickerModule,
|
|
@@ -8534,6 +9098,7 @@ class PrimeNgModule {
|
|
|
8534
9098
|
ButtonModule,
|
|
8535
9099
|
CardModule,
|
|
8536
9100
|
CheckboxModule,
|
|
9101
|
+
ChipModule,
|
|
8537
9102
|
ContextMenuModule,
|
|
8538
9103
|
DataViewModule,
|
|
8539
9104
|
DatePickerModule,
|
|
@@ -8992,7 +9557,7 @@ class DsxdateShort {
|
|
|
8992
9557
|
useExisting: forwardRef(() => DsxdateShort),
|
|
8993
9558
|
multi: true,
|
|
8994
9559
|
},
|
|
8995
|
-
], ngImport: i0, template: "<!-- dsxdate-short.html -->\r\n<p-floatLabel variant=\"on\">\r\n <p-datepicker\r\n fluid\r\n appendTo=\"body\"\r\n [formControl]=\"fechaControl\"\r\n [fluid]=\"true\"\r\n [showIcon]=\"showIcon()\"\r\n [showOnFocus]=\"showOnFocus()\"\r\n [showButtonBar]=\"showButtonBar()\"\r\n [dateFormat]=\"dateFormat()\"\r\n [placeholder]=\"placeholder()\"\r\n pInputMask=\"99/99/9999\"\r\n />\r\n <label>{{ label() }}</label>\r\n</p-floatLabel>\r\n\r\n<!-- \u2705 SIN CONDICI\u00D3N - IGUAL QUE EL ORIGINAL -->\r\n<dsx-message-error [control]=\"fechaControl\" />\r\n\r\n<!-- Debug info -->\r\n@if (debugEnabled() && isDevMode) {\r\n<div\r\n class=\"debug-info\"\r\n style=\"\r\n font-size: 12px;\r\n color: #666;\r\n margin-top: 4px;\r\n border-top: 1px dashed #ccc;\r\n padding-top: 4px;\r\n \"\r\n>\r\n <small>\r\n <strong>Debug:</strong>\r\n Value: {{ fechaControl.value | json }} | Valid: {{ fechaControl.valid }} |\r\n Invalid: {{ fechaControl.invalid }} | Errors: {{ fechaControl.errors | json\r\n }} | Dirty: {{ fechaControl.dirty }} | Touched: {{ fechaControl.touched }} |\r\n Status: {{ fechaControl.status }}\r\n </small>\r\n</div>\r\n}\r\n", styles: [""], dependencies: [{ kind: "component", type: AppMessageErrorComponent, selector: "dsx-message-error", inputs: ["control", "form", "debugMode"] }, { kind: "ngmodule", type: CommonModule }, { 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: "component", type: FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "ngmodule", type: InputMaskModule }, { kind: "directive", type: i1$
|
|
9560
|
+
], ngImport: i0, template: "<!-- dsxdate-short.html -->\r\n<p-floatLabel variant=\"on\">\r\n <p-datepicker\r\n fluid\r\n appendTo=\"body\"\r\n size=\"small\"\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<dsx-message-help [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: "component", type: AppMessageErrorComponent, selector: "dsx-message-error", inputs: ["control", "form", "debugMode"] }, { kind: "ngmodule", type: CommonModule }, { 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: "component", type: FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "ngmodule", type: InputMaskModule }, { kind: "directive", type: i1$7.InputMaskDirective, selector: "[pInputMask]", inputs: ["pInputMaskPT", "pInputMaskUnstyled", "pInputMask", "slotChar", "autoClear", "characterPattern", "keepBuffer"], outputs: ["onComplete", "onUnmaskedChange"] }, { 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: AppMessageHelpComponent, selector: "dsx-message-help", inputs: ["control", "currentIdControl", "helperFunction", "dataSource", "key", "umbral", "debugMode", "idFieldName", "maxSugerencias"] }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }] });
|
|
8996
9561
|
}
|
|
8997
9562
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxdateShort, decorators: [{
|
|
8998
9563
|
type: Component,
|
|
@@ -9004,13 +9569,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
9004
9569
|
InputMaskModule,
|
|
9005
9570
|
JsonPipe,
|
|
9006
9571
|
ReactiveFormsModule,
|
|
9572
|
+
AppMessageHelpComponent,
|
|
9007
9573
|
], providers: [
|
|
9008
9574
|
{
|
|
9009
9575
|
provide: NG_VALUE_ACCESSOR,
|
|
9010
9576
|
useExisting: forwardRef(() => DsxdateShort),
|
|
9011
9577
|
multi: true,
|
|
9012
9578
|
},
|
|
9013
|
-
], template: "<!-- dsxdate-short.html -->\r\n<p-floatLabel variant=\"on\">\r\n <p-datepicker\r\n fluid\r\n appendTo=\"body\"\r\n [formControl]=\"fechaControl\"\r\n [fluid]=\"true\"\r\n [showIcon]=\"showIcon()\"\r\n [showOnFocus]=\"showOnFocus()\"\r\n [showButtonBar]=\"showButtonBar()\"\r\n [dateFormat]=\"dateFormat()\"\r\n [placeholder]=\"placeholder()\"\r\n pInputMask=\"99/99/9999\"\r\n />\r\n <label>{{ label() }}</label>\r\n</p-floatLabel>\r\n\r\n<!-- \u2705 SIN CONDICI\u00D3N - IGUAL QUE EL ORIGINAL -->\r\n<dsx-message-error [control]=\"fechaControl\" />\r\n\r\n<!-- Debug info -->\r\n@if (debugEnabled() && isDevMode) {\r\n<div\r\n class=\"debug-info\"\r\n style=\"\r\n font-size: 12px;\r\n color: #666;\r\n margin-top: 4px;\r\n border-top: 1px dashed #ccc;\r\n padding-top: 4px;\r\n \"\r\n>\r\n <small>\r\n <strong>Debug:</strong>\r\n Value: {{ fechaControl.value | json }} | Valid: {{ fechaControl.valid }} |\r\n Invalid: {{ fechaControl.invalid }} | Errors: {{ fechaControl.errors | json\r\n }} | Dirty: {{ fechaControl.dirty }} | Touched: {{ fechaControl.touched }} |\r\n Status: {{ fechaControl.status }}\r\n </small>\r\n</div>\r\n}\r\n" }]
|
|
9579
|
+
], template: "<!-- dsxdate-short.html -->\r\n<p-floatLabel variant=\"on\">\r\n <p-datepicker\r\n fluid\r\n appendTo=\"body\"\r\n size=\"small\"\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<dsx-message-help [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" }]
|
|
9014
9580
|
}], 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 }] }] } });
|
|
9015
9581
|
|
|
9016
9582
|
class DsxdateTime {
|
|
@@ -9211,7 +9777,7 @@ class DsxdateTime {
|
|
|
9211
9777
|
useExisting: forwardRef(() => DsxdateTime),
|
|
9212
9778
|
multi: true,
|
|
9213
9779
|
},
|
|
9214
|
-
], ngImport: i0, template: "<p-floatLabel variant=\"on\">\r\n <p-datepicker\r\n fluid\r\n appendTo=\"body\"\r\n [formControl]=\"fechaControl\"\r\n [fluid]=\"true\"\r\n [showIcon]=\"showIcon()\"\r\n [showOnFocus]=\"showOnFocus()\"\r\n [showButtonBar]=\"showButtonBar()\"\r\n [showTime]=\"showTime()\"\r\n [hourFormat]=\"hourFormat()\"\r\n [dateFormat]=\"dateFormat()\"\r\n [placeholder]=\"placeholder()\"\r\n pInputMask=\"99/99/9999 99:99\"\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: "component", type: AppMessageErrorComponent, selector: "dsx-message-error", inputs: ["control", "form", "debugMode"] }, { kind: "ngmodule", type: CommonModule }, { 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: "component", type: FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "ngmodule", type: InputMaskModule }, { kind: "directive", type: i1$
|
|
9780
|
+
], ngImport: i0, template: "<p-floatLabel variant=\"on\">\r\n <p-datepicker\r\n fluid\r\n appendTo=\"body\"\r\n [formControl]=\"fechaControl\"\r\n [fluid]=\"true\"\r\n [showIcon]=\"showIcon()\"\r\n [showOnFocus]=\"showOnFocus()\"\r\n [showButtonBar]=\"showButtonBar()\"\r\n [showTime]=\"showTime()\"\r\n [hourFormat]=\"hourFormat()\"\r\n [dateFormat]=\"dateFormat()\"\r\n [placeholder]=\"placeholder()\"\r\n pInputMask=\"99/99/9999 99:99\"\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: "component", type: AppMessageErrorComponent, selector: "dsx-message-error", inputs: ["control", "form", "debugMode"] }, { kind: "ngmodule", type: CommonModule }, { 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: "component", type: FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "ngmodule", type: InputMaskModule }, { kind: "directive", type: i1$7.InputMaskDirective, selector: "[pInputMask]", inputs: ["pInputMaskPT", "pInputMaskUnstyled", "pInputMask", "slotChar", "autoClear", "characterPattern", "keepBuffer"], outputs: ["onComplete", "onUnmaskedChange"] }, { 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: "pipe", type: i1$1.JsonPipe, name: "json" }] });
|
|
9215
9781
|
}
|
|
9216
9782
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxdateTime, decorators: [{
|
|
9217
9783
|
type: Component,
|
|
@@ -10154,7 +10720,7 @@ class DsxSelect {
|
|
|
10154
10720
|
virtualScrollItemSize = input(40, ...(ngDevMode ? [{ debugName: "virtualScrollItemSize" }] : /* istanbul ignore next */ []));
|
|
10155
10721
|
// Iconos
|
|
10156
10722
|
useIcon = input(true, ...(ngDevMode ? [{ debugName: "useIcon" }] : /* istanbul ignore next */ []));
|
|
10157
|
-
itemIcon = input('
|
|
10723
|
+
itemIcon = input('check_small', ...(ngDevMode ? [{ debugName: "itemIcon" }] : /* istanbul ignore next */ []));
|
|
10158
10724
|
selectedIcon = input('done_outline', ...(ngDevMode ? [{ debugName: "selectedIcon" }] : /* istanbul ignore next */ []));
|
|
10159
10725
|
// Debug solo consola
|
|
10160
10726
|
debug = input(false, ...(ngDevMode ? [{ debugName: "debug" }] : /* istanbul ignore next */ []));
|
|
@@ -10356,7 +10922,7 @@ class DsxSelect {
|
|
|
10356
10922
|
useExisting: forwardRef(() => DsxSelect),
|
|
10357
10923
|
multi: true,
|
|
10358
10924
|
},
|
|
10359
|
-
], 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-
|
|
10925
|
+
], 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 size=\"small\"\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-1\">\r\n @if (useIcon()) {\r\n <icon-dsx [name]=\"itemIcon()\" class=\"text-gray-500!\"></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-1\">\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"] }] });
|
|
10360
10926
|
}
|
|
10361
10927
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: DsxSelect, decorators: [{
|
|
10362
10928
|
type: Component,
|
|
@@ -10372,7 +10938,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
10372
10938
|
useExisting: forwardRef(() => DsxSelect),
|
|
10373
10939
|
multi: true,
|
|
10374
10940
|
},
|
|
10375
|
-
], 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-
|
|
10941
|
+
], template: "<!-- dsx-select.html -->\r\n<p-floatLabel [variant]=\"variant()\">\r\n <p-select\r\n fluid\r\n appendTo=\"body\"\r\n size=\"small\"\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-1\">\r\n @if (useIcon()) {\r\n <icon-dsx [name]=\"itemIcon()\" class=\"text-gray-500!\"></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-1\">\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"] }]
|
|
10376
10942
|
}], 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"] }] } });
|
|
10377
10943
|
|
|
10378
10944
|
/**
|
|
@@ -12540,9 +13106,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
12540
13106
|
// form-preview.service.ts
|
|
12541
13107
|
class FormPreviewService {
|
|
12542
13108
|
environment;
|
|
13109
|
+
isDev;
|
|
12543
13110
|
constructor() {
|
|
12544
|
-
// Inyectar el token en el constructor
|
|
12545
13111
|
this.environment = inject(ENVIRONMENT);
|
|
13112
|
+
this.isDev = !this.environment.production;
|
|
12546
13113
|
}
|
|
12547
13114
|
/**
|
|
12548
13115
|
* Construye el HTML para el preview de un objeto
|
|
@@ -12553,17 +13120,30 @@ class FormPreviewService {
|
|
|
12553
13120
|
*
|
|
12554
13121
|
* @example
|
|
12555
13122
|
* ```typescript
|
|
13123
|
+
* // Ejemplo básico
|
|
12556
13124
|
* const data = {
|
|
12557
|
-
*
|
|
12558
|
-
*
|
|
12559
|
-
* email: 'juan@email.com'
|
|
12560
|
-
* },
|
|
13125
|
+
* empleadoId: 2,
|
|
13126
|
+
* fechaIngreso: '2026-04-07',
|
|
12561
13127
|
* estado: 1
|
|
12562
13128
|
* };
|
|
12563
13129
|
*
|
|
13130
|
+
* const empleados = [
|
|
13131
|
+
* { id: 1, nombreCompleto: 'Juan Pérez' },
|
|
13132
|
+
* { id: 2, nombreCompleto: 'María García' }
|
|
13133
|
+
* ];
|
|
13134
|
+
*
|
|
12564
13135
|
* const fields = [
|
|
12565
|
-
* {
|
|
12566
|
-
*
|
|
13136
|
+
* {
|
|
13137
|
+
* key: 'empleadoId',
|
|
13138
|
+
* label: 'Empleado',
|
|
13139
|
+
* referenceMap: empleados,
|
|
13140
|
+
* referenceLabel: 'nombreCompleto'
|
|
13141
|
+
* },
|
|
13142
|
+
* {
|
|
13143
|
+
* key: 'fechaIngreso',
|
|
13144
|
+
* label: 'Fecha de Ingreso',
|
|
13145
|
+
* format: 'dateLong' // "07 de abril de 2026"
|
|
13146
|
+
* },
|
|
12567
13147
|
* {
|
|
12568
13148
|
* key: 'estado',
|
|
12569
13149
|
* label: 'Estado',
|
|
@@ -12571,30 +13151,33 @@ class FormPreviewService {
|
|
|
12571
13151
|
* }
|
|
12572
13152
|
* ];
|
|
12573
13153
|
*
|
|
12574
|
-
* const html = this.formPreviewService.buildObjectSummaryHtml(
|
|
12575
|
-
*
|
|
12576
|
-
*
|
|
12577
|
-
*
|
|
12578
|
-
*
|
|
12579
|
-
*
|
|
13154
|
+
* const html = this.formPreviewService.buildObjectSummaryHtml(
|
|
13155
|
+
* data,
|
|
13156
|
+
* fields,
|
|
13157
|
+
* {
|
|
13158
|
+
* title: 'Datos del Usuario',
|
|
13159
|
+
* showEmpty: false,
|
|
13160
|
+
* compact: true,
|
|
13161
|
+
* debug: true // Solo en desarrollo
|
|
13162
|
+
* }
|
|
13163
|
+
* );
|
|
12580
13164
|
* ```
|
|
12581
13165
|
*/
|
|
12582
13166
|
buildObjectSummaryHtml(data, fields, options) {
|
|
12583
13167
|
const debug = options?.debug ?? false;
|
|
12584
|
-
|
|
12585
|
-
|
|
12586
|
-
if (debug && isDev) {
|
|
13168
|
+
// 🔍 Debug solo en desarrollo
|
|
13169
|
+
if (debug && this.isDev) {
|
|
12587
13170
|
this.debugInputData(data, fields, options);
|
|
12588
13171
|
}
|
|
12589
|
-
//
|
|
13172
|
+
// Validaciones
|
|
12590
13173
|
if (!data) {
|
|
12591
|
-
if (debug && isDev) {
|
|
13174
|
+
if (debug && this.isDev) {
|
|
12592
13175
|
console.error('❌ FormPreview: data es null o undefined');
|
|
12593
13176
|
}
|
|
12594
13177
|
return '';
|
|
12595
13178
|
}
|
|
12596
13179
|
if (!fields || fields.length === 0) {
|
|
12597
|
-
if (debug && isDev) {
|
|
13180
|
+
if (debug && this.isDev) {
|
|
12598
13181
|
console.error('❌ FormPreview: fields está vacío');
|
|
12599
13182
|
}
|
|
12600
13183
|
return '';
|
|
@@ -12610,11 +13193,13 @@ class FormPreviewService {
|
|
|
12610
13193
|
if (field.referenceMap && value !== undefined && value !== null) {
|
|
12611
13194
|
const originalValue = value;
|
|
12612
13195
|
value = this.resolveReferenceValue(value, field);
|
|
12613
|
-
//
|
|
12614
|
-
if (debug && isDev) {
|
|
13196
|
+
// 🔍 Debug solo en desarrollo
|
|
13197
|
+
if (debug && this.isDev) {
|
|
12615
13198
|
console.log(`🔍 Resolviendo referencia para "${field.key}":`, {
|
|
12616
13199
|
original: originalValue,
|
|
12617
13200
|
resuelto: value,
|
|
13201
|
+
referenciaId: field.referenceId || field.key || 'id',
|
|
13202
|
+
referenciaLabel: field.referenceLabel || 'nombre',
|
|
12618
13203
|
tipoMapa: Array.isArray(field.referenceMap)
|
|
12619
13204
|
? 'Array'
|
|
12620
13205
|
: field.referenceMap instanceof Map
|
|
@@ -12625,9 +13210,10 @@ class FormPreviewService {
|
|
|
12625
13210
|
});
|
|
12626
13211
|
}
|
|
12627
13212
|
}
|
|
13213
|
+
// Aplicar formato
|
|
12628
13214
|
const valueText = field.format
|
|
12629
|
-
? field.format
|
|
12630
|
-
: this.
|
|
13215
|
+
? this.formatValue(value, field.format)
|
|
13216
|
+
: this.formatDefault(value);
|
|
12631
13217
|
if (value === undefined) {
|
|
12632
13218
|
propiedadesNoEncontradas.push(field.key);
|
|
12633
13219
|
}
|
|
@@ -12638,8 +13224,8 @@ class FormPreviewService {
|
|
|
12638
13224
|
value: valueText || '—',
|
|
12639
13225
|
});
|
|
12640
13226
|
}
|
|
12641
|
-
//
|
|
12642
|
-
if (debug && isDev) {
|
|
13227
|
+
// 🔍 Debug solo en desarrollo
|
|
13228
|
+
if (debug && this.isDev) {
|
|
12643
13229
|
if (propiedadesNoEncontradas.length > 0) {
|
|
12644
13230
|
console.warn('⚠️ FormPreview: Propiedades no encontradas:', propiedadesNoEncontradas);
|
|
12645
13231
|
console.warn('📋 Propiedades disponibles en data:', Object.keys(data));
|
|
@@ -12651,19 +13237,29 @@ class FormPreviewService {
|
|
|
12651
13237
|
console.log('📋 Fields:', fields);
|
|
12652
13238
|
}
|
|
12653
13239
|
else {
|
|
12654
|
-
console.log('✅ FormPreview: HTML generado correctamente', {
|
|
13240
|
+
console.log('✅ FormPreview: HTML generado correctamente', {
|
|
13241
|
+
totalCeldas: cells.length,
|
|
13242
|
+
campos: cells.map((c) => c.label),
|
|
13243
|
+
});
|
|
12655
13244
|
}
|
|
12656
13245
|
}
|
|
12657
13246
|
if (!cells.length)
|
|
12658
13247
|
return '';
|
|
12659
13248
|
return this.generateHtml(title, cells, compact);
|
|
12660
13249
|
}
|
|
13250
|
+
/**
|
|
13251
|
+
* Resuelve el valor de referencia
|
|
13252
|
+
* Soporta: arrays, maps, objetos literales y funciones
|
|
13253
|
+
*/
|
|
12661
13254
|
resolveReferenceValue(value, field) {
|
|
12662
13255
|
if (Array.isArray(value)) {
|
|
12663
13256
|
return value.map((item) => this.resolveSingleReference(item, field));
|
|
12664
13257
|
}
|
|
12665
13258
|
return this.resolveSingleReference(value, field);
|
|
12666
13259
|
}
|
|
13260
|
+
/**
|
|
13261
|
+
* Resuelve un valor individual de referencia
|
|
13262
|
+
*/
|
|
12667
13263
|
resolveSingleReference(value, field) {
|
|
12668
13264
|
if (!value)
|
|
12669
13265
|
return value;
|
|
@@ -12680,8 +13276,31 @@ class FormPreviewService {
|
|
|
12680
13276
|
referencedItem = map.get(value);
|
|
12681
13277
|
}
|
|
12682
13278
|
else if (Array.isArray(map)) {
|
|
12683
|
-
|
|
12684
|
-
|
|
13279
|
+
// Si no se especifica referenceId, usar el key del campo
|
|
13280
|
+
const idKey = field.referenceId || field.key || 'id';
|
|
13281
|
+
const labelKey = field.referenceLabel || 'nombre';
|
|
13282
|
+
const found = map.find((item) => {
|
|
13283
|
+
if (item[idKey] !== undefined) {
|
|
13284
|
+
return item[idKey] === value;
|
|
13285
|
+
}
|
|
13286
|
+
if (item.id !== undefined) {
|
|
13287
|
+
return item.id === value;
|
|
13288
|
+
}
|
|
13289
|
+
return false;
|
|
13290
|
+
});
|
|
13291
|
+
if (found) {
|
|
13292
|
+
if (found[labelKey] !== undefined && found[labelKey] !== null) {
|
|
13293
|
+
return found[labelKey];
|
|
13294
|
+
}
|
|
13295
|
+
// Fallback: buscar otras propiedades comunes
|
|
13296
|
+
for (const prop of ['label', 'nombre', 'name', 'text', 'value']) {
|
|
13297
|
+
if (found[prop] !== undefined && found[prop] !== null) {
|
|
13298
|
+
return found[prop];
|
|
13299
|
+
}
|
|
13300
|
+
}
|
|
13301
|
+
return found;
|
|
13302
|
+
}
|
|
13303
|
+
return value;
|
|
12685
13304
|
}
|
|
12686
13305
|
else if (typeof map === 'object') {
|
|
12687
13306
|
referencedItem = map[String(value)];
|
|
@@ -12693,12 +13312,23 @@ class FormPreviewService {
|
|
|
12693
13312
|
referencedItem[labelProp] !== null) {
|
|
12694
13313
|
return referencedItem[labelProp];
|
|
12695
13314
|
}
|
|
13315
|
+
for (const prop of ['label', 'nombre', 'name', 'text', 'value']) {
|
|
13316
|
+
if (referencedItem[prop] !== undefined &&
|
|
13317
|
+
referencedItem[prop] !== null) {
|
|
13318
|
+
return referencedItem[prop];
|
|
13319
|
+
}
|
|
13320
|
+
}
|
|
12696
13321
|
return referencedItem;
|
|
12697
13322
|
}
|
|
12698
13323
|
return referencedItem;
|
|
12699
13324
|
}
|
|
12700
13325
|
return value;
|
|
12701
13326
|
}
|
|
13327
|
+
/**
|
|
13328
|
+
* Obtiene un valor anidado usando notación punto
|
|
13329
|
+
* @example
|
|
13330
|
+
* getNestedValue({ user: { name: 'Juan' } }, 'user.name') // 'Juan'
|
|
13331
|
+
*/
|
|
12702
13332
|
getNestedValue(obj, path) {
|
|
12703
13333
|
if (!obj || !path)
|
|
12704
13334
|
return undefined;
|
|
@@ -12711,7 +13341,29 @@ class FormPreviewService {
|
|
|
12711
13341
|
}
|
|
12712
13342
|
return result;
|
|
12713
13343
|
}
|
|
12714
|
-
|
|
13344
|
+
/**
|
|
13345
|
+
* Formatea un valor usando el formato especificado
|
|
13346
|
+
* @param value - Valor a formatear
|
|
13347
|
+
* @param format - Formato a aplicar (string predefinido o función personalizada)
|
|
13348
|
+
* @returns String formateado
|
|
13349
|
+
*/
|
|
13350
|
+
formatValue(value, format) {
|
|
13351
|
+
if (value === null || value === undefined)
|
|
13352
|
+
return '';
|
|
13353
|
+
// Si es función personalizada, ejecutarla
|
|
13354
|
+
if (typeof format === 'function') {
|
|
13355
|
+
return format(value);
|
|
13356
|
+
}
|
|
13357
|
+
// Si es string, verificar si es un formato de fecha
|
|
13358
|
+
if (typeof format === 'string') {
|
|
13359
|
+
return this.formatDate(value, format);
|
|
13360
|
+
}
|
|
13361
|
+
return this.formatDefault(value);
|
|
13362
|
+
}
|
|
13363
|
+
/**
|
|
13364
|
+
* Formato por defecto para cualquier valor
|
|
13365
|
+
*/
|
|
13366
|
+
formatDefault(value) {
|
|
12715
13367
|
if (value === null || value === undefined)
|
|
12716
13368
|
return '';
|
|
12717
13369
|
if (value instanceof Date)
|
|
@@ -12727,6 +13379,68 @@ class FormPreviewService {
|
|
|
12727
13379
|
}
|
|
12728
13380
|
return String(value);
|
|
12729
13381
|
}
|
|
13382
|
+
/**
|
|
13383
|
+
* 🗓️ FORMATOS DE FECHA DISPONIBLES
|
|
13384
|
+
*
|
|
13385
|
+
* Para agregar un nuevo formato:
|
|
13386
|
+
* 1. Agrega el tipo en DateFormat
|
|
13387
|
+
* 2. Agrega el case en el switch del método formatDate
|
|
13388
|
+
* 3. Define las opciones de Intl.DateTimeFormatOptions
|
|
13389
|
+
*
|
|
13390
|
+
* @example
|
|
13391
|
+
* // Agregar 'dateShort' para mostrar "07-abr-2026"
|
|
13392
|
+
* // 1. type DateFormat = 'date' | 'dateLong' | 'dateTime' | 'dateShort'
|
|
13393
|
+
* // 2. case 'dateShort':
|
|
13394
|
+
* // options.day = '2-digit';
|
|
13395
|
+
* // options.month = 'short';
|
|
13396
|
+
* // options.year = 'numeric';
|
|
13397
|
+
* // break;
|
|
13398
|
+
*/
|
|
13399
|
+
formatDate(value, format) {
|
|
13400
|
+
if (!value)
|
|
13401
|
+
return '';
|
|
13402
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
13403
|
+
if (isNaN(date.getTime())) {
|
|
13404
|
+
// Si no es una fecha válida, devolver el valor original
|
|
13405
|
+
return String(value);
|
|
13406
|
+
}
|
|
13407
|
+
const options = {};
|
|
13408
|
+
switch (format) {
|
|
13409
|
+
case 'date':
|
|
13410
|
+
// "07/04/2026"
|
|
13411
|
+
options.day = '2-digit';
|
|
13412
|
+
options.month = '2-digit';
|
|
13413
|
+
options.year = 'numeric';
|
|
13414
|
+
break;
|
|
13415
|
+
case 'dateLong':
|
|
13416
|
+
// "martes 07 de abril de 2026"
|
|
13417
|
+
options.weekday = 'long';
|
|
13418
|
+
options.day = '2-digit';
|
|
13419
|
+
options.month = 'long';
|
|
13420
|
+
options.year = 'numeric';
|
|
13421
|
+
break;
|
|
13422
|
+
case 'dateTime':
|
|
13423
|
+
// "07/04/2026 14:30"
|
|
13424
|
+
options.day = '2-digit';
|
|
13425
|
+
options.month = '2-digit';
|
|
13426
|
+
options.year = 'numeric';
|
|
13427
|
+
options.hour = '2-digit';
|
|
13428
|
+
options.minute = '2-digit';
|
|
13429
|
+
break;
|
|
13430
|
+
default:
|
|
13431
|
+
return this.formatDefault(value);
|
|
13432
|
+
}
|
|
13433
|
+
try {
|
|
13434
|
+
return date.toLocaleDateString('es-ES', options);
|
|
13435
|
+
}
|
|
13436
|
+
catch (error) {
|
|
13437
|
+
// Si hay error al formatear, devolver el valor original
|
|
13438
|
+
return String(value);
|
|
13439
|
+
}
|
|
13440
|
+
}
|
|
13441
|
+
/**
|
|
13442
|
+
* Formatea un valor individual (para objetos y arrays)
|
|
13443
|
+
*/
|
|
12730
13444
|
formatSingleValue(value) {
|
|
12731
13445
|
if (!value || typeof value !== 'object')
|
|
12732
13446
|
return String(value);
|
|
@@ -12758,6 +13472,9 @@ class FormPreviewService {
|
|
|
12758
13472
|
return '[Objeto]';
|
|
12759
13473
|
}
|
|
12760
13474
|
}
|
|
13475
|
+
/**
|
|
13476
|
+
* Genera el HTML del preview
|
|
13477
|
+
*/
|
|
12761
13478
|
generateHtml(title, cells, compact) {
|
|
12762
13479
|
if (compact) {
|
|
12763
13480
|
return `
|
|
@@ -12808,15 +13525,20 @@ class FormPreviewService {
|
|
|
12808
13525
|
</div>
|
|
12809
13526
|
`;
|
|
12810
13527
|
}
|
|
13528
|
+
/**
|
|
13529
|
+
* 🔍 Debug: Muestra información detallada para depuración
|
|
13530
|
+
* ⚠️ SOLO se ejecuta en entorno de desarrollo
|
|
13531
|
+
*/
|
|
12811
13532
|
debugInputData(data, fields, options) {
|
|
12812
|
-
|
|
12813
|
-
if (!isDev)
|
|
13533
|
+
// ⚠️ Seguridad: Si es producción, NO ejecutar nada
|
|
13534
|
+
if (!this.isDev)
|
|
12814
13535
|
return;
|
|
12815
13536
|
console.group('🔍 FormPreview Debug');
|
|
12816
13537
|
console.log('📊 Data:', data);
|
|
12817
13538
|
console.log('📋 Propiedades disponibles:', data ? Object.keys(data) : 'data es null');
|
|
12818
13539
|
console.log('🎯 Fields solicitados:', fields);
|
|
12819
13540
|
console.log('⚙️ Options:', options);
|
|
13541
|
+
console.log('🌍 Entorno:', this.environment.production ? 'Producción' : 'Desarrollo');
|
|
12820
13542
|
if (data) {
|
|
12821
13543
|
for (const field of fields) {
|
|
12822
13544
|
const value = this.getNestedValue(data, field.key);
|
|
@@ -12830,11 +13552,18 @@ class FormPreviewService {
|
|
|
12830
13552
|
}
|
|
12831
13553
|
else {
|
|
12832
13554
|
console.log(`✅ Campo "${field.key}" existe:`, value);
|
|
13555
|
+
// Mostrar información del formato si existe
|
|
13556
|
+
if (field.format) {
|
|
13557
|
+
console.log(` 📝 Formato: ${typeof field.format === 'function' ? 'Función personalizada' : field.format}`);
|
|
13558
|
+
}
|
|
12833
13559
|
}
|
|
12834
13560
|
}
|
|
12835
13561
|
}
|
|
12836
13562
|
console.groupEnd();
|
|
12837
13563
|
}
|
|
13564
|
+
/**
|
|
13565
|
+
* Encuentra propiedades similares para sugerencias en debug
|
|
13566
|
+
*/
|
|
12838
13567
|
findSimilarProperties(search, properties) {
|
|
12839
13568
|
const searchLower = search.toLowerCase();
|
|
12840
13569
|
return properties
|
|
@@ -12844,6 +13573,9 @@ class FormPreviewService {
|
|
|
12844
13573
|
})
|
|
12845
13574
|
.slice(0, 3);
|
|
12846
13575
|
}
|
|
13576
|
+
/**
|
|
13577
|
+
* Escapa caracteres HTML para evitar inyección
|
|
13578
|
+
*/
|
|
12847
13579
|
escapeHtml(str) {
|
|
12848
13580
|
if (!str)
|
|
12849
13581
|
return '';
|
|
@@ -13150,6 +13882,147 @@ function createCurrencyFormatter(locale, currency) {
|
|
|
13150
13882
|
});
|
|
13151
13883
|
}
|
|
13152
13884
|
|
|
13885
|
+
/**
|
|
13886
|
+
* Guarda un valor en localStorage
|
|
13887
|
+
* Soporta: strings, números, objetos, arrays, null, undefined
|
|
13888
|
+
*/
|
|
13889
|
+
function setStorage(key, value) {
|
|
13890
|
+
try {
|
|
13891
|
+
// 🔧 Manejar null y undefined explícitamente
|
|
13892
|
+
if (value === null) {
|
|
13893
|
+
localStorage.setItem(key, 'null');
|
|
13894
|
+
}
|
|
13895
|
+
else if (value === undefined) {
|
|
13896
|
+
localStorage.setItem(key, 'undefined');
|
|
13897
|
+
}
|
|
13898
|
+
else {
|
|
13899
|
+
localStorage.setItem(key, JSON.stringify(value));
|
|
13900
|
+
}
|
|
13901
|
+
}
|
|
13902
|
+
catch (error) {
|
|
13903
|
+
console.error(`Error guardando en localStorage (${key})`, error);
|
|
13904
|
+
}
|
|
13905
|
+
}
|
|
13906
|
+
/**
|
|
13907
|
+
* Obtiene un valor desde localStorage
|
|
13908
|
+
* @param defaultValue - Valor por defecto si no existe la clave
|
|
13909
|
+
* @returns El valor guardado o el defaultValue
|
|
13910
|
+
*/
|
|
13911
|
+
function getStorage(key, defaultValue) {
|
|
13912
|
+
try {
|
|
13913
|
+
const data = localStorage.getItem(key);
|
|
13914
|
+
// Si no existe la clave en el storage
|
|
13915
|
+
if (data === null) {
|
|
13916
|
+
return defaultValue;
|
|
13917
|
+
}
|
|
13918
|
+
// 🔧 Manejar valores especiales
|
|
13919
|
+
if (data === 'null') {
|
|
13920
|
+
return null; // Retorna null explícitamente
|
|
13921
|
+
}
|
|
13922
|
+
if (data === 'undefined') {
|
|
13923
|
+
return undefined;
|
|
13924
|
+
}
|
|
13925
|
+
// Intentar parsear como JSON
|
|
13926
|
+
try {
|
|
13927
|
+
return JSON.parse(data);
|
|
13928
|
+
}
|
|
13929
|
+
catch {
|
|
13930
|
+
// Si no es JSON válido, devolver como string
|
|
13931
|
+
return data;
|
|
13932
|
+
}
|
|
13933
|
+
}
|
|
13934
|
+
catch (error) {
|
|
13935
|
+
console.error(`Error recuperando de localStorage (${key})`, error);
|
|
13936
|
+
return defaultValue;
|
|
13937
|
+
}
|
|
13938
|
+
}
|
|
13939
|
+
// Función específica para objetos con merge
|
|
13940
|
+
function setStorageObject(key, values = {}, merge = true) {
|
|
13941
|
+
try {
|
|
13942
|
+
if (merge) {
|
|
13943
|
+
const current = getStorage(key, {});
|
|
13944
|
+
localStorage.setItem(key, JSON.stringify({ ...current, ...values }));
|
|
13945
|
+
}
|
|
13946
|
+
else {
|
|
13947
|
+
localStorage.setItem(key, JSON.stringify(values));
|
|
13948
|
+
}
|
|
13949
|
+
}
|
|
13950
|
+
catch (error) {
|
|
13951
|
+
console.error(`Error guardando en localStorage (${key})`, error);
|
|
13952
|
+
}
|
|
13953
|
+
}
|
|
13954
|
+
/**
|
|
13955
|
+
* 🆕 Función para eliminar una clave del storage
|
|
13956
|
+
*/
|
|
13957
|
+
function removeStorage(key) {
|
|
13958
|
+
try {
|
|
13959
|
+
localStorage.removeItem(key);
|
|
13960
|
+
}
|
|
13961
|
+
catch (error) {
|
|
13962
|
+
console.error(`Error eliminando de localStorage (${key})`, error);
|
|
13963
|
+
}
|
|
13964
|
+
}
|
|
13965
|
+
/**
|
|
13966
|
+
* 🆕 Función para verificar si existe una clave en el storage
|
|
13967
|
+
*/
|
|
13968
|
+
function hasStorage(key) {
|
|
13969
|
+
try {
|
|
13970
|
+
return localStorage.getItem(key) !== null;
|
|
13971
|
+
}
|
|
13972
|
+
catch (error) {
|
|
13973
|
+
console.error(`Error verificando en localStorage (${key})`, error);
|
|
13974
|
+
return false;
|
|
13975
|
+
}
|
|
13976
|
+
}
|
|
13977
|
+
|
|
13978
|
+
/**
|
|
13979
|
+
* Calcula la fecha sumando días hábiles (Lunes a Sábado, Domingos no cuentan)
|
|
13980
|
+
* Los feriados en el rango no consumen días
|
|
13981
|
+
*
|
|
13982
|
+
* @param fechaInicio - Fecha desde donde empezar
|
|
13983
|
+
* @param cantidadDias - Días hábiles a sumar
|
|
13984
|
+
* @param feriados - Lista de feriados (opcional)
|
|
13985
|
+
* @returns Fecha calculada o null si fechaInicio es null
|
|
13986
|
+
*
|
|
13987
|
+
* @example
|
|
13988
|
+
* // Sin feriados
|
|
13989
|
+
* calcularFechaFin(new Date('2026-07-07'), 15) // 2026-07-25
|
|
13990
|
+
*
|
|
13991
|
+
* @example
|
|
13992
|
+
* // Con feriados
|
|
13993
|
+
* calcularFechaFin(
|
|
13994
|
+
* new Date('2026-07-07'),
|
|
13995
|
+
* 15,
|
|
13996
|
+
* [{ date: '2026-07-14' }, { date: '2026-07-21' }]
|
|
13997
|
+
* ) // 2026-07-27
|
|
13998
|
+
*/
|
|
13999
|
+
function dsxCalcularRangoFecha(fechaInicio, cantidadDias, feriados) {
|
|
14000
|
+
// Validación básica
|
|
14001
|
+
if (!fechaInicio)
|
|
14002
|
+
return null;
|
|
14003
|
+
if (cantidadDias === 0)
|
|
14004
|
+
return new Date(fechaInicio);
|
|
14005
|
+
// Crear Set de feriados con moment para comparación directa
|
|
14006
|
+
const feriadosSet = new Set(feriados?.map((f) => moment(f.dateHoliday).format('YYYY-MM-DD')));
|
|
14007
|
+
// Usar moment para la fecha
|
|
14008
|
+
const fecha = moment(fechaInicio).startOf('day');
|
|
14009
|
+
let dias = cantidadDias;
|
|
14010
|
+
while (dias > 0) {
|
|
14011
|
+
fecha.add(1, 'day');
|
|
14012
|
+
const diaSemana = fecha.day(); // 0=domingo
|
|
14013
|
+
const fechaStr = fecha.format('YYYY-MM-DD');
|
|
14014
|
+
// Días que NO consumen días (se saltan):
|
|
14015
|
+
// 1. Domingos
|
|
14016
|
+
// 2. Feriados
|
|
14017
|
+
if (diaSemana === 0 || feriadosSet.has(fechaStr)) {
|
|
14018
|
+
continue;
|
|
14019
|
+
}
|
|
14020
|
+
// Sábado = medio día, resto = día completo
|
|
14021
|
+
dias -= diaSemana === 6 ? 0.5 : 1;
|
|
14022
|
+
}
|
|
14023
|
+
return fecha.toDate();
|
|
14024
|
+
}
|
|
14025
|
+
|
|
13153
14026
|
function chainControlGroups(form, groups) {
|
|
13154
14027
|
groups.forEach((group) => {
|
|
13155
14028
|
chainControls(form, group);
|
|
@@ -13783,5 +14656,5 @@ function sorensenDiceValidator(dataSource, key, umbral = 0.7) {
|
|
|
13783
14656
|
* Generated bundle index. Do not edit.
|
|
13784
14657
|
*/
|
|
13785
14658
|
|
|
13786
|
-
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, DsxdateTime, 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 };
|
|
14659
|
+
export { ACTION_TYPES, AlertaService, AppMessageErrorComponent, AppMessageHelpComponent, ArrowNavigationDirective, AuthorizeService, AutoScrollHeightDirective, BaseCRUDService, CACHE_KEYS, CacheService, CssV2Component, DSX_PALETTE, DateIndicator, DocxPreviewComponent, DsxAddToolsModule, DsxAutocomplete, DsxButtonComponent, DsxCalendarView, DsxEnableDisable, DsxInputCurrency, DsxMessagesService, DsxSelect, DsxStatusToggle, DsxdateShort, DsxdateTime, 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, dsxCalcularRangoFecha, getActionMessageConfig, getStorage, getZeroBasedRolIndex, guardTokenPurposeGuard, hasStorage, httpAuthorizeInterceptor, minimumAgeValidator, nitValidator, productionEnvironment, provideEnvironment, removeStorage, setStorage, setStorageObject, sorensenDiceValidator, templateStructureValidator, templateVariablesValidator, validateEnvironmentConfig };
|
|
13787
14660
|
//# sourceMappingURL=ngx-dsxlibrary.mjs.map
|