From 59199a98dd80094548f77ba01aec2febd867c515 Mon Sep 17 00:00:00 2001 From: Yury Molodov Date: Mon, 24 Oct 2022 19:45:41 +0200 Subject: [PATCH 1/6] vmui: extend options for app mode (#3252) * feat: add vmui customization for dbaas * feat: extends vmui customization for dbaas * fix: move input tenandId after query * fix: change serverURL when changing tenantID * fix: remove options * docs: add options description --- app/vmui/packages/vmui/README.md | 56 +++++++++++++++++ app/vmui/packages/vmui/public/index.html | 4 +- .../Configurator/Graph/GraphSettings.tsx | 4 +- .../Configurator/Query/AdditionalSettings.tsx | 16 ++--- .../Configurator/Query/QueryConfigurator.tsx | 2 +- .../Configurator/Query/StepConfigurator.tsx | 51 +++++----------- .../Configurator/Settings/GlobalSettings.tsx | 6 +- .../Settings/ServerConfigurator.tsx | 20 ++----- .../Settings/TenantsConfiguration.tsx | 60 +++++++++++++++++++ .../Configurator/Time/ExecutionControls.tsx | 6 +- .../Configurator/Time/TimeSelector.tsx | 4 +- .../components/CustomPanel/CustomPanel.tsx | 4 +- .../CustomPanel/Views/GraphView.tsx | 6 +- .../vmui/src/components/Header/Header.tsx | 51 +++++++++------- .../vmui/src/components/LineChart/tooltip.css | 4 +- .../components/Main/DatePicker/DatePicker.tsx | 4 +- .../PredefinedPanels/PredefinedPanels.tsx | 10 ++-- .../components/ShortcutKeys/ShortcutKeys.tsx | 4 +- .../src/components/Table/TableSettings.tsx | 6 +- .../vmui/src/components/common/Logo.tsx | 14 +++-- .../vmui/src/hooks/useCardinalityFetch.ts | 9 +-- .../packages/vmui/src/hooks/useFetchQuery.ts | 18 ++---- .../vmui/src/hooks/useFetchQueryOptions.ts | 9 +-- .../vmui/src/hooks/useFetchTopQueries.ts | 8 +-- app/vmui/packages/vmui/src/index.css | 4 +- .../packages/vmui/src/state/common/reducer.ts | 10 +++- .../packages/vmui/src/state/graph/reducer.ts | 23 +------ app/vmui/packages/vmui/src/theme/theme.ts | 35 +++++++++-- app/vmui/packages/vmui/src/utils/app-mode.ts | 22 ++++++- .../vmui/src/utils/default-server-url.ts | 5 +- .../packages/vmui/src/utils/query-string.ts | 1 + 31 files changed, 299 insertions(+), 177 deletions(-) create mode 100644 app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Settings/TenantsConfiguration.tsx diff --git a/app/vmui/packages/vmui/README.md b/app/vmui/packages/vmui/README.md index b87cb0044..fe0a53322 100644 --- a/app/vmui/packages/vmui/README.md +++ b/app/vmui/packages/vmui/README.md @@ -44,3 +44,59 @@ You don’t have to ever use `eject`. The curated feature set is suitable for sm You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). To learn React, check out the [React documentation](https://reactjs.org/). + +--- + +# VMUI config options +VMUI can be used to paste into other applications + +1. Go to file `index.html` +2. Find root element `
` +3. Add `data-params` with the options + +#### Options (JSON): + +| Name | Default | Description | +|:------------------------|:--------------:|--------------------------------------------------------------------------------------:| +| serverURL | domain name | Can't be changed from the UI | +| inputTenantID | - | If the flag is present, the "Tenant ID" field is displayed | +| headerStyles.background | `#FFFFFF` | Header background color | +| headerStyles.color | `primary.main` | Header font color | +| palette.primary | `#3F51B5` | used to represent primary interface elements for a user | +| palette.secondary | `#F50057` | used to represent secondary interface elements for a user | +| palette.error | `#FF4141` | used to represent interface elements that the user should be made aware of | +| palette.warning | `#FF9800` | used to represent potentially dangerous actions or important messages | +| palette.success | `#4CAF50` | used to indicate the successful completion of an action that user triggered | +| palette.info | `#03A9F4` | used to present information to the user that is neutral and not necessarily important | + +#### JSON example: +```json +{ + "serverURL": "http://localhost:8428", + "inputTenantID": "true", + "headerStyles": { + "background": "#fff", + "color": "primary.main" + }, + "palette": { + "primary": "#538DE8", + "secondary": "#F76F8E", + "error": "#FD151B", + "warning": "#FFB30F", + "success": "#7BE622", + "info": "#0F5BFF" + } +} +``` + + +#### HTML example: +```html +
+``` + + + + + + diff --git a/app/vmui/packages/vmui/public/index.html b/app/vmui/packages/vmui/public/index.html index 7ee3279d1..2d061a82a 100644 --- a/app/vmui/packages/vmui/public/index.html +++ b/app/vmui/packages/vmui/public/index.html @@ -26,7 +26,9 @@ Learn how to configure a non-root public URL by running `npm run build`. --> VM UI - + + + diff --git a/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Graph/GraphSettings.tsx b/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Graph/GraphSettings.tsx index 0ef35d225..fe91a1245 100644 --- a/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Graph/GraphSettings.tsx +++ b/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Graph/GraphSettings.tsx @@ -21,10 +21,10 @@ const classes = { display: "flex", alignItems: "center", justifyContent: "space-between", - background: "#3F51B5", + backgroundColor: "primary.main", padding: "6px 6px 6px 12px", borderRadius: "4px 4px 0 0", - color: "#FFF", + color: "primary.contrastText", }, popoverBody: { display: "grid", diff --git a/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Query/AdditionalSettings.tsx b/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Query/AdditionalSettings.tsx index ef09a52bf..867ce71f9 100644 --- a/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Query/AdditionalSettings.tsx +++ b/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Query/AdditionalSettings.tsx @@ -5,12 +5,14 @@ import {saveToStorage} from "../../../../utils/storage"; import {useAppDispatch, useAppState} from "../../../../state/common/StateContext"; import BasicSwitch from "../../../../theme/switch"; import StepConfigurator from "./StepConfigurator"; -import {useGraphDispatch, useGraphState} from "../../../../state/graph/GraphStateContext"; +import {useGraphDispatch} from "../../../../state/graph/GraphStateContext"; +import {getAppModeParams} from "../../../../utils/app-mode"; +import TenantsConfiguration from "../Settings/TenantsConfiguration"; const AdditionalSettings: FC = () => { - const {customStep} = useGraphState(); const graphDispatch = useGraphDispatch(); + const {inputTenantID} = getAppModeParams(); const {queryControls: {autocomplete, nocache, isTracingEnabled}, time: {period: {step}}} = useAppState(); const dispatch = useAppDispatch(); @@ -46,15 +48,15 @@ const AdditionalSettings: FC = () => { control={} /> - - + { graphDispatch({type: "SET_CUSTOM_STEP", payload: value}); }} - toggleEnableStep={() => { - graphDispatch({type: "TOGGLE_CUSTOM_STEP"}); - }}/> + /> + {!!inputTenantID && } ; }; diff --git a/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Query/QueryConfigurator.tsx b/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Query/QueryConfigurator.tsx index e49d91e2c..24f2305e9 100644 --- a/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Query/QueryConfigurator.tsx +++ b/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Query/QueryConfigurator.tsx @@ -75,7 +75,7 @@ const QueryConfigurator: FC = ({error, queryOptions}) => } }, [stateQuery]); - return + return {stateQuery.map((q, i) => void, - toggleEnableStep: () => void } -const StepConfigurator: FC = ({ - defaultStep, customStepEnable, setStep, toggleEnableStep -}) => { +const StepConfigurator: FC = ({defaultStep, setStep}) => { const [customStep, setCustomStep] = useState(defaultStep); const [error, setError] = useState(false); - useEffect(() => { - setStep(customStep || 1); - }, [customStep]); + const handleApply = (step: number) => setStep(step || 1); + const debouncedHandleApply = useCallback(debounce(handleApply, 700), []); const onChangeStep = (e: ChangeEvent) => { - if (!customStepEnable) return; const value = +e.target.value; if (value > 0) { setCustomStep(value); + debouncedHandleApply(value); setError(false); } else { setError(true); } }; - const onChangeEnableStep = () => { - setError(false); - toggleEnableStep(); - }; - - return - } - label="Override step value" - /> - - ; + return ; }; -export default StepConfigurator; \ No newline at end of file +export default StepConfigurator; diff --git a/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Settings/GlobalSettings.tsx b/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Settings/GlobalSettings.tsx index 3c9178bac..552ebe50b 100644 --- a/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Settings/GlobalSettings.tsx +++ b/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Settings/GlobalSettings.tsx @@ -9,7 +9,6 @@ import Typography from "@mui/material/Typography"; import CloseIcon from "@mui/icons-material/Close"; import IconButton from "@mui/material/IconButton"; import {useAppDispatch, useAppState} from "../../../../state/common/StateContext"; -import {getAppModeEnable} from "../../../../utils/app-mode"; const modalStyle = { position: "absolute" as const, @@ -27,13 +26,12 @@ const title = "Setting Server URL"; const GlobalSettings: FC = () => { - const appModeEnable = getAppModeEnable(); const {serverUrl} = useAppState(); const dispatch = useAppDispatch(); const [changedServerUrl, setChangedServerUrl] = useState(serverUrl); const setServer = () => { - if (!appModeEnable) dispatch({type: "SET_SERVER", payload: changedServerUrl}); + dispatch({type: "SET_SERVER", payload: changedServerUrl}); handleClose(); }; @@ -79,4 +77,4 @@ const GlobalSettings: FC = () => { ; }; -export default GlobalSettings; \ No newline at end of file +export default GlobalSettings; diff --git a/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Settings/ServerConfigurator.tsx b/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Settings/ServerConfigurator.tsx index 548b752c7..837926a7a 100644 --- a/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Settings/ServerConfigurator.tsx +++ b/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Settings/ServerConfigurator.tsx @@ -1,8 +1,7 @@ -import React, {FC, useEffect, useState} from "preact/compat"; +import React, {FC, useState} from "preact/compat"; import TextField from "@mui/material/TextField"; -import {useAppDispatch, useAppState} from "../../../../state/common/StateContext"; +import {useAppState} from "../../../../state/common/StateContext"; import {ErrorTypes} from "../../../../types"; -import {getAppModeEnable, getAppModeParams} from "../../../../utils/app-mode"; import {ChangeEvent} from "react"; export interface ServerConfiguratorProps { @@ -12,30 +11,19 @@ export interface ServerConfiguratorProps { const ServerConfigurator: FC = ({error, setServer}) => { - const appModeEnable = getAppModeEnable(); - const {serverURL: appServerUrl} = getAppModeParams(); - const {serverUrl} = useAppState(); - const dispatch = useAppDispatch(); const [changedServerUrl, setChangedServerUrl] = useState(serverUrl); - useEffect(() => { - if (appModeEnable) { - dispatch({type: "SET_SERVER", payload: appServerUrl}); - setChangedServerUrl(appServerUrl); - } - }, [appServerUrl]); - const onChangeServer = (e: ChangeEvent) => { const value = e.target.value || ""; setChangedServerUrl(value); setServer(value); }; - return ; }; -export default ServerConfigurator; \ No newline at end of file +export default ServerConfigurator; diff --git a/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Settings/TenantsConfiguration.tsx b/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Settings/TenantsConfiguration.tsx new file mode 100644 index 000000000..27295becf --- /dev/null +++ b/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Settings/TenantsConfiguration.tsx @@ -0,0 +1,60 @@ +import React, {FC, useState, useEffect, useCallback} from "preact/compat"; +import TextField from "@mui/material/TextField"; +import InputAdornment from "@mui/material/InputAdornment"; +import Tooltip from "@mui/material/Tooltip"; +import InfoIcon from "@mui/icons-material/Info"; +import {useAppDispatch, useAppState} from "../../../../state/common/StateContext"; +import {ChangeEvent} from "react"; +import debounce from "lodash.debounce"; +import {getAppModeParams} from "../../../../utils/app-mode"; + +const TenantsConfiguration: FC = () => { + const {serverURL} = getAppModeParams(); + const {tenantId: tenantIdState} = useAppState(); + const dispatch = useAppDispatch(); + + const [tenantId, setTenantId] = useState(tenantIdState || 0); + + const handleApply = (value: string | number) => { + const tenantId = Number(value); + dispatch({type: "SET_TENANT_ID", payload: tenantId}); + if (serverURL) { + const updateServerUrl = serverURL.replace(/(\/select\/)([\d]+)(\/prometheus)/gmi, `$1${tenantId}$3`); + dispatch({type: "SET_SERVER", payload: updateServerUrl}); + dispatch({type: "RUN_QUERY"}); + } + }; + + const debouncedHandleApply = useCallback(debounce(handleApply, 700), []); + + const handleChange = (e: ChangeEvent) => { + setTenantId(e.target.value); + debouncedHandleApply(e.target.value); + }; + + useEffect(() => { + if (tenantId === tenantIdState) return; + setTenantId(tenantIdState); + }, [tenantIdState]); + + return + + + + + ), + }} + />; +}; + +export default TenantsConfiguration; diff --git a/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Time/ExecutionControls.tsx b/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Time/ExecutionControls.tsx index dd90fe44e..25b57dc05 100644 --- a/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Time/ExecutionControls.tsx +++ b/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Time/ExecutionControls.tsx @@ -11,6 +11,7 @@ import List from "@mui/material/List"; import ListItem from "@mui/material/ListItem"; import ListItemText from "@mui/material/ListItemText"; import {useLocation} from "react-router-dom"; +import {getAppModeEnable} from "../../../../utils/app-mode"; interface AutoRefreshOption { seconds: number @@ -35,6 +36,7 @@ const delayOptions: AutoRefreshOption[] = [ export const ExecutionControls: FC = () => { const dispatch = useAppDispatch(); + const appModeEnable = getAppModeEnable(); const {queryControls: {autoRefresh}} = useAppState(); const location = useLocation(); @@ -77,7 +79,7 @@ export const ExecutionControls: FC = () => { sx={{ minWidth: "110px", color: "white", - border: "1px solid rgba(0, 0, 0, 0.2)", + border: appModeEnable ? "none" : "1px solid rgba(0, 0, 0, 0.2)", justifyContent: "space-between", boxShadow: "none", }} @@ -104,4 +106,4 @@ export const ExecutionControls: FC = () => { ; -}; \ No newline at end of file +}; diff --git a/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Time/TimeSelector.tsx b/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Time/TimeSelector.tsx index 8458bdd20..f7b1c838e 100644 --- a/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Time/TimeSelector.tsx +++ b/app/vmui/packages/vmui/src/components/CustomPanel/Configurator/Time/TimeSelector.tsx @@ -15,6 +15,7 @@ import Divider from "@mui/material/Divider"; import ClickAwayListener from "@mui/material/ClickAwayListener"; import Tooltip from "@mui/material/Tooltip"; import AlarmAdd from "@mui/icons-material/AlarmAdd"; +import {getAppModeEnable} from "../../../../utils/app-mode"; const formatDate = "YYYY-MM-DD HH:mm:ss"; @@ -43,6 +44,7 @@ export const TimeSelector: FC = () => { const {time: {period: {end, start}, relativeTime}} = useAppState(); const dispatch = useAppDispatch(); + const appModeEnable = getAppModeEnable(); useEffect(() => { setUntil(formatDateForNativeInput(dateFromSeconds(end))); @@ -96,7 +98,7 @@ export const TimeSelector: FC = () => {