feat: allow selecting multiple labels at once (#945)
Co-authored-by: kolaente <k@knt.li> Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/945 Reviewed-by: dpschen <dpschen@noreply.kolaente.de> Co-authored-by: konrad <k@knt.li> Co-committed-by: konrad <k@knt.li>
This commit is contained in:
parent
70a50ca1c2
commit
9b7882de7a
2 changed files with 20 additions and 16 deletions
|
@ -7,7 +7,9 @@
|
||||||
@focus="focus"
|
@focus="focus"
|
||||||
>
|
>
|
||||||
<div class="control" :class="{'is-loading': loading || localLoading}">
|
<div class="control" :class="{'is-loading': loading || localLoading}">
|
||||||
<div class="input-wrapper input" :class="{'has-multiple': multiple && Array.isArray(internalValue) && internalValue.length > 0}">
|
<div
|
||||||
|
class="input-wrapper input"
|
||||||
|
:class="{'has-multiple': hasMultiple}">
|
||||||
<template v-if="Array.isArray(internalValue)">
|
<template v-if="Array.isArray(internalValue)">
|
||||||
<template v-for="(item, key) in internalValue">
|
<template v-for="(item, key) in internalValue">
|
||||||
<slot name="tag" :item="item">
|
<slot name="tag" :item="item">
|
||||||
|
@ -81,7 +83,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { i18n } from '@/i18n'
|
import {i18n} from '@/i18n'
|
||||||
import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
|
import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -134,9 +136,7 @@ export default {
|
||||||
// If true, will provide an "add this as a new value" entry which fires an @create event when clicking on it.
|
// If true, will provide an "add this as a new value" entry which fires an @create event when clicking on it.
|
||||||
creatable: {
|
creatable: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default() {
|
default: false,
|
||||||
return false
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
// The text shown next to the new value option.
|
// The text shown next to the new value option.
|
||||||
createPlaceholder: {
|
createPlaceholder: {
|
||||||
|
@ -155,23 +155,17 @@ export default {
|
||||||
// If true, allows for selecting multiple items. v-model will be an array with all selected values in that case.
|
// If true, allows for selecting multiple items. v-model will be an array with all selected values in that case.
|
||||||
multiple: {
|
multiple: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default() {
|
default: false,
|
||||||
return false
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
// If true, displays the search results inline instead of using a dropdown.
|
// If true, displays the search results inline instead of using a dropdown.
|
||||||
inline: {
|
inline: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default() {
|
default: false,
|
||||||
return false
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
// If true, shows search results when no query is specified.
|
// If true, shows search results when no query is specified.
|
||||||
showEmpty: {
|
showEmpty: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default() {
|
default: true,
|
||||||
return true
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
// The delay in ms after which the search event will be fired. Used to avoid hitting the network on every keystroke.
|
// The delay in ms after which the search event will be fired. Used to avoid hitting the network on every keystroke.
|
||||||
searchDelay: {
|
searchDelay: {
|
||||||
|
@ -180,8 +174,12 @@ export default {
|
||||||
return 200
|
return 200
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
closeAfterSelect: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Available events:
|
* Available events:
|
||||||
* @search: Triggered every time the search query input changes
|
* @search: Triggered every time the search query input changes
|
||||||
|
@ -234,6 +232,9 @@ export default {
|
||||||
|
|
||||||
return this.searchResults
|
return this.searchResults
|
||||||
},
|
},
|
||||||
|
hasMultiple() {
|
||||||
|
return this.multiple && Array.isArray(this.internalValue) && this.internalValue.length > 0
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// Searching will be triggered with a 200ms delay to avoid searching on every keyup event.
|
// Searching will be triggered with a 200ms delay to avoid searching on every keyup event.
|
||||||
|
@ -285,7 +286,9 @@ export default {
|
||||||
this.$emit('update:modelValue', this.internalValue)
|
this.$emit('update:modelValue', this.internalValue)
|
||||||
this.$emit('select', object)
|
this.$emit('select', object)
|
||||||
this.setSelectedObject(object)
|
this.setSelectedObject(object)
|
||||||
this.closeSearchResults()
|
if (this.closeAfterSelect && this.filteredSearchResults.length > 0 && !this.creatableAvailable) {
|
||||||
|
this.closeSearchResults()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
setSelectedObject(object, resetOnly = false) {
|
setSelectedObject(object, resetOnly = false) {
|
||||||
this.internalValue = object
|
this.internalValue = object
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
:create-placeholder="$t('task.label.createPlaceholder')"
|
:create-placeholder="$t('task.label.createPlaceholder')"
|
||||||
v-model="labels"
|
v-model="labels"
|
||||||
:search-delay="10"
|
:search-delay="10"
|
||||||
|
:close-after-select="false"
|
||||||
>
|
>
|
||||||
<template #tag="props">
|
<template #tag="props">
|
||||||
<span
|
<span
|
||||||
|
|
Loading…
Reference in a new issue