diff --git a/.lintstagedrc b/.lintstagedrc
index a515e5e0..2a377a0c 100644
--- a/.lintstagedrc
+++ b/.lintstagedrc
@@ -2,7 +2,7 @@
"*.{md,json}": ["prettier --cache --write"],
"*.{js,jsx}": ["max lint --fix --eslint-only", "prettier --cache --write"],
"*.{css,less}": [
- "max lint --fix --stylelint-only",
+ "node ./scripts/stylelint-compat.cjs --fix --allow-empty-input",
"prettier --cache --write"
],
"!public/vs/**": [],
@@ -10,5 +10,5 @@
"max lint --fix --eslint-only",
"prettier --cache --parser=typescript --write"
],
- "src/locales/**/*.ts": ["npx tsx src/locales/check.ts"]
+ "src/locales/**/*.ts": ["node --import tsx src/locales/check.ts"]
}
diff --git a/package.json b/package.json
index 4cc41241..c438ac4f 100644
--- a/package.json
+++ b/package.json
@@ -1,10 +1,10 @@
{
"private": true,
- "author": "jialin",
+ "author": "gpustack",
"scripts": {
"build": "max build",
"build:enterprise": "node ./scripts/run-enterprise-build.cjs",
- "check:locales": "npx tsx ./src/locales/check.ts",
+ "check:locales": "node --import tsx ./src/locales/check.ts",
"dev": "max dev",
"dev:enterprise": "node ./scripts/run-enterprise-dev.cjs",
"format": "prettier --cache --write .",
@@ -22,7 +22,7 @@
"@ant-design/icons": "^6.1.0",
"@ant-design/pro-components": "3.1.0-0",
"@braintree/sanitize-url": "^7.1.1",
- "@gpustack/core-ui": "^1.0.0",
+ "@gpustack/core-ui": "^1.0.1",
"@huggingface/gguf": "^0.1.7",
"@huggingface/hub": "^0.15.1",
"@huggingface/tasks": "^0.11.6",
diff --git a/scripts/stylelint-compat.cjs b/scripts/stylelint-compat.cjs
new file mode 100644
index 00000000..454cf36d
--- /dev/null
+++ b/scripts/stylelint-compat.cjs
@@ -0,0 +1,32 @@
+const fs = require('fs');
+const path = require('path');
+const { spawnSync } = require('child_process');
+
+const pnpmDir = path.resolve(__dirname, '../../../node_modules/.pnpm');
+
+function findDir(prefix) {
+ return fs.readdirSync(pnpmDir).find((name) => name.startsWith(prefix));
+}
+
+const stylelintDir = findDir('stylelint@14.8.2');
+if (!stylelintDir) {
+ console.error('Compatible stylelint@14.8.2 not found in workspace node_modules/.pnpm');
+ process.exit(1);
+}
+
+const stylelintBin = path.join(
+ pnpmDir,
+ stylelintDir,
+ 'node_modules/stylelint/bin/stylelint.js'
+);
+
+const result = spawnSync(process.execPath, [stylelintBin, ...process.argv.slice(2)], {
+ stdio: 'inherit',
+ cwd: process.cwd(),
+});
+
+if (result.error) {
+ console.error(result.error);
+}
+
+process.exit(result.status ?? 1);
diff --git a/src/global.less b/src/global.less
index 903a1062..7d9ac681 100644
--- a/src/global.less
+++ b/src/global.less
@@ -169,7 +169,7 @@ body {
}
}
- .ant-table-container table {
+ .ant-table .ant-table-container table {
// border-spacing: 0 20px;
.ant-table-thead th.ant-table-column-sort {
diff --git a/src/layouts/extraRender.tsx b/src/layouts/extraRender.tsx
index a2e64a1e..9672dce5 100644
--- a/src/layouts/extraRender.tsx
+++ b/src/layouts/extraRender.tsx
@@ -294,18 +294,6 @@ export const ExtraContent = (props: { isDarkTheme?: boolean }) => {
)}
-
{
config={{
apiBaseUrl: GPUSTACK_API_BASE_URL,
theme: userSettings.theme,
- iconUrl: '//at.alicdn.com/t/c/font_4613488_8fi68fmt1th.js',
+ iconUrl: '//at.alicdn.com/t/c/font_4613488_mk9rqojjoqk.js',
isDarkTheme: userSettings.isDarkTheme,
defaultColorPrimary: COLOR_PRIMARY
}}
diff --git a/src/layouts/rightRender.tsx b/src/layouts/rightRender.tsx
index c9f8fd58..3624be09 100644
--- a/src/layouts/rightRender.tsx
+++ b/src/layouts/rightRender.tsx
@@ -1,6 +1,5 @@
// @ts-nocheck
import avatarImg from '@/assets/images/avatar.png';
-import IconFont from '@/components/icon-font';
import externalLinks from '@/constants/external-links';
import {
DiscordOutlined,
@@ -12,6 +11,7 @@ import {
ReadOutlined,
SettingOutlined
} from '@ant-design/icons';
+import { IconFont } from '@gpustack/core-ui';
import { getAllLocales, history } from '@umijs/max';
import { Avatar, Menu, Spin } from 'antd';
import _ from 'lodash';
diff --git a/src/locales/en-US/menu.ts b/src/locales/en-US/menu.ts
index aae53820..0605e5fa 100644
--- a/src/locales/en-US/menu.ts
+++ b/src/locales/en-US/menu.ts
@@ -22,6 +22,7 @@ export default {
'menu.models.usage': 'Usage',
'menu.modelCatalog': 'Catalog',
'menu.resources': 'Resources',
+ 'menu.settings': 'Settings',
'menu.apikeys': 'API Keys',
'menu.users': 'Users',
'menu.resources.workers': 'Workers',
diff --git a/src/locales/ja-JP/menu.ts b/src/locales/ja-JP/menu.ts
index d5251429..e7d6fe68 100644
--- a/src/locales/ja-JP/menu.ts
+++ b/src/locales/ja-JP/menu.ts
@@ -27,6 +27,7 @@ export default {
'menu.login': 'ログイン',
'menu.usage': '使用状況',
'menu.404': '404',
+ 'menu.settings': 'Settings',
'menu.resources.workers': 'Workers',
'menu.resources.gpus': 'GPUs',
'menu.resources.modelfiles': 'Model Files',
diff --git a/src/locales/ru-RU/menu.ts b/src/locales/ru-RU/menu.ts
index 1bf03b96..708ac869 100644
--- a/src/locales/ru-RU/menu.ts
+++ b/src/locales/ru-RU/menu.ts
@@ -39,7 +39,8 @@ export default {
'menu.models.userModels': 'Мои модели',
'menu.clusterManagement.clusterDetail': 'Детали кластера',
'menu.clusterManagement.clusterCreate': 'Создать кластер',
- 'menu.resources.backendsList': 'Бэкенды запуска'
+ 'menu.resources.backendsList': 'Бэкенды запуска',
+ 'menu.settings': 'Settings'
};
// ========== To-Do: Translate Keys (Remove After Translation) ==========
diff --git a/src/locales/tr-TR/menu.ts b/src/locales/tr-TR/menu.ts
index 34b95d65..a75540be 100644
--- a/src/locales/tr-TR/menu.ts
+++ b/src/locales/tr-TR/menu.ts
@@ -39,7 +39,8 @@ export default {
'menu.clusterManagement.clusterDetail': 'Küme Detayı',
'menu.clusterManagement.clusterCreate': 'Küme Oluştur',
'menu.resources.backendsList': 'Çıkarım Altyapıları',
- 'menu.models.instances': 'Instances'
+ 'menu.models.instances': 'Instances',
+ 'menu.settings': 'Settings'
};
// ========== To-Do: Translate Keys (Remove After Translation) ==========
diff --git a/src/locales/zh-CN/menu.ts b/src/locales/zh-CN/menu.ts
index 0927abfb..27ba73de 100644
--- a/src/locales/zh-CN/menu.ts
+++ b/src/locales/zh-CN/menu.ts
@@ -21,6 +21,7 @@ export default {
'menu.models.usage': '用量统计',
'menu.modelCatalog': '模型库',
'menu.models.catalog': '模型库',
+ 'menu.settings': '设置',
'menu.resources': '资源',
'menu.apikeys': 'API 密钥',
'menu.users': '用户',
diff --git a/src/pages/api-keys/components/add-apikey-modal/index.tsx b/src/pages/api-keys/components/add-apikey-modal/index.tsx
index c57629af..e91b8fe4 100644
--- a/src/pages/api-keys/components/add-apikey-modal/index.tsx
+++ b/src/pages/api-keys/components/add-apikey-modal/index.tsx
@@ -201,10 +201,11 @@ const AddModal: React.FC = ({
};
useEffect(() => {
- initValues();
if (!open) {
setIsChanged(false);
cacheFormRef.current = {} as any;
+ } else {
+ initValues();
}
}, [open]);
diff --git a/src/pages/api-keys/index.tsx b/src/pages/api-keys/index.tsx
index a6304f1b..ace36760 100644
--- a/src/pages/api-keys/index.tsx
+++ b/src/pages/api-keys/index.tsx
@@ -182,7 +182,7 @@ const APIKeys: React.FC = () => {
rowSelection={rowSelection}
loading={{
spinning: dataSource.loading,
- size: 'default'
+ size: 'middle'
}}
sortDirections={TABLE_SORT_DIRECTIONS}
showSorterTooltip={false}
diff --git a/src/pages/cluster-management/components/k8s-volume-mount.tsx b/src/pages/cluster-management/components/k8s-volume-mount.tsx
index 09133422..dcb7af36 100644
--- a/src/pages/cluster-management/components/k8s-volume-mount.tsx
+++ b/src/pages/cluster-management/components/k8s-volume-mount.tsx
@@ -206,6 +206,7 @@ const VolumeMountsForm: React.FC<{ action: PageActionType }> = ({ action }) => {
]}
>
{
}
}
];
+
+ const generateRowKey = (record: any) => {
+ return record.provider_name
+ ? `${record.provider_name}/${record.name}`
+ : record.name;
+ };
+
return (
@@ -101,7 +108,7 @@ const ActiveTable = () => {
columns={modelColumns}
dataSource={data}
pagination={false}
- rowKey="id"
+ rowKey={generateRowKey}
/>
diff --git a/src/pages/dashboard/components/usage-inner/filter-bar.tsx b/src/pages/dashboard/components/usage-inner/filter-bar.tsx
index 416ea4ae..fb1e9534 100644
--- a/src/pages/dashboard/components/usage-inner/filter-bar.tsx
+++ b/src/pages/dashboard/components/usage-inner/filter-bar.tsx
@@ -152,6 +152,7 @@ const FilterBar: React.FC = (props) => {
placeholder={intl.formatMessage({
id: 'dashboard.usage.selectmodel'
})}
+ isInFormItems={false}
options={modelList}
value={selectedModels}
showCheckedStrategy="SHOW_CHILD"
diff --git a/src/pages/playground/embedding/page.tsx b/src/pages/playground/embedding/page.tsx
index 75f12759..3febd6e9 100644
--- a/src/pages/playground/embedding/page.tsx
+++ b/src/pages/playground/embedding/page.tsx
@@ -10,7 +10,7 @@ import {
InputNumber as CInputNumber,
HighlightCode,
IconFont,
- ResizeContainer,
+ ResizePanel,
ScatterChart,
useOverlayScroller
} from '@gpustack/core-ui';
@@ -691,7 +691,7 @@ const GroundEmbedding: React.FC = forwardRef((props, ref) => {
)}
- = forwardRef((props, ref) => {
items={outputItems}
>
-
+
diff --git a/src/pages/usage/components/daily-usage.tsx b/src/pages/usage/components/daily-usage.tsx
index c85f674a..56000eb5 100644
--- a/src/pages/usage/components/daily-usage.tsx
+++ b/src/pages/usage/components/daily-usage.tsx
@@ -1,7 +1,5 @@
-import CardWrapper from '@/components/card-wrapper';
-import MixLineBar from '@/components/echarts/mix-line-bar';
-import BaseSelect from '@/components/seal-form/base/select';
import { baseColorMap } from '@/pages/dashboard/config';
+import { BaseSelect, CardWrapper, MixLineBarChart } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
import { Segmented } from 'antd';
import dayjs from 'dayjs';
@@ -172,7 +170,7 @@ const DailyUsage: React.FC = (props) => {
onChange={onGranularityChange}
>
- = (props) => {
minWidth: 200
}}
>
- = (props) => {
}}
maxTagCount={1}
size="small"
+ isInFormItems={false}
placeholder={intl.formatMessage({ id: 'usage.filter.model' })}
options={modelOptions}
showCheckedStrategy="SHOW_CHILD"
@@ -339,7 +342,7 @@ const FilterBar: React.FC = (props) => {
value={activeModels}
onChange={handleOnModelsChange}
getPopupContainer={(triggerNode) => triggerNode.parentNode}
- >
+ >
{initialState?.currentUser?.is_admin && (
<>
@@ -363,8 +366,9 @@ const FilterBar: React.FC = (props) => {
minWidth: 200
}}
>
- = (props) => {
optionNode={apiKeyOptionRender}
onChange={handleOnApiKeysChange}
getPopupContainer={(triggerNode) => triggerNode.parentNode}
- >
+ >
>
)}
diff --git a/src/pages/usage/hooks/use-apikeys-columns.tsx b/src/pages/usage/hooks/use-apikeys-columns.tsx
index be004243..876a234c 100644
--- a/src/pages/usage/hooks/use-apikeys-columns.tsx
+++ b/src/pages/usage/hooks/use-apikeys-columns.tsx
@@ -1,5 +1,5 @@
// columns.ts
-import AutoTooltip from '@/components/auto-tooltip';
+import { AutoTooltip } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
import { Tag } from 'antd';
import { useMemo } from 'react';
diff --git a/src/pages/usage/hooks/use-models-columns.tsx b/src/pages/usage/hooks/use-models-columns.tsx
index 107f9a04..f49125bf 100644
--- a/src/pages/usage/hooks/use-models-columns.tsx
+++ b/src/pages/usage/hooks/use-models-columns.tsx
@@ -1,6 +1,6 @@
// columns.ts
-import AutoTooltip from '@/components/auto-tooltip';
import ProviderLogo from '@/pages/maas-provider/components/provider-logo';
+import { AutoTooltip } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
import { Tag } from 'antd';
import { useMemo } from 'react';
diff --git a/src/pages/usage/hooks/use-users-columns.tsx b/src/pages/usage/hooks/use-users-columns.tsx
index 620d963d..b3d97e57 100644
--- a/src/pages/usage/hooks/use-users-columns.tsx
+++ b/src/pages/usage/hooks/use-users-columns.tsx
@@ -1,5 +1,5 @@
// columns.ts
-import AutoTooltip from '@/components/auto-tooltip';
+import { AutoTooltip } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
import { Tag } from 'antd';
import { useMemo } from 'react';
diff --git a/src/pages/usage/index.tsx b/src/pages/usage/index.tsx
index e72faffe..bece2cf8 100644
--- a/src/pages/usage/index.tsx
+++ b/src/pages/usage/index.tsx
@@ -1,7 +1,7 @@
-import { SimpleCard } from '@/components/card-wrapper/simple-card';
import { baseColorMap } from '@/pages/dashboard/config';
import { formatLargeNumber } from '@/utils';
import { useModel } from '@@/plugin-model';
+import { SimpleCard } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
import React, { useEffect, useMemo, useState } from 'react';
import BreakdownTabs from './components/breakdown-tabs';
diff --git a/src/pages/usage/tables/apikeys-table.tsx b/src/pages/usage/tables/apikeys-table.tsx
index f55eb26b..622238ce 100644
--- a/src/pages/usage/tables/apikeys-table.tsx
+++ b/src/pages/usage/tables/apikeys-table.tsx
@@ -1,7 +1,6 @@
-import IconFont from '@/components/icon-font';
import { TABLE_SORT_DIRECTIONS } from '@/config/settings';
-import NoResult from '@/pages/_components/no-result';
import PageBox from '@/pages/_components/page-box';
+import { IconFont, NoResult } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
import { ConfigProvider, Table } from 'antd';
import _ from 'lodash';
@@ -35,7 +34,7 @@ const APIKeys: React.FC<{
const pendingPageResetRef = useRef(false);
const handleTableChange = (pagination: any, filters: any, sorter: any) => {
- let sort_by =
+ const sort_by =
sorter.order === 'descend' ? `-${sorter.field}` : sorter.field;
setQueryParams((prev) => ({
...prev,
diff --git a/src/pages/usage/tables/models-table.tsx b/src/pages/usage/tables/models-table.tsx
index 37aa14cb..b5e11e03 100644
--- a/src/pages/usage/tables/models-table.tsx
+++ b/src/pages/usage/tables/models-table.tsx
@@ -1,7 +1,6 @@
-import IconFont from '@/components/icon-font';
import { TABLE_SORT_DIRECTIONS } from '@/config/settings';
-import NoResult from '@/pages/_components/no-result';
import PageBox from '@/pages/_components/page-box';
+import { IconFont, NoResult } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
import { ConfigProvider, Table } from 'antd';
import _ from 'lodash';
@@ -36,7 +35,7 @@ const Models: React.FC<{
const handleTableChange = (pagination: any, filters: any, sorter: any) => {
console.log('pagination, filters, sorter: ', pagination, filters, sorter);
- let sort_by =
+ const sort_by =
sorter.order === 'descend' ? `-${sorter.field}` : sorter.field;
setQueryParams((prev) => ({
...prev,
diff --git a/src/pages/usage/tables/users-table.tsx b/src/pages/usage/tables/users-table.tsx
index dde66e43..c1744ac5 100644
--- a/src/pages/usage/tables/users-table.tsx
+++ b/src/pages/usage/tables/users-table.tsx
@@ -1,7 +1,6 @@
-import IconFont from '@/components/icon-font';
import { TABLE_SORT_DIRECTIONS } from '@/config/settings';
-import NoResult from '@/pages/_components/no-result';
import PageBox from '@/pages/_components/page-box';
+import { IconFont, NoResult } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
import { ConfigProvider, Table } from 'antd';
import _ from 'lodash';
@@ -35,7 +34,7 @@ const Users: React.FC<{
const pendingPageResetRef = useRef(false);
const handleTableChange = (pagination: any, filters: any, sorter: any) => {
- let sort_by =
+ const sort_by =
sorter.order === 'descend' ? `-${sorter.field}` : sorter.field;
setQueryParams((prev) => ({
...prev,