Skip to content

feat(FR-2691): relocate /data header panels — Dashboard + host-capacity cell#6941

Open
ironAiken2 wants to merge 1 commit into04-21-feat_fr-2613_migrate_vfolder_trash_lifecycle_mutations_to_v2_graphql_apifrom
04-23-feat_fr-2691_relocate__data_header_panels_dashboard_host-capacity_cell
Open

feat(FR-2691): relocate /data header panels — Dashboard + host-capacity cell#6941
ironAiken2 wants to merge 1 commit into04-21-feat_fr-2613_migrate_vfolder_trash_lifecycle_mutations_to_v2_graphql_apifrom
04-23-feat_fr-2691_relocate__data_header_panels_dashboard_host-capacity_cell

Conversation

@ironAiken2
Copy link
Copy Markdown
Contributor

@ironAiken2 ironAiken2 commented Apr 23, 2026

resolves #6937 (FR-2691)

Summary

Clears the three header panels that used to sit above the folder table on /data, redistributes their responsibilities, and reshapes the "Location" column into a "Host" column that surfaces per-volume capacity info without requiring an extra click on every row.

Changes on /data (VFolderNodeListPage.tsx)

  • Removed the top Row that rendered the Create Folder action card, StorageStatusPanelCard, and QuotaPerStorageVolumePanelCard. The Create Folder affordance is already present as the primary button inside the folder table card header, so no replacement action card is needed.
  • Promoted the folder table card to the top of the page.
  • Cleaned up now-unused imports / variables (ActionItemContent, BAINewFolderIcon, BAIAlertIconWithTooltip, Grid.useBreakpoint, useWebUINavigate, ErrorBoundary, per-row Suspense, CARD_MIN_HEIGHT).

Changes in the folder table (VFolderNodesV2.tsx)

  • Column title: data.folders.Location (위치) → data.Host (호스트).
  • Column header affordance: a BAIAlertIconWithTooltip sits next to the "Host" label. Clicking it opens the QuotaPerStorageVolumePanelCard in a Modal, pre-selected on a quota-supporting host. The icon is hidden entirely when no volume reports "quota" in capabilities, so the modal entry point disappears when the feature is unusable — we don't open a dialog with no useful content.
  • Column cells: new VFolderHostCell renders a StorageUsageBadge (sourced from vfolder.list_hosts(), cached under the shared ['vhostInfo'] tan-query key that StorageSelect already uses) plus the host name. No per-cell click behavior — the modal is only reachable via the column-header affordance.
  • Badge gating matches StorageSelect's own precedent: the badge renders whenever the backend attaches a usage object (even {}). StorageUsageBadge resolves a percentage-less usage to a neutral (uncolored) marker. The accompanying tooltip reads Host Status: <Adequate | Caution | Insufficient | Unknown>; the Unknown label is a newly added key that covers the "backend reports no percentage" case.
  • Switched the cell from useSuspenseTanQuery to useTanQuery. A per-cell Suspense boundary whose fallback rendered the bare host text (visually indistinguishable from the "loaded but no usage data" branch) caused rows to stick in the fallback even after vhostInfo resolved.

Changes to QuotaPerStorageVolumePanelCard.tsx

  • Dropped the outer BAICard wrapper and the internal title. The consumer is now a Modal that supplies its own title and chrome, and a nested card here produced a duplicated header on top of the modal frame.
  • Moved the ? tooltip icon (QuestionCircleOutlined with data.HostDetails) into the Modal title so all header affordances live in one place.
  • StorageSelect moved out of the former card's extra slot (right-aligned, borderless) and into the modal body as the first element, left-aligned with a sensible minWidth.
  • Added defaultVolumeInfo?: VolumeInfo prop. When set, the card seeds selectedVolumeInfo with that value and disables the built-in autoSelectType="usage" fallback; users can still switch volumes through the inline StorageSelect. This is how the header icon pre-selects a quota-supporting host.
  • Props type simplified: BAICardProps → a dedicated local interface (card-specific passthrough props no longer make sense).

Changes on the Dashboard (DashboardPage.tsx, StorageStatusPanelCard.tsx)

  • Added a new folderStatus board item between myResourceWithinResourceGroup and totalResourceWithinResourceGroup, wrapped in BAIBoardItemErrorBoundary + Suspense. Invitation badge click routes to /data?invitation=true through useWebUINavigate.
  • Refactored StorageStatusPanelCard to follow the Dashboard board-item pattern used by MyResource / MyResourceWithinResourceGroup:
    • Root is a BAIFlex direction="column" align="stretch" with paddingInline: token.paddingXL and paddingBottom: token.padding.
    • Title uses the shared BAIBoardItemTitle, which reserves space for the board's drag handle. Wrapping in a BAICard caused the title to overlap the handle on the left edge — that's fixed.
    • Props type: BAICardPropsBAIFlexProps.

V2 migration notes (TODOs left in StorageStatusPanelCard.tsx)

The status counts still run off the legacy REST call baiClient.vfolder.list() and the V1 user_resource_policy / project_resource_policy GraphQL root fields. TODOs in the file call out the V2 rewrite with explicit scoping rules:

  • ProjectFolders: when ported to projectVfolders(projectId: …), it must be scoped to the project currently selected in the global header project selector (currentProject.id), not aggregated across every project the user can see.
  • InvitedFolders: migration deferred. The V2 VFolderFilter does not yet expose an "invited only / received share" predicate, so we cannot reproduce the current !is_owner && ownership_type === 'user' filter with a single server-side count. Stays on legacy REST until the backend adds the filter field; revisit in a follow-up issue.

Internationalization

Added data.usage.Unknown to all 21 locales under resources/i18n/, placed alphabetically between StatusOfSelectedHost and Used in the data.usage object. The key powers the tooltip fallback when a host has usage: {} (object present, percentage missing). packages/backend.ai-ui/src/locale/*.json is intentionally untouched — that package does not consume the key.

Testing

  • bash scripts/verify.sh — Relay, Lint, Format, TypeScript all pass on this branch and on every descendant branch in the stack (FR-2573, FR-2619, FR-2685, FR-2688).
  • Manually verified against a manager response where every volume reports usage: {} (no percentage): per-row neutral badges render with Host Status: Unknown tooltip; header ? icon appears because icn02:flash01 / seoul-h100:flash0* advertise "quota" in capabilities; clicking it opens the modal pre-selected on the first quota-capable host.

Checklist: (if applicable)

  • Documentation
  • Minimum required manager version
  • Specific setting for review (eg., KB link, endpoint or how to setup)
  • Minimum requirements to check during review
  • Test case(s) to demonstrate the difference of before/after

Copy link
Copy Markdown
Contributor Author

ironAiken2 commented Apr 23, 2026

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • flow:merge-queue - adds this PR to the back of the merge queue
  • flow:hotfix - for urgent changes, fast-track this PR to the front of the merge queue

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has required the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Coverage report for ./react

St.
Category Percentage Covered / Total
🔴 Statements
8.86% (-0.02% 🔻)
1858/20978
🔴 Branches
8.04% (-0.01% 🔻)
1187/14768
🔴 Functions
5.2% (+0% 🔼)
296/5689
🔴 Lines
8.6% (-0.02% 🔻)
1750/20354
Show new covered files 🐣
St.
File Statements Branches Functions Lines
🔴
... / QuotaPerStorageVolumeDashboardItem.tsx
0% 0% 0% 0%

Test suite run success

865 tests passing in 40 suites.

Report generated by 🧪jest coverage report action from 2af4049

@ironAiken2 ironAiken2 force-pushed the 04-23-feat_fr-2691_relocate__data_header_panels_dashboard_host-capacity_cell branch from b068ff5 to fbabca7 Compare April 23, 2026 07:59
@ironAiken2 ironAiken2 force-pushed the 04-21-feat_fr-2613_migrate_vfolder_trash_lifecycle_mutations_to_v2_graphql_api branch from 2a1e7e6 to 8d4bf6b Compare April 23, 2026 07:59
@ironAiken2 ironAiken2 marked this pull request as ready for review April 23, 2026 08:33
Copilot AI review requested due to automatic review settings April 23, 2026 08:33
@ironAiken2 ironAiken2 force-pushed the 04-23-feat_fr-2691_relocate__data_header_panels_dashboard_host-capacity_cell branch from fbabca7 to aa129c7 Compare April 23, 2026 08:35
@github-actions github-actions Bot added area:ux UI / UX issue. area:i18n Localization size:XL 500~ LoC and removed size:L 100~500 LoC labels Apr 23, 2026
@ironAiken2 ironAiken2 requested review from agatha197, Copilot, nowgnuesLee and yomybaby and removed request for Copilot April 23, 2026 08:38
@ironAiken2 ironAiken2 force-pushed the 04-21-feat_fr-2613_migrate_vfolder_trash_lifecycle_mutations_to_v2_graphql_api branch from 8d4bf6b to b3429c8 Compare April 24, 2026 04:02
@ironAiken2 ironAiken2 force-pushed the 04-23-feat_fr-2691_relocate__data_header_panels_dashboard_host-capacity_cell branch from aa129c7 to 5ac60d3 Compare April 24, 2026 04:02
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Relocates the /data page header panels by moving folder-status information to the Dashboard, and enhances the vfolder list by surfacing per-host capacity/usage context directly in the “Host” column (with a modal entry point for per-volume quota details).

Changes:

  • Removed the /data page’s top header panel row and promoted the folder table card to the top.
  • Added a new Dashboard board item rendering StorageStatusPanelCard, including navigation to /data?invitation=true.
  • Reworked the vfolder table “Host” column to show a per-host usage badge and added a header tooltip icon that opens QuotaPerStorageVolumePanelCard in a modal (plus i18n key data.usage.Unknown across locales).

Reviewed changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
react/src/pages/VFolderNodeListPage.tsx Removes the /data header panels row and cleans up related imports/usage.
react/src/pages/DashboardPage.tsx Adds the folder-status board item and wires invitation navigation to /data.
react/src/components/VFolderNodesV2.tsx Replaces “Location” with “Host” column, adds host usage badge cell + quota modal trigger.
react/src/components/QuotaPerStorageVolumePanelCard.tsx Refactors quota panel to be modal-body-friendly; adds defaultVolumeInfo for preselection.
react/src/components/StorageStatusPanelCard.tsx Refactors layout to a Dashboard board-item body using BAIFlex + BAIBoardItemTitle.
resources/i18n/en.json Adds data.usage.Unknown translation key.
resources/i18n/de.json Adds data.usage.Unknown translation key.
resources/i18n/el.json Adds data.usage.Unknown translation key.
resources/i18n/es.json Adds data.usage.Unknown translation key.
resources/i18n/fi.json Adds data.usage.Unknown translation key.
resources/i18n/fr.json Adds data.usage.Unknown translation key.
resources/i18n/id.json Adds data.usage.Unknown translation key.
resources/i18n/it.json Adds data.usage.Unknown translation key.
resources/i18n/ja.json Adds data.usage.Unknown translation key.
resources/i18n/ko.json Adds data.usage.Unknown translation key.
resources/i18n/mn.json Adds data.usage.Unknown translation key.
resources/i18n/ms.json Adds data.usage.Unknown translation key.
resources/i18n/pl.json Adds data.usage.Unknown translation key.
resources/i18n/pt-BR.json Adds data.usage.Unknown translation key.
resources/i18n/pt.json Adds data.usage.Unknown translation key.
resources/i18n/ru.json Adds data.usage.Unknown translation key.
resources/i18n/th.json Adds data.usage.Unknown translation key.
resources/i18n/tr.json Adds data.usage.Unknown translation key.
resources/i18n/vi.json Adds data.usage.Unknown translation key.
resources/i18n/zh-CN.json Adds data.usage.Unknown translation key.
resources/i18n/zh-TW.json Adds data.usage.Unknown translation key.

Comment thread react/src/components/VFolderNodesV2.tsx Outdated
Comment thread react/src/components/QuotaPerStorageVolumePanelCard.tsx Outdated
Comment thread react/src/components/VFolderNodesV2.tsx
Comment thread react/src/components/VFolderNodesV2.tsx
Comment thread react/src/components/VFolderNodesV2.tsx Outdated
Copy link
Copy Markdown
Contributor

@agatha197 agatha197 left a comment

Choose a reason for hiding this comment

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

I tested host capacity panel with dogbowl, but it doesn't appear.

@ironAiken2 ironAiken2 force-pushed the 04-21-feat_fr-2613_migrate_vfolder_trash_lifecycle_mutations_to_v2_graphql_api branch from b3429c8 to edf4af1 Compare April 24, 2026 04:45
@ironAiken2 ironAiken2 force-pushed the 04-23-feat_fr-2691_relocate__data_header_panels_dashboard_host-capacity_cell branch from 5ac60d3 to f6610e9 Compare April 24, 2026 04:45
@ironAiken2 ironAiken2 changed the base branch from 04-21-feat_fr-2613_migrate_vfolder_trash_lifecycle_mutations_to_v2_graphql_api to graphite-base/6941 April 24, 2026 05:31
@ironAiken2 ironAiken2 force-pushed the 04-23-feat_fr-2691_relocate__data_header_panels_dashboard_host-capacity_cell branch from f6610e9 to 824d4b3 Compare April 24, 2026 06:02
@ironAiken2 ironAiken2 changed the base branch from graphite-base/6941 to 04-21-feat_fr-2613_migrate_vfolder_trash_lifecycle_mutations_to_v2_graphql_api April 24, 2026 06:02
@ironAiken2 ironAiken2 force-pushed the 04-23-feat_fr-2691_relocate__data_header_panels_dashboard_host-capacity_cell branch from 824d4b3 to 058f802 Compare April 24, 2026 06:29
@ironAiken2
Copy link
Copy Markdown
Contributor Author

@agatha197 Thanks for testing! Previously the host-capacity badge was only rendered when vfolder.list_hosts() returned a usage object (which is why it didn't show on dogbowl). This is now corrected so the Host column still renders the host name + a neutral badge even when host info can't be loaded. Please re-verify against dogbowl when you get a chance.

@ironAiken2 ironAiken2 requested a review from agatha197 April 24, 2026 06:30
@ironAiken2 ironAiken2 force-pushed the 04-23-feat_fr-2691_relocate__data_header_panels_dashboard_host-capacity_cell branch from 058f802 to 9c45759 Compare April 27, 2026 02:42
@ironAiken2 ironAiken2 force-pushed the 04-21-feat_fr-2613_migrate_vfolder_trash_lifecycle_mutations_to_v2_graphql_api branch 2 times, most recently from 42e2427 to 2ab0d52 Compare April 27, 2026 04:19
@ironAiken2 ironAiken2 force-pushed the 04-23-feat_fr-2691_relocate__data_header_panels_dashboard_host-capacity_cell branch 3 times, most recently from c84cd7c to 91a0feb Compare April 27, 2026 06:57
@ironAiken2 ironAiken2 force-pushed the 04-21-feat_fr-2613_migrate_vfolder_trash_lifecycle_mutations_to_v2_graphql_api branch 2 times, most recently from 6f4f7f0 to 1d95414 Compare April 27, 2026 08:55
@ironAiken2 ironAiken2 force-pushed the 04-23-feat_fr-2691_relocate__data_header_panels_dashboard_host-capacity_cell branch 2 times, most recently from 025ecbb to dabf732 Compare April 27, 2026 10:00
@ironAiken2 ironAiken2 force-pushed the 04-21-feat_fr-2613_migrate_vfolder_trash_lifecycle_mutations_to_v2_graphql_api branch 2 times, most recently from ac4de81 to 7db3eb6 Compare April 28, 2026 02:03
@ironAiken2 ironAiken2 force-pushed the 04-23-feat_fr-2691_relocate__data_header_panels_dashboard_host-capacity_cell branch from dabf732 to 7a91a43 Compare April 28, 2026 02:03
…ty cell

Resolves #6937(FR-2691)

Removes the three header panels from the /data VFolder list page (Create
Folder action card, StorageStatusPanelCard, QuotaPerStorageVolumePanelCard)
and redistributes their responsibilities:

- Folder-status counts move to the Dashboard as a new `folderStatus` board
  item. StorageStatusPanelCard is unchanged functionally; a
  `TODO(FR-2691 v2-migration)` marker is added alongside its two legacy
  query surfaces (baiClient.vfolder.list REST call and the V1
  user_resource_policy / project_resource_policy GraphQL fields) so a
  follow-up task can move them to myVfolders / projectVfolders V2
  connections with server-side filter+count.
- Per-volume quota visibility moves into the folder table's Location
  column via a new VFolderHostCell: the host name is now clickable and
  carries a StorageUsageBadge sourced from the shared vhostInfo tan-query
  cache key used by StorageSelect. Clicking opens QuotaPerStorageVolumePanelCard
  in a modal, pre-seeded on the clicked host through a new
  `defaultVolumeInfo` prop (auto-select is disabled when a default is
  passed; users can still switch volumes via the inline StorageSelect).

The Create Folder affordance is retained through the existing primary
button inside the folder table card header, so no replacement for the
removed action card is needed.

The cell suspense is scoped per-row so a cold hosts cache does not
suspend the whole page — each row falls back to a plain host label
until the shared payload resolves, after which the badge and click
handler light up.
@ironAiken2 ironAiken2 force-pushed the 04-21-feat_fr-2613_migrate_vfolder_trash_lifecycle_mutations_to_v2_graphql_api branch from 7db3eb6 to 03cf13c Compare April 28, 2026 03:21
@ironAiken2 ironAiken2 force-pushed the 04-23-feat_fr-2691_relocate__data_header_panels_dashboard_host-capacity_cell branch from 7a91a43 to 2af4049 Compare April 28, 2026 03:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:i18n Localization area:ux UI / UX issue. size:XL 500~ LoC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants