Skip to content

feat(aurora-portal): implement three-zone DataGrid header for Object Storage (Swift)#915

Merged
TilmanHaupt merged 17 commits into
mainfrom
mark-swift-data-grid-header-toolbar
Jun 17, 2026
Merged

feat(aurora-portal): implement three-zone DataGrid header for Object Storage (Swift)#915
TilmanHaupt merged 17 commits into
mainfrom
mark-swift-data-grid-header-toolbar

Conversation

@mark-karnaukh-extern-sap

@mark-karnaukh-extern-sap mark-karnaukh-extern-sap commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Implements the three-zone toolbar and DataGrid layout for the Object Storage (Swift) container list view, following the pattern from Images/List.tsx.

What changed

Replaces the combined ListToolbar in SwiftContainers with the three-zone composition:

  • Zone 1 (plain Stack, no background): SortInput on the left, Create Container on the right.
  • Zone 2 (DataGridToolbar): SearchInput with the 500ms debounce pattern (localSearchTerm state + useRef timer), committing to the URL via the existing search param so sort/search survive navigation and deep links.
  • Zone 3 (DataGridToolbar): a select-all checkbox + an Actions popup whose item is Empty Container / Empty Containers (singular/plural by selection), alongside the existing container count + remaining-quota + limits info on the right.
    ContainerTableView now takes hasAnyBulkAction and drops the selection column (header select-all + per-row checkboxes, column count 6→5, grid template) when no bulk action is available; header and rows stay aligned in both modes.

Deviations from the spec (and why)

  • No FiltersInput / SelectedFilters in Zone 2. Swift containers expose no filterable dimensions today, so Zone 2 is search-only. A comment marks where FiltersInput + applyFilterSelection go once filter dimensions exist — rather than wiring filtering against fields that don't exist.
  • Zone 3 always renders (rather than only when canDelete || canUpdate). Unlike the Images reference, this bar also hosts the always-needed count/quota info, so the bar renders unconditionally and only the left-hand bulk controls are gated.
  • hasAnyBulkAction is hardcoded true with a TODO(perms). SwiftContainers has no permission source yet; this keeps current always-on behavior while putting the gating structure in place. canCreate / canDelete / canUpdate permission plumbing is deferred to a follow-up.
  • No FORBIDDEN → listError handling, since that pairs with the permissions source that doesn't exist here yet.

Testing

SwiftContainers and ContainerTableView tests updated for the new flow:

  • Bulk empty is driven through the Actions popup (select → enable Actions → open → Empty Container / Empty Containers) instead of a standalone Empty All (N) button.
  • hasAnyBulkAction=false renders no checkboxes while rows still appear; select-all / deselect-all and per-row checkbox setters verified.

Notes / follow-ups

  • Wire hasAnyBulkAction (and canCreate) to the real permission source when available; introduce FiltersInput if/when containers gain filter dimensions.

Checklist

  • I have performed a self-review of my code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have made corresponding changes to the documentation (if applicable).
  • My changes generate no new warnings or errors.

Summary by CodeRabbit

  • New Features
    • Added an Actions menu for bulk operations on containers and objects, enabling items only after selection.
    • Reworked the toolbar into separate sort/search/bulk-action zones, with debounced search syncing to the URL.
    • Added the ability to hide bulk-selection UI (including the selection column) when bulk actions aren’t available.
  • Bug Fixes
    • Modal titles now correctly switch between singular and plural based on item count.
  • Documentation
    • Updated localized strings for pluralized labels and search placeholders.
  • Tests
    • Expanded coverage for bulk-action flows, selection gating, and singular/plural title behavior.

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Replaces ListToolbar with a three-zone DataGridToolbar in both SwiftContainers and SwiftObjects. Adds a hasAnyBulkAction prop to ContainerTableView and ObjectsTableView to conditionally hide the selection column. Introduces debounced local search state, scoped select-all logic, and an Actions popup menu for bulk operations. Modal titles switch to singular/plural based on count, and locale files are updated accordingly.

Changes

DataGridToolbar bulk-actions refactor for Swift Containers & Objects

Layer / File(s) Summary
Singular/plural modal titles and locale updates
...Containers/EmptyContainersModal.tsx, ...Containers/EmptyContainersModal.test.tsx, ...Objects/DeleteObjectsModal.tsx, ...Objects/DeleteObjectsModal.test.tsx, src/locales/en/messages.po, src/locales/de/messages.po
EmptyContainersModal and DeleteObjectsModal import Lingui's Plural component and use it to render titles as singular ("Empty Container", "Delete Object") when totalCount === 1, otherwise plural. Tests verify singular and plural rendering with unmount/remount. Locale catalogs remove Delete All entries, add pluralized Empty Container/Delete Object entries keyed by selectedCount and totalCount, and add Search containers.../Search objects... placeholders for both English and German.
hasAnyBulkAction prop gating on ContainerTableView and ObjectsTableView
...Containers/ContainerTableView.tsx, ...Objects/ObjectsTableView.tsx, ...Objects/ObjectsTableView.test.tsx
Adds optional hasAnyBulkAction prop (default true) to both table view components. When false, the leading selection checkbox column is hidden by switching grid column templates and counts; header select-all and per-row checkbox cells are conditionally omitted. Test helper accepts hasAnyBulkAction parameter, and new test suite verifies checkboxes are hidden while row action menus remain usable when the prop is false.
SwiftContainers DataGridToolbar refactor and bulk-action wiring
...Containers/index.tsx, ...Containers/index.test.tsx
SwiftContainers replaces ListToolbar with multi-zone DataGridToolbar. Adds URL-backed search with local debounced state (500ms debounce) synced via effect, a hardcoded hasAnyBulkAction flag, and scoped select-all logic for currently displayed rows. Bulk-action popup menu (empty containers) is wired into Zone 3 with singular/plural labeling and gated by hasAnyBulkAction. Tests replace old "Empty All (N)" button assertions with Actions toggle menu flow, covering enabled/disabled states, label changes, modal interactions, success with selection/Actions reset, and error toasts.
SwiftObjects DataGridToolbar refactor and bulk-action wiring
...Objects/index.tsx, ...Objects/index.test.tsx
SwiftObjects replaces ListToolbar with Stack plus two DataGridToolbar sections. Adds hasAnyBulkAction constant (with permissions TODO), debounced localSearchTerm state with cleanup ref and synchronization effect, and scoped select-all for currently displayed selectable (non-folder) object rows. Bulk-action popup menu (delete objects) in Zone 3 includes singular/plural labeling and is gated by hasAnyBulkAction. Tests replace "Delete All (N)" button assertions with Actions menu flow, covering enabled/disabled states, label changes, modal open via menu item, success with selection/Actions reset, and error toasts.

Sequence Diagram(s)

sequenceDiagram
  actor User
  participant Zone1 as DataGridToolbar Zone 1
  participant Zone2 as DataGridToolbar Zone 2
  participant Zone3 as DataGridToolbar Zone 3
  participant TableView as ContainerTableView /<br/>ObjectsTableView
  participant BulkModal as EmptyContainersModal /<br/>DeleteObjectsModal

  User->>Zone2: types search query
  Zone2->>Zone2: debounce 500ms
  Zone2->>TableView: commit to URL searchParam
  User->>TableView: select row checkboxes
  TableView->>Zone3: selectedCount > 0 enables Actions toggle
  User->>Zone3: open Actions menu
  Zone3->>BulkModal: click "Empty Container(s)" /<br/>"Delete Object(s)"
  BulkModal-->>Zone3: success → clear selection,<br/>disable Actions, show toast
  BulkModal-->>Zone3: error → show error toast
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

  • cobaltcore-dev/aurora-dashboard#885: Both PRs introduce the same code-level pattern for conditionally hiding bulk-selection UI in DataGrid tables via a hasAnyBulkAction prop that removes the select-all header checkbox and per-row selection checkbox columns.

  • cobaltcore-dev/aurora-dashboard#738: Both PRs modify the same Swift bulk-selection plumbing for Containers/Objects—adding/updating checkbox "select all" and per-row selection behavior in ContainerTableView/ObjectsTableView and driving bulk empty/delete modals.

Suggested labels

enhancement

Suggested reviewers

  • andypf
  • TilmanHaupt
  • KirylSAP
  • vlad-schur-external-sap

Poem

🐇 Three zones now rule the toolbar land,
With debounce and sort close at hand.
Select all your rows, then open the door—
Bulk empty or delete, that's what Actions are for!
Singular or plural, the title knows right—
The rabbit hops on, all wired up tight. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: implementing a three-zone DataGrid header for Swift Object Storage, which aligns with the comprehensive refactoring across multiple container/object components.
Description check ✅ Passed The description follows the repository template with all major sections complete: Summary, What changed, Deviations from spec, Testing, and a filled Checklist; it provides thorough technical detail about the three-zone layout, component changes, and testing approach.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch mark-swift-data-grid-header-toolbar

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mark-karnaukh-extern-sap mark-karnaukh-extern-sap changed the title feat(object-storage): implement three-zone DataGrid header for Object Storage (Swift) feat(aurora-portal): implement three-zone DataGrid header for Object Storage (Swift) Jun 12, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/client/routes/_auth/projects/`$projectId/storage/-components/Swift/Containers/index.tsx:
- Around line 65-70: The localSearchTerm state is initialized from searchParam
but never synchronized when searchParam changes after initial render, causing
the search input UI to drift from the actual filter state. At
packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Containers/index.tsx
(lines 65-70), add a useEffect hook with searchParam as a dependency that calls
setLocalSearchTerm(searchParam) whenever the URL search parameter changes. Apply
the identical synchronization effect at
packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Objects/index.tsx
(lines 178-183) to keep both locations in sync.
🪄 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: fd0eb5b7-0bd2-40fc-9e88-6ebc504861c4

📥 Commits

Reviewing files that changed from the base of the PR and between 6bf0533 and 4573e44.

📒 Files selected for processing (15)
  • packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Containers/ContainerTableView.tsx
  • packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Containers/EmptyContainersModal.test.tsx
  • packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Containers/EmptyContainersModal.tsx
  • packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Containers/index.test.tsx
  • packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Containers/index.tsx
  • packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Objects/DeleteObjectsModal.test.tsx
  • packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Objects/DeleteObjectsModal.tsx
  • packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Objects/ObjectsTableView.test.tsx
  • packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Objects/ObjectsTableView.tsx
  • packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Objects/index.test.tsx
  • packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Objects/index.tsx
  • packages/aurora/src/locales/de/messages.po
  • packages/aurora/src/locales/de/messages.ts
  • packages/aurora/src/locales/en/messages.po
  • packages/aurora/src/locales/en/messages.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Swift Object Storage Containers (and Objects) list views to use the three-zone DataGrid header/toolbar layout (sort + primary actions, debounced search, bulk actions + info), and adjusts selection-column rendering to be gateable via a hasAnyBulkAction flag.

Changes:

  • Replaces the legacy combined ListToolbar with a three-zone composition for Swift Containers and Swift Objects, including a 500ms debounced search committed to URL search params.
  • Adds hasAnyBulkAction support to conditionally remove the selection column (header + per-row checkboxes) in both ContainerTableView and ObjectsTableView.
  • Updates bulk-action UX (Actions popup, singular/plural labeling) and related tests + i18n strings.

Reviewed changes

Copilot reviewed 13 out of 15 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/aurora/src/locales/en/messages.ts Regenerated Lingui message catalog to include new Swift toolbar strings.
packages/aurora/src/locales/en/messages.po Adds new msgids (search placeholders, “Empty Container”), removes unused “Delete All” strings.
packages/aurora/src/locales/de/messages.po German translations for newly added Swift toolbar strings.
packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Objects/ObjectsTableView.tsx Adds hasAnyBulkAction gating and adjusts grid column templates/count.
packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Objects/ObjectsTableView.test.tsx Tests for selection-column gating behavior.
packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Objects/index.tsx Implements three-zone toolbar for objects, debounced search, bulk Actions menu.
packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Objects/index.test.tsx Updates tests to drive bulk delete via Actions popup instead of a “Delete All (N)” button.
packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Objects/DeleteObjectsModal.tsx Makes modal title singular/plural based on selection count.
packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Objects/DeleteObjectsModal.test.tsx Adds coverage for singular vs plural modal titles.
packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Containers/index.tsx Implements three-zone toolbar for containers, debounced search, bulk Actions menu + info block.
packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Containers/index.test.tsx Updates tests to drive bulk empty via Actions popup instead of “Empty All (N)”.
packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Containers/EmptyContainersModal.tsx Makes modal title singular/plural based on selection count.
packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Containers/EmptyContainersModal.test.tsx Adds coverage for singular vs plural modal titles.
packages/aurora/src/client/routes/_auth/projects/$projectId/storage/-components/Swift/Containers/ContainerTableView.tsx Adds hasAnyBulkAction gating and adjusts grid column count/template.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

KirylSAP
KirylSAP previously approved these changes Jun 15, 2026
andypf
andypf previously approved these changes Jun 15, 2026
@TilmanHaupt TilmanHaupt added the pr-build Triggers Docker image build for PR preview push image to GHCR. label Jun 16, 2026
TilmanHaupt
TilmanHaupt previously approved these changes Jun 16, 2026

@andypf andypf left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@TilmanHaupt TilmanHaupt merged commit 9b00ac4 into main Jun 17, 2026
21 checks passed
@TilmanHaupt TilmanHaupt deleted the mark-swift-data-grid-header-toolbar branch June 17, 2026 07:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

aurora-portal object storage pr-build Triggers Docker image build for PR preview push image to GHCR. swift ux improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Task](portal): Implement DataGrid Header for Object Storage (Swift)

6 participants