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