feat: allow marking a related task done directly from the list of related tasks #2330

Closed
konrad wants to merge 3 commits from feature/enable-related-task-done into main
5 changed files with 40 additions and 19 deletions

View File

@ -68,7 +68,6 @@
<script lang="ts">
import {defineComponent, type PropType} from 'vue'
import {playPop} from '../../../helpers/playPop'
import PriorityLabel from '../../../components/tasks/partials/priorityLabel.vue'
import User from '../../../components/misc/user.vue'
import Done from '@/components/misc/Done.vue'
@ -125,9 +124,6 @@ export default defineComponent({
...task,
done,
})
if (done) {
playPop()
}
} finally {
this.loadingInternal = false
}

View File

@ -84,9 +84,11 @@
<span class="title">{{ rts.title }}</span>
<div class="tasks">
<div :key="t.id" class="task" v-for="t in rts.tasks">
<router-link
:to="{ name: $route.name, params: { id: t.id } }"
:class="{ 'is-strikethrough': t.done}">
<div class="is-flex is-align-items-center">
<Fancycheckbox class="task-done-checkbox" v-model="t.done" @change="toggleTaskDone(t)"/>
<router-link
:to="{ name: $route.name, params: { id: t.id } }"
:class="{ 'is-strikethrough': t.done}">
<span
class="different-list"
v-if="t.listId !== listId"
@ -102,8 +104,9 @@
{{ t.differentList }} >
</span>
</span>
{{ t.title }}
</router-link>
{{ t.title }}
</router-link>
</div>
<BaseButton
v-if="editEnabled"
@click="() => {showDeleteModal = true; relationToDelete = {relationKind: rts.kind, otherTaskId: t.id}}"
@ -145,10 +148,12 @@ import TaskService from '../../../services/task'
import TaskModel from '../../../models/task'
import TaskRelationService from '../../../services/taskRelation'
import TaskRelationModel from '@/models/taskRelation'
import { RELATION_KIND, RELATION_KINDS } from '@/types/IRelationKind'
import {RELATION_KIND, RELATION_KINDS} from '@/types/IRelationKind'
import BaseButton from '@/components/base/BaseButton.vue'
import Multiselect from '@/components/input/multiselect.vue'
import Fancycheckbox from '@/components/input/fancycheckbox.vue'
import type {ITask} from '@/modelTypes/ITask'
export default defineComponent({
name: 'relatedTasks',
@ -169,6 +174,7 @@ export default defineComponent({
}
},
components: {
Fancycheckbox,
BaseButton,
Multiselect,
},
@ -314,6 +320,21 @@ export default defineComponent({
}
})
},
async toggleTaskDone(task: ITask) {
await this.$store.dispatch('tasks/update', task)
// Find the task in the list and update it so that it is correctly strike through
konrad marked this conversation as resolved Outdated

Unsure: Wouldn't it make sense to play this from the store when we update the task an the done prop has changed?

Unsure: Wouldn't it make sense to play this from the store when we update the task an the `done` prop has changed?

Yes.

Yes.

Done.

Done.
Object.entries(this.relatedTasks).forEach(([kind, tasks]) => {
tasks.forEach((t, key) => {
if (t.id === task.id) {
this.relatedTasks[kind][key] = task
}
})
})
this.$message.success({message: this.$t('task.detail.updateSuccess')})
},
},
})
</script>
@ -387,5 +408,13 @@ export default defineComponent({
padding: 0.5rem;
}
// FIXME: The height of the actual checkbox in the <Fancycheckbox/> component is too much resulting in a
// weired positioning of the checkbox. Setting the height here is a workaround until we fix the styling
// of the component.
.task-done-checkbox {
padding: 0;
height: 18px; // The exact height of the checkbox in the container
}
konrad marked this conversation as resolved Outdated

Why do we need to set a height from outside here?

Why do we need to set a height from outside here?

Because otherwise the height of the actual checkbox in the <Fancycheckbox component is too much resulting in a weired positioning of the checkbox. Setting the height here is a workaround until we fix the styling of the component. I didn't want to do this in this PR because the component is used in a lot of places and the change has potential to break a few things. Better do it in another PR.

Because otherwise the height of the actual checkbox in the `<Fancycheckbox` component is too much resulting in a weired positioning of the checkbox. Setting the height here is a workaround until we fix the styling of the component. I didn't want to do this in this PR because the component is used in a lot of places and the change has potential to break a few things. Better do it in another PR.

Okay. Can you prefix it with a // FIXME: or // HACK: then?

Okay. Can you prefix it with a `// FIXME:` or `// HACK:` then?

Done.

Done.
@include modal-transition();
</style>

View File

@ -107,7 +107,6 @@ import BaseButton from '@/components/base/BaseButton.vue'
import Fancycheckbox from '../../input/fancycheckbox.vue'
import DeferTask from './defer-task.vue'
import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
import {playPop} from '@/helpers/playPop'
import ChecklistSummary from './checklist-summary.vue'
import {formatDateSince, formatISO, formatDateLong} from '@/helpers/time/formatDate'
@ -195,10 +194,7 @@ export default defineComponent({
async markAsDone(checked: boolean) {
const updateFunc = async () => {
const task = await this.taskService.update(this.task)
if (this.task.done) {
playPop()
}
const task = await this.$store.dispatch('tasks/update', this.task)
this.task = task
this.$emit('task-updated', task)
this.$message.success({

View File

@ -25,6 +25,7 @@ import type { IAttachment } from '@/modelTypes/IAttachment'
import type { IList } from '@/modelTypes/IList'
import type { RootStoreState, TaskState } from '@/store/types'
import {playPop} from '@/helpers/playPop'
// IDEA: maybe use a small fuzzy search here to prevent errors
function findPropertyByValue(object, key, value) {
@ -94,6 +95,9 @@ const tasksStore : Module<TaskState, RootStoreState>= {
try {
const updatedTask = await taskService.update(task)
ctx.commit('kanban/setTaskInBucket', updatedTask, {root: true})
if (task.done) {
playPop()
}
return updatedTask
} finally {
cancel()

View File

@ -446,7 +446,6 @@ import ColorPicker from '../../components/input/colorPicker.vue'
import heading from '@/components/tasks/partials/heading.vue'
import Datepicker from '@/components/input/datepicker.vue'
import BaseButton from '@/components/base/BaseButton.vue'
import {playPop} from '@/helpers/playPop'
import TaskSubscription from '@/components/misc/subscription.vue'
import {CURRENT_LIST} from '@/store/mutation-types'
@ -716,9 +715,6 @@ export default defineComponent({
...this.task,
done: !this.task.done,
}
if (newTask.done) {
playPop()
}
this.saveTask({
task: newTask,