Files
homebox/frontend/components/global/LabelMaker.vue
Tonya cbaf483788 migrate pages to shadcn (#628)
* feat: migrate tools page and label generator to shadcn

* chore: lint issues

* feat: also do profile page

* feat: shadcn 404 page

* feat: login page shadcn

* fix: daisyui ironically breaks the z height for the login page

* feat: componentise the language selector and add it to the login page

* feat: use nuxtlink

* feat: card and table made more shadcn

* feat: shadcn statscard

* chore: lint

* feat: shadcn labelchip and locationcard

* feat: shadcn locations page

* refactor: remove unused new item page

* chore: lint

* feat: shadcn item card

* fix: wrapping of location and lint

* feat: ctrl enter in text area in form submits form

* feat: begin shadcn locations page and remove pageqrcode comp in favour of integrating it into labelmaker

* chore: lint + remove unused code

* fix: remove uneeded margin

* feat: shadcn labels page and fix some issues with location

* feat: shadcn scanner

* chore: lint

* feat: begin shadcning item pages

* feat: shadcn maintenance page

* feat: begin shadcn search page

* fix: quick switch blurry text and crashing page when switching + incorrect z height for create menu

* feat: finish shadcn search page

* chore: lint

* feat: shadcn edit item page

* fix: quickmenumodal bug

* feat: shadcn item details page

* feat: remove all non-color related daisyui classes

* fix: type error

* fix: quick menu modal again :(
2025-04-20 08:58:03 +01:00

150 lines
4.2 KiB
Vue

<script setup lang="ts">
import { route } from "../../lib/api/base";
import PageQRCode from "./PageQRCode.vue";
import { toast } from "@/components/ui/sonner";
import MdiPrinterPos from "~icons/mdi/printer-pos";
import MdiFileDownload from "~icons/mdi/file-download";
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
DialogDescription,
} from "@/components/ui/dialog";
import { useDialog } from "@/components/ui/dialog-provider";
import { Button, ButtonGroup } from "@/components/ui/button";
import { Tooltip, TooltipContent, TooltipTrigger, TooltipProvider } from "@/components/ui/tooltip";
const { openDialog, closeDialog } = useDialog();
const props = defineProps<{
type: string;
id: string;
}>();
const pubApi = usePublicApi();
const { data: status } = useAsyncData(async () => {
const { data, error } = await pubApi.status();
if (error) {
toast.error("Failed to load status");
return;
}
return data;
});
const serverPrinting = ref(false);
function browserPrint() {
const printWindow = window.open(getLabelUrl(false), "popup=true");
if (printWindow !== null) {
printWindow.onload = () => {
printWindow.print();
};
}
}
async function serverPrint() {
serverPrinting.value = true;
try {
await fetch(getLabelUrl(true));
} catch (err) {
console.error("Failed to print labels:", err);
serverPrinting.value = false;
toast.error("Failed to print label");
return;
}
toast.success("Label printed");
closeDialog("print-label");
serverPrinting.value = false;
}
function downloadLabel() {
const link = document.createElement("a");
link.download = `label-${props.id}.png`;
link.href = getLabelUrl(false);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
function getLabelUrl(print: boolean): string {
const params = { print };
if (props.type === "item") {
return route(`/labelmaker/item/${props.id}`, params);
} else if (props.type === "location") {
return route(`/labelmaker/location/${props.id}`, params);
} else if (props.type === "asset") {
return route(`/labelmaker/asset/${props.id}`, params);
} else {
throw new Error(`Unexpected labelmaker type ${props.type}`);
}
}
</script>
<template>
<div>
<Dialog dialog-id="print-label">
<DialogContent>
<DialogHeader>
<DialogTitle>
{{ $t("components.global.label_maker.print") }}
</DialogTitle>
<DialogDescription>
{{ $t("components.global.label_maker.confirm_description") }}
</DialogDescription>
</DialogHeader>
<img :src="getLabelUrl(false)" />
<DialogFooter>
<ButtonGroup>
<Button v-if="status?.labelPrinting || false" type="submit" :loading="serverPrinting" @click="serverPrint">
{{ $t("components.global.label_maker.server_print") }}
</Button>
<Button type="submit" @click="browserPrint">
{{ $t("components.global.label_maker.browser_print") }}
</Button>
</ButtonGroup>
</DialogFooter>
</DialogContent>
</Dialog>
<TooltipProvider :delay-duration="0">
<ButtonGroup>
<Button variant="outline" disabled class="disabled:opacity-100">
{{ $t("components.global.label_maker.titles") }}
</Button>
<Tooltip>
<TooltipTrigger as-child>
<Button size="icon" @click="downloadLabel">
<MdiFileDownload name="mdi-file-download" />
</Button>
</TooltipTrigger>
<TooltipContent>
{{ $t("components.global.label_maker.download") }}
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger as-child>
<Button size="icon" @click="openDialog('print-label')">
<MdiPrinterPos name="mdi-printer-pos" />
</Button>
</TooltipTrigger>
<TooltipContent>
{{ $t("components.global.label_maker.browser_print") }}
</TooltipContent>
</Tooltip>
<PageQRCode />
</ButtonGroup>
</TooltipProvider>
</div>
</template>