From 5cd0fa0fa9fa09003cd8692725a6338637a0ab5c Mon Sep 17 00:00:00 2001 From: callumalpass Date: Sun, 26 Oct 2025 12:45:38 +1100 Subject: [PATCH] Fix Edit Task modal not adding completedDate on status change (#903) Fixes two related issues in the Edit Task modal: 1. completedDate not being added when marking tasks as done 2. Empty contexts and projects arrays being added to frontmatter Changes: - Extract completedDate logic into reusable helper method - Add completedDate handling to updateTask method - Fix empty projects array handling in TaskEditModal The Edit Task modal now behaves consistently with other completion methods (Agenda view, widget context menu, quick actions). --- docs/releases/unreleased.md | 6 +++++ src/modals/TaskEditModal.ts | 2 +- src/services/TaskService.ts | 49 ++++++++++++++++++++++++++++--------- 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/docs/releases/unreleased.md b/docs/releases/unreleased.md index 1cd94743..67916c42 100644 --- a/docs/releases/unreleased.md +++ b/docs/releases/unreleased.md @@ -42,6 +42,12 @@ Example: ## Fixed +- (#903) Fixed Edit Task modal not adding completedDate when marking tasks as done + - Edit Task modal now correctly adds completedDate when changing status to completed + - Fixed Edit Task modal adding empty contexts and projects arrays to frontmatter + - Behavior now consistent with other completion methods (Agenda view, widget context menu, quick actions) + - Thanks to @nightroman for reporting + - (#969), (#967) Fixed Bases Kanban layout not displaying correctly when no groupBy is configured - All tasks were appearing in a single "None" column - Columns now appear in the order defined in TaskNotes settings (not alphabetical) diff --git a/src/modals/TaskEditModal.ts b/src/modals/TaskEditModal.ts index ed4ea0dd..20714a1c 100644 --- a/src/modals/TaskEditModal.ts +++ b/src/modals/TaskEditModal.ts @@ -650,7 +650,7 @@ export class TaskEditModal extends TaskModal { const oldProjects = this.task.projects || []; if (JSON.stringify(newProjects.sort()) !== JSON.stringify(oldProjects.sort())) { - changes.projects = newProjects; + changes.projects = newProjects.length > 0 ? newProjects : undefined; } // Parse and compare tags diff --git a/src/services/TaskService.ts b/src/services/TaskService.ts index 13e668fc..e2066782 100644 --- a/src/services/TaskService.ts +++ b/src/services/TaskService.ts @@ -552,18 +552,7 @@ export class TaskService { // Update completed date when marking as complete (non-recurring tasks only) // FIX: Use freshTask instead of stale task to check recurrence - if (!freshTask.recurrence) { - const completedDateField = - this.plugin.fieldMapper.toUserField("completedDate"); - if (this.plugin.statusManager.isCompletedStatus(value)) { - frontmatter[completedDateField] = getCurrentDateString(); - } else { - // Remove completed date when marking as incomplete - if (frontmatter[completedDateField]) { - delete frontmatter[completedDateField]; - } - } - } + this.updateCompletedDateInFrontmatter(frontmatter, value, !!freshTask.recurrence); } else if ((property === "due" || property === "scheduled") && !value) { // Remove empty due/scheduled dates delete frontmatter[fieldName]; @@ -1197,6 +1186,11 @@ export class TaskService { } }); + // Handle completedDate for status changes (non-recurring tasks only) + if (updates.status !== undefined) { + this.updateCompletedDateInFrontmatter(frontmatter, updates.status, !!originalTask.recurrence); + } + // Handle task identification based on settings if (this.plugin.settings.taskIdentificationMethod === "property") { const propName = this.plugin.settings.taskPropertyName; @@ -1798,6 +1792,37 @@ export class TaskService { return updatedTask; } + /** + * Update the completedDate field in frontmatter based on the task's status. + * For non-recurring tasks: + * - Sets completedDate to current date when status becomes completed + * - Removes completedDate when status becomes incomplete + * For recurring tasks, this method does nothing (they don't use completedDate). + * + * @param frontmatter - The frontmatter object to modify + * @param newStatus - The new status value + * @param isRecurring - Whether the task is recurring + */ + private updateCompletedDateInFrontmatter( + frontmatter: Record, + newStatus: string, + isRecurring: boolean + ): void { + if (isRecurring) { + return; // Recurring tasks don't use completedDate + } + + const completedDateField = this.plugin.fieldMapper.toUserField("completedDate"); + + if (this.plugin.statusManager.isCompletedStatus(newStatus)) { + frontmatter[completedDateField] = getCurrentDateString(); + } else { + if (frontmatter[completedDateField]) { + delete frontmatter[completedDateField]; + } + } + } + /** * Extract the basename from a project string, handling wikilink format * Examples: