Commit 807a6792 authored by Benjam's avatar Benjam
Browse files

20220420_livraison_avril_#1

parents 8952e278 33dda212
......@@ -21,10 +21,10 @@ npm-build-dev:
stage: build
except:
- master
image: node:14-alpine
image: node:16.14.0-alpine
script:
- npm ci
- npm run build:o2switch:dev
- npm run build:o2switch-dev
artifacts:
paths:
- build/
......@@ -36,14 +36,14 @@ npm-build-prod:
image: node:14-alpine
script:
- npm ci
- npm run build:o2switch:crater
- npm run build:o2switch-crater
artifacts:
paths:
- build/
# this job installs NPM dependencies and Cypress
cypress-install:
image: cypress/browsers:node14.17.0-chrome88-ff89
image: cypress/browsers:node16.14.0-slim-chrome99-ff97
stage: build
script:
- npm ci
......@@ -55,7 +55,7 @@ cypress-install:
- npm run cypress:info
cypress-tests:
image: cypress/browsers:node14.17.0-chrome88-ff89
image: cypress/browsers:node16.14.0-slim-chrome99-ff97
stage: test
script:
- npm run cypress:test:shell-mode:firefox
......
......@@ -11,7 +11,9 @@ Les instructions ci-dessous décrivent comment installer et utiliser crater-ui.
## 1) Installer l'environnement
Pre-requis : installer [nodejs](https://nodejs.org/en/download/) (version 14.15.1 ou supérieure)
Pre-requis : installer [nodejs](https://nodejs.org/en/download/)
Il faut installer la version 16.14.0, qui est celle utilisée par les pipelines gitlab (voir gitlabci)
Puis :
......@@ -21,31 +23,27 @@ Puis :
## 2) Lancer l'application en local
Compiler et lancer l'application en local, avec prise en compte à chaud des modifications : `npm run start`
Remarque :
* Cette configuration utilise l'environnement `dev` par défaut avec l'api disponible à cette adresse https://dev.resiliencealimentaire.org/.
* Ajuster cette configuration si nécessaire en modifiant la valeur de `apiBaseUrl` dans le fichier [`config.js`](config/dev.o2switch/config.js) (par ex: `var apiBaseUrl = "http://127.0.0.1:3000/"` pour utiliser une instance de crater-api qui tourne en local).
Pour lancer l'application en mode développement (démarrage rapide, sans build ni tests, ni formatage, avec prise en compte à chaud des modifications) : `npm run start`
## 3) Lancer les tests cypress
Pour lancer un build avec test et formatage : `npm run build`, et pour tester le build : `npm run serve`
Pour lancer les tests cypress :
Remarque :
* Cette configuration utilise l'environnement `dev` par défaut avec l'api disponible à cette adresse https://dev.resiliencealimentaire.org/.
* En utilisant le script `start:localhost` il est possible de lancer l'application en mode développement, en utilisant un instance de crater-api exécutée en local, à cette adresse http://localhost:3000.
* En utilisant les scripts `build:localhost` et `build:o2switch-crater` (puis `serve`) il est possible de construire un build puis de le tester en utilisant respectivement l'api à l'adresse http://localhost:3000 ou l'api de production à l'adresse https://crater.resiliencealimentaire.org/.
* lancer les tests en mode interactif dans l'app cypress `npm run cypress:test:app-mode:local`
* lancer les tests dans un shell en ligne de commande `npm run cypress:test:shell-mode:local`
## 3) Valider l'application (tests cypress)
## 4) Builder l'application en local et exécuter le build
Pour valider l'ensemble de l'application : `npm run validate`
Cette commande est à lancer avant de pousser le code d'une branche sur le serveur. Elle permet de lancer l'ensemble des tests unitaires, ainsi que les tests cypress
Pour tester un build sur l'environnement `dev` (cad qui utilise l'api `https://dev.resiliencealimentaire.org/`) :
* `npm run build:o2switch:dev` : construit l'application dans `build`
* `npm run serve:build` : lance un serveur et exposer l'application à l'adresse `http://localhost:8088`
Pour lancer les tests cypress spécifiquement :
Pour tester un build sur l'environnement `crater` (cad qui utilise l'api `https://crater.resiliencealimentaire.org/`) :
* `npm run build:o2switch:crater` : construit l'application dans `build`, en optimisant le build pour un environnement de production (voir le fichier snowpack.config.o2switch.crater.mjs)
* `npm run serve:build` : lance un serveur et exposer l'application à l'adresse `http://localhost:8088`
* lancer les tests en mode interactif dans l'app cypress `npm run cypress:test:app-mode`
* lancer les tests dans un shell en ligne de commande `npm run cypress:test:shell-mode`
## 5) Livrer sur les environnements dev et crater
## 4) Livrer sur les environnements dev et crater
L'application est déployée automatiquement sur les 2 environnements de développement (`dev`) et de production (`crater`), via des pipelines gitlab définis dans le fichier [.gitlab-ci.yml](.gitlab-ci.yml)
......
VITE_API_BASE_URL=http://127.0.0.1:3000/
NODE_ENV=production
VITE_API_BASE_URL=https://crater.resiliencealimentaire.org/
VITE_API_BASE_URL=https://dev.resiliencealimentaire.org/
var apiBaseUrl = 'https://crater.resiliencealimentaire.org/';
//var apiBaseUrl = 'http://127.0.0.1:3000/';
var apiBaseUrl = 'https://dev.resiliencealimentaire.org/';
This diff is collapsed.
......@@ -3,59 +3,58 @@
"version": "1.0.0",
"description": "",
"scripts": {
"clean": "rm -rf _ts-build build",
"clean": "rimraf _ts-build build",
"prettier-format": "prettier --write '**/*.{ts,tsx,js,jsx,html}'",
"precompile": "npm run prettier-format",
"compile": "tsc",
"tsc": "tsc",
"compile": "run-s clean tsc prettier-format",
"test": "jest",
"prestart": "npm run compile && npm run test",
"start": "snowpack dev",
"prebuild:local": "npm run compile && npm run test",
"build:local": "snowpack build",
"prebuild:o2switch:dev": "npm run test",
"build:o2switch:dev": "snowpack build --config snowpack.config.o2switch.dev.mjs",
"prebuild:o2switch:crater": "npm run test",
"build:o2switch:crater": "snowpack build --config snowpack.config.o2switch.crater.mjs",
"serve-build": "http-server build --port 8088",
"start": "run-s start:o2switch-dev",
"start:o2switch-dev": "vite --mode o2switch.dev --port 8080",
"start:localhost": "vite --mode localhost --port 8080",
"build": "run-s build:o2switch-dev",
"build:o2switch-dev": "run-s compile test build:vite:o2switch-dev build:cp-config:o2switch-dev",
"build:localhost": "run-s compile test build:vite:localhost",
"build:o2switch-crater": "run-s compile test build:vite:o2switch-crater build:cp-config:o2switch-crater",
"build:vite:o2switch-dev": "vite build --mode o2switch.dev",
"build:vite:localhost": "vite build --mode localhost",
"build:vite:o2switch-crater": "vite build --mode o2switch.crater",
"build:cp-config:o2switch-dev": "ncp config/o2switch.dev build",
"build:cp-config:o2switch-crater": "ncp config/o2switch.crater build",
"serve": "vite preview --port 8088",
"cypress:open": "cypress open --config 'baseUrl=http://localhost:8088/'",
"cypress:run": "cypress run --config 'baseUrl=http://localhost:8088/'",
"cypress:run": "run-s cypress:run:firefox",
"cypress:run:firefox": "cypress run --browser firefox --config 'baseUrl=http://localhost:8088/'",
"cypress:run:chrome": "cypress run --browser chrome --config 'baseUrl=http://localhost:8088/'",
"cypress:verify": "cypress verify",
"cypress:info": "cypress info",
"cypress:version": "cypress version",
"cypress:test:shell-mode": "npm run serve-build & npm run cypress:run",
"cypress:test:shell-mode:firefox": "npm run serve-build & npm run cypress:run:firefox",
"cypress:test:shell-mode:chrome": "npm run serve-build & npm run cypress:run:chrome",
"cypress:test:app-mode": "npm run serve-build & npm run cypress:open",
"cypress:test:app-mode:local": "snowpack build && npm run cypress:test:app-mode",
"cypress:test:shell-mode:local": "npm run build:local && npm run cypress:test:shell-mode:firefox",
"cypress:test:shell-mode:local:dev-config": "npm run build:o2switch:dev && npm run cypress:test:shell-mode:firefox"
"cypress:test:shell-mode": "npm run serve & npm run cypress:run",
"cypress:test:shell-mode:firefox": "npm run serve & npm run cypress:run:firefox",
"cypress:test:shell-mode:chrome": "npm run serve & npm run cypress:run:chrome",
"cypress:test:app-mode": "npm run serve & npm run cypress:open",
"validate": "run-s build cypress:test:shell-mode"
},
"dependencies": {
"autocompleter": "6.1.0",
"chart.js": "2.9.3",
"chartjs-chart-treemap": "0.2.3",
"chartjs-plugin-annotation": "0.5.7",
"apexcharts": "3.30.0",
"leaflet": "1.7.1",
"autocompleter": "^6.1.2",
"apexcharts": "^3.33.2",
"leaflet": "^1.7.1",
"swagger-ui": "3.52.2",
"geojson": "^0.5.0"
"geojson": "^0.5.0",
"lit": "^2.2.1"
},
"devDependencies": {
"@snowpack/plugin-typescript": "1.2.1",
"@types/chart.js": "2.9.34",
"@types/chartjs-plugin-annotation": "0.5.2",
"@types/jest": "27.0.2",
"@types/leaflet": "1.7.5",
"@types/jest": "^27.4.1",
"@types/leaflet": "^1.7.9",
"@types/geojson": "^7946.0.8",
"@types/swagger-ui": "3.47.1",
"cypress": "8.5.0",
"http-server": "13.0.2",
"jest": "27.2.1",
"prettier": "2.5.1",
"snowpack": "3.8.8",
"ts-jest": "27.0.5",
"typescript": "4.4.2"
"@types/swagger-ui": "^3.52.0",
"rimraf": "^3.0.2",
"npm-run-all": "^4.1.5",
"cypress": "^9.5.2",
"jest": "^27.2.5",
"prettier": "^2.6.1",
"vite": "^2.8.6",
"ts-jest": "^27.1.4",
"typescript": "^4.6.3",
"ncp": "^2.0.0"
}
}
/** @type {import("snowpack").SnowpackUserConfig } */
export default {
mount: {
src: '/',
'config/o2switch.dev': {url: '/', dot: true}
},
testOptions: {
files: ["**/__test__/**/*", "**/*.@(spec|test).*"]
},
optimize: {
bundle: false,
minify: false,
sourcemap: true
},
plugins: ['@snowpack/plugin-typescript']
};
\ No newline at end of file
/** @type {import("snowpack").SnowpackUserConfig } */
export default {
mount: {
src: '/',
'config/o2switch.crater': {url: '/', dot: true}
},
testOptions: {
files: ["**/__test__/**/*", "**/*.@(spec|test).*"]
},
optimize: {
// TODO : voir pourquoi bundle: true casse les tests cypress sur gitlab & l'activer en prod
bundle: false,
minify: true,
sourcemap: false
},
plugins: ['@snowpack/plugin-typescript']
};
\ No newline at end of file
/** @type {import("snowpack").SnowpackUserConfig } */
export default {
mount: {
src: '/',
'config/o2switch.dev': {url: '/', dot: true}
},
testOptions: {
files: ["**/__test__/**/*", "**/*.@(spec|test).*"]
},
optimize: {
// TODO : voir pourquoi bundle: true casse les tests cypress sur gitlab & l'activer en prod
bundle: true,
minify: true,
sourcemap: false
},
plugins: ['@snowpack/plugin-typescript']
};
\ No newline at end of file
......@@ -4,7 +4,7 @@
<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="./images/crater-favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./ressources/images/crater-favicon-32x32.png" sizes="32x32" />
</head>
<body style="opacity: 0">
......@@ -34,9 +34,7 @@
<footer id="structure-page__pied-page"></footer>
<script src="./config.js" defer></script>
<script type="module" src="page-statique/api-doc.js" defer></script>
<script type="module" src="page-statique/page-statique.js"></script>
<script type="module" src="./page-statique/api-doc.ts" defer></script>
<script type="module" src="./page-statique/page-statique.ts"></script>
</body>
</html>
......@@ -9,7 +9,7 @@
<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="images/crater-favicon-32x32.png" sizes="32x32" />
<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" />
......@@ -18,7 +18,7 @@
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/images/crater-lien-rs.jpg" />
<meta property="og:image" content="https://crater.resiliencealimentaire.org/ressources/images/crater-lien-rs.jpg" />
<meta property="fb:app_id" content="crater_lga" />
</head>
......@@ -65,6 +65,16 @@
</div>
</body>
<script src="./config.js" defer></script>
<script type="module" src="carte/main-carte.js"></script>
<script type="module" src="./carte/main-carte.ts"></script>
<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 -->
document.addEventListener('DOMContentLoaded', () => {
console.log(
'Variables CSS chargée. Exemple pour la varialbe --c-carte-et-note-territoire-vert = ' +
getComputedStyle(document.documentElement).getPropertyValue('--c-carte-et-note-territoire-vert')
);
});
</script>
</html>
......@@ -106,30 +106,57 @@ div.invisible {
align-items: center;
}
#carte__barre-navigation ul {
margin: 0 ;
padding-left: 2rem;
height: var(--hauteur-entete-retour-diagnostic);
#carte__bouton-retour-diagnostic a {
display: flex;
justify-items: left;
flex-wrap: nowrap;
align-items: center;
margin: 0.2rem;
margin-left: 1rem;
color: var(--bleu-marine);
}
#carte__barre-navigation li {
list-style: none;
margin: 0;
cursor: pointer;
#carte__bouton-retour-diagnostic:hover a {
text-decoration: underline;
}
#carte__barre-navigation a {
text-decoration: none;
font-size: var(--smaller);
#carte__bouton-retour-diagnostic svg {
display: grid;
fill: var(--bleu-marine);
margin: 0.5rem;
width: 20px;
height: 20px;
}
#carte__barre-navigation a:hover{
text-decoration: underline;
#carte__bouton-retour-diagnostic .libelle {
width: 30px;
white-space: nowrap;
}
#carte__boutons-choix-echelle-territoriale {
margin: auto;
width: min-content;
}
#carte__boutons-choix-echelle-territoriale ul {
white-space: nowrap;
background-color: var(--c-carte-groupe-boutons-echelle-territoriale-fond);
padding: 0.2em;
border-radius: 0.5em;
}
#carte__boutons-choix-echelle-territoriale input + label {
background-color: transparent;
border-radius: 0.5em;
}
#carte__boutons-choix-echelle-territoriale input:checked + label {
background-color: var(--c-texte-base3);
box-shadow: 0 2px 6px 0 var(--ombre);
}
#carte__boutons-choix-echelle-territoriale li:hover label {
text-decoration: underline;
}
/*--------------------------------------*/
/* Panneau glissant de choix d'indicateur*/
......@@ -260,32 +287,6 @@ div.invisible {
background-color: transparent;
}
#carte__bouton-retour-diagnostic a {
display: flex;
flex-wrap: nowrap;
align-items: center;
margin: 0.2rem;
margin-left: 1rem;
color: var(--bleu-marine);
}
#carte__bouton-retour-diagnostic:hover a {
text-decoration: underline;
}
#carte__bouton-retour-diagnostic svg {
display: grid;
fill: var(--bleu-marine);
margin: 0.5rem;
width: 20px;
height: 20px;
}
#carte__bouton-retour-diagnostic .libelle {
width: 30px;
white-space: nowrap;
}
#carte__bouton-afficher-panneau-glissant-choix-indicateur {
margin: 0.2rem;
}
......@@ -302,36 +303,6 @@ div.invisible {
color: var(--c-carte-bouton-calques);
}
/*--------------------------------------*/
/* Section carte - boutons choix echelle*/
/*--------------------------------------*/
#carte__boutons-choix-echelle-territoriale {
margin: auto;
width: min-content;
}
#carte__boutons-choix-echelle-territoriale ul {
white-space: nowrap;
background-color: var(--c-carte-groupe-boutons-echelle-territoriale-fond);
padding: 0.2em;
border-radius: 0.5em;
}
#carte__boutons-choix-echelle-territoriale input + label {
background-color: transparent;
border-radius: 0.5em;
}
#carte__boutons-choix-echelle-territoriale input:checked + label {
background-color: var(--c-texte-base3);
box-shadow: 0 2px 6px 0 var(--ombre);
}
#carte__boutons-choix-echelle-territoriale li:hover label {
text-decoration: underline;
}
/*--------------------------------------*/
/* Section carte - LEGENDE */
/*--------------------------------------*/
......@@ -497,6 +468,22 @@ div.invisible {
padding: 0.4rem;
}
/*--------------------------------------*/
/* Section carte - Prefectures */
/*--------------------------------------*/
.icones-villes {
background: black;
}
.icones-villes .libelle {
font-size: var(--bigger);
font-family: var(--base-font-family);
white-space: nowrap;
padding-left: 3px;
}
/* ------------------------------------ */
/* Media queries affichage mobile */
/* ------------------------------------ */
......
import { Afficheur } from '../../commun/controleurs/Afficheur';
import { Indicateur } from '../../commun/domaines/Indicateur';
import {
EnteteTitreEtNavigation,
GroupeBoutons,
injecterHtmlParIdElement,
MenuGlissant,
rendreInvisible,
rendreVisible,
rendreVisibleBody,
EnteteTitreEtNavigation, GroupeBoutons, injecterHtmlParIdElement, MenuGlissant, rendreInvisible, rendreVisible, rendreVisibleBody,
ZoneMessageErreur
} from '../../commun/vues';
import { PanneauGlissant } from '../../commun/vues/crater/PanneauGlissant';
......@@ -98,6 +92,7 @@ export class AfficheurCarte implements Afficheur<PageCarte> {
this.boutonAfficherPanneauGlissant.afficher();
this.panneauGlissant.afficher(false);
this.carteColoree.afficher(
pageCarte.getCouchesVilles(),
pageCarte.getEchelleTerritorialeActive().contoursGeojson!,
pageCarte.getEchelleTerritorialeActive().maxZoom,
pageCarte.getIndicateurActif().libelle,
......
import { getApiBaseUrl } from '../../commun/base';
import { Afficheur } from '../../commun/controleurs/Afficheur';
import { Indicateur } from '../../commun/domaines/Indicateur';
import { chargerContoursTerritoires, chargerIndicateurs } from '../../commun/requetes-api/requetes-api-carte';
import {
chargerContoursTerritoires, chargerCoucheHotelsDepartements, chargerCoucheHotelsRegions, chargerIndicateurs
} from '../../commun/requetes-api/requetes-api-carte';
import { chargerHierarchieTerritoires } from '../../commun/requetes-api/requetes-api-territoires';
import { EchelleTerritoriale } from '../domaines/EchelleTerritoriale';
import { PageCarte } from '../domaines/PageCarte';
import { getApiBaseUrl } from '../../commun/config';
export class ControleurCarte {
private afficheur?: Afficheur<PageCarte>;
......@@ -19,6 +21,11 @@ export class ControleurCarte {
}
async initialiserAffichage(idTerritoire?: string, idEchelleTerritoriale?: string, idIndicateur?: string) {
await chargerCoucheHotelsDepartements().then((coucheHotelsDepartements) => {
chargerCoucheHotelsRegions().then((coucheHotelsRegions) => {
this.pageCarte.setCouchesVilles(coucheHotelsDepartements, coucheHotelsRegions);
});
});
this.pageCarte.setParametresDiagnosticInitial(idTerritoire, idEchelleTerritoriale);
let echelleTerritoriale = EchelleTerritoriale.fromId(idEchelleTerritoriale!);
let hierarchieTerritoires;
......
import { Indicateur } from '../../commun/domaines/Indicateur';
import { HierarchieTerritoires } from '../../diagnostic/domaines';
import { EchelleTerritoriale } from './EchelleTerritoriale';
import { GeoJsonObject } from 'geojson';
export enum EtatCarte {
PRET,
......@@ -12,10 +13,17 @@ export interface DonneesFeatureGeoJson {
nom_territoire: string;
}
export interface CouchesVilles {
coucheHotelsDepartements: GeoJsonObject;
coucheHotelsRegions: GeoJsonObject;
}
export class PageCarte {
private etat = EtatCarte.PRET;
private erreur: any | null = null;
private coucheHotelsDepartements?: GeoJsonObject;
private coucheHotelsRegions?: GeoJsonObject;
private idTerritoireDiagnosticInitial?: string;
private idEchelleTerritorialeDiagnosticInitial?: string;
private idTerritoireZoom?: string;
......@@ -48,6 +56,18 @@ export class PageCarte {
this.erreur = erreur;
}
setCouchesVilles(coucheHotelsDepartements: GeoJsonObject, coucheHotelsRegions: GeoJsonObject) {
this.coucheHotelsDepartements = coucheHotelsDepartements;
this.coucheHotelsRegions = coucheHotelsRegions;
}
getCouchesVilles(): CouchesVilles {
return {
coucheHotelsDepartements: this.coucheHotelsDepartements!,
coucheHotelsRegions: this.coucheHotelsRegions!
};
}
majEchelleTerritorialeActive(echelleTerritoriale: EchelleTerritoriale): void {
this.echelleTerritorialeActive = echelleTerritoriale;
}
......
import L, { FeatureGroup, GeoJSON, GeoJSONOptions, LatLng, LatLngBounds, Layer, LeafletMouseEvent, Map, PathOptions } from 'leaflet';
import L, { FeatureGroup, GeoJSON, GeoJSONOptions, LatLng, LatLngBounds, Layer, LayerGroup, LeafletMouseEvent, Map, PathOptions } from 'leaflet';
import 'leaflet/dist/leaflet.css';
import * as geojson from 'geojson';
import { calculerCouleurNoteSelonGradient, calculerCouleurValeurSelonGradient, JaugeNoteSur10 } from '../../commun/vues';
import { IndicateurSynthese } from '../../diagnostic/domaines/rapports';
import { DonneesFeatureGeoJson } from '../domaines/PageCarte';
import { CouchesVilles, DonneesFeatureGeoJson } from '../domaines/PageCarte';
import { arrondirANDecimales } from '../../commun/base';
import { StyleIndicateur, ValeursIndicateurs } from '../../commun/domaines/Indicateur';
......@@ -62,6 +62,7 @@ export class CarteColoree {
// Déclaration des fonctions publiques
//////////////////////////////////////
afficher(
couchesVilles: CouchesVilles,
contoursGeojson: geojson.GeoJsonObject,
maxZoom: number,
nomIndicateur: string,
......@@ -70,10 +71,12 @@ export class CarteColoree {
texteTitre?: string,
idTerritoirePourZoom?: string
) {
this.ajouterCouchesVilles(couchesVilles);
this.nomIndicateur = nomIndicateur;
this.valeursIndicateurs = valeursIndicateurs;
this.styleIndicateur = styleIndicateur || StyleIndicateur.GRADIENT_ROUGE_ORANGE_VERT_0_A_10;
this.majCoucheContoursTerritoire(contoursGeojson, maxZoom);
this.majCoucheContoursTerritoire(contoursGeojson);
this.carteLeaflet.setMaxZoom(maxZoom);
this.majLegende();
this.majTitre(texteTitre);