From b8fda46525a32573fcb8dc199fb9f8ffb2ae6d9d Mon Sep 17 00:00:00 2001
From: Matt Blenkinsop <matt.blenkinsop@ptfs-europe.com>
Date: Mon, 16 Sep 2024 09:28:54 +0000
Subject: [PATCH] Bug 37911: (follow-up) Enable usage of dependencies

---
 .../prog/js/vue/components/HelloIslands.vue   | 15 +++++
 .../prog/js/vue/modules/islands.ts            | 62 +++++++++++++++----
 .../intranet-tmpl/prog/js/vue/stores/main.js  |  1 +
 .../prog/js/vue/stores/navigation.js          |  1 +
 4 files changed, 66 insertions(+), 13 deletions(-)

diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/HelloIslands.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/HelloIslands.vue
index 9d8350f2877..ef83b0dbe07 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/HelloIslands.vue
+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/HelloIslands.vue
@@ -5,6 +5,10 @@
     <!-- Display message prop -->
     <p v-if="message">{{ message }}</p>
 
+    <!-- Display store data -->
+    <p v-if="stringFromStore">{{ stringFromStore }}</p>
+    <p v-if="anotherStoreString">{{ anotherStoreString }}</p>
+
     <!-- Reactive counter example -->
     <p>Counter: {{ count }}</p>
     <!-- Koha's bootstrap works in here! -->
@@ -15,6 +19,7 @@
 
 <script>
 import { ref } from "vue"
+import { inject } from "vue"
 
 export default {
     props: {
@@ -27,6 +32,16 @@ export default {
             default: "crimson",
         },
     },
+    setup() {
+        const mainStore = inject("mainStore")
+        const { stringFromStore } = mainStore
+        const navigationStore = inject("navigationStore")
+        const { anotherStoreString } = navigationStore
+        return {
+            stringFromStore,
+            anotherStoreString,
+        }
+    },
     data() {
         return {
             count: 0,
diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/modules/islands.ts b/koha-tmpl/intranet-tmpl/prog/js/vue/modules/islands.ts
index e5e8ae76b9d..1571d2ced6c 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/modules/islands.ts
+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/modules/islands.ts
@@ -1,32 +1,57 @@
 import { Component, defineCustomElement } from "vue";
+import { createPinia } from "pinia";
+import { useMainStore } from "../stores/main";
+import { useNavigationStore } from "../stores/navigation";
 
 /**
  * A registry for Vue components.
  * @type {Map<string, () => Promise<Component>>}
  */
-export const componentRegistry: Map<string, () => Promise<Component>> = new Map(
+interface WebComponent {
+    importFn: () => Promise<Component>;
+    config?: {
+        stores: string[];
+    };
+}
+export const componentRegistry: Map<string, WebComponent> = new Map([
     [
-        [
-            "hello-islands",
-            async () => {
+        "hello-islands",
+        {
+            importFn: async () => {
                 const module = await import(
                     /* webpackChunkName: "hello-islands" */
                     "../components/HelloIslands.vue"
                 );
                 return module.default;
             },
-        ],
-        [
-            "hello-world",
-            async () => {
+            config: {
+                stores: ["mainStore", "navigationStore"],
+            },
+        },
+    ],
+    [
+        "hello-world",
+        {
+            importFn: async () => {
                 const module = await import(
-                    /* webpackChunkName: "hello-world" */ "../components/HelloWorld.vue"
+                    /* webpackChunkName: "hello-world" */
+                    "../components/HelloWorld.vue"
                 );
                 return module.default;
             },
-        ],
-    ]
-);
+        },
+    ],
+]);
+
+const pinia = createPinia();
+
+const mainStore = useMainStore(pinia);
+const navigationStore = useNavigationStore(pinia);
+
+const storesMatrix = {
+    mainStore,
+    navigationStore,
+};
 
 /**
  * Hydrates custom elements by scanning the document and loading only necessary components.
@@ -42,7 +67,7 @@ export function hydrate(): void {
         );
 
         requestedIslands.forEach(async name => {
-            const importFn = componentRegistry.get(name);
+            const { importFn, config } = componentRegistry.get(name);
             if (!importFn) {
                 return;
             }
@@ -52,6 +77,17 @@ export function hydrate(): void {
                 name,
                 defineCustomElement(component as any, {
                     shadowRoot: false,
+                    ...(config && {
+                        configureApp(app) {
+                            if (config.stores && config.stores.length > 0) {
+                                app.use(pinia);
+                                config.stores.forEach(store => {
+                                    app.provide(store, storesMatrix[store]);
+                                });
+                            }
+                            // Further config options can be added here as we expand this further
+                        },
+                    }),
                 })
             );
         });
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 7a0c9e65166..b9317d79721 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/main.js
+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/stores/main.js
@@ -12,6 +12,7 @@ export const useMainStore = defineStore("main", {
         displayed_already: false,
         _is_submitting: false,
         _is_loading: false,
+        stringFromStore: "Hello from main store",
     }),
     actions: {
         setMessage(message, displayed = false) {
diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/navigation.js b/koha-tmpl/intranet-tmpl/prog/js/vue/stores/navigation.js
index 1e3ecb58b36..e76802b7e2e 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/navigation.js
+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/stores/navigation.js
@@ -11,6 +11,7 @@ export const useNavigationStore = defineStore("navigation", {
         },
         current: null,
         params: {},
+        anotherStoreString: "Hello from nav store",
     }),
     actions: {
         setRoutes(routesDef) {
-- 
2.39.3 (Apple Git-146)