mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
Move resolution input into separate component + file
Also don't reload the graph on custom resolution input blur if the resolution hasn't changed. Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
parent
a2a177a04c
commit
f7a97417a5
|
@ -6,8 +6,6 @@ import {
|
||||||
Box,
|
Box,
|
||||||
SegmentedControl,
|
SegmentedControl,
|
||||||
Stack,
|
Stack,
|
||||||
Select,
|
|
||||||
TextInput,
|
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import {
|
import {
|
||||||
IconChartAreaFilled,
|
IconChartAreaFilled,
|
||||||
|
@ -21,7 +19,6 @@ import { useAppDispatch, useAppSelector } from "../../state/hooks";
|
||||||
import {
|
import {
|
||||||
GraphDisplayMode,
|
GraphDisplayMode,
|
||||||
GraphResolution,
|
GraphResolution,
|
||||||
getEffectiveResolution,
|
|
||||||
removePanel,
|
removePanel,
|
||||||
setExpr,
|
setExpr,
|
||||||
setVisualizer,
|
setVisualizer,
|
||||||
|
@ -31,10 +28,7 @@ import TimeInput from "./TimeInput";
|
||||||
import RangeInput from "./RangeInput";
|
import RangeInput from "./RangeInput";
|
||||||
import ExpressionInput from "./ExpressionInput";
|
import ExpressionInput from "./ExpressionInput";
|
||||||
import Graph from "./Graph";
|
import Graph from "./Graph";
|
||||||
import {
|
import ResolutionInput from "./ResolutionInput";
|
||||||
formatPrometheusDuration,
|
|
||||||
parsePrometheusDuration,
|
|
||||||
} from "../../lib/formatTime";
|
|
||||||
|
|
||||||
export interface PanelProps {
|
export interface PanelProps {
|
||||||
idx: number;
|
idx: number;
|
||||||
|
@ -51,40 +45,8 @@ const QueryPanel: FC<PanelProps> = ({ idx, metricNames }) => {
|
||||||
const [retriggerIdx, setRetriggerIdx] = useState<number>(0);
|
const [retriggerIdx, setRetriggerIdx] = useState<number>(0);
|
||||||
|
|
||||||
const panel = useAppSelector((state) => state.queryPage.panels[idx]);
|
const panel = useAppSelector((state) => state.queryPage.panels[idx]);
|
||||||
const resolution = panel.visualizer.resolution;
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const [customResolutionInput, setCustomResolutionInput] = useState<string>(
|
|
||||||
formatPrometheusDuration(
|
|
||||||
getEffectiveResolution(resolution, panel.visualizer.range)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const setResolution = (res: GraphResolution) => {
|
|
||||||
dispatch(
|
|
||||||
setVisualizer({
|
|
||||||
idx,
|
|
||||||
visualizer: {
|
|
||||||
...panel.visualizer,
|
|
||||||
resolution: res,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onChangeCustomResolutionInput = (resText: string): void => {
|
|
||||||
const newResolution = parsePrometheusDuration(resText);
|
|
||||||
if (newResolution === null) {
|
|
||||||
setCustomResolutionInput(
|
|
||||||
formatPrometheusDuration(
|
|
||||||
getEffectiveResolution(resolution, panel.visualizer.range)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
setResolution({ type: "custom", value: newResolution });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack gap="lg">
|
<Stack gap="lg">
|
||||||
<ExpressionInput
|
<ExpressionInput
|
||||||
|
@ -174,101 +136,21 @@ const QueryPanel: FC<PanelProps> = ({ idx, metricNames }) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<ResolutionInput
|
||||||
<Select
|
resolution={panel.visualizer.resolution}
|
||||||
title="Resolution"
|
range={panel.visualizer.range}
|
||||||
placeholder="Resolution"
|
onChangeResolution={(res: GraphResolution) => {
|
||||||
maxDropdownHeight={500}
|
dispatch(
|
||||||
data={[
|
setVisualizer({
|
||||||
{
|
idx,
|
||||||
group: "Automatic resolution",
|
visualizer: {
|
||||||
items: [
|
...panel.visualizer,
|
||||||
{ label: "Low res.", value: "low" },
|
resolution: res,
|
||||||
{ label: "Medium res.", value: "medium" },
|
},
|
||||||
{ label: "High res.", value: "high" },
|
})
|
||||||
],
|
);
|
||||||
},
|
|
||||||
{
|
|
||||||
group: "Fixed resolution",
|
|
||||||
items: [
|
|
||||||
{ label: "10s", value: "10000" },
|
|
||||||
{ label: "30s", value: "30000" },
|
|
||||||
{ label: "1m", value: "60000" },
|
|
||||||
{ label: "5m", value: "300000" },
|
|
||||||
{ label: "15m", value: "900000" },
|
|
||||||
{ label: "1h", value: "3600000" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
group: "Custom resolution",
|
|
||||||
items: [{ label: "Enter value...", value: "custom" }],
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
w={160}
|
|
||||||
value={
|
|
||||||
resolution.type === "auto"
|
|
||||||
? resolution.density
|
|
||||||
: resolution.type === "fixed"
|
|
||||||
? resolution.value.toString()
|
|
||||||
: "custom"
|
|
||||||
}
|
|
||||||
onChange={(_value, option) => {
|
|
||||||
if (["low", "medium", "high"].includes(option.value)) {
|
|
||||||
setResolution({
|
|
||||||
type: "auto",
|
|
||||||
density: option.value as "low" | "medium" | "high",
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (option.value === "custom") {
|
|
||||||
// Start the custom resolution at the current effective resolution.
|
|
||||||
const effectiveResolution = getEffectiveResolution(
|
|
||||||
resolution,
|
|
||||||
panel.visualizer.range
|
|
||||||
);
|
|
||||||
setResolution({
|
|
||||||
type: "custom",
|
|
||||||
value: effectiveResolution,
|
|
||||||
});
|
|
||||||
setCustomResolutionInput(
|
|
||||||
formatPrometheusDuration(effectiveResolution)
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const value = parseInt(option.value);
|
|
||||||
if (!isNaN(value)) {
|
|
||||||
setResolution({
|
|
||||||
type: "fixed",
|
|
||||||
value,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
throw new Error("Invalid resolution value");
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{resolution.type === "custom" && (
|
|
||||||
<TextInput
|
|
||||||
placeholder="Resolution"
|
|
||||||
value={customResolutionInput}
|
|
||||||
onChange={(event) =>
|
|
||||||
setCustomResolutionInput(event.currentTarget.value)
|
|
||||||
}
|
|
||||||
onBlur={() =>
|
|
||||||
onChangeCustomResolutionInput(customResolutionInput)
|
|
||||||
}
|
|
||||||
onKeyDown={(event) =>
|
|
||||||
event.key === "Enter" &&
|
|
||||||
onChangeCustomResolutionInput(customResolutionInput)
|
|
||||||
}
|
|
||||||
aria-label="Range"
|
|
||||||
style={{
|
|
||||||
width: `calc(44px + ${customResolutionInput.length + 3}ch)`,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<SegmentedControl
|
<SegmentedControl
|
||||||
|
|
Loading…
Reference in a new issue