feature: add filters and stats for requests

Signed-off-by: Leonidas Spyropoulos <artafinde@archlinux.org>
This commit is contained in:
Leonidas Spyropoulos 2022-07-12 15:12:38 +01:00
parent da5a646a73
commit b757e66997
3 changed files with 116 additions and 5 deletions

View file

@ -8,7 +8,12 @@ from aurweb import db, defaults, time, util
from aurweb.auth import creds, requires_auth
from aurweb.exceptions import handle_form_exceptions
from aurweb.models import PackageRequest
from aurweb.models.package_request import PENDING_ID, REJECTED_ID
from aurweb.models.package_request import (
ACCEPTED_ID,
CLOSED_ID,
PENDING_ID,
REJECTED_ID,
)
from aurweb.requests.util import get_pkgreq_by_id
from aurweb.scripts import notify
from aurweb.templates import make_context, render_template
@ -22,26 +27,59 @@ async def requests(
request: Request,
O: int = Query(default=defaults.O),
PP: int = Query(default=defaults.PP),
filter_pending: bool = False,
filter_closed: bool = False,
filter_accepted: bool = False,
filter_rejected: bool = False,
):
context = make_context(request, "Requests")
context["q"] = dict(request.query_params)
if len(dict(request.query_params)) == 0:
filter_pending = True
O, PP = util.sanitize_params(O, PP)
context["O"] = O
context["PP"] = PP
context["filter_pending"] = filter_pending
context["filter_closed"] = filter_closed
context["filter_accepted"] = filter_accepted
context["filter_rejected"] = filter_rejected
# A PackageRequest query
query = db.query(PackageRequest)
# Requests statistics
context["total_requests"] = query.count()
pending_count = 0 + query.filter(PackageRequest.Status == PENDING_ID).count()
context["pending_requests"] = pending_count
closed_count = 0 + query.filter(PackageRequest.Status == CLOSED_ID).count()
context["closed_requests"] = closed_count
accepted_count = 0 + query.filter(PackageRequest.Status == ACCEPTED_ID).count()
context["accepted_requests"] = accepted_count
rejected_count = 0 + query.filter(PackageRequest.Status == REJECTED_ID).count()
context["rejected_requests"] = rejected_count
# Apply filters
in_filters = []
if filter_pending:
in_filters.append(PENDING_ID)
if filter_closed:
in_filters.append(CLOSED_ID)
if filter_accepted:
in_filters.append(ACCEPTED_ID)
if filter_rejected:
in_filters.append(REJECTED_ID)
filtered = query.filter(PackageRequest.Status.in_(in_filters))
# If the request user is not elevated (TU or Dev), then
# filter PackageRequests which are owned by the request user.
if not request.user.is_elevated():
query = query.filter(PackageRequest.UsersID == request.user.ID)
filtered = filtered.filter(PackageRequest.UsersID == request.user.ID)
context["total"] = query.count()
context["total"] = filtered.count()
context["results"] = (
query.order_by(
filtered.order_by(
# Order primarily by the Status column being PENDING_ID,
# and secondarily by RequestTS; both in descending order.
case([(PackageRequest.Status == PENDING_ID, 1)], else_=0).desc(),

View file

@ -4,6 +4,65 @@
{% set plural = "%d package requests found." %}
{% block pageContent %}
<div class="box">
<h2>{{ "Requests" | tr }}</h2>
<h3>{{ "Total Statistics" | tr }}</h3>
<table class="no-width">
<tbody>
<tr>
<td>{{ "Total" | tr }}:</td>
<td>{{ total_requests }}</td>
</tr>
<tr>
<td>{{ "Pending" | tr }}:</td>
<td>{{ pending_requests }}</td>
</tr>
<tr>
<td>{{ "Closed" | tr }}:</td>
<td>{{ closed_requests }}</td>
</tr>
<tr>
<td>{{ "Accepted" | tr }}:</td>
<td>{{ accepted_requests }}</td>
</tr>
<tr>
<td>{{ "Rejected" | tr }}:</td>
<td>{{ rejected_requests }}</td>
</tr>
</tbody>
</table>
<h3>{{ "Filters" | tr }}</h3>
<div class="box filter-criteria">
<form id="todolist_filter" method="get" action="/requests">
<fieldset>
<legend>{{ "Select filter criteria" | tr }}</legend>
<div>
<label for="id_filter_pending" title="Pending">{{ "Pending" | tr }}</label>
<input type="checkbox" name="filter_pending" id="id_filter_pending" value="True" {{ "checked" if
filter_pending == true }}/>
</div>
<div>
<label for="id_filter_closed" title="Closed">{{ "Closed" | tr }}</label>
<input type="checkbox" name="filter_closed" id="id_filter_closed" value="True" {{ "checked" if
filter_closed == true }}/>
</div>
<div>
<label for="id_filter_accepted" title="Accepted">{{ "Accepted" | tr }}</label>
<input type="checkbox" name="filter_accepted" id="id_filter_accepted" value="True" {{ "checked" if
filter_accepted == true }}/>
</div>
<div>
<label for="id_filter_rejected" title="Rejected">{{ "Rejected" | tr }}</label>
<input type="checkbox" name="filter_rejected" id="id_filter_rejected" value="True" {{ "checked" if
filter_rejected == true }}/>
</div>
<div>
<button type='submit' class='button' name='submit' value='Filter'>{{ "Filter" | tr }}</button>
</div>
</fieldset>
</form>
</div>
</div>
<div id="pkglist-results" class="box">
{% if not total %}
<p>{{ "No requests matched your search criteria." | tr }}</p>

View file

@ -717,6 +717,10 @@ def test_requests(
"O": 0, # Page 1
"SeB": "nd",
"SB": "n",
"filter_pending": True,
"filter_closed": True,
"filter_accepted": True,
"filter_rejected": True,
},
cookies=cookies,
)
@ -732,7 +736,17 @@ def test_requests(
# Request page 2 of the requests page.
with client as request:
resp = request.get("/requests", params={"O": 50}, cookies=cookies) # Page 2
resp = request.get(
"/requests",
params={
"O": 50,
"filter_pending": True,
"filter_closed": True,
"filter_accepted": True,
"filter_rejected": True,
},
cookies=cookies,
) # Page 2
assert resp.status_code == int(HTTPStatus.OK)
assert " Previous" in resp.text