Add custom recurrence patterns (day-of-week, nth-weekday, day-of-month)

Recurring tasks were locked to fixed daily/weekly/biweekly/monthly/yearly
intervals. The `custom` recurrence type and `recurrence_rule` field already
existed in the model and API docs, but RRULE evaluation was a TODO stub
that silently fell back to weekly, and no UI exposed the option.

Implements real RRULE parsing via dateutil.rrule, and adds a builder UI
(day-of-week checkboxes for weekly, day-of-month or Nth-weekday for
monthly) so users can express patterns like "every other Wednesday" or
"every second Tuesday" without hand-writing RRULE strings.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Keith Smith
2026-08-31 18:12:15 -06:00
co-authored by Claude Sonnet 5
parent 4d88d10382
commit 70dcc1f001
9 changed files with 335 additions and 56 deletions
+3
View File
@@ -479,6 +479,8 @@ class TaskDetailView(View):
else:
task.recurrence = 'none'
task.recurrence_rule = request.POST.get('recurrence_rule', '') if task.recurrence == 'custom' else ''
# Create next recurrence if task is being marked as completed
if old_status != 'completed' and task.status == 'completed' and task.recurrence != 'none':
task.create_next_recurrence()
@@ -541,6 +543,7 @@ class TaskCreateView(View):
due_date=request.POST.get('due_date') or None,
due_time=request.POST.get('due_time') or None,
recurrence=recurrence,
recurrence_rule=request.POST.get('recurrence_rule', '') if recurrence == 'custom' else '',
)
tag_ids = request.POST.getlist('tags')