mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
Chore/new sql (#37579)
* just redirect to new on sql empty * clean up * update template and quickstarts link * Nit clean up --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
This commit is contained in:
1 parent
58d6b4b912
commit
efaf4d5183
9 files changed
+110
-73
No files matched your search
@@ -32,6 +32,7 @@ export type MonacoEditorProps = {
|
||||
startLineNumber: number
|
||||
endLineNumber: number
|
||||
}) => void
|
||||
placeholder?: string
|
||||
}
|
||||
|
||||
const MonacoEditor = ({
|
||||
@@ -39,6 +40,7 @@ const MonacoEditor = ({
|
||||
editorRef,
|
||||
monacoRef,
|
||||
autoFocus = true,
|
||||
placeholder = '',
|
||||
className,
|
||||
executeQuery,
|
||||
onHasSelection,
|
||||
@@ -204,6 +206,7 @@ const MonacoEditor = ({
|
||||
options={{
|
||||
tabSize: 2,
|
||||
fontSize: 13,
|
||||
placeholder,
|
||||
lineDecorationsWidth: 0,
|
||||
readOnly: disableEdit,
|
||||
minimap: { enabled: false },
|
||||
|
||||
@@ -718,6 +718,13 @@ export const SQLEditor = () => {
|
||||
<div key={id} className="w-full h-full relative">
|
||||
<MonacoEditor
|
||||
autoFocus
|
||||
placeholder={
|
||||
!promptState.isOpen && !editorRef.current?.getValue()
|
||||
? 'Hit ' +
|
||||
(os === 'macos' ? 'CMD+K' : `CTRL+K`) +
|
||||
' to generate query or just start typing'
|
||||
: ''
|
||||
}
|
||||
id={id}
|
||||
className={cn(isDiffOpen && 'hidden')}
|
||||
editorRef={editorRef}
|
||||
@@ -763,19 +770,6 @@ export const SQLEditor = () => {
|
||||
endLineNumber={promptState.endLineNumber}
|
||||
/>
|
||||
)}
|
||||
<AnimatePresence>
|
||||
{!promptState.isOpen && !editorRef.current?.getValue() && (
|
||||
<motion.p
|
||||
initial={{ y: 5, opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1 }}
|
||||
exit={{ y: 5, opacity: 0 }}
|
||||
className="text-foreground-lighter absolute bottom-4 left-4 z-10 font-mono text-xs flex items-center gap-1"
|
||||
>
|
||||
Hit {os === 'macos' ? <Command size={12} /> : `CTRL+`}K to edit with the
|
||||
Assistant
|
||||
</motion.p>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { toast } from 'sonner'
|
||||
|
||||
import { useCheckPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import { useLocalStorage } from 'hooks/misc/useLocalStorage'
|
||||
import { useSelectedProject } from 'hooks/misc/useSelectedProject'
|
||||
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
|
||||
import { useProfile } from 'lib/profile'
|
||||
import { getAppStateSnapshot } from 'state/app-state'
|
||||
import { useSqlEditorV2StateSnapshot } from 'state/sql-editor-v2'
|
||||
@@ -28,15 +28,14 @@ import {
|
||||
InnerSideBarFilterSortDropdown,
|
||||
InnerSideBarFilterSortDropdownItem,
|
||||
} from 'ui-patterns/InnerSideMenu'
|
||||
import { SqlEditorMenuStaticLinks } from './SqlEditorMenuStaticLinks'
|
||||
import { SearchList } from './SQLEditorNavV2/SearchList'
|
||||
import { SQLEditorNav } from './SQLEditorNavV2/SQLEditorNav'
|
||||
|
||||
export const SQLEditorMenu = () => {
|
||||
const router = useRouter()
|
||||
const { profile } = useProfile()
|
||||
const project = useSelectedProject()
|
||||
const { ref } = useParams()
|
||||
const { profile } = useProfile()
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
const snapV2 = useSqlEditorV2StateSnapshot()
|
||||
|
||||
const [search, setSearch] = useState('')
|
||||
@@ -153,14 +152,7 @@ export const SQLEditorMenu = () => {
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
|
||||
{showSearch ? (
|
||||
<SearchList search={debouncedSearch} />
|
||||
) : (
|
||||
<>
|
||||
<SqlEditorMenuStaticLinks />
|
||||
<SQLEditorNav sort={sort} />
|
||||
</>
|
||||
)}
|
||||
{showSearch ? <SearchList search={debouncedSearch} /> : <SQLEditorNav sort={sort} />}
|
||||
</div>
|
||||
|
||||
<div className="p-4 border-t sticky bottom-0 bg-studio">
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
import { LOCAL_STORAGE_KEYS, useParams } from 'common'
|
||||
import { useLocalStorage } from 'hooks/misc/useLocalStorage'
|
||||
import { BookText } from 'lucide-react'
|
||||
import { useRouter } from 'next/router'
|
||||
import {
|
||||
InnerSideMenuCollapsible,
|
||||
InnerSideMenuCollapsibleContent,
|
||||
InnerSideMenuCollapsibleTrigger,
|
||||
} from 'ui-patterns'
|
||||
import { InnerSideMenuDataItem } from 'ui-patterns/InnerSideMenu'
|
||||
import { DEFAULT_SECTION_STATE, type SectionState } from './SQLEditorNav.constants'
|
||||
|
||||
const OPTIONS = ['templates', 'quickstarts'] as const
|
||||
|
||||
export function CommunitySnippetsSection() {
|
||||
const { ref } = useParams()
|
||||
const router = useRouter()
|
||||
|
||||
const [sectionVisibility, setSectionVisibility] = useLocalStorage<SectionState>(
|
||||
LOCAL_STORAGE_KEYS.SQL_EDITOR_SECTION_STATE(ref ?? ''),
|
||||
DEFAULT_SECTION_STATE
|
||||
)
|
||||
const { community: showCommunitySnippets } = sectionVisibility
|
||||
|
||||
function isPageActive(key: string): boolean {
|
||||
return router.asPath === `/project/${ref}/sql/${key}`
|
||||
}
|
||||
|
||||
return (
|
||||
<InnerSideMenuCollapsible
|
||||
className="px-0"
|
||||
open={showCommunitySnippets}
|
||||
onOpenChange={(value) => {
|
||||
setSectionVisibility({
|
||||
...(sectionVisibility ?? DEFAULT_SECTION_STATE),
|
||||
community: value,
|
||||
})
|
||||
}}
|
||||
>
|
||||
<InnerSideMenuCollapsibleTrigger title="Community" />
|
||||
<InnerSideMenuCollapsibleContent className="group-data-[state=open]:pt-2">
|
||||
{OPTIONS.map((pageId) => {
|
||||
const active = isPageActive(pageId)
|
||||
return (
|
||||
<InnerSideMenuDataItem
|
||||
key={pageId}
|
||||
title={pageId === 'templates' ? 'Templates' : 'Quickstarts'}
|
||||
isActive={active}
|
||||
isOpened={false}
|
||||
href={`/project/${ref}/sql/${pageId}`}
|
||||
className="capitalize"
|
||||
>
|
||||
<BookText size={16} className="text-foreground-muted" />
|
||||
{pageId}
|
||||
</InnerSideMenuDataItem>
|
||||
)
|
||||
})}
|
||||
</InnerSideMenuCollapsibleContent>
|
||||
</InnerSideMenuCollapsible>
|
||||
)
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
export type SectionState = {
|
||||
shared: boolean
|
||||
favorite: boolean
|
||||
private: boolean
|
||||
community: boolean
|
||||
}
|
||||
|
||||
export const DEFAULT_SECTION_STATE: SectionState = {
|
||||
shared: false,
|
||||
favorite: false,
|
||||
private: true,
|
||||
community: true,
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import { useSQLSnippetFoldersDeleteMutation } from 'data/content/sql-folders-del
|
||||
import { Snippet, SnippetFolder, useSQLSnippetFoldersQuery } from 'data/content/sql-folders-query'
|
||||
import { useSqlSnippetsQuery } from 'data/content/sql-snippets-query'
|
||||
import { useLocalStorage } from 'hooks/misc/useLocalStorage'
|
||||
import { useSelectedProject } from 'hooks/misc/useSelectedProject'
|
||||
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
|
||||
import { useProfile } from 'lib/profile'
|
||||
import uuidv4 from 'lib/uuid'
|
||||
import {
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
} from 'state/sql-editor-v2'
|
||||
import { createTabId, useTabsStateSnapshot } from 'state/tabs'
|
||||
import { SqlSnippets } from 'types'
|
||||
import { Separator, TreeView } from 'ui'
|
||||
import { TreeView } from 'ui'
|
||||
import {
|
||||
InnerSideBarEmptyPanel,
|
||||
InnerSideMenuCollapsible,
|
||||
@@ -39,7 +39,9 @@ import {
|
||||
InnerSideMenuSeparator,
|
||||
} from 'ui-patterns'
|
||||
import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
|
||||
import { CommunitySnippetsSection } from './CommunitySnippetsSection'
|
||||
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'
|
||||
|
||||
@@ -47,18 +49,14 @@ interface SQLEditorNavProps {
|
||||
sort?: 'inserted_at' | 'name'
|
||||
}
|
||||
|
||||
type SectionState = { shared: boolean; favorite: boolean; private: boolean }
|
||||
const DEFAULT_SECTION_STATE: SectionState = { shared: false, favorite: false, private: true }
|
||||
|
||||
export const SQLEditorNav = ({ sort = 'inserted_at' }: SQLEditorNavProps) => {
|
||||
const router = useRouter()
|
||||
const { ref: projectRef, id } = useParams()
|
||||
|
||||
const { profile } = useProfile()
|
||||
const project = useSelectedProject()
|
||||
const snapV2 = useSqlEditorV2StateSnapshot()
|
||||
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
const tabs = useTabsStateSnapshot()
|
||||
const snapV2 = useSqlEditorV2StateSnapshot()
|
||||
|
||||
const [sectionVisibility, setSectionVisibility] = useLocalStorage<SectionState>(
|
||||
LOCAL_STORAGE_KEYS.SQL_EDITOR_SECTION_STATE(projectRef ?? ''),
|
||||
@@ -545,6 +543,8 @@ export const SQLEditorNav = ({ sort = 'inserted_at' }: SQLEditorNavProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<InnerSideMenuSeparator />
|
||||
|
||||
<InnerSideMenuCollapsible
|
||||
className="px-0"
|
||||
open={showSharedSnippets}
|
||||
@@ -833,7 +833,11 @@ export const SQLEditorNav = ({ sort = 'inserted_at' }: SQLEditorNavProps) => {
|
||||
</InnerSideMenuCollapsibleContent>
|
||||
</InnerSideMenuCollapsible>
|
||||
|
||||
<Separator />
|
||||
<InnerSideMenuSeparator />
|
||||
|
||||
<CommunitySnippetsSection />
|
||||
|
||||
<InnerSideMenuSeparator />
|
||||
|
||||
<RenameQueryModal
|
||||
snippet={selectedSnippetToRename}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
import { useParams } from 'common'
|
||||
import { useRouter } from 'next/router'
|
||||
import { InnerSideMenuDataItem } from 'ui-patterns/InnerSideMenu'
|
||||
|
||||
const OPTIONS = ['templates', 'quickstarts'] as const
|
||||
|
||||
export function SqlEditorMenuStaticLinks() {
|
||||
const { ref } = useParams()
|
||||
const router = useRouter()
|
||||
|
||||
function isPageActive(key: string): boolean {
|
||||
return router.asPath === `/project/${ref}/sql/${key}`
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{OPTIONS.map((pageId) => {
|
||||
const active = isPageActive(pageId)
|
||||
return (
|
||||
<InnerSideMenuDataItem
|
||||
key={pageId}
|
||||
title="Templates"
|
||||
isActive={active}
|
||||
isOpened={false}
|
||||
href={`/project/${ref}/sql/${pageId}`}
|
||||
className="capitalize"
|
||||
>
|
||||
{pageId}
|
||||
</InnerSideMenuDataItem>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import { EntityTypeIcon } from 'components/ui/EntityTypeIcon'
|
||||
import { useQuerySchemaState } from 'hooks/misc/useSchemaQueryState'
|
||||
import { useTabsStateSnapshot, type Tab } from 'state/tabs'
|
||||
import { cn, TabsTrigger_Shadcn_ } from 'ui'
|
||||
import { useEditorType } from '../editors/EditorsLayout.hooks'
|
||||
|
||||
/**
|
||||
* Individual draggable tab component that handles:
|
||||
@@ -28,8 +29,9 @@ export const SortableTab = ({
|
||||
openTabs: Tab[]
|
||||
onClose: (id: string) => void
|
||||
}) => {
|
||||
const { selectedSchema: currentSchema } = useQuerySchemaState()
|
||||
const editor = useEditorType()
|
||||
const tabs = useTabsStateSnapshot()
|
||||
const { selectedSchema: currentSchema } = useQuerySchemaState()
|
||||
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
|
||||
id: tab.id,
|
||||
})
|
||||
@@ -44,8 +46,8 @@ export const SortableTab = ({
|
||||
const shouldShowSchema = useMemo(() => {
|
||||
// For both table and schema tabs, show schema if:
|
||||
// Any tab has a different schema than the current schema parameter
|
||||
return openTabs.some((t) => t.metadata?.schema !== currentSchema)
|
||||
}, [openTabs, currentSchema])
|
||||
return openTabs.some((t) => editor === 'table' && t.metadata?.schema !== currentSchema)
|
||||
}, [openTabs, currentSchema, editor])
|
||||
|
||||
// Create a motion version of TabsTrigger while preserving all functionality
|
||||
// const MotionTabsTrigger = motion(TabsTrigger_Shadcn_)
|
||||
|
||||
@@ -6,7 +6,6 @@ import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import { EditorBaseLayout } from 'components/layouts/editors/EditorBaseLayout'
|
||||
import SQLEditorLayout from 'components/layouts/SQLEditorLayout/SQLEditorLayout'
|
||||
import { SQLEditorMenu } from 'components/layouts/SQLEditorLayout/SQLEditorMenu'
|
||||
import { NewTab } from 'components/layouts/Tabs/NewTab'
|
||||
import { useAppStateSnapshot } from 'state/app-state'
|
||||
import { useTabsStateSnapshot } from 'state/tabs'
|
||||
import type { NextPageWithLayout } from 'types'
|
||||
@@ -26,10 +25,13 @@ const TableEditorPage: NextPageWithLayout = () => {
|
||||
} else if (lastTabId) {
|
||||
const lastTab = store.tabsMap[lastTabId]
|
||||
if (lastTab) router.push(`/project/${projectRef}/sql/${lastTab.id.replace('sql-', '')}`)
|
||||
} else {
|
||||
router.push(`/project/${projectRef}/sql/new`)
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
return <NewTab />
|
||||
return null
|
||||
}
|
||||
|
||||
TableEditorPage.getLayout = (page) => (
|
||||
|
||||
Reference in new issue
Block a user