Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
895ee81d51 | ||
|
|
d0ba39bf01 | ||
|
|
fc1b40cd98 | ||
|
|
5f184f033c | ||
|
|
d17f3e56b3 | ||
|
|
11b1b5f11d | ||
|
|
37fd4de63d | ||
|
|
1b218ce030 | ||
|
|
40f034e86e | ||
|
|
911f07362f | ||
|
|
ee837972be | ||
|
|
4470e6ccbc | ||
|
|
d8cb4664e5 | ||
|
|
f2e702a3d9 | ||
|
|
435954c31b |
@@ -1,3 +1,15 @@
|
||||
## 0.45.0 — 2026-10-29 — Mobile : tiroir, pied et menu compte
|
||||
|
||||
- **Tiroir mobile** : l'état « replié » mémorisé sur desktop ne rétrécit plus le tiroir (cause : `body.sidebar-collapsed .sidebar { width: 68px; }` gagnait par spécificité sur le 264 px mobile, libellés tronqués par overflow-x). Le tiroir fait 264 px, replié ou non ; le fond ne défile plus derrière lui ; le bouton de repli dans le tiroir le ferme ; un clic sur un lien de navigation le ferme aussi.
|
||||
- **Pied de sidebar visible en mobile** : version, fraîcheur des données, thème et Sortir sont désormais accessibles dans le tiroir (avant : pied masqué, aucun moyen de sortir depuis un téléphone).
|
||||
- **Menu compte draco** : Profil et Déconnexion fonctionnent enfin (ils étaient relayés par draco-barre.js mais jamais pris en charge par le onAction Kanbante — le menu se fermait sans rien faire). En mobile, c'était le seul accès au profil et à la déconnexion.
|
||||
- **Menus draco** : largeur plafonnée à 100vw - 20 px pour ne jamais déborder d'un petit écran.
|
||||
|
||||
## 0.44.0 — 2026-10-29 — Ergonomie : tuile Projets et pied de sidebar
|
||||
|
||||
- **Tuile Projets** : en-tête groupé (gauche : organisation + santé, droite : date + étoile + menu) au lieu de 5 éléments éparpillés ; avancement global labellisé (« Avancement — X/Y terminées ») au lieu d'une barre anonyme ; jalon séparé par un filet, avec étiquette « Prochain jalon » et échéance distincte ; pied en 2 rangées — (1) compte d'issues + bouton Board, (2) répartition par colonne labellisée (« En cours 8 », « Terminé 59 », au lieu de chiffres nus 8 / 59) + prévision ; activité de la semaine en texte secondaire (« Cette semaine : … »).
|
||||
- **Pied de sidebar** : 2 rangées séparées par un filet — (1) profil + bouton Sortir icône seule (⏻, aria-label, sans texte), (2) version + fraîcheur des données en pastille discrète (point vert + « à l'instant », infobulle expliquant les instantanés Gitea). En rail replié, la rangée méta est masquée, les icônes restent centrées.
|
||||
|
||||
## 0.43.0 — 2026-10-29 — Icônes monochromes sur tout le site (#59, suite)
|
||||
|
||||
- **Icônes colorées retirées de toutes les pages** : emoji décoratifs devant titres, boutons et liens supprimés (le texte porte le sens) ; icônes fonctionnelles passées en trait/monochrome — étoile ★/☆ (couleur texte, plus jaune), recherche en SVG, épingler déjà en SVG, thème ☀/☾ en symboles texte.
|
||||
|
||||
+1
-1
@@ -177,7 +177,7 @@ from urllib.parse import urlparse
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
APP_VERSION = "0.43.0"
|
||||
APP_VERSION = "0.45.0"
|
||||
|
||||
|
||||
def _env_bool(name: str, default: bool) -> bool:
|
||||
|
||||
@@ -103,6 +103,13 @@
|
||||
};
|
||||
if (act === "domaine") { try { localStorage.setItem("draco_domain", el.dataset.dom); } catch (e) { } return; }
|
||||
if (act === "rail") { var b = document.getElementById("side-collapse"); if (b) b.click(); return; }
|
||||
/* Menu compte (image 2) : ces deux actions étaient relayées
|
||||
par draco-barre.js mais jamais prises en charge ici —
|
||||
le menu se fermait sans rien faire. En mobile, c'est le
|
||||
seul accès au profil et à la déconnexion (le pied de
|
||||
sidebar était masqué). */
|
||||
if (act === "profil") { location.href = "/profile"; return; }
|
||||
if (act === "deconnexion") { location.href = "/logout"; return; }
|
||||
if (act === "palette") { location.href = "/recherche"; return; }
|
||||
if (act === "alertes") { if (window.DRACO_ALERTES) { window.DRACO_ALERTES.open(); } else { location.href = "/activity"; } return; }
|
||||
/* Correctif fusion #70 : action "menu" supprimée avec le bouton trois points (console agent dans le menu de la marque). */
|
||||
|
||||
+17
-13
@@ -137,19 +137,23 @@
|
||||
{% endfor %}
|
||||
</nav>
|
||||
<div class="side-foot">
|
||||
{% if data_freshness %}
|
||||
<span class="side-fresh side-label" title="Dernière actualisation des données Gitea (instantanés d'arrière-plan)">{{ data_freshness }}</span>
|
||||
{% endif %}
|
||||
{% if current_user %}
|
||||
<a href="/profile" class="side-logout" title="Mon profil"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" aria-hidden="true" style="width:18px;height:18px;display:inline-block;vertical-align:-3px"><circle cx="12" cy="8" r="3.5"/><path d="M4 20c0-3.5 3.5-5.5 8-5.5s8 2 8 5.5"/></svg><span class="side-label"> {{ current_user.display_name or current_user.username }}</span></a>
|
||||
{% endif %}
|
||||
<span class="side-version side-label">v{{ version }}</span>
|
||||
{% if not is_admin %}
|
||||
<button type="button" class="theme-toggle-foot" id="theme-toggle" title="Basculer entre thème sombre et clair" aria-label="Basculer entre thème sombre et clair"><span data-theme-ico>☀</span></button>
|
||||
{% endif %}
|
||||
{% if auth_enabled %}
|
||||
<a href="/logout" class="side-logout" title="Se déconnecter">⏻<span class="side-label"> Sortir</span></a>
|
||||
{% endif %}
|
||||
<div class="side-foot-user">
|
||||
{% if current_user %}
|
||||
<a href="/profile" class="side-logout side-profile" title="Mon profil"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" aria-hidden="true" style="width:18px;height:18px;display:inline-block;vertical-align:-3px"><circle cx="12" cy="8" r="3.5"/><path d="M4 20c0-3.5 3.5-5.5 8-5.5s8 2 8 5.5"/></svg><span class="side-label"> {{ current_user.display_name or current_user.username }}</span></a>
|
||||
{% endif %}
|
||||
{% if not is_admin %}
|
||||
<button type="button" class="theme-toggle-foot" id="theme-toggle" title="Basculer entre thème sombre et clair" aria-label="Basculer entre thème sombre et clair"><span data-theme-ico>☀</span></button>
|
||||
{% endif %}
|
||||
{% if auth_enabled %}
|
||||
<a href="/logout" class="side-logout logout-icon" title="Se déconnecter" aria-label="Se déconnecter">⏻</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="side-foot-meta">
|
||||
<span class="side-version side-label">v{{ version }}</span>
|
||||
{% if data_freshness %}
|
||||
<span class="side-fresh" title="Dernière actualisation des données Gitea (instantanés d'arrière-plan) — les données affichées datent de cet instantané"><span class="fresh-dot" aria-hidden="true"></span><span class="side-label">{{ data_freshness }}</span></span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
<div class="side-backdrop" id="side-backdrop" hidden></div>
|
||||
|
||||
@@ -91,14 +91,17 @@
|
||||
data-search="{{ (repo.name ~ ' ' ~ repo.full_name ~ ' ' ~ (repo.description or ''))|lower }}"
|
||||
x-show="search === '' || $el.dataset.search.includes(search.toLowerCase())">
|
||||
<div class="card-header">
|
||||
<span class="org-tag">{{ repo.owner.login }}</span>
|
||||
{% if multi_conn %}<span class="conn-badge" title="Connexion {{ repo._conn_slug }}">{% if repo._conn_kind == 'github' %}GitHub{% else %}Gitea{% endif %} {{ repo._conn_slug }}</span>{% endif %}
|
||||
{% if repo.health_dot %}
|
||||
<a href="/health/{{ full }}" class="health-dot {{ repo.health_dot.level }}" title="Santé du flux — {{ repo.health_dot.tooltip }}" aria-label="Santé du flux : {{ repo.health_dot.tooltip }}"></a>
|
||||
{% endif %}
|
||||
<span class="date">{{ repo.updated_at[:10] }}</span>
|
||||
{% if not archived %}
|
||||
<button type="button" class="star-btn" data-full="{{ full }}" data-starred="{{ 1 if repo.starred else 0 }}" title="{{ 'Désépingler (étoile Gitea)' if repo.starred else 'Épingler (étoile Gitea)' }}" aria-label="Épingler {{ repo.name }}">{{ '' if repo.starred else '☆' }}</button>
|
||||
<div class="card-header-left">
|
||||
<span class="org-tag">{{ repo.owner.login }}</span>
|
||||
{% if multi_conn %}<span class="conn-badge" title="Connexion {{ repo._conn_slug }}">{% if repo._conn_kind == 'github' %}GitHub{% else %}Gitea{% endif %} {{ repo._conn_slug }}</span>{% endif %}
|
||||
{% if repo.health_dot %}
|
||||
<a href="/health/{{ full }}" class="health-dot {{ repo.health_dot.level }}" title="Santé du flux — {{ repo.health_dot.tooltip }}" aria-label="Santé du flux : {{ repo.health_dot.tooltip }}"></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="card-header-actions">
|
||||
<span class="date" title="Dernière activité">{{ repo.updated_at[:10] }}</span>
|
||||
{% if not archived %}
|
||||
<button type="button" class="star-btn" data-full="{{ full }}" data-starred="{{ 1 if repo.starred else 0 }}" title="{{ 'Désépingler (étoile Gitea)' if repo.starred else 'Épingler (étoile Gitea)' }}" aria-label="Épingler {{ repo.name }}">{{ '' if repo.starred else '☆' }}</button>
|
||||
<div class="card-menu-wrap">
|
||||
<button type="button" class="card-menu-btn" data-menu-btn aria-haspopup="true" aria-expanded="false" title="Actions rapides pour {{ repo.name }}" aria-label="Actions rapides pour {{ repo.name }}">⋯</button>
|
||||
<div class="card-menu" hidden>
|
||||
@@ -115,26 +118,30 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<h3>
|
||||
<a href="/project/{{ repo.owner.login }}/{{ repo.name }}">{{ repo.name }}</a>
|
||||
</h3>
|
||||
<p class="desc">{{ repo.description or '—' }}</p>
|
||||
<p class="desc" title="{{ repo.description or '' }}">{{ repo.description or '—' }}</p>
|
||||
{% if full in stats %}
|
||||
{% set total = stats[full].values()|sum %}
|
||||
{% set done_n = stats[full].get('done', 0) %}
|
||||
{% if total > 0 %}
|
||||
<div class="progress" title="{{ done_n }}/{{ total }} terminées">
|
||||
<span style="width: {{ (100 * done_n / total)|round|int }}%"></span>
|
||||
<div class="card-progress">
|
||||
<div class="progress-head"><span>Avancement</span><span>{{ done_n }}/{{ total }} terminées</span></div>
|
||||
<div class="progress" title="{{ done_n }}/{{ total }} terminées">
|
||||
<span style="width: {{ (100 * done_n / total)|round|int }}%"></span>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if repo.next_milestone %}
|
||||
{% set ms = repo.next_milestone %}
|
||||
<div class="ms-block">
|
||||
<div class="ms-head"><span class="ms-kicker">Prochain jalon</span>{% if ms.due_label %}<span class="ms-due{% if ms.late %} late{% endif %}">échéance {{ ms.due_label }}</span>{% endif %}</div>
|
||||
<div class="ms-line">
|
||||
<a href="/forecast#ms-{{ repo.owner.login }}-{{ repo.name }}" class="ms-title" title="Voir ce jalon dans le tableau des prévisions">{{ ms.title }}</a>
|
||||
{% if ms.due_label %}<span class="ms-due{% if ms.late %} late{% endif %}">{{ '' if ms.late }}échéance {{ ms.due_label }}</span>{% endif %}
|
||||
</div>
|
||||
{% if ms.total %}
|
||||
<div class="progress ms-progress"><span style="width: {{ ms.pct }}%"></span></div>
|
||||
@@ -143,28 +150,32 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="card-footer">
|
||||
<span>{{ repo.open_issues_count or 0 }} issues ouvertes</span>
|
||||
<a href="/board/{{ full }}" class="card-board-link">Board</a>
|
||||
{% if repo.forecast_label %}
|
||||
<span class="forecast-line" title="Prévision d'après le débit réel du journal (fermetures par semaine)">{{ repo.forecast_label }}</span>
|
||||
{% endif %}
|
||||
{% if full in stats %}
|
||||
<div class="mini-progress">
|
||||
{% for col in column_keys %}
|
||||
{% set n = stats[full].get(col, 0) %}
|
||||
{% if n > 0 %}
|
||||
<span class="chip" style="background: color-mix(in srgb, {{ COLUMN_COLORS[col] }} 25%, transparent); color: var(--text)">
|
||||
{{ n }}
|
||||
</span>
|
||||
<div class="foot-main">
|
||||
<span class="foot-count">{{ repo.open_issues_count or 0 }} issues ouvertes</span>
|
||||
<a href="/board/{{ full }}" class="card-board-link btn-sm">Board →</a>
|
||||
</div>
|
||||
<div class="foot-dist">
|
||||
{% if full in stats %}
|
||||
<div class="mini-progress" aria-label="Répartition par colonne">
|
||||
{% for col in column_keys %}
|
||||
{% set n = stats[full].get(col, 0) %}
|
||||
{% if n > 0 %}
|
||||
<span class="chip" title="{{ COLUMN_LABELS[col] }}" style="background: color-mix(in srgb, {{ COLUMN_COLORS[col] }} 25%, transparent); color: var(--text)">
|
||||
{{ COLUMN_LABELS[col] }} {{ n }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if repo.forecast_label %}
|
||||
<span class="forecast-line" title="Prévision d'après le débit réel du journal (fermetures par semaine)">{{ repo.forecast_label }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if repo.activity %}
|
||||
<div class="activity-line">
|
||||
{% if repo.activity.closed or repo.activity.moved %}
|
||||
{{ repo.activity.closed }} fermée(s) · {{ repo.activity.moved }} déplacement(s) cette semaine
|
||||
Cette semaine : {{ repo.activity.closed }} fermée(s) · {{ repo.activity.moved }} déplacement(s)
|
||||
{% elif repo.activity.idle_days is not none and repo.activity.idle_days > 7 %}
|
||||
aucune activité kanban depuis {{ repo.activity.idle_days }} j
|
||||
{% endif %}
|
||||
|
||||
+83
-14
@@ -315,8 +315,15 @@ a.kpi:hover { background: var(--surface-2); text-decoration: none; }
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
gap: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.card-header-left, .card-header-actions {
|
||||
display: flex; align-items: center; gap: 8px; min-width: 0;
|
||||
}
|
||||
.card-header-actions { flex-shrink: 0; }
|
||||
.card-header .date { white-space: nowrap; }
|
||||
.card-header .star-btn { margin-left: 0; }
|
||||
.org-tag {
|
||||
font-size: 0.68rem;
|
||||
text-transform: uppercase;
|
||||
@@ -340,20 +347,33 @@ a.kpi:hover { background: var(--surface-2); text-decoration: none; }
|
||||
min-height: 2.4em;
|
||||
}
|
||||
.card-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-2);
|
||||
gap: 10px;
|
||||
display: flex; flex-direction: column; align-items: stretch;
|
||||
font-size: 0.8rem; color: var(--text-2); gap: 10px;
|
||||
border-top: 1px solid var(--border);
|
||||
padding-top: 12px; margin-top: 14px;
|
||||
}
|
||||
.mini-progress { display: flex; gap: 4px; }
|
||||
.foot-main, .foot-dist {
|
||||
display: flex; justify-content: space-between; align-items: center;
|
||||
gap: 10px; flex-wrap: wrap;
|
||||
}
|
||||
.foot-count { font-weight: 600; color: var(--text); }
|
||||
.card-board-link.btn-sm { text-decoration: none; }
|
||||
.mini-progress { display: flex; gap: 4px; flex-wrap: wrap; }
|
||||
.mini-progress .chip { white-space: nowrap; }
|
||||
.forecast-line { white-space: nowrap; }
|
||||
.chip {
|
||||
padding: 2px 9px;
|
||||
border-radius: var(--radius-full);
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
.card-progress { margin-bottom: 12px; }
|
||||
.progress-head {
|
||||
display: flex; justify-content: space-between; align-items: baseline;
|
||||
gap: 10px; margin-bottom: 6px;
|
||||
font-size: 0.78rem; color: var(--text-2);
|
||||
}
|
||||
.progress-head span:last-child { font-weight: 600; color: var(--text); white-space: nowrap; }
|
||||
.progress {
|
||||
height: 6px;
|
||||
border-radius: var(--radius-full);
|
||||
@@ -1387,7 +1407,24 @@ body.nav-closed-admin [data-group="admin"] .side-chevron { transform: rotate(-90
|
||||
.theme-toggle-foot:hover { color: var(--text); }
|
||||
.side-foot {
|
||||
margin-top: auto; padding-top: 12px;
|
||||
display: flex; align-items: center; justify-content: space-between; gap: 8px;
|
||||
display: flex; flex-direction: column; align-items: stretch; gap: 8px;
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
.side-foot-user { display: flex; align-items: center; gap: 8px; }
|
||||
.side-foot-user .side-profile { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
||||
.side-logout.logout-icon {
|
||||
width: 36px; height: 36px; flex-shrink: 0;
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
border: 1px solid var(--border); border-radius: var(--radius-sm);
|
||||
}
|
||||
.side-logout.logout-icon:hover { border-color: var(--accent, #0d9488); }
|
||||
.side-foot-meta {
|
||||
display: flex; justify-content: space-between; align-items: center; gap: 8px;
|
||||
}
|
||||
.fresh-dot {
|
||||
width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
|
||||
background: var(--accent-2); display: inline-block; margin-right: 6px;
|
||||
vertical-align: 1px;
|
||||
}
|
||||
.side-collapse {
|
||||
/* Depuis la 0.22.0 : bouton icône seule dans l'en-tête de la
|
||||
@@ -1403,7 +1440,7 @@ body.nav-closed-admin [data-group="admin"] .side-chevron { transform: rotate(-90
|
||||
color: var(--text); border-color: var(--accent, #0d9488);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
.side-fresh { color: var(--text-3); font-size: 0.76rem; white-space: nowrap; }
|
||||
.side-fresh { color: var(--text-3); font-size: 0.76rem; white-space: nowrap; display: inline-flex; align-items: center; }
|
||||
.side-logout { color: var(--text-3); font-size: 0.85rem; white-space: nowrap; }
|
||||
.side-logout:hover { color: var(--text); text-decoration: none; }
|
||||
.side-collapse-ico { display: inline-block; transition: transform 0.18s ease; }
|
||||
@@ -1412,7 +1449,9 @@ body.sidebar-collapsed .side-collapse-ico { transform: rotate(180deg); }
|
||||
body.sidebar-collapsed .side-label { display: none; }
|
||||
body.sidebar-collapsed .side-link { justify-content: center; padding-left: 0; padding-right: 0; }
|
||||
body.sidebar-collapsed .side-logo { justify-content: center; padding-left: 0; padding-right: 0; }
|
||||
body.sidebar-collapsed .side-foot { justify-content: center; }
|
||||
body.sidebar-collapsed .side-foot { align-items: center; }
|
||||
body.sidebar-collapsed .side-foot-meta { display: none; }
|
||||
body.sidebar-collapsed .side-foot-user { justify-content: center; }
|
||||
.side-backdrop {
|
||||
position: fixed; inset: 0; z-index: 190;
|
||||
background: rgba(4, 6, 10, 0.55);
|
||||
@@ -1423,12 +1462,30 @@ body.sidebar-collapsed .side-foot { justify-content: center; }
|
||||
body.with-sidebar, body.with-sidebar.sidebar-collapsed { padding-left: 0; }
|
||||
.sidebar { width: 264px; transform: translateX(-105%); box-shadow: none; }
|
||||
body.sidebar-open .sidebar { transform: none; box-shadow: 18px 0 44px rgba(0,0,0,.5); }
|
||||
/* Tiroir mobile : l'état « replié » mémorisé sur desktop ne doit
|
||||
JAMAIS rétrécir le tiroir. Avant, `body.sidebar-collapsed
|
||||
.sidebar { width: 68px; }` (spécificité supérieure à `.sidebar`)
|
||||
gagnait en mobile : libellés tronqués par overflow-x hidden,
|
||||
exactement la capture image 1. Le tiroir fait 264 px, replié
|
||||
ou non, et le fond ne défile plus derrière lui. */
|
||||
body.sidebar-collapsed .sidebar,
|
||||
body.sidebar-open.sidebar-collapsed .sidebar { width: 264px; }
|
||||
body.sidebar-open { overflow: hidden; }
|
||||
body.sidebar-collapsed .side-label { display: initial; }
|
||||
body.sidebar-collapsed .side-link { justify-content: flex-start; padding-left: 10px; padding-right: 10px; }
|
||||
body.sidebar-collapsed .side-logo { justify-content: flex-start; padding-left: 8px; padding-right: 8px; }
|
||||
body.sidebar-collapsed .side-head { flex-direction: row; padding: 4px 6px 12px; }
|
||||
body.sidebar-collapsed .side-search { margin-left: auto; }
|
||||
.side-foot { display: none; }
|
||||
/* Pied visible dans le tiroir (avant : display:none en mobile —
|
||||
aucun moyen de voir la version, la fraîcheur, le thème ni de
|
||||
sortir depuis un téléphone). */
|
||||
.side-foot { display: flex; }
|
||||
body.sidebar-collapsed .side-foot { align-items: stretch; }
|
||||
body.sidebar-collapsed .side-foot-meta { display: flex; }
|
||||
body.sidebar-collapsed .side-foot-user { justify-content: flex-start; }
|
||||
.topbar-search { display: inline-flex; }
|
||||
/* Menus draco (vendangés) : jamais plus larges que l'écran. */
|
||||
header.draco-bar .draco-compte-menu, header.draco-bar .draco-apps-menu { max-width: calc(100vw - 20px); }
|
||||
}
|
||||
|
||||
/* ── Dashboard vague 2 (0.17.0, #17 #18 #20) + page Projet (#25) ── */
|
||||
@@ -1449,7 +1506,19 @@ body.sidebar-collapsed .side-foot { justify-content: center; }
|
||||
.star-btn:hover { transform: scale(1.2); }
|
||||
.star-btn:disabled { opacity: 0.5; }
|
||||
.card-board-link { font-weight: 600; }
|
||||
.ms-block { margin: 10px 0 2px; }
|
||||
.ms-block {
|
||||
margin: 14px 0 2px; padding-top: 12px;
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
.ms-head {
|
||||
display: flex; justify-content: space-between; align-items: baseline;
|
||||
gap: 10px; margin-bottom: 6px;
|
||||
}
|
||||
.ms-kicker {
|
||||
font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.6px;
|
||||
color: var(--text-3); font-weight: 700;
|
||||
}
|
||||
.ms-block .ms-line { margin-bottom: 2px; }
|
||||
.ms-line { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
|
||||
.ms-title { font-weight: 600; font-size: 0.92rem; }
|
||||
.ms-due { font-size: 0.8rem; color: var(--text-2); white-space: nowrap; }
|
||||
@@ -1485,7 +1554,7 @@ body.sidebar-collapsed .side-foot { justify-content: center; }
|
||||
.proj-notes-body { white-space: pre-wrap; font-size: 0.93rem; background: var(--surface-2); border-radius: 10px; padding: 12px 14px; }
|
||||
|
||||
/* ── Dashboard vague 2 suite (0.18.0, #19 #21 #22 #23) ── */
|
||||
.activity-line { margin-top: 8px; font-size: 0.82rem; color: var(--text-2); }
|
||||
.activity-line { margin-top: 10px; font-size: 0.78rem; color: var(--text-3); }
|
||||
/* Barre d'outils unique du dashboard (0.20.0) : onglets
|
||||
segmentés, filtre, tri, regroupement et vue dans UN cadre. */
|
||||
.dash-toolbar {
|
||||
|
||||
@@ -63,8 +63,18 @@
|
||||
});
|
||||
}
|
||||
|
||||
/* En mobile, le bouton de repli dans le tiroir FERME le tiroir :
|
||||
replier un tiroir de 264 px n'a pas de sens, et avant ce
|
||||
correctif il basculait l'état desktop (tiroir 68 px). */
|
||||
var sideLinks = document.querySelectorAll('.side-link');
|
||||
sideLinks.forEach(function (link) {
|
||||
link.addEventListener('click', function () {
|
||||
if (window.innerWidth <= 900) closeDrawer();
|
||||
});
|
||||
});
|
||||
if (collapseBtn) {
|
||||
collapseBtn.addEventListener('click', function () {
|
||||
if (window.innerWidth <= 900) { closeDrawer(); return; }
|
||||
var collapsed = document.body.classList.toggle('sidebar-collapsed');
|
||||
try {
|
||||
localStorage.setItem('kanbante-sidebar', collapsed ? 'collapsed' : 'open');
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
"""Mobile : tiroir, pied et menu compte.
|
||||
|
||||
Bugs signalés sur captures (29 octobre 2026) :
|
||||
- tiroir rétréci à 68 px en mobile quand l'état « replié » desktop
|
||||
était mémorisé (spécificité de `body.sidebar-collapsed .sidebar`) ;
|
||||
- pied de sidebar masqué en mobile (`display: none`) ;
|
||||
- Profil / Déconnexion du menu compte draco sans effet (onAction
|
||||
ne les prenait pas en charge).
|
||||
"""
|
||||
|
||||
|
||||
def test_tiroir_mobile_largeur_fixe():
|
||||
css = open("static/css/style.css", encoding="utf-8").read()
|
||||
assert "body.sidebar-collapsed .sidebar,\n body.sidebar-open.sidebar-collapsed .sidebar { width: 264px; }" in css
|
||||
assert "body.sidebar-open { overflow: hidden; }" in css
|
||||
|
||||
|
||||
def test_pied_visible_en_mobile():
|
||||
css = open("static/css/style.css", encoding="utf-8").read()
|
||||
assert ".side-foot { display: none; }" not in css
|
||||
assert "body.sidebar-collapsed .side-foot-meta { display: flex; }" in css
|
||||
|
||||
|
||||
def test_menu_compte_draco_fonctionnel():
|
||||
tpl = open("app/templates/_draco_bar.html", encoding="utf-8").read()
|
||||
assert 'act === "profil"' in tpl
|
||||
assert 'location.href = "/profile"' in tpl
|
||||
assert 'act === "deconnexion"' in tpl
|
||||
assert 'location.href = "/logout"' in tpl
|
||||
|
||||
|
||||
def test_tiroir_ferme_en_mobile():
|
||||
js = open("static/js/nav.js", encoding="utf-8").read()
|
||||
assert "window.innerWidth <= 900" in js
|
||||
assert "querySelectorAll('.side-link')" in js
|
||||
@@ -19,7 +19,7 @@ def test_activity_line_recent_week(client, fake_gitea):
|
||||
from_column="backlog", to_column="todo",
|
||||
created_at=_ts(0))
|
||||
page = client.get("/")
|
||||
assert "2 fermée(s) · 1 déplacement(s) cette semaine" in page.text
|
||||
assert "Cette semaine : 2 fermée(s) · 1 déplacement(s)" in page.text
|
||||
|
||||
|
||||
def test_activity_line_idle_project(client, fake_gitea):
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
"""Tuile Projets et pied de sidebar : ergonomie refondue.
|
||||
|
||||
Tuile : en-tête groupé, avancement labellisé, jalon étiqueté,
|
||||
pied en 2 rangées avec répartition labellisée par colonne.
|
||||
Pied : Sortir icône seule, fraîcheur en pastille discrète.
|
||||
"""
|
||||
|
||||
|
||||
def test_tuile_structure(client, fake_gitea):
|
||||
page = client.get("/")
|
||||
assert 'class="card-header-left"' in page.text
|
||||
assert 'class="card-header-actions"' in page.text
|
||||
assert 'class="foot-main"' in page.text
|
||||
assert 'class="foot-dist"' in page.text
|
||||
# Répartition, avancement et jalon sont conditionnels (stats /
|
||||
# jalon) : on les vérifie dans le gabarit, pas dans la page de
|
||||
# test sans données.
|
||||
tpl = open("app/templates/dashboard.html", encoding="utf-8").read()
|
||||
assert 'aria-label="Répartition par colonne"' in tpl
|
||||
assert 'class="progress-head"' in tpl
|
||||
assert "Avancement" in tpl
|
||||
assert 'class="ms-kicker">Prochain jalon' in tpl
|
||||
assert "COLUMN_LABELS[col]" in tpl
|
||||
|
||||
|
||||
def test_pied_sidebar_structure():
|
||||
tpl = open("app/templates/_header.html", encoding="utf-8").read()
|
||||
assert 'class="side-foot-user"' in tpl
|
||||
assert 'class="side-foot-meta"' in tpl
|
||||
assert 'class="side-logout logout-icon"' in tpl
|
||||
assert 'aria-label="Se déconnecter"' in tpl
|
||||
assert " Sortir</span>" not in tpl
|
||||
assert 'class="fresh-dot"' in tpl
|
||||
css = open("static/css/style.css", encoding="utf-8").read()
|
||||
assert ".side-foot-meta" in css
|
||||
assert ".fresh-dot" in css
|
||||
assert ".logout-icon" in css
|
||||
Reference in New Issue
Block a user