From 7d1106cfcee67b64536ba8bbc84ef2ab81e9313a Mon Sep 17 00:00:00 2001
From: Julian Leucker <leuckerj@gmail.com>
Date: Fri, 24 Mar 2023 16:09:30 +0100
Subject: [PATCH] Include Deletion Dialog Component

---
 .../components/generic/DeleteDialog.vue       | 132 ++++++++++++++++++
 1 file changed, 132 insertions(+)
 create mode 100644 aleksis/core/frontend/components/generic/DeleteDialog.vue

diff --git a/aleksis/core/frontend/components/generic/DeleteDialog.vue b/aleksis/core/frontend/components/generic/DeleteDialog.vue
new file mode 100644
index 000000000..afed69776
--- /dev/null
+++ b/aleksis/core/frontend/components/generic/DeleteDialog.vue
@@ -0,0 +1,132 @@
+<template>
+  <ApolloMutation
+    v-if="dialogOpen"
+    :mutation="gqlMutation"
+    :variables="{ id: item.id }"
+    :update="update"
+    @done="close(true)"
+  >
+    <template #default="{ mutate, loading, error }">
+      <v-dialog v-model="dialogOpen" max-width="500px">
+        <v-card>
+          <v-card-title class="text-h5">
+            {{ $t("actions.confirm_deletion") }}
+          </v-card-title>
+          <v-card-text>
+            <p class="text-body-1">{{ nameOfObject }}</p>
+          </v-card-text>
+          <v-card-actions>
+            <v-spacer></v-spacer>
+            <v-btn text @click="close(false)" :disabled="loading">
+              {{ $t("actions.cancel") }}
+            </v-btn>
+            <v-btn
+              color="red"
+              text
+              @click="mutate"
+              :loading="loading"
+              :disabled="loading"
+            >
+              {{ $t("actions.delete") }}
+            </v-btn>
+          </v-card-actions>
+        </v-card>
+      </v-dialog>
+      <v-snackbar :value="error !== null">
+        {{ error }}
+
+        <template #action="{ attrs }">
+          <v-btn color="primary" text v-bind="attrs" @click="error = null" icon>
+            <v-icon>$close</v-icon>
+          </v-btn>
+        </template>
+      </v-snackbar>
+    </template>
+  </ApolloMutation>
+</template>
+
+<script>
+export default {
+  name: "DeleteDialog",
+  computed: {
+    nameOfObject() {
+      return this.itemAttribute in this.item || {}
+        ? this.item[this.itemAttribute]
+        : this.item.toString();
+    },
+    dialogOpen: {
+      get() {
+        return this.value;
+      },
+
+      set(val) {
+        this.$emit("input", val)
+      }
+    }
+  },
+  methods: {
+    update(store) {
+      if (!this.gqlQuery) {
+        // There is no GraphQL query to update
+        return;
+      }
+
+      // Read the data from cache for query
+      const storedData = store.readQuery({ query: this.gqlQuery });
+
+      if (!storedData) {
+        // There are no data in the cache yet
+        return;
+      }
+
+      const storedDataKey = Object.keys(storedData)[0];
+
+      // Remove item from stored data
+      const index = storedData[storedDataKey].findIndex(
+        (m) => m.id === this.item.id
+      );
+      storedData[storedDataKey].splice(index, 1);
+
+      // Write data back to the cache
+      store.writeQuery({ query: this.gqlQuery, storedData });
+    },
+    close(success) {
+      this.$emit("input", false);
+      if (success) {
+        this.$emit("success");
+      } else {
+        this.$emit("cancel");
+      }
+    }
+  },
+  props: {
+    value: {
+      type: Boolean,
+      required: true,
+    },
+    item: {
+      type: Object,
+      required: false,
+      default: () => ({}),
+    },
+    itemAttribute: {
+      type: String,
+      required: false,
+      default: "name",
+    },
+    title: {
+      type: String,
+      required: true,
+    },
+    gqlMutation: {
+      type: Object,
+      required: true,
+    },
+    gqlQuery: {
+      type: Object,
+      required: false,
+      default: null,
+    },
+  },
+};
+</script>
-- 
GitLab