refactor du système de routing (EXPORTS DES SETTINGS DRUPAL)
This commit is contained in:
parent
74f099ebdd
commit
d5c5d81841
|
@ -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;
|
function init () {
|
||||||
console.log('drupalSettings', drupalSettings);
|
console.log('DrupalSettings', drupalSettings);
|
||||||
|
|
||||||
function init () {
|
const baseUrl = window.location.protocol + "//" + window.location.host;
|
||||||
console.log('CaravaneTheme init()');
|
const siteName = document.querySelector('#site_name').innerText;
|
||||||
initVues();
|
const { store, mapStore, router, route } = initVueContentModale();
|
||||||
toggleMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
function initVues(){
|
setMenuToggle();
|
||||||
initVueContentModale();
|
setHamburgerWhenLogged(drupalSettings);
|
||||||
|
|
||||||
}
|
// https://www.drupal.org/docs/extending-drupal/contributed-modules/contributed-module-documentation/leaflet/leaflet-api
|
||||||
|
|
||||||
function initVueContentModale(){
|
Drupal.behaviors.customLeafletInteraction = {
|
||||||
const app = createApp(Modale)
|
attach: function(context, settings) {
|
||||||
.use(createPinia()).use(router)
|
$(context).on('leafletMapInit', function (e, settings, map, mapid, markers) {
|
||||||
.use(VueImageZoomer);
|
const {
|
||||||
const store = useContentStore();
|
etapeListLinks,
|
||||||
const mapStore = useMapStore();
|
generalListLinks,
|
||||||
app.mount('#content-modale');
|
logoLink,
|
||||||
|
mapIcons,
|
||||||
|
} = processClickableElements();
|
||||||
|
const clickableElements = [...etapeListLinks, ...generalListLinks, logoLink, ...mapIcons];
|
||||||
|
|
||||||
setHamburgerWhenLogged();
|
setupMapStore(mapStore, map, settings);
|
||||||
|
|
||||||
Drupal.behaviors.customLeafletInteraction = {
|
initFirstLoadRouting(store, router, baseUrl, siteName);
|
||||||
attach: function(context, settings) {
|
|
||||||
$(context).on('leafletMapInit', function (e, settings, map, mapid, markers) {
|
|
||||||
mapStore.defaultMapCenter = map.getCenter();
|
|
||||||
mapStore.maxZoom = settings.settings.maxZoom;
|
|
||||||
mapStore.defaultZoom = settings.settings.minZoom;
|
|
||||||
|
|
||||||
|
|
||||||
initFirstLoadRouting(store, map);
|
handleClickableElements(clickableElements, store, router, baseUrl, siteName, mapStore);
|
||||||
processEtapeLinks(store, map);
|
});
|
||||||
processStaticLinks(store, map);
|
}
|
||||||
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({
|
init()
|
||||||
// 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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
CaravaneTheme()
|
||||||
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()
|
|
||||||
} // end 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: '',
|
||||||
previous: {},
|
dates: {},
|
||||||
|
previous : {},
|
||||||
next: {},
|
next: {},
|
||||||
dates: {
|
|
||||||
start: {
|
|
||||||
d: '',
|
|
||||||
m: '',
|
|
||||||
y: '',
|
|
||||||
},
|
|
||||||
end: {
|
|
||||||
d: '',
|
|
||||||
m: '',
|
|
||||||
y: '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
parties: [],
|
|
||||||
},
|
|
||||||
page: {
|
|
||||||
title: '',
|
|
||||||
vignette: {},
|
vignette: {},
|
||||||
parties: [],
|
parties: [],
|
||||||
},
|
},
|
||||||
|
@ -39,320 +23,237 @@ 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") {
|
|
||||||
this.href = metatag.attributes.href;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.etape.coordinates = {
|
|
||||||
lat: etape.attributes.field_geofield.lat,
|
|
||||||
lon: etape.attributes.field_geofield.lon,
|
|
||||||
};
|
|
||||||
this.etape.title = etape.attributes.title;
|
|
||||||
this.etape.adresse = etape.attributes.field_adresse;
|
|
||||||
this.etape.etape_number = etape.attributes.field_arret_numero;
|
|
||||||
const vignetteFetch = await this.fetchContent('field_vignette', etape.relationships);
|
|
||||||
if (vignetteFetch) {
|
|
||||||
this.etape.vignette = {
|
|
||||||
url: vignetteFetch.attributes.uri.url,
|
|
||||||
alt: etape.relationships.field_vignette.data.meta.alt
|
|
||||||
};
|
|
||||||
}
|
|
||||||
this.etape.couleur = etape.attributes.field_couleur;
|
|
||||||
|
|
||||||
this.etape.dates = {
|
contentTypesLoop:
|
||||||
start: this.getCleanDate(etape.attributes.field_dates.value),
|
for (let type of contentTypes) {
|
||||||
end: this.getCleanDate(etape.attributes.field_dates.end_value),
|
response = await REST.get(`/jsonapi/node/${type}/`);
|
||||||
}
|
for (let content of response.data.data) {
|
||||||
|
for (let tag of content.attributes.metatag) {
|
||||||
const partiesFetch = await this.fetchContent('field_parties', etape.relationships);
|
if (tag.tag === "link" && tag.attributes.href === path) {
|
||||||
if (partiesFetch) {
|
this.contentType = type;
|
||||||
this.etape.parties = [];
|
rawContent = content;
|
||||||
for (let partie of partiesFetch) {
|
contentType = type;
|
||||||
const partieType = partie.type.replace(/^paragraph--/, "");
|
break contentTypesLoop;
|
||||||
let partieContent = {
|
|
||||||
type: partieType,
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (partieType) {
|
|
||||||
case 'carte_sensible':
|
|
||||||
const carteSensibleFetch = await this.fetchContent('field_image_carte', partie.relationships);
|
|
||||||
if (carteSensibleFetch) {
|
|
||||||
partieContent.carteSensible = {
|
|
||||||
url: carteSensibleFetch.attributes.uri.url,
|
|
||||||
alt: partie.relationships.field_image_carte.data.meta.alt,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'titre_texte':
|
|
||||||
partieContent.titre = partie.attributes.field_titre;
|
|
||||||
partieContent.texte = partie.attributes.field_texte.value;
|
|
||||||
break;
|
|
||||||
case 'chiffres_cles':
|
|
||||||
const chiffresClesFetch = await this.fetchContent('field_chiffres_clefs', partie.relationships);
|
|
||||||
if (chiffresClesFetch) {
|
|
||||||
partieContent.chiffresCles = [];
|
|
||||||
for (let chiffre of chiffresClesFetch) {
|
|
||||||
partieContent.chiffresCles.push({
|
|
||||||
chiffre: chiffre.attributes.field_chiffre,
|
|
||||||
description: chiffre.attributes.field_description,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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 'entretien':
|
|
||||||
partieContent.entretien = {};
|
|
||||||
const personnesFetch = await this.fetchContent('field_personne_s', partie.relationships);
|
|
||||||
const questionsReponsesFetch = await this.fetchContent('field_questions_reponses', partie.relationships);
|
|
||||||
if (personnesFetch && questionsReponsesFetch) {
|
|
||||||
partieContent.entretien.personnes = [];
|
|
||||||
for (let personne of personnesFetch) {
|
|
||||||
const portraitFetch = await this.fetchContent('field_portrait', personne.relationships);
|
|
||||||
if (portraitFetch) {
|
|
||||||
partieContent.entretien.personnes.push({
|
|
||||||
portrait: portraitFetch.attributes.uri.url,
|
|
||||||
alt: personne.relationships.field_portrait.data.meta.alt,
|
|
||||||
description: personne.attributes.field_description,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
partieContent.entretien.questionsReponses = [];
|
|
||||||
for (let qr of questionsReponsesFetch) {
|
|
||||||
partieContent.entretien.questionsReponses.push({
|
|
||||||
question: qr.attributes.field_question,
|
|
||||||
reponse: qr.attributes.field_reponse.value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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.etape.parties.push(partieContent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get previous and next étape infos
|
|
||||||
// the list from the json api /node is not ordered
|
|
||||||
// and i need authentification to get the json view ordered list
|
|
||||||
// so i get it from the displayed list in the page
|
|
||||||
const orderedEtapesList = document.querySelectorAll('#etapes-liste li');
|
|
||||||
|
|
||||||
if (orderedEtapesList) {
|
|
||||||
const processEtape = async (etapeItemNid, etapesList, key) => {
|
|
||||||
for (let etape of etapesList) {
|
|
||||||
if (etape.attributes.drupal_internal__nid == etapeItemNid) {
|
|
||||||
const vignetteFetch = await REST.get(etape.relationships.field_vignette.links.related.href);
|
|
||||||
this.etape[key] = {
|
|
||||||
nid: etape.attributes.drupal_internal__nid,
|
|
||||||
couleur: etape.attributes.field_couleur,
|
|
||||||
title: etape.attributes.title,
|
|
||||||
postalCode: etape.attributes.field_adresse.postal_code,
|
|
||||||
dates: {
|
|
||||||
start: this.getCleanDate(etape.attributes.field_dates.value),
|
|
||||||
end: this.getCleanDate(etape.attributes.field_dates.end_value),
|
|
||||||
},
|
|
||||||
vignette: {
|
|
||||||
url: vignetteFetch.data.data.attributes.uri.url,
|
|
||||||
alt: etape.relationships.field_vignette.data.meta.alt,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (let li of orderedEtapesList) {
|
|
||||||
if (li.querySelector('a').dataset.nodeNid == nid) {
|
|
||||||
const previousEtapeItemNid = li.previousElementSibling?.querySelector('a').dataset.nodeNid;
|
|
||||||
const nextEtapeItemNid = li.nextElementSibling?.querySelector('a').dataset.nodeNid;
|
|
||||||
if (previousEtapeItemNid) {
|
|
||||||
await processEtape(previousEtapeItemNid, response.data.data, 'previous');
|
|
||||||
}
|
|
||||||
if (nextEtapeItemNid) {
|
|
||||||
await processEtape(nextEtapeItemNid, response.data.data, 'next');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// pageTitle
|
||||||
|
for (let tag of rawContent.attributes.metatag) {
|
||||||
|
if (tag.tag === "meta") {
|
||||||
|
this.pageTitle = tag.attributes.content;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.setActiveItemInMenu(nid);
|
// contentTitle
|
||||||
|
this.content.contentTitle = rawContent.attributes.title;
|
||||||
|
|
||||||
|
// vignette
|
||||||
|
const vignetteFetch = await this.fetchDeeperContent('field_vignette', rawContent.relationships);
|
||||||
|
if (vignetteFetch) {
|
||||||
|
this.content.vignette = {
|
||||||
|
url: vignetteFetch.attributes.uri.url,
|
||||||
|
alt: rawContent.relationships.field_vignette.data.meta.alt
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contentType === 'etape') {
|
||||||
|
// coordinates
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// parties
|
||||||
|
const fieldParties = contentType === 'etape' ? 'field_parties' : 'field_parties_static';
|
||||||
|
const partiesFetch = await this.fetchDeeperContent(fieldParties, rawContent.relationships);
|
||||||
|
|
||||||
|
if (partiesFetch) {
|
||||||
|
this.content.parties = [];
|
||||||
|
for (let partie of partiesFetch) {
|
||||||
|
const partieType = partie.type.replace(/^paragraph--/, "");
|
||||||
|
let partieContent = {
|
||||||
|
type: partieType,
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (partieType) {
|
||||||
|
case 'carte_sensible':
|
||||||
|
const carteSensibleFetch = await this.fetchDeeperContent('field_image_carte', partie.relationships);
|
||||||
|
if (carteSensibleFetch) {
|
||||||
|
partieContent.carteSensible = {
|
||||||
|
url: carteSensibleFetch.attributes.uri.url,
|
||||||
|
alt: partie.relationships.field_image_carte.data.meta.alt,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'titre_texte':
|
||||||
|
partieContent.titre = partie.attributes.field_titre;
|
||||||
|
partieContent.texte = partie.attributes.field_texte.value;
|
||||||
|
break;
|
||||||
|
case 'chiffres_cles':
|
||||||
|
const chiffresClesFetch = await this.fetchDeeperContent('field_chiffres_clefs', partie.relationships);
|
||||||
|
if (chiffresClesFetch) {
|
||||||
|
partieContent.chiffresCles = [];
|
||||||
|
for (let chiffre of chiffresClesFetch) {
|
||||||
|
partieContent.chiffresCles.push({
|
||||||
|
chiffre: chiffre.attributes.field_chiffre,
|
||||||
|
description: chiffre.attributes.field_description,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'diaporama':
|
||||||
|
const diaporamaFetch = await this.fetchDeeperContent('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 'entretien':
|
||||||
|
partieContent.entretien = {};
|
||||||
|
const personnesFetch = await this.fetchDeeperContent('field_personne_s', partie.relationships);
|
||||||
|
const questionsReponsesFetch = await this.fetchDeeperContent('field_questions_reponses', partie.relationships);
|
||||||
|
if (personnesFetch && questionsReponsesFetch) {
|
||||||
|
partieContent.entretien.personnes = [];
|
||||||
|
for (let personne of personnesFetch) {
|
||||||
|
const portraitFetch = await this.fetchDeeperContent('field_portrait', personne.relationships);
|
||||||
|
if (portraitFetch) {
|
||||||
|
partieContent.entretien.personnes.push({
|
||||||
|
portrait: portraitFetch.attributes.uri.url,
|
||||||
|
alt: personne.relationships.field_portrait.data.meta.alt,
|
||||||
|
description: personne.attributes.field_description,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
partieContent.entretien.questionsReponses = [];
|
||||||
|
for (let qr of questionsReponsesFetch) {
|
||||||
|
partieContent.entretien.questionsReponses.push({
|
||||||
|
question: qr.attributes.field_question,
|
||||||
|
reponse: qr.attributes.field_reponse.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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.content.parties.push(partieContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.error = 'Failed to fetch data';
|
this.error = 'Failed to fetch data';
|
||||||
console.error('Issue with getNodeData', error);
|
console.error('Issue with getNodeData', error);
|
||||||
} finally {
|
} finally {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async fetchStaticData(nid, map) {
|
getCleanDate(date) {
|
||||||
this.resetStore();
|
return {
|
||||||
this.map = map;
|
d: date.split('-')[2],
|
||||||
try {
|
m: new Intl.DateTimeFormat('fr-FR', { month: 'long' }).format(new Date(date)),
|
||||||
const response = await REST.get(`/jsonapi/node/static/`);
|
y: date.split('-')[0],
|
||||||
for (let page of response.data.data) {
|
}
|
||||||
if (page.attributes.drupal_internal__nid == nid) {
|
},
|
||||||
for (let metatag of page.attributes.metatag) {
|
async getRelatedEtape(direction, allEtapesData, path) {
|
||||||
if (metatag.tag === "link") {
|
const getRelatedEtapeContent = async (relatedPath, allEtapesData) => {
|
||||||
this.href = metatag.attributes.href;
|
const baseUrl = window.location.protocol + "//" + window.location.host;
|
||||||
}
|
for (let etape of allEtapesData) {
|
||||||
}
|
for (let tag of etape.attributes.metatag) {
|
||||||
this.page.title = page.attributes.title;
|
if (tag.tag === "link" && tag.attributes.href === baseUrl + relatedPath) {
|
||||||
const vignetteFetch = await this.fetchContent('field_vignette', page.relationships);
|
const vignetteFetch = await REST.get(etape.relationships.field_vignette.links.related.href);
|
||||||
if (vignetteFetch) {
|
this.content[direction] = {
|
||||||
this.page.vignette = {
|
url: tag.attributes.href,
|
||||||
url: vignetteFetch.attributes.uri.url,
|
couleur: etape.attributes.field_couleur,
|
||||||
alt: page.relationships.field_vignette.data.meta.alt
|
title: etape.attributes.title,
|
||||||
};
|
postalCode: etape.attributes.field_adresse.postal_code,
|
||||||
}
|
dates: {
|
||||||
|
start: this.getCleanDate(etape.attributes.field_dates.value),
|
||||||
const partiesFetch = await this.fetchContent('field_parties_static', page.relationships);
|
end: this.getCleanDate(etape.attributes.field_dates.end_value),
|
||||||
if (partiesFetch) {
|
},
|
||||||
this.page.parties = [];
|
vignette: {
|
||||||
|
url: vignetteFetch.data.data.attributes.uri.url,
|
||||||
for (let partie of partiesFetch) {
|
alt: etape.relationships.field_vignette.data.meta.alt,
|
||||||
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) {
|
|
||||||
|
const orderedEtapesList = document.querySelectorAll('#etapes-liste li');
|
||||||
|
if (orderedEtapesList) {
|
||||||
|
for (let li of orderedEtapesList) {
|
||||||
|
const liHref = li.querySelector('a').getAttribute('href');
|
||||||
|
if (path.endsWith(liHref)) {
|
||||||
|
const previousEtapeItemPath = li.previousElementSibling?.querySelector('a').getAttribute('href');
|
||||||
|
const nextEtapeItemPath = li.nextElementSibling?.querySelector('a').getAttribute('href');
|
||||||
|
|
||||||
|
if (previousEtapeItemPath && direction === 'previous') {
|
||||||
|
let prevContent = await getRelatedEtapeContent(previousEtapeItemPath, allEtapesData);
|
||||||
|
return prevContent;
|
||||||
|
}
|
||||||
|
if (nextEtapeItemPath && direction === 'next') {
|
||||||
|
let nextContent = await getRelatedEtapeContent(nextEtapeItemPath, allEtapesData);
|
||||||
|
return nextContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async fetchDeeperContent(field, relationships) {
|
||||||
|
if (relationships[field].data) {
|
||||||
|
try {
|
||||||
|
const contentLink = relationships[field].links.related.href;
|
||||||
|
const contentFetch = await REST.get(contentLink);
|
||||||
|
return contentFetch.data.data;
|
||||||
|
} catch (error) {
|
||||||
this.error = 'Failed to fetch data';
|
this.error = 'Failed to fetch data';
|
||||||
console.error('Issue with getNodeData', error);
|
console.error('Issue with getNodeData', error);
|
||||||
} finally {
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async fetchContent(field, relationships) {
|
|
||||||
if (relationships[field].data) {
|
|
||||||
try {
|
|
||||||
const contentLink = relationships[field].links.related.href;
|
|
||||||
const contentFetch = await REST.get(contentLink);
|
|
||||||
return contentFetch.data.data;
|
|
||||||
} catch (error) {
|
|
||||||
this.error = 'Failed to fetch data';
|
|
||||||
console.error('Issue with getNodeData', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
emptyAll(nid, map) {
|
|
||||||
this.href = '';
|
|
||||||
this.map = map;
|
|
||||||
this.etape = {};
|
|
||||||
this.page = {};
|
|
||||||
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() {
|
resetStore(forFrontDisplay) {
|
||||||
this.loading = true;
|
this.contentType = '';
|
||||||
|
this.pageTitle = '';
|
||||||
|
this.content = {};
|
||||||
|
this.loading = !forFrontDisplay;
|
||||||
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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`;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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,132 +64,95 @@ 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMapMovement = () => {
|
const handleMapMovement = () => {
|
||||||
watch(
|
watch(
|
||||||
() => href.value,
|
() => loading.value,
|
||||||
() => {
|
() => {
|
||||||
isModaleEtape = !isObjectEmpty(etape.value);
|
if (!loading.value) {
|
||||||
|
isModaleEtape = contentType.value === 'etape';
|
||||||
if (!wasModaleEtape && isModaleEtape) {
|
|
||||||
document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value}s`);
|
if (!wasModaleEtape && isModaleEtape) {
|
||||||
mapState.zoomToPlace(map.value, etape.value.coordinates.lat, etape.value.coordinates.lon);
|
// national -> détail
|
||||||
|
document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value}s`);
|
||||||
} else if (wasModaleEtape && isModaleEtape) {
|
mapState.zoomToPlace(content.value.coordinates.lat, content.value.coordinates.lon);
|
||||||
document.documentElement.style.setProperty('--modale-leave-delay', 0);
|
} else if (wasModaleEtape && isModaleEtape) {
|
||||||
document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value * 2}s`);
|
// détail -> détail
|
||||||
mapState.resetMap(map.value);
|
document.documentElement.style.setProperty('--modale-leave-delay', 0);
|
||||||
setTimeout(() => {
|
document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value * 2}s`);
|
||||||
mapState.zoomToPlace(map.value, etape.value.coordinates.lat, etape.value.coordinates.lon);
|
mapState.resetMap(map.value);
|
||||||
}, duration.value * 1000);
|
setTimeout(() => {
|
||||||
|
mapState.zoomToPlace(content.value.coordinates.lat, content.value.coordinates.lon);
|
||||||
} else if (wasModaleEtape && !isModaleEtape) {
|
}, duration.value * 1000);
|
||||||
document.documentElement.style.setProperty('--modale-leave-delay', 0);
|
|
||||||
mapState.resetMap(map.value);
|
} else if (wasModaleEtape && !isModaleEtape) {
|
||||||
}
|
// détail -> national
|
||||||
|
document.documentElement.style.setProperty('--modale-leave-delay', 0);
|
||||||
wasModaleEtape = isModaleEtape;
|
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;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
isModaleEtape = !isObjectEmpty(etape.value);
|
isModaleEtape = contentType.value === 'etape';
|
||||||
wasModaleEtape = isModaleEtape;
|
wasModaleEtape = isModaleEtape;
|
||||||
handleRouteChange();
|
handleColorChange();
|
||||||
handleColorChange();
|
handleMapMovement();
|
||||||
handleHrefChange();
|
|
||||||
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>
|
|
@ -1,9 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<header :style="content.vignette ? '' : { marginTop: '20vh' }">
|
<header :style="content.vignette ? '' : { marginTop: '20vh' }">
|
||||||
<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>
|
Loading…
Reference in New Issue