<template> <MainTemplate> <template #headerInsert> <RouterLink to="../" class="text-primary">zurück zur Liste (abbrechen)</RouterLink> </template> <template #topBar> <div class="flex flex-row items-center justify-between pt-5 pb-3 px-7"> <h1 class="font-bold text-xl h-8">Qualifikation {{ origin?.qualification }} - Daten bearbeiten</h1> </div> </template> <template #main> <Spinner v-if="loading == 'loading'" class="mx-auto" /> <p v-else-if="loading == 'failed'">laden fehlgeschlagen</p> <form v-else-if="qualification != null" class="flex flex-col gap-4 py-2 w-full max-w-xl mx-auto" @submit.prevent="triggerUpdate" > <div> <label for="qualification">Bezeichnung</label> <input type="text" id="qualification" required v-model="qualification.qualification" /> </div> <div> <label for="description">Beschreibung (optional)</label> <input type="text" id="description" v-model="qualification.description" /> </div> <div class="flex flex-row justify-end gap-2"> <button primary-outline type="reset" class="w-fit!" :disabled="canSaveOrReset" @click="resetForm"> verwerfen </button> <button primary type="submit" class="w-fit!" :disabled="status == 'loading' || canSaveOrReset"> speichern </button> <Spinner v-if="status == 'loading'" class="my-auto" /> <SuccessCheckmark v-else-if="status?.status == 'success'" /> <FailureXMark v-else-if="status?.status == 'failed'" /> </div> </form> </template> </MainTemplate> </template> <script setup lang="ts"> import { defineComponent } from "vue"; import { mapState, mapActions } from "pinia"; import MainTemplate from "@/templates/Main.vue"; import { useQualificationStore } from "@/stores/admin/configuration/qualification"; import Spinner from "@/components/Spinner.vue"; import SuccessCheckmark from "@/components/SuccessCheckmark.vue"; import FailureXMark from "@/components/FailureXMark.vue"; import { RouterLink } from "vue-router"; import type { UpdateQualificationViewModel, QualificationViewModel, } from "@/viewmodels/admin/configuration/qualification.models"; import cloneDeep from "lodash.clonedeep"; import isEqual from "lodash.isequal"; </script> <script lang="ts"> export default defineComponent({ props: { id: String, }, data() { return { loading: "loading" as "loading" | "fetched" | "failed", status: null as null | "loading" | { status: "success" | "failed"; reason?: string }, origin: null as null | QualificationViewModel, qualification: null as null | QualificationViewModel, timeout: null as any, }; }, computed: { canSaveOrReset(): boolean { return isEqual(this.origin, this.qualification); }, }, mounted() { this.fetchItem(); }, beforeUnmount() { try { clearTimeout(this.timeout); } catch (error) {} }, methods: { ...mapActions(useQualificationStore, ["fetchQualificationById", "updateActiveQualification"]), resetForm() { this.qualification = cloneDeep(this.origin); }, fetchItem() { this.fetchQualificationById(parseInt(this.id ?? "")) .then((result) => { this.qualification = result.data; this.origin = cloneDeep(result.data); this.loading = "fetched"; }) .catch((err) => { this.loading = "failed"; }); }, triggerUpdate(e: any) { if (this.qualification == null) return; let formData = e.target.elements; let updateQualification: UpdateQualificationViewModel = { id: this.qualification.id, qualification: formData.qualification.value, description: formData.description.value, }; this.status = "loading"; this.updateActiveQualification(updateQualification) .then(() => { this.fetchItem(); this.status = { status: "success" }; }) .catch((err) => { this.status = { status: "failed" }; }) .finally(() => { this.timeout = setTimeout(() => { this.status = null; }, 2000); }); }, }, }); </script>