mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-09 23:24:05 -08:00
Clarify explain view, add tree view close button, fix callback bug
Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
parent
7e0cd2e0b4
commit
8b4291537b
|
@ -11,32 +11,35 @@ import classes from "./ExplainView.module.css";
|
||||||
import SelectorExplainView from "./Selector";
|
import SelectorExplainView from "./Selector";
|
||||||
import AggregationExplainView from "./Aggregation";
|
import AggregationExplainView from "./Aggregation";
|
||||||
import BinaryExprExplainView from "./BinaryExpr/BinaryExpr";
|
import BinaryExprExplainView from "./BinaryExpr/BinaryExpr";
|
||||||
|
import { IconInfoCircle } from "@tabler/icons-react";
|
||||||
interface ExplainViewProps {
|
interface ExplainViewProps {
|
||||||
node: ASTNode | null;
|
node: ASTNode | null;
|
||||||
treeShown: boolean;
|
treeShown: boolean;
|
||||||
setShowTree: () => void;
|
showTree: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ExplainView: FC<ExplainViewProps> = ({
|
const ExplainView: FC<ExplainViewProps> = ({
|
||||||
node,
|
node,
|
||||||
treeShown,
|
treeShown,
|
||||||
setShowTree,
|
showTree: setShowTree,
|
||||||
}) => {
|
}) => {
|
||||||
if (node === null) {
|
if (node === null) {
|
||||||
return (
|
return (
|
||||||
<Alert>
|
<Alert title="How to use the Explain view" icon={<IconInfoCircle />}>
|
||||||
<>
|
This tab can help you understand the behavior of individual components
|
||||||
To use the Explain view,{" "}
|
of a query.
|
||||||
{!treeShown && (
|
<br />
|
||||||
<>
|
<br />
|
||||||
<Anchor fz="unset" onClick={setShowTree}>
|
To use the Explain view,{" "}
|
||||||
enable the query tree view
|
{!treeShown && (
|
||||||
</Anchor>{" "}
|
<>
|
||||||
(also available via the expression input dropdown) and then
|
<Anchor fz="unset" onClick={setShowTree}>
|
||||||
</>
|
enable the query tree view
|
||||||
)}{" "}
|
</Anchor>{" "}
|
||||||
select a node in the tree above.
|
(also available via the expression input menu) and then
|
||||||
</>
|
</>
|
||||||
|
)}{" "}
|
||||||
|
select a node in the tree above.
|
||||||
</Alert>
|
</Alert>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,16 +6,13 @@ import {
|
||||||
Box,
|
Box,
|
||||||
SegmentedControl,
|
SegmentedControl,
|
||||||
Stack,
|
Stack,
|
||||||
Button,
|
|
||||||
Skeleton,
|
Skeleton,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import {
|
import {
|
||||||
IconChartAreaFilled,
|
IconChartAreaFilled,
|
||||||
IconChartLine,
|
IconChartLine,
|
||||||
IconCheckbox,
|
|
||||||
IconGraph,
|
IconGraph,
|
||||||
IconInfoCircle,
|
IconInfoCircle,
|
||||||
IconSquare,
|
|
||||||
IconTable,
|
IconTable,
|
||||||
} from "@tabler/icons-react";
|
} from "@tabler/icons-react";
|
||||||
import { FC, Suspense, useCallback, useMemo, useState } from "react";
|
import { FC, Suspense, useCallback, useMemo, useState } from "react";
|
||||||
|
@ -129,6 +126,10 @@ const QueryPanel: FC<PanelProps> = ({ idx, metricNames }) => {
|
||||||
retriggerIdx={retriggerIdx}
|
retriggerIdx={retriggerIdx}
|
||||||
selectedNode={selectedNode}
|
selectedNode={selectedNode}
|
||||||
setSelectedNode={setSelectedNode}
|
setSelectedNode={setSelectedNode}
|
||||||
|
closeTreeView={() => {
|
||||||
|
dispatch(setShowTree({ idx, showTree: false }));
|
||||||
|
setSelectedNode(null);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
|
@ -165,11 +166,7 @@ const QueryPanel: FC<PanelProps> = ({ idx, metricNames }) => {
|
||||||
<Tabs.Panel pt="sm" value="table">
|
<Tabs.Panel pt="sm" value="table">
|
||||||
<TableTab expr={expr} panelIdx={idx} retriggerIdx={retriggerIdx} />
|
<TableTab expr={expr} panelIdx={idx} retriggerIdx={retriggerIdx} />
|
||||||
</Tabs.Panel>
|
</Tabs.Panel>
|
||||||
<Tabs.Panel
|
<Tabs.Panel pt="sm" value="graph">
|
||||||
pt="sm"
|
|
||||||
value="graph"
|
|
||||||
// style={{ border: "1px solid lightgrey", borderTop: "none" }}
|
|
||||||
>
|
|
||||||
<Group mt="xs" justify="space-between">
|
<Group mt="xs" justify="space-between">
|
||||||
<Group>
|
<Group>
|
||||||
<RangeInput
|
<RangeInput
|
||||||
|
@ -214,7 +211,7 @@ const QueryPanel: FC<PanelProps> = ({ idx, metricNames }) => {
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<Group gap="lg">
|
<Group gap="lg">
|
||||||
<Button
|
{/* <Button
|
||||||
variant="subtle"
|
variant="subtle"
|
||||||
color="gray.9"
|
color="gray.9"
|
||||||
size="xs"
|
size="xs"
|
||||||
|
@ -249,7 +246,7 @@ const QueryPanel: FC<PanelProps> = ({ idx, metricNames }) => {
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Show exemplars
|
Show exemplars
|
||||||
</Button>
|
</Button> */}
|
||||||
|
|
||||||
<SegmentedControl
|
<SegmentedControl
|
||||||
onChange={(value) =>
|
onChange={(value) =>
|
||||||
|
@ -325,7 +322,7 @@ const QueryPanel: FC<PanelProps> = ({ idx, metricNames }) => {
|
||||||
<ExplainView
|
<ExplainView
|
||||||
node={selectedNode?.node ?? null}
|
node={selectedNode?.node ?? null}
|
||||||
treeShown={panel.showTree}
|
treeShown={panel.showTree}
|
||||||
setShowTree={() => {
|
showTree={() => {
|
||||||
dispatch(setShowTree({ idx, showTree: true }));
|
dispatch(setShowTree({ idx, showTree: true }));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import {
|
import {
|
||||||
FC,
|
FC,
|
||||||
|
useCallback,
|
||||||
useEffect,
|
useEffect,
|
||||||
useLayoutEffect,
|
useLayoutEffect,
|
||||||
useMemo,
|
useMemo,
|
||||||
|
@ -57,8 +58,10 @@ const TreeNode: FC<{
|
||||||
selectedNode: { id: string; node: ASTNode } | null;
|
selectedNode: { id: string; node: ASTNode } | null;
|
||||||
setSelectedNode: (Node: { id: string; node: ASTNode } | null) => void;
|
setSelectedNode: (Node: { id: string; node: ASTNode } | null) => void;
|
||||||
parentRef?: React.RefObject<HTMLDivElement>;
|
parentRef?: React.RefObject<HTMLDivElement>;
|
||||||
reportNodeState?: (state: NodeState) => void;
|
reportNodeState?: (childIdx: number, state: NodeState) => void;
|
||||||
reverse: boolean;
|
reverse: boolean;
|
||||||
|
// The index of this node in its parent's children.
|
||||||
|
childIdx: number;
|
||||||
}> = ({
|
}> = ({
|
||||||
node,
|
node,
|
||||||
selectedNode,
|
selectedNode,
|
||||||
|
@ -66,6 +69,7 @@ const TreeNode: FC<{
|
||||||
parentRef,
|
parentRef,
|
||||||
reportNodeState,
|
reportNodeState,
|
||||||
reverse,
|
reverse,
|
||||||
|
childIdx,
|
||||||
}) => {
|
}) => {
|
||||||
const nodeID = useId();
|
const nodeID = useId();
|
||||||
const nodeRef = useRef<HTMLDivElement>(null);
|
const nodeRef = useRef<HTMLDivElement>(null);
|
||||||
|
@ -130,21 +134,32 @@ const TreeNode: FC<{
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (mergedChildState === "error") {
|
if (mergedChildState === "error") {
|
||||||
reportNodeState && reportNodeState("error");
|
reportNodeState && reportNodeState(childIdx, "error");
|
||||||
}
|
}
|
||||||
}, [mergedChildState, reportNodeState]);
|
}, [mergedChildState, reportNodeState, childIdx]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (error) {
|
if (error) {
|
||||||
reportNodeState && reportNodeState("error");
|
reportNodeState && reportNodeState(childIdx, "error");
|
||||||
}
|
}
|
||||||
}, [error, reportNodeState]);
|
}, [error, reportNodeState, childIdx]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isFetching) {
|
if (isFetching) {
|
||||||
reportNodeState && reportNodeState("running");
|
reportNodeState && reportNodeState(childIdx, "running");
|
||||||
}
|
}
|
||||||
}, [isFetching, reportNodeState]);
|
}, [isFetching, reportNodeState, childIdx]);
|
||||||
|
|
||||||
|
const childReportNodeState = useCallback(
|
||||||
|
(childIdx: number, state: NodeState) => {
|
||||||
|
setChildStates((prev) => {
|
||||||
|
const newStates = [...prev];
|
||||||
|
newStates[childIdx] = state;
|
||||||
|
return newStates;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[setChildStates]
|
||||||
|
);
|
||||||
|
|
||||||
// Update the size and position of tree connector lines based on the node's and its parent's position.
|
// Update the size and position of tree connector lines based on the node's and its parent's position.
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
|
@ -185,7 +200,7 @@ const TreeNode: FC<{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reportNodeState && reportNodeState("success");
|
reportNodeState && reportNodeState(childIdx, "success");
|
||||||
|
|
||||||
let resultSeries = 0;
|
let resultSeries = 0;
|
||||||
const labelValuesByName: Record<string, Record<string, number>> = {};
|
const labelValuesByName: Record<string, Record<string, number>> = {};
|
||||||
|
@ -228,7 +243,7 @@ const TreeNode: FC<{
|
||||||
),
|
),
|
||||||
labelExamples,
|
labelExamples,
|
||||||
});
|
});
|
||||||
}, [data, reportNodeState]);
|
}, [data, reportNodeState, childIdx]);
|
||||||
|
|
||||||
const innerNode = (
|
const innerNode = (
|
||||||
<Group
|
<Group
|
||||||
|
@ -367,13 +382,8 @@ const TreeNode: FC<{
|
||||||
setSelectedNode={setSelectedNode}
|
setSelectedNode={setSelectedNode}
|
||||||
parentRef={nodeRef}
|
parentRef={nodeRef}
|
||||||
reverse={true}
|
reverse={true}
|
||||||
reportNodeState={(state: NodeState) => {
|
childIdx={0}
|
||||||
setChildStates((prev) => {
|
reportNodeState={childReportNodeState}
|
||||||
const newStates = [...prev];
|
|
||||||
newStates[0] = state;
|
|
||||||
return newStates;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
{innerNode}
|
{innerNode}
|
||||||
|
@ -384,13 +394,8 @@ const TreeNode: FC<{
|
||||||
setSelectedNode={setSelectedNode}
|
setSelectedNode={setSelectedNode}
|
||||||
parentRef={nodeRef}
|
parentRef={nodeRef}
|
||||||
reverse={false}
|
reverse={false}
|
||||||
reportNodeState={(state: NodeState) => {
|
childIdx={1}
|
||||||
setChildStates((prev) => {
|
reportNodeState={childReportNodeState}
|
||||||
const newStates = [...prev];
|
|
||||||
newStates[1] = state;
|
|
||||||
return newStates;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</div>
|
</div>
|
||||||
|
@ -407,13 +412,8 @@ const TreeNode: FC<{
|
||||||
setSelectedNode={setSelectedNode}
|
setSelectedNode={setSelectedNode}
|
||||||
parentRef={nodeRef}
|
parentRef={nodeRef}
|
||||||
reverse={false}
|
reverse={false}
|
||||||
reportNodeState={(state: NodeState) => {
|
childIdx={idx}
|
||||||
setChildStates((prev) => {
|
reportNodeState={childReportNodeState}
|
||||||
const newStates = [...prev];
|
|
||||||
newStates[idx] = state;
|
|
||||||
return newStates;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
))}
|
))}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { useSuspenseAPIQuery } from "../../api/api";
|
||||||
import { useAppSelector } from "../../state/hooks";
|
import { useAppSelector } from "../../state/hooks";
|
||||||
import ASTNode from "../../promql/ast";
|
import ASTNode from "../../promql/ast";
|
||||||
import TreeNode from "./TreeNode";
|
import TreeNode from "./TreeNode";
|
||||||
import { Card } from "@mantine/core";
|
import { Card, CloseButton } from "@mantine/core";
|
||||||
|
|
||||||
const TreeView: FC<{
|
const TreeView: FC<{
|
||||||
panelIdx: number;
|
panelIdx: number;
|
||||||
|
@ -19,7 +19,8 @@ const TreeView: FC<{
|
||||||
node: ASTNode;
|
node: ASTNode;
|
||||||
} | null
|
} | null
|
||||||
) => void;
|
) => void;
|
||||||
}> = ({ panelIdx, selectedNode, setSelectedNode }) => {
|
closeTreeView: () => void;
|
||||||
|
}> = ({ panelIdx, selectedNode, setSelectedNode, closeTreeView }) => {
|
||||||
const { expr } = useAppSelector((state) => state.queryPage.panels[panelIdx]);
|
const { expr } = useAppSelector((state) => state.queryPage.panels[panelIdx]);
|
||||||
|
|
||||||
const { data } = useSuspenseAPIQuery<ASTNode>({
|
const { data } = useSuspenseAPIQuery<ASTNode>({
|
||||||
|
@ -32,7 +33,17 @@ const TreeView: FC<{
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card withBorder fz="sm" style={{ overflowX: "auto" }} pl="sm">
|
<Card withBorder fz="sm" style={{ overflowX: "auto" }} pl="sm">
|
||||||
|
<CloseButton
|
||||||
|
aria-label="Close tree view"
|
||||||
|
title="Close tree view"
|
||||||
|
pos="absolute"
|
||||||
|
top={7}
|
||||||
|
size="sm"
|
||||||
|
right={7}
|
||||||
|
onClick={closeTreeView}
|
||||||
|
/>
|
||||||
<TreeNode
|
<TreeNode
|
||||||
|
childIdx={0}
|
||||||
node={data.data}
|
node={data.data}
|
||||||
selectedNode={selectedNode}
|
selectedNode={selectedNode}
|
||||||
setSelectedNode={setSelectedNode}
|
setSelectedNode={setSelectedNode}
|
||||||
|
|
Loading…
Reference in a new issue