SecretsManagement() — supabase Function Reference
Architecture documentation for the SecretsManagement() function in SecretsManagement.tsx from the supabase codebase.
Entity Profile
Dependency Diagram
graph TD 9be42c55_67a4_6c60_26ec_df4d90e32819["SecretsManagement()"] fbf17bcf_c38b_443a_2656_70206e6c0a8f["formatSecretColumns()"] 9be42c55_67a4_6c60_26ec_df4d90e32819 -->|calls| fbf17bcf_c38b_443a_2656_70206e6c0a8f style 9be42c55_67a4_6c60_26ec_df4d90e32819 fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
apps/studio/components/interfaces/Integrations/Vault/Secrets/SecretsManagement.tsx lines 34–252
export const SecretsManagement = () => {
const { search } = useParams()
const { data: project } = useSelectedProjectQuery()
// Track the ID being deleted to exclude it from error checking
const deletingSecretIdRef = useRef<string | null>(null)
const [searchValue, setSearchValue] = useState<string>('')
const [showAddSecretModal, setShowAddSecretModal] = useQueryState(
'new',
parseAsBoolean.withDefault(false).withOptions({ history: 'push', clearOnDefault: true })
)
const [selectedSort, setSelectedSort] = useState<'updated_at' | 'name'>('updated_at')
const { can: canManageSecrets } = useAsyncCheckPermissions(
PermissionAction.TENANT_SQL_ADMIN_WRITE,
'tables'
)
const {
data,
isPending: isLoading,
isRefetching,
refetch,
error,
isError,
} = useVaultSecretsQuery({
projectRef: project?.ref!,
connectionString: project?.connectionString,
})
const allSecrets = useMemo(() => data || [], [data])
const { setValue: setSelectedSecretToEdit, value: secretToEdit } = useQueryStateWithSelect({
urlKey: 'edit',
select: (id: string) => (id ? allSecrets?.find((secret) => secret.id === id) : undefined),
enabled: !!allSecrets && !isLoading,
onError: () => toast.error(`Secret not found`),
})
const { setValue: setSelectedSecretToRemove, value: secretToDelete } = useQueryStateWithSelect({
urlKey: 'delete',
select: (id: string) => (id ? allSecrets?.find((secret) => secret.id === id) : undefined),
enabled: !!allSecrets && !isLoading,
onError: (_error, selectedId) =>
handleErrorOnDelete(deletingSecretIdRef, selectedId, `Secret not found`),
})
const secrets = useMemo(() => {
const filtered =
searchValue.length > 0
? allSecrets.filter(
(secret) =>
(secret?.name ?? '').toLowerCase().includes(searchValue.trim().toLowerCase()) ||
(secret?.id ?? '').toLowerCase().includes(searchValue.trim().toLowerCase())
)
: allSecrets
if (selectedSort === 'updated_at') {
return sortBy(filtered, (s) => Number(new Date(s.updated_at))).reverse()
}
return sortBy(filtered, (s) => (s.name || '').toLowerCase())
}, [allSecrets, searchValue, selectedSort])
useEffect(() => {
if (search !== undefined) setSearchValue(search)
}, [search])
const columns = useMemo(
() =>
formatSecretColumns({
onSelectEdit: (secret) => setSelectedSecretToEdit(secret.id),
onSelectRemove: (secret) => setSelectedSecretToRemove(secret.id),
}),
[setSelectedSecretToEdit, setSelectedSecretToRemove]
)
return (
<>
<div className="h-full w-full space-y-4">
<div className="h-full w-full flex flex-col relative">
<div className="bg-surface-200 py-3 px-10 flex items-center justify-between flex-wrap">
<div className="flex items-center gap-2">
<Input
size="tiny"
className="w-52"
placeholder="Search by name or key ID"
icon={<Search />}
value={searchValue ?? ''}
onChange={(e) => setSearchValue(e.target.value)}
actions={[
searchValue && (
<Button
size="tiny"
type="text"
icon={<X />}
onClick={() => {
setSearchValue('')
}}
className="p-0 h-5 w-5"
/>
),
]}
/>
<Select_Shadcn_ value={selectedSort} onValueChange={(v) => setSelectedSort(v as any)}>
<SelectTrigger_Shadcn_ size="tiny" className="w-44">
<SelectValue_Shadcn_ asChild>
<>Sort by {selectedSort}</>
</SelectValue_Shadcn_>
</SelectTrigger_Shadcn_>
<SelectContent_Shadcn_>
<SelectItem_Shadcn_ value="updated_at" className="text-xs">
Updated at
</SelectItem_Shadcn_>
<SelectItem_Shadcn_ value="name" className="text-xs">
Name
</SelectItem_Shadcn_>
</SelectContent_Shadcn_>
</Select_Shadcn_>
</div>
<div className="flex items-center gap-x-2">
<Button
type="default"
icon={<RefreshCw />}
loading={isRefetching}
onClick={() => refetch()}
>
Refresh
</Button>
<DocsButton href={`${DOCS_URL}/guides/database/vault`} />
<ButtonTooltip
type="primary"
disabled={!canManageSecrets}
onClick={() => setShowAddSecretModal(true)}
tooltip={{
content: {
side: 'bottom',
text: !canManageSecrets
? 'You need additional permissions to add secrets'
: undefined,
},
}}
>
Add new secret
</ButtonTooltip>
</div>
</div>
<LoadingLine loading={isLoading || isRefetching} />
{isError ? (
<div className="px-6 py-6 space-x-2 flex items-center justify-center">
<p className="text-sm text-foreground">Failed to load secrets</p>
</div>
) : (
<DataGrid
className="flex-grow border-t-0"
rowHeight={52}
headerRowHeight={36}
columns={columns}
rows={secrets}
rowKeyGetter={(row: VaultSecret) => row.id}
rowClass={() => {
return cn(
'cursor-pointer',
'[&>.rdg-cell]:border-box [&>.rdg-cell]:outline-none [&>.rdg-cell]:shadow-none',
'[&>.rdg-cell:first-child>div]:pl-8'
)
}}
renderers={{
renderRow(_, props) {
return <Row key={(props.row as VaultSecret).id} {...props} />
},
}}
/>
)}
{secrets.length === 0 && !isLoading && !isError ? (
<div className="absolute top-32 px-6 w-full">
<div className="text-center text-sm flex flex-col gap-y-1">
<p className="text-foreground">
{searchValue ? 'No secrets found' : 'No secrets added yet'}
</p>
<p className="text-foreground-light">
{searchValue
? `There are currently no secrets based on the search "${searchValue}"`
: 'The Vault allows you to store sensitive information like API keys'}
</p>
</div>
</div>
) : null}
</div>
</div>
<AddNewSecretModal
visible={showAddSecretModal}
onClose={() => setShowAddSecretModal(false)}
/>
{secretToEdit && (
<EditSecretModal
visible={!!secretToEdit}
secret={secretToEdit}
onClose={() => setSelectedSecretToEdit(null)}
/>
)}
<DeleteSecretModal
selectedSecret={secretToDelete}
onDeleteStart={(secretId) => {
deletingSecretIdRef.current = secretId
}}
onClose={() => {
deletingSecretIdRef.current = null
setSelectedSecretToRemove(null)
}}
/>
</>
)
}
Domain
Subdomains
Calls
Source
Frequently Asked Questions
What does SecretsManagement() do?
SecretsManagement() is a function in the supabase codebase.
What does SecretsManagement() call?
SecretsManagement() calls 1 function(s): formatSecretColumns.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free