136 lines
3.7 KiB
Python
136 lines
3.7 KiB
Python
from flask import abort, flash, redirect, render_template, request, url_for
|
|
from flask_login import current_user, login_required
|
|
|
|
from . import bp
|
|
from .forms import ActionForm, STATUS_LABELS, SubtaskForm, TaskForm
|
|
from .models import TASK_STATUSES
|
|
from .services import (
|
|
TaskNotFoundError,
|
|
add_subtask,
|
|
create_task,
|
|
delete_task,
|
|
get_task,
|
|
list_tasks,
|
|
list_today_tasks,
|
|
toggle_subtask,
|
|
update_task,
|
|
)
|
|
|
|
|
|
def _owned_task_or_404(task_id: int):
|
|
try:
|
|
return get_task(task_id, current_user.id)
|
|
except TaskNotFoundError:
|
|
abort(404)
|
|
|
|
|
|
@bp.get("/")
|
|
@login_required
|
|
def index():
|
|
selected_status = request.args.get("status") or None
|
|
if selected_status not in {None, *TASK_STATUSES}:
|
|
abort(400)
|
|
tasks = list_tasks(current_user.id, selected_status)
|
|
return render_template(
|
|
"tasks/list.html",
|
|
tasks=tasks,
|
|
selected_status=selected_status,
|
|
status_labels=STATUS_LABELS,
|
|
)
|
|
|
|
|
|
@bp.get("/today")
|
|
@login_required
|
|
def today():
|
|
tasks = list_today_tasks(current_user.id)
|
|
return render_template("tasks/today.html", tasks=tasks)
|
|
|
|
|
|
@bp.route("/new", methods=["GET", "POST"])
|
|
@login_required
|
|
def create():
|
|
form = TaskForm()
|
|
if form.validate_on_submit():
|
|
task = create_task(
|
|
current_user.id,
|
|
title=form.title.data,
|
|
description=form.description.data,
|
|
status=form.status.data,
|
|
priority=form.priority.data,
|
|
due_date=form.due_date.data,
|
|
)
|
|
flash("Task captured.", "success")
|
|
return redirect(url_for("tasks.detail", task_id=task.id))
|
|
return render_template("tasks/form.html", form=form, heading="New task")
|
|
|
|
|
|
@bp.get("/<int:task_id>")
|
|
@login_required
|
|
def detail(task_id: int):
|
|
task = _owned_task_or_404(task_id)
|
|
return render_template(
|
|
"tasks/detail.html",
|
|
task=task,
|
|
subtask_form=SubtaskForm(),
|
|
action_form=ActionForm(),
|
|
)
|
|
|
|
|
|
@bp.route("/<int:task_id>/edit", methods=["GET", "POST"])
|
|
@login_required
|
|
def edit(task_id: int):
|
|
task = _owned_task_or_404(task_id)
|
|
form = TaskForm(obj=task)
|
|
if form.validate_on_submit():
|
|
update_task(
|
|
task,
|
|
title=form.title.data,
|
|
description=form.description.data,
|
|
status=form.status.data,
|
|
priority=form.priority.data,
|
|
due_date=form.due_date.data,
|
|
)
|
|
flash("Task updated.", "success")
|
|
return redirect(url_for("tasks.detail", task_id=task.id))
|
|
return render_template("tasks/form.html", form=form, heading="Edit task")
|
|
|
|
|
|
@bp.post("/<int:task_id>/delete")
|
|
@login_required
|
|
def delete(task_id: int):
|
|
task = _owned_task_or_404(task_id)
|
|
form = ActionForm()
|
|
if not form.validate_on_submit():
|
|
abort(400)
|
|
delete_task(task)
|
|
flash("Task deleted.", "info")
|
|
return redirect(url_for("tasks.index"))
|
|
|
|
|
|
@bp.post("/<int:task_id>/subtasks")
|
|
@login_required
|
|
def create_subtask(task_id: int):
|
|
task = _owned_task_or_404(task_id)
|
|
form = SubtaskForm()
|
|
if form.validate_on_submit():
|
|
add_subtask(task, form.title.data)
|
|
flash("Small step added.", "success")
|
|
else:
|
|
for errors in form.errors.values():
|
|
for error in errors:
|
|
flash(error, "error")
|
|
return redirect(url_for("tasks.detail", task_id=task.id))
|
|
|
|
|
|
@bp.post("/<int:task_id>/subtasks/<int:subtask_id>/toggle")
|
|
@login_required
|
|
def toggle_subtask_status(task_id: int, subtask_id: int):
|
|
task = _owned_task_or_404(task_id)
|
|
form = ActionForm()
|
|
if not form.validate_on_submit():
|
|
abort(400)
|
|
try:
|
|
toggle_subtask(task, subtask_id)
|
|
except TaskNotFoundError:
|
|
abort(404)
|
|
return redirect(url_for("tasks.detail", task_id=task.id))
|