mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-26 17:24:23 -04:00
created new activity page
This commit is contained in:
@@ -3,6 +3,7 @@ from flask import Blueprint
|
|||||||
main = Blueprint("main", __name__)
|
main = Blueprint("main", __name__)
|
||||||
|
|
||||||
from app.main.views import ( # noqa isort:skip
|
from app.main.views import ( # noqa isort:skip
|
||||||
|
activity,
|
||||||
add_service,
|
add_service,
|
||||||
api_keys,
|
api_keys,
|
||||||
choose_account,
|
choose_account,
|
||||||
|
|||||||
68
app/main/views/activity.py
Normal file
68
app/main/views/activity.py
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
from flask import abort, render_template, request, session, url_for
|
||||||
|
from flask_login import current_user
|
||||||
|
from werkzeug.utils import redirect
|
||||||
|
|
||||||
|
from app import current_service, job_api_client
|
||||||
|
from app.formatters import get_time_left
|
||||||
|
from app.main import main
|
||||||
|
from app.utils.pagination import (
|
||||||
|
generate_next_dict,
|
||||||
|
generate_pagination_pages,
|
||||||
|
generate_previous_dict,
|
||||||
|
get_page_from_request,
|
||||||
|
)
|
||||||
|
from app.utils.user import user_has_permissions
|
||||||
|
|
||||||
|
|
||||||
|
@main.route("/activity/services/<uuid:service_id>")
|
||||||
|
@user_has_permissions()
|
||||||
|
def all_jobs_activity(service_id):
|
||||||
|
if session.get("invited_user_id"):
|
||||||
|
session.pop("invited_user_id", None)
|
||||||
|
session["service_id"] = service_id
|
||||||
|
|
||||||
|
if not current_user.has_permissions("view_activity"):
|
||||||
|
return redirect(url_for("main.choose_template", service_id=service_id))
|
||||||
|
service_data_retention_days = 7
|
||||||
|
page = get_page_from_request()
|
||||||
|
jobs = job_api_client.get_page_of_jobs(service_id, page=page)
|
||||||
|
all_jobs_dict = generate_job_dict(jobs)
|
||||||
|
prev_page, next_page, pagination = handle_pagination(jobs, service_id, page)
|
||||||
|
|
||||||
|
return render_template(
|
||||||
|
"views/activity/all-activity.html",
|
||||||
|
all_jobs_dict=all_jobs_dict,
|
||||||
|
service_data_retention_days=service_data_retention_days,
|
||||||
|
next_page=next_page,
|
||||||
|
prev_page=prev_page,
|
||||||
|
pagination=pagination
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def handle_pagination(jobs, service_id, page):
|
||||||
|
if page is None:
|
||||||
|
abort(404, "Invalid page argument ({}).".format(request.args.get("page")))
|
||||||
|
|
||||||
|
prev_page = generate_previous_dict("main.all_jobs_activity", service_id, page) if page > 1 else None
|
||||||
|
|
||||||
|
next_page = generate_next_dict("main.all_jobs_activity", service_id, page) if jobs["links"].get("next") else None
|
||||||
|
|
||||||
|
pagination = generate_pagination_pages(jobs["total"], jobs['page_size'], page)
|
||||||
|
|
||||||
|
return prev_page, next_page, pagination
|
||||||
|
|
||||||
|
|
||||||
|
def generate_job_dict(jobs):
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"job_id": job["id"],
|
||||||
|
"time_left": get_time_left(job["created_at"]),
|
||||||
|
"download_link": url_for(".view_job_csv", service_id=current_service.id, job_id=job["id"]),
|
||||||
|
"view_job_link": url_for(".view_job", service_id=current_service.id, job_id=job["id"]),
|
||||||
|
"created_at": job["created_at"],
|
||||||
|
"notification_count": job["notification_count"],
|
||||||
|
"created_by": job["created_by"],
|
||||||
|
"template_name": job["template_name"]
|
||||||
|
}
|
||||||
|
for job in jobs["data"]
|
||||||
|
]
|
||||||
@@ -153,6 +153,9 @@ class HeaderNavigation(Navigation):
|
|||||||
|
|
||||||
class MainNavigation(Navigation):
|
class MainNavigation(Navigation):
|
||||||
mapping = {
|
mapping = {
|
||||||
|
"activity": {
|
||||||
|
"all_jobs_activity",
|
||||||
|
},
|
||||||
"dashboard": {
|
"dashboard": {
|
||||||
"conversation",
|
"conversation",
|
||||||
"inbox",
|
"inbox",
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
{% if current_user.has_permissions() %}
|
{% if current_user.has_permissions() %}
|
||||||
{% if current_user.has_permissions('view_activity') %}
|
{% if current_user.has_permissions('view_activity') %}
|
||||||
<li class="usa-sidenav__item"><a class="{{ main_navigation.is_selected('dashboard') }}" href="{{ url_for('.service_dashboard', service_id=current_service.id) }}">Dashboard</a></li>
|
<li class="usa-sidenav__item"><a class="{{ main_navigation.is_selected('dashboard') }}" href="{{ url_for('.service_dashboard', service_id=current_service.id) }}">Dashboard</a></li>
|
||||||
|
<li class="usa-sidenav__item"><a class="{{ main_navigation.is_selected('activity') }}" href="{{ url_for('.all_jobs_activity', service_id=current_service.id) }}">Activity</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if not current_user.has_permissions('view_activity') %}
|
{% if not current_user.has_permissions('view_activity') %}
|
||||||
<li class="usa-sidenav__item"><a class="{{ casework_navigation.is_selected('sent-messages') }}" href="{{ url_for('.view_notifications', service_id=current_service.id, status='sending,delivered,failed') }}">Sent messages</a></li>
|
<li class="usa-sidenav__item"><a class="{{ casework_navigation.is_selected('sent-messages') }}" href="{{ url_for('.view_notifications', service_id=current_service.id, status='sending,delivered,failed') }}">Sent messages</a></li>
|
||||||
|
|||||||
156
app/templates/views/activity/all-activity.html
Normal file
156
app/templates/views/activity/all-activity.html
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
{% extends "withnav_template.html" %}
|
||||||
|
|
||||||
|
{% from "components/ajax-block.html" import ajax_block %}
|
||||||
|
{% from "components/previous-next-navigation.html" import previous_next_navigation %}
|
||||||
|
|
||||||
|
{% block service_page_title %}
|
||||||
|
All activity
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% set show_pagination %}
|
||||||
|
{% if prev_page or next_page %}
|
||||||
|
<nav aria-label="Pagination" class="usa-pagination">
|
||||||
|
<ul class="usa-pagination__list">
|
||||||
|
{% if prev_page %}
|
||||||
|
<li class="usa-pagination__item usa-pagination__arrow">
|
||||||
|
<a
|
||||||
|
href="{{prev_page['url']}}"
|
||||||
|
class="usa-pagination__link usa-pagination__previous-page"
|
||||||
|
aria-label="Previous page"
|
||||||
|
>
|
||||||
|
<img src="{{ url_for('static', filename='/img/usa-icons/navigate_before.svg') }}" alt="arrow">
|
||||||
|
<span class="usa-pagination__link-text">Previous</span></a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% if pagination %}
|
||||||
|
{% for page in pagination.pages %}
|
||||||
|
{% if page == pagination.current %}
|
||||||
|
<li class="usa-pagination__item usa-pagination__page-no">
|
||||||
|
<span class="usa-pagination__button usa-current" aria-label="Page {{ page }}" aria-current="true">
|
||||||
|
{{ page }}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="usa-pagination__item">
|
||||||
|
<a class="usa-pagination__button" href="?page={{ page }}">
|
||||||
|
{{ page }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% if page == 3 and pagination.last > 4 %}
|
||||||
|
<li class="usa-pagination__item usa-pagination__overflow" aria-label="ellipsis indicating non-visible pages">
|
||||||
|
<span>…</span>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if next_page %}
|
||||||
|
<li class="usa-pagination__item usa-pagination__arrow">
|
||||||
|
<a
|
||||||
|
href="{{ next_page['url'] }}"
|
||||||
|
class="usa-pagination__link usa-pagination__next-page"
|
||||||
|
aria-label="Next page"
|
||||||
|
>
|
||||||
|
<span class="usa-pagination__link-text">Next </span>
|
||||||
|
<img src="{{ url_for('static', filename='/img/usa-icons/navigate_next.svg') }}" alt="arrow">
|
||||||
|
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
{% endif %}
|
||||||
|
{% endset %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block maincolumn_content %}
|
||||||
|
|
||||||
|
<div class="dashboard margin-bottom-8">
|
||||||
|
<h1 class="usa-sr-only">All activity</h1>
|
||||||
|
{% if current_user.has_permissions('manage_templates') and not current_service.all_templates %}
|
||||||
|
<!-- {% include 'views/dashboard/write-first-messages.html' %} -->
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{{ ajax_block(partials, updates_url, 'upcoming') }}
|
||||||
|
|
||||||
|
<h2 class="font-body-2xl line-height-sans-2 margin-0">All activity</h2>
|
||||||
|
|
||||||
|
<h2 class="margin-top-4 margin-bottom-1">Sent jobs</h2>
|
||||||
|
<div class="usa-table-container--scrollable" tabindex="0">
|
||||||
|
<table class="usa-table usa-table--borderless job-table">
|
||||||
|
<thead class="table-field-headings">
|
||||||
|
<tr>
|
||||||
|
<th data-sortable scope="col" role="columnheader" class="table-field-heading-first">
|
||||||
|
<span>Job ID#</span>
|
||||||
|
</th>
|
||||||
|
<th data-sortable scope="col" role="columnheader" class="table-field-heading">
|
||||||
|
<span>Template</span>
|
||||||
|
</th>
|
||||||
|
<th data-sortable scope="col" role="columnheader" class="table-field-heading">
|
||||||
|
<span>Status</span>
|
||||||
|
</th>
|
||||||
|
<th data-sortable scope="col" role="columnheader" class="table-field-heading">
|
||||||
|
<span>Sender</span>
|
||||||
|
</th>
|
||||||
|
<th data-sortable scope="col" role="columnheader" class="table-field-heading">
|
||||||
|
<span>Reports</span>
|
||||||
|
</th>
|
||||||
|
<th data-sortable scope="col" role="columnheader" class="table-field-heading">
|
||||||
|
<span># of Recipients</span>
|
||||||
|
</th>
|
||||||
|
<th data-sortable scope="col" role="columnheader" class="table-field-heading">
|
||||||
|
<span>Message parts used</span>
|
||||||
|
</th>
|
||||||
|
<th data-sortable scope="col" role="columnheader" class="table-field-heading">
|
||||||
|
<span>Delivery rate</span>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% if all_jobs_dict %}
|
||||||
|
{% for job in all_jobs_dict %}
|
||||||
|
{% if job.job_id %}
|
||||||
|
<tr class="table-row" id="{{ job.job_id }}">
|
||||||
|
<td class="table-field file-name" data-sort-value="{{ job.job_id[-12:].rjust(12, '0') }}">
|
||||||
|
<a class="usa-link file-list-filename" href="{{ job.view_job_link }}">
|
||||||
|
{{ job.job_id[-12:] if job and job.job_id else 'Manually entered number' }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td class="table-field template">
|
||||||
|
{{ job.template_name }}
|
||||||
|
</td>
|
||||||
|
<td class="table-field time-sent">
|
||||||
|
{{ job.created_at | format_datetime_table }}
|
||||||
|
</td>
|
||||||
|
<td class="table-field sender">
|
||||||
|
{{ job.created_by.name }}
|
||||||
|
</td>
|
||||||
|
<td class="table-field report table-field-center-aligned">
|
||||||
|
{% if job.time_left != "Data no longer available" %}
|
||||||
|
<a class="usa-link file-list-filename" href="{{ job.download_link }}"><img src="{{ url_for('static', filename='img/material-icons/file_download.svg') }}" alt="File Download Icon"></a>
|
||||||
|
{% elif job %}
|
||||||
|
<span>{{ job.time_left }} n/a</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td class="table-field count-of-recipients">
|
||||||
|
{{ job.notification_count}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
<tr class="table-row">
|
||||||
|
<td class="table-empty-message" colspan="10">No batched job messages found  (messages are kept for {{ service_data_retention_days }} days).</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<p>
|
||||||
|
<b>Note:</b> Report data is only available for 7 days after your message has been sent
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{{show_pagination}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -29,3 +29,20 @@ def generate_previous_next_dict(view, service_id, page, title, url_args):
|
|||||||
"title": title,
|
"title": title,
|
||||||
"label": "page {}".format(page),
|
"label": "page {}".format(page),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def generate_pagination_pages(total_items, page_size, current_page):
|
||||||
|
total_pages = (total_items + page_size - 1) // page_size
|
||||||
|
pagination = {
|
||||||
|
'current': current_page,
|
||||||
|
'pages': [],
|
||||||
|
'last': total_pages
|
||||||
|
}
|
||||||
|
if total_pages <= 4:
|
||||||
|
pagination['pages'] = list(range(1, total_pages + 1))
|
||||||
|
else:
|
||||||
|
if current_page <= 3:
|
||||||
|
pagination['pages'] = [1, 2, 3, total_pages]
|
||||||
|
else:
|
||||||
|
pagination['pages'] = [1, current_page - 1, current_page, current_page + 1, total_pages]
|
||||||
|
return pagination
|
||||||
|
|||||||
Reference in New Issue
Block a user