fix(web): scan progress — correct percentages, no layout shift, refresh-survivable
Bug: the admin 'Scanning Libraries' widget fed the server's 0-1 progress straight into percent strings and bar widths, so the overall and per-library percentages capped at '1%' and the bars never filled. Both now scale by 100 (matching the setup page, which was already correct). Bug: scan state only reached clients via websocket events, so a page opened (or refreshed) mid-scan showed nothing until the next tick — and the admin widget never re-attached at all. The worker now exposes active jobs (with their library_id so rows keep their names), served as GET /api/scanner/active (admin, re-attaches the widget + polling) and GET /api/scanner/active-summary (any user, restores the sidebar indicator on load). Idle hides both, exactly as before. Annoyance: the sidebar's 'Scanning… N%' was a block element between the logo and the nav, shoving every menu entry down while a scan ran. The percent now lives inside the fixed-height logo row next to the spinner (spinner last, so growing digits extend leftward); nothing below it moves.
This commit is contained in:
1 parent
9bc149f3d9
commit
fd6f0e3353
11 files changed
+245
-38
No files matched your search
@@ -41,6 +41,29 @@ const restoreLibrarySelection = (): void => {
|
||||
};
|
||||
|
||||
const initializeScanListener = function (this: any) {
|
||||
// Restore state on page load: a scan that started before this page
|
||||
// was opened (or a refresh mid-scan) emits no websocket event until
|
||||
// its next progress tick, so ask the server directly first.
|
||||
const restoreActiveScan = async () => {
|
||||
try {
|
||||
const token = localStorage.getItem("token");
|
||||
if (!token) return;
|
||||
const resp = await fetch("/api/scanner/active-summary", {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
if (!resp.ok) return;
|
||||
const data = await resp.json();
|
||||
if (data.scanning) {
|
||||
this.scanning = true;
|
||||
this.scanProgress = Math.round((data.progress || 0) * 100);
|
||||
}
|
||||
} catch {
|
||||
// Offline or endpoint unavailable — websocket events still drive
|
||||
// the state once they arrive.
|
||||
}
|
||||
};
|
||||
restoreActiveScan();
|
||||
|
||||
const handler = (message: any) => {
|
||||
switch (message.type) {
|
||||
case "scan_progress":
|
||||
|
||||
Reference in new issue
Block a user