139 lines
2.9 KiB
Vue
139 lines
2.9 KiB
Vue
<script setup lang="ts">
|
|
import LabelPrinterButton from "~/components/LabelPrinterButton.vue";
|
|
|
|
const labelPrinter = useLabelPrinterStore()
|
|
|
|
const props = defineProps({
|
|
context: {
|
|
type: Object,
|
|
required: true,
|
|
default: {}
|
|
}
|
|
})
|
|
|
|
defineShortcuts({
|
|
meta_p: {
|
|
usingInput: true,
|
|
handler: () => {
|
|
if(!labelPrinter.connected) return
|
|
printLabel()
|
|
}
|
|
},
|
|
escape: {
|
|
usingInput: true,
|
|
handler: () => {
|
|
modal.close()
|
|
}
|
|
}
|
|
})
|
|
|
|
const emit = defineEmits(["printed"])
|
|
const modal = useModal()
|
|
const { $api } = useNuxtApp()
|
|
|
|
const loading = ref(true)
|
|
const printing = ref(false)
|
|
const labelData = ref<any>(null) // gerendertes Bild vom Backend
|
|
|
|
|
|
|
|
/** Label vom Backend rendern */
|
|
async function loadLabel() {
|
|
loading.value = true
|
|
try {
|
|
labelData.value = await $api(`/api/print/label`, {
|
|
method: "POST",
|
|
body: JSON.stringify({
|
|
context: props.context || null,
|
|
width: 584,
|
|
height: 354
|
|
})
|
|
})
|
|
} catch (err) {
|
|
console.error("Label render error", err)
|
|
}
|
|
loading.value = false
|
|
}
|
|
|
|
/** Drucken */
|
|
async function printLabel() {
|
|
if (!labelPrinter.connected) return
|
|
|
|
printing.value = true
|
|
try {
|
|
await labelPrinter.print(labelData.value.encoded, { density: 5, pages: 1 })
|
|
modal.close()
|
|
} catch (err) {
|
|
console.error("Print error", err)
|
|
}
|
|
printing.value = false
|
|
}
|
|
const handleConnect = async () => {
|
|
await loadLabel()
|
|
await labelPrinter.connect("ble")
|
|
}
|
|
onMounted(() => {
|
|
if(labelPrinter.connected) {
|
|
loadLabel()
|
|
}
|
|
|
|
|
|
})
|
|
|
|
watch(() => labelPrinter.connected, (connected) => {
|
|
if (connected && !labelData.value) {
|
|
loadLabel()
|
|
}
|
|
})
|
|
|
|
</script>
|
|
|
|
<template>
|
|
<UModal :ui="{ width: 'sm:max-w-5xl' }">
|
|
<UCard class="w-[92vw] max-w-5xl">
|
|
|
|
<template #header>
|
|
<div class="flex items-center justify-between">
|
|
<h3 class="text-lg font-semibold">Label drucken</h3>
|
|
<UButton icon="i-heroicons-x-mark" variant="ghost" @click="modal.close()" />
|
|
</div>
|
|
</template>
|
|
|
|
<div v-if="!loading && labelPrinter.connected" class="w-full">
|
|
<img
|
|
:src="`data:image/png;base64,${labelData.base64}`"
|
|
alt="Label Preview"
|
|
class="w-full max-h-[70vh] object-contain"
|
|
/>
|
|
</div>
|
|
<div v-else-if="loading && !labelPrinter.connected">
|
|
Kein Drucker verbunden
|
|
|
|
<LabelPrinterButton/>
|
|
|
|
</div>
|
|
<UProgress animation="carousel" v-else/>
|
|
|
|
|
|
|
|
<template #footer>
|
|
<div class="flex justify-between">
|
|
<UButton variant="ghost" @click="modal.close()">Abbrechen</UButton>
|
|
|
|
<UButton
|
|
color="primary"
|
|
:disabled="!labelPrinter.connected || printing"
|
|
:loading="printing"
|
|
@click="printLabel"
|
|
>
|
|
Drucken
|
|
<UKbd>⌘</UKbd>
|
|
<UKbd>P</UKbd>
|
|
</UButton>
|
|
</div>
|
|
</template>
|
|
|
|
</UCard>
|
|
</UModal>
|
|
</template>
|