@salesforcedevs/dx-components 1.40.11 → 1.42.0-final-test
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 +4 -2
- package/package.json +46 -47
- package/src/modules/dx/button/button.css +2 -2
- package/src/modules/dx/dropdown/dropdown.css +29 -1
- package/src/modules/dx/dropdown/dropdown.html +1 -1
- package/src/modules/dx/dropdown/dropdown.ts +16 -1
- package/src/modules/dx/dropdownOption/dropdownOption.css +30 -6
- package/src/modules/dx/filterMenu/filterMenu.css +19 -0
- package/src/modules/dx/filterMenu/filterMenu.html +17 -2
- package/src/modules/dx/filterMenu/filterMenu.ts +43 -0
- package/src/modules/dx/popover/popover.ts +119 -7
- package/src/modules/dx/searchHybrid/searchHybrid.css +56 -61
- package/src/modules/dx/searchHybrid/searchHybrid.html +133 -112
- package/src/modules/dx/searchHybrid/searchHybrid.mock.ts +244 -0
- package/src/modules/dx/searchHybrid/searchHybrid.ts +81 -26
- package/src/modules/dx/searchResults/searchResults.css +119 -6
- package/src/modules/dx/searchResults/searchResults.html +89 -91
- package/src/modules/dx/searchResults/searchResults.ts +200 -473
- package/src/modules/dx/sidebar/sidebar.css +1 -0
- package/src/modules/dx/sidebar/sidebar.html +2 -5
- package/src/modules/dx/sidebar/sidebar.ts +44 -29
- package/src/modules/dx/sidebarOld/sidebarOld.html +1 -0
- package/src/modules/dx/sidebarSearch/sidebarSearch.ts +163 -342
- package/src/modules/dx/sidebarSearchResult/sidebarSearchResult.css +61 -23
- package/src/modules/dx/sidebarSearchResult/sidebarSearchResult.ts +12 -4
- package/src/modules/dx/tree/tree.html +1 -0
- package/src/modules/dx/tree/tree.ts +5 -1
- package/src/modules/dx/tree/treeHandler.ts +92 -13
- package/src/modules/dx/treeItem/treeItem.css +41 -0
- package/src/modules/dx/treeItem/treeItem.html +17 -2
- package/src/modules/dx/treeItem/treeItem.ts +109 -11
- package/src/modules/dx/treeTile/treeTile.css +57 -0
- package/src/modules/dx/treeTile/treeTile.ts +12 -3
- package/src/modules/dx/typeBadge/typeBadge.ts +23 -2
- package/src/modules/dx/versionPicker/versionPicker.css +248 -0
- package/src/modules/dx/versionPicker/versionPicker.html +73 -0
- package/src/modules/dx/versionPicker/versionPicker.ts +157 -0
- package/src/modules/dxHelpers/commonSidebar/commonSidebar.css +3 -3
- package/src/modules/dxHelpers/commonTreeItem/commonTreeItem.css +4 -0
- package/src/modules/dxHelpers/typeBadge/typeBadge.css +22 -0
- package/src/modules/dxUtils/openSearch/openSearch.ts +343 -0
- package/src/modules/dxUtils/topicVersion/topicVersion.ts +758 -0
- package/LICENSE +0 -12
|
@@ -1,75 +1,68 @@
|
|
|
1
1
|
import { LightningElement, api } from "lwc";
|
|
2
2
|
import debounce from "debounce";
|
|
3
|
+
import { track as trackGTM } from "dxUtils/analytics";
|
|
3
4
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
SearchAppState,
|
|
16
|
-
loadQueryActions
|
|
17
|
-
} from "@coveo/headless";
|
|
18
|
-
import { buildSearchEngine, getSidebarSearchParams } from "dxUtils/coveo";
|
|
5
|
+
type OpenSearchCacheItem,
|
|
6
|
+
type OpenSearchResultItem,
|
|
7
|
+
fetchSearch,
|
|
8
|
+
resultHref,
|
|
9
|
+
getBaseUrlPath,
|
|
10
|
+
isCurrentLocation,
|
|
11
|
+
getStoredSearch,
|
|
12
|
+
isCacheStale,
|
|
13
|
+
setStoredSearch
|
|
14
|
+
} from "dxUtils/openSearch";
|
|
15
|
+
import { createSearchRegExp } from "dxUtils/regexps";
|
|
19
16
|
import { RecentSearches } from "dxUtils/recentSearches";
|
|
20
|
-
import { toJson } from "dxUtils/normalizers";
|
|
21
17
|
import {
|
|
18
|
+
type HighlightedSections,
|
|
22
19
|
Option,
|
|
23
20
|
PopoverRequestCloseType,
|
|
24
21
|
SidebarSearchResult
|
|
25
22
|
} from "typings/custom";
|
|
26
23
|
|
|
27
|
-
const RESULT_CLICK_LOCAL_STORAGE_KEY = "dx-sidebar-search-result-click";
|
|
28
|
-
export const SESSION_KEY = "dx-sidebar-search-state";
|
|
29
|
-
|
|
30
|
-
const DEFAULT_RESULT_COUNT = 20;
|
|
31
24
|
const SEARCH_DEBOUNCE_DELAY = 1200;
|
|
32
25
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return this._coveoAdvancedQueryConfig;
|
|
26
|
+
/**
|
|
27
|
+
* Find all matches of the search query in text and return ranges for highlighting.
|
|
28
|
+
* Uses the same regex as the full-doc highlighter (createSearchRegExp) so sidebar
|
|
29
|
+
* and doc highlight the same phrases (including spaces between words).
|
|
30
|
+
*/
|
|
31
|
+
function getHighlightRanges(
|
|
32
|
+
text: string,
|
|
33
|
+
searchQuery: string
|
|
34
|
+
): HighlightedSections {
|
|
35
|
+
if (!text || !searchQuery.trim()) {
|
|
36
|
+
return [];
|
|
45
37
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
this._coveoAdvancedQueryConfig = jsonValue;
|
|
38
|
+
const re = createSearchRegExp(searchQuery.trim());
|
|
39
|
+
const ranges: HighlightedSections = [];
|
|
40
|
+
let match: RegExpExecArray | null;
|
|
41
|
+
while ((match = re.exec(text)) !== null) {
|
|
42
|
+
ranges.push({ offset: match.index, length: match[0].length });
|
|
43
|
+
}
|
|
44
|
+
return ranges;
|
|
45
|
+
}
|
|
55
46
|
|
|
56
|
-
|
|
57
|
-
this.dispatchOnLoading(true);
|
|
58
|
-
}
|
|
47
|
+
const UserRecentSearches = new RecentSearches();
|
|
59
48
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
49
|
+
function applySelectedAndSelect(
|
|
50
|
+
items: OpenSearchCacheItem[]
|
|
51
|
+
): SidebarSearchResult[] {
|
|
52
|
+
return items.map((item) => ({
|
|
53
|
+
...item,
|
|
54
|
+
selected: isCurrentLocation(item.href),
|
|
55
|
+
select: () => {}
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
66
58
|
|
|
59
|
+
const getSearchQueryParam = (): string =>
|
|
60
|
+
new URLSearchParams(window.location.search).get("q") ?? "";
|
|
61
|
+
|
|
62
|
+
export default class SidebarSearch extends LightningElement {
|
|
67
63
|
@api
|
|
68
64
|
public fetchMoreResults() {
|
|
69
|
-
|
|
70
|
-
this.fetchingMoreResults = true;
|
|
71
|
-
this.resultList.fetchMoreResults();
|
|
72
|
-
}
|
|
65
|
+
// OpenSearch API does not expose pagination in the same way; no-op
|
|
73
66
|
}
|
|
74
67
|
|
|
75
68
|
@api
|
|
@@ -85,313 +78,150 @@ export default class SidebarSearch extends LightningElement {
|
|
|
85
78
|
this.dropdownRequestedOpen = value;
|
|
86
79
|
}
|
|
87
80
|
|
|
88
|
-
private _coveoAdvancedQueryConfig!: { [key: string]: any };
|
|
89
81
|
private dropdownRequestedOpen: boolean = false;
|
|
90
82
|
private recentSearches: Option[] = [];
|
|
91
|
-
private
|
|
92
|
-
private resultList: ResultList | null = null;
|
|
93
|
-
private resultsPerPage: ResultsPerPage | null = null;
|
|
94
|
-
private preloadedState?: SearchAppState;
|
|
95
|
-
private searchBox: SearchBox | null = null;
|
|
96
|
-
private value?: string = "";
|
|
97
|
-
private engine: SearchEngine | null = null;
|
|
98
|
-
private fetchingMoreResults: boolean = false;
|
|
83
|
+
private value: string = "";
|
|
99
84
|
private didRender = false;
|
|
100
|
-
|
|
101
|
-
private
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
this.coveoPublicAccessToken,
|
|
105
|
-
this.coveoSearchHub,
|
|
106
|
-
this.coveoAdvancedQueryConfig
|
|
107
|
-
];
|
|
108
|
-
|
|
109
|
-
return coveoConfigurations.every(
|
|
110
|
-
(val) =>
|
|
111
|
-
!!val && (typeof val === "string" || typeof val === "object")
|
|
112
|
-
);
|
|
113
|
-
}
|
|
85
|
+
private openSearchInitialized: boolean = false;
|
|
86
|
+
private didTrackThisSearch: boolean = false;
|
|
87
|
+
/** Bumped for every search and on clear; only the latest request may update state. */
|
|
88
|
+
private searchRequestId = 0;
|
|
114
89
|
|
|
115
90
|
private get isDropdownOpen() {
|
|
116
91
|
return (
|
|
117
92
|
this.dropdownRequestedOpen &&
|
|
118
|
-
this.recentSearches &&
|
|
119
|
-
this.recentSearches.length > 0 &&
|
|
93
|
+
this.recentSearches?.length > 0 &&
|
|
120
94
|
!this.value
|
|
121
95
|
);
|
|
122
96
|
}
|
|
123
97
|
|
|
124
98
|
constructor() {
|
|
125
99
|
super();
|
|
126
|
-
|
|
127
100
|
this.updateRecentSearches();
|
|
128
|
-
this.value =
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
disconnectedCallback() {
|
|
132
|
-
this.unsubscribeFromResultList();
|
|
101
|
+
this.value = getSearchQueryParam();
|
|
133
102
|
}
|
|
134
103
|
|
|
135
104
|
renderedCallback() {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
105
|
+
if (!this.openSearchInitialized) {
|
|
106
|
+
this.openSearchInitialized = true;
|
|
107
|
+
if (this.value) {
|
|
108
|
+
const baseUrlPath = getBaseUrlPath();
|
|
109
|
+
const cached = getStoredSearch(baseUrlPath);
|
|
110
|
+
const queryTrimmed = this.value.trim();
|
|
111
|
+
if (
|
|
112
|
+
cached?.query === queryTrimmed &&
|
|
113
|
+
Array.isArray(cached.results) &&
|
|
114
|
+
!isCacheStale(cached)
|
|
115
|
+
) {
|
|
116
|
+
if (!this.didRender) {
|
|
117
|
+
this.dispatchHighlightedTermChange();
|
|
118
|
+
}
|
|
119
|
+
const results = applySelectedAndSelect(cached.results);
|
|
120
|
+
this.dispatchChange(results);
|
|
121
|
+
this.dispatchOnLoading(false);
|
|
122
|
+
} else {
|
|
123
|
+
if (!this.didRender) {
|
|
124
|
+
this.dispatchHighlightedTermChange();
|
|
125
|
+
}
|
|
126
|
+
this.dispatchOnLoading(true);
|
|
127
|
+
this.fetchOpenSearch();
|
|
150
128
|
}
|
|
151
|
-
|
|
129
|
+
} else {
|
|
130
|
+
// No URL query: restore search bar and results from localStorage for this path
|
|
131
|
+
const baseUrlPath = getBaseUrlPath();
|
|
132
|
+
const cached = getStoredSearch(baseUrlPath);
|
|
133
|
+
if (cached?.query && !isCacheStale(cached)) {
|
|
134
|
+
this.value = cached.query;
|
|
135
|
+
const results = applySelectedAndSelect(
|
|
136
|
+
cached.results ?? []
|
|
137
|
+
);
|
|
138
|
+
this.dispatchChange(results);
|
|
139
|
+
this.dispatchHighlightedTermChange();
|
|
140
|
+
}
|
|
141
|
+
this.dispatchOnLoading(false);
|
|
142
|
+
}
|
|
152
143
|
}
|
|
153
|
-
|
|
154
|
-
// If this is the first render and there is a search value, trigger
|
|
155
|
-
// term highlighting
|
|
156
144
|
if (!this.didRender && this.value) {
|
|
157
145
|
this.dispatchHighlightedTermChange();
|
|
158
146
|
}
|
|
159
|
-
|
|
160
147
|
this.didRender = true;
|
|
161
148
|
}
|
|
162
149
|
|
|
163
|
-
private
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
150
|
+
private normalizeOpenSearchResult = (
|
|
151
|
+
item: OpenSearchResultItem,
|
|
152
|
+
index: number
|
|
153
|
+
): SidebarSearchResult => {
|
|
154
|
+
const href = resultHref(item);
|
|
155
|
+
const title = item.title ?? "";
|
|
156
|
+
const excerpt = item.matchedText ?? "";
|
|
157
|
+
const searchQuery = this.value.trim();
|
|
158
|
+
return {
|
|
159
|
+
title,
|
|
160
|
+
titleHighlights: getHighlightRanges(title, searchQuery),
|
|
161
|
+
excerpt,
|
|
162
|
+
excerptHighlights: getHighlightRanges(excerpt, searchQuery),
|
|
163
|
+
// Several hits can share a page URL, so the index keeps keys unique.
|
|
164
|
+
uniqueId: `${index}:${href}`,
|
|
165
|
+
href,
|
|
166
|
+
selected: isCurrentLocation(href),
|
|
167
|
+
select: () => {}
|
|
168
|
+
};
|
|
169
|
+
};
|
|
169
170
|
|
|
171
|
+
private async fetchOpenSearch(): Promise<void> {
|
|
172
|
+
const requestId = ++this.searchRequestId;
|
|
173
|
+
const query = this.value.trim();
|
|
170
174
|
try {
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
json.coveoAdvancedQueryConfig
|
|
175
|
-
).every(
|
|
176
|
-
([key, value]: [string, any]) =>
|
|
177
|
-
this.coveoAdvancedQueryConfig[key] === value
|
|
178
|
-
);
|
|
179
|
-
const hasSameQuery = json?.state?.query?.q === this.value;
|
|
180
|
-
|
|
181
|
-
if (hasSameConfig && hasSameQuery) {
|
|
182
|
-
this.preloadedState = json?.state;
|
|
183
|
-
} else {
|
|
184
|
-
window.sessionStorage.removeItem(SESSION_KEY);
|
|
175
|
+
const rawResults = await fetchSearch(query);
|
|
176
|
+
if (requestId !== this.searchRequestId) {
|
|
177
|
+
return;
|
|
185
178
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
179
|
+
const results: SidebarSearchResult[] = rawResults.map(
|
|
180
|
+
this.normalizeOpenSearchResult
|
|
181
|
+
);
|
|
182
|
+
this.dispatchChange(results);
|
|
183
|
+
this.trackSearchResultsOnce(query, results.length);
|
|
184
|
+
const cacheItems: OpenSearchCacheItem[] = results.map((r) => ({
|
|
185
|
+
title: r.title,
|
|
186
|
+
titleHighlights: r.titleHighlights,
|
|
187
|
+
excerpt: r.excerpt,
|
|
188
|
+
excerptHighlights: r.excerptHighlights,
|
|
189
|
+
uniqueId: r.uniqueId,
|
|
190
|
+
href: r.href
|
|
191
|
+
}));
|
|
192
|
+
setStoredSearch(getBaseUrlPath(), {
|
|
193
|
+
query,
|
|
194
|
+
results: cacheItems
|
|
199
195
|
});
|
|
200
|
-
} catch (
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (!this.engine) {
|
|
205
|
-
console.error("Coveo engine failed to initialize!");
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
if (this.preloadedState) {
|
|
210
|
-
const actions = loadQueryActions(this.engine);
|
|
211
|
-
this.engine.dispatch(actions.updateQuery({ q: this.value || "" }));
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
this.resultList = buildResultList(this.engine, {
|
|
215
|
-
options: { fieldsToInclude: ["sfhtml_url__c"] }
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
this.resultsPerPage = buildResultsPerPage(this.engine, {
|
|
219
|
-
initialState: {
|
|
220
|
-
numberOfResults: DEFAULT_RESULT_COUNT
|
|
196
|
+
} catch (err) {
|
|
197
|
+
if (requestId !== this.searchRequestId) {
|
|
198
|
+
return;
|
|
221
199
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
this.searchBox = buildSearchBox(this.engine, {
|
|
225
|
-
options: { numberOfSuggestions: 3 }
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
this.setAdvancedFilters(this.engine);
|
|
229
|
-
|
|
230
|
-
this.unsubscribeFromResultList = this.resultList?.subscribe(
|
|
231
|
-
this.onResultListChange
|
|
232
|
-
);
|
|
233
|
-
|
|
234
|
-
if (this.value) {
|
|
235
|
-
this.dispatchHighlightedTermChange();
|
|
200
|
+
console.error("OpenSearch Search request failed", err);
|
|
201
|
+
this.dispatchChange([]);
|
|
236
202
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if (this.value) {
|
|
240
|
-
this.submitSearch();
|
|
241
|
-
} else {
|
|
242
|
-
this.dispatchOnLoading(false);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
this.syncAnalytics();
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
private syncAnalytics = () => {
|
|
250
|
-
const storedResult = window.localStorage.getItem(
|
|
251
|
-
RESULT_CLICK_LOCAL_STORAGE_KEY
|
|
252
|
-
);
|
|
253
|
-
if (storedResult) {
|
|
254
|
-
const interactiveResult = buildInteractiveResult(this.engine!, {
|
|
255
|
-
options: { result: JSON.parse(storedResult) }
|
|
256
|
-
});
|
|
257
|
-
interactiveResult.cancelPendingSelect();
|
|
258
|
-
interactiveResult.select();
|
|
259
|
-
window.localStorage.removeItem(RESULT_CLICK_LOCAL_STORAGE_KEY);
|
|
260
|
-
}
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
private onResultListChange = () => {
|
|
264
|
-
if (!this.resultList) {
|
|
265
|
-
return;
|
|
203
|
+
if (requestId === this.searchRequestId) {
|
|
204
|
+
this.dispatchOnLoading(false);
|
|
266
205
|
}
|
|
206
|
+
}
|
|
267
207
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if ((!firstSearchExecuted && !isLoading) || !this.value) {
|
|
272
|
-
// coveo search is firing off some unwanted payloads on startup
|
|
208
|
+
private trackSearchResultsOnce(term: string, resultCount: number): void {
|
|
209
|
+
if (this.didTrackThisSearch || !term) {
|
|
273
210
|
return;
|
|
274
211
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
this.dispatchOnLoading(isLoading);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
if (!isLoading && this.fetchingMoreResults) {
|
|
285
|
-
this.fetchingMoreResults = false;
|
|
286
|
-
}
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
private setAdvancedFilters(engine: SearchEngine) {
|
|
290
|
-
const aq = Object.entries(this.coveoAdvancedQueryConfig).reduce(
|
|
291
|
-
(result, [key, value]) =>
|
|
292
|
-
`${result}(@${key}=="${normalizeCoveoAdvancedQueryValue(
|
|
293
|
-
value
|
|
294
|
-
)}")`,
|
|
295
|
-
""
|
|
296
|
-
);
|
|
297
|
-
|
|
298
|
-
const registerSearchQueryAction = loadAdvancedSearchQueryActions(
|
|
299
|
-
engine
|
|
300
|
-
).registerAdvancedSearchQueries({
|
|
301
|
-
aq: aq
|
|
212
|
+
this.didTrackThisSearch = true;
|
|
213
|
+
trackGTM(this.template.host, "custEv_scopedSearch", {
|
|
214
|
+
search_term: term,
|
|
215
|
+
search_category: "",
|
|
216
|
+
search_type: "site search",
|
|
217
|
+
search_result_count: resultCount
|
|
302
218
|
});
|
|
303
|
-
|
|
304
|
-
engine.dispatch(registerSearchQueryAction);
|
|
305
219
|
}
|
|
306
220
|
|
|
307
|
-
private
|
|
308
|
-
const {
|
|
309
|
-
clickUri,
|
|
310
|
-
excerpt,
|
|
311
|
-
excerptHighlights,
|
|
312
|
-
raw: { sfhtml_url__c },
|
|
313
|
-
title,
|
|
314
|
-
titleHighlights,
|
|
315
|
-
uniqueId
|
|
316
|
-
} = result;
|
|
317
|
-
|
|
318
|
-
// discussion about this normalization here: https://salesforce-internal.slack.com/archives/C020S6784JX/p1639506238376600
|
|
319
|
-
|
|
320
|
-
let pathname, queryParam;
|
|
321
|
-
if (sfhtml_url__c) {
|
|
322
|
-
pathname = `/docs/${sfhtml_url__c}`;
|
|
323
|
-
} else {
|
|
324
|
-
const isNestedGuide = clickUri.includes("/guide/");
|
|
325
|
-
const url = new URL(clickUri);
|
|
326
|
-
const extension =
|
|
327
|
-
isNestedGuide && !url.pathname?.endsWith(".html")
|
|
328
|
-
? ".html"
|
|
329
|
-
: "";
|
|
330
|
-
pathname = `${url.pathname}${extension}`;
|
|
331
|
-
queryParam = url.search;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
let href;
|
|
335
|
-
let isSelected = false;
|
|
336
|
-
const isReferenceUrl = clickUri.includes("/references/");
|
|
337
|
-
if (isReferenceUrl) {
|
|
338
|
-
if (queryParam) {
|
|
339
|
-
href = `${pathname}${queryParam}&q=${this.value}`;
|
|
340
|
-
} else {
|
|
341
|
-
href = `${pathname}?q=${this.value}`;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
//NOTE: This is specific to references related comparison
|
|
345
|
-
const resultHrefWithMetaQuery = `${pathname}${queryParam}`;
|
|
346
|
-
|
|
347
|
-
const urlParams = new URLSearchParams(window.location.search);
|
|
348
|
-
const metaQueryParam = urlParams.get("meta");
|
|
349
|
-
|
|
350
|
-
let currentUrlPathWithQuery = window.location.pathname;
|
|
351
|
-
if (metaQueryParam) {
|
|
352
|
-
currentUrlPathWithQuery = `${currentUrlPathWithQuery}?meta=${metaQueryParam}`;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
isSelected = resultHrefWithMetaQuery === currentUrlPathWithQuery;
|
|
356
|
-
} else {
|
|
357
|
-
href = `${pathname}?q=${this.value}`;
|
|
358
|
-
isSelected = pathname === window.location.pathname;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
return {
|
|
362
|
-
title,
|
|
363
|
-
titleHighlights,
|
|
364
|
-
excerpt,
|
|
365
|
-
excerptHighlights,
|
|
366
|
-
uniqueId,
|
|
367
|
-
href,
|
|
368
|
-
selected: isSelected,
|
|
369
|
-
select: () =>
|
|
370
|
-
window.localStorage.setItem(
|
|
371
|
-
RESULT_CLICK_LOCAL_STORAGE_KEY,
|
|
372
|
-
JSON.stringify(result)
|
|
373
|
-
)
|
|
374
|
-
};
|
|
375
|
-
};
|
|
376
|
-
|
|
377
|
-
private updateSessionStorage() {
|
|
378
|
-
window.sessionStorage.setItem(
|
|
379
|
-
SESSION_KEY,
|
|
380
|
-
JSON.stringify({
|
|
381
|
-
coveoAdvancedQueryConfig: this.coveoAdvancedQueryConfig,
|
|
382
|
-
state: this.engine?.state
|
|
383
|
-
})
|
|
384
|
-
);
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
private dispatchOnChangeEvent(results: Result[]) {
|
|
388
|
-
this.updateSessionStorage();
|
|
221
|
+
private dispatchChange(results: SidebarSearchResult[]) {
|
|
389
222
|
this.dispatchEvent(
|
|
390
223
|
new CustomEvent("change", {
|
|
391
|
-
detail: {
|
|
392
|
-
results: results.map(this.normalizeCoveoResult),
|
|
393
|
-
value: this.value
|
|
394
|
-
}
|
|
224
|
+
detail: { results, value: this.value }
|
|
395
225
|
})
|
|
396
226
|
);
|
|
397
227
|
}
|
|
@@ -427,24 +257,19 @@ export default class SidebarSearch extends LightningElement {
|
|
|
427
257
|
}
|
|
428
258
|
|
|
429
259
|
private submitSearch = debounce((isSyncingSearchValue = false) => {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
// When `isSyncingSearchValue` is true, we are submitting in a case
|
|
435
|
-
// where the search box is already synced correctly.
|
|
436
|
-
if (!isSyncingSearchValue) {
|
|
437
|
-
this.dispatchSidebarSearchChange(this.value);
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
this.searchBox.updateText(this.value || "");
|
|
441
|
-
this.searchBox.submit();
|
|
260
|
+
UserRecentSearches.add(this.value);
|
|
261
|
+
this.updateRecentSearches();
|
|
262
|
+
if (!isSyncingSearchValue) {
|
|
263
|
+
this.dispatchSidebarSearchChange(this.value);
|
|
442
264
|
}
|
|
265
|
+
this.fetchOpenSearch();
|
|
443
266
|
}, SEARCH_DEBOUNCE_DELAY);
|
|
444
267
|
|
|
445
268
|
private onClickRecentSearch(e: CustomEvent) {
|
|
269
|
+
this.searchRequestId++;
|
|
446
270
|
this.value = e.detail;
|
|
447
271
|
this.dispatchSidebarSearchChange(this.value);
|
|
272
|
+
this.dispatchOnLoading(true);
|
|
448
273
|
this.submitSearch(true);
|
|
449
274
|
}
|
|
450
275
|
|
|
@@ -461,7 +286,6 @@ export default class SidebarSearch extends LightningElement {
|
|
|
461
286
|
|
|
462
287
|
private onInputChange(e: CustomEvent) {
|
|
463
288
|
this.value = e.detail;
|
|
464
|
-
|
|
465
289
|
this.handleValueChange(false);
|
|
466
290
|
this.dispatchHighlightedTermChange();
|
|
467
291
|
}
|
|
@@ -475,19 +299,16 @@ export default class SidebarSearch extends LightningElement {
|
|
|
475
299
|
}
|
|
476
300
|
|
|
477
301
|
private handleValueChange(isSyncingSearchValue = false) {
|
|
302
|
+
this.searchRequestId++;
|
|
478
303
|
if (this.value) {
|
|
304
|
+
this.didTrackThisSearch = false;
|
|
479
305
|
this.dispatchOnLoading(true);
|
|
480
|
-
|
|
481
|
-
this.submitSearch(isSyncingSearchValue);
|
|
482
|
-
}
|
|
306
|
+
this.submitSearch(isSyncingSearchValue);
|
|
483
307
|
} else {
|
|
484
|
-
// coveo's reaction to an empty value triggers a return of results
|
|
485
|
-
// bootlegging our own ux here`
|
|
486
308
|
this.dispatchOnLoading(false);
|
|
487
|
-
this.
|
|
488
|
-
// Empty search values are not submitted for search, so we need to manually
|
|
489
|
-
// trigger a search change on our own here
|
|
309
|
+
this.dispatchChange([]);
|
|
490
310
|
this.dispatchSidebarSearchChange(this.value);
|
|
311
|
+
setStoredSearch(getBaseUrlPath(), { query: "", results: [] });
|
|
491
312
|
}
|
|
492
313
|
}
|
|
493
314
|
}
|