Skip to content

feat: extract page tree logic into testable utility (#113)#117

Merged
zacharias-ona merged 1 commit into
mainfrom
feat/113-extract-page-tree-logic
Apr 16, 2026
Merged

feat: extract page tree logic into testable utility (#113)#117
zacharias-ona merged 1 commit into
mainfrom
feat/113-extract-page-tree-logic

Conversation

@zacharias-ona
Copy link
Copy Markdown
Collaborator

Closes #113

What

Extracts pure tree-manipulation logic from src/components/sidebar/page-tree.tsx (836 lines) into src/lib/page-tree.ts — a side-effect-free utility module with no React or Supabase dependencies.

How

New file: src/lib/page-tree.ts — 10 exported functions:

  • buildTree — flat pages → nested TreeNode[] hierarchy
  • getDescendantIds — collect all descendant IDs recursively
  • findNode — locate a node by ID in the tree
  • getNextSiblingPosition — next available position among siblings
  • getSortedSiblings — siblings sorted by position
  • computeSwapPositions — position swaps for move up/down
  • computeNest — new parent_id and position for nesting under preceding sibling
  • computeUnnest — parent_id, position, and sibling shifts for unnesting
  • computeDrop — full update set for drag-and-drop (inside/before/after)
  • TreeNode type export

Updated: src/components/sidebar/page-tree.tsx — imports and uses the extracted functions. All Supabase mutation calls remain in the component. Also improved the fetchPages effect to use an inline async function with cancellation cleanup (fixes a lint warning from react-hooks/set-state-in-effect).

New file: src/lib/page-tree.test.ts — 35 unit tests covering:

  • Tree building: flat list → hierarchy, orphan handling, position sorting, empty input
  • Descendant collection: recursive traversal, leaf nodes
  • Node finding: root, nested, missing
  • Position calculation: empty siblings, max+1, parent scoping
  • Reorder: swap up/down, boundary cases, missing page
  • Nest: under preceding sibling, after existing children, first sibling (impossible), missing page
  • Unnest: to parent level with sibling shifts, root page (impossible), deep nesting
  • Drop: self-drop, descendant prevention, inside/before/after, cross-parent moves

Testing

  • pnpm lint
  • pnpm typecheck
  • pnpm test — 93 tests pass (35 new)
  • pnpm test:e2e — 40 tests pass (including page-crud.spec.ts and sidebar-drag.spec.ts)

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
memo Ready Ready Preview, Comment Apr 16, 2026 10:20pm

Request Review

@zacharias-ona zacharias-ona merged commit 27776cc into main Apr 16, 2026
6 checks passed
@zacharias-ona zacharias-ona deleted the feat/113-extract-page-tree-logic branch April 16, 2026 22:22
@zacharias-ona
Copy link
Copy Markdown
Collaborator Author

✅ UI verification passed — design spec compliance confirmed.

This PR extracts pure logic functions from page-tree.tsx into src/lib/page-tree.ts without modifying any JSX, styling, or visual output. No color tokens, typography, spacing, component usage, accessibility attributes, or layout were changed. Visual screenshot verification was skipped as the rendered UI is identical.

@zacharias-ona
Copy link
Copy Markdown
Collaborator Author

✅ Post-merge verification passed.

E2E suite: 35/42 passed, 4 did not run (dependent on a failed test).

3 pre-existing failures (unrelated to this PR's page-tree changes):

  • members.spec.ts — "owner can revoke a pending invite" (invite row doesn't disappear after revocation)
  • search.spec.ts — "typing in search input shows matching results" (search results not rendering)
  • search.spec.ts — "search with no matches shows empty state" (empty state not rendering)

These tests exercise member management and search — code paths not touched by this PR.

Ad-hoc smoke tests: All passed.

  • ✅ Landing page — loads, has title
  • /sign-in — renders email input
  • /api/health — returns healthy status
  • ✅ Authenticated login flow — redirects to workspace
  • ✅ Workspace page — fully loaded
  • ✅ Page navigation via sidebar — editor route loads with contenteditable element
  • ✅ No console errors (unauthenticated or authenticated)

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.

refactor: extract page tree logic into testable utility

1 participant