From d2604b5c1023ab0992eedf0417cb750be8095c28 Mon Sep 17 00:00:00 2001 From: Morgana Date: Mon, 13 Apr 2026 14:25:53 -0500 Subject: [PATCH] Implemented Task Manager --- app.py | 62 ++++++++++++++++++++++++++++++++++++++ static/database.css | 3 +- static/index.css | 9 ++++++ static/style.css | 4 +++ static/tasks.css | 39 ++++++++++++++++++++++++ static/tasks.js | 46 ++++++++++++++++++++++++++++ templates/database.html | 2 +- templates/index.html | 8 ++--- templates/tasks.html | 67 +++++++++++++++++++++++++++++++++++++++++ 9 files changed, 234 insertions(+), 6 deletions(-) create mode 100644 static/tasks.css create mode 100644 static/tasks.js create mode 100644 templates/tasks.html diff --git a/app.py b/app.py index 110b7a5..d837619 100644 --- a/app.py +++ b/app.py @@ -28,6 +28,14 @@ with open("./config.json", "r", encoding="utf-8") as file: db = mongo.db +def partition(predicate, iterable): + trues = [] + falses = [] + for item in iterable: + (trues if predicate(item) else falses).append(item) + return falses, trues + + @app.context_processor def inject_data(): ddata = db.domains.find_one({"id": request.endpoint}) @@ -190,3 +198,57 @@ def database_edit(collection, oid): name=name, document=document, ) + + +@app.route("/tasks", methods=["GET", "POST"]) +def tasks(): + print(request.form, request.method) + if request.method == "POST": + act = request.form.get("action", "save") + match act: + case "save": + oid = request.form.get("oid") + if oid: + db.tasks.update_one( + {"_id": ObjectId(oid)}, + { + "$set": { + "id": request.form.get("tid") or "000", + "txt": request.form.get("content", ""), + "pre": request.form.get("pre", "").split(), + } + }, + ) + else: + db.tasks.insert_one( + { + "id": request.form.get("tid") or "000", + "txt": request.form.get("content", ""), + "pre": request.form.get("pre", "").split(), + "done": False, + } + ) + case "delete": + oid = request.form.get("oid") + db.tasks.delete_one({"_id": ObjectId(oid)}) + case "mark": + oid = request.form.get("oid") + db.tasks.update_one( + {"_id": ObjectId(oid)}, + {"$set": {"done": request.form.get("done") == "False"}}, + ) + tasks = sorted(db.tasks.find(), key=lambda task: task["id"]) + other_tasks, complete_tasks = partition(lambda task: task["done"], tasks) + active_tasks, blocked_tasks = partition( + lambda task: any( + any(not ot["done"] for ot in tasks if ot["id"] == pre) + for pre in task["pre"] + ), + other_tasks, + ) + return render_template( + "tasks.html", + active_tasks=active_tasks, + blocked_tasks=blocked_tasks, + complete_tasks=complete_tasks, + ) diff --git a/static/database.css b/static/database.css index 6c56577..6d96aa3 100644 --- a/static/database.css +++ b/static/database.css @@ -8,7 +8,8 @@ hr { width: 100%; } -form { +#db-form, +#edit-form { display: flex; flex-direction: row; gap: 0.25em; diff --git a/static/index.css b/static/index.css index 8863cfd..e81b9b4 100644 --- a/static/index.css +++ b/static/index.css @@ -112,6 +112,15 @@ hr#sectorbar { ul { margin: 0.5em 0; } + + li { + color: var(--color); + } + + a { + color: var(--color); + text-decoration: none; + } } #other>div { diff --git a/static/style.css b/static/style.css index f975c29..30c3a41 100644 --- a/static/style.css +++ b/static/style.css @@ -86,6 +86,10 @@ hr { border-bottom: 1px dashed var(--color); } +label { + color: var(--color); +} + header { display: flex; flex-direction: row; diff --git a/static/tasks.css b/static/tasks.css new file mode 100644 index 0000000..691b575 --- /dev/null +++ b/static/tasks.css @@ -0,0 +1,39 @@ +ul { + margin: 1em; + padding: 0; + display: flex; + flex-direction: column; + gap: 0.5em; +} + +li { + list-style: none; + margin: 0; + padding: 0.5em; + background-color: var(--color-bg2); + + border: 1px solid var(--color); + + span { + flex-direction: row; + gap: 0.5em; + } +} + +.task-value, +.task-value-editor { + flex-grow: 1; +} + +output.task-value { + border: none; + text-decoration: 1px dotted underline var(--color); +} + +.view-box { + display: flex; +} + +.edit-box { + display: none; +} \ No newline at end of file diff --git a/static/tasks.js b/static/tasks.js new file mode 100644 index 0000000..4a078bf --- /dev/null +++ b/static/tasks.js @@ -0,0 +1,46 @@ +function getFirst(item, className) { + return item.getElementsByClassName(className)[0] +} + +for (elem of document.getElementsByTagName("li")) { + var editBtn = getFirst(elem, "task-value") + if (editBtn) { + editBtn.onclick = (event) => { + event.preventDefault(true); + var item = event.target.parentNode.parentNode; + getFirst(item, "view-box").style.display = "none"; + getFirst(item, "edit-box").style.display = "flex"; + } + } + var cancelBtn = getFirst(elem, "btn-cancel") + if (cancelBtn) { + cancelBtn.onclick = (event) => { + event.preventDefault(true); + var item = event.target.parentNode.parentNode; + getFirst(item, "edit-box").style.display = "none"; + getFirst(item, "view-box").style.display = "flex"; + } + } + var markBtn = getFirst(elem, "task-id") + if (markBtn) { + markBtn.onclick = (event) => { + event.target.type = "submit"; + event.target.click(); + } + } +} + +var newBtn = document.getElementById("btn-new") +newBtn.onclick = (event) => { + event.preventDefault(true); + var item = event.target.parentNode.parentNode; + getFirst(item, "view-box").style.display = "none"; + getFirst(item, "edit-box").style.display = "flex"; +} +var cancelBtn = document.getElementById("btn-cancel") +cancelBtn.onclick = (event) => { + event.preventDefault(true); + var item = event.target.parentNode.parentNode; + getFirst(item, "edit-box").style.display = "none"; + getFirst(item, "view-box").style.display = "flex"; +} \ No newline at end of file diff --git a/templates/database.html b/templates/database.html index ff3680c..6edc176 100644 --- a/templates/database.html +++ b/templates/database.html @@ -6,7 +6,7 @@ {% block content %}
-
+
diff --git a/templates/index.html b/templates/index.html index 4cf0b1e..f53d794 100644 --- a/templates/index.html +++ b/templates/index.html @@ -68,11 +68,11 @@

News

-

Test1

-

Foo, Bar, Baz

+

Error: Not Implemented

+

Unable to connect to Index Feed.


-

Test2

-

Quux, Quuux, Quuuux

+

Example Text

+

Foo, Bar, Baz, Quux

diff --git a/templates/tasks.html b/templates/tasks.html new file mode 100644 index 0000000..5b7cd59 --- /dev/null +++ b/templates/tasks.html @@ -0,0 +1,67 @@ +{% extends "base.html" %} + +{% block head %} + + +{% endblock %} + +{% macro make_task(task) %} +
  • + + + + {{ task["txt"] }} + {% for pre in task["pre"] %} + {{ pre }} + {% endfor %} + + + + + + + + + + + +
  • + +{% endmacro %} + +{% block content %} +
    +

    Active Tasks:

    +
      + {% for task in active_tasks %} + {{ make_task(task) }} + {% endfor %} +
    • +
      + + + + + + + + + + +
      +
    • +
    +

    Blocked Tasks:

    +
      + {% for task in blocked_tasks %} + {{ make_task(task) }} + {% endfor %} +
    +

    Complete Tasks:

    +
      + {% for task in complete_tasks %} + {{ make_task(task) }} + {% endfor %} +
    +
    +{% endblock %} \ No newline at end of file