Commit 85e53904 authored by Lionel DURAND's avatar Lionel DURAND
Browse files

Livraison #1 octobre 2022

parents 8108feab 1548f36c
# Pour forcer la redirection sur https
RewriteEngine On
RewriteBase /
# Pour forcer la redirection sur https
RewriteCond %{HTTP_HOST} ^dev.resiliencealimentaire.org [NC]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# config pour SPA, voir https://router.vuejs.org/guide/essentials/history-mode.html#apache
# avec exclusion egalement de crater/api
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/crater/api
RewriteRule . /index.html [L]
# Pour forcer la redirection sur https
RewriteEngine On
RewriteBase /
# Pour forcer la redirection sur https
RewriteCond %{HTTP_HOST} ^crater.resiliencealimentaire.org [NC]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
\ No newline at end of file
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# config pour SPA, voir https://router.vuejs.org/guide/essentials/history-mode.html#apache
# avec exclusion egalement de crater/api
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/crater/api
RewriteRule . /index.html [L]
\ No newline at end of file
......@@ -2,7 +2,7 @@ context("Test de vérification des couleurs des territoires après un changement
it('Valider couleur des territoires pour régions', () => {
// init
cy.viewport(1500, 1000);
cy.visit('carte.html');
cy.visit('carte');
cy.get('c-barre-navigation-echelle-territoriale').find('#REGION').click({ force: true });
......
......@@ -4,7 +4,7 @@ context('Test de vérification des couleurs des territoires selon leur note sur
it('Valider couleur des territoires pour agriculteurs & exploitations', () => {
// init
cy.viewport(1500, 1000);
cy.visit('carte.html');
cy.visit('carte');
// Permet d'attendre que la carte soit chargée avant de changer d'axe
cy.get('c-carte').find('.carte__id-territoire__D-75').should('have.attr', 'fill', COULEUR_TERRITOIRE_DONNEES_NON_DISPONIBLES);
......
context("Test l'affichage d'un diagnostic en mode desktop et mobile", () => {
beforeEach(() => {
cy.visit('index.html');
cy.visit('accueil');
});
it.skip('Afficher un diagnostic niveau commune sur écran desktop', () => {
......
......@@ -2,7 +2,7 @@ context("Test l'affichage du diagnostic et le remplissage des données en cache
it("Afficher les 5 échelles territoriales pour le diagnostic d'une commune", () => {
//when
cy.viewport(1500, 1000);
cy.visit('diagnostic.html?idTerritoire=C-31069');
cy.visit('diagnostic?idTerritoire=C-31069');
//then
cy.get('c-barre-navigation-echelle-territoriale').find('label[for=COMMUNE]').should('be.visible');
cy.get('c-barre-navigation-echelle-territoriale').find('label[for=EPCI]').should('be.visible');
......@@ -16,7 +16,7 @@ context("Test l'affichage du diagnostic et le remplissage des données en cache
it.skip("Vider le cache et afficher uniquement 3 échelles pour le diagnostic d'un département", () => {
//given
cy.viewport(1500, 1000);
cy.visit('diagnostic.html?idTerritoire=C-31069');
cy.visit('diagnostic?idTerritoire=C-31069');
// when
cy.rechercherTerritoire('champ-recherche-territoire-fixe', 'haute-garonne', 1);
//then
......
context('Test recherche territoire et liste de suggestions', () => {
beforeEach(() => {
cy.visit('index.html');
cy.visit('accueil');
});
it.skip('Afficher 10 éléments maxi sur une recherche', () => {
......@@ -10,7 +10,7 @@ context('Test recherche territoire et liste de suggestions', () => {
it.skip('Rechercher depuis la barre de navigation en mode desktop', () => {
// init
cy.viewport(1500, 1000);
cy.visit('diagnostic.html?idTerritoire=P-FR');
cy.visit('diagnostic?idTerritoire=P-FR');
// verifier visibilite/masquage des champs recherche
cy.get('nav').should('be.visible');
......@@ -27,7 +27,7 @@ context('Test recherche territoire et liste de suggestions', () => {
it.skip('Rechercher depuis la barre de navigation en mode tablette', () => {
// init
cy.viewport(1300, 1000);
cy.visit('diagnostic.html?idTerritoire=P-FR');
cy.visit('diagnostic?idTerritoire=P-FR');
// verifier visibilite/masquage des champs recherche
// cy.get("header").should("be.hidden");
......
......@@ -7,7 +7,7 @@ context('Test de vérification affichage du bandeau erreur technique', () => {
});
cy.viewport(1500, 1000);
cy.visit('index.html');
cy.visit('accueil');
cy.get(`[data-cy=champ-recherche-territoire]`).find('input').should('be.visible').type('pari', { force: true });
......
......@@ -2,7 +2,7 @@ context('Test de vérification plier/deplier menu glissant', () => {
it('Le bouton du burger menu doit etre masqué sur écran large', () => {
// init
cy.viewport(1500, 1000);
cy.visit('index.html');
cy.visit('accueil');
cy.get('c-menu-glissant').should('be.hidden');
cy.get('[data-cy=bouton-ouvrir-menu-glissant]').should('be.hidden');
......@@ -11,7 +11,7 @@ context('Test de vérification plier/deplier menu glissant', () => {
it('Afficher le menu glissant', () => {
// init
cy.viewport(1000, 1000);
cy.visit('index.html');
cy.visit('accueil');
cy.get('c-menu-glissant').should('be.hidden');
cy.get('[data-cy=bouton-ouvrir-menu-glissant]').click({ force: true });
......@@ -26,7 +26,7 @@ context('Test de vérification plier/deplier menu glissant', () => {
it('Masquer le menu glissant', () => {
// init
cy.viewport(1000, 1000);
cy.visit('index.html');
cy.visit('accueil');
// click sur le bouton fermer
cy.get('[data-cy=bouton-ouvrir-menu-glissant]').click({ force: true });
......
This diff is collapsed.
......@@ -34,9 +34,11 @@
"apexcharts": "./lib/apexcharts-3.35.3.patch",
"geojson": "^0.5.0",
"leaflet": "^1.7.1",
"swagger-ui": "3.52.2"
"swagger-ui": "3.52.2",
"query-selector-shadow-dom": "^1.0.0"
},
"devDependencies": {
"@types/query-selector-shadow-dom": "^1.0.0",
"@types/geojson": "^7946.0.8",
"@types/leaflet": "^1.7.9",
"@types/swagger-ui": "^3.52.0"
......
import './commun/composants/PiedPage.js';
import './commun/composants/MessageErreurGlissant.js';
import './pages/generiques/PageSablier.js';
// TODO : on doit import vue-base ici (alors que les composants vue l'importe également) et ce pour le faire avant diagnostic.css (qui redefinit la hauteur de l'entete). Voir si pas moyend e faire autrement
import '@lga/commun/build/composants/vue-base.css';
import { EvenementErreur, EvenementNaviguer, IDS_EVENEMENTS } from '@lga/commun';
import { css, html, LitElement } from 'lit';
import { customElement, query, state } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import page, { Context } from 'page';
import { BarreNavigationEchelleTerritoriale, Entete, MessageErreurGlissant } from './commun/composants';
import { importDynamique } from './commun/composants/importDynamiqueDirective';
import { estActifModeBeta, PARAMETRE_URL_ACTIVER_FONCTIONS_BETA } from './commun/mode-beta';
import { PARAMETRE_URL_ECHELLE_TERRITORIALE, PARAMETRE_URL_IDENTIFIANT_INDICATEUR, PARAMETRE_URL_IDENTIFIANT_TERRITOIRE } from './commun/routeur';
declare global {
interface HTMLElementTagNameMap {
'c-crater-app': CraterApp;
}
}
type NomPage = 'accueil' | 'diagnostic' | 'carte' | 'projet' | 'methodologie' | 'api';
@customElement('c-crater-app')
export class CraterApp extends LitElement {
// Composant créé dans le DOM principal (pas de shadow dom), pour pouvoir scroller sur les hash internes
protected createRenderRoot() {
return this;
}
static styles = css``;
@state()
pageCourante: NomPage = 'accueil';
@state()
private idTerritoirePrincipal?: string;
@state()
private idEchelleTerritoriale?: string;
@state()
private idIndicateur?: string;
@state()
private hashCourant = '';
@query('c-barre-navigation-echelle-territoriale') private barreNavigationEchelleTerritoriale?: BarreNavigationEchelleTerritoriale;
@query('c-entete') private entete!: Entete;
@query('c-message-erreur-glissant') private messageErreurGlissant!: MessageErreurGlissant;
constructor() {
super();
this.configurerRoutes();
}
private configurerRoutes() {
page.redirect('/', '/accueil');
page.redirect('/index.html', '/accueil');
page.redirect('/diagnostic.html', '/diagnostic');
page.redirect('/carte.html', '/carte');
page.redirect('/projet.html', '/projet');
page.redirect('/methodologie.html', '/methodologie');
page.redirect('/api-doc.html', '/api-doc');
page('/accueil', (ctx) => this.routerVersPage(ctx, 'accueil'));
page('/diagnostic', (ctx) => this.routerVersPage(ctx, 'diagnostic'));
page('/carte', (ctx) => this.routerVersPage(ctx, 'carte'));
page('/projet', (ctx) => this.routerVersPage(ctx, 'projet'));
page('/methodologie', (ctx) => this.routerVersPage(ctx, 'methodologie'));
page('/api-doc', (ctx) => this.routerVersPage(ctx, 'api'));
page('*', (ctx) => this.routerVersPage(ctx, 'accueil'));
page();
}
private routerVersPage = (context: Context, nomPage: NomPage) => {
if (this.pageCourante !== nomPage) {
this.resetScrollPage();
}
this.pageCourante = nomPage;
this.idTerritoirePrincipal = this.getRequestParamValue(context.querystring, PARAMETRE_URL_IDENTIFIANT_TERRITOIRE);
this.idEchelleTerritoriale = this.getRequestParamValue(context.querystring, PARAMETRE_URL_ECHELLE_TERRITORIALE);
this.idIndicateur = this.getRequestParamValue(context.querystring, PARAMETRE_URL_IDENTIFIANT_INDICATEUR);
this.hashCourant = context.hash;
};
private resetScrollPage() {
window.scrollTo({ top: 0, left: 0, behavior: 'auto' });
}
private getRequestParamValue(queryString: string, requestParamName: string): string | undefined {
const params = new URLSearchParams(queryString);
return params.has(requestParamName) ? params.get(requestParamName)! : undefined;
}
render() {
return html`
<c-message-erreur-glissant></c-message-erreur-glissant>
${this.renderPageCourante()}
`;
}
private renderPageCourante() {
switch (this.pageCourante) {
case 'accueil':
return importDynamique(
import('./pages/accueil/PageAccueil.js'),
html`<c-page-accueil idElementCibleScroll="${this.hashCourant}"></c-page-accueil>`,
html`<c-page-sablier></c-page-sablier>`
);
case 'diagnostic':
return importDynamique(
import('./pages/diagnostic/PageDiagnostic.js'),
html`<c-page-diagnostic
idTerritoirePrincipal=${ifDefined(this.idTerritoirePrincipal)}
idElementCibleScroll="${ifDefined(this.hashCourant)}"
></c-page-diagnostic>`,
html`<c-page-sablier></c-page-sablier>`
);
case 'carte':
return importDynamique(
import('./pages/carte/PageCarte.js'),
html`<c-page-carte
idTerritoirePrincipal=${ifDefined(this.idTerritoirePrincipal)}
idEchelleTerritoriale="${ifDefined(this.idEchelleTerritoriale)}"
idIndicateur="${ifDefined(this.idIndicateur)}"
></c-page-carte>`,
html`<c-page-sablier></c-page-sablier>`
);
case 'projet':
return importDynamique(
import('./pages/projet/PageProjet.js'),
html`<c-page-projet></c-page-projet>`,
html`<c-page-sablier></c-page-sablier>`
);
case 'methodologie':
return importDynamique(
import('./pages/methodologie/PageMethodologie.js'),
html`<c-page-methodologie idElementCibleScroll="${this.hashCourant}"></c-page-methodologie>`,
html`<c-page-sablier></c-page-sablier>`
);
case 'api':
return importDynamique(import('./pages/api/PageApi.js'), html`<c-page-api></c-page-api>`, html`<c-page-sablier></c-page-sablier>`);
}
}
naviguer(url: string, cible = '_self') {
if (url.startsWith('#')) {
// lien intern vers hash
const urlCible = new URL(location.href);
urlCible.hash = url;
page(`${urlCible.pathname}${urlCible.search}${urlCible.hash}`);
} else if (!url.startsWith('http') && cible === 'self') {
// lien interne
if (estActifModeBeta()) url.includes('?') ? (url += '&beta') : (url += '?beta');
page(url);
const urlCible = new URL(location.href);
if (estActifModeBeta() && !urlCible.searchParams.has(PARAMETRE_URL_ACTIVER_FONCTIONS_BETA)) {
urlCible.searchParams.set(PARAMETRE_URL_ACTIVER_FONCTIONS_BETA, '');
}
urlCible.hash = url;
page(url);
} else {
// lien externe
window.open(url, cible);
}
}
firstUpdated() {
document.addEventListener(IDS_EVENEMENTS.erreur, (evt: Event) => {
this.messageErreurGlissant.maj((<EvenementErreur>evt).detail.erreur);
});
document.addEventListener(IDS_EVENEMENTS.naviguer, (event: Event) => {
this.naviguer((<EvenementNaviguer>event).detail.url, (<EvenementNaviguer>event).detail.cible);
});
}
}
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>L'API de CRATer</title>
<link rel="icon" type="image/png" href="./ressources/images/crater-favicon-32x32.png" sizes="32x32" />
</head>
<body style="opacity: 0">
<c-message-erreur-glissant></c-message-erreur-glissant>
<c-entete class="zone-entete-page-position-fixe"></c-entete>
<main class="zone-scroll-principal">
<section class="premiereSection">
<h1>Utilisez les données de CRATer dans votre application</h1>
<p>
L'ensemble des données et des résultats du calculateur CRATer sont disponibles sous forme d'APIs, dont la documentation technique
est décrite ci-dessous.
</p>
<p>
L'API est susceptible d'évoluer, sans garantie de compatibilité ascendante entre les versions. Si vous utilisez cette API dans vos
applications, merci de nous l'indiquer via le <a href="./formulaire-crater/">formulaire de contact</a> afin que nous puissions
vous tenir informé des impacts éventuels. Merci également de prendre connaissance des
<a href="./methodologie.html#licence-d-utilisation-crater">conditions d'utilisation des données</a>.
</p>
<div id="swagger-ui"></div>
</section>
</main>
<c-pied-page></c-pied-page>
<script type="module" src="./page-statique/api-doc.ts" defer></script>
<script type="module" src="./page-statique/page-statique.ts"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<title>CRATer - Cartographie</title>
<meta charset="utf-8" />
<!-- maximum-scale=1 nécessaire pour bloquer le zoom auto fait par certains navigateurs (safari) -->
<!-- ce zoom auto est fait qd on rentre dans le champ input et que la font size est < 11px, il n'est pas réinitialisé ensuite -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/png" href="ressources/images/crater-favicon-32x32.png" sizes="32x32" />
<meta property="og:url" content="https://crater.resiliencealimentaire.org" />
<meta property="og:type" content="website" />
<meta property="og:title" content="CRATer, le Calculateur pour la Résilience Alimentaire des TERritoires" />
<meta
property="og:description"
content="Application d'aide au diagnostic du système alimentaire. Visualisez en un clic des indicateurs et leviers d'actions pour votre commune, epci, département ou région."
/>
<meta property="og:image" content="https://crater.resiliencealimentaire.org/ressources/images/crater-lien-rs.jpg" />
<meta property="fb:app_id" content="crater_lga" />
</head>
<body style="opacity: 0">
<c-message-erreur-glissant></c-message-erreur-glissant>
<header class="zone-entete-page-position-fixe">
<c-entete id="carte__entete__titre-et-nav" activerRechercheTerritoire filtrerCategoriesTerritoiresPourRechercheCarte></c-entete>
<c-barre-navigation-echelle-territoriale></c-barre-navigation-echelle-territoriale>
</header>
<div id="carte__contenu-erreur" class="invisible">
<div>
<h2>Données manquantes</h2>
<p>
Il peut s'agir d'une erreur de saisie dans le code du territoire dans l'URL, ou bien d'une indisponibilité temporaire du serveur.
<br />Merci de vérifier votre saisie, et d'essayer à nouveau dans quelques secondes. <br />Si le problème persiste, vous pouvez
nous envoyer un message via le
<a href="https://resiliencealimentaire.org/formulaire-crater/" target="_blank">formulaire de contact</a>.
</p>
</div>
</div>
<div id="carte__contenu-pret">
<main class="zone-scroll-principal">
<section id="section-choix-indicateur" class="masquer-sur-tablette">
<c-menu-indicateurs id="carte__menu-choix-indicateur-dans-panneau-statique"></c-menu-indicateurs>
</section>
<section id="section-carte">
<c-sablier></c-sablier>
<c-menu-indicateurs-glissant class="masquer-par-defaut afficher-sur-tablette"></c-menu-indicateurs-glissant>
<c-titre-et-legende-carte></c-titre-et-legende-carte>
<c-carte></c-carte>
</section>
</main>
</div>
</body>
<script type="module" src="./carte/main-carte.ts"></script>
<!-- Forcer la lecture d'une variable CSS depuis la page HTML pour attendre la fin du traitement CSS -->
<!-- Sans clea, pb intermittent avec Chrome, qui charge les js en modulepreload puis les css, et exécute le js alors que l'analyse CSS n'est pas terminée (et donc la carte est noire) -->
<!-- Une alternative serait de désactiver le modulepreload pour le js, mais pas encore possible avec vitejs voir github.com/vitejs/vite/issues/5120 -->
<script>
document.addEventListener('DOMContentLoaded', () => {
console.log(
'Variables CSS chargée. Exemple pour la variable --c-carte-et-note-territoire-vert = ' +
getComputedStyle(document.documentElement).getPropertyValue('--c-carte-et-note-territoire-vert')
);
});
</script>
</html>
import './PopupCarte.js';
import { CSS_BREAKPOINT_MAX_WIDTH_TABLETTE, EvenementDeplacerCarte } from '@lga/commun';
import * as geojson from 'geojson';
import { Feature, Point } from 'geojson';
......@@ -16,9 +18,6 @@ import {
} from '../../commun/requetes-api/requetes-api-carte';
import { EchelleTerritoriale } from '../domaines/EchelleTerritoriale';
import { TerritoiresVisiblesCarte } from '../domaines/TerritoiresVisiblesCarte';
import { PopupCarte } from './PopupCarte';
PopupCarte;
//
// Config
......@@ -170,7 +169,7 @@ export class Carte extends LitElement {
//////////////////////////////////////
// Déclaration des fonctions publiques
//////////////////////////////////////
afficher(
maj(
idEchelleTerritoriale: string,
territoiresVisiblesCarte: TerritoiresVisiblesCarte,
maxZoom: number,
......@@ -349,7 +348,7 @@ export class Carte extends LitElement {
}
private gererClickFermeturePopup = (event: Event) => {
if (!this.contains(event.target as Node | null)) {
if (!event.composedPath().includes(this)) {
this.carteLeaflet!.closePopup();
}
};
......
import { CSS_BREAKPOINT_MAX_WIDTH_MOBILE_PAYSAGE, CSS_BREAKPOINT_MAX_WIDTH_TABLETTE, EvenementSelectionner } from '@lga/commun';
import '../../commun/composants/Bouton.js';
import { CSS_BREAKPOINT_MAX_WIDTH_MOBILE_PAYSAGE, CSS_BREAKPOINT_MAX_WIDTH_TABLETTE, EvenementNaviguer, EvenementSelectionner } from '@lga/commun';
import { css, html, LitElement, unsafeCSS } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
import { FORME_BOUTON } from '../../commun/composants';
import { naviguer } from '../../commun/navigation';
export interface OptionsIndicateurs {
id: string;
......@@ -21,6 +22,12 @@ export interface OptionsMaillon {
icone?: string;
}
export interface OptionsMenuIndicateurs {
maillons: OptionsMaillon[];
indicateurs: OptionsIndicateurs[];
idIndicateurActif: string;
}
declare global {
interface HTMLElementTagNameMap {
'c-menu-indicateurs': MenuIndicateurs;
......@@ -218,7 +225,8 @@ export class MenuIndicateurs extends LitElement {
<span>${unsafeHTML(i.description)}</span>
</h2>
<c-bouton
@click="${() => naviguer(`./methodologie.html#${i.id}`, '_blank')}"
@click="${() =>
this.dispatchEvent(new EvenementNaviguer(`methodologie#${i.id}`, '_blank'))}"
libelle="?"
libelleTooltip="Plus d'infos sur cet indicateur"
formeBouton="${FORME_BOUTON.rond}"
......@@ -238,9 +246,9 @@ export class MenuIndicateurs extends LitElement {
this.dispatchEvent(new EvenementSelectionner((<HTMLElement>e.target)?.id));
}
maj(maillons: OptionsMaillon[], indicateurs: OptionsIndicateurs[], idIndicateurActif: string) {
this.maillons = maillons;
this.indicateurs = indicateurs;
this.idIndicateurActif = idIndicateurActif;
maj(options: OptionsMenuIndicateurs) {
this.maillons = options.maillons;
this.indicateurs = options.indicateurs;
this.idIndicateurActif = options.idIndicateurActif;
}
}
import './MenuIndicateurs.js';
import { EvenementFermer } from '@lga/commun';
import { css, html, LitElement } from 'lit';
import { customElement, query } from 'lit/decorators.js';
import { customElement, query, state } from 'lit/decorators.js';
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
import { Bouton } from '../../commun/composants';
import { ICONES_SVG } from '../../commun/configuration/icones_svg';
import { MenuIndicateurs, OptionsIndicateurs, OptionsMaillon } from './MenuIndicateurs';
import { MenuIndicateurs, OptionsMenuIndicateurs } from './MenuIndicateurs';
declare global {
interface HTMLElementTagNameMap {
......@@ -57,6 +59,9 @@ export class MenuIndicateursGlissant extends LitElement {
@query('c-menu-indicateurs')
private menuIndicateurs!: MenuIndicateurs;
@state()
private options?: OptionsMenuIndicateurs;
render() {
return html`
<c-panneau-glissant>
......@@ -71,8 +76,14 @@ export class MenuIndicateursGlissant extends LitElement {
`;
}
maj(listeMaillons: OptionsMaillon[], listeIndicateurs: OptionsIndicateurs[], idIndicateurActif: string) {
this.menuIndicateurs.maj(listeMaillons, listeIndicateurs, idIndicateurActif);
maj(options: OptionsMenuIndicateurs) {
this.options = options;
}
updated() {
if (this.options === undefined) return;
this.menuIndicateurs.maj(this.options);
}
private fermer() {
......
import '../../commun/composants/JaugeNoteSur10.js';
import { css, html, LitElement } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
import { formaterNombreEnNDecimalesString } from '../../commun/base';
import { JaugeNoteSur10 } from '../../commun/composants';
import { TypeJauge } from '../../commun/domaines/StyleIndicateur';
import { naviguer } from '../../commun/navigation';