diff --git a/.eslintignore b/.eslintignore index 8f123893d..8346f2f11 100755 --- a/.eslintignore +++ b/.eslintignore @@ -4,4 +4,3 @@ docs node_modules/ __mocks__/ __snapshots__/ -src/cohesion/index.js diff --git a/public/index.html b/public/index.html index 5ce7bb9ec..b21df0898 100644 --- a/public/index.html +++ b/public/index.html @@ -18,20 +18,6 @@ crossorigin="anonymous" referrerpolicy="no-referrer" > - <% if (process.env.OPTIMIZELY_URL) { %> <% } else if (process.env.OPTIMIZELY_PROJECT_ID) { %> diff --git a/src/MainApp.jsx b/src/MainApp.jsx index b107e365a..d37889b8a 100755 --- a/src/MainApp.jsx +++ b/src/MainApp.jsx @@ -5,6 +5,7 @@ import { AppProvider } from '@edx/frontend-platform/react'; import { Helmet } from 'react-helmet'; import { Navigate, Route, Routes } from 'react-router-dom'; +import Cohesion from './cohesion'; import { EmbeddedRegistrationRoute, NotFoundPage, registerIcons, UnAuthOnlyRoute, } from './common-components'; @@ -29,11 +30,13 @@ import { RegistrationPage } from './register'; import { ResetPasswordPage } from './reset-password'; import './index.scss'; +import './cohesion/cohesion.scss'; registerIcons(); const MainApp = () => ( + diff --git a/src/cohesion/index.js b/src/cohesion/index.js index 2239527f1..6acfa77ef 100644 --- a/src/cohesion/index.js +++ b/src/cohesion/index.js @@ -1,52 +1,63 @@ -module.exports = () => { - if (process.env.COHESION_WRITE_KEY && process.env.COHESION_SOURCE_KEY) { - !(function (co, h, e, s, i, o, n) { - const d = "documentElement"; - const a = "className"; - h[d][a] += " preampjs fusejs"; - n.k = e; - co._Cohesion = n; - co._Preamp = { k: s, start: new Date() }; - co._Fuse = { k: i }; - co._Tagular = { k: o }; - [e, s, i, o].map((x) => { - co[x] = - co[x] || - function () { - (co[x].q = co[x].q || []).push([].slice.call(arguments)); - }; - }); - const b = function () { - const u = h[d][a]; - h[d][a] = u.replace(/ ?preampjs| ?fusejs/g, ""); - }; - h.addEventListener("DOMContentLoaded", () => { - co.setTimeout(b, 3e3); - co._Preamp.docReady = co._Fuse.docReady = !0; - }); - const z = h.createElement("script"); - z.async = 1; - z.src = "https://cdn.cohesionapps.com/cohesion/cohesion-latest.min.js"; - z.onerror = function () { - const ce = "error"; - const f = "function"; - for (const o of co[e].q || []) { - o[0] === ce && typeof o[1] === f && o[1](); +import { useEffect } from 'react'; + +const CohesionScript = () => { + useEffect(() => { + const cohesionScript = document.createElement('script'); + const idStitching = document.createElement('script'); + + cohesionScript.innerHTML = ` + !function (co, h, e, s, i, o, n) { + var d = 'documentElement'; var a = 'className'; h[d][a] += ' preampjs fusejs'; + n.k = e; co._Cohesion = n; co._Preamp = { k: s, start: new Date }; co._Fuse = { k: i }; co._Tagular = { k: o }; + [e, s, i, o].map(function (x) { co[x] = co[x] || function () { (co[x].q = co[x].q || []).push([].slice.call(arguments)) } }); + var b = function () { var u = h[d][a]; h[d][a] = u.replace(/ ?preampjs| ?fusejs/g, '') }; + h.addEventListener('DOMContentLoaded', function () { + co.setTimeout(b, 3e3); + co._Preamp.docReady = co._Fuse.docReady = !0 + }); var z = h.createElement('script'); + z.async = 1; z.src = 'https://cdn.cohesionapps.com/cohesion/cohesion-latest.min.js'; + z.onerror = function () { var ce = 'error',f = 'function'; for (var o of co[e].q || []) o[0] === ce && typeof o[1] == f && o[1](); co[e] = function (n, cb) { n === ce && typeof cb == f && cb() }; b() }; + h.head.appendChild(z); + } + (window, document, 'cohesion', 'preamp', 'fuse', 'tagular', { + tagular: { + writeKey: "${process.env.COHESION_WRITE_KEY}", + sourceKey: "${process.env.COHESION_SOURCE_KEY}", + taggy: { + enabled: true + } } - co[e] = function (n, cb) { - n === ce && typeof cb === f && cb(); - }; - b(); - }; - h.head.appendChild(z); - })(window, document, "cohesion", "preamp", "fuse", "tagular", { - tagular: { - writeKey: process.env.COHESION_WRITE_KEY, - sourceKey: process.env.COHESION_SOURCE_KEY, - taggy: { - enabled: true, - }, - }, - }); - } + }); + `; + document.head.appendChild(cohesionScript); + + // Id Stitching script (executed after the cohesionScript is loaded) + cohesionScript.onload = () => { + idStitching.innerHTML = ` + window.tagular("beam", { + "@type": "core.Identify.v1", + traits: {}, + externalIds: [ + { + id: window.analytics.user().anonymousId(), + type: "segment_anonym_id", + collection: "users", + encoding: "none", + }, + ], + }); + `; + document.head.appendChild(idStitching); + }; + + // Cleanup + return () => { + document.head.removeChild(cohesionScript); + document.head.removeChild(idStitching); + }; + }, []); + + return null; }; + +export default CohesionScript; diff --git a/src/common-components/RedirectLogistration.jsx b/src/common-components/RedirectLogistration.jsx index 05ba98e75..84bb4610b 100644 --- a/src/common-components/RedirectLogistration.jsx +++ b/src/common-components/RedirectLogistration.jsx @@ -28,7 +28,7 @@ const RedirectLogistration = (props) => { let finalRedirectUrl = ''; if (success) { - // This event is used by cohestion upon successful login + // This event is used by cohesion upon successful login trackCohesionEvent(cohesionEventData); // If we're in a third party auth pipeline, we must complete the pipeline // once user has successfully logged in. Otherwise, redirect to the specified redirect url. diff --git a/src/common-components/SocialAuthProviders.jsx b/src/common-components/SocialAuthProviders.jsx index 7b78d2c84..744d7a385 100644 --- a/src/common-components/SocialAuthProviders.jsx +++ b/src/common-components/SocialAuthProviders.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { useSelector } from 'react-redux'; import { getConfig } from '@edx/frontend-platform'; import { useIntl } from '@edx/frontend-platform/i18n'; @@ -9,8 +9,8 @@ import { Login } from '@openedx/paragon/icons'; import PropTypes from 'prop-types'; import messages from './messages'; -import { PAGE_TYPES } from '../cohesion/constants'; -import { setCohesionEventStates } from '../cohesion/data/actions'; +import { ELEMENT_TYPES, PAGE_TYPES } from '../cohesion/constants'; +import trackCohesionEvent from '../cohesion/trackers'; import { LOGIN_PAGE, REGISTER_PAGE, SUPPORTED_ICON_CLASSES, } from '../data/constants'; @@ -18,22 +18,19 @@ import { setCookie } from '../data/utils'; const SocialAuthProviders = (props) => { const { formatMessage } = useIntl(); - const dispatch = useDispatch(); const { referrer, socialAuthProviders } = props; const registrationFields = useSelector(state => state.register.registrationFormData); - function handleSubmit(e) { + function handleSubmit(e, providerName) { e.preventDefault(); - const elementType = e.target.nodeName; - const elementText = e.target.name; const eventData = { pageType: referrer === LOGIN_PAGE ? PAGE_TYPES.SIGN_IN : PAGE_TYPES.ACCOUNT_CREATION, - elementType, - webElementText: elementText, - webElementName: elementText.toLowerCase(), + elementType: ELEMENT_TYPES.BUTTON, + webElementText: providerName, + webElementName: providerName.toLowerCase(), }; - - dispatch(setCohesionEventStates(eventData)); + // This event is used by cohesion upon successful login + trackCohesionEvent(eventData); if (referrer === REGISTER_PAGE) { setCookie('marketingEmailsOptIn', registrationFields?.configurableFormFields?.marketingEmailsOptIn); @@ -49,7 +46,7 @@ const SocialAuthProviders = (props) => { type="button" className={`btn-social btn-${provider.id} ${index % 2 === 0 ? 'mr-3' : ''}`} data-provider-url={referrer === LOGIN_PAGE ? provider.loginUrl : provider.registerUrl} - onClick={handleSubmit} + onClick={(event) => handleSubmit(event, provider?.name)} > {provider.iconImage ? (