From 2cb24f06b021bd80f4cd5444a1a3b91ec3ccf7fd Mon Sep 17 00:00:00 2001
From: Danny White <3104761+dnywh@users.noreply.github.com>
Date: Tue, 18 Aug 2026 12:42:22 +1000
Subject: [PATCH] polish privatelink delete flow and list attention copy
---
.../AWSPrivateLink.utils.test.ts | 5 +-
.../AWSPrivateLink/AWSPrivateLink.utils.ts | 15 +++---
.../AWSPrivateLinkAttentionAdmonition.tsx | 2 +-
.../AWSPrivateLink/AWSPrivateLinkSection.tsx | 54 ++++++++++++-------
4 files changed, 45 insertions(+), 31 deletions(-)
diff --git a/apps/studio/components/interfaces/Settings/Integrations/AWSPrivateLink/AWSPrivateLink.utils.test.ts b/apps/studio/components/interfaces/Settings/Integrations/AWSPrivateLink/AWSPrivateLink.utils.test.ts
index 5e184b8399e..7327e65a5af 100644
--- a/apps/studio/components/interfaces/Settings/Integrations/AWSPrivateLink/AWSPrivateLink.utils.test.ts
+++ b/apps/studio/components/interfaces/Settings/Integrations/AWSPrivateLink/AWSPrivateLink.utils.test.ts
@@ -60,14 +60,15 @@ describe('getConnectionsAttentionCopy', () => {
const copy = getConnectionsAttentionCopy({ waitingCount: 1, expiredCount: 0 })
expect(copy?.type).toBe('warning')
expect(copy?.title).toBe('Waiting for the AWS account owner')
- expect(copy?.showAcceptLink).toBe(true)
+ expect(copy?.shouldShowAcceptLink).toBe(true)
})
it('uses destructive copy when only expired', () => {
const copy = getConnectionsAttentionCopy({ waitingCount: 0, expiredCount: 2 })
expect(copy?.type).toBe('destructive')
expect(copy?.title).toBe('Connection requests expired')
- expect(copy?.showAcceptLink).toBe(false)
+ expect(copy?.description).toBe('AWS can no longer accept the expired shares below.')
+ expect(copy?.shouldShowAcceptLink).toBe(false)
})
it('counts statuses from a list', () => {
diff --git a/apps/studio/components/interfaces/Settings/Integrations/AWSPrivateLink/AWSPrivateLink.utils.ts b/apps/studio/components/interfaces/Settings/Integrations/AWSPrivateLink/AWSPrivateLink.utils.ts
index 8820e95f287..a32db4a66d7 100644
--- a/apps/studio/components/interfaces/Settings/Integrations/AWSPrivateLink/AWSPrivateLink.utils.ts
+++ b/apps/studio/components/interfaces/Settings/Integrations/AWSPrivateLink/AWSPrivateLink.utils.ts
@@ -73,7 +73,7 @@ export function getConnectionsAttentionCopy(attention: ConnectionsAttention): {
type: 'warning' | 'destructive'
title: string
description: string
- showAcceptLink: boolean
+ shouldShowAcceptLink: boolean
} | null {
const { waitingCount, expiredCount } = attention
if (waitingCount === 0 && expiredCount === 0) return null
@@ -82,8 +82,8 @@ export function getConnectionsAttentionCopy(attention: ConnectionsAttention): {
return {
type: 'destructive',
title: expiredCount === 1 ? 'A connection request expired' : 'Connection requests expired',
- description: 'Add a new connection to try again. AWS can no longer accept this share.',
- showAcceptLink: false,
+ description: `AWS can no longer accept the expired share${expiredCount === 1 ? '' : 's'} below.`,
+ shouldShowAcceptLink: false,
}
}
@@ -91,9 +91,8 @@ export function getConnectionsAttentionCopy(attention: ConnectionsAttention): {
return {
type: 'warning',
title: 'Some connections need attention',
- description:
- 'Accept waiting resource shares in AWS within 12 hours. Expired requests need a new connection.',
- showAcceptLink: true,
+ description: `Accept the waiting resource share${waitingCount === 1 ? '' : 's'} in AWS within 12 hours.`,
+ shouldShowAcceptLink: true,
}
}
@@ -101,7 +100,7 @@ export function getConnectionsAttentionCopy(attention: ConnectionsAttention): {
type: 'warning',
title:
waitingCount === 1 ? 'Waiting for the AWS account owner' : 'Waiting for AWS account owners',
- description: 'Accept the resource share in AWS within 12 hours.',
- showAcceptLink: true,
+ description: `Accept the resource share${waitingCount === 1 ? '' : 's'} in AWS within 12 hours.`,
+ shouldShowAcceptLink: true,
}
}
diff --git a/apps/studio/components/interfaces/Settings/Integrations/AWSPrivateLink/AWSPrivateLinkAttentionAdmonition.tsx b/apps/studio/components/interfaces/Settings/Integrations/AWSPrivateLink/AWSPrivateLinkAttentionAdmonition.tsx
index 70e00e5c023..f2d4258d9fc 100644
--- a/apps/studio/components/interfaces/Settings/Integrations/AWSPrivateLink/AWSPrivateLinkAttentionAdmonition.tsx
+++ b/apps/studio/components/interfaces/Settings/Integrations/AWSPrivateLink/AWSPrivateLinkAttentionAdmonition.tsx
@@ -25,7 +25,7 @@ export function AWSPrivateLinkAttentionAdmonition({
description={copy.description}
className={className}
actions={
- copy.showAcceptLink && (
+ copy.shouldShowAcceptLink && (
} asChild>
{
const [showForm, setShowForm] = useState(false)
const [showDeleteModal, setShowDeleteModal] = useState(false)
- const { mutate: deleteAccount, isPending: isDeleting } = useAWSAccountDeleteMutation({
+ const { mutateAsync: deleteAccount, isPending: isDeleting } = useAWSAccountDeleteMutation({
onSuccess: () => {
toast.success('Connection will be deleted shortly')
setShowDeleteModal(false)
@@ -68,25 +69,34 @@ export const AWSPrivateLinkSection = () => {
setShowForm(true)
}
- const onConfirmDelete = () => {
- if (selectedAccount && project) {
- deleteAccount({
- projectRef: project.ref,
- awsAccountId: selectedAccount.aws_account_id,
- databaseIdentifier:
- selectedAccount.database_type === 'READ_REPLICA'
- ? selectedAccount.database_identifier
- : undefined,
- })
- }
+ const onConfirmDelete = async () => {
+ if (!selectedAccount || !project) return
+
+ await deleteAccount({
+ projectRef: project.ref,
+ awsAccountId: selectedAccount.aws_account_id,
+ databaseIdentifier:
+ selectedAccount.database_type === 'READ_REPLICA'
+ ? selectedAccount.database_identifier
+ : undefined,
+ })
}
- const deleteDatabaseCopy =
- selectedAccount?.database_type === 'READ_REPLICA'
- ? selectedAccount.database_identifier
- ? `the read replica (ID: ${formatDatabaseID(selectedAccount.database_identifier)})`
- : 'a read replica'
- : 'the primary database'
+ let deleteDatabaseCopy = 'the primary database'
+ if (selectedAccount?.database_type === 'READ_REPLICA') {
+ deleteDatabaseCopy = selectedAccount.database_identifier
+ ? `the read replica (ID: ${formatDatabaseID(selectedAccount.database_identifier)})`
+ : 'the read replica (ID: Unknown identifier)'
+ }
+
+ const deleteConnectionTitle = selectedAccount
+ ? getConnectionTitle({
+ account_name: selectedAccount.account_name,
+ aws_account_id: selectedAccount.aws_account_id,
+ })
+ : ''
+ const showDeleteConnectionId =
+ !!selectedAccount && deleteConnectionTitle === selectedAccount.aws_account_id
return (
<>
@@ -161,8 +171,12 @@ export const AWSPrivateLinkSection = () => {
Delete connection
This removes the PrivateLink connection for{' '}
- {selectedAccount?.aws_account_id} on{' '}
- {deleteDatabaseCopy}. Applications using this private path will lose access.
+ {showDeleteConnectionId ? (
+ {deleteConnectionTitle}
+ ) : (
+ deleteConnectionTitle
+ )}{' '}
+ on {deleteDatabaseCopy}. Applications using this private path will lose access.