Skip to content

feat(web): add repo tab strip, move nav into shell - #26

Merged
ripgrim merged 2 commits into
mainfrom
feat/repo-tabs
Aug 19, 2026
Merged

feat(web): add repo tab strip, move nav into shell#26
ripgrim merged 2 commits into
mainfrom
feat/repo-tabs

Conversation

@ripgrim

@ripgrim ripgrim commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

the topbar belongs to the window now — open-repo strip, switcher,
account. the page tree for whatever scope the url is in moved down
into the page shell (ShellNav), so org pages carry their nav on
every breakpoint, mobile included, where the footer is the strip.

tabs

  • persisted to localStorage (tripwire.repo-tabs.v2)
  • keyed off the matched /$org/$repo route, not the pathname, so
    /$org/home and /admin/* can never open one
  • each tab remembers its own last page; switching away and back
    returns you there
  • opening is a side effect of navigation, not a click handler —
    links, palette, pasted urls and back all land the same tab
  • closing the active tab moves you right, then left, then org home

state is a pure reducer with unit tests. no stored "active tab":
the url is the scope (§8), so the active one is whatever the route
resolves to.

also

  • OrgSubnav dropped, folded into ShellNav
  • MobileFooter is now just the strip
  • org settings link stays on the current page instead of bouncing
    to /$org/home
  • dark --surface-1 #171717 -> #1f1f21

checks

biome, typecheck, boundaries all pass. tabs suite 11/11.
full bun test has 21 integration failures locally — all
createTestDatabase unable to reach the docker daemon, none
related to this diff. ci will settle those.

follow-ups (not blocking)

  • parseStoredRepoTabs doesn't dedupe by id
  • tab list is uncapped; ~20 with oldest-evict would be safer
  • storage write fires on every in-repo navigation, could debounce

Topbar belongs to the window now: it carries the open-repo strip,
switcher and account. The page tree for the current scope moved
into the shell (`ShellNav`), so org pages keep their nav on mobile
where the footer is the tab strip.

Tabs persist to localStorage, keyed off the matched /$org/$repo
route rather than the pathname so /$org/home and /admin/* can't
open one. Each tab remembers its own last page.

- drop OrgSubnav, folded into ShellNav
- MobileFooter is now just the tab strip
- org Settings link stays on the current page instead of
  bouncing to /$org/home
- dark --surface-1 #171717 -> #1f1f21
The re-run scope hangs off repo.org_id, which only gets set when an
install is claimed. The fixture predates claims and synced its repos
with the 4-arg call, so org_id stayed null, the scope block in
loadRunView was skipped and repoName came back null.

Claiming the install exercises that block for the first time, which
surfaced a second problem: apps/web dynamically imports drizzle-orm
in ~14 server modules without declaring it. Bundled builds resolve it
through the root, bun test does not. Declared it.

- test seeds an org + organization_installations claim, syncs with
  the resolved org id
- user-1 stays a non-member, so the session view surfaces the scope
  and still refuses the re-run
@ripgrim
ripgrim merged commit 68ef1b3 into main Aug 19, 2026
1 check 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.

1 participant