Add configurable due time suggestions

This commit is contained in:
rucki
2026-09-11 17:36:38 +02:00
parent 1cd2d06b4b
commit 504f58aa36
8 changed files with 90 additions and 7 deletions
+31 -4
View File
@@ -147,6 +147,33 @@ def parse_due_command(raw):
return cleaned, timezone.make_aware(datetime.combine(due_date, due_time)), True
def default_due_time_options():
return [f'{hour:02d}:{minute:02d}' for hour in range(24) for minute in (0, 30)]
def user_due_time_options(user):
try:
raw = user.preferences.due_time_suggestions
except Exception:
raw = ''
options = []
for line in (raw or '').splitlines():
line = line.strip()
if not line:
continue
match = re.match(r'^(\d{1,2}:\d{2})(?:\s+(.+))?$', line)
if not match:
continue
try:
parsed = time.fromisoformat(match.group(1))
except ValueError:
continue
value = parsed.strftime('%H:%M')
label = match.group(2).strip() if match.group(2) else ''
options.append({'value': value, 'label': label})
return options or [{'value': value, 'label': ''} for value in default_due_time_options()]
def parse_due_at_from_post(post):
due_date = (post.get('due_date') or '').strip()
due_time = (post.get('due_time') or '').strip()
@@ -1307,7 +1334,7 @@ def edit_item(request, pk):
target_visibility, target_team = desired_item_scope(item, request.user, force_private=item.visibility == Item.Visibility.PRIVATE)
if not item_scope_fits_collections(item, target_visibility, target_team):
form.add_error('visibility', _('This visibility is incompatible with a collection that uses the note.'))
return render(request, 'core/_edit_form.html', {'item': item, 'form': form, 'tags': visible_tags(request.user, workspace=active_workspace(request))}, status=409)
return render(request, 'core/_edit_form.html', {'item': item, 'form': form, 'tags': visible_tags(request.user, workspace=active_workspace(request)), 'due_time_options': user_due_time_options(request.user)}, status=409)
item.visibility, item.team = target_visibility, target_team
item.save()
form.save_m2m()
@@ -1319,7 +1346,7 @@ def edit_item(request, pk):
response = render(request, 'core/_item.html', {'item': item, 'overview_lines': request.user.preferences.overview_lines if hasattr(request.user, 'preferences') else 4})
response['HX-Trigger'] = 'tagsChanged'
return response
return render(request, 'core/_edit_form.html', {'item': item, 'tags': visible_tags(request.user, workspace=active_workspace(request))})
return render(request, 'core/_edit_form.html', {'item': item, 'tags': visible_tags(request.user, workspace=active_workspace(request)), 'due_time_options': user_due_time_options(request.user)})
@login_required
@@ -1338,7 +1365,7 @@ def item_editor(request, pk):
target_visibility, target_team = desired_item_scope(item, request.user, force_private=item.visibility == Item.Visibility.PRIVATE)
if not item_scope_fits_collections(item, target_visibility, target_team):
form.add_error('visibility', _('This visibility is incompatible with a collection that uses the note.'))
return render(request, 'core/item_editor.html', {'item': item, 'form': form, 'tags': visible_tags(request.user, workspace=active_workspace(request)), 'next_url': next_url}, status=409)
return render(request, 'core/item_editor.html', {'item': item, 'form': form, 'tags': visible_tags(request.user, workspace=active_workspace(request)), 'next_url': next_url, 'due_time_options': user_due_time_options(request.user)}, status=409)
item.visibility, item.team = target_visibility, target_team
item.save()
form.save_m2m()
@@ -1348,7 +1375,7 @@ def item_editor(request, pk):
apply_team_from_tags(item, request.user, force_private=item.visibility == Item.Visibility.PRIVATE)
assign_item_from_mentions(item)
return redirect(next_url)
return render(request, 'core/item_editor.html', {'item': item, 'tags': visible_tags(request.user, workspace=active_workspace(request)), 'next_url': next_url})
return render(request, 'core/item_editor.html', {'item': item, 'tags': visible_tags(request.user, workspace=active_workspace(request)), 'next_url': next_url, 'due_time_options': user_due_time_options(request.user)})
@login_required