2017-06-28 10:45:41 +00:00
|
|
|
<template>
|
2017-07-04 10:47:24 +00:00
|
|
|
<div id="search" @click="active = true" v-bind:class="{ active , ongoing }">
|
|
|
|
<div id="input">
|
|
|
|
<button v-if="active" class="action" @click="close" >
|
|
|
|
<i class="material-icons">arrow_back</i>
|
|
|
|
</button>
|
|
|
|
<i v-else class="material-icons">search</i>
|
|
|
|
<input type="text"
|
|
|
|
v-model.trim="value"
|
|
|
|
@keyup="keyup"
|
|
|
|
@keyup.enter="submit"
|
|
|
|
aria-label="Write here to search"
|
|
|
|
:placeholder="placeholder()">
|
|
|
|
</div>
|
|
|
|
<div id="result">
|
2017-06-30 14:02:45 +00:00
|
|
|
<div>
|
|
|
|
<span v-if="search.length === 0 && commands.length === 0">{{ text() }}</span>
|
|
|
|
<ul v-else-if="search.length > 0">
|
2017-07-03 17:07:14 +00:00
|
|
|
<li v-for="s in search"><router-link :to="'./' + s">./{{ s }}</router-link></li>
|
2017-06-30 14:02:45 +00:00
|
|
|
</ul>
|
|
|
|
<ul v-else-if="commands.length > 0">
|
|
|
|
<li v-for="c in commands">{{ c }}</li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
<p><i class="material-icons spin">autorenew</i></p>
|
2017-06-28 10:45:41 +00:00
|
|
|
</div>
|
2017-06-30 14:02:45 +00:00
|
|
|
</div>
|
2017-06-28 10:45:41 +00:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2017-06-30 11:43:43 +00:00
|
|
|
import { mapState } from 'vuex'
|
2017-07-03 14:19:17 +00:00
|
|
|
import url from '@/utils/url'
|
2017-07-03 17:07:14 +00:00
|
|
|
import api from '@/utils/api'
|
2017-06-28 10:45:41 +00:00
|
|
|
|
|
|
|
export default {
|
|
|
|
name: 'search',
|
|
|
|
data: function () {
|
|
|
|
return {
|
2017-06-30 14:02:45 +00:00
|
|
|
value: '',
|
2017-07-04 10:47:24 +00:00
|
|
|
active: false,
|
2017-06-30 14:02:45 +00:00
|
|
|
ongoing: false,
|
2017-06-28 10:45:41 +00:00
|
|
|
scrollable: null,
|
2017-06-30 14:02:45 +00:00
|
|
|
search: [],
|
|
|
|
commands: []
|
2017-06-28 10:45:41 +00:00
|
|
|
}
|
2017-06-27 18:00:58 +00:00
|
|
|
},
|
2017-06-30 14:02:45 +00:00
|
|
|
computed: mapState(['user']),
|
2017-06-27 18:00:58 +00:00
|
|
|
mounted: function () {
|
2017-07-04 10:47:24 +00:00
|
|
|
this.scrollable = document.querySelector('#search #result')
|
|
|
|
|
|
|
|
window.addEventListener('keydown', (event) => {
|
|
|
|
// Esc!
|
|
|
|
if (event.keyCode === 27) {
|
|
|
|
this.active = false
|
|
|
|
}
|
|
|
|
})
|
2017-06-27 18:00:58 +00:00
|
|
|
},
|
|
|
|
methods: {
|
2017-07-04 10:47:24 +00:00
|
|
|
close: function (event) {
|
|
|
|
event.stopPropagation()
|
|
|
|
event.preventDefault()
|
|
|
|
this.active = false
|
|
|
|
},
|
2017-06-30 14:02:45 +00:00
|
|
|
placeholder: function () {
|
2017-06-30 11:43:43 +00:00
|
|
|
if (this.user.allowCommands && this.user.commands.length > 0) {
|
2017-06-30 14:02:45 +00:00
|
|
|
return 'Search or execute a command...'
|
|
|
|
}
|
|
|
|
|
|
|
|
return 'Search...'
|
|
|
|
},
|
|
|
|
text: function () {
|
2017-07-04 10:47:24 +00:00
|
|
|
if (this.ongoing) {
|
|
|
|
return ''
|
|
|
|
}
|
|
|
|
|
2017-06-30 14:02:45 +00:00
|
|
|
if (this.value.length === 0) {
|
|
|
|
if (this.user.allowCommands && this.user.commands.length > 0) {
|
|
|
|
return `Search or use one of your supported commands: ${this.user.commands.join(', ')}.`
|
|
|
|
}
|
|
|
|
|
|
|
|
return 'Type and press enter to search.'
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.supported() || !this.user.allowCommands) {
|
|
|
|
return 'Press enter to search.'
|
2017-06-27 18:00:58 +00:00
|
|
|
} else {
|
2017-06-30 14:02:45 +00:00
|
|
|
return 'Press enter to execute.'
|
2017-06-27 18:00:58 +00:00
|
|
|
}
|
|
|
|
},
|
2017-07-04 10:47:24 +00:00
|
|
|
keyup: function (event) {
|
|
|
|
if (event.keyCode === 27) {
|
|
|
|
this.active = false
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
this.active = true
|
2017-06-30 14:02:45 +00:00
|
|
|
this.search.length = 0
|
|
|
|
this.commands.length = 0
|
|
|
|
},
|
2017-06-27 18:00:58 +00:00
|
|
|
supported: function () {
|
2017-06-30 14:02:45 +00:00
|
|
|
let pieces = this.value.split(' ')
|
2017-06-27 18:00:58 +00:00
|
|
|
|
2017-06-30 11:43:43 +00:00
|
|
|
for (let i = 0; i < this.user.commands.length; i++) {
|
|
|
|
if (pieces[0] === this.user.commands[0]) {
|
2017-06-27 18:00:58 +00:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
},
|
|
|
|
click: function (event) {
|
|
|
|
event.currentTarget.classList.add('active')
|
|
|
|
this.$el.querySelector('input').focus()
|
|
|
|
},
|
|
|
|
submit: function (event) {
|
2017-06-30 14:02:45 +00:00
|
|
|
this.ongoing = true
|
2017-06-27 18:00:58 +00:00
|
|
|
|
2017-07-03 17:07:14 +00:00
|
|
|
let path = this.$route.path
|
2017-06-30 14:02:45 +00:00
|
|
|
if (this.$store.state.req.kind !== 'listing') {
|
2017-07-03 17:07:14 +00:00
|
|
|
path = url.removeLastDir(path) + '/'
|
2017-06-27 18:00:58 +00:00
|
|
|
}
|
|
|
|
|
2017-06-30 11:43:43 +00:00
|
|
|
if (this.supported() && this.user.allowCommands) {
|
2017-07-03 17:07:14 +00:00
|
|
|
api.command(path, this.value,
|
|
|
|
(event) => {
|
|
|
|
this.commands.push(event.data)
|
|
|
|
this.scrollable.scrollTop = this.scrollable.scrollHeight
|
|
|
|
},
|
|
|
|
(event) => {
|
|
|
|
this.ongoing = false
|
|
|
|
this.scrollable.scrollTop = this.scrollable.scrollHeight
|
|
|
|
this.$store.commit('setReload', true)
|
|
|
|
}
|
|
|
|
)
|
2017-06-27 18:00:58 +00:00
|
|
|
|
2017-07-03 17:07:14 +00:00
|
|
|
return
|
|
|
|
}
|
2017-06-27 18:00:58 +00:00
|
|
|
|
2017-07-03 17:07:14 +00:00
|
|
|
api.search(path, this.value,
|
|
|
|
(event) => {
|
|
|
|
let url = event.data
|
|
|
|
if (url[0] === '/') url = url.substring(1)
|
2017-06-27 18:00:58 +00:00
|
|
|
|
2017-07-03 17:07:14 +00:00
|
|
|
this.search.push(url)
|
|
|
|
this.scrollable.scrollTop = this.scrollable.scrollHeight
|
|
|
|
},
|
|
|
|
(event) => {
|
2017-06-30 14:02:45 +00:00
|
|
|
this.ongoing = false
|
|
|
|
this.scrollable.scrollTop = this.scrollable.scrollHeight
|
2017-06-27 18:00:58 +00:00
|
|
|
}
|
2017-07-03 17:07:14 +00:00
|
|
|
)
|
2017-06-27 18:00:58 +00:00
|
|
|
}
|
|
|
|
}
|
2017-06-28 10:45:41 +00:00
|
|
|
}
|
|
|
|
</script>
|