diff --git a/app/components/templates/TemplateCard.vue b/app/components/templates/TemplateCard.vue index 16e3f47..5aa3ad8 100644 --- a/app/components/templates/TemplateCard.vue +++ b/app/components/templates/TemplateCard.vue @@ -51,10 +51,13 @@ function formatDate(date: string | number) { > {{ template.description }}

-
+
{{ template.operations.length }} comandos + + {{ template.variables.length }} {{ template.variables.length === 1 ? 'variable' : 'variables' }} + {{ formatDate(template.updatedAt) }} diff --git a/app/components/templates/TemplateList.vue b/app/components/templates/TemplateList.vue index 837da88..4e583e3 100644 --- a/app/components/templates/TemplateList.vue +++ b/app/components/templates/TemplateList.vue @@ -1,21 +1,48 @@ + + diff --git a/app/composables/useTemplates.ts b/app/composables/useTemplates.ts index 70c9f7c..b7ff2fe 100644 --- a/app/composables/useTemplates.ts +++ b/app/composables/useTemplates.ts @@ -1,14 +1,40 @@ import type { Operation } from './usePrintQueue' +export interface TemplateVariable { + name: string + label?: string + defaultValue?: string +} + export interface PrintTemplate { id: string name: string description?: string operations: Operation[] + variables: TemplateVariable[] createdAt: string updatedAt: string } +// Regex para detectar variables en templates +const VARIABLE_REGEX = /\{\{(\w+)(?::([^:}]+))?(?::([^}]+))?\}\}/g + +// Resolver variables en operaciones +export function resolveVariables( + operations: Operation[], + values: Record +): Operation[] { + return JSON.parse(JSON.stringify(operations)).map((op: Operation) => { + for (const [key, val] of Object.entries(op)) { + if (typeof val === 'string') { + // Reemplazar {{nombre:label:default}} con el valor proporcionado + op[key] = val.replace(VARIABLE_REGEX, (_, name) => values[name] ?? '') + } + } + return op + }) +} + export function useTemplates() { const templates = useState('templates', () => []) const loading = useState('templatesLoading', () => false) @@ -119,6 +145,7 @@ export function useTemplates() { updateTemplate, deleteTemplate, loadTemplate, - duplicateTemplate + duplicateTemplate, + resolveVariables } } diff --git a/app/pages/index.vue b/app/pages/index.vue index 134b74d..cf487a9 100644 --- a/app/pages/index.vue +++ b/app/pages/index.vue @@ -71,7 +71,9 @@ onMounted(() => { - + + +
diff --git a/server/utils/templates.ts b/server/utils/templates.ts index bb4f700..9e059b6 100644 --- a/server/utils/templates.ts +++ b/server/utils/templates.ts @@ -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 + 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() + + 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() }