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

(-)a/koha-tmpl/intranet-tmpl/prog/js/vue/modules/islands.ts (-46 / +48 lines)
Lines 4-57 import { useMainStore } from "../stores/main"; Link Here
4
import { useNavigationStore } from "../stores/navigation";
4
import { useNavigationStore } from "../stores/navigation";
5
5
6
/**
6
/**
7
 * A registry for Vue components.
7
 * Represents a web component with an import function and optional configuration.
8
 * @type {Map<string, () => Promise<Component>>}
8
 * @typedef {Object} WebComponentDynamicImport
9
 * @property {function(): Promise<Component>} importFn - A function that imports the component dynamically.
10
 * @property {Object} [config] - An optional configuration object for the web component.
11
 * @property {Array<string>} [config.stores] - An optional array of strings representing store names associated with the component.
9
 */
12
 */
10
interface WebComponent {
13
type WebComponentDynamicImport = {
11
    importFn: () => Promise<Component>;
14
    importFn: () => Promise<Component>;
12
    config?: {
15
    config?: Record<"stores", Array<string>>;
13
        stores: string[];
16
};
14
    };
17
15
}
18
/**
16
export const componentRegistry: Map<string, WebComponent> = new Map([
19
 * A registry for Vue components.
17
    [
20
 * @type {Map<string, WebComponentDynamicImport>}
18
        "hello-islands",
21
 */
19
        {
22
export const componentRegistry: Map<string, WebComponentDynamicImport> =
20
            importFn: async () => {
23
    new Map([
21
                const module = await import(
24
        [
22
                    /* webpackChunkName: "hello-islands" */
25
            "hello-islands",
23
                    "../components/HelloIslands.vue"
26
            {
24
                );
27
                importFn: async () => {
25
                return module.default;
28
                    const module = await import(
26
            },
29
                        /* webpackChunkName: "hello-islands" */
27
            config: {
30
                        "../components/HelloIslands.vue"
28
                stores: ["mainStore", "navigationStore"],
31
                    );
32
                    return module.default;
33
                },
34
                config: {
35
                    stores: ["mainStore", "navigationStore"],
36
                },
29
            },
37
            },
30
        },
38
        ],
31
    ],
39
        [
32
    [
40
            "hello-world",
33
        "hello-world",
41
            {
34
        {
42
                importFn: async () => {
35
            importFn: async () => {
43
                    const module = await import(
36
                const module = await import(
44
                        /* webpackChunkName: "hello-world" */
37
                    /* webpackChunkName: "hello-world" */
45
                        "../components/HelloWorld.vue"
38
                    "../components/HelloWorld.vue"
46
                    );
39
                );
47
                    return module.default;
40
                return module.default;
48
                },
41
            },
49
            },
42
        },
50
        ],
43
    ],
51
    ]);
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
};
55
52
56
/**
53
/**
57
 * Hydrates custom elements by scanning the document and loading only necessary components.
54
 * Hydrates custom elements by scanning the document and loading only necessary components.
Lines 59-64 const storesMatrix = { Link Here
59
 */
56
 */
60
export function hydrate(): void {
57
export function hydrate(): void {
61
    window.requestIdleCallback(async () => {
58
    window.requestIdleCallback(async () => {
59
        const pinia = createPinia();
60
        const storesMatrix = {
61
            mainStore: useMainStore(pinia),
62
            navigationStore: useNavigationStore(pinia),
63
        };
64
62
        const islandTagNames = Array.from(componentRegistry.keys()).join(", ");
65
        const islandTagNames = Array.from(componentRegistry.keys()).join(", ");
63
        const requestedIslands = new Set(
66
        const requestedIslands = new Set(
64
            Array.from(document.querySelectorAll(islandTagNames)).map(element =>
67
            Array.from(document.querySelectorAll(islandTagNames)).map(element =>
Lines 79-85 export function hydrate(): void { Link Here
79
                    shadowRoot: false,
82
                    shadowRoot: false,
80
                    ...(config && {
83
                    ...(config && {
81
                        configureApp(app) {
84
                        configureApp(app) {
82
                            if (config.stores && config.stores.length > 0) {
85
                            if (config.stores?.length > 0) {
83
                                app.use(pinia);
86
                                app.use(pinia);
84
                                config.stores.forEach(store => {
87
                                config.stores.forEach(store => {
85
                                    app.provide(store, storesMatrix[store]);
88
                                    app.provide(store, storesMatrix[store]);
86
- 

Return to bug 37911