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>
This commit is contained in:
sriram veeraghanta 2023-11-20 13:29:54 +05:30
parent 33be52792f
commit 78fee22fec
114 changed files with 825 additions and 2768 deletions

View file

@ -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<IGptResponse> {
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;
});

View file

@ -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<any> {
async createCycle(workspaceSlug: string, projectId: string, data: any): Promise<any> {
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<ICycle>,
user: IUser | undefined
): Promise<any> {
async patchCycle(workspaceSlug: string, projectId: string, cycleId: string, data: Partial<ICycle>): Promise<any> {
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<any> {
async deleteCycle(workspaceSlug: string, projectId: string, cycleId: string): Promise<any> {
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;
});

View file

@ -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<any> {
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<IInboxIssue> {
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<IInboxIssue> },
user: IUser | undefined
data: { issue: Partial<IInboxIssue> }
): Promise<any> {
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<IInboxIssue> {
async createInboxIssue(workspaceSlug: string, projectId: string, inboxId: string, data: any): Promise<IInboxIssue> {
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;
});

View file

@ -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<any> {
async createGithubServiceImport(workspaceSlug: string, data: IGithubServiceImportFormData): Promise<any> {
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;
});

View file

@ -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<any> {
async deleteImporterService(workspaceSlug: string, service: string, importerId: string): Promise<any> {
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;
});

View file

@ -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<IJiraResponse> {
async createJiraImporter(workspaceSlug: string, data: IJiraImporterForm): Promise<IJiraResponse> {
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;
});

View file

@ -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<any> {
async createIssue(workspaceSlug: string, projectId: string, data: any): Promise<any> {
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<IIssue>,
user: IUser | undefined
): Promise<any> {
async patchIssue(workspaceSlug: string, projectId: string, issueId: string, data: Partial<IIssue>): Promise<any> {
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<any> {
async deleteIssue(workspaceSlug: string, projectId: string, issuesId: string): Promise<any> {
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<any> {
async bulkDeleteIssues(workspaceSlug: string, projectId: string, data: any): Promise<any> {
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;
});

View file

@ -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<IIssueComment>,
user: IUser | undefined
data: Partial<IIssueComment>
): Promise<any> {
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<IIssueComment>,
user: IUser | undefined
data: Partial<IIssueComment>
): Promise<any> {
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<any> {
async deleteIssueComment(workspaceSlug: string, projectId: string, issueId: string, commentId: string): Promise<any> {
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;
});

View file

@ -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<IIssueLabel> {
async createIssueLabel(workspaceSlug: string, projectId: string, data: any): Promise<IIssueLabel> {
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<any> {
async patchIssueLabel(workspaceSlug: string, projectId: string, labelId: string, data: any): Promise<any> {
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<any> {
async deleteIssueLabel(workspaceSlug: string, projectId: string, labelId: string): Promise<any> {
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;
});

View file

@ -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<any> {
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<any> {
async deleteIssueReaction(workspaceSlug: string, projectId: string, issueId: string, reaction: string): Promise<any> {
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<any> {
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<any> {
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;
});

View file

@ -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<IModule> {
async createModule(workspaceSlug: string, projectId: string, data: any): Promise<IModule> {
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<any> {
async updateModule(workspaceSlug: string, projectId: string, moduleId: string, data: any): Promise<any> {
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<IModule>,
user: IUser | undefined
data: Partial<IModule>
): Promise<IModule> {
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<any> {
async deleteModule(workspaceSlug: string, projectId: string, moduleId: string): Promise<any> {
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<any> {
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;
});

View file

@ -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<IPage>,
user: IUser | undefined
): Promise<IPage> {
async createPage(workspaceSlug: string, projectId: string, data: Partial<IPage>): Promise<IPage> {
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<IPage>,
user: IUser | undefined
): Promise<IPage> {
async patchPage(workspaceSlug: string, projectId: string, pageId: string, data: Partial<IPage>): Promise<IPage> {
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<any> {
async deletePage(workspaceSlug: string, projectId: string, pageId: string): Promise<any> {
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<IPageBlock>,
user: IUser | undefined
data: Partial<IPageBlock>
): Promise<IPageBlock> {
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<IPageBlock>,
user: IUser | undefined
data: Partial<IPageBlock>
): Promise<IPage> {
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<any> {
async deletePageBlock(workspaceSlug: string, projectId: string, pageId: string, pageBlockId: string): Promise<any> {
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<IIssue> {
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;
});

View file

@ -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<any> {
async createEstimate(workspaceSlug: string, projectId: string, data: IEstimateFormData): Promise<any> {
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<any> {
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<any> {
async deleteEstimate(workspaceSlug: string, projectId: string, estimateId: string): Promise<any> {
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;
});

View file

@ -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<any> {
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;
});

View file

@ -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<any> {
async bulkAddMembersToProject(workspaceSlug: string, projectId: string, data: IProjectBulkAddFormData): Promise<any> {
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;
});

View file

@ -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<IState> {
async createState(workspaceSlug: string, projectId: string, data: any): Promise<IState> {
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<any> {
async updateState(workspaceSlug: string, projectId: string, stateId: string, data: IState): Promise<any> {
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<IState>,
user: IUser | undefined
): Promise<any> {
async patchState(workspaceSlug: string, projectId: string, stateId: string, data: Partial<IState>): Promise<any> {
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<any> {
async deleteState(workspaceSlug: string, projectId: string, stateId: string): Promise<any> {
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;
});

View file

@ -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<IProject>, user: any): Promise<IProject> {
async createProject(workspaceSlug: string, data: Partial<IProject>): Promise<IProject> {
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<IProject>, user: any): Promise<IProject> {
async updateProject(workspaceSlug: string, projectId: string, data: Partial<IProject>): Promise<IProject> {
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<any> {
async deleteProject(workspaceSlug: string, projectId: string): Promise<any> {
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<any> {
async leaveProject(workspaceSlug: string, projectId: string): Promise<any> {
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;
});

View file

@ -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<any> {
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<IProject> | any, eventName: ProjectEventType, user: IUser): Promise<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
if (!trackEvent) return;
return this.request({
url: "/api/track-event",
method: "POST",
data: {
eventName: propertyName,
extra: {
...data,
},
user: user,
},
});
}
async trackIssueCommentEvent(
data: Partial<IIssueComment> | any,
eventName: IssueCommentEventType,
user: IUser | undefined
): Promise<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<IPage> | any, eventName: PagesEventType, user: IUser | undefined): Promise<any> {
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<IPageBlock> | IIssue,
eventName: PageBlocksEventType,
user: IUser
): Promise<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
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<any> {
if (!trackEvent) return;
const payload: any = data;
return this.request({
url: "/api/track-event",
method: "POST",
data: {
eventName,
extra: payload,
user: user,
},
});
}
}

View file

@ -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<any> {
async updateUserOnBoard(): Promise<any> {
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<any> {
async updateUserTourCompleted(): Promise<any> {
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;
});

View file

@ -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<IProjectView>, user: any): Promise<any> {
async createView(workspaceSlug: string, projectId: string, data: Partial<IProjectView>): Promise<any> {
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<IProjectView>,
user: any
): Promise<any> {
async patchView(workspaceSlug: string, projectId: string, viewId: string, data: Partial<IProjectView>): Promise<any> {
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<any> {
async deleteView(workspaceSlug: string, projectId: string, viewId: string): Promise<any> {
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;
});

View file

@ -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<IWorkspace>, user: IUser | undefined): Promise<IWorkspace> {
async createWorkspace(data: Partial<IWorkspace>): Promise<IWorkspace> {
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<IWorkspace>,
user: IUser | undefined
): Promise<IWorkspace> {
async updateWorkspace(workspaceSlug: string, data: Partial<IWorkspace>): Promise<IWorkspace> {
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<any> {
async deleteWorkspace(workspaceSlug: string): Promise<any> {
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<any> {
async inviteWorkspace(workspaceSlug: string, data: IWorkspaceBulkInviteFormData): Promise<any> {
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<any> {
async joinWorkspace(workspaceSlug: string, invitationId: string, data: any): Promise<any> {
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;
});