# Frontend Improvement Tasks Derived from `frontend_report.md`. Checklist form for tracking progress — check items off as they land. Ordered by phase (do Phase 1 before Phase 2, etc.); within a phase, order doesn't matter much. --- ## Phase 1 — Truth-in-UI & dead code ✅ (done) - [x] Wire `views/DashboardView.vue` stats to real API data where an endpoint exists (projects, active projects, overdue tasks, total users, pending approvals, API keys, developer stats, pending reviews, admin system activity). Added `services/developer.ts` and `services/review.ts` wrappers. - [ ] Replace fixed-lookup episode progress with real computed progress — `components/episode/EpisodeCard.vue:117-128` and `components/episode/EpisodeList.vue:267-278` — **deferred**: backend has no `completed_shots`/`progress` field yet (`backend/schemas/episode.py`, `backend/routers/episodes.py`) - [ ] Fix task-status usage counts always showing 0 — `components/settings/CustomTaskStatusManager.vue:275-295` — **deferred**: needs a new `GET /projects/{id}/task-statuses/counts` backend endpoint - [x] Register the missing route: `/projects/:projectId/technical-specs` in `router/index.ts` - [x] Delete confirmed-dead files (or finish wiring them in): - [x] `components/shot/ShotColumnVisibilityControl.vue` — deleted - [x] `components/asset/ColumnVisibilityControl.vue` — deleted - [x] `components/project/ShotsTable.vue` — deleted - [x] `components/examples/FileUploadExample.vue` — deleted - [x] `views/GlobalSettingsView.vue` — deleted - [x] `views/HomeView.vue` — deleted - [x] `components/asset/AssetDeleteConfirmDialog.vue` — fixed (raw divs → shared `Alert` component) and wired into `AssetBrowser.vue`, mirroring `ShotBrowser.vue`'s pattern - [x] `components/activity/ActivityFeed.vue` — wired into `ProjectOverviewView.vue` in place of "coming soon" text; `TaskActivityTimeline.vue` — deleted (no `taskId` available at that call site) - [x] Replace native `confirm()`/`alert()` with styled dialogs: - [x] `components/task/NoteItem.vue:178` → `AlertDialog` - [x] `components/task/TaskAttachments.vue:201` → `AlertDialog` - [x] `components/layout/UserMenu.vue` keyboard-shortcuts `alert()` → `Dialog` - [x] Remove leftover debug logging (all 8 files/line-ranges) - [x] Removed Google OAuth stub buttons (`LoginView.vue`, `RegisterView.vue`) — no OAuth backend exists, so the buttons were pure dead ends - [ ] `/developer/api-keys`, `/developer/projects`, `/developer/tasks`, `/developer/analytics`, `views/ReviewsView.vue` — **left as-is**: their empty states are honest ("No API keys" etc.), not misleading, so out of scope for a truth-in-UI pass. Only fixed the one dead action button on `APIKeysView.vue` (removed `action-text`/`@action` since it did nothing). - [x] Removed dead-end UserMenu items (`/settings/preferences`, `/help`, notifications toggle) and the `/developer/docs` dead link (`AppSidebar.vue`, `DashboardView.vue`) — no real destination existed for any of them **Bonus fixes surfaced during verification (approved mid-implementation):** - Fixed two pre-existing backend bugs that 500'd once real data was wired up: `backend/routers/reviews.py` (`joinedload("reviewer")` string → `joinedload(Review.reviewer)`) and `backend/utils/activity.py` (wrong `models.submission` import path → `models.task`). - Fixed a pre-existing bug shared by both `ShotDeleteConfirmDialog.vue` and `AssetDeleteConfirmDialog.vue`: their `watch(() => props.open, ...)` lacked `{ immediate: true }`, so the impact-summary section never rendered since the dialog only mounts once already open. Deletion itself worked fine either way — this was purely cosmetic, but it was the whole point of the "impact summary" safety feature. ## Phase 2 — Close feature gaps (asset vs. shot parity) ✅ (done) - [x] Add user-assignment popover to `components/asset/EditableTaskStatus.vue` — ported from the shot version; wired through `asset/columns.ts` and `AssetBrowser.vue` - [x] Add column-locking toggle to `components/asset/AssetTableToolbar.vue` — two-pane frozen-column layout ported into `AssetsDataTable.vue` (adapted for asset's page-scroll layout, no vertical scroll-sync needed unlike shot's bounded-height container) - [x] Add row-actions ("…") menu to `components/task/columns.ts` — "View Details" + "Reassign" (no Delete/Edit — no backend `deleteTask`/task-edit-form exists) - [x] Implement the asset detail-panel actions in `AssetBrowser.vue`/`AssetDetailPanel.vue`: create task (task-type picker), select task (opens `TaskDetailPanel` in-place), create note/upload reference/publish version (task picker → deep-links into `TaskDetailPanel`'s Notes/Attachments/Submissions tabs via new `initialTab` prop) - [x] Implement the same for `ShotBrowser.vue`/`ShotDetailPanel.vue` (also fixed the pre-existing dead "Add Note"/"Upload Reference" buttons there) - [x] Consolidate `components/project/ProjectMembersManager.vue` and `components/project/ProjectMemberManagement.vue` into one component (kept `ProjectMemberManagement.vue`, deleted the other) — combined remove-confirmation + approved-user filtering + real avatars from one with toast feedback + shared `Select`/`Dialog` UI-kit from the other - [x] Wire the consolidated member-management component into `ProjectDetailView.vue:149-151` — navigates to the project Settings "Team" tab (mirrors the existing `manageTechnicalSpecs` pattern) rather than a duplicate dialog **Bugs found and fixed during verification (approved mid-implementation):** - `GET /assets/{id}` never returned `task_details` (schema didn't even declare the field) — unlike `GET /shots/{id}`, which already did. Broke the asset detail panel's task list and, transitively, every new create-task/note/reference/version feature. Fixed in `backend/schemas/asset.py` + `backend/routers/assets.py`. - `TaskBrowser.vue`'s `handleRowClick` is a no-op by design (single click reserved for selection) — the new row-actions menu's "View Details"/"Reassign" needed to emit `row-double-click` instead, which is what actually opens the panel. ## Phase 3 — Unify controls ✅ (done) - [x] Extract `ColumnToggleList` component and point at it from: - [x] `components/ui/sidebar/SidebarColumnSwitch.vue` - [x] `components/shot/ShotTableToolbar.vue` - [x] `components/asset/AssetTableToolbar.vue` - [x] `components/task/TaskTableToolbar.vue` Built on a new `CheckableCommandItem` primitive (`Command`/`CommandItem` wrapping a decorative `Checkbox`) instead of `DropdownMenuCheckboxItem` — keeps `CommandInput` search (needed for task-type columns) and avoids the ARIA double-toggle bug already found and fixed in the dead `ShotColumnVisibilityControl.vue`. - [x] Shared toolbar pieces extracted as separate composable pieces rather than one monolithic `EntityTableToolbar` (scope decision, approved before implementation: shot/asset/task toolbars diverge enough — shot's 3-way view mode + bulk-create, asset's thumbnail toggle, task's different filter set — that a config-driven mega-component would be a leaky abstraction): `useDebouncedSearch` composable, `DetailPanelToggleButton.vue`, `ClearFiltersButton.vue`, `SegmentedToggle.vue`. All three toolbars now compose these instead of hand-rolled equivalents. - [x] `SegmentedToggle` component — done (shot grid/list/table, asset grid/list, task all/shots/assets). - [x] Delete confirmation — verified already consistent (Shot/Asset both use `Dialog`+`Alert`+impact-summary+type-to-confirm since Phase 1). Episode/Project deletes are simple client-side guards with no impact-summary fetch at all, so giving them one would be new feature work, not unification — left as-is (verification-only, no code change). - [x] Swap hand-rolled checkbox-divs for `CheckableCommandItem` in: - [x] `SidebarColumnSwitch.vue` - [x] `ShotTableToolbar.vue` - [x] `AssetTableToolbar.vue` - [x] `TaskTableToolbar.vue` - [x] `ShotTaskStatusFilter.vue` / `asset/TaskStatusFilter.vue` — merged into one `components/shared/TaskStatusFilter.vue` - [x] Replace ad hoc `size="sm" class="h-8 w-8 p-0"` with `size="icon-sm"` — 24 occurrences across toolbars, detail panels, row-action triggers, and columns.ts render functions - [x] CTA convention: dense table toolbars (Shot/Asset create buttons) stay icon-only but now have the same `title` tooltip every sibling icon button already had; full-page views (Project/Episode "New X") standardized wording between header and empty-state instances - [x] Standardize row-actions/bulk-actions on `DropdownMenu`/`DropdownMenuItem` — `TaskBulkActionsMenu.vue`'s "Assign To" section now mirrors "Set Status"'s existing submenu instead of a hand-rolled `