From 1242ac5ca3d24f198375234a3888b143e417c925 Mon Sep 17 00:00:00 2001 From: Chris Lawton <31627284+chris-lawton@users.noreply.github.com> Date: Tue, 5 Nov 2019 11:03:22 +0000 Subject: [PATCH] Feature/gh 1645 project page (#1656) * rename payment block for reusability and update header styles * add styles for reporting table * add pagination to past reports --- .../includes/payment_requests.html | 122 ++++++------- .../includes/report_line.html | 56 +++--- .../includes/reports.html | 162 ++++++++++-------- .../application_projects/project_detail.html | 1 + .../apply/past-reports-pagination.js | 27 +++ .../{_payment-block.scss => _data-block.scss} | 136 +++++++++++---- opentech/static_src/src/sass/apply/main.scss | 2 +- 7 files changed, 316 insertions(+), 190 deletions(-) create mode 100644 opentech/static_src/src/javascript/apply/past-reports-pagination.js rename opentech/static_src/src/sass/apply/components/{_payment-block.scss => _data-block.scss} (55%) diff --git a/opentech/apply/projects/templates/application_projects/includes/payment_requests.html b/opentech/apply/projects/templates/application_projects/includes/payment_requests.html index 940cd498a..565b75271 100644 --- a/opentech/apply/projects/templates/application_projects/includes/payment_requests.html +++ b/opentech/apply/projects/templates/application_projects/includes/payment_requests.html @@ -1,81 +1,81 @@ {% load payment_request_tools humanize %} -<div id="payment-requests" class="payment-block"> - <div class="payment-block__header"> - <p class="payment-block__title">Payment Requests</p> - <a class="payment-block__button button button--primary" +<div id="payment-requests" class="data-block"> + <div class="data-block__header"> + <p class="data-block__title">Payment Requests</p> + <a class="data-block__button button button--primary" href="{% url "apply:projects:request" pk=object.pk %}"> Add Request </a> </div> - - <table class="payment-block__table"> - <thead> - <tr> - <th class="payment-block__table-amount">Amount</th> - <th class="payment-block__table-status">Status</th> - <th class="payment-block__table-date">From</th> - <th class="payment-block__table-date">To</th> - <th class="payment-block__table-update"></th> - </tr> - </thead> - <tbody> - {% for payment_request in object.payment_requests.not_rejected %} - <tr> - <td><span class="payment-block__mobile-label">Amount: </span>${{ payment_request.value|intcomma }}</td> - <td><span class="payment-block__mobile-label">Status: </span>{{ payment_request.get_status_display }}</td> - <td><span class="payment-block__mobile-label">From: </span>{{ payment_request.date_from.date }}</td> - <td><span class="payment-block__mobile-label">To: </span>{{ payment_request.date_to.date }}</td> - <td> - <a href="{{ payment_request.get_absolute_url }}">View</a> - {% can_edit payment_request user as user_can_edit_request %} - {% if user_can_edit_request %} - <a href="{% url "apply:projects:payments:edit" pk=payment_request.pk %}"> - Edit - </a> - {% endif %} - - {% can_delete payment_request user as user_can_delete_request %} - {% if user_can_delete_request %} - <a href="{% url 'apply:projects:payments:delete' pk=payment_request.pk %}"> - Delete - </a> - {% endif %} - </td> - </tr> - {% empty %} - <tr> - <td colspan="5">No active Payment Requests.</td> - </tr> - {% endfor %} - </tbody> - </table> - - {% if object.payment_requests.rejected %} - <p class="payment-block__rejected"> - <a class="payment-block__rejected-link js-payment-block-rejected-link" href="#">Show rejected</a> - </p> - - <table class="payment-block__table is-hidden js-payment-block-rejected-table"> + <div class="data-block__body"> + <table class="data-block__table"> <thead> <tr> - <th class="payment-block__table-amount">Amount</th> - <th class="payment-block__table-status">Status</th> - <th class="payment-block__table-view"></th> + <th class="data-block__table-amount">Amount</th> + <th class="data-block__table-status">Status</th> + <th class="data-block__table-date">From</th> + <th class="data-block__table-date">To</th> + <th class="data-block__table-update"></th> </tr> </thead> <tbody> - {% for payment_request in object.payment_requests.rejected %} + {% for payment_request in object.payment_requests.not_rejected %} + <tr> + <td><span class="data-block__mobile-label">Amount: </span>${{ payment_request.value|intcomma }}</td> + <td><span class="data-block__mobile-label">Status: </span>{{ payment_request.get_status_display }}</td> + <td><span class="data-block__mobile-label">From: </span>{{ payment_request.date_from.date }}</td> + <td><span class="data-block__mobile-label">To: </span>{{ payment_request.date_to.date }}</td> + <td> + <a class="data-block__action-link" href="{{ payment_request.get_absolute_url }}">View</a> + {% can_edit payment_request user as user_can_edit_request %} + {% if user_can_edit_request %} + <a class="data-block__action-link" href="{% url "apply:projects:payments:edit" pk=payment_request.pk %}"> + Edit + </a> + {% endif %} + + {% can_delete payment_request user as user_can_delete_request %} + {% if user_can_delete_request %} + <a class="data-block__action-link" href="{% url 'apply:projects:payments:delete' pk=payment_request.pk %}"> + Delete + </a> + {% endif %} + </td> + </tr> + {% empty %} <tr> - <td><span class="payment-block__mobile-label">Amount: </span>${{ payment_request.value }}</td> - <td><span class="payment-block__mobile-label">Status: </span>{{ payment_request.get_status_display }}</td> - <td><a href="{{ payment_request.get_absolute_url }}">View</a></td> + <td colspan="5">No active Payment Requests.</td> </tr> {% endfor %} </tbody> </table> - {% endif %} + {% if object.payment_requests.rejected %} + <p class="data-block__rejected"> + <a class="data-block__rejected-link js-payment-block-rejected-link" href="#">Show rejected</a> + </p> + + <table class="data-block__table is-hidden js-payment-block-rejected-table"> + <thead> + <tr> + <th class="data-block__table-amount">Amount</th> + <th class="data-block__table-status">Status</th> + <th class="data-block__table-view"></th> + </tr> + </thead> + <tbody> + {% for payment_request in object.payment_requests.rejected %} + <tr> + <td><span class="data-block__mobile-label">Amount: </span>${{ payment_request.value }}</td> + <td><span class="data-block__mobile-label">Status: </span>{{ payment_request.get_status_display }}</td> + <td><a href="{{ payment_request.get_absolute_url }}">View</a></td> + </tr> + {% endfor %} + </tbody> + </table> + {% endif %} + </div> </div> {% for form in change_payment_request_status_forms %} diff --git a/opentech/apply/projects/templates/application_projects/includes/report_line.html b/opentech/apply/projects/templates/application_projects/includes/report_line.html index ef6f6d9c4..c2e367a18 100644 --- a/opentech/apply/projects/templates/application_projects/includes/report_line.html +++ b/opentech/apply/projects/templates/application_projects/includes/report_line.html @@ -1,25 +1,31 @@ -<p> - {% if current %} - The {% if report.can_submit %}current{% else %}next{% endif %} reporting - {% else %} - A report is due for the - {% endif %} - period is {{ report.start_date }} to {{ report.end_date }} - {% if report.is_very_late %} - ( ! ) - {% endif %} - {% if report.can_submit %} - <a - class="payment-block__button button button--primary" - href="{% url "apply:projects:reports:edit" pk=report.pk %}" - > - {% if report.draft %}Continue Editing{% else %}Add Report{% endif %} - </a> - {% endif %} - {% if request.user.is_apply_staff and report.can_submit %} - <form action="{% url "apply:projects:reports:skip" pk=report.pk %}" method="post"> - {% csrf_token %} - <input type="submit" value="Skip" class="btn"></input> - </form> - {% endif %} -</p> +<li class="data-block__list-item"> + <div class="data-block__info"> + {% if current %} + The {% if report.can_submit %}current{% else %}next{% endif %} reporting period is + {% else %} + A report is due for the period + {% endif %} + <b>{{ report.start_date }}</b> to <b>{{ report.end_date }}</b> + {% if report.is_very_late %} + <svg class="icon data-block__icon"><use xlink:href="#exclamation-point"></use></svg> + {% endif %} + </div> + + <div class="data-block__links"> + {% if report.can_submit %} + <a + class="data-block__button button button--primary" + href="{% url "apply:projects:reports:edit" pk=report.pk %}" + > + {% if report.draft %}Continue Editing{% else %}Add Report{% endif %} + </a> + {% endif %} + + {% if request.user.is_apply_staff and report.can_submit %} + <form action="{% url "apply:projects:reports:skip" pk=report.pk %}" method="post"> + {% csrf_token %} + <input type="submit" value="Skip" class="btn data-block__action-link"></input> + </form> + {% endif %} + </div> +</li> diff --git a/opentech/apply/projects/templates/application_projects/includes/reports.html b/opentech/apply/projects/templates/application_projects/includes/reports.html index 0fd52c8dc..bec906017 100644 --- a/opentech/apply/projects/templates/application_projects/includes/reports.html +++ b/opentech/apply/projects/templates/application_projects/includes/reports.html @@ -1,76 +1,96 @@ -<div id="payment-requests" class="payment-block"> - <div class="payment-block__header"> - <p class="payment-block__title">Reporting</p> - </div> - <div> - <h6>Report frequency</h6> - <p> - {{ object.report_config.get_frequency_display }} - </p> - {% if request.user.is_apply_staff %} - <p> - <div class="modal" id="change-frequency"> - {{ object.report_config.last_report.serialize|json_script:"lastReportData" }} - <h4 class="modal__header-bar">Change reporting frequency</h4> - <p>Schedule reports every:</p> - {% include 'funds/includes/delegated_form_base.html' with form=update_frequency_form value='Continue'%} +<div class="wrapper wrapper--outer-space-large"> + <div class="data-block"> + <div class="data-block__header"> + <p class="data-block__title">Reporting</p> + </div> + <div class="data-block__body"> + <div> + <h6>Report frequency</h6> + <p> + {{ object.report_config.get_frequency_display }} + </p> + {% if request.user.is_apply_staff %} + <p> + <div class="modal" id="change-frequency"> + {{ object.report_config.last_report.serialize|json_script:"lastReportData" }} + <h4 class="modal__header-bar">Change reporting frequency</h4> + <p>Schedule reports every:</p> + {% include 'funds/includes/delegated_form_base.html' with form=update_frequency_form value='Continue'%} + </div> + <a data-fancybox + data-src="#change-frequency" + href="#"> + Change + </a> + </p> + {% endif %} </div> - <a data-fancybox - data-src="#change-frequency" - href="#"> - Change - </a> - </p> - {% endif %} + <ul class="data-block__list"> + {% for report in object.report_config.past_due_reports %} + {% include "application_projects/includes/report_line.html" with report=report %} + {% endfor %} + {% with next_report=object.report_config.current_due_report %} + {% include "application_projects/includes/report_line.html" with report=next_report current=True %} + {% endwith %} + </ul> + </div> </div> - <div> - {% for report in object.report_config.past_due_reports %} - {% include "application_projects/includes/report_line.html" with report=report %} - {% endfor %} - {% with next_report=object.report_config.current_due_report %} - {% include "application_projects/includes/report_line.html" with report=next_report current=True %} - {% endwith %} +</div> + + +<div class="wrapper wrapper--outer-space-large"> + <div class="data-block"> + <div class="data-block__header"> + <p class="data-block__title">Past reports</p> + </div> + <div class="data-block__body"> + <table class="data-block__table js-past-reports-table"> + <thead> + <tr> + <th class="data-block__table-date">Period End</th> + <th class="data-block__table-date">Submitted</th> + <th class="data-block__table-date">Privacy</th> + <th class="data-block__table-update"></th> + </tr> + </thead> + <tbody> + {% for report in object.reports.done %} + <tr {% if forloop.counter > 8 %}class="is-hidden"{% endif %}> + <td> + <span class="data-block__mobile-label">Period End: </span>{{ report.end_date }} + </td> + <td> + <span class="data-block__mobile-label">Submitted: </span>{{ report.submitted_date|default:"Skipped" }} + </td> + <td> + <span class="data-block__mobile-label">Privacy: </span>{% if report.public %}Public{% else %}Private{% endif %} + </td> + <td class="data-block__links"> + <a class="data-block__action-link" href="{% url "apply:projects:reports:detail" pk=report.pk %}">View</a> + {% if request.user.is_apply_staff %} + <a class="data-block__action-link" href="{% url "apply:projects:reports:edit" pk=report.pk %}">Edit</a> + {% if report.skipped %} + <form action="{% url "apply:projects:reports:skip" pk=report.pk %}" method="post"> + {% csrf_token %} + <input type="submit" value="Unskip" class="btn data-block__action-link"></input> + </form> + {% endif %} + {% endif %} + </td> + </tr> + {% empty %} + <tr> + <td colspan="4">No reports submitted</td> + </tr> + {% endfor %} + </tbody> + </table> + {% if object.reports.done.count > 8 %} + <p class="data-block__pagination"> + <a class="data-block__pagination-link js-data-block-pagination" href="#">Show more</a> + </p> + {% endif %} + </div> </div> - <table class="payment-block__table"> - <thead> - <tr> - <th class="payment-block__table-date">Period End</th> - <th class="payment-block__table-date">Submitted</th> - <th class="payment-block__table-date">Privacy</th> - <th class="payment-block__table-update"></th> - </tr> - </thead> - <tbody> - {% for report in object.reports.done %} - <tr> - <td> - <span class="payment-block__mobile-label">Period End: </span>{{ report.end_date }} - </td> - <td> - <span class="payment-block__mobile-label">Submitted: </span>{{ report.submitted_date|default:"Skipped" }} - </td> - <td> - <span class="payment-block__mobile-label">Privacy: </span>{% if report.public %}Public{% else %}Private{% endif %} - </td> - <td> - {% if request.user.is_apply_staff %} - <a href="{% url "apply:projects:reports:edit" pk=report.pk %}">Edit</a> - {% if report.skipped %} - <form action="{% url "apply:projects:reports:skip" pk=report.pk %}" method="post"> - {% csrf_token %} - <input type="submit" value="Unskip" class="btn"></input> - </form> - {% endif %} - {% endif %} - <a href="{% url "apply:projects:reports:detail" pk=report.pk %}">view</a> - </td> - </tr> - {% empty %} - <tr> - <td colspan="4">No reports submitted</td> - </tr> - {% endfor %} - </tbody> - </table> </div> diff --git a/opentech/apply/projects/templates/application_projects/project_detail.html b/opentech/apply/projects/templates/application_projects/project_detail.html index df19d07d1..2c8fd1119 100644 --- a/opentech/apply/projects/templates/application_projects/project_detail.html +++ b/opentech/apply/projects/templates/application_projects/project_detail.html @@ -269,5 +269,6 @@ <script src="{% static 'js/apply/toggle-payment-block.js' %}"></script> <script src="{% static 'js/apply/toggle-proposal-info.js' %}"></script> <script src="{% static 'js/apply/file-uploads.js' %}"></script> + <script src="{% static 'js/apply/past-reports-pagination.js' %}"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/fancybox/3.4.1/jquery.fancybox.min.js"></script> {% endblock %} diff --git a/opentech/static_src/src/javascript/apply/past-reports-pagination.js b/opentech/static_src/src/javascript/apply/past-reports-pagination.js new file mode 100644 index 000000000..ef1a1b41a --- /dev/null +++ b/opentech/static_src/src/javascript/apply/past-reports-pagination.js @@ -0,0 +1,27 @@ +(function ($) { + + 'use strict'; + + function pastReportsPagination() { + $('.js-data-block-pagination').click((e) => { + e.preventDefault(); + showNextTen(); + }); + } + + function showNextTen() { + const [...nextTen] = $('.js-past-reports-table tr.is-hidden').slice(0, 10); + nextTen.forEach(item => item.classList.remove('is-hidden')); + checkRemaining(); + } + + function checkRemaining() { + const [...remaining] = $('.js-past-reports-table tr.is-hidden'); + if (remaining.length === 0) { + $('.js-data-block-pagination').addClass('is-hidden'); + } + } + + pastReportsPagination(); + +})(jQuery); diff --git a/opentech/static_src/src/sass/apply/components/_payment-block.scss b/opentech/static_src/src/sass/apply/components/_data-block.scss similarity index 55% rename from opentech/static_src/src/sass/apply/components/_payment-block.scss rename to opentech/static_src/src/sass/apply/components/_data-block.scss index b6f48c039..27aee5a96 100644 --- a/opentech/static_src/src/sass/apply/components/_payment-block.scss +++ b/opentech/static_src/src/sass/apply/components/_data-block.scss @@ -1,29 +1,33 @@ -.payment-block { - border: 1px solid $color--mid-grey; - padding: 1rem; +.data-block { + $root: &; margin-bottom: 1rem; - @include media-query(mob-landscape) { - padding: 2rem; - } - &__header { - margin-bottom: 1rem; - - @include media-query(tablet-portrait) { - margin-bottom: 1.5rem; - } + padding: 1rem; + background-color: $color--primary; @include media-query(mob-landscape) { + padding: 1rem 2rem; display: flex; justify-content: space-between; align-items: center; } } + &__body { + border: 1px solid $color--mid-grey; + border-top: 0; + padding: 1rem; + + @include media-query(mob-landscape) { + padding: 2rem; + } + } + &__title { font-size: map-get($font-sizes, delta); margin: 0 0 1rem; + color: $color--white; @include media-query(mob-landscape) { margin: 0; @@ -32,6 +36,24 @@ &__button { padding: .7rem 1.2rem; + + #{$root}__header & { + background-color: $color--white; + color: $color--primary; + + &:hover, + &:focus { + background-color: $color--white; + } + } + + #{$root}__links & { + margin-right: 1rem; + + &:only-child { + margin-right: 0; + } + } } &__status { @@ -43,10 +65,12 @@ } } + &__pagination, &__rejected { text-align: center; } + &__pagination-link, &__rejected-link { font-weight: $weight--bold; } @@ -86,10 +110,6 @@ tbody { font-size: map-get($font-sizes, zeta); - - a { - text-decoration: underline; - } } tr { @@ -104,6 +124,10 @@ padding: 0 0 .5rem; word-break: break-word; + @include media-query(tablet-landscape) { + padding: 1rem; + } + &:first-child { padding: 1rem 0 .5rem; @@ -111,21 +135,6 @@ padding: 1rem; } } - - &:last-child { - padding: 0 0 1rem; - display: flex; - flex-wrap: wrap; - - & > * { - flex: 1 1 55px; - max-width: 55px; - } - } - - @include media-query(tablet-landscape) { - padding: 1rem; - } } } } @@ -147,6 +156,69 @@ &__table-update { min-width: 160px; - width: 25%; + width: 20%; + + @include media-query(desktop) { + width: 30%; + } + } + + &__action-link { + font-size: map-get($font-sizes, zeta); + display: inline-block; + margin-right: 1rem; + text-decoration: underline; + color: $color--primary; + + &:last-child { + margin: 0; + } + } + + &__list-item { + border-bottom: 2px solid $color--light-grey; + padding: 1rem 0; + + @include media-query(tablet-landscape) { + display: flex; + justify-content: space-between; + align-items: center; + } + + &:first-child { + padding-top: 0; + } + + &:last-child { + border-bottom: 0; + } + + &:only-child { + padding: 0; + } + } + + &__info { + margin: 0 1rem 1rem 0; + + @include media-query(tablet-landscape) { + margin: 0 1rem 0 0; + flex: 1; + } + } + + &__links { + display: flex; + align-items: center; + + @include media-query(tablet-landscape) { + justify-content: flex-end; + } + } + + &__icon { + width: 25px; + height: 25px; + fill: $color--tomato; } } diff --git a/opentech/static_src/src/sass/apply/main.scss b/opentech/static_src/src/sass/apply/main.scss index d2cd0d97d..e05387624 100644 --- a/opentech/static_src/src/sass/apply/main.scss +++ b/opentech/static_src/src/sass/apply/main.scss @@ -58,7 +58,7 @@ @import 'components/stat-block'; @import 'components/docs-block'; @import 'components/funding-block'; -@import 'components/payment-block'; +@import 'components/data-block'; @import 'components/invoice-block'; // Layout -- GitLab