Skip to content

Commit 669e1c1

Browse files
committed
🤖 refactor: simplify stats tab experiment to toggle
Convert the Stats Tab experiment setting from a 3-option dropdown (Default/Always on/Always off) to a simple on/off toggle, matching the UX pattern used for other experiments like Post-Compaction Context. Changes: - Replace dropdown with Switch component in ExperimentsSection - Simplify FeatureFlagsContext API: setStatsTabOverride → setStatsTabEnabled - Remove PostHog implementation details from user-facing description - Backend schema unchanged (preserves flexibility) Change-Id: I3dfad1c229690a4806cdbcf2ebb2d758f205c14f Signed-off-by: Thomas Kosiewski <tk@coder.com>
1 parent 32712c6 commit 669e1c1

File tree

2 files changed

+29
-38
lines changed

2 files changed

+29
-38
lines changed

src/browser/components/Settings/sections/ExperimentsSection.tsx

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
type ExperimentId,
77
} from "@/common/constants/experiments";
88
import { Switch } from "@/browser/components/ui/switch";
9-
import { useFeatureFlags, type StatsTabOverride } from "@/browser/contexts/FeatureFlagsContext";
9+
import { useFeatureFlags } from "@/browser/contexts/FeatureFlagsContext";
1010
import { useWorkspaceContext } from "@/browser/contexts/WorkspaceContext";
1111
import { useTelemetry } from "@/browser/hooks/useTelemetry";
1212

@@ -48,35 +48,31 @@ function ExperimentRow(props: ExperimentRowProps) {
4848
);
4949
}
5050

51-
function StatsTabOverrideRow() {
52-
const { statsTabState, setStatsTabOverride } = useFeatureFlags();
51+
function StatsTabRow() {
52+
const { statsTabState, setStatsTabEnabled } = useFeatureFlags();
5353

54-
const onChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
55-
const value = e.target.value as StatsTabOverride;
56-
setStatsTabOverride(value).catch(() => {
57-
// ignore
58-
});
59-
};
54+
const handleToggle = useCallback(
55+
(enabled: boolean) => {
56+
setStatsTabEnabled(enabled).catch(() => {
57+
// ignore
58+
});
59+
},
60+
[setStatsTabEnabled]
61+
);
6062

6163
return (
6264
<div className="flex items-center justify-between py-3">
6365
<div className="flex-1 pr-4">
6466
<div className="text-foreground text-sm font-medium">Stats tab</div>
6567
<div className="text-muted mt-0.5 text-xs">
66-
PostHog experiment-gated timing stats sidebar. Experiment variant:{" "}
67-
{statsTabState?.variant ?? "—"}.
68+
Show timing statistics in the right sidebar
6869
</div>
6970
</div>
70-
<select
71-
className="bg-background text-foreground border-border-light rounded-md border px-2 py-1 text-xs"
72-
value={statsTabState?.override ?? "default"}
73-
onChange={onChange}
74-
aria-label="Stats tab override"
75-
>
76-
<option value="default">Default (experiment)</option>
77-
<option value="on">Always on</option>
78-
<option value="off">Always off</option>
79-
</select>
71+
<Switch
72+
checked={statsTabState?.enabled ?? false}
73+
onCheckedChange={handleToggle}
74+
aria-label="Toggle Stats tab"
75+
/>
8076
</div>
8177
);
8278
}
@@ -105,7 +101,7 @@ export function ExperimentsSection() {
105101
Experimental features that are still in development. Enable at your own risk.
106102
</p>
107103
<div className="divide-border-light divide-y">
108-
<StatsTabOverrideRow />
104+
<StatsTabRow />
109105
{experiments.map((exp) => (
110106
<ExperimentRow
111107
key={exp.id}

src/browser/contexts/FeatureFlagsContext.tsx

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,14 @@ function isStorybook(): boolean {
2626
return false;
2727
}
2828

29-
export type StatsTabVariant = "control" | "stats";
30-
export type StatsTabOverride = "default" | "on" | "off";
31-
3229
export interface StatsTabState {
3330
enabled: boolean;
34-
variant: StatsTabVariant;
35-
override: StatsTabOverride;
3631
}
3732

3833
interface FeatureFlagsContextValue {
3934
statsTabState: StatsTabState | null;
4035
refreshStatsTabState: () => Promise<void>;
41-
setStatsTabOverride: (override: StatsTabOverride) => Promise<void>;
36+
setStatsTabEnabled: (enabled: boolean) => Promise<void>;
4237
}
4338

4439
const FeatureFlagsContext = createContext<FeatureFlagsContextValue | null>(null);
@@ -53,29 +48,29 @@ export function FeatureFlagsProvider(props: { children: ReactNode }) {
5348
const { api } = useAPI();
5449
const [statsTabState, setStatsTabState] = useState<StatsTabState | null>(() => {
5550
if (isStorybook()) {
56-
return { enabled: true, variant: "stats", override: "default" };
51+
return { enabled: true };
5752
}
5853

5954
return null;
6055
});
6156

6257
const refreshStatsTabState = async (): Promise<void> => {
6358
if (!api) {
64-
setStatsTabState({ enabled: false, variant: "control", override: "default" });
59+
setStatsTabState({ enabled: false });
6560
return;
6661
}
6762

6863
const state = await api.features.getStatsTabState();
69-
setStatsTabState(state);
64+
setStatsTabState({ enabled: state.enabled });
7065
};
7166

72-
const setStatsTabOverride = async (override: StatsTabOverride): Promise<void> => {
67+
const setStatsTabEnabled = async (enabled: boolean): Promise<void> => {
7368
if (!api) {
7469
throw new Error("ORPC client not initialized");
7570
}
7671

77-
const state = await api.features.setStatsTabOverride({ override });
78-
setStatsTabState(state);
72+
const state = await api.features.setStatsTabOverride({ override: enabled ? "on" : "off" });
73+
setStatsTabState({ enabled: state.enabled });
7974
};
8075

8176
useEffect(() => {
@@ -86,22 +81,22 @@ export function FeatureFlagsProvider(props: { children: ReactNode }) {
8681
(async () => {
8782
try {
8883
if (!api) {
89-
setStatsTabState({ enabled: false, variant: "control", override: "default" });
84+
setStatsTabState({ enabled: false });
9085
return;
9186
}
9287

9388
const state = await api.features.getStatsTabState();
94-
setStatsTabState(state);
89+
setStatsTabState({ enabled: state.enabled });
9590
} catch {
9691
// Treat as disabled if we can't fetch.
97-
setStatsTabState({ enabled: false, variant: "control", override: "default" });
92+
setStatsTabState({ enabled: false });
9893
}
9994
})();
10095
}, [api]);
10196

10297
return (
10398
<FeatureFlagsContext.Provider
104-
value={{ statsTabState, refreshStatsTabState, setStatsTabOverride }}
99+
value={{ statsTabState, refreshStatsTabState, setStatsTabEnabled }}
105100
>
106101
{props.children}
107102
</FeatureFlagsContext.Provider>

0 commit comments

Comments
 (0)