vmui: change query params compatible with prometheus (#1619)

* feat: change url params for compatible prometheus

* style: add comment for TimeParams

* fix: change get default server for single version

* fix: change function for get query string value
This commit is contained in:
Yury Molodov 2021-09-15 09:42:49 +03:00 committed by Aliaksandr Valialkin
parent 76109eb0e6
commit df87362ef6
7 changed files with 98 additions and 21147 deletions

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,7 @@
"@testing-library/user-event": "^12.2.2",
"@types/d3": "^6.1.0",
"@types/jest": "^26.0.15",
"@types/lodash.get": "^4.4.6",
"@types/node": "^12.19.4",
"@types/qs": "^6.9.6",
"@types/react": "^16.9.56",
@ -23,6 +24,7 @@
"codemirror-promql": "^0.10.2",
"d3": "^6.2.0",
"dayjs": "^1.10.4",
"lodash.get": "^4.4.2",
"qs": "^6.5.2",
"react": "^17.0.1",
"react-dom": "^17.0.1",

View File

@ -3,6 +3,7 @@ import {TimeParams, TimePeriod} from "../../types";
import {dateFromSeconds, getDurationFromPeriod, getTimeperiodForDuration} from "../../utils/time";
import {getFromStorage} from "../../utils/storage";
import {getDefaultServer} from "../../utils/default-server-url";
import {getQueryStringValue} from "../../utils/query-string";
export interface TimeState {
duration: string;
@ -32,14 +33,16 @@ export type Action =
| { type: "TOGGLE_AUTOREFRESH"}
| { type: "TOGGLE_AUTOCOMPLETE"}
const duration = getQueryStringValue("g0.range_input", "1h");
const endInput = getQueryStringValue("g0.end_input", undefined);
export const initialState: AppState = {
serverUrl: getFromStorage("PREFERRED_URL") as string || getDefaultServer(), // https://demo.promlabs.com or https://play.victoriametrics.com/select/accounting/1/6a716b0f-38bc-4856-90ce-448fd713e3fe/prometheus",
displayType: "chart",
query: getFromStorage("LAST_QUERY") as string || "\n", // demo_memory_usage_bytes
query: getQueryStringValue("g0.expr", getFromStorage("LAST_QUERY") as string || "\n"), // demo_memory_usage_bytes
time: {
duration: "1h",
period: getTimeperiodForDuration("1h")
duration,
period: getTimeperiodForDuration(duration, endInput && new Date(endInput))
},
queryControls: {
autoRefresh: false,

View File

@ -4,6 +4,7 @@ export interface TimeParams {
start: number; // timestamp in seconds
end: number; // timestamp in seconds
step?: number; // seconds
date: string; // end input date
}
export interface TimePeriod {

View File

@ -1,6 +1,6 @@
export const getDefaultServer = (): string => {
const {href} = window.location;
const {href, protocol, host, pathname} = window.location;
const regexp = /^http.+\/vmui/;
const [result] = href.match(regexp) || ["https://"];
const [result] = href.match(regexp) || [`${protocol}//${host}${pathname}prometheus`];
return result.replace("vmui", "prometheus");
};

View File

@ -1,49 +1,59 @@
import qs from "qs";
import get from "lodash.get";
const decoder = (value: string) => {
if (/^(\d+|\d*\.\d+)$/.test(value)) {
return parseFloat(value);
}
const keywords = {
true: true,
false: false,
null: null,
undefined: undefined,
};
if (value in keywords) {
return keywords[value as keyof typeof keywords];
}
return decodeURI(value);
const stateToUrlParams = {
"query": "g0.expr",
"time.duration": "g0.range_input",
"time.period.date": "g0.end_input",
"time.period.step": "g0.step_input",
"stacked": "g0.stacked",
};
// TODO need function for detect types.
// const decoder = (value: string) => {
// This function does not parse dates
// if (/^(\d+|\d*\.\d+)$/.test(value)) {
// return parseFloat(value);
// }
//
// const keywords = {
// true: true,
// false: false,
// null: null,
// undefined: undefined,
// };
// if (value in keywords) {
// return keywords[value as keyof typeof keywords];
// }
//
// return decodeURI(value);
// };
export const setQueryStringWithoutPageReload = (qsValue: string): void => {
const w = window;
if (w) {
const newurl = w.location.protocol +
"//" +
w.location.host +
w.location.pathname +
"?" +
qsValue;
const newurl = `${w.location.protocol}//${w.location.host}${w.location.pathname}?${qsValue}`;
w.history.pushState({ path: newurl }, "", newurl);
}
};
export const setQueryStringValue = (
newValue: Record<string, unknown>,
queryString = window.location.search
): void => {
const values = qs.parse(queryString, { ignoreQueryPrefix: true, decoder });
const newQsValue = qs.stringify({ ...values, ...newValue }, { encode: false });
setQueryStringWithoutPageReload(newQsValue);
export const setQueryStringValue = (newValue: Record<string, unknown>): void => {
const queryMap = new Map(Object.entries(stateToUrlParams));
const newQsValue: string[] = [];
queryMap.forEach((queryKey, stateKey) => {
const value = get(newValue, stateKey, "");
if (value) {
newQsValue.push(`${queryKey}=${value}`);
}
});
setQueryStringWithoutPageReload(newQsValue.join("&"));
};
export const getQueryStringValue = (
key: string,
defaultValue?: any,
queryString = window.location.search
): unknown => {
const values = qs.parse(queryString, { ignoreQueryPrefix: true, decoder });
return values[key];
) => {
const values = qs.parse(queryString, { ignoreQueryPrefix: true });
return get(values, key, defaultValue || "");
};

View File

@ -55,14 +55,12 @@ export const getTimeperiodForDuration = (dur: string, date?: Date): TimeParams =
return {
start: n - delta,
end: n,
step: delta / MAX_ITEMS_PER_CHART
step: delta / MAX_ITEMS_PER_CHART,
date: formatDateForNativeInput((date || new Date()))
};
};
export const formatDateForNativeInput = (date: Date): string => {
const isoString = dayjs(date).format("YYYY-MM-DD[T]HH:mm:ss");
return isoString;
};
export const formatDateForNativeInput = (date: Date): string => dayjs(date).format("YYYY-MM-DD[T]HH:mm:ss");
export const getDurationFromPeriod = (p: TimePeriod): string => {
const dur = dayjs.duration(p.to.valueOf() - p.from.valueOf());