fix(tasks): don't allow adding the same assignee multiple times

See https://community.vikunja.io/t/task-can-be-assigned-twice-or-more-to-the-same-user/883
This commit is contained in:
kolaente 2022-10-06 18:03:17 +02:00
parent d4c179c862
commit bc1e366750
No known key found for this signature in database
GPG key ID: F40E70337AB24C9B
2 changed files with 64 additions and 45 deletions

View file

@ -28,7 +28,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import {ref, shallowReactive, watch, type PropType} from 'vue' import {ref, shallowReactive, watch, nextTick, type PropType} from 'vue'
import {useI18n} from 'vue-i18n' import {useI18n} from 'vue-i18n'
import User from '@/components/misc/user.vue' import User from '@/components/misc/user.vue'
@ -43,22 +43,22 @@ import {useTaskStore} from '@/stores/tasks'
import type {IUser} from '@/modelTypes/IUser' import type {IUser} from '@/modelTypes/IUser'
const props = defineProps({ const props = defineProps({
taskId: { taskId: {
type: Number, type: Number,
required: true, required: true,
}, },
listId: { listId: {
type: Number, type: Number,
required: true, required: true,
}, },
disabled: { disabled: {
default: false, default: false,
}, },
modelValue: { modelValue: {
type: Array as PropType<IUser[]>, type: Array as PropType<IUser[]>,
default: () => [], default: () => [],
}, },
}) })
const emit = defineEmits(['update:modelValue']) const emit = defineEmits(['update:modelValue'])
const taskStore = useTaskStore() const taskStore = useTaskStore()
@ -67,6 +67,7 @@ const {t} = useI18n({useScope: 'global'})
const listUserService = shallowReactive(new ListUserService()) const listUserService = shallowReactive(new ListUserService())
const foundUsers = ref([]) const foundUsers = ref([])
const assignees = ref<IUser[]>([]) const assignees = ref<IUser[]>([])
let isAdding = false
watch( watch(
() => props.modelValue, () => props.modelValue,
@ -80,9 +81,19 @@ watch(
) )
async function addAssignee(user: IUser) { async function addAssignee(user: IUser) {
await taskStore.addAssignee({user: user, taskId: props.taskId}) if (isAdding) {
emit('update:modelValue', assignees.value) return
success({message: t('task.assignee.assignSuccess')}) }
try {
nextTick(() => isAdding = true)
await taskStore.addAssignee({user: user, taskId: props.taskId})
emit('update:modelValue', assignees.value)
success({message: t('task.assignee.assignSuccess')})
} finally {
nextTick(() => isAdding = false)
}
} }
async function removeAssignee(user: IUser) { async function removeAssignee(user: IUser) {
@ -119,6 +130,7 @@ function clearAllFoundUsers() {
} }
const multiselect = ref() const multiselect = ref()
function focus() { function focus() {
multiselect.value.focus() multiselect.value.focus()
} }

View file

@ -171,32 +171,39 @@ export const useTaskStore = defineStore('task', {
user: IUser, user: IUser,
taskId: ITask['id'] taskId: ITask['id']
}) { }) {
const kanbanStore = useKanbanStore() const cancel = setModuleLoading(this)
const taskAssigneeService = new TaskAssigneeService()
const r = await taskAssigneeService.create(new TaskAssigneeModel({
userId: user.id,
taskId: taskId,
}))
const t = kanbanStore.getTaskById(taskId)
if (t.task === null) {
// Don't try further adding a label if the task is not in kanban
// Usually this means the kanban board hasn't been accessed until now.
// Vuex seems to have its difficulties with that, so we just log the error and fail silently.
console.debug('Could not add assignee to task in kanban, task not found', t)
return r
}
kanbanStore.setTaskInBucketByIndex({ try {
...t, const kanbanStore = useKanbanStore()
task: { const taskAssigneeService = new TaskAssigneeService()
...t.task, const r = await taskAssigneeService.create(new TaskAssigneeModel({
assignees: [ userId: user.id,
...t.task.assignees, taskId: taskId,
user, }))
], const t = kanbanStore.getTaskById(taskId)
}, if (t.task === null) {
}) // Don't try further adding a label if the task is not in kanban
return r // Usually this means the kanban board hasn't been accessed until now.
// Vuex seems to have its difficulties with that, so we just log the error and fail silently.
console.debug('Could not add assignee to task in kanban, task not found', t)
return r
}
kanbanStore.setTaskInBucketByIndex({
...t,
task: {
...t.task,
assignees: [
...t.task.assignees,
user,
],
},
})
return r
} finally {
cancel()
}
}, },
async removeAssignee({ async removeAssignee({