Files
musicdl-catalog-sync-suite/catalog-sync/docs/superpowers/specs/2026-04-17-task-tree-dashboard-design.md
T

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:

  1. The expanded task detail is rendered as a large HTML block containing Summary, Stages, Workers, Running Items, and Playlist Progress.
  2. 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 Center section 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:

  • queued
  • running
  • pause_requested
  • paused
  • completed
  • completed_with_errors
  • failed
  • canceled

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:

  • job
  • playlist_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:

  • position
  • song_name
  • singers
  • platform
  • remote_song_id
  • status
  • status_note
  • is_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:

  1. Task nodes are keyed by job_id
  2. Playlist nodes are keyed by job_id + playlist_id
  3. Song nodes are keyed by job_id + playlist_id + song_id/position
  4. Existing nodes are updated in place
  5. Expanded/collapsed state is preserved in dashboardState
  6. 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 Items blocks 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