mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-04-23 17:50:38 +00:00
spotlight ability to search users with 'u ' keyword
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="isVisible"
|
||||
@keyup.esc="exit"
|
||||
@keyup.esc="exitSpotlight"
|
||||
tabindex="-1"
|
||||
class="md:absolute fixed w-full h-full dark:bg-dark-foreground md:bg-transparent bg-white md:z-auto z-50"
|
||||
>
|
||||
<div class="relative w-full md:max-w-xl z-50 md:rounded-xl mx-auto 2xl:mt-20 md:mt-8 overflow-y-auto bg-white dark:bg-dark-foreground">
|
||||
|
||||
<!--Query bar-->
|
||||
<div class="z-50 flex items-center p-5 mx-auto">
|
||||
<div class="z-50 flex items-center px-5 py-4 mx-auto">
|
||||
<div class="relative mr-4">
|
||||
<div v-if="isLoading" class="spinner-icon transform scale-50 origin-center translate-y-2.5">
|
||||
<Spinner />
|
||||
@@ -16,10 +16,19 @@
|
||||
<search-icon :class="{'opacity-0': isLoading}" size="22" class="magnify dark-text-theme text-theme vue-feather" />
|
||||
</div>
|
||||
|
||||
<!--Filter-->
|
||||
<div v-if="activeFilter" @click="removeFilter" class="bg-light-background rounded-lg px-2 py-1 mr-3 flex items-center cursor-pointer">
|
||||
<b class="font-bold pr-1.5 text-sm">
|
||||
{{ activeFilter }}
|
||||
</b>
|
||||
<x-icon size="12" />
|
||||
</div>
|
||||
|
||||
<!--Text search field-->
|
||||
<input
|
||||
class="w-full border-none text-xl font-semibold placeholder-gray-700 dark:placeholder-gray-400 bg-transparent focus:outline-none"
|
||||
v-model="query"
|
||||
@keydown.delete="undoFilter"
|
||||
@keydown.enter="showSelected"
|
||||
@keydown.meta="proceedToSelect"
|
||||
@keyup.down="onPageDown"
|
||||
@@ -35,7 +44,7 @@
|
||||
</div>
|
||||
|
||||
<!--Mobile close icon-->
|
||||
<div v-if="$isMobile()" @click="exit" class="cursor-pointer">
|
||||
<div v-if="$isMobile()" @click="exitSpotlight" class="cursor-pointer">
|
||||
<x-icon size="22" class="close" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -44,15 +53,37 @@
|
||||
<div v-if="isNotEmptyQuery" class="spotlight-results relative z-50 px-4 pb-4">
|
||||
|
||||
<!--Show results-->
|
||||
<div v-if="results.length !== 0" v-for="(item, i) in results" :key="item.data.id" class="relative">
|
||||
<div v-if="results.length !== 0" v-for="(result, i) in results" :key="result.data.id" class="relative">
|
||||
|
||||
<!--Users result-->
|
||||
<div
|
||||
v-if="activeFilter === 'users'"
|
||||
:class="{'dark:bg-2x-dark-foreground bg-light-background rounded-xl': i === index}"
|
||||
class="flex items-center px-2.5 py-3.5"
|
||||
>
|
||||
<MemberAvatar
|
||||
:is-border="false"
|
||||
:size="44"
|
||||
:member="result"
|
||||
/>
|
||||
<div class="ml-3">
|
||||
<b class="text-sm font-bold block max-w-1 overflow-hidden overflow-ellipsis whitespace-nowrap" style="max-width: 155px;">
|
||||
{{ result.data.attributes.name }}
|
||||
</b>
|
||||
<span class="block text-xs dark:text-gray-500 text-gray-600">
|
||||
{{ result.data.attributes.email }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Item result-->
|
||||
<ItemList
|
||||
:entry="item"
|
||||
v-if="! activeFilter"
|
||||
:entry="result"
|
||||
:class="{'dark:bg-2x-dark-foreground bg-light-background rounded-xl': i === index}"
|
||||
:highlight="false"
|
||||
:mobile-handler="false"
|
||||
@click.native="openItem(item)"
|
||||
@click.native="openItem(result)"
|
||||
/>
|
||||
|
||||
<!--Keyboard shortcut hint-->
|
||||
@@ -72,16 +103,18 @@
|
||||
|
||||
<script>
|
||||
import Spinner from '/resources/js/components/FilesView/Spinner'
|
||||
import MemberAvatar from "../FilesView/MemberAvatar"
|
||||
import {SearchIcon, XIcon} from 'vue-feather-icons'
|
||||
import ItemList from "../FilesView/ItemList"
|
||||
import {events} from '/resources/js/bus'
|
||||
import {debounce} from 'lodash';
|
||||
import axios from "axios";
|
||||
import {mapGetters} from "vuex";
|
||||
import {mapGetters} from 'vuex'
|
||||
import {debounce} from 'lodash'
|
||||
import axios from "axios"
|
||||
|
||||
export default {
|
||||
name: 'Spotlight',
|
||||
components: {
|
||||
MemberAvatar,
|
||||
SearchIcon,
|
||||
ItemList,
|
||||
Spinner,
|
||||
@@ -91,6 +124,9 @@ export default {
|
||||
...mapGetters([
|
||||
'user'
|
||||
]),
|
||||
isAdmin() {
|
||||
return this.user.data.attributes.role === 'admin'
|
||||
},
|
||||
metaKeyIcon() {
|
||||
return this.$isApple() ? '⌘' : 'alt'
|
||||
},
|
||||
@@ -99,16 +135,28 @@ export default {
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
query(val) {
|
||||
if (val === '' || typeof val === 'undefined')
|
||||
query(query) {
|
||||
if (query === '' || typeof query === 'undefined')
|
||||
this.results = []
|
||||
|
||||
// Reset selection index
|
||||
this.index = 0
|
||||
this.searchFiles(val)
|
||||
|
||||
// Go for filter keyword
|
||||
let getFilterQuery = query.substr(0, 2)
|
||||
|
||||
// search for the users
|
||||
if (getFilterQuery === 'u ' && this.isAdmin && ! this.activeFilter) {
|
||||
this.setFilter('users')
|
||||
}
|
||||
|
||||
this.findResult(query)
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeFilter: undefined,
|
||||
backspaceHits: 0,
|
||||
isVisible: false,
|
||||
isLoading: false,
|
||||
results: [],
|
||||
@@ -117,6 +165,28 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
undoFilter() {
|
||||
if (this.activeFilter && this.query === '' && this.backspaceHits !== 2) {
|
||||
this.backspaceHits++
|
||||
}
|
||||
|
||||
if (this.backspaceHits === 2) {
|
||||
this.removeFilter()
|
||||
}
|
||||
},
|
||||
setFilter(filter) {
|
||||
// Set active filter
|
||||
this.activeFilter = filter
|
||||
|
||||
// Set default values
|
||||
this.results = []
|
||||
this.query = ''
|
||||
},
|
||||
removeFilter() {
|
||||
// Set default values
|
||||
this.activeFilter = undefined
|
||||
this.backspaceHits = 0
|
||||
},
|
||||
proceedToSelect(e) {
|
||||
// Preserve select and reload native shortcut
|
||||
if (!['a', 'r', 'v'].includes(e.key)) {
|
||||
@@ -131,9 +201,20 @@ export default {
|
||||
}
|
||||
},
|
||||
showSelected() {
|
||||
let file = this.results[this.index]
|
||||
let selectedItem = this.results[this.index]
|
||||
|
||||
this.openItem(file)
|
||||
if (this.activeFilter === 'users') {
|
||||
this.openUser(selectedItem)
|
||||
}
|
||||
|
||||
if (! this.activeFilter) {
|
||||
this.openItem(selectedItem)
|
||||
}
|
||||
},
|
||||
openUser(user) {
|
||||
this.$router.push({name: 'UserDetail', params: {id: user.data.id}})
|
||||
|
||||
this.exitSpotlight()
|
||||
},
|
||||
openItem(file) {
|
||||
|
||||
@@ -162,7 +243,7 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
this.exit()
|
||||
this.exitSpotlight()
|
||||
},
|
||||
onPageDown() {
|
||||
if (this.index < (this.results.length - 1))
|
||||
@@ -171,7 +252,7 @@ export default {
|
||||
onPageUp() {
|
||||
if (this.index > 0) this.index--
|
||||
},
|
||||
searchFiles: debounce(function (value) {
|
||||
findResult: debounce(function (value) {
|
||||
// Prevent empty searching
|
||||
if (value === '' || typeof value === 'undefined') return
|
||||
|
||||
@@ -192,20 +273,28 @@ export default {
|
||||
}
|
||||
|
||||
axios
|
||||
.get(route, {
|
||||
.get(`${route}?filter=${this.activeFilter}`, {
|
||||
params: {query: value}
|
||||
})
|
||||
.then(response => {
|
||||
let files = response.data.files.data
|
||||
let folders = response.data.folders.data
|
||||
|
||||
this.results = folders.concat(files)
|
||||
// Show user result
|
||||
if (this.activeFilter === 'users') {
|
||||
this.results = response.data.data
|
||||
}
|
||||
|
||||
// Show file result
|
||||
if (! this.activeFilter) {
|
||||
let files = response.data.files.data
|
||||
let folders = response.data.folders.data
|
||||
|
||||
this.results = folders.concat(files)
|
||||
}
|
||||
})
|
||||
.catch(() => this.$isSomethingWrong())
|
||||
.finally(() => this.isLoading = false)
|
||||
|
||||
}, 150),
|
||||
exit() {
|
||||
exitSpotlight() {
|
||||
this.results = []
|
||||
this.query = ''
|
||||
this.isVisible = false
|
||||
@@ -219,7 +308,7 @@ export default {
|
||||
this.$nextTick(() => this.$refs.searchInput.focus())
|
||||
})
|
||||
|
||||
events.$on('spotlight:hide', () => this.exit())
|
||||
events.$on('spotlight:hide', () => this.exitSpotlight())
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user