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>
This commit is contained in:
33
js/detail.js
33
js/detail.js
@@ -8,12 +8,15 @@
|
||||
* C'est aussi ici qu'on saisit une date exacte : le glisser sur la frise
|
||||
* s'accroche au lundi, ce panneau est le recours quand une phase doit démarrer
|
||||
* un jeudi précis.
|
||||
*
|
||||
* Le panneau n'est **pas modal** : rien ne recouvre la frise pendant qu'il est
|
||||
* ouvert. Voir docs/decisions.md, section 17.
|
||||
*/
|
||||
|
||||
import { STATUTS, dateValide, modifierPhase } from './model.js';
|
||||
|
||||
export function creerPanneau(refs, rappels) {
|
||||
const { panneau, voile, formulaire, titre, erreur, champFin, supprimer, fermer } = refs;
|
||||
const { panneau, formulaire, titre, erreur, champFin, supprimer, fermer } = refs;
|
||||
|
||||
let selection = null; // { projet, phase }
|
||||
let phaseCourante = null;
|
||||
@@ -106,7 +109,6 @@ export function creerPanneau(refs, rappels) {
|
||||
});
|
||||
|
||||
fermer.addEventListener('click', () => api.fermer());
|
||||
voile.addEventListener('click', () => api.fermer());
|
||||
|
||||
document.addEventListener('keydown', (evenement) => {
|
||||
// Échap ferme le panneau, sauf pendant une saisie où il annule d'abord la
|
||||
@@ -117,14 +119,29 @@ export function creerPanneau(refs, rappels) {
|
||||
});
|
||||
|
||||
const api = {
|
||||
ouvrir(projet, phase) {
|
||||
/**
|
||||
* @param {object} options
|
||||
* - nomAEcraser : place le curseur dans le champ « Nom », texte
|
||||
* présélectionné. Réservé à une phase qui vient d'être créée, dont le
|
||||
* nom provisoire est justement là pour être remplacé.
|
||||
*
|
||||
* Hors de ce cas, le focus se pose sur le panneau lui-même et non dans un
|
||||
* champ : `app.js` ignore les flèches quand la frappe part dans un `input`,
|
||||
* et le raccourci le plus utile de l'outil — décaler la phase d'un jour —
|
||||
* serait inaccessible juste après l'avoir sélectionnée.
|
||||
*/
|
||||
ouvrir(projet, phase, { nomAEcraser = false } = {}) {
|
||||
selection = { projet: projet.id, phase: phase.id };
|
||||
phaseCourante = phase;
|
||||
remplir(projet, phase);
|
||||
panneau.hidden = false;
|
||||
voile.hidden = false;
|
||||
formulaire.name.focus();
|
||||
formulaire.name.select();
|
||||
|
||||
if (nomAEcraser) {
|
||||
formulaire.name.focus();
|
||||
formulaire.name.select();
|
||||
} else {
|
||||
panneau.focus();
|
||||
}
|
||||
},
|
||||
|
||||
/** Recharge le contenu après une modification venue de la frise. */
|
||||
@@ -143,10 +160,12 @@ export function creerPanneau(refs, rappels) {
|
||||
},
|
||||
|
||||
fermer() {
|
||||
// Sans cette garde, fermer un panneau déjà fermé relancerait un rendu
|
||||
// complet de la frise — ce qui arriverait à chaque clic dans le vide.
|
||||
if (panneau.hidden) return;
|
||||
selection = null;
|
||||
phaseCourante = null;
|
||||
panneau.hidden = true;
|
||||
voile.hidden = true;
|
||||
rappels.surFermeture();
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user