PDF: Reordenar categorías y evitar truncamiento de familias
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m15s

- Orden: sin hijos → 2 hijos → 3 hijos
- Calcula ancho total de familia antes de renderizar
- Si familia no cabe, salta a siguiente línea completa
This commit is contained in:
2025-11-24 18:04:48 -06:00
parent 63da716ab1
commit ab0dbfb37e
2 changed files with 43 additions and 38 deletions

View File

@@ -230,7 +230,8 @@ function renderizarSeccionFraganciaAroma(
} }
/** /**
* Renderiza categorías con hijos en layout horizontal con wrap * Renderiza categorías con hijos en layout horizontal
* Las familias completas nunca se truncan entre líneas
*/ */
function renderizarCategoriasHorizontal( function renderizarCategoriasHorizontal(
doc: jsPDF, doc: jsPDF,
@@ -242,32 +243,39 @@ function renderizarCategoriasHorizontal(
): void { ): void {
const checkboxSize = 2.5 // Checkbox más pequeño const checkboxSize = 2.5 // Checkbox más pequeño
const rowHeight = 3.8 // Altura de fila const rowHeight = 3.8 // Altura de fila
const familySpacing = 4 // Espacio entre familias (grupos padre+hijos) const familySpacing = 4 // Espacio entre familias
const childIndent = 3 // Indentación para hijos en wrap const itemSpacing = 1 // Espacio entre items dentro de familia
let currentX = x let currentX = x
let currentY = y let currentY = y
doc.setFontSize(PDF_CONFIG.fontSize.tiny)
CATEGORIAS_JERARQUICAS.forEach((cat) => { CATEGORIAS_JERARQUICAS.forEach((cat) => {
const isParentChecked = categoriasSeleccionadas.includes(cat.key as any) // Calcular ancho total de la familia (padre + todos los hijos)
// Calcular ancho necesario para el padre
doc.setFontSize(PDF_CONFIG.fontSize.tiny)
const parentWidth = checkboxSize + 1 + doc.getTextWidth(cat.label) const parentWidth = checkboxSize + 1 + doc.getTextWidth(cat.label)
let familyWidth = parentWidth
// Si no cabe en esta línea, ir a la siguiente if (cat.hijos && cat.hijos.length > 0) {
if (currentX + parentWidth > x + maxWidth && currentX > x) { cat.hijos.forEach((hijo) => {
familyWidth += itemSpacing + checkboxSize + 1 + doc.getTextWidth(hijo.label)
})
}
// Si la familia completa no cabe, ir a la siguiente línea
if (currentX + familyWidth > x + maxWidth && currentX > x) {
currentX = x currentX = x
currentY += rowHeight currentY += rowHeight
} }
// Dibujar checkbox del padre // Renderizar el padre
const isParentChecked = categoriasSeleccionadas.includes(cat.key as any)
dibujarCheckbox(doc, currentX, currentY, isParentChecked, checkboxSize) dibujarCheckbox(doc, currentX, currentY, isParentChecked, checkboxSize)
doc.setFont('helvetica', 'bold') doc.setFont('helvetica', 'bold')
doc.text(cat.label, currentX + checkboxSize + 1, currentY + 2) doc.text(cat.label, currentX + checkboxSize + 1, currentY + 2)
currentX += parentWidth + 1 currentX += parentWidth + itemSpacing
// Si tiene hijos, renderizarlos horizontalmente // Renderizar hijos (si los tiene)
if (cat.hijos && cat.hijos.length > 0) { if (cat.hijos && cat.hijos.length > 0) {
doc.setFont('helvetica', 'normal') doc.setFont('helvetica', 'normal')
@@ -275,15 +283,9 @@ function renderizarCategoriasHorizontal(
const isChildChecked = subcategoriasSeleccionadas.includes(hijo.key) const isChildChecked = subcategoriasSeleccionadas.includes(hijo.key)
const childWidth = checkboxSize + 1 + doc.getTextWidth(hijo.label) const childWidth = checkboxSize + 1 + doc.getTextWidth(hijo.label)
// Si no cabe, wrap a siguiente línea con indentación
if (currentX + childWidth > x + maxWidth) {
currentX = x + childIndent
currentY += rowHeight
}
dibujarCheckbox(doc, currentX, currentY, isChildChecked, checkboxSize) dibujarCheckbox(doc, currentX, currentY, isChildChecked, checkboxSize)
doc.text(hijo.label, currentX + checkboxSize + 1, currentY + 2) doc.text(hijo.label, currentX + checkboxSize + 1, currentY + 2)
currentX += childWidth + 1 currentX += childWidth + itemSpacing
}) })
} }

View File

@@ -165,10 +165,31 @@ export interface CategoriaConHijosPdf {
/** /**
* Categorías de notas para el formulario PDF * Categorías de notas para el formulario PDF
* Estructura jerárquica: padres con hijos que se renderizan horizontalmente * Ordenadas: sin hijos, luego 2 hijos, luego 3 hijos
*/ */
export const CATEGORIAS_JERARQUICAS: CategoriaConHijosPdf[] = [ export const CATEGORIAS_JERARQUICAS: CategoriaConHijosPdf[] = [
// Sin hijos (3)
{ key: 'Floral', label: 'Floral' }, { key: 'Floral', label: 'Floral' },
{ key: 'Verde Vegetal', label: 'Verde/Vegetal' },
{ key: 'Especias', label: 'Especias' },
// Con 2 hijos (2)
{
key: 'Nueces/Cacao',
label: 'Nueces/Cacao',
hijos: [
{ key: 'Nueces', label: 'Nueces' },
{ key: 'Cacao', label: 'Cacao' },
],
},
{
key: 'Dulce',
label: 'Dulce',
hijos: [
{ key: 'Vainilla', label: 'Vainilla' },
{ key: 'Azúcar Morena', label: 'Az.Morena' },
],
},
// Con 3 hijos (3)
{ {
key: 'Afrutado', key: 'Afrutado',
label: 'Afrutado', label: 'Afrutado',
@@ -178,7 +199,6 @@ export const CATEGORIAS_JERARQUICAS: CategoriaConHijosPdf[] = [
{ key: 'Cítricos', label: 'Cítricos' }, { key: 'Cítricos', label: 'Cítricos' },
], ],
}, },
{ key: 'Verde Vegetal', label: 'Verde/Vegetal' },
{ {
key: 'Otro', key: 'Otro',
label: 'Otra', label: 'Otra',
@@ -197,23 +217,6 @@ export const CATEGORIAS_JERARQUICAS: CategoriaConHijosPdf[] = [
{ key: 'Tabaco', label: 'Tabaco' }, { key: 'Tabaco', label: 'Tabaco' },
], ],
}, },
{
key: 'Nueces/Cacao',
label: 'Nueces/Cacao',
hijos: [
{ key: 'Nueces', label: 'Nueces' },
{ key: 'Cacao', label: 'Cacao' },
],
},
{ key: 'Especias', label: 'Especias' },
{
key: 'Dulce',
label: 'Dulce',
hijos: [
{ key: 'Vainilla', label: 'Vainilla' },
{ key: 'Azúcar Morena', label: 'Az.Morena' },
],
},
] ]
/** /**