From d476124762569b3725ada1e5797ee17bfed3e0c9 Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 12:44:21 -0400 Subject: [PATCH 01/20] Add label and description to internal notes field --- atst/forms/internal_comment.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/atst/forms/internal_comment.py b/atst/forms/internal_comment.py index a64833c8..71b88f7e 100644 --- a/atst/forms/internal_comment.py +++ b/atst/forms/internal_comment.py @@ -5,4 +5,8 @@ from .forms import ValidatedForm class InternalCommentForm(ValidatedForm): - text = TextAreaField(validators=[Optional()]) + text = TextAreaField( + "CCPO Internal Notes", + description="You may add additional comments and notes for internal CCPO reference and follow-up here.", + validators=[Optional()], + ) From 905226e98ad9060b38ec26efc630afbbe80b1e56 Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 12:44:53 -0400 Subject: [PATCH 02/20] change label and description for review comments field --- atst/forms/ccpo_review.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atst/forms/ccpo_review.py b/atst/forms/ccpo_review.py index 8b6ea64d..5d910fb6 100644 --- a/atst/forms/ccpo_review.py +++ b/atst/forms/ccpo_review.py @@ -7,7 +7,7 @@ from .validators import Alphabet, PhoneNumber class CCPOReviewForm(ValidatedForm): - comment = TextAreaField("Comments (optional)") + comment = TextAreaField("Instructions or comments", description='Provide instructions or notes for additional information that is necessary to approve the request here. The requestor may then re-submit the updated request or initiate contact outside of AT-AT if further discussion is required. This message will be shared with the person making the JEDI request..') fname_mao = StringField( "First Name (optional)", validators=[Optional(), Alphabet()] ) From 2a97ed5dc361396ca4fe9488f19df85eb3965b39 Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 12:58:23 -0400 Subject: [PATCH 03/20] request approval screen --- atst/routes/requests/approval.py | 2 +- templates/requests/approval.html | 248 +++++++++++++++++-------------- 2 files changed, 138 insertions(+), 112 deletions(-) diff --git a/atst/routes/requests/approval.py b/atst/routes/requests/approval.py index 1843e127..7249f9a4 100644 --- a/atst/routes/requests/approval.py +++ b/atst/routes/requests/approval.py @@ -35,7 +35,7 @@ def render_approval(request, form=None): return render_template( "requests/approval.html", data=data, - status_events=reversed(request.status_events), + reviews=list(reversed(request.reviews)), request=request, current_status=request.status.value, pending_review=pending_review, diff --git a/templates/requests/approval.html b/templates/requests/approval.html index b9559712..a28a35c0 100644 --- a/templates/requests/approval.html +++ b/templates/requests/approval.html @@ -16,8 +16,9 @@ {% endif %}
-
-

Request #{{ request.id }}

+
+

Request #{{ request.id }} +

{{ current_status }}
@@ -32,153 +33,178 @@
{% if pending_review %} -
- {{ f.csrf_token }} -
-
-

Approval Notes

-
+
+ + {{ f.csrf_token }} -
+ +
+
+
+

Review this Request

-
+
+
+ + -

Instructions for the Requestor

+ + +
+
- Provide instructions or notes for additional information that is necessary to approve the request here. The requestor may then re-submit the updated request or initiate contact outside of AT-AT if further discussion is required. These notes will be visible to the person making the JEDI Cloud request. +
+

Message to Requestor (optional)

+
+ {{ TextInput( + f.comment, + label='Approval comments or notes', + description='Provide any comments or notes regarding the approval of this request. This message will be shared with the person making the JEDI request..', + paragraph=True, + noMaxWidth=True + ) }} +
- {{ TextInput(f.comment, paragraph=True, placeholder="Add notes or comments explaining what changes are being requested or why further discussion is needed about this request.") }} +
+ {{ TextInput( + f.comment, + label='Revision instructions or notes', + paragraph=True, + noMaxWidth=True + ) }} +
+
-
+
-
-
-

Authorizing Officials

-

This section is not visible to the person making the request. It is only viewable by CCPO staff.

-

Provide the name of the key officials for both parties that have authorized this request to move forward.

+

Authorizing Officials (optional)

+

Provide the name of the key officials for both parties that have authorized this request to move forward. This section is not visible to the person making the request. It is only viewable by CCPO staff.

+
+ +

Mission Authorizing Official

+ +
+
+ {{ TextInput(f.fname_mao, placeholder="First name of mission authorizing official") }} +
+ +
+ {{ TextInput(f.lname_mao, placeholder="Last name of mission authorizing official") }} +
+
+ +
+
+ {{ TextInput(f.email_mao, placeholder="name@mail.mil") }} +
+ +
+ {{ TextInput(f.phone_mao, placeholder="(123) 456-7890", validation='usPhone') }} +
+
+ +
+ +

CCPO Authorizing Official

+ +
+
+ {{ TextInput(f.fname_ccpo, placeholder="First name of CCPO authorizing official") }} +
+ +
+ {{ TextInput(f.lname_ccpo, placeholder="Last name of CCPO authorizing official") }} +
+
+
+
+
+ +
+ + + + {{ Icon('x') }} + Cancel +
-

Mission Authorizing Official

- - -
- -
- {{ TextInput(f.fname_mao, placeholder="First name of mission authorizing official") }} -
- -
- {{ TextInput(f.lname_mao, placeholder="Last name of mission authorizing official") }} -
- -
- -
- -
- {{ TextInput(f.email_mao, placeholder="name@mail.mil") }} -
- - -
- {{ TextInput(f.phone_mao, placeholder="(123) 456-7890", validation='usPhone') }} -
- -
- - -

CCPO Authorizing Official

- -
- -
- {{ TextInput(f.fname_ccpo, placeholder="First name of CCPO authorizing official") }} -
- -
- {{ TextInput(f.lname_ccpo, placeholder="Last name of CCPO authorizing official") }} -
- -
- - - -
- -
- - - - {{ Icon('x') }} - Cancel - -
- + + +
{% endif %} -
-

CCPO Internal Notes

-

You may add additional comments and notes for internal CCPO reference and follow-up here.

-
-
-
- {{ internal_comment_form.csrf_token }} - {{ TextInput(internal_comment_form.text, paragraph=True) }} - -
+ +
+
+
+
+ + {{ internal_comment_form.csrf_token }} + {{ TextInput(internal_comment_form.text, paragraph=True, noMaxWidth=True) }} + +
-
-
+ +
+ +
+
-
-
-

Approval Log

-
-
-
-
    +
    + {% if reviews %} +
    +
    +

    CCPO Activity Log

    +
    - {% for status_event in status_events %} - {% if status_event.review %} +
    +
      + {% for review in reviews %}
    1. -

      {{ status_event.log_name }} by {{ status_event.review.full_name_reviewer }}

      - {% if status_event.review.comment %} -

      {{ status_event.review.comment }}

      +

      {{ review.log_name }} by {{ review.full_name_reviewer }}

      + {% if review.comment %} +

      {{ review.comment }}

      {% endif %}
      - {% if status_event.review.lname_mao %} + {% if review.lname_mao %}

      Mission Owner approval on behalf of:

      - {{ status_event.review.full_name_mao }} - {{ status_event.review.email_mao }} - {{ status_event.review.phone_mao }} + {{ review.full_name_mao }} + {{ review.email_mao }} + {{ review.phone_mao }}
      {% endif %} - {% if status_event.review.lname_ccpo %} + {% if review.lname_ccpo %}

      CCPO approval on behalf of:

      - {{ status_event.review.full_name_ccpo }} + {{ review.full_name_ccpo }}
      {% endif %}
      - {% set timestamp=status_event.time_created | formattedDate("%Y-%m-%d %H:%M:%S %Z") %} + {% set timestamp=review.status.time_created | formattedDate("%Y-%m-%d %H:%M:%S %Z") %}
    2. - {% endif %} - {% endfor %} - -
    + {% endfor %} +
+
- + {% else %} + {{ Alert('CCPO Activity Log', + message='No CCPO approvals or request changes have been recorded yet.', + level='warning' + ) }} + {% endif %}
+ {% endblock %} From 4eaacce321db11f45318597225d306d0460fba36 Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 12:58:41 -0400 Subject: [PATCH 04/20] add anchor to redirect --- atst/routes/requests/approval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atst/routes/requests/approval.py b/atst/routes/requests/approval.py index 7249f9a4..4d2fb87a 100644 --- a/atst/routes/requests/approval.py +++ b/atst/routes/requests/approval.py @@ -93,4 +93,4 @@ def create_internal_comment(request_id): request = Requests.get(g.current_user, request_id) Requests.update_internal_comments(g.current_user, request, form.data["text"]) - return redirect(url_for("requests.approval", request_id=request_id)) + return redirect(url_for("requests.approval", request_id=request_id, _anchor='ccpo-notes')) From 19e80cd18355adc0505e1db62556367d8357ddfc Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 12:59:30 -0400 Subject: [PATCH 05/20] add noMaxWidth, label and description overrides to text input --- js/components/text_input.js | 3 ++- templates/components/text_input.html | 19 +++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/js/components/text_input.js b/js/components/text_input.js index 8e4f8048..7d0bb78d 100644 --- a/js/components/text_input.js +++ b/js/components/text_input.js @@ -19,7 +19,8 @@ export default { default: () => '' }, initialErrors: Array, - paragraph: String + paragraph: String, + noMaxWidth: String }, data: function () { diff --git a/templates/components/text_input.html b/templates/components/text_input.html index ecd29f5c..f1cfb567 100644 --- a/templates/components/text_input.html +++ b/templates/components/text_input.html @@ -1,24 +1,35 @@ {% from "components/icon.html" import Icon %} {% from "components/tooltip.html" import Tooltip %} -{% macro TextInput(field, tooltip='', placeholder='', validation='anything', paragraph=False, initial_value='') -%} +{% macro TextInput( + field, + label=field.label | striptags, + description=field.description, + tooltip='', + placeholder='', + validation='anything', + paragraph=False, + initial_value='', + noMaxWidth=False) -%} +
+ v-bind:class="['usa-input usa-input--validation--' + validation, { 'usa-input--error': showError, 'usa-input--success': showValid, 'usa-input--validation--paragraph': paragraph, 'no-max-width': noMaxWidth }]">
{% set timestamp=review.status.time_created | formattedDate("%Y-%m-%d %H:%M:%S %Z") %} -
+
+ +
{% endfor %} From b7d2bf87ea09c3c1df43af71d6b794a0d5e11307 Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 13:42:56 -0400 Subject: [PATCH 14/20] change submit button depending on whether approving or denying --- templates/requests/approval.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/requests/approval.html b/templates/requests/approval.html index e0a11416..66762f35 100644 --- a/templates/requests/approval.html +++ b/templates/requests/approval.html @@ -122,8 +122,8 @@
- - + + {{ Icon('x') }} Cancel From 94670b5ecf5897595295903e719f59982ddeb700 Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 13:48:26 -0400 Subject: [PATCH 15/20] Add missing email validation --- templates/requests/approval.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/requests/approval.html b/templates/requests/approval.html index 66762f35..e39c1568 100644 --- a/templates/requests/approval.html +++ b/templates/requests/approval.html @@ -96,7 +96,7 @@
- {{ TextInput(f.email_mao, placeholder="name@mail.mil") }} + {{ TextInput(f.email_mao, placeholder="name@mail.mil", validation='email') }}
From 3e38b5ff1a812ee182458999e9af505e8db40e17 Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 13:54:40 -0400 Subject: [PATCH 16/20] do that format thing --- atst/forms/ccpo_review.py | 5 ++++- atst/routes/requests/approval.py | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/atst/forms/ccpo_review.py b/atst/forms/ccpo_review.py index 5d910fb6..2636d529 100644 --- a/atst/forms/ccpo_review.py +++ b/atst/forms/ccpo_review.py @@ -7,7 +7,10 @@ from .validators import Alphabet, PhoneNumber class CCPOReviewForm(ValidatedForm): - comment = TextAreaField("Instructions or comments", description='Provide instructions or notes for additional information that is necessary to approve the request here. The requestor may then re-submit the updated request or initiate contact outside of AT-AT if further discussion is required. This message will be shared with the person making the JEDI request..') + comment = TextAreaField( + "Instructions or comments", + description="Provide instructions or notes for additional information that is necessary to approve the request here. The requestor may then re-submit the updated request or initiate contact outside of AT-AT if further discussion is required. This message will be shared with the person making the JEDI request..", + ) fname_mao = StringField( "First Name (optional)", validators=[Optional(), Alphabet()] ) diff --git a/atst/routes/requests/approval.py b/atst/routes/requests/approval.py index 4d2fb87a..02bcfe75 100644 --- a/atst/routes/requests/approval.py +++ b/atst/routes/requests/approval.py @@ -93,4 +93,6 @@ def create_internal_comment(request_id): request = Requests.get(g.current_user, request_id) Requests.update_internal_comments(g.current_user, request, form.data["text"]) - return redirect(url_for("requests.approval", request_id=request_id, _anchor='ccpo-notes')) + return redirect( + url_for("requests.approval", request_id=request_id, _anchor="ccpo-notes") + ) From 738cbb1c654a5851da7effc981f5a7261178a61c Mon Sep 17 00:00:00 2001 From: dandds Date: Thu, 13 Sep 2018 14:15:25 -0400 Subject: [PATCH 17/20] render basic approval action for ccpo logs on request review screen --- atst/models/request_status_event.py | 2 ++ templates/requests/approval.html | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/atst/models/request_status_event.py b/atst/models/request_status_event.py index 283633b1..4680d162 100644 --- a/atst/models/request_status_event.py +++ b/atst/models/request_status_event.py @@ -48,6 +48,8 @@ class RequestStatusEvent(Base): def log_name(self): if self.new_status == RequestStatus.CHANGES_REQUESTED: return "Denied" + if self.new_status == RequestStatus.CHANGES_REQUESTED_TO_FINVER: + return "Denied" elif self.new_status == RequestStatus.PENDING_FINANCIAL_VERIFICATION: return "Accepted" else: diff --git a/templates/requests/approval.html b/templates/requests/approval.html index e39c1568..1af2d43c 100644 --- a/templates/requests/approval.html +++ b/templates/requests/approval.html @@ -166,7 +166,8 @@
  • -

    {{ review.log_name }} by {{ review.full_name_reviewer }}

    + {{ review.log_name }} +

    {{ review.status.log_name }} by {{ review.full_name_reviewer }}

    {% if review.comment %}

    {{ review.comment }}

    {% endif %} From fbe701bba1580d249b576685fd175d3af48da1dd Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 14:21:51 -0400 Subject: [PATCH 18/20] use radio for checking approval/denial --- atst/routes/requests/approval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atst/routes/requests/approval.py b/atst/routes/requests/approval.py index 02bcfe75..a0f0f5e8 100644 --- a/atst/routes/requests/approval.py +++ b/atst/routes/requests/approval.py @@ -58,7 +58,7 @@ def submit_approval(request_id): form = CCPOReviewForm(http_request.form) if form.validate(): - if http_request.form.get("approved"): + if http_request.form.get("review") == "approving": Requests.advance(g.current_user, request, form.data) else: Requests.request_changes(g.current_user, request, form.data) From b473a87eea15c0a5a4e5df8d9af49da17c89a058 Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 14:23:33 -0400 Subject: [PATCH 19/20] update test --- tests/routes/test_request_approval.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/routes/test_request_approval.py b/tests/routes/test_request_approval.py index 1955a04f..205bb28e 100644 --- a/tests/routes/test_request_approval.py +++ b/tests/routes/test_request_approval.py @@ -87,7 +87,7 @@ def test_can_submit_request_approval(client, user_session): status=RequestStatus.PENDING_CCPO_ACCEPTANCE ) review_data = RequestReviewFactory.dictionary() - review_data["approved"] = True + review_data["review"] = "approving" response = client.post( url_for("requests.submit_approval", request_id=request.id), data=review_data ) @@ -102,7 +102,7 @@ def test_can_submit_request_denial(client, user_session): status=RequestStatus.PENDING_CCPO_ACCEPTANCE ) review_data = RequestReviewFactory.dictionary() - review_data["denied"] = True + review_data["review"] = "denying" response = client.post( url_for("requests.submit_approval", request_id=request.id), data=review_data ) From 5018ff39fe3f3f7e039d273f872c0330e70cb8fa Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 14:46:44 -0400 Subject: [PATCH 20/20] no need for an alert when no history present --- styles/sections/_request_approval.scss | 2 +- templates/requests/approval.html | 93 +++++++++++++------------- 2 files changed, 47 insertions(+), 48 deletions(-) diff --git a/styles/sections/_request_approval.scss b/styles/sections/_request_approval.scss index 7011d745..f4b36140 100644 --- a/styles/sections/_request_approval.scss +++ b/styles/sections/_request_approval.scss @@ -49,7 +49,7 @@ border-top: 1px dashed $color-gray-light; &:first-child { - border-top-style: solid; + border-top: none; } @include media($medium-screen) { diff --git a/templates/requests/approval.html b/templates/requests/approval.html index 1af2d43c..d93a0f1d 100644 --- a/templates/requests/approval.html +++ b/templates/requests/approval.html @@ -154,58 +154,57 @@
    - {% if reviews %} -
    -
    -

    CCPO Activity Log

    -
    +
    +
    +

    CCPO Activity Log

    +
    -
    -
      - {% for review in reviews %} -
    1. -
      -
      - {{ review.log_name }} -

      {{ review.status.log_name }} by {{ review.full_name_reviewer }}

      - {% if review.comment %} -

      {{ review.comment }}

      +
      + {% if reviews %} +
        + {% for review in reviews %} +
      1. +
        +
        + {{ review.log_name }} +

        {{ review.status.log_name }} by {{ review.full_name_reviewer }}

        + {% if review.comment %} +

        {{ review.comment }}

        + {% endif %} + +
        + {% if review.lname_mao %} +
        +

        Mission Owner approval on behalf of:

        + {{ review.full_name_mao }} + {{ review.email_mao }} + {{ review.phone_mao }} +
        {% endif %} -
        - {% if review.lname_mao %} -
        -

        Mission Owner approval on behalf of:

        - {{ review.full_name_mao }} - {{ review.email_mao }} - {{ review.phone_mao }} -
        - {% endif %} - - {% if review.lname_ccpo %} -
        -

        CCPO approval on behalf of:

        - {{ review.full_name_ccpo }} -
        - {% endif %} -
        + {% if review.lname_ccpo %} +
        +

        CCPO approval on behalf of:

        + {{ review.full_name_ccpo }} +
        + {% endif %}
        - {% set timestamp=review.status.time_created | formattedDate("%Y-%m-%d %H:%M:%S %Z") %} -
        - -
        -
        -
      2. - {% endfor %} -
      -
      +
      + {% set timestamp=review.status.time_created | formattedDate("%Y-%m-%d %H:%M:%S %Z") %} +
      + +
      +
      +
    2. + {% endfor %} +
    + {% else %} +
    +

    No CCPO approvals or request changes have been recorded yet.

    +
    + {% endif %}
    - {% else %} - {{ Alert('CCPO Activity Log', - message='No CCPO approvals or request changes have been recorded yet.', - level='warning' - ) }} - {% endif %} +