This is an automated email from the ASF dual-hosted git repository.

lizhimins pushed a commit to branch rocketmq-studio
in repository https://gitbox.apache.org/repos/asf/rocketmq-dashboard.git


The following commit(s) were added to refs/heads/rocketmq-studio by this push:
     new 86f12eb3 chore(web): stabilize development and test runtime (#972)
86f12eb3 is described below

commit 86f12eb390fb0928670299ea8a753782c59761fb
Author: aias00 <[email protected]>
AuthorDate: Wed Aug 5 02:38:05 2026 -0700

    chore(web): stabilize development and test runtime (#972)
---
 web/src/{main.tsx => StudioApp.tsx}                | 23 +++-------
 web/src/layouts/MainLayout.test.tsx                | 21 ++++-----
 web/src/layouts/MainLayout.tsx                     |  2 +-
 web/src/main.tsx                                   | 53 ++--------------------
 web/src/theme/ThemeContext.tsx                     | 47 +------------------
 .../theme/{ThemeContext.tsx => ThemeProvider.tsx}  | 19 +-------
 web/src/theme/__tests__/ThemeContext.test.tsx      |  3 +-
 web/src/theme/useTheme.ts                          | 21 +++++++++
 web/vite.config.ts                                 |  3 --
 9 files changed, 48 insertions(+), 144 deletions(-)

diff --git a/web/src/main.tsx b/web/src/StudioApp.tsx
similarity index 82%
copy from web/src/main.tsx
copy to web/src/StudioApp.tsx
index d9575877..930bfef4 100644
--- a/web/src/main.tsx
+++ b/web/src/StudioApp.tsx
@@ -15,18 +15,15 @@
  * limitations under the License.
  */
 
-import React from 'react';
-import ReactDOM from 'react-dom/client';
-import { BrowserRouter } from 'react-router-dom';
 import { App as AntdApp, ConfigProvider, theme } from 'antd';
-import zhCN from 'antd/locale/zh_CN';
 import enUS from 'antd/locale/en_US';
-import { LangProvider, useLang } from './i18n/LangContext';
-import { ThemeProvider, useTheme } from './theme/ThemeContext';
+import zhCN from 'antd/locale/zh_CN';
+import { BrowserRouter } from 'react-router-dom';
 import App from './App';
-import './index.css';
+import { useLang } from './i18n/LangContext';
+import { useTheme } from './theme/useTheme';
 
-const ThemedApp = () => {
+const StudioApp = () => {
   const { lang } = useLang();
   const { darkMode } = useTheme();
 
@@ -67,12 +64,4 @@ const ThemedApp = () => {
   );
 };
 
-ReactDOM.createRoot(document.getElementById('root')!).render(
-  <React.StrictMode>
-    <LangProvider>
-      <ThemeProvider>
-        <ThemedApp />
-      </ThemeProvider>
-    </LangProvider>
-  </React.StrictMode>,
-);
+export default StudioApp;
diff --git a/web/src/layouts/MainLayout.test.tsx 
b/web/src/layouts/MainLayout.test.tsx
index c0b1bba9..6e2dcc59 100644
--- a/web/src/layouts/MainLayout.test.tsx
+++ b/web/src/layouts/MainLayout.test.tsx
@@ -21,7 +21,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
 import { logout } from '../api/auth';
 import { LangProvider } from '../i18n/LangContext';
 import useAuthStore from '../stores/authStore';
-import { ThemeProvider } from '../theme/ThemeContext';
+import { ThemeProvider } from '../theme/ThemeProvider';
 import MainLayout from './MainLayout';
 
 vi.mock('../api/auth', () => ({ logout: vi.fn() }));
@@ -46,16 +46,15 @@ vi.mock('antd', async () => {
         'div',
         null,
         children,
-        menu.items
-          .map((item) =>
-            item.key
-              ? React.createElement(
-                  'button',
-                  { key: item.key, onClick: () => menu.onClick({ key: 
item.key! }) },
-                  item.label,
-                )
-              : null,
-          ),
+        menu.items.map((item) =>
+          item.key
+            ? React.createElement(
+                'button',
+                { key: item.key, onClick: () => menu.onClick({ key: item.key! 
}) },
+                item.label,
+              )
+            : null,
+        ),
       ),
     Empty: () => null,
     Input: () => null,
diff --git a/web/src/layouts/MainLayout.tsx b/web/src/layouts/MainLayout.tsx
index 8803cf1e..ed09c449 100644
--- a/web/src/layouts/MainLayout.tsx
+++ b/web/src/layouts/MainLayout.tsx
@@ -41,7 +41,7 @@ import {
   Warning,
 } from '@phosphor-icons/react';
 import { useLang } from '../i18n/LangContext';
-import { useTheme } from '../theme/ThemeContext';
+import { useTheme } from '../theme/useTheme';
 import { logout as requestLogout } from '../api/auth';
 import useAuthStore from '../stores/authStore';
 import {
diff --git a/web/src/main.tsx b/web/src/main.tsx
index d9575877..fb15bf92 100644
--- a/web/src/main.tsx
+++ b/web/src/main.tsx
@@ -17,61 +17,16 @@
 
 import React from 'react';
 import ReactDOM from 'react-dom/client';
-import { BrowserRouter } from 'react-router-dom';
-import { App as AntdApp, ConfigProvider, theme } from 'antd';
-import zhCN from 'antd/locale/zh_CN';
-import enUS from 'antd/locale/en_US';
-import { LangProvider, useLang } from './i18n/LangContext';
-import { ThemeProvider, useTheme } from './theme/ThemeContext';
-import App from './App';
+import { LangProvider } from './i18n/LangContext';
+import { ThemeProvider } from './theme/ThemeProvider';
+import StudioApp from './StudioApp';
 import './index.css';
 
-const ThemedApp = () => {
-  const { lang } = useLang();
-  const { darkMode } = useTheme();
-
-  return (
-    <ConfigProvider
-      locale={lang === 'zh' ? zhCN : enUS}
-      theme={{
-        algorithm: darkMode ? theme.darkAlgorithm : theme.defaultAlgorithm,
-        token: {
-          colorPrimary: '#1677ff',
-          borderRadius: 8,
-          fontFamily:
-            '-apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", 
"Hiragino Sans GB", "Microsoft YaHei", sans-serif',
-          ...(darkMode
-            ? {
-                colorBgBase: '#2a2a2e',
-                colorBgContainer: '#323236',
-                colorBgElevated: '#3a3a3e',
-                colorBorder: '#3a3a3e',
-                colorBorderSecondary: '#333337',
-              }
-            : {}),
-        },
-        components: {
-          Card: { borderRadiusLG: 12 },
-          Table: { borderRadius: 8 },
-          Button: { borderRadius: 8 },
-          Tag: { borderRadiusSM: 6 },
-        },
-      }}
-    >
-      <AntdApp>
-        <BrowserRouter>
-          <App />
-        </BrowserRouter>
-      </AntdApp>
-    </ConfigProvider>
-  );
-};
-
 ReactDOM.createRoot(document.getElementById('root')!).render(
   <React.StrictMode>
     <LangProvider>
       <ThemeProvider>
-        <ThemedApp />
+        <StudioApp />
       </ThemeProvider>
     </LangProvider>
   </React.StrictMode>,
diff --git a/web/src/theme/ThemeContext.tsx b/web/src/theme/ThemeContext.tsx
index a722c8e8..e64633a8 100644
--- a/web/src/theme/ThemeContext.tsx
+++ b/web/src/theme/ThemeContext.tsx
@@ -15,14 +15,9 @@
  * limitations under the License.
  */
 
-import { createContext, useContext, useState, useEffect, type ReactNode } from 
'react';
-import {
-  getStoredThemePreference,
-  getSystemDarkMode,
-  persistThemePreference,
-} from './themePreference';
+import { createContext } from 'react';
 
-interface ThemeContextType {
+export interface ThemeContextType {
   darkMode: boolean;
   setDarkMode: (dark: boolean) => void;
   toggleTheme: () => void;
@@ -34,42 +29,4 @@ const ThemeContext = createContext<ThemeContextType>({
   toggleTheme: () => {},
 });
 
-export const ThemeProvider = ({ children }: { children: ReactNode }) => {
-  const [themeState, setThemeState] = useState(() => {
-    const preference = getStoredThemePreference();
-    return {
-      darkMode: preference ? preference === 'dark' : getSystemDarkMode(),
-      followsSystem: preference === null,
-    };
-  });
-
-  const setDarkMode = (darkMode: boolean) => {
-    persistThemePreference(darkMode);
-    setThemeState({ darkMode, followsSystem: false });
-  };
-
-  const toggleTheme = () => setDarkMode(!themeState.darkMode);
-
-  useEffect(() => {
-    if (!themeState.followsSystem || !window.matchMedia) return;
-
-    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
-    const updateTheme = (event: MediaQueryListEvent) => {
-      setThemeState((current) =>
-        current.followsSystem ? { ...current, darkMode: event.matches } : 
current,
-      );
-    };
-    mediaQuery.addEventListener('change', updateTheme);
-    return () => mediaQuery.removeEventListener('change', updateTheme);
-  }, [themeState.followsSystem]);
-
-  return (
-    <ThemeContext.Provider value={{ darkMode: themeState.darkMode, 
setDarkMode, toggleTheme }}>
-      {children}
-    </ThemeContext.Provider>
-  );
-};
-
-export const useTheme = () => useContext(ThemeContext);
-
 export default ThemeContext;
diff --git a/web/src/theme/ThemeContext.tsx b/web/src/theme/ThemeProvider.tsx
similarity index 83%
copy from web/src/theme/ThemeContext.tsx
copy to web/src/theme/ThemeProvider.tsx
index a722c8e8..16b89cf6 100644
--- a/web/src/theme/ThemeContext.tsx
+++ b/web/src/theme/ThemeProvider.tsx
@@ -15,25 +15,14 @@
  * limitations under the License.
  */
 
-import { createContext, useContext, useState, useEffect, type ReactNode } from 
'react';
+import { useEffect, useState, type ReactNode } from 'react';
+import ThemeContext from './ThemeContext';
 import {
   getStoredThemePreference,
   getSystemDarkMode,
   persistThemePreference,
 } from './themePreference';
 
-interface ThemeContextType {
-  darkMode: boolean;
-  setDarkMode: (dark: boolean) => void;
-  toggleTheme: () => void;
-}
-
-const ThemeContext = createContext<ThemeContextType>({
-  darkMode: false,
-  setDarkMode: () => {},
-  toggleTheme: () => {},
-});
-
 export const ThemeProvider = ({ children }: { children: ReactNode }) => {
   const [themeState, setThemeState] = useState(() => {
     const preference = getStoredThemePreference();
@@ -69,7 +58,3 @@ export const ThemeProvider = ({ children }: { children: 
ReactNode }) => {
     </ThemeContext.Provider>
   );
 };
-
-export const useTheme = () => useContext(ThemeContext);
-
-export default ThemeContext;
diff --git a/web/src/theme/__tests__/ThemeContext.test.tsx 
b/web/src/theme/__tests__/ThemeContext.test.tsx
index 95b919eb..c0ecb9e6 100644
--- a/web/src/theme/__tests__/ThemeContext.test.tsx
+++ b/web/src/theme/__tests__/ThemeContext.test.tsx
@@ -18,7 +18,8 @@
 import { describe, it, expect, vi, beforeEach } from 'vitest';
 import { render, screen } from '@testing-library/react';
 import userEvent from '@testing-library/user-event';
-import { ThemeProvider, useTheme } from '../ThemeContext';
+import { ThemeProvider } from '../ThemeProvider';
+import { useTheme } from '../useTheme';
 
 /** Helper component that displays theme state and provides toggle button. */
 const ThemeConsumer = () => {
diff --git a/web/src/theme/useTheme.ts b/web/src/theme/useTheme.ts
new file mode 100644
index 00000000..bad57a53
--- /dev/null
+++ b/web/src/theme/useTheme.ts
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { useContext } from 'react';
+import ThemeContext from './ThemeContext';
+
+export const useTheme = () => useContext(ThemeContext);
diff --git a/web/vite.config.ts b/web/vite.config.ts
index 571f6d5e..5c6fb649 100644
--- a/web/vite.config.ts
+++ b/web/vite.config.ts
@@ -20,9 +20,6 @@ export default defineConfig(({ mode }) => {
       environment: 'jsdom',
       setupFiles: './src/test/setup.ts',
       css: true,
-      // 32-core box: run test files with full parallelism.
-      maxWorkers: 32,
-      minWorkers: 4,
       // antd interactions driven through userEvent are slow in jsdom, and the 
default
       // 5s budget is exceeded once the whole suite runs in parallel.
       testTimeout: 20000,

Reply via email to