@salesforcedevs/docs-components 1.17.13-table-2 → 1.18.0-search-alpha

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/lwc.config.json CHANGED
@@ -11,7 +11,6 @@
11
11
  "doc/content",
12
12
  "doc/contentCallout",
13
13
  "doc/doDont",
14
- "doc/table",
15
14
  "doc/contentLayout",
16
15
  "doc/contentMedia",
17
16
  "doc/docXmlContent",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/docs-components",
3
- "version": "1.17.13-table-2",
3
+ "version": "1.18.0-search-alpha",
4
4
  "description": "Docs Lightning web components for DSC",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
@@ -1,13 +1,7 @@
1
1
  <template>
2
2
  <doc-content-layout
3
3
  lwc:if={isVersionFetched}
4
- use-old-sidebar={useOldSidebar}
5
4
  class="content-type content-type-reference"
6
- coveo-organization-id={coveoOrganizationId}
7
- coveo-public-access-token={coveoPublicAccessToken}
8
- coveo-analytics-token={coveoAnalyticsToken}
9
- coveo-search-hub={coveoSearchHub}
10
- coveo-advanced-query-config={coveoAdvancedQueryConfig}
11
5
  breadcrumbs={breadcrumbs}
12
6
  sidebar-header={sidebarHeader}
13
7
  sidebar-value={selectedSidebarValue}
@@ -20,6 +14,7 @@
20
14
  languages={languages}
21
15
  language={language}
22
16
  show-footer={enableFooter}
17
+ empty-state-message={emptyStateMessage}
23
18
  >
24
19
  <doc-phase
25
20
  slot="doc-phase"
@@ -3,7 +3,7 @@ import { noCase } from "no-case";
3
3
  import { sentenceCase } from "sentence-case";
4
4
  import qs from "query-string";
5
5
  import { AmfModelParser } from "doc/amfModelParser";
6
- import { normalizeBoolean, toJson } from "dxUtils/normalizers";
6
+ import { normalizeBoolean } from "dxUtils/normalizers";
7
7
  import type { OptionWithLink } from "typings/custom";
8
8
  import type {
9
9
  AmfConfig,
@@ -28,7 +28,7 @@ import {
28
28
  } from "./constants";
29
29
  import { restoreScroll } from "dx/scrollManager";
30
30
  import { DocPhaseInfo } from "typings/custom";
31
- import { logCoveoPageView, oldVersionDocInfo } from "docUtils/utils";
31
+ import { oldVersionDocInfo } from "docUtils/utils";
32
32
 
33
33
  type NavigationItem = {
34
34
  label: string;
@@ -41,11 +41,6 @@ type NavigationItem = {
41
41
  export default class AmfReference extends LightningElement {
42
42
  @api breadcrumbs: string | null = null;
43
43
  @api sidebarHeader!: string;
44
- @api coveoOrganizationId!: string;
45
- @api coveoPublicAccessToken!: string;
46
- @api coveoAnalyticsToken!: string;
47
- @api coveoSearchHub!: string;
48
- @api useOldSidebar: boolean = false;
49
44
  @api tocTitle?: string;
50
45
  @api tocOptions?: string;
51
46
  @api languages!: OptionWithLink[];
@@ -54,7 +49,6 @@ export default class AmfReference extends LightningElement {
54
49
  @track navigation = [] as NavigationItem[];
55
50
  @track versions: Array<ReferenceVersion> = [];
56
51
  @track showVersionBanner = false;
57
- @track _coveoAdvancedQueryConfig!: { [key: string]: any };
58
52
 
59
53
  // Update this to update what component gets rendered in the content block
60
54
  @track
@@ -160,35 +154,18 @@ export default class AmfReference extends LightningElement {
160
154
  this._expandChildren = normalizeBoolean(value);
161
155
  }
162
156
 
163
- /*
164
- * The get coveoAdvancedQueryConfig() method returns this._coveoAdvancedQueryConfig,
165
- * but before returning it, it checks if there are multiple versions (this.versions.length > 1)
166
- * and if a version is selected (this.selectedVersion). If both conditions are met,
167
- * it updates the version property of this._coveoAdvancedQueryConfig with the selected version.
168
- */
169
- @api
170
- get coveoAdvancedQueryConfig(): { [key: string]: any } {
171
- const coveoConfig = this._coveoAdvancedQueryConfig;
172
- if (this.versions.length > 1 && this.selectedVersion) {
173
- const currentGAVersionRef = this.versions[0];
174
- if (this.selectedVersion.id !== currentGAVersionRef.id) {
175
- // Currently Coveo only supports query without "v"
176
- const version = this.selectedVersion.id.replace("v", "");
177
- coveoConfig.version = version;
178
- this._coveoAdvancedQueryConfig = coveoConfig;
179
- }
180
- }
181
- return this._coveoAdvancedQueryConfig;
182
- }
183
-
184
- set coveoAdvancedQueryConfig(config) {
185
- this._coveoAdvancedQueryConfig = toJson(config);
186
- }
187
-
188
157
  private get enableFooter(): boolean {
189
158
  return !this.hideFooter;
190
159
  }
191
160
 
161
+ private get emptyStateMessage(): string {
162
+ return JSON.stringify([
163
+ "Select a relevant API specification",
164
+ "Please consider misspellings",
165
+ "Try different search keywords"
166
+ ]);
167
+ }
168
+
192
169
  // model
193
170
  protected _amfConfigList: AmfConfig[] = [];
194
171
  protected _amfConfigMap: Map<string, AmfConfig> = new Map();
@@ -1436,10 +1413,6 @@ export default class AmfReference extends LightningElement {
1436
1413
  metaVal
1437
1414
  );
1438
1415
 
1439
- logCoveoPageView(
1440
- this.coveoOrganizationId,
1441
- this.coveoAnalyticsToken
1442
- );
1443
1416
  this.updateUrlWithSelected(parentReferencePath, metaVal);
1444
1417
  this.updateTags(metadata.navTitle);
1445
1418
  } else {
@@ -1,43 +1,21 @@
1
1
  <template>
2
2
  <div class="content">
3
- <template lwc:if={useOldSidebar}>
4
- <dx-sidebar-old
5
- class="is-sticky left-nav-bar"
6
- trees={sidebarContent}
7
- value={sidebarValue}
8
- header={sidebarHeader}
9
- ontogglesidebar={onToggleSidebar}
10
- languages={languages}
11
- language={language}
12
- bail-href={bailHref}
13
- bail-label={bailLabel}
14
- dev-center={devCenter}
15
- brand={brand}
16
- >
17
- <slot name="sidebar-header" slot="version-picker"></slot>
18
- </dx-sidebar-old>
19
- </template>
20
- <template lwc:else>
21
- <dx-sidebar
22
- class="is-sticky left-nav-bar"
23
- trees={sidebarContent}
24
- value={sidebarValue}
25
- header={sidebarHeader}
26
- coveo-organization-id={coveoOrganizationId}
27
- coveo-public-access-token={coveoPublicAccessToken}
28
- coveo-search-hub={coveoSearchHub}
29
- coveo-advanced-query-config={coveoAdvancedQueryConfig}
30
- ontogglesidebar={onToggleSidebar}
31
- languages={languages}
32
- language={language}
33
- bail-href={bailHref}
34
- bail-label={bailLabel}
35
- dev-center={devCenter}
36
- brand={brand}
37
- >
38
- <slot name="sidebar-header" slot="version-picker"></slot>
39
- </dx-sidebar>
40
- </template>
3
+ <dx-sidebar-old
4
+ class="is-sticky left-nav-bar"
5
+ trees={sidebarContent}
6
+ value={sidebarValue}
7
+ header={sidebarHeader}
8
+ ontogglesidebar={onToggleSidebar}
9
+ languages={languages}
10
+ language={language}
11
+ bail-href={bailHref}
12
+ bail-label={bailLabel}
13
+ dev-center={devCenter}
14
+ brand={brand}
15
+ empty-state-message={emptyStateMessage}
16
+ >
17
+ <slot name="sidebar-header" slot="version-picker"></slot>
18
+ </dx-sidebar-old>
41
19
  <div class="content-body-doc-phase-container">
42
20
  <slot name="doc-phase"></slot>
43
21
  <slot name="version-banner"></slot>
@@ -32,11 +32,6 @@ export default class ContentLayout extends LightningElement {
32
32
  @api sidebarHeader!: string;
33
33
  @api tocTitle!: string;
34
34
  @api enableSlotChange = false;
35
- @api coveoOrganizationId!: string;
36
- @api coveoPublicAccessToken!: string;
37
- @api coveoAnalyticsToken!: string;
38
- @api coveoSearchHub!: string;
39
- @api coveoAdvancedQueryConfig!: string;
40
35
  @api useOldSidebar?: boolean = false;
41
36
  @api languages!: OptionWithLink[];
42
37
  @api language!: string;
@@ -44,6 +39,7 @@ export default class ContentLayout extends LightningElement {
44
39
  @api bailLabel!: string;
45
40
  @api devCenter: any;
46
41
  @api brand: any;
42
+ @api emptyStateMessage?: string;
47
43
 
48
44
  // This is needed for now to prevent failing snapshot tests due to links in the footer
49
45
  @api showFooter = false;
@@ -210,10 +206,7 @@ export default class ContentLayout extends LightningElement {
210
206
  We have to account for the global nav changing height due to animations.
211
207
  */
212
208
  adjustNavPosition = () => {
213
- const sidebarType = this.useOldSidebar
214
- ? "dx-sidebar-old"
215
- : "dx-sidebar";
216
- const sidebarEl = this.template.querySelector(sidebarType);
209
+ const sidebarEl = this.template.querySelector("dx-sidebar-old");
217
210
  const globalNavEl = document.querySelector(
218
211
  "hgf-c360nav"
219
212
  ) as HTMLElement;
@@ -248,65 +241,41 @@ export default class ContentLayout extends LightningElement {
248
241
  const docHeaderHeight = docHeaderEl.getBoundingClientRect().height;
249
242
  const totalHeaderHeight = globalNavHeight + docHeaderHeight;
250
243
 
251
- // Collect any banners rendered via the doc-phase and version-banner slots
252
- const versionBannerSlot = this.template.querySelector(
253
- "[name=version-banner]"
254
- ) as any;
255
- const docPhaseSlot = this.template.querySelector(
256
- "[name=doc-phase]"
257
- ) as any;
258
- const versionBannerEls = (
259
- versionBannerSlot
260
- ? (versionBannerSlot.assignedElements() as HTMLElement[])
261
- : []
262
- ) as HTMLElement[];
263
- const docPhaseEls = (
264
- docPhaseSlot
265
- ? (docPhaseSlot.assignedElements() as HTMLElement[])
266
- : []
267
- ) as HTMLElement[];
268
- const bannersTotalHeight = [
269
- ...versionBannerEls,
270
- ...docPhaseEls
271
- ].reduce(
272
- (sum, el) => sum + (el?.getBoundingClientRect()?.height || 0),
273
- 0
274
- );
275
-
276
244
  // Selecting the doc section heading and RNB here.
277
245
  const docHeadingEls = Array.from(
278
246
  document.querySelectorAll("doc-heading")
279
247
  );
280
248
  const rightNavBarEl = this.template.querySelector(".right-nav-bar");
281
249
 
282
- (sidebarEl as HTMLElement).style.setProperty(
250
+ sidebarEl.style.setProperty(
283
251
  "--dx-c-content-sidebar-sticky-top",
284
- `${totalHeaderHeight}px`
252
+ `${globalNavHeight + docHeaderHeight}px`
285
253
  );
286
254
 
287
255
  docHeaderEl.style.setProperty(
288
256
  "--dx-g-global-header-height",
289
257
  `${globalNavHeight}px`
290
258
  );
291
- // Expose heights as CSS variables for sticky offsets used by page content
292
- const rootStyle = document.documentElement.style;
293
- rootStyle.setProperty(
294
- "--dx-g-doc-header-banner-height",
295
- `${docHeaderHeight + bannersTotalHeight}px`
296
- );
297
259
 
298
260
  // Adjusting the doc section heading on scroll.
299
261
  docHeadingEls.forEach((docHeadingEl) => {
300
- (docHeadingEl as any).style.scrollMarginTop = `${
301
- totalHeaderHeight + bannersTotalHeight + 40
302
- }px`;
262
+ (docHeadingEl as any).style.scrollMarginTop = docPhaseEl
263
+ ? `${
264
+ totalHeaderHeight +
265
+ docPhaseEl.getBoundingClientRect().height +
266
+ 40
267
+ }px`
268
+ : `${totalHeaderHeight + 40}px`;
303
269
  });
304
270
 
305
271
  // Adjusting the right nav bar on scroll.
306
272
  if (rightNavBarEl) {
307
- (rightNavBarEl as HTMLElement).style.top = `${
308
- totalHeaderHeight + bannersTotalHeight
309
- }px`;
273
+ rightNavBarEl.style.top = docPhaseEl
274
+ ? `${
275
+ totalHeaderHeight +
276
+ docPhaseEl.getBoundingClientRect().height
277
+ }px`
278
+ : `${totalHeaderHeight}px`;
310
279
  }
311
280
 
312
281
  // If doc phase element exists, we need to account for its sticky position. Mobile should include the sidebar height (since it becomes sticky aswell).
@@ -1,43 +1,20 @@
1
1
  <template>
2
2
  <div class="content">
3
- <template lwc:if={useOldSidebar}>
4
- <dx-sidebar-old
5
- class="is-sticky left-nav-bar"
6
- trees={sidebarContent}
7
- value={sidebarValue}
8
- header={sidebarHeader}
9
- ontogglesidebar={onToggleSidebar}
10
- languages={languages}
11
- language={language}
12
- bail-href={bailHref}
13
- bail-label={bailLabel}
14
- dev-center={devCenter}
15
- brand={brand}
16
- >
17
- <slot name="sidebar-header" slot="version-picker"></slot>
18
- </dx-sidebar-old>
19
- </template>
20
- <template lwc:else>
21
- <dx-sidebar
22
- class="is-sticky left-nav-bar"
23
- trees={sidebarContent}
24
- value={sidebarValue}
25
- header={sidebarHeader}
26
- coveo-organization-id={coveoOrganizationId}
27
- coveo-public-access-token={coveoPublicAccessToken}
28
- coveo-search-hub={coveoSearchHub}
29
- coveo-advanced-query-config={coveoAdvancedQueryConfig}
30
- ontogglesidebar={onToggleSidebar}
31
- languages={languages}
32
- language={language}
33
- bail-href={bailHref}
34
- bail-label={bailLabel}
35
- dev-center={devCenter}
36
- brand={brand}
37
- >
38
- <slot name="sidebar-header" slot="version-picker"></slot>
39
- </dx-sidebar>
40
- </template>
3
+ <dx-sidebar-old
4
+ class="is-sticky left-nav-bar"
5
+ trees={sidebarContent}
6
+ value={sidebarValue}
7
+ header={sidebarHeader}
8
+ ontogglesidebar={onToggleSidebar}
9
+ languages={languages}
10
+ language={language}
11
+ bail-href={bailHref}
12
+ bail-label={bailLabel}
13
+ dev-center={devCenter}
14
+ brand={brand}
15
+ >
16
+ <slot name="sidebar-header" slot="version-picker"></slot>
17
+ </dx-sidebar-old>
41
18
  <div class="content-body-doc-phase-container">
42
19
  <slot name="doc-phase"></slot>
43
20
  <slot name="version-banner"></slot>
@@ -2,44 +2,111 @@ import ContentLayout from "doc/contentLayout";
2
2
 
3
3
  const TOC_HEADER_TAG = "doc-heading";
4
4
  const RNB_BY_TAB = "docs-tab";
5
- const SPECIFICATION_TAB_TITLE = "Specification";
5
+ const SPECIFICATION_TAG = "doc-specification-content";
6
6
  export const OBSERVER_ATTACH_WAIT_TIME = 500;
7
7
 
8
8
  export default class LwcContentLayout extends ContentLayout {
9
9
  private rnbByTab: boolean = false;
10
10
 
11
+ // DOM element caches to avoid repeated queries
12
+ private tabPanelListCache: any = null;
13
+ private hasSpecContentCache: boolean | null = null;
14
+ private allTabsCache: any[] | null = null;
15
+ private mainSlotCache: any = null;
16
+
11
17
  private setRNBByTab() {
12
- const tabPanelListItem: any = this.getTabPanelList();
13
- this.rnbByTab = tabPanelListItem?.id === RNB_BY_TAB ? true : false;
18
+ const tabPanelListItem = this.getTabPanelList();
19
+ this.rnbByTab = tabPanelListItem?.id === RNB_BY_TAB;
14
20
  }
15
21
 
16
22
  get showTabBasedRNB() {
17
23
  return this.rnbByTab;
18
24
  }
19
25
 
26
+ /**
27
+ * Check if the main slot contains doc-specification-content
28
+ * Uses caching to avoid repeated DOM queries
29
+ */
30
+ private hasSpecificationContent(): boolean {
31
+ if (this.hasSpecContentCache !== null) {
32
+ return this.hasSpecContentCache;
33
+ }
34
+
35
+ const mainSlot = this.getMainSlot();
36
+ if (mainSlot) {
37
+ const assignedElements = (mainSlot as any).assignedElements();
38
+
39
+ for (const element of assignedElements) {
40
+ if (
41
+ element.tagName === SPECIFICATION_TAG ||
42
+ element.querySelector(SPECIFICATION_TAG) ||
43
+ element.shadowRoot?.querySelector(SPECIFICATION_TAG)
44
+ ) {
45
+ return (this.hasSpecContentCache = true);
46
+ }
47
+ }
48
+ }
49
+ return (this.hasSpecContentCache = false);
50
+ }
51
+
52
+ /**
53
+ * Clear all caches when content changes
54
+ */
55
+ private clearAllCaches(): void {
56
+ this.hasSpecContentCache = null;
57
+ this.tabPanelListCache = null;
58
+ this.allTabsCache = null;
59
+ this.mainSlotCache = null;
60
+ }
61
+
62
+ /**
63
+ * Get the main slot element with caching
64
+ */
65
+ private getMainSlot(): any {
66
+ if (!this.mainSlotCache) {
67
+ this.mainSlotCache =
68
+ this.template.querySelector("slot:not([name])");
69
+ }
70
+ return this.mainSlotCache;
71
+ }
72
+
73
+ /**
74
+ * Get tab panel list with caching
75
+ */
76
+ private getTabPanelList(): any {
77
+ if (!this.tabPanelListCache) {
78
+ // eslint-disable-next-line @lwc/lwc/no-document-query
79
+ this.tabPanelListCache =
80
+ document.querySelector("dx-tab-panel-list");
81
+ }
82
+ return this.tabPanelListCache;
83
+ }
84
+
20
85
  onRNBClick = (event: CustomEvent) => {
21
86
  event.stopPropagation();
22
- const currentTab = this.getSelectedTabId();
23
- if (currentTab === SPECIFICATION_TAB_TITLE) {
87
+ if (this.hasSpecificationContent()) {
24
88
  this.didScrollToSelectedHash = false;
25
89
  }
26
90
  };
27
91
 
28
92
  onTabChanged = () => {
29
93
  this.updateRNB();
30
- };
31
94
 
32
- private getTabPanelList() {
33
- // eslint-disable-next-line @lwc/lwc/no-document-query
34
- return document.querySelector("dx-tab-panel-list");
35
- }
95
+ const { hash } = window.location;
96
+ if (this.hasSpecificationContent() && hash) {
97
+ this.didScrollToSelectedHash = false;
98
+
99
+ requestAnimationFrame(() => this.updateHeadingForRNB());
100
+ }
101
+ };
36
102
 
37
103
  protected getHeadingElements() {
38
104
  let headingElements = super.getHeadingElements();
39
105
  if (this.showTabBasedRNB) {
40
- const tabPanelListItem: any = this.getTabPanelList();
106
+ const tabPanelListItem = this.getTabPanelList();
41
107
  const tabPanels =
42
108
  tabPanelListItem?.querySelectorAll("dx-tab-panel");
109
+
43
110
  for (const tabPanelItem of tabPanels) {
44
111
  if (tabPanelItem.active) {
45
112
  // This is needed for Specification tab content
@@ -65,6 +132,7 @@ export default class LwcContentLayout extends ContentLayout {
65
132
  private updateURL() {
66
133
  const tabs = this.getAllTabs();
67
134
  const selectedTabId = this.getSelectedTabId();
135
+
68
136
  tabs.forEach((tab: any) => {
69
137
  if (tab.getAttribute("aria-selected") === "true") {
70
138
  const tabID = tab.getAttribute("aria-label");
@@ -101,22 +169,38 @@ export default class LwcContentLayout extends ContentLayout {
101
169
  const selectedTabId = this.getSelectedTabId();
102
170
  if (selectedTabId) {
103
171
  this.selectTabById(selectedTabId);
172
+
173
+ // If there's a hash and we have specification content,
174
+ // we need to wait for the content to load before scrolling
175
+ const { hash } = window.location;
176
+ if (this.hasSpecificationContent() && hash) {
177
+ // Reset the scroll flag to allow scrolling once content is loaded
178
+ this.didScrollToSelectedHash = false;
179
+ }
104
180
  }
105
181
  });
106
182
  }
107
183
 
108
184
  private getAllTabs(): any[] {
109
- const tabPanelListItem: any = this.getTabPanelList();
185
+ // Return cached result if available
186
+ if (this.allTabsCache) {
187
+ return this.allTabsCache;
188
+ }
189
+
190
+ const tabPanelListItem = this.getTabPanelList();
110
191
  if (tabPanelListItem?.shadowRoot) {
111
- return Array.from(
192
+ this.allTabsCache = Array.from(
112
193
  tabPanelListItem.shadowRoot.querySelectorAll(
113
194
  "dx-tab-panel-item"
114
195
  )
115
196
  ).map((tabPanelItem: any) =>
116
197
  tabPanelItem.shadowRoot.querySelector("button")
117
198
  );
199
+ } else {
200
+ this.allTabsCache = [];
118
201
  }
119
- return [];
202
+
203
+ return this.allTabsCache;
120
204
  }
121
205
 
122
206
  private selectTabById(tabId: string) {
@@ -158,8 +242,12 @@ export default class LwcContentLayout extends ContentLayout {
158
242
  }
159
243
  }
160
244
 
245
+ onSlotChange(): void {
246
+ this.clearAllCaches();
247
+ super.onSlotChange();
248
+ }
249
+
161
250
  updateHeadingForRNB(): void {
162
- // We only need to update URL in case of /docs and ignore if tabs are used anywhere else in DSC
163
251
  if (this.showTabBasedRNB) {
164
252
  this.updateURL();
165
253
  }
@@ -73,9 +73,7 @@
73
73
  <template lwc:if={method.firstArgument}>
74
74
  <tr key={method.name}>
75
75
  <td rowspan={method.arguments.length}>
76
- <span class="code">
77
- {method.nameInKebabCase}
78
- </span>
76
+ <span class="code">{method.name}</span>
79
77
  </td>
80
78
  <td rowspan={method.arguments.length}>
81
79
  {method.description}
@@ -100,9 +98,7 @@
100
98
  <template lwc:else>
101
99
  <tr key={method.name}>
102
100
  <td>
103
- <span class="code">
104
- {method.nameInKebabCase}
105
- </span>
101
+ <span class="code">{method.name}</span>
106
102
  </td>
107
103
  <td>{method.description}</td>
108
104
  <td colspan="3"></td>
@@ -2,16 +2,10 @@
2
2
  <doc-content-layout
3
3
  lwc:if={displayContent}
4
4
  lwc:ref="docContentLayout"
5
- coveo-organization-id={coveoOrganizationId}
6
- coveo-public-access-token={coveoPublicAccessToken}
7
- coveo-analytics-token={coveoAnalyticsToken}
8
- coveo-search-hub={coveoSearchHub}
9
- coveo-advanced-query-config={coveoAdvancedQueryConfig}
10
5
  sidebar-header={docTitle}
11
6
  sidebar-content={sidebarContent}
12
7
  sidebar-value={sidebarValue}
13
8
  onselect={handleSelect}
14
- use-old-sidebar={useOldSidebar}
15
9
  onlangchange={handleLanguageChange}
16
10
  languages={sidebarFooterContent.languages}
17
11
  language={sidebarFooterContent.language}
@@ -1,9 +1,7 @@
1
1
  /* eslint-disable @lwc/lwc/no-document-query */
2
2
  import { api, track } from "lwc";
3
- import { normalizeBoolean } from "dxUtils/normalizers";
4
3
  import { FetchContent } from "./utils";
5
4
  import {
6
- CoveoAdvancedQueryXMLConfig,
7
5
  DocLanguage,
8
6
  DocVersion,
9
7
  TreeNode,
@@ -16,7 +14,7 @@ import {
16
14
  } from "./types";
17
15
  import { SearchSyncer } from "docUtils/searchSyncer";
18
16
  import { LightningElementWithState } from "dxBaseElements/lightningElementWithState";
19
- import { logCoveoPageView, oldVersionDocInfo } from "docUtils/utils";
17
+ import { oldVersionDocInfo } from "docUtils/utils";
20
18
  import { Breadcrumb, DocPhaseInfo, Language } from "typings/custom";
21
19
  import { track as trackGTM } from "dxUtils/analytics";
22
20
  import DOMPurify from "dompurify";
@@ -42,10 +40,6 @@ export default class DocXmlContent extends LightningElementWithState<{
42
40
  internalLinkClicked: boolean;
43
41
  }> {
44
42
  @api apiDomain = "https://developer.salesforce.com";
45
- @api coveoOrganizationId!: string;
46
- @api coveoPublicAccessToken!: string;
47
- @api coveoAnalyticsToken!: string;
48
- @api coveoSearchHub!: string;
49
43
  @api hideFooter = false;
50
44
 
51
45
  @api
@@ -59,15 +53,6 @@ export default class DocXmlContent extends LightningElementWithState<{
59
53
  }
60
54
  }
61
55
 
62
- @api
63
- get enableCoveo() {
64
- return this._enableCoveo;
65
- }
66
-
67
- set enableCoveo(value) {
68
- this._enableCoveo = normalizeBoolean(value);
69
- }
70
-
71
56
  private availableLanguages: Array<DocLanguage> = [];
72
57
  @track private availableVersions: Array<DocVersion> = [];
73
58
  private contentProvider?: FetchContent;
@@ -83,7 +68,6 @@ export default class DocXmlContent extends LightningElementWithState<{
83
68
  private docTitle = "";
84
69
  private _pathName = "";
85
70
  private listenerAttached = false;
86
- private _enableCoveo?: boolean = false;
87
71
  private sidebarFooterContent: SiderbarFooter = { ...defaultSidebarFooter };
88
72
  private latestVersion = false;
89
73
  private previewVersion = false;
@@ -260,35 +244,13 @@ export default class DocXmlContent extends LightningElementWithState<{
260
244
  // Coveo is enabled and the version is greater than 51 (within the latest 3 versions)
261
245
  // TODO: we need a better fix for version number check
262
246
  return !(
263
- this.enableCoveo &&
264
- this.coveoOrganizationId &&
265
- this.coveoPublicAccessToken &&
266
- (!this.version?.releaseVersion ||
267
- (this.version?.releaseVersion &&
268
- parseInt(
269
- this.version.releaseVersion.replace("v", ""),
270
- 10
271
- ) >= 53))
247
+ !this.version?.releaseVersion ||
248
+ (this.version?.releaseVersion &&
249
+ parseInt(this.version.releaseVersion.replace("v", ""), 10) >=
250
+ 53)
272
251
  );
273
252
  }
274
253
 
275
- private get coveoAdvancedQueryConfig(): CoveoAdvancedQueryXMLConfig {
276
- const config: {
277
- locale?: string;
278
- topicid?: string;
279
- version?: string;
280
- } = {
281
- locale: this.languageId,
282
- topicid: this.deliverable
283
- };
284
-
285
- if (this.releaseVersionId && this.releaseVersionId !== "noversion") {
286
- config.version = this.releaseVersionId;
287
- }
288
-
289
- return config;
290
- }
291
-
292
254
  private get pageHeader(): Header {
293
255
  if (!this._pageHeader) {
294
256
  this._pageHeader = document.querySelector("doc-header")!;
@@ -589,7 +551,6 @@ export default class DocXmlContent extends LightningElementWithState<{
589
551
  }
590
552
 
591
553
  updateUrl(method = HistoryState.PUSH_STATE): void {
592
- logCoveoPageView(this.coveoOrganizationId, this.coveoAnalyticsToken);
593
554
  window.history[method](
594
555
  {},
595
556
  "docs",
@@ -1,267 +0,0 @@
1
- /* stylelint-disable selector-class-pattern */
2
-
3
- /* Table wrapper for overflow handling */
4
- .doc-table-wrapper {
5
- margin: 16px 0;
6
-
7
- /* Ensure sticky positioning context */
8
- position: relative;
9
- }
10
-
11
- /* Only add horizontal scroll when sticky headers are disabled */
12
- .doc-table-wrapper:not(.doc-table-wrapper--sticky-headers) {
13
- overflow-x: auto;
14
- }
15
-
16
- /* When sticky headers are enabled, remove overflow to allow sticky positioning */
17
- .doc-table-wrapper--sticky-headers {
18
- overflow-x: visible;
19
- }
20
-
21
- /* GitHub markdown table styles - exact replication */
22
- .doc-table {
23
- border-spacing: 0;
24
- border-collapse: collapse;
25
- display: table;
26
- width: max-content;
27
- max-width: 100%;
28
- overflow: auto;
29
- font-size: 14px;
30
- line-height: 1.45;
31
- color: #1f2328;
32
- }
33
-
34
- /* Table caption - GitHub style */
35
- .doc-table__caption {
36
- caption-side: top;
37
- padding: 8px 0;
38
- font-weight: 600;
39
- color: #656d76;
40
- text-align: left;
41
- font-size: 14px;
42
- }
43
-
44
- /* Header and cell base styles */
45
- .doc-table__header-cell,
46
- .doc-table__cell {
47
- padding: 6px 13px;
48
- border: 1px solid #d1d9e0;
49
- }
50
-
51
- /* Header specific styles */
52
- .doc-table__header-cell {
53
- font-weight: 600;
54
- background-color: #f6f8fa;
55
- text-align: left;
56
- }
57
-
58
- /* Body cell styles */
59
- .doc-table__cell {
60
- background-color: #fff;
61
- }
62
-
63
- /* Row hover effect - subtle like GitHub */
64
- .doc-table__row:hover .doc-table__cell {
65
- background-color: #f6f8fa;
66
- }
67
-
68
- /* Sticky headers */
69
- .doc-table--sticky-headers .doc-table__header-cell {
70
- position: sticky;
71
- top: calc(
72
- var(--dx-g-global-header-height) +
73
- var(--dx-g-doc-header-banner-height, 0px)
74
- );
75
- z-index: 10;
76
-
77
- /* Ensure background is maintained when sticky */
78
- background-color: #f6f8fa;
79
- }
80
-
81
- /* Bordered table variant - enhanced GitHub style */
82
- .doc-table--bordered {
83
- border: 1px solid #d1d9e0;
84
- border-radius: 6px;
85
- overflow: hidden;
86
- }
87
-
88
- .doc-table--bordered .doc-table__header-cell:first-child,
89
- .doc-table--bordered .doc-table__cell:first-child {
90
- border-left: none;
91
- }
92
-
93
- .doc-table--bordered .doc-table__header-cell:last-child,
94
- .doc-table--bordered .doc-table__cell:last-child {
95
- border-right: none;
96
- }
97
-
98
- /* Striped table variant - GitHub style alternating rows */
99
- .doc-table--striped .doc-table__row:nth-child(even) .doc-table__cell {
100
- background-color: #f6f8fa;
101
- }
102
-
103
- .doc-table--striped .doc-table__row:nth-child(even):hover .doc-table__cell {
104
- background-color: #eaeef2;
105
- }
106
-
107
- /* Links within table cells - GitHub style */
108
- .doc-table__cell a {
109
- color: #0969da;
110
- text-decoration: none;
111
- }
112
-
113
- .doc-table__cell a:hover {
114
- text-decoration: underline;
115
- }
116
-
117
- .doc-table__cell a:visited {
118
- color: #8250df;
119
- }
120
-
121
- /* Code within table cells - GitHub style */
122
- .doc-table__cell code {
123
- padding: 0.2em 0.4em;
124
- margin: 0;
125
- font-size: 85%;
126
- white-space: break-spaces;
127
- background-color: rgb(175 184 193 / 20%);
128
- border-radius: 6px;
129
- font-family: ui-monospace, SFMono-Regular, "SF Mono", Consolas,
130
- "Liberation Mono", Menlo, monospace;
131
- }
132
-
133
- /* Strong/bold text in cells */
134
- .doc-table__cell strong,
135
- .doc-table__cell b {
136
- font-weight: 600;
137
- }
138
-
139
- /* Emphasis/italic text in cells */
140
- .doc-table__cell em,
141
- .doc-table__cell i {
142
- font-style: italic;
143
- }
144
-
145
- /* Empty state - GitHub inspired */
146
- .doc-table__empty {
147
- padding: 32px;
148
- text-align: center;
149
- border: 1px solid #d1d9e0;
150
- border-radius: 6px;
151
- background-color: #f6f8fa;
152
- margin: 16px 0;
153
- }
154
-
155
- .doc-table__empty-message {
156
- color: #656d76;
157
- font-style: italic;
158
- margin: 0;
159
- font-size: 14px;
160
- }
161
-
162
- /* Responsive design - GitHub mobile behavior */
163
- @media (max-width: 768px) {
164
- .doc-table-wrapper {
165
- margin-left: -16px;
166
- margin-right: -16px;
167
- }
168
-
169
- .doc-table {
170
- font-size: 12px;
171
- }
172
-
173
- .doc-table__header-cell,
174
- .doc-table__cell {
175
- padding: 4px 8px;
176
- }
177
-
178
- /* Adjust sticky header position for mobile */
179
- .doc-table--sticky-headers .doc-table__header-cell {
180
- top: calc(
181
- var(--dx-g-global-header-height) +
182
- var(--dx-g-doc-header-banner-height, 0px)
183
- );
184
- }
185
- }
186
-
187
- /* Dark mode support (GitHub style) */
188
- @media (prefers-color-scheme: dark) {
189
- .doc-table {
190
- color: #f0f6fc;
191
- }
192
-
193
- .doc-table__header-cell,
194
- .doc-table__cell {
195
- border-color: #30363d;
196
- }
197
-
198
- .doc-table__header-cell {
199
- background-color: #161b22;
200
- }
201
-
202
- /* Ensure sticky headers maintain background in dark mode */
203
- .doc-table--sticky-headers .doc-table__header-cell {
204
- background-color: #161b22;
205
- }
206
-
207
- .doc-table__cell {
208
- background-color: #0d1117;
209
- }
210
-
211
- .doc-table__row:hover .doc-table__cell {
212
- background-color: #161b22;
213
- }
214
-
215
- .doc-table--striped .doc-table__row:nth-child(even) .doc-table__cell {
216
- background-color: #161b22;
217
- }
218
-
219
- .doc-table--striped .doc-table__row:nth-child(even):hover .doc-table__cell {
220
- background-color: #21262d;
221
- }
222
-
223
- .doc-table__caption {
224
- color: #8b949e;
225
- }
226
-
227
- .doc-table__empty {
228
- background-color: #161b22;
229
- border-color: #30363d;
230
- }
231
-
232
- .doc-table__empty-message {
233
- color: #8b949e;
234
- }
235
-
236
- .doc-table__cell a {
237
- color: #58a6ff;
238
- }
239
-
240
- .doc-table__cell a:visited {
241
- color: #bc8cff;
242
- }
243
-
244
- .doc-table__cell code {
245
- background-color: rgb(110 118 129 / 40%);
246
- }
247
- }
248
-
249
- /* High contrast mode support */
250
- @media (prefers-contrast: high) {
251
- .doc-table__header-cell,
252
- .doc-table__cell {
253
- border: 1px solid;
254
- }
255
-
256
- .doc-table__row:hover .doc-table__cell {
257
- background-color: highlight;
258
- color: highlighttext;
259
- }
260
- }
261
-
262
- /* Reduced motion support */
263
- @media (prefers-reduced-motion: reduce) {
264
- .doc-table__row:hover .doc-table__cell {
265
- transition: none;
266
- }
267
- }
@@ -1,46 +0,0 @@
1
- <template>
2
- <div class={wrapperClasses} if:true={hasData}>
3
- <table class={tableClasses}>
4
- <!-- Caption -->
5
- <caption if:true={caption} class="doc-table__caption">
6
- {caption}
7
- </caption>
8
- <!-- Table Header -->
9
- <thead class="doc-table__head">
10
- <tr class="doc-table__header-row">
11
- <th
12
- for:each={columns}
13
- for:item="column"
14
- key={column.key}
15
- class="doc-table__header-cell"
16
- scope="col"
17
- >
18
- {column.label}
19
- </th>
20
- </tr>
21
- </thead>
22
- <!-- Table Body -->
23
- <tbody class="doc-table__body">
24
- <tr
25
- for:each={processedRows}
26
- for:item="row"
27
- key={row.id}
28
- class="doc-table__row"
29
- >
30
- <td
31
- for:each={row.cells}
32
- for:item="cell"
33
- key={cell.key}
34
- class="doc-table__cell"
35
- >
36
- {cell.value}
37
- </td>
38
- </tr>
39
- </tbody>
40
- </table>
41
- </div>
42
- <!-- Empty state -->
43
- <div class="doc-table__empty" if:false={hasData}>
44
- <p class="doc-table__empty-message">No data available</p>
45
- </div>
46
- </template>
@@ -1,175 +0,0 @@
1
- import { LightningElement, api } from "lwc";
2
-
3
- interface TableColumn {
4
- key: string;
5
- label: string;
6
- type?: "text" | "link" | "html";
7
- }
8
-
9
- interface TableRow {
10
- [key: string]: any;
11
- }
12
-
13
- interface TableData {
14
- columns: TableColumn[];
15
- rows: TableRow[];
16
- }
17
-
18
- export default class Table extends LightningElement {
19
- @api caption: string = "";
20
-
21
- private _striped: boolean = false;
22
- private _bordered: boolean = false;
23
- private _stickyHeaders: boolean = false;
24
-
25
- @api
26
- get striped(): boolean {
27
- return this._striped;
28
- }
29
- set striped(value: boolean | string) {
30
- this._striped = this.toBooleanValue(value);
31
- }
32
-
33
- @api
34
- get bordered(): boolean {
35
- return this._bordered;
36
- }
37
- set bordered(value: boolean | string) {
38
- this._bordered = this.toBooleanValue(value);
39
- }
40
-
41
- @api
42
- get stickyHeaders(): boolean {
43
- return this._stickyHeaders;
44
- }
45
- set stickyHeaders(value: boolean | string) {
46
- this._stickyHeaders = this.toBooleanValue(value);
47
- }
48
-
49
- private _tableData: TableData = { columns: [], rows: [] };
50
-
51
- @api
52
- get tableData(): string | TableData {
53
- return this._tableData;
54
- }
55
-
56
- set tableData(value: string | TableData) {
57
- if (typeof value === "string") {
58
- // Handle the case where object is stringified as "[object Object]"
59
- if (value === "[object Object]") {
60
- console.error(
61
- "Invalid JSON provided to table component: Object was not properly serialized. Use property binding (.table-data) instead of attribute binding (table-data) for objects."
62
- );
63
- this._tableData = { columns: [], rows: [] };
64
- return;
65
- }
66
-
67
- try {
68
- this._tableData = JSON.parse(value);
69
- } catch (error) {
70
- console.error(
71
- "Invalid JSON provided to table component:",
72
- error
73
- );
74
- this._tableData = { columns: [], rows: [] };
75
- }
76
- } else if (value) {
77
- this._tableData = value as TableData;
78
- } else {
79
- this._tableData = { columns: [], rows: [] };
80
- }
81
- }
82
-
83
- get columns(): TableColumn[] {
84
- return this._tableData?.columns || [];
85
- }
86
-
87
- get rows(): TableRow[] {
88
- return this._tableData?.rows || [];
89
- }
90
-
91
- get hasData(): boolean {
92
- return this.columns.length > 0 && this.rows.length > 0;
93
- }
94
-
95
- get wrapperClasses(): string {
96
- const classes = ["doc-table-wrapper"];
97
-
98
- if (this.stickyHeaders) {
99
- classes.push("doc-table-wrapper--sticky-headers");
100
- }
101
-
102
- return classes.join(" ");
103
- }
104
-
105
- get tableClasses(): string {
106
- const classes = ["doc-table"];
107
-
108
- if (this.striped) {
109
- classes.push("doc-table--striped");
110
- }
111
-
112
- if (this.bordered) {
113
- classes.push("doc-table--bordered");
114
- }
115
-
116
- if (this.stickyHeaders) {
117
- classes.push("doc-table--sticky-headers");
118
- }
119
- return classes.join(" ");
120
- }
121
-
122
- get processedRows(): Array<{
123
- id: string;
124
- cells: Array<{ key: string; value: any; type: string }>;
125
- }> {
126
- return this.rows.map((row, index) => ({
127
- id: `row-${index}`,
128
- cells: this.columns.map((column) => ({
129
- key: column.key,
130
- value: row[column.key] || "",
131
- type: column.type || "text"
132
- }))
133
- }));
134
- }
135
-
136
- private renderCellContent(value: any, type: string): string {
137
- if (value === null || value === undefined) {
138
- return "";
139
- }
140
-
141
- switch (type) {
142
- case "html":
143
- return value.toString();
144
- case "link":
145
- if (typeof value === "object" && value.url && value.text) {
146
- return `<a href="${value.url}" target="_blank" rel="noopener noreferrer">${value.text}</a>`;
147
- }
148
- return value.toString();
149
- case "text":
150
- default:
151
- return value.toString();
152
- }
153
- }
154
-
155
- // Method to handle cell content rendering in the template
156
- getCellContent(value: any, type: string): string {
157
- return this.renderCellContent(value, type);
158
- }
159
-
160
- // Method to check if cell content should be rendered as HTML
161
- isHtmlCell(type: string): boolean {
162
- return type === "html" || type === "link";
163
- }
164
-
165
- // Helper method to convert string/boolean values to boolean
166
- private toBooleanValue(value: boolean | string): boolean {
167
- if (typeof value === "boolean") {
168
- return value;
169
- }
170
- if (typeof value === "string") {
171
- return value.toLowerCase() === "true";
172
- }
173
- return false;
174
- }
175
- }