refactor du système de routing (EXPORTS DES SETTINGS DRUPAL)
This commit is contained in:
		
							
								
								
									
										18
									
								
								config/sync/rest.resource.entity.path_alias.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								config/sync/rest.resource.entity.path_alias.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					uuid: f904b753-75c5-477e-bd9c-7259f9bfdf9b
 | 
				
			||||||
 | 
					langcode: fr
 | 
				
			||||||
 | 
					status: false
 | 
				
			||||||
 | 
					dependencies:
 | 
				
			||||||
 | 
					  module:
 | 
				
			||||||
 | 
					    - path_alias
 | 
				
			||||||
 | 
					    - serialization
 | 
				
			||||||
 | 
					    - user
 | 
				
			||||||
 | 
					id: entity.path_alias
 | 
				
			||||||
 | 
					plugin_id: 'entity:path_alias'
 | 
				
			||||||
 | 
					granularity: resource
 | 
				
			||||||
 | 
					configuration:
 | 
				
			||||||
 | 
					  methods:
 | 
				
			||||||
 | 
					    - GET
 | 
				
			||||||
 | 
					  formats:
 | 
				
			||||||
 | 
					    - json
 | 
				
			||||||
 | 
					  authentication:
 | 
				
			||||||
 | 
					    - cookie
 | 
				
			||||||
@@ -269,7 +269,7 @@ display:
 | 
				
			|||||||
            popupAnchor:
 | 
					            popupAnchor:
 | 
				
			||||||
              x: ''
 | 
					              x: ''
 | 
				
			||||||
              'y': ''
 | 
					              'y': ''
 | 
				
			||||||
            html: "<div></div>\r\n<div></div>\r\n<div></div>\r\n<div class=\"nid\">{{ nid }}</div>\r\n<div class=\"couleur\">{{ field_couleur }}</div>"
 | 
					            html: "<div></div>\r\n<div></div>\r\n<div></div>\r\n<div class=\"url\">[node:url]</div>\r\n<div class=\"couleur\">[node:field_couleur]</div>"
 | 
				
			||||||
            html_class: 'leaflet-map-divicon '
 | 
					            html_class: 'leaflet-map-divicon '
 | 
				
			||||||
            circle_marker_options: '{"radius":100,"color":"red","fillColor":"#f03","fillOpacity":0.5}'
 | 
					            circle_marker_options: '{"radius":100,"color":"red","fillColor":"#f03","fillOpacity":0.5}'
 | 
				
			||||||
          leaflet_markercluster:
 | 
					          leaflet_markercluster:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,253 +1,49 @@
 | 
				
			|||||||
import { createApp } from 'vue'
 | 
					import { initVueContentModale } from './utils/vue-setup';
 | 
				
			||||||
import { createPinia } from 'pinia'
 | 
					import { processClickableElements } from './utils/process-clickable-elements';
 | 
				
			||||||
 | 
					import { setMenuToggle, setHamburgerWhenLogged } from './utils/layout-setup';
 | 
				
			||||||
 | 
					import { initFirstLoadRouting, handleClickableElements } from './utils/handle-navigation';
 | 
				
			||||||
 | 
					import { setupMapStore } from './utils/map-setup';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import '../scss/main.scss'
 | 
					import '../scss/main.scss'
 | 
				
			||||||
import Modale from './vuejs/Modale.vue'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import VueImageZoomer from 'vue-image-zoomer'
 | 
					// https://www.drupal.org/docs/drupal-apis/javascript-api/javascript-api-overview
 | 
				
			||||||
import 'vue-image-zoomer/dist/style.css';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { useContentStore } from './stores/content';
 | 
					 | 
				
			||||||
import { useMapStore } from './stores/mapState';
 | 
					 | 
				
			||||||
import router from './router/router';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Working with the history API
 | 
					 | 
				
			||||||
// https://developer.mozilla.org/en-US/docs/Web/API/History_API/Working_with_the_History_API
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// /**
 | 
					 | 
				
			||||||
//  * @file
 | 
					 | 
				
			||||||
//  * reha behaviors.
 | 
					 | 
				
			||||||
//  * https://www.drupal.org/docs/drupal-apis/javascript-api/javascript-api-overview
 | 
					 | 
				
			||||||
//  */
 | 
					 | 
				
			||||||
// (function (Drupal) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//   'use strict';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//   Drupal.behaviors.reha = {
 | 
					 | 
				
			||||||
//     attach: function (context, settings) {
 | 
					 | 
				
			||||||
//       console.log('It works!');
 | 
					 | 
				
			||||||
//     }
 | 
					 | 
				
			||||||
//   };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// } (Drupal));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function ($, Drupal, drupalSettings) {
 | 
					(function ($, Drupal, drupalSettings) {
 | 
				
			||||||
    const CaravaneTheme = function () {
 | 
					    const CaravaneTheme = function () {
 | 
				
			||||||
    const _is_front = drupalSettings.path.isFront;
 | 
					 | 
				
			||||||
    console.log('drupalSettings', drupalSettings);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        function init () {
 | 
					        function init () {
 | 
				
			||||||
      console.log('CaravaneTheme init()');
 | 
					            console.log('DrupalSettings', drupalSettings);            
 | 
				
			||||||
      initVues();
 | 
					 | 
				
			||||||
      toggleMenu();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function initVues(){
 | 
					            const baseUrl = window.location.protocol + "//" + window.location.host;
 | 
				
			||||||
      initVueContentModale();
 | 
					            const siteName = document.querySelector('#site_name').innerText;
 | 
				
			||||||
 | 
					            const { store, mapStore, router, route } = initVueContentModale();            
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					            setMenuToggle();
 | 
				
			||||||
 | 
					            setHamburgerWhenLogged(drupalSettings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function initVueContentModale(){
 | 
					            // https://www.drupal.org/docs/extending-drupal/contributed-modules/contributed-module-documentation/leaflet/leaflet-api
 | 
				
			||||||
      const app = createApp(Modale)
 | 
					 | 
				
			||||||
        .use(createPinia()).use(router)
 | 
					 | 
				
			||||||
        .use(VueImageZoomer);
 | 
					 | 
				
			||||||
      const store = useContentStore();
 | 
					 | 
				
			||||||
      const mapStore = useMapStore();
 | 
					 | 
				
			||||||
      app.mount('#content-modale');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      setHamburgerWhenLogged();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Drupal.behaviors.customLeafletInteraction = {
 | 
					            Drupal.behaviors.customLeafletInteraction = {
 | 
				
			||||||
                attach: function(context, settings) {
 | 
					                attach: function(context, settings) {
 | 
				
			||||||
                    $(context).on('leafletMapInit', function (e, settings, map, mapid, markers) { 
 | 
					                    $(context).on('leafletMapInit', function (e, settings, map, mapid, markers) { 
 | 
				
			||||||
            mapStore.defaultMapCenter = map.getCenter();
 | 
					                        const { 
 | 
				
			||||||
            mapStore.maxZoom = settings.settings.maxZoom;
 | 
					                            etapeListLinks,
 | 
				
			||||||
            mapStore.defaultZoom = settings.settings.minZoom;
 | 
					                            generalListLinks,
 | 
				
			||||||
 | 
					                            logoLink,
 | 
				
			||||||
 | 
					                            mapIcons,
 | 
				
			||||||
 | 
					                        } = processClickableElements();
 | 
				
			||||||
 | 
					                        const clickableElements = [...etapeListLinks, ...generalListLinks, logoLink, ...mapIcons];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        setupMapStore(mapStore, map, settings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            initFirstLoadRouting(store, map);
 | 
					                        initFirstLoadRouting(store, router, baseUrl, siteName);
 | 
				
			||||||
            processEtapeLinks(store, map);
 | 
					
 | 
				
			||||||
            processStaticLinks(store, map);
 | 
					                        handleClickableElements(clickableElements, store, router, baseUrl, siteName, mapStore);
 | 
				
			||||||
            processHeaderLogo(store, map);
 | 
					 | 
				
			||||||
            setupEtapeMapPopup(store, map);
 | 
					 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function initFirstLoadRouting(store, map){
 | 
					 | 
				
			||||||
      var decoupled_origin = JSON.parse(window.localStorage.getItem('decoupled_origin'));
 | 
					 | 
				
			||||||
      console.log('decoupled_origin', decoupled_origin);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if(decoupled_origin && decoupled_origin.entity_id){
 | 
					 | 
				
			||||||
        // Si c'était moi je ne ferais qu'une seule function fetchdata capable de dealer avec les différent type de contenus
 | 
					 | 
				
			||||||
        switch (decoupled_origin.entity_bundle) {
 | 
					 | 
				
			||||||
          case 'etape':
 | 
					 | 
				
			||||||
            store.fetchEtapeData(decoupled_origin.entity_id, map);
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
          case 'static':
 | 
					 | 
				
			||||||
            store.fetchEtapeData(decoupled_origin.entity_id, map);
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        router.push({
 | 
					 | 
				
			||||||
          // name: decoupled_origin.entity_bundle,
 | 
					 | 
				
			||||||
          path: decoupled_origin.url,
 | 
					 | 
				
			||||||
          // params: {
 | 
					 | 
				
			||||||
          //   title: decoupled_origin.entity_uuid
 | 
					 | 
				
			||||||
          // },
 | 
					 | 
				
			||||||
          // props: {
 | 
					 | 
				
			||||||
          //   nid: decoupled_origin.entity_id
 | 
					 | 
				
			||||||
          // }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // reset the storage
 | 
					 | 
				
			||||||
        window.localStorage.removeItem("decoupled_origin");
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function onClickContentLink(e, store, map, category){
 | 
					 | 
				
			||||||
      e.preventDefault();
 | 
					 | 
				
			||||||
      let a;
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      if (e.target.tagName !== 'IMG') {
 | 
					 | 
				
			||||||
        const li = e.target.closest('li');
 | 
					 | 
				
			||||||
        a = li.querySelector('a');
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        a = e.target.closest('a');
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
      let nid = a.dataset.nid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (category === 'etape') {
 | 
					 | 
				
			||||||
        store.fetchEtapeData(nid, map);
 | 
					 | 
				
			||||||
      } else if (category === 'static') {
 | 
					 | 
				
			||||||
        if (nid) {
 | 
					 | 
				
			||||||
          store.fetchStaticData(nid, map);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          store.emptyAll(null, map);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      return null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function processStaticLinks(store, map) {
 | 
					 | 
				
			||||||
      let general_link_fields = document.querySelectorAll('#menu > ul > li > a');
 | 
					 | 
				
			||||||
      for (let i =1; i <  general_link_fields.length; i ++) {
 | 
					 | 
				
			||||||
        let general_link_path = general_link_fields[i].getAttribute('data-drupal-link-system-path');
 | 
					 | 
				
			||||||
        const match = [...general_link_path.match(/^node\/(\d+)$/)];
 | 
					 | 
				
			||||||
        if (match) {
 | 
					 | 
				
			||||||
          const nid = match[1];
 | 
					 | 
				
			||||||
          general_link_fields[i].setAttribute('data-nid', parseInt(nid));
 | 
					 | 
				
			||||||
          general_link_fields[i].addEventListener('click', (e) => onClickContentLink(e, store, map, 'static'));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function processHeaderLogo(store, map) {
 | 
					 | 
				
			||||||
      const logo = document.querySelector('#block-caravane-logocaravane a');
 | 
					 | 
				
			||||||
      logo.addEventListener('click', (e) => onClickContentLink(e, store, map, 'static'));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function processEtapeLinks(store, map) {
 | 
					 | 
				
			||||||
      let etape_li = document.querySelectorAll('#etapes-liste li');
 | 
					 | 
				
			||||||
      etape_li.forEach((li) => {
 | 
					 | 
				
			||||||
        let etape_link = li.querySelector('a.etape-link');
 | 
					 | 
				
			||||||
        let nid = etape_link.dataset.nid;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        if (nid) {
 | 
					 | 
				
			||||||
          li.addEventListener('click', (e) => onClickContentLink(e, store, map, 'etape'));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        let couleur = etape_link.dataset.couleur;
 | 
					 | 
				
			||||||
        let iconElements = li.querySelectorAll('.icone-arret > div');
 | 
					 | 
				
			||||||
        for (let element of iconElements) {
 | 
					 | 
				
			||||||
          element.style.backgroundColor = couleur;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function toggleMenu() {
 | 
					 | 
				
			||||||
      const menuButton = document.querySelector('#block-caravane-mainnavigation > #menu');
 | 
					 | 
				
			||||||
      const menuContainer = document.querySelector('#block-caravane-mainnavigation > #menu > ul');
 | 
					 | 
				
			||||||
      const menuTitle = document.querySelector('#menu-title');
 | 
					 | 
				
			||||||
      const menuBurger = document.querySelector('#hamburger');
 | 
					 | 
				
			||||||
      const menuH2 = document.querySelector('#menu > h2');
 | 
					 | 
				
			||||||
      menuButton.addEventListener('click', (e) => { 
 | 
					 | 
				
			||||||
        setTimeout(() => {
 | 
					 | 
				
			||||||
          menuContainer.classList.toggle('open');
 | 
					 | 
				
			||||||
          menuTitle.classList.toggle('open');
 | 
					 | 
				
			||||||
          menuBurger.classList.toggle('open');
 | 
					 | 
				
			||||||
          menuH2.classList.toggle('open');
 | 
					 | 
				
			||||||
        }, 50);
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
      document.addEventListener('click', (e) => {
 | 
					 | 
				
			||||||
        if (!menuContainer.contains(e.target) && !menuBurger.contains(e.target)) {
 | 
					 | 
				
			||||||
          menuContainer.classList.remove('open');
 | 
					 | 
				
			||||||
          menuTitle.classList.remove('open');
 | 
					 | 
				
			||||||
          menuBurger.classList.remove('open');
 | 
					 | 
				
			||||||
          menuH2.classList.remove('open');  
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function setHamburgerWhenLogged() {
 | 
					 | 
				
			||||||
      if (drupalSettings.user.uid != 0) {
 | 
					 | 
				
			||||||
        const menuBurger = document.querySelector('#hamburger');
 | 
					 | 
				
			||||||
        const menuTitle = document.querySelector('#menu-title');
 | 
					 | 
				
			||||||
        const menuContainer = document.querySelector('#block-caravane-mainnavigation > #menu > ul');
 | 
					 | 
				
			||||||
        const header = document.querySelector('.dialog-off-canvas-main-canvas');
 | 
					 | 
				
			||||||
        const headerTop = header.getBoundingClientRect().top;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        menuTitle.style.top = `${headerTop}px`;        
 | 
					 | 
				
			||||||
        menuBurger.style.top = `${headerTop}px`;
 | 
					 | 
				
			||||||
        menuContainer.style.paddingTop = `${headerTop}px`;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function setupEtapeMapPopup(store, map) {
 | 
					 | 
				
			||||||
      const icons = document.querySelectorAll('.leaflet-map-divicon');
 | 
					 | 
				
			||||||
      for (let icon of icons) {
 | 
					 | 
				
			||||||
        const colorContainer = icon.querySelector('.couleur');
 | 
					 | 
				
			||||||
        let colorDivs = colorContainer.querySelectorAll('.separated-content');
 | 
					 | 
				
			||||||
        let color;
 | 
					 | 
				
			||||||
        colorDivs.forEach((div) => {
 | 
					 | 
				
			||||||
          if (div.innerText.startsWith('<div class="snippets-description">')) {
 | 
					 | 
				
			||||||
            color = div.innerText;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        });              
 | 
					 | 
				
			||||||
        color = color.substring(color.indexOf('>') + 1, color.indexOf('<', color.indexOf('>') + 1)).trim();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const nid = icon.querySelector('.nid');
 | 
					 | 
				
			||||||
        const nidValue = nid.querySelector('.separated-content').innerText;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        icon.addEventListener('click', function(event) {                
 | 
					 | 
				
			||||||
          store.fetchEtapeData(nidValue, map);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        colorContainer.style.display = "none";
 | 
					 | 
				
			||||||
        nid.style.display = "none";
 | 
					 | 
				
			||||||
        const iconElements = icon.querySelectorAll('div');
 | 
					 | 
				
			||||||
        for (let iconElement of iconElements) {
 | 
					 | 
				
			||||||
          iconElement.style.backgroundColor = color;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        icon.removeAttribute('title');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        icon.addEventListener('mouseenter', function (event) {
 | 
					 | 
				
			||||||
          icon.style.transform = `${icon.style.transform} scale(1.1)`;
 | 
					 | 
				
			||||||
          const popup = document.querySelector('.leaflet-tooltip-center > div');
 | 
					 | 
				
			||||||
          popup.style.opacity = "1";
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        icon.addEventListener('mouseleave', function (event) {
 | 
					 | 
				
			||||||
          icon.style.transform = icon.style.transform.split(' ')[0] + icon.style.transform.split(' ')[1] + icon.style.transform.split(' ')[2];
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
        init()
 | 
					        init()
 | 
				
			||||||
  } // end CaravaneTheme()
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    CaravaneTheme()
 | 
					    CaravaneTheme()
 | 
				
			||||||
})(jQuery, Drupal, drupalSettings)
 | 
					})(jQuery, Drupal, drupalSettings)
 | 
				
			||||||
@@ -6,6 +6,7 @@ if(drupalDecoupled.redirect){
 | 
				
			|||||||
  console.log('window.location', window.location);
 | 
					  console.log('window.location', window.location);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  drupalDecoupled.sys_path = drupalDecoupled.sys_path.replace(/^\//, '');
 | 
					  drupalDecoupled.sys_path = drupalDecoupled.sys_path.replace(/^\//, '');
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  drupalDecoupled.url = window.location.pathname;
 | 
					  drupalDecoupled.url = window.location.pathname;
 | 
				
			||||||
  drupalDecoupled.hash = window.location.hash;
 | 
					  drupalDecoupled.hash = window.location.hash;
 | 
				
			||||||
  window.localStorage.setItem('decoupled_origin', JSON.stringify(drupalDecoupled));
 | 
					  window.localStorage.setItem('decoupled_origin', JSON.stringify(drupalDecoupled));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,17 +2,23 @@ import { createRouter, createWebHistory } from 'vue-router';
 | 
				
			|||||||
import ModaleView from '../vuejs/Modale.vue';
 | 
					import ModaleView from '../vuejs/Modale.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const routes = [
 | 
					const routes = [
 | 
				
			||||||
    { 
 | 
					/*     { 
 | 
				
			||||||
      name: 'etape',
 | 
					      name: 'etape',
 | 
				
			||||||
      path: '/etapes/:title?',
 | 
					      path: '/etapes/:title?',
 | 
				
			||||||
      component: ModaleView,
 | 
					      component: ModaleView,
 | 
				
			||||||
      props: {id: null}
 | 
					      props: {id: null},
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    { 
 | 
					    { 
 | 
				
			||||||
      name: 'home',
 | 
					      name: 'home',
 | 
				
			||||||
      path: '/',
 | 
					      path: '/',
 | 
				
			||||||
      component: ModaleView
 | 
					      component: ModaleView,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					 // Not much to do here nah ?
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      path: '/:catchAll(.*)',
 | 
				
			||||||
 | 
					      component: ModaleView,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  ];
 | 
					  ];
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  const router = createRouter({
 | 
					  const router = createRouter({
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,33 +5,17 @@ import REST from '../api/rest-axios';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export const useContentStore = defineStore('content', {
 | 
					export const useContentStore = defineStore('content', {
 | 
				
			||||||
    state: () => ({
 | 
					    state: () => ({
 | 
				
			||||||
        href: '',
 | 
					        contentType: '',
 | 
				
			||||||
        map: {},
 | 
					        pageTitle: '',
 | 
				
			||||||
        etape: {
 | 
					        content: {
 | 
				
			||||||
            title: '',
 | 
					            contentTitle: '',
 | 
				
			||||||
            adresse: {},
 | 
					 | 
				
			||||||
            coordinates: {},
 | 
					            coordinates: {},
 | 
				
			||||||
 | 
					            adresse: {},
 | 
				
			||||||
            etape_number: '',
 | 
					            etape_number: '',
 | 
				
			||||||
            vignette: {},
 | 
					 | 
				
			||||||
            couleur: '',
 | 
					            couleur: '',
 | 
				
			||||||
 | 
					            dates: {},
 | 
				
			||||||
            previous : {},
 | 
					            previous : {},
 | 
				
			||||||
            next: {},
 | 
					            next: {},
 | 
				
			||||||
            dates: {
 | 
					 | 
				
			||||||
                start: {
 | 
					 | 
				
			||||||
                    d: '',
 | 
					 | 
				
			||||||
                    m: '',
 | 
					 | 
				
			||||||
                    y: '',
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                end: {
 | 
					 | 
				
			||||||
                    d: '',
 | 
					 | 
				
			||||||
                    m: '',
 | 
					 | 
				
			||||||
                    y: '',
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            parties: [],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        page: {
 | 
					 | 
				
			||||||
            title: '',
 | 
					 | 
				
			||||||
            vignette: {},
 | 
					            vignette: {},
 | 
				
			||||||
            parties: [],
 | 
					            parties: [],
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
@@ -39,42 +23,75 @@ export const useContentStore = defineStore('content', {
 | 
				
			|||||||
        error: null,
 | 
					        error: null,
 | 
				
			||||||
    }),
 | 
					    }),
 | 
				
			||||||
    actions: {
 | 
					    actions: {
 | 
				
			||||||
        async fetchEtapeData(nid, map) {
 | 
					        async fetchContentData(path) {
 | 
				
			||||||
            this.resetStore();
 | 
					            this.resetStore(false);
 | 
				
			||||||
            this.map = map;
 | 
					            const contentTypes = [ 'etape', 'static' ];
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                const response = await REST.get(`/jsonapi/node/etape/`);
 | 
					                let rawContent, 
 | 
				
			||||||
                for (let etape of response.data.data) {
 | 
					                    contentType,
 | 
				
			||||||
                    if (etape.attributes.drupal_internal__nid == nid) {
 | 
					                    response;
 | 
				
			||||||
                        for (let metatag of etape.attributes.metatag) {
 | 
					
 | 
				
			||||||
                          if (metatag.tag === "link") {
 | 
					                contentTypesLoop:
 | 
				
			||||||
                            this.href = metatag.attributes.href;                           
 | 
					                for (let type of contentTypes) {
 | 
				
			||||||
 | 
					                    response = await REST.get(`/jsonapi/node/${type}/`);
 | 
				
			||||||
 | 
					                    for (let content of response.data.data) {
 | 
				
			||||||
 | 
					                        for (let tag of content.attributes.metatag) {
 | 
				
			||||||
 | 
					                            if (tag.tag === "link" && tag.attributes.href === path) {
 | 
				
			||||||
 | 
					                                this.contentType = type;
 | 
				
			||||||
 | 
					                                rawContent = content;
 | 
				
			||||||
 | 
					                                contentType = type;
 | 
				
			||||||
 | 
					                                break contentTypesLoop;
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        this.etape.coordinates = {
 | 
					                    }
 | 
				
			||||||
                            lat: etape.attributes.field_geofield.lat,
 | 
					                }
 | 
				
			||||||
                            lon: etape.attributes.field_geofield.lon,
 | 
					                // pageTitle
 | 
				
			||||||
                        };
 | 
					                for (let tag of rawContent.attributes.metatag) {
 | 
				
			||||||
                        this.etape.title = etape.attributes.title;
 | 
					                    if (tag.tag === "meta") {
 | 
				
			||||||
                        this.etape.adresse = etape.attributes.field_adresse;
 | 
					                        this.pageTitle = tag.attributes.content;
 | 
				
			||||||
                        this.etape.etape_number = etape.attributes.field_arret_numero;
 | 
					                        break;
 | 
				
			||||||
                        const vignetteFetch = await this.fetchContent('field_vignette', etape.relationships);
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                // contentTitle
 | 
				
			||||||
 | 
					                this.content.contentTitle = rawContent.attributes.title;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // vignette
 | 
				
			||||||
 | 
					                const vignetteFetch = await this.fetchDeeperContent('field_vignette', rawContent.relationships);
 | 
				
			||||||
                if (vignetteFetch) {
 | 
					                if (vignetteFetch) {
 | 
				
			||||||
                            this.etape.vignette = { 
 | 
					                    this.content.vignette = { 
 | 
				
			||||||
                        url: vignetteFetch.attributes.uri.url,
 | 
					                        url: vignetteFetch.attributes.uri.url,
 | 
				
			||||||
                                alt: etape.relationships.field_vignette.data.meta.alt
 | 
					                        alt: rawContent.relationships.field_vignette.data.meta.alt
 | 
				
			||||||
                    };
 | 
					                    };
 | 
				
			||||||
                }                
 | 
					                }                
 | 
				
			||||||
                        this.etape.couleur = etape.attributes.field_couleur;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        this.etape.dates = {
 | 
					                if (contentType === 'etape') {
 | 
				
			||||||
                          start: this.getCleanDate(etape.attributes.field_dates.value),
 | 
					                    // coordinates
 | 
				
			||||||
                          end: this.getCleanDate(etape.attributes.field_dates.end_value),
 | 
					                    this.content.coordinates = {
 | 
				
			||||||
 | 
					                        lat: rawContent.attributes.field_geofield.lat,
 | 
				
			||||||
 | 
					                        lon: rawContent.attributes.field_geofield.lon,
 | 
				
			||||||
 | 
					                    };
 | 
				
			||||||
 | 
					                    // adresse
 | 
				
			||||||
 | 
					                    this.content.adresse = rawContent.attributes.field_adresse;
 | 
				
			||||||
 | 
					                    // étape number
 | 
				
			||||||
 | 
					                    this.content.etape_number = rawContent.attributes.field_arret_numero;
 | 
				
			||||||
 | 
					                    // couleur
 | 
				
			||||||
 | 
					                    this.content.couleur = rawContent.attributes.field_couleur;
 | 
				
			||||||
 | 
					                    // dates
 | 
				
			||||||
 | 
					                    this.content.dates = {
 | 
				
			||||||
 | 
					                        start: this.getCleanDate(rawContent.attributes.field_dates.value),
 | 
				
			||||||
 | 
					                        end: this.getCleanDate(rawContent.attributes.field_dates.end_value),
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    // previous / next
 | 
				
			||||||
 | 
					                    await this.getRelatedEtape('previous', response.data.data, path);
 | 
				
			||||||
 | 
					                    await this.getRelatedEtape('next', response.data.data, path);
 | 
				
			||||||
                }                
 | 
					                }                
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        const partiesFetch = await this.fetchContent('field_parties', etape.relationships);
 | 
					                // parties
 | 
				
			||||||
 | 
					                const fieldParties = contentType === 'etape' ? 'field_parties' : 'field_parties_static';
 | 
				
			||||||
 | 
					                const partiesFetch = await this.fetchDeeperContent(fieldParties, rawContent.relationships);
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                if (partiesFetch) {
 | 
					                if (partiesFetch) {
 | 
				
			||||||
                            this.etape.parties = [];
 | 
					                    this.content.parties = [];
 | 
				
			||||||
                    for (let partie of partiesFetch) {
 | 
					                    for (let partie of partiesFetch) {
 | 
				
			||||||
                        const partieType = partie.type.replace(/^paragraph--/, "");
 | 
					                        const partieType = partie.type.replace(/^paragraph--/, "");
 | 
				
			||||||
                        let partieContent = {
 | 
					                        let partieContent = {
 | 
				
			||||||
@@ -83,7 +100,7 @@ export const useContentStore = defineStore('content', {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                        switch (partieType) {
 | 
					                        switch (partieType) {
 | 
				
			||||||
                            case 'carte_sensible':
 | 
					                            case 'carte_sensible':
 | 
				
			||||||
                                        const carteSensibleFetch = await this.fetchContent('field_image_carte', partie.relationships);
 | 
					                                const carteSensibleFetch = await this.fetchDeeperContent('field_image_carte', partie.relationships);                                
 | 
				
			||||||
                                if (carteSensibleFetch) {
 | 
					                                if (carteSensibleFetch) {
 | 
				
			||||||
                                    partieContent.carteSensible = {
 | 
					                                    partieContent.carteSensible = {
 | 
				
			||||||
                                        url: carteSensibleFetch.attributes.uri.url,
 | 
					                                        url: carteSensibleFetch.attributes.uri.url,
 | 
				
			||||||
@@ -96,7 +113,7 @@ export const useContentStore = defineStore('content', {
 | 
				
			|||||||
                                partieContent.texte = partie.attributes.field_texte.value;                                        
 | 
					                                partieContent.texte = partie.attributes.field_texte.value;                                        
 | 
				
			||||||
                                break;
 | 
					                                break;
 | 
				
			||||||
                            case 'chiffres_cles':
 | 
					                            case 'chiffres_cles':
 | 
				
			||||||
                                        const chiffresClesFetch = await this.fetchContent('field_chiffres_clefs', partie.relationships);
 | 
					                                const chiffresClesFetch = await this.fetchDeeperContent('field_chiffres_clefs', partie.relationships);
 | 
				
			||||||
                                if (chiffresClesFetch) {
 | 
					                                if (chiffresClesFetch) {
 | 
				
			||||||
                                    partieContent.chiffresCles = [];
 | 
					                                    partieContent.chiffresCles = [];
 | 
				
			||||||
                                    for (let chiffre of chiffresClesFetch) {
 | 
					                                    for (let chiffre of chiffresClesFetch) {
 | 
				
			||||||
@@ -108,7 +125,7 @@ export const useContentStore = defineStore('content', {
 | 
				
			|||||||
                                }
 | 
					                                }
 | 
				
			||||||
                                break;
 | 
					                                break;
 | 
				
			||||||
                            case 'diaporama':
 | 
					                            case 'diaporama':
 | 
				
			||||||
                                        const diaporamaFetch = await this.fetchContent('field_diaporama', partie.relationships);
 | 
					                                const diaporamaFetch = await this.fetchDeeperContent('field_diaporama', partie.relationships);
 | 
				
			||||||
                                if (diaporamaFetch) {
 | 
					                                if (diaporamaFetch) {
 | 
				
			||||||
                                    partieContent.diaporama = [];
 | 
					                                    partieContent.diaporama = [];
 | 
				
			||||||
                                    for (let [index, image] of diaporamaFetch.entries()) {
 | 
					                                    for (let [index, image] of diaporamaFetch.entries()) {
 | 
				
			||||||
@@ -121,12 +138,12 @@ export const useContentStore = defineStore('content', {
 | 
				
			|||||||
                                break;
 | 
					                                break;
 | 
				
			||||||
                            case 'entretien':
 | 
					                            case 'entretien':
 | 
				
			||||||
                                partieContent.entretien = {};
 | 
					                                partieContent.entretien = {};
 | 
				
			||||||
                                        const personnesFetch = await this.fetchContent('field_personne_s', partie.relationships);
 | 
					                                const personnesFetch = await this.fetchDeeperContent('field_personne_s', partie.relationships);
 | 
				
			||||||
                                        const questionsReponsesFetch = await this.fetchContent('field_questions_reponses', partie.relationships);
 | 
					                                const questionsReponsesFetch = await this.fetchDeeperContent('field_questions_reponses', partie.relationships);
 | 
				
			||||||
                                if (personnesFetch && questionsReponsesFetch) {
 | 
					                                if (personnesFetch && questionsReponsesFetch) {
 | 
				
			||||||
                                    partieContent.entretien.personnes = [];
 | 
					                                    partieContent.entretien.personnes = [];
 | 
				
			||||||
                                    for (let personne of personnesFetch) {
 | 
					                                    for (let personne of personnesFetch) {
 | 
				
			||||||
                                                const portraitFetch = await this.fetchContent('field_portrait', personne.relationships);
 | 
					                                        const portraitFetch = await this.fetchDeeperContent('field_portrait', personne.relationships);
 | 
				
			||||||
                                        if (portraitFetch) {                                                    
 | 
					                                        if (portraitFetch) {                                                    
 | 
				
			||||||
                                            partieContent.entretien.personnes.push({
 | 
					                                            partieContent.entretien.personnes.push({
 | 
				
			||||||
                                                portrait: portraitFetch.attributes.uri.url,
 | 
					                                                portrait: portraitFetch.attributes.uri.url,
 | 
				
			||||||
@@ -156,23 +173,32 @@ export const useContentStore = defineStore('content', {
 | 
				
			|||||||
                                }
 | 
					                                }
 | 
				
			||||||
                                break;
 | 
					                                break;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                                this.etape.parties.push(partieContent);
 | 
					                        this.content.parties.push(partieContent);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                        
 | 
					            } catch (error) {
 | 
				
			||||||
                        // get previous and next étape infos
 | 
					                this.error = 'Failed to fetch data';
 | 
				
			||||||
                        // the list from the json api /node is not ordered
 | 
					                console.error('Issue with getNodeData', error);
 | 
				
			||||||
                        // and i need authentification to get the json view ordered list
 | 
					            } finally {               
 | 
				
			||||||
                        // so i get it from the displayed list in the page
 | 
					                this.loading = false;                
 | 
				
			||||||
                        const orderedEtapesList = document.querySelectorAll('#etapes-liste li');
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
                        if (orderedEtapesList) {                            
 | 
					        getCleanDate(date) {
 | 
				
			||||||
                            const processEtape = async (etapeItemNid, etapesList, key) => {
 | 
					            return {
 | 
				
			||||||
                                for (let etape of etapesList) {
 | 
					              d: date.split('-')[2],
 | 
				
			||||||
                                    if (etape.attributes.drupal_internal__nid == etapeItemNid) {
 | 
					              m: new Intl.DateTimeFormat('fr-FR', { month: 'long' }).format(new Date(date)),
 | 
				
			||||||
 | 
					              y: date.split('-')[0],
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        async getRelatedEtape(direction, allEtapesData, path) {
 | 
				
			||||||
 | 
					            const getRelatedEtapeContent = async (relatedPath, allEtapesData) => {
 | 
				
			||||||
 | 
					                const baseUrl = window.location.protocol + "//" + window.location.host;
 | 
				
			||||||
 | 
					                for (let etape of allEtapesData) {
 | 
				
			||||||
 | 
					                    for (let tag of etape.attributes.metatag) {
 | 
				
			||||||
 | 
					                        if (tag.tag === "link" && tag.attributes.href === baseUrl + relatedPath) {                            
 | 
				
			||||||
                            const vignetteFetch = await REST.get(etape.relationships.field_vignette.links.related.href);
 | 
					                            const vignetteFetch = await REST.get(etape.relationships.field_vignette.links.related.href);
 | 
				
			||||||
                                        this.etape[key] = {
 | 
					                            this.content[direction] = {
 | 
				
			||||||
                                            nid: etape.attributes.drupal_internal__nid,
 | 
					                                url: tag.attributes.href,
 | 
				
			||||||
                                couleur: etape.attributes.field_couleur,
 | 
					                                couleur: etape.attributes.field_couleur,
 | 
				
			||||||
                                title: etape.attributes.title,
 | 
					                                title: etape.attributes.title,
 | 
				
			||||||
                                postalCode: etape.attributes.field_adresse.postal_code,
 | 
					                                postalCode: etape.attributes.field_adresse.postal_code,
 | 
				
			||||||
@@ -184,110 +210,33 @@ export const useContentStore = defineStore('content', {
 | 
				
			|||||||
                                    url: vignetteFetch.data.data.attributes.uri.url,
 | 
					                                    url: vignetteFetch.data.data.attributes.uri.url,
 | 
				
			||||||
                                    alt: etape.relationships.field_vignette.data.meta.alt,
 | 
					                                    alt: etape.relationships.field_vignette.data.meta.alt,
 | 
				
			||||||
                                },
 | 
					                                },
 | 
				
			||||||
                                        };
 | 
					 | 
				
			||||||
                                        break;
 | 
					 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                            };
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const orderedEtapesList = document.querySelectorAll('#etapes-liste li');
 | 
				
			||||||
 | 
					            if (orderedEtapesList) {
 | 
				
			||||||
                for (let li of orderedEtapesList) {
 | 
					                for (let li of orderedEtapesList) {
 | 
				
			||||||
                                if (li.querySelector('a').dataset.nodeNid == nid) {                                    
 | 
					                    const liHref = li.querySelector('a').getAttribute('href');
 | 
				
			||||||
                                    const previousEtapeItemNid = li.previousElementSibling?.querySelector('a').dataset.nodeNid;
 | 
					                    if (path.endsWith(liHref)) {
 | 
				
			||||||
                                    const nextEtapeItemNid = li.nextElementSibling?.querySelector('a').dataset.nodeNid;
 | 
					                        const previousEtapeItemPath = li.previousElementSibling?.querySelector('a').getAttribute('href');
 | 
				
			||||||
                                    if (previousEtapeItemNid) {
 | 
					                        const nextEtapeItemPath = li.nextElementSibling?.querySelector('a').getAttribute('href');
 | 
				
			||||||
                                        await processEtape(previousEtapeItemNid, response.data.data, 'previous');
 | 
					                        
 | 
				
			||||||
 | 
					                        if (previousEtapeItemPath && direction === 'previous') {
 | 
				
			||||||
 | 
					                            let prevContent = await getRelatedEtapeContent(previousEtapeItemPath, allEtapesData);
 | 
				
			||||||
 | 
					                            return prevContent;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                                    if (nextEtapeItemNid) {
 | 
					                        if (nextEtapeItemPath && direction === 'next') {
 | 
				
			||||||
                                        await processEtape(nextEtapeItemNid, response.data.data, 'next');
 | 
					                            let nextContent = await getRelatedEtapeContent(nextEtapeItemPath, allEtapesData);
 | 
				
			||||||
 | 
					                            return nextContent;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                this.setActiveItemInMenu(nid);
 | 
					 | 
				
			||||||
            } catch (error) {
 | 
					 | 
				
			||||||
                this.error = 'Failed to fetch data';
 | 
					 | 
				
			||||||
                console.error('Issue with getNodeData', error);
 | 
					 | 
				
			||||||
            } finally {
 | 
					 | 
				
			||||||
                this.loading = false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        async fetchStaticData(nid, map) {
 | 
					        async fetchDeeperContent(field, relationships) {
 | 
				
			||||||
            this.resetStore();
 | 
					 | 
				
			||||||
            this.map = map;
 | 
					 | 
				
			||||||
            try {
 | 
					 | 
				
			||||||
                const response = await REST.get(`/jsonapi/node/static/`);                
 | 
					 | 
				
			||||||
                for (let page of response.data.data) {                    
 | 
					 | 
				
			||||||
                    if (page.attributes.drupal_internal__nid == nid) {
 | 
					 | 
				
			||||||
                        for (let metatag of page.attributes.metatag) {
 | 
					 | 
				
			||||||
                            if (metatag.tag === "link") {
 | 
					 | 
				
			||||||
                              this.href = metatag.attributes.href;
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        this.page.title = page.attributes.title;
 | 
					 | 
				
			||||||
                        const vignetteFetch = await this.fetchContent('field_vignette', page.relationships);
 | 
					 | 
				
			||||||
                        if (vignetteFetch) {
 | 
					 | 
				
			||||||
                            this.page.vignette = { 
 | 
					 | 
				
			||||||
                                url: vignetteFetch.attributes.uri.url,
 | 
					 | 
				
			||||||
                                alt: page.relationships.field_vignette.data.meta.alt
 | 
					 | 
				
			||||||
                            };
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        
 | 
					 | 
				
			||||||
                        const partiesFetch = await this.fetchContent('field_parties_static', page.relationships);
 | 
					 | 
				
			||||||
                        if (partiesFetch) {
 | 
					 | 
				
			||||||
                            this.page.parties = [];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                            for (let partie of partiesFetch) {
 | 
					 | 
				
			||||||
                                const partieType = partie.type.replace(/^paragraph--/, "");
 | 
					 | 
				
			||||||
                                let partieContent = {
 | 
					 | 
				
			||||||
                                    type: partieType,
 | 
					 | 
				
			||||||
                                };                               
 | 
					 | 
				
			||||||
                                
 | 
					 | 
				
			||||||
                                switch (partieType) {
 | 
					 | 
				
			||||||
                                    case 'titre_texte':
 | 
					 | 
				
			||||||
                                        partieContent.titre = partie.attributes.field_titre;
 | 
					 | 
				
			||||||
                                        partieContent.texte = partie.attributes.field_texte.value;                                        
 | 
					 | 
				
			||||||
                                        break;
 | 
					 | 
				
			||||||
                                    case 'diaporama':
 | 
					 | 
				
			||||||
                                        const diaporamaFetch = await this.fetchContent('field_diaporama', partie.relationships);
 | 
					 | 
				
			||||||
                                        if (diaporamaFetch) {
 | 
					 | 
				
			||||||
                                            partieContent.diaporama = [];
 | 
					 | 
				
			||||||
                                            for (let [index, image] of diaporamaFetch.entries()) {
 | 
					 | 
				
			||||||
                                                partieContent.diaporama.push({
 | 
					 | 
				
			||||||
                                                    url: image.attributes.uri.url,
 | 
					 | 
				
			||||||
                                                    alt: partie.relationships.field_diaporama.data[index].meta.alt,
 | 
					 | 
				
			||||||
                                                });
 | 
					 | 
				
			||||||
                                            }
 | 
					 | 
				
			||||||
                                        }
 | 
					 | 
				
			||||||
                                        break;
 | 
					 | 
				
			||||||
                                    case 'exergue':
 | 
					 | 
				
			||||||
                                        partieContent.exergue = partie.attributes.field_texte_exergue.value;
 | 
					 | 
				
			||||||
                                        break;
 | 
					 | 
				
			||||||
                                    case 'video':
 | 
					 | 
				
			||||||
                                        partieContent.videos = [];
 | 
					 | 
				
			||||||
                                        for (let video of partie.attributes.field_videos) {
 | 
					 | 
				
			||||||
                                            const videoId = video.split('?v=')[1];
 | 
					 | 
				
			||||||
                                            const videoUrl = `https://www.youtube.com/embed/${videoId}`;
 | 
					 | 
				
			||||||
                                            partieContent.videos.push(videoUrl);                      
 | 
					 | 
				
			||||||
                                        }
 | 
					 | 
				
			||||||
                                        break;
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                                this.page.parties.push(partieContent);
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                this.setActiveItemInMenu(nid);
 | 
					 | 
				
			||||||
            } catch (error) {
 | 
					 | 
				
			||||||
                this.error = 'Failed to fetch data';
 | 
					 | 
				
			||||||
                console.error('Issue with getNodeData', error);
 | 
					 | 
				
			||||||
            } finally {
 | 
					 | 
				
			||||||
                this.loading = false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        async fetchContent(field, relationships) {
 | 
					 | 
				
			||||||
            if (relationships[field].data) {
 | 
					            if (relationships[field].data) {
 | 
				
			||||||
              try {
 | 
					              try {
 | 
				
			||||||
                const contentLink = relationships[field].links.related.href;
 | 
					                const contentLink = relationships[field].links.related.href;
 | 
				
			||||||
@@ -299,60 +248,12 @@ export const useContentStore = defineStore('content', {
 | 
				
			|||||||
              }
 | 
					              }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        emptyAll(nid, map) {
 | 
					        resetStore(forFrontDisplay) {
 | 
				
			||||||
          this.href = '';
 | 
					            this.contentType = '';
 | 
				
			||||||
          this.map = map;
 | 
					            this.pageTitle = '';
 | 
				
			||||||
          this.etape = {};
 | 
					            this.content = {};
 | 
				
			||||||
          this.page = {};
 | 
					            this.loading = !forFrontDisplay;
 | 
				
			||||||
          this.setActiveItemInMenu(nid);
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        setActiveItemInMenu(nid) {
 | 
					 | 
				
			||||||
          const title = this.etape.title || this.page.title;
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
          const generalLinks = document.querySelectorAll('#menu > ul > li > a');
 | 
					 | 
				
			||||||
          if (Object.entries(this.etape).length === 0 && Object.entries(this.page).length === 0) {
 | 
					 | 
				
			||||||
            for (let link of generalLinks) {
 | 
					 | 
				
			||||||
              link.classList.remove('is-active');
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            generalLinks[0].classList.add('is-active');
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            for (let link of generalLinks) {
 | 
					 | 
				
			||||||
              if (link.dataset.nodeNid == nid) {
 | 
					 | 
				
			||||||
                link.classList.add('is-active');
 | 
					 | 
				
			||||||
              } else {
 | 
					 | 
				
			||||||
                link.classList.remove('is-active');
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
          const etapeLinks = document.querySelectorAll('#etapes-liste li');
 | 
					 | 
				
			||||||
          for (let link of etapeLinks) {
 | 
					 | 
				
			||||||
            const a = link.querySelector('a');
 | 
					 | 
				
			||||||
            if (a.innerText === title) {
 | 
					 | 
				
			||||||
              link.classList.remove('inactive');
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
              link.classList.add('inactive');
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          const inactiveLinks = document.querySelectorAll('#etapes-liste li.inactive');
 | 
					 | 
				
			||||||
          if (inactiveLinks.length === etapeLinks.length) {
 | 
					 | 
				
			||||||
            for (let link of inactiveLinks) {
 | 
					 | 
				
			||||||
              link.classList.remove('inactive');
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        resetStore() {
 | 
					 | 
				
			||||||
            this.loading = true;
 | 
					 | 
				
			||||||
            this.error = null;
 | 
					            this.error = null;
 | 
				
			||||||
            this.etape = {};
 | 
					 | 
				
			||||||
            this.page = {};
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        getCleanDate(date) {
 | 
					 | 
				
			||||||
          return {
 | 
					 | 
				
			||||||
            d: date.split('-')[2],
 | 
					 | 
				
			||||||
            m: new Intl.DateTimeFormat('fr-FR', { month: 'long' }).format(new Date(date)),
 | 
					 | 
				
			||||||
            y: date.split('-')[0],
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
@@ -2,6 +2,7 @@ import { defineStore } from 'pinia';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export const useMapStore = defineStore('mapState', {
 | 
					export const useMapStore = defineStore('mapState', {
 | 
				
			||||||
    state: () => ({
 | 
					    state: () => ({
 | 
				
			||||||
 | 
					        map: Object,
 | 
				
			||||||
        defaultZoom: Number,
 | 
					        defaultZoom: Number,
 | 
				
			||||||
        defaultMapCenter: Object,
 | 
					        defaultMapCenter: Object,
 | 
				
			||||||
        currentPlace: Object,
 | 
					        currentPlace: Object,
 | 
				
			||||||
@@ -10,36 +11,36 @@ export const useMapStore = defineStore('mapState', {
 | 
				
			|||||||
        duration: 3,
 | 
					        duration: 3,
 | 
				
			||||||
    }),
 | 
					    }),
 | 
				
			||||||
    actions: {
 | 
					    actions: {
 | 
				
			||||||
        zoomToPlace(map, lat, long) {
 | 
					        zoomToPlace(lat, long) {
 | 
				
			||||||
            map.flyTo([lat, long], this.maxZoom, { duration: this.duration });
 | 
					            this.map.flyTo([lat, long], this.maxZoom, { duration: this.duration });
 | 
				
			||||||
            this.currentZoom = this.maxZoom;            
 | 
					            this.currentZoom = this.maxZoom;            
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        resetMap(map) {
 | 
					        resetMap() {
 | 
				
			||||||
            map.flyTo(this.defaultMapCenter, this.defaultZoom, { duration: this.duration });
 | 
					            this.map.flyTo(this.defaultMapCenter, this.defaultZoom, { duration: this.duration });
 | 
				
			||||||
            this.currentZoom = this.defaultZoom;
 | 
					            this.currentZoom = this.defaultZoom;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        lockMap(map) {
 | 
					        lockMap() {
 | 
				
			||||||
            setTimeout(() => {
 | 
					            setTimeout(() => {
 | 
				
			||||||
                map.options.minZoom = this.currentZoom;
 | 
					                this.map.options.minZoom = this.currentZoom;
 | 
				
			||||||
                map.options.maxZoom = this.currentZoom;
 | 
					                this.map.options.maxZoom = this.currentZoom;
 | 
				
			||||||
            }, this.duration * 1000 + 100);
 | 
					            }, this.duration * 1000 + 100);
 | 
				
			||||||
            map.dragging.disable();
 | 
					            this.map.dragging.disable();
 | 
				
			||||||
            map.touchZoom.disable();
 | 
					            this.map.touchZoom.disable();
 | 
				
			||||||
            map.doubleClickZoom.disable();
 | 
					            this.map.doubleClickZoom.disable();
 | 
				
			||||||
            map.scrollWheelZoom.disable();
 | 
					            this.map.scrollWheelZoom.disable();
 | 
				
			||||||
            map.boxZoom.disable();
 | 
					            this.map.boxZoom.disable();
 | 
				
			||||||
            map.keyboard.disable();
 | 
					            this.map.keyboard.disable();
 | 
				
			||||||
            // map.tap.disable();
 | 
					            // map.tap.disable();
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          unlockMap(map) {
 | 
					          unlockMap() {
 | 
				
			||||||
            map.options.minZoom = this.defaultZoom;
 | 
					            this.map.options.minZoom = this.defaultZoom;
 | 
				
			||||||
            map.options.maxZoom = this.maxZoom;
 | 
					            this.map.options.maxZoom = this.maxZoom;
 | 
				
			||||||
            map.dragging.enable();
 | 
					            this.map.dragging.enable();
 | 
				
			||||||
            map.touchZoom.enable();
 | 
					            this.map.touchZoom.enable();
 | 
				
			||||||
            map.doubleClickZoom.enable();
 | 
					            this.map.doubleClickZoom.enable();
 | 
				
			||||||
            map.scrollWheelZoom.enable();
 | 
					            this.map.scrollWheelZoom.enable();
 | 
				
			||||||
            map.boxZoom.enable();
 | 
					            this.map.boxZoom.enable();
 | 
				
			||||||
            map.keyboard.enable();
 | 
					            this.map.keyboard.enable();
 | 
				
			||||||
            // map.tap.enable();
 | 
					            // map.tap.enable();
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					import { setActiveNavItem } from "./set-active-nav-item";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function initFirstLoadRouting(store, router, baseUrl, siteName) {
 | 
				
			||||||
 | 
					    const decoupled_origin = JSON.parse(window.localStorage.getItem('decoupled_origin'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(decoupled_origin) {       
 | 
				
			||||||
 | 
					        await store.fetchContentData(baseUrl + decoupled_origin.url);
 | 
				
			||||||
 | 
					        router.push(decoupled_origin.url);
 | 
				
			||||||
 | 
					        window.localStorage.removeItem("decoupled_origin");
 | 
				
			||||||
 | 
					        document.title = store.pageTitle; 
 | 
				
			||||||
 | 
					        setActiveNavItem(store.contentType, decoupled_origin.url);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        document.title = siteName;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function handleClickableElements(clickableElements, store, router, baseUrl, siteName, mapStore) {
 | 
				
			||||||
 | 
					    for (const link of clickableElements) {
 | 
				
			||||||
 | 
					        let href = link.href || link.dataset.href;
 | 
				
			||||||
 | 
					        if (href.startsWith(baseUrl)) href = href.replace(baseUrl, '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        link.onclick = async function (e) {
 | 
				
			||||||
 | 
					            router.push(href);
 | 
				
			||||||
 | 
					            if (href !== window.location.pathname) {
 | 
				
			||||||
 | 
					                if (href === '/') {
 | 
				
			||||||
 | 
					                    store.resetStore(true);
 | 
				
			||||||
 | 
					                    document.title = siteName;
 | 
				
			||||||
 | 
					                    mapStore.resetMap();
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    await store.fetchContentData(baseUrl + href);
 | 
				
			||||||
 | 
					                    document.title = store.pageTitle;                
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                setActiveNavItem(store.contentType, href);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										37
									
								
								web/themes/custom/caravane/assets/js/utils/layout-setup.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								web/themes/custom/caravane/assets/js/utils/layout-setup.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					export function setMenuToggle() {
 | 
				
			||||||
 | 
					    const menuButton = document.querySelector('#block-caravane-mainnavigation > #menu');
 | 
				
			||||||
 | 
					    const menuContainer = document.querySelector('#block-caravane-mainnavigation > #menu > ul');
 | 
				
			||||||
 | 
					    const menuTitle = document.querySelector('#menu-title');
 | 
				
			||||||
 | 
					    const menuBurger = document.querySelector('#hamburger');
 | 
				
			||||||
 | 
					    const menuH2 = document.querySelector('#menu > h2');
 | 
				
			||||||
 | 
					    menuButton.addEventListener('click', (e) => { 
 | 
				
			||||||
 | 
					      setTimeout(() => {
 | 
				
			||||||
 | 
					        menuContainer.classList.toggle('open');
 | 
				
			||||||
 | 
					        menuTitle.classList.toggle('open');
 | 
				
			||||||
 | 
					        menuBurger.classList.toggle('open');
 | 
				
			||||||
 | 
					        menuH2.classList.toggle('open');
 | 
				
			||||||
 | 
					      }, 50);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    document.addEventListener('click', (e) => {
 | 
				
			||||||
 | 
					      if (!menuContainer.contains(e.target) && !menuBurger.contains(e.target)) {
 | 
				
			||||||
 | 
					        menuContainer.classList.remove('open');
 | 
				
			||||||
 | 
					        menuTitle.classList.remove('open');
 | 
				
			||||||
 | 
					        menuBurger.classList.remove('open');
 | 
				
			||||||
 | 
					        menuH2.classList.remove('open');  
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function setHamburgerWhenLogged(drupalSettings) {
 | 
				
			||||||
 | 
					    if (drupalSettings.user.uid != 0) {
 | 
				
			||||||
 | 
					      const menuBurger = document.querySelector('#hamburger');
 | 
				
			||||||
 | 
					      const menuTitle = document.querySelector('#menu-title');
 | 
				
			||||||
 | 
					      const menuContainer = document.querySelector('#block-caravane-mainnavigation > #menu > ul');
 | 
				
			||||||
 | 
					      const header = document.querySelector('.dialog-off-canvas-main-canvas');
 | 
				
			||||||
 | 
					      const headerTop = header.getBoundingClientRect().top;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      menuTitle.style.top = `${headerTop}px`;        
 | 
				
			||||||
 | 
					      menuBurger.style.top = `${headerTop}px`;
 | 
				
			||||||
 | 
					      menuContainer.style.paddingTop = `${headerTop}px`;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										6
									
								
								web/themes/custom/caravane/assets/js/utils/map-setup.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								web/themes/custom/caravane/assets/js/utils/map-setup.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					export function setupMapStore(mapStore, map, settings) {
 | 
				
			||||||
 | 
					    mapStore.map = map;
 | 
				
			||||||
 | 
					    mapStore.defaultMapCenter = map.getCenter();
 | 
				
			||||||
 | 
					    mapStore.maxZoom = settings.settings.maxZoom;
 | 
				
			||||||
 | 
					    mapStore.defaultZoom = settings.settings.minZoom;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					export function processClickableElements() {
 | 
				
			||||||
 | 
					    return { 
 | 
				
			||||||
 | 
					        etapeListLinks: processEtapeLinks(),
 | 
				
			||||||
 | 
					        generalListLinks: processStaticLinks(),
 | 
				
			||||||
 | 
					        logoLink: processLogoLink(),
 | 
				
			||||||
 | 
					        mapIcons: processMapIcons(),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function processEtapeLinks() {
 | 
				
			||||||
 | 
					    const etape_li = document.querySelectorAll('#etapes-liste li');
 | 
				
			||||||
 | 
					    etape_li.forEach((li) => {
 | 
				
			||||||
 | 
					        const etape_link = li.querySelector('a.etape-link');
 | 
				
			||||||
 | 
					        etape_link.addEventListener('click', (e) => e.preventDefault());
 | 
				
			||||||
 | 
					        const couleur = etape_link.dataset.couleur;
 | 
				
			||||||
 | 
					        li.dataset.href = etape_link.attributes.href.value;
 | 
				
			||||||
 | 
					        const iconElements = li.querySelectorAll('.icone-arret > div');
 | 
				
			||||||
 | 
					        for (let element of iconElements) {
 | 
				
			||||||
 | 
					          element.style.backgroundColor = couleur;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return etape_li;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function processStaticLinks() {
 | 
				
			||||||
 | 
					    const general_link_fields = document.querySelectorAll('#menu > ul > li > a');
 | 
				
			||||||
 | 
					    for (let i = 0; i <  general_link_fields.length; i ++) {
 | 
				
			||||||
 | 
					        let general_link_path = general_link_fields[i].getAttribute('data-drupal-link-system-path');
 | 
				
			||||||
 | 
					        if (general_link_path && general_link_path !== '<front>') {           
 | 
				
			||||||
 | 
					            const match = [...general_link_path.match(/^node\/(\d+)$/)];
 | 
				
			||||||
 | 
					            if (match) {
 | 
				
			||||||
 | 
					                const nid = match[1];
 | 
				
			||||||
 | 
					                general_link_fields[i].setAttribute('data-nid', parseInt(nid));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        general_link_fields[i].addEventListener('click', (e) => e.preventDefault());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return general_link_fields;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function processLogoLink() {
 | 
				
			||||||
 | 
					    const logo = document.querySelector('#block-caravane-logocaravane a');
 | 
				
			||||||
 | 
					    logo.addEventListener('click', (e) => e.preventDefault());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return logo;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function processMapIcons() {
 | 
				
			||||||
 | 
					    const icons = document.querySelectorAll('.leaflet-map-divicon');
 | 
				
			||||||
 | 
					    for (let icon of icons) {
 | 
				
			||||||
 | 
					        icon.setAttribute('title', '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const hrefContainer = icon.querySelector('.url');
 | 
				
			||||||
 | 
					        icon.dataset.href = hrefContainer.innerText;
 | 
				
			||||||
 | 
					        hrefContainer.style.display = "none";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const colorContainer = icon.querySelector('.couleur');
 | 
				
			||||||
 | 
					        let color = colorContainer.innerText;
 | 
				
			||||||
 | 
					        colorContainer.style.display = "none";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const iconElements = icon.querySelectorAll('div');
 | 
				
			||||||
 | 
					        for (let iconElement of iconElements) {
 | 
				
			||||||
 | 
					          iconElement.style.backgroundColor = color;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        icon.addEventListener('mouseenter', () => {
 | 
				
			||||||
 | 
					            icon.style.transform = `${icon.style.transform} scale(1.1)`;
 | 
				
			||||||
 | 
					            const popup = document.querySelector('.leaflet-tooltip-center > div');
 | 
				
			||||||
 | 
					            popup.style.opacity = "1";
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					        icon.addEventListener('mouseleave', () => {
 | 
				
			||||||
 | 
					            icon.style.transform = icon.style.transform.split(' ')[0] + icon.style.transform.split(' ')[1] + icon.style.transform.split(' ')[2];
 | 
				
			||||||
 | 
					        });  
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return icons;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					export function setActiveNavItem(contentType, href) {
 | 
				
			||||||
 | 
					    const staticNavItems = document.querySelectorAll('#menu > ul > li > a');
 | 
				
			||||||
 | 
					    const etapeNavItems = document.querySelectorAll('#etapes-liste li a');
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for (let item of staticNavItems) {
 | 
				
			||||||
 | 
					        item.classList.remove('is-active');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (let item of etapeNavItems) {
 | 
				
			||||||
 | 
					        item.closest('li').classList.add('inactive');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (href === '/' || href === '') {
 | 
				
			||||||
 | 
					        staticNavItems[0].classList.add('is-active');
 | 
				
			||||||
 | 
					        for (let item of etapeNavItems) {
 | 
				
			||||||
 | 
					            item.closest('li').classList.remove('inactive');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        if (contentType === 'static') {
 | 
				
			||||||
 | 
					            for (let item of staticNavItems) {
 | 
				
			||||||
 | 
					                if (item.getAttribute('href') === href) {
 | 
				
			||||||
 | 
					                    item.classList.add('is-active');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else if (contentType === 'etape') {
 | 
				
			||||||
 | 
					            for (let item of etapeNavItems) {
 | 
				
			||||||
 | 
					                if (item.getAttribute('href') === href) {
 | 
				
			||||||
 | 
					                    item.closest('li').classList.remove('inactive');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										22
									
								
								web/themes/custom/caravane/assets/js/utils/vue-setup.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								web/themes/custom/caravane/assets/js/utils/vue-setup.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					import { createApp } from 'vue';
 | 
				
			||||||
 | 
					import { createPinia } from 'pinia';
 | 
				
			||||||
 | 
					import router from '../router/router';
 | 
				
			||||||
 | 
					import Modale from '../vuejs/Modale.vue';
 | 
				
			||||||
 | 
					import VueImageZoomer from 'vue-image-zoomer';
 | 
				
			||||||
 | 
					import 'vue-image-zoomer/dist/style.css';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { useContentStore } from '../stores/content';
 | 
				
			||||||
 | 
					import { useMapStore } from '../stores/mapState';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function initVueContentModale() {
 | 
				
			||||||
 | 
					    const app = createApp(Modale)
 | 
				
			||||||
 | 
					        .use(createPinia())
 | 
				
			||||||
 | 
					        .use(router)
 | 
				
			||||||
 | 
					        .use(VueImageZoomer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const store = useContentStore();
 | 
				
			||||||
 | 
					    const mapStore = useMapStore();
 | 
				
			||||||
 | 
					    app.mount('#content-modale');    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return { store, mapStore, router };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,44 +1,46 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <Transition>
 | 
					    <Transition>
 | 
				
			||||||
        <div v-if="isEtapeValid || isPageValid">
 | 
					        <div v-if="!loading && (contentType === 'etape' || contentType === 'static')">
 | 
				
			||||||
            <div class="content-wrapper">
 | 
					            <div class="content-wrapper">
 | 
				
			||||||
                <ModaleHeader
 | 
					                <ModaleHeader
 | 
				
			||||||
                    :content="etape.title ? etape : page"
 | 
					                    :contentType="contentType"
 | 
				
			||||||
                    :couleur="etape.couleur || brandColor" />
 | 
					                    :content="content"
 | 
				
			||||||
 | 
					                    :couleur="content.couleur || brandColor" />
 | 
				
			||||||
                <main>
 | 
					                <main>
 | 
				
			||||||
                    <div v-for="partie in etape.parties || page.parties" class="partie">
 | 
					                    <div v-for="partie in content.parties" class="partie">
 | 
				
			||||||
                        <ModaleCarteSensible 
 | 
					                        <ModaleCarteSensible 
 | 
				
			||||||
                            v-if="partie.type === 'carte_sensible'" 
 | 
					                            v-if="partie.type === 'carte_sensible'" 
 | 
				
			||||||
                            :partie="partie" />
 | 
					                            :partie="partie" />
 | 
				
			||||||
                        <ModaleTitreTexte
 | 
					                        <ModaleTitreTexte
 | 
				
			||||||
                            v-if="partie.type === 'titre_texte'"
 | 
					                            v-if="partie.type === 'titre_texte'"
 | 
				
			||||||
                            :partie="partie"
 | 
					                            :partie="partie"
 | 
				
			||||||
                            :couleur="etape.couleur || brandColor" />
 | 
					                            :couleur="content.couleur || brandColor" />
 | 
				
			||||||
                        <ModaleChiffresCles
 | 
					                        <ModaleChiffresCles
 | 
				
			||||||
                            v-if="partie.type === 'chiffres_cles'"
 | 
					                            v-if="partie.type === 'chiffres_cles'"
 | 
				
			||||||
                            :partie="partie"
 | 
					                            :partie="partie"
 | 
				
			||||||
                            :couleur="etape.couleur || brandColor" />
 | 
					                            :couleur="content.couleur || brandColor" />
 | 
				
			||||||
                        <ModaleDiaporama
 | 
					                        <ModaleDiaporama
 | 
				
			||||||
                            v-if="partie.type === 'diaporama'"
 | 
					                            v-if="partie.type === 'diaporama'"
 | 
				
			||||||
                            :partie="partie"
 | 
					                            :partie="partie"
 | 
				
			||||||
                            :couleur="etape.couleur || brandColor" />
 | 
					                            :couleur="content.couleur || brandColor" />
 | 
				
			||||||
                        <ModaleEntretien
 | 
					                        <ModaleEntretien
 | 
				
			||||||
                            v-if="partie.type === 'entretien'"
 | 
					                            v-if="partie.type === 'entretien'"
 | 
				
			||||||
                            :partie="partie"
 | 
					                            :partie="partie"
 | 
				
			||||||
                            :couleur="etape.couleur || brandColor" />
 | 
					                            :couleur="content.couleur || brandColor" />
 | 
				
			||||||
                        <ModaleExergue
 | 
					                        <ModaleExergue
 | 
				
			||||||
                            v-if="partie.type === 'exergue'"
 | 
					                            v-if="partie.type === 'exergue'"
 | 
				
			||||||
                            :partie="partie"
 | 
					                            :partie="partie"
 | 
				
			||||||
                            :couleur="etape.couleur || brandColor" />
 | 
					                            :couleur="content.couleur || brandColor" />
 | 
				
			||||||
                        <ModaleVideos
 | 
					                        <ModaleVideos
 | 
				
			||||||
                            v-if="partie.type === 'video'"
 | 
					                            v-if="partie.type === 'video'"
 | 
				
			||||||
                            :partie="partie" />
 | 
					                            :partie="partie" />
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </main>
 | 
					                </main>
 | 
				
			||||||
                <ModaleFooter
 | 
					                <ModaleFooter
 | 
				
			||||||
                    :content="etape || page"
 | 
					                    :contentType="contentType"
 | 
				
			||||||
                    :couleur="etape.couleur || brandColor"
 | 
					                    :content="content"
 | 
				
			||||||
                    :map="map" />
 | 
					                    :couleur="content.couleur || brandColor"
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </Transition>
 | 
					    </Transition>
 | 
				
			||||||
@@ -46,10 +48,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<script setup>
 | 
					<script setup>
 | 
				
			||||||
import { computed, watch, onMounted } from 'vue';
 | 
					import { computed, watch, onMounted } from 'vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { storeToRefs } from 'pinia';
 | 
					import { storeToRefs } from 'pinia';
 | 
				
			||||||
import { useContentStore } from '../stores/content';
 | 
					import { useContentStore } from '../stores/content';
 | 
				
			||||||
import { useMapStore } from '../stores/mapState';
 | 
					import { useMapStore } from '../stores/mapState';
 | 
				
			||||||
import { useRoute, useRouter } from 'vue-router';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import ModaleHeader from './components/ModaleHeader.vue';
 | 
					import ModaleHeader from './components/ModaleHeader.vue';
 | 
				
			||||||
import ModaleFooter from './components/ModaleFooter.vue';
 | 
					import ModaleFooter from './components/ModaleFooter.vue';
 | 
				
			||||||
@@ -62,73 +64,28 @@ import ModaleEntretien from './components/parties/ModaleEntretien.vue';
 | 
				
			|||||||
import ModaleExergue from './components/parties/ModaleExergue.vue';
 | 
					import ModaleExergue from './components/parties/ModaleExergue.vue';
 | 
				
			||||||
import ModaleVideos from './components/parties/ModaleVideos.vue';
 | 
					import ModaleVideos from './components/parties/ModaleVideos.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { useUtils } from './composables/useUtils';
 | 
					 | 
				
			||||||
const { isObjectEmpty, scrollTop } = useUtils();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const router = useRouter();
 | 
					 | 
				
			||||||
const store = useContentStore();
 | 
					const store = useContentStore();
 | 
				
			||||||
const mapState = useMapStore();
 | 
					const mapState = useMapStore();
 | 
				
			||||||
const route = useRoute();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const { loading, error, href, map, etape, page } = storeToRefs(store);
 | 
					const {
 | 
				
			||||||
const { duration } = storeToRefs(mapState);
 | 
					    contentType,
 | 
				
			||||||
 | 
					    content,
 | 
				
			||||||
 | 
					    loading,
 | 
				
			||||||
 | 
					    error, 
 | 
				
			||||||
 | 
					} = storeToRefs(store);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const isEtapeValid = computed(() => !error.value && !loading.value && etape.value && !isObjectEmpty(etape.value));
 | 
					const { map, duration } = storeToRefs(mapState);
 | 
				
			||||||
const isPageValid = computed(() => !error.value && !loading.value && page.value && !isObjectEmpty(page.value));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
let isModaleEtape, wasModaleEtape;
 | 
					let isModaleEtape, wasModaleEtape;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const brandColor = "#80c8bf";
 | 
					const brandColor = "#80c8bf";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let isProgrammaticNavigation = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const handleRouteChange = () => {
 | 
					 | 
				
			||||||
  watch(
 | 
					 | 
				
			||||||
    () => route.params.id,
 | 
					 | 
				
			||||||
    (newId) => {      
 | 
					 | 
				
			||||||
      if (isProgrammaticNavigation) {
 | 
					 | 
				
			||||||
        isProgrammaticNavigation = false;
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (!newId) {
 | 
					 | 
				
			||||||
        store.emptyAll(map.value);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        store.fetchEtapeData(newId, map.value);
 | 
					 | 
				
			||||||
        if (!etape.value?.data) {
 | 
					 | 
				
			||||||
          store.fetchStaticData(newId, map.value);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        scrollTop();
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    { immediate: true }
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const handleColorChange = () => {
 | 
					const handleColorChange = () => {
 | 
				
			||||||
  watch(
 | 
					  watch(
 | 
				
			||||||
    () => href.value,
 | 
					    () => content.value.couleur,
 | 
				
			||||||
    () => {    
 | 
					    () => {    
 | 
				
			||||||
        document.documentElement.style.setProperty('--etape-couleur', etape.value.couleur || brandColor);
 | 
					        if (contentType.value === 'etape' && content.value.couleur) {
 | 
				
			||||||
    }
 | 
					            document.documentElement.style.setProperty('--etape-couleur', content.value.couleur || brandColor);
 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const handleHrefChange = () => {
 | 
					 | 
				
			||||||
  watch(
 | 
					 | 
				
			||||||
    () => href.value,
 | 
					 | 
				
			||||||
    (newHref) => {
 | 
					 | 
				
			||||||
      const relativePath = newHref.split('.fr')[1];
 | 
					 | 
				
			||||||
      isProgrammaticNavigation = true;
 | 
					 | 
				
			||||||
      if (newHref == '') {
 | 
					 | 
				
			||||||
        router.push('/');
 | 
					 | 
				
			||||||
        mapState.unlockMap(map.value)
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        if (relativePath && relativePath !== '' && relativePath !== '/') {  
 | 
					 | 
				
			||||||
          mapState.lockMap(map.value);     
 | 
					 | 
				
			||||||
          router.push(relativePath);
 | 
					 | 
				
			||||||
          scrollTop();
 | 
					 | 
				
			||||||
        }     
 | 
					 | 
				
			||||||
        }   
 | 
					        }   
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
@@ -136,58 +93,66 @@ const handleHrefChange = () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const handleMapMovement = () => {
 | 
					const handleMapMovement = () => {
 | 
				
			||||||
  watch(
 | 
					  watch(
 | 
				
			||||||
    () => href.value,
 | 
					    () => loading.value,
 | 
				
			||||||
    () => {
 | 
					    () => {
 | 
				
			||||||
      isModaleEtape = !isObjectEmpty(etape.value);
 | 
					        if (!loading.value) {
 | 
				
			||||||
 | 
					            isModaleEtape = contentType.value === 'etape';            
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            if (!wasModaleEtape && isModaleEtape) {
 | 
					            if (!wasModaleEtape && isModaleEtape) {
 | 
				
			||||||
 | 
					                // national -> détail
 | 
				
			||||||
                document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value}s`);
 | 
					                document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value}s`);
 | 
				
			||||||
        mapState.zoomToPlace(map.value, etape.value.coordinates.lat, etape.value.coordinates.lon);
 | 
					                mapState.zoomToPlace(content.value.coordinates.lat, content.value.coordinates.lon);
 | 
				
			||||||
 | 
					 | 
				
			||||||
            } else if (wasModaleEtape && isModaleEtape) { 
 | 
					            } else if (wasModaleEtape && isModaleEtape) { 
 | 
				
			||||||
 | 
					                // détail -> détail
 | 
				
			||||||
                document.documentElement.style.setProperty('--modale-leave-delay', 0);
 | 
					                document.documentElement.style.setProperty('--modale-leave-delay', 0);
 | 
				
			||||||
                document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value * 2}s`);
 | 
					                document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value * 2}s`);
 | 
				
			||||||
                mapState.resetMap(map.value);
 | 
					                mapState.resetMap(map.value);
 | 
				
			||||||
                setTimeout(() => {
 | 
					                setTimeout(() => {
 | 
				
			||||||
          mapState.zoomToPlace(map.value, etape.value.coordinates.lat, etape.value.coordinates.lon);
 | 
					                mapState.zoomToPlace(content.value.coordinates.lat, content.value.coordinates.lon);
 | 
				
			||||||
                }, duration.value * 1000);
 | 
					                }, duration.value * 1000);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
            } else if (wasModaleEtape && !isModaleEtape) { 
 | 
					            } else if (wasModaleEtape && !isModaleEtape) { 
 | 
				
			||||||
 | 
					                // détail -> national
 | 
				
			||||||
                document.documentElement.style.setProperty('--modale-leave-delay', 0);
 | 
					                document.documentElement.style.setProperty('--modale-leave-delay', 0);
 | 
				
			||||||
        mapState.resetMap(map.value);
 | 
					                document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value}s`);
 | 
				
			||||||
 | 
					                mapState.resetMap();
 | 
				
			||||||
 | 
					            } else if (!wasModaleEtape && !isModaleEtape) {
 | 
				
			||||||
 | 
					                // national -> national
 | 
				
			||||||
 | 
					                console.log('national -> national');
 | 
				
			||||||
 | 
					                document.documentElement.style.setProperty('--modale-leave-delay', 0);
 | 
				
			||||||
 | 
					                document.documentElement.style.setProperty('--modale-enter-delay', '0.5s');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
            wasModaleEtape = isModaleEtape;
 | 
					            wasModaleEtape = isModaleEtape;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onMounted(() => {
 | 
					onMounted(() => {
 | 
				
			||||||
  isModaleEtape = !isObjectEmpty(etape.value);
 | 
					    isModaleEtape = contentType.value === 'etape';
 | 
				
			||||||
    wasModaleEtape = isModaleEtape;    
 | 
					    wasModaleEtape = isModaleEtape;    
 | 
				
			||||||
  handleRouteChange();
 | 
					 | 
				
			||||||
    handleColorChange();
 | 
					    handleColorChange();
 | 
				
			||||||
  handleHrefChange();
 | 
					 | 
				
			||||||
    handleMapMovement();
 | 
					    handleMapMovement();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style scss>
 | 
					<style scoped scss>
 | 
				
			||||||
.v-enter-active {
 | 
					.v-enter-active {
 | 
				
			||||||
  transition: all 0.5s linear var(--modale-enter-delay);
 | 
					  transition: margin-top 0.5s ease-out var(--modale-enter-delay);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.v-leave-active {
 | 
					.v-leave-active {
 | 
				
			||||||
  transition: all 0.5s linear var(--modale-leave-delay);
 | 
					    transition: margin-top 0.5s ease-in var(--modale-leave-delay);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.v-enter-from,
 | 
					.v-enter-from,
 | 
				
			||||||
.v-leave-to {
 | 
					.v-leave-to {
 | 
				
			||||||
  transform: translateY(20vh);
 | 
					  margin-top: 150vh;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.v-enter-to,
 | 
					.v-enter-to,
 | 
				
			||||||
.v-leave-from {
 | 
					.v-leave-from {
 | 
				
			||||||
  transform: translateY(0vh);
 | 
					    margin-top: 0vh;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
@@ -4,8 +4,8 @@
 | 
				
			|||||||
            <div class="pattern"></div>
 | 
					            <div class="pattern"></div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
        <div v-if="content.previous || content.next" class="related-etape-links">
 | 
					        <div v-if="contentType === 'etape' && (content.previous || content.next)" class="related-etape-links">
 | 
				
			||||||
            <div v-if="content.previous" class="card previous" @click="store.fetchEtapeData(content.previous.nid, map)">
 | 
					            <div v-if="content.previous" class="card previous" @click="displayRelatedElement(content.previous.url)">
 | 
				
			||||||
                <div class="icon">
 | 
					                <div class="icon">
 | 
				
			||||||
                    <div :style="{ backgroundColor: content.previous.couleur }"></div>
 | 
					                    <div :style="{ backgroundColor: content.previous.couleur }"></div>
 | 
				
			||||||
                    <div :style="{ backgroundColor: content.previous.couleur }"></div>
 | 
					                    <div :style="{ backgroundColor: content.previous.couleur }"></div>
 | 
				
			||||||
@@ -21,7 +21,7 @@
 | 
				
			|||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <div v-if="content.next" class="card next" @click="store.fetchEtapeData(content.next.nid, map)">
 | 
					            <div v-if="content.next" class="card next" @click="displayRelatedElement(content.next.url)">
 | 
				
			||||||
                <div class="icon">
 | 
					                <div class="icon">
 | 
				
			||||||
                    <div :style="{ backgroundColor: content.next.couleur }"></div>
 | 
					                    <div :style="{ backgroundColor: content.next.couleur }"></div>
 | 
				
			||||||
                    <div :style="{ backgroundColor: content.next.couleur }"></div>
 | 
					                    <div :style="{ backgroundColor: content.next.couleur }"></div>
 | 
				
			||||||
@@ -42,14 +42,25 @@
 | 
				
			|||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script setup>
 | 
					<script setup>
 | 
				
			||||||
 | 
					import router from '../../router/router.js';
 | 
				
			||||||
import { useContentStore } from '../../stores/content';
 | 
					import { useContentStore } from '../../stores/content';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const brandColor = "#80c8bf";
 | 
					const brandColor = "#80c8bf";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const store = useContentStore();
 | 
					const store = useContentStore();
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
 | 
					  contentType: String,
 | 
				
			||||||
  content: Object,
 | 
					  content: Object,
 | 
				
			||||||
  couleur: String,
 | 
					  couleur: String,
 | 
				
			||||||
  map: Object,
 | 
					  map: Object,
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function displayRelatedElement(href) {
 | 
				
			||||||
 | 
					    const baseUrl = window.location.protocol + "//" + window.location.host;
 | 
				
			||||||
 | 
					    if (href.startsWith(baseUrl)) href = href.replace(baseUrl, '');  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    router.push(href);
 | 
				
			||||||
 | 
					    await store.fetchContentData(baseUrl + href);
 | 
				
			||||||
 | 
					    document.title = store.pageTitle;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
        <div class="cover">
 | 
					        <div class="cover">
 | 
				
			||||||
            <img v-if="content.vignette" :src="content.vignette.url" :alt="content.vignette.alt">
 | 
					            <img v-if="content.vignette" :src="content.vignette.url" :alt="content.vignette.alt">
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div v-if="content.dates" class="cartouche" :style="{ backgroundColor: couleur }">
 | 
					        <div v-if="contentType === 'etape' && content.dates" class="cartouche" :style="{ backgroundColor: couleur }">
 | 
				
			||||||
            <p>Étape n°{{content.etape_number}}</p>
 | 
					            <p>Étape n°{{content.etape_number}}</p>
 | 
				
			||||||
            <p>Du {{content.dates.start.d}} {{content.dates.start.m}} au {{ content.dates.end.d }} {{ content.dates.end.m }} {{ content.dates.end.y }}</p>
 | 
					            <p>Du {{content.dates.start.d}} {{content.dates.start.m}} au {{ content.dates.end.d }} {{ content.dates.end.m }} {{ content.dates.end.y }}</p>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
@@ -13,7 +13,7 @@
 | 
				
			|||||||
        <div class="locality">
 | 
					        <div class="locality">
 | 
				
			||||||
            <div class="top-triangle"></div>
 | 
					            <div class="top-triangle"></div>
 | 
				
			||||||
            <div class="locality-title">
 | 
					            <div class="locality-title">
 | 
				
			||||||
                <h1>{{content.title}} <em v-if="content.adresse">({{ content.adresse.postal_code.slice(0, 2) }})</em></h1>
 | 
					                <h1>{{content.contentTitle}} <em v-if="content.adresse">({{ content.adresse.postal_code.slice(0, 2) }})</em></h1>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </header>
 | 
					    </header>
 | 
				
			||||||
@@ -21,6 +21,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<script setup>
 | 
					<script setup>
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
 | 
					  contentType: String,
 | 
				
			||||||
  content: Object,
 | 
					  content: Object,
 | 
				
			||||||
  couleur: String,
 | 
					  couleur: String,
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,21 +0,0 @@
 | 
				
			|||||||
export function useUtils() {
 | 
					 | 
				
			||||||
    const isObjectEmpty = (obj) => {
 | 
					 | 
				
			||||||
        if (!obj || typeof obj !== 'object') return true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return !Object.keys(obj).some((key) => {
 | 
					 | 
				
			||||||
        const value = obj[key];
 | 
					 | 
				
			||||||
        if (Array.isArray(value)) return value.length > 0;
 | 
					 | 
				
			||||||
        if (typeof value === 'object') return !isObjectEmpty(value);
 | 
					 | 
				
			||||||
        return value !== null && value !== undefined && value !== '';
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const scrollTop = () => {
 | 
					 | 
				
			||||||
        window.scrollTo({ top: 0, behavior: 'smooth' });
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
        isObjectEmpty,
 | 
					 | 
				
			||||||
        scrollTop,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -253,6 +253,9 @@ body{
 | 
				
			|||||||
              top: 0;
 | 
					              top: 0;
 | 
				
			||||||
              width: 100vw;
 | 
					              width: 100vw;
 | 
				
			||||||
              .leaflet-container {
 | 
					              .leaflet-container {
 | 
				
			||||||
 | 
					                .leaflet-popup {
 | 
				
			||||||
 | 
					                  display: none;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                // add map style here
 | 
					                // add map style here
 | 
				
			||||||
                .leaflet-control-zoom {
 | 
					                .leaflet-control-zoom {
 | 
				
			||||||
                  border: none;
 | 
					                  border: none;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,8 @@ function caravane_preprocess_html(&$variables) {
 | 
				
			|||||||
 * Implements hook_preprocess_HOOK() for page.html.twig.
 | 
					 * Implements hook_preprocess_HOOK() for page.html.twig.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
function caravane_preprocess_page(&$variables) {
 | 
					function caravane_preprocess_page(&$variables) {
 | 
				
			||||||
 | 
					  $config = \Drupal::config('system.site');
 | 
				
			||||||
 | 
					  $variables['site_name'] = $config->get('name');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -89,3 +89,4 @@
 | 
				
			|||||||
  {% endif %}
 | 
					  {% endif %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</div>{# /.layout-container #}
 | 
					</div>{# /.layout-container #}
 | 
				
			||||||
 | 
					<div id="site_name" style="display: none;">{{ site_name }}</div>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user