Consigner les arbitrages sur les tags et le filtre

Section 16 de decisions.md : pourquoi des étiquettes libres plutôt qu'un
référentiel, pourquoi un filtre conjonctif plutôt que disjonctif, pourquoi il
n'est pas enregistré alors que le masquage par l'œil l'est — avec un tableau qui
oppose les deux —, pourquoi la couleur d'un tag est calculée et non choisie, et
pourquoi un tag trop long est tronqué là où une date invalide bloque tout.

Le README décrit l'usage : saisie des tags, filtre cumulatif, portée limitée à la
session.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-01 06:01:19 +02:00
parent 39ea249cdb
commit a2a5c5cb9c
2 changed files with 64 additions and 4 deletions

View File

@@ -37,8 +37,8 @@ Chaque projet porte trois commandes dans la colonne de gauche :
- **le triangle** plie et déplie son couloir ; - **le triangle** plie et déplie son couloir ;
- **l'œil** le masque de la frise sans le supprimer ; - **l'œil** le masque de la frise sans le supprimer ;
- **`⋯`** ouvre son menu : ajouter une phase ou un jalon, renommer, changer la couleur, - **`⋯`** ouvre son menu : ajouter une phase ou un jalon, renommer, changer la couleur et les
figer la référence, supprimer le projet. Un clic droit sur le libellé ouvre le même menu. tags, figer la référence, supprimer le projet. Un clic droit sur le libellé ouvre le même menu.
Une fois un projet en place : Une fois un projet en place :
@@ -56,6 +56,21 @@ Une fois un projet en place :
Faire défiler jusqu'au bord droit élargit la frise vers le futur, et jusqu'au bord gauche 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. 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 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. par les champs du panneau de détail.
@@ -76,6 +91,7 @@ par les champs du panneau de détail.
Il n'y a qu'une seule échelle, donc aucun réglage de zoom à comprendre. 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 - **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. 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. - **Repère « aujourd'hui »** et masquage d'un projet.
## Ce que l'outil ne fait pas ## Ce que l'outil ne fait pas
@@ -114,14 +130,15 @@ node --test
``` ```
Couvre la logique métier : validation des dates, bornes d'un projet, calcul de dérive, génération des Couvre la logique métier : validation des dates, bornes d'un projet, calcul de dérive, génération des
identifiants. Aucune dépendance, le lanceur de tests intégré à Node suffit. identifiants, normalisation et filtrage des tags. Aucune dépendance, le lanceur de tests intégré à
Node suffit.
## Organisation du code ## Organisation du code
| Fichier | Rôle | | Fichier | Rôle |
|---|---| |---|---|
| `serve.py` | Sert les fichiers statiques, expose `GET`/`PUT` sur `/api/data`, écrit les sauvegardes | | `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 | | `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/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/timeline.js` | Rendu de la frise : échelle, couloirs, barres, jalons, pli/dépli |
| `js/drag.js` | Glisser et redimensionner les barres | | `js/drag.js` | Glisser et redimensionner les barres |

View File

@@ -218,3 +218,46 @@ Attention en modifiant `centrerSur` : `scrollLeft` porte sur la grille entière,
première colonne est celle des libellés. Comme elle est `sticky`, elle masque en première colonne est celle des libellés. Comme elle est `sticky`, elle masque en
permanence les premiers pixels de la vue, et le centre utile des couloirs est décalé permanence les premiers pixels de la vue, et le centre utile des couloirs est décalé
d'une demi-largeur de colonne par rapport au centre de la frise. d'une demi-largeur de colonne par rapport au centre de la frise.
## 16. Tags libres et filtre conjonctif
Passé une dizaine de projets, la frise devient un mur : on veut n'y voir que les projets
clients, ou que ceux d'un pôle. D'où des **tags** sur le projet, et un filtre.
**Étiquettes libres, pas de référentiel.** Aucune liste de tags autorisés n'est tenue
quelque part : les tags disponibles sont ceux que portent les projets, et un tag disparaît
de la barre de filtres dès qu'il n'orne plus rien. Un référentiel séparé aurait exigé une
interface pour le gérer, et se serait désynchronisé. La contrepartie — la dérive
orthographique, « client », « Clients », « client final » — est traitée par deux gardes :
la comparaison ignore la casse, et le dialogue d'un projet propose en un clic les tags déjà
employés ailleurs.
**Le filtre exige *tous* les tags cochés**, pas au moins un. Cocher un tag de plus resserre
donc toujours la sélection : on part du tout et on élague, sans jamais voir la frise se
repeupler en cochant. La disjonction se comporte à l'inverse, et il faut alors relire la
liste des tags actifs pour savoir dans quel sens la prochaine case va jouer.
**Le filtre n'est pas enregistré.** C'est un état de vue, comme la fenêtre temporelle
(décision 15) : un filtre qui survivrait au rechargement rouvrirait le planning amputé sans
qu'on se souvienne pourquoi. Le masquage par l'œil (`hidden`), lui, est bien enregistré —
et les deux ne font pas la même chose :
| | Filtre par tags | Œil (`hidden`) |
|---|---|---|
| Portée | La vue entière, libellé compris | Les barres seules, le libellé reste grisé |
| Durée de vie | La session | Enregistré dans le fichier |
| Question posée | « Je ne regarde que les projets clients » | « Ce projet existe, mais il encombre ma frise » |
**La couleur d'un tag est calculée, pas choisie** : une teinte HSL dérivée du nom par
hachage. Rien à stocker, rien à saisir, et le même tag garde sa couleur partout. Des
collisions de teinte sont possibles et sans gravité — le nom est toujours écrit à côté.
**Un tag trop long est tronqué, pas refusé.** Contrairement à une date invalide, qui bloque
le chargement en nommant le fautif, la longueur d'un tag est cosmétique : refuser d'ouvrir
un planning entier pour un libellé bavard serait disproportionné. La limite est donc
appliquée en normalisant, ce qui la rend vraie par construction — aussi bien pour un fichier
édité à la main que pour une saisie dans le dialogue.
Créer un projet alors qu'un filtre est actif **préremplit ses tags** avec ceux du filtre :
sans cela, le nouveau venu naîtrait invisible, hors de la vue depuis laquelle on vient de le
demander.