mirror of
https://github.com/supabase/supabase.git
synced 2026-10-15 06:09:08 +03:00
feat: UI improvements for new API keys + edge functions
This commit is contained in:
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>
|
||||
|
||||
+4
-1
@@ -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>
|
||||
|
||||
+7
-7
@@ -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,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
Reference in new issue
Block a user