From 8607815240f7e6ce2f26a4ccd144711c0056c285 Mon Sep 17 00:00:00 2001 From: jialin Date: Wed, 10 Jul 2024 17:14:04 +0800 Subject: [PATCH] fix: delete worker --- src/components/copy-button/index.tsx | 2 +- src/components/echarts/config.ts | 11 ++- src/components/echarts/line-chart.tsx | 12 ++- src/components/echarts/types.ts | 2 + .../seal-table/components/table-row.tsx | 2 - src/components/status-tag/index.tsx | 14 +++- src/locales/en-US/resources.ts | 3 +- src/locales/zh-CN/resources.ts | 3 +- .../components/resource-utilization.tsx | 5 ++ .../llmodels/components/instance-item.tsx | 3 +- src/pages/llmodels/config/index.ts | 2 +- src/pages/llmodels/config/types.ts | 1 + src/pages/resources/apis/index.ts | 6 ++ src/pages/resources/components/workers.tsx | 79 ++++++++++++++++++- 14 files changed, 129 insertions(+), 16 deletions(-) diff --git a/src/components/copy-button/index.tsx b/src/components/copy-button/index.tsx index 70c91406..bfeade4a 100644 --- a/src/components/copy-button/index.tsx +++ b/src/components/copy-button/index.tsx @@ -31,7 +31,7 @@ const CopyButton: React.FC = ({ > {copied ? ( ) : ( any) { let result = `${params[0].axisValue}`; params.forEach((item: any) => { + let value = isFunction(callback) + ? callback?.(item.data.value) + : item.data.value; result += ` ${item.seriesName}: - ${item.data.value} + ${value} `; }); return `
${result}
`; @@ -55,6 +59,9 @@ export const xAxis = { export const yAxis = { // max: 100, // min: 0, + nameTextStyle: { + padding: [0, 0, 0, -25] + }, splitLine: { show: true, lineStyle: { diff --git a/src/components/echarts/line-chart.tsx b/src/components/echarts/line-chart.tsx index dbaac96c..075b6103 100644 --- a/src/components/echarts/line-chart.tsx +++ b/src/components/echarts/line-chart.tsx @@ -17,9 +17,11 @@ const LineChart: React.FC = (props) => { const { seriesData, xAxisData, + yAxisName, height, width, labelFormatter, + tooltipValueFormatter = null, legendData = [], smooth, title @@ -34,7 +36,12 @@ const LineChart: React.FC = (props) => { }, grid, tooltip: { - ...tooltip + ...tooltip, + formatter(params: any) { + return tooltipValueFormatter + ? tooltip.formatter(params, tooltipValueFormatter) + : tooltip.formatter(params); + } }, xAxis: { ...xAxis, @@ -76,7 +83,8 @@ const LineChart: React.FC = (props) => { text: title }, yAxis: { - ...options.yAxis + ...options.yAxis, + name: yAxisName }, xAxis: { ...options.xAxis, diff --git a/src/components/echarts/types.ts b/src/components/echarts/types.ts index 28116a77..839100e9 100644 --- a/src/components/echarts/types.ts +++ b/src/components/echarts/types.ts @@ -3,12 +3,14 @@ export interface ChartProps { xAxisData: string[]; legendData?: string[]; labelFormatter?: (val?: any) => string; + tooltipValueFormatter?: (val?: any) => string; height: string | number; width?: string | number; title?: string; value?: number; smooth?: boolean; color?: string; + yAxisName?: string; } export interface AreaChartItemProps { diff --git a/src/components/seal-table/components/table-row.tsx b/src/components/seal-table/components/table-row.tsx index abb7f1ea..5cd57a02 100644 --- a/src/components/seal-table/components/table-row.tsx +++ b/src/components/seal-table/components/table-row.tsx @@ -170,8 +170,6 @@ const TableRow: React.FC< useEffect(() => { if (!firstLoad && expanded) { createChunkRequest(); - } else { - chunkRequestRef.current?.current?.cancel?.(); } return () => { chunkRequestRef.current?.current?.cancel?.(); diff --git a/src/components/status-tag/index.tsx b/src/components/status-tag/index.tsx index eb035d3d..26f45c29 100644 --- a/src/components/status-tag/index.tsx +++ b/src/components/status-tag/index.tsx @@ -1,5 +1,7 @@ import { StatusColorMap } from '@/config'; import { StatusType } from '@/config/types'; +import { InfoCircleOutlined } from '@ant-design/icons'; +import { Tooltip } from 'antd'; import classNames from 'classnames'; import { useEffect, useState } from 'react'; import './index.less'; @@ -16,6 +18,7 @@ type StatusTagProps = { statusValue: { status: StatusType; text: string; + message?: string; }; download?: { percent: number; @@ -56,7 +59,16 @@ const StatusTag: React.FC = ({ statusValue, download }) => { border: `1px solid ${statusColor?.text}` }} > - {renderContent()} + {statusValue.message ? ( + + + + + {renderContent()} + + ) : ( + renderContent() + )} ); }; diff --git a/src/locales/en-US/resources.ts b/src/locales/en-US/resources.ts index 03f63789..4660f6dd 100644 --- a/src/locales/en-US/resources.ts +++ b/src/locales/en-US/resources.ts @@ -16,5 +16,6 @@ export default { 'resources.table.gpuutilization': 'GPU Utilization', 'resources.table.vramutilization': 'VRAM Utilization', 'resources.table.total': 'Total', - 'resources.table.used': 'Used' + 'resources.table.used': 'Used', + 'resources.table.wokers': 'workers' }; diff --git a/src/locales/zh-CN/resources.ts b/src/locales/zh-CN/resources.ts index b020eed8..070a1e5c 100644 --- a/src/locales/zh-CN/resources.ts +++ b/src/locales/zh-CN/resources.ts @@ -16,5 +16,6 @@ export default { 'resources.table.gpuutilization': 'GPU 利用率', 'resources.table.vramutilization': '显存利用率', 'resources.table.total': '总量', - 'resources.table.used': '已用' + 'resources.table.used': '已用', + 'resources.table.wokers': 'workers' }; diff --git a/src/pages/dashboard/components/resource-utilization.tsx b/src/pages/dashboard/components/resource-utilization.tsx index 81f079b8..08315ec6 100644 --- a/src/pages/dashboard/components/resource-utilization.tsx +++ b/src/pages/dashboard/components/resource-utilization.tsx @@ -116,6 +116,9 @@ const UtilizationOvertime: React.FC = () => { const typeList = ['gpu', 'cpu', 'memory', 'gpu_memory']; + const tooltipValueFormatter = (value: any) => { + return !value ? value : `${value}%`; + }; const generateData = () => { const legendData: string[] = []; const xAxisData: string[] = []; @@ -154,8 +157,10 @@ const UtilizationOvertime: React.FC = () => { seriesData={seriesData} legendData={legendData} xAxisData={xAxisData} + tooltipValueFormatter={tooltipValueFormatter} smooth={true} width="100%" + yAxisName="(%)" > ); diff --git a/src/pages/llmodels/components/instance-item.tsx b/src/pages/llmodels/components/instance-item.tsx index c52dbcb7..b28803df 100644 --- a/src/pages/llmodels/components/instance-item.tsx +++ b/src/pages/llmodels/components/instance-item.tsx @@ -93,7 +93,8 @@ const InstanceItem: React.FC = ({ } statusValue={{ status: status[item.state] as any, - text: item.state + text: item.state, + message: item.state_message }} > )} diff --git a/src/pages/llmodels/config/index.ts b/src/pages/llmodels/config/index.ts index ba03bf14..c7f1b7b4 100644 --- a/src/pages/llmodels/config/index.ts +++ b/src/pages/llmodels/config/index.ts @@ -33,7 +33,7 @@ export const status: any = { [InstanceStatusMap.Running]: StatusMaps.success, [InstanceStatusMap.Pending]: StatusMaps.transitioning, [InstanceStatusMap.Initializing]: StatusMaps.transitioning, - [InstanceStatusMap.Scheduled]: StatusMaps.success, + [InstanceStatusMap.Scheduled]: StatusMaps.transitioning, [InstanceStatusMap.Error]: StatusMaps.error, [InstanceStatusMap.Downloading]: StatusMaps.transitioning, [InstanceStatusMap.Unknown]: StatusMaps.inactive, diff --git a/src/pages/llmodels/config/types.ts b/src/pages/llmodels/config/types.ts index 6dd60301..59f5eab0 100644 --- a/src/pages/llmodels/config/types.ts +++ b/src/pages/llmodels/config/types.ts @@ -34,6 +34,7 @@ export interface ModelInstanceListItem { port: number; name: string; state: string; + state_message: string; download_progress: number; model_id: number; model_name: string; diff --git a/src/pages/resources/apis/index.ts b/src/pages/resources/apis/index.ts index 3f06fde9..e939528e 100644 --- a/src/pages/resources/apis/index.ts +++ b/src/pages/resources/apis/index.ts @@ -27,3 +27,9 @@ export async function queryGPUDeviceItem(id: string) { methos: 'GET' }); } + +export async function deleteWorker(id: string | number) { + return request(`${WORKERS_API}/${id}`, { + method: 'DELETE' + }); +} diff --git a/src/pages/resources/components/workers.tsx b/src/pages/resources/components/workers.tsx index 1a5d4657..b2cb6ce9 100644 --- a/src/pages/resources/components/workers.tsx +++ b/src/pages/resources/components/workers.tsx @@ -1,14 +1,15 @@ import PageTools from '@/components/page-tools'; import ProgressBar from '@/components/progress-bar'; import StatusTag from '@/components/status-tag'; +import useTableRowSelection from '@/hooks/use-table-row-selection'; import useTableSort from '@/hooks/use-table-sort'; -import { convertFileSize } from '@/utils'; -import { SyncOutlined } from '@ant-design/icons'; +import { convertFileSize, handleBatchRequest } from '@/utils'; +import { DeleteOutlined, SyncOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; -import { Button, Input, Space, Table } from 'antd'; +import { Button, Input, Modal, Space, Table, Tooltip, message } from 'antd'; import _ from 'lodash'; import { memo, useEffect, useState } from 'react'; -import { queryWorkersList } from '../apis'; +import { deleteWorker, queryWorkersList } from '../apis'; import { Filesystem, GPUDeviceItem, ListItem } from '../config/types'; const { Column } = Table; @@ -18,6 +19,7 @@ const Resources: React.FC = () => { const { sortOrder, setSortOrder } = useTableSort({ defaultSortOrder: 'descend' }); + const rowSelection = useTableRowSelection(); const intl = useIntl(); const [total, setTotal] = useState(0); const [loading, setLoading] = useState(false); @@ -90,6 +92,44 @@ const Resources: React.FC = () => { return mountRoot ? formateUtilazation(mountRoot.used, mountRoot.total) : 0; }; + const handleDelete = (row: ListItem) => { + Modal.confirm({ + title: '', + content: intl.formatMessage( + { id: 'common.delete.confirm' }, + { type: ' worker ' } + ), + async onOk() { + console.log('OK'); + await deleteWorker(row.id); + message.success(intl.formatMessage({ id: 'common.message.success' })); + fetchData(); + }, + onCancel() { + console.log('Cancel'); + } + }); + }; + + const handleDeleteBatch = () => { + Modal.confirm({ + title: '', + content: intl.formatMessage( + { id: 'common.delete.confirm' }, + { type: ` wokers ` } + ), + async onOk() { + await handleBatchRequest(rowSelection.selectedRowKeys, deleteWorker); + message.success(intl.formatMessage({ id: 'common.message.success' })); + rowSelection.clearSelections(); + fetchData(); + }, + onCancel() { + console.log('Cancel'); + } + }); + }; + const renderStorageTooltip = (files: Filesystem[]) => { const mountRoot = _.find( files, @@ -137,12 +177,23 @@ const Resources: React.FC = () => { > } + right={ + + } > { ); }} /> + { + return ( + + + + + + ); + }} + />
);