Files
supabase/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils.tsx
Ivan Vasilov f3af2c3d3c feat: SQL Snippets (#41112)
* Use the .sql suffix when generating ids.

* Fix a bug where a new snippet would not show up in the snippet list until refresh.

* Add API routes which serve file snippets.

* Refactor the renameSnippet and moveSnippet to work with file snippets.

* Change the link to the SQL Editor.

* Minor fixes from CodeRabbit.

* Check the file/folder name for invalid chars.

* More fixes from CodeRabbit review.

* Fix minor issues.

* Use zod to parse the snippet ids when deleting.

* Try to fix snyk issue.

* Add validation to the GET content index route.

* Minor fixes.

* Show create a new folder, it was hidden by mistake.

* Add SNIPPETS_MANAGEMENT_FOLDER env var.

* Add snippets folder in the docker-compose.

* Add error toasts if the env var is not set.

* Add snippets management folder to the generateLocalEnv script.

* Revert the docker-compose changes, will be done in a followup PR.

* Revert also the snippets volume folder.

* Remove unneeded line.
2025-12-23 12:09:37 +01:00

192 lines
6.3 KiB
TypeScript

import { Blocks, FileText, Lightbulb, List, Settings, Telescope } from 'lucide-react'
import { ICON_SIZE, ICON_STROKE_WIDTH } from 'components/interfaces/Sidebar'
import { generateAuthMenu } from 'components/layouts/AuthLayout/AuthLayout.utils'
import { generateDatabaseMenu } from 'components/layouts/DatabaseLayout/DatabaseMenu.utils'
import { generateSettingsMenu } from 'components/layouts/ProjectSettingsLayout/SettingsMenu.utils'
import type { Route } from 'components/ui/ui.types'
import { EditorIndexPageLink } from 'data/prefetchers/project.$ref.editor'
import type { Project } from 'data/projects/project-detail-query'
import { Auth, Database, EdgeFunctions, Realtime, SqlEditor, Storage, TableEditor } from 'icons'
import { IS_PLATFORM, PROJECT_STATUS } from 'lib/constants'
export const generateToolRoutes = (ref?: string, project?: Project, features?: {}): Route[] => {
const isProjectBuilding = project?.status === PROJECT_STATUS.COMING_UP
const buildingUrl = `/project/${ref}`
return [
{
key: 'editor',
label: 'Table Editor',
icon: <TableEditor size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/editor`),
linkElement: <EditorIndexPageLink projectRef={ref} />,
},
{
key: 'sql',
label: 'SQL Editor',
icon: <SqlEditor size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/sql`),
},
]
}
export const generateProductRoutes = (
ref?: string,
project?: Project,
features?: {
auth?: boolean
edgeFunctions?: boolean
storage?: boolean
realtime?: boolean
authOverviewPage?: boolean
}
): Route[] => {
const isProjectActive = project?.status === PROJECT_STATUS.ACTIVE_HEALTHY
const isProjectBuilding = project?.status === PROJECT_STATUS.COMING_UP
const buildingUrl = `/project/${ref}`
const authEnabled = features?.auth ?? true
const edgeFunctionsEnabled = features?.edgeFunctions ?? true
const storageEnabled = features?.storage ?? true
const realtimeEnabled = features?.realtime ?? true
const authOverviewPageEnabled = features?.authOverviewPage ?? false
const databaseMenu = generateDatabaseMenu(project)
const authMenu = generateAuthMenu(ref as string)
return [
{
key: 'database',
label: 'Database',
icon: <Database size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
link:
ref &&
(isProjectBuilding
? buildingUrl
: isProjectActive
? `/project/${ref}/database/schemas`
: `/project/${ref}/database/backups/scheduled`),
items: databaseMenu,
},
...(authEnabled
? [
{
key: 'auth',
label: 'Authentication',
icon: <Auth size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
link:
ref &&
(isProjectBuilding
? buildingUrl
: authOverviewPageEnabled
? `/project/${ref}/auth/overview`
: `/project/${ref}/auth/users`),
items: authMenu,
},
]
: []),
...(storageEnabled
? [
{
key: 'storage',
label: 'Storage',
icon: <Storage size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/storage/files`),
},
]
: []),
...(edgeFunctionsEnabled
? [
{
key: 'functions',
label: 'Edge Functions',
icon: <EdgeFunctions size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/functions`),
},
]
: []),
...(realtimeEnabled
? [
{
key: 'realtime',
label: 'Realtime',
icon: <Realtime size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/realtime/inspector`),
},
]
: []),
]
}
export const generateOtherRoutes = (
ref?: string,
project?: Project,
features?: { unifiedLogs?: boolean; showReports?: boolean }
): Route[] => {
const isProjectBuilding = project?.status === PROJECT_STATUS.COMING_UP
const buildingUrl = `/project/${ref}`
const { unifiedLogs, showReports } = features ?? {}
const unifiedLogsEnabled = unifiedLogs ?? false
const reportsEnabled = showReports ?? true
return [
{
key: 'advisors',
label: 'Advisors',
icon: <Lightbulb size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/advisors/security`),
},
...(IS_PLATFORM && reportsEnabled
? [
{
key: 'observability',
label: 'Observability',
icon: <Telescope size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/observability`),
},
]
: []),
{
key: 'logs',
label: 'Logs',
icon: <List size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
link:
ref &&
(isProjectBuilding
? buildingUrl
: unifiedLogsEnabled
? `/project/${ref}/logs`
: `/project/${ref}/logs/explorer`),
},
{
key: 'api',
label: 'API Docs',
icon: <FileText size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/api`),
},
{
key: 'integrations',
label: 'Integrations',
icon: <Blocks size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/integrations`),
},
]
}
export const generateSettingsRoutes = (ref?: string, project?: Project): Route[] => {
const settingsMenu = generateSettingsMenu(ref as string)
return [
{
key: 'settings',
label: 'Project Settings',
icon: <Settings size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
link:
ref &&
(IS_PLATFORM ? `/project/${ref}/settings/general` : `/project/${ref}/settings/log-drains`),
items: settingsMenu,
},
]
}