Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 12 additions & 35 deletions packages/constants/src/event-tracker/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,6 @@ export type EventProps = {
path?: string;
};

export const getWorkspaceEventPayload = (payload: any) => ({
workspace_id: payload.id,
created_at: payload.created_at,
updated_at: payload.updated_at,
organization_size: payload.organization_size,
first_time: payload.first_time,
state: payload.state,
element: payload.element,
});

export const getProjectEventPayload = (payload: any) => ({
workspace_id: payload.workspace_id,
project_id: payload.id,
Expand All @@ -35,20 +25,6 @@ export const getProjectEventPayload = (payload: any) => ({
element: payload.element,
});

export const getCycleEventPayload = (payload: any) => ({
workspace_id: payload.workspace_id,
project_id: payload.project,
cycle_id: payload.id,
created_at: payload.created_at,
updated_at: payload.updated_at,
start_date: payload.start_date,
target_date: payload.target_date,
cycle_status: payload.status,
changed_properties: payload.changed_properties,
state: payload.state,
element: payload.element,
});

export const getModuleEventPayload = (payload: any) => ({
workspace_id: payload.workspace_id,
project_id: payload.project,
Expand Down Expand Up @@ -147,16 +123,6 @@ export const GITHUB_REDIRECTED_TRACKER_EVENT = "github_redirected";
// Groups
export const GROUP_WORKSPACE_TRACKER_EVENT = "workspace_metrics";

export const TRACKING_ELEMENTS = {
RIGHT_HEADER_BUTTON: "right_header_button",
EMPTY_STATE_BUTTON: "empty_state_button",
COMMAND_PALETTE_ITEM: "command_palette_item",
RIGHT_SIDEBAR: "right_sidebar",
QUICK_ACTIONS: "quick_actions",
CONTEXT_MENU: "context_menu",
} as const;
export type TTrackingElement = (typeof TRACKING_ELEMENTS)[keyof typeof TRACKING_ELEMENTS];

export const WORKSPACE_TRACKER_EVENTS = {
create: "workspace_created",
update: "workspace_updated",
Expand All @@ -175,7 +141,18 @@ export const CYCLE_TRACKER_EVENTS = {
delete: "cycle_deleted",
favorite: "cycle_favorited",
unfavorite: "cycle_unfavorited",
};
archive: "cycle_archived",
restore: "cycle_restored",
};
export const CYCLE_TRACKER_ELEMENTS = {
RIGHT_HEADER_ADD_BUTTON: "right_header_add_cycle_button",
EMPTY_STATE_ADD_BUTTON: "empty_state_add_cycle_button",
COMMAND_PALETTE_ADD_ITEM: "command_palette_add_cycle_item",
RIGHT_SIDEBAR: "cycle_right_sidebar",
QUICK_ACTIONS: "cycle_quick_actions",
CONTEXT_MENU: "cycle_context_menu",
LIST_ITEM: "cycle_list_item",
} as const;

export const MODULE_TRACKER_EVENTS = {
create: "module_created",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { FC } from "react";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// ui
import { EProjectFeatureKey, EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { EProjectFeatureKey, EUserPermissions, EUserPermissionsLevel, CYCLE_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Breadcrumbs, Button, Header } from "@plane/ui";
// components
import { CyclesViewHeader } from "@/components/cycles";
// hooks
import { useCommandPalette, useEventTracker, useProject, useUserPermissions } from "@/hooks/store";
import { useCommandPalette, useProject, useUserPermissions } from "@/hooks/store";
import { useAppRouter } from "@/hooks/use-app-router";
// plane web
import { CommonProjectBreadcrumbs } from "@/plane-web/components/breadcrumbs/common";
Expand All @@ -23,7 +23,6 @@ export const CyclesListHeader: FC = observer(() => {

// store hooks
const { toggleCreateCycleModal } = useCommandPalette();
const { setTrackElement } = useEventTracker();
const { allowPermissions } = useUserPermissions();
const { currentProjectDetails, loader } = useProject();
const { t } = useTranslation();
Expand Down Expand Up @@ -51,8 +50,8 @@ export const CyclesListHeader: FC = observer(() => {
<Button
variant="primary"
size="sm"
data-ph-element={CYCLE_TRACKER_ELEMENTS.RIGHT_HEADER_ADD_BUTTON}
onClick={() => {
setTrackElement("Cycles page");
toggleCreateCycleModal(true);
}}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useState } from "react";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// plane imports
import { EUserPermissionsLevel, EUserProjectRoles } from "@plane/constants";
import { EUserPermissionsLevel, EUserProjectRoles, CYCLE_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { TCycleFilters } from "@plane/types";
// components
Expand All @@ -16,15 +16,14 @@ import { ComicBoxButton, DetailedEmptyState } from "@/components/empty-state";
import { CycleModuleListLayout } from "@/components/ui";
// helpers
// hooks
import { useEventTracker, useCycle, useProject, useCycleFilter, useUserPermissions } from "@/hooks/store";
import { useCycle, useProject, useCycleFilter, useUserPermissions } from "@/hooks/store";
import { useAppRouter } from "@/hooks/use-app-router";
import { useResolvedAssetPath } from "@/hooks/use-resolved-asset-path";

const ProjectCyclesPage = observer(() => {
// states
const [createModal, setCreateModal] = useState(false);
// store hooks
const { setTrackElement } = useEventTracker();
const { currentProjectCycleIds, loader } = useCycle();
const { getProjectById, currentProjectDetails } = useProject();
// router
Expand Down Expand Up @@ -100,8 +99,8 @@ const ProjectCyclesPage = observer(() => {
label={t("project_cycles.empty_state.general.primary_button.text")}
title={t("project_cycles.empty_state.general.primary_button.comic.title")}
description={t("project_cycles.empty_state.general.primary_button.comic.description")}
data-ph-element={CYCLE_TRACKER_ELEMENTS.EMPTY_STATE_ADD_BUTTON}
onClick={() => {
setTrackElement("Cycle empty state");
setCreateModal(true);
}}
disabled={!hasMemberLevelPermission}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ export const ModulesListHeader: React.FC = observer(() => {
<Button
variant="primary"
size="sm"
data-ph-element="RIGHT_HEADER_BUTTON"
onClick={() => {
setTrackElement("Modules page");
toggleCreateModuleModal(true);
Expand Down
7 changes: 6 additions & 1 deletion web/ce/helpers/command-palette.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// types
import { CYCLE_TRACKER_ELEMENTS } from "@plane/constants";
import { TCommandPaletteActionList, TCommandPaletteShortcut, TCommandPaletteShortcutList } from "@plane/types";
// store
import { captureClick } from "@/helpers/event-tracker.helper";
import { store } from "@/lib/store-context";

export const getGlobalShortcutsList: () => TCommandPaletteActionList = () => {
Expand Down Expand Up @@ -50,7 +52,10 @@ export const getProjectShortcutsList: () => TCommandPaletteActionList = () => {
q: {
title: "Create a new cycle",
description: "Create a new cycle in the current project",
action: () => toggleCreateCycleModal(true),
action: () => {
toggleCreateCycleModal(true);
captureClick({ elementName: CYCLE_TRACKER_ELEMENTS.COMMAND_PALETTE_ADD_ITEM });
},
},
v: {
title: "Create a new view",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
import { Command } from "cmdk";
import { ContrastIcon, FileText, Layers } from "lucide-react";
// hooks
import { CYCLE_TRACKER_ELEMENTS } from "@plane/constants";
import { DiceIcon } from "@plane/ui";
import { useCommandPalette, useEventTracker } from "@/hooks/store";
import { useCommandPalette } from "@/hooks/store";
// ui

type Props = {
Expand All @@ -16,15 +17,14 @@ export const CommandPaletteProjectActions: React.FC<Props> = (props) => {
// store hooks
const { toggleCreateCycleModal, toggleCreateModuleModal, toggleCreatePageModal, toggleCreateViewModal } =
useCommandPalette();
const { setTrackElement } = useEventTracker();

return (
<>
<Command.Group heading="Cycle">
<Command.Item
data-ph-element={CYCLE_TRACKER_ELEMENTS.COMMAND_PALETTE_ADD_ITEM}
onSelect={() => {
closePalette();
setTrackElement("Command palette");
toggleCreateCycleModal(true);
}}
className="focus:outline-none"
Expand All @@ -40,7 +40,6 @@ export const CommandPaletteProjectActions: React.FC<Props> = (props) => {
<Command.Item
onSelect={() => {
closePalette();
setTrackElement("Command palette");
toggleCreateModuleModal(true);
}}
className="focus:outline-none"
Expand All @@ -56,7 +55,6 @@ export const CommandPaletteProjectActions: React.FC<Props> = (props) => {
<Command.Item
onSelect={() => {
closePalette();
setTrackElement("Command palette");
toggleCreateViewModal(true);
}}
className="focus:outline-none"
Expand All @@ -72,7 +70,6 @@ export const CommandPaletteProjectActions: React.FC<Props> = (props) => {
<Command.Item
onSelect={() => {
closePalette();
setTrackElement("Command palette");
toggleCreatePageModal({ isOpen: true });
}}
className="focus:outline-none"
Expand Down
75 changes: 32 additions & 43 deletions web/core/components/cycles/analytics-sidebar/sidebar-header.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
"use client";

import React, { FC, useEffect, useState } from "react";
import React, { FC, useEffect } from "react";
import { observer } from "mobx-react";
import { Controller, useForm } from "react-hook-form";
import { ArrowRight, ChevronRight } from "lucide-react";
// Plane Imports
import { CYCLE_TRACKER_EVENTS, CYCLE_STATUS, EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import {
CYCLE_TRACKER_EVENTS,
CYCLE_STATUS,
EUserPermissions,
EUserPermissionsLevel,
CYCLE_TRACKER_ELEMENTS,
} from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { ICycle } from "@plane/types";
import { setToast, TOAST_TYPE } from "@plane/ui";
import { getDate, renderFormattedPayloadDate } from "@plane/utils";
// components
import { DateRangeDropdown } from "@/components/dropdowns";
// hooks
import { useCycle, useEventTracker, useUserPermissions } from "@/hooks/store";
import { captureElementAndEvent } from "@/helpers/event-tracker.helper";
import { useCycle, useUserPermissions } from "@/hooks/store";
import { useTimeZoneConverter } from "@/hooks/use-timezone-converter";
// services
import { CycleService } from "@/services/cycle.service";
// local imports
import { ArchiveCycleModal } from "../archived-cycles";
import { CycleDeleteModal } from "../delete-modal";

type Props = {
workspaceSlug: string;
Expand All @@ -38,13 +42,9 @@ const cycleService = new CycleService();

export const CycleSidebarHeader: FC<Props> = observer((props) => {
const { workspaceSlug, projectId, cycleDetails, handleClose, isArchived = false } = props;
// states
const [archiveCycleModal, setArchiveCycleModal] = useState(false);
const [cycleDeleteModal, setCycleDeleteModal] = useState(false);
// hooks
const { allowPermissions } = useUserPermissions();
const { updateCycleDetails } = useCycle();
const { captureCycleEvent } = useEventTracker();
const { t } = useTranslation();
const { renderFormattedDateInUserTimezone, getProjectUTCOffset } = useTimeZoneConverter(projectId);

Expand All @@ -61,29 +61,36 @@ export const CycleSidebarHeader: FC<Props> = observer((props) => {

const currentCycle = CYCLE_STATUS.find((status) => status.value === cycleStatus);

const submitChanges = async (data: Partial<ICycle>, changedProperty: string) => {
const submitChanges = async (data: Partial<ICycle>) => {
if (!workspaceSlug || !projectId || !cycleDetails.id) return;

await updateCycleDetails(workspaceSlug.toString(), projectId.toString(), cycleDetails.id.toString(), data)
.then((res) => {
captureCycleEvent({
eventName: CYCLE_TRACKER_EVENTS.update,
payload: {
...res,
changed_properties: [changedProperty],
element: "Right side-peek",
.then(() => {
captureElementAndEvent({
element: {
elementName: CYCLE_TRACKER_ELEMENTS.RIGHT_SIDEBAR,
},
event: {
eventName: CYCLE_TRACKER_EVENTS.update,
state: "SUCCESS",
payload: {
id: cycleDetails.id,
},
},
});
})

.catch(() => {
captureCycleEvent({
eventName: CYCLE_TRACKER_EVENTS.update,
payload: {
...data,
element: "Right side-peek",
state: "FAILED",
captureElementAndEvent({
element: {
elementName: CYCLE_TRACKER_ELEMENTS.RIGHT_SIDEBAR,
},
event: {
eventName: CYCLE_TRACKER_EVENTS.update,
state: "ERROR",
payload: {
id: cycleDetails.id,
},
},
});
});
Expand Down Expand Up @@ -122,7 +129,7 @@ export const CycleSidebarHeader: FC<Props> = observer((props) => {
isDateValid = true;
}
if (isDateValid) {
submitChanges(payload, "date_range");
submitChanges(payload);
setToast({
type: TOAST_TYPE.SUCCESS,
title: t("project_cycles.action.update.success.title"),
Expand All @@ -145,24 +152,6 @@ export const CycleSidebarHeader: FC<Props> = observer((props) => {

return (
<>
{cycleDetails && workspaceSlug && projectId && (
<>
<ArchiveCycleModal
workspaceSlug={workspaceSlug.toString()}
projectId={projectId.toString()}
cycleId={cycleDetails.id}
isOpen={archiveCycleModal}
handleClose={() => setArchiveCycleModal(false)}
/>
<CycleDeleteModal
cycle={cycleDetails}
isOpen={cycleDeleteModal}
handleClose={() => setCycleDeleteModal(false)}
workspaceSlug={workspaceSlug.toString()}
projectId={projectId.toString()}
/>
</>
)}
<div className="sticky z-10 top-0 pt-2 flex items-center justify-between bg-custom-sidebar-background-100">
<div className="flex items-center justify-center size-5">
<button
Expand Down
Loading