fix: select gpu stype when creating cluster from gpu service

This commit is contained in:
jialin
2026-06-17 12:35:24 +08:00
committed by jialin
parent 1f5678f781
commit aa49539210
7 changed files with 45 additions and 14 deletions
+1
View File
@@ -63,6 +63,7 @@ export const fromClusterCreationAtom = atom(false);
export const clusterSessionAtom = atom<{ export const clusterSessionAtom = atom<{
firstAddWorker: boolean; firstAddWorker: boolean;
firstAddCluster: boolean; firstAddCluster: boolean;
presetClusterType?: 'model' | 'gpu';
// Provider to preselect when the create flow opens — set by the // Provider to preselect when the create flow opens — set by the
// empty-state CTA on feature pages that need a specific provider // empty-state CTA on feature pages that need a specific provider
// (e.g. GPU Service can only schedule on Kubernetes, so its // (e.g. GPU Service can only schedule on Kubernetes, so its
@@ -59,9 +59,16 @@ const ClusterCreate: React.FC<{
// empty-state CTAs that already know which kind of cluster the user // empty-state CTAs that already know which kind of cluster the user
// is heading for (e.g. GPU Service's "Add a Kubernetes Cluster"). // is heading for (e.g. GPU Service's "Add a Kubernetes Cluster").
providerHint?: string; providerHint?: string;
presetClusterType?: 'model' | 'gpu';
setCurrentTitle?: (title: string) => void; setCurrentTitle?: (title: string) => void;
onClose?: () => void; onClose?: () => void;
}> = ({ onClose, action, providerHint, setCurrentTitle }) => { }> = ({
onClose,
action,
providerHint,
presetClusterType,
setCurrentTitle
}) => {
const stepList = useStepList(); const stepList = useStepList();
const [systemConfigState] = useAtom(systemConfigAtom); const [systemConfigState] = useAtom(systemConfigAtom);
const intl = useIntl(); const intl = useIntl();
@@ -377,6 +384,7 @@ const ClusterCreate: React.FC<{
)} )}
<StepsContext.Provider <StepsContext.Provider
value={{ value={{
presetClusterType: presetClusterType,
formValues: formValues, formValues: formValues,
systemConfig: systemConfigState systemConfig: systemConfigState
}} }}
@@ -6,10 +6,10 @@ import ClusterCreate from './cluster-create';
interface ClusterModalProps { interface ClusterModalProps {
open: boolean; open: boolean;
title: string; title: string;
// When set, ClusterCreate preselects this provider and skips the pendingProviderHint?: {
// provider-catalog step. Used by feature pages (e.g. GPU Service) providerHint?: string;
// whose empty state already implies which kind of cluster is needed. presetClusterType?: 'model' | 'gpu';
providerHint?: string; };
onClose: () => void; onClose: () => void;
} }
@@ -17,7 +17,7 @@ const ClusterModal: React.FC<ClusterModalProps> = ({
open, open,
onClose, onClose,
title, title,
providerHint pendingProviderHint
}) => { }) => {
const [currentTitle, setCurrentTitle] = React.useState<string>(title); const [currentTitle, setCurrentTitle] = React.useState<string>(title);
const handleCancel = () => { const handleCancel = () => {
@@ -46,7 +46,8 @@ const ClusterModal: React.FC<ClusterModalProps> = ({
<ClusterCreate <ClusterCreate
onClose={handleCancel} onClose={handleCancel}
action={PageAction.CREATE} action={PageAction.CREATE}
providerHint={providerHint} providerHint={pendingProviderHint?.providerHint}
presetClusterType={pendingProviderHint?.presetClusterType}
setCurrentTitle={setCurrentTitle} setCurrentTitle={setCurrentTitle}
></ClusterCreate> ></ClusterCreate>
</GSDrawer> </GSDrawer>
+16 -6
View File
@@ -321,13 +321,20 @@ const Clusters: React.FC = () => {
// the session atom is cleared right after we open the modal, but // the session atom is cleared right after we open the modal, but
// ClusterCreate mounts a tick later and needs the value to skip the // ClusterCreate mounts a tick later and needs the value to skip the
// provider-catalog step. Cache it locally and clear on close. // provider-catalog step. Cache it locally and clear on close.
const [pendingProviderHint, setPendingProviderHint] = useState< const [pendingProviderHint, setPendingProviderHint] = useState<{
string | undefined providerHint?: string;
>(undefined); presetClusterType?: 'model' | 'gpu';
}>({
providerHint: '',
presetClusterType: undefined
});
useEffect(() => { useEffect(() => {
if (clusterSession?.firstAddCluster && dataSource.loadend) { if (clusterSession?.firstAddCluster && dataSource.loadend) {
setPendingProviderHint(clusterSession.providerHint); setPendingProviderHint({
providerHint: clusterSession.providerHint,
presetClusterType: clusterSession.presetClusterType
});
openClusterModal(); openClusterModal();
// reset session // reset session
setClusterSession(null); setClusterSession(null);
@@ -335,7 +342,10 @@ const Clusters: React.FC = () => {
}, [clusterSession, dataSource.loadend]); }, [clusterSession, dataSource.loadend]);
const handleClusterModalClose = () => { const handleClusterModalClose = () => {
setPendingProviderHint(undefined); setPendingProviderHint({
providerHint: '',
presetClusterType: undefined
});
closeClusterModal(); closeClusterModal();
}; };
@@ -464,7 +474,7 @@ const Clusters: React.FC = () => {
id: 'menu.resources.clusterCreate' id: 'menu.resources.clusterCreate'
})} })}
open={clusterModalStatus.open} open={clusterModalStatus.open}
providerHint={pendingProviderHint} pendingProviderHint={pendingProviderHint}
onClose={handleClusterModalClose} onClose={handleClusterModalClose}
></ClusterModal> ></ClusterModal>
{AddWorkerModal} {AddWorkerModal}
@@ -6,6 +6,7 @@ import { Form } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
import React, { useEffect, useId, useMemo } from 'react'; import React, { useEffect, useId, useMemo } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { useStepsContext } from '../config/steps-context';
import { ClusterListItem as ListItem } from '../config/types'; import { ClusterListItem as ListItem } from '../config/types';
import ImageCredential from './image-credential'; import ImageCredential from './image-credential';
import K8SVolumeMount from './k8s-volume-mount'; import K8SVolumeMount from './k8s-volume-mount';
@@ -175,6 +176,7 @@ const RadioDot = styled.span<{ $active: boolean }>`
export const ClusterTypeSelector: React.FC = () => { export const ClusterTypeSelector: React.FC = () => {
const intl = useIntl(); const intl = useIntl();
const form = Form.useFormInstance(); const form = Form.useFormInstance();
const { presetClusterType } = useStepsContext();
const labelId = useId(); const labelId = useId();
const gpuInstanceOptions = Form.useWatch(GPU_INSTANCE_OPTIONS_PATH, { const gpuInstanceOptions = Form.useWatch(GPU_INSTANCE_OPTIONS_PATH, {
form, form,
@@ -211,6 +213,12 @@ export const ClusterTypeSelector: React.FC = () => {
} }
]; ];
useEffect(() => {
if (presetClusterType) {
handleSelect(presetClusterType);
}
}, [presetClusterType]);
return ( return (
<ClusterTypeWrap> <ClusterTypeWrap>
<ClusterTypeLabel id={labelId}> <ClusterTypeLabel id={labelId}>
@@ -1,13 +1,15 @@
import { createContext, useContext } from 'react'; import { createContext, useContext } from 'react';
export interface StepsContextProps { export interface StepsContextProps {
presetClusterType?: 'model' | 'gpu';
formValues: Record<string, any>; formValues: Record<string, any>;
systemConfig?: Record<string, any>; systemConfig?: Record<string, any>;
} }
export const StepsContext = createContext<StepsContextProps>({ export const StepsContext = createContext<StepsContextProps>({
formValues: {}, formValues: {},
systemConfig: {} systemConfig: {},
presetClusterType: undefined
}); });
export const useStepsContext = () => useContext(StepsContext); export const useStepsContext = () => useContext(StepsContext);
@@ -51,6 +51,7 @@ const GPUService: React.FC = () => {
setClusterSession({ setClusterSession({
firstAddWorker: false, firstAddWorker: false,
firstAddCluster: true, firstAddCluster: true,
presetClusterType: 'gpu',
providerHint: ProviderValueMap.Kubernetes providerHint: ProviderValueMap.Kubernetes
}); });
navigate('/resources/clusters/list'); navigate('/resources/clusters/list');