diff --git a/apps/studio/components/interfaces/Database/Functions/CreateFunction/CreateFunctionHeader.tsx b/apps/studio/components/interfaces/Database/Functions/CreateFunction/CreateFunctionHeader.tsx index de1260fac5d..4e5083d5312 100644 --- a/apps/studio/components/interfaces/Database/Functions/CreateFunction/CreateFunctionHeader.tsx +++ b/apps/studio/components/interfaces/Database/Functions/CreateFunction/CreateFunctionHeader.tsx @@ -2,15 +2,15 @@ import { X } from 'lucide-react' import { SheetClose, SheetHeader, SheetTitle, cn } from 'ui' +interface CreateFunctionHeaderProps { + selectedFunction?: string + isDuplicating?: boolean +} + export const CreateFunctionHeader = ({ selectedFunction, - assistantVisible, - setAssistantVisible, -}: { - selectedFunction?: string - assistantVisible: boolean - setAssistantVisible: (v: boolean) => void -}) => { + isDuplicating, +}: CreateFunctionHeaderProps) => { return (
@@ -27,33 +27,12 @@ export const CreateFunctionHeader = ({ {selectedFunction !== undefined - ? `Edit '${selectedFunction}' function` + ? isDuplicating + ? `Duplicate function` + : `Edit '${selectedFunction}' function` : 'Add a new function'}
- {/* - - - - - {assistantVisible ? 'Hide' : 'Show'} tools - - */}
) } diff --git a/apps/studio/components/interfaces/Database/Functions/CreateFunction/index.tsx b/apps/studio/components/interfaces/Database/Functions/CreateFunction/index.tsx index 829952493cd..f494e11ca38 100644 --- a/apps/studio/components/interfaces/Database/Functions/CreateFunction/index.tsx +++ b/apps/studio/components/interfaces/Database/Functions/CreateFunction/index.tsx @@ -50,8 +50,9 @@ const FORM_ID = 'create-function-sidepanel' interface CreateFunctionProps { func?: DatabaseFunction + isDuplicating?: boolean visible: boolean - setVisible: (value: boolean) => void + onClose: () => void } const FormSchema = z.object({ @@ -68,15 +69,13 @@ const FormSchema = z.object({ .optional(), }) -const CreateFunction = ({ func, visible, setVisible }: CreateFunctionProps) => { +const CreateFunction = ({ func, visible, isDuplicating = false, onClose }: CreateFunctionProps) => { const { data: project } = useSelectedProjectQuery() const [isClosingPanel, setIsClosingPanel] = useState(false) const [advancedSettingsShown, setAdvancedSettingsShown] = useState(false) - // For now, there's no AI assistant for functions - const [assistantVisible, setAssistantVisible] = useState(false) const [focusedEditor, setFocusedEditor] = useState(false) - const isEditing = !!func?.id + const isEditing = !isDuplicating && !!func?.id const form = useForm>({ resolver: zodResolver(FormSchema), @@ -89,7 +88,7 @@ const CreateFunction = ({ func, visible, setVisible }: CreateFunctionProps) => { useDatabaseFunctionUpdateMutation() function isClosingSidePanel() { - form.formState.isDirty ? setIsClosingPanel(true) : setVisible(!visible) + form.formState.isDirty ? setIsClosingPanel(true) : onClose() } const onSubmit: SubmitHandler> = async (data) => { @@ -111,7 +110,7 @@ const CreateFunction = ({ func, visible, setVisible }: CreateFunctionProps) => { { onSuccess: () => { toast.success(`Successfully updated function ${data.name}`) - setVisible(!visible) + onClose() }, } ) @@ -125,7 +124,7 @@ const CreateFunction = ({ func, visible, setVisible }: CreateFunctionProps) => { { onSuccess: () => { toast.success(`Successfully created function ${data.name}`) - setVisible(!visible) + onClose() }, } ) @@ -155,19 +154,11 @@ const CreateFunction = ({ func, visible, setVisible }: CreateFunctionProps) => { isClosingSidePanel()}> -
- +
+
{
- {assistantVisible ? ( -
- {/* This is where the AI assistant would be added */} -
- ) : null} { onCancel={() => setIsClosingPanel(false)} onConfirm={() => { setIsClosingPanel(false) - setVisible(!visible) + onClose() }} >

diff --git a/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionList.tsx b/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionList.tsx index b2e7d008db2..be7259728a9 100644 --- a/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionList.tsx +++ b/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionList.tsx @@ -1,6 +1,6 @@ import { PermissionAction } from '@supabase/shared-types/out/constants' import { includes, noop, sortBy } from 'lodash' -import { Edit, Edit2, FileText, MoreVertical, Trash } from 'lucide-react' +import { Copy, Edit, Edit2, FileText, MoreVertical, Trash } from 'lucide-react' import { useRouter } from 'next/router' import { ButtonTooltip } from 'components/ui/ButtonTooltip' @@ -23,6 +23,7 @@ interface FunctionListProps { schema: string filterString: string isLocked: boolean + duplicateFunction: (fn: any) => void editFunction: (fn: any) => void deleteFunction: (fn: any) => void } @@ -31,6 +32,7 @@ const FunctionList = ({ schema, filterString, isLocked, + duplicateFunction = noop, editFunction = noop, deleteFunction = noop, }: FunctionListProps) => { @@ -132,6 +134,7 @@ const FunctionList = ({

Client API docs

)} + editFunction(x)}>

Edit function

@@ -169,6 +172,13 @@ const FunctionList = ({

Edit function with Assistant

+ duplicateFunction(x)} + > + +

Duplicate function

+
deleteFunction(x)}> diff --git a/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionsList.tsx b/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionsList.tsx index 481251005de..5d8476f3998 100644 --- a/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionsList.tsx +++ b/apps/studio/components/interfaces/Database/Functions/FunctionsList/FunctionsList.tsx @@ -32,6 +32,7 @@ import FunctionList from './FunctionList' interface FunctionsListProps { createFunction: () => void + duplicateFunction: (fn: PostgresFunction) => void editFunction: (fn: PostgresFunction) => void deleteFunction: (fn: PostgresFunction) => void } @@ -40,6 +41,7 @@ const FunctionsList = ({ createFunction = noop, editFunction = noop, deleteFunction = noop, + duplicateFunction = noop, }: FunctionsListProps) => { const router = useRouter() const { search } = useParams() @@ -199,6 +201,7 @@ const FunctionsList = ({ schema={selectedSchema} filterString={filterString} isLocked={isSchemaLocked} + duplicateFunction={duplicateFunction} editFunction={editFunction} deleteFunction={deleteFunction} /> diff --git a/apps/studio/pages/project/[ref]/database/functions.tsx b/apps/studio/pages/project/[ref]/database/functions.tsx index 83b5f67490e..09b2fc34186 100644 --- a/apps/studio/pages/project/[ref]/database/functions.tsx +++ b/apps/studio/pages/project/[ref]/database/functions.tsx @@ -19,6 +19,7 @@ const DatabaseFunctionsPage: NextPageWithLayout = () => { const [selectedFunction, setSelectedFunction] = useState() const [showCreateFunctionForm, setShowCreateFunctionForm] = useState(false) const [showDeleteFunctionForm, setShowDeleteFunctionForm] = useState(false) + const [isDuplicating, setIsDuplicating] = useState(false) const isInlineEditorEnabled = useIsInlineEditorEnabled() // Local editor panel state @@ -42,6 +43,23 @@ const DatabaseFunctionsPage: NextPageWithLayout = () => { } } + const duplicateFunction = (fn: DatabaseFunction) => { + setIsDuplicating(true) + + const dupFn = { + ...fn, + name: `${fn.name}_duplicate`, + } + + if (isInlineEditorEnabled) { + setSelectedFunctionForEditor(dupFn) + setEditorPanelOpen(true) + } else { + setSelectedFunction(dupFn) + setShowCreateFunctionForm(true) + } + } + const editFunction = (fn: DatabaseFunction) => { if (isInlineEditorEnabled) { setSelectedFunctionForEditor(fn) @@ -57,6 +75,12 @@ const DatabaseFunctionsPage: NextPageWithLayout = () => { setShowDeleteFunctionForm(true) } + const resetEditorPanel = () => { + setIsDuplicating(false) + setEditorPanelOpen(false) + setSelectedFunctionForEditor(undefined) + } + if (isPermissionsLoaded && !canReadFunctions) { return } @@ -72,6 +96,7 @@ const DatabaseFunctionsPage: NextPageWithLayout = () => { /> @@ -81,7 +106,11 @@ const DatabaseFunctionsPage: NextPageWithLayout = () => { { + setShowCreateFunctionForm(false) + setIsDuplicating(false) + }} + isDuplicating={isDuplicating} /> { { - setEditorPanelOpen(false) - setSelectedFunctionForEditor(undefined) - }} - onClose={() => { - setEditorPanelOpen(false) - setSelectedFunctionForEditor(undefined) - }} + onRunSuccess={resetEditorPanel} + onClose={resetEditorPanel} initialValue={ selectedFunctionForEditor ? selectedFunctionForEditor.complete_statement @@ -113,12 +136,16 @@ $$;` } label={ selectedFunctionForEditor - ? `Edit function "${selectedFunctionForEditor.name}"` + ? isDuplicating + ? `Duplicate function "${selectedFunctionForEditor.name}"` + : `Edit function "${selectedFunctionForEditor.name}"` : 'Create new database function' } initialPrompt={ selectedFunctionForEditor - ? `Update the database function "${selectedFunctionForEditor.name}" to...` + ? isDuplicating + ? `Duplicate the database function "${selectedFunctionForEditor.name}" to...` + : `Update the database function "${selectedFunctionForEditor.name}" to...` : 'Create a new database function that...' } />