# M7 — Track-level actions menu > **Status:** Draft for review · 2026-05-03 > > **Phase:** M7 task #372. Web-side polish slice. Replaces the single-entry `` (built as scaffolding for M5b's quarantine flag) with a real per-track action set. Lands before M7 #352 (Playlists CRUD) so the "Add to playlist…" entry has a menu to slot into. Mirrored on Flutter in a later slice once the web surface is settled. ## 1. Goal Per-track kebab menu wherever `` or the `` track display is used, exposing the full set of actions a user can take on a track right now: queue manipulation, library state changes (Like, Hide), navigation (Go to album/artist), Lidarr-aware track removal, and a placeholder slot for "Add to playlist…" that #352 fills. ## 2. Goals and non-goals ### Goals - `` exposes nine entries, grouped four ways: 1. **Queue:** Play next · Add to queue 2. **Collection:** Like / Unlike · Add to playlist… (slot reserved; wired by #352) 3. **Navigation:** Go to album · Go to artist 4. **Lifecycle:** Flag this track… · Hide / Unhide · Remove from library *(admin-only)* - "Like / Unlike" and "Hide / Unhide" entries duplicate functionality already on the row (heart and eye icon buttons). Reason: keyboard discoverability — once the kebab is focused, arrow-keys reach every action; mouse users still get one-tap heart/eye on the row. - "Add to playlist…" reserves the menu slot but the submenu of playlists is wired in #352, not here. The slot renders as disabled with a tooltip "Coming with playlists" until #352 ships. - "Go to artist" is single-target (`track.artistId`); compilation/feature artists aren't modeled in the schema today and that's a schema problem to solve before this entry needs a submenu. - "Remove from library" is admin-only — gated client-side by `currentUser.is_admin`, server-side by `auth.RequireAdmin()` on the new `/api/admin/tracks/{id}` route. The endpoint always deletes the file from disk via `os.Remove` (not via Lidarr, which is album-granular and has no per-track delete) plus the DB row, then cascades album → artist tidy-up. For Lidarr-managed tracks the operator chooses whether Lidarr should look for a replacement (default — no extra action; Lidarr's monitoring re-imports on next scan) or the track should be unmonitored (server calls `Lidarr.UnmonitorTrack(mbid)` to flip `monitored: false`). The `?unmonitor=true` query param drives this — unset / `false` = replace, `true` = unmonitor. - Keyboard accessibility: kebab is `