From a698c65a074983180ec773c0e2d70473f972ac48 Mon Sep 17 00:00:00 2001 From: jialin Date: Wed, 25 Sep 2024 16:15:57 +0800 Subject: [PATCH] fix: playground edit message --- config/config.ts | 2 +- src/components/highlight-code/code-viewer.tsx | 13 +- .../highlight-code/styles/index.less | 19 ++- src/components/markdown-viewer/index.less | 4 +- src/components/markdown-viewer/index.tsx | 18 ++- src/components/markdown-viewer/utils.ts | 16 +++ src/components/seal-form/auto-complete.tsx | 2 +- src/global.less | 1 + src/locales/en-US/playground.ts | 5 +- src/locales/zh-CN/playground.ts | 5 +- .../llmodels/components/advance-config.tsx | 10 +- src/pages/llmodels/components/data-form.tsx | 1 + src/pages/llmodels/components/gpu-card.tsx | 2 +- .../llmodels/components/hf-model-file.tsx | 4 +- .../llmodels/components/instance-item.tsx | 1 + src/pages/llmodels/components/model-card.tsx | 16 ++- .../llmodels/components/search-input.tsx | 6 - .../llmodels/components/search-model.tsx | 18 +-- .../llmodels/components/search-result.tsx | 1 - src/pages/llmodels/components/table-list.tsx | 1 - src/pages/llmodels/config/types.ts | 6 +- .../playground/components/message-input.tsx | 107 ++++++++-------- .../components/multiple-chat/content-item.tsx | 119 +++++++++--------- .../components/multiple-chat/index.tsx | 44 ++++++- .../components/multiple-chat/model-item.tsx | 18 ++- .../multiple-chat/system-message.tsx | 51 +++++++- .../playground/components/prompt-modal.tsx | 2 +- .../playground/config/compare-context.ts | 2 + src/pages/playground/style/content-item.less | 2 +- src/pages/playground/style/message-input.less | 11 +- src/pages/playground/style/sys-message.less | 15 ++- src/pages/resources/components/workers.tsx | 6 +- 32 files changed, 338 insertions(+), 190 deletions(-) create mode 100644 src/components/markdown-viewer/utils.ts diff --git a/config/config.ts b/config/config.ts index 36546891..04d89fd6 100644 --- a/config/config.ts +++ b/config/config.ts @@ -14,7 +14,7 @@ const isProduction = env === 'production'; const t = Date.now(); export default defineConfig({ proxy: { - ...proxy() + ...proxy('http://192.168.50.4') }, history: { type: 'hash' diff --git a/src/components/highlight-code/code-viewer.tsx b/src/components/highlight-code/code-viewer.tsx index 1193606a..22843cc6 100644 --- a/src/components/highlight-code/code-viewer.tsx +++ b/src/components/highlight-code/code-viewer.tsx @@ -60,11 +60,14 @@ const CodeViewer: React.FC = (props) => { return (
 = ({
     'list',
     'list_item',
     'br',
-    'html'
+    'html',
+    'escape'
   ];
 
-  const renderItem = (token: any, render: any) => {
-    // console.log('token======66==', token.raw, token.type);
+  const renderItem = useCallback((token: any, render: any) => {
     if (!reDefineTypes.includes(token.type)) {
+      console.log('token======66==', token.type, token);
       return (
          = ({
     if (token.tokens?.length) {
       child = render?.(token.tokens as TokensList, render);
     }
-    const text = child ? child : token.text;
+    const text = child ? child : unescape(token.text);
+
+    if (token.type === 'escape') {
+      htmlstr = text;
+    }
 
     if (token.type === 'html') {
       htmlstr = 
; @@ -125,7 +131,7 @@ const MarkdownViewer: React.FC = ({ } return htmlstr; - }; + }, []); const renderTokens = (tokens: TokensList): any => { return tokens?.map((token: any, index: number) => { return {renderItem(token, renderTokens)}; diff --git a/src/components/markdown-viewer/utils.ts b/src/components/markdown-viewer/utils.ts new file mode 100644 index 00000000..fc1128de --- /dev/null +++ b/src/components/markdown-viewer/utils.ts @@ -0,0 +1,16 @@ +const htmlUnescapes: Record = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'" +}; + +const reEscapedHtml = /&(?:amp|lt|gt|quot|#(?:0+)?39);/g; +const reHasEscapedHtml = RegExp(reEscapedHtml.source); + +export const unescape = (str = '') => { + return reHasEscapedHtml.test(str) + ? str.replace(reEscapedHtml, (entity) => htmlUnescapes[entity] || "'") + : str; +}; diff --git a/src/components/seal-form/auto-complete.tsx b/src/components/seal-form/auto-complete.tsx index dd8269c4..be3707a1 100644 --- a/src/components/seal-form/auto-complete.tsx +++ b/src/components/seal-form/auto-complete.tsx @@ -5,7 +5,7 @@ import Wrapper from './components/wrapper'; import { SealFormItemProps } from './types'; const SealAutoComplete: React.FC< - AutoCompleteProps & SealFormItemProps & { onInput: (e: Event) => void } + AutoCompleteProps & SealFormItemProps & { onInput?: (e: Event) => void } > = (props) => { const { label, diff --git a/src/global.less b/src/global.less index f33e2148..f549088d 100644 --- a/src/global.less +++ b/src/global.less @@ -42,6 +42,7 @@ html { --color-text-3: rgba(0, 0, 0, 45%); --color-text-2: rgba(0, 0, 0, 65%); --color-bg-light-1: #e6f6ff; + --font-size-small: 13px; --font-size-base: 12px; --font-size-large: 16px; --font-size-middle: 14px; diff --git a/src/locales/en-US/playground.ts b/src/locales/en-US/playground.ts index e533246c..b8fc4ce7 100644 --- a/src/locales/en-US/playground.ts +++ b/src/locales/en-US/playground.ts @@ -40,5 +40,8 @@ export default { 'playground.toolbar.compare2Model': '2-Model Compare', 'playground.toolbar.compare3Model': '3-Model Compare', 'playground.toolbar.compare4Model': '4-Model Compare', - 'playground.toolbar.compare6Model': '6-Model Compare' + 'playground.toolbar.compare6Model': '6-Model Compare', + 'playground.input.holder': 'Type / to input message', + 'playground.compare.apply': 'Apply', + 'playground.compare.applytoall': 'Apply to all models' }; diff --git a/src/locales/zh-CN/playground.ts b/src/locales/zh-CN/playground.ts index e38f23c9..9fb5c6d2 100644 --- a/src/locales/zh-CN/playground.ts +++ b/src/locales/zh-CN/playground.ts @@ -40,5 +40,8 @@ export default { 'playground.toolbar.compare2Model': '2 模型对比', 'playground.toolbar.compare3Model': '3 模型对比', 'playground.toolbar.compare4Model': '4 模型对比', - 'playground.toolbar.compare6Model': '6 模型对比' + 'playground.toolbar.compare6Model': '6 模型对比', + 'playground.input.holder': '按 / 开始输入', + 'playground.compare.apply': '应用', + 'playground.compare.applytoall': '应用到所有模型' }; diff --git a/src/pages/llmodels/components/advance-config.tsx b/src/pages/llmodels/components/advance-config.tsx index 3f23623c..b8a7b852 100644 --- a/src/pages/llmodels/components/advance-config.tsx +++ b/src/pages/llmodels/components/advance-config.tsx @@ -1,7 +1,5 @@ import LabelSelector from '@/components/label-selector'; -import ListInput from '@/components/list-input'; import SealSelect from '@/components/seal-form/seal-select'; -import { PageAction } from '@/config'; import { PageActionType } from '@/config/types'; import { InfoCircleOutlined, RightOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; @@ -193,7 +191,7 @@ const AdvanceConfig: React.FC = (props) => { )} - + {/* = (props) => { ]} disabled={action === PageAction.EDIT} > - - name="backend_parameters"> + */} + {/* name="backend_parameters"> = (props) => { onChange={handleBackendParametersChange} options={paramsConfig} > - + */} {scheduleType === 'manual' && ( name="gpu_selector" diff --git a/src/pages/llmodels/components/data-form.tsx b/src/pages/llmodels/components/data-form.tsx index 7e14d0e9..ff40cf40 100644 --- a/src/pages/llmodels/components/data-form.tsx +++ b/src/pages/llmodels/components/data-form.tsx @@ -220,6 +220,7 @@ const DataForm: React.FC = forwardRef((props, ref) => { > = forwardRef((props, ref) => { } ); const fileList = _.filter(_.get(data, ['Data', 'Files']), (file: any) => { - return filterReg.test(file.path) || _.includes(includeReg, file.path); + return filterReg.test(file.Path) || _.includes(includeReg, file.Path); }); const list = _.map(fileList, (item: any) => { return { @@ -192,6 +192,7 @@ const HFModelFile: React.FC = forwardRef((props, ref) => { } const newList = generateGroupByFilename(list); + console.log('newList====', newList); const sortList = _.sortBy(newList, (item: any) => { return sortType === 'size' ? item.size : item.path; }); @@ -199,6 +200,7 @@ const HFModelFile: React.FC = forwardRef((props, ref) => { handleSelectModelFile(sortList[0]); setDataSource({ fileList: sortList, loading: false }); } catch (error) { + console.log('error======', error); setDataSource({ fileList: [], loading: false }); handleSelectModelFile({}); } diff --git a/src/pages/llmodels/components/instance-item.tsx b/src/pages/llmodels/components/instance-item.tsx index 393f15d8..9f6dc1c6 100644 --- a/src/pages/llmodels/components/instance-item.tsx +++ b/src/pages/llmodels/components/instance-item.tsx @@ -210,6 +210,7 @@ const InstanceItem: React.FC = ({ )} {item?.distributed_servers?.rpc_servers?.length && ( ({}); + const [modelData, setModelData] = useState(null); const [readmeText, setReadmeText] = useState(null); const requestToken = useRef(null); const axiosTokenRef = useRef(null); @@ -76,7 +76,7 @@ const ModelCard: React.FC<{ setIsGGUF(modelcard.tags?.includes('gguf')); setIsGGUFModel(modelcard.tags?.includes('gguf')); } catch (error) { - setModelData({}); + setModelData(null); setReadmeText(null); setIsGGUF(false); setIsGGUFModel(false); @@ -101,7 +101,7 @@ const ModelCard: React.FC<{ setIsGGUF(data.Data?.Tags?.includes('gguf')); setIsGGUFModel(data.Data?.Tags?.includes('gguf')); } catch (error) { - setModelData({}); + setModelData(null); setReadmeText(null); setIsGGUF(false); setIsGGUFModel(false); @@ -140,7 +140,7 @@ const ModelCard: React.FC<{ size="small" type="link" target="_blank" - href={`https://huggingface.co/${modelData.id}`} + href={`https://huggingface.co/${modelData?.id}`} > @@ -155,7 +155,7 @@ const ModelCard: React.FC<{ size="small" type="link" target="_blank" - href={`https://modelscope.cn/models/${modelData.name}`} + href={`https://modelscope.cn/models/${modelData?.name}`} > @@ -202,6 +202,11 @@ const ModelCard: React.FC<{ )} + {isGGUFModel && ( + + GGUF + + )}
{readmeText && isGGUFModel && (
diff --git a/src/pages/llmodels/components/search-input.tsx b/src/pages/llmodels/components/search-input.tsx index 698c6954..a35575ca 100644 --- a/src/pages/llmodels/components/search-input.tsx +++ b/src/pages/llmodels/components/search-input.tsx @@ -32,12 +32,6 @@ const SearchInput: React.FC<{ )} prefix={ <> - {/* */} = (props) => { search: { query: searchInputRef.current || '', sort: sort, - tags: filterGGUFRef.current ? ['gguf'] : [], + // tags: filterGGUFRef.current ? ['gguf'] : [], + tags: ['gguf'], task } }; @@ -102,9 +103,10 @@ const SearchModel: React.FC = (props) => { const getModelsFromModelscope = useCallback(async (sort: string) => { try { const params = { - Name: filterGGUFRef.current - ? `${searchInputRef.current} gguf` - : searchInputRef.current || '', + // Name: filterGGUFRef.current + // ? `${searchInputRef.current} gguf` + // : searchInputRef.current || '', + Name: `${searchInputRef.current} gguf`, SortBy: ModelScopeSortType[sort] }; const data = await queryModelScopeModels(params, { @@ -115,7 +117,7 @@ const SearchModel: React.FC = (props) => { path: item.Path, name: `${item.Path}/${item.Name}`, downloads: item.Downloads, - id: item.Name, + id: `${item.Path}/${item.Name}`, updatedAt: item.LastUpdatedTime * 1000, likes: item.Stars, value: item.Name, @@ -231,13 +233,13 @@ const SearchModel: React.FC = (props) => { - GGUF - + */} {!message.content && !focused && ( - - Type / to input message - + )}
= ({ }); }; - const getPasteContent = useCallback(async (event: any) => { - const clipboardData = event.clipboardData || window.clipboardData; - const items = clipboardData.items; - const imgPromises: Promise[] = []; + const getPasteContent = useCallback( + async (event: any) => { + const clipboardData = event.clipboardData || window.clipboardData; + const items = clipboardData.items; + const imgPromises: Promise[] = []; - for (let i = 0; i < items.length; i++) { - let item = items[i]; - console.log('item===========', item); + for (let i = 0; i < items.length; i++) { + let item = items[i]; + console.log('item===========', item); - if (item.kind === 'file' && item.type.indexOf('image') !== -1) { - const file = item.getAsFile(); - const imgPromise = new Promise((resolve, reject) => { - const reader = new FileReader(); - reader.onload = function (event) { - const base64String = event.target?.result as string; - if (base64String) { - resolve(base64String); - } else { - reject('Failed to convert image to base64'); - } - }; - reader.readAsDataURL(file); - }); - imgPromises.push(imgPromise); - } else if (item.kind === 'string') { - // string + if (item.kind === 'file' && item.type.indexOf('image') !== -1) { + const file = item.getAsFile(); + const imgPromise = new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = function (event) { + const base64String = event.target?.result as string; + if (base64String) { + resolve(base64String); + } else { + reject('Failed to convert image to base64'); + } + }; + reader.readAsDataURL(file); + }); + imgPromises.push(imgPromise); + } else if (item.kind === 'string') { + // string + } } - } - try { - const imgs = await Promise.all(imgPromises); - if (imgs.length) { - const list = _.map(imgs, (img: string) => { - imgCountRef.current += 1; - return { - uid: imgCountRef.current, - dataUrl: img - }; - }); + try { + const imgs = await Promise.all(imgPromises); + if (imgs.length) { + const list = _.map(imgs, (img: string) => { + imgCountRef.current += 1; + return { + uid: imgCountRef.current, + dataUrl: img + }; + }); - updateMessage?.({ - role: data.role, - content: data.content, - uid: data.uid, - imgs: [...(data.imgs || []), ...list] - }); - } - } catch (error) { - console.error('Error processing images:', error); - } - }, []); - - const handleOnPaste = useCallback( - (e: any) => { - const text = e.clipboardData.getData('text'); - if (text) { - updateMessage?.({ - role: data.role, - content: inputRef.current?.resizableTextArea?.textArea?.value || '', - uid: data.uid - }); - } else { - getPasteContent(e); + updateMessage?.({ + role: data.role, + content: data.content, + uid: data.uid, + imgs: [...(data.imgs || []), ...list] + }); + } + } catch (error) { + console.error('Error processing images:', error); } }, - [getPasteContent, data, updateMessage] + [data] ); + const handleOnPaste = (e: any) => { + e.preventDefault(); + const text = e.clipboardData.getData('text'); + if (text) { + updateMessage?.({ + role: data.role, + content: data.content + text, + uid: data.uid + }); + } else { + getPasteContent(e); + } + }; + const handleUpdateImgList = useCallback( (list: { uid: number | string; dataUrl: string }[]) => { console.log('list===========', data.imgs, list); diff --git a/src/pages/playground/components/multiple-chat/index.tsx b/src/pages/playground/components/multiple-chat/index.tsx index 2424baa2..f6bf9b33 100644 --- a/src/pages/playground/components/multiple-chat/index.tsx +++ b/src/pages/playground/components/multiple-chat/index.tsx @@ -111,16 +111,38 @@ const MultiCompare: React.FC = ({ modelList }) => { }); }; + const adjustSpan = () => { + const count = spans.count - 1; + if (spans.count === 6) { + setSpans({ + span: 8, + count: count + }); + } else if (spans.count === 5) { + setSpans({ + span: 12, + count: count + }); + } else if (spans.count === 4) { + setSpans({ + span: 8, + count: count + }); + } else if (spans.count === 3) { + setSpans({ + span: 12, + count: count + }); + } + }; + const handleDeleteModel = (instanceId: symbol) => { const newModelList = modelSelections.filter( (model) => model.instanceId !== instanceId ); pruneInstanceSymbol(instanceId); - const span = Math.floor(24 / (24 / spans.span - 1)); - setSpans({ - span, - count: spans.count - }); + + adjustSpan(); setModelSelections(newModelList); }; @@ -143,6 +165,14 @@ const MultiCompare: React.FC = ({ modelList }) => { setModelSelections(updateList); }; + const handleApplySystemChangeToAll = (message: string) => { + const modelRefList = Object.getOwnPropertySymbols(modelRefs.current); + modelRefList.forEach((instanceId: symbol) => { + const ref = modelRefs.current[instanceId]; + ref?.setSystemMessage(message); + }); + }; + const handlePresetPrompt = (list: { role: string; content: string }[]) => { const sysMsg = list.filter((item) => item.role === 'system'); const userMsg = list.filter((item) => item.role === 'user'); @@ -227,6 +257,8 @@ const MultiCompare: React.FC = ({ modelList }) => { spans, globalParams, loadingStatus, + modelFullList: modelList, + handleApplySystemChangeToAll, setGlobalParams, setLoadingStatus: handleSetLoadingStatus, handleDeleteModel: handleDeleteModel @@ -252,7 +284,7 @@ const MultiCompare: React.FC = ({ modelList }) => { setModelSelections={handleUpdateModelSelections} presetPrompt={handlePresetPrompt} modelList={modelFullList} - showModelSelection={true} + showModelSelection={false} /> diff --git a/src/pages/playground/components/multiple-chat/model-item.tsx b/src/pages/playground/components/multiple-chat/model-item.tsx index 552c0281..36b9ac2a 100644 --- a/src/pages/playground/components/multiple-chat/model-item.tsx +++ b/src/pages/playground/components/multiple-chat/model-item.tsx @@ -47,6 +47,8 @@ const ModelItem: React.FC = forwardRef( setGlobalParams, setLoadingStatus, handleDeleteModel, + handleApplySystemChangeToAll, + modelFullList, loadingStatus } = useContext(CompareContext); const intl = useIntl(); @@ -224,7 +226,7 @@ const ModelItem: React.FC = forwardRef( isApplyToAllModels.current = e.target.checked; if (e.target.checked) { setGlobalParams({ - ...params + ..._.omit(params, 'model') }); } }; @@ -289,10 +291,10 @@ const ModelItem: React.FC = forwardRef( }; const modelOptions = useMemo(() => { - return modelList.filter((item) => { + return modelFullList.filter((item) => { return item.type !== 'empty'; }); - }, [modelList]); + }, [modelFullList]); useEffect(() => { console.log('globalParams:', globalParams.model, globalParams); @@ -326,9 +328,9 @@ const ModelItem: React.FC = forwardRef(
@@ -379,7 +381,9 @@ const ModelItem: React.FC = forwardRef( title={
- Apply to all models + {intl.formatMessage({ + id: 'playground.compare.applytoall' + })}
} @@ -401,7 +405,9 @@ const ModelItem: React.FC = forwardRef(
diff --git a/src/pages/playground/components/multiple-chat/system-message.tsx b/src/pages/playground/components/multiple-chat/system-message.tsx index 0d9aafd8..932ece07 100644 --- a/src/pages/playground/components/multiple-chat/system-message.tsx +++ b/src/pages/playground/components/multiple-chat/system-message.tsx @@ -1,18 +1,23 @@ import { CloseOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; -import { Button, Divider, Input, Tooltip } from 'antd'; +import { Button, Checkbox, Divider, Input, Tooltip } from 'antd'; +import classNames from 'classnames'; import React, { useState } from 'react'; import '../../style/sys-message.less'; interface SystemMessageProps { style?: React.CSSProperties; systemMessage: string; + showApplyToAll?: boolean; + applyToAll?: (e: any) => void; setSystemMessage: (value: string) => void; } const SystemMessage: React.FC = (props) => { - const { systemMessage, setSystemMessage, style } = props; + const { systemMessage, showApplyToAll, setSystemMessage, style, applyToAll } = + props; const intl = useIntl(); + const [isChange, setIsChange] = useState(false); const systemMessageRef = React.useRef(null); const [autoSize, setAutoSize] = useState<{ minRows: number; @@ -33,26 +38,51 @@ const SystemMessage: React.FC = (props) => { }, 100); }; - const handleBlur = () => { + const handleBlur = (e: any) => { setAutoSize({ minRows: 1, maxRows: 1, focus: false }); + setIsChange(false); + }; + + const handleOnChange = (e: any) => { + setSystemMessage(e.target.value); + setIsChange(true); }; const handleClearSystemMessage = () => { setSystemMessage(''); }; + const handleClickCheckbox = (e?: any) => { + e.preventDefault(); + }; + + const handleApplyToAllModels = (e: any) => { + if (e.target.checked) { + applyToAll?.(systemMessage); + } + }; + return ( -
+
{ -
+
{intl.formatMessage({ id: 'playground.systemMessage' })} = (props) => { onFocus={handleFocus} onBlur={handleBlur} allowClear={false} - onChange={(e) => setSystemMessage(e.target.value)} + onChange={handleOnChange} > + {isChange && showApplyToAll && ( + + + {intl.formatMessage({ + id: 'playground.compare.applytoall' + })} + + + )}
} diff --git a/src/pages/playground/components/prompt-modal.tsx b/src/pages/playground/components/prompt-modal.tsx index fa75ba96..fbe8ebb7 100644 --- a/src/pages/playground/components/prompt-modal.tsx +++ b/src/pages/playground/components/prompt-modal.tsx @@ -57,7 +57,7 @@ const AddWorker: React.FC = (props) => { type="default" onClick={() => handleSelect(item)} > - Apply + {intl.formatMessage({ id: 'playground.compare.apply' })} {item.data.map((data, i) => { diff --git a/src/pages/playground/config/compare-context.ts b/src/pages/playground/config/compare-context.ts index a322d8c8..5a4905e8 100644 --- a/src/pages/playground/config/compare-context.ts +++ b/src/pages/playground/config/compare-context.ts @@ -8,6 +8,8 @@ interface CompareContextProps { systemMessage?: string; globalParams: Record; loadingStatus: Record; + modelFullList: (Global.BaseOption & { type?: string })[]; + handleApplySystemChangeToAll: (val: string) => void; handleDeleteModel: (instanceId: symbol) => void; setSystemMessage?: (message: string) => void; setGlobalParams: (value: Record) => void; diff --git a/src/pages/playground/style/content-item.less b/src/pages/playground/style/content-item.less index 406b94a0..48d27b17 100644 --- a/src/pages/playground/style/content-item.less +++ b/src/pages/playground/style/content-item.less @@ -13,7 +13,7 @@ .role { position: relative; cursor: pointer; - padding: 2px 4px; + padding: 0 4px; border-radius: var(--border-radius-mini); } diff --git a/src/pages/playground/style/message-input.less b/src/pages/playground/style/message-input.less index 8bc4965f..ef870d3a 100644 --- a/src/pages/playground/style/message-input.less +++ b/src/pages/playground/style/message-input.less @@ -48,14 +48,21 @@ } textarea::-webkit-scrollbar-track { - background-color: #f1f1f1; + background-color: transparent; } textarea::-webkit-scrollbar-thumb { - background-color: #d9d9d9; + background-color: transparent; border-radius: 6px; } + textarea:hover { + &::-webkit-scrollbar-thumb { + background-color: var(--color-scrollbar-thumb); + border-radius: 6px; + } + } + .send-btn { display: flex; justify-content: center; diff --git a/src/pages/playground/style/sys-message.less b/src/pages/playground/style/sys-message.less index 26b599ac..5002a2bf 100644 --- a/src/pages/playground/style/sys-message.less +++ b/src/pages/playground/style/sys-message.less @@ -1,6 +1,19 @@ .sys-message { position: relative; + &.focus { + padding-top: 9px; + } + + .apply-check { + position: absolute; + bottom: 10px; + right: 10px; + direction: rtl; + background-color: var(--color-white-1); + box-shadow: var(--ant-box-shadow-tertiary); + } + .sys-content-wrap { position: relative; display: flex; @@ -26,7 +39,7 @@ .system-label { font-weight: var(--font-weight-bold); - padding-left: 16px; + padding-left: 14px; } .sys-content { diff --git a/src/pages/resources/components/workers.tsx b/src/pages/resources/components/workers.tsx index 821ff507..765fe2e0 100644 --- a/src/pages/resources/components/workers.tsx +++ b/src/pages/resources/components/workers.tsx @@ -45,8 +45,6 @@ const ActionList = [ ]; const Resources: React.FC = () => { - console.log('resources======workers'); - const { sortOrder, setSortOrder } = useTableSort({ defaultSortOrder: 'descend' }); @@ -400,7 +398,7 @@ const Resources: React.FC = () => { return ( {_.map( - record?.status?.gpu_devices, + _.sortBy(record?.status?.gpu_devices || [], ['index']), (item: GPUDeviceItem, index: string) => { return ( @@ -431,7 +429,7 @@ const Resources: React.FC = () => { return ( {_.map( - record?.status?.gpu_devices, + _.sortBy(record?.status?.gpu_devices || [], ['index']), (item: GPUDeviceItem, index: string) => { return (