From 471a7d8f0d4f18d63ea7cf4b94228258015194a4 Mon Sep 17 00:00:00 2001
From: Pedro Amorim <pedro.amorim@ptfs-europe.com>
Date: Mon, 14 Oct 2024 11:52:48 +0000
Subject: [PATCH] Bug 37301: DRY delete

---
 .../prog/js/vue/components/BaseResource.vue   | 67 +++++++++++++++++++
 .../vue/components/ERM/AgreementResource.vue  |  7 ++
 .../js/vue/components/ERM/AgreementsList.vue  | 29 +-------
 .../js/vue/components/ERM/AgreementsShow.vue  | 32 +--------
 4 files changed, 76 insertions(+), 59 deletions(-)

diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/BaseResource.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/BaseResource.vue
index 65f93af2cef..3e083167012 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/BaseResource.vue
+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/BaseResource.vue
@@ -48,6 +48,73 @@ export default {
                 name: this.add_component,
             })
         },
+        /**
+         * Navigates to the list page of the given resource.
+         *
+         * @return {void}
+         */
+        goToResourceList: function () {
+            this.$router.push({
+                name: this.list_component,
+            })
+        },
+        /**
+         * Resource deletion handler.
+         * Accepts an optional callback function to run after deletion.
+         * If no callback is provided, does the following:
+         * - If deleting from show component, navigates to resource list component.
+         * - If deleting from resource list component, redraws the table.
+         *
+         * @param {Object} resource - The resource to delete (optional)
+         * @param {Object} callback - Callback to call after deletion (optional)
+         * @return {void}
+         */
+        doResourceDelete: function (resource, callback) {
+            let resource_id = resource
+                ? resource[this.id_attr]
+                : this[this.resource_name][this.id_attr]
+            let resource_name = resource
+                ? resource[this.name_attr]
+                : this[this.resource_name][this.name_attr]
+
+            this.setConfirmationDialog(
+                {
+                    title: this.$__(
+                        "Are you sure you want to remove this %s?"
+                    ).format(this.i18n.display_name.toLowerCase()),
+                    message: resource_name,
+                    accept_label: this.$__("Yes, delete"),
+                    cancel_label: this.$__("No, do not delete"),
+                },
+                () => {
+                    this.api_client.delete(resource_id).then(
+                        success => {
+                            this.setMessage(
+                                this.$__("%s %s deleted").format(
+                                    this.i18n.display_name,
+                                    resource_name
+                                ),
+                                true
+                            )
+                            if (typeof callback === "function") {
+                                callback()
+                            } else {
+                                if (
+                                    this.$options.name === this.list_component
+                                ) {
+                                    this.$refs.table.redraw(this.table_url())
+                                } else if (
+                                    this.$options.name === this.show_component
+                                ) {
+                                    this.goToResourceList()
+                                }
+                            }
+                        },
+                        error => {}
+                    )
+                }
+            )
+        },
     },
     name: "BaseResource",
     props: {
diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementResource.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementResource.vue
index 88025188146..6e0fd17327f 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementResource.vue
+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementResource.vue
@@ -1,5 +1,6 @@
 <script>
 import BaseResource from "../BaseResource.vue"
+import { APIClient } from "../../fetch/api-client.js"
 
 export default {
     extends: BaseResource,
@@ -7,10 +8,16 @@ export default {
         return {
             ...BaseResource.setup({
                 resource_name: "agreement",
+                name_attr: "name",
                 id_attr: "agreement_id",
                 show_component: "AgreementsShow",
+                list_component: "AgreementsList",
                 add_component: "AgreementsFormAdd",
                 edit_component: "AgreementsFormAddEdit",
+                api_client: APIClient.erm.agreements,
+                i18n: {
+                    display_name: __("Agreement"),
+                },
             }),
             //AgreementResource specific setup here
         }
diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsList.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsList.vue
index d256e1ce792..25063a6acb6 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsList.vue
+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsList.vue
@@ -47,7 +47,7 @@
                 :searchable_av_options="searchable_av_options"
                 @show="goToResourceShow"
                 @edit="goToResourceEdit"
-                @delete="doDelete"
+                @delete="doResourceDelete"
                 @select="doSelect"
             ></KohaTable>
         </div>
@@ -222,33 +222,6 @@ export default {
                     })
                 })
         },
-        doDelete: function (agreement, dt, event) {
-            this.setConfirmationDialog(
-                {
-                    title: this.$__(
-                        "Are you sure you want to remove this agreement?"
-                    ),
-                    message: agreement.name,
-                    accept_label: this.$__("Yes, delete"),
-                    cancel_label: this.$__("No, do not delete"),
-                },
-                () => {
-                    const client = APIClient.erm
-                    client.agreements.delete(agreement.agreement_id).then(
-                        success => {
-                            this.setMessage(
-                                this.$__("Agreement %s deleted").format(
-                                    agreement.name
-                                ),
-                                true
-                            )
-                            dt.draw()
-                        },
-                        error => {}
-                    )
-                }
-            )
-        },
         doSelect: function (agreement, dt, event) {
             this.$emit("select-agreement", agreement.agreement_id)
             this.$emit("close")
diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsShow.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsShow.vue
index 36ed6d13e70..a243a3b36b7 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsShow.vue
+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsShow.vue
@@ -8,7 +8,7 @@
             />
             <ToolbarButton
                 action="delete"
-                @delete_resource="delete_agreement"
+                @delete-resource="doResourceDelete"
             />
         </Toolbar>
 
@@ -398,36 +398,6 @@ export default {
                 error => {}
             )
         },
-        delete_agreement: function () {
-            let agreement_id = this.agreement.agreement_id
-            let agreement_name = this.agreement.name
-
-            this.setConfirmationDialog(
-                {
-                    title: this.$__(
-                        "Are you sure you want to remove this agreement?"
-                    ),
-                    message: agreement_name,
-                    accept_label: this.$__("Yes, delete"),
-                    cancel_label: this.$__("No, do not delete"),
-                },
-                () => {
-                    const client = APIClient.erm
-                    client.agreements.delete(agreement_id).then(
-                        success => {
-                            this.setMessage(
-                                this.$__("Agreement %s deleted").format(
-                                    agreement_name
-                                ),
-                                true
-                            )
-                            this.$router.push({ name: "AgreementsList" })
-                        },
-                        error => {}
-                    )
-                }
-            )
-        },
     },
     components: { Toolbar, ToolbarButton, AdditionalFieldsDisplay },
     name: "AgreementsShow",
-- 
2.39.5