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,