-
Scripts
-
Quick scripts to run on your database.
-
- Click on any script to fill the query box, modify the script, then click
- Run.
-
+
Templates
+
Reusable SQL snippets for common tasks
{sql.map((x, i) => (
diff --git a/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/CommunitySnippetsSection.tsx b/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/ReferenceSnippetsSection.tsx
similarity index 88%
rename from apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/CommunitySnippetsSection.tsx
rename to apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/ReferenceSnippetsSection.tsx
index 593cad2d6f1..fb552dc36d2 100644
--- a/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/CommunitySnippetsSection.tsx
+++ b/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/ReferenceSnippetsSection.tsx
@@ -11,9 +11,9 @@ import { InnerSideMenuDataItem } from 'ui-patterns/InnerSideMenu'
import { DEFAULT_SECTION_STATE, type SectionState } from './SQLEditorNav.constants'
import { useLocalStorage } from '@/hooks/misc/useLocalStorage'
-const OPTIONS = ['templates', 'quickstarts'] as const
+const OPTIONS = ['templates', 'examples'] as const
-export function CommunitySnippetsSection() {
+export function ReferenceSnippetsSection() {
const { ref } = useParams()
const router = useRouter()
@@ -38,14 +38,14 @@ export function CommunitySnippetsSection() {
})
}}
>
-
+
{OPTIONS.map((pageId) => {
const active = isPageActive(pageId)
return (
{
+export const SQLEditorLoadingSnippets = () => {
return (
<>
@@ -26,5 +26,3 @@ const SQLEditorLoadingSnippets = () => {
>
)
}
-
-export default SQLEditorLoadingSnippets
diff --git a/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorNav.tsx b/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorNav.tsx
index 062802a2695..5a3a77e091f 100644
--- a/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorNav.tsx
+++ b/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorNav.tsx
@@ -14,27 +14,27 @@ import {
} from 'ui-patterns'
import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
-import { CommunitySnippetsSection } from './CommunitySnippetsSection'
import { DeleteSnippetsModal } from './DeleteSnippetsModal'
+import { ReferenceSnippetsSection } from './ReferenceSnippetsSection'
import { ShareSnippetModal } from './ShareSnippetModal'
-import SQLEditorLoadingSnippets from './SQLEditorLoadingSnippets'
+import { SQLEditorLoadingSnippets } from './SQLEditorLoadingSnippets'
import { DEFAULT_SECTION_STATE, type SectionState } from './SQLEditorNav.constants'
import { formatFolderResponseForTreeView, getLastItemIds, ROOT_NODE } from './SQLEditorNav.utils'
import { SQLEditorTreeViewItem } from './SQLEditorTreeViewItem'
import { UnshareSnippetModal } from './UnshareSnippetModal'
-import DownloadSnippetModal from '@/components/interfaces/SQLEditor/DownloadSnippetModal'
+import { DownloadSnippetModal } from '@/components/interfaces/SQLEditor/DownloadSnippetModal'
import { MoveQueryModal } from '@/components/interfaces/SQLEditor/MoveQueryModal'
-import RenameQueryModal from '@/components/interfaces/SQLEditor/RenameQueryModal'
+import { RenameQueryModal } from '@/components/interfaces/SQLEditor/RenameQueryModal'
import { generateSnippetTitle } from '@/components/interfaces/SQLEditor/SQLEditor.constants'
import { createSqlSnippetSkeletonV2 } from '@/components/interfaces/SQLEditor/SQLEditor.utils'
import { EmptyPrivateQueriesPanel } from '@/components/layouts/SQLEditorLayout/PrivateSqlSnippetEmpty'
-import EditorMenuListSkeleton from '@/components/layouts/TableEditorLayout/EditorMenuListSkeleton'
+import { EditorMenuListSkeleton } from '@/components/layouts/TableEditorLayout/EditorMenuListSkeleton'
import { useSqlEditorTabsCleanup } from '@/components/layouts/Tabs/Tabs.utils'
import { useContentCountQuery } from '@/data/content/content-count-query'
import { useContentDeleteMutation } from '@/data/content/content-delete-mutation'
import { useSQLSnippetFoldersDeleteMutation } from '@/data/content/sql-folders-delete-mutation'
import { Snippet, SnippetFolder, useSQLSnippetFoldersQuery } from '@/data/content/sql-folders-query'
-import { useSqlSnippetsQuery } from '@/data/content/sql-snippets-query'
+import { useSqlSnippetsQuery, type SqlSnippet } from '@/data/content/sql-snippets-query'
import { useLocalStorage } from '@/hooks/misc/useLocalStorage'
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
import { useProfile } from '@/lib/profile'
@@ -209,7 +209,7 @@ export const SQLEditorNav = ({ sort = 'inserted_at' }: SQLEditorNavProps) => {
let snippets = favoriteSqlSnippetsData?.pages.flatMap((page) => page.contents ?? []) ?? []
if (snippet && snippet.favorite && !snippets.find((x) => x.id === snippet.id)) {
- snippets.push(snippet as any)
+ snippets.push(snippet as SqlSnippet)
}
return (
@@ -260,7 +260,7 @@ export const SQLEditorNav = ({ sort = 'inserted_at' }: SQLEditorNavProps) => {
let snippets = sharedSqlSnippetsData?.pages.flatMap((page) => page.contents ?? []) ?? []
if (snippet && snippet.visibility === 'project' && !snippets.find((x) => x.id === snippet.id)) {
- snippets.push(snippet as any)
+ snippets.push(snippet as SqlSnippet)
}
return (
@@ -750,7 +750,7 @@ export const SQLEditorNav = ({ sort = 'inserted_at' }: SQLEditorNavProps) => {
-
+
diff --git a/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SearchList.tsx b/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SearchList.tsx
index 16a301b1061..bf48277ce7a 100644
--- a/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SearchList.tsx
+++ b/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SearchList.tsx
@@ -10,8 +10,8 @@ import { ShareSnippetModal } from './ShareSnippetModal'
import { formatFolderResponseForTreeView, getLastItemIds } from './SQLEditorNav.utils'
import { SQLEditorTreeViewItem } from './SQLEditorTreeViewItem'
import { UnshareSnippetModal } from './UnshareSnippetModal'
-import DownloadSnippetModal from '@/components/interfaces/SQLEditor/DownloadSnippetModal'
-import RenameQueryModal from '@/components/interfaces/SQLEditor/RenameQueryModal'
+import { DownloadSnippetModal } from '@/components/interfaces/SQLEditor/DownloadSnippetModal'
+import { RenameQueryModal } from '@/components/interfaces/SQLEditor/RenameQueryModal'
import { useContentCountQuery } from '@/data/content/content-count-query'
import { useContentInfiniteQuery } from '@/data/content/content-infinite-query'
import { Snippet, SNIPPET_PAGE_LIMIT } from '@/data/content/sql-folders-query'
diff --git a/apps/studio/components/layouts/TableEditorLayout/EditorMenuListSkeleton.tsx b/apps/studio/components/layouts/TableEditorLayout/EditorMenuListSkeleton.tsx
index 163d653cdc3..10359816ef8 100644
--- a/apps/studio/components/layouts/TableEditorLayout/EditorMenuListSkeleton.tsx
+++ b/apps/studio/components/layouts/TableEditorLayout/EditorMenuListSkeleton.tsx
@@ -1,7 +1,7 @@
import { memo } from 'react'
import { Skeleton } from 'ui'
-const EditorMenuListSkeleton = memo(function EditorMenuListSkeleton() {
+export const EditorMenuListSkeleton = memo(function EditorMenuListSkeleton() {
const items = [
{ width: 'w-40', opacity: 'opacity-100' },
{ width: 'w-32', opacity: 'opacity-100' },
@@ -21,5 +21,3 @@ const EditorMenuListSkeleton = memo(function EditorMenuListSkeleton() {
)
})
-
-export default EditorMenuListSkeleton
diff --git a/apps/studio/components/layouts/TableEditorLayout/TableEditorMenu.tsx b/apps/studio/components/layouts/TableEditorLayout/TableEditorMenu.tsx
index 577b9874414..3055b2c3a2e 100644
--- a/apps/studio/components/layouts/TableEditorLayout/TableEditorMenu.tsx
+++ b/apps/studio/components/layouts/TableEditorLayout/TableEditorMenu.tsx
@@ -20,7 +20,7 @@ import { parseSupaTable } from '@/components/grid/SupabaseGrid.utils'
import { SupaTable } from '@/components/grid/types'
import { ProtectedSchemaWarning } from '@/components/interfaces/Database/ProtectedSchemaWarning'
import { ErrorMatcher } from '@/components/interfaces/ErrorHandling/ErrorMatcher'
-import EditorMenuListSkeleton from '@/components/layouts/TableEditorLayout/EditorMenuListSkeleton'
+import { EditorMenuListSkeleton } from '@/components/layouts/TableEditorLayout/EditorMenuListSkeleton'
import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
import { InfiniteListDefault, LoaderForIconMenuItems } from '@/components/ui/InfiniteList'
import SchemaSelector from '@/components/ui/SchemaSelector'
diff --git a/apps/studio/components/layouts/Tabs/NewTab.tsx b/apps/studio/components/layouts/Tabs/NewTab.tsx
index 63682f8cbd9..72ebd840ae5 100644
--- a/apps/studio/components/layouts/Tabs/NewTab.tsx
+++ b/apps/studio/components/layouts/Tabs/NewTab.tsx
@@ -1,37 +1,11 @@
-import { PermissionAction } from '@supabase/shared-types/out/constants'
-import { useParams } from 'common'
-import { partition } from 'lodash'
import { Table2 } from 'lucide-react'
-import Link from 'next/link'
-import { useRouter } from 'next/router'
-import { toast } from 'sonner'
-import {
- Badge,
- Button,
- Card,
- CardContent,
- CardHeader,
- CardTitle,
- cn,
- SQL_ICON,
- Tabs_Shadcn_,
- TabsContent_Shadcn_,
- TabsList_Shadcn_,
- TabsTrigger_Shadcn_,
-} from 'ui'
+import { Badge, Button, Card, CardContent, CardHeader, CardTitle } from 'ui'
import { useEditorType } from '../editors/EditorsLayout.hooks'
import { ActionCard } from './ActionCard'
import { RecentItems } from './RecentItems'
-import { SQL_TEMPLATES } from '@/components/interfaces/SQLEditor/SQLEditor.queries'
-import { createSqlSnippetSkeletonV2 } from '@/components/interfaces/SQLEditor/SQLEditor.utils'
-import { useSendEventMutation } from '@/data/telemetry/send-event-mutation'
-import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
import { useQuerySchemaState } from '@/hooks/misc/useSchemaQueryState'
-import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
-import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
import { useIsProtectedSchema } from '@/hooks/useProtectedSchemas'
-import { useProfile } from '@/lib/profile'
import {
useImpersonatedAAL,
useImpersonatedExternalAuth,
@@ -39,43 +13,20 @@ import {
useIsImpersonatingAnon,
useRoleImpersonationStateSnapshot,
} from '@/state/role-impersonation-state'
-import { useSqlEditorV2StateSnapshot } from '@/state/sql-editor-v2'
import { useTableEditorStateSnapshot } from '@/state/table-editor'
-import { createTabId, useTabsStateSnapshot } from '@/state/tabs'
-import { type ResponseError } from '@/types'
export function NewTab() {
- const router = useRouter()
- const { ref } = useParams()
const editor = useEditorType()
- const { profile } = useProfile()
- const { data: org } = useSelectedOrganizationQuery()
- const { data: project } = useSelectedProjectQuery()
const { selectedSchema } = useQuerySchemaState()
const { isSchemaLocked } = useIsProtectedSchema({ schema: selectedSchema })
const snap = useTableEditorStateSnapshot()
- const snapV2 = useSqlEditorV2StateSnapshot()
- const tabs = useTabsStateSnapshot()
- const [templates] = partition(SQL_TEMPLATES, { type: 'template' })
- const [quickstarts] = partition(SQL_TEMPLATES, { type: 'quickstart' })
-
const roleState = useRoleImpersonationStateSnapshot()
const impersonatingAnon = useIsImpersonatingAnon()
const impersonatedUser = useImpersonatedUser()
const impersonatedExternalUser = useImpersonatedExternalAuth()
const impersonatedAAL = useImpersonatedAAL()
- const { mutate: sendEvent } = useSendEventMutation()
- const { can: canCreateSQLSnippet } = useAsyncCheckPermissions(
- PermissionAction.CREATE,
- 'user_content',
- {
- resource: { type: 'sql', owner_id: profile?.id },
- subject: { id: profile?.id },
- }
- )
-
const tableEditorActions = isSchemaLocked
? []
: [
@@ -89,52 +40,7 @@ export function NewTab() {
},
]
- const sqlEditorActions = [
- {
- icon: ,
- title: 'New SQL Snippet',
- description: 'Execute SQL queries',
- bgColor: 'bg-green-500',
- isBeta: false,
- onClick: () => router.push(`/project/${ref}/sql/new`),
- },
- ]
-
- const actions = editor === 'sql' ? sqlEditorActions : tableEditorActions
-
- const handleNewQuery = async (sql: string, name: string) => {
- if (!ref) return console.error('Project ref is required')
- if (!project) return console.error('Project is required')
- if (!profile) return console.error('Profile is required')
-
- if (!canCreateSQLSnippet) {
- return toast('Your queries will not be saved as you do not have sufficient permissions')
- }
-
- try {
- const snippet = createSqlSnippetSkeletonV2({
- name,
- sql,
- owner_id: profile?.id,
- project_id: project?.id,
- })
- snapV2.addSnippet({ projectRef: ref, snippet })
- snapV2.addNeedsSaving(snippet.id)
-
- const tabId = createTabId('sql', { id: snippet.id })
-
- tabs.addTab({
- id: tabId,
- type: 'sql',
- label: name,
- metadata: { sqlId: snippet.id },
- })
-
- router.push(`/project/${ref}/sql/${snippet.id}`)
- } catch (error) {
- toast.error(`Failed to create new query: ${(error as ResponseError).message}`)
- }
- }
+ const actions = editor === 'table' ? tableEditorActions : []
return (
@@ -178,71 +84,6 @@ export function NewTab() {
-
- {editor === 'sql' && (
-
-
-
- Templates
- Quickstarts
-
-
-
- {templates.slice(0, 9).map((item, i) => (
-
{
- handleNewQuery(item.sql, item.title)
- sendEvent({
- action: 'sql_editor_template_clicked',
- properties: { templateName: item.title },
- groups: { project: ref ?? 'Unknown', organization: org?.slug ?? 'Unknown' },
- })
- }}
- bgColor="bg-alternative border"
- key={`action-card-${i}`}
- {...item}
- icon={
-
- }
- />
- ))}
-
-
-
-
-
-
-
- {quickstarts.map((item, i) => (
-
{
- handleNewQuery(item.sql, item.title)
- sendEvent({
- action: 'sql_editor_quickstart_clicked',
- properties: { quickstartName: item.title },
- groups: { project: ref ?? 'Unknown', organization: org?.slug ?? 'Unknown' },
- })
- }}
- bgColor="bg-alternative border"
- key={`action-card-${i}`}
- {...item}
- icon={
-
- }
- />
- ))}
-
-
-
-
-
-
-
- )}
)
}
diff --git a/apps/studio/next.config.ts b/apps/studio/next.config.ts
index de8e6c883f3..bdaba9c3961 100644
--- a/apps/studio/next.config.ts
+++ b/apps/studio/next.config.ts
@@ -323,8 +323,8 @@ const nextConfig = {
permanent: true,
},
{
- source: '/project/:ref/sql/templates',
- destination: '/project/:ref/sql',
+ source: '/project/:ref/sql/quickstarts',
+ destination: '/project/:ref/sql/examples',
permanent: true,
},
{
diff --git a/apps/studio/pages/project/[ref]/sql/quickstarts.tsx b/apps/studio/pages/project/[ref]/sql/examples.tsx
similarity index 72%
rename from apps/studio/pages/project/[ref]/sql/quickstarts.tsx
rename to apps/studio/pages/project/[ref]/sql/examples.tsx
index 4764448d6d3..ab28271b591 100644
--- a/apps/studio/pages/project/[ref]/sql/quickstarts.tsx
+++ b/apps/studio/pages/project/[ref]/sql/examples.tsx
@@ -2,7 +2,7 @@ import { useParams } from 'next/navigation'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
-import SQLQuickstarts from '@/components/interfaces/SQLEditor/SQLTemplates/SQLQuickstarts'
+import SQLExamples from '@/components/interfaces/SQLEditor/SQLTemplates/SQLExamples'
import DefaultLayout from '@/components/layouts/DefaultLayout'
import { EditorBaseLayout } from '@/components/layouts/editors/EditorBaseLayout'
import SQLEditorLayout from '@/components/layouts/SQLEditorLayout/SQLEditorLayout'
@@ -10,7 +10,7 @@ import { SQLEditorMenu } from '@/components/layouts/SQLEditorLayout/SQLEditorMen
import { createTabId, useTabsStateSnapshot } from '@/state/tabs'
import type { NextPageWithLayout } from '@/types'
-const SqlQuickstarts: NextPageWithLayout = () => {
+const SqlExamples: NextPageWithLayout = () => {
const router = useRouter()
const ref = useParams<{ ref: string }>()?.ref
const tabs = useTabsStateSnapshot()
@@ -18,22 +18,22 @@ const SqlQuickstarts: NextPageWithLayout = () => {
useEffect(() => {
if (!router.isReady) return
- const tabId = createTabId('sql', { id: 'quickstarts' })
+ const tabId = createTabId('sql', { id: 'examples' })
tabs.addTab({
id: tabId,
type: 'sql',
- label: 'Quickstarts',
+ label: 'Examples',
metadata: {
- sqlId: 'quickstarts',
- name: 'quickstarts',
+ sqlId: 'examples',
+ name: 'examples',
},
})
}, [router.isReady, ref])
- return
+ return
}
-SqlQuickstarts.getLayout = (page) => (
+SqlExamples.getLayout = (page) => (
} product="SQL Editor">
{page}
@@ -41,4 +41,4 @@ SqlQuickstarts.getLayout = (page) => (
)
-export default SqlQuickstarts
+export default SqlExamples