<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">Webapi-Token {{ origin?.title }} - 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="webapi" class="flex flex-col gap-4 py-2 w-full max-w-xl mx-auto" @submit.prevent="triggerWebapiUpdate" > <div> <label for="title">Bezeichnung</label> <input type="text" id="title" required v-model="webapi.title" /> </div> <div class="w-full"> <label for="expiry">Ablaufdatum (optional)</label> <input type="date" id="expiry" step="1" v-model="webapi.expiry" /> </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 { useWebapiStore } from "@/stores/admin/management/webapi"; import Spinner from "@/components/Spinner.vue"; import SuccessCheckmark from "@/components/SuccessCheckmark.vue"; import FailureXMark from "@/components/FailureXMark.vue"; import { RouterLink } from "vue-router"; import cloneDeep from "lodash.clonedeep"; import isEqual from "lodash.isequal"; import type { UpdateWebapiViewModel, WebapiViewModel } from "@/viewmodels/admin/management/webapi.models"; import type { Update } from "vite/types/hmrPayload.js"; </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 | WebapiViewModel, webapi: null as null | WebapiViewModel, timeout: null as any, }; }, computed: { canSaveOrReset(): boolean { return isEqual(this.origin, this.webapi); }, }, mounted() { this.fetchItem(); }, beforeUnmount() { try { clearTimeout(this.timeout); } catch (error) {} }, methods: { ...mapActions(useWebapiStore, ["fetchWebapiById", "updateActiveWebapi"]), resetForm() { this.webapi = cloneDeep(this.origin); }, fetchItem() { this.fetchWebapiById(parseInt(this.id ?? "")) .then((result) => { this.webapi = result.data; this.origin = cloneDeep(result.data); this.loading = "fetched"; }) .catch((err) => { this.loading = "failed"; }); }, triggerWebapiUpdate(e: any) { if (this.webapi == null) return; let formData = e.target.elements; let updateWebapi: UpdateWebapiViewModel = { title: formData.title.value, expiry: formData.expiry.value, }; this.status = "loading"; this.updateActiveWebapi(this.webapi.id, updateWebapi) .then(() => { this.fetchItem(); this.status = { status: "success" }; }) .catch((err) => { this.status = { status: "failed" }; }) .finally(() => { this.timeout = setTimeout(() => { this.status = null; }, 2000); }); }, }, }); </script>