diff --git a/frontend/src/container/TraceDetail/SelectedSpanDetails/EllipsedButton.tsx b/frontend/src/container/TraceDetail/SelectedSpanDetails/EllipsedButton.tsx new file mode 100644 index 0000000000..56ef64e4ee --- /dev/null +++ b/frontend/src/container/TraceDetail/SelectedSpanDetails/EllipsedButton.tsx @@ -0,0 +1,53 @@ +import { StyledButton } from 'components/Styled'; +import React from 'react'; + +import { styles } from './styles'; + +function EllipsedButton({ + onToggleHandler, + setText, + value, + event, + buttonText, +}: Props): JSX.Element { + const isFullValueButton = buttonText === 'View full value'; + + const style = [styles.removePadding]; + + if (!isFullValueButton) { + style.push(styles.removeMargin); + } else { + style.push(styles.selectedSpanDetailsContainer); + style.push(styles.buttonContainer); + } + + return ( + { + onToggleHandler(true); + setText({ + subText: value, + text: event, + }); + }} + type="link" + > + {buttonText} + + ); +} + +interface Props { + onToggleHandler: (isOpen: boolean) => void; + setText: (text: { subText: string; text: string }) => void; + value: string; + event: string; + buttonText?: string; +} + +EllipsedButton.defaultProps = { + buttonText: 'View full log event message', +}; + +export default EllipsedButton; diff --git a/frontend/src/container/TraceDetail/SelectedSpanDetails/ErrorTag.tsx b/frontend/src/container/TraceDetail/SelectedSpanDetails/ErrorTag.tsx index 2a663387a5..69b51b3cd8 100644 --- a/frontend/src/container/TraceDetail/SelectedSpanDetails/ErrorTag.tsx +++ b/frontend/src/container/TraceDetail/SelectedSpanDetails/ErrorTag.tsx @@ -1,29 +1,22 @@ -import { Collapse, Modal } from 'antd'; -import Editor from 'components/Editor'; -import { StyledButton } from 'components/Styled'; +import { Collapse } from 'antd'; import useThemeMode from 'hooks/useThemeMode'; import keys from 'lodash-es/keys'; import map from 'lodash-es/map'; -import React, { useState } from 'react'; +import React from 'react'; import { ITraceTree } from 'types/api/trace/getTraceItem'; -import { CustomSubText, CustomSubTitle, styles } from './styles'; +import EllipsedButton from './EllipsedButton'; +import { CustomSubText, CustomSubTitle } from './styles'; const { Panel } = Collapse; -function ErrorTag({ event }: ErrorTagProps): JSX.Element { - const [isOpen, setIsOpen] = useState(false); +function ErrorTag({ + event, + onToggleHandler, + setText, +}: ErrorTagProps): JSX.Element { const { isDarkMode } = useThemeMode(); - const [text, setText] = useState({ - text: '', - subText: '', - }); - - const onToggleHandler = (state: boolean): void => { - setIsOpen(state); - }; - return ( <> {map(event, ({ attributeMap, name }) => { @@ -45,23 +38,23 @@ function ErrorTag({ event }: ErrorTagProps): JSX.Element { return ( <> {event} - + {value}
{isEllipsed && ( - { - onToggleHandler(true); - setText({ - subText: value, - text: event, - }); + - View full log event message - + /> )}
@@ -71,31 +64,14 @@ function ErrorTag({ event }: ErrorTagProps): JSX.Element { ); })} - - onToggleHandler(false)} - title="Log Message" - visible={isOpen} - destroyOnClose - footer={[]} - width="70vw" - > - {text.text} - - {text.text === 'exception.stacktrace' ? ( - {}} readOnly value={text.subText} /> - ) : ( - - {text.subText} - - )} - ); } interface ErrorTagProps { event: ITraceTree['event']; + onToggleHandler: (isOpen: boolean) => void; + setText: (text: { subText: string; text: string }) => void; } export default ErrorTag; diff --git a/frontend/src/container/TraceDetail/SelectedSpanDetails/index.tsx b/frontend/src/container/TraceDetail/SelectedSpanDetails/index.tsx index 08d6c057a9..49596d14d0 100644 --- a/frontend/src/container/TraceDetail/SelectedSpanDetails/index.tsx +++ b/frontend/src/container/TraceDetail/SelectedSpanDetails/index.tsx @@ -1,9 +1,11 @@ -import { Tabs, Tooltip, Typography } from 'antd'; +import { Modal, Tabs, Tooltip, Typography } from 'antd'; +import Editor from 'components/Editor'; import { StyledSpace } from 'components/Styled'; import useThemeMode from 'hooks/useThemeMode'; -import React, { useMemo } from 'react'; +import React, { useMemo, useState } from 'react'; import { ITraceTree } from 'types/api/trace/getTraceItem'; +import EllipsedButton from './EllipsedButton'; import ErrorTag from './ErrorTag'; import { CardContainer, @@ -12,6 +14,7 @@ import { CustomText, CustomTitle, styles, + SubTextContainer, } from './styles'; const { TabPane } = Tabs; @@ -26,6 +29,17 @@ function SelectedSpanDetails(props: SelectedSpanDetailsProps): JSX.Element { tree?.serviceName, ]); + const [isOpen, setIsOpen] = useState(false); + + const [text, setText] = useState({ + text: '', + subText: '', + }); + + const onToggleHandler = (state: boolean): void => { + setIsOpen(state); + }; + if (!tree) { return
; } @@ -52,18 +66,60 @@ function SelectedSpanDetails(props: SelectedSpanDetailsProps): JSX.Element { + onToggleHandler(false)} + title={text.text} + visible={isOpen} + destroyOnClose + footer={[]} + width="70vw" + centered + > + {text.text === 'exception.stacktrace' ? ( + {}} readOnly value={text.subText} /> + ) : ( + + {text.subText} + + )} + + {tags.length !== 0 ? ( tags.map((tags) => { + const value = tags.key === 'error' ? 'true' : tags.value; + const isEllipsed = value.length > 24; + return ( {tags.value && ( <> {tags.key} - - {tags.key === 'error' ? 'true' : tags.value} - + + value}> + + {value} + + + {isEllipsed && ( + + )} + + )} @@ -75,7 +131,11 @@ function SelectedSpanDetails(props: SelectedSpanDetailsProps): JSX.Element { {tree.event && Object.keys(tree.event).length !== 0 ? ( - + ) : ( No events data in selected span )} diff --git a/frontend/src/container/TraceDetail/SelectedSpanDetails/styles.ts b/frontend/src/container/TraceDetail/SelectedSpanDetails/styles.ts index d8bae86ba7..3c9180dc94 100644 --- a/frontend/src/container/TraceDetail/SelectedSpanDetails/styles.ts +++ b/frontend/src/container/TraceDetail/SelectedSpanDetails/styles.ts @@ -18,7 +18,8 @@ export const CustomText = styled(Paragraph)` export const CustomSubTitle = styled(Title)` &&& { font-size: 14px; - margin-bottom: 8px; + margin-bottom: 0.1rem; + margin-top: 0.5rem; } `; @@ -26,13 +27,19 @@ interface CustomSubTextProps { isDarkMode: boolean; } +export const SubTextContainer = styled.div` + &&& { + background: ${({ isDarkMode }): string => (isDarkMode ? '#444' : '#ddd')}; + } +`; + export const CustomSubText = styled(Paragraph)` &&& { background: ${({ isDarkMode }): string => (isDarkMode ? '#444' : '#ddd')}; font-size: 12px; - padding: 6px 8px; + padding: 4px 8px; word-break: break-all; - margin-bottom: 16px; + margin-bottom: 0rem; } `; @@ -81,10 +88,15 @@ const overflow = css` } `; +const buttonContainer = css` + height: 1.5rem; +`; + export const styles = { removeMargin, removePadding, selectedSpanDetailsContainer, spanEventsTabsContainer, overflow, + buttonContainer, };