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,