From c133980f94d5f689164e6156a373b555e8f3b904 Mon Sep 17 00:00:00 2001
From: Pedro Amorim <pedro.amorim@ptfs-europe.com>
Date: Tue, 8 Aug 2023 11:14:11 +0000
Subject: [PATCH] Bug 34497: Dialog component should allow for optional input
 options on confirmation modal

Currently supports 'Text' or 'Date' inputs
---
 .../prog/js/vue/components/Dialog.vue         | 74 ++++++++++++++++++-
 .../intranet-tmpl/prog/js/vue/stores/main.js  | 17 ++++-
 2 files changed, 89 insertions(+), 2 deletions(-)

diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Dialog.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Dialog.vue
index bb50be5c8c..452038cd6d 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Dialog.vue
+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Dialog.vue
@@ -12,11 +12,42 @@
         <div class="dialog alert confirmation">
             <h1 v-html="confirmation.title"></h1>
             <p v-html="confirmation.message"></p>
+            <div class="inputs" v-if="confirmation.inputs">
+                <form ref="confirmationform">
+                    <div
+                        class="row"
+                        v-for="input in confirmation.inputs"
+                        v-bind:key="input.id"
+                    >
+                        <div class="col-md-6">
+                            <label
+                                :for="`confirmation_input_${input.id}`"
+                                v-bind:class="{ required: input.required }"
+                                >{{ input.label }}:</label
+                            >
+                        </div>
+                        <div class="col-md-6">
+                            <flat-pickr
+                                v-if="input.type == 'Date'"
+                                :id="`confirmation_input_${input.id}`"
+                                v-model="input.value"
+                                :required="input.required"
+                                :config="fp_config"
+                            />
+                            <input
+                                v-if="input.type == 'Text'"
+                                :id="`confirmation_input_${input.id}`"
+                                v-model="input.value"
+                            />
+                        </div>
+                    </div>
+                </form>
+            </div>
             <button
                 v-if="accept_callback"
                 id="accept_modal"
                 class="approve"
-                @click="accept_callback"
+                @click="submit"
             >
                 <i class="fa fa-fw fa-check"></i>
                 <span v-html="confirmation.accept_label"></span>
@@ -44,7 +75,27 @@
 <script>
 import { inject } from "vue"
 import { storeToRefs } from "pinia"
+import flatPickr from "vue-flatpickr-component"
 export default {
+    data() {
+        return {
+            fp_config: flatpickr_defaults,
+        }
+    },
+    methods: {
+        submit: function (e) {
+            if (
+                this.confirmation.inputs &&
+                this.confirmation.inputs.filter(
+                    input => input.required && input.value == null
+                ).length
+            ) {
+                this.$refs.confirmationform.reportValidity()
+            } else {
+                this.accept_callback()
+            }
+        },
+    },
     setup() {
         const mainStore = inject("mainStore")
         const {
@@ -69,6 +120,9 @@ export default {
             removeConfirmationMessages,
         }
     },
+    components: {
+        flatPickr,
+    },
 }
 </script>
 
@@ -116,4 +170,22 @@ export default {
     align-items: center;
     justify-content: center;
 }
+.confirmation .inputs {
+    margin-top: 0.4em;
+}
+.confirmation .inputs input,
+:deep(.flatpickr-input) {
+    width: auto;
+    margin: 0px;
+    float: left;
+}
+
+:deep(.flatpickr-input) {
+    padding-left: 20px;
+}
+
+.confirmation .inputs label {
+    padding: 0.4em;
+    float: right;
+}
 </style>
diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/main.js b/koha-tmpl/intranet-tmpl/prog/js/vue/stores/main.js
index c212a5301c..7a0c9e6516 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/main.js
+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/stores/main.js
@@ -38,10 +38,25 @@ export const useMainStore = defineStore("main", {
             this.displayed_already =
                 displayed; /* Is displayed on the current view */
         },
+        /**
+         * Sets a confirmation dialog pop-up modal
+         * @param  {Object} confirmation Confirmation details
+         * @param  {string} confirmation.title Shows at the top of the dialog
+         * @param  {string} confirmation.message Shows under the title
+         * @param  {string} confirmation.accept_label Label for the 'accept' button
+         * @param  {string} confirmation.cancel_label Label for the 'cancel' button
+         * @param  {Array}  confirmation.inputs Optional inputs details
+         * @param  {string} confirmation.inputs.id Key code of the input, used for HTML elements id
+         * @param  {string} confirmation.inputs.type Type of the input, 'Date' or 'Text'
+         * @param  {string} confirmation.inputs.value Initial/default value
+         * @param  {string} confirmation.inputs.required Sets the input required or not
+         * @param  {string} confirmation.inputs.label Label that sits next to the input
+         * @callback accept_callback Callback function called after the user accepts the dialog. Carries over the user input if inputs exist.
+         */
         setConfirmationDialog(confirmation, accept_callback, displayed = true) {
             if (accept_callback) {
                 this._accept_callback = async () => {
-                    await accept_callback();
+                    await accept_callback(confirmation);
                     this.removeConfirmationMessages();
                 };
             }
-- 
2.30.2