From 866338289ed23033190989789b7bd6a680f88445 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Tue, 30 Dec 2025 13:22:28 +0530 Subject: [PATCH 01/11] chore: navigation preference enhancements (#8468) --- .../(projects)/browse/[workItem]/header.tsx | 2 +- .../projects/(detail)/[projectId]/layout.tsx | 2 +- apps/web/ce/components/breadcrumbs/common.tsx | 2 +- .../components/common/extended-app-header.tsx | 2 +- .../customize-navigation-dialog.tsx | 12 +-- .../workspace/sidebar/projects-list-item.tsx | 6 +- apps/web/core/constants/fetch-keys.ts | 3 + .../core/hooks/use-navigation-preferences.ts | 77 ++++++++++++------- .../layouts/auth-layout/workspace-wrapper.tsx | 10 ++- apps/web/core/services/workspace.service.ts | 20 +++++ apps/web/core/store/workspace/index.ts | 63 ++++++++++++++- apps/web/core/types/navigation-preferences.ts | 4 +- packages/types/src/view-props.ts | 6 ++ 13 files changed, 165 insertions(+), 44 deletions(-) diff --git a/apps/web/app/(all)/[workspaceSlug]/(projects)/browse/[workItem]/header.tsx b/apps/web/app/(all)/[workspaceSlug]/(projects)/browse/[workItem]/header.tsx index cf5176a2be..091fdae9db 100644 --- a/apps/web/app/(all)/[workspaceSlug]/(projects)/browse/[workItem]/header.tsx +++ b/apps/web/app/(all)/[workspaceSlug]/(projects)/browse/[workItem]/header.tsx @@ -30,7 +30,7 @@ export const ProjectWorkItemDetailsHeader = observer(function ProjectWorkItemDet return ( <> - {projectPreferences.navigationMode === "horizontal" && ( + {projectPreferences.navigationMode === "TABBED" && (
diff --git a/apps/web/app/(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/layout.tsx b/apps/web/app/(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/layout.tsx index c3a27ec6ec..885ccf786a 100644 --- a/apps/web/app/(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/layout.tsx +++ b/apps/web/app/(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/layout.tsx @@ -23,7 +23,7 @@ function ProjectLayout({ params }: Route.ComponentProps) { return ( <> - {projectPreferences.navigationMode === "horizontal" && ( + {projectPreferences.navigationMode === "TABBED" && (
diff --git a/apps/web/ce/components/breadcrumbs/common.tsx b/apps/web/ce/components/breadcrumbs/common.tsx index 397de3db55..1aaeaaa78f 100644 --- a/apps/web/ce/components/breadcrumbs/common.tsx +++ b/apps/web/ce/components/breadcrumbs/common.tsx @@ -12,6 +12,6 @@ export function CommonProjectBreadcrumbs(props: TCommonProjectBreadcrumbProps) { // preferences const { preferences: projectPreferences } = useProjectNavigationPreferences(); - if (projectPreferences.navigationMode === "horizontal") return null; + if (projectPreferences.navigationMode === "TABBED") return null; return ; } diff --git a/apps/web/ce/components/common/extended-app-header.tsx b/apps/web/ce/components/common/extended-app-header.tsx index f8661d5c20..10c782d32b 100644 --- a/apps/web/ce/components/common/extended-app-header.tsx +++ b/apps/web/ce/components/common/extended-app-header.tsx @@ -16,7 +16,7 @@ export const ExtendedAppHeader = observer(function ExtendedAppHeader(props: { he // store hooks const { sidebarCollapsed } = useAppTheme(); // derived values - const shouldShowSidebarToggleButton = projectPreferences.navigationMode === "accordion" || (!projectId && !workItem); + const shouldShowSidebarToggleButton = projectPreferences.navigationMode === "ACCORDION" || (!projectId && !workItem); return ( <> diff --git a/apps/web/core/components/navigation/customize-navigation-dialog.tsx b/apps/web/core/components/navigation/customize-navigation-dialog.tsx index b2815c777c..63edd309b6 100644 --- a/apps/web/core/components/navigation/customize-navigation-dialog.tsx +++ b/apps/web/core/components/navigation/customize-navigation-dialog.tsx @@ -265,9 +265,9 @@ export const CustomizeNavigationDialog = observer(function CustomizeNavigationDi updateNavigationMode("accordion")} + value="ACCORDION" + checked={projectPreferences.navigationMode === "ACCORDION"} + onChange={() => updateNavigationMode("ACCORDION")} className="size-4 text-accent-primary focus:ring-accent-strong mt-1" />
@@ -282,9 +282,9 @@ export const CustomizeNavigationDialog = observer(function CustomizeNavigationDi updateNavigationMode("horizontal")} + value="TABBED" + checked={projectPreferences.navigationMode === "TABBED"} + onChange={() => updateNavigationMode("TABBED")} className="size-4 text-accent-primary focus:ring-accent-strong mt-1" />
diff --git a/apps/web/core/components/workspace/sidebar/projects-list-item.tsx b/apps/web/core/components/workspace/sidebar/projects-list-item.tsx index 97f6b2b2c8..d869a12cb6 100644 --- a/apps/web/core/components/workspace/sidebar/projects-list-item.tsx +++ b/apps/web/core/components/workspace/sidebar/projects-list-item.tsx @@ -255,7 +255,7 @@ export const SidebarProjectsListItem = observer(function SidebarProjectsListItem if (!project) return null; const handleItemClick = () => { - if (projectPreferences.navigationMode === "accordion") { + if (projectPreferences.navigationMode === "ACCORDION") { setIsProjectListOpen(!isProjectListOpen); } else { router.push(defaultTabUrl); @@ -266,9 +266,9 @@ export const SidebarProjectsListItem = observer(function SidebarProjectsListItem } }; - const isAccordionMode = projectPreferences.navigationMode === "accordion"; + const isAccordionMode = projectPreferences.navigationMode === "ACCORDION"; - const shouldHighlightProject = URLProjectId === project?.id && projectPreferences.navigationMode !== "accordion"; + const shouldHighlightProject = URLProjectId === project?.id && projectPreferences.navigationMode !== "ACCORDION"; return ( <> diff --git a/apps/web/core/constants/fetch-keys.ts b/apps/web/core/constants/fetch-keys.ts index 0a54ccc196..b7d669506e 100644 --- a/apps/web/core/constants/fetch-keys.ts +++ b/apps/web/core/constants/fetch-keys.ts @@ -83,6 +83,9 @@ export const WORKSPACE_STATES = (workspaceSlug: string) => `WORKSPACE_STATES_${w export const WORKSPACE_SIDEBAR_PREFERENCES = (workspaceSlug: string) => `WORKSPACE_SIDEBAR_PREFERENCES_${workspaceSlug.toUpperCase()}`; +export const WORKSPACE_PROJECT_NAVIGATION_PREFERENCES = (workspaceSlug: string) => + `WORKSPACE_PROJECT_NAVIGATION_PREFERENCES_${workspaceSlug.toUpperCase()}`; + export const PROJECT_GITHUB_REPOSITORY = (projectId: string) => `PROJECT_GITHUB_REPOSITORY_${projectId.toUpperCase()}`; // cycles diff --git a/apps/web/core/hooks/use-navigation-preferences.ts b/apps/web/core/hooks/use-navigation-preferences.ts index 1672936ccd..155414cb8e 100644 --- a/apps/web/core/hooks/use-navigation-preferences.ts +++ b/apps/web/core/hooks/use-navigation-preferences.ts @@ -19,7 +19,6 @@ import { import { useWorkspace } from "./store/use-workspace"; import useLocalStorage from "./use-local-storage"; -const PROJECT_PREFERENCES_KEY = "navigation_preferences_projects"; const APP_RAIL_PREFERENCES_KEY = "app_rail_preferences"; export const usePersonalNavigationPreferences = () => { @@ -105,49 +104,73 @@ export const usePersonalNavigationPreferences = () => { }; export const useProjectNavigationPreferences = () => { - const { storedValue, setValue } = useLocalStorage( - PROJECT_PREFERENCES_KEY, - DEFAULT_PROJECT_PREFERENCES - ); + const { workspaceSlug } = useParams(); + const { getProjectNavigationPreferences, updateProjectNavigationPreferences } = useWorkspace(); + // Get preferences from the store + const storePreferences = getProjectNavigationPreferences(workspaceSlug?.toString() || ""); + + // Computed preferences with fallback logic: API → defaults + const preferences: TProjectNavigationPreferences = useMemo(() => { + // 1. Try API data first + if ( + storePreferences && + (storePreferences.navigation_control_preference || storePreferences.navigation_project_limit !== undefined) + ) { + const limit = storePreferences.navigation_project_limit ?? DEFAULT_PROJECT_PREFERENCES.limitedProjectsCount; + + return { + navigationMode: storePreferences.navigation_control_preference || DEFAULT_PROJECT_PREFERENCES.navigationMode, + limitedProjectsCount: limit > 0 ? limit : DEFAULT_PROJECT_PREFERENCES.limitedProjectsCount, + showLimitedProjects: limit > 0, // Derived: 0 = false, >0 = true + }; + } + + // 2. Fall back to defaults + return DEFAULT_PROJECT_PREFERENCES; + }, [storePreferences]); + + // Update navigation mode const updateNavigationMode = useCallback( - (mode: TProjectNavigationMode) => { - const currentPreferences = storedValue || DEFAULT_PROJECT_PREFERENCES; - setValue({ - navigationMode: mode, - showLimitedProjects: currentPreferences.showLimitedProjects, - limitedProjectsCount: currentPreferences.limitedProjectsCount, + async (mode: TProjectNavigationMode) => { + if (!workspaceSlug) return; + + await updateProjectNavigationPreferences(workspaceSlug.toString(), { + navigation_control_preference: mode, }); }, - [storedValue, setValue] + [workspaceSlug, updateProjectNavigationPreferences] ); + // Update show limited projects const updateShowLimitedProjects = useCallback( - (show: boolean) => { - const currentPreferences = storedValue || DEFAULT_PROJECT_PREFERENCES; - setValue({ - navigationMode: currentPreferences.navigationMode, - showLimitedProjects: show, - limitedProjectsCount: currentPreferences.limitedProjectsCount, + async (show: boolean) => { + if (!workspaceSlug) return; + + // When toggling off, set to 0; when toggling on, use current count or default + const newLimit = show ? preferences.limitedProjectsCount || DEFAULT_PROJECT_PREFERENCES.limitedProjectsCount : 0; + + await updateProjectNavigationPreferences(workspaceSlug.toString(), { + navigation_project_limit: newLimit, }); }, - [storedValue, setValue] + [workspaceSlug, updateProjectNavigationPreferences, preferences.limitedProjectsCount] ); + // Update limited projects count const updateLimitedProjectsCount = useCallback( - (count: number) => { - const currentPreferences = storedValue || DEFAULT_PROJECT_PREFERENCES; - setValue({ - navigationMode: currentPreferences.navigationMode, - showLimitedProjects: currentPreferences.showLimitedProjects, - limitedProjectsCount: count, + async (count: number) => { + if (!workspaceSlug) return; + + await updateProjectNavigationPreferences(workspaceSlug.toString(), { + navigation_project_limit: count, }); }, - [storedValue, setValue] + [workspaceSlug, updateProjectNavigationPreferences] ); return { - preferences: storedValue || DEFAULT_PROJECT_PREFERENCES, + preferences, updateNavigationMode, updateShowLimitedProjects, updateLimitedProjectsCount, diff --git a/apps/web/core/layouts/auth-layout/workspace-wrapper.tsx b/apps/web/core/layouts/auth-layout/workspace-wrapper.tsx index b8c000e386..256afec7df 100644 --- a/apps/web/core/layouts/auth-layout/workspace-wrapper.tsx +++ b/apps/web/core/layouts/auth-layout/workspace-wrapper.tsx @@ -24,6 +24,7 @@ import { WORKSPACE_FAVORITE, WORKSPACE_STATES, WORKSPACE_SIDEBAR_PREFERENCES, + WORKSPACE_PROJECT_NAVIGATION_PREFERENCES, } from "@/constants/fetch-keys"; // hooks import { useFavorite } from "@/hooks/store/use-favorite"; @@ -50,7 +51,7 @@ export const WorkspaceAuthWrapper = observer(function WorkspaceAuthWrapper(props const { workspace: { fetchWorkspaceMembers }, } = useMember(); - const { workspaces, fetchSidebarNavigationPreferences } = useWorkspace(); + const { workspaces, fetchSidebarNavigationPreferences, fetchProjectNavigationPreferences } = useWorkspace(); const { isMobile } = usePlatformOS(); const { loader, workspaceInfoBySlug, fetchUserWorkspaceInfo, fetchUserProjectPermissions, allowPermissions } = useUserPermissions(); @@ -113,6 +114,13 @@ export const WorkspaceAuthWrapper = observer(function WorkspaceAuthWrapper(props { revalidateIfStale: false, revalidateOnFocus: false } ); + // fetch workspace project navigation preferences + useSWR( + workspaceSlug ? WORKSPACE_PROJECT_NAVIGATION_PREFERENCES(workspaceSlug.toString()) : null, + workspaceSlug ? () => fetchProjectNavigationPreferences(workspaceSlug.toString()) : null, + { revalidateIfStale: false, revalidateOnFocus: false } + ); + const handleSignOut = async () => { await signOut().catch(() => setToast({ diff --git a/apps/web/core/services/workspace.service.ts b/apps/web/core/services/workspace.service.ts index 0811a562ad..c544348266 100644 --- a/apps/web/core/services/workspace.service.ts +++ b/apps/web/core/services/workspace.service.ts @@ -19,6 +19,7 @@ import type { TActivityEntityData, IWorkspaceSidebarNavigationItem, IWorkspaceSidebarNavigation, + IWorkspaceUserPropertiesResponse, } from "@plane/types"; // services import { APIService } from "@/services/api.service"; @@ -397,4 +398,23 @@ export class WorkspaceService extends APIService { throw error?.response; }); } + + async fetchWorkspaceFilters(workspaceSlug: string): Promise { + return this.get(`/api/workspaces/${workspaceSlug}/user-properties/`) + .then((response) => response?.data) + .catch((error) => { + throw error?.response?.data; + }); + } + + async patchWorkspaceFilters( + workspaceSlug: string, + data: Partial + ): Promise { + return this.patch(`/api/workspaces/${workspaceSlug}/user-properties/`, data) + .then((response) => response?.data) + .catch((error) => { + throw error?.response?.data; + }); + } } diff --git a/apps/web/core/store/workspace/index.ts b/apps/web/core/store/workspace/index.ts index eea83642f2..797398a1fd 100644 --- a/apps/web/core/store/workspace/index.ts +++ b/apps/web/core/store/workspace/index.ts @@ -2,7 +2,12 @@ import { clone, set } from "lodash-es"; import { action, computed, observable, makeObservable, runInAction } from "mobx"; // types import { computedFn } from "mobx-utils"; -import type { IWorkspaceSidebarNavigationItem, IWorkspace, IWorkspaceSidebarNavigation } from "@plane/types"; +import type { + IWorkspaceSidebarNavigationItem, + IWorkspace, + IWorkspaceSidebarNavigation, + IWorkspaceUserPropertiesResponse, +} from "@plane/types"; // services import { WorkspaceService } from "@/plane-web/services"; // store @@ -23,6 +28,7 @@ export interface IWorkspaceRootStore { currentWorkspace: IWorkspace | null; workspacesCreatedByCurrentUser: IWorkspace[] | null; navigationPreferencesMap: Record; + projectNavigationPreferencesMap: Record; getWorkspaceRedirectionUrl: () => string; // computed actions getWorkspaceBySlug: (workspaceSlug: string) => IWorkspace | null; @@ -45,6 +51,12 @@ export interface IWorkspaceRootStore { data: Array<{ key: string; is_pinned: boolean; sort_order: number }> ) => Promise; getNavigationPreferences: (workspaceSlug: string) => IWorkspaceSidebarNavigation | undefined; + getProjectNavigationPreferences: (workspaceSlug: string) => IWorkspaceUserPropertiesResponse | undefined; + fetchProjectNavigationPreferences: (workspaceSlug: string) => Promise; + updateProjectNavigationPreferences: ( + workspaceSlug: string, + data: Partial + ) => Promise; mutateWorkspaceMembersActivity: (workspaceSlug: string) => Promise; // sub-stores webhook: IWebhookStore; @@ -57,6 +69,7 @@ export abstract class BaseWorkspaceRootStore implements IWorkspaceRootStore { // observables workspaces: Record = {}; navigationPreferencesMap: Record = {}; + projectNavigationPreferencesMap: Record = {}; // services workspaceService; // root store @@ -73,6 +86,7 @@ export abstract class BaseWorkspaceRootStore implements IWorkspaceRootStore { // observables workspaces: observable, navigationPreferencesMap: observable, + projectNavigationPreferencesMap: observable, // computed currentWorkspace: computed, workspacesCreatedByCurrentUser: computed, @@ -88,6 +102,8 @@ export abstract class BaseWorkspaceRootStore implements IWorkspaceRootStore { fetchSidebarNavigationPreferences: action, updateSidebarPreference: action, updateBulkSidebarPreferences: action, + fetchProjectNavigationPreferences: action, + updateProjectNavigationPreferences: action, }); // services @@ -315,6 +331,51 @@ export abstract class BaseWorkspaceRootStore implements IWorkspaceRootStore { } }; + getProjectNavigationPreferences = computedFn( + (workspaceSlug: string): IWorkspaceUserPropertiesResponse | undefined => + this.projectNavigationPreferencesMap[workspaceSlug] + ); + + fetchProjectNavigationPreferences = async (workspaceSlug: string) => { + try { + const response = await this.workspaceService.fetchWorkspaceFilters(workspaceSlug); + + runInAction(() => { + this.projectNavigationPreferencesMap[workspaceSlug] = response; + }); + } catch (error) { + console.error("Failed to fetch project navigation preferences:", error); + throw error; + } + }; + + updateProjectNavigationPreferences = async ( + workspaceSlug: string, + data: Partial + ) => { + const beforeUpdateData = clone(this.projectNavigationPreferencesMap[workspaceSlug]); + + try { + // Optimistically update store + runInAction(() => { + this.projectNavigationPreferencesMap[workspaceSlug] = { + ...this.projectNavigationPreferencesMap[workspaceSlug], + ...data, + }; + }); + + // Call API to persist changes + await this.workspaceService.patchWorkspaceFilters(workspaceSlug, data); + } catch (error) { + // Rollback on failure + runInAction(() => { + this.projectNavigationPreferencesMap[workspaceSlug] = beforeUpdateData; + }); + console.error("Failed to update project navigation preferences:", error); + throw error; + } + }; + /** * Mutate workspace members activity * @param workspaceSlug diff --git a/apps/web/core/types/navigation-preferences.ts b/apps/web/core/types/navigation-preferences.ts index 357593a5aa..3f03802f52 100644 --- a/apps/web/core/types/navigation-preferences.ts +++ b/apps/web/core/types/navigation-preferences.ts @@ -11,7 +11,7 @@ export interface TPersonalNavigationItemState { sort_order: number; } -export type TProjectNavigationMode = "accordion" | "horizontal"; +export type TProjectNavigationMode = "ACCORDION" | "TABBED"; export interface TProjectDisplaySettings { navigationMode: TProjectNavigationMode; @@ -54,7 +54,7 @@ export const DEFAULT_PERSONAL_PREFERENCES: TPersonalNavigationPreferences = { }; export const DEFAULT_PROJECT_PREFERENCES: TProjectNavigationPreferences = { - navigationMode: "accordion", + navigationMode: "ACCORDION", showLimitedProjects: false, limitedProjectsCount: 10, }; diff --git a/packages/types/src/view-props.ts b/packages/types/src/view-props.ts index 7211b58a4a..aa90541a95 100644 --- a/packages/types/src/view-props.ts +++ b/packages/types/src/view-props.ts @@ -194,6 +194,12 @@ export interface IIssueFiltersResponse { display_properties: IIssueDisplayProperties; } +export interface IWorkspaceUserPropertiesResponse extends IIssueFiltersResponse { + navigation_project_limit?: number; + navigation_control_preference?: "ACCORDION" | "TABBED"; + // Note: show_limited_projects is derived from navigation_project_limit (0 = false, >0 = true) +} + export interface IWorkspaceIssueFilterOptions { assignees?: string[] | null; created_by?: string[] | null; From 9141a9377f55144e700f0866bee65c3685efe963 Mon Sep 17 00:00:00 2001 From: Jayash Tripathy <76092296+JayashTripathy@users.noreply.github.com> Date: Tue, 30 Dec 2025 14:32:48 +0530 Subject: [PATCH 02/11] [WEB-5472] refactor: components of project creation flow (#8462) --- .../components/projects/create/attributes.tsx | 3 +- .../ce/components/projects/create/root.tsx | 21 +++++----- .../projects/create/template-select.tsx | 7 +--- .../project/create-project-modal.tsx | 2 +- .../project/create/common-attributes.tsx | 30 +++++++------- .../core/components/project/create/header.tsx | 39 ++++++++++++------- packages/types/src/index.ts | 1 + packages/types/src/pagination.ts | 15 +++++++ 8 files changed, 70 insertions(+), 48 deletions(-) create mode 100644 packages/types/src/pagination.ts diff --git a/apps/web/ce/components/projects/create/attributes.tsx b/apps/web/ce/components/projects/create/attributes.tsx index d86a381098..f19537bdca 100644 --- a/apps/web/ce/components/projects/create/attributes.tsx +++ b/apps/web/ce/components/projects/create/attributes.tsx @@ -1,4 +1,3 @@ -import type { FC } from "react"; import { Controller, useFormContext } from "react-hook-form"; // plane imports import { NETWORK_CHOICES, ETabIndices } from "@plane/constants"; @@ -79,7 +78,7 @@ function ProjectAttributes(props: Props) { placeholder={t("lead")} multiple={false} buttonVariant="border-with-text" - tabIndex={5} + tabIndex={getIndex("lead")} />
); diff --git a/apps/web/ce/components/projects/create/root.tsx b/apps/web/ce/components/projects/create/root.tsx index dce8102940..ddf7920b47 100644 --- a/apps/web/ce/components/projects/create/root.tsx +++ b/apps/web/ce/components/projects/create/root.tsx @@ -1,24 +1,23 @@ -import { useState } from "react"; -import { observer } from "mobx-react"; -import { FormProvider, useForm } from "react-hook-form"; -import { PROJECT_TRACKER_EVENTS, RANDOM_EMOJI_CODES } from "@plane/constants"; +import { PROJECT_TRACKER_EVENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; +import { observer } from "mobx-react"; +import { useState } from "react"; +import { FormProvider, useForm } from "react-hook-form"; // ui import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import { EFileAssetType } from "@plane/types"; -import type { IProject } from "@plane/types"; // constants import ProjectCommonAttributes from "@/components/project/create/common-attributes"; import ProjectCreateHeader from "@/components/project/create/header"; import ProjectCreateButtons from "@/components/project/create/project-create-buttons"; // hooks -import { DEFAULT_COVER_IMAGE_URL, getCoverImageType, uploadCoverImage } from "@/helpers/cover-image.helper"; +import { getCoverImageType, uploadCoverImage } from "@/helpers/cover-image.helper"; import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useProject } from "@/hooks/store/use-project"; import { usePlatformOS } from "@/hooks/use-platform-os"; // plane web types import type { TProject } from "@/plane-web/types/projects"; -import ProjectAttributes from "./attributes"; +import { ProjectAttributes } from "./attributes"; import { getProjectFormValues } from "./utils"; export type TCreateProjectFormProps = { @@ -37,7 +36,7 @@ export const CreateProjectForm = observer(function CreateProjectForm(props: TCre const { t } = useTranslation(); const { addProjectToFavorites, createProject, updateProject } = useProject(); // states - const [isChangeInIdentifierRequired, setIsChangeInIdentifierRequired] = useState(true); + const [shouldAutoSyncIdentifier, setShouldAutoSyncIdentifier] = useState(true); // form info const methods = useForm({ defaultValues: { ...getProjectFormValues(), ...data }, @@ -167,7 +166,7 @@ export const CreateProjectForm = observer(function CreateProjectForm(props: TCre const handleClose = () => { onClose(); - setIsChangeInIdentifierRequired(true); + setShouldAutoSyncIdentifier(true); setTimeout(() => { reset(); }, 300); @@ -182,8 +181,8 @@ export const CreateProjectForm = observer(function CreateProjectForm(props: TCre
diff --git a/apps/web/ce/components/projects/create/template-select.tsx b/apps/web/ce/components/projects/create/template-select.tsx index b41232852c..3220c0fe85 100644 --- a/apps/web/ce/components/projects/create/template-select.tsx +++ b/apps/web/ce/components/projects/create/template-select.tsx @@ -1,11 +1,6 @@ -type TProjectTemplateDropdownSize = "xs" | "sm"; - export type TProjectTemplateSelect = { disabled?: boolean; - size?: TProjectTemplateDropdownSize; - placeholder?: string; - dropDownContainerClassName?: string; - handleModalClose: () => void; + onClick?: () => void; }; // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/apps/web/core/components/project/create-project-modal.tsx b/apps/web/core/components/project/create-project-modal.tsx index 46e102703c..ca6d0a2a66 100644 --- a/apps/web/core/components/project/create-project-modal.tsx +++ b/apps/web/core/components/project/create-project-modal.tsx @@ -60,7 +60,7 @@ export function CreateProjectModal(props: Props) { }); return ( - + {currentStep === EProjectCreationSteps.CREATE_PROJECT && ( ; isMobile: boolean; - isChangeInIdentifierRequired: boolean; - setIsChangeInIdentifierRequired: (value: boolean) => void; + shouldAutoSyncIdentifier: boolean; + setShouldAutoSyncIdentifier: (value: boolean) => void; handleFormOnChange?: () => void; }; function ProjectCommonAttributes(props: Props) { - const { setValue, isMobile, isChangeInIdentifierRequired, setIsChangeInIdentifierRequired, handleFormOnChange } = - props; + const { setValue, isMobile, shouldAutoSyncIdentifier, setShouldAutoSyncIdentifier, handleFormOnChange } = props; const { formState: { errors }, control, @@ -33,21 +32,22 @@ function ProjectCommonAttributes(props: Props) { const { getIndex } = getTabIndex(ETabIndices.PROJECT_CREATE, isMobile); const { t } = useTranslation(); - const handleNameChange = (onChange: (...event: any[]) => void) => (e: ChangeEvent) => { - if (!isChangeInIdentifierRequired) { + const handleNameChange = + (onChange: (event: ChangeEvent) => void) => (e: ChangeEvent) => { + if (!shouldAutoSyncIdentifier) { + onChange(e); + return; + } + if (e.target.value === "") setValue("identifier", ""); + else setValue("identifier", projectIdentifierSanitizer(e.target.value).substring(0, 10)); onChange(e); - return; - } - if (e.target.value === "") setValue("identifier", ""); - else setValue("identifier", projectIdentifierSanitizer(e.target.value).substring(0, 10)); - onChange(e); - handleFormOnChange?.(); - }; + handleFormOnChange?.(); + }; - const handleIdentifierChange = (onChange: any) => (e: ChangeEvent) => { + const handleIdentifierChange = (onChange: (value: string) => void) => (e: ChangeEvent) => { const { value } = e.target; const alphanumericValue = projectIdentifierSanitizer(value); - setIsChangeInIdentifierRequired(false); + setShouldAutoSyncIdentifier(false); onChange(alphanumericValue); handleFormOnChange?.(); }; diff --git a/apps/web/core/components/project/create/header.tsx b/apps/web/core/components/project/create/header.tsx index b201be4fd0..37f635cf9a 100644 --- a/apps/web/core/components/project/create/header.tsx +++ b/apps/web/core/components/project/create/header.tsx @@ -18,11 +18,14 @@ import { ProjectTemplateSelect } from "@/plane-web/components/projects/create/te type Props = { handleClose: () => void; isMobile?: boolean; + handleFormChange?: () => void; + isClosable?: boolean; + handleTemplateSelect?: () => void; }; function ProjectCreateHeader(props: Props) { - const { handleClose, isMobile = false } = props; - const { watch, control } = useFormContext(); + const { handleClose, isMobile = false, handleFormChange, isClosable = true, handleTemplateSelect } = props; + const { watch, control, setValue } = useFormContext(); const { t } = useTranslation(); // derived values const coverImage = watch("cover_image_url"); @@ -38,13 +41,15 @@ function ProjectCreateHeader(props: Props) { className="absolute left-0 top-0 h-full w-full rounded-lg" />
- -
-
- +
+ {isClosable && ( +
+ +
+ )}
( { + onChange(data); + handleFormChange?.(); + }} control={control} - onChange={onChange} value={value ?? null} tabIndex={getIndex("cover_image")} /> @@ -72,7 +80,7 @@ function ProjectCreateHeader(props: Props) { className="flex items-center justify-center" buttonClassName="flex items-center justify-center" label={ - + } @@ -85,15 +93,20 @@ function ProjectCreateHeader(props: Props) { }; else if (val?.type === "icon") logoValue = val.value; - onChange({ + const newLogoProps = { in_use: val?.type, [val?.type]: logoValue, + }; + setValue("logo_props", newLogoProps, { + shouldDirty: true, }); + onChange(newLogoProps); + handleFormChange?.(); setIsOpen(false); }} - defaultIconColor={value.in_use && value.in_use === "icon" ? value.icon?.color : undefined} + defaultIconColor={value?.in_use && value.in_use === "icon" ? value.icon?.color : undefined} defaultOpen={ - value.in_use && value.in_use === "emoji" ? EmojiIconPickerTypes.EMOJI : EmojiIconPickerTypes.ICON + value?.in_use && value.in_use === "emoji" ? EmojiIconPickerTypes.EMOJI : EmojiIconPickerTypes.ICON } /> )} diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 9908d5dba6..9d3103c83b 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -50,3 +50,4 @@ export * from "./workspace-draft-issues/base"; export * from "./workspace-notifications"; export * from "./workspace-views"; export * from "./base-layouts"; +export * from "./pagination"; diff --git a/packages/types/src/pagination.ts b/packages/types/src/pagination.ts new file mode 100644 index 0000000000..94ed237e75 --- /dev/null +++ b/packages/types/src/pagination.ts @@ -0,0 +1,15 @@ +// Generic paginated response type for API responses +export type TPaginatedResponse = { + results: T; + grouped_by?: string | null; + sub_grouped_by?: string | null; + total_count?: number; + next_cursor?: string; + prev_cursor?: string; + next_page_results?: boolean; + prev_page_results?: boolean; + count?: number; + total_pages?: number; + total_results?: number; + extra_stats?: string | null; +}; From 031baaa1621a6fa600e206ad3fea7c858d5d3130 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Tue, 30 Dec 2025 14:35:52 +0530 Subject: [PATCH 03/11] [WEB-857] regression: image uploader error state #8471 --- .../src/core/extensions/custom-image/components/uploader.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/editor/src/core/extensions/custom-image/components/uploader.tsx b/packages/editor/src/core/extensions/custom-image/components/uploader.tsx index ccd67ad096..109073d0b9 100644 --- a/packages/editor/src/core/extensions/custom-image/components/uploader.tsx +++ b/packages/editor/src/core/extensions/custom-image/components/uploader.tsx @@ -168,8 +168,7 @@ export function CustomImageUploader(props: CustomImageUploaderProps) { [uploadFile, editor, getPos] ); - // const isErrorState = failedToLoadImage || hasDuplicationFailed; - const isErrorState = true; + const isErrorState = failedToLoadImage || hasDuplicationFailed; const borderColor = selected && editor.isEditable && !isErrorState From c97e41851530fbb0426c542fa8739ab95218f8a5 Mon Sep 17 00:00:00 2001 From: b-saikrishnakanth <130811169+b-saikrishnakanth@users.noreply.github.com> Date: Tue, 30 Dec 2025 14:59:16 +0530 Subject: [PATCH 04/11] [WEB-4959]chore: refactor project member page #8464 --- .../settings/(workspace)/layout.tsx | 4 +- .../settings/(workspace)/members/page.tsx | 3 +- .../settings/projects/[projectId]/layout.tsx | 10 +++-- .../members/members-activity-button.tsx | 10 +++++ .../ce/components/settings/right-sidebar.tsx | 10 +++++ .../workspace/right-sidebar/index.ts | 1 - .../workspace/right-sidebar/root.tsx | 10 ----- .../ce/store/member/project-member.store.ts | 9 +++++ .../core/components/project/member-list.tsx | 5 +++ .../settings/invitations-list-item.tsx | 3 -- .../workspace/settings/member-columns.tsx | 3 -- .../workspace/settings/members-list-item.tsx | 3 +- apps/web/core/constants/fetch-keys.ts | 6 ++- .../project/base-project-member.store.ts | 21 +++++++--- .../workspace/workspace-member.store.ts | 38 ++++++++++--------- 15 files changed, 85 insertions(+), 51 deletions(-) create mode 100644 apps/web/ce/components/projects/members/members-activity-button.tsx create mode 100644 apps/web/ce/components/settings/right-sidebar.tsx delete mode 100644 apps/web/ce/components/workspace/right-sidebar/index.ts delete mode 100644 apps/web/ce/components/workspace/right-sidebar/root.tsx diff --git a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/layout.tsx b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/layout.tsx index 783f7a0dd0..5ac77bcccc 100644 --- a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/layout.tsx +++ b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/layout.tsx @@ -9,7 +9,7 @@ import { SettingsMobileNav } from "@/components/settings/mobile"; import { WORKSPACE_SETTINGS_ACCESS } from "@plane/constants"; import type { EUserWorkspaceRoles } from "@plane/types"; // plane web components -import { WorkspaceSettingsRightSidebar } from "@/plane-web/components/workspace/right-sidebar"; +import { SettingsRightSidebar } from "@/plane-web/components/settings/right-sidebar"; // hooks import { useUserPermissions } from "@/hooks/store/user"; // local components @@ -48,7 +48,7 @@ const WorkspaceSettingLayout = observer(function WorkspaceSettingLayout({ params
- +
)}
diff --git a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/members/page.tsx b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/members/page.tsx index 5c1fc059d8..1de0255b68 100644 --- a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/members/page.tsx +++ b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/members/page.tsx @@ -42,7 +42,7 @@ const WorkspaceMembersSettingsPage = observer(function WorkspaceMembersSettingsP const { workspace: { workspaceMemberIds, inviteMembersToWorkspace, filtersStore }, } = useMember(); - const { currentWorkspace, mutateWorkspaceMembersActivity } = useWorkspace(); + const { currentWorkspace } = useWorkspace(); const { t } = useTranslation(); // derived values @@ -55,7 +55,6 @@ const WorkspaceMembersSettingsPage = observer(function WorkspaceMembersSettingsP const handleWorkspaceInvite = async (data: IWorkspaceBulkInviteFormData) => { try { await inviteMembersToWorkspace(workspaceSlug, data); - void mutateWorkspaceMembersActivity(workspaceSlug); setInviteModal(false); diff --git a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/projects/[projectId]/layout.tsx b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/projects/[projectId]/layout.tsx index 8e8c09064d..2128bd2f2e 100644 --- a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/projects/[projectId]/layout.tsx +++ b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/projects/[projectId]/layout.tsx @@ -7,10 +7,13 @@ import { SettingsMobileNav } from "@/components/settings/mobile"; import { ProjectSettingsSidebar } from "@/components/settings/project/sidebar"; // plane web imports import { ProjectAuthWrapper } from "@/plane-web/layouts/project-wrapper"; +import { SettingsRightSidebar } from "@/plane-web/components/settings/right-sidebar"; // types import type { Route } from "./+types/layout"; -function ProjectDetailSettingsLayout({ params }: Route.ComponentProps) { +export const ProjectDetailSettingsLayout = observer(function ProjectDetailSettingsLayout({ + params, +}: Route.ComponentProps) { const { workspaceSlug, projectId } = params; // router const pathname = usePathname(); @@ -24,10 +27,11 @@ function ProjectDetailSettingsLayout({ params }: Route.ComponentProps) {
+
); -} +}); -export default observer(ProjectDetailSettingsLayout); +export default ProjectDetailSettingsLayout; diff --git a/apps/web/ce/components/projects/members/members-activity-button.tsx b/apps/web/ce/components/projects/members/members-activity-button.tsx new file mode 100644 index 0000000000..169d47a939 --- /dev/null +++ b/apps/web/ce/components/projects/members/members-activity-button.tsx @@ -0,0 +1,10 @@ +import { observer } from "mobx-react"; + +type TProjectMembersActivityButtonProps = { workspaceSlug: string; projectId: string }; + +export const ProjectMembersActivityButton = observer(function ProjectMembersActivityButton( + // eslint-disable-next-line @typescript-eslint/no-unused-vars + props: TProjectMembersActivityButtonProps +) { + return <>; +}); diff --git a/apps/web/ce/components/settings/right-sidebar.tsx b/apps/web/ce/components/settings/right-sidebar.tsx new file mode 100644 index 0000000000..887da2f8e3 --- /dev/null +++ b/apps/web/ce/components/settings/right-sidebar.tsx @@ -0,0 +1,10 @@ +import { observer } from "mobx-react"; + +type TSettingsRightSidebarProps = { workspaceSlug: string; projectId?: string }; + +export const SettingsRightSidebar = observer(function SettingsRightSidebar( + // eslint-disable-next-line @typescript-eslint/no-unused-vars + props: TSettingsRightSidebarProps +) { + return <>; +}); diff --git a/apps/web/ce/components/workspace/right-sidebar/index.ts b/apps/web/ce/components/workspace/right-sidebar/index.ts deleted file mode 100644 index 1efe34c51e..0000000000 --- a/apps/web/ce/components/workspace/right-sidebar/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./root"; diff --git a/apps/web/ce/components/workspace/right-sidebar/root.tsx b/apps/web/ce/components/workspace/right-sidebar/root.tsx deleted file mode 100644 index c98bb682a5..0000000000 --- a/apps/web/ce/components/workspace/right-sidebar/root.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { observer } from "mobx-react"; - -type TWorkspaceSettingsRightSidebarProps = { workspaceSlug: string }; - -export const WorkspaceSettingsRightSidebar = observer(function WorkspaceSettingsRightSidebar( - // eslint-disable-next-line @typescript-eslint/no-unused-vars - props: TWorkspaceSettingsRightSidebarProps -) { - return <>; -}); diff --git a/apps/web/ce/store/member/project-member.store.ts b/apps/web/ce/store/member/project-member.store.ts index f0e5b3069d..1be3ee1c1c 100644 --- a/apps/web/ce/store/member/project-member.store.ts +++ b/apps/web/ce/store/member/project-member.store.ts @@ -41,4 +41,13 @@ export class ProjectMemberStore extends BaseProjectMemberStore implements IProje * @param userId - The ID of the user to remove from the project */ processMemberRemoval = (projectId: string, userId: string) => this.handleMemberRemoval(projectId, userId); + + /** + * @description Mutate project members activity + * @param workspaceSlug + * @param projectId + */ + mutateProjectMembersActivity = async (_workspaceSlug: string, _projectId: string) => { + // No-op in default/CE version + }; } diff --git a/apps/web/core/components/project/member-list.tsx b/apps/web/core/components/project/member-list.tsx index 5dbe78d72e..acc32265f2 100644 --- a/apps/web/core/components/project/member-list.tsx +++ b/apps/web/core/components/project/member-list.tsx @@ -14,6 +14,8 @@ import { useUserPermissions } from "@/hooks/store/user"; import { MemberListFiltersDropdown } from "./dropdowns/filters/member-list"; import { ProjectMemberListItem } from "./member-list-item"; import { SendProjectInvitationModal } from "./send-project-invitation-modal"; +// plane web components +import { ProjectMembersActivityButton } from "@/plane-web/components/projects/members/members-activity-button"; type TProjectMemberListProps = { projectId: string; @@ -84,6 +86,7 @@ export const ProjectMemberList = observer(function ProjectMemberList(props: TPro className="w-full max-w-[234px] border-none bg-transparent text-13 focus:outline-none placeholder:text-placeholder" placeholder="Search" value={searchQuery} + // eslint-disable-next-line jsx-a11y/no-autofocus autoFocus onChange={(e) => setSearchQuery(e.target.value)} /> @@ -93,9 +96,11 @@ export const ProjectMemberList = observer(function ProjectMemberList(props: TPro handleUpdate={handleRoleFilterUpdate} memberType="project" /> + {isAdmin && } {isAdmin && (
diff --git a/apps/web/core/components/project/create/header.tsx b/apps/web/core/components/project/create/header.tsx index 37f635cf9a..abbaf259bc 100644 --- a/apps/web/core/components/project/create/header.tsx +++ b/apps/web/core/components/project/create/header.tsx @@ -18,13 +18,21 @@ import { ProjectTemplateSelect } from "@/plane-web/components/projects/create/te type Props = { handleClose: () => void; isMobile?: boolean; - handleFormChange?: () => void; + handleFormOnChange?: () => void; isClosable?: boolean; handleTemplateSelect?: () => void; + showActionButtons?: boolean; }; function ProjectCreateHeader(props: Props) { - const { handleClose, isMobile = false, handleFormChange, isClosable = true, handleTemplateSelect } = props; + const { + handleClose, + isMobile = false, + handleFormOnChange, + isClosable = true, + handleTemplateSelect, + showActionButtons = true, + } = props; const { watch, control, setValue } = useFormContext(); const { t } = useTranslation(); // derived values @@ -40,9 +48,11 @@ function ProjectCreateHeader(props: Props) { alt={t("project_cover_image_alt")} className="absolute left-0 top-0 h-full w-full rounded-lg" /> -
- -
+ {showActionButtons && ( +
+ +
+ )} {isClosable && (
diff --git a/apps/web/app/(all)/[workspaceSlug]/(projects)/star-us-link.tsx b/apps/web/app/(all)/[workspaceSlug]/(projects)/star-us-link.tsx index 7501a2e1e8..8b1cc9769e 100644 --- a/apps/web/app/(all)/[workspaceSlug]/(projects)/star-us-link.tsx +++ b/apps/web/app/(all)/[workspaceSlug]/(projects)/star-us-link.tsx @@ -1,12 +1,9 @@ import { useTheme } from "next-themes"; // plane imports -import { HEADER_GITHUB_ICON, GITHUB_REDIRECTED_TRACKER_EVENT } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; // assets import githubBlackImage from "@/app/assets/logos/github-black.png?url"; import githubWhiteImage from "@/app/assets/logos/github-white.png?url"; -// helpers -import { captureElementAndEvent } from "@/helpers/event-tracker.helper"; export function StarUsOnGitHubLink() { // plane hooks @@ -18,17 +15,6 @@ export function StarUsOnGitHubLink() { return ( - captureElementAndEvent({ - element: { - elementName: HEADER_GITHUB_ICON, - }, - event: { - eventName: GITHUB_REDIRECTED_TRACKER_EVENT, - state: "SUCCESS", - }, - }) - } className="flex flex-shrink-0 items-center gap-1.5 rounded-sm bg-layer-2 px-3 py-1.5" href="https://github.com/makeplane/plane" target="_blank" diff --git a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/members/page.tsx b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/members/page.tsx index 1de0255b68..f74d9ca271 100644 --- a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/members/page.tsx +++ b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/members/page.tsx @@ -20,8 +20,6 @@ import { PageHead } from "@/components/core/page-title"; import { MemberListFiltersDropdown } from "@/components/project/dropdowns/filters/member-list"; import { SettingsContentWrapper } from "@/components/settings/content-wrapper"; import { WorkspaceMembersList } from "@/components/workspace/settings/members-list"; -// helpers -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; // hooks import { useMember } from "@/hooks/store/use-member"; import { useWorkspace } from "@/hooks/store/use-workspace"; @@ -58,13 +56,6 @@ const WorkspaceMembersSettingsPage = observer(function WorkspaceMembersSettingsP setInviteModal(false); - captureSuccess({ - eventName: MEMBER_TRACKER_EVENTS.invite, - payload: { - emails: data.emails.map((email) => email.email), - }, - }); - setToast({ type: TOAST_TYPE.SUCCESS, title: "Success!", @@ -76,14 +67,6 @@ const WorkspaceMembersSettingsPage = observer(function WorkspaceMembersSettingsP const err = error as Error & { error?: string }; message = err.error; } - captureError({ - eventName: MEMBER_TRACKER_EVENTS.invite, - payload: { - emails: data.emails.map((email) => email.email), - }, - error: error as Error, - }); - setToast({ type: TOAST_TYPE.ERROR, title: "Error!", diff --git a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/webhooks/[webhookId]/page.tsx b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/webhooks/[webhookId]/page.tsx index c9135696d5..441ae6662f 100644 --- a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/webhooks/[webhookId]/page.tsx +++ b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/webhooks/[webhookId]/page.tsx @@ -1,7 +1,7 @@ import { useState } from "react"; import { observer } from "mobx-react"; import useSWR from "swr"; -import { EUserPermissions, EUserPermissionsLevel, WORKSPACE_SETTINGS_TRACKER_EVENTS } from "@plane/constants"; +import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { IWebhook } from "@plane/types"; // ui @@ -11,7 +11,6 @@ import { PageHead } from "@/components/core/page-title"; import { SettingsContentWrapper } from "@/components/settings/content-wrapper"; import { DeleteWebhookModal, WebhookDeleteSection, WebhookForm } from "@/components/web-hooks"; // hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useWebhook } from "@/hooks/store/use-webhook"; import { useWorkspace } from "@/hooks/store/use-workspace"; import { useUserPermissions } from "@/hooks/store/user"; @@ -55,12 +54,6 @@ function WebhookDetailsPage({ params }: Route.ComponentProps) { try { await updateWebhook(workspaceSlug, formData.id, payload); - - captureSuccess({ - eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.webhook_updated, - payload: { webhook: formData.id }, - }); - setToast({ type: TOAST_TYPE.SUCCESS, title: "Success!", @@ -68,12 +61,6 @@ function WebhookDetailsPage({ params }: Route.ComponentProps) { }); // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { - captureError({ - eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.webhook_updated, - payload: { webhook: formData.id }, - error: error as Error, - }); - setToast({ type: TOAST_TYPE.ERROR, title: "Error!", diff --git a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/webhooks/page.tsx b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/webhooks/page.tsx index 93ae93967e..41ef5af4f6 100644 --- a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/webhooks/page.tsx +++ b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/webhooks/page.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from "react"; import { observer } from "mobx-react"; import useSWR from "swr"; // plane imports -import { EUserPermissions, EUserPermissionsLevel, WORKSPACE_SETTINGS_TRACKER_ELEMENTS } from "@plane/constants"; +import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; // components import { EmptyStateCompact } from "@plane/propel/empty-state"; @@ -13,7 +13,6 @@ import { SettingsHeading } from "@/components/settings/heading"; import { WebhookSettingsLoader } from "@/components/ui/loader/settings/web-hook"; import { WebhooksList, CreateWebhookModal } from "@/components/web-hooks"; // hooks -import { captureClick } from "@/helpers/event-tracker.helper"; import { useWebhook } from "@/hooks/store/use-webhook"; import { useWorkspace } from "@/hooks/store/use-workspace"; import { useUserPermissions } from "@/hooks/store/user"; @@ -72,9 +71,6 @@ function WebhooksListPage({ params }: Route.ComponentProps) { button={{ label: t("workspace_settings.settings.webhooks.add_webhook"), onClick: () => { - captureClick({ - elementName: WORKSPACE_SETTINGS_TRACKER_ELEMENTS.HEADER_ADD_WEBHOOK_BUTTON, - }); setShowCreateWebhookModal(true); }, }} @@ -94,9 +90,6 @@ function WebhooksListPage({ params }: Route.ComponentProps) { { label: t("settings_empty_state.webhooks.cta_primary"), onClick: () => { - captureClick({ - elementName: WORKSPACE_SETTINGS_TRACKER_ELEMENTS.EMPTY_STATE_ADD_WEBHOOK_BUTTON, - }); setShowCreateWebhookModal(true); }, }, diff --git a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/account/api-tokens/page.tsx b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/account/api-tokens/page.tsx index 6553d52a1c..c071ef4c35 100644 --- a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/account/api-tokens/page.tsx +++ b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/account/api-tokens/page.tsx @@ -1,8 +1,7 @@ -import React, { useState } from "react"; +import { useState } from "react"; import { observer } from "mobx-react"; import useSWR from "swr"; // plane imports -import { PROFILE_SETTINGS_TRACKER_ELEMENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; // component import { EmptyStateCompact } from "@plane/propel/empty-state"; @@ -14,7 +13,6 @@ import { SettingsHeading } from "@/components/settings/heading"; import { APITokenSettingsLoader } from "@/components/ui/loader/settings/api-token"; import { API_TOKENS_LIST } from "@/constants/fetch-keys"; // store hooks -import { captureClick } from "@/helpers/event-tracker.helper"; import { useWorkspace } from "@/hooks/store/use-workspace"; const apiTokenService = new APITokenService(); @@ -51,9 +49,6 @@ function ApiTokensPage() { button={{ label: t("workspace_settings.settings.api_tokens.add_token"), onClick: () => { - captureClick({ - elementName: PROFILE_SETTINGS_TRACKER_ELEMENTS.HEADER_ADD_PAT_BUTTON, - }); setIsCreateTokenModalOpen(true); }, }} @@ -72,9 +67,6 @@ function ApiTokensPage() { button={{ label: t("workspace_settings.settings.api_tokens.add_token"), onClick: () => { - captureClick({ - elementName: PROFILE_SETTINGS_TRACKER_ELEMENTS.HEADER_ADD_PAT_BUTTON, - }); setIsCreateTokenModalOpen(true); }, }} @@ -89,9 +81,6 @@ function ApiTokensPage() { { label: t("settings_empty_state.tokens.cta_primary"), onClick: () => { - captureClick({ - elementName: PROFILE_SETTINGS_TRACKER_ELEMENTS.EMPTY_STATE_ADD_PAT_BUTTON, - }); setIsCreateTokenModalOpen(true); }, }, diff --git a/apps/web/app/(all)/invitations/page.tsx b/apps/web/app/(all)/invitations/page.tsx index f16a8a24e6..ca926bc502 100644 --- a/apps/web/app/(all)/invitations/page.tsx +++ b/apps/web/app/(all)/invitations/page.tsx @@ -1,11 +1,11 @@ -import React, { useState } from "react"; +import { useState } from "react"; import { observer } from "mobx-react"; import Link from "next/link"; import useSWR, { mutate } from "swr"; import { CheckCircle2 } from "lucide-react"; // plane imports -import { ROLE, MEMBER_TRACKER_EVENTS, MEMBER_TRACKER_ELEMENTS, GROUP_WORKSPACE_TRACKER_EVENT } from "@plane/constants"; +import { ROLE } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; // types import { Button } from "@plane/propel/button"; @@ -19,9 +19,7 @@ import emptyInvitation from "@/app/assets/empty-state/invitation.svg?url"; import { EmptyState } from "@/components/common/empty-state"; import { WorkspaceLogo } from "@/components/workspace/logo"; import { USER_WORKSPACES_LIST } from "@/constants/fetch-keys"; -// helpers // hooks -import { captureError, captureSuccess, joinEventGroup } from "@/helpers/event-tracker.helper"; import { useWorkspace } from "@/hooks/store/use-workspace"; import { useUser, useUserProfile } from "@/hooks/store/user"; import { useAppRouter } from "@/hooks/use-app-router"; @@ -79,18 +77,6 @@ function UserInvitationsPage() { const firstInviteId = invitationsRespond[0]; const invitation = invitations?.find((i) => i.id === firstInviteId); const redirectWorkspace = invitations?.find((i) => i.id === firstInviteId)?.workspace; - if (redirectWorkspace?.id) { - joinEventGroup(GROUP_WORKSPACE_TRACKER_EVENT, redirectWorkspace?.id, { - date: new Date().toDateString(), - workspace_id: redirectWorkspace?.id, - }); - } - captureSuccess({ - eventName: MEMBER_TRACKER_EVENTS.accept, - payload: { - member_id: invitation?.id, - }, - }); updateUserProfile({ last_workspace_id: redirectWorkspace?.id }) .then(() => { setIsJoiningWorkspaces(false); @@ -107,14 +93,7 @@ function UserInvitationsPage() { setIsJoiningWorkspaces(false); }); }) - .catch((err) => { - captureError({ - eventName: MEMBER_TRACKER_EVENTS.accept, - payload: { - member_id: invitationsRespond?.[0], - }, - error: err, - }); + .catch((_err) => { setToast({ type: TOAST_TYPE.ERROR, title: t("error"), @@ -183,7 +162,6 @@ function UserInvitationsPage() { onClick={submitInvitations} disabled={isJoiningWorkspaces || invitationsRespond.length === 0} loading={isJoiningWorkspaces} - data-ph-element={MEMBER_TRACKER_ELEMENTS.ACCEPT_INVITATION_BUTTON} > {t("accept_and_join")} diff --git a/apps/web/app/provider.tsx b/apps/web/app/provider.tsx index 4d23fed9d3..ef696647b2 100644 --- a/apps/web/app/provider.tsx +++ b/apps/web/app/provider.tsx @@ -29,10 +29,6 @@ const ChatSupportModal = lazy(function ChatSupportModal() { return import("@/components/global/chat-support-modal"); }); -const PostHogProvider = lazy(function PostHogProvider() { - return import("@/lib/posthog-provider"); -}); - export interface IAppProvider { children: React.ReactNode; } @@ -52,9 +48,7 @@ export function AppProvider(props: IAppProvider) { - - {children} - + {children} diff --git a/apps/web/ce/components/onboarding/tour/root.tsx b/apps/web/ce/components/onboarding/tour/root.tsx index f5498b0468..8e9a87004e 100644 --- a/apps/web/ce/components/onboarding/tour/root.tsx +++ b/apps/web/ce/components/onboarding/tour/root.tsx @@ -10,8 +10,6 @@ import IssuesTour from "@/app/assets/onboarding/issues.webp?url"; import ModulesTour from "@/app/assets/onboarding/modules.webp?url"; import PagesTour from "@/app/assets/onboarding/pages.webp?url"; import ViewsTour from "@/app/assets/onboarding/views.webp?url"; -// helpers -import { captureClick } from "@/helpers/event-tracker.helper"; // hooks import { useCommandPalette } from "@/hooks/store/use-command-palette"; import { useUser } from "@/hooks/store/user"; @@ -107,9 +105,6 @@ export const TourRoot = observer(function TourRoot(props: TOnboardingTourProps)
diff --git a/apps/web/ce/helpers/command-palette.ts b/apps/web/ce/helpers/command-palette.ts index d29660a168..697d12c283 100644 --- a/apps/web/ce/helpers/command-palette.ts +++ b/apps/web/ce/helpers/command-palette.ts @@ -1,15 +1,5 @@ -// types -import { - CYCLE_TRACKER_ELEMENTS, - MODULE_TRACKER_ELEMENTS, - PROJECT_PAGE_TRACKER_ELEMENTS, - PROJECT_TRACKER_ELEMENTS, - PROJECT_VIEW_TRACKER_ELEMENTS, - WORK_ITEM_TRACKER_ELEMENTS, -} from "@plane/constants"; import type { TCommandPaletteActionList, TCommandPaletteShortcut, TCommandPaletteShortcutList } from "@plane/types"; // store -import { captureClick } from "@/helpers/event-tracker.helper"; import { store } from "@/lib/store-context"; export const getGlobalShortcutsList: () => TCommandPaletteActionList = () => { @@ -21,7 +11,6 @@ export const getGlobalShortcutsList: () => TCommandPaletteActionList = () => { description: "Create a new work item in the current project", action: () => { toggleCreateIssueModal(true); - captureClick({ elementName: WORK_ITEM_TRACKER_ELEMENTS.COMMAND_PALETTE_ADD_BUTTON }); }, }, }; @@ -36,7 +25,6 @@ export const getWorkspaceShortcutsList: () => TCommandPaletteActionList = () => description: "Create a new project in the current workspace", action: () => { toggleCreateProjectModal(true); - captureClick({ elementName: PROJECT_TRACKER_ELEMENTS.COMMAND_PALETTE_SHORTCUT_CREATE_BUTTON }); }, }, }; @@ -57,7 +45,6 @@ export const getProjectShortcutsList: () => TCommandPaletteActionList = () => { description: "Create a new page in the current project", action: () => { toggleCreatePageModal({ isOpen: true }); - captureClick({ elementName: PROJECT_PAGE_TRACKER_ELEMENTS.COMMAND_PALETTE_SHORTCUT_CREATE_BUTTON }); }, }, m: { @@ -65,7 +52,6 @@ export const getProjectShortcutsList: () => TCommandPaletteActionList = () => { description: "Create a new module in the current project", action: () => { toggleCreateModuleModal(true); - captureClick({ elementName: MODULE_TRACKER_ELEMENTS.COMMAND_PALETTE_ADD_ITEM }); }, }, q: { @@ -73,7 +59,6 @@ export const getProjectShortcutsList: () => TCommandPaletteActionList = () => { description: "Create a new cycle in the current project", action: () => { toggleCreateCycleModal(true); - captureClick({ elementName: CYCLE_TRACKER_ELEMENTS.COMMAND_PALETTE_ADD_ITEM }); }, }, v: { @@ -81,7 +66,6 @@ export const getProjectShortcutsList: () => TCommandPaletteActionList = () => { description: "Create a new view in the current project", action: () => { toggleCreateViewModal(true); - captureClick({ elementName: PROJECT_VIEW_TRACKER_ELEMENTS.COMMAND_PALETTE_ADD_ITEM }); }, }, backspace: { diff --git a/apps/web/core/components/account/auth-forms/forgot-password.tsx b/apps/web/core/components/account/auth-forms/forgot-password.tsx index 0c210530e3..10d2d82318 100644 --- a/apps/web/core/components/account/auth-forms/forgot-password.tsx +++ b/apps/web/core/components/account/auth-forms/forgot-password.tsx @@ -5,14 +5,11 @@ import { Controller, useForm } from "react-hook-form"; // icons import { CircleCheck } from "lucide-react"; // plane imports -import { AUTH_TRACKER_EVENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { Button, getButtonStyling } from "@plane/propel/button"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import { Input } from "@plane/ui"; import { cn, checkEmailValidity } from "@plane/utils"; -// helpers -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; // hooks import useTimer from "@/hooks/use-timer"; // services @@ -59,12 +56,6 @@ export const ForgotPasswordForm = observer(function ForgotPasswordForm() { email: formData.email, }) .then(() => { - captureSuccess({ - eventName: AUTH_TRACKER_EVENTS.forgot_password, - payload: { - email: formData.email, - }, - }); setToast({ type: TOAST_TYPE.SUCCESS, title: t("auth.forgot_password.toast.success.title"), @@ -73,12 +64,6 @@ export const ForgotPasswordForm = observer(function ForgotPasswordForm() { setResendCodeTimer(30); }) .catch((err) => { - captureError({ - eventName: AUTH_TRACKER_EVENTS.forgot_password, - payload: { - email: formData.email, - }, - }); setToast({ type: TOAST_TYPE.ERROR, title: t("auth.forgot_password.toast.error.title"), diff --git a/apps/web/core/components/account/auth-forms/password.tsx b/apps/web/core/components/account/auth-forms/password.tsx index b7b1cad893..e773246153 100644 --- a/apps/web/core/components/account/auth-forms/password.tsx +++ b/apps/web/core/components/account/auth-forms/password.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo, useRef, useState } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; import { observer } from "mobx-react"; import Link from "next/link"; // icons @@ -15,8 +15,6 @@ import { ForgotPasswordPopover } from "@/components/account/auth-forms/forgot-pa // constants // helpers import { EAuthModes, EAuthSteps } from "@/helpers/authentication.helper"; -// hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; // services import { AuthService } from "@/services/auth.service"; @@ -154,15 +152,6 @@ export const AuthPasswordForm = observer(function AuthPasswordForm(props: Props) : true; if (isPasswordValid) { setIsSubmitting(true); - captureSuccess({ - eventName: - mode === EAuthModes.SIGN_IN - ? AUTH_TRACKER_EVENTS.sign_in_with_password - : AUTH_TRACKER_EVENTS.sign_up_with_password, - payload: { - email: passwordFormData.email, - }, - }); if (formRef.current) formRef.current.submit(); // Manually submit the form if the condition is met } else { setBannerMessage(true); @@ -170,15 +159,6 @@ export const AuthPasswordForm = observer(function AuthPasswordForm(props: Props) }} onError={() => { setIsSubmitting(false); - captureError({ - eventName: - mode === EAuthModes.SIGN_IN - ? AUTH_TRACKER_EVENTS.sign_in_with_password - : AUTH_TRACKER_EVENTS.sign_up_with_password, - payload: { - email: passwordFormData.email, - }, - }); }} > diff --git a/apps/web/core/components/account/auth-forms/set-password.tsx b/apps/web/core/components/account/auth-forms/set-password.tsx index d3cfc167ce..0fa36dd876 100644 --- a/apps/web/core/components/account/auth-forms/set-password.tsx +++ b/apps/web/core/components/account/auth-forms/set-password.tsx @@ -5,15 +5,13 @@ import { useSearchParams } from "next/navigation"; // icons import { Eye, EyeOff } from "lucide-react"; // plane imports -import { AUTH_TRACKER_ELEMENTS, AUTH_TRACKER_EVENTS, E_PASSWORD_STRENGTH } from "@plane/constants"; +import { E_PASSWORD_STRENGTH } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { Button } from "@plane/propel/button"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import { Input, PasswordStrengthIndicator } from "@plane/ui"; // components import { getPasswordStrength } from "@plane/utils"; -// helpers -import { captureError, captureSuccess, captureView } from "@/helpers/event-tracker.helper"; // hooks import { useUser } from "@/hooks/store/user"; import { useAppRouter } from "@/hooks/use-app-router"; @@ -60,12 +58,6 @@ export const SetPasswordForm = observer(function SetPasswordForm() { // hooks const { data: user, handleSetPassword } = useUser(); - useEffect(() => { - captureView({ - elementName: AUTH_TRACKER_ELEMENTS.SET_PASSWORD_FORM, - }); - }, []); - useEffect(() => { if (csrfToken === undefined) authService.requestCSRFToken().then((data) => data?.csrf_token && setCsrfToken(data.csrf_token)); @@ -92,9 +84,6 @@ export const SetPasswordForm = observer(function SetPasswordForm() { e.preventDefault(); if (!csrfToken) throw new Error("csrf token not found"); await handleSetPassword(csrfToken, { password: passwordFormData.password }); - captureSuccess({ - eventName: AUTH_TRACKER_EVENTS.password_created, - }); router.push("/"); } catch (error: unknown) { let message = undefined; @@ -102,9 +91,6 @@ export const SetPasswordForm = observer(function SetPasswordForm() { const err = error as Error & { error?: string }; message = err.error; } - captureError({ - eventName: AUTH_TRACKER_EVENTS.password_created, - }); setToast({ type: TOAST_TYPE.ERROR, title: t("common.errors.default.title"), diff --git a/apps/web/core/components/account/auth-forms/unique-code.tsx b/apps/web/core/components/account/auth-forms/unique-code.tsx index dabe028fa9..e09fc392a0 100644 --- a/apps/web/core/components/account/auth-forms/unique-code.tsx +++ b/apps/web/core/components/account/auth-forms/unique-code.tsx @@ -1,6 +1,6 @@ -import React, { useEffect, useState } from "react"; +import { useEffect, useState } from "react"; import { CircleCheck, XCircle } from "lucide-react"; -import { API_BASE_URL, AUTH_TRACKER_ELEMENTS, AUTH_TRACKER_EVENTS } from "@plane/constants"; +import { API_BASE_URL } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { Button } from "@plane/propel/button"; import { Input, Spinner } from "@plane/ui"; @@ -8,7 +8,6 @@ import { Input, Spinner } from "@plane/ui"; // helpers import { EAuthModes } from "@/helpers/authentication.helper"; // hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import useTimer from "@/hooks/use-timer"; // services import { AuthService } from "@/services/auth.service"; @@ -59,22 +58,10 @@ export function AuthUniqueCodeForm(props: TAuthUniqueCodeForm) { setResendCodeTimer(defaultResetTimerValue); handleFormChange("code", uniqueCode?.code || ""); setIsRequestingNewCode(false); - captureSuccess({ - eventName: AUTH_TRACKER_EVENTS.new_code_requested, - payload: { - email: email, - }, - }); } catch { setResendCodeTimer(0); console.error("Error while requesting new code"); setIsRequestingNewCode(false); - captureError({ - eventName: AUTH_TRACKER_EVENTS.new_code_requested, - payload: { - email: email, - }, - }); } }; @@ -93,22 +80,9 @@ export function AuthUniqueCodeForm(props: TAuthUniqueCodeForm) { action={`${API_BASE_URL}/auth/${mode === EAuthModes.SIGN_IN ? "magic-sign-in" : "magic-sign-up"}/`} onSubmit={() => { setIsSubmitting(true); - captureSuccess({ - eventName: AUTH_TRACKER_EVENTS.code_verify, - payload: { - state: "SUCCESS", - first_time: !isExistingEmail, - }, - }); }} onError={() => { setIsSubmitting(false); - captureError({ - eventName: AUTH_TRACKER_EVENTS.code_verify, - payload: { - state: "FAILED", - }, - }); }} > @@ -163,7 +137,6 @@ export function AuthUniqueCodeForm(props: TAuthUniqueCodeForm) {

-
- { - if (currentProjectDetails?.archive_in === 0) { - await handleChange({ archive_in: 1 }); - } else { - await 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} - /> + {currentProjectDetails ? ( diff --git a/apps/web/core/components/automation/auto-close-automation.tsx b/apps/web/core/components/automation/auto-close-automation.tsx index c808e064db..6b9e7a8d42 100644 --- a/apps/web/core/components/automation/auto-close-automation.tsx +++ b/apps/web/core/components/automation/auto-close-automation.tsx @@ -1,17 +1,10 @@ -import React, { useMemo, useState } from "react"; +import { useMemo, useState } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // icons import { ArchiveX } from "lucide-react"; // types -import { - PROJECT_AUTOMATION_MONTHS, - EUserPermissions, - EUserPermissionsLevel, - EIconSize, - PROJECT_SETTINGS_TRACKER_ELEMENTS, - PROJECT_SETTINGS_TRACKER_EVENTS, -} from "@plane/constants"; +import { PROJECT_AUTOMATION_MONTHS, EUserPermissions, EUserPermissionsLevel, EIconSize } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { StateGroupIcon, StatePropertyIcon } from "@plane/propel/icons"; import type { IProject } from "@plane/types"; @@ -21,7 +14,6 @@ import { CustomSelect, CustomSearchSelect, ToggleSwitch, Loader } from "@plane/u import { SelectMonthModal } from "@/components/automation"; // constants // hooks -import { captureElementAndEvent } from "@/helpers/event-tracker.helper"; import { useProject } from "@/hooks/store/use-project"; import { useProjectState } from "@/hooks/store/use-project-state"; import { useUserPermissions } from "@/hooks/store/user"; @@ -111,15 +103,6 @@ export const AutoCloseAutomation = observer(function AutoCloseAutomation(props: } else { await 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} diff --git a/apps/web/core/components/cycles/analytics-sidebar/sidebar-header.tsx b/apps/web/core/components/cycles/analytics-sidebar/sidebar-header.tsx index f89f7b9750..f30f26ea06 100644 --- a/apps/web/core/components/cycles/analytics-sidebar/sidebar-header.tsx +++ b/apps/web/core/components/cycles/analytics-sidebar/sidebar-header.tsx @@ -1,16 +1,9 @@ -import type { FC } from "react"; -import React, { useEffect } from "react"; +import { useEffect } from "react"; import { observer } from "mobx-react"; import { Controller, useForm } from "react-hook-form"; import { ArrowRight } from "lucide-react"; // Plane Imports -import { - CYCLE_TRACKER_EVENTS, - CYCLE_STATUS, - EUserPermissions, - EUserPermissionsLevel, - CYCLE_TRACKER_ELEMENTS, -} from "@plane/constants"; +import { CYCLE_STATUS, EUserPermissions, EUserPermissionsLevel } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { ChevronRightIcon } from "@plane/propel/icons"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; @@ -19,7 +12,6 @@ import { getDate, renderFormattedPayloadDate } from "@plane/utils"; // components import { DateRangeDropdown } from "@/components/dropdowns/date-range"; // hooks -import { captureElementAndEvent } from "@/helpers/event-tracker.helper"; import { useCycle } from "@/hooks/store/use-cycle"; import { useUserPermissions } from "@/hooks/store/user"; import { useTimeZoneConverter } from "@/hooks/use-timezone-converter"; @@ -64,37 +56,7 @@ export const CycleSidebarHeader = observer(function CycleSidebarHeader(props: Pr const submitChanges = async (data: Partial) => { if (!workspaceSlug || !projectId || !cycleDetails.id) return; - - await updateCycleDetails(workspaceSlug.toString(), projectId.toString(), cycleDetails.id.toString(), data) - .then(() => { - captureElementAndEvent({ - element: { - elementName: CYCLE_TRACKER_ELEMENTS.RIGHT_SIDEBAR, - }, - event: { - eventName: CYCLE_TRACKER_EVENTS.update, - state: "SUCCESS", - payload: { - id: cycleDetails.id, - }, - }, - }); - }) - - .catch(() => { - captureElementAndEvent({ - element: { - elementName: CYCLE_TRACKER_ELEMENTS.RIGHT_SIDEBAR, - }, - event: { - eventName: CYCLE_TRACKER_EVENTS.update, - state: "ERROR", - payload: { - id: cycleDetails.id, - }, - }, - }); - }); + await updateCycleDetails(workspaceSlug.toString(), projectId.toString(), cycleDetails.id.toString(), data); }; useEffect(() => { diff --git a/apps/web/core/components/cycles/archived-cycles/modal.tsx b/apps/web/core/components/cycles/archived-cycles/modal.tsx index 5d7b35560a..a686e580af 100644 --- a/apps/web/core/components/cycles/archived-cycles/modal.tsx +++ b/apps/web/core/components/cycles/archived-cycles/modal.tsx @@ -1,11 +1,9 @@ import { useState } from "react"; // ui -import { CYCLE_TRACKER_EVENTS } from "@plane/constants"; import { Button } from "@plane/propel/button"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui"; // hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useCycle } from "@/hooks/store/use-cycle"; import { useAppRouter } from "@/hooks/use-app-router"; @@ -43,12 +41,6 @@ export function ArchiveCycleModal(props: Props) { title: "Archive success", message: "Your archives can be found in project archives.", }); - captureSuccess({ - eventName: CYCLE_TRACKER_EVENTS.archive, - payload: { - id: cycleId, - }, - }); onClose(); router.push(`/${workspaceSlug}/projects/${projectId}/cycles`); return; @@ -59,12 +51,6 @@ export function ArchiveCycleModal(props: Props) { title: "Error!", message: "Cycle could not be archived. Please try again.", }); - captureError({ - eventName: CYCLE_TRACKER_EVENTS.archive, - payload: { - id: cycleId, - }, - }); }) .finally(() => setIsArchiving(false)); }; diff --git a/apps/web/core/components/cycles/delete-modal.tsx b/apps/web/core/components/cycles/delete-modal.tsx index ea485f9810..d491ffe90b 100644 --- a/apps/web/core/components/cycles/delete-modal.tsx +++ b/apps/web/core/components/cycles/delete-modal.tsx @@ -2,14 +2,12 @@ import { useState } from "react"; import { observer } from "mobx-react"; import { useParams, useSearchParams } from "next/navigation"; // types -import { PROJECT_ERROR_MESSAGES, CYCLE_TRACKER_EVENTS } from "@plane/constants"; +import { PROJECT_ERROR_MESSAGES } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { ICycle } from "@plane/types"; // ui import { AlertModalCore } from "@plane/ui"; -// helpers -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; // hooks import { useCycle } from "@/hooks/store/use-cycle"; import { useAppRouter } from "@/hooks/use-app-router"; @@ -48,12 +46,6 @@ export const CycleDeleteModal = observer(function CycleDeleteModal(props: ICycle title: "Success!", message: "Cycle deleted successfully.", }); - captureSuccess({ - eventName: CYCLE_TRACKER_EVENTS.delete, - payload: { - id: cycle.id, - }, - }); }) .catch((errors) => { const isPermissionError = errors?.error === "You don't have the required permissions."; @@ -65,13 +57,6 @@ export const CycleDeleteModal = observer(function CycleDeleteModal(props: ICycle type: TOAST_TYPE.ERROR, message: currentError.i18n_message && t(currentError.i18n_message), }); - captureError({ - eventName: CYCLE_TRACKER_EVENTS.delete, - payload: { - id: cycle.id, - }, - error: errors, - }); }) .finally(() => handleClose()); } catch { diff --git a/apps/web/core/components/cycles/list/cycle-list-item-action.tsx b/apps/web/core/components/cycles/list/cycle-list-item-action.tsx index c0021d362f..e918dd53f6 100644 --- a/apps/web/core/components/cycles/list/cycle-list-item-action.tsx +++ b/apps/web/core/components/cycles/list/cycle-list-item-action.tsx @@ -1,17 +1,11 @@ -import type { FC, MouseEvent } from "react"; +import type { MouseEvent } from "react"; import React, { useEffect, useMemo, useState } from "react"; import { observer } from "mobx-react"; import { useParams, usePathname, useSearchParams } from "next/navigation"; import { useForm } from "react-hook-form"; import { Eye, ArrowRight, CalendarDays } from "lucide-react"; // plane imports -import { - CYCLE_TRACKER_EVENTS, - EUserPermissions, - EUserPermissionsLevel, - IS_FAVORITE_MENU_OPEN, - CYCLE_TRACKER_ELEMENTS, -} from "@plane/constants"; +import { EUserPermissions, EUserPermissionsLevel, IS_FAVORITE_MENU_OPEN } from "@plane/constants"; import { useLocalStorage } from "@plane/hooks"; import { useTranslation } from "@plane/i18n"; import { TransferIcon, WorkItemsIcon, MembersPropertyIcon } from "@plane/propel/icons"; @@ -25,7 +19,6 @@ import { DateRangeDropdown } from "@/components/dropdowns/date-range"; import { ButtonAvatars } from "@/components/dropdowns/member/avatar"; import { MergedDateDisplay } from "@/components/dropdowns/merged-date"; // hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useCycle } from "@/hooks/store/use-cycle"; import { useMember } from "@/hooks/store/use-member"; import { useUserPermissions } from "@/hooks/store/user"; @@ -109,25 +102,11 @@ export const CycleListItemAction = observer(function CycleListItemAction(props: e.preventDefault(); if (!workspaceSlug || !projectId) return; - const addToFavoritePromise = addCycleToFavorites(workspaceSlug?.toString(), projectId.toString(), cycleId) - .then(() => { + const addToFavoritePromise = addCycleToFavorites(workspaceSlug?.toString(), projectId.toString(), cycleId).then( + () => { if (!isFavoriteMenuOpen) toggleFavoriteMenu(true); - captureSuccess({ - eventName: CYCLE_TRACKER_EVENTS.favorite, - payload: { - id: cycleId, - }, - }); - }) - .catch((error) => { - captureError({ - eventName: CYCLE_TRACKER_EVENTS.favorite, - payload: { - id: cycleId, - }, - error, - }); - }); + } + ); setPromiseToast(addToFavoritePromise, { loading: t("project_cycles.action.favorite.loading"), @@ -146,24 +125,11 @@ export const CycleListItemAction = observer(function CycleListItemAction(props: e.preventDefault(); if (!workspaceSlug || !projectId) return; - const removeFromFavoritePromise = removeCycleFromFavorites(workspaceSlug?.toString(), projectId.toString(), cycleId) - .then(() => { - captureSuccess({ - eventName: CYCLE_TRACKER_EVENTS.unfavorite, - payload: { - id: cycleId, - }, - }); - }) - .catch((error) => { - captureError({ - eventName: CYCLE_TRACKER_EVENTS.unfavorite, - payload: { - id: cycleId, - }, - error, - }); - }); + const removeFromFavoritePromise = removeCycleFromFavorites( + workspaceSlug?.toString(), + projectId.toString(), + cycleId + ); setPromiseToast(removeFromFavoritePromise, { loading: t("project_cycles.action.unfavorite.loading"), @@ -319,7 +285,6 @@ export const CycleListItemAction = observer(function CycleListItemAction(props: )} {isEditingAllowed && !cycleDetails.archived_at && ( { e.preventDefault(); e.stopPropagation(); diff --git a/apps/web/core/components/cycles/modal.tsx b/apps/web/core/components/cycles/modal.tsx index 3aeb9e5925..bc068ddd70 100644 --- a/apps/web/core/components/cycles/modal.tsx +++ b/apps/web/core/components/cycles/modal.tsx @@ -1,14 +1,12 @@ -import React, { useEffect, useState } from "react"; +import { useEffect, useState } from "react"; import { mutate } from "swr"; // types -import { CYCLE_TRACKER_EVENTS } from "@plane/constants"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { CycleDateCheckData, ICycle, TCycleTabOptions } from "@plane/types"; // ui import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui"; // hooks import { renderFormattedPayloadDate } from "@plane/utils"; -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useCycle } from "@/hooks/store/use-cycle"; import { useProject } from "@/hooks/store/use-project"; import useKeypress from "@/hooks/use-keypress"; @@ -62,12 +60,6 @@ export function CycleCreateUpdateModal(props: CycleModalProps) { title: "Success!", message: "Cycle created successfully.", }); - captureSuccess({ - eventName: CYCLE_TRACKER_EVENTS.create, - payload: { - id: res.id, - }, - }); }) .catch((err) => { setToast({ @@ -75,10 +67,6 @@ export function CycleCreateUpdateModal(props: CycleModalProps) { title: "Error!", message: err?.detail ?? "Error in creating cycle. Please try again.", }); - captureError({ - eventName: CYCLE_TRACKER_EVENTS.create, - error: err, - }); }); }; @@ -88,12 +76,6 @@ export function CycleCreateUpdateModal(props: CycleModalProps) { const selectedProjectId = payload.project_id ?? projectId.toString(); await updateCycleDetails(workspaceSlug, selectedProjectId, cycleId, payload) .then((res) => { - captureSuccess({ - eventName: CYCLE_TRACKER_EVENTS.update, - payload: { - id: res.id, - }, - }); setToast({ type: TOAST_TYPE.SUCCESS, title: "Success!", @@ -106,10 +88,6 @@ export function CycleCreateUpdateModal(props: CycleModalProps) { title: "Error!", message: err?.detail ?? "Error in updating cycle. Please try again.", }); - captureError({ - eventName: CYCLE_TRACKER_EVENTS.update, - error: err, - }); }); }; diff --git a/apps/web/core/components/cycles/quick-actions.tsx b/apps/web/core/components/cycles/quick-actions.tsx index d0e5c74c70..4254a0f315 100644 --- a/apps/web/core/components/cycles/quick-actions.tsx +++ b/apps/web/core/components/cycles/quick-actions.tsx @@ -1,24 +1,16 @@ import { useState } from "react"; import { observer } from "mobx-react"; import { MoreHorizontal } from "lucide-react"; - // ui -import { - CYCLE_TRACKER_EVENTS, - EUserPermissions, - EUserPermissionsLevel, - CYCLE_TRACKER_ELEMENTS, -} from "@plane/constants"; +import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { IconButton } from "@plane/propel/icon-button"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { TContextMenuItem } from "@plane/ui"; import { ContextMenu, CustomMenu } from "@plane/ui"; import { copyUrlToClipboard, cn } from "@plane/utils"; -// helpers // hooks import { useCycleMenuItems } from "@/components/common/quick-actions-helper"; -import { captureClick, captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useCycle } from "@/hooks/store/use-cycle"; import { useUserPermissions } from "@/hooks/store/user"; import { useAppRouter } from "@/hooks/use-app-router"; @@ -76,12 +68,6 @@ export const CycleQuickActions = observer(function CycleQuickActions(props: Prop title: t("project_cycles.action.restore.success.title"), message: t("project_cycles.action.restore.success.description"), }); - captureSuccess({ - eventName: CYCLE_TRACKER_EVENTS.restore, - payload: { - id: cycleId, - }, - }); router.push(`/${workspaceSlug}/projects/${projectId}/archives/cycles`); }) .catch(() => { @@ -90,12 +76,6 @@ export const CycleQuickActions = observer(function CycleQuickActions(props: Prop title: t("project_cycles.action.restore.failed.title"), message: t("project_cycles.action.restore.failed.description"), }); - captureError({ - eventName: CYCLE_TRACKER_EVENTS.restore, - payload: { - id: cycleId, - }, - }); }); const menuResult = useCycleMenuItems({ @@ -118,11 +98,7 @@ export const CycleQuickActions = observer(function CycleQuickActions(props: Prop const CONTEXT_MENU_ITEMS = MENU_ITEMS.map(function CONTEXT_MENU_ITEMS(item) { return { ...item, - action: () => { - captureClick({ - elementName: CYCLE_TRACKER_ELEMENTS.CONTEXT_MENU, - }); item.action(); }, }; @@ -170,9 +146,6 @@ export const CycleQuickActions = observer(function CycleQuickActions(props: Prop { - captureClick({ - elementName: CYCLE_TRACKER_ELEMENTS.QUICK_ACTIONS, - }); item.action(); }} className={cn( diff --git a/apps/web/core/components/estimates/delete/modal.tsx b/apps/web/core/components/estimates/delete/modal.tsx index e348495bf6..f583bec023 100644 --- a/apps/web/core/components/estimates/delete/modal.tsx +++ b/apps/web/core/components/estimates/delete/modal.tsx @@ -1,13 +1,10 @@ -import type { FC } from "react"; import { useState } from "react"; import { observer } from "mobx-react"; // ui -import { PROJECT_SETTINGS_TRACKER_EVENTS } from "@plane/constants"; import { Button } from "@plane/propel/button"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui"; // hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useProjectEstimates } from "@/hooks/store/estimates"; import { useEstimate } from "@/hooks/store/estimates/use-estimate"; import { useProject } from "@/hooks/store/use-project"; @@ -34,18 +31,11 @@ export const DeleteEstimateModal = observer(function DeleteEstimateModal(props: try { if (!workspaceSlug || !projectId || !estimateId) return; setButtonLoader(true); - await deleteEstimate(workspaceSlug, projectId, estimateId); if (areEstimateEnabledByProjectId(projectId)) { 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", @@ -54,12 +44,6 @@ export const DeleteEstimateModal = observer(function DeleteEstimateModal(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", diff --git a/apps/web/core/components/estimates/empty-screen.tsx b/apps/web/core/components/estimates/empty-screen.tsx index b7f4764a8e..28c69729a1 100644 --- a/apps/web/core/components/estimates/empty-screen.tsx +++ b/apps/web/core/components/estimates/empty-screen.tsx @@ -1,12 +1,8 @@ -import type { FC } from "react"; import { useTheme } from "next-themes"; -import { PROJECT_SETTINGS_TRACKER_ELEMENTS, PROJECT_SETTINGS_TRACKER_EVENTS } from "@plane/constants"; // plane imports import { useTranslation } from "@plane/i18n"; // components import { DetailedEmptyState } from "@/components/empty-state/detailed-empty-state-root"; -// helpers -import { captureElementAndEvent } from "@/helpers/event-tracker.helper"; type TEstimateEmptyScreen = { onButtonClick: () => void; @@ -30,15 +26,6 @@ export function EstimateEmptyScreen(props: TEstimateEmptyScreen) { text: t("project_settings.empty_state.estimates.primary_button"), onClick: () => { onButtonClick(); - captureElementAndEvent({ - element: { - elementName: PROJECT_SETTINGS_TRACKER_ELEMENTS.ESTIMATES_EMPTY_STATE_CREATE_BUTTON, - }, - event: { - eventName: PROJECT_SETTINGS_TRACKER_EVENTS.estimate_created, - state: "SUCCESS", - }, - }); }, }} /> diff --git a/apps/web/core/components/estimates/estimate-disable-switch.tsx b/apps/web/core/components/estimates/estimate-disable-switch.tsx index 705ecfcb4f..4378ce2abb 100644 --- a/apps/web/core/components/estimates/estimate-disable-switch.tsx +++ b/apps/web/core/components/estimates/estimate-disable-switch.tsx @@ -1,11 +1,8 @@ -import type { 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, setToast } from "@plane/propel/toast"; import { ToggleSwitch } from "@plane/ui"; // hooks -import { captureElementAndEvent } from "@/helpers/event-tracker.helper"; import { useProjectEstimates } from "@/hooks/store/estimates"; import { useProject } from "@/hooks/store/use-project"; // i18n @@ -32,15 +29,6 @@ export const EstimateDisableSwitch = observer(function EstimateDisableSwitch(pro 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 @@ -51,15 +39,6 @@ export const EstimateDisableSwitch = observer(function EstimateDisableSwitch(pro : 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"), diff --git a/apps/web/core/components/exporter/export-form.tsx b/apps/web/core/components/exporter/export-form.tsx index 74f947316a..c56e462b50 100644 --- a/apps/web/core/components/exporter/export-form.tsx +++ b/apps/web/core/components/exporter/export-form.tsx @@ -8,8 +8,6 @@ import { EUserPermissionsLevel, EXPORTERS_LIST, // ISSUE_DISPLAY_FILTERS_BY_PAGE, - WORKSPACE_SETTINGS_TRACKER_EVENTS, - WORKSPACE_SETTINGS_TRACKER_ELEMENTS, } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { Button } from "@plane/propel/button"; @@ -20,7 +18,6 @@ import type { TWorkItemFilterExpression } from "@plane/types"; import { CustomSearchSelect, CustomSelect } from "@plane/ui"; // import { WorkspaceLevelWorkItemFiltersHOC } from "@/components/work-item-filters/filters-hoc/workspace-level"; // import { WorkItemFiltersRow } from "@/components/work-item-filters/filters-row"; -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useProject } from "@/hooks/store/use-project"; import { useUser, useUserPermissions } from "@/hooks/store/user"; import { ProjectExportService } from "@/services/project/project-export.service"; @@ -105,12 +102,6 @@ export const ExportForm = observer(function ExportForm(props: Props) { await projectExportService.csvExport(workspaceSlug, payload); mutateServices(); setExportLoading(false); - captureSuccess({ - eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.csv_exported, - payload: { - provider: formData.provider.provider, - }, - }); setToast({ type: TOAST_TYPE.SUCCESS, title: t("workspace_settings.settings.exports.modal.toasts.success.title"), @@ -127,13 +118,6 @@ export const ExportForm = observer(function ExportForm(props: Props) { }); } catch (error) { setExportLoading(false); - captureError({ - eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.csv_exported, - payload: { - provider: formData.provider.provider, - }, - error: error as Error, - }); setToast({ type: TOAST_TYPE.ERROR, title: t("error"), @@ -258,12 +242,7 @@ export const ExportForm = observer(function ExportForm(props: Props) { /> */}
-
diff --git a/apps/web/core/components/global/product-updates/modal.tsx b/apps/web/core/components/global/product-updates/modal.tsx index 87ac429c2e..ef3f7540da 100644 --- a/apps/web/core/components/global/product-updates/modal.tsx +++ b/apps/web/core/components/global/product-updates/modal.tsx @@ -1,12 +1,8 @@ -import { useEffect } from "react"; import { observer } from "mobx-react"; -import { USER_TRACKER_ELEMENTS } from "@plane/constants"; // ui import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui"; // components import { ProductUpdatesFooter } from "@/components/global"; -// helpers -import { captureView } from "@/helpers/event-tracker.helper"; // plane web components import { ProductUpdatesChangelog } from "@/plane-web/components/global/product-updates/changelog"; import { ProductUpdatesHeader } from "@/plane-web/components/global/product-updates/header"; @@ -19,12 +15,6 @@ export type ProductUpdatesModalProps = { export const ProductUpdatesModal = observer(function ProductUpdatesModal(props: ProductUpdatesModalProps) { const { isOpen, handleClose } = props; - useEffect(() => { - if (isOpen) { - captureView({ elementName: USER_TRACKER_ELEMENTS.PRODUCT_CHANGELOG_MODAL }); - } - }, [isOpen]); - return ( diff --git a/apps/web/core/components/home/root.tsx b/apps/web/core/components/home/root.tsx index 2712c3ac8c..8735e8812b 100644 --- a/apps/web/core/components/home/root.tsx +++ b/apps/web/core/components/home/root.tsx @@ -2,10 +2,7 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import useSWR from "swr"; // plane imports -import { PRODUCT_TOUR_TRACKER_EVENTS } from "@plane/constants"; import { ContentWrapper } from "@plane/ui"; -// helpers -import { captureSuccess } from "@/helpers/event-tracker.helper"; // hooks import { useHome } from "@/hooks/store/use-home"; import { useUserProfile, useUser } from "@/hooks/store/user"; @@ -33,19 +30,12 @@ export const WorkspaceHomeView = observer(function WorkspaceHomeView() { } ); - const handleTourCompleted = () => { - updateTourCompleted() - .then(() => { - captureSuccess({ - eventName: PRODUCT_TOUR_TRACKER_EVENTS.complete, - payload: { - user_id: currentUser?.id, - }, - }); - }) - .catch((error) => { - console.error(error); - }); + const handleTourCompleted = async () => { + try { + await updateTourCompleted(); + } catch (error) { + console.error("Error updating tour completed", error); + } }; // TODO: refactor loader implementation diff --git a/apps/web/core/components/home/widgets/empty-states/no-projects.tsx b/apps/web/core/components/home/widgets/empty-states/no-projects.tsx index 7d0d7dca9c..fe4384cb7e 100644 --- a/apps/web/core/components/home/widgets/empty-states/no-projects.tsx +++ b/apps/web/core/components/home/widgets/empty-states/no-projects.tsx @@ -5,14 +5,12 @@ import Link from "next/link"; import { useParams } from "next/navigation"; import { Hotel } from "lucide-react"; // plane ui -import { EUserPermissions, EUserPermissionsLevel, PROJECT_TRACKER_ELEMENTS } from "@plane/constants"; +import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants"; import { useLocalStorage } from "@plane/hooks"; import { useTranslation } from "@plane/i18n"; import { MembersPropertyIcon, CheckIcon, ProjectIcon, CloseIcon } from "@plane/propel/icons"; import { cn, getFileURL } from "@plane/utils"; -// helpers // hooks -import { captureClick } from "@/helpers/event-tracker.helper"; import { useCommandPalette } from "@/hooks/store/use-command-palette"; import { useProject } from "@/hooks/store/use-project"; import { useWorkspace } from "@/hooks/store/use-workspace"; @@ -57,7 +55,6 @@ export const NoProjectsEmptyState = observer(function NoProjectsEmptyState() { e.preventDefault(); e.stopPropagation(); toggleCreateProjectModal(true); - captureClick({ elementName: PROJECT_TRACKER_ELEMENTS.EMPTY_STATE_CREATE_PROJECT_BUTTON }); }, disabled: !canCreateProject, }, diff --git a/apps/web/core/components/inbox/content/issue-root.tsx b/apps/web/core/components/inbox/content/issue-root.tsx index 3c7b3c75dc..c09dc192f2 100644 --- a/apps/web/core/components/inbox/content/issue-root.tsx +++ b/apps/web/core/components/inbox/content/issue-root.tsx @@ -2,7 +2,6 @@ import type { Dispatch, SetStateAction } from "react"; import { useEffect, useMemo, useRef } from "react"; import { observer } from "mobx-react"; // plane imports -import { WORK_ITEM_TRACKER_EVENTS } from "@plane/constants"; import type { EditorRefApi } from "@plane/editor"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { TIssue, TNameDescriptionLoader } from "@plane/types"; @@ -17,8 +16,6 @@ import type { TIssueOperations } from "@/components/issues/issue-detail"; import { IssueActivity } from "@/components/issues/issue-detail/issue-activity"; import { IssueReaction } from "@/components/issues/issue-detail/reactions"; import { IssueTitleInput } from "@/components/issues/title-input"; -// helpers -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; // hooks import { useIssueDetail } from "@/hooks/store/use-issue-detail"; import { useMember } from "@/hooks/store/use-member"; @@ -102,10 +99,6 @@ export const InboxIssueMainContent = observer(function InboxIssueMainContent(pro type: TOAST_TYPE.SUCCESS, message: "Work item deleted successfully", }); - captureSuccess({ - eventName: WORK_ITEM_TRACKER_EVENTS.delete, - payload: { id: _issueId }, - }); } catch (error) { console.log("Error in deleting work item:", error); setToast({ @@ -113,47 +106,24 @@ export const InboxIssueMainContent = observer(function InboxIssueMainContent(pro type: TOAST_TYPE.ERROR, message: "Work item delete failed", }); - captureError({ - eventName: WORK_ITEM_TRACKER_EVENTS.delete, - payload: { id: _issueId }, - error: error as Error, - }); } }, update: async (_workspaceSlug: string, _projectId: string, _issueId: string, data: Partial) => { try { await inboxIssue.updateIssue(data); - captureSuccess({ - eventName: WORK_ITEM_TRACKER_EVENTS.update, - payload: { id: _issueId }, - }); } catch (error) { setToast({ title: "Work item update failed", type: TOAST_TYPE.ERROR, message: "Work item update failed", }); - captureError({ - eventName: WORK_ITEM_TRACKER_EVENTS.update, - payload: { id: _issueId }, - error: error as Error, - }); } }, archive: async (workspaceSlug: string, projectId: string, issueId: string) => { try { await archiveIssue(workspaceSlug, projectId, issueId); - captureSuccess({ - eventName: WORK_ITEM_TRACKER_EVENTS.archive, - payload: { id: issueId }, - }); } catch (error) { console.error("Error in archiving issue:", error); - captureError({ - eventName: WORK_ITEM_TRACKER_EVENTS.archive, - payload: { id: issueId }, - error: error as Error, - }); } }, }), diff --git a/apps/web/core/components/inbox/modals/create-modal/create-root.tsx b/apps/web/core/components/inbox/modals/create-modal/create-root.tsx index d07606b4ea..059a4d2f78 100644 --- a/apps/web/core/components/inbox/modals/create-modal/create-root.tsx +++ b/apps/web/core/components/inbox/modals/create-modal/create-root.tsx @@ -1,8 +1,8 @@ -import type { FC, FormEvent } from "react"; +import type { FormEvent } from "react"; import { useCallback, useEffect, useRef, useState } from "react"; import { observer } from "mobx-react"; // plane imports -import { ETabIndices, WORK_ITEM_TRACKER_EVENTS } from "@plane/constants"; +import { ETabIndices } from "@plane/constants"; import type { EditorRefApi } from "@plane/editor"; import { useTranslation } from "@plane/i18n"; import { Button } from "@plane/propel/button"; @@ -10,8 +10,6 @@ import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { TIssue } from "@plane/types"; import { ToggleSwitch } from "@plane/ui"; import { renderFormattedPayloadDate, getTabIndex } from "@plane/utils"; -// helpers -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; // hooks import { useProject } from "@/hooks/store/use-project"; import { useProjectInbox } from "@/hooks/store/use-project-inbox"; @@ -170,12 +168,6 @@ export const InboxIssueCreateRoot = observer(function InboxIssueCreateRoot(props descriptionEditorRef?.current?.clearEditor(); setFormData(defaultIssueData); } - captureSuccess({ - eventName: WORK_ITEM_TRACKER_EVENTS.create, - payload: { - id: res?.issue?.id, - }, - }); setToast({ type: TOAST_TYPE.SUCCESS, title: `Success!`, @@ -184,13 +176,6 @@ export const InboxIssueCreateRoot = observer(function InboxIssueCreateRoot(props }) .catch((error) => { console.error(error); - captureError({ - eventName: WORK_ITEM_TRACKER_EVENTS.create, - payload: { - id: formData?.id, - }, - error: error as Error, - }); setToast({ type: TOAST_TYPE.ERROR, title: `Error!`, diff --git a/apps/web/core/components/integration/jira/give-details.tsx b/apps/web/core/components/integration/jira/give-details.tsx index 969462a6cf..65601beecc 100644 --- a/apps/web/core/components/integration/jira/give-details.tsx +++ b/apps/web/core/components/integration/jira/give-details.tsx @@ -1,9 +1,6 @@ -import React from "react"; import { observer } from "mobx-react"; import Link from "next/link"; import { useFormContext, Controller } from "react-hook-form"; - -import { PROJECT_TRACKER_ELEMENTS } from "@plane/constants"; import { PlusIcon } from "@plane/propel/icons"; import type { IJiraImporterForm } from "@plane/types"; // hooks @@ -11,7 +8,6 @@ import type { IJiraImporterForm } from "@plane/types"; import { CustomSelect, Input } from "@plane/ui"; // helpers import { checkEmailValidity } from "@plane/utils"; -import { captureClick } from "@/helpers/event-tracker.helper"; import { useCommandPalette } from "@/hooks/store/use-command-palette"; import { useProject } from "@/hooks/store/use-project"; // types @@ -199,9 +195,7 @@ export const JiraGetImportDetail = observer(function JiraGetImportDetail() {
- diff --git a/apps/web/core/components/onboarding/invitations.tsx b/apps/web/core/components/onboarding/invitations.tsx index 7c04a3f655..457fb32650 100644 --- a/apps/web/core/components/onboarding/invitations.tsx +++ b/apps/web/core/components/onboarding/invitations.tsx @@ -1,6 +1,6 @@ -import React, { useState } from "react"; +import { useState } from "react"; // plane imports -import { ROLE, MEMBER_TRACKER_EVENTS, MEMBER_TRACKER_ELEMENTS } from "@plane/constants"; +import { ROLE } from "@plane/constants"; // types import { Button } from "@plane/propel/button"; import type { IWorkspaceMemberInvitation } from "@plane/types"; @@ -11,7 +11,6 @@ import { truncateText } from "@plane/utils"; // helpers import { WorkspaceLogo } from "@/components/workspace/logo"; // hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useWorkspace } from "@/hooks/store/use-workspace"; import { useUserSettings } from "@/hooks/store/user"; // services @@ -43,31 +42,15 @@ export function Invitations(props: Props) { const submitInvitations = async () => { const invitation = invitations?.find((invitation) => invitation.id === invitationsRespond[0]); - if (invitationsRespond.length <= 0 && !invitation?.role) return; - setIsJoiningWorkspaces(true); - try { await workspaceService.joinWorkspaces({ invitations: invitationsRespond }); - captureSuccess({ - eventName: MEMBER_TRACKER_EVENTS.accept, - payload: { - member_id: invitation?.id, - }, - }); await fetchWorkspaces(); await fetchCurrentUserSettings(); await handleNextStep(); - } catch (error: any) { + } catch (error) { console.error(error); - captureError({ - eventName: MEMBER_TRACKER_EVENTS.accept, - payload: { - member_id: invitation?.id, - }, - error: error, - }); setIsJoiningWorkspaces(false); } }; @@ -114,7 +97,6 @@ export function Invitations(props: Props) { className="w-full" onClick={submitInvitations} disabled={isJoiningWorkspaces || !invitationsRespond.length} - data-ph-element={MEMBER_TRACKER_ELEMENTS.ONBOARDING_JOIN_WORKSPACE} > {isJoiningWorkspaces ? : "Continue to workspace"} diff --git a/apps/web/core/components/onboarding/invite-members.tsx b/apps/web/core/components/onboarding/invite-members.tsx index f78d114a0b..9f2464f4f4 100644 --- a/apps/web/core/components/onboarding/invite-members.tsx +++ b/apps/web/core/components/onboarding/invite-members.tsx @@ -15,7 +15,7 @@ import { XCircle } from "lucide-react"; import { Listbox } from "@headlessui/react"; // plane imports import type { EUserPermissions } from "@plane/constants"; -import { ROLE, ROLE_DETAILS, MEMBER_TRACKER_EVENTS, MEMBER_TRACKER_ELEMENTS } from "@plane/constants"; +import { ROLE, ROLE_DETAILS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; // types import { Button } from "@plane/propel/button"; @@ -24,8 +24,6 @@ import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { IUser, IWorkspace } from "@plane/types"; // ui import { Input, Spinner } from "@plane/ui"; -// helpers -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; // services import { WorkspaceService } from "@/plane-web/services"; // components @@ -294,28 +292,14 @@ export function InviteMembers(props: Props) { })), }) .then(async () => { - captureSuccess({ - eventName: MEMBER_TRACKER_EVENTS.invite, - payload: { - workspace: workspace.slug, - }, - }); setToast({ type: TOAST_TYPE.SUCCESS, title: "Success!", message: "Invitations sent successfully.", }); - await nextStep(); }) .catch((err) => { - captureError({ - eventName: MEMBER_TRACKER_EVENTS.invite, - payload: { - workspace: workspace.slug, - }, - error: err, - }); setToast({ type: TOAST_TYPE.ERROR, title: "Error!", @@ -399,7 +383,6 @@ export function InviteMembers(props: Props) { size="xl" className="w-full" disabled={isInvitationDisabled || !isValid || isSubmitting} - data-ph-element={MEMBER_TRACKER_ELEMENTS.ONBOARDING_INVITE_MEMBER} > {isSubmitting ? : "Continue"} diff --git a/apps/web/core/components/onboarding/profile-setup.tsx b/apps/web/core/components/onboarding/profile-setup.tsx index 95bc3c2210..0374a8ee05 100644 --- a/apps/web/core/components/onboarding/profile-setup.tsx +++ b/apps/web/core/components/onboarding/profile-setup.tsx @@ -1,13 +1,8 @@ -import React, { useMemo, useState } from "react"; +import { useMemo, useState } from "react"; import { observer } from "mobx-react"; import { Controller, useForm } from "react-hook-form"; import { Eye, EyeOff } from "lucide-react"; -import { - AUTH_TRACKER_EVENTS, - E_PASSWORD_STRENGTH, - ONBOARDING_TRACKER_ELEMENTS, - USER_TRACKER_EVENTS, -} from "@plane/constants"; +import { E_PASSWORD_STRENGTH } from "@plane/constants"; // types import { useTranslation } from "@plane/i18n"; import { Button } from "@plane/propel/button"; @@ -18,10 +13,7 @@ import { Input, PasswordStrengthIndicator, Spinner } from "@plane/ui"; // components import { cn, getFileURL, getPasswordStrength } from "@plane/utils"; import { UserImageUploadModal } from "@/components/core/modals/user-image-upload-modal"; -// constants -// helpers // hooks -import { captureError, captureSuccess, captureView } from "@/helpers/event-tracker.helper"; import { useUser, useUserProfile } from "@/hooks/store/user"; // services import { AuthService } from "@/services/auth.service"; @@ -118,18 +110,7 @@ export const ProfileSetup = observer(function ProfileSetup(props: Props) { const handleSetPassword = async (password: string) => { const token = await authService.requestCSRFToken().then((data) => data?.csrf_token); - await authService - .setPassword(token, { password }) - .then(() => { - captureSuccess({ - eventName: AUTH_TRACKER_EVENTS.password_created, - }); - }) - .catch(() => { - captureError({ - eventName: AUTH_TRACKER_EVENTS.password_created, - }); - }); + await authService.setPassword(token, { password }); }; const handleSubmitProfileSetup = async (formData: TProfileSetupFormValues) => { @@ -148,13 +129,6 @@ export const ProfileSetup = observer(function ProfileSetup(props: Props) { updateUserProfile(profileUpdatePayload), totalSteps > 2 && stepChange({ profile_complete: true }), ]); - captureSuccess({ - eventName: USER_TRACKER_EVENTS.add_details, - payload: { - use_case: profileUpdatePayload.use_case, - role: formData.role, - }, - }); setToast({ type: TOAST_TYPE.SUCCESS, title: "Success", @@ -165,9 +139,6 @@ export const ProfileSetup = observer(function ProfileSetup(props: Props) { finishOnboarding(); } } catch { - captureError({ - eventName: USER_TRACKER_EVENTS.add_details, - }); setToast({ type: TOAST_TYPE.ERROR, title: "Error", @@ -188,20 +159,11 @@ export const ProfileSetup = observer(function ProfileSetup(props: Props) { formData.password && handleSetPassword(formData.password), ]).then(() => { if (formData.password) { - captureView({ - elementName: ONBOARDING_TRACKER_ELEMENTS.PASSWORD_CREATION_SELECTED, - }); } else { - captureView({ - elementName: ONBOARDING_TRACKER_ELEMENTS.PASSWORD_CREATION_SKIPPED, - }); + setProfileSetupStep(EProfileSetupSteps.USER_PERSONALIZATION); } - setProfileSetupStep(EProfileSetupSteps.USER_PERSONALIZATION); }); } catch { - captureError({ - eventName: USER_TRACKER_EVENTS.add_details, - }); setToast({ type: TOAST_TYPE.ERROR, title: "Error", @@ -220,13 +182,6 @@ export const ProfileSetup = observer(function ProfileSetup(props: Props) { updateUserProfile(profileUpdatePayload), totalSteps > 2 && stepChange({ profile_complete: true }), ]); - captureSuccess({ - eventName: USER_TRACKER_EVENTS.add_details, - payload: { - use_case: profileUpdatePayload.use_case, - role: formData.role, - }, - }); setToast({ type: TOAST_TYPE.SUCCESS, title: "Success", @@ -237,9 +192,6 @@ export const ProfileSetup = observer(function ProfileSetup(props: Props) { finishOnboarding(); } } catch { - captureError({ - eventName: USER_TRACKER_EVENTS.add_details, - }); setToast({ type: TOAST_TYPE.ERROR, title: "Error", @@ -250,9 +202,6 @@ export const ProfileSetup = observer(function ProfileSetup(props: Props) { const onSubmit = async (formData: TProfileSetupFormValues) => { if (!user) return; - captureView({ - elementName: ONBOARDING_TRACKER_ELEMENTS.PROFILE_SETUP_FORM, - }); if (profileSetupStep === EProfileSetupSteps.ALL) await handleSubmitProfileSetup(formData); if (profileSetupStep === EProfileSetupSteps.USER_DETAILS) await handleSubmitUserDetail(formData); if (profileSetupStep === EProfileSetupSteps.USER_PERSONALIZATION) await handleSubmitUserPersonalization(formData); diff --git a/apps/web/core/components/onboarding/root.tsx b/apps/web/core/components/onboarding/root.tsx index 22fbf9ccc7..b839066fbe 100644 --- a/apps/web/core/components/onboarding/root.tsx +++ b/apps/web/core/components/onboarding/root.tsx @@ -1,13 +1,9 @@ -import type { FC } from "react"; import { useCallback, useEffect, useState } from "react"; import { observer } from "mobx-react"; // plane imports -import { USER_TRACKER_EVENTS } from "@plane/constants"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { IWorkspaceMemberInvitation, TOnboardingStep, TOnboardingSteps, TUserProfile } from "@plane/types"; import { EOnboardingSteps } from "@plane/types"; -// helpers -import { captureSuccess } from "@/helpers/event-tracker.helper"; // hooks import { useWorkspace } from "@/hooks/store/use-workspace"; import { useUser, useUserProfile } from "@/hooks/store/user"; @@ -34,24 +30,15 @@ export const OnboardingRoot = observer(function OnboardingRoot({ invitations = [ // complete onboarding const finishOnboarding = useCallback(async () => { if (!user) return; - - await finishUserOnboarding() - .then(() => { - captureSuccess({ - eventName: USER_TRACKER_EVENTS.onboarding_complete, - payload: { - email: user.email, - user_id: user.id, - }, - }); - }) - .catch(() => { - setToast({ - type: TOAST_TYPE.ERROR, - title: "Failed", - message: "Failed to finish onboarding, Please try again later.", - }); + try { + await finishUserOnboarding(); + } catch (_error) { + setToast({ + type: TOAST_TYPE.ERROR, + title: "Failed", + message: "Failed to finish onboarding, Please try again later.", }); + } }, [user, finishUserOnboarding]); // handle step change diff --git a/apps/web/core/components/onboarding/steps/profile/root.tsx b/apps/web/core/components/onboarding/steps/profile/root.tsx index a6530e47cb..06a1062490 100644 --- a/apps/web/core/components/onboarding/steps/profile/root.tsx +++ b/apps/web/core/components/onboarding/steps/profile/root.tsx @@ -1,10 +1,9 @@ -import type { FC } from "react"; import { useMemo, useState } from "react"; import { observer } from "mobx-react"; import { Controller, useForm } from "react-hook-form"; import { ImageIcon } from "lucide-react"; // plane imports -import { E_PASSWORD_STRENGTH, ONBOARDING_TRACKER_ELEMENTS, USER_TRACKER_EVENTS } from "@plane/constants"; +import { E_PASSWORD_STRENGTH } from "@plane/constants"; import { Button } from "@plane/propel/button"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { IUser } from "@plane/types"; @@ -12,8 +11,6 @@ import { EOnboardingSteps } from "@plane/types"; import { cn, getFileURL, getPasswordStrength } from "@plane/utils"; // components import { UserImageUploadModal } from "@/components/core/modals/user-image-upload-modal"; -// helpers -import { captureError, captureView } from "@/helpers/event-tracker.helper"; // hooks import { useInstance } from "@/hooks/store/use-instance"; import { useUser, useUserProfile } from "@/hooks/store/user"; @@ -94,9 +91,6 @@ export const ProfileSetupStep = observer(function ProfileSetupStep({ handleStepC formData.password && handleSetPassword(formData.password), ]); } catch { - captureError({ - eventName: USER_TRACKER_EVENTS.add_details, - }); setToast({ type: TOAST_TYPE.ERROR, title: "Error", @@ -107,15 +101,11 @@ export const ProfileSetupStep = observer(function ProfileSetupStep({ handleStepC const onSubmit = async (formData: TProfileSetupFormValues) => { if (!user) return; - captureView({ - elementName: ONBOARDING_TRACKER_ELEMENTS.PROFILE_SETUP_FORM, - }); updateUserProfile({ has_marketing_email_consent: formData.has_marketing_email_consent, }); - await handleSubmitUserDetail(formData).then(() => { - handleStepChange(EOnboardingSteps.PROFILE_SETUP); - }); + await handleSubmitUserDetail(formData); + handleStepChange(EOnboardingSteps.PROFILE_SETUP); }; const handleDelete = (url: string | null | undefined) => { diff --git a/apps/web/core/components/onboarding/steps/role/root.tsx b/apps/web/core/components/onboarding/steps/role/root.tsx index 63342cce21..824f5763bf 100644 --- a/apps/web/core/components/onboarding/steps/role/root.tsx +++ b/apps/web/core/components/onboarding/steps/role/root.tsx @@ -1,16 +1,12 @@ -import type { FC } from "react"; import { observer } from "mobx-react"; import { Controller, useForm } from "react-hook-form"; import { Box, PenTool, Rocket, Monitor, RefreshCw } from "lucide-react"; // plane imports -import { ONBOARDING_TRACKER_ELEMENTS, USER_TRACKER_EVENTS } from "@plane/constants"; import { Button } from "@plane/propel/button"; import { CheckIcon, ViewsIcon } from "@plane/propel/icons"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { TUserProfile } from "@plane/types"; import { EOnboardingSteps } from "@plane/types"; -// helpers -import { captureError, captureSuccess, captureView } from "@/helpers/event-tracker.helper"; // hooks import { useUserProfile } from "@/hooks/store/user"; // local components @@ -61,22 +57,12 @@ export const RoleSetupStep = observer(function RoleSetupStep({ handleStepChange updateUserProfile(profileUpdatePayload), // totalSteps > 2 && stepChange({ profile_complete: true }), ]); - captureSuccess({ - eventName: USER_TRACKER_EVENTS.add_details, - payload: { - use_case: formData.use_case, - role: formData.role, - }, - }); setToast({ type: TOAST_TYPE.SUCCESS, title: "Success", message: "Profile setup completed!", }); } catch { - captureError({ - eventName: USER_TRACKER_EVENTS.add_details, - }); setToast({ type: TOAST_TYPE.ERROR, title: "Error", @@ -87,12 +73,8 @@ export const RoleSetupStep = observer(function RoleSetupStep({ handleStepChange const onSubmit = async (formData: TProfileSetupFormValues) => { if (!profile) return; - captureView({ - elementName: ONBOARDING_TRACKER_ELEMENTS.PROFILE_SETUP_FORM, - }); - await handleSubmitUserPersonalization(formData).then(() => { - handleStepChange(EOnboardingSteps.ROLE_SETUP); - }); + await handleSubmitUserPersonalization(formData); + handleStepChange(EOnboardingSteps.ROLE_SETUP); }; const handleSkip = () => { diff --git a/apps/web/core/components/onboarding/steps/team/root.tsx b/apps/web/core/components/onboarding/steps/team/root.tsx index a5263d01d9..b088e7c144 100644 --- a/apps/web/core/components/onboarding/steps/team/root.tsx +++ b/apps/web/core/components/onboarding/steps/team/root.tsx @@ -9,26 +9,19 @@ import type { UseFormWatch, } from "react-hook-form"; import { Controller, useFieldArray, useForm } from "react-hook-form"; -// icons import { usePopper } from "react-popper"; import { XCircle } from "lucide-react"; import { Listbox } from "@headlessui/react"; // plane imports import type { EUserPermissions } from "@plane/constants"; -import { ROLE, ROLE_DETAILS, MEMBER_TRACKER_EVENTS, MEMBER_TRACKER_ELEMENTS } from "@plane/constants"; +import { ROLE, ROLE_DETAILS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { Button } from "@plane/propel/button"; import { PlusIcon, CheckIcon, ChevronDownIcon } from "@plane/propel/icons"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; -// types import { EOnboardingSteps } from "@plane/types"; -// ui import { Input, Spinner } from "@plane/ui"; -// constants -// helpers - // hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useWorkspace } from "@/hooks/store/use-workspace"; // services import { WorkspaceService } from "@/plane-web/services"; @@ -299,28 +292,14 @@ export const InviteTeamStep = observer(function InviteTeamStep(props: Props) { })), }) .then(async () => { - captureSuccess({ - eventName: MEMBER_TRACKER_EVENTS.invite, - payload: { - workspace: workspace.slug, - }, - }); setToast({ type: TOAST_TYPE.SUCCESS, title: "Success!", message: "Invitations sent successfully.", }); - await nextStep(); }) .catch((err) => { - captureError({ - eventName: MEMBER_TRACKER_EVENTS.invite, - payload: { - workspace: workspace.slug, - }, - error: err, - }); setToast({ type: TOAST_TYPE.ERROR, title: "Error!", @@ -399,7 +378,6 @@ export const InviteTeamStep = observer(function InviteTeamStep(props: Props) { size="xl" className="w-full" disabled={isInvitationDisabled || !isValid || isSubmitting} - data-ph-element={MEMBER_TRACKER_ELEMENTS.ONBOARDING_INVITE_MEMBER} > {isSubmitting ? : "Continue"} diff --git a/apps/web/core/components/onboarding/steps/usecase/root.tsx b/apps/web/core/components/onboarding/steps/usecase/root.tsx index a33eac894b..63a3401497 100644 --- a/apps/web/core/components/onboarding/steps/usecase/root.tsx +++ b/apps/web/core/components/onboarding/steps/usecase/root.tsx @@ -1,17 +1,13 @@ -import type { FC } from "react"; import { observer } from "mobx-react"; import { Controller, useForm } from "react-hook-form"; - // plane imports -import { ONBOARDING_TRACKER_ELEMENTS, USER_TRACKER_EVENTS, USE_CASES } from "@plane/constants"; +import { USE_CASES } from "@plane/constants"; import { Button } from "@plane/propel/button"; import { CheckIcon } from "@plane/propel/icons"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { TUserProfile } from "@plane/types"; import { EOnboardingSteps } from "@plane/types"; import { cn } from "@plane/utils"; -// helpers -import { captureError, captureSuccess, captureView } from "@/helpers/event-tracker.helper"; // hooks import { useUserProfile } from "@/hooks/store/user"; // local imports @@ -52,21 +48,12 @@ export const UseCaseSetupStep = observer(function UseCaseSetupStep({ handleStepC updateUserProfile(profileUpdatePayload), // totalSteps > 2 && stepChange({ profile_complete: true }), ]); - captureSuccess({ - eventName: USER_TRACKER_EVENTS.add_details, - payload: { - use_case: profileUpdatePayload.use_case, - }, - }); setToast({ type: TOAST_TYPE.SUCCESS, title: "Success", message: "Profile setup completed!", }); } catch { - captureError({ - eventName: USER_TRACKER_EVENTS.add_details, - }); setToast({ type: TOAST_TYPE.ERROR, title: "Error", @@ -78,12 +65,8 @@ export const UseCaseSetupStep = observer(function UseCaseSetupStep({ handleStepC // on submit const onSubmit = async (formData: TProfileSetupFormValues) => { if (!profile) return; - captureView({ - elementName: ONBOARDING_TRACKER_ELEMENTS.PROFILE_SETUP_FORM, - }); - await handleSubmitUserPersonalization(formData).then(() => { - handleStepChange(EOnboardingSteps.USE_CASE_SETUP); - }); + await handleSubmitUserPersonalization(formData); + handleStepChange(EOnboardingSteps.USE_CASE_SETUP); }; // handle skip diff --git a/apps/web/core/components/onboarding/steps/workspace/create.tsx b/apps/web/core/components/onboarding/steps/workspace/create.tsx index 53a5c454a7..6100f75c1a 100644 --- a/apps/web/core/components/onboarding/steps/workspace/create.tsx +++ b/apps/web/core/components/onboarding/steps/workspace/create.tsx @@ -3,20 +3,13 @@ import { observer } from "mobx-react"; import { Controller, useForm } from "react-hook-form"; import { CircleCheck } from "lucide-react"; // plane imports -import { - ORGANIZATION_SIZE, - RESTRICTED_URLS, - WORKSPACE_TRACKER_ELEMENTS, - WORKSPACE_TRACKER_EVENTS, -} from "@plane/constants"; +import { ORGANIZATION_SIZE, RESTRICTED_URLS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { Button } from "@plane/propel/button"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { IUser, IWorkspace } from "@plane/types"; import { Spinner } from "@plane/ui"; import { cn } from "@plane/utils"; -// helpers -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; // hooks import { useWorkspace } from "@/hooks/store/use-workspace"; import { useUserProfile, useUserSettings } from "@/hooks/store/user"; @@ -82,19 +75,10 @@ export const WorkspaceCreateStep = observer(function WorkspaceCreateStep({ title: t("workspace_creation.toast.success.title"), message: t("workspace_creation.toast.success.message"), }); - captureSuccess({ - eventName: WORKSPACE_TRACKER_EVENTS.create, - payload: { slug: formData.slug }, - }); await fetchWorkspaces(); await completeStep(workspaceResponse.id); onComplete(formData.organization_size === "Just myself"); } catch { - captureError({ - eventName: WORKSPACE_TRACKER_EVENTS.create, - payload: { slug: formData.slug }, - error: new Error("Error creating workspace"), - }); setToast({ type: TOAST_TYPE.ERROR, title: t("workspace_creation.toast.error.title"), @@ -299,14 +283,7 @@ export const WorkspaceCreateStep = observer(function WorkspaceCreateStep({
- {hasInvitations && ( diff --git a/apps/web/core/components/onboarding/steps/workspace/join-invites.tsx b/apps/web/core/components/onboarding/steps/workspace/join-invites.tsx index 7cc70e8d7f..98511293c0 100644 --- a/apps/web/core/components/onboarding/steps/workspace/join-invites.tsx +++ b/apps/web/core/components/onboarding/steps/workspace/join-invites.tsx @@ -1,14 +1,12 @@ -import React, { useState } from "react"; +import { useState } from "react"; // plane imports -import { MEMBER_TRACKER_ELEMENTS, MEMBER_TRACKER_EVENTS, ROLE } from "@plane/constants"; +import { ROLE } from "@plane/constants"; import { Button } from "@plane/propel/button"; import type { IWorkspaceMemberInvitation } from "@plane/types"; import { Checkbox, Spinner } from "@plane/ui"; import { truncateText } from "@plane/utils"; // constants import { WorkspaceLogo } from "@/components/workspace/logo"; -// helpers -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; // hooks import { useWorkspace } from "@/hooks/store/use-workspace"; import { useUserSettings } from "@/hooks/store/user"; @@ -52,24 +50,11 @@ export function WorkspaceJoinInvitesStep(props: Props) { try { await workspaceService.joinWorkspaces({ invitations: invitationsRespond }); - captureSuccess({ - eventName: MEMBER_TRACKER_EVENTS.accept, - payload: { - member_id: invitation?.id, - }, - }); await fetchWorkspaces(); await fetchCurrentUserSettings(); await handleNextStep(); } catch (error: any) { console.error(error); - captureError({ - eventName: MEMBER_TRACKER_EVENTS.accept, - payload: { - member_id: invitation?.id, - }, - error: error, - }); setIsJoiningWorkspaces(false); } }; @@ -114,7 +99,6 @@ export function WorkspaceJoinInvitesStep(props: Props) { className="w-full" onClick={submitInvitations} disabled={isJoiningWorkspaces || !invitationsRespond.length} - data-ph-element={MEMBER_TRACKER_ELEMENTS.ONBOARDING_JOIN_WORKSPACE} > {isJoiningWorkspaces ? : "Continue"} diff --git a/apps/web/core/components/pages/dropdowns/actions.tsx b/apps/web/core/components/pages/dropdowns/actions.tsx index 07180394ff..0b300a757e 100644 --- a/apps/web/core/components/pages/dropdowns/actions.tsx +++ b/apps/web/core/components/pages/dropdowns/actions.tsx @@ -3,9 +3,8 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { ArchiveRestoreIcon, FileOutput, LockKeyhole, LockKeyholeOpen } from "lucide-react"; // constants -import { EPageAccess, PROJECT_PAGE_TRACKER_ELEMENTS } from "@plane/constants"; +import { EPageAccess } from "@plane/constants"; // plane editor -import type { EditorRefApi } from "@plane/editor"; import { LinkIcon, CopyIcon, LockIcon, NewTabIcon, ArchiveIcon, TrashIcon, GlobeIcon } from "@plane/propel/icons"; // plane ui import type { TContextMenuItem } from "@plane/ui"; @@ -13,9 +12,7 @@ import { ContextMenu, CustomMenu } from "@plane/ui"; // components import { cn } from "@plane/utils"; import { DeletePageModal } from "@/components/pages/modals/delete-page-modal"; -// helpers // hooks -import { captureClick } from "@/helpers/event-tracker.helper"; import { usePageOperations } from "@/hooks/use-page-operations"; // plane web components import { MovePageModal } from "@/plane-web/components/pages"; @@ -82,9 +79,6 @@ export const PageActions = observer(function PageActions(props: Props) { { key: "toggle-lock", action: () => { - captureClick({ - elementName: PROJECT_PAGE_TRACKER_ELEMENTS.LOCK_BUTTON, - }); pageOperations.toggleLock(); }, title: is_locked ? "Unlock" : "Lock", @@ -94,9 +88,6 @@ export const PageActions = observer(function PageActions(props: Props) { { key: "toggle-access", action: () => { - captureClick({ - elementName: PROJECT_PAGE_TRACKER_ELEMENTS.ACCESS_TOGGLE, - }); pageOperations.toggleAccess(); }, title: access === EPageAccess.PUBLIC ? "Make private" : "Make public", @@ -120,9 +111,6 @@ export const PageActions = observer(function PageActions(props: Props) { { key: "make-a-copy", action: () => { - captureClick({ - elementName: PROJECT_PAGE_TRACKER_ELEMENTS.DUPLICATE_BUTTON, - }); pageOperations.duplicate(); }, title: "Make a copy", @@ -132,9 +120,6 @@ export const PageActions = observer(function PageActions(props: Props) { { key: "archive-restore", action: () => { - captureClick({ - elementName: PROJECT_PAGE_TRACKER_ELEMENTS.ARCHIVE_BUTTON, - }); pageOperations.toggleArchive(); }, title: archived_at ? "Restore" : "Archive", @@ -144,9 +129,6 @@ export const PageActions = observer(function PageActions(props: Props) { { key: "delete", action: () => { - captureClick({ - elementName: PROJECT_PAGE_TRACKER_ELEMENTS.CONTEXT_MENU, - }); setDeletePageModal(true); }, title: "Delete", diff --git a/apps/web/core/components/pages/header/favorite-control.tsx b/apps/web/core/components/pages/header/favorite-control.tsx index ea5ea44c8e..7e74abba72 100644 --- a/apps/web/core/components/pages/header/favorite-control.tsx +++ b/apps/web/core/components/pages/header/favorite-control.tsx @@ -1,11 +1,7 @@ import { observer } from "mobx-react"; import { Star } from "lucide-react"; -// constants -import { PROJECT_PAGE_TRACKER_ELEMENTS } from "@plane/constants"; // ui import { IconButton } from "@plane/propel/icon-button"; -// helpers -import { captureClick } from "@/helpers/event-tracker.helper"; // hooks import { usePageOperations } from "@/hooks/use-page-operations"; // store @@ -31,9 +27,6 @@ export const PageFavoriteControl = observer(function PageFavoriteControl({ page size="lg" icon={Star} onClick={() => { - captureClick({ - elementName: PROJECT_PAGE_TRACKER_ELEMENTS.FAVORITE_BUTTON, - }); pageOperations.toggleFavorite(); }} aria-label={is_favorite ? "Remove favorite" : "Add to favorites"} diff --git a/apps/web/core/components/pages/list/block-item-action.tsx b/apps/web/core/components/pages/list/block-item-action.tsx index 278a83dd48..c8034e7bfe 100644 --- a/apps/web/core/components/pages/list/block-item-action.tsx +++ b/apps/web/core/components/pages/list/block-item-action.tsx @@ -1,13 +1,10 @@ import { observer } from "mobx-react"; import { Earth, Info, Minus } from "lucide-react"; // plane imports -import { PROJECT_PAGE_TRACKER_ELEMENTS } from "@plane/constants"; import { LockIcon } from "@plane/propel/icons"; import { Tooltip } from "@plane/propel/tooltip"; import { Avatar, FavoriteStar } from "@plane/ui"; import { renderFormattedDate, getFileURL } from "@plane/utils"; -// helpers -import { captureClick } from "@/helpers/event-tracker.helper"; // hooks import { useMember } from "@/hooks/store/use-member"; import { usePageOperations } from "@/hooks/use-page-operations"; @@ -65,9 +62,6 @@ export const BlockItemAction = observer(function BlockItemAction(props: Props) { onClick={(e) => { e.preventDefault(); e.stopPropagation(); - captureClick({ - elementName: PROJECT_PAGE_TRACKER_ELEMENTS.FAVORITE_BUTTON, - }); pageOperations.toggleFavorite(); }} selected={is_favorite} diff --git a/apps/web/core/components/pages/modals/create-page-modal.tsx b/apps/web/core/components/pages/modals/create-page-modal.tsx index f398be341a..927c0f268f 100644 --- a/apps/web/core/components/pages/modals/create-page-modal.tsx +++ b/apps/web/core/components/pages/modals/create-page-modal.tsx @@ -1,13 +1,10 @@ -import type { FC } from "react"; import { useEffect, useState } from "react"; // constants import type { EPageAccess } from "@plane/constants"; -import { PROJECT_PAGE_TRACKER_EVENTS } from "@plane/constants"; import type { TPage } from "@plane/types"; // ui import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui"; // hooks -import { captureSuccess, captureError } from "@/helpers/event-tracker.helper"; import { useAppRouter } from "@/hooks/use-app-router"; // plane web hooks import type { EPageStoreType } from "@/plane-web/hooks/store"; @@ -64,20 +61,11 @@ export function CreatePageModal(props: Props) { try { const pageData = await createPage(pageFormData); if (pageData) { - captureSuccess({ - eventName: PROJECT_PAGE_TRACKER_EVENTS.create, - payload: { - id: pageData.id, - }, - }); handleStateClear(); if (redirectionEnabled) router.push(`/${workspaceSlug}/projects/${projectId}/pages/${pageData.id}`); } - } catch (error: any) { - captureError({ - eventName: PROJECT_PAGE_TRACKER_EVENTS.create, - error, - }); + } catch (error) { + console.error(error); } }; diff --git a/apps/web/core/components/pages/modals/delete-page-modal.tsx b/apps/web/core/components/pages/modals/delete-page-modal.tsx index 4c91aecf15..701431c18e 100644 --- a/apps/web/core/components/pages/modals/delete-page-modal.tsx +++ b/apps/web/core/components/pages/modals/delete-page-modal.tsx @@ -2,13 +2,10 @@ import { useState } from "react"; import { observer } from "mobx-react"; // ui import { useParams } from "next/navigation"; -import { PROJECT_PAGE_TRACKER_EVENTS } from "@plane/constants"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import { AlertModalCore } from "@plane/ui"; import { getPageName } from "@plane/utils"; // constants -// hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; // plane web hooks import { useAppRouter } from "@/hooks/use-app-router"; import type { EPageStoreType } from "@/plane-web/hooks/store"; @@ -46,12 +43,6 @@ export const DeletePageModal = observer(function DeletePageModal(props: TConfirm setIsDeleting(true); await removePage({ pageId }) .then(() => { - captureSuccess({ - eventName: PROJECT_PAGE_TRACKER_EVENTS.delete, - payload: { - id: pageId, - }, - }); handleClose(); setToast({ type: TOAST_TYPE.SUCCESS, @@ -64,12 +55,6 @@ export const DeletePageModal = observer(function DeletePageModal(props: TConfirm } }) .catch(() => { - captureError({ - eventName: PROJECT_PAGE_TRACKER_EVENTS.delete, - payload: { - id: pageId, - }, - }); setToast({ type: TOAST_TYPE.ERROR, title: "Error!", diff --git a/apps/web/core/components/pages/pages-list-main-content.tsx b/apps/web/core/components/pages/pages-list-main-content.tsx index 58e239140b..e41d0f8858 100644 --- a/apps/web/core/components/pages/pages-list-main-content.tsx +++ b/apps/web/core/components/pages/pages-list-main-content.tsx @@ -2,12 +2,7 @@ import { useState } from "react"; import { observer } from "mobx-react"; // plane imports import { useParams, useRouter } from "next/navigation"; -import { - EUserPermissionsLevel, - EPageAccess, - PROJECT_PAGE_TRACKER_ELEMENTS, - PROJECT_PAGE_TRACKER_EVENTS, -} from "@plane/constants"; +import { EUserPermissionsLevel, EPageAccess } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { EmptyStateDetailed } from "@plane/propel/empty-state"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; @@ -15,7 +10,6 @@ import type { TPage, TPageNavigationTabs } from "@plane/types"; import { EUserProjectRoles } from "@plane/types"; // components import { PageLoader } from "@/components/pages/loaders/page-loader"; -import { captureClick, captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useProject } from "@/hooks/store/use-project"; import { useUserPermissions } from "@/hooks/store/user"; // plane web hooks @@ -60,23 +54,10 @@ export const PagesListMainContent = observer(function PagesListMainContent(props await createPage(payload) .then((res) => { - captureSuccess({ - eventName: PROJECT_PAGE_TRACKER_EVENTS.create, - payload: { - id: res?.id, - state: "SUCCESS", - }, - }); const pageId = `/${workspaceSlug}/projects/${currentProjectDetails?.id}/pages/${res?.id}`; router.push(pageId); }) .catch((err) => { - captureError({ - eventName: PROJECT_PAGE_TRACKER_EVENTS.create, - payload: { - state: "ERROR", - }, - }); setToast({ type: TOAST_TYPE.ERROR, title: "Error!", @@ -100,7 +81,6 @@ export const PagesListMainContent = observer(function PagesListMainContent(props label: t("project_empty_state.pages.cta_primary"), onClick: () => { handleCreatePage(); - captureClick({ elementName: PROJECT_PAGE_TRACKER_ELEMENTS.EMPTY_STATE_CREATE_BUTTON }); }, variant: "primary", disabled: !canPerformEmptyStateActions || isCreatingPage, @@ -120,7 +100,6 @@ export const PagesListMainContent = observer(function PagesListMainContent(props label: t("project_empty_state.pages.cta_primary"), onClick: () => { handleCreatePage(); - captureClick({ elementName: PROJECT_PAGE_TRACKER_ELEMENTS.EMPTY_STATE_CREATE_BUTTON }); }, variant: "primary", disabled: !canPerformEmptyStateActions || isCreatingPage, @@ -139,7 +118,6 @@ export const PagesListMainContent = observer(function PagesListMainContent(props label: t("project_empty_state.pages.cta_primary"), onClick: () => { handleCreatePage(); - captureClick({ elementName: PROJECT_PAGE_TRACKER_ELEMENTS.EMPTY_STATE_CREATE_BUTTON }); }, variant: "primary", disabled: !canPerformEmptyStateActions || isCreatingPage, diff --git a/apps/web/core/components/profile/form.tsx b/apps/web/core/components/profile/form.tsx index 2a25b24e97..ec9d52bb29 100644 --- a/apps/web/core/components/profile/form.tsx +++ b/apps/web/core/components/profile/form.tsx @@ -4,7 +4,6 @@ import { Controller, useForm } from "react-hook-form"; import { CircleUserRound } from "lucide-react"; import { Disclosure, Transition } from "@headlessui/react"; // plane imports -import { PROFILE_SETTINGS_TRACKER_ELEMENTS, PROFILE_SETTINGS_TRACKER_EVENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { Button } from "@plane/propel/button"; import { ChevronDownIcon } from "@plane/propel/icons"; @@ -21,7 +20,6 @@ import { UserImageUploadModal } from "@/components/core/modals/user-image-upload import { CoverImage } from "@/components/common/cover-image"; // helpers import { handleCoverImageChange } from "@/helpers/cover-image.helper"; -import { captureSuccess, captureError } from "@/helpers/event-tracker.helper"; // hooks import { useInstance } from "@/hooks/store/use-instance"; import { useUser, useUserProfile } from "@/hooks/store/user"; @@ -164,16 +162,9 @@ export const ProfileForm = observer(function ProfileForm(props: TProfileFormProp }); updateUserAndProfile .then(() => { - captureSuccess({ - eventName: PROFILE_SETTINGS_TRACKER_EVENTS.update_profile, - }); return; }) - .catch(() => { - captureError({ - eventName: PROFILE_SETTINGS_TRACKER_EVENTS.update_profile, - }); - }); + .catch(() => {}); }; return ( @@ -385,12 +376,7 @@ export const ProfileForm = observer(function ProfileForm(props: TProfileFormProp
-
@@ -417,11 +403,7 @@ export const ProfileForm = observer(function ProfileForm(props: TProfileFormProp
{t("deactivate_account_description")}
-
diff --git a/apps/web/core/components/profile/notification/email-notification-form.tsx b/apps/web/core/components/profile/notification/email-notification-form.tsx index 39e9d382cb..8ab4fac880 100644 --- a/apps/web/core/components/profile/notification/email-notification-form.tsx +++ b/apps/web/core/components/profile/notification/email-notification-form.tsx @@ -1,14 +1,11 @@ -import type { FC } from "react"; -import React, { useEffect } from "react"; +import { useEffect } from "react"; import { Controller, useForm } from "react-hook-form"; -import { PROFILE_SETTINGS_TRACKER_ELEMENTS, PROFILE_SETTINGS_TRACKER_EVENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { IUserEmailNotificationSettings } from "@plane/types"; // ui import { ToggleSwitch } from "@plane/ui"; // services -import { captureClick, captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { UserService } from "@/services/user.service"; // types interface IEmailNotificationFormProps { @@ -33,25 +30,12 @@ export function EmailNotificationForm(props: IEmailNotificationFormProps) { await userService.updateCurrentUserEmailNotificationSettings({ [key]: value, }); - captureSuccess({ - eventName: PROFILE_SETTINGS_TRACKER_EVENTS.notifications_updated, - payload: { - [key]: value, - }, - }); setToast({ title: t("success"), type: TOAST_TYPE.SUCCESS, message: t("email_notification_setting_updated_successfully"), }); - } catch (err) { - console.error(err); - captureError({ - eventName: PROFILE_SETTINGS_TRACKER_EVENTS.notifications_updated, - payload: { - [key]: value, - }, - }); + } catch (_error) { setToast({ title: t("error"), type: TOAST_TYPE.ERROR, @@ -82,9 +66,6 @@ export function EmailNotificationForm(props: IEmailNotificationFormProps) { value={value} onChange={(newValue) => { onChange(newValue); - captureClick({ - elementName: PROFILE_SETTINGS_TRACKER_ELEMENTS.PROPERTY_CHANGES_TOGGLE, - }); handleSettingChange("property_change", newValue); }} size="sm" @@ -107,9 +88,6 @@ export function EmailNotificationForm(props: IEmailNotificationFormProps) { value={value} onChange={(newValue) => { onChange(newValue); - captureClick({ - elementName: PROFILE_SETTINGS_TRACKER_ELEMENTS.STATE_CHANGES_TOGGLE, - }); handleSettingChange("state_change", newValue); }} size="sm" @@ -154,9 +132,6 @@ export function EmailNotificationForm(props: IEmailNotificationFormProps) { value={value} onChange={(newValue) => { onChange(newValue); - captureClick({ - elementName: PROFILE_SETTINGS_TRACKER_ELEMENTS.COMMENTS_TOGGLE, - }); handleSettingChange("comment", newValue); }} size="sm" @@ -179,9 +154,6 @@ export function EmailNotificationForm(props: IEmailNotificationFormProps) { value={value} onChange={(newValue) => { onChange(newValue); - captureClick({ - elementName: PROFILE_SETTINGS_TRACKER_ELEMENTS.MENTIONS_TOGGLE, - }); handleSettingChange("mention", newValue); }} size="sm" diff --git a/apps/web/core/components/profile/preferences/language-timezone.tsx b/apps/web/core/components/profile/preferences/language-timezone.tsx index 677ae2bcbd..ef2de25298 100644 --- a/apps/web/core/components/profile/preferences/language-timezone.tsx +++ b/apps/web/core/components/profile/preferences/language-timezone.tsx @@ -1,10 +1,8 @@ import { observer } from "mobx-react"; -import { PROFILE_SETTINGS_TRACKER_ELEMENTS, PROFILE_SETTINGS_TRACKER_EVENTS } from "@plane/constants"; import { SUPPORTED_LANGUAGES, useTranslation } from "@plane/i18n"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import { CustomSelect } from "@plane/ui"; import { TimezoneSelect } from "@/components/global"; -import { captureElementAndEvent } from "@/helpers/event-tracker.helper"; import { useUser, useUserProfile } from "@/hooks/store/user"; export const LanguageTimezone = observer(function LanguageTimezone() { @@ -17,81 +15,38 @@ export const LanguageTimezone = observer(function LanguageTimezone() { const { updateUserProfile } = useUserProfile(); const { t } = useTranslation(); - const handleTimezoneChange = (value: string) => { - updateCurrentUser({ user_timezone: value }) - .then(() => { - captureElementAndEvent({ - element: { - elementName: PROFILE_SETTINGS_TRACKER_ELEMENTS.TIMEZONE_DROPDOWN, - }, - event: { - eventName: PROFILE_SETTINGS_TRACKER_EVENTS.timezone_updated, - payload: { - timezone: value, - }, - state: "SUCCESS", - }, - }); - setToast({ - title: "Success!", - message: "Timezone updated successfully", - type: TOAST_TYPE.SUCCESS, - }); - }) - .catch(() => { - captureElementAndEvent({ - element: { - elementName: PROFILE_SETTINGS_TRACKER_ELEMENTS.TIMEZONE_DROPDOWN, - }, - event: { - eventName: PROFILE_SETTINGS_TRACKER_EVENTS.timezone_updated, - state: "ERROR", - }, - }); - setToast({ - title: "Error!", - message: "Failed to update timezone", - type: TOAST_TYPE.ERROR, - }); + const handleTimezoneChange = async (value: string) => { + try { + await updateCurrentUser({ user_timezone: value }); + setToast({ + title: "Success!", + message: "Timezone updated successfully", + type: TOAST_TYPE.SUCCESS, }); + } catch (_error) { + setToast({ + title: "Error!", + message: "Failed to update timezone", + type: TOAST_TYPE.ERROR, + }); + } }; - const handleLanguageChange = (value: string) => { - updateUserProfile({ language: value }) - .then(() => { - captureElementAndEvent({ - element: { - elementName: PROFILE_SETTINGS_TRACKER_ELEMENTS.LANGUAGE_DROPDOWN, - }, - event: { - eventName: PROFILE_SETTINGS_TRACKER_EVENTS.language_updated, - payload: { - language: value, - }, - state: "SUCCESS", - }, - }); - setToast({ - title: "Success!", - message: "Language updated successfully", - type: TOAST_TYPE.SUCCESS, - }); - }) - .catch(() => { - captureElementAndEvent({ - element: { - elementName: PROFILE_SETTINGS_TRACKER_ELEMENTS.LANGUAGE_DROPDOWN, - }, - event: { - eventName: PROFILE_SETTINGS_TRACKER_EVENTS.language_updated, - state: "ERROR", - }, - }); - setToast({ - title: "Error!", - message: "Failed to update language", - type: TOAST_TYPE.ERROR, - }); + + const handleLanguageChange = async (value: string) => { + try { + await updateUserProfile({ language: value }); + setToast({ + title: "Success!", + message: "Language updated successfully", + type: TOAST_TYPE.SUCCESS, }); + } catch (_error) { + setToast({ + title: "Error!", + message: "Failed to update language", + type: TOAST_TYPE.ERROR, + }); + } }; const getLanguageLabel = (value: string) => { diff --git a/apps/web/core/components/profile/start-of-week-preference.tsx b/apps/web/core/components/profile/start-of-week-preference.tsx index 259e570a7f..d95a0857be 100644 --- a/apps/web/core/components/profile/start-of-week-preference.tsx +++ b/apps/web/core/components/profile/start-of-week-preference.tsx @@ -1,16 +1,10 @@ -import React from "react"; import { observer } from "mobx-react"; // plane imports -import { - PROFILE_SETTINGS_TRACKER_ELEMENTS, - PROFILE_SETTINGS_TRACKER_EVENTS, - START_OF_THE_WEEK_OPTIONS, -} from "@plane/constants"; +import { START_OF_THE_WEEK_OPTIONS } from "@plane/constants"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { EStartOfTheWeek } from "@plane/types"; import { CustomSelect } from "@plane/ui"; // hooks -import { captureElementAndEvent } from "@/helpers/event-tracker.helper"; import { useUserProfile } from "@/hooks/store/user"; import { PreferencesSection } from "../preferences/section"; @@ -23,6 +17,15 @@ export const StartOfWeekPreference = observer(function StartOfWeekPreference(pro // hooks const { data: userProfile, updateUserProfile } = useUserProfile(); + const handleStartOfWeekChange = async (val: number) => { + try { + await updateUserProfile({ start_of_the_week: val }); + setToast({ type: TOAST_TYPE.SUCCESS, title: "Success", message: "First day of the week updated successfully" }); + } catch (_error) { + setToast({ type: TOAST_TYPE.ERROR, title: "Update failed", message: "Please try again later." }); + } + }; + return ( { - updateUserProfile({ start_of_the_week: val }) - .then(() => { - captureElementAndEvent({ - element: { - elementName: PROFILE_SETTINGS_TRACKER_ELEMENTS.FIRST_DAY_OF_WEEK_DROPDOWN, - }, - event: { - eventName: PROFILE_SETTINGS_TRACKER_EVENTS.first_day_updated, - payload: { - start_of_the_week: val, - }, - state: "SUCCESS", - }, - }); - setToast({ - type: TOAST_TYPE.SUCCESS, - title: "Success", - message: "First day of the week updated successfully", - }); - }) - .catch(() => { - captureElementAndEvent({ - element: { - elementName: PROFILE_SETTINGS_TRACKER_ELEMENTS.FIRST_DAY_OF_WEEK_DROPDOWN, - }, - event: { - eventName: PROFILE_SETTINGS_TRACKER_EVENTS.first_day_updated, - state: "ERROR", - }, - }); - setToast({ type: TOAST_TYPE.ERROR, title: "Update failed", message: "Please try again later." }); - }); - }} + onChange={handleStartOfWeekChange} input maxHeight="lg" > diff --git a/apps/web/core/components/project-states/create-update/create.tsx b/apps/web/core/components/project-states/create-update/create.tsx index 7cded141b5..a47eaed264 100644 --- a/apps/web/core/components/project-states/create-update/create.tsx +++ b/apps/web/core/components/project-states/create-update/create.tsx @@ -1,22 +1,20 @@ import { useState } from "react"; import { observer } from "mobx-react"; -import { STATE_TRACKER_EVENTS, STATE_GROUPS } from "@plane/constants"; +import { STATE_GROUPS } from "@plane/constants"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { IState, TStateGroups, TStateOperationsCallbacks } from "@plane/types"; // components import { StateForm } from "@/components/project-states"; -// hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; type TStateCreate = { groupKey: TStateGroups; - shouldTrackEvents: boolean; + shouldTrackEvents?: boolean; createStateCallback: TStateOperationsCallbacks["createState"]; handleClose: () => void; }; export const StateCreate = observer(function StateCreate(props: TStateCreate) { - const { groupKey, shouldTrackEvents, createStateCallback, handleClose } = props; + const { groupKey, createStateCallback, handleClose } = props; // states const [loader, setLoader] = useState(false); @@ -31,14 +29,7 @@ export const StateCreate = observer(function StateCreate(props: TStateCreate) { try { const response = await createStateCallback({ ...formData, group: groupKey }); - if (shouldTrackEvents) - captureSuccess({ - eventName: STATE_TRACKER_EVENTS.create, - payload: { - state_group: groupKey, - id: response.id, - }, - }); + setToast({ type: TOAST_TYPE.SUCCESS, title: "Success!", @@ -48,13 +39,6 @@ export const StateCreate = observer(function StateCreate(props: TStateCreate) { return { status: "success" }; } catch (error) { const errorStatus = error as { status: number; data: { error: string } }; - if (shouldTrackEvents) - captureError({ - eventName: STATE_TRACKER_EVENTS.create, - payload: { - state_group: groupKey, - }, - }); if (errorStatus?.status === 400) { setToast({ type: TOAST_TYPE.ERROR, diff --git a/apps/web/core/components/project-states/create-update/update.tsx b/apps/web/core/components/project-states/create-update/update.tsx index a71e913e9e..beeec8ef25 100644 --- a/apps/web/core/components/project-states/create-update/update.tsx +++ b/apps/web/core/components/project-states/create-update/update.tsx @@ -1,12 +1,9 @@ import { useState } from "react"; import { observer } from "mobx-react"; -import { STATE_TRACKER_EVENTS } from "@plane/constants"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { IState, TStateOperationsCallbacks } from "@plane/types"; // components import { StateForm } from "@/components/project-states"; -// hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; type TStateUpdate = { state: IState; @@ -16,7 +13,7 @@ type TStateUpdate = { }; export const StateUpdate = observer(function StateUpdate(props: TStateUpdate) { - const { state, updateStateCallback, shouldTrackEvents, handleClose } = props; + const { state, updateStateCallback, handleClose } = props; // states const [loader, setLoader] = useState(false); @@ -30,15 +27,6 @@ export const StateUpdate = observer(function StateUpdate(props: TStateUpdate) { try { await updateStateCallback(state.id, formData); - if (shouldTrackEvents) { - captureSuccess({ - eventName: STATE_TRACKER_EVENTS.update, - payload: { - state_group: state.group, - id: state.id, - }, - }); - } setToast({ type: TOAST_TYPE.SUCCESS, title: "Success!", @@ -61,15 +49,6 @@ export const StateUpdate = observer(function StateUpdate(props: TStateUpdate) { title: "Error!", message: "State could not be updated. Please try again.", }); - if (shouldTrackEvents) { - captureError({ - eventName: STATE_TRACKER_EVENTS.update, - payload: { - state_group: state.group, - id: state.id, - }, - }); - } return { status: "error" }; } } diff --git a/apps/web/core/components/project-states/options/delete.tsx b/apps/web/core/components/project-states/options/delete.tsx index dc554012bb..7048bf4b1e 100644 --- a/apps/web/core/components/project-states/options/delete.tsx +++ b/apps/web/core/components/project-states/options/delete.tsx @@ -1,7 +1,6 @@ import { useState } from "react"; import { observer } from "mobx-react"; import { Loader } from "lucide-react"; -import { STATE_TRACKER_EVENTS, STATE_TRACKER_ELEMENTS } from "@plane/constants"; import { CloseIcon } from "@plane/propel/icons"; // plane imports import { TOAST_TYPE, setToast } from "@plane/propel/toast"; @@ -10,18 +9,17 @@ import type { IState, TStateOperationsCallbacks } from "@plane/types"; import { AlertModalCore } from "@plane/ui"; import { cn } from "@plane/utils"; // hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { usePlatformOS } from "@/hooks/use-platform-os"; type TStateDelete = { totalStates: number; state: IState; deleteStateCallback: TStateOperationsCallbacks["deleteState"]; - shouldTrackEvents: boolean; + shouldTrackEvents?: boolean; }; export const StateDelete = observer(function StateDelete(props: TStateDelete) { - const { totalStates, state, deleteStateCallback, shouldTrackEvents } = props; + const { totalStates, state, deleteStateCallback } = props; // hooks const { isMobile } = usePlatformOS(); // states @@ -37,26 +35,9 @@ export const StateDelete = observer(function StateDelete(props: TStateDelete) { try { await deleteStateCallback(state.id); - if (shouldTrackEvents) { - captureSuccess({ - eventName: STATE_TRACKER_EVENTS.delete, - payload: { - id: state.id, - }, - }); - } - setIsDelete(false); } catch (error) { const errorStatus = error as { status: number; data: { error: string } }; - if (shouldTrackEvents) { - captureError({ - eventName: STATE_TRACKER_EVENTS.delete, - payload: { - id: state.id, - }, - }); - } if (errorStatus.status === 400) { setToast({ type: TOAST_TYPE.ERROR, @@ -99,7 +80,6 @@ export const StateDelete = observer(function StateDelete(props: TStateDelete) { )} disabled={isDeleteDisabled} onClick={() => setIsDeleteModal(true)} - data-ph-element={STATE_TRACKER_ELEMENTS.STATE_LIST_DELETE_BUTTON} > { - captureSuccess({ - eventName: STATE_TRACKER_EVENTS.delete, - payload: { - id: data.id, - }, - }); handleClose(); }) .catch((err) => { @@ -60,12 +51,6 @@ export const StateDeleteModal = observer(function StateDeleteModal(props: TState title: "Error!", message: "State could not be deleted. Please try again.", }); - captureError({ - eventName: STATE_TRACKER_EVENTS.delete, - payload: { - id: data.id, - }, - }); }) .finally(() => { setIsDeleteLoading(false); diff --git a/apps/web/core/components/project/card-list.tsx b/apps/web/core/components/project/card-list.tsx index 24efb4802e..01e7842379 100644 --- a/apps/web/core/components/project/card-list.tsx +++ b/apps/web/core/components/project/card-list.tsx @@ -1,13 +1,12 @@ import { observer } from "mobx-react"; // plane imports -import { EUserPermissionsLevel, EUserPermissions, PROJECT_TRACKER_ELEMENTS } from "@plane/constants"; +import { EUserPermissionsLevel, EUserPermissions } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { EmptyStateDetailed } from "@plane/propel/empty-state"; import { ContentWrapper } from "@plane/ui"; // components import { calculateTotalFilters } from "@plane/utils"; import { ProjectsLoader } from "@/components/ui/loader/projects-loader"; -import { captureClick } from "@/helpers/event-tracker.helper"; // hooks import { useCommandPalette } from "@/hooks/store/use-command-palette"; import { useProject } from "@/hooks/store/use-project"; @@ -62,7 +61,6 @@ export const ProjectCardList = observer(function ProjectCardList(props: TProject label: t("workspace_projects.empty_state.general.primary_button.text"), onClick: () => { toggleCreateProjectModal(true); - captureClick({ elementName: PROJECT_TRACKER_ELEMENTS.EMPTY_STATE_CREATE_PROJECT_BUTTON }); }, disabled: !canPerformEmptyStateActions, variant: "primary", diff --git a/apps/web/core/components/project/create/header.tsx b/apps/web/core/components/project/create/header.tsx index abbaf259bc..3e6c1384cc 100644 --- a/apps/web/core/components/project/create/header.tsx +++ b/apps/web/core/components/project/create/header.tsx @@ -55,7 +55,7 @@ function ProjectCreateHeader(props: Props) { )} {isClosable && (
-
diff --git a/apps/web/core/components/project/delete-project-modal.tsx b/apps/web/core/components/project/delete-project-modal.tsx index 8b4f33f39f..3a0276fee9 100644 --- a/apps/web/core/components/project/delete-project-modal.tsx +++ b/apps/web/core/components/project/delete-project-modal.tsx @@ -1,16 +1,12 @@ import { useParams } from "next/navigation"; import { Controller, useForm } from "react-hook-form"; import { AlertTriangle } from "lucide-react"; -// types -import { PROJECT_TRACKER_EVENTS } from "@plane/constants"; +// Plane imports import { Button } from "@plane/propel/button"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { IProject } from "@plane/types"; -// ui import { Input, EModalPosition, EModalWidth, ModalCore } from "@plane/ui"; -// constants // hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useProject } from "@/hooks/store/use-project"; import { useAppRouter } from "@/hooks/use-app-router"; @@ -55,36 +51,22 @@ export function DeleteProjectModal(props: DeleteProjectModal) { const onSubmit = async () => { if (!workspaceSlug || !canDelete) return; - await deleteProject(workspaceSlug.toString(), project.id) - .then(() => { - if (projectId && projectId.toString() === project.id) router.push(`/${workspaceSlug}/projects`); - - handleClose(); - captureSuccess({ - eventName: PROJECT_TRACKER_EVENTS.delete, - payload: { - id: project.id, - }, - }); - setToast({ - type: TOAST_TYPE.SUCCESS, - title: "Success!", - message: "Project deleted successfully.", - }); - }) - .catch(() => { - captureError({ - eventName: PROJECT_TRACKER_EVENTS.delete, - payload: { - id: project.id, - }, - }); - setToast({ - type: TOAST_TYPE.ERROR, - title: "Error!", - message: "Something went wrong. Please try again later.", - }); + try { + await deleteProject(workspaceSlug.toString(), project.id); + if (projectId && projectId.toString() === project.id) router.push(`/${workspaceSlug}/projects`); + handleClose(); + setToast({ + type: TOAST_TYPE.SUCCESS, + title: "Success!", + message: "Project deleted successfully.", }); + } catch (_error) { + setToast({ + type: TOAST_TYPE.ERROR, + title: "Error!", + message: "Something went wrong. Please try again later.", + }); + } }; return ( diff --git a/apps/web/core/components/project/form.tsx b/apps/web/core/components/project/form.tsx index cc405aaab6..634275c40f 100644 --- a/apps/web/core/components/project/form.tsx +++ b/apps/web/core/components/project/form.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from "react"; import { Controller, useForm } from "react-hook-form"; import { Info } from "lucide-react"; -import { NETWORK_CHOICES, PROJECT_TRACKER_ELEMENTS, PROJECT_TRACKER_EVENTS } from "@plane/constants"; +import { NETWORK_CHOICES } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; // plane imports import { Button } from "@plane/propel/button"; @@ -18,7 +18,6 @@ import { ImagePickerPopover } from "@/components/core/image-picker-popover"; import { TimezoneSelect } from "@/components/global"; // helpers import { handleCoverImageChange } from "@/helpers/cover-image.helper"; -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; // hooks import { useProject } from "@/hooks/store/use-project"; import { usePlatformOS } from "@/hooks/use-platform-os"; @@ -87,12 +86,6 @@ export function ProjectDetailsForm(props: IProjectDetailsForm) { if (!workspaceSlug || !project) return; return updateProject(workspaceSlug.toString(), project.id, payload) .then(() => { - captureSuccess({ - eventName: PROJECT_TRACKER_EVENTS.update, - payload: { - id: projectId, - }, - }); setToast({ type: TOAST_TYPE.SUCCESS, title: t("toast.success"), @@ -101,13 +94,6 @@ export function ProjectDetailsForm(props: IProjectDetailsForm) { }) .catch((err) => { try { - captureError({ - eventName: PROJECT_TRACKER_EVENTS.update, - payload: { - id: projectId, - }, - }); - // Handle the new error format where codes are nested in arrays under field names const errorData = err ?? {}; @@ -437,14 +423,7 @@ export function ProjectDetailsForm(props: IProjectDetailsForm) {
<> - diff --git a/apps/web/core/components/project/leave-project-modal.tsx b/apps/web/core/components/project/leave-project-modal.tsx index 20a81e9f65..202a43f38c 100644 --- a/apps/web/core/components/project/leave-project-modal.tsx +++ b/apps/web/core/components/project/leave-project-modal.tsx @@ -1,18 +1,13 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { Controller, useForm } from "react-hook-form"; -// headless ui import { AlertTriangleIcon } from "lucide-react"; -// types -import { MEMBER_TRACKER_EVENTS } from "@plane/constants"; +// Plane imports import { Button } from "@plane/propel/button"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { IProject } from "@plane/types"; -// ui import { Input, EModalPosition, EModalWidth, ModalCore } from "@plane/ui"; -// constants // hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useUserPermissions } from "@/hooks/store/user"; import { useAppRouter } from "@/hooks/use-app-router"; @@ -62,21 +57,8 @@ export const LeaveProjectModal = observer(function LeaveProjectModal(props: ILea return leaveProject(workspaceSlug.toString(), project.id) .then(() => { handleClose(); - captureSuccess({ - eventName: MEMBER_TRACKER_EVENTS.project.leave, - payload: { - project: project.id, - }, - }); }) .catch((err) => { - captureError({ - eventName: MEMBER_TRACKER_EVENTS.project.leave, - payload: { - project: project.id, - }, - error: err, - }); setToast({ type: TOAST_TYPE.ERROR, title: "Error!", diff --git a/apps/web/core/components/project/member-list-item.tsx b/apps/web/core/components/project/member-list-item.tsx index b3589a74ca..4955f85c48 100644 --- a/apps/web/core/components/project/member-list-item.tsx +++ b/apps/web/core/components/project/member-list-item.tsx @@ -1,10 +1,7 @@ import { observer } from "mobx-react"; // plane imports -import { MEMBER_TRACKER_EVENTS } from "@plane/constants"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import { Table } from "@plane/ui"; -// helpers -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; // hooks import { useMember } from "@/hooks/store/use-member"; import { useUser, useUserPermissions } from "@/hooks/store/user"; @@ -45,21 +42,8 @@ export const ProjectMemberListItem = observer(function ProjectMemberListItem(pro await leaveProject(workspaceSlug.toString(), projectId.toString()) .then(async () => { router.push(`/${workspaceSlug}/projects`); - captureSuccess({ - eventName: MEMBER_TRACKER_EVENTS.project.leave, - payload: { - project: projectId, - }, - }); }) .catch((err) => { - captureError({ - eventName: MEMBER_TRACKER_EVENTS.project.leave, - payload: { - project: projectId, - }, - error: err, - }); setToast({ type: TOAST_TYPE.ERROR, title: "You can’t leave this project yet.", diff --git a/apps/web/core/components/project/send-project-invitation-modal.tsx b/apps/web/core/components/project/send-project-invitation-modal.tsx index 8b1391da88..e2b8ef68e1 100644 --- a/apps/web/core/components/project/send-project-invitation-modal.tsx +++ b/apps/web/core/components/project/send-project-invitation-modal.tsx @@ -2,7 +2,7 @@ import React, { useEffect } from "react"; import { observer } from "mobx-react"; import { useForm, Controller, useFieldArray } from "react-hook-form"; // plane imports -import { ROLE, EUserPermissions, MEMBER_TRACKER_EVENTS } from "@plane/constants"; +import { ROLE, EUserPermissions } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { Button } from "@plane/propel/button"; import { PlusIcon, CloseIcon, ChevronDownIcon } from "@plane/propel/icons"; @@ -11,7 +11,6 @@ import { Avatar, CustomSelect, CustomSearchSelect, EModalPosition, EModalWidth, // helpers import { getFileURL } from "@plane/utils"; // hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useMember } from "@/hooks/store/use-member"; import { useUserPermissions } from "@/hooks/store/user"; @@ -86,23 +85,9 @@ export const SendProjectInvitationModal = observer(function SendProjectInvitatio type: TOAST_TYPE.SUCCESS, message: "Members added successfully.", }); - - captureSuccess({ - eventName: MEMBER_TRACKER_EVENTS.project.add, - payload: { - members: [...payload.members.map((member) => member.member_id)], - }, - }); }) .catch((error) => { console.error(error); - captureError({ - eventName: MEMBER_TRACKER_EVENTS.project.add, - payload: { - members: [...payload.members.map((member) => member.member_id)], - }, - error: error, - }); }) .finally(() => { reset(defaultValues); diff --git a/apps/web/core/components/project/settings/features-list.tsx b/apps/web/core/components/project/settings/features-list.tsx index a2fa4ccdef..fcfab32ae0 100644 --- a/apps/web/core/components/project/settings/features-list.tsx +++ b/apps/web/core/components/project/settings/features-list.tsx @@ -1,14 +1,11 @@ import { observer } from "mobx-react"; // plane imports -import { PROJECT_TRACKER_EVENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { setPromiseToast } from "@plane/propel/toast"; import { Tooltip } from "@plane/propel/tooltip"; import type { IProject } from "@plane/types"; // components import { SettingsHeading } from "@/components/settings/heading"; -// helpers -import { captureSuccess } from "@/helpers/event-tracker.helper"; // hooks import { useProject } from "@/hooks/store/use-project"; import { useUser } from "@/hooks/store/user"; @@ -53,12 +50,6 @@ export const ProjectFeaturesList = observer(function ProjectFeaturesList(props: }, }); void updateProjectPromise.then(() => { - captureSuccess({ - eventName: PROJECT_TRACKER_EVENTS.feature_toggled, - payload: { - feature_key: featureKey, - }, - }); return undefined; }); }; diff --git a/apps/web/core/components/views/delete-view-modal.tsx b/apps/web/core/components/views/delete-view-modal.tsx index b1810b30ff..f657fb60e8 100644 --- a/apps/web/core/components/views/delete-view-modal.tsx +++ b/apps/web/core/components/views/delete-view-modal.tsx @@ -1,15 +1,12 @@ -import React, { useState } from "react"; +import { useState } from "react"; import { observer } from "mobx-react"; import { useParams, useRouter } from "next/navigation"; // types -import { PROJECT_VIEW_TRACKER_EVENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { IProjectView } from "@plane/types"; // ui import { AlertModalCore } from "@plane/ui"; -// helpers -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; // hooks import { useProjectView } from "@/hooks/store/use-project-view"; @@ -36,41 +33,24 @@ export const DeleteProjectViewModal = observer(function DeleteProjectViewModal(p const handleDeleteView = async () => { if (!workspaceSlug || !projectId) return; - - setIsDeleteLoading(true); - - await deleteView(workspaceSlug.toString(), projectId.toString(), data.id) - .then(() => { - handleClose(); - router.push(`/${workspaceSlug}/projects/${projectId}/views`); - setToast({ - type: TOAST_TYPE.SUCCESS, - title: "Success!", - message: "View deleted successfully.", - }); - captureSuccess({ - eventName: PROJECT_VIEW_TRACKER_EVENTS.delete, - payload: { - view_id: data.id, - }, - }); - }) - .catch(() => { - setToast({ - type: TOAST_TYPE.ERROR, - title: "Error!", - message: "View could not be deleted. Please try again.", - }); - captureError({ - eventName: PROJECT_VIEW_TRACKER_EVENTS.delete, - payload: { - view_id: data.id, - }, - }); - }) - .finally(() => { - setIsDeleteLoading(false); + try { + setIsDeleteLoading(true); + await deleteView(workspaceSlug.toString(), projectId.toString(), data.id); + handleClose(); + router.push(`/${workspaceSlug}/projects/${projectId}/views`); + setToast({ + type: TOAST_TYPE.SUCCESS, + title: "Success!", + message: "View deleted successfully.", }); + } catch (_error) { + setToast({ + type: TOAST_TYPE.ERROR, + title: "Error!", + message: "View could not be deleted. Please try again.", + }); + } + setIsDeleteLoading(false); }; return ( diff --git a/apps/web/core/components/views/modal.tsx b/apps/web/core/components/views/modal.tsx index 289d1d44be..785e901ff0 100644 --- a/apps/web/core/components/views/modal.tsx +++ b/apps/web/core/components/views/modal.tsx @@ -1,14 +1,11 @@ -import type { FC } from "react"; import { observer } from "mobx-react"; // types -import { PROJECT_VIEW_TRACKER_EVENTS } from "@plane/constants"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { IProjectView } from "@plane/types"; import { EIssuesStoreType } from "@plane/types"; // ui import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui"; // hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useIssues } from "@/hooks/store/use-issues"; import { useProjectView } from "@/hooks/store/use-project-view"; import { useWorkItemFilters } from "@/hooks/store/work-item-filters/use-work-item-filters"; @@ -42,60 +39,37 @@ export const CreateUpdateProjectViewModal = observer(function CreateUpdateProjec }; const handleCreateView = async (payload: IProjectView) => { - await createView(workspaceSlug, projectId, payload) - .then((res) => { - handleClose(); - router.push(`/${workspaceSlug}/projects/${projectId}/views/${res.id}`); - setToast({ - type: TOAST_TYPE.SUCCESS, - title: "Success!", - message: "View created successfully.", - }); - captureSuccess({ - eventName: PROJECT_VIEW_TRACKER_EVENTS.create, - payload: { - view_id: res.id, - }, - }); - }) - .catch(() => { - setToast({ - type: TOAST_TYPE.ERROR, - title: "Error!", - message: "Something went wrong. Please try again.", - }); - captureError({ - eventName: PROJECT_VIEW_TRACKER_EVENTS.create, - }); + try { + const res = await createView(workspaceSlug, projectId, payload); + handleClose(); + router.push(`/${workspaceSlug}/projects/${projectId}/views/${res.id}`); + setToast({ + type: TOAST_TYPE.SUCCESS, + title: "Success!", + message: "View created successfully.", }); + } catch (_error) { + setToast({ + type: TOAST_TYPE.ERROR, + title: "Error!", + message: "Failed to create view. Please try again.", + }); + } }; const handleUpdateView = async (payload: IProjectView) => { - await updateView(workspaceSlug, projectId, data?.id as string, payload) - .then((viewDetails) => { - mutateFilters(workspaceSlug, viewDetails.id, viewDetails); - resetExpression(EIssuesStoreType.PROJECT_VIEW, viewDetails.id, viewDetails.rich_filters); - handleClose(); - captureSuccess({ - eventName: PROJECT_VIEW_TRACKER_EVENTS.update, - payload: { - view_id: data?.id, - }, - }); - }) - .catch((err) => { - setToast({ - type: TOAST_TYPE.ERROR, - title: "Error!", - message: err?.detail ?? "Something went wrong. Please try again.", - }); - captureError({ - eventName: PROJECT_VIEW_TRACKER_EVENTS.update, - payload: { - view_id: data?.id, - }, - }); + try { + const viewDetails = await updateView(workspaceSlug, projectId, data?.id as string, payload); + mutateFilters(workspaceSlug, viewDetails.id, viewDetails); + resetExpression(EIssuesStoreType.PROJECT_VIEW, viewDetails.id, viewDetails.rich_filters); + handleClose(); + } catch (_error) { + setToast({ + type: TOAST_TYPE.ERROR, + title: "Error!", + message: "Failed to update view. Please try again.", }); + } }; const handleFormSubmit = async (formData: IProjectView) => { diff --git a/apps/web/core/components/views/quick-actions.tsx b/apps/web/core/components/views/quick-actions.tsx index dbab8280b8..6e1faad59e 100644 --- a/apps/web/core/components/views/quick-actions.tsx +++ b/apps/web/core/components/views/quick-actions.tsx @@ -2,7 +2,7 @@ import { useState } from "react"; import { observer } from "mobx-react"; import { MoreHorizontal } from "lucide-react"; // types -import { EUserPermissions, EUserPermissionsLevel, PROJECT_VIEW_TRACKER_ELEMENTS } from "@plane/constants"; +import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants"; import { IconButton } from "@plane/propel/icon-button"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { IProjectView } from "@plane/types"; @@ -12,7 +12,6 @@ import { ContextMenu, CustomMenu } from "@plane/ui"; import { copyUrlToClipboard, cn } from "@plane/utils"; // helpers import { useViewMenuItems } from "@/components/common/quick-actions-helper"; -import { captureClick } from "@/helpers/event-tracker.helper"; // hooks import { useUser, useUserPermissions } from "@/hooks/store/user"; import { PublishViewModal, useViewPublish } from "@/plane-web/components/views/publish"; @@ -77,9 +76,7 @@ export const ViewQuickActions = observer(function ViewQuickActions(props: Props) const CONTEXT_MENU_ITEMS = MENU_ITEMS.map(function CONTEXT_MENU_ITEMS(item) { return { ...item, - action: () => { - captureClick({ elementName: PROJECT_VIEW_TRACKER_ELEMENTS.LIST_ITEM_CONTEXT_MENU }); item.action(); }, }; @@ -110,7 +107,6 @@ export const ViewQuickActions = observer(function ViewQuickActions(props: Props) { - captureClick({ elementName: PROJECT_VIEW_TRACKER_ELEMENTS.QUICK_ACTIONS }); item.action(); }} className={cn( diff --git a/apps/web/core/components/web-hooks/create-webhook-modal.tsx b/apps/web/core/components/web-hooks/create-webhook-modal.tsx index 49f8b6c313..e3c36746a2 100644 --- a/apps/web/core/components/web-hooks/create-webhook-modal.tsx +++ b/apps/web/core/components/web-hooks/create-webhook-modal.tsx @@ -1,7 +1,6 @@ -import React, { useState } from "react"; +import { useState } from "react"; import { useParams } from "next/navigation"; // types -import { WORKSPACE_SETTINGS_TRACKER_EVENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { IWebhook, IWorkspace, TWebhookEventTypes } from "@plane/types"; @@ -10,7 +9,6 @@ import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui"; // helpers import { csvDownload } from "@plane/utils"; // hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import useKeypress from "@/hooks/use-keypress"; // components import { WebhookForm } from "./form"; @@ -68,12 +66,6 @@ export function CreateWebhookModal(props: ICreateWebhookModal) { await createWebhook(workspaceSlug.toString(), payload) .then(({ webHook, secretKey }) => { - captureSuccess({ - eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.webhook_created, - payload: { - webhook: formData?.url, - }, - }); setToast({ type: TOAST_TYPE.SUCCESS, title: t("workspace_settings.settings.webhooks.toasts.created.title"), @@ -86,13 +78,6 @@ export function CreateWebhookModal(props: ICreateWebhookModal) { csvDownload(csvData, `webhook-secret-key-${Date.now()}`); }) .catch((error) => { - captureError({ - eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.webhook_created, - payload: { - webhook: formData?.url, - }, - error: error as Error, - }); setToast({ type: TOAST_TYPE.ERROR, title: t("workspace_settings.settings.webhooks.toasts.not_created.title"), diff --git a/apps/web/core/components/web-hooks/delete-webhook-modal.tsx b/apps/web/core/components/web-hooks/delete-webhook-modal.tsx index f370b8b606..11d72cd904 100644 --- a/apps/web/core/components/web-hooks/delete-webhook-modal.tsx +++ b/apps/web/core/components/web-hooks/delete-webhook-modal.tsx @@ -1,11 +1,9 @@ import { useState } from "react"; import { useParams } from "next/navigation"; // ui -import { WORKSPACE_SETTINGS_TRACKER_EVENTS } from "@plane/constants"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import { AlertModalCore } from "@plane/ui"; // hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useWebhook } from "@/hooks/store/use-webhook"; import { useAppRouter } from "@/hooks/use-app-router"; @@ -31,39 +29,23 @@ export function DeleteWebhookModal(props: IDeleteWebhook) { const handleDelete = async () => { if (!workspaceSlug || !webhookId) return; - setIsDeleting(true); - - removeWebhook(workspaceSlug.toString(), webhookId.toString()) - .then(() => { - captureSuccess({ - eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.webhook_deleted, - payload: { - webhook: webhookId, - }, - }); - setToast({ - type: TOAST_TYPE.SUCCESS, - title: "Success!", - message: "Webhook deleted successfully.", - }); - router.replace(`/${workspaceSlug}/settings/webhooks/`); - }) - .catch((error) => { - captureError({ - eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.webhook_deleted, - payload: { - webhook: webhookId, - }, - error: error as Error, - }); - setToast({ - type: TOAST_TYPE.ERROR, - title: "Error!", - message: error?.error ?? "Something went wrong. Please try again.", - }); - }) - .finally(() => setIsDeleting(false)); + try { + await removeWebhook(workspaceSlug.toString(), webhookId.toString()); + router.replace(`/${workspaceSlug}/settings/webhooks/`); + setToast({ + type: TOAST_TYPE.SUCCESS, + title: "Success!", + message: "Webhook deleted successfully.", + }); + } catch (_error) { + setToast({ + type: TOAST_TYPE.ERROR, + title: "Error!", + message: "Webhook could not be deleted. Please try again.", + }); + } + setIsDeleting(false); }; return ( diff --git a/apps/web/core/components/web-hooks/form/toggle.tsx b/apps/web/core/components/web-hooks/form/toggle.tsx index b83f88cc26..88aca446df 100644 --- a/apps/web/core/components/web-hooks/form/toggle.tsx +++ b/apps/web/core/components/web-hooks/form/toggle.tsx @@ -1,12 +1,9 @@ import type { Control } from "react-hook-form"; import { Controller } from "react-hook-form"; // constants -import { WORKSPACE_SETTINGS_TRACKER_ELEMENTS } from "@plane/constants"; import type { IWebhook } from "@plane/types"; // ui import { ToggleSwitch } from "@plane/ui"; -// hooks -import { captureClick } from "@/helpers/event-tracker.helper"; interface IWebHookToggle { control: Control; @@ -23,9 +20,6 @@ export function WebhookToggle({ control }: IWebHookToggle) { { - captureClick({ - elementName: WORKSPACE_SETTINGS_TRACKER_ELEMENTS.WEBHOOK_DETAILS_PAGE_TOGGLE_SWITCH, - }); onChange(val); }} size="sm" diff --git a/apps/web/core/components/web-hooks/webhooks-list-item.tsx b/apps/web/core/components/web-hooks/webhooks-list-item.tsx index 023bb13991..1355406f7a 100644 --- a/apps/web/core/components/web-hooks/webhooks-list-item.tsx +++ b/apps/web/core/components/web-hooks/webhooks-list-item.tsx @@ -1,14 +1,10 @@ -import type { FC } from "react"; import Link from "next/link"; import { useParams } from "next/navigation"; -import { WORKSPACE_SETTINGS_TRACKER_ELEMENTS, WORKSPACE_SETTINGS_TRACKER_EVENTS } from "@plane/constants"; +// Plane imports import type { IWebhook } from "@plane/types"; -// hooks import { ToggleSwitch } from "@plane/ui"; -import { captureElementAndEvent } from "@/helpers/event-tracker.helper"; +// hooks import { useWebhook } from "@/hooks/store/use-webhook"; -// ui -// types interface IWebhookListItem { webhook: IWebhook; @@ -21,37 +17,9 @@ export function WebhooksListItem(props: IWebhookListItem) { // store hooks const { updateWebhook } = useWebhook(); - const handleToggle = () => { + const handleToggle = async () => { if (!workspaceSlug || !webhook.id) return; - updateWebhook(workspaceSlug.toString(), webhook.id, { is_active: !webhook.is_active }) - .then(() => { - captureElementAndEvent({ - element: { - elementName: WORKSPACE_SETTINGS_TRACKER_ELEMENTS.WEBHOOK_LIST_ITEM_TOGGLE_SWITCH, - }, - event: { - eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.webhook_toggled, - state: "SUCCESS", - payload: { - webhook: webhook.url, - }, - }, - }); - }) - .catch(() => { - captureElementAndEvent({ - element: { - elementName: WORKSPACE_SETTINGS_TRACKER_ELEMENTS.WEBHOOK_LIST_ITEM_TOGGLE_SWITCH, - }, - event: { - eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.webhook_toggled, - state: "ERROR", - payload: { - webhook: webhook.url, - }, - }, - }); - }); + await updateWebhook(workspaceSlug.toString(), webhook.id, { is_active: !webhook.is_active }); }; return ( diff --git a/apps/web/core/components/work-item-filters/filters-hoc/project-level.tsx b/apps/web/core/components/work-item-filters/filters-hoc/project-level.tsx index b076ff03fd..2c3f42207c 100644 --- a/apps/web/core/components/work-item-filters/filters-hoc/project-level.tsx +++ b/apps/web/core/components/work-item-filters/filters-hoc/project-level.tsx @@ -2,7 +2,7 @@ import { useCallback, useMemo, useState } from "react"; import { isEqual, cloneDeep } from "lodash-es"; import { observer } from "mobx-react"; // plane imports -import { EUserPermissionsLevel, PROJECT_VIEW_TRACKER_EVENTS } from "@plane/constants"; +import { EUserPermissionsLevel } from "@plane/constants"; import { setToast, TOAST_TYPE } from "@plane/propel/toast"; import type { IProjectView, TWorkItemFilterExpression } from "@plane/types"; import { EUserProjectRoles, EViewAccess } from "@plane/types"; @@ -10,7 +10,6 @@ import { EUserProjectRoles, EViewAccess } from "@plane/types"; import { removeNillKeys } from "@/components/issues/issue-layouts/utils"; import { CreateUpdateProjectViewModal } from "@/components/views/modal"; // hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useCycle } from "@/hooks/store/use-cycle"; import { useLabel } from "@/hooks/store/use-label"; import { useMember } from "@/hooks/store/use-member"; @@ -153,12 +152,6 @@ export const ProjectLevelWorkItemFiltersHOC = observer(function ProjectLevelWork title: "Success!", message: "Your view has been updated successfully.", }); - captureSuccess({ - eventName: PROJECT_VIEW_TRACKER_EVENTS.update, - payload: { - view_id: viewDetails.id, - }, - }); }) .catch(() => { setToast({ @@ -166,12 +159,6 @@ export const ProjectLevelWorkItemFiltersHOC = observer(function ProjectLevelWork title: "Error!", message: "Your view could not be updated. Please try again.", }); - captureError({ - eventName: PROJECT_VIEW_TRACKER_EVENTS.update, - payload: { - view_id: viewDetails.id, - }, - }); }); }, [viewDetails, updateView, workspaceSlug, projectId, getViewFilterPayload] diff --git a/apps/web/core/components/work-item-filters/filters-hoc/workspace-level.tsx b/apps/web/core/components/work-item-filters/filters-hoc/workspace-level.tsx index 59842f8e94..5f15f8fe1c 100644 --- a/apps/web/core/components/work-item-filters/filters-hoc/workspace-level.tsx +++ b/apps/web/core/components/work-item-filters/filters-hoc/workspace-level.tsx @@ -2,7 +2,7 @@ import { useCallback, useMemo, useState } from "react"; import { isEqual, cloneDeep } from "lodash-es"; import { observer } from "mobx-react"; // plane imports -import { DEFAULT_GLOBAL_VIEWS_LIST, EUserPermissionsLevel, GLOBAL_VIEW_TRACKER_EVENTS } from "@plane/constants"; +import { DEFAULT_GLOBAL_VIEWS_LIST, EUserPermissionsLevel } from "@plane/constants"; import { setToast, TOAST_TYPE } from "@plane/propel/toast"; import type { IWorkspaceView, TWorkItemFilterExpression } from "@plane/types"; import { EUserProjectRoles, EViewAccess } from "@plane/types"; @@ -10,7 +10,6 @@ import { EUserProjectRoles, EViewAccess } from "@plane/types"; import { removeNillKeys } from "@/components/issues/issue-layouts/utils"; import { CreateUpdateWorkspaceViewModal } from "@/components/workspace/views/modal"; // hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useGlobalView } from "@/hooks/store/use-global-view"; import { useLabel } from "@/hooks/store/use-label"; import { useMember } from "@/hooks/store/use-member"; @@ -140,12 +139,6 @@ export const WorkspaceLevelWorkItemFiltersHOC = observer(function WorkspaceLevel title: "Success!", message: "Your view has been updated successfully.", }); - captureSuccess({ - eventName: GLOBAL_VIEW_TRACKER_EVENTS.update, - payload: { - view_id: viewDetails.id, - }, - }); }) .catch(() => { setToast({ @@ -153,12 +146,6 @@ export const WorkspaceLevelWorkItemFiltersHOC = observer(function WorkspaceLevel title: "Error!", message: "Your view could not be updated. Please try again.", }); - captureError({ - eventName: GLOBAL_VIEW_TRACKER_EVENTS.update, - payload: { - view_id: viewDetails.id, - }, - }); }); }, [viewDetails, updateGlobalView, workspaceSlug, getViewFilterPayload] diff --git a/apps/web/core/components/workspace-notifications/sidebar/header/options/root.tsx b/apps/web/core/components/workspace-notifications/sidebar/header/options/root.tsx index e1469e7cca..e90622de40 100644 --- a/apps/web/core/components/workspace-notifications/sidebar/header/options/root.tsx +++ b/apps/web/core/components/workspace-notifications/sidebar/header/options/root.tsx @@ -1,17 +1,10 @@ import { observer } from "mobx-react"; import { CheckCheck, RefreshCw } from "lucide-react"; // plane imports -import { - ENotificationLoader, - ENotificationQueryParamType, - NOTIFICATION_TRACKER_ELEMENTS, - NOTIFICATION_TRACKER_EVENTS, -} from "@plane/constants"; +import { ENotificationLoader, ENotificationQueryParamType } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { Tooltip } from "@plane/propel/tooltip"; import { Spinner } from "@plane/ui"; -// helpers -import { captureSuccess } from "@/helpers/event-tracker.helper"; // hooks import { useWorkspaceNotifications } from "@/hooks/store/notifications"; import { usePlatformOS } from "@/hooks/use-platform-os"; @@ -59,12 +52,8 @@ export const NotificationSidebarHeaderOptions = observer(function NotificationSi { - captureSuccess({ - eventName: NOTIFICATION_TRACKER_EVENTS.all_marked_read, - }); handleMarkAllNotificationsAsRead(); }} /> diff --git a/apps/web/core/components/workspace-notifications/sidebar/notification-card/options/archive.tsx b/apps/web/core/components/workspace-notifications/sidebar/notification-card/options/archive.tsx index 61c2f8ac50..3c1c76399a 100644 --- a/apps/web/core/components/workspace-notifications/sidebar/notification-card/options/archive.tsx +++ b/apps/web/core/components/workspace-notifications/sidebar/notification-card/options/archive.tsx @@ -1,14 +1,9 @@ import { observer } from "mobx-react"; import { ArchiveRestore } from "lucide-react"; // plane imports -import { NOTIFICATION_TRACKER_ELEMENTS, NOTIFICATION_TRACKER_EVENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { ArchiveIcon } from "@plane/propel/icons"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; -// helpers -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; -// hooks -import { useWorkspaceNotifications } from "@/hooks/store/notifications"; // store import type { INotification } from "@/store/notifications/notification"; // local imports @@ -24,7 +19,6 @@ export const NotificationItemArchiveOption = observer(function NotificationItemA ) { const { workspaceSlug, notification } = props; // hooks - const { currentNotificationTab } = useWorkspaceNotifications(); const { asJson: data, archiveNotification, unArchiveNotification } = notification; const { t } = useTranslation(); @@ -32,32 +26,17 @@ export const NotificationItemArchiveOption = observer(function NotificationItemA try { const request = data.archived_at ? unArchiveNotification : archiveNotification; await request(workspaceSlug); - captureSuccess({ - eventName: data.archived_at ? NOTIFICATION_TRACKER_EVENTS.unarchive : NOTIFICATION_TRACKER_EVENTS.archive, - payload: { - id: data?.data?.issue?.id, - tab: currentNotificationTab, - }, - }); setToast({ title: data.archived_at ? t("notification.toasts.unarchived") : t("notification.toasts.archived"), type: TOAST_TYPE.SUCCESS, }); } catch (e) { console.error(e); - captureError({ - eventName: data.archived_at ? NOTIFICATION_TRACKER_EVENTS.unarchive : NOTIFICATION_TRACKER_EVENTS.archive, - payload: { - id: data?.data?.issue?.id, - tab: currentNotificationTab, - }, - }); } }; return ( diff --git a/apps/web/core/components/workspace/create-workspace-form.tsx b/apps/web/core/components/workspace/create-workspace-form.tsx index 8b380da8df..2af67c09e9 100644 --- a/apps/web/core/components/workspace/create-workspace-form.tsx +++ b/apps/web/core/components/workspace/create-workspace-form.tsx @@ -2,12 +2,7 @@ import type { Dispatch, SetStateAction } from "react"; import { useEffect, useState } from "react"; import { observer } from "mobx-react"; import { Controller, useForm } from "react-hook-form"; -import { - ORGANIZATION_SIZE, - RESTRICTED_URLS, - WORKSPACE_TRACKER_ELEMENTS, - WORKSPACE_TRACKER_EVENTS, -} from "@plane/constants"; +import { ORGANIZATION_SIZE, RESTRICTED_URLS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { Button } from "@plane/propel/button"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; @@ -15,7 +10,6 @@ import type { IWorkspace } from "@plane/types"; // ui import { CustomSelect, Input } from "@plane/ui"; // hooks -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; import { useWorkspace } from "@/hooks/store/use-workspace"; import { useAppRouter } from "@/hooks/use-app-router"; // services @@ -71,13 +65,8 @@ export const CreateWorkspaceForm = observer(function CreateWorkspaceForm(props: const res = (await workspaceService.workspaceSlugCheck(formData.slug)) as { status: boolean }; if (res.status === true && !RESTRICTED_URLS.includes(formData.slug)) { setSlugError(false); - try { const workspaceResponse = await createWorkspace(formData); - captureSuccess({ - eventName: WORKSPACE_TRACKER_EVENTS.create, - payload: { slug: formData.slug }, - }); setToast({ type: TOAST_TYPE.SUCCESS, title: t("workspace_creation.toast.success.title"), @@ -86,11 +75,6 @@ export const CreateWorkspaceForm = observer(function CreateWorkspaceForm(props: if (onSubmit) await onSubmit(workspaceResponse); } catch { - captureError({ - eventName: WORKSPACE_TRACKER_EVENTS.create, - payload: { slug: formData.slug }, - error: new Error("Error creating workspace"), - }); setToast({ type: TOAST_TYPE.ERROR, title: t("workspace_creation.toast.error.title"), @@ -250,14 +234,7 @@ export const CreateWorkspaceForm = observer(function CreateWorkspaceForm(props:
{secondaryButton} - {!secondaryButton && ( diff --git a/apps/web/core/components/workspace/delete-workspace-form.tsx b/apps/web/core/components/workspace/delete-workspace-form.tsx index 52603caabb..c0041d8ab6 100644 --- a/apps/web/core/components/workspace/delete-workspace-form.tsx +++ b/apps/web/core/components/workspace/delete-workspace-form.tsx @@ -1,18 +1,14 @@ -import React from "react"; import { observer } from "mobx-react"; import { Controller, useForm } from "react-hook-form"; import { AlertTriangle } from "lucide-react"; -// types -import { WORKSPACE_TRACKER_EVENTS } from "@plane/constants"; +// Plane Imports import { useTranslation } from "@plane/i18n"; import { Button } from "@plane/propel/button"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { IWorkspace } from "@plane/types"; -// ui import { Input } from "@plane/ui"; -// hooks import { cn } from "@plane/utils"; -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; +// hooks import { useWorkspace } from "@/hooks/store/use-workspace"; import { useUserSettings } from "@/hooks/store/user"; import { useAppRouter } from "@/hooks/use-app-router"; @@ -59,33 +55,23 @@ export const DeleteWorkspaceForm = observer(function DeleteWorkspaceForm(props: const onSubmit = async () => { if (!data || !canDelete) return; - await deleteWorkspace(data.slug) - .then(async () => { - await fetchCurrentUserSettings(); - handleClose(); - router.push(getWorkspaceRedirectionUrl()); - captureSuccess({ - eventName: WORKSPACE_TRACKER_EVENTS.delete, - payload: { slug: data.slug }, - }); - setToast({ - type: TOAST_TYPE.SUCCESS, - title: t("workspace_settings.settings.general.delete_modal.success_title"), - message: t("workspace_settings.settings.general.delete_modal.success_message"), - }); - }) - .catch(() => { - setToast({ - type: TOAST_TYPE.ERROR, - title: t("workspace_settings.settings.general.delete_modal.error_title"), - message: t("workspace_settings.settings.general.delete_modal.error_message"), - }); - captureError({ - eventName: WORKSPACE_TRACKER_EVENTS.delete, - payload: { slug: data.slug }, - error: new Error("Error deleting workspace"), - }); + try { + await deleteWorkspace(data.slug); + await fetchCurrentUserSettings(); + handleClose(); + router.push(getWorkspaceRedirectionUrl()); + setToast({ + type: TOAST_TYPE.SUCCESS, + title: t("workspace_settings.settings.general.delete_modal.success_title"), + message: t("workspace_settings.settings.general.delete_modal.success_message"), }); + } catch (_error) { + setToast({ + type: TOAST_TYPE.ERROR, + title: t("workspace_settings.settings.general.delete_modal.error_title"), + message: t("workspace_settings.settings.general.delete_modal.error_message"), + }); + } }; return ( diff --git a/apps/web/core/components/workspace/settings/invitations-list-item.tsx b/apps/web/core/components/workspace/settings/invitations-list-item.tsx index 8565436556..12b4cc821f 100644 --- a/apps/web/core/components/workspace/settings/invitations-list-item.tsx +++ b/apps/web/core/components/workspace/settings/invitations-list-item.tsx @@ -1,9 +1,8 @@ import { useState } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; - // plane imports -import { ROLE, EUserPermissions, EUserPermissionsLevel, MEMBER_TRACKER_ELEMENTS } from "@plane/constants"; +import { ROLE, EUserPermissions, EUserPermissionsLevel } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { LinkIcon, TrashIcon, ChevronDownIcon } from "@plane/propel/icons"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; @@ -13,7 +12,6 @@ import { cn, copyTextToClipboard } from "@plane/utils"; // components import { ConfirmWorkspaceMemberRemove } from "@/components/workspace/confirm-workspace-member-remove"; // hooks -import { captureClick } from "@/helpers/event-tracker.helper"; import { useMember } from "@/hooks/store/use-member"; import { useUserPermissions } from "@/hooks/store/user"; @@ -96,9 +94,6 @@ export const WorkspaceInvitationsListItem = observer(function WorkspaceInvitatio { key: "remove", action: () => { - captureClick({ - elementName: MEMBER_TRACKER_ELEMENTS.WORKSPACE_INVITATIONS_LIST_CONTEXT_MENU, - }); setRemoveMemberModal(true); }, title: t("common.remove"), diff --git a/apps/web/core/components/workspace/settings/members-list-item.tsx b/apps/web/core/components/workspace/settings/members-list-item.tsx index 31c41615db..9499110ee5 100644 --- a/apps/web/core/components/workspace/settings/members-list-item.tsx +++ b/apps/web/core/components/workspace/settings/members-list-item.tsx @@ -1,7 +1,6 @@ import { isEmpty } from "lodash-es"; import { observer } from "mobx-react"; // plane imports -import { MEMBER_TRACKER_EVENTS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { IWorkspaceMember } from "@plane/types"; @@ -10,8 +9,6 @@ import { Table } from "@plane/ui"; import { MembersLayoutLoader } from "@/components/ui/loader/layouts/members-layout-loader"; import { ConfirmWorkspaceMemberRemove } from "@/components/workspace/confirm-workspace-member-remove"; import type { RowData } from "@/components/workspace/settings/member-columns"; -// helpers -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; // hooks import { useMember } from "@/hooks/store/use-member"; import { useWorkspace } from "@/hooks/store/use-workspace"; @@ -47,22 +44,8 @@ export const WorkspaceMembersListItem = observer(function WorkspaceMembersListIt await leaveWorkspace(workspaceSlug.toString()); await fetchCurrentUserSettings(); router.push(getWorkspaceRedirectionUrl()); - captureSuccess({ - eventName: MEMBER_TRACKER_EVENTS.workspace.leave, - payload: { - workspace: workspaceSlug, - }, - }); } catch (err: unknown) { const error = err as { error?: string }; - const errorForCapture: Error | string = err instanceof Error ? err : String(err); - captureError({ - eventName: MEMBER_TRACKER_EVENTS.workspace.leave, - payload: { - workspace: workspaceSlug, - }, - error: errorForCapture, - }); setToast({ type: TOAST_TYPE.ERROR, title: "Error!", diff --git a/apps/web/core/components/workspace/settings/workspace-details.tsx b/apps/web/core/components/workspace/settings/workspace-details.tsx index bc13dfbd25..5bcc832d2d 100644 --- a/apps/web/core/components/workspace/settings/workspace-details.tsx +++ b/apps/web/core/components/workspace/settings/workspace-details.tsx @@ -1,15 +1,8 @@ import { useEffect, useState } from "react"; import { observer } from "mobx-react"; import { Controller, useForm } from "react-hook-form"; - -// constants -import { - ORGANIZATION_SIZE, - EUserPermissions, - EUserPermissionsLevel, - WORKSPACE_TRACKER_EVENTS, - WORKSPACE_TRACKER_ELEMENTS, -} from "@plane/constants"; +// Plane Imports +import { ORGANIZATION_SIZE, EUserPermissions, EUserPermissionsLevel } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { Button } from "@plane/propel/button"; import { EditIcon } from "@plane/propel/icons"; @@ -19,9 +12,8 @@ import { CustomSelect, Input } from "@plane/ui"; import { copyUrlToClipboard, getFileURL } from "@plane/utils"; // components import { WorkspaceImageUploadModal } from "@/components/core/modals/workspace-image-upload-modal"; -// helpers import { TimezoneSelect } from "@/components/global/timezone-select"; -import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; +// hooks import { useWorkspace } from "@/hooks/store/use-workspace"; import { useUserPermissions } from "@/hooks/store/user"; // plane web components @@ -70,21 +62,12 @@ export const WorkspaceDetails = observer(function WorkspaceDetails() { try { await updateWorkspace(currentWorkspace.slug, payload); - captureSuccess({ - eventName: WORKSPACE_TRACKER_EVENTS.update, - payload: { slug: currentWorkspace.slug }, - }); setToast({ title: "Success!", type: TOAST_TYPE.SUCCESS, message: "Workspace updated successfully", }); } catch (err: unknown) { - captureError({ - eventName: WORKSPACE_TRACKER_EVENTS.update, - payload: { slug: currentWorkspace.slug }, - error: err instanceof Error ? err : new Error(String(err)), - }); console.error(err); } finally { setTimeout(() => { @@ -305,7 +288,6 @@ export const WorkspaceDetails = observer(function WorkspaceDetails() { {isAdmin && (
)}
diff --git a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/members/page.tsx b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/members/page.tsx index f74d9ca271..d096a17fff 100644 --- a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/members/page.tsx +++ b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/members/page.tsx @@ -40,7 +40,7 @@ const WorkspaceMembersSettingsPage = observer(function WorkspaceMembersSettingsP const { workspace: { workspaceMemberIds, inviteMembersToWorkspace, filtersStore }, } = useMember(); - const { currentWorkspace } = useWorkspace(); + const { currentWorkspace, mutateWorkspaceMembersActivity } = useWorkspace(); const { t } = useTranslation(); // derived values @@ -53,6 +53,7 @@ const WorkspaceMembersSettingsPage = observer(function WorkspaceMembersSettingsP const handleWorkspaceInvite = async (data: IWorkspaceBulkInviteFormData) => { try { await inviteMembersToWorkspace(workspaceSlug, data); + void mutateWorkspaceMembersActivity(workspaceSlug); setInviteModal(false); diff --git a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/projects/[projectId]/layout.tsx b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/projects/[projectId]/layout.tsx index 2128bd2f2e..8e8c09064d 100644 --- a/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/projects/[projectId]/layout.tsx +++ b/apps/web/app/(all)/[workspaceSlug]/(settings)/settings/projects/[projectId]/layout.tsx @@ -7,13 +7,10 @@ import { SettingsMobileNav } from "@/components/settings/mobile"; import { ProjectSettingsSidebar } from "@/components/settings/project/sidebar"; // plane web imports import { ProjectAuthWrapper } from "@/plane-web/layouts/project-wrapper"; -import { SettingsRightSidebar } from "@/plane-web/components/settings/right-sidebar"; // types import type { Route } from "./+types/layout"; -export const ProjectDetailSettingsLayout = observer(function ProjectDetailSettingsLayout({ - params, -}: Route.ComponentProps) { +function ProjectDetailSettingsLayout({ params }: Route.ComponentProps) { const { workspaceSlug, projectId } = params; // router const pathname = usePathname(); @@ -27,11 +24,10 @@ export const ProjectDetailSettingsLayout = observer(function ProjectDetailSettin
-
); -}); +} -export default ProjectDetailSettingsLayout; +export default observer(ProjectDetailSettingsLayout); diff --git a/apps/web/ce/components/projects/members/members-activity-button.tsx b/apps/web/ce/components/projects/members/members-activity-button.tsx deleted file mode 100644 index 169d47a939..0000000000 --- a/apps/web/ce/components/projects/members/members-activity-button.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { observer } from "mobx-react"; - -type TProjectMembersActivityButtonProps = { workspaceSlug: string; projectId: string }; - -export const ProjectMembersActivityButton = observer(function ProjectMembersActivityButton( - // eslint-disable-next-line @typescript-eslint/no-unused-vars - props: TProjectMembersActivityButtonProps -) { - return <>; -}); diff --git a/apps/web/ce/components/settings/right-sidebar.tsx b/apps/web/ce/components/settings/right-sidebar.tsx deleted file mode 100644 index 887da2f8e3..0000000000 --- a/apps/web/ce/components/settings/right-sidebar.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { observer } from "mobx-react"; - -type TSettingsRightSidebarProps = { workspaceSlug: string; projectId?: string }; - -export const SettingsRightSidebar = observer(function SettingsRightSidebar( - // eslint-disable-next-line @typescript-eslint/no-unused-vars - props: TSettingsRightSidebarProps -) { - return <>; -}); diff --git a/apps/web/ce/components/workspace/right-sidebar/index.ts b/apps/web/ce/components/workspace/right-sidebar/index.ts new file mode 100644 index 0000000000..1efe34c51e --- /dev/null +++ b/apps/web/ce/components/workspace/right-sidebar/index.ts @@ -0,0 +1 @@ +export * from "./root"; diff --git a/apps/web/ce/components/workspace/right-sidebar/root.tsx b/apps/web/ce/components/workspace/right-sidebar/root.tsx new file mode 100644 index 0000000000..c98bb682a5 --- /dev/null +++ b/apps/web/ce/components/workspace/right-sidebar/root.tsx @@ -0,0 +1,10 @@ +import { observer } from "mobx-react"; + +type TWorkspaceSettingsRightSidebarProps = { workspaceSlug: string }; + +export const WorkspaceSettingsRightSidebar = observer(function WorkspaceSettingsRightSidebar( + // eslint-disable-next-line @typescript-eslint/no-unused-vars + props: TWorkspaceSettingsRightSidebarProps +) { + return <>; +}); diff --git a/apps/web/ce/store/member/project-member.store.ts b/apps/web/ce/store/member/project-member.store.ts index 1be3ee1c1c..f0e5b3069d 100644 --- a/apps/web/ce/store/member/project-member.store.ts +++ b/apps/web/ce/store/member/project-member.store.ts @@ -41,13 +41,4 @@ export class ProjectMemberStore extends BaseProjectMemberStore implements IProje * @param userId - The ID of the user to remove from the project */ processMemberRemoval = (projectId: string, userId: string) => this.handleMemberRemoval(projectId, userId); - - /** - * @description Mutate project members activity - * @param workspaceSlug - * @param projectId - */ - mutateProjectMembersActivity = async (_workspaceSlug: string, _projectId: string) => { - // No-op in default/CE version - }; } diff --git a/apps/web/core/components/project/member-list.tsx b/apps/web/core/components/project/member-list.tsx index acc32265f2..5dbe78d72e 100644 --- a/apps/web/core/components/project/member-list.tsx +++ b/apps/web/core/components/project/member-list.tsx @@ -14,8 +14,6 @@ import { useUserPermissions } from "@/hooks/store/user"; import { MemberListFiltersDropdown } from "./dropdowns/filters/member-list"; import { ProjectMemberListItem } from "./member-list-item"; import { SendProjectInvitationModal } from "./send-project-invitation-modal"; -// plane web components -import { ProjectMembersActivityButton } from "@/plane-web/components/projects/members/members-activity-button"; type TProjectMemberListProps = { projectId: string; @@ -86,7 +84,6 @@ export const ProjectMemberList = observer(function ProjectMemberList(props: TPro className="w-full max-w-[234px] border-none bg-transparent text-13 focus:outline-none placeholder:text-placeholder" placeholder="Search" value={searchQuery} - // eslint-disable-next-line jsx-a11y/no-autofocus autoFocus onChange={(e) => setSearchQuery(e.target.value)} /> @@ -96,11 +93,9 @@ export const ProjectMemberList = observer(function ProjectMemberList(props: TPro handleUpdate={handleRoleFilterUpdate} memberType="project" /> - {isAdmin && } {isAdmin && ( )} diff --git a/apps/web/ce/components/workspace/right-sidebar/index.ts b/apps/web/ce/components/workspace/right-sidebar/index.ts deleted file mode 100644 index 1efe34c51e..0000000000 --- a/apps/web/ce/components/workspace/right-sidebar/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./root"; diff --git a/apps/web/ce/components/workspace/right-sidebar/root.tsx b/apps/web/ce/components/workspace/right-sidebar/root.tsx deleted file mode 100644 index c98bb682a5..0000000000 --- a/apps/web/ce/components/workspace/right-sidebar/root.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { observer } from "mobx-react"; - -type TWorkspaceSettingsRightSidebarProps = { workspaceSlug: string }; - -export const WorkspaceSettingsRightSidebar = observer(function WorkspaceSettingsRightSidebar( - // eslint-disable-next-line @typescript-eslint/no-unused-vars - props: TWorkspaceSettingsRightSidebarProps -) { - return <>; -}); diff --git a/apps/web/core/components/workspace/settings/invitations-list-item.tsx b/apps/web/core/components/workspace/settings/invitations-list-item.tsx index 20ea3d7a9c..12b4cc821f 100644 --- a/apps/web/core/components/workspace/settings/invitations-list-item.tsx +++ b/apps/web/core/components/workspace/settings/invitations-list-item.tsx @@ -14,7 +14,6 @@ import { ConfirmWorkspaceMemberRemove } from "@/components/workspace/confirm-wor // hooks import { useMember } from "@/hooks/store/use-member"; import { useUserPermissions } from "@/hooks/store/user"; -import { useWorkspace } from "@/hooks/store/use-workspace"; type Props = { invitationId: string; @@ -30,7 +29,6 @@ export const WorkspaceInvitationsListItem = observer(function WorkspaceInvitatio const { t } = useTranslation(); // store hooks const { allowPermissions, workspaceInfoBySlug } = useUserPermissions(); - const { mutateWorkspaceMembersActivity } = useWorkspace(); const { workspace: { updateMemberInvitation, deleteMemberInvitation, getWorkspaceInvitationDetails }, } = useMember(); @@ -59,7 +57,6 @@ export const WorkspaceInvitationsListItem = observer(function WorkspaceInvitatio title: "Success!", message: "Invitation removed successfully.", }); - void mutateWorkspaceMembersActivity(workspaceSlug); } catch (err: unknown) { const error = err as { error?: string }; setToast({ diff --git a/apps/web/core/components/workspace/settings/member-columns.tsx b/apps/web/core/components/workspace/settings/member-columns.tsx index b98438b1d4..4167a79397 100644 --- a/apps/web/core/components/workspace/settings/member-columns.tsx +++ b/apps/web/core/components/workspace/settings/member-columns.tsx @@ -16,8 +16,6 @@ import { getFileURL } from "@plane/utils"; // hooks import { useMember } from "@/hooks/store/use-member"; import { useUser, useUserPermissions } from "@/hooks/store/user"; -import { useWorkspace } from "@/hooks/store/use-workspace"; -// plane web constants export interface RowData { member: IWorkspaceMember; @@ -121,7 +119,6 @@ export const AccountTypeColumn = observer(function AccountTypeColumn(props: Acco const { workspace: { updateMember }, } = useMember(); - const { mutateWorkspaceMembersActivity } = useWorkspace(); const { data: currentUser } = useUser(); // derived values @@ -156,7 +153,6 @@ export const AccountTypeColumn = observer(function AccountTypeColumn(props: Acco await updateMember(workspaceSlug.toString(), rowData.member.id, { role: value as unknown as EUserPermissions, }); - void mutateWorkspaceMembersActivity(workspaceSlug); } catch (err: unknown) { const error = err as { error?: string | string[] }; const errorString = Array.isArray(error?.error) ? error.error[0] : error?.error; diff --git a/apps/web/core/components/workspace/settings/members-list-item.tsx b/apps/web/core/components/workspace/settings/members-list-item.tsx index 4f0b20dc5d..9499110ee5 100644 --- a/apps/web/core/components/workspace/settings/members-list-item.tsx +++ b/apps/web/core/components/workspace/settings/members-list-item.tsx @@ -32,7 +32,7 @@ export const WorkspaceMembersListItem = observer(function WorkspaceMembersListIt workspace: { removeMemberFromWorkspace }, } = useMember(); const { leaveWorkspace } = useUserPermissions(); - const { getWorkspaceRedirectionUrl, mutateWorkspaceMembersActivity } = useWorkspace(); + const { getWorkspaceRedirectionUrl } = useWorkspace(); const { fetchCurrentUserSettings } = useUserSettings(); const { t } = useTranslation(); // derived values @@ -59,7 +59,6 @@ export const WorkspaceMembersListItem = observer(function WorkspaceMembersListIt try { await removeMemberFromWorkspace(workspaceSlug.toString(), memberId); - void mutateWorkspaceMembersActivity(workspaceSlug); } catch (err: unknown) { const error = err as { error?: string }; setToast({ diff --git a/apps/web/core/store/member/workspace/workspace-member.store.ts b/apps/web/core/store/member/workspace/workspace-member.store.ts index edf9d2a297..ad0df64fcf 100644 --- a/apps/web/core/store/member/workspace/workspace-member.store.ts +++ b/apps/web/core/store/member/workspace/workspace-member.store.ts @@ -11,10 +11,10 @@ import { WorkspaceService } from "@/plane-web/services"; import type { IRouterStore } from "@/store/router.store"; import type { IUserStore } from "@/store/user"; // store -import type { CoreRootStore } from "../../root.store"; import type { IMemberRootStore } from "../index.ts"; import type { IWorkspaceMemberFiltersStore } from "./workspace-member-filters.store"; import { WorkspaceMemberFiltersStore } from "./workspace-member-filters.store"; +import type { RootStore } from "@/plane-web/store/root.store"; export interface IWorkspaceMembership { id: string; @@ -72,7 +72,7 @@ export class WorkspaceMemberStore implements IWorkspaceMemberStore { // services workspaceService; - constructor(_memberRoot: IMemberRootStore, _rootStore: CoreRootStore) { + constructor(_memberRoot: IMemberRootStore, _rootStore: RootStore) { makeObservable(this, { // observables workspaceMemberMap: observable,