change(ui): refactor isRed isYellow methods into props, fix bugreport empty messages
This commit is contained in:
parent
5afad675ca
commit
dafce70d41
19 changed files with 51 additions and 57 deletions
|
|
@ -21,17 +21,17 @@ function Step({ step, ind, isDefault }: { step: IStep; ind: number; isDefault?:
|
|||
const menuItems = [
|
||||
{
|
||||
icon: 'quotes',
|
||||
text: 'Add/Remove Note',
|
||||
text: 'Notes',
|
||||
onClick: () => bugReportStore.toggleSubStepModal(true, 'note', step.key),
|
||||
},
|
||||
{
|
||||
icon: 'info-circle',
|
||||
text: `Add/Remove Error`,
|
||||
text: `Errors`,
|
||||
onClick: () => bugReportStore.toggleSubStepModal(true, 'error', step.key),
|
||||
},
|
||||
{
|
||||
icon: 'network',
|
||||
text: 'Add/Remove Network Request',
|
||||
text: 'Bad Network Requests',
|
||||
onClick: () => bugReportStore.toggleSubStepModal(true, 'network', step.key),
|
||||
},
|
||||
];
|
||||
|
|
@ -64,7 +64,7 @@ function Step({ step, ind, isDefault }: { step: IStep; ind: number; isDefault?:
|
|||
)}
|
||||
>
|
||||
{/* @ts-ignore */}
|
||||
<Tooltip title="Add Note, Error or Network Request" className="!flex items-center">
|
||||
<Tooltip title="Add Note, Error or bad Network Request" className="!flex items-center">
|
||||
<ItemMenu
|
||||
label={
|
||||
<Icon
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ import { filterList, debounce } from 'App/utils';
|
|||
import { useStore } from 'App/mstore';
|
||||
|
||||
const Titles = {
|
||||
note: 'Note',
|
||||
network: 'Fetch/XHR',
|
||||
error: 'Console Error',
|
||||
note: 'Notes',
|
||||
network: 'Fetch/XHR Errors',
|
||||
error: 'Console Errors',
|
||||
};
|
||||
const Icons = {
|
||||
note: 'quotes' as const,
|
||||
|
|
@ -171,6 +171,7 @@ function SubModal(props: ModalProps) {
|
|||
zIndex: 999,
|
||||
}}
|
||||
>
|
||||
{/* @ts-ignore */}
|
||||
<ModalContent type={props.type} items={items} />
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -28,7 +28,10 @@ export interface INetworkReq extends Item {
|
|||
|
||||
export type SubItem = INoteItem | IError | INetworkReq;
|
||||
|
||||
const safeStr = (ogStr: string) => (ogStr.length > 60 ? ogStr.slice(0, 60) + '...' : ogStr);
|
||||
const safeStr = (ogStr: string) => {
|
||||
if (!ogStr) return ''
|
||||
return (ogStr.length > 80 ? ogStr.slice(0, 80) + '...' : ogStr)
|
||||
}
|
||||
|
||||
export const NetworkComp = ({ item }: { item: INetworkReq }) => (
|
||||
<div className="flex items-start flex-col z-10">
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ function ConsoleRow(props: Props) {
|
|||
return (
|
||||
<div
|
||||
className={cn(stl.line, 'flex py-2 px-4 overflow-hidden group relative select-none', {
|
||||
info: !log.isYellow() && !log.isRed(),
|
||||
warn: log.isYellow(),
|
||||
error: log.isRed(),
|
||||
info: !log.isYellow && !log.isRed,
|
||||
warn: log.isYellow,
|
||||
error: log.isRed,
|
||||
'cursor-pointer': canExpand,
|
||||
})}
|
||||
style={style}
|
||||
|
|
@ -34,7 +34,7 @@ function ConsoleRow(props: Props) {
|
|||
{/* <div className={cn(stl.timestamp, {})}>
|
||||
{Duration.fromMillis(log.time).toFormat('mm:ss.SSS')}
|
||||
</div> */}
|
||||
<div key={log.key} className={cn('')} data-scroll-item={log.isRed()}>
|
||||
<div key={log.key} className={cn('')} data-scroll-item={log.isRed}>
|
||||
<div className={cn(stl.message, 'flex items-center')}>
|
||||
{canExpand && (
|
||||
<Icon name={expanded ? 'caret-down-fill' : 'caret-right-fill'} className="mr-2" />
|
||||
|
|
|
|||
|
|
@ -43,11 +43,11 @@ export function renderDuration(r) {
|
|||
if (!r.success) return 'x';
|
||||
|
||||
const text = `${Math.round(r.duration)}ms`;
|
||||
if (!r.isRed() && !r.isYellow()) return text;
|
||||
if (!r.isRed && !r.isYellow) return text;
|
||||
|
||||
let tooltipText;
|
||||
let className = 'w-full h-full flex items-center ';
|
||||
if (r.isYellow()) {
|
||||
if (r.isYellow) {
|
||||
tooltipText = 'Slower than average';
|
||||
className += 'warn color-orange';
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -134,11 +134,11 @@ export function renderDuration(r) {
|
|||
if (!r.success) return 'x';
|
||||
|
||||
const text = `${Math.floor(r.duration)}ms`;
|
||||
if (!r.isRed() && !r.isYellow()) return text;
|
||||
if (!r.isRed && !r.isYellow) return text;
|
||||
|
||||
let tooltipText;
|
||||
let className = 'w-full h-full flex items-center ';
|
||||
if (r.isYellow()) {
|
||||
if (r.isYellow) {
|
||||
tooltipText = 'Slower than average';
|
||||
className += 'warn color-orange';
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ function OverviewPanel({ issuesList }: { issuesList: Record<string, any>[] }) {
|
|||
const fetchPresented = fetchList.length > 0;
|
||||
|
||||
const resourceList = resourceListUnmap
|
||||
.filter((r: any) => r.isRed() || r.isYellow())
|
||||
.filter((r: any) => r.isRed || r.isYellow)
|
||||
.concat(fetchList.filter((i: any) => parseInt(i.status) >= 400))
|
||||
.concat(graphqlList.filter((i: any) => parseInt(i.status) >= 400))
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export default class UserEvent extends React.PureComponent {
|
|||
|
||||
getLevelClassname() {
|
||||
const { userEvent } = this.props;
|
||||
if (userEvent.isRed()) return 'error color-red';
|
||||
if (userEvent.isRed) return 'error color-red';
|
||||
return '';
|
||||
}
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ export default class UserEvent extends React.PureComponent {
|
|||
message = typeof message === 'string' ? message : JSON.stringify(message);
|
||||
return (
|
||||
<div
|
||||
data-scroll-item={userEvent.isRed()}
|
||||
data-scroll-item={userEvent.isRed}
|
||||
onClick={this.onClickDetails}
|
||||
className={cn(
|
||||
'group flex items-center py-2 px-4 border-b cursor-pointer relative',
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ function SubHeader(props) {
|
|||
} = store.get()
|
||||
|
||||
const mappedResourceList = resourceList
|
||||
.filter((r) => r.isRed() || r.isYellow())
|
||||
.filter((r) => r.isRed || r.isYellow)
|
||||
.concat(fetchList.filter((i) => parseInt(i.status) >= 400))
|
||||
.concat(graphqlList.filter((i) => parseInt(i.status) >= 400))
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ type Durationed = {
|
|||
|
||||
type CanBeRed = {
|
||||
//+isRed: boolean,
|
||||
isRed: () => boolean;
|
||||
isRed: boolean;
|
||||
};
|
||||
|
||||
interface Row extends Timed, Durationed, CanBeRed {
|
||||
|
|
@ -171,7 +171,7 @@ export default class TimeTable extends React.PureComponent<Props, State> {
|
|||
key={key}
|
||||
className={cn('border-b border-color-gray-light-shade', stl.row, {
|
||||
[stl.hoverable]: hoverable,
|
||||
'error color-red': !!row.isRed && row.isRed(),
|
||||
'error color-red': !!row.isRed && row.isRed,
|
||||
'cursor-pointer': typeof onRowClick === 'function',
|
||||
[stl.activeRow]: activeIndex === index,
|
||||
// [stl.inactiveRow]: !activeIndex || index > activeIndex,
|
||||
|
|
@ -194,7 +194,7 @@ export default class TimeTable extends React.PureComponent<Props, State> {
|
|||
onPrevClick = () => {
|
||||
let prevRedIndex = -1;
|
||||
for (let i = this.state.firstVisibleRowIndex - 1; i >= 0; i--) {
|
||||
if (this.props.rows[i].isRed()) {
|
||||
if (this.props.rows[i].isRed) {
|
||||
prevRedIndex = i;
|
||||
break;
|
||||
}
|
||||
|
|
@ -207,7 +207,7 @@ export default class TimeTable extends React.PureComponent<Props, State> {
|
|||
onNextClick = () => {
|
||||
let prevRedIndex = -1;
|
||||
for (let i = this.state.firstVisibleRowIndex + 1; i < this.props.rows.length; i++) {
|
||||
if (this.props.rows[i].isRed()) {
|
||||
if (this.props.rows[i].isRed) {
|
||||
prevRedIndex = i;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ function ConsoleRow(props: Props) {
|
|||
className={cn(
|
||||
'border-b flex items-center py-2 px-4 overflow-hidden group relative select-none',
|
||||
{
|
||||
info: !log.isYellow() && !log.isRed(),
|
||||
warn: log.isYellow(),
|
||||
error: log.isRed(),
|
||||
info: !log.isYellow && !log.isRed,
|
||||
warn: log.isYellow,
|
||||
error: log.isRed,
|
||||
'cursor-pointer': clickable,
|
||||
'cursor-pointer underline decoration-dotted decoration-gray-200': !!log.errorId,
|
||||
}
|
||||
|
|
@ -42,7 +42,7 @@ function ConsoleRow(props: Props) {
|
|||
<div className="mr-2">
|
||||
<Icon size="14" {...iconProps} />
|
||||
</div>
|
||||
<div key={log.key} data-scroll-item={log.isRed()}>
|
||||
<div key={log.key} data-scroll-item={log.isRed}>
|
||||
<div className={cn('flex items-center')}>
|
||||
{canExpand && (
|
||||
<Icon name={expanded ? 'caret-down-fill' : 'caret-right-fill'} className="mr-2" />
|
||||
|
|
|
|||
|
|
@ -109,11 +109,11 @@ export function renderDuration(r: any) {
|
|||
if (!r.success) return 'x';
|
||||
|
||||
const text = `${Math.floor(r.duration)}ms`;
|
||||
if (!r.isRed() && !r.isYellow()) return text;
|
||||
if (!r.isRed && !r.isYellow) return text;
|
||||
|
||||
let tooltipText;
|
||||
let className = 'w-full h-full flex items-center ';
|
||||
if (r.isYellow()) {
|
||||
if (r.isYellow) {
|
||||
tooltipText = 'Slower than average';
|
||||
className += 'warn color-orange';
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ function StackEventRow(props: Props) {
|
|||
return (
|
||||
<div
|
||||
style={style}
|
||||
data-scroll-item={event.isRed()}
|
||||
data-scroll-item={event.isRed}
|
||||
onClick={props.onClick}
|
||||
className={cn(
|
||||
'group flex items-center py-2 px-4 border-b cursor-pointer relative',
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ type Durationed = {
|
|||
|
||||
type CanBeRed = {
|
||||
//+isRed: boolean,
|
||||
isRed: () => boolean;
|
||||
isRed: boolean;
|
||||
};
|
||||
|
||||
interface Row extends Timed, Durationed, CanBeRed {
|
||||
|
|
@ -211,7 +211,7 @@ export default class TimeTable extends React.PureComponent<Props, State> {
|
|||
stl.row,
|
||||
{
|
||||
[stl.hoverable]: hoverable,
|
||||
'error color-red': !!row.isRed && row.isRed(),
|
||||
'error color-red': row.isRed,
|
||||
'cursor-pointer': typeof onRowClick === 'function',
|
||||
[stl.activeRow]: activeIndex === index,
|
||||
[stl.inactiveRow]: !activeIndex || index > activeIndex,
|
||||
|
|
@ -240,7 +240,7 @@ export default class TimeTable extends React.PureComponent<Props, State> {
|
|||
onPrevClick = () => {
|
||||
let prevRedIndex = -1;
|
||||
for (let i = this.state.firstVisibleRowIndex - 1; i >= 0; i--) {
|
||||
if (this.props.rows[i].isRed()) {
|
||||
if (this.props.rows[i].isRed) {
|
||||
prevRedIndex = i;
|
||||
break;
|
||||
}
|
||||
|
|
@ -253,7 +253,7 @@ export default class TimeTable extends React.PureComponent<Props, State> {
|
|||
onNextClick = () => {
|
||||
let prevRedIndex = -1;
|
||||
for (let i = this.state.firstVisibleRowIndex + 1; i < this.props.rows.length; i++) {
|
||||
if (this.props.rows[i].isRed()) {
|
||||
if (this.props.rows[i].isRed) {
|
||||
prevRedIndex = i;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ export default class Lists {
|
|||
}
|
||||
for (const name of MARKED_LIST_NAMES) {
|
||||
// TODO: provide types
|
||||
lists[name] = new ListWalkerWithMarks((el) => el.isRed(), initialLists[name])
|
||||
lists[name] = new ListWalkerWithMarks((el) => el.isRed, initialLists[name])
|
||||
}
|
||||
this.lists = lists as ListsObject
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,12 +30,11 @@ export default class WebPlayer extends Player {
|
|||
event: session.events || [],
|
||||
stack: session.stackEvents || [],
|
||||
resource: session.resources || [], // MBTODO: put ResourceTiming in file
|
||||
exceptions: session.errors?.map(({ time, errorId, name }: any) =>
|
||||
exceptions: session.errors?.map(({ name, ...rest }: any) =>
|
||||
Log({
|
||||
level: LogLevel.ERROR,
|
||||
value: name,
|
||||
time,
|
||||
errorId,
|
||||
...rest,
|
||||
})
|
||||
) || [],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ export interface ILog {
|
|||
}
|
||||
|
||||
export const Log = (log: ILog) => ({
|
||||
isRed: () => log.level === LogLevel.EXCEPTION || log.level === LogLevel.ERROR,
|
||||
isYellow: () => log.level === LogLevel.WARN,
|
||||
isRed: log.level === LogLevel.EXCEPTION || log.level === LogLevel.ERROR,
|
||||
isYellow: log.level === LogLevel.WARN,
|
||||
...log
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -103,15 +103,9 @@ export default class Resource {
|
|||
ttfb: timings && timings.ttfb,
|
||||
timewidth: timings && timings.timewidth,
|
||||
timings,
|
||||
isRed: !success || resource.score >= RED_BOUND,
|
||||
isYellow: resource.score < RED_BOUND && resource.score >= YELLOW_BOUND,
|
||||
})
|
||||
}
|
||||
|
||||
isRed() {
|
||||
return !this.success || this.score >= RED_BOUND;
|
||||
}
|
||||
|
||||
isYellow() {
|
||||
return this.score < RED_BOUND && this.score >= YELLOW_BOUND;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export const SUMOLOGIC = 'sumologic';
|
|||
|
||||
export const typeList = [OPENREPLAY, SENTRY, DATADOG, STACKDRIVER, ROLLBAR, BUGSNAG, CLOUDWATCH, ELASTICSEARCH, SUMOLOGIC];
|
||||
|
||||
export function isRed(event: StackEvent) {
|
||||
export function isRed(event: IStackEvent) {
|
||||
if (!event.payload) return false;
|
||||
switch (event.source) {
|
||||
case SENTRY:
|
||||
|
|
@ -45,7 +45,7 @@ export interface IStackEvent {
|
|||
source: any;
|
||||
level: string;
|
||||
|
||||
isRed: () => boolean;
|
||||
isRed: boolean;
|
||||
}
|
||||
|
||||
export default class StackEvent {
|
||||
|
|
@ -58,13 +58,10 @@ export default class StackEvent {
|
|||
level: IStackEvent["level"];
|
||||
|
||||
constructor(evt: IStackEvent) {
|
||||
const event = { ...evt, source: evt.source || OPENREPLAY }
|
||||
Object.assign(this, {
|
||||
...evt,
|
||||
source: evt.source || OPENREPLAY
|
||||
...event,
|
||||
isRed: isRed(event),
|
||||
});
|
||||
}
|
||||
|
||||
isRed() {
|
||||
return isRed(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue