forked from github/plane
chore: track events for estimates and importers (#1012)
This commit is contained in:
parent
b34cf0c471
commit
93c105c495
@ -63,7 +63,11 @@ const IntegrationGuide = () => {
|
||||
services. This tool will guide you to relocate the issue to Plane.
|
||||
</div>
|
||||
</div>
|
||||
<a href="https://docs.plane.so" target="_blank" rel="noopener noreferrer">
|
||||
<a
|
||||
href="https://docs.plane.so/importers/github"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<div className="flex flex-shrink-0 cursor-pointer items-center gap-2 whitespace-nowrap text-sm font-medium text-[#3F76FF] hover:text-opacity-80">
|
||||
Read More
|
||||
<ArrowRightIcon width={"18px"} color={"#3F76FF"} />
|
||||
@ -124,7 +128,7 @@ const IntegrationGuide = () => {
|
||||
{importerServices ? (
|
||||
importerServices.length > 0 ? (
|
||||
<div className="space-y-2">
|
||||
<div className="divide-y">
|
||||
<div className="divide-y divide-brand-base">
|
||||
{importerServices.map((service) => (
|
||||
<SingleImport
|
||||
key={service.id}
|
||||
|
@ -6,6 +6,8 @@ import { TrashIcon } from "@heroicons/react/24/outline";
|
||||
import { renderShortDateWithYearFormat } from "helpers/date-time.helper";
|
||||
// types
|
||||
import { IImporterService } from "types";
|
||||
// constants
|
||||
import { IMPORTERS_EXPORTERS_LIST } from "constants/workspace";
|
||||
|
||||
type Props = {
|
||||
service: IImporterService;
|
||||
@ -13,17 +15,16 @@ type Props = {
|
||||
handleDelete: () => void;
|
||||
};
|
||||
|
||||
const importersList: { [key: string]: string } = {
|
||||
github: "GitHub",
|
||||
};
|
||||
|
||||
export const SingleImport: React.FC<Props> = ({ service, refreshing, handleDelete }) => (
|
||||
<div className="flex items-center justify-between gap-2 py-3">
|
||||
<div>
|
||||
<h4 className="flex items-center gap-2 text-sm">
|
||||
<span>
|
||||
Import from <span className="font-medium">{importersList[service.service]}</span> to{" "}
|
||||
<span className="font-medium">{service.project_detail.name}</span>
|
||||
Import from{" "}
|
||||
<span className="font-medium">
|
||||
{IMPORTERS_EXPORTERS_LIST.find((i) => i.provider === service.service)?.title}
|
||||
</span>{" "}
|
||||
to <span className="font-medium">{service.project_detail.name}</span>
|
||||
</span>
|
||||
<span
|
||||
className={`rounded px-2 py-0.5 text-xs capitalize ${
|
||||
|
@ -1,10 +1,14 @@
|
||||
// services
|
||||
import APIService from "services/api.service";
|
||||
// types
|
||||
import type { IEstimate, IEstimateFormData, IEstimatePoint } from "types";
|
||||
import type { IEstimate, IEstimateFormData } from "types";
|
||||
import trackEventServices from "services/track-event.service";
|
||||
|
||||
const { NEXT_PUBLIC_API_BASE_URL } = process.env;
|
||||
|
||||
const trackEvent =
|
||||
process.env.NEXT_PUBLIC_TRACK_EVENTS === "true" || process.env.NEXT_PUBLIC_TRACK_EVENTS === "1";
|
||||
|
||||
class ProjectEstimateServices extends APIService {
|
||||
constructor() {
|
||||
super(NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
|
||||
@ -16,7 +20,11 @@ class ProjectEstimateServices extends APIService {
|
||||
data: IEstimateFormData
|
||||
): Promise<any> {
|
||||
return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/estimates/`, data)
|
||||
.then((response) => response?.data)
|
||||
.then((response) => {
|
||||
if (trackEvent)
|
||||
trackEventServices.trackIssueEstimateEvent(response?.data, "ESTIMATE_CREATE");
|
||||
return response?.data;
|
||||
})
|
||||
.catch((error) => {
|
||||
throw error?.response;
|
||||
});
|
||||
@ -32,7 +40,11 @@ class ProjectEstimateServices extends APIService {
|
||||
`/api/workspaces/${workspaceSlug}/projects/${projectId}/estimates/${estimateId}/`,
|
||||
data
|
||||
)
|
||||
.then((response) => response?.data)
|
||||
.then((response) => {
|
||||
if (trackEvent)
|
||||
trackEventServices.trackIssueEstimateEvent(response?.data, "ESTIMATE_UPDATE");
|
||||
return response?.data;
|
||||
})
|
||||
.catch((error) => {
|
||||
throw error?.response?.data;
|
||||
});
|
||||
@ -64,7 +76,11 @@ class ProjectEstimateServices extends APIService {
|
||||
return this.delete(
|
||||
`/api/workspaces/${workspaceSlug}/projects/${projectId}/estimates/${estimateId}/`
|
||||
)
|
||||
.then((response) => response?.data)
|
||||
.then((response) => {
|
||||
if (trackEvent)
|
||||
trackEventServices.trackIssueEstimateEvent(response?.data, "ESTIMATE_DELETE");
|
||||
return response?.data;
|
||||
})
|
||||
.catch((error) => {
|
||||
throw error?.response?.data;
|
||||
});
|
||||
|
@ -1,10 +1,14 @@
|
||||
import APIService from "services/api.service";
|
||||
import trackEventServices from "services/track-event.service";
|
||||
|
||||
import { IGithubRepoInfo, IGithubServiceImportFormData } from "types";
|
||||
|
||||
const { NEXT_PUBLIC_API_BASE_URL } = process.env;
|
||||
|
||||
const integrationServiceType: string = "github";
|
||||
const trackEvent =
|
||||
process.env.NEXT_PUBLIC_TRACK_EVENTS === "true" || process.env.NEXT_PUBLIC_TRACK_EVENTS === "1";
|
||||
|
||||
const integrationServiceType: string = "github";
|
||||
class GithubIntegrationService extends APIService {
|
||||
constructor() {
|
||||
super(NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
|
||||
@ -41,7 +45,11 @@ class GithubIntegrationService extends APIService {
|
||||
`/api/workspaces/${workspaceSlug}/projects/importers/${integrationServiceType}/`,
|
||||
data
|
||||
)
|
||||
.then((response) => response?.data)
|
||||
.then((response) => {
|
||||
if (trackEvent)
|
||||
trackEventServices.trackImporterEvent(response?.data, "GITHUB_IMPORTER_CREATE");
|
||||
return response?.data;
|
||||
})
|
||||
.catch((error) => {
|
||||
throw error?.response?.data;
|
||||
});
|
||||
|
@ -1,9 +1,14 @@
|
||||
import APIService from "services/api.service";
|
||||
import trackEventServices from "services/track-event.service";
|
||||
|
||||
// types
|
||||
import { IAppIntegration, IImporterService, IWorkspaceIntegration } from "types";
|
||||
|
||||
const { NEXT_PUBLIC_API_BASE_URL } = process.env;
|
||||
|
||||
const trackEvent =
|
||||
process.env.NEXT_PUBLIC_TRACK_EVENTS === "true" || process.env.NEXT_PUBLIC_TRACK_EVENTS === "1";
|
||||
|
||||
class IntegrationService extends APIService {
|
||||
constructor() {
|
||||
super(NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
|
||||
@ -49,7 +54,12 @@ class IntegrationService extends APIService {
|
||||
importerId: string
|
||||
): Promise<any> {
|
||||
return this.delete(`/api/workspaces/${workspaceSlug}/importers/${service}/${importerId}/`)
|
||||
.then((res) => res?.data)
|
||||
.then((response) => {
|
||||
const eventName = service === "github" ? "GITHUB_IMPORTER_DELETE" : "JIRA_IMPORTER_DELETE";
|
||||
|
||||
if (trackEvent) trackEventServices.trackImporterEvent(response?.data, eventName);
|
||||
return response?.data;
|
||||
})
|
||||
.catch((error) => {
|
||||
throw error?.response?.data;
|
||||
});
|
||||
|
@ -1,10 +1,14 @@
|
||||
import APIService from "services/api.service";
|
||||
import trackEventServices from "services/track-event.service";
|
||||
|
||||
// types
|
||||
import { IJiraMetadata, IJiraResponse, IJiraImporterForm } from "types";
|
||||
|
||||
const { NEXT_PUBLIC_API_BASE_URL } = process.env;
|
||||
|
||||
const trackEvent =
|
||||
process.env.NEXT_PUBLIC_TRACK_EVENTS === "true" || process.env.NEXT_PUBLIC_TRACK_EVENTS === "1";
|
||||
|
||||
class JiraImportedService extends APIService {
|
||||
constructor() {
|
||||
super(NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
|
||||
@ -22,7 +26,11 @@ class JiraImportedService extends APIService {
|
||||
|
||||
async createJiraImporter(workspaceSlug: string, data: IJiraImporterForm): Promise<IJiraResponse> {
|
||||
return this.post(`/api/workspaces/${workspaceSlug}/projects/importers/jira/`, data)
|
||||
.then((response) => response?.data)
|
||||
.then((response) => {
|
||||
if (trackEvent)
|
||||
trackEventServices.trackImporterEvent(response?.data, "JIRA_IMPORTER_CREATE");
|
||||
return response?.data;
|
||||
})
|
||||
.catch((error) => {
|
||||
throw error?.response?.data;
|
||||
});
|
||||
|
@ -7,6 +7,7 @@ const trackEvent =
|
||||
// types
|
||||
import type {
|
||||
ICycle,
|
||||
IEstimate,
|
||||
IGptResponse,
|
||||
IIssue,
|
||||
IIssueComment,
|
||||
@ -45,7 +46,10 @@ type PagesEventType = "PAGE_CREATE" | "PAGE_UPDATE" | "PAGE_DELETE";
|
||||
|
||||
type ViewEventType = "VIEW_CREATE" | "VIEW_UPDATE" | "VIEW_DELETE";
|
||||
|
||||
type IssueCommentType = "ISSUE_COMMENT_CREATE" | "ISSUE_COMMENT_UPDATE" | "ISSUE_COMMENT_DELETE";
|
||||
type IssueCommentEventType =
|
||||
| "ISSUE_COMMENT_CREATE"
|
||||
| "ISSUE_COMMENT_UPDATE"
|
||||
| "ISSUE_COMMENT_DELETE";
|
||||
|
||||
export type MiscellaneousEventType =
|
||||
| "TOGGLE_CYCLE_ON"
|
||||
@ -73,6 +77,13 @@ type IssueLabelEventType = "ISSUE_LABEL_CREATE" | "ISSUE_LABEL_UPDATE" | "ISSUE_
|
||||
|
||||
type GptEventType = "ASK_GPT" | "USE_GPT_RESPONSE_IN_ISSUE" | "USE_GPT_RESPONSE_IN_PAGE_BLOCK";
|
||||
|
||||
type IssueEstimateEventType = "ESTIMATE_CREATE" | "ESTIMATE_UPDATE" | "ESTIMATE_DELETE";
|
||||
|
||||
type ImporterEventType =
|
||||
| "GITHUB_IMPORTER_CREATE"
|
||||
| "GITHUB_IMPORTER_DELETE"
|
||||
| "JIRA_IMPORTER_CREATE"
|
||||
| "JIRA_IMPORTER_DELETE";
|
||||
class TrackEventServices extends APIService {
|
||||
constructor() {
|
||||
super("/");
|
||||
@ -209,7 +220,7 @@ class TrackEventServices extends APIService {
|
||||
|
||||
async trackIssueCommentEvent(
|
||||
data: Partial<IIssueComment> | any,
|
||||
eventName: IssueCommentType
|
||||
eventName: IssueCommentEventType
|
||||
): Promise<any> {
|
||||
let payload: any;
|
||||
if (eventName !== "ISSUE_COMMENT_DELETE")
|
||||
@ -549,6 +560,61 @@ class TrackEventServices extends APIService {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async trackIssueEstimateEvent(
|
||||
data: { estimate: IEstimate },
|
||||
eventName: IssueEstimateEventType
|
||||
): Promise<any> {
|
||||
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,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async trackImporterEvent(data: any, eventName: ImporterEventType): Promise<any> {
|
||||
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,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const trackEventServices = new TrackEventServices();
|
||||
|
2
apps/app/types/estimate.d.ts
vendored
2
apps/app/types/estimate.d.ts
vendored
@ -8,7 +8,9 @@ export interface IEstimate {
|
||||
updated_by: string;
|
||||
points: IEstimatePoint[];
|
||||
project: string;
|
||||
project_detail: IProject;
|
||||
workspace: string;
|
||||
workspace_detail: IWorkspace;
|
||||
}
|
||||
|
||||
export interface IEstimatePoint {
|
||||
|
Loading…
Reference in New Issue
Block a user