diff --git a/website/client/components/tasks/column.vue b/website/client/components/tasks/column.vue index 68b5c93b3c..2b58b13a81 100644 --- a/website/client/components/tasks/column.vue +++ b/website/client/components/tasks/column.vue @@ -15,7 +15,7 @@ v-model="quickAddText", @keyup.enter="quickAdd", ref="quickAdd", ) - .sortable-tasks(ref="tasksList", v-sortable='', @onsort='sorted') + .sortable-tasks(ref="tasksList", v-sortable='activeFilters[type].label !== "scheduled"', @onsort='sorted', data-sortableId) task( v-for="task in taskList", :key="task.id", :task="task", @@ -365,19 +365,25 @@ export default { loadCompletedTodos: 'tasks:fetchCompletedTodos', createTask: 'tasks:create', }), - sorted (data) { + async sorted (data) { + const filteredList = this.taskList.filter(this.activeFilters[this.type].filter); const sorting = this.taskList; - const taskIdToMove = this.taskList[data.oldIndex]._id; + const taskIdToMove = filteredList[data.oldIndex]._id; + // Server + const taskIdToReplace = filteredList[data.newIndex]; + const newIndexOnServer = this.taskList.findIndex(taskId => taskId === taskIdToReplace); + let newOrder = await this.$store.dispatch('tasks:move', { + taskId: taskIdToMove, + position: newIndexOnServer, + }); + this.user.tasksOrder[`${this.type}s`] = newOrder; + + // Client if (sorting) { const deleted = sorting.splice(data.oldIndex, 1); sorting.splice(data.newIndex, 0, deleted[0]); } - - this.$store.dispatch('tasks:move', { - taskId: taskIdToMove, - position: data.newIndex, - }); }, quickAdd () { const task = taskDefaults({type: this.type, text: this.quickAddText}); @@ -394,6 +400,14 @@ export default { } this.activeFilters[type] = filter; + if (['scheduled', 'due'].indexOf(filter.label) === -1) { + let sortedTasks = this.$store.dispatch('tasks:order', [ + this.tasks[`${type}s`], + this.user.tasksOrder, + ]); + this.tasks[`${type}s`] = sortedTasks[`${type}s`]; + } + if (filter.sort) { this.tasks[`${type}s`] = sortBy(this.tasks[`${type}s`], filter.sort); } diff --git a/website/client/directives/sortable.directive.js b/website/client/directives/sortable.directive.js index b7d2820e19..09ddbf15ca 100644 --- a/website/client/directives/sortable.directive.js +++ b/website/client/directives/sortable.directive.js @@ -1,23 +1,45 @@ import Sortable from 'sortablejs'; +import uuid from 'uuid'; -let emit = (vnode, eventName, data) => { - let handlers = vnode.data && vnode.data.on || - vnode.componentOptions && vnode.componentOptions.listeners; +let emit = (vNode, eventName, data) => { + let handlers = vNode.data && vNode.data.on || + vNode.componentOptions && vNode.componentOptions.listeners; if (handlers && handlers[eventName]) { handlers[eventName].fns(data); } }; +let sortableReferences = {}; + +function createSortable (el, vNode) { + let sortableRef = Sortable.create(el, { + onSort: (evt) => { + emit(vNode, 'onsort', { + oldIndex: evt.oldIndex, + newIndex: evt.newIndex, + }); + }, + }); + + let uniqueId = uuid(); + sortableReferences[uniqueId] = sortableRef; + el.dataset.sortableId = uniqueId; +} + export default { - bind (el, binding, vnode) { - Sortable.create(el, { - onSort: (evt) => { - emit(vnode, 'onsort', { - oldIndex: evt.oldIndex, - newIndex: evt.newIndex, - }); - }, - }); + bind (el, binding, vNode) { + createSortable(el, vNode); + }, + unbind (el) { + if (sortableReferences[el.dataset.sortableId]) sortableReferences[el.dataset.sortableId].destroy(); + }, + update (el, vNode) { + if (sortableReferences[el.dataset.sortableId] && !vNode.value) { + sortableReferences[el.dataset.sortableId].destroy(); + delete sortableReferences[el.dataset.sortableId]; + return; + } + if (!sortableReferences[el.dataset.sortableId]) createSortable(el, vNode); }, };