mirror of
https://github.com/supabase/supabase.git
synced 2026-10-11 20:35:07 +03:00
feat(studio): add SidebarToolbar feature preview toggle
This commit is contained in:
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'
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in new issue
Block a user