View | Details | Raw Unified | Return to bug 37911
Collapse All | Expand All

(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/components/HelloIslands.vue (+15 lines)
Lines 5-10 Link Here
5
    <!-- Display message prop -->
5
    <!-- Display message prop -->
6
    <p v-if="message">{{ message }}</p>
6
    <p v-if="message">{{ message }}</p>
7
7
8
    <!-- Display store data -->
9
    <p v-if="stringFromStore">{{ stringFromStore }}</p>
10
    <p v-if="anotherStoreString">{{ anotherStoreString }}</p>
11
8
    <!-- Reactive counter example -->
12
    <!-- Reactive counter example -->
9
    <p>Counter: {{ count }}</p>
13
    <p>Counter: {{ count }}</p>
10
    <!-- Koha's bootstrap works in here! -->
14
    <!-- Koha's bootstrap works in here! -->
Lines 15-20 Link Here
15
19
16
<script>
20
<script>
17
import { ref } from "vue"
21
import { ref } from "vue"
22
import { inject } from "vue"
18
23
19
export default {
24
export default {
20
    props: {
25
    props: {
Lines 27-32 export default { Link Here
27
            default: "crimson",
32
            default: "crimson",
28
        },
33
        },
29
    },
34
    },
35
    setup() {
36
        const mainStore = inject("mainStore")
37
        const { stringFromStore } = mainStore
38
        const navigationStore = inject("navigationStore")
39
        const { anotherStoreString } = navigationStore
40
        return {
41
            stringFromStore,
42
            anotherStoreString,
43
        }
44
    },
30
    data() {
45
    data() {
31
        return {
46
        return {
32
            count: 0,
47
            count: 0,
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/modules/islands.ts (-13 / +49 lines)
Lines 1-32 Link Here
1
import { Component, defineCustomElement } from "vue";
1
import { Component, defineCustomElement } from "vue";
2
import { createPinia } from "pinia";
3
import { useMainStore } from "../stores/main";
4
import { useNavigationStore } from "../stores/navigation";
2
5
3
/**
6
/**
4
 * A registry for Vue components.
7
 * A registry for Vue components.
5
 * @type {Map<string, () => Promise<Component>>}
8
 * @type {Map<string, () => Promise<Component>>}
6
 */
9
 */
7
export const componentRegistry: Map<string, () => Promise<Component>> = new Map(
10
interface WebComponent {
11
    importFn: () => Promise<Component>;
12
    config?: {
13
        stores: string[];
14
    };
15
}
16
export const componentRegistry: Map<string, WebComponent> = new Map([
8
    [
17
    [
9
        [
18
        "hello-islands",
10
            "hello-islands",
19
        {
11
            async () => {
20
            importFn: async () => {
12
                const module = await import(
21
                const module = await import(
13
                    /* webpackChunkName: "hello-islands" */
22
                    /* webpackChunkName: "hello-islands" */
14
                    "../components/HelloIslands.vue"
23
                    "../components/HelloIslands.vue"
15
                );
24
                );
16
                return module.default;
25
                return module.default;
17
            },
26
            },
18
        ],
27
            config: {
19
        [
28
                stores: ["mainStore", "navigationStore"],
20
            "hello-world",
29
            },
21
            async () => {
30
        },
31
    ],
32
    [
33
        "hello-world",
34
        {
35
            importFn: async () => {
22
                const module = await import(
36
                const module = await import(
23
                    /* webpackChunkName: "hello-world" */ "../components/HelloWorld.vue"
37
                    /* webpackChunkName: "hello-world" */
38
                    "../components/HelloWorld.vue"
24
                );
39
                );
25
                return module.default;
40
                return module.default;
26
            },
41
            },
27
        ],
42
        },
28
    ]
43
    ],
29
);
44
]);
45
46
const pinia = createPinia();
47
48
const mainStore = useMainStore(pinia);
49
const navigationStore = useNavigationStore(pinia);
50
51
const storesMatrix = {
52
    mainStore,
53
    navigationStore,
54
};
30
55
31
/**
56
/**
32
 * Hydrates custom elements by scanning the document and loading only necessary components.
57
 * Hydrates custom elements by scanning the document and loading only necessary components.
Lines 42-48 export function hydrate(): void { Link Here
42
        );
67
        );
43
68
44
        requestedIslands.forEach(async name => {
69
        requestedIslands.forEach(async name => {
45
            const importFn = componentRegistry.get(name);
70
            const { importFn, config } = componentRegistry.get(name);
46
            if (!importFn) {
71
            if (!importFn) {
47
                return;
72
                return;
48
            }
73
            }
Lines 52-57 export function hydrate(): void { Link Here
52
                name,
77
                name,
53
                defineCustomElement(component as any, {
78
                defineCustomElement(component as any, {
54
                    shadowRoot: false,
79
                    shadowRoot: false,
80
                    ...(config && {
81
                        configureApp(app) {
82
                            if (config.stores && config.stores.length > 0) {
83
                                app.use(pinia);
84
                                config.stores.forEach(store => {
85
                                    app.provide(store, storesMatrix[store]);
86
                                });
87
                            }
88
                            // Further config options can be added here as we expand this further
89
                        },
90
                    }),
55
                })
91
                })
56
            );
92
            );
57
        });
93
        });
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/main.js (+1 lines)
Lines 12-17 export const useMainStore = defineStore("main", { Link Here
12
        displayed_already: false,
12
        displayed_already: false,
13
        _is_submitting: false,
13
        _is_submitting: false,
14
        _is_loading: false,
14
        _is_loading: false,
15
        stringFromStore: "Hello from main store",
15
    }),
16
    }),
16
    actions: {
17
    actions: {
17
        setMessage(message, displayed = false) {
18
        setMessage(message, displayed = false) {
(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/navigation.js (-1 / +1 lines)
Lines 11-16 export const useNavigationStore = defineStore("navigation", { Link Here
11
        },
11
        },
12
        current: null,
12
        current: null,
13
        params: {},
13
        params: {},
14
        anotherStoreString: "Hello from nav store",
14
    }),
15
    }),
15
    actions: {
16
    actions: {
16
        setRoutes(routesDef) {
17
        setRoutes(routesDef) {
17
- 

Return to bug 37911