feat(ui) - overview - stack event modal
This commit is contained in:
parent
930e502f25
commit
0a9c2ed4d1
6 changed files with 151 additions and 2 deletions
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
export { default } from './JsonViewer';
|
||||
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
export { default } from './Sentry';
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue