build: sync config
This commit is contained in:
+26
-2
@@ -1,6 +1,9 @@
|
||||
import { GPUStackVersionAtom, UpdateCheckAtom } from '@/atoms/user';
|
||||
import { setAtomStorage } from '@/atoms/utils';
|
||||
import { DEFAULT_ENTER_PAGE, GPUSTACK_API_BASE_URL } from '@/config/settings';
|
||||
import { getGPUStackPlugin } from '@/plugins';
|
||||
import { GPUStackPluginManager } from '@/plugins/manager';
|
||||
import { mergeEnterpriseRoutes } from '@/plugins/route-merger';
|
||||
import { requestConfig } from '@/request-config';
|
||||
import {
|
||||
queryCurrentUserState,
|
||||
@@ -14,6 +17,7 @@ import {
|
||||
readState,
|
||||
writeState
|
||||
} from '@/utils/localstore/index';
|
||||
import '@gpustack/core-ui/style.css';
|
||||
import { RequestConfig, history } from '@umijs/max';
|
||||
import { message } from 'antd';
|
||||
|
||||
@@ -33,8 +37,18 @@ const checkDefaultPage = async (userInfo: any) => {
|
||||
export async function getInitialState(): Promise<{
|
||||
fetchUserInfo: () => Promise<Global.UserInfo>;
|
||||
currentUser?: Global.UserInfo;
|
||||
pluginData?: Record<string, any>;
|
||||
}> {
|
||||
const { location } = history;
|
||||
const enterprisePlugin = getGPUStackPlugin();
|
||||
|
||||
// initialize plugins and merge enterprise locales
|
||||
let pluginData = {};
|
||||
try {
|
||||
pluginData = await GPUStackPluginManager.initialize();
|
||||
} catch (error) {
|
||||
console.error('Failed to initialize plugins:', error);
|
||||
}
|
||||
|
||||
const getUpdateCheck = async () => {
|
||||
try {
|
||||
@@ -103,11 +117,13 @@ export async function getInitialState(): Promise<{
|
||||
checkDefaultPage(userInfo);
|
||||
return {
|
||||
fetchUserInfo,
|
||||
currentUser: userInfo
|
||||
currentUser: userInfo,
|
||||
pluginData
|
||||
};
|
||||
}
|
||||
return {
|
||||
fetchUserInfo
|
||||
fetchUserInfo,
|
||||
pluginData
|
||||
};
|
||||
}
|
||||
|
||||
@@ -115,3 +131,11 @@ export const request: RequestConfig = {
|
||||
baseURL: `/${GPUSTACK_API_BASE_URL}`,
|
||||
...requestConfig
|
||||
};
|
||||
|
||||
/**
|
||||
* 动态修改路由
|
||||
* @param routes 路由配置
|
||||
*/
|
||||
export function patchClientRoutes({ routes }: any) {
|
||||
mergeEnterpriseRoutes(routes);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {
|
||||
InfiniteScroller,
|
||||
ResizeContainer,
|
||||
TemplateCardSkeleton
|
||||
TemplateCardSkeleton,
|
||||
useScrollerContext
|
||||
} from '@gpustack/core-ui';
|
||||
import { useScrollerContext } from '@gpustack/core-ui/lib/components/infinite-scroller/use-scroller-context';
|
||||
import { Spin } from 'antd';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export const COLOR_PRIMARY = '#007BFF';
|
||||
@@ -1,4 +1,4 @@
|
||||
import { COLOR_PRIMARY } from './index';
|
||||
import { COLOR_PRIMARY } from './constants';
|
||||
|
||||
export default {
|
||||
'root-entry-name': 'variable',
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { COLOR_PRIMARY } from './constants';
|
||||
import dark from './dark';
|
||||
import light from './light';
|
||||
|
||||
export const COLOR_PRIMARY = '#007BFF';
|
||||
|
||||
export default {
|
||||
light,
|
||||
dark,
|
||||
colorPrimary: COLOR_PRIMARY
|
||||
};
|
||||
|
||||
export { COLOR_PRIMARY };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { COLOR_PRIMARY } from './index';
|
||||
import { COLOR_PRIMARY } from './constants';
|
||||
|
||||
export default {
|
||||
'root-entry-name': 'variable',
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { userSettingsHelperAtom } from '@/atoms/settings';
|
||||
import { getAtomStorage, setAtomStorage } from '@/atoms/utils';
|
||||
|
||||
export default function useUserSettingsStorage() {
|
||||
const setStorageUserSettings = (value: Record<string, any>) => {
|
||||
setAtomStorage(userSettingsHelperAtom, value || {});
|
||||
};
|
||||
|
||||
const getStorageUserSettings = () => {
|
||||
return getAtomStorage(userSettingsHelperAtom);
|
||||
};
|
||||
|
||||
return {
|
||||
setStorageUserSettings,
|
||||
getStorageUserSettings
|
||||
};
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { userSettingsHelperAtom } from '@/atoms/settings';
|
||||
import themeConfig from '@/config/theme';
|
||||
import { useAtom } from 'jotai';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { userSettingsHelperAtom } from '../atoms/settings';
|
||||
import themeConfig from '../config/theme';
|
||||
|
||||
type Theme = 'light' | 'realDark' | 'auto';
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import VersionInfo, { modalConfig } from '@/components/version-info';
|
||||
import externalLinks from '@/constants/external-links';
|
||||
import useBodyScroll from '@/hooks/use-body-scroll';
|
||||
import { logout } from '@/pages/login/apis';
|
||||
import { getGPUStackPlugin } from '@/plugins';
|
||||
import { useModel } from '@@/plugin-model';
|
||||
import {
|
||||
DiscordOutlined,
|
||||
@@ -105,6 +106,7 @@ const CustomItem = styled.div`
|
||||
|
||||
export const ExtraContent = (props: { isDarkTheme?: boolean }) => {
|
||||
const { isDarkTheme } = props;
|
||||
const pluginManager = getGPUStackPlugin();
|
||||
const { saveScrollHeight, restoreScrollHeight } = useBodyScroll();
|
||||
const [modal, contextHolder] = Modal.useModal();
|
||||
const [version] = useAtom(GPUStackVersionAtom);
|
||||
@@ -117,6 +119,7 @@ export const ExtraContent = (props: { isDarkTheme?: boolean }) => {
|
||||
};
|
||||
|
||||
const { initialState } = initialInfo;
|
||||
console.log('plugin+++++++++', pluginManager);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -291,6 +294,18 @@ export const ExtraContent = (props: { isDarkTheme?: boolean }) => {
|
||||
</NewLabel>
|
||||
)}
|
||||
</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}>
|
||||
<IconWrapper>
|
||||
<IconFont
|
||||
|
||||
+17
-3
@@ -3,8 +3,10 @@ import { userAtom } from '@/atoms/user';
|
||||
import DarkMask from '@/components/dark-mask';
|
||||
import routeCachekey from '@/config/route-cachekey';
|
||||
import { DEFAULT_ENTER_PAGE, GPUSTACK_API_BASE_URL } from '@/config/settings';
|
||||
import { COLOR_PRIMARY } from '@/config/theme';
|
||||
import useOverlayScroller from '@/hooks/use-overlay-scroller';
|
||||
import useUserSettings from '@/hooks/use-user-settings';
|
||||
import useUserSettingsStorage from '@/hooks/use-user-settings-storage';
|
||||
import useAddResource from '@/pages/dashboard/hooks/use-add-resource';
|
||||
import { logout } from '@/pages/login/apis';
|
||||
import {
|
||||
@@ -128,6 +130,7 @@ export default (props: any) => {
|
||||
});
|
||||
const [, contextHolder] = Modal.useModal();
|
||||
const { themeData, setUserSettings, userSettings } = useUserSettings();
|
||||
const userSettingsStorage = useUserSettingsStorage();
|
||||
const [userInfo] = useAtom(userAtom);
|
||||
const [routeCache] = useAtom(routeCacheAtom);
|
||||
const location = useLocation();
|
||||
@@ -205,7 +208,7 @@ export default (props: any) => {
|
||||
|
||||
const role = initialState?.currentUser?.is_admin ? 'admin' : 'user';
|
||||
const [route] = useAccessMarkedRoutes(mapRoutes(newRoutes, role));
|
||||
|
||||
console.log('route++++++++', route, clientRoutes);
|
||||
patchRoutes({
|
||||
routes: route.children,
|
||||
initialState: initialInfo.initialState
|
||||
@@ -363,7 +366,13 @@ export default (props: any) => {
|
||||
apiBaseUrl: GPUSTACK_API_BASE_URL,
|
||||
theme: userSettings.theme,
|
||||
iconUrl: '//at.alicdn.com/t/c/font_4613488_8fi68fmt1th.js',
|
||||
isDarkTheme: userSettings.isDarkTheme
|
||||
isDarkTheme: userSettings.isDarkTheme,
|
||||
defaultColorPrimary: COLOR_PRIMARY
|
||||
}}
|
||||
hooks={{
|
||||
useUserSettings: useUserSettings,
|
||||
useUserSettingsStorage: () => userSettingsStorage,
|
||||
useIntl: useIntl
|
||||
}}
|
||||
i18n={intl}
|
||||
locale={{
|
||||
@@ -371,7 +380,12 @@ export default (props: any) => {
|
||||
setLocale: setLocale
|
||||
}}
|
||||
services={{
|
||||
request: request
|
||||
request: request,
|
||||
router: {
|
||||
push: (path: string) => navigate(path),
|
||||
replace: (path: string) => navigate(path, { replace: true }),
|
||||
goBack: () => navigate(-1)
|
||||
}
|
||||
}}
|
||||
localStore={{
|
||||
readColumnSettings,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// columns.ts
|
||||
import { tableSorter } from '@/config/settings';
|
||||
import { AutoTooltip, DropdownButtons } from '@gpustack/core-ui';
|
||||
import icons from '@gpustack/core-ui/lib/components/icon-font/icons';
|
||||
import { AutoTooltip, DropdownButtons, icons } from '@gpustack/core-ui';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Tag } from 'antd';
|
||||
import { ColumnsType } from 'antd/lib/table';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {
|
||||
InfiniteScroller,
|
||||
ResizeContainer,
|
||||
TemplateCardSkeleton
|
||||
TemplateCardSkeleton,
|
||||
useScrollerContext
|
||||
} from '@gpustack/core-ui';
|
||||
import { useScrollerContext } from '@gpustack/core-ui/lib/components/infinite-scroller/use-scroller-context';
|
||||
import { Spin } from 'antd';
|
||||
import React from 'react';
|
||||
import backendListCss from '../styles/backend-list.less';
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
GPUDriverMap,
|
||||
ManufacturerMap
|
||||
} from '@/pages/resources/config/gpu-driver';
|
||||
import icons from '@gpustack/core-ui/lib/components/icon-font/icons';
|
||||
import { icons } from '@gpustack/core-ui';
|
||||
import jsYaml from 'js-yaml';
|
||||
import { trim } from 'lodash';
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { DownloadOutlined } from '@ant-design/icons';
|
||||
import { DropdownButtons, IconFont, useDownloadLogs } from '@gpustack/core-ui';
|
||||
import icons from '@gpustack/core-ui/lib/components/icon-font/icons';
|
||||
import {
|
||||
DropdownButtons,
|
||||
IconFont,
|
||||
icons,
|
||||
useDownloadLogs
|
||||
} from '@gpustack/core-ui';
|
||||
import { BENCHMARKS_API } from '../apis';
|
||||
import { BenchmarkStatusValueMap } from '../config';
|
||||
import { BenchmarkListItem as ListItem } from '../config/types';
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import { PageAction } from '@/config';
|
||||
import { PageActionType } from '@/config/types';
|
||||
import { CollapsePanel, IconFont, ScrollSpyTabs } from '@gpustack/core-ui';
|
||||
import { useWrapperContext } from '@gpustack/core-ui/lib/components/column-wrapper/use-wrapper-context';
|
||||
import {
|
||||
CollapsePanel,
|
||||
IconFont,
|
||||
ScrollSpyTabs,
|
||||
useWrapperContext
|
||||
} from '@gpustack/core-ui';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Form } from 'antd';
|
||||
import {
|
||||
|
||||
@@ -10,9 +10,9 @@ import {
|
||||
FilterBar,
|
||||
IconFont,
|
||||
Table as SealTable,
|
||||
TableOrder,
|
||||
TableProvider
|
||||
} from '@gpustack/core-ui';
|
||||
import { TableOrder } from '@gpustack/core-ui/lib/components/table/types';
|
||||
import { useIntl, useNavigate } from '@umijs/max';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { message } from 'antd';
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { DropdownActions } from '@gpustack/core-ui';
|
||||
import ListMap from '@gpustack/core-ui/lib/components/dynamic-form/components/list-map';
|
||||
import { FieldSchema } from '@gpustack/core-ui/lib/components/dynamic-form/config/types';
|
||||
import { DropdownActions, type FieldSchema, ListMap } from '@gpustack/core-ui';
|
||||
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
|
||||
@@ -14,9 +14,9 @@ import {
|
||||
IconFont,
|
||||
LabelSelector,
|
||||
Select as SealSelect,
|
||||
useAppUtils
|
||||
useAppUtils,
|
||||
type CollapseContainerProps
|
||||
} from '@gpustack/core-ui';
|
||||
import { type CollapseContainerProps } from '@gpustack/core-ui/lib/components/collapse-container';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { Button, Form } from 'antd';
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import ListMap from '@gpustack/core-ui/lib/components/dynamic-form/components/list-map';
|
||||
import { statusType } from '@gpustack/core-ui/lib/components/dynamic-form/config/types';
|
||||
import useValidateFields from '@gpustack/core-ui/lib/components/dynamic-form/hooks/use-validate-fields';
|
||||
import { ListMap, type statusType, useValidateFields } from '@gpustack/core-ui';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Form } from 'antd';
|
||||
import React, { forwardRef, useState } from 'react';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FieldSchema } from '@gpustack/core-ui/lib/components/dynamic-form/config/types';
|
||||
import { type FieldSchema } from '@gpustack/core-ui';
|
||||
|
||||
export const fields = {
|
||||
volumes: {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { StatusMaps } from '@/config';
|
||||
import { GPUSTACK_API_BASE_URL } from '@/config/settings';
|
||||
import { StatusType } from '@/config/types';
|
||||
import { GPUsConfigs } from '@/pages/resources/config/gpu-driver';
|
||||
import icons from '@gpustack/core-ui/lib/components/icon-font/icons';
|
||||
import { icons } from '@gpustack/core-ui';
|
||||
|
||||
export const ClusterStatusValueMap = {
|
||||
Provisioning: 'provisioning',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import icons from '@gpustack/core-ui/lib/components/icon-font/icons';
|
||||
import { icons } from '@gpustack/core-ui';
|
||||
import React from 'react';
|
||||
import { ProviderValueMap } from '.';
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@ import {
|
||||
AutoTooltip,
|
||||
DropdownButtons,
|
||||
GrafanaIcon,
|
||||
StatusTag
|
||||
StatusTag,
|
||||
icons,
|
||||
type TableColumnProps as SealColumnProps
|
||||
} from '@gpustack/core-ui';
|
||||
import icons from '@gpustack/core-ui/lib/components/icon-font/icons';
|
||||
import { ColumnProps as SealColumnProps } from '@gpustack/core-ui/lib/components/table/types';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Tooltip } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { DeleteOutlined, EditOutlined } from '@ant-design/icons';
|
||||
import { AutoTooltip, DropdownButtons } from '@gpustack/core-ui';
|
||||
import { ColumnProps } from '@gpustack/core-ui/lib/components/table/types';
|
||||
import {
|
||||
AutoTooltip,
|
||||
DropdownButtons,
|
||||
type TableColumnProps
|
||||
} from '@gpustack/core-ui';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import dayjs from 'dayjs';
|
||||
import _ from 'lodash';
|
||||
@@ -27,7 +30,7 @@ const actionItems = [
|
||||
const usePoolsColumns = (
|
||||
handleSelect: (val: string, record: ListItem) => void,
|
||||
sortOrder?: string[]
|
||||
): ColumnProps[] => {
|
||||
): TableColumnProps[] => {
|
||||
const intl = useIntl();
|
||||
|
||||
return useMemo(() => {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {
|
||||
InfiniteScroller,
|
||||
ResizeContainer,
|
||||
TemplateCardSkeleton
|
||||
TemplateCardSkeleton,
|
||||
useScrollerContext
|
||||
} from '@gpustack/core-ui';
|
||||
import { useScrollerContext } from '@gpustack/core-ui/lib/components/infinite-scroller/use-scroller-context';
|
||||
import { Spin } from 'antd';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
@@ -2,10 +2,10 @@ import { useBenchmarkTargetInstance } from '@/pages/llmodels/hooks/use-run-bench
|
||||
import { DeleteOutlined, DownloadOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
DropdownButtons,
|
||||
type HandlerOptions,
|
||||
IconFont,
|
||||
useDownloadStream
|
||||
} from '@gpustack/core-ui';
|
||||
import { HandlerOptions } from '@gpustack/core-ui/lib/hooks/use-chunk-fetch';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Progress, notification } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ListItem as WorkerListItem } from '@/pages/resources/config/types';
|
||||
import { SimpleTable, StatusTag } from '@gpustack/core-ui';
|
||||
import { type ColumnProps } from '@gpustack/core-ui/lib/components/simple-table';
|
||||
import { SimpleTable, StatusTag, type ColumnProps } from '@gpustack/core-ui';
|
||||
import { Progress, Tooltip } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import { InstanceStatusMap, status } from '../../config';
|
||||
|
||||
@@ -18,9 +18,9 @@ import {
|
||||
DropdownActions,
|
||||
DropdownButtons,
|
||||
PageTools,
|
||||
Table as SealTable
|
||||
Table as SealTable,
|
||||
TableOrder
|
||||
} from '@gpustack/core-ui';
|
||||
import { TableOrder } from '@gpustack/core-ui/lib/components/table/types';
|
||||
import { useIntl, useNavigate, useSearchParams } from '@umijs/max';
|
||||
import { useMemoizedFn, useToggle } from 'ahooks';
|
||||
import { Button, Space, message } from 'antd';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import HotKeys from '@/config/hotkeys';
|
||||
import icons from '@gpustack/core-ui/lib/components/icon-font/icons';
|
||||
import { icons } from '@gpustack/core-ui';
|
||||
import React from 'react';
|
||||
import { modelCategoriesMap, modelSourceMap } from './index';
|
||||
|
||||
|
||||
@@ -3,8 +3,7 @@ import useSetChunkRequest from '@/hooks/use-chunk-request';
|
||||
import { usePaginationStatus } from '@/hooks/use-pagination-status';
|
||||
import { useTableMultiSort } from '@/hooks/use-table-sort';
|
||||
import useUpdateChunkedList from '@/hooks/use-update-chunk-list';
|
||||
import { TableProvider } from '@gpustack/core-ui';
|
||||
import { TableOrder } from '@gpustack/core-ui/lib/components/table/types';
|
||||
import { TableOrder, TableProvider } from '@gpustack/core-ui';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import _ from 'lodash';
|
||||
import qs from 'query-string';
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import { PageAction } from '@/config';
|
||||
import { PageActionType } from '@/config/types';
|
||||
import { CollapsePanel, IconFont, ScrollSpyTabs } from '@gpustack/core-ui';
|
||||
import { useWrapperContext } from '@gpustack/core-ui/lib/components/column-wrapper/use-wrapper-context';
|
||||
import {
|
||||
CollapsePanel,
|
||||
IconFont,
|
||||
ScrollSpyTabs,
|
||||
useWrapperContext
|
||||
} from '@gpustack/core-ui';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Form } from 'antd';
|
||||
import _ from 'lodash';
|
||||
|
||||
@@ -3,9 +3,13 @@ import { systemConfigAtom } from '@/atoms/system';
|
||||
import { OPENAI_COMPATIBLE, tableSorter } from '@/config/settings';
|
||||
import { TargetStatusValueMap } from '@/pages/model-routes/config';
|
||||
import { QuestionCircleOutlined } from '@ant-design/icons';
|
||||
import { AutoTooltip, DropdownButtons, GrafanaIcon } from '@gpustack/core-ui';
|
||||
import icons from '@gpustack/core-ui/lib/components/icon-font/icons';
|
||||
import { ColumnProps } from '@gpustack/core-ui/lib/components/table/types';
|
||||
import {
|
||||
AutoTooltip,
|
||||
DropdownButtons,
|
||||
GrafanaIcon,
|
||||
icons,
|
||||
type TableColumnProps
|
||||
} from '@gpustack/core-ui';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { Tooltip } from 'antd';
|
||||
@@ -98,7 +102,7 @@ const useModelsColumns = ({
|
||||
clusterList,
|
||||
sortOrder,
|
||||
targetList
|
||||
}: ModelsColumnsHookProps & { targetList: any[] }): ColumnProps[] => {
|
||||
}: ModelsColumnsHookProps & { targetList: any[] }): TableColumnProps[] => {
|
||||
const intl = useIntl();
|
||||
const systemConfig = useAtomValue(systemConfigAtom);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import useBodyScroll from '@/hooks/use-body-scroll';
|
||||
import { PageSize } from '@gpustack/core-ui/lib/components/logs-viewer/config';
|
||||
import { PageSize } from '@gpustack/core-ui';
|
||||
import { useState } from 'react';
|
||||
import { MODEL_INSTANCE_API } from '../apis';
|
||||
import { InstanceRealtimeLogStatus } from '../config';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { StatusMaps } from '@/config';
|
||||
import { StatusType } from '@/config/types';
|
||||
import icons from '@gpustack/core-ui/lib/components/icon-font/icons';
|
||||
import { icons } from '@gpustack/core-ui';
|
||||
import { ProviderEnum } from './providers';
|
||||
export { maasProviderLabelMap, maasProviderOptions } from './providers';
|
||||
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import { PageAction } from '@/config';
|
||||
import { PageActionType } from '@/config/types';
|
||||
import { json2Yaml, yaml2Json } from '@/pages/backends/config';
|
||||
import { CollapsePanel, IconFont, ScrollSpyTabs } from '@gpustack/core-ui';
|
||||
import { useWrapperContext } from '@gpustack/core-ui/lib/components/column-wrapper/use-wrapper-context';
|
||||
import useFinishFailed from '@gpustack/core-ui/lib/components/scroll-spy-tabs/use-finish-failed';
|
||||
import useScrollActiveChange from '@gpustack/core-ui/lib/components/scroll-spy-tabs/use-scroll-active-change';
|
||||
import {
|
||||
CollapsePanel,
|
||||
IconFont,
|
||||
ScrollSpyTabs,
|
||||
useFinishFailed,
|
||||
useScrollActiveChange,
|
||||
useWrapperContext
|
||||
} from '@gpustack/core-ui';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Form } from 'antd';
|
||||
import _ from 'lodash';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { StatusMaps } from '@/config';
|
||||
import { StatusType } from '@/config/types';
|
||||
import icons from '@gpustack/core-ui/lib/components/icon-font/icons';
|
||||
import { icons } from '@gpustack/core-ui';
|
||||
|
||||
export const TargetStatusValueMap: Record<string, string> = {
|
||||
Active: 'active',
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import { PageAction } from '@/config';
|
||||
import { PageActionType } from '@/config/types';
|
||||
import { modelCategoriesMap } from '@/pages/llmodels/config';
|
||||
import { CollapsePanel, IconFont, ScrollSpyTabs } from '@gpustack/core-ui';
|
||||
import { useWrapperContext } from '@gpustack/core-ui/lib/components/column-wrapper/use-wrapper-context';
|
||||
import useFinishFailed from '@gpustack/core-ui/lib/components/scroll-spy-tabs/use-finish-failed';
|
||||
import useScrollActiveChange from '@gpustack/core-ui/lib/components/scroll-spy-tabs/use-scroll-active-change';
|
||||
import {
|
||||
CollapsePanel,
|
||||
IconFont,
|
||||
ScrollSpyTabs,
|
||||
useFinishFailed,
|
||||
useScrollActiveChange,
|
||||
useWrapperContext
|
||||
} from '@gpustack/core-ui';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Form } from 'antd';
|
||||
import _ from 'lodash';
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
// columns.ts
|
||||
import { tableSorter } from '@/config/settings';
|
||||
import ModelTag from '@/pages/_components/model-tag';
|
||||
import { AutoTooltip, DropdownButtons } from '@gpustack/core-ui';
|
||||
import { type ColumnProps } from '@gpustack/core-ui/lib/components/table/types';
|
||||
import {
|
||||
AutoTooltip,
|
||||
DropdownButtons,
|
||||
type TableColumnProps
|
||||
} from '@gpustack/core-ui';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import dayjs from 'dayjs';
|
||||
import { useMemo } from 'react';
|
||||
@@ -11,7 +14,7 @@ import { RouteItem } from '../config/types';
|
||||
const useAccessColumns = (
|
||||
handleSelect: (val: string, record: RouteItem) => void,
|
||||
onCellClick?: (record: RouteItem, dataIndex: string) => void
|
||||
): ColumnProps[] => {
|
||||
): TableColumnProps[] => {
|
||||
const intl = useIntl();
|
||||
|
||||
const filterActions = (record: RouteItem) => {
|
||||
|
||||
@@ -11,9 +11,9 @@ import {
|
||||
FilterBar,
|
||||
IconFont,
|
||||
Table as SealTable,
|
||||
TableOrder,
|
||||
TableProvider
|
||||
} from '@gpustack/core-ui';
|
||||
import { TableOrder } from '@gpustack/core-ui/lib/components/table/types';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { message } from 'antd';
|
||||
|
||||
@@ -6,9 +6,9 @@ import {
|
||||
AlertInfo,
|
||||
ImageEditor as CanvasImageEditor,
|
||||
IconFont,
|
||||
processImage,
|
||||
SingleImage
|
||||
} from '@gpustack/core-ui';
|
||||
import { processImage } from '@gpustack/core-ui/lib/components/image-editor/extract-image-colors';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Divider } from 'antd';
|
||||
import _ from 'lodash';
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { getGPUStackPlugin } from '@/plugins';
|
||||
import { Result } from 'antd';
|
||||
import React from 'react';
|
||||
|
||||
const SettingsPage: React.FC = () => {
|
||||
const enterprisePlugin = getGPUStackPlugin();
|
||||
const BrandingUI = enterprisePlugin?.components?.BrandingUI;
|
||||
|
||||
if (!BrandingUI) {
|
||||
return (
|
||||
<Result
|
||||
status="404"
|
||||
title="404"
|
||||
subTitle="Enterprise settings page is unavailable."
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return <BrandingUI />;
|
||||
};
|
||||
|
||||
export default SettingsPage;
|
||||
@@ -1,7 +1,11 @@
|
||||
// columns.ts
|
||||
import { tableSorter } from '@/config/settings';
|
||||
import { AutoTooltip, DropdownButtons, IconFont } from '@gpustack/core-ui';
|
||||
import icons from '@gpustack/core-ui/lib/components/icon-font/icons';
|
||||
import {
|
||||
AutoTooltip,
|
||||
DropdownButtons,
|
||||
IconFont,
|
||||
icons
|
||||
} from '@gpustack/core-ui';
|
||||
import { useIntl, useModel } from '@umijs/max';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { Tag } from 'antd';
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { GPUStackPluginManager } from './manager';
|
||||
import { AppPlugin } from './types';
|
||||
|
||||
/**
|
||||
* Hook to access the enterprise plugin instance
|
||||
*/
|
||||
export const getGPUStackPlugin = (): AppPlugin | undefined => {
|
||||
return GPUStackPluginManager.get('enterprise');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to access a plugin by its name
|
||||
*/
|
||||
export const getPlugin = (name: string): AppPlugin | undefined => {
|
||||
return GPUStackPluginManager.get(name);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to check if a plugin is registered
|
||||
*/
|
||||
export const hasPlugin = (name: string): boolean => {
|
||||
return GPUStackPluginManager.has(name);
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
import { addLocale } from '@umijs/max';
|
||||
|
||||
const mergedLocales = new Set<string>();
|
||||
|
||||
/**
|
||||
* Merge enterprise plugin locales into the main application
|
||||
*/
|
||||
export function mergeEnterpriseLocales(locales: Record<string, any> = {}) {
|
||||
if (!locales) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Merging enterprise plugin locales:', Object.keys(locales));
|
||||
|
||||
// Iterate over all locale configurations of the enterprise plugin
|
||||
Object.entries(locales).forEach(([locale, messages]) => {
|
||||
try {
|
||||
if (mergedLocales.has(locale)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Merge the enterprise locale into the main application
|
||||
addLocale(locale, messages, {
|
||||
momentLocale: '',
|
||||
// @ts-ignore
|
||||
antd: locale
|
||||
});
|
||||
mergedLocales.add(locale);
|
||||
console.log(`✓ Merged enterprise locale: ${locale}`);
|
||||
} catch (error) {
|
||||
console.error(`Failed to merge enterprise locale ${locale}:`, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import { AppPlugin, IPluginManager } from './types';
|
||||
|
||||
class PluginManager implements IPluginManager {
|
||||
private plugins = new Map<string, AppPlugin>();
|
||||
private initialized = false;
|
||||
|
||||
/**
|
||||
* register a plugin
|
||||
*/
|
||||
register(name: string, plugin: AppPlugin) {
|
||||
if (this.plugins.has(name)) {
|
||||
console.warn(`Plugin "${name}" is already registered. Overwriting...`);
|
||||
}
|
||||
this.plugins.set(name, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a plugin
|
||||
*/
|
||||
get(name: string): AppPlugin | undefined {
|
||||
return this.plugins.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a plugin exists
|
||||
*/
|
||||
has(name: string): boolean {
|
||||
return this.plugins.has(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* get all plugins
|
||||
*/
|
||||
getAll(): Map<string, AppPlugin> {
|
||||
return this.plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize all plugins
|
||||
*/
|
||||
async initialize(): Promise<Record<string, any>> {
|
||||
if (this.initialized) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const initData: Record<string, any> = {};
|
||||
|
||||
for (const [name, plugin] of this.plugins.entries()) {
|
||||
if (plugin.onAppInit) {
|
||||
try {
|
||||
const data = await plugin.onAppInit();
|
||||
if (data) {
|
||||
initData[name] = data;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Failed to initialize plugin "${name}":`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.initialized = true;
|
||||
return initData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知所有插件应用已就绪
|
||||
*/
|
||||
async notifyReady(): Promise<void> {
|
||||
for (const [name, plugin] of this.plugins.entries()) {
|
||||
if (plugin.onAppReady) {
|
||||
try {
|
||||
await plugin.onAppReady();
|
||||
} catch (error) {
|
||||
console.error(`Plugin "${name}" onAppReady failed:`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const GPUStackPluginManager = new PluginManager();
|
||||
@@ -0,0 +1,2 @@
|
||||
// If the enterprise plugin is not installed, imports will be redirected to this empty module to prevent errors.
|
||||
export default undefined;
|
||||
@@ -0,0 +1,57 @@
|
||||
import { getGPUStackPlugin } from '@/plugins';
|
||||
import type { RouteConfig } from '@/plugins/types';
|
||||
|
||||
type ClientRoute = RouteConfig & {
|
||||
id?: string;
|
||||
children?: ClientRoute[];
|
||||
routes?: ClientRoute[];
|
||||
};
|
||||
|
||||
function getLayoutChildren(routes: ClientRoute[]): ClientRoute[] | null {
|
||||
const rootRoute = routes.find((route) => route.path === '/');
|
||||
if (!rootRoute) return null;
|
||||
|
||||
const rootChildren = rootRoute.routes || rootRoute.children;
|
||||
if (!Array.isArray(rootChildren)) return null;
|
||||
|
||||
const globalLayout = rootChildren.find((route) =>
|
||||
route.id?.includes('global-layout')
|
||||
);
|
||||
if (!globalLayout) return null;
|
||||
|
||||
const layoutChildren = globalLayout.children || globalLayout.routes;
|
||||
return Array.isArray(layoutChildren) ? layoutChildren : null;
|
||||
}
|
||||
|
||||
function mergeRoute(targetRoutes: ClientRoute[], pluginRoute: ClientRoute) {
|
||||
const existsIndex = targetRoutes.findIndex(
|
||||
(route) =>
|
||||
(pluginRoute.path && route.path === pluginRoute.path) ||
|
||||
(pluginRoute.key && route.key === pluginRoute.key)
|
||||
);
|
||||
|
||||
if (existsIndex === -1) {
|
||||
targetRoutes.push(pluginRoute);
|
||||
return;
|
||||
}
|
||||
|
||||
const currentRoute = targetRoutes[existsIndex];
|
||||
targetRoutes[existsIndex] = {
|
||||
...currentRoute,
|
||||
...pluginRoute,
|
||||
routes: pluginRoute.routes || currentRoute.routes,
|
||||
children: pluginRoute.children || currentRoute.children
|
||||
};
|
||||
}
|
||||
|
||||
export function mergeEnterpriseRoutes(routes: ClientRoute[]) {
|
||||
const enterprisePlugin = getGPUStackPlugin();
|
||||
if (!enterprisePlugin?.routes?.length) return;
|
||||
|
||||
const layoutChildren = getLayoutChildren(routes);
|
||||
if (!layoutChildren) return;
|
||||
|
||||
enterprisePlugin.routes.forEach((route) =>
|
||||
mergeRoute(layoutChildren, route as ClientRoute)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
import { ComponentType } from 'react';
|
||||
|
||||
/**
|
||||
* routes
|
||||
*/
|
||||
export interface RouteConfig {
|
||||
path: string;
|
||||
component?: ComponentType;
|
||||
routes?: RouteConfig[];
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* login module configuration
|
||||
*/
|
||||
export interface LoginPlugin {
|
||||
shouldUseCustomLogin?: () => boolean;
|
||||
CustomLoginComponent?: ComponentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* branding module configuration
|
||||
*/
|
||||
export interface BrandingPlugin {
|
||||
ConfigPage?: ComponentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* localization configuration
|
||||
*/
|
||||
export interface LocalesConfig {
|
||||
[locale: string]: Record<string, any>;
|
||||
}
|
||||
|
||||
/**
|
||||
* application plugin interface
|
||||
*/
|
||||
export interface AppPlugin {
|
||||
/**
|
||||
* application initialization hook
|
||||
* called when the application starts, can return initialization data
|
||||
*/
|
||||
onAppInit?: () => Promise<Record<string, any>> | Record<string, any>;
|
||||
|
||||
/**
|
||||
* application ready hook
|
||||
* called when the application is fully loaded
|
||||
*/
|
||||
onAppReady?: () => void | Promise<void>;
|
||||
|
||||
/**
|
||||
* login module
|
||||
*/
|
||||
login?: LoginPlugin;
|
||||
|
||||
/**
|
||||
* branding module
|
||||
*/
|
||||
branding?: BrandingPlugin;
|
||||
|
||||
/**
|
||||
* localization configuration
|
||||
*/
|
||||
locales?: LocalesConfig;
|
||||
|
||||
/**
|
||||
* routes extension
|
||||
*/
|
||||
routes?: RouteConfig[];
|
||||
|
||||
/**
|
||||
* components extension
|
||||
*/
|
||||
components?: Record<string, ComponentType>;
|
||||
|
||||
/**
|
||||
* Hooks extension
|
||||
*/
|
||||
hooks?: Record<string, (...args: unknown[]) => unknown>;
|
||||
|
||||
/**
|
||||
* other custom fields for future extensions
|
||||
*/
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* plugin manager interface
|
||||
*/
|
||||
export interface IPluginManager {
|
||||
register(name: string, plugin: AppPlugin): void;
|
||||
get(name: string): AppPlugin | undefined;
|
||||
has(name: string): boolean;
|
||||
getAll(): Map<string, AppPlugin>;
|
||||
}
|
||||
Reference in New Issue
Block a user