Remove multiselect again and diy
This commit is contained in:
parent
4692a1046d
commit
acd1b9b83a
|
@ -1,34 +1,51 @@
|
|||
<template>
|
||||
<modal v-if="active">
|
||||
<div class="card p-4">
|
||||
<multiselect
|
||||
placeholder="What do you want to do?"
|
||||
:search-results="results"
|
||||
label="title"
|
||||
@search="search"
|
||||
:inline="true"
|
||||
:show-empty="false"
|
||||
@select="select"
|
||||
:search-delay="0"
|
||||
<modal v-if="active" class="quick-actions">
|
||||
<div class="card">
|
||||
<input
|
||||
v-focus
|
||||
class="input"
|
||||
:class="{'is-loading': loading}"
|
||||
v-model="query"
|
||||
placeholder="Type a command or search..."
|
||||
@keyup="search"
|
||||
ref="searchInput"
|
||||
@keydown.down.prevent="() => select(0, 0)"
|
||||
/>
|
||||
|
||||
<div class="results">
|
||||
<div v-for="(r, k) in results" :key="k" class="result">
|
||||
<span class="result-title">
|
||||
{{ r.title }}
|
||||
</span>
|
||||
<div class="result-items">
|
||||
<button
|
||||
v-for="(i, key) in r.items"
|
||||
:key="key"
|
||||
:ref="`result-${k}_${key}`"
|
||||
@keydown.up.prevent="() => select(k, key - 1)"
|
||||
@keydown.down.prevent="() => select(k, key + 1)"
|
||||
@click.prevent.stop="() => doAction(r.type, i)"
|
||||
@keyup.prevent.enter="() => doAction(r.type, i)"
|
||||
>
|
||||
{{ i.title }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Multiselect from '@/components/input/multiselect'
|
||||
|
||||
import TaskService from '@/services/task'
|
||||
|
||||
const TYPE_LIST = 'list'
|
||||
const TYPE_TASK = 'task'
|
||||
const TYPE_ACTION = 'action'
|
||||
const TYPE_TEAM = 'team'
|
||||
|
||||
export default {
|
||||
name: 'quick-actions',
|
||||
components: {
|
||||
Multiselect,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
query: '',
|
||||
|
@ -59,40 +76,59 @@ export default {
|
|||
const lists = (Object.values(this.$store.state.lists).filter(l => {
|
||||
return l.title.toLowerCase().includes(this.query.toLowerCase())
|
||||
}) ?? [])
|
||||
.map(l => {
|
||||
l.type = TYPE_LIST
|
||||
return l
|
||||
})
|
||||
|
||||
const actions = this.availableActions
|
||||
.filter(a => a.title.includes(this.query.toLowerCase()))
|
||||
.map(a => {
|
||||
a.type = TYPE_ACTION
|
||||
return a
|
||||
})
|
||||
.filter(a => a.title.toLowerCase().includes(this.query.toLowerCase()))
|
||||
|
||||
return [...actions, ...lists, ...this.foundTasks, ...this.foundTeams]
|
||||
return [
|
||||
{
|
||||
type: TYPE_ACTION,
|
||||
title: 'Actions',
|
||||
items: actions,
|
||||
},
|
||||
{
|
||||
type: TYPE_TASK,
|
||||
title: 'Tasks',
|
||||
items: this.foundTasks,
|
||||
},
|
||||
{
|
||||
type: TYPE_LIST,
|
||||
title: 'Lists',
|
||||
items: lists,
|
||||
},
|
||||
{
|
||||
type: TYPE_TEAM,
|
||||
title: 'Teams',
|
||||
items: this.foundTeams,
|
||||
},
|
||||
].filter(i => i.items.length > 0)
|
||||
},
|
||||
nothing() {
|
||||
return this.search === '' || Object.keys(this.results).length === 0
|
||||
},
|
||||
loading() {
|
||||
return this.taskService.loading
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.taskService = new TaskService()
|
||||
},
|
||||
methods: {
|
||||
search(query) {
|
||||
this.query = query
|
||||
this.searchTasks(query)
|
||||
search() {
|
||||
this.searchTasks()
|
||||
},
|
||||
searchTasks(query) {
|
||||
searchTasks() {
|
||||
if (this.query === '') {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.taskSearchTimeout !== null) {
|
||||
clearTimeout(this.taskSearchTimeout)
|
||||
this.taskSearchTimeout = null
|
||||
}
|
||||
|
||||
this.taskSearchTimeout = setTimeout(() => {
|
||||
this.taskService.getAll({}, {s: query})
|
||||
this.taskService.getAll({}, {s: this.query})
|
||||
.then(r => {
|
||||
r = r.map(t => {
|
||||
t.type = TYPE_TASK
|
||||
|
@ -102,8 +138,8 @@ export default {
|
|||
})
|
||||
}, 150)
|
||||
},
|
||||
select(e) {
|
||||
switch (e.type) {
|
||||
doAction(type, e) {
|
||||
switch (type) {
|
||||
case TYPE_LIST:
|
||||
this.$router.push({name: 'list.index', params: {listId: e.id}})
|
||||
break
|
||||
|
@ -114,6 +150,35 @@ export default {
|
|||
break
|
||||
}
|
||||
},
|
||||
select(parentIndex, index) {
|
||||
|
||||
if (index < 0 && parentIndex === 0) {
|
||||
this.$refs.searchInput.focus()
|
||||
return
|
||||
}
|
||||
|
||||
if (index < 0) {
|
||||
parentIndex--;
|
||||
index = this.results[parentIndex].items.length - 1
|
||||
}
|
||||
|
||||
let elems = this.$refs[`result-${parentIndex}_${index}`]
|
||||
|
||||
if (this.results[parentIndex].items.length === index) {
|
||||
elems = this.$refs[`result-${parentIndex + 1}_0`]
|
||||
}
|
||||
|
||||
if (typeof elems === 'undefined' || elems.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
if (Array.isArray(elems)) {
|
||||
elems[0].focus()
|
||||
return
|
||||
}
|
||||
|
||||
elems.focus()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -23,3 +23,4 @@
|
|||
@import 'api-config';
|
||||
@import 'datepicker';
|
||||
@import 'notifications';
|
||||
@import 'quick-actions';
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
.quick-actions {
|
||||
|
||||
.modal-content {
|
||||
top: 6rem !important;
|
||||
transform: translate(-50%, -3rem) !important;
|
||||
}
|
||||
|
||||
.input {
|
||||
border: 0;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.results {
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
color: $grey-800;
|
||||
|
||||
.result {
|
||||
&-title {
|
||||
background: $grey-50;
|
||||
padding: .5rem;
|
||||
display: block;
|
||||
font-size: .75rem;
|
||||
}
|
||||
|
||||
&-items {
|
||||
button {
|
||||
font-size: .9rem;
|
||||
width: 100%;
|
||||
background: transparent;
|
||||
text-align: left;
|
||||
box-shadow: none;
|
||||
border-radius: 0;
|
||||
text-transform: none;
|
||||
font-family: $family-sans-serif;
|
||||
font-weight: normal;
|
||||
padding: .5rem .75rem;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
|
||||
&:focus, &:hover {
|
||||
background: $grey-50;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: $grey-100;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue