ngx-dsxlibrary 2.21.7 → 2.21.8

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-dsxlibrary.mjs","sources":["../../../projects/ngx-dsx/src/lib/components/app-message-error/app-message-error.component.ts","../../../projects/ngx-dsx/src/lib/components/app-message-error/app-message-error.component.html","../../../projects/ngx-dsx/src/lib/components/inputs/file/file.component.ts","../../../projects/ngx-dsx/src/lib/components/inputs/file/file.component.html","../../../projects/ngx-dsx/src/lib/components/json/json-viewer/json-viewer.component.ts","../../../projects/ngx-dsx/src/lib/components/json/json-viewer/json-viewer.component.html","../../../projects/ngx-dsx/src/lib/components/kpicard/kpicard.component.ts","../../../projects/ngx-dsx/src/lib/components/kpicard/kpicard.component.html","../../../projects/ngx-dsx/src/lib/components/view/docx-preview/docx-preview.component.ts","../../../projects/ngx-dsx/src/lib/components/view/docx-preview/docx-preview.component.html","../../../projects/ngx-dsx/src/lib/services/src/icon-dsx.service.ts","../../../projects/ngx-dsx/src/lib/components/icon-dsx/icon-dsx.component.ts","../../../projects/ngx-dsx/src/lib/components/icon-dsx/icon-dsx.component.html","../../../projects/ngx-dsx/src/lib/pipe/src/json-highlight.pipe.ts","../../../projects/ngx-dsx/src/lib/injections/environment.token.ts","../../../projects/ngx-dsx/src/lib/components/json/json-values-debuj/json-values-debuj.component.ts","../../../projects/ngx-dsx/src/lib/components/json/json-values-debuj/json-values-debuj.component.html","../../../projects/ngx-dsx/src/lib/services/src/spinner-loading.service.ts","../../../projects/ngx-dsx/src/lib/components/logo/logo-dsx/logo-dsx.component.ts","../../../projects/ngx-dsx/src/lib/components/logo/logo-dsx/logo-dsx.component.html","../../../projects/ngx-dsx/src/lib/components/loading-lottie/loading-lottie.component.ts","../../../projects/ngx-dsx/src/lib/components/loading-lottie/loading-lottie.component.html","../../../projects/ngx-dsx/src/lib/components/loading/css-v2/css-v2.component.ts","../../../projects/ngx-dsx/src/lib/components/loading/css-v2/css-v2.component.html","../../../projects/ngx-dsx/src/lib/components/loading/loading.component.ts","../../../projects/ngx-dsx/src/lib/components/loading/loading.component.html","../../../projects/ngx-dsx/src/lib/services/src/alerta.service.ts","../../../projects/ngx-dsx/src/lib/models/src/environment-base.ts","../../../projects/ngx-dsx/src/lib/services/src/security.service.ts","../../../projects/ngx-dsx/src/lib/services/src/authorize.service.ts","../../../projects/ngx-dsx/src/lib/injections/parameterSecurity.ts","../../../projects/ngx-dsx/src/lib/services/src/parameter-values.service.ts","../../../projects/ngx-dsx/src/lib/services/src/request-metrics.service.ts","../../../projects/ngx-dsx/src/lib/components/status/network-status/network-status.component.ts","../../../projects/ngx-dsx/src/lib/components/status/network-status/network-status.component.html","../../../projects/ngx-dsx/src/lib/components/navbar-dsx/navbar-dsx.component.ts","../../../projects/ngx-dsx/src/lib/components/navbar-dsx/navbar-dsx.component.html","../../../projects/ngx-dsx/src/lib/directives/src/arrow-navigation.directive.ts","../../../projects/ngx-dsx/src/lib/directives/src/only-rango-pattern.directive.ts","../../../projects/ngx-dsx/src/lib/directives/src/select-all-on-focus.directive.ts","../../../projects/ngx-dsx/src/lib/injections/cache.token.ts","../../../projects/ngx-dsx/src/lib/services/src/error-handler.service.ts","../../../projects/ngx-dsx/src/lib/interceptors/http-authorize.interceptor.ts","../../../projects/ngx-dsx/src/lib/models/src/cache.types.ts","../../../projects/ngx-dsx/src/lib/modules/src/dsx-add-tools.module.ts","../../../projects/ngx-dsx/src/lib/modules/src/prime-ng.module.ts","../../../projects/ngx-dsx/src/lib/pipe/src/join-by.pipe.ts","../../../projects/ngx-dsx/src/lib/pipe/src/truncate.pipe.ts","../../../projects/ngx-dsx/src/lib/services/src/endpoint.service.ts","../../../projects/ngx-dsx/src/lib/services/src/base-crud.service.ts","../../../projects/ngx-dsx/src/lib/services/src/cache.service.ts","../../../projects/ngx-dsx/src/lib/services/src/cache.provider.ts","../../../projects/ngx-dsx/src/lib/services/src/dte.service.ts","../../../projects/ngx-dsx/src/lib/utils/src/form-data.util.ts","../../../projects/ngx-dsx/src/lib/services/src/http-helpers.service.ts","../../../projects/ngx-dsx/src/lib/services/src/master-detail-change.service.ts","../../../projects/ngx-dsx/src/lib/services/src/utility-add.service.ts","../../../projects/ngx-dsx/src/lib/utils/src/currency.util.ts","../../../projects/ngx-dsx/src/lib/validations/addons.validators.ts","../../../projects/ngx-dsx/src/public-api.ts","../../../projects/ngx-dsx/src/ngx-dsxlibrary.ts"],"sourcesContent":["import { DecimalPipe } from '@angular/common';\r\nimport {\r\n AfterViewInit,\r\n Component,\r\n DoCheck,\r\n ElementRef,\r\n Input,\r\n OnDestroy,\r\n Renderer2,\r\n} from '@angular/core';\r\nimport { AbstractControl, FormGroup } from '@angular/forms';\r\nimport { TagModule } from 'primeng/tag';\r\n\r\n@Component({\r\n selector: 'app-message-error',\r\n imports: [TagModule, DecimalPipe],\r\n templateUrl: './app-message-error.component.html',\r\n styleUrl: './app-message-error.component.css',\r\n})\r\n/**\r\n * Renderiza mensajes de validacion para un control o formulario.\r\n *\r\n * Nota de depuracion:\r\n * - En contenedores PrimeNG `p-floatlabel`, el mensaje visual se pinta como\r\n * overlay (CSS absoluto) para no deformar la posicion del label.\r\n * - Para evitar solapamiento con el siguiente campo, este componente ajusta\r\n * temporalmente el `margin-bottom` del `.p-floatlabel` padre cuando el error\r\n * esta visible.\r\n */\r\nexport class AppMessageErrorComponent\r\n implements AfterViewInit, DoCheck, OnDestroy\r\n{\r\n // Espacio vertical reservado bajo el float label cuando hay error visible.\r\n private readonly floatLabelErrorSpace = '1.25rem';\r\n // Referencia al contenedor PrimeNG padre, si existe.\r\n private floatLabelElement: HTMLElement | null = null;\r\n // Se conserva el estilo inline original para restaurarlo al ocultar/destruir.\r\n private previousInlineMarginBottom = '';\r\n // Evita escrituras de estilo repetidas cuando el estado de visibilidad no cambia.\r\n private lastAppliedVisibleState = false;\r\n\r\n constructor(\r\n private readonly elementRef: ElementRef<HTMLElement>,\r\n private readonly renderer: Renderer2,\r\n ) {}\r\n\r\n // Control de formulario que se pasa como input.\r\n @Input() control: AbstractControl | null | undefined = null;\r\n @Input() form: FormGroup | null = null;\r\n\r\n ngAfterViewInit(): void {\r\n // Busca el FloatLabel mas cercano para ajustar su separacion inferior.\r\n this.floatLabelElement = this.elementRef.nativeElement.closest(\r\n '.p-floatlabel',\r\n ) as HTMLElement | null;\r\n\r\n if (this.floatLabelElement) {\r\n this.previousInlineMarginBottom =\r\n this.floatLabelElement.style.marginBottom;\r\n this.syncFloatLabelSpacing();\r\n }\r\n }\r\n\r\n ngDoCheck(): void {\r\n // Se ejecuta en cada ciclo para reaccionar al estado touched/invalid.\r\n this.syncFloatLabelSpacing();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n if (!this.floatLabelElement) {\r\n return;\r\n }\r\n\r\n if (this.previousInlineMarginBottom) {\r\n this.renderer.setStyle(\r\n this.floatLabelElement,\r\n 'margin-bottom',\r\n this.previousInlineMarginBottom,\r\n );\r\n return;\r\n }\r\n\r\n this.renderer.removeStyle(this.floatLabelElement, 'margin-bottom');\r\n }\r\n\r\n private syncFloatLabelSpacing(): void {\r\n if (!this.floatLabelElement) {\r\n return;\r\n }\r\n\r\n const isVisible = !!(this.control?.touched && this.control?.invalid);\r\n if (isVisible === this.lastAppliedVisibleState) {\r\n return;\r\n }\r\n\r\n this.lastAppliedVisibleState = isVisible;\r\n if (isVisible) {\r\n this.renderer.setStyle(\r\n this.floatLabelElement,\r\n 'margin-bottom',\r\n this.floatLabelErrorSpace,\r\n );\r\n return;\r\n }\r\n\r\n if (this.previousInlineMarginBottom) {\r\n this.renderer.setStyle(\r\n this.floatLabelElement,\r\n 'margin-bottom',\r\n this.previousInlineMarginBottom,\r\n );\r\n return;\r\n }\r\n\r\n this.renderer.removeStyle(this.floatLabelElement, 'margin-bottom');\r\n }\r\n}\r\n","<div\r\n class=\"dsx-error-slot\"\r\n [class.is-visible]=\"control?.touched && control?.invalid\"\r\n>\r\n @if (control?.touched && control?.invalid) {\r\n <div class=\"dsx-error-message\">\r\n @if (control?.errors?.[\"required\"]) {\r\n El campo <strong>es requerido.</strong>\r\n } @else if (control?.errors?.[\"invalidNIT\"]) {\r\n <strong>{{ control?.errors?.[\"invalidNIT\"]?.message }}</strong\r\n >.\r\n } @else if (control?.errors?.[\"invalidCUI\"]) {\r\n <strong>{{ control?.errors?.[\"invalidCUI\"]?.message }}</strong\r\n >.\r\n } @else if (control?.errors?.[\"invalidDateRange\"]) {\r\n <strong>{{ control?.errors?.[\"invalidDateRange\"]?.message }}</strong\r\n >.\r\n } @else if (control?.errors?.[\"dateNotRange\"]) {\r\n <strong>{{ control?.errors?.[\"dateNotRange\"]?.message }}</strong\r\n >.\r\n } @else if (control?.errors?.[\"minlength\"]) {\r\n Debe tener al menos\r\n <strong>{{ control?.errors?.[\"minlength\"]?.requiredLength }}</strong>\r\n caracteres.\r\n } @else if (control?.errors?.[\"maxlength\"]) {\r\n Debe tener como máximo\r\n <strong>{{ control?.errors?.[\"maxlength\"]?.requiredLength }}</strong>\r\n caracteres.\r\n } @else if (control?.errors?.[\"min\"]) {\r\n El valor mínimo permitido es\r\n <strong>{{ control?.errors?.[\"min\"]?.min }}</strong\r\n >.\r\n } @else if (control?.errors?.[\"max\"]) {\r\n El valor máximo permitido es\r\n <strong>{{ control?.errors?.[\"max\"]?.max | number: \"1.2-2\" }}</strong\r\n >.\r\n } @else if (control?.errors?.[\"email\"]) {\r\n Debe ser una dirección de correo válida.\r\n } @else if (control?.errors?.[\"pattern\"]) {\r\n El campo no tiene el formato requerido.\r\n } @else {\r\n Existe un error aún no identificado.\r\n }\r\n </div>\r\n }\r\n</div>\r\n<!-- mensaje para formulario en general -->\r\n@if (form?.invalid && form?.touched) {\r\n <div class=\"mt-2 mb-2\">\r\n @if (this.form?.errors?.[\"atLeastOneRequired\"]) {\r\n <p-tag severity=\"danger\" [rounded]=\"true\">\r\n {{ form?.getError(\"atLeastOneRequired\")?.message }}</p-tag\r\n >\r\n }\r\n </div>\r\n}\r\n","import { Component, forwardRef, input, signal, viewChild } from '@angular/core';\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\r\nimport { FileUpload } from 'primeng/fileupload';\r\n\r\n@Component({\r\n selector: 'dsx-file-upload',\r\n imports: [FileUpload],\r\n templateUrl: './file.component.html',\r\n styleUrl: './file.component.css',\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => FileComponent),\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class FileComponent implements ControlValueAccessor {\r\n fileUpload = viewChild.required<FileUpload>('fileUpload');\r\n accept = input<string>('.xls,.xlsx');\r\n // Tamaño máximo en MB (se convierte internamente a bytes)\r\n maxFileSize = input<number>(5);\r\n // Mensajes para tipo de archivo inválido\r\n invalidSummary = input<string>('El formato es inválido.');\r\n invalidDetail = input<string>('Archivo debe tener un formato válido. ({0}).');\r\n\r\n // Mensajes para tamaño de archivo inválido\r\n invalidSizeSummary = input<string>('Tamaño de archivo inválido.');\r\n invalidSizeDetail = input<string>('El tamaño máximo permitido es {0}');\r\n disabled = signal<boolean>(false);\r\n private value: File | null = null;\r\n private onChange = (_: File | null) => {};\r\n private onTouched = () => {};\r\n\r\n onSelect(event: any) {\r\n const file = event.files?.[0] ?? null;\r\n this.value = file;\r\n this.onChange(file);\r\n this.onTouched();\r\n }\r\n\r\n /** 👇 API pública */\r\n clear() {\r\n this.fileUpload()?.clear();\r\n this.value = null;\r\n this.onChange(null);\r\n }\r\n\r\n writeValue(value: File | null): void {\r\n this.value = value;\r\n\r\n if (!value) {\r\n // Si se limpia el valor desde el formulario, limpiamos el componente\r\n this.fileUpload()?.clear();\r\n }\r\n }\r\n registerOnChange(fn: any): void {\r\n this.onChange = fn;\r\n }\r\n registerOnTouched(fn: any): void {\r\n this.onTouched = fn;\r\n }\r\n setDisabledState(isDisabled: boolean): void {\r\n this.disabled.set(isDisabled);\r\n }\r\n}\r\n","<p-fileUpload\r\n #fileUpload\r\n mode=\"basic\"\r\n [accept]=\"accept()\"\r\n [maxFileSize]=\"maxFileSize() * 1024 * 1024\"\r\n [invalidFileTypeMessageSummary]=\"invalidSummary()\"\r\n [invalidFileTypeMessageDetail]=\"invalidDetail()\"\r\n [invalidFileSizeMessageSummary]=\"invalidSizeSummary()\"\r\n [invalidFileSizeMessageDetail]=\"invalidSizeDetail()\"\r\n (onSelect)=\"onSelect($event)\"\r\n [disabled]=\"disabled()\"\r\n/>\r\n","import { Component, effect, forwardRef, input } from '@angular/core';\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\r\nimport { TreeNode } from 'primeng/api';\r\nimport { TreeModule } from 'primeng/tree';\r\n\r\n@Component({\r\n selector: 'app-json-viewer',\r\n standalone: true,\r\n imports: [TreeModule],\r\n templateUrl: './json-viewer.component.html',\r\n styleUrl: './json-viewer.component.css',\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => JsonViewerComponent),\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class JsonViewerComponent implements ControlValueAccessor {\r\n data = input<unknown>(null);\r\n nodes: TreeNode[] = [];\r\n selectedNode: TreeNode | null = null;\r\n private controlValue: unknown = null;\r\n\r\n constructor() {\r\n effect(() => {\r\n if (this.controlValue === null || this.controlValue === undefined) {\r\n this.updateNodes(this.data());\r\n }\r\n });\r\n }\r\n\r\n writeValue(value: unknown): void {\r\n this.controlValue = value;\r\n this.updateNodes(value);\r\n }\r\n\r\n registerOnChange(fn: (value: unknown) => void): void {\r\n void fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n void fn;\r\n }\r\n\r\n setDisabledState(isDisabled: boolean): void {\r\n void isDisabled;\r\n }\r\n\r\n onNodeSelect(event: { node?: TreeNode }): void {\r\n const node = event?.node;\r\n\r\n if (!node?.children?.length) return;\r\n\r\n node.expanded = !node.expanded;\r\n this.selectedNode = null;\r\n this.nodes = [...this.nodes];\r\n }\r\n\r\n private updateNodes(value: unknown): void {\r\n this.nodes = this.buildTree(this.parseIfNeeded(value));\r\n }\r\n\r\n private parseIfNeeded(data: unknown): any {\r\n if (!data) return {};\r\n\r\n if (typeof data === 'string') {\r\n try {\r\n return JSON.parse(data);\r\n } catch {\r\n return {};\r\n }\r\n }\r\n\r\n return data;\r\n }\r\n\r\n private buildTree(data: any, parentKey: string = '0'): TreeNode[] {\r\n if (Array.isArray(data)) {\r\n return data.map((item, index) => {\r\n const key = `${parentKey}-${index}`;\r\n\r\n if (this.isComplex(item)) {\r\n return {\r\n key,\r\n label: `[${index}]`,\r\n //icon: this.getIcon(item),\r\n children: this.buildTree(item, key),\r\n };\r\n }\r\n\r\n return {\r\n key,\r\n label: `[${index}]: ${this.formatPrimitive(item)}`,\r\n //icon: 'pi pi-file',\r\n };\r\n });\r\n }\r\n\r\n if (typeof data === 'object' && data !== null) {\r\n return Object.keys(data).map((key, index) => {\r\n const value = data[key];\r\n const nodeKey = `${parentKey}-${index}`;\r\n\r\n if (this.isComplex(value)) {\r\n return {\r\n key: nodeKey,\r\n label: key,\r\n //icon: this.getIcon(value),\r\n children: this.buildTree(value, nodeKey),\r\n };\r\n }\r\n\r\n return {\r\n key: nodeKey,\r\n label: `${key}: ${this.formatPrimitive(value)}`,\r\n icon: 'pi pi-file',\r\n };\r\n });\r\n }\r\n\r\n return [\r\n {\r\n key: parentKey,\r\n label: this.formatPrimitive(data),\r\n icon: 'pi pi-file',\r\n },\r\n ];\r\n }\r\n\r\n private isComplex(value: unknown): boolean {\r\n return (\r\n Array.isArray(value) || (typeof value === 'object' && value !== null)\r\n );\r\n }\r\n\r\n private formatPrimitive(value: unknown): string {\r\n if (value === null || value === undefined) return '-';\r\n\r\n if (typeof value === 'string') return value;\r\n\r\n return String(value);\r\n }\r\n\r\n private getIcon(value: any): string {\r\n if (Array.isArray(value)) return 'pi pi-list';\r\n\r\n if (typeof value === 'object') return 'pi pi-folder';\r\n\r\n return 'pi pi-file';\r\n }\r\n}\r\n","<p-tree\r\n\t[value]=\"nodes\"\r\n\tclass=\"json-tree w-full\"\r\n\tselectionMode=\"single\"\r\n\t[(selection)]=\"selectedNode\"\r\n\t[highlightOnSelect]=\"false\"\r\n\t(onNodeSelect)=\"onNodeSelect($event)\"\r\n>\r\n</p-tree>\r\n","import { Component, input } from '@angular/core';\r\nimport { CountUpDirective } from 'ngx-countup';\r\n\r\n@Component({\r\n selector: 'app-kpicard',\r\n imports: [CountUpDirective],\r\n templateUrl: './kpicard.component.html',\r\n styleUrl: './kpicard.component.css',\r\n})\r\nexport class KpicardComponent {\r\n //type = input.required<string>();\r\n option = input.required<'currency' | 'integer' | 'percent'>();\r\n label = input.required<string>();\r\n iconType = input<string>('fa-regular fa-bell');\r\n color = input<string>();\r\n valor = input<number>(0);\r\n theme = input<\r\n | 'light'\r\n | 'dark'\r\n | 'aqua'\r\n | 'sunset'\r\n | 'mint'\r\n | 'peach'\r\n | 'plasma'\r\n | 'nebula'\r\n >('light');\r\n\r\n options: Record<'currency' | 'integer' | 'percent', any> = {\r\n currency: {\r\n startVal: 0,\r\n duration: 0.5,\r\n //prefix: 'Q',\r\n decimalPlaces: 2, // Decimales\r\n useGrouping: true, // Separador de miles\r\n separator: ',', // Carácter separador\r\n decimal: '.', // Carácter decimal\r\n suffix: ' GTQ', // Sufijo\r\n scrollSpyDelay: 200, // Retardo antes de la animación\r\n enableScrollSpy: true,\r\n scrollSpyOnce: true,\r\n },\r\n integer: {\r\n startVal: 0,\r\n duration: 0.5,\r\n prefix: 'Cant. ',\r\n decimalPlaces: 2, // Decimales\r\n useGrouping: true, // Separador de miles\r\n separator: ',', // Carácter separador\r\n decimal: '.', // Carácter decimal\r\n scrollSpyDelay: 200, // Retardo antes de la animación\r\n enableScrollSpy: true,\r\n scrollSpyOnce: true,\r\n },\r\n percent: {\r\n startVal: 0,\r\n duration: 0.5,\r\n suffix: '%',\r\n decimalPlaces: 2, // Decimales\r\n useGrouping: true, // Separador de miles\r\n separator: ',', // Carácter separador\r\n decimal: '.', // Carácter decimal\r\n scrollSpyDelay: 200, // Retardo antes de la animación\r\n enableScrollSpy: true,\r\n scrollSpyOnce: true,\r\n },\r\n };\r\n\r\n // ✅ Método auxiliar para obtener la opción con seguridad\r\n getSelectedOption() {\r\n return this.options[this.option()] ?? this.options.currency; // Si no existe, usa `currency`\r\n }\r\n}\r\n","<div [class]=\"`kpi-card ${color()} ${theme()}-theme`\">\r\n <div class=\"kpi-container\">\r\n <span\r\n [countUp]=\"valor()\"\r\n [countUpOptions]=\"getSelectedOption()\"\r\n [class]=\"`card-value-${theme()}`\"\r\n >0</span\r\n >\r\n <span [class]=\"`card-text-${theme()}`\">{{ label() }}</span>\r\n </div>\r\n <i [class]=\"`${iconType()} icon icon-${theme()}`\"></i>\r\n</div>\r\n","import {\r\n Component,\r\n effect,\r\n ElementRef,\r\n EventEmitter,\r\n Input,\r\n input,\r\n Output,\r\n signal,\r\n viewChild,\r\n WritableSignal,\r\n} from '@angular/core';\r\nimport { DialogModule } from 'primeng/dialog';\r\n\r\ntype DocxRenderOptions = {\r\n ignoreWidth?: boolean;\r\n renderHeaders?: boolean;\r\n renderFooters?: boolean;\r\n};\r\n\r\n@Component({\r\n selector: 'app-docx-preview',\r\n imports: [DialogModule],\r\n templateUrl: './docx-preview.component.html',\r\n styleUrl: './docx-preview.component.css',\r\n})\r\nexport class DocxPreviewComponent {\r\n view = viewChild<ElementRef>('viewer');\r\n private visibleState: WritableSignal<boolean> = signal(false);\r\n private renderToken = 0;\r\n\r\n @Input()\r\n set visible(value: boolean) {\r\n this.visibleState.set(!!value);\r\n }\r\n\r\n get visible(): boolean {\r\n return this.visibleState();\r\n }\r\n\r\n @Output() visibleChange = new EventEmitter<boolean>();\r\n blob = input<Blob | null>(null);\r\n\r\n constructor() {\r\n effect(() => {\r\n const container = this.view()?.nativeElement;\r\n const isVisible = this.visibleState();\r\n const fileBlob = this.blob();\r\n\r\n if (!container) {\r\n return;\r\n }\r\n\r\n if (!isVisible) {\r\n this.renderToken++;\r\n container.innerHTML = '';\r\n return;\r\n }\r\n\r\n if (!(fileBlob instanceof Blob)) {\r\n this.renderToken++;\r\n container.innerHTML =\r\n '<p>No hay un archivo .docx válido para previsualizar.</p>';\r\n return;\r\n }\r\n\r\n if (!fileBlob.size) {\r\n this.renderToken++;\r\n container.innerHTML = '<p>El archivo .docx está vacío.</p>';\r\n return;\r\n }\r\n\r\n const token = ++this.renderToken;\r\n container.innerHTML = '';\r\n const options: DocxRenderOptions = {\r\n ignoreWidth: true,\r\n renderHeaders: true,\r\n renderFooters: true,\r\n };\r\n\r\n void this.renderDocx(fileBlob, container, options, token);\r\n });\r\n }\r\n\r\n private async renderDocx(\r\n fileBlob: Blob,\r\n container: HTMLElement,\r\n options: DocxRenderOptions,\r\n token: number,\r\n ) {\r\n try {\r\n const dynamicImport = new Function(\r\n 'modulePath',\r\n 'return import(modulePath);',\r\n ) as (modulePath: string) => Promise<{ renderAsync: Function }>;\r\n\r\n const docxPreviewModule = await dynamicImport('docx-preview');\r\n\r\n if (token !== this.renderToken || !this.visibleState()) {\r\n return;\r\n }\r\n\r\n await docxPreviewModule.renderAsync(\r\n fileBlob,\r\n container,\r\n undefined,\r\n options,\r\n );\r\n } catch {\r\n if (token !== this.renderToken || !this.visibleState()) {\r\n return;\r\n }\r\n\r\n container.innerHTML =\r\n '<p>No se pudo cargar la vista previa DOCX. Instala <strong>docx-preview</strong> para habilitar esta función.</p>';\r\n }\r\n }\r\n\r\n onHide() {\r\n const container = this.view()?.nativeElement;\r\n\r\n if (container) {\r\n this.renderToken++;\r\n container.innerHTML = '';\r\n }\r\n\r\n this.visibleChange.emit(false);\r\n }\r\n}\r\n","<p-dialog\r\n header=\"Vista preliminar del documento\"\r\n [visible]=\"visible\"\r\n (onHide)=\"onHide()\"\r\n [modal]=\"true\"\r\n [breakpoints]=\"{ '1199px': '75vw', '575px': '90vw' }\"\r\n [style]=\"{ width: '80vw' }\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n>\r\n <div #viewer></div>\r\n</p-dialog>\r\n","import { HttpClient } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\r\nimport { catchError, map, Observable, of, shareReplay } from 'rxjs';\r\n\r\n/** SVG de warning_amber como fallback cuando no se encuentra un icono */\r\nconst WARNING_AMBER_SVG = `<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"currentColor\"><path d=\"M80-160v-80h800v80H80Zm40-120 360-560 360 560H120Zm178-80h364L480-660 298-360Zm182 0Z\"/></svg>`;\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class IconDsxService {\r\n private cache = new Map<string, Observable<SafeHtml>>();\r\n\r\n constructor(\r\n private http: HttpClient,\r\n private sanitizer: DomSanitizer,\r\n ) {}\r\n\r\n /** Carga SVG desde assets/dsxResource/material-design-icons/outlined */\r\n getIcon(name: string): Observable<SafeHtml> {\r\n if (this.cache.has(name)) {\r\n return this.cache.get(name)!;\r\n }\r\n\r\n const iconPath = `mdio/${name}.svg`;\r\n\r\n const request$ = this.http.get(iconPath, { responseType: 'text' }).pipe(\r\n map((svg) => this.sanitizer.bypassSecurityTrustHtml(svg)),\r\n catchError(() => {\r\n return of(this.sanitizer.bypassSecurityTrustHtml(WARNING_AMBER_SVG));\r\n }),\r\n shareReplay(1),\r\n );\r\n\r\n this.cache.set(name, request$);\r\n return request$;\r\n }\r\n}\r\n","import { AsyncPipe } from '@angular/common';\r\nimport { Component, Input } from '@angular/core';\r\nimport { SafeHtml } from '@angular/platform-browser';\r\nimport { Observable } from 'rxjs';\r\nimport { IconDsxService } from '../../services/src/icon-dsx.service';\r\n\r\n@Component({\r\n selector: 'icon-dsx',\r\n imports: [AsyncPipe],\r\n templateUrl: './icon-dsx.component.html',\r\n styleUrl: './icon-dsx.component.css',\r\n})\r\nexport class IconDsxComponent {\r\n @Input() name!: string;\r\n\r\n svg$!: Observable<SafeHtml>; // 👈 AHORA es un Observable\r\n\r\n constructor(private iconService: IconDsxService) {}\r\n\r\n ngOnInit(): void {\r\n this.svg$ = this.iconService.getIcon(this.name); // 👈 AHORA CUADRA CON EL async\r\n }\r\n}\r\n","<span class=\"dsx-icon\" [innerHTML]=\"svg$ | async\"></span>\r\n","import { Pipe, PipeTransform } from '@angular/core';\r\n\r\n@Pipe({\r\n name: 'jsonHighlight',\r\n})\r\nexport class JsonHighlightPipe implements PipeTransform {\r\n /**\r\n * Stringifica el JSON manteniendo arrays en una línea para una vista más compacta\r\n */\r\n private compactStringify(obj: any, indent: number = 2): string {\r\n const spaces = ' '.repeat(indent);\r\n\r\n if (obj === null) {\r\n return 'null';\r\n }\r\n\r\n if (typeof obj !== 'object') {\r\n if (typeof obj === 'string') {\r\n return JSON.stringify(obj);\r\n }\r\n return String(obj);\r\n }\r\n\r\n if (obj instanceof Date) {\r\n return JSON.stringify(obj.toISOString());\r\n }\r\n\r\n if (Array.isArray(obj)) {\r\n // Mantener arrays en una línea\r\n const items = obj.map((item) => {\r\n if (item instanceof Date) {\r\n return JSON.stringify(item.toISOString());\r\n }\r\n if (typeof item === 'object' && item !== null) {\r\n return this.compactStringify(item, indent);\r\n }\r\n return typeof item === 'string'\r\n ? JSON.stringify(item)\r\n : item === null\r\n ? 'null'\r\n : String(item);\r\n });\r\n return `[${items.join(', ')}]`;\r\n }\r\n\r\n // Para objetos, mantener la indentación\r\n const keys = Object.keys(obj);\r\n if (keys.length === 0) {\r\n return '{}';\r\n }\r\n\r\n const innerIndent = indent + 2;\r\n const innerSpaces = ' '.repeat(innerIndent);\r\n const lines = keys.map((key) => {\r\n const value = obj[key];\r\n const stringified =\r\n value instanceof Date\r\n ? JSON.stringify(value.toISOString())\r\n : typeof value === 'object' && value !== null\r\n ? this.compactStringify(value, innerIndent)\r\n : typeof value === 'string'\r\n ? JSON.stringify(value)\r\n : value === null\r\n ? 'null'\r\n : String(value);\r\n return `${innerSpaces}\"${key}\": ${stringified}`;\r\n });\r\n\r\n return `{\\n${lines.join(',\\n')}\\n${spaces}}`;\r\n }\r\n\r\n transform(value: any): string {\r\n if (!value) {\r\n return '';\r\n }\r\n\r\n const json = this.compactStringify(value);\r\n // Detecta fechas ISO: \"YYYY-MM-DDTHH:MM:SS.mmmZ\"\r\n const ISO_DATE_RE = /^\"(\\d{4}-\\d{2}-\\d{2})T(\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)\"$/;\r\n\r\n // Aplica estilo y colores para diferenciar claves, valores, booleanos, números, etc.\r\n return json\r\n .replace(/&/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/(\"(\\\\u[a-zA-Z0-9]{4}|\\\\[^u]|[^\\\\\"])*\"(\\s*:)?)/g, (match) => {\r\n // Si es una clave (tiene dos puntos al final)\r\n if (/:$/.test(match)) {\r\n return `<span class=\"json-key\">${match}</span>`;\r\n }\r\n // Detectar fechas ISO (YYYY-MM-DDTHH:MM:SS.mmmZ)\r\n const isoMatch = match.match(ISO_DATE_RE);\r\n if (isoMatch) {\r\n return `<span class=\"json-string json-date\">\"<span class=\"json-date-part\">${isoMatch[1]}</span><span class=\"json-date-sep\">T</span><span class=\"json-date-time\">${isoMatch[2]}</span>\"</span>`;\r\n }\r\n // Si es un string (no tiene dos puntos)\r\n return `<span class=\"json-string\">${match}</span>`;\r\n })\r\n .replace(/\\b(true|false|null)\\b/g, (match) => {\r\n if (match === 'null') {\r\n return '<span class=\"json-null\">null</span>';\r\n }\r\n return `<span class=\"json-boolean\">${match}</span>`;\r\n })\r\n .replace(/\\b(\\d+\\.?\\d*)\\b/g, '<span class=\"json-number\">$1</span>')\r\n .replace(/[{}\\[\\]]/g, '<span class=\"json-bracket\">$&</span>')\r\n .replace(/,/g, '<span class=\"json-comma\">$&</span>')\r\n .replace(/:/g, '<span class=\"json-colon\">$&</span>');\r\n }\r\n}\r\n","import { InjectionToken, Provider } from '@angular/core';\r\n\r\n/**\r\n * Valores válidos para el tema de SweetAlert2.\r\n * Esta constante permite autocompletado y validación en tiempo de compilación.\r\n *\r\n * @example\r\n * ```typescript\r\n * // En environment.ts\r\n * export const environment: EnvironmentConfig = {\r\n * // ...otros campos\r\n * sweetAlertTheme: 'dark', // ✅ Autocompletado disponible\r\n * };\r\n * ```\r\n */\r\nexport const SWEET_ALERT_THEMES = [\r\n 'auto',\r\n 'light',\r\n 'dark',\r\n 'default',\r\n 'bootstrap-4',\r\n 'borderless',\r\n 'bulma',\r\n 'material-ui',\r\n 'minimal',\r\n 'wordpress-admin',\r\n] as const;\r\n\r\n/**\r\n * Tipo literal para los temas válidos de SweetAlert2.\r\n * Se genera automáticamente desde la constante SWEET_ALERT_THEMES.\r\n */\r\nexport type SweetAlertThemeType = (typeof SWEET_ALERT_THEMES)[number];\r\n\r\n/**\r\n * Esquema de configuración del entorno - Fuente única de verdad (Single Source of Truth)\r\n *\r\n * Este objeto define todos los campos requeridos y sus tipos esperados para la configuración del entorno.\r\n * Sirve como referencia automática para:\r\n * - Generar el tipo TypeScript `EnvironmentConfig`\r\n * - Validar la presencia de campos requeridos\r\n * - Validar los tipos de datos en runtime\r\n * - Detectar automáticamente campos que requieren validación especial (URLs)\r\n *\r\n * **Cómo agregar una nueva propiedad:**\r\n * 1. Agrégala a este objeto con su tipo: 'string', 'boolean' o 'number'\r\n * 2. Todo lo demás se actualiza automáticamente (tipo TypeScript, validaciones, etc.)\r\n *\r\n * @example\r\n * ```typescript\r\n * const ENVIRONMENT_SCHEMA = {\r\n * production: 'boolean' as const,\r\n * myAppUrl: 'string' as const,\r\n * apiTimeout: 'number' as const, // ← Agregar nueva propiedad\r\n * } as const;\r\n * ```\r\n *\r\n * @internal\r\n */\r\nconst ENVIRONMENT_SCHEMA = {\r\n production: 'boolean' as const,\r\n myAppUrl: 'string' as const,\r\n SeguridadITApiUrl: 'string' as const,\r\n tokenName: 'string' as const,\r\n tokenNameRF: 'string' as const,\r\n sessionStatus: 'string' as const,\r\n refreshTokenExpiry: 'string' as const,\r\n rolIndex: 'number' as const,\r\n} as const;\r\n\r\n/**\r\n * Tipo que define la configuración del entorno de la aplicación.\r\n *\r\n * Este tipo se genera automáticamente a partir de `ENVIRONMENT_SCHEMA` usando\r\n * TypeScript mapped types. No es necesario mantenerlo manualmente.\r\n *\r\n * **Características:**\r\n * - Se sincroniza automáticamente con ENVIRONMENT_SCHEMA\r\n * - Proporciona autocompletado en IDEs\r\n * - Garantiza type-safety en tiempo de compilación\r\n * - Se valida en runtime usando `provideEnvironment()`\r\n *\r\n * **Campos requeridos:**\r\n * @property production - Indica si la aplicación está en modo producción\r\n * @property myAppUrl - URL base de la aplicación principal (debe incluir protocolo http:// o https://)\r\n * @property SeguridadITApiUrl - URL base de la API de seguridad (debe incluir protocolo http:// o https://)\r\n * @property tokenName - Nombre del token de acceso en el almacenamiento local/sesión\r\n * @property tokenNameRF - Nombre del refresh token en el almacenamiento local/sesión\r\n * @property sessionStatus - Nombre de la clave para el estado de sesión\r\n * @property refreshTokenExpiry - Tiempo de expiración del refresh token (ej: \"7d\", \"24h\")\r\n * @property rolIndex - Índice lógico (1-based) del rol principal asociado al entorno\r\n *\r\n * **Campos opcionales:**\r\n * @property sweetAlertTheme - Tema visual global para SweetAlert2 ('auto' | 'light' | 'dark' | 'default' | 'bootstrap-4' | 'borderless' | 'bulma' | 'material-ui' | 'minimal' | 'wordpress-admin')\r\n *\r\n * @example\r\n * ```typescript\r\n * // En tu archivo environment.ts\r\n * import { EnvironmentConfig } from '@devsoftxela/ngx-dsx';\r\n *\r\n * export const environment: EnvironmentConfig = {\r\n * production: false,\r\n * myAppUrl: 'http://localhost:4200/',\r\n * SeguridadITApiUrl: 'http://localhost:5000/',\r\n * tokenName: 'access_token',\r\n * tokenNameRF: 'refresh_token',\r\n * sessionStatus: 'session_status',\r\n * refreshTokenExpiry: '7d',\r\n * sweetAlertTheme: 'dark' // ← Tema global para alertas (opcional)\r\n * };\r\n * ```\r\n */\r\nexport type EnvironmentConfig = {\r\n [K in keyof typeof ENVIRONMENT_SCHEMA]: (typeof ENVIRONMENT_SCHEMA)[K] extends 'string'\r\n ? string\r\n : (typeof ENVIRONMENT_SCHEMA)[K] extends 'boolean'\r\n ? boolean\r\n : (typeof ENVIRONMENT_SCHEMA)[K] extends 'number'\r\n ? number\r\n : never;\r\n} & {\r\n /**\r\n * Tema visual global para las alertas SweetAlert2.\r\n * Es opcional. Si no se define, se usará el tema por defecto de SweetAlert2.\r\n *\r\n * Valores válidos: 'auto' | 'light' | 'dark' | 'default' | 'bootstrap-4' |\r\n * 'borderless' | 'bulma' | 'material-ui' | 'minimal' | 'wordpress-admin'\r\n *\r\n * @example\r\n * ```typescript\r\n * sweetAlertTheme: 'dark' // Tema oscuro\r\n * sweetAlertTheme: 'minimal' // Tema minimalista\r\n * sweetAlertTheme: 'auto' // Detecta según preferencias del sistema\r\n * ```\r\n */\r\n /**\r\n * Tema visual global para las alertas SweetAlert2.\r\n *\r\n * Se define como `SweetAlertThemeType` para que TypeScript emita un error\r\n * en tiempo de compilación cuando se utilice un valor no válido.\r\n *\r\n * Si por alguna razón necesitas permitir cadenas arbitrarias (no\r\n * recomendadas), utiliza `EnvironmentConfigLenient` exportado más abajo.\r\n */\r\n sweetAlertTheme?: SweetAlertThemeType;\r\n /**\r\n * Lista de roles que se utilizan para las guardas de rutas.\r\n * Debe ser un arreglo no vacío de strings.\r\n */\r\n rolesGuards: string[];\r\n};\r\n\r\n/**\r\n * Variante leniente del tipo `EnvironmentConfig` que permite strings\r\n * arbitrarios en `sweetAlertTheme` (mantiene compatibilidad hacia atrás).\r\n *\r\n * Úsalo solo si realmente necesitas pasar valores no listados en\r\n * `SWEET_ALERT_THEMES` y entiendes que no habrá chequeo estático.\r\n */\r\nexport type EnvironmentConfigLenient = Omit<\r\n EnvironmentConfig,\r\n 'sweetAlertTheme'\r\n> & {\r\n sweetAlertTheme?: SweetAlertThemeType | (string & {});\r\n};\r\n\r\n/**\r\n * Token de inyección de dependencias para la configuración del entorno.\r\n *\r\n * Este token se utiliza para inyectar la configuración del entorno en servicios y componentes.\r\n * **IMPORTANTE:** No uses este token directamente en providers. En su lugar, usa la función\r\n * `provideEnvironment()` que incluye validación automática.\r\n *\r\n * @example\r\n * ```typescript\r\n * // ✅ Forma correcta - En tu configuración de app\r\n * import { provideEnvironment } from '@devsoftxela/ngx-dsx';\r\n * import { environment } from './environments/environment';\r\n *\r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [\r\n * provideEnvironment(environment), // ← Con validación automática\r\n * ]\r\n * };\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // ✅ Forma correcta - Inyectar en servicios\r\n * import { inject } from '@angular/core';\r\n * import { ENVIRONMENT, EnvironmentConfig } from '@devsoftxela/ngx-dsx';\r\n *\r\n * export class MiServicio {\r\n * private environment: EnvironmentConfig = inject(ENVIRONMENT);\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // ❌ Forma incorrecta - Sin validación\r\n * providers: [\r\n * { provide: ENVIRONMENT, useValue: environment } // ← Sin validación\r\n * ]\r\n * ```\r\n *\r\n * @see {@link provideEnvironment} para configurar con validación\r\n * @see {@link EnvironmentConfig} para la estructura de datos\r\n */\r\nexport const ENVIRONMENT = new InjectionToken<EnvironmentConfig>(\r\n 'EnvironmentConfig',\r\n);\r\n\r\n/**\r\n * Valida que la configuración del entorno esté completa y correctamente configurada.\r\n *\r\n * Esta función verifica que:\r\n * - La configuración del entorno no sea null o undefined\r\n * - Todas las propiedades requeridas estén presentes y no estén vacías\r\n * - Las URLs tengan un formato válido\r\n *\r\n * @param environment - Configuración del entorno a validar\r\n * @throws Error si alguna validación falla, con un mensaje descriptivo del problema\r\n *\r\n * @example\r\n * ```typescript\r\n * const config: EnvironmentConfig = { ... };\r\n * validateEnvironmentConfig(config);\r\n * ```\r\n */\r\nexport function validateEnvironmentConfig(\r\n environment: EnvironmentConfig,\r\n): void {\r\n if (!environment) {\r\n throw new Error(\r\n '[ENVIRONMENT] La configuración del entorno no está definida. ' +\r\n 'Asegúrate de proporcionar una configuración válida usando provideEnvironment().',\r\n );\r\n }\r\n\r\n // Obtener automáticamente todos los campos requeridos del schema\r\n // Usamos keyof typeof ENVIRONMENT_SCHEMA para solo validar campos del schema base\r\n const requiredFields = Object.keys(\r\n ENVIRONMENT_SCHEMA,\r\n ) as (keyof typeof ENVIRONMENT_SCHEMA)[];\r\n\r\n const missingFields: string[] = [];\r\n const emptyFields: string[] = [];\r\n const wrongTypeFields: string[] = [];\r\n\r\n // Validar que todos los campos requeridos existan, no estén vacíos y tengan el tipo correcto\r\n requiredFields.forEach((field) => {\r\n const expectedType = ENVIRONMENT_SCHEMA[field];\r\n\r\n if (!(field in environment)) {\r\n missingFields.push(field);\r\n } else if (\r\n environment[field] === null ||\r\n environment[field] === undefined\r\n ) {\r\n emptyFields.push(field);\r\n } else {\r\n // Validar tipo de dato\r\n const actualType = typeof environment[field];\r\n if (actualType !== expectedType) {\r\n wrongTypeFields.push(\r\n `${field} (esperado: ${expectedType}, recibido: ${actualType})`,\r\n );\r\n }\r\n\r\n // Validar que strings no estén vacíos\r\n if (\r\n expectedType === 'string' &&\r\n typeof environment[field] === 'string' &&\r\n (environment[field] as string).trim() === ''\r\n ) {\r\n emptyFields.push(field);\r\n }\r\n }\r\n });\r\n\r\n // Reportar campos faltantes\r\n if (missingFields.length > 0) {\r\n throw new Error(\r\n `[ENVIRONMENT] Faltan los siguientes campos en la configuración del entorno: ${missingFields.join(\r\n ', ',\r\n )}. ` + 'Por favor, verifica tu configuración de environment.',\r\n );\r\n }\r\n\r\n // Reportar campos vacíos\r\n if (emptyFields.length > 0) {\r\n throw new Error(\r\n `[ENVIRONMENT] Los siguientes campos están vacíos en la configuración del entorno: ${emptyFields.join(\r\n ', ',\r\n )}. ` + 'Por favor, proporciona valores válidos para estos campos.',\r\n );\r\n }\r\n\r\n // Reportar campos con tipo incorrecto\r\n if (wrongTypeFields.length > 0) {\r\n throw new Error(\r\n `[ENVIRONMENT] Los siguientes campos tienen un tipo de dato incorrecto: ${wrongTypeFields.join(\r\n ', ',\r\n )}. ` + 'Por favor, corrige los tipos de datos.',\r\n );\r\n }\r\n\r\n // Validar formato de URLs (solo para campos que contengan 'url' en su nombre)\r\n requiredFields.forEach((field) => {\r\n if (\r\n field.toLowerCase().includes('url') &&\r\n typeof environment[field] === 'string'\r\n ) {\r\n validateUrl(field as string, environment[field] as string);\r\n }\r\n });\r\n\r\n // Validar rolesGuards\r\n if (\r\n !Array.isArray(environment.rolesGuards) ||\r\n environment.rolesGuards.length === 0 ||\r\n !environment.rolesGuards.every(\r\n (r) => typeof r === 'string' && r.trim().length > 0,\r\n )\r\n ) {\r\n throw new Error(\r\n \"[ENVIRONMENT] El campo 'rolesGuards' debe ser un arreglo no vacío de cadenas de texto válidas.\",\r\n );\r\n }\r\n\r\n // Validar sweetAlertTheme si está definido: emitir warning y usar tema por defecto si es inválido\r\n if (\r\n environment.sweetAlertTheme !== undefined &&\r\n typeof environment.sweetAlertTheme === 'string'\r\n ) {\r\n const allowedThemes = SWEET_ALERT_THEMES as readonly string[];\r\n if (!allowedThemes.includes(environment.sweetAlertTheme)) {\r\n console.warn(\r\n `[ENVIRONMENT] Valor no reconocido para 'sweetAlertTheme': '${environment.sweetAlertTheme}'. Temas válidos: ${allowedThemes.join(\r\n ', ',\r\n )}. Se usará el tema por defecto de SweetAlert2.`,\r\n );\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Valida que una URL tenga un formato válido.\r\n * Permite tanto URLs absolutas (http://..., https://...) como rutas relativas (/, /api, etc.).\r\n *\r\n * @param fieldName - Nombre del campo para mensajes de error\r\n * @param url - URL a validar\r\n * @throws Error si la URL no tiene un formato válido\r\n */\r\nfunction validateUrl(fieldName: string, url: string): void {\r\n // Patrón para rutas relativas (comienzan con /)\r\n const relativePathPattern = /^\\/[^/]*/;\r\n\r\n // Si es una ruta relativa, solo validar que sea válida\r\n if (relativePathPattern.test(url)) {\r\n // Validar que la URL termine con '/' para evitar problemas de concatenación\r\n if (!url.endsWith('/')) {\r\n console.warn(\r\n `[ENVIRONMENT] Advertencia: El campo '${fieldName}' no termina con '/'. ` +\r\n `Valor actual: '${url}'. Se recomienda que las URLs base terminen con '/' para evitar problemas de concatenación.`,\r\n );\r\n }\r\n return; // La ruta relativa es válida\r\n }\r\n\r\n // Si no es una ruta relativa, debe ser una URL absoluta\r\n try {\r\n // Intentar crear un objeto URL para validar el formato\r\n new URL(url);\r\n } catch {\r\n // Si falla, verificar si al menos tiene un formato básico válido\r\n const urlPattern = /^https?:\\/\\/.+/;\r\n if (!urlPattern.test(url)) {\r\n throw new Error(\r\n `[ENVIRONMENT] El campo '${fieldName}' no tiene un formato de URL válido. ` +\r\n `Valor actual: '${url}'. Debe ser una URL absoluta (http://... o https://...) o una ruta relativa que comience con /`,\r\n );\r\n }\r\n }\r\n\r\n // Validar que la URL termine con '/' para evitar problemas de concatenación\r\n if (!url.endsWith('/')) {\r\n console.warn(\r\n `[ENVIRONMENT] Advertencia: El campo '${fieldName}' no termina con '/'. ` +\r\n `Valor actual: '${url}'. Se recomienda que las URLs base terminen con '/' para evitar problemas de concatenación.`,\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Proporciona una configuración de entorno validada para la inyección de dependencias.\r\n *\r\n * Esta función crea un provider que valida automáticamente la configuración del entorno\r\n * cuando la aplicación se inicializa. Si la configuración es inválida, lanza un error\r\n * descriptivo que indica qué está mal configurado.\r\n *\r\n * @param environment - Configuración del entorno a proporcionar\r\n * @returns Provider de Angular configurado con la validación integrada\r\n *\r\n * @example\r\n * ```typescript\r\n * // En app.config.ts o main.ts\r\n * import { provideEnvironment } from './path/to/environment.token';\r\n * import { environment } from './environments/environment';\r\n *\r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [\r\n * provideEnvironment(environment),\r\n * // ... otros providers\r\n * ]\r\n * };\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Para módulos (NgModule)\r\n * import { provideEnvironment } from './path/to/environment.token';\r\n * import { environment } from './environments/environment';\r\n *\r\n * @NgModule({\r\n * providers: [\r\n * provideEnvironment(environment),\r\n * // ... otros providers\r\n * ]\r\n * })\r\n * export class AppModule { }\r\n * ```\r\n */\r\nexport function provideEnvironment(environment: EnvironmentConfig): Provider {\r\n return {\r\n provide: ENVIRONMENT,\r\n useFactory: () => {\r\n // Validar la configuración al momento de la inyección\r\n validateEnvironmentConfig(environment);\r\n return environment;\r\n },\r\n };\r\n}\r\n","import {\r\n Component,\r\n ViewEncapsulation,\r\n inject,\r\n Input,\r\n signal,\r\n} from '@angular/core';\r\nimport { FormGroup } from '@angular/forms';\r\nimport { JsonHighlightPipe } from '../../../pipe/src/json-highlight.pipe';\r\nimport {\r\n ENVIRONMENT,\r\n EnvironmentConfig,\r\n} from '../../../injections/environment.token';\r\n\r\n@Component({\r\n selector: 'app-json-values-debuj',\r\n imports: [JsonHighlightPipe],\r\n templateUrl: './json-values-debuj.component.html',\r\n styleUrl: './json-values-debuj.component.css',\r\n /**\r\n * Usamos ViewEncapsulation.None para que los estilos .json-* definidos en el CSS\r\n * apliquen también al HTML generado dinámicamente por [innerHTML] en el <pre>.\r\n *\r\n * Con la encapsulación por defecto (Emulated), Angular añade atributos tipo\r\n * _ngcontent-xxx a los elementos del template, pero el contenido insertado vía\r\n * [innerHTML] NO lleva esos atributos, por lo que las reglas scoped no coinciden\r\n * y el resaltado de sintaxis (json-key, json-string, etc.) no se ve.\r\n *\r\n * Al usar ViewEncapsulation.None, las clases .json-* se vuelven globales dentro\r\n * de la app (y de los proyectos que consumen la librería), permitiendo que el\r\n * pipe JsonHighlight pinte correctamente el JSON para depuración.\r\n */\r\n encapsulation: ViewEncapsulation.None,\r\n})\r\nexport class JsonValuesDebujComponent {\r\n @Input() form!: FormGroup;\r\n // Inyecta la configuración del entorno usando el token ENVIRONMENT\r\n private environment: EnvironmentConfig = inject(ENVIRONMENT);\r\n // Señal reactiva para indicar si estamos en modo de desarrollo\r\n private readonly isDevSignal = signal<boolean>(!this.environment.production);\r\n\r\n // Método para verificar el estado de desarrollo\r\n isDev(): boolean {\r\n return this.isDevSignal();\r\n }\r\n}\r\n","@if (isDev()) {\r\n <span class=\"debug-title\">Development mode</span>\r\n <div class=\"custom-container\">\r\n <pre\r\n class=\"custom-pre\"\r\n [innerHTML]=\"form.getRawValue() | jsonHighlight\"\r\n ></pre>\r\n </div>\r\n}\r\n","import { Injectable, signal } from '@angular/core';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\n/**\r\n * Servicio centralizado para controlar el estado de carga global.\r\n *\r\n * Expone una señal (`spinnerVisible`) que puede consumirse en componentes\r\n * para mostrar u ocultar un spinner.\r\n *\r\n * Uso recomendado:\r\n * - `show()` / `hide()` para flujos con múltiples operaciones concurrentes.\r\n * - `showImmediate()` para feedback visual inmediato (sin afectar contador).\r\n * - `reset()` para recuperar estado en errores inesperados.\r\n */\r\nexport class SpinnerLoadingService {\r\n /**\r\n * Señal reactiva que indica si el spinner debe mostrarse.\r\n *\r\n * Ejemplo:\r\n * ```ts\r\n * readonly isLoading = this.spinnerLoadingService.spinnerVisible;\r\n * ```\r\n */\r\n spinnerVisible = signal(false);\r\n\r\n /**\r\n * Contador interno de operaciones activas.\r\n * Permite que el spinner permanezca visible mientras haya procesos en curso.\r\n */\r\n private counter = 0;\r\n\r\n constructor() {}\r\n\r\n /**\r\n * Incrementa el contador de cargas activas.\r\n *\r\n * Muestra el spinner solo en la transición de `0 -> 1` para evitar\r\n * renderizados redundantes cuando hay varias operaciones simultáneas.\r\n *\r\n * Cuándo usarlo:\r\n * - Antes de iniciar una petición HTTP manual.\r\n * - Antes de ejecutar una acción asíncrona larga.\r\n */\r\n show(): void {\r\n this.counter++;\r\n if (this.counter === 1) {\r\n this.spinnerVisible.set(true);\r\n }\r\n }\r\n\r\n /**\r\n * Muestra el spinner de forma inmediata sin modificar el contador.\r\n *\r\n * Cuándo usarlo:\r\n * - Para feedback instantáneo en la UI (por ejemplo, al hacer clic en un botón).\r\n * - Cuando otro mecanismo (ejemplo: interceptor HTTP) controlará `show()`/`hide()`.\r\n */\r\n showImmediate(): void {\r\n this.spinnerVisible.set(true);\r\n }\r\n\r\n /**\r\n * Decrementa el contador de cargas activas.\r\n *\r\n * Oculta el spinner únicamente cuando el contador llega a `0`.\r\n * Si se llama más veces de las debidas, el contador no baja de `0`.\r\n *\r\n * Cuándo usarlo:\r\n * - Al finalizar una operación iniciada con `show()`.\r\n */\r\n hide(): void {\r\n if (this.counter > 0) {\r\n this.counter--;\r\n }\r\n\r\n if (this.counter === 0) {\r\n this.spinnerVisible.set(false);\r\n }\r\n }\r\n\r\n /**\r\n * Restablece el estado del servicio a su valor inicial.\r\n *\r\n * Fuerza `counter = 0` y oculta el spinner.\r\n * Útil en escenarios de recuperación por error o al reinicializar contexto.\r\n */\r\n reset(): void {\r\n this.counter = 0;\r\n this.spinnerVisible.set(false);\r\n }\r\n}\r\n","import { AfterViewInit, Component, ElementRef, viewChild } from '@angular/core';\r\nimport { createTimeline } from 'animejs';\r\n\r\n@Component({\r\n selector: 'app-logo-dsx',\r\n imports: [],\r\n templateUrl: './logo-dsx.component.html',\r\n styleUrl: './logo-dsx.component.css',\r\n})\r\nexport class LogoDsxComponent implements AfterViewInit {\r\n logo = viewChild.required<ElementRef>('logo');\r\n hexagon = viewChild.required<ElementRef>('logoHexagon');\r\n circle = viewChild.required<ElementRef>('logoCircle');\r\n mask = viewChild.required<ElementRef>('logoMask');\r\n text = viewChild.required<ElementRef>('logoText');\r\n currentYear: number;\r\n\r\n constructor() {\r\n this.currentYear = new Date().getFullYear(); // Asigna el año actual\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n createTimeline({\r\n autoplay: true,\r\n delay: 90,\r\n })\r\n .add(this.logo().nativeElement, {\r\n translateY: [-100, 0],\r\n opacity: [0, 1],\r\n duration: 420,\r\n easing: 'outCubic',\r\n })\r\n .add(\r\n this.hexagon().nativeElement,\r\n {\r\n rotate: [-54, 0],\r\n duration: 220,\r\n easing: 'outBack',\r\n },\r\n 60,\r\n )\r\n .add(\r\n this.circle().nativeElement,\r\n {\r\n scale: [0, 1],\r\n duration: 320,\r\n easing: 'outElastic(amplitude = 1, period = .2)',\r\n },\r\n 150,\r\n )\r\n .add(\r\n this.mask().nativeElement,\r\n {\r\n scale: [0, 1],\r\n duration: 300,\r\n easing: 'outElastic(amplitude = 1, period = .2)',\r\n },\r\n 170,\r\n )\r\n .add(\r\n this.text().nativeElement,\r\n {\r\n translateX: ['-60%', 0],\r\n opacity: [0, 1],\r\n duration: 380,\r\n easing: 'outExpo',\r\n },\r\n 650,\r\n )\r\n .add(\r\n this.logo().nativeElement,\r\n {\r\n translateY: -8,\r\n duration: 70,\r\n easing: 'outQuad',\r\n },\r\n 420,\r\n )\r\n .add(\r\n this.logo().nativeElement,\r\n {\r\n translateY: 0,\r\n duration: 150,\r\n easing: 'outBounce',\r\n },\r\n 490,\r\n );\r\n }\r\n}\r\n","<div class=\"site-logo\">\r\n <figure #logo>\r\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 148 128\">\r\n <defs>\r\n <linearGradient id=\"logo-gradient\" x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\">\r\n <stop offset=\"0%\" stop-color=\"#00ffff\" />\r\n <stop offset=\"100%\" stop-color=\"#ff00ff\" />\r\n </linearGradient>\r\n <linearGradient\r\n id=\"circle-gradient\"\r\n x1=\"0%\"\r\n y1=\"100%\"\r\n x2=\"100%\"\r\n y2=\"0%\"\r\n >\r\n <stop offset=\"0%\" stop-color=\"#ff00ff\" />\r\n <stop offset=\"100%\" stop-color=\"#00ffff\" />\r\n </linearGradient>\r\n <mask id=\"circle-mask\">\r\n <rect fill=\"white\" width=\"100%\" height=\"100%\"></rect>\r\n <circle\r\n #logoMask\r\n id=\"logo-mask\"\r\n fill=\"black\"\r\n cx=\"120\"\r\n cy=\"96\"\r\n r=\"28\"\r\n ></circle>\r\n </mask>\r\n </defs>\r\n <polygon\r\n #logoHexagon\r\n id=\"logo-hexagon\"\r\n fill=\"#475569\"\r\n stroke=\"#9ca3af\"\r\n stroke-width=\"2\"\r\n stroke-linejoin=\"round\"\r\n points=\"64 128 8.574 96 8.574 32 64 0 119.426 32 119.426 96\"\r\n mask=\"url(#circle-mask)\"\r\n ></polygon>\r\n <circle #logoCircle fill=\"#16a34a\" cx=\"120\" cy=\"96\" r=\"20\"></circle>\r\n </svg>\r\n </figure>\r\n <div class=\"site-title\">\r\n <div #logoText class=\"site-title-text\">\r\n DEV<span\r\n >SOFTXela<span style=\"font-size: small; vertical-align: super\"\r\n >&copy;</span\r\n >\r\n {{ currentYear }}</span\r\n >\r\n </div>\r\n </div>\r\n</div>\r\n","import { Component, effect, inject, input } from '@angular/core';\r\nimport { SpinnerLoadingService } from '../../services/src/spinner-loading.service';\r\nimport { AnimationOptions, LottieComponent } from 'ngx-lottie';\r\nimport { LogoDsxComponent } from '../logo/logo-dsx/logo-dsx.component';\r\n\r\n@Component({\r\n selector: 'app-loading-lottie',\r\n imports: [LottieComponent, LogoDsxComponent],\r\n templateUrl: './loading-lottie.component.html',\r\n styleUrl: './loading-lottie.component.css',\r\n})\r\nexport class LoadingLottieComponent {\r\n // Accedemos directamente a la señal del servicio\r\n _spinnerService = inject(SpinnerLoadingService);\r\n currentYear: number;\r\n jsonUrl = input<string>('Loader_Liquid4');\r\n size = input<string>('250px');\r\n options: AnimationOptions = { path: '' };\r\n\r\n constructor() {\r\n this.currentYear = new Date().getFullYear(); // Asigna el año actual\r\n effect(() => {\r\n this.options = {\r\n path: `jsonlottie/${this.jsonUrl() + '.json'}`,\r\n };\r\n });\r\n }\r\n}\r\n","@if (_spinnerService.spinnerVisible()) {\r\n <div class=\"loader-container\">\r\n <ng-lottie\r\n [options]=\"options\"\r\n [width]=\"size()\"\r\n [height]=\"size()\"\r\n ></ng-lottie>\r\n <!-- <p class=\"loading-text\">&copy;DevsoftXela {{ currentYear }}</p> -->\r\n <app-logo-dsx></app-logo-dsx>\r\n </div>\r\n}\r\n","import { Component, inject } from '@angular/core';\r\nimport { SpinnerLoadingService } from '../../../services/src/spinner-loading.service';\r\n\r\n@Component({\r\n selector: 'app-loading-v2',\r\n imports: [],\r\n templateUrl: './css-v2.component.html',\r\n styleUrl: './css-v2.component.css',\r\n})\r\nexport class CssV2Component {\r\n _spinnerService = inject(SpinnerLoadingService);\r\n}\r\n","@if(_spinnerService.spinnerVisible()){\r\n<div class=\"spinner-overlay\">\r\n <div class=\"spinner-container\">\r\n <div class=\"center_div\">\r\n <div class=\"wave\"></div>\r\n <div class=\"wave\"></div>\r\n <div class=\"wave\"></div>\r\n <div class=\"wave\"></div>\r\n <div class=\"wave\"></div>\r\n <div class=\"wave\"></div>\r\n <div class=\"wave\"></div>\r\n </div>\r\n <p class=\"loading-text\">Cargando...</p>\r\n </div>\r\n</div>\r\n}\r\n","import { Component, inject } from '@angular/core';\r\nimport { SpinnerLoadingService } from '../../services/src/spinner-loading.service';\r\n\r\n@Component({\r\n selector: 'app-loading',\r\n imports: [],\r\n templateUrl: './loading.component.html',\r\n styleUrl: './loading.component.css',\r\n})\r\nexport class LoadingComponent {\r\n // Accedemos directamente a la señal del servicio\r\n _spinnerService = inject(SpinnerLoadingService);\r\n currentYear: number;\r\n\r\n constructor() {\r\n this.currentYear = new Date().getFullYear(); // Asigna el año actual\r\n }\r\n}\r\n","<!-- Actualización 2025-31-01 12:00 -->\r\n@if(_spinnerService.spinnerVisible()){\r\n<div class=\"spinner-overlay\">\r\n <div class=\"loader\">\r\n <div class=\"external-shadow\">\r\n <div class=\"central\"></div>\r\n </div>\r\n <img src=\"/icon/secure.png\" class=\"spinner-image\" />\r\n </div>\r\n <p class=\"loading-text\">&copy;DevsoftXela {{ currentYear }}</p>\r\n</div>\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { ToastrService } from 'ngx-toastr';\r\nimport Swal, {\r\n SweetAlertIcon,\r\n SweetAlertOptions,\r\n SweetAlertResult,\r\n SweetAlertTheme,\r\n} from 'sweetalert2';\r\nimport {\r\n ENVIRONMENT,\r\n SWEET_ALERT_THEMES,\r\n} from '../../injections/environment.token';\r\nimport { ResponseHttpModel } from '../../models/src/response-http.model';\r\n\r\n/**\r\n * Opciones configurables para personalizar el comportamiento y apariencia de las alertas visuales.\r\n *\r\n * Permite definir iconos, imágenes, botones, temporizadores y temas para las alertas SweetAlert2.\r\n *\r\n * @property icono - Nombre del archivo de imagen ubicado en 'assets/dsxResource/'. Ejemplo: 'success-icon.png'. Por defecto: 'icon/check02.png'.\r\n * @property icon - Tipo de icono SweetAlert2 ('success' | 'error' | 'warning' | 'info' | 'question'). Opcional.\r\n * @property showConfirmButton - Si es true, muestra el botón de confirmación y desactiva el cierre automático. Por defecto: false.\r\n * @property confirmButtonText - Texto personalizado para el botón de confirmación. Por defecto: 'Ok'.\r\n * @property timer - Tiempo en milisegundos para el cierre automático de la alerta. Ignorado si showConfirmButton es true. Por defecto: 2000.\r\n * @property imageWidth - Ancho en píxeles de la imagen personalizada. Por defecto: 125.\r\n * @property imageHeight - Alto en píxeles de la imagen personalizada. Por defecto: 125.\r\n * @property showImage - Si es true, muestra la imagen personalizada; si es false, solo el icono SweetAlert2. Por defecto: true.\r\n * @property theme - Tema visual de SweetAlert2 (por ejemplo, 'dark', 'minimal', etc). Opcional.\r\n *\r\n * @example\r\n * // Alerta con icono personalizado y cierre automático\r\n * const options: AlertOptions = {\r\n * icono: 'custom-icon.png',\r\n * icon: 'warning',\r\n * timer: 3000\r\n * };\r\n *\r\n * @example\r\n * // Alerta de confirmación con botón y sin imagen\r\n * const confirmOptions: AlertOptions = {\r\n * showConfirmButton: true,\r\n * confirmButtonText: 'Aceptar',\r\n * showImage: false\r\n * };\r\n */\r\ninterface AlertOptions {\r\n icono?: string;\r\n icon?: SweetAlertIcon;\r\n showConfirmButton?: boolean;\r\n confirmButtonText?: string;\r\n timer?: number;\r\n imageWidth?: number;\r\n imageHeight?: number;\r\n showImage?: boolean;\r\n theme?: SweetAlertTheme;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class AlertaService {\r\n private toastrService = inject(ToastrService);\r\n\r\n /**\r\n * Configuración del entorno inyectada (opcional).\r\n * Se usa para obtener el tema global de SweetAlert2 desde el environment.\r\n */\r\n private environment = inject(ENVIRONMENT, { optional: true });\r\n\r\n /**\r\n * Tema visual por defecto para todas las alertas SweetAlert2.\r\n * Se inicializa desde el environment si está configurado, o puede establecerse\r\n * manualmente llamando a setDefaultTheme().\r\n *\r\n * **Prioridad de temas:**\r\n * 1. Tema específico pasado en options de cada alerta\r\n * 2. Tema establecido con setDefaultTheme()\r\n * 3. Tema configurado en environment.sweetAlertTheme\r\n * 4. Tema por defecto de SweetAlert2\r\n */\r\n private defaultTheme: SweetAlertTheme | undefined = undefined;\r\n\r\n constructor() {\r\n // Inicializar el tema desde el environment si está disponible\r\n if (this.environment?.sweetAlertTheme) {\r\n const allowed = SWEET_ALERT_THEMES as readonly string[];\r\n const themeValue = this.environment.sweetAlertTheme;\r\n if (typeof themeValue === 'string' && !allowed.includes(themeValue)) {\r\n console.warn(\r\n `[AlertaService] Tema de SweetAlert2 inválido: '${themeValue}'. Se utilizará el tema por defecto.`,\r\n );\r\n } else {\r\n this.defaultTheme = themeValue as SweetAlertTheme;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Permite establecer el theme global para todas las alertas SweetAlert2.\r\n * Este tema sobrescribe el configurado en el environment.\r\n *\r\n * @param theme - Valor de theme válido para SweetAlert2 (por ejemplo: 'dark', 'minimal', etc).\r\n *\r\n * @example\r\n * ```typescript\r\n * // Cambiar el tema en tiempo de ejecución\r\n * alertaService.setDefaultTheme('dark');\r\n * ```\r\n */\r\n setDefaultTheme(theme: SweetAlertTheme) {\r\n this.defaultTheme = theme;\r\n }\r\n\r\n /**\r\n * Obtiene el tema actual configurado para SweetAlert2.\r\n * @returns El tema actual o undefined si no hay tema configurado.\r\n */\r\n getDefaultTheme(): SweetAlertTheme | undefined {\r\n return this.defaultTheme;\r\n }\r\n\r\n /**\r\n * @param {number} toastrType - 1. Success 2. Info 3. Warning 4. Error\r\n * @param {string} toastrTitle - Titulo de la alerta\r\n * @param {string} toastrMessage - Mensaje de la alerta\r\n * @param {number} toastrAlign - Alineación de la alerta, por defecto 1. OPCIONES: 0. top-left 1. top-center 2. top-right 3. bottom-left 4. bottom-center 5. bottom-right\r\n * @param {number} toastrTimer - Tiempo de la alerta default 3000\r\n * @returns - Retonar una alerta toastr\r\n * */\r\n\r\n toastrAlerts(\r\n toastrType: number,\r\n toastrTitle: string,\r\n toastrMessage: string,\r\n toastrAlign: number = 1,\r\n toastrTimer: number = 3000,\r\n ) {\r\n const alignMessage = [\r\n { id: 0, align: 'toast-top-left' },\r\n { id: 1, align: 'toast-top-center' },\r\n { id: 2, align: 'toast-top-right' },\r\n { id: 3, align: 'toast-bottom-left' },\r\n { id: 4, align: 'toast-bottom-center' },\r\n { id: 5, align: 'toast-bottom-right' },\r\n ];\r\n\r\n const valueAlign: string | undefined = alignMessage.find(\r\n (c) => c.id == toastrAlign,\r\n )?.align;\r\n\r\n const toastrMethods: {\r\n [key: number]: (message: string, title?: string, options?: any) => void;\r\n } = {\r\n 1: this.toastrService.success.bind(this.toastrService),\r\n 2: this.toastrService.info.bind(this.toastrService),\r\n 3: this.toastrService.warning.bind(this.toastrService),\r\n 4: this.toastrService.error.bind(this.toastrService),\r\n };\r\n\r\n const showToast = toastrMethods[toastrType];\r\n\r\n if (showToast) {\r\n showToast(toastrMessage, toastrTitle, {\r\n enableHtml: true,\r\n closeButton: true,\r\n progressBar: true,\r\n positionClass: valueAlign,\r\n timeOut: toastrTimer,\r\n });\r\n }\r\n }\r\n\r\n private preloadImage(icono: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const img = new Image();\r\n img.src = `/${icono}`;\r\n img.onload = () => resolve();\r\n img.onerror = (err) => reject(err);\r\n });\r\n }\r\n\r\n /**\r\n * Muestra un diálogo de confirmación con SweetAlert2, espera la respuesta del usuario\r\n * y retorna `true` si confirmó o `false` si canceló/cerró.\r\n *\r\n * La imagen se precarga antes de mostrar el diálogo para evitar un parpadeo visual.\r\n *\r\n * @param title - Título principal del diálogo.\r\n * @param text - Cuerpo del mensaje; admite HTML (se inyecta como `html`).\r\n * @param icono - Ruta relativa de la imagen dentro de `assets/dsxResource/`.\r\n * Por defecto: `'icon2/garbage_make_empty_001.png'`.\r\n * @returns `Promise<boolean>` que resuelve en `true` si el usuario pulsó **Aceptar**,\r\n * o en `false` si pulsó **Cancelar** o cerró el diálogo.\r\n *\r\n * @example\r\n * // Uso con icono por defecto (papelera)\r\n * const confirmado = await this.alertaService.alertConfirm(\r\n * 'Eliminar',\r\n * 'Desea <strong>eliminar</strong> este registro?',\r\n * );\r\n *\r\n * @example\r\n * // Sobreescribir el icono pasando la ruta como tercer argumento\r\n * // La ruta es relativa a assets/dsxResource/\r\n * const confirmado = await this.alertaService.alertConfirm(\r\n * 'Archivar',\r\n * 'Desea <strong>archivar</strong> este registro?',\r\n * 'icon2/archive_001.png', // ← icono personalizado\r\n * );\r\n */\r\n alertConfirm(\r\n title: string,\r\n text: string,\r\n icono: string = 'icon2/garbage_make_empty_001.png',\r\n ): Promise<boolean> {\r\n return this.preloadImage(icono).then(() =>\r\n Swal.fire({\r\n title: title,\r\n html: text,\r\n footer: `<strong>DEVSoftXela</strong> ${new Date().getFullYear()}`,\r\n imageUrl: `/${icono}`,\r\n imageWidth: 150,\r\n imageHeight: 150,\r\n imageAlt: 'icon',\r\n showCloseButton: true,\r\n showCancelButton: true,\r\n confirmButtonColor: '#3085d6',\r\n cancelButtonColor: '#d33',\r\n confirmButtonText: `<i class=\"fa fa-thumbs-up\"></i> Aceptar!`,\r\n cancelButtonText: `<i class=\"fa fa-thumbs-down\"></i> Cancelar`,\r\n }).then((result) => result.isConfirmed),\r\n );\r\n }\r\n\r\n /**\r\n * Muestra una alerta de confirmación estándar para guardar o actualizar un registro.\r\n *\r\n * @param isNew - Indica si se trata de un nuevo registro (true = \"Salvar\", false = \"Actualizar\").\r\n * @returns Promise<boolean> que indica si el usuario confirmó la acción.\r\n */\r\n alertConfirmSaveOrUpdate(isNew: boolean): Promise<boolean> {\r\n const title = isNew ? 'Salvar' : 'Actualizar';\r\n const text = 'Desea <strong>guardar</strong> el registro?';\r\n const icono = 'icon2/save_2029637.png';\r\n return this.alertConfirm(title, text, icono);\r\n }\r\n\r\n /**\r\n * Variante de alerta de confirmación que recibe el id numérico del registro.\r\n *\r\n * Internamente evalúa si el registro es nuevo (`id === 0`) y delega en\r\n * alertConfirmSaveOrUpdate(isNew: boolean) para mostrar el mensaje.\r\n *\r\n * @param id - Identificador del registro. Se considera nuevo cuando `id === 0`.\r\n * @returns Promise<boolean> que indica si el usuario confirmó la acción.\r\n */\r\n alertConfirmSaveOrUpdateById(id: number): Promise<boolean> {\r\n const isNew = id === 0;\r\n return this.alertConfirmSaveOrUpdate(isNew);\r\n }\r\n\r\n /**\r\n * Muestra una alerta de confirmación estándar para eliminar, borrar (soft delete) o restaurar un registro.\r\n *\r\n * - Si se pasa un objeto con la propiedad `activo === false`, el mensaje se personaliza para \"Restaurar\".\r\n * - Si `activo` es true o no se envía, el comportamiento es el mismo de antes (Eliminar/Borrar según `softDelete`).\r\n *\r\n * @param softDelete - Si es true se muestra mensaje de borrado lógico, si es false eliminación definitiva.\r\n * @param data - Objeto opcional que puede incluir la propiedad `activo`. Si `activo === false` se mostrará un mensaje de restaurar.\r\n * @returns Promise<boolean> que indica si el usuario confirmó la acción.\r\n */\r\n alertConfirmDelete(\r\n softDelete: boolean,\r\n data?: { activo?: boolean },\r\n ): Promise<boolean> {\r\n const isActive = data?.activo; // true | false | undefined\r\n const isRestore = isActive === false; // solo si viene explícitamente en false\r\n\r\n const title = isRestore ? 'Restaurar' : 'Eliminar';\r\n\r\n const text = isRestore\r\n ? 'Desea <strong>restaurar</strong> el registro?'\r\n : softDelete\r\n ? 'Desea <strong>borrar</strong> el registro?'\r\n : 'Desea <strong>eliminar definitivmente</strong> el registro?';\r\n\r\n const icono = isRestore\r\n ? 'icon2/garbage_make_empty.png' // puedes usar otro icono de restaurar\r\n : softDelete\r\n ? 'icon2/recycle-bin_16854652.png'\r\n : 'icon2/delete2.png';\r\n\r\n return this.alertConfirm(title, text, icono);\r\n }\r\n\r\n alertaHtml(\r\n titleAlert: string,\r\n message: string,\r\n icono: string = 'icon/notFound01.png',\r\n timer: number = 3500,\r\n ): Promise<void> {\r\n return this.preloadImage(icono).then(() => {\r\n Swal.fire({\r\n title: titleAlert,\r\n imageUrl: `/${icono}`,\r\n imageWidth: 145,\r\n imageHeight: 125,\r\n imageAlt: 'error 404',\r\n html: `\r\n <strong>ALERTA: </strong><i>${message}</i> <span> comuniquese con el administrador. </span>\r\n `,\r\n showConfirmButton: false,\r\n timerProgressBar: true,\r\n timer: timer,\r\n });\r\n return;\r\n });\r\n }\r\n\r\n /**\r\n * Muestra una alerta visual personalizada usando SweetAlert2.\r\n *\r\n * Permite configurar el mensaje, el título, el icono, la imagen, el botón de confirmación,\r\n * el temporizador y el tema visual, entre otras opciones.\r\n *\r\n * @param titleAlert - Título principal de la alerta (obligatorio).\r\n * @param messageHtml - Mensaje en formato HTML (obligatorio).\r\n * @param options - Opciones configurables de la alerta (opcional). Permite personalizar icono, imagen, botón, temporizador, etc.\r\n * @returns Promise<SweetAlertResult> que se resuelve cuando el usuario interactúa con la alerta o cuando se cierra automáticamente.\r\n *\r\n * @example\r\n * // Alerta básica con icono de éxito y cierre automático\r\n * alertaHtmlSuccess('Operación exitosa', 'Los datos se guardaron correctamente');\r\n *\r\n * @example\r\n * // Alerta de error con imagen personalizada y temporizador\r\n * alertaHtmlSuccess('Error crítico', 'No se pudo conectar al servidor', {\r\n * icono: 'error-icon.png',\r\n * icon: 'error',\r\n * timer: 5000\r\n * });\r\n *\r\n * @example\r\n * // Alerta de confirmación con botón personalizado y sin imagen\r\n * alertaHtmlSuccess('Confirmar acción', '¿Está seguro de eliminar este registro?', {\r\n * showConfirmButton: true,\r\n * confirmButtonText: 'Sí, eliminar',\r\n * icon: 'warning',\r\n * showImage: false\r\n * }).then((result) => {\r\n * if (result.isConfirmed) {\r\n * // Lógica cuando el usuario confirma\r\n * }\r\n * });\r\n */\r\n alertaHtmlSuccess(\r\n titleAlert: string,\r\n messageHtml: string,\r\n options: AlertOptions = {},\r\n ): Promise<SweetAlertResult> {\r\n const {\r\n icono = 'icon/check02.png',\r\n icon,\r\n showConfirmButton = false,\r\n confirmButtonText = 'Ok',\r\n timer = 2000,\r\n imageWidth = 125,\r\n imageHeight = 125,\r\n showImage = true,\r\n theme, // Puede venir por options o usar el global\r\n } = options;\r\n\r\n /**\r\n * Nota importante:\r\n * Para que el parámetro `theme` funcione correctamente, el proyecto que\r\n * consume esta librería debe importar el CSS del tema de SweetAlert2 en\r\n * sus estilos (por ejemplo en `styles.scss` o en `angular.json` -> \"styles\").\r\n * Si no se importa el CSS correspondiente al tema seleccionado, las\r\n * alertas no aplicarán el estilo del tema y se verán con el estilo por\r\n * defecto de SweetAlert2.\r\n */\r\n\r\n // Usa el theme global si no se especifica uno en options\r\n const alertTheme = theme !== undefined ? theme : this.defaultTheme;\r\n\r\n // Configuración base de SweetAlert\r\n const alertConfig: SweetAlertOptions = {\r\n title: titleAlert,\r\n html: messageHtml,\r\n draggable: true,\r\n showConfirmButton,\r\n confirmButtonText,\r\n timer: showConfirmButton ? undefined : timer, // Timer solo si no hay botón\r\n timerProgressBar: !showConfirmButton && timer > 0,\r\n imageUrl: showImage && icono ? `/${icono}` : undefined,\r\n imageWidth: showImage ? imageWidth : undefined,\r\n imageHeight: showImage ? imageHeight : undefined,\r\n imageAlt: showImage ? 'image alert' : undefined,\r\n // Aplica el theme global o el específico (cast a SweetAlertTheme para compatibilidad)\r\n ...(alertTheme !== undefined && { theme: alertTheme as SweetAlertTheme }),\r\n };\r\n // Solo agrega el icono si está definido\r\n if (icon !== undefined) {\r\n alertConfig.icon = icon;\r\n }\r\n\r\n // Precargar imagen solo si es necesario\r\n if (showImage && icono) {\r\n return this.preloadImage(icono).then(() => Swal.fire(alertConfig));\r\n }\r\n\r\n return Swal.fire(alertConfig);\r\n }\r\n\r\n // private configureTimer(\r\n // config: SweetAlertOptions,\r\n // showConfirmButton: boolean,\r\n // timer: number\r\n // ) {\r\n // if (!showConfirmButton && timer > 0) {\r\n // config.timer = timer;\r\n // config.timerProgressBar = true;\r\n // }\r\n // }\r\n\r\n // No se puede utilizar por conflicto con primeng\r\n // notyfAlert(message: string) {\r\n // this.notyf.success({\r\n // message: message,\r\n // duration: 1500,\r\n // position: {\r\n // x: 'center',\r\n // y: 'top',\r\n // },\r\n // });\r\n // }\r\n\r\n toastrHttpResponse(response: ResponseHttpModel) {\r\n const time = 3000;\r\n const align = 'toast-top-center';\r\n if (response.isSuccess) {\r\n this.toastrService.success(response.statusMessage, response.title, {\r\n enableHtml: true,\r\n closeButton: true,\r\n progressBar: true,\r\n positionClass: align,\r\n timeOut: time,\r\n });\r\n } else {\r\n this.toastrService.error(response.statusMessage, response.title, {\r\n enableHtml: true,\r\n closeButton: true,\r\n progressBar: true,\r\n positionClass: align,\r\n timeOut: time,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Muestra un mensaje tipo toast usando PrimeNG MessageService.\r\n *\r\n * @param severity - Tipo de severidad del mensaje. Valores posibles:\r\n * 'success' | 'info' | 'warn' | 'error' | 'contrast' | 'secondary'.\r\n * Por defecto: 'success'.\r\n * @param title - Título del mensaje (aparece como summary).\r\n * @param message - Detalle del mensaje (aparece como detail).\r\n * @param time - Duración en milisegundos que el mensaje estará visible. Por defecto: 1500 ms.\r\n *\r\n * @example\r\n * // Mensaje de éxito\r\n * alertaService.showPrimeMessage('success', 'Operación exitosa', 'El registro fue guardado correctamente');\r\n *\r\n * @example\r\n * // Mensaje de advertencia personalizado\r\n * alertaService.showPrimeMessage('warn', 'Advertencia', 'Faltan campos obligatorios', 3000);\r\n */\r\n // showPrimeMessage(\r\n // title: string,\r\n // message: string,\r\n // severity:\r\n // | 'success'\r\n // | 'info'\r\n // | 'warn'\r\n // | 'error'\r\n // | 'contrast'\r\n // | 'secondary' = 'success',\r\n // time: number = 1500\r\n // ) {\r\n // this.primeMessageService.add({\r\n // severity: severity,\r\n // summary: title,\r\n // detail: message,\r\n // life: time,\r\n // });\r\n // }\r\n}\r\n","import { EnvironmentConfig } from '../../injections/environment.token';\r\n\r\n/**\r\n * Configuración base de entorno para la aplicación.\r\n *\r\n * Este tipo es un alias de {@link EnvironmentConfig} para usarlo en el\r\n * contexto de modelos de la librería (por ejemplo, para defaults de dev/prod).\r\n *\r\n * De esta forma, cualquier cambio en ENVIRONMENT_SCHEMA / EnvironmentConfig\r\n * se propaga automáticamente aquí y se evita la desincronización entre\r\n * definiciones.\r\n */\r\nexport interface AppEnvironment extends EnvironmentConfig {}\r\n\r\n/**\r\n * Configuración base que provee la librería para entornos de desarrollo.\r\n *\r\n * Se omiten `myAppUrl` y `rolIndex` porque normalmente dependen de cada\r\n * aplicación cliente. Esos campos se vuelven obligatorios al combinar este\r\n * tipo con {@link DevEnvironmentComplete} en el proyecto que consume.\r\n */\r\nexport type DevEnvironmentDefaults = Omit<\r\n AppEnvironment,\r\n 'myAppUrl' | 'rolIndex'\r\n>;\r\n\r\n/**\r\n * Configuración base que provee la librería para entornos de producción.\r\n *\r\n * Se omite únicamente `rolIndex`, que debe ser definido por cada\r\n * aplicación cliente. En el proyecto consumidor se recomienda usar\r\n * {@link ProdEnvironmentComplete} para forzar ese campo como requerido.\r\n */\r\nexport type ProdEnvironmentDefaults = Omit<AppEnvironment, 'rolIndex'>;\r\n\r\n/**\r\n * Tipo recomendado para el `environment` de desarrollo en las aplicaciones\r\n * que consumen la librería.\r\n *\r\n * Combina los valores por defecto de la librería con los campos que cada\r\n * app debe completar: `myAppUrl` y `rolIndex`.\r\n */\r\nexport type DevEnvironmentComplete = DevEnvironmentDefaults &\r\n Pick<AppEnvironment, 'myAppUrl' | 'rolIndex'>;\r\n\r\n/**\r\n * Tipo recomendado para el `environment` de producción en las aplicaciones\r\n * que consumen la librería.\r\n *\r\n * Combina los valores por defecto de la librería con el campo obligatorio\r\n * `rolIndex` que aporta cada aplicación cliente.\r\n */\r\nexport type ProdEnvironmentComplete = ProdEnvironmentDefaults &\r\n Pick<AppEnvironment, 'rolIndex'>;\r\n\r\n/**\r\n * Entorno de desarrollo.\r\n *\r\n * No define `myAppUrl` porque normalmente se toma de la configuración\r\n * de la aplicación Angular (por ejemplo, `environment.ts` del proyecto).\r\n */\r\nexport const developmentEnvironment: DevEnvironmentDefaults = {\r\n production: false,\r\n SeguridadITApiUrl: 'https://localhost:7197/',\r\n tokenName: 'securityIT-Authorize',\r\n tokenNameRF: 'refresh-Authorize',\r\n sessionStatus: 'lastActivity',\r\n refreshTokenExpiry: 'refreshToken-Expiry',\r\n rolesGuards: ['Administrador SIIT'],\r\n};\r\n\r\n/**\r\n * Entorno de producción.\r\n *\r\n * Define todas las propiedades de `AppEnvironment`, incluida `myAppUrl`.\r\n */\r\nexport const productionEnvironment: ProdEnvironmentDefaults = {\r\n production: true,\r\n myAppUrl: '/',\r\n SeguridadITApiUrl: 'https://securityapi.itgtxela.com/',\r\n tokenName: 'securityIT-Authorize',\r\n tokenNameRF: 'refresh-Authorize',\r\n sessionStatus: 'lastActivity',\r\n refreshTokenExpiry: 'refreshToken-Expiry',\r\n rolesGuards: ['Administrador SIIT'],\r\n};\r\n\r\n/**\r\n * Devuelve el índice 0-based del rol principal a partir del `rolIndex` 1-based\r\n * definido en el entorno.\r\n *\r\n * Úsalo cuando necesites indexar arreglos (por ejemplo, listas de roles) para\r\n * evitar repetir la resta de 1 en múltiples lugares del código.\r\n *\r\n * @example\r\n * ```ts\r\n * import { getZeroBasedRolIndex } from '@devsoftxela/ngx-dsx';\r\n *\r\n * const idx = getZeroBasedRolIndex(environment);\r\n * const rol = roles[idx];\r\n * ```\r\n */\r\nexport function getZeroBasedRolIndex(\r\n env: Pick<AppEnvironment, 'rolIndex'>,\r\n): number {\r\n return Math.max(0, env.rolIndex - 1);\r\n}\r\n","import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { Observable } from 'rxjs';\r\nimport {\r\n ENVIRONMENT,\r\n EnvironmentConfig,\r\n} from '../../injections/environment.token';\r\nimport { ServiceResult } from '../../models';\r\nimport { SeguridadITParameter } from '../../models/src/parameterSecurity.model';\r\nimport { DataToken } from '../../models/src/token.model';\r\n\r\n/**\r\n * Servicio de seguridad que gestiona la autenticación y autorización mediante tokens JWT.\r\n *\r\n * Este servicio proporciona métodos para:\r\n * - Refrescar tokens de acceso\r\n * - Revocar tokens de refresco\r\n * - Obtener parámetros de seguridad\r\n *\r\n * @example\r\n * ```typescript\r\n * constructor(private securityService: SecurityService) {}\r\n *\r\n * refreshToken() {\r\n * this.securityService.tokenRefresh(this.refreshToken)\r\n * .subscribe(data => console.log(data));\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SecurityService {\r\n /** Servicio HttpClient para realizar peticiones HTTP */\r\n private http = inject(HttpClient);\r\n\r\n /**\r\n * Configuración del entorno inyectada mediante el token ENVIRONMENT.\r\n * La validación se realiza automáticamente al usar provideEnvironment().\r\n */\r\n private environment: EnvironmentConfig = inject(ENVIRONMENT);\r\n\r\n /** URL base de la API JWT construida desde la configuración del entorno */\r\n private urlApi: string = `${this.environment.myAppUrl}api/parameter`;\r\n private SeguridadITApi: string = `${this.environment.SeguridadITApiUrl}api/jwt`;\r\n\r\n /**\r\n * Obtiene un nuevo token de acceso utilizando un refresh token válido.\r\n *\r\n * Este método envía una solicitud POST al endpoint de refresco de token\r\n * y devuelve un nuevo par de tokens (access token y refresh token).\r\n *\r\n * @param refreshToken - El refresh token válido para obtener un nuevo token de acceso\r\n * @returns Observable que emite un objeto DataToken con el nuevo par de tokens\r\n *\r\n * @example\r\n * ```typescript\r\n * this.securityService.tokenRefresh('your-refresh-token')\r\n * .subscribe({\r\n * next: (data) => console.log('Nuevo token:', data.accessToken),\r\n * error: (err) => console.error('Error al refrescar token:', err)\r\n * });\r\n * ```\r\n */\r\n tokenRefresh(refreshToken: string): Observable<ServiceResult<DataToken>> {\r\n // Crea el cuerpo de la solicitud con el refresh token\r\n const body = { refreshToken };\r\n\r\n // Realiza una solicitud POST al endpoint de refresco de token\r\n return this.http.post<ServiceResult<DataToken>>(\r\n `${this.SeguridadITApi}/refresh-token/`,\r\n body,\r\n {\r\n headers: new HttpHeaders({\r\n 'Content-Type': 'application/json', // Establece el tipo de contenido como JSON\r\n }),\r\n },\r\n );\r\n }\r\n\r\n /**\r\n * Revoca un refresh token para invalidarlo y prevenir su uso futuro.\r\n *\r\n * Este método envía una solicitud POST al endpoint de revocación de token\r\n * para invalidar permanentemente el refresh token proporcionado.\r\n *\r\n * @param refreshToken - El refresh token que se desea revocar\r\n * @returns Observable que emite true si la revocación fue exitosa, false en caso contrario\r\n *\r\n * @example\r\n * ```typescript\r\n * this.securityService.tokenRevok('your-refresh-token')\r\n * .subscribe({\r\n * next: (success) => {\r\n * if (success) console.log('Token revocado exitosamente');\r\n * },\r\n * error: (err) => console.error('Error al revocar token:', err)\r\n * });\r\n * ```\r\n */\r\n tokenRevok(refreshToken: string): Observable<boolean> {\r\n // Crea el cuerpo de la solicitud con el refresh token\r\n const body = { refreshToken };\r\n // Realiza una solicitud POST al endpoint de revocación de token\r\n return this.http.post<boolean>(\r\n `${this.SeguridadITApi}/revoke-token/`,\r\n body,\r\n {\r\n headers: new HttpHeaders({\r\n 'Content-Type': 'application/json', // Establece el tipo de contenido como JSON\r\n }),\r\n },\r\n );\r\n }\r\n\r\n /**\r\n * Obtiene los parámetros de seguridad de la aplicación desde el servidor.\r\n *\r\n * Este método recupera la configuración de seguridad que incluye políticas de contraseñas,\r\n * tiempos de expiración de sesión, y otras configuraciones relacionadas con la seguridad.\r\n *\r\n * @param invalidCacheParam - Indica si se debe invalidar la caché del servidor.\r\n * Si es true, fuerza al servidor a devolver los datos más recientes\r\n * sin usar la caché. Por defecto es false.\r\n * @returns Observable que emite un objeto SeguridadITParameter con la configuración de seguridad\r\n *\r\n * @example\r\n * ```typescript\r\n * // Obtener parámetros usando caché\r\n * this.securityService.getParameterSecurity()\r\n * .subscribe(params => console.log('Parámetros:', params));\r\n *\r\n * // Obtener parámetros sin usar caché\r\n * this.securityService.getParameterSecurity(true)\r\n * .subscribe(params => console.log('Parámetros actualizados:', params));\r\n * ```\r\n */\r\n getParameterSecurity(\r\n invalidCacheParam: boolean = false,\r\n ): Observable<ServiceResult<SeguridadITParameter>> {\r\n // Crea los parámetros de la solicitud, incluyendo el parámetro invalidCacheParam,\r\n // parametro diseñado para invalidar la caché a traves del filtro\r\n const params = new HttpParams().set(\r\n 'invalidCacheParam',\r\n invalidCacheParam.toString(),\r\n );\r\n\r\n // Realiza una solicitud GET al endpoint de parámetros de seguridad\r\n return this.http.get<ServiceResult<SeguridadITParameter>>(\r\n `${this.urlApi}/security-parameter/`,\r\n { params },\r\n );\r\n }\r\n}\r\n","import { inject, Injectable, isDevMode } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { JwtHelperService } from '@auth0/angular-jwt';\r\nimport { CookieService } from 'ngx-cookie-service';\r\nimport {\r\n ENVIRONMENT,\r\n EnvironmentConfig,\r\n} from '../../injections/environment.token';\r\nimport { getZeroBasedRolIndex } from '../../models/src/environment-base';\r\nimport { DataToken, jwtSecurityModel } from '../../models/src/token.model';\r\nimport { SecurityService } from './security.service';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class AuthorizeService {\r\n _cookieService = inject(CookieService);\r\n _router = inject(Router);\r\n helperJwt = new JwtHelperService();\r\n private _isRefreshing = false;\r\n private _securityService = inject(SecurityService);\r\n private environment: EnvironmentConfig = inject(ENVIRONMENT);\r\n\r\n /**\r\n * Detecta si el host actual es local o de red privada.\r\n *\r\n * Se usa para evitar fallback de cookies en escenarios de desarrollo,\r\n * incluso cuando por configuración externa `environment.production`\r\n * viene en `true`.\r\n */\r\n private isLocalOrPrivateHost(): boolean {\r\n if (typeof window === 'undefined') {\r\n return false;\r\n }\r\n\r\n const host = window.location?.hostname ?? '';\r\n if (!host) {\r\n return false;\r\n }\r\n\r\n const normalizedHost = host.toLowerCase();\r\n if (\r\n normalizedHost === 'localhost' ||\r\n normalizedHost === '127.0.0.1' ||\r\n normalizedHost === '::1' ||\r\n normalizedHost.endsWith('.local')\r\n ) {\r\n return true;\r\n }\r\n\r\n const privateIpv4Pattern = /^(10\\.|192\\.168\\.|172\\.(1[6-9]|2\\d|3[0-1])\\.)/;\r\n return privateIpv4Pattern.test(normalizedHost);\r\n }\r\n\r\n // Función para obtener opciones de cookies estándar\r\n /**\r\n * Construye las opciones usadas por `CookieService` al crear cookies.\r\n *\r\n * Motivo del cambio:\r\n * - Los navegadores rechazan cookies con `SameSite=None` si no se envían sobre\r\n * `Secure` (HTTPS). En entornos locales HTTP esto causa que las cookies no\r\n * sean guardadas aunque el servicio intente crearlas.\r\n *\r\n * Comportamiento:\r\n * - En producción y cuando la página usa `https:` se aplica `secure: true`,\r\n * `sameSite: 'None'` y se establece `domain` (como antes).\r\n * - Si no hay HTTPS (p. ej. red local con HTTP) se fuerza `sameSite: 'Lax'`\r\n * y `secure` queda en `false` para evitar que el navegador rechace la cookie.\r\n * - Esto preserva el comportamiento original en entornos con HTTPS.\r\n */\r\n private getCookieOptions(expiryDate: Date): any {\r\n const isProduction = this.environment.production;\r\n const isHttps =\r\n typeof window !== 'undefined' && window.location?.protocol === 'https:';\r\n\r\n const cookieOptions: any = {\r\n path: '/',\r\n expires: expiryDate,\r\n secure: isHttps,\r\n sameSite: isHttps ? 'None' : 'Lax',\r\n };\r\n\r\n // Solo establecer dominio cuando estemos en producción y usemos HTTPS\r\n if (isProduction && isHttps) {\r\n cookieOptions.domain = '.itgtxela.com';\r\n }\r\n\r\n if (isProduction && !isHttps) {\r\n console.warn(\r\n '[AuthorizeService] Entorno en producción pero sin HTTPS. Ajustando opciones de cookie para evitar rechazo por Secure/SameSite.',\r\n );\r\n }\r\n\r\n return cookieOptions;\r\n }\r\n\r\n // Función para establecer una cookie\r\n /**\r\n * Crea una cookie de autenticación y controla un fallback seguro.\r\n *\r\n * Reglas de fallback (`document.cookie`):\r\n * - Solo aplica en ejecución real de producción.\r\n * - Solo aplica cuando la página NO está en HTTPS.\r\n * - Nunca aplica en `isDevMode()`.\r\n * - Nunca aplica en hosts locales/privados.\r\n *\r\n * Objetivo:\r\n * - Mantener política estricta en producción real.\r\n * - Evitar falsos positivos de fallback durante desarrollo local.\r\n */\r\n private setCookie(name: string, value: string, expiryDate: Date): void {\r\n const options = this.getCookieOptions(expiryDate);\r\n const isHttps =\r\n typeof window !== 'undefined' && window.location?.protocol === 'https:';\r\n const isLocalOrPrivateHost = this.isLocalOrPrivateHost();\r\n const allowFallback =\r\n !isDevMode() &&\r\n this.environment.production &&\r\n !isHttps &&\r\n !isLocalOrPrivateHost;\r\n\r\n // Intentamos usar CookieService (respeta domain/secure/samesite cuando corresponde).\r\n // El fallback con document.cookie se limita a producción sin HTTPS.\r\n try {\r\n this._cookieService.set(\r\n name,\r\n value,\r\n options.expires,\r\n options.path,\r\n options.domain,\r\n options.secure,\r\n options.sameSite,\r\n );\r\n\r\n // Verificar si la cookie quedó creada; si no, intentar fallback con document.cookie\r\n const created = this._cookieService.get(name);\r\n if (!created && allowFallback) {\r\n try {\r\n const expires =\r\n options.expires instanceof Date\r\n ? options.expires.toUTCString()\r\n : '';\r\n // Fallback mínimo: no usar Secure ni domain para entornos HTTP locales.\r\n document.cookie = `${name}=${value}; path=/; ${expires ? 'expires=' + expires + '; ' : ''}SameSite=Lax`;\r\n console.warn(\r\n `[AuthorizeService] Cookie '${name}' creada via fallback document.cookie`,\r\n );\r\n } catch (err) {\r\n console.warn(\r\n `[AuthorizeService] No se pudo crear cookie fallback para '${name}':`,\r\n err,\r\n );\r\n }\r\n } else if (!created && this.environment.production) {\r\n console.warn(\r\n `[AuthorizeService] Cookie '${name}' no pudo verificarse con CookieService en entorno no elegible para fallback.`,\r\n );\r\n }\r\n } catch (err) {\r\n console.error(\r\n '[AuthorizeService] Error al crear cookie con CookieService:',\r\n err,\r\n );\r\n if (allowFallback) {\r\n try {\r\n const expires = expiryDate.toUTCString();\r\n document.cookie = `${name}=${value}; path=/; expires=${expires}; SameSite=Lax`;\r\n console.warn(\r\n `[AuthorizeService] Cookie '${name}' creada via fallback document.cookie tras error.`,\r\n );\r\n } catch (err2) {\r\n console.error(\r\n '[AuthorizeService] Fallback document.cookie falló:',\r\n err2,\r\n );\r\n }\r\n }\r\n }\r\n }\r\n\r\n get isRefreshing() {\r\n return this._isRefreshing;\r\n }\r\n set isRefreshing(value) {\r\n this._isRefreshing = value;\r\n }\r\n\r\n getToken(): string | null {\r\n return this._cookieService.get(this.environment.tokenName);\r\n //return localStorage.getItem(environment.tokenName);\r\n }\r\n\r\n /**\r\n * Obtiene el Refresh Token almacenado en cookies.\r\n *\r\n * - En modo desarrollo (isDevMode):\r\n * Si no existe un refresh token en cookies, genera uno temporal\r\n * para evitar errores durante pruebas locales.\r\n *\r\n * - En modo producción:\r\n * Simplemente devuelve el refresh token real almacenado por el backend.\r\n *\r\n * @returns string | null - El refresh token o null si no existe.\r\n */\r\n getTokenRefresh(): string | null {\r\n // 🔹 MODO DESARROLLO: asegura que siempre haya un token de prueba\r\n if (isDevMode()) {\r\n const tokenRefresh = this._cookieService.get(\r\n this.environment.tokenNameRF,\r\n );\r\n\r\n // Si no existe un refresh token, generamos uno de desarrollo\r\n if (!tokenRefresh) {\r\n const devTokens: DataToken = {\r\n token: '',\r\n tokenRefresh: '8508408a-6cbc-4ebb-b105-d851655a3b0c', // Token dummy para testing\r\n refreshTokenExpiry: new Date(),\r\n };\r\n\r\n // Carga y guarda las cookies necesarias\r\n this.tokenReload(devTokens);\r\n }\r\n }\r\n\r\n // 🔹 DEVUELVE el refresh token real o de desarrollo\r\n return this._cookieService.get(this.environment.tokenNameRF);\r\n }\r\n\r\n // Actualizar valores de status\r\n setLastActivity(): void {\r\n const tokenExpiryDate = new Date();\r\n // Expira en 30 minutos\r\n tokenExpiryDate.setMinutes(tokenExpiryDate.getMinutes() + 30);\r\n this.setCookie(\r\n this.environment.sessionStatus,\r\n Date.now().toString(),\r\n tokenExpiryDate,\r\n );\r\n }\r\n\r\n getLastActivity(): number | null {\r\n // Obtiene el valor de la cookie\r\n const lastActivity = this._cookieService.get(\r\n this.environment.sessionStatus,\r\n );\r\n\r\n if (lastActivity) {\r\n // Intenta convertir el valor en un número\r\n const timestamp = parseInt(lastActivity, 10);\r\n\r\n // Verifica que sea un número válido\r\n if (!isNaN(timestamp)) {\r\n return timestamp;\r\n }\r\n }\r\n\r\n // Si no hay cookie o el valor no es válido, devuelve null\r\n return null;\r\n }\r\n\r\n // Almacenar los tokens en cookies\r\n tokenReload(tokens: DataToken) {\r\n const tokenExpiryDate = new Date();\r\n tokenExpiryDate.setMinutes(tokenExpiryDate.getMinutes() + 30); // Access token expiry: 30 mins\r\n\r\n // Usar la fecha de expiración que viene del servidor para el refresh token\r\n const refreshTokenExpiryDate = new Date(tokens.refreshTokenExpiry);\r\n\r\n // Guardar el access token y refresh token con sus fechas de expiración\r\n this.setCookie(this.environment.tokenName, tokens.token, tokenExpiryDate);\r\n this.setCookie(\r\n this.environment.tokenNameRF,\r\n tokens.tokenRefresh,\r\n refreshTokenExpiryDate,\r\n );\r\n\r\n // Guardar el estado de sesión\r\n this.setLastActivity();\r\n }\r\n\r\n getTokenValid(token: string | null): boolean {\r\n // Devuelve true si el token NO ha expirado\r\n return !this.helperJwt.isTokenExpired(token);\r\n }\r\n\r\n /**\r\n * Obtiene los valores principales del JWT almacenado (usuario, roles y estado).\r\n *\r\n * Este getter:\r\n * - Lee el access token desde cookies.\r\n * - Devuelve un objeto tipado (jwtSecurityModel).\r\n * - Decodifica el token para obtener `unique_name` y `role`.\r\n * - Determina si el token está expirado usando JwtHelperService.\r\n *\r\n * Si no existe token:\r\n * - Devuelve un objeto vacío con valores en null y `isTokenExpired = true`.\r\n *\r\n * Uso:\r\n * const info = this.authorize.getTokenValues;\r\n */\r\n get getTokenValues(): jwtSecurityModel {\r\n // Obtener el token almacenado\r\n const token = this.getToken();\r\n\r\n // Si no existe token → devolver estructura vacía\r\n if (!token) {\r\n return {\r\n userName: null,\r\n role: null,\r\n isTokenExpired: true,\r\n };\r\n }\r\n\r\n // Decodificar JWT\r\n const decoded = this.helperJwt.decodeToken(token) || {};\r\n\r\n return {\r\n userName: decoded.unique_name ?? null,\r\n\r\n // JWT puede traer role como string o como array → convertir a array\r\n role: decoded.role\r\n ? Array.isArray(decoded.role)\r\n ? decoded.role\r\n : [decoded.role]\r\n : null,\r\n\r\n // Validación de expiración del JWT\r\n isTokenExpired: this.helperJwt.isTokenExpired(token),\r\n };\r\n }\r\n\r\n /**\r\n * Rol principal calculado a partir del JWT y del rolIndex configurado\r\n * en el environment.\r\n *\r\n * - Usa getTokenValues para obtener el array de roles del token.\r\n * - Usa getZeroBasedRolIndex(environment) para convertir el rolIndex 1-based\r\n * del entorno a un índice 0-based.\r\n * - Si el rol viene con formato \"ROL~descripcion\", devuelve solo la parte\r\n * anterior al separador `~`.\r\n */\r\n get primaryRole(): string | null {\r\n const idx = getZeroBasedRolIndex(this.environment);\r\n const tokenValues = this.getTokenValues;\r\n const roles = tokenValues.role ?? [];\r\n const raw = roles[idx] ?? null;\r\n return typeof raw === 'string' ? raw.split('~')[0] : null;\r\n }\r\n\r\n /**\r\n * Verifica si el usuario está autenticado.\r\n *\r\n * La validación se basa en la existencia del refresh token en cookies.\r\n * El navegador gestiona automáticamente la expiración de las cookies.\r\n *\r\n * @returns `true` si el usuario está autenticado, `false` en caso contrario\r\n */\r\n isAuthenticated(): boolean {\r\n const refreshToken = this.getTokenRefresh();\r\n return !!(refreshToken && refreshToken.trim() !== '');\r\n }\r\n\r\n /**\r\n * Cierra la sesión del usuario de forma segura y controlada.\r\n *\r\n * Este método implementa un proceso de logout robusto que:\r\n * 1. Verifica el estado actual de la sesión y la ubicación del usuario\r\n * 2. Intenta revocar el refresh token en el servidor (si existe)\r\n * 3. Limpia todos los datos de sesión local\r\n * 4. Redirige al usuario a la página de login\r\n *\r\n * **Casos manejados:**\r\n * - Usuario ya en página de login: Solo limpia datos locales\r\n * - Sin refresh token: Limpia datos locales y redirige\r\n * - Con refresh token: Intenta revocarlo, luego limpia y redirige\r\n * - Error al revocar: Limpia datos locales de todas formas (seguridad)\r\n * - Modo desarrollo: Maneja tokens de prueba correctamente\r\n *\r\n * **Importante:** Este método es **asíncrono** en su ejecución interna pero no retorna una promesa.\r\n * La redirección al login ocurre después de limpiar la sesión, independientemente del resultado de la revocación.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Uso básico desde un componente\r\n * this.authorizeService.logout();\r\n *\r\n * // Uso con navegación posterior controlada\r\n * this.authorizeService.logout();\r\n * // La redirección al login es automática\r\n * ```\r\n *\r\n * @see {@link clearSessionData} para el proceso de limpieza de datos\r\n * @see {@link SecurityService.tokenRevok} para la revocación en el servidor\r\n */\r\n logout(): void {\r\n try {\r\n // 1️⃣ Prevenir acciones innecesarias si ya está en el login\r\n if (this._router.url === '/login') {\r\n console.info(\r\n '[AuthorizeService] Usuario ya en página de login, limpiando sesión local...',\r\n );\r\n this.clearSessionData();\r\n return;\r\n }\r\n\r\n // 2️⃣ Obtener el refresh token de forma segura\r\n const refreshToken = this.getTokenRefresh();\r\n\r\n // 3️⃣ Si no hay refresh token, proceder con limpieza directa\r\n if (!refreshToken || refreshToken.trim() === '') {\r\n console.warn(\r\n '[AuthorizeService] No se encontró refresh token, limpiando sesión local...',\r\n );\r\n this.clearSessionData();\r\n return;\r\n }\r\n\r\n // 4️⃣ Intentar revocar el token en el servidor\r\n console.info(\r\n '[AuthorizeService] Revocando refresh token en el servidor...',\r\n );\r\n\r\n this._securityService.tokenRevok(refreshToken).subscribe({\r\n next: (success) => {\r\n if (success) {\r\n console.info(\r\n '[AuthorizeService] Refresh token revocado exitosamente en el servidor',\r\n );\r\n } else {\r\n console.warn(\r\n '[AuthorizeService] El servidor no pudo revocar el token, pero continuando con logout',\r\n );\r\n }\r\n this.clearSessionData();\r\n },\r\n error: (error) => {\r\n // 5️⃣ Manejar errores de revocación con información detallada\r\n console.error(\r\n '[AuthorizeService] Error al revocar el refresh token:',\r\n {\r\n message: error?.message || 'Error desconocido',\r\n status: error?.status,\r\n statusText: error?.statusText,\r\n url: error?.url,\r\n },\r\n );\r\n\r\n // Por seguridad, limpiar la sesión incluso si falla la revocación\r\n console.warn(\r\n '[AuthorizeService] Limpiando sesión local por seguridad a pesar del error',\r\n );\r\n this.clearSessionData();\r\n },\r\n complete: () => {\r\n console.info('[AuthorizeService] Proceso de logout completado');\r\n },\r\n });\r\n } catch (error) {\r\n // 6️⃣ Capturar cualquier error inesperado en el proceso de logout\r\n console.error(\r\n '[AuthorizeService] Error crítico durante el proceso de logout:',\r\n error,\r\n );\r\n\r\n // Garantizar que la sesión se limpie incluso si ocurre un error inesperado\r\n try {\r\n this.clearSessionData();\r\n } catch (cleanupError) {\r\n console.error(\r\n '[AuthorizeService] Error crítico al limpiar sesión:',\r\n cleanupError,\r\n );\r\n // Último recurso: redirigir al login sin importar qué\r\n this._router.navigate(['/login']).catch((navError) => {\r\n console.error(\r\n '[AuthorizeService] Error al navegar a login:',\r\n navError,\r\n );\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Limpia todos los datos de sesión del usuario de forma segura.\r\n *\r\n * Este método privado se encarga de:\r\n * - Eliminar todas las cookies relacionadas con autenticación\r\n * - Limpiar el localStorage completamente\r\n * - Redirigir al usuario a la página de login\r\n *\r\n * **Cookies eliminadas:**\r\n * - Token de acceso (access token)\r\n * - Token de refresco (refresh token)\r\n * - Estado de sesión (session status)\r\n *\r\n * **Consideraciones:**\r\n * - Se eliminan las cookies con path '/' para asegurar su borrado\r\n * - En producción, también se considera el dominio configurado\r\n * - El localStorage se limpia completamente por seguridad\r\n * - La redirección es forzada incluso si hay errores previos\r\n *\r\n * @private\r\n */\r\n private clearSessionData(): void {\r\n try {\r\n console.info(\r\n '[AuthorizeService] Iniciando limpieza de datos de sesión...',\r\n );\r\n\r\n // 1️⃣ Eliminar cookies con path explícito\r\n const cookiesToDelete = [\r\n this.environment.tokenName,\r\n this.environment.tokenNameRF,\r\n this.environment.sessionStatus,\r\n ];\r\n\r\n cookiesToDelete.forEach((cookieName) => {\r\n try {\r\n // Eliminar con path '/'\r\n this._cookieService.delete(cookieName, '/');\r\n\r\n // En producción, también intentar eliminar con dominio específico\r\n if (this.environment.production) {\r\n this._cookieService.delete(cookieName, '/', '.itgtxela.com');\r\n }\r\n\r\n console.debug(`[AuthorizeService] Cookie eliminada: ${cookieName}`);\r\n } catch (error) {\r\n console.error(\r\n `[AuthorizeService] Error al eliminar cookie ${cookieName}:`,\r\n error,\r\n );\r\n }\r\n });\r\n\r\n // 2️⃣ Limpiar localStorage\r\n try {\r\n localStorage.clear();\r\n console.debug('[AuthorizeService] localStorage limpiado');\r\n } catch (error) {\r\n console.error(\r\n '[AuthorizeService] Error al limpiar localStorage:',\r\n error,\r\n );\r\n }\r\n\r\n // 3️⃣ Redirigir al login\r\n console.info('[AuthorizeService] Redirigiendo a página de login...');\r\n this._router.navigate(['/login']).then(\r\n () => console.info('[AuthorizeService] Redirección exitosa a /login'),\r\n (error) =>\r\n console.error('[AuthorizeService] Error en la redirección:', error),\r\n );\r\n } catch (error) {\r\n console.error(\r\n '[AuthorizeService] Error crítico en clearSessionData:',\r\n error,\r\n );\r\n\r\n // Último recurso: intentar redirigir sin importar qué\r\n this._router.navigate(['/login']).catch((navError) => {\r\n console.error(\r\n '[AuthorizeService] Error final al intentar redirigir:',\r\n navError,\r\n );\r\n });\r\n }\r\n }\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\nimport { MyParameterValues } from '../models/src/parameterSecurity.model';\r\n\r\nexport const INITIAL_PARAMETERS = new InjectionToken<MyParameterValues[]>(\r\n 'InitialParameters'\r\n);\r\n","import { inject, Injectable, signal } from '@angular/core';\r\nimport {\r\n catchError,\r\n delay,\r\n map,\r\n Observable,\r\n of,\r\n retry,\r\n throwError,\r\n} from 'rxjs';\r\nimport { INITIAL_PARAMETERS } from '../../injections/parameterSecurity';\r\nimport {\r\n MyParameterValues,\r\n ParameterSecurity,\r\n} from '../../models/src/parameterSecurity.model';\r\nimport { SecurityService } from './security.service';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\n/**\r\n * Servicio para gestionar los parámetros de seguridad de la aplicación.\r\n * Permite cargar los parámetros desde la API, mantenerlos en memoria, acceder y comparar valores de forma segura.\r\n * Utiliza tipado genérico para los nombres de parámetros y cache interno para optimizar consultas repetidas.\r\n *\r\n * @template T Tipo de los nombres de parámetros permitidos (usualmente un union type de string)\r\n */\r\nexport class ParameterValuesService<T extends string = string> {\r\n /**\r\n * Parámetros iniciales inyectados mediante INITIAL_PARAMETERS.\r\n * Se usan para validar y mapear los parámetros recibidos de la API.\r\n */\r\n private initialParameters = inject(INITIAL_PARAMETERS);\r\n\r\n /**\r\n * Cache interno para optimizar la comparación de valores de parámetros.\r\n * La clave es una combinación de nombre e índice, el valor es el resultado de la consulta.\r\n */\r\n private parameterCache = new Map<string, any>();\r\n\r\n private alertedParams = new Set<string>();\r\n private alertedParamsIsParameterValue = new Set<string>();\r\n\r\n /**\r\n * Servicio que contiene el método getParameterSecurity() para obtener los parámetros desde la API.\r\n */\r\n private apiService = inject(SecurityService);\r\n\r\n /**\r\n * Señal reactiva que contiene los parámetros cargados y permite actualizaciones automáticas.\r\n */\r\n private _dataParameter = signal<MyParameterValues<T>[]>(\r\n this.initializeData(),\r\n );\r\n\r\n /**\r\n * Flag que indica si ya se cargaron los parámetros desde la API.\r\n */\r\n private _loaded = signal(false);\r\n get loaded() {\r\n return this._loaded();\r\n }\r\n\r\n /**\r\n * Inicializa los datos de parámetros usando los valores inyectados.\r\n * @returns Array de parámetros iniciales tipados\r\n */\r\n private initializeData(): MyParameterValues<T>[] {\r\n return this.initialParameters.map((param) =>\r\n this.createMyParameterValue(param.parameterName as T, param.values),\r\n );\r\n }\r\n\r\n /**\r\n * Crea una instancia de MyParameterValues tipada y segura.\r\n * @param parameterName Nombre del parámetro\r\n * @param values Valores asociados al parámetro\r\n * @returns Objeto MyParameterValues\r\n */\r\n private createMyParameterValue(\r\n parameterName: T,\r\n values: any[],\r\n ): MyParameterValues<T> {\r\n return {\r\n parameterName,\r\n values: [...values],\r\n };\r\n }\r\n\r\n /**\r\n * Devuelve los parámetros actuales como un array de solo lectura.\r\n */\r\n get dataParameter(): Readonly<MyParameterValues<T>[]> {\r\n return this._dataParameter();\r\n }\r\n\r\n /**\r\n * Setter privado para actualizar los parámetros.\r\n * Solo puede ser usado dentro del servicio para mantener la integridad de los datos.\r\n * @param values Array de parámetros a almacenar\r\n */\r\n private setDataParameter(values: MyParameterValues<T>[]): void {\r\n if (!Array.isArray(values)) {\r\n console.error('Error: valores inválidos para dataParameter');\r\n return;\r\n }\r\n this._dataParameter.set(values);\r\n }\r\n\r\n /**\r\n * Carga los parámetros desde la API.\r\n * Si ya se cargaron y force=false, devuelve la copia en memoria.\r\n * @param force Indica si se debe forzar la recarga desde la API (default: false)\r\n * @returns Observable que emite los parámetros cargados como MyParameterValues[]\r\n */\r\n loadParameters(force = false): Observable<MyParameterValues<T>[]> {\r\n if (this._loaded() && !force) {\r\n return of([...this.dataParameter]); // copia mutable\r\n }\r\n\r\n return this.apiService.getParameterSecurity(force).pipe(\r\n map((response) => {\r\n const apiParameters = response.data?.parameterSecurity ?? [];\r\n this.validateParameters(apiParameters);\r\n const values = this.mapToMyParameterValues(apiParameters);\r\n this.setDataParameter(values);\r\n this._loaded.set(true);\r\n return values;\r\n }),\r\n // 👇 fallback si falla la llamada pero ya teníamos data\r\n catchError((error) => {\r\n if (this._loaded() && this.dataParameter.length > 0) {\r\n return of([...this.dataParameter]);\r\n }\r\n this._loaded.set(false);\r\n return throwError(() => error);\r\n }),\r\n );\r\n }\r\n\r\n /**\r\n * Fuerza la recarga de los parámetros desde la API.\r\n * @returns Observable que emite los parámetros actualizados\r\n */\r\n refreshParameters(): Observable<MyParameterValues<T>[]> {\r\n return this.loadParameters(true);\r\n }\r\n\r\n /**\r\n * Crea una copia segura y mutable de los parámetros actuales.\r\n * @returns Array de parámetros\r\n */\r\n private createSafeCopy(): MyParameterValues<T>[] {\r\n return this.dataParameter.map((item) =>\r\n this.createMyParameterValue(item.parameterName, [...item.values]),\r\n );\r\n }\r\n\r\n /**\r\n * Mapea los parámetros recibidos de la API a objetos tipados y seguros.\r\n * @param apiParameters Parámetros recibidos desde la API\r\n * @returns Array de MyParameterValues\r\n */\r\n private mapToMyParameterValues(\r\n apiParameters: ParameterSecurity[],\r\n ): MyParameterValues<T>[] {\r\n const initialNames = this.initialParameters.map((p) => p.parameterName);\r\n\r\n return apiParameters\r\n .filter((param) => initialNames.includes(param.parameterName))\r\n .map((param) => {\r\n // Función de conversión type-safe\r\n return this.convertToTypedParameter(param);\r\n })\r\n .filter((param): param is MyParameterValues<T> => param !== null);\r\n }\r\n\r\n /**\r\n * Convierte un parámetro de la API a un objeto tipado, validando el nombre.\r\n * @param param Parámetro recibido de la API\r\n * @returns Objeto MyParameterValues o null si no es válido\r\n */\r\n private convertToTypedParameter(\r\n param: ParameterSecurity,\r\n ): MyParameterValues<T> | null {\r\n const initialParam = this.initialParameters.find(\r\n (p) => p.parameterName === param.parameterName,\r\n );\r\n\r\n if (!initialParam) {\r\n return null;\r\n }\r\n\r\n // Conversión segura con verificación\r\n if (this.isValidParameterName(param.parameterName)) {\r\n return this.createMyParameterValue(\r\n param.parameterName as T,\r\n param.parameterValues?.map((v) => v.value) ?? [],\r\n );\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Verifica si un nombre de parámetro es válido según los parámetros iniciales.\r\n * @param name Nombre a validar\r\n * @returns true si es válido\r\n */\r\n private isValidParameterName(name: string): name is T {\r\n // Verifica que el nombre esté en los parámetros iniciales\r\n return this.initialParameters.some((param) => param.parameterName === name);\r\n }\r\n\r\n /**\r\n * Valida que los parámetros devueltos por la API coincidan con los iniciales.\r\n * Muestra errores o advertencias en consola si existen diferencias.\r\n * @param apiParameters Parámetros recibidos desde la API\r\n */\r\n private validateParameters(apiParameters: ParameterSecurity[]): void {\r\n const initialNames = this.initialParameters.map((p) => p.parameterName);\r\n const apiNames = apiParameters.map((p) => p.parameterName);\r\n\r\n const missing = initialNames.filter((name) => !apiNames.includes(name));\r\n const extra = apiNames.filter((name) => !initialNames.includes(name));\r\n\r\n if (missing.length) {\r\n console.warn(`Faltan en API: ${missing.join(', ')}`);\r\n const ok = confirm(`Faltan en API: ${missing.join(', ')}. ¿Continuar?`);\r\n if (!ok) return;\r\n }\r\n if (extra.length) {\r\n console.warn(`Extra en API: ${extra.join(', ')}`);\r\n const ok = confirm(`Extra en API: ${extra.join(', ')}. ¿Continuar?`);\r\n if (!ok) return;\r\n }\r\n if (initialNames.length !== apiNames.length) {\r\n console.warn(\r\n `Cantidad distinta: iniciales=${initialNames.length}, api=${apiNames.length}`,\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Obtiene un valor específico de un parámetro.\r\n * Si `index` es null (valor por defecto), devuelve todo el arreglo de valores.\r\n * Devuelve `defaultValue` si no existe el parámetro o el índice es inválido.\r\n * Valida que el parámetro exista antes de acceder a su valor.\r\n * @param parameterName Nombre del parámetro\r\n * @param index Índice del valor dentro del array. Si es null (default), devuelve todos los valores.\r\n * @param defaultValue Valor por defecto si no existe (default: null)\r\n * @returns Valor del parámetro, todos los valores si index es null, o defaultValue si no existe o el índice es inválido\r\n */\r\n getValue<U = any>(parameterName: T): U[];\r\n getValue<U = any>(\r\n parameterName: T,\r\n index: number,\r\n defaultValue?: U | null,\r\n ): U;\r\n getValue<U = any>(\r\n parameterName: T,\r\n index: null,\r\n defaultValue?: U[] | null,\r\n ): U[];\r\n getValue<U = any>(\r\n parameterName: T,\r\n index: number | null = null,\r\n defaultValue: U | U[] | null = null,\r\n ): U | U[] {\r\n const param = this.dataParameter.find(\r\n (p) => p.parameterName === parameterName,\r\n );\r\n\r\n if (!param) {\r\n if (!this.alertedParams.has(parameterName)) {\r\n alert(`Advertencia: El parámetro '${parameterName}' no existe.`);\r\n this.alertedParams.add(parameterName);\r\n }\r\n return defaultValue as U | U[];\r\n }\r\n\r\n if (index === null) {\r\n return param.values as U[];\r\n }\r\n\r\n if (index < 0 || index >= param.values.length) {\r\n alert(\r\n `Advertencia: Índice ${index} fuera de rango para el parámetro '${parameterName}'.`,\r\n );\r\n return defaultValue as U;\r\n }\r\n\r\n return param.values[index] as U;\r\n }\r\n\r\n /**\r\n * Compara un valor específico con un valor esperado, usando cache para optimizar llamadas repetidas.\r\n * @param parameterName Nombre del parámetro\r\n * @param expectedValue Valor esperado\r\n * @param index Índice del valor dentro del array (default: 0)\r\n * @returns true si coincide, false en caso contrario\r\n */\r\n isParameterValue<U = any>(\r\n parameterName: T,\r\n expectedValue: U,\r\n index = 0,\r\n ): boolean {\r\n const cacheKey = `${String(parameterName)}_${index}`;\r\n\r\n const param = this.dataParameter.find(\r\n (p) => p.parameterName === parameterName,\r\n );\r\n\r\n if (!param) {\r\n if (!this.alertedParamsIsParameterValue.has(parameterName)) {\r\n alert(`Error: El parámetro '${parameterName}' no existe.`);\r\n this.alertedParamsIsParameterValue.add(parameterName);\r\n }\r\n return false;\r\n }\r\n\r\n if (!this.parameterCache.has(cacheKey)) {\r\n const value = this.getValue<U>(parameterName, index);\r\n this.parameterCache.set(cacheKey, value);\r\n }\r\n\r\n return this.parameterCache.get(cacheKey) === expectedValue;\r\n }\r\n\r\n /**\r\n * Limpia el cache interno de comparaciones de parámetros.\r\n */\r\n clearParameterCache(): void {\r\n this.parameterCache.clear();\r\n }\r\n\r\n /**\r\n * Verifica si un parámetro tiene al menos un valor.\r\n * @param parameterName Nombre del parámetro\r\n * @returns true si tiene al menos un valor, false si no tiene\r\n */\r\n hasAnyValue(parameterName: T): boolean {\r\n return this.getAllValues(parameterName).length > 0;\r\n }\r\n\r\n /**\r\n * Devuelve todos los valores de un parámetro.\r\n * @param parameterName Nombre del parámetro\r\n * @returns Array de valores\r\n */\r\n getAllValues<U = any>(parameterName: T): U[] {\r\n return (this.dataParameter.find((p) => p.parameterName === parameterName)\r\n ?.values ?? []) as U[];\r\n }\r\n}\r\n","import { Injectable, signal } from '@angular/core';\r\n\r\nexport type NetworkScore = 100 | 75 | 50 | 25;\r\n\r\nexport interface RequestMetricsState {\r\n lastDurationMs: number;\r\n averageDurationMs: number;\r\n requestsCount: number;\r\n score: NetworkScore;\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class RequestMetricsService {\r\n private historySize = 20;\r\n private durations: number[] = [];\r\n\r\n readonly state = signal<RequestMetricsState>({\r\n lastDurationMs: 0,\r\n averageDurationMs: 0,\r\n requestsCount: 0,\r\n score: 100,\r\n });\r\n\r\n registerRequest(durationMs: number) {\r\n this.durations.push(durationMs);\r\n if (this.durations.length > this.historySize) {\r\n this.durations.shift();\r\n }\r\n\r\n const avg =\r\n this.durations.reduce((acc, d) => acc + d, 0) / this.durations.length;\r\n\r\n const score = this.mapDurationToScore(avg);\r\n\r\n this.state.set({\r\n lastDurationMs: durationMs,\r\n averageDurationMs: avg,\r\n requestsCount: this.durations.length,\r\n score,\r\n });\r\n }\r\n\r\n private mapDurationToScore(avgMs: number): NetworkScore {\r\n // Ajusta umbrales a tu realidad\r\n if (avgMs <= 325) return 100;\r\n if (avgMs <= 800) return 75;\r\n if (avgMs <= 1500) return 50;\r\n return 25;\r\n }\r\n}\r\n","import { DecimalPipe } from '@angular/common';\r\nimport { Component, inject } from '@angular/core';\r\nimport { Avatar } from 'primeng/avatar';\r\nimport { TooltipModule } from 'primeng/tooltip';\r\nimport { RequestMetricsService } from '../../../services/src/request-metrics.service';\r\n\r\n@Component({\r\n selector: 'app-network-status',\r\n imports: [Avatar, DecimalPipe, TooltipModule],\r\n templateUrl: './network-status.component.html',\r\n styleUrl: './network-status.component.css',\r\n})\r\nexport class NetworkStatusComponent {\r\n private readonly metrics = inject(RequestMetricsService);\r\n state = this.metrics.state; // signal\r\n\r\n get tooltipText(): string {\r\n const { score, averageDurationMs, requestsCount } = this.state();\r\n const avg = Math.round(averageDurationMs);\r\n return `Estado de la red: ${score}% (promedio ${avg} ms, últimas ${requestsCount} peticiones)`;\r\n }\r\n\r\n getStatusImage(): string {\r\n const score = this.state().score;\r\n\r\n // 100 hasta 76 -> imagen \"muy buena\"\r\n if (score >= 76) {\r\n return 'image/Status_Green.png';\r\n }\r\n\r\n // 75 hasta 50 -> imagen \"media\"\r\n if (score >= 50) {\r\n return 'image/Status_Yellow.png';\r\n }\r\n\r\n // 50 o menos -> última imagen (mala)\r\n return 'image/Status_Red.png';\r\n }\r\n}\r\n","<div class=\"network-status-container\">\r\n <p-avatar\r\n [image]=\"getStatusImage()\"\r\n [pTooltip]=\"tooltipText\"\r\n tooltipPosition=\"bottom\"\r\n />\r\n <span> {{ state().score }}% </span>\r\n <span> {{ state().averageDurationMs | number: \"1.0-0\" }}ms </span>\r\n</div>\r\n","import { Component, inject, input, OnInit } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { ButtonModule } from 'primeng/button';\r\nimport { ImageModule } from 'primeng/image';\r\nimport { MenubarModule } from 'primeng/menubar';\r\nimport {\r\n ENVIRONMENT,\r\n EnvironmentConfig,\r\n} from '../../injections/environment.token';\r\nimport { AlertaService } from '../../services/src/alerta.service';\r\nimport { AuthorizeService } from '../../services/src/authorize.service';\r\nimport { ParameterValuesService } from '../../services/src/parameter-values.service';\r\nimport { IconDsxComponent } from '../icon-dsx/icon-dsx.component';\r\nimport { NetworkStatusComponent } from '../status/network-status/network-status.component';\r\n\r\n@Component({\r\n selector: 'app-navbar-dsx',\r\n imports: [\r\n ButtonModule,\r\n FormsModule,\r\n IconDsxComponent,\r\n ImageModule,\r\n MenubarModule,\r\n NetworkStatusComponent,\r\n ],\r\n templateUrl: './navbar-dsx.component.html',\r\n styleUrl: './navbar-dsx.component.css',\r\n})\r\nexport class NavbarDsxComponent implements OnInit {\r\n _authorizeService = inject(AuthorizeService);\r\n appVersion = input<string>('V1.0.0');\r\n checked: boolean = false; // Estado del interruptor (tema claro/oscuro)\r\n logoWidth = input<string>('300');\r\n private readonly _alertaService = inject(AlertaService);\r\n private readonly _parameterSecurityService = inject(ParameterValuesService);\r\n urlLogo = input<string>('assets/image/logoApp.png');\r\n private readonly environment: EnvironmentConfig = inject(ENVIRONMENT);\r\n\r\n ngOnInit(): void {\r\n // Inicializa el tema al cargar el componente\r\n this.initializeTheme();\r\n }\r\n\r\n // Rol actual calculado en base al token y al rolIndex del environment.\r\n // Se evalúa en cada ciclo de detección de cambios, por lo que refleja\r\n // automáticamente los cambios cuando se refresca el token.\r\n get currentRole(): string | null {\r\n return this._authorizeService.primaryRole;\r\n }\r\n\r\n // Inicializa el tema y el estado del interruptor\r\n initializeTheme(): void {\r\n const savedTheme = localStorage.getItem('theme') || 'light'; // Obtén el tema guardado o usa 'light' por defecto\r\n this.checked = savedTheme === 'dark'; // Actualiza el estado del interruptor\r\n this.applyTheme(savedTheme); // Aplica el tema\r\n }\r\n\r\n // Cambia el tema y actualiza el estado del interruptor\r\n onThemeChange(isDarkMode: boolean): void {\r\n // Determina el tema basado en el estado del interruptor\r\n const theme = isDarkMode ? 'dark' : 'light';\r\n // Aplica el tema\r\n this.applyTheme(theme);\r\n }\r\n\r\n // Aplica el tema y guarda la preferencia en localStorage\r\n applyTheme(theme: string): void {\r\n const html = document.documentElement;\r\n\r\n // Elimina las clases previas y agrega la nueva clase\r\n html.classList.remove('my-app-dark', 'my-app-light');\r\n html.classList.add(theme === 'dark' ? 'my-app-dark' : 'my-app-light');\r\n\r\n // Guarda el tema en localStorage\r\n localStorage.setItem('theme', theme);\r\n }\r\n\r\n actualizarSeguridadIT() {\r\n this._parameterSecurityService.refreshParameters().subscribe({\r\n next: (values) => {\r\n this._alertaService.toastrAlerts(\r\n 2,\r\n 'SeguridadIT',\r\n 'Parametro actualizado!',\r\n 2,\r\n );\r\n //console.log('Parámetros cargados:', values);\r\n },\r\n error: (err) => {\r\n console.error('Error al actualizar parámetros de SeguridadIT', err);\r\n this._alertaService.toastrAlerts(\r\n 3,\r\n 'SeguridadIT',\r\n 'Error al actualizar parámetros!',\r\n 2,\r\n );\r\n },\r\n complete: () => this._parameterSecurityService.clearParameterCache(),\r\n });\r\n }\r\n}\r\n","<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ón de permisos -->\r\n <p-button\r\n class=\"mr-2\"\r\n label=\"Permisos\"\r\n variant=\"text\"\r\n severity=\"info\"\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","import { Directive, ElementRef, HostListener } from '@angular/core';\r\n\r\n/**\r\n * Directiva de navegación por teclado entre elementos de una tabla.\r\n *\r\n * Uso: colocar el atributo [appKeyboardNav] en cada control navegable dentro\r\n * de un contenedor <table>. La directiva busca el <table> más cercano con\r\n * `closest('table')` y recorre todos los elementos marcados con ese atributo.\r\n *\r\n * Teclas soportadas:\r\n * - Enter / ArrowDown / ArrowRight → siguiente elemento\r\n * - Shift+Enter / ArrowUp / ArrowLeft → elemento anterior\r\n * La navegación es cíclica (del último vuelve al primero y viceversa).\r\n *\r\n * NOTA DE COMPATIBILIDAD — componentes PrimeNG:\r\n * Actualmente validado con <p-inputnumber>. Los componentes de PrimeNG (y otros\r\n * wrappers) no exponen un <input> nativo directamente en el host; en su lugar\r\n * renderizan el <input> como hijo en el shadow/light DOM interno.\r\n * Por eso esta directiva no hace `.focus()` sobre el host del componente, sino\r\n * que resuelve primero el control nativo enfocable interno mediante\r\n * `resolveFocusableTarget()`. Si en el futuro se integran otros componentes\r\n * (p-dropdown, p-select, etc.) puede ser necesario ampliar ese selector o agregar\r\n * lógica específica por tipo de componente, ya que cada uno renderiza su control\r\n * interno de forma diferente.\r\n */\r\n@Directive({\r\n selector: '[appKeyboardNav]',\r\n})\r\nexport class ArrowNavigationDirective {\r\n /**\r\n * Activa los logs de depuración en consola.\r\n * Cambiar a `true` para trazar el flujo de navegación durante el desarrollo.\r\n */\r\n private readonly debug = false;\r\n\r\n constructor(private el: ElementRef<HTMLElement>) {}\r\n\r\n @HostListener('keydown', ['$event'])\r\n handleKey(event: KeyboardEvent) {\r\n this.log('keydown recibido', {\r\n key: event.key,\r\n shiftKey: event.shiftKey,\r\n element: this.el.nativeElement,\r\n });\r\n\r\n const keys = ['Enter', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];\r\n if (!keys.includes(event.key)) {\r\n this.log('tecla ignorada', { key: event.key });\r\n return;\r\n }\r\n\r\n event.preventDefault();\r\n\r\n // Obtiene todos los elementos navegables no deshabilitados dentro del <table>\r\n const elements = this.getElements();\r\n const index = elements.indexOf(this.el.nativeElement);\r\n\r\n this.log('elementos navegables detectados', {\r\n total: elements.length,\r\n currentIndex: index,\r\n });\r\n\r\n // Si el elemento actual no está en la lista (p.ej. no tiene [appKeyboardNav]) se aborta\r\n if (index === -1) {\r\n this.log('elemento actual no encontrado en la lista navegable');\r\n return;\r\n }\r\n\r\n let nextIndex = index;\r\n\r\n switch (event.key) {\r\n case 'Enter':\r\n nextIndex = event.shiftKey ? index - 1 : index + 1;\r\n break;\r\n\r\n case 'ArrowDown':\r\n nextIndex = index + 1;\r\n break;\r\n\r\n case 'ArrowUp':\r\n nextIndex = index - 1;\r\n break;\r\n\r\n case 'ArrowRight':\r\n nextIndex = index + 1;\r\n break;\r\n\r\n case 'ArrowLeft':\r\n nextIndex = index - 1;\r\n break;\r\n }\r\n\r\n // Navegación cíclica: al pasar del último vuelve al primero y viceversa\r\n if (nextIndex >= elements.length) nextIndex = 0;\r\n if (nextIndex < 0) nextIndex = elements.length - 1;\r\n\r\n const nextElement = elements[nextIndex];\r\n this.log('moviendo foco', {\r\n from: index,\r\n to: nextIndex,\r\n nextElement,\r\n });\r\n\r\n this.focusElement(nextElement);\r\n }\r\n\r\n /**\r\n * Recoge todos los elementos con [appKeyboardNav] dentro del <table> contenedor\r\n * y filtra los que estén deshabilitados.\r\n */\r\n private getElements(): HTMLElement[] {\r\n const container = this.el.nativeElement.closest('table');\r\n\r\n if (!container) {\r\n this.log('no se encontró contenedor table con closest()');\r\n return [];\r\n }\r\n\r\n return Array.from(\r\n container.querySelectorAll<HTMLElement>('[appKeyboardNav]'),\r\n ).filter((el) => !el.hasAttribute('disabled'));\r\n }\r\n\r\n /**\r\n * Aplica el foco al control enfocable real dentro del elemento destino.\r\n * Necesario para componentes wrapper como <p-inputnumber>, donde el foco\r\n * debe recaer en el <input> interno y no en el host del componente.\r\n */\r\n private focusElement(element: HTMLElement) {\r\n const target = this.resolveFocusableTarget(element);\r\n\r\n this.log('target de foco resuelto', {\r\n source: element,\r\n target,\r\n });\r\n\r\n if (!target) {\r\n this.log('no se encontró target enfocable');\r\n return;\r\n }\r\n\r\n target.focus();\r\n\r\n // Selecciona el contenido del input para facilitar la edición inmediata\r\n if (\r\n target instanceof HTMLInputElement ||\r\n target instanceof HTMLTextAreaElement\r\n ) {\r\n this.log('aplicando select() al target enfocable');\r\n target.select();\r\n }\r\n }\r\n\r\n /**\r\n * Resuelve el control interno enfocable de un elemento.\r\n *\r\n * Si el elemento es directamente enfocable (input, button, etc.) lo retorna tal cual.\r\n * De lo contrario busca el primer descendiente que sea un control nativo activo.\r\n *\r\n * NOTA: cada componente de PrimeNG u otras librerías puede renderizar su control\r\n * interno con una estructura diferente. Si un componente no recibe el foco\r\n * correctamente, revisar primero el HTML renderizado en DevTools y ajustar el\r\n * selector de `querySelector` según sea necesario.\r\n */\r\n private resolveFocusableTarget(element: HTMLElement): HTMLElement | null {\r\n if (this.isDirectlyFocusable(element)) return element;\r\n\r\n const nestedFocusable = element.querySelector<HTMLElement>(\r\n 'input:not([disabled]), textarea:not([disabled]), select:not([disabled]), button:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\r\n );\r\n\r\n return nestedFocusable ?? null;\r\n }\r\n\r\n /** Determina si un elemento puede recibir el foco directamente. */\r\n private isDirectlyFocusable(element: HTMLElement): boolean {\r\n if (element.hasAttribute('disabled')) return false;\r\n\r\n const tag = element.tagName.toLowerCase();\r\n if (['input', 'textarea', 'select', 'button'].includes(tag)) return true;\r\n\r\n return element.tabIndex >= 0;\r\n }\r\n\r\n /**\r\n * Traza un mensaje en consola cuando el modo debug está activo.\r\n * Para activar: cambiar `debug = false` a `debug = true`.\r\n */\r\n private log(message: string, data?: unknown) {\r\n if (!this.debug) return;\r\n // console.log('[ArrowNavigationDirective]', message, data ?? '');\r\n }\r\n}\r\n","import { Directive, ElementRef, HostListener } from '@angular/core';\r\n\r\n/**\r\n * Directiva que permite solo la entrada de:\r\n * - Dígitos (0-9)\r\n * - Separadores punto (.)\r\n * - Rango con guión (-)\r\n * - O bien un comodín completo \"*\" que representa \"todos\"\r\n *\r\n * Ejemplos válidos:\r\n * - 1.2.3\r\n * - 4-6\r\n * - 1.3.5-9\r\n * - * (comodín: todos)\r\n *\r\n * Restringe:\r\n * - Letras\r\n * - Espacios\r\n * - Caracteres especiales (salvo \"*\")\r\n * - Doble punto (..), doble guión (--), o combinaciones como (.-)\r\n * - Mezclas de comodín con números (por ejemplo: *1, 1.*)\r\n */\r\n@Directive({\r\n selector: '[appOnlyRangoPattern]',\r\n})\r\nexport class OnlyRangoPatternDirective {\r\n constructor(private el: ElementRef<HTMLInputElement>) {}\r\n\r\n /**\r\n * Expresión regular para permitir caracteres válidos individualmente (tecla por tecla).\r\n */\r\n private keyRegex: RegExp = /^[0-9.\\-]$/;\r\n\r\n /**\r\n * Escucha el evento de teclado y permite únicamente teclas válidas.\r\n * También evita combinaciones inválidas como `..`, `--`, `.1`, etc.\r\n */\r\n @HostListener('keydown', ['$event'])\r\n onKeyDown(event: KeyboardEvent): void {\r\n const input = this.el.nativeElement;\r\n const currentValue = input.value;\r\n const cursorPos = input.selectionStart ?? 0;\r\n const selectionStart = input.selectionStart ?? 0;\r\n const selectionEnd = input.selectionEnd ?? 0;\r\n const hasFullSelection =\r\n selectionStart === 0 && selectionEnd === currentValue.length;\r\n const nextValue =\r\n currentValue.slice(0, cursorPos) +\r\n event.key +\r\n currentValue.slice(cursorPos);\r\n\r\n const allowedKeys = [\r\n 'Backspace',\r\n 'Delete',\r\n 'ArrowLeft',\r\n 'ArrowRight',\r\n 'Tab',\r\n 'Home',\r\n 'End',\r\n ];\r\n\r\n if (allowedKeys.includes(event.key)) return;\r\n\r\n // Si ya hay comodín \"*\" sin selección completa, no se permiten más caracteres\r\n // (solo borrar/navegar). Si todo el texto está seleccionado, se permite\r\n // sobrescribirlo.\r\n if (currentValue === '*' && !hasFullSelection) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n // Permitir comodín \"*\" si el campo está vacío o si todo el contenido\r\n // está seleccionado (para poder reemplazar rápidamente los números).\r\n if (event.key === '*') {\r\n if (!currentValue || hasFullSelection) {\r\n return;\r\n }\r\n\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n if (!this.keyRegex.test(event.key)) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n // No permitir más de un punto o guión seguido, o combinaciones como \".-\", \"-.\", etc.\r\n if (/(\\.\\.|--|-\\.)|(\\.-)/.test(nextValue)) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n // No permitir iniciar con punto o guión\r\n if (cursorPos === 0 && (event.key === '.' || event.key === '-')) {\r\n event.preventDefault();\r\n }\r\n }\r\n\r\n /**\r\n * Previene el pegado de cadenas que no cumplan con la estructura válida.\r\n * Solo permite: número o número separados por punto o guión correctamente.\r\n */\r\n @HostListener('paste', ['$event'])\r\n onPaste(event: ClipboardEvent): void {\r\n const pasted = event.clipboardData?.getData('text') ?? '';\r\n const sanitized = pasted.trim();\r\n\r\n // Permitir comodín completo \"*\" pegado\r\n if (sanitized === '*') {\r\n return;\r\n }\r\n\r\n // Patrón completo de cadena válida: ej. 1.2.3.4-6\r\n const pattern = /^(\\d+(-\\d+)?)(\\.\\d+(-\\d+)?)*$/;\r\n\r\n if (!pattern.test(sanitized)) {\r\n event.preventDefault();\r\n }\r\n }\r\n}\r\n","import { Directive, HostListener } from '@angular/core';\r\n\r\n@Directive({\r\n selector: '[appSelectAllOnFocus]',\r\n})\r\nexport class SelectAllOnFocusDirective {\r\n @HostListener('onFocus', ['$event'])\r\n @HostListener('focus', ['$event'])\r\n selectAll(event: Event): void {\r\n const htmlInput = event.target as HTMLInputElement;\r\n if (htmlInput) {\r\n htmlInput.select();\r\n }\r\n }\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\n\r\nexport const CACHE_KEYS = new InjectionToken<Record<string, string>>(\r\n 'CACHE_KEYS'\r\n);\r\n","import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http';\r\nimport { Injectable, inject, isDevMode } from '@angular/core';\r\nimport { throwError } from 'rxjs';\r\nimport { ErrorModel } from '../../models/src/error.model';\r\nimport { AlertaService } from './alerta.service';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ErrorHandlerService {\r\n _serviceAlerta = inject(AlertaService);\r\n\r\n handleErrorResponse(error: HttpErrorResponse | Error) {\r\n // Si el error ya no es un HttpErrorResponse (por ejemplo, un Error relanzado\r\n // desde otro catch), sólo lo propagamos sin volver a mostrar mensajes.\r\n if (!(error instanceof HttpErrorResponse)) {\r\n if (isDevMode()) {\r\n console.error(\r\n 'Error no HTTP capturado por ErrorHandlerService:',\r\n error,\r\n );\r\n }\r\n\r\n return throwError(() => error);\r\n }\r\n\r\n const err: ErrorModel = error as ErrorModel;\r\n const technicalMessage = `Error status: ${error.status}, Message: ${error.message}, URL: ${error.url}`;\r\n\r\n let userMessage = 'Ha ocurrido un error inesperado.';\r\n\r\n switch (error.status) {\r\n case HttpStatusCode.BadRequest:\r\n userMessage =\r\n 'Solicitud incorrecta (400). Verifica los datos ingresados o validaciones existentes.';\r\n break;\r\n case HttpStatusCode.Unauthorized:\r\n userMessage =\r\n '<b>Acceso no autorizado</b> (401). Por favor inicia sesión.';\r\n break;\r\n case HttpStatusCode.Forbidden:\r\n userMessage = 'No tienes permisos para realizar esta acción (403).';\r\n break;\r\n case HttpStatusCode.NotFound:\r\n userMessage = 'No se encontró el recurso solicitado (404).';\r\n break;\r\n case HttpStatusCode.Conflict: // Capturar error de concurrencia\r\n userMessage =\r\n 'El registro fue modificado por otro usuario. Por favor, actualiza los datos antes de continuar.';\r\n break;\r\n case HttpStatusCode.InternalServerError:\r\n userMessage =\r\n 'Ocurrió un error en el servidor (500). Inténtalo más tarde.';\r\n break;\r\n default:\r\n userMessage = 'Un error inesperado ha ocurrido.';\r\n break;\r\n }\r\n\r\n // Preparar detalle del error para mostrar, priorizando solo la parte \"errors\" del objeto\r\n let errorDetail = '';\r\n\r\n if (error && typeof error.error === 'object' && error.error !== null) {\r\n const anyError: any = error.error as any;\r\n\r\n // Si existe la propiedad \"errors\" (típica de ASP.NET Core ProblemDetails), usar solo esa\r\n const validationErrors = anyError.errors ?? anyError.Errors;\r\n\r\n if (validationErrors && typeof validationErrors === 'object') {\r\n // Formatear las validaciones como texto legible\r\n const parts: string[] = [];\r\n for (const key of Object.keys(validationErrors)) {\r\n const value = validationErrors[key];\r\n const messages = Array.isArray(value)\r\n ? value.join(', ')\r\n : String(value);\r\n parts.push(`${key}: ${messages}`);\r\n }\r\n errorDetail = parts.join(' | ');\r\n } else {\r\n // Si no hay \"errors\", usar el objeto completo serializado\r\n errorDetail = JSON.stringify(anyError);\r\n }\r\n } else {\r\n errorDetail = (error?.error ?? '') as string;\r\n }\r\n\r\n // Mostrar mensaje para el usuario\r\n this._serviceAlerta.alertaHtmlSuccess(\r\n 'Servicio de Errores',\r\n '<i>Código:</i> ' +\r\n err.status +\r\n ' <i>Message:</i> ' +\r\n userMessage +\r\n (errorDetail\r\n ? `<strong class=\"alertMessageDsx\"> (${errorDetail})</strong>`\r\n : ''),\r\n { icon: 'error', icono: '', showConfirmButton: true },\r\n );\r\n\r\n // Imprimir el mensaje técnico\r\n if (isDevMode()) {\r\n console.error(err);\r\n }\r\n\r\n // Retornar el error para continuar con el flujo de manejo de errores\r\n return throwError(() => new Error(technicalMessage));\r\n }\r\n}\r\n","// Interceptor HTTP para manejar autorización y refresco de tokens en peticiones HTTP.\r\n// Permite agregar el token de autorización, manejar errores 401 y refrescar el token automáticamente.\r\nimport {\r\n HttpErrorResponse,\r\n HttpInterceptorFn,\r\n HttpStatusCode,\r\n} from '@angular/common/http';\r\nimport { inject } from '@angular/core';\r\nimport {\r\n BehaviorSubject,\r\n catchError,\r\n EMPTY,\r\n filter,\r\n finalize,\r\n switchMap,\r\n take,\r\n} from 'rxjs';\r\nimport { ServiceResult } from '../models/src/response-http.model';\r\nimport { DataToken } from '../models/src/token.model';\r\nimport { AuthorizeService } from '../services/src/authorize.service';\r\nimport { ErrorHandlerService } from '../services/src/error-handler.service';\r\nimport { SecurityService } from '../services/src/security.service';\r\nimport { SpinnerLoadingService } from '../services/src/spinner-loading.service';\r\nimport { RequestMetricsService } from '../services/src/request-metrics.service';\r\n// Indica si se está realizando un refresh de token\r\nlet isRefreshing = false;\r\n// Subject para emitir el nuevo token tras el refresh\r\nlet refreshTokenSubject = new BehaviorSubject<string | null>(null);\r\n\r\n/**\r\n * Interceptor principal para autorización HTTP.\r\n * - Agrega el token de autorización a cada petición.\r\n * - Muestra/oculta el spinner de carga según el número de peticiones activas.\r\n * - Maneja errores 401 (Unauthorized) refrescando el token si es posible.\r\n * - Repite la petición original tras refrescar el token.\r\n */\r\nexport const httpAuthorizeInterceptor: HttpInterceptorFn = (req, next) => {\r\n const _authorizeService = inject(AuthorizeService);\r\n const _securityService = inject(SecurityService);\r\n const _spinnerService = inject(SpinnerLoadingService);\r\n const _handleErrorService = inject(ErrorHandlerService);\r\n const _metricsService = inject(RequestMetricsService);\r\n const _token = _authorizeService.getToken();\r\n let authReq = req;\r\n\r\n // Si la URL de la petición es inválida, retorna un observable vacío\r\n // Surgio a partir de angular V21\r\n if (!req.url || req.url.trim() === '' || req.url === '/') {\r\n return EMPTY;\r\n }\r\n\r\n // Justo después del console.log(...)\r\n const url = req.url || '';\r\n\r\n const isAssetRequest = url.includes('/assets/') || url.startsWith('mdio/'); // ajusta según tu caso\r\n\r\n if (isAssetRequest) {\r\n // No agregar token ni mostrar spinner para estos recursos\r\n return next(req);\r\n }\r\n\r\n if (_token) {\r\n authReq = req.clone({\r\n setHeaders: { Authorization: `Bearer ${_token}` },\r\n });\r\n }\r\n\r\n //console.log('Interceptor - Petición HTTP iniciada:', req.url);\r\n\r\n // Para depuración: muestra el token agregado\r\n //console.log('Interceptor - Token agregado a la petición:', authReq);\r\n\r\n // Notifica que inicia una petición (el servicio lleva el conteo interno)\r\n _spinnerService.show();\r\n\r\n const start = performance.now();\r\n\r\n // Ejecuta la petición HTTP\r\n return next(authReq).pipe(\r\n // Manejo de errores en la respuesta\r\n catchError((error: HttpErrorResponse) => {\r\n // Si el error es 401 (no autorizado), intenta refrescar el token\r\n if (error.status === HttpStatusCode.Unauthorized) {\r\n const refreshToken = _authorizeService.getTokenRefresh();\r\n // Si no hay refresh token, delega el manejo del error\r\n if (!refreshToken) {\r\n return _handleErrorService.handleErrorResponse(error);\r\n }\r\n\r\n // Si no se está refrescando el token, inicia el proceso de refresh\r\n if (!isRefreshing) {\r\n isRefreshing = true;\r\n // Reiniciar el subject en cada ciclo de refresh para evitar estados cerrados por error\r\n refreshTokenSubject = new BehaviorSubject<string | null>(null);\r\n\r\n // Solicita el refresh del token\r\n return _securityService.tokenRefresh(refreshToken).pipe(\r\n switchMap((response: ServiceResult<DataToken>) => {\r\n // Si el servicio de refresh indica fallo o no retorna datos, mostrar error y cortar flujo\r\n if (!response.isSuccess || !response.data) {\r\n //console.log('Refresh token fallido:', response);\r\n isRefreshing = false;\r\n const refreshError = new HttpErrorResponse({\r\n status: HttpStatusCode.Unauthorized,\r\n statusText: 'Token de refresco inválido',\r\n error: response.message,\r\n url: req.url,\r\n });\r\n\r\n // Notificar a las peticiones en espera que el refresh falló\r\n refreshTokenSubject.error(refreshError);\r\n\r\n // Enviamos el error al manejador centralizado para mostrar el mensaje al usuario\r\n return _handleErrorService.handleErrorResponse(refreshError);\r\n }\r\n\r\n // Refresh exitoso: actualizar tokens y repetir la petición original\r\n isRefreshing = false;\r\n _authorizeService.tokenReload(response.data); // Actualiza el token en el servicio\r\n refreshTokenSubject.next(response.data.token); // Emite el nuevo token\r\n\r\n return next(\r\n req.clone({\r\n setHeaders: {\r\n Authorization: `Bearer ${response.data.token}`,\r\n },\r\n }),\r\n );\r\n }),\r\n catchError((err) => {\r\n isRefreshing = false;\r\n refreshTokenSubject.error(err); // Emite el error en el subject\r\n return _handleErrorService.handleErrorResponse(err);\r\n }),\r\n );\r\n } else {\r\n // Si ya se está refrescando, espera a que el subject emita el nuevo token\r\n return refreshTokenSubject.pipe(\r\n filter((token) => token != null), // Espera a que el token sea válido\r\n take(1), // Toma solo la primera emisión válida\r\n switchMap((token) =>\r\n next(\r\n req.clone({\r\n setHeaders: { Authorization: `Bearer ${token}` },\r\n }),\r\n ),\r\n ),\r\n );\r\n }\r\n }\r\n\r\n // Para otros errores, delega al servicio de manejo de errores\r\n return _handleErrorService.handleErrorResponse(error);\r\n }),\r\n // Al finalizar la petición (éxito o error), actualiza el conteo y oculta el spinner si corresponde\r\n // comentarizar el hide para verificar el spinner en la aplicacion final\r\n finalize(() => {\r\n const duration = performance.now() - start;\r\n _metricsService.registerRequest(duration);\r\n _spinnerService.hide();\r\n }),\r\n );\r\n};\r\n","export type InferCacheKeyType<T extends Record<string, string>> = keyof T;\r\n\r\n/**\r\n * Transforma un tipo de mapa `T` cuyas claves son simbólicas\r\n * y cuyos valores son nombres de propiedades reales de caché,\r\n * a un objeto donde esas propiedades reales son claves booleanas.\r\n *\r\n * @example\r\n * ```ts\r\n * type T = { cliente: 'invalidateCacheCliente' };\r\n * InferCacheOptions<T> // { invalidateCacheCliente: boolean }\r\n * ```\r\n */\r\nexport type InferCacheOptions<T extends Record<string, string>> = {\r\n [K in keyof T as T[K]]: boolean;\r\n};\r\n\r\nexport function createInitialCache<T extends Record<string, string>>(\r\n cacheKeys: T\r\n): {\r\n -readonly [K in keyof T as T[K]]: boolean;\r\n} {\r\n return Object.fromEntries(\r\n Object.values(cacheKeys).map((key) => [key, false])\r\n ) as any;\r\n}\r\n","import { CommonModule } from '@angular/common';\r\nimport { NgModule } from '@angular/core';\r\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\r\nimport { JsonValuesDebujComponent } from '../../components/json/json-values-debuj/json-values-debuj.component';\r\nimport { IconDsxComponent } from '../../components/icon-dsx/icon-dsx.component';\r\n\r\n@NgModule({\r\n declarations: [],\r\n imports: [IconDsxComponent, JsonValuesDebujComponent],\r\n exports: [\r\n CommonModule,\r\n FormsModule,\r\n IconDsxComponent,\r\n JsonValuesDebujComponent,\r\n ReactiveFormsModule,\r\n ],\r\n providers: [],\r\n})\r\nexport class DsxAddToolsModule {}\r\n","import { NgModule } from '@angular/core';\r\n\r\n//PrimeNG\r\nimport { AccordionModule } from 'primeng/accordion';\r\nimport { AutoCompleteModule } from 'primeng/autocomplete';\r\nimport { AutoFocusModule } from 'primeng/autofocus';\r\nimport { AvatarModule } from 'primeng/avatar';\r\nimport { AvatarGroupModule } from 'primeng/avatargroup';\r\nimport { BadgeModule } from 'primeng/badge';\r\nimport { ButtonModule } from 'primeng/button';\r\nimport { CardModule } from 'primeng/card';\r\nimport { CheckboxModule } from 'primeng/checkbox';\r\nimport { ContextMenuModule } from 'primeng/contextmenu';\r\nimport { DatePickerModule } from 'primeng/datepicker';\r\nimport { DialogModule } from 'primeng/dialog';\r\nimport { DividerModule } from 'primeng/divider';\r\nimport { DrawerModule } from 'primeng/drawer';\r\nimport { FieldsetModule } from 'primeng/fieldset';\r\nimport { FileUploadModule } from 'primeng/fileupload';\r\nimport { FloatLabelModule } from 'primeng/floatlabel';\r\nimport { IconFieldModule } from 'primeng/iconfield';\r\nimport { ImageModule } from 'primeng/image';\r\nimport { InputIconModule } from 'primeng/inputicon';\r\nimport { InputMaskModule } from 'primeng/inputmask';\r\nimport { InputNumberModule } from 'primeng/inputnumber';\r\nimport { InputTextModule } from 'primeng/inputtext';\r\nimport { KeyFilterModule } from 'primeng/keyfilter';\r\nimport { KnobModule } from 'primeng/knob';\r\nimport { MenubarModule } from 'primeng/menubar';\r\nimport { MessageModule } from 'primeng/message';\r\nimport { MultiSelectModule } from 'primeng/multiselect';\r\nimport { OrganizationChartModule } from 'primeng/organizationchart';\r\nimport { OverlayBadgeModule } from 'primeng/overlaybadge';\r\nimport { PanelMenuModule } from 'primeng/panelmenu';\r\nimport { PasswordModule } from 'primeng/password';\r\nimport { PickListModule } from 'primeng/picklist';\r\nimport { PopoverModule } from 'primeng/popover';\r\nimport { RadioButtonModule } from 'primeng/radiobutton';\r\nimport { RatingModule } from 'primeng/rating';\r\nimport { RippleModule } from 'primeng/ripple';\r\nimport { ScrollerModule } from 'primeng/scroller';\r\nimport { ScrollPanelModule } from 'primeng/scrollpanel';\r\nimport { SelectModule } from 'primeng/select';\r\nimport { SelectButtonModule } from 'primeng/selectbutton';\r\nimport { SliderModule } from 'primeng/slider';\r\nimport { SpeedDialModule } from 'primeng/speeddial';\r\nimport { SplitButtonModule } from 'primeng/splitbutton';\r\nimport { StepperModule } from 'primeng/stepper';\r\nimport { TableModule } from 'primeng/table';\r\nimport { TabsModule } from 'primeng/tabs';\r\nimport { TagModule } from 'primeng/tag';\r\nimport { TextareaModule } from 'primeng/textarea';\r\nimport { TimelineModule } from 'primeng/timeline';\r\nimport { ToastModule } from 'primeng/toast';\r\nimport { ToggleButtonModule } from 'primeng/togglebutton';\r\nimport { TooltipModule } from 'primeng/tooltip';\r\nimport { TreeModule } from 'primeng/tree';\r\nimport { TreeTableModule } from 'primeng/treetable';\r\n\r\nconst PRIME_NG_MODULES = [\r\n AccordionModule,\r\n AutoCompleteModule,\r\n AutoFocusModule,\r\n AvatarGroupModule,\r\n AvatarModule,\r\n BadgeModule,\r\n ButtonModule,\r\n CardModule,\r\n CheckboxModule,\r\n ContextMenuModule,\r\n DatePickerModule,\r\n DialogModule,\r\n DividerModule,\r\n DrawerModule,\r\n FieldsetModule,\r\n FileUploadModule,\r\n FloatLabelModule,\r\n IconFieldModule,\r\n ImageModule,\r\n InputIconModule,\r\n InputMaskModule,\r\n InputNumberModule,\r\n InputTextModule,\r\n KeyFilterModule,\r\n KnobModule,\r\n MenubarModule,\r\n MessageModule,\r\n MultiSelectModule,\r\n OrganizationChartModule,\r\n OverlayBadgeModule,\r\n PanelMenuModule,\r\n PasswordModule,\r\n PickListModule,\r\n PopoverModule,\r\n RadioButtonModule,\r\n RatingModule,\r\n RippleModule,\r\n ScrollerModule,\r\n ScrollPanelModule,\r\n SelectButtonModule,\r\n SelectModule,\r\n SliderModule,\r\n SpeedDialModule,\r\n SplitButtonModule,\r\n StepperModule,\r\n TableModule,\r\n TabsModule,\r\n TagModule,\r\n TextareaModule,\r\n TimelineModule,\r\n ToastModule,\r\n ToggleButtonModule,\r\n TooltipModule,\r\n TreeModule,\r\n TreeTableModule,\r\n];\r\n\r\n@NgModule({\r\n declarations: [],\r\n imports: [],\r\n exports: [...PRIME_NG_MODULES],\r\n providers: [],\r\n})\r\nexport class PrimeNgModule {}\r\n","import { Pipe, PipeTransform } from '@angular/core';\n\n/**\n * Pipe `joinByPipe`\n *\n * Une los valores de una propiedad de un arreglo de objetos en una sola cadena\n * separado por el `separator` proporcionado.\n *\n * Uso (template):\n * - `items | joinByPipe:'name'` => une la propiedad `name` con `, ` como separador\n * - `items | joinByPipe:'name':'; '` => usa `; ` como separador\n *\n * Ejemplo:\n * const items = [{ name: 'Ana' }, { name: 'Luis' }, { other: 'x' }];\n * // Resultado: 'Ana, Luis'\n *\n * Comportamiento:\n * - Si el arreglo es nulo, indefinido o vacío devuelve `''`.\n * - Si la propiedad no existe en el primer elemento devuelve `''` y registra\n * una advertencia en la consola.\n * - Convierte cada valor a `string`, filtra valores vacíos y los concatena.\n */\n@Pipe({\n name: 'joinBy',\n standalone: true,\n})\nexport class JoinByPipe implements PipeTransform {\n /**\n * Transforma un arreglo de objetos en una cadena unida por `separator` usando\n * la propiedad indicada.\n *\n * @param array - Arreglo de objetos o `null`/`undefined`.\n * @param property - Clave del objeto cuyos valores se van a unir.\n * @param separator - Cadena que separará los valores (por defecto `', '`).\n * @returns Una cadena con los valores unidos o `''` si no hay datos válidos.\n */\n transform<T extends Record<string, any>>(\n array: T[] | null | undefined,\n property: keyof T,\n separator: string = ', ',\n ): string {\n // Si el arreglo está vacío o es nulo/indefinido retornamos cadena vacía\n if (!array?.length) return '';\n\n // Validar que la propiedad exista al menos en el primer elemento\n if (!(property in array[0])) {\n console.warn(\n `JoinByPipe: La propiedad \"${String(property)}\" no existe en el objeto.`,\n );\n return '';\n }\n\n // Convertir valores a string, eliminar vacíos y unir con el separador\n return array\n .map((item) => String(item[property] ?? ''))\n .filter((value) => value.length > 0)\n .join(separator);\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\r\n\r\n@Pipe({\r\n name: 'truncate',\r\n standalone: true,\r\n})\r\nexport class TruncatePipe implements PipeTransform {\r\n /**\r\n * Transforma una cadena de texto truncándola según los parámetros proporcionados.\r\n *\r\n * @param value - La cadena de texto que se desea truncar.\r\n * @param limit - El número máximo de caracteres permitidos. Por defecto es 100. Si no se encuentra un espacio dentro del límite, usa el límite original (15).\r\n * @param completeWords - Si es true, evita cortar palabras a la mitad. Por defecto es false.\r\n * @param ellipsis - La cadena que se añadirá al final del texto truncado. Por defecto es '...'.\r\n * @returns La cadena truncada con el ellipsis añadido, si es necesario.\r\n */\r\n transform(\r\n value: string,\r\n limit: number = 20,\r\n completeWords: boolean = false,\r\n ellipsis: string = '...'\r\n ): string {\r\n // Si el valor es nulo o indefinido, devuelve una cadena vacía para evitar errores.\r\n if (!value) {\r\n return '';\r\n }\r\n\r\n // Si completeWords es true, ajusta el límite para no cortar palabras.\r\n if (completeWords) {\r\n // Encuentra el último espacio dentro del límite para evitar cortar palabras.\r\n limit = value.slice(0, limit).lastIndexOf(' ');\r\n\r\n // Si no se encuentra un espacio dentro del límite, usa el límite original.\r\n if (limit < 0) {\r\n limit = 15; // Valor por defecto si no hay espacios.\r\n }\r\n }\r\n\r\n // Trunca el texto y añade el ellipsis si la longitud del texto supera el límite.\r\n return value.length > limit ? value.slice(0, limit) + ellipsis : value;\r\n }\r\n}\r\n","import { HttpClient } from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { Observable } from 'rxjs';\r\nimport {\r\n ENVIRONMENT,\r\n EnvironmentConfig,\r\n} from '../../injections/environment.token';\r\nimport {\r\n ServiceResult,\r\n ServiceResultVoid,\r\n} from '../../models/src/response-http.model';\r\n\r\n/**\r\n * Servicio genérico para consumir endpoints REST de la API.\r\n *\r\n * @typeParam T Tipo base de la entidad. Puede sobrescribirse por método.\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class EndpointService<T> {\r\n /** Cliente HTTP de Angular utilizado para realizar las peticiones. */\r\n private http = inject(HttpClient);\r\n\r\n /** Configuración de entorno que contiene la URL base de la API. */\r\n private environment: EnvironmentConfig = inject(ENVIRONMENT);\r\n\r\n /**\r\n * Construye la URL completa del endpoint a partir de la configuración de entorno.\r\n *\r\n * @param endpoint Segmento del endpoint (por ejemplo: 'usuarios', 'facturas').\r\n * @returns URL absoluta del endpoint.\r\n */\r\n private getUrl(endpoint: string): string {\r\n return `${this.environment.myAppUrl}api/${endpoint}`;\r\n }\r\n\r\n /**\r\n * Obtiene un listado de recursos del endpoint especificado.\r\n *\r\n * @typeParam TList Tipo de cada elemento del listado (por defecto `T`).\r\n * @param endpoint Segmento del endpoint (sin la parte de `api/`).\r\n * @param invalidateCache Indica si se invalida la caché del lado del servidor.\r\n * @returns Observable con un arreglo de elementos del tipo `TList`.\r\n */\r\n list<TList = T>(\r\n endpoint: string,\r\n invalidateCache: boolean = false,\r\n ): Observable<TList[]> {\r\n return this.http.get<TList[]>(\r\n `${this.getUrl(endpoint)}/listar/${invalidateCache}`,\r\n );\r\n }\r\n\r\n /**\r\n * Obtiene un recurso por su identificador.\r\n *\r\n * @typeParam TEdit Tipo del recurso retornado (por defecto `T`).\r\n * @param endpoint Segmento del endpoint (sin la parte de `api/`).\r\n * @param id Identificador del recurso a recuperar.\r\n * @returns Observable con el elemento del tipo `TEdit`.\r\n */\r\n edit<TEdit = T>(endpoint: string, id: number): Observable<TEdit> {\r\n return this.http.get<TEdit>(`${this.getUrl(endpoint)}/get-id/${id}`);\r\n }\r\n\r\n /**\r\n * Crea o actualiza un recurso en el endpoint especificado.\r\n *\r\n * @typeParam TSave Tipo del payload enviado al backend (por defecto `T`).\r\n * @typeParam TResponse Tipo de la entidad en la respuesta (por defecto `T`).\r\n * @param endpoint Segmento del endpoint (sin la parte de `api/`).\r\n * @param values Objeto con los datos del recurso a guardar.\r\n * @returns Observable con el resultado del servicio que envuelve `TResponse`.\r\n */\r\n save<TSave = T, TResponse = T>(\r\n endpoint: string,\r\n values: TSave,\r\n ): Observable<ServiceResult<TResponse>> {\r\n return this.http.put<ServiceResult<TResponse>>(\r\n `${this.getUrl(endpoint)}/save`,\r\n values,\r\n );\r\n }\r\n\r\n /**\r\n * Elimina un recurso del endpoint especificado.\r\n *\r\n * @param endpoint Segmento del endpoint (sin la parte de `api/`).\r\n * @param id Identificador del recurso a eliminar (numérico o textual).\r\n * @param softDelete Indica si la eliminación es lógica (por defecto) o física.\r\n * @returns Observable con el modelo de respuesta HTTP genérico.\r\n */\r\n delete(\r\n endpoint: string,\r\n id: number | string,\r\n softDelete: boolean = true,\r\n ): Observable<ServiceResultVoid> {\r\n return this.http.delete<ServiceResultVoid>(\r\n `${this.getUrl(endpoint)}/delete/${id}/${softDelete}`,\r\n );\r\n }\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { EndpointService } from './endpoint.service';\r\n\r\n/**\r\n * Clase base para servicios CRUD tipados.\r\n *\r\n * @typeParam TBase Modelo base que representa la entidad principal.\r\n * @typeParam TEdit Modelo de respuesta para la operación de edición/consulta por id.\r\n * @typeParam TSave Modelo de entrada para guardar (create/update).\r\n * @typeParam TList Modelo de cada elemento del listado.\r\n * @typeParam TDelete Tipo del identificador usado para eliminar (number o string).\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport abstract class BaseCRUDService<\r\n TBase,\r\n TEdit = TBase,\r\n TSave = TBase,\r\n TList = TBase,\r\n TDelete extends string | number = number,\r\n> {\r\n /** Segmento del endpoint (sin prefijo api/). */\r\n protected abstract endpoint: string;\r\n\r\n /** Servicio HTTP base para operaciones REST. */\r\n protected readonly _endpointService = inject(EndpointService);\r\n\r\n /**\r\n * Obtiene el listado de registros.\r\n * @param invalidateCache Si es true, solicita invalidar caché en backend.\r\n */\r\n list(invalidateCache: boolean = false) {\r\n return this._endpointService.list<TList>(this.endpoint, invalidateCache);\r\n }\r\n\r\n /**\r\n * Obtiene un registro por id para edición.\r\n * @param id Identificador numérico del registro.\r\n */\r\n edit(id: number) {\r\n return this._endpointService.edit<TEdit>(this.endpoint, id);\r\n }\r\n\r\n /**\r\n * Guarda un registro (creación o actualización).\r\n * @param values Payload tipado para persistir.\r\n */\r\n save(values: TSave) {\r\n return this._endpointService.save<TSave, TBase>(this.endpoint, values);\r\n }\r\n\r\n /**\r\n * Elimina un registro por identificador.\r\n * @param value Identificador del registro a eliminar.\r\n * @param softDelete Si es true, realiza eliminación lógica.\r\n */\r\n delete(value: TDelete, softDelete: boolean = true) {\r\n return this._endpointService.delete(this.endpoint, value, softDelete);\r\n }\r\n}\r\n","import { inject, Injectable, signal } from '@angular/core';\r\nimport { CACHE_KEYS } from '../../injections/cache.token';\r\nimport { InferCacheOptions } from '../../models/src/cache.types';\r\nimport { AlertaService } from './alerta.service';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\n\r\n/**\r\n * Servicio genérico para el manejo de caché reactivo basado en claves definidas por el consumidor.\r\n *\r\n * Este servicio utiliza señales (`signal`) para almacenar el estado de invalidación de caché\r\n * y permite marcar ciertas entradas como inválidas mediante una llamada a `invalidate`.\r\n *\r\n * ---\r\n * ## Uso básico\r\n * Si no se especifica el tipo genérico `T`, el servicio funcionará con un mapa genérico\r\n * `Record<string, string>` sin autocompletado.\r\n *\r\n * ```ts\r\n * const cacheService = inject(CacheService);\r\n * cacheService.invalidate(['cualquierClave']);\r\n * ```\r\n *\r\n * ---\r\n * ## Uso tipado (recomendado)\r\n * 1. Definir las claves de caché en el proyecto consumidor:\r\n * ```ts\r\n * export const INITIAL_CACHE_KEYS = {\r\n * cliente: 'invalidateCacheCliente',\r\n * empresa: 'invalidateCacheEmpresa'\r\n * } as const;\r\n *\r\n * export type ValueCacheKeys = typeof INITIAL_CACHE_KEYS;\r\n * ```\r\n *\r\n * 2. Proveer estas claves en `AppModule` o un módulo raíz:\r\n * ```ts\r\n * providers: [\r\n * { provide: CACHE_KEYS, useValue: INITIAL_CACHE_KEYS }\r\n * ]\r\n * ```\r\n *\r\n * 3. Inyectar el servicio especificando el tipo:\r\n * ```ts\r\n * const cacheService = inject<CacheService<ValueCacheKeys>>(CacheService);\r\n *\r\n * cacheService.options.invalidateCacheCliente; // ✅ boolean con autocompletado\r\n * cacheService.invalidate(['cliente']); // marca como invalidado\r\n * ```\r\n *\r\n * @typeParam T - Objeto con claves simbólicas (`keyof T`) como `cliente`, `empresa`,\r\n * y valores string literales usados como claves reales de caché.\r\n * Por defecto: `Record<string, string>`.\r\n */\r\nexport class CacheService<\r\n T extends Record<string, string> = Record<string, string>,\r\n> {\r\n /**\r\n * Mapa de claves simbólicas a claves reales de caché.\r\n * Se inyecta desde el proyecto consumidor mediante `CACHE_KEYS`.\r\n */\r\n private keys = inject(CACHE_KEYS) as T;\r\n\r\n /**\r\n * Servicio de alerta utilizado para mostrar notificaciones al usuario.\r\n */\r\n private alert = inject(AlertaService);\r\n\r\n /**\r\n * Estado reactivo que contiene un objeto donde cada propiedad (clave real de caché)\r\n * tiene un valor booleano que indica si el caché ha sido invalidado (`true`)\r\n * o sigue siendo válido (`false`).\r\n *\r\n * Este estado es tipado automáticamente en función de los valores de `T`.\r\n */\r\n private _options = signal<InferCacheOptions<T>>(\r\n Object.fromEntries(\r\n Object.values(this.keys).map((k) => [k, false]),\r\n ) as InferCacheOptions<T>,\r\n );\r\n\r\n /**\r\n * Obtiene el estado actual del caché.\r\n * Cada propiedad representa una clave real de caché con su valor booleano.\r\n */\r\n get options(): InferCacheOptions<T> {\r\n return this._options();\r\n }\r\n\r\n /**\r\n * Invalida una o más claves simbólicas, marcando su correspondiente\r\n * propiedad de caché como `true` (invalidada).\r\n *\r\n * @param keysToInvalidate - Lista de claves simbólicas (`keyof T`) a invalidar.\r\n *\r\n * @example\r\n * ```ts\r\n * cacheService.invalidate(['cliente', 'empresa']);\r\n * ```\r\n */\r\n invalidate(keysToInvalidate: (keyof T)[] | null = null): void {\r\n if (!keysToInvalidate?.length) return;\r\n\r\n const current: InferCacheOptions<T> = { ...this._options() };\r\n\r\n keysToInvalidate.forEach((key) => {\r\n const prop = this.keys[key] as keyof InferCacheOptions<T>;\r\n current[prop] = true as InferCacheOptions<T>[typeof prop];\r\n });\r\n\r\n this._options.set(current);\r\n\r\n this.alert.toastrAlerts(\r\n 2,\r\n 'Estado',\r\n 'Datos actualizados (cache).',\r\n 2,\r\n 1000,\r\n );\r\n }\r\n}\r\n","import { InjectionToken, Provider } from '@angular/core';\r\nimport { CacheService } from './cache.service';\r\n\r\nexport function createTypedCacheProvider<T extends Record<string, string>>(\r\n tokenName: string\r\n): { token: InjectionToken<CacheService<T>>; provider: Provider } {\r\n const token = new InjectionToken<CacheService<T>>(tokenName);\r\n\r\n const provider: Provider = {\r\n provide: token,\r\n useFactory: () => new CacheService<T>(),\r\n deps: [],\r\n };\r\n\r\n return { token, provider };\r\n}\r\n","import { HttpClient } from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport {\r\n ENVIRONMENT,\r\n EnvironmentConfig,\r\n} from '../../injections/environment.token';\r\nimport { Observable } from 'rxjs';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class DteService {\r\n /** Servicio HttpClient para realizar peticiones HTTP */\r\n private http = inject(HttpClient);\r\n\r\n /**\r\n * Configuración del entorno inyectada mediante el token ENVIRONMENT.\r\n * La validación se realiza automáticamente al usar provideEnvironment().\r\n */\r\n private environment: EnvironmentConfig = inject(ENVIRONMENT);\r\n\r\n /** URL base de la API JWT construida desde la configuración del entorno */\r\n private SeguridadITApi: string = `${this.environment.SeguridadITApiUrl}api/dte`;\r\n\r\n pdfDTE(UUID: string): Observable<Blob> {\r\n // Realiza una solicitud POST al endpoint de refresco de token\r\n return this.http.get<Blob>(`${this.SeguridadITApi}/pdf-dte/${UUID}`, {\r\n responseType: 'blob' as 'json',\r\n });\r\n }\r\n}\r\n","export function containsFile(obj: any): boolean {\r\n for (const key in obj) {\r\n const value = obj[key];\r\n\r\n if (value instanceof File || value instanceof Blob) {\r\n return true;\r\n }\r\n\r\n if (value instanceof FileList) {\r\n return true;\r\n }\r\n\r\n if (typeof value === 'object' && value !== null) {\r\n if (containsFile(value)) {\r\n return true;\r\n }\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport function toFormData(\r\n data: any,\r\n formData: FormData = new FormData(),\r\n parentKey?: string,\r\n): FormData {\r\n Object.keys(data).forEach((key) => {\r\n const value = data[key];\r\n const formKey = parentKey ? `${parentKey}.${key}` : key;\r\n\r\n if (value === null || value === undefined) return;\r\n\r\n if (value instanceof File || value instanceof Blob) {\r\n formData.append(formKey, value);\r\n return;\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n value.forEach((v, i) => {\r\n toFormData(v, formData, `${formKey}[${i}]`);\r\n });\r\n return;\r\n }\r\n\r\n if (typeof value === 'object') {\r\n toFormData(value, formData, formKey);\r\n return;\r\n }\r\n\r\n formData.append(formKey, String(value));\r\n });\r\n\r\n return formData;\r\n}\r\n","import {\r\n HttpClient,\r\n HttpHeaders,\r\n HttpParams,\r\n HttpResponse,\r\n} from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { Observable } from 'rxjs';\r\nimport { toFormData } from '../../utils/src/form-data.util';\r\n\r\ntype HttpParamValue = string | number | boolean | Date | null | undefined;\r\ntype HttpParamsRecord = Record<string, HttpParamValue | HttpParamValue[]>;\r\n\r\nexport interface BlobRequestOptions {\r\n params?: HttpParamsRecord | HttpParams;\r\n headers?: HttpHeaders | Record<string, string | string[]>;\r\n withCredentials?: boolean;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\n/**\r\n * HttpHelperService\r\n *\r\n * Servicio diseñado para endpoints que usan [FromForm] en ASP.NET Core.\r\n * Siempre convierte el objeto a FormData, independientemente de si contiene\r\n * un archivo o no. Si el campo de tipo File/Blob/FileList es null o undefined,\r\n * simplemente se omite del FormData.\r\n *\r\n * Ejemplo sin archivo:\r\n *\r\n * this.api.post('puesto/guardar', { puestoId: 1, nombre: 'Admin' });\r\n *\r\n * Ejemplo con archivo (el campo puede ser null si no se seleccionó):\r\n *\r\n * this.api.post('puesto/cargar-funciones', {\r\n * puestoId: 1,\r\n * puestoNombre: 'Administrador',\r\n * file: this.file // puede ser null\r\n * });\r\n */\r\nexport class HttpHelpersService {\r\n private readonly http = inject(HttpClient);\r\n\r\n /**\r\n * POST orientado a endpoints `[FromForm]` en backend (ASP.NET Core u otros).\r\n *\r\n * Convierte automáticamente `data` a `FormData`, por lo que permite enviar\r\n * campos simples y archivos (`File`, `Blob`, `FileList`) en una sola llamada.\r\n *\r\n * Casos de uso comunes:\r\n * - Crear/actualizar recursos con adjuntos.\r\n * - Subir archivos junto con metadata (id, nombre, observaciones, etc.).\r\n * - Mantener un único método de POST para formularios multipart.\r\n *\r\n * @typeParam T Tipo de respuesta esperada del backend.\r\n * @param url Endpoint relativo o absoluto.\r\n * @param data Objeto plano que se transformará a `FormData`.\r\n * @returns `Observable<T>` con la respuesta del backend.\r\n *\r\n * @example\r\n * this.httpHelpers.postForm<{ ok: boolean }>('documentos/subir', {\r\n * documentoId: 15,\r\n * descripcion: 'Contrato firmado',\r\n * archivo: this.archivoSeleccionado // File | null\r\n * });\r\n */\r\n postForm<T>(url: string, data: Record<string, unknown>): Observable<T> {\r\n return this.http.post<T>(url, toFormData(data));\r\n }\r\n\r\n /**\r\n * PUT orientado a endpoints `[FromForm]` en backend (ASP.NET Core u otros).\r\n *\r\n * Equivalente a `postForm`, pero usando el verbo HTTP PUT para actualizar recursos existentes.\r\n *\r\n * @typeParam T Tipo de respuesta esperada del backend.\r\n * @param url Endpoint relativo o absoluto.\r\n * @param data Objeto plano que se transformará a `FormData`.\r\n * @returns `Observable<T>` con la respuesta del backend.\r\n *\r\n * @example\r\n * this.httpHelpers.putForm<{ ok: boolean }>('documentos/actualizar/15', {\r\n * documentoId: 15,\r\n * descripcion: 'Contrato actualizado',\r\n * archivo: this.archivoSeleccionado // File | null\r\n * });\r\n */\r\n putForm<T>(url: string, data: Record<string, unknown>): Observable<T> {\r\n return this.http.put<T>(url, toFormData(data));\r\n }\r\n\r\n /**\r\n * GET para descarga de archivos en formato Blob.\r\n * Útil cuando solo se necesita el contenido del archivo.\r\n */\r\n getBlob(url: string, options: BlobRequestOptions = {}): Observable<Blob> {\r\n return this.http.get(url, {\r\n responseType: 'blob',\r\n params: this.toHttpParams(options.params),\r\n headers: options.headers,\r\n withCredentials: options.withCredentials,\r\n });\r\n }\r\n\r\n /**\r\n * GET para descarga de archivos devolviendo HttpResponse completo.\r\n * Útil para leer headers como `content-disposition` (nombre de archivo) o status.\r\n *\r\n * Consideraciones de backend:\r\n * - Validar `fileName`/id en route params antes de construir la ruta física.\r\n * - Definir query params opcionales (ej. versión, idioma, tenant) y documentarlos.\r\n * - Si se requiere cookie/sesión, habilitar `withCredentials` en frontend y CORS en backend.\r\n */\r\n getBlobResponse(\r\n url: string,\r\n options: BlobRequestOptions = {},\r\n ): Observable<HttpResponse<Blob>> {\r\n return this.http.get(url, {\r\n responseType: 'blob',\r\n observe: 'response',\r\n params: this.toHttpParams(options.params),\r\n headers: options.headers,\r\n withCredentials: options.withCredentials,\r\n });\r\n }\r\n\r\n private toHttpParams(\r\n params?: BlobRequestOptions['params'],\r\n ): HttpParams | undefined {\r\n if (!params) {\r\n return undefined;\r\n }\r\n\r\n if (params instanceof HttpParams) {\r\n return params;\r\n }\r\n\r\n let httpParams = new HttpParams();\r\n\r\n for (const [key, value] of Object.entries(params)) {\r\n if (value === null || value === undefined) {\r\n continue;\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n for (const item of value) {\r\n if (item === null || item === undefined) {\r\n continue;\r\n }\r\n httpParams = httpParams.append(key, this.normalizeParamValue(item));\r\n }\r\n continue;\r\n }\r\n\r\n httpParams = httpParams.set(key, this.normalizeParamValue(value));\r\n }\r\n\r\n return httpParams;\r\n }\r\n\r\n private normalizeParamValue(\r\n value: Exclude<HttpParamValue, null | undefined>,\r\n ): string {\r\n if (value instanceof Date) {\r\n return value.toISOString();\r\n }\r\n\r\n return String(value);\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\n\r\nfunction pickByKeys<T extends object, K extends keyof T>(\r\n source: T,\r\n keys: readonly K[],\r\n): Pick<T, K> {\r\n const result = {} as Pick<T, K>;\r\n\r\n for (const key of keys) {\r\n result[key] = source[key];\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction tryParseDateValue(value: unknown): number | null {\r\n if (value instanceof Date) {\r\n const time = value.getTime();\r\n\r\n return Number.isNaN(time) ? null : time;\r\n }\r\n\r\n if (typeof value === 'string' || typeof value === 'number') {\r\n const parsed = new Date(value);\r\n const time = parsed.getTime();\r\n\r\n return Number.isNaN(time) ? null : time;\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction normalizeComparableValue(base: unknown, current: unknown): unknown {\r\n const baseDateValue = tryParseDateValue(base);\r\n\r\n if (baseDateValue !== null) {\r\n const currentDateValue = tryParseDateValue(current);\r\n\r\n return currentDateValue ?? current;\r\n }\r\n\r\n return current;\r\n}\r\n\r\nfunction normalizeBaseEntity<TBase extends object>(\r\n baseValue: TBase,\r\n keys?: ReadonlyArray<keyof TBase>,\r\n): Partial<Record<keyof TBase, unknown>> {\r\n const normalized: Partial<Record<keyof TBase, unknown>> = {};\r\n const selectedKeys = keys ?? (Object.keys(baseValue) as Array<keyof TBase>);\r\n\r\n for (const key of selectedKeys) {\r\n const base = (baseValue as Record<string, unknown>)[key as string];\r\n\r\n normalized[key] = normalizeComparableValue(base, base);\r\n }\r\n\r\n return normalized;\r\n}\r\n\r\nfunction normalizeRawEntityAgainstBase<TBase extends object>(\r\n baseValue: TBase,\r\n rawValue: MasterDetailRawEntity<TBase>,\r\n keys?: ReadonlyArray<keyof TBase>,\r\n useBaseValueForNullish = true,\r\n): Partial<Record<keyof TBase, unknown>> {\r\n const coerceByBaseType = (base: unknown, current: unknown): unknown => {\r\n if (typeof base === 'number') {\r\n if (typeof current === 'string' && current.trim() !== '') {\r\n const normalizedText = current.trim();\r\n const direct = Number(normalizedText);\r\n\r\n if (!Number.isNaN(direct)) return direct;\r\n\r\n const commaDecimal = Number(normalizedText.replace(',', '.'));\r\n\r\n if (!Number.isNaN(commaDecimal)) return commaDecimal;\r\n\r\n const noSpaces = normalizedText.replace(/\\s+/g, '');\r\n const noThousandsDots = Number(\r\n noSpaces.replace(/\\./g, '').replace(',', '.'),\r\n );\r\n\r\n if (!Number.isNaN(noThousandsDots)) return noThousandsDots;\r\n\r\n return current;\r\n }\r\n\r\n return current;\r\n }\r\n\r\n if (typeof base === 'boolean') {\r\n if (typeof current === 'string') {\r\n const lowered = current.trim().toLowerCase();\r\n\r\n if (lowered === 'true') return true;\r\n if (lowered === 'false') return false;\r\n }\r\n\r\n return current;\r\n }\r\n\r\n if (base instanceof Date) {\r\n if (current instanceof Date) return current;\r\n\r\n if (typeof current === 'string' || typeof current === 'number') {\r\n const parsed = new Date(current);\r\n\r\n return Number.isNaN(parsed.getTime()) ? current : parsed;\r\n }\r\n\r\n return current;\r\n }\r\n\r\n if (typeof base === 'string') {\r\n if (current === null || current === undefined) return current;\r\n\r\n return typeof current === 'string' ? current : String(current);\r\n }\r\n\r\n return current;\r\n };\r\n\r\n const normalized: Partial<Record<keyof TBase, unknown>> = {};\r\n const selectedKeys = keys ?? (Object.keys(baseValue) as Array<keyof TBase>);\r\n\r\n for (const key of selectedKeys) {\r\n const base = (baseValue as Record<string, unknown>)[key as string];\r\n const current = rawValue[key as string];\r\n const isNullish = current === null || current === undefined;\r\n const isEmptyString = typeof current === 'string' && current.trim() === '';\r\n const treatEmptyAsNullish = isEmptyString && typeof base !== 'string';\r\n const shouldUseBase =\r\n useBaseValueForNullish && (isNullish || treatEmptyAsNullish);\r\n\r\n normalized[key] = shouldUseBase ? base : coerceByBaseType(base, current);\r\n\r\n normalized[key] = normalizeComparableValue(base, normalized[key]);\r\n }\r\n\r\n return normalized;\r\n}\r\n\r\n/**\r\n * Estado maestro-detalle usado por el tracker.\r\n */\r\nexport interface MasterDetailState<TMaster, TDetail> {\r\n /** Entidad principal (cabecera o maestro). */\r\n master: TMaster;\r\n /** Coleccion de entidades detalle asociadas al maestro. */\r\n detail: TDetail[];\r\n}\r\n\r\n/**\r\n * Tipo crudo para valores provenientes de formularios.\r\n */\r\nexport type MasterDetailRawEntity<TBase extends object> = Partial<\r\n Record<keyof TBase, unknown>\r\n> &\r\n Record<string, unknown>;\r\n\r\n/**\r\n * Opciones simplificadas para comparar estado base vs valores crudos de formulario.\r\n */\r\nexport interface MasterDetailSimpleFormOptions<\r\n TBaseMaster extends object,\r\n TBaseDetail extends object,\r\n> {\r\n /** Campos del maestro a seguir. */\r\n masterKeys?: ReadonlyArray<keyof TBaseMaster>;\r\n\r\n /** Campos del detalle a seguir. */\r\n detailKeys?: ReadonlyArray<keyof TBaseDetail>;\r\n\r\n /**\r\n * Si es `true` (default), cuando el valor actual sea `null` o `undefined`\r\n * se usa el valor base para evitar falsos positivos en formularios.\r\n */\r\n useBaseValueForNullish?: boolean;\r\n}\r\n\r\nexport interface MasterDetailDifference {\r\n scope: 'master' | 'detail';\r\n path: string;\r\n baseValue: unknown;\r\n currentValue: unknown;\r\n}\r\n\r\n/**\r\n * Resultado detallado de comparacion entre estado inicial y actual.\r\n */\r\nexport interface MasterDetailChangeResult {\r\n hasChanges: boolean;\r\n masterChanged: boolean;\r\n detailChanged: boolean;\r\n firstDifference: MasterDetailDifference | null;\r\n}\r\n\r\n/**\r\n * Tracker simplificado para comparar estado base vs `getRawValue()`.\r\n */\r\nexport interface MasterDetailSimpleFormTracker<\r\n TBaseMaster extends object,\r\n TBaseDetail extends object,\r\n> {\r\n /**\r\n * Indica si existe cualquier cambio entre el estado inicial y el actual.\r\n */\r\n hasChanges: (\r\n currentState: MasterDetailState<\r\n MasterDetailRawEntity<TBaseMaster>,\r\n MasterDetailRawEntity<TBaseDetail>\r\n >,\r\n ) => boolean;\r\n\r\n /**\r\n * Retorna un desglose de cambios por seccion (maestro/detalle).\r\n */\r\n getChanges: (\r\n currentState: MasterDetailState<\r\n MasterDetailRawEntity<TBaseMaster>,\r\n MasterDetailRawEntity<TBaseDetail>\r\n >,\r\n ) => MasterDetailChangeResult;\r\n\r\n /**\r\n * Reemplaza el estado base de comparacion con uno nuevo.\r\n */\r\n reset: (state: MasterDetailState<TBaseMaster, TBaseDetail>) => void;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\n/**\r\n * Servicio utilitario para detectar cambios en formularios o vistas\r\n * maestro-detalle sin acoplarse a una estructura de dominio concreta.\r\n */\r\nexport class MasterDetailChangeService {\r\n private static findFirstDifference(\r\n leftValue: unknown,\r\n rightValue: unknown,\r\n path = 'root',\r\n ): { path: string; leftValue: unknown; rightValue: unknown } | null {\r\n if (leftValue instanceof Date && rightValue instanceof Date) {\r\n return leftValue.getTime() === rightValue.getTime()\r\n ? null\r\n : { path, leftValue, rightValue };\r\n }\r\n\r\n if (Array.isArray(leftValue) && Array.isArray(rightValue)) {\r\n if (leftValue.length !== rightValue.length) {\r\n return {\r\n path: `${path}.length`,\r\n leftValue: leftValue.length,\r\n rightValue: rightValue.length,\r\n };\r\n }\r\n\r\n for (let index = 0; index < leftValue.length; index += 1) {\r\n const difference = MasterDetailChangeService.findFirstDifference(\r\n leftValue[index],\r\n rightValue[index],\r\n `${path}[${index}]`,\r\n );\r\n\r\n if (difference) {\r\n return difference;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n if (\r\n leftValue != null &&\r\n rightValue != null &&\r\n typeof leftValue === 'object' &&\r\n typeof rightValue === 'object'\r\n ) {\r\n const leftKeys = Object.keys(leftValue);\r\n const rightKeys = Object.keys(rightValue);\r\n\r\n if (leftKeys.length !== rightKeys.length) {\r\n return {\r\n path: `${path}.__keys__`,\r\n leftValue: leftKeys,\r\n rightValue: rightKeys,\r\n };\r\n }\r\n\r\n for (const key of leftKeys) {\r\n const difference = MasterDetailChangeService.findFirstDifference(\r\n (leftValue as Record<string, unknown>)[key],\r\n (rightValue as Record<string, unknown>)[key],\r\n `${path}.${key}`,\r\n );\r\n\r\n if (difference) {\r\n return difference;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n return Object.is(leftValue, rightValue)\r\n ? null\r\n : { path, leftValue, rightValue };\r\n }\r\n\r\n /**\r\n * Version simplificada para formularios: recibe `getRawValue()` directamente\r\n * y compara por claves sin requerir mapeo manual en el consumidor.\r\n */\r\n createSimpleFormTracker<\r\n TBaseMaster extends object,\r\n TBaseDetail extends object,\r\n >(\r\n initialState: MasterDetailState<TBaseMaster, TBaseDetail>,\r\n options?: MasterDetailSimpleFormOptions<TBaseMaster, TBaseDetail>,\r\n ): MasterDetailSimpleFormTracker<TBaseMaster, TBaseDetail> {\r\n const defaultMasterKeys = Object.keys(initialState.master) as Array<\r\n keyof TBaseMaster\r\n >;\r\n const defaultDetailKeys =\r\n initialState.detail.length > 0\r\n ? (Object.keys(initialState.detail[0]) as Array<keyof TBaseDetail>)\r\n : ([] as Array<keyof TBaseDetail>);\r\n\r\n const masterKeys = options?.masterKeys ?? defaultMasterKeys;\r\n const detailKeys = options?.detailKeys ?? defaultDetailKeys;\r\n const useBaseValueForNullish = options?.useBaseValueForNullish ?? true;\r\n\r\n let initialMaster = structuredClone(initialState.master);\r\n let initialDetail = structuredClone(initialState.detail);\r\n\r\n const buildComparisonPayload = (\r\n currentState: MasterDetailState<\r\n MasterDetailRawEntity<TBaseMaster>,\r\n MasterDetailRawEntity<TBaseDetail>\r\n >,\r\n ) => {\r\n const normalizedBaseMaster = normalizeBaseEntity(\r\n initialMaster,\r\n masterKeys,\r\n );\r\n const normalizedCurrentMaster = normalizeRawEntityAgainstBase(\r\n initialMaster,\r\n currentState.master,\r\n masterKeys,\r\n useBaseValueForNullish,\r\n );\r\n\r\n const normalizedBaseDetail = initialDetail.map((item) =>\r\n normalizeBaseEntity(item, detailKeys),\r\n );\r\n\r\n const normalizedCurrentDetail = currentState.detail.map((item, index) =>\r\n normalizeRawEntityAgainstBase(\r\n initialDetail[index] ?? ({} as TBaseDetail),\r\n item,\r\n detailKeys,\r\n useBaseValueForNullish,\r\n ),\r\n );\r\n\r\n return {\r\n normalizedBaseMaster,\r\n normalizedCurrentMaster,\r\n normalizedBaseDetail,\r\n normalizedCurrentDetail,\r\n };\r\n };\r\n\r\n const resolveChanges = (\r\n currentState: MasterDetailState<\r\n MasterDetailRawEntity<TBaseMaster>,\r\n MasterDetailRawEntity<TBaseDetail>\r\n >,\r\n ): MasterDetailChangeResult => {\r\n const {\r\n normalizedBaseMaster,\r\n normalizedCurrentMaster,\r\n normalizedBaseDetail,\r\n normalizedCurrentDetail,\r\n } = buildComparisonPayload(currentState);\r\n\r\n const masterDifference = MasterDetailChangeService.findFirstDifference(\r\n normalizedBaseMaster,\r\n normalizedCurrentMaster,\r\n 'master',\r\n );\r\n\r\n const detailDifference = MasterDetailChangeService.findFirstDifference(\r\n normalizedBaseDetail,\r\n normalizedCurrentDetail,\r\n 'detail',\r\n );\r\n\r\n return {\r\n hasChanges: masterDifference !== null || detailDifference !== null,\r\n masterChanged: masterDifference !== null,\r\n detailChanged: detailDifference !== null,\r\n firstDifference: masterDifference\r\n ? {\r\n scope: 'master',\r\n path: masterDifference.path,\r\n baseValue: masterDifference.leftValue,\r\n currentValue: masterDifference.rightValue,\r\n }\r\n : detailDifference\r\n ? {\r\n scope: 'detail',\r\n path: detailDifference.path,\r\n baseValue: detailDifference.leftValue,\r\n currentValue: detailDifference.rightValue,\r\n }\r\n : null,\r\n };\r\n };\r\n\r\n return {\r\n hasChanges: (currentState) => resolveChanges(currentState).hasChanges,\r\n getChanges: (currentState) => resolveChanges(currentState),\r\n\r\n reset: (state: MasterDetailState<TBaseMaster, TBaseDetail>) => {\r\n initialMaster = structuredClone(state.master);\r\n initialDetail = structuredClone(state.detail);\r\n },\r\n };\r\n }\r\n}\r\n","import { HttpHeaders, HttpResponse } from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport {\r\n AbstractControl,\r\n FormBuilder,\r\n FormControl,\r\n FormGroup,\r\n ValidatorFn,\r\n} from '@angular/forms';\r\nimport { Router } from '@angular/router';\r\nimport moment from 'moment-timezone';\r\nimport {\r\n auditTime,\r\n debounceTime,\r\n distinctUntilChanged,\r\n merge,\r\n Observable,\r\n Subject,\r\n takeUntil,\r\n} from 'rxjs';\r\nimport {\r\n ENVIRONMENT,\r\n EnvironmentConfig,\r\n} from '../../injections/environment.token';\r\nimport { ResponseHttpModel, ServiceResult } from '../../models';\r\nimport {\r\n FechasConversion,\r\n FilterOption,\r\n TipoFechaConversion,\r\n} from '../../models/src/extensions.model';\r\nimport {\r\n FieldConfig,\r\n FormRule,\r\n ReactiveForm,\r\n TypedForm,\r\n} from '../../models/src/field-config.model';\r\nimport { AlertaService } from './alerta.service';\r\n\r\ninterface CreateTypedFormOptions {\r\n /**\r\n * Si es true, deshabilita por defecto los controles que no tengan\r\n * la propiedad \"disabled\" explícitamente definida en su configuración.\r\n */\r\n disableUnassignedControls?: boolean;\r\n}\r\n\r\ntype DateInput = string | Date | null | undefined;\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class UtilityAddService {\r\n private _serviceAlerta = inject(AlertaService);\r\n private environment: EnvironmentConfig = inject(ENVIRONMENT);\r\n private _router = inject(Router);\r\n\r\n /**\r\n * Convierte una fecha a una cadena de texto formateada según la zona horaria especificada.\r\n *\r\n * @param {string | Date} fecha - La fecha que se desea convertir. Puede ser una cadena de texto o un objeto Date.\r\n * @returns {string | null} - La fecha formateada en la zona horaria especificada o null si la fecha es null.\r\n */\r\n convertirFechaSegunZonaHoraria(fecha: DateInput): string | null {\r\n if (!fecha) return null; // Comprobamos si la fecha es null o undefined\r\n // Cambia esto a la zona horaria que desees\r\n const zonaHoraria = 'America/Guatemala';\r\n return moment(fecha).tz(zonaHoraria).format();\r\n }\r\n\r\n /**\r\n * Convierte una fecha a un objeto Date en formato ISO, opcionalmente ajustando la hora al inicio del día.\r\n *\r\n * @param {string | Date} fecha - La fecha que se desea convertir. Puede ser una cadena de texto o un objeto Date.\r\n * @param {boolean} initHour - Si es true, la hora se ajusta al inicio del día (00:00:00).\r\n * @returns {Date | null} - La fecha convertida en formato Date o null si la fecha es null.\r\n */\r\n convertirFechaISOString(\r\n fecha: DateInput,\r\n initHour: boolean = false,\r\n ): Date | null {\r\n if (!fecha) return null; // Comprobamos si la fecha es null o undefined\r\n // Validar si la fecha es válida\r\n let fechaMoment = moment(fecha);\r\n if (initHour) {\r\n fechaMoment.startOf('days');\r\n }\r\n return fechaMoment.toDate();\r\n }\r\n\r\n /**\r\n * Convierte una fecha a una cadena en formato ISO 8601.\r\n *\r\n * @param {string | Date} fecha - La fecha a convertir. Puede ser un string o un objeto Date.\r\n * @param {boolean} initHour - Si es true, ajusta la hora al inicio del día (00:00:00).\r\n * @returns {string | null} - La fecha en formato ISO 8601 (ejemplo: '2025-09-05T00:00:00.000Z') o null si la fecha es inválida.\r\n *\r\n * @example\r\n * // Fecha como string\r\n * service.convertirFechaISO8601('2025-09-05'); // '2025-09-05T00:00:00.000Z'\r\n * // Fecha como Date y ajustando al inicio del día\r\n * service.convertirFechaISO8601(new Date(), true); // '2025-09-05T00:00:00.000Z'\r\n */\r\n convertirFechaISO8601(\r\n fecha: DateInput,\r\n initHour: boolean = false,\r\n ): string | null {\r\n if (!fecha) return null; // Comprobamos si la fecha es null o undefined\r\n // Validar si la fecha es válida\r\n let fechaMoment = moment(fecha);\r\n if (initHour) {\r\n fechaMoment.startOf('days');\r\n }\r\n return fechaMoment.toISOString();\r\n }\r\n\r\n /**\r\n * Convierte una fecha a una cadena de texto en formato corto (YYYY-MM-DD).\r\n *\r\n * @param {string | Date} fecha - La fecha que se desea convertir. Puede ser una cadena de texto o un objeto Date.\r\n * @param {boolean} initHour - Si es true, la hora se ajusta al inicio del día (00:00:00).\r\n * @returns {string | null} - La fecha formateada en formato corto (YYYY-MM-DD) o null si la fecha es null.\r\n */\r\n convertirFechaShort(\r\n fecha: DateInput,\r\n initHour: boolean = false,\r\n ): string | null {\r\n if (!fecha) return null; // Comprobamos si la fecha es null o undefined\r\n // Validar si la fecha es válida\r\n const fechaMoment = moment(fecha).format('YYYY-MM-DD');\r\n return fechaMoment;\r\n }\r\n\r\n /**\r\n * Convierte una fecha a una cadena de texto que representa solo la hora (HH:mm).\r\n *\r\n * @param {string | Date} fecha - La fecha que se desea convertir. Puede ser una cadena de texto o un objeto Date.\r\n * @returns {string | null} - La hora formateada (HH:mm) o null si la fecha es null.\r\n */\r\n convertirFechaTime(fecha: DateInput): string | null {\r\n if (!fecha) return null; // Comprobamos si la fecha es null o undefined\r\n const fechaMoment = moment(fecha).format('HH:mm');\r\n return fechaMoment;\r\n }\r\n\r\n /**\r\n * Convierte una fecha a una cadena de texto en formato timestamp (YYYYMMDD).\r\n *\r\n * @param {string | Date} fecha - La fecha que se desea convertir. Puede ser una cadena de texto o un objeto Date.\r\n * @returns {string | null} - La fecha formateada en formato timestamp (YYYYMMDD) o null si la fecha es null.\r\n */\r\n convertirTimeStampString(fecha: DateInput): string | null {\r\n if (!fecha) return null; // Comprobamos si la fecha es null o undefined\r\n const fechaMoment = moment(fecha).format('YYYYMMDD');\r\n return fechaMoment;\r\n }\r\n\r\n /* OPCIONES PARA FOMULARIOS REACTIVOS */\r\n /**\r\n * Crea un FormGroup tipado a partir de una configuración de campos.\r\n *\r\n * @param {FormBuilder} fb - Instancia de FormBuilder para crear el FormGroup.\r\n * @param {FieldConfig<T>} config - Configuración de los campos del formulario.\r\n * @param {ValidatorFn[]} groupValidators - Validadores adicionales a nivel de grupo.\r\n * @param {CreateTypedFormOptions} options - Opciones de creación del formulario.\r\n * - disableUnassignedControls: Si es true, deshabilita solo los campos que no\r\n * tienen \"disabled\" definido, respetando los valores explícitos del usuario.\r\n * @returns {FormGroup} - El FormGroup creado.\r\n *\r\n * @example\r\n * const form = this.utilityAddService.createTypedForm(\r\n * this.fb,\r\n * {\r\n * codigo: { value: 'A1' }, // Se deshabilita por opción global\r\n * nombre: { value: 'Demo', disabled: false }, // Se respeta explícitamente\r\n * },\r\n * { disableUnassignedControls: true },\r\n * );\r\n */\r\n createTypedForm<T>(\r\n fb: FormBuilder,\r\n config: FieldConfig<T>,\r\n options?: CreateTypedFormOptions,\r\n ): FormGroup;\r\n createTypedForm<T>(\r\n fb: FormBuilder,\r\n config: FieldConfig<T>,\r\n groupValidators?: ValidatorFn[],\r\n options?: CreateTypedFormOptions,\r\n ): FormGroup;\r\n createTypedForm<T>(\r\n fb: FormBuilder,\r\n config: FieldConfig<T>,\r\n groupValidatorsOrOptions?: ValidatorFn[] | CreateTypedFormOptions,\r\n options: CreateTypedFormOptions = { disableUnassignedControls: false },\r\n ): FormGroup {\r\n const groupValidators = Array.isArray(groupValidatorsOrOptions)\r\n ? groupValidatorsOrOptions\r\n : undefined;\r\n const resolvedOptions = Array.isArray(groupValidatorsOrOptions)\r\n ? options\r\n : (groupValidatorsOrOptions ?? options);\r\n\r\n const formGroup: { [key in keyof T]?: FormControl } = {};\r\n\r\n // Crear controles de formulario individuales\r\n for (const key in config) {\r\n if (Object.prototype.hasOwnProperty.call(config, key)) {\r\n const fieldConfig = config[key];\r\n const { value, validators = [] } = fieldConfig;\r\n const hasAssignedDisabled = Object.prototype.hasOwnProperty.call(\r\n fieldConfig,\r\n 'disabled',\r\n );\r\n const disabled = hasAssignedDisabled\r\n ? Boolean(fieldConfig.disabled)\r\n : Boolean(resolvedOptions.disableUnassignedControls);\r\n\r\n formGroup[key] = new FormControl({ value, disabled }, validators);\r\n }\r\n }\r\n\r\n // Crear el FormGroup con validadores adicionales a nivel de grupo si existen\r\n const group = fb.group(\r\n formGroup,\r\n groupValidators ? { validators: groupValidators } : {},\r\n );\r\n\r\n return group;\r\n }\r\n\r\n /**\r\n * Crea un ReactiveForm tipado con capacidad de suscripción y limpieza.\r\n *\r\n * Extiende createTypedForm() agregando un Subject (destroy$) para manejar\r\n * la suscripción y limpieza automática de observables cuando el componente\r\n * se destruye.\r\n *\r\n * @template T - El tipo genérico del modelo para el formulario.\r\n * @param fb - Instancia de FormBuilder.\r\n * @param config - Configuración de los campos del formulario (FieldConfig<T>).\r\n * @param groupValidators - Validadores adicionales a nivel de grupo.\r\n * @param options - Opciones de creación del formulario.\r\n * - disableUnassignedControls: Si es true, deshabilita solo los campos que no\r\n * tienen \"disabled\" definido, respetando los valores explícitos del usuario.\r\n * @returns ReactiveForm<T> - FormGroup tipado con Subject destroy$ para limpieza.\r\n *\r\n * @example\r\n * ```typescript\r\n * interface LoginForm {\r\n * username: string;\r\n * password: string;\r\n * }\r\n *\r\n * const config: FieldConfig<LoginForm> = {\r\n * username: { value: '', validators: [Validators.required] },\r\n * password: { value: '', validators: [Validators.required] }\r\n * };\r\n *\r\n * const form = this.utilityAddService.createReactiveForm(\r\n * this.fb,\r\n * config,\r\n * [this.matchPasswordsValidator],\r\n * { disableUnassignedControls: true },\r\n * );\r\n *\r\n * // Al destruir el componente, limpiar todas las suscripciones\r\n * ngOnDestroy() {\r\n * form.destroy$.next();\r\n * form.destroy$.complete();\r\n * }\r\n * ```\r\n */\r\n createReactiveForm<T>(\r\n fb: FormBuilder,\r\n config: FieldConfig<T>,\r\n options?: CreateTypedFormOptions,\r\n ): ReactiveForm<T>;\r\n createReactiveForm<T>(\r\n fb: FormBuilder,\r\n config: FieldConfig<T>,\r\n groupValidators?: ValidatorFn[],\r\n options?: CreateTypedFormOptions,\r\n ): ReactiveForm<T>;\r\n createReactiveForm<T>(\r\n fb: FormBuilder,\r\n config: FieldConfig<T>,\r\n groupValidatorsOrOptions?: ValidatorFn[] | CreateTypedFormOptions,\r\n options: CreateTypedFormOptions = { disableUnassignedControls: false },\r\n ): ReactiveForm<T> {\r\n const groupValidators = Array.isArray(groupValidatorsOrOptions)\r\n ? groupValidatorsOrOptions\r\n : undefined;\r\n const resolvedOptions = Array.isArray(groupValidatorsOrOptions)\r\n ? options\r\n : (groupValidatorsOrOptions ?? options);\r\n\r\n const form = this.createTypedForm(\r\n fb,\r\n config,\r\n groupValidators,\r\n resolvedOptions,\r\n ) as TypedForm<T> & {\r\n destroy$: Subject<void>;\r\n };\r\n\r\n form.destroy$ = new Subject<void>();\r\n\r\n return form;\r\n }\r\n\r\n /**\r\n * Suscribe a los cambios de un control específico del formulario.\r\n *\r\n * Monitorea el control especificado y ejecuta un callback cada vez que su valor\r\n * cambia. Soporta debouncing y deduplicación automática de valores idénticos.\r\n *\r\n * @template T - El tipo del formulario.\r\n * @template K - La clave del control a monitorear.\r\n * @param form - El ReactiveForm a monitorear.\r\n * @param controlName - Nombre del control a observar.\r\n * @param callback - Función a ejecutar cuando cambia el valor. Recibe el nuevo valor y el formulario.\r\n * @param options - Opciones de configuración:\r\n * - debounce?: Milisegundos de espera antes de ejecutar el callback (default: sin debounce).\r\n * - distinct?: Si es true (default), solo ejecuta si el valor cambió (comparación por referencia).\r\n *\r\n * @example\r\n * ```typescript\r\n * this.utilityAddService.onControlChange(\r\n * form,\r\n * 'email',\r\n * (value, form) => {\r\n * console.log('Email cambió a:', value);\r\n * },\r\n * { debounce: 500, distinct: true }\r\n * );\r\n * ```\r\n */\r\n onControlChange<T, K extends keyof T>(\r\n form: ReactiveForm<T>,\r\n controlName: K,\r\n callback: (value: T[K] | null, form: ReactiveForm<T>) => void,\r\n options?: {\r\n debounce?: number;\r\n distinct?: boolean;\r\n },\r\n ) {\r\n let stream = form.get(controlName as string)!.valueChanges;\r\n\r\n if (options?.distinct !== false) {\r\n stream = stream.pipe(distinctUntilChanged());\r\n }\r\n\r\n if (options?.debounce) {\r\n stream = stream.pipe(debounceTime(options.debounce));\r\n }\r\n\r\n stream\r\n .pipe(takeUntil(form.destroy$))\r\n .subscribe((value) => callback(value as T[K], form));\r\n }\r\n\r\n /**\r\n * Suscribe a los cambios de múltiples controles del formulario.\r\n *\r\n * Monitorea una lista de controles y ejecuta un callback cuando cualquiera\r\n * de ellos cambia. Útil para reacciones complejas que dependen de varios campos.\r\n * Soporta operaciones asincrónicas en el callback.\r\n *\r\n * @template T - El tipo del formulario.\r\n * @param form - El ReactiveForm a monitorear.\r\n * @param controls - Array de nombres de controles a observar.\r\n * @param callback - Función a ejecutar cuando cambia cualquier control. Puede ser asincrónica.\r\n * @param options - Opciones de configuración:\r\n * - debounce?: Milisegundos de espera antes de ejecutar el callback.\r\n *\r\n * @example\r\n * ```typescript\r\n * this.utilityAddService.onControlsChange(\r\n * form,\r\n * ['startDate', 'endDate'],\r\n * async (form) => {\r\n * const startDate = form.get('startDate')?.value;\r\n * const endDate = form.get('endDate')?.value;\r\n * // Validar rango de fechas\r\n * await this.validateDateRange(startDate, endDate);\r\n * },\r\n * { debounce: 300 }\r\n * );\r\n * ```\r\n */\r\n onControlsChange<T>(\r\n form: ReactiveForm<T>,\r\n controls: (keyof T)[],\r\n callback: (form: ReactiveForm<T>) => void | Promise<void>,\r\n options?: { debounce?: number },\r\n ) {\r\n const observables = controls.map(\r\n (control) => form.get(control as string)!.valueChanges,\r\n );\r\n\r\n let stream = merge(...observables);\r\n\r\n if (options?.debounce) {\r\n stream = stream.pipe(debounceTime(options.debounce));\r\n }\r\n\r\n stream = stream.pipe(auditTime(0));\r\n\r\n stream.pipe(takeUntil(form.destroy$)).subscribe(() => callback(form));\r\n }\r\n\r\n /**\r\n * Registra reglas de validación personalizadas que se evalúan dinámicamente.\r\n *\r\n * Permite definir reglas complejas que se ejecutan cuando sus dependencias cambian.\r\n * Cada regla puede depender de múltiples campos y ejecutar lógica asincrónica\r\n * para actualizar otros campos del formulario.\r\n *\r\n * @template T - El tipo del formulario.\r\n * @param form - El ReactiveForm donde se aplicarán las reglas.\r\n * @param rules - Array de FormRule<T> que especifican:\r\n * - dependsOn: Campos que disparan la regla cuando cambian.\r\n * - compute: Función que actualiza el formulario en base a los cambios.\r\n * - debounce?: Milisegundos de espera opcional.\r\n *\r\n * @example\r\n * ```typescript\r\n * const rules: FormRule<MyForm>[] = [\r\n * {\r\n * dependsOn: ['country'],\r\n * debounce: 300,\r\n * compute: async (form) => {\r\n * const country = form.get('country')?.value;\r\n * const states = await this.getStatesByCountry(country);\r\n * form.get('state')?.setValue(states[0]);\r\n * }\r\n * }\r\n * ];\r\n *\r\n * this.utilityAddService.registerRules(form, rules);\r\n * ```\r\n */\r\n registerRules<T>(form: ReactiveForm<T>, rules: FormRule<T>[]) {\r\n const runningRules = new Set<FormRule<T>>();\r\n\r\n rules.forEach((rule) => {\r\n this.onControlsChange(\r\n form,\r\n rule.dependsOn,\r\n async (form) => {\r\n if (runningRules.has(rule)) return;\r\n\r\n try {\r\n runningRules.add(rule);\r\n await rule.compute(form);\r\n } finally {\r\n runningRules.delete(rule);\r\n }\r\n },\r\n { debounce: rule.debounce },\r\n );\r\n });\r\n }\r\n\r\n /**\r\n * Sanitiza un formulario obteniendo valores de un formulario, aplicando conversiones de fecha según los campos especificados.\r\n *\r\n * @template T - El tipo genérico del modelo a procesar.\r\n * @param form - El formulario reactivo de Angular del que se obtendrán los valores.\r\n * @param campos - Uno o más objetos que especifican los campos de fecha y el tipo de conversión a aplicar. Cada objeto debe contener:\r\n * - `nombre`: El nombre del campo de fecha en el modelo.\r\n * - `tipo`: El tipo de conversión que se debe aplicar (por ejemplo, `'short'`, `'zh'`, `'iso').\r\n * @returns Un objeto del tipo `T` con los datos procesados y las conversiones de fecha aplicadas.\r\n * @throws Error - Si el campo de fecha especificado no existe en los datos del formulario.\r\n *\r\n * @example\r\n * // Procesar varios campos de fecha\r\n * const precioValues = service.sanitizarModelo<ItemPrecioModel>(\r\n * form,\r\n * { nombre: 'fechaInicio', tipo: 'short' },\r\n * { nombre: 'fechaFin', tipo: 'zh' }\r\n * );\r\n */\r\n sanitizarForm<T>(form: any, ...campos: FechasConversion[]): T {\r\n // Obtén todos los valores del formulario\r\n const rawData = form.getRawValue();\r\n\r\n if (!rawData) {\r\n throw new Error('El formulario no tiene valores.');\r\n }\r\n\r\n // Procesa los valores sin envolver en un arreglo\r\n const updatedValue = { ...rawData };\r\n\r\n // Itera sobre los campos de fecha especificados para realizar las conversiones\r\n campos.forEach(({ nombre, tipo }) => {\r\n if (!(nombre in updatedValue)) {\r\n throw new Error(`El campo \"${nombre}\" no existe en el valor.`);\r\n }\r\n updatedValue[nombre] = updatedValue[nombre]\r\n ? this.convertirFecha(updatedValue[nombre], tipo)\r\n : null;\r\n });\r\n\r\n return updatedValue as T;\r\n }\r\n\r\n /**\r\n * Sanitiza un objeto plano, aplicando conversiones de fecha según los campos especificados.\r\n *\r\n * @template T - El tipo genérico del objeto a procesar.\r\n * @param values - El objeto con los datos.\r\n * @param campos - Uno o más objetos que especifican los campos de fecha y el tipo de conversión a aplicar.\r\n * @returns Un objeto del tipo T con las conversiones de fecha aplicadas.\r\n */\r\n sanitizarModel<T extends Record<string, any>>(\r\n values: T,\r\n ...campos: FechasConversion[]\r\n ): T {\r\n // Crear una copia del objeto para no modificar el original\r\n const updatedValue: Record<string, any> = { ...values };\r\n\r\n campos.forEach(({ nombre, tipo }) => {\r\n if (!(nombre in updatedValue)) {\r\n throw new Error(`El campo \"${nombre}\" no existe en el objeto.`);\r\n }\r\n\r\n const valorActual = updatedValue[nombre];\r\n\r\n if (\r\n valorActual !== null &&\r\n valorActual !== undefined &&\r\n valorActual !== ''\r\n ) {\r\n updatedValue[nombre] = this.convertirFecha(valorActual, tipo);\r\n } else {\r\n updatedValue[nombre] = null;\r\n }\r\n });\r\n\r\n return updatedValue as T;\r\n }\r\n\r\n /**\r\n * Convierte una fecha al formato especificado.\r\n *\r\n * @param fecha - La fecha en formato string que se desea convertir.\r\n * Debe estar en un formato reconocible por `Date` o en ISO 8601.\r\n * @param tipo - El tipo de conversión a realizar. Soporta:\r\n * - `'short'`: Devuelve la fecha en formato corto (YYYY-MM-DD).\r\n * - `'zh'`: Devuelve la fecha ajustada a la zona horaria configurada.\r\n * - `'iso'`: Devuelve la fecha como objeto Date en formato ISO.\r\n * - `'iso8601'`: Devuelve la fecha como string en formato ISO 8601.\r\n * @returns La fecha convertida como string o Date según el tipo especificado, o null si la fecha es inválida.\r\n * @throws Error - Si el tipo de conversión no es válido o soportado.\r\n *\r\n * @example\r\n * // Formato corto\r\n * service.convertirFecha('2025-08-21', 'short'); // '2025-08-21'\r\n * // Zona horaria\r\n * service.convertirFecha('2025-08-21', 'zh'); // '2025-08-21T00:00:00-06:00' (ejemplo)\r\n * // Formato ISO (Date)\r\n * service.convertirFecha('2025-08-21', 'iso'); // Date { ... }\r\n * // Formato ISO 8601 (string)\r\n * service.convertirFecha('2025-08-21', 'iso8601'); // '2025-08-21T00:00:00.000Z'\r\n */\r\n private convertirFecha(\r\n fecha: DateInput,\r\n tipo: TipoFechaConversion,\r\n ): Date | string | null {\r\n switch (tipo) {\r\n case 'short':\r\n // Implementación para el formato corto\r\n return this.convertirFechaShort(fecha);\r\n case 'zh':\r\n // Implementación para zonas horarias\r\n return this.convertirFechaSegunZonaHoraria(fecha);\r\n case 'iso': {\r\n return this.convertirFechaISOString(fecha);\r\n }\r\n case 'iso8601': {\r\n return this.convertirFechaISO8601(fecha);\r\n }\r\n default:\r\n throw new Error(`Tipo de conversión desconocido: ${tipo}`);\r\n }\r\n }\r\n\r\n /**\r\n * Maneja la respuesta de un archivo descargable\r\n * @param fileObservable Observable que emite el Blob del archivo\r\n * @param actionId 0 para abrir en nueva ventana, 1 para descargar\r\n * @param fileName Nombre del archivo sin extensión\r\n */\r\n handleFileResponse(\r\n fileObservable: Observable<Blob>,\r\n actionId: number = 0,\r\n fileName: string,\r\n ): void {\r\n fileObservable.subscribe({\r\n next: (fileBlob: Blob) => {\r\n const fileUrl = URL.createObjectURL(fileBlob);\r\n const fileExtension = this.getFileExtension(fileBlob.type);\r\n\r\n if (this.isExcelFile(fileBlob.type)) {\r\n this.forceDownload(fileUrl, fileName + fileExtension);\r\n } else {\r\n this.handleNonExcelFiles(fileUrl, actionId, fileName, fileExtension);\r\n }\r\n\r\n this.revokeObjectUrl(fileUrl);\r\n },\r\n error: (err) => console.error('Error al manejar el archivo:', err),\r\n });\r\n }\r\n\r\n /**\r\n * Maneja la respuesta de un archivo descargable cuando se necesita\r\n * obtener el nombre de archivo desde los headers HTTP (Content-Disposition).\r\n *\r\n * @param fileObservable Observable que emite HttpResponse<Blob>\r\n * @param actionId 0 para abrir en nueva ventana, 1 para descargar\r\n * @param fallbackFileName Nombre de archivo por defecto si no viene en el header\r\n */\r\n handleFileResponseFromResponse(\r\n fileObservable: Observable<HttpResponse<Blob>>,\r\n actionId: number = 0,\r\n fallbackFileName: string = 'archivo sin nombre',\r\n ): void {\r\n fileObservable.subscribe({\r\n next: (response) => {\r\n const fileBlob = response.body as Blob;\r\n\r\n if (!fileBlob) {\r\n console.error('La respuesta no contiene cuerpo (Blob)');\r\n return;\r\n }\r\n\r\n const headerFileName = this.getFileNameFromContentDisposition(\r\n response.headers,\r\n );\r\n const baseFileName = headerFileName || fallbackFileName;\r\n\r\n const fileUrl = URL.createObjectURL(fileBlob);\r\n const fileExtension = this.getFileExtension(fileBlob.type);\r\n\r\n this.logIfNotProduction(\r\n 'Manejando archivo con tipo:',\r\n fileBlob,\r\n fileBlob.type,\r\n 'nombre:',\r\n baseFileName,\r\n );\r\n\r\n if (this.isExcelFile(fileBlob.type)) {\r\n this.forceDownload(fileUrl, baseFileName + fileExtension);\r\n } else {\r\n this.handleNonExcelFiles(\r\n fileUrl,\r\n actionId,\r\n baseFileName,\r\n fileExtension,\r\n );\r\n }\r\n\r\n this.revokeObjectUrl(fileUrl);\r\n },\r\n error: (err) => console.error('Error al manejar el archivo:', err),\r\n });\r\n }\r\n\r\n /**\r\n * Extrae el blob y el nombre del archivo desde una respuesta HTTP sin realizar la descarga.\r\n * Es útil cuando necesitas reutilizar el blob para múltiples operaciones.\r\n *\r\n * @param fileObservable Observable que emite HttpResponse<Blob>\r\n * @param fallbackFileName Nombre de archivo por defecto si no viene en el header\r\n * @returns Observable que emite un objeto con { blob, fileName }\r\n *\r\n * @example\r\n * this.utilityAddService.extractFileDataFromResponse(this.fileService.getFile())\r\n * .subscribe(({ blob, fileName }) => {\r\n * // Usar blob y fileName para múltiples operaciones\r\n * this.utilityAddService.descargarManual(blob, fileName);\r\n * });\r\n */\r\n extractFileDataFromResponse(\r\n fileObservable: Observable<HttpResponse<Blob>>,\r\n fallbackFileName: string = 'archivo sin nombre',\r\n ): Observable<{ blob: Blob; fileName: string }> {\r\n return new Observable((observer) => {\r\n fileObservable.subscribe({\r\n next: (response) => {\r\n const fileBlob = response.body as Blob;\r\n\r\n if (!fileBlob) {\r\n observer.error('La respuesta no contiene cuerpo (Blob)');\r\n return;\r\n }\r\n\r\n const headerFileName = this.getFileNameFromContentDisposition(\r\n response.headers,\r\n );\r\n const baseFileName = headerFileName || fallbackFileName;\r\n const fullFileName = this.ensureFileNameWithExtension(\r\n baseFileName,\r\n fileBlob.type,\r\n );\r\n\r\n this.logIfNotProduction(\r\n 'Extrayendo archivo con tipo:',\r\n fileBlob.type,\r\n 'nombre:',\r\n fullFileName,\r\n );\r\n\r\n observer.next({\r\n blob: fileBlob,\r\n fileName: fullFileName,\r\n });\r\n observer.complete();\r\n },\r\n error: (err) => observer.error(err),\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Descarga un archivo manualmente usando el blob y nombre del archivo proporcionados.\r\n * Es útil como complemento a extractFileDataFromResponse para reutilizar blobs.\r\n *\r\n * @param blob Objeto Blob del archivo a descargar\r\n * @param fileName Nombre completo del archivo incluyendo extensión\r\n *\r\n * @example\r\n * // Opción 1: Usar directamente con un blob\r\n * this.utilityAddService.descargarBlob(blob, 'Reporte.xlsx');\r\n *\r\n * // Opción 2: Combinar con extractFileDataFromResponse\r\n * this.utilityAddService.extractFileDataFromResponse(httpResponse$)\r\n * .subscribe(({ blob, fileName }) => {\r\n * this.utilityAddService.descargarBlob(blob, fileName);\r\n * });\r\n */\r\n descargarBlob(\r\n blob: Blob | null | undefined,\r\n fileName: string | null | undefined,\r\n ): void {\r\n if (!blob) {\r\n console.warn('No se proporcionó un blob válido para descargar.');\r\n return;\r\n }\r\n\r\n const fileUrl = URL.createObjectURL(blob);\r\n const downloadLink = document.createElement('a');\r\n downloadLink.href = fileUrl;\r\n\r\n const baseFileName = fileName?.trim() || 'archivo_descargado';\r\n const fullFileName = this.ensureFileNameWithExtension(\r\n baseFileName,\r\n blob.type,\r\n );\r\n\r\n downloadLink.download = fullFileName;\r\n downloadLink.click();\r\n this.revokeObjectUrl(fileUrl);\r\n }\r\n\r\n /**\r\n * Verifica si un archivo es de tipo Excel.\r\n *\r\n * @param fileType - Tipo MIME del archivo a verificar.\r\n * @returns true si es un archivo Excel (.xlsx), false en caso contrario.\r\n * @private\r\n */\r\n private isExcelFile(fileType: string): boolean {\r\n return fileType.includes(\r\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\r\n );\r\n }\r\n\r\n /**\r\n * Extrae el nombre del archivo desde el header Content-Disposition de una respuesta HTTP.\r\n *\r\n * Parsea el header Content-Disposition siguiendo el estándar RFC 5987 para\r\n * extraer el nombre del archivo, incluyendo manejo de caracteres especiales\r\n * y codificaciones UTF-8.\r\n *\r\n * @param headers - Headers HTTP de la respuesta.\r\n * @returns El nombre del archivo o null si no se encuentra.\r\n * @private\r\n *\r\n * @example\r\n * // Header: Content-Disposition: attachment; filename*=UTF-8''Reporte%202025.pdf\r\n * // Retorna: 'Reporte 2025.pdf'\r\n */\r\n private getFileNameFromContentDisposition(\r\n headers: HttpHeaders,\r\n ): string | null {\r\n const contentDisposition = headers.get('content-disposition');\r\n\r\n if (!contentDisposition) return null;\r\n\r\n const matches = /filename\\*?[^;=\\n]*=((['\"]).*?\\2|[^;\\n]*)/i.exec(\r\n contentDisposition,\r\n );\r\n if (!matches || !matches[1]) return null;\r\n\r\n let fileName = matches[1].replace(/['\"]/g, '').trim();\r\n\r\n // Manejar posibles codificaciones tipo RFC5987: filename*=UTF-8''Nombre.pdf\r\n if (fileName.toLowerCase().includes(\"utf-8''\")) {\r\n fileName = decodeURIComponent(fileName.split(\"''\")[1] || '');\r\n }\r\n\r\n return fileName;\r\n }\r\n\r\n /**\r\n * Determina la extensión de archivo basada en su tipo MIME.\r\n *\r\n * @param fileType - Tipo MIME del archivo.\r\n * @returns La extensión correspondiente:\r\n * - '.pdf' para archivos PDF.\r\n * - '.xlsx' para archivos Excel.\r\n * - Otras extensiones conocidas según el MIME.\r\n * - Cadena vacía si no se puede inferir.\r\n * @private\r\n */\r\n private getFileExtension(fileType: string): string {\r\n const normalizedType = fileType.toLowerCase();\r\n\r\n if (normalizedType.includes('pdf')) return '.pdf';\r\n if (normalizedType.includes('spreadsheetml')) return '.xlsx';\r\n if (normalizedType.includes('ms-excel')) return '.xls';\r\n if (normalizedType.includes('csv')) return '.csv';\r\n if (normalizedType.includes('zip')) return '.zip';\r\n if (normalizedType.includes('json')) return '.json';\r\n if (normalizedType.includes('xml')) return '.xml';\r\n if (normalizedType.includes('text/plain')) return '.txt';\r\n if (normalizedType.includes('png')) return '.png';\r\n if (normalizedType.includes('jpeg') || normalizedType.includes('jpg')) {\r\n return '.jpg';\r\n }\r\n\r\n return '';\r\n }\r\n\r\n /**\r\n * Asegura que el nombre del archivo tenga extensión.\r\n * Si ya trae extensión, lo respeta sin modificarlo.\r\n * Si no trae extensión, intenta inferirla desde el tipo MIME.\r\n *\r\n * @param fileName - Nombre del archivo, con o sin extensión.\r\n * @param fileType - Tipo MIME del archivo.\r\n * @returns Nombre de archivo con extensión cuando es posible.\r\n * @private\r\n */\r\n private ensureFileNameWithExtension(\r\n fileName: string,\r\n fileType: string,\r\n ): string {\r\n const hasExtension = /\\.[^./\\\\]+$/.test(fileName);\r\n if (hasExtension) return fileName;\r\n\r\n const fileExtension = this.getFileExtension(fileType);\r\n return fileExtension ? `${fileName}${fileExtension}` : fileName;\r\n }\r\n\r\n /**\r\n * Maneja archivos no Excel (como PDFs) realizando acciones de visualización o descarga.\r\n *\r\n * @param fileUrl - URL temporal del objeto Blob del archivo.\r\n * @param actionId - ID de acción:\r\n * - 0: Abre el archivo en una nueva pestaña.\r\n * - 1: Inicia la descarga del archivo.\r\n * @param fileName - Nombre base del archivo sin extensión.\r\n * @param fileExtension - Extensión del archivo incluyendo el punto (ej: '.pdf').\r\n * @private\r\n */\r\n private handleNonExcelFiles(\r\n fileUrl: string,\r\n actionId: number,\r\n fileName: string,\r\n fileExtension: string,\r\n ): void {\r\n switch (actionId) {\r\n case 0: // Abrir en nueva ventana\r\n window.open(fileUrl, '_blank');\r\n break;\r\n case 1: // Descargar archivo\r\n this.forceDownload(fileUrl, fileName + fileExtension);\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * Abre un archivo PDF en una nueva pestaña del navegador.\r\n *\r\n * @param blob - Objeto Blob que contiene los datos del archivo PDF.\r\n *\r\n * @example\r\n * // Uso típico con respuesta de servicio HTTP\r\n * this.pdfService.getPdf(id).subscribe(blob => {\r\n * this.utilityAddService.PdfView(blob);\r\n * });\r\n *\r\n * @description\r\n * Este método crea un URL temporal para el Blob del PDF y lo abre en una nueva\r\n * pestaña del navegador. El URL se revoca automáticamente después de 100ms para\r\n * liberar memoria.\r\n */\r\n PdfView(blob: Blob): any {\r\n // Crear un URL temporal para el Blob\r\n const pdfUrl = URL.createObjectURL(blob);\r\n // Abrir el PDF en una nueva pestaña\r\n window.open(pdfUrl, '_blank');\r\n\r\n // Liberar el URL del Blob una vez que la pestaña ha sido abierta\r\n // Esperar un poco para asegurarse de que el archivo se ha abierto\r\n setTimeout(() => {\r\n window.URL.revokeObjectURL(pdfUrl);\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Descarga un archivo PDF con un nombre personalizado que incluye el prefijo \"DTE_\".\r\n *\r\n * @param blob - Objeto Blob que contiene los datos del archivo PDF a descargar.\r\n * @param filename - Nombre base del archivo sin extensión (se agregará automáticamente \".pdf\" y el prefijo \"DTE_\").\r\n *\r\n * @example\r\n * // Uso típico con respuesta de servicio HTTP\r\n * this.dteService.getDTE(operacionId).subscribe(blob => {\r\n * this.utilityAddService.downloadPdfFile(blob, '12345');\r\n * // Descarga el archivo como: DTE_12345.pdf\r\n * });\r\n *\r\n * @description\r\n * Este método crea un URL temporal para el Blob y simula un clic en un enlace de\r\n * descarga para iniciar la descarga automática del archivo. El nombre del archivo\r\n * sigue el formato: DTE_{filename}.pdf. El URL se revoca después de 100ms para\r\n * liberar memoria.\r\n */\r\n downloadPdfFile(blob: Blob, filename: string) {\r\n // Crear un URL temporal para el Blob\r\n const pdfUrl = URL.createObjectURL(blob);\r\n\r\n // Crear un enlace de descarga\r\n const link = document.createElement('a');\r\n link.href = pdfUrl;\r\n\r\n // Establecer el nombre del archivo utilizando el operacionId\r\n link.download = `DTE_${filename}.pdf`;\r\n\r\n // Simular un clic en el enlace para iniciar la descarga\r\n link.click();\r\n\r\n // Liberar el URL del Blob después de un pequeño retraso\r\n setTimeout(() => {\r\n window.URL.revokeObjectURL(pdfUrl);\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Inicia la descarga programada de un archivo.\r\n *\r\n * Crea un elemento <a> temporal, lo configura con el archivo y tipo MIME,\r\n * y simula un clic para iniciar la descarga del navegador.\r\n *\r\n * @param fileUrl - URL temporal (object URL) del archivo a descargar.\r\n * @param fullFileName - Nombre completo del archivo incluyendo extensión.\r\n * @private\r\n */\r\n private forceDownload(fileUrl: string, fullFileName: string): void {\r\n const downloadLink = document.createElement('a');\r\n downloadLink.href = fileUrl;\r\n downloadLink.download = fullFileName;\r\n downloadLink.click();\r\n }\r\n\r\n /**\r\n * Libera la memoria de un URL de objeto temporal.\r\n *\r\n * Revoca un object URL creado con URL.createObjectURL() después de un pequeño\r\n * retraso (100ms) para asegurar que el navegador ha terminado de usar el archivo.\r\n *\r\n * @param fileUrl - URL del objeto a revocar.\r\n * @private\r\n */\r\n private revokeObjectUrl(fileUrl: string): void {\r\n setTimeout(() => {\r\n window.URL.revokeObjectURL(fileUrl);\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Muestra información en consola solo en desarrollo, permitiendo múltiples argumentos como console.log nativo.\r\n *\r\n * @param args - Argumentos a mostrar en consola (texto, objetos, etc).\r\n * @example\r\n * logIfNotProduction('Datos:', response);\r\n * logIfNotProduction('Error:', error, { extra: true });\r\n */\r\n logIfNotProduction(...args: any[]): void {\r\n if (!this.environment.production) {\r\n console.log(...args);\r\n }\r\n }\r\n\r\n /**\r\n * Valida todos los campos de un formulario y muestra una alerta.\r\n *\r\n * Marca todos los controles como tocados (triggereando la validación visual)\r\n * y muestra una notificación toastr indicando que hay validaciones pendientes.\r\n * Útil para formularios donde deseas mostrar todos los errores de validación\r\n * de una vez.\r\n *\r\n * @param form - El FormGroup a validar.\r\n *\r\n * @example\r\n * ```typescript\r\n * if (this.form.invalid) {\r\n * this.utilityAddService.checkFormValid(this.form);\r\n * return;\r\n * }\r\n * ```\r\n */\r\n checkFormValid(control: AbstractControl | null | undefined): void {\r\n if (!control) return;\r\n\r\n // Marca todos los controles (incluyendo anidados en FormGroup/FormArray)\r\n control.markAllAsTouched();\r\n\r\n // Muestra un mensaje de alerta\r\n this._serviceAlerta.toastrAlerts(\r\n 3,\r\n 'Formulario',\r\n 'Validaciones pendientes',\r\n 2,\r\n );\r\n }\r\n\r\n /**\r\n * Extrae valores únicos de un campo específico de un array de objetos.\r\n *\r\n * Obtiene todos los valores distintos de una propiedad en un array de objetos,\r\n * retornando un array de objetos FilterOption tipado y ordenado alfabéticamente.\r\n * Incluye validaciones para detectar campos inexistentes con mensajes de alerta.\r\n *\r\n * @template T - Tipo de los objetos en el array.\r\n * @param data - Array de objetos del cual extraer valores únicos.\r\n * @param field - Nombre del campo del cual extraer valores únicos.\r\n * @returns Array de FilterOption ordenado alfabéticamente, o array vacío si hay errores.\r\n *\r\n * @example\r\n * ```typescript\r\n * interface Usuario {\r\n * id: number;\r\n * nombre: string;\r\n * departamento: string;\r\n * }\r\n *\r\n * const usuarios: Usuario[] = [\r\n * { id: 1, nombre: 'Juan', departamento: 'TI' },\r\n * { id: 2, nombre: 'María', departamento: 'RRHH' },\r\n * { id: 3, nombre: 'Pedro', departamento: 'TI' }\r\n * ];\r\n *\r\n * const deptosUnicos = this.utilityAddService.getUniqueValues(usuarios, 'departamento');\r\n * // Retorna: [\r\n * // { value: 'RRHH', field: 'departamento' },\r\n * // { value: 'TI', field: 'departamento' }\r\n * // ]\r\n * ```\r\n */\r\n getUniqueValues<T>(data: T[], field: keyof T): FilterOption[] {\r\n if (!data || data.length === 0) {\r\n console.warn(\r\n 'UtilityAddService.getUniqueValues: El array de datos está vacío. No se puede obtener valores únicos.',\r\n );\r\n return [];\r\n }\r\n\r\n const hasField = data.some((item) =>\r\n Object.prototype.hasOwnProperty.call(item as object, field as string),\r\n );\r\n\r\n if (!hasField) {\r\n const availableFields = Array.from(\r\n new Set(data.flatMap((item) => Object.keys(item as object))),\r\n ).sort();\r\n\r\n console.warn(\r\n `UtilityAddService.getUniqueValues: El campo \"${String(\r\n field,\r\n )}\" no existe en los objetos proporcionados. Campos disponibles: ${availableFields.join(\r\n ', ',\r\n )}`,\r\n );\r\n\r\n return [];\r\n }\r\n\r\n const uniqueValues = data.reduce((acc: FilterOption[], current) => {\r\n const fieldValue = current[field];\r\n\r\n if (\r\n typeof fieldValue === 'string' &&\r\n !acc.some((item) => item.value === fieldValue)\r\n ) {\r\n acc.push({\r\n value: fieldValue,\r\n field: field.toString(),\r\n });\r\n }\r\n return acc;\r\n }, []);\r\n\r\n return uniqueValues.sort((a, b) => a.value.localeCompare(b.value));\r\n }\r\n\r\n /**\r\n * Helper function para parsear fechas para filtro de primeNg en table\r\n * @param date - Fecha en formato string, Date o null/undefined\r\n * @returns Date | null - Objeto Date válido o null\r\n */\r\n parseDate(date: string | Date | null): Date | null {\r\n if (!date) return null;\r\n return typeof date === 'string' ? new Date(date) : date;\r\n }\r\n\r\n /**\r\n * Función pura que procesa una cadena de texto conteniendo números individuales y/o rangos numéricos,\r\n * devolviendo un array con todos los números expandidos.\r\n *\r\n * @param input - Cadena de texto con el formato: número[.número][.inicio-fin][...]\r\n * @returns Array de números con todos los valores individuales y rangos expandidos\r\n *\r\n * @example\r\n * // Uso básico\r\n * const result = parseNumericRanges('1.5.7.10-12');\r\n * // Retorna: [1, 5, 7, 10, 11, 12]\r\n *\r\n * @example\r\n * // Con espacios y caracteres especiales\r\n * const result = parseNumericRanges(' 3. 5-7 .10-12abc');\r\n * // Retorna: [3, 5, 6, 7, 10, 11, 12]\r\n *\r\n * @example\r\n * // Rangos invertidos (serán ignorados)\r\n * const result = parseNumericRanges('10-8');\r\n * // Retorna: [] (array vacío)\r\n *\r\n * @note\r\n * Características especiales:\r\n * - Elimina automáticamente espacios y caracteres no numéricos\r\n * - Los números deben estar separados por puntos (.)\r\n * - Los rangos deben usar guión (-) sin espacios entre números\r\n * - Es tolerante a formatos inconsistentes\r\n * - Omite elementos inválidos sin generar errores\r\n */\r\n parseNumericRanges(input: string): number[] {\r\n const cleanString = input.replace(/[^\\d.\\- ]/g, '').replace(/\\s+/g, '');\r\n\r\n const parts = cleanString.split('.');\r\n const result: number[] = [];\r\n\r\n for (const part of parts) {\r\n if (!part) continue;\r\n\r\n if (part.includes('-')) {\r\n const [startStr, endStr] = part.split('-');\r\n const start = parseInt(startStr, 10);\r\n const end = parseInt(endStr, 10);\r\n\r\n if (!isNaN(start) && !isNaN(end) && start <= end) {\r\n for (let i = start; i <= end; i++) {\r\n result.push(i);\r\n }\r\n }\r\n } else {\r\n const number = parseInt(part, 10);\r\n if (!isNaN(number)) {\r\n result.push(number);\r\n }\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Adaptador para procesar eventos de input y extraer rangos numéricos.\r\n *\r\n * @param event - Objeto Event del DOM, preferiblemente de un elemento input\r\n * @returns\r\n * - Array de números generado a partir del valor del input, cuando hay\r\n * números/rangos.\r\n * - El carácter comodín \"*\" cuando el valor del input es exactamente \"*\".\r\n *\r\n * @example\r\n * // Uso en template Angular\r\n * <input (input)=\"processNumericRangesFromEvent($event)\">\r\n *\r\n * @example\r\n * // Uso directo\r\n * const result = processNumericRangesFromEvent(inputEvent);\r\n *\r\n * @note\r\n * Esta función es un wrapper que:\r\n * - Extrae el valor del input del evento\r\n * - Delega el procesamiento a parseNumericRanges()\r\n * - Mantiene compatibilidad con eventos de diferentes frameworks\r\n *\r\n * @dependencies\r\n * Requiere que el evento tenga la propiedad target.value (standard DOM)\r\n * Para otros tipos de eventos (ej. Angular Material) puede necesitar ajustes\r\n */\r\n processNumericRangesFromEvent(event: Event): number[] | '*' {\r\n const rawValue = (event.target as HTMLInputElement).value ?? '';\r\n const inputValue = rawValue.trim();\r\n\r\n // Si el valor es exactamente el comodín \"*\", lo devolvemos tal cual\r\n // para que el consumidor pueda interpretarlo como \"todos\".\r\n if (inputValue === '*') {\r\n return '*';\r\n }\r\n\r\n // Para mezclas de números y asteriscos, parseNumericRanges elimina\r\n // cualquier carácter no numérico/rango (como \"*\"), dando prioridad\r\n // a los números y omitiendo el comodín.\r\n return this.parseNumericRanges(inputValue);\r\n }\r\n\r\n /**\r\n * Maneja la respuesta estándar de una operación HTTP, mostrando alertas y realizando acciones comunes en formularios.\r\n *\r\n * @param response - Respuesta de la operación (debe tener isSuccess, title, statusMessage).\r\n * @param urlHome - Ruta a la que se navega si la operación es exitosa y el id es mayor a 0.\r\n * @param form - Formulario reactivo a resetear si la operación es exitosa.\r\n * @param getForm - Función para recargar el formulario (por ejemplo, para obtener datos actualizados).\r\n * @param id - Identificador usado para decidir si se navega a urlHome tras éxito.\r\n *\r\n * @example\r\n * // Uso típico en un componente\r\n * this.utilityAddService.handleResponse(\r\n * response,\r\n * '/home',\r\n * this.form,\r\n * () => this.getForm(),\r\n * this.id\r\n * );\r\n *\r\n * @description\r\n * - Si response.isSuccess es true:\r\n * - Muestra alerta tipo toastr.\r\n * - Si id > 0, navega a urlHome.\r\n * - Resetea el formulario y ejecuta getForm().\r\n * - Si response.isSuccess es false:\r\n * - Muestra alerta visual personalizada con icono de error.\r\n */\r\n public handleResponse(\r\n response: ResponseHttpModel,\r\n urlHome: string,\r\n form: FormGroup,\r\n getForm: () => void,\r\n id: number,\r\n ): void {\r\n try {\r\n this.logIfNotProduction('handleResponse - response:', response);\r\n if (response.isSuccess) {\r\n this._serviceAlerta.toastrAlerts(\r\n 1,\r\n response.title,\r\n response.statusMessage,\r\n 2,\r\n );\r\n if (id > 0) {\r\n this._router.navigate([urlHome]);\r\n return;\r\n }\r\n getForm();\r\n form?.reset();\r\n } else {\r\n this._serviceAlerta.alertaHtmlSuccess(\r\n response.title,\r\n response.statusMessage,\r\n {\r\n icono: 'icon2/hard_drive_error.png',\r\n showConfirmButton: true,\r\n },\r\n );\r\n }\r\n } catch (error) {\r\n this.logIfNotProduction('Error en handleResponse:', error);\r\n this._serviceAlerta.toastrAlerts(\r\n 4,\r\n 'Error',\r\n error instanceof Error ? error.message : String(error),\r\n 2,\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Maneja la respuesta estándar de una operación HTTP que devuelve un ServiceResult<T>,\r\n * mostrando alertas y realizando acciones comunes en formularios.\r\n *\r\n * @typeParam T - Tipo de dato contenido en la propiedad data de ServiceResult.\r\n * @param response - Respuesta del servicio (debe tener isSuccess, title, message, etc.).\r\n * @param urlHome - Ruta a la que se navega si la operación es exitosa y el id es mayor a 0.\r\n * @param form - Formulario reactivo a resetear si la operación es exitosa.\r\n * @param getForm - Función para recargar el formulario (por ejemplo, para obtener datos actualizados).\r\n * @param id - Identificador usado para decidir si se navega a urlHome tras éxito.\r\n *\r\n * @example\r\n * // Uso típico en un componente con ServiceResult\r\n * this.utilityAddService.handleResponseService<MiModelo>(\r\n * response,\r\n * '/home',\r\n * this.form,\r\n * () => this.getForm(),\r\n * this.id\r\n * );\r\n *\r\n * @description\r\n * - Si response.isSuccess es true:\r\n * - Muestra alerta tipo toastr.\r\n * - Si id > 0, navega a urlHome.\r\n * - Resetea el formulario y ejecuta getForm().\r\n * - Si response.isSuccess es false:\r\n * - Muestra alerta visual personalizada con icono de error.\r\n */\r\n public handleResponseService<T>(\r\n response: ServiceResult<T>,\r\n urlHome: string,\r\n form: FormGroup,\r\n getForm: () => void,\r\n id: number,\r\n ): void {\r\n try {\r\n this.logIfNotProduction('handleResponse - response:', response);\r\n if (response.isSuccess) {\r\n this._serviceAlerta.toastrAlerts(\r\n 1,\r\n response.title,\r\n response.message,\r\n 2,\r\n );\r\n if (id > 0) {\r\n this._router.navigate([urlHome]);\r\n return;\r\n }\r\n getForm();\r\n form?.reset();\r\n } else {\r\n this._serviceAlerta.alertaHtmlSuccess(\r\n response.title,\r\n response.message,\r\n {\r\n icono: 'icon2/hard_drive_error.png',\r\n showConfirmButton: true,\r\n },\r\n );\r\n }\r\n } catch (error) {\r\n this.logIfNotProduction('Error en handleResponseService:', error);\r\n this._serviceAlerta.toastrAlerts(\r\n 4,\r\n 'Error',\r\n error instanceof Error ? error.message : String(error),\r\n 2,\r\n );\r\n }\r\n }\r\n}\r\n","/**\r\n * Formateador de moneda por defecto para Guatemala.\r\n *\r\n * Usa la configuración regional `es-GT` y el código de moneda `GTQ`.\r\n * Siempre muestra 2 decimales.\r\n *\r\n * Ejemplo de uso:\r\n * ```ts\r\n * GTQFormatter.format(1234.5); // \"Q 1,234.50\"\r\n * ```\r\n */\r\nexport const GTQFormatter = new Intl.NumberFormat('es-GT', {\r\n style: 'currency',\r\n currency: 'GTQ',\r\n minimumFractionDigits: 2,\r\n maximumFractionDigits: 2,\r\n});\r\n\r\n/**\r\n * Crea un formateador de moneda personalizado.\r\n *\r\n * Permite definir la configuración regional (`locale`) y el código de moneda (`currency`)\r\n * manteniendo 2 decimales fijos.\r\n *\r\n * Ejemplos de uso:\r\n * ```ts\r\n * const usdFormatter = createCurrencyFormatter('en-US', 'USD');\r\n * usdFormatter.format(1000); // \"$1,000.00\"\r\n *\r\n * const mxnFormatter = createCurrencyFormatter('es-MX', 'MXN');\r\n * mxnFormatter.format(1500.75); // \"$1,500.75\"\r\n * ```\r\n *\r\n * @param locale Código de configuración regional, por ejemplo: `es-GT`, `en-US`.\r\n * @param currency Código de moneda ISO 4217, por ejemplo: `GTQ`, `USD`, `EUR`.\r\n * @returns Instancia de `Intl.NumberFormat` configurada para moneda.\r\n */\r\nexport function createCurrencyFormatter(\r\n locale: string,\r\n currency: string,\r\n): Intl.NumberFormat {\r\n return new Intl.NumberFormat(locale, {\r\n style: 'currency',\r\n currency,\r\n minimumFractionDigits: 2,\r\n maximumFractionDigits: 2,\r\n });\r\n}\r\n","import {\r\n AbstractControl,\r\n FormGroup,\r\n ValidationErrors,\r\n ValidatorFn,\r\n} from '@angular/forms';\r\n\r\n/**\r\n * Valida que el control contenga un rango de fechas válido (dos fechas no nulas y válidas).\r\n */\r\nexport function dateRangeValidator(\r\n control: AbstractControl,\r\n): ValidationErrors | null {\r\n const dates: Date[] = control.value;\r\n\r\n // Verificar si el valor es un array con exactamente dos elementos\r\n if (Array.isArray(dates) && dates.length === 2) {\r\n const [startDate, endDate] = dates;\r\n\r\n // Verificar que las fechas sean válidas y no nulas\r\n if (\r\n startDate &&\r\n endDate &&\r\n !isNaN(new Date(startDate).getTime()) &&\r\n !isNaN(new Date(endDate).getTime())\r\n ) {\r\n return null; // Válido\r\n } else {\r\n return {\r\n invalidDateRange: {\r\n message: 'Ambas fechas deben ser válidas y no nulas.',\r\n requiredLength: 2,\r\n },\r\n }; // Error si alguna fecha es nula o inválida\r\n }\r\n }\r\n return null; // Si el control no contiene un array válido, no hay error\r\n}\r\n\r\n/**\r\n * Validador a nivel de formulario que verifica que la fecha \"hasta\"\r\n * (toKey) sea mayor o igual que la fecha \"desde\" (fromKey),\r\n * comparando ambas como instancias de Date.\r\n *\r\n * Reglas:\r\n * - Si una o ambas fechas están vacías (null/undefined), no se genera error\r\n * y se delega la obligatoriedad a otros validadores como `required`.\r\n * - Si ambas fechas tienen valor, la fecha \"hasta\" debe ser >= fecha \"desde\"\r\n * según su valor numérico (`getTime()`).\r\n * - Si los valores no son fechas válidas, el comportamiento dependerá\r\n * de cómo los controles entreguen el valor (se recomienda usar Date).\r\n *\r\n * @param fromKey Nombre del control que representa la fecha inicial.\r\n * @param toKey Nombre del control que representa la fecha final.\r\n * @returns Un ValidatorFn que devuelve `null` si el rango es válido o está\r\n * incompleto; y un objeto con la clave `invalidDateRange` si el\r\n * rango es inválido.\r\n */\r\nexport function dateRangeValidatorFromTo(\r\n fromKey: string,\r\n toKey: string,\r\n): ValidatorFn {\r\n return (group: AbstractControl): ValidationErrors | null => {\r\n const fromControl = group.get(fromKey);\r\n const toControl = group.get(toKey);\r\n\r\n const from = fromControl?.value as Date | null;\r\n const to = toControl?.value as Date | null;\r\n\r\n if (!from || !to) return null;\r\n\r\n // Rango válido: limpiar error en el control \"hasta\" si existe\r\n if (to.getTime() >= from.getTime()) {\r\n if (toControl && toControl.errors?.['invalidDateRange']) {\r\n const { invalidDateRange, ...rest } = toControl.errors;\r\n toControl.setErrors(Object.keys(rest).length ? rest : null);\r\n }\r\n return null;\r\n }\r\n\r\n // Rango inválido: asignar error tanto al grupo como al control \"hasta\"\r\n const error: ValidationErrors = {\r\n invalidDateRange: {\r\n message: 'La fecha final debe ser mayor o igual que la fecha inicial.',\r\n requiredLength: 2,\r\n },\r\n };\r\n\r\n if (toControl) {\r\n const currentErrors = toControl.errors || {};\r\n toControl.setErrors({ ...currentErrors, ...error });\r\n }\r\n\r\n return error;\r\n };\r\n}\r\n\r\n/**\r\n * Valida que una fecha única esté dentro de un rango mínimo y máximo.\r\n * Las fechas deben utilizar la función de convertirFechaISOString para asegurar el formato correcto y que funcione con el componente primeNg.\r\n * @param minDate Fecha mínima permitida.\r\n * @param maxDate Fecha máxima permitida.\r\n */\r\nexport function dateMinMaxValidator(minDate: Date, maxDate: Date) {\r\n return (control: AbstractControl): ValidationErrors | null => {\r\n const date: Date = control.value;\r\n\r\n // Verificar si el valor es una fecha válida\r\n if (date && !isNaN(new Date(date).getTime())) {\r\n const currentDate = new Date(date);\r\n\r\n // Validar si la fecha está fuera del rango permitido\r\n if (currentDate < minDate || currentDate > maxDate) {\r\n return {\r\n dateNotRange: {\r\n message: `La fecha debe estar entre ${minDate.toLocaleDateString()} y ${maxDate.toLocaleDateString()}`,\r\n minDate: minDate.toISOString(),\r\n maxDate: maxDate.toISOString(),\r\n },\r\n };\r\n }\r\n\r\n return null; // Fecha válida y dentro del rango\r\n }\r\n\r\n return null;\r\n };\r\n}\r\n\r\n/**\r\n * Valida que al menos uno de los campos especificados esté lleno.\r\n * @param fields Los nombres de los campos a validar.\r\n */\r\nexport function atLeastOneFieldRequiredValidator(fields: string[]) {\r\n return (formGroup: AbstractControl): ValidationErrors | null => {\r\n // Obtener el FormGroup para poder acceder a los controles\r\n const form = formGroup as FormGroup;\r\n\r\n // Verificar si al menos uno de los campos tiene un valor\r\n const isAnyFieldFilled = fields.some((field) => {\r\n const control = form.get(field);\r\n return control?.value !== null && control?.value !== '';\r\n });\r\n\r\n // Si al menos un campo tiene un valor, la validación es exitosa\r\n if (isAnyFieldFilled) {\r\n return null; // Validación pasada\r\n } else {\r\n // Construir el mensaje dinámico con los campos no llenados\r\n const emptyFields = fields.filter((field) => {\r\n const control = form.get(field);\r\n return control?.value === null || control?.value === '';\r\n });\r\n\r\n const fieldNames = emptyFields.join(', ');\r\n const message = `Debe completar al menos uno de los siguientes campos: ${fieldNames}.`;\r\n\r\n // Si ninguno tiene valor, devolver el mensaje con el error\r\n return {\r\n atLeastOneRequired: {\r\n message: message,\r\n },\r\n };\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Validador personalizado para verificar si un NIT (Número de Identificación Tributaria) es válido.\r\n * Este validador se puede usar en formularios reactivos de Angular.\r\n *\r\n * @param control - El control del formulario que contiene el valor del NIT.\r\n * @returns Un objeto de error si el NIT no es válido, o `null` si el NIT es válido.\r\n */\r\nexport function nitValidator(\r\n control: AbstractControl,\r\n): ValidationErrors | null {\r\n const nit = control.value;\r\n\r\n // Si el campo está vacío, no hay error\r\n if (!nit) {\r\n return null;\r\n }\r\n\r\n // Validar el NIT utilizando la función NITCorrecto\r\n const esValido = NITCorrecto(nit);\r\n\r\n // Si el NIT no es válido, retornar un objeto de error con el formato deseado\r\n if (!esValido) {\r\n return {\r\n invalidNIT: {\r\n message: 'El NIT ingresado no es válido.', // Mensaje de error personalizado\r\n requiredLength: nit.length, // Longitud del NIT ingresado (opcional)\r\n },\r\n };\r\n }\r\n\r\n // Si el NIT es válido, retornar null (sin errores)\r\n return null;\r\n}\r\n\r\n/**\r\n * Función auxiliar para validar un NIT según un algoritmo específico.\r\n *\r\n * @param nit - El NIT a validar.\r\n * @returns `true` si el NIT es válido, `false` en caso contrario.\r\n */\r\nfunction NITCorrecto(nit: string): boolean {\r\n try {\r\n const largo = nit.length;\r\n // Invertir el NIT (excepto el último dígito) para facilitar el cálculo\r\n const validar = nit\r\n .substring(0, largo - 1)\r\n .split('')\r\n .reverse()\r\n .join('');\r\n const cadena = validar.split('');\r\n const comparador = nit.substring(largo - 1, largo); // Último dígito del NIT\r\n let posicion = 2; // Factor de ponderación inicial\r\n let sumaValidar = 0; // Acumulador para la suma ponderada\r\n\r\n // Calcular la suma ponderada de los dígitos del NIT\r\n for (const c of cadena) {\r\n sumaValidar += parseInt(c, 10) * posicion;\r\n posicion += 1;\r\n }\r\n\r\n // Calcular el residuo de la operación de validación\r\n const residuo = operacionValidar(11 - operacionValidar(sumaValidar));\r\n\r\n // Validar el NIT según el residuo y el último dígito\r\n if (residuo === 10 && comparador.toUpperCase() === 'K') {\r\n return true; // El NIT es válido si el residuo es 10 y el último dígito es 'K'\r\n } else if (residuo.toString() === comparador) {\r\n return true; // El NIT es válido si el residuo coincide con el último dígito\r\n } else {\r\n return false; // El NIT no es válido\r\n }\r\n } catch (error) {\r\n // Si ocurre un error durante la validación, el NIT no es válido\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Función auxiliar para calcular el residuo de una operación aritmética.\r\n *\r\n * @param valor - El valor sobre el cual se calculará el residuo.\r\n * @returns El residuo de la división del valor entre 11.\r\n */\r\nfunction operacionValidar(valor: number): number {\r\n return valor % 11;\r\n}\r\n\r\n/**\r\n * Validador personalizado para verificar si un CUI (Código Único de Identificación) es válido.\r\n * Este validador se puede usar en formularios reactivos de Angular.\r\n *\r\n * @param control - El control del formulario que contiene el valor del CUI.\r\n * @returns Un objeto de error si el CUI no es válido, o `null` si el CUI es válido.\r\n */\r\nexport function cuiValidator(\r\n control: AbstractControl,\r\n): ValidationErrors | null {\r\n const cui = control.value;\r\n\r\n // Si el campo está vacío, no hay error\r\n if (!cui) {\r\n return null;\r\n }\r\n\r\n // Validar el CUI\r\n const esValido = CUICorrecto(cui);\r\n\r\n // Si el CUI no es válido, retornar un objeto de error\r\n if (!esValido) {\r\n return {\r\n invalidCUI: {\r\n message: 'El CUI ingresado no es válido.',\r\n requiredLength: 13,\r\n actualLength: cui.length,\r\n },\r\n };\r\n }\r\n\r\n // Si el CUI es válido, retornar null (sin errores)\r\n return null;\r\n}\r\n\r\n/**\r\n * Función que implementa el algoritmo de validación del CUI\r\n * @param cui Número de CUI a validar (debe tener 13 dígitos)\r\n * @returns boolean indicando si el CUI es válido\r\n */\r\nfunction CUICorrecto(cui: string | number): boolean {\r\n // Convertir a string si es número\r\n const cuiStr = typeof cui === 'number' ? cui.toString() : cui;\r\n\r\n // Validar longitud y que sean solo dígitos\r\n if (cuiStr.length !== 13 || !/^\\d+$/.test(cuiStr)) {\r\n return false;\r\n }\r\n\r\n try {\r\n const primeros8 = cuiStr.substring(0, 8);\r\n const digitoVerificador = parseInt(cuiStr.substring(8, 9), 10);\r\n let suma = 0;\r\n\r\n // Calcular la suma ponderada\r\n for (let i = 0; i < primeros8.length; i++) {\r\n const digito = parseInt(primeros8[i], 10);\r\n suma += digito * (i + 2); // Los pesos son 2, 3, 4, ..., 9\r\n }\r\n\r\n // Calcular residuo y validar\r\n const residuo = suma % 11;\r\n return residuo === digitoVerificador;\r\n } catch (error) {\r\n console.error('Error validando CUI:', error);\r\n return false;\r\n }\r\n}\r\n","/*\r\n * Public API Surface of ngx-dsx\r\n */\r\nexport * from './lib/components';\r\nexport * from './lib/components/icon-dsx/icon-dsx.component';\r\nexport * from './lib/components/json/json-values-debuj/json-values-debuj.component';\r\nexport * from './lib/components/loading-lottie/loading-lottie.component';\r\nexport * from './lib/components/loading/css-v2/css-v2.component';\r\nexport * from './lib/components/loading/loading.component';\r\nexport * from './lib/components/logo/logo-dsx/logo-dsx.component';\r\nexport * from './lib/components/navbar-dsx/navbar-dsx.component';\r\nexport * from './lib/components/status/network-status/network-status.component';\r\nexport * from './lib/directives/src/arrow-navigation.directive';\r\nexport * from './lib/directives/src/only-rango-pattern.directive';\r\nexport * from './lib/directives/src/select-all-on-focus.directive';\r\nexport * from './lib/injections/cache.token';\r\nexport {\r\n ENVIRONMENT,\r\n provideEnvironment,\r\n SWEET_ALERT_THEMES,\r\n validateEnvironmentConfig,\r\n type EnvironmentConfig,\r\n type SweetAlertThemeType,\r\n} from './lib/injections/environment.token';\r\nexport * from './lib/injections/parameterSecurity';\r\nexport * from './lib/interceptors/http-authorize.interceptor';\r\nexport * from './lib/models';\r\nexport * from './lib/models/src/environment-base';\r\nexport * from './lib/models/src/field-config.model';\r\nexport * from './lib/models/src/parameterSecurity.model';\r\nexport * from './lib/modules/src/dsx-add-tools.module';\r\nexport * from './lib/modules/src/prime-ng.module';\r\nexport * from './lib/pipe';\r\nexport * from './lib/services/src/alerta.service';\r\nexport * from './lib/services/src/authorize.service';\r\nexport * from './lib/services/src/base-crud.service';\r\nexport * from './lib/services/src/cache.provider';\r\nexport * from './lib/services/src/cache.service';\r\nexport * from './lib/services/src/dte.service';\r\nexport * from './lib/services/src/endpoint.service';\r\nexport * from './lib/services/src/error-handler.service';\r\nexport * from './lib/services/src/http-helpers.service';\r\nexport * from './lib/services/src/master-detail-change.service';\r\nexport * from './lib/services/src/parameter-values.service';\r\nexport * from './lib/services/src/security.service';\r\nexport * from './lib/services/src/spinner-loading.service';\r\nexport * from './lib/services/src/utility-add.service';\r\nexport * from './lib/utils';\r\nexport * from './lib/validations/addons.validators';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i1.IconDsxService","i2"],"mappings":"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"}
1
+ {"version":3,"file":"ngx-dsxlibrary.mjs","sources":["../../../projects/ngx-dsx/src/lib/components/app-message-error/app-message-error.component.ts","../../../projects/ngx-dsx/src/lib/components/app-message-error/app-message-error.component.html","../../../projects/ngx-dsx/src/lib/components/inputs/file/file.component.ts","../../../projects/ngx-dsx/src/lib/components/inputs/file/file.component.html","../../../projects/ngx-dsx/src/lib/components/json/json-viewer/json-viewer.component.ts","../../../projects/ngx-dsx/src/lib/components/json/json-viewer/json-viewer.component.html","../../../projects/ngx-dsx/src/lib/components/kpicard/kpicard.component.ts","../../../projects/ngx-dsx/src/lib/components/kpicard/kpicard.component.html","../../../projects/ngx-dsx/src/lib/components/view/docx-preview/docx-preview.component.ts","../../../projects/ngx-dsx/src/lib/components/view/docx-preview/docx-preview.component.html","../../../projects/ngx-dsx/src/lib/services/src/icon-dsx.service.ts","../../../projects/ngx-dsx/src/lib/components/icon-dsx/icon-dsx.component.ts","../../../projects/ngx-dsx/src/lib/components/icon-dsx/icon-dsx.component.html","../../../projects/ngx-dsx/src/lib/pipe/src/json-highlight.pipe.ts","../../../projects/ngx-dsx/src/lib/injections/environment.token.ts","../../../projects/ngx-dsx/src/lib/components/json/json-values-debuj/json-values-debuj.component.ts","../../../projects/ngx-dsx/src/lib/components/json/json-values-debuj/json-values-debuj.component.html","../../../projects/ngx-dsx/src/lib/services/src/spinner-loading.service.ts","../../../projects/ngx-dsx/src/lib/components/logo/logo-dsx/logo-dsx.component.ts","../../../projects/ngx-dsx/src/lib/components/logo/logo-dsx/logo-dsx.component.html","../../../projects/ngx-dsx/src/lib/components/loading-lottie/loading-lottie.component.ts","../../../projects/ngx-dsx/src/lib/components/loading-lottie/loading-lottie.component.html","../../../projects/ngx-dsx/src/lib/components/loading/css-v2/css-v2.component.ts","../../../projects/ngx-dsx/src/lib/components/loading/css-v2/css-v2.component.html","../../../projects/ngx-dsx/src/lib/components/loading/loading.component.ts","../../../projects/ngx-dsx/src/lib/components/loading/loading.component.html","../../../projects/ngx-dsx/src/lib/services/src/alerta.service.ts","../../../projects/ngx-dsx/src/lib/models/src/environment-base.ts","../../../projects/ngx-dsx/src/lib/services/src/security.service.ts","../../../projects/ngx-dsx/src/lib/services/src/authorize.service.ts","../../../projects/ngx-dsx/src/lib/injections/parameterSecurity.ts","../../../projects/ngx-dsx/src/lib/services/src/parameter-values.service.ts","../../../projects/ngx-dsx/src/lib/services/src/request-metrics.service.ts","../../../projects/ngx-dsx/src/lib/components/status/network-status/network-status.component.ts","../../../projects/ngx-dsx/src/lib/components/status/network-status/network-status.component.html","../../../projects/ngx-dsx/src/lib/components/navbar-dsx/navbar-dsx.component.ts","../../../projects/ngx-dsx/src/lib/components/navbar-dsx/navbar-dsx.component.html","../../../projects/ngx-dsx/src/lib/directives/src/arrow-navigation.directive.ts","../../../projects/ngx-dsx/src/lib/directives/src/only-rango-pattern.directive.ts","../../../projects/ngx-dsx/src/lib/directives/src/select-all-on-focus.directive.ts","../../../projects/ngx-dsx/src/lib/injections/cache.token.ts","../../../projects/ngx-dsx/src/lib/services/src/error-handler.service.ts","../../../projects/ngx-dsx/src/lib/interceptors/http-authorize.interceptor.ts","../../../projects/ngx-dsx/src/lib/models/src/cache.types.ts","../../../projects/ngx-dsx/src/lib/modules/src/dsx-add-tools.module.ts","../../../projects/ngx-dsx/src/lib/modules/src/prime-ng.module.ts","../../../projects/ngx-dsx/src/lib/pipe/src/join-by.pipe.ts","../../../projects/ngx-dsx/src/lib/pipe/src/truncate.pipe.ts","../../../projects/ngx-dsx/src/lib/services/src/endpoint.service.ts","../../../projects/ngx-dsx/src/lib/services/src/base-crud.service.ts","../../../projects/ngx-dsx/src/lib/services/src/cache.service.ts","../../../projects/ngx-dsx/src/lib/services/src/cache.provider.ts","../../../projects/ngx-dsx/src/lib/services/src/dte.service.ts","../../../projects/ngx-dsx/src/lib/utils/src/form-data.util.ts","../../../projects/ngx-dsx/src/lib/services/src/http-helpers.service.ts","../../../projects/ngx-dsx/src/lib/services/src/master-detail-change.service.ts","../../../projects/ngx-dsx/src/lib/services/src/utility-add.service.ts","../../../projects/ngx-dsx/src/lib/utils/src/currency.util.ts","../../../projects/ngx-dsx/src/lib/validations/addons.validators.ts","../../../projects/ngx-dsx/src/public-api.ts","../../../projects/ngx-dsx/src/ngx-dsxlibrary.ts"],"sourcesContent":["import { DecimalPipe } from '@angular/common';\r\nimport {\r\n AfterViewInit,\r\n Component,\r\n DoCheck,\r\n ElementRef,\r\n Input,\r\n OnDestroy,\r\n Renderer2,\r\n} from '@angular/core';\r\nimport { AbstractControl, FormGroup } from '@angular/forms';\r\nimport { TagModule } from 'primeng/tag';\r\n\r\n@Component({\r\n selector: 'app-message-error',\r\n imports: [TagModule, DecimalPipe],\r\n templateUrl: './app-message-error.component.html',\r\n styleUrl: './app-message-error.component.css',\r\n})\r\n/**\r\n * Renderiza mensajes de validacion para un control o formulario.\r\n *\r\n * Nota de depuracion:\r\n * - En contenedores PrimeNG `p-floatlabel`, el mensaje visual se pinta como\r\n * overlay (CSS absoluto) para no deformar la posicion del label.\r\n * - Para evitar solapamiento con el siguiente campo, este componente ajusta\r\n * temporalmente el `margin-bottom` del `.p-floatlabel` padre cuando el error\r\n * esta visible.\r\n */\r\nexport class AppMessageErrorComponent\r\n implements AfterViewInit, DoCheck, OnDestroy\r\n{\r\n // Espacio vertical reservado bajo el float label cuando hay error visible.\r\n private readonly floatLabelErrorSpace = '1.25rem';\r\n // Referencia al contenedor PrimeNG padre, si existe.\r\n private floatLabelElement: HTMLElement | null = null;\r\n // Se conserva el estilo inline original para restaurarlo al ocultar/destruir.\r\n private previousInlineMarginBottom = '';\r\n // Evita escrituras de estilo repetidas cuando el estado de visibilidad no cambia.\r\n private lastAppliedVisibleState = false;\r\n\r\n constructor(\r\n private readonly elementRef: ElementRef<HTMLElement>,\r\n private readonly renderer: Renderer2,\r\n ) {}\r\n\r\n // Control de formulario que se pasa como input.\r\n @Input() control: AbstractControl | null | undefined = null;\r\n @Input() form: FormGroup | null = null;\r\n\r\n ngAfterViewInit(): void {\r\n // Busca el FloatLabel mas cercano para ajustar su separacion inferior.\r\n this.floatLabelElement = this.elementRef.nativeElement.closest(\r\n '.p-floatlabel',\r\n ) as HTMLElement | null;\r\n\r\n if (this.floatLabelElement) {\r\n this.previousInlineMarginBottom =\r\n this.floatLabelElement.style.marginBottom;\r\n this.syncFloatLabelSpacing();\r\n }\r\n }\r\n\r\n ngDoCheck(): void {\r\n // Se ejecuta en cada ciclo para reaccionar al estado touched/invalid.\r\n this.syncFloatLabelSpacing();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n if (!this.floatLabelElement) {\r\n return;\r\n }\r\n\r\n if (this.previousInlineMarginBottom) {\r\n this.renderer.setStyle(\r\n this.floatLabelElement,\r\n 'margin-bottom',\r\n this.previousInlineMarginBottom,\r\n );\r\n return;\r\n }\r\n\r\n this.renderer.removeStyle(this.floatLabelElement, 'margin-bottom');\r\n }\r\n\r\n private syncFloatLabelSpacing(): void {\r\n if (!this.floatLabelElement) {\r\n return;\r\n }\r\n\r\n const isVisible = !!(this.control?.touched && this.control?.invalid);\r\n if (isVisible === this.lastAppliedVisibleState) {\r\n return;\r\n }\r\n\r\n this.lastAppliedVisibleState = isVisible;\r\n if (isVisible) {\r\n this.renderer.setStyle(\r\n this.floatLabelElement,\r\n 'margin-bottom',\r\n this.floatLabelErrorSpace,\r\n );\r\n return;\r\n }\r\n\r\n if (this.previousInlineMarginBottom) {\r\n this.renderer.setStyle(\r\n this.floatLabelElement,\r\n 'margin-bottom',\r\n this.previousInlineMarginBottom,\r\n );\r\n return;\r\n }\r\n\r\n this.renderer.removeStyle(this.floatLabelElement, 'margin-bottom');\r\n }\r\n}\r\n","<div\r\n class=\"dsx-error-slot\"\r\n [class.is-visible]=\"control?.touched && control?.invalid\"\r\n>\r\n @if (control?.touched && control?.invalid) {\r\n <div class=\"dsx-error-message\">\r\n @if (control?.errors?.[\"required\"]) {\r\n El campo <strong>es requerido.</strong>\r\n } @else if (control?.errors?.[\"invalidNIT\"]) {\r\n <strong>{{ control?.errors?.[\"invalidNIT\"]?.message }}</strong\r\n >.\r\n } @else if (control?.errors?.[\"invalidCUI\"]) {\r\n <strong>{{ control?.errors?.[\"invalidCUI\"]?.message }}</strong\r\n >.\r\n } @else if (control?.errors?.[\"invalidDateRange\"]) {\r\n <strong>{{ control?.errors?.[\"invalidDateRange\"]?.message }}</strong\r\n >.\r\n } @else if (control?.errors?.[\"dateNotRange\"]) {\r\n <strong>{{ control?.errors?.[\"dateNotRange\"]?.message }}</strong\r\n >.\r\n } @else if (control?.errors?.[\"minlength\"]) {\r\n Debe tener al menos\r\n <strong>{{ control?.errors?.[\"minlength\"]?.requiredLength }}</strong>\r\n caracteres.\r\n } @else if (control?.errors?.[\"maxlength\"]) {\r\n Debe tener como máximo\r\n <strong>{{ control?.errors?.[\"maxlength\"]?.requiredLength }}</strong>\r\n caracteres.\r\n } @else if (control?.errors?.[\"min\"]) {\r\n El valor mínimo permitido es\r\n <strong>{{ control?.errors?.[\"min\"]?.min }}</strong\r\n >.\r\n } @else if (control?.errors?.[\"max\"]) {\r\n El valor máximo permitido es\r\n <strong>{{ control?.errors?.[\"max\"]?.max | number: \"1.2-2\" }}</strong\r\n >.\r\n } @else if (control?.errors?.[\"email\"]) {\r\n Debe ser una dirección de correo válida.\r\n } @else if (control?.errors?.[\"pattern\"]) {\r\n El campo no tiene el formato requerido.\r\n } @else {\r\n Existe un error aún no identificado.\r\n }\r\n </div>\r\n }\r\n</div>\r\n<!-- mensaje para formulario en general -->\r\n@if (form?.invalid && form?.touched) {\r\n <div class=\"mt-2 mb-2\">\r\n @if (this.form?.errors?.[\"atLeastOneRequired\"]) {\r\n <p-tag severity=\"danger\" [rounded]=\"true\">\r\n {{ form?.getError(\"atLeastOneRequired\")?.message }}</p-tag\r\n >\r\n }\r\n </div>\r\n}\r\n","import { Component, forwardRef, input, signal, viewChild } from '@angular/core';\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\r\nimport { FileUpload } from 'primeng/fileupload';\r\n\r\n@Component({\r\n selector: 'dsx-file-upload',\r\n imports: [FileUpload],\r\n templateUrl: './file.component.html',\r\n styleUrl: './file.component.css',\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => FileComponent),\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class FileComponent implements ControlValueAccessor {\r\n fileUpload = viewChild.required<FileUpload>('fileUpload');\r\n accept = input<string>('.xls,.xlsx');\r\n // Tamaño máximo en MB (se convierte internamente a bytes)\r\n maxFileSize = input<number>(5);\r\n // Mensajes para tipo de archivo inválido\r\n invalidSummary = input<string>('El formato es inválido.');\r\n invalidDetail = input<string>('Archivo debe tener un formato válido. ({0}).');\r\n\r\n // Mensajes para tamaño de archivo inválido\r\n invalidSizeSummary = input<string>('Tamaño de archivo inválido.');\r\n invalidSizeDetail = input<string>('El tamaño máximo permitido es {0}');\r\n disabled = signal<boolean>(false);\r\n private value: File | null = null;\r\n private onChange = (_: File | null) => {};\r\n private onTouched = () => {};\r\n\r\n onSelect(event: any) {\r\n const file = event.files?.[0] ?? null;\r\n this.value = file;\r\n this.onChange(file);\r\n this.onTouched();\r\n }\r\n\r\n /** 👇 API pública */\r\n clear() {\r\n this.fileUpload()?.clear();\r\n this.value = null;\r\n this.onChange(null);\r\n }\r\n\r\n writeValue(value: File | null): void {\r\n this.value = value;\r\n\r\n if (!value) {\r\n // Si se limpia el valor desde el formulario, limpiamos el componente\r\n this.fileUpload()?.clear();\r\n }\r\n }\r\n registerOnChange(fn: any): void {\r\n this.onChange = fn;\r\n }\r\n registerOnTouched(fn: any): void {\r\n this.onTouched = fn;\r\n }\r\n setDisabledState(isDisabled: boolean): void {\r\n this.disabled.set(isDisabled);\r\n }\r\n}\r\n","<p-fileUpload\r\n #fileUpload\r\n mode=\"basic\"\r\n [accept]=\"accept()\"\r\n [maxFileSize]=\"maxFileSize() * 1024 * 1024\"\r\n [invalidFileTypeMessageSummary]=\"invalidSummary()\"\r\n [invalidFileTypeMessageDetail]=\"invalidDetail()\"\r\n [invalidFileSizeMessageSummary]=\"invalidSizeSummary()\"\r\n [invalidFileSizeMessageDetail]=\"invalidSizeDetail()\"\r\n (onSelect)=\"onSelect($event)\"\r\n [disabled]=\"disabled()\"\r\n/>\r\n","import { Component, effect, forwardRef, input } from '@angular/core';\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\r\nimport { TreeNode } from 'primeng/api';\r\nimport { TreeModule } from 'primeng/tree';\r\n\r\n@Component({\r\n selector: 'app-json-viewer',\r\n standalone: true,\r\n imports: [TreeModule],\r\n templateUrl: './json-viewer.component.html',\r\n styleUrl: './json-viewer.component.css',\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => JsonViewerComponent),\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class JsonViewerComponent implements ControlValueAccessor {\r\n data = input<unknown>(null);\r\n nodes: TreeNode[] = [];\r\n selectedNode: TreeNode | null = null;\r\n private controlValue: unknown = null;\r\n\r\n constructor() {\r\n effect(() => {\r\n if (this.controlValue === null || this.controlValue === undefined) {\r\n this.updateNodes(this.data());\r\n }\r\n });\r\n }\r\n\r\n writeValue(value: unknown): void {\r\n this.controlValue = value;\r\n this.updateNodes(value);\r\n }\r\n\r\n registerOnChange(fn: (value: unknown) => void): void {\r\n void fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n void fn;\r\n }\r\n\r\n setDisabledState(isDisabled: boolean): void {\r\n void isDisabled;\r\n }\r\n\r\n onNodeSelect(event: { node?: TreeNode }): void {\r\n const node = event?.node;\r\n\r\n if (!node?.children?.length) return;\r\n\r\n node.expanded = !node.expanded;\r\n this.selectedNode = null;\r\n this.nodes = [...this.nodes];\r\n }\r\n\r\n private updateNodes(value: unknown): void {\r\n this.nodes = this.buildTree(this.parseIfNeeded(value));\r\n }\r\n\r\n private parseIfNeeded(data: unknown): any {\r\n if (!data) return {};\r\n\r\n if (typeof data === 'string') {\r\n try {\r\n return JSON.parse(data);\r\n } catch {\r\n return {};\r\n }\r\n }\r\n\r\n return data;\r\n }\r\n\r\n private buildTree(data: any, parentKey: string = '0'): TreeNode[] {\r\n if (Array.isArray(data)) {\r\n return data.map((item, index) => {\r\n const key = `${parentKey}-${index}`;\r\n\r\n if (this.isComplex(item)) {\r\n return {\r\n key,\r\n label: `[${index}]`,\r\n //icon: this.getIcon(item),\r\n children: this.buildTree(item, key),\r\n };\r\n }\r\n\r\n return {\r\n key,\r\n label: `[${index}]: ${this.formatPrimitive(item)}`,\r\n //icon: 'pi pi-file',\r\n };\r\n });\r\n }\r\n\r\n if (typeof data === 'object' && data !== null) {\r\n return Object.keys(data).map((key, index) => {\r\n const value = data[key];\r\n const nodeKey = `${parentKey}-${index}`;\r\n\r\n if (this.isComplex(value)) {\r\n return {\r\n key: nodeKey,\r\n label: key,\r\n //icon: this.getIcon(value),\r\n children: this.buildTree(value, nodeKey),\r\n };\r\n }\r\n\r\n return {\r\n key: nodeKey,\r\n label: `${key}: ${this.formatPrimitive(value)}`,\r\n icon: 'pi pi-file',\r\n };\r\n });\r\n }\r\n\r\n return [\r\n {\r\n key: parentKey,\r\n label: this.formatPrimitive(data),\r\n icon: 'pi pi-file',\r\n },\r\n ];\r\n }\r\n\r\n private isComplex(value: unknown): boolean {\r\n return (\r\n Array.isArray(value) || (typeof value === 'object' && value !== null)\r\n );\r\n }\r\n\r\n private formatPrimitive(value: unknown): string {\r\n if (value === null || value === undefined) return '-';\r\n\r\n if (typeof value === 'string') return value;\r\n\r\n return String(value);\r\n }\r\n\r\n private getIcon(value: any): string {\r\n if (Array.isArray(value)) return 'pi pi-list';\r\n\r\n if (typeof value === 'object') return 'pi pi-folder';\r\n\r\n return 'pi pi-file';\r\n }\r\n}\r\n","<p-tree\r\n\t[value]=\"nodes\"\r\n\tclass=\"json-tree w-full\"\r\n\tselectionMode=\"single\"\r\n\t[(selection)]=\"selectedNode\"\r\n\t[highlightOnSelect]=\"false\"\r\n\t(onNodeSelect)=\"onNodeSelect($event)\"\r\n>\r\n</p-tree>\r\n","import { Component, input } from '@angular/core';\r\nimport { CountUpDirective } from 'ngx-countup';\r\n\r\n@Component({\r\n selector: 'app-kpicard',\r\n imports: [CountUpDirective],\r\n templateUrl: './kpicard.component.html',\r\n styleUrl: './kpicard.component.css',\r\n})\r\nexport class KpicardComponent {\r\n //type = input.required<string>();\r\n option = input.required<'currency' | 'integer' | 'percent'>();\r\n label = input.required<string>();\r\n iconType = input<string>('fa-regular fa-bell');\r\n color = input<string>();\r\n valor = input<number>(0);\r\n theme = input<\r\n | 'light'\r\n | 'dark'\r\n | 'aqua'\r\n | 'sunset'\r\n | 'mint'\r\n | 'peach'\r\n | 'plasma'\r\n | 'nebula'\r\n >('light');\r\n\r\n options: Record<'currency' | 'integer' | 'percent', any> = {\r\n currency: {\r\n startVal: 0,\r\n duration: 0.5,\r\n //prefix: 'Q',\r\n decimalPlaces: 2, // Decimales\r\n useGrouping: true, // Separador de miles\r\n separator: ',', // Carácter separador\r\n decimal: '.', // Carácter decimal\r\n suffix: ' GTQ', // Sufijo\r\n scrollSpyDelay: 200, // Retardo antes de la animación\r\n enableScrollSpy: true,\r\n scrollSpyOnce: true,\r\n },\r\n integer: {\r\n startVal: 0,\r\n duration: 0.5,\r\n prefix: 'Cant. ',\r\n decimalPlaces: 2, // Decimales\r\n useGrouping: true, // Separador de miles\r\n separator: ',', // Carácter separador\r\n decimal: '.', // Carácter decimal\r\n scrollSpyDelay: 200, // Retardo antes de la animación\r\n enableScrollSpy: true,\r\n scrollSpyOnce: true,\r\n },\r\n percent: {\r\n startVal: 0,\r\n duration: 0.5,\r\n suffix: '%',\r\n decimalPlaces: 2, // Decimales\r\n useGrouping: true, // Separador de miles\r\n separator: ',', // Carácter separador\r\n decimal: '.', // Carácter decimal\r\n scrollSpyDelay: 200, // Retardo antes de la animación\r\n enableScrollSpy: true,\r\n scrollSpyOnce: true,\r\n },\r\n };\r\n\r\n // ✅ Método auxiliar para obtener la opción con seguridad\r\n getSelectedOption() {\r\n return this.options[this.option()] ?? this.options.currency; // Si no existe, usa `currency`\r\n }\r\n}\r\n","<div [class]=\"`kpi-card ${color()} ${theme()}-theme`\">\r\n <div class=\"kpi-container\">\r\n <span\r\n [countUp]=\"valor()\"\r\n [countUpOptions]=\"getSelectedOption()\"\r\n [class]=\"`card-value-${theme()}`\"\r\n >0</span\r\n >\r\n <span [class]=\"`card-text-${theme()}`\">{{ label() }}</span>\r\n </div>\r\n <i [class]=\"`${iconType()} icon icon-${theme()}`\"></i>\r\n</div>\r\n","import {\r\n Component,\r\n effect,\r\n ElementRef,\r\n EventEmitter,\r\n Input,\r\n input,\r\n Output,\r\n signal,\r\n viewChild,\r\n WritableSignal,\r\n} from '@angular/core';\r\nimport { DialogModule } from 'primeng/dialog';\r\n\r\ntype DocxRenderOptions = {\r\n ignoreWidth?: boolean;\r\n renderHeaders?: boolean;\r\n renderFooters?: boolean;\r\n};\r\n\r\n@Component({\r\n selector: 'app-docx-preview',\r\n imports: [DialogModule],\r\n templateUrl: './docx-preview.component.html',\r\n styleUrl: './docx-preview.component.css',\r\n})\r\nexport class DocxPreviewComponent {\r\n view = viewChild<ElementRef>('viewer');\r\n private visibleState: WritableSignal<boolean> = signal(false);\r\n private renderToken = 0;\r\n\r\n @Input()\r\n set visible(value: boolean) {\r\n this.visibleState.set(!!value);\r\n }\r\n\r\n get visible(): boolean {\r\n return this.visibleState();\r\n }\r\n\r\n @Output() visibleChange = new EventEmitter<boolean>();\r\n blob = input<Blob | null>(null);\r\n\r\n constructor() {\r\n effect(() => {\r\n const container = this.view()?.nativeElement;\r\n const isVisible = this.visibleState();\r\n const fileBlob = this.blob();\r\n\r\n if (!container) {\r\n return;\r\n }\r\n\r\n if (!isVisible) {\r\n this.renderToken++;\r\n container.innerHTML = '';\r\n return;\r\n }\r\n\r\n if (!(fileBlob instanceof Blob)) {\r\n this.renderToken++;\r\n container.innerHTML =\r\n '<p>No hay un archivo .docx válido para previsualizar.</p>';\r\n return;\r\n }\r\n\r\n if (!fileBlob.size) {\r\n this.renderToken++;\r\n container.innerHTML = '<p>El archivo .docx está vacío.</p>';\r\n return;\r\n }\r\n\r\n const token = ++this.renderToken;\r\n container.innerHTML = '';\r\n const options: DocxRenderOptions = {\r\n ignoreWidth: true,\r\n renderHeaders: true,\r\n renderFooters: true,\r\n };\r\n\r\n void this.renderDocx(fileBlob, container, options, token);\r\n });\r\n }\r\n\r\n private async renderDocx(\r\n fileBlob: Blob,\r\n container: HTMLElement,\r\n options: DocxRenderOptions,\r\n token: number,\r\n ) {\r\n try {\r\n const dynamicImport = new Function(\r\n 'modulePath',\r\n 'return import(modulePath);',\r\n ) as (modulePath: string) => Promise<{ renderAsync: Function }>;\r\n\r\n const docxPreviewModule = await dynamicImport('docx-preview');\r\n\r\n if (token !== this.renderToken || !this.visibleState()) {\r\n return;\r\n }\r\n\r\n await docxPreviewModule.renderAsync(\r\n fileBlob,\r\n container,\r\n undefined,\r\n options,\r\n );\r\n } catch {\r\n if (token !== this.renderToken || !this.visibleState()) {\r\n return;\r\n }\r\n\r\n container.innerHTML =\r\n '<p>No se pudo cargar la vista previa DOCX. Instala <strong>docx-preview</strong> para habilitar esta función.</p>';\r\n }\r\n }\r\n\r\n onHide() {\r\n const container = this.view()?.nativeElement;\r\n\r\n if (container) {\r\n this.renderToken++;\r\n container.innerHTML = '';\r\n }\r\n\r\n this.visibleChange.emit(false);\r\n }\r\n}\r\n","<p-dialog\r\n header=\"Vista preliminar del documento\"\r\n [visible]=\"visible\"\r\n (onHide)=\"onHide()\"\r\n [modal]=\"true\"\r\n [breakpoints]=\"{ '1199px': '75vw', '575px': '90vw' }\"\r\n [style]=\"{ width: '80vw' }\"\r\n [draggable]=\"false\"\r\n [resizable]=\"false\"\r\n>\r\n <div #viewer></div>\r\n</p-dialog>\r\n","import { HttpClient } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\r\nimport { catchError, map, Observable, of, shareReplay } from 'rxjs';\r\n\r\n/** SVG de warning_amber como fallback cuando no se encuentra un icono */\r\nconst WARNING_AMBER_SVG = `<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"currentColor\"><path d=\"M80-160v-80h800v80H80Zm40-120 360-560 360 560H120Zm178-80h364L480-660 298-360Zm182 0Z\"/></svg>`;\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class IconDsxService {\r\n private cache = new Map<string, Observable<SafeHtml>>();\r\n\r\n constructor(\r\n private http: HttpClient,\r\n private sanitizer: DomSanitizer,\r\n ) {}\r\n\r\n /** Carga SVG desde assets/dsxResource/material-design-icons/outlined */\r\n getIcon(name: string): Observable<SafeHtml> {\r\n if (this.cache.has(name)) {\r\n return this.cache.get(name)!;\r\n }\r\n\r\n const iconPath = `mdio/${name}.svg`;\r\n\r\n const request$ = this.http.get(iconPath, { responseType: 'text' }).pipe(\r\n map((svg) => this.sanitizer.bypassSecurityTrustHtml(svg)),\r\n catchError(() => {\r\n return of(this.sanitizer.bypassSecurityTrustHtml(WARNING_AMBER_SVG));\r\n }),\r\n shareReplay(1),\r\n );\r\n\r\n this.cache.set(name, request$);\r\n return request$;\r\n }\r\n}\r\n","import { AsyncPipe } from '@angular/common';\r\nimport { Component, Input } from '@angular/core';\r\nimport { SafeHtml } from '@angular/platform-browser';\r\nimport { Observable } from 'rxjs';\r\nimport { IconDsxService } from '../../services/src/icon-dsx.service';\r\n\r\n@Component({\r\n selector: 'icon-dsx',\r\n imports: [AsyncPipe],\r\n templateUrl: './icon-dsx.component.html',\r\n styleUrl: './icon-dsx.component.css',\r\n})\r\nexport class IconDsxComponent {\r\n @Input() name!: string;\r\n\r\n svg$!: Observable<SafeHtml>; // 👈 AHORA es un Observable\r\n\r\n constructor(private iconService: IconDsxService) {}\r\n\r\n ngOnInit(): void {\r\n this.svg$ = this.iconService.getIcon(this.name); // 👈 AHORA CUADRA CON EL async\r\n }\r\n}\r\n","<span class=\"dsx-icon\" [innerHTML]=\"svg$ | async\"></span>\r\n","import { Pipe, PipeTransform } from '@angular/core';\r\n\r\n@Pipe({\r\n name: 'jsonHighlight',\r\n})\r\nexport class JsonHighlightPipe implements PipeTransform {\r\n /**\r\n * Stringifica el JSON manteniendo arrays en una línea para una vista más compacta\r\n */\r\n private compactStringify(obj: any, indent: number = 2): string {\r\n const spaces = ' '.repeat(indent);\r\n\r\n if (obj === null) {\r\n return 'null';\r\n }\r\n\r\n if (typeof obj !== 'object') {\r\n if (typeof obj === 'string') {\r\n return JSON.stringify(obj);\r\n }\r\n return String(obj);\r\n }\r\n\r\n if (obj instanceof Date) {\r\n return JSON.stringify(obj.toISOString());\r\n }\r\n\r\n if (Array.isArray(obj)) {\r\n // Mantener arrays en una línea\r\n const items = obj.map((item) => {\r\n if (item instanceof Date) {\r\n return JSON.stringify(item.toISOString());\r\n }\r\n if (typeof item === 'object' && item !== null) {\r\n return this.compactStringify(item, indent);\r\n }\r\n return typeof item === 'string'\r\n ? JSON.stringify(item)\r\n : item === null\r\n ? 'null'\r\n : String(item);\r\n });\r\n return `[${items.join(', ')}]`;\r\n }\r\n\r\n // Para objetos, mantener la indentación\r\n const keys = Object.keys(obj);\r\n if (keys.length === 0) {\r\n return '{}';\r\n }\r\n\r\n const innerIndent = indent + 2;\r\n const innerSpaces = ' '.repeat(innerIndent);\r\n const lines = keys.map((key) => {\r\n const value = obj[key];\r\n const stringified =\r\n value instanceof Date\r\n ? JSON.stringify(value.toISOString())\r\n : typeof value === 'object' && value !== null\r\n ? this.compactStringify(value, innerIndent)\r\n : typeof value === 'string'\r\n ? JSON.stringify(value)\r\n : value === null\r\n ? 'null'\r\n : String(value);\r\n return `${innerSpaces}\"${key}\": ${stringified}`;\r\n });\r\n\r\n return `{\\n${lines.join(',\\n')}\\n${spaces}}`;\r\n }\r\n\r\n transform(value: any): string {\r\n if (!value) {\r\n return '';\r\n }\r\n\r\n const json = this.compactStringify(value);\r\n // Detecta fechas ISO: \"YYYY-MM-DDTHH:MM:SS.mmmZ\"\r\n const ISO_DATE_RE = /^\"(\\d{4}-\\d{2}-\\d{2})T(\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)\"$/;\r\n\r\n // Aplica estilo y colores para diferenciar claves, valores, booleanos, números, etc.\r\n return json\r\n .replace(/&/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/(\"(\\\\u[a-zA-Z0-9]{4}|\\\\[^u]|[^\\\\\"])*\"(\\s*:)?)/g, (match) => {\r\n // Si es una clave (tiene dos puntos al final)\r\n if (/:$/.test(match)) {\r\n return `<span class=\"json-key\">${match}</span>`;\r\n }\r\n // Detectar fechas ISO (YYYY-MM-DDTHH:MM:SS.mmmZ)\r\n const isoMatch = match.match(ISO_DATE_RE);\r\n if (isoMatch) {\r\n return `<span class=\"json-string json-date\">\"<span class=\"json-date-part\">${isoMatch[1]}</span><span class=\"json-date-sep\">T</span><span class=\"json-date-time\">${isoMatch[2]}</span>\"</span>`;\r\n }\r\n // Si es un string (no tiene dos puntos)\r\n return `<span class=\"json-string\">${match}</span>`;\r\n })\r\n .replace(/\\b(true|false|null)\\b/g, (match) => {\r\n if (match === 'null') {\r\n return '<span class=\"json-null\">null</span>';\r\n }\r\n return `<span class=\"json-boolean\">${match}</span>`;\r\n })\r\n .replace(/\\b(\\d+\\.?\\d*)\\b/g, '<span class=\"json-number\">$1</span>')\r\n .replace(/[{}\\[\\]]/g, '<span class=\"json-bracket\">$&</span>')\r\n .replace(/,/g, '<span class=\"json-comma\">$&</span>')\r\n .replace(/:/g, '<span class=\"json-colon\">$&</span>');\r\n }\r\n}\r\n","import { InjectionToken, Provider } from '@angular/core';\r\n\r\n/**\r\n * Valores válidos para el tema de SweetAlert2.\r\n * Esta constante permite autocompletado y validación en tiempo de compilación.\r\n *\r\n * @example\r\n * ```typescript\r\n * // En environment.ts\r\n * export const environment: EnvironmentConfig = {\r\n * // ...otros campos\r\n * sweetAlertTheme: 'dark', // ✅ Autocompletado disponible\r\n * };\r\n * ```\r\n */\r\nexport const SWEET_ALERT_THEMES = [\r\n 'auto',\r\n 'light',\r\n 'dark',\r\n 'default',\r\n 'bootstrap-4',\r\n 'borderless',\r\n 'bulma',\r\n 'material-ui',\r\n 'minimal',\r\n 'wordpress-admin',\r\n] as const;\r\n\r\n/**\r\n * Tipo literal para los temas válidos de SweetAlert2.\r\n * Se genera automáticamente desde la constante SWEET_ALERT_THEMES.\r\n */\r\nexport type SweetAlertThemeType = (typeof SWEET_ALERT_THEMES)[number];\r\n\r\n/**\r\n * Esquema de configuración del entorno - Fuente única de verdad (Single Source of Truth)\r\n *\r\n * Este objeto define todos los campos requeridos y sus tipos esperados para la configuración del entorno.\r\n * Sirve como referencia automática para:\r\n * - Generar el tipo TypeScript `EnvironmentConfig`\r\n * - Validar la presencia de campos requeridos\r\n * - Validar los tipos de datos en runtime\r\n * - Detectar automáticamente campos que requieren validación especial (URLs)\r\n *\r\n * **Cómo agregar una nueva propiedad:**\r\n * 1. Agrégala a este objeto con su tipo: 'string', 'boolean' o 'number'\r\n * 2. Todo lo demás se actualiza automáticamente (tipo TypeScript, validaciones, etc.)\r\n *\r\n * @example\r\n * ```typescript\r\n * const ENVIRONMENT_SCHEMA = {\r\n * production: 'boolean' as const,\r\n * myAppUrl: 'string' as const,\r\n * apiTimeout: 'number' as const, // ← Agregar nueva propiedad\r\n * } as const;\r\n * ```\r\n *\r\n * @internal\r\n */\r\nconst ENVIRONMENT_SCHEMA = {\r\n production: 'boolean' as const,\r\n myAppUrl: 'string' as const,\r\n SeguridadITApiUrl: 'string' as const,\r\n tokenName: 'string' as const,\r\n tokenNameRF: 'string' as const,\r\n sessionStatus: 'string' as const,\r\n refreshTokenExpiry: 'string' as const,\r\n rolIndex: 'number' as const,\r\n} as const;\r\n\r\n/**\r\n * Tipo que define la configuración del entorno de la aplicación.\r\n *\r\n * Este tipo se genera automáticamente a partir de `ENVIRONMENT_SCHEMA` usando\r\n * TypeScript mapped types. No es necesario mantenerlo manualmente.\r\n *\r\n * **Características:**\r\n * - Se sincroniza automáticamente con ENVIRONMENT_SCHEMA\r\n * - Proporciona autocompletado en IDEs\r\n * - Garantiza type-safety en tiempo de compilación\r\n * - Se valida en runtime usando `provideEnvironment()`\r\n *\r\n * **Campos requeridos:**\r\n * @property production - Indica si la aplicación está en modo producción\r\n * @property myAppUrl - URL base de la aplicación principal (debe incluir protocolo http:// o https://)\r\n * @property SeguridadITApiUrl - URL base de la API de seguridad (debe incluir protocolo http:// o https://)\r\n * @property tokenName - Nombre del token de acceso en el almacenamiento local/sesión\r\n * @property tokenNameRF - Nombre del refresh token en el almacenamiento local/sesión\r\n * @property sessionStatus - Nombre de la clave para el estado de sesión\r\n * @property refreshTokenExpiry - Tiempo de expiración del refresh token (ej: \"7d\", \"24h\")\r\n * @property rolIndex - Índice lógico (1-based) del rol principal asociado al entorno\r\n *\r\n * **Campos opcionales:**\r\n * @property sweetAlertTheme - Tema visual global para SweetAlert2 ('auto' | 'light' | 'dark' | 'default' | 'bootstrap-4' | 'borderless' | 'bulma' | 'material-ui' | 'minimal' | 'wordpress-admin')\r\n *\r\n * @example\r\n * ```typescript\r\n * // En tu archivo environment.ts\r\n * import { EnvironmentConfig } from '@devsoftxela/ngx-dsx';\r\n *\r\n * export const environment: EnvironmentConfig = {\r\n * production: false,\r\n * myAppUrl: 'http://localhost:4200/',\r\n * SeguridadITApiUrl: 'http://localhost:5000/',\r\n * tokenName: 'access_token',\r\n * tokenNameRF: 'refresh_token',\r\n * sessionStatus: 'session_status',\r\n * refreshTokenExpiry: '7d',\r\n * sweetAlertTheme: 'dark' // ← Tema global para alertas (opcional)\r\n * };\r\n * ```\r\n */\r\nexport type EnvironmentConfig = {\r\n [K in keyof typeof ENVIRONMENT_SCHEMA]: (typeof ENVIRONMENT_SCHEMA)[K] extends 'string'\r\n ? string\r\n : (typeof ENVIRONMENT_SCHEMA)[K] extends 'boolean'\r\n ? boolean\r\n : (typeof ENVIRONMENT_SCHEMA)[K] extends 'number'\r\n ? number\r\n : never;\r\n} & {\r\n /**\r\n * Tema visual global para las alertas SweetAlert2.\r\n * Es opcional. Si no se define, se usará el tema por defecto de SweetAlert2.\r\n *\r\n * Valores válidos: 'auto' | 'light' | 'dark' | 'default' | 'bootstrap-4' |\r\n * 'borderless' | 'bulma' | 'material-ui' | 'minimal' | 'wordpress-admin'\r\n *\r\n * @example\r\n * ```typescript\r\n * sweetAlertTheme: 'dark' // Tema oscuro\r\n * sweetAlertTheme: 'minimal' // Tema minimalista\r\n * sweetAlertTheme: 'auto' // Detecta según preferencias del sistema\r\n * ```\r\n */\r\n /**\r\n * Tema visual global para las alertas SweetAlert2.\r\n *\r\n * Se define como `SweetAlertThemeType` para que TypeScript emita un error\r\n * en tiempo de compilación cuando se utilice un valor no válido.\r\n *\r\n * Si por alguna razón necesitas permitir cadenas arbitrarias (no\r\n * recomendadas), utiliza `EnvironmentConfigLenient` exportado más abajo.\r\n */\r\n sweetAlertTheme?: SweetAlertThemeType;\r\n /**\r\n * Lista de roles que se utilizan para las guardas de rutas.\r\n * Debe ser un arreglo no vacío de strings.\r\n */\r\n rolesGuards: string[];\r\n};\r\n\r\n/**\r\n * Variante leniente del tipo `EnvironmentConfig` que permite strings\r\n * arbitrarios en `sweetAlertTheme` (mantiene compatibilidad hacia atrás).\r\n *\r\n * Úsalo solo si realmente necesitas pasar valores no listados en\r\n * `SWEET_ALERT_THEMES` y entiendes que no habrá chequeo estático.\r\n */\r\nexport type EnvironmentConfigLenient = Omit<\r\n EnvironmentConfig,\r\n 'sweetAlertTheme'\r\n> & {\r\n sweetAlertTheme?: SweetAlertThemeType | (string & {});\r\n};\r\n\r\n/**\r\n * Token de inyección de dependencias para la configuración del entorno.\r\n *\r\n * Este token se utiliza para inyectar la configuración del entorno en servicios y componentes.\r\n * **IMPORTANTE:** No uses este token directamente en providers. En su lugar, usa la función\r\n * `provideEnvironment()` que incluye validación automática.\r\n *\r\n * @example\r\n * ```typescript\r\n * // ✅ Forma correcta - En tu configuración de app\r\n * import { provideEnvironment } from '@devsoftxela/ngx-dsx';\r\n * import { environment } from './environments/environment';\r\n *\r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [\r\n * provideEnvironment(environment), // ← Con validación automática\r\n * ]\r\n * };\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // ✅ Forma correcta - Inyectar en servicios\r\n * import { inject } from '@angular/core';\r\n * import { ENVIRONMENT, EnvironmentConfig } from '@devsoftxela/ngx-dsx';\r\n *\r\n * export class MiServicio {\r\n * private environment: EnvironmentConfig = inject(ENVIRONMENT);\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // ❌ Forma incorrecta - Sin validación\r\n * providers: [\r\n * { provide: ENVIRONMENT, useValue: environment } // ← Sin validación\r\n * ]\r\n * ```\r\n *\r\n * @see {@link provideEnvironment} para configurar con validación\r\n * @see {@link EnvironmentConfig} para la estructura de datos\r\n */\r\nexport const ENVIRONMENT = new InjectionToken<EnvironmentConfig>(\r\n 'EnvironmentConfig',\r\n);\r\n\r\n/**\r\n * Valida que la configuración del entorno esté completa y correctamente configurada.\r\n *\r\n * Esta función verifica que:\r\n * - La configuración del entorno no sea null o undefined\r\n * - Todas las propiedades requeridas estén presentes y no estén vacías\r\n * - Las URLs tengan un formato válido\r\n *\r\n * @param environment - Configuración del entorno a validar\r\n * @throws Error si alguna validación falla, con un mensaje descriptivo del problema\r\n *\r\n * @example\r\n * ```typescript\r\n * const config: EnvironmentConfig = { ... };\r\n * validateEnvironmentConfig(config);\r\n * ```\r\n */\r\nexport function validateEnvironmentConfig(\r\n environment: EnvironmentConfig,\r\n): void {\r\n if (!environment) {\r\n throw new Error(\r\n '[ENVIRONMENT] La configuración del entorno no está definida. ' +\r\n 'Asegúrate de proporcionar una configuración válida usando provideEnvironment().',\r\n );\r\n }\r\n\r\n // Obtener automáticamente todos los campos requeridos del schema\r\n // Usamos keyof typeof ENVIRONMENT_SCHEMA para solo validar campos del schema base\r\n const requiredFields = Object.keys(\r\n ENVIRONMENT_SCHEMA,\r\n ) as (keyof typeof ENVIRONMENT_SCHEMA)[];\r\n\r\n const missingFields: string[] = [];\r\n const emptyFields: string[] = [];\r\n const wrongTypeFields: string[] = [];\r\n\r\n // Validar que todos los campos requeridos existan, no estén vacíos y tengan el tipo correcto\r\n requiredFields.forEach((field) => {\r\n const expectedType = ENVIRONMENT_SCHEMA[field];\r\n\r\n if (!(field in environment)) {\r\n missingFields.push(field);\r\n } else if (\r\n environment[field] === null ||\r\n environment[field] === undefined\r\n ) {\r\n emptyFields.push(field);\r\n } else {\r\n // Validar tipo de dato\r\n const actualType = typeof environment[field];\r\n if (actualType !== expectedType) {\r\n wrongTypeFields.push(\r\n `${field} (esperado: ${expectedType}, recibido: ${actualType})`,\r\n );\r\n }\r\n\r\n // Validar que strings no estén vacíos\r\n if (\r\n expectedType === 'string' &&\r\n typeof environment[field] === 'string' &&\r\n (environment[field] as string).trim() === ''\r\n ) {\r\n emptyFields.push(field);\r\n }\r\n }\r\n });\r\n\r\n // Reportar campos faltantes\r\n if (missingFields.length > 0) {\r\n throw new Error(\r\n `[ENVIRONMENT] Faltan los siguientes campos en la configuración del entorno: ${missingFields.join(\r\n ', ',\r\n )}. ` + 'Por favor, verifica tu configuración de environment.',\r\n );\r\n }\r\n\r\n // Reportar campos vacíos\r\n if (emptyFields.length > 0) {\r\n throw new Error(\r\n `[ENVIRONMENT] Los siguientes campos están vacíos en la configuración del entorno: ${emptyFields.join(\r\n ', ',\r\n )}. ` + 'Por favor, proporciona valores válidos para estos campos.',\r\n );\r\n }\r\n\r\n // Reportar campos con tipo incorrecto\r\n if (wrongTypeFields.length > 0) {\r\n throw new Error(\r\n `[ENVIRONMENT] Los siguientes campos tienen un tipo de dato incorrecto: ${wrongTypeFields.join(\r\n ', ',\r\n )}. ` + 'Por favor, corrige los tipos de datos.',\r\n );\r\n }\r\n\r\n // Validar formato de URLs (solo para campos que contengan 'url' en su nombre)\r\n requiredFields.forEach((field) => {\r\n if (\r\n field.toLowerCase().includes('url') &&\r\n typeof environment[field] === 'string'\r\n ) {\r\n validateUrl(field as string, environment[field] as string);\r\n }\r\n });\r\n\r\n // Validar rolesGuards\r\n if (\r\n !Array.isArray(environment.rolesGuards) ||\r\n environment.rolesGuards.length === 0 ||\r\n !environment.rolesGuards.every(\r\n (r) => typeof r === 'string' && r.trim().length > 0,\r\n )\r\n ) {\r\n throw new Error(\r\n \"[ENVIRONMENT] El campo 'rolesGuards' debe ser un arreglo no vacío de cadenas de texto válidas.\",\r\n );\r\n }\r\n\r\n // Validar sweetAlertTheme si está definido: emitir warning y usar tema por defecto si es inválido\r\n if (\r\n environment.sweetAlertTheme !== undefined &&\r\n typeof environment.sweetAlertTheme === 'string'\r\n ) {\r\n const allowedThemes = SWEET_ALERT_THEMES as readonly string[];\r\n if (!allowedThemes.includes(environment.sweetAlertTheme)) {\r\n console.warn(\r\n `[ENVIRONMENT] Valor no reconocido para 'sweetAlertTheme': '${environment.sweetAlertTheme}'. Temas válidos: ${allowedThemes.join(\r\n ', ',\r\n )}. Se usará el tema por defecto de SweetAlert2.`,\r\n );\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Valida que una URL tenga un formato válido.\r\n * Permite tanto URLs absolutas (http://..., https://...) como rutas relativas (/, /api, etc.).\r\n *\r\n * @param fieldName - Nombre del campo para mensajes de error\r\n * @param url - URL a validar\r\n * @throws Error si la URL no tiene un formato válido\r\n */\r\nfunction validateUrl(fieldName: string, url: string): void {\r\n // Patrón para rutas relativas (comienzan con /)\r\n const relativePathPattern = /^\\/[^/]*/;\r\n\r\n // Si es una ruta relativa, solo validar que sea válida\r\n if (relativePathPattern.test(url)) {\r\n // Validar que la URL termine con '/' para evitar problemas de concatenación\r\n if (!url.endsWith('/')) {\r\n console.warn(\r\n `[ENVIRONMENT] Advertencia: El campo '${fieldName}' no termina con '/'. ` +\r\n `Valor actual: '${url}'. Se recomienda que las URLs base terminen con '/' para evitar problemas de concatenación.`,\r\n );\r\n }\r\n return; // La ruta relativa es válida\r\n }\r\n\r\n // Si no es una ruta relativa, debe ser una URL absoluta\r\n try {\r\n // Intentar crear un objeto URL para validar el formato\r\n new URL(url);\r\n } catch {\r\n // Si falla, verificar si al menos tiene un formato básico válido\r\n const urlPattern = /^https?:\\/\\/.+/;\r\n if (!urlPattern.test(url)) {\r\n throw new Error(\r\n `[ENVIRONMENT] El campo '${fieldName}' no tiene un formato de URL válido. ` +\r\n `Valor actual: '${url}'. Debe ser una URL absoluta (http://... o https://...) o una ruta relativa que comience con /`,\r\n );\r\n }\r\n }\r\n\r\n // Validar que la URL termine con '/' para evitar problemas de concatenación\r\n if (!url.endsWith('/')) {\r\n console.warn(\r\n `[ENVIRONMENT] Advertencia: El campo '${fieldName}' no termina con '/'. ` +\r\n `Valor actual: '${url}'. Se recomienda que las URLs base terminen con '/' para evitar problemas de concatenación.`,\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Proporciona una configuración de entorno validada para la inyección de dependencias.\r\n *\r\n * Esta función crea un provider que valida automáticamente la configuración del entorno\r\n * cuando la aplicación se inicializa. Si la configuración es inválida, lanza un error\r\n * descriptivo que indica qué está mal configurado.\r\n *\r\n * @param environment - Configuración del entorno a proporcionar\r\n * @returns Provider de Angular configurado con la validación integrada\r\n *\r\n * @example\r\n * ```typescript\r\n * // En app.config.ts o main.ts\r\n * import { provideEnvironment } from './path/to/environment.token';\r\n * import { environment } from './environments/environment';\r\n *\r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [\r\n * provideEnvironment(environment),\r\n * // ... otros providers\r\n * ]\r\n * };\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Para módulos (NgModule)\r\n * import { provideEnvironment } from './path/to/environment.token';\r\n * import { environment } from './environments/environment';\r\n *\r\n * @NgModule({\r\n * providers: [\r\n * provideEnvironment(environment),\r\n * // ... otros providers\r\n * ]\r\n * })\r\n * export class AppModule { }\r\n * ```\r\n */\r\nexport function provideEnvironment(environment: EnvironmentConfig): Provider {\r\n return {\r\n provide: ENVIRONMENT,\r\n useFactory: () => {\r\n // Validar la configuración al momento de la inyección\r\n validateEnvironmentConfig(environment);\r\n return environment;\r\n },\r\n };\r\n}\r\n","import {\r\n Component,\r\n ViewEncapsulation,\r\n inject,\r\n Input,\r\n signal,\r\n} from '@angular/core';\r\nimport { FormGroup } from '@angular/forms';\r\nimport { JsonHighlightPipe } from '../../../pipe/src/json-highlight.pipe';\r\nimport {\r\n ENVIRONMENT,\r\n EnvironmentConfig,\r\n} from '../../../injections/environment.token';\r\n\r\n@Component({\r\n selector: 'app-json-values-debuj',\r\n imports: [JsonHighlightPipe],\r\n templateUrl: './json-values-debuj.component.html',\r\n styleUrl: './json-values-debuj.component.css',\r\n /**\r\n * Usamos ViewEncapsulation.None para que los estilos .json-* definidos en el CSS\r\n * apliquen también al HTML generado dinámicamente por [innerHTML] en el <pre>.\r\n *\r\n * Con la encapsulación por defecto (Emulated), Angular añade atributos tipo\r\n * _ngcontent-xxx a los elementos del template, pero el contenido insertado vía\r\n * [innerHTML] NO lleva esos atributos, por lo que las reglas scoped no coinciden\r\n * y el resaltado de sintaxis (json-key, json-string, etc.) no se ve.\r\n *\r\n * Al usar ViewEncapsulation.None, las clases .json-* se vuelven globales dentro\r\n * de la app (y de los proyectos que consumen la librería), permitiendo que el\r\n * pipe JsonHighlight pinte correctamente el JSON para depuración.\r\n */\r\n encapsulation: ViewEncapsulation.None,\r\n})\r\nexport class JsonValuesDebujComponent {\r\n @Input() form!: FormGroup;\r\n // Inyecta la configuración del entorno usando el token ENVIRONMENT\r\n private environment: EnvironmentConfig = inject(ENVIRONMENT);\r\n // Señal reactiva para indicar si estamos en modo de desarrollo\r\n private readonly isDevSignal = signal<boolean>(!this.environment.production);\r\n\r\n // Método para verificar el estado de desarrollo\r\n isDev(): boolean {\r\n return this.isDevSignal();\r\n }\r\n}\r\n","@if (isDev()) {\r\n <span class=\"debug-title\">Development mode</span>\r\n <div class=\"custom-container\">\r\n <pre\r\n class=\"custom-pre\"\r\n [innerHTML]=\"form.getRawValue() | jsonHighlight\"\r\n ></pre>\r\n </div>\r\n}\r\n","import { Injectable, signal } from '@angular/core';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\n/**\r\n * Servicio centralizado para controlar el estado de carga global.\r\n *\r\n * Expone una señal (`spinnerVisible`) que puede consumirse en componentes\r\n * para mostrar u ocultar un spinner.\r\n *\r\n * Uso recomendado:\r\n * - `show()` / `hide()` para flujos con múltiples operaciones concurrentes.\r\n * - `showImmediate()` para feedback visual inmediato (sin afectar contador).\r\n * - `reset()` para recuperar estado en errores inesperados.\r\n */\r\nexport class SpinnerLoadingService {\r\n /**\r\n * Señal reactiva que indica si el spinner debe mostrarse.\r\n *\r\n * Ejemplo:\r\n * ```ts\r\n * readonly isLoading = this.spinnerLoadingService.spinnerVisible;\r\n * ```\r\n */\r\n spinnerVisible = signal(false);\r\n\r\n /**\r\n * Contador interno de operaciones activas.\r\n * Permite que el spinner permanezca visible mientras haya procesos en curso.\r\n */\r\n private counter = 0;\r\n\r\n constructor() {}\r\n\r\n /**\r\n * Incrementa el contador de cargas activas.\r\n *\r\n * Muestra el spinner solo en la transición de `0 -> 1` para evitar\r\n * renderizados redundantes cuando hay varias operaciones simultáneas.\r\n *\r\n * Cuándo usarlo:\r\n * - Antes de iniciar una petición HTTP manual.\r\n * - Antes de ejecutar una acción asíncrona larga.\r\n */\r\n show(): void {\r\n this.counter++;\r\n if (this.counter === 1) {\r\n this.spinnerVisible.set(true);\r\n }\r\n }\r\n\r\n /**\r\n * Muestra el spinner de forma inmediata sin modificar el contador.\r\n *\r\n * Cuándo usarlo:\r\n * - Para feedback instantáneo en la UI (por ejemplo, al hacer clic en un botón).\r\n * - Cuando otro mecanismo (ejemplo: interceptor HTTP) controlará `show()`/`hide()`.\r\n */\r\n showImmediate(): void {\r\n this.spinnerVisible.set(true);\r\n }\r\n\r\n /**\r\n * Decrementa el contador de cargas activas.\r\n *\r\n * Oculta el spinner únicamente cuando el contador llega a `0`.\r\n * Si se llama más veces de las debidas, el contador no baja de `0`.\r\n *\r\n * Cuándo usarlo:\r\n * - Al finalizar una operación iniciada con `show()`.\r\n */\r\n hide(): void {\r\n if (this.counter > 0) {\r\n this.counter--;\r\n }\r\n\r\n if (this.counter === 0) {\r\n this.spinnerVisible.set(false);\r\n }\r\n }\r\n\r\n /**\r\n * Restablece el estado del servicio a su valor inicial.\r\n *\r\n * Fuerza `counter = 0` y oculta el spinner.\r\n * Útil en escenarios de recuperación por error o al reinicializar contexto.\r\n */\r\n reset(): void {\r\n this.counter = 0;\r\n this.spinnerVisible.set(false);\r\n }\r\n}\r\n","import { AfterViewInit, Component, ElementRef, viewChild } from '@angular/core';\r\nimport { createTimeline } from 'animejs';\r\n\r\n@Component({\r\n selector: 'app-logo-dsx',\r\n imports: [],\r\n templateUrl: './logo-dsx.component.html',\r\n styleUrl: './logo-dsx.component.css',\r\n})\r\nexport class LogoDsxComponent implements AfterViewInit {\r\n logo = viewChild.required<ElementRef>('logo');\r\n hexagon = viewChild.required<ElementRef>('logoHexagon');\r\n circle = viewChild.required<ElementRef>('logoCircle');\r\n mask = viewChild.required<ElementRef>('logoMask');\r\n text = viewChild.required<ElementRef>('logoText');\r\n currentYear: number;\r\n\r\n constructor() {\r\n this.currentYear = new Date().getFullYear(); // Asigna el año actual\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n createTimeline({\r\n autoplay: true,\r\n delay: 90,\r\n })\r\n .add(this.logo().nativeElement, {\r\n translateY: [-100, 0],\r\n opacity: [0, 1],\r\n duration: 420,\r\n easing: 'outCubic',\r\n })\r\n .add(\r\n this.hexagon().nativeElement,\r\n {\r\n rotate: [-54, 0],\r\n duration: 220,\r\n easing: 'outBack',\r\n },\r\n 60,\r\n )\r\n .add(\r\n this.circle().nativeElement,\r\n {\r\n scale: [0, 1],\r\n duration: 320,\r\n easing: 'outElastic(amplitude = 1, period = .2)',\r\n },\r\n 150,\r\n )\r\n .add(\r\n this.mask().nativeElement,\r\n {\r\n scale: [0, 1],\r\n duration: 300,\r\n easing: 'outElastic(amplitude = 1, period = .2)',\r\n },\r\n 170,\r\n )\r\n .add(\r\n this.text().nativeElement,\r\n {\r\n translateX: ['-60%', 0],\r\n opacity: [0, 1],\r\n duration: 380,\r\n easing: 'outExpo',\r\n },\r\n 650,\r\n )\r\n .add(\r\n this.logo().nativeElement,\r\n {\r\n translateY: -8,\r\n duration: 70,\r\n easing: 'outQuad',\r\n },\r\n 420,\r\n )\r\n .add(\r\n this.logo().nativeElement,\r\n {\r\n translateY: 0,\r\n duration: 150,\r\n easing: 'outBounce',\r\n },\r\n 490,\r\n );\r\n }\r\n}\r\n","<div class=\"site-logo\">\r\n <figure #logo>\r\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 148 128\">\r\n <defs>\r\n <linearGradient id=\"logo-gradient\" x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\">\r\n <stop offset=\"0%\" stop-color=\"#00ffff\" />\r\n <stop offset=\"100%\" stop-color=\"#ff00ff\" />\r\n </linearGradient>\r\n <linearGradient\r\n id=\"circle-gradient\"\r\n x1=\"0%\"\r\n y1=\"100%\"\r\n x2=\"100%\"\r\n y2=\"0%\"\r\n >\r\n <stop offset=\"0%\" stop-color=\"#ff00ff\" />\r\n <stop offset=\"100%\" stop-color=\"#00ffff\" />\r\n </linearGradient>\r\n <mask id=\"circle-mask\">\r\n <rect fill=\"white\" width=\"100%\" height=\"100%\"></rect>\r\n <circle\r\n #logoMask\r\n id=\"logo-mask\"\r\n fill=\"black\"\r\n cx=\"120\"\r\n cy=\"96\"\r\n r=\"28\"\r\n ></circle>\r\n </mask>\r\n </defs>\r\n <polygon\r\n #logoHexagon\r\n id=\"logo-hexagon\"\r\n fill=\"#475569\"\r\n stroke=\"#9ca3af\"\r\n stroke-width=\"2\"\r\n stroke-linejoin=\"round\"\r\n points=\"64 128 8.574 96 8.574 32 64 0 119.426 32 119.426 96\"\r\n mask=\"url(#circle-mask)\"\r\n ></polygon>\r\n <circle #logoCircle fill=\"#16a34a\" cx=\"120\" cy=\"96\" r=\"20\"></circle>\r\n </svg>\r\n </figure>\r\n <div class=\"site-title\">\r\n <div #logoText class=\"site-title-text\">\r\n DEV<span\r\n >SOFTXela<span style=\"font-size: small; vertical-align: super\"\r\n >&copy;</span\r\n >\r\n {{ currentYear }}</span\r\n >\r\n </div>\r\n </div>\r\n</div>\r\n","import { Component, effect, inject, input } from '@angular/core';\r\nimport { SpinnerLoadingService } from '../../services/src/spinner-loading.service';\r\nimport { AnimationOptions, LottieComponent } from 'ngx-lottie';\r\nimport { LogoDsxComponent } from '../logo/logo-dsx/logo-dsx.component';\r\n\r\n@Component({\r\n selector: 'app-loading-lottie',\r\n imports: [LottieComponent, LogoDsxComponent],\r\n templateUrl: './loading-lottie.component.html',\r\n styleUrl: './loading-lottie.component.css',\r\n})\r\nexport class LoadingLottieComponent {\r\n // Accedemos directamente a la señal del servicio\r\n _spinnerService = inject(SpinnerLoadingService);\r\n currentYear: number;\r\n jsonUrl = input<string>('Loader_Liquid4');\r\n size = input<string>('250px');\r\n options: AnimationOptions = { path: '' };\r\n\r\n constructor() {\r\n this.currentYear = new Date().getFullYear(); // Asigna el año actual\r\n effect(() => {\r\n this.options = {\r\n path: `jsonlottie/${this.jsonUrl() + '.json'}`,\r\n };\r\n });\r\n }\r\n}\r\n","@if (_spinnerService.spinnerVisible()) {\r\n <div class=\"loader-container\">\r\n <ng-lottie\r\n [options]=\"options\"\r\n [width]=\"size()\"\r\n [height]=\"size()\"\r\n ></ng-lottie>\r\n <!-- <p class=\"loading-text\">&copy;DevsoftXela {{ currentYear }}</p> -->\r\n <app-logo-dsx></app-logo-dsx>\r\n </div>\r\n}\r\n","import { Component, inject } from '@angular/core';\r\nimport { SpinnerLoadingService } from '../../../services/src/spinner-loading.service';\r\n\r\n@Component({\r\n selector: 'app-loading-v2',\r\n imports: [],\r\n templateUrl: './css-v2.component.html',\r\n styleUrl: './css-v2.component.css',\r\n})\r\nexport class CssV2Component {\r\n _spinnerService = inject(SpinnerLoadingService);\r\n}\r\n","@if(_spinnerService.spinnerVisible()){\r\n<div class=\"spinner-overlay\">\r\n <div class=\"spinner-container\">\r\n <div class=\"center_div\">\r\n <div class=\"wave\"></div>\r\n <div class=\"wave\"></div>\r\n <div class=\"wave\"></div>\r\n <div class=\"wave\"></div>\r\n <div class=\"wave\"></div>\r\n <div class=\"wave\"></div>\r\n <div class=\"wave\"></div>\r\n </div>\r\n <p class=\"loading-text\">Cargando...</p>\r\n </div>\r\n</div>\r\n}\r\n","import { Component, inject } from '@angular/core';\r\nimport { SpinnerLoadingService } from '../../services/src/spinner-loading.service';\r\n\r\n@Component({\r\n selector: 'app-loading',\r\n imports: [],\r\n templateUrl: './loading.component.html',\r\n styleUrl: './loading.component.css',\r\n})\r\nexport class LoadingComponent {\r\n // Accedemos directamente a la señal del servicio\r\n _spinnerService = inject(SpinnerLoadingService);\r\n currentYear: number;\r\n\r\n constructor() {\r\n this.currentYear = new Date().getFullYear(); // Asigna el año actual\r\n }\r\n}\r\n","<!-- Actualización 2025-31-01 12:00 -->\r\n@if(_spinnerService.spinnerVisible()){\r\n<div class=\"spinner-overlay\">\r\n <div class=\"loader\">\r\n <div class=\"external-shadow\">\r\n <div class=\"central\"></div>\r\n </div>\r\n <img src=\"/icon/secure.png\" class=\"spinner-image\" />\r\n </div>\r\n <p class=\"loading-text\">&copy;DevsoftXela {{ currentYear }}</p>\r\n</div>\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { ToastrService } from 'ngx-toastr';\r\nimport Swal, {\r\n SweetAlertIcon,\r\n SweetAlertOptions,\r\n SweetAlertResult,\r\n SweetAlertTheme,\r\n} from 'sweetalert2';\r\nimport {\r\n ENVIRONMENT,\r\n SWEET_ALERT_THEMES,\r\n} from '../../injections/environment.token';\r\nimport { ResponseHttpModel } from '../../models/src/response-http.model';\r\n\r\n/**\r\n * Opciones configurables para personalizar el comportamiento y apariencia de las alertas visuales.\r\n *\r\n * Permite definir iconos, imágenes, botones, temporizadores y temas para las alertas SweetAlert2.\r\n *\r\n * @property icono - Nombre del archivo de imagen ubicado en 'assets/dsxResource/'. Ejemplo: 'success-icon.png'. Por defecto: 'icon/check02.png'.\r\n * @property icon - Tipo de icono SweetAlert2 ('success' | 'error' | 'warning' | 'info' | 'question'). Opcional.\r\n * @property showConfirmButton - Si es true, muestra el botón de confirmación y desactiva el cierre automático. Por defecto: false.\r\n * @property confirmButtonText - Texto personalizado para el botón de confirmación. Por defecto: 'Ok'.\r\n * @property timer - Tiempo en milisegundos para el cierre automático de la alerta. Ignorado si showConfirmButton es true. Por defecto: 2000.\r\n * @property imageWidth - Ancho en píxeles de la imagen personalizada. Por defecto: 125.\r\n * @property imageHeight - Alto en píxeles de la imagen personalizada. Por defecto: 125.\r\n * @property showImage - Si es true, muestra la imagen personalizada; si es false, solo el icono SweetAlert2. Por defecto: true.\r\n * @property theme - Tema visual de SweetAlert2 (por ejemplo, 'dark', 'minimal', etc). Opcional.\r\n *\r\n * @example\r\n * // Alerta con icono personalizado y cierre automático\r\n * const options: AlertOptions = {\r\n * icono: 'custom-icon.png',\r\n * icon: 'warning',\r\n * timer: 3000\r\n * };\r\n *\r\n * @example\r\n * // Alerta de confirmación con botón y sin imagen\r\n * const confirmOptions: AlertOptions = {\r\n * showConfirmButton: true,\r\n * confirmButtonText: 'Aceptar',\r\n * showImage: false\r\n * };\r\n */\r\ninterface AlertOptions {\r\n icono?: string;\r\n icon?: SweetAlertIcon;\r\n showConfirmButton?: boolean;\r\n confirmButtonText?: string;\r\n timer?: number;\r\n imageWidth?: number;\r\n imageHeight?: number;\r\n showImage?: boolean;\r\n theme?: SweetAlertTheme;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class AlertaService {\r\n private toastrService = inject(ToastrService);\r\n\r\n /**\r\n * Configuración del entorno inyectada (opcional).\r\n * Se usa para obtener el tema global de SweetAlert2 desde el environment.\r\n */\r\n private environment = inject(ENVIRONMENT, { optional: true });\r\n\r\n /**\r\n * Tema visual por defecto para todas las alertas SweetAlert2.\r\n * Se inicializa desde el environment si está configurado, o puede establecerse\r\n * manualmente llamando a setDefaultTheme().\r\n *\r\n * **Prioridad de temas:**\r\n * 1. Tema específico pasado en options de cada alerta\r\n * 2. Tema establecido con setDefaultTheme()\r\n * 3. Tema configurado en environment.sweetAlertTheme\r\n * 4. Tema por defecto de SweetAlert2\r\n */\r\n private defaultTheme: SweetAlertTheme | undefined = undefined;\r\n\r\n constructor() {\r\n // Inicializar el tema desde el environment si está disponible\r\n if (this.environment?.sweetAlertTheme) {\r\n const allowed = SWEET_ALERT_THEMES as readonly string[];\r\n const themeValue = this.environment.sweetAlertTheme;\r\n if (typeof themeValue === 'string' && !allowed.includes(themeValue)) {\r\n console.warn(\r\n `[AlertaService] Tema de SweetAlert2 inválido: '${themeValue}'. Se utilizará el tema por defecto.`,\r\n );\r\n } else {\r\n this.defaultTheme = themeValue as SweetAlertTheme;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Permite establecer el theme global para todas las alertas SweetAlert2.\r\n * Este tema sobrescribe el configurado en el environment.\r\n *\r\n * @param theme - Valor de theme válido para SweetAlert2 (por ejemplo: 'dark', 'minimal', etc).\r\n *\r\n * @example\r\n * ```typescript\r\n * // Cambiar el tema en tiempo de ejecución\r\n * alertaService.setDefaultTheme('dark');\r\n * ```\r\n */\r\n setDefaultTheme(theme: SweetAlertTheme) {\r\n this.defaultTheme = theme;\r\n }\r\n\r\n /**\r\n * Obtiene el tema actual configurado para SweetAlert2.\r\n * @returns El tema actual o undefined si no hay tema configurado.\r\n */\r\n getDefaultTheme(): SweetAlertTheme | undefined {\r\n return this.defaultTheme;\r\n }\r\n\r\n /**\r\n * @param {number} toastrType - 1. Success 2. Info 3. Warning 4. Error\r\n * @param {string} toastrTitle - Titulo de la alerta\r\n * @param {string} toastrMessage - Mensaje de la alerta\r\n * @param {number} toastrAlign - Alineación de la alerta, por defecto 1. OPCIONES: 0. top-left 1. top-center 2. top-right 3. bottom-left 4. bottom-center 5. bottom-right\r\n * @param {number} toastrTimer - Tiempo de la alerta default 3000\r\n * @returns - Retonar una alerta toastr\r\n * */\r\n\r\n toastrAlerts(\r\n toastrType: number,\r\n toastrTitle: string,\r\n toastrMessage: string,\r\n toastrAlign: number = 1,\r\n toastrTimer: number = 3000,\r\n ) {\r\n const alignMessage = [\r\n { id: 0, align: 'toast-top-left' },\r\n { id: 1, align: 'toast-top-center' },\r\n { id: 2, align: 'toast-top-right' },\r\n { id: 3, align: 'toast-bottom-left' },\r\n { id: 4, align: 'toast-bottom-center' },\r\n { id: 5, align: 'toast-bottom-right' },\r\n ];\r\n\r\n const valueAlign: string | undefined = alignMessage.find(\r\n (c) => c.id == toastrAlign,\r\n )?.align;\r\n\r\n const toastrMethods: {\r\n [key: number]: (message: string, title?: string, options?: any) => void;\r\n } = {\r\n 1: this.toastrService.success.bind(this.toastrService),\r\n 2: this.toastrService.info.bind(this.toastrService),\r\n 3: this.toastrService.warning.bind(this.toastrService),\r\n 4: this.toastrService.error.bind(this.toastrService),\r\n };\r\n\r\n const showToast = toastrMethods[toastrType];\r\n\r\n if (showToast) {\r\n showToast(toastrMessage, toastrTitle, {\r\n enableHtml: true,\r\n closeButton: true,\r\n progressBar: true,\r\n positionClass: valueAlign,\r\n timeOut: toastrTimer,\r\n });\r\n }\r\n }\r\n\r\n private preloadImage(icono: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const img = new Image();\r\n img.src = `/${icono}`;\r\n img.onload = () => resolve();\r\n img.onerror = (err) => reject(err);\r\n });\r\n }\r\n\r\n /**\r\n * Muestra un diálogo de confirmación con SweetAlert2, espera la respuesta del usuario\r\n * y retorna `true` si confirmó o `false` si canceló/cerró.\r\n *\r\n * La imagen se precarga antes de mostrar el diálogo para evitar un parpadeo visual.\r\n *\r\n * @param title - Título principal del diálogo.\r\n * @param text - Cuerpo del mensaje; admite HTML (se inyecta como `html`).\r\n * @param icono - Ruta relativa de la imagen dentro de `assets/dsxResource/`.\r\n * Por defecto: `'icon2/garbage_make_empty_001.png'`.\r\n * @returns `Promise<boolean>` que resuelve en `true` si el usuario pulsó **Aceptar**,\r\n * o en `false` si pulsó **Cancelar** o cerró el diálogo.\r\n *\r\n * @example\r\n * // Uso con icono por defecto (papelera)\r\n * const confirmado = await this.alertaService.alertConfirm(\r\n * 'Eliminar',\r\n * 'Desea <strong>eliminar</strong> este registro?',\r\n * );\r\n *\r\n * @example\r\n * // Sobreescribir el icono pasando la ruta como tercer argumento\r\n * // La ruta es relativa a assets/dsxResource/\r\n * const confirmado = await this.alertaService.alertConfirm(\r\n * 'Archivar',\r\n * 'Desea <strong>archivar</strong> este registro?',\r\n * 'icon2/archive_001.png', // ← icono personalizado\r\n * );\r\n */\r\n alertConfirm(\r\n title: string,\r\n text: string,\r\n icono: string = 'icon2/garbage_make_empty_001.png',\r\n ): Promise<boolean> {\r\n return this.preloadImage(icono).then(() =>\r\n Swal.fire({\r\n title: title,\r\n html: text,\r\n footer: `<strong>DEVSoftXela</strong> ${new Date().getFullYear()}`,\r\n imageUrl: `/${icono}`,\r\n imageWidth: 150,\r\n imageHeight: 150,\r\n imageAlt: 'icon',\r\n showCloseButton: true,\r\n showCancelButton: true,\r\n confirmButtonColor: '#3085d6',\r\n cancelButtonColor: '#d33',\r\n confirmButtonText: `<i class=\"fa fa-thumbs-up\"></i> Aceptar!`,\r\n cancelButtonText: `<i class=\"fa fa-thumbs-down\"></i> Cancelar`,\r\n }).then((result) => result.isConfirmed),\r\n );\r\n }\r\n\r\n /**\r\n * Muestra una alerta de confirmación estándar para guardar o actualizar un registro.\r\n *\r\n * @param isNew - Indica si se trata de un nuevo registro (true = \"Salvar\", false = \"Actualizar\").\r\n * @returns Promise<boolean> que indica si el usuario confirmó la acción.\r\n */\r\n alertConfirmSaveOrUpdate(isNew: boolean): Promise<boolean> {\r\n const title = isNew ? 'Salvar' : 'Actualizar';\r\n const text = 'Desea <strong>guardar</strong> el registro?';\r\n const icono = 'icon2/save_2029637.png';\r\n return this.alertConfirm(title, text, icono);\r\n }\r\n\r\n /**\r\n * Variante de alerta de confirmación que recibe el id numérico del registro.\r\n *\r\n * Internamente evalúa si el registro es nuevo (`id === 0`) y delega en\r\n * alertConfirmSaveOrUpdate(isNew: boolean) para mostrar el mensaje.\r\n *\r\n * @param id - Identificador del registro. Se considera nuevo cuando `id === 0`.\r\n * @returns Promise<boolean> que indica si el usuario confirmó la acción.\r\n */\r\n alertConfirmSaveOrUpdateById(id: number): Promise<boolean> {\r\n const isNew = id === 0;\r\n return this.alertConfirmSaveOrUpdate(isNew);\r\n }\r\n\r\n /**\r\n * Muestra una alerta de confirmación estándar para eliminar, borrar (soft delete) o restaurar un registro.\r\n *\r\n * - Si se pasa un objeto con la propiedad `activo === false`, el mensaje se personaliza para \"Restaurar\".\r\n * - Si `activo` es true o no se envía, el comportamiento es el mismo de antes (Eliminar/Borrar según `softDelete`).\r\n *\r\n * @param softDelete - Si es true se muestra mensaje de borrado lógico, si es false eliminación definitiva.\r\n * @param data - Objeto opcional que puede incluir la propiedad `activo`. Si `activo === false` se mostrará un mensaje de restaurar.\r\n * @returns Promise<boolean> que indica si el usuario confirmó la acción.\r\n */\r\n alertConfirmDelete(\r\n softDelete: boolean,\r\n data?: { activo?: boolean },\r\n ): Promise<boolean> {\r\n const isActive = data?.activo; // true | false | undefined\r\n const isRestore = isActive === false; // solo si viene explícitamente en false\r\n\r\n const title = isRestore ? 'Restaurar' : 'Eliminar';\r\n\r\n const text = isRestore\r\n ? 'Desea <strong>restaurar</strong> el registro?'\r\n : softDelete\r\n ? 'Desea <strong>borrar</strong> el registro?'\r\n : 'Desea <strong>eliminar definitivmente</strong> el registro?';\r\n\r\n const icono = isRestore\r\n ? 'icon2/garbage_make_empty.png' // puedes usar otro icono de restaurar\r\n : softDelete\r\n ? 'icon2/recycle-bin_16854652.png'\r\n : 'icon2/delete2.png';\r\n\r\n return this.alertConfirm(title, text, icono);\r\n }\r\n\r\n alertaHtml(\r\n titleAlert: string,\r\n message: string,\r\n icono: string = 'icon/notFound01.png',\r\n timer: number = 3500,\r\n ): Promise<void> {\r\n return this.preloadImage(icono).then(() => {\r\n Swal.fire({\r\n title: titleAlert,\r\n imageUrl: `/${icono}`,\r\n imageWidth: 145,\r\n imageHeight: 125,\r\n imageAlt: 'error 404',\r\n html: `\r\n <strong>ALERTA: </strong><i>${message}</i> <span> comuniquese con el administrador. </span>\r\n `,\r\n showConfirmButton: false,\r\n timerProgressBar: true,\r\n timer: timer,\r\n });\r\n return;\r\n });\r\n }\r\n\r\n /**\r\n * Muestra una alerta visual personalizada usando SweetAlert2.\r\n *\r\n * Permite configurar el mensaje, el título, el icono, la imagen, el botón de confirmación,\r\n * el temporizador y el tema visual, entre otras opciones.\r\n *\r\n * @param titleAlert - Título principal de la alerta (obligatorio).\r\n * @param messageHtml - Mensaje en formato HTML (obligatorio).\r\n * @param options - Opciones configurables de la alerta (opcional). Permite personalizar icono, imagen, botón, temporizador, etc.\r\n * @returns Promise<SweetAlertResult> que se resuelve cuando el usuario interactúa con la alerta o cuando se cierra automáticamente.\r\n *\r\n * @example\r\n * // Alerta básica con icono de éxito y cierre automático\r\n * alertaHtmlSuccess('Operación exitosa', 'Los datos se guardaron correctamente');\r\n *\r\n * @example\r\n * // Alerta de error con imagen personalizada y temporizador\r\n * alertaHtmlSuccess('Error crítico', 'No se pudo conectar al servidor', {\r\n * icono: 'error-icon.png',\r\n * icon: 'error',\r\n * timer: 5000\r\n * });\r\n *\r\n * @example\r\n * // Alerta de confirmación con botón personalizado y sin imagen\r\n * alertaHtmlSuccess('Confirmar acción', '¿Está seguro de eliminar este registro?', {\r\n * showConfirmButton: true,\r\n * confirmButtonText: 'Sí, eliminar',\r\n * icon: 'warning',\r\n * showImage: false\r\n * }).then((result) => {\r\n * if (result.isConfirmed) {\r\n * // Lógica cuando el usuario confirma\r\n * }\r\n * });\r\n */\r\n alertaHtmlSuccess(\r\n titleAlert: string,\r\n messageHtml: string,\r\n options: AlertOptions = {},\r\n ): Promise<SweetAlertResult> {\r\n const {\r\n icono = 'icon/check02.png',\r\n icon,\r\n showConfirmButton = false,\r\n confirmButtonText = 'Ok',\r\n timer = 2000,\r\n imageWidth = 125,\r\n imageHeight = 125,\r\n showImage = true,\r\n theme, // Puede venir por options o usar el global\r\n } = options;\r\n\r\n /**\r\n * Nota importante:\r\n * Para que el parámetro `theme` funcione correctamente, el proyecto que\r\n * consume esta librería debe importar el CSS del tema de SweetAlert2 en\r\n * sus estilos (por ejemplo en `styles.scss` o en `angular.json` -> \"styles\").\r\n * Si no se importa el CSS correspondiente al tema seleccionado, las\r\n * alertas no aplicarán el estilo del tema y se verán con el estilo por\r\n * defecto de SweetAlert2.\r\n */\r\n\r\n // Usa el theme global si no se especifica uno en options\r\n const alertTheme = theme !== undefined ? theme : this.defaultTheme;\r\n\r\n // Configuración base de SweetAlert\r\n const alertConfig: SweetAlertOptions = {\r\n title: titleAlert,\r\n html: messageHtml,\r\n draggable: true,\r\n showConfirmButton,\r\n confirmButtonText,\r\n timer: showConfirmButton ? undefined : timer, // Timer solo si no hay botón\r\n timerProgressBar: !showConfirmButton && timer > 0,\r\n imageUrl: showImage && icono ? `/${icono}` : undefined,\r\n imageWidth: showImage ? imageWidth : undefined,\r\n imageHeight: showImage ? imageHeight : undefined,\r\n imageAlt: showImage ? 'image alert' : undefined,\r\n // Aplica el theme global o el específico (cast a SweetAlertTheme para compatibilidad)\r\n ...(alertTheme !== undefined && { theme: alertTheme as SweetAlertTheme }),\r\n };\r\n // Solo agrega el icono si está definido\r\n if (icon !== undefined) {\r\n alertConfig.icon = icon;\r\n }\r\n\r\n // Precargar imagen solo si es necesario\r\n if (showImage && icono) {\r\n return this.preloadImage(icono).then(() => Swal.fire(alertConfig));\r\n }\r\n\r\n return Swal.fire(alertConfig);\r\n }\r\n\r\n // private configureTimer(\r\n // config: SweetAlertOptions,\r\n // showConfirmButton: boolean,\r\n // timer: number\r\n // ) {\r\n // if (!showConfirmButton && timer > 0) {\r\n // config.timer = timer;\r\n // config.timerProgressBar = true;\r\n // }\r\n // }\r\n\r\n // No se puede utilizar por conflicto con primeng\r\n // notyfAlert(message: string) {\r\n // this.notyf.success({\r\n // message: message,\r\n // duration: 1500,\r\n // position: {\r\n // x: 'center',\r\n // y: 'top',\r\n // },\r\n // });\r\n // }\r\n\r\n toastrHttpResponse(response: ResponseHttpModel) {\r\n const time = 3000;\r\n const align = 'toast-top-center';\r\n if (response.isSuccess) {\r\n this.toastrService.success(response.statusMessage, response.title, {\r\n enableHtml: true,\r\n closeButton: true,\r\n progressBar: true,\r\n positionClass: align,\r\n timeOut: time,\r\n });\r\n } else {\r\n this.toastrService.error(response.statusMessage, response.title, {\r\n enableHtml: true,\r\n closeButton: true,\r\n progressBar: true,\r\n positionClass: align,\r\n timeOut: time,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Muestra un mensaje tipo toast usando PrimeNG MessageService.\r\n *\r\n * @param severity - Tipo de severidad del mensaje. Valores posibles:\r\n * 'success' | 'info' | 'warn' | 'error' | 'contrast' | 'secondary'.\r\n * Por defecto: 'success'.\r\n * @param title - Título del mensaje (aparece como summary).\r\n * @param message - Detalle del mensaje (aparece como detail).\r\n * @param time - Duración en milisegundos que el mensaje estará visible. Por defecto: 1500 ms.\r\n *\r\n * @example\r\n * // Mensaje de éxito\r\n * alertaService.showPrimeMessage('success', 'Operación exitosa', 'El registro fue guardado correctamente');\r\n *\r\n * @example\r\n * // Mensaje de advertencia personalizado\r\n * alertaService.showPrimeMessage('warn', 'Advertencia', 'Faltan campos obligatorios', 3000);\r\n */\r\n // showPrimeMessage(\r\n // title: string,\r\n // message: string,\r\n // severity:\r\n // | 'success'\r\n // | 'info'\r\n // | 'warn'\r\n // | 'error'\r\n // | 'contrast'\r\n // | 'secondary' = 'success',\r\n // time: number = 1500\r\n // ) {\r\n // this.primeMessageService.add({\r\n // severity: severity,\r\n // summary: title,\r\n // detail: message,\r\n // life: time,\r\n // });\r\n // }\r\n}\r\n","import { EnvironmentConfig } from '../../injections/environment.token';\r\n\r\n/**\r\n * Configuración base de entorno para la aplicación.\r\n *\r\n * Este tipo es un alias de {@link EnvironmentConfig} para usarlo en el\r\n * contexto de modelos de la librería (por ejemplo, para defaults de dev/prod).\r\n *\r\n * De esta forma, cualquier cambio en ENVIRONMENT_SCHEMA / EnvironmentConfig\r\n * se propaga automáticamente aquí y se evita la desincronización entre\r\n * definiciones.\r\n */\r\nexport interface AppEnvironment extends EnvironmentConfig {}\r\n\r\n/**\r\n * Configuración base que provee la librería para entornos de desarrollo.\r\n *\r\n * Se omiten `myAppUrl` y `rolIndex` porque normalmente dependen de cada\r\n * aplicación cliente. Esos campos se vuelven obligatorios al combinar este\r\n * tipo con {@link DevEnvironmentComplete} en el proyecto que consume.\r\n */\r\nexport type DevEnvironmentDefaults = Omit<\r\n AppEnvironment,\r\n 'myAppUrl' | 'rolIndex'\r\n>;\r\n\r\n/**\r\n * Configuración base que provee la librería para entornos de producción.\r\n *\r\n * Se omite únicamente `rolIndex`, que debe ser definido por cada\r\n * aplicación cliente. En el proyecto consumidor se recomienda usar\r\n * {@link ProdEnvironmentComplete} para forzar ese campo como requerido.\r\n */\r\nexport type ProdEnvironmentDefaults = Omit<AppEnvironment, 'rolIndex'>;\r\n\r\n/**\r\n * Tipo recomendado para el `environment` de desarrollo en las aplicaciones\r\n * que consumen la librería.\r\n *\r\n * Combina los valores por defecto de la librería con los campos que cada\r\n * app debe completar: `myAppUrl` y `rolIndex`.\r\n */\r\nexport type DevEnvironmentComplete = DevEnvironmentDefaults &\r\n Pick<AppEnvironment, 'myAppUrl' | 'rolIndex'>;\r\n\r\n/**\r\n * Tipo recomendado para el `environment` de producción en las aplicaciones\r\n * que consumen la librería.\r\n *\r\n * Combina los valores por defecto de la librería con el campo obligatorio\r\n * `rolIndex` que aporta cada aplicación cliente.\r\n */\r\nexport type ProdEnvironmentComplete = ProdEnvironmentDefaults &\r\n Pick<AppEnvironment, 'rolIndex'>;\r\n\r\n/**\r\n * Entorno de desarrollo.\r\n *\r\n * No define `myAppUrl` porque normalmente se toma de la configuración\r\n * de la aplicación Angular (por ejemplo, `environment.ts` del proyecto).\r\n */\r\nexport const developmentEnvironment: DevEnvironmentDefaults = {\r\n production: false,\r\n SeguridadITApiUrl: 'https://localhost:7197/',\r\n tokenName: 'securityIT-Authorize',\r\n tokenNameRF: 'refresh-Authorize',\r\n sessionStatus: 'lastActivity',\r\n refreshTokenExpiry: 'refreshToken-Expiry',\r\n rolesGuards: ['Administrador SIIT'],\r\n};\r\n\r\n/**\r\n * Entorno de producción.\r\n *\r\n * Define todas las propiedades de `AppEnvironment`, incluida `myAppUrl`.\r\n */\r\nexport const productionEnvironment: ProdEnvironmentDefaults = {\r\n production: true,\r\n myAppUrl: '/',\r\n SeguridadITApiUrl: 'https://securityapi.itgtxela.com/',\r\n tokenName: 'securityIT-Authorize',\r\n tokenNameRF: 'refresh-Authorize',\r\n sessionStatus: 'lastActivity',\r\n refreshTokenExpiry: 'refreshToken-Expiry',\r\n rolesGuards: ['Administrador SIIT'],\r\n};\r\n\r\n/**\r\n * Devuelve el índice 0-based del rol principal a partir del `rolIndex` 1-based\r\n * definido en el entorno.\r\n *\r\n * Úsalo cuando necesites indexar arreglos (por ejemplo, listas de roles) para\r\n * evitar repetir la resta de 1 en múltiples lugares del código.\r\n *\r\n * @example\r\n * ```ts\r\n * import { getZeroBasedRolIndex } from '@devsoftxela/ngx-dsx';\r\n *\r\n * const idx = getZeroBasedRolIndex(environment);\r\n * const rol = roles[idx];\r\n * ```\r\n */\r\nexport function getZeroBasedRolIndex(\r\n env: Pick<AppEnvironment, 'rolIndex'>,\r\n): number {\r\n return Math.max(0, env.rolIndex - 1);\r\n}\r\n","import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { Observable } from 'rxjs';\r\nimport {\r\n ENVIRONMENT,\r\n EnvironmentConfig,\r\n} from '../../injections/environment.token';\r\nimport { ServiceResult } from '../../models';\r\nimport { SeguridadITParameter } from '../../models/src/parameterSecurity.model';\r\nimport { DataToken } from '../../models/src/token.model';\r\n\r\n/**\r\n * Servicio de seguridad que gestiona la autenticación y autorización mediante tokens JWT.\r\n *\r\n * Este servicio proporciona métodos para:\r\n * - Refrescar tokens de acceso\r\n * - Revocar tokens de refresco\r\n * - Obtener parámetros de seguridad\r\n *\r\n * @example\r\n * ```typescript\r\n * constructor(private securityService: SecurityService) {}\r\n *\r\n * refreshToken() {\r\n * this.securityService.tokenRefresh(this.refreshToken)\r\n * .subscribe(data => console.log(data));\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class SecurityService {\r\n /** Servicio HttpClient para realizar peticiones HTTP */\r\n private http = inject(HttpClient);\r\n\r\n /**\r\n * Configuración del entorno inyectada mediante el token ENVIRONMENT.\r\n * La validación se realiza automáticamente al usar provideEnvironment().\r\n */\r\n private environment: EnvironmentConfig = inject(ENVIRONMENT);\r\n\r\n /** URL base de la API JWT construida desde la configuración del entorno */\r\n private urlApi: string = `${this.environment.myAppUrl}api/parameter`;\r\n private SeguridadITApi: string = `${this.environment.SeguridadITApiUrl}api/jwt`;\r\n\r\n /**\r\n * Obtiene un nuevo token de acceso utilizando un refresh token válido.\r\n *\r\n * Este método envía una solicitud POST al endpoint de refresco de token\r\n * y devuelve un nuevo par de tokens (access token y refresh token).\r\n *\r\n * @param refreshToken - El refresh token válido para obtener un nuevo token de acceso\r\n * @returns Observable que emite un objeto DataToken con el nuevo par de tokens\r\n *\r\n * @example\r\n * ```typescript\r\n * this.securityService.tokenRefresh('your-refresh-token')\r\n * .subscribe({\r\n * next: (data) => console.log('Nuevo token:', data.accessToken),\r\n * error: (err) => console.error('Error al refrescar token:', err)\r\n * });\r\n * ```\r\n */\r\n tokenRefresh(refreshToken: string): Observable<ServiceResult<DataToken>> {\r\n // Crea el cuerpo de la solicitud con el refresh token\r\n const body = { refreshToken };\r\n\r\n // Realiza una solicitud POST al endpoint de refresco de token\r\n return this.http.post<ServiceResult<DataToken>>(\r\n `${this.SeguridadITApi}/refresh-token/`,\r\n body,\r\n {\r\n headers: new HttpHeaders({\r\n 'Content-Type': 'application/json', // Establece el tipo de contenido como JSON\r\n }),\r\n },\r\n );\r\n }\r\n\r\n /**\r\n * Revoca un refresh token para invalidarlo y prevenir su uso futuro.\r\n *\r\n * Este método envía una solicitud POST al endpoint de revocación de token\r\n * para invalidar permanentemente el refresh token proporcionado.\r\n *\r\n * @param refreshToken - El refresh token que se desea revocar\r\n * @returns Observable que emite true si la revocación fue exitosa, false en caso contrario\r\n *\r\n * @example\r\n * ```typescript\r\n * this.securityService.tokenRevok('your-refresh-token')\r\n * .subscribe({\r\n * next: (success) => {\r\n * if (success) console.log('Token revocado exitosamente');\r\n * },\r\n * error: (err) => console.error('Error al revocar token:', err)\r\n * });\r\n * ```\r\n */\r\n tokenRevok(refreshToken: string): Observable<boolean> {\r\n // Crea el cuerpo de la solicitud con el refresh token\r\n const body = { refreshToken };\r\n // Realiza una solicitud POST al endpoint de revocación de token\r\n return this.http.post<boolean>(\r\n `${this.SeguridadITApi}/revoke-token/`,\r\n body,\r\n {\r\n headers: new HttpHeaders({\r\n 'Content-Type': 'application/json', // Establece el tipo de contenido como JSON\r\n }),\r\n },\r\n );\r\n }\r\n\r\n /**\r\n * Obtiene los parámetros de seguridad de la aplicación desde el servidor.\r\n *\r\n * Este método recupera la configuración de seguridad que incluye políticas de contraseñas,\r\n * tiempos de expiración de sesión, y otras configuraciones relacionadas con la seguridad.\r\n *\r\n * @param invalidCacheParam - Indica si se debe invalidar la caché del servidor.\r\n * Si es true, fuerza al servidor a devolver los datos más recientes\r\n * sin usar la caché. Por defecto es false.\r\n * @returns Observable que emite un objeto SeguridadITParameter con la configuración de seguridad\r\n *\r\n * @example\r\n * ```typescript\r\n * // Obtener parámetros usando caché\r\n * this.securityService.getParameterSecurity()\r\n * .subscribe(params => console.log('Parámetros:', params));\r\n *\r\n * // Obtener parámetros sin usar caché\r\n * this.securityService.getParameterSecurity(true)\r\n * .subscribe(params => console.log('Parámetros actualizados:', params));\r\n * ```\r\n */\r\n getParameterSecurity(\r\n invalidCacheParam: boolean = false,\r\n ): Observable<ServiceResult<SeguridadITParameter>> {\r\n // Crea los parámetros de la solicitud, incluyendo el parámetro invalidCacheParam,\r\n // parametro diseñado para invalidar la caché a traves del filtro\r\n const params = new HttpParams().set(\r\n 'invalidCacheParam',\r\n invalidCacheParam.toString(),\r\n );\r\n\r\n // Realiza una solicitud GET al endpoint de parámetros de seguridad\r\n return this.http.get<ServiceResult<SeguridadITParameter>>(\r\n `${this.urlApi}/security-parameter/`,\r\n { params },\r\n );\r\n }\r\n}\r\n","import { inject, Injectable, isDevMode } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { JwtHelperService } from '@auth0/angular-jwt';\r\nimport { CookieService } from 'ngx-cookie-service';\r\nimport {\r\n ENVIRONMENT,\r\n EnvironmentConfig,\r\n} from '../../injections/environment.token';\r\nimport { getZeroBasedRolIndex } from '../../models/src/environment-base';\r\nimport { DataToken, jwtSecurityModel } from '../../models/src/token.model';\r\nimport { SecurityService } from './security.service';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class AuthorizeService {\r\n _cookieService = inject(CookieService);\r\n _router = inject(Router);\r\n helperJwt = new JwtHelperService();\r\n private _isRefreshing = false;\r\n private _securityService = inject(SecurityService);\r\n private environment: EnvironmentConfig = inject(ENVIRONMENT);\r\n\r\n /**\r\n * Detecta si el host actual es local o de red privada.\r\n *\r\n * Se usa para evitar fallback de cookies en escenarios de desarrollo,\r\n * incluso cuando por configuración externa `environment.production`\r\n * viene en `true`.\r\n */\r\n private isLocalOrPrivateHost(): boolean {\r\n if (typeof window === 'undefined') {\r\n return false;\r\n }\r\n\r\n const host = window.location?.hostname ?? '';\r\n if (!host) {\r\n return false;\r\n }\r\n\r\n const normalizedHost = host.toLowerCase();\r\n if (\r\n normalizedHost === 'localhost' ||\r\n normalizedHost === '127.0.0.1' ||\r\n normalizedHost === '::1' ||\r\n normalizedHost.endsWith('.local')\r\n ) {\r\n return true;\r\n }\r\n\r\n const privateIpv4Pattern = /^(10\\.|192\\.168\\.|172\\.(1[6-9]|2\\d|3[0-1])\\.)/;\r\n return privateIpv4Pattern.test(normalizedHost);\r\n }\r\n\r\n // Función para obtener opciones de cookies estándar\r\n /**\r\n * Construye las opciones usadas por `CookieService` al crear cookies.\r\n *\r\n * Motivo del cambio:\r\n * - Los navegadores rechazan cookies con `SameSite=None` si no se envían sobre\r\n * `Secure` (HTTPS). En entornos locales HTTP esto causa que las cookies no\r\n * sean guardadas aunque el servicio intente crearlas.\r\n *\r\n * Comportamiento:\r\n * - En producción y cuando la página usa `https:` se aplica `secure: true`,\r\n * `sameSite: 'None'` y se establece `domain` (como antes).\r\n * - Si no hay HTTPS (p. ej. red local con HTTP) se fuerza `sameSite: 'Lax'`\r\n * y `secure` queda en `false` para evitar que el navegador rechace la cookie.\r\n * - Esto preserva el comportamiento original en entornos con HTTPS.\r\n */\r\n private getCookieOptions(expiryDate: Date): any {\r\n const isProduction = this.environment.production;\r\n const isHttps =\r\n typeof window !== 'undefined' && window.location?.protocol === 'https:';\r\n\r\n const cookieOptions: any = {\r\n path: '/',\r\n expires: expiryDate,\r\n secure: isHttps,\r\n sameSite: isHttps ? 'None' : 'Lax',\r\n };\r\n\r\n // Solo establecer dominio cuando estemos en producción y usemos HTTPS\r\n if (isProduction && isHttps) {\r\n cookieOptions.domain = '.itgtxela.com';\r\n }\r\n\r\n if (isProduction && !isHttps) {\r\n console.warn(\r\n '[AuthorizeService] Entorno en producción pero sin HTTPS. Ajustando opciones de cookie para evitar rechazo por Secure/SameSite.',\r\n );\r\n }\r\n\r\n return cookieOptions;\r\n }\r\n\r\n // Función para establecer una cookie\r\n /**\r\n * Crea una cookie de autenticación y controla un fallback seguro.\r\n *\r\n * Reglas de fallback (`document.cookie`):\r\n * - Solo aplica en ejecución real de producción.\r\n * - Solo aplica cuando la página NO está en HTTPS.\r\n * - Nunca aplica en `isDevMode()`.\r\n * - Nunca aplica en hosts locales/privados.\r\n *\r\n * Objetivo:\r\n * - Mantener política estricta en producción real.\r\n * - Evitar falsos positivos de fallback durante desarrollo local.\r\n */\r\n private setCookie(name: string, value: string, expiryDate: Date): void {\r\n const options = this.getCookieOptions(expiryDate);\r\n const isHttps =\r\n typeof window !== 'undefined' && window.location?.protocol === 'https:';\r\n const isLocalOrPrivateHost = this.isLocalOrPrivateHost();\r\n const allowFallback =\r\n !isDevMode() &&\r\n this.environment.production &&\r\n !isHttps &&\r\n !isLocalOrPrivateHost;\r\n\r\n // Intentamos usar CookieService (respeta domain/secure/samesite cuando corresponde).\r\n // El fallback con document.cookie se limita a producción sin HTTPS.\r\n try {\r\n this._cookieService.set(\r\n name,\r\n value,\r\n options.expires,\r\n options.path,\r\n options.domain,\r\n options.secure,\r\n options.sameSite,\r\n );\r\n\r\n // Verificar si la cookie quedó creada; si no, intentar fallback con document.cookie\r\n const created = this._cookieService.get(name);\r\n if (!created && allowFallback) {\r\n try {\r\n const expires =\r\n options.expires instanceof Date\r\n ? options.expires.toUTCString()\r\n : '';\r\n // Fallback mínimo: no usar Secure ni domain para entornos HTTP locales.\r\n document.cookie = `${name}=${value}; path=/; ${expires ? 'expires=' + expires + '; ' : ''}SameSite=Lax`;\r\n console.warn(\r\n `[AuthorizeService] Cookie '${name}' creada via fallback document.cookie`,\r\n );\r\n } catch (err) {\r\n console.warn(\r\n `[AuthorizeService] No se pudo crear cookie fallback para '${name}':`,\r\n err,\r\n );\r\n }\r\n } else if (!created && this.environment.production) {\r\n console.warn(\r\n `[AuthorizeService] Cookie '${name}' no pudo verificarse con CookieService en entorno no elegible para fallback.`,\r\n );\r\n }\r\n } catch (err) {\r\n console.error(\r\n '[AuthorizeService] Error al crear cookie con CookieService:',\r\n err,\r\n );\r\n if (allowFallback) {\r\n try {\r\n const expires = expiryDate.toUTCString();\r\n document.cookie = `${name}=${value}; path=/; expires=${expires}; SameSite=Lax`;\r\n console.warn(\r\n `[AuthorizeService] Cookie '${name}' creada via fallback document.cookie tras error.`,\r\n );\r\n } catch (err2) {\r\n console.error(\r\n '[AuthorizeService] Fallback document.cookie falló:',\r\n err2,\r\n );\r\n }\r\n }\r\n }\r\n }\r\n\r\n get isRefreshing() {\r\n return this._isRefreshing;\r\n }\r\n set isRefreshing(value) {\r\n this._isRefreshing = value;\r\n }\r\n\r\n getToken(): string | null {\r\n return this._cookieService.get(this.environment.tokenName);\r\n //return localStorage.getItem(environment.tokenName);\r\n }\r\n\r\n /**\r\n * Obtiene el Refresh Token almacenado en cookies.\r\n *\r\n * - En modo desarrollo (isDevMode):\r\n * Si no existe un refresh token en cookies, genera uno temporal\r\n * para evitar errores durante pruebas locales.\r\n *\r\n * - En modo producción:\r\n * Simplemente devuelve el refresh token real almacenado por el backend.\r\n *\r\n * @returns string | null - El refresh token o null si no existe.\r\n */\r\n getTokenRefresh(): string | null {\r\n // 🔹 MODO DESARROLLO: asegura que siempre haya un token de prueba\r\n if (isDevMode()) {\r\n const tokenRefresh = this._cookieService.get(\r\n this.environment.tokenNameRF,\r\n );\r\n\r\n // Si no existe un refresh token, generamos uno de desarrollo\r\n if (!tokenRefresh) {\r\n const devTokens: DataToken = {\r\n token: '',\r\n tokenRefresh: '8508408a-6cbc-4ebb-b105-d851655a3b0c', // Token dummy para testing\r\n refreshTokenExpiry: new Date(),\r\n };\r\n\r\n // Carga y guarda las cookies necesarias\r\n this.tokenReload(devTokens);\r\n }\r\n }\r\n\r\n // 🔹 DEVUELVE el refresh token real o de desarrollo\r\n return this._cookieService.get(this.environment.tokenNameRF);\r\n }\r\n\r\n // Actualizar valores de status\r\n setLastActivity(): void {\r\n const tokenExpiryDate = new Date();\r\n // Expira en 30 minutos\r\n tokenExpiryDate.setMinutes(tokenExpiryDate.getMinutes() + 30);\r\n this.setCookie(\r\n this.environment.sessionStatus,\r\n Date.now().toString(),\r\n tokenExpiryDate,\r\n );\r\n }\r\n\r\n getLastActivity(): number | null {\r\n // Obtiene el valor de la cookie\r\n const lastActivity = this._cookieService.get(\r\n this.environment.sessionStatus,\r\n );\r\n\r\n if (lastActivity) {\r\n // Intenta convertir el valor en un número\r\n const timestamp = parseInt(lastActivity, 10);\r\n\r\n // Verifica que sea un número válido\r\n if (!isNaN(timestamp)) {\r\n return timestamp;\r\n }\r\n }\r\n\r\n // Si no hay cookie o el valor no es válido, devuelve null\r\n return null;\r\n }\r\n\r\n // Almacenar los tokens en cookies\r\n tokenReload(tokens: DataToken) {\r\n const tokenExpiryDate = new Date();\r\n tokenExpiryDate.setMinutes(tokenExpiryDate.getMinutes() + 30); // Access token expiry: 30 mins\r\n\r\n // Usar la fecha de expiración que viene del servidor para el refresh token\r\n const refreshTokenExpiryDate = new Date(tokens.refreshTokenExpiry);\r\n\r\n // Guardar el access token y refresh token con sus fechas de expiración\r\n this.setCookie(this.environment.tokenName, tokens.token, tokenExpiryDate);\r\n this.setCookie(\r\n this.environment.tokenNameRF,\r\n tokens.tokenRefresh,\r\n refreshTokenExpiryDate,\r\n );\r\n\r\n // Guardar el estado de sesión\r\n this.setLastActivity();\r\n }\r\n\r\n getTokenValid(token: string | null): boolean {\r\n // Devuelve true si el token NO ha expirado\r\n return !this.helperJwt.isTokenExpired(token);\r\n }\r\n\r\n /**\r\n * Obtiene los valores principales del JWT almacenado (usuario, roles y estado).\r\n *\r\n * Este getter:\r\n * - Lee el access token desde cookies.\r\n * - Devuelve un objeto tipado (jwtSecurityModel).\r\n * - Decodifica el token para obtener `unique_name` y `role`.\r\n * - Determina si el token está expirado usando JwtHelperService.\r\n *\r\n * Si no existe token:\r\n * - Devuelve un objeto vacío con valores en null y `isTokenExpired = true`.\r\n *\r\n * Uso:\r\n * const info = this.authorize.getTokenValues;\r\n */\r\n get getTokenValues(): jwtSecurityModel {\r\n // Obtener el token almacenado\r\n const token = this.getToken();\r\n\r\n // Si no existe token → devolver estructura vacía\r\n if (!token) {\r\n return {\r\n userName: null,\r\n role: null,\r\n isTokenExpired: true,\r\n };\r\n }\r\n\r\n // Decodificar JWT\r\n const decoded = this.helperJwt.decodeToken(token) || {};\r\n\r\n return {\r\n userName: decoded.unique_name ?? null,\r\n\r\n // JWT puede traer role como string o como array → convertir a array\r\n role: decoded.role\r\n ? Array.isArray(decoded.role)\r\n ? decoded.role\r\n : [decoded.role]\r\n : null,\r\n\r\n // Validación de expiración del JWT\r\n isTokenExpired: this.helperJwt.isTokenExpired(token),\r\n };\r\n }\r\n\r\n /**\r\n * Rol principal calculado a partir del JWT y del rolIndex configurado\r\n * en el environment.\r\n *\r\n * - Usa getTokenValues para obtener el array de roles del token.\r\n * - Usa getZeroBasedRolIndex(environment) para convertir el rolIndex 1-based\r\n * del entorno a un índice 0-based.\r\n * - Si el rol viene con formato \"ROL~descripcion\", devuelve solo la parte\r\n * anterior al separador `~`.\r\n */\r\n get primaryRole(): string | null {\r\n const idx = getZeroBasedRolIndex(this.environment);\r\n const tokenValues = this.getTokenValues;\r\n const roles = tokenValues.role ?? [];\r\n const raw = roles[idx] ?? null;\r\n return typeof raw === 'string' ? raw.split('~')[0] : null;\r\n }\r\n\r\n /**\r\n * Verifica si el usuario está autenticado.\r\n *\r\n * La validación se basa en la existencia del refresh token en cookies.\r\n * El navegador gestiona automáticamente la expiración de las cookies.\r\n *\r\n * @returns `true` si el usuario está autenticado, `false` en caso contrario\r\n */\r\n isAuthenticated(): boolean {\r\n const refreshToken = this.getTokenRefresh();\r\n return !!(refreshToken && refreshToken.trim() !== '');\r\n }\r\n\r\n /**\r\n * Cierra la sesión del usuario de forma segura y controlada.\r\n *\r\n * Este método implementa un proceso de logout robusto que:\r\n * 1. Verifica el estado actual de la sesión y la ubicación del usuario\r\n * 2. Intenta revocar el refresh token en el servidor (si existe)\r\n * 3. Limpia todos los datos de sesión local\r\n * 4. Redirige al usuario a la página de login\r\n *\r\n * **Casos manejados:**\r\n * - Usuario ya en página de login: Solo limpia datos locales\r\n * - Sin refresh token: Limpia datos locales y redirige\r\n * - Con refresh token: Intenta revocarlo, luego limpia y redirige\r\n * - Error al revocar: Limpia datos locales de todas formas (seguridad)\r\n * - Modo desarrollo: Maneja tokens de prueba correctamente\r\n *\r\n * **Importante:** Este método es **asíncrono** en su ejecución interna pero no retorna una promesa.\r\n * La redirección al login ocurre después de limpiar la sesión, independientemente del resultado de la revocación.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Uso básico desde un componente\r\n * this.authorizeService.logout();\r\n *\r\n * // Uso con navegación posterior controlada\r\n * this.authorizeService.logout();\r\n * // La redirección al login es automática\r\n * ```\r\n *\r\n * @see {@link clearSessionData} para el proceso de limpieza de datos\r\n * @see {@link SecurityService.tokenRevok} para la revocación en el servidor\r\n */\r\n logout(): void {\r\n try {\r\n // 1️⃣ Prevenir acciones innecesarias si ya está en el login\r\n if (this._router.url === '/login') {\r\n console.info(\r\n '[AuthorizeService] Usuario ya en página de login, limpiando sesión local...',\r\n );\r\n this.clearSessionData();\r\n return;\r\n }\r\n\r\n // 2️⃣ Obtener el refresh token de forma segura\r\n const refreshToken = this.getTokenRefresh();\r\n\r\n // 3️⃣ Si no hay refresh token, proceder con limpieza directa\r\n if (!refreshToken || refreshToken.trim() === '') {\r\n console.warn(\r\n '[AuthorizeService] No se encontró refresh token, limpiando sesión local...',\r\n );\r\n this.clearSessionData();\r\n return;\r\n }\r\n\r\n // 4️⃣ Intentar revocar el token en el servidor\r\n console.info(\r\n '[AuthorizeService] Revocando refresh token en el servidor...',\r\n );\r\n\r\n this._securityService.tokenRevok(refreshToken).subscribe({\r\n next: (success) => {\r\n if (success) {\r\n console.info(\r\n '[AuthorizeService] Refresh token revocado exitosamente en el servidor',\r\n );\r\n } else {\r\n console.warn(\r\n '[AuthorizeService] El servidor no pudo revocar el token, pero continuando con logout',\r\n );\r\n }\r\n this.clearSessionData();\r\n },\r\n error: (error) => {\r\n // 5️⃣ Manejar errores de revocación con información detallada\r\n console.error(\r\n '[AuthorizeService] Error al revocar el refresh token:',\r\n {\r\n message: error?.message || 'Error desconocido',\r\n status: error?.status,\r\n statusText: error?.statusText,\r\n url: error?.url,\r\n },\r\n );\r\n\r\n // Por seguridad, limpiar la sesión incluso si falla la revocación\r\n console.warn(\r\n '[AuthorizeService] Limpiando sesión local por seguridad a pesar del error',\r\n );\r\n this.clearSessionData();\r\n },\r\n complete: () => {\r\n console.info('[AuthorizeService] Proceso de logout completado');\r\n },\r\n });\r\n } catch (error) {\r\n // 6️⃣ Capturar cualquier error inesperado en el proceso de logout\r\n console.error(\r\n '[AuthorizeService] Error crítico durante el proceso de logout:',\r\n error,\r\n );\r\n\r\n // Garantizar que la sesión se limpie incluso si ocurre un error inesperado\r\n try {\r\n this.clearSessionData();\r\n } catch (cleanupError) {\r\n console.error(\r\n '[AuthorizeService] Error crítico al limpiar sesión:',\r\n cleanupError,\r\n );\r\n // Último recurso: redirigir al login sin importar qué\r\n this._router.navigate(['/login']).catch((navError) => {\r\n console.error(\r\n '[AuthorizeService] Error al navegar a login:',\r\n navError,\r\n );\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Limpia todos los datos de sesión del usuario de forma segura.\r\n *\r\n * Este método privado se encarga de:\r\n * - Eliminar todas las cookies relacionadas con autenticación\r\n * - Limpiar el localStorage completamente\r\n * - Redirigir al usuario a la página de login\r\n *\r\n * **Cookies eliminadas:**\r\n * - Token de acceso (access token)\r\n * - Token de refresco (refresh token)\r\n * - Estado de sesión (session status)\r\n *\r\n * **Consideraciones:**\r\n * - Se eliminan las cookies con path '/' para asegurar su borrado\r\n * - En producción, también se considera el dominio configurado\r\n * - El localStorage se limpia completamente por seguridad\r\n * - La redirección es forzada incluso si hay errores previos\r\n *\r\n * @private\r\n */\r\n private clearSessionData(): void {\r\n try {\r\n console.info(\r\n '[AuthorizeService] Iniciando limpieza de datos de sesión...',\r\n );\r\n\r\n // 1️⃣ Eliminar cookies con path explícito\r\n const cookiesToDelete = [\r\n this.environment.tokenName,\r\n this.environment.tokenNameRF,\r\n this.environment.sessionStatus,\r\n ];\r\n\r\n cookiesToDelete.forEach((cookieName) => {\r\n try {\r\n // Eliminar con path '/'\r\n this._cookieService.delete(cookieName, '/');\r\n\r\n // En producción, también intentar eliminar con dominio específico\r\n if (this.environment.production) {\r\n this._cookieService.delete(cookieName, '/', '.itgtxela.com');\r\n }\r\n\r\n console.debug(`[AuthorizeService] Cookie eliminada: ${cookieName}`);\r\n } catch (error) {\r\n console.error(\r\n `[AuthorizeService] Error al eliminar cookie ${cookieName}:`,\r\n error,\r\n );\r\n }\r\n });\r\n\r\n // 2️⃣ Limpiar localStorage\r\n try {\r\n localStorage.clear();\r\n console.debug('[AuthorizeService] localStorage limpiado');\r\n } catch (error) {\r\n console.error(\r\n '[AuthorizeService] Error al limpiar localStorage:',\r\n error,\r\n );\r\n }\r\n\r\n // 3️⃣ Redirigir al login\r\n console.info('[AuthorizeService] Redirigiendo a página de login...');\r\n this._router.navigate(['/login']).then(\r\n () => console.info('[AuthorizeService] Redirección exitosa a /login'),\r\n (error) =>\r\n console.error('[AuthorizeService] Error en la redirección:', error),\r\n );\r\n } catch (error) {\r\n console.error(\r\n '[AuthorizeService] Error crítico en clearSessionData:',\r\n error,\r\n );\r\n\r\n // Último recurso: intentar redirigir sin importar qué\r\n this._router.navigate(['/login']).catch((navError) => {\r\n console.error(\r\n '[AuthorizeService] Error final al intentar redirigir:',\r\n navError,\r\n );\r\n });\r\n }\r\n }\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\nimport { MyParameterValues } from '../models/src/parameterSecurity.model';\r\n\r\nexport const INITIAL_PARAMETERS = new InjectionToken<MyParameterValues[]>(\r\n 'InitialParameters'\r\n);\r\n","import { inject, Injectable, signal } from '@angular/core';\r\nimport {\r\n catchError,\r\n delay,\r\n map,\r\n Observable,\r\n of,\r\n retry,\r\n throwError,\r\n} from 'rxjs';\r\nimport { INITIAL_PARAMETERS } from '../../injections/parameterSecurity';\r\nimport {\r\n MyParameterValues,\r\n ParameterSecurity,\r\n} from '../../models/src/parameterSecurity.model';\r\nimport { SecurityService } from './security.service';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\n/**\r\n * Servicio para gestionar los parámetros de seguridad de la aplicación.\r\n * Permite cargar los parámetros desde la API, mantenerlos en memoria, acceder y comparar valores de forma segura.\r\n * Utiliza tipado genérico para los nombres de parámetros y cache interno para optimizar consultas repetidas.\r\n *\r\n * @template T Tipo de los nombres de parámetros permitidos (usualmente un union type de string)\r\n */\r\nexport class ParameterValuesService<T extends string = string> {\r\n /**\r\n * Parámetros iniciales inyectados mediante INITIAL_PARAMETERS.\r\n * Se usan para validar y mapear los parámetros recibidos de la API.\r\n */\r\n private initialParameters = inject(INITIAL_PARAMETERS);\r\n\r\n /**\r\n * Cache interno para optimizar la comparación de valores de parámetros.\r\n * La clave es una combinación de nombre e índice, el valor es el resultado de la consulta.\r\n */\r\n private parameterCache = new Map<string, any>();\r\n\r\n private alertedParams = new Set<string>();\r\n private alertedParamsIsParameterValue = new Set<string>();\r\n\r\n /**\r\n * Servicio que contiene el método getParameterSecurity() para obtener los parámetros desde la API.\r\n */\r\n private apiService = inject(SecurityService);\r\n\r\n /**\r\n * Señal reactiva que contiene los parámetros cargados y permite actualizaciones automáticas.\r\n */\r\n private _dataParameter = signal<MyParameterValues<T>[]>(\r\n this.initializeData(),\r\n );\r\n\r\n /**\r\n * Flag que indica si ya se cargaron los parámetros desde la API.\r\n */\r\n private _loaded = signal(false);\r\n get loaded() {\r\n return this._loaded();\r\n }\r\n\r\n /**\r\n * Inicializa los datos de parámetros usando los valores inyectados.\r\n * @returns Array de parámetros iniciales tipados\r\n */\r\n private initializeData(): MyParameterValues<T>[] {\r\n return this.initialParameters.map((param) =>\r\n this.createMyParameterValue(param.parameterName as T, param.values),\r\n );\r\n }\r\n\r\n /**\r\n * Crea una instancia de MyParameterValues tipada y segura.\r\n * @param parameterName Nombre del parámetro\r\n * @param values Valores asociados al parámetro\r\n * @returns Objeto MyParameterValues\r\n */\r\n private createMyParameterValue(\r\n parameterName: T,\r\n values: any[],\r\n ): MyParameterValues<T> {\r\n return {\r\n parameterName,\r\n values: [...values],\r\n };\r\n }\r\n\r\n /**\r\n * Devuelve los parámetros actuales como un array de solo lectura.\r\n */\r\n get dataParameter(): Readonly<MyParameterValues<T>[]> {\r\n return this._dataParameter();\r\n }\r\n\r\n /**\r\n * Setter privado para actualizar los parámetros.\r\n * Solo puede ser usado dentro del servicio para mantener la integridad de los datos.\r\n * @param values Array de parámetros a almacenar\r\n */\r\n private setDataParameter(values: MyParameterValues<T>[]): void {\r\n if (!Array.isArray(values)) {\r\n console.error('Error: valores inválidos para dataParameter');\r\n return;\r\n }\r\n this._dataParameter.set(values);\r\n }\r\n\r\n /**\r\n * Carga los parámetros desde la API.\r\n * Si ya se cargaron y force=false, devuelve la copia en memoria.\r\n * @param force Indica si se debe forzar la recarga desde la API (default: false)\r\n * @returns Observable que emite los parámetros cargados como MyParameterValues[]\r\n */\r\n loadParameters(force = false): Observable<MyParameterValues<T>[]> {\r\n if (this._loaded() && !force) {\r\n return of([...this.dataParameter]); // copia mutable\r\n }\r\n\r\n return this.apiService.getParameterSecurity(force).pipe(\r\n map((response) => {\r\n const apiParameters = response.data?.parameterSecurity ?? [];\r\n this.validateParameters(apiParameters);\r\n const values = this.mapToMyParameterValues(apiParameters);\r\n this.setDataParameter(values);\r\n this._loaded.set(true);\r\n return values;\r\n }),\r\n // 👇 fallback si falla la llamada pero ya teníamos data\r\n catchError((error) => {\r\n if (this._loaded() && this.dataParameter.length > 0) {\r\n return of([...this.dataParameter]);\r\n }\r\n this._loaded.set(false);\r\n return throwError(() => error);\r\n }),\r\n );\r\n }\r\n\r\n /**\r\n * Fuerza la recarga de los parámetros desde la API.\r\n * @returns Observable que emite los parámetros actualizados\r\n */\r\n refreshParameters(): Observable<MyParameterValues<T>[]> {\r\n return this.loadParameters(true);\r\n }\r\n\r\n /**\r\n * Crea una copia segura y mutable de los parámetros actuales.\r\n * @returns Array de parámetros\r\n */\r\n private createSafeCopy(): MyParameterValues<T>[] {\r\n return this.dataParameter.map((item) =>\r\n this.createMyParameterValue(item.parameterName, [...item.values]),\r\n );\r\n }\r\n\r\n /**\r\n * Mapea los parámetros recibidos de la API a objetos tipados y seguros.\r\n * @param apiParameters Parámetros recibidos desde la API\r\n * @returns Array de MyParameterValues\r\n */\r\n private mapToMyParameterValues(\r\n apiParameters: ParameterSecurity[],\r\n ): MyParameterValues<T>[] {\r\n const initialNames = this.initialParameters.map((p) => p.parameterName);\r\n\r\n return apiParameters\r\n .filter((param) => initialNames.includes(param.parameterName))\r\n .map((param) => {\r\n // Función de conversión type-safe\r\n return this.convertToTypedParameter(param);\r\n })\r\n .filter((param): param is MyParameterValues<T> => param !== null);\r\n }\r\n\r\n /**\r\n * Convierte un parámetro de la API a un objeto tipado, validando el nombre.\r\n * @param param Parámetro recibido de la API\r\n * @returns Objeto MyParameterValues o null si no es válido\r\n */\r\n private convertToTypedParameter(\r\n param: ParameterSecurity,\r\n ): MyParameterValues<T> | null {\r\n const initialParam = this.initialParameters.find(\r\n (p) => p.parameterName === param.parameterName,\r\n );\r\n\r\n if (!initialParam) {\r\n return null;\r\n }\r\n\r\n // Conversión segura con verificación\r\n if (this.isValidParameterName(param.parameterName)) {\r\n return this.createMyParameterValue(\r\n param.parameterName as T,\r\n param.parameterValues?.map((v) => v.value) ?? [],\r\n );\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Verifica si un nombre de parámetro es válido según los parámetros iniciales.\r\n * @param name Nombre a validar\r\n * @returns true si es válido\r\n */\r\n private isValidParameterName(name: string): name is T {\r\n // Verifica que el nombre esté en los parámetros iniciales\r\n return this.initialParameters.some((param) => param.parameterName === name);\r\n }\r\n\r\n /**\r\n * Valida que los parámetros devueltos por la API coincidan con los iniciales.\r\n * Muestra errores o advertencias en consola si existen diferencias.\r\n * @param apiParameters Parámetros recibidos desde la API\r\n */\r\n private validateParameters(apiParameters: ParameterSecurity[]): void {\r\n const initialNames = this.initialParameters.map((p) => p.parameterName);\r\n const apiNames = apiParameters.map((p) => p.parameterName);\r\n\r\n const missing = initialNames.filter((name) => !apiNames.includes(name));\r\n const extra = apiNames.filter((name) => !initialNames.includes(name));\r\n\r\n if (missing.length) {\r\n console.warn(`Faltan en API: ${missing.join(', ')}`);\r\n const ok = confirm(`Faltan en API: ${missing.join(', ')}. ¿Continuar?`);\r\n if (!ok) return;\r\n }\r\n if (extra.length) {\r\n console.warn(`Extra en API: ${extra.join(', ')}`);\r\n const ok = confirm(`Extra en API: ${extra.join(', ')}. ¿Continuar?`);\r\n if (!ok) return;\r\n }\r\n if (initialNames.length !== apiNames.length) {\r\n console.warn(\r\n `Cantidad distinta: iniciales=${initialNames.length}, api=${apiNames.length}`,\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Obtiene un valor específico de un parámetro.\r\n * Si `index` es null (valor por defecto), devuelve todo el arreglo de valores.\r\n * Devuelve `defaultValue` si no existe el parámetro o el índice es inválido.\r\n * Valida que el parámetro exista antes de acceder a su valor.\r\n * @param parameterName Nombre del parámetro\r\n * @param index Índice del valor dentro del array. Si es null (default), devuelve todos los valores.\r\n * @param defaultValue Valor por defecto si no existe (default: null)\r\n * @returns Valor del parámetro, todos los valores si index es null, o defaultValue si no existe o el índice es inválido\r\n */\r\n getValue<U = any>(parameterName: T): U[];\r\n getValue<U = any>(\r\n parameterName: T,\r\n index: number,\r\n defaultValue?: U | null,\r\n ): U;\r\n getValue<U = any>(\r\n parameterName: T,\r\n index: null,\r\n defaultValue?: U[] | null,\r\n ): U[];\r\n getValue<U = any>(\r\n parameterName: T,\r\n index: number | null = null,\r\n defaultValue: U | U[] | null = null,\r\n ): U | U[] {\r\n const param = this.dataParameter.find(\r\n (p) => p.parameterName === parameterName,\r\n );\r\n\r\n if (!param) {\r\n if (!this.alertedParams.has(parameterName)) {\r\n alert(`Advertencia: El parámetro '${parameterName}' no existe.`);\r\n this.alertedParams.add(parameterName);\r\n }\r\n return defaultValue as U | U[];\r\n }\r\n\r\n if (index === null) {\r\n return param.values as U[];\r\n }\r\n\r\n if (index < 0 || index >= param.values.length) {\r\n alert(\r\n `Advertencia: Índice ${index} fuera de rango para el parámetro '${parameterName}'.`,\r\n );\r\n return defaultValue as U;\r\n }\r\n\r\n return param.values[index] as U;\r\n }\r\n\r\n /**\r\n * Compara un valor específico con un valor esperado, usando cache para optimizar llamadas repetidas.\r\n * @param parameterName Nombre del parámetro\r\n * @param expectedValue Valor esperado\r\n * @param index Índice del valor dentro del array (default: 0)\r\n * @returns true si coincide, false en caso contrario\r\n */\r\n isParameterValue<U = any>(\r\n parameterName: T,\r\n expectedValue: U,\r\n index = 0,\r\n ): boolean {\r\n const cacheKey = `${String(parameterName)}_${index}`;\r\n\r\n const param = this.dataParameter.find(\r\n (p) => p.parameterName === parameterName,\r\n );\r\n\r\n if (!param) {\r\n if (!this.alertedParamsIsParameterValue.has(parameterName)) {\r\n alert(`Error: El parámetro '${parameterName}' no existe.`);\r\n this.alertedParamsIsParameterValue.add(parameterName);\r\n }\r\n return false;\r\n }\r\n\r\n if (!this.parameterCache.has(cacheKey)) {\r\n const value = this.getValue<U>(parameterName, index);\r\n this.parameterCache.set(cacheKey, value);\r\n }\r\n\r\n return this.parameterCache.get(cacheKey) === expectedValue;\r\n }\r\n\r\n /**\r\n * Limpia el cache interno de comparaciones de parámetros.\r\n */\r\n clearParameterCache(): void {\r\n this.parameterCache.clear();\r\n }\r\n\r\n /**\r\n * Verifica si un parámetro tiene al menos un valor.\r\n * @param parameterName Nombre del parámetro\r\n * @returns true si tiene al menos un valor, false si no tiene\r\n */\r\n hasAnyValue(parameterName: T): boolean {\r\n return this.getAllValues(parameterName).length > 0;\r\n }\r\n\r\n /**\r\n * Devuelve todos los valores de un parámetro.\r\n * @param parameterName Nombre del parámetro\r\n * @returns Array de valores\r\n */\r\n getAllValues<U = any>(parameterName: T): U[] {\r\n return (this.dataParameter.find((p) => p.parameterName === parameterName)\r\n ?.values ?? []) as U[];\r\n }\r\n}\r\n","import { Injectable, signal } from '@angular/core';\r\n\r\nexport type NetworkScore = 100 | 75 | 50 | 25;\r\n\r\nexport interface RequestMetricsState {\r\n lastDurationMs: number;\r\n averageDurationMs: number;\r\n requestsCount: number;\r\n score: NetworkScore;\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class RequestMetricsService {\r\n private historySize = 20;\r\n private durations: number[] = [];\r\n\r\n readonly state = signal<RequestMetricsState>({\r\n lastDurationMs: 0,\r\n averageDurationMs: 0,\r\n requestsCount: 0,\r\n score: 100,\r\n });\r\n\r\n registerRequest(durationMs: number) {\r\n this.durations.push(durationMs);\r\n if (this.durations.length > this.historySize) {\r\n this.durations.shift();\r\n }\r\n\r\n const avg =\r\n this.durations.reduce((acc, d) => acc + d, 0) / this.durations.length;\r\n\r\n const score = this.mapDurationToScore(avg);\r\n\r\n this.state.set({\r\n lastDurationMs: durationMs,\r\n averageDurationMs: avg,\r\n requestsCount: this.durations.length,\r\n score,\r\n });\r\n }\r\n\r\n private mapDurationToScore(avgMs: number): NetworkScore {\r\n // Ajusta umbrales a tu realidad\r\n if (avgMs <= 325) return 100;\r\n if (avgMs <= 800) return 75;\r\n if (avgMs <= 1500) return 50;\r\n return 25;\r\n }\r\n}\r\n","import { DecimalPipe } from '@angular/common';\r\nimport { Component, inject } from '@angular/core';\r\nimport { Avatar } from 'primeng/avatar';\r\nimport { TooltipModule } from 'primeng/tooltip';\r\nimport { RequestMetricsService } from '../../../services/src/request-metrics.service';\r\n\r\n@Component({\r\n selector: 'app-network-status',\r\n imports: [Avatar, DecimalPipe, TooltipModule],\r\n templateUrl: './network-status.component.html',\r\n styleUrl: './network-status.component.css',\r\n})\r\nexport class NetworkStatusComponent {\r\n private readonly metrics = inject(RequestMetricsService);\r\n state = this.metrics.state; // signal\r\n\r\n get tooltipText(): string {\r\n const { score, averageDurationMs, requestsCount } = this.state();\r\n const avg = Math.round(averageDurationMs);\r\n return `Estado de la red: ${score}% (promedio ${avg} ms, últimas ${requestsCount} peticiones)`;\r\n }\r\n\r\n getStatusImage(): string {\r\n const score = this.state().score;\r\n\r\n // 100 hasta 76 -> imagen \"muy buena\"\r\n if (score >= 76) {\r\n return 'image/Status_Green.png';\r\n }\r\n\r\n // 75 hasta 50 -> imagen \"media\"\r\n if (score >= 50) {\r\n return 'image/Status_Yellow.png';\r\n }\r\n\r\n // 50 o menos -> última imagen (mala)\r\n return 'image/Status_Red.png';\r\n }\r\n}\r\n","<div class=\"network-status-container\">\r\n <p-avatar\r\n [image]=\"getStatusImage()\"\r\n [pTooltip]=\"tooltipText\"\r\n tooltipPosition=\"bottom\"\r\n />\r\n <span> {{ state().score }}% </span>\r\n <span> {{ state().averageDurationMs | number: \"1.0-0\" }}ms </span>\r\n</div>\r\n","import { Component, inject, input, OnInit } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { ButtonModule } from 'primeng/button';\r\nimport { ImageModule } from 'primeng/image';\r\nimport { MenubarModule } from 'primeng/menubar';\r\nimport {\r\n ENVIRONMENT,\r\n EnvironmentConfig,\r\n} from '../../injections/environment.token';\r\nimport { AlertaService } from '../../services/src/alerta.service';\r\nimport { AuthorizeService } from '../../services/src/authorize.service';\r\nimport { ParameterValuesService } from '../../services/src/parameter-values.service';\r\nimport { IconDsxComponent } from '../icon-dsx/icon-dsx.component';\r\nimport { NetworkStatusComponent } from '../status/network-status/network-status.component';\r\n\r\n@Component({\r\n selector: 'app-navbar-dsx',\r\n imports: [\r\n ButtonModule,\r\n FormsModule,\r\n IconDsxComponent,\r\n ImageModule,\r\n MenubarModule,\r\n NetworkStatusComponent,\r\n ],\r\n templateUrl: './navbar-dsx.component.html',\r\n styleUrl: './navbar-dsx.component.css',\r\n})\r\nexport class NavbarDsxComponent implements OnInit {\r\n _authorizeService = inject(AuthorizeService);\r\n appVersion = input<string>('V1.0.0');\r\n checked: boolean = false; // Estado del interruptor (tema claro/oscuro)\r\n logoWidth = input<string>('300');\r\n private readonly _alertaService = inject(AlertaService);\r\n private readonly _parameterSecurityService = inject(ParameterValuesService);\r\n urlLogo = input<string>('assets/image/logoApp.png');\r\n private readonly environment: EnvironmentConfig = inject(ENVIRONMENT);\r\n\r\n ngOnInit(): void {\r\n // Inicializa el tema al cargar el componente\r\n this.initializeTheme();\r\n }\r\n\r\n // Rol actual calculado en base al token y al rolIndex del environment.\r\n // Se evalúa en cada ciclo de detección de cambios, por lo que refleja\r\n // automáticamente los cambios cuando se refresca el token.\r\n get currentRole(): string | null {\r\n return this._authorizeService.primaryRole;\r\n }\r\n\r\n // Inicializa el tema y el estado del interruptor\r\n initializeTheme(): void {\r\n const savedTheme = localStorage.getItem('theme') || 'light'; // Obtén el tema guardado o usa 'light' por defecto\r\n this.checked = savedTheme === 'dark'; // Actualiza el estado del interruptor\r\n this.applyTheme(savedTheme); // Aplica el tema\r\n }\r\n\r\n // Cambia el tema y actualiza el estado del interruptor\r\n onThemeChange(isDarkMode: boolean): void {\r\n // Determina el tema basado en el estado del interruptor\r\n const theme = isDarkMode ? 'dark' : 'light';\r\n // Aplica el tema\r\n this.applyTheme(theme);\r\n }\r\n\r\n // Aplica el tema y guarda la preferencia en localStorage\r\n applyTheme(theme: string): void {\r\n const html = document.documentElement;\r\n\r\n // Elimina las clases previas y agrega la nueva clase\r\n html.classList.remove('my-app-dark', 'my-app-light');\r\n html.classList.add(theme === 'dark' ? 'my-app-dark' : 'my-app-light');\r\n\r\n // Guarda el tema en localStorage\r\n localStorage.setItem('theme', theme);\r\n }\r\n\r\n actualizarSeguridadIT() {\r\n this._parameterSecurityService.refreshParameters().subscribe({\r\n next: (values) => {\r\n this._alertaService.toastrAlerts(\r\n 2,\r\n 'SeguridadIT',\r\n 'Parametro actualizado!',\r\n 2,\r\n );\r\n //console.log('Parámetros cargados:', values);\r\n },\r\n error: (err) => {\r\n console.error('Error al actualizar parámetros de SeguridadIT', err);\r\n this._alertaService.toastrAlerts(\r\n 3,\r\n 'SeguridadIT',\r\n 'Error al actualizar parámetros!',\r\n 2,\r\n );\r\n },\r\n complete: () => this._parameterSecurityService.clearParameterCache(),\r\n });\r\n }\r\n}\r\n","<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ón de permisos -->\r\n <p-button\r\n class=\"mr-2\"\r\n label=\"Permisos\"\r\n variant=\"text\"\r\n severity=\"info\"\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","import { Directive, ElementRef, HostListener } from '@angular/core';\r\n\r\n/**\r\n * Directiva de navegación por teclado entre elementos de una tabla.\r\n *\r\n * Uso: colocar el atributo [appKeyboardNav] en cada control navegable dentro\r\n * de un contenedor <table>. La directiva busca el <table> más cercano con\r\n * `closest('table')` y recorre todos los elementos marcados con ese atributo.\r\n *\r\n * Teclas soportadas:\r\n * - Enter / ArrowDown / ArrowRight → siguiente elemento\r\n * - Shift+Enter / ArrowUp / ArrowLeft → elemento anterior\r\n * La navegación es cíclica (del último vuelve al primero y viceversa).\r\n *\r\n * NOTA DE COMPATIBILIDAD — componentes PrimeNG:\r\n * Actualmente validado con <p-inputnumber>. Los componentes de PrimeNG (y otros\r\n * wrappers) no exponen un <input> nativo directamente en el host; en su lugar\r\n * renderizan el <input> como hijo en el shadow/light DOM interno.\r\n * Por eso esta directiva no hace `.focus()` sobre el host del componente, sino\r\n * que resuelve primero el control nativo enfocable interno mediante\r\n * `resolveFocusableTarget()`. Si en el futuro se integran otros componentes\r\n * (p-dropdown, p-select, etc.) puede ser necesario ampliar ese selector o agregar\r\n * lógica específica por tipo de componente, ya que cada uno renderiza su control\r\n * interno de forma diferente.\r\n */\r\n@Directive({\r\n selector: '[appKeyboardNav]',\r\n})\r\nexport class ArrowNavigationDirective {\r\n /**\r\n * Activa los logs de depuración en consola.\r\n * Cambiar a `true` para trazar el flujo de navegación durante el desarrollo.\r\n */\r\n private readonly debug = false;\r\n\r\n constructor(private el: ElementRef<HTMLElement>) {}\r\n\r\n @HostListener('keydown', ['$event'])\r\n handleKey(event: KeyboardEvent) {\r\n this.log('keydown recibido', {\r\n key: event.key,\r\n shiftKey: event.shiftKey,\r\n element: this.el.nativeElement,\r\n });\r\n\r\n const keys = ['Enter', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];\r\n if (!keys.includes(event.key)) {\r\n this.log('tecla ignorada', { key: event.key });\r\n return;\r\n }\r\n\r\n event.preventDefault();\r\n\r\n // Obtiene todos los elementos navegables no deshabilitados dentro del <table>\r\n const elements = this.getElements();\r\n const index = elements.indexOf(this.el.nativeElement);\r\n\r\n this.log('elementos navegables detectados', {\r\n total: elements.length,\r\n currentIndex: index,\r\n });\r\n\r\n // Si el elemento actual no está en la lista (p.ej. no tiene [appKeyboardNav]) se aborta\r\n if (index === -1) {\r\n this.log('elemento actual no encontrado en la lista navegable');\r\n return;\r\n }\r\n\r\n let nextIndex = index;\r\n\r\n switch (event.key) {\r\n case 'Enter':\r\n nextIndex = event.shiftKey ? index - 1 : index + 1;\r\n break;\r\n\r\n case 'ArrowDown':\r\n nextIndex = index + 1;\r\n break;\r\n\r\n case 'ArrowUp':\r\n nextIndex = index - 1;\r\n break;\r\n\r\n case 'ArrowRight':\r\n nextIndex = index + 1;\r\n break;\r\n\r\n case 'ArrowLeft':\r\n nextIndex = index - 1;\r\n break;\r\n }\r\n\r\n // Navegación cíclica: al pasar del último vuelve al primero y viceversa\r\n if (nextIndex >= elements.length) nextIndex = 0;\r\n if (nextIndex < 0) nextIndex = elements.length - 1;\r\n\r\n const nextElement = elements[nextIndex];\r\n this.log('moviendo foco', {\r\n from: index,\r\n to: nextIndex,\r\n nextElement,\r\n });\r\n\r\n this.focusElement(nextElement);\r\n }\r\n\r\n /**\r\n * Recoge todos los elementos con [appKeyboardNav] dentro del <table> contenedor\r\n * y filtra los que estén deshabilitados.\r\n */\r\n private getElements(): HTMLElement[] {\r\n const container = this.el.nativeElement.closest('table');\r\n\r\n if (!container) {\r\n this.log('no se encontró contenedor table con closest()');\r\n return [];\r\n }\r\n\r\n return Array.from(\r\n container.querySelectorAll<HTMLElement>('[appKeyboardNav]'),\r\n ).filter((el) => !el.hasAttribute('disabled'));\r\n }\r\n\r\n /**\r\n * Aplica el foco al control enfocable real dentro del elemento destino.\r\n * Necesario para componentes wrapper como <p-inputnumber>, donde el foco\r\n * debe recaer en el <input> interno y no en el host del componente.\r\n */\r\n private focusElement(element: HTMLElement) {\r\n const target = this.resolveFocusableTarget(element);\r\n\r\n this.log('target de foco resuelto', {\r\n source: element,\r\n target,\r\n });\r\n\r\n if (!target) {\r\n this.log('no se encontró target enfocable');\r\n return;\r\n }\r\n\r\n target.focus();\r\n\r\n // Selecciona el contenido del input para facilitar la edición inmediata\r\n if (\r\n target instanceof HTMLInputElement ||\r\n target instanceof HTMLTextAreaElement\r\n ) {\r\n this.log('aplicando select() al target enfocable');\r\n target.select();\r\n }\r\n }\r\n\r\n /**\r\n * Resuelve el control interno enfocable de un elemento.\r\n *\r\n * Si el elemento es directamente enfocable (input, button, etc.) lo retorna tal cual.\r\n * De lo contrario busca el primer descendiente que sea un control nativo activo.\r\n *\r\n * NOTA: cada componente de PrimeNG u otras librerías puede renderizar su control\r\n * interno con una estructura diferente. Si un componente no recibe el foco\r\n * correctamente, revisar primero el HTML renderizado en DevTools y ajustar el\r\n * selector de `querySelector` según sea necesario.\r\n */\r\n private resolveFocusableTarget(element: HTMLElement): HTMLElement | null {\r\n if (this.isDirectlyFocusable(element)) return element;\r\n\r\n const nestedFocusable = element.querySelector<HTMLElement>(\r\n 'input:not([disabled]), textarea:not([disabled]), select:not([disabled]), button:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\r\n );\r\n\r\n return nestedFocusable ?? null;\r\n }\r\n\r\n /** Determina si un elemento puede recibir el foco directamente. */\r\n private isDirectlyFocusable(element: HTMLElement): boolean {\r\n if (element.hasAttribute('disabled')) return false;\r\n\r\n const tag = element.tagName.toLowerCase();\r\n if (['input', 'textarea', 'select', 'button'].includes(tag)) return true;\r\n\r\n return element.tabIndex >= 0;\r\n }\r\n\r\n /**\r\n * Traza un mensaje en consola cuando el modo debug está activo.\r\n * Para activar: cambiar `debug = false` a `debug = true`.\r\n */\r\n private log(message: string, data?: unknown) {\r\n if (!this.debug) return;\r\n // console.log('[ArrowNavigationDirective]', message, data ?? '');\r\n }\r\n}\r\n","import { Directive, ElementRef, HostListener } from '@angular/core';\r\n\r\n/**\r\n * Directiva que permite solo la entrada de:\r\n * - Dígitos (0-9)\r\n * - Separadores punto (.)\r\n * - Rango con guión (-)\r\n * - O bien un comodín completo \"*\" que representa \"todos\"\r\n *\r\n * Ejemplos válidos:\r\n * - 1.2.3\r\n * - 4-6\r\n * - 1.3.5-9\r\n * - * (comodín: todos)\r\n *\r\n * Restringe:\r\n * - Letras\r\n * - Espacios\r\n * - Caracteres especiales (salvo \"*\")\r\n * - Doble punto (..), doble guión (--), o combinaciones como (.-)\r\n * - Mezclas de comodín con números (por ejemplo: *1, 1.*)\r\n */\r\n@Directive({\r\n selector: '[appOnlyRangoPattern]',\r\n})\r\nexport class OnlyRangoPatternDirective {\r\n constructor(private el: ElementRef<HTMLInputElement>) {}\r\n\r\n /**\r\n * Expresión regular para permitir caracteres válidos individualmente (tecla por tecla).\r\n */\r\n private keyRegex: RegExp = /^[0-9.\\-]$/;\r\n\r\n /**\r\n * Escucha el evento de teclado y permite únicamente teclas válidas.\r\n * También evita combinaciones inválidas como `..`, `--`, `.1`, etc.\r\n */\r\n @HostListener('keydown', ['$event'])\r\n onKeyDown(event: KeyboardEvent): void {\r\n const input = this.el.nativeElement;\r\n const currentValue = input.value;\r\n const cursorPos = input.selectionStart ?? 0;\r\n const selectionStart = input.selectionStart ?? 0;\r\n const selectionEnd = input.selectionEnd ?? 0;\r\n const hasFullSelection =\r\n selectionStart === 0 && selectionEnd === currentValue.length;\r\n const nextValue =\r\n currentValue.slice(0, cursorPos) +\r\n event.key +\r\n currentValue.slice(cursorPos);\r\n\r\n const allowedKeys = [\r\n 'Backspace',\r\n 'Delete',\r\n 'ArrowLeft',\r\n 'ArrowRight',\r\n 'Tab',\r\n 'Home',\r\n 'End',\r\n ];\r\n\r\n if (allowedKeys.includes(event.key)) return;\r\n\r\n // Si ya hay comodín \"*\" sin selección completa, no se permiten más caracteres\r\n // (solo borrar/navegar). Si todo el texto está seleccionado, se permite\r\n // sobrescribirlo.\r\n if (currentValue === '*' && !hasFullSelection) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n // Permitir comodín \"*\" si el campo está vacío o si todo el contenido\r\n // está seleccionado (para poder reemplazar rápidamente los números).\r\n if (event.key === '*') {\r\n if (!currentValue || hasFullSelection) {\r\n return;\r\n }\r\n\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n if (!this.keyRegex.test(event.key)) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n // No permitir más de un punto o guión seguido, o combinaciones como \".-\", \"-.\", etc.\r\n if (/(\\.\\.|--|-\\.)|(\\.-)/.test(nextValue)) {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n // No permitir iniciar con punto o guión\r\n if (cursorPos === 0 && (event.key === '.' || event.key === '-')) {\r\n event.preventDefault();\r\n }\r\n }\r\n\r\n /**\r\n * Previene el pegado de cadenas que no cumplan con la estructura válida.\r\n * Solo permite: número o número separados por punto o guión correctamente.\r\n */\r\n @HostListener('paste', ['$event'])\r\n onPaste(event: ClipboardEvent): void {\r\n const pasted = event.clipboardData?.getData('text') ?? '';\r\n const sanitized = pasted.trim();\r\n\r\n // Permitir comodín completo \"*\" pegado\r\n if (sanitized === '*') {\r\n return;\r\n }\r\n\r\n // Patrón completo de cadena válida: ej. 1.2.3.4-6\r\n const pattern = /^(\\d+(-\\d+)?)(\\.\\d+(-\\d+)?)*$/;\r\n\r\n if (!pattern.test(sanitized)) {\r\n event.preventDefault();\r\n }\r\n }\r\n}\r\n","import { Directive, HostListener } from '@angular/core';\r\n\r\n@Directive({\r\n selector: '[appSelectAllOnFocus]',\r\n})\r\nexport class SelectAllOnFocusDirective {\r\n @HostListener('onFocus', ['$event'])\r\n @HostListener('focus', ['$event'])\r\n selectAll(event: Event): void {\r\n const htmlInput = event.target as HTMLInputElement;\r\n if (htmlInput) {\r\n htmlInput.select();\r\n }\r\n }\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\n\r\nexport const CACHE_KEYS = new InjectionToken<Record<string, string>>(\r\n 'CACHE_KEYS'\r\n);\r\n","import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http';\r\nimport { Injectable, inject, isDevMode } from '@angular/core';\r\nimport { throwError } from 'rxjs';\r\nimport { ErrorModel } from '../../models/src/error.model';\r\nimport { AlertaService } from './alerta.service';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ErrorHandlerService {\r\n _serviceAlerta = inject(AlertaService);\r\n\r\n handleErrorResponse(error: HttpErrorResponse | Error) {\r\n // Si el error ya no es un HttpErrorResponse (por ejemplo, un Error relanzado\r\n // desde otro catch), sólo lo propagamos sin volver a mostrar mensajes.\r\n if (!(error instanceof HttpErrorResponse)) {\r\n if (isDevMode()) {\r\n console.error(\r\n 'Error no HTTP capturado por ErrorHandlerService:',\r\n error,\r\n );\r\n }\r\n\r\n return throwError(() => error);\r\n }\r\n\r\n const err: ErrorModel = error as ErrorModel;\r\n const technicalMessage = `Error status: ${error.status}, Message: ${error.message}, URL: ${error.url}`;\r\n\r\n let userMessage = 'Ha ocurrido un error inesperado.';\r\n\r\n switch (error.status) {\r\n case HttpStatusCode.BadRequest:\r\n userMessage =\r\n 'Solicitud incorrecta (400). Verifica los datos ingresados o validaciones existentes.';\r\n break;\r\n case HttpStatusCode.Unauthorized:\r\n userMessage =\r\n '<b>Acceso no autorizado</b> (401). Por favor inicia sesión.';\r\n break;\r\n case HttpStatusCode.Forbidden:\r\n userMessage = 'No tienes permisos para realizar esta acción (403).';\r\n break;\r\n case HttpStatusCode.NotFound:\r\n userMessage = 'No se encontró el recurso solicitado (404).';\r\n break;\r\n case HttpStatusCode.Conflict: // Capturar error de concurrencia\r\n userMessage =\r\n 'El registro fue modificado por otro usuario. Por favor, actualiza los datos antes de continuar.';\r\n break;\r\n case HttpStatusCode.InternalServerError:\r\n userMessage =\r\n 'Ocurrió un error en el servidor (500). Inténtalo más tarde.';\r\n break;\r\n default:\r\n userMessage = 'Un error inesperado ha ocurrido.';\r\n break;\r\n }\r\n\r\n // Preparar detalle del error para mostrar, priorizando solo la parte \"errors\" del objeto\r\n let errorDetail = '';\r\n\r\n if (error && typeof error.error === 'object' && error.error !== null) {\r\n const anyError: any = error.error as any;\r\n\r\n // Si existe la propiedad \"errors\" (típica de ASP.NET Core ProblemDetails), usar solo esa\r\n const validationErrors = anyError.errors ?? anyError.Errors;\r\n\r\n if (validationErrors && typeof validationErrors === 'object') {\r\n // Formatear las validaciones como texto legible\r\n const parts: string[] = [];\r\n for (const key of Object.keys(validationErrors)) {\r\n const value = validationErrors[key];\r\n const messages = Array.isArray(value)\r\n ? value.join(', ')\r\n : String(value);\r\n parts.push(`${key}: ${messages}`);\r\n }\r\n errorDetail = parts.join(' | ');\r\n } else {\r\n // Si no hay \"errors\", usar el objeto completo serializado\r\n errorDetail = JSON.stringify(anyError);\r\n }\r\n } else {\r\n errorDetail = (error?.error ?? '') as string;\r\n }\r\n\r\n // Mostrar mensaje para el usuario\r\n this._serviceAlerta.alertaHtmlSuccess(\r\n 'Servicio de Errores',\r\n '<i>Código:</i> ' +\r\n err.status +\r\n ' <i>Message:</i> ' +\r\n userMessage +\r\n (errorDetail\r\n ? `<strong class=\"alertMessageDsx\"> (${errorDetail})</strong>`\r\n : ''),\r\n { icon: 'error', icono: '', showConfirmButton: true },\r\n );\r\n\r\n // Imprimir el mensaje técnico\r\n if (isDevMode()) {\r\n console.error(err);\r\n }\r\n\r\n // Retornar el error para continuar con el flujo de manejo de errores\r\n return throwError(() => new Error(technicalMessage));\r\n }\r\n}\r\n","// Interceptor HTTP para manejar autorización y refresco de tokens en peticiones HTTP.\r\n// Permite agregar el token de autorización, manejar errores 401 y refrescar el token automáticamente.\r\nimport {\r\n HttpErrorResponse,\r\n HttpInterceptorFn,\r\n HttpStatusCode,\r\n} from '@angular/common/http';\r\nimport { inject } from '@angular/core';\r\nimport {\r\n BehaviorSubject,\r\n catchError,\r\n EMPTY,\r\n filter,\r\n finalize,\r\n switchMap,\r\n take,\r\n} from 'rxjs';\r\nimport { ServiceResult } from '../models/src/response-http.model';\r\nimport { DataToken } from '../models/src/token.model';\r\nimport { AuthorizeService } from '../services/src/authorize.service';\r\nimport { ErrorHandlerService } from '../services/src/error-handler.service';\r\nimport { SecurityService } from '../services/src/security.service';\r\nimport { SpinnerLoadingService } from '../services/src/spinner-loading.service';\r\nimport { RequestMetricsService } from '../services/src/request-metrics.service';\r\n// Indica si se está realizando un refresh de token\r\nlet isRefreshing = false;\r\n// Subject para emitir el nuevo token tras el refresh\r\nlet refreshTokenSubject = new BehaviorSubject<string | null>(null);\r\n\r\n/**\r\n * Interceptor principal para autorización HTTP.\r\n * - Agrega el token de autorización a cada petición.\r\n * - Muestra/oculta el spinner de carga según el número de peticiones activas.\r\n * - Maneja errores 401 (Unauthorized) refrescando el token si es posible.\r\n * - Repite la petición original tras refrescar el token.\r\n */\r\nexport const httpAuthorizeInterceptor: HttpInterceptorFn = (req, next) => {\r\n const _authorizeService = inject(AuthorizeService);\r\n const _securityService = inject(SecurityService);\r\n const _spinnerService = inject(SpinnerLoadingService);\r\n const _handleErrorService = inject(ErrorHandlerService);\r\n const _metricsService = inject(RequestMetricsService);\r\n const _token = _authorizeService.getToken();\r\n let authReq = req;\r\n\r\n // Si la URL de la petición es inválida, retorna un observable vacío\r\n // Surgio a partir de angular V21\r\n if (!req.url || req.url.trim() === '' || req.url === '/') {\r\n return EMPTY;\r\n }\r\n\r\n // Justo después del console.log(...)\r\n const url = req.url || '';\r\n\r\n const isAssetRequest = url.includes('/assets/') || url.startsWith('mdio/'); // ajusta según tu caso\r\n\r\n if (isAssetRequest) {\r\n // No agregar token ni mostrar spinner para estos recursos\r\n return next(req);\r\n }\r\n\r\n if (_token) {\r\n authReq = req.clone({\r\n setHeaders: { Authorization: `Bearer ${_token}` },\r\n });\r\n }\r\n\r\n //console.log('Interceptor - Petición HTTP iniciada:', req.url);\r\n\r\n // Para depuración: muestra el token agregado\r\n //console.log('Interceptor - Token agregado a la petición:', authReq);\r\n\r\n // Notifica que inicia una petición (el servicio lleva el conteo interno)\r\n _spinnerService.show();\r\n\r\n const start = performance.now();\r\n\r\n // Ejecuta la petición HTTP\r\n return next(authReq).pipe(\r\n // Manejo de errores en la respuesta\r\n catchError((error: HttpErrorResponse) => {\r\n // Si el error es 401 (no autorizado), intenta refrescar el token\r\n if (error.status === HttpStatusCode.Unauthorized) {\r\n const refreshToken = _authorizeService.getTokenRefresh();\r\n // Si no hay refresh token, delega el manejo del error\r\n if (!refreshToken) {\r\n return _handleErrorService.handleErrorResponse(error);\r\n }\r\n\r\n // Si no se está refrescando el token, inicia el proceso de refresh\r\n if (!isRefreshing) {\r\n isRefreshing = true;\r\n // Reiniciar el subject en cada ciclo de refresh para evitar estados cerrados por error\r\n refreshTokenSubject = new BehaviorSubject<string | null>(null);\r\n\r\n // Solicita el refresh del token\r\n return _securityService.tokenRefresh(refreshToken).pipe(\r\n switchMap((response: ServiceResult<DataToken>) => {\r\n // Si el servicio de refresh indica fallo o no retorna datos, mostrar error y cortar flujo\r\n if (!response.isSuccess || !response.data) {\r\n //console.log('Refresh token fallido:', response);\r\n isRefreshing = false;\r\n const refreshError = new HttpErrorResponse({\r\n status: HttpStatusCode.Unauthorized,\r\n statusText: 'Token de refresco inválido',\r\n error: response.message,\r\n url: req.url,\r\n });\r\n\r\n // Notificar a las peticiones en espera que el refresh falló\r\n refreshTokenSubject.error(refreshError);\r\n\r\n // Enviamos el error al manejador centralizado para mostrar el mensaje al usuario\r\n return _handleErrorService.handleErrorResponse(refreshError);\r\n }\r\n\r\n // Refresh exitoso: actualizar tokens y repetir la petición original\r\n isRefreshing = false;\r\n _authorizeService.tokenReload(response.data); // Actualiza el token en el servicio\r\n refreshTokenSubject.next(response.data.token); // Emite el nuevo token\r\n\r\n return next(\r\n req.clone({\r\n setHeaders: {\r\n Authorization: `Bearer ${response.data.token}`,\r\n },\r\n }),\r\n );\r\n }),\r\n catchError((err) => {\r\n isRefreshing = false;\r\n refreshTokenSubject.error(err); // Emite el error en el subject\r\n return _handleErrorService.handleErrorResponse(err);\r\n }),\r\n );\r\n } else {\r\n // Si ya se está refrescando, espera a que el subject emita el nuevo token\r\n return refreshTokenSubject.pipe(\r\n filter((token) => token != null), // Espera a que el token sea válido\r\n take(1), // Toma solo la primera emisión válida\r\n switchMap((token) =>\r\n next(\r\n req.clone({\r\n setHeaders: { Authorization: `Bearer ${token}` },\r\n }),\r\n ),\r\n ),\r\n );\r\n }\r\n }\r\n\r\n // Para otros errores, delega al servicio de manejo de errores\r\n return _handleErrorService.handleErrorResponse(error);\r\n }),\r\n // Al finalizar la petición (éxito o error), actualiza el conteo y oculta el spinner si corresponde\r\n // comentarizar el hide para verificar el spinner en la aplicacion final\r\n finalize(() => {\r\n const duration = performance.now() - start;\r\n _metricsService.registerRequest(duration);\r\n _spinnerService.hide();\r\n }),\r\n );\r\n};\r\n","export type InferCacheKeyType<T extends Record<string, string>> = keyof T;\r\n\r\n/**\r\n * Transforma un tipo de mapa `T` cuyas claves son simbólicas\r\n * y cuyos valores son nombres de propiedades reales de caché,\r\n * a un objeto donde esas propiedades reales son claves booleanas.\r\n *\r\n * @example\r\n * ```ts\r\n * type T = { cliente: 'invalidateCacheCliente' };\r\n * InferCacheOptions<T> // { invalidateCacheCliente: boolean }\r\n * ```\r\n */\r\nexport type InferCacheOptions<T extends Record<string, string>> = {\r\n [K in keyof T as T[K]]: boolean;\r\n};\r\n\r\nexport function createInitialCache<T extends Record<string, string>>(\r\n cacheKeys: T\r\n): {\r\n -readonly [K in keyof T as T[K]]: boolean;\r\n} {\r\n return Object.fromEntries(\r\n Object.values(cacheKeys).map((key) => [key, false])\r\n ) as any;\r\n}\r\n","import { CommonModule } from '@angular/common';\r\nimport { NgModule } from '@angular/core';\r\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\r\nimport { JsonValuesDebujComponent } from '../../components/json/json-values-debuj/json-values-debuj.component';\r\nimport { IconDsxComponent } from '../../components/icon-dsx/icon-dsx.component';\r\n\r\n@NgModule({\r\n declarations: [],\r\n imports: [IconDsxComponent, JsonValuesDebujComponent],\r\n exports: [\r\n CommonModule,\r\n FormsModule,\r\n IconDsxComponent,\r\n JsonValuesDebujComponent,\r\n ReactiveFormsModule,\r\n ],\r\n providers: [],\r\n})\r\nexport class DsxAddToolsModule {}\r\n","import { NgModule } from '@angular/core';\r\n\r\n//PrimeNG\r\nimport { AccordionModule } from 'primeng/accordion';\r\nimport { AutoCompleteModule } from 'primeng/autocomplete';\r\nimport { AutoFocusModule } from 'primeng/autofocus';\r\nimport { AvatarModule } from 'primeng/avatar';\r\nimport { AvatarGroupModule } from 'primeng/avatargroup';\r\nimport { BadgeModule } from 'primeng/badge';\r\nimport { ButtonModule } from 'primeng/button';\r\nimport { CardModule } from 'primeng/card';\r\nimport { CheckboxModule } from 'primeng/checkbox';\r\nimport { ContextMenuModule } from 'primeng/contextmenu';\r\nimport { DatePickerModule } from 'primeng/datepicker';\r\nimport { DialogModule } from 'primeng/dialog';\r\nimport { DividerModule } from 'primeng/divider';\r\nimport { DrawerModule } from 'primeng/drawer';\r\nimport { FieldsetModule } from 'primeng/fieldset';\r\nimport { FileUploadModule } from 'primeng/fileupload';\r\nimport { FloatLabelModule } from 'primeng/floatlabel';\r\nimport { IconFieldModule } from 'primeng/iconfield';\r\nimport { ImageModule } from 'primeng/image';\r\nimport { InputIconModule } from 'primeng/inputicon';\r\nimport { InputMaskModule } from 'primeng/inputmask';\r\nimport { InputNumberModule } from 'primeng/inputnumber';\r\nimport { InputTextModule } from 'primeng/inputtext';\r\nimport { KeyFilterModule } from 'primeng/keyfilter';\r\nimport { KnobModule } from 'primeng/knob';\r\nimport { MenubarModule } from 'primeng/menubar';\r\nimport { MessageModule } from 'primeng/message';\r\nimport { MultiSelectModule } from 'primeng/multiselect';\r\nimport { OrganizationChartModule } from 'primeng/organizationchart';\r\nimport { OverlayBadgeModule } from 'primeng/overlaybadge';\r\nimport { PanelMenuModule } from 'primeng/panelmenu';\r\nimport { PasswordModule } from 'primeng/password';\r\nimport { PickListModule } from 'primeng/picklist';\r\nimport { PopoverModule } from 'primeng/popover';\r\nimport { RadioButtonModule } from 'primeng/radiobutton';\r\nimport { RatingModule } from 'primeng/rating';\r\nimport { RippleModule } from 'primeng/ripple';\r\nimport { ScrollerModule } from 'primeng/scroller';\r\nimport { ScrollPanelModule } from 'primeng/scrollpanel';\r\nimport { SelectModule } from 'primeng/select';\r\nimport { SelectButtonModule } from 'primeng/selectbutton';\r\nimport { SliderModule } from 'primeng/slider';\r\nimport { SpeedDialModule } from 'primeng/speeddial';\r\nimport { SplitButtonModule } from 'primeng/splitbutton';\r\nimport { StepperModule } from 'primeng/stepper';\r\nimport { TableModule } from 'primeng/table';\r\nimport { TabsModule } from 'primeng/tabs';\r\nimport { TagModule } from 'primeng/tag';\r\nimport { TextareaModule } from 'primeng/textarea';\r\nimport { TimelineModule } from 'primeng/timeline';\r\nimport { ToastModule } from 'primeng/toast';\r\nimport { ToggleButtonModule } from 'primeng/togglebutton';\r\nimport { TooltipModule } from 'primeng/tooltip';\r\nimport { TreeModule } from 'primeng/tree';\r\nimport { TreeTableModule } from 'primeng/treetable';\r\n\r\nconst PRIME_NG_MODULES = [\r\n AccordionModule,\r\n AutoCompleteModule,\r\n AutoFocusModule,\r\n AvatarGroupModule,\r\n AvatarModule,\r\n BadgeModule,\r\n ButtonModule,\r\n CardModule,\r\n CheckboxModule,\r\n ContextMenuModule,\r\n DatePickerModule,\r\n DialogModule,\r\n DividerModule,\r\n DrawerModule,\r\n FieldsetModule,\r\n FileUploadModule,\r\n FloatLabelModule,\r\n IconFieldModule,\r\n ImageModule,\r\n InputIconModule,\r\n InputMaskModule,\r\n InputNumberModule,\r\n InputTextModule,\r\n KeyFilterModule,\r\n KnobModule,\r\n MenubarModule,\r\n MessageModule,\r\n MultiSelectModule,\r\n OrganizationChartModule,\r\n OverlayBadgeModule,\r\n PanelMenuModule,\r\n PasswordModule,\r\n PickListModule,\r\n PopoverModule,\r\n RadioButtonModule,\r\n RatingModule,\r\n RippleModule,\r\n ScrollerModule,\r\n ScrollPanelModule,\r\n SelectButtonModule,\r\n SelectModule,\r\n SliderModule,\r\n SpeedDialModule,\r\n SplitButtonModule,\r\n StepperModule,\r\n TableModule,\r\n TabsModule,\r\n TagModule,\r\n TextareaModule,\r\n TimelineModule,\r\n ToastModule,\r\n ToggleButtonModule,\r\n TooltipModule,\r\n TreeModule,\r\n TreeTableModule,\r\n];\r\n\r\n@NgModule({\r\n declarations: [],\r\n imports: [],\r\n exports: [...PRIME_NG_MODULES],\r\n providers: [],\r\n})\r\nexport class PrimeNgModule {}\r\n","import { Pipe, PipeTransform } from '@angular/core';\n\n/**\n * Pipe `joinByPipe`\n *\n * Une los valores de una propiedad de un arreglo de objetos en una sola cadena\n * separado por el `separator` proporcionado.\n *\n * Uso (template):\n * - `items | joinByPipe:'name'` => une la propiedad `name` con `, ` como separador\n * - `items | joinByPipe:'name':'; '` => usa `; ` como separador\n *\n * Ejemplo:\n * const items = [{ name: 'Ana' }, { name: 'Luis' }, { other: 'x' }];\n * // Resultado: 'Ana, Luis'\n *\n * Comportamiento:\n * - Si el arreglo es nulo, indefinido o vacío devuelve `''`.\n * - Si la propiedad no existe en el primer elemento devuelve `''` y registra\n * una advertencia en la consola.\n * - Convierte cada valor a `string`, filtra valores vacíos y los concatena.\n */\n@Pipe({\n name: 'joinBy',\n standalone: true,\n})\nexport class JoinByPipe implements PipeTransform {\n /**\n * Transforma un arreglo de objetos en una cadena unida por `separator` usando\n * la propiedad indicada.\n *\n * @param array - Arreglo de objetos o `null`/`undefined`.\n * @param property - Clave del objeto cuyos valores se van a unir.\n * @param separator - Cadena que separará los valores (por defecto `', '`).\n * @returns Una cadena con los valores unidos o `''` si no hay datos válidos.\n */\n transform<T extends Record<string, any>>(\n array: T[] | null | undefined,\n property: keyof T,\n separator: string = ', ',\n ): string {\n // Si el arreglo está vacío o es nulo/indefinido retornamos cadena vacía\n if (!array?.length) return '';\n\n // Validar que la propiedad exista al menos en el primer elemento\n if (!(property in array[0])) {\n console.warn(\n `JoinByPipe: La propiedad \"${String(property)}\" no existe en el objeto.`,\n );\n return '';\n }\n\n // Convertir valores a string, eliminar vacíos y unir con el separador\n return array\n .map((item) => String(item[property] ?? ''))\n .filter((value) => value.length > 0)\n .join(separator);\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\r\n\r\n@Pipe({\r\n name: 'truncate',\r\n standalone: true,\r\n})\r\nexport class TruncatePipe implements PipeTransform {\r\n /**\r\n * Transforma una cadena de texto truncándola según los parámetros proporcionados.\r\n *\r\n * @param value - La cadena de texto que se desea truncar.\r\n * @param limit - El número máximo de caracteres permitidos. Por defecto es 100. Si no se encuentra un espacio dentro del límite, usa el límite original (15).\r\n * @param completeWords - Si es true, evita cortar palabras a la mitad. Por defecto es false.\r\n * @param ellipsis - La cadena que se añadirá al final del texto truncado. Por defecto es '...'.\r\n * @returns La cadena truncada con el ellipsis añadido, si es necesario.\r\n */\r\n transform(\r\n value: string,\r\n limit: number = 20,\r\n completeWords: boolean = false,\r\n ellipsis: string = '...'\r\n ): string {\r\n // Si el valor es nulo o indefinido, devuelve una cadena vacía para evitar errores.\r\n if (!value) {\r\n return '';\r\n }\r\n\r\n // Si completeWords es true, ajusta el límite para no cortar palabras.\r\n if (completeWords) {\r\n // Encuentra el último espacio dentro del límite para evitar cortar palabras.\r\n limit = value.slice(0, limit).lastIndexOf(' ');\r\n\r\n // Si no se encuentra un espacio dentro del límite, usa el límite original.\r\n if (limit < 0) {\r\n limit = 15; // Valor por defecto si no hay espacios.\r\n }\r\n }\r\n\r\n // Trunca el texto y añade el ellipsis si la longitud del texto supera el límite.\r\n return value.length > limit ? value.slice(0, limit) + ellipsis : value;\r\n }\r\n}\r\n","import { HttpClient } from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { Observable } from 'rxjs';\r\nimport {\r\n ENVIRONMENT,\r\n EnvironmentConfig,\r\n} from '../../injections/environment.token';\r\nimport {\r\n ServiceResult,\r\n ServiceResultVoid,\r\n} from '../../models/src/response-http.model';\r\n\r\n/**\r\n * Servicio genérico para consumir endpoints REST de la API.\r\n *\r\n * @typeParam T Tipo base de la entidad. Puede sobrescribirse por método.\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class EndpointService<T> {\r\n /** Cliente HTTP de Angular utilizado para realizar las peticiones. */\r\n private http = inject(HttpClient);\r\n\r\n /** Configuración de entorno que contiene la URL base de la API. */\r\n private environment: EnvironmentConfig = inject(ENVIRONMENT);\r\n\r\n /**\r\n * Construye la URL completa del endpoint a partir de la configuración de entorno.\r\n *\r\n * @param endpoint Segmento del endpoint (por ejemplo: 'usuarios', 'facturas').\r\n * @returns URL absoluta del endpoint.\r\n */\r\n private getUrl(endpoint: string): string {\r\n return `${this.environment.myAppUrl}api/${endpoint}`;\r\n }\r\n\r\n /**\r\n * Obtiene un listado de recursos del endpoint especificado.\r\n *\r\n * @typeParam TList Tipo de cada elemento del listado (por defecto `T`).\r\n * @param endpoint Segmento del endpoint (sin la parte de `api/`).\r\n * @param invalidateCache Indica si se invalida la caché del lado del servidor.\r\n * @returns Observable con un arreglo de elementos del tipo `TList`.\r\n */\r\n list<TList = T>(\r\n endpoint: string,\r\n invalidateCache: boolean = false,\r\n ): Observable<TList[]> {\r\n return this.http.get<TList[]>(\r\n `${this.getUrl(endpoint)}/listar/${invalidateCache}`,\r\n );\r\n }\r\n\r\n /**\r\n * Obtiene un recurso por su identificador.\r\n *\r\n * @typeParam TEdit Tipo del recurso retornado (por defecto `T`).\r\n * @param endpoint Segmento del endpoint (sin la parte de `api/`).\r\n * @param id Identificador del recurso a recuperar.\r\n * @returns Observable con el elemento del tipo `TEdit`.\r\n */\r\n edit<TEdit = T>(endpoint: string, id: number): Observable<TEdit> {\r\n return this.http.get<TEdit>(`${this.getUrl(endpoint)}/get-id/${id}`);\r\n }\r\n\r\n /**\r\n * Crea o actualiza un recurso en el endpoint especificado.\r\n *\r\n * @typeParam TSave Tipo del payload enviado al backend (por defecto `T`).\r\n * @typeParam TResponse Tipo de la entidad en la respuesta (por defecto `T`).\r\n * @param endpoint Segmento del endpoint (sin la parte de `api/`).\r\n * @param values Objeto con los datos del recurso a guardar.\r\n * @returns Observable con el resultado del servicio que envuelve `TResponse`.\r\n */\r\n save<TSave = T, TResponse = T>(\r\n endpoint: string,\r\n values: TSave,\r\n ): Observable<ServiceResult<TResponse>> {\r\n return this.http.put<ServiceResult<TResponse>>(\r\n `${this.getUrl(endpoint)}/save`,\r\n values,\r\n );\r\n }\r\n\r\n /**\r\n * Elimina un recurso del endpoint especificado.\r\n *\r\n * @param endpoint Segmento del endpoint (sin la parte de `api/`).\r\n * @param id Identificador del recurso a eliminar (numérico o textual).\r\n * @param softDelete Indica si la eliminación es lógica (por defecto) o física.\r\n * @returns Observable con el modelo de respuesta HTTP genérico.\r\n */\r\n delete(\r\n endpoint: string,\r\n id: number | string,\r\n softDelete: boolean = true,\r\n ): Observable<ServiceResultVoid> {\r\n return this.http.delete<ServiceResultVoid>(\r\n `${this.getUrl(endpoint)}/delete/${id}/${softDelete}`,\r\n );\r\n }\r\n}\r\n","import { inject, Injectable } from '@angular/core';\r\nimport { EndpointService } from './endpoint.service';\r\n\r\n/**\r\n * Clase base para servicios CRUD tipados.\r\n *\r\n * @typeParam TBase Modelo base que representa la entidad principal.\r\n * @typeParam TEdit Modelo de respuesta para la operación de edición/consulta por id.\r\n * @typeParam TSave Modelo de entrada para guardar (create/update).\r\n * @typeParam TList Modelo de cada elemento del listado.\r\n * @typeParam TDelete Tipo del identificador usado para eliminar (number o string).\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport abstract class BaseCRUDService<\r\n TBase,\r\n TEdit = TBase,\r\n TSave = TBase,\r\n TList = TBase,\r\n TDelete extends string | number = number,\r\n> {\r\n /** Segmento del endpoint (sin prefijo api/). */\r\n protected abstract endpoint: string;\r\n\r\n /** Servicio HTTP base para operaciones REST. */\r\n protected readonly _endpointService = inject(EndpointService);\r\n\r\n /**\r\n * Obtiene el listado de registros.\r\n * @param invalidateCache Si es true, solicita invalidar caché en backend.\r\n */\r\n list(invalidateCache: boolean = false) {\r\n return this._endpointService.list<TList>(this.endpoint, invalidateCache);\r\n }\r\n\r\n /**\r\n * Obtiene un registro por id para edición.\r\n * @param id Identificador numérico del registro.\r\n */\r\n edit(id: number) {\r\n return this._endpointService.edit<TEdit>(this.endpoint, id);\r\n }\r\n\r\n /**\r\n * Guarda un registro (creación o actualización).\r\n * @param values Payload tipado para persistir.\r\n */\r\n save(values: TSave) {\r\n return this._endpointService.save<TSave, TBase>(this.endpoint, values);\r\n }\r\n\r\n /**\r\n * Elimina un registro por identificador.\r\n * @param value Identificador del registro a eliminar.\r\n * @param softDelete Si es true, realiza eliminación lógica.\r\n */\r\n delete(value: TDelete, softDelete: boolean = true) {\r\n return this._endpointService.delete(this.endpoint, value, softDelete);\r\n }\r\n}\r\n","import { inject, Injectable, signal } from '@angular/core';\r\nimport { CACHE_KEYS } from '../../injections/cache.token';\r\nimport { InferCacheOptions } from '../../models/src/cache.types';\r\nimport { AlertaService } from './alerta.service';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\n\r\n/**\r\n * Servicio genérico para el manejo de caché reactivo basado en claves definidas por el consumidor.\r\n *\r\n * Este servicio utiliza señales (`signal`) para almacenar el estado de invalidación de caché\r\n * y permite marcar ciertas entradas como inválidas mediante una llamada a `invalidate`.\r\n *\r\n * ---\r\n * ## Uso básico\r\n * Si no se especifica el tipo genérico `T`, el servicio funcionará con un mapa genérico\r\n * `Record<string, string>` sin autocompletado.\r\n *\r\n * ```ts\r\n * const cacheService = inject(CacheService);\r\n * cacheService.invalidate(['cualquierClave']);\r\n * ```\r\n *\r\n * ---\r\n * ## Uso tipado (recomendado)\r\n * 1. Definir las claves de caché en el proyecto consumidor:\r\n * ```ts\r\n * export const INITIAL_CACHE_KEYS = {\r\n * cliente: 'invalidateCacheCliente',\r\n * empresa: 'invalidateCacheEmpresa'\r\n * } as const;\r\n *\r\n * export type ValueCacheKeys = typeof INITIAL_CACHE_KEYS;\r\n * ```\r\n *\r\n * 2. Proveer estas claves en `AppModule` o un módulo raíz:\r\n * ```ts\r\n * providers: [\r\n * { provide: CACHE_KEYS, useValue: INITIAL_CACHE_KEYS }\r\n * ]\r\n * ```\r\n *\r\n * 3. Inyectar el servicio especificando el tipo:\r\n * ```ts\r\n * const cacheService = inject<CacheService<ValueCacheKeys>>(CacheService);\r\n *\r\n * cacheService.options.invalidateCacheCliente; // ✅ boolean con autocompletado\r\n * cacheService.invalidate(['cliente']); // marca como invalidado\r\n * ```\r\n *\r\n * @typeParam T - Objeto con claves simbólicas (`keyof T`) como `cliente`, `empresa`,\r\n * y valores string literales usados como claves reales de caché.\r\n * Por defecto: `Record<string, string>`.\r\n */\r\nexport class CacheService<\r\n T extends Record<string, string> = Record<string, string>,\r\n> {\r\n /**\r\n * Mapa de claves simbólicas a claves reales de caché.\r\n * Se inyecta desde el proyecto consumidor mediante `CACHE_KEYS`.\r\n */\r\n private keys = inject(CACHE_KEYS) as T;\r\n\r\n /**\r\n * Servicio de alerta utilizado para mostrar notificaciones al usuario.\r\n */\r\n private alert = inject(AlertaService);\r\n\r\n /**\r\n * Estado reactivo que contiene un objeto donde cada propiedad (clave real de caché)\r\n * tiene un valor booleano que indica si el caché ha sido invalidado (`true`)\r\n * o sigue siendo válido (`false`).\r\n *\r\n * Este estado es tipado automáticamente en función de los valores de `T`.\r\n */\r\n private _options = signal<InferCacheOptions<T>>(\r\n Object.fromEntries(\r\n Object.values(this.keys).map((k) => [k, false]),\r\n ) as InferCacheOptions<T>,\r\n );\r\n\r\n /**\r\n * Obtiene el estado actual del caché.\r\n * Cada propiedad representa una clave real de caché con su valor booleano.\r\n */\r\n get options(): InferCacheOptions<T> {\r\n return this._options();\r\n }\r\n\r\n /**\r\n * Invalida una o más claves simbólicas, marcando su correspondiente\r\n * propiedad de caché como `true` (invalidada).\r\n *\r\n * @param keysToInvalidate - Lista de claves simbólicas (`keyof T`) a invalidar.\r\n *\r\n * @example\r\n * ```ts\r\n * cacheService.invalidate(['cliente', 'empresa']);\r\n * ```\r\n */\r\n invalidate(keysToInvalidate: (keyof T)[] | null = null): void {\r\n if (!keysToInvalidate?.length) return;\r\n\r\n const current: InferCacheOptions<T> = { ...this._options() };\r\n\r\n keysToInvalidate.forEach((key) => {\r\n const prop = this.keys[key] as keyof InferCacheOptions<T>;\r\n current[prop] = true as InferCacheOptions<T>[typeof prop];\r\n });\r\n\r\n this._options.set(current);\r\n\r\n this.alert.toastrAlerts(\r\n 2,\r\n 'Estado',\r\n 'Datos actualizados (cache).',\r\n 2,\r\n 1000,\r\n );\r\n }\r\n}\r\n","import { InjectionToken, Provider } from '@angular/core';\r\nimport { CacheService } from './cache.service';\r\n\r\nexport function createTypedCacheProvider<T extends Record<string, string>>(\r\n tokenName: string\r\n): { token: InjectionToken<CacheService<T>>; provider: Provider } {\r\n const token = new InjectionToken<CacheService<T>>(tokenName);\r\n\r\n const provider: Provider = {\r\n provide: token,\r\n useFactory: () => new CacheService<T>(),\r\n deps: [],\r\n };\r\n\r\n return { token, provider };\r\n}\r\n","import { HttpClient } from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport {\r\n ENVIRONMENT,\r\n EnvironmentConfig,\r\n} from '../../injections/environment.token';\r\nimport { Observable } from 'rxjs';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class DteService {\r\n /** Servicio HttpClient para realizar peticiones HTTP */\r\n private http = inject(HttpClient);\r\n\r\n /**\r\n * Configuración del entorno inyectada mediante el token ENVIRONMENT.\r\n * La validación se realiza automáticamente al usar provideEnvironment().\r\n */\r\n private environment: EnvironmentConfig = inject(ENVIRONMENT);\r\n\r\n /** URL base de la API JWT construida desde la configuración del entorno */\r\n private SeguridadITApi: string = `${this.environment.SeguridadITApiUrl}api/dte`;\r\n\r\n pdfDTE(UUID: string): Observable<Blob> {\r\n // Realiza una solicitud POST al endpoint de refresco de token\r\n return this.http.get<Blob>(`${this.SeguridadITApi}/pdf-dte/${UUID}`, {\r\n responseType: 'blob' as 'json',\r\n });\r\n }\r\n}\r\n","export function containsFile(obj: any): boolean {\r\n for (const key in obj) {\r\n const value = obj[key];\r\n\r\n if (value instanceof File || value instanceof Blob) {\r\n return true;\r\n }\r\n\r\n if (value instanceof FileList) {\r\n return true;\r\n }\r\n\r\n if (typeof value === 'object' && value !== null) {\r\n if (containsFile(value)) {\r\n return true;\r\n }\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport function toFormData(\r\n data: any,\r\n formData: FormData = new FormData(),\r\n parentKey?: string,\r\n): FormData {\r\n Object.keys(data).forEach((key) => {\r\n const value = data[key];\r\n const formKey = parentKey ? `${parentKey}.${key}` : key;\r\n\r\n if (value === null || value === undefined) return;\r\n\r\n if (value instanceof File || value instanceof Blob) {\r\n formData.append(formKey, value);\r\n return;\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n value.forEach((v, i) => {\r\n toFormData(v, formData, `${formKey}[${i}]`);\r\n });\r\n return;\r\n }\r\n\r\n if (typeof value === 'object') {\r\n toFormData(value, formData, formKey);\r\n return;\r\n }\r\n\r\n formData.append(formKey, String(value));\r\n });\r\n\r\n return formData;\r\n}\r\n","import {\r\n HttpClient,\r\n HttpHeaders,\r\n HttpParams,\r\n HttpResponse,\r\n} from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { Observable } from 'rxjs';\r\nimport { toFormData } from '../../utils/src/form-data.util';\r\n\r\ntype HttpParamValue = string | number | boolean | Date | null | undefined;\r\ntype HttpParamsRecord = Record<string, HttpParamValue | HttpParamValue[]>;\r\n\r\nexport interface BlobRequestOptions {\r\n params?: HttpParamsRecord | HttpParams;\r\n headers?: HttpHeaders | Record<string, string | string[]>;\r\n withCredentials?: boolean;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\n/**\r\n * HttpHelperService\r\n *\r\n * Servicio diseñado para endpoints que usan [FromForm] en ASP.NET Core.\r\n * Siempre convierte el objeto a FormData, independientemente de si contiene\r\n * un archivo o no. Si el campo de tipo File/Blob/FileList es null o undefined,\r\n * simplemente se omite del FormData.\r\n *\r\n * Ejemplo sin archivo:\r\n *\r\n * this.api.post('puesto/guardar', { puestoId: 1, nombre: 'Admin' });\r\n *\r\n * Ejemplo con archivo (el campo puede ser null si no se seleccionó):\r\n *\r\n * this.api.post('puesto/cargar-funciones', {\r\n * puestoId: 1,\r\n * puestoNombre: 'Administrador',\r\n * file: this.file // puede ser null\r\n * });\r\n */\r\nexport class HttpHelpersService {\r\n private readonly http = inject(HttpClient);\r\n\r\n /**\r\n * POST orientado a endpoints `[FromForm]` en backend (ASP.NET Core u otros).\r\n *\r\n * Convierte automáticamente `data` a `FormData`, por lo que permite enviar\r\n * campos simples y archivos (`File`, `Blob`, `FileList`) en una sola llamada.\r\n *\r\n * Casos de uso comunes:\r\n * - Crear/actualizar recursos con adjuntos.\r\n * - Subir archivos junto con metadata (id, nombre, observaciones, etc.).\r\n * - Mantener un único método de POST para formularios multipart.\r\n *\r\n * @typeParam T Tipo de respuesta esperada del backend.\r\n * @param url Endpoint relativo o absoluto.\r\n * @param data Objeto plano que se transformará a `FormData`.\r\n * @returns `Observable<T>` con la respuesta del backend.\r\n *\r\n * @example\r\n * this.httpHelpers.postForm<{ ok: boolean }>('documentos/subir', {\r\n * documentoId: 15,\r\n * descripcion: 'Contrato firmado',\r\n * archivo: this.archivoSeleccionado // File | null\r\n * });\r\n */\r\n postForm<T>(url: string, data: object): Observable<T> {\r\n return this.http.post<T>(url, toFormData(data as Record<string, unknown>));\r\n }\r\n\r\n /**\r\n * PUT orientado a endpoints `[FromForm]` en backend (ASP.NET Core u otros).\r\n *\r\n * Equivalente a `postForm`, pero usando el verbo HTTP PUT para actualizar recursos existentes.\r\n *\r\n * @typeParam T Tipo de respuesta esperada del backend.\r\n * @param url Endpoint relativo o absoluto.\r\n * @param data Objeto plano que se transformará a `FormData`.\r\n * @returns `Observable<T>` con la respuesta del backend.\r\n *\r\n * @example\r\n * this.httpHelpers.putForm<{ ok: boolean }>('documentos/actualizar/15', {\r\n * documentoId: 15,\r\n * descripcion: 'Contrato actualizado',\r\n * archivo: this.archivoSeleccionado // File | null\r\n * });\r\n */\r\n putForm<T>(url: string, data: object): Observable<T> {\r\n return this.http.put<T>(url, toFormData(data as Record<string, unknown>));\r\n }\r\n\r\n /**\r\n * GET para descarga de archivos en formato Blob.\r\n * Útil cuando solo se necesita el contenido del archivo.\r\n */\r\n getBlob(url: string, options: BlobRequestOptions = {}): Observable<Blob> {\r\n return this.http.get(url, {\r\n responseType: 'blob',\r\n params: this.toHttpParams(options.params),\r\n headers: options.headers,\r\n withCredentials: options.withCredentials,\r\n });\r\n }\r\n\r\n /**\r\n * GET para descarga de archivos devolviendo HttpResponse completo.\r\n * Útil para leer headers como `content-disposition` (nombre de archivo) o status.\r\n *\r\n * Consideraciones de backend:\r\n * - Validar `fileName`/id en route params antes de construir la ruta física.\r\n * - Definir query params opcionales (ej. versión, idioma, tenant) y documentarlos.\r\n * - Si se requiere cookie/sesión, habilitar `withCredentials` en frontend y CORS en backend.\r\n */\r\n getBlobResponse(\r\n url: string,\r\n options: BlobRequestOptions = {},\r\n ): Observable<HttpResponse<Blob>> {\r\n return this.http.get(url, {\r\n responseType: 'blob',\r\n observe: 'response',\r\n params: this.toHttpParams(options.params),\r\n headers: options.headers,\r\n withCredentials: options.withCredentials,\r\n });\r\n }\r\n\r\n private toHttpParams(\r\n params?: BlobRequestOptions['params'],\r\n ): HttpParams | undefined {\r\n if (!params) {\r\n return undefined;\r\n }\r\n\r\n if (params instanceof HttpParams) {\r\n return params;\r\n }\r\n\r\n let httpParams = new HttpParams();\r\n\r\n for (const [key, value] of Object.entries(params)) {\r\n if (value === null || value === undefined) {\r\n continue;\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n for (const item of value) {\r\n if (item === null || item === undefined) {\r\n continue;\r\n }\r\n httpParams = httpParams.append(key, this.normalizeParamValue(item));\r\n }\r\n continue;\r\n }\r\n\r\n httpParams = httpParams.set(key, this.normalizeParamValue(value));\r\n }\r\n\r\n return httpParams;\r\n }\r\n\r\n private normalizeParamValue(\r\n value: Exclude<HttpParamValue, null | undefined>,\r\n ): string {\r\n if (value instanceof Date) {\r\n return value.toISOString();\r\n }\r\n\r\n return String(value);\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\n\r\nfunction pickByKeys<T extends object, K extends keyof T>(\r\n source: T,\r\n keys: readonly K[],\r\n): Pick<T, K> {\r\n const result = {} as Pick<T, K>;\r\n\r\n for (const key of keys) {\r\n result[key] = source[key];\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction tryParseDateValue(value: unknown): number | null {\r\n if (value instanceof Date) {\r\n const time = value.getTime();\r\n\r\n return Number.isNaN(time) ? null : time;\r\n }\r\n\r\n if (typeof value === 'string' || typeof value === 'number') {\r\n const parsed = new Date(value);\r\n const time = parsed.getTime();\r\n\r\n return Number.isNaN(time) ? null : time;\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction normalizeComparableValue(base: unknown, current: unknown): unknown {\r\n const baseDateValue = tryParseDateValue(base);\r\n\r\n if (baseDateValue !== null) {\r\n const currentDateValue = tryParseDateValue(current);\r\n\r\n return currentDateValue ?? current;\r\n }\r\n\r\n return current;\r\n}\r\n\r\nfunction normalizeBaseEntity<TBase extends object>(\r\n baseValue: TBase,\r\n keys?: ReadonlyArray<keyof TBase>,\r\n): Partial<Record<keyof TBase, unknown>> {\r\n const normalized: Partial<Record<keyof TBase, unknown>> = {};\r\n const selectedKeys = keys ?? (Object.keys(baseValue) as Array<keyof TBase>);\r\n\r\n for (const key of selectedKeys) {\r\n const base = (baseValue as Record<string, unknown>)[key as string];\r\n\r\n normalized[key] = normalizeComparableValue(base, base);\r\n }\r\n\r\n return normalized;\r\n}\r\n\r\nfunction normalizeRawEntityAgainstBase<TBase extends object>(\r\n baseValue: TBase,\r\n rawValue: MasterDetailRawEntity<TBase>,\r\n keys?: ReadonlyArray<keyof TBase>,\r\n useBaseValueForNullish = true,\r\n): Partial<Record<keyof TBase, unknown>> {\r\n const coerceByBaseType = (base: unknown, current: unknown): unknown => {\r\n if (typeof base === 'number') {\r\n if (typeof current === 'string' && current.trim() !== '') {\r\n const normalizedText = current.trim();\r\n const direct = Number(normalizedText);\r\n\r\n if (!Number.isNaN(direct)) return direct;\r\n\r\n const commaDecimal = Number(normalizedText.replace(',', '.'));\r\n\r\n if (!Number.isNaN(commaDecimal)) return commaDecimal;\r\n\r\n const noSpaces = normalizedText.replace(/\\s+/g, '');\r\n const noThousandsDots = Number(\r\n noSpaces.replace(/\\./g, '').replace(',', '.'),\r\n );\r\n\r\n if (!Number.isNaN(noThousandsDots)) return noThousandsDots;\r\n\r\n return current;\r\n }\r\n\r\n return current;\r\n }\r\n\r\n if (typeof base === 'boolean') {\r\n if (typeof current === 'string') {\r\n const lowered = current.trim().toLowerCase();\r\n\r\n if (lowered === 'true') return true;\r\n if (lowered === 'false') return false;\r\n }\r\n\r\n return current;\r\n }\r\n\r\n if (base instanceof Date) {\r\n if (current instanceof Date) return current;\r\n\r\n if (typeof current === 'string' || typeof current === 'number') {\r\n const parsed = new Date(current);\r\n\r\n return Number.isNaN(parsed.getTime()) ? current : parsed;\r\n }\r\n\r\n return current;\r\n }\r\n\r\n if (typeof base === 'string') {\r\n if (current === null || current === undefined) return current;\r\n\r\n return typeof current === 'string' ? current : String(current);\r\n }\r\n\r\n return current;\r\n };\r\n\r\n const normalized: Partial<Record<keyof TBase, unknown>> = {};\r\n const selectedKeys = keys ?? (Object.keys(baseValue) as Array<keyof TBase>);\r\n\r\n for (const key of selectedKeys) {\r\n const base = (baseValue as Record<string, unknown>)[key as string];\r\n const current = rawValue[key as string];\r\n const isNullish = current === null || current === undefined;\r\n const isEmptyString = typeof current === 'string' && current.trim() === '';\r\n const treatEmptyAsNullish = isEmptyString && typeof base !== 'string';\r\n const shouldUseBase =\r\n useBaseValueForNullish && (isNullish || treatEmptyAsNullish);\r\n\r\n normalized[key] = shouldUseBase ? base : coerceByBaseType(base, current);\r\n\r\n normalized[key] = normalizeComparableValue(base, normalized[key]);\r\n }\r\n\r\n return normalized;\r\n}\r\n\r\n/**\r\n * Estado maestro-detalle usado por el tracker.\r\n */\r\nexport interface MasterDetailState<TMaster, TDetail> {\r\n /** Entidad principal (cabecera o maestro). */\r\n master: TMaster;\r\n /** Coleccion de entidades detalle asociadas al maestro. */\r\n detail: TDetail[];\r\n}\r\n\r\n/**\r\n * Tipo crudo para valores provenientes de formularios.\r\n */\r\nexport type MasterDetailRawEntity<TBase extends object> = Partial<\r\n Record<keyof TBase, unknown>\r\n> &\r\n Record<string, unknown>;\r\n\r\n/**\r\n * Opciones simplificadas para comparar estado base vs valores crudos de formulario.\r\n */\r\nexport interface MasterDetailSimpleFormOptions<\r\n TBaseMaster extends object,\r\n TBaseDetail extends object,\r\n> {\r\n /** Campos del maestro a seguir. */\r\n masterKeys?: ReadonlyArray<keyof TBaseMaster>;\r\n\r\n /** Campos del detalle a seguir. */\r\n detailKeys?: ReadonlyArray<keyof TBaseDetail>;\r\n\r\n /**\r\n * Si es `true` (default), cuando el valor actual sea `null` o `undefined`\r\n * se usa el valor base para evitar falsos positivos en formularios.\r\n */\r\n useBaseValueForNullish?: boolean;\r\n}\r\n\r\nexport interface MasterDetailDifference {\r\n scope: 'master' | 'detail';\r\n path: string;\r\n baseValue: unknown;\r\n currentValue: unknown;\r\n}\r\n\r\n/**\r\n * Resultado detallado de comparacion entre estado inicial y actual.\r\n */\r\nexport interface MasterDetailChangeResult {\r\n hasChanges: boolean;\r\n masterChanged: boolean;\r\n detailChanged: boolean;\r\n firstDifference: MasterDetailDifference | null;\r\n}\r\n\r\n/**\r\n * Tracker simplificado para comparar estado base vs `getRawValue()`.\r\n */\r\nexport interface MasterDetailSimpleFormTracker<\r\n TBaseMaster extends object,\r\n TBaseDetail extends object,\r\n> {\r\n /**\r\n * Indica si existe cualquier cambio entre el estado inicial y el actual.\r\n */\r\n hasChanges: (\r\n currentState: MasterDetailState<\r\n MasterDetailRawEntity<TBaseMaster>,\r\n MasterDetailRawEntity<TBaseDetail>\r\n >,\r\n ) => boolean;\r\n\r\n /**\r\n * Retorna un desglose de cambios por seccion (maestro/detalle).\r\n */\r\n getChanges: (\r\n currentState: MasterDetailState<\r\n MasterDetailRawEntity<TBaseMaster>,\r\n MasterDetailRawEntity<TBaseDetail>\r\n >,\r\n ) => MasterDetailChangeResult;\r\n\r\n /**\r\n * Reemplaza el estado base de comparacion con uno nuevo.\r\n */\r\n reset: (state: MasterDetailState<TBaseMaster, TBaseDetail>) => void;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\n/**\r\n * Servicio utilitario para detectar cambios en formularios o vistas\r\n * maestro-detalle sin acoplarse a una estructura de dominio concreta.\r\n */\r\nexport class MasterDetailChangeService {\r\n private static findFirstDifference(\r\n leftValue: unknown,\r\n rightValue: unknown,\r\n path = 'root',\r\n ): { path: string; leftValue: unknown; rightValue: unknown } | null {\r\n if (leftValue instanceof Date && rightValue instanceof Date) {\r\n return leftValue.getTime() === rightValue.getTime()\r\n ? null\r\n : { path, leftValue, rightValue };\r\n }\r\n\r\n if (Array.isArray(leftValue) && Array.isArray(rightValue)) {\r\n if (leftValue.length !== rightValue.length) {\r\n return {\r\n path: `${path}.length`,\r\n leftValue: leftValue.length,\r\n rightValue: rightValue.length,\r\n };\r\n }\r\n\r\n for (let index = 0; index < leftValue.length; index += 1) {\r\n const difference = MasterDetailChangeService.findFirstDifference(\r\n leftValue[index],\r\n rightValue[index],\r\n `${path}[${index}]`,\r\n );\r\n\r\n if (difference) {\r\n return difference;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n if (\r\n leftValue != null &&\r\n rightValue != null &&\r\n typeof leftValue === 'object' &&\r\n typeof rightValue === 'object'\r\n ) {\r\n const leftKeys = Object.keys(leftValue);\r\n const rightKeys = Object.keys(rightValue);\r\n\r\n if (leftKeys.length !== rightKeys.length) {\r\n return {\r\n path: `${path}.__keys__`,\r\n leftValue: leftKeys,\r\n rightValue: rightKeys,\r\n };\r\n }\r\n\r\n for (const key of leftKeys) {\r\n const difference = MasterDetailChangeService.findFirstDifference(\r\n (leftValue as Record<string, unknown>)[key],\r\n (rightValue as Record<string, unknown>)[key],\r\n `${path}.${key}`,\r\n );\r\n\r\n if (difference) {\r\n return difference;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n return Object.is(leftValue, rightValue)\r\n ? null\r\n : { path, leftValue, rightValue };\r\n }\r\n\r\n /**\r\n * Version simplificada para formularios: recibe `getRawValue()` directamente\r\n * y compara por claves sin requerir mapeo manual en el consumidor.\r\n */\r\n createSimpleFormTracker<\r\n TBaseMaster extends object,\r\n TBaseDetail extends object,\r\n >(\r\n initialState: MasterDetailState<TBaseMaster, TBaseDetail>,\r\n options?: MasterDetailSimpleFormOptions<TBaseMaster, TBaseDetail>,\r\n ): MasterDetailSimpleFormTracker<TBaseMaster, TBaseDetail> {\r\n const defaultMasterKeys = Object.keys(initialState.master) as Array<\r\n keyof TBaseMaster\r\n >;\r\n const defaultDetailKeys =\r\n initialState.detail.length > 0\r\n ? (Object.keys(initialState.detail[0]) as Array<keyof TBaseDetail>)\r\n : ([] as Array<keyof TBaseDetail>);\r\n\r\n const masterKeys = options?.masterKeys ?? defaultMasterKeys;\r\n const detailKeys = options?.detailKeys ?? defaultDetailKeys;\r\n const useBaseValueForNullish = options?.useBaseValueForNullish ?? true;\r\n\r\n let initialMaster = structuredClone(initialState.master);\r\n let initialDetail = structuredClone(initialState.detail);\r\n\r\n const buildComparisonPayload = (\r\n currentState: MasterDetailState<\r\n MasterDetailRawEntity<TBaseMaster>,\r\n MasterDetailRawEntity<TBaseDetail>\r\n >,\r\n ) => {\r\n const normalizedBaseMaster = normalizeBaseEntity(\r\n initialMaster,\r\n masterKeys,\r\n );\r\n const normalizedCurrentMaster = normalizeRawEntityAgainstBase(\r\n initialMaster,\r\n currentState.master,\r\n masterKeys,\r\n useBaseValueForNullish,\r\n );\r\n\r\n const normalizedBaseDetail = initialDetail.map((item) =>\r\n normalizeBaseEntity(item, detailKeys),\r\n );\r\n\r\n const normalizedCurrentDetail = currentState.detail.map((item, index) =>\r\n normalizeRawEntityAgainstBase(\r\n initialDetail[index] ?? ({} as TBaseDetail),\r\n item,\r\n detailKeys,\r\n useBaseValueForNullish,\r\n ),\r\n );\r\n\r\n return {\r\n normalizedBaseMaster,\r\n normalizedCurrentMaster,\r\n normalizedBaseDetail,\r\n normalizedCurrentDetail,\r\n };\r\n };\r\n\r\n const resolveChanges = (\r\n currentState: MasterDetailState<\r\n MasterDetailRawEntity<TBaseMaster>,\r\n MasterDetailRawEntity<TBaseDetail>\r\n >,\r\n ): MasterDetailChangeResult => {\r\n const {\r\n normalizedBaseMaster,\r\n normalizedCurrentMaster,\r\n normalizedBaseDetail,\r\n normalizedCurrentDetail,\r\n } = buildComparisonPayload(currentState);\r\n\r\n const masterDifference = MasterDetailChangeService.findFirstDifference(\r\n normalizedBaseMaster,\r\n normalizedCurrentMaster,\r\n 'master',\r\n );\r\n\r\n const detailDifference = MasterDetailChangeService.findFirstDifference(\r\n normalizedBaseDetail,\r\n normalizedCurrentDetail,\r\n 'detail',\r\n );\r\n\r\n return {\r\n hasChanges: masterDifference !== null || detailDifference !== null,\r\n masterChanged: masterDifference !== null,\r\n detailChanged: detailDifference !== null,\r\n firstDifference: masterDifference\r\n ? {\r\n scope: 'master',\r\n path: masterDifference.path,\r\n baseValue: masterDifference.leftValue,\r\n currentValue: masterDifference.rightValue,\r\n }\r\n : detailDifference\r\n ? {\r\n scope: 'detail',\r\n path: detailDifference.path,\r\n baseValue: detailDifference.leftValue,\r\n currentValue: detailDifference.rightValue,\r\n }\r\n : null,\r\n };\r\n };\r\n\r\n return {\r\n hasChanges: (currentState) => resolveChanges(currentState).hasChanges,\r\n getChanges: (currentState) => resolveChanges(currentState),\r\n\r\n reset: (state: MasterDetailState<TBaseMaster, TBaseDetail>) => {\r\n initialMaster = structuredClone(state.master);\r\n initialDetail = structuredClone(state.detail);\r\n },\r\n };\r\n }\r\n}\r\n","import { HttpHeaders, HttpResponse } from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport {\r\n AbstractControl,\r\n FormBuilder,\r\n FormControl,\r\n FormGroup,\r\n ValidatorFn,\r\n} from '@angular/forms';\r\nimport { Router } from '@angular/router';\r\nimport moment from 'moment-timezone';\r\nimport {\r\n auditTime,\r\n debounceTime,\r\n distinctUntilChanged,\r\n merge,\r\n Observable,\r\n Subject,\r\n takeUntil,\r\n} from 'rxjs';\r\nimport {\r\n ENVIRONMENT,\r\n EnvironmentConfig,\r\n} from '../../injections/environment.token';\r\nimport { ResponseHttpModel, ServiceResult } from '../../models';\r\nimport {\r\n FechasConversion,\r\n FilterOption,\r\n TipoFechaConversion,\r\n} from '../../models/src/extensions.model';\r\nimport {\r\n FieldConfig,\r\n FormRule,\r\n ReactiveForm,\r\n TypedForm,\r\n} from '../../models/src/field-config.model';\r\nimport { AlertaService } from './alerta.service';\r\n\r\ninterface CreateTypedFormOptions {\r\n /**\r\n * Si es true, deshabilita por defecto los controles que no tengan\r\n * la propiedad \"disabled\" explícitamente definida en su configuración.\r\n */\r\n disableUnassignedControls?: boolean;\r\n}\r\n\r\ntype DateInput = string | Date | null | undefined;\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class UtilityAddService {\r\n private _serviceAlerta = inject(AlertaService);\r\n private environment: EnvironmentConfig = inject(ENVIRONMENT);\r\n private _router = inject(Router);\r\n\r\n /**\r\n * Convierte una fecha a una cadena de texto formateada según la zona horaria especificada.\r\n *\r\n * @param {string | Date} fecha - La fecha que se desea convertir. Puede ser una cadena de texto o un objeto Date.\r\n * @returns {string | null} - La fecha formateada en la zona horaria especificada o null si la fecha es null.\r\n */\r\n convertirFechaSegunZonaHoraria(fecha: DateInput): string | null {\r\n if (!fecha) return null; // Comprobamos si la fecha es null o undefined\r\n // Cambia esto a la zona horaria que desees\r\n const zonaHoraria = 'America/Guatemala';\r\n return moment(fecha).tz(zonaHoraria).format();\r\n }\r\n\r\n /**\r\n * Convierte una fecha a un objeto Date en formato ISO, opcionalmente ajustando la hora al inicio del día.\r\n *\r\n * @param {string | Date} fecha - La fecha que se desea convertir. Puede ser una cadena de texto o un objeto Date.\r\n * @param {boolean} initHour - Si es true, la hora se ajusta al inicio del día (00:00:00).\r\n * @returns {Date | null} - La fecha convertida en formato Date o null si la fecha es null.\r\n */\r\n convertirFechaISOString(\r\n fecha: DateInput,\r\n initHour: boolean = false,\r\n ): Date | null {\r\n if (!fecha) return null; // Comprobamos si la fecha es null o undefined\r\n // Validar si la fecha es válida\r\n let fechaMoment = moment(fecha);\r\n if (initHour) {\r\n fechaMoment.startOf('days');\r\n }\r\n return fechaMoment.toDate();\r\n }\r\n\r\n /**\r\n * Convierte una fecha a una cadena en formato ISO 8601.\r\n *\r\n * @param {string | Date} fecha - La fecha a convertir. Puede ser un string o un objeto Date.\r\n * @param {boolean} initHour - Si es true, ajusta la hora al inicio del día (00:00:00).\r\n * @returns {string | null} - La fecha en formato ISO 8601 (ejemplo: '2025-09-05T00:00:00.000Z') o null si la fecha es inválida.\r\n *\r\n * @example\r\n * // Fecha como string\r\n * service.convertirFechaISO8601('2025-09-05'); // '2025-09-05T00:00:00.000Z'\r\n * // Fecha como Date y ajustando al inicio del día\r\n * service.convertirFechaISO8601(new Date(), true); // '2025-09-05T00:00:00.000Z'\r\n */\r\n convertirFechaISO8601(\r\n fecha: DateInput,\r\n initHour: boolean = false,\r\n ): string | null {\r\n if (!fecha) return null; // Comprobamos si la fecha es null o undefined\r\n // Validar si la fecha es válida\r\n let fechaMoment = moment(fecha);\r\n if (initHour) {\r\n fechaMoment.startOf('days');\r\n }\r\n return fechaMoment.toISOString();\r\n }\r\n\r\n /**\r\n * Convierte una fecha a una cadena de texto en formato corto (YYYY-MM-DD).\r\n *\r\n * @param {string | Date} fecha - La fecha que se desea convertir. Puede ser una cadena de texto o un objeto Date.\r\n * @param {boolean} initHour - Si es true, la hora se ajusta al inicio del día (00:00:00).\r\n * @returns {string | null} - La fecha formateada en formato corto (YYYY-MM-DD) o null si la fecha es null.\r\n */\r\n convertirFechaShort(\r\n fecha: DateInput,\r\n initHour: boolean = false,\r\n ): string | null {\r\n if (!fecha) return null; // Comprobamos si la fecha es null o undefined\r\n // Validar si la fecha es válida\r\n const fechaMoment = moment(fecha).format('YYYY-MM-DD');\r\n return fechaMoment;\r\n }\r\n\r\n /**\r\n * Convierte una fecha a una cadena de texto que representa solo la hora (HH:mm).\r\n *\r\n * @param {string | Date} fecha - La fecha que se desea convertir. Puede ser una cadena de texto o un objeto Date.\r\n * @returns {string | null} - La hora formateada (HH:mm) o null si la fecha es null.\r\n */\r\n convertirFechaTime(fecha: DateInput): string | null {\r\n if (!fecha) return null; // Comprobamos si la fecha es null o undefined\r\n const fechaMoment = moment(fecha).format('HH:mm');\r\n return fechaMoment;\r\n }\r\n\r\n /**\r\n * Convierte una fecha a una cadena de texto en formato timestamp (YYYYMMDD).\r\n *\r\n * @param {string | Date} fecha - La fecha que se desea convertir. Puede ser una cadena de texto o un objeto Date.\r\n * @returns {string | null} - La fecha formateada en formato timestamp (YYYYMMDD) o null si la fecha es null.\r\n */\r\n convertirTimeStampString(fecha: DateInput): string | null {\r\n if (!fecha) return null; // Comprobamos si la fecha es null o undefined\r\n const fechaMoment = moment(fecha).format('YYYYMMDD');\r\n return fechaMoment;\r\n }\r\n\r\n /* OPCIONES PARA FOMULARIOS REACTIVOS */\r\n /**\r\n * Crea un FormGroup tipado a partir de una configuración de campos.\r\n *\r\n * @param {FormBuilder} fb - Instancia de FormBuilder para crear el FormGroup.\r\n * @param {FieldConfig<T>} config - Configuración de los campos del formulario.\r\n * @param {ValidatorFn[]} groupValidators - Validadores adicionales a nivel de grupo.\r\n * @param {CreateTypedFormOptions} options - Opciones de creación del formulario.\r\n * - disableUnassignedControls: Si es true, deshabilita solo los campos que no\r\n * tienen \"disabled\" definido, respetando los valores explícitos del usuario.\r\n * @returns {FormGroup} - El FormGroup creado.\r\n *\r\n * @example\r\n * const form = this.utilityAddService.createTypedForm(\r\n * this.fb,\r\n * {\r\n * codigo: { value: 'A1' }, // Se deshabilita por opción global\r\n * nombre: { value: 'Demo', disabled: false }, // Se respeta explícitamente\r\n * },\r\n * { disableUnassignedControls: true },\r\n * );\r\n */\r\n createTypedForm<T>(\r\n fb: FormBuilder,\r\n config: FieldConfig<T>,\r\n options?: CreateTypedFormOptions,\r\n ): FormGroup;\r\n createTypedForm<T>(\r\n fb: FormBuilder,\r\n config: FieldConfig<T>,\r\n groupValidators?: ValidatorFn[],\r\n options?: CreateTypedFormOptions,\r\n ): FormGroup;\r\n createTypedForm<T>(\r\n fb: FormBuilder,\r\n config: FieldConfig<T>,\r\n groupValidatorsOrOptions?: ValidatorFn[] | CreateTypedFormOptions,\r\n options: CreateTypedFormOptions = { disableUnassignedControls: false },\r\n ): FormGroup {\r\n const groupValidators = Array.isArray(groupValidatorsOrOptions)\r\n ? groupValidatorsOrOptions\r\n : undefined;\r\n const resolvedOptions = Array.isArray(groupValidatorsOrOptions)\r\n ? options\r\n : (groupValidatorsOrOptions ?? options);\r\n\r\n const formGroup: { [key in keyof T]?: FormControl } = {};\r\n\r\n // Crear controles de formulario individuales\r\n for (const key in config) {\r\n if (Object.prototype.hasOwnProperty.call(config, key)) {\r\n const fieldConfig = config[key];\r\n const { value, validators = [] } = fieldConfig;\r\n const hasAssignedDisabled = Object.prototype.hasOwnProperty.call(\r\n fieldConfig,\r\n 'disabled',\r\n );\r\n const disabled = hasAssignedDisabled\r\n ? Boolean(fieldConfig.disabled)\r\n : Boolean(resolvedOptions.disableUnassignedControls);\r\n\r\n formGroup[key] = new FormControl({ value, disabled }, validators);\r\n }\r\n }\r\n\r\n // Crear el FormGroup con validadores adicionales a nivel de grupo si existen\r\n const group = fb.group(\r\n formGroup,\r\n groupValidators ? { validators: groupValidators } : {},\r\n );\r\n\r\n return group;\r\n }\r\n\r\n /**\r\n * Crea un ReactiveForm tipado con capacidad de suscripción y limpieza.\r\n *\r\n * Extiende createTypedForm() agregando un Subject (destroy$) para manejar\r\n * la suscripción y limpieza automática de observables cuando el componente\r\n * se destruye.\r\n *\r\n * @template T - El tipo genérico del modelo para el formulario.\r\n * @param fb - Instancia de FormBuilder.\r\n * @param config - Configuración de los campos del formulario (FieldConfig<T>).\r\n * @param groupValidators - Validadores adicionales a nivel de grupo.\r\n * @param options - Opciones de creación del formulario.\r\n * - disableUnassignedControls: Si es true, deshabilita solo los campos que no\r\n * tienen \"disabled\" definido, respetando los valores explícitos del usuario.\r\n * @returns ReactiveForm<T> - FormGroup tipado con Subject destroy$ para limpieza.\r\n *\r\n * @example\r\n * ```typescript\r\n * interface LoginForm {\r\n * username: string;\r\n * password: string;\r\n * }\r\n *\r\n * const config: FieldConfig<LoginForm> = {\r\n * username: { value: '', validators: [Validators.required] },\r\n * password: { value: '', validators: [Validators.required] }\r\n * };\r\n *\r\n * const form = this.utilityAddService.createReactiveForm(\r\n * this.fb,\r\n * config,\r\n * [this.matchPasswordsValidator],\r\n * { disableUnassignedControls: true },\r\n * );\r\n *\r\n * // Al destruir el componente, limpiar todas las suscripciones\r\n * ngOnDestroy() {\r\n * form.destroy$.next();\r\n * form.destroy$.complete();\r\n * }\r\n * ```\r\n */\r\n createReactiveForm<T>(\r\n fb: FormBuilder,\r\n config: FieldConfig<T>,\r\n options?: CreateTypedFormOptions,\r\n ): ReactiveForm<T>;\r\n createReactiveForm<T>(\r\n fb: FormBuilder,\r\n config: FieldConfig<T>,\r\n groupValidators?: ValidatorFn[],\r\n options?: CreateTypedFormOptions,\r\n ): ReactiveForm<T>;\r\n createReactiveForm<T>(\r\n fb: FormBuilder,\r\n config: FieldConfig<T>,\r\n groupValidatorsOrOptions?: ValidatorFn[] | CreateTypedFormOptions,\r\n options: CreateTypedFormOptions = { disableUnassignedControls: false },\r\n ): ReactiveForm<T> {\r\n const groupValidators = Array.isArray(groupValidatorsOrOptions)\r\n ? groupValidatorsOrOptions\r\n : undefined;\r\n const resolvedOptions = Array.isArray(groupValidatorsOrOptions)\r\n ? options\r\n : (groupValidatorsOrOptions ?? options);\r\n\r\n const form = this.createTypedForm(\r\n fb,\r\n config,\r\n groupValidators,\r\n resolvedOptions,\r\n ) as TypedForm<T> & {\r\n destroy$: Subject<void>;\r\n };\r\n\r\n form.destroy$ = new Subject<void>();\r\n\r\n return form;\r\n }\r\n\r\n /**\r\n * Suscribe a los cambios de un control específico del formulario.\r\n *\r\n * Monitorea el control especificado y ejecuta un callback cada vez que su valor\r\n * cambia. Soporta debouncing y deduplicación automática de valores idénticos.\r\n *\r\n * @template T - El tipo del formulario.\r\n * @template K - La clave del control a monitorear.\r\n * @param form - El ReactiveForm a monitorear.\r\n * @param controlName - Nombre del control a observar.\r\n * @param callback - Función a ejecutar cuando cambia el valor. Recibe el nuevo valor y el formulario.\r\n * @param options - Opciones de configuración:\r\n * - debounce?: Milisegundos de espera antes de ejecutar el callback (default: sin debounce).\r\n * - distinct?: Si es true (default), solo ejecuta si el valor cambió (comparación por referencia).\r\n *\r\n * @example\r\n * ```typescript\r\n * this.utilityAddService.onControlChange(\r\n * form,\r\n * 'email',\r\n * (value, form) => {\r\n * console.log('Email cambió a:', value);\r\n * },\r\n * { debounce: 500, distinct: true }\r\n * );\r\n * ```\r\n */\r\n onControlChange<T, K extends keyof T>(\r\n form: ReactiveForm<T>,\r\n controlName: K,\r\n callback: (value: T[K] | null, form: ReactiveForm<T>) => void,\r\n options?: {\r\n debounce?: number;\r\n distinct?: boolean;\r\n },\r\n ) {\r\n let stream = form.get(controlName as string)!.valueChanges;\r\n\r\n if (options?.distinct !== false) {\r\n stream = stream.pipe(distinctUntilChanged());\r\n }\r\n\r\n if (options?.debounce) {\r\n stream = stream.pipe(debounceTime(options.debounce));\r\n }\r\n\r\n stream\r\n .pipe(takeUntil(form.destroy$))\r\n .subscribe((value) => callback(value as T[K], form));\r\n }\r\n\r\n /**\r\n * Suscribe a los cambios de múltiples controles del formulario.\r\n *\r\n * Monitorea una lista de controles y ejecuta un callback cuando cualquiera\r\n * de ellos cambia. Útil para reacciones complejas que dependen de varios campos.\r\n * Soporta operaciones asincrónicas en el callback.\r\n *\r\n * @template T - El tipo del formulario.\r\n * @param form - El ReactiveForm a monitorear.\r\n * @param controls - Array de nombres de controles a observar.\r\n * @param callback - Función a ejecutar cuando cambia cualquier control. Puede ser asincrónica.\r\n * @param options - Opciones de configuración:\r\n * - debounce?: Milisegundos de espera antes de ejecutar el callback.\r\n *\r\n * @example\r\n * ```typescript\r\n * this.utilityAddService.onControlsChange(\r\n * form,\r\n * ['startDate', 'endDate'],\r\n * async (form) => {\r\n * const startDate = form.get('startDate')?.value;\r\n * const endDate = form.get('endDate')?.value;\r\n * // Validar rango de fechas\r\n * await this.validateDateRange(startDate, endDate);\r\n * },\r\n * { debounce: 300 }\r\n * );\r\n * ```\r\n */\r\n onControlsChange<T>(\r\n form: ReactiveForm<T>,\r\n controls: (keyof T)[],\r\n callback: (form: ReactiveForm<T>) => void | Promise<void>,\r\n options?: { debounce?: number },\r\n ) {\r\n const observables = controls.map(\r\n (control) => form.get(control as string)!.valueChanges,\r\n );\r\n\r\n let stream = merge(...observables);\r\n\r\n if (options?.debounce) {\r\n stream = stream.pipe(debounceTime(options.debounce));\r\n }\r\n\r\n stream = stream.pipe(auditTime(0));\r\n\r\n stream.pipe(takeUntil(form.destroy$)).subscribe(() => callback(form));\r\n }\r\n\r\n /**\r\n * Registra reglas de validación personalizadas que se evalúan dinámicamente.\r\n *\r\n * Permite definir reglas complejas que se ejecutan cuando sus dependencias cambian.\r\n * Cada regla puede depender de múltiples campos y ejecutar lógica asincrónica\r\n * para actualizar otros campos del formulario.\r\n *\r\n * @template T - El tipo del formulario.\r\n * @param form - El ReactiveForm donde se aplicarán las reglas.\r\n * @param rules - Array de FormRule<T> que especifican:\r\n * - dependsOn: Campos que disparan la regla cuando cambian.\r\n * - compute: Función que actualiza el formulario en base a los cambios.\r\n * - debounce?: Milisegundos de espera opcional.\r\n *\r\n * @example\r\n * ```typescript\r\n * const rules: FormRule<MyForm>[] = [\r\n * {\r\n * dependsOn: ['country'],\r\n * debounce: 300,\r\n * compute: async (form) => {\r\n * const country = form.get('country')?.value;\r\n * const states = await this.getStatesByCountry(country);\r\n * form.get('state')?.setValue(states[0]);\r\n * }\r\n * }\r\n * ];\r\n *\r\n * this.utilityAddService.registerRules(form, rules);\r\n * ```\r\n */\r\n registerRules<T>(form: ReactiveForm<T>, rules: FormRule<T>[]) {\r\n const runningRules = new Set<FormRule<T>>();\r\n\r\n rules.forEach((rule) => {\r\n this.onControlsChange(\r\n form,\r\n rule.dependsOn,\r\n async (form) => {\r\n if (runningRules.has(rule)) return;\r\n\r\n try {\r\n runningRules.add(rule);\r\n await rule.compute(form);\r\n } finally {\r\n runningRules.delete(rule);\r\n }\r\n },\r\n { debounce: rule.debounce },\r\n );\r\n });\r\n }\r\n\r\n /**\r\n * Sanitiza un formulario obteniendo valores de un formulario, aplicando conversiones de fecha según los campos especificados.\r\n *\r\n * @template T - El tipo genérico del modelo a procesar.\r\n * @param form - El formulario reactivo de Angular del que se obtendrán los valores.\r\n * @param campos - Uno o más objetos que especifican los campos de fecha y el tipo de conversión a aplicar. Cada objeto debe contener:\r\n * - `nombre`: El nombre del campo de fecha en el modelo.\r\n * - `tipo`: El tipo de conversión que se debe aplicar (por ejemplo, `'short'`, `'zh'`, `'iso').\r\n * @returns Un objeto del tipo `T` con los datos procesados y las conversiones de fecha aplicadas.\r\n * @throws Error - Si el campo de fecha especificado no existe en los datos del formulario.\r\n *\r\n * @example\r\n * // Procesar varios campos de fecha\r\n * const precioValues = service.sanitizarModelo<ItemPrecioModel>(\r\n * form,\r\n * { nombre: 'fechaInicio', tipo: 'short' },\r\n * { nombre: 'fechaFin', tipo: 'zh' }\r\n * );\r\n */\r\n sanitizarForm<T>(form: any, ...campos: FechasConversion[]): T {\r\n // Obtén todos los valores del formulario\r\n const rawData = form.getRawValue();\r\n\r\n if (!rawData) {\r\n throw new Error('El formulario no tiene valores.');\r\n }\r\n\r\n // Procesa los valores sin envolver en un arreglo\r\n const updatedValue = { ...rawData };\r\n\r\n // Itera sobre los campos de fecha especificados para realizar las conversiones\r\n campos.forEach(({ nombre, tipo }) => {\r\n if (!(nombre in updatedValue)) {\r\n throw new Error(`El campo \"${nombre}\" no existe en el valor.`);\r\n }\r\n updatedValue[nombre] = updatedValue[nombre]\r\n ? this.convertirFecha(updatedValue[nombre], tipo)\r\n : null;\r\n });\r\n\r\n return updatedValue as T;\r\n }\r\n\r\n /**\r\n * Sanitiza un objeto plano, aplicando conversiones de fecha según los campos especificados.\r\n *\r\n * @template T - El tipo genérico del objeto a procesar.\r\n * @param values - El objeto con los datos.\r\n * @param campos - Uno o más objetos que especifican los campos de fecha y el tipo de conversión a aplicar.\r\n * @returns Un objeto del tipo T con las conversiones de fecha aplicadas.\r\n */\r\n sanitizarModel<T extends Record<string, any>>(\r\n values: T,\r\n ...campos: FechasConversion[]\r\n ): T {\r\n // Crear una copia del objeto para no modificar el original\r\n const updatedValue: Record<string, any> = { ...values };\r\n\r\n campos.forEach(({ nombre, tipo }) => {\r\n if (!(nombre in updatedValue)) {\r\n throw new Error(`El campo \"${nombre}\" no existe en el objeto.`);\r\n }\r\n\r\n const valorActual = updatedValue[nombre];\r\n\r\n if (\r\n valorActual !== null &&\r\n valorActual !== undefined &&\r\n valorActual !== ''\r\n ) {\r\n updatedValue[nombre] = this.convertirFecha(valorActual, tipo);\r\n } else {\r\n updatedValue[nombre] = null;\r\n }\r\n });\r\n\r\n return updatedValue as T;\r\n }\r\n\r\n /**\r\n * Convierte una fecha al formato especificado.\r\n *\r\n * @param fecha - La fecha en formato string que se desea convertir.\r\n * Debe estar en un formato reconocible por `Date` o en ISO 8601.\r\n * @param tipo - El tipo de conversión a realizar. Soporta:\r\n * - `'short'`: Devuelve la fecha en formato corto (YYYY-MM-DD).\r\n * - `'zh'`: Devuelve la fecha ajustada a la zona horaria configurada.\r\n * - `'iso'`: Devuelve la fecha como objeto Date en formato ISO.\r\n * - `'iso8601'`: Devuelve la fecha como string en formato ISO 8601.\r\n * @returns La fecha convertida como string o Date según el tipo especificado, o null si la fecha es inválida.\r\n * @throws Error - Si el tipo de conversión no es válido o soportado.\r\n *\r\n * @example\r\n * // Formato corto\r\n * service.convertirFecha('2025-08-21', 'short'); // '2025-08-21'\r\n * // Zona horaria\r\n * service.convertirFecha('2025-08-21', 'zh'); // '2025-08-21T00:00:00-06:00' (ejemplo)\r\n * // Formato ISO (Date)\r\n * service.convertirFecha('2025-08-21', 'iso'); // Date { ... }\r\n * // Formato ISO 8601 (string)\r\n * service.convertirFecha('2025-08-21', 'iso8601'); // '2025-08-21T00:00:00.000Z'\r\n */\r\n private convertirFecha(\r\n fecha: DateInput,\r\n tipo: TipoFechaConversion,\r\n ): Date | string | null {\r\n switch (tipo) {\r\n case 'short':\r\n // Implementación para el formato corto\r\n return this.convertirFechaShort(fecha);\r\n case 'zh':\r\n // Implementación para zonas horarias\r\n return this.convertirFechaSegunZonaHoraria(fecha);\r\n case 'iso': {\r\n return this.convertirFechaISOString(fecha);\r\n }\r\n case 'iso8601': {\r\n return this.convertirFechaISO8601(fecha);\r\n }\r\n default:\r\n throw new Error(`Tipo de conversión desconocido: ${tipo}`);\r\n }\r\n }\r\n\r\n /**\r\n * Maneja la respuesta de un archivo descargable\r\n * @param fileObservable Observable que emite el Blob del archivo\r\n * @param actionId 0 para abrir en nueva ventana, 1 para descargar\r\n * @param fileName Nombre del archivo sin extensión\r\n */\r\n handleFileResponse(\r\n fileObservable: Observable<Blob>,\r\n actionId: number = 0,\r\n fileName: string,\r\n ): void {\r\n fileObservable.subscribe({\r\n next: (fileBlob: Blob) => {\r\n const fileUrl = URL.createObjectURL(fileBlob);\r\n const fileExtension = this.getFileExtension(fileBlob.type);\r\n\r\n if (this.isExcelFile(fileBlob.type)) {\r\n this.forceDownload(fileUrl, fileName + fileExtension);\r\n } else {\r\n this.handleNonExcelFiles(fileUrl, actionId, fileName, fileExtension);\r\n }\r\n\r\n this.revokeObjectUrl(fileUrl);\r\n },\r\n error: (err) => console.error('Error al manejar el archivo:', err),\r\n });\r\n }\r\n\r\n /**\r\n * Maneja la respuesta de un archivo descargable cuando se necesita\r\n * obtener el nombre de archivo desde los headers HTTP (Content-Disposition).\r\n *\r\n * @param fileObservable Observable que emite HttpResponse<Blob>\r\n * @param actionId 0 para abrir en nueva ventana, 1 para descargar\r\n * @param fallbackFileName Nombre de archivo por defecto si no viene en el header\r\n */\r\n handleFileResponseFromResponse(\r\n fileObservable: Observable<HttpResponse<Blob>>,\r\n actionId: number = 0,\r\n fallbackFileName: string = 'archivo sin nombre',\r\n ): void {\r\n fileObservable.subscribe({\r\n next: (response) => {\r\n const fileBlob = response.body as Blob;\r\n\r\n if (!fileBlob) {\r\n console.error('La respuesta no contiene cuerpo (Blob)');\r\n return;\r\n }\r\n\r\n const headerFileName = this.getFileNameFromContentDisposition(\r\n response.headers,\r\n );\r\n const baseFileName = headerFileName || fallbackFileName;\r\n\r\n const fileUrl = URL.createObjectURL(fileBlob);\r\n const fileExtension = this.getFileExtension(fileBlob.type);\r\n\r\n this.logIfNotProduction(\r\n 'Manejando archivo con tipo:',\r\n fileBlob,\r\n fileBlob.type,\r\n 'nombre:',\r\n baseFileName,\r\n );\r\n\r\n if (this.isExcelFile(fileBlob.type)) {\r\n this.forceDownload(fileUrl, baseFileName + fileExtension);\r\n } else {\r\n this.handleNonExcelFiles(\r\n fileUrl,\r\n actionId,\r\n baseFileName,\r\n fileExtension,\r\n );\r\n }\r\n\r\n this.revokeObjectUrl(fileUrl);\r\n },\r\n error: (err) => console.error('Error al manejar el archivo:', err),\r\n });\r\n }\r\n\r\n /**\r\n * Extrae el blob y el nombre del archivo desde una respuesta HTTP sin realizar la descarga.\r\n * Es útil cuando necesitas reutilizar el blob para múltiples operaciones.\r\n *\r\n * @param fileObservable Observable que emite HttpResponse<Blob>\r\n * @param fallbackFileName Nombre de archivo por defecto si no viene en el header\r\n * @returns Observable que emite un objeto con { blob, fileName }\r\n *\r\n * @example\r\n * this.utilityAddService.extractFileDataFromResponse(this.fileService.getFile())\r\n * .subscribe(({ blob, fileName }) => {\r\n * // Usar blob y fileName para múltiples operaciones\r\n * this.utilityAddService.descargarManual(blob, fileName);\r\n * });\r\n */\r\n extractFileDataFromResponse(\r\n fileObservable: Observable<HttpResponse<Blob>>,\r\n fallbackFileName: string = 'archivo sin nombre',\r\n ): Observable<{ blob: Blob; fileName: string }> {\r\n return new Observable((observer) => {\r\n fileObservable.subscribe({\r\n next: (response) => {\r\n const fileBlob = response.body as Blob;\r\n\r\n if (!fileBlob) {\r\n observer.error('La respuesta no contiene cuerpo (Blob)');\r\n return;\r\n }\r\n\r\n const headerFileName = this.getFileNameFromContentDisposition(\r\n response.headers,\r\n );\r\n const baseFileName = headerFileName || fallbackFileName;\r\n const fullFileName = this.ensureFileNameWithExtension(\r\n baseFileName,\r\n fileBlob.type,\r\n );\r\n\r\n this.logIfNotProduction(\r\n 'Extrayendo archivo con tipo:',\r\n fileBlob.type,\r\n 'nombre:',\r\n fullFileName,\r\n );\r\n\r\n observer.next({\r\n blob: fileBlob,\r\n fileName: fullFileName,\r\n });\r\n observer.complete();\r\n },\r\n error: (err) => observer.error(err),\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Descarga un archivo manualmente usando el blob y nombre del archivo proporcionados.\r\n * Es útil como complemento a extractFileDataFromResponse para reutilizar blobs.\r\n *\r\n * @param blob Objeto Blob del archivo a descargar\r\n * @param fileName Nombre completo del archivo incluyendo extensión\r\n *\r\n * @example\r\n * // Opción 1: Usar directamente con un blob\r\n * this.utilityAddService.descargarBlob(blob, 'Reporte.xlsx');\r\n *\r\n * // Opción 2: Combinar con extractFileDataFromResponse\r\n * this.utilityAddService.extractFileDataFromResponse(httpResponse$)\r\n * .subscribe(({ blob, fileName }) => {\r\n * this.utilityAddService.descargarBlob(blob, fileName);\r\n * });\r\n */\r\n descargarBlob(\r\n blob: Blob | null | undefined,\r\n fileName: string | null | undefined,\r\n ): void {\r\n if (!blob) {\r\n console.warn('No se proporcionó un blob válido para descargar.');\r\n return;\r\n }\r\n\r\n const fileUrl = URL.createObjectURL(blob);\r\n const downloadLink = document.createElement('a');\r\n downloadLink.href = fileUrl;\r\n\r\n const baseFileName = fileName?.trim() || 'archivo_descargado';\r\n const fullFileName = this.ensureFileNameWithExtension(\r\n baseFileName,\r\n blob.type,\r\n );\r\n\r\n downloadLink.download = fullFileName;\r\n downloadLink.click();\r\n this.revokeObjectUrl(fileUrl);\r\n }\r\n\r\n /**\r\n * Verifica si un archivo es de tipo Excel.\r\n *\r\n * @param fileType - Tipo MIME del archivo a verificar.\r\n * @returns true si es un archivo Excel (.xlsx), false en caso contrario.\r\n * @private\r\n */\r\n private isExcelFile(fileType: string): boolean {\r\n return fileType.includes(\r\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\r\n );\r\n }\r\n\r\n /**\r\n * Extrae el nombre del archivo desde el header Content-Disposition de una respuesta HTTP.\r\n *\r\n * Parsea el header Content-Disposition siguiendo el estándar RFC 5987 para\r\n * extraer el nombre del archivo, incluyendo manejo de caracteres especiales\r\n * y codificaciones UTF-8.\r\n *\r\n * @param headers - Headers HTTP de la respuesta.\r\n * @returns El nombre del archivo o null si no se encuentra.\r\n * @private\r\n *\r\n * @example\r\n * // Header: Content-Disposition: attachment; filename*=UTF-8''Reporte%202025.pdf\r\n * // Retorna: 'Reporte 2025.pdf'\r\n */\r\n private getFileNameFromContentDisposition(\r\n headers: HttpHeaders,\r\n ): string | null {\r\n const contentDisposition = headers.get('content-disposition');\r\n\r\n if (!contentDisposition) return null;\r\n\r\n const matches = /filename\\*?[^;=\\n]*=((['\"]).*?\\2|[^;\\n]*)/i.exec(\r\n contentDisposition,\r\n );\r\n if (!matches || !matches[1]) return null;\r\n\r\n let fileName = matches[1].replace(/['\"]/g, '').trim();\r\n\r\n // Manejar posibles codificaciones tipo RFC5987: filename*=UTF-8''Nombre.pdf\r\n if (fileName.toLowerCase().includes(\"utf-8''\")) {\r\n fileName = decodeURIComponent(fileName.split(\"''\")[1] || '');\r\n }\r\n\r\n return fileName;\r\n }\r\n\r\n /**\r\n * Determina la extensión de archivo basada en su tipo MIME.\r\n *\r\n * @param fileType - Tipo MIME del archivo.\r\n * @returns La extensión correspondiente:\r\n * - '.pdf' para archivos PDF.\r\n * - '.xlsx' para archivos Excel.\r\n * - Otras extensiones conocidas según el MIME.\r\n * - Cadena vacía si no se puede inferir.\r\n * @private\r\n */\r\n private getFileExtension(fileType: string): string {\r\n const normalizedType = fileType.toLowerCase();\r\n\r\n if (normalizedType.includes('pdf')) return '.pdf';\r\n if (normalizedType.includes('spreadsheetml')) return '.xlsx';\r\n if (normalizedType.includes('ms-excel')) return '.xls';\r\n if (normalizedType.includes('csv')) return '.csv';\r\n if (normalizedType.includes('zip')) return '.zip';\r\n if (normalizedType.includes('json')) return '.json';\r\n if (normalizedType.includes('xml')) return '.xml';\r\n if (normalizedType.includes('text/plain')) return '.txt';\r\n if (normalizedType.includes('png')) return '.png';\r\n if (normalizedType.includes('jpeg') || normalizedType.includes('jpg')) {\r\n return '.jpg';\r\n }\r\n\r\n return '';\r\n }\r\n\r\n /**\r\n * Asegura que el nombre del archivo tenga extensión.\r\n * Si ya trae extensión, lo respeta sin modificarlo.\r\n * Si no trae extensión, intenta inferirla desde el tipo MIME.\r\n *\r\n * @param fileName - Nombre del archivo, con o sin extensión.\r\n * @param fileType - Tipo MIME del archivo.\r\n * @returns Nombre de archivo con extensión cuando es posible.\r\n * @private\r\n */\r\n private ensureFileNameWithExtension(\r\n fileName: string,\r\n fileType: string,\r\n ): string {\r\n const hasExtension = /\\.[^./\\\\]+$/.test(fileName);\r\n if (hasExtension) return fileName;\r\n\r\n const fileExtension = this.getFileExtension(fileType);\r\n return fileExtension ? `${fileName}${fileExtension}` : fileName;\r\n }\r\n\r\n /**\r\n * Maneja archivos no Excel (como PDFs) realizando acciones de visualización o descarga.\r\n *\r\n * @param fileUrl - URL temporal del objeto Blob del archivo.\r\n * @param actionId - ID de acción:\r\n * - 0: Abre el archivo en una nueva pestaña.\r\n * - 1: Inicia la descarga del archivo.\r\n * @param fileName - Nombre base del archivo sin extensión.\r\n * @param fileExtension - Extensión del archivo incluyendo el punto (ej: '.pdf').\r\n * @private\r\n */\r\n private handleNonExcelFiles(\r\n fileUrl: string,\r\n actionId: number,\r\n fileName: string,\r\n fileExtension: string,\r\n ): void {\r\n switch (actionId) {\r\n case 0: // Abrir en nueva ventana\r\n window.open(fileUrl, '_blank');\r\n break;\r\n case 1: // Descargar archivo\r\n this.forceDownload(fileUrl, fileName + fileExtension);\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * Abre un archivo PDF en una nueva pestaña del navegador.\r\n *\r\n * @param blob - Objeto Blob que contiene los datos del archivo PDF.\r\n *\r\n * @example\r\n * // Uso típico con respuesta de servicio HTTP\r\n * this.pdfService.getPdf(id).subscribe(blob => {\r\n * this.utilityAddService.PdfView(blob);\r\n * });\r\n *\r\n * @description\r\n * Este método crea un URL temporal para el Blob del PDF y lo abre en una nueva\r\n * pestaña del navegador. El URL se revoca automáticamente después de 100ms para\r\n * liberar memoria.\r\n */\r\n PdfView(blob: Blob): any {\r\n // Crear un URL temporal para el Blob\r\n const pdfUrl = URL.createObjectURL(blob);\r\n // Abrir el PDF en una nueva pestaña\r\n window.open(pdfUrl, '_blank');\r\n\r\n // Liberar el URL del Blob una vez que la pestaña ha sido abierta\r\n // Esperar un poco para asegurarse de que el archivo se ha abierto\r\n setTimeout(() => {\r\n window.URL.revokeObjectURL(pdfUrl);\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Descarga un archivo PDF con un nombre personalizado que incluye el prefijo \"DTE_\".\r\n *\r\n * @param blob - Objeto Blob que contiene los datos del archivo PDF a descargar.\r\n * @param filename - Nombre base del archivo sin extensión (se agregará automáticamente \".pdf\" y el prefijo \"DTE_\").\r\n *\r\n * @example\r\n * // Uso típico con respuesta de servicio HTTP\r\n * this.dteService.getDTE(operacionId).subscribe(blob => {\r\n * this.utilityAddService.downloadPdfFile(blob, '12345');\r\n * // Descarga el archivo como: DTE_12345.pdf\r\n * });\r\n *\r\n * @description\r\n * Este método crea un URL temporal para el Blob y simula un clic en un enlace de\r\n * descarga para iniciar la descarga automática del archivo. El nombre del archivo\r\n * sigue el formato: DTE_{filename}.pdf. El URL se revoca después de 100ms para\r\n * liberar memoria.\r\n */\r\n downloadPdfFile(blob: Blob, filename: string) {\r\n // Crear un URL temporal para el Blob\r\n const pdfUrl = URL.createObjectURL(blob);\r\n\r\n // Crear un enlace de descarga\r\n const link = document.createElement('a');\r\n link.href = pdfUrl;\r\n\r\n // Establecer el nombre del archivo utilizando el operacionId\r\n link.download = `DTE_${filename}.pdf`;\r\n\r\n // Simular un clic en el enlace para iniciar la descarga\r\n link.click();\r\n\r\n // Liberar el URL del Blob después de un pequeño retraso\r\n setTimeout(() => {\r\n window.URL.revokeObjectURL(pdfUrl);\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Inicia la descarga programada de un archivo.\r\n *\r\n * Crea un elemento <a> temporal, lo configura con el archivo y tipo MIME,\r\n * y simula un clic para iniciar la descarga del navegador.\r\n *\r\n * @param fileUrl - URL temporal (object URL) del archivo a descargar.\r\n * @param fullFileName - Nombre completo del archivo incluyendo extensión.\r\n * @private\r\n */\r\n private forceDownload(fileUrl: string, fullFileName: string): void {\r\n const downloadLink = document.createElement('a');\r\n downloadLink.href = fileUrl;\r\n downloadLink.download = fullFileName;\r\n downloadLink.click();\r\n }\r\n\r\n /**\r\n * Libera la memoria de un URL de objeto temporal.\r\n *\r\n * Revoca un object URL creado con URL.createObjectURL() después de un pequeño\r\n * retraso (100ms) para asegurar que el navegador ha terminado de usar el archivo.\r\n *\r\n * @param fileUrl - URL del objeto a revocar.\r\n * @private\r\n */\r\n private revokeObjectUrl(fileUrl: string): void {\r\n setTimeout(() => {\r\n window.URL.revokeObjectURL(fileUrl);\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Muestra información en consola solo en desarrollo, permitiendo múltiples argumentos como console.log nativo.\r\n *\r\n * @param args - Argumentos a mostrar en consola (texto, objetos, etc).\r\n * @example\r\n * logIfNotProduction('Datos:', response);\r\n * logIfNotProduction('Error:', error, { extra: true });\r\n */\r\n logIfNotProduction(...args: any[]): void {\r\n if (!this.environment.production) {\r\n console.log(...args);\r\n }\r\n }\r\n\r\n /**\r\n * Valida todos los campos de un formulario y muestra una alerta.\r\n *\r\n * Marca todos los controles como tocados (triggereando la validación visual)\r\n * y muestra una notificación toastr indicando que hay validaciones pendientes.\r\n * Útil para formularios donde deseas mostrar todos los errores de validación\r\n * de una vez.\r\n *\r\n * @param form - El FormGroup a validar.\r\n *\r\n * @example\r\n * ```typescript\r\n * if (this.form.invalid) {\r\n * this.utilityAddService.checkFormValid(this.form);\r\n * return;\r\n * }\r\n * ```\r\n */\r\n checkFormValid(control: AbstractControl | null | undefined): void {\r\n if (!control) return;\r\n\r\n // Marca todos los controles (incluyendo anidados en FormGroup/FormArray)\r\n control.markAllAsTouched();\r\n\r\n // Muestra un mensaje de alerta\r\n this._serviceAlerta.toastrAlerts(\r\n 3,\r\n 'Formulario',\r\n 'Validaciones pendientes',\r\n 2,\r\n );\r\n }\r\n\r\n /**\r\n * Extrae valores únicos de un campo específico de un array de objetos.\r\n *\r\n * Obtiene todos los valores distintos de una propiedad en un array de objetos,\r\n * retornando un array de objetos FilterOption tipado y ordenado alfabéticamente.\r\n * Incluye validaciones para detectar campos inexistentes con mensajes de alerta.\r\n *\r\n * @template T - Tipo de los objetos en el array.\r\n * @param data - Array de objetos del cual extraer valores únicos.\r\n * @param field - Nombre del campo del cual extraer valores únicos.\r\n * @returns Array de FilterOption ordenado alfabéticamente, o array vacío si hay errores.\r\n *\r\n * @example\r\n * ```typescript\r\n * interface Usuario {\r\n * id: number;\r\n * nombre: string;\r\n * departamento: string;\r\n * }\r\n *\r\n * const usuarios: Usuario[] = [\r\n * { id: 1, nombre: 'Juan', departamento: 'TI' },\r\n * { id: 2, nombre: 'María', departamento: 'RRHH' },\r\n * { id: 3, nombre: 'Pedro', departamento: 'TI' }\r\n * ];\r\n *\r\n * const deptosUnicos = this.utilityAddService.getUniqueValues(usuarios, 'departamento');\r\n * // Retorna: [\r\n * // { value: 'RRHH', field: 'departamento' },\r\n * // { value: 'TI', field: 'departamento' }\r\n * // ]\r\n * ```\r\n */\r\n getUniqueValues<T>(data: T[], field: keyof T): FilterOption[] {\r\n if (!data || data.length === 0) {\r\n console.warn(\r\n 'UtilityAddService.getUniqueValues: El array de datos está vacío. No se puede obtener valores únicos.',\r\n );\r\n return [];\r\n }\r\n\r\n const hasField = data.some((item) =>\r\n Object.prototype.hasOwnProperty.call(item as object, field as string),\r\n );\r\n\r\n if (!hasField) {\r\n const availableFields = Array.from(\r\n new Set(data.flatMap((item) => Object.keys(item as object))),\r\n ).sort();\r\n\r\n console.warn(\r\n `UtilityAddService.getUniqueValues: El campo \"${String(\r\n field,\r\n )}\" no existe en los objetos proporcionados. Campos disponibles: ${availableFields.join(\r\n ', ',\r\n )}`,\r\n );\r\n\r\n return [];\r\n }\r\n\r\n const uniqueValues = data.reduce((acc: FilterOption[], current) => {\r\n const fieldValue = current[field];\r\n\r\n if (\r\n typeof fieldValue === 'string' &&\r\n !acc.some((item) => item.value === fieldValue)\r\n ) {\r\n acc.push({\r\n value: fieldValue,\r\n field: field.toString(),\r\n });\r\n }\r\n return acc;\r\n }, []);\r\n\r\n return uniqueValues.sort((a, b) => a.value.localeCompare(b.value));\r\n }\r\n\r\n /**\r\n * Helper function para parsear fechas para filtro de primeNg en table\r\n * @param date - Fecha en formato string, Date o null/undefined\r\n * @returns Date | null - Objeto Date válido o null\r\n */\r\n parseDate(date: string | Date | null): Date | null {\r\n if (!date) return null;\r\n return typeof date === 'string' ? new Date(date) : date;\r\n }\r\n\r\n /**\r\n * Función pura que procesa una cadena de texto conteniendo números individuales y/o rangos numéricos,\r\n * devolviendo un array con todos los números expandidos.\r\n *\r\n * @param input - Cadena de texto con el formato: número[.número][.inicio-fin][...]\r\n * @returns Array de números con todos los valores individuales y rangos expandidos\r\n *\r\n * @example\r\n * // Uso básico\r\n * const result = parseNumericRanges('1.5.7.10-12');\r\n * // Retorna: [1, 5, 7, 10, 11, 12]\r\n *\r\n * @example\r\n * // Con espacios y caracteres especiales\r\n * const result = parseNumericRanges(' 3. 5-7 .10-12abc');\r\n * // Retorna: [3, 5, 6, 7, 10, 11, 12]\r\n *\r\n * @example\r\n * // Rangos invertidos (serán ignorados)\r\n * const result = parseNumericRanges('10-8');\r\n * // Retorna: [] (array vacío)\r\n *\r\n * @note\r\n * Características especiales:\r\n * - Elimina automáticamente espacios y caracteres no numéricos\r\n * - Los números deben estar separados por puntos (.)\r\n * - Los rangos deben usar guión (-) sin espacios entre números\r\n * - Es tolerante a formatos inconsistentes\r\n * - Omite elementos inválidos sin generar errores\r\n */\r\n parseNumericRanges(input: string): number[] {\r\n const cleanString = input.replace(/[^\\d.\\- ]/g, '').replace(/\\s+/g, '');\r\n\r\n const parts = cleanString.split('.');\r\n const result: number[] = [];\r\n\r\n for (const part of parts) {\r\n if (!part) continue;\r\n\r\n if (part.includes('-')) {\r\n const [startStr, endStr] = part.split('-');\r\n const start = parseInt(startStr, 10);\r\n const end = parseInt(endStr, 10);\r\n\r\n if (!isNaN(start) && !isNaN(end) && start <= end) {\r\n for (let i = start; i <= end; i++) {\r\n result.push(i);\r\n }\r\n }\r\n } else {\r\n const number = parseInt(part, 10);\r\n if (!isNaN(number)) {\r\n result.push(number);\r\n }\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Adaptador para procesar eventos de input y extraer rangos numéricos.\r\n *\r\n * @param event - Objeto Event del DOM, preferiblemente de un elemento input\r\n * @returns\r\n * - Array de números generado a partir del valor del input, cuando hay\r\n * números/rangos.\r\n * - El carácter comodín \"*\" cuando el valor del input es exactamente \"*\".\r\n *\r\n * @example\r\n * // Uso en template Angular\r\n * <input (input)=\"processNumericRangesFromEvent($event)\">\r\n *\r\n * @example\r\n * // Uso directo\r\n * const result = processNumericRangesFromEvent(inputEvent);\r\n *\r\n * @note\r\n * Esta función es un wrapper que:\r\n * - Extrae el valor del input del evento\r\n * - Delega el procesamiento a parseNumericRanges()\r\n * - Mantiene compatibilidad con eventos de diferentes frameworks\r\n *\r\n * @dependencies\r\n * Requiere que el evento tenga la propiedad target.value (standard DOM)\r\n * Para otros tipos de eventos (ej. Angular Material) puede necesitar ajustes\r\n */\r\n processNumericRangesFromEvent(event: Event): number[] | '*' {\r\n const rawValue = (event.target as HTMLInputElement).value ?? '';\r\n const inputValue = rawValue.trim();\r\n\r\n // Si el valor es exactamente el comodín \"*\", lo devolvemos tal cual\r\n // para que el consumidor pueda interpretarlo como \"todos\".\r\n if (inputValue === '*') {\r\n return '*';\r\n }\r\n\r\n // Para mezclas de números y asteriscos, parseNumericRanges elimina\r\n // cualquier carácter no numérico/rango (como \"*\"), dando prioridad\r\n // a los números y omitiendo el comodín.\r\n return this.parseNumericRanges(inputValue);\r\n }\r\n\r\n /**\r\n * Maneja la respuesta estándar de una operación HTTP, mostrando alertas y realizando acciones comunes en formularios.\r\n *\r\n * @param response - Respuesta de la operación (debe tener isSuccess, title, statusMessage).\r\n * @param urlHome - Ruta a la que se navega si la operación es exitosa y el id es mayor a 0.\r\n * @param form - Formulario reactivo a resetear si la operación es exitosa.\r\n * @param getForm - Función para recargar el formulario (por ejemplo, para obtener datos actualizados).\r\n * @param id - Identificador usado para decidir si se navega a urlHome tras éxito.\r\n *\r\n * @example\r\n * // Uso típico en un componente\r\n * this.utilityAddService.handleResponse(\r\n * response,\r\n * '/home',\r\n * this.form,\r\n * () => this.getForm(),\r\n * this.id\r\n * );\r\n *\r\n * @description\r\n * - Si response.isSuccess es true:\r\n * - Muestra alerta tipo toastr.\r\n * - Si id > 0, navega a urlHome.\r\n * - Resetea el formulario y ejecuta getForm().\r\n * - Si response.isSuccess es false:\r\n * - Muestra alerta visual personalizada con icono de error.\r\n */\r\n public handleResponse(\r\n response: ResponseHttpModel,\r\n urlHome: string,\r\n form: FormGroup,\r\n getForm: () => void,\r\n id: number,\r\n ): void {\r\n try {\r\n this.logIfNotProduction('handleResponse - response:', response);\r\n if (response.isSuccess) {\r\n this._serviceAlerta.toastrAlerts(\r\n 1,\r\n response.title,\r\n response.statusMessage,\r\n 2,\r\n );\r\n if (id > 0) {\r\n this._router.navigate([urlHome]);\r\n return;\r\n }\r\n getForm();\r\n form?.reset();\r\n } else {\r\n this._serviceAlerta.alertaHtmlSuccess(\r\n response.title,\r\n response.statusMessage,\r\n {\r\n icono: 'icon2/hard_drive_error.png',\r\n showConfirmButton: true,\r\n },\r\n );\r\n }\r\n } catch (error) {\r\n this.logIfNotProduction('Error en handleResponse:', error);\r\n this._serviceAlerta.toastrAlerts(\r\n 4,\r\n 'Error',\r\n error instanceof Error ? error.message : String(error),\r\n 2,\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Maneja la respuesta estándar de una operación HTTP que devuelve un ServiceResult<T>,\r\n * mostrando alertas y realizando acciones comunes en formularios.\r\n *\r\n * @typeParam T - Tipo de dato contenido en la propiedad data de ServiceResult.\r\n * @param response - Respuesta del servicio (debe tener isSuccess, title, message, etc.).\r\n * @param urlHome - Ruta a la que se navega si la operación es exitosa y el id es mayor a 0.\r\n * @param form - Formulario reactivo a resetear si la operación es exitosa.\r\n * @param getForm - Función para recargar el formulario (por ejemplo, para obtener datos actualizados).\r\n * @param id - Identificador usado para decidir si se navega a urlHome tras éxito.\r\n *\r\n * @example\r\n * // Uso típico en un componente con ServiceResult\r\n * this.utilityAddService.handleResponseService<MiModelo>(\r\n * response,\r\n * '/home',\r\n * this.form,\r\n * () => this.getForm(),\r\n * this.id\r\n * );\r\n *\r\n * @description\r\n * - Si response.isSuccess es true:\r\n * - Muestra alerta tipo toastr.\r\n * - Si id > 0, navega a urlHome.\r\n * - Resetea el formulario y ejecuta getForm().\r\n * - Si response.isSuccess es false:\r\n * - Muestra alerta visual personalizada con icono de error.\r\n */\r\n public handleResponseService<T>(\r\n response: ServiceResult<T>,\r\n urlHome: string,\r\n form: FormGroup,\r\n getForm: () => void,\r\n id: number,\r\n ): void {\r\n try {\r\n this.logIfNotProduction('handleResponse - response:', response);\r\n if (response.isSuccess) {\r\n this._serviceAlerta.toastrAlerts(\r\n 1,\r\n response.title,\r\n response.message,\r\n 2,\r\n );\r\n if (id > 0) {\r\n this._router.navigate([urlHome]);\r\n return;\r\n }\r\n getForm();\r\n form?.reset();\r\n } else {\r\n this._serviceAlerta.alertaHtmlSuccess(\r\n response.title,\r\n response.message,\r\n {\r\n icono: 'icon2/hard_drive_error.png',\r\n showConfirmButton: true,\r\n },\r\n );\r\n }\r\n } catch (error) {\r\n this.logIfNotProduction('Error en handleResponseService:', error);\r\n this._serviceAlerta.toastrAlerts(\r\n 4,\r\n 'Error',\r\n error instanceof Error ? error.message : String(error),\r\n 2,\r\n );\r\n }\r\n }\r\n}\r\n","/**\r\n * Formateador de moneda por defecto para Guatemala.\r\n *\r\n * Usa la configuración regional `es-GT` y el código de moneda `GTQ`.\r\n * Siempre muestra 2 decimales.\r\n *\r\n * Ejemplo de uso:\r\n * ```ts\r\n * GTQFormatter.format(1234.5); // \"Q 1,234.50\"\r\n * ```\r\n */\r\nexport const GTQFormatter = new Intl.NumberFormat('es-GT', {\r\n style: 'currency',\r\n currency: 'GTQ',\r\n minimumFractionDigits: 2,\r\n maximumFractionDigits: 2,\r\n});\r\n\r\n/**\r\n * Crea un formateador de moneda personalizado.\r\n *\r\n * Permite definir la configuración regional (`locale`) y el código de moneda (`currency`)\r\n * manteniendo 2 decimales fijos.\r\n *\r\n * Ejemplos de uso:\r\n * ```ts\r\n * const usdFormatter = createCurrencyFormatter('en-US', 'USD');\r\n * usdFormatter.format(1000); // \"$1,000.00\"\r\n *\r\n * const mxnFormatter = createCurrencyFormatter('es-MX', 'MXN');\r\n * mxnFormatter.format(1500.75); // \"$1,500.75\"\r\n * ```\r\n *\r\n * @param locale Código de configuración regional, por ejemplo: `es-GT`, `en-US`.\r\n * @param currency Código de moneda ISO 4217, por ejemplo: `GTQ`, `USD`, `EUR`.\r\n * @returns Instancia de `Intl.NumberFormat` configurada para moneda.\r\n */\r\nexport function createCurrencyFormatter(\r\n locale: string,\r\n currency: string,\r\n): Intl.NumberFormat {\r\n return new Intl.NumberFormat(locale, {\r\n style: 'currency',\r\n currency,\r\n minimumFractionDigits: 2,\r\n maximumFractionDigits: 2,\r\n });\r\n}\r\n","import {\r\n AbstractControl,\r\n FormGroup,\r\n ValidationErrors,\r\n ValidatorFn,\r\n} from '@angular/forms';\r\n\r\n/**\r\n * Valida que el control contenga un rango de fechas válido (dos fechas no nulas y válidas).\r\n */\r\nexport function dateRangeValidator(\r\n control: AbstractControl,\r\n): ValidationErrors | null {\r\n const dates: Date[] = control.value;\r\n\r\n // Verificar si el valor es un array con exactamente dos elementos\r\n if (Array.isArray(dates) && dates.length === 2) {\r\n const [startDate, endDate] = dates;\r\n\r\n // Verificar que las fechas sean válidas y no nulas\r\n if (\r\n startDate &&\r\n endDate &&\r\n !isNaN(new Date(startDate).getTime()) &&\r\n !isNaN(new Date(endDate).getTime())\r\n ) {\r\n return null; // Válido\r\n } else {\r\n return {\r\n invalidDateRange: {\r\n message: 'Ambas fechas deben ser válidas y no nulas.',\r\n requiredLength: 2,\r\n },\r\n }; // Error si alguna fecha es nula o inválida\r\n }\r\n }\r\n return null; // Si el control no contiene un array válido, no hay error\r\n}\r\n\r\n/**\r\n * Validador a nivel de formulario que verifica que la fecha \"hasta\"\r\n * (toKey) sea mayor o igual que la fecha \"desde\" (fromKey),\r\n * comparando ambas como instancias de Date.\r\n *\r\n * Reglas:\r\n * - Si una o ambas fechas están vacías (null/undefined), no se genera error\r\n * y se delega la obligatoriedad a otros validadores como `required`.\r\n * - Si ambas fechas tienen valor, la fecha \"hasta\" debe ser >= fecha \"desde\"\r\n * según su valor numérico (`getTime()`).\r\n * - Si los valores no son fechas válidas, el comportamiento dependerá\r\n * de cómo los controles entreguen el valor (se recomienda usar Date).\r\n *\r\n * @param fromKey Nombre del control que representa la fecha inicial.\r\n * @param toKey Nombre del control que representa la fecha final.\r\n * @returns Un ValidatorFn que devuelve `null` si el rango es válido o está\r\n * incompleto; y un objeto con la clave `invalidDateRange` si el\r\n * rango es inválido.\r\n */\r\nexport function dateRangeValidatorFromTo(\r\n fromKey: string,\r\n toKey: string,\r\n): ValidatorFn {\r\n return (group: AbstractControl): ValidationErrors | null => {\r\n const fromControl = group.get(fromKey);\r\n const toControl = group.get(toKey);\r\n\r\n const from = fromControl?.value as Date | null;\r\n const to = toControl?.value as Date | null;\r\n\r\n if (!from || !to) return null;\r\n\r\n // Rango válido: limpiar error en el control \"hasta\" si existe\r\n if (to.getTime() >= from.getTime()) {\r\n if (toControl && toControl.errors?.['invalidDateRange']) {\r\n const { invalidDateRange, ...rest } = toControl.errors;\r\n toControl.setErrors(Object.keys(rest).length ? rest : null);\r\n }\r\n return null;\r\n }\r\n\r\n // Rango inválido: asignar error tanto al grupo como al control \"hasta\"\r\n const error: ValidationErrors = {\r\n invalidDateRange: {\r\n message: 'La fecha final debe ser mayor o igual que la fecha inicial.',\r\n requiredLength: 2,\r\n },\r\n };\r\n\r\n if (toControl) {\r\n const currentErrors = toControl.errors || {};\r\n toControl.setErrors({ ...currentErrors, ...error });\r\n }\r\n\r\n return error;\r\n };\r\n}\r\n\r\n/**\r\n * Valida que una fecha única esté dentro de un rango mínimo y máximo.\r\n * Las fechas deben utilizar la función de convertirFechaISOString para asegurar el formato correcto y que funcione con el componente primeNg.\r\n * @param minDate Fecha mínima permitida.\r\n * @param maxDate Fecha máxima permitida.\r\n */\r\nexport function dateMinMaxValidator(minDate: Date, maxDate: Date) {\r\n return (control: AbstractControl): ValidationErrors | null => {\r\n const date: Date = control.value;\r\n\r\n // Verificar si el valor es una fecha válida\r\n if (date && !isNaN(new Date(date).getTime())) {\r\n const currentDate = new Date(date);\r\n\r\n // Validar si la fecha está fuera del rango permitido\r\n if (currentDate < minDate || currentDate > maxDate) {\r\n return {\r\n dateNotRange: {\r\n message: `La fecha debe estar entre ${minDate.toLocaleDateString()} y ${maxDate.toLocaleDateString()}`,\r\n minDate: minDate.toISOString(),\r\n maxDate: maxDate.toISOString(),\r\n },\r\n };\r\n }\r\n\r\n return null; // Fecha válida y dentro del rango\r\n }\r\n\r\n return null;\r\n };\r\n}\r\n\r\n/**\r\n * Valida que al menos uno de los campos especificados esté lleno.\r\n * @param fields Los nombres de los campos a validar.\r\n */\r\nexport function atLeastOneFieldRequiredValidator(fields: string[]) {\r\n return (formGroup: AbstractControl): ValidationErrors | null => {\r\n // Obtener el FormGroup para poder acceder a los controles\r\n const form = formGroup as FormGroup;\r\n\r\n // Verificar si al menos uno de los campos tiene un valor\r\n const isAnyFieldFilled = fields.some((field) => {\r\n const control = form.get(field);\r\n return control?.value !== null && control?.value !== '';\r\n });\r\n\r\n // Si al menos un campo tiene un valor, la validación es exitosa\r\n if (isAnyFieldFilled) {\r\n return null; // Validación pasada\r\n } else {\r\n // Construir el mensaje dinámico con los campos no llenados\r\n const emptyFields = fields.filter((field) => {\r\n const control = form.get(field);\r\n return control?.value === null || control?.value === '';\r\n });\r\n\r\n const fieldNames = emptyFields.join(', ');\r\n const message = `Debe completar al menos uno de los siguientes campos: ${fieldNames}.`;\r\n\r\n // Si ninguno tiene valor, devolver el mensaje con el error\r\n return {\r\n atLeastOneRequired: {\r\n message: message,\r\n },\r\n };\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Validador personalizado para verificar si un NIT (Número de Identificación Tributaria) es válido.\r\n * Este validador se puede usar en formularios reactivos de Angular.\r\n *\r\n * @param control - El control del formulario que contiene el valor del NIT.\r\n * @returns Un objeto de error si el NIT no es válido, o `null` si el NIT es válido.\r\n */\r\nexport function nitValidator(\r\n control: AbstractControl,\r\n): ValidationErrors | null {\r\n const nit = control.value;\r\n\r\n // Si el campo está vacío, no hay error\r\n if (!nit) {\r\n return null;\r\n }\r\n\r\n // Validar el NIT utilizando la función NITCorrecto\r\n const esValido = NITCorrecto(nit);\r\n\r\n // Si el NIT no es válido, retornar un objeto de error con el formato deseado\r\n if (!esValido) {\r\n return {\r\n invalidNIT: {\r\n message: 'El NIT ingresado no es válido.', // Mensaje de error personalizado\r\n requiredLength: nit.length, // Longitud del NIT ingresado (opcional)\r\n },\r\n };\r\n }\r\n\r\n // Si el NIT es válido, retornar null (sin errores)\r\n return null;\r\n}\r\n\r\n/**\r\n * Función auxiliar para validar un NIT según un algoritmo específico.\r\n *\r\n * @param nit - El NIT a validar.\r\n * @returns `true` si el NIT es válido, `false` en caso contrario.\r\n */\r\nfunction NITCorrecto(nit: string): boolean {\r\n try {\r\n const largo = nit.length;\r\n // Invertir el NIT (excepto el último dígito) para facilitar el cálculo\r\n const validar = nit\r\n .substring(0, largo - 1)\r\n .split('')\r\n .reverse()\r\n .join('');\r\n const cadena = validar.split('');\r\n const comparador = nit.substring(largo - 1, largo); // Último dígito del NIT\r\n let posicion = 2; // Factor de ponderación inicial\r\n let sumaValidar = 0; // Acumulador para la suma ponderada\r\n\r\n // Calcular la suma ponderada de los dígitos del NIT\r\n for (const c of cadena) {\r\n sumaValidar += parseInt(c, 10) * posicion;\r\n posicion += 1;\r\n }\r\n\r\n // Calcular el residuo de la operación de validación\r\n const residuo = operacionValidar(11 - operacionValidar(sumaValidar));\r\n\r\n // Validar el NIT según el residuo y el último dígito\r\n if (residuo === 10 && comparador.toUpperCase() === 'K') {\r\n return true; // El NIT es válido si el residuo es 10 y el último dígito es 'K'\r\n } else if (residuo.toString() === comparador) {\r\n return true; // El NIT es válido si el residuo coincide con el último dígito\r\n } else {\r\n return false; // El NIT no es válido\r\n }\r\n } catch (error) {\r\n // Si ocurre un error durante la validación, el NIT no es válido\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Función auxiliar para calcular el residuo de una operación aritmética.\r\n *\r\n * @param valor - El valor sobre el cual se calculará el residuo.\r\n * @returns El residuo de la división del valor entre 11.\r\n */\r\nfunction operacionValidar(valor: number): number {\r\n return valor % 11;\r\n}\r\n\r\n/**\r\n * Validador personalizado para verificar si un CUI (Código Único de Identificación) es válido.\r\n * Este validador se puede usar en formularios reactivos de Angular.\r\n *\r\n * @param control - El control del formulario que contiene el valor del CUI.\r\n * @returns Un objeto de error si el CUI no es válido, o `null` si el CUI es válido.\r\n */\r\nexport function cuiValidator(\r\n control: AbstractControl,\r\n): ValidationErrors | null {\r\n const cui = control.value;\r\n\r\n // Si el campo está vacío, no hay error\r\n if (!cui) {\r\n return null;\r\n }\r\n\r\n // Validar el CUI\r\n const esValido = CUICorrecto(cui);\r\n\r\n // Si el CUI no es válido, retornar un objeto de error\r\n if (!esValido) {\r\n return {\r\n invalidCUI: {\r\n message: 'El CUI ingresado no es válido.',\r\n requiredLength: 13,\r\n actualLength: cui.length,\r\n },\r\n };\r\n }\r\n\r\n // Si el CUI es válido, retornar null (sin errores)\r\n return null;\r\n}\r\n\r\n/**\r\n * Función que implementa el algoritmo de validación del CUI\r\n * @param cui Número de CUI a validar (debe tener 13 dígitos)\r\n * @returns boolean indicando si el CUI es válido\r\n */\r\nfunction CUICorrecto(cui: string | number): boolean {\r\n // Convertir a string si es número\r\n const cuiStr = typeof cui === 'number' ? cui.toString() : cui;\r\n\r\n // Validar longitud y que sean solo dígitos\r\n if (cuiStr.length !== 13 || !/^\\d+$/.test(cuiStr)) {\r\n return false;\r\n }\r\n\r\n try {\r\n const primeros8 = cuiStr.substring(0, 8);\r\n const digitoVerificador = parseInt(cuiStr.substring(8, 9), 10);\r\n let suma = 0;\r\n\r\n // Calcular la suma ponderada\r\n for (let i = 0; i < primeros8.length; i++) {\r\n const digito = parseInt(primeros8[i], 10);\r\n suma += digito * (i + 2); // Los pesos son 2, 3, 4, ..., 9\r\n }\r\n\r\n // Calcular residuo y validar\r\n const residuo = suma % 11;\r\n return residuo === digitoVerificador;\r\n } catch (error) {\r\n console.error('Error validando CUI:', error);\r\n return false;\r\n }\r\n}\r\n","/*\r\n * Public API Surface of ngx-dsx\r\n */\r\nexport * from './lib/components';\r\nexport * from './lib/components/icon-dsx/icon-dsx.component';\r\nexport * from './lib/components/json/json-values-debuj/json-values-debuj.component';\r\nexport * from './lib/components/loading-lottie/loading-lottie.component';\r\nexport * from './lib/components/loading/css-v2/css-v2.component';\r\nexport * from './lib/components/loading/loading.component';\r\nexport * from './lib/components/logo/logo-dsx/logo-dsx.component';\r\nexport * from './lib/components/navbar-dsx/navbar-dsx.component';\r\nexport * from './lib/components/status/network-status/network-status.component';\r\nexport * from './lib/directives/src/arrow-navigation.directive';\r\nexport * from './lib/directives/src/only-rango-pattern.directive';\r\nexport * from './lib/directives/src/select-all-on-focus.directive';\r\nexport * from './lib/injections/cache.token';\r\nexport {\r\n ENVIRONMENT,\r\n provideEnvironment,\r\n SWEET_ALERT_THEMES,\r\n validateEnvironmentConfig,\r\n type EnvironmentConfig,\r\n type SweetAlertThemeType,\r\n} from './lib/injections/environment.token';\r\nexport * from './lib/injections/parameterSecurity';\r\nexport * from './lib/interceptors/http-authorize.interceptor';\r\nexport * from './lib/models';\r\nexport * from './lib/models/src/environment-base';\r\nexport * from './lib/models/src/field-config.model';\r\nexport * from './lib/models/src/parameterSecurity.model';\r\nexport * from './lib/modules/src/dsx-add-tools.module';\r\nexport * from './lib/modules/src/prime-ng.module';\r\nexport * from './lib/pipe';\r\nexport * from './lib/services/src/alerta.service';\r\nexport * from './lib/services/src/authorize.service';\r\nexport * from './lib/services/src/base-crud.service';\r\nexport * from './lib/services/src/cache.provider';\r\nexport * from './lib/services/src/cache.service';\r\nexport * from './lib/services/src/dte.service';\r\nexport * from './lib/services/src/endpoint.service';\r\nexport * from './lib/services/src/error-handler.service';\r\nexport * from './lib/services/src/http-helpers.service';\r\nexport * from './lib/services/src/master-detail-change.service';\r\nexport * from './lib/services/src/parameter-values.service';\r\nexport * from './lib/services/src/security.service';\r\nexport * from './lib/services/src/spinner-loading.service';\r\nexport * from './lib/services/src/utility-add.service';\r\nexport * from './lib/utils';\r\nexport * from './lib/validations/addons.validators';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i1.IconDsxService","i2"],"mappings":"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"}