Add task filter for assignees (#349)

Rearrange filter

Add task filter for assignees

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/349
Co-Authored-By: konrad <konrad@kola-entertainments.de>
Co-Committed-By: konrad <konrad@kola-entertainments.de>
This commit is contained in:
konrad 2020-12-19 21:39:25 +00:00
parent 69a9f867b4
commit 8c41cd54a8

View file

@ -18,18 +18,6 @@
</fancycheckbox> </fancycheckbox>
</div> </div>
</div> </div>
<div class="field">
<label class="label">Due Date</label>
<div class="control">
<flat-pickr
:config="flatPickerConfig"
@on-close="setDueDateFilter"
class="input"
placeholder="Due Date Range"
v-model="filters.dueDate"
/>
</div>
</div>
<div class="field"> <div class="field">
<label class="label">Priority</label> <label class="label">Priority</label>
<div class="control single-value-control"> <div class="control single-value-control">
@ -46,6 +34,34 @@
</fancycheckbox> </fancycheckbox>
</div> </div>
</div> </div>
<div class="field">
<label class="label">Percent Done</label>
<div class="control single-value-control">
<percent-done-select
v-model.number="filters.percentDone"
@change="setPercentDoneFilter"
:disabled="!filters.usePercentDone"
/>
<fancycheckbox
v-model="filters.usePercentDone"
@change="setPercentDoneFilter"
>
Enable Filter By Percent Done
</fancycheckbox>
</div>
</div>
<div class="field">
<label class="label">Due Date</label>
<div class="control">
<flat-pickr
:config="flatPickerConfig"
@on-close="setDueDateFilter"
class="input"
placeholder="Due Date Range"
v-model="filters.dueDate"
/>
</div>
</div>
<div class="field"> <div class="field">
<label class="label">Start Date</label> <label class="label">Start Date</label>
<div class="control"> <div class="control">
@ -82,20 +98,37 @@
/> />
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label class="label">Percent Done</label> <label class="label">Assignees</label>
<div class="control single-value-control"> <div class="control">
<percent-done-select <multiselect
v-model.number="filters.percentDone" :clear-on-select="true"
@change="setPercentDoneFilter" :close-on-select="true"
:disabled="!filters.usePercentDone" :hide-selected="true"
/> :internal-search="true"
<fancycheckbox :loading="userService.loading"
v-model="filters.usePercentDone" :multiple="true"
@change="setPercentDoneFilter" :options="foundUsers"
:options-limit="300"
:searchable="true"
:showNoOptions="false"
:taggable="false"
@search-change="findUser"
@select="user => addUser(user)"
@remove="removeUser"
label="username"
placeholder="Type to search for a user..."
track-by="id"
v-model="users"
> >
Enable Filter By Percent Done <template slot="clear" slot-scope="props">
</fancycheckbox> <div
@mousedown.prevent.stop="clearAllUsers(props.search)"
class="multiselect__clear"
v-if="users.length"></div>
</template>
</multiselect>
</div> </div>
</div> </div>
</div> </div>
@ -106,11 +139,16 @@
import Fancycheckbox from '../../input/fancycheckbox' import Fancycheckbox from '../../input/fancycheckbox'
import flatPickr from 'vue-flatpickr-component' import flatPickr from 'vue-flatpickr-component'
import 'flatpickr/dist/flatpickr.css' import 'flatpickr/dist/flatpickr.css'
import Multiselect from 'vue-multiselect'
import {formatISO} from 'date-fns' import {formatISO} from 'date-fns'
import differenceWith from 'lodash/differenceWith'
import PrioritySelect from '@/components/tasks/partials/prioritySelect' import PrioritySelect from '@/components/tasks/partials/prioritySelect'
import PercentDoneSelect from '@/components/tasks/partials/percentDoneSelect' import PercentDoneSelect from '@/components/tasks/partials/percentDoneSelect'
import UserService from '../../../services/user'
export default { export default {
name: 'filters', name: 'filters',
components: { components: {
@ -118,6 +156,7 @@ export default {
Fancycheckbox, Fancycheckbox,
flatPickr, flatPickr,
PercentDoneSelect, PercentDoneSelect,
Multiselect,
}, },
data() { data() {
return { return {
@ -141,6 +180,7 @@ export default {
percentDone: 0, percentDone: 0,
usePercentDone: false, usePercentDone: false,
reminders: '', reminders: '',
assignees: '',
}, },
flatPickerConfig: { flatPickerConfig: {
altFormat: 'j M Y H:i', altFormat: 'j M Y H:i',
@ -150,8 +190,15 @@ export default {
time_24hr: true, time_24hr: true,
mode: 'range', mode: 'range',
}, },
userService: UserService,
foundUsers: [],
users: [],
} }
}, },
created() {
this.userService = new UserService()
},
mounted() { mounted() {
this.params = this.value this.params = this.value
this.filters.requireAllFilters = this.params.filter_concat === 'and' this.filters.requireAllFilters = this.params.filter_concat === 'and'
@ -254,8 +301,8 @@ export default {
this.filters[variableName] = `${start.getFullYear()}-${start.getMonth() + 1}-${start.getDate()} to ${end.getFullYear()}-${end.getMonth() + 1}-${end.getDate()}` this.filters[variableName] = `${start.getFullYear()}-${start.getMonth() + 1}-${start.getDate()} to ${end.getFullYear()}-${end.getMonth() + 1}-${end.getDate()}`
} }
}, },
setSingleValueFilter(filterName, variableName, useVariableName) { setSingleValueFilter(filterName, variableName, useVariableName = '', comparator = 'equals') {
if (!this.filters[useVariableName]) { if (useVariableName !== '' && !this.filters[useVariableName]) {
this.removePropertyFromFilter(filterName) this.removePropertyFromFilter(filterName)
return return
} }
@ -270,7 +317,7 @@ export default {
if (!found) { if (!found) {
this.params.filter_by.push(filterName) this.params.filter_by.push(filterName)
this.params.filter_comparator.push('equals') this.params.filter_comparator.push(comparator)
this.params.filter_value.push(this.filters[variableName]) this.params.filter_value.push(this.filters[variableName])
} }
@ -367,6 +414,51 @@ export default {
prepareReminders() { prepareReminders() {
this.prepareDate('reminders', 'reminders') this.prepareDate('reminders', 'reminders')
}, },
clearUsers() {
this.$set(this, 'foundUsers', [])
},
findUser(query) {
if(query === '') {
this.clearUsers()
}
this.userService.getAll({}, {s: query})
.then(response => {
// Filter the results to not include users who are already assigneid
this.$set(this, 'foundUsers', differenceWith(response, this.users, (first, second) => {
return first.id === second.id
}))
})
.catch(e => {
this.error(e, this)
})
},
addUser() {
this.$nextTick(() => {
this.changeAssigneeFilter()
})
},
removeUser() {
this.$nextTick(() => {
this.changeAssigneeFilter()
})
},
changeAssigneeFilter() {
if(this.users.length === 0) {
this.removePropertyFromFilter('assignees')
this.change()
return
}
let userIDs = []
this.users.forEach(u => {
userIDs.push(u.id)
})
this.$set(this.filters, 'assignees', userIDs.join(','))
this.setSingleValueFilter('assignees', 'assignees', '', 'in')
},
}, },
} }
</script> </script>