Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GTM event tracking #51599

Merged
merged 20 commits into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions __mocks__/@react-native-firebase/analytics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default function analytics() {
return {
logEvent: jest.fn(),
};
}
2 changes: 1 addition & 1 deletion config/webpack/webpack.common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const getCommonConfiguration = ({file = '.env', platform = 'web'}: Environment):
isWeb: platform === 'web',
isProduction: file === '.env.production',
isStaging: file === '.env.staging',
useThirdPartyScripts: process.env.USE_THIRD_PARTY_SCRIPTS === 'true' || (platform === 'web' && file === '.env.production'),
useThirdPartyScripts: process.env.USE_THIRD_PARTY_SCRIPTS === 'true' || (platform === 'web' && ['.env.production', '.env.staging'].includes(file)),
}),
new PreloadWebpackPlugin({
rel: 'preload',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import {createStackNavigator} from '@react-navigation/stack';
import React, {useCallback} from 'react';
import React, {useCallback, useEffect} from 'react';
import {View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import NoDropZone from '@components/DragAndDrop/NoDropZone';
import FocusTrapForScreens from '@components/FocusTrap/FocusTrapForScreen';
import useKeyboardShortcut from '@hooks/useKeyboardShortcut';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import GoogleTagManager from '@libs/GoogleTagManager';
import OnboardingModalNavigatorScreenOptions from '@libs/Navigation/AppNavigator/OnboardingModalNavigatorScreenOptions';
import type {OnboardingModalNavigatorParamList} from '@libs/Navigation/types';
import OnboardingRefManager from '@libs/OnboardingRefManager';
Expand All @@ -14,6 +16,7 @@ import OnboardingEmployees from '@pages/OnboardingEmployees';
import OnboardingPersonalDetails from '@pages/OnboardingPersonalDetails';
import OnboardingPurpose from '@pages/OnboardingPurpose';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import SCREENS from '@src/SCREENS';
import Overlay from './Overlay';

Expand All @@ -23,6 +26,17 @@ function OnboardingModalNavigator() {
const styles = useThemeStyles();
const {onboardingIsMediumOrLargerScreenWidth} = useResponsiveLayout();
const outerViewRef = React.useRef<View>(null);
const [accountID] = useOnyx(ONYXKEYS.SESSION, {selector: (session) => session?.accountID ?? 0});

// Publish a sign_up event when we start the onboarding flow. This should track basic sign ups
// as well as Google and Apple SSO.
useEffect(() => {
if (!accountID) {
return;
}

GoogleTagManager.publishEvent('sign_up', accountID);
arosiclair marked this conversation as resolved.
Show resolved Hide resolved
}, [accountID]);

const handleOuterClick = useCallback(() => {
OnboardingRefManager.handleOuterClick();
Expand Down
10 changes: 10 additions & 0 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import DateUtils from '@libs/DateUtils';
import DistanceRequestUtils from '@libs/DistanceRequestUtils';
import * as ErrorUtils from '@libs/ErrorUtils';
import * as FileUtils from '@libs/fileDownload/FileUtils';
import GoogleTagManager from '@libs/GoogleTagManager';
import * as IOUUtils from '@libs/IOUUtils';
import * as LocalePhoneNumber from '@libs/LocalePhoneNumber';
import * as Localize from '@libs/Localize';
Expand Down Expand Up @@ -3415,6 +3416,7 @@ function categorizeTrackedExpense(
comment: string,
merchant: string,
created: string,
isDraftPolicy: boolean,
category?: string,
tag?: string,
taxCode = '',
Expand Down Expand Up @@ -3471,6 +3473,12 @@ function categorizeTrackedExpense(
};

API.write(WRITE_COMMANDS.CATEGORIZE_TRACKED_EXPENSE, parameters, {optimisticData, successData, failureData});

// If a draft policy was used, then the CategorizeTrackedExpense command will create a real one
// so let's track that conversion here
if (isDraftPolicy) {
GoogleTagManager.publishEvent('workspace_created', userAccountID);
}
}

function shareTrackedExpense(
Expand Down Expand Up @@ -3770,6 +3778,7 @@ function trackExpense(
payeeAccountID: number,
participant: Participant,
comment: string,
isDraftPolicy: boolean,
receipt?: Receipt,
category?: string,
tag?: string,
Expand Down Expand Up @@ -3865,6 +3874,7 @@ function trackExpense(
comment,
merchant,
created,
isDraftPolicy,
category,
tag,
taxCode,
Expand Down
28 changes: 18 additions & 10 deletions src/libs/actions/PaymentMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
} from '@libs/API/parameters';
import {READ_COMMANDS, SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types';
import * as CardUtils from '@libs/CardUtils';
import GoogleTagManager from '@libs/GoogleTagManager';
import Navigation from '@libs/Navigation/Navigation';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand Down Expand Up @@ -159,7 +160,7 @@ function makeDefaultPaymentMethod(bankAccountID: number, fundID: number, previou
* Calls the API to add a new card.
*
*/
function addPaymentCard(params: PaymentCardParams) {
function addPaymentCard(accountID: number, params: PaymentCardParams) {
const cardMonth = CardUtils.getMonthFromExpirationDateString(params.expirationDate);
const cardYear = CardUtils.getYearFromExpirationDateString(params.expirationDate);

Expand Down Expand Up @@ -203,21 +204,26 @@ function addPaymentCard(params: PaymentCardParams) {
successData,
failureData,
});

GoogleTagManager.publishEvent('paid_adoption', accountID);
}

/**
* Calls the API to add a new card.
*
*/
function addSubscriptionPaymentCard(cardData: {
cardNumber: string;
cardYear: string;
cardMonth: string;
cardCVV: string;
addressName: string;
addressZip: string;
currency: ValueOf<typeof CONST.PAYMENT_CARD_CURRENCY>;
}) {
function addSubscriptionPaymentCard(
accountID: number,
cardData: {
cardNumber: string;
cardYear: string;
cardMonth: string;
cardCVV: string;
addressName: string;
addressZip: string;
currency: ValueOf<typeof CONST.PAYMENT_CARD_CURRENCY>;
},
) {
const {cardNumber, cardYear, cardMonth, cardCVV, addressName, addressZip, currency} = cardData;

const parameters: AddPaymentCardParams = {
Expand Down Expand Up @@ -265,6 +271,8 @@ function addSubscriptionPaymentCard(cardData: {
failureData,
});
}

GoogleTagManager.publishEvent('paid_adoption', accountID);
}

/**
Expand Down
10 changes: 10 additions & 0 deletions src/libs/actions/Policy/Policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import * as CurrencyUtils from '@libs/CurrencyUtils';
import DateUtils from '@libs/DateUtils';
import * as ErrorUtils from '@libs/ErrorUtils';
import getIsNarrowLayout from '@libs/getIsNarrowLayout';
import GoogleTagManager from '@libs/GoogleTagManager';
import Log from '@libs/Log';
import * as NetworkStore from '@libs/Network/NetworkStore';
import * as NumberUtils from '@libs/NumberUtils';
Expand Down Expand Up @@ -1838,6 +1839,11 @@ function createWorkspace(policyOwnerEmail = '', makeMeAdmin = false, policyName
const {optimisticData, failureData, successData, params} = buildPolicyData(policyOwnerEmail, makeMeAdmin, policyName, policyID, undefined, engagementChoice);
API.write(WRITE_COMMANDS.CREATE_WORKSPACE, params, {optimisticData, successData, failureData});

// Publish a workspace created event if this is their first policy
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NAB, I wonder if the events and should be called workspace or policy since we try to keep everything in the BE as policy. Also its weird to see both of them in the comment on one line :D

Suggested change
// Publish a workspace created event if this is their first policy
// Publish a workspace created event if this is their first workspace

if (getAdminPolicies().length === 0) {
GoogleTagManager.publishEvent('workspace_created', sessionAccountID);
}

return params;
}

Expand Down Expand Up @@ -3743,6 +3749,10 @@ function setWorkspaceEReceiptsEnabled(policyID: string, eReceipts: boolean) {
API.write(WRITE_COMMANDS.SET_WORKSPACE_ERECEIPTS_ENABLED, parameters, onyxData);
}

function getAdminPolicies(): Policy[] {
return Object.values(allPolicies ?? {}).filter<Policy>((policy): policy is Policy => !!policy && policy.role === CONST.POLICY.ROLE.ADMIN && policy.type !== CONST.POLICY.TYPE.PERSONAL);
}

function getAdminPoliciesConnectedToSageIntacct(): Policy[] {
return Object.values(allPolicies ?? {}).filter<Policy>((policy): policy is Policy => !!policy && policy.role === CONST.POLICY.ROLE.ADMIN && !!policy?.connections?.intacct);
}
Expand Down
10 changes: 9 additions & 1 deletion src/pages/iou/request/step/IOURequestStepAmount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,24 +45,31 @@
function IOURequestStepAmount({
report,
route: {
params: {iouType, reportID, transactionID, backTo, pageIndex, action, currency: selectedCurrency = ''},
params: {iouType, reportID, transactionID = '-1', backTo, pageIndex, action, currency: selectedCurrency = ''},
},
transaction,
currentUserPersonalDetails,
shouldKeepUserInput = false,
}: IOURequestStepAmountProps) {
const [splitDraftTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT}${transactionID ?? -1}`);

Check failure on line 54 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Cannot redeclare block-scoped variable 'splitDraftTransaction'.
const [draftTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID ?? -1}`);

Check failure on line 55 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Cannot redeclare block-scoped variable 'draftTransaction'.
const [skipConfirmation] = useOnyx(`${ONYXKEYS.COLLECTION.SKIP_CONFIRMATION}${transactionID ?? -1}`);

Check failure on line 56 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Cannot redeclare block-scoped variable 'skipConfirmation'.
const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST);

Check failure on line 57 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Cannot redeclare block-scoped variable 'personalDetails'.
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report ? report.policyID : -1}`);

Check failure on line 58 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Cannot redeclare block-scoped variable 'policy'.

const {translate} = useLocalize();
const textInput = useRef<BaseTextInputRef | null>(null);
const focusTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const isSaveButtonPressed = useRef(false);
const iouRequestType = getRequestType(transaction);
const policyID = report?.policyID ?? '-1';

const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID ?? -1}`);
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`);

Check failure on line 68 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Cannot redeclare block-scoped variable 'policy'.

Check failure on line 68 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Parsing error: Identifier 'policy' has already been declared

Check failure on line 68 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

'policy' is already defined

Check failure on line 68 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

Parsing error: Identifier 'policy' has already been declared

Check failure on line 68 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

'policy' is already defined
const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST);

Check failure on line 69 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Cannot redeclare block-scoped variable 'personalDetails'.

Check failure on line 69 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

'personalDetails' is already defined

Check failure on line 69 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

'personalDetails' is already defined
const [draftTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`);

Check failure on line 70 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Cannot redeclare block-scoped variable 'draftTransaction'.

Check failure on line 70 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

'draftTransaction' is already defined

Check failure on line 70 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

'draftTransaction' is already defined
const [splitDraftTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT}${transactionID}`);

Check failure on line 71 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Cannot redeclare block-scoped variable 'splitDraftTransaction'.

Check failure on line 71 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

'splitDraftTransaction' is already defined

Check failure on line 71 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

'splitDraftTransaction' is already defined
const [skipConfirmation] = useOnyx(`${ONYXKEYS.COLLECTION.SKIP_CONFIRMATION}${transactionID}`);

Check failure on line 72 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Cannot redeclare block-scoped variable 'skipConfirmation'.

Check failure on line 72 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

'skipConfirmation' is already defined

Check failure on line 72 in src/pages/iou/request/step/IOURequestStepAmount.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

'skipConfirmation' is already defined

const isEditing = action === CONST.IOU.ACTION.EDIT;
const isSplitBill = iouType === CONST.IOU.TYPE.SPLIT;
Expand Down Expand Up @@ -236,6 +243,7 @@
currentUserPersonalDetails.accountID,
participants.at(0) ?? {},
'',
false,
);
return;
}
Expand Down
3 changes: 3 additions & 0 deletions src/pages/iou/request/step/IOURequestStepConfirmation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ function IOURequestStepConfirmation({

const report = reportReal ?? reportDraft;
const policy = policyReal ?? policyDraft;
const isDraftPolicy = policy === policyDraft;
const policyCategories = policyCategoriesReal ?? policyCategoriesDraft;

const styles = useThemeStyles();
Expand Down Expand Up @@ -287,6 +288,7 @@ function IOURequestStepConfirmation({
currentUserPersonalDetails.accountID,
participant,
trimmedComment,
isDraftPolicy,
receiptObj,
transaction.category,
transaction.tag,
Expand Down Expand Up @@ -317,6 +319,7 @@ function IOURequestStepConfirmation({
policyCategories,
action,
customUnitRateID,
isDraftPolicy,
],
);

Expand Down
1 change: 1 addition & 0 deletions src/pages/iou/request/step/IOURequestStepDistance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ function IOURequestStepDistance({
currentUserPersonalDetails.accountID,
participant,
'',
false,
{},
'',
'',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ function IOURequestStepScan({
currentUserPersonalDetails.accountID,
participant,
'',
false,
receipt,
);
} else {
Expand Down Expand Up @@ -335,6 +336,7 @@ function IOURequestStepScan({
currentUserPersonalDetails.accountID,
participant,
'',
false,
receipt,
'',
'',
Expand Down
2 changes: 2 additions & 0 deletions src/pages/iou/request/step/IOURequestStepScan/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ function IOURequestStepScan({
currentUserPersonalDetails.accountID,
participant,
'',
false,
receipt,
);
} else {
Expand Down Expand Up @@ -365,6 +366,7 @@ function IOURequestStepScan({
currentUserPersonalDetails.accountID,
participant,
'',
false,
receipt,
'',
'',
Expand Down
28 changes: 16 additions & 12 deletions src/pages/settings/Subscription/PaymentCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ function AddPaymentCard() {
const styles = useThemeStyles();
const {translate} = useLocalize();
const [privateSubscription] = useOnyx(ONYXKEYS.NVP_PRIVATE_SUBSCRIPTION);
const [accountID] = useOnyx(ONYXKEYS.SESSION, {selector: (session) => session?.accountID ?? 0});

const subscriptionPlan = useSubscriptionPlan();
const subscriptionPrice = useSubscriptionPrice();
Expand All @@ -43,18 +44,21 @@ function AddPaymentCard() {
};
}, []);

const addPaymentCard = useCallback((values: FormOnyxValues<typeof ONYXKEYS.FORMS.ADD_PAYMENT_CARD_FORM>) => {
const cardData = {
cardNumber: CardUtils.getMCardNumberString(values.cardNumber),
cardMonth: CardUtils.getMonthFromExpirationDateString(values.expirationDate),
cardYear: CardUtils.getYearFromExpirationDateString(values.expirationDate),
cardCVV: values.securityCode,
addressName: values.nameOnCard,
addressZip: values.addressZipCode,
currency: values.currency ?? CONST.PAYMENT_CARD_CURRENCY.USD,
};
PaymentMethods.addSubscriptionPaymentCard(cardData);
}, []);
const addPaymentCard = useCallback(
(values: FormOnyxValues<typeof ONYXKEYS.FORMS.ADD_PAYMENT_CARD_FORM>) => {
const cardData = {
cardNumber: CardUtils.getMCardNumberString(values.cardNumber),
cardMonth: CardUtils.getMonthFromExpirationDateString(values.expirationDate),
cardYear: CardUtils.getYearFromExpirationDateString(values.expirationDate),
cardCVV: values.securityCode,
addressName: values.nameOnCard,
addressZip: values.addressZipCode,
currency: values.currency ?? CONST.PAYMENT_CARD_CURRENCY.USD,
};
PaymentMethods.addSubscriptionPaymentCard(accountID ?? 0, cardData);
},
[accountID],
);

const [formData] = useOnyx(ONYXKEYS.FORMS.ADD_PAYMENT_CARD_FORM);
const prevFormDataSetupComplete = usePrevious(!!formData?.setupComplete);
Expand Down
13 changes: 11 additions & 2 deletions src/pages/settings/Wallet/AddDebitCardPage.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React, {useEffect, useRef} from 'react';
import React, {useCallback, useEffect, useRef} from 'react';
import {useOnyx} from 'react-native-onyx';
import PaymentCardForm from '@components/AddPaymentCard/PaymentCardForm';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import type {AnimatedTextInputRef} from '@components/RNTextInput';
import ScreenWrapper from '@components/ScreenWrapper';
import useLocalize from '@hooks/useLocalize';
import usePrevious from '@hooks/usePrevious';
import type {PaymentCardParams} from '@libs/API/parameters';
import Navigation from '@libs/Navigation/Navigation';
import NotFoundPage from '@pages/ErrorPage/NotFoundPage';
import * as PaymentMethods from '@userActions/PaymentMethods';
Expand All @@ -19,6 +20,7 @@ function DebitCardPage() {
const [formData] = useOnyx(ONYXKEYS.FORMS.ADD_PAYMENT_CARD_FORM);
const prevFormDataSetupComplete = usePrevious(!!formData?.setupComplete);
const nameOnCardRef = useRef<AnimatedTextInputRef>(null);
const [accountID] = useOnyx(ONYXKEYS.SESSION, {selector: (session) => session?.accountID ?? 0});

/**
* Reset the form values on the mount and unmount so that old errors don't show when this form is displayed again.
Expand All @@ -39,6 +41,13 @@ function DebitCardPage() {
PaymentMethods.continueSetup();
}, [prevFormDataSetupComplete, formData?.setupComplete]);

const addPaymentCard = useCallback(
(params: PaymentCardParams) => {
PaymentMethods.addPaymentCard(accountID ?? 0, params);
},
[accountID],
);

return (
<ScreenWrapper
onEntryTransitionEnd={() => nameOnCardRef.current?.focus()}
Expand All @@ -55,7 +64,7 @@ function DebitCardPage() {
showAddressField
isDebitCard
showStateSelector
addPaymentCard={PaymentMethods.addPaymentCard}
addPaymentCard={addPaymentCard}
submitButtonText={translate('common.save')}
/>
</ScreenWrapper>
Expand Down
Loading
Loading