ngx-dsxlibrary 2.21.47 → 2.21.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ngx-dsxlibrary-src-lib-components.mjs +74 -17
- package/fesm2022/ngx-dsxlibrary-src-lib-components.mjs.map +1 -1
- package/fesm2022/ngx-dsxlibrary.mjs +117 -18
- package/fesm2022/ngx-dsxlibrary.mjs.map +1 -1
- package/ngx-dsxlibrary-2.21.48.tgz +0 -0
- package/package.json +1 -1
- package/types/ngx-dsxlibrary-src-lib-components.d.ts +2 -0
- package/types/ngx-dsxlibrary.d.ts +4 -1
- package/ngx-dsxlibrary-2.21.47.tgz +0 -0
|
@@ -38,8 +38,10 @@ class AppMessageErrorComponent {
|
|
|
38
38
|
elementRef;
|
|
39
39
|
renderer;
|
|
40
40
|
// Espacio vertical reservado bajo el float label cuando hay error visible.
|
|
41
|
-
defaultFloatLabelErrorSpace = '
|
|
42
|
-
templateFloatLabelErrorSpace = '
|
|
41
|
+
defaultFloatLabelErrorSpace = '2.1rem';
|
|
42
|
+
templateFloatLabelErrorSpace = '2.1rem';
|
|
43
|
+
templateFloatLabelLongErrorSpace = '3.4rem';
|
|
44
|
+
templateLongErrorThreshold = 165;
|
|
43
45
|
// Referencia al contenedor PrimeNG padre, si existe.
|
|
44
46
|
floatLabelElement = null;
|
|
45
47
|
// Se conserva el estilo inline original para restaurarlo al ocultar/destruir.
|
|
@@ -110,17 +112,27 @@ class AppMessageErrorComponent {
|
|
|
110
112
|
return !!this.control.touched;
|
|
111
113
|
}
|
|
112
114
|
getFloatLabelErrorSpace() {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
+
const templateError = this.control?.errors?.['invalidTemplateVariables'] ||
|
|
116
|
+
this.control?.errors?.['invalidTemplateStructure'];
|
|
117
|
+
if (templateError) {
|
|
118
|
+
const errorData = templateError;
|
|
119
|
+
const firstDetail = Array.isArray(errorData.details)
|
|
120
|
+
? (errorData.details[0] ?? '')
|
|
121
|
+
: '';
|
|
122
|
+
const messageLength = `${errorData.message ?? ''} ${firstDetail}`.trim()
|
|
123
|
+
.length;
|
|
124
|
+
return messageLength > this.templateLongErrorThreshold
|
|
125
|
+
? this.templateFloatLabelLongErrorSpace
|
|
126
|
+
: this.templateFloatLabelErrorSpace;
|
|
115
127
|
}
|
|
116
128
|
return this.defaultFloatLabelErrorSpace;
|
|
117
129
|
}
|
|
118
130
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: AppMessageErrorComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
|
119
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: AppMessageErrorComponent, isStandalone: true, selector: "app-message-error", inputs: { control: "control", form: "form" }, ngImport: i0, template: "<div class=\"dsx-error-slot\" [class.is-visible]=\"isControlErrorVisible()\">\r\n @if (isControlErrorVisible()) {\r\n <div class=\"dsx-error-message\">\r\n <i\r\n class=\"pi pi-exclamation-triangle dsx-error-icon\"\r\n aria-hidden=\"true\"\r\n ></i>\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 } @else if (control?.errors?.[\"invalidCUI\"]) {\r\n <strong>{{ control?.errors?.[\"invalidCUI\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"invalidDateRange\"]) {\r\n <strong>{{ control?.errors?.[\"invalidDateRange\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"dateNotRange\"]) {\r\n <strong>{{ control?.errors?.[\"dateNotRange\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"invalidDate\"]) {\r\n <strong>{{ control?.errors?.[\"invalidDate\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"minimumAge\"]) {\r\n <strong>{{ control?.errors?.[\"minimumAge\"]?.message }}</strong>\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\u00E1ximo\r\n <strong>{{ control?.errors?.[\"maxlength\"]?.requiredLength }}</strong>\r\n caracteres.\r\n } @else if (control?.errors?.[\"min\"]) {\r\n El valor m\u00EDnimo permitido es\r\n <strong>{{ control?.errors?.[\"min\"]?.min }}</strong>\r\n } @else if (control?.errors?.[\"max\"]) {\r\n El valor m\u00E1ximo permitido es\r\n <strong>{{ control?.errors?.[\"max\"]?.max | number: \"1.2-2\" }}</strong>\r\n } @else if (control?.errors?.[\"email\"]) {\r\n Debe ser una direcci\u00F3n de correo v\u00E1lida.\r\n } @else if (control?.errors?.[\"pattern\"]) {\r\n El campo no tiene el formato requerido.\r\n } @else if (control?.errors?.[\"alreadyValueExists\"]) {\r\n <strong>{{ control?.errors?.[\"alreadyValueExists\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"invalidTemplateVariables\"]) {\r\n <div class=\"dsx-template-error\">\r\n <strong>\r\n {{ control?.errors?.[\"invalidTemplateVariables\"]?.message }}\r\n </strong>\r\n @if (control?.errors?.[\"invalidTemplateVariables\"]?.details?.length) {\r\n <span class=\"dsx-template-error-detail\">\r\n {{ control?.errors?.[\"invalidTemplateVariables\"]?.details?.[0] }}\r\n </span>\r\n }\r\n </div>\r\n } @else {\r\n Existe un error a\u00FAn 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", styles: [":host{display:block}.dsx-error-slot{max-height:0;margin-top:0;overflow:hidden;opacity:0;transition:max-height .22s ease,margin-top .22s ease,opacity .18s ease}.dsx-error-slot.is-visible{max-height:
|
|
131
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: AppMessageErrorComponent, isStandalone: true, selector: "app-message-error", inputs: { control: "control", form: "form" }, ngImport: i0, template: "<div class=\"dsx-error-slot\" [class.is-visible]=\"isControlErrorVisible()\">\r\n @if (isControlErrorVisible()) {\r\n <div class=\"dsx-error-message\">\r\n <i\r\n class=\"pi pi-exclamation-triangle dsx-error-icon\"\r\n aria-hidden=\"true\"\r\n ></i>\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 } @else if (control?.errors?.[\"invalidCUI\"]) {\r\n <strong>{{ control?.errors?.[\"invalidCUI\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"invalidDateRange\"]) {\r\n <strong>{{ control?.errors?.[\"invalidDateRange\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"dateNotRange\"]) {\r\n <strong>{{ control?.errors?.[\"dateNotRange\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"invalidDate\"]) {\r\n <strong>{{ control?.errors?.[\"invalidDate\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"minimumAge\"]) {\r\n <strong>{{ control?.errors?.[\"minimumAge\"]?.message }}</strong>\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\u00E1ximo\r\n <strong>{{ control?.errors?.[\"maxlength\"]?.requiredLength }}</strong>\r\n caracteres.\r\n } @else if (control?.errors?.[\"min\"]) {\r\n El valor m\u00EDnimo permitido es\r\n <strong>{{ control?.errors?.[\"min\"]?.min }}</strong>\r\n } @else if (control?.errors?.[\"max\"]) {\r\n El valor m\u00E1ximo permitido es\r\n <strong>{{ control?.errors?.[\"max\"]?.max | number: \"1.2-2\" }}</strong>\r\n } @else if (control?.errors?.[\"email\"]) {\r\n Debe ser una direcci\u00F3n de correo v\u00E1lida.\r\n } @else if (control?.errors?.[\"pattern\"]) {\r\n El campo no tiene el formato requerido.\r\n } @else if (control?.errors?.[\"alreadyValueExists\"]) {\r\n <strong>{{ control?.errors?.[\"alreadyValueExists\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"invalidTemplateVariables\"]) {\r\n <div class=\"dsx-template-error\">\r\n <strong>\r\n {{ control?.errors?.[\"invalidTemplateVariables\"]?.message }}\r\n </strong>\r\n @if (control?.errors?.[\"invalidTemplateVariables\"]?.details?.length) {\r\n <span class=\"dsx-template-error-detail\">\r\n {{ control?.errors?.[\"invalidTemplateVariables\"]?.details?.[0] }}\r\n </span>\r\n }\r\n </div>\r\n } @else if (control?.errors?.[\"invalidTemplateStructure\"]) {\r\n <div class=\"dsx-template-error\">\r\n <strong>\r\n {{ control?.errors?.[\"invalidTemplateStructure\"]?.message }}\r\n </strong>\r\n @if (control?.errors?.[\"invalidTemplateStructure\"]?.details?.length) {\r\n <span class=\"dsx-template-error-detail\">\r\n {{ control?.errors?.[\"invalidTemplateStructure\"]?.details?.[0] }}\r\n </span>\r\n }\r\n </div>\r\n } @else {\r\n Existe un error a\u00FAn 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", styles: [":host{display:block}.dsx-error-slot{max-height:0;margin-top:0;overflow:hidden;opacity:0;transition:max-height .22s ease,margin-top .22s ease,opacity .18s ease}.dsx-error-slot.is-visible{max-height:7.5rem;margin-top:.3rem;opacity:1}.dsx-error-message{--dsx-error-color: #b42318;--dsx-error-bg: #fff2f0;color:var(--dsx-error-color);font-family:Roboto,Montserrat,sans-serif;font-size:clamp(.75rem,.72rem + .12vw,.8125rem);font-weight:400;line-height:1.35;letter-spacing:.01em;display:flex;align-items:flex-start;gap:.35rem;position:relative;z-index:1;padding:.2rem .45rem;border-left:3px solid var(--dsx-error-color);border-radius:0 6px 6px 0;background:var(--dsx-error-bg);box-shadow:0 1px 2px #00000014;width:100%;max-width:100%;white-space:normal;word-break:break-word;overflow-wrap:anywhere;transform:translateY(-2px);transition:transform .2s ease}.dsx-error-message strong{font-weight:500}.dsx-error-icon{font-style:normal;flex-shrink:0;font-size:.78rem;line-height:1;color:var(--dsx-error-color);margin-top:.08rem}.dsx-error-slot.is-visible .dsx-error-message{transform:translateY(0)}@media(max-width:640px){.dsx-error-slot.is-visible{max-height:9rem}.dsx-error-message{max-width:100%}}:host-context(.p-floatlabel){position:absolute;top:100%;left:0;width:100%;z-index:3;pointer-events:none}:host-context(.p-floatlabel) .dsx-error-slot{max-height:none;margin-top:.25rem;overflow:visible;opacity:0;transform:translateY(-3px);transition:opacity .16s ease,transform .18s ease}:host-context(.p-floatlabel) .dsx-error-slot.is-visible{opacity:1;transform:translateY(0)}:host-context(.p-floatlabel) .dsx-error-message{width:calc(100% - .25rem);max-width:calc(100% - .25rem)}\n"], dependencies: [{ kind: "ngmodule", type: TagModule }, { kind: "component", type: i1.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "pipe", type: DecimalPipe, name: "number" }] });
|
|
120
132
|
}
|
|
121
133
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: AppMessageErrorComponent, decorators: [{
|
|
122
134
|
type: Component,
|
|
123
|
-
args: [{ selector: 'app-message-error', imports: [TagModule, DecimalPipe], template: "<div class=\"dsx-error-slot\" [class.is-visible]=\"isControlErrorVisible()\">\r\n @if (isControlErrorVisible()) {\r\n <div class=\"dsx-error-message\">\r\n <i\r\n class=\"pi pi-exclamation-triangle dsx-error-icon\"\r\n aria-hidden=\"true\"\r\n ></i>\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 } @else if (control?.errors?.[\"invalidCUI\"]) {\r\n <strong>{{ control?.errors?.[\"invalidCUI\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"invalidDateRange\"]) {\r\n <strong>{{ control?.errors?.[\"invalidDateRange\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"dateNotRange\"]) {\r\n <strong>{{ control?.errors?.[\"dateNotRange\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"invalidDate\"]) {\r\n <strong>{{ control?.errors?.[\"invalidDate\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"minimumAge\"]) {\r\n <strong>{{ control?.errors?.[\"minimumAge\"]?.message }}</strong>\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\u00E1ximo\r\n <strong>{{ control?.errors?.[\"maxlength\"]?.requiredLength }}</strong>\r\n caracteres.\r\n } @else if (control?.errors?.[\"min\"]) {\r\n El valor m\u00EDnimo permitido es\r\n <strong>{{ control?.errors?.[\"min\"]?.min }}</strong>\r\n } @else if (control?.errors?.[\"max\"]) {\r\n El valor m\u00E1ximo permitido es\r\n <strong>{{ control?.errors?.[\"max\"]?.max | number: \"1.2-2\" }}</strong>\r\n } @else if (control?.errors?.[\"email\"]) {\r\n Debe ser una direcci\u00F3n de correo v\u00E1lida.\r\n } @else if (control?.errors?.[\"pattern\"]) {\r\n El campo no tiene el formato requerido.\r\n } @else if (control?.errors?.[\"alreadyValueExists\"]) {\r\n <strong>{{ control?.errors?.[\"alreadyValueExists\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"invalidTemplateVariables\"]) {\r\n <div class=\"dsx-template-error\">\r\n <strong>\r\n {{ control?.errors?.[\"invalidTemplateVariables\"]?.message }}\r\n </strong>\r\n @if (control?.errors?.[\"invalidTemplateVariables\"]?.details?.length) {\r\n <span class=\"dsx-template-error-detail\">\r\n {{ control?.errors?.[\"invalidTemplateVariables\"]?.details?.[0] }}\r\n </span>\r\n }\r\n </div>\r\n } @else {\r\n Existe un error a\u00FAn 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", styles: [":host{display:block}.dsx-error-slot{max-height:0;margin-top:0;overflow:hidden;opacity:0;transition:max-height .22s ease,margin-top .22s ease,opacity .18s ease}.dsx-error-slot.is-visible{max-height:
|
|
135
|
+
args: [{ selector: 'app-message-error', imports: [TagModule, DecimalPipe], template: "<div class=\"dsx-error-slot\" [class.is-visible]=\"isControlErrorVisible()\">\r\n @if (isControlErrorVisible()) {\r\n <div class=\"dsx-error-message\">\r\n <i\r\n class=\"pi pi-exclamation-triangle dsx-error-icon\"\r\n aria-hidden=\"true\"\r\n ></i>\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 } @else if (control?.errors?.[\"invalidCUI\"]) {\r\n <strong>{{ control?.errors?.[\"invalidCUI\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"invalidDateRange\"]) {\r\n <strong>{{ control?.errors?.[\"invalidDateRange\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"dateNotRange\"]) {\r\n <strong>{{ control?.errors?.[\"dateNotRange\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"invalidDate\"]) {\r\n <strong>{{ control?.errors?.[\"invalidDate\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"minimumAge\"]) {\r\n <strong>{{ control?.errors?.[\"minimumAge\"]?.message }}</strong>\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\u00E1ximo\r\n <strong>{{ control?.errors?.[\"maxlength\"]?.requiredLength }}</strong>\r\n caracteres.\r\n } @else if (control?.errors?.[\"min\"]) {\r\n El valor m\u00EDnimo permitido es\r\n <strong>{{ control?.errors?.[\"min\"]?.min }}</strong>\r\n } @else if (control?.errors?.[\"max\"]) {\r\n El valor m\u00E1ximo permitido es\r\n <strong>{{ control?.errors?.[\"max\"]?.max | number: \"1.2-2\" }}</strong>\r\n } @else if (control?.errors?.[\"email\"]) {\r\n Debe ser una direcci\u00F3n de correo v\u00E1lida.\r\n } @else if (control?.errors?.[\"pattern\"]) {\r\n El campo no tiene el formato requerido.\r\n } @else if (control?.errors?.[\"alreadyValueExists\"]) {\r\n <strong>{{ control?.errors?.[\"alreadyValueExists\"]?.message }}</strong>\r\n } @else if (control?.errors?.[\"invalidTemplateVariables\"]) {\r\n <div class=\"dsx-template-error\">\r\n <strong>\r\n {{ control?.errors?.[\"invalidTemplateVariables\"]?.message }}\r\n </strong>\r\n @if (control?.errors?.[\"invalidTemplateVariables\"]?.details?.length) {\r\n <span class=\"dsx-template-error-detail\">\r\n {{ control?.errors?.[\"invalidTemplateVariables\"]?.details?.[0] }}\r\n </span>\r\n }\r\n </div>\r\n } @else if (control?.errors?.[\"invalidTemplateStructure\"]) {\r\n <div class=\"dsx-template-error\">\r\n <strong>\r\n {{ control?.errors?.[\"invalidTemplateStructure\"]?.message }}\r\n </strong>\r\n @if (control?.errors?.[\"invalidTemplateStructure\"]?.details?.length) {\r\n <span class=\"dsx-template-error-detail\">\r\n {{ control?.errors?.[\"invalidTemplateStructure\"]?.details?.[0] }}\r\n </span>\r\n }\r\n </div>\r\n } @else {\r\n Existe un error a\u00FAn 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", styles: [":host{display:block}.dsx-error-slot{max-height:0;margin-top:0;overflow:hidden;opacity:0;transition:max-height .22s ease,margin-top .22s ease,opacity .18s ease}.dsx-error-slot.is-visible{max-height:7.5rem;margin-top:.3rem;opacity:1}.dsx-error-message{--dsx-error-color: #b42318;--dsx-error-bg: #fff2f0;color:var(--dsx-error-color);font-family:Roboto,Montserrat,sans-serif;font-size:clamp(.75rem,.72rem + .12vw,.8125rem);font-weight:400;line-height:1.35;letter-spacing:.01em;display:flex;align-items:flex-start;gap:.35rem;position:relative;z-index:1;padding:.2rem .45rem;border-left:3px solid var(--dsx-error-color);border-radius:0 6px 6px 0;background:var(--dsx-error-bg);box-shadow:0 1px 2px #00000014;width:100%;max-width:100%;white-space:normal;word-break:break-word;overflow-wrap:anywhere;transform:translateY(-2px);transition:transform .2s ease}.dsx-error-message strong{font-weight:500}.dsx-error-icon{font-style:normal;flex-shrink:0;font-size:.78rem;line-height:1;color:var(--dsx-error-color);margin-top:.08rem}.dsx-error-slot.is-visible .dsx-error-message{transform:translateY(0)}@media(max-width:640px){.dsx-error-slot.is-visible{max-height:9rem}.dsx-error-message{max-width:100%}}:host-context(.p-floatlabel){position:absolute;top:100%;left:0;width:100%;z-index:3;pointer-events:none}:host-context(.p-floatlabel) .dsx-error-slot{max-height:none;margin-top:.25rem;overflow:visible;opacity:0;transform:translateY(-3px);transition:opacity .16s ease,transform .18s ease}:host-context(.p-floatlabel) .dsx-error-slot.is-visible{opacity:1;transform:translateY(0)}:host-context(.p-floatlabel) .dsx-error-message{width:calc(100% - .25rem);max-width:calc(100% - .25rem)}\n"] }]
|
|
124
136
|
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { control: [{
|
|
125
137
|
type: Input
|
|
126
138
|
}], form: [{
|
|
@@ -1101,30 +1113,71 @@ class TemplateHighlight {
|
|
|
1101
1113
|
processText(raw, allowedKeys) {
|
|
1102
1114
|
if (!raw)
|
|
1103
1115
|
return '';
|
|
1104
|
-
// Primero marcamos
|
|
1116
|
+
// Primero marcamos variables y etiquetas en el texto crudo usando placeholders.
|
|
1105
1117
|
const spanMap = new Map();
|
|
1106
1118
|
let idx = 0;
|
|
1107
|
-
let result =
|
|
1119
|
+
let result = raw;
|
|
1120
|
+
// Variables {{...}}
|
|
1108
1121
|
result = result.replace(/{{(.*?)}}/g, (match, content) => {
|
|
1109
1122
|
const trimmed = content.trim();
|
|
1110
1123
|
let span;
|
|
1111
1124
|
if (content !== trimmed) {
|
|
1112
|
-
span = `<span class="var-invalid" title="Espacios inválidos">${this.
|
|
1125
|
+
span = `<span class="var-invalid" title="Espacios inválidos">${this.escapeHtml(match)}</span>`;
|
|
1113
1126
|
}
|
|
1114
1127
|
else if (!/^[A-Z0-9_]+$/.test(trimmed)) {
|
|
1115
|
-
span = `<span class="var-invalid" title="Formato inválido">${this.
|
|
1128
|
+
span = `<span class="var-invalid" title="Formato inválido">${this.escapeHtml(match)}</span>`;
|
|
1116
1129
|
}
|
|
1117
1130
|
else if (!allowedKeys.includes(trimmed)) {
|
|
1118
|
-
span = `<span class="var-invalid" title="Variable no definida">${this.
|
|
1131
|
+
span = `<span class="var-invalid" title="Variable no definida">${this.escapeHtml(match)}</span>`;
|
|
1119
1132
|
}
|
|
1120
1133
|
else {
|
|
1121
|
-
span = `<span class="var-valid">${this.
|
|
1134
|
+
span = `<span class="var-valid">${this.escapeHtml(match)}</span>`;
|
|
1122
1135
|
}
|
|
1123
|
-
const placeholder =
|
|
1136
|
+
const placeholder = `__SPAN_${idx++}__`;
|
|
1124
1137
|
spanMap.set(placeholder, span);
|
|
1125
1138
|
return placeholder;
|
|
1126
1139
|
});
|
|
1127
|
-
//
|
|
1140
|
+
// Etiquetas estructurales: <negrita>, </negrita>, </salto>
|
|
1141
|
+
const tagRegex = /<[^>\n]+>/g;
|
|
1142
|
+
const allowedTags = new Set(['<negrita>', '</negrita>', '</salto>']);
|
|
1143
|
+
const tagMatches = [...raw.matchAll(tagRegex)];
|
|
1144
|
+
const invalidTagReasonByIndex = new Map();
|
|
1145
|
+
const negritaStack = [];
|
|
1146
|
+
for (let i = 0; i < tagMatches.length; i++) {
|
|
1147
|
+
const tag = tagMatches[i][0];
|
|
1148
|
+
if (!allowedTags.has(tag)) {
|
|
1149
|
+
invalidTagReasonByIndex.set(i, `Etiqueta inválida: "${tag}". Etiquetas permitidas: <negrita>, </negrita>, </salto>.`);
|
|
1150
|
+
continue;
|
|
1151
|
+
}
|
|
1152
|
+
if (tag === '<negrita>') {
|
|
1153
|
+
negritaStack.push(i);
|
|
1154
|
+
continue;
|
|
1155
|
+
}
|
|
1156
|
+
if (tag === '</negrita>' && negritaStack.length === 0) {
|
|
1157
|
+
invalidTagReasonByIndex.set(i, 'Estructura incorrecta: Se encontró "</negrita>" sin una apertura "<negrita>" previa.');
|
|
1158
|
+
continue;
|
|
1159
|
+
}
|
|
1160
|
+
if (tag === '</negrita>') {
|
|
1161
|
+
negritaStack.pop();
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
for (const openTagIndex of negritaStack) {
|
|
1165
|
+
invalidTagReasonByIndex.set(openTagIndex, 'Estructura incorrecta: Falta cerrar una o más etiquetas "</negrita>".');
|
|
1166
|
+
}
|
|
1167
|
+
let tagIndex = 0;
|
|
1168
|
+
result = result.replace(tagRegex, (tag) => {
|
|
1169
|
+
const reason = invalidTagReasonByIndex.get(tagIndex);
|
|
1170
|
+
const span = reason
|
|
1171
|
+
? `<span class="tag-invalid" title="${this.escapeAttr(reason)}">${this.escapeHtml(tag)}</span>`
|
|
1172
|
+
: `<span class="tag-valid">${this.escapeHtml(tag)}</span>`;
|
|
1173
|
+
const placeholder = `__SPAN_${idx++}__`;
|
|
1174
|
+
spanMap.set(placeholder, span);
|
|
1175
|
+
tagIndex += 1;
|
|
1176
|
+
return placeholder;
|
|
1177
|
+
});
|
|
1178
|
+
// Escapamos el resto del texto (fuera de placeholders).
|
|
1179
|
+
result = this.escapeHtml(result);
|
|
1180
|
+
// Ahora marcamos llaves sueltas: {{ o }} que no estén en pareja de variable.
|
|
1128
1181
|
result = result.replace(/{{|}}/g, (m) => {
|
|
1129
1182
|
return `<span class="var-brace-error" title="Llave desbalanceada">${m}</span>`;
|
|
1130
1183
|
});
|
|
@@ -1143,14 +1196,18 @@ class TemplateHighlight {
|
|
|
1143
1196
|
.replace(/>/g, '>');
|
|
1144
1197
|
}
|
|
1145
1198
|
escapeAttr(text) {
|
|
1146
|
-
return text
|
|
1199
|
+
return text
|
|
1200
|
+
.replace(/&/g, '&')
|
|
1201
|
+
.replace(/"/g, '"')
|
|
1202
|
+
.replace(/</g, '<')
|
|
1203
|
+
.replace(/>/g, '>');
|
|
1147
1204
|
}
|
|
1148
1205
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: TemplateHighlight, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1149
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: TemplateHighlight, isStandalone: true, selector: "dsx-template-highlight", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null }, allowedKeys: { classPropertyName: "allowedKeys", publicName: "allowedKeys", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<p-tabs value=\"0\">\r\n <p-tablist>\r\n <p-tab value=\"0\">\r\n <i class=\"pi pi-file-edit tab-icon\" aria-hidden=\"true\"></i>\r\n <span>Preliminar</span>\r\n </p-tab>\r\n <p-tab value=\"1\">\r\n <i class=\"pi pi-list tab-icon\" aria-hidden=\"true\"></i>\r\n <span>Variables</span>\r\n </p-tab>\r\n </p-tablist>\r\n <p-tabpanels>\r\n <p-tabpanel value=\"0\">\r\n <div class=\"template-highlight\" [innerHTML]=\"highlightedText()\"></div>\r\n </p-tabpanel>\r\n <p-tabpanel value=\"1\">\r\n @if (allowedKeys().length) {\r\n <ul class=\"template-vars-list\">\r\n @for (key of allowedKeys(); track key) {\r\n <li>\r\n <strong>{{ key }}</strong>\r\n </li>\r\n }\r\n </ul>\r\n }\r\n </p-tabpanel>\r\n </p-tabpanels>\r\n</p-tabs>\r\n", styles: [":host .template-highlight{white-space:pre-wrap;font-family:monospace;text-align:justify}:host .template-vars-list{margin:0 0 .65rem;padding-left:1rem}:host .template-vars-list li{margin:.15rem 0}:host .tab-icon{margin-right:.45rem}:host ::ng-deep .var-valid{color:#0a7a0a;background:#e6ffe6;border-radius:3px;padding:0 2px;font-weight:600}:host ::ng-deep .var-invalid{color:#b30000;background:#ffe6e6;border-radius:3px;padding:0 2px;font-weight:600;text-decoration:underline wavy #b30000;cursor:help}:host ::ng-deep .var-brace-error{color:#cc7a00;background:#fff2cc;border-radius:3px;padding:0 2px;font-weight:600}\n"], dependencies: [{ kind: "ngmodule", type: TabsModule }, { kind: "component", type: i1$5.Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: i1$5.TabPanels, selector: "p-tabpanels" }, { kind: "component", type: i1$5.TabPanel, selector: "p-tabpanel", inputs: ["lazy", "value"], outputs: ["valueChange"] }, { kind: "component", type: i1$5.TabList, selector: "p-tablist" }, { kind: "component", type: i1$5.Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }] });
|
|
1206
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: TemplateHighlight, isStandalone: true, selector: "dsx-template-highlight", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null }, allowedKeys: { classPropertyName: "allowedKeys", publicName: "allowedKeys", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<p-tabs value=\"0\">\r\n <p-tablist>\r\n <p-tab value=\"0\">\r\n <i class=\"pi pi-file-edit tab-icon\" aria-hidden=\"true\"></i>\r\n <span>Preliminar</span>\r\n </p-tab>\r\n <p-tab value=\"1\">\r\n <i class=\"pi pi-list tab-icon\" aria-hidden=\"true\"></i>\r\n <span>Variables</span>\r\n </p-tab>\r\n </p-tablist>\r\n <p-tabpanels>\r\n <p-tabpanel value=\"0\">\r\n <div class=\"template-highlight\" [innerHTML]=\"highlightedText()\"></div>\r\n </p-tabpanel>\r\n <p-tabpanel value=\"1\">\r\n @if (allowedKeys().length) {\r\n <ul class=\"template-vars-list\">\r\n @for (key of allowedKeys(); track key) {\r\n <li>\r\n <strong>{{ key }}</strong>\r\n </li>\r\n }\r\n </ul>\r\n }\r\n </p-tabpanel>\r\n </p-tabpanels>\r\n</p-tabs>\r\n", styles: [":host .template-highlight{white-space:pre-wrap;font-family:monospace;text-align:justify}:host .template-vars-list{margin:0 0 .65rem;padding-left:1rem}:host .template-vars-list li{margin:.15rem 0}:host .tab-icon{margin-right:.45rem}:host ::ng-deep .var-valid{color:#0a7a0a;background:#e6ffe6;border-radius:3px;padding:0 2px;font-weight:600}:host ::ng-deep .var-invalid{color:#b30000;background:#ffe6e6;border-radius:3px;padding:0 2px;font-weight:600;text-decoration:underline wavy #b30000;cursor:help}:host ::ng-deep .var-brace-error{color:#cc7a00;background:#fff2cc;border-radius:3px;padding:0 2px;font-weight:600}:host ::ng-deep .tag-valid{color:#0a6c74;background:#e6f7f8;border-radius:3px;padding:0 2px;font-weight:600}:host ::ng-deep .tag-invalid{color:#ad4e00;background:#fff3e8;border-radius:3px;padding:0 2px;font-weight:600;text-decoration:underline wavy #ad4e00;cursor:help}\n"], dependencies: [{ kind: "ngmodule", type: TabsModule }, { kind: "component", type: i1$5.Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: i1$5.TabPanels, selector: "p-tabpanels" }, { kind: "component", type: i1$5.TabPanel, selector: "p-tabpanel", inputs: ["lazy", "value"], outputs: ["valueChange"] }, { kind: "component", type: i1$5.TabList, selector: "p-tablist" }, { kind: "component", type: i1$5.Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }] });
|
|
1150
1207
|
}
|
|
1151
1208
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: TemplateHighlight, decorators: [{
|
|
1152
1209
|
type: Component,
|
|
1153
|
-
args: [{ selector: 'dsx-template-highlight', imports: [TabsModule], template: "<p-tabs value=\"0\">\r\n <p-tablist>\r\n <p-tab value=\"0\">\r\n <i class=\"pi pi-file-edit tab-icon\" aria-hidden=\"true\"></i>\r\n <span>Preliminar</span>\r\n </p-tab>\r\n <p-tab value=\"1\">\r\n <i class=\"pi pi-list tab-icon\" aria-hidden=\"true\"></i>\r\n <span>Variables</span>\r\n </p-tab>\r\n </p-tablist>\r\n <p-tabpanels>\r\n <p-tabpanel value=\"0\">\r\n <div class=\"template-highlight\" [innerHTML]=\"highlightedText()\"></div>\r\n </p-tabpanel>\r\n <p-tabpanel value=\"1\">\r\n @if (allowedKeys().length) {\r\n <ul class=\"template-vars-list\">\r\n @for (key of allowedKeys(); track key) {\r\n <li>\r\n <strong>{{ key }}</strong>\r\n </li>\r\n }\r\n </ul>\r\n }\r\n </p-tabpanel>\r\n </p-tabpanels>\r\n</p-tabs>\r\n", styles: [":host .template-highlight{white-space:pre-wrap;font-family:monospace;text-align:justify}:host .template-vars-list{margin:0 0 .65rem;padding-left:1rem}:host .template-vars-list li{margin:.15rem 0}:host .tab-icon{margin-right:.45rem}:host ::ng-deep .var-valid{color:#0a7a0a;background:#e6ffe6;border-radius:3px;padding:0 2px;font-weight:600}:host ::ng-deep .var-invalid{color:#b30000;background:#ffe6e6;border-radius:3px;padding:0 2px;font-weight:600;text-decoration:underline wavy #b30000;cursor:help}:host ::ng-deep .var-brace-error{color:#cc7a00;background:#fff2cc;border-radius:3px;padding:0 2px;font-weight:600}\n"] }]
|
|
1210
|
+
args: [{ selector: 'dsx-template-highlight', imports: [TabsModule], template: "<p-tabs value=\"0\">\r\n <p-tablist>\r\n <p-tab value=\"0\">\r\n <i class=\"pi pi-file-edit tab-icon\" aria-hidden=\"true\"></i>\r\n <span>Preliminar</span>\r\n </p-tab>\r\n <p-tab value=\"1\">\r\n <i class=\"pi pi-list tab-icon\" aria-hidden=\"true\"></i>\r\n <span>Variables</span>\r\n </p-tab>\r\n </p-tablist>\r\n <p-tabpanels>\r\n <p-tabpanel value=\"0\">\r\n <div class=\"template-highlight\" [innerHTML]=\"highlightedText()\"></div>\r\n </p-tabpanel>\r\n <p-tabpanel value=\"1\">\r\n @if (allowedKeys().length) {\r\n <ul class=\"template-vars-list\">\r\n @for (key of allowedKeys(); track key) {\r\n <li>\r\n <strong>{{ key }}</strong>\r\n </li>\r\n }\r\n </ul>\r\n }\r\n </p-tabpanel>\r\n </p-tabpanels>\r\n</p-tabs>\r\n", styles: [":host .template-highlight{white-space:pre-wrap;font-family:monospace;text-align:justify}:host .template-vars-list{margin:0 0 .65rem;padding-left:1rem}:host .template-vars-list li{margin:.15rem 0}:host .tab-icon{margin-right:.45rem}:host ::ng-deep .var-valid{color:#0a7a0a;background:#e6ffe6;border-radius:3px;padding:0 2px;font-weight:600}:host ::ng-deep .var-invalid{color:#b30000;background:#ffe6e6;border-radius:3px;padding:0 2px;font-weight:600;text-decoration:underline wavy #b30000;cursor:help}:host ::ng-deep .var-brace-error{color:#cc7a00;background:#fff2cc;border-radius:3px;padding:0 2px;font-weight:600}:host ::ng-deep .tag-valid{color:#0a6c74;background:#e6f7f8;border-radius:3px;padding:0 2px;font-weight:600}:host ::ng-deep .tag-invalid{color:#ad4e00;background:#fff3e8;border-radius:3px;padding:0 2px;font-weight:600;text-decoration:underline wavy #ad4e00;cursor:help}\n"] }]
|
|
1154
1211
|
}], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: false }] }], allowedKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowedKeys", required: false }] }] } });
|
|
1155
1212
|
|
|
1156
1213
|
/**
|