2018-12-25 23:41:55 +01:00
< template >
2020-07-22 12:29:03 +02:00
< div class = "is-max-width-desktop show-tasks" >
2021-12-29 17:22:14 +01:00
< fancycheckbox
@ change = "setDate"
class = "is-pulled-right"
v - if = "!showAll"
v - model = "showNulls"
>
{ { $t ( 'task.show.noDates' ) } }
< / fancycheckbox >
2021-12-28 23:50:04 +01:00
< h3 class = "mb-2" >
{ { pageTitle } }
2021-06-24 01:24:57 +02:00
< / h3 >
2021-12-29 15:44:13 +01:00
< p v-if = "!showAll" >
2021-12-28 23:50:04 +01:00
{ { $t ( 'task.show.select' ) } }
2021-12-29 15:44:13 +01:00
< datepicker-with-range @dateChanged ="setDate" / >
2021-12-28 23:50:04 +01:00
< / p >
2021-08-06 19:25:17 +02:00
< template v-if = "!loading && (!tasks || tasks.length === 0) && showNothingToDo" >
2021-06-24 01:24:57 +02:00
< h3 class = "nothing" > { { $t ( 'task.show.noTasks' ) } } < / h3 >
2021-12-28 23:50:04 +01:00
< LlamaCool class = "llama-cool" / >
2018-12-25 23:41:55 +01:00
< / template >
2021-08-06 19:25:17 +02:00
< div : class = "{ 'is-loading': loading}" class = "spinner" > < / div >
2021-01-24 14:00:21 +01:00
2021-01-24 15:37:19 +01:00
< card :padding = "false" class = "has-overflow" :has-content = "false" v-if = "tasks && tasks.length > 0" >
2021-01-24 14:00:21 +01:00
< div class = "tasks" >
< single-task-in-list
: key = "t.id"
class = "task"
v - for = "t in tasks"
: show - list = "true"
: the - task = "t"
@ taskUpdated = "updateTasks" / >
< / div >
< / card >
2018-12-25 23:41:55 +01:00
< / div >
< / template >
< script >
2021-12-28 23:50:04 +01:00
import SingleTaskInList from '@/components/tasks/partials/singleTaskInList'
2020-09-05 22:35:52 +02:00
import { mapState } from 'vuex'
2018-12-25 23:41:55 +01:00
2021-12-28 23:50:04 +01:00
import Fancycheckbox from '@/components/input/fancycheckbox'
import { LOADING , LOADING _MODULE } from '@/store/mutation-types'
2020-07-22 12:29:03 +02:00
2021-11-13 15:16:14 +01:00
import LlamaCool from '@/assets/llama-cool.svg?component'
2021-12-29 15:44:13 +01:00
import DatepickerWithRange from '@/components/date/datepickerWithRange'
2021-10-03 20:48:02 +02:00
2021-12-28 23:50:04 +01:00
function formatDate ( date ) {
return ` ${ date . getFullYear ( ) } - ${ date . getMonth ( ) + 1 } - ${ date . getDate ( ) } ${ date . getHours ( ) } : ${ date . getMinutes ( ) } `
}
2020-09-05 22:35:52 +02:00
export default {
name : 'ShowTasks' ,
components : {
2021-12-29 15:44:13 +01:00
DatepickerWithRange ,
2020-09-05 22:35:52 +02:00
Fancycheckbox ,
SingleTaskInList ,
2021-11-13 15:16:14 +01:00
LlamaCool ,
2020-09-05 22:35:52 +02:00
} ,
data ( ) {
return {
tasks : [ ] ,
showNulls : true ,
2021-01-16 20:20:43 +01:00
showOverdue : false ,
2020-07-22 12:29:03 +02:00
2021-12-29 15:44:13 +01:00
// TODO: Set the date range based on the default (to make sure it shows up in the picker) -> maybe also use a computed which depends on dateFrom and dateTo?
2021-12-28 23:50:04 +01:00
dateRange : null ,
2020-07-22 12:29:03 +02:00
2021-01-24 14:00:21 +01:00
showNothingToDo : false ,
2020-09-05 22:35:52 +02:00
}
} ,
props : {
startDate : Date ,
endDate : Date ,
showAll : Boolean ,
} ,
created ( ) {
this . loadPendingTasks ( )
} ,
2021-01-24 14:00:21 +01:00
mounted ( ) {
2021-12-28 23:50:04 +01:00
// FIXME
2021-01-24 14:00:21 +01:00
setTimeout ( ( ) => this . showNothingToDo = true , 100 )
} ,
2020-09-05 22:35:52 +02:00
watch : {
2021-09-08 11:59:38 +02:00
'$route' : {
handler : 'loadPendingTasks' ,
deep : true ,
} ,
2020-09-05 22:35:52 +02:00
} ,
2021-06-24 01:24:57 +02:00
computed : {
2021-12-28 23:50:04 +01:00
dateFrom ( ) {
const d = new Date ( Number ( this . $route . query . from ) )
return ! isNaN ( d )
? d
: this . startDate
} ,
dateTo ( ) {
const d = new Date ( Number ( this . $route . query . to ) )
return ! isNaN ( d )
? d
: this . endDate
} ,
pageTitle ( ) {
const title = this . showAll
? this . $t ( 'task.show.titleCurrent' )
: this . $t ( 'task.show.fromuntil' , {
2021-12-29 17:08:33 +01:00
from : this . format ( this . dateFrom , 'PPP' ) ,
until : this . format ( this . dateTo , 'PPP' )
2021-12-28 23:50:04 +01:00
} )
this . setTitle ( title )
return title
} ,
2021-06-24 01:24:57 +02:00
... mapState ( {
userAuthenticated : state => state . auth . authenticated ,
2021-08-06 19:25:17 +02:00
loading : state => state [ LOADING ] && state [ LOADING _MODULE ] === 'tasks' ,
2021-06-24 01:24:57 +02:00
} ) ,
} ,
2020-09-05 22:35:52 +02:00
methods : {
2021-12-29 15:44:13 +01:00
setDate ( { dateFrom , dateTo } ) {
2021-06-03 17:18:38 +02:00
this . $router . push ( {
name : this . $route . name ,
query : {
2021-12-29 15:44:13 +01:00
from : + new Date ( dateFrom ) ,
to : + new Date ( dateTo ) ,
2021-06-03 17:18:38 +02:00
showOverdue : this . showOverdue ,
showNulls : this . showNulls ,
} ,
} )
} ,
2021-10-11 19:37:20 +02:00
async loadPendingTasks ( ) {
2020-09-05 22:35:52 +02:00
// Since this route is authentication only, users would get an error message if they access the page unauthenticated.
// Since this component is mounted as the home page before unauthenticated users get redirected
// to the login page, they will almost always see the error message.
if ( ! this . userAuthenticated ) {
return
}
2020-07-22 12:29:03 +02:00
2021-06-03 17:18:38 +02:00
this . showOverdue = this . $route . query . showOverdue
this . showNulls = this . $route . query . showNulls
2020-07-07 22:07:13 +02:00
2020-09-05 22:35:52 +02:00
const params = {
sort _by : [ 'due_date' , 'id' ] ,
2021-02-20 18:35:29 +01:00
order _by : [ 'desc' , 'desc' ] ,
2020-09-05 22:35:52 +02:00
filter _by : [ 'done' ] ,
filter _value : [ false ] ,
filter _comparator : [ 'equals' ] ,
filter _concat : 'and' ,
filter _include _nulls : this . showNulls ,
}
2021-12-29 16:03:05 +01:00
// FIXME: Add button to show / hide overdue
2020-09-05 22:35:52 +02:00
if ( ! this . showAll ) {
if ( this . showNulls ) {
params . filter _by . push ( 'start_date' )
2021-12-28 23:50:04 +01:00
params . filter _value . push ( this . dateFrom )
2020-09-05 22:35:52 +02:00
params . filter _comparator . push ( 'greater' )
2020-05-09 15:46:05 +02:00
2020-09-05 22:35:52 +02:00
params . filter _by . push ( 'end_date' )
2021-12-28 23:50:04 +01:00
params . filter _value . push ( this . dateTo )
2020-05-09 15:46:05 +02:00
params . filter _comparator . push ( 'less' )
2018-12-25 23:41:55 +01:00
}
2020-09-05 22:35:52 +02:00
params . filter _by . push ( 'due_date' )
2021-12-29 17:22:14 +01:00
params . filter _value . push ( this . dateTo )
2020-09-05 22:35:52 +02:00
params . filter _comparator . push ( 'less' )
2021-01-16 20:20:43 +01:00
if ( ! this . showOverdue ) {
params . filter _by . push ( 'due_date' )
2021-12-29 17:22:14 +01:00
params . filter _value . push ( this . dateFrom )
2021-01-16 20:20:43 +01:00
params . filter _comparator . push ( 'greater' )
}
2020-09-05 22:35:52 +02:00
}
2021-10-11 19:37:20 +02:00
const tasks = await this . $store . dispatch ( 'tasks/loadTasks' , params )
2021-02-20 18:35:29 +01:00
2021-10-11 19:37:20 +02:00
// FIXME: sort tasks in computed
// Sort all tasks to put those with a due date before the ones without a due date, the
// soonest before the later ones.
// We can't use the api sorting here because that sorts tasks with a due date after
// ones without a due date.
2021-10-17 16:30:34 +02:00
this . tasks = tasks . sort ( ( a , b ) => {
const sortByDueDate = b . dueDate - a . dueDate
return sortByDueDate === 0
? b . id - a . id
: sortByDueDate
} )
2020-09-05 22:35:52 +02:00
} ,
2021-10-11 19:37:20 +02:00
// FIXME: this modification should happen in the store
2020-09-05 22:35:52 +02:00
updateTasks ( updatedTask ) {
for ( const t in this . tasks ) {
if ( this . tasks [ t ] . id === updatedTask . id ) {
2021-08-19 21:35:38 +02:00
this . tasks [ t ] = updatedTask
2020-09-28 20:37:06 +02:00
// Move the task to the end of the done tasks if it is now done
if ( updatedTask . done ) {
this . tasks . splice ( t , 1 )
this . tasks . push ( updatedTask )
}
2020-09-05 22:35:52 +02:00
break
2020-03-23 23:24:14 +01:00
}
2020-09-05 22:35:52 +02:00
}
2018-12-25 23:41:55 +01:00
} ,
2020-09-05 22:35:52 +02:00
} ,
}
2018-12-25 23:41:55 +01:00
< / script >
2021-10-18 14:22:47 +02:00
< style lang = "scss" scoped >
2021-11-13 15:16:14 +01:00
h3 {
text - align : left ;
2021-10-18 14:22:47 +02:00
2021-11-13 15:16:14 +01:00
& . nothing {
text - align : center ;
margin - top : 3 rem ;
2021-10-18 14:22:47 +02:00
}
2021-11-13 15:16:14 +01:00
: deep ( . input ) {
width : 190 px ;
vertical - align : middle ;
margin : .5 rem 0 ;
2021-10-18 14:22:47 +02:00
}
2021-11-13 15:16:14 +01:00
}
2021-10-18 14:22:47 +02:00
2021-11-16 22:44:07 +01:00
. tasks {
padding : .5 rem ;
}
2021-11-13 15:16:14 +01:00
. llama - cool {
margin - top : 2 rem ;
2021-10-18 14:22:47 +02:00
}
< / style >