style: cluster creation steps

This commit is contained in:
jialin
2026-01-06 17:21:32 +08:00
parent 0ba8300959
commit 0eba1da6c4
21 changed files with 223 additions and 79 deletions
+10 -10
View File
@@ -199,16 +199,16 @@ export default [
hideInMenu: true, hideInMenu: true,
component: './cluster-management/cluster-detail' component: './cluster-management/cluster-detail'
}, },
{ // {
name: 'clusterCreate', // name: 'clusterCreate',
path: '/cluster-management/clusters/create', // path: '/cluster-management/clusters/create',
key: 'clusterCreate', // key: 'clusterCreate',
icon: 'icon-cluster2-outline', // icon: 'icon-cluster2-outline',
selectedIcon: 'icon-cluster2-filled', // selectedIcon: 'icon-cluster2-filled',
defaultIcon: 'icon-cluster2-outline', // defaultIcon: 'icon-cluster2-outline',
hideInMenu: true, // hideInMenu: true,
component: './cluster-management/cluster-create' // component: './cluster-management/cluster-create'
}, // },
{ {
name: 'credentials', name: 'credentials',
path: '/cluster-management/credentials', path: '/cluster-management/credentials',
+3
View File
@@ -23,6 +23,8 @@ const Wrapper = styled.div<{ $token: any }>`
--ant-table-row-hover-bg: ${(props) => props.$token.rowHoverBg}; --ant-table-row-hover-bg: ${(props) => props.$token.rowHoverBg};
--ant-table-header-icon-color: ${(props) => --ant-table-header-icon-color: ${(props) =>
props.$token.tableHeaderIconColor}; props.$token.tableHeaderIconColor};
--ant-table-header-icon-hover-color: ${(props) =>
props.$token.tableHeaderIconHoverColor};
`; `;
const SealTable: React.FC<SealTableProps & { pagination: PaginationProps }> = ( const SealTable: React.FC<SealTableProps & { pagination: PaginationProps }> = (
@@ -152,6 +154,7 @@ const SealTable: React.FC<SealTableProps & { pagination: PaginationProps }> = (
$token={{ $token={{
...token.Table, ...token.Table,
tableHeaderIconColor: token.colorTextQuaternary, tableHeaderIconColor: token.colorTextQuaternary,
tableHeaderIconHoverColor: token.colorTextSecondary,
colorBorderSecondary: token.colorBorderSecondary colorBorderSecondary: token.colorBorderSecondary
}} }}
> >
@@ -38,6 +38,16 @@
justify-content: center; justify-content: center;
} }
&:hover {
.sorter-header {
.sorter {
.anticon {
color: var(--ant-table-header-icon-hover-color);
}
}
}
}
.sorter-header { .sorter-header {
display: flex; display: flex;
flex: 1; flex: 1;
@@ -55,6 +65,7 @@
.anticon { .anticon {
font-size: 12px; font-size: 12px;
color: var(--ant-table-header-icon-color); color: var(--ant-table-header-icon-color);
transition: color var(--ant-motion-duration-slow);
} }
.sorter-up { .sorter-up {
+4 -1
View File
@@ -25,7 +25,10 @@ export default {
cellFontSize: 14, cellFontSize: 14,
rowSelectedHoverBg: '#1d1d1d', rowSelectedHoverBg: '#1d1d1d',
rowHoverBg: '#1d1d1d', rowHoverBg: '#1d1d1d',
rowSelectedBg: 'transparent' rowSelectedBg: 'transparent',
headerSortActiveBg: 'transparent',
headerSortHoverBg: 'transparent',
headerBg: 'none'
}, },
Button: { Button: {
contentFontSizeLG: 14, contentFontSizeLG: 14,
+4 -1
View File
@@ -25,7 +25,10 @@ export default {
cellFontSize: 14, cellFontSize: 14,
rowSelectedHoverBg: 'rgb(249 249 249)', rowSelectedHoverBg: 'rgb(249 249 249)',
rowHoverBg: 'rgb(249 249 249)', rowHoverBg: 'rgb(249 249 249)',
rowSelectedBg: 'transparent' rowSelectedBg: 'transparent',
headerSortActiveBg: 'transparent',
headerSortHoverBg: 'transparent',
headerBg: 'none'
}, },
Button: { Button: {
contentFontSizeLG: 14, contentFontSizeLG: 14,
+2 -2
View File
@@ -322,12 +322,12 @@ export default (props: any) => {
}} }}
modal={{ modal={{
mask: { mask: {
blur: false blur: true
} }
}} }}
drawer={{ drawer={{
mask: { mask: {
blur: false blur: true
} }
}} }}
> >
+3 -3
View File
@@ -211,8 +211,8 @@ export const yamlTemplate = `# ----------------------------------------
# - run_command: optional # - run_command: optional
# - entrypoint: optional # - entrypoint: optional
# - custom_framework: # - custom_framework:
# - optional # - required
# - choose from: ${Object.values(GPUDriverMap).join(', ')}, CPU # - choose from: ${Object.values(GPUDriverMap).join(', ')}, cpu
backend_name: vllm-custom backend_name: vllm-custom
description: this is my custom vllm backend description: this is my custom vllm backend
@@ -231,5 +231,5 @@ version_configs:
image_name: lm/vllm:test image_name: lm/vllm:test
entrypoint: entrypoint:
run_command: run_command:
custom_framework: custom_framework: rocm
`; `;
+33 -24
View File
@@ -44,7 +44,7 @@ const Content = styled.div`
`; `;
const StepsWrapper = styled.div` const StepsWrapper = styled.div`
width: 240px; width: 220px;
padding-inline: 24px; padding-inline: 24px;
padding-block: 16px; padding-block: 16px;
border-right: 1px solid var(--ant-color-split); border-right: 1px solid var(--ant-color-split);
@@ -87,6 +87,8 @@ const ClusterCreate: React.FC<{
} as ClusterFormData); } as ClusterFormData);
const [formValues, setFormValues] = useState<Record<string, any>>({}); const [formValues, setFormValues] = useState<Record<string, any>>({});
const [submitLoading, setSubmitLoading] = useState<boolean>(false); const [submitLoading, setSubmitLoading] = useState<boolean>(false);
const [isAddWorkerStep, setIsAddWorkerStep] = useState<boolean>(false);
const [isComplete, setIsComplete] = useState<boolean>(false);
const formRefs: Record<string, any> = { const formRefs: Record<string, any> = {
[moduleMap.BasicForm]: useRef<any>(null), [moduleMap.BasicForm]: useRef<any>(null),
@@ -238,6 +240,12 @@ const ClusterCreate: React.FC<{
}); });
}; };
// add worker or cluster registration step
const handleAddWorker = () => {
setIsAddWorkerStep(true);
onNext();
};
/** /**
* this function is used to render the modules in the current step, they are not forms * this function is used to render the modules in the current step, they are not forms
* @returns * @returns
@@ -261,6 +269,8 @@ const ClusterCreate: React.FC<{
} }
registrationInfo={registrationInfo} registrationInfo={registrationInfo}
provider={extraData.provider} provider={extraData.provider}
onSkip={onClose}
onAddWorker={handleAddWorker}
/> />
) : null; ) : null;
}); });
@@ -294,6 +304,7 @@ const ClusterCreate: React.FC<{
const res = await createCluster({ data }); const res = await createCluster({ data });
const info = await queryClusterToken({ id: res.id }); const info = await queryClusterToken({ id: res.id });
setSubmitLoading(false); setSubmitLoading(false);
setIsComplete(true);
setRegistrationInfo({ setRegistrationInfo({
...info, ...info,
cluster_id: res.id cluster_id: res.id
@@ -307,23 +318,16 @@ const ClusterCreate: React.FC<{
}; };
const handleCancel = () => { const handleCancel = () => {
// TODO: delete it if created by drawer
// if (clusterSession?.firstAddCluster) {
// setClusterSession({
// firstAddCluster: false,
// firstAddWorker: false
// });
// onClose?.();
// return;
// }
onClose?.(); onClose?.();
}; };
return ( return (
<MainWrapper> <MainWrapper>
<StepsWrapper> {/* {!isAddWorkerStep && (
<ClusterSteps steps={steps} currentStep={currentStep}></ClusterSteps> <StepsWrapper>
</StepsWrapper> <ClusterSteps steps={steps} currentStep={currentStep}></ClusterSteps>
</StepsWrapper>
)} */}
<ColumnWrapper <ColumnWrapper
styles={{ styles={{
container: { paddingTop: 16, paddingBottom: 16 } container: { paddingTop: 16, paddingBottom: 16 }
@@ -340,19 +344,24 @@ const ClusterCreate: React.FC<{
/> />
} }
> >
<Title level={5} style={{ marginBottom: 8 }}> {/* {!isComplete && (
{steps[currentStep]?.subTitle || steps[currentStep]?.title} <div style={{ marginBottom: 24 }}>
</Title> <Title level={5} style={{ marginBottom: 8, fontSize: 14 }}>
<Text type="secondary"> {steps[currentStep]?.subTitle || steps[currentStep]?.title}
{steps[currentStep]?.description || steps[currentStep]?.content} </Title>
</Text> </div>
<div style={{ flex: 1, marginTop: 32 }}> )} */}
{!isAddWorkerStep && (
<div style={{ marginBottom: 32 }}>
<ClusterSteps
steps={steps}
currentStep={currentStep}
></ClusterSteps>
</div>
)}
<div style={{ flex: 1 }}>
{currentStep === startStep && ( {currentStep === startStep && (
<ProviderCatalog <ProviderCatalog
groupIcons={{
'clusters.create.provider.self': 'icon-server02',
'clusters.create.provider.cloud': 'icon-cloud'
}}
cols={2} cols={2}
dataList={providerList} dataList={providerList}
height={70} height={70}
@@ -4,17 +4,22 @@ import ClusterCreate from './cluster-create';
interface ClusterModalProps { interface ClusterModalProps {
open: boolean; open: boolean;
title: string;
onClose: () => void; onClose: () => void;
} }
const ClusterModal: React.FC<ClusterModalProps> = ({ open, onClose }) => { const ClusterModal: React.FC<ClusterModalProps> = ({
open,
onClose,
title
}) => {
const handleCancel = () => { const handleCancel = () => {
onClose(); onClose();
}; };
return ( return (
<GSDrawer <GSDrawer
title={'Create Cluster'} title={title}
open={open} open={open}
onClose={handleCancel} onClose={handleCancel}
destroyOnHidden={true} destroyOnHidden={true}
@@ -25,7 +30,7 @@ const ClusterModal: React.FC<ClusterModalProps> = ({ open, onClose }) => {
body: { body: {
paddingBlock: 0 paddingBlock: 0
}, },
wrapper: { width: 900 } wrapper: { width: 700 }
}} }}
footer={false} footer={false}
> >
@@ -411,6 +411,9 @@ const Clusters: React.FC = () => {
></AddPool> ></AddPool>
<DeleteModal ref={modalRef}></DeleteModal> <DeleteModal ref={modalRef}></DeleteModal>
<ClusterModal <ClusterModal
title={intl.formatMessage({
id: 'menu.clusterManagement.clusterCreate'
})}
open={clusterModalStatus.open} open={clusterModalStatus.open}
onClose={closeClusterModal} onClose={closeClusterModal}
></ClusterModal> ></ClusterModal>
@@ -1,4 +1,5 @@
import { CheckCircleFilled, CheckCircleOutlined } from '@ant-design/icons'; import { CheckCircleFilled, CheckCircleOutlined } from '@ant-design/icons';
import { Steps } from 'antd';
import React from 'react'; import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
@@ -14,6 +15,12 @@ const Box = styled.div`
font-size: 14px; font-size: 14px;
margin-bottom: 24px; margin-bottom: 24px;
} }
.ant-steps {
--steps-title-font-size: 14px;
.ant-steps-item {
--steps-item-base-width: 20px;
}
}
`; `;
const StepItemWrapper = styled.div` const StepItemWrapper = styled.div`
@@ -86,19 +93,30 @@ const ClusterSteps: React.FC<{
}> = (props) => { }> = (props) => {
const { steps, currentStep = 0, onChange } = props; const { steps, currentStep = 0, onChange } = props;
const visibleSteps = steps.filter((step) => !step.hideInSteps);
return ( return (
<Box> <Box>
<div className="indicates">
STEP {currentStep + 1} OF {steps.length}
</div>
<Wrapper> <Wrapper>
{steps.map((item, index) => ( {/* {visibleSteps.map((item, index) => (
<StepsItem <StepsItem
key={index} key={index}
active={currentStep === index} active={currentStep === index}
item={item} item={item}
></StepsItem> ></StepsItem>
))} ))} */}
<Steps
current={currentStep}
items={visibleSteps}
type="panel"
styles={{
item: {
paddingBlock: 0
},
itemRail: {
borderColor: 'var(--ant-color-split)'
}
}}
></Steps>
</Wrapper> </Wrapper>
</Box> </Box>
); );
@@ -58,7 +58,7 @@ const FooterButtons: React.FC<FooterButtonsProps> = (props) => {
<ArrowRightOutlined /> <ArrowRightOutlined />
</Button> </Button>
)} )}
{showButtons.skip && ( {showButtons.done && (
<Button type="primary" onClick={handleCancel}> <Button type="primary" onClick={handleCancel}>
{intl.formatMessage({ id: 'common.button.done' })} {intl.formatMessage({ id: 'common.button.done' })}
</Button> </Button>
@@ -70,8 +70,7 @@ const FooterButtons: React.FC<FooterButtonsProps> = (props) => {
style={{ minWidth: 88 }} style={{ minWidth: 88 }}
loading={loading} loading={loading}
> >
{/* {intl.formatMessage({ id: 'common.button.save' })} */} {intl.formatMessage({ id: 'common.button.save' })}
Create & Continue
</Button> </Button>
)} )}
</div> </div>
@@ -0,0 +1,54 @@
import { CheckCircleFilled } from '@ant-design/icons';
import { Button, Flex, Result } from 'antd';
import React from 'react';
import { ProviderValueMap } from '../config';
const SuccessResult: React.FC<{
provider: string;
onSkip: () => void;
onAddWorker: () => void;
}> = ({ provider, onSkip, onAddWorker }) => {
const k8sTips =
'Next, register this Kubernetes cluster. You can also skip this step and register it later from the cluster list.';
const dockerTips = (
<div className="flex-column">
<span>Next, add worker to this cluster.</span>
<span>
You can also skip this step and add them later from the cluster list.
</span>
</div>
);
return (
<Result
styles={{
title: {
fontSize: 16,
fontWeight: 500
}
}}
icon={
<CheckCircleFilled
style={{ color: 'var(--ant-color-success)', fontSize: 42 }}
/>
}
status="success"
title="Cluster Created Successfully!"
subTitle={provider === ProviderValueMap.Kubernetes ? k8sTips : dockerTips}
extra={[
<Flex gap={16} justify="center" key="buttons">
<Button key="buy" onClick={onSkip}>
Skip for now
</Button>
<Button type="primary" key="console" onClick={onAddWorker}>
{provider === ProviderValueMap.Kubernetes
? 'Register Cluster'
: 'Add Worker'}
</Button>
</Flex>
]}
/>
);
};
export default SuccessResult;
@@ -44,7 +44,6 @@ const Box = styled.div`
font-size: 10px; font-size: 10px;
font-weight: 400; font-weight: 400;
background-color: var(--ant-blue-1); background-color: var(--ant-blue-1);
color: var(--ant-color-info);
} }
} }
`; `;
+6 -1
View File
@@ -1,4 +1,4 @@
import { fromClusterCreationAtom } from '@/atoms/clusters'; import { clusterSessionAtom, fromClusterCreationAtom } from '@/atoms/clusters';
import DeleteModal from '@/components/delete-modal'; import DeleteModal from '@/components/delete-modal';
import IconFont from '@/components/icon-font'; import IconFont from '@/components/icon-font';
import { FilterBar } from '@/components/page-tools'; import { FilterBar } from '@/components/page-tools';
@@ -62,6 +62,7 @@ const Credentials: React.FC = () => {
deleteAPI: deleteCredential, deleteAPI: deleteCredential,
contentForDelete: 'menu.clusterManagement.credentials' contentForDelete: 'menu.clusterManagement.credentials'
}); });
const [, setClusterSession] = useAtom(clusterSessionAtom);
const [isFromCluster, setIsFromCluster] = useAtom(fromClusterCreationAtom); const [isFromCluster, setIsFromCluster] = useAtom(fromClusterCreationAtom);
const intl = useIntl(); const intl = useIntl();
const navigate = useNavigate(); const navigate = useNavigate();
@@ -109,6 +110,10 @@ const Credentials: React.FC = () => {
} else { } else {
await createCredential({ data: params }); await createCredential({ data: params });
if (isFromCluster) { if (isFromCluster) {
setClusterSession({
firstAddWorker: false,
firstAddCluster: true
});
navigate(-1); navigate(-1);
} }
} }
@@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import AddWorkerStep from '../components/add-worker/add-worker-step'; import AddWorkerStep from '../components/add-worker/add-worker-step';
import ProviderCatalog from '../components/provider-catalog'; import ProviderCatalog from '../components/provider-catalog';
import SuccessResult from '../components/success-result';
import BasicForm from './basic-form'; import BasicForm from './basic-form';
import WorkerPoolForm from './worker-pools-form'; import WorkerPoolForm from './worker-pools-form';
@@ -8,12 +9,14 @@ export const moduleMap = {
BasicForm: 'BasicForm', BasicForm: 'BasicForm',
WorkerPoolForm: 'WorkerPoolForm', WorkerPoolForm: 'WorkerPoolForm',
ProviderCatalog: 'ProviderCatalog', ProviderCatalog: 'ProviderCatalog',
AddWorkerStep: 'AddWorkerStep' AddWorkerStep: 'AddWorkerStep',
SuccessResult: 'SuccessResult'
}; };
export const moduleRegistry: Record<string, React.ComponentType<any>> = { export const moduleRegistry: Record<string, React.ComponentType<any>> = {
[moduleMap.BasicForm]: BasicForm, [moduleMap.BasicForm]: BasicForm,
[moduleMap.WorkerPoolForm]: WorkerPoolForm, [moduleMap.WorkerPoolForm]: WorkerPoolForm,
[moduleMap.ProviderCatalog]: ProviderCatalog, [moduleMap.ProviderCatalog]: ProviderCatalog,
[moduleMap.AddWorkerStep]: AddWorkerStep [moduleMap.AddWorkerStep]: AddWorkerStep,
[moduleMap.SuccessResult]: SuccessResult
}; };
@@ -15,9 +15,9 @@ export default function useStepList() {
return useMemo( return useMemo(
() => [ () => [
{ {
title: intl.formatMessage({ id: 'clusters.table.provider' }), title: intl.formatMessage({ id: 'clusters.create.selectProvider' }),
content: 'Choose where your cluster will run.', content: '',
subTitle: 'Select Provider', subTitle: '',
description: description:
'Choose the environment where your cluster will be deployed.', 'Choose the environment where your cluster will be deployed.',
showButtons: (provider?: ProviderType) => { showButtons: (provider?: ProviderType) => {
@@ -25,7 +25,8 @@ export default function useStepList() {
previous: false, previous: false,
next: true, next: true,
save: false, save: false,
skip: false skip: false,
done: false
}; };
}, },
defaultShow: true, defaultShow: true,
@@ -35,7 +36,7 @@ export default function useStepList() {
}, },
{ {
title: intl.formatMessage({ id: 'common.title.config' }), title: intl.formatMessage({ id: 'common.title.config' }),
content: 'Configure your cluster settings.', content: '',
description: description:
'Set the cluster name, description, or other essential parameters in advanced settings.', 'Set the cluster name, description, or other essential parameters in advanced settings.',
showButtons: (provider?: ProviderType) => { showButtons: (provider?: ProviderType) => {
@@ -43,7 +44,8 @@ export default function useStepList() {
previous: true, previous: true,
next: provider === ProviderValueMap.DigitalOcean, next: provider === ProviderValueMap.DigitalOcean,
save: provider !== ProviderValueMap.DigitalOcean, save: provider !== ProviderValueMap.DigitalOcean,
skip: false skip: false,
done: false
}; };
}, },
defaultShow: true, defaultShow: true,
@@ -53,13 +55,14 @@ export default function useStepList() {
}, },
{ {
title: intl.formatMessage({ id: 'clusters.button.addNodePool' }), title: intl.formatMessage({ id: 'clusters.button.addNodePool' }),
content: 'Add worker pools to your cluster.', content: '',
showButtons: (provider?: ProviderType) => { showButtons: (provider?: ProviderType) => {
return { return {
previous: true, previous: true,
next: false, next: false,
save: true, save: true,
skip: false skip: false,
done: false
}; };
}, },
defaultShow: false, defaultShow: false,
@@ -69,37 +72,57 @@ export default function useStepList() {
beforeNext: handleBack beforeNext: handleBack
}, },
{ {
title: intl.formatMessage({ id: 'resources.button.create' }), title: 'Completed',
content: 'The cluster is created successfully.', content: '',
description: description: '',
'The cluster is now set up and you can add workers to it. You can also add workers later from the cluster list.',
showButtons: (provider?: ProviderType) => { showButtons: (provider?: ProviderType) => {
return { return {
previous: false, previous: false,
next: false, next: false,
save: false, save: false,
skip: true skip: true,
done: false
}; };
}, },
defaultShow: false, defaultShow: false,
showForms: [], showForms: [],
showModules: [moduleMap.SuccessResult],
providers: [ProviderValueMap.Docker, ProviderValueMap.Kubernetes]
},
{
title: intl.formatMessage({ id: 'resources.button.create' }),
content: '',
description: '',
showButtons: (provider?: ProviderType) => {
return {
previous: false,
next: false,
save: false,
skip: false,
done: true
};
},
defaultShow: false,
hideInSteps: true,
showForms: [],
showModules: [moduleMap.AddWorkerStep], showModules: [moduleMap.AddWorkerStep],
providers: [ProviderValueMap.Docker] providers: [ProviderValueMap.Docker]
}, },
{ {
title: intl.formatMessage({ id: 'clusters.button.register' }), title: intl.formatMessage({ id: 'clusters.button.register' }),
content: '', content: '',
description: description: '',
'Register an existing Kubernetes cluster to manage its workers. You can also register a cluster later from the cluster list.',
showButtons: (provider?: ProviderType) => { showButtons: (provider?: ProviderType) => {
return { return {
previous: false, previous: false,
next: false, next: false,
save: false, save: false,
skip: true skip: false,
done: true
}; };
}, },
defaultShow: false, defaultShow: false,
hideInSteps: true,
showForms: [], showForms: [],
showModules: [moduleMap.AddWorkerStep], showModules: [moduleMap.AddWorkerStep],
providers: [ProviderValueMap.Kubernetes] providers: [ProviderValueMap.Kubernetes]
@@ -179,7 +179,7 @@ const WorkerPoolsForm = forwardRef((props: WorkerPoolsFormProps, ref) => {
return ( return (
<div> <div>
<PageTools <PageTools
marginBottom={22} marginBottom={12}
marginTop={0} marginTop={0}
// left={ // left={
// <span className="flex-center gap-16"> // <span className="flex-center gap-16">
@@ -189,7 +189,12 @@ const WorkerPoolsForm = forwardRef((props: WorkerPoolsFormProps, ref) => {
// </span> // </span>
// } // }
left={ left={
<Button onClick={handleAddPool} type="link" icon={<PlusOutlined />}> <Button
onClick={handleAddPool}
type="link"
icon={<PlusOutlined />}
style={{ paddingInline: 0 }}
>
{intl.formatMessage({ id: 'clusters.button.addNodePool' })} {intl.formatMessage({ id: 'clusters.button.addNodePool' })}
</Button> </Button>
} }
+3 -2
View File
@@ -414,7 +414,7 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
} }
// TODO // TODO
// fetchContextLength({ ...params, source }); fetchContextLength({ ...params, source });
}, [isGGUF, source, localPath, modelScopeModelId, huggingfaceRepoId]); }, [isGGUF, source, localPath, modelScopeModelId, huggingfaceRepoId]);
return ( return (
@@ -480,7 +480,8 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
initialValues?.speculative_config?.ngram_max_match_length || 10 initialValues?.speculative_config?.ngram_max_match_length || 10
}, },
...initialValues, ...initialValues,
backend_version: initialValues?.backend_version || null backend_version: initialValues?.backend_version || null,
max_context_len: initialValues?.max_context_len || 2048
}} }}
> >
<BasicForm <BasicForm
@@ -261,7 +261,7 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef((props, ref) => {
placement: 'right' placement: 'right'
}} }}
minWidth={60} minWidth={60}
maxWidth={180} maxWidth={220}
> >
{data.label} {data.label}
</AutoTooltip> </AutoTooltip>
@@ -275,7 +275,7 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef((props, ref) => {
placement: 'right' placement: 'right'
}} }}
minWidth={60} minWidth={60}
maxWidth={180} maxWidth={220}
> >
{data.label} {data.label}
</AutoTooltip> </AutoTooltip>
+1 -1
View File
@@ -16,7 +16,7 @@
width: 100%; width: 100%;
.title { .title {
max-width: min(100%, 180px); max-width: min(100%, 230px);
min-width: min(120px, 32%); min-width: min(120px, 32%);
} }
} }