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:
Julius Volz 2024-07-23 23:13:06 +02:00
parent a2a177a04c
commit f7a97417a5

View file

@ -6,8 +6,6 @@ import {
Box,
SegmentedControl,
Stack,
Select,
TextInput,
} from "@mantine/core";
import {
IconChartAreaFilled,
@ -21,7 +19,6 @@ import { useAppDispatch, useAppSelector } from "../../state/hooks";
import {
GraphDisplayMode,
GraphResolution,
getEffectiveResolution,
removePanel,
setExpr,
setVisualizer,
@ -31,10 +28,7 @@ import TimeInput from "./TimeInput";
import RangeInput from "./RangeInput";
import ExpressionInput from "./ExpressionInput";
import Graph from "./Graph";
import {
formatPrometheusDuration,
parsePrometheusDuration,
} from "../../lib/formatTime";
import ResolutionInput from "./ResolutionInput";
export interface PanelProps {
idx: number;
@ -51,40 +45,8 @@ const QueryPanel: FC<PanelProps> = ({ idx, metricNames }) => {
const [retriggerIdx, setRetriggerIdx] = useState<number>(0);
const panel = useAppSelector((state) => state.queryPage.panels[idx]);
const resolution = panel.visualizer.resolution;
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 (
<Stack gap="lg">
<ExpressionInput
@ -174,101 +136,21 @@ const QueryPanel: FC<PanelProps> = ({ idx, metricNames }) => {
)
}
/>
<Select
title="Resolution"
placeholder="Resolution"
maxDropdownHeight={500}
data={[
{
group: "Automatic resolution",
items: [
{ label: "Low res.", value: "low" },
{ label: "Medium res.", value: "medium" },
{ label: "High res.", value: "high" },
],
<ResolutionInput
resolution={panel.visualizer.resolution}
range={panel.visualizer.range}
onChangeResolution={(res: GraphResolution) => {
dispatch(
setVisualizer({
idx,
visualizer: {
...panel.visualizer,
resolution: res,
},
{
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>
<SegmentedControl