6.3 KiB
Catalogsync Task Tree Dashboard Design
Goal
Replace the current Task Center detail tables with a stable tree view:
- task
- playlist
- song
The new Task Center must keep task nodes visible across status transitions such as running -> paused -> completed, and live refresh must update existing nodes instead of rebuilding the entire task table.
Problem Statement
The current dashboard still feels unstable for two reasons:
- The expanded task detail is rendered as a large HTML block containing
Summary,Stages,Workers,Running Items, andPlaylist Progress. - The frontend refresh path still calls
setTaskRows(...), which rebuilds the whole Task Center body and then rebinds all event handlers.
Even after paused tasks were kept in the query, this full redraw still recreates DOM nodes and causes visible flicker. It also makes the UI feel like a live report view instead of an operator task tree.
Scope
In Scope
- Rebuild only the
Task Centersection of/dashboard - Keep the dashboard top cards for now:
- live snapshot
- summary
- quick actions
- create job
- playlist coverage
- Replace the task detail block with a three-level tree:
- task node
- playlist child node
- song child node
- Keep pause/resume/cancel actions on the task node
- Preserve expanded task and playlist state across refreshes
- Update task status, progress, and counts in place without full Task Center redraw
- Keep non-music resource labeling in song rows
Out of Scope
- Redesigning the top dashboard cards
- Removing
/jobs,/songs, or other pages - Changing job execution semantics
- Changing download logic or retry semantics
Chosen UI Structure
Task Center Layout
Task Center becomes a single tree container instead of a table plus nested detail tables.
Each task node shows:
- expand/collapse toggle
- task display name
- task type
- task status
- scope summary
- primary progress text and progress bar
- active worker count
- lane label
- pause/resume button
- cancel button
When expanded, the task shows only its playlist children.
Each playlist node shows:
- expand/collapse toggle
- playlist name
- source label such as
qq #64 - downloaded song count / total song count
- progress bar
- compact state summary:
- running
- pending
- failed
- skipped
When expanded, the playlist shows only its song children.
Each song node shows:
- sequence number
- song name
- singer summary
- platform/source id summary
- song status tag
- optional
非音乐资源tag - status note
This makes the page behave more like a file explorer tree and removes the distracting intermediate tables.
Data Model and API Expectations
Task List
list_task_center_rows() must return recent tasks for all operator-visible lifecycle states, not just active ones.
The intended visible states are:
queuedrunningpause_requestedpausedcompletedcompleted_with_errorsfailedcanceled
This ensures a task stays in the tree when its state changes; only its displayed status changes.
Task Detail
/api/jobs/{job_id} may continue returning its current payload shape, but the dashboard will only consume:
jobplaylist_progress
The frontend will ignore summary, stages, workers, and running_items for Task Center rendering.
Playlist Songs
/api/jobs/{job_id}/playlists/{playlist_id}/songs remains the lazy-loaded source for song child nodes.
The existing fields are sufficient:
positionsong_namesingersplatformremote_song_idstatusstatus_noteis_non_music_resource
Rendering Strategy
Initial Render
The server-rendered HTML for /dashboard should render a task tree shell directly, not a table with hidden detail rows.
Live Updates
The Task Center refresh path must switch from full innerHTML replacement to keyed DOM patching.
Rules:
- Task nodes are keyed by
job_id - Playlist nodes are keyed by
job_id + playlist_id - Song nodes are keyed by
job_id + playlist_id + song_id/position - Existing nodes are updated in place
- Expanded/collapsed state is preserved in
dashboardState - Status changes never collapse or remove a visible node by themselves
Removal Policy
Nodes may be removed only when they are absent from the latest server payload because they have truly fallen out of the visible result window, not because they changed from active to paused/completed.
Refresh Model
Dashboard Summary Refresh
The lightweight snapshot refresh may continue updating:
- live snapshot text
- summary numbers
- download stats
- playlist coverage
These sections can still use simple row replacement because they are small and not interactive.
Task Tree Refresh
Task rows must be refreshed through a dedicated keyed patch function:
- update existing task header fields
- insert new task nodes
- remove missing task nodes only when no longer returned
- if a task is expanded, refresh its playlist subtree in place
- if a playlist is expanded, refresh its song subtree in place when fresh data arrives
The Task Center must no longer call a function that rebuilds the whole container on every poll.
Error Handling
- Failed songs remain visible in the playlist subtree with their note
- Non-music resources remain visible and are labeled
非音乐资源 - If playlist song loading fails, show the error message only inside that playlist node
- If task detail loading fails, show the error only inside that task node
Testing Strategy
Automated
- repository test: task list includes completed jobs
- API test: dashboard HTML renders the tree shell instead of detail tables
- API test: dashboard data continues to expose task rows for live refresh
Manual
- open
/dashboard - expand one paused task
- expand one playlist
- wait through multiple refresh cycles
- verify:
- expanded task stays expanded
- expanded playlist stays expanded
- no
Summary / Stages / Workers / Running Itemsblocks appear under tasks - task status changes update text only, without the whole Task Center flashing
Assumptions
- The operator still wants the top dashboard cards retained for now
- Recent finished tasks should remain visible in the Task Center instead of disappearing immediately
- The current lazy-load model for song lists is acceptable as long as the node itself stays stable