From 2a78a8075ed54aac47e5e8945079bd0c9ad92ea1 Mon Sep 17 00:00:00 2001 From: Zhengchao An Date: Sat, 18 Jul 2026 10:40:34 +0800 Subject: [PATCH] fix: restore replication and KMS actions (#171) --- app/(dashboard)/site-replication/page.tsx | 41 ++++++++++++----------- app/(dashboard)/sse/page.tsx | 3 +- components/buckets/replication-tab.tsx | 7 +--- tests/lib/bucket-settings-safety.test.js | 3 +- tests/lib/site-replication-tls.test.js | 7 ++++ tests/lib/sse-safety.test.js | 2 ++ 6 files changed, 36 insertions(+), 27 deletions(-) diff --git a/app/(dashboard)/site-replication/page.tsx b/app/(dashboard)/site-replication/page.tsx index 7ab54c8..c86d650 100644 --- a/app/(dashboard)/site-replication/page.tsx +++ b/app/(dashboard)/site-replication/page.tsx @@ -25,6 +25,7 @@ import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle } import { DropdownMenu, DropdownMenuContent, + DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, @@ -376,25 +377,27 @@ export default function SiteReplicationPage() { } /> - {peer.name || t("Peer site")} - {canManageSites ? ( - setEditingPeer(peer)}> - - {t("Edit Site")} - - ) : null} - {canResyncSites ? ( - void handleResync(peer, "start")}> - - {t("Start Resync")} - - ) : null} - {canResyncSites ? ( - void handleResync(peer, "cancel")}> - - {t("Cancel Resync")} - - ) : null} + + {peer.name || t("Peer site")} + {canManageSites ? ( + setEditingPeer(peer)}> + + {t("Edit Site")} + + ) : null} + {canResyncSites ? ( + void handleResync(peer, "start")}> + + {t("Start Resync")} + + ) : null} + {canResyncSites ? ( + void handleResync(peer, "cancel")}> + + {t("Cancel Resync")} + + ) : null} + {canRemoveSites ? : null} {canRemoveSites ? ( confirmRemoveSite(peer)}> diff --git a/app/(dashboard)/sse/page.tsx b/app/(dashboard)/sse/page.tsx index 6a784e6..df6b542 100644 --- a/app/(dashboard)/sse/page.tsx +++ b/app/(dashboard)/sse/page.tsx @@ -905,7 +905,7 @@ export default function SSEPage() { const isPendingDefaultKey = pendingKeyAction?.key.key_id === status?.config_summary?.default_key_id const mutationLocked = Boolean(activeMutation || statusError || loadingStatus) - const localKmsReadOnly = formState.backendType === "local" + const localKmsReadOnly = hasConfiguration && formState.backendType === "local" const formDisabled = mutationLocked || loadingStatus || submittingConfig || localKmsReadOnly const mutationInFlight = Boolean(activeMutation || submittingConfig || creatingKey || processingKeyAction) const canSetCreatedKeyAsDefault = status?.backend_type !== "Local" && !isConfigDirty @@ -1079,6 +1079,7 @@ export default function SSEPage() { ) : null}
{ event.preventDefault() void submitConfiguration() diff --git a/components/buckets/replication-tab.tsx b/components/buckets/replication-tab.tsx index 78a051f..5b1f87c 100644 --- a/components/buckets/replication-tab.tsx +++ b/components/buckets/replication-tab.tsx @@ -101,12 +101,7 @@ export function BucketReplicationTab({ bucketName, hideTitle = false, renderHead Rules: remaining, }) } - if ( - remaining.length > 0 && - !role && - targetArn && - !remaining.some((item) => item.Destination?.Bucket === targetArn) - ) { + if (!role && targetArn && !remaining.some((item) => item.Destination?.Bucket === targetArn)) { try { await deleteRemoteReplicationTarget(bucketName, targetArn) } catch (cleanupError) { diff --git a/tests/lib/bucket-settings-safety.test.js b/tests/lib/bucket-settings-safety.test.js index 6130a74..fc5d875 100644 --- a/tests/lib/bucket-settings-safety.test.js +++ b/tests/lib/bucket-settings-safety.test.js @@ -215,7 +215,8 @@ test("replication creation rereads rules and never removes an uncertain remote t assert.match(replicationFormSource, /normalizeReplicationRulesForRolelessConfig/) assert.match(replicationFormSource, /Role: ""/) assert.match(replicationTabSource, /Role: role/) - assert.match(replicationTabSource, /remaining\.length > 0 &&[\s\S]{0,80}!role &&/) + assert.match(replicationTabSource, /if \(\s*!role &&[\s\S]{0,120}!remaining\.some/) + assert.doesNotMatch(replicationTabSource, /remaining\.length > 0 &&[\s\S]{0,80}!role &&/) assert.doesNotMatch(replicationTabSource, /Replication configuration Role is missing/) }) diff --git a/tests/lib/site-replication-tls.test.js b/tests/lib/site-replication-tls.test.js index 23dcc72..cb88e39 100644 --- a/tests/lib/site-replication-tls.test.js +++ b/tests/lib/site-replication-tls.test.js @@ -63,3 +63,10 @@ test("site replication overview reports each peer TLS trust mode", async () => { assert.match(source, /formatTlsVerification/) assert.match(source, /TLS Verification/) }) + +test("site replication action labels stay inside a Base UI menu group", async () => { + const source = await readFile(new URL("../../app/(dashboard)/site-replication/page.tsx", import.meta.url), "utf8") + + assert.match(source, /DropdownMenuGroup/) + assert.match(source, /[\s\S]*?[\s\S]*?<\/DropdownMenuGroup>/) +}) diff --git a/tests/lib/sse-safety.test.js b/tests/lib/sse-safety.test.js index 055b531..976a742 100644 --- a/tests/lib/sse-safety.test.js +++ b/tests/lib/sse-safety.test.js @@ -51,6 +51,7 @@ test("default-key creation uses a safe status baseline and clears secrets after test("Local KMS cannot be reconfigured until the backend supports safe secret rotation", () => { assert.match(source, /backendType: "vault-transit"/) + assert.match(source, /const localKmsReadOnly = hasConfiguration && formState\.backendType === "local"/) assert.match( source, /Local filesystem KMS configuration is read-only in Console until safe master-key rotation is available\./, @@ -61,6 +62,7 @@ test("Local KMS cannot be reconfigured until the backend supports safe secret ro }) test("SSE form and dialogs stay reachable on narrow screens", () => { + assert.match(source, //) assert.match(source, /grid-rows-\[auto_minmax\(0,1fr\)_auto\]/) assert.match(source, /md:hidden/)