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).
73 lines
4.9 KiB
Markdown
73 lines
4.9 KiB
Markdown
# Slice 4 — FileBrowser table mobile layout (worker output)
|
|
|
|
## Files changed
|
|
|
|
| File | Status | Lines |
|
|
|------|--------|------|
|
|
| `frontend/src/pages/FileBrowser.impl.tsx` | modified | +40 / -2 |
|
|
| `frontend/src/pages/__tests__/FileBrowser.test.tsx` | modified | +78 / -2 |
|
|
|
|
**Total: ~114 changed lines** (118 insertions, 4 deletions). Well under the 400-line budget.
|
|
|
|
## What was implemented
|
|
|
|
### 4.1 — Mobile fields + card render
|
|
|
|
Below `md` (`isMobile === true`), the file table renders as `<MobileCardRow>` cards inside the existing `<div className="rounded-lg border bg-card">` wrapper (with `p-4` padding, matching the Media pattern). Desktop renders the existing `<DataTable>` byte-for-byte identical.
|
|
|
|
**Mobile card field list** (module-level `fileCardFields` constant):
|
|
|
|
| Field | Key | Rationale |
|
|
|-------|-----|-----------|
|
|
| **Name** (primary) | `name` | Primary identifier — file or directory name |
|
|
| Type | `type` | "dir" / "file" / "up" — distinguishes the row kind at a glance |
|
|
| Size | `size` | Already human-readable via `formatSize`; "-" for dirs |
|
|
| Modified | `modified` | Already formatted via `formatTime`; "-" when empty |
|
|
|
|
4 fields total (1 primary + 3). The `ext` column was omitted because the extension is already visible in the filename itself — redundant on mobile.
|
|
|
|
**Preserved behaviors:**
|
|
|
|
- **Whole-card tap** = `handleRowClick(row)` — the same handler the desktop DataTable uses. Dir/up rows navigate into the directory; file rows select the file for ffprobe preview.
|
|
- **Directory navigation** works on mobile — tapping a folder card navigates into it (status caption updates to show the new cwd).
|
|
- **Path bar / breadcrumbs** (`Remote path` input + Open/Refresh buttons) render outside the table in the `SectionCard`, so they are unaffected by the isMobile branch. The existing `flex flex-col gap-2 md:flex-row` already stacks them on mobile.
|
|
- **ffprobe and Jobs sections** live outside the table and are unchanged.
|
|
- **No pagination** — FileBrowser does not paginate (the task confirmed this).
|
|
- **Desktop (`md+`)** — byte-for-byte identical: the `isMobile === false` branch renders the exact same `<DataTable>` with the same props.
|
|
|
|
### 4.2 — Tests
|
|
|
|
Added a `setMatchMedia(matches)` helper (mirrors the Media.test.tsx pattern) and called `setMatchMedia(false)` in `beforeEach` so the 3 existing desktop tests pass unchanged. Added 4 new tests in a `describe("FileBrowser (mobile card layout — slice 4)")` block:
|
|
|
|
1. **Cards render with file/dir name as primary below md** — asserts card titles render ("movies", "video.mkv", "notes.txt") and no table column headers leak.
|
|
2. **Tapping a directory card navigates into it** — clicks "movies", asserts status shows "Current: /movies" with no "Selected:" segment.
|
|
3. **Path/breadcrumb controls still render on mobile** — asserts "Remote path" input, Open and Refresh buttons are present.
|
|
4. **DataTable renders at desktop width** — asserts column headers (Type/Name/Ext/Size/Modified) present at desktop width.
|
|
|
|
## Validation
|
|
|
|
```
|
|
npm run lint → 0 errors, 2 pre-existing warnings (UsersPage.impl.tsx, unrelated)
|
|
npm run build → ✓ built (tsc -b + vite)
|
|
npm run test → 25 files / 98 tests passed (was 94; +4 new)
|
|
```
|
|
|
|
## Deviations from design
|
|
|
|
1. **`ext` field omitted from mobile card.** The task said "Fields (3-5): size, modified time, and type/extension (file vs directory)." I interpreted "type/extension" as a single concept (dir vs file vs up) and used the `type` field to cover it. The `ext` column is redundant because the filename already contains the extension (e.g. "video.mkv"). Including it would waste card space. This is a per-table field choice, which the design explicitly delegates to the consuming page (§trade-offs).
|
|
|
|
2. **No deviations from the established Media.tsx pattern.** Module-level `MobileCardField<DisplayRow>[]` constant, `isMobile` from `useIsMobile()`, `getRowId` wired to `row.id`, `onRowClick` wired to the existing `handleRowClick`. Same `p-4` wrapper inside the bordered container.
|
|
|
|
## 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 and the Media.tsx reference pattern.
|
|
|
|
## Residual risks
|
|
|
|
- **`enableRowSelection` on mobile.** The mobile card has no selection checkbox — the whole card is the tap target for navigation/selection via `handleRowClick`. This matches R3.3's "tap target = the whole card where applicable" and the FileBrowser's existing behavior where clicking a file row selects it. The checkbox-based selection is desktop-only, consistent with the Media slice.
|
|
- **The ".." (up) row** renders as a card with name "..", type "up", size "-", modified "-". This is the universal convention for "go to parent directory" and is tappable. Functionally correct.
|
|
|
|
## Review findings
|
|
|
|
No blockers identified during self-review. All validation commands green. No staged files.
|