From 33378024c4d1f8539d1c970664022e83b78b6d76 Mon Sep 17 00:00:00 2001 From: Xin00163 Date: Fri, 26 Aug 2022 11:28:29 +0100 Subject: [PATCH 1/4] feat(PPDSC-2322): add tealiumTrack to instrumentation --- .../component-api/component-api.tsx | 8 ++- site/pages/_app.tsx | 1 + site/pages/_document.tsx | 12 ++-- site/pages/components/tooltip.tsx | 1 + .../getting-started/code/instrumentation.tsx | 1 + .../instrumentation-provider.tsx | 1 + .../component-api-section.test.tsx.snap | 14 ++++- .../__tests__/tealium-track-no-window.test.ts | 18 ++++++ .../handlers/__tests__/tealium-track.test.ts | 57 +++++++++++++++++++ src/instrumentation/handlers/index.ts | 2 + src/instrumentation/handlers/tealium-track.ts | 23 ++++++++ src/tabs/types.ts | 3 +- 12 files changed, 130 insertions(+), 11 deletions(-) create mode 100644 src/instrumentation/handlers/__tests__/tealium-track-no-window.test.ts create mode 100644 src/instrumentation/handlers/__tests__/tealium-track.test.ts create mode 100644 src/instrumentation/handlers/tealium-track.ts diff --git a/site/components/component-api/component-api.tsx b/site/components/component-api/component-api.tsx index b7f65dd621..f0ee7665ee 100644 --- a/site/components/component-api/component-api.tsx +++ b/site/components/component-api/component-api.tsx @@ -109,7 +109,13 @@ export const ComponentAPI: React.FC = ({components}) => ( {tabs.length > 1 && ( {tabs.map(({label, tabSummary, content}) => ( - + {tabSummary && {tabSummary}} {content} diff --git a/site/pages/_app.tsx b/site/pages/_app.tsx index 0a796adeed..708fa5fd8f 100644 --- a/site/pages/_app.tsx +++ b/site/pages/_app.tsx @@ -122,6 +122,7 @@ export default class MyApp extends App { const handlers = [ instrumentationHandlers.createConsoleHandler(), instrumentationHandlers.createTealiumHandler(), + instrumentationHandlers.createTealiumTrackHandler(), ]; return ( diff --git a/site/pages/_document.tsx b/site/pages/_document.tsx index f61c07e66b..e44edd214a 100644 --- a/site/pages/_document.tsx +++ b/site/pages/_document.tsx @@ -246,13 +246,11 @@ export default class MyDocument extends Document { } `} /> - {isSiteEnvProduction && ( - - )} +
diff --git a/site/pages/components/tooltip.tsx b/site/pages/components/tooltip.tsx index 290a723d7b..482c821537 100644 --- a/site/pages/components/tooltip.tsx +++ b/site/pages/components/tooltip.tsx @@ -386,6 +386,7 @@ const TooltipComponent = (layoutProps: LayoutProps) => ( componentAPI={{ components: [ { + title: 'Tooltip', propsSummary: 'The Tooltip has a range of props that can be used to define an appropriate experience for different use cases.', overridesSummary: diff --git a/site/pages/getting-started/code/instrumentation.tsx b/site/pages/getting-started/code/instrumentation.tsx index ff2d800fff..adbc0124f5 100644 --- a/site/pages/getting-started/code/instrumentation.tsx +++ b/site/pages/getting-started/code/instrumentation.tsx @@ -203,6 +203,7 @@ const InstrumentationSetup = (layoutProps: LayoutProps) => ( const handlers = [ instrumentationHandlers.createConsoleHandler(), instrumentationHandlers.createTealiumHandler(), + instrumentationHandlers.createTealiumTrackHandler(), ]; const contextObject = { diff --git a/site/public/static/examples/instrumentation/instrumentation-provider.tsx b/site/public/static/examples/instrumentation/instrumentation-provider.tsx index 4d227c74aa..86a6bd1dcf 100644 --- a/site/public/static/examples/instrumentation/instrumentation-provider.tsx +++ b/site/public/static/examples/instrumentation/instrumentation-provider.tsx @@ -8,6 +8,7 @@ import { const handlers = [ instrumentationHandlers.createConsoleHandler(), instrumentationHandlers.createTealiumHandler(), + instrumentationHandlers.createTealiumTrackHandler(), ]; const contextObject = { diff --git a/site/templates/template-sections/__tests__/__snapshots__/component-api-section.test.tsx.snap b/site/templates/template-sections/__tests__/__snapshots__/component-api-section.test.tsx.snap index bb37cfdfb1..c0f056a77b 100644 --- a/site/templates/template-sections/__tests__/__snapshots__/component-api-section.test.tsx.snap +++ b/site/templates/template-sections/__tests__/__snapshots__/component-api-section.test.tsx.snap @@ -386,7 +386,12 @@ exports[`ComponentAPISection renders section as expected 1`] = ` \\"overrides\\": { \\"typographyPreset\\": \\"utilityButton020\\", \\"stylePreset\\": \\"componentPageTabs\\" - } + }, + \\"eventContext\\": { + \\"component\\": \\"Component\\", + \\"tabName\\": \\"Props\\" + }, + \\"eventOriginator\\": \\"component api\\" }" data-testid="Tab" > @@ -425,7 +430,12 @@ exports[`ComponentAPISection renders section as expected 1`] = ` \\"overrides\\": { \\"typographyPreset\\": \\"utilityButton020\\", \\"stylePreset\\": \\"componentPageTabs\\" - } + }, + \\"eventContext\\": { + \\"component\\": \\"Component\\", + \\"tabName\\": \\"Overrides\\" + }, + \\"eventOriginator\\": \\"component api\\" }" data-testid="Tab" > diff --git a/src/instrumentation/handlers/__tests__/tealium-track-no-window.test.ts b/src/instrumentation/handlers/__tests__/tealium-track-no-window.test.ts new file mode 100644 index 0000000000..59994f1507 --- /dev/null +++ b/src/instrumentation/handlers/__tests__/tealium-track-no-window.test.ts @@ -0,0 +1,18 @@ +/** + * @jest-environment node + */ +import {EventTrigger} from '../../types'; +import {sendEventTrackingToTealium} from '../tealium-track'; + +const mockEvent = { + originator: 'link', + trigger: EventTrigger.Click, + context: {some: 'object', prop: 'context'}, +}; + +describe('instrumentation event handler - tealiumTrack on server side (without extendedWindow)', () => { + test('returns null', () => { + const sendEventResult = sendEventTrackingToTealium(mockEvent); + expect(sendEventResult).toEqual(null); + }); +}); diff --git a/src/instrumentation/handlers/__tests__/tealium-track.test.ts b/src/instrumentation/handlers/__tests__/tealium-track.test.ts new file mode 100644 index 0000000000..114f605add --- /dev/null +++ b/src/instrumentation/handlers/__tests__/tealium-track.test.ts @@ -0,0 +1,57 @@ +import {EventTrigger} from '../../types'; +import createTealiumTrackHandler, {ExtendedWindow} from '../tealium-track'; + +const extendedWindow: ExtendedWindow = (window as Window) as ExtendedWindow; + +describe('instrumentation event handler - tealium track', () => { + const mockEvents = [ + { + originator: 'link', + trigger: EventTrigger.Click, + context: {some: 'object 1', prop1: 'context'}, + }, + { + originator: 'link', + trigger: EventTrigger.Swipe, + context: {context: 'object 2', prop1: 'context'}, + }, + { + originator: 'link', + trigger: EventTrigger.Load, + context: {some: 'object 2', prop1: 'context'}, + }, + ]; + + const events = [ + { + originator: 'link', + trigger: EventTrigger.Load, + context: {context: 'object 2', prop1: 'context'}, + }, + { + originator: 'link', + trigger: EventTrigger.Click, + context: {context: 'object 2', prop1: 'context'}, + }, + ]; + + beforeEach(() => { + (extendedWindow.tealiumTrack as any) = jest.fn(); + }); + + test('triggers an event', () => { + const handler = createTealiumTrackHandler(); + handler(events); + + expect(extendedWindow.tealiumTrack).toBeCalledWith(events[0]); + }); + + test('triggers each event', () => { + const handler = createTealiumTrackHandler(); + handler(mockEvents); + + expect(extendedWindow.tealiumTrack).nthCalledWith(1, mockEvents[0]); + expect(extendedWindow.tealiumTrack).nthCalledWith(2, mockEvents[1]); + expect(extendedWindow.tealiumTrack).toBeCalledWith(mockEvents[2]); + }); +}); diff --git a/src/instrumentation/handlers/index.ts b/src/instrumentation/handlers/index.ts index 3027de02d1..463c5a3734 100644 --- a/src/instrumentation/handlers/index.ts +++ b/src/instrumentation/handlers/index.ts @@ -1,7 +1,9 @@ import createConsoleHandler from './console'; import createTealiumHandler from './tealium'; +import createTealiumTrackHandler from './tealium-track'; export const instrumentationHandlers = { createConsoleHandler, createTealiumHandler, + createTealiumTrackHandler, }; diff --git a/src/instrumentation/handlers/tealium-track.ts b/src/instrumentation/handlers/tealium-track.ts new file mode 100644 index 0000000000..36f084f922 --- /dev/null +++ b/src/instrumentation/handlers/tealium-track.ts @@ -0,0 +1,23 @@ +import {EventHandler, InstrumentationEvent} from '../types'; + +export interface ExtendedWindow extends Window { + tealiumTrack(e: InstrumentationEvent): void; +} + +const extendedWindow: ExtendedWindow | null = + typeof window !== 'undefined' ? ((window as Window) as ExtendedWindow) : null; + +export function sendEventTrackingToTealium(e: InstrumentationEvent) { + if (extendedWindow) { + return extendedWindow.tealiumTrack(e); + } + return null; +} + +const createTealiumTrackHandler = (): EventHandler => events => + events.map(event => { + sendEventTrackingToTealium(event); + return event; + }); + +export default createTealiumTrackHandler; diff --git a/src/tabs/types.ts b/src/tabs/types.ts index 21b9df8bae..a898e2b66a 100644 --- a/src/tabs/types.ts +++ b/src/tabs/types.ts @@ -5,6 +5,7 @@ import {DividerOverrides} from '../divider'; import {ScrollProps} from '../scroll'; import {Override} from '../utils/overrides'; import {LogicalProps} from '../utils/logical-properties'; +import {EventData} from '../instrumentation'; export enum TabAlign { Start = 'start', @@ -116,6 +117,6 @@ export interface TabButtonProps extends CommonTabProps { align?: TabAlign; } -export interface TabProps extends CommonTabProps { +export interface TabProps extends CommonTabProps, EventData { label: React.ReactNode; } From 57f09c04298d69c1d214c35cf61cecf659780622 Mon Sep 17 00:00:00 2001 From: Xin00163 Date: Mon, 5 Sep 2022 14:06:05 +0100 Subject: [PATCH 2/4] fix(PPDSC-2322): address comments --- site/components/component-api/component-api.tsx | 7 +++++-- site/pages/components/divider.tsx | 1 + site/pages/components/drawer.tsx | 2 +- site/pages/components/fieldset.tsx | 1 + site/pages/components/modal.tsx | 1 + site/pages/components/popover.tsx | 1 + site/pages/components/visibility.tsx | 6 +++--- src/instrumentation/handlers/tealium-track.ts | 2 +- 8 files changed, 14 insertions(+), 7 deletions(-) diff --git a/site/components/component-api/component-api.tsx b/site/components/component-api/component-api.tsx index 766320d869..8cbc9e0c05 100644 --- a/site/components/component-api/component-api.tsx +++ b/site/components/component-api/component-api.tsx @@ -113,8 +113,11 @@ export const ComponentAPI: React.FC = ({components}) => ( label={label} overrides={tabOverrides} key={label} - eventContext={{component: title, tabName: label}} - eventOriginator="component api" + eventContext={{ + componentName: title, + tabName: label, + }} + eventOriginator="component api tabs" > {tabSummary && {tabSummary}} {content} diff --git a/site/pages/components/divider.tsx b/site/pages/components/divider.tsx index 257268fdd4..ee5fc08bd5 100644 --- a/site/pages/components/divider.tsx +++ b/site/pages/components/divider.tsx @@ -144,6 +144,7 @@ const DividerComponent = (layoutProps: LayoutProps) => ( componentAPI={{ components: [ { + title: 'Divider', propsSummary: 'The Divider has a prop that can be used to define an appropriate experience for different use cases.', overridesSummary: diff --git a/site/pages/components/drawer.tsx b/site/pages/components/drawer.tsx index e944664f1f..d05348c6ad 100644 --- a/site/pages/components/drawer.tsx +++ b/site/pages/components/drawer.tsx @@ -426,7 +426,7 @@ const DrawerComponent = (layoutProps: LayoutProps) => ( 'The Drawer has a range of props that can be used to define an appropriate experience for different use cases.', components: [ { - title: 'Props', + title: 'Drawer', summary: `The Drawer has a range of props that can be used to define an appropriate experience for different use cases.`, propsRows: [ { diff --git a/site/pages/components/fieldset.tsx b/site/pages/components/fieldset.tsx index 5186c9d493..90df97cb94 100644 --- a/site/pages/components/fieldset.tsx +++ b/site/pages/components/fieldset.tsx @@ -203,6 +203,7 @@ const FieldsetComponent = (layoutProps: LayoutProps) => ( componentAPI={{ components: [ { + title: 'Fieldset', propsSummary: 'The Fieldset has a range of props that can be used to define an appropriate experience for different use cases.', overridesSummary: diff --git a/site/pages/components/modal.tsx b/site/pages/components/modal.tsx index e9464c5abf..a0a9353475 100644 --- a/site/pages/components/modal.tsx +++ b/site/pages/components/modal.tsx @@ -469,6 +469,7 @@ const ModalComponent = (layoutProps: LayoutProps) => ( componentAPI={{ components: [ { + title: 'Modal', propsSummary: 'The Modal has a range of props that can be used to define an appropriate experience for different use cases.', overridesSummary: diff --git a/site/pages/components/popover.tsx b/site/pages/components/popover.tsx index 35f3de1284..b979728855 100644 --- a/site/pages/components/popover.tsx +++ b/site/pages/components/popover.tsx @@ -466,6 +466,7 @@ const PopoverComponent = (layoutProps: LayoutProps) => ( componentAPI={{ components: [ { + title: 'Popover', propsSummary: 'The Popover has a range of props that can be used to define an appropriate experience for different use cases.', overridesSummary: diff --git a/site/pages/components/visibility.tsx b/site/pages/components/visibility.tsx index 14f78a71f5..4841c359c8 100644 --- a/site/pages/components/visibility.tsx +++ b/site/pages/components/visibility.tsx @@ -178,7 +178,7 @@ const VisibilityComponent = (layoutProps: LayoutProps) => ( introduction="'Visible', 'Hidden' and 'ScreenReaderOnly' have a range of props that can be used to define an appropriate experience for different use cases." components={[ { - title: 'Visible Component Props', + title: 'Visible', summary: '‘Visible’ has a range of props that can be used to define an appropriate experience for different use cases.', propsRows: [ @@ -238,7 +238,7 @@ const VisibilityComponent = (layoutProps: LayoutProps) => ( ], }, { - title: 'Hidden Component Props', + title: 'Hidden', summary: '‘Hidden’ has a range of props that can be used to define an appropriate experience for different use cases.', propsRows: [ @@ -298,7 +298,7 @@ const VisibilityComponent = (layoutProps: LayoutProps) => ( ], }, { - title: 'ScreenReaderOnly Component Props', + title: 'ScreenReaderOnly', summary: '‘ScreenReaderOnly’ has a range of props that can be used to define an appropriate experience for different use cases.', propsRows: [ diff --git a/src/instrumentation/handlers/tealium-track.ts b/src/instrumentation/handlers/tealium-track.ts index 36f084f922..d8ebd33765 100644 --- a/src/instrumentation/handlers/tealium-track.ts +++ b/src/instrumentation/handlers/tealium-track.ts @@ -8,7 +8,7 @@ const extendedWindow: ExtendedWindow | null = typeof window !== 'undefined' ? ((window as Window) as ExtendedWindow) : null; export function sendEventTrackingToTealium(e: InstrumentationEvent) { - if (extendedWindow) { + if (extendedWindow && extendedWindow.tealiumTrack) { return extendedWindow.tealiumTrack(e); } return null; From e6e534e4b7bb84b118ec733fb982a0ba8102377a Mon Sep 17 00:00:00 2001 From: Xin00163 Date: Tue, 6 Sep 2022 09:22:16 +0100 Subject: [PATCH 3/4] fix(PPDSC-2322): data team comments --- .../__snapshots__/component-api.test.tsx.snap | 159 +++++++++++++----- .../__tests__/component-api.test.tsx | 1 + .../component-api/component-api.tsx | 4 +- site/components/component-api/types.ts | 2 +- site/pages/_document.tsx | 12 +- .../component-api-section.test.tsx.snap | 8 +- 6 files changed, 129 insertions(+), 57 deletions(-) diff --git a/site/components/component-api/__tests__/__snapshots__/component-api.test.tsx.snap b/site/components/component-api/__tests__/__snapshots__/component-api.test.tsx.snap index eb42e4439d..7e803feb55 100644 --- a/site/components/component-api/__tests__/__snapshots__/component-api.test.tsx.snap +++ b/site/components/component-api/__tests__/__snapshots__/component-api.test.tsx.snap @@ -49,16 +49,76 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = ` } .emotion-2 { - overflow-x: auto; + margin-bottom: 40px; } .emotion-3 { + margin: 0; + color: #09111C; + display: inline-block; +} + +.emotion-3 svg { + fill: #09111C; +} + +@media screen and (max-width: 1439px) { + .emotion-3 { + font-family: "Poppins",sans-serif; + font-size: 20px; + line-height: 22.5px; + font-weight: 700; + letter-spacing: 0; + padding: 0.5px 0px; + } + + .emotion-3::before { + content: ''; + margin-bottom: -0.2155em; + display: block; + } + + .emotion-3::after { + content: ''; + margin-top: -0.2125em; + display: block; + } +} + +@media screen and (min-width: 1440px) { + .emotion-3 { + font-family: "Poppins",sans-serif; + font-size: 24px; + line-height: 27px; + font-weight: 700; + letter-spacing: 0; + padding: 0.5px 0px; + } + + .emotion-3::before { + content: ''; + margin-bottom: -0.2155em; + display: block; + } + + .emotion-3::after { + content: ''; + margin-top: -0.2125em; + display: block; + } +} + +.emotion-4 { + overflow-x: auto; +} + +.emotion-5 { border-collapse: collapse; border-spacing: 0; width: 100%; } -.emotion-4 { +.emotion-6 { border-style: solid; border-color: #C0C7CC; border-width: 0 0 1px 0; @@ -77,7 +137,7 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = ` padding-bottom: 16px; } -.emotion-5 { +.emotion-7 { border-style: solid; border-color: #C0C7CC; border-width: 0 0 1px 0; @@ -96,7 +156,7 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = ` padding-bottom: 16px; } -.emotion-8 { +.emotion-10 { border-style: solid; border-color: #C0C7CC; border-width: 0 0 1px 0; @@ -115,7 +175,7 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = ` padding-bottom: 16px; } -.emotion-9 { +.emotion-11 { border-style: solid; border-color: #DEE2E5; border-width: 0 0 1px 0; @@ -128,20 +188,20 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = ` border-width: 0; } -.emotion-10 { +.emotion-12 { padding: 16px 16px 16px 0; text-align: left; vertical-align: top; } -.emotion-11 { +.emotion-13 { padding: 16px 16px 16px 0; min-width: 100px; text-align: left; vertical-align: top; } -.emotion-12 { +.emotion-14 { box-sizing: border-box; display: -webkit-inline-box; display: -webkit-inline-flex; @@ -172,16 +232,16 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = ` white-space: nowrap; } -.emotion-12 svg { +.emotion-14 svg { width: 16px; height: 16px; } -.emotion-12 svg { +.emotion-14 svg { fill: #2E3F54; } -.emotion-13 { +.emotion-15 { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; @@ -202,7 +262,7 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = ` margin-right: calc(-4px/2); } -.emotion-14 { +.emotion-16 { display: -webkit-inline-box; display: -webkit-inline-flex; display: -ms-inline-flexbox; @@ -211,7 +271,7 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = ` margin-right: calc(4px/2); } -.emotion-15 { +.emotion-17 { margin: 0; font-family: 'DM Mono',courier; font-size: 14px; @@ -221,7 +281,7 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = ` display: inline-block; } -.emotion-15::before { +.emotion-17::before { content: ''; display: block; height: 0; @@ -229,7 +289,7 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = ` margin-bottom: -0.4267857142857143em; } -.emotion-15::after { +.emotion-17::after { content: ''; display: block; height: 0; @@ -237,7 +297,7 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = ` margin-top: -0.3642857142857143em; } -.emotion-18 { +.emotion-20 { padding: 16px 16px 16px 0; max-width: 100px; text-align: left; @@ -245,7 +305,7 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = ` overflow: hidden; } -.emotion-19 { +.emotion-21 { box-sizing: border-box; display: -webkit-inline-box; display: -webkit-inline-flex; @@ -278,16 +338,16 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = ` border-width: 1px; } -.emotion-19 svg { +.emotion-21 svg { width: 16px; height: 16px; } -.emotion-19 svg { +.emotion-21 svg { fill: #007B22; } -.emotion-22 { +.emotion-24 { display: inline-block; vertical-align: middle; overflow: hidden; @@ -297,7 +357,7 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = ` } @media screen and (prefers-reduced-motion: no-preference) { - .emotion-22 { + .emotion-24 { transition-property: fill; transition-duration: 200ms; transition-timing-function: cubic-bezier(0, 0, .5, 1); @@ -305,19 +365,19 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = ` } @media screen and (prefers-reduced-motion: reduce) { - .emotion-22 { + .emotion-24 { transition-property: fill; transition-duration: 0ms; transition-timing-function: cubic-bezier(0, 0, .5, 1); } } -.emotion-22.emotion-22 { +.emotion-24.emotion-24 { fill: #007B22; } @media screen and (prefers-reduced-motion: no-preference) { - .emotion-22.emotion-22 { + .emotion-24.emotion-24 { transition-property: fill; transition-duration: 200ms; transition-timing-function: cubic-bezier(0, 0, .5, 1); @@ -325,7 +385,7 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = ` } @media screen and (prefers-reduced-motion: reduce) { - .emotion-22.emotion-22 { + .emotion-24.emotion-24 { transition-property: fill; transition-duration: 0ms; transition-timing-function: cubic-bezier(0, 0, .5, 1); @@ -341,33 +401,42 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = `
- + component + + +
+
@@ -375,28 +444,28 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = `
Name Type Default Description Required
children string @@ -405,29 +474,29 @@ exports[`ComponentAPI renders with mandatory props for one component 1`] = ` Description.