Paginate the list of bills (#480)

We display 100 bills on each page.  We only show previous/next buttons (at
the top of the view) and the list of pages (at the bottom) if there are
more than one pages.

This uses built-in pagination support from Flask-SQLAlchemy:

  https://flask-sqlalchemy.palletsprojects.com/en/2.x/api/#flask_sqlalchemy.BaseQuery.paginate
  https://flask-sqlalchemy.palletsprojects.com/en/2.x/api/#flask_sqlalchemy.Pagination
This commit is contained in:
zorun 2020-02-20 09:43:00 +01:00 committed by GitHub
parent 72653c0d3a
commit 9378694034
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 3 deletions

View file

@ -272,6 +272,15 @@ footer .footer-left {
margin-top: 30px; margin-top: 30px;
} }
#previous-page {
margin-top: 30px;
}
#next-page {
margin-top: 30px;
padding-left: 2em;
}
/* Avoid text color flickering when it loose focus as the modal appears */ /* Avoid text color flickering when it loose focus as the modal appears */
.btn-primary[data-toggle="modal"] { .btn-primary[data-toggle="modal"] {
color: #fff; color: #fff;

View file

@ -97,13 +97,23 @@
</div> </div>
</div> </div>
{% if bills.count() > 0 %} {% if bills.pages > 1 %}
<span id="previous-page" class="float-left">
<a class="btn btn-outline-secondary float-left {% if bills.page == 1 %}disabled{% endif %}" href="{{ url_for('main.list_bills', page=bills.prev_num) }}">&laquo; {{ _("Newer bills") }}</a>
</span>
<span id="next-page" class="float-left">
<a class="btn btn-outline-secondary float-left {% if bills.page == bills.pages %}disabled{% endif %}" href="{{ url_for('main.list_bills', page=bills.next_num) }}">{{ _("Older bills") }} &raquo;</a>
</span>
{% endif %}
{% if bills.total > 0 %}
<div class="clearfix"></div> <div class="clearfix"></div>
<table id="bill_table" class="col table table-striped table-hover table-responsive-sm"> <table id="bill_table" class="col table table-striped table-hover table-responsive-sm">
<thead><tr><th>{{ _("When?") }}</th><th>{{ _("Who paid?") }}</<th><th>{{ _("For what?") }}</th><th>{{ _("For whom?") }}</th><th>{{ _("How much?") }}</th><th>{{ _("Actions") }}</th></tr></thead> <thead><tr><th>{{ _("When?") }}</th><th>{{ _("Who paid?") }}</<th><th>{{ _("For what?") }}</th><th>{{ _("For whom?") }}</th><th>{{ _("How much?") }}</th><th>{{ _("Actions") }}</th></tr></thead>
<tbody> <tbody>
{% for bill in bills %} {% for bill in bills.items %}
<tr owers="{{bill.owers|join(',','id')}}" payer="{{bill.payer.id}}"> <tr owers="{{bill.owers|join(',','id')}}" payer="{{bill.payer.id}}">
<td> <td>
<span data-toggle="tooltip" data-placement="top" <span data-toggle="tooltip" data-placement="top"
@ -133,6 +143,20 @@
</tbody> </tbody>
</table> </table>
{% if bills.pages > 1 %}
<ul class="pagination">
<li class="page-item {% if bills.page == 1 %}disabled{% endif %}"><a class="page-link" href="{{ url_for('main.list_bills', page=bills.prev_num) }}">&laquo; Newer bills</a></li>
{%- for page in bills.iter_pages() %}
{% if page %}
<li class="page-item {% if page == bills.page %}active{% endif %}"><a class="page-link" href="{{ url_for('main.list_bills', page=page) }}">{{ page }}</a></li>
{% else %}
<li class="page-item disabled"><span class="ellipsis page-link"></span></li>
{% endif %}
{%- endfor %}
<li class="page-item {% if bills.page == bills.pages %}disabled{% endif %}"><a class="page-link" href="{{ url_for('main.list_bills', page=bills.next_num) }}">Older bills &raquo;</a></li>
</ul>
{% endif %}
{% else %} {% else %}
<div class="py-3 d-flex justify-content-center empty-bill"> <div class="py-3 d-flex justify-content-center empty-bill">
<div class="card d-inline-flex p-2"> <div class="card d-inline-flex p-2">

View file

@ -586,7 +586,11 @@ def list_bills():
if "last_selected_payer" in session: if "last_selected_payer" in session:
bill_form.payer.data = session["last_selected_payer"] bill_form.payer.data = session["last_selected_payer"]
# Preload the "owers" relationship for all bills # Preload the "owers" relationship for all bills
bills = g.project.get_bills().options(orm.subqueryload(Bill.owers)) bills = (
g.project.get_bills()
.options(orm.subqueryload(Bill.owers))
.paginate(per_page=100, error_out=True)
)
return render_template( return render_template(
"list_bills.html", "list_bills.html",