Merge branch 'main' into cliente/tagumedica
This commit is contained in:
commit
b7c684d39e
6 files changed
+27
-7
No files matched your search
@@ -24,7 +24,8 @@ export function parseHtmlValues(def: HtmlReportDef, raw: Readonly<Record<string,
|
|||||||
const missing: string[] = [];
|
const missing: string[] = [];
|
||||||
for (const p of def.params) {
|
for (const p of def.params) {
|
||||||
const v = raw[p.name];
|
const v = raw[p.name];
|
||||||
let text = typeof v === 'string' ? v.trim() : typeof v === 'number' ? String(v) : '';
|
// un parámetro de solo lectura vale siempre su valor por defecto, escriba lo que escriba el cliente
|
||||||
|
let text = p.readOnly ? '' : typeof v === 'string' ? v.trim() : typeof v === 'number' ? String(v) : '';
|
||||||
if (text === '') text = p.defaultValue ?? '';
|
if (text === '') text = p.defaultValue ?? '';
|
||||||
if (text === '') {
|
if (text === '') {
|
||||||
if (p.required) missing.push(p.label);
|
if (p.required) missing.push(p.label);
|
||||||
|
|||||||
@@ -48,11 +48,18 @@ describe('registro de reportes HTML', () => {
|
|||||||
expect(() => validateHtmlReports([{ ...def, params: [P({ name: 'a' }), P({ name: 'a' })] }])).toThrow(/repite el parámetro/);
|
expect(() => validateHtmlReports([{ ...def, params: [P({ name: 'a' }), P({ name: 'a' })] }])).toThrow(/repite el parámetro/);
|
||||||
expect(() => validateHtmlReports([{ ...def, template: '../fuera.njk' }])).toThrow(/dentro de la carpeta/);
|
expect(() => validateHtmlReports([{ ...def, template: '../fuera.njk' }])).toThrow(/dentro de la carpeta/);
|
||||||
expect(() => validateHtmlReports([{ ...def, template: '/etc/passwd' }])).toThrow(/dentro de la carpeta/);
|
expect(() => validateHtmlReports([{ ...def, template: '/etc/passwd' }])).toThrow(/dentro de la carpeta/);
|
||||||
|
expect(() => validateHtmlReports([{ ...def, params: [P({ name: 'papel', readOnly: true })] }])).toThrow(/solo lectura y necesita un valor por defecto/);
|
||||||
expect(validateHtmlReports([def])).toHaveLength(1);
|
expect(validateHtmlReports([def])).toHaveLength(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('valores de los parámetros', () => {
|
describe('valores de los parámetros', () => {
|
||||||
|
it('un parámetro de solo lectura vale siempre su valor por defecto, aunque el cliente mande otro', () => {
|
||||||
|
const fijo = { ...def, params: [P({ name: 'papel', label: 'Papel', kind: 'select', options: [{ value: 'Carta', label: 'Carta' }, { value: 'A4', label: 'A4' }], defaultValue: 'Carta', readOnly: true })] };
|
||||||
|
expect(parseHtmlValues(fijo, {})).toEqual({ papel: 'Carta' });
|
||||||
|
expect(parseHtmlValues(fijo, { papel: 'A4' })).toEqual({ papel: 'Carta' });
|
||||||
|
});
|
||||||
|
|
||||||
it('exige los obligatorios, aplica el valor por defecto y comprueba tipos', () => {
|
it('exige los obligatorios, aplica el valor por defecto y comprueba tipos', () => {
|
||||||
expect(parseHtmlValues(def, { doc: '144153', cantidad: 6 })).toEqual({ doc: '144153', cantidad: '6', papel: 'Carta', fecha: '' });
|
expect(parseHtmlValues(def, { doc: '144153', cantidad: 6 })).toEqual({ doc: '144153', cantidad: '6', papel: 'Carta', fecha: '' });
|
||||||
expect(() => parseHtmlValues(def, { cantidad: '6' })).toThrow(/Falta indicar: Entrega/);
|
expect(() => parseHtmlValues(def, { cantidad: '6' })).toThrow(/Falta indicar: Entrega/);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export function validateHtmlReports(reports: readonly HtmlReportDef[]): readonly
|
|||||||
for (const p of r.params) {
|
for (const p of r.params) {
|
||||||
if (names.has(p.name)) throw new Error(`El reporte ${r.code} repite el parámetro ${p.name}`);
|
if (names.has(p.name)) throw new Error(`El reporte ${r.code} repite el parámetro ${p.name}`);
|
||||||
names.add(p.name);
|
names.add(p.name);
|
||||||
|
if (p.readOnly && !p.defaultValue) throw new Error(`El parámetro ${p.name} de ${r.code} es de solo lectura y necesita un valor por defecto`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return reports;
|
return reports;
|
||||||
|
|||||||
@@ -60,6 +60,15 @@ describe('ReportParamField', () => {
|
|||||||
expect(select.value).toBe('2');
|
expect(select.value).toBe('2');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('un parámetro de solo lectura se ve con su valor pero no se puede cambiar', async () => {
|
||||||
|
await show(param({ kind: 'select', label: 'Papel', options: [{ value: 'Carta', label: 'Carta' }], readOnly: true }), 'Carta');
|
||||||
|
const select = el().querySelector('select') as HTMLSelectElement;
|
||||||
|
expect(select.value).toBe('Carta');
|
||||||
|
expect(select.disabled || select.hasAttribute('readonly') || select.closest('[readonly]') !== null).toBe(true);
|
||||||
|
await show(param({ label: 'Nombre', readOnly: true }), 'fijo');
|
||||||
|
expect(inputs()[0].readOnly).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
it('un rango pide desde y hasta y los emite como lista', async () => {
|
it('un rango pide desde y hasta y los emite como lista', async () => {
|
||||||
await show(param({ kind: 'date', range: true }), ['2026-01-01', '2026-01-31']);
|
await show(param({ kind: 'date', range: true }), ['2026-01-01', '2026-01-31']);
|
||||||
expect(labels().join(' ')).toContain('desde / hasta');
|
expect(labels().join(' ')).toContain('desde / hasta');
|
||||||
|
|||||||
@@ -24,23 +24,23 @@ const asList = (v: Value): readonly string[] => (typeof v === 'string' ? (v ===
|
|||||||
@case ('single') {
|
@case ('single') {
|
||||||
@switch (p.kind) {
|
@switch (p.kind) {
|
||||||
@case ('number') {
|
@case ('number') {
|
||||||
<sbo-number-field [label]="p.label" [required]="p.required" [value]="num(single())" (valueChange)="value.set($event === null ? '' : '' + $event)" />
|
<sbo-number-field [label]="p.label" [required]="p.required" [readonly]="!!p.readOnly" [value]="num(single())" (valueChange)="value.set($event === null ? '' : '' + $event)" />
|
||||||
}
|
}
|
||||||
@case ('date') {
|
@case ('date') {
|
||||||
<sbo-date-field [label]="p.label" [required]="p.required" [value]="single()" (valueChange)="value.set($event)" />
|
<sbo-date-field [label]="p.label" [required]="p.required" [readonly]="!!p.readOnly" [value]="single()" (valueChange)="value.set($event)" />
|
||||||
}
|
}
|
||||||
@case ('select') {
|
@case ('select') {
|
||||||
<sbo-select-field [label]="p.label" [required]="p.required" [options]="p.options ?? []" placeholder="" [value]="single() || null" (valueChange)="value.set($event === null ? '' : '' + $event)" />
|
<sbo-select-field [label]="p.label" [required]="p.required" [readonly]="!!p.readOnly" [options]="p.options ?? []" placeholder="" [value]="single() || null" (valueChange)="value.set($event === null ? '' : '' + $event)" />
|
||||||
}
|
}
|
||||||
@case ('lookup') {
|
@case ('lookup') {
|
||||||
@if (catalog(); as c) {
|
@if (catalog(); as c) {
|
||||||
<sbo-lookup-field [label]="p.label" [required]="p.required" [lookup]="c.lookup" resolveOnLeave [value]="single()" (valueChange)="value.set($event)" />
|
<sbo-lookup-field [label]="p.label" [required]="p.required" [readonly]="!!p.readOnly" [lookup]="c.lookup" resolveOnLeave [value]="single()" (valueChange)="value.set($event)" />
|
||||||
} @else {
|
} @else {
|
||||||
<sbo-text-field [label]="p.label" [required]="p.required" [value]="single()" (valueChange)="value.set($event)" />
|
<sbo-text-field [label]="p.label" [required]="p.required" [readonly]="!!p.readOnly" [value]="single()" (valueChange)="value.set($event)" />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@default {
|
@default {
|
||||||
<sbo-text-field [label]="p.label" [required]="p.required" [placeholder]="p.placeholder ?? ''" [value]="single()" (valueChange)="value.set($event)" />
|
<sbo-text-field [label]="p.label" [required]="p.required" [readonly]="!!p.readOnly" [placeholder]="p.placeholder ?? ''" [value]="single()" (valueChange)="value.set($event)" />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ export interface GatewayParam {
|
|||||||
/** Se admiten varios valores. */
|
/** Se admiten varios valores. */
|
||||||
multiple?: boolean;
|
multiple?: boolean;
|
||||||
defaultValue?: string;
|
defaultValue?: string;
|
||||||
|
/** Se muestra pero no se edita: vale siempre su valor por defecto (por ejemplo el papel de unas etiquetas precortadas). */
|
||||||
|
readOnly?: boolean;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
/** Opciones de una lista fija (`kind = select`). */
|
/** Opciones de una lista fija (`kind = select`). */
|
||||||
options?: { value: string; label: string }[];
|
options?: { value: string; label: string }[];
|
||||||
|
|||||||
Reference in new issue
Block a user