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:
2026-08-07 18:35:17 +02:00
parent e04877daae
commit ff147a17b9
16 changed files with 1150 additions and 35 deletions

View File

@@ -29,6 +29,8 @@ import {
phasesParMois,
projetFiltre,
} from './model.js';
import { aplatirMarkdown } from './markdown.js';
import { rendreMarkdown } from './notes.js';
import { pastillesTags } from './tags.js';
/**
@@ -218,14 +220,20 @@ function triangle(phase) {
/**
* Les notes occupent une seconde rangée de la grille, sous toutes les colonnes.
* `white-space: pre-wrap` (style.css) leur conserve leurs retours à la ligne :
* elles sont souvent une petite liste, et la mettre à plat en changerait le
* sens.
*
* Elles sont rendues en markdown, comme dans le panneau : une note doit se lire
* pareil des deux côtés, sans quoi on douterait d'avoir la même sous les yeux.
*
* Les cases à cocher, elles, restent **inertes** ici. La vue est en lecture
* seule (décision 24), et une case cliquable y serait la seule chose qu'on
* puisse modifier — une exception isolée dans une vue dont toute la promesse est
* qu'on n'y casse rien. On les voit cochées ou non, ce qui est justement ce
* qu'on vient y chercher quand on fait le point.
*/
function notes(phase) {
const bloc = document.createElement('p');
const bloc = document.createElement('div');
bloc.className = 'mois-entree__notes';
bloc.textContent = phase.notes;
bloc.append(rendreMarkdown(phase.notes));
bloc.hidden = true;
return bloc;
}
@@ -239,7 +247,10 @@ function infobulle(projet, phase) {
: `${formaterDateLongue(phase.start)}${formaterDateLongue(phase.end)}` +
` (${jours} jour${jours > 1 ? 's' : ''})`) +
`\n${LIBELLES_STATUT[phase.status]}` +
(phase.notes ? `\n\n${phase.notes}` : '')
// Aplati : un `title` ne connaît que le texte. Sans cela, survoler afficherait
// la source markdown, astérisques comprises — une note *moins* lisible
// qu'avant qu'on ne l'enrichisse.
(phase.notes ? `\n\n${aplatirMarkdown(phase.notes)}` : '')
);
}