change(ui): refactor isRed isYellow methods into props, fix bugreport empty messages

This commit is contained in:
nick-delirium 2023-01-23 12:13:51 +01:00
parent 5afad675ca
commit dafce70d41
19 changed files with 51 additions and 57 deletions

View file

@ -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

View file

@ -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>
);

View file

@ -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">

View file

@ -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" />

View file

@ -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 {

View file

@ -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 {

View file

@ -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))

View file

@ -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',

View file

@ -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))

View file

@ -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;
}

View file

@ -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" />

View file

@ -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 {

View file

@ -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',

View file

@ -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;
}

View file

@ -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
}

View file

@ -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,
})
) || [],
}

View file

@ -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
})

View file

@ -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;
}
}

View file

@ -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);
}
}