mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-17 15:36:48 +00:00
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:
parent
1eff6d82c9
commit
f80a6c3014
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
@ -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;
|
||||
Loading…
x
Reference in New Issue
Block a user