feat: allow marking a related task done directly from the list

This commit is contained in:
kolaente 2022-09-07 17:47:07 +02:00 committed by Dominik Pschenitschni
parent 943d5f7975
commit ce0f58c783
No known key found for this signature in database
GPG key ID: B257AC0149F43A77
5 changed files with 60 additions and 33 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'
@ -126,9 +125,6 @@ export default defineComponent({
...task,
done,
})
if (done) {
playPop()
}
} finally {
this.loadingInternal = false
}

View file

@ -83,26 +83,34 @@
<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 as string, params: { id: t.id } }"
:class="{ 'is-strikethrough': t.done}">
<span
class="different-list"
v-if="t.listId !== listId"
<div class="is-flex is-align-items-center">
<Fancycheckbox
class="task-done-checkbox"
v-model="t.done"
@update:model-value="toggleTaskDone(t)"
/>
<router-link
:to="{ name: route.name as string, params: { id: t.id } }"
:class="{ 'is-strikethrough': t.done}"
>
<span
v-if="t.differentNamespace !== null"
v-tooltip="$t('task.relation.differentNamespace')">
{{ t.differentNamespace }} >
class="different-list"
v-if="t.listId !== listId"
>
<span
v-if="t.differentNamespace !== null"
v-tooltip="$t('task.relation.differentNamespace')">
{{ t.differentNamespace }} >
</span>
<span
v-if="t.differentList !== null"
v-tooltip="$t('task.relation.differentList')">
{{ t.differentList }} >
</span>
</span>
<span
v-if="t.differentList !== null"
v-tooltip="$t('task.relation.differentList')">
{{ t.differentList }} >
</span>
</span>
{{ t.title }}
</router-link>
{{ t.title }}
</router-link>
</div>
<BaseButton
v-if="editEnabled"
@click="setRelationToDelete({
@ -154,7 +162,9 @@ import TaskRelationModel from '@/models/taskRelation'
import BaseButton from '@/components/base/BaseButton.vue'
import Multiselect from '@/components/input/multiselect.vue'
import { error } from '@/message'
import Fancycheckbox from '@/components/input/fancycheckbox.vue'
import {error, success} from '@/message'
const props = defineProps({
taskId: {
@ -330,6 +340,23 @@ async function createAndRelateTask(title: string) {
newTaskRelation.task = newTask
await addTaskRelation()
}
async function toggleTaskDone(task: ITask) {
await store.dispatch('tasks/update', task)
// Find the task in the list and update it so that it is correctly strike through
Object.entries(relatedTasks.value).some(([kind, tasks]) => {
return tasks.some((t, key) => {
const found = t.id === task.id
if (found) {
relatedTasks.value[kind as IRelationKind]![key] = task
}
return found
})
})
success({message: t('task.detail.updateSuccess')})
}
</script>
<style lang="scss" scoped>
@ -402,5 +429,13 @@ async function createAndRelateTask(title: string) {
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
}
@include modal-transition();
</style>

View file

@ -114,7 +114,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'
import ColorBubble from '@/components/misc/colorBubble.vue'
@ -208,10 +207,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,8 +25,9 @@ import type { IAttachment } from '@/modelTypes/IAttachment'
import type { IList } from '@/modelTypes/IList'
import type { RootStoreState, TaskState } from '@/store/types'
import { useLabelStore } from '@/stores/labels'
import { useListStore } from '@/stores/lists'
import {useLabelStore} from '@/stores/labels'
import {useListStore} from '@/stores/lists'
import {playPop} from '@/helpers/playPop'
// IDEA: maybe use a small fuzzy search here to prevent errors
function findPropertyByValue(object, key, value) {
@ -96,6 +97,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

@ -451,7 +451,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'
@ -733,9 +732,6 @@ export default defineComponent({
...this.task,
done: !this.task.done,
}
if (newTask.done) {
playPop()
}
this.saveTask({
task: newTask,