mirror of
https://github.com/go-vikunja/vikunja.git
synced 2026-04-24 22:25:15 +00:00
fix: reload list view when marking recurring task done (#1457)
This commit is contained in:
@@ -215,6 +215,7 @@
|
||||
:task="task"
|
||||
:loading="taskUpdating[task.id] ?? false"
|
||||
:project-id="projectId"
|
||||
@taskCompletedRecurring="handleRecurringTaskCompletion"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -303,7 +304,7 @@ import {
|
||||
} from '@/helpers/saveCollapsedBucketState'
|
||||
import {calculateItemPosition} from '@/helpers/calculateItemPosition'
|
||||
|
||||
import {isSavedFilter} from '@/services/savedFilter'
|
||||
import {isSavedFilter, useSavedFilter} from '@/services/savedFilter'
|
||||
import {success} from '@/message'
|
||||
import {useProjectStore} from '@/stores/projects'
|
||||
import type {TaskFilterParams} from '@/services/taskCollection'
|
||||
@@ -342,6 +343,9 @@ const projectStore = useProjectStore()
|
||||
const taskPositionService = ref(new TaskPositionService())
|
||||
const taskBucketService = ref(new TaskBucketService())
|
||||
|
||||
// Saved filter composable for accessing filter data
|
||||
const {filter: savedFilter} = useSavedFilter(() => props.projectId)
|
||||
|
||||
const taskContainerRefs = ref<{ [id: IBucket['id']]: HTMLElement }>({})
|
||||
const bucketLimitInputRef = ref<HTMLInputElement | null>(null)
|
||||
|
||||
@@ -664,6 +668,22 @@ function updateBuckets(value: IBucket[]) {
|
||||
kanbanStore.setBuckets(value)
|
||||
}
|
||||
|
||||
function handleRecurringTaskCompletion() {
|
||||
// Only reload if we're in a saved filter and the filter contains date fields
|
||||
if (!isSavedFilter(project.value)) {
|
||||
return
|
||||
}
|
||||
|
||||
const filterContainsDateFields = savedFilter.value.filters?.filter?.includes('due_date') ||
|
||||
savedFilter.value.filters?.filter?.includes('start_date') ||
|
||||
savedFilter.value.filters?.filter?.includes('end_date')
|
||||
|
||||
if (filterContainsDateFields) {
|
||||
// Reload the kanban board to refresh tasks that now match/don't match the filter
|
||||
kanbanStore.loadBucketsForProject(props.projectId, props.viewId, params.value)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: fix type
|
||||
function updateBucketPosition(e: { newIndex: number }) {
|
||||
// (2) bucket positon is changed
|
||||
|
||||
@@ -112,7 +112,8 @@ import {useTaskList} from '@/composables/useTaskList'
|
||||
import {PERMISSIONS as Permissions} from '@/constants/permissions'
|
||||
import {calculateItemPosition} from '@/helpers/calculateItemPosition'
|
||||
import type {ITask} from '@/modelTypes/ITask'
|
||||
import {isSavedFilter} from '@/services/savedFilter'
|
||||
import {isSavedFilter, useSavedFilter} from '@/services/savedFilter'
|
||||
import {TASK_REPEAT_MODES} from '@/types/IRepeatMode'
|
||||
|
||||
import {useBaseStore} from '@/stores/base'
|
||||
|
||||
@@ -152,6 +153,9 @@ const {
|
||||
|
||||
const taskPositionService = ref(new TaskPositionService())
|
||||
|
||||
// Saved filter composable for accessing filter data
|
||||
const {filter: savedFilter} = useSavedFilter(() => props.projectId)
|
||||
|
||||
const tasks = ref<ITask[]>([])
|
||||
watch(
|
||||
allTasks,
|
||||
@@ -216,9 +220,30 @@ function updateTaskList(task: ITask) {
|
||||
|
||||
function updateTasks(updatedTask: ITask) {
|
||||
if (props.projectId < 0) {
|
||||
// In the case of a filter, we'll reload the filter in the background to avoid tasks which do
|
||||
// not match the filter show up here
|
||||
loadTasks(false)
|
||||
const originalTask = allTasks.value.find(t => t.id === updatedTask.id)
|
||||
const isRecurringTask = originalTask && (originalTask.repeatAfter.amount > 0 || originalTask.repeatMode === TASK_REPEAT_MODES.REPEAT_MODE_MONTH)
|
||||
|
||||
const filterContainsDateFields = project.value && isSavedFilter(project.value) &&
|
||||
project.value.title &&
|
||||
(savedFilter.value.filters?.filter?.includes('due_date') ||
|
||||
savedFilter.value.filters?.filter?.includes('start_date') ||
|
||||
savedFilter.value.filters?.filter?.includes('end_date'))
|
||||
|
||||
|
||||
if (isRecurringTask && filterContainsDateFields) {
|
||||
// In the case of a filter, we'll reload the filter in the background to avoid tasks which do
|
||||
// not match the filter show up here
|
||||
loadTasks(false)
|
||||
return
|
||||
}
|
||||
|
||||
// For other updates in saved filters, just update the task in place
|
||||
for (const t in allTasks.value) {
|
||||
if (allTasks.value[t].id === updatedTask.id) {
|
||||
allTasks.value[t] = updatedTask
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -128,6 +128,7 @@ import AssigneeList from '@/components/tasks/partials/AssigneeList.vue'
|
||||
import {playPopSound} from '@/helpers/playPop'
|
||||
import {isEditorContentEmpty} from '@/helpers/editorContentEmpty'
|
||||
import {useProjectStore} from '@/stores/projects'
|
||||
import {TASK_REPEAT_MODES} from '@/types/IRepeatMode'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
task: ITask,
|
||||
@@ -137,6 +138,10 @@ const props = withDefaults(defineProps<{
|
||||
loading: false,
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
'taskCompletedRecurring': [task: ITask]
|
||||
}>()
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const loadingInternal = ref(false)
|
||||
@@ -165,6 +170,9 @@ const isOverdue = computed(() => (
|
||||
))
|
||||
|
||||
async function toggleTaskDone(task: ITask) {
|
||||
const isRecurringTask = task.repeatAfter.amount > 0 || task.repeatMode === TASK_REPEAT_MODES.REPEAT_MODE_MONTH
|
||||
const wasBeingMarkedDone = !task.done
|
||||
|
||||
loadingInternal.value = true
|
||||
try {
|
||||
const updatedTask = await useTaskStore().update({
|
||||
@@ -175,6 +183,11 @@ async function toggleTaskDone(task: ITask) {
|
||||
if (updatedTask.done) {
|
||||
playPopSound()
|
||||
}
|
||||
|
||||
// Emit event if this was a recurring task being marked as done
|
||||
if (isRecurringTask && wasBeingMarkedDone && updatedTask.done) {
|
||||
emit('taskCompletedRecurring', updatedTask)
|
||||
}
|
||||
} finally {
|
||||
loadingInternal.value = false
|
||||
}
|
||||
|
||||
@@ -37,8 +37,8 @@ export function getSavedFilterIdFromProjectId(projectId: IProject['id']) {
|
||||
return filterId
|
||||
}
|
||||
|
||||
export function isSavedFilter(project: IProject) {
|
||||
return getSavedFilterIdFromProjectId(project?.id) > 0
|
||||
export function isSavedFilter(project: IProject | undefined | null) {
|
||||
return getSavedFilterIdFromProjectId(project?.id || 0) > 0
|
||||
}
|
||||
|
||||
export default class SavedFilterService extends AbstractService<ISavedFilter> {
|
||||
|
||||
Reference in New Issue
Block a user