mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-05 20:16:04 +08:00
parent
e22be60a9e
commit
b9d63d6b8f
@ -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 (
|
||||||
|
<StyledButton
|
||||||
|
styledclass={style}
|
||||||
|
onClick={(): void => {
|
||||||
|
onToggleHandler(true);
|
||||||
|
setText({
|
||||||
|
subText: value,
|
||||||
|
text: event,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
type="link"
|
||||||
|
>
|
||||||
|
{buttonText}
|
||||||
|
</StyledButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
@ -1,29 +1,22 @@
|
|||||||
import { Collapse, Modal } from 'antd';
|
import { Collapse } from 'antd';
|
||||||
import Editor from 'components/Editor';
|
|
||||||
import { StyledButton } from 'components/Styled';
|
|
||||||
import useThemeMode from 'hooks/useThemeMode';
|
import useThemeMode from 'hooks/useThemeMode';
|
||||||
import keys from 'lodash-es/keys';
|
import keys from 'lodash-es/keys';
|
||||||
import map from 'lodash-es/map';
|
import map from 'lodash-es/map';
|
||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import { ITraceTree } from 'types/api/trace/getTraceItem';
|
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;
|
const { Panel } = Collapse;
|
||||||
|
|
||||||
function ErrorTag({ event }: ErrorTagProps): JSX.Element {
|
function ErrorTag({
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
event,
|
||||||
|
onToggleHandler,
|
||||||
|
setText,
|
||||||
|
}: ErrorTagProps): JSX.Element {
|
||||||
const { isDarkMode } = useThemeMode();
|
const { isDarkMode } = useThemeMode();
|
||||||
|
|
||||||
const [text, setText] = useState({
|
|
||||||
text: '',
|
|
||||||
subText: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
const onToggleHandler = (state: boolean): void => {
|
|
||||||
setIsOpen(state);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{map(event, ({ attributeMap, name }) => {
|
{map(event, ({ attributeMap, name }) => {
|
||||||
@ -45,23 +38,23 @@ function ErrorTag({ event }: ErrorTagProps): JSX.Element {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<CustomSubTitle>{event}</CustomSubTitle>
|
<CustomSubTitle>{event}</CustomSubTitle>
|
||||||
<CustomSubText ellipsis={isEllipsed} isDarkMode={isDarkMode}>
|
<CustomSubText
|
||||||
|
ellipsis={{
|
||||||
|
rows: isEllipsed ? 1 : 0,
|
||||||
|
}}
|
||||||
|
isDarkMode={isDarkMode}
|
||||||
|
>
|
||||||
{value}
|
{value}
|
||||||
<br />
|
<br />
|
||||||
{isEllipsed && (
|
{isEllipsed && (
|
||||||
<StyledButton
|
<EllipsedButton
|
||||||
styledclass={[styles.removeMargin, styles.removePadding]}
|
{...{
|
||||||
onClick={(): void => {
|
event,
|
||||||
onToggleHandler(true);
|
onToggleHandler,
|
||||||
setText({
|
setText,
|
||||||
subText: value,
|
value,
|
||||||
text: event,
|
|
||||||
});
|
|
||||||
}}
|
}}
|
||||||
type="link"
|
/>
|
||||||
>
|
|
||||||
View full log event message
|
|
||||||
</StyledButton>
|
|
||||||
)}
|
)}
|
||||||
</CustomSubText>
|
</CustomSubText>
|
||||||
</>
|
</>
|
||||||
@ -71,31 +64,14 @@ function ErrorTag({ event }: ErrorTagProps): JSX.Element {
|
|||||||
</Collapse>
|
</Collapse>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
<Modal
|
|
||||||
onCancel={(): void => onToggleHandler(false)}
|
|
||||||
title="Log Message"
|
|
||||||
visible={isOpen}
|
|
||||||
destroyOnClose
|
|
||||||
footer={[]}
|
|
||||||
width="70vw"
|
|
||||||
>
|
|
||||||
<CustomSubTitle>{text.text}</CustomSubTitle>
|
|
||||||
|
|
||||||
{text.text === 'exception.stacktrace' ? (
|
|
||||||
<Editor onChange={(): void => {}} readOnly value={text.subText} />
|
|
||||||
) : (
|
|
||||||
<CustomSubText ellipsis={false} isDarkMode={isDarkMode}>
|
|
||||||
{text.subText}
|
|
||||||
</CustomSubText>
|
|
||||||
)}
|
|
||||||
</Modal>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ErrorTagProps {
|
interface ErrorTagProps {
|
||||||
event: ITraceTree['event'];
|
event: ITraceTree['event'];
|
||||||
|
onToggleHandler: (isOpen: boolean) => void;
|
||||||
|
setText: (text: { subText: string; text: string }) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ErrorTag;
|
export default ErrorTag;
|
||||||
|
@ -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 { StyledSpace } from 'components/Styled';
|
||||||
import useThemeMode from 'hooks/useThemeMode';
|
import useThemeMode from 'hooks/useThemeMode';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo, useState } from 'react';
|
||||||
import { ITraceTree } from 'types/api/trace/getTraceItem';
|
import { ITraceTree } from 'types/api/trace/getTraceItem';
|
||||||
|
|
||||||
|
import EllipsedButton from './EllipsedButton';
|
||||||
import ErrorTag from './ErrorTag';
|
import ErrorTag from './ErrorTag';
|
||||||
import {
|
import {
|
||||||
CardContainer,
|
CardContainer,
|
||||||
@ -12,6 +14,7 @@ import {
|
|||||||
CustomText,
|
CustomText,
|
||||||
CustomTitle,
|
CustomTitle,
|
||||||
styles,
|
styles,
|
||||||
|
SubTextContainer,
|
||||||
} from './styles';
|
} from './styles';
|
||||||
|
|
||||||
const { TabPane } = Tabs;
|
const { TabPane } = Tabs;
|
||||||
@ -26,6 +29,17 @@ function SelectedSpanDetails(props: SelectedSpanDetailsProps): JSX.Element {
|
|||||||
tree?.serviceName,
|
tree?.serviceName,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
|
const [text, setText] = useState({
|
||||||
|
text: '',
|
||||||
|
subText: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const onToggleHandler = (state: boolean): void => {
|
||||||
|
setIsOpen(state);
|
||||||
|
};
|
||||||
|
|
||||||
if (!tree) {
|
if (!tree) {
|
||||||
return <div />;
|
return <div />;
|
||||||
}
|
}
|
||||||
@ -52,18 +66,60 @@ function SelectedSpanDetails(props: SelectedSpanDetailsProps): JSX.Element {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</StyledSpace>
|
</StyledSpace>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
onCancel={(): void => onToggleHandler(false)}
|
||||||
|
title={text.text}
|
||||||
|
visible={isOpen}
|
||||||
|
destroyOnClose
|
||||||
|
footer={[]}
|
||||||
|
width="70vw"
|
||||||
|
centered
|
||||||
|
>
|
||||||
|
{text.text === 'exception.stacktrace' ? (
|
||||||
|
<Editor onChange={(): void => {}} readOnly value={text.subText} />
|
||||||
|
) : (
|
||||||
|
<CustomSubText ellipsis={false} isDarkMode={isDarkMode}>
|
||||||
|
{text.subText}
|
||||||
|
</CustomSubText>
|
||||||
|
)}
|
||||||
|
</Modal>
|
||||||
|
|
||||||
<Tabs defaultActiveKey="1">
|
<Tabs defaultActiveKey="1">
|
||||||
<TabPane tab="Tags" key="1">
|
<TabPane tab="Tags" key="1">
|
||||||
{tags.length !== 0 ? (
|
{tags.length !== 0 ? (
|
||||||
tags.map((tags) => {
|
tags.map((tags) => {
|
||||||
|
const value = tags.key === 'error' ? 'true' : tags.value;
|
||||||
|
const isEllipsed = value.length > 24;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment key={JSON.stringify(tags)}>
|
<React.Fragment key={JSON.stringify(tags)}>
|
||||||
{tags.value && (
|
{tags.value && (
|
||||||
<>
|
<>
|
||||||
<CustomSubTitle>{tags.key}</CustomSubTitle>
|
<CustomSubTitle>{tags.key}</CustomSubTitle>
|
||||||
<CustomSubText isDarkMode={isDarkMode}>
|
<SubTextContainer isDarkMode={isDarkMode}>
|
||||||
{tags.key === 'error' ? 'true' : tags.value}
|
<Tooltip overlay={(): string => value}>
|
||||||
</CustomSubText>
|
<CustomSubText
|
||||||
|
ellipsis={{
|
||||||
|
rows: isEllipsed ? 1 : 0,
|
||||||
|
}}
|
||||||
|
isDarkMode={isDarkMode}
|
||||||
|
>
|
||||||
|
{value}
|
||||||
|
</CustomSubText>
|
||||||
|
|
||||||
|
{isEllipsed && (
|
||||||
|
<EllipsedButton
|
||||||
|
{...{
|
||||||
|
event: tags.key,
|
||||||
|
onToggleHandler,
|
||||||
|
setText,
|
||||||
|
value,
|
||||||
|
buttonText: 'View full value',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Tooltip>
|
||||||
|
</SubTextContainer>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
@ -75,7 +131,11 @@ function SelectedSpanDetails(props: SelectedSpanDetailsProps): JSX.Element {
|
|||||||
</TabPane>
|
</TabPane>
|
||||||
<TabPane tab="Events" key="2">
|
<TabPane tab="Events" key="2">
|
||||||
{tree.event && Object.keys(tree.event).length !== 0 ? (
|
{tree.event && Object.keys(tree.event).length !== 0 ? (
|
||||||
<ErrorTag event={tree.event} />
|
<ErrorTag
|
||||||
|
onToggleHandler={onToggleHandler}
|
||||||
|
setText={setText}
|
||||||
|
event={tree.event}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Typography>No events data in selected span</Typography>
|
<Typography>No events data in selected span</Typography>
|
||||||
)}
|
)}
|
||||||
|
@ -18,7 +18,8 @@ export const CustomText = styled(Paragraph)`
|
|||||||
export const CustomSubTitle = styled(Title)`
|
export const CustomSubTitle = styled(Title)`
|
||||||
&&& {
|
&&& {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 0.1rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -26,13 +27,19 @@ interface CustomSubTextProps {
|
|||||||
isDarkMode: boolean;
|
isDarkMode: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const SubTextContainer = styled.div<CustomSubTextProps>`
|
||||||
|
&&& {
|
||||||
|
background: ${({ isDarkMode }): string => (isDarkMode ? '#444' : '#ddd')};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export const CustomSubText = styled(Paragraph)<CustomSubTextProps>`
|
export const CustomSubText = styled(Paragraph)<CustomSubTextProps>`
|
||||||
&&& {
|
&&& {
|
||||||
background: ${({ isDarkMode }): string => (isDarkMode ? '#444' : '#ddd')};
|
background: ${({ isDarkMode }): string => (isDarkMode ? '#444' : '#ddd')};
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
padding: 6px 8px;
|
padding: 4px 8px;
|
||||||
word-break: break-all;
|
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 = {
|
export const styles = {
|
||||||
removeMargin,
|
removeMargin,
|
||||||
removePadding,
|
removePadding,
|
||||||
selectedSpanDetailsContainer,
|
selectedSpanDetailsContainer,
|
||||||
spanEventsTabsContainer,
|
spanEventsTabsContainer,
|
||||||
overflow,
|
overflow,
|
||||||
|
buttonContainer,
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user