From a274349ace56dee290d0c71881601a643da86beb Mon Sep 17 00:00:00 2001 From: jialin Date: Thu, 4 Dec 2025 16:37:12 +0800 Subject: [PATCH] chore: upgrade info --- src/app.tsx | 9 +- src/atoms/user.ts | 8 +- src/components/version-info/index.tsx | 38 +-- src/layouts/extraRender.tsx | 4 +- src/layouts/index.tsx | 239 ++----------------- src/pages/login/components/login-form.tsx | 2 +- src/pages/login/components/password-form.tsx | 2 +- 7 files changed, 56 insertions(+), 246 deletions(-) diff --git a/src/app.tsx b/src/app.tsx index 1799316c..c40086d9 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -79,10 +79,15 @@ export async function getInitialState(): Promise<{ const getAppVersionInfo = async () => { try { const data = await queryVersionInfo(); - const isProduction = data.version?.indexOf('0.0.0') === -1; + + const isDev = data.version?.indexOf('0.0.0') > -1; + const isRc = data.version?.indexOf('rc') > -1; + setAtomStorage(GPUStackVersionAtom, { ...data, - isProduction + isProd: !isDev && !isRc, + isDev, + isRc }); } catch (error) { console.error('queryVersionInfo error', error); diff --git a/src/atoms/user.ts b/src/atoms/user.ts index e84ed294..f36ac76f 100644 --- a/src/atoms/user.ts +++ b/src/atoms/user.ts @@ -6,11 +6,15 @@ export const userAtom = atomWithStorage('userInfo', null); export const GPUStackVersionAtom = atom<{ version: string; git_commit: string; - isProduction: boolean; + isProd: boolean; + isDev?: boolean; + isRc?: boolean; }>({ version: '', git_commit: '', - isProduction: false + isProd: false, + isDev: false, + isRc: false }); export const UpdateCheckAtom = atom<{ diff --git a/src/components/version-info/index.tsx b/src/components/version-info/index.tsx index c433901b..f7aa2720 100644 --- a/src/components/version-info/index.tsx +++ b/src/components/version-info/index.tsx @@ -1,18 +1,29 @@ import Logo from '@/assets/images/gpustack-logo.png'; import { GPUStackVersionAtom, UpdateCheckAtom, userAtom } from '@/atoms/user'; -import { getAtomStorage } from '@/atoms/utils'; import externalLinks from '@/constants/external-links'; import { Button } from 'antd'; +import { useAtom } from 'jotai'; import React from 'react'; import './index.less'; const VersionInfo: React.FC<{ intl: any }> = ({ intl }) => { - const latestVersion = getAtomStorage(UpdateCheckAtom).latest_version; - const currentVersion = getAtomStorage(GPUStackVersionAtom)?.version; + const [gpuStackVersionAtom] = useAtom(GPUStackVersionAtom); + const [userDataAtom] = useAtom(userAtom); + const [updateCheck] = useAtom(UpdateCheckAtom); - const isProd = - currentVersion?.indexOf('rc') === -1 && - currentVersion?.indexOf('0.0.0') === -1; + // current version info + const { + version: currentVersion, + git_commit, + isProd, + isDev + } = gpuStackVersionAtom; + + // user info + const { is_admin } = userDataAtom || {}; + + // update check latest version info + const { latest_version: latestVersion } = updateCheck; const uiVersion = document.documentElement.getAttribute('data-version'); @@ -29,10 +40,7 @@ const VersionInfo: React.FC<{ intl: any }> = ({ intl }) => { )} {isProd ? ( - - {getAtomStorage(GPUStackVersionAtom)?.version || - getAtomStorage(GPUStackVersionAtom)?.git_commit} - + {currentVersion || git_commit} ) : ( @@ -40,9 +48,7 @@ const VersionInfo: React.FC<{ intl: any }> = ({ intl }) => { {' '} {intl.formatMessage({ id: 'common.footer.version.server' })} - {currentVersion.indexOf('0.0.0') > -1 - ? getAtomStorage(GPUStackVersionAtom)?.git_commit - : getAtomStorage(GPUStackVersionAtom)?.version} + {isDev ? git_commit : currentVersion} UI @@ -51,12 +57,10 @@ const VersionInfo: React.FC<{ intl: any }> = ({ intl }) => { )} - {getAtomStorage(userAtom)?.is_admin && isProd && ( + {is_admin && isProd && (
- {latestVersion && - latestVersion !== currentVersion && - latestVersion.indexOf('0.0.0') === -1 + {latestVersion && latestVersion !== currentVersion && !isDev ? intl.formatMessage( { id: 'users.version.update' }, { version: latestVersion } diff --git a/src/layouts/extraRender.tsx b/src/layouts/extraRender.tsx index 1f4ea093..6860c38f 100644 --- a/src/layouts/extraRender.tsx +++ b/src/layouts/extraRender.tsx @@ -122,12 +122,12 @@ export const ExtraContent = (props: { isDarkTheme?: boolean }) => { initialState?.currentUser?.is_admin && updateCheck.latest_version && updateCheck.latest_version !== version?.version && - updateCheck.latest_version?.indexOf('0.0.0') === -1 && - updateCheck.latest_version?.indexOf('rc') === -1 + version?.isProd ); }, [ updateCheck.latest_version, version.version, + version.isProd, initialState?.currentUser?.is_admin ]); diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index 40e61288..75b124a9 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -1,16 +1,11 @@ // @ts-nocheck import { routeCacheAtom, setRouteCache } from '@/atoms/route-cache'; -import { GPUStackVersionAtom, UpdateCheckAtom, userAtom } from '@/atoms/user'; +import { userAtom } from '@/atoms/user'; import DarkMask from '@/components/dark-mask'; import IconFont from '@/components/icon-font'; -import ShortCuts, { - modalConfig as ShortCutsConfig -} from '@/components/short-cuts'; -import VersionInfo, { modalConfig } from '@/components/version-info'; import routeCachekey from '@/config/route-cachekey'; import { DEFAULT_ENTER_PAGE } from '@/config/settings'; -import useBodyScroll from '@/hooks/use-body-scroll'; import useOverlayScroller from '@/hooks/use-overlay-scroller'; import useUserSettings from '@/hooks/use-user-settings'; import { logout } from '@/pages/login/apis'; @@ -18,7 +13,6 @@ import { useAccessMarkedRoutes } from '@@/plugin-access'; import { useModel } from '@@/plugin-model'; import { ProLayout } from '@ant-design/pro-components'; import { - Link, Outlet, dropByCacheKey, history, @@ -29,18 +23,17 @@ import { useNavigate, type IRoute } from '@umijs/max'; -import { Button, ConfigProvider, Modal, Tooltip, theme } from 'antd'; +import { Button, ConfigProvider, Modal, theme } from 'antd'; import 'driver.js/dist/driver.css'; import { useAtom } from 'jotai'; import 'overlayscrollbars/overlayscrollbars.css'; -import { useEffect, useMemo, useState } from 'react'; +import { useEffect, useMemo } from 'react'; import { PageContainerInner } from '../pages/_components/page-box'; import Exception from './Exception'; import './Layout.css'; import { LogoIcon, SLogoIcon } from './Logo'; import ErrorBoundary from './error-boundary'; import { ExtraContent } from './extraRender'; -import { getRightRenderContent } from './rightRender'; import { patchRoutes } from './runtime'; import SiderMenu from './sider-menu'; @@ -57,16 +50,11 @@ const NO_CONTAINER_PAGES = [ const loginPath = DEFAULT_ENTER_PAGE.login; -type InitialStateType = { - fetchUserInfo: () => Promise; - currentUser?: Global.UserInfo; -}; - // Filter out the routes that need to be displayed, where filterFn indicates the levels that should not be shown const filterRoutes = ( routes: IRoute[], filterFn: (route: IRoute) => boolean -) => { +): any[] => { if (routes.length === 0) { return []; } @@ -117,21 +105,13 @@ export default (props: any) => { defer: false }); const [modal, contextHolder] = Modal.useModal(); - const { themeData, setTheme, setUserSettings, userSettings, isDarkTheme } = - useUserSettings(); - const { saveScrollHeight, restoreScrollHeight } = useBodyScroll(); - const { initialize: initializeMenu } = useOverlayScroller(); + const { themeData, setUserSettings, userSettings } = useUserSettings(); const [userInfo] = useAtom(userAtom); const [routeCache] = useAtom(routeCacheAtom); - const [version] = useAtom(GPUStackVersionAtom); - const [updateCheck] = useAtom(UpdateCheckAtom); const location = useLocation(); const navigate = useNavigate(); const intl = useIntl(); - const { clientRoutes, pluginManager } = useAppData(); - // const [collapsed, setCollapsed] = useState(userSettings.collapsed || false); - const [collapseValue, setCollapseValue] = useState(false); - const [collapseKeys, setCollapseKeys] = useState>(new Set()); + const { clientRoutes } = useAppData(); const initialInfo = (useModel && useModel('@@initialState')) || { initialState: undefined, @@ -150,23 +130,6 @@ export default (props: any) => { return intl.formatMessage({ id: args.id }); }; - const showVersion = () => { - saveScrollHeight(); - modal.info({ - ...modalConfig, - width: 460, - content: , - onCancel: restoreScrollHeight - }); - }; - - const showShortcuts = () => { - Modal.info({ - ...ShortCutsConfig, - content: - }); - }; - const initRouteCacheValue = (pathname) => { if (routeCache.get(pathname) === undefined && routeCachekey[pathname]) { setRouteCache(pathname, false); @@ -184,22 +147,17 @@ export default (props: any) => { const runtimeConfig = { ...initialInfo, - logout: async (userInfo) => { + logout: async () => { await logout(); navigate(loginPath); }, - showVersion: () => { - return showVersion(); - }, - showShortcuts: () => { - return showShortcuts(); - }, + showVersion: () => {}, + showShortcuts: () => {}, notFound: 404 not found }; const handleToggleCollapse = (e: any) => { e.stopPropagation(); - // setCollapsed(!collapsed); setUserSettings({ ...userSettings, collapsed: !userSettings.collapsed @@ -235,38 +193,6 @@ export default (props: any) => { console.log('matchedRoute=========', matchedRoute, route); - const allRouteKeys = useMemo(() => { - const keys = new Set(); - const childrenRoutes = route?.children || []; - const traverseRoutes = (routes) => { - routes.forEach((r) => { - if (r.path) { - keys.add(r.path); - } - if (r.children) { - traverseRoutes(r.children); - } - }); - }; - traverseRoutes(childrenRoutes); - - return keys; - }, [route?.children]); - - const showUpgrade = useMemo(() => { - return ( - initialState?.currentUser?.is_admin && - updateCheck.latest_version && - updateCheck.latest_version !== version?.version && - updateCheck.latest_version?.indexOf('0.0.0') === -1 && - updateCheck.latest_version?.indexOf('rc') === -1 - ); - }, [ - updateCheck.latest_version, - version.version, - initialState?.currentUser?.is_admin - ]); - useEffect(() => { const body = document.querySelector('body'); if (body) { @@ -306,92 +232,13 @@ export default (props: any) => { ); }; - const handleToggleGroup = (menuItemProps, e) => { - e.stopPropagation(); - - if (collapseKeys.has(menuItemProps.key)) { - collapseKeys.delete(menuItemProps.key); - } else { - collapseKeys.add(menuItemProps.key); - } - setCollapseKeys(new Set(collapseKeys)); - }; - - const menuContentRender = (menuProps, defaultDom) => { + const menuContentRender = (menuProps: any, defaultDom: React.ReactNode) => { return ; }; - const actionRender = (layoutProps) => { - const dom = getRightRenderContent({ - runtimeConfig, - loading, - initialState, - setInitialState, - intl, - isDarkTheme: userSettings.isDarkTheme, - siderWidth: layoutProps?.siderWidth, - collapsed: layoutProps?.collapsed, - showUpgrade - }); - - return dom; - }; - - const menuItemRender = (menuItemProps, defaultDom) => { - if (menuItemProps.isUrl || menuItemProps.children) { - return defaultDom; - } - if (menuItemProps.path && location.pathname !== menuItemProps.path) { - return ( - - - {defaultDom} - - - ); - } - return ( - - {defaultDom} - - ); - }; - - const menuDataRender = (menuData) => { - const currentItem = menuData.find((s) => location.pathname === s.path); - const result = menuData.map((item) => { - const newItem = { ...item }; - - const selected = - location.pathname === newItem.path || - location.pathname.indexOf(newItem.path) > -1; - - if (newItem.icon) { - newItem.icon = selected ? ( - - ) : ( - - ); - } - if (newItem.children) { - newItem.children = menuDataRender(newItem.children); - } - return newItem; - }); - - return result; - }; - - const onPageChange = (route) => { + const onPageChange = (route: any) => { const { location } = history; const { pathname } = location; - console.log('onPageChange', pathname, route); initRouteCacheValue(pathname); dropRouteCache(pathname); @@ -413,7 +260,7 @@ export default (props: any) => { } }; - const onMenuHeaderClick = (e) => { + const onMenuHeaderClick = (e: React.MouseEvent) => { e.stopPropagation(); e.preventDefault(); const pagepath = initialState?.currentUser?.is_admin @@ -423,65 +270,13 @@ export default (props: any) => { navigate(pagepath); }; - const onCollapse = (value) => { + const onCollapse = (value: boolean) => { setUserSettings({ ...userSettings, collapsed: value }); }; - useEffect(() => { - // clear previous marks and measures - performance.clearMarks(); - performance.clearMeasures(); - - // record start time - performance.mark('route-start'); - - requestAnimationFrame(() => { - // record end time - performance.mark('route-end'); - - // make sure `route-start` exists - if (performance.getEntriesByName('route-start').length > 0) { - performance.measure('route-change', 'route-start', 'route-end'); - - const measure = performance.getEntriesByName('route-change')[0]; - console.log( - `[Performance] Route change to ${location.pathname} took ${measure.duration.toFixed(2)}ms` - ); - - // clear marks and measures - performance.clearMarks(); - performance.clearMeasures(); - } else { - console.warn('Missing performance mark: route-start'); - } - }); - }, [location.pathname]); - - const onRenderCallback = (id, phase, actualDuration) => { - console.log( - `[Profiler] Route: ${id} - Phase: ${phase} - Render time: ${actualDuration.toFixed(2)}ms` - ); - }; - - const currentTheme = useMemo(() => { - const data = { - algorithm: userSettings.isDarkTheme - ? theme.darkAlgorithm - : theme.defaultAlgorithm, - ...themeData - }; - return data; - }, [userSettings.isDarkTheme, themeData]); - - const outlet = runtimeConfig.childrenRender ? ( - runtimeConfig.childrenRender(, props) - ) : ( - - ); - return ( { type: 'group' }} splitMenus={true} - logo={collapsed ? SLogoIcon : LogoIcon} + logo={userSettings.collapsed ? : } menuContentRender={menuContentRender} disableContentMargin {...runtimeConfig} @@ -544,9 +339,11 @@ export default (props: any) => { noAccessible={runtimeConfig?.noAccessible} > {isNoContainerPage ? ( - outlet + ) : ( - {outlet} + + + )} diff --git a/src/pages/login/components/login-form.tsx b/src/pages/login/components/login-form.tsx index 50daf8df..51280405 100644 --- a/src/pages/login/components/login-form.tsx +++ b/src/pages/login/components/login-form.tsx @@ -88,7 +88,7 @@ const useStyles = createStyles(({ token, css }) => ({ const LoginForm = () => { const [messageApi, contextHolder] = message.useMessage(); const { styles } = useStyles(); - const [userInfo, setUserInfo] = useAtom(userAtom); + const [, setUserInfo] = useAtom(userAtom); const { initialState, setInitialState } = useModel('@@initialState') || {}; const [authError, setAuthError] = useState(null); const intl = useIntl(); diff --git a/src/pages/login/components/password-form.tsx b/src/pages/login/components/password-form.tsx index 81532dce..1383ea8b 100644 --- a/src/pages/login/components/password-form.tsx +++ b/src/pages/login/components/password-form.tsx @@ -34,7 +34,7 @@ const PasswordForm: React.FC = () => { }); await setUserInfo({ - ...userInfo, + ...(userInfo || {}), require_password_change: false }); setInitialPassword('');