Skip to content

Commit

Permalink
Chore/sql editor fixes (supabase#29204)
Browse files Browse the repository at this point in the history
* Add validation for same folder name

* Add validation in move query modal for folder name

* Add validation in move query modal for folder name min length 1

* Handle rename folder failed due to duplicate folder name

* Fix renaming folder to a name that already exists
  • Loading branch information
joshenlim authored Sep 11, 2024
1 parent 193e153 commit 9e1d6f9
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 9 deletions.
18 changes: 12 additions & 6 deletions apps/studio/components/interfaces/SQLEditor/MoveQueryModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,23 @@ export const MoveQueryModal = ({ visible, snippets = [], onClose }: MoveQueryMod

const { mutateAsync: createFolder, isLoading: isCreatingFolder } =
useSQLSnippetFolderCreateMutation()
const {
mutate: moveSnippet,
mutateAsync: moveSnippetAsync,
isLoading: isMovingSnippet,
} = useContentUpsertV2Mutation({
const { mutateAsync: moveSnippetAsync, isLoading: isMovingSnippet } = useContentUpsertV2Mutation({
onError: (error) => {
toast.error(`Failed to move query: ${error.message}`)
},
})

const FormSchema = z.object({ name: z.string() })
const FormSchema = z
.object({ name: z.string().min(1, 'Please provide a name for the folder') })
.refine(
(data) => {
return !snapV2.allFolderNames.includes(data.name)
},
{
message: 'This folder name already exists',
path: ['name'],
}
)
const form = useForm<z.infer<typeof FormSchema>>({
mode: 'onSubmit',
reValidateMode: 'onSubmit',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -531,8 +531,11 @@ export const SQLEditorNav = ({ searchText: _searchText }: SQLEditorNavProps) =>
onSelectShare={() => setSelectedSnippetToShare(element.metadata as Snippet)}
onEditSave={(name: string) => {
// [Joshen] Inline editing only for folders for now
if (name.length === 0) snapV2.removeFolder(element.id as string)
else snapV2.saveFolder({ id: element.id as string, name })
if (name.length === 0 && element.id === 'new-folder') {
snapV2.removeFolder(element.id as string)
} else if (name.length > 0) {
snapV2.saveFolder({ id: element.id as string, name })
}
}}
/>
)}
Expand Down
39 changes: 38 additions & 1 deletion apps/studio/state/sql-editor-v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ export const sqlEditorState = proxy({
},
limit: 100,
order: 'inserted_at' as 'name' | 'inserted_at',
// For handling renaming folder failed
lastUpdatedFolderName: '',

get allFolderNames() {
return Object.values(sqlEditorState.folders).map((x) => x.folder.name)
},

// ========================================================================
// ## Methods to interact the store with
Expand Down Expand Up @@ -204,6 +210,17 @@ export const sqlEditorState = proxy({

saveFolder: ({ id, name }: { id: string; name: string }) => {
const hasChanges = sqlEditorState.folders[id].folder.name !== name

if (id === 'new-folder' && sqlEditorState.allFolderNames.includes(name)) {
sqlEditorState.removeFolder(id)
return toast.error('This folder name already exists')
} else if (hasChanges && sqlEditorState.allFolderNames.includes(name)) {
sqlEditorState.folders[id] = { ...sqlEditorState.folders[id], status: 'idle' }
return toast.error('This folder name already exists')
}

const originalFolderName = sqlEditorState.folders[id].folder.name.slice()

sqlEditorState.folders[id] = {
projectRef: sqlEditorState.folders[id].projectRef,
status: hasChanges ? 'saving' : 'idle',
Expand All @@ -213,7 +230,10 @@ export const sqlEditorState = proxy({
name,
},
}
if (hasChanges) sqlEditorState.needsSaving.add(id)
if (hasChanges) {
sqlEditorState.lastUpdatedFolderName = originalFolderName
sqlEditorState.needsSaving.add(id)
}
},

removeFolder: (id: string) => {
Expand Down Expand Up @@ -390,6 +410,23 @@ async function upsertFolder(id: string, projectRef: string, name: string) {
}
} catch (error: any) {
toast.error(`Failed to save folder: ${error.message}`)
if (error.message.includes('create')) {
sqlEditorState.removeFolder(id)
} else if (
error.message.includes('update') &&
sqlEditorState.lastUpdatedFolderName.length > 0
) {
sqlEditorState.folders[id] = {
...sqlEditorState.folders[id],
status: 'idle',
folder: {
...sqlEditorState.folders[id].folder,
name: sqlEditorState.lastUpdatedFolderName,
},
}
}
} finally {
sqlEditorState.lastUpdatedFolderName = ''
}
}

Expand Down
8 changes: 8 additions & 0 deletions packages/ui/src/components/TreeView/TreeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,17 @@ const TreeViewItem = forwardRef<
useEffect(() => {
if (isEditing) {
inputRef.current?.focus()
} else {
setLocalValueState(name)
}
}, [isEditing])

useEffect(() => {
if (!isLoading) {
setLocalValueState(name)
}
}, [isLoading])

const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
onEditSubmit?.(localValueState)
Expand Down

0 comments on commit 9e1d6f9

Please sign in to comment.