mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
339 lines
11 KiB
TypeScript
339 lines
11 KiB
TypeScript
import { action, computed, makeObservable, observable } from "mobx";
|
|
import posthog from "posthog-js";
|
|
// stores
|
|
import { RootStore } from "./root.store";
|
|
// helpers
|
|
import { getUserRole } from "helpers/user.helper";
|
|
// constants
|
|
import {
|
|
EventProps,
|
|
IssueEventProps,
|
|
getCycleEventPayload,
|
|
getIssueEventPayload,
|
|
getModuleEventPayload,
|
|
getProjectEventPayload,
|
|
getProjectStateEventPayload,
|
|
getWorkspaceEventPayload,
|
|
getPageEventPayload,
|
|
getIssuesListOpenedPayload,
|
|
getIssuesFilterEventPayload,
|
|
getIssuesDisplayFilterPayload,
|
|
LP_UPDATED,
|
|
ISSUES_LIST_OPENED,
|
|
GROUP_WORKSPACE,
|
|
WORKSPACE_CREATED,
|
|
LABEL_REMOVED_G,
|
|
LABEL_ADDED_G,
|
|
} from "@/constants/event-tracker";
|
|
import { IIssueLabelTree } from "@plane/types";
|
|
|
|
export interface IEventTrackerStore {
|
|
// properties
|
|
trackElement: string | undefined;
|
|
// computed
|
|
getRequiredProperties: any;
|
|
getTrackElement: string | undefined;
|
|
// actions
|
|
resetSession: () => void;
|
|
setTrackElement: (element: string) => void;
|
|
captureEvent: (eventName: string, payload?: any) => void;
|
|
joinWorkspaceMetricGroup: (workspaceId?: string) => void;
|
|
captureWorkspaceEvent: (props: EventProps) => void;
|
|
captureProjectEvent: (props: EventProps) => void;
|
|
captureCycleEvent: (props: EventProps) => void;
|
|
captureModuleEvent: (props: EventProps) => void;
|
|
capturePageEvent: (props: EventProps) => void;
|
|
captureIssueEvent: (props: IssueEventProps) => void;
|
|
captureProjectStateEvent: (props: EventProps) => void;
|
|
captureIssuesListOpenedEvent: (payload: any) => void;
|
|
captureIssuesFilterEvent: (props: EventProps) => void;
|
|
captureIssuesDisplayFilterEvent: (props: EventProps) => void;
|
|
captureLabelDragNDropEvent: (
|
|
childLabelParent: string | null | undefined,
|
|
parentLabel: string | null | undefined,
|
|
childLabel: string | null | undefined,
|
|
projectLabelsTree: IIssueLabelTree[] | undefined
|
|
) => void;
|
|
}
|
|
|
|
export class EventTrackerStore implements IEventTrackerStore {
|
|
trackElement: string | undefined = undefined;
|
|
rootStore;
|
|
constructor(_rootStore: RootStore) {
|
|
makeObservable(this, {
|
|
// properties
|
|
trackElement: observable,
|
|
// computed
|
|
getRequiredProperties: computed,
|
|
getTrackElement: computed,
|
|
// actions
|
|
resetSession: action,
|
|
setTrackElement: action,
|
|
captureEvent: action,
|
|
captureProjectEvent: action,
|
|
captureCycleEvent: action,
|
|
captureModuleEvent: action,
|
|
capturePageEvent: action,
|
|
captureIssueEvent: action,
|
|
captureProjectStateEvent: action,
|
|
captureIssuesListOpenedEvent: action,
|
|
joinWorkspaceMetricGroup: action,
|
|
captureWorkspaceEvent: action,
|
|
});
|
|
// store
|
|
this.rootStore = _rootStore;
|
|
}
|
|
|
|
/**
|
|
* @description: Returns the current track element.
|
|
*/
|
|
get getTrackElement() {
|
|
return this.trackElement;
|
|
}
|
|
|
|
/**
|
|
* @description: Returns the necessary property for the event tracking
|
|
*/
|
|
get getRequiredProperties() {
|
|
const currentWorkspaceRole = this.rootStore.user.membership.currentWorkspaceRole;
|
|
const currentWorkspaceDetails = this.rootStore.workspaceRoot.currentWorkspace;
|
|
const currentProjectDetails = this.rootStore.projectRoot.project.currentProjectDetails;
|
|
return {
|
|
workspace_id: currentWorkspaceDetails?.id,
|
|
project_id: currentProjectDetails?.id,
|
|
user_project_role: currentProjectDetails?.member_role
|
|
? getUserRole(currentProjectDetails?.member_role as number)
|
|
: undefined,
|
|
user_workspace_role: getUserRole(currentWorkspaceRole as number),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @description: Set the trigger point of event.
|
|
* @param {string} element
|
|
*/
|
|
setTrackElement = (element?: string) => {
|
|
this.trackElement = element;
|
|
};
|
|
|
|
/**
|
|
* @description: Reset the session.
|
|
*/
|
|
resetSession = () => {
|
|
posthog?.reset();
|
|
};
|
|
|
|
/**
|
|
* @description: Creates the workspace metric group.
|
|
* @param {string} userEmail
|
|
* @param {string} workspaceId
|
|
*/
|
|
joinWorkspaceMetricGroup = (workspaceId?: string) => {
|
|
if (!workspaceId) return;
|
|
posthog?.group(GROUP_WORKSPACE, workspaceId, {
|
|
date: new Date().toDateString(),
|
|
workspace_id: workspaceId,
|
|
});
|
|
};
|
|
|
|
/**
|
|
* @description: Captures the event.
|
|
* @param {string} eventName
|
|
* @param {any} payload
|
|
*/
|
|
captureEvent = (eventName: string, payload?: any) => {
|
|
posthog?.capture(eventName, {
|
|
...this.getRequiredProperties,
|
|
...payload,
|
|
element: payload?.element ?? this.trackElement,
|
|
});
|
|
this.setTrackElement(undefined);
|
|
};
|
|
|
|
/**
|
|
* @description: Captures the workspace crud related events.
|
|
* @param {EventProps} props
|
|
*/
|
|
captureWorkspaceEvent = (props: EventProps) => {
|
|
const { eventName, payload } = props;
|
|
if (eventName === WORKSPACE_CREATED && payload.state == "SUCCESS") {
|
|
this.joinWorkspaceMetricGroup(payload.id);
|
|
}
|
|
const eventPayload: any = {
|
|
...getWorkspaceEventPayload(payload),
|
|
...this.getRequiredProperties,
|
|
element: payload.element ?? this.trackElement,
|
|
};
|
|
posthog?.capture(eventName, eventPayload);
|
|
this.setTrackElement(undefined);
|
|
};
|
|
|
|
/**
|
|
* @description: Captures the project related events.
|
|
* @param {EventProps} props
|
|
*/
|
|
captureProjectEvent = (props: EventProps) => {
|
|
const { eventName, payload } = props;
|
|
const eventPayload: any = {
|
|
...getProjectEventPayload(payload),
|
|
...this.getRequiredProperties,
|
|
element: payload.element ?? this.trackElement,
|
|
};
|
|
posthog?.capture(eventName, eventPayload);
|
|
this.setTrackElement(undefined);
|
|
};
|
|
|
|
/**
|
|
* @description: Captures the cycle related events.
|
|
* @param {EventProps} props
|
|
*/
|
|
captureCycleEvent = (props: EventProps) => {
|
|
const { eventName, payload } = props;
|
|
const eventPayload: any = {
|
|
...getCycleEventPayload(payload),
|
|
...this.getRequiredProperties,
|
|
element: payload.element ?? this.trackElement,
|
|
};
|
|
posthog?.capture(eventName, eventPayload);
|
|
this.setTrackElement(undefined);
|
|
};
|
|
|
|
/**
|
|
* @description: Captures the module related events.
|
|
* @param {EventProps} props
|
|
*/
|
|
captureModuleEvent = (props: EventProps) => {
|
|
const { eventName, payload } = props;
|
|
const eventPayload: any = {
|
|
...getModuleEventPayload(payload),
|
|
...this.getRequiredProperties,
|
|
element: payload.element ?? this.trackElement,
|
|
};
|
|
posthog?.capture(eventName, eventPayload);
|
|
this.setTrackElement(undefined);
|
|
};
|
|
|
|
/**
|
|
* @description: Captures the project pages related events.
|
|
* @param {EventProps} props
|
|
*/
|
|
capturePageEvent = (props: EventProps) => {
|
|
const { eventName, payload } = props;
|
|
const eventPayload: any = {
|
|
...getPageEventPayload(payload),
|
|
...this.getRequiredProperties,
|
|
element: payload.element ?? this.trackElement,
|
|
};
|
|
posthog?.capture(eventName, eventPayload);
|
|
this.setTrackElement(undefined);
|
|
};
|
|
|
|
/**
|
|
* @description: Captures the issue related events.
|
|
* @param {IssueEventProps} props
|
|
*/
|
|
captureIssueEvent = (props: IssueEventProps) => {
|
|
const { eventName, payload } = props;
|
|
const eventPayload: any = {
|
|
...getIssueEventPayload(props),
|
|
...this.getRequiredProperties,
|
|
state_group: this.rootStore.state.getStateById(payload.state_id)?.group ?? "",
|
|
element: payload.element ?? this.trackElement,
|
|
};
|
|
posthog?.capture(eventName, eventPayload);
|
|
this.setTrackElement(undefined);
|
|
};
|
|
|
|
/**
|
|
* @description: Captures the issue related events.
|
|
* @param {IssueEventProps} props
|
|
*/
|
|
captureProjectStateEvent = (props: EventProps) => {
|
|
const { eventName, payload } = props;
|
|
const eventPayload: any = {
|
|
...getProjectStateEventPayload(payload),
|
|
...this.getRequiredProperties,
|
|
element: payload.element ?? this.trackElement,
|
|
};
|
|
|
|
posthog?.capture(eventName, eventPayload);
|
|
this.setTrackElement(undefined);
|
|
};
|
|
|
|
/**
|
|
* @description: Captures the event whenever the issues list is opened.
|
|
* @param {any} payload
|
|
*/
|
|
captureIssuesListOpenedEvent = (payload: any) => {
|
|
const eventPayload = {
|
|
...getIssuesListOpenedPayload(payload),
|
|
...this.getRequiredProperties,
|
|
type: this.getRequiredProperties.project_id ? "Project" : "Workspace",
|
|
};
|
|
posthog?.capture(ISSUES_LIST_OPENED, eventPayload);
|
|
this.setTrackElement(undefined);
|
|
};
|
|
|
|
/**
|
|
* @description: Captures the event whenever the issues filters are changed.
|
|
* @param {IssueEventProps} props
|
|
*/
|
|
captureIssuesFilterEvent = (props: EventProps) => {
|
|
const { eventName, payload } = props;
|
|
const eventPayload = {
|
|
...getIssuesFilterEventPayload(payload),
|
|
...this.getRequiredProperties,
|
|
type: this.getRequiredProperties.project_id ? "Project" : "Workspace",
|
|
};
|
|
posthog?.capture(eventName, eventPayload);
|
|
this.setTrackElement(undefined);
|
|
};
|
|
|
|
/**
|
|
* @description: Captures the event whenever the issues display-filters are changed.
|
|
* @param {IssueEventProps} props
|
|
*/
|
|
captureIssuesDisplayFilterEvent = (props: EventProps) => {
|
|
const { eventName, payload } = props;
|
|
const eventPayload = {
|
|
...getIssuesDisplayFilterPayload(payload),
|
|
...this.getRequiredProperties,
|
|
type: this.getRequiredProperties.project_id ? "Project" : "Workspace",
|
|
current_display_filter: eventName === LP_UPDATED ? payload?.filters?.displayFilters : undefined,
|
|
};
|
|
posthog?.capture(eventName, eventPayload);
|
|
this.setTrackElement(undefined);
|
|
};
|
|
|
|
captureLabelDragNDropEvent = (
|
|
childLabelParent: string | null | undefined,
|
|
parentLabel: string | null | undefined,
|
|
childLabel: string | null | undefined,
|
|
projectLabelsTree: IIssueLabelTree[] | undefined
|
|
) => {
|
|
if (childLabelParent != parentLabel) {
|
|
// if the child label has a parent, then remove it from the parent and add it to a new parent.
|
|
if (childLabelParent) {
|
|
this.captureEvent(LABEL_REMOVED_G, {
|
|
group_id: childLabelParent,
|
|
child_id: childLabel,
|
|
child_count: (projectLabelsTree?.find((label) => label.id === childLabelParent)?.children?.length ?? 0) - 1,
|
|
});
|
|
parentLabel &&
|
|
this.captureEvent(LABEL_ADDED_G, {
|
|
group_id: parentLabel,
|
|
child_id: childLabel,
|
|
child_count: (projectLabelsTree?.find((label) => label.id === parentLabel)?.children?.length ?? 0) + 1,
|
|
});
|
|
} else {
|
|
// if the child label has no parent, then add it to a new parent.
|
|
this.captureEvent(LABEL_ADDED_G, {
|
|
group_id: parentLabel,
|
|
child_id: childLabel,
|
|
child_count: (projectLabelsTree?.find((label) => label.id === parentLabel)?.children?.length ?? 0) + 1,
|
|
});
|
|
}
|
|
}
|
|
};
|
|
}
|