docs: add Phase 8 (CMS Track Browser) to PLAN; supersede §6.2
This commit is contained in:
@@ -77,12 +77,12 @@ See `COMPLETED.md` for Phase 6 (§6.1, §6.3) and entity-prep (§6.2 model layer
|
||||
|
||||
---
|
||||
|
||||
### 6.2 Card-contextual filtering of the Tracks page — `[deferred]`
|
||||
### 6.2 Card-contextual filtering of the Tracks page — `[superseded by §8]`
|
||||
|
||||
- **What:** Make the Album and Genre dashboard cards navigate into a *filtered* `/tracks` view (e.g. clicking an album card shows only that album's tracks), rather than the unfiltered table.
|
||||
- **Why:** Turns the dashboard from a read-only summary into a navigation hub — the natural next step once the cards exist.
|
||||
- **Why deferred:** The dashboard cards aggregate *across all* albums/genres — there is no single album/genre to filter to from a top-level count card. Meaningful per-album/per-genre navigation needs an intermediate browse surface (a list of albums, a list of genres) for the admin to pick from — i.e. it's really a CMS analogue of the public `AlbumsView`/`GenresView`, not a property of the summary cards. That's a larger surface than the dashboard itself and shouldn't be smuggled in. The `GET api/track/page` endpoint already accepts `album=` and `genre=` query filters, so the API substrate is ready; the missing piece is the CMS browse UI and the filter plumbing in `TrackList`.
|
||||
- **Shape (sketch, not committed):** CMS album/genre browse pages (or tabs on `/tracks`) backed by the existing `albums`/`genres` endpoints; rows link to `/tracks?album=…` / `/tracks?genre=…`; `TrackList.LoadServerData` reads the query param and passes it to `GetPagedAsync`. Revisit as its own item when Daniel wants it.
|
||||
- **Superseded:** **§8 (CMS Track Browser)** builds exactly the intermediate browse surface this item was waiting on — Album Mode and Genre Mode *are* the CMS analogue of `AlbumsView`/`GenresView`, and the filter plumbing into `GetPagedAsync` is part of §8's data contract. This item folds into §8; do not implement it separately.
|
||||
|
||||
---
|
||||
|
||||
@@ -130,7 +130,39 @@ Reusable presentational components in `DeepDrftShared.Client` (the RCL consumed
|
||||
|
||||
---
|
||||
|
||||
## Cross-cutting / not yet themed
|
||||
## Phase 8 — CMS Track Browser
|
||||
|
||||
Three browse modes for the CMS `/tracks` page — **Track**, **Album**, **Genre** — selected by a toggle, each deep-linkable so the public home page can link straight into a mode. One view-model feeds all three views; the divergence is in rendering, not data paths (per the standing "same data, different uses" preference). This supersedes the deferred §6.2 — Album and Genre modes *are* the intermediate browse surface that item was waiting on. Full spec: `product-notes/phase-8-cms-track-browser.md` (component decomposition, VM design, URL scheme, data contracts, open questions). Several decisions are still open there (notably whether to widen `AlbumSummaryDto`) — needs Daniel sign-off before build.
|
||||
|
||||
### 8.1 URL scheme + mode toggle
|
||||
|
||||
- **What:** `/tracks` (Track mode, default), `/tracks/albums`, `/tracks/genres` as route segments; a toggle inside the existing "Tracks" tab switches mode and pushes the matching URL. The Waveform Pre-Processing tab is untouched.
|
||||
- **Why:** The public home page hard-codes these as cross-host deep-links; a route segment reads as a stable address and matches the app's existing segment-based routing (`/tracks/upload`, `/tracks/{id}`). Query-param mode (`?mode=`) was the alternative — rejected as transient-looking view state, optionally tolerated as an alias.
|
||||
- **Shape:** One `TrackList` component carrying three `@page` directives (or three thin wrappers passing an `InitialMode`); the toggle drives `Mode` + `NavigationManager.NavigateTo`. See notes §3, §9.
|
||||
|
||||
### 8.2 `CmsTrackGrid` — the reusable flat track table (DRY core)
|
||||
|
||||
- **What:** Extract today's `MudTable<TrackDto>` into a standalone `CmsTrackGrid.razor` taking `AlbumFilter`/`GenreFilter` params. Apply the new column layout: Track # → 40×40 art thumb → Track Name → Artist → Album → Genre → Release Date (`d MMMM, yyyy`) → Actions. Entry Key + File Name move out of the grid into an Info-icon tooltip (monospace). Art thumb reuses the public `TrackCard` fallback pattern, defined locally CMS-side.
|
||||
- **Why:** Single source of truth for the track-table layout — consumed by both Track mode (no filter) and Genre mode (genre filter), so no duplicated table markup. Decluttering Entry Key / File Name into a tooltip keeps the grid scannable while the data stays reachable.
|
||||
- **Shape:** Owns its own `MudTable` + `LoadServerData` + delete-confirm (lifted from `TrackList`). `GetPagedAsync` gains optional `album`/`genre` filter params — the one real data-contract change (the endpoint already supports the filters). Display date format is presentation-only; sort key stays the raw `DateOnly`. See notes §8, §11.
|
||||
|
||||
### 8.3 Album mode
|
||||
|
||||
- **What:** `CmsAlbumBrowser` — parent album rows (art, name, artist, track count, genre, earliest release date, release-type chip, Edit + Delete) that expand to child track rows (track # + name only). Edit → Batch Edit page (§8.5); Delete → album-scoped delete of every track.
|
||||
- **Why:** A scannable album catalogue is the CMS analogue of the public `AlbumsView`, and the natural place to manage a release as a unit.
|
||||
- **Shape:** Parent rows from `GetAlbumSummariesAsync` (eager, once); child tracks lazy via `GetPagedAsync(album:)` on first expand, cached per row — no new endpoint. Expandable `MudTable` over `MudTreeView` (parent rows are multi-column, not tree-shaped). **Open:** the parent row needs artist/genre/date/type, which aren't on `AlbumSummaryDto` — either widen the DTO + summary query (recommended; fully-populated resting row) or derive lazily on expand (thin resting row, no contract change). Daniel's call. See notes §6, §10, §12(3).
|
||||
|
||||
### 8.4 Genre mode
|
||||
|
||||
- **What:** `CmsGenreBrowser` — a responsive `MudCard` grid (one card per genre: name + track count); clicking a card expands it (accordion, one open at a time) to reveal a `CmsTrackGrid` filtered to that genre.
|
||||
- **Why:** CMS analogue of the public `GenresView`; the card-to-grid expand is the cheapest second mode because the grid is already built (§8.2).
|
||||
- **Shape:** `GetGenreSummariesAsync` once; the expanded panel renders `CmsTrackGrid` with `GenreFilter` set and the Add button suppressed — zero duplicated table markup. See notes §7.
|
||||
|
||||
### 8.5 Batch Edit page
|
||||
|
||||
- **What:** New page `/tracks/album/{albumName}/edit`, reached from an Album-mode row's Edit action. `BatchUpload`'s master-detail mechanics with the album's data preloaded; submit swaps per-row `UploadTrackAsync` for `UpdateAsync` on existing tracks (new tracks still upload). Distinct from the existing single-track edit at `/tracks/{id}`.
|
||||
- **Why:** Editing a release as a unit (rename tracks, reorder, swap cover, add tracks) without round-tripping the single-track editor per track.
|
||||
- **Shape:** Recommend a *new* `BatchEdit.razor` sharing extracted sub-components with `BatchUpload` (album-header block, master list, detail pane) over growing `BatchUpload` with an `isEdit` flag — the flag breeds conditional soup across preload/detail/submit. Cover art uses the established upload-once-then-link-via-`UpdateAsync` two-step. **Open:** does remove-in-edit delete an existing track (with confirm) or just detach? See notes §10, §12(8,9).
|
||||
|
||||
A small set of items that are real but don't fit a phase yet. Surface them when they become relevant rather than committing now.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user