home · contact · privacy
Add Todos view, filterable and sortable by process, date, comment, etc.
authorChristian Heller <c.heller@plomlompom.de>
Thu, 30 May 2024 02:49:57 +0000 (04:49 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Thu, 30 May 2024 02:49:57 +0000 (04:49 +0200)
plomtask/http.py
plomtask/todos.py
templates/_base.html
templates/process.html
templates/todos.html [new file with mode: 0644]

index dbc78ebaeb0b17aa3ff5173c40c6c96036255261..f6b17a076c6fa92455983b1198351cc486c79906 100644 (file)
@@ -152,6 +152,41 @@ class TaskHandler(BaseHTTPRequestHandler):
                 'todo_candidates': Todo.by_date(self.conn, todo.date),
                 'condition_candidates': Condition.all(self.conn)}
 
                 'todo_candidates': Todo.by_date(self.conn, todo.date),
                 'condition_candidates': Condition.all(self.conn)}
 
+    def do_GET_todos(self) -> dict[str, object]:
+        """Show Todos from ?start= to ?end=, of ?process=, ?comment= pattern"""
+        sort_by = self.params.get_str('sort_by')
+        start = self.params.get_str('start')
+        end = self.params.get_str('end')
+        process_id = self.params.get_int_or_none('process_id')
+        comment_pattern = self.params.get_str('comment_pattern')
+        todos = []
+        for t in Todo.matching(self.conn, comment_pattern):
+            # pylint: disable=too-many-boolean-expressions
+            if (start and t.date < start)\
+                    or (end and t.date > end)\
+                    or (process_id and t.process.id_ != process_id):
+                continue
+            todos += [t]
+        if sort_by == 'doneness':
+            todos.sort(key=lambda t: t.is_done)
+        elif sort_by == '-doneness':
+            todos.sort(key=lambda t: t.is_done, reverse=True)
+        elif sort_by == 'process':
+            todos.sort(key=lambda t: t.process.title.newest)
+        elif sort_by == '-process':
+            todos.sort(key=lambda t: t.process.title.newest, reverse=True)
+        elif sort_by == 'comment':
+            todos.sort(key=lambda t: t.comment)
+        elif sort_by == '-comment':
+            todos.sort(key=lambda t: t.comment, reverse=True)
+        elif sort_by == '-date':
+            todos.sort(key=lambda t: t.date, reverse=True)
+        else:
+            todos.sort(key=lambda c: c.title.newest)
+        return {'start': start, 'end': end, 'process_id': process_id,
+                'comment_pattern': comment_pattern, 'todos': todos,
+                'all_processes': Process.all(self.conn), 'sort_by': sort_by}
+
     def do_GET_conditions(self) -> dict[str, object]:
         """Show all Conditions."""
         pattern = self.params.get_str('pattern')
     def do_GET_conditions(self) -> dict[str, object]:
         """Show all Conditions."""
         pattern = self.params.get_str('pattern')
@@ -193,6 +228,7 @@ class TaskHandler(BaseHTTPRequestHandler):
         return {'process': process,
                 'steps': process.get_steps(self.conn),
                 'owners': process.used_as_step_by(self.conn),
         return {'process': process,
                 'steps': process.get_steps(self.conn),
                 'owners': process.used_as_step_by(self.conn),
+                'n_todos': len(Todo.by_process_id(self.conn, process.id_)),
                 'step_candidates': Process.all(self.conn),
                 'condition_candidates': Condition.all(self.conn)}
 
                 'step_candidates': Process.all(self.conn),
                 'condition_candidates': Condition.all(self.conn)}
 
index bffa23ae8c46ae02004344e7c206a4e7104050a0..712609aa8d81fdbe4f194a244ab6927224ee67ca 100644 (file)
@@ -31,6 +31,7 @@ class Todo(BaseModel[int], ConditionsRelations):
                          ('todo_disables', 'todo', 'disables'),
                          ('todo_children', 'parent', 'children'),
                          ('todo_children', 'child', 'parents')]
                          ('todo_disables', 'todo', 'disables'),
                          ('todo_children', 'parent', 'children'),
                          ('todo_children', 'child', 'parents')]
+    to_search = ['comment']
 
     # pylint: disable=too-many-arguments
     def __init__(self, id_: int | None,
 
     # pylint: disable=too-many-arguments
     def __init__(self, id_: int | None,
@@ -107,6 +108,12 @@ class Todo(BaseModel[int], ConditionsRelations):
                 target += [Condition.by_id(db_conn, cond_id)]
         return todo
 
                 target += [Condition.by_id(db_conn, cond_id)]
         return todo
 
+    @classmethod
+    def by_process_id(cls, db_conn: DatabaseConnection,
+                      process_id: int | None) -> list[Todo]:
+        """Collect all Todos of Process of process_id."""
+        return [t for t in cls.all(db_conn) if t.process.id_ == process_id]
+
     @classmethod
     def by_date(cls, db_conn: DatabaseConnection, date: str) -> list[Todo]:
         """Collect all Todos for Day of date."""
     @classmethod
     def by_date(cls, db_conn: DatabaseConnection, date: str) -> list[Todo]:
         """Collect all Todos for Day of date."""
index 0070630605f3db45602f70d524196344bb69c7a4..d192631e55befd85dde6a0a97a914fefc891e143 100644 (file)
@@ -25,10 +25,11 @@ td, th, tr, table {
 {% endblock %}
 </style>
 <body>
 {% endblock %}
 </style>
 <body>
-<a href="processes">processes</a>
-<a href="conditions">conditions</a>
 <a href="day">today</a>
 <a href="calendar">calendar</a>
 <a href="day">today</a>
 <a href="calendar">calendar</a>
+<a href="conditions">conditions</a>
+<a href="processes">processes</a>
+<a href="todos">todos</a>
 <hr>
 {% block content %}
 {% endblock %}
 <hr>
 {% block content %}
 {% endblock %}
index a07645e6a38646f08d5d4b0b23e35fba90a80f49..8944c955688da6cc1021559645a36f0e34603938 100644 (file)
@@ -101,6 +101,13 @@ add: <input name="new_top_step" list="step_candidates" autocomplete="off" />
 </td>
 <tr>
 
 </td>
 <tr>
 
+<tr>
+<th>todos</th>
+<td>
+<a href="todos?process_id={{process.id_}}">{{n_todos}}</a><br />
+</td>
+<tr>
+
 </table>
 {{ macros.edit_buttons() }}
 </form>
 </table>
 {{ macros.edit_buttons() }}
 </form>
diff --git a/templates/todos.html b/templates/todos.html
new file mode 100644 (file)
index 0000000..54ac6f5
--- /dev/null
@@ -0,0 +1,36 @@
+{% extends '_base.html' %}
+{% import '_macros.html' as macros %}
+
+
+
+{% block content %}
+<h3>todos</h3>
+
+<form action="todos" method="GET">
+<input type="submit" value="filter" />
+process <input name="process_id" value="{{process_id or ''}}" list="processes" />
+from <input name="start" value="{{start}}" />
+to <input name="end" value="{{end}}" />
+in comment  <input name="comment_pattern" value="{{comment_pattern}}" />
+<input type="submit" value="OK" />
+</form>
+
+<table>
+<tr>
+<th><a href="?sort_by={% if sort_by == "doneness" %}-{% endif %}doneness">done</a></th>
+<th><a href="?sort_by={% if sort_by == "date" %}-{% endif %}date">date</a></th>
+<th><a href="?sort_by={% if sort_by == "process" %}-{% endif %}process">process</a></th>
+<th><a href="?sort_by={% if sort_by == "comment" %}-{% endif %}comment">comment</a></th>
+</tr>
+{% for todo in todos %}
+<tr>
+<td>[{% if todo.is_done %}x{% else %} {% endif %}]</td>
+<td><a href="{{todo.date}}">{{todo.date}}</a></td>
+<td><a href="process?id={{todo.process.id_}}">{{todo.process.title.newest}}</a></td>
+<td><a href="{{todo.comment}}">{{todo.comment}}</a></td>
+</tr>
+{% endfor %}
+</table>
+{{ macros.datalist_of_titles("processes", all_processes) }}
+{% endblock %}
+