vmui: add the ability to expand all tracing entries (#5677) (#5726)

This commit is contained in:
Yury Molodov 2024-01-30 20:10:10 +01:00 committed by GitHub
parent 300d701df0
commit 81b5db04f6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 93 additions and 9 deletions

View file

@ -14,13 +14,14 @@ interface RecursiveProps {
isRoot?: boolean;
trace: Trace;
totalMsec: number;
isExpandedAll? : boolean;
}
interface OpenLevels {
[x: number]: boolean
}
const NestedNav: FC<RecursiveProps> = ({ isRoot, trace, totalMsec }) => {
const NestedNav: FC<RecursiveProps> = ({ isRoot, trace, totalMsec, isExpandedAll }) => {
const { isDarkTheme } = useAppState();
const { isMobile } = useDeviceDetect();
const [openLevels, setOpenLevels] = useState({} as OpenLevels);
@ -53,6 +54,26 @@ const NestedNav: FC<RecursiveProps> = ({ isRoot, trace, totalMsec }) => {
});
};
const getIdsFromChildren = (tracingData: Trace) => {
const ids = [tracingData.idValue];
tracingData?.children?.forEach((child) => {
ids.push(...getIdsFromChildren(child));
});
return ids;
};
useEffect(() => {
if (!isExpandedAll) {
setOpenLevels([]);
return;
}
const allIds = getIdsFromChildren(trace);
const openLevels = {} as OpenLevels;
allIds.forEach(id => { openLevels[id] = true; });
setOpenLevels(openLevels);
}, [isExpandedAll]);
return (
<div
className={classNames({
@ -106,13 +127,14 @@ const NestedNav: FC<RecursiveProps> = ({ isRoot, trace, totalMsec }) => {
)}
</div>
</div>
{openLevels[trace.idValue] && (
{(openLevels[trace.idValue]) && (
<div className="vm-nested-nav__childrens">
{hasChildren && trace.children.map((trace) => (
<NestedNav
key={trace.duration}
trace={trace}
totalMsec={totalMsec}
isExpandedAll={isExpandedAll}
/>
))}
</div>

View file

@ -2,6 +2,8 @@
$color-base-nested-nav: $color-tropical-blue;
$color-base-nested-nav-dark: $color-background-body;
$width-line: 2px;
$left-position: calc(-1 * $padding-small);
.vm-nested-nav {
position: relative;
@ -48,19 +50,19 @@ $color-base-nested-nav-dark: $color-background-body;
content: "";
position: absolute;
top: calc(50% - 1px);
height: 2px;
height: $width-line;
width: $padding-small;
background-color: $color-base-nested-nav;
left: calc(-1 * $padding-small);
left: $left-position;
}
&:before {
content: "";
position: absolute;
bottom: 50%;
left: calc(-1 * $padding-small);
left: $left-position;
height: calc(50% + $padding-small);
width: 2px;
width: $width-line;
background-color: $color-base-nested-nav;
}
@ -122,9 +124,9 @@ $color-base-nested-nav-dark: $color-background-body;
content: "";
position: absolute;
top: 0;
left: calc(-1 * $padding-small);
left: $left-position;
height: 100%;
width: 2px;
width: $width-line;
background-color: $color-base-nested-nav;
}
}

View file

@ -1,7 +1,7 @@
import React, { FC, useState } from "preact/compat";
import Trace from "./Trace";
import Button from "../Main/Button/Button";
import { CodeIcon, DeleteIcon } from "../Main/Icons";
import { ArrowDownIcon, CodeIcon, DeleteIcon, DownloadIcon } from "../Main/Icons";
import "./style.scss";
import NestedNav from "./NestedNav/NestedNav";
import Alert from "../Main/Alert/Alert";
@ -20,6 +20,7 @@ interface TraceViewProps {
const TracingsView: FC<TraceViewProps> = ({ traces, jsonEditor = false, onDeleteClick }) => {
const { isMobile } = useDeviceDetect();
const [openTrace, setOpenTrace] = useState<Trace | null>(null);
const [expandedTraces, setExpandedTraces] = useState<number[]>([]);
const handleCloseJson = () => {
setOpenTrace(null);
@ -52,6 +53,27 @@ const TracingsView: FC<TraceViewProps> = ({ traces, jsonEditor = false, onDelete
setOpenTrace(tracingData);
};
const handleSaveToFile = (tracingData: Trace) => () => {
const blob = new Blob([tracingData.originalJSON], { type: "application/json" });
const href = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = href;
link.download = `vmui_trace_${tracingData.queryValue}.json`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(href);
};
const handleExpandAll = (tracingData: Trace) => () => {
setExpandedTraces(prev => prev.includes(tracingData.idValue)
? prev.filter(n => n !== tracingData.idValue)
: [...prev, tracingData.idValue]
);
};
return (
<>
<div className="vm-tracings-view">
@ -64,6 +86,28 @@ const TracingsView: FC<TraceViewProps> = ({ traces, jsonEditor = false, onDelete
<h3 className="vm-tracings-view-trace-header-title">
Trace for <b className="vm-tracings-view-trace-header-title__query">{trace.queryValue}</b>
</h3>
<Tooltip title={expandedTraces.includes(trace.idValue) ? "Collapse All" : "Expand All"}>
<Button
variant="text"
startIcon={(
<div
className={classNames({
"vm-tracings-view-trace-header__expand-icon": true,
"vm-tracings-view-trace-header__expand-icon_open": expandedTraces.includes(trace.idValue) })}
><ArrowDownIcon/></div>
)}
onClick={handleExpandAll(trace)}
ariaLabel={expandedTraces.includes(trace.idValue) ? "Collapse All" : "Expand All"}
/>
</Tooltip>
<Tooltip title={"Save Trace to JSON"}>
<Button
variant="text"
startIcon={<DownloadIcon/>}
onClick={handleSaveToFile(trace)}
ariaLabel="Save trace to JSON"
/>
</Tooltip>
<Tooltip title={"Open JSON"}>
<Button
variant="text"
@ -92,6 +136,7 @@ const TracingsView: FC<TraceViewProps> = ({ traces, jsonEditor = false, onDelete
isRoot
trace={trace}
totalMsec={trace.duration}
isExpandedAll={expandedTraces.includes(trace.idValue)}
/>
</nav>
</div>

View file

@ -21,6 +21,20 @@
font-weight: bold;
}
}
&__expand-icon {
display: flex;
align-items: center;
justify-content: center;
width: 20px;
transition: transform 200ms ease-in-out;
transform: rotate(-90deg);
color: $color-text-secondary;
&_open {
transform: rotate(0);
}
}
}
&__nav {

View file

@ -64,6 +64,7 @@ The sandbox cluster installation is running under the constant load generated by
- add an `Export query` button to the graph that saves the result of executing the query in `JSON`. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5497).
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add `-vmui.defaultTimezone` flag to set a default timezone. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5375) and [these docs](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/app/vmui#timezone-configuration).
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): include UTC in the timezone selection dropdown for standardized time referencing. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5375).
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add the ability to expand/collapse all tracing entries and download tracing data in .json format. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5677).
* FEATURE: add [VictoriaMetrics datasource](https://github.com/VictoriaMetrics/grafana-datasource) to docker compose environment. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5363).
* BUGFIX: properly return the list of matching label names and label values from [`/api/v1/labels`](https://docs.victoriametrics.com/url-examples.html#apiv1labels) and [`/api/v1/label/.../values`](https://docs.victoriametrics.com/url-examples.html#apiv1labelvalues) when the database contains more than `-search.maxUniqueTimeseries` unique [time series](https://docs.victoriametrics.com/keyConcepts.html#time-series) on the selected time range. Previously VictoriaMetrics could return `the number of matching timeseries exceeds ...` error in this case. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5055).