Elle s'épaississait en mode plié, au motif qu'elle y était seule sur sa ligne. Mais plier un couloir ne change rien à ce que cette barre représente : la voir changer d'aspect au pli laissait croire à deux objets différents. Elle garde donc partout la hauteur de sa version dépliée, plus mince qu'une barre de phase — puisqu'elle voisine avec elles dès que le projet est déplié, et qu'elle ne se glisse pas. `--hauteur-cumulative` remonte dans `:root` : la barre et le fantôme qui la double sont frères et non imbriqués, la variable doit donc vivre au-dessus des deux. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
174 lines
8.5 KiB
Markdown
174 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 et toujours rendue pareil. 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.
|
|
- **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.
|