From 6595a387d0960d1546b4bdd7f1f20edb338764d3 Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Mon, 20 Nov 2023 13:29:54 +0530 Subject: [PATCH] feat: event tracking using posthog and created application provider to render multiple wrappers (#2757) * fix: event tracker changes * fix: App provider implementation using wrappers * fix: updating packages * fix: handling warning * fix: wrapper fixes and minor optimization changes * fix: chore app-provider clearnup * fix: cleanup * fix: removing jitsu tracking * fix: minor updates * fix: adding event to posthog event tracker (#2802) * dev: posthog event tracker update intitiate * fix: adding events for posthog integration * fix: event payload --------- Co-authored-by: Ramesh Kumar Chandra <31303617+rameshkumarchandra@users.noreply.github.com> --- packages/ui/package.json | 9 +- turbo.json | 7 +- .../custom-analytics/sidebar/sidebar.tsx | 14 - .../analytics/project-modal/main-content.tsx | 66 +- .../command-palette/command-modal.tsx | 4 +- .../issue/change-issue-assignee.tsx | 6 +- .../issue/change-issue-priority.tsx | 9 +- .../issue/change-issue-state.tsx | 6 +- .../core/modals/bulk-delete-issues-modal.tsx | 13 +- .../core/modals/gpt-assistant-modal.tsx | 35 +- .../cycles/gantt-chart/cycles-list-layout.tsx | 4 +- web/components/cycles/sidebar.tsx | 5 +- web/components/exporter/export-modal.tsx | 2 +- web/components/inbox/issue-activity.tsx | 6 +- .../integration/delete-import-modal.tsx | 4 +- web/components/integration/github/root.tsx | 4 +- web/components/integration/jira/root.tsx | 4 +- web/components/issues/draft-issue-form.tsx | 13 +- web/components/issues/draft-issue-modal.tsx | 26 +- web/components/issues/form.tsx | 13 +- .../kanban/headers/group-by-card.tsx | 8 +- .../list/headers/group-by-card.tsx | 8 +- web/components/issues/main-content.tsx | 6 +- .../issues/peek-overview/issue-activity.tsx | 8 +- .../issues/sidebar-select/blocked.tsx | 5 +- .../issues/sidebar-select/blocker.tsx | 5 +- .../issues/sidebar-select/duplicate.tsx | 5 +- .../issues/sidebar-select/label.tsx | 6 +- .../issues/sidebar-select/relates-to.tsx | 5 +- web/components/issues/sidebar.tsx | 24 +- .../issues/sub-issues/properties.tsx | 41 +- web/components/issues/sub-issues/root.tsx | 2 +- web/components/modules/sidebar.tsx | 3 +- web/components/onboarding/invite-members.tsx | 4 +- web/components/onboarding/join-workspaces.tsx | 12 +- web/components/pages/create-block.tsx | 14 +- .../pages/create-update-block-inline.tsx | 75 +- .../pages/create-update-page-modal.tsx | 39 +- web/components/pages/delete-page-modal.tsx | 4 +- web/components/pages/pages-view.tsx | 2 +- web/components/pages/single-page-block.tsx | 63 +- .../project/create-project-modal.tsx | 12 +- .../project/delete-project-modal.tsx | 7 + web/components/project/form.tsx | 10 +- .../project/send-project-invitation-modal.tsx | 10 +- .../project/settings/features-list.tsx | 33 - .../states/create-update-state-inline.tsx | 19 +- web/components/states/delete-state-modal.tsx | 6 +- .../workspace/create-workspace-form.tsx | 12 + .../workspace/delete-workspace-modal.tsx | 13 +- .../workspace/settings/workspace-details.tsx | 10 +- web/constants/crisp.tsx | 45 - web/contexts/issue-view.context.tsx | 119 +-- web/helpers/event-tracker.helper.ts | 13 + web/helpers/user.helper.ts | 12 + web/hooks/use-comment-reaction.tsx | 7 +- web/hooks/use-issue-reaction.tsx | 6 +- web/lib/app-provider.tsx | 46 + web/lib/auth.ts | 195 ---- web/lib/cookie.ts | 16 - web/lib/wrappers/crisp-wrapper.tsx | 40 + web/lib/wrappers/posthog-wrapper.tsx | 72 ++ .../store-wrapper.tsx} | 13 +- web/package.json | 1 + web/pages/[workspaceSlug]/analytics.tsx | 34 +- .../archived-issues/[archivedIssueId].tsx | 6 +- .../projects/[projectId]/cycles/index.tsx | 1 + .../projects/[projectId]/issues/[issueId].tsx | 8 +- .../projects/[projectId]/pages/[pageId].tsx | 43 +- .../[workspaceSlug]/settings/members.tsx | 11 +- web/pages/_app.tsx | 17 +- web/pages/api/track-event.ts | 34 - web/pages/api/unsplash.ts | 26 - web/pages/workspace-invitations/index.tsx | 13 +- web/services/ai.service.ts | 13 +- web/services/cycle.service.ts | 32 +- web/services/inbox.service.ts | 50 +- web/services/integrations/github.service.ts | 16 +- .../integrations/integration.service.ts | 18 +- web/services/integrations/jira.service.ts | 16 +- web/services/issue/issue.service.ts | 78 +- web/services/issue/issue_comment.service.ts | 41 +- web/services/issue/issue_label.service.ts | 75 +- web/services/issue/issue_reaction.service.ts | 42 +- web/services/module.service.ts | 60 +- web/services/page.service.ts | 74 +- .../project/project-estimate.service.ts | 37 +- .../project/project-export.service.ts | 19 +- .../project/project-member.service.ts | 27 +- web/services/project/project-state.service.ts | 45 +- web/services/project/project.service.ts | 39 +- web/services/track_event.service.ts | 850 ------------------ web/services/user.service.ts | 22 +- web/services/view.service.ts | 30 +- web/services/workspace.service.ts | 47 +- web/store/cycle/cycle_issue.store.ts | 14 +- web/store/cycle/cycle_issue_filters.store.ts | 4 +- web/store/cycle/cycles.store.ts | 11 +- web/store/inbox/inbox_issue_detail.store.ts | 34 +- web/store/issue/issue_detail.store.ts | 23 +- web/store/issue/issue_quick_add.store.ts | 7 +- web/store/module/module_filters.store.ts | 16 +- web/store/module/module_issue.store.ts | 14 +- web/store/module/modules.store.ts | 13 +- web/store/project-view/project_views.store.ts | 17 +- web/store/project/project-estimates.store.ts | 17 +- web/store/project/project-label.store.ts | 22 +- web/store/project/project-state.store.ts | 28 +- web/store/project/project.store.ts | 13 +- web/store/user.store.ts | 4 +- web/store/workspace/workspace-member.store.ts | 4 +- web/store/workspace/workspace.store.ts | 12 +- web/types/app.d.ts | 2 + yarn.lock | 208 +++-- 114 files changed, 825 insertions(+), 2768 deletions(-) delete mode 100644 web/constants/crisp.tsx create mode 100644 web/helpers/event-tracker.helper.ts create mode 100644 web/helpers/user.helper.ts create mode 100644 web/lib/app-provider.tsx delete mode 100644 web/lib/auth.ts delete mode 100644 web/lib/cookie.ts create mode 100644 web/lib/wrappers/crisp-wrapper.tsx create mode 100644 web/lib/wrappers/posthog-wrapper.tsx rename web/lib/{mobx/store-init.tsx => wrappers/store-wrapper.tsx} (91%) delete mode 100644 web/pages/api/track-event.ts delete mode 100644 web/pages/api/unsplash.ts delete mode 100644 web/services/track_event.service.ts diff --git a/packages/ui/package.json b/packages/ui/package.json index 72413eb7c..58b014553 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -18,10 +18,10 @@ "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist" }, "devDependencies": { - "@types/react-color": "^3.0.9", "@types/node": "^20.5.2", - "@types/react": "18.2.0", - "@types/react-dom": "18.2.0", + "@types/react": "^18.2.37", + "@types/react-color": "^3.0.9", + "@types/react-dom": "^18.2.15", "classnames": "^2.3.2", "eslint-config-custom": "*", "react": "^18.2.0", @@ -30,9 +30,6 @@ "tsup": "^5.10.1", "typescript": "4.7.4" }, - "publishConfig": { - "access": "public" - }, "dependencies": { "@blueprintjs/core": "^4.16.3", "@blueprintjs/popover2": "^1.13.3", diff --git a/turbo.json b/turbo.json index ac462d08b..454e09f14 100644 --- a/turbo.json +++ b/turbo.json @@ -1,6 +1,7 @@ { "$schema": "https://turbo.build/schema.json", "globalEnv": [ + "NODE_ENV", "NEXT_PUBLIC_API_BASE_URL", "NEXT_PUBLIC_DEPLOY_URL", "NEXT_PUBLIC_SENTRY_DSN", @@ -16,12 +17,8 @@ "NEXT_PUBLIC_DEPLOY_WITH_NGINX", "NEXT_PUBLIC_POSTHOG_KEY", "NEXT_PUBLIC_POSTHOG_HOST", - "SLACK_OAUTH_URL", - "SLACK_CLIENT_ID", - "SLACK_CLIENT_SECRET", "JITSU_TRACKER_ACCESS_KEY", - "JITSU_TRACKER_HOST", - "UNSPLASH_ACCESS_KEY" + "JITSU_TRACKER_HOST" ], "pipeline": { "build": { diff --git a/web/components/analytics/custom-analytics/sidebar/sidebar.tsx b/web/components/analytics/custom-analytics/sidebar/sidebar.tsx index c99a7cece..240baf31b 100644 --- a/web/components/analytics/custom-analytics/sidebar/sidebar.tsx +++ b/web/components/analytics/custom-analytics/sidebar/sidebar.tsx @@ -4,7 +4,6 @@ import { observer } from "mobx-react-lite"; import { mutate } from "swr"; // services import { AnalyticsService } from "services/analytics.service"; -import { TrackEventService } from "services/track_event.service"; // hooks import useToast from "hooks/use-toast"; import { useMobxStore } from "lib/mobx/store-provider"; @@ -29,7 +28,6 @@ type Props = { }; const analyticsService = new AnalyticsService(); -const trackEventService = new TrackEventService(); export const CustomAnalyticsSidebar: React.FC = observer( ({ analytics, params, fullScreen, isProjectLevel = false }) => { @@ -90,18 +88,6 @@ export const CustomAnalyticsSidebar: React.FC = observer( eventPayload.moduleId = moduleDetails.id; eventPayload.moduleName = moduleDetails.name; } - - trackEventService.trackAnalyticsEvent( - eventPayload, - cycleId - ? "CYCLE_ANALYTICS_EXPORT" - : moduleId - ? "MODULE_ANALYTICS_EXPORT" - : projectId - ? "PROJECT_ANALYTICS_EXPORT" - : "WORKSPACE_ANALYTICS_EXPORT", - user - ); }; const exportAnalytics = () => { diff --git a/web/components/analytics/project-modal/main-content.tsx b/web/components/analytics/project-modal/main-content.tsx index bdab57392..55ed1d403 100644 --- a/web/components/analytics/project-modal/main-content.tsx +++ b/web/components/analytics/project-modal/main-content.tsx @@ -1,15 +1,10 @@ import React from "react"; -import { useRouter } from "next/router"; import { observer } from "mobx-react-lite"; import { Tab } from "@headlessui/react"; -// mobx store -import { useMobxStore } from "lib/mobx/store-provider"; -// services -import { TrackEventService } from "services/track_event.service"; // components import { CustomAnalytics, ScopeAndDemand } from "components/analytics"; // types -import { ICycle, IModule, IProject, IWorkspace } from "types"; +import { ICycle, IModule, IProject } from "types"; // constants import { ANALYTICS_TABS } from "constants/analytics"; @@ -20,63 +15,8 @@ type Props = { projectDetails: IProject | undefined; }; -const trackEventService = new TrackEventService(); - export const ProjectAnalyticsModalMainContent: React.FC = observer((props) => { - const { fullScreen, cycleDetails, moduleDetails, projectDetails } = props; - - const router = useRouter(); - const { workspaceSlug } = router.query; - - const { user: userStore } = useMobxStore(); - - const user = userStore.currentUser; - - const trackAnalyticsEvent = (tab: string) => { - if (!workspaceSlug || !user) return; - - const eventPayload: any = { - workspaceSlug: workspaceSlug.toString(), - }; - - if (projectDetails) { - const workspaceDetails = projectDetails.workspace as IWorkspace; - - eventPayload.workspaceId = workspaceDetails.id; - eventPayload.workspaceName = workspaceDetails.name; - eventPayload.projectId = projectDetails.id; - eventPayload.projectIdentifier = projectDetails.identifier; - eventPayload.projectName = projectDetails.name; - } - - if (cycleDetails || moduleDetails) { - const details = cycleDetails || moduleDetails; - - eventPayload.workspaceId = details?.workspace_detail?.id; - eventPayload.workspaceName = details?.workspace_detail?.name; - eventPayload.projectId = details?.project_detail.id; - eventPayload.projectIdentifier = details?.project_detail.identifier; - eventPayload.projectName = details?.project_detail.name; - } - - if (cycleDetails) { - eventPayload.cycleId = cycleDetails.id; - eventPayload.cycleName = cycleDetails.name; - } - - if (moduleDetails) { - eventPayload.moduleId = moduleDetails.id; - eventPayload.moduleName = moduleDetails.name; - } - - const eventType = tab === "scope_and_demand" ? "SCOPE_AND_DEMAND_ANALYTICS" : "CUSTOM_ANALYTICS"; - - trackEventService.trackAnalyticsEvent( - eventPayload, - cycleDetails ? `CYCLE_${eventType}` : moduleDetails ? `MODULE_${eventType}` : `PROJECT_${eventType}`, - user - ); - }; + const { fullScreen, cycleDetails, moduleDetails } = props; return ( @@ -89,7 +29,7 @@ export const ProjectAnalyticsModalMainContent: React.FC = observer((props selected ? "bg-custom-background-80" : "" }` } - onClick={() => trackAnalyticsEvent(tab.key)} + onClick={() => {}} > {tab.title} diff --git a/web/components/command-palette/command-modal.tsx b/web/components/command-palette/command-modal.tsx index 04625f77a..bd066326d 100644 --- a/web/components/command-palette/command-modal.tsx +++ b/web/components/command-palette/command-modal.tsx @@ -125,7 +125,7 @@ export const CommandModal: React.FC = observer((props) => { const payload = { ...formData }; await issueService - .patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload, user) + .patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload) .then(() => { mutate(PROJECT_ISSUES_ACTIVITY(issueId as string)); mutate(ISSUE_DETAILS(issueId as string)); @@ -134,7 +134,7 @@ export const CommandModal: React.FC = observer((props) => { console.error(e); }); }, - [workspaceSlug, issueId, projectId, user] + [workspaceSlug, issueId, projectId] ); const handleIssueAssignees = (assignee: string) => { diff --git a/web/components/command-palette/issue/change-issue-assignee.tsx b/web/components/command-palette/issue/change-issue-assignee.tsx index 512428310..1693a6b94 100644 --- a/web/components/command-palette/issue/change-issue-assignee.tsx +++ b/web/components/command-palette/issue/change-issue-assignee.tsx @@ -25,7 +25,7 @@ type Props = { const issueService = new IssueService(); export const ChangeIssueAssignee: FC = observer((props) => { - const { setIsPaletteOpen, issue, user } = props; + const { setIsPaletteOpen, issue } = props; // router const router = useRouter(); const { workspaceSlug, projectId, issueId } = router.query; @@ -71,7 +71,7 @@ export const ChangeIssueAssignee: FC = observer((props) => { const payload = { ...formData }; await issueService - .patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload, user) + .patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload) .then(() => { mutate(PROJECT_ISSUES_ACTIVITY(issueId as string)); }) @@ -79,7 +79,7 @@ export const ChangeIssueAssignee: FC = observer((props) => { console.error(e); }); }, - [workspaceSlug, issueId, projectId, user] + [workspaceSlug, issueId, projectId] ); const handleIssueAssignees = (assignee: string) => { diff --git a/web/components/command-palette/issue/change-issue-priority.tsx b/web/components/command-palette/issue/change-issue-priority.tsx index 5551a8a3a..c5e4bfa2a 100644 --- a/web/components/command-palette/issue/change-issue-priority.tsx +++ b/web/components/command-palette/issue/change-issue-priority.tsx @@ -1,9 +1,6 @@ import React, { Dispatch, SetStateAction, useCallback } from "react"; - import { useRouter } from "next/router"; - import { mutate } from "swr"; - // cmdk import { Command } from "cmdk"; // services @@ -26,7 +23,7 @@ type Props = { // services const issueService = new IssueService(); -export const ChangeIssuePriority: React.FC = ({ setIsPaletteOpen, issue, user }) => { +export const ChangeIssuePriority: React.FC = ({ setIsPaletteOpen, issue }) => { const router = useRouter(); const { workspaceSlug, projectId, issueId } = router.query; @@ -49,7 +46,7 @@ export const ChangeIssuePriority: React.FC = ({ setIsPaletteOpen, issue, const payload = { ...formData }; await issueService - .patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload, user) + .patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload) .then(() => { mutate(PROJECT_ISSUES_ACTIVITY(issueId as string)); }) @@ -57,7 +54,7 @@ export const ChangeIssuePriority: React.FC = ({ setIsPaletteOpen, issue, console.error(e); }); }, - [workspaceSlug, issueId, projectId, user] + [workspaceSlug, issueId, projectId] ); const handleIssueState = (priority: TIssuePriorities) => { diff --git a/web/components/command-palette/issue/change-issue-state.tsx b/web/components/command-palette/issue/change-issue-state.tsx index 688aeb49f..cbddfb688 100644 --- a/web/components/command-palette/issue/change-issue-state.tsx +++ b/web/components/command-palette/issue/change-issue-state.tsx @@ -25,7 +25,7 @@ type Props = { const issueService = new IssueService(); const stateService = new ProjectStateService(); -export const ChangeIssueState: React.FC = ({ setIsPaletteOpen, issue, user }) => { +export const ChangeIssueState: React.FC = ({ setIsPaletteOpen, issue }) => { const router = useRouter(); const { workspaceSlug, projectId, issueId } = router.query; @@ -52,7 +52,7 @@ export const ChangeIssueState: React.FC = ({ setIsPaletteOpen, issue, use const payload = { ...formData }; await issueService - .patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload, user) + .patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload) .then(() => { mutateStates(); mutate(PROJECT_ISSUES_ACTIVITY(issueId as string)); @@ -61,7 +61,7 @@ export const ChangeIssueState: React.FC = ({ setIsPaletteOpen, issue, use console.error(e); }); }, - [workspaceSlug, issueId, projectId, mutateStates, user] + [workspaceSlug, issueId, projectId, mutateStates] ); const handleIssueState = (stateId: string) => { diff --git a/web/components/core/modals/bulk-delete-issues-modal.tsx b/web/components/core/modals/bulk-delete-issues-modal.tsx index f1c951385..a70a722a2 100644 --- a/web/components/core/modals/bulk-delete-issues-modal.tsx +++ b/web/components/core/modals/bulk-delete-issues-modal.tsx @@ -31,7 +31,7 @@ type Props = { const issueService = new IssueService(); export const BulkDeleteIssuesModal: React.FC = (props) => { - const { isOpen, onClose, user } = props; + const { isOpen, onClose } = props; // router const router = useRouter(); const { workspaceSlug, projectId } = router.query; @@ -78,14 +78,9 @@ export const BulkDeleteIssuesModal: React.FC = (props) => { if (!Array.isArray(data.delete_issue_ids)) data.delete_issue_ids = [data.delete_issue_ids]; await issueService - .bulkDeleteIssues( - workspaceSlug as string, - projectId as string, - { - issue_ids: data.delete_issue_ids, - }, - user - ) + .bulkDeleteIssues(workspaceSlug as string, projectId as string, { + issue_ids: data.delete_issue_ids, + }) .then(() => { setToastAlert({ type: "success", diff --git a/web/components/core/modals/gpt-assistant-modal.tsx b/web/components/core/modals/gpt-assistant-modal.tsx index b98b1bc1c..d677e7daa 100644 --- a/web/components/core/modals/gpt-assistant-modal.tsx +++ b/web/components/core/modals/gpt-assistant-modal.tsx @@ -4,10 +4,8 @@ import { useRouter } from "next/router"; import { Controller, useForm } from "react-hook-form"; // services import { AIService } from "services/ai.service"; -import { TrackEventService } from "services/track_event.service"; // hooks import useToast from "hooks/use-toast"; -import useUserAuth from "hooks/use-user-auth"; // ui import { Button, Input } from "@plane/ui"; // components @@ -34,27 +32,15 @@ type FormData = { // services const aiService = new AIService(); -const trackEventService = new TrackEventService(); -export const GptAssistantModal: React.FC = ({ - isOpen, - handleClose, - inset = "top-0 left-0", - content, - htmlContent, - onResponse, - projectId, - block, - issue, -}) => { +export const GptAssistantModal: React.FC = (props) => { + const { isOpen, handleClose, inset = "top-0 left-0", content, htmlContent, onResponse, projectId } = props; const [response, setResponse] = useState(""); const [invalidResponse, setInvalidResponse] = useState(false); const router = useRouter(); const { workspaceSlug } = router.query; - const { user } = useUserAuth(); - const editorRef = useRef(null); const { setToastAlert } = useToast(); @@ -92,15 +78,10 @@ export const GptAssistantModal: React.FC = ({ } await aiService - .createGptTask( - workspaceSlug as string, - projectId as string, - { - prompt: content && content !== "" ? content : htmlContent ?? "", - task: formData.task, - }, - user - ) + .createGptTask(workspaceSlug as string, projectId as string, { + prompt: content && content !== "" ? content : htmlContent ?? "", + task: formData.task, + }) .then((res) => { setResponse(res.response_html); setFocus("task"); @@ -193,10 +174,6 @@ export const GptAssistantModal: React.FC = ({ onClick={() => { onResponse(response); onClose(); - if (block && user) - trackEventService.trackUseGPTResponseEvent(block, "USE_GPT_RESPONSE_IN_PAGE_BLOCK", user); - else if (issue && user) - trackEventService.trackUseGPTResponseEvent(issue, "USE_GPT_RESPONSE_IN_ISSUE", user); }} > Use this response diff --git a/web/components/cycles/gantt-chart/cycles-list-layout.tsx b/web/components/cycles/gantt-chart/cycles-list-layout.tsx index d5bd4e140..6a605536b 100644 --- a/web/components/cycles/gantt-chart/cycles-list-layout.tsx +++ b/web/components/cycles/gantt-chart/cycles-list-layout.tsx @@ -11,7 +11,7 @@ import useUser from "hooks/use-user"; import useProjectDetails from "hooks/use-project-details"; // components import { GanttChartRoot, IBlockUpdateData, CycleGanttSidebar } from "components/gantt-chart"; -import { CycleGanttBlock, CycleGanttSidebarBlock } from "components/cycles"; +import { CycleGanttBlock } from "components/cycles"; // types import { ICycle } from "types"; @@ -60,7 +60,7 @@ export const CyclesListGanttChartView: FC = ({ cycles, mutateCycles }) => if (newPayload.sort_order && payload.sort_order) newPayload.sort_order = payload.sort_order.newSortOrder; - cycleService.patchCycle(workspaceSlug.toString(), cycle.project, cycle.id, newPayload, user); + cycleService.patchCycle(workspaceSlug.toString(), cycle.project, cycle.id, newPayload); }; const blockFormat = (blocks: ICycle[]) => diff --git a/web/components/cycles/sidebar.tsx b/web/components/cycles/sidebar.tsx index 3288dfe0b..17e3c0d19 100644 --- a/web/components/cycles/sidebar.tsx +++ b/web/components/cycles/sidebar.tsx @@ -52,9 +52,8 @@ export const CycleDetailsSidebar: React.FC = observer((props) => { const router = useRouter(); const { workspaceSlug, projectId, peekCycle } = router.query; - const { user: userStore, cycle: cycleDetailsStore } = useMobxStore(); + const { cycle: cycleDetailsStore } = useMobxStore(); - const user = userStore.currentUser ?? undefined; const cycleDetails = cycleDetailsStore.cycle_details[cycleId] ?? undefined; const { setToastAlert } = useToast(); @@ -74,7 +73,7 @@ export const CycleDetailsSidebar: React.FC = observer((props) => { mutate(CYCLE_DETAILS(cycleId as string), (prevData) => ({ ...(prevData as ICycle), ...data }), false); cycleService - .patchCycle(workspaceSlug as string, projectId as string, cycleId as string, data, user) + .patchCycle(workspaceSlug as string, projectId as string, cycleId as string, data) .then(() => mutate(CYCLE_DETAILS(cycleId as string))) .catch((e) => console.log(e)); }; diff --git a/web/components/exporter/export-modal.tsx b/web/components/exporter/export-modal.tsx index 4cf99e0ce..2fe509071 100644 --- a/web/components/exporter/export-modal.tsx +++ b/web/components/exporter/export-modal.tsx @@ -63,7 +63,7 @@ export const Exporter: React.FC = observer((props) => { multiple: multiple, }; await projectExportService - .csvExport(workspaceSlug as string, payload, user) + .csvExport(workspaceSlug as string, payload) .then(() => { mutateServices(); router.push(`/${workspaceSlug}/settings/exports`); diff --git a/web/components/inbox/issue-activity.tsx b/web/components/inbox/issue-activity.tsx index 61102f865..d8d68313b 100644 --- a/web/components/inbox/issue-activity.tsx +++ b/web/components/inbox/issue-activity.tsx @@ -41,7 +41,7 @@ export const InboxIssueActivity: React.FC = observer(({ issueDetails }) = if (!workspaceSlug || !projectId || !inboxIssueId || !user) return; await issueCommentService - .patchIssueComment(workspaceSlug as string, projectId as string, inboxIssueId as string, commentId, data, user) + .patchIssueComment(workspaceSlug as string, projectId as string, inboxIssueId as string, commentId, data) .then(() => mutateIssueActivity()); }; @@ -51,7 +51,7 @@ export const InboxIssueActivity: React.FC = observer(({ issueDetails }) = mutateIssueActivity((prevData: any) => prevData?.filter((p: any) => p.id !== commentId), false); await issueCommentService - .deleteIssueComment(workspaceSlug as string, projectId as string, inboxIssueId as string, commentId, user) + .deleteIssueComment(workspaceSlug as string, projectId as string, inboxIssueId as string, commentId) .then(() => mutateIssueActivity()); }; @@ -59,7 +59,7 @@ export const InboxIssueActivity: React.FC = observer(({ issueDetails }) = if (!workspaceSlug || !issueDetails || !user) return; await issueCommentService - .createIssueComment(workspaceSlug.toString(), issueDetails.project, issueDetails.id, formData, user) + .createIssueComment(workspaceSlug.toString(), issueDetails.project, issueDetails.id, formData) .then(() => { mutate(PROJECT_ISSUES_ACTIVITY(issueDetails.id)); }) diff --git a/web/components/integration/delete-import-modal.tsx b/web/components/integration/delete-import-modal.tsx index 8d222c4db..9873d729f 100644 --- a/web/components/integration/delete-import-modal.tsx +++ b/web/components/integration/delete-import-modal.tsx @@ -29,7 +29,7 @@ type Props = { // services const integrationService = new IntegrationService(); -export const DeleteImportModal: React.FC = ({ isOpen, handleClose, data, user }) => { +export const DeleteImportModal: React.FC = ({ isOpen, handleClose, data }) => { const [deleteLoading, setDeleteLoading] = useState(false); const [confirmDeleteImport, setConfirmDeleteImport] = useState(false); @@ -50,7 +50,7 @@ export const DeleteImportModal: React.FC = ({ isOpen, handleClose, data, ); integrationService - .deleteImporterService(workspaceSlug as string, data.service, data.id, user) + .deleteImporterService(workspaceSlug as string, data.service, data.id) .catch(() => setToastAlert({ type: "error", diff --git a/web/components/integration/github/root.tsx b/web/components/integration/github/root.tsx index aac2b10e9..705a41255 100644 --- a/web/components/integration/github/root.tsx +++ b/web/components/integration/github/root.tsx @@ -87,7 +87,7 @@ type Props = { const integrationService = new IntegrationService(); const githubIntegrationService = new GithubIntegrationService(); -export const GithubImporterRoot: React.FC = ({ user }) => { +export const GithubImporterRoot: React.FC = () => { const [currentStep, setCurrentStep] = useState({ state: "import-configure", }); @@ -147,7 +147,7 @@ export const GithubImporterRoot: React.FC = ({ user }) => { }; await githubIntegrationService - .createGithubServiceImport(workspaceSlug as string, payload, user) + .createGithubServiceImport(workspaceSlug as string, payload) .then(() => { router.push(`/${workspaceSlug}/settings/imports`); mutate(IMPORTER_SERVICES_LIST(workspaceSlug as string)); diff --git a/web/components/integration/jira/root.tsx b/web/components/integration/jira/root.tsx index 4cd3c2490..3651a97d9 100644 --- a/web/components/integration/jira/root.tsx +++ b/web/components/integration/jira/root.tsx @@ -60,7 +60,7 @@ type Props = { // services const jiraImporterService = new JiraImporterService(); -export const JiraImporterRoot: React.FC = ({ user }) => { +export const JiraImporterRoot: React.FC = () => { const [currentStep, setCurrentStep] = useState({ state: "import-configure", }); @@ -81,7 +81,7 @@ export const JiraImporterRoot: React.FC = ({ user }) => { if (!workspaceSlug) return; await jiraImporterService - .createJiraImporter(workspaceSlug.toString(), data, user) + .createJiraImporter(workspaceSlug.toString(), data) .then(() => { mutate(IMPORTER_SERVICES_LIST(workspaceSlug.toString())); router.push(`/${workspaceSlug}/settings/imports`); diff --git a/web/components/issues/draft-issue-form.tsx b/web/components/issues/draft-issue-form.tsx index e42d8aab3..e80c4609a 100644 --- a/web/components/issues/draft-issue-form.tsx +++ b/web/components/issues/draft-issue-form.tsx @@ -231,15 +231,10 @@ export const DraftIssueForm: FC = (props) => { setIAmFeelingLucky(true); aiService - .createGptTask( - workspaceSlug as string, - projectId as string, - { - prompt: issueName, - task: "Generate a proper description for this issue.", - }, - user - ) + .createGptTask(workspaceSlug as string, projectId as string, { + prompt: issueName, + task: "Generate a proper description for this issue.", + }) .then((res) => { if (res.response === "") setToastAlert({ diff --git a/web/components/issues/draft-issue-modal.tsx b/web/components/issues/draft-issue-modal.tsx index 189706cef..5d8711426 100644 --- a/web/components/issues/draft-issue-modal.tsx +++ b/web/components/issues/draft-issue-modal.tsx @@ -226,36 +226,24 @@ export const CreateUpdateDraftIssueModal: React.FC = observer( const addIssueToCycle = async (issueId: string, cycleId: string) => { if (!workspaceSlug || !activeProject || !user) return; - await issueService.addIssueToCycle( - workspaceSlug as string, - activeProject ?? "", - cycleId, - { - issues: [issueId], - }, - user - ); + await issueService.addIssueToCycle(workspaceSlug as string, activeProject ?? "", cycleId, { + issues: [issueId], + }); }; const addIssueToModule = async (issueId: string, moduleId: string) => { if (!workspaceSlug || !activeProject || !user) return; - await moduleService.addIssuesToModule( - workspaceSlug as string, - activeProject ?? "", - moduleId as string, - { - issues: [issueId], - }, - user - ); + await moduleService.addIssuesToModule(workspaceSlug as string, activeProject ?? "", moduleId as string, { + issues: [issueId], + }); }; const createIssue = async (payload: Partial) => { if (!workspaceSlug || !activeProject || !user) return; await issueService - .createIssue(workspaceSlug.toString(), activeProject, payload, user) + .createIssue(workspaceSlug.toString(), activeProject, payload) .then(async (res) => { if (payload.cycle && payload.cycle !== "") await addIssueToCycle(res.id, payload.cycle); if (payload.module && payload.module !== "") await addIssueToModule(res.id, payload.module); diff --git a/web/components/issues/form.tsx b/web/components/issues/form.tsx index a335ef687..f33d8e6be 100644 --- a/web/components/issues/form.tsx +++ b/web/components/issues/form.tsx @@ -188,15 +188,10 @@ export const IssueForm: FC = observer((props) => { setIAmFeelingLucky(true); aiService - .createGptTask( - workspaceSlug as string, - projectId as string, - { - prompt: issueName, - task: "Generate a proper description for this issue.", - }, - user - ) + .createGptTask(workspaceSlug as string, projectId as string, { + prompt: issueName, + task: "Generate a proper description for this issue.", + }) .then((res) => { if (res.response === "") setToastAlert({ diff --git a/web/components/issues/issue-layouts/kanban/headers/group-by-card.tsx b/web/components/issues/issue-layouts/kanban/headers/group-by-card.tsx index bb5060326..a336106d3 100644 --- a/web/components/issues/issue-layouts/kanban/headers/group-by-card.tsx +++ b/web/components/issues/issue-layouts/kanban/headers/group-by-card.tsx @@ -1,6 +1,5 @@ import React, { FC } from "react"; import { useRouter } from "next/router"; - // services import { ModuleService } from "services/module.service"; import { IssueService } from "services/issue"; @@ -11,7 +10,6 @@ import { ExistingIssuesListModal } from "components/core"; // lucide icons import { Minimize2, Maximize2, Circle, Plus } from "lucide-react"; // hooks -import useUser from "hooks/use-user"; import useToast from "hooks/use-toast"; // mobx import { observer } from "mobx-react-lite"; @@ -43,8 +41,6 @@ export const HeaderGroupByCard: FC = observer((props) => { const router = useRouter(); const { workspaceSlug, projectId, moduleId, cycleId } = router.query; - const { user } = useUser(); - const { setToastAlert } = useToast(); const renderExistingIssueModal = moduleId || cycleId; @@ -58,7 +54,7 @@ export const HeaderGroupByCard: FC = observer((props) => { }; await moduleService - .addIssuesToModule(workspaceSlug as string, projectId as string, moduleId as string, payload, user) + .addIssuesToModule(workspaceSlug as string, projectId as string, moduleId as string, payload) .catch(() => setToastAlert({ type: "error", @@ -76,7 +72,7 @@ export const HeaderGroupByCard: FC = observer((props) => { }; await issueService - .addIssueToCycle(workspaceSlug as string, projectId as string, cycleId as string, payload, user) + .addIssueToCycle(workspaceSlug as string, projectId as string, cycleId as string, payload) .catch(() => { setToastAlert({ type: "error", diff --git a/web/components/issues/issue-layouts/list/headers/group-by-card.tsx b/web/components/issues/issue-layouts/list/headers/group-by-card.tsx index 4a43fdf77..764b7bcf7 100644 --- a/web/components/issues/issue-layouts/list/headers/group-by-card.tsx +++ b/web/components/issues/issue-layouts/list/headers/group-by-card.tsx @@ -1,6 +1,5 @@ import React from "react"; import { useRouter } from "next/router"; - // services import { ModuleService } from "services/module.service"; import { IssueService } from "services/issue"; @@ -11,7 +10,6 @@ import { CreateUpdateIssueModal } from "components/issues/modal"; import { ExistingIssuesListModal } from "components/core"; import { CustomMenu } from "@plane/ui"; // hooks -import useUser from "hooks/use-user"; import useToast from "hooks/use-toast"; // mobx import { observer } from "mobx-react-lite"; @@ -34,8 +32,6 @@ export const HeaderGroupByCard = observer(({ icon, title, count, issuePayload }: const [isOpen, setIsOpen] = React.useState(false); const [openExistingIssueListModal, setOpenExistingIssueListModal] = React.useState(false); - const { user } = useUser(); - const { setToastAlert } = useToast(); const verticalAlignPosition = false; @@ -51,7 +47,7 @@ export const HeaderGroupByCard = observer(({ icon, title, count, issuePayload }: }; await moduleService - .addIssuesToModule(workspaceSlug as string, projectId as string, moduleId as string, payload, user) + .addIssuesToModule(workspaceSlug as string, projectId as string, moduleId as string, payload) .catch(() => setToastAlert({ type: "error", @@ -69,7 +65,7 @@ export const HeaderGroupByCard = observer(({ icon, title, count, issuePayload }: }; await issueService - .addIssueToCycle(workspaceSlug as string, projectId as string, cycleId as string, payload, user) + .addIssueToCycle(workspaceSlug as string, projectId as string, cycleId as string, payload) .catch(() => { setToastAlert({ type: "error", diff --git a/web/components/issues/main-content.tsx b/web/components/issues/main-content.tsx index ce1c820f5..7f1e68930 100644 --- a/web/components/issues/main-content.tsx +++ b/web/components/issues/main-content.tsx @@ -69,7 +69,7 @@ export const IssueMainContent: React.FC = observer((props) => { if (!workspaceSlug || !projectId || !issueId) return; await issueCommentService - .patchIssueComment(workspaceSlug as string, projectId as string, issueId as string, commentId, data, user) + .patchIssueComment(workspaceSlug as string, projectId as string, issueId as string, commentId, data) .then(() => mutateIssueActivity()); }; @@ -79,7 +79,7 @@ export const IssueMainContent: React.FC = observer((props) => { mutateIssueActivity((prevData: any) => prevData?.filter((p: any) => p.id !== commentId), false); await issueCommentService - .deleteIssueComment(workspaceSlug as string, projectId as string, issueId as string, commentId, user) + .deleteIssueComment(workspaceSlug as string, projectId as string, issueId as string, commentId) .then(() => mutateIssueActivity()); }; @@ -87,7 +87,7 @@ export const IssueMainContent: React.FC = observer((props) => { if (!workspaceSlug || !issueDetails || !user) return; await issueCommentService - .createIssueComment(workspaceSlug.toString(), issueDetails.project, issueDetails.id, formData, user) + .createIssueComment(workspaceSlug.toString(), issueDetails.project, issueDetails.id, formData) .then(() => { mutate(PROJECT_ISSUES_ACTIVITY(issueDetails.id)); }) diff --git a/web/components/issues/peek-overview/issue-activity.tsx b/web/components/issues/peek-overview/issue-activity.tsx index dc1d044af..e6d32d3cc 100644 --- a/web/components/issues/peek-overview/issue-activity.tsx +++ b/web/components/issues/peek-overview/issue-activity.tsx @@ -2,7 +2,6 @@ import useSWR, { mutate } from "swr"; // services import { IssueCommentService, IssueService } from "services/issue"; // hooks -import useUser from "hooks/use-user"; import useToast from "hooks/use-toast"; import useProjectDetails from "hooks/use-project-details"; // components @@ -26,7 +25,6 @@ export const PeekOverviewIssueActivity: React.FC = (props) => { // toast const { setToastAlert } = useToast(); - const { user } = useUser(); const { projectDetails } = useProjectDetails(); const { data: issueActivity, mutate: mutateIssueActivity } = useSWR( @@ -40,7 +38,7 @@ export const PeekOverviewIssueActivity: React.FC = (props) => { if (!workspaceSlug || !issue) return; await issueCommentService - .patchIssueComment(workspaceSlug as string, issue.project, issue.id, commentId, data, user) + .patchIssueComment(workspaceSlug as string, issue.project, issue.id, commentId, data) .then(() => mutateIssueActivity()); }; @@ -50,7 +48,7 @@ export const PeekOverviewIssueActivity: React.FC = (props) => { mutateIssueActivity((prevData: any) => prevData?.filter((p: any) => p.id !== commentId), false); await issueCommentService - .deleteIssueComment(workspaceSlug as string, issue.project, issue.id, commentId, user) + .deleteIssueComment(workspaceSlug as string, issue.project, issue.id, commentId) .then(() => mutateIssueActivity()); }; @@ -58,7 +56,7 @@ export const PeekOverviewIssueActivity: React.FC = (props) => { if (!workspaceSlug || !issue) return; await issueCommentService - .createIssueComment(workspaceSlug.toString(), issue.project, issue.id, formData, user) + .createIssueComment(workspaceSlug.toString(), issue.project, issue.id, formData) .then(() => { mutate(PROJECT_ISSUES_ACTIVITY(issue.id)); }) diff --git a/web/components/issues/sidebar-select/blocked.tsx b/web/components/issues/sidebar-select/blocked.tsx index 73bf747af..61f5eca62 100644 --- a/web/components/issues/sidebar-select/blocked.tsx +++ b/web/components/issues/sidebar-select/blocked.tsx @@ -68,7 +68,7 @@ export const SidebarBlockedSelect: React.FC = ({ issueId, submitChanges, if (!user) return; issueService - .createIssueRelation(workspaceSlug as string, projectId as string, issueId as string, user, { + .createIssueRelation(workspaceSlug as string, projectId as string, issueId as string, { related_list: [ ...selectedIssues.map((issue) => ({ issue: issueId as string, @@ -134,8 +134,7 @@ export const SidebarBlockedSelect: React.FC = ({ issueId, submitChanges, workspaceSlug as string, projectId as string, issueId as string, - relation.id, - user + relation.id ); }} > diff --git a/web/components/issues/sidebar-select/blocker.tsx b/web/components/issues/sidebar-select/blocker.tsx index 139212313..161fcc1d4 100644 --- a/web/components/issues/sidebar-select/blocker.tsx +++ b/web/components/issues/sidebar-select/blocker.tsx @@ -69,7 +69,7 @@ export const SidebarBlockerSelect: React.FC = ({ issueId, submitChanges, if (!user) return; issueService - .createIssueRelation(workspaceSlug as string, projectId as string, issueId as string, user, { + .createIssueRelation(workspaceSlug as string, projectId as string, issueId as string, { related_list: [ ...selectedIssues.map((issue) => ({ issue: issue.blocker_issue_detail.id, @@ -144,8 +144,7 @@ export const SidebarBlockerSelect: React.FC = ({ issueId, submitChanges, workspaceSlug as string, projectId as string, relation.issue_detail?.id as string, - relation.id, - user + relation.id ); }} > diff --git a/web/components/issues/sidebar-select/duplicate.tsx b/web/components/issues/sidebar-select/duplicate.tsx index a28d472ba..a56ea420d 100644 --- a/web/components/issues/sidebar-select/duplicate.tsx +++ b/web/components/issues/sidebar-select/duplicate.tsx @@ -67,7 +67,7 @@ export const SidebarDuplicateSelect: React.FC = (props) => { if (!user) return; issueService - .createIssueRelation(workspaceSlug as string, projectId as string, issueId as string, user, { + .createIssueRelation(workspaceSlug as string, projectId as string, issueId as string, { related_list: [ ...selectedIssues.map((issue) => ({ issue: issueId as string, @@ -137,8 +137,7 @@ export const SidebarDuplicateSelect: React.FC = (props) => { workspaceSlug as string, projectId as string, issueId as string, - relation.id, - user + relation.id ) .then(() => { submitChanges(); diff --git a/web/components/issues/sidebar-select/label.tsx b/web/components/issues/sidebar-select/label.tsx index 52a50562c..37100448c 100644 --- a/web/components/issues/sidebar-select/label.tsx +++ b/web/components/issues/sidebar-select/label.tsx @@ -7,8 +7,6 @@ import { TwitterPicker } from "react-color"; import { Popover, Transition } from "@headlessui/react"; // services import { IssueLabelService } from "services/issue"; -// hooks -import useUser from "hooks/use-user"; // ui import { Input } from "@plane/ui"; import { IssueLabelSelect } from "../select"; @@ -61,8 +59,6 @@ export const SidebarLabelSelect: React.FC = ({ defaultValues, }); - const { user } = useUser(); - const { data: issueLabels, mutate: issueLabelMutate } = useSWR( workspaceSlug && projectId ? PROJECT_ISSUE_LABELS(projectId as string) : null, workspaceSlug && projectId @@ -74,7 +70,7 @@ export const SidebarLabelSelect: React.FC = ({ if (!workspaceSlug || !projectId || isSubmitting) return; await issueLabelService - .createIssueLabel(workspaceSlug as string, projectId as string, formData, user) + .createIssueLabel(workspaceSlug as string, projectId as string, formData) .then((res) => { reset(defaultValues); diff --git a/web/components/issues/sidebar-select/relates-to.tsx b/web/components/issues/sidebar-select/relates-to.tsx index 2f543e381..bac0684a1 100644 --- a/web/components/issues/sidebar-select/relates-to.tsx +++ b/web/components/issues/sidebar-select/relates-to.tsx @@ -68,7 +68,7 @@ export const SidebarRelatesSelect: React.FC = (props) => { if (!user) return; issueService - .createIssueRelation(workspaceSlug as string, projectId as string, issueId as string, user, { + .createIssueRelation(workspaceSlug as string, projectId as string, issueId as string, { related_list: [ ...selectedIssues.map((issue) => ({ issue: issueId as string, @@ -138,8 +138,7 @@ export const SidebarRelatesSelect: React.FC = (props) => { workspaceSlug as string, projectId as string, issueId as string, - relation.id, - user + relation.id ) .then(() => { submitChanges(); diff --git a/web/components/issues/sidebar.tsx b/web/components/issues/sidebar.tsx index 3ef335309..e67b73baa 100644 --- a/web/components/issues/sidebar.tsx +++ b/web/components/issues/sidebar.tsx @@ -101,15 +101,9 @@ export const IssueDetailsSidebar: React.FC = observer((props) => { if (!workspaceSlug || !projectId || !issueDetail || !user) return; issueService - .addIssueToCycle( - workspaceSlug as string, - projectId as string, - cycleId, - { - issues: [issueDetail.id], - }, - user - ) + .addIssueToCycle(workspaceSlug as string, projectId as string, cycleId, { + issues: [issueDetail.id], + }) .then(() => { mutate(ISSUE_DETAILS(issueId as string)); }); @@ -122,15 +116,9 @@ export const IssueDetailsSidebar: React.FC = observer((props) => { if (!workspaceSlug || !projectId || !issueDetail || !user) return; moduleService - .addIssuesToModule( - workspaceSlug as string, - projectId as string, - moduleId, - { - issues: [issueDetail.id], - }, - user - ) + .addIssuesToModule(workspaceSlug as string, projectId as string, moduleId, { + issues: [issueDetail.id], + }) .then(() => { mutate(ISSUE_DETAILS(issueId as string)); }); diff --git a/web/components/issues/sub-issues/properties.tsx b/web/components/issues/sub-issues/properties.tsx index faf593efb..2bd76cd92 100644 --- a/web/components/issues/sub-issues/properties.tsx +++ b/web/components/issues/sub-issues/properties.tsx @@ -5,7 +5,6 @@ import { mutate } from "swr"; import { useMobxStore } from "lib/mobx/store-provider"; // services import { IssueService } from "services/issue"; -import { TrackEventService } from "services/track_event.service"; // components import { ViewDueDateSelect, ViewStartDateSelect } from "components/issues"; import { PrioritySelect } from "components/project"; @@ -25,7 +24,6 @@ export interface IIssueProperty { // services const issueService = new IssueService(); -const trackEventService = new TrackEventService(); export const IssueProperty: React.FC = observer((props) => { const { workspaceSlug, parentIssue, issue, user, editable } = props; @@ -36,18 +34,6 @@ export const IssueProperty: React.FC = observer((props) => { const handlePriorityChange = (data: any) => { partialUpdateIssue({ priority: data }); - trackEventService.trackIssuePartialPropertyUpdateEvent( - { - workspaceSlug, - workspaceId: issue.workspace, - projectId: issue.project_detail.id, - projectIdentifier: issue.project_detail.identifier, - projectName: issue.project_detail.name, - issueId: issue.id, - }, - "ISSUE_PROPERTY_UPDATE_PRIORITY", - user as IUser - ); }; const handleStateChange = (data: IState) => { @@ -55,35 +41,10 @@ export const IssueProperty: React.FC = observer((props) => { state: data.id, state_detail: data, }); - trackEventService.trackIssuePartialPropertyUpdateEvent( - { - workspaceSlug, - workspaceId: issue.workspace, - projectId: issue.project_detail.id, - projectIdentifier: issue.project_detail.identifier, - projectName: issue.project_detail.name, - issueId: issue.id, - }, - "ISSUE_PROPERTY_UPDATE_STATE", - user as IUser - ); }; const handleAssigneeChange = (data: string[]) => { partialUpdateIssue({ assignees: data }); - - trackEventService.trackIssuePartialPropertyUpdateEvent( - { - workspaceSlug, - workspaceId: issue.workspace, - projectId: issue.project_detail.id, - projectIdentifier: issue.project_detail.identifier, - projectName: issue.project_detail.name, - issueId: issue.id, - }, - "ISSUE_PROPERTY_UPDATE_ASSIGNEE", - user as IUser - ); }; const partialUpdateIssue = async (data: Partial) => { @@ -100,7 +61,7 @@ export const IssueProperty: React.FC = observer((props) => { false ); - const issueResponse = await issueService.patchIssue(workspaceSlug as string, issue.project, issue.id, data, user); + const issueResponse = await issueService.patchIssue(workspaceSlug as string, issue.project, issue.id, data); mutate( SUB_ISSUES(parentIssue.id), diff --git a/web/components/issues/sub-issues/root.tsx b/web/components/issues/sub-issues/root.tsx index 3e8a345f8..3cacdd2a9 100644 --- a/web/components/issues/sub-issues/root.tsx +++ b/web/components/issues/sub-issues/root.tsx @@ -126,7 +126,7 @@ export const SubIssuesRoot: React.FC = observer((props) => { const removeIssueFromSubIssues = async (parentIssueId: string, issue: IIssue) => { if (!workspaceSlug || !projectId || !parentIssue || !issue?.id) return; issueService - .patchIssue(workspaceSlug.toString(), projectId.toString(), issue.id, { parent: null }, user) + .patchIssue(workspaceSlug.toString(), projectId.toString(), issue.id, { parent: null }) .then(async () => { if (parentIssueId) await mutate(SUB_ISSUES(parentIssueId)); handleIssuesLoader({ key: "delete", issueId: issue?.id }); diff --git a/web/components/modules/sidebar.tsx b/web/components/modules/sidebar.tsx index f4c14871b..62613bd39 100644 --- a/web/components/modules/sidebar.tsx +++ b/web/components/modules/sidebar.tsx @@ -57,7 +57,6 @@ export const ModuleDetailsSidebar: React.FC = observer((props) => { const { module: moduleStore, user: userStore } = useMobxStore(); - const user = userStore.currentUser ?? undefined; const userRole = userStore.currentProjectRole; const moduleDetails = moduleStore.moduleDetails[moduleId] ?? undefined; @@ -80,7 +79,7 @@ export const ModuleDetailsSidebar: React.FC = observer((props) => { ); moduleService - .patchModule(workspaceSlug as string, projectId as string, moduleId as string, data, user) + .patchModule(workspaceSlug as string, projectId as string, moduleId as string, data) .then(() => mutate(MODULE_DETAILS(moduleId as string))) .catch((e) => console.log(e)); }; diff --git a/web/components/onboarding/invite-members.tsx b/web/components/onboarding/invite-members.tsx index 08617ca71..fa639af72 100644 --- a/web/components/onboarding/invite-members.tsx +++ b/web/components/onboarding/invite-members.tsx @@ -164,7 +164,7 @@ const InviteMemberForm: React.FC = (props) => { }; export const InviteMembers: React.FC = (props) => { - const { finishOnboarding, stepChange, user, workspace } = props; + const { finishOnboarding, stepChange, workspace } = props; const { setToastAlert } = useToast(); @@ -195,7 +195,7 @@ export const InviteMembers: React.FC = (props) => { const payload = { ...formData }; await workspaceService - .inviteWorkspace(workspace.slug, payload, user) + .inviteWorkspace(workspace.slug, payload) .then(async () => { setToastAlert({ type: "success", diff --git a/web/components/onboarding/join-workspaces.tsx b/web/components/onboarding/join-workspaces.tsx index d846614dd..51c965acd 100644 --- a/web/components/onboarding/join-workspaces.tsx +++ b/web/components/onboarding/join-workspaces.tsx @@ -18,6 +18,7 @@ import { IWorkspaceMemberInvitation, TOnboardingSteps } from "types"; import { USER_WORKSPACES, USER_WORKSPACE_INVITATIONS } from "constants/fetch-keys"; // constants import { ROLE } from "constants/workspace"; +import { trackEvent } from "helpers/event-tracker.helper"; type Props = { finishOnboarding: () => Promise; @@ -61,7 +62,11 @@ export const JoinWorkspaces: React.FC = ({ finishOnboarding, stepChange, await workspaceService .joinWorkspaces({ invitations: invitationsRespond }) - .then(async () => { + .then(async (res) => { + trackEvent( + 'WORKSPACE_USER_INVITE_ACCEPT', + res + ) await mutateInvitations(); await mutate(USER_WORKSPACES); await updateLastWorkspace(); @@ -83,9 +88,8 @@ export const JoinWorkspaces: React.FC = ({ finishOnboarding, stepChange, return (
handleInvitation(invitation, isSelected ? "withdraw" : "accepted")} >
diff --git a/web/components/pages/create-block.tsx b/web/components/pages/create-block.tsx index 1decabae0..0fe548d25 100644 --- a/web/components/pages/create-block.tsx +++ b/web/components/pages/create-block.tsx @@ -24,7 +24,7 @@ type Props = { const pageService = new PageService(); -export const CreateBlock: FC = ({ user }) => { +export const CreateBlock: FC = () => { // const [blockTitle, setBlockTitle] = useState(""); // router const router = useRouter(); @@ -46,15 +46,9 @@ export const CreateBlock: FC = ({ user }) => { if (!workspaceSlug || !projectId || !pageId) return; await pageService - .createPageBlock( - workspaceSlug as string, - projectId as string, - pageId as string, - { - name: watch("name"), - }, - user - ) + .createPageBlock(workspaceSlug as string, projectId as string, pageId as string, { + name: watch("name"), + }) .then((res) => { mutate( PAGE_BLOCKS_LIST(pageId as string), diff --git a/web/components/pages/create-update-block-inline.tsx b/web/components/pages/create-update-block-inline.tsx index c1b3c5155..d2533a967 100644 --- a/web/components/pages/create-update-block-inline.tsx +++ b/web/components/pages/create-update-block-inline.tsx @@ -40,14 +40,7 @@ const pagesService = new PageService(); const issueService = new IssueService(); const fileService = new FileService(); -export const CreateUpdateBlockInline: FC = ({ - handleClose, - data, - handleAiAssistance, - setIsSyncing, - focus, - user, -}) => { +export const CreateUpdateBlockInline: FC = ({ handleClose, data, handleAiAssistance, setIsSyncing, focus }) => { const [iAmFeelingLucky, setIAmFeelingLucky] = useState(false); const [gptAssistantModal, setGptAssistantModal] = useState(false); @@ -83,17 +76,11 @@ export const CreateUpdateBlockInline: FC = ({ if (!workspaceSlug || !projectId || !pageId) return; await pagesService - .createPageBlock( - workspaceSlug as string, - projectId as string, - pageId as string, - { - name: formData.name, - description: formData.description ?? "", - description_html: formData.description_html ?? "

", - }, - user - ) + .createPageBlock(workspaceSlug as string, projectId as string, pageId as string, { + name: formData.name, + description: formData.description ?? "", + description_html: formData.description_html ?? "

", + }) .then((res) => { mutate( PAGE_BLOCKS_LIST(pageId as string), @@ -111,7 +98,7 @@ export const CreateUpdateBlockInline: FC = ({ }) .finally(() => onClose()); }, - [workspaceSlug, projectId, pageId, onClose, setToastAlert, user] + [workspaceSlug, projectId, pageId, onClose, setToastAlert] ); const updatePageBlock = useCallback( @@ -132,41 +119,28 @@ export const CreateUpdateBlockInline: FC = ({ ); await pagesService - .patchPageBlock( - workspaceSlug as string, - projectId as string, - pageId as string, - data.id, - { - name: formData.name, - description: formData.description, - description_html: formData.description_html, - }, - user - ) + .patchPageBlock(workspaceSlug as string, projectId as string, pageId as string, data.id, { + name: formData.name, + description: formData.description, + description_html: formData.description_html, + }) .then((res) => { mutate(PAGE_BLOCKS_LIST(pageId as string)); editorRef.current?.setEditorValue(res.description_html); if (data.issue && data.sync) issueService - .patchIssue( - workspaceSlug as string, - projectId as string, - data.issue, - { - name: res.name, - description: res.description, - description_html: res.description_html, - }, - user - ) + .patchIssue(workspaceSlug as string, projectId as string, data.issue, { + name: res.name, + description: res.description, + description_html: res.description_html, + }) .finally(() => { if (setIsSyncing) setIsSyncing(false); }); }) .finally(() => onClose()); }, - [workspaceSlug, projectId, pageId, data, onClose, setIsSyncing, user] + [workspaceSlug, projectId, pageId, data, onClose, setIsSyncing] ); const handleAutoGenerateDescription = async () => { @@ -175,15 +149,10 @@ export const CreateUpdateBlockInline: FC = ({ setIAmFeelingLucky(true); aiService - .createGptTask( - workspaceSlug as string, - projectId as string, - { - prompt: watch("name"), - task: "Generate a proper description for this issue.", - }, - user - ) + .createGptTask(workspaceSlug as string, projectId as string, { + prompt: watch("name"), + task: "Generate a proper description for this issue.", + }) .then((res) => { if (res.response === "") setToastAlert({ diff --git a/web/components/pages/create-update-page-modal.tsx b/web/components/pages/create-update-page-modal.tsx index a5803fcad..7c5547ed5 100644 --- a/web/components/pages/create-update-page-modal.tsx +++ b/web/components/pages/create-update-page-modal.tsx @@ -1,10 +1,6 @@ import React from "react"; - import { useRouter } from "next/router"; - import { mutate } from "swr"; - -// headless ui import { Dialog, Transition } from "@headlessui/react"; // services import { PageService } from "services/page.service"; @@ -16,6 +12,7 @@ import { PageForm } from "./page-form"; import { IUser, IPage } from "types"; // fetch-keys import { ALL_PAGES_LIST, FAVORITE_PAGES_LIST, MY_PAGES_LIST, RECENT_PAGES_LIST } from "constants/fetch-keys"; +import { trackEvent } from "helpers/event-tracker.helper"; type Props = { isOpen: boolean; @@ -30,7 +27,7 @@ type Props = { const pageService = new PageService(); export const CreateUpdatePageModal: React.FC = (props) => { - const { isOpen, handleClose, data, user, workspaceSlug, projectId } = props; + const { isOpen, handleClose, data, workspaceSlug, projectId } = props; // router const router = useRouter(); @@ -42,7 +39,7 @@ export const CreateUpdatePageModal: React.FC = (props) => { const createPage = async (payload: IPage) => { await pageService - .createPage(workspaceSlug as string, projectId as string, payload, user) + .createPage(workspaceSlug as string, projectId as string, payload) .then((res) => { mutate(RECENT_PAGES_LIST(projectId as string)); mutate( @@ -64,14 +61,19 @@ export const CreateUpdatePageModal: React.FC = (props) => { false ); onClose(); - router.push(`/${workspaceSlug}/projects/${projectId}/pages/${res.id}`); - setToastAlert({ type: "success", title: "Success!", message: "Page created successfully.", }); + trackEvent( + 'PAGE_CREATE', + { + ...res, + caase: "SUCCES" + } + ) }) .catch(() => { setToastAlert({ @@ -79,12 +81,18 @@ export const CreateUpdatePageModal: React.FC = (props) => { title: "Error!", message: "Page could not be created. Please try again.", }); + trackEvent( + 'PAGE_CREATE', + { + case: "FAILED" + } + ) }); }; const updatePage = async (payload: IPage) => { await pageService - .patchPage(workspaceSlug as string, projectId as string, data?.id ?? "", payload, user) + .patchPage(workspaceSlug as string, projectId as string, data?.id ?? "", payload) .then((res) => { mutate(RECENT_PAGES_LIST(projectId as string)); mutate( @@ -124,6 +132,13 @@ export const CreateUpdatePageModal: React.FC = (props) => { title: "Success!", message: "Page updated successfully.", }); + trackEvent( + 'PAGE_UPDATE', + { + ...res, + case: "SUCCESS" + } + ) }) .catch(() => { setToastAlert({ @@ -131,6 +146,12 @@ export const CreateUpdatePageModal: React.FC = (props) => { title: "Error!", message: "Page could not be updated. Please try again.", }); + trackEvent( + 'PAGE_UPDATE', + { + case: "FAILED" + } + ) }); }; diff --git a/web/components/pages/delete-page-modal.tsx b/web/components/pages/delete-page-modal.tsx index a8b4eb21c..20073abb5 100644 --- a/web/components/pages/delete-page-modal.tsx +++ b/web/components/pages/delete-page-modal.tsx @@ -29,7 +29,7 @@ type TConfirmPageDeletionProps = { // services const pageService = new PageService(); -export const DeletePageModal: React.FC = ({ isOpen, setIsOpen, data, user }) => { +export const DeletePageModal: React.FC = ({ isOpen, setIsOpen, data }) => { const [isDeleteLoading, setIsDeleteLoading] = useState(false); const router = useRouter(); @@ -47,7 +47,7 @@ export const DeletePageModal: React.FC = ({ isOpen, s if (!data || !workspaceSlug || !projectId) return; await pageService - .deletePage(workspaceSlug as string, data.project, data.id, user) + .deletePage(workspaceSlug as string, data.project, data.id) .then(() => { mutate(RECENT_PAGES_LIST(projectId as string)); mutate( diff --git a/web/components/pages/pages-view.tsx b/web/components/pages/pages-view.tsx index 3154f7981..2c2b94713 100644 --- a/web/components/pages/pages-view.tsx +++ b/web/components/pages/pages-view.tsx @@ -182,7 +182,7 @@ export const PagesView: React.FC = observer(({ pages, viewType }) => { false ); - pageService.patchPage(workspaceSlug.toString(), projectId.toString(), page.id, formData, user).then(() => { + pageService.patchPage(workspaceSlug.toString(), projectId.toString(), page.id, formData).then(() => { mutate(RECENT_PAGES_LIST(projectId.toString())); }); }; diff --git a/web/components/pages/single-page-block.tsx b/web/components/pages/single-page-block.tsx index 6f6766f84..a03e0da65 100644 --- a/web/components/pages/single-page-block.tsx +++ b/web/components/pages/single-page-block.tsx @@ -85,33 +85,20 @@ export const SinglePageBlock: React.FC = ({ block, projectDetails, showBl ); await pageService - .patchPageBlock( - workspaceSlug as string, - projectId as string, - pageId as string, - block.id, - { - name: formData.name, - description: formData.description, - description_html: formData.description_html, - }, - user - ) + .patchPageBlock(workspaceSlug as string, projectId as string, pageId as string, block.id, { + name: formData.name, + description: formData.description, + description_html: formData.description_html, + }) .then((res) => { mutate(PAGE_BLOCKS_LIST(pageId as string)); if (block.issue && block.sync) issueService - .patchIssue( - workspaceSlug as string, - projectId as string, - block.issue, - { - name: res.name, - description: res.description, - description_html: res.description_html, - }, - user - ) + .patchIssue(workspaceSlug as string, projectId as string, block.issue, { + name: res.name, + description: res.description, + description_html: res.description_html, + }) .finally(() => setIsSyncing(false)); }); }; @@ -120,7 +107,7 @@ export const SinglePageBlock: React.FC = ({ block, projectDetails, showBl if (!workspaceSlug || !projectId || !pageId) return; await pageService - .convertPageBlockToIssue(workspaceSlug as string, projectId as string, pageId as string, block.id, user) + .convertPageBlockToIssue(workspaceSlug as string, projectId as string, pageId as string, block.id) .then((res: IIssue) => { mutate( PAGE_BLOCKS_LIST(pageId as string), @@ -158,7 +145,7 @@ export const SinglePageBlock: React.FC = ({ block, projectDetails, showBl ); await pageService - .deletePageBlock(workspaceSlug as string, projectId as string, pageId as string, block.id, user) + .deletePageBlock(workspaceSlug as string, projectId as string, pageId as string, block.id) .catch(() => { setToastAlert({ type: "error", @@ -174,15 +161,10 @@ export const SinglePageBlock: React.FC = ({ block, projectDetails, showBl setIAmFeelingLucky(true); aiService - .createGptTask( - workspaceSlug as string, - projectId as string, - { - prompt: block.name, - task: "Generate a proper description for this issue.", - }, - user - ) + .createGptTask(workspaceSlug as string, projectId as string, { + prompt: block.name, + task: "Generate a proper description for this issue.", + }) .then((res) => { if (res.response === "") setToastAlert({ @@ -246,16 +228,9 @@ export const SinglePageBlock: React.FC = ({ block, projectDetails, showBl false ); - pageService.patchPageBlock( - workspaceSlug as string, - projectId as string, - pageId as string, - block.id, - { - sync: !block.sync, - }, - user - ); + pageService.patchPageBlock(workspaceSlug as string, projectId as string, pageId as string, block.id, { + sync: !block.sync, + }); }; const handleCopyText = () => { diff --git a/web/components/project/create-project-modal.tsx b/web/components/project/create-project-modal.tsx index e1d199239..6659dca87 100644 --- a/web/components/project/create-project-modal.tsx +++ b/web/components/project/create-project-modal.tsx @@ -20,6 +20,8 @@ import { getRandomEmoji, renderEmoji } from "helpers/emoji.helper"; import { IWorkspaceMember } from "types"; // constants import { NETWORK_CHOICES, PROJECT_UNSPLASH_COVERS } from "constants/project"; +// track events +import { trackEvent } from "helpers/event-tracker.helper"; type Props = { isOpen: boolean; @@ -129,6 +131,14 @@ export const CreateProjectModal: FC = observer((props) => { return projectStore .createProject(workspaceSlug.toString(), payload) .then((res) => { + const newPayload = { + ...payload, + id: res.id + } + trackEvent( + "CREATE_PROJECT", + newPayload, + ) setToastAlert({ type: "success", title: "Success!", @@ -211,7 +221,7 @@ export const CreateProjectModal: FC = observer((props) => { )}
-
diff --git a/web/components/project/delete-project-modal.tsx b/web/components/project/delete-project-modal.tsx index 90217e69e..9c41106fc 100644 --- a/web/components/project/delete-project-modal.tsx +++ b/web/components/project/delete-project-modal.tsx @@ -12,6 +12,7 @@ import { Button, Input } from "@plane/ui"; import type { IProject } from "types"; // fetch-keys import { useMobxStore } from "lib/mobx/store-provider"; +import { trackEvent } from "helpers/event-tracker.helper"; type DeleteProjectModal = { isOpen: boolean; @@ -62,6 +63,9 @@ export const DeleteProjectModal: React.FC = (props) => { if (projectId && projectId.toString() === project.id) router.push(`/${workspaceSlug}/projects`); handleClose(); + trackEvent( + 'DELETE_PROJECT' + ) setToastAlert({ type: "success", title: "Success!", @@ -69,6 +73,9 @@ export const DeleteProjectModal: React.FC = (props) => { }); }) .catch(() => { + trackEvent( + 'DELETE_PROJECT/FAIL' + ) setToastAlert({ type: "error", title: "Error!", diff --git a/web/components/project/form.tsx b/web/components/project/form.tsx index 297ab7110..63d8a2a92 100644 --- a/web/components/project/form.tsx +++ b/web/components/project/form.tsx @@ -16,6 +16,7 @@ import { ProjectService } from "services/project"; // hooks import useToast from "hooks/use-toast"; import { useMobxStore } from "lib/mobx/store-provider"; +import { trackEvent } from "helpers/event-tracker.helper"; export interface IProjectDetailsForm { project: IProject; @@ -61,7 +62,11 @@ export const ProjectDetailsForm: FC = (props) => { return projectStore .updateProject(workspaceSlug.toString(), project.id, payload) - .then(() => { + .then((res) => { + trackEvent( + 'UPDATE_PROJECT', + res + ); setToastAlert({ type: "success", title: "Success!", @@ -69,6 +74,9 @@ export const ProjectDetailsForm: FC = (props) => { }); }) .catch((error) => { + trackEvent( + 'UPDATE_PROJECT/FAIL', + ); setToastAlert({ type: "error", title: "Error!", diff --git a/web/components/project/send-project-invitation-modal.tsx b/web/components/project/send-project-invitation-modal.tsx index 8fc895fe5..6509a4e4f 100644 --- a/web/components/project/send-project-invitation-modal.tsx +++ b/web/components/project/send-project-invitation-modal.tsx @@ -20,6 +20,7 @@ import { IUser, TUserProjectRole } from "types"; import { WORKSPACE_MEMBERS } from "constants/fetch-keys"; // constants import { ROLE } from "constants/workspace"; +import { trackEvent } from "helpers/event-tracker.helper"; type Props = { isOpen: boolean; @@ -52,7 +53,7 @@ const projectMemberService = new ProjectMemberService(); const workspaceService = new WorkspaceService(); export const SendProjectInvitationModal: React.FC = observer((props) => { - const { isOpen, setIsOpen, members, user, onSuccess } = props; + const { isOpen, setIsOpen, members, onSuccess } = props; const router = useRouter(); const { workspaceSlug, projectId } = router.query; @@ -91,9 +92,12 @@ export const SendProjectInvitationModal: React.FC = observer((props) => { const payload = { ...formData }; await projectMemberService - .bulkAddMembersToProject(workspaceSlug.toString(), projectId.toString(), payload, user) - .then(() => { + .bulkAddMembersToProject(workspaceSlug.toString(), projectId.toString(), payload) + .then((res) => { setIsOpen(false); + trackEvent( + 'PROJECT_MEMBER_INVITE', + ) setToastAlert({ title: "Success", type: "success", diff --git a/web/components/project/settings/features-list.tsx b/web/components/project/settings/features-list.tsx index fc32c6a92..105c1b2c7 100644 --- a/web/components/project/settings/features-list.tsx +++ b/web/components/project/settings/features-list.tsx @@ -5,8 +5,6 @@ import { ContrastIcon, FileText, Inbox, Layers } from "lucide-react"; import { DiceIcon, ToggleSwitch } from "@plane/ui"; // mobx store import { useMobxStore } from "lib/mobx/store-provider"; -// services -import { MiscellaneousEventType, TrackEventService } from "services/track_event.service"; // hooks import useToast from "hooks/use-toast"; // types @@ -47,26 +45,6 @@ const PROJECT_FEATURES_LIST = [ }, ]; -const getEventType = (feature: string, toggle: boolean): MiscellaneousEventType => { - switch (feature) { - case "Cycles": - return toggle ? "TOGGLE_CYCLE_ON" : "TOGGLE_CYCLE_OFF"; - case "Modules": - return toggle ? "TOGGLE_MODULE_ON" : "TOGGLE_MODULE_OFF"; - case "Views": - return toggle ? "TOGGLE_VIEW_ON" : "TOGGLE_VIEW_OFF"; - case "Pages": - return toggle ? "TOGGLE_PAGES_ON" : "TOGGLE_PAGES_OFF"; - case "Inbox": - return toggle ? "TOGGLE_INBOX_ON" : "TOGGLE_INBOX_OFF"; - default: - throw new Error("Invalid feature"); - } -}; - -// services -const trackEventService = new TrackEventService(); - export const ProjectFeaturesList: FC = observer(() => { // router const router = useRouter(); @@ -109,17 +87,6 @@ export const ProjectFeaturesList: FC = observer(() => { { - trackEventService.trackMiscellaneousEvent( - { - workspaceId: (currentProjectDetails?.workspace as any)?.id, - workspaceSlug, - projectId, - projectIdentifier: currentProjectDetails?.identifier, - projectName: currentProjectDetails?.name, - }, - getEventType(feature.title, !currentProjectDetails?.[feature.property as keyof IProject]), - currentUser - ); handleSubmit({ [feature.property]: !currentProjectDetails?.[feature.property as keyof IProject], }); diff --git a/web/components/states/create-update-state-inline.tsx b/web/components/states/create-update-state-inline.tsx index 15a268272..fa0fdd6b9 100644 --- a/web/components/states/create-update-state-inline.tsx +++ b/web/components/states/create-update-state-inline.tsx @@ -18,6 +18,7 @@ import type { IState } from "types"; import { STATES_LIST } from "constants/fetch-keys"; // constants import { GROUP_CHOICES } from "constants/project"; +import { trackEvent } from "helpers/event-tracker.helper"; type Props = { data: IState | null; @@ -87,8 +88,12 @@ export const CreateUpdateStateInline: React.FC = observer((props) => { await projectStateStore .createState(workspaceSlug.toString(), projectId.toString(), formData) - .then(() => { + .then((res) => { handleClose(); + trackEvent( + 'STATE_CREATE', + res + ) setToastAlert({ type: "success", title: "Success!", @@ -116,10 +121,13 @@ export const CreateUpdateStateInline: React.FC = observer((props) => { await projectStateStore .updateState(workspaceSlug.toString(), projectId.toString(), data.id, formData) - .then(() => { + .then((res) => { mutate(STATES_LIST(projectId.toString())); handleClose(); - + trackEvent( + 'STATE_UPDATE', + res + ) setToastAlert({ type: "success", title: "Success!", @@ -161,9 +169,8 @@ export const CreateUpdateStateInline: React.FC = observer((props) => { {({ open }) => ( <> {watch("color") && watch("color") !== "" && ( = observer((props) => { await projectStateStore .deleteState(workspaceSlug.toString(), data.project, data.id) - .then(() => { + .then((res) => { + trackEvent( + 'STATE_DELETE', + ) handleClose(); }) .catch((err) => { diff --git a/web/components/workspace/create-workspace-form.tsx b/web/components/workspace/create-workspace-form.tsx index a0792fe70..02238887e 100644 --- a/web/components/workspace/create-workspace-form.tsx +++ b/web/components/workspace/create-workspace-form.tsx @@ -14,6 +14,8 @@ import { Button, CustomSelect, Input } from "@plane/ui"; import { IWorkspace } from "types"; // constants import { ORGANIZATION_SIZE, RESTRICTED_URLS } from "constants/workspace"; +// events +import { trackEvent } from "helpers/event-tracker.helper"; type Props = { onSubmit?: (res: IWorkspace) => Promise; @@ -71,6 +73,16 @@ export const CreateWorkspaceForm: FC = observer((props) => { await workspaceStore .createWorkspace(formData) .then(async (res) => { + const payload = { + name: formData.name, + slug: formData.slug, + workspace_url: formData.url, + organization_size: formData.organization_size + }; + trackEvent( + "CREATE_WORKSPACE", + payload + ) setToastAlert({ type: "success", title: "Success!", diff --git a/web/components/workspace/delete-workspace-modal.tsx b/web/components/workspace/delete-workspace-modal.tsx index 3fb4a8a51..93b3b7351 100644 --- a/web/components/workspace/delete-workspace-modal.tsx +++ b/web/components/workspace/delete-workspace-modal.tsx @@ -12,6 +12,7 @@ import useToast from "hooks/use-toast"; import { Button, Input } from "@plane/ui"; // types import type { IWorkspace } from "types"; +import { trackEvent } from "helpers/event-tracker.helper"; type Props = { isOpen: boolean; @@ -57,11 +58,17 @@ export const DeleteWorkspaceModal: React.FC = observer((props) => { await workspaceStore .deleteWorkspace(data.slug) - .then(() => { + .then((res) => { handleClose(); - + console.log('DELETE WORKPSACE', res); router.push("/"); - + const payload = { + slug: data.slug + }; + trackEvent( + 'DELETE_WORKSPACE', + payload + ); setToastAlert({ type: "success", title: "Success!", diff --git a/web/components/workspace/settings/workspace-details.tsx b/web/components/workspace/settings/workspace-details.tsx index 69034b201..e4a2bbac6 100644 --- a/web/components/workspace/settings/workspace-details.tsx +++ b/web/components/workspace/settings/workspace-details.tsx @@ -18,6 +18,7 @@ import { Button, CustomSelect, Input, Spinner } from "@plane/ui"; import { IWorkspace } from "types"; // constants import { ORGANIZATION_SIZE } from "constants/workspace"; +import { trackEvent } from "helpers/event-tracker.helper"; const defaultValues: Partial = { name: "", @@ -66,12 +67,17 @@ export const WorkspaceDetails: FC = observer(() => { }; await updateWorkspace(currentWorkspace.slug, payload) - .then(() => + .then((res) => { + trackEvent( + 'UPDATE_WORKSPACE', + res + ) setToastAlert({ title: "Success", type: "success", message: "Workspace updated successfully", }) + } ) .catch((err) => console.error(err)); }; @@ -83,7 +89,7 @@ export const WorkspaceDetails: FC = observer(() => { fileService.deleteFile(currentWorkspace.id, url).then(() => { updateWorkspace(currentWorkspace.slug, { logo: "" }) - .then(() => { + .then((res) => { setToastAlert({ type: "success", title: "Success!", diff --git a/web/constants/crisp.tsx b/web/constants/crisp.tsx deleted file mode 100644 index 90dfda7c7..000000000 --- a/web/constants/crisp.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { useCallback, useEffect } from "react"; -import { observer } from "mobx-react-lite"; -// hooks -import { useMobxStore } from "lib/mobx/store-provider"; - -declare global { - interface Window { - $crisp: any; - CRISP_WEBSITE_ID: any; - } -} - -const Crisp = observer(() => { - const { - user: { currentUser }, - } = useMobxStore(); - - const validateCurrentUser = useCallback(() => { - if (currentUser) return currentUser.email; - return null; - }, [currentUser]); - - useEffect(() => { - if (typeof window && validateCurrentUser()) { - window.$crisp = []; - window.CRISP_WEBSITE_ID = process.env.NEXT_PUBLIC_CRISP_ID; - (function () { - var d = document; - var s = d.createElement("script"); - s.src = "https://client.crisp.chat/l.js"; - s.async = true; - d.getElementsByTagName("head")[0].appendChild(s); - // defining email when logged in - if (validateCurrentUser()) { - window.$crisp.push(["set", "user:email", [validateCurrentUser()]]); - window.$crisp.push(["do", "chat:hide"]); - window.$crisp.push(["do", "chat:close"]); - } - })(); - } - }, [validateCurrentUser]); - - return <>; -}); -export default Crisp; diff --git a/web/contexts/issue-view.context.tsx b/web/contexts/issue-view.context.tsx index c64dcf194..867f87b57 100644 --- a/web/contexts/issue-view.context.tsx +++ b/web/contexts/issue-view.context.tsx @@ -8,10 +8,8 @@ import { ProjectService, ProjectMemberService } from "services/project"; import { CycleService } from "services/cycle.service"; import { ModuleService } from "services/module.service"; import { ViewService } from "services/view.service"; -// hooks -import useUserAuth from "hooks/use-user-auth"; // types -import { IIssueFilterOptions, IProjectMember, IUser, IIssueDisplayFilterOptions, IProjectViewProps } from "types"; +import { IIssueFilterOptions, IProjectMember, IIssueDisplayFilterOptions, IProjectViewProps } from "types"; // fetch-keys import { CYCLE_DETAILS, MODULE_DETAILS, USER_PROJECT_VIEW, VIEW_DETAILS } from "constants/fetch-keys"; @@ -134,58 +132,22 @@ const saveDataToServer = async (workspaceSlug: string, projectId: string, state: }); }; -const saveCycleFilters = async ( - workspaceSlug: string, - projectId: string, - cycleId: string, - state: any, - user: IUser | undefined -) => { - await cycleService.patchCycle( - workspaceSlug, - projectId, - cycleId, - { - ...state, - }, - user - ); +const saveCycleFilters = async (workspaceSlug: string, projectId: string, cycleId: string, state: any) => { + await cycleService.patchCycle(workspaceSlug, projectId, cycleId, { + ...state, + }); }; -const saveModuleFilters = async ( - workspaceSlug: string, - projectId: string, - moduleId: string, - state: any, - user: IUser | undefined -) => { - await moduleService.patchModule( - workspaceSlug, - projectId, - moduleId, - { - ...state, - }, - user - ); +const saveModuleFilters = async (workspaceSlug: string, projectId: string, moduleId: string, state: any) => { + await moduleService.patchModule(workspaceSlug, projectId, moduleId, { + ...state, + }); }; -const saveViewFilters = async ( - workspaceSlug: string, - projectId: string, - viewId: string, - state: any, - user: IUser | undefined -) => { - await viewService.patchView( - workspaceSlug, - projectId, - viewId, - { - ...state, - }, - user - ); +const saveViewFilters = async (workspaceSlug: string, projectId: string, viewId: string, state: any) => { + await viewService.patchView(workspaceSlug, projectId, viewId, { + ...state, + }); }; const setNewDefault = async (workspaceSlug: string, projectId: string, state: any) => { @@ -214,8 +176,6 @@ export const IssueViewContextProvider: React.FC<{ children: React.ReactNode }> = const router = useRouter(); const { workspaceSlug, projectId, cycleId, moduleId, viewId } = router.query; - const { user } = useUserAuth(); - const { data: myViewProps, mutate: mutateMyViewProps } = useSWR( workspaceSlug && projectId ? USER_PROJECT_VIEW(projectId as string) : null, workspaceSlug && projectId @@ -342,20 +302,14 @@ export const IssueViewContextProvider: React.FC<{ children: React.ReactNode }> = }; }, false); - saveCycleFilters( - workspaceSlug.toString(), - projectId.toString(), - cycleId.toString(), - { - view_props: { - filters: { - ...state.filters, - ...property, - }, + saveCycleFilters(workspaceSlug.toString(), projectId.toString(), cycleId.toString(), { + view_props: { + filters: { + ...state.filters, + ...property, }, }, - user - ); + }); } else if (moduleId) { mutateModuleDetails((prevData: any) => { if (!prevData) return prevData; @@ -371,20 +325,14 @@ export const IssueViewContextProvider: React.FC<{ children: React.ReactNode }> = }; }, false); - saveModuleFilters( - workspaceSlug.toString(), - projectId.toString(), - moduleId.toString(), - { - view_props: { - filters: { - ...state.filters, - ...property, - }, + saveModuleFilters(workspaceSlug.toString(), projectId.toString(), moduleId.toString(), { + view_props: { + filters: { + ...state.filters, + ...property, }, }, - user - ); + }); } else if (viewId) { mutateViewDetails((prevData: any) => { if (!prevData) return prevData; @@ -397,18 +345,12 @@ export const IssueViewContextProvider: React.FC<{ children: React.ReactNode }> = }; }, false); if (saveToServer) - saveViewFilters( - workspaceSlug as string, - projectId as string, - viewId as string, - { - query_data: { - ...state.filters, - ...property, - }, + saveViewFilters(workspaceSlug as string, projectId as string, viewId as string, { + query_data: { + ...state.filters, + ...property, }, - user - ); + }); } else { mutateMyViewProps((prevData: any) => { if (!prevData) return prevData; @@ -445,7 +387,6 @@ export const IssueViewContextProvider: React.FC<{ children: React.ReactNode }> = mutateModuleDetails, viewId, mutateViewDetails, - user, ] ); diff --git a/web/helpers/event-tracker.helper.ts b/web/helpers/event-tracker.helper.ts new file mode 100644 index 000000000..7b3a613e8 --- /dev/null +++ b/web/helpers/event-tracker.helper.ts @@ -0,0 +1,13 @@ +import posthog from "posthog-js"; + +export const trackEvent = (eventName: string, payload: object | [] | null = null) => { + try { + console.log(eventName); + posthog?.capture(eventName, { + ...payload, + }); + console.log(payload); + } catch (error) { + console.log(error); + } +}; diff --git a/web/helpers/user.helper.ts b/web/helpers/user.helper.ts new file mode 100644 index 000000000..569da6018 --- /dev/null +++ b/web/helpers/user.helper.ts @@ -0,0 +1,12 @@ +export const getUserRole = (role: number) => { + switch (role) { + case 5: + return "GUEST"; + case 10: + return "VIEWER"; + case 15: + return "MEMBER"; + case 20: + return "ADMIN"; + } +}; diff --git a/web/hooks/use-comment-reaction.tsx b/web/hooks/use-comment-reaction.tsx index af1d0a90f..db21db17a 100644 --- a/web/hooks/use-comment-reaction.tsx +++ b/web/hooks/use-comment-reaction.tsx @@ -1,5 +1,4 @@ import useSWR from "swr"; - // fetch keys import { COMMENT_REACTION_LIST } from "constants/fetch-keys"; // services @@ -52,8 +51,7 @@ const useCommentReaction = ( workspaceSlug.toString(), projectId.toString(), commendId.toString(), - { reaction }, - user.user + { reaction } ); mutateCommentReactions((prev: any) => [...(prev || []), data]); @@ -77,8 +75,7 @@ const useCommentReaction = ( workspaceSlug.toString(), projectId.toString(), commendId.toString(), - reaction, - user.user + reaction ); mutateCommentReactions(); diff --git a/web/hooks/use-issue-reaction.tsx b/web/hooks/use-issue-reaction.tsx index c4ea210de..8ed0cd695 100644 --- a/web/hooks/use-issue-reaction.tsx +++ b/web/hooks/use-issue-reaction.tsx @@ -47,8 +47,7 @@ const useIssueReaction = ( workspaceSlug.toString(), projectId.toString(), issueId.toString(), - { reaction }, - user.user + { reaction } ); mutateReaction((prev: any) => [...(prev || []), data]); @@ -72,8 +71,7 @@ const useIssueReaction = ( workspaceSlug.toString(), projectId.toString(), issueId.toString(), - reaction, - user.user + reaction ); mutateReaction(); diff --git a/web/lib/app-provider.tsx b/web/lib/app-provider.tsx new file mode 100644 index 000000000..3a822401c --- /dev/null +++ b/web/lib/app-provider.tsx @@ -0,0 +1,46 @@ +import { FC, ReactNode } from "react"; +import dynamic from "next/dynamic"; +import Router from "next/router"; +import NProgress from "nprogress"; +import { observer } from "mobx-react-lite"; +// mobx store provider +import { useMobxStore } from "lib/mobx/store-provider"; +// dynamic imports +const StoreWrapper = dynamic(() => import("lib/wrappers/store-wrapper"), { ssr: false }); +const PosthogWrapper = dynamic(() => import("lib/wrappers/posthog-wrapper"), { ssr: false }); +const CrispWrapper = dynamic(() => import("lib/wrappers/crisp-wrapper"), { ssr: false }); + +// nprogress +NProgress.configure({ showSpinner: false }); +Router.events.on("routeChangeStart", NProgress.start); +Router.events.on("routeChangeError", NProgress.done); +Router.events.on("routeChangeComplete", NProgress.done); + +export interface IAppProvider { + children: ReactNode; +} + +export const AppProvider: FC = observer((props) => { + const { children } = props; + // store + const { + user: { currentUser, currentWorkspaceRole, currentProjectRole }, + appConfig: { envConfig }, + } = useMobxStore(); + + return ( + + + + {children} + + + + ); +}); diff --git a/web/lib/auth.ts b/web/lib/auth.ts deleted file mode 100644 index 6f84db402..000000000 --- a/web/lib/auth.ts +++ /dev/null @@ -1,195 +0,0 @@ -// cookies -import { convertCookieStringToObject } from "./cookie"; -// types -import type { IProjectMember, IUser, IWorkspace, IWorkspaceMember } from "types"; -// helper -import { API_BASE_URL } from "helpers/common.helper"; - -export const requiredAuth = async (cookie?: string) => { - const cookies = convertCookieStringToObject(cookie); - const token = cookies?.accessToken; - - if (!token) return null; - - let user: IUser | null = null; - - try { - const data = await fetch(`${API_BASE_URL}/api/users/me/`, { - method: "GET", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${token}`, - }, - }) - .then((res) => res.json()) - .then((data) => data); - - user = data.user; - } catch (err) { - console.error(err); - user = null; - } - - return user; -}; - -export const requiredAdmin = async (workspaceSlug: string, projectId: string, cookie?: string) => { - const user = await requiredAuth(cookie); - - if (!user) return null; - - const cookies = convertCookieStringToObject(cookie); - const token = cookies?.accessToken; - - let memberDetail: IProjectMember | null = null; - - try { - const data = await fetch( - `${API_BASE_URL}/api/workspaces/${workspaceSlug}/projects/${projectId}/project-members/me/`, - { - method: "GET", - headers: { - Authorization: `Bearer ${token}`, - }, - } - ) - .then((res) => res.json()) - .then((data) => data); - - memberDetail = data; - } catch (err) { - console.error(err); - memberDetail = null; - } - - return memberDetail || null; -}; - -export const requiredWorkspaceAdmin = async (workspaceSlug: string, cookie?: string) => { - const user = await requiredAuth(cookie); - - if (!user) return null; - - const cookies = convertCookieStringToObject(cookie); - const token = cookies?.accessToken; - - let memberDetail: IWorkspaceMember | null = null; - - try { - const data = await fetch(`${API_BASE_URL}/api/workspaces/${workspaceSlug}/workspace-members/me/`, { - method: "GET", - headers: { - Authorization: `Bearer ${token}`, - }, - }) - .then((res) => res.json()) - .then((data) => data); - - memberDetail = data; - } catch (err) { - console.error(err); - memberDetail = null; - } - - return memberDetail || null; -}; - -export const homePageRedirect = async (cookie?: string) => { - const user = await requiredAuth(cookie); - - if (!user) - return { - redirect: { - destination: "/", - permanent: false, - }, - }; - - if (!user.is_onboarded) - return { - redirect: { - destination: "/onboarding", - permanent: false, - }, - }; - - let workspaces: IWorkspace[] = []; - - const cookies = convertCookieStringToObject(cookie); - const token = cookies?.accessToken; - - try { - const data = await fetch(`${API_BASE_URL}/api/users/me/workspaces/`, { - method: "GET", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${token}`, - }, - }) - .then((res) => res.json()) - .then((data) => data); - - workspaces = data; - } catch (e) { - console.error(e); - return { - redirect: { - destination: "/error", - permanent: false, - }, - }; - } - - const lastActiveWorkspace = workspaces.find((workspace) => workspace.id === user.last_workspace_id); - - if (lastActiveWorkspace) { - return { - redirect: { - destination: `/${lastActiveWorkspace.slug}`, - permanent: false, - }, - }; - } else if (workspaces.length > 0) { - return { - redirect: { - destination: `/${workspaces[0].slug}`, - permanent: false, - }, - }; - } - - const invitations = await fetch(`${API_BASE_URL}/api/users/me/invitations/workspaces/`, { - method: "GET", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${token}`, - }, - }) - .then((res) => res.json()) - .then((data) => data) - .catch((e) => { - console.error(e); - return { - redirect: { - destination: "/error", - permanent: false, - }, - }; - }); - - if (invitations.length > 0) - return { - redirect: { - destination: "/invitations", - permanent: false, - }, - }; - else { - return { - redirect: { - destination: "/create-workspace", - permanent: false, - }, - }; - } -}; diff --git a/web/lib/cookie.ts b/web/lib/cookie.ts deleted file mode 100644 index 394cca3f4..000000000 --- a/web/lib/cookie.ts +++ /dev/null @@ -1,16 +0,0 @@ -export const convertCookieStringToObject = (cookieHeader: string | undefined) => { - const list: any = {}; - if (!cookieHeader) return list; - - cookieHeader.split(`;`).forEach(function (cookie) { - // eslint-disable-next-line prefer-const - let [name, ...rest] = cookie.split(`=`); - name = name?.trim(); - if (!name) return; - const value = rest.join(`=`).trim(); - if (!value) return; - list[name] = decodeURIComponent(value); - }); - - return list; -}; diff --git a/web/lib/wrappers/crisp-wrapper.tsx b/web/lib/wrappers/crisp-wrapper.tsx new file mode 100644 index 000000000..87480dfaa --- /dev/null +++ b/web/lib/wrappers/crisp-wrapper.tsx @@ -0,0 +1,40 @@ +import { useEffect, ReactNode, FC } from "react"; +// hooks +import { IUser } from "types"; + +declare global { + interface Window { + $crisp: any; + CRISP_WEBSITE_ID: any; + } +} + +export interface ICrispWrapper { + children: ReactNode; + user: IUser | null; +} + +const CrispWrapper: FC = (props) => { + const { children, user } = props; + + useEffect(() => { + if (typeof window && user?.email) { + window.$crisp = []; + window.CRISP_WEBSITE_ID = process.env.NEXT_PUBLIC_CRISP_ID; + (function () { + var d = document; + var s = d.createElement("script"); + s.src = "https://client.crisp.chat/l.js"; + s.async = true; + d.getElementsByTagName("head")[0].appendChild(s); + window.$crisp.push(["set", "user:email", [user.email]]); + window.$crisp.push(["do", "chat:hide"]); + window.$crisp.push(["do", "chat:close"]); + })(); + } + }, [user?.email]); + + return <>{children}; +}; + +export default CrispWrapper; diff --git a/web/lib/wrappers/posthog-wrapper.tsx b/web/lib/wrappers/posthog-wrapper.tsx new file mode 100644 index 000000000..1e7c35c0d --- /dev/null +++ b/web/lib/wrappers/posthog-wrapper.tsx @@ -0,0 +1,72 @@ +import { FC, ReactNode, useEffect } from "react"; +import { useRouter } from "next/router"; +import posthog from "posthog-js"; +import { PostHogProvider } from "posthog-js/react"; +// mobx store provider +import { IUser } from "types"; +// helpers +import { getUserRole } from "helpers/user.helper"; + +export interface IPosthogWrapper { + children: ReactNode; + user: IUser | null; + workspaceRole: number | undefined; + projectRole: number | undefined; + posthogAPIKey: string | null; + posthogHost: string | null; +} + +const PosthogWrapper: FC = (props) => { + const { children, user, workspaceRole, projectRole, posthogAPIKey, posthogHost } = props; + // router + const router = useRouter(); + + useEffect(() => { + if (user) { + // Identify sends an event, so you want may want to limit how often you call it + posthog?.identify(user.email, { + email: user.email, + first_name: user.first_name, + last_name: user.last_name, + id: user.id, + workspace_role: workspaceRole ? getUserRole(workspaceRole) : undefined, + project_role: projectRole ? getUserRole(projectRole) : undefined, + }); + } + }, [user, workspaceRole, projectRole]); + + useEffect(() => { + if (posthogAPIKey && posthogHost) { + posthog.init(posthogAPIKey, { + api_host: posthogHost || "https://app.posthog.com", + // Enable debug mode in development + loaded: (posthog) => { + if (process.env.NODE_ENV === "development") posthog.debug(); + }, + autocapture: false, + capture_pageview: false, // Disable automatic pageview capture, as we capture manually + }); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + // Track page views + const handleRouteChange = () => { + posthog?.capture("$pageview"); + }; + router.events.on("routeChangeComplete", handleRouteChange); + + return () => { + router.events.off("routeChangeComplete", handleRouteChange); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + if (posthogAPIKey) { + return {children}; + } + return <>{children}; +}; + +export default PosthogWrapper; diff --git a/web/lib/mobx/store-init.tsx b/web/lib/wrappers/store-wrapper.tsx similarity index 91% rename from web/lib/mobx/store-init.tsx rename to web/lib/wrappers/store-wrapper.tsx index f89aa72c7..cec08f158 100644 --- a/web/lib/mobx/store-init.tsx +++ b/web/lib/wrappers/store-wrapper.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { ReactNode, useEffect, useState, FC } from "react"; import { observer } from "mobx-react-lite"; import useSWR from "swr"; import { useTheme } from "next-themes"; @@ -8,7 +8,12 @@ import { useMobxStore } from "lib/mobx/store-provider"; // helpers import { applyTheme, unsetCustomCssVariables } from "helpers/theme.helper"; -const MobxStoreInit = observer(() => { +interface IStoreWrapper { + children: ReactNode; +} + +const StoreWrapper: FC = observer((props) => { + const { children } = props; // router const router = useRouter(); const { workspaceSlug, projectId, cycleId, moduleId, globalViewId, viewId, inboxId } = router.query; @@ -86,7 +91,7 @@ const MobxStoreInit = observer(() => { setInboxId, ]); - return <>; + return <>{children}; }); -export default MobxStoreInit; +export default StoreWrapper; diff --git a/web/package.json b/web/package.json index b2791978f..9657cdd68 100644 --- a/web/package.json +++ b/web/package.json @@ -41,6 +41,7 @@ "next-pwa": "^5.6.0", "next-themes": "^0.2.1", "nprogress": "^0.2.0", + "posthog-js": "^1.88.4", "react": "18.2.0", "react-color": "^2.19.3", "react-datepicker": "^4.8.0", diff --git a/web/pages/[workspaceSlug]/analytics.tsx b/web/pages/[workspaceSlug]/analytics.tsx index a71904e67..839991af0 100644 --- a/web/pages/[workspaceSlug]/analytics.tsx +++ b/web/pages/[workspaceSlug]/analytics.tsx @@ -1,11 +1,8 @@ -import React, { Fragment, useEffect, ReactElement } from "react"; -import { useRouter } from "next/router"; +import React, { Fragment, ReactElement } from "react"; import { observer } from "mobx-react-lite"; import { Tab } from "@headlessui/react"; // mobx store import { useMobxStore } from "lib/mobx/store-provider"; -// services -import { TrackEventService } from "services/track_event.service"; // layouts import { AppLayout } from "layouts/app-layout"; // components @@ -21,40 +18,13 @@ import { ANALYTICS_TABS } from "constants/analytics"; // type import { NextPageWithLayout } from "types/app"; -const trackEventService = new TrackEventService(); - const AnalyticsPage: NextPageWithLayout = observer(() => { - // router - const router = useRouter(); - const { workspaceSlug } = router.query; // store const { project: { workspaceProjects }, - user: { currentUser }, commandPalette: { toggleCreateProjectModal }, } = useMobxStore(); - const trackAnalyticsEvent = (tab: string) => { - if (!currentUser) return; - const eventPayload = { - workspaceSlug: workspaceSlug?.toString(), - }; - const eventType = - tab === "scope_and_demand" ? "WORKSPACE_SCOPE_AND_DEMAND_ANALYTICS" : "WORKSPACE_CUSTOM_ANALYTICS"; - trackEventService.trackAnalyticsEvent(eventPayload, eventType, currentUser); - }; - - useEffect(() => { - if (!workspaceSlug) return; - - if (currentUser && workspaceSlug) - trackEventService.trackAnalyticsEvent( - { workspaceSlug: workspaceSlug?.toString() }, - "WORKSPACE_SCOPE_AND_DEMAND_ANALYTICS", - currentUser - ); - }, [currentUser, workspaceSlug]); - return ( <> {workspaceProjects && workspaceProjects.length > 0 ? ( @@ -69,7 +39,7 @@ const AnalyticsPage: NextPageWithLayout = observer(() => { selected ? "bg-custom-background-80" : "" }` } - onClick={() => trackAnalyticsEvent(tab.key)} + onClick={() => {}} > {tab.title} diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/[archivedIssueId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/[archivedIssueId].tsx index cf0987edb..b02585182 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/[archivedIssueId].tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/[archivedIssueId].tsx @@ -5,7 +5,6 @@ import { useForm } from "react-hook-form"; // services import { IssueService, IssueArchiveService } from "services/issue"; // hooks -import useUserAuth from "hooks/use-user-auth"; import useToast from "hooks/use-toast"; // layouts import { AppLayout } from "layouts/app-layout"; @@ -45,7 +44,6 @@ const ArchivedIssueDetailsPage: NextPageWithLayout = () => { // states const [isRestoring, setIsRestoring] = useState(false); // hooks - const { user } = useUserAuth(); const { setToastAlert } = useToast(); const { data: issueDetails, mutate: mutateIssueDetails } = useSWR( @@ -86,7 +84,7 @@ const ArchivedIssueDetailsPage: NextPageWithLayout = () => { }; await issueService - .patchIssue(workspaceSlug as string, projectId as string, archivedIssueId as string, payload, user) + .patchIssue(workspaceSlug as string, projectId as string, archivedIssueId as string, payload) .then(() => { mutateIssueDetails(); mutate(PROJECT_ISSUES_ACTIVITY(archivedIssueId as string)); @@ -95,7 +93,7 @@ const ArchivedIssueDetailsPage: NextPageWithLayout = () => { console.error(e); }); }, - [workspaceSlug, archivedIssueId, projectId, mutateIssueDetails, user] + [workspaceSlug, archivedIssueId, projectId, mutateIssueDetails] ); useEffect(() => { diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx index a4e1eb296..c1314b414 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx @@ -22,6 +22,7 @@ import { NextPageWithLayout } from "types/app"; import { CYCLE_TAB_LIST, CYCLE_VIEW_LAYOUTS } from "constants/cycle"; // lib cookie import { setLocalStorage, getLocalStorage } from "lib/local-storage"; +// TODO: use-local-storage hook instead of lib file. const ProjectCyclesPage: NextPageWithLayout = observer(() => { const [createModal, setCreateModal] = useState(false); diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx index 32c11345e..753244628 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx @@ -4,8 +4,6 @@ import useSWR, { mutate } from "swr"; import { useForm } from "react-hook-form"; // services import { IssueService } from "services/issue"; -// hooks -import useUserAuth from "hooks/use-user-auth"; // layouts import { AppLayout } from "layouts/app-layout"; // components @@ -43,8 +41,6 @@ const IssueDetailsPage: NextPageWithLayout = () => { const router = useRouter(); const { workspaceSlug, projectId, issueId } = router.query; - const { user } = useUserAuth(); - const { data: issueDetails, mutate: mutateIssueDetails, @@ -85,7 +81,7 @@ const IssueDetailsPage: NextPageWithLayout = () => { delete payload.issue_relations; await issueService - .patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload, user) + .patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload) .then(() => { mutateIssueDetails(); mutate(PROJECT_ISSUES_ACTIVITY(issueId as string)); @@ -94,7 +90,7 @@ const IssueDetailsPage: NextPageWithLayout = () => { console.error(e); }); }, - [workspaceSlug, issueId, projectId, mutateIssueDetails, user] + [workspaceSlug, issueId, projectId, mutateIssueDetails] ); useEffect(() => { diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/pages/[pageId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/pages/[pageId].tsx index dd1efde15..e64bb628e 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/pages/[pageId].tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/pages/[pageId].tsx @@ -105,18 +105,16 @@ const PageDetailsPage: NextPageWithLayout = () => { if (!formData.name || formData.name.length === 0 || formData.name === "") return; - await pageService - .patchPage(workspaceSlug as string, projectId as string, pageId as string, formData, user) - .then(() => { - mutate( - PAGE_DETAILS(pageId as string), - (prevData) => ({ - ...prevData, - ...formData, - }), - false - ); - }); + await pageService.patchPage(workspaceSlug as string, projectId as string, pageId as string, formData).then(() => { + mutate( + PAGE_DETAILS(pageId as string), + (prevData) => ({ + ...prevData, + ...formData, + }), + false + ); + }); }; const partialUpdatePage = async (formData: Partial) => { @@ -131,11 +129,9 @@ const PageDetailsPage: NextPageWithLayout = () => { false ); - await pageService - .patchPage(workspaceSlug as string, projectId as string, pageId as string, formData, user) - .then(() => { - mutate(PAGE_DETAILS(pageId as string)); - }); + await pageService.patchPage(workspaceSlug as string, projectId as string, pageId as string, formData).then(() => { + mutate(PAGE_DETAILS(pageId as string)); + }); }; const handleAddToFavorites = () => { @@ -209,16 +205,9 @@ const PageDetailsPage: NextPageWithLayout = () => { false ); - pageService.patchPageBlock( - workspaceSlug as string, - projectId as string, - pageId as string, - result.draggableId, - { - sort_order: newSortOrder, - }, - user - ); + pageService.patchPageBlock(workspaceSlug as string, projectId as string, pageId as string, result.draggableId, { + sort_order: newSortOrder, + }); }; const handleCopyText = () => { diff --git a/web/pages/[workspaceSlug]/settings/members.tsx b/web/pages/[workspaceSlug]/settings/members.tsx index 303c0a9d1..93aba3db1 100644 --- a/web/pages/[workspaceSlug]/settings/members.tsx +++ b/web/pages/[workspaceSlug]/settings/members.tsx @@ -17,6 +17,7 @@ import { Search } from "lucide-react"; // types import { NextPageWithLayout } from "types/app"; import { IWorkspaceBulkInviteFormData } from "types"; +import { trackEvent } from "helpers/event-tracker.helper"; const WorkspaceMembersSettingsPage: NextPageWithLayout = observer(() => { const router = useRouter(); @@ -35,21 +36,23 @@ const WorkspaceMembersSettingsPage: NextPageWithLayout = observer(() => { if (!workspaceSlug) return; return inviteMembersToWorkspace(workspaceSlug.toString(), data) - .then(async () => { + .then(async (res) => { setInviteModal(false); + trackEvent("WORKSPACE_USER_INVITE"); setToastAlert({ type: "success", title: "Success!", message: "Invitations sent successfully.", }); }) - .catch((err) => + .catch((err) => { + trackEvent("WORKSPACE_USER_INVITE/FAIL"); setToastAlert({ type: "error", title: "Error!", message: `${err.error ?? "Something went wrong. Please try again."}`, - }) - ); + }); + }); }; return ( diff --git a/web/pages/_app.tsx b/web/pages/_app.tsx index d4dca452a..9f2cf995b 100644 --- a/web/pages/_app.tsx +++ b/web/pages/_app.tsx @@ -1,10 +1,7 @@ import { ReactElement } from "react"; import Head from "next/head"; -import dynamic from "next/dynamic"; -import Router from "next/router"; import { AppProps } from "next/app"; import { ThemeProvider } from "next-themes"; -import NProgress from "nprogress"; // styles import "styles/globals.css"; import "styles/editor.css"; @@ -19,18 +16,10 @@ import { THEMES } from "constants/themes"; import { SITE_TITLE } from "constants/seo-variables"; // mobx store provider import { MobxStoreProvider } from "lib/mobx/store-provider"; -import MobxStoreInit from "lib/mobx/store-init"; +import { AppProvider } from "lib/app-provider"; // types import { NextPageWithLayout } from "types/app"; -const CrispWithNoSSR = dynamic(() => import("constants/crisp"), { ssr: false }); - -// nprogress -NProgress.configure({ showSpinner: false }); -Router.events.on("routeChangeStart", NProgress.start); -Router.events.on("routeChangeError", NProgress.done); -Router.events.on("routeChangeComplete", NProgress.done); - type AppPropsWithLayout = AppProps & { Component: NextPageWithLayout; }; @@ -47,9 +36,7 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) { - - - {getLayout()} + {getLayout()} diff --git a/web/pages/api/track-event.ts b/web/pages/api/track-event.ts deleted file mode 100644 index 4928c552e..000000000 --- a/web/pages/api/track-event.ts +++ /dev/null @@ -1,34 +0,0 @@ -import type { NextApiRequest, NextApiResponse } from "next"; -// jitsu -import { createClient } from "@jitsu/nextjs"; - -const jitsuClient = createClient({ - key: process.env.JITSU_TRACKER_ACCESS_KEY || "", - tracking_host: process.env.JITSU_TRACKER_HOST || "", -}); - -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - const { eventName, user, extra } = req.body; - - if (!eventName) { - return res.status(400).json({ message: "Bad request" }); - } - - if (!user) return res.status(401).json({ message: "Unauthorized" }); - - jitsuClient - .id({ - id: user?.id, - email: user?.email, - first_name: user?.first_name, - last_name: user?.last_name, - display_name: user?.display_name, - }) - .then(() => { - jitsuClient.track(eventName, { - ...extra, - }); - }); - - res.status(200).json({ message: "success" }); -} diff --git a/web/pages/api/unsplash.ts b/web/pages/api/unsplash.ts deleted file mode 100644 index 11acb2096..000000000 --- a/web/pages/api/unsplash.ts +++ /dev/null @@ -1,26 +0,0 @@ -import axios from "axios"; -import type { NextApiRequest, NextApiResponse } from "next"; - -const unsplashKey = process.env.UNSPLASH_ACCESS_KEY; - -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - try { - const { query, page, per_page = 20 } = req.query; - - const url = query - ? `https://api.unsplash.com/search/photos/?client_id=${unsplashKey}&query=${query}&page=${page}&per_page=${per_page}` - : `https://api.unsplash.com/photos/?client_id=${unsplashKey}&page=${page}&per_page=${per_page}`; - - const response = await axios({ - method: "GET", - url, - headers: { - "Content-Type": "application/json", - }, - }); - - res.status(200).json(response?.data); - } catch (error) { - res.status(500).json({ message: "Failed to fetch unsplash", error }); - } -} diff --git a/web/pages/workspace-invitations/index.tsx b/web/pages/workspace-invitations/index.tsx index c2d3bd9e2..784dc166f 100644 --- a/web/pages/workspace-invitations/index.tsx +++ b/web/pages/workspace-invitations/index.tsx @@ -36,15 +36,10 @@ const WorkspaceInvitationPage: NextPageWithLayout = () => { const handleAccept = () => { if (!invitationDetail) return; workspaceService - .joinWorkspace( - invitationDetail.workspace.slug, - invitationDetail.id, - { - accepted: true, - email: invitationDetail.email, - }, - user - ) + .joinWorkspace(invitationDetail.workspace.slug, invitationDetail.id, { + accepted: true, + email: invitationDetail.email, + }) .then(() => { if (email === user?.email) { router.push("/invitations"); diff --git a/web/services/ai.service.ts b/web/services/ai.service.ts index 63bf02ee4..363da51ed 100644 --- a/web/services/ai.service.ts +++ b/web/services/ai.service.ts @@ -1,12 +1,9 @@ import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // types -import { IUser, IGptResponse } from "types"; +import { IGptResponse } from "types"; // helpers import { API_BASE_URL } from "helpers/common.helper"; -const trackEventService = new TrackEventService(); - export class AIService extends APIService { constructor() { super(API_BASE_URL); @@ -15,14 +12,10 @@ export class AIService extends APIService { async createGptTask( workspaceSlug: string, projectId: string, - data: { prompt: string; task: string }, - user: IUser | undefined + data: { prompt: string; task: string } ): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/ai-assistant/`, data) - .then((response) => { - trackEventService.trackAskGptEvent(response?.data, "ASK_GPT", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response; }); diff --git a/web/services/cycle.service.ts b/web/services/cycle.service.ts index 2e8b0b998..892d8fb1b 100644 --- a/web/services/cycle.service.ts +++ b/web/services/cycle.service.ts @@ -1,24 +1,18 @@ // services import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // types -import type { CycleDateCheckData, IUser, ICycle, IIssue } from "types"; +import type { CycleDateCheckData, ICycle, IIssue } from "types"; // helpers import { API_BASE_URL } from "helpers/common.helper"; -const trackEventService = new TrackEventService(); - export class CycleService extends APIService { constructor() { super(API_BASE_URL); } - async createCycle(workspaceSlug: string, projectId: string, data: any, user: any): Promise { + async createCycle(workspaceSlug: string, projectId: string, data: any): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/cycles/`, data) - .then((response) => { - trackEventService.trackCycleEvent(response?.data, "CYCLE_CREATE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); @@ -71,29 +65,17 @@ export class CycleService extends APIService { }); } - async patchCycle( - workspaceSlug: string, - projectId: string, - cycleId: string, - data: Partial, - user: IUser | undefined - ): Promise { + async patchCycle(workspaceSlug: string, projectId: string, cycleId: string, data: Partial): Promise { return this.patch(`/api/workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/`, data) - .then((response) => { - if (user) trackEventService.trackCycleEvent(response?.data, "CYCLE_UPDATE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async deleteCycle(workspaceSlug: string, projectId: string, cycleId: string, user: IUser | undefined): Promise { + async deleteCycle(workspaceSlug: string, projectId: string, cycleId: string): Promise { return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/`) - .then((response) => { - trackEventService.trackCycleEvent(response?.data, "CYCLE_DELETE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/services/inbox.service.ts b/web/services/inbox.service.ts index 05b19aa41..3cde8ffff 100644 --- a/web/services/inbox.service.ts +++ b/web/services/inbox.service.ts @@ -1,11 +1,8 @@ import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // helpers import { API_BASE_URL } from "helpers/common.helper"; // types -import type { IInboxIssue, IInbox, TInboxStatus, IUser, IInboxQueryParams } from "types"; - -const trackEventService = new TrackEventService(); +import type { IInboxIssue, IInbox, TInboxStatus, IInboxQueryParams } from "types"; export class InboxService extends APIService { constructor() { @@ -70,16 +67,12 @@ export class InboxService extends APIService { workspaceSlug: string, projectId: string, inboxId: string, - inboxIssueId: string, - user: IUser | undefined + inboxIssueId: string ): Promise { return this.delete( `/api/workspaces/${workspaceSlug}/projects/${projectId}/inboxes/${inboxId}/inbox-issues/${inboxIssueId}/` ) - .then((response) => { - if (user) trackEventService.trackInboxEvent(response?.data, "INBOX_ISSUE_DELETE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); @@ -90,25 +83,13 @@ export class InboxService extends APIService { projectId: string, inboxId: string, inboxIssueId: string, - data: TInboxStatus, - user: IUser | undefined + data: TInboxStatus ): Promise { return this.patch( `/api/workspaces/${workspaceSlug}/projects/${projectId}/inboxes/${inboxId}/inbox-issues/${inboxIssueId}/`, data ) - .then((response) => { - const action = - data.status === -1 - ? "INBOX_ISSUE_REJECTED" - : data.status === 0 - ? "INBOX_ISSUE_SNOOZED" - : data.status === 1 - ? "INBOX_ISSUE_ACCEPTED" - : "INBOX_ISSUE_DUPLICATED"; - trackEventService.trackInboxEvent(response?.data, action, user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); @@ -119,34 +100,21 @@ export class InboxService extends APIService { projectId: string, inboxId: string, inboxIssueId: string, - data: { issue: Partial }, - user: IUser | undefined + data: { issue: Partial } ): Promise { return this.patch( `/api/workspaces/${workspaceSlug}/projects/${projectId}/inboxes/${inboxId}/inbox-issues/${inboxIssueId}/`, data ) - .then((response) => { - if (user) trackEventService.trackInboxEvent(response?.data, "INBOX_ISSUE_UPDATE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async createInboxIssue( - workspaceSlug: string, - projectId: string, - inboxId: string, - data: any, - user: IUser | undefined - ): Promise { + async createInboxIssue(workspaceSlug: string, projectId: string, inboxId: string, data: any): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/inboxes/${inboxId}/inbox-issues/`, data) - .then((response) => { - if (user) trackEventService.trackInboxEvent(response?.data, "INBOX_ISSUE_CREATE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/services/integrations/github.service.ts b/web/services/integrations/github.service.ts index bec6101e5..c69f8bd7e 100644 --- a/web/services/integrations/github.service.ts +++ b/web/services/integrations/github.service.ts @@ -1,14 +1,11 @@ import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // helpers import { API_BASE_URL } from "helpers/common.helper"; // types -import { IUser, IGithubRepoInfo, IGithubServiceImportFormData } from "types"; +import { IGithubRepoInfo, IGithubServiceImportFormData } from "types"; const integrationServiceType: string = "github"; -const trackEventService = new TrackEventService(); - export class GithubIntegrationService extends APIService { constructor() { super(API_BASE_URL); @@ -32,16 +29,9 @@ export class GithubIntegrationService extends APIService { }); } - async createGithubServiceImport( - workspaceSlug: string, - data: IGithubServiceImportFormData, - user: IUser | undefined - ): Promise { + async createGithubServiceImport(workspaceSlug: string, data: IGithubServiceImportFormData): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/importers/${integrationServiceType}/`, data) - .then((response) => { - trackEventService.trackImporterEvent(response?.data, "GITHUB_IMPORTER_CREATE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/services/integrations/integration.service.ts b/web/services/integrations/integration.service.ts index e36ea4889..a6b4ae447 100644 --- a/web/services/integrations/integration.service.ts +++ b/web/services/integrations/integration.service.ts @@ -1,12 +1,9 @@ import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // types -import { IAppIntegration, IUser, IImporterService, IWorkspaceIntegration, IExportServiceResponse } from "types"; +import { IAppIntegration, IImporterService, IWorkspaceIntegration, IExportServiceResponse } from "types"; // helper import { API_BASE_URL } from "helpers/common.helper"; -const trackEventService = new TrackEventService(); - export class IntegrationService extends APIService { constructor() { super(API_BASE_URL); @@ -60,18 +57,9 @@ export class IntegrationService extends APIService { }); } - async deleteImporterService( - workspaceSlug: string, - service: string, - importerId: string, - user: IUser | undefined - ): Promise { + async deleteImporterService(workspaceSlug: string, service: string, importerId: string): Promise { return this.delete(`/api/workspaces/${workspaceSlug}/importers/${service}/${importerId}/`) - .then((response) => { - const eventName = service === "github" ? "GITHUB_IMPORTER_DELETE" : "JIRA_IMPORTER_DELETE"; - trackEventService.trackImporterEvent(response?.data, eventName, user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/services/integrations/jira.service.ts b/web/services/integrations/jira.service.ts index 744dc2b11..50deeecf8 100644 --- a/web/services/integrations/jira.service.ts +++ b/web/services/integrations/jira.service.ts @@ -1,10 +1,7 @@ import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; import { API_BASE_URL } from "helpers/common.helper"; // types -import { IJiraMetadata, IJiraResponse, IJiraImporterForm, IUser } from "types"; - -const trackEventService = new TrackEventService(); +import { IJiraMetadata, IJiraResponse, IJiraImporterForm } from "types"; export class JiraImporterService extends APIService { constructor() { @@ -21,16 +18,9 @@ export class JiraImporterService extends APIService { }); } - async createJiraImporter( - workspaceSlug: string, - data: IJiraImporterForm, - user: IUser | undefined - ): Promise { + async createJiraImporter(workspaceSlug: string, data: IJiraImporterForm): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/importers/jira/`, data) - .then((response) => { - trackEventService.trackImporterEvent(response?.data, "JIRA_IMPORTER_CREATE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/services/issue/issue.service.ts b/web/services/issue/issue.service.ts index 5f2844896..d1dba8ea3 100644 --- a/web/services/issue/issue.service.ts +++ b/web/services/issue/issue.service.ts @@ -1,24 +1,18 @@ // services import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // type -import type { IUser, IIssue, IIssueActivity, ISubIssueResponse, IIssueDisplayProperties } from "types"; +import type { IIssue, IIssueActivity, ISubIssueResponse, IIssueDisplayProperties } from "types"; // helper import { API_BASE_URL } from "helpers/common.helper"; -const trackEventService = new TrackEventService(); - export class IssueService extends APIService { constructor() { super(API_BASE_URL); } - async createIssue(workspaceSlug: string, projectId: string, data: any, user: IUser | undefined): Promise { + async createIssue(workspaceSlug: string, projectId: string, data: any): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/`, data) - .then((response) => { - trackEventService.trackIssueEvent(response.data, "ISSUE_CREATE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); @@ -68,26 +62,10 @@ export class IssueService extends APIService { cycleId: string, data: { issues: string[]; - }, - user: IUser | undefined + } ) { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/cycle-issues/`, data) - .then((response) => { - trackEventService.trackIssueMovedToCycleOrModuleEvent( - { - workspaceSlug, - workspaceName: response?.data?.[0]?.issue_detail?.workspace_detail?.name, - projectId, - projectIdentifier: response?.data?.[0]?.issue_detail?.project_detail?.identifier, - projectName: response?.data?.[0]?.issue_detail?.project_detail?.name, - issueId: response?.data?.[0]?.issue_detail?.id, - cycleId, - }, - response.data.length > 1 ? "ISSUE_MOVED_TO_CYCLE_IN_BULK" : "ISSUE_MOVED_TO_CYCLE", - user as IUser - ); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); @@ -107,7 +85,6 @@ export class IssueService extends APIService { workspaceSlug: string, projectId: string, issueId: string, - user: IUser, data: { related_list: Array<{ relation_type: "duplicate" | "relates_to" | "blocked_by"; @@ -117,29 +94,17 @@ export class IssueService extends APIService { } ) { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-relation/`, data) - .then((response) => { - trackEventService.trackIssueRelationEvent(response.data, "ISSUE_RELATION_CREATE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response; }); } - async deleteIssueRelation( - workspaceSlug: string, - projectId: string, - issueId: string, - relationId: string, - user: IUser - ) { + async deleteIssueRelation(workspaceSlug: string, projectId: string, issueId: string, relationId: string) { return this.delete( `/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-relation/${relationId}/` ) - .then((response) => { - trackEventService.trackIssueRelationEvent(response.data, "ISSUE_RELATION_DELETE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response; }); @@ -167,40 +132,25 @@ export class IssueService extends APIService { }); } - async patchIssue( - workspaceSlug: string, - projectId: string, - issueId: string, - data: Partial, - user: IUser | undefined - ): Promise { + async patchIssue(workspaceSlug: string, projectId: string, issueId: string, data: Partial): Promise { return this.patch(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/`, data) - .then((response) => { - trackEventService.trackIssueEvent(response.data, "ISSUE_UPDATE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async deleteIssue(workspaceSlug: string, projectId: string, issuesId: string, user: IUser | undefined): Promise { + async deleteIssue(workspaceSlug: string, projectId: string, issuesId: string): Promise { return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issuesId}/`) - .then((response) => { - trackEventService.trackIssueEvent({ issuesId }, "ISSUE_DELETE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async bulkDeleteIssues(workspaceSlug: string, projectId: string, data: any, user: IUser | undefined): Promise { + async bulkDeleteIssues(workspaceSlug: string, projectId: string, data: any): Promise { return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/bulk-delete-issues/`, data) - .then((response) => { - trackEventService.trackIssueBulkDeleteEvent(data, user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/services/issue/issue_comment.service.ts b/web/services/issue/issue_comment.service.ts index 12c08a517..3c2bb8669 100644 --- a/web/services/issue/issue_comment.service.ts +++ b/web/services/issue/issue_comment.service.ts @@ -1,12 +1,9 @@ import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // types -import { IIssueComment, IUser } from "types"; +import { IIssueComment } from "types"; // helper import { API_BASE_URL } from "helpers/common.helper"; -const trackEventService = new TrackEventService(); - export class IssueCommentService extends APIService { constructor() { super(API_BASE_URL); @@ -24,14 +21,10 @@ export class IssueCommentService extends APIService { workspaceSlug: string, projectId: string, issueId: string, - data: Partial, - user: IUser | undefined + data: Partial ): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/comments/`, data) - .then((response) => { - trackEventService.trackIssueCommentEvent(response.data, "ISSUE_COMMENT_CREATE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); @@ -42,43 +35,23 @@ export class IssueCommentService extends APIService { projectId: string, issueId: string, commentId: string, - data: Partial, - user: IUser | undefined + data: Partial ): Promise { return this.patch( `/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/comments/${commentId}/`, data ) - .then((response) => { - trackEventService.trackIssueCommentEvent(response.data, "ISSUE_COMMENT_UPDATE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async deleteIssueComment( - workspaceSlug: string, - projectId: string, - issueId: string, - commentId: string, - user: IUser | undefined - ): Promise { + async deleteIssueComment(workspaceSlug: string, projectId: string, issueId: string, commentId: string): Promise { return this.delete( `/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/comments/${commentId}/` ) - .then((response) => { - trackEventService.trackIssueCommentEvent( - { - issueId, - commentId, - }, - "ISSUE_COMMENT_DELETE", - user - ); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/services/issue/issue_label.service.ts b/web/services/issue/issue_label.service.ts index d6bab8348..dc55b1501 100644 --- a/web/services/issue/issue_label.service.ts +++ b/web/services/issue/issue_label.service.ts @@ -1,11 +1,8 @@ import { API_BASE_URL } from "helpers/common.helper"; // services import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // types -import { IIssueLabel, IUser } from "types"; - -const trackEventServices = new TrackEventService(); +import { IIssueLabel } from "types"; export class IssueLabelService extends APIService { constructor() { @@ -28,83 +25,25 @@ export class IssueLabelService extends APIService { }); } - async createIssueLabel( - workspaceSlug: string, - projectId: string, - data: any, - user: IUser | undefined - ): Promise { + async createIssueLabel(workspaceSlug: string, projectId: string, data: any): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-labels/`, data) - .then((response: { data: IIssueLabel; [key: string]: any }) => { - trackEventServices.trackIssueLabelEvent( - { - workSpaceId: response?.data?.workspace_detail?.id, - workSpaceName: response?.data?.workspace_detail?.name, - workspaceSlug, - projectId, - projectIdentifier: response?.data?.project_detail?.identifier, - projectName: response?.data?.project_detail?.name, - labelId: response?.data?.id, - color: response?.data?.color, - }, - "ISSUE_LABEL_CREATE", - user as IUser - ); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async patchIssueLabel( - workspaceSlug: string, - projectId: string, - labelId: string, - data: any, - user: IUser | undefined - ): Promise { + async patchIssueLabel(workspaceSlug: string, projectId: string, labelId: string, data: any): Promise { return this.patch(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-labels/${labelId}/`, data) - .then((response) => { - trackEventServices.trackIssueLabelEvent( - { - workSpaceId: response?.data?.workspace_detail?.id, - workSpaceName: response?.data?.workspace_detail?.name, - workspaceSlug, - projectId, - projectIdentifier: response?.data?.project_detail?.identifier, - projectName: response?.data?.project_detail?.name, - labelId: response?.data?.id, - color: response?.data?.color, - }, - "ISSUE_LABEL_UPDATE", - user as IUser - ); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async deleteIssueLabel( - workspaceSlug: string, - projectId: string, - labelId: string, - user: IUser | undefined - ): Promise { + async deleteIssueLabel(workspaceSlug: string, projectId: string, labelId: string): Promise { return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-labels/${labelId}/`) - .then((response) => { - trackEventServices.trackIssueLabelEvent( - { - workspaceSlug, - projectId, - }, - "ISSUE_LABEL_DELETE", - user as IUser - ); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/services/issue/issue_reaction.service.ts b/web/services/issue/issue_reaction.service.ts index 737d9879f..ce5846156 100644 --- a/web/services/issue/issue_reaction.service.ts +++ b/web/services/issue/issue_reaction.service.ts @@ -1,11 +1,8 @@ import { API_BASE_URL } from "helpers/common.helper"; // services import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // types -import type { IUser, IssueReaction, IssueCommentReaction, IssueReactionForm, IssueCommentReactionForm } from "types"; - -const trackEventService = new TrackEventService(); +import type { IssueReaction, IssueCommentReaction, IssueReactionForm, IssueCommentReactionForm } from "types"; export class IssueReactionService extends APIService { constructor() { @@ -16,14 +13,10 @@ export class IssueReactionService extends APIService { workspaceSlug: string, projectId: string, issueId: string, - data: IssueReactionForm, - user?: IUser + data: IssueReactionForm ): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/reactions/`, data) - .then((response) => { - trackEventService.trackReactionEvent(response?.data, "ISSUE_REACTION_CREATE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); @@ -37,20 +30,11 @@ export class IssueReactionService extends APIService { }); } - async deleteIssueReaction( - workspaceSlug: string, - projectId: string, - issueId: string, - reaction: string, - user?: IUser - ): Promise { + async deleteIssueReaction(workspaceSlug: string, projectId: string, issueId: string, reaction: string): Promise { return this.delete( `/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/reactions/${reaction}/` ) - .then((response) => { - trackEventService.trackReactionEvent(response?.data, "ISSUE_REACTION_DELETE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); @@ -60,14 +44,10 @@ export class IssueReactionService extends APIService { workspaceSlug: string, projectId: string, commentId: string, - data: IssueCommentReactionForm, - user?: IUser + data: IssueCommentReactionForm ): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/comments/${commentId}/reactions/`, data) - .then((response) => { - trackEventService.trackReactionEvent(response?.data, "ISSUE_COMMENT_REACTION_CREATE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); @@ -89,16 +69,12 @@ export class IssueReactionService extends APIService { workspaceSlug: string, projectId: string, commentId: string, - reaction: string, - user?: IUser + reaction: string ): Promise { return this.delete( `/api/workspaces/${workspaceSlug}/projects/${projectId}/comments/${commentId}/reactions/${reaction}/` ) - .then((response) => { - trackEventService.trackReactionEvent(response?.data, "ISSUE_COMMENT_REACTION_DELETE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/services/module.service.ts b/web/services/module.service.ts index dec4b2d8f..9a4e6049b 100644 --- a/web/services/module.service.ts +++ b/web/services/module.service.ts @@ -1,12 +1,9 @@ // services import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // types -import type { IModule, IIssue, IUser } from "types"; +import type { IModule, IIssue } from "types"; import { API_BASE_URL } from "helpers/common.helper"; -const trackEventService = new TrackEventService(); - export class ModuleService extends APIService { constructor() { super(API_BASE_URL); @@ -20,29 +17,17 @@ export class ModuleService extends APIService { }); } - async createModule(workspaceSlug: string, projectId: string, data: any, user: any): Promise { + async createModule(workspaceSlug: string, projectId: string, data: any): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/`, data) - .then((response) => { - trackEventService.trackModuleEvent(response?.data, "MODULE_CREATE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async updateModule( - workspaceSlug: string, - projectId: string, - moduleId: string, - data: any, - user: IUser | undefined - ): Promise { + async updateModule(workspaceSlug: string, projectId: string, moduleId: string, data: any): Promise { return this.put(`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/`, data) - .then((response) => { - trackEventService.trackModuleEvent(response?.data, "MODULE_UPDATE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); @@ -60,25 +45,18 @@ export class ModuleService extends APIService { workspaceSlug: string, projectId: string, moduleId: string, - data: Partial, - user: IUser | undefined + data: Partial ): Promise { return this.patch(`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/`, data) - .then((response) => { - if (user) trackEventService.trackModuleEvent(response?.data, "MODULE_UPDATE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async deleteModule(workspaceSlug: string, projectId: string, moduleId: string, user: any): Promise { + async deleteModule(workspaceSlug: string, projectId: string, moduleId: string): Promise { return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/`) - .then((response) => { - trackEventService.trackModuleEvent(response?.data, "MODULE_DELETE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); @@ -116,26 +94,10 @@ export class ModuleService extends APIService { workspaceSlug: string, projectId: string, moduleId: string, - data: { issues: string[] }, - user: IUser | undefined + data: { issues: string[] } ): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/module-issues/`, data) - .then((response) => { - trackEventService.trackIssueMovedToCycleOrModuleEvent( - { - workspaceSlug, - workspaceName: response?.data?.[0]?.issue_detail?.workspace_detail?.name, - projectId, - projectIdentifier: response?.data?.[0]?.issue_detail?.project_detail?.identifier, - projectName: response?.data?.[0]?.issue_detail?.project_detail?.name, - issueId: response?.data?.[0]?.issue_detail?.id, - moduleId, - }, - response?.data?.length > 1 ? "ISSUE_MOVED_TO_MODULE_IN_BULK" : "ISSUE_MOVED_TO_MODULE", - user as IUser - ); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/services/page.service.ts b/web/services/page.service.ts index a344c69ec..e12f929e5 100644 --- a/web/services/page.service.ts +++ b/web/services/page.service.ts @@ -1,56 +1,33 @@ import { API_BASE_URL } from "helpers/common.helper"; // services import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // types -import { IPage, IPageBlock, RecentPagesResponse, IIssue, IUser } from "types"; - -const trackEventService = new TrackEventService(); +import { IPage, IPageBlock, RecentPagesResponse, IIssue } from "types"; export class PageService extends APIService { constructor() { super(API_BASE_URL); } - async createPage( - workspaceSlug: string, - projectId: string, - data: Partial, - user: IUser | undefined - ): Promise { + async createPage(workspaceSlug: string, projectId: string, data: Partial): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/pages/`, data) - .then((response) => { - trackEventService.trackPageEvent(response?.data, "PAGE_CREATE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async patchPage( - workspaceSlug: string, - projectId: string, - pageId: string, - data: Partial, - user: IUser | undefined - ): Promise { + async patchPage(workspaceSlug: string, projectId: string, pageId: string, data: Partial): Promise { return this.patch(`/api/workspaces/${workspaceSlug}/projects/${projectId}/pages/${pageId}/`, data) - .then((response) => { - trackEventService.trackPageEvent(response?.data, "PAGE_UPDATE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async deletePage(workspaceSlug: string, projectId: string, pageId: string, user: IUser | undefined): Promise { + async deletePage(workspaceSlug: string, projectId: string, pageId: string): Promise { return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/pages/${pageId}/`) - .then((response) => { - trackEventService.trackPageEvent(response?.data, "PAGE_DELETE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); @@ -118,14 +95,10 @@ export class PageService extends APIService { workspaceSlug: string, projectId: string, pageId: string, - data: Partial, - user: IUser | undefined + data: Partial ): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/pages/${pageId}/page-blocks/`, data) - .then((response) => { - trackEventService.trackPageBlockEvent(response?.data, "PAGE_BLOCK_CREATE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); @@ -151,36 +124,23 @@ export class PageService extends APIService { projectId: string, pageId: string, pageBlockId: string, - data: Partial, - user: IUser | undefined + data: Partial ): Promise { return this.patch( `/api/workspaces/${workspaceSlug}/projects/${projectId}/pages/${pageId}/page-blocks/${pageBlockId}/`, data ) - .then((response) => { - trackEventService.trackPageBlockEvent(response?.data, "PAGE_BLOCK_UPDATE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async deletePageBlock( - workspaceSlug: string, - projectId: string, - pageId: string, - pageBlockId: string, - user: IUser | undefined - ): Promise { + async deletePageBlock(workspaceSlug: string, projectId: string, pageId: string, pageBlockId: string): Promise { return this.delete( `/api/workspaces/${workspaceSlug}/projects/${projectId}/pages/${pageId}/page-blocks/${pageBlockId}/` ) - .then((response) => { - trackEventService.trackPageBlockEvent(response?.data, "PAGE_BLOCK_DELETE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); @@ -198,16 +158,12 @@ export class PageService extends APIService { workspaceSlug: string, projectId: string, pageId: string, - blockId: string, - user: IUser | undefined + blockId: string ): Promise { return this.post( `/api/workspaces/${workspaceSlug}/projects/${projectId}/pages/${pageId}/page-blocks/${blockId}/issues/` ) - .then((response) => { - trackEventService.trackPageBlockEvent(response?.data, "PAGE_BLOCK_CONVERTED_TO_ISSUE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/services/project/project-estimate.service.ts b/web/services/project/project-estimate.service.ts index 322d986fa..4a849868c 100644 --- a/web/services/project/project-estimate.service.ts +++ b/web/services/project/project-estimate.service.ts @@ -1,29 +1,18 @@ // services import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // types -import type { IUser, IEstimate, IEstimateFormData } from "types"; +import type { IEstimate, IEstimateFormData } from "types"; // helpers import { API_BASE_URL } from "helpers/common.helper"; -const trackEventService = new TrackEventService(); - export class ProjectEstimateService extends APIService { constructor() { super(API_BASE_URL); } - async createEstimate( - workspaceSlug: string, - projectId: string, - data: IEstimateFormData, - user: IUser | undefined - ): Promise { + async createEstimate(workspaceSlug: string, projectId: string, data: IEstimateFormData): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/estimates/`, data) - .then((response) => { - trackEventService.trackIssueEstimateEvent(response?.data, "ESTIMATE_CREATE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response; }); @@ -33,14 +22,10 @@ export class ProjectEstimateService extends APIService { workspaceSlug: string, projectId: string, estimateId: string, - data: IEstimateFormData, - user: IUser | undefined + data: IEstimateFormData ): Promise { return this.patch(`/api/workspaces/${workspaceSlug}/projects/${projectId}/estimates/${estimateId}/`, data) - .then((response) => { - trackEventService.trackIssueEstimateEvent(response?.data, "ESTIMATE_UPDATE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); @@ -62,17 +47,9 @@ export class ProjectEstimateService extends APIService { }); } - async deleteEstimate( - workspaceSlug: string, - projectId: string, - estimateId: string, - user: IUser | undefined - ): Promise { + async deleteEstimate(workspaceSlug: string, projectId: string, estimateId: string): Promise { return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/estimates/${estimateId}/`) - .then((response) => { - trackEventService.trackIssueEstimateEvent(response?.data, "ESTIMATE_DELETE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/services/project/project-export.service.ts b/web/services/project/project-export.service.ts index 64e42925c..b5503a829 100644 --- a/web/services/project/project-export.service.ts +++ b/web/services/project/project-export.service.ts @@ -1,12 +1,7 @@ import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; -// types -import { IUser } from "types"; // helpers import { API_BASE_URL } from "helpers/common.helper"; -const trackEventService = new TrackEventService(); - export class ProjectExportService extends APIService { constructor() { super(API_BASE_URL); @@ -17,20 +12,10 @@ export class ProjectExportService extends APIService { data: { provider: string; project: string[]; - }, - user: IUser + } ): Promise { return this.post(`/api/workspaces/${workspaceSlug}/export-issues/`, data) - .then((response) => { - trackEventService.trackExporterEvent( - { - workspaceSlug, - }, - "CSV_EXPORTER_CREATE", - user - ); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/services/project/project-member.service.ts b/web/services/project/project-member.service.ts index 35c7a620a..5f3e4710a 100644 --- a/web/services/project/project-member.service.ts +++ b/web/services/project/project-member.service.ts @@ -1,11 +1,8 @@ import { API_BASE_URL } from "helpers/common.helper"; // services import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // types -import type { IUser, IProjectBulkAddFormData, IProjectMember, IProjectMemberInvitation } from "types"; - -const trackEventService = new TrackEventService(); +import type { IProjectBulkAddFormData, IProjectMember, IProjectMemberInvitation } from "types"; export class ProjectMemberService extends APIService { constructor() { @@ -20,27 +17,9 @@ export class ProjectMemberService extends APIService { }); } - async bulkAddMembersToProject( - workspaceSlug: string, - projectId: string, - data: IProjectBulkAddFormData, - user: IUser | undefined - ): Promise { + async bulkAddMembersToProject(workspaceSlug: string, projectId: string, data: IProjectBulkAddFormData): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/members/`, data) - .then((response) => { - trackEventService.trackProjectEvent( - { - workspaceId: response?.data?.workspace?.id, - workspaceSlug, - projectId, - projectName: response?.data?.project?.name, - memberEmail: response?.data?.member?.email, - }, - "PROJECT_MEMBER_INVITE", - user as IUser - ); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/services/project/project-state.service.ts b/web/services/project/project-state.service.ts index 44b649327..214dcc948 100644 --- a/web/services/project/project-state.service.ts +++ b/web/services/project/project-state.service.ts @@ -1,24 +1,18 @@ // services import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // helpers import { API_BASE_URL } from "helpers/common.helper"; // types -import type { IUser, IState } from "types"; - -const trackEventService = new TrackEventService(); +import type { IState } from "types"; export class ProjectStateService extends APIService { constructor() { super(API_BASE_URL); } - async createState(workspaceSlug: string, projectId: string, data: any, user: IUser | undefined): Promise { + async createState(workspaceSlug: string, projectId: string, data: any): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/states/`, data) - .then((response) => { - trackEventService.trackStateEvent(response?.data, "STATE_CREATE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response; }); @@ -48,46 +42,25 @@ export class ProjectStateService extends APIService { }); } - async updateState( - workspaceSlug: string, - projectId: string, - stateId: string, - data: IState, - user: IUser | undefined - ): Promise { + async updateState(workspaceSlug: string, projectId: string, stateId: string, data: IState): Promise { return this.put(`/api/workspaces/${workspaceSlug}/projects/${projectId}/states/${stateId}/`, data) - .then((response) => { - trackEventService.trackStateEvent(response?.data, "STATE_UPDATE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response; }); } - async patchState( - workspaceSlug: string, - projectId: string, - stateId: string, - data: Partial, - user: IUser | undefined - ): Promise { + async patchState(workspaceSlug: string, projectId: string, stateId: string, data: Partial): Promise { return this.patch(`/api/workspaces/${workspaceSlug}/projects/${projectId}/states/${stateId}/`, data) - .then((response) => { - trackEventService.trackStateEvent(response?.data, "STATE_UPDATE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async deleteState(workspaceSlug: string, projectId: string, stateId: string, user: IUser | undefined): Promise { + async deleteState(workspaceSlug: string, projectId: string, stateId: string): Promise { return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/states/${stateId}/`) - .then((response) => { - trackEventService.trackStateEvent(response?.data, "STATE_DELETE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response; }); diff --git a/web/services/project/project.service.ts b/web/services/project/project.service.ts index 74d678d23..e4f1149f2 100644 --- a/web/services/project/project.service.ts +++ b/web/services/project/project.service.ts @@ -1,7 +1,6 @@ import { API_BASE_URL } from "helpers/common.helper"; // services import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // types import type { GithubRepositoriesResponse, @@ -12,19 +11,14 @@ import type { TProjectIssuesSearchParams, } from "types"; -const trackEventService = new TrackEventService(); - export class ProjectService extends APIService { constructor() { super(API_BASE_URL); } - async createProject(workspaceSlug: string, data: Partial, user: any): Promise { + async createProject(workspaceSlug: string, data: Partial): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/`, data) - .then((response) => { - trackEventService.trackProjectEvent(response.data, "CREATE_PROJECT", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response; }); @@ -58,23 +52,17 @@ export class ProjectService extends APIService { }); } - async updateProject(workspaceSlug: string, projectId: string, data: Partial, user: any): Promise { + async updateProject(workspaceSlug: string, projectId: string, data: Partial): Promise { return this.patch(`/api/workspaces/${workspaceSlug}/projects/${projectId}/`, data) - .then((response) => { - trackEventService.trackProjectEvent(response.data, "UPDATE_PROJECT", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async deleteProject(workspaceSlug: string, projectId: string, user: any | undefined): Promise { + async deleteProject(workspaceSlug: string, projectId: string): Promise { return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/`) - .then((response) => { - trackEventService.trackProjectEvent({ projectId }, "DELETE_PROJECT", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); @@ -88,20 +76,9 @@ export class ProjectService extends APIService { }); } - async leaveProject(workspaceSlug: string, projectId: string, user: any): Promise { + async leaveProject(workspaceSlug: string, projectId: string): Promise { return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/members/leave/`) - .then((response) => { - trackEventService.trackProjectEvent( - "PROJECT_MEMBER_LEAVE", - { - workspaceSlug, - projectId, - ...response?.data, - }, - user - ); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/services/track_event.service.ts b/web/services/track_event.service.ts deleted file mode 100644 index d3a2bd743..000000000 --- a/web/services/track_event.service.ts +++ /dev/null @@ -1,850 +0,0 @@ -// services -import { APIService } from "services/api.service"; - -const trackEvent = process.env.NEXT_PUBLIC_TRACK_EVENTS === "true" || process.env.NEXT_PUBLIC_TRACK_EVENTS === "1"; - -// types -import type { - IUser, - ICycle, - IEstimate, - IGptResponse, - IIssue, - IIssueComment, - IModule, - IPage, - IPageBlock, - IProject, - IState, - IProjectView, - IWorkspace, - IssueCommentReaction, - IssueReaction, -} from "types"; - -type WorkspaceEventType = - | "CREATE_WORKSPACE" - | "UPDATE_WORKSPACE" - | "DELETE_WORKSPACE" - | "WORKSPACE_USER_INVITE" - | "WORKSPACE_USER_INVITE_ACCEPT" - | "WORKSPACE_USER_BULK_INVITE_ACCEPT"; - -type ProjectEventType = - | "CREATE_PROJECT" - | "UPDATE_PROJECT" - | "DELETE_PROJECT" - | "PROJECT_MEMBER_INVITE" - | "PROJECT_MEMBER_LEAVE"; - -type IssueEventType = "ISSUE_CREATE" | "ISSUE_UPDATE" | "ISSUE_DELETE"; - -type CycleEventType = "CYCLE_CREATE" | "CYCLE_UPDATE" | "CYCLE_DELETE"; - -type StateEventType = "STATE_CREATE" | "STATE_UPDATE" | "STATE_DELETE"; - -type ModuleEventType = "MODULE_CREATE" | "MODULE_UPDATE" | "MODULE_DELETE"; - -type PagesEventType = "PAGE_CREATE" | "PAGE_UPDATE" | "PAGE_DELETE"; - -type ViewEventType = "VIEW_CREATE" | "VIEW_UPDATE" | "VIEW_DELETE"; - -type IssueCommentEventType = "ISSUE_COMMENT_CREATE" | "ISSUE_COMMENT_UPDATE" | "ISSUE_COMMENT_DELETE"; - -type Toggle = "TOGGLE_CYCLE" | "TOGGLE_MODULE" | "TOGGLE_VIEW" | "TOGGLE_PAGES" | "TOGGLE_STATE" | "TOGGLE_INBOX"; - -export type MiscellaneousEventType = `${Toggle}_ON` | `${Toggle}_OFF`; - -type IntegrationEventType = "ADD_WORKSPACE_INTEGRATION" | "REMOVE_WORKSPACE_INTEGRATION"; - -type GitHubSyncEventType = "GITHUB_REPO_SYNC"; - -type PageBlocksEventType = - | "PAGE_BLOCK_CREATE" - | "PAGE_BLOCK_UPDATE" - | "PAGE_BLOCK_DELETE" - | "PAGE_BLOCK_CONVERTED_TO_ISSUE"; - -type IssueLabelEventType = "ISSUE_LABEL_CREATE" | "ISSUE_LABEL_UPDATE" | "ISSUE_LABEL_DELETE"; - -type GptEventType = "ASK_GPT" | "USE_GPT_RESPONSE_IN_ISSUE" | "USE_GPT_RESPONSE_IN_PAGE_BLOCK"; - -type IssueEstimateEventType = "ESTIMATE_CREATE" | "ESTIMATE_UPDATE" | "ESTIMATE_DELETE"; - -type InboxEventType = - | "INBOX_CREATE" - | "INBOX_UPDATE" - | "INBOX_DELETE" - | "INBOX_ISSUE_CREATE" - | "INBOX_ISSUE_UPDATE" - | "INBOX_ISSUE_DELETE" - | "INBOX_ISSUE_DUPLICATED" - | "INBOX_ISSUE_ACCEPTED" - | "INBOX_ISSUE_SNOOZED" - | "INBOX_ISSUE_REJECTED"; - -type ImporterEventType = - | "GITHUB_IMPORTER_CREATE" - | "GITHUB_IMPORTER_DELETE" - | "JIRA_IMPORTER_CREATE" - | "JIRA_IMPORTER_DELETE"; - -type ExporterEventType = "CSV_EXPORTER_CREATE"; - -type AnalyticsEventType = - | "WORKSPACE_SCOPE_AND_DEMAND_ANALYTICS" - | "WORKSPACE_CUSTOM_ANALYTICS" - | "WORKSPACE_ANALYTICS_EXPORT" - | "PROJECT_SCOPE_AND_DEMAND_ANALYTICS" - | "PROJECT_CUSTOM_ANALYTICS" - | "PROJECT_ANALYTICS_EXPORT" - | "CYCLE_SCOPE_AND_DEMAND_ANALYTICS" - | "CYCLE_CUSTOM_ANALYTICS" - | "CYCLE_ANALYTICS_EXPORT" - | "MODULE_SCOPE_AND_DEMAND_ANALYTICS" - | "MODULE_CUSTOM_ANALYTICS" - | "MODULE_ANALYTICS_EXPORT"; - -type ReactionEventType = - | "ISSUE_REACTION_CREATE" - | "ISSUE_COMMENT_REACTION_CREATE" - | "ISSUE_REACTION_DELETE" - | "ISSUE_COMMENT_REACTION_DELETE"; - -export class TrackEventService extends APIService { - constructor() { - super("/"); - } - - async trackWorkspaceEvent(data: IWorkspace | any, eventName: WorkspaceEventType, user: IUser): Promise { - if (!trackEvent) return; - - let payload: any; - if ( - eventName !== "DELETE_WORKSPACE" && - eventName !== "WORKSPACE_USER_INVITE" && - eventName !== "WORKSPACE_USER_INVITE_ACCEPT" && - eventName !== "WORKSPACE_USER_BULK_INVITE_ACCEPT" - ) - payload = { - workspaceId: data.id, - workspaceSlug: data.slug, - workspaceName: data.name, - }; - else payload = data; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...payload, - }, - user: user, - }, - }); - } - - async trackProjectEvent(data: Partial | any, eventName: ProjectEventType, user: IUser): Promise { - if (!trackEvent) return; - - let payload: any; - if (eventName !== "DELETE_PROJECT" && eventName !== "PROJECT_MEMBER_INVITE" && eventName !== "PROJECT_MEMBER_LEAVE") - payload = { - workspaceId: data?.workspace_detail?.id, - workspaceName: data?.workspace_detail?.name, - workspaceSlug: data?.workspace_detail?.slug, - projectId: data?.id, - projectName: data?.name, - }; - else payload = data; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...payload, - }, - user: user, - }, - }); - } - - async trackUserOnboardingCompleteEvent(data: any, user: IUser): Promise { - if (!trackEvent) return; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName: "USER_ONBOARDING_COMPLETE", - extra: { - ...data, - }, - user: user, - }, - }); - } - - async trackUserTourCompleteEvent(data: any, user: IUser): Promise { - if (!trackEvent) return; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName: "USER_TOUR_COMPLETE", - extra: { - ...data, - }, - user: user, - }, - }); - } - - async trackIssueEvent(data: IIssue | any, eventName: IssueEventType, user: IUser): Promise { - if (!trackEvent) return; - - let payload: any; - if (eventName !== "ISSUE_DELETE") - payload = { - workspaceId: data?.workspace_detail?.id, - workspaceName: data?.workspace_detail?.name, - workspaceSlug: data?.workspace_detail?.slug, - projectId: data?.project_detail?.id, - projectName: data?.project_detail?.name, - projectIdentifier: data?.project_detail?.identifier, - issueId: data?.id, - }; - else payload = data; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...payload, - }, - user: user, - }, - }); - } - - async trackIssueMarkedAsDoneEvent(data: any, user: IUser): Promise { - if (!trackEvent) return; - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName: "ISSUES_MARKED_AS_DONE", - extra: { - ...data, - }, - user: user, - }, - }); - } - - async trackIssuePartialPropertyUpdateEvent( - data: any, - propertyName: - | "ISSUE_PROPERTY_UPDATE_PRIORITY" - | "ISSUE_PROPERTY_UPDATE_STATE" - | "ISSUE_PROPERTY_UPDATE_ASSIGNEE" - | "ISSUE_PROPERTY_UPDATE_DUE_DATE" - | "ISSUE_PROPERTY_UPDATE_ESTIMATE", - user: IUser - ): Promise { - if (!trackEvent) return; - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName: propertyName, - extra: { - ...data, - }, - user: user, - }, - }); - } - - async trackIssueCommentEvent( - data: Partial | any, - eventName: IssueCommentEventType, - user: IUser | undefined - ): Promise { - if (!trackEvent) return; - - let payload: any; - if (eventName !== "ISSUE_COMMENT_DELETE") - payload = { - workspaceId: data?.workspace_detail?.id, - workspaceName: data?.workspace_detail?.name, - workspaceSlug: data?.workspace_detail?.slug, - projectId: data?.project_detail?.id, - projectName: data?.project_detail?.name, - projectIdentifier: data?.project_detail?.identifier, - issueId: data?.issue, - }; - else payload = data; - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...payload, - }, - user: user, - }, - }); - } - - async trackIssueRelationEvent( - data: any, - eventName: "ISSUE_RELATION_CREATE" | "ISSUE_RELATION_DELETE", - user: IUser - ): Promise { - if (!trackEvent) return; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: data, - user: user, - }, - }); - } - - async trackIssueMovedToCycleOrModuleEvent( - data: any, - eventName: - | "ISSUE_MOVED_TO_CYCLE" - | "ISSUE_MOVED_TO_MODULE" - | "ISSUE_MOVED_TO_CYCLE_IN_BULK" - | "ISSUE_MOVED_TO_MODULE_IN_BULK", - user: IUser - ): Promise { - if (!trackEvent) return; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...data, - }, - user: user, - }, - }); - } - - async trackIssueBulkDeleteEvent(data: any, user: IUser): Promise { - if (!trackEvent) return; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName: "ISSUE_BULK_DELETE", - extra: { - ...data, - }, - user: user, - }, - }); - } - - async trackIssueLabelEvent(data: any, eventName: IssueLabelEventType, user: IUser): Promise { - if (!trackEvent) return; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...data, - }, - user: user, - }, - }); - } - - async trackStateEvent(data: IState | any, eventName: StateEventType, user: IUser): Promise { - if (!trackEvent) return; - - let payload: any; - if (eventName !== "STATE_DELETE") - payload = { - workspaceId: data?.workspace_detail?.id, - workspaceName: data?.workspace_detail?.name, - workspaceSlug: data?.workspace_detail?.slug, - projectId: data?.project_detail?.id, - projectName: data?.project_detail?.name, - projectIdentifier: data?.project_detail?.identifier, - stateId: data.id, - }; - else payload = data; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...payload, - }, - user: user, - }, - }); - } - - async trackCycleEvent(data: ICycle | any, eventName: CycleEventType, user: IUser): Promise { - if (!trackEvent) return; - - let payload: any; - if (eventName !== "CYCLE_DELETE") - payload = { - workspaceId: data?.workspace_detail?.id, - workspaceName: data?.workspace_detail?.name, - workspaceSlug: data?.workspace_detail?.slug, - projectId: data?.project_detail?.id, - projectName: data?.project_detail?.name, - projectIdentifier: data?.project_detail?.identifier, - cycleId: data.id, - }; - else payload = data; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...payload, - }, - user: user, - }, - }); - } - - async trackModuleEvent(data: IModule | any, eventName: ModuleEventType, user: IUser): Promise { - if (!trackEvent) return; - - let payload: any; - if (eventName !== "MODULE_DELETE") - payload = { - workspaceId: data?.workspace_detail?.id, - workspaceName: data?.workspace_detail?.name, - workspaceSlug: data?.workspace_detail?.slug, - projectId: data?.project_detail?.id, - projectName: data.project_detail?.name, - projectIdentifier: data?.project_detail?.identifier, - moduleId: data.id, - }; - else payload = data; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...payload, - }, - user: user, - }, - }); - } - - async trackPageEvent(data: Partial | any, eventName: PagesEventType, user: IUser | undefined): Promise { - if (!trackEvent) return; - - let payload: any; - if (eventName !== "PAGE_DELETE") - payload = { - workspaceId: data?.workspace_detail?.id, - workspaceName: data?.workspace_detail?.name, - workspaceSlug: data?.workspace_detail?.slug, - projectId: data?.project_detail?.id, - projectName: data?.project_detail?.name, - projectIdentifier: data?.project_detail?.identifier, - pageId: data.id, - }; - else payload = data; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...payload, - }, - user: user, - }, - }); - } - - async trackPageBlockEvent( - data: Partial | IIssue, - eventName: PageBlocksEventType, - user: IUser - ): Promise { - if (!trackEvent) return; - - let payload: any; - if (eventName !== "PAGE_BLOCK_DELETE" && eventName !== "PAGE_BLOCK_CONVERTED_TO_ISSUE") - payload = { - workspaceId: data?.workspace_detail?.id, - workspaceName: data?.workspace_detail?.name, - workspaceSlug: data?.workspace_detail?.slug, - projectId: data?.project_detail?.id, - projectName: data?.project_detail?.name, - projectIdentifier: data?.project_detail?.identifier, - pageId: (data as IPageBlock)?.page, - pageBlockId: data.id, - }; - else if (eventName === "PAGE_BLOCK_CONVERTED_TO_ISSUE") { - payload = { - workspaceId: data?.workspace_detail?.id, - workspaceName: data?.workspace_detail?.name, - workspaceSlug: data?.workspace_detail?.slug, - projectId: data?.project_detail?.id, - projectName: data?.project_detail?.name, - projectIdentifier: data?.project_detail?.identifier, - issueId: data?.id, - }; - } else payload = data; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...payload, - }, - user: user, - }, - }); - } - - async trackAskGptEvent(data: IGptResponse, eventName: GptEventType, user: IUser): Promise { - if (!trackEvent) return; - - const payload = { - workspaceId: data?.workspace_detail?.id, - workspaceName: data?.workspace_detail?.name, - workspaceSlug: data?.workspace_detail?.slug, - projectId: data?.project_detail?.id, - projectIdentifier: data?.project_detail?.identifier, - projectName: data?.project_detail?.name, - count: data?.count, - }; - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...payload, - }, - user: user, - }, - }); - } - - async trackUseGPTResponseEvent(data: IIssue | IPageBlock, eventName: GptEventType, user: IUser): Promise { - if (!trackEvent) return; - - let payload: any; - - if (eventName === "USE_GPT_RESPONSE_IN_ISSUE") { - payload = { - workspaceId: data?.workspace_detail?.id, - workspaceName: data?.workspace_detail?.name, - workspaceSlug: data?.workspace_detail?.slug, - projectId: data?.project_detail?.id, - projectIdentifier: data?.project_detail?.identifier, - projectName: data?.project_detail?.name, - issueId: data.id, - }; - } else if (eventName === "USE_GPT_RESPONSE_IN_PAGE_BLOCK") { - payload = { - workspaceId: data?.workspace_detail?.id, - workspaceName: data?.workspace_detail?.name, - workspaceSlug: data?.workspace_detail?.slug, - projectId: data?.project_detail?.id, - projectIdentifier: data?.project_detail?.identifier, - projectName: data?.project_detail?.name, - pageId: (data as IPageBlock)?.page, - pageBlockId: data.id, - }; - } - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...payload, - }, - user: user, - }, - }); - } - - async trackViewEvent(data: IProjectView, eventName: ViewEventType, user: IUser): Promise { - if (!trackEvent) return; - - let payload: any; - if (eventName === "VIEW_DELETE") payload = data; - else - payload = { - labels: Boolean(data.query_data.labels), - assignees: Boolean(data.query_data.assignees), - priority: Boolean(data.query_data.priority), - state: Boolean(data.query_data.state), - created_by: Boolean(data.query_data.created_by), - }; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...payload, - }, - user: user, - }, - }); - } - - async trackMiscellaneousEvent(data: any, eventName: MiscellaneousEventType, user: IUser | undefined): Promise { - if (!trackEvent || !user) return; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...data, - }, - user: user, - }, - }); - } - - async trackAppIntegrationEvent(data: any, eventName: IntegrationEventType, user: IUser): Promise { - if (!trackEvent) return; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...data, - }, - user: user, - }, - }); - } - - async trackGitHubSyncEvent(data: any, eventName: GitHubSyncEventType, user: IUser): Promise { - if (!trackEvent) return; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...data, - }, - user: user, - }, - }); - } - - async trackIssueEstimateEvent( - data: { estimate: IEstimate }, - eventName: IssueEstimateEventType, - user: IUser - ): Promise { - if (!trackEvent) return; - - let payload: any; - if (eventName === "ESTIMATE_DELETE") payload = data; - else - payload = { - workspaceId: data?.estimate?.workspace_detail?.id, - workspaceName: data?.estimate?.workspace_detail?.name, - workspaceSlug: data?.estimate?.workspace_detail?.slug, - projectId: data?.estimate?.project_detail?.id, - projectName: data?.estimate?.project_detail?.name, - projectIdentifier: data?.estimate?.project_detail?.identifier, - estimateId: data.estimate?.id, - }; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...payload, - }, - user: user, - }, - }); - } - - async trackImporterEvent(data: any, eventName: ImporterEventType, user: IUser | undefined): Promise { - if (!trackEvent) return; - - let payload: any; - if (eventName === "GITHUB_IMPORTER_DELETE" || eventName === "JIRA_IMPORTER_DELETE") payload = data; - else - payload = { - workspaceId: data?.workspace_detail?.id, - workspaceName: data?.workspace_detail?.name, - workspaceSlug: data?.workspace_detail?.slug, - projectId: data?.project_detail?.id, - projectName: data?.project_detail?.name, - projectIdentifier: data?.project_detail?.identifier, - }; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...payload, - }, - user: user, - }, - }); - } - - async trackAnalyticsEvent(data: any, eventName: AnalyticsEventType, user: IUser): Promise { - if (!trackEvent) return; - - const payload = { ...data }; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: payload, - user: user, - }, - }); - } - - async trackExporterEvent(data: any, eventName: ExporterEventType, user: IUser): Promise { - if (!trackEvent) return; - - const payload = { ...data }; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...payload, - }, - user: user, - }, - }); - } - - // TODO: add types to the data - async trackInboxEvent(data: any, eventName: InboxEventType, user: IUser): Promise { - if (!trackEvent) return; - - let payload: any; - if (eventName !== "INBOX_DELETE") - payload = { - issue: data?.issue?.id, - inbox: data?.id, - workspaceId: data?.issue?.workspace_detail?.id, - workspaceName: data?.issue?.workspace_detail?.name, - workspaceSlug: data?.issue?.workspace_detail?.slug, - projectId: data?.issue?.project_detail?.id, - projectName: data?.issue?.project_detail?.name, - }; - else payload = data; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: { - ...payload, - }, - user: user, - }, - }); - } - - async trackReactionEvent( - data: IssueReaction | IssueCommentReaction, - eventName: ReactionEventType, - user: IUser - ): Promise { - if (!trackEvent) return; - - let payload: any; - if (eventName === "ISSUE_REACTION_DELETE" || eventName === "ISSUE_COMMENT_REACTION_DELETE") payload = data; - else - payload = { - workspaceId: data?.workspace, - projectId: data?.project, - reaction: data?.reaction, - }; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: payload, - user: user, - }, - }); - } - - async trackProjectPublishSettingsEvent(data: any, eventName: string, user: IUser): Promise { - if (!trackEvent) return; - - const payload: any = data; - - return this.request({ - url: "/api/track-event", - method: "POST", - data: { - eventName, - extra: payload, - user: user, - }, - }); - } -} diff --git a/web/services/user.service.ts b/web/services/user.service.ts index a2cd74697..1d9d1ce94 100644 --- a/web/services/user.service.ts +++ b/web/services/user.service.ts @@ -1,6 +1,5 @@ // services import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // types import type { IIssue, @@ -15,8 +14,6 @@ import type { // helpers import { API_BASE_URL } from "helpers/common.helper"; -const trackEventService = new TrackEventService(); - export class UserService extends APIService { constructor() { super(API_BASE_URL); @@ -79,32 +76,21 @@ export class UserService extends APIService { }); } - async updateUserOnBoard({ userRole }: any, user: IUser | undefined): Promise { + async updateUserOnBoard(): Promise { return this.patch("/api/users/me/onboard/", { is_onboarded: true, }) - .then((response) => { - trackEventService.trackUserOnboardingCompleteEvent( - { - user_role: userRole ?? "None", - }, - user as IUser - ); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async updateUserTourCompleted(user: IUser): Promise { + async updateUserTourCompleted(): Promise { return this.patch("/api/users/me/tour-completed/", { is_tour_completed: true, }) - .then((response) => { - trackEventService.trackUserTourCompleteEvent({ user_role: user.role ?? "None" }, user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/services/view.service.ts b/web/services/view.service.ts index 97f0db9a2..e4e28adf9 100644 --- a/web/services/view.service.ts +++ b/web/services/view.service.ts @@ -1,51 +1,33 @@ import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // types import { IProjectView } from "types/views"; // helpers import { API_BASE_URL } from "helpers/common.helper"; -const trackEventService = new TrackEventService(); - export class ViewService extends APIService { constructor() { super(API_BASE_URL); } - async createView(workspaceSlug: string, projectId: string, data: Partial, user: any): Promise { + async createView(workspaceSlug: string, projectId: string, data: Partial): Promise { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/views/`, data) - .then((response) => { - trackEventService.trackViewEvent(response?.data, "VIEW_CREATE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async patchView( - workspaceSlug: string, - projectId: string, - viewId: string, - data: Partial, - user: any - ): Promise { + async patchView(workspaceSlug: string, projectId: string, viewId: string, data: Partial): Promise { return this.patch(`/api/workspaces/${workspaceSlug}/projects/${projectId}/views/${viewId}/`, data) - .then((response) => { - trackEventService.trackViewEvent(response?.data, "VIEW_UPDATE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async deleteView(workspaceSlug: string, projectId: string, viewId: string, user: any): Promise { + async deleteView(workspaceSlug: string, projectId: string, viewId: string): Promise { return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/views/${viewId}/`) - .then((response) => { - trackEventService.trackViewEvent(response?.data, "VIEW_DELETE", user); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/services/workspace.service.ts b/web/services/workspace.service.ts index 98d85ec8a..1e5b18f5a 100644 --- a/web/services/workspace.service.ts +++ b/web/services/workspace.service.ts @@ -1,6 +1,5 @@ // services import { APIService } from "services/api.service"; -import { TrackEventService } from "services/track_event.service"; // helpers import { API_BASE_URL } from "helpers/common.helper"; // types @@ -12,7 +11,6 @@ import { ILastActiveWorkspaceDetails, IWorkspaceSearchResults, IProductUpdateResponse, - IUser, IWorkspaceBulkInviteFormData, IWorkspaceViewProps, } from "types"; @@ -20,8 +18,6 @@ import { IWorkspaceView } from "types/workspace-views"; // store import { IIssueGroupWithSubGroupsStructure, IIssueGroupedStructure, IIssueUnGroupedStructure } from "store/issue"; -const trackEventService = new TrackEventService(); - export class WorkspaceService extends APIService { constructor() { super(API_BASE_URL); @@ -43,66 +39,43 @@ export class WorkspaceService extends APIService { }); } - async createWorkspace(data: Partial, user: IUser | undefined): Promise { + async createWorkspace(data: Partial): Promise { return this.post("/api/workspaces/", data) - .then((response) => { - trackEventService.trackWorkspaceEvent(response.data, "CREATE_WORKSPACE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async updateWorkspace( - workspaceSlug: string, - data: Partial, - user: IUser | undefined - ): Promise { + async updateWorkspace(workspaceSlug: string, data: Partial): Promise { return this.patch(`/api/workspaces/${workspaceSlug}/`, data) - .then((response) => { - trackEventService.trackWorkspaceEvent(response.data, "UPDATE_WORKSPACE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async deleteWorkspace(workspaceSlug: string, user: IUser | undefined): Promise { + async deleteWorkspace(workspaceSlug: string): Promise { return this.delete(`/api/workspaces/${workspaceSlug}/`) - .then((response) => { - trackEventService.trackWorkspaceEvent({ workspaceSlug }, "DELETE_WORKSPACE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async inviteWorkspace( - workspaceSlug: string, - data: IWorkspaceBulkInviteFormData, - user: IUser | undefined - ): Promise { + async inviteWorkspace(workspaceSlug: string, data: IWorkspaceBulkInviteFormData): Promise { return this.post(`/api/workspaces/${workspaceSlug}/invite/`, data) - .then((response) => { - trackEventService.trackWorkspaceEvent(response.data, "WORKSPACE_USER_INVITE", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); } - async joinWorkspace(workspaceSlug: string, invitationId: string, data: any, user: IUser | undefined): Promise { + async joinWorkspace(workspaceSlug: string, invitationId: string, data: any): Promise { return this.post(`/api/workspaces/${workspaceSlug}/invitations/${invitationId}/join/`, data, { headers: {}, }) - .then((response) => { - trackEventService.trackWorkspaceEvent(response.data, "WORKSPACE_USER_INVITE_ACCEPT", user as IUser); - return response?.data; - }) + .then((response) => response?.data) .catch((error) => { throw error?.response?.data; }); diff --git a/web/store/cycle/cycle_issue.store.ts b/web/store/cycle/cycle_issue.store.ts index 17d8f351c..7e2db12b5 100644 --- a/web/store/cycle/cycle_issue.store.ts +++ b/web/store/cycle/cycle_issue.store.ts @@ -324,17 +324,9 @@ export class CycleIssueStore implements ICycleIssueStore { addIssueToCycle = async (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => { try { - const user = this.rootStore.user.currentUser ?? undefined; - - await this.issueService.addIssueToCycle( - workspaceSlug, - projectId, - cycleId, - { - issues: issueIds, - }, - user - ); + await this.issueService.addIssueToCycle(workspaceSlug, projectId, cycleId, { + issues: issueIds, + }); this.fetchIssues(workspaceSlug, projectId, cycleId); } catch (error) { diff --git a/web/store/cycle/cycle_issue_filters.store.ts b/web/store/cycle/cycle_issue_filters.store.ts index 95fad6d98..5b8f6a536 100644 --- a/web/store/cycle/cycle_issue_filters.store.ts +++ b/web/store/cycle/cycle_issue_filters.store.ts @@ -133,9 +133,7 @@ export class CycleIssueFilterStore implements ICycleIssueFilterStore { }, }; - const user = this.rootStore.user.currentUser ?? undefined; - - await this.cycleService.patchCycle(workspaceSlug, projectId, cycleId, payload, user); + await this.cycleService.patchCycle(workspaceSlug, projectId, cycleId, payload); } catch (error) { this.fetchCycleFilters(workspaceSlug, projectId, cycleId); diff --git a/web/store/cycle/cycles.store.ts b/web/store/cycle/cycles.store.ts index 67e3fc2ca..048326841 100644 --- a/web/store/cycle/cycles.store.ts +++ b/web/store/cycle/cycles.store.ts @@ -248,12 +248,7 @@ export class CycleStore implements ICycleStore { createCycle = async (workspaceSlug: string, projectId: string, data: Partial) => { try { - const response = await this.cycleService.createCycle( - workspaceSlug, - projectId, - data, - this.rootStore.user.currentUser - ); + const response = await this.cycleService.createCycle(workspaceSlug, projectId, data); runInAction(() => { this.cycle_details = { @@ -274,7 +269,7 @@ export class CycleStore implements ICycleStore { patchCycle = async (workspaceSlug: string, projectId: string, cycleId: string, data: Partial) => { try { - const _response = await this.cycleService.patchCycle(workspaceSlug, projectId, cycleId, data, undefined); + const _response = await this.cycleService.patchCycle(workspaceSlug, projectId, cycleId, data); const _cycleDetails = { ...this.cycle_details, @@ -297,7 +292,7 @@ export class CycleStore implements ICycleStore { removeCycle = async (workspaceSlug: string, projectId: string, cycleId: string) => { try { - const _response = await this.cycleService.deleteCycle(workspaceSlug, projectId, cycleId, undefined); + const _response = await this.cycleService.deleteCycle(workspaceSlug, projectId, cycleId); const _currentView = this.cycleView === "active" ? "current" : this.cycleView; this.fetchCycles(workspaceSlug, projectId, _currentView); diff --git a/web/store/inbox/inbox_issue_detail.store.ts b/web/store/inbox/inbox_issue_detail.store.ts index 9085264f5..25653ab09 100644 --- a/web/store/inbox/inbox_issue_detail.store.ts +++ b/web/store/inbox/inbox_issue_detail.store.ts @@ -121,13 +121,7 @@ export class InboxIssueDetailsStore implements IInboxIssueDetailsStore { }; try { - const response = await this.inboxService.createInboxIssue( - workspaceSlug, - projectId, - inboxId, - payload, - this.rootStore.user.currentUser ?? undefined - ); + const response = await this.inboxService.createInboxIssue(workspaceSlug, projectId, inboxId, payload); runInAction(() => { this.issueDetails = { @@ -175,14 +169,7 @@ export class InboxIssueDetailsStore implements IInboxIssueDetailsStore { }; }); - await this.inboxService.patchInboxIssue( - workspaceSlug, - projectId, - inboxId, - issueId, - { issue: data }, - this.rootStore.user.currentUser ?? undefined - ); + await this.inboxService.patchInboxIssue(workspaceSlug, projectId, inboxId, issueId, { issue: data }); } catch (error) { runInAction(() => { this.error = error; @@ -224,14 +211,7 @@ export class InboxIssueDetailsStore implements IInboxIssueDetailsStore { }; }); - await this.inboxService.markInboxStatus( - workspaceSlug, - projectId, - inboxId, - issueId, - data, - this.rootStore.user.currentUser ?? undefined - ); + await this.inboxService.markInboxStatus(workspaceSlug, projectId, inboxId, issueId, data); } catch (error) { runInAction(() => { this.error = error; @@ -259,13 +239,7 @@ export class InboxIssueDetailsStore implements IInboxIssueDetailsStore { }; }); - await this.inboxService.deleteInboxIssue( - workspaceSlug, - projectId, - inboxId, - issueId, - this.rootStore.user.currentUser ?? undefined - ); + await this.inboxService.deleteInboxIssue(workspaceSlug, projectId, inboxId, issueId); } catch (error) { runInAction(() => { this.error = error; diff --git a/web/store/issue/issue_detail.store.ts b/web/store/issue/issue_detail.store.ts index 58d4aabe7..226a5d7d3 100644 --- a/web/store/issue/issue_detail.store.ts +++ b/web/store/issue/issue_detail.store.ts @@ -251,12 +251,7 @@ export class IssueDetailStore implements IIssueDetailStore { }); try { - const response = await this.issueService.createIssue( - workspaceSlug, - projectId, - data, - this.rootStore.user.currentUser! - ); + const response = await this.issueService.createIssue(workspaceSlug, projectId, data); runInAction(() => { this.loader = false; @@ -283,9 +278,7 @@ export class IssueDetailStore implements IIssueDetailStore { this.error = null; }); - const user = this.rootStore.user.currentUser ?? undefined; - - const response = await this.issueService.createIssue(workspaceSlug, projectId, data, user); + const response = await this.issueService.createIssue(workspaceSlug, projectId, data); runInAction(() => { this.loader = false; @@ -323,7 +316,7 @@ export class IssueDetailStore implements IIssueDetailStore { if (!user) return; - const response = await this.issueService.patchIssue(workspaceSlug, projectId, issueId, data, user); + const response = await this.issueService.patchIssue(workspaceSlug, projectId, issueId, data); runInAction(() => { this.loader = false; @@ -365,7 +358,7 @@ export class IssueDetailStore implements IIssueDetailStore { if (!user) return; - const response = await this.issueService.deleteIssue(workspaceSlug, projectId, issueId, user); + const response = await this.issueService.deleteIssue(workspaceSlug, projectId, issueId); runInAction(() => { this.loader = false; @@ -521,8 +514,7 @@ export class IssueDetailStore implements IIssueDetailStore { workspaceSlug, projectId, issueId, - data, - undefined + data ); const _issueComments = { @@ -551,8 +543,7 @@ export class IssueDetailStore implements IIssueDetailStore { projectId, issueId, commentId, - data, - undefined + data ); const _issueComments = { @@ -577,7 +568,7 @@ export class IssueDetailStore implements IIssueDetailStore { [issueId]: this.issue_comments[issueId].filter((comment: any) => comment.id != commentId), }; - await this.issueCommentService.deleteIssueComment(workspaceSlug, projectId, issueId, commentId, undefined); + await this.issueCommentService.deleteIssueComment(workspaceSlug, projectId, issueId, commentId); runInAction(() => { this.issue_comments = _issueComments; diff --git a/web/store/issue/issue_quick_add.store.ts b/web/store/issue/issue_quick_add.store.ts index 44683b578..da71ebb57 100644 --- a/web/store/issue/issue_quick_add.store.ts +++ b/web/store/issue/issue_quick_add.store.ts @@ -67,12 +67,7 @@ export class IssueQuickAddStore implements IIssueQuickAddStore { try { this.updateIssueStructure(group_id, sub_group_id, data as IIssue); - const response = await this.issueService.createIssue( - workspaceSlug, - projectId, - data, - this.rootStore.user.currentUser! - ); + const response = await this.issueService.createIssue(workspaceSlug, projectId, data); this.updateQuickAddIssueStructure(group_id, sub_group_id, { ...data, diff --git a/web/store/module/module_filters.store.ts b/web/store/module/module_filters.store.ts index ae94af59e..e205bbd30 100644 --- a/web/store/module/module_filters.store.ts +++ b/web/store/module/module_filters.store.ts @@ -152,19 +152,11 @@ export class ModuleFilterStore implements IModuleFilterStore { this.moduleFilters = newFilters; }); - const user = this.rootStore.user.currentUser ?? undefined; - - this.moduleService.patchModule( - workspaceSlug, - projectId, - moduleId, - { - view_props: { - filters: newFilters, - }, + this.moduleService.patchModule(workspaceSlug, projectId, moduleId, { + view_props: { + filters: newFilters, }, - user - ); + }); } catch (error) { this.fetchModuleFilters(workspaceSlug, projectId, moduleId); diff --git a/web/store/module/module_issue.store.ts b/web/store/module/module_issue.store.ts index 165b51b62..39311a057 100644 --- a/web/store/module/module_issue.store.ts +++ b/web/store/module/module_issue.store.ts @@ -339,17 +339,9 @@ export class ModuleIssueStore implements IModuleIssueStore { addIssueToModule = async (workspaceSlug: string, projectId: string, moduleId: string, issueIds: string[]) => { try { - const user = this.rootStore.user.currentUser ?? undefined; - - await this.moduleService.addIssuesToModule( - workspaceSlug, - projectId, - moduleId, - { - issues: issueIds, - }, - user - ); + await this.moduleService.addIssuesToModule(workspaceSlug, projectId, moduleId, { + issues: issueIds, + }); this.fetchIssues(workspaceSlug, projectId, moduleId); } catch (error) { diff --git a/web/store/module/modules.store.ts b/web/store/module/modules.store.ts index 0dc122438..59f4b08f7 100644 --- a/web/store/module/modules.store.ts +++ b/web/store/module/modules.store.ts @@ -208,12 +208,7 @@ export class ModuleStore implements IModuleStore { createModule = async (workspaceSlug: string, projectId: string, data: Partial) => { try { - const response = await this.moduleService.createModule( - workspaceSlug, - projectId, - data, - this.rootStore.user.currentUser - ); + const response = await this.moduleService.createModule(workspaceSlug, projectId, data); runInAction(() => { this.modules = { @@ -255,9 +250,7 @@ export class ModuleStore implements IModuleStore { }); }); - const user = this.rootStore.user.currentUser ?? undefined; - - const response = await this.moduleService.patchModule(workspaceSlug, projectId, moduleId, data, user); + const response = await this.moduleService.patchModule(workspaceSlug, projectId, moduleId, data); return response; } catch (error) { @@ -283,7 +276,7 @@ export class ModuleStore implements IModuleStore { }; }); - await this.moduleService.deleteModule(workspaceSlug, projectId, moduleId, this.rootStore.user.currentUser); + await this.moduleService.deleteModule(workspaceSlug, projectId, moduleId); } catch (error) { console.error("Failed to delete module in module store", error); diff --git a/web/store/project-view/project_views.store.ts b/web/store/project-view/project_views.store.ts index 76c58002d..51afee972 100644 --- a/web/store/project-view/project_views.store.ts +++ b/web/store/project-view/project_views.store.ts @@ -142,12 +142,7 @@ export class ProjectViewsStore implements IProjectViewsStore { createView = async (workspaceSlug: string, projectId: string, data: Partial): Promise => { try { - const response = await this.viewService.createView( - workspaceSlug, - projectId, - data, - this.rootStore.user.currentUser - ); + const response = await this.viewService.createView(workspaceSlug, projectId, data); runInAction(() => { this.viewsList = { @@ -191,13 +186,7 @@ export class ProjectViewsStore implements IProjectViewsStore { }; }); - const response = await this.viewService.patchView( - workspaceSlug, - projectId, - viewId, - data, - this.rootStore.user.currentUser - ); + const response = await this.viewService.patchView(workspaceSlug, projectId, viewId, data); return response; } catch (error) { @@ -220,7 +209,7 @@ export class ProjectViewsStore implements IProjectViewsStore { }; }); - await this.viewService.deleteView(workspaceSlug, projectId, viewId, this.rootStore.user.currentUser); + await this.viewService.deleteView(workspaceSlug, projectId, viewId); } catch (error) { this.fetchAllViews(workspaceSlug, projectId); diff --git a/web/store/project/project-estimates.store.ts b/web/store/project/project-estimates.store.ts index 0cb51c2dc..f634d3fd9 100644 --- a/web/store/project/project-estimates.store.ts +++ b/web/store/project/project-estimates.store.ts @@ -49,12 +49,7 @@ export class ProjectEstimatesStore implements IProjectEstimateStore { createEstimate = async (workspaceSlug: string, projectId: string, data: IEstimateFormData) => { try { - const response = await this.estimateService.createEstimate( - workspaceSlug, - projectId, - data, - this.rootStore.user.currentUser! - ); + const response = await this.estimateService.createEstimate(workspaceSlug, projectId, data); const responseEstimate = { ...response.estimate, @@ -88,13 +83,7 @@ export class ProjectEstimatesStore implements IProjectEstimateStore { }); try { - const response = await this.estimateService.patchEstimate( - workspaceSlug, - projectId, - estimateId, - data, - this.rootStore.user.currentUser! - ); + const response = await this.estimateService.patchEstimate(workspaceSlug, projectId, estimateId, data); await this.rootStore.project.fetchProjectEstimates(workspaceSlug, projectId); return response; @@ -126,7 +115,7 @@ export class ProjectEstimatesStore implements IProjectEstimateStore { try { // deleting using api - await this.estimateService.deleteEstimate(workspaceSlug, projectId, estimateId, this.rootStore.user.currentUser!); + await this.estimateService.deleteEstimate(workspaceSlug, projectId, estimateId); } catch (error) { console.log("Failed to delete estimate from project store"); // reverting back to original estimate list diff --git a/web/store/project/project-label.store.ts b/web/store/project/project-label.store.ts index d6a804a60..2bc7b9794 100644 --- a/web/store/project/project-label.store.ts +++ b/web/store/project/project-label.store.ts @@ -119,12 +119,7 @@ export class ProjectLabelStore implements IProjectLabelStore { createLabel = async (workspaceSlug: string, projectId: string, data: Partial) => { try { - const response = await this.issueLabelService.createIssueLabel( - workspaceSlug, - projectId, - data, - this.rootStore.user.currentUser! - ); + const response = await this.issueLabelService.createIssueLabel(workspaceSlug, projectId, data); runInAction(() => { this.labels = { @@ -208,13 +203,7 @@ export class ProjectLabelStore implements IProjectLabelStore { }); try { - const response = await this.issueLabelService.patchIssueLabel( - workspaceSlug, - projectId, - labelId, - data, - this.rootStore.user.currentUser! - ); + const response = await this.issueLabelService.patchIssueLabel(workspaceSlug, projectId, labelId, data); return response; } catch (error) { @@ -243,12 +232,7 @@ export class ProjectLabelStore implements IProjectLabelStore { try { // deleting using api - await this.issueLabelService.deleteIssueLabel( - workspaceSlug, - projectId, - labelId, - this.rootStore.user.currentUser! - ); + await this.issueLabelService.deleteIssueLabel(workspaceSlug, projectId, labelId); } catch (error) { console.log("Failed to delete label from project store"); // reverting back to original label list diff --git a/web/store/project/project-state.store.ts b/web/store/project/project-state.store.ts index b0b136cb2..2c4247b75 100644 --- a/web/store/project/project-state.store.ts +++ b/web/store/project/project-state.store.ts @@ -4,8 +4,7 @@ import { RootStore } from "../root"; import { IState } from "types"; // services import { ProjectService, ProjectStateService } from "services/project"; -import { groupBy, orderArrayBy, groupByField } from "helpers/array.helper"; -import { orderStateGroups } from "helpers/state.helper"; +import { groupByField } from "helpers/array.helper"; export interface IProjectStateStore { loader: boolean; @@ -104,12 +103,7 @@ export class ProjectStateStore implements IProjectStateStore { createState = async (workspaceSlug: string, projectId: string, data: Partial) => { try { - const response = await this.stateService.createState( - workspaceSlug, - projectId, - data, - this.rootStore.user.currentUser! - ); + const response = await this.stateService.createState(workspaceSlug, projectId, data); runInAction(() => { this.states = { @@ -143,13 +137,7 @@ export class ProjectStateStore implements IProjectStateStore { }; }); - const response = await this.stateService.patchState( - workspaceSlug, - projectId, - stateId, - data, - this.rootStore.user.currentUser! - ); + const response = await this.stateService.patchState(workspaceSlug, projectId, stateId, data); return response; } catch (error) { @@ -179,7 +167,7 @@ export class ProjectStateStore implements IProjectStateStore { }); // deleting using api - await this.stateService.deleteState(workspaceSlug, projectId, stateId, this.rootStore.user.currentUser!); + await this.stateService.deleteState(workspaceSlug, projectId, stateId); } catch (error) { console.log("Failed to delete state from project store"); // reverting back to original label list @@ -259,13 +247,7 @@ export class ProjectStateStore implements IProjectStateStore { }; }); - await this.stateService.patchState( - workspaceSlug, - projectId, - stateId, - { sequence: newSequence }, - this.rootStore.user.currentUser! - ); + await this.stateService.patchState(workspaceSlug, projectId, stateId, { sequence: newSequence }); } catch (err) { console.log("Failed to move state position"); // reverting back to old state group if api fails diff --git a/web/store/project/project.store.ts b/web/store/project/project.store.ts index d7979f3f5..3216a5e74 100644 --- a/web/store/project/project.store.ts +++ b/web/store/project/project.store.ts @@ -384,7 +384,7 @@ export class ProjectStore implements IProjectStore { this.loader = true; this.error = null; - const response = await this.projectService.leaveProject(workspaceSlug, projectId, this.rootStore.user); + const response = await this.projectService.leaveProject(workspaceSlug, projectId); await this.fetchProjects(workspaceSlug); runInAction(() => { @@ -402,7 +402,7 @@ export class ProjectStore implements IProjectStore { createProject = async (workspaceSlug: string, data: any) => { try { - const response = await this.projectService.createProject(workspaceSlug, data, this.rootStore.user.currentUser); + const response = await this.projectService.createProject(workspaceSlug, data); runInAction(() => { this.projects = { ...this.projects, @@ -433,12 +433,7 @@ export class ProjectStore implements IProjectStore { }; }); - const response = await this.projectService.updateProject( - workspaceSlug, - projectId, - data, - this.rootStore.user.currentUser - ); + const response = await this.projectService.updateProject(workspaceSlug, projectId, data); return response; } catch (error) { console.log("Failed to create project from project store"); @@ -451,7 +446,7 @@ export class ProjectStore implements IProjectStore { deleteProject = async (workspaceSlug: string, projectId: string) => { try { - await this.projectService.deleteProject(workspaceSlug, projectId, this.rootStore.user.currentUser); + await this.projectService.deleteProject(workspaceSlug, projectId); await this.fetchProjects(workspaceSlug); } catch (error) { console.log("Failed to delete project from project store"); diff --git a/web/store/user.store.ts b/web/store/user.store.ts index 6b7e41548..177694f53 100644 --- a/web/store/user.store.ts +++ b/web/store/user.store.ts @@ -282,7 +282,7 @@ class UserStore implements IUserStore { if (!user) return; - await this.userService.updateUserOnBoard({ userRole: user.role }, user); + await this.userService.updateUserOnBoard(); } catch (error) { this.fetchCurrentUser(); @@ -300,7 +300,7 @@ class UserStore implements IUserStore { } as IUser; }); - const response = await this.userService.updateUserTourCompleted(this.currentUser); + const response = await this.userService.updateUserTourCompleted(); return response; } diff --git a/web/store/workspace/workspace-member.store.ts b/web/store/workspace/workspace-member.store.ts index b9803d1f1..2f36e6eea 100644 --- a/web/store/workspace/workspace-member.store.ts +++ b/web/store/workspace/workspace-member.store.ts @@ -1,7 +1,7 @@ import { action, computed, observable, makeObservable, runInAction } from "mobx"; import { RootStore } from "../root"; // types -import { IUser, IWorkspaceMember, IWorkspaceMemberInvitation, IWorkspaceBulkInviteFormData } from "types"; +import { IWorkspaceMember, IWorkspaceMemberInvitation, IWorkspaceBulkInviteFormData } from "types"; // services import { WorkspaceService } from "services/workspace.service"; @@ -175,7 +175,7 @@ export class WorkspaceMemberStore implements IWorkspaceMemberStore { */ inviteMembersToWorkspace = async (workspaceSlug: string, data: IWorkspaceBulkInviteFormData) => { try { - await this.workspaceService.inviteWorkspace(workspaceSlug, data, this.rootStore.user.currentUser as IUser); + await this.workspaceService.inviteWorkspace(workspaceSlug, data); await this.fetchWorkspaceMemberInvitations(workspaceSlug); } catch (error) { throw error; diff --git a/web/store/workspace/workspace.store.ts b/web/store/workspace/workspace.store.ts index 5fa071cd3..e4e4f3ea4 100644 --- a/web/store/workspace/workspace.store.ts +++ b/web/store/workspace/workspace.store.ts @@ -212,9 +212,7 @@ export class WorkspaceStore implements IWorkspaceStore { this.error = null; }); - const user = this.rootStore.user.currentUser ?? undefined; - - const response = await this.workspaceService.createWorkspace(data, user); + const response = await this.workspaceService.createWorkspace(data); runInAction(() => { this.loader = false; @@ -247,9 +245,7 @@ export class WorkspaceStore implements IWorkspaceStore { this.error = null; }); - const user = this.rootStore.user.currentUser ?? undefined; - - const response = await this.workspaceService.updateWorkspace(workspaceSlug, data, user); + const response = await this.workspaceService.updateWorkspace(workspaceSlug, data); runInAction(() => { this.loader = false; @@ -281,9 +277,7 @@ export class WorkspaceStore implements IWorkspaceStore { this.error = null; }); - const user = this.rootStore.user.currentUser ?? undefined; - - await this.workspaceService.deleteWorkspace(workspaceSlug, user); + await this.workspaceService.deleteWorkspace(workspaceSlug); runInAction(() => { this.loader = false; diff --git a/web/types/app.d.ts b/web/types/app.d.ts index c762fb76f..d5a7953b1 100644 --- a/web/types/app.d.ts +++ b/web/types/app.d.ts @@ -9,4 +9,6 @@ export interface IAppConfig { github_client_id: string | null; magic_login: boolean; slack_client_id: string | null; + posthog_api_key: string | null; + posthog_host: string | null; } diff --git a/yarn.lock b/yarn.lock index eef1655f4..53210f2ca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1519,35 +1519,35 @@ resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz#08d6c5e20cf7e4cc02fd181c4b0c225cd31dbb60" integrity sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA== -"@mui/base@5.0.0-beta.22": - version "5.0.0-beta.22" - resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.22.tgz#9ea6be6c8bfc4d8f825660da36d228f5315d4706" - integrity sha512-l4asGID5tmyerx9emJfXOKLyXzaBtdXNIFE3M+IrSZaFtGFvaQKHhc3+nxxSxPf1+G44psjczM0ekRQCdXx9HA== +"@mui/base@5.0.0-beta.23": + version "5.0.0-beta.23" + resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.23.tgz#dd10dfc609d8937749521f940965f757fa3c0f2c" + integrity sha512-9L8SQUGAWtd/Qi7Qem26+oSSgpY7f2iQTuvcz/rsGpyZjSomMMO6lwYeQSA0CpWM7+aN7eGoSY/WV6wxJiIxXw== dependencies: "@babel/runtime" "^7.23.2" "@floating-ui/react-dom" "^2.0.2" "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.16" + "@mui/utils" "^5.14.17" "@popperjs/core" "^2.11.8" clsx "^2.0.0" prop-types "^15.8.1" -"@mui/core-downloads-tracker@^5.14.16": - version "5.14.16" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.16.tgz#03ceb422d69a33e6c1cbd7e943cf60816878be2a" - integrity sha512-97isBjzH2v1K7oB4UH2f4NOkBShOynY6dhnoR2XlUk/g6bb7ZBv2I3D1hvvqPtpEigKu93e7f/jAYr5d9LOc5w== +"@mui/core-downloads-tracker@^5.14.17": + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.17.tgz#68ec40ea00832fb685f09bd493648b1f68f5baf4" + integrity sha512-eE0uxrpJAEL2ZXkeGLKg8HQDafsiXY+6eNpP4lcv3yIjFfGbU6Hj9/P7Adt8jpU+6JIhmxvILGj2r27pX+zdrQ== "@mui/material@^5.14.1": - version "5.14.16" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.16.tgz#45cd62d312d10399d3813ee6dc43bd1f11179bf4" - integrity sha512-W4zZ4vnxgGk6/HqBwgsDHKU7x2l2NhX+r8gAwfg58Rhu3ikfY7NkIS6y8Gl3NkATc4GG1FNaGjjpQKfJx3U6Jw== + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.17.tgz#8e11098e52965be3e9ed117d6c107bbe511fac46" + integrity sha512-+y0VeOLWfEA4Z98We/UH6KCo8+f2HLZDK45FY+sJf8kSojLy3VntadKtC/u0itqnXXb1Pr4wKB2tSIBW02zY4Q== dependencies: "@babel/runtime" "^7.23.2" - "@mui/base" "5.0.0-beta.22" - "@mui/core-downloads-tracker" "^5.14.16" - "@mui/system" "^5.14.16" + "@mui/base" "5.0.0-beta.23" + "@mui/core-downloads-tracker" "^5.14.17" + "@mui/system" "^5.14.17" "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.16" + "@mui/utils" "^5.14.17" "@types/react-transition-group" "^4.4.8" clsx "^2.0.0" csstype "^3.1.2" @@ -1555,35 +1555,35 @@ react-is "^18.2.0" react-transition-group "^4.4.5" -"@mui/private-theming@^5.14.16": - version "5.14.16" - resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.14.16.tgz#ffdc9a9d3deaa46af000f04c0a9cc3a982f73071" - integrity sha512-FNlL0pTSEBh8nXsVWreCHDSHk+jG8cBx1sxRbT8JVtL+PYbYPi802zfV4B00Kkf0LNRVRvAVQwojMWSR/MYGng== +"@mui/private-theming@^5.14.17": + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.14.17.tgz#2fdf9d7df54dcb27e8ae7e00f440eb8310376ec3" + integrity sha512-u4zxsCm9xmQrlhVPug+Ccrtsjv7o2+rehvrgHoh0siSguvVgVQq5O3Hh10+tp/KWQo2JR4/nCEwquSXgITS1+g== dependencies: "@babel/runtime" "^7.23.2" - "@mui/utils" "^5.14.16" + "@mui/utils" "^5.14.17" prop-types "^15.8.1" -"@mui/styled-engine@^5.14.16": - version "5.14.16" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.14.16.tgz#a4a78a9980f138c2e705d04d67d44051f5005f22" - integrity sha512-FfvYvTG/Zd+KXMMImbcMYEeQAbONGuX5Vx3gBmmtB6KyA7Mvm9Pma1ly3R0gc44yeoFd+2wBjn1feS8h42HW5w== +"@mui/styled-engine@^5.14.17": + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.14.17.tgz#7f79d863604076db5278bd38a2eeac44cd2ed336" + integrity sha512-AqpVjBEA7wnBvKPW168bNlqB6EN7HxTjLOY7oi275AzD/b1C7V0wqELy6NWoJb2yya5sRf7ENf4iNi3+T5cOgw== dependencies: "@babel/runtime" "^7.23.2" "@emotion/cache" "^11.11.0" csstype "^3.1.2" prop-types "^15.8.1" -"@mui/system@^5.14.16": - version "5.14.16" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.16.tgz#5c30c5123767416358c3b73774eb985e189119a4" - integrity sha512-uKnPfsDqDs8bbN54TviAuoGWOmFiQLwNZ3Wvj+OBkJCzwA6QnLb/sSeCB7Pk3ilH4h4jQ0BHtbR+Xpjy9wlOuA== +"@mui/system@^5.14.17": + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.17.tgz#3e212d1e699d4c777bbe5c6584ae129b1ef7d8bc" + integrity sha512-Ccz3XlbCqka6DnbHfpL3o3TfOeWQPR+ewvNAgm8gnS9M0yVMmzzmY6z0w/C1eebb+7ZP7IoLUj9vojg/GBaTPg== dependencies: "@babel/runtime" "^7.23.2" - "@mui/private-theming" "^5.14.16" - "@mui/styled-engine" "^5.14.16" + "@mui/private-theming" "^5.14.17" + "@mui/styled-engine" "^5.14.17" "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.16" + "@mui/utils" "^5.14.17" clsx "^2.0.0" csstype "^3.1.2" prop-types "^15.8.1" @@ -1593,10 +1593,10 @@ resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.8.tgz#2ed4402f104d65fcd4f460ca358654c8935e2285" integrity sha512-9u0ji+xspl96WPqvrYJF/iO+1tQ1L5GTaDOeG3vCR893yy7VcWwRNiVMmPdPNpMDqx0WV1wtEW9OMwK9acWJzQ== -"@mui/utils@^5.14.16": - version "5.14.16" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.16.tgz#09a15fd45530cadc642c5c08eb6cc660ea230506" - integrity sha512-3xV31GposHkwRbQzwJJuooWpK2ybWdEdeUPtRjv/6vjomyi97F3+68l+QVj9tPTvmfSbr2sx5c/NuvDulrdRmA== +"@mui/utils@^5.14.17": + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.17.tgz#8e2e7ca58865119eec8c6bdb359f539c25aaf576" + integrity sha512-yxnWgSS4J6DMFPw2Dof85yBkG02VTbEiqsikymMsnZnXDurtVGTIhlNuV24GTmFTuJMzEyTTU9UF+O7zaL8LEQ== dependencies: "@babel/runtime" "^7.23.2" "@types/prop-types" "^15.7.9" @@ -2598,21 +2598,21 @@ integrity sha512-rhlLWwVkOodBGRMK0mAmE34l2a+BqM2Y7q1ViuQRBhs/6sZ8d83O4hARHKVwqT5stY4i1l7d7PoemV3uAGI6+g== "@types/debug@^4.0.0": - version "4.1.10" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.10.tgz#f23148a6eb771a34c466a4fc28379d8101e84494" - integrity sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA== + version "4.1.11" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.11.tgz#b20d24098288f19e48fdf776c5d9ccd024629e4e" + integrity sha512-R2qflTjHDs4CL6D/6TkqBeIHr54WzZfIxN729xvCNlYIVp2LknlnCro5Yo3frNaX2E5gO9pZ3/QAPVdGmu+q9w== dependencies: "@types/ms" "*" "@types/dom4@^2.0.2": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/dom4/-/dom4-2.0.3.tgz#bd084dbd4c15bee49442c5cd231acdcd14efbe90" - integrity sha512-xQT2XxtDGP1WFfTB/Lti629HpguNrfZ3dg84bWXASd6JUay6WgR73Wb6DG3kmr2/iGAWZ7NNLceGVWYWfgPX0g== + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/dom4/-/dom4-2.0.4.tgz#427a4ce8590727aed5ce0fe39a64f175a57fdc1c" + integrity sha512-PD+wqNhrjWFjAlSVd18jvChZvOXB2SOwAILBmuYev5zswBats5qmzs/QFoooLKd2omj9BT05a8MeSeRmXLGY+Q== "@types/estree@*", "@types/estree@^1.0.0": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.4.tgz#d9748f5742171b26218516cf1828b8eafaf8a9fa" - integrity sha512-2JwWnHK9H+wUZNorf2Zr6ves96WHoWDJIftkcxPKsS7Djta6Zu519LarhRNljPXkpsZR2ZMwNCPeW7omW07BJw== + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== "@types/estree@0.0.39": version "0.0.39" @@ -2642,22 +2642,22 @@ "@types/unist" "*" "@types/hoist-non-react-statics@^3.3.1": - version "3.3.4" - resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.4.tgz#cc477ce0283bb9d19ea0cbfa2941fe2c8493a1be" - integrity sha512-ZchYkbieA+7tnxwX/SCBySx9WwvWR8TaP5tb2jRAzwvLb/rWchGw3v0w3pqUbUvj0GCwW2Xz/AVPSk6kUGctXQ== + version "3.3.5" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz#dab7867ef789d87e2b4b0003c9d65c49cc44a494" + integrity sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg== dependencies: "@types/react" "*" hoist-non-react-statics "^3.3.0" "@types/js-cookie@^3.0.2", "@types/js-cookie@^3.0.3": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-3.0.5.tgz#5eba4033a4f17fb2b29d975892694315194eca33" - integrity sha512-dtLshqoiGRDHbHueIT9sjkd2F4tW1qPSX2xKAQK8p1e6pM+Z913GM1shv7dOqqasEMYbC5zEaClJomQe8OtQLA== + version "3.0.6" + resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-3.0.6.tgz#a04ca19e877687bd449f5ad37d33b104b71fdf95" + integrity sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ== "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.14" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.14.tgz#74a97a5573980802f32c8e47b663530ab3b6b7d1" - integrity sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw== + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/json5@^0.0.29": version "0.0.29" @@ -2665,14 +2665,14 @@ integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== "@types/linkify-it@*": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.4.tgz#def6a9bb0ce78140860602f16ace37a9997f086a" - integrity sha512-hPpIeeHb/2UuCw06kSNAOVWgehBLXEo0/fUs0mw3W2qhqX89PI2yvok83MnuctYGCPrabGIoi0fFso4DQ+sNUQ== + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.5.tgz#1e78a3ac2428e6d7e6c05c1665c242023a4601d8" + integrity sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw== "@types/lodash.debounce@^4.0.7": - version "4.0.8" - resolved "https://registry.yarnpkg.com/@types/lodash.debounce/-/lodash.debounce-4.0.8.tgz#d5fe36a35aa57773e05d960b3e3c703fd9ffb8b3" - integrity sha512-REumepIJjQFSOaBUoj81U5ZzF9YIhovzE2Lm6ejUbycmwx597k2ivG1cVfPtAj4eVuSbGoZDkJR0sRIahsE6/Q== + version "4.0.9" + resolved "https://registry.yarnpkg.com/@types/lodash.debounce/-/lodash.debounce-4.0.9.tgz#0f5f21c507bce7521b5e30e7a24440975ac860a5" + integrity sha512-Ma5JcgTREwpLRwMM+XwBR7DaWe96nC38uCBDFKZWbNKD+osjVzdpnUSwBcqCptrp16sSOLBAUb50Car5I0TCsQ== dependencies: "@types/lodash" "*" @@ -2697,9 +2697,9 @@ "@types/unist" "^2" "@types/mdurl@*": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.4.tgz#574bfbec51eb41ab5f444116c8555bc4347feba5" - integrity sha512-ARVxjAEX5TARFRzpDRVC6cEk0hUIXCCwaMhz8y7S1/PxU6zZS1UMjyobz7q4w/D/R552r4++EhwmXK1N2rAy0A== + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.5.tgz#3e0d2db570e9fb6ccb2dc8fde0be1d79ac810d39" + integrity sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA== "@types/minimatch@*": version "5.1.2" @@ -2707,9 +2707,9 @@ integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== "@types/ms@*": - version "0.7.33" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.33.tgz#80bf1da64b15f21fd8c1dc387c31929317d99ee9" - integrity sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ== + version "0.7.34" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433" + integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== "@types/node@*", "@types/node@^20.5.2": version "20.8.10" @@ -2734,29 +2734,29 @@ integrity sha512-p6ua9zBxz5otCmbpb5D3U4B5Nanw6Pk3PPyX05xnxbB/fRv71N7CPmORg7uAD5P70T0xmx1pzAx/FUfa5X+3cw== "@types/nprogress@^0.2.0": - version "0.2.2" - resolved "https://registry.yarnpkg.com/@types/nprogress/-/nprogress-0.2.2.tgz#c73bf540ac7926fb1b6d03f9d2725e07b3848d65" - integrity sha512-2wLrSJXLztGmr7wXwM0hA/wuIOY9DznVdd+ZFofHOiXcj9JnVt+2ZeLRJ7v5ZVlmheSkUOSg3Q3O4Ce7yji79A== + version "0.2.3" + resolved "https://registry.yarnpkg.com/@types/nprogress/-/nprogress-0.2.3.tgz#b2150b054a13622fabcba12cf6f0b54c48b14287" + integrity sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA== "@types/object.omit@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/object.omit/-/object.omit-3.0.2.tgz#13d23915cc16fa54b0d4cfbcb79840f4fe1474d9" - integrity sha512-BxWU36cMP+FKD3OLFluQaj2cBev2sx2LJaHELuphHwnleq+xnEhTmuYYYx4pOT/1U/ZoR6B+RdvxWh2FD6lGGA== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/object.omit/-/object.omit-3.0.3.tgz#cc52b1d9774c1619b5c6fc50229d087f01eabd68" + integrity sha512-xrq4bQTBGYY2cw+gV4PzoG2Lv3L0pjZ1uXStRRDQoATOYW1lCsFQHhQ+OkPhIcQoqLjAq7gYif7D14Qaa6Zbew== "@types/object.pick@^1.3.2": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@types/object.pick/-/object.pick-1.3.3.tgz#f4d4a76e9ef1161e965b963d2bb33c3f6c300125" - integrity sha512-qZqHmdGEALeSATMB1djT1S5szv6Wtpb7DKpHrt2XG4iyKlV7C2Xk8GmDXr1KXakOqUfX6ohw7ceruYt4NVmB1Q== + version "1.3.4" + resolved "https://registry.yarnpkg.com/@types/object.pick/-/object.pick-1.3.4.tgz#1a38b6e69a35f36ec2dcc8b9f5ffd555c1c4d7fc" + integrity sha512-5PjwB0uP2XDp3nt5u5NJAG2DORHIRClPzWT/TTZhJ2Ekwe8M5bA9tvPdi9NO/n2uvu2/ictat8kgqvLfcIE1SA== "@types/parse-json@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.1.tgz#27f7559836ad796cea31acb63163b203756a5b4e" - integrity sha512-3YmXzzPAdOTVljVMkTMBdBEvlOLg2cDQaDhnnhT3nT9uDbnJzjWhKlzb+desT12Y7tGqaN6d+AbozcKzyL36Ng== + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== "@types/prop-types@*", "@types/prop-types@^15.0.0", "@types/prop-types@^15.7.9": - version "15.7.9" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.9.tgz#b6f785caa7ea1fe4414d9df42ee0ab67f23d8a6d" - integrity sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g== + version "15.7.10" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.10.tgz#892afc9332c4d62a5ea7e897fe48ed2085bbb08a" + integrity sha512-mxSnDQxPqsZxmeShFH+uwQ4kO4gcJcGahjjMFeLbKE95IAZiiZyiEepGZjtXJ7hN/yfu0bu9xN2ajcU0JcxX6A== "@types/react-color@^3.0.6", "@types/react-color@^3.0.9": version "3.0.9" @@ -2783,13 +2783,6 @@ dependencies: "@types/react" "*" -"@types/react-dom@18.2.0": - version "18.2.0" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.0.tgz#374f28074bb117f56f58c4f3f71753bebb545156" - integrity sha512-8yQrvS6sMpSwIovhPOwfyNf2Wz6v/B62LFSVYQ85+Rq3tLsBIG7rP5geMxaijTUxSkrO6RzN/IRuIAADYQsleA== - dependencies: - "@types/react" "*" - "@types/react-dom@^18.2.14": version "18.2.14" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.14.tgz#c01ba40e5bb57fc1dc41569bb3ccdb19eab1c539" @@ -2797,6 +2790,13 @@ dependencies: "@types/react" "*" +"@types/react-dom@^18.2.15": + version "18.2.15" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.15.tgz#921af67f9ee023ac37ea84b1bc0cc40b898ea522" + integrity sha512-HWMdW+7r7MR5+PZqJF6YFNSCtjz1T0dsvo/f1BV6HkV+6erD/nA7wd9NM00KVG83zf2nJ7uATPO9ttdIPvi3gg== + dependencies: + "@types/react" "*" + "@types/react-transition-group@^4.4.8": version "4.4.8" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.8.tgz#46f87d80512959cac793ecc610a93d80ef241ccf" @@ -2804,7 +2804,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@18.0.28", "@types/react@18.2.0", "@types/react@^18.2.35", "@types/react@^18.2.5": +"@types/react@*", "@types/react@18.0.28", "@types/react@18.2.0", "@types/react@^18.2.35", "@types/react@^18.2.37", "@types/react@^18.2.5": version "18.2.0" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.0.tgz#15cda145354accfc09a18d2f2305f9fc099ada21" integrity sha512-0FLj93y5USLHdnhIhABk83rm8XEGA7kH3cr+YUlvxoUGp1xNt/DINUMvqPxLyOQMzLmZe8i4RTHbvb8MC7NmrA== @@ -4020,9 +4020,9 @@ ejs@^3.1.6: jake "^10.8.5" electron-to-chromium@^1.4.535: - version "1.4.576" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.576.tgz#0c6940fdc0d60f7e34bd742b29d8fa847c9294d1" - integrity sha512-yXsZyXJfAqzWk1WKryr0Wl0MN2D47xodPvEEwlVePBnhU5E7raevLQR+E6b9JAD3GfL/7MbAL9ZtWQQPcLx7wA== + version "1.4.577" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.577.tgz#a732f11cf4532be96e5e3f1197dcda54c2cec7ad" + integrity sha512-/5xHPH6f00SxhHw6052r+5S1xO7gHNc89hV7tqlvnStvKbSrDqc/u6AlwPvVWWNj+s4/KL6T6y8ih+nOY0qYNA== emoji-regex@^8.0.0: version "8.0.0" @@ -4874,9 +4874,9 @@ fast-fifo@^1.1.0, fast-fifo@^1.2.0: integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" - integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -4908,6 +4908,11 @@ fault@^2.0.0: dependencies: format "^0.2.0" +fflate@^0.4.1: + version "0.4.8" + resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.4.8.tgz#f90b82aefbd8ac174213abb338bd7ef848f0f5ae" + integrity sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA== + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -6998,6 +7003,13 @@ postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.29: picocolors "^1.0.0" source-map-js "^1.0.2" +posthog-js@^1.88.4: + version "1.88.4" + resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.88.4.tgz#480995e18b2c3052f29142a6c5f02e1eafadc759" + integrity sha512-ZKgC0q22Bv0WGsi/BJcamDIoBR3DPpF26kCq0eFxtV3gKDMpGIlhlODQCo28bSENziGVO4LSeGrUvo/6OsQ7xA== + dependencies: + fflate "^0.4.1" + prebuild-install@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" @@ -8314,9 +8326,9 @@ tippy.js@^6.3.7: "@popperjs/core" "^2.9.0" tiptap-markdown@^0.8.2: - version "0.8.3" - resolved "https://registry.yarnpkg.com/tiptap-markdown/-/tiptap-markdown-0.8.3.tgz#51e93aad3c603c75a91111494ef4fd04115165fe" - integrity sha512-RULu1OXFTHdTJCHwdUOvDk0nDoH8YdgXulR0f+8XBd/x+SuT+EafdQuEKz2ggFlW1Mvl5niKGT5lAHTeXYFmaw== + version "0.8.4" + resolved "https://registry.yarnpkg.com/tiptap-markdown/-/tiptap-markdown-0.8.4.tgz#d6cdbd6e4aa88b58c3c149c2d0d25c70b3e11ac9" + integrity sha512-aCwr8cpVdZeb/2J0ffz8PvpLmQBcFE9GOxk2vB0Y9zlJEGWnSiGo1BWnwaeiyAdQqfBzV7NyNg+oz2A/MbC/Sg== dependencies: "@types/markdown-it" "^12.2.3" markdown-it "^13.0.1"