mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-18 12:54:27 +01:00
Merge branch 'gtm_analytics_v4' into dev
This commit is contained in:
commit
d62c12664a
@ -13,7 +13,9 @@
|
||||
"angular": true,
|
||||
"Fablab": true,
|
||||
"moment": true,
|
||||
"_": true
|
||||
"_": true,
|
||||
"Humanize": true,
|
||||
"GTM": true
|
||||
},
|
||||
"plugins": ["lint-erb"],
|
||||
"overrides": [
|
||||
|
@ -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
|
||||
|
@ -38,7 +38,6 @@ import 'checklist-model/checklist-model';
|
||||
import 'angular-unsavedchanges/lib/unsavedChanges';
|
||||
import 'angular-loading-bar/src/loading-bar';
|
||||
import 'angular-scroll/angular-scroll';
|
||||
import 'angular-google-analytics/dist/angular-google-analytics';
|
||||
import 'src/javascript/lib/dirDisqus';
|
||||
import 'src/javascript/lib/humanize';
|
||||
import 'underscore/underscore';
|
||||
|
@ -17,22 +17,17 @@ angular.module('application', ['ngCookies', 'ngResource', 'ngSanitize', 'ui.rout
|
||||
'ngUpload', 'duScroll', 'application.filters', 'application.services', 'application.directives',
|
||||
'frapontillo.bootstrap-switch', 'application.controllers', 'application.router', 'application.components',
|
||||
'ui.select', 'ui.calendar', 'angularMoment', 'Devise', 'angular-growl', 'xeditable',
|
||||
'checklist-model', 'unsavedChanges', 'angular-loading-bar', 'ngTouch', 'angular-google-analytics',
|
||||
'checklist-model', 'unsavedChanges', 'angular-loading-bar', 'ngTouch',
|
||||
'angularUtils.directives.dirDisqus', 'summernote', 'elasticsearch', 'angular-medium-editor', 'naif.base64',
|
||||
'minicolors', 'pascalprecht.translate', 'ngFitText', 'ngAside', 'ngCapsLock', 'vcRecaptcha', 'ui.codemirror',
|
||||
'bm.uiTour'])
|
||||
.config(['$httpProvider', 'AuthProvider', 'growlProvider', 'unsavedWarningsConfigProvider', 'AnalyticsProvider', 'uibDatepickerPopupConfig', '$provide', '$translateProvider', 'TourConfigProvider', '$sceDelegateProvider',
|
||||
function ($httpProvider, AuthProvider, growlProvider, unsavedWarningsConfigProvider, AnalyticsProvider, uibDatepickerPopupConfig, $provide, $translateProvider, TourConfigProvider, $sceDelegateProvider) {
|
||||
.config(['$httpProvider', 'AuthProvider', 'growlProvider', 'unsavedWarningsConfigProvider', 'uibDatepickerPopupConfig', '$provide', '$translateProvider', 'TourConfigProvider', '$sceDelegateProvider',
|
||||
function ($httpProvider, AuthProvider, growlProvider, unsavedWarningsConfigProvider, uibDatepickerPopupConfig, $provide, $translateProvider, TourConfigProvider, $sceDelegateProvider) {
|
||||
// Google analytics
|
||||
// first we check the user acceptance
|
||||
const cookiesConsent = document.cookie.replace(/(?:(?:^|.*;\s*)fab-manager-cookies-consent\s*=\s*([^;]*).*$)|^.*$/, '$1');
|
||||
if (cookiesConsent === 'accept') {
|
||||
AnalyticsProvider.setAccount(Fablab.trackingId);
|
||||
// track all routes (or not)
|
||||
AnalyticsProvider.trackPages(true);
|
||||
AnalyticsProvider.setDomainName(Fablab.baseHostUrl);
|
||||
AnalyticsProvider.useAnalytics(true);
|
||||
AnalyticsProvider.setPageEvent('$stateChangeSuccess');
|
||||
GTM.enableAnalytics(Fablab.trackingId);
|
||||
} else {
|
||||
// if the cookies were not explicitly accepted, delete them
|
||||
document.cookie = '_ga=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
|
||||
@ -67,8 +62,8 @@ angular.module('application', ['ngCookies', 'ngResource', 'ngSanitize', 'ui.rout
|
||||
TourConfigProvider.enableNavigationInterceptors();
|
||||
|
||||
$sceDelegateProvider.resourceUrlWhitelist(['self']);
|
||||
}]).run(['$rootScope', '$transitions', '$log', 'Auth', 'amMoment', '$state', 'editableOptions', 'Analytics',
|
||||
function ($rootScope, $transitions, $log, Auth, amMoment, $state, editableOptions, Analytics) {
|
||||
}]).run(['$rootScope', '$transitions', '$log', 'Auth', 'amMoment', '$state', 'editableOptions',
|
||||
function ($rootScope, $transitions, $log, Auth, amMoment, $state, editableOptions) {
|
||||
// Angular-moment (date-time manipulations library)
|
||||
amMoment.changeLocale(Fablab.moment_locale);
|
||||
|
||||
@ -80,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).
|
||||
@ -124,10 +122,6 @@ angular.module('application', ['ngCookies', 'ngResource', 'ngSanitize', 'ui.rout
|
||||
});
|
||||
});
|
||||
|
||||
// This code does nothing but it is here to remember to not remove the Analytics dependency,
|
||||
// see https://github.com/revolunet/angular-google-analytics#automatic-page-view-tracking
|
||||
Analytics.pageView();
|
||||
|
||||
/**
|
||||
* This helper method builds and return an array containing every integers between
|
||||
* the provided start and end.
|
||||
|
@ -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<AbstractPaymentModalProps> = ({ isOp
|
||||
*/
|
||||
const handleFormSuccess = async (result: Invoice|PaymentSchedule): Promise<void> => {
|
||||
setSubmitState(false);
|
||||
GTM.trackPurchase(result.id, result.total);
|
||||
afterSuccess(result);
|
||||
};
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -13,28 +13,20 @@ Application.Controllers.controller('CookiesController', ['$scope', '$cookies', '
|
||||
// link pointed by "learn more"
|
||||
$scope.learnMoreUrl = 'https://www.cookiesandyou.com/';
|
||||
|
||||
// current user wallet
|
||||
// add a cookie to the browser, saving the user choice to refuse cookies
|
||||
$scope.declineCookies = function () {
|
||||
const expires = moment().add(13, 'months').toDate();
|
||||
$cookies.put('fab-manager-cookies-consent', 'decline', { expires });
|
||||
readCookie();
|
||||
};
|
||||
|
||||
// current wallet transactions
|
||||
// add a cookie to the browser, saving the user choice to accept cookies.
|
||||
// Then enable the analytics
|
||||
$scope.acceptCookies = function () {
|
||||
const expires = moment().add(13, 'months').toDate();
|
||||
$cookies.put('fab-manager-cookies-consent', 'accept', { expires });
|
||||
readCookie();
|
||||
// enable tracking using code provided by google analytics
|
||||
/* eslint-disable */
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', Fablab.trackingId, 'auto');
|
||||
ga('send', 'pageview');
|
||||
/* eslint-enable */
|
||||
GTM.enableAnalytics(Fablab.trackingId);
|
||||
};
|
||||
|
||||
/* PRIVATE SCOPE */
|
||||
@ -44,7 +36,7 @@ Application.Controllers.controller('CookiesController', ['$scope', '$cookies', '
|
||||
*/
|
||||
const initialize = function () {
|
||||
readCookie();
|
||||
// if the privacy policy was defined, redirect the user to it
|
||||
// if the privacy policy was defined, redirect the user to it when clicking on "read more"
|
||||
Setting.get({ name: 'privacy_body' }, data => {
|
||||
if (data.setting.value) {
|
||||
$scope.learnMoreUrl = '#!/privacy-policy';
|
||||
|
@ -1,8 +1,3 @@
|
||||
/* eslint-disable
|
||||
no-undef,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS101: Remove unnecessary use of Array.from
|
||||
@ -135,7 +130,7 @@ Application.Filters.filter('projectsCollabored', [function () {
|
||||
};
|
||||
}]);
|
||||
|
||||
// depend on humanize.js lib in /vendor
|
||||
// depend on app/frontend/src/javascript/lib/humanize.js
|
||||
Application.Filters.filter('humanize', [function () {
|
||||
return (element, param) => Humanize.truncate(element, param, null);
|
||||
}]);
|
||||
|
43
app/frontend/src/javascript/lib/gtm.js
Normal file
43
app/frontend/src/javascript/lib/gtm.js
Normal file
@ -0,0 +1,43 @@
|
||||
// this script loads the google tag manager, used by Google Analytics V4
|
||||
(function () {
|
||||
const GTM = {};
|
||||
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag () { window.dataLayer.push(arguments); }
|
||||
|
||||
GTM.enableAnalytics = function (trackingId) {
|
||||
gtag('js', new Date());
|
||||
gtag('config', trackingId);
|
||||
|
||||
const node = document.createElement('script');
|
||||
const firstScript = document.getElementsByTagName('script')[0];
|
||||
node.async = true;
|
||||
node.src = `//www.googletagmanager.com/gtag/js?id=${trackingId}`;
|
||||
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) {
|
||||
module.exports = GTM;
|
||||
}
|
||||
}).call(this);
|
@ -195,4 +195,11 @@ class Setting < ApplicationRecord
|
||||
setting = find_or_initialize_by(name: name)
|
||||
setting.save && setting.history_values.create(invoicing_profile: user.invoicing_profile, value: value.to_s)
|
||||
end
|
||||
|
||||
##
|
||||
# Check if the given setting was set
|
||||
##
|
||||
def self.set?(name)
|
||||
find_by(name: name)&.value.nil? ? false : true
|
||||
end
|
||||
end
|
||||
|
@ -1381,7 +1381,7 @@ en:
|
||||
online_payment: "Is the online payment module active?"
|
||||
invoices: "Is the invoicing module active?"
|
||||
openlab: "Is the project sharing module (OpenLab) active?"
|
||||
tracking_id_info_html: "<p>To enable the statistical tracking of the visits using Google Analytics, set your tracking ID here. It is in the form UA-000000-2. Visit <a href='https://analytics.google.com/analytics/web/' target='_blank'>the Google Analytics website</a> to get one.<br/><strong>Warning:</strong> if you enable this feature, remember to write it in your privacy policy, above.</p><p>The host name is also required to use Google Analytics. You can get it by clicking on the adjacent button. This last parameter is used elsewhere, please set it carefully.</p>"
|
||||
tracking_id_info_html: "To enable the statistical tracking of the visits using Google Analytics V4, set your tracking ID here. It is in the form G-XXXXXX. Visit <a href='https://analytics.google.com/analytics/web/' target='_blank'>the Google Analytics website</a> to get one.<br/><strong>Warning:</strong> if you enable this feature, a cookie will be created. Remember to write it down in your privacy policy, above."
|
||||
tracking_id: "Tracking ID"
|
||||
open_api_clients:
|
||||
add_new_client: "Create new API client"
|
||||
|
@ -28,6 +28,7 @@ const customConfig = {
|
||||
'window.CodeMirror': 'codemirror',
|
||||
MediumEditor: 'medium-editor',
|
||||
Humanize: path.resolve(path.join(__dirname, '../../app/frontend/src/javascript/lib/humanize.js')),
|
||||
GTM: path.resolve(path.join(__dirname, '../../app/frontend/src/javascript/lib/gtm.js')),
|
||||
moment: 'moment',
|
||||
Application: [path.resolve(path.join(__dirname, '../../app/frontend/src/javascript/app.js')), 'Application'],
|
||||
process: 'process/browser'
|
||||
|
@ -63,7 +63,6 @@
|
||||
"angular-base64-upload": "^0.0.9",
|
||||
"angular-bootstrap-switch": "https://github.com/sleede/angular-bootstrap-switch.git#develop",
|
||||
"angular-cookies": "1.7",
|
||||
"angular-google-analytics": "1.1",
|
||||
"angular-growl-v2": "https://github.com/JanStevens/angular-growl-2.git#0.7.9",
|
||||
"angular-i18n": "1.7",
|
||||
"angular-loading-bar": "^0.9.0",
|
||||
|
@ -1968,11 +1968,6 @@ angular-cookies@1.7:
|
||||
resolved "https://registry.yarnpkg.com/angular-cookies/-/angular-cookies-1.7.9.tgz#0f0cd2a9d1c81e5b8d6c6711d41f0909f9d0b8e0"
|
||||
integrity sha512-3eRq/aPrtCZKDWQnc3nW3sFoMbLiHkCkyDF2O9u7VXnqvVsUPaipk5R1ZqahgcSQHQrN/F5IU4T4nrz52qAZmA==
|
||||
|
||||
angular-google-analytics@1.1:
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/angular-google-analytics/-/angular-google-analytics-1.1.8.tgz#e497926c0f77cd6eec0c0cbdf0b20e58938cf8a0"
|
||||
integrity sha1-5JeSbA93zW7sDAy98LIOWJOM+KA=
|
||||
|
||||
"angular-growl-v2@https://github.com/JanStevens/angular-growl-2.git#0.7.9":
|
||||
version "0.7.9"
|
||||
resolved "https://github.com/JanStevens/angular-growl-2.git#2a3a40e01419af879f80f582baaeceef3408e295"
|
||||
|
Loading…
x
Reference in New Issue
Block a user