ngx-dsxlibrary 2.21.40 → 2.21.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ngx-dsxlibrary-src-lib-services.mjs +43 -0
- package/fesm2022/ngx-dsxlibrary-src-lib-services.mjs.map +1 -1
- package/fesm2022/ngx-dsxlibrary.mjs +291 -7
- package/fesm2022/ngx-dsxlibrary.mjs.map +1 -1
- package/ngx-dsxlibrary-2.21.42.tgz +0 -0
- package/package.json +6 -2
- package/types/ngx-dsxlibrary-src-lib-services.d.ts +12 -1
- package/types/ngx-dsxlibrary.d.ts +39 -3
- package/ngx-dsxlibrary-2.21.40.tgz +0 -0
|
@@ -1,4 +1,47 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Injectable } from '@angular/core';
|
|
3
|
+
import QRCode from 'qrcode';
|
|
4
|
+
|
|
5
|
+
class QrService {
|
|
6
|
+
/**
|
|
7
|
+
* Genera un código QR como Blob usando qrcode
|
|
8
|
+
* Sin necesidad de llamadas HTTP externas, evita problemas de CORS
|
|
9
|
+
*/
|
|
10
|
+
async getQrBlob(textToEncode) {
|
|
11
|
+
try {
|
|
12
|
+
// Genera el QR como Data URL
|
|
13
|
+
const dataUrl = await QRCode.toDataURL(textToEncode, {
|
|
14
|
+
errorCorrectionLevel: 'H',
|
|
15
|
+
type: 'image/png',
|
|
16
|
+
width: 300,
|
|
17
|
+
margin: 1,
|
|
18
|
+
color: {
|
|
19
|
+
dark: '#000000',
|
|
20
|
+
light: '#FFFFFF',
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
// Convierte Data URL a Blob
|
|
24
|
+
const response = await fetch(dataUrl);
|
|
25
|
+
return response.blob();
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
console.error('Error generando QR:', err);
|
|
29
|
+
throw err;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: QrService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
33
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: QrService, providedIn: 'root' });
|
|
34
|
+
}
|
|
35
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: QrService, decorators: [{
|
|
36
|
+
type: Injectable,
|
|
37
|
+
args: [{
|
|
38
|
+
providedIn: 'root',
|
|
39
|
+
}]
|
|
40
|
+
}] });
|
|
41
|
+
|
|
1
42
|
/**
|
|
2
43
|
* Generated bundle index. Do not edit.
|
|
3
44
|
*/
|
|
45
|
+
|
|
46
|
+
export { QrService };
|
|
4
47
|
//# sourceMappingURL=ngx-dsxlibrary-src-lib-services.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngx-dsxlibrary-src-lib-services.mjs","sources":["../../../projects/ngx-dsx/src/lib/services/ngx-dsxlibrary-src-lib-services.ts"],"sourcesContent":["/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ngx-dsxlibrary-src-lib-services.mjs","sources":["../../../projects/ngx-dsx/src/lib/services/src/qr.service.ts","../../../projects/ngx-dsx/src/lib/services/ngx-dsxlibrary-src-lib-services.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\nimport QRCode from 'qrcode';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class QrService {\r\n /**\r\n * Genera un código QR como Blob usando qrcode\r\n * Sin necesidad de llamadas HTTP externas, evita problemas de CORS\r\n */\r\n async getQrBlob(textToEncode: string): Promise<Blob> {\r\n try {\r\n // Genera el QR como Data URL\r\n const dataUrl = await QRCode.toDataURL(textToEncode, {\r\n errorCorrectionLevel: 'H',\r\n type: 'image/png',\r\n width: 300,\r\n margin: 1,\r\n color: {\r\n dark: '#000000',\r\n light: '#FFFFFF',\r\n },\r\n });\r\n\r\n // Convierte Data URL a Blob\r\n const response = await fetch(dataUrl);\r\n return response.blob();\r\n } catch (err) {\r\n console.error('Error generando QR:', err);\r\n throw err;\r\n }\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;MAMa,SAAS,CAAA;AACpB;;;AAGG;IACH,MAAM,SAAS,CAAC,YAAoB,EAAA;AAClC,QAAA,IAAI;;YAEF,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE;AACnD,gBAAA,oBAAoB,EAAE,GAAG;AACzB,gBAAA,IAAI,EAAE,WAAW;AACjB,gBAAA,KAAK,EAAE,GAAG;AACV,gBAAA,MAAM,EAAE,CAAC;AACT,gBAAA,KAAK,EAAE;AACL,oBAAA,IAAI,EAAE,SAAS;AACf,oBAAA,KAAK,EAAE,SAAS;AACjB,iBAAA;AACF,aAAA,CAAC;;AAGF,YAAA,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC;AACrC,YAAA,OAAO,QAAQ,CAAC,IAAI,EAAE;QACxB;QAAE,OAAO,GAAG,EAAE;AACZ,YAAA,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,GAAG,CAAC;AACzC,YAAA,MAAM,GAAG;QACX;IACF;wGA1BW,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAT,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,SAAS,cAFR,MAAM,EAAA,CAAA;;4FAEP,SAAS,EAAA,UAAA,EAAA,CAAA;kBAHrB,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;ACLD;;AAEG;;;;"}
|
|
@@ -40,6 +40,7 @@ import * as i4 from 'primeng/menubar';
|
|
|
40
40
|
import { MenubarModule } from 'primeng/menubar';
|
|
41
41
|
import { JwtHelperService } from '@auth0/angular-jwt';
|
|
42
42
|
import { CookieService } from 'ngx-cookie-service';
|
|
43
|
+
import QRCode from 'qrcode';
|
|
43
44
|
import * as i6 from 'primeng/floatlabel';
|
|
44
45
|
import { FloatLabelModule } from 'primeng/floatlabel';
|
|
45
46
|
import * as i7 from 'primeng/password';
|
|
@@ -3397,6 +3398,13 @@ class DsxButtonComponent {
|
|
|
3397
3398
|
id = input(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
3398
3399
|
requireIdInput = input(false, ...(ngDevMode ? [{ debugName: "requireIdInput" }] : /* istanbul ignore next */ []));
|
|
3399
3400
|
requiresIdGreaterThanZero = input(false, ...(ngDevMode ? [{ debugName: "requiresIdGreaterThanZero" }] : /* istanbul ignore next */ []));
|
|
3401
|
+
/**
|
|
3402
|
+
* Modo opcional para `softDelete`:
|
|
3403
|
+
* - `true` => botón "Borrar"
|
|
3404
|
+
* - `false` => botón "Retornar" (activar registro)
|
|
3405
|
+
* - `undefined` => conserva la configuración por defecto
|
|
3406
|
+
*/
|
|
3407
|
+
softDeleteMode = input(undefined, ...(ngDevMode ? [{ debugName: "softDeleteMode" }] : /* istanbul ignore next */ []));
|
|
3400
3408
|
labelOverride = input(undefined, ...(ngDevMode ? [{ debugName: "labelOverride" }] : /* istanbul ignore next */ []));
|
|
3401
3409
|
tooltipOverride = input(undefined, ...(ngDevMode ? [{ debugName: "tooltipOverride" }] : /* istanbul ignore next */ []));
|
|
3402
3410
|
iconOverride = input(undefined, ...(ngDevMode ? [{ debugName: "iconOverride" }] : /* istanbul ignore next */ []));
|
|
@@ -3510,6 +3518,18 @@ class DsxButtonComponent {
|
|
|
3510
3518
|
const cfg = ACTION_CONFIG[this.type()];
|
|
3511
3519
|
const colorOverride = this.colorOverride();
|
|
3512
3520
|
const outlinedOverride = this.outlinedOverride();
|
|
3521
|
+
if (this.type() === 'softDelete' && this.softDeleteMode() !== undefined) {
|
|
3522
|
+
const shouldDelete = this.softDeleteMode();
|
|
3523
|
+
return {
|
|
3524
|
+
...cfg,
|
|
3525
|
+
label: shouldDelete ? 'Borrar' : 'Retornar',
|
|
3526
|
+
tooltip: shouldDelete ? 'Borrar registro' : 'Activar registro',
|
|
3527
|
+
icon: shouldDelete ? 'restore_from_trash' : 'published_with_changes',
|
|
3528
|
+
primeIcon: shouldDelete ? 'pi pi-trash' : 'pi pi-check-circle',
|
|
3529
|
+
colorToken: colorOverride ?? (shouldDelete ? 'warning' : 'success'),
|
|
3530
|
+
outlined: outlinedOverride ?? cfg.outlined,
|
|
3531
|
+
};
|
|
3532
|
+
}
|
|
3513
3533
|
if (this.type() === 'saveOrUpdate') {
|
|
3514
3534
|
const currentId = this.getNormalizedId();
|
|
3515
3535
|
const isUpdate = typeof currentId === 'number' && currentId > 0;
|
|
@@ -3536,6 +3556,9 @@ class DsxButtonComponent {
|
|
|
3536
3556
|
get icon() {
|
|
3537
3557
|
return this.iconOverride() ?? this.config.icon;
|
|
3538
3558
|
}
|
|
3559
|
+
get materialIcon() {
|
|
3560
|
+
return this.icon || 'file_export';
|
|
3561
|
+
}
|
|
3539
3562
|
get primeIcon() {
|
|
3540
3563
|
if (this.primeIconOverride()) {
|
|
3541
3564
|
return this.primeIconOverride();
|
|
@@ -3678,15 +3701,15 @@ class DsxButtonComponent {
|
|
|
3678
3701
|
return this._paramService.isParameterValue(parameterName, this.parameterExpectedValue(), this.parameterIndex());
|
|
3679
3702
|
}
|
|
3680
3703
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: DsxButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3681
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: DsxButtonComponent, isStandalone: true, selector: "dsx-button", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, routerLink: { classPropertyName: "routerLink", publicName: "routerLink", isSignal: true, isRequired: false, transformFunction: null }, routerPath: { classPropertyName: "routerPath", publicName: "routerPath", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, iconOnly: { classPropertyName: "iconOnly", publicName: "iconOnly", isSignal: true, isRequired: false, transformFunction: null }, iconOnlyWidth: { classPropertyName: "iconOnlyWidth", publicName: "iconOnlyWidth", isSignal: true, isRequired: false, transformFunction: null }, raised: { classPropertyName: "raised", publicName: "raised", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, parameterName: { classPropertyName: "parameterName", publicName: "parameterName", isSignal: true, isRequired: false, transformFunction: null }, parameterExpectedValue: { classPropertyName: "parameterExpectedValue", publicName: "parameterExpectedValue", isSignal: true, isRequired: false, transformFunction: null }, parameterIndex: { classPropertyName: "parameterIndex", publicName: "parameterIndex", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, requireIdInput: { classPropertyName: "requireIdInput", publicName: "requireIdInput", isSignal: true, isRequired: false, transformFunction: null }, requiresIdGreaterThanZero: { classPropertyName: "requiresIdGreaterThanZero", publicName: "requiresIdGreaterThanZero", isSignal: true, isRequired: false, transformFunction: null }, labelOverride: { classPropertyName: "labelOverride", publicName: "labelOverride", isSignal: true, isRequired: false, transformFunction: null }, tooltipOverride: { classPropertyName: "tooltipOverride", publicName: "tooltipOverride", isSignal: true, isRequired: false, transformFunction: null }, iconOverride: { classPropertyName: "iconOverride", publicName: "iconOverride", isSignal: true, isRequired: false, transformFunction: null }, primeIconOverride: { classPropertyName: "primeIconOverride", publicName: "primeIconOverride", isSignal: true, isRequired: false, transformFunction: null }, colorOverride: { classPropertyName: "colorOverride", publicName: "colorOverride", isSignal: true, isRequired: false, transformFunction: null }, outlinedOverride: { classPropertyName: "outlinedOverride", publicName: "outlinedOverride", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, host: { properties: { "class.dsx-button-compact-host": "this.compactHostClass" } }, ngImport: i0, template: "<!--Bot\u00F3n con las configuraciones din\u00E1micas para CRUD -->\r\n@if (showButton()) {\r\n<p-button\r\n [label]=\"buttonLabel\"\r\n [style]=\"buttonStyle\"\r\n [styleClass]=\"buttonStyleClass\"\r\n [pTooltip]=\"tooltip\"\r\n [tooltipDisabled]=\"disabled()\"\r\n tooltipPosition=\"top\"\r\n [raised]=\"isCompactIconButton ? false : raised()\"\r\n [rounded]=\"rounded()\"\r\n [text]=\"isCompactIconButton\"\r\n [size]=\"buttonSize\"\r\n severity=\"secondary\"\r\n [disabled]=\"disabled()\"\r\n [icon]=\"primeIcon\"\r\n (click)=\"onButtonClick()\"\r\n
|
|
3704
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: DsxButtonComponent, isStandalone: true, selector: "dsx-button", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, routerLink: { classPropertyName: "routerLink", publicName: "routerLink", isSignal: true, isRequired: false, transformFunction: null }, routerPath: { classPropertyName: "routerPath", publicName: "routerPath", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, iconOnly: { classPropertyName: "iconOnly", publicName: "iconOnly", isSignal: true, isRequired: false, transformFunction: null }, iconOnlyWidth: { classPropertyName: "iconOnlyWidth", publicName: "iconOnlyWidth", isSignal: true, isRequired: false, transformFunction: null }, raised: { classPropertyName: "raised", publicName: "raised", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, parameterName: { classPropertyName: "parameterName", publicName: "parameterName", isSignal: true, isRequired: false, transformFunction: null }, parameterExpectedValue: { classPropertyName: "parameterExpectedValue", publicName: "parameterExpectedValue", isSignal: true, isRequired: false, transformFunction: null }, parameterIndex: { classPropertyName: "parameterIndex", publicName: "parameterIndex", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, requireIdInput: { classPropertyName: "requireIdInput", publicName: "requireIdInput", isSignal: true, isRequired: false, transformFunction: null }, requiresIdGreaterThanZero: { classPropertyName: "requiresIdGreaterThanZero", publicName: "requiresIdGreaterThanZero", isSignal: true, isRequired: false, transformFunction: null }, softDeleteMode: { classPropertyName: "softDeleteMode", publicName: "softDeleteMode", isSignal: true, isRequired: false, transformFunction: null }, labelOverride: { classPropertyName: "labelOverride", publicName: "labelOverride", isSignal: true, isRequired: false, transformFunction: null }, tooltipOverride: { classPropertyName: "tooltipOverride", publicName: "tooltipOverride", isSignal: true, isRequired: false, transformFunction: null }, iconOverride: { classPropertyName: "iconOverride", publicName: "iconOverride", isSignal: true, isRequired: false, transformFunction: null }, primeIconOverride: { classPropertyName: "primeIconOverride", publicName: "primeIconOverride", isSignal: true, isRequired: false, transformFunction: null }, colorOverride: { classPropertyName: "colorOverride", publicName: "colorOverride", isSignal: true, isRequired: false, transformFunction: null }, outlinedOverride: { classPropertyName: "outlinedOverride", publicName: "outlinedOverride", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, host: { properties: { "class.dsx-button-compact-host": "this.compactHostClass" } }, ngImport: i0, template: "<!--Bot\u00F3n con las configuraciones din\u00E1micas para CRUD -->\r\n@if (showButton()) {\r\n<p-button\r\n [label]=\"buttonLabel\"\r\n [style]=\"buttonStyle\"\r\n [styleClass]=\"buttonStyleClass\"\r\n [pTooltip]=\"tooltip\"\r\n [tooltipDisabled]=\"disabled()\"\r\n tooltipPosition=\"top\"\r\n [raised]=\"isCompactIconButton ? false : raised()\"\r\n [rounded]=\"rounded()\"\r\n [text]=\"isCompactIconButton\"\r\n [size]=\"buttonSize\"\r\n severity=\"secondary\"\r\n [disabled]=\"disabled()\"\r\n [icon]=\"iconOnly() ? primeIcon : undefined\"\r\n (click)=\"onButtonClick()\"\r\n>\r\n @if (!iconOnly()) {\r\n <span class=\"material-symbols-outlined\">{{ materialIcon }}</span>\r\n }\r\n</p-button>\r\n}\r\n", styles: [":host{display:inline-flex;margin-bottom:.25rem}:host.dsx-button-compact-host{margin-bottom:0}:host ::ng-deep .p-button .p-button-label{font-family:Montserrat,Roboto,sans-serif;font-weight:500;letter-spacing:.01em}:host ::ng-deep .p-button.dsx-button-compact{min-height:2rem;padding-block:.2rem}:host ::ng-deep .p-button .material-symbols-outlined.p-button-icon{line-height:1;vertical-align:middle}:host ::ng-deep .p-button.dsx-button-compact .p-button-icon{margin:0;font-size:1.2rem;line-height:1}:host ::ng-deep .p-button.dsx-button-compact .material-symbols-outlined.p-button-icon{font-variation-settings:\"FILL\" 1,\"wght\" 500,\"GRAD\" 0,\"opsz\" 24}:host ::ng-deep .p-button:disabled,:host ::ng-deep .p-button.p-disabled{cursor:not-allowed!important;opacity:.45!important;filter:grayscale(.2) saturate(.75)}:host ::ng-deep .p-button:disabled *,:host ::ng-deep .p-button.p-disabled *{cursor:not-allowed!important}\n"], dependencies: [{ kind: "component", type: Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1$3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }] });
|
|
3682
3705
|
}
|
|
3683
3706
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: DsxButtonComponent, decorators: [{
|
|
3684
3707
|
type: Component,
|
|
3685
|
-
args: [{ selector: 'dsx-button', imports: [Button, TooltipModule], template: "<!--Bot\u00F3n con las configuraciones din\u00E1micas para CRUD -->\r\n@if (showButton()) {\r\n<p-button\r\n [label]=\"buttonLabel\"\r\n [style]=\"buttonStyle\"\r\n [styleClass]=\"buttonStyleClass\"\r\n [pTooltip]=\"tooltip\"\r\n [tooltipDisabled]=\"disabled()\"\r\n tooltipPosition=\"top\"\r\n [raised]=\"isCompactIconButton ? false : raised()\"\r\n [rounded]=\"rounded()\"\r\n [text]=\"isCompactIconButton\"\r\n [size]=\"buttonSize\"\r\n severity=\"secondary\"\r\n [disabled]=\"disabled()\"\r\n [icon]=\"primeIcon\"\r\n (click)=\"onButtonClick()\"\r\n
|
|
3708
|
+
args: [{ selector: 'dsx-button', imports: [Button, TooltipModule], template: "<!--Bot\u00F3n con las configuraciones din\u00E1micas para CRUD -->\r\n@if (showButton()) {\r\n<p-button\r\n [label]=\"buttonLabel\"\r\n [style]=\"buttonStyle\"\r\n [styleClass]=\"buttonStyleClass\"\r\n [pTooltip]=\"tooltip\"\r\n [tooltipDisabled]=\"disabled()\"\r\n tooltipPosition=\"top\"\r\n [raised]=\"isCompactIconButton ? false : raised()\"\r\n [rounded]=\"rounded()\"\r\n [text]=\"isCompactIconButton\"\r\n [size]=\"buttonSize\"\r\n severity=\"secondary\"\r\n [disabled]=\"disabled()\"\r\n [icon]=\"iconOnly() ? primeIcon : undefined\"\r\n (click)=\"onButtonClick()\"\r\n>\r\n @if (!iconOnly()) {\r\n <span class=\"material-symbols-outlined\">{{ materialIcon }}</span>\r\n }\r\n</p-button>\r\n}\r\n", styles: [":host{display:inline-flex;margin-bottom:.25rem}:host.dsx-button-compact-host{margin-bottom:0}:host ::ng-deep .p-button .p-button-label{font-family:Montserrat,Roboto,sans-serif;font-weight:500;letter-spacing:.01em}:host ::ng-deep .p-button.dsx-button-compact{min-height:2rem;padding-block:.2rem}:host ::ng-deep .p-button .material-symbols-outlined.p-button-icon{line-height:1;vertical-align:middle}:host ::ng-deep .p-button.dsx-button-compact .p-button-icon{margin:0;font-size:1.2rem;line-height:1}:host ::ng-deep .p-button.dsx-button-compact .material-symbols-outlined.p-button-icon{font-variation-settings:\"FILL\" 1,\"wght\" 500,\"GRAD\" 0,\"opsz\" 24}:host ::ng-deep .p-button:disabled,:host ::ng-deep .p-button.p-disabled{cursor:not-allowed!important;opacity:.45!important;filter:grayscale(.2) saturate(.75)}:host ::ng-deep .p-button:disabled *,:host ::ng-deep .p-button.p-disabled *{cursor:not-allowed!important}\n"] }]
|
|
3686
3709
|
}], ctorParameters: () => [], propDecorators: { compactHostClass: [{
|
|
3687
3710
|
type: HostBinding,
|
|
3688
3711
|
args: ['class.dsx-button-compact-host']
|
|
3689
|
-
}], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], routerLink: [{ type: i0.Input, args: [{ isSignal: true, alias: "routerLink", required: false }] }], routerPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "routerPath", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], iconOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnly", required: false }] }], iconOnlyWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnlyWidth", required: false }] }], raised: [{ type: i0.Input, args: [{ isSignal: true, alias: "raised", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], parameterName: [{ type: i0.Input, args: [{ isSignal: true, alias: "parameterName", required: false }] }], parameterExpectedValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "parameterExpectedValue", required: false }] }], parameterIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "parameterIndex", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], requireIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "requireIdInput", required: false }] }], requiresIdGreaterThanZero: [{ type: i0.Input, args: [{ isSignal: true, alias: "requiresIdGreaterThanZero", required: false }] }], labelOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelOverride", required: false }] }], tooltipOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipOverride", required: false }] }], iconOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOverride", required: false }] }], primeIconOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "primeIconOverride", required: false }] }], colorOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorOverride", required: false }] }], outlinedOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "outlinedOverride", required: false }] }], action: [{ type: i0.Output, args: ["action"] }] } });
|
|
3712
|
+
}], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], routerLink: [{ type: i0.Input, args: [{ isSignal: true, alias: "routerLink", required: false }] }], routerPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "routerPath", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], iconOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnly", required: false }] }], iconOnlyWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnlyWidth", required: false }] }], raised: [{ type: i0.Input, args: [{ isSignal: true, alias: "raised", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], parameterName: [{ type: i0.Input, args: [{ isSignal: true, alias: "parameterName", required: false }] }], parameterExpectedValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "parameterExpectedValue", required: false }] }], parameterIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "parameterIndex", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], requireIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "requireIdInput", required: false }] }], requiresIdGreaterThanZero: [{ type: i0.Input, args: [{ isSignal: true, alias: "requiresIdGreaterThanZero", required: false }] }], softDeleteMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "softDeleteMode", required: false }] }], labelOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelOverride", required: false }] }], tooltipOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipOverride", required: false }] }], iconOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOverride", required: false }] }], primeIconOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "primeIconOverride", required: false }] }], colorOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorOverride", required: false }] }], outlinedOverride: [{ type: i0.Input, args: [{ isSignal: true, alias: "outlinedOverride", required: false }] }], action: [{ type: i0.Output, args: ["action"] }] } });
|
|
3690
3713
|
const ACTION_CONFIG = {
|
|
3691
3714
|
delete: {
|
|
3692
3715
|
label: 'Eliminar',
|
|
@@ -3739,11 +3762,11 @@ const ACTION_CONFIG = {
|
|
|
3739
3762
|
tooltip: 'Salvar datos',
|
|
3740
3763
|
},
|
|
3741
3764
|
refresh: {
|
|
3742
|
-
label: '
|
|
3743
|
-
icon: '
|
|
3765
|
+
label: 'Refrescar',
|
|
3766
|
+
icon: 'cloud_sync',
|
|
3744
3767
|
primeIcon: 'pi pi-refresh',
|
|
3745
3768
|
colorToken: 'info',
|
|
3746
|
-
tooltip: '
|
|
3769
|
+
tooltip: 'Sincronizar datos',
|
|
3747
3770
|
},
|
|
3748
3771
|
create: {
|
|
3749
3772
|
label: 'Agregar',
|
|
@@ -4855,6 +4878,267 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
4855
4878
|
], template: "<p-menubar>\r\n <ng-template #start>\r\n <p-image\r\n class=\"ms-15\"\r\n [src]=\"urlLogo()\"\r\n alt=\"Image\"\r\n [width]=\"logoWidth()\"\r\n />\r\n <span class=\"version-text\">{{ appVersion() }}</span>\r\n </ng-template>\r\n <ng-template #end>\r\n <div>\r\n <!-- Datos del usuario -->\r\n <div class=\"navbar-user-info\">\r\n <icon-dsx name=\"verified_user\" class=\"navbar-user-icon\"></icon-dsx>\r\n <div class=\"navbar-user-text\">\r\n <span class=\"navbar-user-name\">\r\n {{ _authorizeService.getTokenValues.userName }}\r\n </span>\r\n <span class=\"navbar-user-role\">\r\n {{ currentRole }}\r\n </span>\r\n </div>\r\n </div>\r\n\r\n <!-- Componente de estado de red -->\r\n <app-network-status></app-network-status>\r\n\r\n <!-- Actualizaci\u00F3n de permisos -->\r\n <p-button\r\n 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", styles: [":host ::ng-deep .p-menubar{display:flex;align-items:center!important;padding:.25rem 1.5rem!important;border-radius:999px;border:1px solid rgba(255,255,255,.2);background:#ffffff1f!important;backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);box-shadow:0 10px 30px #0f172a14;margin-left:4rem;margin-right:2.5rem}:host ::ng-deep .p-menubar-end>*{display:flex;align-items:center}.version-text{font-size:1.3rem;font-family:Montserrat,sans-serif!important;margin-left:.5rem;font-weight:600;background-image:linear-gradient(to right,#38bdf8,#630cb4);-webkit-background-clip:text;background-clip:text;color:transparent;text-shadow:0 2px 4px rgba(0,0,0,.1);padding:.2rem 0}.navbar-user-info{display:flex;align-items:center;gap:.35rem;padding:0 .75rem;border-radius:999px;background-color:#00000005}.navbar-user-icon{font-size:1.1rem;color:#374151}.navbar-user-name{font-size:.8rem;font-weight:500;color:#374151;white-space:nowrap}.navbar-user-text{display:flex;flex-direction:column;line-height:1.1}.navbar-user-role{font-size:.7rem;color:#6b7280;white-space:nowrap}.ui-switch{--switch-bg: rgb(135, 150, 165);--switch-width: 48px;--switch-height: 20px;--circle-diameter: 32px;--circle-bg: rgb(232, 89, 15);--circle-inset: calc((var(--circle-diameter) - var(--switch-height)) / 2)}.ui-switch input{display:none}.slider{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:var(--switch-width);height:var(--switch-height);background:var(--switch-bg);border-radius:999px;position:relative;cursor:pointer}.slider .circle{top:calc(var(--circle-inset) * -1);left:0;width:var(--circle-diameter);height:var(--circle-diameter);position:absolute;background:var(--circle-bg);border-radius:inherit;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjAiIHdpZHRoPSIyMCIgdmlld0JveD0iMCAwIDIwIDIwIj4KICAgIDxwYXRoIGZpbGw9IiNmZmYiCiAgICAgICAgZD0iTTkuMzA1IDEuNjY3VjMuNzVoMS4zODlWMS42NjdoLTEuMzl6bS00LjcwNyAxLjk1bC0uOTgyLjk4Mkw1LjA5IDYuMDcybC45ODItLjk4Mi0xLjQ3My0xLjQ3M3ptMTAuODAyIDBMMTMuOTI3IDUuMDlsLjk4Mi45ODIgMS40NzMtMS40NzMtLjk4Mi0uOTgyek0xMCA1LjEzOWE0Ljg3MiA0Ljg3MiAwIDAwLTQuODYyIDQuODZBNC44NzIgNC44NzIgMCAwMDEwIDE0Ljg2MiA0Ljg3MiA0Ljg3MiAwIDAwMTQuODYgMTAgNC44NzIgNC44NzIgMCAwMDEwIDUuMTM5em0wIDEuMzg5QTMuNDYyIDMuNDYyIDAgMDExMy40NzEgMTBhMy40NjIgMy40NjIgMCAwMS0zLjQ3MyAzLjQ3MkEzLjQ2MiAzLjQ2MiAwIDAxNi41MjcgMTAgMy40NjIgMy40NjIgMCAwMTEwIDYuNTI4ek0xLjY2NSA5LjMwNXYxLjM5aDIuMDgzdi0xLjM5SDEuNjY2em0xNC41ODMgMHYxLjM5aDIuMDg0di0xLjM5aC0yLjA4NHpNNS4wOSAxMy45MjhMMy42MTYgMTUuNGwuOTgyLjk4MiAxLjQ3My0xLjQ3My0uOTgyLS45ODJ6bTkuODIgMGwtLjk4Mi45ODIgMS40NzMgMS40NzMuOTgyLS45ODItMS40NzMtMS40NzN6TTkuMzA1IDE2LjI1djIuMDgzaDEuMzg5VjE2LjI1aC0xLjM5eiIgLz4KPC9zdmc+);background-repeat:no-repeat;background-position:center center;-webkit-transition:left .15s cubic-bezier(.4,0,.2,1) 0ms,-webkit-transform .15s cubic-bezier(.4,0,.2,1) 0ms;-o-transition:left .15s cubic-bezier(.4,0,.2,1) 0ms,transform .15s cubic-bezier(.4,0,.2,1) 0ms;transition:left .15s cubic-bezier(.4,0,.2,1) 0ms,transform .15s cubic-bezier(.4,0,.2,1) 0ms,-webkit-transform .15s cubic-bezier(.4,0,.2,1) 0ms;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;box-shadow:0 2px 1px -1px #0003,0 1px 1px #00000024,0 1px 3px #0000001f}.slider .circle:before{content:\"\";position:absolute;width:100%;height:100%;background:#ffffffbf;border-radius:inherit;-webkit-transition:all .5s;-o-transition:all .5s;transition:all .5s;opacity:0}.ui-switch input:checked+.slider .circle{left:calc(100% - var(--circle-diameter));background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjAiIHdpZHRoPSIyMCIgdmlld0JveD0iMCAwIDIwIDIwIj4KICAgIDxwYXRoIGZpbGw9IiNmZmYiCiAgICAgICAgZD0iTTQuMiAyLjVsLS43IDEuOC0xLjguNyAxLjguNy43IDEuOC42LTEuOEw2LjcgNWwtMS45LS43LS42LTEuOHptMTUgOC4zYTYuNyA2LjcgMCAxMS02LjYtNi42IDUuOCA1LjggMCAwMDYuNiA2LjZ6IiAvPgo8L3N2Zz4=);background-color:#003892}.ui-switch input:active+.slider .circle:before{-webkit-transition:0s;-o-transition:0s;transition:0s;opacity:1;width:0;height:0}\n"] }]
|
|
4856
4879
|
}], propDecorators: { appVersion: [{ type: i0.Input, args: [{ isSignal: true, alias: "appVersion", required: false }] }], logoWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoWidth", required: false }] }], urlLogo: [{ type: i0.Input, args: [{ isSignal: true, alias: "urlLogo", required: false }] }] } });
|
|
4857
4880
|
|
|
4881
|
+
class QrService {
|
|
4882
|
+
/**
|
|
4883
|
+
* Genera un código QR como Blob usando qrcode
|
|
4884
|
+
* Sin necesidad de llamadas HTTP externas, evita problemas de CORS
|
|
4885
|
+
*/
|
|
4886
|
+
async getQrBlob(textToEncode) {
|
|
4887
|
+
try {
|
|
4888
|
+
// Genera el QR como Data URL
|
|
4889
|
+
const dataUrl = await QRCode.toDataURL(textToEncode, {
|
|
4890
|
+
errorCorrectionLevel: 'H',
|
|
4891
|
+
type: 'image/png',
|
|
4892
|
+
width: 300,
|
|
4893
|
+
margin: 1,
|
|
4894
|
+
color: {
|
|
4895
|
+
dark: '#000000',
|
|
4896
|
+
light: '#FFFFFF',
|
|
4897
|
+
},
|
|
4898
|
+
});
|
|
4899
|
+
// Convierte Data URL a Blob
|
|
4900
|
+
const response = await fetch(dataUrl);
|
|
4901
|
+
return response.blob();
|
|
4902
|
+
}
|
|
4903
|
+
catch (err) {
|
|
4904
|
+
console.error('Error generando QR:', err);
|
|
4905
|
+
throw err;
|
|
4906
|
+
}
|
|
4907
|
+
}
|
|
4908
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: QrService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
4909
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: QrService, providedIn: 'root' });
|
|
4910
|
+
}
|
|
4911
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: QrService, decorators: [{
|
|
4912
|
+
type: Injectable,
|
|
4913
|
+
args: [{
|
|
4914
|
+
providedIn: 'root',
|
|
4915
|
+
}]
|
|
4916
|
+
}] });
|
|
4917
|
+
|
|
4918
|
+
class QrGenerator {
|
|
4919
|
+
qrService = inject(QrService);
|
|
4920
|
+
sanitizer = inject(DomSanitizer);
|
|
4921
|
+
// Inputs del padre
|
|
4922
|
+
codigoQr = input(null, ...(ngDevMode ? [{ debugName: "codigoQr" }] : /* istanbul ignore next */ [])); // Contenido a codificar en el QR
|
|
4923
|
+
labelQr = input('SCAN ME', ...(ngDevMode ? [{ debugName: "labelQr" }] : /* istanbul ignore next */ [])); // Texto del banner inferior
|
|
4924
|
+
// Señales internas (copias escribibles de los inputs)
|
|
4925
|
+
qrImageUrl = signal(null, ...(ngDevMode ? [{ debugName: "qrImageUrl" }] : /* istanbul ignore next */ []));
|
|
4926
|
+
labelText = signal('SCAN ME', ...(ngDevMode ? [{ debugName: "labelText" }] : /* istanbul ignore next */ []));
|
|
4927
|
+
textToEncode = signal('', ...(ngDevMode ? [{ debugName: "textToEncode" }] : /* istanbul ignore next */ []));
|
|
4928
|
+
constructor() {
|
|
4929
|
+
effect(() => {
|
|
4930
|
+
// Sincronizar labelQr → labelText
|
|
4931
|
+
this.labelText.set(this.labelQr());
|
|
4932
|
+
// Sincronizar codigoQr → textToEncode y generar el QR
|
|
4933
|
+
if (this.codigoQr()) {
|
|
4934
|
+
this.textToEncode.set(this.codigoQr());
|
|
4935
|
+
setTimeout(() => this.generateQrCode(), 100);
|
|
4936
|
+
}
|
|
4937
|
+
});
|
|
4938
|
+
}
|
|
4939
|
+
currentRawBlob = null;
|
|
4940
|
+
generateQrCode() {
|
|
4941
|
+
if (!this.textToEncode())
|
|
4942
|
+
return;
|
|
4943
|
+
this.qrService
|
|
4944
|
+
.getQrBlob(this.textToEncode())
|
|
4945
|
+
.then((blob) => {
|
|
4946
|
+
this.currentRawBlob = blob;
|
|
4947
|
+
this.generateDesignImage();
|
|
4948
|
+
})
|
|
4949
|
+
.catch((err) => console.error('Error generando QR:', err));
|
|
4950
|
+
}
|
|
4951
|
+
onLabelChange(value) {
|
|
4952
|
+
this.labelText.set(value);
|
|
4953
|
+
// Regenera la imagen de preview con la nueva etiqueta
|
|
4954
|
+
this.generateDesignImage();
|
|
4955
|
+
}
|
|
4956
|
+
generateDesignImage() {
|
|
4957
|
+
if (!this.currentRawBlob)
|
|
4958
|
+
return;
|
|
4959
|
+
const qrImage = new Image();
|
|
4960
|
+
const qrUrl = URL.createObjectURL(this.currentRawBlob);
|
|
4961
|
+
qrImage.src = qrUrl;
|
|
4962
|
+
qrImage.onload = () => {
|
|
4963
|
+
const qrSize = qrImage.width || 300;
|
|
4964
|
+
const padding = 40;
|
|
4965
|
+
const labelAreaHeight = 70;
|
|
4966
|
+
const canvas = document.createElement('canvas');
|
|
4967
|
+
canvas.width = qrSize + padding * 2;
|
|
4968
|
+
canvas.height = qrSize + labelAreaHeight + padding;
|
|
4969
|
+
const ctx = canvas.getContext('2d');
|
|
4970
|
+
if (!ctx)
|
|
4971
|
+
return;
|
|
4972
|
+
// Fondo blanco
|
|
4973
|
+
ctx.fillStyle = '#FFFFFF';
|
|
4974
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
4975
|
+
// DIBUJAR LAS ESQUINAS DE ENFOQUE
|
|
4976
|
+
ctx.strokeStyle = '#000000';
|
|
4977
|
+
ctx.lineWidth = 5;
|
|
4978
|
+
const lineLength = 25;
|
|
4979
|
+
const xMin = padding - 10;
|
|
4980
|
+
const yMin = padding - 10;
|
|
4981
|
+
const xMax = padding + qrSize + 10;
|
|
4982
|
+
const yMax = padding + qrSize + 10;
|
|
4983
|
+
// Esquinas
|
|
4984
|
+
ctx.beginPath();
|
|
4985
|
+
ctx.moveTo(xMin + lineLength, yMin);
|
|
4986
|
+
ctx.lineTo(xMin, yMin);
|
|
4987
|
+
ctx.lineTo(xMin, yMin + lineLength);
|
|
4988
|
+
ctx.stroke();
|
|
4989
|
+
ctx.beginPath();
|
|
4990
|
+
ctx.moveTo(xMax - lineLength, yMin);
|
|
4991
|
+
ctx.lineTo(xMax, yMin);
|
|
4992
|
+
ctx.lineTo(xMax, yMin + lineLength);
|
|
4993
|
+
ctx.stroke();
|
|
4994
|
+
ctx.beginPath();
|
|
4995
|
+
ctx.moveTo(xMin + lineLength, yMax);
|
|
4996
|
+
ctx.lineTo(xMin, yMax);
|
|
4997
|
+
ctx.lineTo(xMin, yMax - lineLength);
|
|
4998
|
+
ctx.stroke();
|
|
4999
|
+
ctx.beginPath();
|
|
5000
|
+
ctx.moveTo(xMax - lineLength, yMax);
|
|
5001
|
+
ctx.lineTo(xMax, yMax);
|
|
5002
|
+
ctx.lineTo(xMax, yMax - lineLength);
|
|
5003
|
+
ctx.stroke();
|
|
5004
|
+
// Dibujar el código QR
|
|
5005
|
+
ctx.drawImage(qrImage, padding, padding, qrSize, qrSize);
|
|
5006
|
+
// Configuración del banner
|
|
5007
|
+
const rectWidth = qrSize * 0.8;
|
|
5008
|
+
const rectHeight = 45;
|
|
5009
|
+
const rectX = padding + (qrSize - rectWidth) / 2;
|
|
5010
|
+
const rectY = yMax + 20;
|
|
5011
|
+
// Caja negra
|
|
5012
|
+
ctx.fillStyle = '#000000';
|
|
5013
|
+
ctx.fillRect(rectX, rectY, rectWidth, rectHeight);
|
|
5014
|
+
// Triángulo indicador
|
|
5015
|
+
ctx.beginPath();
|
|
5016
|
+
ctx.moveTo(canvas.width / 2, rectY - 8);
|
|
5017
|
+
ctx.lineTo(canvas.width / 2 - 10, rectY);
|
|
5018
|
+
ctx.lineTo(canvas.width / 2 + 10, rectY);
|
|
5019
|
+
ctx.closePath();
|
|
5020
|
+
ctx.fill();
|
|
5021
|
+
// Texto
|
|
5022
|
+
ctx.fillStyle = '#FFFFFF';
|
|
5023
|
+
ctx.font = 'bold 18px sans-serif';
|
|
5024
|
+
ctx.textAlign = 'center';
|
|
5025
|
+
ctx.textBaseline = 'middle';
|
|
5026
|
+
ctx.fillText(this.labelText().toUpperCase(), canvas.width / 2, rectY + rectHeight / 2);
|
|
5027
|
+
// Convertir a URL para mostrar en preview
|
|
5028
|
+
canvas.toBlob((blob) => {
|
|
5029
|
+
if (blob) {
|
|
5030
|
+
const previewUrl = URL.createObjectURL(blob);
|
|
5031
|
+
this.qrImageUrl.set(this.sanitizer.bypassSecurityTrustUrl(previewUrl));
|
|
5032
|
+
}
|
|
5033
|
+
}, 'image/png');
|
|
5034
|
+
};
|
|
5035
|
+
}
|
|
5036
|
+
downloadWithLabel() {
|
|
5037
|
+
if (!this.currentRawBlob)
|
|
5038
|
+
return;
|
|
5039
|
+
const qrImage = new Image();
|
|
5040
|
+
const qrUrl = URL.createObjectURL(this.currentRawBlob);
|
|
5041
|
+
qrImage.src = qrUrl;
|
|
5042
|
+
qrImage.onload = () => {
|
|
5043
|
+
const qrSize = qrImage.width || 300;
|
|
5044
|
+
const padding = 40; // Aumentamos el margen para las esquinas de enfoque
|
|
5045
|
+
const labelAreaHeight = 70;
|
|
5046
|
+
const canvas = document.createElement('canvas');
|
|
5047
|
+
canvas.width = qrSize + padding * 2;
|
|
5048
|
+
canvas.height = qrSize + labelAreaHeight + padding;
|
|
5049
|
+
const ctx = canvas.getContext('2d');
|
|
5050
|
+
if (!ctx)
|
|
5051
|
+
return;
|
|
5052
|
+
// Fondo blanco
|
|
5053
|
+
ctx.fillStyle = '#FFFFFF';
|
|
5054
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
5055
|
+
// DIBUJAR LAS ESQUINAS DE ENFOQUE (Estilo de tu imagen de referencia)
|
|
5056
|
+
ctx.strokeStyle = '#000000'; // Color negro para las líneas de enfoque
|
|
5057
|
+
ctx.lineWidth = 5; // Grosor de las esquinas
|
|
5058
|
+
const lineLength = 25; // Largo de cada segmento de la esquina
|
|
5059
|
+
// Área delimitadora donde se posicionará el QR
|
|
5060
|
+
const xMin = padding - 10;
|
|
5061
|
+
const yMin = padding - 10;
|
|
5062
|
+
const xMax = padding + qrSize + 10;
|
|
5063
|
+
const yMax = padding + qrSize + 10;
|
|
5064
|
+
// Esquina Superior Izquierda
|
|
5065
|
+
ctx.beginPath();
|
|
5066
|
+
ctx.moveTo(xMin + lineLength, yMin);
|
|
5067
|
+
ctx.lineTo(xMin, yMin);
|
|
5068
|
+
ctx.lineTo(xMin, yMin + lineLength);
|
|
5069
|
+
ctx.stroke();
|
|
5070
|
+
// Esquina Superior Derecha
|
|
5071
|
+
ctx.beginPath();
|
|
5072
|
+
ctx.moveTo(xMax - lineLength, yMin);
|
|
5073
|
+
ctx.lineTo(xMax, yMin);
|
|
5074
|
+
ctx.lineTo(xMax, yMin + lineLength);
|
|
5075
|
+
ctx.stroke();
|
|
5076
|
+
// Esquina Inferior Izquierda
|
|
5077
|
+
ctx.beginPath();
|
|
5078
|
+
ctx.moveTo(xMin + lineLength, yMax);
|
|
5079
|
+
ctx.lineTo(xMin, yMax);
|
|
5080
|
+
ctx.lineTo(xMin, yMax + lineLength);
|
|
5081
|
+
ctx.stroke();
|
|
5082
|
+
// Esquina Inferior Derecha
|
|
5083
|
+
ctx.beginPath();
|
|
5084
|
+
ctx.moveTo(xMax - lineLength, yMax);
|
|
5085
|
+
ctx.lineTo(xMax, yMax);
|
|
5086
|
+
ctx.lineTo(xMax, yMax + lineLength);
|
|
5087
|
+
ctx.stroke();
|
|
5088
|
+
// Dibujar el código QR original obtenido desde qrcoder.co.uk
|
|
5089
|
+
ctx.drawImage(qrImage, padding, padding, qrSize, qrSize);
|
|
5090
|
+
// Configuración geométrica de la etiqueta negra inferior
|
|
5091
|
+
const rectWidth = qrSize * 0.8;
|
|
5092
|
+
const rectHeight = 45;
|
|
5093
|
+
const rectX = padding + (qrSize - rectWidth) / 2;
|
|
5094
|
+
const rectY = yMax + 20; // Separado adecuadamente de la línea de enfoque inferior
|
|
5095
|
+
// Dibujar caja contenedora de texto
|
|
5096
|
+
ctx.fillStyle = '#000000';
|
|
5097
|
+
ctx.fillRect(rectX, rectY, rectWidth, rectHeight);
|
|
5098
|
+
// Pequeño triángulo indicador (Flecha superior de la caja)
|
|
5099
|
+
ctx.beginPath();
|
|
5100
|
+
ctx.moveTo(canvas.width / 2, rectY - 8);
|
|
5101
|
+
ctx.lineTo(canvas.width / 2 - 10, rectY);
|
|
5102
|
+
ctx.lineTo(canvas.width / 2 + 10, rectY);
|
|
5103
|
+
ctx.closePath();
|
|
5104
|
+
ctx.fill();
|
|
5105
|
+
// Renderizar Texto de Referencia
|
|
5106
|
+
ctx.fillStyle = '#FFFFFF';
|
|
5107
|
+
ctx.font = 'bold 18px sans-serif';
|
|
5108
|
+
ctx.textAlign = 'center';
|
|
5109
|
+
ctx.textBaseline = 'middle';
|
|
5110
|
+
ctx.fillText(this.labelText().toUpperCase(), canvas.width / 2, rectY + rectHeight / 2);
|
|
5111
|
+
// Conversión final y descarga en JPEG
|
|
5112
|
+
canvas.toBlob((finalBlob) => {
|
|
5113
|
+
if (finalBlob) {
|
|
5114
|
+
const downloadUrl = URL.createObjectURL(finalBlob);
|
|
5115
|
+
const link = document.createElement('a');
|
|
5116
|
+
link.href = downloadUrl;
|
|
5117
|
+
const now = new Date();
|
|
5118
|
+
const timestamp = now.getFullYear().toString() +
|
|
5119
|
+
(now.getMonth() + 1).toString().padStart(2, '0') +
|
|
5120
|
+
now.getDate().toString().padStart(2, '0') +
|
|
5121
|
+
now.getHours().toString().padStart(2, '0') +
|
|
5122
|
+
now.getMinutes().toString().padStart(2, '0') +
|
|
5123
|
+
now.getSeconds().toString().padStart(2, '0');
|
|
5124
|
+
link.download = `qr-${timestamp}.jpg`;
|
|
5125
|
+
document.body.appendChild(link);
|
|
5126
|
+
link.click();
|
|
5127
|
+
document.body.removeChild(link);
|
|
5128
|
+
URL.revokeObjectURL(downloadUrl);
|
|
5129
|
+
URL.revokeObjectURL(qrUrl);
|
|
5130
|
+
}
|
|
5131
|
+
}, 'image/jpeg', 0.95);
|
|
5132
|
+
};
|
|
5133
|
+
}
|
|
5134
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: QrGenerator, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5135
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: QrGenerator, isStandalone: true, selector: "dsx-qr-generator", inputs: { codigoQr: { classPropertyName: "codigoQr", publicName: "codigoQr", isSignal: true, isRequired: false, transformFunction: null }, labelQr: { classPropertyName: "labelQr", publicName: "labelQr", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"w-full max-w-xs mx-auto text-center\">\r\n <!-- Encabezado -->\r\n <h2 class=\"text-sm font-semibold text-gray-700 mb-2\">\r\n Generador de C\u00F3digo QR\r\n </h2>\r\n\r\n <!-- Valor recibido como validaci\u00F3n (solo lectura) -->\r\n <p class=\"text-xs text-gray-400 mb-3 truncate\">\r\n <span class=\"font-medium text-gray-500\">Contenido: </span>{{ textToEncode()\r\n }}\r\n </p>\r\n\r\n <!-- Preview del QR con dise\u00F1o -->\r\n @if (qrImageUrl()) {\r\n <div class=\"flex flex-col items-center gap-3\">\r\n <!-- Imagen generada con esquinas y banner -->\r\n <div\r\n class=\"rounded-xl border border-gray-200 bg-white p-1 shadow-md inline-block\"\r\n >\r\n <img\r\n [src]=\"qrImageUrl()\"\r\n alt=\"C\u00F3digo QR\"\r\n class=\"w-44 h-auto block rounded\"\r\n />\r\n </div>\r\n\r\n <!-- Bot\u00F3n descarga -->\r\n <button\r\n style=\"\r\n background: #059669;\r\n color: #fff;\r\n font-size: 0.8rem;\r\n padding: 0.4rem 1rem;\r\n border-radius: 0.5rem;\r\n \"\r\n class=\"font-semibold hover:opacity-90 transition-opacity flex items-center justify-center gap-1\"\r\n (click)=\"downloadWithLabel()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n style=\"width: 1rem; height: 1rem; flex-shrink: 0\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n >\r\n <path\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n d=\"M4 16v2a2 2 0 002 2h12a2 2 0 002-2v-2M7 10l5 5 5-5M12 15V3\"\r\n />\r\n </svg>\r\n Descargar JPEG\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: FormsModule }] });
|
|
5136
|
+
}
|
|
5137
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: QrGenerator, decorators: [{
|
|
5138
|
+
type: Component,
|
|
5139
|
+
args: [{ selector: 'dsx-qr-generator', imports: [FormsModule], template: "<div class=\"w-full max-w-xs mx-auto text-center\">\r\n <!-- Encabezado -->\r\n <h2 class=\"text-sm font-semibold text-gray-700 mb-2\">\r\n Generador de C\u00F3digo QR\r\n </h2>\r\n\r\n <!-- Valor recibido como validaci\u00F3n (solo lectura) -->\r\n <p class=\"text-xs text-gray-400 mb-3 truncate\">\r\n <span class=\"font-medium text-gray-500\">Contenido: </span>{{ textToEncode()\r\n }}\r\n </p>\r\n\r\n <!-- Preview del QR con dise\u00F1o -->\r\n @if (qrImageUrl()) {\r\n <div class=\"flex flex-col items-center gap-3\">\r\n <!-- Imagen generada con esquinas y banner -->\r\n <div\r\n class=\"rounded-xl border border-gray-200 bg-white p-1 shadow-md inline-block\"\r\n >\r\n <img\r\n [src]=\"qrImageUrl()\"\r\n alt=\"C\u00F3digo QR\"\r\n class=\"w-44 h-auto block rounded\"\r\n />\r\n </div>\r\n\r\n <!-- Bot\u00F3n descarga -->\r\n <button\r\n style=\"\r\n background: #059669;\r\n color: #fff;\r\n font-size: 0.8rem;\r\n padding: 0.4rem 1rem;\r\n border-radius: 0.5rem;\r\n \"\r\n class=\"font-semibold hover:opacity-90 transition-opacity flex items-center justify-center gap-1\"\r\n (click)=\"downloadWithLabel()\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n style=\"width: 1rem; height: 1rem; flex-shrink: 0\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n >\r\n <path\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n d=\"M4 16v2a2 2 0 002 2h12a2 2 0 002-2v-2M7 10l5 5 5-5M12 15V3\"\r\n />\r\n </svg>\r\n Descargar JPEG\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n" }]
|
|
5140
|
+
}], ctorParameters: () => [], propDecorators: { codigoQr: [{ type: i0.Input, args: [{ isSignal: true, alias: "codigoQr", required: false }] }], labelQr: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelQr", required: false }] }] } });
|
|
5141
|
+
|
|
4858
5142
|
class TokenPurposeLogin {
|
|
4859
5143
|
fb = inject(FormBuilder);
|
|
4860
5144
|
_authorizeService = inject(AuthorizeService);
|
|
@@ -7017,5 +7301,5 @@ function minimumAgeValidator(minimumAge, referenceDate) {
|
|
|
7017
7301
|
* Generated bundle index. Do not edit.
|
|
7018
7302
|
*/
|
|
7019
7303
|
|
|
7020
|
-
export { ACTION_TYPES, AlertaService, AppMessageErrorComponent, ArrowNavigationDirective, AuthorizeService, BaseCRUDService, CACHE_KEYS, CacheService, CssV2Component, DSX_PALETTE, DateIndicator, DocxPreviewComponent, DsxAddToolsModule, DsxButtonComponent, DsxEnableDisable, DsxStatusToggle, DteService, ENVIRONMENT, EndpointService, ErrorHandlerService, FileComponent, GTQFormatter, HttpHelpersService, INITIAL_PARAMETERS, IconDsxComponent, JoinByPipe, JsonHighlightPipe, JsonValuesDebujComponent, JsonViewerComponent, KpicardComponent, LoadingComponent, LoadingLottieComponent, LogoDsxComponent, MasterDetailChangeService, NavbarDsxComponent, NetworkStatusComponent, OnlyRangoPatternDirective, ParameterValuesService, PdfPreviewComponent, PrimeNgModule, SWEET_ALERT_THEMES, SecurityService, SelectAllOnFocusDirective, SpinnerLoadingService, TemplateHighlight, TokenPurposeLogin, TruncatePipe, UtilityAddService, asyncExistsValidator, atLeastOneFieldRequiredValidator, chainControlGroups, createCurrencyFormatter, createInitialCache, createTypedCacheProvider, cuiValidator, dateMinMaxValidator, dateRangeValidator, dateRangeValidatorFromTo, developmentEnvironment, getZeroBasedRolIndex, guardTokenPurposeGuard, httpAuthorizeInterceptor, minimumAgeValidator, nitValidator, productionEnvironment, provideEnvironment, templateVariablesValidator, validateEnvironmentConfig };
|
|
7304
|
+
export { ACTION_TYPES, AlertaService, AppMessageErrorComponent, ArrowNavigationDirective, AuthorizeService, BaseCRUDService, CACHE_KEYS, CacheService, CssV2Component, DSX_PALETTE, DateIndicator, DocxPreviewComponent, DsxAddToolsModule, DsxButtonComponent, DsxEnableDisable, DsxStatusToggle, DteService, ENVIRONMENT, EndpointService, ErrorHandlerService, FileComponent, GTQFormatter, HttpHelpersService, INITIAL_PARAMETERS, IconDsxComponent, JoinByPipe, JsonHighlightPipe, JsonValuesDebujComponent, JsonViewerComponent, KpicardComponent, LoadingComponent, LoadingLottieComponent, LogoDsxComponent, MasterDetailChangeService, NavbarDsxComponent, NetworkStatusComponent, OnlyRangoPatternDirective, ParameterValuesService, PdfPreviewComponent, PrimeNgModule, QrGenerator, QrService, SWEET_ALERT_THEMES, SecurityService, SelectAllOnFocusDirective, SpinnerLoadingService, TemplateHighlight, TokenPurposeLogin, TruncatePipe, UtilityAddService, asyncExistsValidator, atLeastOneFieldRequiredValidator, chainControlGroups, createCurrencyFormatter, createInitialCache, createTypedCacheProvider, cuiValidator, dateMinMaxValidator, dateRangeValidator, dateRangeValidatorFromTo, developmentEnvironment, getZeroBasedRolIndex, guardTokenPurposeGuard, httpAuthorizeInterceptor, minimumAgeValidator, nitValidator, productionEnvironment, provideEnvironment, templateVariablesValidator, validateEnvironmentConfig };
|
|
7021
7305
|
//# sourceMappingURL=ngx-dsxlibrary.mjs.map
|