mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
chore: label events added
This commit is contained in:
parent
c94375e3c7
commit
38fbf1f513
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect } from "react";
|
import React, { use, useEffect } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
@ -6,7 +6,7 @@ import { TwitterPicker } from "react-color";
|
|||||||
import { Dialog, Popover, Transition } from "@headlessui/react";
|
import { Dialog, Popover, Transition } from "@headlessui/react";
|
||||||
import { ChevronDown } from "lucide-react";
|
import { ChevronDown } from "lucide-react";
|
||||||
// hooks
|
// hooks
|
||||||
import { useLabel } from "hooks/store";
|
import { useEventTracker, useLabel } from "hooks/store";
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
// ui
|
// ui
|
||||||
import { Button, Input } from "@plane/ui";
|
import { Button, Input } from "@plane/ui";
|
||||||
@ -14,6 +14,7 @@ import { Button, Input } from "@plane/ui";
|
|||||||
import type { IIssueLabel, IState } from "@plane/types";
|
import type { IIssueLabel, IState } from "@plane/types";
|
||||||
// constants
|
// constants
|
||||||
import { LABEL_COLOR_OPTIONS, getRandomLabelColor } from "constants/label";
|
import { LABEL_COLOR_OPTIONS, getRandomLabelColor } from "constants/label";
|
||||||
|
import { LABEL_CREATED } from "constants/event-tracker";
|
||||||
|
|
||||||
// types
|
// types
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -35,6 +36,7 @@ export const CreateLabelModal: React.FC<Props> = observer((props) => {
|
|||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
// store hooks
|
// store hooks
|
||||||
const { createLabel } = useLabel();
|
const { createLabel } = useLabel();
|
||||||
|
const { captureEvent } = useEventTracker();
|
||||||
// form info
|
// form info
|
||||||
const {
|
const {
|
||||||
formState: { errors, isSubmitting },
|
formState: { errors, isSubmitting },
|
||||||
@ -71,10 +73,20 @@ export const CreateLabelModal: React.FC<Props> = observer((props) => {
|
|||||||
|
|
||||||
await createLabel(workspaceSlug.toString(), projectId.toString(), formData)
|
await createLabel(workspaceSlug.toString(), projectId.toString(), formData)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
|
captureEvent(LABEL_CREATED, {
|
||||||
|
label_id: res.id,
|
||||||
|
color: res.color,
|
||||||
|
parent: res.parent,
|
||||||
|
element: "Project settings labels page",
|
||||||
|
state: "SUCCESS",
|
||||||
|
});
|
||||||
onClose();
|
onClose();
|
||||||
if (onSuccess) onSuccess(res);
|
if (onSuccess) onSuccess(res);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
captureEvent(LABEL_CREATED, {
|
||||||
|
state: "FAILED",
|
||||||
|
});
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
title: "Oops!",
|
title: "Oops!",
|
||||||
type: "error",
|
type: "error",
|
||||||
|
@ -5,7 +5,7 @@ import { TwitterPicker } from "react-color";
|
|||||||
import { Controller, SubmitHandler, useForm } from "react-hook-form";
|
import { Controller, SubmitHandler, useForm } from "react-hook-form";
|
||||||
import { Popover, Transition } from "@headlessui/react";
|
import { Popover, Transition } from "@headlessui/react";
|
||||||
// hooks
|
// hooks
|
||||||
import { useLabel } from "hooks/store";
|
import { useEventTracker, useLabel } from "hooks/store";
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
// ui
|
// ui
|
||||||
import { Button, Input } from "@plane/ui";
|
import { Button, Input } from "@plane/ui";
|
||||||
@ -13,6 +13,8 @@ import { Button, Input } from "@plane/ui";
|
|||||||
import { IIssueLabel } from "@plane/types";
|
import { IIssueLabel } from "@plane/types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { getRandomLabelColor, LABEL_COLOR_OPTIONS } from "constants/label";
|
import { getRandomLabelColor, LABEL_COLOR_OPTIONS } from "constants/label";
|
||||||
|
// constants
|
||||||
|
import { LABEL_CREATED, LABEL_UPDATED } from "constants/event-tracker";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
labelForm: boolean;
|
labelForm: boolean;
|
||||||
@ -35,6 +37,7 @@ export const CreateUpdateLabelInline = observer(
|
|||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
// store hooks
|
// store hooks
|
||||||
const { createLabel, updateLabel } = useLabel();
|
const { createLabel, updateLabel } = useLabel();
|
||||||
|
const { captureEvent } = useEventTracker();
|
||||||
// toast alert
|
// toast alert
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
// form info
|
// form info
|
||||||
@ -42,7 +45,7 @@ export const CreateUpdateLabelInline = observer(
|
|||||||
handleSubmit,
|
handleSubmit,
|
||||||
control,
|
control,
|
||||||
reset,
|
reset,
|
||||||
formState: { errors, isSubmitting },
|
formState: { errors, isSubmitting, dirtyFields },
|
||||||
watch,
|
watch,
|
||||||
setValue,
|
setValue,
|
||||||
setFocus,
|
setFocus,
|
||||||
@ -60,7 +63,14 @@ export const CreateUpdateLabelInline = observer(
|
|||||||
if (!workspaceSlug || !projectId || isSubmitting) return;
|
if (!workspaceSlug || !projectId || isSubmitting) return;
|
||||||
|
|
||||||
await createLabel(workspaceSlug.toString(), projectId.toString(), formData)
|
await createLabel(workspaceSlug.toString(), projectId.toString(), formData)
|
||||||
.then(() => {
|
.then((res) => {
|
||||||
|
captureEvent(LABEL_CREATED, {
|
||||||
|
label_id: res.id,
|
||||||
|
color: res.color,
|
||||||
|
parent: res.parent,
|
||||||
|
element: "Project settings labels page",
|
||||||
|
state: "SUCCESS",
|
||||||
|
});
|
||||||
handleClose();
|
handleClose();
|
||||||
reset(defaultValues);
|
reset(defaultValues);
|
||||||
})
|
})
|
||||||
@ -78,7 +88,15 @@ export const CreateUpdateLabelInline = observer(
|
|||||||
if (!workspaceSlug || !projectId || isSubmitting) return;
|
if (!workspaceSlug || !projectId || isSubmitting) return;
|
||||||
|
|
||||||
await updateLabel(workspaceSlug.toString(), projectId.toString(), labelToUpdate?.id!, formData)
|
await updateLabel(workspaceSlug.toString(), projectId.toString(), labelToUpdate?.id!, formData)
|
||||||
.then(() => {
|
.then((res) => {
|
||||||
|
captureEvent(LABEL_UPDATED, {
|
||||||
|
label_id: res.id,
|
||||||
|
color: res.color,
|
||||||
|
parent: res.parent,
|
||||||
|
change_details: Object.keys(dirtyFields),
|
||||||
|
element: "Project settings labels page",
|
||||||
|
state: "SUCCESS",
|
||||||
|
});
|
||||||
reset(defaultValues);
|
reset(defaultValues);
|
||||||
handleClose();
|
handleClose();
|
||||||
})
|
})
|
||||||
|
@ -3,7 +3,7 @@ import { useRouter } from "next/router";
|
|||||||
import { Dialog, Transition } from "@headlessui/react";
|
import { Dialog, Transition } from "@headlessui/react";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
// hooks
|
// hooks
|
||||||
import { useLabel } from "hooks/store";
|
import { useEventTracker, useLabel } from "hooks/store";
|
||||||
// icons
|
// icons
|
||||||
import { AlertTriangle } from "lucide-react";
|
import { AlertTriangle } from "lucide-react";
|
||||||
// hooks
|
// hooks
|
||||||
@ -12,6 +12,8 @@ import useToast from "hooks/use-toast";
|
|||||||
import { Button } from "@plane/ui";
|
import { Button } from "@plane/ui";
|
||||||
// types
|
// types
|
||||||
import type { IIssueLabel } from "@plane/types";
|
import type { IIssueLabel } from "@plane/types";
|
||||||
|
// constants
|
||||||
|
import { LABEL_DELETED, LABEL_GROUP_DELETED } from "constants/event-tracker";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@ -25,7 +27,8 @@ export const DeleteLabelModal: React.FC<Props> = observer((props) => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
// store hooks
|
// store hooks
|
||||||
const { deleteLabel } = useLabel();
|
const { deleteLabel, projectLabelsTree } = useLabel();
|
||||||
|
const { captureEvent } = useEventTracker();
|
||||||
// states
|
// states
|
||||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||||
// hooks
|
// hooks
|
||||||
@ -43,6 +46,21 @@ export const DeleteLabelModal: React.FC<Props> = observer((props) => {
|
|||||||
|
|
||||||
await deleteLabel(workspaceSlug.toString(), projectId.toString(), data.id)
|
await deleteLabel(workspaceSlug.toString(), projectId.toString(), data.id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
const labelChildCount = projectLabelsTree?.find((label) => label.id === data.id)?.children?.length || 0;
|
||||||
|
if (labelChildCount > 0) {
|
||||||
|
captureEvent(LABEL_GROUP_DELETED, {
|
||||||
|
group_id: data.id,
|
||||||
|
children_count: labelChildCount,
|
||||||
|
element: "Project settings labels page",
|
||||||
|
state: "SUCCESS",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
captureEvent(LABEL_DELETED, {
|
||||||
|
label_id: data.id,
|
||||||
|
element: "Project settings labels page",
|
||||||
|
state: "SUCCESS",
|
||||||
|
});
|
||||||
|
}
|
||||||
handleClose();
|
handleClose();
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
@ -11,7 +11,7 @@ import {
|
|||||||
} from "@hello-pangea/dnd";
|
} from "@hello-pangea/dnd";
|
||||||
import { useTheme } from "next-themes";
|
import { useTheme } from "next-themes";
|
||||||
// hooks
|
// hooks
|
||||||
import { useLabel, useUser } from "hooks/store";
|
import { useEventTracker, useLabel, useUser } from "hooks/store";
|
||||||
import useDraggableInPortal from "hooks/use-draggable-portal";
|
import useDraggableInPortal from "hooks/use-draggable-portal";
|
||||||
// components
|
// components
|
||||||
import {
|
import {
|
||||||
@ -27,6 +27,7 @@ import { Button, Loader } from "@plane/ui";
|
|||||||
import { IIssueLabel } from "@plane/types";
|
import { IIssueLabel } from "@plane/types";
|
||||||
// constants
|
// constants
|
||||||
import { PROJECT_SETTINGS_EMPTY_STATE_DETAILS } from "constants/empty-state";
|
import { PROJECT_SETTINGS_EMPTY_STATE_DETAILS } from "constants/empty-state";
|
||||||
|
import { LABEL_ADDED_G, LABEL_REMOVED_G } from "constants/event-tracker";
|
||||||
|
|
||||||
const LABELS_ROOT = "labels.root";
|
const LABELS_ROOT = "labels.root";
|
||||||
|
|
||||||
@ -45,7 +46,8 @@ export const ProjectSettingsLabelList: React.FC = observer(() => {
|
|||||||
const { resolvedTheme } = useTheme();
|
const { resolvedTheme } = useTheme();
|
||||||
// store hooks
|
// store hooks
|
||||||
const { currentUser } = useUser();
|
const { currentUser } = useUser();
|
||||||
const { projectLabels, updateLabelPosition, projectLabelsTree } = useLabel();
|
const { projectLabels, updateLabelPosition, projectLabelsTree, getLabelById } = useLabel();
|
||||||
|
const { captureEvent } = useEventTracker();
|
||||||
// portal
|
// portal
|
||||||
const renderDraggable = useDraggableInPortal();
|
const renderDraggable = useDraggableInPortal();
|
||||||
|
|
||||||
@ -76,6 +78,30 @@ export const ProjectSettingsLabelList: React.FC = observer(() => {
|
|||||||
if (destination?.droppableId === LABELS_ROOT) parentLabel = null;
|
if (destination?.droppableId === LABELS_ROOT) parentLabel = null;
|
||||||
|
|
||||||
if (result.reason == "DROP" && childLabel != parentLabel) {
|
if (result.reason == "DROP" && childLabel != parentLabel) {
|
||||||
|
const childLabelData = getLabelById(childLabel);
|
||||||
|
if (childLabelData?.parent != parentLabel) {
|
||||||
|
if (childLabelData?.parent) {
|
||||||
|
captureEvent(LABEL_REMOVED_G, {
|
||||||
|
group_id: childLabelData?.parent,
|
||||||
|
child_id: childLabel,
|
||||||
|
child_count:
|
||||||
|
(projectLabelsTree?.find((label) => label.id === childLabelData?.parent)?.children?.length ?? 0) - 1,
|
||||||
|
});
|
||||||
|
parentLabel &&
|
||||||
|
captureEvent(LABEL_ADDED_G, {
|
||||||
|
group_id: parentLabel,
|
||||||
|
child_id: childLabel,
|
||||||
|
child_count: (projectLabelsTree?.find((label) => label.id === parentLabel)?.children?.length ?? 0) + 1,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
captureEvent(LABEL_ADDED_G, {
|
||||||
|
group_id: parentLabel,
|
||||||
|
child_id: childLabel,
|
||||||
|
child_count: (projectLabelsTree?.find((label) => label.id === parentLabel)?.children?.length ?? 0) + 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updateLabelPosition(
|
updateLabelPosition(
|
||||||
workspaceSlug?.toString()!,
|
workspaceSlug?.toString()!,
|
||||||
projectId?.toString()!,
|
projectId?.toString()!,
|
||||||
|
@ -178,7 +178,7 @@ export const elementFromPath = (path?: string) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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";
|
||||||
export const WORKSPACE_DELETED = "Workspace deleted";
|
export const WORKSPACE_DELETED = "Workspace deleted";
|
||||||
@ -213,7 +213,6 @@ 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_ARCHIVED = "Issue archived";
|
||||||
export const ISSUE_RESTORED = "Issue restored";
|
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";
|
||||||
@ -231,6 +230,13 @@ export const LAYOUT_CHANGED = "Layout changed";
|
|||||||
export const STATE_CREATED = "State created";
|
export const STATE_CREATED = "State created";
|
||||||
export const STATE_UPDATED = "State updated";
|
export const STATE_UPDATED = "State updated";
|
||||||
export const STATE_DELETED = "State deleted";
|
export const STATE_DELETED = "State deleted";
|
||||||
|
// Label Events
|
||||||
|
export const LABEL_CREATED = "Label created";
|
||||||
|
export const LABEL_UPDATED = "Label updated";
|
||||||
|
export const LABEL_DELETED = "Label deleted";
|
||||||
|
export const LABEL_GROUP_DELETED = "Label group deleted";
|
||||||
|
export const LABEL_ADDED_G = "Label added to group";
|
||||||
|
export const LABEL_REMOVED_G = "Label removed from group";
|
||||||
// Project Page Events
|
// Project Page Events
|
||||||
export const PAGE_CREATED = "Page created";
|
export const PAGE_CREATED = "Page created";
|
||||||
export const PAGE_UPDATED = "Page updated";
|
export const PAGE_UPDATED = "Page updated";
|
||||||
|
Loading…
Reference in New Issue
Block a user