feat/alphabetical-sort (#1162)
Alphabetical sorting. Disables re-ordering when applied. Does not work with the search button as expected, but neither do the filters tbh... Works fine with the search in the filters menu. I know we talked about having a dropdown but since this is pretty much finished I thought I'd submit a PR. I am a bit short on time these days but may submit a new PR to add the dropdown ( should be simple enough ) Co-authored-by: Stefan Genov <stefantigro@gmail.com> Co-authored-by: Dominik Pschenitschni <mail@celement.de> Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/1162 Reviewed-by: konrad <k@knt.li> Reviewed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de> Co-authored-by: Michaelpalacce <stefantigro@gmail.com> Co-committed-by: Michaelpalacce <stefantigro@gmail.com>
This commit is contained in:
parent
d86eb9ea0b
commit
7ebca9afc5
4 changed files with 50 additions and 24 deletions
|
@ -1,23 +1,24 @@
|
||||||
<template>
|
<template>
|
||||||
<card class="filters has-overflow">
|
<card class="filters has-overflow">
|
||||||
<fancycheckbox v-model="params.filter_include_nulls">
|
|
||||||
{{ $t('filters.attributes.includeNulls') }}
|
|
||||||
</fancycheckbox>
|
|
||||||
<fancycheckbox
|
|
||||||
v-model="filters.requireAllFilters"
|
|
||||||
@change="setFilterConcat()"
|
|
||||||
>
|
|
||||||
{{ $t('filters.attributes.requireAll') }}
|
|
||||||
</fancycheckbox>
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label">
|
<fancycheckbox v-model="params.filter_include_nulls">
|
||||||
|
{{ $t('filters.attributes.includeNulls') }}
|
||||||
|
</fancycheckbox>
|
||||||
|
<fancycheckbox
|
||||||
|
v-model="filters.requireAllFilters"
|
||||||
|
@change="setFilterConcat()"
|
||||||
|
>
|
||||||
|
{{ $t('filters.attributes.requireAll') }}
|
||||||
|
</fancycheckbox>
|
||||||
|
<fancycheckbox @change="setDoneFilter" v-model="filters.done">
|
||||||
{{ $t('filters.attributes.showDoneTasks') }}
|
{{ $t('filters.attributes.showDoneTasks') }}
|
||||||
</label>
|
</fancycheckbox>
|
||||||
<div class="control">
|
<fancycheckbox
|
||||||
<fancycheckbox @change="setDoneFilter" v-model="filters.done">
|
v-if="!$route.name.includes('list.kanban') || !$route.name.includes('list.table')"
|
||||||
{{ $t('filters.attributes.showDoneTasks') }}
|
v-model="sortAlphabetically"
|
||||||
</fancycheckbox>
|
>
|
||||||
</div>
|
{{ $t('filters.attributes.sortAlphabetically') }}
|
||||||
|
</fancycheckbox>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label">{{ $t('misc.search') }}</label>
|
<label class="label">{{ $t('misc.search') }}</label>
|
||||||
|
@ -190,6 +191,7 @@ import NamespaceService from '@/services/namespace'
|
||||||
import EditLabels from '@/components/tasks/partials/editLabels.vue'
|
import EditLabels from '@/components/tasks/partials/editLabels.vue'
|
||||||
|
|
||||||
import {objectToSnakeCase} from '@/helpers/case'
|
import {objectToSnakeCase} from '@/helpers/case'
|
||||||
|
import {getDefaultParams} from '@/components/tasks/mixins/taskList'
|
||||||
|
|
||||||
// FIXME: merge with DEFAULT_PARAMS in taskList.js
|
// FIXME: merge with DEFAULT_PARAMS in taskList.js
|
||||||
const DEFAULT_PARAMS = {
|
const DEFAULT_PARAMS = {
|
||||||
|
@ -220,6 +222,8 @@ const DEFAULT_FILTERS = {
|
||||||
namespace: '',
|
namespace: '',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const ALPHABETICAL_SORT = 'title'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'filters',
|
name: 'filters',
|
||||||
components: {
|
components: {
|
||||||
|
@ -272,6 +276,18 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
sortAlphabetically: {
|
||||||
|
get() {
|
||||||
|
return this.params?.sort_by?.find(sortBy => sortBy === ALPHABETICAL_SORT) !== undefined
|
||||||
|
},
|
||||||
|
set(sortAlphabetically) {
|
||||||
|
this.params.sort_by = sortAlphabetically
|
||||||
|
? [ALPHABETICAL_SORT]
|
||||||
|
: getDefaultParams().sort_by
|
||||||
|
|
||||||
|
this.change()
|
||||||
|
},
|
||||||
|
},
|
||||||
foundLabels() {
|
foundLabels() {
|
||||||
return this.$store.getters['labels/filterLabelsByQuery'](this.labels, this.query)
|
return this.$store.getters['labels/filterLabelsByQuery'](this.labels, this.query)
|
||||||
},
|
},
|
||||||
|
|
|
@ -44,7 +44,6 @@ export default {
|
||||||
params = null,
|
params = null,
|
||||||
forceLoading = false,
|
forceLoading = false,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// Because this function is triggered every time on topNavigation, we're putting a condition here to only load it when we actually want to show tasks
|
// Because this function is triggered every time on topNavigation, we're putting a condition here to only load it when we actually want to show tasks
|
||||||
// FIXME: This is a bit hacky -> Cleanup.
|
// FIXME: This is a bit hacky -> Cleanup.
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -374,6 +374,7 @@
|
||||||
"includeNulls": "Include Tasks which don't have a value set",
|
"includeNulls": "Include Tasks which don't have a value set",
|
||||||
"requireAll": "Require all filters to be true for a task to show up",
|
"requireAll": "Require all filters to be true for a task to show up",
|
||||||
"showDoneTasks": "Show Done Tasks",
|
"showDoneTasks": "Show Done Tasks",
|
||||||
|
"sortAlphabetically": "Sort Alphabetically",
|
||||||
"enablePriority": "Enable Filter By Priority",
|
"enablePriority": "Enable Filter By Priority",
|
||||||
"enablePercentDone": "Enable Filter By Percent Done",
|
"enablePercentDone": "Enable Filter By Percent Done",
|
||||||
"dueDateRange": "Due Date Range",
|
"dueDateRange": "Due Date Range",
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
:disabled="!canWrite"
|
:disabled="!canWrite"
|
||||||
item-key="id"
|
item-key="id"
|
||||||
:component-data="{
|
:component-data="{
|
||||||
class: { 'dragging-disabled': !canWrite },
|
class: { 'dragging-disabled': !canWrite || isAlphabeticalSorting },
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<template #item="{element: t}">
|
<template #item="{element: t}">
|
||||||
|
@ -148,6 +148,7 @@ import {HAS_TASKS} from '@/store/mutation-types'
|
||||||
import Nothing from '@/components/misc/nothing.vue'
|
import Nothing from '@/components/misc/nothing.vue'
|
||||||
import Pagination from '@/components/misc/pagination.vue'
|
import Pagination from '@/components/misc/pagination.vue'
|
||||||
import Popup from '@/components/misc/popup'
|
import Popup from '@/components/misc/popup'
|
||||||
|
import { ALPHABETICAL_SORT } from '@/components/list/partials/filters'
|
||||||
|
|
||||||
import draggable from 'vuedraggable'
|
import draggable from 'vuedraggable'
|
||||||
import {calculateItemPosition} from '../../../helpers/calculateItemPosition'
|
import {calculateItemPosition} from '../../../helpers/calculateItemPosition'
|
||||||
|
@ -206,6 +207,9 @@ export default {
|
||||||
saveListView(this.$route.params.listId, this.$route.name)
|
saveListView(this.$route.params.listId, this.$route.name)
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
isAlphabeticalSorting() {
|
||||||
|
return this.params.sort_by.find( sortBy => sortBy === ALPHABETICAL_SORT ) !== undefined
|
||||||
|
},
|
||||||
firstNewPosition() {
|
firstNewPosition() {
|
||||||
if (this.tasks.length === 0) {
|
if (this.tasks.length === 0) {
|
||||||
return 0
|
return 0
|
||||||
|
@ -254,12 +258,18 @@ export default {
|
||||||
focusNewTaskInput() {
|
focusNewTaskInput() {
|
||||||
this.$refs.newTaskInput.$refs.newTaskInput.focus()
|
this.$refs.newTaskInput.$refs.newTaskInput.focus()
|
||||||
},
|
},
|
||||||
updateTaskList(task) {
|
updateTaskList( task ) {
|
||||||
const tasks = [
|
if ( this.isAlphabeticalSorting ) {
|
||||||
task,
|
// reload tasks with current filter and sorting
|
||||||
...this.tasks,
|
this.loadTasks(1, undefined, undefined, true)
|
||||||
]
|
}
|
||||||
this.tasks = tasks
|
else {
|
||||||
|
this.tasks = [
|
||||||
|
task,
|
||||||
|
...this.tasks,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
this.$store.commit(HAS_TASKS, true)
|
this.$store.commit(HAS_TASKS, true)
|
||||||
},
|
},
|
||||||
editTask(id) {
|
editTask(id) {
|
||||||
|
|
Loading…
Reference in a new issue