From 69aa7b906ea2873a3cc2b587afa4c754345d6d80 Mon Sep 17 00:00:00 2001 From: Oluwaseun Olorunsola Date: Wed, 18 Dec 2024 11:19:59 +0100 Subject: [PATCH] Setup basic event tracking framework MAILPOET-6365 --- .../src/components/block-editor/layout.tsx | 4 ++++ packages/js/email-editor/src/editor.tsx | 2 ++ .../src/events/event-collector.ts | 16 ++++++++++++++ .../email-editor/src/events/event-pipeline.ts | 18 ++++++++++++++++ packages/js/email-editor/src/events/index.ts | 2 ++ packages/js/email-editor/src/store/actions.ts | 21 +++++++++++++++---- 6 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 packages/js/email-editor/src/events/event-collector.ts create mode 100644 packages/js/email-editor/src/events/event-pipeline.ts create mode 100644 packages/js/email-editor/src/events/index.ts diff --git a/packages/js/email-editor/src/components/block-editor/layout.tsx b/packages/js/email-editor/src/components/block-editor/layout.tsx index f8354151a8..7c2f7a0673 100644 --- a/packages/js/email-editor/src/components/block-editor/layout.tsx +++ b/packages/js/email-editor/src/components/block-editor/layout.tsx @@ -25,7 +25,11 @@ import { VisualEditor } from './visual-editor/visual-editor'; import { TemplateSelection } from '../template-select'; +import { recordEvent } from '../../events'; + export function Layout() { + recordEvent( 'editor-layout-loaded' ); + const { isFullscreenActive, isSidebarOpened, diff --git a/packages/js/email-editor/src/editor.tsx b/packages/js/email-editor/src/editor.tsx index 222f283dd4..d3028e17a2 100644 --- a/packages/js/email-editor/src/editor.tsx +++ b/packages/js/email-editor/src/editor.tsx @@ -8,6 +8,7 @@ import { InnerEditor } from './components/block-editor'; import { createStore, storeName } from './store'; import { initHooks } from './editor-hooks'; import { KeyboardShortcuts } from './components/keybord-shortcuts'; +import { initEventCollector } from './events'; import './index.scss'; function Editor() { @@ -42,6 +43,7 @@ export function initialize( elementId: string ) { if ( ! container ) { return; } + initEventCollector(); createStore(); initializeLayout(); initBlocks(); diff --git a/packages/js/email-editor/src/events/event-collector.ts b/packages/js/email-editor/src/events/event-collector.ts new file mode 100644 index 0000000000..e83931476f --- /dev/null +++ b/packages/js/email-editor/src/events/event-collector.ts @@ -0,0 +1,16 @@ +import { doAction } from '@wordpress/hooks'; +import { EMAIL_STRING, dispatcher } from './event-pipeline'; + +const eventListenerHandler = ( eventData ) => { + doAction( 'mailpoet-email-editor-events', eventData.detail ); +}; + +const initEventCollector = () => { + dispatcher.addEventListener( EMAIL_STRING, eventListenerHandler ); +}; + +window.addEventListener( 'unload', function () { + dispatcher.removeEventListener( EMAIL_STRING, eventListenerHandler ); +} ); + +export { initEventCollector }; diff --git a/packages/js/email-editor/src/events/event-pipeline.ts b/packages/js/email-editor/src/events/event-pipeline.ts new file mode 100644 index 0000000000..ec8d730c04 --- /dev/null +++ b/packages/js/email-editor/src/events/event-pipeline.ts @@ -0,0 +1,18 @@ +const EMAIL_STRING = 'email-editor-events'; + +const dispatcher = new EventTarget(); + +const recordEvent = ( name: string, data = {} ) => { + const recordedData = typeof data !== 'object' ? { data } : data; + + const eventData = { + name: `${ EMAIL_STRING }_${ name }`, + ...recordedData, + }; + + dispatcher.dispatchEvent( + new CustomEvent( EMAIL_STRING, { detail: eventData } ) + ); +}; + +export { recordEvent, EMAIL_STRING, dispatcher }; diff --git a/packages/js/email-editor/src/events/index.ts b/packages/js/email-editor/src/events/index.ts new file mode 100644 index 0000000000..235df9b35e --- /dev/null +++ b/packages/js/email-editor/src/events/index.ts @@ -0,0 +1,2 @@ +export { recordEvent } from './event-pipeline'; +export * from './event-collector'; diff --git a/packages/js/email-editor/src/store/actions.ts b/packages/js/email-editor/src/store/actions.ts index 55ff4cc8af..5b569bfc7b 100644 --- a/packages/js/email-editor/src/store/actions.ts +++ b/packages/js/email-editor/src/store/actions.ts @@ -25,6 +25,7 @@ import { parse, } from '@wordpress/blocks'; import { decodeEntities } from '@wordpress/html-entities'; +import { recordEvent } from '../events'; export const toggleFeature = ( feature: Feature ) => @@ -65,19 +66,26 @@ export function updateSendPreviewEmail( toEmail: string ) { export const openSidebar = ( key = mainSidebarDocumentTab ) => - ( { registry } ): unknown => - registry + ( { registry } ): unknown => { + recordEvent( 'editor-sidebar-opened' ); + return registry .dispatch( interfaceStore ) .enableComplementaryArea( storeName, key ); + }; export const closeSidebar = () => - ( { registry } ): unknown => - registry + ( { registry } ): unknown => { + recordEvent( 'editor-sidebar-closed' ); + + return registry .dispatch( interfaceStore ) .disableComplementaryArea( storeName ); + }; export function toggleSettingsSidebarActiveTab( activeTab: string ) { + recordEvent( 'editor-settings-sidebar-active-tab', { activeTab } ); + return { type: 'TOGGLE_SETTINGS_SIDEBAR_ACTIVE_TAB', state: { activeTab } as Partial< State[ 'settingsSidebar' ] >, @@ -96,6 +104,7 @@ export function* saveEditedEmail() { ); result.then( () => { + recordEvent( 'editor-content-saved', { postId } ); void dispatch( noticesStore ).createErrorNotice( __( 'Email saved!', 'mailpoet' ), { @@ -107,6 +116,7 @@ export function* saveEditedEmail() { } ); result.catch( () => { + recordEvent( 'editor-content-not-saved', { postId } ); void dispatch( noticesStore ).createErrorNotice( __( 'The email could not be saved. Please, clear browser cache and reload the page. If the problem persists, duplicate the email and try again.', @@ -142,6 +152,7 @@ export function* updateEmailMailPoetProperty( name: string, value: string ) { }, } ); + recordEvent( 'updated-mailpoet-email-property', { postId } ); } export const setTemplateToPost = @@ -192,7 +203,9 @@ export function* requestSendingNewsletterPreview( isSendingPreviewEmail: false, }, }; + recordEvent( 'sent-preview-email', { postId, email } ); } catch ( errorResponse ) { + recordEvent( 'error-sent-preview-email', { email } ); yield { type: 'CHANGE_PREVIEW_STATE', state: {