chore: added issue open related events

This commit is contained in:
LAKHAN BAHETI 2024-02-29 19:55:32 +05:30
parent b7aeb0f70d
commit d263335a29
21 changed files with 98 additions and 83 deletions

View File

@ -2,7 +2,7 @@ import { useRouter } from "next/router";
import { useEffect } from "react"; import { useEffect } from "react";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
// store hooks // store hooks
import { useEstimate, useLabel } from "hooks/store"; import { useEstimate, useEventTracker, useLabel } from "hooks/store";
// icons // icons
import { Tooltip, BlockedIcon, BlockerIcon, RelatedIcon, LayersIcon, DiceIcon } from "@plane/ui"; import { Tooltip, BlockedIcon, BlockerIcon, RelatedIcon, LayersIcon, DiceIcon } from "@plane/ui";
import { import {
@ -25,10 +25,14 @@ import { renderFormattedDate } from "helpers/date-time.helper";
import { capitalizeFirstLetter } from "helpers/string.helper"; import { capitalizeFirstLetter } from "helpers/string.helper";
// types // types
import { IIssueActivity } from "@plane/types"; import { IIssueActivity } from "@plane/types";
// constants
import { ISSUE_OPENED, elementFromPath } from "constants/event-tracker";
export const IssueLink = ({ activity }: { activity: IIssueActivity }) => { export const IssueLink = ({ activity }: { activity: IIssueActivity }) => {
const router = useRouter(); const router = useRouter();
const { workspaceSlug } = router.query; const { workspaceSlug } = router.query;
// store hooks
const { captureEvent } = useEventTracker();
return ( return (
<Tooltip tooltipContent={activity?.issue_detail ? activity.issue_detail.name : "This issue has been deleted"}> <Tooltip tooltipContent={activity?.issue_detail ? activity.issue_detail.name : "This issue has been deleted"}>
@ -38,6 +42,13 @@ export const IssueLink = ({ activity }: { activity: IIssueActivity }) => {
href={`${`/${workspaceSlug ?? activity.workspace_detail?.slug}/projects/${activity.project}/issues/${ href={`${`/${workspaceSlug ?? activity.workspace_detail?.slug}/projects/${activity.project}/issues/${
activity.issue activity.issue
}`}`} }`}`}
onClick={() => {
captureEvent(ISSUE_OPENED, {
...elementFromPath(router.asPath),
element_id: "activity",
mode: "detail",
});
}}
target={activity.issue === null ? "_self" : "_blank"} target={activity.issue === null ? "_self" : "_blank"}
rel={activity.issue === null ? "" : "noopener noreferrer"} rel={activity.issue === null ? "" : "noopener noreferrer"}
className="inline-flex items-center gap-1 font-medium text-custom-text-100 hover:underline" className="inline-flex items-center gap-1 font-medium text-custom-text-100 hover:underline"

View File

@ -1,6 +1,6 @@
import Link from "next/link"; import Link from "next/link";
// hooks // hooks
import { useIssueDetail } from "hooks/store"; import { useEventTracker, useIssueDetail } from "hooks/store";
// components // components
import { import {
AssignedCompletedIssueListItem, AssignedCompletedIssueListItem,
@ -20,6 +20,8 @@ import { cn } from "helpers/common.helper";
import { getRedirectionFilters } from "helpers/dashboard.helper"; import { getRedirectionFilters } from "helpers/dashboard.helper";
// types // types
import { TAssignedIssuesWidgetResponse, TCreatedIssuesWidgetResponse, TIssue, TIssuesListTypes } from "@plane/types"; import { TAssignedIssuesWidgetResponse, TCreatedIssuesWidgetResponse, TIssue, TIssuesListTypes } from "@plane/types";
// constants
import { ISSUE_OPENED } from "constants/event-tracker";
export type WidgetIssuesListProps = { export type WidgetIssuesListProps = {
isLoading: boolean; isLoading: boolean;
@ -33,9 +35,19 @@ export const WidgetIssuesList: React.FC<WidgetIssuesListProps> = (props) => {
const { isLoading, tab, type, widgetStats, workspaceSlug } = props; const { isLoading, tab, type, widgetStats, workspaceSlug } = props;
// store hooks // store hooks
const { setPeekIssue } = useIssueDetail(); const { setPeekIssue } = useIssueDetail();
const { captureEvent } = useEventTracker();
const handleIssuePeekOverview = (issue: TIssue) => const handleIssuePeekOverview = (issue: TIssue) => {
setPeekIssue({ workspaceSlug, projectId: issue.project_id, issueId: issue.id }); setPeekIssue({ workspaceSlug, projectId: issue.project_id, issueId: issue.id });
captureEvent(ISSUE_OPENED, {
element: "Dashboard",
element_id: tab,
mode: "peek",
filters: {
due_date: issue.target_date,
},
});
};
const filterParams = getRedirectionFilters(tab); const filterParams = getRedirectionFilters(tab);

View File

@ -111,8 +111,7 @@ export const CycleIssuesHeader: React.FC = observer(() => {
updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_FILTERS, { layout: layout }, cycleId).then(() => updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_FILTERS, { layout: layout }, cycleId).then(() =>
captureEvent(LAYOUT_CHANGED, { captureEvent(LAYOUT_CHANGED, {
layout: layout, layout: layout,
element: elementFromPath(router.asPath), ...elementFromPath(router.asPath),
element_id: cycleId,
}) })
); );
}, },
@ -142,7 +141,6 @@ export const CycleIssuesHeader: React.FC = observer(() => {
payload: { payload: {
path: router.asPath, path: router.asPath,
filters: issueFilters, filters: issueFilters,
element_id: cycleId,
filter_property: value, filter_property: value,
filter_type: key, filter_type: key,
}, },
@ -164,7 +162,6 @@ export const CycleIssuesHeader: React.FC = observer(() => {
property: Object.values(updatedDisplayFilter)?.[0], property: Object.values(updatedDisplayFilter)?.[0],
path: router.asPath, path: router.asPath,
filters: issueFilters, filters: issueFilters,
element_id: cycleId,
}, },
}) })
); );
@ -182,7 +179,6 @@ export const CycleIssuesHeader: React.FC = observer(() => {
display_property: Object.keys(property).join(","), display_property: Object.keys(property).join(","),
path: router.asPath, path: router.asPath,
filters: issueFilters, filters: issueFilters,
element_id: cycleId,
}, },
}) })
); );
@ -293,7 +289,6 @@ export const CycleIssuesHeader: React.FC = observer(() => {
path: router.asPath, path: router.asPath,
current_filters: issueFilters?.filters, current_filters: issueFilters?.filters,
layout: issueFilters?.displayFilters?.layout, layout: issueFilters?.displayFilters?.layout,
element_id: cycleId,
}, },
}) })
} }

View File

@ -88,7 +88,6 @@ export const GlobalIssuesHeader: React.FC<Props> = observer((props) => {
payload: { payload: {
path: router.asPath, path: router.asPath,
filters: issueFilters, filters: issueFilters,
element_id: globalViewId,
filter_property: value, filter_property: value,
filter_type: key, filter_type: key,
}, },
@ -115,7 +114,6 @@ export const GlobalIssuesHeader: React.FC<Props> = observer((props) => {
property: Object.values(updatedDisplayFilter)?.[0], property: Object.values(updatedDisplayFilter)?.[0],
path: router.asPath, path: router.asPath,
filters: issueFilters, filters: issueFilters,
element_id: globalViewId,
}, },
}) })
); );
@ -139,7 +137,6 @@ export const GlobalIssuesHeader: React.FC<Props> = observer((props) => {
display_property: Object.keys(property).join(","), display_property: Object.keys(property).join(","),
path: router.asPath, path: router.asPath,
filters: issueFilters, filters: issueFilters,
element_id: globalViewId,
}, },
}) })
); );
@ -212,7 +209,6 @@ export const GlobalIssuesHeader: React.FC<Props> = observer((props) => {
path: router.asPath, path: router.asPath,
current_filters: issueFilters?.filters, current_filters: issueFilters?.filters,
layout: issueFilters?.displayFilters?.layout, layout: issueFilters?.displayFilters?.layout,
element_id: globalViewId,
}, },
}) })
} }

View File

@ -114,8 +114,7 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_FILTERS, { layout: layout }, moduleId).then(() => updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_FILTERS, { layout: layout }, moduleId).then(() =>
captureEvent(LAYOUT_CHANGED, { captureEvent(LAYOUT_CHANGED, {
layout: layout, layout: layout,
element: elementFromPath(router.asPath), ...elementFromPath(router.asPath),
element_id: moduleId,
}) })
); );
}, },
@ -145,7 +144,6 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
payload: { payload: {
path: router.asPath, path: router.asPath,
filters: issueFilters, filters: issueFilters,
element_id: moduleId,
filter_property: value, filter_property: value,
filter_type: key, filter_type: key,
}, },
@ -167,7 +165,6 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
property: Object.values(updatedDisplayFilter)?.[0], property: Object.values(updatedDisplayFilter)?.[0],
path: router.asPath, path: router.asPath,
filters: issueFilters, filters: issueFilters,
element_id: moduleId,
}, },
}) })
); );
@ -185,7 +182,6 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
display_property: Object.keys(property).join(","), display_property: Object.keys(property).join(","),
path: router.asPath, path: router.asPath,
filters: issueFilters, filters: issueFilters,
element_id: moduleId,
}, },
}) })
); );
@ -297,7 +293,6 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
path: router.asPath, path: router.asPath,
current_filters: issueFilters?.filters, current_filters: issueFilters?.filters,
layout: issueFilters?.displayFilters?.layout, layout: issueFilters?.displayFilters?.layout,
element_id: moduleId,
}, },
}) })
} }

View File

@ -89,7 +89,6 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
payload: { payload: {
path: router.asPath, path: router.asPath,
filters: issueFilters, filters: issueFilters,
element_id: projectId,
filter_property: value, filter_property: value,
filter_type: key, filter_type: key,
}, },
@ -105,8 +104,7 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_FILTERS, { layout: layout }).then(() => updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_FILTERS, { layout: layout }).then(() =>
captureEvent(LAYOUT_CHANGED, { captureEvent(LAYOUT_CHANGED, {
layout: layout, layout: layout,
element: elementFromPath(router.asPath), ...elementFromPath(router.asPath),
element_id: projectId,
}) })
); );
}, },
@ -124,7 +122,6 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
property: Object.values(updatedDisplayFilter)?.[0], property: Object.values(updatedDisplayFilter)?.[0],
path: router.asPath, path: router.asPath,
filters: issueFilters, filters: issueFilters,
element_id: projectId,
}, },
}) })
); );
@ -142,7 +139,6 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
display_property: Object.keys(property).join(","), display_property: Object.keys(property).join(","),
path: router.asPath, path: router.asPath,
filters: issueFilters, filters: issueFilters,
element_id: projectId,
}, },
}); });
}); });
@ -242,7 +238,6 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
path: router.asPath, path: router.asPath,
current_filters: issueFilters?.filters, current_filters: issueFilters?.filters,
layout: issueFilters?.displayFilters?.layout, layout: issueFilters?.displayFilters?.layout,
element_id: projectId,
}, },
}) })
} }

View File

@ -76,8 +76,7 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_FILTERS, { layout: layout }, viewId).then(() => updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_FILTERS, { layout: layout }, viewId).then(() =>
captureEvent(LAYOUT_CHANGED, { captureEvent(LAYOUT_CHANGED, {
layout: layout, layout: layout,
element: elementFromPath(router.asPath), ...elementFromPath(router.asPath),
element_id: viewId,
}) })
); );
}, },
@ -107,7 +106,6 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
payload: { payload: {
path: router.asPath, path: router.asPath,
filters: issueFilters, filters: issueFilters,
element_id: viewId,
filter_property: value, filter_property: value,
filter_type: key, filter_type: key,
}, },
@ -128,7 +126,6 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
property: Object.values(updatedDisplayFilter)?.[0], property: Object.values(updatedDisplayFilter)?.[0],
path: router.asPath, path: router.asPath,
filters: issueFilters, filters: issueFilters,
element_id: viewId,
}, },
}) })
); );
@ -146,7 +143,6 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
display_property: Object.keys(property).join(","), display_property: Object.keys(property).join(","),
path: router.asPath, path: router.asPath,
filters: issueFilters, filters: issueFilters,
element_id: viewId,
}, },
}) })
); );
@ -257,7 +253,6 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
path: router.asPath, path: router.asPath,
current_filters: issueFilters?.filters, current_filters: issueFilters?.filters,
layout: issueFilters?.displayFilters?.layout, layout: issueFilters?.displayFilters?.layout,
element_id: projectId,
}, },
}) })
} }

View File

@ -106,7 +106,6 @@ export const AllIssueLayoutRoot: React.FC = observer(() => {
await fetchFilters(workspaceSlug.toString(), globalViewId.toString()); await fetchFilters(workspaceSlug.toString(), globalViewId.toString());
captureIssuesListOpenedEvent({ captureIssuesListOpenedEvent({
path: router.asPath, path: router.asPath,
element_id: globalViewId,
}); });
await fetchIssues(workspaceSlug.toString(), globalViewId.toString(), issueIds ? "mutation" : "init-loader"); await fetchIssues(workspaceSlug.toString(), globalViewId.toString(), issueIds ? "mutation" : "init-loader");
routerFilterParams(); routerFilterParams();
@ -247,7 +246,7 @@ export const AllIssueLayoutRoot: React.FC = observer(() => {
viewId={globalViewId} viewId={globalViewId}
/> />
{/* peek overview */} {/* peek overview */}
<IssuePeekOverview /> <IssuePeekOverview issuesFilter={issueFilters} />
</Fragment> </Fragment>
)} )}
</div> </div>

View File

@ -31,7 +31,6 @@ export const ArchivedIssueLayoutRoot: React.FC = observer(() => {
captureIssuesListOpenedEvent({ captureIssuesListOpenedEvent({
path: router.asPath, path: router.asPath,
filters: issuesFilter?.issueFilters?.filters, filters: issuesFilter?.issueFilters?.filters,
element_id: projectId,
}); });
await issues?.fetchIssues( await issues?.fetchIssues(
workspaceSlug.toString(), workspaceSlug.toString(),
@ -61,7 +60,7 @@ export const ArchivedIssueLayoutRoot: React.FC = observer(() => {
<div className="relative h-full w-full overflow-auto"> <div className="relative h-full w-full overflow-auto">
<ArchivedIssueListLayout /> <ArchivedIssueListLayout />
</div> </div>
<IssuePeekOverview is_archived /> <IssuePeekOverview issuesFilter={issuesFilter.issueFilters} is_archived />
</Fragment> </Fragment>
)} )}
</div> </div>

View File

@ -44,7 +44,6 @@ export const CycleLayoutRoot: React.FC = observer(() => {
captureIssuesListOpenedEvent({ captureIssuesListOpenedEvent({
path: router.asPath, path: router.asPath,
filters: issuesFilter?.issueFilters?.filters, filters: issuesFilter?.issueFilters?.filters,
element_id: cycleId,
}); });
await issues?.fetchIssues( await issues?.fetchIssues(
workspaceSlug.toString(), workspaceSlug.toString(),
@ -132,7 +131,7 @@ export const CycleLayoutRoot: React.FC = observer(() => {
) : null} ) : null}
</div> </div>
{/* peek overview */} {/* peek overview */}
<IssuePeekOverview /> <IssuePeekOverview issuesFilter={issuesFilter.issueFilters}/>
</Fragment> </Fragment>
)} )}
</div> </div>

View File

@ -31,7 +31,6 @@ export const DraftIssueLayoutRoot: React.FC = observer(() => {
captureIssuesListOpenedEvent({ captureIssuesListOpenedEvent({
path: router.asPath, path: router.asPath,
filters: issuesFilter?.issueFilters?.filters, filters: issuesFilter?.issueFilters?.filters,
element_id: projectId,
}); });
await issues?.fetchIssues( await issues?.fetchIssues(
workspaceSlug.toString(), workspaceSlug.toString(),
@ -67,7 +66,7 @@ export const DraftIssueLayoutRoot: React.FC = observer(() => {
<DraftKanBanLayout /> <DraftKanBanLayout />
) : null} ) : null}
{/* issue peek overview */} {/* issue peek overview */}
<IssuePeekOverview is_draft /> <IssuePeekOverview issuesFilter={issuesFilter.issueFilters} is_draft />
</div> </div>
)} )}
</div> </div>

View File

@ -40,7 +40,6 @@ export const ModuleLayoutRoot: React.FC = observer(() => {
captureIssuesListOpenedEvent({ captureIssuesListOpenedEvent({
path: router.asPath, path: router.asPath,
filters: issuesFilter?.issueFilters?.filters, filters: issuesFilter?.issueFilters?.filters,
element_id: moduleId,
}) })
await issues?.fetchIssues( await issues?.fetchIssues(
workspaceSlug.toString(), workspaceSlug.toString(),
@ -117,7 +116,7 @@ export const ModuleLayoutRoot: React.FC = observer(() => {
) : null} ) : null}
</div> </div>
{/* peek overview */} {/* peek overview */}
<IssuePeekOverview /> <IssuePeekOverview issuesFilter={issuesFilter.issueFilters}/>
</Fragment> </Fragment>
)} )}
</div> </div>

View File

@ -38,7 +38,6 @@ export const ProjectLayoutRoot: FC = observer(() => {
captureIssuesListOpenedEvent({ captureIssuesListOpenedEvent({
path: router.asPath, path: router.asPath,
filters: issuesFilter?.issueFilters?.filters, filters: issuesFilter?.issueFilters?.filters,
element_id: projectId,
}); });
await issues?.fetchIssues( await issues?.fetchIssues(
workspaceSlug.toString(), workspaceSlug.toString(),
@ -87,7 +86,7 @@ export const ProjectLayoutRoot: FC = observer(() => {
</div> </div>
{/* peek overview */} {/* peek overview */}
<IssuePeekOverview /> <IssuePeekOverview issuesFilter={issuesFilter.issueFilters} />
</Fragment> </Fragment>
)} )}
</div> </div>

View File

@ -38,7 +38,6 @@ export const ProjectViewLayoutRoot: React.FC = observer(() => {
captureIssuesListOpenedEvent({ captureIssuesListOpenedEvent({
path: router.asPath, path: router.asPath,
filters: issuesFilter?.issueFilters?.filters, filters: issuesFilter?.issueFilters?.filters,
element_id: viewId,
}); });
await issues?.fetchIssues( await issues?.fetchIssues(
workspaceSlug.toString(), workspaceSlug.toString(),
@ -100,7 +99,7 @@ export const ProjectViewLayoutRoot: React.FC = observer(() => {
</div> </div>
{/* peek overview */} {/* peek overview */}
<IssuePeekOverview /> <IssuePeekOverview issuesFilter={issuesFilter.issueFilters}/>
</Fragment> </Fragment>
)} )}
</div> </div>

View File

@ -9,12 +9,14 @@ import { copyUrlToClipboard } from "helpers/string.helper";
// hooks // hooks
import useToast from "hooks/use-toast"; import useToast from "hooks/use-toast";
// store hooks // store hooks
import { useIssueDetail, useProjectState, useUser } from "hooks/store"; import { useEventTracker, useIssueDetail, useProjectState, useUser } from "hooks/store";
// helpers // helpers
import { cn } from "helpers/common.helper"; import { cn } from "helpers/common.helper";
// components // components
import { IssueSubscription, IssueUpdateStatus } from "components/issues"; import { IssueSubscription, IssueUpdateStatus } from "components/issues";
import { STATE_GROUPS } from "constants/state"; import { STATE_GROUPS } from "constants/state";
// constants
import { ISSUE_OPENED, elementFromPath } from "constants/event-tracker";
export type TPeekModes = "side-peek" | "modal" | "full-screen"; export type TPeekModes = "side-peek" | "modal" | "full-screen";
@ -74,6 +76,7 @@ export const IssuePeekOverviewHeader: FC<PeekOverviewHeaderProps> = observer((pr
issue: { getIssueById }, issue: { getIssueById },
} = useIssueDetail(); } = useIssueDetail();
const { getStateById } = useProjectState(); const { getStateById } = useProjectState();
const { captureEvent } = useEventTracker();
// hooks // hooks
const { setToastAlert } = useToast(); const { setToastAlert } = useToast();
// derived values // derived values
@ -97,6 +100,11 @@ export const IssuePeekOverviewHeader: FC<PeekOverviewHeaderProps> = observer((pr
const redirectToIssueDetail = () => { const redirectToIssueDetail = () => {
router.push({ pathname: `/${issueLink}` }); router.push({ pathname: `/${issueLink}` });
removeRoutePeekId(); removeRoutePeekId();
captureEvent(ISSUE_OPENED, {
...elementFromPath(router.asPath),
element: "peek",
mode: "detail",
});
}; };
// auth // auth
const isArchivingAllowed = !isArchived && !disabled; const isArchivingAllowed = !isArchived && !disabled;

View File

@ -7,15 +7,23 @@ import { useEventTracker, useIssueDetail, useIssues, useUser } from "hooks/store
// components // components
import { IssueView } from "components/issues"; import { IssueView } from "components/issues";
// types // types
import { TIssue } from "@plane/types"; import { IIssueFilters, TIssue } from "@plane/types";
// constants // constants
import { EUserProjectRoles } from "constants/project"; import { EUserProjectRoles } from "constants/project";
import { EIssuesStoreType } from "constants/issue"; import { EIssuesStoreType } from "constants/issue";
import { ISSUE_UPDATED, ISSUE_DELETED, ISSUE_ARCHIVED, ISSUE_RESTORED } from "constants/event-tracker"; import {
ISSUE_UPDATED,
ISSUE_DELETED,
ISSUE_ARCHIVED,
ISSUE_RESTORED,
elementFromPath,
ISSUE_OPENED,
} from "constants/event-tracker";
interface IIssuePeekOverview { interface IIssuePeekOverview {
is_archived?: boolean; is_archived?: boolean;
is_draft?: boolean; is_draft?: boolean;
issuesFilter?: IIssueFilters;
} }
export type TIssuePeekOperations = { export type TIssuePeekOperations = {
@ -48,11 +56,12 @@ export type TIssuePeekOperations = {
}; };
export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => { export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
const { is_archived = false, is_draft = false } = props; const { is_archived = false, is_draft = false, issuesFilter } = props;
// hooks // hooks
const { setToastAlert } = useToast(); const { setToastAlert } = useToast();
// router // router
const router = useRouter(); const router = useRouter();
const { userId } = router.query;
const { const {
membership: { currentWorkspaceAllProjectsRole }, membership: { currentWorkspaceAllProjectsRole },
} = useUser(); } = useUser();
@ -68,7 +77,7 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
} = useIssueDetail(); } = useIssueDetail();
const { addIssueToCycle, removeIssueFromCycle, addModulesToIssue, removeIssueFromModule, removeModulesFromIssue } = const { addIssueToCycle, removeIssueFromCycle, addModulesToIssue, removeIssueFromModule, removeModulesFromIssue } =
useIssueDetail(); useIssueDetail();
const { captureIssueEvent } = useEventTracker(); const { captureEvent, captureIssueEvent } = useEventTracker();
// state // state
const [loader, setLoader] = useState(false); const [loader, setLoader] = useState(false);
@ -387,6 +396,19 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
} }
}, [peekIssue, issueOperations]); }, [peekIssue, issueOperations]);
useEffect(() => {
if (peekIssue && issuesFilter) {
captureEvent(ISSUE_OPENED, {
layout: issuesFilter?.displayFilters?.layout,
display_properties: issuesFilter?.displayFilters,
filters: issuesFilter?.filters,
mode: "peek",
profile_id: userId,
...elementFromPath(router.asPath),
});
}
}, [peekIssue, userId, captureEvent, router.asPath]);
if (!peekIssue?.workspaceSlug || !peekIssue?.projectId || !peekIssue?.issueId) return <></>; if (!peekIssue?.workspaceSlug || !peekIssue?.projectId || !peekIssue?.issueId) return <></>;
const issue = getIssueById(peekIssue.issueId) || undefined; const issue = getIssueById(peekIssue.issueId) || undefined;

View File

@ -23,6 +23,8 @@ type NotificationCardProps = {
selectedTab: NotificationType; selectedTab: NotificationType;
notification: IUserNotification; notification: IUserNotification;
isSnoozedTabOpen: boolean; isSnoozedTabOpen: boolean;
isArchivedTabOpen: boolean;
isUnreadTabOpen: boolean;
closePopover: () => void; closePopover: () => void;
markNotificationReadStatus: (notificationId: string) => Promise<void>; markNotificationReadStatus: (notificationId: string) => Promise<void>;
markNotificationReadStatusToggle: (notificationId: string) => Promise<void>; markNotificationReadStatusToggle: (notificationId: string) => Promise<void>;
@ -36,6 +38,8 @@ export const NotificationCard: React.FC<NotificationCardProps> = (props) => {
selectedTab, selectedTab,
notification, notification,
isSnoozedTabOpen, isSnoozedTabOpen,
isArchivedTabOpen,
isUnreadTabOpen,
closePopover, closePopover,
markNotificationReadStatus, markNotificationReadStatus,
markNotificationReadStatusToggle, markNotificationReadStatusToggle,
@ -127,7 +131,14 @@ export const NotificationCard: React.FC<NotificationCardProps> = (props) => {
markNotificationReadStatus(notification.id); markNotificationReadStatus(notification.id);
captureEvent(ISSUE_OPENED, { captureEvent(ISSUE_OPENED, {
issue_id: notification.data.issue.id, issue_id: notification.data.issue.id,
element: "notification", element: "Notification",
element_id: isArchivedTabOpen
? "archived"
: isSnoozedTabOpen
? "snoozed"
: isUnreadTabOpen
? "unread"
: selectedTab,
}); });
closePopover(); closePopover();
}} }}

View File

@ -132,6 +132,8 @@ export const NotificationPopover = observer(() => {
selectedTab={selectedTab} selectedTab={selectedTab}
key={notification.id} key={notification.id}
isSnoozedTabOpen={snoozed} isSnoozedTabOpen={snoozed}
isArchivedTabOpen={archived}
isUnreadTabOpen={readNotification}
closePopover={() => setIsActive(false)} closePopover={() => setIsActive(false)}
notification={notification} notification={notification}
markNotificationArchivedStatus={markNotificationArchivedStatus} markNotificationArchivedStatus={markNotificationArchivedStatus}

View File

@ -88,7 +88,7 @@ export const ProfileIssuesPage = observer((props: IProfileIssuesPage) => {
) : null} ) : null}
</div> </div>
{/* peek overview */} {/* peek overview */}
<IssuePeekOverview /> <IssuePeekOverview issuesFilter={issueFilters}/>
</> </>
); );
}); });

View File

@ -54,21 +54,6 @@ export const GlobalViewsHeader: React.FC = observer(() => {
// bring the active view to the centre of the header // bring the active view to the centre of the header
useEffect(() => { useEffect(() => {
<<<<<<< HEAD
if (!globalViewId) return;
captureEvent(GLOBAL_VIEW_OPENED, {
view_id: globalViewId,
view_type: ["all-issues", "assigned", "created", "subscribed"].includes(globalViewId.toString())
? "Default"
: "Custom",
});
const activeTabElement = document.querySelector(`#global-view-${globalViewId.toString()}`);
if (activeTabElement) activeTabElement.scrollIntoView({ behavior: "smooth", inline: "center" });
}, [globalViewId, captureEvent]);
=======
if (globalViewId && currentWorkspaceViews) { if (globalViewId && currentWorkspaceViews) {
captureEvent(GLOBAL_VIEW_OPENED, { captureEvent(GLOBAL_VIEW_OPENED, {
view_id: globalViewId, view_id: globalViewId,
@ -85,7 +70,6 @@ export const GlobalViewsHeader: React.FC = observer(() => {
} }
} }
}, [globalViewId, currentWorkspaceViews, containerRef]); }, [globalViewId, currentWorkspaceViews, containerRef]);
>>>>>>> 62693abb0992a35f2cd57c7caf8b94304c2756f7
const isAuthorizedUser = !!currentWorkspaceRole && currentWorkspaceRole >= EUserWorkspaceRoles.MEMBER; const isAuthorizedUser = !!currentWorkspaceRole && currentWorkspaceRole >= EUserWorkspaceRoles.MEMBER;

View File

@ -124,8 +124,7 @@ export const getProjectStateEventPayload = (payload: any) => {
}; };
export const getIssuesListOpenedPayload = (payload: any) => ({ export const getIssuesListOpenedPayload = (payload: any) => ({
element: elementFromPath(payload.path), ...elementFromPath(payload?.path),
element_id: payload.element_id,
layout: payload?.displayFilters?.layout, layout: payload?.displayFilters?.layout,
filters: payload?.filters, filters: payload?.filters,
display_properties: payload?.displayProperties, display_properties: payload?.displayProperties,
@ -136,8 +135,7 @@ export const getIssuesFilterEventPayload = (payload: any) => ({
filter_property: payload?.filter_property, filter_property: payload?.filter_property,
layout: payload?.filters?.displayFilters?.layout, layout: payload?.filters?.displayFilters?.layout,
current_filters: payload?.filters?.filters, current_filters: payload?.filters?.filters,
element: elementFromPath(payload.path), ...elementFromPath(payload?.path),
element_id: payload.element_id,
}); });
export const getIssuesDisplayFilterPayload = (payload: any) => { export const getIssuesDisplayFilterPayload = (payload: any) => {
@ -150,8 +148,7 @@ export const getIssuesDisplayFilterPayload = (payload: any) => {
return { return {
layout: payload?.filters?.displayFilters?.layout, layout: payload?.filters?.displayFilters?.layout,
current_display_properties: payload?.filters?.displayProperties, current_display_properties: payload?.filters?.displayProperties,
element: elementFromPath(payload.path), ...elementFromPath(payload?.path),
element_id: payload.element_id,
display_property: payload.display_property, display_property: payload.display_property,
property: property, property: property,
property_type: payload.property_type, property_type: payload.property_type,
@ -159,13 +156,10 @@ export const getIssuesDisplayFilterPayload = (payload: any) => {
}; };
export const elementFromPath = (path?: string) => { export const elementFromPath = (path?: string) => {
if (!path) path = path?.split("?")?.[0];
return { if (!path) return;
element: "Project",
element_id: path?.split("/").at(-2),
};
let element = "Project"; let element = "Dashboard";
if (path.includes("workspace-views")) element = "Global view"; if (path.includes("workspace-views")) element = "Global view";
else if (path.includes("cycles")) element = "Cycle"; else if (path.includes("cycles")) element = "Cycle";
else if (path.includes("modules")) element = "Module"; else if (path.includes("modules")) element = "Module";
@ -175,12 +169,11 @@ export const elementFromPath = (path?: string) => {
else if (path.includes("inbox")) element = "Inbox"; else if (path.includes("inbox")) element = "Inbox";
else if (path.includes("draft")) element = "Draft"; else if (path.includes("draft")) element = "Draft";
else if (path.includes("archived")) element = "Archive"; else if (path.includes("archived")) element = "Archive";
else if (path.includes("projects")) element = "Project";
return { return {
element: element, element: element,
element_id: ["Project", "Draft", "Archive"].includes(element) element_id: ["Project", "Draft", "Archive"].includes(element) ? path.split("/").at(-2) : path.split("/").at(-1),
? path.split("/").at(-2)
: path.split("/").at(-1),
}; };
}; };
@ -217,6 +210,9 @@ 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";
export const ISSUE_ARCHIVED = "Issue archived";
export const ISSUE_RESTORED = "Issue restored";
// Issue Checkout Events // Issue Checkout Events
export const ISSUES_LIST_OPENED = "Issues list opened"; export const ISSUES_LIST_OPENED = "Issues list opened";
export const ISSUE_OPENED = "Issue opened"; export const ISSUE_OPENED = "Issue opened";