Skip to content

Commit

Permalink
Track install and error events
Browse files Browse the repository at this point in the history
  • Loading branch information
bgrgicak committed Nov 4, 2024
1 parent 8f414d1 commit acea593
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 54 deletions.
73 changes: 40 additions & 33 deletions packages/playground/website/src/components/layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
setSiteManagerOpen,
} from '../../lib/state/redux/slice-ui';
import { ImportFormModal } from '../import-form/modal';
import { logErrorEvent } from '../../lib/tracking';

acquireOAuthTokenIfNeeded();

Expand All @@ -42,8 +43,8 @@ export const modalSlugs = {
START_ERROR: 'start-error',
IMPORT_FORM: 'import-form',
GITHUB_IMPORT: 'github-import',
GITHUB_EXPORT: 'github-export'
}
GITHUB_EXPORT: 'github-export',
};

const displayMode = getDisplayModeFromQuery();
function getDisplayModeFromQuery(): DisplayMode {
Expand Down Expand Up @@ -159,6 +160,8 @@ function Modals(blueprint: Blueprint) {
useEffect(() => {
addCrashListener(logger, (e) => {
const error = e as CustomEvent;
logErrorEvent(error.detail?.source);

if (error.detail?.source === 'php-wasm') {
dispatch(setActiveModal(modalSlugs.ERROR_REPORT));
}
Expand All @@ -179,39 +182,43 @@ function Modals(blueprint: Blueprint) {
} else if (currentModal === modalSlugs.IMPORT_FORM) {
return <ImportFormModal />;
} else if (currentModal === modalSlugs.GITHUB_IMPORT) {
return <GithubImportModal
onImported={({
url,
path,
files,
pluginOrThemeName,
contentType,
urlInformation: { owner, repo, type, pr },
}) => {
setGithubExportValues({
repoUrl: url,
prNumber: pr?.toString(),
toPathInRepo: path,
prAction: pr ? 'update' : 'create',
return (
<GithubImportModal
onImported={({
url,
path,
files,
pluginOrThemeName,
contentType,
plugin: pluginOrThemeName,
theme: pluginOrThemeName,
});
setGithubExportFiles(files);
}}
/>;
urlInformation: { owner, repo, type, pr },
}) => {
setGithubExportValues({
repoUrl: url,
prNumber: pr?.toString(),
toPathInRepo: path,
prAction: pr ? 'update' : 'create',
contentType,
plugin: pluginOrThemeName,
theme: pluginOrThemeName,
});
setGithubExportFiles(files);
}}
/>
);
} else if (currentModal === modalSlugs.GITHUB_EXPORT) {
return <GithubExportModal
allowZipExport={
(query.get('ghexport-allow-include-zip') ?? 'yes') === 'yes'
}
initialValues={githubExportValues}
initialFilesBeforeChanges={githubExportFiles}
onExported={(prUrl, formValues) => {
setGithubExportValues(formValues);
setGithubExportFiles(undefined);
}}
/>;
return (
<GithubExportModal
allowZipExport={
(query.get('ghexport-allow-include-zip') ?? 'yes') === 'yes'
}
initialValues={githubExportValues}
initialFilesBeforeChanges={githubExportFiles}
onExported={(prUrl, formValues) => {
setGithubExportValues(formValues);
setGithubExportFiles(undefined);
}}
/>
);
}

if (query.get('gh-ensure-auth') === 'yes') {
Expand Down
23 changes: 10 additions & 13 deletions packages/playground/website/src/lib/state/redux/boot-site-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ import {
removeClientInfo,
updateClientInfo,
} from './slice-clients';
import { logTrackingEvent } from '../../tracking';
import { Blueprint, StepDefinition } from '@wp-playground/blueprints';
import {
logBlueprintStepEvent,
logErrorEvent,
logTrackingEvent,
} from '../../tracking';
import { Blueprint } from '@wp-playground/blueprints';
import { logger } from '@php-wasm/logger';
import { setupPostMessageRelay } from '@php-wasm/web';
import { startPlaygroundWeb } from '@wp-playground/client';
Expand Down Expand Up @@ -100,17 +104,6 @@ export function bootSiteClient(
blueprint = site.metadata.runtimeConfiguration;
} else {
blueprint = site.metadata.originalBlueprint;
// Log the names of provided Blueprint's steps.
// Only the names (e.g. "runPhp" or "login") are logged. Step options like
// code, password, URLs are never sent anywhere.
const steps = (blueprint?.steps || [])
?.filter(
(step: any) => !!(typeof step === 'object' && step?.step)
)
.map((step) => (step as StepDefinition).step);
for (const step of steps) {
logTrackingEvent('step', { step });
}
}

let playground: PlaygroundClient;
Expand All @@ -125,6 +118,9 @@ export function bootSiteClient(
onClientConnected: (playground) => {
(window as any)['playground'] = playground;
},
onBlueprintStepCompleted: (result, step) => {
logBlueprintStepEvent(step);
},
mounts: mountDescriptor
? [
{
Expand Down Expand Up @@ -177,6 +173,7 @@ export function bootSiteClient(
}
} catch (e) {
logger.error(e);
logErrorEvent('boot');
dispatch(setActiveSiteError('site-boot-failed'));
dispatch(setActiveModal(modalSlugs.ERROR_REPORT));
return;
Expand Down
87 changes: 79 additions & 8 deletions packages/playground/website/src/lib/tracking.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,94 @@
import { StepDefinition } from '@wp-playground/blueprints';

/**
* Declare the global window.gtag function
*/
declare global {
interface Window { gtag: any; }
interface Window {
gtag: any;
}
}

/**
* Google Analytics event names
*/
type GAEvent = 'load' | 'step';
type GAEvent = 'load' | 'step' | 'install' | 'error';

/**
* Log a tracking event to Google Analytics
* @param GAEvent The event name
* @param Object Event data
*/
export const logTrackingEvent = (event: GAEvent, data?: {[key: string]: string}) => {
if (typeof window === 'undefined' || !window.gtag) {
return;
}
window.gtag('event', event, data);
}
export const logTrackingEvent = (
event: GAEvent,
data?: { [key: string]: string }
) => {
if (typeof window === 'undefined' || !window.gtag) {
return;
}
window.gtag('event', event, data);
};

/**
* Log Plugin install events
* @param step The Blueprint step
*/
export const logPluginInstallEvent = (step: StepDefinition) => {
const pluginData = (step as any).pluginData;
if (pluginData.slug) {
logTrackingEvent('install', {
plugin: pluginData.slug,
});
} else if (pluginData.url) {
logTrackingEvent('install', {
plugin: pluginData.url,
});
}
};

/**
* Log Theme install events
* @param step The Blueprint step
*/
export const logThemeInstallEvent = (step: StepDefinition) => {
const themeData = (step as any).themeData;
if (themeData.slug) {
logTrackingEvent('install', {
theme: themeData.slug,
});
} else if (themeData.url) {
logTrackingEvent('install', {
theme: themeData.url,
});
}
};

/**
* Log Blueprint step events
* @param step The Blueprint step
*/
export const logBlueprintStepEvent = (step: StepDefinition) => {
/**
* Log the names of provided Blueprint's steps.
* Only the names (e.g. "runPhp" or "login") are logged. Step options like
* code, password, URLs are never sent anywhere.
*/
logTrackingEvent('step', { step: step.step });

if (step.step === 'installPlugin') {
logPluginInstallEvent(step);
} else if (step.step === 'installTheme') {
logThemeInstallEvent(step);
}
};

/**
* Log error events
*
* @param error The error
*/
export const logErrorEvent = (source: string) => {
logTrackingEvent('error', {
source,
});
};

0 comments on commit acea593

Please sign in to comment.