Added basic search.

This commit is contained in:
Magnus Åhall 2023-07-19 10:00:36 +02:00
parent 57180e986e
commit c58a1b988b
6 changed files with 211 additions and 21 deletions

29
static/css/search.css Normal file
View file

@ -0,0 +1,29 @@
/*
@theme_gradient: linear-gradient(to right, #009fff, #ec2f4b);
@theme_gradient: linear-gradient(to right, #f5af19, #f12711);
@theme_gradient: linear-gradient(to right, #fdc830, #f37335);
@theme_gradient: linear-gradient(to right, #8a2387, #e94057, #f27121);
@theme_gradient: linear-gradient(to right, #659999, #f4791f);
*/
#search {
padding: 16px;
color: #333;
}
#search h2 {
margin-bottom: 8px;
}
#search input[type=text] {
font-size: 1em;
}
#search button {
display: block;
margin-top: 8px;
}
#search .matches .matched-node {
cursor: pointer;
margin-top: 6px;
}
#search .matches .matched-node:before {
content: "•";
margin-right: 6px;
}

View file

@ -5,6 +5,7 @@
<meta name="viewport" content="initial-scale=1.0, user-scalable=yes" />
<link rel="stylesheet" type="text/css" href="/css/{{ .VERSION }}/main.css">
<link rel="stylesheet" type="text/css" href="/css/{{ .VERSION }}/login.css">
<link rel="stylesheet" type="text/css" href="/css/{{ .VERSION }}/search.css">
<script type="importmap">
{
"imports": {

View file

@ -85,6 +85,10 @@ export class NodeUI extends Component {
case 'keys':
page = html`<${Keys} nodeui=${this} />`
break
case 'search':
page = html`<${Search} nodeui=${this} />`
break
}
let menu = ''
@ -124,41 +128,37 @@ export class NodeUI extends Component {
keyHandler(evt) {//{{{
let handled = true
// All keybindings is Alt+Shift, since the popular browsers at the time (2023) allows to override thees.
// Ctrl+S is the exception to using Alt+Shift, since it is overridable and in such widespread use for saving.
// Thus, the exception is acceptable to consequent use of alt+shift.
if(!(evt.shiftKey && evt.altKey) && !(evt.key.toUpperCase() == 'S' && evt.ctrlKey))
return
switch(evt.key.toUpperCase()) {
case 'E':
if(evt.shiftKey && evt.altKey)
this.showPage('keys')
else
handled = false
this.showPage('keys')
break
case 'N':
if(evt.shiftKey && evt.altKey)
this.createNode()
else
handled = false
this.createNode()
break
case 'P':
if(evt.shiftKey && evt.altKey)
this.showPage('node-properties')
else
handled = false
this.showPage('node-properties')
break
case 'S':
if(evt.ctrlKey || (evt.shiftKey && evt.altKey))
this.saveNode()
else
handled = false
this.saveNode()
break
case 'U':
if(evt.shiftKey && evt.altKey)
this.showPage('upload')
else
handled = false
this.showPage('upload')
break
case 'F':
this.showPage('search')
break
default:
handled = false
@ -723,4 +723,69 @@ class NodeProperties extends Component {
}//}}}
}
class Search extends Component {
constructor() {//{{{
super()
this.state = {
matches: [],
results_returned: false,
}
}//}}}
render({ nodeui }, { matches, results_returned }) {//{{{
let match_elements = [
html`<h2>Results</h2>`,
]
let matched_nodes = matches.map(node=>html`
<div class="matched-node" onclick=${()=>nodeui.goToNode(node.ID)}>
${node.Name}
</div>
`)
match_elements.push(html`<div class="matches">${matched_nodes}</div>`)
return html`
<div id="search">
<h1>Search</h1>
<input type="text" id="search-for" placeholder="Search for" onkeydown=${evt=>this.keyHandler(evt)} />
<button onclick=${()=>this.search()}>Search</button>
${results_returned ? match_elements : ''}
</div>`
}//}}}
componentDidMount() {//{{{
document.getElementById('search-for').focus()
}//}}}
keyHandler(evt) {//{{{
let handled = true
switch(evt.key.toUpperCase()) {
case 'ENTER':
this.search()
break
default:
handled = false
}
if(handled) {
evt.preventDefault()
evt.stopPropagation()
}
}//}}}
search() {//{{{
let Search = document.getElementById('search-for').value
window._app.current.request('/node/search', { Search })
.then(res=>{
this.setState({
matches: res.Nodes,
results_returned: true,
})
})
.catch(window._app.current.responseError)
}//}}}
}
// vim: foldmethod=marker

31
static/less/search.less Normal file
View file

@ -0,0 +1,31 @@
@import "theme.less";
#search {
padding: 16px;
color: #333;
h2 {
margin-bottom: 8px;
}
input[type=text] {
font-size: 1em;
}
button {
display: block;
margin-top: 8px;
}
.matches {
.matched-node {
cursor: pointer;
margin-top: 6px;
&:before {
content: "•";
margin-right: 6px;
}
}
}
}