From 8a82cc209a403c21e462b1590712a6cb161252f8 Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Sat, 25 Apr 2026 19:15:20 -0700 Subject: [PATCH 1/3] move v2 toggle to experimental settings --- .../_dashboard/components/TopBar/TopBar.tsx | 4 +- .../VersionToggle/VersionToggle.tsx | 46 -------------- .../TopBar/components/VersionToggle/index.ts | 1 - .../SettingsSidebar/GeneralSettings.tsx | 8 +++ .../ExperimentalSettings.tsx | 61 +++++++++++++++++++ .../components/ExperimentalSettings/index.ts | 1 + .../settings/experimental/page.tsx | 22 +++++++ .../routes/_authenticated/settings/layout.tsx | 4 ++ .../utils/settings-search/settings-search.ts | 22 +++++++ .../src/renderer/stores/settings-state.ts | 1 + .../src/renderer/stores/v2-local-override.ts | 2 + 11 files changed, 122 insertions(+), 50 deletions(-) delete mode 100644 apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/VersionToggle/VersionToggle.tsx delete mode 100644 apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/VersionToggle/index.ts create mode 100644 apps/desktop/src/renderer/routes/_authenticated/settings/experimental/components/ExperimentalSettings/ExperimentalSettings.tsx create mode 100644 apps/desktop/src/renderer/routes/_authenticated/settings/experimental/components/ExperimentalSettings/index.ts create mode 100644 apps/desktop/src/renderer/routes/_authenticated/settings/experimental/page.tsx diff --git a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/TopBar.tsx b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/TopBar.tsx index 397c4ed4e62..f753391ed28 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/TopBar.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/TopBar.tsx @@ -13,7 +13,6 @@ import { SearchBarTrigger } from "./components/SearchBarTrigger"; import { SidebarToggle } from "./components/SidebarToggle"; import { V2WorkspaceOpenInButton } from "./components/V2WorkspaceOpenInButton"; import { V2WorkspaceSearchBarTrigger } from "./components/V2WorkspaceSearchBarTrigger"; -import { VersionToggle } from "./components/VersionToggle"; import { WindowControls } from "./components/WindowControls"; export function TopBar() { @@ -31,7 +30,7 @@ export function TopBar() { { enabled: !!workspaceId && !isV2WorkspaceRoute }, ); const isOnline = useOnlineStatus(); - const { isV2CloudEnabled, isRemoteV2Enabled } = useIsV2CloudEnabled(); + const { isV2CloudEnabled } = useIsV2CloudEnabled(); // Default to Mac layout while loading to avoid overlap with traffic lights const isMac = platform === undefined || platform === "darwin"; @@ -46,7 +45,6 @@ export function TopBar() { - {isRemoteV2Enabled && } {isV2WorkspaceRoute ? ( diff --git a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/VersionToggle/VersionToggle.tsx b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/VersionToggle/VersionToggle.tsx deleted file mode 100644 index 33462108871..00000000000 --- a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/VersionToggle/VersionToggle.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { Tooltip, TooltipContent, TooltipTrigger } from "@superset/ui/tooltip"; -import { cn } from "@superset/ui/utils"; -import { useV2LocalOverrideStore } from "renderer/stores/v2-local-override"; - -export function VersionToggle() { - const { forceV1, toggle } = useV2LocalOverrideStore(); - const activeVersion = forceV1 ? "v1" : "v2"; - - return ( - - - - - - {forceV1 - ? "Early Access: Switch to Superset V2" - : "Switch to Superset V1"} - - - ); -} diff --git a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/VersionToggle/index.ts b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/VersionToggle/index.ts deleted file mode 100644 index 3e06c734ddd..00000000000 --- a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/VersionToggle/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { VersionToggle } from "./VersionToggle"; diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/components/SettingsSidebar/GeneralSettings.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/components/SettingsSidebar/GeneralSettings.tsx index 0905de1ef99..9d13ea7b860 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/components/SettingsSidebar/GeneralSettings.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/components/SettingsSidebar/GeneralSettings.tsx @@ -1,6 +1,7 @@ import { cn } from "@superset/ui/utils"; import { Link, useMatchRoute } from "@tanstack/react-router"; import { + HiOutlineBeaker, HiOutlineBell, HiOutlineBuildingOffice2, HiOutlineCommandLine, @@ -35,6 +36,7 @@ type SettingsRoute = | "/settings/terminal" | "/settings/links" | "/settings/models" + | "/settings/experimental" | "/settings/integrations" | "/settings/billing" | "/settings/api-keys" @@ -123,6 +125,12 @@ const SECTION_GROUPS: SectionGroup[] = [ label: "Models", icon: , }, + { + id: "/settings/experimental", + section: "experimental", + label: "Experimental", + icon: , + }, ], }, { diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/experimental/components/ExperimentalSettings/ExperimentalSettings.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/experimental/components/ExperimentalSettings/ExperimentalSettings.tsx new file mode 100644 index 00000000000..90c4da1646d --- /dev/null +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/experimental/components/ExperimentalSettings/ExperimentalSettings.tsx @@ -0,0 +1,61 @@ +import { Label } from "@superset/ui/label"; +import { Switch } from "@superset/ui/switch"; +import { useIsV2CloudEnabled } from "renderer/hooks/useIsV2CloudEnabled"; +import { useV2LocalOverrideStore } from "renderer/stores/v2-local-override"; +import { + isItemVisible, + SETTING_ITEM_ID, + type SettingItemId, +} from "../../../utils/settings-search"; + +interface ExperimentalSettingsProps { + visibleItems?: SettingItemId[] | null; +} + +export function ExperimentalSettings({ + visibleItems, +}: ExperimentalSettingsProps) { + const showSupersetV2 = isItemVisible( + SETTING_ITEM_ID.EXPERIMENTAL_SUPERSET_V2, + visibleItems, + ); + const { isV2CloudEnabled, isRemoteV2Enabled } = useIsV2CloudEnabled(); + const setForceV1 = useV2LocalOverrideStore((state) => state.setForceV1); + + return ( +
+
+

Experimental

+

+ Try early access features and previews +

+
+ +
+ {showSupersetV2 && ( +
+
+ +

+ Use the new workspace experience when early access is available +

+ {!isRemoteV2Enabled && ( +

+ Early access is not enabled for this account. +

+ )} +
+ setForceV1(!enabled)} + disabled={!isRemoteV2Enabled} + /> +
+ )} +
+
+ ); +} diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/experimental/components/ExperimentalSettings/index.ts b/apps/desktop/src/renderer/routes/_authenticated/settings/experimental/components/ExperimentalSettings/index.ts new file mode 100644 index 00000000000..7f3499d9e21 --- /dev/null +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/experimental/components/ExperimentalSettings/index.ts @@ -0,0 +1 @@ +export { ExperimentalSettings } from "./ExperimentalSettings"; diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/experimental/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/experimental/page.tsx new file mode 100644 index 00000000000..f03700a391b --- /dev/null +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/experimental/page.tsx @@ -0,0 +1,22 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { useMemo } from "react"; +import { useSettingsSearchQuery } from "renderer/stores/settings-state"; +import { getMatchingItemsForSection } from "../utils/settings-search"; +import { ExperimentalSettings } from "./components/ExperimentalSettings"; + +export const Route = createFileRoute("/_authenticated/settings/experimental/")({ + component: ExperimentalSettingsPage, +}); + +function ExperimentalSettingsPage() { + const searchQuery = useSettingsSearchQuery(); + + const visibleItems = useMemo(() => { + if (!searchQuery) return null; + return getMatchingItemsForSection(searchQuery, "experimental").map( + (item) => item.id, + ); + }, [searchQuery]); + + return ; +} diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/layout.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/layout.tsx index 5b1597aad31..55957c7d412 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/layout.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/layout.tsx @@ -34,6 +34,7 @@ const SECTION_ORDER: SettingsSection[] = [ "terminal", "links", "models", + "experimental", "organization", "integrations", "billing", @@ -52,6 +53,7 @@ function getSectionFromPath(pathname: string): SettingsSection | null { if (pathname.includes("/settings/terminal")) return "terminal"; if (pathname.includes("/settings/links")) return "links"; if (pathname.includes("/settings/models")) return "models"; + if (pathname.includes("/settings/experimental")) return "experimental"; if (pathname.includes("/settings/integrations")) return "integrations"; if (pathname.includes("/settings/permissions")) return "permissions"; if (pathname.includes("/settings/project")) return "project"; @@ -80,6 +82,8 @@ function getPathFromSection(section: SettingsSection): string { return "/settings/links"; case "models": return "/settings/models"; + case "experimental": + return "/settings/experimental"; case "integrations": return "/settings/integrations"; case "permissions": diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/utils/settings-search/settings-search.ts b/apps/desktop/src/renderer/routes/_authenticated/settings/utils/settings-search/settings-search.ts index eaf25734214..a332c1ad67c 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/utils/settings-search/settings-search.ts +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/utils/settings-search/settings-search.ts @@ -46,6 +46,8 @@ export const SETTING_ITEM_ID = { MODELS_ANTHROPIC: "models-anthropic", MODELS_OPENAI: "models-openai", + EXPERIMENTAL_SUPERSET_V2: "experimental-superset-v2", + INTEGRATIONS_LINEAR: "integrations-linear", INTEGRATIONS_GITHUB: "integrations-github", INTEGRATIONS_SLACK: "integrations-slack", @@ -704,6 +706,26 @@ export const SETTINGS_ITEMS: SettingsItem[] = [ "auto name", ], }, + { + id: SETTING_ITEM_ID.EXPERIMENTAL_SUPERSET_V2, + section: "experimental", + title: "Try Superset Version 2 (Early Access)", + description: "Switch between Superset V1 and the new V2 experience", + keywords: [ + "experimental", + "experiments", + "v2", + "v1", + "version", + "early access", + "beta", + "preview", + "workspace", + "workspaces", + "toggle", + "switch", + ], + }, { id: SETTING_ITEM_ID.INTEGRATIONS_LINEAR, section: "integrations", diff --git a/apps/desktop/src/renderer/stores/settings-state.ts b/apps/desktop/src/renderer/stores/settings-state.ts index 98d18fe2599..e3a744e3151 100644 --- a/apps/desktop/src/renderer/stores/settings-state.ts +++ b/apps/desktop/src/renderer/stores/settings-state.ts @@ -13,6 +13,7 @@ export type SettingsSection = | "terminal" | "links" | "models" + | "experimental" | "integrations" | "billing" | "apikeys" diff --git a/apps/desktop/src/renderer/stores/v2-local-override.ts b/apps/desktop/src/renderer/stores/v2-local-override.ts index 01b66fb9885..3cfc22b1147 100644 --- a/apps/desktop/src/renderer/stores/v2-local-override.ts +++ b/apps/desktop/src/renderer/stores/v2-local-override.ts @@ -4,6 +4,7 @@ import { devtools, persist } from "zustand/middleware"; interface V2LocalOverrideState { /** When true, forces v1 mode locally even though v2 is enabled remotely. */ forceV1: boolean; + setForceV1: (forceV1: boolean) => void; toggle: () => void; } @@ -12,6 +13,7 @@ export const useV2LocalOverrideStore = create()( persist( (set, get) => ({ forceV1: false, + setForceV1: (forceV1) => set({ forceV1 }), toggle: () => set({ forceV1: !get().forceV1 }), }), { name: "v2-local-override" }, From f710ee078797f8696a3c767ec3bb9edd9365a197 Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Sat, 25 Apr 2026 19:20:38 -0700 Subject: [PATCH 2/3] move experimental settings under system --- .../components/SettingsSidebar/GeneralSettings.tsx | 12 ++++++------ .../routes/_authenticated/settings/layout.tsx | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/components/SettingsSidebar/GeneralSettings.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/components/SettingsSidebar/GeneralSettings.tsx index 9d13ea7b860..74378ce1a31 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/components/SettingsSidebar/GeneralSettings.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/components/SettingsSidebar/GeneralSettings.tsx @@ -125,12 +125,6 @@ const SECTION_GROUPS: SectionGroup[] = [ label: "Models", icon: , }, - { - id: "/settings/experimental", - section: "experimental", - label: "Experimental", - icon: , - }, ], }, { @@ -178,6 +172,12 @@ const SECTION_GROUPS: SectionGroup[] = [ icon: , macOnly: true, }, + { + id: "/settings/experimental", + section: "experimental", + label: "Experimental", + icon: , + }, ], }, ]; diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/layout.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/layout.tsx index 55957c7d412..2bff0a9e57c 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/layout.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/layout.tsx @@ -34,12 +34,12 @@ const SECTION_ORDER: SettingsSection[] = [ "terminal", "links", "models", - "experimental", "organization", "integrations", "billing", "apikeys", "permissions", + "experimental", ]; function getSectionFromPath(pathname: string): SettingsSection | null { From fca3582c4d4349eb55490b1674e0f4d1789a6f57 Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Sat, 25 Apr 2026 19:27:43 -0700 Subject: [PATCH 3/3] remove unused v2 override toggle --- apps/desktop/src/renderer/stores/v2-local-override.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/desktop/src/renderer/stores/v2-local-override.ts b/apps/desktop/src/renderer/stores/v2-local-override.ts index 3cfc22b1147..c815a605aa2 100644 --- a/apps/desktop/src/renderer/stores/v2-local-override.ts +++ b/apps/desktop/src/renderer/stores/v2-local-override.ts @@ -5,16 +5,14 @@ interface V2LocalOverrideState { /** When true, forces v1 mode locally even though v2 is enabled remotely. */ forceV1: boolean; setForceV1: (forceV1: boolean) => void; - toggle: () => void; } export const useV2LocalOverrideStore = create()( devtools( persist( - (set, get) => ({ + (set) => ({ forceV1: false, setForceV1: (forceV1) => set({ forceV1 }), - toggle: () => set({ forceV1: !get().forceV1 }), }), { name: "v2-local-override" }, ),