DOCS/kanban/cards/5-planifie/290-refonte-visuelle-config-section-et-dialogues.md
2026-09-04 16:48:04 +02:00

16 KiB
Raw Permalink Blame History

title, area, horizon, tags, flag, src
title area horizon tags flag src
Refonte visuelle des écrans Configuration & Section, et de leurs dialogues manager v1 manager-app, UI, dialogues good | Maquette prête, code à faire DOCS/claude design/refonte-configuration-sections.html

Lots 1 à 5 codés le 04/09 (flutter analyze sans erreur, flutter build web passe ; rien de vérifié à l'écran). Pilote select_resource_modal : coquille standard, corps souple, plus de double défilement, showValues mort supprimé, largeur 0,85 conservée. Lot 1 : text_field_container sans width: double.infinity ni rayon 29, compteur discret dans rounded_input_field. Lot 2 : libellé au-dessus et plus d'auto-centrage dans string_/multi_string_/resource_/check_input_container. Lot 3 : grille responsive de sections, réordonnancement par Draggable/DragTarget (ReorderableListView ne fait pas de grille, et pas de dépendance nouvelle), tuile « Ajouter » à la place du bouton vert. Lot 4 : les deux écrans de détail en EditorHeader + EditorColumns + Pane (nouveau Components/pane.dart), _buildFooter supprimé, le QR devient le rail « Diffusion ». Lot 5 : grille de types dans new_section_popup, modal de traduction en rail de langues + IndexedStack, et multi_input_modal réduit à une redirection isHTML: false. 24 clés i18n ajoutées en FR/EN/NL.

🐛 Le bug des catégories est confirmé et corrigé : showCreateOrUpdateCategories recevait un newValues vide de l'appelant et le renvoyait tel quel — valider sans rien toucher effaçait les catégories. Le tampon part maintenant des catégories existantes, et les libellés en dur sont passés par AppLocalizations.

Lot 6 entamé : Components/collection_editor.dart existe — liste ordonnée à gauche (réordonnancement par poignée), élément édité en place à droite, ligne « Ajouter » en fin de liste, suppression dans l'en-tête du détail. Trois types migrés : Slider et Article (via un ContentFields partagé, extrait de showNewOrUpdateContentSlider) et PDF (le bloc figé 70 × 440 disparaît). Les filtres d'envoi au backend sont conservés à l'identique (contenus sans ressource exclus, champs d'article recopiés).

⚠️ Trois fichiers sont devenus du code mort mais ne sont pas supprimés : pdf_file_input_container.dart, pdf_list.dart, new_update_pdfFile.dart. Ils portent des modifications non committées d'un autre lot — les effacer perdrait ce travail. À supprimer une fois l'arbre propre.

Lot 6 terminé pour le gabarit B. Décision prise le 04/09 (artifact 4af75171) : CollectionEditor reçoit un mode distant (RemoteCollection : create / delete / reorder asynchrones, voile de chargement, retour à l'état d'avant si l'appel échoue). Quiz l'utilise : la modale de question disparaît, les messages de score remontent en tête de carte, les réponses gardent QuizzResponseList tel quel. Menu garde la navigation vers sub_section_edit_screen — une sous-section est une section complète — et prend la grille de tuiles, extraite en SectionGrid et partagée avec les sections d'une configuration. Parcours : liste qui suit son contenu, les deux SizedBox(height: 500) de event_config et section_parcours_config retirés, éditeur à fenêtre unique inchangé.

🐛 Le rang en double est corrigé dans Quiz et Menu : ils n'écrivaient que l'order de l'élément déplacé, les autres gardaient le leur. La liste entière est renumérotée et envoyée en un Future.wait, comme le faisait déjà Parcours.

Agenda n'a pas été migré, et c'est délibéré : ses événements sont groupés par langue (_displayGroups, pastilles de langue quand un groupe en compte plusieurs) et n'ont pas d'ordre — une liste ordonnée à édition en place perdrait le groupement. Il reçoit ce qui lui revient : hauteur pilotée par le contenu (le height: 600 saute), lignes au système de tokens, modale conservée.

Gabarit C — Jeu est fait, Map et Événement sont dégrossis. game_config devient champs à gauche + canevas à droite : le canevas montre le découpage réel de l'image en rows × cols, seule décision que le formulaire ne montrait pas. Au passage, son TabBar n'en était pas un — les deux onglets construisaient le même formulaire et ne servaient qu'à écrire gameType : c'est devenu un choix à deux valeurs, et le SizedBox(height: 650) a disparu. geoloc_input_container passe à la coquille standard et affiche les coordonnées retenues au lieu d'un bouton « Changer la localisation », la carte prenant la hauteur disponible. Côté map_config : en-tête en grille de tokens, height: 700 et height: 70 retirés. Côté event_config : height: 600 retiré, la liste des blocs suit son contenu.

Reste : le canevas de Map et d'Événement — et il est maintenant maquetté : DOCS/claude design/refonte-gabarit-canevas.html (diffusion : artifact caf400b5). Liste des points, fiche, carte côte à côte ; les points non sélectionnés restent visibles en gris ; MapGeometryPicker sort de son dialogue pour devenir le canevas (déplacement, pas écriture) ; les informations pratiques d'un point (5 champs sur 9) sont repliées derrière un compteur. Absorbe showNewOrUpdateGeoPoint (362 l.), geometry_input_container et showNewOrUpdateMapAnnotation (182 l.). Une question produit reste ouverte : que montre le canevas d'Événement quand baseSectionMapId est nul — carte vide, ou invitation à choisir un plan d'abord (ma proposition).

Étape 1 du canevas faite le 04/09 : Components/map_canvas.dart — le dessin est sorti du dialogue. Il reçoit une géométrie, la rend modifiable, rend la main à chaque changement (pas de bouton « Enregistrer » : c'est l'écran qui enregistre), et affiche les autres tracés en fond via MapCanvasGhost. Barre d'outils compacte sur la carte, pied qui donne les coordonnées et ce qu'on modifie, bouton « agrandir » optionnel. MapGeometryPicker n'est plus qu'une coquille autour de lui, donc etape_fields et showNewOrUpdateEventAgenda ne bougent pas. Au passage, ses libellés « Ligne » / « Polygone » en dur sont passés par AppLocalizations. Taille tranchée : 420 px par défaut + mode agrandi, pas une interface centrée carte — un point porte neuf champs traduits, la carte n'en porte qu'un.

Étapes 2 à 4 faites : le gabarit C est en place dans Map. Map/geo_point_editor.dart — liste des points à gauche, fiche au centre, carte à droite ; les points non sélectionnés apparaissent en fond ; le mode agrandi replie la fiche et garde le rail. Les neuf champs traduits sont rangés par fréquence : titre, catégorie, description et image visibles, les cinq informations pratiques repliées derrière un compteur. map_config passe de 937 à ~510 lignes : la modale showNewOrUpdateGeoPoint n'est plus appelée, getElement et son boxDecoration sont supprimés, et recherche + catégories filtrent désormais la liste et la carte par un seul calcul. Les points sont créés, modifiés et supprimés directement par l'API (sectionMapCreate / Update / Delete), la suppression passant par la confirmation destructive.

Étape 5 faite : le canevas d'Événement. Les annotations passent dans l'éditeur de collection en mode distant, avec le canevas dans le panneau d'édition. Plan par défaut retenu (décision Thomas) : le premier plan disponible est pris quand baseSectionMapId est nul, plutôt que de bloquer. 🐛 Trouvé en chemin : MapAnnotationDTO portait déjà un champ geometry que l'ancienne modale ne remplissait jamais — elle ne réglait que geometryType. Une annotation déclarait donc une forme sans jamais recevoir de coordonnées ; le canevas les lui donne. Enfin showMultiStringInputAndResourceHTML est passé à la coquille standard : plus aucun dialogue de ce chantier sur l'ancienne.

Plan de test : DOCS/test-plan-refonte-config-section.md, 14 sections. Rien n'a été vérifié à l'écran — flutter analyze propre et flutter build web qui passe, c'est tout.

Reste : supprimer le code mort une fois l'arbre git propre — showNewOrUpdateGeoPoint, showNewOrUpdateMapAnnotation, pdf_file_input_container, pdf_list, new_update_pdfFile, listView_card_subSection, new_update_question_quizz ; et geometry_input_container quand etape_fields et showNewOrUpdateEventAgenda auront leur canevas.

Restent aussi showMultiStringInputAndResourceHTML sur l'ancienne coquille, et le code mort à supprimer une fois l'arbre propre : pdf_file_input_container, pdf_list, new_update_pdfFile, listView_card_subSection, new_update_question_quizz.
⚠️ À vérifier manuellement en priorité : les deux chemins qui recréent les contrôleurs Quill (traduction IA, « appliquer à toutes les langues ») ; les hauteurs figées restées autour des champs devenus plus hauts (height: 70, 100) dans les écrans non repris — showNewOrUpdateGeoPoint, showNewOrUpdateEventAgenda, sub_section_edit_screen, new_configuration_popup.

Maquette prête et complète : DOCS/claude design/refonte-configuration-sections.html (diffusion : artifact 4d0c2ad6). Elle contient le diagnostic, les deux écrans, les 3 gabarits qui couvrent les 13 types de section, la coquille de dialogue, et deux dialogues dessinés — traduction et choix du type. Rien à décider côté design : tout est tranché.

Le blanc ne vient pas des écrans mais de 4 composants partagés. text_field_container.dart impose width: double.infinity + rayon 29 ; string_input_container.dart met le label à gauche dans un Row ; multi_string_input_container et resource_input_container se centrent eux-mêmes ; section_reorderList.dart réserve 0,3 × hauteur pour une liste horizontale de cartes 150×150. On les corrige une fois, les 13 types en héritent.

⚠️ Aucune direction visuelle à inventer : constants.dart porte déjà le système (kSpace1..8, kRadiusInput 5 / Card 8 / Shell 10 / Pill, kTitleCard, kLabelField, kTextHint) et confirmation_dialog.dart + resource_picker.dart l'appliquent déjà. Ces deux écrans sont simplement antérieurs au système.

Premier pas conseillé : select_resource_modal.dart, pas les composants partagés. Un fichier, ~15 lignes, zéro ligne dans ResourcesScreen, et ça corrige un vrai bug — AlertDialog dispose de hauteur 48 mais le contenu en demande 0,85 × hauteur plus titre plus actions, d'où un défilement dans un défilement. Ça sert de pilote avant de toucher aux composants qui irriguent 30 écrans. Ne pas toucher à la largeur 0,85 : la règle du rail de facettes de v1-mediatheque-plan.md §3.3 est écrite sur cette hypothèse et déjà codée.

⚠️ Deux pièges qui ne sont pas du visuel. D'abord, manager-app n'a que 3 tests, aucun sur ces composants : vérification manuelle, et il reste des conteneurs à hauteur figée (height: 70, 100, SizedBox(height: 250)) autour — ce qui rentrait juste débordera. Ensuite un chemin d'écriture est câblé dans les composants : section_detail_screen.dart:270 déclenche un save(true, …) depuis MultiStringInputContainer.onGetResult, et la ligne 381 un save(false, …) depuis la case iBeacon. À ne pas perdre ni dédoubler.

⚠️ Le piège Quill (remonté de mémoire par Thomas, confirmé dans le code). Ça marche aujourd'hui parce que l'empilement vertical monte toutes les langues : _controllers est bâtie une fois dans initState (translation_input_container.dart:52) et libérée seulement dans dispose. Le rail de langues de la maquette casse cette propriété s'il reconstruit l'éditeur à chaque bascule. Règle : map construite une fois pour toutes les langues, bascule par IndexedStack/Offstage, jamais de TabBarView (construction paresseuse, enfants lâchés hors écran sans AutomaticKeepAliveClientMixin). Trace d'une tentative abandonnée : translation_tab.dart existe en TabBar, son appel est en commentaire dans multi_input_modal.dart:46-51. À retester en priorité : la traduction IA (ligne 142) et « appliquer à toutes les langues » (ligne 183), les deux chemins qui libèrent et recréent les contrôleurs.

Deux fusions et un ménage décidés dans la maquette : multi_input_modal.dart est le jumeau sans HTML du modal de traduction (même travail, deux implémentations) → une coquille, deux corps, Quill si isHTML et champ simple sinon ; les 8 showNewOrUpdate* et les 2 sélecteurs géo disparaissent dans les gabarits B et C ; showValues est mort en double (select_resource_modal.dart:64 et multi_input_modal.dart:186, appel commenté ligne 53).

⚠️ Conflit résolu avec l'auditsecurity/audit-manager-app.md recommandait d'extraire un FormDialogScaffold pour les 15 occurrences des showNewOrUpdate*. Or la refonte les supprime : les extraire d'abord, ce serait refactoriser du code à jeter. Ordre imposé : absorber d'abord (gabarits B et C), extraire ensuite sur ce qui survit — traduction, nouvelle section, nouvelle configuration, sélecteur de couleur, fichiers PDF, catégories. L'audit et STATUS.md ont été annotés en ce sens le 2026-09-04.

🐛 Trouvé en passant, à vérifier : pdf_file_input_container.dart et category_input_container.dart sont un copier-coller — mêmes dimensions, même structure — mais le second a ses libellés en dur (« Annuler », « Valider ») et son onGetResult(result) commenté. Une catégorie de carte modifiée ne remonte peut-être pas à la volée. Lecture de code, pas testé.