Skip to content

refactor(FR-2977): unify revision-source prefill in DeploymentAddRevisionModal#7602

Merged
graphite-app[bot] merged 1 commit into
mainfrom
05-27-refactor_fr-2977_unify_revision-source_prefill_in_deploymentaddrevisionmodal
Jun 5, 2026
Merged

refactor(FR-2977): unify revision-source prefill in DeploymentAddRevisionModal#7602
graphite-app[bot] merged 1 commit into
mainfrom
05-27-refactor_fr-2977_unify_revision-source_prefill_in_deploymentaddrevisionmodal

Conversation

@agatha197

@agatha197 agatha197 commented May 27, 2026

Copy link
Copy Markdown
Contributor

Resolves #7601 (FR-2977)

Summary

Base refactor for DeploymentAddRevisionModal so any caller (e.g. a future "Duplicate as new revision" action — see the parallel PR #7561) can hand the modal an arbitrary source ModelRevision to prefill from, replacing the prop-drilled fragment ref + dual-useEffectEvent state pump that surfaced during review of FR-2957:

  • Single source fragment. Define DeploymentAddRevisionModal_revisionSource on ModelRevision at module scope and spread it in two places: on currentRevision inside the modal's deployment fragment (DeploymentAddRevisionModal_deployment), and on whatever revision a caller wants to pass in via the new optional sourceRevisionFrgmt prop. Both are read via useFragment sharing one $data shape, so the extracted applyRevisionToCustomForm(rev) helper accepts either without an unsafe cast.
  • Optional sourceRevisionFrgmt prop. The modal now takes sourceRevisionFrgmt?: DeploymentAddRevisionModal_revisionSource$key | null alongside the required deploymentFrgmt. The Preset/Custom toggle remains user-controlled — effectiveMode defaults to mode ?? 'preset', so the modal still opens in the user's persisted mode regardless of sourceRevisionFrgmt. When provided (e.g. "Duplicate as new revision" from a revision detail drawer), the Custom form is pre-filled from the source on first Custom-mode entry and the "Load current revision" alert is suppressed (it would be redundant — the form already reflects the source). When omitted, the modal behaves as the plain "Add revision" entry — Custom mode shows the alert with a button that prefills from deployment.currentRevision on demand.
  • Apply-once gating via useEffectEvent. useEffect keyed on effectiveMode. When the user lands in Custom mode for the first time in a session, applySourcePrefillOnce (a useEffectEvent) seeds the form from sourceRevision and flips a hasAppliedSourcePrefill boolean so a subsequent Preset → Custom toggle does not re-stomp the user's edits. The existing consumePresetTransferPrefill / consumeCustomTransferPrefill flows are unchanged and run from the same effect.
  • i18n key deployment.CurrentRevisionConfigurationLoaded for the toast that fires after Load current / source-prefill is applied. The key was first added across all 22 locales in 5ff2c0c5 (ko/ja translated, the rest as English placeholder); the 18 remaining-language translations (de, el, es, fi, fr, id, it, ms, mn, pl, pt, pt-BR, ru, th, tr, vi, zh-CN, zh-TW) were amended into the refactor commit f91462517 while resolving review feedback.

Notes

  • Parallel with feat(FR-2957): add new-revision-from-this action in revision detail drawer #7561 (FR-2957), not stacked. feat(FR-2957): add new-revision-from-this action in revision detail drawer #7561 lands the "Duplicate as new revision" menu entry / icon / i18n in the revision detail drawer and is the first intended consumer of sourceRevisionFrgmt. Both PRs are parented on main; for actual rollout this refactor needs to land first (so feat(FR-2957): add new-revision-from-this action in revision detail drawer #7561 has a prop to pass into) but Graphite isn't enforcing the order.
  • Callsite-neutral for the source-revision path on this PR. DeploymentDetailPage opens the modal without sourceRevisionFrgmt, exactly as before — only the existing "Add revision" + "Load current revision" flows run on this branch. The Preset-mode "Load current" path is not handled in this PR; the alert is still rendered inside the Custom form, matching pre-refactor behavior.
  • API evolved beyond the original issue's "mode + sourceRevisionId as props" sketch. An earlier draft of this refactor tried a usePreloadedQuery / useQueryLoader design with $sourceRevisionId + $hasSourceRevision query variables and a revision(id:) @include(if:) field — that has been replaced with the plain fragment-ref prop above, which is simpler for callers (one prop, one fragment spread on their own query) and doesn't require the modal to own a separate query for the source.
  • Alert action button styling. The "Load current revision" alert's button intentionally drops type="primary" so the modal's footer Add Revision CTA is the only primary action — avoiding two competing primaries in one modal.
  • Out of scope: presetTransferPrefill / customTransferPrefill (the preset ↔ custom value transfer from FR-2862) — same anti-shape, but translates between two different form shapes and is a structurally different problem.
  • Modal UX is unchanged — alert copy, mode segmented control behavior, Apply button placement, footer all preserved. Pure data-flow refactor on this PR.

Test plan

  • Add Revision button (sourceless) — opens in the persisted mode, no auto-prefill, mode toggle visible, "Load current revision" alert visible in Custom.
  • Load current revision alert — populates the Custom form with the deployment's current revision values (Model Folder, Runtime, image, 4 Core / 8 GiB, Single Node, etc.) and fires the success toast.
  • Toggle Custom ↔ Preset — the existing transfer prefill still moves the shared values across (Custom → Preset transfers Model Folder; Preset → Custom transfers Model Folder back).
  • sourceRevisionFrgmt consumer path — exercised end-to-end once feat(FR-2957): add new-revision-from-this action in revision detail drawer #7561 lands and wires the "Duplicate as new revision" entry.

Screenshots

Preset Mode (default) Advanced Mode — Load current revision alert After loading current revision
Preset Mode Advanced Mode with alert After loading current revision

@github-actions github-actions Bot added the size:XL 500~ LoC label May 27, 2026

agatha197 commented May 27, 2026

Copy link
Copy Markdown
Contributor Author

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

github-actions Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for react-coverage (./react)

Status Category Percentage Covered / Total
🔵 Lines 6.45% 1798 / 27849
🔵 Statements 5.24% 1994 / 38008
🔵 Functions 5.34% 300 / 5609
🔵 Branches 3.67% 1305 / 35555
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
react/src/components/DeploymentAddRevisionModal.tsx 0% 0% 0% 0% 149-1827
react/src/components/DeploymentConfigurationSection.tsx 0% 0% 0% 0% 82-394
react/src/pages/DeploymentDetailPage.tsx 0% 0% 0% 0% 52-156
Generated in workflow #1495 for commit 2827871 by the Vitest Coverage Report Action

@agatha197 agatha197 force-pushed the 05-27-refactor_fr-2977_unify_revision-source_prefill_in_deploymentaddrevisionmodal branch from ce82933 to 034f843 Compare May 28, 2026 01:55
@agatha197 agatha197 marked this pull request as ready for review May 28, 2026 01:56
Copilot AI review requested due to automatic review settings May 28, 2026 01:56

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

Refactors DeploymentAddRevisionModal to a render-as-you-fetch model with a single shared DeploymentAddRevisionModal_revisionSource fragment. The modal now consumes a PreloadedQuery whose variables (sourceRevisionId, hasSourceRevision) can request an id-based revision lookup via revision(id:) @include @since("25.16.0"). Both currentRevision and the optional source revision are read through the same fragment, and a single keyed effect applies the prefill — replacing the previous useLazyLoadQuery + duplicate-state pump pattern and laying the groundwork for the stacked "Duplicate as new revision" PR (#7561).

Changes:

  • Introduce DeploymentAddRevisionModal_revisionSource fragment + exported DeploymentAddRevisionQuery; add $sourceRevisionId/$hasSourceRevision variables and a conditional revision(id:) top-level field.
  • Switch the modal from useLazyLoadQuery to usePreloadedQuery+useDeferredValue, derive effectiveMode='custom' when the queryRef carries hasSourceRevision, and reduce prefill to one keyed useEffect/useEffectEvent using appliedSourceIdRef.
  • Move query kickoff to DeploymentDetailPage via useQueryLoader, drop the local <Suspense> boundary, and gate modal render on addRevisionQueryRef != null.

Reviewed changes

Copilot reviewed 3 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
react/src/pages/DeploymentDetailPage.tsx Replaces useToggle with useState+useQueryLoader to preload the modal query on click; removes the local Suspense boundary.
react/src/components/DeploymentConfigurationSection.tsx Updates the Add Revision button comment to reflect the render-as-you-fetch flow.
react/src/components/DeploymentAddRevisionModal.tsx Adds the shared revision-source fragment, exported preloaded query, single apply-prefill effect, and locks mode to Custom when queryRef.variables.hasSourceRevision is true.
react/src/generated/DeploymentAddRevisionModalQuery.graphql.ts Regenerated query artifact for the new variables and conditional revision field.
react/src/generated/DeploymentAddRevisionModal_revisionSource.graphql.ts New generated fragment artifact for the shared revision-source selection.
Files not reviewed (2)
  • react/src/generated/DeploymentAddRevisionModalQuery.graphql.ts: Language not supported
  • react/src/generated/DeploymentAddRevisionModal_revisionSource.graphql.ts: Language not supported

Comment thread react/src/components/DeploymentAddRevisionModal.tsx Outdated
@agatha197 agatha197 force-pushed the 05-27-refactor_fr-2977_unify_revision-source_prefill_in_deploymentaddrevisionmodal branch from 034f843 to 1b84a66 Compare May 28, 2026 05:54
agatha197 pushed a commit that referenced this pull request May 28, 2026
@agatha197 agatha197 marked this pull request as draft May 28, 2026 07:57
@agatha197 agatha197 marked this pull request as ready for review May 28, 2026 09:04

@nowgnuesLee nowgnuesLee 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.

Please resolve the merge conflicts.

@agatha197 agatha197 force-pushed the 05-27-refactor_fr-2977_unify_revision-source_prefill_in_deploymentaddrevisionmodal branch from 1b84a66 to 3ba8330 Compare May 29, 2026 05:38
@agatha197 agatha197 requested a review from nowgnuesLee May 29, 2026 05:38
Comment thread react/src/components/DeploymentAddRevisionModal.tsx
@agatha197 agatha197 force-pushed the 05-27-refactor_fr-2977_unify_revision-source_prefill_in_deploymentaddrevisionmodal branch 2 times, most recently from 3274d43 to 7623f0e Compare May 30, 2026 13:04
@agatha197 agatha197 requested a review from nowgnuesLee May 30, 2026 13:05
@agatha197 agatha197 force-pushed the 05-27-refactor_fr-2977_unify_revision-source_prefill_in_deploymentaddrevisionmodal branch from 7623f0e to 8e34245 Compare June 1, 2026 01:12
@agatha197 agatha197 marked this pull request as draft June 1, 2026 01:12
@agatha197 agatha197 force-pushed the 05-27-refactor_fr-2977_unify_revision-source_prefill_in_deploymentaddrevisionmodal branch 2 times, most recently from 0972d0b to 15817ad Compare June 1, 2026 01:32
@github-actions github-actions Bot added area:ux UI / UX issue. area:i18n Localization labels Jun 1, 2026

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

Copilot reviewed 23 out of 27 changed files in this pull request and generated 21 comments.

Files not reviewed (4)
  • react/src/generated/DeploymentAddRevisionModalQuery.graphql.ts: Language not supported
  • react/src/generated/DeploymentAddRevisionModal_deployment.graphql.ts: Language not supported
  • react/src/generated/DeploymentAddRevisionModal_revisionSource.graphql.ts: Language not supported
  • react/src/generated/DeploymentDetailPageQuery.graphql.ts: Language not supported

Comment thread react/src/components/DeploymentAddRevisionModal.tsx
Comment thread react/src/components/DeploymentAddRevisionModal.tsx
Comment thread react/src/components/DeploymentAddRevisionModal.tsx
Comment thread resources/i18n/de.json Outdated
Comment thread resources/i18n/el.json Outdated
Comment thread resources/i18n/th.json Outdated
Comment thread resources/i18n/tr.json Outdated
Comment thread resources/i18n/vi.json Outdated
Comment thread resources/i18n/zh-CN.json Outdated
Comment thread resources/i18n/zh-TW.json Outdated
@agatha197 agatha197 force-pushed the 05-27-refactor_fr-2977_unify_revision-source_prefill_in_deploymentaddrevisionmodal branch 2 times, most recently from 13d7638 to f914625 Compare June 1, 2026 05:49
agatha197 added a commit that referenced this pull request Jun 1, 2026
Add an "Add new revision from this" overflow action in each revision
history table row and in the revision detail drawer. Selecting it opens
DeploymentAddRevisionModal with that revision passed as
`sourceRevisionFrgmt`, prefilling the Custom form from it.

Rebased onto #7602 (FR-2977): the fragment-based revision-source prefill
modal refactor now lives entirely in the parent PR, so this branch
carries only the consumer-side changes (drawer/history menu items,
fragment spreads, i18n). Drops the now-unused `FailedToPrepareNewRevision`
i18n key.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
agatha197 added a commit that referenced this pull request Jun 1, 2026
Add an "Add new revision from this" overflow action in each revision
history table row and in the revision detail drawer. Selecting it opens
DeploymentAddRevisionModal with that revision passed as
`sourceRevisionFrgmt`, prefilling the Custom form from it.

Rebased onto #7602 (FR-2977): the fragment-based revision-source prefill
modal refactor now lives entirely in the parent PR, so this branch
carries only the consumer-side changes (drawer/history menu items,
fragment spreads, i18n). Drops the now-unused `FailedToPrepareNewRevision`
i18n key.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
agatha197 added a commit that referenced this pull request Jun 4, 2026
Add an "Add new revision from this" overflow action in each revision
history table row and in the revision detail drawer. Selecting it opens
DeploymentAddRevisionModal with that revision passed as
`sourceRevisionFrgmt`, prefilling the Custom form from it.

Rebased onto #7602 (FR-2977): the fragment-based revision-source prefill
modal refactor now lives entirely in the parent PR, so this branch
carries only the consumer-side changes (drawer/history menu items,
fragment spreads, i18n). Drops the now-unused `FailedToPrepareNewRevision`
i18n key.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@agatha197 agatha197 force-pushed the 05-27-refactor_fr-2977_unify_revision-source_prefill_in_deploymentaddrevisionmodal branch 2 times, most recently from d18f4ea to de61da7 Compare June 4, 2026 07:13
@agatha197 agatha197 force-pushed the 05-27-refactor_fr-2977_unify_revision-source_prefill_in_deploymentaddrevisionmodal branch 3 times, most recently from a8f8b52 to dca38f7 Compare June 5, 2026 01:34

@nowgnuesLee nowgnuesLee 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.

LGTM

@graphite-app

graphite-app Bot commented Jun 5, 2026

Copy link
Copy Markdown

Merge activity

…sionModal (#7602)

Resolves #7601 (FR-2977)

## Summary

Base refactor for `DeploymentAddRevisionModal` so any caller (e.g. a future "Duplicate as new revision" action — see the parallel PR #7561) can hand the modal an arbitrary source `ModelRevision` to prefill from, replacing the prop-drilled fragment ref + dual-`useEffectEvent` state pump that surfaced during review of FR-2957:

- **Single source fragment.** Define `DeploymentAddRevisionModal_revisionSource` on `ModelRevision` at module scope and spread it in two places: on `currentRevision` inside the modal's deployment fragment (`DeploymentAddRevisionModal_deployment`), and on whatever revision a caller wants to pass in via the new optional `sourceRevisionFrgmt` prop. Both are read via `useFragment` sharing one `$data` shape, so the extracted `applyRevisionToCustomForm(rev)` helper accepts either without an unsafe cast.
- **Optional `sourceRevisionFrgmt` prop.** The modal now takes `sourceRevisionFrgmt?: DeploymentAddRevisionModal_revisionSource$key | null` alongside the required `deploymentFrgmt`. The Preset/Custom toggle remains user-controlled — `effectiveMode` defaults to `mode ?? 'preset'`, so the modal still opens in the user's persisted mode regardless of `sourceRevisionFrgmt`. When provided (e.g. "Duplicate as new revision" from a revision detail drawer), the Custom form is pre-filled from the source on **first Custom-mode entry** and the "Load current revision" alert is suppressed (it would be redundant — the form already reflects the source). When omitted, the modal behaves as the plain "Add revision" entry — Custom mode shows the alert with a button that prefills from `deployment.currentRevision` on demand.
- **Apply-once gating via `useEffectEvent`.** `useEffect` keyed on `effectiveMode`. When the user lands in Custom mode for the first time in a session, `applySourcePrefillOnce` (a `useEffectEvent`) seeds the form from `sourceRevision` and flips a `hasAppliedSourcePrefill` boolean so a subsequent Preset → Custom toggle does not re-stomp the user's edits. The existing `consumePresetTransferPrefill` / `consumeCustomTransferPrefill` flows are unchanged and run from the same effect.
- **i18n key** `deployment.CurrentRevisionConfigurationLoaded` for the toast that fires after Load current / source-prefill is applied. The key was first added across all 22 locales in `5ff2c0c5` (ko/ja translated, the rest as English placeholder); the 18 remaining-language translations (de, el, es, fi, fr, id, it, ms, mn, pl, pt, pt-BR, ru, th, tr, vi, zh-CN, zh-TW) were amended into the refactor commit `f91462517` while resolving review feedback.

## Notes

- **Parallel with #7561 (FR-2957), not stacked.** #7561 lands the "Duplicate as new revision" menu entry / icon / i18n in the revision detail drawer and is the first intended consumer of `sourceRevisionFrgmt`. Both PRs are parented on `main`; for actual rollout this refactor needs to land first (so #7561 has a prop to pass into) but Graphite isn't enforcing the order.
- **Callsite-neutral for the source-revision path on this PR.** `DeploymentDetailPage` opens the modal without `sourceRevisionFrgmt`, exactly as before — only the existing "Add revision" + "Load current revision" flows run on this branch. The Preset-mode "Load current" path is not handled in this PR; the alert is still rendered inside the Custom form, matching pre-refactor behavior.
- **API evolved beyond the original issue's "`mode` + `sourceRevisionId` as props" sketch.** An earlier draft of this refactor tried a `usePreloadedQuery` / `useQueryLoader` design with `$sourceRevisionId` + `$hasSourceRevision` query variables and a `revision(id:) @include(if:)` field — that has been replaced with the plain fragment-ref prop above, which is simpler for callers (one prop, one fragment spread on their own query) and doesn't require the modal to own a separate query for the source.
- **Alert action button styling.** The "Load current revision" alert's button intentionally drops `type="primary"` so the modal's footer Add Revision CTA is the only primary action — avoiding two competing primaries in one modal.
- **Out of scope:** `presetTransferPrefill` / `customTransferPrefill` (the preset ↔ custom value transfer from FR-2862) — same anti-shape, but translates between two different form shapes and is a structurally different problem.
- **Modal UX is unchanged** — alert copy, mode segmented control behavior, Apply button placement, footer all preserved. Pure data-flow refactor on this PR.

## Test plan

- [x] **Add Revision button (sourceless)** — opens in the persisted mode, no auto-prefill, mode toggle visible, "Load current revision" alert visible in Custom.
- [x] **Load current revision alert** — populates the Custom form with the deployment's current revision values (Model Folder, Runtime, image, 4 Core / 8 GiB, Single Node, etc.) and fires the success toast.
- [x] **Toggle Custom ↔ Preset** — the existing transfer prefill still moves the shared values across (Custom → Preset transfers Model Folder; Preset → Custom transfers Model Folder back).
- [ ] **`sourceRevisionFrgmt` consumer path** — exercised end-to-end once #7561 lands and wires the "Duplicate as new revision" entry.

## Screenshots

| Preset Mode (default) | Advanced Mode — Load current revision alert | After loading current revision |
|---|---|---|
| ![Preset Mode](https://raw.githubusercontent.com/lablup/backend.ai-webui/assets/images/screenshots/pr-7602/20260528-060632-screenshot-02-add-revision-modal-preset.png) | ![Advanced Mode with alert](https://raw.githubusercontent.com/lablup/backend.ai-webui/assets/images/screenshots/pr-7602/20260528-060632-screenshot-03-add-revision-modal-advanced-with-alert.png) | ![After loading current revision](https://raw.githubusercontent.com/lablup/backend.ai-webui/assets/images/screenshots/pr-7602/20260528-060632-screenshot-04-add-revision-modal-loaded-current.png) |
@graphite-app graphite-app Bot force-pushed the 05-27-refactor_fr-2977_unify_revision-source_prefill_in_deploymentaddrevisionmodal branch from dca38f7 to 2827871 Compare June 5, 2026 04:43
@graphite-app graphite-app Bot merged commit 2827871 into main Jun 5, 2026
13 checks passed
@graphite-app graphite-app Bot deleted the 05-27-refactor_fr-2977_unify_revision-source_prefill_in_deploymentaddrevisionmodal branch June 5, 2026 04:44
agatha197 added a commit that referenced this pull request Jun 5, 2026
Add an "Add new revision from this" overflow action in each revision
history table row and in the revision detail drawer. Selecting it opens
DeploymentAddRevisionModal with that revision passed as
`sourceRevisionFrgmt`, prefilling the Custom form from it.

Rebased onto #7602 (FR-2977): the fragment-based revision-source prefill
modal refactor now lives entirely in the parent PR, so this branch
carries only the consumer-side changes (drawer/history menu items,
fragment spreads, i18n). Drops the now-unused `FailedToPrepareNewRevision`
i18n key.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
graphite-app Bot pushed a commit that referenced this pull request Jun 5, 2026
…rawer (#7561)

Resolves #7560 (FR-2957)

> **Stacked on #7602 (FR-2977).** The base PR refactors `DeploymentAddRevisionModal` to an id-based revision source. This top PR is a thin layer on top of that — menu items, i18n, icon, and the parent state that drives `sourceRevisionId`. The bulk of the original FR-2957 diff (fragment definition, dual `useEffectEvent` state pump, fragment-ref prop drilling) moved into FR-2977 in cleaner form.

## Summary
- Add an **Add new revision from this** overflow action in the revision detail drawer (next to the Apply button) and in each revision history table row menu
- On click, set `sourceRevisionId` on `DeploymentAddRevisionModal` so the modal opens locked to Custom mode and auto-prefills with that revision's full configuration (handled by FR-2977's machinery)
- Add i18n key `deployment.AddNewRevisionFromThis` (all 21 languages)
- Use `CopyOutlined` (not a branching icon) — the action copies settings into a new linear revision; it does not fork or branch the history

## Test plan
- [ ] Open a deployment's revision history; verify "Add new revision from this" appears in each row's overflow menu
- [ ] Open a revision detail drawer; verify the "More" (⋯) overflow next to Apply shows "Add new revision from this"
- [ ] Click it — verify the Add Revision modal opens in Custom mode pre-filled with that revision's configuration (Model Folder, Runtime, image, resources, env vars, mounts)
- [ ] Submit the Add Revision flow — verify a new revision is created at the linear end of the history (no branching)
- [ ] Confirm the Apply button (rollback) still works as before

## Screenshots

> Note: the screenshots below were captured against an earlier label ("Duplicate as new revision"). The shipped copy is **"Add new revision from this"** (`deployment.AddNewRevisionFromThis`); the layout and behavior are unchanged.

| Row overflow menu | Revision detail drawer (Apply + ⋯) | Pre-filled Add Revision modal |
|---|---|---|
| ![row menu](https://raw.githubusercontent.com/lablup/backend.ai-webui/assets/images/screenshots/pr-7561/20260527-023303-revision-row-overflow-duplicate.png) | ![drawer apply + more](https://raw.githubusercontent.com/lablup/backend.ai-webui/assets/images/screenshots/pr-7561/20260527-023309-revision-drawer-apply-more-duplicate.png) | ![modal prefilled](https://raw.githubusercontent.com/lablup/backend.ai-webui/assets/images/screenshots/pr-7561/20260527-023315-add-revision-modal-prefilled.png) |

The drawer header groups **Apply** with a **More (⋯)** overflow (`Space.Compact`, both primary), matching the established convention from `DeploymentConfigurationSection`. Selecting **Add new revision from this** sets `sourceRevisionId` on the modal; FR-2977's `revision(id:)` + single-effect prefill applies the values.

## What this PR no longer contains (moved to FR-2977)

- The `DeploymentAddRevisionModal_duplicateRevision` fragment (replaced by `DeploymentAddRevisionModal_revisionSource` in the base PR)
- The `pendingDuplicatePrefill` state + the two `useEffectEvent`s (replaced by a single derived `effectiveMode` + single apply effect in the base PR)
- The fragment ref `useState` and `...DeploymentAddRevisionModal_duplicateRevision` spread on the list query (removed; the modal resolves source via id)
graphite-app Bot pushed a commit that referenced this pull request Jun 5, 2026
#7671)

Resolves #7601 (FR-2977)

> **Stacked on #7561 (FR-2957).** That PR adds the "Add new revision from this" entry, which is what surfaces the revision-detail drawer changes below.

## Summary

Follow-up polish for FR-2977 after #7602 + #7561, focused on the deployment detail page's revision area.

- **Move the "Applying revision #N" alert inside the Current Revision tab** (`DeploymentConfigurationSection`). Previously the alert sat at the deployment level between Basic Information and the revision tabs, so it was visible even on the Revision History tab where it had no context. It now lives inside the `currentRevision` tab content next to the revision detail it describes, with `marginBottom: token.marginMD` for separation from `DeploymentRevisionDetail`.
- **Show the full revision UUID in `DeploymentRevisionDetail`.** The drawer/Current-Revision view rendered the 36-char revision ID inside a 2-column 183px cell, which truncated it to ~12 visible chars even with a copy button. Both `revision-number` and `revision-id` items now use `span: screens.md ? 2 : 1`, so each occupies a dedicated full-width row in the 2-column Descriptions. `BAIId` is rendered with `style={{ maxWidth: 'none' }}` so it sits at its natural width — the copy icon stays directly next to the UUID, and the `Current` / `Applying` `BAITag` follows immediately after in the same `BAIFlex`.
- **Move the "Add Rules" button inline in `DeploymentAutoScalingTab`.** It used to live in the `BAICard extra` slot; it now sits inside `AutoScalingRuleList`'s toolbar to the right of the refresh button (the inline-add path the list already exposed via `hideInlineAddButton`). The card stops owning a primary button it didn't actually need.
- **Misc.** Wrap `DeploymentAddRevisionModal` in a `<Suspense fallback={null}>` inside `DeploymentRevisionHistoryTab` so the row-level "Add new revision from this" action doesn't suspend the whole page on first open.

## Test plan

- [x] Open a deployment with a deploying revision — verify the "Applying revision #N" alert appears inside the Current Revision tab (not above the tabs), and disappears when switching to Revision History.
- [x] Open a revision via the Revision History row link — drawer shows `Revision Number` on one full-width row and `Revision ID <uuid> [copy] [Current|Applying]` on the next, full UUID visible, copy icon adjacent to the UUID.
- [x] On the Current Revision tab — same layout; `Current` tag visible next to the copy icon.
- [x] Auto-Scaling tab — "Add Rules" button sits to the right of the refresh button (inline), and is not duplicated in `BAICard extra`.
- [x] `bash scripts/verify.sh` — TypeScript, Relay, Lint, Format all pass.
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.

Refactor DeploymentAddRevisionModal to id-based revision source

3 participants