DatabaseMenu.utils.tsx186 lines · main
1import { useParams } from 'common'
2import { ArrowUpRight } from 'lucide-react'
3
4import { useIsColumnLevelPrivilegesEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext'
5import { useIsETLPrivateAlpha } from '@/components/interfaces/Database/Replication/useIsETLPrivateAlpha'
6import type {
7 ProductMenuGroup,
8 ProductMenuGroupItem,
9} from '@/components/ui/ProductMenu/ProductMenu.types'
10import { useDatabaseExtensionsQuery } from '@/data/database-extensions/database-extensions-query'
11import { useProjectAddonsQuery } from '@/data/subscriptions/project-addons-query'
12import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
13import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
14import { IS_PLATFORM } from '@/lib/constants'
15import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
16
17const ExternalLinkIcon = <ArrowUpRight strokeWidth={1} className="h-4 w-4" />
18
19export const useGenerateDatabaseMenu = (): ProductMenuGroup[] => {
20 const { ref } = useParams()
21 const { data: project } = useSelectedProjectQuery()
22
23 const {
24 databaseReplication: showPgReplicate,
25 databaseRoles: showRoles,
26 integrationsWrappers: showWrappers,
27 } = useIsFeatureEnabled(['database:replication', 'database:roles', 'integrations:wrappers'])
28
29 const { data } = useDatabaseExtensionsQuery({
30 projectRef: project?.ref,
31 connectionString: project?.connectionString,
32 })
33 const { data: addons } = useProjectAddonsQuery({ projectRef: project?.ref })
34
35 const pgNetExtensionExists = (data ?? []).some((ext) => ext.name === 'pg_net')
36 const pitrEnabled = addons?.selected_addons.some((addon) => addon.type === 'pitr') ?? false
37 const columnLevelPrivileges = useIsColumnLevelPrivilegesEnabled()
38 const enablePgReplicate = useIsETLPrivateAlpha()
39
40 const getDatabaseURL = (path: string) => `/project/${ref}/database/${path}`
41
42 return [
43 {
44 title: 'Database Management',
45 items: [
46 {
47 name: 'Schema Visualizer',
48 key: 'schemas',
49 url: getDatabaseURL('schemas'),
50 shortcutId: SHORTCUT_IDS.NAV_DATABASE_SCHEMA_VISUALIZER,
51 },
52 {
53 name: 'Tables',
54 key: 'tables',
55 url: getDatabaseURL('tables'),
56 shortcutId: SHORTCUT_IDS.NAV_DATABASE_TABLES,
57 },
58 {
59 name: 'Functions',
60 key: 'functions',
61 url: getDatabaseURL('functions'),
62 shortcutId: SHORTCUT_IDS.NAV_DATABASE_FUNCTIONS,
63 },
64 {
65 name: 'Triggers',
66 key: 'triggers',
67 url: getDatabaseURL('triggers/data'),
68 shortcutId: SHORTCUT_IDS.NAV_DATABASE_TRIGGERS,
69 },
70 {
71 name: 'Enumerated Types',
72 key: 'types',
73 url: getDatabaseURL('types'),
74 shortcutId: SHORTCUT_IDS.NAV_DATABASE_TYPES,
75 },
76 {
77 name: 'Extensions',
78 key: 'extensions',
79 url: getDatabaseURL('extensions'),
80 shortcutId: SHORTCUT_IDS.NAV_DATABASE_EXTENSIONS,
81 },
82 {
83 name: 'Indexes',
84 key: 'indexes',
85 url: getDatabaseURL('indexes'),
86 shortcutId: SHORTCUT_IDS.NAV_DATABASE_INDEXES,
87 },
88 {
89 name: 'Publications',
90 key: 'publications',
91 url: getDatabaseURL('publications'),
92 shortcutId: SHORTCUT_IDS.NAV_DATABASE_PUBLICATIONS,
93 },
94 ],
95 },
96 {
97 title: 'Configuration',
98 items: [
99 showRoles && {
100 name: 'Roles',
101 key: 'roles',
102 url: getDatabaseURL('roles'),
103 shortcutId: SHORTCUT_IDS.NAV_DATABASE_ROLES,
104 },
105 columnLevelPrivileges && {
106 name: 'Column Privileges',
107 key: 'column-privileges',
108 url: getDatabaseURL('column-privileges'),
109 shortcutId: SHORTCUT_IDS.NAV_DATABASE_COLUMN_PRIVILEGES,
110 },
111 {
112 name: 'Policies',
113 key: 'policies',
114 url: `/project/${ref}/auth/policies`,
115 rightIcon: ExternalLinkIcon,
116 },
117 {
118 name: 'Settings',
119 key: 'settings',
120 url: getDatabaseURL('settings'),
121 shortcutId: SHORTCUT_IDS.NAV_DATABASE_SETTINGS,
122 },
123 ].filter(Boolean) as ProductMenuGroupItem[],
124 },
125 {
126 title: 'Platform',
127 items: [
128 IS_PLATFORM &&
129 showPgReplicate && {
130 name: 'Replication',
131 key: 'replication',
132 url: getDatabaseURL('replication'),
133 label: enablePgReplicate ? 'New' : undefined,
134 shortcutId: SHORTCUT_IDS.NAV_DATABASE_REPLICATION,
135 },
136 IS_PLATFORM && {
137 name: 'Backups',
138 key: 'backups',
139 url: pitrEnabled ? getDatabaseURL('backups/pitr') : getDatabaseURL('backups/scheduled'),
140 shortcutId: SHORTCUT_IDS.NAV_DATABASE_BACKUPS,
141 },
142 {
143 name: 'Migrations',
144 key: 'migrations',
145 url: getDatabaseURL('migrations'),
146 shortcutId: SHORTCUT_IDS.NAV_DATABASE_MIGRATIONS,
147 },
148 showWrappers && {
149 name: 'Wrappers',
150 key: 'wrappers',
151 url: `/project/${ref}/integrations?category=wrapper`,
152 rightIcon: ExternalLinkIcon,
153 },
154 pgNetExtensionExists && {
155 name: 'Database Webhooks',
156 key: 'hooks',
157 url: `/project/${ref}/integrations/webhooks/overview`,
158 rightIcon: ExternalLinkIcon,
159 },
160 ].filter(Boolean) as ProductMenuGroupItem[],
161 },
162 {
163 title: 'Tools',
164 items: [
165 {
166 name: 'Security Advisor',
167 key: 'security-advisor',
168 url: `/project/${ref}/advisors/security`,
169 rightIcon: ExternalLinkIcon,
170 },
171 {
172 name: 'Performance Advisor',
173 key: 'performance-advisor',
174 url: `/project/${ref}/advisors/performance`,
175 rightIcon: ExternalLinkIcon,
176 },
177 {
178 name: 'Query Performance',
179 key: 'query-performance',
180 url: `/project/${ref}/observability/query-performance`,
181 rightIcon: ExternalLinkIcon,
182 },
183 ],
184 },
185 ]
186}