chore: added sign-up/in, onboarding, dashboard, all-issues related events (#3595)

* chore: added event constants

* chore: added workspace events

* chore: added workspace group for events

* chore: member invitation event added

* chore: added project pages related events.

* fix: member integer role to string

* chore: added sign-up & sign-in events

* chore: added global-view related events

* chore: added notification related events

* chore: project, cycle property change added

* chore: cycle favourite, and change-properties added

* chore: module davorite, and sidebar property changes added

* fix: build errors

* chore: all events defined in constants
This commit is contained in:
Lakhan Baheti 2024-02-09 16:22:08 +05:30 committed by GitHub
parent 8d730e6680
commit 4f72ebded9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
80 changed files with 1276 additions and 507 deletions

View file

@ -18,6 +18,7 @@ import { getRandomEmoji, renderEmoji } from "helpers/emoji.helper";
import { NETWORK_CHOICES, PROJECT_UNSPLASH_COVERS } from "constants/project";
// constants
import { EUserWorkspaceRoles } from "constants/workspace";
import { PROJECT_CREATED } from "constants/event-tracker";
type Props = {
isOpen: boolean;
@ -134,13 +135,8 @@ export const CreateProjectModal: FC<Props> = observer((props) => {
state: "SUCCESS",
};
captureProjectEvent({
eventName: "Project created",
eventName: PROJECT_CREATED,
payload: newPayload,
group: {
isGrouping: true,
groupType: "Workspace_metrics",
groupId: res.workspace,
},
});
setToastAlert({
type: "success",
@ -160,16 +156,11 @@ export const CreateProjectModal: FC<Props> = observer((props) => {
message: err.data[key],
});
captureProjectEvent({
eventName: "Project created",
eventName: PROJECT_CREATED,
payload: {
...payload,
state: "FAILED",
},
group: {
isGrouping: true,
groupType: "Workspace_metrics",
groupId: currentWorkspace?.id!,
},
}
});
});
});

View file

@ -10,6 +10,8 @@ import useToast from "hooks/use-toast";
import { Button, Input } from "@plane/ui";
// types
import type { IProject } from "@plane/types";
// constants
import { PROJECT_DELETED } from "constants/event-tracker";
type DeleteProjectModal = {
isOpen: boolean;
@ -62,13 +64,8 @@ export const DeleteProjectModal: React.FC<DeleteProjectModal> = (props) => {
handleClose();
captureProjectEvent({
eventName: "Project deleted",
eventName: PROJECT_DELETED,
payload: { ...project, state: "SUCCESS", element: "Project general settings" },
group: {
isGrouping: true,
groupType: "Workspace_metrics",
groupId: currentWorkspace?.id!,
},
});
setToastAlert({
type: "success",
@ -78,13 +75,8 @@ export const DeleteProjectModal: React.FC<DeleteProjectModal> = (props) => {
})
.catch(() => {
captureProjectEvent({
eventName: "Project deleted",
eventName: PROJECT_DELETED,
payload: { ...project, state: "FAILED", element: "Project general settings" },
group: {
isGrouping: true,
groupType: "Workspace_metrics",
groupId: currentWorkspace?.id!,
},
});
setToastAlert({
type: "error",

View file

@ -18,6 +18,7 @@ import { renderFormattedDate } from "helpers/date-time.helper";
import { NETWORK_CHOICES } from "constants/project";
// services
import { ProjectService } from "services/project";
import { PROJECT_UPDATED } from "constants/event-tracker";
export interface IProjectDetailsForm {
project: IProject;
@ -45,7 +46,7 @@ export const ProjectDetailsForm: FC<IProjectDetailsForm> = (props) => {
setValue,
setError,
reset,
formState: { errors },
formState: { errors, dirtyFields },
} = useForm<IProject>({
defaultValues: {
...project,
@ -77,13 +78,15 @@ export const ProjectDetailsForm: FC<IProjectDetailsForm> = (props) => {
return updateProject(workspaceSlug.toString(), project.id, payload)
.then((res) => {
const changed_properties = Object.keys(dirtyFields);
console.log(dirtyFields);
captureProjectEvent({
eventName: "Project updated",
payload: { ...res, state: "SUCCESS", element: "Project general settings" },
group: {
isGrouping: true,
groupType: "Workspace_metrics",
groupId: res.workspace,
eventName: PROJECT_UPDATED,
payload: {
...res,
changed_properties: changed_properties,
state: "SUCCESS",
element: "Project general settings",
},
});
setToastAlert({
@ -94,13 +97,8 @@ export const ProjectDetailsForm: FC<IProjectDetailsForm> = (props) => {
})
.catch((error) => {
captureProjectEvent({
eventName: "Project updated",
eventName: PROJECT_UPDATED,
payload: { ...payload, state: "FAILED", element: "Project general settings" },
group: {
isGrouping: true,
groupType: "Workspace_metrics",
groupId: currentWorkspace?.id,
},
});
setToastAlert({
type: "error",
@ -153,7 +151,7 @@ export const ProjectDetailsForm: FC<IProjectDetailsForm> = (props) => {
<div className="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent" />
<img src={watch("cover_image")!} alt={watch("cover_image")!} className="h-44 w-full rounded-md object-cover" />
<div className="absolute bottom-4 z-5 flex w-full items-end justify-between gap-3 px-4">
<div className="z-5 absolute bottom-4 flex w-full items-end justify-between gap-3 px-4">
<div className="flex flex-grow gap-3 truncate">
<div className="flex h-[52px] w-[52px] flex-shrink-0 items-center justify-center rounded-lg bg-custom-background-90">
<div className="grid h-7 w-7 place-items-center">

View file

@ -11,6 +11,8 @@ import useToast from "hooks/use-toast";
import { Button, Input } from "@plane/ui";
// types
import { IProject } from "@plane/types";
// constants
import { PROJECT_MEMBER_LEAVE } from "constants/event-tracker";
type FormData = {
projectName: string;
@ -63,8 +65,9 @@ export const LeaveProjectModal: FC<ILeaveProjectModal> = observer((props) => {
.then(() => {
handleClose();
router.push(`/${workspaceSlug}/projects`);
captureEvent("Project member leave", {
captureEvent(PROJECT_MEMBER_LEAVE, {
state: "SUCCESS",
element: "Project settings members page",
});
})
.catch(() => {
@ -73,8 +76,9 @@ export const LeaveProjectModal: FC<ILeaveProjectModal> = observer((props) => {
title: "Error!",
message: "Something went wrong please try again later.",
});
captureEvent("Project member leave", {
captureEvent(PROJECT_MEMBER_LEAVE, {
state: "FAILED",
element: "Project settings members page",
});
});
} else {

View file

@ -3,7 +3,7 @@ import { useRouter } from "next/router";
import Link from "next/link";
import { observer } from "mobx-react-lite";
// hooks
import { useMember, useProject, useUser } from "hooks/store";
import { useEventTracker, useMember, useProject, useUser } from "hooks/store";
import useToast from "hooks/use-toast";
// components
import { ConfirmProjectMemberRemove } from "components/project";
@ -14,6 +14,7 @@ import { ChevronDown, Dot, XCircle } from "lucide-react";
// constants
import { ROLE } from "constants/workspace";
import { EUserProjectRoles } from "constants/project";
import { PROJECT_MEMBER_LEAVE } from "constants/event-tracker";
type Props = {
userId: string;
@ -35,6 +36,7 @@ export const ProjectMemberListItem: React.FC<Props> = observer((props) => {
const {
project: { removeMemberFromProject, getProjectMemberDetails, updateMember },
} = useMember();
const { captureEvent } = useEventTracker();
// toast alert
const { setToastAlert } = useToast();
@ -48,8 +50,11 @@ export const ProjectMemberListItem: React.FC<Props> = observer((props) => {
if (userDetails.member.id === currentUser?.id) {
await leaveProject(workspaceSlug.toString(), projectId.toString())
.then(async () => {
captureEvent(PROJECT_MEMBER_LEAVE, {
state: "SUCCESS",
element: "Project settings members page",
});
await fetchProjects(workspaceSlug.toString());
router.push(`/${workspaceSlug}/projects`);
})
.catch((err) =>

View file

@ -9,9 +9,12 @@ import { useEventTracker, useMember, useUser, useWorkspace } from "hooks/store";
import useToast from "hooks/use-toast";
// ui
import { Avatar, Button, CustomSelect, CustomSearchSelect } from "@plane/ui";
// helpers
import { getUserRole } from "helpers/user.helper";
// constants
import { ROLE } from "constants/workspace";
import { EUserProjectRoles } from "constants/project";
import { PROJECT_MEMBER_ADDED } from "constants/event-tracker";
type Props = {
isOpen: boolean;
@ -49,7 +52,6 @@ export const SendProjectInvitationModal: React.FC<Props> = observer((props) => {
const {
membership: { currentProjectRole },
} = useUser();
const { currentWorkspace } = useWorkspace();
const {
project: { projectMemberIds, bulkAddMembersToProject },
workspace: { workspaceMemberIds, getWorkspaceMemberDetails },
@ -79,7 +81,7 @@ export const SendProjectInvitationModal: React.FC<Props> = observer((props) => {
const payload = { ...formData };
await bulkAddMembersToProject(workspaceSlug.toString(), projectId.toString(), payload)
.then((res) => {
.then(() => {
if (onSuccess) onSuccess();
onClose();
setToastAlert({
@ -87,32 +89,23 @@ export const SendProjectInvitationModal: React.FC<Props> = observer((props) => {
type: "success",
message: "Members added successfully.",
});
captureEvent(
"Member added",
{
...res,
state: "SUCCESS",
},
{
isGrouping: true,
groupType: "Workspace_metrics",
groupId: currentWorkspace?.id!,
}
);
captureEvent(PROJECT_MEMBER_ADDED, {
members: [
...payload.members.map((member) => ({
member_id: member.member_id,
role: ROLE[member.role],
})),
],
state: "SUCCESS",
element: "Project settings members page",
});
})
.catch((error) => {
console.error(error);
captureEvent(
"Member added",
{
state: "FAILED",
},
{
isGrouping: true,
groupType: "Workspace_metrics",
groupId: currentWorkspace?.id!,
}
);
captureEvent(PROJECT_MEMBER_ADDED, {
state: "FAILED",
element: "Project settings members page",
});
})
.finally(() => {
reset(defaultValues);

View file

@ -51,12 +51,11 @@ export const ProjectFeaturesList: FC<Props> = observer(() => {
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
// store hooks
const { setTrackElement, captureEvent } = useEventTracker();
const { captureEvent } = useEventTracker();
const {
currentUser,
membership: { currentProjectRole },
} = useUser();
const { currentWorkspace } = useWorkspace();
const { currentProjectDetails, updateProject } = useProject();
const isAdmin = currentProjectRole === EUserProjectRoles.ADMIN;
// toast alert
@ -91,14 +90,9 @@ export const ProjectFeaturesList: FC<Props> = observer(() => {
<ToggleSwitch
value={Boolean(currentProjectDetails?.[feature.property as keyof IProject])}
onChange={() => {
setTrackElement("PROJECT_SETTINGS_FEATURES_PAGE");
captureEvent(`Toggle ${feature.title.toLowerCase()}`, {
workspace_id: currentWorkspace?.id,
workspace_slug: currentWorkspace?.slug,
project_id: currentProjectDetails?.id,
project_name: currentProjectDetails?.name,
project_identifier: currentProjectDetails?.identifier,
enabled: !currentProjectDetails?.[feature.property as keyof IProject],
element: "Project settings feature page",
});
handleSubmit({
[feature.property]: !currentProjectDetails?.[feature.property as keyof IProject],