feat(studio): add SidebarToolbar feature preview toggle

This commit is contained in:
Francesco Sansalvadore committed 2026-02-09 11:31:04 +01:00
1 parent 6f9dcec049
commit 9ef46aada9
10 files changed
+67 -10

No files matched your search

@@ -50,4 +50,11 @@ export const FEATURE_PREVIEWS = [
isNew: true,
isPlatformOnly: false,
},
{
key: LOCAL_STORAGE_KEYS.UI_PREVIEW_SIDEBAR_TOOLBAR,
name: 'Sidebar Toolbar',
discussionsUrl: 'https://github.com/orgs/supabase/discussions/42462',
isNew: true,
isPlatformOnly: false,
},
] as const
@@ -115,12 +115,20 @@ export const useIsTableFilterBarEnabled = () => {
return flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_TABLE_FILTER_BAR]
}
export const useIsSidebarToolbarEnabled = () => {
const { flags } = useFeaturePreviewContext()
const showSidebarToolbar = useFlag('enableSidebarToolbar')
return showSidebarToolbar && flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_SIDEBAR_TOOLBAR]
}
export const useFeaturePreviewModal = () => {
const [featurePreviewModal, setFeaturePreviewModal] = useQueryState('featurePreviewModal')
const gitlessBranchingEnabled = useFlag('gitlessBranching')
const advisorRulesEnabled = useFlag('advisorRules')
const isUnifiedLogsPreviewAvailable = useFlag('unifiedLogs')
const isSidebarToolbarAvailable = useFlag('enableSidebarToolbar')
const selectedFeatureKeyFromQuery = featurePreviewModal?.trim() ?? null
const showFeaturePreviewModal = selectedFeatureKeyFromQuery !== null
@@ -135,11 +143,13 @@ export const useFeaturePreviewModal = () => {
return advisorRulesEnabled
case 'supabase-ui-preview-unified-logs':
return isUnifiedLogsPreviewAvailable
case 'supabase-ui-sidebar-toolbar':
return isSidebarToolbarAvailable
default:
return true
}
},
[gitlessBranchingEnabled, advisorRulesEnabled, isUnifiedLogsPreviewAvailable]
[gitlessBranchingEnabled, advisorRulesEnabled, isUnifiedLogsPreviewAvailable, isSidebarToolbarAvailable]
)
const selectedFeatureKey = (
@@ -14,6 +14,7 @@ import { CLSPreview } from './CLSPreview'
import { FEATURE_PREVIEWS } from './FeaturePreview.constants'
import { useFeaturePreviewContext, useFeaturePreviewModal } from './FeaturePreviewContext'
import { QueueOperationsPreview } from './QueueOperationsPreview'
import { SidebarToolbarPreview } from './SidebarToolbarPreview'
import { TableFilterBarPreview } from './TableFilterBarPreview'
import { UnifiedLogsPreview } from './UnifiedLogsPreview'
@@ -27,6 +28,7 @@ const FEATURE_PREVIEW_KEY_TO_CONTENT: {
[LOCAL_STORAGE_KEYS.UI_PREVIEW_UNIFIED_LOGS]: <UnifiedLogsPreview />,
[LOCAL_STORAGE_KEYS.UI_PREVIEW_QUEUE_OPERATIONS]: <QueueOperationsPreview />,
[LOCAL_STORAGE_KEYS.UI_PREVIEW_TABLE_FILTER_BAR]: <TableFilterBarPreview />,
[LOCAL_STORAGE_KEYS.UI_PREVIEW_SIDEBAR_TOOLBAR]: <SidebarToolbarPreview />,
}
const FeaturePreviewModal = () => {
@@ -0,0 +1,31 @@
import { BASE_PATH } from 'lib/constants'
import Image from 'next/image'
export const SidebarToolbarPreview = () => {
return (
<div className="flex flex-col gap-2">
<p className="text-foreground-light text-sm mb-4">
Enable a dedicated vertical toolbar on the right side of the dashboard for accessing side
panels. This creates a consistent, repeatable pattern for opening panels while reducing
clutter in the top navigation bar.
</p>
<Image
src={`${BASE_PATH}/img/previews/sidebar-toolbar-preview.png`}
width={1296}
height={900}
alt="sidebar-toolbar-preview"
className="rounded border"
/>
<div className="space-y-2 !mt-4">
<p className="text-sm">Enabling this preview will:</p>
<ul className="list-disc pl-6 text-sm text-foreground-light space-y-1">
<li>Add a dedicated sidebar toolbar on the right side of the dashboard</li>
<li>
Move the Help, Advisors, SQL Editor, and AI Assistant buttons from the top navigation
bar to the new sidebar toolbar
</li>
</ul>
</div>
</div>
)
}
@@ -1,4 +1,3 @@
import { useFlag } from 'common'
import { ProfileImage } from 'components/ui/ProfileImage'
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
import { IS_PLATFORM } from 'lib/constants'
@@ -25,7 +24,10 @@ import {
} from 'ui'
import { useCommandMenuOpenedTelemetry, useSetCommandMenuOpen } from 'ui-patterns/CommandMenu'
import { useFeaturePreviewModal } from './App/FeaturePreview/FeaturePreviewContext'
import {
useFeaturePreviewModal,
useIsSidebarToolbarEnabled,
} from './App/FeaturePreview/FeaturePreviewContext'
export function UserDropdown() {
const router = useRouter()
@@ -34,7 +36,7 @@ export function UserDropdown() {
const profileShowEmailEnabled = useIsFeatureEnabled('profile:show_email')
const { username, avatarUrl, primaryEmail, isLoading } = useProfileNameAndPicture()
const showSidebarToolbar = useFlag('enableSidebarToolbar')
const showSidebarToolbar = useIsSidebarToolbarEnabled()
const setCommandMenuOpen = useSetCommandMenuOpen()
const sendTelemetry = useCommandMenuOpenedTelemetry()
const { openFeaturePreviewModal } = useFeaturePreviewModal()
@@ -1,4 +1,4 @@
import { LOCAL_STORAGE_KEYS, useFlag, useParams } from 'common'
import { LOCAL_STORAGE_KEYS, useParams } from 'common'
import { AppBannerWrapper } from 'components/interfaces/App/AppBannerWrapper'
import { Sidebar } from 'components/interfaces/Sidebar'
import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage'
@@ -8,6 +8,7 @@ import { PropsWithChildren } from 'react'
import { useAppStateSnapshot } from 'state/app-state'
import { ResizablePanel, ResizablePanelGroup, SidebarProvider } from 'ui'
import { useIsSidebarToolbarEnabled } from '../interfaces/App/FeaturePreview/FeaturePreviewContext'
import { LayoutHeader } from './ProjectLayout/LayoutHeader/LayoutHeader'
import { LayoutSidebar } from './ProjectLayout/LayoutSidebar'
import { LayoutSidebarProvider } from './ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
@@ -39,7 +40,7 @@ export const DefaultLayout = ({
const router = useRouter()
const appSnap = useAppStateSnapshot()
const showProductMenu = !!ref && router.pathname !== '/project/[ref]'
const showSidebarToolbar = useFlag('enableSidebarToolbar')
const showSidebarToolbar = useIsSidebarToolbarEnabled()
const [lastVisitedOrganization] = useLocalStorageQuery(
LOCAL_STORAGE_KEYS.LAST_VISITED_ORGANIZATION,
@@ -1,5 +1,8 @@
import { LOCAL_STORAGE_KEYS, useFlag, useParams } from 'common'
import { useIsBranching2Enabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
import { LOCAL_STORAGE_KEYS, useParams } from 'common'
import {
useIsBranching2Enabled,
useIsSidebarToolbarEnabled,
} from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
import { LocalDropdown } from 'components/interfaces/LocalDropdown'
import { UserDropdown } from 'components/interfaces/UserDropdown'
import { AdvisorButton } from 'components/layouts/AppLayout/AdvisorButton'
@@ -74,7 +77,7 @@ export const LayoutHeader = ({
const { setMobileMenuOpen } = useAppStateSnapshot()
const gitlessBranching = useIsBranching2Enabled()
const showSidebarToolbar = useFlag('enableSidebarToolbar')
const showSidebarToolbar = useIsSidebarToolbarEnabled()
const connectSheetFlag = usePHFlag<string | boolean>('connectSheet')
const isFlagResolved = connectSheetFlag !== undefined
const isConnectSheetEnabled = connectSheetFlag === true || connectSheetFlag === 'variation'
+1 -1
View File
@@ -13,7 +13,7 @@ interface ProfileImageProps {
export const ProfileImage = ({ alt, src, placeholder, className }: ProfileImageProps) => {
const [hasInvalidImg, setHasInvalidImg] = useState(false)
return !!src && !hasInvalidImg ? (
return !src && !hasInvalidImg ? (
<Image
alt={alt ?? ''}
src={src}
Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

@@ -20,6 +20,7 @@ export const LOCAL_STORAGE_KEYS = {
UI_PREVIEW_ADVISOR_RULES: 'supabase-ui-advisor-rules',
UI_PREVIEW_QUEUE_OPERATIONS: 'supabase-ui-queue-operations',
UI_PREVIEW_TABLE_FILTER_BAR: 'supabase-ui-table-filter-bar',
UI_PREVIEW_SIDEBAR_TOOLBAR: 'supabase-ui-sidebar-toolbar',
NEW_LAYOUT_NOTICE_ACKNOWLEDGED: 'new-layout-notice-acknowledge',
TABS_INTERFACE_ACKNOWLEDGED: 'tabs-interface-acknowledge',