diff --git a/data/test.db b/data/test.db index 2f2f142d93f55b5661c089395d795c6bd40d1d10..c72faf72e932c1aa982825c4d8c93b11503077dc 100644 Binary files a/data/test.db and b/data/test.db differ diff --git a/web/components/help/help.js b/web/components/help/help.js new file mode 100644 index 0000000000000000000000000000000000000000..96c11126f3e7f4efda4ed202056189cf929fe841 --- /dev/null +++ b/web/components/help/help.js @@ -0,0 +1,112 @@ +// Imports +import * as Results from "/components/help/results-help.js"; +import * as Vote from "/components/help/vote-help.js"; +import * as Management from "/components/help/management-help.js"; +import * as User from "/components/help/user-help.js"; + +// DOM elements + +export async function mount(where) { + const helperPage = new Helper(); + await helperPage.mount(where); +} + +class Helper { + constructor() {} + + async mount(where) { + const mountpoint = where; + document.getElementById(mountpoint).innerHTML = /* HTML */ ` + <div class="tabs is-boxed is-toggle is-fullwidth"> + <ul> + <li id="results-helper" class="is-active"> + <a> + <span class="icon is-small" + ><i class="fas fa-poll" aria-hidden="true"></i + ></span> + <span>Résultats</span> + </a> + </li> + <li id="votes-helper"> + <a> + <span class="icon is-small" + ><i class="fas fa-vote-yea" aria-hidden="true"></i + ></span> + <span>Votes</span> + </a> + </li> + <li id="management-helper"> + <a> + <span class="icon is-small" + ><i class="fas fas fa-edit" aria-hidden="true"></i + ></span> + <span>Gestion</span> + </a> + </li> + <li id="user-helper"> + <a> + <span class="icon is-small" + ><i class="fas fas fa-users" aria-hidden="true"></i + ></span> + <span>Utilisateurs</span> + </a> + </li> + </ul> + </div> + <section id="help-section" class="container" style="margin-bottom: 230px;"></section> + `; + + this.handleDOM(); + await Results.mount("help-section"); + + } + handleDOM() { + document + .getElementById("results-helper") + .addEventListener("click", async function () { + await Results.mount("help-section"); + document.getElementById("votes-helper").setAttribute("class", ""); + document.getElementById("management-helper").setAttribute("class", ""); + document.getElementById("user-helper").setAttribute("class", ""); + document + .getElementById("results-helper") + .setAttribute("class", "is-active"); + }); + + document + .getElementById("votes-helper") + .addEventListener("click", async function () { + await Vote.mount("help-section"); + document.getElementById("results-helper").setAttribute("class", ""); + document.getElementById("management-helper").setAttribute("class", ""); + document.getElementById("user-helper").setAttribute("class", ""); + document + .getElementById("votes-helper") + .setAttribute("class", "is-active"); + }); + + document + .getElementById("management-helper") + .addEventListener("click", async function () { + await Management.mount("help-section"); + document.getElementById("results-helper").setAttribute("class", ""); + document.getElementById("votes-helper").setAttribute("class", ""); + document.getElementById("user-helper").setAttribute("class", ""); + document + .getElementById("management-helper") + .setAttribute("class", "is-active"); + }); + + document + .getElementById("user-helper") + .addEventListener("click", async function () { + await User.mount("help-section"); + document.getElementById("results-helper").setAttribute("class", ""); + document.getElementById("votes-helper").setAttribute("class", ""); + document.getElementById("management-helper").setAttribute("class", ""); + document + .getElementById("user-helper") + .setAttribute("class", "is-active"); + }); + } +} diff --git a/web/components/help/management-help.js b/web/components/help/management-help.js new file mode 100644 index 0000000000000000000000000000000000000000..22cdcd764bb2e2be95d7141d3f0655330649292a --- /dev/null +++ b/web/components/help/management-help.js @@ -0,0 +1,188 @@ +export async function mount(where) { + const managementHelperComponent = new ManagementHelper(); + await managementHelperComponent.mount(where); +} + +class ManagementHelper { + constructor() {} + + async mount(where) { + const mountpoint = where; + document.getElementById(mountpoint).innerHTML = /* HTML */ ` + <div class="card-no-hover helper"> + <h2 class="title is-2">Aide pour la gestion d'une élection</h2> + + <h5 class="title is-5">Onglet Partis politiques</h5> + + L'onglet "Partis Politiques" permet de créer des tendances poltiques qui + se retrouvent sur plusieurs circonscriptions.<br /> + Pour ajuter un parti il suffit de cliquer sur + <span class="icon is-small"> + <i class="fas fa-plus"></i> + </span> + Un fenêtre s'ouvre et permet de saisir le nom du parti (ou de la + tendance politique) et de choisir la couleur qui sera associé à ce parti + dans l'affichage des résultats. Pour modifier un parti, il suffit de + cliquer sur + <span class="icon is-small"> + <i class="fas fa-pen"></i> + </span> + et pour en supprimer un sur + <span class="icon is-small"> <i class="fas fa-times"></i> </span>. La + suppression affichera l'ensemble des listes qui sont rattachées à ce + parti sur toutes les élections et demandera de confirmer l'action de + suppression car toutes ces listes seront alors supprimées.<br /><br /> + + <h5 class="title is-5">Onglet Élection</h5> + L'onglet élection permet de créer le découpage territorial d'une + élection. Il est possible de naviguer dans l'abrorescence de l'élection + en cliquant sur les différentes zones la composant<br /><br /> + + <article class="message is-warning"> + <div class="message-header"> + <p>Attention</p> + </div> + <div class="message-body"> + Il est necessaire pour que l'application fonctionne corrctement que + chaque élection ai au moins une circonscription composée elle même + d'au moins une ville avec au minimum un bureau. + </div> + </article> + + <strong>Élection</strong> + Pour créer une nouvelle élection cliquer sur + <span class="icon is-small"> <i class="fas fa-plus"></i> </span>, une + fenêtre s'ouvre alors, il faut saisir le nom de cette élection, choisir + le système de vote qui sera appliqué (pour calculer les résultats), + selectionner la carte pour les cirocnscriptions et celle pour les + villes. En cliquant sur "Sauvegarder" l'élection sera ajoutée et en + cliquant sur "Sauvegarder (ajouter circonscription)" elle sera + sauvegardée et la fenêtre pour y attacher une circonscription sera + ouverte.<br /><br /> + + <strong>Circonscription</strong> + Une circonscription peut être ajoutée à l'élection selectionnée en + cliquant sur + <span class="icon is-small"><i class="fas fa-plus"></i></span> . Il faut + alors saisir son nom, le nombre de siège à pourvoir et l'identifiant qui + lui correspond sur la carte des circonscriptions. <br />En cliquant sur + "Sauvegarder" la circonscription sera ajoutée et en cliquant sur + "Sauvegarder (ajouter circonscription)" elle sera ajoutée et la fenêtre + pour ajouter une nouvelle circonscription à l'élection sera ouverte. En + cliquant sur "Sauvegarder (ajouter ville)" elle sera ajoutée et la + fenêtre pour ajouter une ville à la circonscription sera ouverte.<br /><br /> + + <strong>Ville</strong> + Une ville peut être ajoutée à une circonscription selectionnée en + cliquant sur + <span class="icon is-small"><i class="fas fa-plus"></i></span> . Il faut + alors saisir son nom et l'identifiant qui lui correspond sur la carte + des villes. <br />En cliquant sur "Sauvegarder" la ville sera ajoutée et + en cliquant sur "Sauvegarder (ajouter ville)" elle sera ajoutée et la + fenêtre pour ajouter une nouvelle ville à la circonscription sera + ouverte. En cliquant sur "Sauvegarder (ajouter bureau)" elle sera + ajoutée et la fenêtre pour ajouter un bureau à la ville sera ouverte.<br /><br /> + + <strong>Bureau</strong> + Un bureau peut être ajoutée à une ville selectionnée en cliquant sur + <span class="icon is-small"><i class="fas fa-plus"></i></span> . Il faut + alors saisir son nom et le nombre d'inscrit dans ce bureau. + <article class="message is-warning"> + <div class="message-header"> + <p>Attention</p> + <button class="delete" aria-label="delete"></button> + </div> + <div class="message-body"> + Le nombre d'inscrit est obligatoire car il permet de calculer le + taux d'abstention et le pourcentage de saisie en cours qui est + pondéré par le nombre d'inscrits par bureau. + </div> + </article> + En cliquant sur "Sauvegarder" le bureau sera ajouté et en cliquant sur + "Sauvegarder (ajouter bureau)" il sera ajouté et la fenêtre pour ajouter + un nouveau bureau à la ville sera ouverte.<br /><br /> + + <strong>Cloner une élection</strong> + Il est possible de cloner une élection et son arborescence en cliquant + sur + <span class="icon is-small"> + <i class="fas fa-clone"></i> + </span> + dans la liste des élections.<br /><br /> + + <h5 class="title is-5">Onglet Tour</h5> + Une élection est composée de un ou plusieurs tours, il faut donc + configuré ces tours pour utiliser l'application.<br /><br /> + + Dans l'onglet "Tour" il est possible de créer un tour pour une élection + en cliquant sur + <span class="icon is-small"><i class="fas fa-plus"></i></span>. Il faut + alors sélectionner l'élection à laquelle on crée un tour, la date du + tour et le numéro du tour. Il est possible de modifier les informations + en cliquant sur + <span class="icon is-small"><i class="fas fa-pen"></i></span> et de le + supprimer en cliquant sur + <span class="icon is-small"><i class="fas fa-times"></i></span + ><br /><br /> + + En cliquant sur un tour, on rentre dans la configuration du tour. La + bouton sur la gauche permet de revenir à l'écran précédent. Il y a deux + sections qui peuvent être ouvertes l'une après l'autre, il faut cliquer + sur la barre de titre de l'une des deux sections pour en changer.<br /><br /> + + <strong>Section "Bureaux de Votes"</strong><br /> + La liste de tous les bureaux de votes de l'éelection s'affiche ici. En + cliquant sur un bureau les détails de ce bureau s'affiche. Il est + possible de consulter les votes et de les modifier comme dans l'onglet + "Votes". Il est possible de "Valider" un bureau, les votes de ce bureau + ne pourront alors plus être modifié.<br /><br /> + + Pour ajouter un utilisateur à la liste des saisseurs, cliquer sur + l'icône + <span class="icon is-small"> + <i class="fas fa-user"></i> + </span> + pour ouvrir la liste des saisisseurs de ce burea, il suffit ensuite de + cliquer sur l'utilisateur dans la colonne de droite "Saisisseurs + disponibles", il va alors basculer dans la colonne de gauche + "Saisisseurs actifs". Pour le supprimer il suffit de faire de même dans + la colonne de gauche "Saisisseurs actifs", il va alors basculer dans la + colonne de droite "Saisisseurs disponibles".<br /><br /> + + <strong>Section "Liste des candidats par circonscription"</strong> + La liste des circonscription du tour est affichée, en cliquant sur une + circonscription, la liste des listes de candidats de la circonscription + s'affiche. Il est possible d'en créer une en cliquant sur + <span class="icon is-small"> <i class="fas fa-plus"></i>. </span>Une + fenêtre s'ouvre alors pour saisir le nom de la liste et le parti auquel + elle est attachée. En cliquant sur + <span class="icon is-small"> + <i class="fas fa-download"></i> + </span> + Une fenêtre s'ouvre et permet d'importer une liste directement depuis un + tour précédent pour éviter de resaisir toutes les informations de la + listes.<br /><br /> + + En cliquant sur une liste, les canddiats s'affichent, il est possible + d'ajouter et de modifier des candidats en éditant les champs dans le + tableau et en cliquant sur + <span class="icon is-small"> + <i class="fas fa-check"></i> + </span> + pour chaque ligne éditée afin qu'elles soient prises en compte.<br /> + Le rang ordonne les candidats lors du calcul des élus, la date de + naissance permet de départager des listes et des candidats lors du + calcul des élus en cas d'égalité, la case incompatibilité potentielle + permet d'identifier les élus qui pourraient poser problème s'ils sont + élus (autre mandat en cours, fonctionnaire...). La case refusé permet + d'éliminer du calcul des élus des candidats qui se sont porter sur une + liste mais qui finalement ne souhaient pas siéger. La case supprimer + permet d'éliminer du calcul des élus les candidats qui seraient décédé + entre la date de cloture de dépôt des listes et l'élection. (La case + "Conseiller communautaire" n'est pas fonctionelle mais permettrai + d'identifier les élus qui vont siéger au conseil communautaire lors + d'élection municipale) + </div> + `; + } +} diff --git a/web/components/help/results-help.js b/web/components/help/results-help.js new file mode 100644 index 0000000000000000000000000000000000000000..17a1ac389188aed456d2304166bb5ea9f69b177c --- /dev/null +++ b/web/components/help/results-help.js @@ -0,0 +1,65 @@ +export async function mount(where) { + const resultsHelperComponent = new ResultsHelper(); + await resultsHelperComponent.mount(where); +} + +class ResultsHelper { + constructor() {} + + async mount(where) { + const mountpoint = where; + document.getElementById(mountpoint).innerHTML = /* HTML */ ` + <div class="card-no-hover helper"> + <h2 class="title is-2">Aide pour les résultats</h2> + + Le menu "Résultats" permet de voir les résultats d'un tour d'une + élection. Il faut donc sélectionner le tour de l'élection que l'on + souhaite consulter.<br /> + + Il est possible de filtrer les résultats pour ne prendre en compte que + les zones qui sont complétées, que celles qui ont étaient validée avec + les résultats de la préfecture ou alors en prenant en compte les zones + avec des résultats partiels.<br /><br /> + + <h5 class="title is-5">Onglet Général</h5> + + L'onglet général permet de voir les résultats pour l'ensemble du + tour.<br /> + À venir : la partie statistiques permet de comparer les résultats avec + d'autres élections afin de suivre la tendande dans le temps.<br /><br /> + + <h5 class="title is-5">Onglet circonscriptions ou villes</h5> + Les onglets "Circonscription" et "Villes" fonctionnent de la même façon + mais avec le zonage appropié.<br /> + + L'écran est découpé en trois composants : la carte (à gauche), le flux + d'actualité (en haut à droite) et les résultats détaillés (en bas à + droite).<br />Chaque zone peut être aggrandie en appuyant sur + <span class="icon is-small"> + <i class="fa fa-expand-arrows-alt"></i> </span + >. Pour diminuer la taille de la zone et revenir à l'état initial il + suffit de cliquer sur + <span class="icon is-small"> + <i class="fa fa-compress-arrows-alt"></i> </span + ><br /><br /> + Le flux d'actualité défile de manière automatique, il est possible de + désactiver ce défilement en décochant la case "Défilement automatique". + Lorsque la souris se trouve au dessus de la zone du flux, le défilement + s'arrête. Il est possible d'ouvrir les résultats détaillés d'une zone en + cliquant dessus dans le flux, les détails s'affichent alors dans la + partie "Résultats détaillés" <br /><br /> + La partie résultat détaillés permet de voir les résultats d'une zone en + particulier en selectionnant la circonscription (et la ville dans l'onglet "Villes"). En cliquant sur + <span class="icon is-small"> + <i class="fa fa-expand-arrows-alt"></i> + </span> + il est possible de voir des statistiques sur la zone comme + l'abstention, le nombre de votes blanc et nuls. Avec le filtre "partiel" + le pourcentage de saisie de la zone s'affiche également afin de savoir + si les résultats donnés sont proche d'être complets ou non.<br /> + Dans l'onglet "Circonscription" lorsque les résultats d'une + circonscription sont tous saisis la liste des élus s'affiche. + </div> + `; + } +} diff --git a/web/components/help/user-help.js b/web/components/help/user-help.js new file mode 100644 index 0000000000000000000000000000000000000000..7ee8b461209574789bfdb19c9cedc011e27f09fb --- /dev/null +++ b/web/components/help/user-help.js @@ -0,0 +1,63 @@ +export async function mount(where) { + const userHelperComponent = new UserHelper(); + await userHelperComponent.mount(where); +} + +class UserHelper { + constructor() {} + + async mount(where) { + const mountpoint = where; + document.getElementById(mountpoint).innerHTML = /* HTML */ ` + <div class="card-no-hover helper"> + <h2 class="title is-2">Aide pour la gestion des utilisateurs</h2> + + Les utilisateurs peuvent soient provenir de la base locale de + l'application soit être provisionnés par un fournisseur d'identité. La + différence se fait sur la présence du champ IdOAuth qui n'est renseigné + que pour les utilisateurs provisonnés depuis le fournisseur d'identité + raccordé à l'application.<br /><br /> + + <h5 class="title is-5">Ajout d'un utilisateur</h5> + + Pour ajouter un utilisateur il faut cliquer sur le bouton + <span class="icon is-small"> + <i class="fas fa-plus"></i> + </span> + en dessous du tabeau avec la liste des utilisateurs. Il faut au minimum + renseigner un identifiant et un rôle pour l'utilisateur. Le mot de + passe, qui est également obligatoire, est généré de manière aléatoire et + peut être modifié. <br /><br /> + + <h5 class="title is-5">Modification d'un utilisateur</h5> + + Pour modifier un utilisateur il faut cliquer sur le bouton "modifier" + dans la colonne action des utilisateurs. La même modale que pour la + création s'ouvre. Enlever le rôle de saisisseur à un utilisateur + enlèvera toutes ses affectations sur les bureaux qui seront + définitivement perdus.<br /> + + Lors de la modification d'un utilisateur le champ mot de passe est vide, + s'il est laissé vide le mot de passe ne sera pas modifié, autrement il + sera modifié par la valeur du champ.<br /><br /> + + <h5 class="title is-5">Affectation des saisisseurs sur les bureaux</h5> + + Pour affecter des utilisateurs à un bureau il faut se rendre dans le + menu "Gestion" puis dans l'onglet "Tour", sélectionner un tour, puis + dans la liste des bureaux de votes cliquer sur l'icône + <span class="icon is-small"> + <i class="fas fa-user"></i> + </span> + pour ouvrir la liste des saisisseurs de ce bureau.<br /> + + Pour ajouter un utilisateur à la liste des saisseurs il suffit de + cliquer sur l'utilisateur dans la colonne de droite "Saisisseurs + disponibles", il va alors basculer dans la colonne de gauche + "Saisisseurs actifs". Pour le supprimer il suffit de faire de même dans + la colonne de gauche "Saisisseurs actifs", il va alors basculer dans la + colonne de droite "Saisisseurs disponibles". + </div> + `; + } +} diff --git a/web/components/help/vote-help.js b/web/components/help/vote-help.js new file mode 100644 index 0000000000000000000000000000000000000000..756f6f9632238ccd077ff96a770eb2e0d24d20c5 --- /dev/null +++ b/web/components/help/vote-help.js @@ -0,0 +1,46 @@ +export async function mount(where) { + const voteHelperComponent = new VoteHelper(); + await voteHelperComponent.mount(where); +} + +class VoteHelper { + constructor() {} + + async mount(where) { + const mountpoint = where; + document.getElementById(mountpoint).innerHTML = /* HTML */ ` + <div class="card-no-hover helper"> + <h2 class="title is-2">Aide pour la saisie des votes</h2> + <h5 class="title is-5">Sélection d'un bureau</h5> + Lors de l'ouverture du menu "Votes", il est necessaire de choisir le + bureau de vote qui sera saisi. Il faut commencer par choisir une + élection puis un tour par exemple "Métropolitaine 2020") et tour 1 pour + saisir les résultats du premier tour des élections métropolitaines + 2020.<br /> + À partir de ce moment tous les bureaux du premier tour des élections + métropolitaines 2020 apparaissent dans la partie droite de l'écran. Il + est possible de filtrer plus en profondeur les bureaux en sélectionnant + une Circonscription puis une Ville.<br /> + Il faut ensuite cliquer sur un des bureaux de la liste pour saisir les + résultats de ce bureau. <br /><br /> + <h5 class="title is-5">Saisie des votes</h5> + Il est possible de vérifier que l'on saisi les résultats pour le bon + bureau en vérifiant en haut de la page le fil d'ariane qui indique le + bureau selectionné dans son arborescence.<br /> + Chaque ligne du tableau correspond à une liste de la circonscription, + les deux dernières lignes correspondent aux votes blanc et nuls. Il faut + alors sasir le nombre de voix dans chaque ligne du tableau.<br /> + En bas du tableau, la somme des suffrages et la somme des suffrages + exprimées (sans les votes blanc et nuls) permet de vérifier la saisie en + accord avec le PV de vote après sauvegarde des résultats. <br /> + Pour sauvegarder les résultats il faut cliquer sur le bouton "Sauvegarder".<br /> + Le bouton "Supprimer" permet de supprimer les résultats saisis pour ce + bureau.<br /> + Le bouton "Annuler" permet d'annuler les modifications apportées mais + qui n'ont pas était sauvegardées et revient donc à l'état initial.<br /> + Le bouton "Retour" permet de revenir à la page de sélection des + bureaux.<br /> + </div> + `; + } +} diff --git a/web/components/home/home.js b/web/components/home/home.js deleted file mode 100644 index 7c041869da630a4918f62d3bd66a79aaf8ca1326..0000000000000000000000000000000000000000 --- a/web/components/home/home.js +++ /dev/null @@ -1,20 +0,0 @@ -// Imports - -// DOM elements -let mountpoint; - -// local variables - -export async function mount(where) { - mountpoint = where; - document.getElementById(mountpoint).innerHTML = /* HTML */ ` - <section class="section"> - <div class="container"> - <h1 class="title">Accueil</h1> - <h2 class="subtitle"> - Cette application permet de gérer, saisir et voir les résultats d'une élection. - </h2> - </div> - </section> - `; -} diff --git a/web/components/management/candidate-lists.js b/web/components/management/candidate-lists.js index 1f77a2d017f95e3b62da0273307cd312cbdcfb1d..2cc80e686be4036e273118a55340436677b87566 100644 --- a/web/components/management/candidate-lists.js +++ b/web/components/management/candidate-lists.js @@ -176,7 +176,7 @@ class CandidateList { <div class="control select"> <select name="party" - id="candclone-cardidateList-modal-party" + id="candidateList-modal-party" ></select> </div> </div> diff --git a/web/components/navbar/navbar.js b/web/components/navbar/navbar.js index f0e19ae61e6fada509b29abd512710fd2a471384..991b6cb46b8f5c72cf064c2c87f5102835c7f4b9 100644 --- a/web/components/navbar/navbar.js +++ b/web/components/navbar/navbar.js @@ -59,9 +59,6 @@ export async function CreateMenu() { user === undefined ? `` : /* HTML */ ` - <a class="navbar-item" href="#home" - ><i class="navbar-menu-icon fas fa-home"></i>Accueil</a - > <a class="navbar-item" href="#visualization" ><i class="navbar-menu-icon fas fa-poll"></i>Résultats</a > @@ -85,6 +82,9 @@ export async function CreateMenu() { > ` : ""} + <a class="navbar-item" href="#help" + ><i class="navbar-menu-icon fas fa-question-circle"></i>Aide</a + > ` } </div> diff --git a/web/components/visualization/results-zone.js b/web/components/visualization/results-zone.js index d52f471e264b1ebf128de175a7e003a185f3ab26..1279afa9e4961b60c529449e8d260a742c8eaf76 100644 --- a/web/components/visualization/results-zone.js +++ b/web/components/visualization/results-zone.js @@ -68,7 +68,7 @@ class ResultZoneComponent { <div id="results-section" class="card-no-hover" "> <header class="card-header"> <p class="card-header-title"> - Résultats + Résultats détaillés </p> <button id="zoom-results" class="button is-success"> <span class="icon is-small"> diff --git a/web/main.js b/web/main.js index 6cb579d0c7caced44ac2db8293fd566359a35d21..1ad9ed94e0736fa302bea4476f0ed1756f86558a 100644 --- a/web/main.js +++ b/web/main.js @@ -1,10 +1,10 @@ -import * as Home from "/components/home/home.js"; import * as Users from "/components/users/users.js"; import * as Management from "/components/management/management.js"; import * as Votes from "/components/vote/vote-page.js"; import * as Visualization from "/components/visualization/visualization-page.js"; import * as Login from "/components/login/login.js"; import * as Navbar from "/components/navbar/navbar.js"; +import * as Helper from "/components/help/help.js"; import { AnimateCSS } from "/services/common/common.js"; const mountPoint = document.getElementById("main"); @@ -19,11 +19,6 @@ document.addEventListener("DOMContentLoaded", function () { async function navigate() { window.clearInterval(window.intervalRefreshResults); switch (location.hash) { - case "#home": - load(mountPoint, async function () { - await Home.mount("main"); - }); - break; case "#votes": load(mountPoint, async function () { await Votes.mount("main"); @@ -49,8 +44,13 @@ async function navigate() { await Login.mount("main"); }); break; + case "#help": + load(mountPoint, async function () { + await Helper.mount("main"); + }); + break; default: - location.hash = "#home"; + location.hash = "#visualization"; break; } } diff --git a/web/style.css b/web/style.css index 59436c858ad37d61d49264048886b506543862be..56fdee475f424520ebf2464be7bd5878bc89376b 100644 --- a/web/style.css +++ b/web/style.css @@ -227,3 +227,8 @@ select { #map-component { height: 100%; } + +.helper { + text-align: justify; + padding: 2em; +}