Recherche partout (#68, chantier 2+3) : onglets, Tout voir sur place, focus, mise en page #38

Merged
bruno merged 4 commits from recherche-onglets-ux-68 into main 2026-10-28 14:25:41 -04:00
Owner

Recherche partout — chantier 2+3 : mise en page + UX + onglets (fusion #68, suite de validation)

Branche recherche-onglets-ux-68 → main. Ne pas merger sans le go du coordinateur ; aucune version bumpée, aucune issue ouverte/fermée par cette PR. Référence de validation : issue Projets/fusion-trois-apps #68 (son état n'est pas changé par cette PR).

Ce qui est corrigé, point par point

  1. Mise en page TikTak : cause trouvée — recherche.html étend base.html sans layout_class, donc .rp-page (enfant direct de .layout) tombait en auto-placement dans la 2e colonne de la grille (largeur sidebar), d'où l'étroite colonne à gauche. Correctif dans recherche.css seul, gardé par l'ancêtre .layout (TikTak seul) : .layout > .rp-page { grid-column: 2 / -1; max-width: none; } — la page occupe toute la largeur disponible juste à droite du rail d'icônes, sans toucher aux autres pages (elles ne portent pas .rp-page) ; en mobile (≤760 px) elle prend la colonne unique.
  2. Mise en page ObsiGate : voir le paragraphe propre à ObsiGate ci-dessous.
  3. Focus automatique : l'attribut autofocus seul ne survivait pas au chargement des surcouches (barre, palette, app). La page appelle désormais focus() explicitement en fin d'init, plus un rappel requestAnimationFrame/setTimeout et un rappel pageshow ; cliquer la barre « Rechercher partout » (data-act="palette") alors qu'on est déjà sur la page replace le curseur dans la boîte (et sélectionne le texte) au lieu de recharger ; / et Ctrl+K / ⌘K inchangés.
  4. « Tout voir » : ne quitte plus la page. Le clic bascule vers l'onglet de l'application (son href reste une URL partageable ?q=&tab= au cas où le JS ne tournerait pas) ; dans l'onglet propre à l'app, le lien est masqué (redondant).
  5. Onglets : Tout, ObsiGate, Flowdeck, TikTak, Kanbante, Console Spark — mêmes onglets, mêmes compteurs sur les 4 hôtes. « Tout » = les 4 sections groupées, chaque liste tronquée à 8 ; un onglet app = tous les résultats de cette app (requête ObsiGate en limit=100, les autres API renvoient leur jeu complet, aucune troncature côté client). L'onglet actif vit dans l'URL (?tab=, absent = Tout) : partageable, et le retour arrière navigateur le restaure (popstate). Clavier : ←/→, Début/Fin entre onglets ; ↑/↓ puis Entrée sur les résultats visibles conservés (les liens des sections masquées sont exclus de la navigation).
  6. Compteurs et états : chaque onglet affiche le TOTAL de son application (pas le nombre tronqué de « Tout »), « … » pendant le chargement, « 0 » pour un vide honnête, rien pour une section en erreur (pas de faux 0). « Tout » affiche « … » tant qu'une section charge, sinon la somme des totaux connus. Une section injoignable ne casse pas les autres (état par section, comme en #68) ; le correctif CORS lui-même est chez un autre travailleur et n'est pas touché ici (aucun fichier CORS/middleware, aucune ligne d'onglets de la barre modifiée).
  7. Console Spark : AUCUN endpoint de recherche console n'est mergé à ce jour (agent-commun : seule la PR #12 est ouverte, autre programme — ce dépôt n'est pas touché ici, et l'endpoint n'est pas réimplémenté ici). Le code tente l'appel conventionnel GET {base-console}/api/search?q= (même convention que les autres hôtes ; chemin À CONFIRMER avec le travailleur console dès que son endpoint atterrit) et, en cas d'échec, de HTTP non-OK ou de format non reconnu, affiche honnêtement « Console Spark : recherche indisponible pour l'instant » — jamais de faux résultats, jamais de faux 0. La base console vient de data-base-console rendu par l'hôte, sinon de window.DRACO_URLS.agent / window.DRACO_AGENT_URL, sinon de la dérivation -dev, sinon du href d'un onglet de barre console/spark, sinon du défaut prod agent.dracodev.net. L'onglet console n'est interrogé que lorsqu'il est affiché ; « Tout » ne le contient pas, pour ne pas polluer la vue groupée d'un message d'indisponibilité.

Fichiers

  • Page de recherche de l'hôte (gabarit + onglets + section console), recherche.js et recherche.css vendangés à l'identique sur les 4 hôtes, tests de logique pure étendus. Aucun autre fichier touché.

Tests (chiffres réels, pas de déployé, pas de capture)

  • Tests de logique pure : TikTak/Kanbante/Flowdeck node tests/recherche.test.js → 59 assertions OK chacun ; ObsiGate node tests/frontend/recherche.test.mjs → 42 assertions OK. Nouveautés couvertes : parseTab, visibleKeys (Tout = 4 sections, sans console), troncature 8 vs complet, compteurs (…/total/0/vide), buildSearchUrl, searchPath/normalize complets, normalizeConsole (URL absolue/relative conservée, sans URL = pas de faux lien, format inconnu = non reconnu), resolveConsoleBase (explicite > injecté > -dev > href barre > prod). Suites existantes sans régression (les assertions #68 d'origine passent toutes).
  • Harnais DOM local (hors PR, fait tourner le vrai recherche.js avec un fetch factice : ObsiGate 12 résultats, Flowdeck 3, TikTak vide, Kanbante en erreur, console en erreur) → 23 assertions OK : focus au chargement, « Tout » = 8 liens affichés pour ObsiGate avec compteur 12, compteurs 12/3/0/vide, « Tout » = 15, section Kanbante en erreur sans casser la page, « Tout voir » ObsiGate → onglet avec les 12 résultats + URL ?q=test&tab=obsigate + focus onglet, flèche droite → Flowdeck, console = message indisponible et compteur vide, popstate restaure requête + onglet, clic palette → focus + sélection, Entrée → premier résultat visible.
  • Écarts préexistants nommés : aucun écart nouveau constaté dans les fichiers touchés ; les validations déployées ci-dessous restent à faire par Bruno après merge/publication (aucun test déployé, aucune capture dans cette PR).

À valider en direct par Bruno après merge/publication

Mise en page TikTak (pleine largeur à droite du rail, mobile compris) ; mise en page ObsiGate (voir paragraphe ObsiGate) ; focus (clic barre, ⌘K, /, rechargement) ; « Tout voir » (reste sur la page, bascule d'onglet) ; onglets + URL (partage ?tab=, retour arrière) ; compteurs (totaux, …, 0, section en erreur) ; onglet Console Spark (indisponible honnête tant que l'endpoint console n'est pas mergé, puis résultats réels après confirmation du chemin avec l'autre travailleur).

Paragraphe propre à Kanbante

Mise en page : inchangée (la page, déjà dans le gabarit avec _header.html, n'était pas visée par les retours de Bruno) — seuls les onglets, « Tout voir », le focus et la section console sont ajoutés. Base console rendue explicitement : data-base-console depuis agent_url (contexte render() commun). Fichiers : app/templates/recherche.html, static/js/recherche.js, static/css/recherche.css, tests/recherche.test.js.

## Recherche partout — chantier 2+3 : mise en page + UX + onglets (fusion #68, suite de validation) Branche `recherche-onglets-ux-68` → `main`. Ne pas merger sans le go du coordinateur ; aucune version bumpée, aucune issue ouverte/fermée par cette PR. Référence de validation : issue Projets/fusion-trois-apps #68 (son état n'est pas changé par cette PR). ### Ce qui est corrigé, point par point 1. Mise en page TikTak : cause trouvée — `recherche.html` étend `base.html` sans `layout_class`, donc `.rp-page` (enfant direct de `.layout`) tombait en auto-placement dans la 2e colonne de la grille (largeur sidebar), d'où l'étroite colonne à gauche. Correctif dans `recherche.css` seul, gardé par l'ancêtre `.layout` (TikTak seul) : `.layout > .rp-page { grid-column: 2 / -1; max-width: none; }` — la page occupe toute la largeur disponible juste à droite du rail d'icônes, sans toucher aux autres pages (elles ne portent pas `.rp-page`) ; en mobile (≤760 px) elle prend la colonne unique. 2. Mise en page ObsiGate : voir le paragraphe propre à ObsiGate ci-dessous. 3. Focus automatique : l'attribut `autofocus` seul ne survivait pas au chargement des surcouches (barre, palette, app). La page appelle désormais `focus()` explicitement en fin d'init, plus un rappel `requestAnimationFrame`/`setTimeout` et un rappel `pageshow` ; cliquer la barre « Rechercher partout » (`data-act="palette"`) alors qu'on est déjà sur la page replace le curseur dans la boîte (et sélectionne le texte) au lieu de recharger ; `/` et Ctrl+K / ⌘K inchangés. 4. « Tout voir » : ne quitte plus la page. Le clic bascule vers l'onglet de l'application (son `href` reste une URL partageable `?q=&tab=` au cas où le JS ne tournerait pas) ; dans l'onglet propre à l'app, le lien est masqué (redondant). 5. Onglets : Tout, ObsiGate, Flowdeck, TikTak, Kanbante, Console Spark — mêmes onglets, mêmes compteurs sur les 4 hôtes. « Tout » = les 4 sections groupées, chaque liste tronquée à 8 ; un onglet app = tous les résultats de cette app (requête ObsiGate en `limit=100`, les autres API renvoient leur jeu complet, aucune troncature côté client). L'onglet actif vit dans l'URL (`?tab=`, absent = Tout) : partageable, et le retour arrière navigateur le restaure (`popstate`). Clavier : ←/→, Début/Fin entre onglets ; ↑/↓ puis Entrée sur les résultats visibles conservés (les liens des sections masquées sont exclus de la navigation). 6. Compteurs et états : chaque onglet affiche le TOTAL de son application (pas le nombre tronqué de « Tout »), « … » pendant le chargement, « 0 » pour un vide honnête, rien pour une section en erreur (pas de faux 0). « Tout » affiche « … » tant qu'une section charge, sinon la somme des totaux connus. Une section injoignable ne casse pas les autres (état par section, comme en #68) ; le correctif CORS lui-même est chez un autre travailleur et n'est pas touché ici (aucun fichier CORS/middleware, aucune ligne d'onglets de la barre modifiée). 7. Console Spark : AUCUN endpoint de recherche console n'est mergé à ce jour (agent-commun : seule la PR #12 est ouverte, autre programme — ce dépôt n'est pas touché ici, et l'endpoint n'est pas réimplémenté ici). Le code tente l'appel conventionnel `GET {base-console}/api/search?q=` (même convention que les autres hôtes ; chemin À CONFIRMER avec le travailleur console dès que son endpoint atterrit) et, en cas d'échec, de HTTP non-OK ou de format non reconnu, affiche honnêtement « Console Spark : recherche indisponible pour l'instant » — jamais de faux résultats, jamais de faux 0. La base console vient de `data-base-console` rendu par l'hôte, sinon de `window.DRACO_URLS.agent` / `window.DRACO_AGENT_URL`, sinon de la dérivation -dev, sinon du href d'un onglet de barre console/spark, sinon du défaut prod `agent.dracodev.net`. L'onglet console n'est interrogé que lorsqu'il est affiché ; « Tout » ne le contient pas, pour ne pas polluer la vue groupée d'un message d'indisponibilité. ### Fichiers - Page de recherche de l'hôte (gabarit + onglets + section console), `recherche.js` et `recherche.css` vendangés à l'identique sur les 4 hôtes, tests de logique pure étendus. Aucun autre fichier touché. ### Tests (chiffres réels, pas de déployé, pas de capture) - Tests de logique pure : TikTak/Kanbante/Flowdeck `node tests/recherche.test.js` → 59 assertions OK chacun ; ObsiGate `node tests/frontend/recherche.test.mjs` → 42 assertions OK. Nouveautés couvertes : `parseTab`, `visibleKeys` (Tout = 4 sections, sans console), troncature 8 vs complet, compteurs (`…`/total/`0`/vide), `buildSearchUrl`, `searchPath`/`normalize` complets, `normalizeConsole` (URL absolue/relative conservée, sans URL = pas de faux lien, format inconnu = non reconnu), `resolveConsoleBase` (explicite > injecté > -dev > href barre > prod). Suites existantes sans régression (les assertions #68 d'origine passent toutes). - Harnais DOM local (hors PR, fait tourner le vrai `recherche.js` avec un `fetch` factice : ObsiGate 12 résultats, Flowdeck 3, TikTak vide, Kanbante en erreur, console en erreur) → 23 assertions OK : focus au chargement, « Tout » = 8 liens affichés pour ObsiGate avec compteur 12, compteurs 12/3/0/vide, « Tout » = 15, section Kanbante en erreur sans casser la page, « Tout voir » ObsiGate → onglet avec les 12 résultats + URL `?q=test&tab=obsigate` + focus onglet, flèche droite → Flowdeck, console = message indisponible et compteur vide, `popstate` restaure requête + onglet, clic palette → focus + sélection, Entrée → premier résultat visible. - Écarts préexistants nommés : aucun écart nouveau constaté dans les fichiers touchés ; les validations déployées ci-dessous restent à faire par Bruno après merge/publication (aucun test déployé, aucune capture dans cette PR). ### À valider en direct par Bruno après merge/publication Mise en page TikTak (pleine largeur à droite du rail, mobile compris) ; mise en page ObsiGate (voir paragraphe ObsiGate) ; focus (clic barre, ⌘K, `/`, rechargement) ; « Tout voir » (reste sur la page, bascule d'onglet) ; onglets + URL (partage `?tab=`, retour arrière) ; compteurs (totaux, `…`, `0`, section en erreur) ; onglet Console Spark (indisponible honnête tant que l'endpoint console n'est pas mergé, puis résultats réels après confirmation du chemin avec l'autre travailleur). ### Paragraphe propre à Kanbante Mise en page : inchangée (la page, déjà dans le gabarit avec `_header.html`, n'était pas visée par les retours de Bruno) — seuls les onglets, « Tout voir », le focus et la section console sont ajoutés. Base console rendue explicitement : `data-base-console` depuis `agent_url` (contexte `render()` commun). Fichiers : `app/templates/recherche.html`, `static/js/recherche.js`, `static/css/recherche.css`, `tests/recherche.test.js`.
bruno added 4 commits 2026-10-28 13:49:54 -04:00
bruno merged commit 8f437e3a3e into main 2026-10-28 14:25:41 -04:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Projets/kanbante#38