Skip to content

Commit 1ccca2e

Browse files
authored
Search dropdown improvements (#3533)
1 parent 4542b9b commit 1ccca2e

File tree

7 files changed

+224
-39
lines changed

7 files changed

+224
-39
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ bin
1717
.vale.ini
1818
.frontmatter
1919
frontmatter.json
20-
Pipfile
20+
Pipfile
21+
typesense.env

assets/js/index.js

+53-36
Original file line numberDiff line numberDiff line change
@@ -68,42 +68,59 @@ if(main && scrollBtn) {
6868
observer.observe(main);
6969
}
7070

71-
docsearch({
72-
inputSelector: '.navbar-nav .td-search-input',
73-
typesenseCollectionName: 'docsearch',
74-
typesenseServerConfig: {
75-
nodes: [{
76-
host: 'cgnvrk0xwyj9576lp-1.a1.typesense.net',
77-
port: '443',
78-
protocol: 'https'
79-
}],
80-
apiKey: 'GHQK6od8KfpvTEh4YpA113gUc2dU5fGR'
81-
},
82-
typesenseSearchParameters: {
83-
group_by: "url_without_anchor",
84-
group_limit: 1
85-
},
86-
// unclear what if anything this achieves.
87-
contextualSearch: true
88-
});
89-
docsearch({
90-
inputSelector: '.td-sidebar__search .td-search-input',
91-
typesenseCollectionName: 'docsearch',
92-
typesenseServerConfig: {
93-
nodes: [{
94-
host: 'cgnvrk0xwyj9576lp-1.a1.typesense.net',
95-
port: '443',
96-
protocol: 'https'
97-
}],
98-
apiKey: 'GHQK6od8KfpvTEh4YpA113gUc2dU5fGR'
99-
},
100-
typesenseSearchParameters: {
101-
group_by: "url_without_anchor",
102-
group_limit: 1
103-
},
104-
// unclear what if anything this achieves.
105-
contextualSearch: true
106-
});
71+
function handleSearch(inputSelector) {
72+
const searchConfig = {
73+
inputSelector: inputSelector,
74+
typesenseCollectionName: 'docsearch',
75+
typesenseServerConfig: {
76+
nodes: [{
77+
host: 'cgnvrk0xwyj9576lp-1.a1.typesense.net',
78+
port: '443',
79+
protocol: 'https'
80+
}],
81+
apiKey: 'GHQK6od8KfpvTEh4YpA113gUc2dU5fGR'
82+
},
83+
typesenseSearchParams: {
84+
query_by: 'hierarchy.lvl0,hierarchy.lvl1,url_without_anchor',
85+
query_by_weight: '100,50,1',
86+
sort_by: "_text_match:desc,item_priority:desc",
87+
prioritize_token_position: true,
88+
group_by: "url_without_anchor",
89+
group_limit: 1
90+
},
91+
autocompleteOptions: {
92+
autoselect: false,
93+
debug: false,
94+
hint: false
95+
}
96+
};
97+
98+
const search = docsearch(searchConfig);
99+
100+
let opened = false;
101+
search.autocomplete.on('autocomplete:shown', (e, a, b, c) => {
102+
opened = true;
103+
});
104+
search.autocomplete.on('autocomplete:closed', () => {
105+
opened = false;
106+
});
107+
let cursorUsed = false;
108+
// we can't detect the cursor changing to an empty auto complete entry,
109+
// so the only case where getting to search results via Enter will work is
110+
// text typed followed by Enter.
111+
search.autocomplete.on('autocomplete:cursorchanged', (event, suggestion) => {
112+
cursorUsed = true;
113+
});
114+
// search.autocomplete.on('keydown', (e) => {
115+
// if (opened && !cursorUsed && e.key === 'Enter' && search.input[0].value !== '') {
116+
// const query = encodeURIComponent(search.input[0].value);
117+
// window.location = `${window.location.origin}/search?query=${query}`;
118+
// }
119+
// });
120+
}
121+
122+
handleSearch('.navbar-nav .td-search-input');
123+
handleSearch('.td-sidebar__search .td-search-input');
107124

108125
// Userflow START
109126
!function(){var e="undefined"==typeof window?{}:window,r=e.userflow;if(!r){var t="https://js.userflow.com/",n=null;r=e.userflow={_stubbed:!0,load:function(){return n||(n=new Promise((function(r,o){var s=document.createElement("script");s.async=!0;var a=e.USERFLOWJS_ENV_VARS||{};"es2020"===(a.USERFLOWJS_BROWSER_TARGET||function(e){for(var r=[[/Edg\//,/Edg\/(\d+)/,80],[/OPR\//,/OPR\/(\d+)/,67],[/Chrome\//,/Chrome\/(\d+)/,80],[/Safari\//,/Version\/(\d+)/,14],[/Firefox\//,/Firefox\/(\d+)/,74]],t=0;t<r.length;t++){var n=r[t],o=n[0],s=n[1],a=n[2];if(e.match(o)){var u=e.match(new RegExp(s));if(u&&parseInt(u[1],10)>=a)return"es2020";break}}return"legacy"}(navigator.userAgent))?(s.type="module",s.src=a.USERFLOWJS_ES2020_URL||t+"es2020/userflow.js"):s.src=a.USERFLOWJS_LEGACY_URL||t+"legacy/userflow.js",s.onload=function(){r()},s.onerror=function(){document.head.removeChild(s),n=null;var e=new Error("Could not load Userflow.js");console.error(e.message),o(e)},document.head.appendChild(s)}))),n}};var o=e.USERFLOWJS_QUEUE=e.USERFLOWJS_QUEUE||[],s=function(e){r[e]=function(){var t=Array.prototype.slice.call(arguments);r.load(),o.push([e,null,t])}},a=function(e){r[e]=function(){var t,n=Array.prototype.slice.call(arguments);r.load();var s=new Promise((function(e,r){t={resolve:e,reject:r}}));return o.push([e,t,n]),s}},u=function(e,t){r[e]=function(){return t}};s("_setTargetEnv"),s("closeResourceCenter"),s("init"),s("off"),s("on"),s("prepareAudio"),s("registerCustomInput"),s("remount"),s("reset"),s("setBaseZIndex"),s("setCustomInputSelector"),s("setCustomNavigate"),s("setCustomScrollIntoView"),s("setInferenceAttributeFilter"),s("setInferenceAttributeNames"),s("setInferenceClassNameFilter"),s("setResourceCenterLauncherHidden"),s("setScrollPadding"),s("setShadowDomEnabled"),s("setPageTrackingDisabled"),s("setUrlFilter"),s("openResourceCenter"),s("toggleResourceCenter"),a("endAll"),a("endAllFlows"),a("endChecklist"),a("group"),a("identify"),a("identifyAnonymous"),a("start"),a("startFlow"),a("startWalk"),a("track"),a("updateGroup"),a("updateUser"),u("getResourceCenterState",null),u("isIdentified",!1)}}();

assets/js/search-results.js

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
const { TypesenseInstantSearchAdapter, instantsearch } = window;
2+
const observer = lozad();
3+
4+
const indexName = 'docsearch';
5+
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter({
6+
server: {
7+
apiKey: "GHQK6od8KfpvTEh4YpA113gUc2dU5fGR",
8+
nodes: [
9+
{
10+
host: "cgnvrk0xwyj9576lp-1.a1.typesense.net",
11+
port: "443",
12+
protocol: "https",
13+
},
14+
],
15+
cacheSearchResultsForSeconds: 2 * 60,
16+
},
17+
additionalSearchParameters: {
18+
query_by: 'hierarchy.lvl0,hierarchy.lvl1,url_without_anchor',
19+
query_by_weight: '100,50,1',
20+
sort_by: "_text_match:desc,item_priority:desc",
21+
prioritize_token_position: true,
22+
group_by: "url_without_anchor",
23+
group_limit: 1,
24+
},
25+
});
26+
27+
const searchClient = typesenseInstantsearchAdapter.searchClient;
28+
29+
const search = instantsearch({
30+
indexName: indexName,
31+
searchClient,
32+
});
33+
34+
search.addWidgets([
35+
instantsearch.widgets.hits({
36+
container: "#hits",
37+
templates: {
38+
item: `
39+
<div class="col hover-card">
40+
<a href="{{url}}" target="_blank">
41+
<div class="small-hover-card-div">
42+
<div class="title">{{hierarchy.lvl0}}</div>
43+
<div class="description">
44+
<p>{{#helpers.highlight}}{ "attribute": "hierarchy.lvl1", "highlightedTagName": "mark" }{{/helpers.highlight}}</p>
45+
</div>
46+
</div>
47+
</a>
48+
</div>
49+
`,
50+
},
51+
}),
52+
instantsearch.widgets.configure({
53+
hitsPerPage: 12,
54+
}),
55+
instantsearch.widgets.pagination({
56+
container: "#pagination",
57+
}),
58+
instantsearch.widgets.searchBox({
59+
container: '#search-box',
60+
}),
61+
]);
62+
63+
search.start();
64+
65+
const urlParams = new URLSearchParams(window.location.search);
66+
const query = urlParams.get('query');
67+
68+
search.setUiState({
69+
[indexName]: {
70+
query: query
71+
}
72+
});

assets/scss/_styles_project.scss

+12
Original file line numberDiff line numberDiff line change
@@ -2054,3 +2054,15 @@ h3.body-header[style] {
20542054
.hs_email.hs-email.hs-fieldtype-text.field.hs-form-field label, .hs_email.hs-email.hs-fieldtype-text.field.hs-form-field .input {
20552055
margin-right: 1rem;
20562056
}
2057+
2058+
.algolia-autocomplete .typesense-docsearch-suggestion--subcategory-column {
2059+
display: none !important;
2060+
float:left;
2061+
width:0 !important;
2062+
padding-left:0;
2063+
padding:0px;
2064+
}
2065+
2066+
.algolia-autocomplete .typesense-docsearch-suggestion--content {
2067+
width: 100% !important;
2068+
}

docs/search/_index.md

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
title: "Search Results"
3+
linkTitle: "Search Results"
4+
weight: 200
5+
type: "docs"
6+
layout: "search"
7+
no_list: true
8+
notoc: true
9+
hide_children: true
10+
toc_hide: true
11+
sitemap:
12+
priority: 0
13+
date: "2024-10-07"
14+
---

docsearch.json

+10-2
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,24 @@
2020
"url": "https://docs.viam.com/appendix/changelog/",
2121
"tags": ["changelog"],
2222
"page_rank": 1
23+
},{
24+
"url": "https://docs.viam.com/appendix/apis/",
25+
"tags": ["apis"],
26+
"page_rank": 2
27+
},{
28+
"url": "https://docs.viam.com/registry/examples/",
29+
"tags": ["apis"],
30+
"page_rank": 30
2331
},{
2432
"url": "https://docs.viam.com/",
2533
"tags": [],
26-
"page_rank": 10
34+
"page_rank": 40
2735
}],
2836
"sitemap_urls": ["https://docs.viam.com/sitemap.xml"],
2937
"use_anchors": true,
3038
"selectors": {
3139
"lvl0": ".td-content h1",
32-
"lvl1": ".td-content .lead",
40+
"lvl1": ".td-content p:first-of-type",
3341
"lvl2": ".td-content h2",
3442
"lvl3": ".td-content h3",
3543
"lvl4": ".td-content h4",

layouts/docs/search.html

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<!doctype html>
2+
<html lang="{{ .Site.Language.Lang }}" class="no-js">
3+
<head>
4+
{{ partial "head.html" . }}
5+
</head>
6+
<body class="td-{{ .Kind }}{{ with .Page.Params.body_class }} {{ . }}{{ end }}">
7+
{{- if hugo.IsProduction -}}{{- if .Site.Config.Services.GoogleAnalytics.ID -}}
8+
<!-- Google Tag Manager (noscript) -->
9+
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id={{ .Site.Config.Services.GoogleAnalytics.ID }}"
10+
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
11+
<!-- End Google Tag Manager (noscript) -->
12+
{{- end -}}{{- end -}}
13+
<header>
14+
{{ partial "navbar.html" . }}
15+
</header>
16+
<div class="container-fluid td-outer">
17+
<div class="td-main">
18+
<div class="row flex-xl-nowrap">
19+
<aside class="col-12 col-md-3 col-xl-2 td-sidebar d-print-none">
20+
{{ partial "sidebar.html" . }}
21+
</aside>
22+
<main class="col-12 col-md-9 col-xl-10 pl-md-5" role="main">
23+
{{ if not .Site.Params.ui.breadcrumb_disable }}{{ partial "breadcrumb.html" . }}{{ end }}
24+
<div class="td-content">
25+
<h1>{{ .Title }}</h1>
26+
27+
<div id="tutorial-menu" class="lozad">
28+
<div id="resource-list" style="display:none;"></div>
29+
<div id="platformarea-list" data-parent="#tutorial-menu"></div>
30+
</div>
31+
<div class="search-panel__results card-container lozad">
32+
<div id="hits" class="row-no-margin"></div>
33+
<div id="pagination"></div>
34+
<div id="search-box" style="display:none;visibility:hidden"></div>
35+
</div>
36+
</div>
37+
</main>
38+
</div>
39+
{{ $img := resources.GetMatch "/icons/learn-viam-robot-icon-ai.svg" }}
40+
<button onclick="initAndClick()" class="docsbutton" id="chatButton" title="Chatbot and support">
41+
<span id="chatButtonContent">
42+
<i style="font-size:x-large;" class="fas fa-comments"></i>
43+
<span>Ask AI</span>
44+
</span>
45+
</button>
46+
</div>
47+
{{ partial "footer.html" . }}
48+
</div>
49+
50+
{{ partial "scripts.html" . }}
51+
52+
<script src="https://cdn.jsdelivr.net/npm/typesense-instantsearch-adapter@2/dist/typesense-instantsearch-adapter.min.js"></script>
53+
54+
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
55+
56+
{{ $jsSearchResults := resources.Get "js/search-results.js" }}
57+
{{ $jsSearchResults := $jsSearchResults | minify }}
58+
<script type="text/javascript" src="{{ $jsSearchResults.RelPermalink }}" crossorigin="anonymous"></script>
59+
60+
</body>
61+
</html>

0 commit comments

Comments
 (0)