mirror of
https://github.com/makeplane/plane
synced 2025-08-07 19:59:33 +00:00
Compare commits
1 Commits
fix/node-v
...
chore-work
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55d6841f9a |
@@ -1,6 +1,7 @@
|
||||
import { FC } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Pen, Trash } from "lucide-react";
|
||||
import { PROJECT_SETTINGS_TRACKER_ELEMENTS } from "@plane/constants";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// components
|
||||
import { ProIcon } from "@/components/common";
|
||||
@@ -29,13 +30,17 @@ export const EstimateListItemButtons: FC<TEstimateListItem> = observer((props) =
|
||||
}
|
||||
position="top"
|
||||
>
|
||||
<button className="relative flex-shrink-0 w-6 h-6 flex justify-center items-center rounded cursor-pointer transition-colors overflow-hidden hover:bg-custom-background-80">
|
||||
<button
|
||||
className="relative flex-shrink-0 w-6 h-6 flex justify-center items-center rounded cursor-pointer transition-colors overflow-hidden hover:bg-custom-background-80"
|
||||
data-ph-element={PROJECT_SETTINGS_TRACKER_ELEMENTS.ESTIMATES_LIST_ITEM}
|
||||
>
|
||||
<Pen size={12} />
|
||||
</button>
|
||||
</Tooltip>
|
||||
<button
|
||||
className="relative flex-shrink-0 w-6 h-6 flex justify-center items-center rounded cursor-pointer transition-colors overflow-hidden hover:bg-custom-background-80"
|
||||
onClick={() => onDeleteClick && onDeleteClick(estimateId)}
|
||||
data-ph-element={PROJECT_SETTINGS_TRACKER_ELEMENTS.ESTIMATES_LIST_ITEM}
|
||||
>
|
||||
<Trash size={12} />
|
||||
</button>
|
||||
|
||||
@@ -5,7 +5,13 @@ import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { ArchiveRestore } from "lucide-react";
|
||||
// types
|
||||
import { PROJECT_AUTOMATION_MONTHS, EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
|
||||
import {
|
||||
PROJECT_AUTOMATION_MONTHS,
|
||||
EUserPermissions,
|
||||
EUserPermissionsLevel,
|
||||
PROJECT_SETTINGS_TRACKER_ELEMENTS,
|
||||
PROJECT_SETTINGS_TRACKER_EVENTS,
|
||||
} from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { IProject } from "@plane/types";
|
||||
// ui
|
||||
@@ -14,6 +20,7 @@ import { CustomSelect, Loader, ToggleSwitch } from "@plane/ui";
|
||||
import { SelectMonthModal } from "@/components/automation";
|
||||
// constants
|
||||
// hooks
|
||||
import { captureElementAndEvent } from "@/helpers/event-tracker.helper";
|
||||
import { useProject, useUserPermissions } from "@/hooks/store";
|
||||
|
||||
type Props = {
|
||||
@@ -39,7 +46,7 @@ export const AutoArchiveAutomation: React.FC<Props> = observer((props) => {
|
||||
EUserPermissionsLevel.PROJECT,
|
||||
workspaceSlug?.toString(),
|
||||
currentProjectDetails?.id
|
||||
);
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -65,11 +72,22 @@ export const AutoArchiveAutomation: React.FC<Props> = observer((props) => {
|
||||
</div>
|
||||
<ToggleSwitch
|
||||
value={currentProjectDetails?.archive_in !== 0}
|
||||
onChange={() =>
|
||||
currentProjectDetails?.archive_in === 0
|
||||
? handleChange({ archive_in: 1 })
|
||||
: handleChange({ archive_in: 0 })
|
||||
}
|
||||
onChange={() => {
|
||||
if (currentProjectDetails?.archive_in === 0) {
|
||||
handleChange({ archive_in: 1 });
|
||||
} else {
|
||||
handleChange({ archive_in: 0 });
|
||||
}
|
||||
captureElementAndEvent({
|
||||
element: {
|
||||
elementName: PROJECT_SETTINGS_TRACKER_ELEMENTS.AUTOMATIONS_ARCHIVE_TOGGLE_BUTTON,
|
||||
},
|
||||
event: {
|
||||
eventName: PROJECT_SETTINGS_TRACKER_EVENTS.auto_archive_workitems,
|
||||
state: "SUCCESS",
|
||||
},
|
||||
});
|
||||
}}
|
||||
size="sm"
|
||||
disabled={!isAdmin}
|
||||
/>
|
||||
|
||||
@@ -6,7 +6,14 @@ import { useParams } from "next/navigation";
|
||||
// icons
|
||||
import { ArchiveX } from "lucide-react";
|
||||
// types
|
||||
import { PROJECT_AUTOMATION_MONTHS, EUserPermissions, EUserPermissionsLevel, EIconSize } from "@plane/constants";
|
||||
import {
|
||||
PROJECT_AUTOMATION_MONTHS,
|
||||
EUserPermissions,
|
||||
EUserPermissionsLevel,
|
||||
EIconSize,
|
||||
PROJECT_SETTINGS_TRACKER_ELEMENTS,
|
||||
PROJECT_SETTINGS_TRACKER_EVENTS,
|
||||
} from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { IProject } from "@plane/types";
|
||||
// ui
|
||||
@@ -15,6 +22,7 @@ import { CustomSelect, CustomSearchSelect, ToggleSwitch, StateGroupIcon, DoubleC
|
||||
import { SelectMonthModal } from "@/components/automation";
|
||||
// constants
|
||||
// hooks
|
||||
import { captureElementAndEvent } from "@/helpers/event-tracker.helper";
|
||||
import { useProject, useProjectState, useUserPermissions } from "@/hooks/store";
|
||||
|
||||
type Props = {
|
||||
@@ -91,11 +99,22 @@ export const AutoCloseAutomation: React.FC<Props> = observer((props) => {
|
||||
</div>
|
||||
<ToggleSwitch
|
||||
value={currentProjectDetails?.close_in !== 0}
|
||||
onChange={() =>
|
||||
currentProjectDetails?.close_in === 0
|
||||
? handleChange({ close_in: 1, default_state: defaultState })
|
||||
: handleChange({ close_in: 0, default_state: null })
|
||||
}
|
||||
onChange={() => {
|
||||
if (currentProjectDetails?.close_in === 0) {
|
||||
handleChange({ close_in: 1, default_state: defaultState });
|
||||
} else {
|
||||
handleChange({ close_in: 0, default_state: null });
|
||||
}
|
||||
captureElementAndEvent({
|
||||
element: {
|
||||
elementName: PROJECT_SETTINGS_TRACKER_ELEMENTS.AUTOMATIONS_CLOSE_TOGGLE_BUTTON,
|
||||
},
|
||||
event: {
|
||||
eventName: PROJECT_SETTINGS_TRACKER_EVENTS.auto_close_workitems,
|
||||
state: "SUCCESS",
|
||||
},
|
||||
});
|
||||
}}
|
||||
size="sm"
|
||||
disabled={!isAdmin}
|
||||
/>
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
import { FC, useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
// ui
|
||||
import { PROJECT_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
|
||||
import { Button, EModalPosition, EModalWidth, ModalCore, TOAST_TYPE, setToast } from "@plane/ui";
|
||||
// hooks
|
||||
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
|
||||
import { useEstimate, useProject, useProjectEstimates } from "@/hooks/store";
|
||||
|
||||
type TDeleteEstimateModal = {
|
||||
@@ -35,6 +37,12 @@ export const DeleteEstimateModal: FC<TDeleteEstimateModal> = observer((props) =>
|
||||
await updateProject(workspaceSlug, projectId, { estimate: null });
|
||||
}
|
||||
setButtonLoader(false);
|
||||
captureSuccess({
|
||||
eventName: PROJECT_SETTINGS_TRACKER_EVENTS.estimate_deleted,
|
||||
payload: {
|
||||
id: estimateId,
|
||||
},
|
||||
});
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Estimate deleted",
|
||||
@@ -43,6 +51,12 @@ export const DeleteEstimateModal: FC<TDeleteEstimateModal> = observer((props) =>
|
||||
handleClose();
|
||||
} catch (error) {
|
||||
setButtonLoader(false);
|
||||
captureError({
|
||||
eventName: PROJECT_SETTINGS_TRACKER_EVENTS.estimate_deleted,
|
||||
payload: {
|
||||
id: estimateId,
|
||||
},
|
||||
});
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Estimate creation failed",
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
import { FC } from "react";
|
||||
import { useTheme } from "next-themes";
|
||||
import { PROJECT_SETTINGS_TRACKER_ELEMENTS, PROJECT_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
// public images
|
||||
import { captureElementAndEvent } from "@/helpers/event-tracker.helper";
|
||||
import { DetailedEmptyState } from "../empty-state";
|
||||
|
||||
type TEstimateEmptyScreen = {
|
||||
@@ -26,7 +28,18 @@ export const EstimateEmptyScreen: FC<TEstimateEmptyScreen> = (props) => {
|
||||
className="w-full !px-0 !py-0"
|
||||
primaryButton={{
|
||||
text: t("project_settings.empty_state.estimates.primary_button"),
|
||||
onClick: onButtonClick,
|
||||
onClick: () => {
|
||||
onButtonClick();
|
||||
captureElementAndEvent({
|
||||
element: {
|
||||
elementName: PROJECT_SETTINGS_TRACKER_ELEMENTS.ESTIMATES_EMPTY_STATE_CREATE_BUTTON,
|
||||
},
|
||||
event: {
|
||||
eventName: PROJECT_SETTINGS_TRACKER_EVENTS.estimate_created,
|
||||
state: "SUCCESS",
|
||||
},
|
||||
});
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
import { FC } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { PROJECT_SETTINGS_TRACKER_ELEMENTS, PROJECT_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { TOAST_TYPE, ToggleSwitch, setToast } from "@plane/ui";
|
||||
// hooks
|
||||
import { captureElementAndEvent } from "@/helpers/event-tracker.helper";
|
||||
import { useProject, useProjectEstimates } from "@/hooks/store";
|
||||
// i18n
|
||||
type TEstimateDisableSwitch = {
|
||||
@@ -30,6 +32,15 @@ export const EstimateDisableSwitch: FC<TEstimateDisableSwitch> = observer((props
|
||||
await updateProject(workspaceSlug, projectId, {
|
||||
estimate: currentProjectActiveEstimate ? null : currentActiveEstimateId,
|
||||
});
|
||||
captureElementAndEvent({
|
||||
element: {
|
||||
elementName: PROJECT_SETTINGS_TRACKER_ELEMENTS.ESTIMATES_TOGGLE_BUTTON,
|
||||
},
|
||||
event: {
|
||||
eventName: PROJECT_SETTINGS_TRACKER_EVENTS.estimates_toggle,
|
||||
state: "SUCCESS",
|
||||
},
|
||||
});
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: currentProjectActiveEstimate
|
||||
@@ -40,6 +51,15 @@ export const EstimateDisableSwitch: FC<TEstimateDisableSwitch> = observer((props
|
||||
: t("project_settings.estimates.toasts.enabled.success.message"),
|
||||
});
|
||||
} catch (err) {
|
||||
captureElementAndEvent({
|
||||
element: {
|
||||
elementName: PROJECT_SETTINGS_TRACKER_ELEMENTS.ESTIMATES_TOGGLE_BUTTON,
|
||||
},
|
||||
event: {
|
||||
eventName: PROJECT_SETTINGS_TRACKER_EVENTS.estimates_toggle,
|
||||
state: "ERROR",
|
||||
},
|
||||
});
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: t("project_settings.estimates.toasts.disabled.error.title"),
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { MutableRefObject, useRef, useState } from "react";
|
||||
import { LucideIcon, X } from "lucide-react";
|
||||
// plane helpers
|
||||
import { PROJECT_SETTINGS_TRACKER_ELEMENTS, PROJECT_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
|
||||
import { useOutsideClickDetector } from "@plane/hooks";
|
||||
// types
|
||||
import { IIssueLabel } from "@plane/types";
|
||||
@@ -11,6 +12,7 @@ import { CustomMenu, DragHandle } from "@plane/ui";
|
||||
// helpers
|
||||
import { cn } from "@plane/utils";
|
||||
// components
|
||||
import { captureSuccess } from "@/helpers/event-tracker.helper";
|
||||
import { LabelName } from "./label-name";
|
||||
|
||||
export interface ICustomMenuItem {
|
||||
@@ -90,7 +92,16 @@ export const LabelItemBlock = (props: ILabelItemBlock) => {
|
||||
<div className="py-0.5">
|
||||
<button
|
||||
className="flex size-5 items-center justify-center rounded hover:bg-custom-background-80"
|
||||
onClick={() => handleLabelDelete(label)}
|
||||
onClick={() => {
|
||||
handleLabelDelete(label);
|
||||
captureSuccess({
|
||||
eventName: PROJECT_SETTINGS_TRACKER_EVENTS.label_deleted,
|
||||
payload: {
|
||||
id: label?.id,
|
||||
},
|
||||
});
|
||||
}}
|
||||
data-ph-element={PROJECT_SETTINGS_TRACKER_ELEMENTS.LABELS_DELETE_BUTTON}
|
||||
>
|
||||
<X className="size-3.5 flex-shrink-0 text-custom-sidebar-text-300" />
|
||||
</button>
|
||||
|
||||
@@ -2,8 +2,10 @@ import React, { Dispatch, SetStateAction, useState } from "react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { X, Pencil } from "lucide-react";
|
||||
// types
|
||||
import { PROJECT_SETTINGS_TRACKER_ELEMENTS, PROJECT_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
|
||||
import { IIssueLabel } from "@plane/types";
|
||||
// hooks
|
||||
import { captureElementAndEvent } from "@/helpers/event-tracker.helper";
|
||||
import { useLabel } from "@/hooks/store";
|
||||
// components
|
||||
import { CreateUpdateLabelInline, TLabelOperationsCallbacks } from "./create-update-label-inline";
|
||||
@@ -67,6 +69,16 @@ export const ProjectSettingLabelItem: React.FC<Props> = (props) => {
|
||||
onClick: () => {
|
||||
setEditLabelForm(true);
|
||||
setIsUpdating(true);
|
||||
captureElementAndEvent({
|
||||
element: {
|
||||
elementName: PROJECT_SETTINGS_TRACKER_ELEMENTS.LABELS_CONTEXT_MENU,
|
||||
},
|
||||
event: {
|
||||
eventName: PROJECT_SETTINGS_TRACKER_EVENTS.label_updated,
|
||||
payload: { id: label?.id },
|
||||
state: "SUCCESS",
|
||||
},
|
||||
});
|
||||
},
|
||||
isVisible: true,
|
||||
text: "Edit label",
|
||||
|
||||
@@ -4,10 +4,15 @@ import React, { useState, useRef } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
// plane imports
|
||||
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
|
||||
import {
|
||||
EUserPermissions,
|
||||
EUserPermissionsLevel,
|
||||
PROJECT_SETTINGS_TRACKER_ELEMENTS,
|
||||
PROJECT_SETTINGS_TRACKER_EVENTS,
|
||||
} from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { IIssueLabel } from "@plane/types";
|
||||
import { Button, Loader } from "@plane/ui";
|
||||
import { Loader } from "@plane/ui";
|
||||
import { DetailedEmptyState } from "@/components/empty-state";
|
||||
import {
|
||||
CreateUpdateLabelInline,
|
||||
@@ -17,6 +22,7 @@ import {
|
||||
TLabelOperationsCallbacks,
|
||||
} from "@/components/labels";
|
||||
// hooks
|
||||
import { captureElementAndEvent } from "@/helpers/event-tracker.helper";
|
||||
import { useLabel, useUserPermissions } from "@/hooks/store";
|
||||
import { useResolvedAssetPath } from "@/hooks/use-resolved-asset-path";
|
||||
import { SettingsHeading } from "../settings";
|
||||
@@ -81,7 +87,18 @@ export const ProjectSettingsLabelList: React.FC = observer(() => {
|
||||
description={t("project_settings.labels.description")}
|
||||
button={{
|
||||
label: t("common.add_label"),
|
||||
onClick: newLabel,
|
||||
onClick: () => {
|
||||
newLabel();
|
||||
captureElementAndEvent({
|
||||
element: {
|
||||
elementName: PROJECT_SETTINGS_TRACKER_ELEMENTS.LABELS_HEADER_CREATE_BUTTON,
|
||||
},
|
||||
event: {
|
||||
eventName: PROJECT_SETTINGS_TRACKER_EVENTS.label_created,
|
||||
state: "SUCCESS",
|
||||
},
|
||||
});
|
||||
},
|
||||
}}
|
||||
showButton={isEditable}
|
||||
/>
|
||||
@@ -110,7 +127,18 @@ export const ProjectSettingsLabelList: React.FC = observer(() => {
|
||||
description={""}
|
||||
primaryButton={{
|
||||
text: "Create your first label",
|
||||
onClick: newLabel,
|
||||
onClick: () => {
|
||||
newLabel();
|
||||
captureElementAndEvent({
|
||||
element: {
|
||||
elementName: PROJECT_SETTINGS_TRACKER_ELEMENTS.LABELS_EMPTY_STATE_CREATE_BUTTON,
|
||||
},
|
||||
event: {
|
||||
eventName: PROJECT_SETTINGS_TRACKER_EVENTS.label_created,
|
||||
state: "SUCCESS",
|
||||
},
|
||||
});
|
||||
},
|
||||
}}
|
||||
assetPath={resolvedPath}
|
||||
className="w-full !px-0 !py-0"
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
import { FC } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { PROJECT_TRACKER_ELEMENTS } from "@plane/constants";
|
||||
import { PROJECT_TRACKER_ELEMENTS, PROJECT_TRACKER_EVENTS } from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { IProject } from "@plane/types";
|
||||
import { ToggleSwitch, Tooltip, setPromiseToast } from "@plane/ui";
|
||||
// hooks
|
||||
import { SettingsHeading } from "@/components/settings";
|
||||
import { captureSuccess } from "@/helpers/event-tracker.helper";
|
||||
import { useProject, useUser } from "@/hooks/store";
|
||||
// plane web components
|
||||
import { UpgradeBadge } from "@/plane-web/components/workspace";
|
||||
@@ -37,6 +38,7 @@ export const ProjectFeaturesList: FC<Props> = observer((props) => {
|
||||
[featureProperty]: !currentProjectDetails?.[featureProperty as keyof IProject],
|
||||
};
|
||||
const updateProjectPromise = updateProject(workspaceSlug, projectId, settingsPayload);
|
||||
|
||||
setPromiseToast(updateProjectPromise, {
|
||||
loading: "Updating project feature...",
|
||||
success: {
|
||||
@@ -48,6 +50,14 @@ export const ProjectFeaturesList: FC<Props> = observer((props) => {
|
||||
message: () => "Something went wrong while updating project feature. Please try again.",
|
||||
},
|
||||
});
|
||||
updateProjectPromise.then(() => {
|
||||
captureSuccess({
|
||||
eventName: PROJECT_TRACKER_EVENTS.feature_toggled,
|
||||
payload: {
|
||||
feature_key: featureKey,
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
if (!currentUser) return <></>;
|
||||
|
||||
@@ -26,6 +26,7 @@ export const PROJECT_TRACKER_EVENTS = {
|
||||
create: "project_created",
|
||||
update: "project_updated",
|
||||
delete: "project_deleted",
|
||||
feature_toggled: "feature_toggled",
|
||||
};
|
||||
export const PROJECT_TRACKER_ELEMENTS = {
|
||||
EXTENDED_SIDEBAR_ADD_BUTTON: "extended_sidebar_add_project_button",
|
||||
@@ -268,3 +269,29 @@ export const SIDEBAR_TRACKER_ELEMENTS = {
|
||||
USER_MENU_ITEM: "sidenav_user_menu_item",
|
||||
CREATE_WORK_ITEM_BUTTON: "sidebar_create_work_item_button",
|
||||
};
|
||||
|
||||
export const PROJECT_SETTINGS_TRACKER_ELEMENTS = {
|
||||
LABELS_EMPTY_STATE_CREATE_BUTTON: "labels_empty_state_create_button",
|
||||
LABELS_HEADER_CREATE_BUTTON: "labels_header_create_button",
|
||||
LABELS_CONTEXT_MENU: "labels_context_menu",
|
||||
LABELS_DELETE_BUTTON: "labels_delete_button",
|
||||
ESTIMATES_TOGGLE_BUTTON: "estimates_toggle_button",
|
||||
ESTIMATES_EMPTY_STATE_CREATE_BUTTON: "estimates_empty_state_create_button",
|
||||
ESTIMATES_LIST_ITEM: "estimates_list_item",
|
||||
AUTOMATIONS_ARCHIVE_TOGGLE_BUTTON: "automations_archive_toggle_button",
|
||||
AUTOMATIONS_CLOSE_TOGGLE_BUTTON: "automations_close_toggle_button",
|
||||
};
|
||||
export const PROJECT_SETTINGS_TRACKER_EVENTS = {
|
||||
// labels
|
||||
label_created: "label_created",
|
||||
label_updated: "label_updated",
|
||||
label_deleted: "label_deleted",
|
||||
// estimates
|
||||
estimate_created: "estimate_created",
|
||||
estimate_updated: "estimate_updated",
|
||||
estimate_deleted: "estimate_deleted",
|
||||
estimates_toggle: "estimates_toggled",
|
||||
// automations
|
||||
auto_close_workitems: "auto_close_workitems",
|
||||
auto_archive_workitems: "auto_archive_workitems",
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user