@salesforcedevs/dx-components 1.3.57-alpha.9 → 1.3.62-alpha01
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 +5 -3
- package/src/assets/icons/salesforcebrand-sprite/svg/symbols.svg +118 -7
- package/src/assets/svg/privacyicon.png +0 -0
- package/src/modules/dx/cardBlogPost/cardBlogPost.html +3 -3
- package/src/modules/dx/cardBlogPost/cardBlogPost.ts +18 -3
- package/src/modules/dx/cardCallout/cardCallout.ts +7 -0
- package/src/modules/dx/cardContent/cardContent.css +5 -0
- package/src/modules/dx/cardContent/cardContent.html +12 -6
- package/src/modules/dx/cardContent/cardContent.ts +39 -7
- package/src/modules/dx/cardDocs/cardDocs.html +6 -2
- package/src/modules/dx/cardDocs/cardDocs.ts +47 -0
- package/src/modules/dx/cardExpanded/cardExpanded.css +15 -5
- package/src/modules/dx/cardExpanded/cardExpanded.html +9 -5
- package/src/modules/dx/cardExpanded/cardExpanded.ts +24 -8
- package/src/modules/dx/cardNews/cardNews.ts +1 -0
- package/src/modules/dx/cardTrial/cardTrial.html +5 -1
- package/src/modules/dx/cardTrial/cardTrial.ts +40 -1
- package/src/modules/dx/cardTrialExpanded/cardTrialExpanded.css +10 -0
- package/src/modules/dx/cardTrialExpanded/cardTrialExpanded.html +16 -10
- package/src/modules/dx/cardTrialExpanded/cardTrialExpanded.ts +43 -1
- 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 +116 -2
- package/src/modules/dx/footer/footer.css +9 -0
- package/src/modules/dx/footer/footer.html +6 -0
- package/src/modules/dx/footer/footer.ts +7 -14
- package/src/modules/dx/footer/links.ts +5 -0
- 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.html +2 -2
- package/src/modules/dx/mainContentHeader/mainContentHeader.ts +21 -6
- package/src/modules/dx/modal/modal.html +1 -1
- package/src/modules/dx/modal/modal.ts +6 -1
- package/src/modules/dx/pagination/pagination.ts +5 -10
- package/src/modules/dx/scrollManager/scrollManager.ts +14 -9
- package/src/modules/dx/searchResults/coveo.css +32 -31
- package/src/modules/dx/searchResults/searchResults.ts +11 -0
- package/src/modules/dx/tab/tab.ts +14 -3
- package/src/modules/dx/tabPanelItem/tabPanelItem.html +1 -1
- package/src/modules/dx/tbidAvatarButton/tbidAvatarButton.ts +26 -16
- package/src/modules/dx/toc/toc.ts +24 -7
- package/src/modules/dx/treeItem/treeItem.ts +24 -7
- package/src/modules/dxBaseElements/headerBase/headerBase.ts +10 -8
- package/src/modules/dxUtils/normalizers/normalizers.ts +1 -3
|
@@ -14,19 +14,10 @@ import { track } from "dxUtils/analytics";
|
|
|
14
14
|
const PATH = "/newsletter";
|
|
15
15
|
const LOCAL_STORAGE_KEY = "subscriberEmail";
|
|
16
16
|
const createNewsletterSignupHref = (email: string): string => {
|
|
17
|
-
window.localStorage.setItem(
|
|
18
|
-
LOCAL_STORAGE_KEY,
|
|
19
|
-
email
|
|
20
|
-
);
|
|
17
|
+
window.localStorage.setItem(LOCAL_STORAGE_KEY, email);
|
|
21
18
|
return PATH;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const ANALYTICS_INFO = {
|
|
25
|
-
itemTitle: "Newsletter Sign Up Footer",
|
|
26
|
-
elementType: "button",
|
|
27
|
-
destinationType: "internal",
|
|
28
|
-
ctaClick: true
|
|
29
19
|
};
|
|
20
|
+
|
|
30
21
|
export default class Footer extends LightningElement {
|
|
31
22
|
@api locale: string | null = null;
|
|
32
23
|
@api
|
|
@@ -110,9 +101,11 @@ export default class Footer extends LightningElement {
|
|
|
110
101
|
const href = createNewsletterSignupHref(e.detail);
|
|
111
102
|
|
|
112
103
|
track(e.currentTarget, "custEv_ctaButtonClick", {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
104
|
+
click_text: this.inputSubmitLabel,
|
|
105
|
+
click_url: PATH,
|
|
106
|
+
element_type: "button",
|
|
107
|
+
element_title: "dx-footer",
|
|
108
|
+
content_category: "cta"
|
|
116
109
|
});
|
|
117
110
|
|
|
118
111
|
window.location.assign(href);
|
|
@@ -167,6 +167,11 @@ export const termsLinks = [
|
|
|
167
167
|
rel: "nofollow",
|
|
168
168
|
label: "Cookie Preferences",
|
|
169
169
|
onclick: openOneTrustInfoDisplay
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
href: "https://www.salesforce.com/form/other/privacy-request/",
|
|
173
|
+
label: "Your Privacy Choices",
|
|
174
|
+
img: "/assets/svg/privacyicon.png"
|
|
170
175
|
}
|
|
171
176
|
];
|
|
172
177
|
|
|
@@ -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(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="container">
|
|
3
|
-
<div class="text-container"
|
|
2
|
+
<div class="container" style={style}>
|
|
3
|
+
<div class="text-container">
|
|
4
4
|
<h1 class="heading dx-text-heading-2">{title}</h1>
|
|
5
5
|
<span class="body dx-text-body-1">{body}</span>
|
|
6
6
|
<span if:true={subtitle} class="subtitle dx-text-heading-4b">
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LightningElement, api } from "lwc";
|
|
2
|
+
import cx from "classnames";
|
|
2
3
|
import { track } from "dxUtils/analytics";
|
|
3
4
|
|
|
4
5
|
export default class MainContentHeader extends LightningElement {
|
|
@@ -10,16 +11,30 @@ export default class MainContentHeader extends LightningElement {
|
|
|
10
11
|
@api imgSrc!: string;
|
|
11
12
|
@api imgSrcMobile!: string;
|
|
12
13
|
@api ctaTarget?: string | null = null;
|
|
14
|
+
@api backgroundGradientColor?: string;
|
|
15
|
+
|
|
16
|
+
private get style() {
|
|
17
|
+
return cx(
|
|
18
|
+
this.backgroundGradientColor &&
|
|
19
|
+
`background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, #ffff 100%), var(--dx-g-${this.backgroundGradientColor});`
|
|
20
|
+
);
|
|
21
|
+
}
|
|
13
22
|
|
|
14
23
|
private onCtaClick(e: Event) {
|
|
15
24
|
if (e.currentTarget) {
|
|
16
25
|
track(e.currentTarget, "custEv_ctaButtonClick", {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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"
|
|
23
38
|
});
|
|
24
39
|
}
|
|
25
40
|
}
|
|
@@ -39,7 +39,7 @@ export default class Modal extends LightningElement {
|
|
|
39
39
|
|
|
40
40
|
handleKeyDown(event: KeyboardEvent): void {
|
|
41
41
|
if (event.key === "Escape") {
|
|
42
|
-
this.
|
|
42
|
+
this.handleCloseModal();
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -47,4 +47,9 @@ export default class Modal extends LightningElement {
|
|
|
47
47
|
this._open = !this._open;
|
|
48
48
|
this.dispatchEvent(new CustomEvent("togglemodal"));
|
|
49
49
|
}
|
|
50
|
+
|
|
51
|
+
handleCloseModal() {
|
|
52
|
+
this._open = false;
|
|
53
|
+
this.dispatchEvent(new CustomEvent("closemodal"));
|
|
54
|
+
}
|
|
50
55
|
}
|
|
@@ -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,4 +1,5 @@
|
|
|
1
1
|
import { LightningElement } from "lwc";
|
|
2
|
+
import { throttle } from "throttle-debounce";
|
|
2
3
|
|
|
3
4
|
const RESTORE_SCROLL_EVENT_NAME = "restore-scroll";
|
|
4
5
|
const LOAD_TIME_SCROLL_RESTORE_DELAY = 750;
|
|
@@ -8,7 +9,13 @@ declare module globalThis {
|
|
|
8
9
|
let singletonScrollManagerConnected: boolean;
|
|
9
10
|
}
|
|
10
11
|
// mostly components shouldn't be using this, but there are a few exceptions such as amfReference
|
|
12
|
+
|
|
13
|
+
let scrollUnlocked: boolean = false;
|
|
14
|
+
|
|
11
15
|
export const restoreScroll = () => {
|
|
16
|
+
if (scrollUnlocked) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
12
19
|
document.body.scrollTop = document.documentElement.scrollTop =
|
|
13
20
|
window.history.state?.scroll.value;
|
|
14
21
|
};
|
|
@@ -32,13 +39,13 @@ export default class ScrollManager extends LightningElement {
|
|
|
32
39
|
*/
|
|
33
40
|
|
|
34
41
|
protected scrollCount = 0; // this is for dark magic, basically we lock the user out of scrolling in the first quarter second, unless they really mean it. We do this because load timings mean that the scroll can get messed up in that period
|
|
35
|
-
protected scrollUnlocked = false;
|
|
36
42
|
|
|
37
43
|
renderedCallback() {
|
|
38
|
-
|
|
44
|
+
scrollUnlocked = window.location.hash !== ""; // if we have anchor links, skip the entire scroll restore
|
|
45
|
+
if (!globalThis.singletonScrollManagerRendered && !scrollUnlocked) {
|
|
39
46
|
globalThis.singletonScrollManagerRendered = true;
|
|
40
47
|
if (
|
|
41
|
-
window.history.state?.scroll
|
|
48
|
+
window.history.state?.scroll?.docSize ===
|
|
42
49
|
document.body.scrollHeight
|
|
43
50
|
) {
|
|
44
51
|
// only do this if loading is complete and the scrollHeight matches expectations
|
|
@@ -49,10 +56,8 @@ export default class ScrollManager extends LightningElement {
|
|
|
49
56
|
// sometimes loading is slow, so we may want to reset the scroll to
|
|
50
57
|
// the correct position after loading is complete, to avoid weird behavior
|
|
51
58
|
// but only if the user hasn't scrolled around in the meantime
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
this.scrollUnlocked = true;
|
|
55
|
-
}
|
|
59
|
+
restoreScroll();
|
|
60
|
+
scrollUnlocked = true;
|
|
56
61
|
}, LOAD_TIME_SCROLL_RESTORE_DELAY);
|
|
57
62
|
}
|
|
58
63
|
} else {
|
|
@@ -75,7 +80,7 @@ export default class ScrollManager extends LightningElement {
|
|
|
75
80
|
}
|
|
76
81
|
}
|
|
77
82
|
|
|
78
|
-
saveScroll = () => {
|
|
83
|
+
saveScroll = throttle(100, () => {
|
|
79
84
|
window.history.replaceState(
|
|
80
85
|
{
|
|
81
86
|
scroll: {
|
|
@@ -86,7 +91,7 @@ export default class ScrollManager extends LightningElement {
|
|
|
86
91
|
"",
|
|
87
92
|
window.location.href
|
|
88
93
|
);
|
|
89
|
-
};
|
|
94
|
+
});
|
|
90
95
|
|
|
91
96
|
manualScrollListener = () => {
|
|
92
97
|
if (this.scrollCount < 5) {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/*
|
|
2
2
|
Code generated by scripts/postinstall.js DO NOT EDIT
|
|
3
|
-
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/*
|
|
4
6
|
* @param direction vertical or horizontal
|
|
5
7
|
* @param position type of positioning to apply (relative/absolute)
|
|
6
8
|
*/
|
|
@@ -1376,6 +1378,15 @@ Code generated by scripts/postinstall.js DO NOT EDIT
|
|
|
1376
1378
|
.coveo-filetype-salesforce-standard-work-order-item,
|
|
1377
1379
|
.coveo-filetype-salesforce-standard-work-order,
|
|
1378
1380
|
.coveo-filetype-salesforce-standard-work-type,
|
|
1381
|
+
.coveo-filetype-slack,
|
|
1382
|
+
.coveo-icon.filetype.Slackmessage,
|
|
1383
|
+
.coveo-icon.filetype.slackmessage,
|
|
1384
|
+
.coveo-icon.filetype.Slackchannel,
|
|
1385
|
+
.coveo-icon.filetype.slackchannel,
|
|
1386
|
+
.coveo-icon.filetype.Slackfile,
|
|
1387
|
+
.coveo-icon.filetype.slackfile,
|
|
1388
|
+
.coveo-icon.filetype.Slackuser,
|
|
1389
|
+
.coveo-icon.filetype.slackuser,
|
|
1379
1390
|
.coveo-filetype-user,
|
|
1380
1391
|
.coveo-icon.objecttype.People,
|
|
1381
1392
|
.coveo-icon.objecttype.people,
|
|
@@ -1584,21 +1595,6 @@ Code generated by scripts/postinstall.js DO NOT EDIT
|
|
|
1584
1595
|
background-size: 56px 64px;
|
|
1585
1596
|
}
|
|
1586
1597
|
|
|
1587
|
-
.coveo-filetype-slack,
|
|
1588
|
-
.coveo-icon.filetype.Slackmessage,
|
|
1589
|
-
.coveo-icon.filetype.slackmessage,
|
|
1590
|
-
.coveo-icon.filetype.Slackchannel,
|
|
1591
|
-
.coveo-icon.filetype.slackchannel,
|
|
1592
|
-
.coveo-icon.filetype.Slackfile,
|
|
1593
|
-
.coveo-icon.filetype.slackfile,
|
|
1594
|
-
.coveo-icon.filetype.Slackuser,
|
|
1595
|
-
.coveo-icon.filetype.slackuser {
|
|
1596
|
-
display: inline-block;
|
|
1597
|
-
width: 124px;
|
|
1598
|
-
height: 124px;
|
|
1599
|
-
background-size: 124px 124px;
|
|
1600
|
-
}
|
|
1601
|
-
|
|
1602
1598
|
.coveo-filetype-attachment-small,
|
|
1603
1599
|
.coveo-icon.objecttype.coveo-small.Attachment,
|
|
1604
1600
|
.coveo-icon.objecttype.coveo-small.attachment,
|
|
@@ -2124,6 +2120,15 @@ Code generated by scripts/postinstall.js DO NOT EDIT
|
|
|
2124
2120
|
.coveo-filetype-salesforce-standard-work-order-item-small,
|
|
2125
2121
|
.coveo-filetype-salesforce-standard-work-order-small,
|
|
2126
2122
|
.coveo-filetype-salesforce-standard-work-type-small,
|
|
2123
|
+
.coveo-filetype-slack-small,
|
|
2124
|
+
.coveo-icon.filetype.coveo-small.Slackmessage,
|
|
2125
|
+
.coveo-icon.filetype.coveo-small.slackmessage,
|
|
2126
|
+
.coveo-icon.filetype.coveo-small.Slackchannel,
|
|
2127
|
+
.coveo-icon.filetype.coveo-small.slackchannel,
|
|
2128
|
+
.coveo-icon.filetype.coveo-small.Slackfile,
|
|
2129
|
+
.coveo-icon.filetype.coveo-small.slackfile,
|
|
2130
|
+
.coveo-icon.filetype.coveo-small.Slackuser,
|
|
2131
|
+
.coveo-icon.filetype.coveo-small.slackuser,
|
|
2127
2132
|
.coveo-filetype-user-small,
|
|
2128
2133
|
.coveo-icon.objecttype.coveo-small.People,
|
|
2129
2134
|
.coveo-icon.objecttype.coveo-small.people,
|
|
@@ -2332,21 +2337,6 @@ Code generated by scripts/postinstall.js DO NOT EDIT
|
|
|
2332
2337
|
background-size: 28px 32px;
|
|
2333
2338
|
}
|
|
2334
2339
|
|
|
2335
|
-
.coveo-filetype-slack-small,
|
|
2336
|
-
.coveo-icon.filetype.coveo-small.Slackmessage,
|
|
2337
|
-
.coveo-icon.filetype.coveo-small.slackmessage,
|
|
2338
|
-
.coveo-icon.filetype.coveo-small.Slackchannel,
|
|
2339
|
-
.coveo-icon.filetype.coveo-small.slackchannel,
|
|
2340
|
-
.coveo-icon.filetype.coveo-small.Slackfile,
|
|
2341
|
-
.coveo-icon.filetype.coveo-small.slackfile,
|
|
2342
|
-
.coveo-icon.filetype.coveo-small.Slackuser,
|
|
2343
|
-
.coveo-icon.filetype.coveo-small.slackuser {
|
|
2344
|
-
display: inline-block;
|
|
2345
|
-
width: 62px;
|
|
2346
|
-
height: 62px;
|
|
2347
|
-
background-size: 62px 62px;
|
|
2348
|
-
}
|
|
2349
|
-
|
|
2350
2340
|
.coveo-filetype-attachment,
|
|
2351
2341
|
.coveo-icon.objecttype.Attachment,
|
|
2352
2342
|
.coveo-icon.objecttype.attachment,
|
|
@@ -8065,6 +8055,13 @@ select.coveo-dropdown::-ms-expand {
|
|
|
8065
8055
|
* @param $size size of the icon to use
|
|
8066
8056
|
*/
|
|
8067
8057
|
|
|
8058
|
+
@font-face {
|
|
8059
|
+
font-family: 'Lato';
|
|
8060
|
+
src: url('https://static.cloud.coveo.com/searchui/v2.10104/0/fonts/lato.woff2'), url('https://staticdev.cloud.coveo.com/searchui/v2.10104/0/fonts/lato.woff2'), url('../fonts/lato.woff2'), url('https://static.cloud.coveo.com/searchui/v2.10104/0/fonts/lato.woff'), url('https://staticdev.cloud.coveo.com/searchui/v2.10104/0/fonts/lato.woff'), url('../fonts/lato.woff');
|
|
8061
|
+
font-weight: normal;
|
|
8062
|
+
font-style: normal;
|
|
8063
|
+
}
|
|
8064
|
+
|
|
8068
8065
|
.CoveoSearchInterface {
|
|
8069
8066
|
min-height: 100%;
|
|
8070
8067
|
position: relative;
|
|
@@ -18738,6 +18735,10 @@ button.coveo-user-feedback-banner-explain-why-active {
|
|
|
18738
18735
|
* @param $size size of the icon to use
|
|
18739
18736
|
*/
|
|
18740
18737
|
|
|
18738
|
+
.coveo-user-explanation-modal .coveo-small-close {
|
|
18739
|
+
display: none;
|
|
18740
|
+
}
|
|
18741
|
+
|
|
18741
18742
|
.coveo-user-explanation-modal-explanation-section {
|
|
18742
18743
|
display: flex;
|
|
18743
18744
|
flex-wrap: wrap;
|
|
@@ -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
|
|
|
@@ -41,6 +41,11 @@ const enum PlatformEventsType {
|
|
|
41
41
|
UserMerge = "UserMerge"
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
// TODO: We probably should rewrite the logic of this component once the new identity stuff is released,
|
|
45
|
+
// especially because SSO should work in all browsers at that point, and we won't need to do any weird
|
|
46
|
+
// checking for the presence of SFIDWidget (and all the associated pain from trying to "time" the triggering of login
|
|
47
|
+
// events due to logins coming via two distinct routes in Chrome).
|
|
48
|
+
|
|
44
49
|
// This component handles the core Salesforce OAuth 2.0 flow used by TBID for login, rendering a
|
|
45
50
|
// simple Login button or avatar icon depending on login status. It should be reusable in any case
|
|
46
51
|
// where TBID login is needed.
|
|
@@ -56,6 +61,7 @@ export default class TbidAvatarButton extends LightningElement {
|
|
|
56
61
|
private eventSource?: EventSource;
|
|
57
62
|
private _isRequestingUserInfo = false;
|
|
58
63
|
private _didReceiveUserInfo = false;
|
|
64
|
+
private _didDispatchLoginSuccess = false;
|
|
59
65
|
|
|
60
66
|
// _didReceiveUserInfo is a proxy for "isLoggedIn" because we only want to show the UI corresponding
|
|
61
67
|
// to logged-in state when user info has been received (avoids flashes of weird content)
|
|
@@ -155,8 +161,12 @@ export default class TbidAvatarButton extends LightningElement {
|
|
|
155
161
|
// then this method waits a maximum of 1 second for the widget to finish logging in. If it does
|
|
156
162
|
// *not* respond quickly, the method resolves early so that we can stop waiting pointlessly.
|
|
157
163
|
private waitForSFIDWidget = async () => {
|
|
164
|
+
const millisecondsFor30fps = 33;
|
|
158
165
|
const widgetNotAlivePromise = new Promise<boolean>((resolve) => {
|
|
159
|
-
const timeoutId = setTimeout(
|
|
166
|
+
const timeoutId = setTimeout(
|
|
167
|
+
() => resolve(false),
|
|
168
|
+
5 * millisecondsFor30fps // give SFIDWidget roughly 5 chances to load
|
|
169
|
+
);
|
|
160
170
|
window.SFIDWidget?.isAlive({
|
|
161
171
|
// If the widget responds as expected, this promise will fail to resolve and thus
|
|
162
172
|
// we will continue to wait on the other promise, below.
|
|
@@ -165,7 +175,7 @@ export default class TbidAvatarButton extends LightningElement {
|
|
|
165
175
|
});
|
|
166
176
|
const widgetLoggedInPromise = pollUntil(
|
|
167
177
|
() => Boolean(window.SFIDWidget?.openid_response),
|
|
168
|
-
|
|
178
|
+
millisecondsFor30fps,
|
|
169
179
|
1000
|
|
170
180
|
);
|
|
171
181
|
const success = await Promise.race([
|
|
@@ -279,12 +289,13 @@ export default class TbidAvatarButton extends LightningElement {
|
|
|
279
289
|
// on SSO login. For some reason, the user info on SSO login lacks the user's photo URLs, so we
|
|
280
290
|
// have to re-request it. Maybe something to bring up with the TBID team.
|
|
281
291
|
await this.requestUserInfo();
|
|
282
|
-
this.dispatchLoginSuccess();
|
|
292
|
+
this.dispatchLoginSuccess(true);
|
|
283
293
|
} else if (
|
|
284
294
|
tokenResponse.status === 409 &&
|
|
285
|
-
!this._didReceiveUserInfo
|
|
295
|
+
!this._didReceiveUserInfo &&
|
|
296
|
+
!this._isRequestingUserInfo // don't duplicate requests when we already have this token and a request is on-going
|
|
286
297
|
) {
|
|
287
|
-
// Valid token received, but we still need to grab userInfo. This could happen in certain edge cases
|
|
298
|
+
// Valid but duplicate token received, but we still need to grab userInfo. This could happen in certain edge cases
|
|
288
299
|
// involving "seamless SSO" (e.g., you might be sitting on our page in more than one tab, then log in
|
|
289
300
|
// on one of them; in that case, our back-end will receive the token from one tab, end up _rejecting_ it
|
|
290
301
|
// as a duplicate on other tabs where the login event occurs, and yet still need to request user info
|
|
@@ -384,11 +395,6 @@ export default class TbidAvatarButton extends LightningElement {
|
|
|
384
395
|
};
|
|
385
396
|
|
|
386
397
|
private requestUserInfo = async () => {
|
|
387
|
-
if (this._isRequestingUserInfo) {
|
|
388
|
-
// prevent duplicate requests
|
|
389
|
-
return;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
398
|
this._isRequestingUserInfo = true;
|
|
393
399
|
|
|
394
400
|
try {
|
|
@@ -422,12 +428,16 @@ export default class TbidAvatarButton extends LightningElement {
|
|
|
422
428
|
);
|
|
423
429
|
};
|
|
424
430
|
|
|
425
|
-
private dispatchLoginSuccess = () => {
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
+
private dispatchLoginSuccess = (receivedNewToken = false) => {
|
|
432
|
+
// Receiving a new token should be treated as a new (SSO) login.
|
|
433
|
+
if (!this._didDispatchLoginSuccess || receivedNewToken) {
|
|
434
|
+
this._didDispatchLoginSuccess = true;
|
|
435
|
+
this.dispatchEvent(
|
|
436
|
+
new CustomEvent("tbidloginsuccess", {
|
|
437
|
+
bubbles: true
|
|
438
|
+
})
|
|
439
|
+
);
|
|
440
|
+
}
|
|
431
441
|
};
|
|
432
442
|
|
|
433
443
|
private dispatchLogoutSuccess = () => {
|
|
@@ -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
|
}
|