Frontend half of the async staging scan. The endpoints now return {scanning, progress} while a
large staging folder is still being scanned in the background; the page surfaces that and fills in
automatically when it completes — no manual refresh, no timeout.
- types: ImportStagingFiles/GroupsPayload gain optional scanning + progress (additive).
- useImportStaging exposes `scanning`/`scanProgress` and, while scanning, polls via a plain
setInterval(refetch, 1500). Deliberately NOT react-query's refetchInterval — and a plain interval
that only runs while scanning leaves the normal + error query states completely untouched.
- the header shows "Scanning N of M files…" instead of a count while the scan runs.
vitest: new test asserts the scan-progress header renders from a {scanning} response; typecheck
clean. Note: -route.test.tsx's pre-existing "staging files fail to load" test fails only in the
full-file run (passes in isolation) — verified it also fails on clean dev with all my changes
stashed, so it's a pre-existing test-isolation flake, not from this change.
The two import behaviour toggles previously lived only in Settings → Import.
Mirror them onto the React Import page (above the processing queue) so they're
visible and adjustable right where you import.
- New ImportOptions component: two Switches ("Quality check on import",
"Use folder as artist") with optimistic update + immediate save.
- API: fetchImportOptions / saveImportOptions / importOptionsQueryOptions —
read the whole settings blob, POST a partial {import: {...}} (the settings
endpoint partial-merges, so the rest of config is untouched). Both default ON
when absent, matching the backend defaults.
- Same import.quality_filter_enabled / import.folder_artist_override config
keys as the Settings page, so the two stay in sync.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CubeComming had to dig through app.log to learn WHY a file failed ("integrity
check failed: Duration mismatch ..."). The reason was already returned in the
singles/process `errors` array and carried on the queue entry — the window just
showed "Failed" with no detail.
Now each failed file's reason renders under its row (red, left-bordered, with a
title tooltip for the full text). Pure presentation of data already present; no
API change. Vite build clean.
- thread primary_source through album and track search payloads while keeping per-result source on the returned rows
- reuse the shared Notice primitive for fallback and error messaging in the import pages
- update the import route tests and shell route smoke coverage for the new behavior
- let the singles action buttons use the default size again
- remove redundant type="button" props from import controls
- switch import page conditional classes to clsx object notation
- drop route-test assertions that pinned compact auto-import sizes
- move the import page over to shared button variants and option buttons
- strip route-local button chrome back to layout-only helpers
- keep the import route styling focused on layout, cards, and state indicators
- add shared Base UI-backed checkbox and slider primitives under the form component layer
- move the singles import checkbox and auto-import confidence slider to the shared controls
- keep the import route tests aligned with the new accessible component roles
- bring the React import page back in line with the legacy emoji/glyph treatment\n- restore album, singles, auto-import, and queue fallback icons\n- keep the visual refresh aligned with the old page while preserving the React port
- Move import page, tabs, workflow state, and route tests into React-owned route slices
- Preserve shell gating, staging queries, album matching, singles matching, auto-import, and queue behavior
- Add migration plan snapshot so cleanup/refinement can build on a stable baseline