@salesforcedevs/dx-components 1.3.53 → 1.3.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/modules/dx/cardBlogPost/cardBlogPost.html +1 -0
- package/src/modules/dx/cardBlogPost/cardBlogPost.ts +17 -0
- package/src/modules/dx/cardCallout/cardCallout.ts +7 -0
- package/src/modules/dx/cardContent/cardContent.html +2 -0
- package/src/modules/dx/cardContent/cardContent.ts +7 -0
- package/src/modules/dx/cardDocs/cardDocs.html +6 -2
- package/src/modules/dx/cardDocs/cardDocs.ts +47 -0
- package/src/modules/dx/cardNews/cardNews.ts +1 -0
- package/src/modules/dx/cardTrial/cardTrial.ts +5 -3
- package/src/modules/dx/cardTrialExpanded/cardTrialExpanded.ts +5 -3
- package/src/modules/dx/codeBlock/codeBlock.ts +19 -4
- package/src/modules/dx/dropdown/dropdown.html +2 -4
- package/src/modules/dx/dropdown/dropdown.ts +2 -7
- package/src/modules/dx/dropdownOption/dropdownOption.ts +11 -21
- package/src/modules/dx/feature/feature.html +1 -0
- package/src/modules/dx/feature/feature.ts +13 -0
- package/src/modules/dx/featuredContentHeader/featuredContentHeader.ts +115 -1
- package/src/modules/dx/footer/footer.ts +5 -9
- package/src/modules/dx/footerOption/footerOption.ts +12 -4
- package/src/modules/dx/groupText/groupText.ts +8 -14
- package/src/modules/dx/headerMobileNavMenuOption/headerMobileNavMenuOption.ts +8 -0
- package/src/modules/dx/headerNav/headerNav.html +1 -0
- package/src/modules/dx/headerNav/headerNav.ts +4 -0
- package/src/modules/dx/mainContentHeader/mainContentHeader.ts +12 -6
- package/src/modules/dx/pagination/pagination.ts +5 -10
- package/src/modules/dx/searchResults/searchResults.ts +11 -0
- package/src/modules/dx/tab/tab.ts +14 -3
- package/src/modules/dx/toc/toc.ts +24 -7
- package/src/modules/dx/treeItem/treeItem.ts +14 -5
- package/src/modules/dxBaseElements/headerBase/headerBase.ts +8 -6
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LightningElement, api } from "lwc";
|
|
2
|
+
import { track } from "dxUtils/analytics";
|
|
2
3
|
|
|
3
4
|
export default class CardBlogPost extends LightningElement {
|
|
4
5
|
@api body!: string;
|
|
@@ -18,4 +19,20 @@ export default class CardBlogPost extends LightningElement {
|
|
|
18
19
|
private get _datetime() {
|
|
19
20
|
return this.datetime || this.dateTime;
|
|
20
21
|
}
|
|
22
|
+
|
|
23
|
+
private onLinkClick(event: Event) {
|
|
24
|
+
const payload = {
|
|
25
|
+
click_text: this.title,
|
|
26
|
+
click_url: this.href,
|
|
27
|
+
element_title: "dx-card-blog-post",
|
|
28
|
+
element_type: "card",
|
|
29
|
+
content_category: "link"
|
|
30
|
+
};
|
|
31
|
+
track(event.target!, "custEv_blogCardClick", {
|
|
32
|
+
...payload,
|
|
33
|
+
blog_author: this.authors,
|
|
34
|
+
blog_title: this.title
|
|
35
|
+
});
|
|
36
|
+
track(event.target!, "custEv_linkClick", payload);
|
|
37
|
+
}
|
|
21
38
|
}
|
|
@@ -37,5 +37,12 @@ export default class CardCallout extends LightningElement {
|
|
|
37
37
|
elementType: "card callout",
|
|
38
38
|
destinationType: "internal"
|
|
39
39
|
});
|
|
40
|
+
track(e.currentTarget!, "custEv_linkClick", {
|
|
41
|
+
click_text: this.title,
|
|
42
|
+
click_url: this.href,
|
|
43
|
+
element_title: "dx-card-callout",
|
|
44
|
+
element_type: "card",
|
|
45
|
+
content_category: "link"
|
|
46
|
+
});
|
|
40
47
|
}
|
|
41
48
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
<a
|
|
4
4
|
if:true={hasImage}
|
|
5
5
|
href={href}
|
|
6
|
+
onclick={handleClick}
|
|
6
7
|
onmouseenter={setLinkHovered}
|
|
7
8
|
onmouseleave={setLinkInactive}
|
|
8
9
|
target={target}
|
|
@@ -31,6 +32,7 @@
|
|
|
31
32
|
<dx-card-title
|
|
32
33
|
href={href}
|
|
33
34
|
target={target}
|
|
35
|
+
onclick={handleClick}
|
|
34
36
|
onmouseenter={setLinkHovered}
|
|
35
37
|
onmouseleave={setLinkInactive}
|
|
36
38
|
title={title}
|
|
@@ -18,6 +18,7 @@ export default class CardContent extends LightningElement {
|
|
|
18
18
|
@api subtitle?: string | null = null;
|
|
19
19
|
@api target?: string | null = null;
|
|
20
20
|
@api title!: string;
|
|
21
|
+
@api hrefClick: any = null;
|
|
21
22
|
@api
|
|
22
23
|
get authors() {
|
|
23
24
|
if (this._authors && this._authors.length) {
|
|
@@ -80,4 +81,10 @@ export default class CardContent extends LightningElement {
|
|
|
80
81
|
private onDatetimeSlotChange(e: LightningSlotElement): void {
|
|
81
82
|
this.isDatetimeEmpty = isSlotEmpty(e);
|
|
82
83
|
}
|
|
84
|
+
|
|
85
|
+
private handleClick(e: Event) {
|
|
86
|
+
if (this.hrefClick) {
|
|
87
|
+
this.hrefClick(e);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
83
90
|
}
|
|
@@ -13,8 +13,12 @@
|
|
|
13
13
|
"
|
|
14
14
|
>
|
|
15
15
|
<span class="dx-text-label-3">{label}</span>
|
|
16
|
-
<dx-card-title
|
|
17
|
-
|
|
16
|
+
<dx-card-title
|
|
17
|
+
title={title}
|
|
18
|
+
target={target}
|
|
19
|
+
onclick={handleLinkClick}
|
|
20
|
+
></dx-card-title>
|
|
21
|
+
<span class="dx-text-body-2" onclick={handleTextClick}>{body}</span>
|
|
18
22
|
</div>
|
|
19
23
|
<div class="dx-card-base_section-vertical dx-card-base_ctas">
|
|
20
24
|
<slot onslotchange={onSlotChange}></slot>
|
|
@@ -2,6 +2,7 @@ import { LightningElement, api } from "lwc";
|
|
|
2
2
|
import cx from "classnames";
|
|
3
3
|
import { LightningSlotElement } from "typings/custom";
|
|
4
4
|
import { stopPropagationOnSlotted } from "dxUtils/slot";
|
|
5
|
+
import { track } from "dxUtils/analytics";
|
|
5
6
|
|
|
6
7
|
export default class CardDocs extends LightningElement {
|
|
7
8
|
@api body!: string;
|
|
@@ -25,6 +26,52 @@ export default class CardDocs extends LightningElement {
|
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
private onSlotChange(e: LightningSlotElement) {
|
|
29
|
+
const payloadInnerButton = {
|
|
30
|
+
element_title: "dx-button",
|
|
31
|
+
element_type: "link",
|
|
32
|
+
content_category: "card"
|
|
33
|
+
};
|
|
34
|
+
// @ts-ignore
|
|
35
|
+
const slot = e.target;
|
|
36
|
+
const elements = slot.assignedElements();
|
|
37
|
+
elements.forEach((slotElement) => {
|
|
38
|
+
slotElement?.addEventListener("click", (event: Event) => {
|
|
39
|
+
track(event.currentTarget!, "custEv_cardClick", {
|
|
40
|
+
...payloadInnerButton,
|
|
41
|
+
click_text: slotElement.innerText,
|
|
42
|
+
click_url: slotElement.href
|
|
43
|
+
});
|
|
44
|
+
track(event.currentTarget!, "custEv_linkClick", {
|
|
45
|
+
...payloadInnerButton,
|
|
46
|
+
click_text: slotElement.innerText,
|
|
47
|
+
click_url: slotElement.href
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
});
|
|
28
51
|
stopPropagationOnSlotted(e);
|
|
29
52
|
}
|
|
53
|
+
|
|
54
|
+
private handleLinkClick(event: PointerEvent) {
|
|
55
|
+
const paylodCardInfo = {
|
|
56
|
+
click_text: this.title,
|
|
57
|
+
element_title: "dx-card-title",
|
|
58
|
+
click_url: this.href,
|
|
59
|
+
element_type: "link",
|
|
60
|
+
content_category: "cta"
|
|
61
|
+
};
|
|
62
|
+
track(event.currentTarget!, "custEv_cardClick", paylodCardInfo);
|
|
63
|
+
track(event.currentTarget!, "custEv_linkClick", paylodCardInfo);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private handleTextClick(event: PointerEvent) {
|
|
67
|
+
const payloadCardTextInfo = {
|
|
68
|
+
click_text: this.body,
|
|
69
|
+
element_title: "span",
|
|
70
|
+
click_url: this.href,
|
|
71
|
+
element_type: "tile",
|
|
72
|
+
content_category: "cta"
|
|
73
|
+
};
|
|
74
|
+
track(event.currentTarget!, "custEv_ctaTile", payloadCardTextInfo);
|
|
75
|
+
track(event.currentTarget!, "custEv_linkClick", payloadCardTextInfo);
|
|
76
|
+
}
|
|
30
77
|
}
|
|
@@ -109,13 +109,15 @@ export default class CardTrial extends LightningElement {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
private handleSignUpClick(e: PointerEvent) {
|
|
112
|
-
|
|
112
|
+
const payload = {
|
|
113
113
|
click_text: this.label,
|
|
114
|
-
element_title:
|
|
114
|
+
element_title: "dx-button",
|
|
115
115
|
element_type: "card",
|
|
116
116
|
click_url: this.href,
|
|
117
117
|
content_category: "cta"
|
|
118
|
-
}
|
|
118
|
+
};
|
|
119
|
+
track(e.currentTarget!, "custEv_signupStart", payload);
|
|
120
|
+
track(e.currentTarget!, "custEv_linkClick", payload);
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
private isExternalURL(url: string | undefined): boolean {
|
|
@@ -68,13 +68,15 @@ export default class CardTrial extends LightningElement {
|
|
|
68
68
|
|
|
69
69
|
private handleSignUpClick(e: PointerEvent) {
|
|
70
70
|
if (this.href.includes("signup")) {
|
|
71
|
-
|
|
71
|
+
const payload = {
|
|
72
72
|
click_text: this.buttonCta,
|
|
73
|
-
element_title:
|
|
73
|
+
element_title: "dx-button",
|
|
74
74
|
element_type: "card",
|
|
75
75
|
click_url: this.href,
|
|
76
76
|
content_category: "cta"
|
|
77
|
-
}
|
|
77
|
+
};
|
|
78
|
+
track(e.currentTarget!, "custEv_signupStart", payload);
|
|
79
|
+
track(e.currentTarget!, "custEv_linkClick", payload);
|
|
78
80
|
}
|
|
79
81
|
}
|
|
80
82
|
}
|
|
@@ -174,6 +174,15 @@ export default class CodeBlock extends LightningElement {
|
|
|
174
174
|
this.selectedLanguageLabel = this.selectedLanguage.label;
|
|
175
175
|
this.selectedLanguageId = this.selectedLanguage.id;
|
|
176
176
|
this.formatCodeBlock();
|
|
177
|
+
|
|
178
|
+
gtmTrack(newLang, "custEv_ctaLinkClick", {
|
|
179
|
+
event: "custEv_ctaLinkClick",
|
|
180
|
+
click_text: newLang.detail,
|
|
181
|
+
element_title: "dx-dropdown",
|
|
182
|
+
click_url: this.selectedLanguageId,
|
|
183
|
+
element_type: "link",
|
|
184
|
+
content_category: "code block"
|
|
185
|
+
});
|
|
177
186
|
}
|
|
178
187
|
|
|
179
188
|
/**
|
|
@@ -181,8 +190,11 @@ export default class CodeBlock extends LightningElement {
|
|
|
181
190
|
* https://github.com/storybookjs/storybook/issues/13529
|
|
182
191
|
*/
|
|
183
192
|
async copySource(event: any) {
|
|
184
|
-
gtmTrack(event.target, "
|
|
185
|
-
|
|
193
|
+
gtmTrack(event.target, "custEv_iconClick", {
|
|
194
|
+
click_text: this.copyBtnText,
|
|
195
|
+
element_type: "icon",
|
|
196
|
+
element_title: "dx-icon",
|
|
197
|
+
content_category: "code block"
|
|
186
198
|
});
|
|
187
199
|
|
|
188
200
|
try {
|
|
@@ -206,8 +218,11 @@ export default class CodeBlock extends LightningElement {
|
|
|
206
218
|
this.theme = this.theme === DARK ? LIGHT : DARK;
|
|
207
219
|
setLocalStorageData(LOCAL_STORAGE_KEY, this.theme);
|
|
208
220
|
|
|
209
|
-
gtmTrack(event.target, "
|
|
210
|
-
|
|
221
|
+
gtmTrack(event.target, "custEv_iconClick", {
|
|
222
|
+
click_text: this.updateThemeBtnText,
|
|
223
|
+
element_type: "icon",
|
|
224
|
+
element_title: "dx-icon",
|
|
225
|
+
content_category: "code block"
|
|
211
226
|
});
|
|
212
227
|
}
|
|
213
228
|
|
|
@@ -21,9 +21,8 @@
|
|
|
21
21
|
>
|
|
22
22
|
<template for:each={options} for:item="option" for:index="index">
|
|
23
23
|
<dx-dropdown-option
|
|
24
|
-
suppress-gtm-nav-headings={suppressGtmNavHeadings}
|
|
25
24
|
analytics-event={analyticsEvent}
|
|
26
|
-
analytics-
|
|
25
|
+
analytics-payload={analyticsPayload}
|
|
27
26
|
active={option.active}
|
|
28
27
|
key-value={option.keyValue}
|
|
29
28
|
if:false={option.options}
|
|
@@ -44,9 +43,8 @@
|
|
|
44
43
|
<span class="menu_heading">{option.label}</span>
|
|
45
44
|
<template for:each={option.options} for:item="suboption">
|
|
46
45
|
<dx-dropdown-option
|
|
47
|
-
suppress-gtm-nav-headings={suppressGTMNavHeadings}
|
|
48
46
|
analytics-event={analyticsEvent}
|
|
49
|
-
analytics-
|
|
47
|
+
analytics-payload={analyticsPayload}
|
|
50
48
|
active={suboption.active}
|
|
51
49
|
key={suboption.id}
|
|
52
50
|
key-value={suboption.keyValue}
|
|
@@ -38,13 +38,8 @@ export default class Dropdown extends LightningElement {
|
|
|
38
38
|
@api variant: DropdownVariant = "base";
|
|
39
39
|
|
|
40
40
|
// props forwarded to dropdown option
|
|
41
|
-
@api analyticsEvent
|
|
42
|
-
@api
|
|
43
|
-
elementType: "dropdown",
|
|
44
|
-
destinationType: "internal",
|
|
45
|
-
ctaClick: true
|
|
46
|
-
};
|
|
47
|
-
@api suppressGtmNavHeadings?: boolean = false;
|
|
41
|
+
@api analyticsEvent?: string;
|
|
42
|
+
@api analyticsPayload?: AnalyticsPayload;
|
|
48
43
|
|
|
49
44
|
@api
|
|
50
45
|
get options() {
|
|
@@ -9,12 +9,11 @@ import { track } from "dxUtils/analytics";
|
|
|
9
9
|
|
|
10
10
|
export default class DropdownOption extends LightningElement {
|
|
11
11
|
@api option!: OptionWithNested;
|
|
12
|
-
@api suppressGtmNavHeadings: boolean = false;
|
|
13
12
|
@api keyValue!: string;
|
|
14
13
|
@api active: boolean = false;
|
|
15
14
|
@api navItemLabel: String | null = null;
|
|
16
15
|
@api analyticsEvent: string | null = null;
|
|
17
|
-
@api
|
|
16
|
+
@api analyticsPayload?: AnalyticsPayload | undefined;
|
|
18
17
|
@api indexPosition: number = 0;
|
|
19
18
|
@api variant: DropdownVariant = "base";
|
|
20
19
|
|
|
@@ -43,25 +42,16 @@ export default class DropdownOption extends LightningElement {
|
|
|
43
42
|
new CustomEvent("select", { detail: this.keyValue })
|
|
44
43
|
);
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (!this.suppressGtmNavHeadings) {
|
|
58
|
-
payload.navHeading = navHeading;
|
|
59
|
-
payload.navSubHeading = navSubHeading;
|
|
60
|
-
payload.pageLocation = window.location.pathname;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (this.analyticsEvent && e.currentTarget) {
|
|
64
|
-
track(e.currentTarget, this.analyticsEvent, payload);
|
|
45
|
+
if (this.analyticsEvent && this.analyticsPayload && e.currentTarget) {
|
|
46
|
+
track(e.currentTarget, this.analyticsEvent, {
|
|
47
|
+
...this.analyticsPayload,
|
|
48
|
+
click_text: this.option.label,
|
|
49
|
+
click_url: this.option.link?.href,
|
|
50
|
+
element_type: this.analyticsPayload?.element_type || "dropdown",
|
|
51
|
+
...(this.analyticsPayload?.nav_type
|
|
52
|
+
? { nav_item: this.option.label }
|
|
53
|
+
: {})
|
|
54
|
+
});
|
|
65
55
|
}
|
|
66
56
|
}
|
|
67
57
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LightningElement, api } from "lwc";
|
|
2
|
+
import { track } from "dxUtils/analytics";
|
|
2
3
|
|
|
3
4
|
export default class Feature extends LightningElement {
|
|
4
5
|
@api label!: string;
|
|
@@ -31,4 +32,16 @@ export default class Feature extends LightningElement {
|
|
|
31
32
|
get iconSymbol(): string {
|
|
32
33
|
return this.isExternalLink ? "new_window" : "";
|
|
33
34
|
}
|
|
35
|
+
|
|
36
|
+
handleClick(event: Event) {
|
|
37
|
+
const payload = {
|
|
38
|
+
click_text: this.buttonLabel,
|
|
39
|
+
element_title: "dx-button",
|
|
40
|
+
click_url: this.buttonHref,
|
|
41
|
+
element_type: "button",
|
|
42
|
+
content_category: "cta"
|
|
43
|
+
};
|
|
44
|
+
track(event.target!, "custEv_ctaButtonClick", payload);
|
|
45
|
+
track(event.target!, "custEv_linkClick", payload);
|
|
46
|
+
}
|
|
34
47
|
}
|
|
@@ -4,6 +4,7 @@ import { LightningSlotElement } from "typings/custom";
|
|
|
4
4
|
import { isSlotEmpty } from "dxUtils/slot";
|
|
5
5
|
import { toJson } from "dxUtils/normalizers";
|
|
6
6
|
import { ImageAndLabel } from "../imageAndLabel";
|
|
7
|
+
import { track } from "dxUtils/analytics";
|
|
7
8
|
import svgs from "./svgs";
|
|
8
9
|
|
|
9
10
|
export default class FeaturedContentHeader extends LightningElement {
|
|
@@ -32,7 +33,12 @@ export default class FeaturedContentHeader extends LightningElement {
|
|
|
32
33
|
private _authors?: Array<ImageAndLabel>;
|
|
33
34
|
private isSlotEmpty: boolean = true;
|
|
34
35
|
private isLinkHovered: boolean = false;
|
|
35
|
-
|
|
36
|
+
private progressPodcastPlayed = {
|
|
37
|
+
percent25: false,
|
|
38
|
+
percent50: false,
|
|
39
|
+
percent75: false,
|
|
40
|
+
percent100: false
|
|
41
|
+
};
|
|
36
42
|
// ! Move this map away from the component and probably the filter too.
|
|
37
43
|
@api
|
|
38
44
|
get authors() {
|
|
@@ -103,6 +109,57 @@ export default class FeaturedContentHeader extends LightningElement {
|
|
|
103
109
|
|
|
104
110
|
private onSlotChange(e: LightningSlotElement): void {
|
|
105
111
|
this.isSlotEmpty = isSlotEmpty(e);
|
|
112
|
+
const slot = e.target;
|
|
113
|
+
const slotElements = slot.assignedElements();
|
|
114
|
+
|
|
115
|
+
if (slotElements.length) {
|
|
116
|
+
const slotContentElement = slotElements[0];
|
|
117
|
+
const playerElement = slotContentElement.shadowRoot.querySelector(
|
|
118
|
+
"audio"
|
|
119
|
+
) as HTMLAudioElement;
|
|
120
|
+
if (playerElement) {
|
|
121
|
+
playerElement.addEventListener("play", (event: Event) => {
|
|
122
|
+
const playerState = this.handlePlayerState(playerElement);
|
|
123
|
+
this.trackAnalytics(
|
|
124
|
+
event,
|
|
125
|
+
"play",
|
|
126
|
+
playerState.timePlayed,
|
|
127
|
+
playerState.percentagePlayed
|
|
128
|
+
);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
playerElement.addEventListener("pause", (event: Event) => {
|
|
132
|
+
const playerState = this.handlePlayerState(playerElement);
|
|
133
|
+
this.trackAnalytics(
|
|
134
|
+
event,
|
|
135
|
+
"pause",
|
|
136
|
+
playerState.timePlayed,
|
|
137
|
+
playerState.percentagePlayed
|
|
138
|
+
);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
playerElement.addEventListener("timeupdate", (event: Event) => {
|
|
142
|
+
const playerState = this.handlePlayerState(playerElement);
|
|
143
|
+
if (
|
|
144
|
+
(playerState.percentagePlayed === 25 &&
|
|
145
|
+
!this.progressPodcastPlayed.percent25) ||
|
|
146
|
+
(playerState.percentagePlayed === 50 &&
|
|
147
|
+
!this.progressPodcastPlayed.percent50) ||
|
|
148
|
+
(playerState.percentagePlayed === 75 &&
|
|
149
|
+
!this.progressPodcastPlayed.percent75) ||
|
|
150
|
+
(playerState.percentagePlayed === 100 &&
|
|
151
|
+
!this.progressPodcastPlayed.percent100)
|
|
152
|
+
) {
|
|
153
|
+
this.trackAnalytics(
|
|
154
|
+
event,
|
|
155
|
+
"progress",
|
|
156
|
+
playerState.timePlayed,
|
|
157
|
+
playerState.percentagePlayed
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
106
163
|
}
|
|
107
164
|
|
|
108
165
|
renderedCallback(): void {
|
|
@@ -119,4 +176,61 @@ export default class FeaturedContentHeader extends LightningElement {
|
|
|
119
176
|
}
|
|
120
177
|
}
|
|
121
178
|
}
|
|
179
|
+
|
|
180
|
+
private trackAnalytics(
|
|
181
|
+
event: Event,
|
|
182
|
+
action: "play" | "pause" | "progress",
|
|
183
|
+
timePlayed: number,
|
|
184
|
+
percentagePlayed: number
|
|
185
|
+
) {
|
|
186
|
+
let trackEvent = null;
|
|
187
|
+
switch (action) {
|
|
188
|
+
case "play":
|
|
189
|
+
trackEvent = "custEv_podcastPlay";
|
|
190
|
+
break;
|
|
191
|
+
case "pause":
|
|
192
|
+
trackEvent = "custEv_podcastPause";
|
|
193
|
+
break;
|
|
194
|
+
case "progress":
|
|
195
|
+
trackEvent = "custEv_podcastProgress";
|
|
196
|
+
break;
|
|
197
|
+
default:
|
|
198
|
+
trackEvent = null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (!trackEvent) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
track(event.target!, trackEvent, {
|
|
206
|
+
media_name: this.title,
|
|
207
|
+
media_action: action,
|
|
208
|
+
media_episode: this.href,
|
|
209
|
+
media_percentage_played: percentagePlayed,
|
|
210
|
+
media_seconds_played: timePlayed,
|
|
211
|
+
media_type: "podcast"
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
if (Math.trunc(percentagePlayed) === 25) {
|
|
215
|
+
this.progressPodcastPlayed.percent25 = true;
|
|
216
|
+
} else if (Math.trunc(percentagePlayed) === 50) {
|
|
217
|
+
this.progressPodcastPlayed.percent50 = true;
|
|
218
|
+
} else if (Math.trunc(percentagePlayed) === 75) {
|
|
219
|
+
this.progressPodcastPlayed.percent75 = true;
|
|
220
|
+
} else if (Math.trunc(percentagePlayed) === 100) {
|
|
221
|
+
this.progressPodcastPlayed.percent100 = true;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
private handlePlayerState(player: HTMLAudioElement) {
|
|
226
|
+
let timePlayed = 0;
|
|
227
|
+
let percentagePlayed = 0;
|
|
228
|
+
if (player) {
|
|
229
|
+
timePlayed = player.currentTime / 1000;
|
|
230
|
+
percentagePlayed = Math.trunc(
|
|
231
|
+
(player.currentTime * 100) / player.duration
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
return { timePlayed, percentagePlayed };
|
|
235
|
+
}
|
|
122
236
|
}
|
|
@@ -18,12 +18,6 @@ const createNewsletterSignupHref = (email: string): string => {
|
|
|
18
18
|
return PATH;
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
const ANALYTICS_INFO = {
|
|
22
|
-
itemTitle: "Newsletter Sign Up Footer",
|
|
23
|
-
elementType: "button",
|
|
24
|
-
destinationType: "internal",
|
|
25
|
-
ctaClick: true
|
|
26
|
-
};
|
|
27
21
|
export default class Footer extends LightningElement {
|
|
28
22
|
@api locale: string | null = null;
|
|
29
23
|
@api
|
|
@@ -107,9 +101,11 @@ export default class Footer extends LightningElement {
|
|
|
107
101
|
const href = createNewsletterSignupHref(e.detail);
|
|
108
102
|
|
|
109
103
|
track(e.currentTarget, "custEv_ctaButtonClick", {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
104
|
+
click_text: this.inputSubmitLabel,
|
|
105
|
+
click_url: PATH,
|
|
106
|
+
element_type: "button",
|
|
107
|
+
element_title: "dx-footer",
|
|
108
|
+
content_category: "cta"
|
|
113
109
|
});
|
|
114
110
|
|
|
115
111
|
window.location.assign(href);
|
|
@@ -10,10 +10,18 @@ export default class FooterOption extends LightningElement {
|
|
|
10
10
|
|
|
11
11
|
sendGtm(e: PointerEvent) {
|
|
12
12
|
track(e.currentTarget, "custEv_bottomNavLinkClick", {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
click_text: this.label || undefined,
|
|
14
|
+
click_url: this.href || undefined,
|
|
15
|
+
nav_item: this.label || undefined,
|
|
16
|
+
element_type: "link",
|
|
17
|
+
nav_type: "footer"
|
|
18
|
+
});
|
|
19
|
+
track(e.currentTarget!, "custEv_linkClick", {
|
|
20
|
+
click_text: this.label,
|
|
21
|
+
element_title: "dx-button",
|
|
22
|
+
click_url: this.href,
|
|
23
|
+
element_type: "link",
|
|
24
|
+
content_category: "cta"
|
|
17
25
|
});
|
|
18
26
|
}
|
|
19
27
|
}
|
|
@@ -20,12 +20,6 @@ const subtitleClasses = {
|
|
|
20
20
|
[MEDIUM]: "dx-text-heading-7"
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
const ANALYTICS_INFO = {
|
|
24
|
-
elementType: "button",
|
|
25
|
-
destinationType: "internal",
|
|
26
|
-
ctaClick: true
|
|
27
|
-
};
|
|
28
|
-
|
|
29
23
|
export default class GroupText extends LightningElement {
|
|
30
24
|
@api title!: string;
|
|
31
25
|
@api body?: string;
|
|
@@ -99,13 +93,13 @@ export default class GroupText extends LightningElement {
|
|
|
99
93
|
}
|
|
100
94
|
|
|
101
95
|
private trackClick(event: Event) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
96
|
+
track(event.target!, "custEv_ctaButtonClick", {
|
|
97
|
+
click_text: event.currentTarget.innerText,
|
|
98
|
+
item_title: event.currentTarget.innerText,
|
|
99
|
+
click_url: event.currentTarget.href,
|
|
100
|
+
element_type: "button",
|
|
101
|
+
element_title: "dx-group-text",
|
|
102
|
+
content_category: "cta"
|
|
103
|
+
});
|
|
110
104
|
}
|
|
111
105
|
}
|
|
@@ -16,5 +16,13 @@ export default class HeaderMobileNavMenuOption extends LightningElement {
|
|
|
16
16
|
clickText: this.href || undefined,
|
|
17
17
|
pageLocation: window.location.pathname || undefined
|
|
18
18
|
});
|
|
19
|
+
|
|
20
|
+
track(e.currentTarget!, "custEv_linkClick", {
|
|
21
|
+
click_text: this.itemLabel,
|
|
22
|
+
element_title: "dx-button",
|
|
23
|
+
click_url: this.href,
|
|
24
|
+
element_type: "link",
|
|
25
|
+
content_category: "cta"
|
|
26
|
+
});
|
|
19
27
|
}
|
|
20
28
|
}
|
|
@@ -46,6 +46,10 @@ export default class HeaderNav extends LightningElement {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
private _navItems: OptionWithNested[] = [];
|
|
49
|
+
private ANALYTICS_PAYLOAD = {
|
|
50
|
+
nav_level: "2",
|
|
51
|
+
nav_type: "global"
|
|
52
|
+
};
|
|
49
53
|
|
|
50
54
|
private requestOpenNavMenu(e: PointerEvent) {
|
|
51
55
|
const detail = (<HTMLButtonElement>e.currentTarget).getAttribute(
|
|
@@ -23,12 +23,18 @@ export default class MainContentHeader extends LightningElement {
|
|
|
23
23
|
private onCtaClick(e: Event) {
|
|
24
24
|
if (e.currentTarget) {
|
|
25
25
|
track(e.currentTarget, "custEv_ctaButtonClick", {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
click_text: this.ctaLabel,
|
|
27
|
+
click_url: this.ctaHref,
|
|
28
|
+
element_type: "button",
|
|
29
|
+
element_title: "dx-button",
|
|
30
|
+
content_category: "cta"
|
|
31
|
+
});
|
|
32
|
+
track(e.currentTarget!, "custEv_linkClick", {
|
|
33
|
+
click_text: this.ctaLabel,
|
|
34
|
+
element_title: "dx-button",
|
|
35
|
+
click_url: this.ctaHref,
|
|
36
|
+
element_type: "link",
|
|
37
|
+
content_category: "cta"
|
|
32
38
|
});
|
|
33
39
|
}
|
|
34
40
|
}
|
|
@@ -2,13 +2,6 @@ import classNames from "classnames";
|
|
|
2
2
|
import { LightningElement, api } from "lwc";
|
|
3
3
|
import { track } from "dxUtils/analytics";
|
|
4
4
|
|
|
5
|
-
const ANALYTICS_INFO = {
|
|
6
|
-
clickUrl: window.location.href,
|
|
7
|
-
ctaClick: false,
|
|
8
|
-
elementType: "button",
|
|
9
|
-
destinationType: "internal"
|
|
10
|
-
};
|
|
11
|
-
|
|
12
5
|
enum PaginationClickType {
|
|
13
6
|
Number,
|
|
14
7
|
Next,
|
|
@@ -99,9 +92,11 @@ export default class Pagination extends LightningElement {
|
|
|
99
92
|
: (e.target as HTMLElement).dataset.partId;
|
|
100
93
|
|
|
101
94
|
track(e.currentTarget!, "custEv_pagination", {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
95
|
+
click_text: clickText,
|
|
96
|
+
click_url: window.location.href,
|
|
97
|
+
element_type: "button",
|
|
98
|
+
nav_type: "pagination",
|
|
99
|
+
nav_item: clickText
|
|
105
100
|
});
|
|
106
101
|
|
|
107
102
|
this.dispatchEvent(new CustomEvent("pagechange", { detail: page }));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LightningElement, api, track } from "lwc";
|
|
2
2
|
import type * as CoveoSDK from "coveo-search-ui";
|
|
3
|
+
import { track as trackGTM } from "dxUtils/analytics";
|
|
3
4
|
|
|
4
5
|
interface CoveoSearch {
|
|
5
6
|
state: typeof CoveoSDK.state;
|
|
@@ -151,6 +152,7 @@ export default class SearchResults extends LightningElement {
|
|
|
151
152
|
return cv.state === "selected";
|
|
152
153
|
});
|
|
153
154
|
});
|
|
155
|
+
this.trackSearchResults(event, this.query, this.totalResults);
|
|
154
156
|
});
|
|
155
157
|
}
|
|
156
158
|
|
|
@@ -184,4 +186,13 @@ export default class SearchResults extends LightningElement {
|
|
|
184
186
|
}
|
|
185
187
|
}
|
|
186
188
|
}
|
|
189
|
+
|
|
190
|
+
private trackSearchResults(event: Event, term: string, resultCount: any) {
|
|
191
|
+
trackGTM(event.target!, "custEv_search", {
|
|
192
|
+
search_term: term,
|
|
193
|
+
search_category: "",
|
|
194
|
+
search_type: "site search",
|
|
195
|
+
search_result_count: resultCount
|
|
196
|
+
});
|
|
197
|
+
}
|
|
187
198
|
}
|
|
@@ -32,9 +32,20 @@ export default class Tab extends LightningElement {
|
|
|
32
32
|
|
|
33
33
|
private sendGtm(e: PointerEvent) {
|
|
34
34
|
track(e.currentTarget!, "custEv_topNavLinkClick", {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
click_text: this.label || undefined,
|
|
36
|
+
click_url: this.href || undefined,
|
|
37
|
+
nav_level: "1",
|
|
38
|
+
nav_item: this.label || undefined,
|
|
39
|
+
element_type: "link",
|
|
40
|
+
nav_type: "global"
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
track(e.currentTarget!, "custEv_linkClick", {
|
|
44
|
+
click_text: this.label,
|
|
45
|
+
element_title: "button",
|
|
46
|
+
click_url: this.href,
|
|
47
|
+
element_type: "link",
|
|
48
|
+
content_category: "cta"
|
|
38
49
|
});
|
|
39
50
|
}
|
|
40
51
|
|
|
@@ -75,16 +75,33 @@ export default class Toc extends LightningElement {
|
|
|
75
75
|
|
|
76
76
|
this._value = id!;
|
|
77
77
|
|
|
78
|
-
sendGtm(e.currentTarget!, "
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
78
|
+
sendGtm(e.currentTarget!, "custEv_tableOfContents", {
|
|
79
|
+
click_text: text,
|
|
80
|
+
clickAction: "click",
|
|
81
|
+
click_url: href,
|
|
82
|
+
element_title: "a",
|
|
83
|
+
element_type: "link",
|
|
84
|
+
content_category: "cta"
|
|
84
85
|
});
|
|
85
86
|
}
|
|
86
87
|
|
|
87
|
-
private toggleShowContent() {
|
|
88
|
+
private toggleShowContent(e: Event) {
|
|
88
89
|
this.showContent = !this.showContent;
|
|
90
|
+
this.trackShowContent(e);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private trackShowContent(event: Event) {
|
|
94
|
+
let action = "collapse";
|
|
95
|
+
if (this.showContent) {
|
|
96
|
+
action = "expand";
|
|
97
|
+
}
|
|
98
|
+
sendGtm(event.target!, "custEv_tableOfContents", {
|
|
99
|
+
click_text: this.toggleButtonAriaLabel,
|
|
100
|
+
clickAction: action,
|
|
101
|
+
click_url: "",
|
|
102
|
+
element_title: "dx-button",
|
|
103
|
+
element_type: "button",
|
|
104
|
+
content_category: "cta"
|
|
105
|
+
});
|
|
89
106
|
}
|
|
90
107
|
}
|
|
@@ -146,11 +146,20 @@ export default class TreeItem extends LightningElement {
|
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
private sendGtm(event: Event) {
|
|
149
|
-
track(event.currentTarget!, "
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
149
|
+
track(event.currentTarget!, "custEv_leftNavLinkClick", {
|
|
150
|
+
click_text: this._treeNode.label,
|
|
151
|
+
click_url: this.href,
|
|
152
|
+
nav_item: this.parentName,
|
|
153
|
+
nav_type: "left nav bar",
|
|
154
|
+
element_type: "link"
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
track(event.currentTarget!, "custEv_linkClick", {
|
|
158
|
+
click_text: this._treeNode.label,
|
|
159
|
+
element_title: "dx-tree-item",
|
|
160
|
+
click_url: this.href,
|
|
161
|
+
element_type: "link",
|
|
162
|
+
content_category: "cta"
|
|
154
163
|
});
|
|
155
164
|
}
|
|
156
165
|
}
|
|
@@ -21,10 +21,9 @@ const VALID_BRANDS = [
|
|
|
21
21
|
];
|
|
22
22
|
|
|
23
23
|
export const ANALYTICS_INFO = {
|
|
24
|
-
click_text: "
|
|
25
|
-
element_title: "
|
|
26
|
-
|
|
27
|
-
element_type: "internal",
|
|
24
|
+
click_text: "browse trials",
|
|
25
|
+
element_title: "dx-button",
|
|
26
|
+
element_type: "button",
|
|
28
27
|
content_category: "cta"
|
|
29
28
|
};
|
|
30
29
|
|
|
@@ -201,10 +200,13 @@ export abstract class HeaderBase extends LightningElement {
|
|
|
201
200
|
};
|
|
202
201
|
|
|
203
202
|
private handleSignUpClick(e: PointerEvent) {
|
|
204
|
-
|
|
203
|
+
const payload = {
|
|
205
204
|
...ANALYTICS_INFO,
|
|
206
205
|
click_url: this.signupLink
|
|
207
|
-
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
track(e.currentTarget!, "custEv_browseTrialsClick", payload);
|
|
209
|
+
track(e.currentTarget!, "custEv_linkClick", payload);
|
|
208
210
|
}
|
|
209
211
|
|
|
210
212
|
protected additionalClasses(): string {
|