From cfa077b5c58d2d96fb8685382a15e74017162c4d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laurent=20L=C3=A9cluse?= <laurent.lecluse@unicaen.fr>
Date: Tue, 7 Jan 2025 16:28:13 +0100
Subject: [PATCH] =?UTF-8?q?[Fix]=20Les=20composants=20Vue=20sont=20aussi?=
 =?UTF-8?q?=20charg=C3=A9s=20=C3=A0=20l'int=C3=A9rieur=20de=20HTML=20renvo?=
 =?UTF-8?q?y=C3=A9=20en=20Ajax?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 CHANGELOG.md      |  6 ++++++
 js/Client/main.js | 52 +++++++++++++++++++++++++++++++++--------------
 2 files changed, 43 insertions(+), 15 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index b094fa7..0df59bc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,12 @@
 CHANGELOG
 =========
 
+6.2.6 (07/01/2025)
+------------------
+
+- [Fix] Les composants Vue sont aussi chargés à l'intérieur de HTML renvoyé en Ajax
+
+
 6.2.5 (19/09/2024)
 ------------------
 
diff --git a/js/Client/main.js b/js/Client/main.js
index b1dda1c..51698c0 100644
--- a/js/Client/main.js
+++ b/js/Client/main.js
@@ -1,54 +1,76 @@
 import {createApp} from 'vue';
 import {createBootstrap} from 'bootstrap-vue-next';
-
-// on met en place le client d'UnicaenVue
 import unicaenVue from './unicaenVue';
 
 function init(vues, options)
 {
-    const components = {}
+    const components = {};
 
-    if (undefined === options){
+    if (undefined === options) {
         options = {};
     }
 
+    // Convertir les chemins des composants en noms de composants
     for (const path in vues) {
         let compPath = path.slice(2, -4);
         let compName = compPath.replaceAll('/', '');
-
         components[compName] = vues[path].default;
     }
 
-    // instantiate the Vue apps
-    // Note our lookup is a wrapping div with .vue-app class
-    for (const el of document.getElementsByClassName('vue-app')) {
+    // Fonction pour initialiser une application Vue sur un élément
+    function mountVueApp(el)
+    {
         let app = createApp({
             template: el.innerHTML,
             components: components
         });
 
-        if (undefined !== options.beforeMount){
+        if (undefined !== options.beforeMount) {
             options.beforeMount(app);
         }
 
-        //autoload de tous les composants déclarés
-        if (undefined !== options.autoloads){
-
+        // Autoload des composants déclarés
+        if (undefined !== options.autoloads) {
             for (const alias in options.autoloads) {
                 let compName = options.autoloads[alias].replaceAll('/', '');
                 app.component(alias, components[compName]);
             }
         }
 
-        app.use(createBootstrap({components: true, directives: true}))
+        app.use(createBootstrap({components: true, directives: true}));
         app.mount(el);
 
-        if (undefined !== options.afterMount){
+        if (undefined !== options.afterMount) {
             options.afterMount(app);
         }
     }
+
+    // Initialiser les applications Vue sur les éléments existants
+    for (const el of document.getElementsByClassName('vue-app')) {
+        mountVueApp(el);
+    }
+
+    // Observer les changements du DOM pour détecter les nouveaux éléments chargés en AJAX
+    const observer = new MutationObserver((mutationsList) => {
+        for (const mutation of mutationsList) {
+            if (mutation.type === 'childList') {
+                // Vérifier si de nouveaux éléments avec la classe .vue-app ont été ajoutés
+                for (const node of mutation.addedNodes) {
+                    if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains('vue-app')) {
+                        mountVueApp(node);
+                    }
+                }
+            }
+        }
+    });
+
+    // Démarrer l'observation du DOM
+    observer.observe(document.body, {
+        childList: true, // Observer les ajouts/suppressions d'enfants
+        subtree: true,   // Observer tout le sous-arbre du DOM
+    });
 }
 
 export default {
     init
-}
\ No newline at end of file
+};
\ No newline at end of file
-- 
GitLab