diff --git a/src/app.tsx b/src/app.tsx index 540c6efb..b89c6c69 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -13,6 +13,7 @@ import { writeState } from '@/utils/localstore/index'; import { RequestConfig, history } from '@umijs/max'; +import { message } from 'antd'; const loginPath = '/login'; @@ -53,13 +54,24 @@ export async function getInitialState(): Promise<{ }): Promise => { try { const data = await queryCurrentUserState({ - skipErrorHandler: config?.skipErrorHandler ?? false + skipErrorHandler: true }); if (data.is_admin) { getUpdateCheck(); } return data; } catch (error: any) { + const data = error?.response?.data; + if (data?.code === 401 && data?.message.includes('deactivate')) { + message.error({ + content: ( +
+ {data?.message} +
+ ), + duration: 5 + }); + } history.push(loginPath); } return {} as Global.UserInfo; @@ -81,9 +93,7 @@ export async function getInitialState(): Promise<{ getAppVersionInfo(); if (![loginPath].includes(location.pathname)) { - const userInfo = await fetchUserInfo({ - skipErrorHandler: location.pathname === '/' - }); + const userInfo = await fetchUserInfo(); checkDefaultPage(userInfo); return { fetchUserInfo, diff --git a/src/components/tags-wrapper/index.tsx b/src/components/tags-wrapper/index.tsx index a338f723..75c626c5 100644 --- a/src/components/tags-wrapper/index.tsx +++ b/src/components/tags-wrapper/index.tsx @@ -8,7 +8,7 @@ import './index.less'; interface TagsWrapperProps { gap?: number; dataList: any[]; - renderTag: (item: any) => React.ReactNode; + renderTag: (item: any, index?: number) => React.ReactNode; } const TagsWrapper: React.FC = (props) => { @@ -94,7 +94,7 @@ const TagsWrapper: React.FC = (props) => { {_.map( _.slice(dataList, hiddenIndices.start, hiddenIndices.end), (item: any, index: number) => { - return {renderTag?.(item)}; + return {renderTag?.(item, index)}; } )} @@ -108,7 +108,7 @@ const TagsWrapper: React.FC = (props) => { _.slice(dataList, hiddenIndices.end), (item: any, index: number) => { return { - label: renderTag?.(item), + label: renderTag?.(item, index), key: index, onClick: handleClick }; diff --git a/src/locales/en-US/common.ts b/src/locales/en-US/common.ts index 0883c3fd..16e57ba8 100644 --- a/src/locales/en-US/common.ts +++ b/src/locales/en-US/common.ts @@ -261,5 +261,6 @@ export default { 'common.button.edit.item': 'Edit {name}', 'common.button.terminal': 'Terminal', 'common.button.addItem': 'Add Item', - 'common.help.default': 'Default: {content}' + 'common.help.default': 'Default: {content}', + 'common.filter.status': 'Filter by status' }; diff --git a/src/locales/en-US/models.ts b/src/locales/en-US/models.ts index 0060a024..33321e70 100644 --- a/src/locales/en-US/models.ts +++ b/src/locales/en-US/models.ts @@ -203,5 +203,8 @@ export default { 'models.form.gpusAllocationType.auto.tips': 'System calculates GPUs per replica automatically.', 'models.form.gpusAllocationType.custom.tips': - 'You can specify the exact number of GPUs per replica.' + 'You can specify the exact number of GPUs per replica.', + 'models.mymodels.status.inactive': 'Stopped', + 'models.mymodels.status.degrade': 'Abnormal', + 'models.mymodels.status.active': 'Active' }; diff --git a/src/locales/ja-JP/common.ts b/src/locales/ja-JP/common.ts index d339e9e0..2d720826 100644 --- a/src/locales/ja-JP/common.ts +++ b/src/locales/ja-JP/common.ts @@ -261,7 +261,8 @@ export default { 'common.button.edit.item': 'Edit {name}', 'common.button.terminal': 'Terminal', 'common.button.addItem': 'Add Item', - 'common.help.default': 'Default: {content}' + 'common.help.default': 'Default: {content}', + 'common.filter.status': 'Filter by status' }; // ========== To-Do: Translate Keys (Remove After Translation) ========== @@ -288,5 +289,6 @@ export default { // 21. 'common.button.edit.item': 'Edit {name}', // 22. 'common.button.terminal': 'Terminal', // 23. 'common.button.addItem': 'Add Item', -// 24. 'common.help.default': 'Default: {content}' +// 24. 'common.help.default': 'Default: {content}', +// 25. 'common.filter.status': 'Filter by status' // ========== End of To-Do List ========== diff --git a/src/locales/ja-JP/models.ts b/src/locales/ja-JP/models.ts index 5448bbd1..b3e4ab59 100644 --- a/src/locales/ja-JP/models.ts +++ b/src/locales/ja-JP/models.ts @@ -200,7 +200,10 @@ export default { 'models.form.gpusAllocationType.auto.tips': 'System calculates GPUs per replica automatically.', 'models.form.gpusAllocationType.custom.tips': - 'You can specify the exact number of GPUs per replica.' + 'You can specify the exact number of GPUs per replica.', + 'models.mymodels.status.inactive': 'Stopped', + 'models.mymodels.status.degrade': 'Abnormal', + 'models.mymodels.status.active': 'Active' }; // ========== To-Do: Translate Keys (Remove After Translation) ========== @@ -240,6 +243,9 @@ export default { // 35. 'models.form.gpusAllocationType.auto': 'Auto', // 36. 'models.form.gpusAllocationType.custom': 'Custom', // 37. 'models.form.gpusAllocationType.auto.tips': 'System calculates GPUs per replica automatically.', -// 38. 'models.form.gpusAllocationType.custom.tips': 'You can specify the exact number of GPUs per replica.' +// 38. 'models.form.gpusAllocationType.custom.tips': 'You can specify the exact number of GPUs per replica.', +// 39. 'models.mymodels.status.inactive': 'Stopped', +// 41. 'models.mymodels.status.degrade': 'Abnormal', +// 42. 'models.mymodels.status.active': 'Active' // ========== End of To-Do List ========== diff --git a/src/locales/ru-RU/common.ts b/src/locales/ru-RU/common.ts index 705290e0..76c51000 100644 --- a/src/locales/ru-RU/common.ts +++ b/src/locales/ru-RU/common.ts @@ -260,9 +260,10 @@ export default { 'common.button.edit.item': 'Редактировать {name}', 'common.button.terminal': 'Терминал', 'common.button.addItem': 'Добавить элемент', - 'common.help.default': 'По умолчанию: {content}' + 'common.help.default': 'По умолчанию: {content}', + 'common.filter.status': 'Filter by status' }; // ========== To-Do: Translate Keys (Remove After Translation) ========== - +// 1. 'common.filter.status': 'Filter by status' // ========== End of To-Do List ========== diff --git a/src/locales/ru-RU/models.ts b/src/locales/ru-RU/models.ts index f126597e..f511a6c6 100644 --- a/src/locales/ru-RU/models.ts +++ b/src/locales/ru-RU/models.ts @@ -187,20 +187,30 @@ export default { 'models.form.chunkSize': 'Размер чанков кэша', 'models.form.maxCPUSize': 'Максимальный размер CPU кэша (ГиБ)', 'models.form.remoteURL': 'URL удаленного хранилища', - 'models.form.runCommandPlaceholder': 'напр., vllm serve Qwen/Qwen2.5-1.5B-Instruct', + 'models.form.runCommandPlaceholder': + 'напр., vllm serve Qwen/Qwen2.5-1.5B-Instruct', 'models.accessSettings.public': 'Публичный', 'models.accessSettings.authed': 'Аутентифицированный', 'models.accessSettings.allowedUsers': 'Разрешенные пользователи', - 'models.accessSettings.public.tips': 'При публичном доступе любой пользователь может получить доступ к модели без аутентификации, что может привести к риску утечки данных.', + 'models.accessSettings.public.tips': + 'При публичном доступе любой пользователь может получить доступ к модели без аутентификации, что может привести к риску утечки данных.', 'models.table.button.deploy': 'Развернуть сейчас', 'models.form.backendVersion.holder': 'Введите или выберите версию', 'models.form.gpusperreplica': 'GPU на реплику', 'models.form.gpusAllocationType': 'Тип распределения GPU', 'models.form.gpusAllocationType.auto': 'Авто', 'models.form.gpusAllocationType.custom': 'Вручную', - 'models.form.gpusAllocationType.auto.tips': 'Система автоматически рассчитывает количество GPU на реплику.', - 'models.form.gpusAllocationType.custom.tips': 'Вы можете указать точное количество GPU на реплику.' + 'models.form.gpusAllocationType.auto.tips': + 'Система автоматически рассчитывает количество GPU на реплику.', + 'models.form.gpusAllocationType.custom.tips': + 'Вы можете указать точное количество GPU на реплику.', + 'models.mymodels.status.inactive': 'Stopped', + 'models.mymodels.status.degrade': 'Abnormal', + 'models.mymodels.status.active': 'Active' }; // ========== To-Do: Translate Keys (Remove After Translation) ========== - +// 1. 'models.mymodels.status.inactive': 'Stopped', +// 3. 'models.mymodels.status.degrade': 'Abnormal', +// 4. 'models.mymodels.status.active': 'Active' +// ========== End of To-Do List ========== diff --git a/src/locales/zh-CN/common.ts b/src/locales/zh-CN/common.ts index 60aebff2..06eff571 100644 --- a/src/locales/zh-CN/common.ts +++ b/src/locales/zh-CN/common.ts @@ -253,5 +253,6 @@ export default { 'common.button.edit.item': '编辑 {name}', 'common.button.terminal': '终端', 'common.button.addItem': '添加项', - 'common.help.default': '默认: {content}' + 'common.help.default': '默认: {content}', + 'common.filter.status': '按状态筛选' }; diff --git a/src/locales/zh-CN/models.ts b/src/locales/zh-CN/models.ts index 96a3c086..c2abef55 100644 --- a/src/locales/zh-CN/models.ts +++ b/src/locales/zh-CN/models.ts @@ -191,5 +191,8 @@ export default { 'models.form.gpusAllocationType.custom': '自定义', 'models.form.gpusAllocationType.auto.tips': '系统自动计算每个副本的 GPU 数量。', - 'models.form.gpusAllocationType.custom.tips': '您可以指定每个副本的 GPU 数量' + 'models.form.gpusAllocationType.custom.tips': '您可以指定每个副本的 GPU 数量', + 'models.mymodels.status.inactive': '已停止', + 'models.mymodels.status.degrade': '异常', + 'models.mymodels.status.active': '可用' }; diff --git a/src/pages/llmodels/components/model-item.tsx b/src/pages/llmodels/components/model-item.tsx index e71afd23..08dd3b4f 100644 --- a/src/pages/llmodels/components/model-item.tsx +++ b/src/pages/llmodels/components/model-item.tsx @@ -1,31 +1,24 @@ import IconFont from '@/components/icon-font'; import StatusTag from '@/components/status-tag'; +import TagWrapper from '@/components/tags-wrapper'; import ThemeTag from '@/components/tags-wrapper/theme-tag'; import Card from '@/components/templates/card'; -import { StatusMaps } from '@/config'; import { useIntl, useNavigate } from '@umijs/max'; import { Button } from 'antd'; import _ from 'lodash'; import React, { useMemo } from 'react'; import styled from 'styled-components'; -import { modelCategories, modelCategoriesMap, modelSourceMap } from '../config'; +import { + modelCategories, + modelCategoriesMap, + modelSourceMap, + MyModelsStatusLabelMap, + MyModelsStatusMap, + MyModelsStatusValueMap +} from '../config'; import { categoryToPathMap } from '../config/button-actions'; import { categoryConfig } from './model-tag'; -const MyModelsStatusValueMap = { - Inactive: 'Inactive', - Starting: 'Starting', - Degrade: 'Degrade', - Active: 'Active' -}; - -const MyModelsStatusMap = { - [MyModelsStatusValueMap.Inactive]: StatusMaps.inactive, - [MyModelsStatusValueMap.Starting]: StatusMaps.transitioning, - [MyModelsStatusValueMap.Degrade]: StatusMaps.warning, - [MyModelsStatusValueMap.Active]: StatusMaps.success -}; - const CardWrapper = styled.div` &:hover { .content { @@ -36,6 +29,14 @@ const CardWrapper = styled.div` } `; +const Dot = styled.span` + background-color: var(--ant-color-text-quaternary); + border-radius: 50%; + flex: none; + height: 3px; + width: 3px; +`; + const ModelItemContent = styled.div` display: flex; flex-direction: column; @@ -63,6 +64,7 @@ const ModelItemContent = styled.div` font-weight: 400; } .extra-info { + width: 100%; display: flex; align-items: center; gap: 8px; @@ -105,6 +107,14 @@ const sourceIconMap = { [modelSourceMap.modelscope_value]: 'icon-tu2' }; +const renderTag = (item: any, index = 0) => { + return ( + + {item} + + ); +}; + const ModelItem: React.FC<{ model: Record; onClick: (model: any) => void; @@ -155,16 +165,15 @@ const ModelItem: React.FC<{ if (!model.replicas && !model.ready_replicas) { return MyModelsStatusValueMap.Inactive; } + if (model.replicas > 0 && !model.ready_replicas) { - return MyModelsStatusValueMap.Starting; - } - if (model.replicas > 1 && model.replicas !== model.ready_replicas) { return MyModelsStatusValueMap.Degrade; } + if (model.replicas === model.ready_replicas && model.replicas > 0) { return MyModelsStatusValueMap.Active; } - return MyModelsStatusValueMap.Inactive; + return MyModelsStatusValueMap.Degrade; }, [model]); return ( @@ -177,18 +186,20 @@ const ModelItem: React.FC<{ ghost header={
- + {model.name} @@ -214,16 +225,27 @@ const ModelItem: React.FC<{ ); })} + {maxToken > 0 && ( - - {maxToken}K context - + <> + + + {maxToken}K context + + + )} + {model.meta?.voices?.length > 0 && ( + <> + + + )} - {[ - MyModelsStatusValueMap.Active, - MyModelsStatusValueMap.Degrade - ].includes(status) && ( + {[MyModelsStatusValueMap.Active].includes(model.status) && (