- Nuevo layout responsivo mobile-first con tabs inferiores - Sidebar colapsable en desktop con cola de impresión - Sistema de templates reutilizables con localStorage - Soporte Dark/Light mode con UColorModeButton - Composables usePrintQueue y useTemplates para estado global - Componentes modulares: CommandBuilder, QuickActions, PrintQueue, QueueItem - Navegación por tabs: Constructor | Cola | Templates
82 lines
2.0 KiB
TypeScript
82 lines
2.0 KiB
TypeScript
export interface Operation {
|
|
op: string
|
|
[key: string]: any
|
|
}
|
|
|
|
export interface PrintResult {
|
|
ok: boolean
|
|
msg?: string
|
|
error?: string
|
|
code?: string
|
|
raw?: string
|
|
}
|
|
|
|
export function usePrintQueue() {
|
|
const operations = useState<Operation[]>('printQueue', () => [])
|
|
const result = useState<PrintResult>('printResult', () => ({ ok: true, msg: 'Listo.' }))
|
|
const loading = useState('printLoading', () => false)
|
|
|
|
function addOperations(ops: Operation[]) {
|
|
if (Array.isArray(ops) && ops.length) {
|
|
operations.value = [...operations.value, ...ops]
|
|
}
|
|
}
|
|
|
|
function updateOperation(index: number, op: Operation) {
|
|
operations.value = operations.value.map((o, i) => i === index ? op : o)
|
|
}
|
|
|
|
function removeOperation(index: number) {
|
|
operations.value = operations.value.filter((_, i) => i !== index)
|
|
}
|
|
|
|
function moveOperation(from: number, direction: 'up' | 'down') {
|
|
const to = direction === 'up' ? from - 1 : from + 1
|
|
if (to < 0 || to >= operations.value.length) return
|
|
|
|
const arr = [...operations.value]
|
|
;[arr[from], arr[to]] = [arr[to], arr[from]]
|
|
operations.value = arr
|
|
}
|
|
|
|
function clearQueue() {
|
|
operations.value = []
|
|
}
|
|
|
|
function loadFromTemplate(ops: Operation[]) {
|
|
operations.value = JSON.parse(JSON.stringify(ops))
|
|
}
|
|
|
|
async function sendToPrinter() {
|
|
if (operations.value.length === 0) return
|
|
|
|
loading.value = true
|
|
try {
|
|
result.value = await $fetch('/api/print', {
|
|
method: 'POST',
|
|
body: { operations: operations.value }
|
|
})
|
|
} catch (error: any) {
|
|
result.value = {
|
|
ok: false,
|
|
error: error.message || 'Error al enviar a la impresora'
|
|
}
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
return {
|
|
operations: readonly(operations),
|
|
result: readonly(result),
|
|
loading: readonly(loading),
|
|
addOperations,
|
|
updateOperation,
|
|
removeOperation,
|
|
moveOperation,
|
|
clearQueue,
|
|
loadFromTemplate,
|
|
sendToPrinter
|
|
}
|
|
}
|