From f19823e9e77ae0017022dbfe63f66d2b065ba33a Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Mon, 29 Apr 2024 05:08:40 +0200 Subject: [PATCH] In Day view, differentiate done and undone Todos, and collect doneness checkboxes. --- plomtask/http.py | 13 ++++++--- plomtask/todos.py | 38 ++++++++++++++++++++++++- templates/base.html | 3 -- templates/day.html | 69 ++++++++++++++++++++++++++++++++++----------- tests/todos.py | 12 ++++---- 5 files changed, 105 insertions(+), 30 deletions(-) diff --git a/plomtask/http.py b/plomtask/http.py index 2b41db8..316fd08 100644 --- a/plomtask/http.py +++ b/plomtask/http.py @@ -127,10 +127,10 @@ class TaskHandler(BaseHTTPRequestHandler): date = self.params.get_str('date', todays_date()) top_todos = [t for t in Todo.by_date(self.conn, date) if not t.parents] - seen_todos: set[int] = set() - seen_conditions: set[int] = set() - todo_trees = [t.get_step_tree(seen_todos, seen_conditions) - for t in top_todos] + todo_trees = [t.get_undone_steps_tree() for t in top_todos] + done_trees = [] + for t in top_todos: + done_trees += t.get_done_steps_tree() condition_listings: list[ConditionListing] = [] for cond in Condition.all(self.conn): enablers = Todo.enablers_for_at(self.conn, cond, date) @@ -138,6 +138,7 @@ class TaskHandler(BaseHTTPRequestHandler): condition_listings += [ConditionListing(cond, enablers, disablers)] return {'day': Day.by_id(self.conn, date, create=True), 'todo_trees': todo_trees, + 'done_trees': done_trees, 'processes': Process.all(self.conn), 'condition_listings': condition_listings} @@ -207,6 +208,10 @@ class TaskHandler(BaseHTTPRequestHandler): todo.adopt_from(existing_todos) todo.make_missing_children(self.conn) todo.save(self.conn) + for todo_id in self.form_data.get_all_int('done'): + todo = Todo.by_id(self.conn, todo_id) + todo.is_done = True + todo.save(self.conn) return f'/day?date={date}' def do_POST_todo(self) -> str: diff --git a/plomtask/todos.py b/plomtask/todos.py index a874a6d..d53674b 100644 --- a/plomtask/todos.py +++ b/plomtask/todos.py @@ -17,6 +17,7 @@ class TodoStepsNode: is_todo: bool children: list[TodoStepsNode] seen: bool + hide: bool class Todo(BaseModel[int], ConditionsRelations): @@ -185,11 +186,46 @@ class Todo(BaseModel[int], ConditionsRelations): else: seen = step.id_ in seen_conditions seen_conditions.add(step.id_) - return TodoStepsNode(step, is_todo, children, seen) + return TodoStepsNode(step, is_todo, children, seen, False) node = make_node(self) return node + def get_undone_steps_tree(self) -> TodoStepsNode: + """Return tree of depended-on undone Todos and Conditions.""" + + def walk_tree(node: TodoStepsNode) -> None: + if isinstance(node.item, Todo) and node.item.is_done: + node.hide = True + for child in node.children: + walk_tree(child) + + seen_todos: set[int] = set() + seen_conditions: set[int] = set() + step_tree = self.get_step_tree(seen_todos, seen_conditions) + walk_tree(step_tree) + return step_tree + + def get_done_steps_tree(self) -> list[TodoStepsNode]: + """Return tree of depended-on done Todos.""" + + def make_nodes(node: TodoStepsNode) -> list[TodoStepsNode]: + children: list[TodoStepsNode] = [] + if not isinstance(node.item, Todo): + return children + for child in node.children: + children += make_nodes(child) + if node.item.is_done: + node.children = children + return [node] + return children + + seen_todos: set[int] = set() + seen_conditions: set[int] = set() + step_tree = self.get_step_tree(seen_todos, seen_conditions) + nodes = make_nodes(step_tree) + return nodes + def add_child(self, child: Todo) -> None: """Add child to self.children, avoid recursion, update parenthoods.""" diff --git a/templates/base.html b/templates/base.html index 71c79b4..87b1864 100644 --- a/templates/base.html +++ b/templates/base.html @@ -5,9 +5,6 @@ body { font-family: monospace; } -ul { - list-style-type: none; -} input.btn-harmless { color: green; } diff --git a/templates/day.html b/templates/day.html index e3fe5ef..efa1c9b 100644 --- a/templates/day.html +++ b/templates/day.html @@ -1,18 +1,50 @@ {% extends 'base.html' %} -{% macro node_with_children(node, indent) %} -
  • {% for i in range(indent) %}+{% endfor %} + +{% macro show_node(node, indent) %} {% if node.is_todo %} -{% if not node.item.is_doable %}{% endif %}[{% if node.item.is_done %}x{% else %} {% endif %}]{% if not node.item.is_doable %}{% endif %} +{% for i in range(indent) %}  {% endfor %} + {% if node.seen %}({% else %}{% endif %}{{node.item.process.title.newest|e}}{% if node.seen %}){% else %}{% endif %} {% else %} -< {% if node.seen %}({% else %}{% endif %}{{node.item.title.newest|e}}{% if node.seen %}){% else %}{% endif %} +{% for i in range(indent) %} {% endfor %} + +{% if node.seen %}({% else %}{% endif %}{{node.item.title.newest|e}}{% if node.seen %}){% else %}{% endif %} +{% endif %} +{% endmacro %} + + +{% macro undone_with_children(node, indent) %} +{% if not node.hide %} + + +{% if node.is_todo %} + +{% endif %} + + +{{ show_node(node, indent) }} + + +{% endif %} +{% for child in node.children %} +{{ undone_with_children(child, indent+1) }} +{% endfor %} +{% endmacro %} + + +{% macro done_with_children(node, indent) %} +{% if not node.hide %} + + +{{ show_node(node, indent) }} + + {% endif %} {% for child in node.children %} -{{ node_with_children(child, indent+1) }} +{{ done_with_children(child, indent+1) }} {% endfor %} {% endmacro %} + {% block content %}

    {{day.date}} / {{day.weekday}}

    @@ -27,25 +59,30 @@ add todo: {% endfor %} -

    conditions

    +