feat: Variables programáticas en templates

Permite definir variables en templates con sintaxis {{nombre🏷️default}}
- Auto-detección de variables al guardar templates
- Drawer para completar valores al cargar template con variables
- Badge mostrando cantidad de variables en tarjeta de template
- Resolución de variables antes de cargar en cola
This commit is contained in:
2025-11-25 01:57:24 -06:00
parent 05bf0e3c91
commit c7c32d8c54
6 changed files with 214 additions and 13 deletions

View File

@@ -4,9 +4,14 @@ import { existsSync } from 'fs'
import { join } from 'path'
export interface Operation {
id: string
type: 'text' | 'feed' | 'cut' | 'pulse' | 'image' | 'barcode' | 'qrcode'
params: Record<string, unknown>
op: string
[key: string]: any
}
export interface TemplateVariable {
name: string
label?: string
defaultValue?: string
}
export interface PrintTemplate {
@@ -14,10 +19,42 @@ export interface PrintTemplate {
name: string
description?: string
operations: Operation[]
variables: TemplateVariable[]
createdAt: string
updatedAt: string
}
// Regex para detectar {{nombre}}, {{nombre:label}}, {{nombre:label:default}}
const VARIABLE_REGEX = /\{\{(\w+)(?::([^:}]+))?(?::([^}]+))?\}\}/g
// Extraer variables de las operaciones
export function extractVariables(operations: Operation[]): TemplateVariable[] {
const variablesMap = new Map<string, TemplateVariable>()
for (const op of operations) {
// Buscar en campos que pueden contener variables
const searchFields = ['value', 'data']
for (const field of searchFields) {
if (typeof op[field] === 'string') {
const matches = op[field].matchAll(VARIABLE_REGEX)
for (const match of matches) {
const [, name, label, defaultValue] = match
// Solo guardar la primera definición de cada variable
if (!variablesMap.has(name)) {
variablesMap.set(name, {
name,
label: label || undefined,
defaultValue: defaultValue || undefined
})
}
}
}
}
}
return Array.from(variablesMap.values())
}
export interface TemplatesStore {
templates: PrintTemplate[]
}
@@ -84,6 +121,7 @@ export async function createTemplate(data: {
name: data.name,
description: data.description || '',
operations: data.operations,
variables: extractVariables(data.operations),
createdAt: now,
updatedAt: now
}
@@ -103,9 +141,15 @@ export async function updateTemplate(id: string, data: Partial<{
if (index === -1) return null
// Si se actualizan las operaciones, recalcular las variables
const variables = data.operations
? extractVariables(data.operations)
: store.templates[index].variables
store.templates[index] = {
...store.templates[index],
...data,
variables,
updatedAt: new Date().toISOString()
}