fix discrepancy ui
Continuous Integration / backend-tests (push) Successful in 44s
Continuous Integration / frontend-check (push) Successful in 25s
Continuous Integration / e2e-tests (push) Successful in 7m1s

This commit is contained in:
2026-05-01 23:26:29 -04:00
parent 351bc169c5
commit c303e73071
5 changed files with 28 additions and 20 deletions
+11 -1
View File
@@ -11,7 +11,7 @@ from typing import Any, Dict, List, Optional, Tuple
import psutil
from loguru import logger
from sqlalchemy.orm import Session
from sqlalchemy.orm.exc import StaleDataError
from sqlalchemy.orm.exc import ObjectDeletedError, StaleDataError
from app.db import models
from app.db.database import SessionLocal
@@ -911,6 +911,16 @@ class ScannerService:
)
JobManager.complete_job(hashing_job.id)
except ObjectDeletedError:
logger.debug(
"Background hashing aborted: Job was deleted by another process"
)
# Exit gracefully - another process cancelled this job
try:
with self._metrics_lock:
self.is_hashing = False
except Exception:
pass
except Exception as e:
logger.error(f"Background hashing failed: {e}")
# Try to report failure, but don't blow up if JobManager fails too
@@ -35,7 +35,7 @@
onNavigate = (path: string) => {},
onToggleTrack = (item: FileItem) => {},
onSelect = (item: FileItem) => {},
onUndoDismiss = (item: FileItem) => {},
onAddToCart = (item: FileItem) => {},
onDelete = (item: FileItem) => {},
mode = "host",
isSearching = false,
@@ -47,7 +47,7 @@
onNavigate?: (path: string) => void;
onToggleTrack?: (item: FileItem) => void;
onSelect?: (item: FileItem) => void;
onUndoDismiss?: (item: FileItem) => void;
onAddToCart?: (item: FileItem) => void;
onDelete?: (item: FileItem) => void;
mode?: "host" | "index" | "cart" | "live" | "discrepancies";
isSearching?: boolean;
@@ -605,7 +605,7 @@
onClick={(e) => handleRowClick(e, item)}
onDoubleClick={() => handleRowDoubleClick(item)}
onToggleTrack={() => onToggleTrack(item)}
onUndoDismiss={() => onUndoDismiss(item)}
onAddToCart={() => onAddToCart(item)}
onDelete={() => onDelete(item)}
/>
{/each}
@@ -14,7 +14,6 @@
ShieldAlert,
Square,
EyeOff,
Undo2,
Trash2
} from "lucide-svelte";
import { Checkbox } from "$lib/components/ui/checkbox";
@@ -29,7 +28,7 @@
onClick = (e: MouseEvent) => {},
onDoubleClick = () => {},
onToggleTrack = () => {},
onUndoDismiss = () => {},
onAddToCart = () => {},
onDelete = () => {},
mode = "host",
colWidths = { mtime: 200, type: 150, size: 120 }
@@ -40,7 +39,7 @@
onClick?: (e: MouseEvent) => void;
onDoubleClick?: () => void;
onToggleTrack?: () => void;
onUndoDismiss?: () => void;
onAddToCart?: () => void;
onDelete?: () => void;
mode?: "host" | "index" | "live" | "cart" | "discrepancies";
colWidths?: { mtime: number; type: number; size: number };
@@ -251,15 +250,15 @@
<!-- QUICK ACTIONS -->
<div class="w-24 shrink-0 flex items-center justify-end gap-1 px-2">
{#if mode === "discrepancies"}
{#if item.discrepancy_id}
{#if item.discrepancy_id && item.has_versions && !item.is_deleted}
<Button
variant="ghost"
size="icon"
class="h-7 w-7 text-text-secondary hover:text-blue-400 hover:bg-blue-500/10"
onclick={(e: MouseEvent) => { e.stopPropagation(); onUndoDismiss(); }}
title="Undo dismiss"
class="h-7 w-7 text-text-secondary hover:text-green-400 hover:bg-green-500/10"
onclick={(e: MouseEvent) => { e.stopPropagation(); onAddToCart(); }}
title="Add to restore cart"
>
<Undo2 size={14} />
<CassetteTape size={14} />
</Button>
{/if}
{#if item.is_deleted}
@@ -80,16 +80,15 @@
}
}
async function undoDismiss(item: FileItem) {
async function addToCart(item: FileItem) {
if (!item.discrepancy_id) return;
try {
await dismissDiscrepancySystemDiscrepanciesFileIdDismissPost({
await addFileToRecoveryQueueRestoresQueueFileFileIdPost({
path: { file_id: item.discrepancy_id }
});
toast.success("Dismissal undone");
await loadDiscrepancies();
toast.success("Added to restore cart");
} catch (error: any) {
toast.error(error.body?.detail || "Failed to undo dismiss");
toast.error(error.body?.detail || "Failed to add to restore cart");
}
}
@@ -184,7 +183,7 @@
files={files}
mode="discrepancies"
onNavigate={navigateTo}
onUndoDismiss={undoDismiss}
onAddToCart={addToCart}
onDelete={deletePermanently}
/>
</div>
+2 -2
View File
@@ -330,8 +330,8 @@ test.describe('Discrepancies', () => {
await expect(page.getByText('Files missing from disk or confirmed deleted')).toBeVisible();
console.log('Step 3: Verify summary cards are visible');
await expect(page.locator('span').filter({ hasText: 'Missing from disk' }).first()).toBeVisible();
await expect(page.locator('span').filter({ hasText: 'Pending confirmation' }).first()).toBeVisible();
await expect(page.locator('span').filter({ hasText: 'Missing with no backup' }).first()).toBeVisible();
await expect(page.locator('span').filter({ hasText: 'Missing with backup' }).first()).toBeVisible();
await requestContext.dispose();
});