diff --git a/app/vmui/packages/vmui/src/components/Configurators/AdditionalSettings/AdditionalSettings.tsx b/app/vmui/packages/vmui/src/components/Configurators/AdditionalSettings/AdditionalSettings.tsx
index 46959aa03..7dbe65f5b 100644
--- a/app/vmui/packages/vmui/src/components/Configurators/AdditionalSettings/AdditionalSettings.tsx
+++ b/app/vmui/packages/vmui/src/components/Configurators/AdditionalSettings/AdditionalSettings.tsx
@@ -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
{
{!!inputTenantID && (
diff --git a/app/vmui/packages/vmui/src/components/Configurators/StepConfigurator/StepConfigurator.tsx b/app/vmui/packages/vmui/src/components/Configurators/StepConfigurator/StepConfigurator.tsx
index 9c32522ae..97f18d30e 100644
--- a/app/vmui/packages/vmui/src/components/Configurators/StepConfigurator/StepConfigurator.tsx
+++ b/app/vmui/packages/vmui/src/components/Configurators/StepConfigurator/StepConfigurator.tsx
@@ -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 = ({ defaultStep, setStep }) => {
+const StepConfigurator: FC = ({ 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 = ({ defaultStep, setStep }) =
};
useEffect(() => {
- if (defaultStep) handleSetStep(defaultStep);
- }, [defaultStep]);
+ if (value) handleSetStep(value);
+ }, [value]);
return (
{
const { tenantId } = useAppState();
const { displayType } = useCustomPanelState();
const { query } = useQueryState();
const { duration, relativeTime, period: { date, step } } = useTimeState();
+ const { customStep } = useGraphState();
const setSearchParamsFromState = () => {
const params: Record = {};
@@ -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, []);
};
diff --git a/app/vmui/packages/vmui/src/utils/time.ts b/app/vmui/packages/vmui/src/utils/time.ts
index b6c13713a..c6d40ab3c 100644
--- a/app/vmui/packages/vmui/src/utils/time.ts
+++ b/app/vmui/packages/vmui/src/utils/time.ts
@@ -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> | 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,