diff --git a/frontend/src/container/SpanDetailsDrawer/Events/Events.tsx b/frontend/src/container/SpanDetailsDrawer/Events/Events.tsx index 336556c10b56..fa1b598a600c 100644 --- a/frontend/src/container/SpanDetailsDrawer/Events/Events.tsx +++ b/frontend/src/container/SpanDetailsDrawer/Events/Events.tsx @@ -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(''); + 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 { {event.attributeMap && Object.keys(event.attributeMap).map((attributeKey) => ( -
- - - {attributeKey} - - - -
- - - {event.attributeMap[attributeKey]} - - -
-
+ ))} ), @@ -115,6 +120,18 @@ function EventsTable(props: IEventsTableProps): JSX.Element { ))} + +
+					{modalContent?.content}
+				
+
); } diff --git a/frontend/src/container/SpanDetailsDrawer/Events/components/AttributeWithExpandablePopover.styles.scss b/frontend/src/container/SpanDetailsDrawer/Events/components/AttributeWithExpandablePopover.styles.scss new file mode 100644 index 000000000000..875a626017ed --- /dev/null +++ b/frontend/src/container/SpanDetailsDrawer/Events/components/AttributeWithExpandablePopover.styles.scss @@ -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; + } +} diff --git a/frontend/src/container/SpanDetailsDrawer/Events/components/AttributeWithExpandablePopover.tsx b/frontend/src/container/SpanDetailsDrawer/Events/components/AttributeWithExpandablePopover.tsx new file mode 100644 index 000000000000..eb4a0f01fff3 --- /dev/null +++ b/frontend/src/container/SpanDetailsDrawer/Events/components/AttributeWithExpandablePopover.tsx @@ -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 = ( +
+
+				{attributeValue}
+			
+ +
+ ); + + return ( +
+ + + {attributeKey} + + + +
+ + + {attributeValue} + + +
+
+ ); +} + +export default AttributeWithExpandablePopover; diff --git a/frontend/src/container/SpanDetailsDrawer/Events/components/EventAttribute.tsx b/frontend/src/container/SpanDetailsDrawer/Events/components/EventAttribute.tsx new file mode 100644 index 000000000000..f5b15003ff37 --- /dev/null +++ b/frontend/src/container/SpanDetailsDrawer/Events/components/EventAttribute.tsx @@ -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 ( + + ); + } + + return ( +
+ + + {attributeKey} + + +
+ + + {attributeValue} + + +
+
+ ); +} + +export default EventAttribute;