From 1df87807fd7b360a8c7eb9eb770b5773385a9e30 Mon Sep 17 00:00:00 2001 From: Yury Molodov <yurymolodov@gmail.com> Date: Thu, 22 Dec 2022 23:54:28 +0100 Subject: [PATCH] vmui: step (#3521) * feat: add step rounding * fix: change step in URL parameters * refactor: change comment for roundStep --- .../AdditionalSettings/AdditionalSettings.tsx | 20 ++++++++++++++++--- .../StepConfigurator/StepConfigurator.tsx | 16 +++++++-------- .../CustomPanel/hooks/useSetQueryParams.ts | 7 +++++-- app/vmui/packages/vmui/src/utils/time.ts | 20 ++++++++++++++++++- 4 files changed, 49 insertions(+), 14 deletions(-) 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 46959aa035..7dbe65f5bd 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 <div className="vm-additional-settings"> <Switch label={"Autocomplete"} @@ -58,6 +71,7 @@ const AdditionalSettings: FC = () => { <StepConfigurator defaultStep={step} setStep={onChangeStep} + value={customStep} /> </div> {!!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 9c32522ae6..97f18d30e2 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<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} diff --git a/app/vmui/packages/vmui/src/pages/CustomPanel/hooks/useSetQueryParams.ts b/app/vmui/packages/vmui/src/pages/CustomPanel/hooks/useSetQueryParams.ts index 8f85222b4b..8c51aad28a 100644 --- a/app/vmui/packages/vmui/src/pages/CustomPanel/hooks/useSetQueryParams.ts +++ b/app/vmui/packages/vmui/src/pages/CustomPanel/hooks/useSetQueryParams.ts @@ -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, []); }; diff --git a/app/vmui/packages/vmui/src/utils/time.ts b/app/vmui/packages/vmui/src/utils/time.ts index b6c13713ab..c6d40ab3c5 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<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,