diff --git a/locust/webui/README.md b/locust/webui/README.md
index da32f66292..310c3ebc85 100644
--- a/locust/webui/README.md
+++ b/locust/webui/README.md
@@ -6,7 +6,7 @@ The Locust UI is used for viewing stats, reports, and information on your curren
**Using the Locust UI as a library should be considered an experimental feature**
-The Locust UI may be extended to fit your needs. If you only need limited extensibility, you may do so in your Locustfile, see the [extend_web_ui example](https://github.com/locustio/locust/blob/master/examples/extend_web_ui.py).
+The Locust UI may be extended to fit your needs. If you only need limited extensibility, you may do so in your Locustfile, see the [extend_web_ui example](https://github.com/locustio/locust/blob/master/examples/extend_web_ui.py).
However, you may want to further extend certain functionalities. To do so, you may replace the default Locust UI with your own React application. Start by installing the locust-ui in your React application:
```sh
@@ -66,7 +66,7 @@ For Locust to be able to pass data to your React frontend, place the following s
To load the favicon, place the link in your head:
```html
-
+
```
Lastly, you must configure Locust to point to your own React build output. To achieve this, you can use the flag `--build-path` and provide the **absolute** path to your build directory.
@@ -108,14 +108,17 @@ function App() {
The `tabs` prop allows for complete control of which tabs are rendered. You can then customize which base tabs are shown or where your new tab should be placed:
```js
-import LocustUi, { baseTabs } from "locust-ui";
+import LocustUi, { tabConfig } from "locust-ui";
-const tabs = [...baseTabs];
-tabs.splice(2, 0, {
- title: "Custom Tab",
- key: "custom-tab",
- component: MyCustomTab,
-});
+const tabs = [
+ tabConfig.stats,
+ tabConfig.charts,
+ {
+ title: "Custom Tab",
+ key: "custom-tab",
+ component: MyCustomTab,
+ },
+]
function App() {
return (
@@ -164,6 +167,3 @@ function App() {
tabs={/* Optional array of tabs that will take precedence over extendedTabs */}
/>
```
-
-
-
diff --git a/locust/webui/src/components/Tabs/Tabs.constants.tsx b/locust/webui/src/components/Tabs/Tabs.constants.tsx
index c879c47ea6..91eee63688 100644
--- a/locust/webui/src/components/Tabs/Tabs.constants.tsx
+++ b/locust/webui/src/components/Tabs/Tabs.constants.tsx
@@ -8,47 +8,59 @@ import SwarmRatios from 'components/SwarmRatios/SwarmRatios';
import WorkersTable from 'components/WorkersTable/WorkersTable';
import { LOG_VIEWER_KEY } from 'constants/logs';
import { IRootState } from 'redux/store';
+import { ITab } from 'types/tab.types';
-export const baseTabs = [
- {
+export const tabConfig = {
+ stats: {
component: StatsTable,
key: 'stats',
title: 'Statistics',
},
- {
+ charts: {
component: SwarmCharts,
key: 'charts',
title: 'Charts',
},
- {
+ failures: {
component: FailuresTable,
key: 'failures',
title: 'Failures',
},
- {
+ exceptions: {
component: ExceptionsTable,
key: 'exceptions',
title: 'Exceptions',
},
- {
+ ratios: {
component: SwarmRatios,
key: 'ratios',
title: 'Current Ratio',
},
- {
+ reports: {
component: Reports,
key: 'reports',
title: 'Download Data',
},
- {
+ logs: {
component: LogViewer,
key: LOG_VIEWER_KEY,
title: 'Logs',
},
- {
+ workers: {
component: WorkersTable,
key: 'workers',
title: 'Workers',
shouldDisplayTab: (state: IRootState) => state.swarm.isDistributed,
},
+};
+
+export const baseTabs: ITab[] = [
+ tabConfig.stats,
+ tabConfig.charts,
+ tabConfig.failures,
+ tabConfig.exceptions,
+ tabConfig.ratios,
+ tabConfig.reports,
+ tabConfig.logs,
+ tabConfig.workers,
];
diff --git a/locust/webui/src/hooks/useCreateTheme.ts b/locust/webui/src/hooks/useCreateTheme.ts
index ee6fea760c..41ca54bb0c 100644
--- a/locust/webui/src/hooks/useCreateTheme.ts
+++ b/locust/webui/src/hooks/useCreateTheme.ts
@@ -1,15 +1,14 @@
import { useMemo } from 'react';
-import { Theme } from '@mui/material/styles';
import { THEME_MODE } from 'constants/theme';
import { useSelector } from 'redux/hooks';
import createTheme from 'styles/theme';
-export default function useCreateTheme(extendedTheme?: Theme) {
+export default function useCreateTheme() {
const isDarkMode = useSelector(({ theme: { isDarkMode } }) => isDarkMode);
const theme = useMemo(
- () => createTheme(isDarkMode ? THEME_MODE.DARK : THEME_MODE.LIGHT, extendedTheme),
+ () => createTheme(isDarkMode ? THEME_MODE.DARK : THEME_MODE.LIGHT),
[isDarkMode],
);
diff --git a/locust/webui/src/lib.tsx b/locust/webui/src/lib.tsx
index 40e92efc37..1c2515bf02 100644
--- a/locust/webui/src/lib.tsx
+++ b/locust/webui/src/lib.tsx
@@ -22,7 +22,8 @@ export { default as useFetchExceptions } from 'hooks/useFetchExceptions';
export { default as useFetchTasks } from 'hooks/useFetchTasks';
export { default as useFetchStats } from 'hooks/useFetchStats';
export { default as Navbar } from 'components/Layout/Navbar/Navbar';
-export { default as useTheme } from 'hooks/useTheme';
+export { default as useCreateTheme } from 'hooks/useCreateTheme';
+export { tabConfig } from 'components/Tabs/Tabs.constants';
export { store as locustStore } from 'redux/store';
export type { IRootState } from 'redux/store';
diff --git a/locust/webui/src/pages/Dashboard.tsx b/locust/webui/src/pages/Dashboard.tsx
index 38c838ae29..ea8a8cfe55 100644
--- a/locust/webui/src/pages/Dashboard.tsx
+++ b/locust/webui/src/pages/Dashboard.tsx
@@ -7,10 +7,10 @@ import useLogViewer from 'components/LogViewer/useLogViewer';
import SwarmForm from 'components/SwarmForm/SwarmForm';
import Tabs from 'components/Tabs/Tabs';
import { SWARM_STATE } from 'constants/swarm';
+import useCreateTheme from 'hooks/useCreateTheme';
import useFetchExceptions from 'hooks/useFetchExceptions';
import useFetchStats from 'hooks/useFetchStats';
import useFetchTasks from 'hooks/useFetchTasks';
-import useTheme from 'hooks/useTheme';
import { IRootState } from 'redux/store';
import { ITab } from 'types/tab.types';
import { SwarmState } from 'types/ui.types';
@@ -28,7 +28,7 @@ function Dashboard({ swarmState, tabs, extendedTabs }: IDashboard) {
useFetchTasks();
useLogViewer();
- const { theme } = useTheme();
+ const theme = useCreateTheme();
return (