diff --git a/frontend/app/types/session/event.ts b/frontend/app/types/session/event.ts index bb901a6b1..99693d756 100644 --- a/frontend/app/types/session/event.ts +++ b/frontend/app/types/session/event.ts @@ -5,12 +5,18 @@ const LOCATION = 'LOCATION'; const CUSTOM = 'CUSTOM'; const CLICKRAGE = 'CLICKRAGE'; const IOS_VIEW = 'VIEW'; -export const TYPES = { CONSOLE, CLICK, INPUT, LOCATION, CUSTOM, CLICKRAGE, IOS_VIEW}; +export const TYPES = { CONSOLE, CLICK, INPUT, LOCATION, CUSTOM, CLICKRAGE, IOS_VIEW }; interface IEvent { time: number; timestamp: number; - type: typeof CONSOLE | typeof CLICK | typeof INPUT | typeof LOCATION | typeof CUSTOM | typeof CLICKRAGE; + type: + | typeof CONSOLE + | typeof CLICK + | typeof INPUT + | typeof LOCATION + | typeof CUSTOM + | typeof CLICKRAGE; name: string; key: number; label: string; @@ -18,18 +24,23 @@ interface IEvent { target: { path: string; label: string; - } + }; } + interface ConsoleEvent extends IEvent { - subtype: string - value: string + subtype: string; + value: string; } + interface ClickEvent extends IEvent { targetContent: string; count: number; } + interface InputEvent extends IEvent { value: string; + hesitation: number; + duration: number; } interface LocationEvent extends IEvent { @@ -51,11 +62,10 @@ interface LocationEvent extends IEvent { export type EventData = ConsoleEvent | ClickEvent | InputEvent | LocationEvent | IEvent; class Event { - key: IEvent["key"] - time: IEvent["time"]; - label: IEvent["label"]; - target: IEvent["target"]; - + key: IEvent['key']; + time: IEvent['time']; + label: IEvent['label']; + target: IEvent['target']; constructor(event: IEvent) { Object.assign(this, { @@ -64,98 +74,102 @@ class Event { key: event.key, target: { path: event.target?.path || event.targetPath, - label: event.target?.label - } - }) + label: event.target?.label, + }, + }); } } class Console extends Event { readonly type = CONSOLE; - readonly name = 'Console' + readonly name = 'Console'; subtype: string; value: string; constructor(evt: ConsoleEvent) { super(evt); - this.subtype = evt.subtype - this.value = evt.value + this.subtype = evt.subtype; + this.value = evt.value; } } export class Click extends Event { readonly type: typeof CLICKRAGE | typeof CLICK = CLICK; - readonly name = 'Click' + readonly name = 'Click'; targetContent = ''; - count: number + count: number; constructor(evt: ClickEvent, isClickRage?: boolean) { + console.log(evt); super(evt); - this.targetContent = evt.targetContent - this.count = evt.count + this.targetContent = evt.targetContent; + this.count = evt.count; if (isClickRage) { - this.type = CLICKRAGE + this.type = CLICKRAGE; } } } class Input extends Event { readonly type = INPUT; - readonly name = 'Input' - value = '' + readonly name = 'Input'; + readonly hesitation: number = 0; + readonly duration: number = 0; + + value = ''; constructor(evt: InputEvent) { super(evt); - this.value = evt.value + this.value = evt.value; + this.hesitation = evt.hesitation; + this.duration = evt.duration; } } - export class Location extends Event { readonly name = 'Location'; readonly type = LOCATION; - url: LocationEvent["url"] - host: LocationEvent["host"]; - fcpTime: LocationEvent["fcpTime"]; - loadTime: LocationEvent["loadTime"]; - domContentLoadedTime: LocationEvent["domContentLoadedTime"]; - domBuildingTime: LocationEvent["domBuildingTime"]; - speedIndex: LocationEvent["speedIndex"]; - visuallyComplete: LocationEvent["visuallyComplete"]; - timeToInteractive: LocationEvent["timeToInteractive"]; - referrer: LocationEvent["referrer"]; + url: LocationEvent['url']; + host: LocationEvent['host']; + fcpTime: LocationEvent['fcpTime']; + loadTime: LocationEvent['loadTime']; + domContentLoadedTime: LocationEvent['domContentLoadedTime']; + domBuildingTime: LocationEvent['domBuildingTime']; + speedIndex: LocationEvent['speedIndex']; + visuallyComplete: LocationEvent['visuallyComplete']; + timeToInteractive: LocationEvent['timeToInteractive']; + referrer: LocationEvent['referrer']; constructor(evt: LocationEvent) { super(evt); Object.assign(this, { ...evt, - fcpTime: evt.firstContentfulPaintTime || evt.firstPaintTime + fcpTime: evt.firstContentfulPaintTime || evt.firstPaintTime, }); } } export type InjectedEvent = Console | Click | Input | Location; -export default function(event: EventData) { +export default function (event: EventData) { if (event.type && event.type === CONSOLE) { - return new Console(event as ConsoleEvent) + return new Console(event as ConsoleEvent); } if (event.type && event.type === CLICK) { - return new Click(event as ClickEvent) + return new Click(event as ClickEvent); } if (event.type && event.type === INPUT) { - return new Input(event as InputEvent) + return new Input(event as InputEvent); } if (event.type && event.type === LOCATION) { - return new Location(event as LocationEvent) + return new Location(event as LocationEvent); } if (event.type && event.type === CLICKRAGE) { - return new Click(event as ClickEvent, true) + return new Click(event as ClickEvent, true); } // not used right now? // if (event.type === CUSTOM || !event.type) { // return new Event(event) // } - console.error(`Unknown event type: ${event.type}`) + console.error(`Unknown event type: ${event.type}`); } - diff --git a/frontend/app/types/session/issue.ts b/frontend/app/types/session/issue.ts index 68ab64001..2abedc5ea 100644 --- a/frontend/app/types/session/issue.ts +++ b/frontend/app/types/session/issue.ts @@ -5,7 +5,8 @@ const types = { JS_EXCEPTION: 'js_exception', BAD_REQUEST: 'bad_request', CRASH: 'crash', - CLICK_RAGE: 'click_rage' + CLICK_RAGE: 'click_rage', + MOUSE_THRASHING: 'mouse_thrashing', } as const type TypeKeys = keyof typeof types @@ -21,6 +22,7 @@ export const issues_types = [ { 'type': types.BAD_REQUEST, 'visible': true, 'order': 2, 'name': 'Bad Requests', 'icon': 'funnel/file-medical-alt' }, { 'type': types.CLICK_RAGE, 'visible': true, 'order': 3, 'name': 'Click Rage', 'icon': 'funnel/emoji-angry' }, { 'type': types.CRASH, 'visible': true, 'order': 4, 'name': 'Crashes', 'icon': 'funnel/file-earmark-break' }, + { 'type': types.MOUSE_THRASHING, 'visible': true, 'order': 5, 'name': 'Mouse Thrashing', 'icon': 'close' }, // { 'type': 'memory', 'visible': true, 'order': 4, 'name': 'High Memory', 'icon': 'funnel/sd-card' }, // { 'type': 'vault', 'visible': true, 'order': 5, 'name': 'Vault', 'icon': 'safe' }, // { 'type': 'bookmark', 'visible': true, 'order': 5, 'name': 'Bookmarks', 'icon': 'safe' },