feat(completion): explicit completion-date control menu#12
Open
renatomen wants to merge 10 commits into
Open
Conversation
U3: resolveCompletionDate(task, mode, ctx) maps today/asScheduled/onDue/onPicked to a concrete date, reporting unavailability (via i18n reason key) instead of substituting a fallback so the menu can disable an option. asScheduled prefers the clicked occurrence and never falls through to due; completion-anchored recurrences resolve asScheduled to scheduled (explicit re-anchor).
…line U4: updateProperty/updateTaskProperty accept an optional completionDate that overrides the getCompletionDateForTask default (task.occurrence_date || today) for non-recurring status completions. Parameter is optional so all existing status writes and the status-icon path are unchanged; recurring tasks remain unaffected by the existing property===status && !recurring guard. External HTTP/CLI/MCP exposure deferred (Scope Boundaries).
U5: replace the single recurring 'Mark complete for this date' item with four explicit actions (Complete today / as scheduled / on due date / on…), and add them net-new for non-recurring tasks. Each resolves via the four-mode resolver and dispatches the native mechanism: recurring -> toggleRecurringTaskComplete; non-recurring -> a status change carrying the completion date. Unavailable modes render disabled with a reason tooltip (R4). Un-complete is per task type (R11): recurring toggles the resolved date out per action; a completed non-recurring task collapses to one 'Mark incomplete' that reverts to the default status. Recurring labels carry an (Instance) prefix. U6: 'Complete on…' opens the shared date picker and records the chosen date (date-only, matching completedDate/complete_instances storage); cancel is a no-op. Adds contextMenus.task.completion i18n keys (en); other locales fall back to English pending translation (tracked in i18n.state.json).
Non-recurring completion/un-completion now surface a neutral failure notice (the old key wrongly said 'recurring task'). Adds tests for the no-completed- status guard, recurring 'Complete on due date' dispatch, and non-recurring 'Complete today' dispatch.
Local runs in non-UTC timezones (e.g. Pacific/Auckland, UTC+13) fail date/ day-boundary tests that pass on CI (GitHub Actions runs in UTC). Set process.env.TZ='UTC' before the config is exported so Jest's worker processes inherit it and read the zone at startup, before any Date is constructed. Overridable via 'TZ=... jest' for timezone-specific testing.
…le reactivates occurrence
Post-review UX refinements:
- Nest the four completion actions (and, for recurring, skip) under a single
'Complete or skip' submenu ('Complete' for non-recurring) to keep the
top-level menu compact; the occurrence note stays top-level.
- Uniform sentence-case labels for both task types (no per-type qualifier):
Completed today / Completed on schedule / Completed on due date /
Completed on (pick date); Skip instance; Mark incomplete.
- Rescheduling a recurring task onto a date removes that date from
complete_instances/skipped_instances, so moving the scheduled date back
reactivates the occurrence without manually editing those lists.
…dule clears instances on or after the new date
- Rename the submenu 'Complete or skip' -> 'Mark complete or skip' ('Complete'
-> 'Mark complete' for the non-recurring variant).
- Rescheduling a recurring task now drops every complete_instances/
skipped_instances entry on or after the new scheduled date (was: exact-date
match only), so an accidental off-schedule completion recorded on a later date
is also cleared when moving the schedule back. Entries strictly before the new
date are preserved as genuine history.
Rescheduling a recurring task that would clear completed/skipped instances (on or after the new date) now prompts for confirmation, listing the affected dates; declining aborts the reschedule entirely (nothing is written). Threaded via an optional confirmClearInstances callback on updateProperty: the context-menu and scheduled-date-modal paths supply a ConfirmationModal; the headless API (and any silent update) omit it and keep the prior behavior. Calendar drag still clears silently (revert-on-cancel deferred).
… menu Adds an appearance setting 'Group complete and skip actions in a submenu' (default on = current submenu behavior). When off, the completion actions (and skip for recurring tasks) render directly in the task context menu instead of nested under 'Mark complete or skip'. Read via settings.completionMenuAsSubmenu, defaulting to the submenu when unset (backward compatible).
In flat menu mode (submenu setting off), wrap the completion/skip actions with a separator before and after so the block is visually delimited from the rest of the task context menu.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR2 of the completion-date-control work — stacked on #11 (base is the PR1 branch; it will retarget to
mainonce #11 merges).Lets users choose, per action, which date a task's completion/skip is recorded against — without opening the task.
Core (U3–U6)
resolveCompletionDate(task, mode, ctx)resolvestoday / asScheduled / onDue / onPickedto a concrete date, reporting unavailability instead of substituting (so options can be disabled).asScheduledprefers the clicked occurrence and never falls through to due; completion-anchored recurrences resolveasScheduledto scheduled (explicit re-anchor).completionDatethreaded through the status pipeline so non-recurring completions record a chosencompletedDate(default today; recurring unaffected by the existingstatus && !recurringguard).Refinements
Testing
completionDateResolver,taskContextMenu.complete,taskContextMenu.pickDate,TaskService(completedDate threading, reschedule-clear, confirm callback),issue-1724. All green; typecheck, lint (ts/architecture), build green.Known follow-ups (not blocking)
contextMenus.task.completion.*and the appearance-setting keys are English-only; the 8 other locales fall back to English (tracked ini18n.state.json).