From de1e7797708265d6f1f55f74563cd1957e232b5a Mon Sep 17 00:00:00 2001 From: AI Assistant Date: Sat, 7 Mar 2026 11:45:52 +0200 Subject: [PATCH] fix(parcel-sync): progress display stuck + numbers jumping during sync 2 bugs: 1. After Magic/base download completes, progress bar stayed stuck at 77% because exportProgress was never updated to 'done' client-side. Fix: set progress to 'Finalizat' + 100% after successful blob download. 2. syncLayer overwrote the export route's weighted percentages (0-100) with raw feature counts (50/200), causing progress bar to jump. Fix: when isSubStep=true, sync writes phase/note/phaseCurrent/phaseTotal but preserves the parent route's downloaded/total weighted values. --- .../components/parcel-sync-module.tsx | 30 +++++++++++++++++++ .../parcel-sync/services/sync-service.ts | 27 ++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/modules/parcel-sync/components/parcel-sync-module.tsx b/src/modules/parcel-sync/components/parcel-sync-module.tsx index 8464b48..c074234 100644 --- a/src/modules/parcel-sync/components/parcel-sync-module.tsx +++ b/src/modules/parcel-sync/components/parcel-sync-module.tsx @@ -579,6 +579,21 @@ export function ParcelSyncModule() { a.click(); a.remove(); URL.revokeObjectURL(url); + + // Mark progress as done after successful download + setExportProgress((prev) => + prev + ? { + ...prev, + status: "done", + phase: "Finalizat", + downloaded: prev.total ?? 100, + total: prev.total ?? 100, + message: `Descărcare completă — ${filename}`, + note: undefined, + } + : null, + ); } catch (error) { const msg = error instanceof Error ? error.message : "Eroare export"; setExportProgress((prev) => @@ -863,6 +878,21 @@ export function ParcelSyncModule() { a.click(); a.remove(); URL.revokeObjectURL(url); + + // Mark progress as done after successful download + setExportProgress((prev) => + prev + ? { + ...prev, + status: "done", + phase: "Finalizat", + downloaded: prev.total ?? 100, + total: prev.total ?? 100, + message: `Descărcare completă — ${filename}`, + note: undefined, + } + : null, + ); } catch (error) { const msg = error instanceof Error ? error.message : "Eroare export"; setExportProgress((prev) => diff --git a/src/modules/parcel-sync/services/sync-service.ts b/src/modules/parcel-sync/services/sync-service.ts index b005efc..3f68df9 100644 --- a/src/modules/parcel-sync/services/sync-service.ts +++ b/src/modules/parcel-sync/services/sync-service.ts @@ -13,6 +13,7 @@ import { findLayerById, type LayerCatalogItem } from "./eterra-layers"; import { fetchUatGeometry } from "./uat-geometry"; import { setProgress, + getProgress, clearProgress, type SyncProgress, } from "./progress-store"; @@ -62,6 +63,26 @@ export async function syncLayer( const push = (partial: Partial) => { if (!jobId) return; + if (isSubStep) { + // When running as sub-step of a larger export, only write + // phase/note/phaseCurrent/phaseTotal — preserve the parent's + // downloaded/total weighted percentages. + const existing = getProgress(jobId); + setProgress({ + jobId, + downloaded: existing?.downloaded ?? 0, + total: existing?.total, + status: "running", + ...existing, + // Only overwrite informational fields + phase: partial.phase ?? existing?.phase, + note: partial.note, + phaseCurrent: partial.downloaded, // map sync's downloaded → sub-detail + phaseTotal: partial.total, // map sync's total → sub-detail + message: partial.message, + } as SyncProgress); + return; + } setProgress({ jobId, downloaded: 0, @@ -287,7 +308,11 @@ export async function syncLayer( where: { id: syncRun.id }, data: { status: "error", errorMessage: msg, completedAt: new Date() }, }); - push({ phase: "Eroare sync", status: isSubStep ? "running" : "error", message: msg }); + push({ + phase: "Eroare sync", + status: isSubStep ? "running" : "error", + message: msg, + }); if (jobId && !isSubStep) setTimeout(() => clearProgress(jobId), 60_000); return { layerId,