From 46182584c9c2cdd22e301a34b7833d61e209179e Mon Sep 17 00:00:00 2001 From: LAKHAN BAHETI Date: Mon, 27 May 2024 13:28:51 +0530 Subject: [PATCH] added issues list open events from sidebar --- .../roots/archived-issue-layout-root.tsx | 8 +++- .../issue-layouts/roots/cycle-layout-root.tsx | 9 ++++- .../roots/draft-issue-layout-root.tsx | 11 ++++- .../roots/module-layout-root.tsx | 9 ++++- .../roots/project-layout-root.tsx | 9 ++++- .../roots/project-view-layout-root.tsx | 9 ++++- web/constants/event-tracker.ts | 40 ++++++++++++++----- web/store/event-tracker.store.ts | 22 +++++----- 8 files changed, 90 insertions(+), 27 deletions(-) diff --git a/web/components/issues/issue-layouts/roots/archived-issue-layout-root.tsx b/web/components/issues/issue-layouts/roots/archived-issue-layout-root.tsx index 98a4e060b..bcec481be 100644 --- a/web/components/issues/issue-layouts/roots/archived-issue-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/archived-issue-layout-root.tsx @@ -11,6 +11,8 @@ import { IssuePeekOverview, } from "@/components/issues"; import { ListLayoutLoader } from "@/components/ui"; +// constants +import { E_ARCHIVE } from "@/constants/event-tracker"; import { EIssuesStoreType } from "@/constants/issue"; // ui import { useIssues, useEventTracker } from "@/hooks/store"; @@ -28,7 +30,11 @@ export const ArchivedIssueLayoutRoot: React.FC = observer(() => { async () => { if (workspaceSlug && projectId) { await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString()); - captureIssuesListOpenedEvent(router.asPath, issuesFilter?.issueFilters?.filters); + captureIssuesListOpenedEvent({ + filters: issuesFilter?.issueFilters, + element: E_ARCHIVE, + elementId: projectId.toString(), + }); await issues?.fetchIssues( workspaceSlug.toString(), projectId.toString(), diff --git a/web/components/issues/issue-layouts/roots/cycle-layout-root.tsx b/web/components/issues/issue-layouts/roots/cycle-layout-root.tsx index 929eb8ea8..6f83e72b8 100644 --- a/web/components/issues/issue-layouts/roots/cycle-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/cycle-layout-root.tsx @@ -20,8 +20,9 @@ import { } from "@/components/issues"; import { ActiveLoader } from "@/components/ui"; // constants +import { E_CYCLE } from "@/constants/event-tracker"; import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; -import { useCycle, useIssues } from "@/hooks/store"; +import { useCycle, useIssues, useEventTracker } from "@/hooks/store"; // types export const CycleLayoutRoot: React.FC = observer(() => { @@ -30,6 +31,7 @@ export const CycleLayoutRoot: React.FC = observer(() => { // store hooks const { issues, issuesFilter } = useIssues(EIssuesStoreType.CYCLE); const { getCycleById } = useCycle(); + const { captureIssuesListOpenedEvent } = useEventTracker(); // state const [transferIssuesModal, setTransferIssuesModal] = useState(false); @@ -40,6 +42,11 @@ export const CycleLayoutRoot: React.FC = observer(() => { async () => { if (workspaceSlug && projectId && cycleId) { await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString(), cycleId.toString()); + captureIssuesListOpenedEvent({ + filters: issuesFilter?.issueFilters, + element: E_CYCLE, + elementId: cycleId.toString(), + }); await issues?.fetchIssues( workspaceSlug.toString(), projectId.toString(), diff --git a/web/components/issues/issue-layouts/roots/draft-issue-layout-root.tsx b/web/components/issues/issue-layouts/roots/draft-issue-layout-root.tsx index c2cea7a26..c4acb670a 100644 --- a/web/components/issues/issue-layouts/roots/draft-issue-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/draft-issue-layout-root.tsx @@ -5,15 +5,16 @@ import useSWR from "swr"; // hooks import { IssuePeekOverview } from "@/components/issues/peek-overview"; import { ActiveLoader } from "@/components/ui"; +// constants +import { E_DRAFT } from "@/constants/event-tracker"; import { EIssuesStoreType } from "@/constants/issue"; -import { useIssues } from "@/hooks/store"; +import { useIssues, useEventTracker } from "@/hooks/store"; // components import { ProjectDraftEmptyState } from "../empty-states"; import { DraftIssueAppliedFiltersRoot } from "../filters/applied-filters/roots/draft-issue"; import { DraftKanBanLayout } from "../kanban/roots/draft-issue-root"; import { DraftIssueListLayout } from "../list/roots/draft-issue-root"; // ui -// constants export const DraftIssueLayoutRoot: React.FC = observer(() => { // router @@ -21,12 +22,18 @@ export const DraftIssueLayoutRoot: React.FC = observer(() => { const { workspaceSlug, projectId } = router.query; // hooks const { issues, issuesFilter } = useIssues(EIssuesStoreType.DRAFT); + const { captureIssuesListOpenedEvent } = useEventTracker(); useSWR( workspaceSlug && projectId ? `DRAFT_ISSUES_${workspaceSlug.toString()}_${projectId.toString()}` : null, async () => { if (workspaceSlug && projectId) { await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString()); + captureIssuesListOpenedEvent({ + filters: issuesFilter?.issueFilters, + element: E_DRAFT, + elementId: projectId.toString(), + }); await issues?.fetchIssues( workspaceSlug.toString(), projectId.toString(), diff --git a/web/components/issues/issue-layouts/roots/module-layout-root.tsx b/web/components/issues/issue-layouts/roots/module-layout-root.tsx index ed2eafd00..3d8d994b5 100644 --- a/web/components/issues/issue-layouts/roots/module-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/module-layout-root.tsx @@ -18,8 +18,9 @@ import { } from "@/components/issues"; import { ActiveLoader } from "@/components/ui"; // constants +import { E_MODULE } from "@/constants/event-tracker"; import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; -import { useIssues } from "@/hooks/store"; +import { useIssues, useEventTracker } from "@/hooks/store"; // types export const ModuleLayoutRoot: React.FC = observer(() => { @@ -28,6 +29,7 @@ export const ModuleLayoutRoot: React.FC = observer(() => { const { workspaceSlug, projectId, moduleId } = router.query; // hooks const { issues, issuesFilter } = useIssues(EIssuesStoreType.MODULE); + const { captureIssuesListOpenedEvent } = useEventTracker(); useSWR( workspaceSlug && projectId && moduleId @@ -36,6 +38,11 @@ export const ModuleLayoutRoot: React.FC = observer(() => { async () => { if (workspaceSlug && projectId && moduleId) { await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString(), moduleId.toString()); + captureIssuesListOpenedEvent({ + filters: issuesFilter?.issueFilters, + element: E_MODULE, + elementId: moduleId.toString(), + }); await issues?.fetchIssues( workspaceSlug.toString(), projectId.toString(), diff --git a/web/components/issues/issue-layouts/roots/project-layout-root.tsx b/web/components/issues/issue-layouts/roots/project-layout-root.tsx index e153356b8..b41984b95 100644 --- a/web/components/issues/issue-layouts/roots/project-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/project-layout-root.tsx @@ -16,9 +16,10 @@ import { } from "@/components/issues"; import { ActiveLoader } from "@/components/ui"; // constants +import { E_PROJECT } from "@/constants/event-tracker"; import { EIssuesStoreType } from "@/constants/issue"; // hooks -import { useIssues } from "@/hooks/store"; +import { useIssues, useEventTracker } from "@/hooks/store"; export const ProjectLayoutRoot: FC = observer(() => { // router @@ -26,12 +27,18 @@ export const ProjectLayoutRoot: FC = observer(() => { const { workspaceSlug, projectId } = router.query; // hooks const { issues, issuesFilter } = useIssues(EIssuesStoreType.PROJECT); + const { captureIssuesListOpenedEvent } = useEventTracker(); useSWR( workspaceSlug && projectId ? `PROJECT_ISSUES_${workspaceSlug}_${projectId}` : null, async () => { if (workspaceSlug && projectId) { await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString()); + captureIssuesListOpenedEvent({ + filters: issuesFilter?.issueFilters, + element: E_PROJECT, + elementId: projectId.toString(), + }); await issues?.fetchIssues( workspaceSlug.toString(), projectId.toString(), diff --git a/web/components/issues/issue-layouts/roots/project-view-layout-root.tsx b/web/components/issues/issue-layouts/roots/project-view-layout-root.tsx index 62b2b8a8d..a2de200c7 100644 --- a/web/components/issues/issue-layouts/roots/project-view-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/project-view-layout-root.tsx @@ -16,8 +16,9 @@ import { } from "@/components/issues"; import { ActiveLoader } from "@/components/ui"; // constants +import { E_PROJECT_VIEW } from "@/constants/event-tracker"; import { EIssuesStoreType } from "@/constants/issue"; -import { useIssues } from "@/hooks/store"; +import { useIssues, useEventTracker } from "@/hooks/store"; // types export const ProjectViewLayoutRoot: React.FC = observer(() => { @@ -26,12 +27,18 @@ export const ProjectViewLayoutRoot: React.FC = observer(() => { const { workspaceSlug, projectId, viewId } = router.query; // hooks const { issues, issuesFilter } = useIssues(EIssuesStoreType.PROJECT_VIEW); + const { captureIssuesListOpenedEvent } = useEventTracker(); useSWR( workspaceSlug && projectId && viewId ? `PROJECT_VIEW_ISSUES_${workspaceSlug}_${projectId}_${viewId}` : null, async () => { if (workspaceSlug && projectId && viewId) { await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString(), viewId.toString()); + captureIssuesListOpenedEvent({ + filters: issuesFilter?.issueFilters, + element: E_PROJECT_VIEW, + elementId: viewId.toString(), + }); await issues?.fetchIssues( workspaceSlug.toString(), projectId.toString(), diff --git a/web/constants/event-tracker.ts b/web/constants/event-tracker.ts index 52bcbe694..7362fe4a6 100644 --- a/web/constants/event-tracker.ts +++ b/web/constants/event-tracker.ts @@ -1,3 +1,5 @@ +import { IIssueFilters } from "@plane/types"; + export type IssueEventProps = { eventName: string; payload: any; @@ -5,6 +7,12 @@ export type IssueEventProps = { routePath?: string; }; +export type IssuesListOpenedEventProps = { + element: string; + elementId: string; + filters: IIssueFilters | undefined; +}; + export type EventProps = { eventName: string; payload: any; @@ -129,22 +137,23 @@ export const getProjectStateEventPayload = (payload: any) => ({ }); export const getIssuesListOpenedPayload = (payload: any) => ({ - element: elementFromPath(payload.routePath), type: payload.project_id ? "Project" : "Workspace", - layout: payload?.displayFilters?.layout, - filters: payload?.filters, - display_properties: payload?.displayProperties, + layout: payload?.filters?.displayFilters?.layout, + filters: payload?.filters?.filters, + display_properties: payload?.filters?.displayProperties, + workspace_id: payload.workspace_id, + project_id: payload.project_id, }); // Returns the element based on the path const elementFromPath = (routePath?: string) => { - if (routePath?.includes("workspace-views")) return "Workspace view"; - if (routePath?.includes("cycles")) return "Cycle"; - if (routePath?.includes("modules")) return "Module"; - if (routePath?.includes("views")) return "Project view"; - if (routePath?.includes("inbox")) return "Inbox"; - if (routePath?.includes("draft")) return "Draft"; - if (routePath?.includes("archived")) return "Archive"; + if (routePath?.includes("workspace-views")) return E_WORKSPACE_VIEW; + if (routePath?.includes("cycles")) return E_CYCLE; + if (routePath?.includes("modules")) return E_MODULE; + if (routePath?.includes("views")) return E_PROJECT_VIEW; + if (routePath?.includes("inbox")) return E_INBOX; + if (routePath?.includes("draft")) return E_DRAFT; + if (routePath?.includes("archived")) return E_ARCHIVE; return ""; }; @@ -232,3 +241,12 @@ export const SNOOZED_NOTIFICATIONS = "Snoozed notifications viewed"; export const ARCHIVED_NOTIFICATIONS = "Archived notifications viewed"; // Groups export const GROUP_WORKSPACE = "Workspace_metrics"; +// Elements +export const E_PROJECT = "Project"; +export const E_CYCLE = "Cycle"; +export const E_MODULE = "Module"; +export const E_PROJECT_VIEW = "Project view"; +export const E_WORKSPACE_VIEW = "Workspace view"; +export const E_DRAFT = "Draft"; +export const E_ARCHIVE = "Archives"; +export const E_INBOX = "Inbox"; diff --git a/web/store/event-tracker.store.ts b/web/store/event-tracker.store.ts index 3bbccc3d8..1c157af19 100644 --- a/web/store/event-tracker.store.ts +++ b/web/store/event-tracker.store.ts @@ -18,6 +18,7 @@ import { ISSUES_LIST_OPENED, GROUP_WORKSPACE, WORKSPACE_CREATED, + IssuesListOpenedEventProps, } from "@/constants/event-tracker"; import { RootStore } from "./root.store"; @@ -38,7 +39,7 @@ export interface IEventTrackerStore { capturePageEvent: (props: EventProps) => void; captureIssueEvent: (props: IssueEventProps) => void; captureProjectStateEvent: (props: EventProps) => void; - captureIssuesListOpenedEvent: (routePath: string, filters: any) => void; + captureIssuesListOpenedEvent: (props: IssuesListOpenedEventProps) => void; } export class EventTrackerStore implements IEventTrackerStore { @@ -228,15 +229,18 @@ export class EventTrackerStore implements IEventTrackerStore { * @param {string} path * @param {any} filters */ - captureIssuesListOpenedEvent = (routePath: string, filters: any) => { - const eventPayload = { - ...getIssuesListOpenedPayload({ - routePath: routePath, - filters: filters, - }), + captureIssuesListOpenedEvent = (props: IssuesListOpenedEventProps) => { + const { element, elementId, filters } = props; + const eventPayload = getIssuesListOpenedPayload({ + filters: filters, ...this.requiredProperties, - }; - posthog?.capture(ISSUES_LIST_OPENED, eventPayload); + }); + + posthog?.capture(ISSUES_LIST_OPENED, { + ...eventPayload, + element: element, + elementId: elementId, + }); this.setTrackElement(undefined); }; }