From 6f75da7914295170a538815577260f23af02b62d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20G=C3=B6bel?= <dgoebel@techfak.uni-bielefeld.de>
Date: Tue, 28 Mar 2023 11:38:27 +0200
Subject: [PATCH] Add button to delete an entire workflow

#54
---
 src/components/modals/DeleteModal.vue         |  8 +++--
 src/components/modals/SearchUserModal.vue     |  2 +-
 .../workflows/WorkflowWithVersionsCard.vue    | 33 +++++++++++------
 src/stores/buckets.ts                         |  9 ++---
 .../workflows/ListWorkflowExecutionsView.vue  |  1 +
 src/views/workflows/MyWorkflowsView.vue       | 35 +++++++++++++++++--
 6 files changed, 68 insertions(+), 20 deletions(-)

diff --git a/src/components/modals/DeleteModal.vue b/src/components/modals/DeleteModal.vue
index 439d0c3..5995e92 100644
--- a/src/components/modals/DeleteModal.vue
+++ b/src/components/modals/DeleteModal.vue
@@ -5,7 +5,7 @@ import BootstrapModal from "@/components/modals/BootstrapModal.vue";
 
 const props = defineProps<{
   modalID: string;
-  objectNameDelete: string;
+  objectNameDelete?: string;
   backModalId?: string;
 }>();
 
@@ -43,7 +43,9 @@ onMounted(() => {
     <template v-slot:body>
       <p>
         Are you sure you want to delete
-        <strong>{{ props.objectNameDelete }}</strong>
+        <strong v-if="props.objectNameDelete">{{
+          props.objectNameDelete
+        }}</strong>
       </p>
       <div class="form-check">
         <input
@@ -62,7 +64,7 @@ onMounted(() => {
     </template>
     <template v-slot:footer>
       <button
-        v-if="backModalId !== undefined"
+        v-if="backModalId"
         type="button"
         class="btn btn-secondary"
         :data-bs-target="'#' + props.backModalId"
diff --git a/src/components/modals/SearchUserModal.vue b/src/components/modals/SearchUserModal.vue
index 44c2c8a..ccaff93 100644
--- a/src/components/modals/SearchUserModal.vue
+++ b/src/components/modals/SearchUserModal.vue
@@ -133,7 +133,7 @@ function searchUser(name: string) {
     </template>
     <template v-slot:footer>
       <button
-        v-if="backModalId !== undefined"
+        v-if="backModalId"
         type="button"
         class="btn btn-secondary"
         :data-bs-target="'#' + props.backModalId"
diff --git a/src/components/workflows/WorkflowWithVersionsCard.vue b/src/components/workflows/WorkflowWithVersionsCard.vue
index 9ea8df4..5a30e8f 100644
--- a/src/components/workflows/WorkflowWithVersionsCard.vue
+++ b/src/components/workflows/WorkflowWithVersionsCard.vue
@@ -14,6 +14,7 @@ const truncateDescription = ref<boolean>(true);
 
 const emit = defineEmits<{
   (e: "workflow-update-click", workflow: WorkflowOut): void;
+  (e: "workflow-delete-click", workflow: WorkflowOut): void;
 }>();
 
 const statusToIconMapping: Record<string, string> = {
@@ -34,16 +35,28 @@ const statusToIconMapping: Record<string, string> = {
           <span class="placeholder col-6"></span>
         </div>
         <span v-else class="text-truncate">{{ props.workflow.name }}</span>
-        <button
-          type="button"
-          class="btn btn-success"
-          :class="{ disabled: props.loading }"
-          @click="emit('workflow-update-click', props.workflow)"
-          data-bs-toggle="modal"
-          data-bs-target="#updateWorkflowModal"
-        >
-          Update
-        </button>
+        <div>
+          <button
+            type="button"
+            class="btn btn-outline-danger me-2"
+            @click="emit('workflow-delete-click', props.workflow)"
+            :class="{ disabled: props.loading }"
+            data-bs-toggle="modal"
+            data-bs-target="#deleteWorkflowModal"
+          >
+            <font-awesome-icon icon="fa-solid fa-trash" />
+          </button>
+          <button
+            type="button"
+            class="btn btn-success"
+            :class="{ disabled: props.loading }"
+            @click="emit('workflow-update-click', props.workflow)"
+            data-bs-toggle="modal"
+            data-bs-target="#updateWorkflowModal"
+          >
+            Update
+          </button>
+        </div>
       </div>
       <p class="card-text" :class="{ 'text-truncate': truncateDescription }">
         <span v-if="props.loading" class="placeholder-glow"
diff --git a/src/stores/buckets.ts b/src/stores/buckets.ts
index c95040f..ec2f3b3 100644
--- a/src/stores/buckets.ts
+++ b/src/stores/buckets.ts
@@ -156,6 +156,9 @@ export const useBucketStore = defineStore({
       if (currentTime - this._bla > 5000) {
         this._bla = currentTime;
         const authStore = useAuthStore();
+        if (this.buckets.length > 0) {
+          onFinally?.();
+        }
         BucketService.bucketListBuckets(authStore.currentUID)
           .then((buckets) => {
             this.buckets = buckets;
@@ -165,10 +168,8 @@ export const useBucketStore = defineStore({
           .finally(onFinally);
         this._fetchOwnPermissions();
       } else {
-        this._lastFetchBucketPromise
-          ?.then(onFulfilled)
-          .catch(onRejected)
-          .finally(onFinally);
+        onFinally?.();
+        this._lastFetchBucketPromise?.then(onFulfilled).catch(onRejected);
       }
     },
     fetchBucket(
diff --git a/src/views/workflows/ListWorkflowExecutionsView.vue b/src/views/workflows/ListWorkflowExecutionsView.vue
index 7d0e548..ebfa317 100644
--- a/src/views/workflows/ListWorkflowExecutionsView.vue
+++ b/src/views/workflows/ListWorkflowExecutionsView.vue
@@ -301,6 +301,7 @@ onMounted(() => {
           </td>
           <td v-else>
             <router-link
+              v-if="execution.workflow_id"
               :to="{
                 name: 'workflow-version',
                 params: {
diff --git a/src/views/workflows/MyWorkflowsView.vue b/src/views/workflows/MyWorkflowsView.vue
index 7ecb28c..cf18673 100644
--- a/src/views/workflows/MyWorkflowsView.vue
+++ b/src/views/workflows/MyWorkflowsView.vue
@@ -7,15 +7,18 @@ import WorkflowWithVersionsCard from "@/components/workflows/WorkflowWithVersion
 import CreateWorkflowModal from "@/components/workflows/modals/CreateWorkflowModal.vue";
 import CardTransitionGroup from "@/components/transitions/CardTransitionGroup.vue";
 import UpdateWorkflowModal from "@/components/workflows/modals/UpdateWorkflowModal.vue";
+import DeleteModal from "@/components/modals/DeleteModal.vue";
 
 const userRepository = useAuthStore();
 const workflowsState = reactive<{
   workflows: WorkflowOut[];
   loading: boolean;
   updateWorkflow: WorkflowOut;
+  potentialWorkflowDelete?: WorkflowOut;
 }>({
   workflows: [],
   loading: true,
+  potentialWorkflowDelete: undefined,
   updateWorkflow: {
     short_description: "",
     name: "",
@@ -33,7 +36,7 @@ const workflowsState = reactive<{
   },
 });
 
-function workflowUpdateClick(workflow: WorkflowOut) {
+function workflowUpdateClicked(workflow: WorkflowOut) {
   workflowsState.updateWorkflow = workflow;
 }
 
@@ -49,6 +52,24 @@ function workflowUpdated(version: WorkflowVersionFull) {
     });
 }
 
+function workflowDeleteClicked(workflow: WorkflowOut) {
+  workflowsState.potentialWorkflowDelete = workflow;
+}
+
+function confirmedWorkflowDelete(workflow_id?: string) {
+  if (workflow_id) {
+    WorkflowService.workflowDeleteWorkflow(workflow_id)
+      .then(() => {
+        workflowsState.workflows = workflowsState.workflows.filter(
+          (workflow) => workflow.workflow_id !== workflow_id
+        );
+      })
+      .finally(() => {
+        workflowsState.potentialWorkflowDelete = undefined;
+      });
+  }
+}
+
 onMounted(() => {
   WorkflowService.workflowListWorkflows(
     undefined,
@@ -74,6 +95,15 @@ onMounted(() => {
     modal-i-d="updateWorkflowModal"
     @workflow-updated="workflowUpdated"
   />
+  <delete-modal
+    modal-i-d="deleteWorkflowModal"
+    :object-name-delete="workflowsState.potentialWorkflowDelete?.name"
+    @confirm-delete="
+      confirmedWorkflowDelete(
+        workflowsState.potentialWorkflowDelete?.workflow_id
+      )
+    "
+  />
   <div
     class="row m-2 border-bottom border-light mb-4 justify-content-between align-items-center pb-2"
   >
@@ -96,7 +126,8 @@ onMounted(() => {
         :key="workflow.workflow_id"
         :workflow="workflow"
         :loading="false"
-        @workflow-update-click="workflowUpdateClick"
+        @workflow-update-click="workflowUpdateClicked"
+        @workflow-delete-click="workflowDeleteClicked"
       />
     </card-transition-group>
     <div v-else class="text-center mt-5 fs-2">
-- 
GitLab