diff --git a/apps/studio/components/interfaces/SQLEditor/MonacoEditor.tsx b/apps/studio/components/interfaces/SQLEditor/MonacoEditor.tsx index e853f87be47..52d63d4dc0f 100644 --- a/apps/studio/components/interfaces/SQLEditor/MonacoEditor.tsx +++ b/apps/studio/components/interfaces/SQLEditor/MonacoEditor.tsx @@ -12,12 +12,12 @@ import { useSqlEditorV2StateSnapshot } from 'state/sql-editor-v2' import { useTabsStateSnapshot } from 'state/tabs' import { cn } from 'ui' import { Admonition } from 'ui-patterns' -import { untitledSnippetTitle } from './SQLEditor.constants' import type { IStandaloneCodeEditor } from './SQLEditor.types' import { createSqlSnippetSkeletonV2 } from './SQLEditor.utils' export type MonacoEditorProps = { id: string + snippetName: string className?: string editorRef: MutableRefObject monacoRef: MutableRefObject @@ -37,6 +37,7 @@ export type MonacoEditorProps = { const MonacoEditor = ({ id, + snippetName, editorRef, monacoRef, autoFocus = true, @@ -165,7 +166,7 @@ const MonacoEditor = ({ } else { if (ref && profile !== undefined && project !== undefined) { const snippet = createSqlSnippetSkeletonV2({ - name: untitledSnippetTitle, + name: snippetName, sql: value, owner_id: profile?.id, project_id: project?.id, diff --git a/apps/studio/components/interfaces/SQLEditor/SQLEditor.tsx b/apps/studio/components/interfaces/SQLEditor/SQLEditor.tsx index b23aa4dd11b..79171e6b922 100644 --- a/apps/studio/components/interfaces/SQLEditor/SQLEditor.tsx +++ b/apps/studio/components/interfaces/SQLEditor/SQLEditor.tsx @@ -7,7 +7,7 @@ import { useRouter } from 'next/router' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { toast } from 'sonner' -import { IS_PLATFORM, LOCAL_STORAGE_KEYS, useParams } from 'common' +import { LOCAL_STORAGE_KEYS, useParams } from 'common' import ResizableAIWidget from 'components/ui/AIEditor/ResizableAIWidget' import { GridFooter } from 'components/ui/GridFooter' import { useSqlTitleGenerateMutation } from 'data/ai/sql-title-mutation' @@ -22,9 +22,10 @@ import { useOrgAiOptInLevel } from 'hooks/misc/useOrgOptedIntoAi' import { useSchemasForAi } from 'hooks/misc/useSchemasForAi' import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization' import { useSelectedProject } from 'hooks/misc/useSelectedProject' +import { generateDeterministicUuid } from 'lib/api/snippets.browser' import { BASE_PATH } from 'lib/constants' import { formatSql } from 'lib/formatSql' -import { detectOS, uuidv4 } from 'lib/helpers' +import { detectOS } from 'lib/helpers' import { useProfile } from 'lib/profile' import { wrapWithRoleImpersonation } from 'lib/role-impersonation' import { useAiAssistantStateSnapshot } from 'state/ai-assistant-state' @@ -51,7 +52,6 @@ import { cn, } from 'ui' import { useSqlEditorDiff, useSqlEditorPrompt } from './hooks' -import { NewSqlTab } from './NewSqlTab' import { RunQueryWarningModal } from './RunQueryWarningModal' import { ROWS_PER_PAGE_OPTIONS, @@ -122,8 +122,13 @@ export const SQLEditor = () => { // generate an id to be used for new snippets. The dependency on urlId is to avoid a bug which // shows up when clicking on the SQL Editor while being in the SQL editor on a random snippet. + const generatedNewSnippetName = useMemo( + () => `${untitledSnippetTitle} ${Math.floor(Math.random() * 900) + 100}`, + // eslint-disable-next-line react-hooks/exhaustive-deps + [urlId] + ) // eslint-disable-next-line react-hooks/exhaustive-deps - const generatedId = useMemo(() => uuidv4(), [urlId]) + const generatedId = useMemo(() => generateDeterministicUuid([generatedNewSnippetName]), [urlId]) // the id is stable across renders - it depends either on the url or on the memoized generated id const id = !urlId || urlId === 'new' ? generatedId : urlId @@ -636,8 +641,6 @@ export const SQLEditor = () => { } }, [isDiffOpen, isDiffEditorMounted]) - const isNewSnippetOnSelfhosted = urlId === 'new' && !IS_PLATFORM - return ( <> {
- ) : isNewSnippetOnSelfhosted ? ( - ) : ( <> {isDiffOpen && ( @@ -729,6 +730,7 @@ export const SQLEditor = () => { : '' } id={id} + snippetName={snapV2.snippets[id]?.snippet.name ?? generatedNewSnippetName} className={cn(isDiffOpen && 'hidden')} editorRef={editorRef} monacoRef={monacoRef} @@ -779,9 +781,9 @@ export const SQLEditor = () => { - + - + {isLoading ? (