StorageMenuV2.tsx121 lines · main
1import { IS_PLATFORM, useParams } from 'common'
2import Link from 'next/link'
3import { useRouter } from 'next/router'
4import { Badge, Menu } from 'ui'
5
6import { BUCKET_TYPES } from './Storage.constants'
7import { useStorageV2Page } from './Storage.utils'
8import { ShortcutTooltip } from '@/components/ui/ShortcutTooltip'
9import {
10 useIsAnalyticsBucketsEnabled,
11 useIsVectorBucketsEnabled,
12} from '@/data/config/project-storage-config-query'
13import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
14import { SHORTCUT_IDS, type ShortcutId } from '@/state/shortcuts/registry'
15import { useShortcut } from '@/state/shortcuts/useShortcut'
16
17const BUCKET_TYPE_SHORTCUTS: Record<keyof typeof BUCKET_TYPES, ShortcutId> = {
18 files: SHORTCUT_IDS.NAV_STORAGE_FILES,
19 analytics: SHORTCUT_IDS.NAV_STORAGE_ANALYTICS,
20 vectors: SHORTCUT_IDS.NAV_STORAGE_VECTORS,
21}
22
23export const StorageMenuV2 = () => {
24 const router = useRouter()
25 const { ref } = useParams()
26 const page = useStorageV2Page()
27
28 const { storageAnalytics, storageVectors } = useIsFeatureEnabled([
29 'storage:analytics',
30 'storage:vectors',
31 ])
32
33 const isAnalyticsBucketsEnabled = useIsAnalyticsBucketsEnabled({ projectRef: ref })
34 const isVectorBucketsEnabled = useIsVectorBucketsEnabled({ projectRef: ref })
35
36 const showAnalytics = IS_PLATFORM && storageAnalytics
37 const showVectors = IS_PLATFORM && storageVectors
38
39 useShortcut(SHORTCUT_IDS.NAV_STORAGE_FILES, () => router.push(`/project/${ref}/storage/files`))
40 useShortcut(
41 SHORTCUT_IDS.NAV_STORAGE_ANALYTICS,
42 () => router.push(`/project/${ref}/storage/analytics`),
43 { enabled: showAnalytics }
44 )
45 useShortcut(
46 SHORTCUT_IDS.NAV_STORAGE_VECTORS,
47 () => router.push(`/project/${ref}/storage/vectors`),
48 { enabled: showVectors }
49 )
50 useShortcut(SHORTCUT_IDS.NAV_STORAGE_S3, () => router.push(`/project/${ref}/storage/s3`), {
51 enabled: IS_PLATFORM,
52 })
53
54 const bucketTypes = Object.entries(BUCKET_TYPES).filter(([key]) => {
55 if (key === 'analytics') return showAnalytics
56 if (key === 'vectors') return showVectors
57 return true
58 })
59
60 return (
61 <Menu type="pills" className="my-2 md:my-4 flex grow flex-col">
62 <div className="space-y-4">
63 <div className="md:mx-3">
64 <Menu.Group title={<span className="uppercase font-mono">Manage</span>} />
65
66 {bucketTypes.map(([type, config]) => {
67 const isSelected = page === type
68 const isAlphaEnabled =
69 (type === 'analytics' && isAnalyticsBucketsEnabled) ||
70 (type === 'vectors' && isVectorBucketsEnabled)
71 const shortcutId = BUCKET_TYPE_SHORTCUTS[type as keyof typeof BUCKET_TYPES]
72
73 const item = (
74 <Link href={`/project/${ref}/storage/${type}`}>
75 <Menu.Item rounded active={isSelected}>
76 <div className="flex items-center justify-between">
77 <p className="truncate">{config.displayName}</p>
78 {isAlphaEnabled && <Badge variant="success">New</Badge>}
79 </div>
80 </Menu.Item>
81 </Link>
82 )
83
84 return (
85 <div key={type}>
86 {shortcutId ? (
87 <ShortcutTooltip shortcutId={shortcutId} side="right" delayDuration={1000}>
88 {item}
89 </ShortcutTooltip>
90 ) : (
91 item
92 )}
93 </div>
94 )
95 })}
96 </div>
97
98 {IS_PLATFORM && (
99 <>
100 <div className="h-px w-[calc(100%-1.5rem)] mx-auto md:w-full bg-border" />
101 <div className="md:mx-3">
102 <Menu.Group title={<span className="uppercase font-mono">Configuration</span>} />
103
104 <ShortcutTooltip
105 shortcutId={SHORTCUT_IDS.NAV_STORAGE_S3}
106 side="right"
107 delayDuration={1000}
108 >
109 <Link href={`/project/${ref}/storage/s3`}>
110 <Menu.Item rounded active={page === 's3'}>
111 <p className="truncate">S3</p>
112 </Menu.Item>
113 </Link>
114 </ShortcutTooltip>
115 </div>
116 </>
117 )}
118 </div>
119 </Menu>
120 )
121}