Skip to content

fix(canvas): make the channel sidebar feel instant#2681

Merged
raquelmsmith merged 3 commits into
mainfrom
posthog-code/instant-channel-in-sidebar
Jun 15, 2026
Merged

fix(canvas): make the channel sidebar feel instant#2681
raquelmsmith merged 3 commits into
mainfrom
posthog-code/instant-channel-in-sidebar

Conversation

@raquelmsmith

@raquelmsmith raquelmsmith commented Jun 15, 2026

Copy link
Copy Markdown
Member

The channel sidebar felt slow in two ways. Both come down to the same backing query — ["canvas-channels"], populated by a paginated GET over the desktop file system — and this PR fixes each.

1. A newly-created channel was slow to appear

On create, the code only called invalidateQueries, forcing a full re-fetch to complete before the new channel showed up — even though the create API already returns the fully-formed channel.

Fix: createMutation.onSuccess now writes the returned channel straight into the cache, then invalidates to reconcile in the background. The sidebar selector already sorts folders alphabetically, so it lands in the right spot the instant the POST resolves — before navigation completes. A duplicate-id guard avoids a double insert if the 30s poll landed it first.

2. The channel list was slow to load on app start

getDesktopFileSystem() fetched every entry in the desktop file system — all dashboards and filed tasks too — page by page, up to 50 sequential round-trips, then filtered to type === "folder" on the client. On startup the sidebar waited for that whole tree walk.

Fix: filter to type=folder server-side and request a larger page (limit=200), so the common case is a single round-trip returning only channels. The endpoint already accepts type filtering (channel tasks use type=task). The returned set is identical to the prior client-side filter, so behavior is unchanged. Renamed getDesktopFileSystemgetDesktopFileSystemChannels to reflect the narrowed contract (its only caller is this sidebar).

Verification

  • useChannels.test.tsx proves the created channel appears from the optimistic write while the refetch is hung.
  • pnpm --filter @posthog/api-client typecheck, pnpm --filter @posthog/ui typecheck, the UI test, and Biome all clean.

🤖 Generated with Claude Code

Creating a channel only invalidated the ["canvas-channels"] query, which
forced a full paginated re-fetch of the desktop file system before the new
channel appeared in the left sidebar — making the app feel unresponsive.

The create API already returns the fully-formed channel, so insert it into
the query cache on success and let the invalidation reconcile in the
background. The sidebar selector already sorts folders alphabetically, so the
new channel lands in the right position instantly.

Adds a test asserting the channel appears from the optimistic cache write
without waiting on the refetch.

Generated-By: PostHog Code
Task-Id: fcd3b6b6-ee4f-4861-9bba-c0ea91b13262
@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit 012dc62.

@greptile-apps

greptile-apps Bot commented Jun 15, 2026

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

---

### Issue 1 of 2
packages/ui/src/features/canvas/hooks/useChannels.test.tsx:17-20
**Mock object cast avoids required interface fields**

`{ id, path, type: "folder" } as unknown as Schemas.FileSystem` sidesteps any additional required fields in the `FileSystem` interface. If the interface gains a required field that the production code relies on, these tests will silently pass with incomplete mocks. Prefer populating all required fields so TypeScript catches drift (or use a typed factory that provides safe defaults).

### Issue 2 of 2
packages/ui/src/features/canvas/hooks/useChannels.test.tsx:37-63
**Duplicate-ID guard has no test**

The PR description explicitly calls out "a duplicate-id guard avoids a double insert if the 30s poll landed it first," but only the happy-path insertion is exercised here. A second test case — seed the list with the created channel already present, call `createChannel`, and assert the list length hasn't grown — would give that guard the same coverage as the optimistic-insert path.

Reviews (1): Last reviewed commit: "fix(canvas): show newly created channel ..." | Re-trigger Greptile

Comment thread packages/ui/src/features/canvas/hooks/useChannels.test.tsx
Comment thread packages/ui/src/features/canvas/hooks/useChannels.test.tsx
Listing channels fetched the entire desktop file system — every dashboard
and filed task included — page by page (up to 50 sequential round-trips),
then filtered to type === "folder" on the client. On startup this delayed the
sidebar until the whole tree had been walked.

Filter to type=folder server-side and request a larger page (limit=200), so
the common case is a single round-trip returning only channels. The endpoint
already accepts type filtering (channel tasks use type=task). The result set
is identical to the prior client-side filter, so the sidebar's defensive
folder filter is retained but now a no-op.

Renames getDesktopFileSystem -> getDesktopFileSystemChannels to reflect the
narrowed contract; its only caller is the channel sidebar.

Generated-By: PostHog Code
Task-Id: fcd3b6b6-ee4f-4861-9bba-c0ea91b13262
@raquelmsmith raquelmsmith changed the title fix(canvas): show newly created channel in sidebar immediately fix(canvas): make the channel sidebar feel instant Jun 15, 2026
Address review feedback on useChannels.test.tsx:

- Replace the `as unknown as Schemas.FileSystem` cast with a factory that
  populates all required fields, so TypeScript catches interface drift.
- Add a test for the duplicate-id guard: when the poll has already landed the
  channel, creating it again keeps the list at one entry.

Generated-By: PostHog Code
Task-Id: fcd3b6b6-ee4f-4861-9bba-c0ea91b13262
@raquelmsmith raquelmsmith marked this pull request as ready for review June 15, 2026 17:14
@greptile-apps

greptile-apps Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Reviews (2): Last reviewed commit: "test(canvas): type the channel fixture a..." | Re-trigger Greptile

@raquelmsmith raquelmsmith requested a review from adamleithp June 15, 2026 17:17
@raquelmsmith raquelmsmith merged commit a3dd3fd into main Jun 15, 2026
27 checks passed
@raquelmsmith raquelmsmith deleted the posthog-code/instant-channel-in-sidebar branch June 15, 2026 17:18
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