rerefactor du fetching de contenus une mielleure ux au load des modales (description dans le readme)
This commit is contained in:
@@ -1,201 +1,68 @@
|
||||
// query et traitement des contenus
|
||||
|
||||
import { defineStore } from 'pinia';
|
||||
import REST from '../api/rest-axios';
|
||||
|
||||
import { useLayoutStore } from './layout';
|
||||
|
||||
import { findContentByPath } from '../utils/content/findContentByPath';
|
||||
import { getCleanDate, fetchFromRelationships, getRelatedEtape, getRelatedRessources } from '../utils/content/contentFetchUtils';
|
||||
import { getCarteSensible, getTitreTexte, getChiffresCles, getDiaporama, getEntretien, getVideos, getDocument, getGallerie } from '../utils/content/cleanParties';
|
||||
import { getPartenaires, getGouvernance, getRessources } from '../utils/content/multiItemPages';
|
||||
import { fetchSingletonFullContent, fetchSingletonPartialContent } from '../utils/content/fetchSingleton';
|
||||
import { fetchMultipleFullContent, fetchMultiplePartialContent } from '../utils/content/fetchMultiple';
|
||||
|
||||
export const useContentStore = defineStore('content', {
|
||||
state: () => ({
|
||||
contentType: '',
|
||||
rawContent: {},
|
||||
pageTitle: '',
|
||||
content: {},
|
||||
partialLoading: false,
|
||||
loading: false,
|
||||
error: null,
|
||||
}),
|
||||
actions: {
|
||||
async fetchContentData(path) {
|
||||
// pages etape, statiques et ressource ont un seul item par page (singuliers)
|
||||
// pages gouvernance (contact), ressources et partenaire ont plusieurs items par pages (multiples)
|
||||
async fetchPartialContentData(path) {
|
||||
this.resetStore(false);
|
||||
const contentTypes = ['etape', 'static', 'gouvernance', 'partenaire', 'ressource'];
|
||||
|
||||
try {
|
||||
const { contentType, rawContent } = await findContentByPath(contentTypes, path);
|
||||
this.contentType = contentType;
|
||||
this.rawContent = rawContent;
|
||||
|
||||
if (
|
||||
this.contentType === 'etape'
|
||||
|| this.contentType === 'static'
|
||||
|| this.contentType === 'ressourceItem'
|
||||
) {
|
||||
const vignettePromise = fetchFromRelationships('field_vignette', rawContent.relationships);
|
||||
const partiesPromise = fetchFromRelationships(this.contentType === 'ressourceItem' ? 'field_parties_ressource' : 'field_parties', rawContent.relationships);
|
||||
|
||||
let previousEtapePromise, nextEtapePromise;
|
||||
|
||||
|
||||
if (this.contentType === 'etape') {
|
||||
previousEtapePromise = getRelatedEtape('previous', path);
|
||||
nextEtapePromise = getRelatedEtape('next', path);
|
||||
|
||||
this.content.coordinates = {
|
||||
lat: rawContent.attributes.field_geofield.lat,
|
||||
lon: rawContent.attributes.field_geofield.lon,
|
||||
};
|
||||
this.content.adresse = rawContent.attributes.field_adresse;
|
||||
this.content.etape_number = rawContent.attributes.field_arret_numero;
|
||||
this.content.couleur = rawContent.attributes.field_couleur;
|
||||
this.content.dates = {
|
||||
start: getCleanDate(rawContent.attributes.field_dates.value),
|
||||
end: getCleanDate(rawContent.attributes.field_dates.end_value),
|
||||
}
|
||||
this.content.relatedRessources = await getRelatedRessources(rawContent.id);
|
||||
}
|
||||
|
||||
if (this.contentType === 'ressourceItem') {
|
||||
console.log(rawContent);
|
||||
|
||||
this.content.ressourceType = rawContent.attributes.field_type_de_ressource;
|
||||
this.content.auteurice = rawContent.attributes.field_autheurice;
|
||||
this.content.date = getCleanDate(rawContent.attributes.field_date_ressource);
|
||||
this.content.introduction = rawContent.attributes.field_introduction?.processed;
|
||||
if (rawContent.relationships.field_etape.data) {
|
||||
const relatedEtapeFetch = fetchFromRelationships('field_etape', rawContent.relationships);
|
||||
const relatedEtape = await Promise.resolve(relatedEtapeFetch);
|
||||
const relatedEtapeUrl = relatedEtape.attributes.metatag.find(tag => tag.tag === "link")?.attributes.href;
|
||||
this.content.relatedEtape = await getRelatedEtape('', relatedEtapeUrl);
|
||||
}
|
||||
|
||||
useLayoutStore().hideEtapeList(true);
|
||||
}
|
||||
|
||||
this.pageTitle = rawContent.attributes.metatag.find(tag => tag.tag === "meta")?.attributes.content;
|
||||
this.content.contentTitle = rawContent.attributes.title;
|
||||
|
||||
const [vignetteData, partiesData] = await Promise.all([vignettePromise, partiesPromise]);
|
||||
|
||||
if (vignetteData) {
|
||||
this.content.vignette = {
|
||||
url: {
|
||||
original: vignetteData.attributes.uri.url,
|
||||
small: vignetteData.attributes.image_style_uri.content_small,
|
||||
medium: vignetteData.attributes.image_style_uri.content_medium,
|
||||
large: vignetteData.attributes.image_style_uri.content_large,
|
||||
},
|
||||
alt: rawContent.relationships.field_vignette.data.meta.alt
|
||||
};
|
||||
}
|
||||
|
||||
if (partiesData) {
|
||||
const partiesPromises = partiesData.map(async (partie) => {
|
||||
const partieType = partie.type.replace(/^paragraph--/, "");
|
||||
let partieContent = { type: partieType };
|
||||
|
||||
switch (partieType) {
|
||||
case 'carte_sensible':
|
||||
partieContent.carteSensible = await getCarteSensible(partie);
|
||||
break;
|
||||
case 'titre_texte':
|
||||
const { titre, texte } = await getTitreTexte(partie);
|
||||
partieContent.titre = titre;
|
||||
partieContent.texte = texte;
|
||||
break;
|
||||
case 'chiffres_cles':
|
||||
partieContent.chiffresCles = await getChiffresCles(partie);
|
||||
break;
|
||||
case 'diaporama':
|
||||
partieContent.diaporama = await getDiaporama(partie);
|
||||
break;
|
||||
case 'entretien':
|
||||
partieContent.entretien = await getEntretien(partie);
|
||||
break;
|
||||
case 'exergue':
|
||||
partieContent.exergue = partie.attributes.field_texte_exergue.value;
|
||||
break;
|
||||
case 'video':
|
||||
partieContent.videos = getVideos(partie);
|
||||
break;
|
||||
case 'document':
|
||||
partieContent.document = await getDocument(partie);
|
||||
break;
|
||||
case 'galleries':
|
||||
partieContent.gallerie = await getGallerie(partie);
|
||||
break;
|
||||
}
|
||||
return partieContent;
|
||||
});
|
||||
|
||||
// liens
|
||||
if (rawContent.attributes.field_liens?.length) {
|
||||
this.content.liens = [];
|
||||
for (let lien of rawContent.attributes.field_liens) {
|
||||
this.content.liens.push({
|
||||
title: lien.title,
|
||||
url: lien.uri,
|
||||
});
|
||||
}
|
||||
}
|
||||
// pièces jointes
|
||||
if (rawContent.relationships.field_pieces_jointes?.data.length) {
|
||||
this.content.pieces_jointes = [];
|
||||
for (let pieceJointe of rawContent.relationships.field_pieces_jointes.data) {
|
||||
if (pieceJointe.meta.display) {
|
||||
const uuid = pieceJointe.id;
|
||||
const response = await REST.get(`/jsonapi/file/file/${uuid}`);
|
||||
this.content.pieces_jointes.push({
|
||||
title: pieceJointe.meta.description,
|
||||
url: response.data.data.attributes.uri.url,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.content.parties = await Promise.all(partiesPromises);
|
||||
}
|
||||
|
||||
// related étapes
|
||||
if (contentType === 'etape') {
|
||||
const [prevContent, nextContent] = await Promise.all([previousEtapePromise, nextEtapePromise]);
|
||||
this.content.previous = prevContent;
|
||||
this.content.next = nextContent;
|
||||
}
|
||||
) {
|
||||
let { pageTitle, partialContent } = fetchSingletonPartialContent(this.contentType, this.rawContent);
|
||||
this.pageTitle = pageTitle;
|
||||
this.content = partialContent;
|
||||
} else {
|
||||
// pages gouvernance (contact), ressources et partenaire
|
||||
// ont plusieurs items par pages
|
||||
const intro = await REST.get(`/jsonapi/config_pages/intro_${this.contentType}/`);
|
||||
const introContent = intro.data.data[0];
|
||||
|
||||
this.pageTitle =
|
||||
`${introContent.attributes.field_titre} ${introContent.attributes.metatag.find(tag => tag.tag === "meta")?.attributes.content}`;
|
||||
|
||||
this.content.contentTitle = introContent.attributes.field_titre;
|
||||
this.content.intro = introContent.attributes.field_intro?.value;
|
||||
|
||||
let multiItemPageArray = [];
|
||||
|
||||
switch (this.contentType) {
|
||||
case 'ressource':
|
||||
multiItemPageArray = await getRessources(rawContent);
|
||||
this.content.ressourceTypes = new Set(multiItemPageArray.map(item => item.ressourceType));
|
||||
useLayoutStore().hideEtapeList(true);
|
||||
break;
|
||||
case 'partenaire':
|
||||
multiItemPageArray = await getPartenaires(rawContent);
|
||||
break;
|
||||
case 'gouvernance':
|
||||
multiItemPageArray = await getGouvernance(rawContent);
|
||||
break;
|
||||
}
|
||||
|
||||
this.content[`${this.contentType}s`] = multiItemPageArray;
|
||||
|
||||
let { pageTitle, partialContent } = await fetchMultiplePartialContent(this.contentType);
|
||||
this.pageTitle = pageTitle;
|
||||
this.content = partialContent;
|
||||
}
|
||||
} catch (error) {
|
||||
this.error = 'Failed to fetch data';
|
||||
console.error('Issue with getNodeData', error);
|
||||
} catch(error) {
|
||||
this.error = 'Failed to fetch partial data';
|
||||
console.error('Issue with fetchPartialContentData', error);
|
||||
} finally {
|
||||
this.partialLoading = false;
|
||||
}
|
||||
},
|
||||
async fetchFullContentData(path) {
|
||||
try {
|
||||
if (
|
||||
this.contentType === 'etape'
|
||||
|| this.contentType === 'static'
|
||||
|| this.contentType === 'ressourceItem'
|
||||
) {
|
||||
this.content = { ...this.content, ...await fetchSingletonFullContent(this.contentType, this.rawContent, path) };
|
||||
} else {
|
||||
this.content = { ...this.content, ...await fetchMultipleFullContent(this.contentType, this.rawContent) };
|
||||
}
|
||||
} catch(error) {
|
||||
this.error = 'Failed to fetch full data';
|
||||
console.error('Issue with fetchFullContentData', error);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
@@ -204,6 +71,7 @@ export const useContentStore = defineStore('content', {
|
||||
this.contentType = '';
|
||||
this.pageTitle = '';
|
||||
this.content = {};
|
||||
this.partialLoading = !forFrontDisplay;
|
||||
this.loading = !forFrontDisplay;
|
||||
this.error = null;
|
||||
useLayoutStore().hideEtapeList(false);
|
||||
|
@@ -128,6 +128,14 @@ export const useLayoutStore = defineStore('layout', {
|
||||
setHeaderPosition(currentPageIsIndex) {
|
||||
const header = document.querySelector('.layout-container > header');
|
||||
header.style.position = currentPageIsIndex ? 'fixed' : 'relative';
|
||||
}
|
||||
},
|
||||
toggleModaleTransition(shouldModaleTransition, enterDelay) {
|
||||
if (shouldModaleTransition) {
|
||||
document.documentElement.style.setProperty('--modale-enter-delay', `${enterDelay}s`);
|
||||
} else {
|
||||
document.documentElement.style.setProperty('margin-top', '0');
|
||||
document.documentElement.style.setProperty('transition', 'none');
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@@ -16,6 +16,39 @@ export const useMapStore = defineStore('mapState', {
|
||||
animationDuration: 3,
|
||||
}),
|
||||
actions: {
|
||||
handleMapMovement(isModaleEtape, wasModaleEtape, lat = this.defaultMapCenter.lat, lon = this.defaultMapCenter.lng) {
|
||||
if (this.animationsAreEnabled) {
|
||||
if (isModaleEtape) {
|
||||
if (!wasModaleEtape) {
|
||||
// national -> détail
|
||||
useLayoutStore().toggleModaleTransition(true, this.animationDuration);
|
||||
this.zoomToPlace(lat, lon);
|
||||
} else {
|
||||
// détail -> détail
|
||||
useLayoutStore().toggleModaleTransition(true, this.animationDuration);
|
||||
this.zoomToPlace(lat, lon);
|
||||
}
|
||||
} else {
|
||||
if (wasModaleEtape) {
|
||||
// détail -> national
|
||||
useLayoutStore().toggleModaleTransition(true, this.animationDuration);
|
||||
this.resetMap();
|
||||
} else {
|
||||
// national -> national
|
||||
useLayoutStore().toggleModaleTransition(true, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isModaleEtape) {
|
||||
// ? -> détail
|
||||
this.zoomToPlace(lat, lon);
|
||||
} else {
|
||||
// ? -> national
|
||||
this.resetMap();
|
||||
}
|
||||
useLayoutStore().toggleModaleTransition(false);
|
||||
}
|
||||
},
|
||||
zoomToPlace(lat, long) {
|
||||
if (useLayoutStore().isDesktop) long = long - 0.03;
|
||||
this.map.flyTo(
|
||||
|
Reference in New Issue
Block a user