fix: Corregir errores de crypto.randomUUID, hydration y UI de impresoras
- Agregar fallback para crypto.randomUUID en useTemplates.ts (compatibilidad con navegadores antiguos) - Envolver sidebar con ClientOnly para evitar hydration mismatch - Agregar botón de configuración de impresoras en sidebar - Agregar drawer lateral para gestión de impresoras en desktop
This commit is contained in:
@@ -11,6 +11,19 @@ export interface PrintTemplate {
|
|||||||
|
|
||||||
const STORAGE_KEY = 'printercentral-templates'
|
const STORAGE_KEY = 'printercentral-templates'
|
||||||
|
|
||||||
|
// Función para generar UUID compatible con todos los navegadores
|
||||||
|
function generateId(): string {
|
||||||
|
if (typeof crypto !== 'undefined' && crypto.randomUUID) {
|
||||||
|
return crypto.randomUUID()
|
||||||
|
}
|
||||||
|
// Fallback para navegadores sin crypto.randomUUID
|
||||||
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
||||||
|
const r = Math.random() * 16 | 0
|
||||||
|
const v = c === 'x' ? r : (r & 0x3 | 0x8)
|
||||||
|
return v.toString(16)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export function useTemplates() {
|
export function useTemplates() {
|
||||||
const templates = useState<PrintTemplate[]>('templates', () => [])
|
const templates = useState<PrintTemplate[]>('templates', () => [])
|
||||||
const initialized = useState('templatesInitialized', () => false)
|
const initialized = useState('templatesInitialized', () => false)
|
||||||
@@ -37,7 +50,7 @@ export function useTemplates() {
|
|||||||
|
|
||||||
function saveTemplate(name: string, description: string, operations: Operation[]): PrintTemplate {
|
function saveTemplate(name: string, description: string, operations: Operation[]): PrintTemplate {
|
||||||
const template: PrintTemplate = {
|
const template: PrintTemplate = {
|
||||||
id: crypto.randomUUID(),
|
id: generateId(),
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
operations: JSON.parse(JSON.stringify(operations)),
|
operations: JSON.parse(JSON.stringify(operations)),
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ const activeTab = ref('constructor')
|
|||||||
const isDesktop = useMediaQuery('(min-width: 768px)')
|
const isDesktop = useMediaQuery('(min-width: 768px)')
|
||||||
const queue = usePrintQueue()
|
const queue = usePrintQueue()
|
||||||
const printers = usePrinters()
|
const printers = usePrinters()
|
||||||
|
const showPrintersDrawer = ref(false)
|
||||||
|
|
||||||
// Cargar impresoras al iniciar
|
// Cargar impresoras al iniciar
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -18,30 +19,42 @@ onMounted(() => {
|
|||||||
<!-- Layout principal -->
|
<!-- Layout principal -->
|
||||||
<div class="flex h-[calc(100vh-73px)]">
|
<div class="flex h-[calc(100vh-73px)]">
|
||||||
<!-- Sidebar solo en desktop -->
|
<!-- Sidebar solo en desktop -->
|
||||||
<aside
|
<ClientOnly>
|
||||||
v-if="isDesktop"
|
<aside
|
||||||
class="w-80 border-r border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-950 flex flex-col"
|
v-if="isDesktop"
|
||||||
>
|
class="w-80 border-r border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-950 flex flex-col"
|
||||||
<div class="p-4 border-b border-gray-200 dark:border-gray-800">
|
>
|
||||||
<h2 class="font-semibold text-gray-900 dark:text-white">Cola de Impresión</h2>
|
<div class="p-4 border-b border-gray-200 dark:border-gray-800">
|
||||||
<p class="text-sm text-gray-500 dark:text-gray-400">
|
<h2 class="font-semibold text-gray-900 dark:text-white">Cola de Impresión</h2>
|
||||||
{{ queue.operations.value.length }} comandos
|
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||||
</p>
|
{{ queue.operations.value.length }} comandos
|
||||||
</div>
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Selector de impresora -->
|
<!-- Selector de impresora -->
|
||||||
<div class="p-4 border-b border-gray-200 dark:border-gray-800">
|
<div class="p-4 border-b border-gray-200 dark:border-gray-800">
|
||||||
<PrintersSelector />
|
<div class="flex items-center gap-2">
|
||||||
</div>
|
<PrintersSelector class="flex-1" />
|
||||||
|
<UButton
|
||||||
|
icon="i-heroicons-cog-6-tooth"
|
||||||
|
color="neutral"
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
title="Configurar impresoras"
|
||||||
|
@click="showPrintersDrawer = true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flex-1 overflow-y-auto p-4">
|
<div class="flex-1 overflow-y-auto p-4">
|
||||||
<QueuePrintQueue />
|
<QueuePrintQueue />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="p-4 border-t border-gray-200 dark:border-gray-800">
|
<div class="p-4 border-t border-gray-200 dark:border-gray-800">
|
||||||
<QueueActions />
|
<QueueActions />
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
</ClientOnly>
|
||||||
|
|
||||||
<!-- Panel principal -->
|
<!-- Panel principal -->
|
||||||
<main class="flex-1 overflow-y-auto pb-mobile-nav md:pb-0">
|
<main class="flex-1 overflow-y-auto pb-mobile-nav md:pb-0">
|
||||||
@@ -71,5 +84,15 @@ onMounted(() => {
|
|||||||
|
|
||||||
<!-- Navegación mobile -->
|
<!-- Navegación mobile -->
|
||||||
<LayoutMobileNavigation v-model="activeTab" />
|
<LayoutMobileNavigation v-model="activeTab" />
|
||||||
|
|
||||||
|
<!-- Drawer para gestionar impresoras (desktop) -->
|
||||||
|
<UDrawer v-model:open="showPrintersDrawer" direction="right">
|
||||||
|
<template #header>
|
||||||
|
<h3 class="text-lg font-semibold">Gestión de Impresoras</h3>
|
||||||
|
</template>
|
||||||
|
<div class="p-4">
|
||||||
|
<PrintersList />
|
||||||
|
</div>
|
||||||
|
</UDrawer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user