From 3e7c5dccddde572d769c93ecb0643388249a7e44 Mon Sep 17 00:00:00 2001 From: Amy Sterling Date: Mon, 27 Apr 2026 11:53:58 -0400 Subject: [PATCH] Add limit/offset/order query params to table_view The table view was hardcoded to render the first 15 rows in default insertion order with no URL params for sorting or paging, which made it impossible to verify newly-written annotations (largest ids) or to browse a table past row 15 from the UI. Accept three optional query params on table_view, all backward compatible (a parameterless URL still returns the first 15 rows ascending): limit int default 15, clamped to [1, 500] offset int default 0, clamped to [0, inf) order str default "asc", "asc" or "desc" on Model.id Bad values fall back to the corresponding default rather than 500ing. The template gains "Showing rows N-M of TOTAL" plus prev / next / toggle-order links. --- annotationengine/templates/table.html | 17 +++++++++++++++ annotationengine/views.py | 31 +++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/annotationengine/templates/table.html b/annotationengine/templates/table.html index 68ce4e5..1e3d8c8 100644 --- a/annotationengine/templates/table.html +++ b/annotationengine/templates/table.html @@ -11,6 +11,23 @@

{% block title %}{{aligned_volume_name}} {{table_name}}{% endblock %}

Description: {{table_description}}

+{% set start_row = offset + 1 if table_size > 0 else 0 %} +{% set end_row = offset + limit if (offset + limit) < table_size else table_size %} +{% set prev_offset = offset - limit if offset > limit else 0 %} +{% set next_offset = offset + limit %} +{% set toggle_order = 'desc' if order == 'asc' else 'asc' %} +

Showing rows {{start_row}}–{{end_row}} of {{table_size}} ({{order}})

+

+ {% if offset > 0 %} + « Prev + {% endif %} + {% if next_offset < table_size %} + Next » + {% endif %} +  |  + Toggle order +

+ {{df_table|safe}} {% endblock %} \ No newline at end of file diff --git a/annotationengine/views.py b/annotationengine/views.py index 177d30d..e9505d3 100644 --- a/annotationengine/views.py +++ b/annotationengine/views.py @@ -1,6 +1,7 @@ from flask import ( render_template, current_app, + request, Blueprint, url_for, ) @@ -119,15 +120,37 @@ def table_view(aligned_volume_name, table_name): RefModel = db.database.cached_table(md["reference_table"]) Model = db.database._get_model_from_table_name(table_name) table_size = db.database.get_annotation_table_size(table_name) - query = db.database.cached_session.query(Model).limit(15) - top15_df = pd.read_sql(query.statement, db.database.engine) - top15_df = fix_wkb_columns(top15_df) + + try: + limit = min(max(int(request.args.get("limit", 15)), 1), 500) + except (TypeError, ValueError): + limit = 15 + try: + offset = max(int(request.args.get("offset", 0)), 0) + except (TypeError, ValueError): + offset = 0 + order = request.args.get("order", "asc").lower() + if order not in ("asc", "desc"): + order = "asc" + + order_col = Model.id.desc() if order == "desc" else Model.id.asc() + query = ( + db.database.cached_session.query(Model) + .order_by(order_col) + .offset(offset) + .limit(limit) + ) + rows_df = pd.read_sql(query.statement, db.database.engine) + rows_df = fix_wkb_columns(rows_df) return render_template( "table.html", aligned_volume_name=aligned_volume_name, table_name=table_name, table_size=table_size, - df_table=top15_df.to_html(escape=False), + df_table=rows_df.to_html(escape=False), table_description=md["description"], version=__version__, + limit=limit, + offset=offset, + order=order, )