mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
vmui: make the step input field global across all the tabs and views (#3644)
* feat: make the step input field global * fix: correct get step from url * fix: set minimumSignificantDigits to 1 * app/vmselect/vmui: `make vmui-update` Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com>
This commit is contained in:
parent
cdb6d651e9
commit
04c408e986
23 changed files with 220 additions and 126 deletions
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"files": {
|
||||
"main.css": "./static/css/main.7672c15c.css",
|
||||
"main.js": "./static/js/main.84759f8d.js",
|
||||
"main.css": "./static/css/main.01144815.css",
|
||||
"main.js": "./static/js/main.f9c0c050.js",
|
||||
"static/js/27.c1ccfd29.chunk.js": "./static/js/27.c1ccfd29.chunk.js",
|
||||
"index.html": "./index.html"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/css/main.7672c15c.css",
|
||||
"static/js/main.84759f8d.js"
|
||||
"static/css/main.01144815.css",
|
||||
"static/js/main.f9c0c050.js"
|
||||
]
|
||||
}
|
|
@ -1 +1 @@
|
|||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="VM-UI is a metric explorer for Victoria Metrics"/><link rel="apple-touch-icon" href="./apple-touch-icon.png"/><link rel="icon" type="image/png" sizes="32x32" href="./favicon-32x32.png"><link rel="manifest" href="./manifest.json"/><title>VM UI</title><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono&family=Lato:wght@300;400;700&display=swap" rel="stylesheet"><script src="./dashboards/index.js" type="module"></script><script defer="defer" src="./static/js/main.84759f8d.js"></script><link href="./static/css/main.7672c15c.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="VM-UI is a metric explorer for Victoria Metrics"/><link rel="apple-touch-icon" href="./apple-touch-icon.png"/><link rel="icon" type="image/png" sizes="32x32" href="./favicon-32x32.png"><link rel="manifest" href="./manifest.json"/><title>VM UI</title><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono&family=Lato:wght@300;400;700&display=swap" rel="stylesheet"><script src="./dashboards/index.js" type="module"></script><script defer="defer" src="./static/js/main.f9c0c050.js"></script><link href="./static/css/main.01144815.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
1
app/vmselect/vmui/static/css/main.01144815.css
Normal file
1
app/vmselect/vmui/static/css/main.01144815.css
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
app/vmselect/vmui/static/js/main.f9c0c050.js
Normal file
2
app/vmselect/vmui/static/js/main.f9c0c050.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -17,6 +17,17 @@
|
|||
* @license MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* React Router DOM v6.4.5
|
||||
*
|
||||
* Copyright (c) Remix Software Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE.md file in the root directory of this source tree.
|
||||
*
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* React Router v6.4.5
|
||||
*
|
|
@ -1,20 +1,13 @@
|
|||
import React, { FC, useEffect } from "preact/compat";
|
||||
import StepConfigurator from "../StepConfigurator/StepConfigurator";
|
||||
import { useGraphDispatch, useGraphState } from "../../../state/graph/GraphStateContext";
|
||||
import React, { FC } from "preact/compat";
|
||||
import { getAppModeParams } from "../../../utils/app-mode";
|
||||
import TenantsConfiguration from "../TenantsConfiguration/TenantsConfiguration";
|
||||
import { useCustomPanelDispatch, useCustomPanelState } from "../../../state/customPanel/CustomPanelStateContext";
|
||||
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();
|
||||
|
@ -23,9 +16,6 @@ const AdditionalSettings: FC = () => {
|
|||
const { nocache, isTracingEnabled } = useCustomPanelState();
|
||||
const customPanelDispatch = useCustomPanelDispatch();
|
||||
|
||||
const { period: { step }, duration } = useTimeState();
|
||||
const prevDuration = usePrevious(duration);
|
||||
|
||||
const onChangeCache = () => {
|
||||
customPanelDispatch({ type: "TOGGLE_NO_CACHE" });
|
||||
};
|
||||
|
@ -38,19 +28,6 @@ const AdditionalSettings: FC = () => {
|
|||
queryDispatch({ type: "TOGGLE_AUTOCOMPLETE" });
|
||||
};
|
||||
|
||||
const onChangeStep = (value: string) => {
|
||||
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"}
|
||||
|
@ -67,13 +44,6 @@ const AdditionalSettings: FC = () => {
|
|||
value={isTracingEnabled}
|
||||
onChange={onChangeQueryTracing}
|
||||
/>
|
||||
<div className="vm-additional-settings__input">
|
||||
<StepConfigurator
|
||||
defaultStep={step}
|
||||
setStep={onChangeStep}
|
||||
value={customStep}
|
||||
/>
|
||||
</div>
|
||||
{!!inputTenantID && (
|
||||
<div className="vm-additional-settings__input">
|
||||
<TenantsConfiguration/>
|
||||
|
|
|
@ -1,26 +1,59 @@
|
|||
import React, { FC, useEffect, useState } from "preact/compat";
|
||||
import { RestartIcon } from "../../Main/Icons";
|
||||
import React, { FC, useEffect, useRef, useState } from "preact/compat";
|
||||
import { RestartIcon, TimelineIcon } from "../../Main/Icons";
|
||||
import TextField from "../../Main/TextField/TextField";
|
||||
import Button from "../../Main/Button/Button";
|
||||
import Tooltip from "../../Main/Tooltip/Tooltip";
|
||||
import { ErrorTypes } from "../../../types";
|
||||
import { supportedDurations } from "../../../utils/time";
|
||||
import { useTimeState } from "../../../state/time/TimeStateContext";
|
||||
import { useGraphDispatch, useGraphState } from "../../../state/graph/GraphStateContext";
|
||||
import usePrevious from "../../../hooks/usePrevious";
|
||||
import "./style.scss";
|
||||
import { getAppModeEnable } from "../../../utils/app-mode";
|
||||
import Popper from "../../Main/Popper/Popper";
|
||||
|
||||
interface StepConfiguratorProps {
|
||||
defaultStep?: string,
|
||||
value?: string,
|
||||
setStep: (step: string) => void,
|
||||
}
|
||||
const StepConfigurator: FC = () => {
|
||||
const appModeEnable = getAppModeEnable();
|
||||
|
||||
const StepConfigurator: FC<StepConfiguratorProps> = ({ value, defaultStep, setStep }) => {
|
||||
const { customStep: value } = useGraphState();
|
||||
const { period: { step: defaultStep } } = useTimeState();
|
||||
const graphDispatch = useGraphDispatch();
|
||||
|
||||
const { period: duration } = useTimeState();
|
||||
const prevDuration = usePrevious(duration.end - duration.start);
|
||||
|
||||
const [openOptions, setOpenOptions] = useState(false);
|
||||
const [customStep, setCustomStep] = useState(value || defaultStep);
|
||||
const [error, setError] = useState("");
|
||||
|
||||
const buttonRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const toggleOpenOptions = () => {
|
||||
setOpenOptions(prev => !prev);
|
||||
};
|
||||
|
||||
const handleCloseOptions = () => {
|
||||
setOpenOptions(false);
|
||||
};
|
||||
|
||||
const handleApply = (value?: string) => {
|
||||
const step = value || customStep || defaultStep || "1s";
|
||||
const durations = step.match(/[a-zA-Z]+/g) || [];
|
||||
setStep(!durations.length ? `${step}s` : step);
|
||||
const stepDur = !durations.length ? `${step}s` : step;
|
||||
graphDispatch({ type: "SET_CUSTOM_STEP", payload: stepDur });
|
||||
setCustomStep(stepDur);
|
||||
setError("");
|
||||
};
|
||||
|
||||
const handleFocus = () => {
|
||||
if (document.activeElement instanceof HTMLInputElement) {
|
||||
document.activeElement.select();
|
||||
}
|
||||
};
|
||||
|
||||
const handleEnter = () => {
|
||||
handleApply();
|
||||
handleCloseOptions();
|
||||
};
|
||||
|
||||
const handleChangeStep = (value: string) => {
|
||||
|
@ -46,28 +79,94 @@ const StepConfigurator: FC<StepConfiguratorProps> = ({ value, defaultStep, setSt
|
|||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (value) handleChangeStep(value);
|
||||
if (value) {
|
||||
handleApply(value);
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!value && defaultStep) {
|
||||
handleApply(defaultStep);
|
||||
}
|
||||
}, [defaultStep]);
|
||||
|
||||
useEffect(() => {
|
||||
const dur = duration.end - duration.start;
|
||||
if (dur === prevDuration || !prevDuration) return;
|
||||
if (defaultStep) {
|
||||
handleApply(defaultStep);
|
||||
}
|
||||
}, [duration, prevDuration, defaultStep]);
|
||||
|
||||
return (
|
||||
<TextField
|
||||
label="Step value"
|
||||
value={customStep}
|
||||
error={error}
|
||||
onChange={handleChangeStep}
|
||||
onEnter={handleApply}
|
||||
onBlur={handleApply}
|
||||
endIcon={(
|
||||
<Tooltip title="Reset step to default">
|
||||
<Button
|
||||
variant={"text"}
|
||||
size={"small"}
|
||||
startIcon={<RestartIcon/>}
|
||||
onClick={handleReset}
|
||||
<div
|
||||
className="vm-step-control"
|
||||
ref={buttonRef}
|
||||
>
|
||||
<Tooltip title="Query resolution step width">
|
||||
<Button
|
||||
className={appModeEnable ? "" : "vm-header-button"}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<TimelineIcon/>}
|
||||
onClick={toggleOpenOptions}
|
||||
>
|
||||
STEP {customStep}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Popper
|
||||
open={openOptions}
|
||||
placement="bottom-right"
|
||||
onClose={handleCloseOptions}
|
||||
buttonRef={buttonRef}
|
||||
>
|
||||
<div className="vm-step-control-popper">
|
||||
<TextField
|
||||
autofocus
|
||||
label="Step value"
|
||||
value={customStep}
|
||||
error={error}
|
||||
onChange={handleChangeStep}
|
||||
onEnter={handleEnter}
|
||||
onFocus={handleFocus}
|
||||
onBlur={handleApply}
|
||||
endIcon={(
|
||||
<Tooltip title={`Set default step value: ${defaultStep}`}>
|
||||
<Button
|
||||
size="small"
|
||||
variant="text"
|
||||
color="primary"
|
||||
startIcon={<RestartIcon/>}
|
||||
onClick={handleReset}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
/>
|
||||
<div className="vm-step-control-popper-info">
|
||||
<code>step</code> - the <a
|
||||
className="vm-link vm-link_colored"
|
||||
href="https://prometheus.io/docs/prometheus/latest/querying/basics/#time-durations"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
interval
|
||||
</a>
|
||||
between datapoints, which must be returned from the range query.
|
||||
The <code>query</code> is executed at
|
||||
<code>start</code>, <code>start+step</code>, <code>start+2*step</code>, …, <code>end</code> timestamps.
|
||||
<a
|
||||
className="vm-link vm-link_colored"
|
||||
href="https://docs.victoriametrics.com/keyConcepts.html#range-query"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Read more about Range query
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</Popper>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
@use "src/styles/variables" as *;
|
||||
@use "src/components/Main/Button/style" as *;
|
||||
|
||||
.vm-step-control {
|
||||
display: inline-flex;
|
||||
|
||||
button {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
&-popper {
|
||||
display: grid;
|
||||
gap: $padding-small;
|
||||
max-width: 300px;
|
||||
max-height: 208px;
|
||||
overflow: auto;
|
||||
padding: $padding-global;
|
||||
font-size: $font-size;
|
||||
|
||||
&-info {
|
||||
font-size: $font-size-small;
|
||||
line-height: 1.6;
|
||||
|
||||
a {
|
||||
margin: 0 0.2em;
|
||||
}
|
||||
|
||||
code {
|
||||
padding: 0.2em 0.4em;
|
||||
margin: 0 0.2em;
|
||||
font-size: 85%;
|
||||
background-color: rgba($color-black, 0.05);
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,6 @@
|
|||
import React, { FC, useEffect, useMemo } from "preact/compat";
|
||||
import React, { FC, useMemo } from "preact/compat";
|
||||
import Select from "../../Main/Select/Select";
|
||||
import StepConfigurator from "../../Configurators/StepConfigurator/StepConfigurator";
|
||||
import "./style.scss";
|
||||
import { useTimeState } from "../../../state/time/TimeStateContext";
|
||||
import { useGraphDispatch, useGraphState } from "../../../state/graph/GraphStateContext";
|
||||
import usePrevious from "../../../hooks/usePrevious";
|
||||
import { GRAPH_SIZES } from "../../../constants/graph";
|
||||
|
||||
interface ExploreMetricsHeaderProps {
|
||||
|
@ -36,28 +32,9 @@ const ExploreMetricsHeader: FC<ExploreMetricsHeaderProps> = ({
|
|||
onToggleMetric,
|
||||
onChangeSize
|
||||
}) => {
|
||||
|
||||
const { period: { step }, duration } = useTimeState();
|
||||
const { customStep } = useGraphState();
|
||||
const graphDispatch = useGraphDispatch();
|
||||
const prevDuration = usePrevious(duration);
|
||||
|
||||
const noInstanceText = useMemo(() => job ? "" : "No instances. Please select job", [job]);
|
||||
const noMetricsText = useMemo(() => job ? "" : "No metric names. Please select job", [job]);
|
||||
|
||||
const handleChangeStep = (value: string) => {
|
||||
graphDispatch({ type: "SET_CUSTOM_STEP", payload: value });
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (duration === prevDuration || !prevDuration) return;
|
||||
if (customStep) handleChangeStep(step || "1s");
|
||||
}, [duration, prevDuration]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!customStep && step) handleChangeStep(step);
|
||||
}, [step]);
|
||||
|
||||
return (
|
||||
<div className="vm-explore-metrics-header vm-block">
|
||||
<div className="vm-explore-metrics-header__job">
|
||||
|
@ -81,13 +58,6 @@ const ExploreMetricsHeader: FC<ExploreMetricsHeaderProps> = ({
|
|||
clearable
|
||||
/>
|
||||
</div>
|
||||
<div className="vm-explore-metrics-header__step">
|
||||
<StepConfigurator
|
||||
defaultStep={step}
|
||||
setStep={handleChangeStep}
|
||||
value={customStep}
|
||||
/>
|
||||
</div>
|
||||
<div className="vm-explore-metrics-header__size">
|
||||
<Select
|
||||
label="Size graphs"
|
||||
|
|
|
@ -8,7 +8,7 @@ const Footer: FC = () => {
|
|||
|
||||
return <footer className="vm-footer">
|
||||
<a
|
||||
className="vm__link vm-footer__website"
|
||||
className="vm-link vm-footer__website"
|
||||
target="_blank"
|
||||
href="https://victoriametrics.com/"
|
||||
rel="noreferrer"
|
||||
|
@ -17,7 +17,7 @@ const Footer: FC = () => {
|
|||
victoriametrics.com
|
||||
</a>
|
||||
<a
|
||||
className="vm__link"
|
||||
className="vm-link"
|
||||
target="_blank"
|
||||
href="https://github.com/VictoriaMetrics/VictoriaMetrics/issues/new/choose"
|
||||
rel="noreferrer"
|
||||
|
|
|
@ -15,6 +15,7 @@ import Tabs from "../../Main/Tabs/Tabs";
|
|||
import "./style.scss";
|
||||
import classNames from "classnames";
|
||||
import { useDashboardsState } from "../../../state/dashboards/DashboardsStateContext";
|
||||
import StepConfigurator from "../../Configurators/StepConfigurator/StepConfigurator";
|
||||
|
||||
const Header: FC = () => {
|
||||
const primaryColor = getCssVariable("color-primary");
|
||||
|
@ -101,6 +102,7 @@ const Header: FC = () => {
|
|||
/>
|
||||
</div>
|
||||
<div className="vm-header__settings">
|
||||
{headerSetup?.stepControl && <StepConfigurator/>}
|
||||
{headerSetup?.timeSelector && <TimeSelector/>}
|
||||
{headerSetup?.cardinalityDatePicker && <CardinalityDatePicker/>}
|
||||
{headerSetup?.executionControls && <ExecutionControls/>}
|
||||
|
|
|
@ -333,3 +333,14 @@ export const ResizeIcon = () => (
|
|||
<path d="M21 11V3h-8l3.29 3.29-10 10L3 13v8h8l-3.29-3.29 10-10z"></path>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const TimelineIcon = () => (
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
d="M23 8c0 1.1-.9 2-2 2-.18 0-.35-.02-.51-.07l-3.56 3.55c.05.16.07.34.07.52 0 1.1-.9 2-2 2s-2-.9-2-2c0-.18.02-.36.07-.52l-2.55-2.55c-.16.05-.34.07-.52.07s-.36-.02-.52-.07l-4.55 4.56c.05.16.07.33.07.51 0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2c.18 0 .35.02.51.07l4.56-4.55C8.02 9.36 8 9.18 8 9c0-1.1.9-2 2-2s2 .9 2 2c0 .18-.02.36-.07.52l2.55 2.55c.16-.05.34-.07.52-.07s.36.02.52.07l3.55-3.56C19.02 8.35 19 8.18 19 8c0-1.1.9-2 2-2s2 .9 2 2z"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
|
|
|
@ -2,6 +2,7 @@ import { useEffect } from "react";
|
|||
import { compactObject } from "../../../utils/object";
|
||||
import { useTimeState } from "../../../state/time/TimeStateContext";
|
||||
import { setQueryStringWithoutPageReload } from "../../../utils/query-string";
|
||||
import { useGraphState } from "../../../state/graph/GraphStateContext";
|
||||
|
||||
interface queryProps {
|
||||
job: string
|
||||
|
@ -11,13 +12,14 @@ interface queryProps {
|
|||
}
|
||||
|
||||
export const useSetQueryParams = ({ job, instance, metrics, size }: queryProps) => {
|
||||
const { duration, relativeTime, period: { date, step } } = useTimeState();
|
||||
const { duration, relativeTime, period: { date } } = useTimeState();
|
||||
const { customStep } = useGraphState();
|
||||
|
||||
const setSearchParamsFromState = () => {
|
||||
const params = compactObject({
|
||||
["g0.range_input"]: duration,
|
||||
["g0.end_input"]: date,
|
||||
["g0.step_input"]: step,
|
||||
["g0.step_input"]: customStep,
|
||||
["g0.relative_time"]: relativeTime,
|
||||
size,
|
||||
job,
|
||||
|
@ -28,6 +30,6 @@ export const useSetQueryParams = ({ job, instance, metrics, size }: queryProps)
|
|||
setQueryStringWithoutPageReload(params);
|
||||
};
|
||||
|
||||
useEffect(setSearchParamsFromState, [duration, relativeTime, date, step, job, instance, metrics, size]);
|
||||
useEffect(setSearchParamsFromState, [duration, relativeTime, date, customStep, job, instance, metrics, size]);
|
||||
useEffect(setSearchParamsFromState, []);
|
||||
};
|
||||
|
|
|
@ -4,7 +4,6 @@ import { AxisRange, YaxisState } from "../../../state/graph/reducer";
|
|||
import GraphView from "../../../components/Views/GraphView/GraphView";
|
||||
import { useFetchQuery } from "../../../hooks/useFetchQuery";
|
||||
import Spinner from "../../../components/Main/Spinner/Spinner";
|
||||
import StepConfigurator from "../../../components/Configurators/StepConfigurator/StepConfigurator";
|
||||
import GraphSettings from "../../../components/Configurators/GraphSettings/GraphSettings";
|
||||
import { marked } from "marked";
|
||||
import { useTimeDispatch, useTimeState } from "../../../state/time/TimeStateContext";
|
||||
|
@ -12,7 +11,7 @@ import { InfoIcon } from "../../../components/Main/Icons";
|
|||
import "./style.scss";
|
||||
import Alert from "../../../components/Main/Alert/Alert";
|
||||
import Tooltip from "../../../components/Main/Tooltip/Tooltip";
|
||||
import usePrevious from "../../../hooks/usePrevious";
|
||||
import { useGraphState } from "../../../state/graph/GraphStateContext";
|
||||
|
||||
export interface PredefinedPanelsProps extends PanelSettings {
|
||||
filename: string;
|
||||
|
@ -28,13 +27,12 @@ const PredefinedPanel: FC<PredefinedPanelsProps> = ({
|
|||
alias
|
||||
}) => {
|
||||
|
||||
const { period, duration } = useTimeState();
|
||||
const { period } = useTimeState();
|
||||
const { customStep } = useGraphState();
|
||||
const dispatch = useTimeDispatch();
|
||||
const prevDuration = usePrevious(duration);
|
||||
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [visible, setVisible] = useState(true);
|
||||
const [customStep, setCustomStep] = useState(period.step || "1s");
|
||||
const [yaxis, setYaxis] = useState<YaxisState>({
|
||||
limits: {
|
||||
enable: false,
|
||||
|
@ -77,11 +75,6 @@ const PredefinedPanel: FC<PredefinedPanelsProps> = ({
|
|||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (duration === prevDuration || !prevDuration) return;
|
||||
if (customStep) setCustomStep(period.step || "1s");
|
||||
}, [duration, prevDuration]);
|
||||
|
||||
if (!validExpr) return (
|
||||
<Alert variant="error">
|
||||
<code>"expr"</code> not found. Check the configuration file <b>{filename}</b>.
|
||||
|
@ -123,13 +116,6 @@ const PredefinedPanel: FC<PredefinedPanelsProps> = ({
|
|||
<h3 className="vm-predefined-panel-header__title">
|
||||
{title || ""}
|
||||
</h3>
|
||||
<div className="vm-predefined-panel-header__step">
|
||||
<StepConfigurator
|
||||
defaultStep={period.step}
|
||||
value={customStep}
|
||||
setStep={setCustomStep}
|
||||
/>
|
||||
</div>
|
||||
<GraphSettings
|
||||
yaxis={yaxis}
|
||||
setYaxisLimits={setYaxisLimits}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
&-header {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr 160px auto;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: $padding-small;
|
||||
|
|
|
@ -2,21 +2,23 @@ import { useEffect } from "react";
|
|||
import { compactObject } from "../../../utils/object";
|
||||
import { useTimeState } from "../../../state/time/TimeStateContext";
|
||||
import { setQueryStringWithoutPageReload } from "../../../utils/query-string";
|
||||
import { useGraphState } from "../../../state/graph/GraphStateContext";
|
||||
|
||||
export const useSetQueryParams = () => {
|
||||
const { duration, relativeTime, period: { date, step } } = useTimeState();
|
||||
const { duration, relativeTime, period: { date } } = useTimeState();
|
||||
const { customStep } = useGraphState();
|
||||
|
||||
const setSearchParamsFromState = () => {
|
||||
const params = compactObject({
|
||||
["g0.range_input"]: duration,
|
||||
["g0.end_input"]: date,
|
||||
["g0.step_input"]: step,
|
||||
["g0.step_input"]: customStep,
|
||||
["g0.relative_time"]: relativeTime
|
||||
});
|
||||
|
||||
setQueryStringWithoutPageReload(params);
|
||||
};
|
||||
|
||||
useEffect(setSearchParamsFromState, [duration, relativeTime, date, step]);
|
||||
useEffect(setSearchParamsFromState, [duration, relativeTime, date, customStep]);
|
||||
useEffect(setSearchParamsFromState, []);
|
||||
};
|
||||
|
|
|
@ -40,7 +40,7 @@ const Index: FC = () => {
|
|||
const getQueryStatsTitle = (key: keyof TopQueryStats) => {
|
||||
if (!data) return key;
|
||||
const value = data[key];
|
||||
if (typeof value === "number") return formatPrettyNumber(value);
|
||||
if (typeof value === "number") return formatPrettyNumber(value, 0, value);
|
||||
return value || key;
|
||||
};
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ const TracePage: FC = () => {
|
|||
{"\n"}
|
||||
In order to use tracing please refer to the doc:
|
||||
<a
|
||||
className="vm__link vm__link_colored"
|
||||
className="vm-link vm-link_colored"
|
||||
href="https://docs.victoriametrics.com/#query-tracing"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
|
|
|
@ -11,6 +11,7 @@ const router = {
|
|||
export interface RouterOptions {
|
||||
title?: string,
|
||||
header: {
|
||||
stepControl?: boolean,
|
||||
timeSelector?: boolean,
|
||||
executionControls?: boolean,
|
||||
globalSettings?: boolean,
|
||||
|
@ -20,6 +21,7 @@ export interface RouterOptions {
|
|||
|
||||
const routerOptionsDefault = {
|
||||
header: {
|
||||
stepControl: true,
|
||||
timeSelector: true,
|
||||
executionControls: true,
|
||||
}
|
||||
|
@ -33,6 +35,7 @@ export const routerOptions: {[key: string]: RouterOptions} = {
|
|||
[router.metrics]: {
|
||||
title: "Explore metrics",
|
||||
header: {
|
||||
stepControl: true,
|
||||
timeSelector: true,
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@use "src/styles/variables" as *;
|
||||
|
||||
.vm__link {
|
||||
.vm-link {
|
||||
transition: color 200ms ease;
|
||||
cursor: pointer;
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ The following tip changes can be tested by building VictoriaMetrics components f
|
|||
## tip
|
||||
|
||||
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add ability to show custom dashboards at vmui by specifying a path to a directory with dashboard config files via `-vmui.customDashboardsPath` command-line flag. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3322) and [these docs](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/app/vmui/packages/vmui/public/dashboards).
|
||||
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): apply the `step` globally to all the displayed graphs. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3574).
|
||||
|
||||
* BUGFIX: reduce the increased CPU usage at `vmselect` to v1.85.3 level when processing heavy queries. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3641).
|
||||
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): [dockerswarm_sd_configs](https://docs.victoriametrics.com/sd_configs.html#dockerswarm_sd_configs): apply `filters` only to objects of the specified `role`. Previously filters were applied to all the objects, which could cause errors when different types of objects were used with filters that were not compatible with them. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3579).
|
||||
|
|
Loading…
Reference in a new issue