<template> <form ref="form" class="flex flex-col h-fit w-full border border-primary rounded-md" @submit.prevent="updateUsage"> <div class="bg-primary p-2 text-white flex flex-row justify-between items-center"> <p>Templates zu "{{ templateUsage.scope }}" zuweisen</p> <div class="flex flex-row justify-end w-16"> <button v-if="status == null" type="submit" class="!p-0 !h-fit !w-fit" title="speichern"> <ArchiveBoxArrowDownIcon class="w-5 h-5 p-1 box-content pointer-events-none" /> </button> <Spinner v-else-if="status == 'loading'" class="my-auto" /> <SuccessCheckmark v-else-if="status?.status == 'success'" /> <FailureXMark v-else-if="status?.status == 'failed'" /> <button type="button" class="!p-0 !h-fit !w-fit" title="zurücksetzen" @click="resetForm"> <ArchiveBoxXMarkIcon class="w-5 h-5 p-1 box-content pointer-events-none" /> </button> </div> </div> <div class="flex flex-col p-2 gap-2"> <div class="flex flex-row gap-2 items-center"> <p class="min-w-16">Kopfzeile:</p> <select ref="header" id="header" :value="templateUsage.header?.id ?? 'def'"> <option value="def">Standart-Vorlage verwenden</option> <option v-for="template in templates" :key="template.id" :value="template.id">{{ template.template }}</option> </select> </div> <div class="flex flex-row gap-2 items-center"> <p class="min-w-16">Hauptteil:</p> <select ref="body" id="body" :value="templateUsage.body?.id ?? 'def'"> <option value="def">Standart-Vorlage verwenden</option> <option v-for="template in templates" :key="template.id" :value="template.id">{{ template.template }}</option> </select> </div> <div class="flex flex-row gap-2 items-center"> <p class="min-w-16">Fußzeile:</p> <select ref="footer" id="footer" :value="templateUsage.footer?.id ?? 'def'"> <option value="def">Standart-Vorlage verwenden</option> <option v-for="template in templates" :key="template.id" :value="template.id">{{ template.template }}</option> </select> </div> </div> </form> </template> <script setup lang="ts"> import { defineComponent, type PropType } from "vue"; import { mapState, mapActions } from "pinia"; import { ArchiveBoxArrowDownIcon, ArchiveBoxXMarkIcon } from "@heroicons/vue/24/outline"; import type { TemplateUsageViewModel } from "../../../../viewmodels/admin/templateUsage.models"; import { useTemplateStore } from "../../../../stores/admin/template"; import { useTemplateUsageStore } from "../../../../stores/admin/templateUsage"; import Spinner from "@/components/Spinner.vue"; import SuccessCheckmark from "@/components/SuccessCheckmark.vue"; import FailureXMark from "@/components/FailureXMark.vue"; </script> <script lang="ts"> export default defineComponent({ props: { templateUsage: { type: Object as PropType<TemplateUsageViewModel>, default: {} }, }, data() { return { status: null as null | "loading" | { status: "success" | "failed"; reason?: string }, timeout: undefined as any, }; }, computed: { ...mapState(useTemplateStore, ["templates"]), }, beforeUnmount() { try { clearTimeout(this.timeout); } catch (error) {} }, methods: { ...mapActions(useTemplateUsageStore, ["updateTemplateUsage"]), updateUsage(e: any) { const fromData = e.target.elements; const headerId = fromData.header.value === "def" ? null : fromData.header.value; const bodyId = fromData.body.value === "def" ? null : fromData.body.value; const footerId = fromData.footer.value === "def" ? null : fromData.footer.value; this.updateTemplateUsage({ scope: this.templateUsage.scope, headerId: headerId, bodyId: bodyId, footerId: footerId, }) .then(() => { this.status = { status: "success" }; this.timeout = setTimeout(() => { this.status = null; }, 2000); }) .catch(() => { this.status = { status: "failed" }; }); }, resetForm() { (this.$refs.header as HTMLSelectElement).value = String(this.templateUsage.header?.id ?? "def"); (this.$refs.body as HTMLSelectElement).value = String(this.templateUsage.body?.id ?? "def"); (this.$refs.footer as HTMLSelectElement).value = String(this.templateUsage.footer?.id ?? "def"); }, }, }); </script>