grafana/public/app/features/explore/TraceView/useChildrenState.ts
Andrej Ocenas 1864807b15
Tracing: Performance optimization (#23474)
* Add integration with Jeager
Add Jaeger datasource and modify derived fields in loki to allow for opening a trace in Jager in separate split.
Modifies build so that this branch docker images are pushed to docker hub
Add a traceui dir with docker-compose and provision files for demoing.:wq

* Enable docker logger plugin to send logs to loki

* Add placeholder zipkin datasource

* Fixed rebase issues, added enhanceDataFrame to non-legacy code path

* Trace selector for jaeger query field

* Fix logs default mode for Loki

* Fix loading jaeger query field services on split

* Updated grafana image in traceui/compose file

* Fix prettier error

* Hide behind feature flag, clean up unused code.

* Fix tests

* Fix tests

* Cleanup code and review feedback

* Remove traceui directory

* Remove circle build changes

* Fix feature toggles object

* Fix merge issues

* Add trace ui in Explore

* WIP

* WIP

* WIP

* Make jaeger datasource return trace data instead of link

* Allow js in jest tests

* Return data from Jaeger datasource

* Take yarn.lock from master

* Fix missing component

* Update yarn lock

* Fix some ts and lint errors

* Fix merge

* Fix type errors

* Make tests pass again

* Add tests

* Fix es5 compatibility

* Add header with minimap

* Fix sizing issue due to column resizer handle

* Fix issues with sizing, search functionality, duplicate react, tests

* Refactor TraceView component, fix tests

* Fix type errors

* Add dark theme styling

* Add tests for hooks

* More color changes

* Fix tests to deal with additional theme wrappers.

* Add memoization

* Fix duplicate identifier

Co-authored-by: David Kaltschmidt <david.kaltschmidt@gmail.com>
2020-04-15 16:04:01 +02:00

107 lines
3.1 KiB
TypeScript

import { useCallback, useState } from 'react';
import { Span } from '@jaegertracing/jaeger-ui-components';
/**
* Children state means whether spans are collapsed or not. Also provides some functions to manipulate that state.
*/
export function useChildrenState() {
const [childrenHiddenIDs, setChildrenHiddenIDs] = useState(new Set<string>());
const expandOne = useCallback(
function expandOne(spans: Span[]) {
if (childrenHiddenIDs.size === 0) {
return;
}
let prevExpandedDepth = -1;
let expandNextHiddenSpan = true;
const newChildrenHiddenIDs = spans.reduce((res, s) => {
if (s.depth <= prevExpandedDepth) {
expandNextHiddenSpan = true;
}
if (expandNextHiddenSpan && res.has(s.spanID)) {
res.delete(s.spanID);
expandNextHiddenSpan = false;
prevExpandedDepth = s.depth;
}
return res;
}, new Set(childrenHiddenIDs));
setChildrenHiddenIDs(newChildrenHiddenIDs);
},
[childrenHiddenIDs]
);
const collapseOne = useCallback(
function collapseOne(spans: Span[]) {
if (shouldDisableCollapse(spans, childrenHiddenIDs)) {
return;
}
let nearestCollapsedAncestor: Span | undefined;
const newChildrenHiddenIDs = spans.reduce((res, curSpan) => {
if (nearestCollapsedAncestor && curSpan.depth <= nearestCollapsedAncestor.depth) {
res.add(nearestCollapsedAncestor.spanID);
if (curSpan.hasChildren) {
nearestCollapsedAncestor = curSpan;
}
} else if (curSpan.hasChildren && !res.has(curSpan.spanID)) {
nearestCollapsedAncestor = curSpan;
}
return res;
}, new Set(childrenHiddenIDs));
// The last one
if (nearestCollapsedAncestor) {
newChildrenHiddenIDs.add(nearestCollapsedAncestor.spanID);
}
setChildrenHiddenIDs(newChildrenHiddenIDs);
},
[childrenHiddenIDs]
);
const expandAll = useCallback(function expandAll() {
setChildrenHiddenIDs(new Set<string>());
}, []);
const collapseAll = useCallback(
function collapseAll(spans: Span[]) {
if (shouldDisableCollapse(spans, childrenHiddenIDs)) {
return;
}
const newChildrenHiddenIDs = spans.reduce((res, s) => {
if (s.hasChildren) {
res.add(s.spanID);
}
return res;
}, new Set<string>());
setChildrenHiddenIDs(newChildrenHiddenIDs);
},
[childrenHiddenIDs]
);
const childrenToggle = useCallback(
function childrenToggle(spanID: string) {
const newChildrenHiddenIDs = new Set(childrenHiddenIDs);
if (childrenHiddenIDs.has(spanID)) {
newChildrenHiddenIDs.delete(spanID);
} else {
newChildrenHiddenIDs.add(spanID);
}
setChildrenHiddenIDs(newChildrenHiddenIDs);
},
[childrenHiddenIDs]
);
return {
childrenHiddenIDs,
expandOne,
collapseOne,
expandAll,
collapseAll,
childrenToggle,
};
}
function shouldDisableCollapse(allSpans: Span[], hiddenSpansIds: Set<string>) {
const allParentSpans = allSpans.filter(s => s.hasChildren);
return allParentSpans.length === hiddenSpansIds.size;
}