feat: UI improvements for new API keys + edge functions

This commit is contained in:
Stojan Dimitrovski committed 2025-06-07 13:08:57 +02:00
1 parent 6d5f7f25b2
commit d0c329ccb2
5 files changed
+48 -9

No files matched your search

@@ -33,6 +33,11 @@ export const CreateNewAPIKeysButton = () => {
name: 'default',
})
// sleep 1 second to allow functions secret creation to settle
await new Promise((accept) => {
setTimeout(accept, 1000)
})
// Create secret key
await createAPIKey({
projectRef,
@@ -1,5 +1,5 @@
import { zodResolver } from '@hookform/resolvers/zod'
import { useState } from 'react'
import { useState, useMemo } from 'react'
import { SubmitHandler, useForm } from 'react-hook-form'
import {
Button,
@@ -14,8 +14,10 @@ import {
DialogTrigger,
FormControl_Shadcn_,
FormField_Shadcn_,
FormLabel_Shadcn_,
Form_Shadcn_,
Input_Shadcn_,
Switch,
} from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import * as z from 'zod'
@@ -28,6 +30,7 @@ const FORM_ID = 'create-secret-api-key'
const SCHEMA = z.object({
name: z.string(),
description: z.string().trim(),
expose_as_env: z.boolean(),
})
const CreateSecretAPIKeyDialog = () => {
@@ -43,6 +46,7 @@ const CreateSecretAPIKeyDialog = () => {
defaultValues: {
name: '',
description: '',
expose_as_env: true,
},
})
@@ -55,6 +59,7 @@ const CreateSecretAPIKeyDialog = () => {
type: 'secret',
name: values.name,
description: values.description,
expose_as_env: values.expose_as_env,
},
{
onSuccess: () => {
@@ -123,6 +128,30 @@ const CreateSecretAPIKeyDialog = () => {
</FormItemLayout>
)}
/>
<FormField_Shadcn_
key="expose_as_env"
name="expose_as_env"
className="flex-row"
control={form.control}
render={({ field }) => {
const name = form.watch('name').toUpperCase()
return (
<FormItemLayout
label="Expose as environment variable"
description={`Will be available as SUPABASE_SECRET_KEY_${name || '<NAME>'} in Edge Functions and other integrations that support them.`}
>
<FormControl_Shadcn_>
<Switch
key="expose_as_env"
checked={field.value}
onCheckedChange={(value) => field.onChange(value)}
/>
</FormControl_Shadcn_>
</FormItemLayout>
)
}}
/>
</form>
</Form_Shadcn_>
</DialogSection>
@@ -16,7 +16,10 @@ const EdgeFunctionSecret = ({ secret, onSelectDelete }: EdgeFunctionSecretProps)
const canUpdateSecrets = useCheckPermissions(PermissionAction.SECRETS_WRITE, '*')
// [Joshen] Following API's validation:
// https://github.com/supabase/infrastructure/blob/develop/api/src/routes/v1/projects/ref/secrets/secrets.controller.ts#L106
const isReservedSecret = !!secret.name.match(/^(SUPABASE_).*/)
const isReservedSecret = !!(
secret.name.match(/^(SUPABASE_).*/) &&
!secret.name.match(/^SUPABASE_(PUBLISHABLE|SECRET)_[A-Z0-9_]+$/)
)
return (
<Table.tr>
@@ -38,9 +38,9 @@ const EdgeFunctionSecrets = () => {
const secrets =
searchString.length > 0
? data?.filter((secret) => secret.name.toLowerCase().includes(searchString.toLowerCase())) ??
[]
: data ?? []
? (data?.filter((secret) => secret.name.toLowerCase().includes(searchString.toLowerCase())) ??
[])
: (data ?? [])
return (
<>
@@ -76,10 +76,10 @@ const EdgeFunctionSecrets = () => {
head={[
<Table.th key="secret-name">Name</Table.th>,
<Table.th key="secret-value" className="flex items-center gap-x-2">
Digest{' '}
<Badge color="scale" className="font-mono">
SHA256
</Badge>
</Badge>{' '}
Digest or prefix
</Table.th>,
<Table.th key="secret-updated-at">Updated at</Table.th>,
<Table.th key="actions" />,
@@ -95,7 +95,7 @@ const EdgeFunctionSecrets = () => {
))
) : secrets.length === 0 && searchString.length > 0 ? (
<Table.tr>
<Table.td colSpan={3}>
<Table.td colSpan={4}>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-foreground-light">
Your search for "{searchString}" did not return any results
@@ -104,7 +104,7 @@ const EdgeFunctionSecrets = () => {
</Table.tr>
) : (
<Table.tr>
<Table.td colSpan={3}>
<Table.td colSpan={4}>
<p className="text-sm text-foreground">No secrets created</p>
<p className="text-sm text-foreground-light">
There are no secrets associated with your project yet
@@ -9,6 +9,7 @@ export type APIKeyCreateVariables = {
projectRef?: string
name: string
description?: string
expose_as_env?: boolean
} & (
| {
type: 'publishable'
@@ -44,6 +45,7 @@ export async function createAPIKey(payload: APIKeyCreateVariables) {
type: payload.type,
name: payload.name,
description: payload.description || null,
expose_as_env: payload.expose_as_env,
},
})