Skip to content

refactor(components): extract useDraftLifecycle hook#61

Merged
saagpatel merged 1 commit into
masterfrom
codex/refactor/wave5-7-draft-lifecycle
Apr 21, 2026
Merged

refactor(components): extract useDraftLifecycle hook#61
saagpatel merged 1 commit into
masterfrom
codex/refactor/wave5-7-draft-lifecycle

Conversation

@saagpatel
Copy link
Copy Markdown
Owner

What

Consolidates the six orchestration `useEffect`s in `DraftTab.tsx` into one `useDraftLifecycle` hook:

  • on-mount `refreshWorkspaceCatalog()`
  • input-change `findSimilar()` + dismissal-reset
  • `savedDraftId` → `loadAlternatives()`
  • Cmd-1/2/3 keyboard listener for panel density modes (with editable-target and conversation-mode guards)
  • `initialDraft` prop replay on mount
  • on-mount `loadTemplates()`

Also moves `isEditableTarget` — the helper used only by the keyboard listener — into the hook.

Shell reduction: 1451 → 1393 LOC (-58 on this PR).

Why

These effects are all orchestration glue that runs on mount or on dependency changes to drive downstream state. None of them own local state the shell still uses — they're pure side-effect producers. Collapsing them behind one hook call removes six `useEffect` blocks + their dep arrays + their inline comment banners + the `isEditableTarget` helper function from the shell.

How

  1. Create `useDraftLifecycle.ts` that takes all six effects' inputs as one options object and wires them up internally.
  2. Delete the six `useEffect` blocks from the shell.
  3. Delete the `isEditableTarget` helper from the shell (now lives in the hook).
  4. Prune the now-unused `useEffect` import from the React import line.
  5. Call the hook once from the shell after `useWorkspaceDraftState` (needs `handleLoadDraft`) and after `handlePanelDensityModeChange` (the shell's local callback).
  6. Add `useDraftLifecycle.test.ts` with 7 tests covering: mount effects, input debounce, savedDraftId loader, initialDraft replay, Cmd-1/2/3 dispatch, conversation-mode keyboard skip, editable-target keyboard skip.

Testing

  • `pnpm tsc --noEmit` — clean.
  • `pnpm test` — 241 pass (was 234; +7 new hook tests).
  • `pnpm ui:gate:static` — exit 0.

Risk / Notes

  • `DraftTabHandle` unchanged.
  • Effect ordering preserved — React still runs them in declaration order, which in the new hook matches the shell's previous order exactly.
  • Keyboard shortcut guards (metaKey required; altKey/ctrlKey exclude; editable-target skip; conversation-mode skip) preserved verbatim.

Wave 5 status after this PR

  • DraftTab: 2573 → 1393 LOC (-1180, ~46% total reduction)
  • Tests: 184 → 241 (+57 direct Draft concern tests)
  • 13 hooks + 1 panel + 1 handle pin extracted
  • ~393 LOC above the 1000 success target. Remaining paths: a `useDraftShellState` bundle for base state declarations, or a `useDraftPanels` helper that consolidates the JSX builder blocks (inputPanel / diagnosisPanel / responsePanel / workspacePanel / dialogs / viewToggle / workflowStrip) into one call.

Consolidate the six orchestration useEffects that remained in the
DraftTab shell (workspace-catalog refresh on mount, similar-response
suggestion debounce, savedDraftId->loadAlternatives, Cmd-1/2/3
panel-density keyboard listener, initialDraft replay, loadTemplates
on mount) into a dedicated hook. Shell drops from 1451 to 1393 LOC
and gains seven renderHook tests exercising each effect plus the
keyboard shortcut's editable-target + conversation-mode guards.
@saagpatel saagpatel merged commit ca16719 into master Apr 21, 2026
16 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants