Skip to content

feat(canvas): add code-pane nav section to channels pane#2688

Open
raquelmsmith wants to merge 6 commits into
mainfrom
posthog-code/channels-nav-section
Open

feat(canvas): add code-pane nav section to channels pane#2688
raquelmsmith wants to merge 6 commits into
mainfrom
posthog-code/channels-nav-section

Conversation

@raquelmsmith

@raquelmsmith raquelmsmith commented Jun 16, 2026

Copy link
Copy Markdown
Member

Summary

image

Adds the Code pane's sidebar navigation section — New task, Home, Search, Inbox, Agents, Skills, MCP servers, Command Center — to the Channels pane.

The section is extracted into a single self-contained SidebarNavSection component rendered in both sidebars, so pages stay single-source. For the self-contained destinations (Home, Skills, MCP servers, Command Center), parallel /website/* routes render the same shared view components, so clicking them from the channels sidebar stays in the channels chrome instead of switching back to Code.

Inbox and Agents are deep, route-coupled subsystems (their /code/inbox/* and /code/agents/scouts/* route literals are hardcoded across ~15 components and core constants), so they intentionally still jump to the existing /code routes for now. Search opens the command-menu overlay in place.

Changes

Shared nav section

  • New SidebarNavSection.tsx — holds the full nav block plus every item's data/handlers (active flags from useAppView(), inbox signal-count, Command Center count, HOME_TAB_FLAG gating, click handlers). Reuses the existing *Item components unchanged.
  • SidebarMenu.tsx renders <SidebarNavSection /> (Code pane); __root.tsx renders it in the channels-space left column above ChannelsList.

Stay-in-channels routing

  • New /website/{home,skills,mcp-servers,command-center} route files, each rendering the shared HomeView / SkillsView / McpServersView / CommandCenterView.
  • navigationBridge.ts gains navigateToWebsite* functions; SidebarNavSection picks the /website variant when it renders inside the channels space (detected via router pathname).
  • useAppView.ts maps the /website mirrors to the same view types so sidebar active-state highlighting works identically in either space.
  • WebsiteLayout.tsx surfaces the shared header-store title in its top bar for these channel-less pages (the channels layout has no HeaderRow).

Behavior

  • The nav section appears in the channels sidebar, matching the Code pane.
  • Home / Skills / MCP servers / Command Center clicked from channels render inside the channels chrome (rail + channel sidebar stay), at /website/*, with the matching item active and its title in the content top bar.
  • Inbox / Agents / New task jump to the Code space (unchanged).
  • Search opens the command menu in place.
  • Code pane behaves exactly as before.

Verification

  • pnpm build — all packages build (route tree regenerated).
  • pnpm --filter @posthog/ui typecheck — clean.
  • biome check on changed files (lint + import sorting) — clean.

To try it: pnpm dev, open the Channels space via the AppNav rail (PROJECT_BLUEBIRD_FLAG defaults on in dev), then click Skills / MCP servers / Command Center / Home — you stay in the channels sidebar.

🤖 Generated with Claude Code

Extract the sidebar navigation section (New task, Home, Search, Inbox,
Agents, Skills, MCP servers, Command Center) out of SidebarMenu into a
self-contained SidebarNavSection component, and render it in both the
Code pane and the Channels pane.

The new component wires every item's active state, badge count, and
click handler internally so it works in either layout. Items route to
the existing code-space views; from the Channels pane that switches the
layout back to Code, while Search opens the command menu in place.

Generated-By: PostHog Code
Task-Id: 93824635-f0b3-4b9d-bf15-f31a4e505939
@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit 7363ab0.

@greptile-apps

greptile-apps Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
packages/ui/src/features/sidebar/components/SidebarNavSection.tsx:68-75
**Redundant `useTasks` subscription when composed inside `SidebarMenu`**

`SidebarNavSection` fetches `allTasks` via `useTasks` solely to compute `commandCenterActiveCount`. When this component renders inside `SidebarMenu`, `SidebarMenu` already calls `useTasks` with the identical arguments (`{ showAllUsers, showInternal }`). React Query deduplicates the network request, but there are now two live subscriptions to the same query. The self-containment goal is valid for the Channels pane, but it introduces a redundant hook invocation every time the component is used in the Code pane context.

Reviews (1): Last reviewed commit: "feat(canvas): add code-pane nav section ..." | Re-trigger Greptile

Comment on lines +68 to +75
const showInternal = useSidebarStore((s) => s.showInternal);
const { data: allTasks = [] } = useTasks({ showAllUsers, showInternal });
const taskIds = new Set(allTasks.map((t) => t.id));
const commandCenterCells = useCommandCenterStore((s) => s.cells);
const commandCenterActiveCount = commandCenterCells.filter(
(taskId) => taskId != null && taskIds.has(taskId),
).length;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Redundant useTasks subscription when composed inside SidebarMenu

SidebarNavSection fetches allTasks via useTasks solely to compute commandCenterActiveCount. When this component renders inside SidebarMenu, SidebarMenu already calls useTasks with the identical arguments ({ showAllUsers, showInternal }). React Query deduplicates the network request, but there are now two live subscriptions to the same query. The self-containment goal is valid for the Channels pane, but it introduces a redundant hook invocation every time the component is used in the Code pane context.

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/ui/src/features/sidebar/components/SidebarNavSection.tsx
Line: 68-75

Comment:
**Redundant `useTasks` subscription when composed inside `SidebarMenu`**

`SidebarNavSection` fetches `allTasks` via `useTasks` solely to compute `commandCenterActiveCount`. When this component renders inside `SidebarMenu`, `SidebarMenu` already calls `useTasks` with the identical arguments (`{ showAllUsers, showInternal }`). React Query deduplicates the network request, but there are now two live subscriptions to the same query. The self-containment goal is valid for the Channels pane, but it introduces a redundant hook invocation every time the component is used in the Code pane context.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 7363ab0. SidebarMenu now derives the command-center count from the task map and cells it already holds, and passes it down; SidebarNavSection gates its own useTasks with enabled so it only subscribes when rendered standalone in the Channels pane. No more duplicate subscription in the Code pane, and the component stays self-contained where it has no parent to lean on.

Mirror the self-contained nav destinations (Home, Skills, MCP servers,
Command Center) under /website so clicking them from the channels
sidebar renders inside the channels chrome instead of switching back to
Code. Each mirror route renders the same shared view component, so pages
stay single-source — only the route entry is duplicated.

- Add /website/{home,skills,mcp-servers,command-center} routes rendering
  the shared HomeView/SkillsView/McpServersView/CommandCenterView.
- Add navigateToWebsite* bridge functions; SidebarNavSection picks the
  /website variant when it renders inside the channels space.
- useAppView maps the /website mirrors to the same view types so sidebar
  active-state highlighting works identically in either space.
- WebsiteLayout surfaces the shared header-store title in its top bar for
  these channel-less pages, since the channels layout has no HeaderRow.

Inbox and Agents are deep, route-coupled subsystems; they intentionally
still jump to the /code routes for now.

Generated-By: PostHog Code
Task-Id: 93824635-f0b3-4b9d-bf15-f31a4e505939
Render the same ProjectSwitcher (name, email, org, current project) at
the bottom of the channels sidebar, using the identical wrapper as the
code sidebar's SidebarContent. The component is self-contained (no
props), so it sources its own auth/project data in either space.

Generated-By: PostHog Code
Task-Id: 93824635-f0b3-4b9d-bf15-f31a4e505939
The New task button in the channels sidebar now opens the new-task
screen at /website/new instead of jumping to /code, keeping the channels
chrome. The route renders the same shared TaskInput (with the same
prefill) as the /code/ index, so the page stays single-source.

openTaskInput gains a `space` option; SidebarNavSection passes
space: "website" when it renders inside the channels space.

Generated-By: PostHog Code
Task-Id: 93824635-f0b3-4b9d-bf15-f31a4e505939
A channel's name is used verbatim as its server-side filesystem path
segment, so constrain it to [a-z0-9-] only — no spaces, uppercase, or
other characters.

Add a shared validateChannelName helper in core (with tests) and wire it
into the Create and Rename channel modals: an inline red error shows
under the field and the submit button is disabled until the name is
valid, matching the existing GitBranchDialog validation pattern.

Generated-By: PostHog Code
Task-Id: 8af89649-aa10-4e81-baf6-2c60f2116012
@raquelmsmith raquelmsmith requested a review from adamleithp June 16, 2026 03:40
SidebarNavSection derived the Command Center badge count from its own
useTasks subscription. When composed inside SidebarMenu (the Code pane),
SidebarMenu already subscribes to the identical task query, so this added
a second live subscription to the same data.

Pass the count down from SidebarMenu — which already holds the task map
and command-center cells — and gate the nav section's own useTasks with
`enabled` so it only fetches when rendered standalone in the Channels
pane. The component stays self-contained in that layout while dropping
the duplicate subscription in the Code pane.

Generated-By: PostHog Code
Task-Id: 8af89649-aa10-4e81-baf6-2c60f2116012
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