preview template usage

This commit is contained in:
Julian Krauser 2024-12-24 13:53:00 +01:00
parent faa691b834
commit d6743f0d16
3 changed files with 71 additions and 3 deletions

View file

@ -0,0 +1,50 @@
<template>
<div class="w-full h-full flex flex-col gap-2">
<Spinner v-if="status == 'loading'" />
<div class="grow">
<iframe ref="viewer" class="w-full h-full" />
</div>
<button primary-outline class="!w-fit self-end" @click="closeModal">schließen</button>
</div>
</template>
<script setup lang="ts">
import { defineComponent } from "vue";
import { mapState, mapActions } from "pinia";
import { useModalStore } from "@/stores/modal";
import Spinner from "@/components/Spinner.vue";
import { useTemplateUsageStore } from "@/stores/admin/templateUsage";
</script>
<script lang="ts">
export default defineComponent({
data() {
return {
status: null as null | "loading" | { status: "success" | "failed"; reason?: string },
}
},
computed: {
...mapState(useModalStore, ["data"]),
},
mounted() {
this.fetchItem();
},
methods: {
...mapActions(useModalStore, ["closeModal"]),
...mapActions(useTemplateUsageStore, ["previewTemplateUsage"]),
fetchItem() {
this.status = "loading"
this.previewTemplateUsage(this.data)
.then((response) => {
this.status = { status: "success" };
const blob = new Blob([response.data], { type: "application/pdf" });
(this.$refs.viewer as HTMLIFrameElement).src = window.URL.createObjectURL(blob);
})
.catch(() => {
this.status = { status: "success" };
});
},
},
});
</script>

View file

@ -3,6 +3,9 @@
<div class="bg-primary p-2 text-white flex flex-row justify-between items-center"> <div class="bg-primary p-2 text-white flex flex-row justify-between items-center">
<p>Templates zu "{{ templateUsage.scope }}" zuweisen</p> <p>Templates zu "{{ templateUsage.scope }}" zuweisen</p>
<div class="flex flex-row justify-end w-16"> <div class="flex flex-row justify-end w-16">
<button type="button" class="!p-0 !h-fit !w-fit" title="Vorschau erzeugen" @click="previewUsage">
<EyeIcon class="w-5 h-5 p-1 box-content pointer-events-none" />
</button>
<button v-if="status == null" type="submit" class="!p-0 !h-fit !w-fit" title="speichern"> <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" /> <ArchiveBoxArrowDownIcon class="w-5 h-5 p-1 box-content pointer-events-none" />
</button> </button>
@ -41,15 +44,16 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { defineComponent, type PropType } from "vue"; import { defineAsyncComponent, defineComponent, markRaw, type PropType } from "vue";
import { mapState, mapActions } from "pinia"; import { mapState, mapActions } from "pinia";
import { ArchiveBoxArrowDownIcon, ArchiveBoxXMarkIcon } from "@heroicons/vue/24/outline"; import { ArchiveBoxArrowDownIcon, ArchiveBoxXMarkIcon, EyeIcon } from "@heroicons/vue/24/outline";
import type { TemplateUsageViewModel } from "../../../../viewmodels/admin/templateUsage.models"; import type { TemplateUsageViewModel } from "../../../../viewmodels/admin/templateUsage.models";
import { useTemplateStore } from "../../../../stores/admin/template"; import { useTemplateStore } from "../../../../stores/admin/template";
import { useTemplateUsageStore } from "../../../../stores/admin/templateUsage"; import { useTemplateUsageStore } from "../../../../stores/admin/templateUsage";
import Spinner from "@/components/Spinner.vue"; import Spinner from "@/components/Spinner.vue";
import SuccessCheckmark from "@/components/SuccessCheckmark.vue"; import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
import FailureXMark from "@/components/FailureXMark.vue"; import FailureXMark from "@/components/FailureXMark.vue";
import { useModalStore } from "@/stores/modal";
</script> </script>
<script lang="ts"> <script lang="ts">
@ -72,13 +76,21 @@ export default defineComponent({
} catch (error) {} } catch (error) {}
}, },
methods: { methods: {
...mapActions(useModalStore, ["openModal"]),
...mapActions(useTemplateUsageStore, ["updateTemplateUsage"]), ...mapActions(useTemplateUsageStore, ["updateTemplateUsage"]),
previewUsage() {
this.openModal(
markRaw(defineAsyncComponent(() => import("@/components/admin/settings/templateUsage/TemplatePreviewModal.vue"))),
this.templateUsage.scope
)
},
updateUsage(e: any) { updateUsage(e: any) {
const fromData = e.target.elements; const fromData = e.target.elements;
const headerId = fromData.header.value === "def" ? null : fromData.header.value; const headerId = fromData.header.value === "def" ? null : fromData.header.value;
const bodyId = fromData.body.value === "def" ? null : fromData.body.value; const bodyId = fromData.body.value === "def" ? null : fromData.body.value;
const footerId = fromData.footer.value === "def" ? null : fromData.footer.value; const footerId = fromData.footer.value === "def" ? null : fromData.footer.value;
this.status = "loading"
this.updateTemplateUsage({ this.updateTemplateUsage({
scope: this.templateUsage.scope, scope: this.templateUsage.scope,
headerId: headerId, headerId: headerId,
@ -92,7 +104,7 @@ export default defineComponent({
}, 2000); }, 2000);
}) })
.catch(() => { .catch(() => {
this.status = { status: "failed" }; this.status = { status: "success" };
}); });
}, },
resetForm() { resetForm() {

View file

@ -3,6 +3,7 @@ import { http } from "@/serverCom";
import type { AxiosResponse } from "axios"; import type { AxiosResponse } from "axios";
import type { CreateTemplateViewModel, UpdateTemplateViewModel } from "../../viewmodels/admin/template.models"; import type { CreateTemplateViewModel, UpdateTemplateViewModel } from "../../viewmodels/admin/template.models";
import type { TemplateUsageViewModel, UpdateTemplateUsageViewModel } from "../../viewmodels/admin/templateUsage.models"; import type { TemplateUsageViewModel, UpdateTemplateUsageViewModel } from "../../viewmodels/admin/templateUsage.models";
import type { PermissionModule } from "../../types/permissionTypes";
export const useTemplateUsageStore = defineStore("templateUsage", { export const useTemplateUsageStore = defineStore("templateUsage", {
state: () => { state: () => {
@ -24,6 +25,11 @@ export const useTemplateUsageStore = defineStore("templateUsage", {
this.loading = "failed"; this.loading = "failed";
}); });
}, },
async previewTemplateUsage(scope: PermissionModule): Promise<AxiosResponse<any, any>> {
return await http.get(`/admin/templateusage/${scope}`, {
responseType: "blob",
});
},
async updateTemplateUsage(templateUsage: UpdateTemplateUsageViewModel): Promise<AxiosResponse<any, any>> { async updateTemplateUsage(templateUsage: UpdateTemplateUsageViewModel): Promise<AxiosResponse<any, any>> {
const result = await http.patch(`/admin/templateusage/${templateUsage.scope}`, { const result = await http.patch(`/admin/templateusage/${templateUsage.scope}`, {
headerId: templateUsage.headerId, headerId: templateUsage.headerId,