[WEB-4405] chore: workspace settings events (#7312)
* feat: event tracker helper * feat: track click events for `data-ph-element` * fix: handled click events * fix: handled name * chore: tracker element updates * chore: remove export * chore: tracker element type * chore: track element and event helper. * chore: minor improvements * chore: minor refactors * fix: workspace events * fix: added slug * fix: changes nomenclature * fix: nomenclature * chore: update event tracker helper types * fix: data id * refactor: cycle events (#7290) * chore: update event tracker helper types * refactor: cycle events * refactor: cycle events * refactor: cycle event tracker * chore: update tracker elements * chore: check for closest element with data-ph-element attribute --------- Co-authored-by: Prateek Shourya <prateekshourya@Prateeks-MacBook-Pro.local> * Refactor module events (#7291) * chore: update event tracker helper types * refactor: cycle events * refactor: cycle events * refactor: cycle event tracker * refactor: module tracker event and element * chore: update tracker element * chore: revert unnecessary changes --------- Co-authored-by: Prateek Shourya <prateekshourya@Prateeks-MacBook-Pro.local> * refactor: global views, product tour, notifications, onboarding, users and sidebar related events * chore: member tracker events (#7302) * chore: member-tracker-events * fix: constants * refactor: update event tracker constants * refactor: auth related event trackers (#7306) * Chore: state events (#7307) * chore: state events * fix: refactor * chore: project events (#7305) * chore: project-events * fix: refactor * fix: removed hardcoded values * fix: github redirection event * chore: project page tracker events (#7304) * added events for most page events * refactor: simplify lock button event handling in PageLockControl --------- Co-authored-by: Palanikannan M <akashmalinimurugu@gmail.com> Co-authored-by: M. Palanikannan <73993394+Palanikannan1437@users.noreply.github.com> * chore: minor cleanup and import fixes * refactor: added tracker elements for buttons (#7308) Co-authored-by: Prateek Shourya <prateekshourya29@gmail.com> * fix: event type * refactor: posthog group event * chore: removed instances of event tracker (#7309) * refactor: remove event tracker stores and hooks * refactor: remove event tracker store * fix: build errors * clean up event tracker payloads * chore: workspace-settings-events * fix: refactor --------- Co-authored-by: Prateek Shourya <prateekshourya@Prateeks-MacBook-Pro.local> Co-authored-by: Prateek Shourya <prateekshourya29@gmail.com> Co-authored-by: Palanikannan M <akashmalinimurugu@gmail.com> Co-authored-by: M. Palanikannan <73993394+Palanikannan1437@users.noreply.github.com> Co-authored-by: Vamsi Krishna <46787868+vamsikrishnamathala@users.noreply.github.com>
This commit is contained in:
parent
4d0a7e4658
commit
c6fbbfd8cc
11 changed files with 188 additions and 16 deletions
|
|
@ -4,7 +4,7 @@ import { useState } from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { useParams } from "next/navigation";
|
import { useParams } from "next/navigation";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
|
import { EUserPermissions, EUserPermissionsLevel, WORKSPACE_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
|
||||||
import { IWebhook } from "@plane/types";
|
import { IWebhook } from "@plane/types";
|
||||||
// ui
|
// ui
|
||||||
import { TOAST_TYPE, setToast } from "@plane/ui";
|
import { TOAST_TYPE, setToast } from "@plane/ui";
|
||||||
|
|
@ -14,6 +14,7 @@ import { PageHead } from "@/components/core";
|
||||||
import { SettingsContentWrapper } from "@/components/settings";
|
import { SettingsContentWrapper } from "@/components/settings";
|
||||||
import { DeleteWebhookModal, WebhookDeleteSection, WebhookForm } from "@/components/web-hooks";
|
import { DeleteWebhookModal, WebhookDeleteSection, WebhookForm } from "@/components/web-hooks";
|
||||||
// hooks
|
// hooks
|
||||||
|
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
|
||||||
import { useUserPermissions, useWebhook, useWorkspace } from "@/hooks/store";
|
import { useUserPermissions, useWebhook, useWorkspace } from "@/hooks/store";
|
||||||
|
|
||||||
const WebhookDetailsPage = observer(() => {
|
const WebhookDetailsPage = observer(() => {
|
||||||
|
|
@ -55,6 +56,12 @@ const WebhookDetailsPage = observer(() => {
|
||||||
};
|
};
|
||||||
await updateWebhook(workspaceSlug.toString(), formData.id, payload)
|
await updateWebhook(workspaceSlug.toString(), formData.id, payload)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
captureSuccess({
|
||||||
|
eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.webhook_updated,
|
||||||
|
payload: {
|
||||||
|
webhook: formData.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
setToast({
|
setToast({
|
||||||
type: TOAST_TYPE.SUCCESS,
|
type: TOAST_TYPE.SUCCESS,
|
||||||
title: "Success!",
|
title: "Success!",
|
||||||
|
|
@ -62,6 +69,13 @@ const WebhookDetailsPage = observer(() => {
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
captureError({
|
||||||
|
eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.webhook_updated,
|
||||||
|
payload: {
|
||||||
|
webhook: formData.id,
|
||||||
|
},
|
||||||
|
error: error as Error,
|
||||||
|
});
|
||||||
setToast({
|
setToast({
|
||||||
type: TOAST_TYPE.ERROR,
|
type: TOAST_TYPE.ERROR,
|
||||||
title: "Error!",
|
title: "Error!",
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { observer } from "mobx-react";
|
||||||
import { useParams } from "next/navigation";
|
import { useParams } from "next/navigation";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
// plane imports
|
// plane imports
|
||||||
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
|
import { EUserPermissions, EUserPermissionsLevel, WORKSPACE_SETTINGS_TRACKER_ELEMENTS } from "@plane/constants";
|
||||||
import { useTranslation } from "@plane/i18n";
|
import { useTranslation } from "@plane/i18n";
|
||||||
// components
|
// components
|
||||||
import { NotAuthorizedView } from "@/components/auth-screens";
|
import { NotAuthorizedView } from "@/components/auth-screens";
|
||||||
|
|
@ -15,6 +15,7 @@ import { SettingsContentWrapper, SettingsHeading } from "@/components/settings";
|
||||||
import { WebhookSettingsLoader } from "@/components/ui";
|
import { WebhookSettingsLoader } from "@/components/ui";
|
||||||
import { WebhooksList, CreateWebhookModal } from "@/components/web-hooks";
|
import { WebhooksList, CreateWebhookModal } from "@/components/web-hooks";
|
||||||
// hooks
|
// hooks
|
||||||
|
import { captureClick } from "@/helpers/event-tracker.helper";
|
||||||
import { useUserPermissions, useWebhook, useWorkspace } from "@/hooks/store";
|
import { useUserPermissions, useWebhook, useWorkspace } from "@/hooks/store";
|
||||||
import { useResolvedAssetPath } from "@/hooks/use-resolved-asset-path";
|
import { useResolvedAssetPath } from "@/hooks/use-resolved-asset-path";
|
||||||
|
|
||||||
|
|
@ -71,7 +72,12 @@ const WebhooksListPage = observer(() => {
|
||||||
description={t("workspace_settings.settings.webhooks.description")}
|
description={t("workspace_settings.settings.webhooks.description")}
|
||||||
button={{
|
button={{
|
||||||
label: t("workspace_settings.settings.webhooks.add_webhook"),
|
label: t("workspace_settings.settings.webhooks.add_webhook"),
|
||||||
onClick: () => setShowCreateWebhookModal(true),
|
onClick: () => {
|
||||||
|
captureClick({
|
||||||
|
elementName: WORKSPACE_SETTINGS_TRACKER_ELEMENTS.HEADER_ADD_WEBHOOK_BUTTON,
|
||||||
|
});
|
||||||
|
setShowCreateWebhookModal(true);
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{Object.keys(webhooks).length > 0 ? (
|
{Object.keys(webhooks).length > 0 ? (
|
||||||
|
|
@ -89,7 +95,12 @@ const WebhooksListPage = observer(() => {
|
||||||
size="md"
|
size="md"
|
||||||
primaryButton={{
|
primaryButton={{
|
||||||
text: t("workspace_settings.settings.webhooks.add_webhook"),
|
text: t("workspace_settings.settings.webhooks.add_webhook"),
|
||||||
onClick: () => setShowCreateWebhookModal(true),
|
onClick: () => {
|
||||||
|
captureClick({
|
||||||
|
elementName: WORKSPACE_SETTINGS_TRACKER_ELEMENTS.EMPTY_STATE_ADD_WEBHOOK_BUTTON,
|
||||||
|
});
|
||||||
|
setShowCreateWebhookModal(true);
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import {
|
||||||
SUBSCRIPTION_REDIRECTION_URLS,
|
SUBSCRIPTION_REDIRECTION_URLS,
|
||||||
SUBSCRIPTION_WITH_BILLING_FREQUENCY,
|
SUBSCRIPTION_WITH_BILLING_FREQUENCY,
|
||||||
TALK_TO_SALES_URL,
|
TALK_TO_SALES_URL,
|
||||||
|
WORKSPACE_SETTINGS_TRACKER_ELEMENTS,
|
||||||
|
WORKSPACE_SETTINGS_TRACKER_EVENTS,
|
||||||
} from "@plane/constants";
|
} from "@plane/constants";
|
||||||
import { useTranslation } from "@plane/i18n";
|
import { useTranslation } from "@plane/i18n";
|
||||||
import { EProductSubscriptionEnum, TBillingFrequency } from "@plane/types";
|
import { EProductSubscriptionEnum, TBillingFrequency } from "@plane/types";
|
||||||
|
|
@ -16,6 +18,7 @@ import { DiscountInfo } from "@/components/license/modal/card/discount-info";
|
||||||
import { getUpgradeButtonStyle } from "@/components/workspace/billing/subscription";
|
import { getUpgradeButtonStyle } from "@/components/workspace/billing/subscription";
|
||||||
import { TPlanDetail } from "@/constants/plans";
|
import { TPlanDetail } from "@/constants/plans";
|
||||||
// local imports
|
// local imports
|
||||||
|
import { captureSuccess } from "@/helpers/event-tracker.helper";
|
||||||
import { PlanFrequencyToggle } from "./frequency-toggle";
|
import { PlanFrequencyToggle } from "./frequency-toggle";
|
||||||
|
|
||||||
type TPlanDetailProps = {
|
type TPlanDetailProps = {
|
||||||
|
|
@ -49,6 +52,12 @@ export const PlanDetail: FC<TPlanDetailProps> = observer((props) => {
|
||||||
const frequency = billingFrequency ?? "year";
|
const frequency = billingFrequency ?? "year";
|
||||||
// Get the redirection URL based on the subscription type and billing frequency
|
// Get the redirection URL based on the subscription type and billing frequency
|
||||||
const redirectUrl = SUBSCRIPTION_REDIRECTION_URLS[subscriptionType][frequency] ?? TALK_TO_SALES_URL;
|
const redirectUrl = SUBSCRIPTION_REDIRECTION_URLS[subscriptionType][frequency] ?? TALK_TO_SALES_URL;
|
||||||
|
captureSuccess({
|
||||||
|
eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.upgrade_plan_redirected,
|
||||||
|
payload: {
|
||||||
|
subscriptionType,
|
||||||
|
},
|
||||||
|
});
|
||||||
// Open the URL in a new tab
|
// Open the URL in a new tab
|
||||||
window.open(redirectUrl, "_blank");
|
window.open(redirectUrl, "_blank");
|
||||||
};
|
};
|
||||||
|
|
@ -101,7 +110,15 @@ export const PlanDetail: FC<TPlanDetailProps> = observer((props) => {
|
||||||
|
|
||||||
{/* Subscription button */}
|
{/* Subscription button */}
|
||||||
<div className={cn("flex flex-col gap-1 py-3 items-start transition-all duration-300")}>
|
<div className={cn("flex flex-col gap-1 py-3 items-start transition-all duration-300")}>
|
||||||
<button onClick={handleRedirection} className={cn(upgradeButtonStyle, COMMON_BUTTON_STYLE)}>
|
<button
|
||||||
|
onClick={handleRedirection}
|
||||||
|
className={cn(upgradeButtonStyle, COMMON_BUTTON_STYLE)}
|
||||||
|
data-ph-element={
|
||||||
|
isSubscriptionActive
|
||||||
|
? WORKSPACE_SETTINGS_TRACKER_ELEMENTS.BILLING_UPGRADE_BUTTON(subscriptionType)
|
||||||
|
: WORKSPACE_SETTINGS_TRACKER_ELEMENTS.BILLING_TALK_TO_SALES_BUTTON
|
||||||
|
}
|
||||||
|
>
|
||||||
{isSubscriptionActive ? `Upgrade to ${subscriptionName}` : t("common.upgrade_cta.talk_to_sales")}
|
{isSubscriptionActive ? `Upgrade to ${subscriptionName}` : t("common.upgrade_cta.talk_to_sales")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,16 @@
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { intersection } from "lodash";
|
import { intersection } from "lodash";
|
||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
import { EUserPermissions, EUserPermissionsLevel, EXPORTERS_LIST } from "@plane/constants";
|
import {
|
||||||
|
EUserPermissions,
|
||||||
|
EUserPermissionsLevel,
|
||||||
|
EXPORTERS_LIST,
|
||||||
|
WORKSPACE_SETTINGS_TRACKER_EVENTS,
|
||||||
|
WORKSPACE_SETTINGS_TRACKER_ELEMENTS,
|
||||||
|
} from "@plane/constants";
|
||||||
import { useTranslation } from "@plane/i18n";
|
import { useTranslation } from "@plane/i18n";
|
||||||
import { Button, CustomSearchSelect, CustomSelect, TOAST_TYPE, setToast } from "@plane/ui";
|
import { Button, CustomSearchSelect, CustomSelect, TOAST_TYPE, setToast } from "@plane/ui";
|
||||||
|
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
|
||||||
import { useProject, useUser, useUserPermissions } from "@/hooks/store";
|
import { useProject, useUser, useUserPermissions } from "@/hooks/store";
|
||||||
import { ProjectExportService } from "@/services/project/project-export.service";
|
import { ProjectExportService } from "@/services/project/project-export.service";
|
||||||
|
|
||||||
|
|
@ -73,6 +80,12 @@ export const ExportForm = (props: Props) => {
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutateServices();
|
mutateServices();
|
||||||
setExportLoading(false);
|
setExportLoading(false);
|
||||||
|
captureSuccess({
|
||||||
|
eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.csv_exported,
|
||||||
|
payload: {
|
||||||
|
provider: formData.provider.provider,
|
||||||
|
},
|
||||||
|
});
|
||||||
setToast({
|
setToast({
|
||||||
type: TOAST_TYPE.SUCCESS,
|
type: TOAST_TYPE.SUCCESS,
|
||||||
title: t("workspace_settings.settings.exports.modal.toasts.success.title"),
|
title: t("workspace_settings.settings.exports.modal.toasts.success.title"),
|
||||||
|
|
@ -88,8 +101,15 @@ export const ExportForm = (props: Props) => {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch((error) => {
|
||||||
setExportLoading(false);
|
setExportLoading(false);
|
||||||
|
captureError({
|
||||||
|
eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.csv_exported,
|
||||||
|
payload: {
|
||||||
|
provider: formData.provider.provider,
|
||||||
|
},
|
||||||
|
error: error as Error,
|
||||||
|
});
|
||||||
setToast({
|
setToast({
|
||||||
type: TOAST_TYPE.ERROR,
|
type: TOAST_TYPE.ERROR,
|
||||||
title: t("error"),
|
title: t("error"),
|
||||||
|
|
@ -163,7 +183,12 @@ export const ExportForm = (props: Props) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between ">
|
<div className="flex items-center justify-between ">
|
||||||
<Button variant="primary" type="submit" loading={exportLoading}>
|
<Button
|
||||||
|
variant="primary"
|
||||||
|
type="submit"
|
||||||
|
loading={exportLoading}
|
||||||
|
data-ph-element={WORKSPACE_SETTINGS_TRACKER_ELEMENTS.EXPORT_BUTTON}
|
||||||
|
>
|
||||||
{exportLoading ? `${t("workspace_settings.settings.exports.exporting")}...` : t("export")}
|
{exportLoading ? `${t("workspace_settings.settings.exports.exporting")}...` : t("export")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useParams } from "next/navigation";
|
import { useParams } from "next/navigation";
|
||||||
// types
|
// types
|
||||||
|
import { WORKSPACE_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
|
||||||
import { useTranslation } from "@plane/i18n";
|
import { useTranslation } from "@plane/i18n";
|
||||||
import { IWebhook, IWorkspace, TWebhookEventTypes } from "@plane/types";
|
import { IWebhook, IWorkspace, TWebhookEventTypes } from "@plane/types";
|
||||||
// ui
|
// ui
|
||||||
|
|
@ -10,6 +11,7 @@ import { EModalPosition, EModalWidth, ModalCore, TOAST_TYPE, setToast } from "@p
|
||||||
// helpers
|
// helpers
|
||||||
import { csvDownload } from "@plane/utils";
|
import { csvDownload } from "@plane/utils";
|
||||||
// hooks
|
// hooks
|
||||||
|
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
|
||||||
import useKeypress from "@/hooks/use-keypress";
|
import useKeypress from "@/hooks/use-keypress";
|
||||||
// components
|
// components
|
||||||
import { WebhookForm } from "./form";
|
import { WebhookForm } from "./form";
|
||||||
|
|
@ -67,6 +69,12 @@ export const CreateWebhookModal: React.FC<ICreateWebhookModal> = (props) => {
|
||||||
|
|
||||||
await createWebhook(workspaceSlug.toString(), payload)
|
await createWebhook(workspaceSlug.toString(), payload)
|
||||||
.then(({ webHook, secretKey }) => {
|
.then(({ webHook, secretKey }) => {
|
||||||
|
captureSuccess({
|
||||||
|
eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.webhook_created,
|
||||||
|
payload: {
|
||||||
|
webhook: formData?.url,
|
||||||
|
},
|
||||||
|
});
|
||||||
setToast({
|
setToast({
|
||||||
type: TOAST_TYPE.SUCCESS,
|
type: TOAST_TYPE.SUCCESS,
|
||||||
title: t("workspace_settings.settings.webhooks.toasts.created.title"),
|
title: t("workspace_settings.settings.webhooks.toasts.created.title"),
|
||||||
|
|
@ -79,6 +87,13 @@ export const CreateWebhookModal: React.FC<ICreateWebhookModal> = (props) => {
|
||||||
csvDownload(csvData, `webhook-secret-key-${Date.now()}`);
|
csvDownload(csvData, `webhook-secret-key-${Date.now()}`);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
captureError({
|
||||||
|
eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.webhook_created,
|
||||||
|
payload: {
|
||||||
|
webhook: formData?.url,
|
||||||
|
},
|
||||||
|
error: error as Error,
|
||||||
|
});
|
||||||
setToast({
|
setToast({
|
||||||
type: TOAST_TYPE.ERROR,
|
type: TOAST_TYPE.ERROR,
|
||||||
title: t("workspace_settings.settings.webhooks.toasts.not_created.title"),
|
title: t("workspace_settings.settings.webhooks.toasts.not_created.title"),
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,10 @@
|
||||||
import React, { FC, useState } from "react";
|
import React, { FC, useState } from "react";
|
||||||
import { useParams } from "next/navigation";
|
import { useParams } from "next/navigation";
|
||||||
// ui
|
// ui
|
||||||
|
import { WORKSPACE_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
|
||||||
import { AlertModalCore, TOAST_TYPE, setToast } from "@plane/ui";
|
import { AlertModalCore, TOAST_TYPE, setToast } from "@plane/ui";
|
||||||
// hooks
|
// hooks
|
||||||
|
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
|
||||||
import { useWebhook } from "@/hooks/store";
|
import { useWebhook } from "@/hooks/store";
|
||||||
import { useAppRouter } from "@/hooks/use-app-router";
|
import { useAppRouter } from "@/hooks/use-app-router";
|
||||||
|
|
||||||
|
|
@ -35,6 +37,12 @@ export const DeleteWebhookModal: FC<IDeleteWebhook> = (props) => {
|
||||||
|
|
||||||
removeWebhook(workspaceSlug.toString(), webhookId.toString())
|
removeWebhook(workspaceSlug.toString(), webhookId.toString())
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
captureSuccess({
|
||||||
|
eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.webhook_deleted,
|
||||||
|
payload: {
|
||||||
|
webhook: webhookId,
|
||||||
|
},
|
||||||
|
});
|
||||||
setToast({
|
setToast({
|
||||||
type: TOAST_TYPE.SUCCESS,
|
type: TOAST_TYPE.SUCCESS,
|
||||||
title: "Success!",
|
title: "Success!",
|
||||||
|
|
@ -42,13 +50,20 @@ export const DeleteWebhookModal: FC<IDeleteWebhook> = (props) => {
|
||||||
});
|
});
|
||||||
router.replace(`/${workspaceSlug}/settings/webhooks/`);
|
router.replace(`/${workspaceSlug}/settings/webhooks/`);
|
||||||
})
|
})
|
||||||
.catch((error) =>
|
.catch((error) => {
|
||||||
|
captureError({
|
||||||
|
eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.webhook_deleted,
|
||||||
|
payload: {
|
||||||
|
webhook: webhookId,
|
||||||
|
},
|
||||||
|
error: error as Error,
|
||||||
|
});
|
||||||
setToast({
|
setToast({
|
||||||
type: TOAST_TYPE.ERROR,
|
type: TOAST_TYPE.ERROR,
|
||||||
title: "Error!",
|
title: "Error!",
|
||||||
message: error?.error ?? "Something went wrong. Please try again.",
|
message: error?.error ?? "Something went wrong. Please try again.",
|
||||||
})
|
});
|
||||||
)
|
})
|
||||||
.finally(() => setIsDeleting(false));
|
.finally(() => setIsDeleting(false));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import { ChevronDown, ChevronUp } from "lucide-react";
|
import { ChevronDown, ChevronUp } from "lucide-react";
|
||||||
import { Disclosure, Transition } from "@headlessui/react";
|
import { Disclosure, Transition } from "@headlessui/react";
|
||||||
|
import { WORKSPACE_SETTINGS_TRACKER_ELEMENTS } from "@plane/constants";
|
||||||
import { Button } from "@plane/ui";
|
import { Button } from "@plane/ui";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|
@ -36,7 +37,11 @@ export const WebhookDeleteSection: React.FC<Props> = (props) => {
|
||||||
webhook.
|
webhook.
|
||||||
</span>
|
</span>
|
||||||
<div>
|
<div>
|
||||||
<Button variant="danger" onClick={openDeleteModal}>
|
<Button
|
||||||
|
variant="danger"
|
||||||
|
onClick={openDeleteModal}
|
||||||
|
data-ph-element={WORKSPACE_SETTINGS_TRACKER_ELEMENTS.WEBHOOK_DELETE_BUTTON}
|
||||||
|
>
|
||||||
Delete webhook
|
Delete webhook
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
import React, { FC, useEffect, useState } from "react";
|
import React, { FC, useEffect, useState } from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
|
import { WORKSPACE_SETTINGS_TRACKER_ELEMENTS } from "@plane/constants";
|
||||||
import { useTranslation } from "@plane/i18n";
|
import { useTranslation } from "@plane/i18n";
|
||||||
import { IWebhook, TWebhookEventTypes } from "@plane/types";
|
import { IWebhook, TWebhookEventTypes } from "@plane/types";
|
||||||
// hooks
|
// hooks
|
||||||
|
|
@ -93,7 +94,11 @@ export const WebhookForm: FC<Props> = observer((props) => {
|
||||||
{data ? (
|
{data ? (
|
||||||
<div className="pt-0 space-y-5">
|
<div className="pt-0 space-y-5">
|
||||||
<WebhookSecretKey data={data} />
|
<WebhookSecretKey data={data} />
|
||||||
<Button type="submit" loading={isSubmitting}>
|
<Button
|
||||||
|
type="submit"
|
||||||
|
loading={isSubmitting}
|
||||||
|
data-ph-element={WORKSPACE_SETTINGS_TRACKER_ELEMENTS.WEBHOOK_UPDATE_BUTTON}
|
||||||
|
>
|
||||||
{isSubmitting ? t("updating") : t("update")}
|
{isSubmitting ? t("updating") : t("update")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { Control, Controller } from "react-hook-form";
|
import { Control, Controller } from "react-hook-form";
|
||||||
|
// constants
|
||||||
|
import { WORKSPACE_SETTINGS_TRACKER_ELEMENTS } from "@plane/constants";
|
||||||
import { IWebhook } from "@plane/types";
|
import { IWebhook } from "@plane/types";
|
||||||
// ui
|
// ui
|
||||||
import { ToggleSwitch } from "@plane/ui";
|
import { ToggleSwitch } from "@plane/ui";
|
||||||
// types
|
// hooks
|
||||||
|
import { captureClick } from "@/helpers/event-tracker.helper";
|
||||||
|
|
||||||
interface IWebHookToggle {
|
interface IWebHookToggle {
|
||||||
control: Control<IWebhook, any>;
|
control: Control<IWebhook, any>;
|
||||||
|
|
@ -20,6 +23,9 @@ export const WebhookToggle = ({ control }: IWebHookToggle) => (
|
||||||
<ToggleSwitch
|
<ToggleSwitch
|
||||||
value={value}
|
value={value}
|
||||||
onChange={(val: boolean) => {
|
onChange={(val: boolean) => {
|
||||||
|
captureClick({
|
||||||
|
elementName: WORKSPACE_SETTINGS_TRACKER_ELEMENTS.WEBHOOK_DETAILS_PAGE_TOGGLE_SWITCH,
|
||||||
|
});
|
||||||
onChange(val);
|
onChange(val);
|
||||||
}}
|
}}
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,11 @@
|
||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useParams } from "next/navigation";
|
import { useParams } from "next/navigation";
|
||||||
|
import { WORKSPACE_SETTINGS_TRACKER_ELEMENTS, WORKSPACE_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
|
||||||
import { IWebhook } from "@plane/types";
|
import { IWebhook } from "@plane/types";
|
||||||
// hooks
|
// hooks
|
||||||
import { ToggleSwitch } from "@plane/ui";
|
import { ToggleSwitch } from "@plane/ui";
|
||||||
|
import { captureElementAndEvent } from "@/helpers/event-tracker.helper";
|
||||||
import { useWebhook } from "@/hooks/store";
|
import { useWebhook } from "@/hooks/store";
|
||||||
// ui
|
// ui
|
||||||
// types
|
// types
|
||||||
|
|
@ -23,8 +25,35 @@ export const WebhooksListItem: FC<IWebhookListItem> = (props) => {
|
||||||
|
|
||||||
const handleToggle = () => {
|
const handleToggle = () => {
|
||||||
if (!workspaceSlug || !webhook.id) return;
|
if (!workspaceSlug || !webhook.id) return;
|
||||||
|
updateWebhook(workspaceSlug.toString(), webhook.id, { is_active: !webhook.is_active })
|
||||||
updateWebhook(workspaceSlug.toString(), webhook.id, { is_active: !webhook.is_active });
|
.then(() => {
|
||||||
|
captureElementAndEvent({
|
||||||
|
element: {
|
||||||
|
elementName: WORKSPACE_SETTINGS_TRACKER_ELEMENTS.WEBHOOK_LIST_ITEM_TOGGLE_SWITCH,
|
||||||
|
},
|
||||||
|
event: {
|
||||||
|
eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.webhook_toggled,
|
||||||
|
state: "SUCCESS",
|
||||||
|
payload: {
|
||||||
|
webhook: webhook.url,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
captureElementAndEvent({
|
||||||
|
element: {
|
||||||
|
elementName: WORKSPACE_SETTINGS_TRACKER_ELEMENTS.WEBHOOK_LIST_ITEM_TOGGLE_SWITCH,
|
||||||
|
},
|
||||||
|
event: {
|
||||||
|
eventName: WORKSPACE_SETTINGS_TRACKER_EVENTS.webhook_toggled,
|
||||||
|
state: "ERROR",
|
||||||
|
payload: {
|
||||||
|
webhook: webhook.url,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { EProductSubscriptionEnum } from "@plane/types";
|
||||||
|
|
||||||
// Dashboard Events
|
// Dashboard Events
|
||||||
export const GITHUB_REDIRECTED_TRACKER_EVENT = "github_redirected";
|
export const GITHUB_REDIRECTED_TRACKER_EVENT = "github_redirected";
|
||||||
export const HEADER_GITHUB_ICON = "header_github_icon";
|
export const HEADER_GITHUB_ICON = "header_github_icon";
|
||||||
|
|
@ -268,3 +270,31 @@ export const SIDEBAR_TRACKER_ELEMENTS = {
|
||||||
USER_MENU_ITEM: "sidenav_user_menu_item",
|
USER_MENU_ITEM: "sidenav_user_menu_item",
|
||||||
CREATE_WORK_ITEM_BUTTON: "sidebar_create_work_item_button",
|
CREATE_WORK_ITEM_BUTTON: "sidebar_create_work_item_button",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const WORKSPACE_SETTINGS_TRACKER_EVENTS = {
|
||||||
|
// Billing
|
||||||
|
upgrade_plan_redirected: "upgrade_plan_redirected",
|
||||||
|
// Exports
|
||||||
|
csv_exported: "csv_exported",
|
||||||
|
// Webhooks
|
||||||
|
webhook_created: "webhook_created",
|
||||||
|
webhook_deleted: "webhook_deleted",
|
||||||
|
webhook_toggled: "webhook_toggled",
|
||||||
|
webhook_details_page_toggled: "webhook_details_page_toggled",
|
||||||
|
webhook_updated: "webhook_updated",
|
||||||
|
};
|
||||||
|
export const WORKSPACE_SETTINGS_TRACKER_ELEMENTS = {
|
||||||
|
// Billing
|
||||||
|
BILLING_UPGRADE_BUTTON: (subscriptionType: EProductSubscriptionEnum) => `billing_upgrade_${subscriptionType}_button`,
|
||||||
|
BILLING_TALK_TO_SALES_BUTTON: "billing_talk_to_sales_button",
|
||||||
|
// Exports
|
||||||
|
EXPORT_BUTTON: "export_button",
|
||||||
|
// Webhooks
|
||||||
|
HEADER_ADD_WEBHOOK_BUTTON: "header_add_webhook_button",
|
||||||
|
EMPTY_STATE_ADD_WEBHOOK_BUTTON: "empty_state_add_webhook_button",
|
||||||
|
LIST_ITEM_DELETE_BUTTON: "list_item_delete_button",
|
||||||
|
WEBHOOK_LIST_ITEM_TOGGLE_SWITCH: "webhook_list_item_toggle_switch",
|
||||||
|
WEBHOOK_DETAILS_PAGE_TOGGLE_SWITCH: "webhook_details_page_toggle_switch",
|
||||||
|
WEBHOOK_DELETE_BUTTON: "webhook_delete_button",
|
||||||
|
WEBHOOK_UPDATE_BUTTON: "webhook_update_button",
|
||||||
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue