Skip to content

refactor: decompose Sidebar (#115)#130

Merged
nkcoder merged 1 commit into
mainfrom
refactor/115-sidebar-decompose
Jul 4, 2026
Merged

refactor: decompose Sidebar (#115)#130
nkcoder merged 1 commit into
mainfrom
refactor/115-sidebar-decompose

Conversation

@nkcoder

@nkcoder nkcoder commented Jul 4, 2026

Copy link
Copy Markdown
Owner

What

Final slice of #115 (M2 — oversized components). Decomposes Sidebar.tsx (1652 → 315 lines) into focused modules. No behavior change — the whole tree renders identically; only Sidebar is imported externally (by App.tsx), so all 13 integration test suites pass unchanged.

New modules

  • lib/sidebarTypes.ts (81) — tree-node + metadata interfaces
  • lib/sidebarNodes.ts (61) — pure emptyFolder / makeTableNode / hydrateSchemaNodes, now unit-tested in sidebarNodes.test.ts (8 tests)
  • hooks/useSidebarTree.ts (312) — per-datasource lazy tree: schema/table/sub-folder state, loaders (live + cached-metadata + refresh), and all toggle handlers
  • components/SidebarIcons.tsx (133) — icon glyphs; dedupes the checks/index SVGs that appeared twice inline
  • components/TreeRow.tsx (83) — the TreeRow primitive + ROW_H
  • components/SidebarChrome.tsx (83) — ToolBtn, CtxMenuItem
  • components/SidebarTableNode.tsx (232) — a table row + its five sub-folders and items
  • components/SidebarConnectionNode.tsx (403) — a connection node (schemas → tables → views + saved-queries folder)

Sidebar.tsx now owns only the toolbar / search / tree map / context menu / footer shell and wires the hook to the components.

Acceptance criteria (issue #115 — all three files now done)

  • File meaningfully reduced (1652 → 315)
  • Pure helpers live in a separately unit-tested module (lib/sidebarNodes.ts)
  • No behavior change; design tokens (T.*) and patterns preserved
  • Every resulting file is < 500 lines (largest 403)
  • Suites pass: 464 unit (+8 new) + 91 e2e, tsc, biome clean

Notes

#115)

Split the 1652-line Sidebar.tsx into focused modules:
- lib/sidebarTypes.ts — tree-node + metadata interfaces
- lib/sidebarNodes.ts — pure emptyFolder/makeTableNode/hydrateSchemaNodes (+tests)
- hooks/useSidebarTree.ts — per-datasource tree state, loaders, toggle handlers
- components/SidebarIcons.tsx — icon glyphs (dedupes repeated inline SVGs)
- components/TreeRow.tsx, SidebarChrome.tsx — presentational primitives
- components/SidebarTableNode.tsx + SidebarConnectionNode.tsx — tree render
Sidebar.tsx (315 lines) now owns only the toolbar/search/tree/menu/footer shell.

Every resulting file is <500 lines. No behavior change; 464 unit (+8 new) +
91 e2e pass, tsc + biome clean.
@nkcoder nkcoder merged commit f075e7e into main Jul 4, 2026
2 checks passed
@nkcoder nkcoder deleted the refactor/115-sidebar-decompose branch July 4, 2026 22:14
nkcoder added a commit that referenced this pull request Jul 4, 2026
…131)

* test: cover Find, ConnectionGeneralTab, and session-hook error paths

Fills gaps surfaced while regression-testing the #127#130 refactor:

- e2e/query-editor-find.spec.ts: in-editor Find (Cmd+F) had no e2e
  coverage after the #128 QueryEditor/FindBar split — open/focus/close,
  match count, next/prev navigation, clear-resets.
- ConnectionGeneralTab.test.tsx: the #129-extracted tab had no test
  (40% func) — field edits, port numeric coercion, password
  mask/reveal, isEdit placeholder, derived URL.
- useDatasourceSession: GetCompletions failure during connect/refresh;
  disconnect no-op when nothing is connected.
- useQueryHistory: null history result coerces to [].

* test: raise hooks branch coverage + set two-tier coverage thresholds

Adds the missing hooks-branch tests and turns the flat #51 threshold into
a two-tier gate:

- useSidebarTree.test.ts (new): the hook had no direct test — covers the
  live-load error branches (columns/sub-folder load failures), the
  toggleColumnsFolder guard + toggle, and each sub-folder loader.
- useQueryExecution: non-result-set (DDL) rows-affected path; error leaves
  a pinned tab intact; double-pin preserves the first; close a non-active tab.
- useDatasourceSession: successful refresh clears a same-ds warning; a
  refresh for one ds leaves another ds's warning intact.

hooks branch coverage 78.6% -> 82.7%; overall 89.8% -> 90.6% stmt.

vitest.config.ts: global ratchet floor (90/82/90/91) as a regression gate,
plus higher per-dir floors for pure logic (lib/ 97/90/100/99, hooks/
95/82/95/97). Verified the glob thresholds are enforced.
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.

1 participant