feat(desktop): add local v1/v2 version toggle in top bar#3347
Conversation
When the v2 feature flag is enabled remotely, a segmented toggle appears in the top bar (next to resource consumption) that lets you switch between v1 and v2 locally without changing the PostHog flag. The preference persists in localStorage across app restarts.
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThe changes introduce a centralized feature flag management pattern by creating a Changes
Sequence DiagramsequenceDiagram
actor User
participant VersionToggle
participant V2LocalOverrideStore
participant useIsV2CloudEnabled
participant PostHog
participant TopBar/UI
User->>VersionToggle: Click toggle button
VersionToggle->>V2LocalOverrideStore: Call toggle()
V2LocalOverrideStore->>V2LocalOverrideStore: Flip forceV1 state<br/>(persist to localStorage)
V2LocalOverrideStore-->>useIsV2CloudEnabled: State change detected
useIsV2CloudEnabled->>PostHog: Read FEATURE_FLAGS.V2_CLOUD
PostHog-->>useIsV2CloudEnabled: Return remote flag state
useIsV2CloudEnabled->>V2LocalOverrideStore: Read forceV1 value
V2LocalOverrideStore-->>useIsV2CloudEnabled: Return forceV1
useIsV2CloudEnabled->>useIsV2CloudEnabled: Compute isV2CloudEnabled<br/>(remote && !forceV1)
useIsV2CloudEnabled-->>TopBar/UI: Return { isV2CloudEnabled, isRemoteV2Enabled }
TopBar/UI->>TopBar/UI: Re-render with updated state
TopBar/UI-->>User: Display active version (V1 or V2)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR adds a local v1/v2 version toggle pill in the desktop app's top bar, visible when the PostHog Key changes:
Confidence Score: 4/5Safe to merge — core logic is correct and migration is complete; one non-critical UX quirk remains in the toggle interaction model. All V2_CLOUD flag usages are correctly centralized, the Zustand store uses the right middleware ordering and persist key, and the conditional rendering logic is sound. The only functional concern is that the segmented control acts as a blind toggle rather than an explicit selector, which could confuse users who click the already-active segment. This doesn't break any functionality but is worth addressing before widespread use. apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/VersionToggle/VersionToggle.tsx — UX interaction model and accessibility Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
PH[PostHog: V2_CLOUD flag] --> hook[useIsV2CloudEnabled]
LS[localStorage: v2-local-override
forceV1: boolean] --> store[useV2LocalOverrideStore]
store --> hook
hook -->|isRemoteV2Enabled| TopBar
hook -->|isV2CloudEnabled| TopBar
hook -->|isV2CloudEnabled| DashboardLayout
hook -->|isV2CloudEnabled| AuthenticatedLayout
hook -->|isV2CloudEnabled| TerminalSettings
TopBar -->|isRemoteV2Enabled === true| VersionToggle
VersionToggle -->|toggle| store
subgraph Effective State
A{remoteV2Enabled?}
A -- No --> V1[App runs V1]
A -- Yes --> B{forceV1?}
B -- Yes --> V1
B -- No --> V2[App runs V2]
end
hook --> A
Reviews (1): Last reviewed commit: "lint" | Re-trigger Greptile |
| <TooltipTrigger asChild> | ||
| <button | ||
| type="button" | ||
| onClick={toggle} | ||
| className="no-drag flex items-center h-6 rounded-full bg-muted border border-border text-[11px] font-medium overflow-hidden transition-colors" |
There was a problem hiding this comment.
Segmented control acts as a blind toggle, not a selector
The entire <button> has a single onClick={toggle}. This means clicking the already-active segment also flips to the other version, which is unexpected UX for a segmented control — users expect clicking the active segment to be a no-op.
Consider splitting into two independent <button> elements that each set an explicit target state instead of toggling:
<button
type="button"
onClick={() => useV2LocalOverrideStore.getState().setForceV1(true)}
className={cn("px-2 py-0.5 rounded-full transition-colors", forceV1 ? "bg-foreground text-background" : "text-muted-foreground hover:text-foreground")}
>
v1
</button>
<button
type="button"
onClick={() => useV2LocalOverrideStore.getState().setForceV1(false)}
className={cn("px-2 py-0.5 rounded-full transition-colors", !forceV1 ? "bg-foreground text-background" : "text-muted-foreground hover:text-foreground")}
>
v2
</button>This would require adding a setForceV1(value: boolean) action alongside toggle in the store.
🧹 Preview Cleanup CompleteThe following preview resources have been cleaned up:
Thank you for your contribution! 🎉 |
…#3347) * feat(desktop): add local v1/v2 version toggle in top bar When the v2 feature flag is enabled remotely, a segmented toggle appears in the top bar (next to resource consumption) that lets you switch between v1 and v2 locally without changing the PostHog flag. The preference persists in localStorage across app restarts. * lint
Summary
useIsV2CloudEnabledhookTest plan
Summary by cubic
Adds a local v1/v2 toggle in the desktop top bar that appears only when the remote V2 flag is on. Users can switch versions locally and the choice persists across restarts.
New Features
useV2LocalOverrideStoreusingzustandpersistto save preference in localStorage.useIsV2CloudEnabledexposingisV2CloudEnabledandisRemoteV2Enabled.Refactors
V2_CLOUDchecks intouseIsV2CloudEnabledand updated TopBar, dashboard layout, authenticated layout, and terminal settings to use it.Written for commit 7ef3d28. Summary will update on new commits.
Summary by CodeRabbit