gitlab-org--gitlab-foss/app/assets/javascripts/google_tag_manager/index.js

319 lines
7.3 KiB
JavaScript

import { v4 as uuidv4 } from 'uuid';
import { logError } from '~/lib/logger';
const SKU_PREMIUM = '2c92a00d76f0d5060176f2fb0a5029ff';
const SKU_ULTIMATE = '2c92a0ff76f0d5250176f2f8c86f305a';
const PRODUCT_INFO = {
[SKU_PREMIUM]: {
// eslint-disable-next-line @gitlab/require-i18n-strings
name: 'Premium',
id: '0002',
price: '228',
variant: 'SaaS',
},
[SKU_ULTIMATE]: {
// eslint-disable-next-line @gitlab/require-i18n-strings
name: 'Ultimate',
id: '0001',
price: '1188',
variant: 'SaaS',
},
};
const EMPTY_NAMESPACE_ID_VALUE = 'not available';
const generateProductInfo = (sku, quantity) => {
const product = PRODUCT_INFO[sku];
if (!product) {
logError('Unexpected product sku provided to generateProductInfo');
return {};
}
const productInfo = {
...product,
brand: 'GitLab',
category: 'DevOps',
quantity,
};
return productInfo;
};
const isSupported = () => Boolean(window.dataLayer) && gon.features?.gitlabGtmDatalayer;
// gon.features.gitlabGtmDatalayer is set by writing
// `push_frontend_feature_flag(:gitlab_gtm_datalayer, type: :ops)`
// to the appropriate controller
// window.dataLayer is set by adding partials to the appropriate view found in
// views/layouts/_google_tag_manager_body.html.haml and _google_tag_manager_head.html.haml
const pushEvent = (event, args = {}) => {
if (!window.dataLayer) {
return;
}
try {
window.dataLayer.push({
event,
...args,
});
} catch (e) {
logError('Unexpected error while pushing to dataLayer', e);
}
};
const pushEnhancedEcommerceEvent = (event, args = {}) => {
if (!window.dataLayer) {
return;
}
try {
window.dataLayer.push({ ecommerce: null }); // Clear the previous ecommerce object
window.dataLayer.push({
event,
...args,
});
} catch (e) {
logError('Unexpected error while pushing to dataLayer', e);
}
};
const pushAccountSubmit = (accountType, accountMethod) =>
pushEvent('accountSubmit', { accountType, accountMethod });
const trackFormSubmission = (accountType) => {
const form = document.getElementById('new_new_user');
form.addEventListener('submit', () => {
pushAccountSubmit(accountType, 'form');
});
};
const trackOmniAuthSubmission = (accountType) => {
const links = document.querySelectorAll('.js-oauth-login');
links.forEach((link) => {
const { provider } = link.dataset;
link.addEventListener('click', () => {
pushAccountSubmit(accountType, provider);
});
});
};
export const trackFreeTrialAccountSubmissions = () => {
if (!isSupported()) {
return;
}
trackFormSubmission('freeThirtyDayTrial');
trackOmniAuthSubmission('freeThirtyDayTrial');
};
export const trackNewRegistrations = () => {
if (!isSupported()) {
return;
}
trackFormSubmission('standardSignUp');
trackOmniAuthSubmission('standardSignUp');
};
export const trackSaasTrialSubmit = () => {
if (!isSupported()) {
return;
}
pushEvent('saasTrialSubmit');
};
export const trackSaasTrialSkip = () => {
if (!isSupported()) {
return;
}
const skipLink = document.querySelector('.js-skip-trial');
skipLink.addEventListener('click', () => {
pushEvent('saasTrialSkip');
});
};
export const trackSaasTrialGroup = () => {
if (!isSupported()) {
return;
}
const form = document.querySelector('.js-saas-trial-group');
form.addEventListener('submit', () => {
pushEvent('saasTrialGroup');
});
};
export const trackProjectImport = () => {
if (!isSupported()) {
return;
}
const importButtons = document.querySelectorAll('.js-import-project-btn');
importButtons.forEach((button) => {
button.addEventListener('click', () => {
const { platform } = button.dataset;
pushEvent('projectImport', { platform });
});
});
};
export const trackSaasTrialGetStarted = () => {
if (!isSupported()) {
return;
}
const getStartedButton = document.querySelector('.js-get-started-btn');
getStartedButton.addEventListener('click', () => {
pushEvent('saasTrialGetStarted');
});
};
export const trackTrialAcceptTerms = () => {
if (!isSupported()) {
return;
}
pushEvent('saasTrialAcceptTerms');
};
export const trackCheckout = (selectedPlan, quantity) => {
if (!isSupported()) {
return;
}
const product = generateProductInfo(selectedPlan, quantity);
if (Object.keys(product).length === 0) {
return;
}
const eventData = {
ecommerce: {
currencyCode: 'USD',
checkout: {
actionField: { step: 1 },
products: [product],
},
},
};
// eslint-disable-next-line @gitlab/require-i18n-strings
pushEnhancedEcommerceEvent('EECCheckout', eventData);
};
export const getNamespaceId = () => {
return window.gl.snowplowStandardContext?.data?.namespace_id || EMPTY_NAMESPACE_ID_VALUE;
};
export const trackTransaction = (transactionDetails) => {
if (!isSupported()) {
return;
}
const transactionId = uuidv4();
const { paymentOption, revenue, tax, selectedPlan, quantity } = transactionDetails;
const product = generateProductInfo(selectedPlan, quantity);
const namespaceId = getNamespaceId();
if (Object.keys(product).length === 0) {
return;
}
const eventData = {
ecommerce: {
currencyCode: 'USD',
purchase: {
actionField: {
id: transactionId,
affiliation: 'GitLab',
option: paymentOption,
revenue: revenue.toString(),
tax: tax.toString(),
},
products: [{ ...product, dimension36: namespaceId }],
},
},
};
pushEnhancedEcommerceEvent('EECtransactionSuccess', eventData);
};
export const pushEECproductAddToCartEvent = () => {
if (!isSupported()) {
return;
}
window.dataLayer.push({
event: 'EECproductAddToCart',
ecommerce: {
currencyCode: 'USD',
add: {
products: [
{
name: 'CI/CD Minutes',
id: '0003',
price: '10',
brand: 'GitLab',
category: 'DevOps',
variant: 'add-on',
quantity: 1,
},
],
},
},
});
};
export const trackAddToCartUsageTab = () => {
const getStartedButton = document.querySelector('.js-buy-additional-minutes');
if (!getStartedButton) {
return;
}
getStartedButton.addEventListener('click', pushEECproductAddToCartEvent);
};
export const trackCombinedGroupProjectForm = () => {
if (!isSupported()) {
return;
}
const form = document.querySelector('.js-groups-projects-form');
form.addEventListener('submit', () => {
pushEvent('combinedGroupProjectFormSubmit');
});
};
export const trackCompanyForm = (aboutYourCompanyType) => {
if (!isSupported()) {
return;
}
pushEvent('aboutYourCompanyFormSubmit', { aboutYourCompanyType });
};
export const saasTrialWelcome = () => {
if (!isSupported()) {
return;
}
const saasTrialWelcomeButton = document.querySelector('.js-trial-welcome-btn');
saasTrialWelcomeButton?.addEventListener('click', () => {
pushEvent('saasTrialWelcome');
});
};
export const saasTrialContinuousOnboarding = () => {
if (!isSupported()) {
return;
}
const getStartedButton = document.querySelector('.js-get-started-btn');
getStartedButton?.addEventListener('click', () => {
pushEvent('saasTrialContinuousOnboarding');
});
};