feat(aurora-portal): ceph versioning ui#879
Conversation
📝 WalkthroughWalkthroughAdds Ceph bucket versioning end‑to‑end: server schema/router support for create-time versioning and S3 error classification; client UI for enable/suspend, version history, restore/delete; credential/error UX updates; tests and EN/DE localization strings. ChangesCeph Object Versioning
Sequence Diagram(s)sequenceDiagram
participant Client as Client UI
participant TRPC as trpcReact
participant Server as Aurora Server (ceph router)
participant Ceph as Ceph S3 Backend
Client->>TRPC: call storage.ceph.containers.create(enableVersioning)
TRPC->>Server: forward create request
Server->>Ceph: CreateBucketCommand
Server->>Ceph: PutBucketVersioningCommand (if requested)
Ceph-->>Server: result / error
Server-->>TRPC: CreateBucketOutput (success + optional versioningError)
TRPC-->>Client: mutation result
Client->>TRPC: invalidate versioning.getStatus / objects.list on success
TRPC->>Client: cache invalidated (UI refetch)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/aurora/src/locales/de/messages.po (1)
4-4:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winRemove duplicated PO header key.
POT-Creation-Dateis duplicated in the header. Keep a single entry to avoid malformed/ambiguous metadata in translation tooling.Suggested fix
"POT-Creation-Date: 2026-04-27 16:27+0200\n" -"POT-Creation-Date: 2026-04-27 16:27+0200\n" "MIME-Version: 1.0\n"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/aurora/src/locales/de/messages.po` at line 4, Remove the duplicated PO header key "POT-Creation-Date" in the messages.po header block so only a single "POT-Creation-Date" entry remains; locate the header block in packages/aurora/src/locales/de/messages.po, delete the redundant "POT-Creation-Date: 2026-04-27 16:27+0200\n" line, and ensure the remaining header entry preserves correct PO header formatting and trailing newline.
🧹 Nitpick comments (4)
packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/index.tsx (1)
206-206: ⚡ Quick winHard page reload may degrade user experience.
window.location.reload()triggers a full page refresh, which discards all React state and forces the user to wait for the entire app to reload. The CredentialPrompt component in ContainerListView.tsx (line 69) usesrefetch()instead, which is a better pattern. Consider using the same approach here for consistency.♻️ Proposed fix using refetch
// Check if this is a NO_CEPH_CREDENTIALS error if (errorMessage === "NO_CEPH_CREDENTIALS") { - return <CredentialPrompt onSuccess={() => window.location.reload()} /> + return <CredentialPrompt onSuccess={() => refetch()} /> }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/aurora/src/client/routes/_auth/projects/`$projectId/storage/-components/Ceph/Containers/index.tsx at line 206, Replace the hard reload in the CredentialPrompt usage with a call to the component query refetch to preserve React state: instead of onSuccess={() => window.location.reload()} in Containers/index.tsx, wire up the existing refetch function (the same pattern used in ContainerListView.tsx) so onSuccess invokes refetch(); if refetch isn't in scope, pass it down from the parent or adjust CredentialPrompt's props to accept a callback (e.g., onSuccessRefetch) and call that to trigger refetch(). Ensure the prop name matches the CredentialPrompt signature and update any callers accordingly.packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/ContainerListView.tsx (1)
73-74: Use TRPC error codes instead of parsingerror.messagesubstrings.
ContainerListView.tsxsetsisAccessDenied/isAuthErrorviaerrorMessage.includes(...), which is brittle to message wording changes. The Storage backend already maps S3 errorCode/nameto structuredTRPCError.code(e.g.,AccessDenied→FORBIDDEN,InvalidAccessKeyId→UNAUTHORIZEDinpackages/aurora/src/server/Storage/helpers/s3ErrorMapper.ts). Branch on the structured TRPC client error (e.g.,error instanceof TRPCClientErrorand itsdata?.code) instead of matchingerror.message.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/aurora/src/client/routes/_auth/projects/`$projectId/storage/-components/Ceph/Containers/ContainerListView.tsx around lines 73 - 74, Replace the brittle substring checks for error messages in ContainerListView.tsx (the isAccessDenied / isAuthError logic) with structured TRPC client error checks: detect TRPCClientError (import from `@trpc/client`) and branch on error.data?.code === 'FORBIDDEN' for access denied and error.data?.code === 'UNAUTHORIZED' for invalid credentials (fall back to existing logic only if error is not a TRPCClientError). Update the boolean assignments to use these checks so they reflect the server-mapped TRPCError codes instead of inspecting error.message.packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectVersionHistoryModal.tsx (2)
244-252: ⚡ Quick winRemove
setTimeoutworkaround for query invalidation.The 100ms
setTimeoutbeforerefetch()appears to work around a perceived timing issue, butinvalidate()already triggers a refetch for active queries. The arbitrary delay is a code smell that could mask a real race condition or simply add unnecessary latency.♻️ Proposed cleanup
Remove the
setTimeoutcalls and rely on the invalidation thatRestoreVersionModalandDeleteVersionModalalready perform:onSuccess={(objectKey, versionId) => { setRestoreTarget(null) onRestoreVersion?.(objectKey, versionId) - // Invalidate is handled by RestoreVersionModal, but we refetch to ensure immediate update - setTimeout(() => refetch(), 100) }}onSuccess={(objectKey, versionId) => { setDeleteTarget(null) onDeleteVersion?.(objectKey, versionId) - // Invalidate is handled by DeleteVersionModal, but we refetch to ensure immediate update - setTimeout(() => refetch(), 100) }}The child modals'
invalidate()calls will automatically trigger a refetch since this query is active.Also applies to: 264-272
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/aurora/src/client/routes/_auth/projects/`$projectId/storage/-components/Ceph/Objects/ObjectVersionHistoryModal.tsx around lines 244 - 252, Remove the 100ms setTimeout workaround and call refetch() directly after clearing state; specifically, in the onSuccess handler that currently does setRestoreTarget(null); onRestoreVersion?.(objectKey, versionId); setTimeout(() => refetch(), 100), replace the delayed refetch with an immediate refetch (i.e., call refetch() right after invoking onRestoreVersion) and do the same for the equivalent block used with DeleteVersionModal, relying on RestoreVersionModal/DeleteVersionModal's invalidate() to trigger proper query refreshes.
68-72: ⚡ Quick winRemove redundant refetch in
useEffect.The query is configured with
staleTime: 0(line 63), so React Query will automatically fetch when the query becomes enabled (whenisOpenchanges totrue). TheuseEffectthat callsrefetch()triggers a second, unnecessary fetch.♻️ Proposed cleanup
- // Refetch when modal opens - useEffect(() => { - if (isOpen && projectId && bucketName && objectKey) { - refetch() - } - }, [isOpen, projectId, bucketName, objectKey, refetch]) - // data is already ObjectVersion[] array const versions = data || []The query's
enabledcondition already handles refetching when the modal opens.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/aurora/src/client/routes/_auth/projects/`$projectId/storage/-components/Ceph/Objects/ObjectVersionHistoryModal.tsx around lines 68 - 72, The useEffect that calls refetch() is redundant because the React Query for this component is configured with staleTime: 0 and its enabled condition already causes a fetch when isOpen toggles; remove the entire useEffect block (the useEffect referencing isOpen, projectId, bucketName, objectKey, refetch) so that the query's enabled logic handles fetching automatically and avoid the duplicate network request.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@packages/aurora/src/client/routes/_auth/projects/`$projectId/storage/-components/Ceph/Objects/ObjectVersionHistoryModal.tsx:
- Line 141: The component currently infers latest version with "const isLatest =
index === 0" in ObjectVersionHistoryModal.tsx; change this to use the
server-provided flag on the version object (e.g., replace the index check with
"version.isLatest") so the UI relies on the authoritative ObjectVersion.isLatest
field rather than list ordering; update any downstream uses of isLatest in the
component to read from version.isLatest and remove dependence on the index-based
logic.
- Around line 147-159: In ObjectVersionHistoryModal (the JSX that renders the
Badge using isLatest and isDeleteMarker) change the conditional so
isDeleteMarker is checked first rather than after isLatest; update the rendering
logic to display the "Delete Marker" Badge when isDeleteMarker is true,
otherwise show "Latest" when isLatest is true, otherwise show "Older"—this
ensures delete-marker badges take precedence over latest badges.
In `@packages/aurora/src/locales/de/messages.po`:
- Around line 115-117: Several msgid entries (e.g., "⚠️ Warning: Irreversible
Action" and the other untranslated entries listed) in the German .po locale are
left with empty msgstr values and must be filled with proper German
translations; open the German messages.po and provide accurate German msgstr
translations for the referenced msgid keys (including the ranges at 166-168,
334-336, 1057-1062, 1849-1851, 2233-2235, 3160-3162, 3304-3333, 3445-3450),
preserving punctuation and any emojis/formatting, and ensure each msgstr is
non-empty and context-appropriate for versioning/auth/destructive confirmation
flows.
In `@packages/aurora/src/server/Storage/helpers/s3ErrorMapper.ts`:
- Around line 60-65: Update the s3 error mapping so all auth-related S3
errorCodes produce the same normalized auth message used for InvalidAccessKeyId:
when errorCode is one of "SignatureDoesNotMatch", "TokenRefreshRequired",
"RequestTimeTooSkewed" (in addition to "InvalidAccessKeyId" and "AccessDenied")
push the auth-specific text into parts (the same text you use for
InvalidAccessKeyId) and ensure the overall mapped status remains UNAUTHORIZED;
modify the conditional around errorCode in s3ErrorMapper (the branch that
currently checks "AccessDenied" / "InvalidAccessKeyId") to include these
additional codes so the UI auth-error branch sees a consistent message.
In `@packages/aurora/src/server/Storage/routers/ceph/containerRouter.ts`:
- Around line 163-173: The bucket creation flow currently treats any error from
the subsequent PutBucketVersioningCommand as a full failure and throws a "create
bucket" error; change the code around the s3.send calls (CreateBucketCommand and
PutBucketVersioningCommand) so that CreateBucketCommand errors still throw, but
errors from PutBucketVersioningCommand are caught and handled as
partial-success: catch exceptions from PutBucketVersioningCommand (where
enableVersioning is true), log/warn the error with context via the existing
logger, and return or resolve the successful bucket-creation response while
including a flag or message (e.g., versioningFailed or versioningError) in the
result so callers know versioning didn’t apply instead of throwing a
create-bucket error; ensure you reference the same s3.send usage and keep
CreateBucketCommand behavior unchanged.
---
Outside diff comments:
In `@packages/aurora/src/locales/de/messages.po`:
- Line 4: Remove the duplicated PO header key "POT-Creation-Date" in the
messages.po header block so only a single "POT-Creation-Date" entry remains;
locate the header block in packages/aurora/src/locales/de/messages.po, delete
the redundant "POT-Creation-Date: 2026-04-27 16:27+0200\n" line, and ensure the
remaining header entry preserves correct PO header formatting and trailing
newline.
---
Nitpick comments:
In
`@packages/aurora/src/client/routes/_auth/projects/`$projectId/storage/-components/Ceph/Containers/ContainerListView.tsx:
- Around line 73-74: Replace the brittle substring checks for error messages in
ContainerListView.tsx (the isAccessDenied / isAuthError logic) with structured
TRPC client error checks: detect TRPCClientError (import from `@trpc/client`) and
branch on error.data?.code === 'FORBIDDEN' for access denied and
error.data?.code === 'UNAUTHORIZED' for invalid credentials (fall back to
existing logic only if error is not a TRPCClientError). Update the boolean
assignments to use these checks so they reflect the server-mapped TRPCError
codes instead of inspecting error.message.
In
`@packages/aurora/src/client/routes/_auth/projects/`$projectId/storage/-components/Ceph/Containers/index.tsx:
- Line 206: Replace the hard reload in the CredentialPrompt usage with a call to
the component query refetch to preserve React state: instead of onSuccess={() =>
window.location.reload()} in Containers/index.tsx, wire up the existing refetch
function (the same pattern used in ContainerListView.tsx) so onSuccess invokes
refetch(); if refetch isn't in scope, pass it down from the parent or adjust
CredentialPrompt's props to accept a callback (e.g., onSuccessRefetch) and call
that to trigger refetch(). Ensure the prop name matches the CredentialPrompt
signature and update any callers accordingly.
In
`@packages/aurora/src/client/routes/_auth/projects/`$projectId/storage/-components/Ceph/Objects/ObjectVersionHistoryModal.tsx:
- Around line 244-252: Remove the 100ms setTimeout workaround and call refetch()
directly after clearing state; specifically, in the onSuccess handler that
currently does setRestoreTarget(null); onRestoreVersion?.(objectKey, versionId);
setTimeout(() => refetch(), 100), replace the delayed refetch with an immediate
refetch (i.e., call refetch() right after invoking onRestoreVersion) and do the
same for the equivalent block used with DeleteVersionModal, relying on
RestoreVersionModal/DeleteVersionModal's invalidate() to trigger proper query
refreshes.
- Around line 68-72: The useEffect that calls refetch() is redundant because the
React Query for this component is configured with staleTime: 0 and its enabled
condition already causes a fetch when isOpen toggles; remove the entire
useEffect block (the useEffect referencing isOpen, projectId, bucketName,
objectKey, refetch) so that the query's enabled logic handles fetching
automatically and avoid the duplicate network request.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 23b1eafd-14c7-4dce-87fc-9197a8be290e
📒 Files selected for processing (20)
packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/ContainerListView.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/CreateBucketModal.test.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/CreateBucketModal.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/CredentialPrompt.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/EnableVersioningModal.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/SuspendVersioningModal.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/index.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/DeleteVersionModal.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectBrowserView.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectVersionHistoryModal.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectsTableView.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/RestoreVersionModal.tsxpackages/aurora/src/locales/de/messages.popackages/aurora/src/locales/de/messages.tspackages/aurora/src/locales/en/messages.popackages/aurora/src/locales/en/messages.tspackages/aurora/src/server/Storage/cephProcedure.tspackages/aurora/src/server/Storage/helpers/s3ErrorMapper.tspackages/aurora/src/server/Storage/routers/ceph/containerRouter.tspackages/aurora/src/server/Storage/types/ceph.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/aurora/src/server/Storage/helpers/s3ErrorMapper.test.ts`:
- Around line 276-278: The test's regex for the error message is too permissive
and should assert the full explanatory text appended by the s3 error mapper;
update the expectation in s3ErrorMapper.test (the assertion that uses
TEST_BUCKET and TEST_KEY) to match the complete string "Failed to delete object
— bucket: ${TEST_BUCKET} — key: ${TEST_KEY} — Access denied — your credentials
are valid but lack permissions for this operation" (or an equivalent regex
anchored to include that full trailing explanation) so it fails if the detailed
message is removed or changed.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: cd7746c1-53b7-47c6-b085-88ab9be0c473
📒 Files selected for processing (9)
packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/ContainerListView.test.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/CredentialPrompt.test.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectBrowserView.test.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectsTableView.test.tsxpackages/aurora/src/locales/de/messages.popackages/aurora/src/locales/de/messages.tspackages/aurora/src/locales/en/messages.popackages/aurora/src/locales/en/messages.tspackages/aurora/src/server/Storage/helpers/s3ErrorMapper.test.ts
✅ Files skipped from review due to trivial changes (2)
- packages/aurora/src/locales/de/messages.po
- packages/aurora/src/locales/en/messages.po
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@packages/aurora/src/client/routes/_auth/projects/`$projectId/storage/-components/Ceph/Objects/ObjectsTableView.tsx:
- Line 210: ObjectsTableView uses non-disjoint keys (key={isFolder ? row.prefix
: row.key}), which can collide when a folder prefix equals an object key; update
the key generation to make folder vs object keys unique (e.g. prefix with
distinct discriminator strings) by changing the key expression that references
isFolder, row.prefix and row.key to include a marker like "folder-" vs "object-"
so folder rows and object rows cannot share the same React key.
- Around line 115-120: The effect inside the ObjectsTableView component
currently recalculates scrollbar width only when rows.length changes (useEffect
around setScrollbarWidth), which causes header misalignment on viewport or
container resizes; replace this with a ResizeObserver on parentRef (or listen to
window resize) that recomputes const width = parentRef.current.offsetWidth -
parentRef.current.clientWidth and calls setScrollbarWidth, and ensure you
disconnect/cleanup the ResizeObserver in the effect cleanup to avoid leaks.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 93915abf-09d5-4c96-b844-6835dde6c6ca
📒 Files selected for processing (18)
.changeset/thirty-apes-look.mdpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/CreateBucketModal.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/CredentialPrompt.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/index.test.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/index.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectBrowserView.test.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectBrowserView.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectVersionHistoryModal.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectsTableView.test.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectsTableView.tsxpackages/aurora/src/locales/de/messages.popackages/aurora/src/locales/de/messages.tspackages/aurora/src/locales/en/messages.popackages/aurora/src/locales/en/messages.tspackages/aurora/src/server/Storage/helpers/s3ErrorMapper.test.tspackages/aurora/src/server/Storage/helpers/s3ErrorMapper.tspackages/aurora/src/server/Storage/routers/ceph/containerRouter.tspackages/aurora/src/server/Storage/types/ceph.ts
✅ Files skipped from review due to trivial changes (3)
- .changeset/thirty-apes-look.md
- packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/CredentialPrompt.tsx
- packages/aurora/src/locales/en/messages.po
🚧 Files skipped from review as they are similar to previous changes (8)
- packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectsTableView.test.tsx
- packages/aurora/src/server/Storage/helpers/s3ErrorMapper.ts
- packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/index.tsx
- packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/CreateBucketModal.tsx
- packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectBrowserView.test.tsx
- packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectBrowserView.tsx
- packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectVersionHistoryModal.tsx
- packages/aurora/src/locales/de/messages.po
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@packages/aurora/src/client/routes/_auth/projects/`$projectId/storage/-components/Ceph/Objects/ObjectsTableView.tsx:
- Line 210: ObjectsTableView uses non-disjoint keys (key={isFolder ? row.prefix
: row.key}), which can collide when a folder prefix equals an object key; update
the key generation to make folder vs object keys unique (e.g. prefix with
distinct discriminator strings) by changing the key expression that references
isFolder, row.prefix and row.key to include a marker like "folder-" vs "object-"
so folder rows and object rows cannot share the same React key.
- Around line 115-120: The effect inside the ObjectsTableView component
currently recalculates scrollbar width only when rows.length changes (useEffect
around setScrollbarWidth), which causes header misalignment on viewport or
container resizes; replace this with a ResizeObserver on parentRef (or listen to
window resize) that recomputes const width = parentRef.current.offsetWidth -
parentRef.current.clientWidth and calls setScrollbarWidth, and ensure you
disconnect/cleanup the ResizeObserver in the effect cleanup to avoid leaks.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 93915abf-09d5-4c96-b844-6835dde6c6ca
📒 Files selected for processing (18)
.changeset/thirty-apes-look.mdpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/CreateBucketModal.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/CredentialPrompt.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/index.test.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/index.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectBrowserView.test.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectBrowserView.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectVersionHistoryModal.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectsTableView.test.tsxpackages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectsTableView.tsxpackages/aurora/src/locales/de/messages.popackages/aurora/src/locales/de/messages.tspackages/aurora/src/locales/en/messages.popackages/aurora/src/locales/en/messages.tspackages/aurora/src/server/Storage/helpers/s3ErrorMapper.test.tspackages/aurora/src/server/Storage/helpers/s3ErrorMapper.tspackages/aurora/src/server/Storage/routers/ceph/containerRouter.tspackages/aurora/src/server/Storage/types/ceph.ts
✅ Files skipped from review due to trivial changes (3)
- .changeset/thirty-apes-look.md
- packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/CredentialPrompt.tsx
- packages/aurora/src/locales/en/messages.po
🚧 Files skipped from review as they are similar to previous changes (8)
- packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectsTableView.test.tsx
- packages/aurora/src/server/Storage/helpers/s3ErrorMapper.ts
- packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/index.tsx
- packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Containers/CreateBucketModal.tsx
- packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectBrowserView.test.tsx
- packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectBrowserView.tsx
- packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectVersionHistoryModal.tsx
- packages/aurora/src/locales/de/messages.po
🛑 Comments failed to post (2)
packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Ceph/Objects/ObjectsTableView.tsx (2)
115-120:
⚠️ Potential issue | 🟡 Minor | ⚡ Quick winRecompute scrollbar width on container resize, not only row-count changes.
Line 120 only reacts to
rows.length, so header alignment can drift after viewport/layout resize while row count is unchanged.Proposed fix
- useEffect(() => { - if (parentRef.current) { - const width = parentRef.current.offsetWidth - parentRef.current.clientWidth - setScrollbarWidth(width) - } - }, [rows.length]) + useEffect(() => { + const el = parentRef.current + if (!el) return + + const update = () => setScrollbarWidth(el.offsetWidth - el.clientWidth) + update() + + const ro = new ResizeObserver(update) + ro.observe(el) + window.addEventListener("resize", update) + return () => { + ro.disconnect() + window.removeEventListener("resize", update) + } + }, [rows.length])📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.useEffect(() => { const el = parentRef.current if (!el) return const update = () => setScrollbarWidth(el.offsetWidth - el.clientWidth) update() const ro = new ResizeObserver(update) ro.observe(el) window.addEventListener("resize", update) return () => { ro.disconnect() window.removeEventListener("resize", update) } }, [rows.length])🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/aurora/src/client/routes/_auth/projects/`$projectId/storage/-components/Ceph/Objects/ObjectsTableView.tsx around lines 115 - 120, The effect inside the ObjectsTableView component currently recalculates scrollbar width only when rows.length changes (useEffect around setScrollbarWidth), which causes header misalignment on viewport or container resizes; replace this with a ResizeObserver on parentRef (or listen to window resize) that recomputes const width = parentRef.current.offsetWidth - parentRef.current.clientWidth and calls setScrollbarWidth, and ensure you disconnect/cleanup the ResizeObserver in the effect cleanup to avoid leaks.
210-210:
⚠️ Potential issue | 🟠 Major | ⚡ Quick winUse disjoint React keys for folder vs object rows.
Line 210 can produce duplicate keys when a folder prefix and an object key are the same string (valid in S3/Ceph), which can mis-bind virtualized row rendering/actions.
Proposed fix
- key={isFolder ? row.prefix : row.key} + key={isFolder ? `folder:${row.prefix}` : `object:${row.key}`}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/aurora/src/client/routes/_auth/projects/`$projectId/storage/-components/Ceph/Objects/ObjectsTableView.tsx at line 210, ObjectsTableView uses non-disjoint keys (key={isFolder ? row.prefix : row.key}), which can collide when a folder prefix equals an object key; update the key generation to make folder vs object keys unique (e.g. prefix with distinct discriminator strings) by changing the key expression that references isFolder, row.prefix and row.key to include a marker like "folder-" vs "object-" so folder rows and object rows cannot share the same React key.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
packages/aurora/src/locales/de/messages.po (1)
3238-3239:⚠️ Potential issue | 🟠 Major | ⚡ Quick winComplete German translations before release (duplicate concern).
This newly added entry
"Unknown domain"is untranslated (msgstr ""), continuing the pattern already flagged in the previous review. As noted earlier, user-critical strings must have German translations to avoid breaking the localized experience for the versioning and authentication flows.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/aurora/src/locales/de/messages.po` around lines 3238 - 3239, The PO entry for msgid "Unknown domain" is untranslated (msgstr ""), so update the msgstr for that msgid with the correct German translation (e.g., "Unbekannte Domain" or the appropriate localized phrasing) in the same file and ensure the string matches project tone/capitalization; after editing the msgstr, run your PO linter/validation (or msgfmt) to confirm no syntax errors and that the translation appears in the compiled locale resources used by the authentication/versioning flows.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@packages/aurora/src/locales/de/messages.po`:
- Around line 3238-3239: The PO entry for msgid "Unknown domain" is untranslated
(msgstr ""), so update the msgstr for that msgid with the correct German
translation (e.g., "Unbekannte Domain" or the appropriate localized phrasing) in
the same file and ensure the string matches project tone/capitalization; after
editing the msgstr, run your PO linter/validation (or msgfmt) to confirm no
syntax errors and that the translation appears in the compiled locale resources
used by the authentication/versioning flows.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: bda74011-a36f-461c-9a7e-8e23b90858be
📒 Files selected for processing (4)
packages/aurora/src/locales/de/messages.popackages/aurora/src/locales/de/messages.tspackages/aurora/src/locales/en/messages.popackages/aurora/src/locales/en/messages.ts
✅ Files skipped from review due to trivial changes (1)
- packages/aurora/src/locales/en/messages.po
Summary
This PR implements the complete UI for S3 bucket versioning feature. It allows users to enable/suspend versioning, view version history, restore previous versions, and permanently delete specific versions. The BFF layer was implemented in a previous PR.
Changes Made
Bucket Creation
CreateBucketModalto enable versioning during bucket creationcreateBucketInputSchemato acceptenableVersioningboolean flagPutBucketVersioningCommandafter bucket creation if flag is trueBucket View
Versioning Modals
Version History
Version Operations
Implementation Details
ObjectVersioninterface from server typesRelated Issues
Screenshots (if applicable)
See screenshots in task description showing:
Testing Instructions
pnpm iChecklist
Summary by CodeRabbit