feat: add support for expandable popover for stack message and body in trace details page (#8330)

* feat: add support for expandable popover for stack message and body in trace details page

* refactor: overall improvements + refactor ExpandableAttribute
This commit is contained in:
Shaheer Kochai 2025-06-24 16:22:33 +04:30 committed by GitHub
parent 1eff6d82c9
commit f80a6c3014
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 162 additions and 16 deletions

View File

@ -1,12 +1,13 @@
import './Events.styles.scss';
import { Collapse, Input, Tooltip, Typography } from 'antd';
import { Collapse, Input, Modal, Typography } from 'antd';
import { getYAxisFormattedValue } from 'components/Graph/yAxisConfig';
import { Diamond } from 'lucide-react';
import { useState } from 'react';
import { Span } from 'types/api/trace/getTraceV2';
import NoData from '../NoData/NoData';
import EventAttribute from './components/EventAttribute';
interface IEventsTableProps {
span: Span;
@ -17,6 +18,19 @@ interface IEventsTableProps {
function EventsTable(props: IEventsTableProps): JSX.Element {
const { span, startTime, isSearchVisible } = props;
const [fieldSearchInput, setFieldSearchInput] = useState<string>('');
const [modalContent, setModalContent] = useState<{
title: string;
content: string;
} | null>(null);
const showAttributeModal = (title: string, content: string): void => {
setModalContent({ title, content });
};
const handleCancel = (): void => {
setModalContent(null);
};
const events = span.event;
return (
@ -91,21 +105,12 @@ function EventsTable(props: IEventsTableProps): JSX.Element {
</div>
{event.attributeMap &&
Object.keys(event.attributeMap).map((attributeKey) => (
<div className="attribute-container" key={attributeKey}>
<Tooltip title={attributeKey}>
<Typography.Text className="attribute-key" ellipsis>
{attributeKey}
</Typography.Text>
</Tooltip>
<div className="wrapper">
<Tooltip title={event.attributeMap[attributeKey]}>
<Typography.Text className="attribute-value" ellipsis>
{event.attributeMap[attributeKey]}
</Typography.Text>
</Tooltip>
</div>
</div>
<EventAttribute
key={attributeKey}
attributeKey={attributeKey}
attributeValue={event.attributeMap[attributeKey]}
onExpand={showAttributeModal}
/>
))}
</div>
),
@ -115,6 +120,18 @@ function EventsTable(props: IEventsTableProps): JSX.Element {
</div>
))}
</div>
<Modal
title={modalContent?.title}
open={!!modalContent}
onCancel={handleCancel}
footer={null}
width="80vw"
centered
>
<pre className="attribute-with-expandable-popover__full-view">
{modalContent?.content}
</pre>
</Modal>
</div>
);
}

View File

@ -0,0 +1,31 @@
.attribute-with-expandable-popover {
&__popover {
display: flex;
flex-direction: column;
gap: 8px;
max-width: 50vw;
}
&__preview {
max-height: 40vh;
overflow-y: auto;
white-space: pre-wrap;
word-break: break-all;
padding: 8px;
border-radius: 4px;
}
&__expand-button {
align-self: flex-end;
display: flex;
align-items: center;
flex-grow: 0;
}
&__full-view {
max-height: 70vh;
overflow-y: auto;
white-space: pre-wrap;
word-break: break-all;
}
}

View File

@ -0,0 +1,52 @@
import './AttributeWithExpandablePopover.styles.scss';
import { Button, Popover, Tooltip, Typography } from 'antd';
import { Fullscreen } from 'lucide-react';
interface AttributeWithExpandablePopoverProps {
attributeKey: string;
attributeValue: string;
onExpand: (title: string, content: string) => void;
}
function AttributeWithExpandablePopover({
attributeKey,
attributeValue,
onExpand,
}: AttributeWithExpandablePopoverProps): JSX.Element {
const popoverContent = (
<div className="attribute-with-expandable-popover__popover">
<pre className="attribute-with-expandable-popover__preview">
{attributeValue}
</pre>
<Button
onClick={(): void => onExpand(attributeKey, attributeValue)}
size="small"
className="attribute-with-expandable-popover__expand-button"
icon={<Fullscreen size={14} />}
>
Expand
</Button>
</div>
);
return (
<div className="attribute-container" key={attributeKey}>
<Tooltip title={attributeKey}>
<Typography.Text className="attribute-key" ellipsis>
{attributeKey}
</Typography.Text>
</Tooltip>
<div className="wrapper">
<Popover content={popoverContent} trigger="hover" placement="topRight">
<Typography.Text className="attribute-value" ellipsis>
{attributeValue}
</Typography.Text>
</Popover>
</div>
</div>
);
}
export default AttributeWithExpandablePopover;

View File

@ -0,0 +1,46 @@
import { Tooltip, Typography } from 'antd';
import AttributeWithExpandablePopover from './AttributeWithExpandablePopover';
const EXPANDABLE_ATTRIBUTE_KEYS = ['exception.stacktrace', 'exception.message'];
interface EventAttributeProps {
attributeKey: string;
attributeValue: string;
onExpand: (title: string, content: string) => void;
}
function EventAttribute({
attributeKey,
attributeValue,
onExpand,
}: EventAttributeProps): JSX.Element {
if (EXPANDABLE_ATTRIBUTE_KEYS.includes(attributeKey)) {
return (
<AttributeWithExpandablePopover
attributeKey={attributeKey}
attributeValue={attributeValue}
onExpand={onExpand}
/>
);
}
return (
<div className="attribute-container" key={attributeKey}>
<Tooltip title={attributeKey}>
<Typography.Text className="attribute-key" ellipsis>
{attributeKey}
</Typography.Text>
</Tooltip>
<div className="wrapper">
<Tooltip title={attributeValue}>
<Typography.Text className="attribute-value" ellipsis>
{attributeValue}
</Typography.Text>
</Tooltip>
</div>
</div>
);
}
export default EventAttribute;