diff --git a/src/pages/cluster-management/cluster-create.tsx b/src/pages/cluster-management/cluster-create.tsx index 32b1ab12..c52be6a7 100644 --- a/src/pages/cluster-management/cluster-create.tsx +++ b/src/pages/cluster-management/cluster-create.tsx @@ -1,13 +1,12 @@ import { clusterSessionAtom } from '@/atoms/clusters'; import { PageAction } from '@/config'; import { PageActionType } from '@/config/types'; -import PageBreadcrumb from '@/pages/_components/page-breadcrumb'; +import ColumnWrapper from '@/pages/_components/column-wrapper'; import { useIntl, useNavigate, useSearchParams } from '@umijs/max'; import { useAtom } from 'jotai'; import _ from 'lodash'; import React, { useEffect, useMemo, useRef, useState } from 'react'; import styled from 'styled-components'; -import { PageContainerInner } from '../_components/page-box'; import { createCluster, queryClusterList, @@ -38,10 +37,28 @@ const Container = styled.div` `; const Content = styled.div` - width: 600px; + width: 100%; `; -const ClusterCreate = () => { +const StepsWrapper = styled.div` + width: 230px; + padding-inline: 24px; + padding-block: 16px; + // background-color: var(--ant-color-fill-quaternary); + border-right: 1px solid var(--ant-color-split); + .ant-steps.ant-steps-vertical { + height: 600px; + } +`; + +const MainWrapper = styled.div` + display: flex; + height: 100%; +`; + +const ClusterCreate: React.FC<{ + onClose?: () => void; +}> = ({ onClose }) => { const intl = useIntl(); const startStep = 0; const stepList = useStepList(); @@ -297,10 +314,12 @@ const ClusterCreate = () => { firstAddCluster: false, firstAddWorker: false }); - navigate(`/cluster-management/clusters/list`); + // navigate(`/cluster-management/clusters/list`); + onClose?.(); return; } - navigate(-1); + onClose?.(); + // navigate(-1); }; const breadcrumbItems = [ @@ -314,46 +333,55 @@ const ClusterCreate = () => { ]; return ( - - ]} - header={{ - title: - }} - > - -
- {currentStep === startStep && ( - + + + + - )} - - {renderModules()} - - {renderForms()} - - -
-
+ } + > +
+ {currentStep === startStep && ( + + )} + + {renderModules()} + + {renderForms()} + + +
+ + ); }; diff --git a/src/pages/cluster-management/cluster-modal.tsx b/src/pages/cluster-management/cluster-modal.tsx new file mode 100644 index 00000000..eccd085d --- /dev/null +++ b/src/pages/cluster-management/cluster-modal.tsx @@ -0,0 +1,37 @@ +import GSDrawer from '@/components/scroller-modal/gs-drawer'; +import React from 'react'; +import ClusterCreate from './cluster-create'; + +interface ClusterModalProps { + open: boolean; + onClose: () => void; +} + +const ClusterModal: React.FC = ({ open, onClose }) => { + const handleCancel = () => { + onClose(); + }; + + return ( + + + + ); +}; + +export default ClusterModal; diff --git a/src/pages/cluster-management/clusters.tsx b/src/pages/cluster-management/clusters.tsx index 3d6579a2..420ea8ff 100644 --- a/src/pages/cluster-management/clusters.tsx +++ b/src/pages/cluster-management/clusters.tsx @@ -30,6 +30,7 @@ import { updateCluster, WORKER_POOLS_API } from './apis'; +import ClusterModal from './cluster-modal'; import AddCluster from './components/add-cluster'; import AddPool from './components/add-pool'; import { @@ -47,6 +48,7 @@ import { } from './config/types'; import useAddWorker from './hooks/use-add-worker'; import useClusterColumns from './hooks/use-cluster-columns'; +import useCreateCluster from './hooks/use-create-cluster'; const Clusters: React.FC = () => { const { @@ -77,6 +79,10 @@ const Clusters: React.FC = () => { const intl = useIntl(); const { handleAddWorker, checkDefaultCluster, AddWorkerModal, setStepList } = useAddWorker({}); + const { clusterModalStatus, openClusterModal, closeClusterModal } = + useCreateCluster({ + refresh: handleSearch + }); const [openAddModal, setOpenAddModal] = useState<{ open: boolean; @@ -124,7 +130,7 @@ const Clusters: React.FC = () => { }; const handleClickDropdown = () => { - navigate(`/cluster-management/clusters/create?action=${PageAction.CREATE}`); + openClusterModal(); }; const handleModalOk = async (data: FormData) => { @@ -396,6 +402,10 @@ const Clusters: React.FC = () => { onOk={handleSubmitWorkerPool} > + {AddWorkerModal} ); diff --git a/src/pages/cluster-management/components/cluster-steps.tsx b/src/pages/cluster-management/components/cluster-steps.tsx index ac1a4e88..eab09dbb 100644 --- a/src/pages/cluster-management/components/cluster-steps.tsx +++ b/src/pages/cluster-management/components/cluster-steps.tsx @@ -7,8 +7,7 @@ const { Step } = Steps; const Wrapper = styled.div` width: min(1200px, 100%); margin: 0 auto; - padding-block: 30px; - background-color: var(--ant-color-bg-container); + padding-block: 0px; .ant-steps-item-description { max-width: 300px !important; color: var(--ant-color-text-description) !important; @@ -24,7 +23,12 @@ const ClusterSteps: React.FC<{ return ( - + {steps.map((step) => ( = (props) => { onNext(); }; return ( - - <div className="flex-center gap-16"> + <Title style={{ padding: '16px 24px 32px' }}> + <div className="flex-center gap-20"> {showButtons.previous && ( - <Button type="link" icon={<LeftOutlined />} onClick={onPrevious}> + <Button type="default" icon={<LeftOutlined />} onClick={onPrevious}> {intl.formatMessage({ id: 'common.button.prev' })} </Button> )} {showButtons.next && ( - <Button type="link" onClick={handleOnNext}> + <Button + type="primary" + onClick={handleOnNext} + style={{ minWidth: 100 }} + > {intl.formatMessage({ id: 'common.button.next' })} <RightOutlined /> </Button> @@ -62,7 +66,8 @@ const FooterButtons: React.FC<FooterButtonsProps> = (props) => { style={{ minWidth: 88 }} loading={loading} > - {intl.formatMessage({ id: 'common.button.save' })} + {/* {intl.formatMessage({ id: 'common.button.save' })} */} + Create & Continue </Button> )} </div> diff --git a/src/pages/cluster-management/components/provider-catalog.tsx b/src/pages/cluster-management/components/provider-catalog.tsx index cef96d07..5aef2af1 100644 --- a/src/pages/cluster-management/components/provider-catalog.tsx +++ b/src/pages/cluster-management/components/provider-catalog.tsx @@ -1,3 +1,4 @@ +import IconFont from '@/components/icon-font'; import Card from '@/components/templates/card'; import { useIntl } from '@umijs/max'; import React, { useMemo } from 'react'; @@ -10,7 +11,7 @@ const Wrapper = styled.div<{ $cols?: number }>` grid-template-columns: repeat(${(props) => props.$cols || 3}, 1fr); gap: 16px; .template-card-wrapper { - padding: 10px; + padding: 10px 16px; } .template-card-inner { justify-content: center; @@ -21,16 +22,26 @@ const Container = styled.div` display: flex; margin: 0 auto; flex-direction: column; - gap: 16px; + gap: 24px; `; const Title = styled.span` display: flex; + gap: 8px; align-items: center; - justify-content: space-between; font-weight: 700; - font-size: 16px; - margin-block: 20px 16px; + font-size: 14px; + margin-bottom: 16px; + .icon { + color: var(--ant-color-text-secondary); + border-radius: 4px; + display: flex; + align-items: center; + justify-content: center; + width: 24px; + height: 24px; + background-color: var(--ant-color-fill-tertiary); + } `; const Header = styled.div` @@ -38,6 +49,9 @@ const Header = styled.div` flex-direction: column; align-items: flex-start; gap: 4px; + .title { + font-weight: 500; + } .description { font-size: 13px; font-weight: 400; @@ -47,6 +61,7 @@ const Header = styled.div` interface ProviderCatalogProps { onSelect?: (provider: string, item: any) => void; + groupIcons?: Record<string, string>; cols?: number; current?: ProviderType | string; clickable?: boolean; @@ -64,6 +79,7 @@ interface ProviderCatalogProps { const ProviderCatalog: React.FC<ProviderCatalogProps> = ({ onSelect, + groupIcons, cols = 3, dataList, clickable, @@ -86,7 +102,7 @@ const ProviderCatalog: React.FC<ProviderCatalogProps> = ({ const renderTitle = (item: any) => { return ( <Header> - <span> + <span className="title"> {item.locale ? intl.formatMessage({ id: item.label }) : item.label} </span> {item.description && ( @@ -103,7 +119,14 @@ const ProviderCatalog: React.FC<ProviderCatalogProps> = ({ {Object.entries(groupList).map(([groupName, items]) => ( <div key={groupName}> {groupName !== 'default' && ( - <Title>{intl.formatMessage({ id: groupName })} + + {groupIcons && groupIcons[groupName] && ( + <span className="icon"> + <IconFont type={groupIcons[groupName]} /> + </span> + )} + <span>{intl.formatMessage({ id: groupName })}</span> + )} {items?.map((action) => ( diff --git a/src/pages/cluster-management/components/support-gpus.tsx b/src/pages/cluster-management/components/support-gpus.tsx index 74fd95cd..8c9bbaea 100644 --- a/src/pages/cluster-management/components/support-gpus.tsx +++ b/src/pages/cluster-management/components/support-gpus.tsx @@ -141,11 +141,11 @@ const SupportedHardware: React.FC = ({ ); diff --git a/src/pages/cluster-management/hooks/use-create-cluster.tsx b/src/pages/cluster-management/hooks/use-create-cluster.tsx new file mode 100644 index 00000000..c1a05e4d --- /dev/null +++ b/src/pages/cluster-management/hooks/use-create-cluster.tsx @@ -0,0 +1,26 @@ +import { useState } from 'react'; + +const useCreateCluster = (options: { refresh: () => void }) => { + const [clusterModalStatus, setClusterModalStatus] = useState<{ + open: boolean; + }>({ + open: false + }); + + const openClusterModal = () => { + setClusterModalStatus({ open: true }); + }; + + const closeClusterModal = () => { + setClusterModalStatus({ open: false }); + options.refresh(); + }; + + return { + clusterModalStatus, + openClusterModal, + closeClusterModal + }; +}; + +export default useCreateCluster; diff --git a/src/pages/cluster-management/step-forms/basic-form.tsx b/src/pages/cluster-management/step-forms/basic-form.tsx index a7b52860..72a91726 100644 --- a/src/pages/cluster-management/step-forms/basic-form.tsx +++ b/src/pages/cluster-management/step-forms/basic-form.tsx @@ -10,8 +10,8 @@ const Title = styled.span` display: flex; align-items: center; justify-content: space-between; - font-weight: 700; - font-size: 16px; + font-weight: 600; + font-size: 14px; .text { font-size: 20px; } diff --git a/src/pages/cluster-management/step-forms/worker-pools-form.tsx b/src/pages/cluster-management/step-forms/worker-pools-form.tsx index 4474ec6e..76382b50 100644 --- a/src/pages/cluster-management/step-forms/worker-pools-form.tsx +++ b/src/pages/cluster-management/step-forms/worker-pools-form.tsx @@ -30,8 +30,8 @@ const Title = styled.span` display: flex; align-items: center; justify-content: space-between; - font-weight: 700; - font-size: 16px; + font-weight: 600; + font-size: 14px; .text { font-size: 20px; }