diff --git a/src/components/echarts/config.ts b/src/components/echarts/config.ts index 8d5c07eb..33975fe1 100644 --- a/src/components/echarts/config.ts +++ b/src/components/echarts/config.ts @@ -100,3 +100,84 @@ export const lineItemConfig = { opacity: 0.7 } }; + +export const gaugeItemConfig = { + type: 'gauge', + radius: '88%', + center: ['50%', '65%'], + startAngle: 190, + endAngle: -10, + min: 0, + max: 100, + splitNumber: 5, + progress: { + show: true, + roundCap: false, + width: 12 + }, + pointer: { + length: '80%', + width: 4, + itemStyle: { + color: 'auto' + } + }, + axisLine: { + roundCap: false, + lineStyle: { + width: 12, + // color: [[1, 'rgba(221, 221, 221, 0.5)']], + color: [ + [0.5, 'rgba(84, 204, 152, 80%)'], + [0.8, 'rgba(250, 173, 20, 80%)'], + [1, 'rgba(255, 77, 79, 80%)'] + ] + } + }, + axisTick: { + distance: -12, + length: 6, + splitNumber: 5, + lineStyle: { + width: 1.5, + color: 'rgba(255, 255, 255, 1)' + } + }, + splitLine: { + distance: -12, + length: 12, + lineStyle: { + width: 1.5, + color: 'rgba(255, 255, 255, 1)' + } + }, + axisLabel: { + distance: 14, + color: 'rgba(0, 0, 0, .5)', + fontSize: 12 + }, + detail: { + lineHeight: 40, + height: 40, + offsetCenter: [5, 30], + valueAnimation: false, + fontSize: 20, + color: 'rgba(0, 0, 0, 0.88)', + formatter(value: any) { + return '{value|' + value + '}{unit|%}'; + }, + rich: { + value: { + fontSize: 20, + fontWeight: '500', + color: 'rgba(0, 0, 0, 0.88)' + }, + unit: { + fontSize: 16, + color: 'rgba(0, 0, 0, 0.88)', + fontWeight: '500', + padding: [0, 0, 0, 2] + } + } + } +}; diff --git a/src/components/echarts/gauge.tsx b/src/components/echarts/gauge.tsx new file mode 100644 index 00000000..f7e72ced --- /dev/null +++ b/src/components/echarts/gauge.tsx @@ -0,0 +1,63 @@ +import Chart from '@/components/echarts/chart'; +import { + gaugeItemConfig, + title as titleConfig +} from '@/components/echarts/config'; +import EmptyData from '@/components/empty-data'; +import { memo } from 'react'; +import { ChartProps } from './types'; + +const GaugeChart: React.FC> = ( + props +) => { + const { value, height, width, labelFormatter, title, color } = props; + if (!value && value !== 0) { + return ; + } + + const setDataOptions = () => { + return { + title: { + ...titleConfig, + text: title, + top: '0', + left: 'center' + }, + series: [ + { + ...gaugeItemConfig, + axisLine: { + ...gaugeItemConfig.axisLine, + lineStyle: { + ...gaugeItemConfig.axisLine.lineStyle, + color: [ + [value / 100, color], + [1, 'rgba(221, 221, 221, 0.5)'] + ] + } + }, + itemStyle: { + color: 'transparent' + }, + detail: { + ...gaugeItemConfig.detail, + formatter: labelFormatter || gaugeItemConfig.detail.formatter + }, + data: [{ value }] + } + ] + }; + }; + + const dataOptions: any = setDataOptions(); + + return ( + + ); +}; + +export default memo(GaugeChart); diff --git a/src/components/echarts/index.ts b/src/components/echarts/index.ts index f46df571..ff9533d7 100644 --- a/src/components/echarts/index.ts +++ b/src/components/echarts/index.ts @@ -1,9 +1,10 @@ import type { // 系列类型的定义后缀都为 SeriesOption BarSeriesOption, + GaugeSeriesOption, LineSeriesOption } from 'echarts/charts'; -import { BarChart, LineChart } from 'echarts/charts'; +import { BarChart, GaugeChart, LineChart } from 'echarts/charts'; import type { DatasetComponentOption, GridComponentOption, @@ -34,6 +35,7 @@ type ECOption = ComposeOption< | TooltipComponentOption | GridComponentOption | DatasetComponentOption + | GaugeSeriesOption >; // 注册必须的组件 @@ -46,6 +48,7 @@ echarts.use([ TransformComponent, BarChart, LineChart, + GaugeChart, LabelLayout, UniversalTransition, CanvasRenderer diff --git a/src/components/echarts/types.ts b/src/components/echarts/types.ts index 30308460..28116a77 100644 --- a/src/components/echarts/types.ts +++ b/src/components/echarts/types.ts @@ -6,7 +6,9 @@ export interface ChartProps { height: string | number; width?: string | number; title?: string; + value?: number; smooth?: boolean; + color?: string; } export interface AreaChartItemProps { diff --git a/src/components/icon-font/index.tsx b/src/components/icon-font/index.tsx index be8bc81b..1cdb5126 100644 --- a/src/components/icon-font/index.tsx +++ b/src/components/icon-font/index.tsx @@ -1,7 +1,7 @@ import { createFromIconfontCN } from '@ant-design/icons'; const IconFont = createFromIconfontCN({ - scriptUrl: '//at.alicdn.com/t/c/font_4613488_n8fe7jbl7n.js' + scriptUrl: '//at.alicdn.com/t/c/font_4613488_t2n96lwj8gf.js' }); export default IconFont; diff --git a/src/components/seal-table/components/table-row.tsx b/src/components/seal-table/components/table-row.tsx index 98638f54..abb7f1ea 100644 --- a/src/components/seal-table/components/table-row.tsx +++ b/src/components/seal-table/components/table-row.tsx @@ -35,9 +35,10 @@ const TableRow: React.FC< const [firstLoad, setFirstLoad] = useState(true); const pollTimer = useRef(null); const chunkRequestRef = useRef(null); + const childrenDataRef = useRef([]); console.log('table row===='); - const { updateChunkedList } = useUpdateChunkedList(childrenData, { + const { updateChunkedList } = useUpdateChunkedList({ setDataList: setChildrenData, callback: (list) => renderChildren?.(list) }); @@ -54,12 +55,16 @@ const TableRow: React.FC< }, [rowSelection]); useEffect(() => { - if (expandedRowKeys?.includes(record[rowKey])) { - setExpanded(true); - } else { - setExpanded(false); - } - }, [expandedRowKeys]); + childrenDataRef.current = childrenData; + }, [childrenData]); + + // useEffect(() => { + // if (expandedRowKeys?.includes(record[rowKey])) { + // setExpanded(true); + // } else { + // setExpanded(false); + // } + // }, [expandedRowKeys]); useEffect(() => { return () => { @@ -102,7 +107,7 @@ const TableRow: React.FC< const updateChildrenHandler = (list: any) => { _.each(list, (data: any) => { - updateChunkedList(data); + updateChunkedList(data, childrenDataRef.current); }); }; const createChunkRequest = () => { diff --git a/src/global.less b/src/global.less index 135125db..df83f61d 100644 --- a/src/global.less +++ b/src/global.less @@ -386,7 +386,7 @@ body { .user-menu-container { .user-avatar.ant-menu-submenu { .ant-menu-submenu-title { - padding-left: 8px; + padding-left: 10px; } } diff --git a/src/layouts/rightRender.tsx b/src/layouts/rightRender.tsx index 850355c2..9a2faf7d 100644 --- a/src/layouts/rightRender.tsx +++ b/src/layouts/rightRender.tsx @@ -70,7 +70,7 @@ export function getRightRenderContent(opts: { mode: 'vertical', expandIcon: false, inlineCollapsed: collapsed, - triggerSubMenuAction: 'click', + triggerSubMenuAction: 'hover', items: [ { key: 'lang', diff --git a/src/locales/zh-CN/playground.ts b/src/locales/zh-CN/playground.ts index 95379da7..d2910850 100644 --- a/src/locales/zh-CN/playground.ts +++ b/src/locales/zh-CN/playground.ts @@ -3,7 +3,7 @@ export default { 'playground.title': '试验场', 'playground.system': '系统', 'playground.user': '用户', - 'playground.assistant': '助手', + 'playground.assistant': '小助手', 'playground.newMessage': '新消息', 'playground.viewcode': '查看代码', 'playground.model': '模型', diff --git a/src/pages/dashboard/components/system-load.tsx b/src/pages/dashboard/components/system-load.tsx index 7e3fde0e..288cfab9 100644 --- a/src/pages/dashboard/components/system-load.tsx +++ b/src/pages/dashboard/components/system-load.tsx @@ -1,4 +1,5 @@ import CardWrapper from '@/components/card-wrapper'; +import GaugeChart from '@/components/echarts/gauge'; import PageTools from '@/components/page-tools'; import breakpoints from '@/config/breakpoints'; import useWindowResize from '@/hooks/use-window-resize'; @@ -7,10 +8,19 @@ import { Col, Row } from 'antd'; import dayjs from 'dayjs'; import _ from 'lodash'; import { useContext, useEffect, useState } from 'react'; -import UitilBar from '../../../components/util-bar'; import { DashboardContext } from '../config/dashboard-context'; import ResourceUtilization from './resource-utilization'; +const strokeColorFunc = (percent: number) => { + if (percent <= 50) { + return 'rgb(84, 204, 152, 80%)'; + } + if (percent <= 80) { + return 'rgba(250, 173, 20, 80%)'; + } + return ' rgba(255, 77, 79, 80%)'; +}; + const SystemLoad = () => { const intl = useIntl(); const data = useContext(DashboardContext)?.system_load?.current || {}; @@ -58,36 +68,44 @@ const SystemLoad = () => { - + > - + height={smallChartHeight} + color={strokeColorFunc(data.gpu_memory?.utilization_rate)} + value={_.round(data.gpu_memory?.utilization_rate || 0, 1)} + > - + height={smallChartHeight} + color={strokeColorFunc(data.cpu?.utilization_rate)} + value={_.round(data.cpu?.utilization_rate || 0, 1)} + > - + height={smallChartHeight} + color={strokeColorFunc(data.memory?.utilization_rate)} + value={_.round(data.memory?.utilization_rate || 0, 1)} + > diff --git a/src/pages/llmodels/components/instance-item.tsx b/src/pages/llmodels/components/instance-item.tsx index 04e495cb..f3c0429e 100644 --- a/src/pages/llmodels/components/instance-item.tsx +++ b/src/pages/llmodels/components/instance-item.tsx @@ -29,7 +29,11 @@ const InstanceItem: React.FC = ({ { label: intl.formatMessage({ id: 'common.button.viewlog' }), key: 'viewlog', - status: [InstanceStatusMap.Running, InstanceStatusMap.Error], + status: [ + InstanceStatusMap.Running, + InstanceStatusMap.Error, + InstanceStatusMap.Downloading + ], icon: }, { diff --git a/src/pages/playground/components/chat-footer.tsx b/src/pages/playground/components/chat-footer.tsx index 2b6b4f6c..5d271e36 100644 --- a/src/pages/playground/components/chat-footer.tsx +++ b/src/pages/playground/components/chat-footer.tsx @@ -1,5 +1,6 @@ import IconFont from '@/components/icon-font'; import HotKeys from '@/config/hotkeys'; +import { platformCall } from '@/utils'; import { CodeOutlined, DeleteOutlined, @@ -7,8 +8,9 @@ import { PlusOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; -import { Button, Col, Row, Space } from 'antd'; +import { Button, Col, Dropdown, Row, Space } from 'antd'; import { useHotkeys } from 'react-hotkeys-hook'; +import { Roles } from '../config'; import '../style/chat-footer.less'; interface ChatFooterProps { @@ -23,6 +25,7 @@ interface ChatFooterProps { } const ChatFooter: React.FC = (props) => { + const platform = platformCall(); const intl = useIntl(); const { onSubmit, @@ -42,38 +45,28 @@ const ChatFooter: React.FC = (props) => { { enabled: !disabled } ); - const renderSubmitButton = () => { - if (disabled) { - return ( - <> - {intl.formatMessage({ id: 'common.button.stop' })} - - - - - ); + const MessageRoles = [ + { key: Roles.User, label: intl.formatMessage({ id: 'playground.user' }) }, + { + key: Roles.Assistant, + label: intl.formatMessage({ id: 'playground.assistant' }) } - return ( - <> - {intl.formatMessage({ id: 'common.button.submit' })} - - + - - - ); - }; + ]; + return (
- + + + ) : ( )} diff --git a/src/pages/playground/components/ground-left.tsx b/src/pages/playground/components/ground-left.tsx index 48300e4e..bf0e01d4 100644 --- a/src/pages/playground/components/ground-left.tsx +++ b/src/pages/playground/components/ground-left.tsx @@ -56,10 +56,11 @@ const MessageList: React.FC = (props) => { const setMessageId = () => { messageId.current = messageId.current + 1; }; - const handleNewMessage = () => { + const handleNewMessage = (role: any) => { messageList.push({ - role: - _.last(messageList)?.role === Roles.User ? Roles.Assistant : Roles.User, + // role: + // _.last(messageList)?.role === Roles.User ? Roles.Assistant : Roles.User, + role: role.key, content: '', uid: messageId.current + 1 }); diff --git a/src/pages/playground/components/params-settings.tsx b/src/pages/playground/components/params-settings.tsx index 16d4092e..ea8e01ea 100644 --- a/src/pages/playground/components/params-settings.tsx +++ b/src/pages/playground/components/params-settings.tsx @@ -19,14 +19,12 @@ type ParamsSettingsFormProps = { }; type ParamsSettingsProps = { - onClose?: () => void; selectedModel?: string; params?: ParamsSettingsFormProps; setParams: (params: any) => void; }; const ParamsSettings: React.FC = ({ - onClose, selectedModel, setParams }) => { @@ -83,11 +81,6 @@ const ParamsSettings: React.FC = ({ console.log('handleOnFinishFailed', errorInfo); }; - const handleCancel = () => { - form.resetFields(); - onClose?.(); - }; - const handleValuesChange = (changedValues: any, allValues: any) => { setParams?.(allValues); }; diff --git a/src/pages/playground/config/index.ts b/src/pages/playground/config/index.ts index a1123893..8e403b82 100644 --- a/src/pages/playground/config/index.ts +++ b/src/pages/playground/config/index.ts @@ -5,11 +5,11 @@ export const Roles = { }; export const playGroundRoles = [ { - key: 'user', + key: Roles.User, label: 'playground.user' }, { - key: 'assistant', + key: Roles.Assistant, label: 'playground.assitant' } ]; diff --git a/src/pages/playground/index.tsx b/src/pages/playground/index.tsx index a526eb80..f5d84700 100644 --- a/src/pages/playground/index.tsx +++ b/src/pages/playground/index.tsx @@ -8,24 +8,9 @@ import './style/play-ground.less'; const Playground: React.FC = () => { const [searchParams] = useSearchParams(); - const [selectedModel, setSelectedModel] = useState('llama3:latest'); - const [showPopover, setShowPopover] = useState(false); const selectModel = searchParams.get('model') || ''; const [params, setParams] = useState({}); - console.log('query======', searchParams, selectModel); - const handleSelectChange = (value: string) => { - setSelectedModel(value); - }; - - const handleTogglePopover = () => { - setShowPopover(!showPopover); - }; - - const handleClosePopover = () => { - setShowPopover(false); - }; - return (
@@ -38,11 +23,7 @@ const Playground: React.FC = () => {
- +