From 15ee0a0758eb47a4c110249dafc8483c60d5cb12 Mon Sep 17 00:00:00 2001 From: Andrew Baldwin <andrew.baldwin44@gmail.com> Date: Fri, 16 Aug 2024 22:52:00 -0400 Subject: [PATCH] Expose tab config --- locust/webui/README.md | 24 +++++++-------- .../src/components/Tabs/Tabs.constants.tsx | 30 +++++++++++++------ locust/webui/src/hooks/useCreateTheme.ts | 5 ++-- locust/webui/src/lib.tsx | 3 +- locust/webui/src/pages/Dashboard.tsx | 4 +-- 5 files changed, 39 insertions(+), 27 deletions(-) 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 -<link rel="icon" href="./assets/favicon.ico" /> +<link rel="icon" href="./assets/favicon.png" /> ``` 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 ( <ThemeProvider theme={theme}>