Skip to content

Commit 4790132

Browse files
committed
feat(FR-1368): add deployment launcher — multi-step form, hook, page, and deploy split buttons (#6912)
Resolves #6912 ## Summary Consolidates the full deployment launcher UX (FR-2674, FR-2683, FR-2675, FR-2684): - **FR-2674**: `DeploymentLauncherPageContent` — multi-step form (Basic → Resources → Review) with nuqs URL state, pre-fill support, and per-step validation - **FR-2683**: `useDeploymentLauncher` hook — encapsulates Quick Deploy (`deployInstantly`) and launcher navigation (`openLauncher`) using `createModelDeployment`; gated behind `model-deployment-extended-filter` flag - **FR-2675**: `DeploymentLauncherPage` — page-level orchestrator for `/deployments/new` (create) and `/deployments/:id/edit` routes; owns the `createModelDeployment` / `addModelRevision` mutations - **FR-2684**: Migrate Deploy buttons in `ModelCardDrawer` and `VFolderDeployModal` to `[Deploy | ▼]` split button using `useDeploymentLauncher`; dropdown opens pre-filled launcher at the review step
1 parent 11e3cc1 commit 4790132

37 files changed

Lines changed: 3037 additions & 139 deletions

data/schema.graphql

Lines changed: 575 additions & 3 deletions
Large diffs are not rendered by default.

packages/backend.ai-ui/src/components/BAIProjectResourceGroupSelect.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,13 @@ const BAIProjectResourceGroupSelect: React.FC<
4646

4747
const { resourceGroups } = useProjectResourceGroups(projectName, { filter });
4848

49-
// If the current selected value is not in the resourceGroups, reset the value to undefined
49+
// If the loaded resource group list does not contain the current value, reset to undefined.
50+
// Guard on resourceGroups.length > 0 so we don't wipe a pre-filled value while the list
51+
// is still loading — an empty list means "not yet fetched", not "no valid groups".
5052
useEffect(() => {
5153
if (
5254
controllableValue &&
55+
resourceGroups.length > 0 &&
5356
!_.some(resourceGroups, (item) => item.name === controllableValue)
5457
) {
5558
setControllableValueWithTransition(undefined);
@@ -68,18 +71,17 @@ const BAIProjectResourceGroupSelect: React.FC<
6871
: undefined;
6972

7073
useEffect(() => {
71-
if (
72-
autoSelectDefault &&
73-
autoSelectedOption &&
74-
autoSelectedOption.value !== selectProps.value
75-
) {
74+
if (autoSelectDefault && autoSelectedOption && !controllableValue) {
7675
setControllableValueWithTransition(
7776
autoSelectedOption.value,
7877
autoSelectedOption,
7978
);
8079
}
80+
// controllableValue is intentionally excluded from deps — we only want
81+
// to fire when the available options first appear (autoSelectedOption?.value
82+
// transitions from undefined→name), not on every selection change.
8183
// eslint-disable-next-line react-hooks/exhaustive-deps
82-
}, [autoSelectDefault]);
84+
}, [autoSelectDefault, autoSelectedOption?.value]);
8385

8486
return (
8587
<BAISelect

packages/backend.ai-ui/src/hooks/useProjectResourceGroups.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export const useProjectResourceGroups = (
5555
projectName: string,
5656
options?: UseProjectResourceGroupsOptions,
5757
) => {
58+
'use memo';
5859
const baiRequestWithPromise = useBAISignedRequestWithPromise();
5960

6061
const { data } = useSuspenseTanQuery<ProjectResourceGroupsQueryResult>({

0 commit comments

Comments
 (0)