Revoir l'ergonomie des panneaux et de la colonne des projets

Les panneaux d'édition étaient modaux et la colonne de gauche tronquait
tout ce qu'elle portait. Sept corrections, mesurées sur data/exemple.json.

Panneaux
- Le voile qui recouvrait la page disparaît : la frise reste manipulable
  pendant l'édition, et cliquer une autre barre y bascule la sélection.
  Il rendait aussi le raccourci flèches inatteignable, le focus partant
  dans le champ « Nom » sans qu'on puisse cliquer ailleurs pour en sortir.
- Un clic dans une zone inerte referme le panneau : ce que rendait le
  voile, sans le calque qui figeait la frise.
- Les paramètres d'un projet quittent le <dialog> modal pour le même
  panneau qu'une phase, avec la même édition au fil de la saisie.
  « Nouveau projet » crée donc le projet aussitôt, comme le fait déjà
  l'ajout d'une phase : plus aucune création ne passe par un formulaire.

Colonne des projets
- Le nom ne disposait que de 56 px sur 250, et « client » s'affichait
  « c. ». Les commandes passent en surimpression au survol, les tags
  cèdent en bloc derrière un compteur, et le nom cède en dernier.
- La colonne se redimensionne, largeur conservée dans localStorage.
- L'œil disparaît : il faisait doublon avec l'entrée « Masquer » du menu.
  Un « + » le remplace, l'ajout d'une phase étant l'action la plus
  fréquente, et le nom du projet devient cliquable — il portait déjà un
  curseur « main » sans aucune action derrière.
- Plus de commande « Ajouter un jalon » : un jalon est une phase dont on
  coche la case, pas un autre objet.

Frise
- Le nom d'une phase reste accroché au bord visible quand sa barre
  s'enfonce sous la colonne.
- Cliquer un nom de phase hors écran ramène la frise sur elle.
- La barre cumulative d'un projet s'affiche aussi quand il est déplié,
  amincie pour ne pas se faire passer pour une barre de phase.

Arbitrages consignés dans docs/decisions.md, sections 8 et 17 à 21.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-01 10:42:35 +02:00
parent a2a5c5cb9c
commit eaca2f7813
9 changed files with 1032 additions and 333 deletions

View File

@@ -42,7 +42,21 @@
-->
<main class="frise" id="frise">
<div class="grille">
<div class="grille__coin"></div>
<div class="grille__coin">
<!--
Poignée de largeur de la colonne. Placée dans le coin, seul endroit
de la colonne qui reste visible quel que soit le défilement.
-->
<div
class="poignee-colonne"
id="poignee-colonne"
role="separator"
aria-orientation="vertical"
aria-label="Largeur de la colonne des projets"
tabindex="0"
title="Glisser pour élargir la colonne — double-clic pour la réinitialiser"
></div>
</div>
<div class="grille__entete" id="entete"></div>
<div class="grille__libelles" id="libelles"></div>
<div class="grille__couloirs" id="couloirs"></div>
@@ -61,8 +75,14 @@
<button type="button" id="effacer-filtres-vide">Tout afficher</button>
</p>
<!-- Panneau de détail, ouvert au clic sur une phase. -->
<aside class="panneau" id="panneau" hidden aria-label="Détail de la phase">
<!--
Panneau de détail, ouvert au clic sur une phase. Volontairement **non
modal** : la frise reste vivante derrière lui, on passe d'une phase à
l'autre en cliquant sa barre. `tabindex="-1"` permet d'y poser le focus à
l'ouverture sans le placer dans un champ de saisie, ce qui laisse les
flèches piloter la phase sélectionnée.
-->
<aside class="panneau" id="panneau" hidden tabindex="-1" aria-label="Détail de la phase">
<div class="panneau__entete">
<h2 id="panneau-titre">Phase</h2>
<button type="button" id="fermer-panneau" aria-label="Fermer">&times;</button>
@@ -112,58 +132,57 @@
</form>
</aside>
<div class="voile" id="voile" hidden></div>
<!-- Menu contextuel, positionné à l'ouverture près de son point d'ancrage. -->
<div class="menu" id="menu" hidden role="menu"></div>
<!-- Création et renommage d'un projet. -->
<dialog class="dialogue" id="dialogue-projet">
<form method="dialog">
<h2 id="dialogue-projet-titre">Nouveau projet</h2>
<!--
Paramètres d'un projet. Même panneau, mêmes gestes et même édition en
direct que le détail d'une phase : renommer un projet et renommer une
phase sont la même opération à un niveau près, elles n'ont pas à se
présenter différemment.
-->
<aside
class="panneau"
id="panneau-projet"
hidden
tabindex="-1"
aria-label="Paramètres du projet"
>
<div class="panneau__entete">
<h2 id="panneau-projet-titre">Projet</h2>
<button type="button" id="fermer-panneau-projet" aria-label="Fermer">&times;</button>
</div>
<form class="panneau__corps" id="formulaire-projet">
<label>
Nom
<input type="text" id="dialogue-projet-nom" required autocomplete="off" />
<input type="text" name="name" required autocomplete="off" />
</label>
<fieldset class="couleurs">
<legend>Couleur du couloir</legend>
<div id="dialogue-projet-couleurs"></div>
<div id="panneau-projet-couleurs"></div>
</fieldset>
<label>
Tags, séparés par des virgules
<input
type="text"
id="dialogue-projet-tags"
autocomplete="off"
placeholder="client, refonte"
/>
<input type="text" name="tags" autocomplete="off" placeholder="client, refonte" />
</label>
<!-- Masqué tant qu'aucun tag n'existe ailleurs dans le planning. -->
<fieldset class="couleurs" id="dialogue-projet-suggestions-bloc" hidden>
<fieldset class="couleurs" id="panneau-projet-suggestions-bloc" hidden>
<legend>Tags déjà utilisés</legend>
<div class="tags tags--suggestions" id="dialogue-projet-suggestions"></div>
<div class="tags tags--suggestions" id="panneau-projet-suggestions"></div>
</fieldset>
<p class="dialogue__erreur" id="dialogue-projet-erreur" role="alert" hidden></p>
<p class="panneau__erreur" id="erreur-projet" role="alert" hidden></p>
<menu class="dialogue__actions">
<!--
`formnovalidate` est indispensable : le champ « Nom » est `required`,
et sans lui la validation HTML refuserait la soumission — donc la
fermeture du dialogue — tant qu'aucun nom n'est saisi. On se
retrouverait incapable d'annuler une création de projet.
-->
<button type="submit" value="annuler" formnovalidate>Annuler</button>
<button type="submit" value="ok" class="bouton--principal" id="dialogue-projet-ok">
Créer
<div class="panneau__actions">
<button type="button" id="supprimer-projet" class="bouton--danger">
Supprimer le projet
</button>
</menu>
</div>
</form>
</dialog>
</aside>
<!-- Confirmation d'une action irréversible. -->
<dialog class="dialogue" id="dialogue-confirmation">