fix(kanban): guard task modal race conditions (#1472)

This commit is contained in:
kolaente 2025-09-11 17:15:57 +02:00 committed by GitHub
parent a8b72e7363
commit 8ce8d445ba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 36 additions and 3 deletions

View File

@ -1,4 +1,4 @@
import {computed, h, shallowRef, type VNode, watchEffect} from 'vue'
import {computed, defineAsyncComponent, h, shallowRef, type VNode, watchEffect} from 'vue'
import {useRoute, useRouter} from 'vue-router'
import {useBaseStore} from '@/stores/base'
import {useProjectStore} from '@/stores/projects'
@ -46,7 +46,11 @@ export function useRouteWithModal() {
routeProps.backdropView = backdropView.value
const component = route.matched[0]?.components?.default
let component = route.matched[0]?.components?.default
if (typeof component === 'function') {
component = defineAsyncComponent(component)
}
if (!component) {
currentModal.value = undefined

View File

@ -589,7 +589,7 @@
<script lang="ts" setup>
import {ref, reactive, shallowReactive, computed, watch, nextTick, onMounted, onBeforeUnmount} from 'vue'
import {useRouter, type RouteLocation} from 'vue-router'
import {useRouter, type RouteLocation, onBeforeRouteLeave} from 'vue-router'
import {storeToRefs} from 'pinia'
import {useI18n} from 'vue-i18n'
import {unrefElement} from '@vueuse/core'
@ -668,6 +668,7 @@ const authStore = useAuthStore()
const baseStore = useBaseStore()
const task = ref<ITask>(new TaskModel())
const taskNotFound = ref(false)
const taskTitle = computed(() => task.value.title)
useTitle(taskTitle)
@ -689,6 +690,33 @@ onBeforeUnmount(() => {
document.removeEventListener('keydown', saveTaskViaHotkey)
})
onBeforeRouteLeave(async () => {
if (taskNotFound.value) {
return
}
if (!project.value) {
await new Promise<void>((resolve) => {
const timeout = setTimeout(() => {
stop()
resolve()
}, 5000) // 5 second timeout
const stop = watch(project, (p) => {
if (p) {
clearTimeout(timeout)
stop()
resolve()
}
})
})
}
if (project.value) {
await baseStore.handleSetCurrentProjectIfNotSet(project.value)
}
})
// We doubled the task color property here because verte does not have a real change property, leading
// to the color property change being triggered when the # is removed from it, leading to an update,
// which leads in turn to a change... This creates an infinite loop in which the task is updated, changed,
@ -749,6 +777,7 @@ watch(
}
} catch (e) {
if (e?.response?.status === 404) {
taskNotFound.value = true
router.replace({name: 'not-found'})
return
}