mirror of
https://github.com/khoaliber/khoj.git
synced 2026-03-02 21:19:12 +00:00
Support Incremental Search on Web Interface
## Support Incremental Search on Khoj Web Interface - Use default, fast path to query /search API while user is typing - Upgrade to cross-encoder re-ranked results once user hits enter on search box ## Improve Render of Org Results on Web Interface - We were previously just wrapping results from /search API into a pre formatted div field. This was not easy to read - Use [org.js](https://mooz.github.io/org-js/) to render results from Khoj `/search` API as proper HTML - Improve org.js to render all task states, stylize task tags and make org-mode results look more like original content Closes #42 #41
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
<meta charset="utf-8">
|
||||
<title>Khoj</title>
|
||||
</head>
|
||||
<script type="text/javascript" src="static/org.js"></script>
|
||||
|
||||
<script>
|
||||
function render_image(item) {
|
||||
@@ -14,22 +15,41 @@
|
||||
</a>`
|
||||
}
|
||||
|
||||
function render_json(data) {
|
||||
return `<pre id="json">${JSON.stringify(data, null, 2)}</pre>`
|
||||
function render_org(query, data) {
|
||||
var orgCode = `Query: ${query}\n` + data.map(function (item) {
|
||||
return `${item.entry}`
|
||||
}).join("\n")
|
||||
var orgParser = new Org.Parser();
|
||||
var orgDocument = orgParser.parse(orgCode);
|
||||
var orgHTMLDocument = orgDocument.convert(Org.ConverterHTML);
|
||||
return orgHTMLDocument.toString();
|
||||
}
|
||||
|
||||
function search() {
|
||||
function render_json(data, query, type) {
|
||||
if (type === "org") {
|
||||
return render_org(query, data);
|
||||
} else if (type === "image") {
|
||||
return data.map(render_image).join('');
|
||||
} else {
|
||||
return `<pre id="json">${JSON.stringify(data, null, 2)}</pre>`;
|
||||
}
|
||||
}
|
||||
|
||||
function search(rerank=false) {
|
||||
query = document.getElementById("query").value;
|
||||
type = document.getElementById("type").value;
|
||||
console.log(query, type);
|
||||
fetch(`/search?q=${query}&t=${type}&n=6`)
|
||||
url = type === "image"
|
||||
? `/search?q=${query}&t=${type}&n=6`
|
||||
: `/search?q=${query}&t=${type}&n=6&r=${rerank}`;
|
||||
fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log(data);
|
||||
document.getElementById("results").innerHTML =
|
||||
type == "image"
|
||||
? data.map(render_image).join('')
|
||||
: render_json(data);
|
||||
`<div id=results-${type}>`
|
||||
+ render_json(data, query, type)
|
||||
+ `</div>`;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -44,9 +64,14 @@
|
||||
});
|
||||
}
|
||||
|
||||
function search_on_enter(event) {
|
||||
if (event.key == 'Enter') {
|
||||
search();
|
||||
function incremental_search(event) {
|
||||
type = document.getElementById("type").value;
|
||||
if (event.key === 'Enter') {
|
||||
search(rerank=true);
|
||||
}
|
||||
// Limit incremental search to text types
|
||||
else if (type !== "image") {
|
||||
search(rerank=false);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -54,8 +79,8 @@
|
||||
<body>
|
||||
<h1>Khoj</h1>
|
||||
|
||||
<!--Add Text Box To Enter Query -->
|
||||
<input id="query" type="text" placeholder="Search" onkeydown=search_on_enter(event) autofocus>
|
||||
<!--Add Text Box To Enter Query, Trigger Incremental Search OnChange -->
|
||||
<input type="text" id="query" onkeyup=incremental_search(event) placeholder="What is the meaning of life?">
|
||||
|
||||
<!--Add Dropdown to Select Query Type.
|
||||
Query Types can be: org, ledger, image, music, markdown.
|
||||
@@ -68,8 +93,6 @@
|
||||
<option value="music">Music</option>
|
||||
</select>
|
||||
|
||||
<!--Add Button To Search -->
|
||||
<button id="search" onclick="search()">Search</button>
|
||||
<!--Add Button To Regenerate -->
|
||||
<button id="regenerate" onclick="regenerate()">Regenerate</button>
|
||||
|
||||
@@ -121,7 +144,7 @@
|
||||
border-radius: 5px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
#results {
|
||||
#results-image {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
@@ -136,6 +159,31 @@
|
||||
#json {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
#results-org {
|
||||
text-align: left;
|
||||
white-space: pre-line;
|
||||
}
|
||||
span.task-status {
|
||||
color: white;
|
||||
padding: 3.5px 3.5px 0;
|
||||
margin-right: 5px;
|
||||
border-radius: 5px;
|
||||
background-color: #ed6f00;
|
||||
}
|
||||
span.task-status.todo {
|
||||
background-color: #048ba8
|
||||
}
|
||||
span.task-status.done {
|
||||
background-color: #06a77d;
|
||||
}
|
||||
span.task-tag {
|
||||
color: white;
|
||||
padding: 3.5px 3.5px 0;
|
||||
margin-right: 5px;
|
||||
border-radius: 5px;
|
||||
background-color: #bbb;
|
||||
}
|
||||
</style>
|
||||
|
||||
</html>
|
||||
|
||||
1829
src/interface/web/org.js
Normal file
1829
src/interface/web/org.js
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user