fix: rebase main

This commit is contained in:
jialin
2026-04-24 14:28:30 +08:00
committed by jialin
parent 16449613e0
commit 597a86562a
28 changed files with 88 additions and 56 deletions
+2 -2
View File
@@ -2,7 +2,7 @@
"*.{md,json}": ["prettier --cache --write"], "*.{md,json}": ["prettier --cache --write"],
"*.{js,jsx}": ["max lint --fix --eslint-only", "prettier --cache --write"], "*.{js,jsx}": ["max lint --fix --eslint-only", "prettier --cache --write"],
"*.{css,less}": [ "*.{css,less}": [
"max lint --fix --stylelint-only", "node ./scripts/stylelint-compat.cjs --fix --allow-empty-input",
"prettier --cache --write" "prettier --cache --write"
], ],
"!public/vs/**": [], "!public/vs/**": [],
@@ -10,5 +10,5 @@
"max lint --fix --eslint-only", "max lint --fix --eslint-only",
"prettier --cache --parser=typescript --write" "prettier --cache --parser=typescript --write"
], ],
"src/locales/**/*.ts": ["npx tsx src/locales/check.ts"] "src/locales/**/*.ts": ["node --import tsx src/locales/check.ts"]
} }
+3 -3
View File
@@ -1,10 +1,10 @@
{ {
"private": true, "private": true,
"author": "jialin", "author": "gpustack",
"scripts": { "scripts": {
"build": "max build", "build": "max build",
"build:enterprise": "node ./scripts/run-enterprise-build.cjs", "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": "max dev",
"dev:enterprise": "node ./scripts/run-enterprise-dev.cjs", "dev:enterprise": "node ./scripts/run-enterprise-dev.cjs",
"format": "prettier --cache --write .", "format": "prettier --cache --write .",
@@ -22,7 +22,7 @@
"@ant-design/icons": "^6.1.0", "@ant-design/icons": "^6.1.0",
"@ant-design/pro-components": "3.1.0-0", "@ant-design/pro-components": "3.1.0-0",
"@braintree/sanitize-url": "^7.1.1", "@braintree/sanitize-url": "^7.1.1",
"@gpustack/core-ui": "^1.0.0", "@gpustack/core-ui": "^1.0.1",
"@huggingface/gguf": "^0.1.7", "@huggingface/gguf": "^0.1.7",
"@huggingface/hub": "^0.15.1", "@huggingface/hub": "^0.15.1",
"@huggingface/tasks": "^0.11.6", "@huggingface/tasks": "^0.11.6",
+32
View File
@@ -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);
+1 -1
View File
@@ -169,7 +169,7 @@ body {
} }
} }
.ant-table-container table { .ant-table .ant-table-container table {
// border-spacing: 0 20px; // border-spacing: 0 20px;
.ant-table-thead th.ant-table-column-sort { .ant-table-thead th.ant-table-column-sort {
-12
View File
@@ -294,18 +294,6 @@ export const ExtraContent = (props: { isDarkTheme?: boolean }) => {
</NewLabel> </NewLabel>
)} )}
</div> </div>
<Button
type="text"
size="small"
onClick={() => {
history.push('/settings');
}}
style={{
color: 'var(--ant-color-text-tertiary)'
}}
>
<IconFont type="icon-settings-02" style={{ fontSize: 18 }} />
</Button>
<DropdownActions menu={{ ...helpMenu }} popupRender={helpPopupRender}> <DropdownActions menu={{ ...helpMenu }} popupRender={helpPopupRender}>
<IconWrapper> <IconWrapper>
<IconFont <IconFont
+1 -1
View File
@@ -365,7 +365,7 @@ export default (props: any) => {
config={{ config={{
apiBaseUrl: GPUSTACK_API_BASE_URL, apiBaseUrl: GPUSTACK_API_BASE_URL,
theme: userSettings.theme, 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, isDarkTheme: userSettings.isDarkTheme,
defaultColorPrimary: COLOR_PRIMARY defaultColorPrimary: COLOR_PRIMARY
}} }}
+1 -1
View File
@@ -1,6 +1,5 @@
// @ts-nocheck // @ts-nocheck
import avatarImg from '@/assets/images/avatar.png'; import avatarImg from '@/assets/images/avatar.png';
import IconFont from '@/components/icon-font';
import externalLinks from '@/constants/external-links'; import externalLinks from '@/constants/external-links';
import { import {
DiscordOutlined, DiscordOutlined,
@@ -12,6 +11,7 @@ import {
ReadOutlined, ReadOutlined,
SettingOutlined SettingOutlined
} from '@ant-design/icons'; } from '@ant-design/icons';
import { IconFont } from '@gpustack/core-ui';
import { getAllLocales, history } from '@umijs/max'; import { getAllLocales, history } from '@umijs/max';
import { Avatar, Menu, Spin } from 'antd'; import { Avatar, Menu, Spin } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
+1
View File
@@ -22,6 +22,7 @@ export default {
'menu.models.usage': 'Usage', 'menu.models.usage': 'Usage',
'menu.modelCatalog': 'Catalog', 'menu.modelCatalog': 'Catalog',
'menu.resources': 'Resources', 'menu.resources': 'Resources',
'menu.settings': 'Settings',
'menu.apikeys': 'API Keys', 'menu.apikeys': 'API Keys',
'menu.users': 'Users', 'menu.users': 'Users',
'menu.resources.workers': 'Workers', 'menu.resources.workers': 'Workers',
+1
View File
@@ -27,6 +27,7 @@ export default {
'menu.login': 'ログイン', 'menu.login': 'ログイン',
'menu.usage': '使用状況', 'menu.usage': '使用状況',
'menu.404': '404', 'menu.404': '404',
'menu.settings': 'Settings',
'menu.resources.workers': 'Workers', 'menu.resources.workers': 'Workers',
'menu.resources.gpus': 'GPUs', 'menu.resources.gpus': 'GPUs',
'menu.resources.modelfiles': 'Model Files', 'menu.resources.modelfiles': 'Model Files',
+2 -1
View File
@@ -39,7 +39,8 @@ export default {
'menu.models.userModels': 'Мои модели', 'menu.models.userModels': 'Мои модели',
'menu.clusterManagement.clusterDetail': 'Детали кластера', 'menu.clusterManagement.clusterDetail': 'Детали кластера',
'menu.clusterManagement.clusterCreate': 'Создать кластер', 'menu.clusterManagement.clusterCreate': 'Создать кластер',
'menu.resources.backendsList': 'Бэкенды запуска' 'menu.resources.backendsList': 'Бэкенды запуска',
'menu.settings': 'Settings'
}; };
// ========== To-Do: Translate Keys (Remove After Translation) ========== // ========== To-Do: Translate Keys (Remove After Translation) ==========
+2 -1
View File
@@ -39,7 +39,8 @@ export default {
'menu.clusterManagement.clusterDetail': 'Küme Detayı', 'menu.clusterManagement.clusterDetail': 'Küme Detayı',
'menu.clusterManagement.clusterCreate': 'Küme Oluştur', 'menu.clusterManagement.clusterCreate': 'Küme Oluştur',
'menu.resources.backendsList': 'Çıkarım Altyapıları', '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) ========== // ========== To-Do: Translate Keys (Remove After Translation) ==========
+1
View File
@@ -21,6 +21,7 @@ export default {
'menu.models.usage': '用量统计', 'menu.models.usage': '用量统计',
'menu.modelCatalog': '模型库', 'menu.modelCatalog': '模型库',
'menu.models.catalog': '模型库', 'menu.models.catalog': '模型库',
'menu.settings': '设置',
'menu.resources': '资源', 'menu.resources': '资源',
'menu.apikeys': 'API 密钥', 'menu.apikeys': 'API 密钥',
'menu.users': '用户', 'menu.users': '用户',
@@ -201,10 +201,11 @@ const AddModal: React.FC<AddModalProps> = ({
}; };
useEffect(() => { useEffect(() => {
initValues();
if (!open) { if (!open) {
setIsChanged(false); setIsChanged(false);
cacheFormRef.current = {} as any; cacheFormRef.current = {} as any;
} else {
initValues();
} }
}, [open]); }, [open]);
+1 -1
View File
@@ -182,7 +182,7 @@ const APIKeys: React.FC = () => {
rowSelection={rowSelection} rowSelection={rowSelection}
loading={{ loading={{
spinning: dataSource.loading, spinning: dataSource.loading,
size: 'default' size: 'middle'
}} }}
sortDirections={TABLE_SORT_DIRECTIONS} sortDirections={TABLE_SORT_DIRECTIONS}
showSorterTooltip={false} showSorterTooltip={false}
@@ -206,6 +206,7 @@ const VolumeMountsForm: React.FC<{ action: PageActionType }> = ({ action }) => {
]} ]}
> >
<CInput.Input <CInput.Input
disabled={name === 0}
label={intl.formatMessage({ label={intl.formatMessage({
id: 'clusters.volume.name' id: 'clusters.volume.name'
})} })}
@@ -80,6 +80,13 @@ const ActiveTable = () => {
} }
} }
]; ];
const generateRowKey = (record: any) => {
return record.provider_name
? `${record.provider_name}/${record.name}`
: record.name;
};
return ( return (
<Row gutter={[20, 0]}> <Row gutter={[20, 0]}>
<Col xs={24} sm={24} md={24} lg={24} xl={24}> <Col xs={24} sm={24} md={24} lg={24} xl={24}>
@@ -101,7 +108,7 @@ const ActiveTable = () => {
columns={modelColumns} columns={modelColumns}
dataSource={data} dataSource={data}
pagination={false} pagination={false}
rowKey="id" rowKey={generateRowKey}
/> />
</div> </div>
</Col> </Col>
@@ -152,6 +152,7 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
placeholder={intl.formatMessage({ placeholder={intl.formatMessage({
id: 'dashboard.usage.selectmodel' id: 'dashboard.usage.selectmodel'
})} })}
isInFormItems={false}
options={modelList} options={modelList}
value={selectedModels} value={selectedModels}
showCheckedStrategy="SHOW_CHILD" showCheckedStrategy="SHOW_CHILD"
+3 -3
View File
@@ -10,7 +10,7 @@ import {
InputNumber as CInputNumber, InputNumber as CInputNumber,
HighlightCode, HighlightCode,
IconFont, IconFont,
ResizeContainer, ResizePanel,
ScatterChart, ScatterChart,
useOverlayScroller useOverlayScroller
} from '@gpustack/core-ui'; } from '@gpustack/core-ui';
@@ -691,7 +691,7 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
<Spin spinning={true} size="middle"></Spin> <Spin spinning={true} size="middle"></Spin>
</div> </div>
)} )}
<ResizeContainer <ResizePanel
ref={resizeRef} ref={resizeRef}
maxHeight={resizeMaxHeight} maxHeight={resizeMaxHeight}
minHeight={180} minHeight={180}
@@ -715,7 +715,7 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
items={outputItems} items={outputItems}
></Tabs> ></Tabs>
</div> </div>
</ResizeContainer> </ResizePanel>
</div> </div>
</div> </div>
</div> </div>
+2 -4
View File
@@ -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 { baseColorMap } from '@/pages/dashboard/config';
import { BaseSelect, CardWrapper, MixLineBarChart } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Segmented } from 'antd'; import { Segmented } from 'antd';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
@@ -172,7 +170,7 @@ const DailyUsage: React.FC<DailyUsageProps> = (props) => {
onChange={onGranularityChange} onChange={onGranularityChange}
></Segmented> ></Segmented>
</ControlsWrapper> </ControlsWrapper>
<MixLineBar <MixLineBarChart
chartData={chartData} chartData={chartData}
seriesData={[]} seriesData={[]}
xAxisData={xAxisData} xAxisData={xAxisData}
+1 -3
View File
@@ -1,7 +1,5 @@
import AutoTooltip from '@/components/auto-tooltip';
import ModalFooter from '@/components/modal-footer';
import ScrollerModal from '@/components/scroller-modal';
import { exportJsonToExcel } from '@/utils/excel-reader'; import { exportJsonToExcel } from '@/utils/excel-reader';
import { AutoTooltip, ModalFooter, ScrollerModal } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Table, TableColumnType } from 'antd'; import { Table, TableColumnType } from 'antd';
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
+12 -8
View File
@@ -1,11 +1,13 @@
import AutoTooltip from '@/components/auto-tooltip';
import IconFont from '@/components/icon-font';
import SealCascader from '@/components/seal-form/seal-cascader';
import SimpleSelect from '@/components/seal-form/simple-select';
import useRangePickerPreset from '@/pages/dashboard/hooks/use-rangepicker-preset'; import useRangePickerPreset from '@/pages/dashboard/hooks/use-rangepicker-preset';
import ProviderLogo from '@/pages/maas-provider/components/provider-logo'; import ProviderLogo from '@/pages/maas-provider/components/provider-logo';
import { useModel } from '@@/plugin-model'; import { useModel } from '@@/plugin-model';
import { DownloadOutlined, SyncOutlined } from '@ant-design/icons'; import { DownloadOutlined, SyncOutlined } from '@ant-design/icons';
import {
AutoTooltip,
Cascader,
IconFont,
SimpleSelect
} from '@gpustack/core-ui';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Button, DatePicker, Dropdown, MenuProps } from 'antd'; import { Button, DatePicker, Dropdown, MenuProps } from 'antd';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
@@ -308,7 +310,7 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
minWidth: 200 minWidth: 200
}} }}
> >
<SealCascader <Cascader
showSearch showSearch
multiple={true} multiple={true}
classNames={{ classNames={{
@@ -331,6 +333,7 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
}} }}
maxTagCount={1} maxTagCount={1}
size="small" size="small"
isInFormItems={false}
placeholder={intl.formatMessage({ id: 'usage.filter.model' })} placeholder={intl.formatMessage({ id: 'usage.filter.model' })}
options={modelOptions} options={modelOptions}
showCheckedStrategy="SHOW_CHILD" showCheckedStrategy="SHOW_CHILD"
@@ -339,7 +342,7 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
value={activeModels} value={activeModels}
onChange={handleOnModelsChange} onChange={handleOnModelsChange}
getPopupContainer={(triggerNode) => triggerNode.parentNode} getPopupContainer={(triggerNode) => triggerNode.parentNode}
></SealCascader> ></Cascader>
</div> </div>
{initialState?.currentUser?.is_admin && ( {initialState?.currentUser?.is_admin && (
<> <>
@@ -363,8 +366,9 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
minWidth: 200 minWidth: 200
}} }}
> >
<SealCascader <Cascader
showSearch showSearch
isInFormItems={false}
multiple={true} multiple={true}
classNames={{ classNames={{
popup: { popup: {
@@ -393,7 +397,7 @@ const FilterBar: React.FC<FilterBarProps> = (props) => {
optionNode={apiKeyOptionRender} optionNode={apiKeyOptionRender}
onChange={handleOnApiKeysChange} onChange={handleOnApiKeysChange}
getPopupContainer={(triggerNode) => triggerNode.parentNode} getPopupContainer={(triggerNode) => triggerNode.parentNode}
></SealCascader> ></Cascader>
</div> </div>
</> </>
)} )}
@@ -1,5 +1,5 @@
// columns.ts // columns.ts
import AutoTooltip from '@/components/auto-tooltip'; import { AutoTooltip } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Tag } from 'antd'; import { Tag } from 'antd';
import { useMemo } from 'react'; import { useMemo } from 'react';
+1 -1
View File
@@ -1,6 +1,6 @@
// columns.ts // columns.ts
import AutoTooltip from '@/components/auto-tooltip';
import ProviderLogo from '@/pages/maas-provider/components/provider-logo'; import ProviderLogo from '@/pages/maas-provider/components/provider-logo';
import { AutoTooltip } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Tag } from 'antd'; import { Tag } from 'antd';
import { useMemo } from 'react'; import { useMemo } from 'react';
+1 -1
View File
@@ -1,5 +1,5 @@
// columns.ts // columns.ts
import AutoTooltip from '@/components/auto-tooltip'; import { AutoTooltip } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Tag } from 'antd'; import { Tag } from 'antd';
import { useMemo } from 'react'; import { useMemo } from 'react';
+1 -1
View File
@@ -1,7 +1,7 @@
import { SimpleCard } from '@/components/card-wrapper/simple-card';
import { baseColorMap } from '@/pages/dashboard/config'; import { baseColorMap } from '@/pages/dashboard/config';
import { formatLargeNumber } from '@/utils'; import { formatLargeNumber } from '@/utils';
import { useModel } from '@@/plugin-model'; import { useModel } from '@@/plugin-model';
import { SimpleCard } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import React, { useEffect, useMemo, useState } from 'react'; import React, { useEffect, useMemo, useState } from 'react';
import BreakdownTabs from './components/breakdown-tabs'; import BreakdownTabs from './components/breakdown-tabs';
+2 -3
View File
@@ -1,7 +1,6 @@
import IconFont from '@/components/icon-font';
import { TABLE_SORT_DIRECTIONS } from '@/config/settings'; import { TABLE_SORT_DIRECTIONS } from '@/config/settings';
import NoResult from '@/pages/_components/no-result';
import PageBox from '@/pages/_components/page-box'; import PageBox from '@/pages/_components/page-box';
import { IconFont, NoResult } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { ConfigProvider, Table } from 'antd'; import { ConfigProvider, Table } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
@@ -35,7 +34,7 @@ const APIKeys: React.FC<{
const pendingPageResetRef = useRef(false); const pendingPageResetRef = useRef(false);
const handleTableChange = (pagination: any, filters: any, sorter: any) => { const handleTableChange = (pagination: any, filters: any, sorter: any) => {
let sort_by = const sort_by =
sorter.order === 'descend' ? `-${sorter.field}` : sorter.field; sorter.order === 'descend' ? `-${sorter.field}` : sorter.field;
setQueryParams((prev) => ({ setQueryParams((prev) => ({
...prev, ...prev,
+2 -3
View File
@@ -1,7 +1,6 @@
import IconFont from '@/components/icon-font';
import { TABLE_SORT_DIRECTIONS } from '@/config/settings'; import { TABLE_SORT_DIRECTIONS } from '@/config/settings';
import NoResult from '@/pages/_components/no-result';
import PageBox from '@/pages/_components/page-box'; import PageBox from '@/pages/_components/page-box';
import { IconFont, NoResult } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { ConfigProvider, Table } from 'antd'; import { ConfigProvider, Table } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
@@ -36,7 +35,7 @@ const Models: React.FC<{
const handleTableChange = (pagination: any, filters: any, sorter: any) => { const handleTableChange = (pagination: any, filters: any, sorter: any) => {
console.log('pagination, filters, sorter: ', pagination, filters, sorter); console.log('pagination, filters, sorter: ', pagination, filters, sorter);
let sort_by = const sort_by =
sorter.order === 'descend' ? `-${sorter.field}` : sorter.field; sorter.order === 'descend' ? `-${sorter.field}` : sorter.field;
setQueryParams((prev) => ({ setQueryParams((prev) => ({
...prev, ...prev,
+2 -3
View File
@@ -1,7 +1,6 @@
import IconFont from '@/components/icon-font';
import { TABLE_SORT_DIRECTIONS } from '@/config/settings'; import { TABLE_SORT_DIRECTIONS } from '@/config/settings';
import NoResult from '@/pages/_components/no-result';
import PageBox from '@/pages/_components/page-box'; import PageBox from '@/pages/_components/page-box';
import { IconFont, NoResult } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { ConfigProvider, Table } from 'antd'; import { ConfigProvider, Table } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
@@ -35,7 +34,7 @@ const Users: React.FC<{
const pendingPageResetRef = useRef(false); const pendingPageResetRef = useRef(false);
const handleTableChange = (pagination: any, filters: any, sorter: any) => { const handleTableChange = (pagination: any, filters: any, sorter: any) => {
let sort_by = const sort_by =
sorter.order === 'descend' ? `-${sorter.field}` : sorter.field; sorter.order === 'descend' ? `-${sorter.field}` : sorter.field;
setQueryParams((prev) => ({ setQueryParams((prev) => ({
...prev, ...prev,