From 9cb4ccad0df39dacbda7e9479a010933cdd7a966 Mon Sep 17 00:00:00 2001 From: Geoffroy Begouaussel <geoffroy.begouaussel@pix.fr> Date: Mon, 18 Nov 2024 16:39:27 +0100 Subject: [PATCH] feat(mon-pix): add results-page matomo metrics --- .../custom-organization-block.gjs | 26 +++++++++ .../results/evaluation-results-hero/index.gjs | 49 ++++++++++++++-- .../retry-or-reset-block.gjs | 56 +++++++++++++++++++ .../results-details/index.gjs | 14 +++++ .../evaluation-results-tabs/rewards/index.gjs | 14 +++++ .../evaluation-results-tabs/trainings.gjs | 19 +++++++ .../results/hero/retry-or-reset-block-test.js | 11 +++- 7 files changed, 183 insertions(+), 6 deletions(-) diff --git a/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/custom-organization-block.gjs b/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/custom-organization-block.gjs index 9d854b6e5e6..3f16e5b8c4e 100644 --- a/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/custom-organization-block.gjs +++ b/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/custom-organization-block.gjs @@ -1,10 +1,14 @@ import PixButtonLink from '@1024pix/pix-ui/components/pix-button-link'; +import { action } from '@ember/object'; +import { inject as service } from '@ember/service'; import Component from '@glimmer/component'; import { t } from 'ember-intl'; import MarkdownToHtml from '../../../../markdown-to-html'; export default class EvaluationResultsCustomOrganizationBlock extends Component { + @service metrics; + get customButtonUrl() { if (this.args.campaign.customResultPageButtonUrl && this.args.campaign.customResultPageButtonText) { const params = {}; @@ -21,6 +25,26 @@ export default class EvaluationResultsCustomOrganizationBlock extends Component } } + @action + handleCustomButtonDisplay() { + this.metrics.add({ + event: 'custom-event', + 'pix-event-category': 'Fin de parcours', + 'pix-event-action': "Affichage du bloc de l'organisation", + 'pix-event-name': 'Présence d’un bouton comportant un lien externe', + }); + } + + @action + handleCustomButtonClick() { + this.metrics.add({ + event: 'custom-event', + 'pix-event-category': 'Fin de parcours', + 'pix-event-action': "Affichage du bloc de l'organisation", + 'pix-event-name': 'Clic sur le lien externe', + }); + } + <template> <div class="evaluation-results-hero__organization-block"> <h3 class="evaluation-results-hero-organization-block__title"> @@ -34,10 +58,12 @@ export default class EvaluationResultsCustomOrganizationBlock extends Component /> {{/if}} {{#if this.customButtonUrl}} + {{this.handleCustomButtonDisplay}} <PixButtonLink class="evaluation-results-hero-organization-block__link" @href={{this.customButtonUrl}} @variant="secondary" + onclick={{this.handleCustomButtonClick}} > {{@campaign.customResultPageButtonText}} </PixButtonLink> diff --git a/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/index.gjs b/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/index.gjs index e4af72a354c..a1bc7c6eab6 100644 --- a/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/index.gjs +++ b/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/index.gjs @@ -4,7 +4,7 @@ import PixMessage from '@1024pix/pix-ui/components/pix-message'; import PixStars from '@1024pix/pix-ui/components/pix-stars'; import { fn } from '@ember/helper'; import { action } from '@ember/object'; -import { service } from '@ember/service'; +import { inject as service } from '@ember/service'; import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; import { t } from 'ember-intl'; @@ -17,6 +17,7 @@ import RetryOrResetBlock from './retry-or-reset-block'; export default class EvaluationResultsHero extends Component { @service currentUser; + @service metrics; @service router; @service store; @service tabManager; @@ -61,7 +62,7 @@ export default class EvaluationResultsHero extends Component { } @action - async improveResults() { + async handleImproveResults() { if (this.isButtonLoading) return; try { @@ -69,8 +70,17 @@ export default class EvaluationResultsHero extends Component { this.isButtonLoading = true; const campaignParticipationResult = this.args.campaignParticipationResult; + const adapter = this.store.adapterFor('campaign-participation-result'); await adapter.beginImprovement(campaignParticipationResult.id); + + this.metrics.add({ + event: 'custom-event', + 'pix-event-category': 'Fin de parcours', + 'pix-event-action': 'Amélioration des résultats', + 'pix-event-name': "Clic sur le bouton 'Je retente'", + }); + this.router.transitionTo('campaigns.entry-point', this.args.campaign.code); } catch { this.hasGlobalError = true; @@ -98,6 +108,13 @@ export default class EvaluationResultsHero extends Component { campaignParticipationResult.isShared = true; campaignParticipationResult.canImprove = false; + + this.metrics.add({ + event: 'custom-event', + 'pix-event-category': 'Fin de parcours', + 'pix-event-action': 'Envoi des résultats', + 'pix-event-name': "Envoi des résultats depuis l'en-tête", + }); } catch { this.hasGlobalError = true; } finally { @@ -110,6 +127,26 @@ export default class EvaluationResultsHero extends Component { this.hasGlobalError = value; } + @action + handleBackToHomepageDisplay() { + this.metrics.add({ + event: 'custom-event', + 'pix-event-category': 'Fin de parcours', + 'pix-event-action': 'Sortie de parcours', + 'pix-event-name': "Affichage du bouton 'Revenir à la page d'accueil'", + }); + } + + @action + handleBackToHomepageClick() { + this.metrics.add({ + event: 'custom-event', + 'pix-event-category': 'Fin de parcours', + 'pix-event-action': 'Sortie de parcours', + 'pix-event-name': "Clic sur le bouton 'Revenir à la page d'accueil'", + }); + } + <template> <div class="evaluation-results-hero"> <div class="evaluation-results-hero__results"> @@ -186,7 +223,8 @@ export default class EvaluationResultsHero extends Component { </PixButton> {{else}} {{#unless @campaign.hasCustomResultPageButton}} - <PixButtonLink @route="authentication.login" @size="large"> + {{this.handleBackToHomepageDisplay}} + <PixButtonLink @route="authentication.login" @size="large" onclick={{this.handleBackToHomepageClick}}> {{t "navigation.back-to-homepage"}} </PixButtonLink> {{/unless}} @@ -204,7 +242,7 @@ export default class EvaluationResultsHero extends Component { <PixButton @variant="tertiary" @size="large" - @triggerAction={{this.improveResults}} + @triggerAction={{this.handleImproveResults}} @isLoading={{this.isButtonLoading}} > {{t "pages.skill-review.actions.improve"}} @@ -212,7 +250,8 @@ export default class EvaluationResultsHero extends Component { {{/if}} {{else}} {{#unless @campaign.hasCustomResultPageButton}} - <PixButtonLink @route="authentication.login" @size="large"> + {{this.handleBackToHomepageDisplay}} + <PixButtonLink @route="authentication.login" @size="large" onclick={{this.handleBackToHomepageClick}}> {{if this.currentUser.user.isAnonymous (t "common.actions.login") (t "navigation.back-to-homepage")}} </PixButtonLink> {{/unless}} diff --git a/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/retry-or-reset-block.gjs b/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/retry-or-reset-block.gjs index c830d632fce..ab2cba80572 100644 --- a/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/retry-or-reset-block.gjs +++ b/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/retry-or-reset-block.gjs @@ -4,21 +4,75 @@ import PixButtonLink from '@1024pix/pix-ui/components/pix-button-link'; import PixMessage from '@1024pix/pix-ui/components/pix-message'; import PixModal from '@1024pix/pix-ui/components/pix-modal'; import { action } from '@ember/object'; +import { inject as service } from '@ember/service'; import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; import { t } from 'ember-intl'; export default class EvaluationResultsHeroRetryOrResetBlock extends Component { + @service metrics; + @tracked isResetModalVisible = false; retryQueryParams = { retry: true }; resetQueryParams = { reset: true }; + constructor() { + super(...arguments); + + if (this.args.campaignParticipationResult.canRetry) { + this.metrics.add({ + event: 'custom-event', + 'pix-event-category': 'Fin de parcours', + 'pix-event-action': 'Affichage du bloc RAZ/Repasser un parcours', + 'pix-event-name': "Présence du bouton 'Repasser un parcours'", + }); + } + + if (this.args.campaignParticipationResult.canReset) { + this.metrics.add({ + event: 'custom-event', + 'pix-event-category': 'Fin de parcours', + 'pix-event-action': 'Affichage du bloc RAZ/Repasser un parcours', + 'pix-event-name': "Présence du bouton 'Remettre à zéro et tout retenter'", + }); + } + } + + @action + handleRetryClick() { + this.metrics.add({ + event: 'custom-event', + 'pix-event-category': 'Fin de parcours', + 'pix-event-action': 'Affichage du bloc RAZ/Repasser un parcours', + 'pix-event-name': "Clic sur le bouton 'Repasser mon parcours'", + }); + } + @action toggleResetModalVisibility() { + if (!this.isResetModalVisible) { + this.metrics.add({ + event: 'custom-event', + 'pix-event-category': 'Fin de parcours', + 'pix-event-action': 'Affichage du bloc RAZ/Repasser un parcours', + 'pix-event-name': "Ouverture de la modale 'Remettre à zéro et tout retenter'", + }); + } + this.isResetModalVisible = !this.isResetModalVisible; } + @action + handleResetClick() { + this.metrics.add({ + event: 'custom-event', + 'pix-event-category': 'Fin de parcours', + 'pix-event-action': 'Affichage du bloc RAZ/Repasser un parcours', + 'pix-event-name': "Confirmation de la modale 'Remettre à zéro et tout retenter'", + }); + } + <template> <div class="evaluation-results-hero__retry"> <div class="evaluation-results-hero-retry__content"> @@ -35,6 +89,7 @@ export default class EvaluationResultsHeroRetryOrResetBlock extends Component { @route="campaigns.entry-point" @model={{@campaign.code}} @query={{this.retryQueryParams}} + onclick={{this.handleRetryClick}} > {{t "pages.skill-review.hero.retry.actions.retry"}} </PixButtonLink> @@ -68,6 +123,7 @@ export default class EvaluationResultsHeroRetryOrResetBlock extends Component { @model={{@campaign.code}} @query={{this.resetQueryParams}} @variant="error" + onclick={{this.handleResetClick}} > {{t "common.actions.confirm"}} </PixButtonLink> diff --git a/mon-pix/app/components/campaigns/assessment/results/evaluation-results-tabs/results-details/index.gjs b/mon-pix/app/components/campaigns/assessment/results/evaluation-results-tabs/results-details/index.gjs index a7a02134c9b..f99031e3359 100644 --- a/mon-pix/app/components/campaigns/assessment/results/evaluation-results-tabs/results-details/index.gjs +++ b/mon-pix/app/components/campaigns/assessment/results/evaluation-results-tabs/results-details/index.gjs @@ -1,9 +1,23 @@ +import { inject as service } from '@ember/service'; import Component from '@glimmer/component'; import { t } from 'ember-intl'; import CompetenceRow from './competence-row'; export default class EvaluationResultsDetailsTab extends Component { + @service metrics; + + constructor() { + super(...arguments); + + this.metrics.add({ + event: 'custom-event', + 'pix-event-category': 'Fin de parcours', + 'pix-event-action': 'Affichage onglet', + 'pix-event-name': "Affichage de l'onglet Détails", + }); + } + get groupedCompetencesByArea() { return this.args.competenceResults.reduce((areas, competenceResult) => { const existingArea = areas.find((area) => area.areaTitle === competenceResult.areaTitle); diff --git a/mon-pix/app/components/campaigns/assessment/results/evaluation-results-tabs/rewards/index.gjs b/mon-pix/app/components/campaigns/assessment/results/evaluation-results-tabs/rewards/index.gjs index 5406d0c2732..773edcd5194 100644 --- a/mon-pix/app/components/campaigns/assessment/results/evaluation-results-tabs/rewards/index.gjs +++ b/mon-pix/app/components/campaigns/assessment/results/evaluation-results-tabs/rewards/index.gjs @@ -1,3 +1,4 @@ +import { inject as service } from '@ember/service'; import FaIcon from '@fortawesome/ember-fontawesome/components/fa-icon'; import Component from '@glimmer/component'; import { t } from 'ember-intl'; @@ -5,6 +6,19 @@ import { t } from 'ember-intl'; import RewardsBadge from './badge'; export default class Rewards extends Component { + @service metrics; + + constructor() { + super(...arguments); + + this.metrics.add({ + event: 'custom-event', + 'pix-event-category': 'Fin de parcours', + 'pix-event-action': 'Affichage onglet', + 'pix-event-name': "Affichage de l'onglet Récompenses", + }); + } + getFilteredAndSortedBadges(acquisitionStatus) { return this.args.badges .toArray() diff --git a/mon-pix/app/components/campaigns/assessment/results/evaluation-results-tabs/trainings.gjs b/mon-pix/app/components/campaigns/assessment/results/evaluation-results-tabs/trainings.gjs index dcb9b706efc..0d4adfa4300 100644 --- a/mon-pix/app/components/campaigns/assessment/results/evaluation-results-tabs/trainings.gjs +++ b/mon-pix/app/components/campaigns/assessment/results/evaluation-results-tabs/trainings.gjs @@ -11,10 +11,22 @@ import TrainingCard from '../../../../training/card'; export default class EvaluationResultsTabsTrainings extends Component { @service currentUser; @service store; + @service metrics; @tracked isShareResultsLoading = false; @tracked isShareResultsError = false; + constructor() { + super(...arguments); + + this.metrics.add({ + event: 'custom-event', + 'pix-event-category': 'Fin de parcours', + 'pix-event-action': 'Affichage onglet', + 'pix-event-name': "Affichage de l'onglet Formations", + }); + } + @action async shareResults() { const adapter = this.store.adapterFor('campaign-participation-result'); @@ -33,6 +45,13 @@ export default class EvaluationResultsTabsTrainings extends Component { }, { reload: true }, ); + + this.metrics.add({ + event: 'custom-event', + 'pix-event-category': 'Fin de parcours', + 'pix-event-action': 'Envoi des résultats', + 'pix-event-name': "Envoi des résultats depuis l'onglet Formations", + }); } catch { this.isShareResultsError = true; } finally { diff --git a/mon-pix/tests/integration/components/campaigns/assessment/results/hero/retry-or-reset-block-test.js b/mon-pix/tests/integration/components/campaigns/assessment/results/hero/retry-or-reset-block-test.js index 64d63a4edfc..fb7407c9c16 100644 --- a/mon-pix/tests/integration/components/campaigns/assessment/results/hero/retry-or-reset-block-test.js +++ b/mon-pix/tests/integration/components/campaigns/assessment/results/hero/retry-or-reset-block-test.js @@ -12,8 +12,17 @@ module( setupIntlRenderingTest(hooks); test('displays a title, a description and a message', async function (assert) { + // given + this.set('campaign', {}); + this.set('campaignParticipationResult', {}); + // when - const screen = await render(hbs`<Campaigns::Assessment::Results::EvaluationResultsHero::RetryOrResetBlock />`); + const screen = await render( + hbs`<Campaigns::Assessment::Results::EvaluationResultsHero::RetryOrResetBlock + @campaign={{this.campaign}} + @campaignParticipationResult={{this.campaignParticipationResult}} +/>`, + ); // then assert.dom(screen.getByText(t('pages.skill-review.hero.retry.title'))).exists();