Skip to content

Commit

Permalink
Améliore le système de tracking (#1009)
Browse files Browse the repository at this point in the history
* chore: Move hooks to hook folder

* feat: Move tracking logic to context, add event saving system

* fix: Plausible bug

* feat: Improving context

* feat: Reset events state when restarting a simulation

* feat: Rename context + fix use engine issue

* fix: Rebase issues

* fix: Bug engine called in `useFunnel`

* feat: Move all logic to `useFunnel`

* feat: Switch to Matomo context

* feat: Move matomo events to dedicated file

* feat: Remove useFunnel move parcours test events

* chore: Nettoyage

* feat: Add track region event

* feat: Add event to detect active iframes

* feat: Move save events sent logic to redux

* chore: Rename Provider

* chore: Cancel removal of trackers

* chore : Readd other deleted event tracker

* fix: Bug + move category event tracker to start button

* chore: Rename provider

* fix: Remove duplicates

* fix: Add missing element in condition

* feat: Add again deleted events

* fix: Reenable dev tracker

* feat: Ajoute un event listener sur body pour discriminer les iframes interagies

* fix: revert event label mods + add missing events

* fix: corrige catégories évènements

* fix: Events format

* fix: Issues after rebase

* fix: Error after rebase

* feat: Update cypress workflow

* fix: Oubli tracker

* chore: Add missing trans
  • Loading branch information
bjlaa committed May 9, 2023
1 parent a4b28b0 commit d719038
Show file tree
Hide file tree
Showing 66 changed files with 720 additions and 334 deletions.
5 changes: 3 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ module.exports = {
extends: [
"eslint:recommended",
"plugin:react/recommended",
"prettier"
, "plugin:jsx-a11y/strict"
"prettier",
"plugin:jsx-a11y/strict",
"plugin:react-hooks/recommended"
]
}
7 changes: 6 additions & 1 deletion .github/workflows/test-e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ on:
branches:
- 'master'
pull_request:
types: [ready_for_review]
types:
- opened
- reopened
- synchronize
- ready_for_review

jobs:
e2e:
Expand All @@ -18,6 +22,7 @@ jobs:
matrix:
containers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
name: Testing e2e in worker ${{ matrix.containers }}
if: github.event.pull_request.draft == false
steps:
- name: Checkout repository
uses: actions/checkout@v3.5.2
Expand Down
2 changes: 1 addition & 1 deletion nosgestesclimat
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"eslint": "^8.19.0",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-webpack-plugin": "^3.2.0",
"file-loader": "^6.2.0",
"i18next-parser": "^6.5.0",
Expand Down
22 changes: 13 additions & 9 deletions source/Provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { BrowserRouter } from 'react-router-dom'
import reducers, { RootState } from 'Reducers/rootReducer'
import { applyMiddleware, compose, createStore, Middleware, Store } from 'redux'
import thunk from 'redux-thunk'
import { TrackerProvider } from './contexts/TrackerContext'
import { MatomoProvider } from './contexts/MatomoContext'
import RulesProvider from './RulesProvider'
import { inIframe } from './utils'
import { getIsIframe } from './utils'

declare global {
interface Window {
Expand All @@ -21,7 +21,11 @@ declare global {

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose

if (NODE_ENV === 'production' && 'serviceWorker' in navigator && !inIframe()) {
if (
NODE_ENV === 'production' &&
'serviceWorker' in navigator &&
!getIsIframe()
) {
window.addEventListener('load', () => {
navigator.serviceWorker
.register('/sw.js')
Expand Down Expand Up @@ -74,9 +78,9 @@ export default function Provider({

return (
// If IE < 11 display nothing
<TrackerProvider>
<ReduxProvider store={store}>
<RulesProvider>
<ReduxProvider store={store}>
<RulesProvider>
<MatomoProvider>
<ThemeColorsProvider
color={iframeCouleur && decodeURIComponent(iframeCouleur)}
>
Expand All @@ -90,8 +94,8 @@ export default function Provider({
</SitePathProvider>
</IframeOptionsProvider>
</ThemeColorsProvider>
</RulesProvider>
</ReduxProvider>
</TrackerProvider>
</MatomoProvider>
</RulesProvider>
</ReduxProvider>
)
}
8 changes: 8 additions & 0 deletions source/actions/actions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { RootState, SimulationConfig } from 'Reducers/rootReducer'
import { AnyAction } from 'redux'
import { ThunkAction } from 'redux-thunk'
import { DottedName } from 'Rules'
import { Localisation } from '../components/localisation/utils'
Expand Down Expand Up @@ -253,3 +254,10 @@ export const updateAmortissementAvion = (amortissementAvionObject: Object) => ({
type: 'SET_AMORTISSEMENT',
amortissementAvionObject,
})

export const updateEventsSent = (eventSent: {
[key: string]: boolean
}): AnyAction => ({
type: 'UPDATE_EVENTS_SENT',
eventSent,
})
190 changes: 190 additions & 0 deletions source/analytics/matomo-events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import { DottedName } from 'Rules'

/*
* Matomo events
* https://matomo.org/docs/event-tracking/
* [
* 'trackEvent', // Type de l'évènement
* 'Category' (string), // Catégorie de l'évènement à rattacher à son contexte (cf. exemples ci-dessous)
* 'Action' (string), // Action concrête mesurée (clic sur machin, submit de tel truc, etc.)
* 'Name' (string), // Nom de l'évènement (optionnel) si besoin de détailier l'action
* 'Value' (number) // Une valeur numérique (optionnelle)
* ]
*/

// Partage
export const getMatomoEventShareMobile = (score: number) => [
'trackEvent',
'Partage page de fin',
'Clic bouton "Partager mes résultats" sur mobile',
null,
score,
]
export const getMatomoEventShareDesktop = (score: number) => [
'trackEvent',
'Partage page de fin',
'Clic bouton "Partager mes résultats" sur desktop',
null,
score,
]

// Formulaire
export const getMatomoEventClickNextQuestion = (currentQuestion: string) => [
'trackEvent',
'Formulaire',
'Clic bouton "Suivant"',
currentQuestion,
]
export const getMatomoEventClickDontKnow = (currentQuestion: string) => [
'trackEvent',
'Formulaire',
'Clic bouton "Je ne sais pas"',
currentQuestion,
]
export const getMatomoEventClickHelp = (dottedName: DottedName) => [
'trackEvent',
'help',
dottedName,
]
export const matomoEventKilometerHelp = [
'trackEvent',
'Aide saisie km',
'Ajout trajet km voiture',
]
export const matomoEventKilometerHelpClickOpen = [
'trackEvent',
'Aide saisie km',
'Ouvre aide à la saisie km voiture',
]
export const matomoEventKilometerHelpClickClose = [
'trackEvent',
'Aide saisie km',
'Ferme aide à la saisie km voiture',
]
export const getMatomoEventAmortissement = (dottedName: DottedName) => [
'trackEvent',
'Formulaire',
'Utilisation amortissement avion',
dottedName,
]

// Change Region
export const getMatomoEventChangeRegion = (code: string) => [
'trackEvent',
'I18N',
'Clic bannière localisation',
code,
]

// Iframe
export const getMatomoEventVisitViaIframe = (url: string) => [
'trackEvent',
'iframe',
'visites via iframe',
url,
]
export const matomoEventInteractionIframe = [
'trackEvent',
'iframe',
'interaction avec iframe',
]

// Mode groupe
export const matomoEventModeGroupeFiltres = [
'trackEvent',
'Mode Groupe',
'Ouvre filtres',
]
export const getMatomoEventModeGroupeRealtimeActivation = (
isRealTime: boolean
) => [
'trackEvent',
'Mode Groupe',
isRealTime
? 'Désactivation du mode temps réel'
: 'Activation du mode temps réel',
]
export const getMatomoEventModeGroupeRoomCreation = (mode: string) => [
'trackEvent',
'Mode Groupe',
'Création salle',
mode,
]
export const matomoEventModeGroupeCTAStart = [
'trackEvent',
'Mode Groupe',
'Clic CTA accueil',
]

// Funnel
export const matomoEventParcoursTestStart = [
'trackEvent',
'NGC',
'Clic CTA accueil',
]
export const matomoEventParcoursTestReprendre = [
'trackEvent',
'NGC',
'Clic CTA accueil : Reprendre mon test',
]
export const getMatomoEventParcoursTestTutorialProgress = (
last: boolean,
index: number
) => ['trackEvent', 'testIntro', last ? 'Terminer' : `diapo ${index} passée`]
export const matomoEventParcoursTestSkipTutorial = [
'trackEvent',
'testIntro',
'tuto passé',
]
export const matomoEventFirstAnswer = [
'trackEvent',
'NGC',
'1ère réponse au bilan',
]
export const getMatomoEventParcoursTestCategoryStarted = (category: string) => [
'trackEvent',
'NGC',
'Catégorie démarrée',
category,
]
export const matomoEvent50PercentProgress = [
'trackEvent',
'NGC',
'Progress > 50%',
]
export const matomoEvent90PercentProgress = [
'trackEvent',
'NGC',
'Progress > 90%',
]
export const getMatomoEventParcoursTestOver = (bilan: number | undefined) => [
'trackEvent',
'NGC',
'A terminé la simulation',
null,
bilan || '',
]
export const matomoEventClickBanner = [
'trackEvent',
'NGC',
'Clic explication score',
]
export const matomoEventSwipeEndPage = [
'trackEvent',
'NGC',
'Swipe page de fin',
]
export const getMatomoEventClickActionButtonEndPage = (
score: string | number
) => ['trackEvent', 'NGC', 'Clic bouton action page /fin', null, score]

// Actions
export const getMatomoEventActionRejected = (
dottedName: DottedName,
nodeValue: string
) => ['trackEvent', '/actions', 'Action rejetée', dottedName, nodeValue]

export const getMatomoEventActionAccepted = (
dottedName: DottedName,
nodeValue: string
) => ['trackEvent', '/actions', 'Action sélectionnée', dottedName, nodeValue]
1 change: 0 additions & 1 deletion source/components/Feedback/FeedbackForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ export default function FeedbackForm({ onCancel }: Props) {
script.src = 'https://mon-entreprise.zammad.com/assets/form/form.js'
document.body.appendChild(script)
}, 100)
// tracker.push(['trackEvent', 'Feedback', 'written feedback submitted'])
}, [])

return (
Expand Down
12 changes: 2 additions & 10 deletions source/components/Feedback/PageFeedback.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useCallback, useContext, useState } from 'react'
import { Trans } from 'react-i18next'
import { useLocation } from 'react-router-dom'
import { TrackerContext } from '../../contexts/TrackerContext'
import { MatomoContext } from '../../contexts/MatomoContext'
import safeLocalStorage from '../../storage/safeLocalStorage'
import './Feedback.css'
import Form from './FeedbackForm'
Expand Down Expand Up @@ -33,7 +33,7 @@ export default function PageFeedback({
customEventName,
}: PageFeedbackProps) {
const location = useLocation()
const tracker = useContext(TrackerContext)
const { trackEvent } = useContext(MatomoContext)
const [state, setState] = useState({
showForm: false,
showThanks: false,
Expand All @@ -44,18 +44,11 @@ export default function PageFeedback({
})

const handleFeedback = useCallback(({ useful }: { useful: boolean }) => {
tracker.push([
'trackEvent',
'Feedback',
useful ? 'positive rating' : 'negative rating',
location.pathname,
])
const feedback = [
customEventName || 'rate page usefulness',
location.pathname,
useful ? 10 : 0.1,
] as [string, string, number]
tracker.push(['trackEvent', 'Feedback', ...feedback])
saveFeedbackOccurrenceInLocalStorage(feedback)
setState({
showThanks: useful,
Expand All @@ -65,7 +58,6 @@ export default function PageFeedback({
}, [])

const handleErrorReporting = useCallback(() => {
tracker.push(['trackEvent', 'Feedback', 'report error', location.pathname])
setState({ ...state, showForm: true })
}, [])

Expand Down
2 changes: 1 addition & 1 deletion source/components/NewsBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { sortReleases } from 'Pages/news/NewsItem'
import { Trans, useTranslation } from 'react-i18next'
import { Link } from 'react-router-dom'
import styled from 'styled-components'
import { usePersistingState } from '../hooks/usePersistState'
import { getCurrentLangInfos } from '../locales/translation'
import { capitalise0 } from '../utils'
import { usePersistingState } from './utils/persistState'

export const localStorageKey = 'last-viewed-release'

Expand Down
2 changes: 1 addition & 1 deletion source/components/ProgressCircle.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { motion, useMotionValue, useSpring } from 'framer-motion'
import { useEffect } from 'react'
import { useSelector } from 'react-redux'
import { useSimulationProgress } from '../hooks/useNextQuestion'
import { configSelector } from '../selectors/simulationSelectors'
import { useSimulationProgress } from './utils/useNextQuestion'

export default () => {
const engineState = useSelector((state) => state.engineState)
Expand Down
2 changes: 1 addition & 1 deletion source/components/SearchButton.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useState } from 'react'
import { Trans } from 'react-i18next'
import { Navigate } from 'react-router'
import useKeypress from './utils/useKeyPress'
import useKeypress from '../hooks/useKeyPress'

type SearchButtonProps = {
invisibleButton?: boolean
Expand Down
2 changes: 1 addition & 1 deletion source/components/SessionBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import { RootState } from 'Reducers/rootReducer'
import { answeredQuestionsSelector } from 'Selectors/simulationSelectors'
import styled from 'styled-components'
import { resetLocalisation } from '../actions/actions'
import { usePersistingState } from '../hooks/usePersistState'
import { useTestCompleted } from '../selectors/simulationSelectors'
import { enquêteSelector } from '../sites/publicodes/enquête/enquêteSelector'
import { omit } from '../utils'
import CardGameIcon from './CardGameIcon'
import ProgressCircle from './ProgressCircle'
import { usePersistingState } from './utils/persistState'

const ActionsInteractiveIcon = () => {
const actionChoices = useSelector((state) => state.actionChoices),
Expand Down

0 comments on commit d719038

Please sign in to comment.