1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Rename track to capture. Fix types.

Signed-off-by: Juho Heikka <juho.heikka@gmail.com>
This commit is contained in:
Juho Heikka 2022-05-19 14:43:57 +03:00
parent 98b88180d8
commit 80a5a77f15
14 changed files with 57 additions and 133 deletions

View File

@ -7,11 +7,12 @@ import "./button.scss";
import type { ButtonHTMLAttributes } from "react";
import React from "react";
import { cssNames } from "../../utils";
import type { TooltipDecoratorProps } from "../tooltip";
import { withTooltip } from "../tooltip";
import { withInjectables } from "@ogre-tools/injectable-react";
import trackEventInjectable from "../../telemetry/track-event.injectable";
import captureMouseEventInjectable from "../../telemetry/capture-mouse-event.injectable";
interface Dependencies {
track: (e: React.MouseEvent) => void;
captureMouseEvent: (e: React.MouseEvent) => void;
}
export interface ButtonProps extends ButtonHTMLAttributes<any> {
@ -33,7 +34,7 @@ export interface ButtonProps extends ButtonHTMLAttributes<any> {
const NonInjectedButton = withTooltip((props: ButtonProps & Dependencies) => {
const {
waiting, label, primary, accent, plain, hidden, active, big,
round, outlined, light, children, track, ...btnProps
round, outlined, light, children, captureMouseEvent, ...btnProps
} = props;
if (hidden) return null;
@ -43,7 +44,7 @@ const NonInjectedButton = withTooltip((props: ButtonProps & Dependencies) => {
});
const onClick = (e: React.MouseEvent) => {
track(e);
captureMouseEvent(e);
if (btnProps.onClick) {
btnProps.onClick(e);
@ -73,12 +74,12 @@ const NonInjectedButton = withTooltip((props: ButtonProps & Dependencies) => {
});
export const Button = withInjectables<Dependencies, ButtonProps>(
export const Button = withInjectables<Dependencies, ButtonProps & TooltipDecoratorProps>(
NonInjectedButton,
{
getProps: (di, props) => ({
track: di.inject(trackEventInjectable),
captureMouseEvent: di.inject(captureMouseEventInjectable),
...props,
}),
},

View File

@ -8,7 +8,7 @@ import React from "react";
import type { SingleOrMany } from "../../utils";
import { cssNames, noop } from "../../utils";
import { withInjectables } from "@ogre-tools/injectable-react";
import trackWithIdInjectable from "../../telemetry/track-with-id.injectable";
import captureWithIdInjectable from "../../telemetry/capture-with-id.injectable";
export interface CheckboxProps {
className?: string;
@ -58,7 +58,7 @@ export const Checkbox = withInjectables<Dependencies, CheckboxProps>(
{
getProps: (di, props) => ({
captureClick: di.inject(trackWithIdInjectable),
captureClick: di.inject(captureWithIdInjectable),
...props,
}),
},

View File

@ -18,7 +18,7 @@ import { Tooltip } from "../tooltip";
import type { NormalizeCatalogEntityContextMenu } from "../../catalog/normalize-menu-item.injectable";
import { withInjectables } from "@ogre-tools/injectable-react";
import normalizeCatalogEntityContextMenuInjectable from "../../catalog/normalize-menu-item.injectable";
import trackWithIdInjectable from "../../../renderer/telemetry/track-with-id.injectable";
import captureWithIdInjectable from "../../telemetry/capture-with-id.injectable";
export interface HotbarIconProps extends AvatarProps {
uid: string;
@ -107,6 +107,6 @@ export const HotbarIcon = withInjectables<Dependencies, HotbarIconProps>(NonInje
getProps: (di, props) => ({
...props,
normalizeMenuItem: di.inject(normalizeCatalogEntityContextMenuInjectable),
capture: di.inject(trackWithIdInjectable),
capture: di.inject(captureWithIdInjectable),
}),
});

View File

@ -32,7 +32,7 @@ import userStoreInjectable from "../../../common/user-store/user-store.injectabl
import pageFiltersStoreInjectable from "./page-filters/store.injectable";
import type { OpenConfirmDialog } from "../confirm-dialog/open.injectable";
import openConfirmDialogInjectable from "../confirm-dialog/open.injectable";
import trackWithIdInjectable from "../../../renderer/telemetry/track-with-id.injectable";
import captureWithIdInjectable from "../../telemetry/capture-with-id.injectable";
export interface ItemListLayoutContentProps<Item extends ItemObject, PreLoadStores extends boolean> {
getFilters: () => Filter[];
@ -113,7 +113,9 @@ class NonInjectedItemListLayoutContent<
sortItem={item}
selected={detailsItem && detailsItem.getId() === item.getId()}
onClick={hasDetailsView ? prevDefault(() => {
this.props.capture(this.props.tableId, "Table Row Click");
if (this.props.tableId) {
this.props.capture(this.props.tableId, "Table Row Click");
}
return onDetails?.(item);
}) : undefined}
@ -387,6 +389,6 @@ export const ItemListLayoutContent = withInjectables<Dependencies, ItemListLayou
userStore: di.inject(userStoreInjectable),
pageFiltersStore: di.inject(pageFiltersStoreInjectable),
openConfirmDialog: di.inject(openConfirmDialogInjectable),
capture: di.inject(trackWithIdInjectable),
capture: di.inject(captureWithIdInjectable),
}),
}) as <Item extends ItemObject, PreLoadStores extends boolean>(props: ItemListLayoutContentProps<Item, PreLoadStores>) => React.ReactElement;

View File

@ -9,7 +9,7 @@ import type { HTMLAttributes } from "react";
import React from "react";
import { Icon } from "../icon";
import { withInjectables } from "@ogre-tools/injectable-react";
import trackWithIdInjectable from "../../telemetry/track-with-id.injectable";
import captureWithIdInjectable from "../../telemetry/capture-with-id.injectable";
export interface CloseButtonProps extends HTMLAttributes<HTMLDivElement> {
}
@ -26,7 +26,7 @@ function NonInjectedCloseButton(props: CloseButtonProps & Dependencies) {
{...rest}
onClick={(e) => {
capture(`${window.location.pathname}`, "Close Button Click");
props?.onClick(e);
props?.onClick?.(e);
}}>
<div
className={styles.closeButton}
@ -47,7 +47,7 @@ export const CloseButton = withInjectables<Dependencies, CloseButtonProps>(
{
getProps: (di, props) => ({
capture: di.inject(trackWithIdInjectable),
capture: di.inject(captureWithIdInjectable),
...props,
}),
},

View File

@ -16,7 +16,7 @@ import { withInjectables } from "@ogre-tools/injectable-react";
import type { SidebarStorageState } from "./sidebar-storage/sidebar-storage.injectable";
import sidebarStorageInjectable from "./sidebar-storage/sidebar-storage.injectable";
import type { HierarchicalSidebarItem } from "./sidebar-items.injectable";
import trackWithIdInjectable from "../../../renderer/telemetry/track-with-id.injectable";
import captureWithIdInjectable from "../../telemetry/capture-with-id.injectable";
interface Dependencies {
sidebarStorage: StorageLayer<SidebarStorageState>;
@ -98,7 +98,9 @@ class NonInjectedSidebarItem extends React.Component<
event.preventDefault();
event.stopPropagation();
this.props.capture(this.registration.title.toString(), "Click Side Bar Item");
if (this.registration.title) {
this.props.capture(this.registration.title.toString(), "Click Side Bar Item");
}
if (this.isExpandable) {
this.toggleExpand();
@ -129,7 +131,7 @@ export const SidebarItem = withInjectables<Dependencies, SidebarItemProps>(NonIn
getProps: (di, props) => ({
...props,
sidebarStorage: di.inject(sidebarStorageInjectable),
capture: di.inject(trackWithIdInjectable),
capture: di.inject(captureWithIdInjectable),
}),
});

View File

@ -12,7 +12,7 @@ import { Tab, Tabs } from "../tabs";
import { ErrorBoundary } from "../error-boundary";
import type { HierarchicalSidebarItem } from "./sidebar-items.injectable";
import { withInjectables } from "@ogre-tools/injectable-react";
import trackWithIdInjectable from "../../../renderer/telemetry/track-with-id.injectable";
import captureWithIdInjectable from "../../telemetry/capture-with-id.injectable";
interface Dependencies {
captureClick: (id: string, action: string) => void;
@ -44,7 +44,9 @@ const NonInjectedTabLayout = observer(
return (
<Tab
onClick={() => {
captureClick(registration.title.toString(), "Tab Click");
if (registration.title) {
captureClick(registration.title.toString(), "Tab Click");
}
registration.onClick();
}}
key={registration.id}
@ -73,7 +75,7 @@ export const TabLayout = withInjectables<Dependencies, TabLayoutProps>(
{
getProps: (di, props) => ({
captureClick: di.inject(trackWithIdInjectable),
captureClick: di.inject(captureWithIdInjectable),
...props,
}),
},

View File

@ -14,7 +14,7 @@ import type { IconProps } from "../icon";
import { Icon } from "../icon";
import isEqual from "lodash/isEqual";
import { withInjectables } from "@ogre-tools/injectable-react";
import trackWithIdInjectable from "../../../renderer/telemetry/track-with-id.injectable";
import captureWithIdInjectable from "../../telemetry/capture-with-id.injectable";
export const MenuContext = React.createContext<MenuContextValue | null>(null);
export type MenuContextValue = Menu;
@ -436,7 +436,7 @@ class NonInjectedMenuItem extends React.Component<MenuItemProps & Dependencies>
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
onClick!(evt);
const name = this.elem.querySelectorAll(".title")[0]?.textContent;
const name = this.elem?.querySelectorAll(".title")[0]?.textContent;
if (name) {
const id = `${window.location.pathname.split("/").pop()} ${name}`;
@ -493,7 +493,7 @@ export const MenuItem = withInjectables<Dependencies, MenuItemProps>(
{
getProps: (di, props) => ({
captureClick: di.inject(trackWithIdInjectable),
captureClick: di.inject(captureWithIdInjectable),
...props,
}),
},

View File

@ -12,12 +12,12 @@ import type { ObservableSet } from "mobx";
import { action, computed, makeObservable } from "mobx";
import { observer } from "mobx-react";
import ReactSelect, { components, createFilter } from "react-select";
import type { Props as ReactSelectProps, GroupBase, MultiValue, OptionsOrGroups, PropsValue, SingleValue } from "react-select";
import type { Props as ReactSelectProps, GroupBase, MultiValue, OptionsOrGroups, PropsValue, SingleValue, OnChangeValue, ActionMeta } from "react-select";
import type { ThemeStore } from "../../themes/store";
import { autoBind, cssNames } from "../../utils";
import { withInjectables } from "@ogre-tools/injectable-react";
import themeStoreInjectable from "../../themes/store.injectable";
import trackWithIdInjectable from "../../telemetry/track-with-id.injectable";
import captureWithIdInjectable from "../../telemetry/capture-with-id.injectable";
const { Menu } = components;
@ -230,12 +230,12 @@ class NonInjectedSelect<
onKeyDown={this.onKeyDown}
className={cssNames("Select", this.themeClass, className)}
classNamePrefix="Select"
onChange={action(() => {
onChange={action((newValue: OnChangeValue<Option, IsMulti>, actionMeta: ActionMeta<Option>) => {
if (inputId) {
props.capture(inputId, "Select Change");
}
onChange();
return onChange?.(newValue, actionMeta);
})} // This is done so that all changes are actionable
components={{
...components,
@ -257,7 +257,7 @@ export const Select = withInjectables<Dependencies, SelectProps<unknown, SelectO
getProps: (di, props) => ({
...props,
themeStore: di.inject(themeStoreInjectable),
capture: di.inject(trackWithIdInjectable),
capture: di.inject(captureWithIdInjectable),
}),
}) as <
Value,

View File

@ -9,7 +9,7 @@ import type { ChangeEvent, HTMLProps } from "react";
import React from "react";
import { cssNames } from "../../utils";
import { withInjectables } from "@ogre-tools/injectable-react";
import trackWithIdInjectable from "../../telemetry/track-with-id.injectable";
import captureWithIdInjectable from "../../telemetry/capture-with-id.injectable";
export interface SwitchProps extends Omit<HTMLProps<HTMLInputElement>, "onChange"> {
onChange?: (checked: boolean, event: ChangeEvent<HTMLInputElement>) => void;
@ -29,7 +29,10 @@ function NonInjectedSwitch({ children, disabled, onChange, captureChange, ...pro
disabled={disabled}
onChange={(event) =>{
onChange?.(event.target.checked, event);
captureChange(children.toString(), `Switch ${props.checked ? "On" : "Off"}`);
if (children) {
captureChange(children.toString(), `Switch ${props.checked ? "On" : "Off"}`);
}
}}
{...props}
/>
@ -42,7 +45,7 @@ export const Switch = withInjectables<Dependencies, SwitchProps>(
{
getProps: (di, props) => ({
captureChange: di.inject(trackWithIdInjectable),
captureChange: di.inject(captureWithIdInjectable),
...props,
}),
},

View File

@ -9,7 +9,7 @@ import React from "react";
import { autoBind, cssNames } from "../../utils";
import { Icon } from "../icon";
import { withInjectables } from "@ogre-tools/injectable-react";
import trackWithIdInjectable from "../../../renderer/telemetry/track-with-id.injectable";
import captureWithIdInjectable from "../../telemetry/capture-with-id.injectable";
const TabsContext = React.createContext<TabsContextValue>({});
@ -157,7 +157,7 @@ export const Tab = withInjectables<Dependencies, TabProps>(
{
getProps: (di, props) => ({
capture: di.inject(trackWithIdInjectable),
capture: di.inject(captureWithIdInjectable),
...props,
}),
},

View File

@ -37,12 +37,11 @@ function getEventName(el: HTMLElement) {
return eventName;
}
function trackEventName(eventBus: EventEmitter<[AppEvent]>, event: React.MouseEvent) {
function captureMouseEvent(eventBus: EventEmitter<[AppEvent]>, event: React.MouseEvent) {
const name = getEventName(event.target as HTMLElement);
const action = capitalize(event.type);
console.log("track event name");
console.log(`${action} ${name}`);
console.log(`[captureMouseEvent]: ${action} ${name}`);
eventBus.emit({
destination: "MixPanel",
@ -51,13 +50,13 @@ function trackEventName(eventBus: EventEmitter<[AppEvent]>, event: React.MouseEv
});
}
const trackEventInjectable = getInjectable({
id: "track-mouse-event",
const captureMouseEventInjectable = getInjectable({
id: "capture-mouse-event",
instantiate: (di) => {
return (event: React.MouseEvent) => {
return trackEventName(di.inject(appEventBusInjectable), event);
return captureMouseEvent(di.inject(appEventBusInjectable), event);
};
},
});
export default trackEventInjectable;
export default captureMouseEventInjectable;

View File

@ -12,10 +12,10 @@ function getNameFromId(id: string) {
return id.split(/[/,-,--]/).filter(Boolean).map((part) => `${part[0].toUpperCase()+part.substring(1)}`).join("");
}
function trackWithId(eventBus: EventEmitter<[AppEvent]>, id: string, action: string) {
function captureWithId(eventBus: EventEmitter<[AppEvent]>, id: string, action: string) {
const target = getNameFromId(id);
console.log(`[trackWithId]: ${name}`);
console.log(`[captureWithId]: ${target}`);
eventBus.emit({
name: target,
@ -24,13 +24,13 @@ function trackWithId(eventBus: EventEmitter<[AppEvent]>, id: string, action: str
});
}
const trackWithIdInjectable = getInjectable({
id: "track-with-id",
const captureWithIdInjectable = getInjectable({
id: "capture-with-id",
instantiate: (di) => {
return (id: string, action: string) => {
return trackWithId(di.inject(appEventBusInjectable), id, action);
return captureWithId(di.inject(appEventBusInjectable), id, action);
};
},
});
export default trackWithIdInjectable;
export default captureWithIdInjectable;

View File

@ -1,85 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import type { AppEvent } from "../../common/app-event-bus/event-bus";
import appEventBusInjectable from "../../common/app-event-bus/app-event-bus.injectable";
import type { EventEmitter } from "../../common/event-emitter";
function getButtonEventName(el: HTMLElement) {
let headers: string[] = [];
const levels = 3;
let parent = el;
for (let i = 0; i < levels; i++) {
if (parent.parentElement) {
parent = parent.parentElement;
}
}
const nodelist = parent.querySelectorAll("h1, h2, h3, h4, h5, h6, .header");
nodelist.forEach(node => headers.push(node.textContent));
if (headers.length === 0) {
const path = window.location.pathname.split("/");
headers.push(path[path.length-1]);
}
headers = [...new Set(headers)];
headers.push(el.textContent);
const buttonEventName = headers.join(" ");
return buttonEventName;
}
// foo_bar-baz => Foo Bar Baz
function getNameFromId(id: string) {
return id.split(/[_,-]/).map((part) => `${part[0].toUpperCase()+part.substring(1)}`).join("");
}
export class Telemetry {
private eventBus: EventEmitter<[AppEvent]>;
private destination = "jep";
private debug = false;
constructor(eventBus: EventEmitter<[AppEvent]>) {
this.eventBus = eventBus;
}
private emitEvent(action: string, name: string) {
console.log(`[TELEMETRY]: ${action} ${name}`);
if (!this.debug) {
this.eventBus.emit({
destination: this.destination,
name,
action,
});
}
}
buttonClickEvent(e: React.MouseEvent) {
const el = e.target as HTMLElement;
this.emitEvent("Click", getButtonEventName(el));
}
selectChangeEvent(id: string) {
this.emitEvent("Select Change", getNameFromId(id));
}
tableRowClick(id: string) {
this.emitEvent("Table Row Click", getNameFromId(id));
}
}
const telemetryInjectable = getInjectable({
id: "telemetry",
instantiate: (di) => new Telemetry(di.inject(appEventBusInjectable)),
});
export default telemetryInjectable;