feat: Sistema de gestión de impresoras persistente
- Crear modelo Printer con campos: id, name, host, deviceId, timeout, isDefault - Almacenamiento persistente en data/printers.json - APIs CRUD: GET/POST /api/printers, GET/PUT/DELETE /api/printers/:id - API para seleccionar impresora activa: POST /api/printers/select - Endpoint de impresión ahora usa la impresora seleccionada o la especificada por printerId - Composable usePrinters() para el cliente - UI: Selector de impresora en sidebar, tab Impresoras en mobile - Componentes: PrintersList, PrintersCard, PrintersForm, PrintersSelector
This commit is contained in:
203
app/composables/usePrinters.ts
Normal file
203
app/composables/usePrinters.ts
Normal file
@@ -0,0 +1,203 @@
|
||||
// Composable para gestión de impresoras
|
||||
export interface Printer {
|
||||
id: string
|
||||
name: string
|
||||
host: string
|
||||
deviceId: string
|
||||
timeout: number
|
||||
isDefault: boolean
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
}
|
||||
|
||||
const printers = ref<Printer[]>([])
|
||||
const selectedPrinterId = ref<string | null>(null)
|
||||
const loading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
|
||||
export function usePrinters() {
|
||||
const selectedPrinter = computed(() =>
|
||||
printers.value.find(p => p.id === selectedPrinterId.value) || null
|
||||
)
|
||||
|
||||
const defaultPrinter = computed(() =>
|
||||
printers.value.find(p => p.isDefault) || printers.value[0] || null
|
||||
)
|
||||
|
||||
async function fetchPrinters() {
|
||||
loading.value = true
|
||||
error.value = null
|
||||
|
||||
try {
|
||||
const response = await $fetch<{
|
||||
ok: boolean
|
||||
printers: Printer[]
|
||||
selectedPrinterId: string | null
|
||||
error?: string
|
||||
}>('/api/printers')
|
||||
|
||||
if (response.ok) {
|
||||
printers.value = response.printers
|
||||
selectedPrinterId.value = response.selectedPrinterId
|
||||
} else {
|
||||
error.value = response.error || 'Error al cargar impresoras'
|
||||
}
|
||||
} catch (err: any) {
|
||||
error.value = err.message
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function createPrinter(data: {
|
||||
name: string
|
||||
host: string
|
||||
deviceId: string
|
||||
timeout?: number
|
||||
isDefault?: boolean
|
||||
}) {
|
||||
loading.value = true
|
||||
error.value = null
|
||||
|
||||
try {
|
||||
const response = await $fetch<{
|
||||
ok: boolean
|
||||
printer?: Printer
|
||||
error?: string
|
||||
}>('/api/printers', {
|
||||
method: 'POST',
|
||||
body: data
|
||||
})
|
||||
|
||||
if (response.ok && response.printer) {
|
||||
printers.value.push(response.printer)
|
||||
// Si es la primera impresora, seleccionarla
|
||||
if (printers.value.length === 1) {
|
||||
selectedPrinterId.value = response.printer.id
|
||||
}
|
||||
return response.printer
|
||||
} else {
|
||||
error.value = response.error || 'Error al crear impresora'
|
||||
return null
|
||||
}
|
||||
} catch (err: any) {
|
||||
error.value = err.message
|
||||
return null
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function updatePrinter(id: string, data: Partial<{
|
||||
name: string
|
||||
host: string
|
||||
deviceId: string
|
||||
timeout: number
|
||||
isDefault: boolean
|
||||
}>) {
|
||||
loading.value = true
|
||||
error.value = null
|
||||
|
||||
try {
|
||||
const response = await $fetch<{
|
||||
ok: boolean
|
||||
printer?: Printer
|
||||
error?: string
|
||||
}>(`/api/printers/${id}`, {
|
||||
method: 'PUT',
|
||||
body: data
|
||||
})
|
||||
|
||||
if (response.ok && response.printer) {
|
||||
const index = printers.value.findIndex(p => p.id === id)
|
||||
if (index !== -1) {
|
||||
// Si se estableció como default, quitar default de las demás
|
||||
if (data.isDefault) {
|
||||
printers.value.forEach(p => p.isDefault = false)
|
||||
}
|
||||
printers.value[index] = response.printer
|
||||
}
|
||||
return response.printer
|
||||
} else {
|
||||
error.value = response.error || 'Error al actualizar impresora'
|
||||
return null
|
||||
}
|
||||
} catch (err: any) {
|
||||
error.value = err.message
|
||||
return null
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function deletePrinter(id: string) {
|
||||
loading.value = true
|
||||
error.value = null
|
||||
|
||||
try {
|
||||
const response = await $fetch<{
|
||||
ok: boolean
|
||||
error?: string
|
||||
}>(`/api/printers/${id}`, {
|
||||
method: 'DELETE'
|
||||
})
|
||||
|
||||
if (response.ok) {
|
||||
const index = printers.value.findIndex(p => p.id === id)
|
||||
if (index !== -1) {
|
||||
printers.value.splice(index, 1)
|
||||
}
|
||||
// Si era la seleccionada, seleccionar otra
|
||||
if (selectedPrinterId.value === id) {
|
||||
selectedPrinterId.value = printers.value[0]?.id || null
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
error.value = response.error || 'Error al eliminar impresora'
|
||||
return false
|
||||
}
|
||||
} catch (err: any) {
|
||||
error.value = err.message
|
||||
return false
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function selectPrinter(printerId: string | null) {
|
||||
try {
|
||||
const response = await $fetch<{
|
||||
ok: boolean
|
||||
error?: string
|
||||
}>('/api/printers/select', {
|
||||
method: 'POST',
|
||||
body: { printerId }
|
||||
})
|
||||
|
||||
if (response.ok) {
|
||||
selectedPrinterId.value = printerId
|
||||
return true
|
||||
} else {
|
||||
error.value = response.error || 'Error al seleccionar impresora'
|
||||
return false
|
||||
}
|
||||
} catch (err: any) {
|
||||
error.value = err.message
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
printers,
|
||||
selectedPrinterId,
|
||||
selectedPrinter,
|
||||
defaultPrinter,
|
||||
loading,
|
||||
error,
|
||||
fetchPrinters,
|
||||
createPrinter,
|
||||
updatePrinter,
|
||||
deletePrinter,
|
||||
selectPrinter
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user