diff --git a/studio/components/interfaces/Database/Functions/CreateFunction.tsx b/studio/components/interfaces/Database/Functions/CreateFunction.tsx index 263627cea7a..186007d6b89 100644 --- a/studio/components/interfaces/Database/Functions/CreateFunction.tsx +++ b/studio/components/interfaces/Database/Functions/CreateFunction.tsx @@ -1,4 +1,4 @@ -import { FC, useEffect, useContext, createContext, FormEvent } from 'react' +import { FC, useEffect, useContext, createContext, FormEvent, useState } from 'react' import { isEmpty, mapValues, has, filter, keyBy, isUndefined, partition, isNull } from 'lodash' import { observer, useLocalObservable } from 'mobx-react-lite' import { @@ -12,6 +12,7 @@ import { Radio, IconPlus, Toggle, + Modal, } from '@supabase/ui' import { Dictionary } from 'components/grid' import { makeAutoObservable } from 'mobx' @@ -20,6 +21,7 @@ import { useStore } from 'hooks' import Panel from 'components/ui/Panel' import SqlEditor from 'components/ui/SqlEditor' import { POSTGRES_DATA_TYPES } from 'components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.constants' +import ConfirmationModal from 'components/ui/ConfirmationModal' class CreateFunctionFormState { id: number | undefined @@ -145,6 +147,7 @@ class CreateFunctionStore implements ICreateFunctionStore { meta = null schemas = [] advancedVisible = false + isDirty = false constructor() { makeAutoObservable(this) @@ -172,7 +175,12 @@ class CreateFunctionStore implements ICreateFunctionStore { this.loading = value } + setIsDirty = (value: boolean) => { + this.isDirty = value + } + onFormChange = ({ key, value }: { key: string; value: any }) => { + this.isDirty = true if (has(this.formState, key)) { const temp = (this.formState as any)[key] as any ;(this.formState as any)[key] = { ...temp, value, error: undefined } @@ -296,6 +304,8 @@ const CreateFunction: FC = ({ func, visible, setVisible }) const _localState = useLocalObservable(() => new CreateFunctionStore()) _localState.meta = meta as any + const [isClosingPanel, setIsClosingPanel] = useState(false) + useEffect(() => { const fetchSchemas = async () => { await (_localState!.meta as any).schemas.load() @@ -308,6 +318,7 @@ const CreateFunction: FC = ({ func, visible, setVisible }) useEffect(() => { _localState.formState.reset(func) + _localState.setIsDirty(false) }, [visible, func]) async function handleSubmit() { @@ -348,12 +359,16 @@ const CreateFunction: FC = ({ func, visible, setVisible }) } } + function isClosingSidePanel() { + _localState.isDirty ? setIsClosingPanel(true) : setVisible(!visible) + } + return ( <> setVisible(!visible)} + onCancel={isClosingSidePanel} header={_localState.title} className="hooks-sidepanel transform transition-all duration-300 ease-in-out mr-0" loading={_localState.loading} @@ -436,6 +451,24 @@ const CreateFunction: FC = ({ func, visible, setVisible }) )} + setIsClosingPanel(false)} + onSelectConfirm={() => { + setIsClosingPanel(false) + setVisible(!visible) + }} + children={ + +

+ There are unsaved changes. Are you sure you want to close the panel? Your changes + will be lost. +

+
+ } + />
) diff --git a/studio/components/interfaces/Functions/FunctionsLayout.tsx b/studio/components/interfaces/Functions/FunctionsLayout.tsx index f39ff98d5dd..3614be8ea50 100644 --- a/studio/components/interfaces/Functions/FunctionsLayout.tsx +++ b/studio/components/interfaces/Functions/FunctionsLayout.tsx @@ -2,12 +2,11 @@ import Link from 'next/link' import { useRouter } from 'next/router' import React, { useEffect } from 'react' import { observer } from 'mobx-react-lite' -import { IconCode, Loading, Badge } from '@supabase/ui' +import { IconCode, Loading } from '@supabase/ui' import { useStore, withAuth } from 'hooks' import FunctionsNav from './FunctionsNav' import BaseLayout from 'components/layouts' -import WarningBanner from 'components/ui/WarningBanner' const FunctionsLayout = ({ children }: { children?: React.ReactNode }) => { const { functions, ui } = useStore() @@ -58,7 +57,7 @@ const FunctionsLayout = ({ children }: { children?: React.ReactNode }) => {
-

Functions

+

Edge Functions

Beta

@@ -85,10 +84,11 @@ const FunctionsLayout = ({ children }: { children?: React.ReactNode }) => { > +

- Functions + Edge Functions

Beta

@@ -119,22 +119,10 @@ const FunctionsLayout = ({ children }: { children?: React.ReactNode }) => { {item && }
{children}
diff --git a/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils.tsx b/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils.tsx index be88a785db2..c34fcc22c61 100644 --- a/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils.tsx +++ b/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils.tsx @@ -72,7 +72,7 @@ export const generateProductRoutes = (ref: string, project?: ProjectBase): Route ? [ { key: 'functions', - label: 'Functions', + label: 'Edge Functions', icon: , link: isProjectBuilding ? buildingUrl : `/project/${ref}/functions`, },