Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/tasks.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Service/CollectionsService.php12
-rw-r--r--lib/Service/SettingsService.php2
-rw-r--r--package-lock.json7
-rw-r--r--package.json2
-rw-r--r--src/app.vue32
-rw-r--r--src/components/Task.vue2
-rw-r--r--src/components/TheCollections/Calendar.vue8
-rw-r--r--src/components/TheCollections/General.vue22
-rw-r--r--src/components/TheDetails.vue14
-rw-r--r--src/components/TheList.vue50
-rw-r--r--src/components/TheSettings.vue17
-rw-r--r--src/models/todo.js2
-rw-r--r--src/services/cdav.js47
-rw-r--r--src/services/parseIcs.js3
-rw-r--r--src/store/calendars.js462
-rw-r--r--src/store/collections.js2
-rw-r--r--src/store/dummyCalendars.js420
-rw-r--r--src/store/storeHelper.js2
-rw-r--r--src/store/tasks.js10
19 files changed, 604 insertions, 512 deletions
diff --git a/lib/Service/CollectionsService.php b/lib/Service/CollectionsService.php
index ea22317e..6f7ffa80 100644
--- a/lib/Service/CollectionsService.php
+++ b/lib/Service/CollectionsService.php
@@ -48,32 +48,32 @@ class CollectionsService {
$collections = array(
array(
'id' => "starred",
- 'displayname' => (string)$this->l10n->t('Important'),
+ 'displayName' => (string)$this->l10n->t('Important'),
'show' => 2,
'icon' => 'icon-task-star'),
array(
'id' => "today",
- 'displayname' => (string)$this->l10n->t('Today'),
+ 'displayName' => (string)$this->l10n->t('Today'),
'show' => 2,
'icon' => 'icon-calendar'),
array(
'id' => "week",
- 'displayname' => (string)$this->l10n->t('Week'),
+ 'displayName' => (string)$this->l10n->t('Week'),
'show' => 2,
'icon' => 'icon-calendar'),
array(
'id' => "all",
- 'displayname' => (string)$this->l10n->t('All'),
+ 'displayName' => (string)$this->l10n->t('All'),
'show' => 2,
'icon' => 'icon-all'),
array(
'id' => "current",
- 'displayname' => (string)$this->l10n->t('Current'),
+ 'displayName' => (string)$this->l10n->t('Current'),
'show' => 2,
'icon' => 'icon-current'),
array(
'id' => "completed",
- 'displayname' => (string)$this->l10n->t('Completed'),
+ 'displayName' => (string)$this->l10n->t('Completed'),
'show' => 2,
'icon' => 'icon-checkmark')
);
diff --git a/lib/Service/SettingsService.php b/lib/Service/SettingsService.php
index 14686f2c..cc27ce26 100644
--- a/lib/Service/SettingsService.php
+++ b/lib/Service/SettingsService.php
@@ -43,7 +43,7 @@ class SettingsService {
*/
public function get() {
$settings = array(
- 'defaultCalendarUri' => (string)$this->settings->getUserValue($this->userId, $this->appName,'various_defaultCalendarUri'),
+ 'defaultCalendarId' => (string)$this->settings->getUserValue($this->userId, $this->appName,'various_defaultCalendarId'),
'showHidden' => (int)$this->settings->getUserValue($this->userId, $this->appName,'various_showHidden'),
'sortOrder' => (string)$this->settings->getUserValue($this->userId, $this->appName,'various_sortOrder'),
'sortDirection' => (bool)$this->settings->getUserValue($this->userId, $this->appName,'various_sortDirection'),
diff --git a/package-lock.json b/package-lock.json
index fbdb78dd..66085197 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2255,6 +2255,13 @@
"integrity": "sha512-Jt9tIBkRc9POUof7QA/VwWd+58fKkEEfI+/t1/eOlxKM7ZhrczNzMFefge7Ai+39y1pR/pP6cI19guHy3FSLmw==",
"dev": true
},
+ "cdav-library": {
+ "version": "github:nextcloud/cdav-library#46f1313d6d3843f7a55b8c065f2ff370f5357562",
+ "from": "github:nextcloud/cdav-library",
+ "requires": {
+ "@babel/polyfill": "^7.0.0"
+ }
+ },
"center-align": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
diff --git a/package.json b/package.json
index e7425934..5128d34c 100644
--- a/package.json
+++ b/package.json
@@ -27,9 +27,11 @@
"dependencies": {
"axios": "^0.18.0",
"babel-polyfill": "^6.26.0",
+ "cdav-library": "github:nextcloud/cdav-library",
"ical.js": "~1.2.2",
"jstimezonedetect": "",
"nextcloud-vue": "^0.2.0",
+ "p-limit": "^2.0.0",
"ui-select": "git+https://github.com/angular-ui/ui-select.git#v0.19.8",
"v-tooltip": "2.0.0-rc.33",
"vue": "^2.5.17",
diff --git a/src/app.vue b/src/app.vue
index 65ab4abd..1fe9eb29 100644
--- a/src/app.vue
+++ b/src/app.vue
@@ -41,12 +41,44 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
<script>
import TheList from './components/TheList'
import TheSettings from './components/TheSettings'
+import client from './services/cdav.js'
export default {
name: 'App',
components: {
'theSettings': TheSettings,
'theList': TheList
+ },
+ beforeMount() {
+ // get calendars then get todos
+ client.connect({ enableCalDAV: true }).then(() => {
+ this.$store.dispatch('getCalendars')
+ .then((calendars) => {
+ // No calendars? Create a new one!
+ if (calendars.length === 0) {
+ this.$store.dispatch('appendCalendar', { displayName: t('tasks', 'Tasks') })
+ .then(() => {
+ this.fetchTodos()
+ })
+ // else, let's get those todos!
+ } else {
+ this.fetchTodos()
+ }
+ })
+ })
+ },
+ methods: {
+ /**
+ * Fetch the todos of each calendar
+ */
+ fetchTodos() {
+ // wait for all calendars to have fetch their todos
+ // Promise.all(this.calendars.map(calendar => this.$store.dispatch('getTodosFromCalendar', { calendar })))
+ // .then(results => {
+ // this.loading = false
+ // console.log(results)
+ // })
+ }
}
}
</script>
diff --git a/src/components/Task.vue b/src/components/Task.vue
index fbe576e9..b0ae1a7f 100644
--- a/src/components/Task.vue
+++ b/src/components/Task.vue
@@ -45,7 +45,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
<a class="task-star" @click="toggleStarred(task.uri)">
<span :class="[iconStar]" class="icon icon-task-star right large reactive" />
</a>
- <a v-show="task.calendar.writable"
+ <a v-show="!task.calendar.readOnly"
class="task-addsubtask add-subtask">
<span :taskId="task.uri"
:title="subtasksCreationPlaceholder(task.summary)" class="icon icon-add right large reactive"
diff --git a/src/components/TheCollections/Calendar.vue b/src/components/TheCollections/Calendar.vue
index 9af7ac73..0e0c6496 100644
--- a/src/components/TheCollections/Calendar.vue
+++ b/src/components/TheCollections/Calendar.vue
@@ -20,8 +20,8 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
-->
<template>
- <div>
- <div v-show="calendar.writable"
+ <div v-if="calendar">
+ <div v-show="!calendar.readOnly"
id="add-task"
class="add-task">
<form name="addTaskForm" @submit="addTask">
@@ -129,7 +129,7 @@ export default {
},
inputString: function() {
- return t('tasks', 'Add a task to "{calendar}"...', { calendar: this.calendar.displayname })
+ return t('tasks', 'Add a task to "{calendar}"...', { calendar: this.calendar.displayName })
},
/**
@@ -155,7 +155,7 @@ export default {
},
addTask: function() {
- console.log('Add task with name ' + this.newTaskName + ' to calendar ' + this.calendar.displayname)
+ console.log('Add task with name ' + this.newTaskName + ' to calendar ' + this.calendar.displayName)
this.newTaskName = ''
}
}
diff --git a/src/components/TheCollections/General.vue b/src/components/TheCollections/General.vue
index 6bc20101..3ec2c9eb 100644
--- a/src/components/TheCollections/General.vue
+++ b/src/components/TheCollections/General.vue
@@ -20,8 +20,8 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
-->
<template>
- <div>
- <div v-show="collectionId !== 'completed' && calendar.writable"
+ <div v-if="calendar">
+ <div v-show="collectionId !== 'completed' && !calendar.readOnly"
id="add-task"
class="add-task">
<form name="addTaskForm" @submit="addTask">
@@ -36,17 +36,17 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
<div class="task-list">
<div v-for="calendar in filteredCalendars"
:key="calendar.id"
- :rel="calendar.uri"
+ :rel="calendar.id"
class="grouped-tasks ui-droppable">
- <h2 class="heading">{{ calendar.displayname }}</h2>
- <ol :calendarID="calendar.uri"
+ <h2 class="heading">{{ calendar.displayName }}</h2>
+ <ol :calendarID="calendar.id"
:collectionID="collectionId"
class="tasks"
type="list"
dnd-list="draggedTasks"
dnd-drop="dropAsRootTask(event, item, index)"
dnd-dragover="dragover(event, index)">
- <router-link v-for="task in filteredTasks = tasks(calendar.uri)"
+ <router-link v-for="task in filteredTasks = tasks(calendar.id)"
:task-id="task.uri"
:key="task.uid"
:to="'/collections/' + collectionId + '/tasks/' + task.uri"
@@ -109,20 +109,20 @@ export default {
*/
filteredCalendars: function() {
return this.calendars.filter(calendar => {
- return this.calendarCount(calendar.uri, this.$route.params.collectionId)
+ return this.calendarCount(calendar.id, this.$route.params.collectionId)
})
},
inputString: function() {
switch (this.collectionId) {
case 'starred':
- return t('tasks', 'Add an important task to "{calendar}"...', { calendar: this.calendar.displayname })
+ return t('tasks', 'Add an important task to "{calendar}"...', { calendar: this.calendar.displayName })
case 'today':
- return t('tasks', 'Add a task due today to "{calendar}"...', { calendar: this.calendar.displayname })
+ return t('tasks', 'Add a task due today to "{calendar}"...', { calendar: this.calendar.displayName })
case 'all':
- return t('tasks', 'Add a task to "{calendar}"...', { calendar: this.calendar.displayname })
+ return t('tasks', 'Add a task to "{calendar}"...', { calendar: this.calendar.displayName })
case 'current':
- return t('tasks', 'Add a current task to "{calendar}"...', { calendar: this.calendar.displayname })
+ return t('tasks', 'Add a current task to "{calendar}"...', { calendar: this.calendar.displayName })
}
}
},
diff --git a/src/components/TheDetails.vue b/src/components/TheDetails.vue
index 007f7523..b172dbad 100644
--- a/src/components/TheDetails.vue
+++ b/src/components/TheDetails.vue
@@ -22,7 +22,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
<template>
<div class="content-wrapper">
<div v-if="task!=undefined"
- :class="{'disabled': !task.calendar.writable}"
+ :class="{'disabled': task.calendar.readOnly}"
class="flex-container">
<div :class="{'editing': edit=='summary'}" class="title">
<a :aria-checked="task.completed"
@@ -30,10 +30,10 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
class="checkbox reactive"
role="checkbox"
@click="toggleCompleted(task.uri)">
- <span :class="{'icon-checkmark': task.completed, 'disabled': !task.calendar.writable}" class="icon detail-checkbox" />
+ <span :class="{'icon-checkmark': task.completed, 'disabled': task.calendar.readOnly}" class="icon detail-checkbox" />
</a>
<a class="star reactive" @click="toggleStarred(task.uri)">
- <span :class="[{'disabled': !task.calendar.writable}, iconStar]"
+ <span :class="[{'disabled': task.calendar.readOnly}, iconStar]"
class="icon icon-task-star" />
</a>
<div v-click-outside="() => finishEditing('summary')">
@@ -117,7 +117,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
role="checkbox"
@click="toggleAllDay(task.uri)">
<div>
- <span :class="{'icon-checkmark': task.allDay, 'disabled': !task.calendar.writable}" class="icon detail-checkbox" />
+ <span :class="{'icon-checkmark': task.allDay, 'disabled': task.calendar.readOnly}" class="icon detail-checkbox" />
<span class="section-title">{{ t('tasks', 'All day') }}</span>
</div>
</li>
@@ -227,7 +227,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
</ul>
</div>
<div class="footer">
- <a v-show="task.calendar.writable"
+ <a v-show="!task.calendar.readOnly"
class="left close-all reactive"
@click="deleteTask(task.uri)">
<span class="icon icon-trash" />
@@ -389,7 +389,7 @@ export default {
},
computed: Object.assign({
isAllDayPossible: function() {
- return this.task.calendar.writable && (this.task.due || this.task.start)
+ return !this.task.calendar.readOnly && (this.task.due || this.task.start)
},
priorityString: function() {
if (this.task.priority > 5) {
@@ -452,7 +452,7 @@ export default {
if (event && event.target.classList.contains('mx-datepicker-btn-confirm')) {
return
}
- if (this.task.calendar.writable && this.edit !== type) {
+ if (!this.task.calendar.readOnly && this.edit !== type) {
this.edit = type
this.tmpTask[type] = this.task[type]
}
diff --git a/src/components/TheList.vue b/src/components/TheList.vue
index 0dab655f..877bdfe3 100644
--- a/src/components/TheList.vue
+++ b/src/components/TheList.vue
@@ -35,7 +35,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
dnd-dragover="dragoverCollection(event, index)">
<a class="sprite">
<span v-if="collection.id=='today'" class="date">{{ dayOfMonth }}</span>
- <span class="title">{{ collection.displayname }}</span>
+ <span class="title">{{ collection.displayName }}</span>
</a>
<div v-if="collection.id!='completed'" class="app-navigation-entry-utils">
<ul>
@@ -46,11 +46,11 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
<router-link
v-click-outside="() => resetView(calendar)"
v-for="calendar in calendars"
- :id="'list_' + calendar.uri"
- :calendar-id="calendar.uri"
- :to="'/calendars/' + calendar.uri"
- :key="calendar.uri"
- :class="{edit: editing == calendar.uri, caldav: caldav == calendar.uri}"
+ :id="'list_' + calendar.id"
+ :calendar-id="calendar.id"
+ :to="'/calendars/' + calendar.id"
+ :key="calendar.id"
+ :class="{edit: editing == calendar.id, caldav: caldav == calendar.id}"
tag="li"
class="list with-menu editing"
active-class="active"
@@ -59,12 +59,12 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
dnd-dragover="dragoverList(event, index)">
<div :style="{'background-color': calendar.color}" class="app-navigation-entry-bullet" />
<a>
- <span class="title">{{ calendar.displayname }}</span>
+ <span class="title">{{ calendar.displayName }}</span>
</a>
<div class="app-navigation-entry-utils">
<ul>
- <li class="app-navigation-entry-utils-counter">{{ calendarCount(calendar.uri) | counterFormatter }}</li>
- <popover v-show="calendar.writable" tag="li" class="app-navigation-entry-utils-menu-button">
+ <li class="app-navigation-entry-utils-counter">{{ calendarCount(calendar.id) | counterFormatter }}</li>
+ <popover v-show="!calendar.readOnly" tag="li" class="app-navigation-entry-utils-menu-button">
<ul>
<li>
<a @click="edit(calendar)">
@@ -79,12 +79,12 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
</a>
</li>
<li>
- <a :href="exportUrl(calendar)" :download="calendar.uri + '.ics'">
+ <a :href="exportUrl(calendar)" :download="calendar.id + '.ics'">
<span class="icon-download" />
<span>{{ t('tasks', 'Download') }}</span>
</a>
</li>
- <confirmation :message="deleteMessage(calendar.displayname)" @delete-calendar="deleteCalendar(calendar, ...arguments)" />
+ <confirmation :message="deleteMessage(calendar.displayName)" @delete-calendar="deleteCalendar(calendar, ...arguments)" />
</ul>
</popover>
</ul>
@@ -93,14 +93,14 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
<form>
<input v-tooltip="{
content: tooltipMessage,
- show: showTooltip(calendar.uri),
+ show: showTooltip(calendar.id),
trigger: 'manual'
}"
v-model="newCalendarName"
class="edit"
type="text"
autofocus-on-insert
- @keyup="checkName($event, calendar.uri)">
+ @keyup="checkName($event, calendar.id)">
<input :title="t('tasks', 'Cancel')"
type="cancel"
value=""
@@ -234,23 +234,23 @@ export default {
return this.tooltipTarget === target
},
edit: function(calendar) {
- this.editing = calendar.uri
- this.newCalendarName = calendar.displayname
+ this.editing = calendar.id
+ this.newCalendarName = calendar.displayName
this.selectedColor = calendar.color
this.nameError = false
this.tooltipTarget = ''
},
resetView: function(calendar) {
- if (this.editing === calendar.uri) {
+ if (this.editing === calendar.id) {
this.editing = ''
}
- if (this.caldav === calendar.uri) {
+ if (this.caldav === calendar.id) {
this.caldav = ''
}
this.tooltipTarget = ''
},
showCalDAVUrl: function(calendar) {
- this.caldav = calendar.uri
+ this.caldav = calendar.id
},
exportUrl(calendar) {
var url = calendar.url
@@ -284,14 +284,14 @@ export default {
},
save: function(calendar) {
// TODO: Call correct methods of store
- console.log('Change name and color of calendar ' + calendar.uri + ' to ' + this.newCalendarName + ' and ' + this.selectedColor)
+ console.log('Change name and color of calendar ' + calendar.id + ' to ' + this.newCalendarName + ' and ' + this.selectedColor)
this.editing = false
},
- checkName: function(event, uri) {
- var check = this.isNameAllowed(this.newCalendarName, uri)
+ checkName: function(event, id) {
+ var check = this.isNameAllowed(this.newCalendarName, id)
this.tooltipMessage = check.msg
if (!check.allowed) {
- this.tooltipTarget = uri
+ this.tooltipTarget = id
this.nameError = true
} else {
this.tooltipTarget = ''
@@ -305,12 +305,12 @@ export default {
this.nameError = false
}
},
- isNameAllowed: function(name, uri) {
+ isNameAllowed: function(name, id) {
var check = {
allowed: false,
msg: ''
}
- if (this.isCalendarNameUsed(name, uri)) {
+ if (this.isCalendarNameUsed(name, id)) {
check.msg = t('tasks', 'The name "%s" is already used.').replace('%s', name)
} else if (!name) {
check.msg = t('tasks', 'An empty name is not allowed.')
@@ -323,7 +323,7 @@ export default {
return t('tasks', 'This will delete the calendar "%s" and all corresponding events and tasks.').replace('%s', name)
},
deleteCalendar: function(calendar) {
- console.log('Delete calendar ' + calendar.uri)
+ console.log('Delete calendar ' + calendar.id)
}
}
}
diff --git a/src/components/TheSettings.vue b/src/components/TheSettings.vue
index 2851defc..7d8cb574 100644
--- a/src/components/TheSettings.vue
+++ b/src/components/TheSettings.vue
@@ -30,11 +30,11 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
<ul>
<li>
<label for="defaultCalendar">{{ t('tasks', 'Default list') }}</label>
- <select id="defaultCalendar" v-model="defaultCalendarUri">
+ <select id="defaultCalendar" v-model="defaultCalendarId">
<option v-for="calendar in calendars"
- :value="calendar.uri"
- :key="calendar.uri">
- {{ calendar.displayname }}
+ :value="calendar.id"
+ :key="calendar.id">
+ {{ calendar.displayName }}
</option>
</select>
</li>
@@ -47,7 +47,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
<span :class="collection.icon" class="icon">
<span v-if="collection.id=='today'">{{ dayOfMonth }}</span>
</span>
- <label :for="'visibilityCollection-' + collection.id" class="title">{{ collection.displayname }}</label>
+ <label :for="'visibilityCollection-' + collection.id" class="title">{{ collection.displayName }}</label>
</div>
<select :id="'visibilityCollection-' + collection.id"
:value="collection.show"
@@ -90,12 +90,13 @@ export default {
}
},
computed: Object.assign({
- defaultCalendarUri: {
+ defaultCalendarId: {
get() {
- return this.$store.getters.getDefaultCalendar.uri
+ var cal = this.$store.getters.getDefaultCalendar
+ return cal ? cal.id : ''
},
set(value) {
- this.$store.dispatch('setSetting', { type: 'defaultCalendarUri', value: value })
+ this.$store.dispatch('setSetting', { type: 'defaultCalendarId', value: value })
}
}
},
diff --git a/src/models/todo.js b/src/models/todo.js
new file mode 100644
index 00000000..81484fa7
--- /dev/null
+++ b/src/models/todo.js
@@ -0,0 +1,2 @@
+export default class {
+}
diff --git a/src/services/cdav.js b/src/services/cdav.js
new file mode 100644
index 00000000..a913404b
--- /dev/null
+++ b/src/services/cdav.js
@@ -0,0 +1,47 @@
+/**
+ * @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @author John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+import DavClient from 'cdav-library'
+
+function xhrProvider() {
+ var headers = {
+ 'X-Requested-With': 'XMLHttpRequest',
+ 'requesttoken': OC.requestToken
+ }
+ var xhr = new XMLHttpRequest()
+ var oldOpen = xhr.open
+
+ // override open() method to add headers
+ xhr.open = function() {
+ var result = oldOpen.apply(this, arguments)
+ for (let name in headers) {
+ xhr.setRequestHeader(name, headers[name])
+ }
+ return result
+ }
+ OC.registerXHRForErrorProcessing(xhr)
+ return xhr
+}
+
+export default new DavClient({
+ rootUrl: OC.linkToRemote('dav')
+}, xhrProvider)
diff --git a/src/services/parseIcs.js b/src/services/parseIcs.js
new file mode 100644
index 00000000..be5499a2
--- /dev/null
+++ b/src/services/parseIcs.js
@@ -0,0 +1,3 @@
+export default function(ics, calendar) {
+
+}
diff --git a/src/store/calendars.js b/src/store/calendars.js
index ad778e1d..2d745a11 100644
--- a/src/store/calendars.js
+++ b/src/store/calendars.js
@@ -4,6 +4,15 @@
* @author Raimund Schlüßler
* @copyright 2018 Raimund Schlüßler <raimund.schluessler@mailbox.org>
*
+ * @author John Molakvoæ
+ * @copyright 2018 John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @author Georg Ehrke
+ * @copyright 2018 Georg Ehrke <oc.list@georgehrke.com>
+ *
+ * @author Thomas Citharel <tcit@tcit.fr>
+ * @copyright 2018 Thomas Citharel <tcit@tcit.fr>
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
@@ -21,15 +30,49 @@
'use strict'
import Vue from 'vue'
-import Vuex from 'vuex'
-import DummyCalendars from './dummyCalendars'
-
+import ICAL from 'ical.js'
+import parseIcs from '../services/parseIcs'
+import client from '../services/cdav'
+import Event from '../models/todo'
+import pLimit from 'p-limit'
import { isTaskInList } from './storeHelper'
-Vue.use(Vuex)
+const calendarModel = {
+ id: '',
+ color: '',
+ displayName: '',
+ enabled: true,
+ owner: '',
+ shares: [],
+ tasks: [],
+ url: '',
+ readOnly: false,
+ dav: false
+}
const state = {
- calendars: DummyCalendars.calendars
+ calendars: []
+}
+
+/**
+ * map a dav collection to our calendar object model
+ *
+ * @param {Object} calendar the calendar object from the cdav library
+ * @returns {Object}
+ */
+export function mapDavCollectionToCalendar(calendar) {
+ return {
+ // get last part of url
+ id: calendar.url.split('/').slice(-2, -1)[0],
+ displayName: calendar.displayname,
+ color: calendar.color,
+ enabled: calendar.enabled !== false,
+ owner: calendar.owner,
+ readOnly: false, // this currently does not work correctly. Need to get the state from the actual calendar!
+ tasks: [],
+ url: calendar.url,
+ dav: calendar
+ }
}
const getters = {
@@ -38,13 +81,18 @@ const getters = {
* Returns the calendars sorted alphabetically
*/
getSortedCalendars: state => {
- return Object.values(state.calendars).sort(function(cal1, cal2) {
- var n1 = cal1.displayname.toUpperCase()
- var n2 = cal2.displayname.toUpperCase()
+ return state.calendars.sort(function(cal1, cal2) {
+ var n1 = cal1.displayName.toUpperCase()
+ var n2 = cal2.displayName.toUpperCase()
return (n1 < n2) ? -1 : (n1 > n2) ? 1 : 0
})
},
+ getCalendarById: state => (calendarId) => {
+ var calendar = state.calendars.find(search => search.id === calendarId)
+ return calendar
+ },
+
/**
* Returns the count of tasks in a calendar
*
@@ -54,8 +102,9 @@ const getters = {
*
* @param {String} calendarId the Id of the calendar in question
*/
- getCalendarCount: state => (calendarId) => {
- return Object.values(state.calendars[calendarId].tasks)
+ getCalendarCount: (state, getters) => (calendarId) => {
+ var calendar = getters.getCalendarById(calendarId)
+ return Object.values(calendar.tasks)
.filter(task => {
return task.completed === false && !task.related
}).length
@@ -72,8 +121,8 @@ const getters = {
* @param {String} calendarId the Id of the calendar in question
* @param {String} collectionId the Id of the collection in question
*/
- getCalendarCountByCollectionId: state => (calendarId, collectionId) => {
- var calendar = state.calendars[calendarId]
+ getCalendarCountByCollectionId: (state, getters) => (calendarId, collectionId) => {
+ var calendar = getters.getCalendarById(calendarId)
var count = calendar.tasks.filter(task => {
return isTaskInList(task, collectionId) && !task.related
}).length
@@ -89,8 +138,9 @@ const getters = {
*
* @param {String} calendarId the Id of the calendar in question
*/
- getCalendarCountCompleted: state => (calendarId) => {
- return Object.values(state.calendars[calendarId].tasks)
+ getCalendarCountCompleted: (state, getters) => (calendarId) => {
+ var calendar = getters.getCalendarById(calendarId)
+ return Object.values(calendar.tasks)
.filter(task => {
return task.completed === true && !task.related
}).length
@@ -100,12 +150,11 @@ const getters = {
* Returns if a calendar name is already used by an other calendar
*
* @param {String} name the name to check
- * @param {String} uri the uri of the calendar to exclude
+ * @param {String} id the Id of the calendar to exclude
*/
- isCalendarNameUsed: state => (name, uri) => {
- var calendars = Object.values(state.calendars)
- return calendars.some(calendar => {
- return (calendar.displayname === name && calendar.uri !== uri)
+ isCalendarNameUsed: state => (name, id) => {
+ return state.calendars.some(calendar => {
+ return (calendar.displayname === name && calendar.id !== id)
})
},
@@ -113,7 +162,7 @@ const getters = {
* Returns the current calendar
*/
getCalendarByRoute: (state, getters, rootState) => {
- return state.calendars[rootState.route.params.calendarId]
+ return getters.getCalendarById(rootState.route.params.calendarId)
},
/**
@@ -123,12 +172,379 @@ const getters = {
* Calendar order might change randomly.
*/
getDefaultCalendar: (state, getters, rootState) => {
- return state.calendars[rootState.settings.settings.defaultCalendarUri] || getters.getSortedCalendars[0]
+ return getters.getCalendarById(rootState.settings.settings.defaultCalendarId) || getters.getSortedCalendars[0]
}
}
-const mutations = {}
+const mutations = {
+
+ /**
+ * Add calendar into state
+ *
+ * @param {Object} state the store data
+ * @param {Object} calendar the calendar to add
+ */
+ addCalendar(state, calendar) {
+ // extend the calendar to the default model
+ state.calendars.push(Object.assign({}, calendarModel, calendar))
+ },
+
+ /**
+ * Delete calendar
+ *
+ * @param {Object} state the store data
+ * @param {Object} calendar the calendar to delete
+ */
+ deleteCalendar(state, calendar) {
+ state.calendars.splice(state.calendars.indexOf(calendar), 1)
+ },
+
+ /**
+ * Toggle whether a calendar is Enabled
+ * @param {Object} context the store mutations
+ * @param {Object} calendar the calendar to toggle
+ */
+ toggleCalendarEnabled(context, calendar) {
+ calendar = state.calendars.find(search => search.id === calendar.id)
+ calendar.enabled = !calendar.enabled
+ },
+
+ /**
+ * Rename a calendar
+ * @param {Object} context the store mutations
+ * @param {Object} data destructuring object
+ * @param {Object} data.calendar the calendar to rename
+ * @param {String} data.newName the new name of the calendar
+ */
+ renameCalendar(context, { calendar, newName }) {
+ calendar = state.calendars.find(search => search.id === calendar.id)
+ calendar.displayName = newName
+ },
+
+ /**
+ * Append a list of events to an calendar
+ * and remove duplicates
+ *
+ * @param {Object} state the store data
+ * @param {Object} data destructuring object
+ * @param {Object} data.calendar the calendar to add the event to
+ * @param {Event[]} data.events array of events to append
+ */
+ appendEventsToCalendar(state, { calendar, events }) {
+ calendar = state.calendars.find(search => search === calendar)
+
+ // convert list into an array and remove duplicate
+ calendar.events = events.reduce((list, event) => {
+ if (list[event.uid]) {
+ console.debug('Duplicate event overrided', list[event.uid], event)
+ }
+ Vue.set(list, event.uid, event)
+ return list
+ }, calendar.events)
+ },
+
+ /**
+ * Add an event to an calendar and overwrite if duplicate uid
+ *
+ * @param {Object} state the store data
+ * @param {Event} event the event to add
+ */
+ addEventToCalendar(state, event) {
+ let calendar = state.calendars.find(search => search.id === event.calendar.id)
+ Vue.set(calendar.events, event.uid, event)
+ },
+
+ /**
+ * Delete an event in a specified calendar
+ *
+ * @param {Object} state the store data
+ * @param {Event} event the event to delete
+ */
+ deleteEventFromCalendar(state, event) {
+ let calendar = state.calendars.find(search => search.id === event.calendar.id)
+ Vue.delete(calendar, event.uid)
+ },
-const actions = {}
+ /**
+ * Share calendar with a user or group
+ *
+ * @param {Object} state the store data
+ * @param {Object} data destructuring object
+ * @param {Object} data.calendar the calendar
+ * @param {string} data.sharee the sharee
+ * @param {string} data.id id
+ * @param {Boolean} data.group group
+ */
+ shareCalendar(state, { calendar, sharee, id, group }) {
+ calendar = state.calendars.find(search => search.id === calendar.id)
+ let newSharee = {
+ displayname: sharee,
+ id,
+ writeable: false,
+ group
+ }
+ calendar.shares.push(newSharee)
+ },
+
+ /**
+ * Remove Sharee from calendar shares list
+ *
+ * @param {Object} state the store data
+ * @param {Object} sharee the sharee
+ */
+ removeSharee(state, sharee) {
+ let calendar = state.calendars.find(search => {
+ for (let i in search.shares) {
+ if (search.shares[i] === sharee) {
+ return true
+ }
+ }
+ })
+ calendar.shares.splice(calendar.shares.indexOf(sharee), 1)
+ },
+
+ /**
+ * Toggle sharee's writable permission
+ *
+ * @param {Object} state the store data
+ * @param {Object} sharee the sharee
+ */
+ updateShareeWritable(state, sharee) {
+ let calendar = state.calendars.find(search => {
+ for (let i in search.shares) {
+ if (search.shares[i] === sharee) {
+ return true
+ }
+ }
+ })
+ sharee = calendar.shares.find(search => search === sharee)
+ sharee.writeable = !sharee.writeable
+ }
+}
+
+const actions = {
+ /**
+ * Retrieve and commit calendars
+ *
+ * @param {Object} context the store mutations
+ * @returns {Promise<Array>} the calendars
+ */
+ async getCalendars(context) {
+ let calendars = await client.calendarHomes[0].findAllCalendars()
+ .then(calendars => {
+ return calendars.map(calendar => {
+ return mapDavCollectionToCalendar(calendar)
+ })
+ })
+
+ calendars.forEach(calendar => {
+ context.commit('addCalendar', calendar)
+ })
+
+ return calendars
+ },
+
+ /**
+ * Append a new calendar to array of existing calendars
+ *
+ * @param {Object} context the store mutations
+ * @param {Object} calendar The calendar to append
+ * @returns {Promise}
+ */
+ async appendCalendar(context, calendar) {
+ return client.calendarHomes[0].createCalendarCollection(calendar.displayName)
+ .then((response) => {
+ calendar = mapDavCollectionToCalendar(response)
+ context.commit('addCalendar', calendar)
+ })
+ .catch((error) => { throw error })
+ },
+
+ /**
+ * Delete calendar
+ * @param {Object} context the store mutations Current context
+ * @param {Object} calendar the calendar to delete
+ * @returns {Promise}
+ */
+ async deleteCalendar(context, calendar) {
+ return calendar.dav.delete()
+ .then((response) => {
+ // delete all the events from the store that belong to this calendar
+ Object.values(calendar.events)
+ .forEach(event => context.commit('deleteEvent', event))
+ // then delete the calendar
+ context.commit('deleteCalendar', calendar)
+ })
+ .catch((error) => { throw error })
+ },
+
+ /**
+ * Toggle whether a calendar is Enabled
+ * @param {Object} context the store mutations Current context
+ * @param {Object} calendar the calendar to toggle
+ * @returns {Promise}
+ */
+ async toggleCalendarEnabled(context, calendar) {
+ calendar.dav.enabled = !calendar.dav.enabled
+ return calendar.dav.update()
+ .then((response) => context.commit('toggleCalendarEnabled', calendar))
+ .catch((error) => { throw error })
+ },
+
+ /**
+ * Rename a calendar
+ * @param {Object} context the store mutations Current context
+ * @param {Object} data.calendar the calendar to rename
+ * @param {String} data.newName the new name of the calendar
+ * @returns {Promise}
+ */
+ async renameCalendar(context, { calendar, newName }) {
+ calendar.dav.displayname = newName
+ return calendar.dav.update()
+ .then((response) => context.commit('renameCalendar', { calendar, newName }))
+ .catch((error) => { throw error })
+ },
+
+ /**
+ * Retrieve the events of the specified calendar
+ * and commit the results
+ *
+ * @param {Object} context the store mutations
+ * @param {Object} importDetails = { ics, calendar }
+ * @returns {Promise}
+ */
+ async getTodosFromCalendar(context, { calendar }) {
+ return calendar.dav.findByType('VTODO')
+ .then((response) => {
+ // We don't want to lose the url information
+ // so we need to parse one by one
+ const events = response.map(item => {
+ let event = new Event(item.data, calendar)
+ Vue.set(event, 'dav', item)
+ return event
+ })
+ context.commit('appendTodosToCalendar', { calendar, events })
+ context.commit('appendTodos', events)
+ return events
+ })
+ .catch((error) => {
+ // unrecoverable error, if no events were loaded,
+ // remove the calendar
+ // TODO: create a failed calendar state and show that there was an issue?
+ context.commit('deleteCalendar', calendar)
+ console.error(error)
+ })
+ },
+
+ /**
+ *
+ * @param {Object} context the store mutations
+ * @param {Object} importDetails = { ics, calendar }
+ */
+ async importEventsIntoCalendar(context, { ics, calendar }) {
+ const events = parseIcs(ics, calendar)
+ context.commit('changeStage', 'importing')
+
+ // max simultaneous requests
+ const limit = pLimit(3)
+ const requests = []
+
+ // create the array of requests to send
+ events.map(async event => {
+ // Get vcard string
+ try {
+ let vData = ICAL.stringify(event.vCard.jCal)
+ // push event to server and use limit
+ requests.push(limit(() => event.calendar.dav.createVCard(vData)
+ .then((response) => {
+ // setting the event dav property
+ Vue.set(event, 'dav', response)
+
+ // success, update store
+ context.commit('addEvent', event)
+ context.commit('addEventToCalendar', event)
+ context.commit('incrementAccepted')
+ })
+ .catch((error) => {
+ // error
+ context.commit('incrementDenied')
+ console.error(error)
+ })
+ ))
+ } catch (e) {
+ context.commit('incrementDenied')
+ }
+ })
+
+ Promise.all(requests).then(() => {
+ context.commit('changeStage', 'default')
+ })
+ },
+
+ /**
+ * Remove sharee from calendar
+ * @param {Object} context the store mutations Current context
+ * @param {Object} sharee calendar sharee object
+ */
+ removeSharee(context, sharee) {
+ context.commit('removeSharee', sharee)
+ },
+
+ /**
+ * Toggle permissions of calendar Sharees writeable rights
+ * @param {Object} context the store mutations Current context
+ * @param {Object} sharee calendar sharee object
+ */
+ toggleShareeWritable(context, sharee) {
+ context.commit('updateShareeWritable', sharee)
+ },
+
+ /**
+ * Share calendar with User or Group
+ * @param {Object} context the store mutations Current context
+ * @param {Object} data.calendar the calendar
+ * @param {String} data.sharee the sharee
+ * @param {Boolean} data.id id
+ * @param {Boolean} data.group group
+ */
+ shareCalendar(context, { calendar, sharee, id, group }) {
+ // Share calendar with entered group or user
+ context.commit('shareCalendar', { calendar, sharee, id, group })
+ },
+
+ /**
+ * Move an event to the provided calendar
+ *
+ * @param {Object} context the store mutations
+ * @param {Object} data destructuring object
+ * @param {Event} data.event the event to move
+ * @param {Object} data.calendar the calendar to move the event to
+ */
+ async moveEventToCalendar(context, { event, calendar }) {
+ // only local move if the event doesn't exists on the server
+ if (event.dav) {
+ // TODO: implement proper move
+ // await events.dav.move(calendar.dav)
+ // .catch((error) => {
+ // console.error(error)
+ // OC.Notification.showTemporary(t('calendars', 'An error occurred'))
+ // })
+ let vData = ICAL.stringify(event.vCard.jCal)
+ let newDav
+ await calendar.dav.createVCard(vData)
+ .then((response) => { newDav = response })
+ .catch((error) => { throw error })
+ await event.dav.delete()
+ .catch((error) => {
+ console.error(error)
+ OC.Notification.showTemporary(t('calendars', 'An error occurred'))
+ })
+ await Vue.set(event, 'dav', newDav)
+ }
+ await context.commit('deleteEventFromCalendar', event)
+ await context.commit('updateEventCalendar', { event, calendar })
+ await context.commit('addEventToCalendar', event)
+ }
+}
export default { state, getters, mutations, actions }
diff --git a/src/store/collections.js b/src/store/collections.js
index 55515864..d62d7a64 100644
--- a/src/store/collections.js
+++ b/src/store/collections.js
@@ -46,7 +46,7 @@ const getters = {
*/
getCollectionCount: (state, getters, rootState) => (collectionId) => {
var count = 0
- Object.values(rootState.calendars.calendars).forEach(calendar => {
+ rootState.calendars.calendars.forEach(calendar => {
count += calendar.tasks.filter(task => {
return isTaskInList(task, collectionId) && !task.related
}).length
diff --git a/src/store/dummyCalendars.js b/src/store/dummyCalendars.js
deleted file mode 100644
index 62964c23..00000000
--- a/src/store/dummyCalendars.js
+++ /dev/null
@@ -1,420 +0,0 @@
-/**
- * Nextcloud - Tasks
- *
- * @author Raimund Schlüßler
- * @copyright 2018 Raimund Schlüßler <raimund.schluessler@mailbox.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-'use strict'
-
-export default ({
- calendars: {
- 'test-1': {
- uri: 'test-1',
- displayname: 'Test 1',
- color: '#ff0000',
- writable: true,
- url: '/nextcloud/remote.php/dav/calendars/raimund.schluessler/test-1',
- caldav: 'caldav-url',
- tasks: [
- {
- calendar: {
- writable: true,
- color: '#ff0000'
- },
- uid: 'ydf95848mn',
- uri: 'ydf95848mn.ics',
- // construct dates for tomorrow
- due: moment().add(1, 'days').format('YYYYMMDDTHHmmss'),
- start: moment().add(1, 'days').format('YYYYMMDDTHHmmss'),
- summary: 'Test 1 - Task 1',
- complete: 0,
- completed: true,
- priority: 1,
- categories: [
- {
- id: 1,
- name: 'Test 1 Category 1'
- },
- {
- id: 2,
- name: 'Test 1 Category 2'
- },
- {
- id: 3,
- name: 'Test 1 Category 3'
- },
- {
- id: 4,
- name: 'Test 1 Category 4'
- },
- {
- id: 5,
- name: 'Test 1 Category 5'
- },
- {
- id: 6,
- name: 'Test 1 Category 6'
- }
- ],
- note: 'Migrate this app to vue.',
- hideSubtasks: false,
- allDay: false
- },
- {
- calendar: {
- writable: true,
- color: '#ff0000'
- },
- uid: 'ydf95748mn',
- uri: 'ydf95748mn.ics',
- // construct dates for yesterday
- due: moment().subtract(1, 'days').format('YYYYMMDDTHHmmss'),
- start: moment().subtract(1, 'days').format('YYYYMMDDTHHmmss'),
- summary: 'Test 1 - Task 2',
- complete: 20,
- completed: false,
- priority: 5,
- categories: [],
- note: 'Migrate this app to vue.',
- hideSubtasks: false,
- allDay: false
- },
- {
- calendar: {
- writable: true,
- color: '#ff0000'
- },
- uid: 'ydf95849mn',
- uri: 'ydf95849mn.ics',
- // construct dates for last week
- due: moment().subtract(5, 'days').format('YYYYMMDDTHHmmss'),
- start: moment().subtract(5, 'days').format('YYYYMMDDTHHmmss'),
- summary: 'Test 1 - Task 3',
- complete: 60,
- completed: false,
- priority: 7,
- categories: [],
- note: 'Migrate this app to vue.',
- related: 'ydf95748mn',
- hideSubtasks: false,
- allDay: false
- },
- {
- calendar: {
- writable: true,
- color: '#ff0000'
- },
- uid: 'rtf95849mn',
- uri: 'rtf95849mn.ics',
- // construct dates for next week
- due: moment().add(5, 'days').format('YYYYMMDDTHHmmss'),
- start: moment().add(5, 'days').format('YYYYMMDDTHHmmss'),
- summary: 'Test 1 - Task 4',
- complete: 0,
- completed: false,
- priority: 7,
- categories: [],
- note: 'Migrate this app to vue.',
- related: 'ydf95748mn',
- hideSubtasks: false,
- allDay: false
- },
- {
- calendar: {
- writable: true,
- color: '#ff0000'
- },
- uid: 'yaf92889mn',
- uri: 'yaf92889mn.ics',
- // construct dates for today future
- due: moment().add(1, 'hours').format('YYYYMMDDTHHmmss'),
- start: moment().add(1, 'hours').format('YYYYMMDDTHHmmss'),
- summary: 'Test 1 - Task 5',
- complete: 80,
- completed: false,
- priority: 7,
- categories: [],
- note: 'Migrate this app to vue.',
- related: 'ydf95849mn',
- hideSubtasks: false,
- allDay: false
- }
- ]
- },
- 'test-2': {
- uri: 'test-2',
- displayname: 'Test 2',
- color: '#eef',
- writable: false,
- url: '/nextcloud/remote.php/dav/calendars/raimund.schluessler/test-2',
- tasks: [
- {
- calendar: {
- writable: false,
- color: '#eef'
- },
- uid: 'ydf91848mn',
- uri: 'ydf91848mn.ics',
- // construct dates for today past
- due: moment().subtract(1, 'hours').format('YYYYMMDDTHHmmss'),
- start: moment().subtract(1, 'hours').format('YYYYMMDDTHHmmss'),
- summary: 'Test 2 - Task 1',
- complete: 90,
- completed: true,
- priority: 1,
- categories: [],
- note: 'Migrate this app to vue.',
- hideSubtasks: false,
- allDay: false
- },
- {
- calendar: {
- writable: false,
- color: '#eef'
- },
- uid: 'yef91848mn',
- uri: 'yef91848mn.ics',
- // construct dates for far future
- due: moment().add(5, 'years').format('YYYYMMDDTHHmmss'),
- start: moment().add(5, 'years').format('YYYYMMDDTHHmmss'),
- summary: 'Test 2 - Task 2',
- complete: 0,
- completed: false,
- priority: 5,
- categories: [],
- note: 'Migrate this app to vue.',
- hideSubtasks: false,
- allDay: false
- },
- {
- calendar: {
- writable: false,
- color: '#eef'
- },
- uid: 'yff91848mn',
- uri: 'yff91848mn.ics',
- // construct dates for far past
- due: moment().subtract(5, 'years').format('YYYYMMDDTHHmmss'),
- start: moment().subtract(5, 'years').format('YYYYMMDDTHHmmss'),
- summary: 'Test 2 - Task 3',
- complete: 6,
- completed: true,
- priority: 7,
- categories: [],
- note: 'Migrate this app to vue.',
- hideSubtasks: false,
- allDay: false
- },
- {
- calendar: {
- writable: false,
- color: '#eef'
- },
- uid: 'ydg91848mn',
- uri: 'ydg91848mn.ics',
- // construct dates for tomorrow, date only
- due: moment().add(1, 'days').format('YYYYMMDD'),
- start: moment().add(1, 'days').format('YYYYMMDD'),
- summary: 'Test 2 - Task 4',
- complete: 6,
- completed: false,
- priority: 7,
- categories: [],
- note: 'Migrate this app to vue.',
- hideSubtasks: false,
- allDay: true
- },
- {
- calendar: {
- writable: false,
- color: '#eef'
- },
- uid: 'ydh91848mn',
- uri: 'ydh91848mn.ics',
- // construct dates for yesterday, date only
- due: moment().subtract(1, 'days').format('YYYYMMDD'),
- start: moment().subtract(1, 'days').format('YYYYMMDD'),
- summary: 'Test 2 - Task 5',
- complete: 6,
- completed: false,
- priority: 7,
- categories: [],
- note: 'Migrate this app to vue.',
- hideSubtasks: false,
- allDay: true
- }
- ]
- },
- 'test-3': {
- uri: 'test-3',
- displayname: 'Test 3',
- color: '#112233',
- writable: true,
- url: '/nextcloud/remote.php/dav/calendars/raimund.schluessler/test-3',
- tasks: [
-
- {
- calendar: {
- writable: true,
- color: '#112233'
- },
- uid: 'ydi92848mn',
- uri: 'ydi92848mn.ics',
- // construct dates for last week, date only
- due: moment().subtract(5, 'days').format('YYYYMMDD'),
- start: moment().subtract(5, 'days').format('YYYYMMDD'),
- summary: 'Test 3 - Task 1',
- complete: 1,
- completed: false,
- priority: 1,
- categories: [],
- note: 'Migrate this app to vue.',
- hideSubtasks: false,
- allDay: true
- },
- {
- calendar: {
- writable: true,
- color: '#112233'
- },
- uid: 'ydj91848mn',
- uri: 'ydj91848mn.ics',
- // construct dates for next week, date only
- due: moment().add(5, 'days').format('YYYYMMDD'),
- start: moment().add(5, 'days').format('YYYYMMDD'),
- summary: 'Test 3 - Task 2',
- complete: 3,
- completed: true,
- priority: 5,
- categories: [],
- note: 'Migrate this app to vue.',
- hideSubtasks: false,
- allDay: true
- },
- {
- calendar: {
- writable: true,
- color: '#112233'
- },
- uid: 'ydk91848mn',
- uri: 'ydk91848mn.ics',
- // construct dates for today future, date only
- due: moment().add(1, 'hours').format('YYYYMMDD'),
- start: moment().add(1, 'hours').format('YYYYMMDD'),
- summary: 'Test 3 - Task 3',
- complete: 6,
- completed: false,
- priority: 7,
- categories: [],
- note: 'Migrate this app to vue.',
- hideSubtasks: false,
- allDay: true
- },
- {
- calendar: {
- writable: true,
- color: '#112233'
- },
- uid: 'ydl91848mn',
- uri: 'ydl91848mn.ics',
- // construct dates for today past, date only
- due: moment().subtract(1, 'hours').format('YYYYMMDD'),
- start: moment().subtract(1, 'hours').format('YYYYMMDD'),
- summary: 'Test 3 - Task 4',
- complete: 6,
- completed: false,
- priority: 7,
- categories: [],
- note: 'Migrate this app to vue.',
- hideSubtasks: false,
- allDay: true
- },
- {
- calendar: {
- writable: true,
- color: '#112233'
- },
- uid: 'ydl913r8mn',
- uri: 'ydl913r8mn.ics',
- // construct dates for today past, date only
- due: '',
- start: '',
- summary: 'Test 3 - Task 5',
- complete: 6,
- completed: false,
- priority: 7,
- categories: [],
- note: 'Migrate this app to vue.',
- hideSubtasks: false,
- allDay: false
- },
- {
- calendar: {
- writable: true,
- color: '#112233'
- },
- uid: 'y2w913r8mn',
- uri: 'y2w913r8mn.ics',
- summary: 'Test 3 - Task 6',
- complete: 6,
- completed: false,
- priority: 7,
- categories: [],
- note: 'Migrate this app to vue.',
- hideSubtasks: false,
- allDay: false
- }
- ]
- },
- 'test-4': {
- uri: 'test-4',
- displayname: 'Test 4',
- color: '#112245',
- writable: true,
- url: '/nextcloud/remote.php/dav/calendars/raimund.schluessler/test-4',
- tasks: []
- },
- 'a-list': {
- uri: 'a-list',
- displayname: 'A list',
- color: '#dd2245',
- writable: true,
- url: '/nextcloud/remote.php/dav/calendars/raimund.schluessler/a-list',
- tasks: [
- {
- calendar: {
- writable: true,
- color: '#dd2245'
- },
- uid: 'ydl92pr8mn',
- uri: 'ydl92pr8mn.ics',
- // construct dates for today past, date only
- due: '',
- start: '',
- summary: 'A list - Task 1',
- complete: 0,
- completed: false,
- priority: 0,
- categories: [],
- note: 'Migrate this app to vue.',
- hideSubtasks: false,
- allDay: false
- }
- ]
- }
- }
-})
diff --git a/src/store/storeHelper.js b/src/store/storeHelper.js
index 682005a1..de6228f3 100644
--- a/src/store/storeHelper.js
+++ b/src/store/storeHelper.js
@@ -42,7 +42,7 @@ function isTaskInList(task, listId) {
case 'week':
return task.completed === false && (week(task.start) || week(task.due))
default:
- return '' + task.calendar.uri === '' + listId
+ return '' + task.calendar.id === '' + listId
}
}
diff --git a/src/store/tasks.js b/src/store/tasks.js
index 12105cad..da3306c0 100644
--- a/src/store/tasks.js
+++ b/src/store/tasks.js
@@ -32,7 +32,8 @@ const getters = {
* @param {String} calendarId the Id of the calendar in question
*/
getTasksByCalendarId: (state, getters, rootState) => (calendarId) => {
- return Object.values(rootState.calendars.calendars[calendarId].tasks)
+ var calendar = getters.getCalendarById(calendarId)
+ return Object.values(calendar.tasks)
},
/**
@@ -47,7 +48,7 @@ const getters = {
*/
getAllTasks: (state, getters, rootState) => {
var tasks = []
- Object.values(rootState.calendars.calendars).forEach(calendar => {
+ rootState.calendars.calendars.forEach(calendar => {
tasks.concat(calendar.tasks)
})
return tasks
@@ -59,13 +60,14 @@ const getters = {
getTaskByRoute: (state, getters, rootState) => {
// If a calendar is given, only search in that calendar.
if (rootState.route.params.calendarId) {
- return rootState.calendars.calendars[rootState.route.params.calendarId].tasks.find(task => {
+ var calendar = getters.getCalendarById(rootState.route.params.calendarId)
+ return calendar.tasks.find(task => {
return task.uri === rootState.route.params.taskId
})
}
// Else, we have to search all calendars
var task
- for (let calendar of Object.values(rootState.calendars.calendars)) {
+ for (let calendar of rootState.calendars.calendars) {
task = calendar.tasks.find(task => {
return task.uri === rootState.route.params.taskId
})