feat: instances on worker

This commit is contained in:
jialin
2025-09-16 11:26:17 +08:00
parent 949eded4ee
commit 43936e21d9
21 changed files with 589 additions and 184 deletions
@@ -0,0 +1,125 @@
import { FilterBar } from '@/components/page-tools';
import useTableFetch from '@/hooks/use-table-fetch';
import { queryClusterList } from '@/pages/cluster-management/apis';
import {
MODEL_INSTANCE_API,
queryModelsInstances
} from '@/pages/llmodels/apis';
import { InstanceStatusMap } from '@/pages/llmodels/config';
import { ModelInstanceListItem } from '@/pages/llmodels/config/types';
import { useIntl } from '@umijs/max';
import { ConfigProvider, Empty, Table } from 'antd';
import React, { useEffect, useState } from 'react';
import useInstanceColumns from '../hooks/use-instances-columns';
const statusList = Object.entries(InstanceStatusMap).map(([key, value]) => ({
label: key,
value: value
}));
const WorkerDetailContent: React.FC<{ worker_id: number | undefined }> = ({
worker_id
}) => {
const {
dataSource,
queryParams,
handlePageChange,
handleTableChange,
handleSearch,
handleQueryChange,
handleNameChange
} = useTableFetch<ModelInstanceListItem>({
fetchAPI: queryModelsInstances,
polling: false,
API: MODEL_INSTANCE_API,
defaultQueryParams: {
worker_id
}
});
const intl = useIntl();
const [clusterList, setClusterList] = useState<Global.BaseOption<number>[]>(
[]
);
const getClusterList = async () => {
try {
const res = await queryClusterList({ page: 1, perPage: 100 });
const list = res.items?.map((item) => ({
label: item.name,
value: item.id
}));
setClusterList(list || []);
} catch (error) {
setClusterList([]);
}
};
const renderEmpty = (type?: string) => {
if (type !== 'Table') return;
if (
!dataSource.loading &&
dataSource.loadend &&
!dataSource.dataList.length
) {
return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE}></Empty>;
}
return <div></div>;
};
const handleSelectChange = (value: string) => {
handleQueryChange({ state: value });
};
const columns = useInstanceColumns({
clusterList
});
useEffect(() => {
console.log('columns changed!');
}, [columns]);
useEffect(() => {
getClusterList();
}, []);
return (
<>
<FilterBar
marginBottom={22}
marginTop={0}
buttonText={intl.formatMessage({ id: 'resources.button.create' })}
handleSearch={handleSearch}
handleSelectChange={handleSelectChange}
handleInputChange={handleNameChange}
showDeleteButton={false}
showPrimaryButton={false}
selectHolder={intl.formatMessage({ id: 'resources.filter.status' })}
showSelect={true}
selectOptions={statusList}
width={{ input: 300 }}
></FilterBar>
<ConfigProvider renderEmpty={renderEmpty}>
<Table
columns={columns}
style={{ width: '100%' }}
tableLayout={dataSource.loadend ? 'auto' : 'fixed'}
dataSource={dataSource.dataList}
loading={dataSource.loading}
rowKey="id"
onChange={handleTableChange}
pagination={{
showSizeChanger: true,
pageSize: queryParams.perPage,
current: queryParams.page,
total: dataSource.total,
hideOnSinglePage: queryParams.perPage === 10,
onChange: handlePageChange
}}
></Table>
</ConfigProvider>
</>
);
};
export default WorkerDetailContent;
@@ -0,0 +1,34 @@
import GSDrawer from '@/components/scroller-modal/gs-drawer';
import React from 'react';
import { ListItem } from '../config/types';
import WorkerDetailContent from './worker-detail-content';
interface WorkerDetailModalProps {
open: boolean;
onClose?: () => void;
currentData: ListItem | null;
}
const WorkerDetailModal: React.FC<WorkerDetailModalProps> = ({
open,
onClose,
currentData
}) => {
const handleOnClose = () => {
onClose?.();
};
return (
<GSDrawer
width={'calc(100vw - 200px)'}
title={`${currentData?.name}`}
open={open}
destroyOnClose={true}
onClose={handleOnClose}
>
<WorkerDetailContent worker_id={currentData?.id} />
</GSDrawer>
);
};
export default WorkerDetailModal;
+27 -2
View File
@@ -16,6 +16,7 @@ import {
import { ListItem } from '../config/types';
import useWorkerColumns from '../hooks/use-worker-columns';
import UpdateLabels from './update-labels';
import WorkerDetailModal from './worker-detail-modal';
const Workers: React.FC = () => {
const {
@@ -55,6 +56,13 @@ const Workers: React.FC = () => {
list: [],
data: {}
});
const [workerDetailStatus, setWorkerDetailStatus] = useState<{
open: boolean;
currentData: ListItem | null;
}>({
open: false,
currentData: null
});
const getClusterList = async () => {
try {
@@ -118,6 +126,13 @@ const Workers: React.FC = () => {
});
};
const handleViewDetail = (record: ListItem) => {
setWorkerDetailStatus({
open: true,
currentData: record
});
};
const handleSelect = useMemoizedFn((val: any, record: ListItem) => {
if (val === 'edit') {
handleUpdateLabels(record);
@@ -126,6 +141,9 @@ const Workers: React.FC = () => {
if (val === 'delete') {
handleDelete(record);
}
if (val === 'details') {
handleViewDetail(record);
}
});
const renderEmpty = (type?: string) => {
@@ -149,8 +167,8 @@ const Workers: React.FC = () => {
const columns = useWorkerColumns({
clusterData,
dataSource,
extraStatus,
loadend: dataSource.loadend,
firstLoad: extraStatus.firstLoad,
handleSelect
});
@@ -216,6 +234,13 @@ const Workers: React.FC = () => {
labels: updateLabelsData.data.labels
}}
></UpdateLabels>
<WorkerDetailModal
open={workerDetailStatus.open}
currentData={workerDetailStatus.currentData}
onClose={() =>
setWorkerDetailStatus({ currentData: null, open: false })
}
/>
</PageContainer>
</>
);