diff --git a/CHANGELOG.md b/CHANGELOG.md index 485a41b3a..e699aebeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Changelog Fab-manager +- Support for Google Analytics V4 - Updated environment documentation - Updated react-i18next to 11.15.6 - Updated i18next to 21.6.13 @@ -10,6 +11,7 @@ - Removed unmaintained gem sidekiq-cron and replaced it with sidekiq-scheduler - Removed unmaintained @rails/webpacker v5 and replaced it with shakapacker v6 - Removed dependency to auto-ngtemplate-loader +- Removed support for Universal Analytics - Updated deprecated division operators in sass - Fix a bug: a sentence was not linked to a translation key - Fix a bug: the version check may be scheduled at an invalid time diff --git a/app/frontend/src/javascript/app.js b/app/frontend/src/javascript/app.js index 81c05ed41..d80152cad 100644 --- a/app/frontend/src/javascript/app.js +++ b/app/frontend/src/javascript/app.js @@ -75,6 +75,9 @@ angular.module('application', ['ngCookies', 'ngResource', 'ngSanitize', 'ui.rout $transitions.onSuccess({ }, function (trans) { $state.prevState = trans.$from().name; $state.prevParams = trans.$from().params; + + const path = trans.router.stateService.href(trans.$to(), {}, { absolute: true }); + GTM.trackPage(path, trans.$to().name); }); // Global function to allow the user to navigate to the previous screen (ie. $state). diff --git a/app/frontend/src/javascript/components/payment/abstract-payment-modal.tsx b/app/frontend/src/javascript/components/payment/abstract-payment-modal.tsx index 9691930f7..26f19bb6c 100644 --- a/app/frontend/src/javascript/components/payment/abstract-payment-modal.tsx +++ b/app/frontend/src/javascript/components/payment/abstract-payment-modal.tsx @@ -52,6 +52,8 @@ interface AbstractPaymentModalProps { modalSize?: ModalSize, } +declare const GTM: any; + /** * This component is an abstract modal that must be extended by each payment gateway to include its payment form. * @@ -156,6 +158,7 @@ export const AbstractPaymentModal: React.FC = ({ isOp */ const handleFormSuccess = async (result: Invoice|PaymentSchedule): Promise => { setSubmitState(false); + GTM.trackPurchase(result.id, result.total); afterSuccess(result); }; diff --git a/app/frontend/src/javascript/controllers/application.js.erb b/app/frontend/src/javascript/controllers/application.js.erb index 104175cc7..c78eda622 100644 --- a/app/frontend/src/javascript/controllers/application.js.erb +++ b/app/frontend/src/javascript/controllers/application.js.erb @@ -461,6 +461,7 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco // what to do when the modal is closed // authentication succeeded, set the session, gather the notifications and redirect + GTM.trackLogin(); $scope.setCurrentUser(user); if ((toState !== null) && (toParams !== null)) { diff --git a/app/frontend/src/javascript/lib/gtm.js b/app/frontend/src/javascript/lib/gtm.js index 3f8282322..a1b7ea9e7 100644 --- a/app/frontend/src/javascript/lib/gtm.js +++ b/app/frontend/src/javascript/lib/gtm.js @@ -2,9 +2,10 @@ (function () { const GTM = {}; + window.dataLayer = window.dataLayer || []; + function gtag () { window.dataLayer.push(arguments); } + GTM.enableAnalytics = function (trackingId) { - window.dataLayer = window.dataLayer || []; - function gtag () { window.dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', trackingId); @@ -15,6 +16,25 @@ firstScript.parentNode.insertBefore(node, firstScript); }; + GTM.trackPage = function (url, title) { + gtag('event', 'page_view', { + page_location: url, + page_title: title + }); + }; + + GTM.trackLogin = function () { + gtag('event', 'login'); + }; + + GTM.trackPurchase = function (transactionId, value) { + gtag('event', 'purchase', { + transaction_id: transactionId, + value: value, + currency: Fablab.intl_currency + }); + }; + this.GTM = GTM; if (typeof module !== 'undefined' && module !== null) {