# Case Browse — UI Redesign Tracker

**Decision:** Option B ("Command bar + resizable dock") is the default layout.
Option C ("Investigator workspace") ships behind a per-user layout toggle
(persisted in `localStorage`, key `caseBrowseLayout`).
See [case-browse-ui-redesign-options.md](case-browse-ui-redesign-options.md).

Legend: ☐ pending · ◐ in progress · ☑ done

---

## Phase 1 — Quick wins (Q1–Q9)

| ID | Item | Status | Notes |
|----|------|--------|-------|
| Q1 | ←/→ keyboard Back/Next (skips inputs/selects/textareas) | ☑ | `CaseBrowseHotkeys` JS hook |
| Q2 | "✓ Saved" pulse on successful auto-save | ☑ | `saved_field` assign + `:clear_saved` timer |
| Q3 | Copy-to-clipboard on Case Ref / Case Key Value | ☑ | `CopyToClipboard` hook; execCommand fallback (page served over http) |
| Q4 | Neutral spinner replaces red "Fetching" | ☑ | |
| Q5 | Status badges + Title Case labels in Detail Views | ☑ | reuse `status_badge/1` |
| Q6 | Empty states explain *why* | ☑ | esp. Activations / Key Journal for decline-opened cases |
| Q7 | aria-labels + `aria-pressed` on toggles/stars, focus rings restored | ☑ | |
| Q8 | Tab count badges (Notes / Forms Journal / Uploads) | ☑ | |
| Q9 | ✕ clears drill selection from the amber banner | ☑ | new `clear-drill` event |
| Q10 | Auto-load activations on case load (was: only on Refresh click) | ☑ | added during implementation — empty tab was misleading |

## Phase 2 — Option B (default "classic" layout)

| ID | Item | Status | Notes |
|----|------|--------|-------|
| B1 | Nav strip: ← Search left, segmented Back/Next, progress bar, "Case n of N", macros merged in | ☑ | |
| B2 | Two-tier header: read-only identity bar (tier 1) + editable actions toolbar (tier 2, grouped Resolution / Lock / Diary) | ☑ | workflow-status tint kept on tier 1 (parity, open question Q2 in options doc) |
| B3 | Read-only values as text (not inputs); full Case Ref visible | ☑ | |
| B4 | Relabel "Closed Status" → "Case Status", "Status" → "Workflow" | ☑ | display-only; events/fields unchanged |
| B5 | Left panel contextual — only on Case Forms tab; Detail Views/Visualisation full width | ☑ | Case Keys value moved into Detail Views summary |
| B6 | Detail Views sections: Summary / Why-opened callout / Transaction Details | ☑ | |
| B7 | Resizable bottom dock (drag handle + maximize button, height persisted) | ☑ | `CaseBrowseDock` hook, localStorage `caseBrowseDockH` |
| B8 | Shared pane components extracted (`CaseBrowseComponents`) | ☑ | prerequisite for the dual layout |

## Phase 3 — Option C ("workspace" layout, behind toggle)

| ID | Item | Status | Notes |
|----|------|--------|-------|
| C1 | Layout toggle in nav strip; preference persisted + restored on mount | ☑ | `toggle-layout` / `set-layout` events |
| C2 | Right rail: Why-opened callout pinned + state controls + quick notes | ☑ | notes visible beside evidence |
| C3 | Full-height evidence area with merged tab strip (Details / Key Journal / Activations / Visualisation / Forms) | ☑ | |
| C4 | Low-traffic journals (Case / Events / Forms / Uploads) collapsed into "Journals ▾" dropdown tab | ☑ | |
| C5 | Filter bar (Top / Elevation / Activations Only) rendered inside the views that use it | ☑ | |

## Phase 4 — Verification

| ID | Item | Status | Notes |
|----|------|--------|-------|
| V1 | `mix compile` clean | ☑ | |
| V2 | `mix assets.build` clean | ☑ | |
| V3 | Manual smoke: both layouts, toggle round-trip, dock resize, keyboard nav, copy, saved pulse | ☐ | needs running app |

## Phase 5 — AG Grid conversion (management/view consistency)

Decision: convert Activations, Case Journal, and Case Events Journal to AG
Grid (same sort/filter/resize/export as Case Key Journal already has). Case
Notes stays a free-text feed (not tabular); Case Forms Journal stays a plain
table (small per-case volume, not worth master/detail complexity); Case
Uploads keeps its drop-zone + plain file list.

| ID | Item | Status | Notes |
|----|------|--------|-------|
| G1 | `ActivationsAgGridHook` — Score (link)/Rule/Activated At | ☑ | `assets/js/hooks/case/ActivationsAgGridHook.js` |
| G2 | `CaseJournalAgGridHook` — Id (link)/Closed/Closed User/Locked/Locked User/Workflow/Diary/Diary User/Diary Date, current-case row highlight | ☑ | `assets/js/hooks/case/CaseJournalAgGridHook.js` |
| G3 | `CaseEventsAgGridHook` — Event/Before/After/Id (link)/Created User/Created Date | ☑ | `assets/js/hooks/case/CaseEventsAgGridHook.js` |
| G4 | `activations_pane`, `case_journal_pane`, `events_pane` swapped from `<table>` to AG Grid divs | ☑ | `case_browse_components.ex`; `serialize_case_journal/3` and `serialize_events/1` added |
| G5 | Hooks registered in `hooks/index.js` | ☑ | `ActivationsGrid`, `CaseJournalGrid`, `CaseEventsGrid` |
| G6 | `mix compile` / `mix assets.build` clean after conversion | ☑ | |
| G7 | Manual smoke: sort/filter/resize/export on all three new grids, id-link navigation, drill/refresh still populate them correctly | ☐ | needs running app |

## Deferred / future

- `j`/`k` grid row navigation, `n` focus-note shortcuts (Option C stretch)
- "Auto-advance on close" (open question #3 — needs stakeholder answer)
- Server-side (per-user DB) layout preference instead of localStorage
- <1440px responsive audit (open question #4)
