diff --git a/apps/studio/components/interfaces/Functions/EdgeFunctionDetails/EdgeFunctionDetails.tsx b/apps/studio/components/interfaces/Functions/EdgeFunctionDetails/EdgeFunctionDetails.tsx
index aa42058a0a5..1f73410f167 100644
--- a/apps/studio/components/interfaces/Functions/EdgeFunctionDetails/EdgeFunctionDetails.tsx
+++ b/apps/studio/components/interfaces/Functions/EdgeFunctionDetails/EdgeFunctionDetails.tsx
@@ -37,7 +37,7 @@ const EdgeFunctionDetails = () => {
const router = useRouter()
const { ref: projectRef, functionSlug } = useParams()
const [showDeleteModal, setShowDeleteModal] = useState(false)
- const [showInstructions, setShowInstructions] = useState(false)
+ const [showInstructions, setShowInstructions] = useState(true)
const { data: settings } = useProjectSettingsV2Query({ projectRef })
const { data: customDomainData } = useCustomDomainsQuery({ projectRef })
@@ -150,7 +150,7 @@ const EdgeFunctionDetails = () => {
value={selectedFunction?.slug}
/>
-
+ {/* */}
{
- Command line access
+ Deploy, invoke and manage environment variables
setShowInstructions(!showInstructions)}>
{showInstructions ? (
@@ -235,7 +235,7 @@ const EdgeFunctionDetails = () => {
Invoke
- Secrets management
+ Environment variables (secrets)
diff --git a/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/AddNewSecretForm.tsx b/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/AddNewSecretForm.tsx
new file mode 100644
index 00000000000..7dccbd5ad4b
--- /dev/null
+++ b/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/AddNewSecretForm.tsx
@@ -0,0 +1,124 @@
+import { zodResolver } from '@hookform/resolvers/zod'
+import { useEffect, useRef, useState } from 'react'
+import { SubmitHandler, useForm } from 'react-hook-form'
+import { toast } from 'sonner'
+import z from 'zod'
+
+import { useParams } from 'common'
+import { useSecretsCreateMutation } from 'data/secrets/secrets-create-mutation'
+import { Eye, EyeOff } from 'lucide-react'
+import {
+ Button,
+ Form_Shadcn_,
+ FormControl_Shadcn_,
+ FormField_Shadcn_,
+ FormItem_Shadcn_,
+ FormLabel_Shadcn_,
+} from 'ui'
+import { Input } from 'ui-patterns/DataInputs/Input'
+import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
+import Panel from 'components/ui/Panel'
+
+interface AddNewSecretFormProps {
+ onComplete?: () => void
+}
+
+const AddNewSecretForm = ({ onComplete }: AddNewSecretFormProps) => {
+ const { ref: projectRef } = useParams()
+ const submitRef = useRef(null)
+ const [showSecretValue, setShowSecretValue] = useState(false)
+
+ const FormSchema = z.object({
+ name: z
+ .string()
+ .min(1, 'Please provide a name for your secret')
+ .refine((value) => !value.match(/^(SUPABASE_).*/), {
+ message: 'Name must not start with the SUPABASE_ prefix',
+ }),
+ value: z.string().min(1, 'Please provider a value for your secret'),
+ })
+ const defaultValues = { name: '', value: '' }
+
+ const form = useForm({
+ resolver: zodResolver(FormSchema),
+ defaultValues,
+ })
+
+ const { mutate: createSecret, isLoading: isCreating } = useSecretsCreateMutation({
+ onSuccess: (_, variables) => {
+ toast.success(`Successfully created new secret "${variables.secrets[0].name}"`)
+ form.reset(defaultValues)
+ onComplete?.()
+ },
+ })
+
+ const onSubmit: SubmitHandler> = async (data) => {
+ createSecret({ projectRef, secrets: [data] })
+ }
+
+ return (
+
+
+ Add a new environment variable
+
+
+
+
+
+ )
+}
+
+export default AddNewSecretForm
diff --git a/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecrets.tsx b/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecrets.tsx
index 8b7f43e33e8..108b478f90d 100644
--- a/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecrets.tsx
+++ b/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecrets.tsx
@@ -13,11 +13,11 @@ import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
import { useSecretsDeleteMutation } from 'data/secrets/secrets-delete-mutation'
import { ProjectSecret, useSecretsQuery } from 'data/secrets/secrets-query'
import { useCheckPermissions } from 'hooks/misc/useCheckPermissions'
-import { Badge } from 'ui'
+import { Badge, Separator } from 'ui'
import { Input } from 'ui-patterns/DataInputs/Input'
import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
-import AddNewSecretModal from './AddNewSecretModal'
import EdgeFunctionSecret from './EdgeFunctionSecret'
+import AddNewSecretForm from './AddNewSecretForm'
const EdgeFunctionSecrets = () => {
const { ref: projectRef } = useParams()
@@ -48,11 +48,17 @@ const EdgeFunctionSecrets = () => {
return (
<>
{isLoading && }
-
{isError && }
+ {canUpdateSecrets && (
+
+
setShowCreateSecret(false)} />
+
+
+ )}
+
{isSuccess && (
-
+
{!canReadSecrets ? (
) : (
@@ -61,28 +67,11 @@ const EdgeFunctionSecrets = () => {
setSearchString(e.target.value)}
icon={
}
/>
-
-
- setShowCreateSecret(true)}
- tooltip={{
- content: {
- side: 'bottom',
- text: !canUpdateSecrets
- ? 'You need additional permissions to update edge function secrets'
- : undefined,
- },
- }}
- >
- Add new secret
-
-
{
)}
- setShowCreateSecret(false)} />
-
{isNewAPIDocsEnabled && (
{
return (
<>
-
- Edge Function Secrets Management
-
- Manage the secrets for your project's edge functions
-
+
+
+ Edge Function Environment Variables
+
+ Manage the environment variables (secrets) for your project's edge functions
+
+
+
+
+