a8dfbd5dc6
Delete the old top-level page files whose content was migrated into service-page tabs in slices 5-9: - pages/Media.tsx, Applications.tsx (-> MediaTab) - pages/FileBrowser.tsx, FileBrowser.impl.tsx (-> FilesTab) - pages/Actions.tsx (-> ActionsTab) - pages/Users.tsx, UsersPage.impl.tsx (replaced by Authentik tabs) - components/BackupsPage.tsx (-> JobsTab) - components/ObservabilityPage.tsx (split into Alerts/Links/Metrics tabs) - hooks/useUsers.ts (orphaned after Users page deletion) - the corresponding page test files (Media, FileBrowser, Applications, Actions, UsersPage) that tested the deleted pages directly. The service-tab components are the live implementations; ServicePage renders them. No live code references the deleted files. Docs: append an Information Architecture section to REQUIREMENTS.md documenting the services-as-hub model (nav shape, service-page tabs, service type registry, Users->Authentik, Observability split, legacy route 404s, empty state). Add a CHANGELOG entry under [Unreleased]. 92 frontend tests pass (was 112; -20 deleted page tests); 271 backend tests pass; lint/build green. Refs openspec/changes/services-as-hub-ia/ (tasks slice 11).
63 lines
4.3 KiB
Markdown
63 lines
4.3 KiB
Markdown
# Slice 5 — Jellyfin content tabs: Media + Requests (worker output)
|
|
|
|
## Files changed
|
|
|
|
| File | Status | Lines |
|
|
|------|--------|-------|
|
|
| `frontend/src/pages/service-tabs/MediaTab.tsx` | new | 511 |
|
|
| `frontend/src/pages/service-tabs/RequestsTab.tsx` | new | 64 |
|
|
| `frontend/src/pages/service-tabs/__tests__/MediaTab.test.tsx` | new | 78 |
|
|
| `frontend/src/pages/service-tabs/__tests__/RequestsTab.test.tsx` | new | 59 |
|
|
| `frontend/src/pages/service-tabs/index.ts` | modified | +2 / -2 (import MediaTab/RequestsTab from new files) |
|
|
| `frontend/src/pages/service-tabs/stubs.tsx` | modified | -8 (removed MediaTab/RequestsTab stubs) |
|
|
|
|
**Total: ~724 changed lines.** Over the 400-line budget, but the MediaTab lift is inherently large (near-verbatim copy of Media.tsx — 450 lines — with the service-id source swapped from URL params to the `instance` prop). The genuine new logic is RequestsTab (64 lines) + tests (137 lines) + index/stubs changes (12 lines).
|
|
|
|
## How instance.id is wired into the hooks
|
|
|
|
The old Media.tsx read the Jellyfin service ID from a URL search param (`?jellyfin_service_id=`) with a `<Select>` dropdown and a `useEffect` that synced the param. The new MediaTab replaces all of that with a direct read from the `instance` prop:
|
|
|
|
```tsx
|
|
export function MediaTab({ instance }: { instance: ServiceInstance }) {
|
|
const serviceId = instance.id;
|
|
// All hooks receive serviceId directly:
|
|
const { data: status } = useMediaStatus(serviceId);
|
|
const buildIndex = useBuildIndex(serviceId);
|
|
// etc.
|
|
}
|
|
```
|
|
|
|
The service-selection dropdown, `useSearchParams`, `useServiceInstances("jellyfin")`, and the URL-sync effect are all removed. The `useNavigate` stays for the row-click → file browser navigation (`/files?path=...`).
|
|
|
|
## What RequestsTab renders
|
|
|
|
**Not configured** (empty `jellyseerr_url` or `jellyseerr_api_key`): an `<Alert>` CTA: "Jellyseerr is not configured for this Jellyfin instance. Add `jellyseerr_url` and `jellyseerr_api_key` to the Jellyfin config (Config tab) to enable request management."
|
|
|
|
**Configured** (both fields set): shows the Jellyseerr URL as an external link + an `<Alert>` explaining the requests view is under development. No faked data — no backend requests endpoint exists yet (out of scope for this slice).
|
|
|
|
## Validation
|
|
|
|
```
|
|
cd frontend && npm run lint → 0 errors, 2 pre-existing warnings (UsersPage.impl.tsx, unrelated)
|
|
cd frontend && npm run build → ✓ built (tsc -b + vite)
|
|
cd frontend && npm run test → 27 files / 90 tests passed (was 84; +6 new)
|
|
```
|
|
|
|
## Deviations from design
|
|
|
|
1. **Over 400-line budget.** The MediaTab lift is ~511 lines because it's a near-verbatim copy of Media.tsx (which is itself ~450 lines). The task acknowledged this: "Media.tsx is large; the lift is mostly mechanical." RequestsTab was kept minimal (64 lines) to partially offset. Could not have shrunk MediaTab without dropping features (build controls, status, filters, table).
|
|
|
|
2. **No mobile card layout on MediaTab.** This branch is based on `main`, NOT on `mobile-responsive-parity`. Main's Media.tsx uses a DataTable with TanStack column-visibility-based mobile hiding (the `usePrefersSmallScreen` / `MOBILE_HIDDEN_COLUMNS` pattern), NOT the MobileCardRow from the mobile branch. I lifted exactly what main has — no invented mobile layout.
|
|
|
|
3. **Old Media.test.tsx and Applications.test.tsx still pass.** They render the page components directly (not via routing), so the route removal doesn't affect them. They'll be deleted in Slice 11 cleanup.
|
|
|
|
## skill_resolution
|
|
|
|
`none` — no project/user SKILL.md paths were injected by the parent, and no `.atl/skill-registry.md` was found. The task was self-contained against the OpenSpec design/tasks docs.
|
|
|
|
## Residual risks
|
|
|
|
- **MediaTab duplicates Media.tsx.** The old page file stays in the repo (cleanup is Slice 11). Until then there's a ~450-line dead file. Not harmful (no route references it).
|
|
- **RequestsTab has no real data.** It shows a "coming soon" placeholder when configured. Building a backend requests endpoint + frontend list is a follow-up.
|
|
- **Row-click still navigates to `/files?path=...`.** In the new IA, Files lives on the ssh_tasks service page, not at `/files` (which now 404s). This row-click will break until the ssh_tasks FilesTab (Slice 6) either re-adds a `/files` route or the link target changes to `/services/ssh_tasks/<id>?path=...`. Flagged for Slice 6.
|