diff --git a/src/assets/styles/common.less b/src/assets/styles/common.less index 59fffba9..3045b92d 100644 --- a/src/assets/styles/common.less +++ b/src/assets/styles/common.less @@ -136,6 +136,10 @@ position: relative; } +.font-size-0 { + font-size: 0; +} + .font-size-12 { font-size: var(--font-size-base); } diff --git a/src/components/seal-table/styles/cell.less b/src/components/seal-table/styles/cell.less index 323dc9fe..fd9d838d 100644 --- a/src/components/seal-table/styles/cell.less +++ b/src/components/seal-table/styles/cell.less @@ -4,13 +4,14 @@ display: flex; align-items: center; justify-content: flex-start; - height: 68px; + min-height: 68px; word-break: break-word; min-width: 20px; overflow: hidden; .cell-content { max-width: 100%; + line-height: 18px; } &-left { diff --git a/src/global.less b/src/global.less index f4d0bd71..5bb98665 100644 --- a/src/global.less +++ b/src/global.less @@ -65,6 +65,7 @@ html { --color-progress-green: rgba(84, 204, 152, 100%); --color-border-1: rgba(217, 217, 217, 100%); --ant-rate-star-color: #fadb14; + --color-fill-mask: rgba(255, 255, 255, 60%); // ======== input ============ --ant-input-active-shadow: 0 0 0 2px rgba(5, 255, 105, 6%); --ant-input-active-border-color: #007bff; diff --git a/src/pages/llmodels/components/deploy-modal.tsx b/src/pages/llmodels/components/deploy-modal.tsx index 3a398938..051a79ea 100644 --- a/src/pages/llmodels/components/deploy-modal.tsx +++ b/src/pages/llmodels/components/deploy-modal.tsx @@ -3,6 +3,7 @@ import { PageActionType } from '@/config/types'; import { CloseOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; import { Button, Drawer } from 'antd'; +import { debounce } from 'lodash'; import { memo, useCallback, useEffect, useRef, useState } from 'react'; import { modelSourceMap } from '../config'; import { FormData, ListItem } from '../config/types'; @@ -53,6 +54,7 @@ const AddModal: React.FC = (props) => { }, []); const handleOnSelectModel = (item: any) => { + handleSelectModelFile({ fakeName: '' }); setSelectedModel(item); }; @@ -60,12 +62,14 @@ const AddModal: React.FC = (props) => { form.current?.submit?.(); }; + const debounceFetchModelFiles = debounce(() => { + modelFileRef.current?.fetchModelFiles?.(); + }, 300); + const handleSetIsGGUF = (flag: boolean) => { setIsGGUF(flag); if (flag) { - setTimeout(() => { - modelFileRef.current?.fetchModelFiles?.(); - }, 50); + debounceFetchModelFiles(); } }; diff --git a/src/pages/llmodels/components/hf-model-file.tsx b/src/pages/llmodels/components/hf-model-file.tsx index 79a00474..defb1b6d 100644 --- a/src/pages/llmodels/components/hf-model-file.tsx +++ b/src/pages/llmodels/components/hf-model-file.tsx @@ -261,7 +261,7 @@ const HFModelFile: React.FC = forwardRef((props, ref) => { }, []); return ( -
+
{intl.formatMessage({ id: 'models.available.files' })} ( @@ -282,83 +282,89 @@ const HFModelFile: React.FC = forwardRef((props, ref) => { style={{ width: '120px' }} > + {dataSource.loading && ( +
+ +
+ )}
- - {dataSource.fileList.length ? ( - - {_.map(dataSource.fileList, (item: any) => { - return ( - -
handleSelectModelFile(item)} - onKeyDown={(e) => handleOnEnter(e, item)} - > -
{item.path}
-
- + {_.map(dataSource.fileList, (item: any) => { + return ( + +
handleSelectModelFile(item)} + onKeyDown={(e) => handleOnEnter(e, item)} + > +
{item.path}
+
+ + + {convertFileSize(item.size)} + + + {getModelQuantizationType(item)} + {item.parts && item.parts.length > 1 && ( + + } > - - {convertFileSize(item.size)} - - - {getModelQuantizationType(item)} - {item.parts && item.parts.length > 1 && ( - - } > - - - - {item.parts.length} parts - - - - )} -
+ + + {item.parts.length} parts + + + + )}
- - ); +
+ + ); + })} + + ) : ( + !dataSource.loading && + !dataSource.fileList.length && ( + - ) : ( - !dataSource.loading && - !dataSource.fileList.length && ( - - ) - )} - + /> + ) + )}
diff --git a/src/pages/llmodels/components/search-model.tsx b/src/pages/llmodels/components/search-model.tsx index 3003d468..ba05eb71 100644 --- a/src/pages/llmodels/components/search-model.tsx +++ b/src/pages/llmodels/components/search-model.tsx @@ -136,7 +136,6 @@ const SearchModel: React.FC = (props) => { } axiosTokenRef.current?.abort?.(); axiosTokenRef.current = new AbortController(); - if (dataSource.loading) return; const sort = sortType ?? dataSource.sortType; try { setDataSource((pre) => { @@ -208,7 +207,6 @@ const SearchModel: React.FC = (props) => { }; const handleFilterGGUFChange = (e: any) => { - console.log('filterggufChange:', e.target.checked); filterGGUFRef.current = e.target.checked; handleOnSearchRepo(); }; diff --git a/src/pages/llmodels/components/table-list.tsx b/src/pages/llmodels/components/table-list.tsx index 7c618bf8..d1b2d33c 100644 --- a/src/pages/llmodels/components/table-list.tsx +++ b/src/pages/llmodels/components/table-list.tsx @@ -522,20 +522,24 @@ const Models: React.FC = ({ return ( {text} {record.reranker && ( - - - Reranker - + + Reranker )} {record.embedding_only && !record.reranker && ( - + Embedding Only diff --git a/src/pages/llmodels/style/hf-model-file.less b/src/pages/llmodels/style/hf-model-file.less index 6b016f9b..9a494b11 100644 --- a/src/pages/llmodels/style/hf-model-file.less +++ b/src/pages/llmodels/style/hf-model-file.less @@ -45,6 +45,23 @@ } } +.files-wrap { + position: relative; + + .spin-wrapper { + position: absolute; + left: 0; + right: 0; + height: 100%; + z-index: 100; + bottom: 0; + top: 0; + padding-top: 150px; + text-align: center; + background-color: var(--color-fill-mask); + } +} + .wrapper { padding: 16px @padding; } diff --git a/src/pages/playground/components/thumb-img.tsx b/src/pages/playground/components/thumb-img.tsx index c06b599c..01960812 100644 --- a/src/pages/playground/components/thumb-img.tsx +++ b/src/pages/playground/components/thumb-img.tsx @@ -23,12 +23,19 @@ const ThumbImg: React.FC<{
{_.map(dataList, (item: any) => { return ( - + }} diff --git a/src/pages/playground/components/upload-img.tsx b/src/pages/playground/components/upload-img.tsx index e4eb45ae..97aa61ec 100644 --- a/src/pages/playground/components/upload-img.tsx +++ b/src/pages/playground/components/upload-img.tsx @@ -3,11 +3,12 @@ import { useIntl } from '@umijs/max'; import { Button, Tooltip, Upload } from 'antd'; import type { UploadFile } from 'antd/es/upload'; import { RcFile } from 'antd/es/upload'; -import { debounce } from 'lodash'; +import { debounce, round } from 'lodash'; import React, { useCallback, useRef } from 'react'; interface UploadImgProps { size?: 'small' | 'middle' | 'large'; + height?: number; handleUpdateImgList: ( imgList: { dataUrl: string; uid: number | string }[] ) => void; @@ -15,6 +16,7 @@ interface UploadImgProps { const UploadImg: React.FC = ({ handleUpdateImgList, + height = 100, size = 'small' }) => { const intl = useIntl(); @@ -36,6 +38,22 @@ const UploadImg: React.FC = ({ [handleUpdateImgList, intl] ); + const getImgDimensions = useCallback( + (file: any): Promise<{ ratio: number }> => { + return new Promise((resolve) => { + const img = new Image(); + img.onload = () => { + resolve({ ratio: round(img.width / img.height, 2) }); + }; + img.onerror = () => { + resolve({ ratio: 1 }); + }; + img.src = URL.createObjectURL(file); + }); + }, + [] + ); + const handleChange = useCallback( async (info: any) => { const { fileList } = info; @@ -44,7 +62,12 @@ const UploadImg: React.FC = ({ fileList.map(async (item: UploadFile) => { if (item.originFileObj && !item.url) { const base64 = await getBase64(item.originFileObj as RcFile); + const { ratio } = await getImgDimensions( + item.originFileObj as RcFile + ); + item.url = base64; + item.ratio = ratio; } return item; }) @@ -56,7 +79,9 @@ const UploadImg: React.FC = ({ .map((item: UploadFile) => { return { dataUrl: item.url as string, - uid: item.uid + uid: item.uid, + height: height, + width: height * item.ratio }; });