fix(FR-2919): add reversible BAIDeleteConfirmModal variant, fix title overflow, and downgrade reversible confirm flows#7480
Conversation
How to use the Graphite Merge QueueAdd either label to this PR to merge it via 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. |
Coverage Report for backend-ai-ui-coverage (./packages/backend.ai-ui)
File Coverage
|
||||||||||||||||||||||||||||||||||||||
Coverage Report for react-coverage (./react)
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||
0fa1875 to
9d9c0ae
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds a reversible confirmation path to BAIDeleteConfirmModal so recoverable RBAC/autoscaling actions can share the delete modal chrome without typed confirmation, while also adding related localization and Storybook coverage.
Changes:
- Added
reversiblebehavior and long-title wrapping toBAIDeleteConfirmModal. - Updated RBAC revoke/remove and autoscaling rule delete flows to use the reversible modal variant.
- Added i18n keys and Storybook examples for reversible and long-title scenarios.
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
packages/backend.ai-ui/src/components/BAIDeleteConfirmModal.tsx |
Adds reversible modal behavior and title wrapping. |
packages/backend.ai-ui/src/components/BAIDeleteConfirmModal.stories.tsx |
Adds reversible and long-title Storybook cases. |
react/src/components/AutoScalingRuleList.tsx |
Switches autoscaling rule deletion to reversible confirm copy. |
react/src/components/RoleAssignmentTab.tsx |
Removes typed confirmation for reversible user revocation. |
react/src/components/RolePermissionTab.tsx |
Removes typed confirmation and adds permission-removal detail copy. |
resources/i18n/de.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/el.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/en.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/es.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/fi.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/fr.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/id.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/it.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/ja.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/ko.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/mn.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/ms.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/pl.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/pt-BR.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/pt.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/ru.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/th.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/tr.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/vi.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/zh-CN.json |
Adds autoscaling delete and RBAC permission removal translations. |
resources/i18n/zh-TW.json |
Adds autoscaling delete and RBAC permission removal translations. |
a8fed74 to
8ece8b6
Compare
…ert RBAC regression PR #7370 (FR-2819) consolidated all confirm flows onto the typed-input BAIDeleteConfirmModal, regressing FR-2804 which had downgraded reversible RBAC flows to a lightweight confirm. - BAIDeleteConfirmModal: add `reversible` prop — keeps the same header/ footer/body chrome but suppresses the typed-confirmation input (even for multi-item) and the "cannot be undone" warning. - Fix long-title overflow: long unbreakable titles (e.g. full image refs) now wrap inside the modal header instead of escaping it. - RoleAssignmentTab (Revoke User) & RolePermissionTab (Remove Permission): switch to `reversible`, drop typed-input props. - AutoScalingRuleList (Delete rule): switch to `reversible`; fix title ('Delete Auto Scaling Rule' instead of the metric name) and drop the misleading 'permanently delete' target copy. - Re-add rbac.ConfirmDeletePermissionWithDetail; add autoScalingRule.DeleteAutoScalingRule; translations for 20 locales. - Storybook: add Reversible, ReversibleMultipleItems, LongTitle cases. Deferred (kept as-is, re-audited): AI Agent Reset (legacy dead-path pre-v26.4.8-rc.3), AutoScalingRuleListLegacy. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
8ece8b6 to
3556e4b
Compare

Resolves #7476(FR-2919)
Background
PR #7370 (FR-2819, merged 2026-05-18) deleted
BAIConfirmModalWithInputand consolidated every confirm flow onto the typed-inputBAIDeleteConfirmModal. It applied the wrong criterion ("deletes a DB record") and regressed FR-2804, which had previously downgraded reversible RBAC flows to a lightweight confirm.Changes
1.
BAIDeleteConfirmModal— newreversiblevariant (design unification)reversible?: boolean. Keeps the exact same header/footer/body chrome but never renders the typed-confirmation input (even for multi-item or withrequireConfirmInput) and omits the "This action cannot be undone." warning. Satisfies FR-2919 scope item 3.2.
BAIDeleteConfirmModal—plainItemsprop + long-title overflow fixplainItems?: boolean: drops the default surface (background / border / padding / scroll) around the item list, so a self-contained itemlabel(e.g. a table) does not get a redundant double border.width:100%+overflowWrap:'anywhere').3. Reversible flows downgraded to
reversibleRoleAssignmentTab— Revoke User: drop typed-input props →reversible(reverts FR-2804 regression).RolePermissionTab— Remove Permission: drop typed-input props +target, setdescription={t('rbac.ConfirmDeletePermissionWithDetail')}(reverts FR-2804 regression).AutoScalingRuleList— Delete rule: →reversible; title fixed toautoScalingRule.DeleteAutoScalingRuleinstead of the raw metric name; description uses a dedicated placeholder-freeautoScalingRule.DeleteConfirmation(avoids the mis-localized genericdialog.ask.*key — the metric name is already shown in the item list).4. RolePermissionTab — permission shown as a read-only table
{entityType} - {operation} ({scopeType})(scope type only, no target name).BAITable(1 row, no row actions) mirroring the main permissions table columns: 적용 범위 / 적용 대상 / 권한 타입 / 동작 (rbac.ScopeType/rbac.ScopeId/rbac.EntityType/rbac.Operation), sameTagstyling, combined withplainItems(no double border).resolveScopeNamehelper used by both the ScopeId column and the modal so they never drift.5. i18n
rbac.ConfirmDeletePermissionWithDetail; addautoScalingRule.DeleteAutoScalingRuleandautoScalingRule.DeleteConfirmation(placeholder-free). All translated into 20 locales.6. Storybook
Reversible,ReversibleMultipleItems,LongTitle,PlainItemsstories.BAIDeleteConfirmModal call sites (31 total) — at-a-glance
The shared
BAIDeleteConfirmModalis used in the components below. Only the 3 marked 🟢 use the new lightweight (reversible) version — everything else keeps the typed-confirmation modal (genuinely irreversible delete/purge/terminate), so reviewers can focus on the 🟢 + ⏸ rows.RoleAssignmentTabRolePermissionTabAutoScalingRuleListAIAgentPage(Reset to default)AutoScalingRuleListLegacy/servingtwin — left unchangedVFolderNodes,DeleteForeverVFolderModalV2,DeleteSelectedItemsModalDeploymentList,DeploymentConfigurationSection,ProjectAdminDeploymentsPage,EndpointList,AdminDeploymentPresetListPage,PrometheusPresetTab,AdminModelCardListPage(×2)ContainerRegistryList,CustomizedImageListProjectResourcePolicyList,KeypairResourcePolicyList,UserResourcePolicyList,ResourcePresetList,ResourceGroupListMyKeypairManagementModal,UserCredentialList,PurgeUsersModal,DeploymentAccessTokensTabBAIProjectTable,RBACManagementPage,ShellScriptEditModal,AIAgentPage(Delete agent)All 31 were re-audited against
.claude/rules/destructive-confirmation.md("recoverable in <30s without support?"). Only the 🟢 three are reversible; the rest correctly stay typed-confirm.Verification
bash scripts/verify.sh: Relay / Lint / Format PASS. TypeScript reports the pre-existing project-wide baseline failure (Card/Select.Option/ErrorBoundary"cannot be used as a JSX component", widespread implicit-any) across many untouched files — zero errors in touched files.🤖 Generated with Claude Code