Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BD-46] refactor: segment events refactoring #2840

Merged
43 changes: 43 additions & 0 deletions www/segment-events/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* Events are identified by the following structured pattern:
* openedx.paragon.event_environment.event_name.event_action
*/

export const ICON_COPIED_EVENT = 'openedx.paragon.docs.icons-table.selected-icon.copied';
export const LEAVE_FEEDBACK_CLICKED_EVENT = 'openedx.paragon.docs.leave-feedback.clicked';
export const CONTRAST_CHECKER_CLICKED_EVENT = 'openedx.paragon.docs.menu.tools.visit-contrast-checker.clicked';
export const PAGE_EDIT_BTN_CLICKED_EVENT = 'openedx.paragon.docs.page-edit.clicked';

export const PLAYGROUND_EVENTS = {
LINK_CLICKED: 'openedx.paragon.docs.menu.playground.visit-playground.clicked',
URL_COPIED: 'openedx.paragon.docs.playground.copy-url.copied',
};

export const SHADOW_GENERATOR_LAYER_EVENTS = {
ENABLED: 'openedx.paragon.docs.elevation.shadow-generator.layer.enabled',
DISABLED: 'openedx.paragon.docs.elevation.shadow-generator.layer.disabled',
REMOVED: 'openedx.paragon.docs.elevation.shadow-generator.layer.removed',
ADDED: 'openedx.paragon.docs.elevation.shadow-generator.layer.added',
UPDATED: 'openedx.paragon.docs.elevation.shadow-generator.layer.updated',
};

export const SETTINGS_EVENTS = {
OPENED: 'openedx.paragon.docs.settings.opened',
CLOSED: 'openedx.paragon.docs.settings.closed',
CHANGED: 'openedx.paragon.docs.setting.changed',
};

export const EXAMPLE_CODE_BLOCK_WITH_HEADING_EVENTS = {
CLOSED: 'openedx.paragon.docs.example-code-block.closed',
OPENED: 'openedx.paragon.docs.example-code-block.opened',
};

export const EXAMPLE_CODE_BLOCK_WITHOUT_HEADING_EVENTS = {
CLOSED: 'openedx.paragon.docs.example-code-block.without-heading.closed',
OPENED: 'openedx.paragon.docs.example-code-block.without-heading.opened',
};

export const USAGE_INSIGHTS_EVENTS = {
TAB_CLICKED: 'openedx.paragon.docs.usage-insights.tab.clicked',
COMPONENT_LINK_CLICKED: 'openedx.paragon.docs.usage-insights.component-usage-link.clicked',
};
3 changes: 3 additions & 0 deletions www/segment-events/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './constants';

export { sendUserAnalyticsEvent } from './utils';
8 changes: 8 additions & 0 deletions www/segment-events/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
function sendUserAnalyticsEvent(eventName, context) {
if (context) {
return global.analytics.track(eventName, context);
}
return global.analytics.track(eventName);
}

module.exports = { sendUserAnalyticsEvent };
20 changes: 14 additions & 6 deletions www/src/components/CodeBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ import { FormattedMessage, useIntl } from 'react-intl';
import * as ParagonReact from '~paragon-react';
import * as ParagonIcons from '~paragon-icons';
import { ContentCopy } from '~paragon-icons';
import {
EXAMPLE_CODE_BLOCK_WITH_HEADING_EVENTS,
EXAMPLE_CODE_BLOCK_WITHOUT_HEADING_EVENTS,
sendUserAnalyticsEvent,
} from '../../segment-events';
import MiyazakiCard from './exampleComponents/MiyazakiCard';
import HipsterIpsum from './exampleComponents/HipsterIpsum';
import ExamplePropsForm from './exampleComponents/ExamplePropsForm';
Expand Down Expand Up @@ -64,16 +69,19 @@ function CollapsibleLiveEditor({ children, clickToCopy, handleCodeChange }: Coll
const headingElement = getCodeBlockHeading(e.target);

if (!headingElement) {
global.analytics.track(`openedx.paragon.docs.ui.example-code-block.${collapseIsOpen ? 'closed' : 'opened'}`, {
value: `${componentNameAndCategory}id-not-generated`,
});
const event = collapseIsOpen
? EXAMPLE_CODE_BLOCK_WITHOUT_HEADING_EVENTS.CLOSED
: EXAMPLE_CODE_BLOCK_WITHOUT_HEADING_EVENTS.OPENED;

sendUserAnalyticsEvent(event, { value: `${componentNameAndCategory}id-not-generated` });
return;
}

global.analytics.track(`openedx.paragon.docs.ui.example-code-block.${collapseIsOpen ? 'closed' : 'opened'}`, {
value: `${componentNameAndCategory}${headingElement.id}`,
});
const event = collapseIsOpen
? EXAMPLE_CODE_BLOCK_WITH_HEADING_EVENTS.CLOSED
: EXAMPLE_CODE_BLOCK_WITH_HEADING_EVENTS.OPENED;

sendUserAnalyticsEvent(event, { value: `${componentNameAndCategory}${headingElement.id}` });
};

return (
Expand Down
3 changes: 2 additions & 1 deletion www/src/components/IconsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import debounce from 'lodash.debounce';
import { Icon, SearchField, Toast } from '~paragon-react';
import * as IconComponents from '~paragon-icons';
import { ICON_COPIED_EVENT, sendUserAnalyticsEvent } from '../../segment-events';

const WINDOW_HEIGHT = 2400;
const ROW_HEIGHT = 100;
Expand Down Expand Up @@ -75,7 +76,7 @@ function IconsTable({ iconNames }) {
const copyToClipboard = (content) => {
navigator.clipboard.writeText(content);
setShowToast(true);
global.analytics.track('openedx.paragon.docs.icons-table.selected-icon.copied', { name: currentIcon });
sendUserAnalyticsEvent(ICON_COPIED_EVENT, { name: currentIcon });
};

const handleChangeSearchValue = useMemo(() => debounce(setSearchValue, 500, { leading: false }), []);
Expand Down
5 changes: 2 additions & 3 deletions www/src/components/LeaveFeedback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { AnchorHTMLAttributes } from 'react';
import PropTypes from 'prop-types';
import { Nav, Button, Hyperlink } from '~paragon-react';
import { useLocation } from '@reach/router';
import { LEAVE_FEEDBACK_CLICKED_EVENT, sendUserAnalyticsEvent } from '../../segment-events';

export interface LeaveFeedbackProps extends Partial<AnchorHTMLAttributes<HTMLAnchorElement>> {
isNavLink?: boolean;
Expand All @@ -12,9 +13,7 @@ function LeaveFeedback({ isNavLink, ...props }: LeaveFeedbackProps) {
const FEEDBACK_URL = `https://github.com/openedx/paragon/issues/new?title=%5Bparagon-openedx.netlify.app%5D%20Feedback%20(on%20${location.pathname})&amp;labels=docs&template=feedback_template.md`;
const leaveFeedbackLinkTitle = 'Leave feedback';

const handleLinkFeedbackClick = () => {
global.analytics.track('openedx.paragon.docs.leave_feedback.clicked');
};
const handleLinkFeedbackClick = () => sendUserAnalyticsEvent(LEAVE_FEEDBACK_CLICKED_EVENT);

if (isNavLink) {
return (
Expand Down
9 changes: 3 additions & 6 deletions www/src/components/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import classNames from 'classnames';
import Search from './Search';
import { SettingsContext } from '../context/SettingsContext';
import { THEMES } from '../../theme-config';
import { PLAYGROUND_EVENTS, sendUserAnalyticsEvent, CONTRAST_CHECKER_CLICKED_EVENT } from '../../segment-events';
import { FOUNDATION_PAGES } from '../config';

// MDX transforms markdown generated by gatsby-transformer-react-docgen
Expand Down Expand Up @@ -145,13 +146,9 @@ function MenuComponentListCategory({ children, title }: IMenuComponentListCatego
);
}

const handlePlaygroundClick = () => {
global.analytics.track('openedx.paragon.docs.menu.playground.visit_playground.clicked');
};
const handlePlaygroundClick = () => sendUserAnalyticsEvent(PLAYGROUND_EVENTS.LINK_CLICKED);

const handleContrastCheckerClick = () => {
global.analytics.track('openedx.paragon.docs.menu.tools.visit_contrast_checker.clicked');
};
const handleContrastCheckerClick = () => sendUserAnalyticsEvent(CONTRAST_CHECKER_CLICKED_EVENT);

MenuComponentListCategory.propTypes = {
children: PropTypes.node.isRequired,
Expand Down
5 changes: 2 additions & 3 deletions www/src/components/PageEditBtn/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { AnchorHTMLAttributes } from 'react';
import PropTypes from 'prop-types';
import { Button, Hyperlink, Nav } from '~paragon-react';
import { PAGE_EDIT_BTN_CLICKED_EVENT, sendUserAnalyticsEvent } from '../../../segment-events';

export interface PageEditBtnProps extends Partial<AnchorHTMLAttributes<HTMLAnchorElement>> {
githubEditPath?: string,
Expand All @@ -10,9 +11,7 @@ export interface PageEditBtnProps extends Partial<AnchorHTMLAttributes<HTMLAncho
function PageEditBtn({ githubEditPath, isNavLink, ...props }: PageEditBtnProps) {
const pageEditLinkTitle = 'Edit this page';

const handlePageEditBtnClick = () => {
global.analytics.track('openedx.paragon.docs.page_edit.clicked');
};
const handlePageEditBtnClick = () => sendUserAnalyticsEvent(PAGE_EDIT_BTN_CLICKED_EVENT);

if (isNavLink) {
return (
Expand Down
8 changes: 4 additions & 4 deletions www/src/components/insights/UsagesList.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Hyperlink } from '~paragon-react';
import { USAGE_INSIGHTS_EVENTS, sendUserAnalyticsEvent } from '../../../segment-events';

type UsagesType = {
filePath: string,
Expand All @@ -21,10 +22,9 @@ export default function UsagesList({
projectName,
} : UsagesListPropTypes) {
const handleUsageLinkClick = (linkToUsage) => {
global.analytics.track(
'openedx.paragon.docs.usage-insights.component-usage-link.clicked',
{ project: projectName, component: componentName, linkToUsage },
);
sendUserAnalyticsEvent(USAGE_INSIGHTS_EVENTS.COMPONENT_LINK_CLICKED, {
project: projectName, component: componentName, linkToUsage,
});
};

return (
Expand Down
9 changes: 7 additions & 2 deletions www/src/context/SettingsContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { IntlProvider } from 'react-intl';
import { messages } from '~paragon-react';

import { THEMES, DEFAULT_THEME } from '../../theme-config';
import { SETTINGS_EVENTS, sendUserAnalyticsEvent } from '../../segment-events';

export interface IDefaultValue {
settings: {
Expand Down Expand Up @@ -44,12 +45,16 @@ function SettingsContextProvider({ children }) {
}
setSettings(prevState => ({ ...prevState, [key]: value }));
global.localStorage.setItem('pgn__settings', JSON.stringify({ ...settings, [key]: value }));
global.analytics.track(`openedx.paragon.docs.settings.${key}.changed`, { [key]: value });
sendUserAnalyticsEvent(SETTINGS_EVENTS.CHANGED, { [key]: value });
PKulkoRaccoonGang marked this conversation as resolved.
Show resolved Hide resolved
};

const toggleSettings = (value: boolean) => {
const event = value
? SETTINGS_EVENTS.OPENED
: SETTINGS_EVENTS.CLOSED;

setShowSettings(value);
global.analytics.track(`openedx.paragon.docs.settings.${value ? 'opened' : 'closed'}`);
sendUserAnalyticsEvent(event);
};

// this hook will be called after the first render, so we can safely access localStorage
Expand Down
11 changes: 6 additions & 5 deletions www/src/pages/foundations/elevation.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Close, WbSunny, DoDisturb } from '~paragon-icons';
import SEO from '../../components/SEO';
import Layout from '../../components/PageLayout';
import { SettingsContext } from '../../context/SettingsContext';
import { sendUserAnalyticsEvent, SHADOW_GENERATOR_LAYER_EVENTS } from '../../../segment-events';

const boxShadowSides = ['down', 'up', 'right', 'left', 'centered'];
const boxShadowLevels = [1, 2, 3, 4, 5];
Expand Down Expand Up @@ -86,7 +87,7 @@ function BoxShadowToolkit({
});

const updateBoxShadowModel = (property, value) => {
global.analytics.track('openedx.paragon.docs.elevation.generator.updated', { property, value });
sendUserAnalyticsEvent(SHADOW_GENERATOR_LAYER_EVENTS.UPDATED, { property, value });

const newBoxShadowModel = {
...boxShadowModel,
Expand Down Expand Up @@ -196,20 +197,20 @@ function BoxShadowGenerator() {
};

const addNewBoxShadowLayer = () => {
global.analytics.track('openedx.paragon.elevation.generator.layer.added');
sendUserAnalyticsEvent(SHADOW_GENERATOR_LAYER_EVENTS.ADDED);
setBoxShadows([
...boxShadows,
{ id: boxShadows[boxShadows.length - 1].id + 1, enabled: true, style: DEFAULT_BOX_SHADOW },
]);
};

const removeBoxShadowLayer = (toolkitId) => {
global.analytics.track('openedx.paragon.elevation.shadow-generator.layer.removed');
sendUserAnalyticsEvent(SHADOW_GENERATOR_LAYER_EVENTS.REMOVED);
setBoxShadows(boxShadows.filter((shadow) => shadow.id !== toolkitId));
};

const disableBoxShadowLayer = (toolkitId) => {
global.analytics.track('openedx.paragon.elevation.shadow-generator.layer.disabled');
sendUserAnalyticsEvent(SHADOW_GENERATOR_LAYER_EVENTS.DISABLED);
const updatedBoxShadows = boxShadows
.map((shadow) => {
if (shadow.id === toolkitId) {
Expand All @@ -221,7 +222,7 @@ function BoxShadowGenerator() {
};

const enableBoxShadowLayer = (toolkitId) => {
global.analytics.track('openedx.paragon.elevation.shadow-generator.layer.enabled');
sendUserAnalyticsEvent(SHADOW_GENERATOR_LAYER_EVENTS.ENABLED);
const updatedBoxShadows = boxShadows
.map((shadow) => {
if (shadow.id === toolkitId) {
Expand Down
3 changes: 2 additions & 1 deletion www/src/pages/insights.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import ComponentsUsage from '../components/insights/ComponentsUsage';

// @ts-ignore
import dependentProjectsAnalysis from '../../../dependent-usage.json'; // eslint-disable-line
import { sendUserAnalyticsEvent, USAGE_INSIGHTS_EVENTS } from '../../segment-events';
import { INSIGHTS_TABS, INSIGHTS_PAGES } from '../config';
import componentsUsage from '../utils/componentsUsage';
import { IInsightsContext } from '../types/types';
Expand Down Expand Up @@ -63,7 +64,7 @@ export default function InsightsPage({ pageContext: { tab, githubEditPath } }: I

const handleOnSelect = (value: string) => {
if (value !== tab) {
global.analytics.track(`openedx.paragon.docs.insights.tabs.${value.toLowerCase().trim()}.clicked`);
sendUserAnalyticsEvent(USAGE_INSIGHTS_EVENTS.TAB_CLICKED, { tabName: value });
navigate(INSIGHTS_PAGES.find(item => item.tab === value).path);
}
};
Expand Down
3 changes: 2 additions & 1 deletion www/src/pages/playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import localforage from 'localforage';
import SEO from '../components/SEO';
import { SiteTitle } from '../components/header';
import { storageKey } from '../../playroom/constants';
import { PLAYGROUND_EVENTS, sendUserAnalyticsEvent } from '../../segment-events';

const FEEDBACK_URL = 'https://github.com/openedx/paragon/issues/new?assignees=&labels=playground&template=feedback_template.md&title=[Playground]';

Expand Down Expand Up @@ -73,7 +74,7 @@ export default function Playground({ location }) {
onClick={() => {
setCopyUrlState('copied');
navigator.clipboard.writeText(location.href);
global.analytics.track('openedx.paragon.docs.playground.url-copied');
sendUserAnalyticsEvent(PLAYGROUND_EVENTS.URL_COPIED);
}}
labels={{
default: 'Copy URL',
Expand Down