Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/trace-waterfall-redesign.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hyperdx/app": patch
---

feat: redesign the trace waterfall — per-service span colors, vertical service color bar, child counts, duration outside the bar with the span body on hover, expand/collapse depth controls.
91 changes: 31 additions & 60 deletions packages/app/src/components/DBTracePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,13 @@ import {
ActionIcon,
Box,
Button,
Divider,
Flex,
Group,
Stack,
Text,
Tooltip,
} from '@mantine/core';
import { IconPencil, IconX } from '@tabler/icons-react';
import { IconX } from '@tabler/icons-react';

import { DBTraceWaterfallChartContainer } from '@/components/DBTraceWaterfallChart';
import { SQLInlineEditorControlled } from '@/components/SQLEditor/SQLInlineEditor';
Expand Down Expand Up @@ -266,11 +265,8 @@ export default function DBTracePanel({
}
}, [parentSourceData, traceIdSetValue]);

const [showTraceIdInput, setShowTraceIdInput] = useState(false);

// Tidy the URL: drop a selection that belongs to a different trace. Purely
// cosmetic — the read-time `selectedSpan` gate already prevents a foreign
// selection from rendering; this just keeps the param from lingering.
// Reset highlighted row when trace ID changes
// otherwise we'll show stale span details
useEffect(() => {
if (eventRowWhere != null && eventRowWhere.traceId !== traceId) {
setEventRowWhere(null);
Expand Down Expand Up @@ -307,50 +303,11 @@ export default function DBTracePanel({
minHeight: 0,
}}
>
<Flex align="center" justify="space-between" mb="sm">
<Flex align="center">
<Text size="xs" me="xs">
{parentSourceData &&
(isLogSource(parentSourceData) || isTraceSource(parentSourceData))
? parentSourceData.traceIdExpression
: ''}
: {traceId || 'No trace id found for event'}
</Text>
{traceId != null && (
<Button
variant="subtle"
size="xs"
onClick={() => setShowTraceIdInput(v => !v)}
>
<IconPencil size={14} />
</Button>
)}
</Flex>
<Group gap="sm">
<Text size="sm">
{parentSourceData?.kind === SourceKind.Log
? 'Trace Source'
: 'Correlated Log Source'}
</Text>
<SourceSelectControlled
control={control}
name="source"
size="xs"
onSchemaPreview={() => setIsSourceSchemaPreviewOpen(true)}
isSchemaPreviewEnabled={isSourceSchemaPreviewEnabled(
childSourceData,
)}
/>
<SourceSchemaPreview
source={childSourceData}
controlled
open={isSourceSchemaPreviewOpen}
onClose={() => setIsSourceSchemaPreviewOpen(false)}
/>
</Group>
</Flex>
{(showTraceIdInput || !traceId) && parentSourceId != null && (
<Stack gap="xs">
{/* Fallback Trace ID Expression editor: only surfaced when no trace id
resolved for the event. The trace id itself now lives in the side
panel header (Copy Trace ID), so it's not duplicated here. */}
{!traceId && parentSourceId != null && (
<Stack gap="xs" mb="sm">
<Text size="xs">Trace ID Expression</Text>
<Flex align="center">
<SQLInlineEditorControlled
Expand Down Expand Up @@ -384,18 +341,9 @@ export default function DBTracePanel({
>
Save
</Button>
<Button
ms="sm"
variant="secondary"
onClick={() => setShowTraceIdInput(false)}
size="xs"
>
Cancel
</Button>
</Flex>
</Stack>
)}
<Divider my="sm" />
{/* Inline resizable split view: waterfall (left) + span detail (right) */}
<div
style={{
Expand Down Expand Up @@ -425,6 +373,29 @@ export default function DBTracePanel({
onClick={selectSpan}
initialRowHighlightHint={initialRowHighlightHint}
emptyState={emptyState}
controlsExtra={
<Group gap={4} align="center" wrap="nowrap">
<Text size="xxs" c="dimmed" style={{ whiteSpace: 'nowrap' }}>
Correlated logs
</Text>
<SourceSelectControlled
control={control}
name="source"
size="xs"
w={150}
onSchemaPreview={() => setIsSourceSchemaPreviewOpen(true)}
isSchemaPreviewEnabled={isSourceSchemaPreviewEnabled(
childSourceData,
)}
/>
<SourceSchemaPreview
source={childSourceData}
controlled
open={isSourceSchemaPreviewOpen}
onClose={() => setIsSourceSchemaPreviewOpen(false)}
/>
</Group>
}
/>
)}
</div>
Expand Down
Loading
Loading