Files
gestion_projets/README.md
Bertrand Benjamin eaca2f7813 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>
2026-08-01 10:58:47 +02:00

173 lines
8.5 KiB
Markdown

# Frise multi-projets
Un outil de **planification macro** : voir sur une seule frise chronologique où en est chaque
projet, quelles sont ses grandes phases, et comment les projets se situent les uns par rapport aux
autres.
Ce n'est **pas** un outil de suivi quotidien : pas de sous-tâches, pas de tickets, pas de
checklists. Une phase représente plusieurs semaines ou plusieurs mois de travail.
## Démarrer
```sh
python3 serve.py
```
Puis ouvrir <http://localhost:8000>. Aucune installation, aucune dépendance, aucune étape de
compilation — ni côté Python (bibliothèque standard uniquement) ni côté navigateur (JavaScript
vanilla en modules ES natifs).
Options :
```sh
python3 serve.py --port 9000 # changer le port
python3 serve.py --data data/exemple.json # ouvrir un autre fichier de données
```
Au premier lancement, le planning est vide. Pour découvrir l'outil sur des données
réalistes :
```sh
cp data/exemple.json data/projets.json
```
## Prise en main
**Nouveau projet** crée le projet aussitôt, sous un nom provisoire, et ouvre ses paramètres avec
ce nom présélectionné : on tape simplement par-dessus. Il n'y a aucun formulaire à valider — ni
ici, ni pour une phase. Tout s'applique au fil de la saisie, et un projet créé par erreur se
supprime depuis son propre panneau.
Dans la colonne de gauche, le **triangle** plie et déplie le couloir d'un projet, et un clic sur
son **nom** ouvre ses paramètres : nom, couleur, tags. Deux commandes apparaissent au survol de
la ligne, sur son bord droit :
- **`+`** ajoute une phase à la suite de la dernière, et ouvre son panneau de détail ;
- **`⋯`** ouvre le menu du projet : ajouter une phase, plier, masquer de la frise, renommer,
figer la référence, supprimer. Un clic droit sur le libellé ouvre le même menu.
Il n'y a pas de commande séparée pour créer un **jalon** : c'est une phase dont on coche la case
« Jalon » dans le panneau, ce qui ramène sa fin sur son début. La bascule joue dans les deux sens
à tout moment.
La colonne se **redimensionne** en glissant la ligne qui la sépare de la frise, en haut à
gauche : un double-clic revient à la largeur d'origine. Cette largeur est propre au navigateur,
elle n'est pas enregistrée dans le planning.
Une fois un projet en place :
| Geste | Effet |
|---|---|
| Glisser le corps d'une barre | Décale la phase, durée conservée |
| Glisser le bord d'une barre | Change la date de début ou de fin |
| Clic sur une barre ou son nom | Ouvre le panneau de détail |
| Clic sur une autre barre, panneau ouvert | Bascule le panneau sur cette phase |
| Clic sur un nom de phase hors écran | Ramène la frise sur elle |
| `←` `→` | Décale d'un jour la phase sélectionnée |
| `Maj` + `←` `→` | Allonge ou raccourcit d'un jour |
| `Échap` | Annule le glisser en cours, ou ferme le panneau |
| Clic dans une zone vide | Ferme le panneau ouvert |
| `Maj` + molette | Fait défiler la frise horizontalement |
| `↑` `↓` dans un menu | Parcourt les entrées |
Faire défiler jusqu'au bord droit élargit la frise vers le futur, et jusqu'au bord gauche
vers le passé. Le bouton **Aujourd'hui** ramène la vue sur la date du jour.
### Filtrer par tag
Un projet peut porter des **tags**`client`, `interne`, `R&D` —, saisis séparés par des virgules
dans le dialogue « Renommer, changer la couleur… ». Il n'y a pas de liste à tenir : les tags
existants sont proposés en un clic, et un tag disparaît dès que plus aucun projet ne le porte.
Ils s'affichent en petites pastilles colorées dans la colonne de gauche, et une barre de filtres
apparaît sous la barre d'outils dès qu'un tag existe. Cliquer un tag — dans la barre de filtres ou
directement sur la pastille d'un projet — restreint la frise à ceux qui le portent ; recliquer le
retire.
Cocher plusieurs tags **cumule les conditions** : `client` + `urgent` ne montre que les projets
portant les deux. Le filtre n'est pas enregistré, il ne vaut que pour la session en cours. Le bouton
**Tout afficher** le vide d'un coup.
Les barres s'accrochent au lundi pendant le glisser. Pour une date au jour près, passer
par les champs du panneau de détail.
## Ce que fait l'outil
- **Plusieurs projets**, chacun décomposé en **phases** ayant un nom, des dates de début et de fin,
un statut, des notes libres. Une phase peut être un **jalon** (une date unique, rendue en losange).
- **Une frise commune**, les projets empilés en couloirs, pour les comparer d'un coup d'œil.
- **Une barre cumulative par projet**, segmentée en teintes selon le statut de chaque phase : la
forme d'ensemble, toujours visible sur la ligne du projet. Elle ne se glisse pas.
- **Couloirs pliables** : déplié, chaque phase occupe sa ligne sous la barre cumulative ; plié, il
ne reste que celle-ci, en plus épais.
- **Manipulation directe** : glisser une barre pour la décaler, tirer ses bords pour changer sa
durée. Les barres s'accrochent au lundi ; pour une date exacte, on passe par le panneau de détail.
- **Planning de référence** : une fois le planning validé, on le fige. La frise affiche alors une
barre fantôme sous la barre réelle et la dérive en semaines — de quoi répondre à « ce projet a-t-il
glissé, et de combien ? ».
- **Un en-tête à trois niveaux** — année, mois, numéro de semaine ISO — qui donne le
repère temporel sans jamais descendre au jour : à cette échelle, la semaine suffit.
Il n'y a qu'une seule échelle, donc aucun réglage de zoom à comprendre.
- **Une frise sans fin** : elle s'élargit d'elle-même quand le défilement approche d'un
bord, ce qui permet d'aller planifier dans un futur qu'aucune phase n'occupe encore.
- **Des tags sur les projets**, et un filtre qui restreint la frise à ceux qui les portent tous.
- **Repère « aujourd'hui »** et masquage d'un projet.
## Ce que l'outil ne fait pas
Volontairement : pas de dépendances entre phases, pas de sous-tâches, pas de collaboration temps
réel, pas d'authentification, pas de gestion de charge par personne, pas de notifications.
Les durées se comptent en **jours calendaires** : ni week-ends ni jours fériés ne sont gérés. À
l'échelle de phases de plusieurs semaines, la distinction n'apporte rien.
Les raisons derrière ces choix sont détaillées dans [docs/decisions.md](docs/decisions.md).
## Où vivent les données
Tout tient dans un fichier JSON, `data/projets.json`, décrit dans
[docs/modele-donnees.md](docs/modele-donnees.md). Il est indenté et utilise des identifiants
parlants (`site-web`, `cadrage`) plutôt que des UUID : il reste éditable à la main et lisible dans un
diff git.
À chaque sauvegarde, le serveur copie la version précédente dans `data/backups/`, horodatée.
Le planning n'est **pas versionné** : `.gitignore` exclut `data/projets.json`, ce dépôt ne contenant
que le code. Seul `data/exemple.json` y figure, comme jeu de démonstration.
**Pour synchroniser plusieurs machines**, placer le dossier du projet dans un espace synchronisé
(Syncthing, Drive). L'option `--data` ne permet pas de pointer ailleurs : le serveur refuse un
fichier situé hors de son propre dossier.
L'outil ne gère pas les conflits — si deux machines modifient le planning en même temps, la dernière
écriture l'emporte. Les sauvegardes horodatées de `data/backups/` sont le filet de sécurité.
## Tests
```sh
node --test
```
Couvre la logique métier : validation des dates, bornes d'un projet, calcul de dérive, génération des
identifiants, normalisation et filtrage des tags. Aucune dépendance, le lanceur de tests intégré à
Node suffit.
## Organisation du code
| Fichier | Rôle |
|---|---|
| `serve.py` | Sert les fichiers statiques, expose `GET`/`PUT` sur `/api/data`, écrit les sauvegardes |
| `js/model.js` | Données et règles métier : CRUD, validation, bornes, référence, dérive, tags |
| `js/storage.js` | Dialogue avec le serveur, sauvegarde debouncée, indicateur d'état |
| `js/timeline.js` | Rendu de la frise : échelle, couloirs, barres, jalons, pli/dépli |
| `js/drag.js` | Glisser et redimensionner les barres |
| `js/detail.js` | Panneau de détail d'une phase |
| `js/projet.js` | Panneau des paramètres d'un projet : nom, couleur, tags |
| `js/menu.js` | Menu contextuel et dialogue de confirmation |
| `js/app.js` | Amorçage, état en mémoire, câblage des événements |
Le rendu utilise des éléments DOM positionnés en absolu, pas de SVG ni de bibliothèque Gantt.
Les identifiants de code et les clés JSON sont en anglais ; l'interface, les commentaires et la
documentation sont en français.