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
Signed by: dpschen
GPG Key ID: B257AC0149F43A77
5 changed files with 60 additions and 33 deletions

View File

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

View File

@ -83,26 +83,34 @@
<span class="title">{{ rts.title }}</span> <span class="title">{{ rts.title }}</span>
<div class="tasks"> <div class="tasks">
<div :key="t.id" class="task" v-for="t in rts.tasks"> <div :key="t.id" class="task" v-for="t in rts.tasks">
<router-link <div class="is-flex is-align-items-center">
:to="{ name: route.name as string, params: { id: t.id } }" <Fancycheckbox
:class="{ 'is-strikethrough': t.done}"> class="task-done-checkbox"
<span v-model="t.done"
class="different-list" @update:model-value="toggleTaskDone(t)"
v-if="t.listId !== listId" />
<router-link
:to="{ name: route.name as string, params: { id: t.id } }"
:class="{ 'is-strikethrough': t.done}"
> >
<span <span
v-if="t.differentNamespace !== null" class="different-list"
v-tooltip="$t('task.relation.differentNamespace')"> v-if="t.listId !== listId"
{{ t.differentNamespace }} > >
<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>
<span {{ t.title }}
v-if="t.differentList !== null" </router-link>
v-tooltip="$t('task.relation.differentList')"> </div>
{{ t.differentList }} >
</span>
</span>
{{ t.title }}
</router-link>
<BaseButton <BaseButton
v-if="editEnabled" v-if="editEnabled"
@click="setRelationToDelete({ @click="setRelationToDelete({
@ -154,7 +162,9 @@ import TaskRelationModel from '@/models/taskRelation'
import BaseButton from '@/components/base/BaseButton.vue' import BaseButton from '@/components/base/BaseButton.vue'
import Multiselect from '@/components/input/multiselect.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({ const props = defineProps({
taskId: { taskId: {
@ -330,6 +340,23 @@ async function createAndRelateTask(title: string) {
newTaskRelation.task = newTask newTaskRelation.task = newTask
await addTaskRelation() 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> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -402,5 +429,13 @@ async function createAndRelateTask(title: string) {
padding: 0.5rem; 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(); @include modal-transition();
</style> </style>

View File

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

View File

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

View File

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