Rendre les notes en markdown, et en donner au projet
Une phase avait quatre lignes de texte brut ; un projet n'avait rien. Les deux
manques se tiennent : la frise ne dit pas qui pilote ni sur quel budget, et ce
contexte finissait dans les notes de la première phase venue, où il ne survit
pas à sa suppression.
Le bloc de notes est le même dans les deux panneaux et prend toute la hauteur
restante : les autres champs ont une taille dictée par leur contenu, une note
fait ce qu'on a à dire. Il s'ouvre sur l'aperçu quand la note existe, sur la
saisie quand elle est vide.
Les cases à cocher se cliquent dans l'aperçu — seul geste de l'aperçu qui touche
aux données. La bascule réécrit la seule ligne visée plutôt que de régénérer la
note, qui verrait sinon sa mise en forme normalisée. Inertes dans la vue par
mois, en lecture seule (décision 24).
La barre d'outils écrit par `document.execCommand('insertText')` et non en
affectant `value`, qui viderait la pile d'annulation du navigateur : `Ctrl+Z`
doit continuer de marcher. Le DOM est bâti nœud par nœud, sans un `innerHTML`.
Les infobulles aplatissent le markdown — `title` ne connaît que le texte —, et
celles d'un jalon et d'un libellé de projet les affichent désormais.
Le format passe en version 4 : le validateur reconstruit chaque projet champ par
champ, un binaire antérieur effacerait les notes de projet à la première
sauvegarde.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,7 @@ dans un diff git et éditable à la main.
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 3,
|
||||
"version": 4,
|
||||
"projects": [
|
||||
{
|
||||
"id": "site-web",
|
||||
@@ -18,6 +18,7 @@ dans un diff git et éditable à la main.
|
||||
"tags": ["client", "web"],
|
||||
"collapsed": false,
|
||||
"hidden": false,
|
||||
"notes": "## Contexte\n\nPiloté par **Marie D.**\n\n- [x] cadrage validé\n- [ ] recette",
|
||||
"baselineDate": "2026-06-12",
|
||||
"phases": [
|
||||
{
|
||||
@@ -27,7 +28,7 @@ dans un diff git et éditable à la main.
|
||||
"end": "2026-08-20",
|
||||
"status": "done",
|
||||
"milestone": false,
|
||||
"notes": "Ateliers avec les trois pôles.",
|
||||
"notes": "Ateliers avec les trois pôles.\n\nPérimètre arrêté le **8 juillet**.",
|
||||
"baseline": { "start": "2026-07-25", "end": "2026-08-10" }
|
||||
},
|
||||
{
|
||||
@@ -49,11 +50,17 @@ dans un diff git et éditable à la main.
|
||||
|
||||
| Champ | Type | Description |
|
||||
|---|---|---|
|
||||
| `version` | entier | Version du format. Vaut `3`. Sert à détecter un fichier trop ancien au chargement. |
|
||||
| `version` | entier | Version du format. Vaut `4`. Sert à détecter un fichier trop ancien au chargement. |
|
||||
| `projects` | tableau | Les projets, dans l'ordre d'affichage des couloirs. |
|
||||
|
||||
Un fichier en version `2` — celle d'avant les tags — se charge sans rien demander : ses projets
|
||||
reçoivent une liste de tags vide, et il est réécrit en version `3` à la première sauvegarde.
|
||||
Un fichier plus ancien se charge sans rien demander et est réécrit au format courant à la première
|
||||
sauvegarde : une version `2` — celle d'avant les tags — voit ses projets recevoir une liste de tags
|
||||
vide, une version `3` — celle d'avant les notes de projet — des notes vides.
|
||||
|
||||
Un fichier écrit par une version **plus récente** est en revanche refusé. C'est la raison d'être du
|
||||
numéro : le validateur reconstruit chaque projet champ par champ et laisse tomber ce qu'il ne connaît
|
||||
pas, si bien qu'un binaire antérieur ouvrirait sans broncher un fichier plus riche que lui et en
|
||||
effacerait les champs inconnus à la première sauvegarde.
|
||||
|
||||
## Projet
|
||||
|
||||
@@ -65,6 +72,7 @@ reçoivent une liste de tags vide, et il est réécrit en version `3` à la prem
|
||||
| `tags` | tableau | Étiquettes libres servant à filtrer la frise. Trié, sans doublon, éventuellement vide. |
|
||||
| `collapsed` | booléen | `true` si le couloir est plié. |
|
||||
| `hidden` | booléen | `true` si le projet est masqué de la frise. Ses données restent intactes. |
|
||||
| `notes` | chaîne | Texte libre en markdown, éventuellement vide. Ce que la frise ne sait pas dire : contexte, interlocuteurs, décisions. |
|
||||
| `baselineDate` | chaîne ou absent | Date à laquelle la référence a été figée. Absent si elle ne l'a jamais été. |
|
||||
| `phases` | tableau | Les phases, triées par date de début croissante. |
|
||||
|
||||
@@ -78,7 +86,7 @@ reçoivent une liste de tags vide, et il est réécrit en version `3` à la prem
|
||||
| `end` | chaîne | Date de fin **incluse**, `AAAA-MM-JJ`. |
|
||||
| `status` | chaîne | `todo`, `doing`, `done` ou `blocked`. |
|
||||
| `milestone` | booléen | `true` pour un jalon. |
|
||||
| `notes` | chaîne | Texte libre, éventuellement vide. |
|
||||
| `notes` | chaîne | Texte libre en markdown, éventuellement vide. |
|
||||
| `baseline` | objet ou absent | Dates de référence : `{ "start": …, "end": … }`. Absent tant que la référence n'a pas été figée. |
|
||||
|
||||
## Règles de validation
|
||||
@@ -99,6 +107,9 @@ Appliquées par `js/model.js` et couvertes par `tests/model.test.js`.
|
||||
- `tags` est un tableau de chaînes. Le tableau lui-même et le type de ses éléments sont vérifiés —
|
||||
un tag mal typé serait un tag qu'on croit poser et qui ne filtre rien. Leur *contenu*, en revanche,
|
||||
est normalisé sans erreur (voir ci-dessous).
|
||||
- `notes`, de projet comme de phase, est ramenée à `""` si ce n'est pas une chaîne. Le champ n'engage
|
||||
aucun calcul, contrairement aux dates : bloquer le chargement d'un planning entier pour lui serait
|
||||
disproportionné.
|
||||
|
||||
## Tags
|
||||
|
||||
@@ -130,6 +141,43 @@ temporelle. Voir [decisions.md](decisions.md), section 16.
|
||||
Un fichier invalide n'est jamais réparé en silence : le chargement échoue avec un message qui pointe
|
||||
le projet et la phase fautifs, pour que le fichier puisse être corrigé à la main.
|
||||
|
||||
## Notes
|
||||
|
||||
Un projet et une phase portent chacun un champ `notes`, en **markdown**. Rien n'est stocké d'autre
|
||||
que le texte source : le rendu est refait à l'affichage par `js/markdown.js` (analyse) et
|
||||
`js/notes.js` (mise en DOM). Un fichier reste donc lisible et modifiable à la main, et une note
|
||||
écrite hors de l'outil s'affiche sans conversion.
|
||||
|
||||
Le markdown reconnu est un **sous-ensemble**, choisi pour ce qu'on écrit dans une note de suivi :
|
||||
|
||||
| Syntaxe | Rendu |
|
||||
|---|---|
|
||||
| `# Titre` à `###### Titre` | Titres, décalés de deux niveaux sous celui du panneau |
|
||||
| `**gras**`, `*italique*`, `_italique_` | Emphase |
|
||||
| `` `code` `` et blocs ```` ``` ```` | Code littéral |
|
||||
| `- item`, `* item`, `1. item` | Listes, imbricables à l'indentation |
|
||||
| `- [ ] item`, `- [x] item` | Cases à cocher, cliquables dans le panneau |
|
||||
| `[texte](https://…)` | Lien |
|
||||
| `> cité` | Citation, réanalysée (elle peut contenir une liste) |
|
||||
| `---` | Séparateur |
|
||||
| `\*` | Le caractère littéral qui suit la contre-oblique |
|
||||
|
||||
Trois écarts assumés au markdown standard :
|
||||
|
||||
- **Un retour à la ligne en est un.** Le standard recolle les lignes d'un même paragraphe et exige
|
||||
deux espaces en fin de ligne pour un vrai retour ; c'est un piège invisible dans un champ de
|
||||
saisie, où l'on écrit souvent une petite liste à la volée.
|
||||
- **Ce qui n'est pas reconnu reste du texte.** `**gras` sans fermeture s'affiche tel quel plutôt que
|
||||
d'avaler la suite : une note à moitié écrite est l'état normal d'une note.
|
||||
- **Ni tableaux, ni images, ni HTML brut.** Les deux premiers ne tiennent pas dans un volet latéral ;
|
||||
le troisième rouvrirait la porte à l'injection que la construction du DOM nœud par nœud ferme.
|
||||
|
||||
Les **liens** ne sont suivis que si leur schéma est `http`, `https` ou `mailto` — liste blanche, et
|
||||
non liste noire. Un planning s'échange, et rien ne garantit que la note affichée a été écrite par
|
||||
celui qui la lit. Un lien refusé n'est pas effacé : son libellé redevient du texte.
|
||||
|
||||
Voir [decisions.md](decisions.md), section 25.
|
||||
|
||||
## Dates : conventions
|
||||
|
||||
Les dates sont manipulées comme des **chaînes `AAAA-MM-JJ`**, pas comme des objets `Date`. Cela évite
|
||||
|
||||
Reference in New Issue
Block a user