home · contact · privacy
Add text-based search/filter for Conditions and Processes.
authorChristian Heller <c.heller@plomlompom.de>
Tue, 21 May 2024 02:29:54 +0000 (04:29 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Tue, 21 May 2024 02:29:54 +0000 (04:29 +0200)
plomtask/conditions.py
plomtask/db.py
plomtask/http.py
plomtask/processes.py
templates/conditions.html
templates/processes.html

index 8ab4282080b4898f8d08da4e443f8ac3d64131ee..d2559272cd876c5b071b59437998e3356409cd07 100644 (file)
@@ -12,6 +12,7 @@ class Condition(BaseModel[int]):
     table_name = 'conditions'
     to_save = ['is_active']
     to_save_versioned = ['title', 'description']
+    to_search = ['title.newest', 'description.newest']
 
     def __init__(self, id_: int | None, is_active: bool = False) -> None:
         super().__init__(id_)
index d2791b1bdf43da11d389b805fffd6b2791ae168d..548381e72e5c473047d7b90cb7f55ea1627b0ca6 100644 (file)
@@ -185,6 +185,17 @@ class DatabaseConnection:
         return list(self.exec(f'SELECT * FROM {table_name} WHERE {key} = ?',
                               (target,)))
 
+    # def column_where_pattern(self,
+    #                          table_name: str,
+    #                          column: str,
+    #                          pattern: str,
+    #                          keys: list[str]) -> list[Any]:
+    #     """Return column of rows where one of keys matches pattern."""
+    #     targets = tuple([f'%{pattern}%'] * len(keys))
+    #     haystack = ' OR '.join([f'{k} LIKE ?' for k in keys])
+    #     sql = f'SELECT {column} FROM {table_name} WHERE {haystack}'
+    #     return [row[0] for row in self.exec(sql, targets)]
+
     def column_where(self, table_name: str, column: str, key: str,
                      target: int | str) -> list[Any]:
         """Return column of table where key == target."""
@@ -220,6 +231,7 @@ class BaseModel(Generic[BaseModelId]):
     to_save_relations: list[tuple[str, str, str]] = []
     id_: None | BaseModelId
     cache_: dict[BaseModelId, Self]
+    to_search: list[str] = []
 
     def __init__(self, id_: BaseModelId | None) -> None:
         if isinstance(id_, int) and id_ < 1:
@@ -342,6 +354,26 @@ class BaseModel(Generic[BaseModelId]):
                 items[item.id_] = item
         return list(items.values())
 
+    @classmethod
+    def matching(cls: type[BaseModelInstance], db_conn: DatabaseConnection,
+                 pattern: str) -> list[BaseModelInstance]:
+        """Return all objects whose .to_search match pattern."""
+        items = cls.all(db_conn)
+        if pattern:
+            filtered = []
+            for item in items:
+                for attr_name in cls.to_search:
+                    toks = attr_name.split('.')
+                    parent = item
+                    for tok in toks:
+                        attr = getattr(parent, tok)
+                        parent = attr
+                    if pattern in attr:
+                        filtered += [item]
+                        break
+            return filtered
+        return items
+
     def save(self, db_conn: DatabaseConnection) -> None:
         """Write self to DB and cache and ensure .id_.
 
index 41ce5d6a5da6738fe9eae35b5abff6cc2fd4a243..484147239ae8f3ef91d2ece69458d4b94c27e596 100644 (file)
@@ -154,7 +154,8 @@ class TaskHandler(BaseHTTPRequestHandler):
 
     def do_GET_conditions(self) -> dict[str, object]:
         """Show all Conditions."""
-        conditions = Condition.all(self.conn)
+        pattern = self.params.get_str('pattern')
+        conditions = Condition.matching(self.conn, pattern)
         sort_by = self.params.get_str('sort_by')
         if sort_by == 'is_active':
             conditions.sort(key=lambda c: c.is_active)
@@ -164,7 +165,9 @@ class TaskHandler(BaseHTTPRequestHandler):
             conditions.sort(key=lambda c: c.title.newest, reverse=True)
         else:
             conditions.sort(key=lambda c: c.title.newest)
-        return {'conditions': conditions, 'sort_by': sort_by}
+        return {'conditions': conditions,
+                'sort_by': sort_by,
+                'pattern': pattern}
 
     def do_GET_condition(self) -> dict[str, object]:
         """Show Condition of ?id=."""
@@ -213,7 +216,8 @@ class TaskHandler(BaseHTTPRequestHandler):
 
     def do_GET_processes(self) -> dict[str, object]:
         """Show all Processes."""
-        processes = Process.all(self.conn)
+        pattern = self.params.get_str('pattern')
+        processes = Process.matching(self.conn, pattern)
         sort_by = self.params.get_str('sort_by')
         if sort_by == 'steps':
             processes.sort(key=lambda c: len(c.explicit_steps))
@@ -223,7 +227,7 @@ class TaskHandler(BaseHTTPRequestHandler):
             processes.sort(key=lambda c: c.title.newest, reverse=True)
         else:
             processes.sort(key=lambda c: c.title.newest)
-        return {'processes': processes, 'sort_by': sort_by}
+        return {'processes': processes, 'sort_by': sort_by, 'pattern': pattern}
 
     def do_POST(self) -> None:
         """Handle any POST request."""
index c23c6de7d89995ff14d909ffe731b9952db06592..684dec81dde47e6bd409ffaa52edc3a251246e8d 100644 (file)
@@ -30,6 +30,7 @@ class Process(BaseModel[int], ConditionsRelations):
                          ('process_blockers', 'process', 'blockers'),
                          ('process_enables', 'process', 'enables'),
                          ('process_disables', 'process', 'disables')]
+    to_search = ['title.newest', 'description.newest']
 
     def __init__(self, id_: int | None, calendarize: bool = False) -> None:
         BaseModel.__init__(self, id_)
index e8e9fed7fcf5a46b3b39b04ca134a54e94d29f05..5990711b059f1dc94fabcdc17c1a35bf25814f94 100644 (file)
@@ -3,6 +3,11 @@
 {% block content %}
 <h3>conditions</h3>
 
+<form action="conditions" method="GET">
+<input type="submit" value="filter" />
+<input name="pattern" value="{{pattern}}" />
+</form>
+
 <table>
 <tr>
 <th><a href="?sort_by={% if sort_by == "is_active" %}-{% endif %}is_active">active</a></th>
index 977ac405ac89c57fd66d65bf8dd71d7c78cbfb67..9b282bf7def6558368961b9236810acd96e342f0 100644 (file)
@@ -3,6 +3,11 @@
 {% block content %}
 <h3>processes</h3>
 
+<form action="processes" method="GET">
+<input type="submit" value="filter" />
+<input name="pattern" value="{{pattern}}" />
+</form>
+
 <table>
 <tr>
 <th><a href="?sort_by={% if sort_by == "steps" %}-{% endif %}steps">steps</a></th>