2021-09-10 14:39:18 +00:00
|
|
|
import TaskCollectionService from '@/services/taskCollection'
|
2021-07-25 14:02:49 +00:00
|
|
|
import cloneDeep from 'lodash/cloneDeep'
|
2021-07-28 19:56:29 +00:00
|
|
|
import {calculateItemPosition} from '../../../helpers/calculateItemPosition'
|
2020-04-01 20:13:57 +00:00
|
|
|
|
2021-09-10 13:02:52 +00:00
|
|
|
// FIXME: merge with DEFAULT_PARAMS in filters.vue
|
|
|
|
const DEFAULT_PARAMS = {
|
|
|
|
sort_by: ['position', 'id'],
|
|
|
|
order_by: ['asc', 'desc'],
|
|
|
|
filter_by: ['done'],
|
|
|
|
filter_value: ['false'],
|
|
|
|
filter_comparator: ['equals'],
|
|
|
|
filter_concat: 'and',
|
|
|
|
}
|
|
|
|
|
2021-09-10 14:39:18 +00:00
|
|
|
function createPagination(totalPages, currentPage) {
|
|
|
|
const pages = []
|
|
|
|
for (let i = 0; i < totalPages; i++) {
|
|
|
|
|
|
|
|
// Show ellipsis instead of all pages
|
|
|
|
if (
|
|
|
|
i > 0 && // Always at least the first page
|
|
|
|
(i + 1) < totalPages && // And the last page
|
|
|
|
(
|
|
|
|
// And the current with current + 1 and current - 1
|
|
|
|
(i + 1) > currentPage + 1 ||
|
|
|
|
(i + 1) < currentPage - 1
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
// Only add an ellipsis if the last page isn't already one
|
|
|
|
if (pages[i - 1] && !pages[i - 1].isEllipsis) {
|
|
|
|
pages.push({
|
|
|
|
number: 0,
|
|
|
|
isEllipsis: true,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
pages.push({
|
|
|
|
number: i + 1,
|
|
|
|
isEllipsis: false,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return pages
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getRouteForPagination(page = 1, type = 'list') {
|
|
|
|
return {
|
|
|
|
name: 'list.' + type,
|
|
|
|
params: {
|
|
|
|
type: type,
|
|
|
|
},
|
|
|
|
query: {
|
|
|
|
page: page,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-01 20:13:57 +00:00
|
|
|
/**
|
|
|
|
* This mixin provides a base set of methods and properties to get tasks on a list.
|
|
|
|
*/
|
|
|
|
export default {
|
|
|
|
data() {
|
|
|
|
return {
|
2021-09-10 14:39:18 +00:00
|
|
|
taskCollectionService: new TaskCollectionService(),
|
2020-04-01 20:13:57 +00:00
|
|
|
tasks: [],
|
|
|
|
|
|
|
|
currentPage: 0,
|
|
|
|
|
2021-01-30 16:17:04 +00:00
|
|
|
loadedList: null,
|
|
|
|
|
2020-04-01 20:13:57 +00:00
|
|
|
showTaskSearch: false,
|
|
|
|
searchTerm: '',
|
2020-06-11 15:34:13 +00:00
|
|
|
|
|
|
|
showTaskFilter: false,
|
2021-09-10 13:02:52 +00:00
|
|
|
params: DEFAULT_PARAMS,
|
2020-04-01 20:13:57 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
watch: {
|
2021-09-10 14:39:18 +00:00
|
|
|
// Only listen for query path changes
|
|
|
|
'$route.query': {
|
|
|
|
handler: 'loadTasksForPage',
|
|
|
|
immediate: true,
|
|
|
|
},
|
2021-07-20 20:16:44 +00:00
|
|
|
'$route.path': 'loadTasksOnSavedFilter',
|
2020-04-01 20:13:57 +00:00
|
|
|
},
|
2021-09-10 14:39:18 +00:00
|
|
|
computed: {
|
|
|
|
pages() {
|
|
|
|
return createPagination(this.taskCollectionService.totalPages, this.currentPage)
|
|
|
|
},
|
2020-04-01 20:13:57 +00:00
|
|
|
},
|
|
|
|
methods: {
|
2020-06-11 15:34:13 +00:00
|
|
|
loadTasks(
|
|
|
|
page,
|
|
|
|
search = '',
|
|
|
|
params = null,
|
2021-07-20 20:16:44 +00:00
|
|
|
forceLoading = false,
|
2020-06-11 15:34:13 +00:00
|
|
|
) {
|
2020-04-25 23:11:34 +00:00
|
|
|
|
2020-11-01 17:36:00 +00:00
|
|
|
// 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
|
2020-04-25 23:11:34 +00:00
|
|
|
// FIXME: This is a bit hacky -> Cleanup.
|
|
|
|
if (
|
|
|
|
this.$route.name !== 'list.list' &&
|
2021-07-20 20:16:44 +00:00
|
|
|
this.$route.name !== 'list.table' &&
|
|
|
|
!forceLoading
|
2020-04-25 23:11:34 +00:00
|
|
|
) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-02-20 15:43:39 +00:00
|
|
|
if (params === null) {
|
|
|
|
params = this.params
|
|
|
|
}
|
|
|
|
|
|
|
|
if (search !== '') {
|
|
|
|
params.s = search
|
|
|
|
}
|
|
|
|
|
2021-01-30 16:17:04 +00:00
|
|
|
const list = {listId: parseInt(this.$route.params.listId)}
|
|
|
|
|
|
|
|
const currentList = {
|
|
|
|
id: list.listId,
|
|
|
|
params: params,
|
|
|
|
search: search,
|
2021-02-20 16:10:56 +00:00
|
|
|
page: page,
|
2021-01-30 16:17:04 +00:00
|
|
|
}
|
2021-07-20 20:16:44 +00:00
|
|
|
if (JSON.stringify(currentList) === JSON.stringify(this.loadedList) && !forceLoading) {
|
2021-01-30 16:17:04 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-09-10 14:39:18 +00:00
|
|
|
this.tasks = []
|
2020-05-21 09:36:42 +00:00
|
|
|
|
2021-01-30 16:17:04 +00:00
|
|
|
this.taskCollectionService.getAll(list, params, page)
|
2020-04-01 20:13:57 +00:00
|
|
|
.then(r => {
|
2021-09-10 14:39:18 +00:00
|
|
|
this.tasks = r
|
2020-04-01 20:13:57 +00:00
|
|
|
this.currentPage = page
|
|
|
|
|
2021-02-20 15:43:39 +00:00
|
|
|
this.loadedList = cloneDeep(currentList)
|
2020-04-01 20:13:57 +00:00
|
|
|
})
|
|
|
|
.catch(e => {
|
2021-06-22 20:07:57 +00:00
|
|
|
this.error(e)
|
2020-04-01 20:13:57 +00:00
|
|
|
})
|
|
|
|
},
|
2021-09-10 14:39:18 +00:00
|
|
|
|
2020-04-01 20:13:57 +00:00
|
|
|
loadTasksForPage(e) {
|
|
|
|
// The page parameter can be undefined, in the case where the user loads a new list from the side bar menu
|
2020-04-14 21:37:08 +00:00
|
|
|
let page = Number(e.page)
|
2020-04-01 20:13:57 +00:00
|
|
|
if (typeof e.page === 'undefined') {
|
|
|
|
page = 1
|
|
|
|
}
|
|
|
|
let search = e.search
|
|
|
|
if (typeof e.search === 'undefined') {
|
|
|
|
search = ''
|
|
|
|
}
|
|
|
|
this.initTasks(page, search)
|
|
|
|
},
|
2021-07-20 20:16:44 +00:00
|
|
|
loadTasksOnSavedFilter() {
|
|
|
|
if(typeof this.$route.params.listId !== 'undefined' && parseInt(this.$route.params.listId) < 0) {
|
|
|
|
this.loadTasks(1, '', null, true)
|
|
|
|
}
|
|
|
|
},
|
2020-04-01 20:13:57 +00:00
|
|
|
sortTasks() {
|
|
|
|
if (this.tasks === null || this.tasks === []) {
|
|
|
|
return
|
|
|
|
}
|
2020-06-11 15:34:13 +00:00
|
|
|
return this.tasks.sort(function (a, b) {
|
2020-04-01 20:13:57 +00:00
|
|
|
if (a.done < b.done)
|
|
|
|
return -1
|
|
|
|
if (a.done > b.done)
|
|
|
|
return 1
|
|
|
|
|
2021-07-28 19:56:29 +00:00
|
|
|
if (a.position < b.position)
|
2020-04-01 20:13:57 +00:00
|
|
|
return -1
|
2021-07-28 19:56:29 +00:00
|
|
|
if (a.position > b.position)
|
2020-04-01 20:13:57 +00:00
|
|
|
return 1
|
|
|
|
return 0
|
|
|
|
})
|
|
|
|
},
|
|
|
|
searchTasks() {
|
2020-05-22 15:32:18 +00:00
|
|
|
// Only search if the search term changed
|
|
|
|
if (this.$route.query === this.searchTerm) {
|
2020-04-01 20:13:57 +00:00
|
|
|
return
|
|
|
|
}
|
2020-05-22 15:32:18 +00:00
|
|
|
|
2020-04-01 20:13:57 +00:00
|
|
|
this.$router.push({
|
2020-04-25 23:11:34 +00:00
|
|
|
name: 'list.list',
|
2020-09-05 20:35:52 +00:00
|
|
|
query: {search: this.searchTerm},
|
2020-04-01 20:13:57 +00:00
|
|
|
})
|
|
|
|
},
|
|
|
|
hideSearchBar() {
|
|
|
|
// This is a workaround.
|
|
|
|
// When clicking on the search button, @blur from the input is fired. If we
|
|
|
|
// would then directly hide the whole search bar directly, no click event
|
|
|
|
// from the button gets fired. To prevent this, we wait 200ms until we hide
|
|
|
|
// everything so the button has a chance of firering the search event.
|
|
|
|
setTimeout(() => {
|
|
|
|
this.showTaskSearch = false
|
|
|
|
}, 200)
|
|
|
|
},
|
2021-07-28 19:56:29 +00:00
|
|
|
saveTaskPosition(e) {
|
|
|
|
this.drag = false
|
|
|
|
|
|
|
|
const task = this.tasks[e.newIndex]
|
|
|
|
const taskBefore = this.tasks[e.newIndex - 1] ?? null
|
|
|
|
const taskAfter = this.tasks[e.newIndex + 1] ?? null
|
|
|
|
|
|
|
|
task.position = calculateItemPosition(taskBefore !== null ? taskBefore.position : null, taskAfter !== null ? taskAfter.position : null)
|
|
|
|
|
|
|
|
this.$store.dispatch('tasks/update', task)
|
|
|
|
.then(r => {
|
|
|
|
this.$set(this.tasks, e.newIndex, r)
|
|
|
|
})
|
|
|
|
.catch(e => {
|
|
|
|
this.error(e)
|
|
|
|
})
|
|
|
|
},
|
2021-09-10 14:39:18 +00:00
|
|
|
getRouteForPagination,
|
2020-09-05 20:35:52 +00:00
|
|
|
},
|
2020-04-01 20:13:57 +00:00
|
|
|
}
|