diff --git a/packages/trace-viewer/src/ui/networkTab.tsx b/packages/trace-viewer/src/ui/networkTab.tsx index 83063f19b3..8e366d3a0e 100644 --- a/packages/trace-viewer/src/ui/networkTab.tsx +++ b/packages/trace-viewer/src/ui/networkTab.tsx @@ -30,7 +30,8 @@ type Filter = 'status' | 'method' | 'file' | 'time' | 'size' | 'content-type'; export const NetworkTab: React.FunctionComponent<{ model: modelUtil.MultiTraceModel | undefined, selectedTime: Boundaries | undefined, -}> = ({ model, selectedTime }) => { + onEntryHovered: (entry: Entry | undefined) => void, +}> = ({ model, selectedTime, onEntryHovered }) => { const [resource, setResource] = React.useState(); const [filter, setFilter] = React.useState(undefined); const [negateFilter, setNegateFilter] = React.useState(false); @@ -64,6 +65,7 @@ export const NetworkTab: React.FunctionComponent<{ items={resources} render={entry => } onSelected={setResource} + onHighlighted={onEntryHovered} /> } {resource && setResource(undefined)} />} diff --git a/packages/trace-viewer/src/ui/timeline.css b/packages/trace-viewer/src/ui/timeline.css index 6e98cde085..411e6188c3 100644 --- a/packages/trace-viewer/src/ui/timeline.css +++ b/packages/trace-viewer/src/ui/timeline.css @@ -62,26 +62,33 @@ left: 0; } -.timeline-lane.timeline-bars { - pointer-events: auto; - margin-bottom: 5px; - height: 5px; - overflow: visible; +.timeline-bars { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; } .timeline-bar { position: absolute; - height: 2px; --action-color: gray; - background-color: var(--action-color); + --action-background-color: #88888802; + border-top: 2px solid var(--action-color); +} + +.timeline-bar.active { + background-color: var(--action-background-color); } .timeline-bar.action { --action-color: var(--vscode-charts-red); + --action-background-color: #e5140033; } .timeline-bar.network { --action-color: var(--vscode-charts-blue); + --action-background-color: #1a85ff33; } .timeline-label { diff --git a/packages/trace-viewer/src/ui/timeline.tsx b/packages/trace-viewer/src/ui/timeline.tsx index 41f9698b5e..0f3df5a83d 100644 --- a/packages/trace-viewer/src/ui/timeline.tsx +++ b/packages/trace-viewer/src/ui/timeline.tsx @@ -32,16 +32,19 @@ type TimelineBar = { rightPosition: number; leftTime: number; rightTime: number; + active: boolean; }; export const Timeline: React.FunctionComponent<{ model: MultiTraceModel | undefined, boundaries: Boundaries, + highlightedAction: ActionTraceEventInContext | undefined, + highlightedEntry: Entry | undefined, onSelected: (action: ActionTraceEventInContext) => void, selectedTime: Boundaries | undefined, setSelectedTime: (time: Boundaries | undefined) => void, sdkLanguage: Language, -}> = ({ model, boundaries, onSelected, selectedTime, setSelectedTime, sdkLanguage }) => { +}> = ({ model, boundaries, onSelected, highlightedAction, highlightedEntry, selectedTime, setSelectedTime, sdkLanguage }) => { const [measure, ref] = useMeasure(); const [dragWindow, setDragWindow] = React.useState<{ startX: number, endX: number, pivot?: number, type: 'resize' | 'move' } | undefined>(); const [previewPoint, setPreviewPoint] = React.useState(); @@ -70,6 +73,7 @@ export const Timeline: React.FunctionComponent<{ rightTime: entry.endTime || boundaries.maximum, leftPosition: timeToPosition(measure.width, boundaries, entry.startTime), rightPosition: timeToPosition(measure.width, boundaries, entry.endTime || boundaries.maximum), + active: highlightedAction === entry, }); } @@ -82,10 +86,11 @@ export const Timeline: React.FunctionComponent<{ rightTime: endTime, leftPosition: timeToPosition(measure.width, boundaries, startTime), rightPosition: timeToPosition(measure.width, boundaries, endTime), + active: highlightedEntry === resource, }); } return bars; - }, [model, boundaries, measure]); + }, [model, boundaries, measure, highlightedAction, highlightedEntry]); const onMouseDown = React.useCallback((event: React.MouseEvent) => { setPreviewPoint(undefined); @@ -215,19 +220,21 @@ export const Timeline: React.FunctionComponent<{ ; }) } - {
{ +
+ +
{ bars.map((bar, index) => { return
; }) - }
} - + }
= ({ model, hideStackFrames, showSourcesFirst, rootDir, fallbackLocation, initialSelection, onSelectionChanged, isLive }) => { const [selectedAction, setSelectedAction] = React.useState(undefined); const [highlightedAction, setHighlightedAction] = React.useState(); + const [highlightedEntry, setHighlightedEntry] = React.useState(); const [selectedNavigatorTab, setSelectedNavigatorTab] = React.useState('actions'); const [selectedPropertiesTab, setSelectedPropertiesTab] = React.useState(showSourcesFirst ? 'source' : 'call'); const [isInspecting, setIsInspecting] = React.useState(false); @@ -122,7 +124,7 @@ export const Workbench: React.FunctionComponent<{ const networkTab: TabbedPaneTabModel = { id: 'network', title: 'Network', - render: () => + render: () => }; const attachmentsTab: TabbedPaneTabModel = { id: 'attachments', @@ -161,6 +163,8 @@ export const Workbench: React.FunctionComponent<{