# 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 `` cards inside the existing `
` wrapper (with `p-4` padding, matching the Media pattern). Desktop renders the existing `` 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 `` 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[]` 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.