diff --git a/atst/routes/portfolios/index.py b/atst/routes/portfolios/index.py index 647d68be..1d7739e7 100644 --- a/atst/routes/portfolios/index.py +++ b/atst/routes/portfolios/index.py @@ -62,9 +62,11 @@ def portfolio_reports(portfolio_id): prev_month = current_month - timedelta(days=28) two_months_ago = prev_month - timedelta(days=28) - expiration_date = ( - portfolio.legacy_task_order and portfolio.legacy_task_order.expiration_date + task_order = next( + (task_order for task_order in portfolio.task_orders if task_order.is_active), + None, ) + expiration_date = task_order and task_order.end_date if expiration_date: remaining_difference = expiration_date - today remaining_days = remaining_difference.days @@ -76,8 +78,7 @@ def portfolio_reports(portfolio_id): cumulative_budget=Reports.cumulative_budget(portfolio), portfolio_totals=Reports.portfolio_totals(portfolio), monthly_totals=Reports.monthly_totals(portfolio), - jedi_request=portfolio.request, - legacy_task_order=portfolio.legacy_task_order, + task_order=task_order, current_month=current_month, prev_month=prev_month, two_months_ago=two_months_ago, diff --git a/static/icons/envelope.svg b/static/icons/envelope.svg new file mode 100644 index 00000000..a2557ef2 --- /dev/null +++ b/static/icons/envelope.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/styles/components/_portfolio_layout.scss b/styles/components/_portfolio_layout.scss index 9eefb286..9c28239f 100644 --- a/styles/components/_portfolio_layout.scss +++ b/styles/components/_portfolio_layout.scss @@ -95,17 +95,21 @@ margin: 6 * $gap $gap 0 $gap; } +@mixin subheading { + color: $color-gray-dark; + padding: $gap 0; + text-transform: uppercase; + opacity: 0.54; + font-size: $small-font-size; + font-weight: bold; +} + .portfolio-applications { .portfolio-applications__header { margin-bottom: 4 * $gap; .portfolio-applications__header--title { - color: $color-gray-dark; - padding: $gap 0; - text-transform: uppercase; - opacity: 0.54; - font-size: $small-font-size; - font-weight: bold; + @include subheading; } .portfolio-applications__header--actions { @@ -287,3 +291,19 @@ } } } + +.portfolio-reports { + .portfolio-reports__header { + margin-bottom: 4 * $gap; + + .portfolio-reports__header--title { + @include subheading; + } + } + + .panel { + box-shadow: 0 6px 18px 0 rgba(144,164,183,0.3); + border-top: none; + border-bottom: none; + } +} diff --git a/styles/sections/_reports.scss b/styles/sections/_reports.scss index 8f2d5fd5..576a7bda 100644 --- a/styles/sections/_reports.scss +++ b/styles/sections/_reports.scss @@ -7,6 +7,11 @@ .funding-summary-row__col { + hr { + margin: 2 * $gap 0; + border-bottom: 1px solid $color-gray-lightest; + } + @include media($medium-screen) { @include grid-pad; flex-grow: 1; @@ -36,6 +41,11 @@ max-width: 100%; } + .subheading { + @include h4; + margin: 0 $gap 2 * $gap 0; + -ms-flex-negative: 1; + } // Spending Summary // =============================== @@ -53,40 +63,28 @@ } } - .spend-summary__heading { - @include h3; - margin: 0 $gap 0 0; - -ms-flex-negative: 1; - } - .spend-summary__budget { margin: 0 0 0 $gap; @include ie-only { margin: $gap 0 0 0; } + } - > div { - text-align: right; - margin: 0 0 ($gap / 2) 0; + dl { + text-align: left; + margin: 0 0 ($gap / 2) 0; - @include ie-only { - text-align: left; - } + @include ie-only { + text-align: left; + } - dd, dt { - display: inline; - } - - dt { - color: $color-gray; - margin-right: $gap; - font-weight: normal; - } - - dd { - font-weight: bold; - } + dt { + text-transform: uppercase; + color: $color-gray-light; + margin-right: $gap; + font-weight: bold; + font-size: $small-font-size; } } @@ -97,42 +95,42 @@ } .spend-summary__spent { - margin: $gap 0 0 0; + margin: 2 * $gap 0; display: flex; - flex-direction: row-reverse; + flex-direction: column; justify-content: flex-end; - dd, dt { - @include h5; - } - dt { - font-weight: normal; - margin-left: $gap; + letter-spacing: 0.47px; } } } - // Task Order Summary // =============================== &.to-summary { - .to-summary__row { - .to-summary__heading { - @include h3; - margin: 0; - } + .icon-link { + font-weight: $font-normal + } - .to-summary__to-number { - margin: 0; - dd { - &::before { - content: '#'; - color: $color-gray; - margin-right: $gap; - } + .subheading { + margin-bottom: 0; + } + + .to-summary__heading { + @include h4; + margin: 0 $gap 0 0; + } + + .to-summary__to-number { + margin: 0; + dd { + &::before { + content: '#'; + color: $color-gray; + margin-right: $gap; } } @@ -163,23 +161,27 @@ .to-summary__expiration { dl { - margin: ($gap * 2) 0 0 0; + text-align: right; - > div { - margin: 0 0 ($gap / 2) 0; + dd, dt { + display: inline; + } - dd, dt { - display: block; - } + dt { + font-size: $small-font-size; + text-transform: uppercase; + font-weight: $font-bold; + color: $color-gray-light; + } - dt { - color: $color-gray; - margin-right: $gap; - font-weight: normal; - } + dd.ending-soon { + color: $color-red-dark; + font-size: $h2-font-size; + white-space: nowrap; - dd { - font-weight: bold; + .icon { + @include icon-size(28); + @include icon-color($color-red-dark); } } } @@ -203,9 +205,12 @@ .spend-table { + box-shadow: 0 6px 18px 0 rgba(144,164,183,0.3); + .spend-table__header { @include panel-base; @include panel-theme-default; + border-top: none; border-bottom: 0; display: flex; flex-direction: row; @@ -215,8 +220,8 @@ padding: $gap * 2; .spend-table__title { - @include h3; - margin: 0; + @include h4; + font-size: $lead-font-size; flex: 2; } @@ -227,6 +232,12 @@ } table { + thead th { + text-transform: uppercase; + border-bottom: 1px solid $color-gray-lightest; + border-top: none; + } + th, td { white-space: nowrap; @@ -234,10 +245,6 @@ margin: 0; } - &.current-month { - background-color: $color-aqua-lightest; - } - &.previous-month { color: $color-gray; } @@ -286,28 +293,53 @@ .spend-table__portfolio { th, td { font-weight: bold; + border-bottom: 1px solid $color-gray-lightest; } } .spend-table__application { .spend-table__application__toggler { - @include icon-link-color($color-black-light, $color-gray-lightest); + @include icon-link-color($color-blue, $color-gray-lightest); margin-left: -$gap; + color: $color-blue; .icon { @include icon-size(12); margin-right: $gap; } + + .open-indicator { + position: absolute; + bottom: 0; + left: 5 * $gap; + width: 0; + height: 0; + border-left: 10px solid transparent; + border-right: 10px solid transparent; + + border-bottom: 10px solid $color-blue-light; + } + } + + th, td { + border-bottom: none; + } + + th[scope=rowgroup] { + position: relative; } .spend-table__application__env { - margin-left: $gap; + margin-left: 2 * $gap; - &:last-child { - td, th { - padding-bottom: $gap * 5; - box-shadow: inset 0 (-$gap * 2.5) 0 $color-gray-lightest; + th, td { + .icon-link { + font-weight: $font-normal; + font-size: $base-font-size; } + + border-bottom: 1px dashed $color-white; + background-color: $color-blue-light; } } } diff --git a/templates/portfolios/header.html b/templates/portfolios/header.html index 5e3bd508..1895ecac 100644 --- a/templates/portfolios/header.html +++ b/templates/portfolios/header.html @@ -12,7 +12,7 @@
- {{ portfolio.name }} + {{ secondary_breadcrumb or portfolio.name }}
Available budget diff --git a/templates/portfolios/reports/index.html b/templates/portfolios/reports/index.html index 9a455ddc..e124dc93 100644 --- a/templates/portfolios/reports/index.html +++ b/templates/portfolios/reports/index.html @@ -1,6 +1,5 @@ {% extends "portfolios/base.html" %} -{% from "components/alert.html" import Alert %} {% from "components/icon.html" import Icon %} {% from "components/empty_state.html" import EmptyState %} @@ -8,42 +7,38 @@ {% block portfolio_content %} - {{ Alert("Budget Report for Portfolio " + portfolio.name, - message="

Track your monthly and cumulative expenditures for your portfolio, applications, and environments below.

\ -

Please note that the projected spend is based on the average expense over the last three completed months and therefore does not account for future changes that might be made in scale or configuration of your cloud services.

", - actions=[ - {"label": "Learn More", "href": url_for('atst.helpdocs'), "icon": "info"} - ] ) }} - +
+

Portfolio Total Spend

-

Portfolio Total Spend

-
+
{% set budget = portfolio_totals['budget'] %} {% set spent = portfolio_totals['spent'] %} {% set remaining = budget - spent %} -
-
Budget
+
+
Budget
{{ budget | dollars }}
-
+
-
+
Remaining
{{ remaining | dollars }}
-
+
+
+
-
Total spend to date
+
Total spending to date
{{ spent | dollars }}
@@ -55,52 +50,68 @@
-

Task Order

+

Current Task Order

Task Order Number
-
{{ legacy_task_order.number }}
+
{{ task_order.number }}
-
-
-
-
Expires
-
- {% if expiration_date %} - - - {% else %} - - - {% endif %} -
-
+
+
+
+

Expiration Date

-
Remaining
-
+ {% if expiration_date %} + + + {% else %} + - + {% endif %} +
+ + {{ Icon('cog') }} + Manage Task Order + +
+
+
+
Remaining Days
+
{% if remaining_days is not none %} - {{ remaining_days }} days + {{ Icon('arrow-down') }} + {{ remaining_days }} {% else %} - {% endif %}
-
-
- - - Manage Task Order - + +
+
+
-
Contracting Officer
-
- {{ jedi_request.contracting_officer_full_name }} - {{ jedi_request.contracting_officer_email }} +
Contracting Officer
+
+
+ {% if task_order.ko_first_name and task_order.ko_last_name %} + {{ task_order.ko_first_name }} {{ task_order.ko_last_name }} + {% endif %} +
+ +
+ {% if task_order.ko_email %} + + {{ Icon('envelope') }} + {{ task_order.ko_email }} + + {% endif %} +
@@ -142,7 +153,7 @@
-

Cumulative Budget

+

Cumulative Budget

@@ -331,7 +342,7 @@
-

Total spend per month

+

Total spent per month