Kanbante 0.45.11 : barre v0.4.0 — icônes monoline du menu compte, vendange verbatim (HUB-11) + tests + version/changelog
CI / test (pull_request) Failing after 2s
CI / test (push) Failing after 2m37s

This commit is contained in:
Spark
2026-11-05 05:09:06 +00:00
parent bd84628ba3
commit 6ccd4adaa5
6 changed files with 148 additions and 3 deletions
+7
View File
@@ -1,3 +1,10 @@
## 0.45.11 — 2026-11-05 — Barre commune v0.4.0 : icônes monoline du menu compte (HUB-11)
- **Barre d'apps v0.4.0 vendangée (dracodev-commons, branche `menu-compte-icones-v0-4-0`, PR commons #10)** : `static/css/draco-barre.css` et `static/js/draco-barre.js` remplacés **verbatim** — SHA-256 CSS `d8cf53b2…a6bd06ec`, JS `36cc24b2…e5d39a0` (preuve dans `tests/test_barre_v040.py`). Le gabarit `_draco_bar.html` est inchangé.
- **Menu compte à icônes** : **Télécharger**, **À Propos**, **Aides**, **Profil** et **Déconnexion** reçoivent des **icônes SVG monoline** (contour, trait fin, `currentColor`, ~18 px) dans le style des icônes du rail de la console Spark — aucun emoji. L'en-tête d'identité reste sans icône ; les liens Hub (Profil → Hub compris) et le relais « Déconnexion » sont inchangés.
- **Cache** : le bump du fichier `VERSION` change le `?v=` des CSS/JS de la barre ; `APP_VERSION` suit automatiquement (source unique `VERSION`).
- Tests : `tests/test_barre_v040.py` (verbatim v0.4.0, marqueurs icônes) ; l'empreinte v0.3.0 de `tests/test_barre_v030.py` devient une preuve de supersession (patron HUB-1).
## 0.45.10 — 2026-11-04 — Barre commune v0.3.0 : liens Hub du menu compte (HUB-1) ## 0.45.10 — 2026-11-04 — Barre commune v0.3.0 : liens Hub du menu compte (HUB-1)
> Renumérotée 0.45.10 à la publication : le numéro 0.45.9 avait été consommé entre-temps par la release du correctif « source de version » (voir l'entrée suivante), publiée avant la fusion de la PR #81. > Renumérotée 0.45.10 à la publication : le numéro 0.45.9 avait été consommé entre-temps par la release du correctif « source de version » (voir l'entrée suivante), publiée avant la fusion de la PR #81.
+1 -1
View File
@@ -1 +1 @@
0.45.10 0.45.11
+13
View File
@@ -24,6 +24,10 @@
compte (Télécharger, À Propos, Aides, Profil) réutilisent compte (Télécharger, À Propos, Aides, Profil) réutilisent
.draco-menu-item (déjà ancre-compatible : text-decoration none) .draco-menu-item (déjà ancre-compatible : text-decoration none)
et le séparateur .draco-menu-sep du menu des applications. et le séparateur .draco-menu-sep du menu des applications.
v0.4.0 (HUB-11) : .draco-menu-icone — les icônes monoline des
items du menu compte (SVG inline construit par le JS) : 18 px,
replacées à gauche du libellé par order: -1 (l'item est en
flex), couleur atténuée --ink-2, pleine --ink au survol/focus.
Jetons repris du prototype validé Console v7.2. Jetons repris du prototype validé Console v7.2.
Thème : clair par défaut, sombre via [data-theme="dark"] sur <html> Thème : clair par défaut, sombre via [data-theme="dark"] sur <html>
ou prefers-color-scheme si l'app intégratrice ne force rien ou prefers-color-scheme si l'app intégratrice ne force rien
@@ -94,6 +98,15 @@
text-decoration: none; cursor: pointer; text-decoration: none; cursor: pointer;
} }
.draco-menu-item:hover, .draco-menu-item:focus-visible { background: var(--surface-2); } .draco-menu-item:hover, .draco-menu-item:focus-visible { background: var(--surface-2); }
/* Icônes monoline du menu compte (v0.4.0) : appendues après le
libellé dans le DOM, replacées à gauche par order: -1. */
.draco-menu-icone {
order: -1; flex: none; display: inline-flex; align-items: center;
width: 18px; height: 18px; color: var(--ink-2);
}
.draco-menu-icone svg { display: block; width: 18px; height: 18px; }
.draco-menu-item:hover .draco-menu-icone,
.draco-menu-item:focus-visible .draco-menu-icone { color: var(--ink); }
.draco-menu-sep { height: 1px; margin: 6px 10px; background: var(--line); } .draco-menu-sep { height: 1px; margin: 6px 10px; background: var(--line); }
.draco-compte-nom { .draco-compte-nom {
padding: 8px 10px 10px; font-weight: 700; font-size: 14px; padding: 8px 10px 10px; font-weight: 700; font-size: 14px;
+69
View File
@@ -29,6 +29,13 @@
* l'ouverture des menus. Le Hub n'a pas d'onglet dans la barre : * l'ouverture des menus. Le Hub n'a pas d'onglet dans la barre :
* comme spark, sa clé est résolue et exposée via DRACO_BAR.urls, * comme spark, sa clé est résolue et exposée via DRACO_BAR.urls,
* sans étape « href rendu » (voir « URL » ci-dessous). * sans étape « href rendu » (voir « URL » ci-dessous).
* v0.4.0 (carte HUB-11, fusion #125) : icônes monoline dans le
* menu compte — chaque item (les 4 liens du Hub et « Déconnexion »)
* reçoit un glyphe SVG inline dans le style des icônes du rail de
* la console (contour, trait fin régulier, currentColor, aucun
* remplissage), aligné à gauche du libellé via .draco-menu-icone.
* L'en-tête d'identité ne reçoit pas d'icône. Aucun changement de
* comportement : liens résolus et Déconnexion relayée inchangés.
* *
* Aucun gestionnaire inline : un seul écouteur délégué sur le document * Aucun gestionnaire inline : un seul écouteur délégué sur le document
* (patron validé par le prototype — les onclick du HTML généré sont * (patron validé par le prototype — les onclick du HTML généré sont
@@ -483,6 +490,66 @@
if (!appsMenu.hidden) lastOpener = brand; if (!appsMenu.hidden) lastOpener = brand;
} }
/* Icônes monoline du menu compte (v0.4.0) — glyphes contour
* dans le style des icônes du rail de la console : viewBox 24,
* stroke currentColor, remplissage nul, extrémités rondes.
* Chaque glyphe est une liste de primitives [balise, attributs]
* construites en DOM (jamais d'innerHTML), comme le reste du
* fichier. Le libellé reste le nœud texte de l'item ; l'icône,
* appendue après, est replacée à gauche par le CSS (order: -1
* sur .draco-menu-icone, l'item étant déjà en flex). */
var MENU_ICONES = {
/* Flèche vers le bas dans un plateau. */
"telecharger": [
["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }],
["polyline", { points: "7 10 12 15 17 10" }],
["line", { x1: "12", y1: "15", x2: "12", y2: "3" }]
],
/* Cercle d'information. */
"a-propos": [
["circle", { cx: "12", cy: "12", r: "9" }],
["line", { x1: "12", y1: "11", x2: "12", y2: "16" }],
["line", { x1: "12", y1: "8", x2: "12.01", y2: "8" }]
],
/* Cercle d'interrogation. */
"aide": [
["circle", { cx: "12", cy: "12", r: "9" }],
["path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }],
["line", { x1: "12", y1: "17", x2: "12.01", y2: "17" }]
],
/* Personne : tête + épaules. */
"profil": [
["path", { d: "M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" }],
["circle", { cx: "12", cy: "7", r: "4" }]
],
/* Flèche sortant d'un cadre (porte). */
"deconnexion": [
["path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }],
["polyline", { points: "16 17 21 12 16 7" }],
["line", { x1: "21", y1: "12", x2: "9", y2: "12" }]
]
};
function menuIcone(nom) {
var span = document.createElement("span");
span.className = "draco-menu-icone";
span.setAttribute("aria-hidden", "true");
var svg = document.createElement("svg");
svg.setAttribute("viewBox", "0 0 24 24");
svg.setAttribute("fill", "none");
svg.setAttribute("stroke", "currentColor");
svg.setAttribute("stroke-width", "1.8");
svg.setAttribute("stroke-linecap", "round");
svg.setAttribute("stroke-linejoin", "round");
svg.setAttribute("focusable", "false");
(MENU_ICONES[nom] || []).forEach(function (spec) {
var el = document.createElement(spec[0]);
for (var k in spec[1]) el.setAttribute(k, spec[1][k]);
svg.appendChild(el);
});
span.appendChild(svg);
return span;
}
/* Menu compte (v0.1.6 ; v0.3.0 pour les liens) — en-tête /* Menu compte (v0.1.6 ; v0.3.0 pour les liens) — en-tête
* d'identité, puis les liens du Hub (Télécharger, À Propos, * d'identité, puis les liens du Hub (Télécharger, À Propos,
* Aides, Profil — vrais <a href>, même patron que le menu des * Aides, Profil — vrais <a href>, même patron que le menu des
@@ -508,6 +575,7 @@
a.setAttribute("data-hub-link", pair[0]); a.setAttribute("data-hub-link", pair[0]);
a.setAttribute("role", "menuitem"); a.setAttribute("role", "menuitem");
a.textContent = pair[1]; a.textContent = pair[1];
a.appendChild(menuIcone(pair[0]));
compteMenu.appendChild(a); compteMenu.appendChild(a);
}); });
var sep = document.createElement("div"); var sep = document.createElement("div");
@@ -520,6 +588,7 @@
b.setAttribute("data-compte-act", "deconnexion"); b.setAttribute("data-compte-act", "deconnexion");
b.setAttribute("role", "menuitem"); b.setAttribute("role", "menuitem");
b.textContent = "Déconnexion"; b.textContent = "Déconnexion";
b.appendChild(menuIcone("deconnexion"));
compteMenu.appendChild(b); compteMenu.appendChild(b);
bar.appendChild(compteMenu); bar.appendChild(compteMenu);
} }
+6 -2
View File
@@ -42,8 +42,12 @@ def _nettoyer(monkeypatch):
def test_barre_css_js_verbatim_commons_v030(): def test_barre_css_js_verbatim_commons_v030():
assert _sha256("static/css/draco-barre.css") == SHA256_CSS_V030 # Remplacé en 0.45.11 : la re-vendange v0.4.0 (HUB-11)
assert _sha256("static/js/draco-barre.js") == SHA256_JS_V030 # supersède les empreintes v0.3.0 — les empreintes courantes
# sont verrouillées par tests/test_barre_v040.py. On garde ici
# la preuve que les fichiers ont bien quitté la v0.3.0.
assert _sha256("static/css/draco-barre.css") != SHA256_CSS_V030
assert _sha256("static/js/draco-barre.js") != SHA256_JS_V030
def test_js_liens_hub_et_profil_lien(): def test_js_liens_hub_et_profil_lien():
+52
View File
@@ -0,0 +1,52 @@
"""Barre commune v0.4.0 (HUB-11, fusion #125) — re-vendange 0.45.11.
- CSS/JS vendangés VERBATIM depuis dracodev-commons, branche
menu-compte-icones-v0-4-0 (PR commons #10), ui/barre-apps/.
- Menu compte : chaque item (Télécharger, À Propos, Aides,
Profil, Déconnexion) porte une icône SVG monoline construite
en DOM (contour, currentColor, sans remplissage), dans le
style des icônes du rail de la console — aucun emoji.
L'en-tête d'identité reste sans icône ; les liens Hub et le
relais « Déconnexion » sont inchangés depuis la v0.3.0.
"""
import hashlib
from pathlib import Path
R = Path(__file__).resolve().parents[1]
# Empreintes SHA-256 de la source commons v0.4.0
# (Projets/dracodev-commons, ui/barre-apps/, branche
# menu-compte-icones-v0-4-0 @e8ca99a).
SHA256_CSS_V040 = "d8cf53b2f6700ebc7499d43869d5cae256d1f74636f0113bffb174b8a6bd06ec"
SHA256_JS_V040 = "36cc24b2bfea757633a7cbcfded54fb73405d9f6fdbde1b4a8fb8df7ae5d39a0"
def _sha256(chemin):
return hashlib.sha256((R / chemin).read_bytes()).hexdigest()
def test_barre_css_js_verbatim_commons_v040():
assert _sha256("static/css/draco-barre.css") == SHA256_CSS_V040
assert _sha256("static/js/draco-barre.js") == SHA256_JS_V040
def test_js_icones_monoline_menu_compte():
js = (R / "static/js/draco-barre.js").read_text(encoding="utf-8")
assert "MENU_ICONES" in js
for nom in ("telecharger", "a-propos", "aide", "profil", "deconnexion"):
assert f'"{nom}"' in js
assert "draco-menu-icone" in js
assert 'setAttribute("stroke", "currentColor")' in js
assert 'setAttribute("fill", "none")' in js
# Comportements v0.3.0 conservés.
assert 'hub: "https://hub.dracodev.net/"' in js
assert '"profil", "Profil"' in js
assert 'data-compte-act", "deconnexion"' in js
def test_css_icone_menu_compte():
css = (R / "static/css/draco-barre.css").read_text(encoding="utf-8")
assert ".draco-menu-icone" in css
bloc = css.split(".draco-menu-icone {", 1)[1].split("}", 1)[0]
assert "width: 18px" in bloc
assert "var(--ink-2)" in bloc