Merge pull request #414 from nextcloud/delete-completed
Allow to delete completed tasks, closes #69
This commit is contained in:
commit
d99f62fdb8
4 changed files with 199 additions and 4 deletions
|
@ -1345,3 +1345,36 @@
|
|||
box-shadow: 0 0 0 0 rgba(50, 50, 50, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.delete-completed {
|
||||
margin: 50px;
|
||||
width: auto;
|
||||
min-width: 30vw;
|
||||
&__button {
|
||||
display: inline-block;
|
||||
padding: 10px;
|
||||
padding-left: 34px;
|
||||
background-position: 10px center;
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
width: unset !important;
|
||||
height: unset !important;
|
||||
background-size: unset !important;
|
||||
}
|
||||
&__header {
|
||||
padding-top: 20px;
|
||||
max-width: 80%;
|
||||
margin: 12px auto;
|
||||
}
|
||||
&__progress {
|
||||
width: 80%;
|
||||
margin: auto;
|
||||
}
|
||||
&__tracker {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 80%;
|
||||
margin: auto;
|
||||
padding-top: 10px;
|
||||
}
|
||||
}
|
||||
|
|
152
src/components/DeleteCompletedModal.vue
Normal file
152
src/components/DeleteCompletedModal.vue
Normal file
|
@ -0,0 +1,152 @@
|
|||
<!--
|
||||
Nextcloud - Tasks
|
||||
|
||||
@author Raimund Schlüßler
|
||||
@copyright 2019 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/>.
|
||||
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="loadmore reactive">
|
||||
<span v-show="completedTasksCount" @click="openModal">
|
||||
{{ t('tasks', 'Delete all completed tasks.') }}
|
||||
</span>
|
||||
<Modal v-if="modalOpen"
|
||||
:out-transition="true"
|
||||
@close="closeModal"
|
||||
>
|
||||
<div class="emptycontent delete-completed">
|
||||
<p class="icon-delete" />
|
||||
<div v-if="completedTasksCount">
|
||||
<h3 class="delete-completed__header">
|
||||
{{ n('tasks',
|
||||
'This will delete {taskCount} completed task and its subtasks from calendar "{calendarName}".',
|
||||
'This will delete {taskCount} completed tasks and their subtasks from calendar "{calendarName}".',
|
||||
initialCompletedRootTasksCount,
|
||||
{
|
||||
taskCount: initialCompletedRootTasksCount,
|
||||
calendarName: calendar.displayName
|
||||
}
|
||||
) }}
|
||||
</h3>
|
||||
<button class="delete-completed__button icon-delete" type="button"
|
||||
@click="deleteCompletedTasks"
|
||||
>
|
||||
{{ t('tasks', 'Delete completed tasks.') }}
|
||||
</button>
|
||||
</div>
|
||||
<div v-else>
|
||||
<h3 class="delete-completed__header">
|
||||
{{ t('tasks', 'Deleted all completed tasks from calendar "{calendarName}".', {calendarName: calendar.displayName}) }}
|
||||
</h3>
|
||||
</div>
|
||||
<div>
|
||||
<progress :max="initialCompletedTasksCount" :value="progress" class="delete-completed__progress" />
|
||||
<p class="delete-completed__tracker">
|
||||
<span>{{ percentage }} %</span>
|
||||
<span v-if="failed === 0">
|
||||
{{ t('tasks', 'No errors') }}
|
||||
</span>
|
||||
<span v-else v-tooltip.auto="t('tasks', 'Open your browser console for more details')">
|
||||
{{ n('tasks',
|
||||
'Could not delete {failedCount} task.',
|
||||
'Could not delete {failedCount} tasks.',
|
||||
failed,
|
||||
{ failedCount: failed }
|
||||
) }}
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters, mapActions } from 'vuex'
|
||||
import { Modal } from 'nextcloud-vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Modal,
|
||||
},
|
||||
props: {
|
||||
calendar: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
modalOpen: false,
|
||||
initialCompletedTasksCount: 0,
|
||||
initialCompletedRootTasksCount: 0,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
loadedCompleted() {
|
||||
return this.calendar.loadedCompleted
|
||||
},
|
||||
tasks() {
|
||||
return this.completedRootTasks(this.calendar.tasks)
|
||||
},
|
||||
completedTasksCount() {
|
||||
var completedCount = function counter(tasks) {
|
||||
var i = tasks.length
|
||||
tasks.map((task) => {
|
||||
i += counter(Object.values(task.subTasks))
|
||||
})
|
||||
return i
|
||||
}
|
||||
return completedCount(this.tasks)
|
||||
},
|
||||
failed() {
|
||||
return 0
|
||||
},
|
||||
progress() {
|
||||
return this.initialCompletedTasksCount - this.completedTasksCount
|
||||
},
|
||||
percentage() {
|
||||
return this.initialCompletedTasksCount <= 0
|
||||
? 0
|
||||
: Math.floor(this.progress / this.initialCompletedTasksCount * 100)
|
||||
},
|
||||
...mapGetters({
|
||||
completedCount: 'getCalendarCountCompleted',
|
||||
completedRootTasks: 'findCompletedRootTasks',
|
||||
}),
|
||||
},
|
||||
methods: {
|
||||
...mapActions([
|
||||
'deleteTask',
|
||||
]),
|
||||
openModal() {
|
||||
this.modalOpen = true
|
||||
this.initialCompletedTasksCount = this.completedTasksCount
|
||||
// Number of completed root tasks
|
||||
this.initialCompletedRootTasksCount = this.tasks.length
|
||||
},
|
||||
closeModal() {
|
||||
this.modalOpen = false
|
||||
},
|
||||
deleteCompletedTasks() {
|
||||
this.tasks.map(
|
||||
(task) => this.deleteTask({ task: task, dav: true })
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
|
@ -65,6 +65,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
/>
|
||||
</task-drag-container>
|
||||
<LoadCompletedButton :calendar="calendar" />
|
||||
<DeleteCompletedModal v-if="calendar.loadedCompleted" :calendar="calendar" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -75,6 +76,7 @@ import { mapGetters, mapActions } from 'vuex'
|
|||
import { sort } from '../../store/storeHelper'
|
||||
import SortorderDropdown from '../SortorderDropdown'
|
||||
import LoadCompletedButton from '../LoadCompletedButton'
|
||||
import DeleteCompletedModal from '../DeleteCompletedModal'
|
||||
import Task from '../Task'
|
||||
import TaskDragContainer from '../TaskDragContainer'
|
||||
|
||||
|
@ -84,6 +86,7 @@ export default {
|
|||
'SortorderDropdown': SortorderDropdown,
|
||||
'LoadCompletedButton': LoadCompletedButton,
|
||||
TaskDragContainer,
|
||||
DeleteCompletedModal,
|
||||
},
|
||||
props: {
|
||||
calendarId: {
|
||||
|
|
|
@ -634,6 +634,12 @@ const actions = {
|
|||
* @param {Boolean} [data.dav = true] Trigger a dav deletion
|
||||
*/
|
||||
async deleteTask(context, { task, dav = true }) {
|
||||
function deleteTaskFromStore() {
|
||||
context.commit('deleteTask', task)
|
||||
let parent = context.getters.getTaskByUid(task.related)
|
||||
context.commit('deleteTaskFromParent', { task: task, parent: parent })
|
||||
context.commit('deleteTaskFromCalendar', task)
|
||||
}
|
||||
// delete all subtasks first
|
||||
await Promise.all(Object.values(task.subTasks).map(async(subTask) => {
|
||||
await context.dispatch('deleteTask', { task: subTask, dav: true })
|
||||
|
@ -641,15 +647,16 @@ const actions = {
|
|||
// only local delete if the task doesn't exists on the server
|
||||
if (task.dav && dav) {
|
||||
await task.dav.delete()
|
||||
.then(() => {
|
||||
deleteTaskFromStore()
|
||||
})
|
||||
.catch((error) => {
|
||||
console.debug(error)
|
||||
task.syncstatus = new TaskStatus('error', t('tasks', 'Could not delete the task.'))
|
||||
})
|
||||
} else {
|
||||
deleteTaskFromStore()
|
||||
}
|
||||
context.commit('deleteTask', task)
|
||||
let parent = context.getters.getTaskByUid(task.related)
|
||||
context.commit('deleteTaskFromParent', { task: task, parent: parent })
|
||||
context.commit('deleteTaskFromCalendar', task)
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue