@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.
Files changed (31) hide show
  1. package/package.json +1 -1
  2. package/src/modules/dx/cardBlogPost/cardBlogPost.html +1 -0
  3. package/src/modules/dx/cardBlogPost/cardBlogPost.ts +17 -0
  4. package/src/modules/dx/cardCallout/cardCallout.ts +7 -0
  5. package/src/modules/dx/cardContent/cardContent.html +2 -0
  6. package/src/modules/dx/cardContent/cardContent.ts +7 -0
  7. package/src/modules/dx/cardDocs/cardDocs.html +6 -2
  8. package/src/modules/dx/cardDocs/cardDocs.ts +47 -0
  9. package/src/modules/dx/cardNews/cardNews.ts +1 -0
  10. package/src/modules/dx/cardTrial/cardTrial.ts +5 -3
  11. package/src/modules/dx/cardTrialExpanded/cardTrialExpanded.ts +5 -3
  12. package/src/modules/dx/codeBlock/codeBlock.ts +19 -4
  13. package/src/modules/dx/dropdown/dropdown.html +2 -4
  14. package/src/modules/dx/dropdown/dropdown.ts +2 -7
  15. package/src/modules/dx/dropdownOption/dropdownOption.ts +11 -21
  16. package/src/modules/dx/feature/feature.html +1 -0
  17. package/src/modules/dx/feature/feature.ts +13 -0
  18. package/src/modules/dx/featuredContentHeader/featuredContentHeader.ts +115 -1
  19. package/src/modules/dx/footer/footer.ts +5 -9
  20. package/src/modules/dx/footerOption/footerOption.ts +12 -4
  21. package/src/modules/dx/groupText/groupText.ts +8 -14
  22. package/src/modules/dx/headerMobileNavMenuOption/headerMobileNavMenuOption.ts +8 -0
  23. package/src/modules/dx/headerNav/headerNav.html +1 -0
  24. package/src/modules/dx/headerNav/headerNav.ts +4 -0
  25. package/src/modules/dx/mainContentHeader/mainContentHeader.ts +12 -6
  26. package/src/modules/dx/pagination/pagination.ts +5 -10
  27. package/src/modules/dx/searchResults/searchResults.ts +11 -0
  28. package/src/modules/dx/tab/tab.ts +14 -3
  29. package/src/modules/dx/toc/toc.ts +24 -7
  30. package/src/modules/dx/treeItem/treeItem.ts +14 -5
  31. package/src/modules/dxBaseElements/headerBase/headerBase.ts +8 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/dx-components",
3
- "version": "1.3.53",
3
+ "version": "1.3.54",
4
4
  "description": "DX Lightning web components",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -4,6 +4,7 @@
4
4
  body={body}
5
5
  featured={featured}
6
6
  href={href}
7
+ href-click={onLinkClick}
7
8
  img-alt={imgAlt}
8
9
  img-src={imgSrc}
9
10
  label={label}
@@ -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 title={title} target={target}></dx-card-title>
17
- <span class="dx-text-body-2">{body}</span>
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
  }
@@ -74,5 +74,6 @@ export default class CardNews extends LightningElement {
74
74
  clickUrl: this.href
75
75
  };
76
76
  track(e.currentTarget!, "custEv_ctaLinkClick", payload);
77
+ track(e.currentTarget!, "custEv_linkClick", payload);
77
78
  }
78
79
  }
@@ -109,13 +109,15 @@ export default class CardTrial extends LightningElement {
109
109
  }
110
110
 
111
111
  private handleSignUpClick(e: PointerEvent) {
112
- track(e.currentTarget!, "custEv_signupStart", {
112
+ const payload = {
113
113
  click_text: this.label,
114
- element_title: this.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
- track(e.currentTarget!, "custEv_signupStart", {
71
+ const payload = {
72
72
  click_text: this.buttonCta,
73
- element_title: this.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, "custEv_codeBlock", {
185
- codeBlockAction: "copy"
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, "custEv_codeBlock", {
210
- codeBlockAction: this.theme === DARK ? "darkmode" : "lightmode"
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-base-payload={analyticsBasePayload}
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-base-payload={analyticsBasePayload}
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: string | null = null;
42
- @api analyticsBasePayload: AnalyticsPayload = {
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 analyticsBasePayload!: AnalyticsPayload;
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
- const payload: any = {
47
- ...this.analyticsBasePayload,
48
- clickText: this.keyValue || undefined,
49
- itemTitle: this.option.label || undefined,
50
- clickUrl: this.option.link?.href || undefined
51
- };
52
-
53
- const navHeading = this.navItemLabel || this.option.label || undefined;
54
- const navSubHeading =
55
- (this.navItemLabel ? this.option.label : undefined) || undefined;
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
  }
@@ -12,6 +12,7 @@
12
12
  target={target}
13
13
  icon-symbol={iconSymbol}
14
14
  href={buttonHref}
15
+ onclick={handleClick}
15
16
  >
16
17
  {buttonLabel}
17
18
  </dx-button>
@@ -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
- ...ANALYTICS_INFO,
111
- clickText: this.inputSubmitLabel,
112
- clickUrl: PATH
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
- navHeading: this.generalLabel || undefined,
14
- navSubHeading: this.label || undefined,
15
- clickText: this.href || undefined,
16
- pageLocation: window.location.pathname || undefined
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
- const payload = {
103
- ...ANALYTICS_INFO,
104
- clickText: event.currentTarget.innerText,
105
- itemTitle: event.currentTarget.innerText,
106
- clickUrl: event.currentTarget.href
107
- };
108
-
109
- track(event.target!, "custEv_ctaButtonClick", payload);
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
  }
@@ -14,6 +14,7 @@
14
14
  <!-- DESKTOP "MORE CONTENT" NAV ITEM -->
15
15
  <dx-dropdown
16
16
  analytics-event="custEv_topNavLinkClick"
17
+ analytics-payload={ANALYTICS_PAYLOAD}
17
18
  if:true={navItem.options}
18
19
  nav-item-label={navItem.label}
19
20
  open-on-hover
@@ -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
- clickText: this.ctaLabel,
27
- itemTitle: this.title,
28
- clickUrl: this.ctaHref,
29
- elementType: "button",
30
- destinationType: "internal",
31
- ctaClick: true
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
- ...ANALYTICS_INFO,
103
- clickText,
104
- itemTitle: clickText
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
- navHeading: this.label || undefined,
36
- clickText: this.href || undefined,
37
- pageLocation: window.location.pathname
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!, "custEv_tableOfContentsClick", {
79
- clickText: text,
80
- clickUrl: href,
81
- elementType: "link",
82
- locationOnPage: "table of contents",
83
- itemTitle: this.title
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!, "custEv_leftNavClick", {
150
- navType: "left nav bar",
151
- clickText: this._treeNode.label,
152
- clickUrl: this.href,
153
- navItem: this.parentName
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: "Sign Up",
25
- element_title: "Sign Up Header Button",
26
- elementType: "button",
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
- track(e.currentTarget!, "custEv_browseTrialsClick", {
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 {