11 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | |||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 11-per-library-scan-pipeline | 02 | execute | 2 |
|
|
true |
|
|
Purpose: Fulfill LSCAN-03 (progress identifies which library) and LSCAN-04 frontend (cancel/pause work per-library with clear scope). Output: Updated config-page with library-aware cancel dialog, library-manager with Scan All button, Wails binding stubs.
<execution_context> @/home/caleb/.config/opencode/get-shit-done/workflows/execute-plan.md @/home/caleb/.config/opencode/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/phases/11-per-library-scan-pipeline/11-CONTEXT.md @.planning/phases/11-per-library-scan-pipeline/11-01-SUMMARY.md @.planning/phases/09-scan-cancellation-keyboard-shortcuts/09-03-SUMMARY.mdUpdated ScanProgress payload (from backend/library/metrics.go after Plan 01):
interface ScanProgress {
phase: 'counting' | 'scanning' | 'orphans' | 'thumbnails';
total: number;
processed: number;
added: number;
skipped: number;
updated: number;
libraryId: number; // NEW — which library is scanning
libraryName: string; // NEW — display name
queuedCount: number; // NEW — libraries still queued
}
New Wails-bound methods (from Plan 01):
// These will need stubs in Library.d.ts and Library.js
export function ScanLibrary(id: number): Promise<void>;
export function ScanAllLibraries(): Promise<void>;
export function CancelCurrentScan(): Promise<void>;
export function CancelAllScans(): Promise<void>;
export function GetScanQueueLength(): Promise<number>;
New events (from Plan 01):
LibraryScanQueued: "LibraryScanQueued",
LibraryScanQueueDrained: "LibraryScanQueueDrained",
Existing cancel dialog pattern from config-page.ts:
- Modal overlay with stopPropagation
- Three button choices
- handleCancelKeep / handleCancelDiscard / handleCancelDialogDismiss
And corresponding runtime implementations in Library.js:
export function ScanLibrary(id) { return window['go']['library']['Library']['ScanLibrary'](id); }
export function ScanAllLibraries() { return window['go']['library']['Library']['ScanAllLibraries'](); }
export function CancelCurrentScan() { return window['go']['library']['Library']['CancelCurrentScan'](); }
export function CancelAllScans() { return window['go']['library']['Library']['CancelAllScans'](); }
export function GetScanQueueLength() { return window['go']['library']['Library']['GetScanQueueLength'](); }
export function QueuedLibraryNames() { return window['go']['library']['Library']['QueuedLibraryNames'](); }
-
Update config-page.ts ScanProgress interface to include the new fields:
- Add
libraryId: number,libraryName: string,queuedCount: numberto theScanProgressinterface
- Add
-
Update imports — replace
CancelScanimport withCancelCurrentScan, CancelAllScansfrom@go/library/Library -
Update progress display (
renderScanProgressmethod or equivalent):- When
scanProgress.libraryNameis non-empty, show "Scanning: [Library Name]" as the progress label instead of just "Scanning" - When
scanProgress.queuedCount > 0, add a line below: "[N] libraries queued" in tertiary text color - Format:
Scanning: My Music (245/1200 files)with2 libraries queuedbelow
- When
-
Update cancel dialog — replace the current three-option dialog with the per-library-aware version per CONTEXT.md:
- Add
@state() private scanQueuedCount = 0;to track queue state - Update
handleScanProgressto also savequeuedCount - When
queuedCount > 0(multi-scan in progress): show modal dialog with TWO buttons:- "Cancel This Library" — calls
CancelCurrentScan()(stops current, next starts) - "Cancel All Scanning" — calls
CancelAllScans()(stops everything) - No default — user must pick (per CONTEXT.md: "no default, user must pick")
- "Cancel This Library" — calls
- When
queuedCount === 0(single scan): keep existing cancel behavior but callCancelCurrentScan()instead ofCancelScan(). Can use the existing Keep/Discard/Continue dialog pattern. - Update
handleCancelKeep→ callCancelCurrentScan()instead ofCancelScan() - Update
handleCancelDiscard→ callCancelCurrentScan()instead ofCancelScan()
- Add
-
Handle new events in
connectedCallback:- Listen for
LibraryScanQueued— updatescanQueuedCountfrom event payload - Listen for
LibraryScanQueueDrained— setscanQueuedCount = 0, reset scan state
- Listen for
-
Update scan buttons section — when not scanning, show "Scan All Libraries" as an additional button alongside Soft Scan and Full Rescan. It calls
ScanAllLibraries().
Styling notes:
- Use existing design tokens (
--yj-text-primary,--yj-text-tertiary,--yj-accent) - Queue count text:
.progress-detailstyle (smaller, tertiary color) - Library name in progress: bold, primary text color
- Cancel modal buttons: "Cancel This Library" gets
btn-warning, "Cancel All Scanning" getsbtn-danger - Keep
.cancel-dialogCSS class pattern from Phase 9
TypeScript strictness:
overridekeyword on lifecycle methodsimport typefor type-only imports- Private event handlers as arrow functions cd /mnt/vault/dev/golang/yellowjacket/frontend && npx tsc --noEmit
- ScanProgress interface includes libraryId, libraryName, queuedCount
- Progress UI shows "Scanning: [Library Name]" and queue count
- Cancel dialog shows scope choice when multiple scans queued
- CancelCurrentScan/CancelAllScans called instead of CancelScan
- Scan All Libraries button exists in scan actions
- TypeScript compiles cleanly
-
Update progress rendering in
renderScanProgress():- Show library name: "Scanning: [Library Name]" as the progress label
- Show queued count when > 0: "[N] libraries queued" in tertiary text
-
Update imports — add
ScanAllLibrariesimport from@go/library/Library -
Add "Scan All Libraries" button to the scan actions section:
- Place it alongside existing "Soft Scan" and "Full Rescan" buttons
- Style:
btn-primaryclass, disabled when scanning - Handler:
private handleScanAll = async (): Promise<void> => { await ScanAllLibraries(); } - Label: "Scan All Libraries" (or "Scanning..." when active)
-
Listen for LibraryScanQueued and LibraryScanQueueDrained events:
- In
connectedCallback, add event subscriptions - In
disconnectedCallback, clean up subscriptions - These events update scanning state for the UI
- In
-
Update handleScanComplete to handle per-library scan completion:
- The
LibraryScanCompleteevent now includeslibraryNamein the metrics - If queue is still draining, don't reset scanning state (wait for
LibraryScanQueueDrained) - Only fully reset
scanning = falseonLibraryScanQueueDrainedor whenqueuedCount === 0in the complete event cd /mnt/vault/dev/golang/yellowjacket/frontend && npx tsc --noEmit
- The
- Library-manager shows library name in scan progress
- "Scan All Libraries" button exists and calls ScanAllLibraries
- Scan state properly tracks queue draining (doesn't reset early)
- TypeScript compiles cleanly
Full project builds (backend + frontend)
cd .. && go build ./...
</verification>
<success_criteria>
- Progress bar shows "Scanning: [Library Name] (N/M files)" during scan
- Queue count visible when libraries are queued
- Cancel modal offers "Cancel This Library" / "Cancel All Scanning" during queued scans
- "Scan All Libraries" button exists in both config-page and library-manager
- TypeScript compiles cleanly
</success_criteria>
<output>
After completion, create `.planning/phases/11-per-library-scan-pipeline/11-02-SUMMARY.md`
</output>