chore: issue-open from sidebar events added

This commit is contained in:
LAKHAN BAHETI 2024-02-22 15:22:20 +05:30
parent fc5901d2d6
commit 8886aface1
10 changed files with 89 additions and 48 deletions

View File

@ -3,7 +3,7 @@ import { useRouter } from "next/router";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import useSWR from "swr"; import useSWR from "swr";
// mobx store // mobx store
import { useIssues } from "hooks/store"; import { useEventTracker, useIssues } from "hooks/store";
// components // components
import { import {
ArchivedIssueListLayout, ArchivedIssueListLayout,
@ -21,12 +21,14 @@ export const ArchivedIssueLayoutRoot: React.FC = observer(() => {
const { workspaceSlug, projectId } = router.query; const { workspaceSlug, projectId } = router.query;
// hooks // hooks
const { issues, issuesFilter } = useIssues(EIssuesStoreType.ARCHIVED); const { issues, issuesFilter } = useIssues(EIssuesStoreType.ARCHIVED);
const { captureIssuesListOpenedEvent } = useEventTracker();
useSWR( useSWR(
workspaceSlug && projectId ? `ARCHIVED_ISSUES_${workspaceSlug.toString()}_${projectId.toString()}` : null, workspaceSlug && projectId ? `ARCHIVED_ISSUES_${workspaceSlug.toString()}_${projectId.toString()}` : null,
async () => { async () => {
if (workspaceSlug && projectId) { if (workspaceSlug && projectId) {
await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString()); await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString());
captureIssuesListOpenedEvent(router.asPath, issuesFilter?.issueFilters?.filters);
await issues?.fetchIssues( await issues?.fetchIssues(
workspaceSlug.toString(), workspaceSlug.toString(),
projectId.toString(), projectId.toString(),

View File

@ -4,7 +4,7 @@ import { observer } from "mobx-react-lite";
import useSWR from "swr"; import useSWR from "swr";
import size from "lodash/size"; import size from "lodash/size";
// hooks // hooks
import { useCycle, useIssues } from "hooks/store"; import { useCycle, useEventTracker, useIssues } from "hooks/store";
// components // components
import { import {
CycleAppliedFiltersRoot, CycleAppliedFiltersRoot,
@ -29,6 +29,7 @@ export const CycleLayoutRoot: React.FC = observer(() => {
// store hooks // store hooks
const { issues, issuesFilter } = useIssues(EIssuesStoreType.CYCLE); const { issues, issuesFilter } = useIssues(EIssuesStoreType.CYCLE);
const { getCycleById } = useCycle(); const { getCycleById } = useCycle();
const { captureIssuesListOpenedEvent } = useEventTracker();
// state // state
const [transferIssuesModal, setTransferIssuesModal] = useState(false); const [transferIssuesModal, setTransferIssuesModal] = useState(false);
@ -39,6 +40,7 @@ export const CycleLayoutRoot: React.FC = observer(() => {
async () => { async () => {
if (workspaceSlug && projectId && cycleId) { if (workspaceSlug && projectId && cycleId) {
await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString(), cycleId.toString()); await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString(), cycleId.toString());
captureIssuesListOpenedEvent(router.asPath, issuesFilter?.issueFilters?.filters);
await issues?.fetchIssues( await issues?.fetchIssues(
workspaceSlug.toString(), workspaceSlug.toString(),
projectId.toString(), projectId.toString(),

View File

@ -3,7 +3,7 @@ import { useRouter } from "next/router";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import useSWR from "swr"; import useSWR from "swr";
// hooks // hooks
import { useIssues } from "hooks/store"; import { useEventTracker, useIssues } from "hooks/store";
// components // components
import { DraftIssueAppliedFiltersRoot } from "../filters/applied-filters/roots/draft-issue"; import { DraftIssueAppliedFiltersRoot } from "../filters/applied-filters/roots/draft-issue";
import { DraftIssueListLayout } from "../list/roots/draft-issue-root"; import { DraftIssueListLayout } from "../list/roots/draft-issue-root";
@ -21,12 +21,14 @@ export const DraftIssueLayoutRoot: React.FC = observer(() => {
const { workspaceSlug, projectId } = router.query; const { workspaceSlug, projectId } = router.query;
// hooks // hooks
const { issues, issuesFilter } = useIssues(EIssuesStoreType.DRAFT); const { issues, issuesFilter } = useIssues(EIssuesStoreType.DRAFT);
const { captureIssuesListOpenedEvent } = useEventTracker();
useSWR( useSWR(
workspaceSlug && projectId ? `DRAFT_ISSUES_${workspaceSlug.toString()}_${projectId.toString()}` : null, workspaceSlug && projectId ? `DRAFT_ISSUES_${workspaceSlug.toString()}_${projectId.toString()}` : null,
async () => { async () => {
if (workspaceSlug && projectId) { if (workspaceSlug && projectId) {
await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString()); await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString());
captureIssuesListOpenedEvent(router.asPath, issuesFilter?.issueFilters?.filters);
await issues?.fetchIssues( await issues?.fetchIssues(
workspaceSlug.toString(), workspaceSlug.toString(),
projectId.toString(), projectId.toString(),

View File

@ -4,7 +4,7 @@ import { observer } from "mobx-react-lite";
import useSWR from "swr"; import useSWR from "swr";
import size from "lodash/size"; import size from "lodash/size";
// mobx store // mobx store
import { useIssues } from "hooks/store"; import { useEventTracker, useIssues } from "hooks/store";
// components // components
import { import {
IssuePeekOverview, IssuePeekOverview,
@ -28,6 +28,7 @@ export const ModuleLayoutRoot: React.FC = observer(() => {
const { workspaceSlug, projectId, moduleId } = router.query; const { workspaceSlug, projectId, moduleId } = router.query;
// hooks // hooks
const { issues, issuesFilter } = useIssues(EIssuesStoreType.MODULE); const { issues, issuesFilter } = useIssues(EIssuesStoreType.MODULE);
const { captureIssuesListOpenedEvent } = useEventTracker();
useSWR( useSWR(
workspaceSlug && projectId && moduleId workspaceSlug && projectId && moduleId
@ -36,6 +37,7 @@ export const ModuleLayoutRoot: React.FC = observer(() => {
async () => { async () => {
if (workspaceSlug && projectId && moduleId) { if (workspaceSlug && projectId && moduleId) {
await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString(), moduleId.toString()); await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString(), moduleId.toString());
captureIssuesListOpenedEvent(router.asPath, issuesFilter?.issueFilters?.filters);
await issues?.fetchIssues( await issues?.fetchIssues(
workspaceSlug.toString(), workspaceSlug.toString(),
projectId.toString(), projectId.toString(),

View File

@ -16,7 +16,7 @@ import {
// ui // ui
import { Spinner } from "@plane/ui"; import { Spinner } from "@plane/ui";
// hooks // hooks
import { useIssues } from "hooks/store"; import { useEventTracker, useIssues } from "hooks/store";
// helpers // helpers
import { ActiveLoader } from "components/ui"; import { ActiveLoader } from "components/ui";
// constants // constants
@ -28,10 +28,12 @@ export const ProjectLayoutRoot: FC = observer(() => {
const { workspaceSlug, projectId } = router.query; const { workspaceSlug, projectId } = router.query;
// hooks // hooks
const { issues, issuesFilter } = useIssues(EIssuesStoreType.PROJECT); const { issues, issuesFilter } = useIssues(EIssuesStoreType.PROJECT);
const { captureIssuesListOpenedEvent } = useEventTracker();
useSWR(workspaceSlug && projectId ? `PROJECT_ISSUES_${workspaceSlug}_${projectId}` : null, async () => { useSWR(workspaceSlug && projectId ? `PROJECT_ISSUES_${workspaceSlug}_${projectId}` : null, async () => {
if (workspaceSlug && projectId) { if (workspaceSlug && projectId) {
await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString()); await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString());
captureIssuesListOpenedEvent(router.asPath, issuesFilter?.issueFilters?.filters);
await issues?.fetchIssues( await issues?.fetchIssues(
workspaceSlug.toString(), workspaceSlug.toString(),
projectId.toString(), projectId.toString(),

View File

@ -3,7 +3,7 @@ import { useRouter } from "next/router";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import useSWR from "swr"; import useSWR from "swr";
// mobx store // mobx store
import { useIssues } from "hooks/store"; import { useEventTracker, useIssues } from "hooks/store";
// components // components
import { import {
IssuePeekOverview, IssuePeekOverview,
@ -28,12 +28,14 @@ export const ProjectViewLayoutRoot: React.FC = observer(() => {
const { workspaceSlug, projectId, viewId } = router.query; const { workspaceSlug, projectId, viewId } = router.query;
// hooks // hooks
const { issues, issuesFilter } = useIssues(EIssuesStoreType.PROJECT_VIEW); const { issues, issuesFilter } = useIssues(EIssuesStoreType.PROJECT_VIEW);
const { captureIssuesListOpenedEvent } = useEventTracker();
useSWR( useSWR(
workspaceSlug && projectId && viewId ? `PROJECT_VIEW_ISSUES_${workspaceSlug}_${projectId}_${viewId}` : null, workspaceSlug && projectId && viewId ? `PROJECT_VIEW_ISSUES_${workspaceSlug}_${projectId}_${viewId}` : null,
async () => { async () => {
if (workspaceSlug && projectId && viewId) { if (workspaceSlug && projectId && viewId) {
await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString(), viewId.toString()); await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString(), viewId.toString());
captureIssuesListOpenedEvent(router.asPath, issuesFilter?.issueFilters?.filters);
await issues?.fetchIssues( await issues?.fetchIssues(
workspaceSlug.toString(), workspaceSlug.toString(),
projectId.toString(), projectId.toString(),

View File

@ -145,6 +145,7 @@ export const ProjectSidebarListItem: React.FC<Props> = observer((props) => {
if (window.innerWidth < 768) { if (window.innerWidth < 768) {
themeStore.toggleMobileSidebar(); themeStore.toggleMobileSidebar();
} }
setTrackElement('Project sidebar');
}; };
useOutsideClickDetector(actionSectionRef, () => setIsMenuActive(false)); useOutsideClickDetector(actionSectionRef, () => setIsMenuActive(false));

View File

@ -139,7 +139,7 @@ export const ProjectSidebarList: FC = observer(() => {
<button <button
className="opacity-0 group-hover:opacity-100" className="opacity-0 group-hover:opacity-100"
onClick={() => { onClick={() => {
setTrackElement("APP_SIDEBAR_FAVORITES_BLOCK"); setTrackElement("Sidebar");
setIsFavoriteProjectCreate(true); setIsFavoriteProjectCreate(true);
setIsProjectModalOpen(true); setIsProjectModalOpen(true);
}} }}

View File

@ -21,7 +21,6 @@ export const getWorkspaceEventPayload = (payload: any) => ({
}); });
export const getProjectEventPayload = (payload: any) => ({ export const getProjectEventPayload = (payload: any) => ({
workspace_id: payload.workspace_id,
project_id: payload.id, project_id: payload.id,
identifier: payload.identifier, identifier: payload.identifier,
project_visibility: payload.network == 2 ? "Public" : "Private", project_visibility: payload.network == 2 ? "Public" : "Private",
@ -34,8 +33,6 @@ export const getProjectEventPayload = (payload: any) => ({
}); });
export const getCycleEventPayload = (payload: any) => ({ export const getCycleEventPayload = (payload: any) => ({
workspace_id: payload.workspace_id,
project_id: payload.project,
cycle_id: payload.id, cycle_id: payload.id,
created_at: payload.created_at, created_at: payload.created_at,
updated_at: payload.updated_at, updated_at: payload.updated_at,
@ -48,8 +45,6 @@ export const getCycleEventPayload = (payload: any) => ({
}); });
export const getModuleEventPayload = (payload: any) => ({ export const getModuleEventPayload = (payload: any) => ({
workspace_id: payload.workspace_id,
project_id: payload.project,
module_id: payload.id, module_id: payload.id,
created_at: payload.created_at, created_at: payload.created_at,
updated_at: payload.updated_at, updated_at: payload.updated_at,
@ -64,8 +59,6 @@ export const getModuleEventPayload = (payload: any) => ({
}); });
export const getPageEventPayload = (payload: any) => ({ export const getPageEventPayload = (payload: any) => ({
workspace_id: payload.workspace_id,
project_id: payload.project,
created_at: payload.created_at, created_at: payload.created_at,
updated_at: payload.updated_at, updated_at: payload.updated_at,
access: payload.access === 0 ? "Public" : "Private", access: payload.access === 0 ? "Public" : "Private",
@ -109,19 +102,7 @@ export const getIssueEventPayload = (props: IssueEventProps) => {
eventPayload = { eventPayload = {
...eventPayload, ...eventPayload,
...updates, ...updates,
updated_from: props.path?.includes("workspace-views") updated_from: elementFromPath(path),
? "All views"
: props.path?.includes("cycles")
? "Cycle"
: props.path?.includes("modules")
? "Module"
: props.path?.includes("views")
? "Project view"
: props.path?.includes("inbox")
? "Inbox"
: props.path?.includes("draft")
? "Draft"
: "Project",
}; };
} }
return eventPayload; return eventPayload;
@ -129,8 +110,6 @@ export const getIssueEventPayload = (props: IssueEventProps) => {
export const getProjectStateEventPayload = (payload: any) => { export const getProjectStateEventPayload = (payload: any) => {
return { return {
workspace_id: payload.workspace_id,
project_id: payload.id,
state_id: payload.id, state_id: payload.id,
created_at: payload.created_at, created_at: payload.created_at,
updated_at: payload.updated_at, updated_at: payload.updated_at,
@ -142,6 +121,25 @@ export const getProjectStateEventPayload = (payload: any) => {
}; };
}; };
export const getIssuesListOpenedPayload = (payload: any) => ({
element: elementFromPath(payload.path),
type: payload.project_id ? "Project" : "Workspace",
layout: payload?.displayFilters?.layout,
filters: payload?.filters,
display_properties: payload?.displayProperties,
});
const elementFromPath = (path?: string) => {
if (path?.includes("workspace-views")) return "Workspace view";
if (path?.includes("cycles")) return "Cycle";
if (path?.includes("modules")) return "Module";
if (path?.includes("views")) return "Project view";
if (path?.includes("inbox")) return "Inbox";
if (path?.includes("draft")) return "Draft";
if (path?.includes("archived")) return "Archive";
return "Project";
};
// Workspace crud Events // Workspace crud Events
export const WORKSPACE_CREATED = "Workspace created"; export const WORKSPACE_CREATED = "Workspace created";
export const WORKSPACE_UPDATED = "Workspace updated"; export const WORKSPACE_UPDATED = "Workspace updated";
@ -175,6 +173,8 @@ export const VIEW_UNFAVORITED = "View unfavorited";
export const ISSUE_CREATED = "Issue created"; export const ISSUE_CREATED = "Issue created";
export const ISSUE_UPDATED = "Issue updated"; export const ISSUE_UPDATED = "Issue updated";
export const ISSUE_DELETED = "Issue deleted"; export const ISSUE_DELETED = "Issue deleted";
// Issue Checkout Events
export const ISSUES_LIST_OPENED = "Issues list opened";
export const ISSUE_OPENED = "Issue opened"; export const ISSUE_OPENED = "Issue opened";
// Project State Events // Project State Events
export const STATE_CREATED = "State created"; export const STATE_CREATED = "State created";
@ -235,7 +235,7 @@ export const NOTIFICATION_SNOOZED = "Notification snoozed";
export const NOTIFICATION_READ = "Notification marked read"; export const NOTIFICATION_READ = "Notification marked read";
export const UNREAD_NOTIFICATIONS = "Unread notifications viewed"; export const UNREAD_NOTIFICATIONS = "Unread notifications viewed";
export const NOTIFICATIONS_READ = "All notifications marked read"; export const NOTIFICATIONS_READ = "All notifications marked read";
export const SNOOZED_NOTIFICATIONS= "Snoozed notifications viewed"; export const SNOOZED_NOTIFICATIONS = "Snoozed notifications viewed";
export const ARCHIVED_NOTIFICATIONS = "Archived notifications viewed"; export const ARCHIVED_NOTIFICATIONS = "Archived notifications viewed";
// Groups // Groups
export const GROUP_WORKSPACE = "Workspace_metrics"; export const GROUP_WORKSPACE = "Workspace_metrics";

View File

@ -17,6 +17,8 @@ import {
getProjectStateEventPayload, getProjectStateEventPayload,
getWorkspaceEventPayload, getWorkspaceEventPayload,
getPageEventPayload, getPageEventPayload,
ISSUES_LIST_OPENED,
getIssuesListOpenedPayload,
} from "constants/event-tracker"; } from "constants/event-tracker";
export interface IEventTrackerStore { export interface IEventTrackerStore {
@ -37,6 +39,7 @@ export interface IEventTrackerStore {
capturePageEvent: (props: EventProps) => void; capturePageEvent: (props: EventProps) => void;
captureIssueEvent: (props: IssueEventProps) => void; captureIssueEvent: (props: IssueEventProps) => void;
captureProjectStateEvent: (props: EventProps) => void; captureProjectStateEvent: (props: EventProps) => void;
captureIssuesListOpenedEvent: (path: string, filters: any) => void;
} }
export class EventTrackerStore implements IEventTrackerStore { export class EventTrackerStore implements IEventTrackerStore {
@ -55,6 +58,12 @@ export class EventTrackerStore implements IEventTrackerStore {
captureEvent: action, captureEvent: action,
captureProjectEvent: action, captureProjectEvent: action,
captureCycleEvent: action, captureCycleEvent: action,
captureModuleEvent: action,
capturePageEvent: action,
captureIssueEvent: action,
captureProjectStateEvent: action,
captureIssuesListOpenedEvent: action,
joinWorkspaceMetricGroup: action,
}); });
// store // store
this.rootStore = _rootStore; this.rootStore = _rootStore;
@ -133,10 +142,11 @@ export class EventTrackerStore implements IEventTrackerStore {
if (eventName === WORKSPACE_CREATED && payload.state == "SUCCESS") { if (eventName === WORKSPACE_CREATED && payload.state == "SUCCESS") {
this.joinWorkspaceMetricGroup(payload.id); this.joinWorkspaceMetricGroup(payload.id);
} }
const eventPayload: any = getWorkspaceEventPayload({ const eventPayload: any = {
...payload, ...getWorkspaceEventPayload(payload),
...this.getRequiredProperties,
element: payload.element ?? this.trackElement, element: payload.element ?? this.trackElement,
}); };
posthog?.capture(eventName, eventPayload); posthog?.capture(eventName, eventPayload);
this.setTrackElement(undefined); this.setTrackElement(undefined);
}; };
@ -147,11 +157,11 @@ export class EventTrackerStore implements IEventTrackerStore {
*/ */
captureProjectEvent = (props: EventProps) => { captureProjectEvent = (props: EventProps) => {
const { eventName, payload } = props; const { eventName, payload } = props;
const eventPayload: any = getProjectEventPayload({ const eventPayload: any = {
...getProjectEventPayload(payload),
...this.getRequiredProperties, ...this.getRequiredProperties,
...payload,
element: payload.element ?? this.trackElement, element: payload.element ?? this.trackElement,
}); };
posthog?.capture(eventName, eventPayload); posthog?.capture(eventName, eventPayload);
this.setTrackElement(undefined); this.setTrackElement(undefined);
}; };
@ -162,11 +172,11 @@ export class EventTrackerStore implements IEventTrackerStore {
*/ */
captureCycleEvent = (props: EventProps) => { captureCycleEvent = (props: EventProps) => {
const { eventName, payload } = props; const { eventName, payload } = props;
const eventPayload: any = getCycleEventPayload({ const eventPayload: any = {
...getCycleEventPayload(payload),
...this.getRequiredProperties, ...this.getRequiredProperties,
...payload,
element: payload.element ?? this.trackElement, element: payload.element ?? this.trackElement,
}); };
posthog?.capture(eventName, eventPayload); posthog?.capture(eventName, eventPayload);
this.setTrackElement(undefined); this.setTrackElement(undefined);
}; };
@ -177,11 +187,11 @@ export class EventTrackerStore implements IEventTrackerStore {
*/ */
captureModuleEvent = (props: EventProps) => { captureModuleEvent = (props: EventProps) => {
const { eventName, payload } = props; const { eventName, payload } = props;
const eventPayload: any = getModuleEventPayload({ const eventPayload: any = {
...getModuleEventPayload(payload),
...this.getRequiredProperties, ...this.getRequiredProperties,
...payload,
element: payload.element ?? this.trackElement, element: payload.element ?? this.trackElement,
}); };
posthog?.capture(eventName, eventPayload); posthog?.capture(eventName, eventPayload);
this.setTrackElement(undefined); this.setTrackElement(undefined);
}; };
@ -192,11 +202,11 @@ export class EventTrackerStore implements IEventTrackerStore {
*/ */
capturePageEvent = (props: EventProps) => { capturePageEvent = (props: EventProps) => {
const { eventName, payload } = props; const { eventName, payload } = props;
const eventPayload: any = getPageEventPayload({ const eventPayload: any = {
...getPageEventPayload(payload),
...this.getRequiredProperties, ...this.getRequiredProperties,
...payload,
element: payload.element ?? this.trackElement, element: payload.element ?? this.trackElement,
}); };
posthog?.capture(eventName, eventPayload); posthog?.capture(eventName, eventPayload);
this.setTrackElement(undefined); this.setTrackElement(undefined);
}; };
@ -223,12 +233,30 @@ export class EventTrackerStore implements IEventTrackerStore {
*/ */
captureProjectStateEvent = (props: EventProps) => { captureProjectStateEvent = (props: EventProps) => {
const { eventName, payload } = props; const { eventName, payload } = props;
const eventPayload: any = getProjectStateEventPayload({ const eventPayload: any = {
...getProjectStateEventPayload(payload),
...this.getRequiredProperties, ...this.getRequiredProperties,
...payload,
element: payload.element ?? this.trackElement, element: payload.element ?? this.trackElement,
}); };
posthog?.capture(eventName, eventPayload); posthog?.capture(eventName, eventPayload);
this.setTrackElement(undefined); this.setTrackElement(undefined);
}; };
/**
* @description: Captures the event whenever the issues list is opened.
* @param {string} path
* @param {any} filters
*/
captureIssuesListOpenedEvent = (path: string, filters: any) => {
const eventPayload = {
...getIssuesListOpenedPayload({
path: path,
filters: filters,
}),
...this.getRequiredProperties,
};
posthog?.capture(ISSUES_LIST_OPENED, eventPayload);
this.setTrackElement(undefined);
};
} }