- en-tête vitré sticky, navigation en pastilles avec état actif, logo en tuile dégradée, fil d'Ariane projet - dashboard: hero + tuiles de synthèse (actifs, fermées/déplacements 30 j, cycle moyen), barre de progression par projet, états vides guidés, raccourci clavier / - board: sélecteur de milestones + bandeau de progression, colonnes à défilement indépendant, placeholders de colonnes vides, hint sur le panneau de notes, toast et drawer animés - live.js: recharge douce conditionnelle (visible, pas de drawer, pas de saisie, pas de drag) sinon pastille d'actualisation - accessibilité: anneau de focus visible, prefers-reduced-motion, responsive retravaillé; board.js: drapeau de drag partagé avec live.js + raccourci / vers le filtre
45 lines
1.5 KiB
JavaScript
45 lines
1.5 KiB
JavaScript
// Kanbante — live updates via Server-Sent Events.
|
|
// When Gitea reports activity (webhook -> /api/stream), reload the
|
|
// page softly if it is safe (visible tab, no drawer open, no text
|
|
// being typed, no drag in progress); otherwise show a pill the
|
|
// user can click when ready.
|
|
(function () {
|
|
if (!window.EventSource) return;
|
|
|
|
var pill = null;
|
|
var timer = null;
|
|
|
|
function showPill() {
|
|
if (pill) return;
|
|
pill = document.createElement('button');
|
|
pill.id = 'live-pill';
|
|
pill.type = 'button';
|
|
pill.textContent = '🔄 Nouvelle activité Gitea — actualiser';
|
|
pill.addEventListener('click', function () { window.location.reload(); });
|
|
document.body.appendChild(pill);
|
|
}
|
|
|
|
function safeToReload() {
|
|
if (document.visibilityState !== 'visible') return false;
|
|
if (window.__kanbanteDragging) return false;
|
|
var drawer = document.getElementById('card-detail');
|
|
if (drawer && !drawer.hidden) return false;
|
|
var active = document.activeElement;
|
|
if (active && (active.tagName === 'TEXTAREA' ||
|
|
(active.tagName === 'INPUT' && active.type === 'text'))) return false;
|
|
return true;
|
|
}
|
|
|
|
function scheduleReload() {
|
|
if (timer) return;
|
|
timer = setTimeout(function () {
|
|
timer = null;
|
|
if (safeToReload()) window.location.reload();
|
|
else showPill();
|
|
}, 1200);
|
|
}
|
|
|
|
var source = new EventSource('/api/stream');
|
|
source.addEventListener('gitea', scheduleReload);
|
|
})();
|