diff --git a/src/components/icon-font/icons.ts b/src/components/icon-font/icons.ts index 96436c47..fc8e022e 100644 --- a/src/components/icon-font/icons.ts +++ b/src/components/icon-font/icons.ts @@ -28,7 +28,8 @@ const icons = { ModelScope: React.createElement(IconFont, { type: 'icon-tu2' }), LocalPath: React.createElement(IconFont, { type: 'icon-hard-disk' }), Launch: React.createElement(IconFont, { type: 'icon-rocket-launch' }), - Deployment: React.createElement(IconFont, { type: 'icon-rocket-launch1' }) + Deployment: React.createElement(IconFont, { type: 'icon-rocket-launch1' }), + Docker: React.createElement(IconFont, { type: 'icon-docker' }) }; export default icons; diff --git a/src/components/icon-font/index.tsx b/src/components/icon-font/index.tsx index c3d89719..ca2555d4 100644 --- a/src/components/icon-font/index.tsx +++ b/src/components/icon-font/index.tsx @@ -2,7 +2,7 @@ import { createFromIconfontCN } from '@ant-design/icons'; // import './iconfont/iconfont.js'; const IconFont = createFromIconfontCN({ - scriptUrl: '//at.alicdn.com/t/c/font_4613488_pouhrqmodr9.js' + scriptUrl: '//at.alicdn.com/t/c/font_4613488_arejw0wk0kd.js' }); export default IconFont; diff --git a/src/components/scroller-modal/gs-drawer.tsx b/src/components/scroller-modal/gs-drawer.tsx index 64464ff8..2d3c55e8 100644 --- a/src/components/scroller-modal/gs-drawer.tsx +++ b/src/components/scroller-modal/gs-drawer.tsx @@ -1,15 +1,40 @@ import { useEscHint } from '@/hooks/use-esc-hint'; -import { Drawer, type DrawerProps } from 'antd'; +import { CloseOutlined } from '@ant-design/icons'; +import { Button, Drawer, type DrawerProps } from 'antd'; const ScrollerModal = (props: DrawerProps) => { + const { title, closable = true, ...restProps } = props; const { EscHint } = useEscHint({ enabled: !props.keyboard && props.open }); - + const handleCancel = (e: React.MouseEvent) => { + props.onClose?.(e); + }; return ( <> - - {props.children} + + + {title} + + {closable && ( + + )} + + } + > + {restProps.children} {EscHint} diff --git a/src/pages/cluster-management/clusters.tsx b/src/pages/cluster-management/clusters.tsx index 48918cc7..95e2f10f 100644 --- a/src/pages/cluster-management/clusters.tsx +++ b/src/pages/cluster-management/clusters.tsx @@ -15,16 +15,16 @@ import { } from '@ant-design/icons'; import { PageContainer } from '@ant-design/pro-components'; import { useIntl } from '@umijs/max'; -import { Empty, Table, message } from 'antd'; +import { Table, message } from 'antd'; import { useState } from 'react'; -import styled from 'styled-components'; import { - createCredential, - deleteCredential, - queryCredentialList, - updateCredential + createCluster, + deleteCluster, + queryClusterList, + updateCluster } from './apis'; import AddCluster from './components/add-cluster'; +import ClusterDetailModal from './components/cluster-detail-modal'; import ClusterItem from './components/cluster-item'; import { ClusterDataList } from './config'; import { @@ -57,39 +57,6 @@ const addActions = [ } ]; -const WorkerWrapper = styled.div` - display: flex; - flex-direction: column; - gap: 4px; - align-items: flex-start; - .worker { - display: flex; - align-items: center; - gap: 5px; - .value { - line-height: 1em; - color: var(--ant-color-text-secondary); - } - } - .dot { - display: inline-block; - width: 8px; - height: 8px; - border-radius: 50%; - margin-right: 4px; - &.ready { - background-color: var(--ant-color-success); - } - &.error { - background-color: var(--ant-color-error); - } - - &.transition { - background-color: var(--ant-blue-5); - } - } -`; - const ActionList = [ { key: 'edit', @@ -139,13 +106,23 @@ const Credentials: React.FC = () => { handleSearch, handleNameChange } = useTableFetch({ - fetchAPI: queryCredentialList, - deleteAPI: deleteCredential, + fetchAPI: queryClusterList, + deleteAPI: deleteCluster, contentForDelete: 'users.table.user' }); const intl = useIntl(); - const [openAddWorker, setOpenAddWorker] = useState({ + const [openClusterDetail, setOpenClusterDetail] = useState<{ + open: boolean; + id: number; + }>({ + open: false, + id: 0 + }); + const [openAddWorker, setOpenAddWorker] = useState<{ + open: boolean; + token: string; + }>({ open: false, token: '' }); @@ -202,14 +179,12 @@ const Credentials: React.FC = () => { }; try { if (action === PageAction.EDIT) { - await updateCredential({ - data: { - ...params, - id: currentData?.id - } + await updateCluster({ + data: params, + id: currentData!.id }); } else { - await createCredential({ data: params }); + await createCluster({ data: params }); } fetchData(); setOpenAddModal(false); @@ -244,6 +219,11 @@ const Credentials: React.FC = () => { setCurrentData(row); } else if (val === 'addPool') { handleAddPool(row.provider); + } else if (val === 'details') { + setOpenClusterDetail({ + open: true, + id: row.id + }); } }; @@ -251,18 +231,6 @@ const Credentials: React.FC = () => { return ; }; - const renderEmpty = (type?: string) => { - if (type !== 'Table') return; - if ( - !dataSource.loading && - dataSource.loadend && - !dataSource.dataList.length - ) { - return ; - } - return
; - }; - return ( <> { onCancel={() => setOpenAddWorker({ open: false, token: '' })} token={openAddWorker.token} > + setOpenClusterDetail({ open: false, id: 0 })} + > ); diff --git a/src/pages/cluster-management/components/cluster-detail.tsx b/src/pages/cluster-management/components/cluster-detail-content.tsx similarity index 96% rename from src/pages/cluster-management/components/cluster-detail.tsx rename to src/pages/cluster-management/components/cluster-detail-content.tsx index ca0b97be..d64347c0 100644 --- a/src/pages/cluster-management/components/cluster-detail.tsx +++ b/src/pages/cluster-management/components/cluster-detail-content.tsx @@ -16,9 +16,7 @@ const SubTitle = styled.div` `; interface ClusterDetailProps { - provider: string; data: ClusterListItem; - show: boolean; } const gaugeConfig = { @@ -41,8 +39,9 @@ const gaugeConfig = { } }; -const ClusterDetail: React.FC = ({ data, show }) => { +const ClusterDetail: React.FC = ({ data }) => { const chartHeight = 160; + const [show, setShow] = React.useState(false); const [addPoolStatus, setAddPoolStatus] = React.useState({ open: false, action: PageAction.CREATE, diff --git a/src/pages/cluster-management/components/cluster-detail-modal.tsx b/src/pages/cluster-management/components/cluster-detail-modal.tsx new file mode 100644 index 00000000..9534a0db --- /dev/null +++ b/src/pages/cluster-management/components/cluster-detail-modal.tsx @@ -0,0 +1,42 @@ +import GSDrawer from '@/components/scroller-modal/gs-drawer'; +import React from 'react'; +import ClusterDetailContent from './cluster-detail-content'; + +interface ClusterDetailModalProps { + open: boolean; + onClose?: () => void; + id: number; +} + +const ClusterDetailModal: React.FC = ({ + open, + onClose, + id: clusterId +}) => { + const [data, setData] = React.useState({ + id: 1, + name: 'kubernetes-cluster', + provider: 'kubernetes', + clusterType: 'Kubernetes', + workers: 2, + gpus: 4, + status: 'ready', + deployments: 1 + }); + const handleOnClose = () => { + onClose?.(); + }; + + return ( + + + + ); +}; + +export default ClusterDetailModal; diff --git a/src/pages/cluster-management/components/cluster-item.tsx b/src/pages/cluster-management/components/cluster-item.tsx index a5011c65..12427e05 100644 --- a/src/pages/cluster-management/components/cluster-item.tsx +++ b/src/pages/cluster-management/components/cluster-item.tsx @@ -31,9 +31,9 @@ const actionItems = [ icon: }, { - key: 'view', + key: 'details', label: 'common.button.view', - icon: + icon: }, { key: 'add_worker', diff --git a/src/pages/cluster-management/credentials.tsx b/src/pages/cluster-management/credentials.tsx index d4301bec..c037c697 100644 --- a/src/pages/cluster-management/credentials.tsx +++ b/src/pages/cluster-management/credentials.tsx @@ -34,7 +34,10 @@ import { updateCredential } from './apis'; import AddModal from './components/add-credential'; -import { FormData, ListItem } from './config/types'; +import { + CredentialFormData as FormData, + CredentialListItem as ListItem +} from './config/types'; const { Column } = Table; const ActionList = [ @@ -127,9 +130,9 @@ const Credentials: React.FC = () => { if (openModalStatus.action === PageAction.EDIT) { await updateCredential({ data: { - ...params, - id: currentData?.id - } + ...params + }, + id: currentData!.id }); } else { await createCredential({ data: params }); diff --git a/src/pages/llmodels/components/deploy-modal.tsx b/src/pages/llmodels/components/deploy-modal.tsx index 8a92b4c0..6677dad4 100644 --- a/src/pages/llmodels/components/deploy-modal.tsx +++ b/src/pages/llmodels/components/deploy-modal.tsx @@ -3,7 +3,6 @@ import ModalFooter from '@/components/modal-footer'; import GSDrawer from '@/components/scroller-modal/gs-drawer'; import { PageActionType } from '@/config/types'; import useDeferredRequest from '@/hooks/use-deferred-request'; -import { CloseOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; import { Button } from 'antd'; import _ from 'lodash'; @@ -500,14 +499,7 @@ const AddModal: FC = (props) => { return ( - {title} - - - } + title={title} open={open} onClose={handleCancel} destroyOnClose={true} diff --git a/src/pages/llmodels/config/button-actions.ts b/src/pages/llmodels/config/button-actions.ts index 1878f096..82d22aa9 100644 --- a/src/pages/llmodels/config/button-actions.ts +++ b/src/pages/llmodels/config/button-actions.ts @@ -193,7 +193,6 @@ export const modelFileActions = [ export const categoryToPathMap: Record = { [modelCategoriesMap.llm]: '/playground/chat', - [modelCategoriesMap.image]: '/playground/text-to-image', [modelCategoriesMap.text_to_speech]: '/playground/speech?type=tts', [modelCategoriesMap.speech_to_text]: '/playground/speech?type=stt', [modelCategoriesMap.reranker]: '/playground/rerank', diff --git a/src/pages/llmodels/config/index.ts b/src/pages/llmodels/config/index.ts index 2150c603..4f3fc139 100644 --- a/src/pages/llmodels/config/index.ts +++ b/src/pages/llmodels/config/index.ts @@ -330,14 +330,17 @@ export const modelCategoriesMap = { llm: 'llm' }; +export const categoryOptions = [ + { label: 'LLM', value: modelCategoriesMap.llm }, + { label: 'Embedding', value: modelCategoriesMap.embedding }, + { label: 'Reranker', value: modelCategoriesMap.reranker }, + { label: 'Text-to-Speech', value: modelCategoriesMap.text_to_speech }, + { label: 'Speech-to-Text', value: modelCategoriesMap.speech_to_text } +]; + export const modelCategories = [ { label: 'common.options.auto', value: null, locale: true }, - { label: 'LLM', value: modelCategoriesMap.llm }, - { label: 'Image', value: modelCategoriesMap.image }, - { label: 'Text-to-Speech', value: modelCategoriesMap.text_to_speech }, - { label: 'Speech-to-Text', value: modelCategoriesMap.speech_to_text }, - { label: 'Embedding', value: modelCategoriesMap.embedding }, - { label: 'Reranker', value: modelCategoriesMap.reranker } + ...categoryOptions ]; export const sourceRepoConfig = { diff --git a/src/pages/llmodels/config/types.ts b/src/pages/llmodels/config/types.ts index 598bf872..aa4ca02e 100644 --- a/src/pages/llmodels/config/types.ts +++ b/src/pages/llmodels/config/types.ts @@ -86,8 +86,6 @@ export interface DistributedServerItem { } export interface DistributedServers { - rpc_servers: DistributedServerItem[]; - ray_actors: DistributedServerItem[]; subordinate_workers: DistributedServerItem[]; } export interface ModelInstanceListItem { diff --git a/src/pages/llmodels/download/index.tsx b/src/pages/llmodels/download/index.tsx index 9955a2bc..4ce6273f 100644 --- a/src/pages/llmodels/download/index.tsx +++ b/src/pages/llmodels/download/index.tsx @@ -1,8 +1,6 @@ import ModalFooter from '@/components/modal-footer'; import GSDrawer from '@/components/scroller-modal/gs-drawer'; -import { CloseOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; -import { Button } from 'antd'; import { debounce } from 'lodash'; import React, { useCallback, useEffect, useRef, useState } from 'react'; import ColumnWrapper from '../components/column-wrapper'; @@ -127,22 +125,7 @@ const DownloadModel: React.FC = (props) => { return ( - - {title} - - - - } + title={title} open={open} onClose={handleCancel} destroyOnClose={true} diff --git a/src/pages/llmodels/user-models.tsx b/src/pages/llmodels/user-models.tsx index aac1951f..32c08538 100644 --- a/src/pages/llmodels/user-models.tsx +++ b/src/pages/llmodels/user-models.tsx @@ -5,19 +5,28 @@ import CardSkeleton from '@/components/templates/card-skelton'; import useTableFetch from '@/hooks/use-table-fetch'; import { SyncOutlined } from '@ant-design/icons'; import { PageContainer } from '@ant-design/pro-components'; -import { useIntl } from '@umijs/max'; +import { useIntl, useNavigate } from '@umijs/max'; import { Button, Input, Select, Space } from 'antd'; import React from 'react'; import { MODELS_API, queryModelsList } from './apis'; import ModelItem from './components/model-item'; +import { categoryOptions, modelCategoriesMap } from './config'; +import { categoryToPathMap } from './config/button-actions'; const UserModels: React.FC = () => { - const { dataSource, queryParams, fetchData, handleSearch, handleNameChange } = - useTableFetch({ - fetchAPI: queryModelsList, - API: MODELS_API, - watch: false - }); + const navigate = useNavigate(); + const { + dataSource, + queryParams, + fetchData, + handleSearch, + handleQueryChange, + handleNameChange + } = useTableFetch({ + fetchAPI: queryModelsList, + API: MODELS_API, + watch: false + }); const intl = useIntl(); const loadMore = () => { @@ -27,8 +36,30 @@ const UserModels: React.FC = () => { }); }; + const handleCategoryChange = (value: string) => { + handleQueryChange({ + categories: value + }); + }; + const handleOnClick = (model: any) => { - console.log('Deploying model:', model); + for (const [category, path] of Object.entries(categoryToPathMap)) { + if ( + model.categories?.includes(category) && + [ + modelCategoriesMap.text_to_speech, + modelCategoriesMap.speech_to_text + ].includes(category) + ) { + navigate(`${path}&model=${model.name}`); + return; + } + if (model.categories?.includes(category)) { + navigate(`${path}?model=${model.name}`); + return; + } + } + navigate(`/playground/chat?model=${model.name}`); }; const renderCard = (data: any) => { @@ -72,7 +103,8 @@ const UserModels: React.FC = () => { style={{ width: 180 }} size="large" maxTagCount={1} - options={[]} + options={categoryOptions} + onChange={handleCategoryChange} >