diff --git a/app/main/__init__.py b/app/main/__init__.py index 8626582f2..2375c8e58 100644 --- a/app/main/__init__.py +++ b/app/main/__init__.py @@ -3,6 +3,7 @@ from flask import Blueprint main = Blueprint("main", __name__) from app.main.views import ( # noqa isort:skip + activity, add_service, api_keys, choose_account, diff --git a/app/main/views/activity.py b/app/main/views/activity.py new file mode 100644 index 000000000..f8e0f8dba --- /dev/null +++ b/app/main/views/activity.py @@ -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/") +@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"] + ] diff --git a/app/navigation.py b/app/navigation.py index 3c79598cc..3ce3b6e62 100644 --- a/app/navigation.py +++ b/app/navigation.py @@ -153,6 +153,9 @@ class HeaderNavigation(Navigation): class MainNavigation(Navigation): mapping = { + "activity": { + "all_jobs_activity", + }, "dashboard": { "conversation", "inbox", diff --git a/app/templates/new/components/main_nav.html b/app/templates/new/components/main_nav.html index a3b02823e..d3ee0fd08 100644 --- a/app/templates/new/components/main_nav.html +++ b/app/templates/new/components/main_nav.html @@ -8,6 +8,7 @@ {% if current_user.has_permissions() %} {% if current_user.has_permissions('view_activity') %}
  • Dashboard
  • +
  • Activity
  • {% endif %} {% if not current_user.has_permissions('view_activity') %}
  • Sent messages
  • diff --git a/app/templates/views/activity/all-activity.html b/app/templates/views/activity/all-activity.html new file mode 100644 index 000000000..8a48b6050 --- /dev/null +++ b/app/templates/views/activity/all-activity.html @@ -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 %} + + {% endif %} +{% endset %} + + +{% block maincolumn_content %} + +
    +

    All activity

    + {% if current_user.has_permissions('manage_templates') and not current_service.all_templates %} + + {% endif %} + + {{ ajax_block(partials, updates_url, 'upcoming') }} + +

    All activity

    + +

    Sent jobs

    +
    + + + + + + + + + + + + + + + {% if all_jobs_dict %} + {% for job in all_jobs_dict %} + {% if job.job_id %} + + + + + + + + + {% endif %} + {% endfor %} + {% else %} + + + + {% endif %} + +
    + Job ID# + + Template + + Status + + Sender + + Reports + + # of Recipients + + Message parts used + + Delivery rate +
    + + {{ job.job_id[-12:] if job and job.job_id else 'Manually entered number' }} + + + {{ job.template_name }} + + {{ job.created_at | format_datetime_table }} + + {{ job.created_by.name }} + + {% if job.time_left != "Data no longer available" %} + File Download Icon + {% elif job %} + {{ job.time_left }} n/a + {% endif %} + + {{ job.notification_count}} +
    No batched job messages found  (messages are kept for {{ service_data_retention_days }} days).
    +

    + Note: Report data is only available for 7 days after your message has been sent +

    +
    + {{show_pagination}} +
    + +{% endblock %} diff --git a/app/utils/pagination.py b/app/utils/pagination.py index a9ed28d3c..15858d73a 100644 --- a/app/utils/pagination.py +++ b/app/utils/pagination.py @@ -29,3 +29,20 @@ def generate_previous_next_dict(view, service_id, page, title, url_args): "title": title, "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