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,