vmui: step (#3521)

* feat: add step rounding

* fix: change step in URL parameters

* refactor: change comment for roundStep
This commit is contained in:
Yury Molodov 2022-12-22 23:54:28 +01:00 committed by Aliaksandr Valialkin
parent c2fc996e01
commit b3398a125f
No known key found for this signature in database
GPG key ID: A72BEC6CD3D0DED1
4 changed files with 49 additions and 14 deletions

View file

@ -1,6 +1,6 @@
import React, { FC } from "preact/compat";
import React, { FC, useEffect } from "preact/compat";
import StepConfigurator from "../StepConfigurator/StepConfigurator";
import { useGraphDispatch } from "../../../state/graph/GraphStateContext";
import { useGraphDispatch, useGraphState } from "../../../state/graph/GraphStateContext";
import { getAppModeParams } from "../../../utils/app-mode";
import TenantsConfiguration from "../TenantsConfiguration/TenantsConfiguration";
import { useCustomPanelDispatch, useCustomPanelState } from "../../../state/customPanel/CustomPanelStateContext";
@ -8,10 +8,13 @@ import { useTimeState } from "../../../state/time/TimeStateContext";
import { useQueryDispatch, useQueryState } from "../../../state/query/QueryStateContext";
import "./style.scss";
import Switch from "../../Main/Switch/Switch";
import usePrevious from "../../../hooks/usePrevious";
const AdditionalSettings: FC = () => {
const { customStep } = useGraphState();
const graphDispatch = useGraphDispatch();
const { inputTenantID } = getAppModeParams();
const { autocomplete } = useQueryState();
@ -20,7 +23,8 @@ const AdditionalSettings: FC = () => {
const { nocache, isTracingEnabled } = useCustomPanelState();
const customPanelDispatch = useCustomPanelDispatch();
const { period: { step } } = useTimeState();
const { period: { step }, duration } = useTimeState();
const prevDuration = usePrevious(duration);
const onChangeCache = () => {
customPanelDispatch({ type: "TOGGLE_NO_CACHE" });
@ -38,6 +42,15 @@ const AdditionalSettings: FC = () => {
graphDispatch({ type: "SET_CUSTOM_STEP", payload: value });
};
useEffect(() => {
if (!customStep && step) onChangeStep(step);
}, [step]);
useEffect(() => {
if (duration === prevDuration || !prevDuration) return;
if (step) onChangeStep(step);
}, [duration, prevDuration]);
return <div className="vm-additional-settings">
<Switch
label={"Autocomplete"}
@ -58,6 +71,7 @@ const AdditionalSettings: FC = () => {
<StepConfigurator
defaultStep={step}
setStep={onChangeStep}
value={customStep}
/>
</div>
{!!inputTenantID && (

View file

@ -1,5 +1,4 @@
import React, { FC, useCallback, useState } from "preact/compat";
import { useEffect } from "react";
import React, { FC, useCallback, useEffect, useState } from "preact/compat";
import debounce from "lodash.debounce";
import { RestartIcon } from "../../Main/Icons";
import TextField from "../../Main/TextField/TextField";
@ -8,16 +7,17 @@ import Tooltip from "../../Main/Tooltip/Tooltip";
interface StepConfiguratorProps {
defaultStep?: number,
value?: number,
setStep: (step: number) => void,
}
const StepConfigurator: FC<StepConfiguratorProps> = ({ defaultStep, setStep }) => {
const StepConfigurator: FC<StepConfiguratorProps> = ({ value, defaultStep, setStep }) => {
const [customStep, setCustomStep] = useState(defaultStep);
const [customStep, setCustomStep] = useState(value || defaultStep);
const [error, setError] = useState("");
const handleApply = (step: number) => setStep(step || 1);
const debouncedHandleApply = useCallback(debounce(handleApply, 700), []);
const debouncedHandleApply = useCallback(debounce(handleApply, 500), []);
const onChangeStep = (val: string) => {
const value = +val;
@ -40,12 +40,12 @@ const StepConfigurator: FC<StepConfiguratorProps> = ({ defaultStep, setStep }) =
};
useEffect(() => {
if (defaultStep) handleSetStep(defaultStep);
}, [defaultStep]);
if (value) handleSetStep(value);
}, [value]);
return (
<TextField
label="Step value"
label="Step value of seconds"
type="number"
value={customStep}
error={error}

View file

@ -6,12 +6,14 @@ import { useQueryState } from "../../../state/query/QueryStateContext";
import { displayTypeTabs } from "../DisplayTypeSwitch";
import { setQueryStringWithoutPageReload } from "../../../utils/query-string";
import { compactObject } from "../../../utils/object";
import { useGraphState } from "../../../state/graph/GraphStateContext";
export const useSetQueryParams = () => {
const { tenantId } = useAppState();
const { displayType } = useCustomPanelState();
const { query } = useQueryState();
const { duration, relativeTime, period: { date, step } } = useTimeState();
const { customStep } = useGraphState();
const setSearchParamsFromState = () => {
const params: Record<string, unknown> = {};
@ -20,15 +22,16 @@ export const useSetQueryParams = () => {
params[`${group}.expr`] = q;
params[`${group}.range_input`] = duration;
params[`${group}.end_input`] = date;
params[`${group}.step_input`] = step;
params[`${group}.tab`] = displayTypeTabs.find(t => t.value === displayType)?.prometheusCode || 0;
params[`${group}.relative_time`] = relativeTime;
params[`${group}.tenantID`] = tenantId;
if ((step !== customStep) && customStep) params[`${group}.step_input`] = customStep;
});
setQueryStringWithoutPageReload(compactObject(params));
};
useEffect(setSearchParamsFromState, [tenantId, displayType, query, duration, relativeTime, date, step]);
useEffect(setSearchParamsFromState, [tenantId, displayType, query, duration, relativeTime, date, step, customStep]);
useEffect(setSearchParamsFromState, []);
};

View file

@ -26,6 +26,23 @@ const shortDurations = supportedDurations.map(d => d.short);
export const roundToMilliseconds = (num: number): number => Math.round(num*1000)/1000;
const roundStep = (step: number) => {
const integerStep = Math.round(step);
if (step >= 100) {
return integerStep - (integerStep%10); // integer multiple of 10
}
if (step < 100 && step >= 10) {
return integerStep - (integerStep%5); // integer multiple of 5
}
if (step < 10 && step >= 1) {
return integerStep; // integer
}
if (step < 1 && step > 0.01) {
return Math.round(step * 40) / 40; // float to thousandths multiple of 5
}
return roundToMilliseconds(step);
};
export const isSupportedDuration = (str: string): Partial<Record<UnitTypeShort, string>> | undefined => {
const digits = str.match(/\d+/g);
@ -57,7 +74,8 @@ export const getTimeperiodForDuration = (dur: string, date?: Date): TimeParams =
}, {});
const delta = dayjs.duration(durObject).asSeconds();
const step = roundToMilliseconds(delta / MAX_ITEMS_PER_CHART) || 0.001;
const rawStep = delta / MAX_ITEMS_PER_CHART;
const step = roundStep(rawStep) || 0.001;
return {
start: n - delta,