mirror of
https://github.com/makeplane/plane.git
synced 2026-07-13 22:09:12 +02:00
[WEB-4604] feat: add missing posthog events for project grouping, trial and upgrade. (#3783)
This commit is contained in:
@@ -4,6 +4,7 @@ import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
// plane imports
|
||||
import { PROJECT_GROUPING_TRACKER_EVENTS } from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { EUserWorkspaceRoles } from "@plane/types";
|
||||
import { ToggleSwitch } from "@plane/ui";
|
||||
@@ -12,6 +13,7 @@ import { NotAuthorizedView } from "@/components/auth-screens";
|
||||
import { PageHead } from "@/components/core";
|
||||
// store hooks
|
||||
import { SettingsContentWrapper, SettingsHeading } from "@/components/settings";
|
||||
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
|
||||
import { useUserPermissions, useWorkspace } from "@/hooks/store";
|
||||
// plane web components
|
||||
import { WithFeatureFlagHOC } from "@/plane-web/components/feature-flags";
|
||||
@@ -44,13 +46,24 @@ const WorklogsPage = observer(() => {
|
||||
if (!isAdmin) return <NotAuthorizedView section="settings" className="h-auto" />;
|
||||
|
||||
const toggleProjectGroupingFeature = async () => {
|
||||
const willEnableProjectGrouping = !isProjectGroupingEnabled;
|
||||
try {
|
||||
const payload = {
|
||||
[EWorkspaceFeatures.IS_PROJECT_GROUPING_ENABLED]: !isProjectGroupingEnabled,
|
||||
[EWorkspaceFeatures.IS_PROJECT_GROUPING_ENABLED]: willEnableProjectGrouping,
|
||||
};
|
||||
await updateWorkspaceFeature(workspaceSlug.toString(), payload);
|
||||
captureSuccess({
|
||||
eventName: willEnableProjectGrouping
|
||||
? PROJECT_GROUPING_TRACKER_EVENTS.ENABLE
|
||||
: PROJECT_GROUPING_TRACKER_EVENTS.DISABLE,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
captureError({
|
||||
eventName: willEnableProjectGrouping
|
||||
? PROJECT_GROUPING_TRACKER_EVENTS.DISABLE
|
||||
: PROJECT_GROUPING_TRACKER_EVENTS.ENABLE,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -4,19 +4,23 @@ import { useState } from "react";
|
||||
import { useParams } from "next/navigation";
|
||||
// plane imports
|
||||
import { Loader } from "lucide-react";
|
||||
import { LICENSE_TRACKER_ELEMENTS, LICENSE_TRACKER_EVENTS } from "@plane/constants";
|
||||
import { EProductSubscriptionEnum } from "@plane/types";
|
||||
import { setToast, TOAST_TYPE } from "@plane/ui";
|
||||
import { cn } from "@plane/utils";
|
||||
// plane web imports
|
||||
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
|
||||
import { useWorkspaceSubscription } from "@/plane-web/hooks/store";
|
||||
|
||||
export type TTrialButtonProps = {
|
||||
productId: string | undefined;
|
||||
priceId: string | undefined;
|
||||
handleClose: () => void;
|
||||
priceId: string | undefined;
|
||||
productId: string | undefined;
|
||||
variant: EProductSubscriptionEnum;
|
||||
};
|
||||
|
||||
export const TrialButton: React.FC<TTrialButtonProps> = (props: TTrialButtonProps) => {
|
||||
const { productId, priceId, handleClose } = props;
|
||||
const { handleClose, productId, priceId, variant } = props;
|
||||
// router
|
||||
const { workspaceSlug } = useParams();
|
||||
// states
|
||||
@@ -39,6 +43,12 @@ export const TrialButton: React.FC<TTrialButtonProps> = (props: TTrialButtonProp
|
||||
await freeTrialSubscription(workspaceSlug.toString(), { product_id: productId, price_id: priceId });
|
||||
handleClose();
|
||||
handleSuccessModalToggle(true);
|
||||
captureSuccess({
|
||||
eventName: LICENSE_TRACKER_EVENTS.trial_started,
|
||||
payload: {
|
||||
plan: variant,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
const currentError = error as unknown as { error: string; detail: string };
|
||||
console.error("Error in freeTrialSubscription", error);
|
||||
@@ -47,6 +57,12 @@ export const TrialButton: React.FC<TTrialButtonProps> = (props: TTrialButtonProp
|
||||
title: "Error!",
|
||||
message: currentError?.detail ?? currentError?.error ?? "Something went wrong. Please try again.",
|
||||
});
|
||||
captureError({
|
||||
eventName: LICENSE_TRACKER_EVENTS.trial_started,
|
||||
payload: {
|
||||
plan: variant,
|
||||
},
|
||||
});
|
||||
} finally {
|
||||
setTrialLoader(false);
|
||||
}
|
||||
@@ -54,6 +70,7 @@ export const TrialButton: React.FC<TTrialButtonProps> = (props: TTrialButtonProp
|
||||
|
||||
return (
|
||||
<button
|
||||
data-element={LICENSE_TRACKER_ELEMENTS.MODAL_TRIAL_BUTTON}
|
||||
disabled={trialLoader}
|
||||
className="text-center text-sm text-custom-text-300 hover:text-custom-text-100 font-medium transition-all flex justify-center items-center gap-1.5 -ml-5"
|
||||
onClick={() => handleTrial(productId, priceId)}
|
||||
|
||||
@@ -8,6 +8,8 @@ import useSWR from "swr";
|
||||
import {
|
||||
BUSINESS_PLAN_FEATURES,
|
||||
ENTERPRISE_PLAN_FEATURES,
|
||||
LICENSE_TRACKER_ELEMENTS,
|
||||
LICENSE_TRACKER_EVENTS,
|
||||
PRO_PLAN_FEATURES,
|
||||
SUBSCRIPTION_WEBPAGE_URLS,
|
||||
SUBSCRIPTION_WITH_TRIAL,
|
||||
@@ -19,6 +21,7 @@ import { cn, getSubscriptionName } from "@plane/utils";
|
||||
import { FreePlanCard, PlanUpgradeCard } from "@/components/license";
|
||||
import { TCheckoutParams } from "@/components/license/modal/card/checkout-button";
|
||||
// plane web imports
|
||||
import { captureClick, captureError, captureSuccess } from "@/helpers/event-tracker.helper";
|
||||
import { useSelfHostedSubscription, useWorkspaceSubscription } from "@/plane-web/hooks/store";
|
||||
import { PaymentService } from "@/plane-web/services/payment.service";
|
||||
// local imports
|
||||
@@ -71,12 +74,18 @@ export const PaidPlanUpgradeModal: FC<PaidPlanUpgradeModalProps> = observer((pro
|
||||
);
|
||||
|
||||
const handleStripeCheckout = ({ planVariant, productId, priceId }: TCheckoutParams) => {
|
||||
captureClick({
|
||||
elementName: LICENSE_TRACKER_ELEMENTS.MODAL_UPGRADE_BUTTON,
|
||||
});
|
||||
if (!productId || !priceId) {
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error!",
|
||||
message: "Unable to get the product id or price id. Please try again.",
|
||||
});
|
||||
captureError({
|
||||
eventName: LICENSE_TRACKER_EVENTS.upgrade_product_or_price_not_found,
|
||||
});
|
||||
return;
|
||||
}
|
||||
setUpgradeLoaderType(planVariant);
|
||||
@@ -88,6 +97,9 @@ export const PaidPlanUpgradeModal: FC<PaidPlanUpgradeModalProps> = observer((pro
|
||||
.then((response) => {
|
||||
if (response.url) {
|
||||
window.open(response.url, "_blank");
|
||||
captureSuccess({
|
||||
eventName: LICENSE_TRACKER_EVENTS.upgrade_url_received,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
@@ -96,6 +108,9 @@ export const PaidPlanUpgradeModal: FC<PaidPlanUpgradeModalProps> = observer((pro
|
||||
title: "Error!",
|
||||
message: error?.error ?? "Failed to generate payment link. Please try again.",
|
||||
});
|
||||
captureError({
|
||||
eventName: LICENSE_TRACKER_EVENTS.upgrade_url_received,
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
setUpgradeLoaderType(undefined);
|
||||
@@ -108,7 +123,7 @@ export const PaidPlanUpgradeModal: FC<PaidPlanUpgradeModalProps> = observer((pro
|
||||
priceId: string | undefined
|
||||
) => {
|
||||
if (SUBSCRIPTION_WITH_TRIAL.includes(variant)) {
|
||||
return <TrialButton productId={productId} priceId={priceId} handleClose={handleClose} />;
|
||||
return <TrialButton handleClose={handleClose} productId={productId} priceId={priceId} variant={variant} />;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { FC } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
// plane imports
|
||||
import { EProductSubscriptionTier } from "@plane/constants";
|
||||
import { EProductSubscriptionTier, LICENSE_TRACKER_ELEMENTS } from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { EProductSubscriptionEnum, IPaymentProduct } from "@plane/types";
|
||||
import { Button, getButtonStyling, getUpgradeButtonStyle, Loader } from "@plane/ui";
|
||||
@@ -73,6 +73,7 @@ export const SubscriptionButton: FC<TSubscriptionButtonProps> = observer((props)
|
||||
|
||||
return (
|
||||
<button
|
||||
data-ph-element={LICENSE_TRACKER_ELEMENTS.BILLING_PAGE_COMPARISON_SECTION_UPGRADE_BUTTON}
|
||||
onClick={() => handleSubscriptionUpgrade(subscriptionType)}
|
||||
className={cn(upgradeButtonStyle, COMMON_BUTTON_STYLE)}
|
||||
disabled={!!upgradeLoader}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { FC } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { LoaderIcon } from "lucide-react";
|
||||
import { LICENSE_TRACKER_ELEMENTS } from "@plane/constants";
|
||||
import { EProductSubscriptionEnum } from "@plane/types";
|
||||
// plane imports
|
||||
import { Button } from "@plane/ui";
|
||||
@@ -35,6 +36,7 @@ export const TrialDetails: FC<TTrialDetailsProps> = observer((props) => {
|
||||
if (isTrialAllowed) {
|
||||
return (
|
||||
<Button
|
||||
data-ph-element={LICENSE_TRACKER_ELEMENTS.BILLING_PAGE_TRIAL_BUTTON}
|
||||
variant="link-neutral"
|
||||
size="sm"
|
||||
onClick={() => handleTrial(subscriptionType)}
|
||||
|
||||
@@ -3,7 +3,12 @@ import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
import useSWR from "swr";
|
||||
// plane imports
|
||||
import { DEFAULT_PRODUCT_BILLING_FREQUENCY, SUBSCRIPTION_WITH_BILLING_FREQUENCY } from "@plane/constants";
|
||||
import {
|
||||
DEFAULT_PRODUCT_BILLING_FREQUENCY,
|
||||
LICENSE_TRACKER_ELEMENTS,
|
||||
LICENSE_TRACKER_EVENTS,
|
||||
SUBSCRIPTION_WITH_BILLING_FREQUENCY,
|
||||
} from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import {
|
||||
EProductSubscriptionEnum,
|
||||
@@ -18,6 +23,7 @@ import { cn, getSubscriptionProduct, getSubscriptionProductPrice } from "@plane/
|
||||
// helpers
|
||||
import { SettingsHeading } from "@/components/settings";
|
||||
// plane web imports
|
||||
import { captureClick, captureError, captureSuccess } from "@/helpers/event-tracker.helper";
|
||||
import {
|
||||
CloudFreePlanCard,
|
||||
OnePlanCard,
|
||||
@@ -92,6 +98,12 @@ export const BillingRoot = observer(() => {
|
||||
price_id: selectedPriceId,
|
||||
});
|
||||
handleSuccessModalToggle(true);
|
||||
captureSuccess({
|
||||
eventName: LICENSE_TRACKER_EVENTS.trial_started,
|
||||
payload: {
|
||||
plan: selectedSubscriptionType,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
const currentError = error as unknown as { error: string; detail: string };
|
||||
console.error("Error in freeTrialSubscription", error);
|
||||
@@ -100,6 +112,12 @@ export const BillingRoot = observer(() => {
|
||||
title: "Error!",
|
||||
message: currentError?.detail ?? currentError?.error ?? "Something went wrong. Please try again.",
|
||||
});
|
||||
captureError({
|
||||
eventName: LICENSE_TRACKER_EVENTS.trial_started,
|
||||
payload: {
|
||||
plan: selectedSubscriptionType,
|
||||
},
|
||||
});
|
||||
} finally {
|
||||
setTrialLoader(null);
|
||||
}
|
||||
@@ -126,6 +144,9 @@ export const BillingRoot = observer(() => {
|
||||
}
|
||||
if (!selectedProductId || !selectedPriceId) {
|
||||
setToast({ type: TOAST_TYPE.ERROR, title: "Error!", message: "Missing product or price ID" });
|
||||
captureError({
|
||||
eventName: LICENSE_TRACKER_EVENTS.upgrade_product_or_price_not_found,
|
||||
});
|
||||
return;
|
||||
}
|
||||
setUpgradeLoader(selectedSubscriptionType);
|
||||
@@ -136,6 +157,9 @@ export const BillingRoot = observer(() => {
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.url) window.open(response.url, isSelfManaged ? "_blank" : "_self");
|
||||
captureSuccess({
|
||||
eventName: LICENSE_TRACKER_EVENTS.upgrade_url_received,
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
setToast({
|
||||
@@ -143,6 +167,9 @@ export const BillingRoot = observer(() => {
|
||||
title: "Error!",
|
||||
message: error?.error ?? "Failed to generate payment link",
|
||||
});
|
||||
captureError({
|
||||
eventName: LICENSE_TRACKER_EVENTS.upgrade_url_received,
|
||||
});
|
||||
})
|
||||
.finally(() => setUpgradeLoader(null));
|
||||
};
|
||||
@@ -191,6 +218,9 @@ export const BillingRoot = observer(() => {
|
||||
*/
|
||||
const handleSelectedPlanUpgrade = (selectedSubscriptionType: EProductSubscriptionEnum): Promise<void> => {
|
||||
const { selectedProduct, selectedPrice } = getSelectedProductAndPrice(selectedSubscriptionType);
|
||||
captureClick({
|
||||
elementName: LICENSE_TRACKER_ELEMENTS.BILLING_PAGE_PLAN_CARD_UPGRADE_BUTTON,
|
||||
});
|
||||
return handleUpgradeSubscription({
|
||||
selectedSubscriptionType,
|
||||
selectedProductId: selectedProduct?.id,
|
||||
|
||||
@@ -12,6 +12,22 @@ export const EPIC_TRACKER_ELEMENTS = {
|
||||
export const LICENSE_TRACKER_EVENTS = {
|
||||
purchase_modal_opened: "purchase_modal_opened",
|
||||
success_modal_opened: "success_modal_opened",
|
||||
trial_started: "trial_started",
|
||||
upgrade_url_received: "upgrade_url_received",
|
||||
upgrade_product_or_price_not_found: "upgrade_product_or_price_not_found",
|
||||
};
|
||||
|
||||
export const LICENSE_TRACKER_ELEMENTS = {
|
||||
MODAL_TRIAL_BUTTON: "modal_trial_button",
|
||||
BILLING_PAGE_TRIAL_BUTTON: "billing_page_trial_button",
|
||||
MODAL_UPGRADE_BUTTON: "modal_upgrade_button",
|
||||
BILLING_PAGE_COMPARISON_SECTION_UPGRADE_BUTTON: "billing_page_comparison_section_upgrade_button",
|
||||
BILLING_PAGE_PLAN_CARD_UPGRADE_BUTTON: "billing_page_plan_card_upgrade_button",
|
||||
};
|
||||
|
||||
export const PROJECT_GROUPING_TRACKER_EVENTS = {
|
||||
ENABLE: "project_grouping_enabled",
|
||||
DISABLE: "project_grouping_disabled",
|
||||
};
|
||||
|
||||
export const PROJECT_OVERVIEW_TRACKER_EVENTS = {
|
||||
|
||||
Reference in New Issue
Block a user