NavigationBar.utils.tsx 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. import { Auth, Database, EdgeFunctions, Realtime, SqlEditor, Storage, TableEditor } from 'icons'
  2. import { Blocks, Lightbulb, List, Settings, Telescope } from 'lucide-react'
  3. import { ICON_SIZE, ICON_STROKE_WIDTH } from '@/components/interfaces/Sidebar'
  4. import type { Route } from '@/components/ui/ui.types'
  5. import { EditorIndexPageLink } from '@/data/prefetchers/project.$ref.editor'
  6. import type { Project } from '@/data/projects/project-detail-query'
  7. import { IS_PLATFORM, PROJECT_STATUS } from '@/lib/constants'
  8. import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
  9. interface RouteContext {
  10. ref?: string
  11. isProjectActive: boolean
  12. isProjectBuilding: boolean
  13. buildingUrl: string
  14. }
  15. interface ProductFeatures {
  16. auth?: boolean
  17. edgeFunctions?: boolean
  18. storage?: boolean
  19. realtime?: boolean
  20. authOverviewPage?: boolean
  21. }
  22. interface OtherFeatures {
  23. isPlatform?: boolean
  24. unifiedLogs?: boolean
  25. showReports?: boolean
  26. showLogs?: boolean
  27. }
  28. interface SettingsFeatures {
  29. isPlatform?: boolean
  30. }
  31. function getRouteContext(ref?: string, project?: Project): RouteContext {
  32. return {
  33. ref,
  34. isProjectActive: project?.status === PROJECT_STATUS.ACTIVE_HEALTHY,
  35. isProjectBuilding: project?.status === PROJECT_STATUS.COMING_UP,
  36. buildingUrl: `/project/${ref}`,
  37. }
  38. }
  39. export const generateToolRoutes = (ref?: string, project?: Project): Route[] => {
  40. const { isProjectActive, isProjectBuilding, buildingUrl } = getRouteContext(ref, project)
  41. return [
  42. {
  43. key: 'editor',
  44. label: 'Table Editor',
  45. disabled: !isProjectActive,
  46. icon: <TableEditor size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
  47. link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/editor`),
  48. linkElement: <EditorIndexPageLink projectRef={ref} />,
  49. shortcutId: SHORTCUT_IDS.NAV_TABLE_EDITOR,
  50. },
  51. {
  52. key: 'sql',
  53. label: 'SQL Editor',
  54. disabled: !isProjectActive,
  55. icon: <SqlEditor size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
  56. link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/sql`),
  57. shortcutId: SHORTCUT_IDS.NAV_SQL_EDITOR,
  58. },
  59. ]
  60. }
  61. export const generateProductRoutes = (
  62. ref?: string,
  63. project?: Project,
  64. features?: ProductFeatures
  65. ): Route[] => {
  66. const { isProjectActive, isProjectBuilding, buildingUrl } = getRouteContext(ref, project)
  67. const authEnabled = features?.auth ?? true
  68. const edgeFunctionsEnabled = features?.edgeFunctions ?? true
  69. const storageEnabled = features?.storage ?? true
  70. const realtimeEnabled = features?.realtime ?? true
  71. const authOverviewPageEnabled = features?.authOverviewPage ?? false
  72. return [
  73. {
  74. key: 'database',
  75. label: 'Database',
  76. disabled: !isProjectActive,
  77. icon: <Database size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
  78. link:
  79. ref &&
  80. (isProjectBuilding
  81. ? buildingUrl
  82. : isProjectActive
  83. ? `/project/${ref}/database/schemas`
  84. : `/project/${ref}/database/backups/scheduled`),
  85. shortcutId: SHORTCUT_IDS.NAV_DATABASE,
  86. },
  87. ...(authEnabled
  88. ? [
  89. {
  90. key: 'auth',
  91. label: 'Authentication',
  92. disabled: !isProjectActive,
  93. icon: <Auth size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
  94. link:
  95. ref &&
  96. (isProjectBuilding
  97. ? buildingUrl
  98. : authOverviewPageEnabled
  99. ? `/project/${ref}/auth/overview`
  100. : `/project/${ref}/auth/users`),
  101. shortcutId: SHORTCUT_IDS.NAV_AUTH,
  102. },
  103. ]
  104. : []),
  105. ...(storageEnabled
  106. ? [
  107. {
  108. key: 'storage',
  109. label: 'Storage',
  110. disabled: !isProjectActive,
  111. icon: <Storage size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
  112. link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/storage/files`),
  113. shortcutId: SHORTCUT_IDS.NAV_STORAGE,
  114. },
  115. ]
  116. : []),
  117. ...(edgeFunctionsEnabled
  118. ? [
  119. {
  120. key: 'functions',
  121. label: 'Edge Functions',
  122. disabled: false,
  123. icon: <EdgeFunctions size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
  124. link: ref && `/project/${ref}/functions`,
  125. shortcutId: SHORTCUT_IDS.NAV_FUNCTIONS,
  126. },
  127. ]
  128. : []),
  129. ...(realtimeEnabled
  130. ? [
  131. {
  132. key: 'realtime',
  133. label: 'Realtime',
  134. disabled: !isProjectActive,
  135. icon: <Realtime size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
  136. link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/realtime/inspector`),
  137. shortcutId: SHORTCUT_IDS.NAV_REALTIME,
  138. },
  139. ]
  140. : []),
  141. ]
  142. }
  143. export const generateOtherRoutes = (
  144. ref?: string,
  145. project?: Project,
  146. features?: OtherFeatures
  147. ): Route[] => {
  148. const { isProjectActive, isProjectBuilding, buildingUrl } = getRouteContext(ref, project)
  149. const isPlatform = features?.isPlatform ?? IS_PLATFORM
  150. const unifiedLogsEnabled = features?.unifiedLogs ?? false
  151. const reportsEnabled = features?.showReports ?? true
  152. const logsEnabled = features?.showLogs ?? true
  153. return [
  154. {
  155. key: 'advisors',
  156. label: 'Advisors',
  157. disabled: !isProjectActive,
  158. icon: <Lightbulb size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
  159. link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/advisors/security`),
  160. shortcutId: SHORTCUT_IDS.NAV_ADVISORS,
  161. },
  162. // Observability is only available on the platform, not for self-hosted/CLI
  163. ...(isPlatform && reportsEnabled
  164. ? [
  165. {
  166. key: 'observability',
  167. label: 'Observability',
  168. disabled: !isProjectActive,
  169. icon: <Telescope size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
  170. link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/observability`),
  171. shortcutId: SHORTCUT_IDS.NAV_OBSERVABILITY,
  172. },
  173. ]
  174. : []),
  175. ...(logsEnabled
  176. ? [
  177. {
  178. key: 'logs',
  179. label: 'Logs',
  180. disabled: false,
  181. icon: <List size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
  182. link:
  183. ref &&
  184. (unifiedLogsEnabled ? `/project/${ref}/logs` : `/project/${ref}/logs/explorer`),
  185. shortcutId: SHORTCUT_IDS.NAV_LOGS,
  186. },
  187. ]
  188. : []),
  189. {
  190. key: 'integrations',
  191. label: 'Integrations',
  192. disabled: !isProjectActive,
  193. icon: <Blocks size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
  194. link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/integrations`),
  195. shortcutId: SHORTCUT_IDS.NAV_INTEGRATIONS,
  196. },
  197. ]
  198. }
  199. export const generateSettingsRoutes = (ref?: string, features?: SettingsFeatures): Route[] => {
  200. const isPlatform = features?.isPlatform ?? IS_PLATFORM
  201. return [
  202. {
  203. key: 'settings',
  204. label: 'Project Settings',
  205. icon: <Settings size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
  206. link:
  207. ref &&
  208. (isPlatform ? `/project/${ref}/settings/general` : `/project/${ref}/settings/log-drains`),
  209. disabled: false,
  210. shortcutId: SHORTCUT_IDS.NAV_SETTINGS,
  211. },
  212. ]
  213. }