Add a "done" option to kanban buckets (#440)

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/440
Co-authored-by: konrad <konrad@kola-entertainments.de>
Co-committed-by: konrad <konrad@kola-entertainments.de>
This commit is contained in:
konrad 2021-03-24 20:16:56 +00:00
parent f1115c2338
commit 2435bd68a0
4 changed files with 65 additions and 7 deletions

View file

@ -20,6 +20,7 @@ export default class BucketModel extends AbstractModel {
listId: 0, listId: 0,
limit: 0, limit: 0,
tasks: [], tasks: [],
isDoneBucket: false,
createdBy: null, createdBy: null,
created: null, created: null,

View file

@ -8,6 +8,12 @@ import TaskCollectionService from '@/services/taskCollection'
const tasksPerBucket = 25 const tasksPerBucket = 25
const addTaskToBucketAndSort = (state, task) => {
const bi = filterObject(state.buckets, b => b.id === task.bucketId)
state.buckets[bi].tasks.push(task)
state.buckets[bi].tasks.sort((a, b) => a.position > b.position ? 1 : -1)
}
/** /**
* This store is intended to hold the currently active kanban view. * This store is intended to hold the currently active kanban view.
* It should hold only the current buckets. * It should hold only the current buckets.
@ -64,16 +70,38 @@ export default {
return return
} }
for (const b in state.buckets) { let found = false
if (state.buckets[b].id === task.bucketId) {
const findAndUpdate = b => {
for (const t in state.buckets[b].tasks) { for (const t in state.buckets[b].tasks) {
if (state.buckets[b].tasks[t].id === task.id) { if (state.buckets[b].tasks[t].id === task.id) {
const bucket = state.buckets[b] const bucket = state.buckets[b]
bucket.tasks[t] = task bucket.tasks[t] = task
if (bucket.id !== task.bucketId) {
bucket.tasks.splice(t, 1)
addTaskToBucketAndSort(state, task)
}
Vue.set(state.buckets, b, bucket) Vue.set(state.buckets, b, bucket)
found = true
return return
} }
} }
}
for (const b in state.buckets) {
if (state.buckets[b].id === task.bucketId) {
findAndUpdate(b)
if (found) {
return
}
}
}
for (const b in state.buckets) {
findAndUpdate(b)
if (found) {
return return
} }
} }

View file

@ -79,6 +79,9 @@ button.table {
.icon { .icon {
padding-right: .5rem; padding-right: .5rem;
}
.icon:not(.has-text-success) {
color: $grey-300 !important; color: $grey-300 !important;
} }

View file

@ -19,6 +19,13 @@
<div :class="{ 'is-loading': loading && !oneTaskUpdating}" class="kanban loader-container"> <div :class="{ 'is-loading': loading && !oneTaskUpdating}" class="kanban loader-container">
<div :key="`bucket${bucket.id}`" class="bucket" v-for="bucket in buckets"> <div :key="`bucket${bucket.id}`" class="bucket" v-for="bucket in buckets">
<div class="bucket-header"> <div class="bucket-header">
<span
v-if="bucket.isDoneBucket"
class="icon is-small has-text-success mr-2"
v-tooltip="'All tasks moved into this bucket will automatically marked as done.'"
>
<icon icon="check-double"/>
</span>
<h2 <h2
:ref="`bucket${bucket.id}title`" :ref="`bucket${bucket.id}title`"
@focusout="() => saveBucketTitle(bucket.id)" @focusout="() => saveBucketTitle(bucket.id)"
@ -63,6 +70,14 @@
Limit: {{ bucket.limit > 0 ? bucket.limit : 'Not set' }} Limit: {{ bucket.limit > 0 ? bucket.limit : 'Not set' }}
</template> </template>
</a> </a>
<a
@click="toggleDoneBucket(bucket)"
class="dropdown-item"
v-tooltip="'All tasks moved into the done bucket will be marked as done automatically. All tasks marked as done from elsewhere will be moved as well.'"
>
<span class="icon is-small" :class="{'has-text-success': bucket.isDoneBucket}"><icon icon="check-double"/></span>
Done bucket
</a>
<a <a
:class="{'is-disabled': buckets.length <= 1}" :class="{'is-disabled': buckets.length <= 1}"
@click="() => deleteBucketModal(bucket.id)" @click="() => deleteBucketModal(bucket.id)"
@ -591,6 +606,17 @@ export default {
bucket.limit === 0 || // If there is no limit set, dragging & dropping should always work bucket.limit === 0 || // If there is no limit set, dragging & dropping should always work
bucket.tasks.length < bucket.limit // Disallow dropping to buckets which have their limit reached bucket.tasks.length < bucket.limit // Disallow dropping to buckets which have their limit reached
}, },
toggleDoneBucket(bucket) {
bucket.isDoneBucket = !bucket.isDoneBucket
this.$store.dispatch('kanban/updateBucket', bucket)
.then(() => {
this.success({message: 'The done bucket has been saved successfully.'}, this)
})
.catch(e => {
this.error(e, this)
bucket.isDoneBucket = !bucket.isDoneBucket
})
},
}, },
} }
</script> </script>