Load task from server if not found locally
Signed-off-by: Raimund Schlüßler <raimund.schluessler@mailbox.org> Co-Authored-By: John Molakvoæ <skjnldsv@users.noreply.github.com>
This commit is contained in:
parent
e57091a08b
commit
741af5a5e5
3 changed files with 148 additions and 5 deletions
|
@ -21,7 +21,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<template>
|
||||
<div class="content-wrapper">
|
||||
<div v-if="task!=undefined"
|
||||
<div v-if="task"
|
||||
:class="{'disabled': task.calendar.readOnly}"
|
||||
class="flex-container"
|
||||
>
|
||||
|
@ -340,7 +340,8 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
<div v-else class="notice">
|
||||
<span>{{ $t('tasks', 'Task not found!') }}</span>
|
||||
<span v-if="loading">{{ $t('tasks', 'Loading task from server.') }}</span>
|
||||
<span v-else>{{ $t('tasks', 'Task not found!') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -500,6 +501,7 @@ export default {
|
|||
},
|
||||
data: function() {
|
||||
return {
|
||||
loading: false,
|
||||
edit: '',
|
||||
tmpTask: {
|
||||
summary: '',
|
||||
|
@ -572,10 +574,21 @@ export default {
|
|||
},
|
||||
...mapGetters({
|
||||
writableCalendars: 'getSortedWritableCalendars',
|
||||
task: 'getTaskByRoute'
|
||||
task: 'getTaskByRoute',
|
||||
calendar: 'getCalendarByRoute',
|
||||
calendars: 'getSortedCalendars',
|
||||
}),
|
||||
},
|
||||
|
||||
watch: {
|
||||
$route: 'loadTask',
|
||||
calendars: 'loadTask',
|
||||
},
|
||||
|
||||
created() {
|
||||
this.loadTask()
|
||||
},
|
||||
|
||||
/**
|
||||
* Before we close the details view, we save possible edits.
|
||||
*
|
||||
|
@ -615,8 +628,28 @@ export default {
|
|||
'toggleAllDay',
|
||||
'moveTask',
|
||||
'setClassification',
|
||||
'getTaskByUri',
|
||||
]),
|
||||
|
||||
async loadTask() {
|
||||
if (this.task === undefined || this.task === null) {
|
||||
const calendars = this.calendar ? [this.calendar] : this.calendars
|
||||
for (const calendar of calendars) {
|
||||
this.loading = true
|
||||
try {
|
||||
const task = await this.getTaskByUri({ calendar, taskUri: this.$route.params.taskId })
|
||||
// If we found the task, we don't need to query the other calendars.
|
||||
if (task) {
|
||||
break
|
||||
}
|
||||
} catch {
|
||||
console.debug('Task ' + this.$route.params.taskId + ' not found in calendar ' + calendar.displayName + '.')
|
||||
}
|
||||
}
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
removeTask: function() {
|
||||
this.deleteTask({ task: this.task, dav: true })
|
||||
this.closeDetails()
|
||||
|
|
|
@ -71,6 +71,33 @@ function findVTODObyState(calendar, completed, related) {
|
|||
return calendar.dav.calendarQuery([query])
|
||||
}
|
||||
|
||||
export {
|
||||
findVTODObyState
|
||||
function findVTODObyUid(calendar, taskUid) {
|
||||
const query = {
|
||||
name: [NS.IETF_CALDAV, 'comp-filter'],
|
||||
attributes: [
|
||||
['name', 'VCALENDAR']
|
||||
],
|
||||
children: [{
|
||||
name: [NS.IETF_CALDAV, 'comp-filter'],
|
||||
attributes: [
|
||||
['name', 'VTODO']
|
||||
]
|
||||
}]
|
||||
}
|
||||
query.children[0].children = [{
|
||||
name: [NS.IETF_CALDAV, 'prop-filter'],
|
||||
attributes: [
|
||||
['name', 'uid']
|
||||
],
|
||||
children: [{
|
||||
name: [NS.IETF_CALDAV, 'text-match'],
|
||||
value: taskUid
|
||||
}]
|
||||
}]
|
||||
return calendar.dav.calendarQuery([query])
|
||||
}
|
||||
|
||||
export {
|
||||
findVTODObyState,
|
||||
findVTODObyUid
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import { isParentInList, momentToICALTime } from './storeHelper'
|
|||
import ICAL from 'ical.js'
|
||||
import TaskStatus from '../models/taskStatus'
|
||||
import router from '../components/TheRouter'
|
||||
import { findVTODObyUid } from './cdav-requests'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
|
@ -720,6 +721,88 @@ const actions = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the task with the given uri from the given calendar
|
||||
* and commits the result
|
||||
*
|
||||
* @param {Object} context The store mutations
|
||||
* @param {Object} data Destructuring object
|
||||
* @param {Calendar} data.calendar The calendar
|
||||
* @param {String} data.taskUri The uri of the requested task
|
||||
* @returns {Task}
|
||||
*/
|
||||
async getTaskByUri(context, { calendar, taskUri }) {
|
||||
const response = await calendar.dav.find(taskUri)
|
||||
if (response) {
|
||||
const task = new Task(response.data, calendar)
|
||||
Vue.set(task, 'dav', response)
|
||||
if (task.related) {
|
||||
let parent = context.getters.getTaskByUid(task.related)
|
||||
// If the parent is not found locally, we try to get it from the server.
|
||||
if (!parent) {
|
||||
parent = await context.dispatch('getTaskByUid', { calendar, taskUid: task.related })
|
||||
}
|
||||
context.commit('addTaskToParent', { task, parent })
|
||||
}
|
||||
|
||||
// In case we already have subtasks of this task in the store, add them as well.
|
||||
const subTasksInStore = context.getters.getTasksByParent(task)
|
||||
subTasksInStore.forEach(
|
||||
subTask => {
|
||||
context.commit('addTaskToParent', { task: subTask, parent: task })
|
||||
}
|
||||
)
|
||||
|
||||
context.commit('appendTasksToCalendar', { calendar, tasks: [task] })
|
||||
context.commit('appendTasks', [task])
|
||||
return task
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the task with the given uid from the given calendar
|
||||
* and commits the result
|
||||
*
|
||||
* @param {Object} context The store mutations
|
||||
* @param {Object} data Destructuring object
|
||||
* @param {Calendar} data.calendar The calendar
|
||||
* @param {String} data.taskUid The uid of the requested task
|
||||
* @returns {Task}
|
||||
*/
|
||||
async getTaskByUid(context, { calendar, taskUid }) {
|
||||
const response = await findVTODObyUid(calendar, taskUid)
|
||||
// We expect to only get zero or one task when we query by UID.
|
||||
if (response.length) {
|
||||
const task = new Task(response[0].data, calendar)
|
||||
Vue.set(task, 'dav', response[0])
|
||||
if (task.related) {
|
||||
let parent = context.getters.getTaskByUid(task.related)
|
||||
// If the parent is not found locally, we try to get it from the server.
|
||||
if (!parent) {
|
||||
parent = await context.dispatch('getTaskByUid', { calendar, taskUid: task.related })
|
||||
}
|
||||
context.commit('addTaskToParent', { task, parent })
|
||||
}
|
||||
|
||||
// In case we already have subtasks of this task in the store, add them as well.
|
||||
const subTasksInStore = context.getters.getTasksByParent(task)
|
||||
subTasksInStore.forEach(
|
||||
subTask => {
|
||||
context.commit('addTaskToParent', { task: subTask, parent: task })
|
||||
}
|
||||
)
|
||||
|
||||
context.commit('appendTasksToCalendar', { calendar, tasks: [task] })
|
||||
context.commit('appendTasks', [task])
|
||||
return task
|
||||
} else {
|
||||
console.debug('no task')
|
||||
return null
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggles the completed state of a task
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue