feat(ui) - overview - stack event modal

This commit is contained in:
Shekar Siri 2022-08-11 17:51:10 +02:00
parent 930e502f25
commit 0a9c2ed4d1
6 changed files with 151 additions and 2 deletions

View file

@ -1,12 +1,30 @@
import React from 'react';
import JsonViewer from './components/JsonViewer';
import Sentry from './components/Sentry';
import { OPENREPLAY, SENTRY, DATADOG, STACKDRIVER } from 'Types/session/stackEvent';
interface Props {
event: any;
}
function StackEventModal(props: Props) {
const renderPopupContent = () => {
const {
event: { source, payload, name },
} = props;
switch (source) {
case SENTRY:
return <Sentry event={payload} />;
case DATADOG:
return <JsonViewer title={name} data={payload} icon="integrations/datadog" />;
case STACKDRIVER:
return <JsonViewer title={name} data={payload} icon="integrations/stackdriver" />;
default:
return <JsonViewer title={name} data={payload} icon={`integrations/${source}`} />;
}
};
return (
<div className="bg-white h-screen overflow-y-auto" style={{ width: '350px' }}>
Content
<div className="bg-white h-screen overflow-y-auto" style={{ width: '450px' }}>
{renderPopupContent()}
</div>
);
}

View file

@ -0,0 +1,15 @@
import React from 'react';
import { Icon, JSONTree } from 'UI';
export default class JsonViewer extends React.PureComponent {
render() {
const { data, title, icon } = this.props;
return (
<div className="p-5">
<Icon name={icon} size="30" />
<h4 className="my-5 capitalize"> {title}</h4>
<JSONTree src={data} collapsed={false} />
</div>
);
}
}

View file

@ -0,0 +1 @@
export { default } from './JsonViewer';

View file

@ -0,0 +1,67 @@
import React from 'react';
import { getIn, get } from 'immutable';
import cn from 'classnames';
import { withRequest } from 'HOCs';
import { Loader, Icon, JSONTree } from 'UI';
import { Accordion } from 'semantic-ui-react';
import stl from './sentry.module.css';
@withRequest({
endpoint: (props) => `/integrations/sentry/events/${props.event.id}`,
dataName: 'detailedEvent',
loadOnInitialize: true,
})
export default class SentryEventInfo extends React.PureComponent {
makePanelsFromStackTrace(stacktrace) {
return get(stacktrace, 'frames', []).map(({ filename, function: method, lineNo, context = [] }) => ({
key: `${filename}_${method}_${lineNo}`,
title: {
content: (
<span className={stl.accordionTitle}>
<b>{filename}</b>
{' in '}
<b>{method}</b>
{' at line '}
<b>{lineNo}</b>
</span>
),
},
content: {
content: (
<ol start={getIn(context, [0, 0], 0)} className={stl.lineList}>
{context.map(([ctxLineNo, codeText]) => (
<li className={cn(stl.codeLine, { [stl.highlighted]: ctxLineNo === lineNo })}>{codeText}</li>
))}
</ol>
),
},
}));
}
renderBody() {
const { detailedEvent, requestError, event } = this.props;
const exceptionEntry = get(detailedEvent, ['entries'], []).find(({ type }) => type === 'exception');
const stacktraces = getIn(exceptionEntry, ['data', 'values']);
if (!stacktraces) {
return <JSONTree src={requestError ? event : detailedEvent} sortKeys={false} enableClipboard />;
}
return stacktraces.map(({ type, value, stacktrace }) => (
<div key={type} className={stl.stacktrace}>
<h6>{type}</h6>
<p>{value}</p>
<Accordion styled panels={this.makePanelsFromStackTrace(stacktrace)} />
</div>
));
}
render() {
const { open, toggleOpen, loading } = this.props;
return (
<div className={stl.wrapper}>
<Icon name="integrations/sentry-text" size="30" color="gray-medium" />
<Loader loading={loading}>{this.renderBody()}</Loader>
</div>
);
}
}

View file

@ -0,0 +1 @@
export { default } from './Sentry';

View file

@ -0,0 +1,47 @@
.wrapper {
padding: 20px 40px 30px;
}
.icon {
margin-left: -5px;
}
.stacktrace {
& h6 {
display: flex;
align-items: center;
font-size: 17px;
padding-top: 7px;
margin-bottom: 10px;
}
& p {
font-family: 'Menlo', 'monaco', 'consolas', monospace;
}
}
.accordionTitle {
font-weight: 100;
& > b {
font-weight: 700;
}
}
.lineList {
list-style-position: inside;
list-style-type: decimal-leading-zero;
background: $gray-lightest;
}
.codeLine {
font-family: 'Menlo', 'monaco', 'consolas', monospace;
line-height: 24px;
font-size: 12px;
white-space: pre-wrap;
word-wrap: break-word;
min-height: 24px;
padding: 0 25px;
&.highlighted {
background: $red;
color: $white;
}
}