EdgeFunctionSecret.tsx128 lines · main
1import { PermissionAction } from '@supabase/shared-types/out/constants'
2import { Edit2, MoreVertical, Trash } from 'lucide-react'
3import { toast } from 'sonner'
4import {
5 Button,
6 copyToClipboard,
7 DropdownMenu,
8 DropdownMenuContent,
9 DropdownMenuItem,
10 DropdownMenuSeparator,
11 DropdownMenuTrigger,
12 TableCell,
13 TableRow,
14 Tooltip,
15 TooltipContent,
16 TooltipTrigger,
17} from 'ui'
18import { TimestampInfo } from 'ui-patterns'
19
20import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
21import type { ProjectSecret } from '@/data/secrets/secrets-query'
22import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
23
24interface EdgeFunctionSecretProps {
25 secret: ProjectSecret
26 onSelectDelete: () => void
27 onSelectEdit: () => void
28}
29
30const EdgeFunctionSecret = ({ secret, onSelectEdit, onSelectDelete }: EdgeFunctionSecretProps) => {
31 const { can: canUpdateSecrets } = useAsyncCheckPermissions(PermissionAction.SECRETS_WRITE, '*')
32
33 return (
34 <TableRow>
35 <TableCell>
36 <Tooltip>
37 <TooltipTrigger
38 onClick={() => {
39 copyToClipboard(secret.name)
40 toast.success(`Copied ${secret.name}`)
41 }}
42 >
43 <p className="truncate py-1">
44 <code className="text-code-inline">{secret.name}</code>
45 </p>
46 </TooltipTrigger>
47 <TooltipContent side="bottom">Click to copy</TooltipContent>
48 </Tooltip>
49 </TableCell>
50 <TableCell>
51 <p className="max-w-96 truncate" title={secret.value}>
52 <code className="text-code-inline text-foreground-light!">{secret.value}</code>
53 </p>
54 </TableCell>
55 <TableCell>
56 {!!secret.updated_at ? (
57 <TimestampInfo
58 displayAs="utc"
59 utcTimestamp={secret.updated_at}
60 labelFormat="DD MMM YYYY HH:mm:ss (ZZ)"
61 className="text-sm! text-foreground-light whitespace-nowrap"
62 />
63 ) : (
64 '-'
65 )}
66 </TableCell>
67 <TableCell>
68 <div className="flex items-center justify-end">
69 <DropdownMenu>
70 <DropdownMenuTrigger asChild>
71 <Button
72 aria-label="More options"
73 type="default"
74 className="px-1"
75 icon={<MoreVertical />}
76 />
77 </DropdownMenuTrigger>
78 <DropdownMenuContent side="bottom" align="end" className="w-52">
79 <DropdownMenuItem asChild>
80 <ButtonTooltip
81 type="text"
82 icon={<Edit2 size={14} />}
83 className="w-full justify-start group text-inherit"
84 disabled={!canUpdateSecrets}
85 onClick={() => onSelectEdit()}
86 tooltip={{
87 content: {
88 side: 'bottom',
89 text: !canUpdateSecrets
90 ? 'You need additional permissions to edit edge function secrets'
91 : undefined,
92 },
93 }}
94 >
95 Edit secret
96 </ButtonTooltip>
97 </DropdownMenuItem>
98
99 <DropdownMenuSeparator />
100
101 <DropdownMenuItem asChild>
102 <ButtonTooltip
103 type="text"
104 icon={<Trash size={14} className="group-not-disabled:text-destructive" />}
105 className="w-full justify-start group text-inherit"
106 disabled={!canUpdateSecrets}
107 onClick={() => onSelectDelete()}
108 tooltip={{
109 content: {
110 side: 'bottom',
111 text: !canUpdateSecrets
112 ? 'You need additional permissions to delete edge function secrets'
113 : undefined,
114 },
115 }}
116 >
117 Delete secret
118 </ButtonTooltip>
119 </DropdownMenuItem>
120 </DropdownMenuContent>
121 </DropdownMenu>
122 </div>
123 </TableCell>
124 </TableRow>
125 )
126}
127
128export default EdgeFunctionSecret