Browse Source

add data table

Daniel Sheffield 1 year ago
parent
commit
fd6a295036
5 changed files with 57 additions and 21 deletions
  1. 6 0
      app/rest/data-item.tpl
  2. 4 1
      app/rest/filter-heading.tpl
  3. 1 1
      app/rest/filter-item.tpl
  4. 14 9
      app/rest/filter.tpl
  5. 32 10
      app/rest/pyapi.py

+ 6 - 0
app/rest/data-item.tpl

@@ -0,0 +1,6 @@
+<tr>
+    <td>{{ product }}</td>
+    <td>{{ category }}</td>
+    <td>{{ group }}</td>
+    <td></td>
+</tr>

+ 4 - 1
app/rest/filter-heading.tpl

@@ -1 +1,4 @@
-<th>{{fname.title()}}</th>
+<th>
+    <span> {{fname.title()}} </span>
+    <button style="position: absolute; right: 0.2em" type="submit" {{ "hidden" if not first else "" }}>Apply</button>
+</th>

+ 1 - 1
app/rest/filter-item.tpl

@@ -3,7 +3,7 @@
   type="text"
   id={{fname}}"
   name="{{fname}}"
-  size="{{size}}"
+  size="{{10 if fname == 'unit' else size}}"
   pattern="((.*\\|)*(.*))?(!(.*\\|)*(.*))?"
   title="Must be of the form include!exclude where include and exclude are | separated lists"
   value="{{fvalue}}" />

+ 14 - 9
app/rest/filter.tpl

@@ -1,11 +1,16 @@
-<form id="filter" style="display: inline-block">
-    <table>
-        <tr>
-{{! ''.join( header ) }}
-        </tr>
-        <tr>
-{{! ''.join( items ) }}
-        </tr>
+<form id="filter" style="display: inline-block"  method="{{ method }}" action="{{ action }}">
+    <table class="pure-table pure-table-bordered pure-table-striped">
+        <thead style="position: sticky; top: 0">
+            <tr>
+{{! ''.join( header )}}
+            </tr>
+            <tr>
+{{! ''.join( items )}}
+            </tr>
+        </thead>
+        <tbody>       
+{{! ''.join( data )}}
+            </details>
+        </tbody>
     </table>
-    <button type="submit" method="{{ method }}" action="{{ action }}">Apply Filter</button>
 </form>

+ 32 - 10
app/rest/pyapi.py

@@ -50,7 +50,7 @@ from io import StringIO
 def get_filter(query: DictProperty, allow: Iterable[str] = None):
     return {
         k: get_include_exclude(
-            query[k] if k in query else None
+            (query[k] or 'kg' if k == 'unit' else query[k]) if k in query else None
         ) for k in sorted(set(query.keys()) | set(allow)) if allow is None or k in allow
     }
 
@@ -68,18 +68,40 @@ def get_query(**params):
 def normalize_query(query: DictProperty, allow: Iterable[str] = None):
     return get_query(**get_filter(query, allow=allow))
 
-def get_form(action, method, **data):
+def get_form(action, method, filter_data, data):
+    keys = sorted(filter_data, key=lambda x: {
+        'product': 0,
+        'category': 1,
+        'group': 2,
+        'unit': 3
+    }[x])
+    data = data.groupby([
+        k for k in keys if k != 'unit'
+    ]).size().reset_index()[[
+        k for k in keys if k != 'unit'
+    ]]
     return template(
         'app/rest/filter.tpl',
         action=action,
         method=method,
-        header=[ template('app/rest/filter-heading', fname=k) for k in sorted(data) ],
+        header=[ template(
+            'app/rest/filter-heading',
+            fname=k,
+            first=(idx == 0),
+        ) for idx, k in enumerate(keys) ],
         items=[ template(
-                'app/rest/filter-item.tpl',
-                fname=k,
-                fvalue=get_query_param(*data[k]),
-                size=36,
-            ) for k in sorted(data) ]
+            'app/rest/filter-item.tpl',
+            fname=k,
+            fvalue=get_query_param(*filter_data[k]),
+            size=36,
+        ) for k in keys ],
+        data=[ template(
+            'app/rest/data-item.tpl',
+            product=row['product'],
+            category=row['category'],
+            group=row['group'],
+            size=36,
+        ) for _, row in data.iterrows() ]
     )
 
 
@@ -109,7 +131,7 @@ def trend():
             plt.savefig(f, format='svg')
     finally:
         conn.commit()
-
+    
     return f"""
 <!DOCTYPE html>
 <html>
@@ -121,7 +143,7 @@ def trend():
         <link rel="stylesheet" href="https://shandan.one/css/responsive-visibility-collapse.css"/>
     </head>
     <body align="center">
-{get_form(path, 'get', **get_filter(request.query, allow=PARAMS))}
+{get_form(path, 'get', get_filter(request.query, allow=PARAMS), data)}
 {f.getvalue()}
     </body>
 </html>