mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
vmui: add option to customize url params for individual pages (#2582)
This commit is contained in:
parent
87e4e76537
commit
8739fb8a91
3 changed files with 54 additions and 24 deletions
|
@ -19,29 +19,29 @@ import DashboardsLayout from "./components/PredefinedPanels/DashboardsLayout";
|
|||
const App: FC = () => {
|
||||
|
||||
return <>
|
||||
<CssBaseline /> {/* CSS Baseline: kind of normalize.css made by materialUI team - can be scoped */}
|
||||
<LocalizationProvider dateAdapter={DayjsUtils}> {/* Allows datepicker to work with DayJS */}
|
||||
<StyledEngineProvider injectFirst>
|
||||
<ThemeProvider theme={THEME}> {/* Material UI theme customization */}
|
||||
<StateProvider> {/* Serialized into query string, common app settings */}
|
||||
<AuthStateProvider> {/* Auth related info - optionally persisted to Local Storage */}
|
||||
<GraphStateProvider> {/* Graph settings */}
|
||||
<SnackbarProvider> {/* Display various snackbars */}
|
||||
<HashRouter>
|
||||
<HashRouter>
|
||||
<CssBaseline /> {/* CSS Baseline: kind of normalize.css made by materialUI team - can be scoped */}
|
||||
<LocalizationProvider dateAdapter={DayjsUtils}> {/* Allows datepicker to work with DayJS */}
|
||||
<StyledEngineProvider injectFirst>
|
||||
<ThemeProvider theme={THEME}> {/* Material UI theme customization */}
|
||||
<StateProvider> {/* Serialized into query string, common app settings */}
|
||||
<AuthStateProvider> {/* Auth related info - optionally persisted to Local Storage */}
|
||||
<GraphStateProvider> {/* Graph settings */}
|
||||
<SnackbarProvider> {/* Display various snackbars */}
|
||||
<Routes>
|
||||
<Route path={"/"} element={<HomeLayout/>}>
|
||||
<Route path={router.home} element={<CustomPanel/>}/>
|
||||
<Route path={router.dashboards} element={<DashboardsLayout/>}/>
|
||||
</Route>
|
||||
</Routes>
|
||||
</HashRouter>
|
||||
</SnackbarProvider>
|
||||
</GraphStateProvider>
|
||||
</AuthStateProvider>
|
||||
</StateProvider>
|
||||
</ThemeProvider>
|
||||
</StyledEngineProvider>
|
||||
</LocalizationProvider>
|
||||
</SnackbarProvider>
|
||||
</GraphStateProvider>
|
||||
</AuthStateProvider>
|
||||
</StateProvider>
|
||||
</ThemeProvider>
|
||||
</StyledEngineProvider>
|
||||
</LocalizationProvider>
|
||||
</HashRouter>
|
||||
</>;
|
||||
};
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import React, {createContext, FC, useContext, useEffect, useMemo, useReducer} fr
|
|||
import {Action, AppState, initialState, reducer} from "./reducer";
|
||||
import {getQueryStringValue, setQueryStringValue} from "../../utils/query-string";
|
||||
import {Dispatch} from "react";
|
||||
import {useLocation} from "react-router-dom";
|
||||
|
||||
type StateContextType = { state: AppState, dispatch: Dispatch<Action> };
|
||||
|
||||
|
@ -17,12 +18,13 @@ export const initialPrepopulatedState = Object.entries(initialState)
|
|||
}), {}) as AppState;
|
||||
|
||||
export const StateProvider: FC = ({children}) => {
|
||||
const location = useLocation();
|
||||
|
||||
const [state, dispatch] = useReducer(reducer, initialPrepopulatedState);
|
||||
|
||||
useEffect(() => {
|
||||
setQueryStringValue(state as unknown as Record<string, unknown>);
|
||||
}, [state]);
|
||||
}, [state, location]);
|
||||
|
||||
const contextValue = useMemo(() => {
|
||||
return { state, dispatch };
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
import qs from "qs";
|
||||
import get from "lodash.get";
|
||||
import router from "../router";
|
||||
|
||||
const stateToUrlParams = {
|
||||
const graphStateToUrlParams = {
|
||||
"time.duration": "range_input",
|
||||
"time.period.date": "end_input",
|
||||
"time.period.step": "step_input",
|
||||
"time.relativeTime": "relative_time",
|
||||
"displayType": "tab"
|
||||
"displayType": "tab",
|
||||
};
|
||||
|
||||
const stateToUrlParams = {
|
||||
[router.home]: graphStateToUrlParams,
|
||||
[router.dashboards]: graphStateToUrlParams,
|
||||
};
|
||||
|
||||
// TODO need function for detect types.
|
||||
|
@ -32,14 +38,23 @@ const stateToUrlParams = {
|
|||
export const setQueryStringWithoutPageReload = (qsValue: string): void => {
|
||||
const w = window;
|
||||
if (w) {
|
||||
const newurl = `${w.location.protocol}//${w.location.host}${w.location.pathname}?${qsValue}${w.location.hash}`;
|
||||
const qs = qsValue ? `?${qsValue}` : "";
|
||||
const newurl = `${w.location.protocol}//${w.location.host}${w.location.pathname}${qs}${w.location.hash}`;
|
||||
w.history.pushState({ path: newurl }, "", newurl);
|
||||
}
|
||||
};
|
||||
|
||||
export const setQueryStringValue = (newValue: Record<string, unknown>): void => {
|
||||
const queryMap = new Map(Object.entries(stateToUrlParams));
|
||||
const query = get(newValue, "query", "") as string[];
|
||||
const route = window.location.hash.replace("#", "");
|
||||
const params = stateToUrlParams[route] || {};
|
||||
const queryMap = new Map(Object.entries(params));
|
||||
const isGraphRoute = route === router.home || route === router.dashboards;
|
||||
const newQsValue = isGraphRoute ? getGraphQsValue(newValue, queryMap) : getQsValue(newValue, queryMap);
|
||||
setQueryStringWithoutPageReload(newQsValue.join("&"));
|
||||
};
|
||||
|
||||
const getGraphQsValue = (newValue: Record<string, unknown>, queryMap: Map<string, string>): string[] => {
|
||||
const query = get(newValue, "query", []) as string[];
|
||||
const newQsValue: string[] = [];
|
||||
query.forEach((q, i) => {
|
||||
queryMap.forEach((queryKey, stateKey) => {
|
||||
|
@ -52,7 +67,20 @@ export const setQueryStringValue = (newValue: Record<string, unknown>): void =>
|
|||
newQsValue.push(`g${i}.expr=${encodeURIComponent(q)}`);
|
||||
});
|
||||
|
||||
setQueryStringWithoutPageReload(newQsValue.join("&"));
|
||||
return newQsValue;
|
||||
};
|
||||
|
||||
const getQsValue = (newValue: Record<string, unknown>, queryMap: Map<string, string>): string[] => {
|
||||
const newQsValue: string[] = [];
|
||||
queryMap.forEach((queryKey, stateKey) => {
|
||||
const value = get(newValue, stateKey, "") as string;
|
||||
if (value) {
|
||||
const valueEncoded = encodeURIComponent(value);
|
||||
newQsValue.push(`${queryKey}=${valueEncoded}`);
|
||||
}
|
||||
});
|
||||
|
||||
return newQsValue;
|
||||
};
|
||||
|
||||
export const getQueryStringValue = (
|
||||
|
|
Loading…
Reference in a new issue