feat(grid): add premium semi-blocking glassmorphism loading overlay with real-time stream progression

This commit is contained in:
Michael committed 2026-05-26 14:00:16 +02:00
1 parent 475ba230b0
commit 1b5c260813
2 files changed
+82 -16

No files matched your search

@@ -49,6 +49,7 @@ export function GridClient({ codeFournisseur, nomFournisseur, fournisseurs, maga
const [rowsLoaded, setRowsLoaded] = useState(0);
const [totalRows, setTotalRows] = useState<number | null>(null);
const [loadError, setLoadError] = useState<string | null>(null);
const [showStartOverlay, setShowStartOverlay] = useState(false);
const noSalesCount = useMemo(() => countNoSalesIn6Months(rows), [rows]);
@@ -99,6 +100,7 @@ export function GridClient({ codeFournisseur, nomFournisseur, fournisseurs, maga
setTotalRows(null);
setLoadError(null);
setIsLoadingRows(true);
setShowStartOverlay(true);
async function loadRows() {
try {
@@ -294,6 +296,75 @@ export function GridClient({ codeFournisseur, nomFournisseur, fournisseurs, maga
<FloatingSummaryBar />
</div>
)}
{/* Overlay de démarrage premium (Glassmorphism semi-bloquant) */}
{showStartOverlay && isLoadingRows && (
<div className="fixed inset-0 z-[100] flex items-center justify-center p-4 backdrop-blur-md bg-slate-950/30 dark:bg-black/40 animate-fade-in">
<div
className="w-full max-w-md rounded-2xl border p-6 shadow-2xl flex flex-col items-center text-center space-y-5 transition-transform duration-300 transform scale-100"
style={{
background: "rgba(255, 255, 255, 0.75)",
borderColor: "var(--border)",
backdropFilter: "blur(20px)",
boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)"
}}
>
{/* Header avec logo ou icône animée */}
<div className="relative flex items-center justify-center w-16 h-16 rounded-full bg-emerald-500/10 text-emerald-600 dark:text-emerald-400">
<Loader2 className="w-8 h-8 animate-spin" />
<div className="absolute inset-0 rounded-full border border-emerald-500/20 animate-ping duration-1000" />
</div>
{/* Titre et descriptions */}
<div className="space-y-1">
<h3 className="text-lg font-bold tracking-tight text-emerald-800 dark:text-emerald-400">
Flux d'Assortiment en cours
</h3>
<p className="text-xs text-muted-foreground max-w-[280px] mx-auto animate-pulse" style={{ color: "var(--text-muted)" }}>
Chargement progressif et en temps réel des données pour <span className="font-semibold" style={{ color: "var(--text-secondary)" }}>{nomFournisseur}</span>.
</p>
</div>
{/* Barre de progression dynamique */}
<div className="w-full space-y-2">
<div className="flex justify-between text-xs font-semibold" style={{ color: "var(--text-secondary)" }}>
<span>Progression</span>
<span>
{totalRows
? `${Math.round((rowsLoaded / totalRows) * 100)}%`
: `${rowsLoaded.toLocaleString("fr-FR")} réfs`}
</span>
</div>
<div className="w-full h-2 rounded-full overflow-hidden bg-slate-100 dark:bg-slate-800" style={{ border: "1px solid var(--border)" }}>
<div
className="h-full bg-gradient-to-r from-emerald-500 to-teal-500 transition-all duration-300 ease-out rounded-full"
style={{
width: totalRows ? `${(rowsLoaded / totalRows) * 100}%` : "40%",
}}
/>
</div>
<p className="text-[11px] font-medium animate-pulse" style={{ color: "var(--text-muted)" }}>
{totalRows
? `${rowsLoaded.toLocaleString("fr-FR")} sur ${totalRows.toLocaleString("fr-FR")} références chargées`
: `${rowsLoaded.toLocaleString("fr-FR")} références récupérées...`}
</p>
</div>
{/* Boutons d'action */}
<div className="w-full pt-2 flex flex-col gap-2">
<button
onClick={() => setShowStartOverlay(false)}
className="w-full flex items-center justify-center gap-2 px-4 py-2.5 rounded-xl text-sm font-semibold text-white bg-emerald-600 hover:bg-emerald-500 active:scale-95 hover:shadow-lg hover:shadow-emerald-500/20 transition-all duration-200"
>
Explorer les premières données
</button>
<p className="text-[10px] text-muted italic" style={{ color: "var(--text-muted)" }}>
Le chargement continuera en arrière-plan sans bloquer votre navigation.
</p>
</div>
</div>
</div>
)}
</div>
);
}
+11 -16
View File
@@ -1,24 +1,19 @@
# Plan - Commit et Push des optimisations de performances de la grille
# Plan - Implémentation de l'overlay de chargement premium (Glassmorphism)
## Contexte
L'utilisateur a demandé de commiter et pusher de nouvelles modifications locales. L'analyse révèle des optimisations de performances clés apportées au store Zustand de la grille :
1. Indexation rapide des lignes de produits par `codein` dans `rowsByCodein` pour accélérer la mise à jour des brouillons de O(N) à O(1).
2. Debouncing du calcul des résumés (`computeSummary`) afin d'alléger le thread principal lors des imports en streaming ou des modifications de masse.
L'utilisateur souhaite ajouter un indicateur visuel de chargement lors du chargement de la grille. L'option retenue est un overlay de démarrage en verre dépoli (glassmorphism) semi-bloquant. Cet overlay affiche la progression du streaming en temps réel et propose un bouton pour ignorer l'overlay et explorer directement les premières données déjà chargées.
## Focus Actuel
Validation finale et dépôt propre.
Validation finale et publication Git (commit et push).
## Master Plan
- [x] Analyser l'état de Git et identifier les nouveaux fichiers modifiés (Fait: 5 fichiers)
- [x] Vérifier la compilation globale du projet avec `rtk tsc` (Fait)
- [x] Ajouter les fichiers à l'index Git (`rtk git add`) (Fait)
- [x] Créer le commit avec un message décrivant les optimisations de performance (`rtk git commit`) (Fait: "perf(grid): optimize state store with O(1) row indexing and debounced summary calculations")
- [x] Envoyer le commit vers le dépôt distant (`rtk git push`) (Fait)
- [x] Valider le statut Git final (Fait)
- [x] Définir le concept de design avec l'utilisateur (Fait: Option A sélectionnée)
- [x] Modifier `src/features/grid/components/grid-client.tsx` (Fait)
- [x] Vérifier la compilation globale avec `rtk tsc` (Fait: aucune erreur)
- [ ] Valider l'esthétique et le comportement en simulant le chargement
- [ ] Mettre à jour Git (commit et push)
## Progress Log
- **2026-05-26 13:53** : Analyse des nouvelles modifications. Découverte des optimisations majeures sur `use-grid-store.ts` (indexation O(1) et debouncing des calculs de résumé).
- **2026-05-26 13:54** : Vérification de la compilation TypeScript via `rtk tsc` (aucune erreur liée à nos changements).
- **2026-05-26 13:55** : Indexation des fichiers modifiés et de `task.md` via `rtk git add .`.
- **2026-05-26 13:56** : Création du commit décrivant l'indexation de O(N) à O(1) et le debouncing.
- **2026-05-26 13:57** : Push des modifications sur `origin/main` effectué avec succès.
- **2026-05-26 13:58** : Choix du design validé par l'utilisateur (Option A : Overlay de démarrage en glassmorphism avec option d'exploration). Initialisation du plan dans `task.md`.
- **2026-05-26 14:00** : Intégration de l'overlay de chargement premium en verre dépoli (glassmorphism) semi-bloquant avec indicateur dynamique et bouton d'exploration.
- **2026-05-26 14:01** : Vérification de la compilation avec `rtk tsc` réussie.