diff --git a/atst/domain/environment_roles.py b/atst/domain/environment_roles.py index ec34b123..ef8a4b8e 100644 --- a/atst/domain/environment_roles.py +++ b/atst/domain/environment_roles.py @@ -3,9 +3,10 @@ from flask import current_app as app from atst.database import db from atst.models import ( - EnvironmentRole, - ApplicationRole, Environment, + EnvironmentRole, + Application, + ApplicationRole, ApplicationRoleStatus, ) from atst.domain.exceptions import NotFoundError @@ -126,3 +127,15 @@ class EnvironmentRoles(object): .one_or_none() ) return existing_env_role + + @classmethod + def for_user(cls, user_id, portfolio_id): + return ( + db.session.query(EnvironmentRole) + .join(ApplicationRole) + .join(Application) + .filter(Application.portfolio_id == portfolio_id) + .filter(ApplicationRole.application_id == Application.id) + .filter(ApplicationRole.user_id == user_id) + .all() + ) diff --git a/atst/routes/applications/index.py b/atst/routes/applications/index.py index dc9f4c9c..92b65398 100644 --- a/atst/routes/applications/index.py +++ b/atst/routes/applications/index.py @@ -1,7 +1,8 @@ -from flask import render_template +from flask import render_template, g from .blueprint import applications_bp from atst.domain.authz.decorator import user_can_access_decorator as user_can +from atst.domain.environment_roles import EnvironmentRoles from atst.models.permissions import Permissions @@ -23,4 +24,11 @@ def has_portfolio_applications(_user, portfolio=None, **_kwargs): message="view portfolio applications", ) def portfolio_applications(portfolio_id): - return render_template("applications/index.html") + user_env_roles = EnvironmentRoles.for_user(g.current_user.id, portfolio_id) + environment_access = { + env_role.environment_id: env_role.role for env_role in user_env_roles + } + + return render_template( + "applications/index.html", environment_access=environment_access + ) diff --git a/styles/core/_grid.scss b/styles/core/_grid.scss index ff07cca6..d060198d 100644 --- a/styles/core/_grid.scss +++ b/styles/core/_grid.scss @@ -40,8 +40,7 @@ } &.col--grow { - flex: 1; - flex-grow: 1; + flex: 1 auto; padding-right: $spacing-small; } diff --git a/styles/core/_variables.scss b/styles/core/_variables.scss index dc609fe4..fe81b498 100644 --- a/styles/core/_variables.scss +++ b/styles/core/_variables.scss @@ -16,6 +16,7 @@ $footer-height: 5rem; $usa-banner-height: 2.8rem; $sidenav-expanded-width: 25rem; $sidenav-collapsed-width: 10rem; +$max-panel-width: 80rem; /* * USWDS Variables diff --git a/styles/elements/_accordions.scss b/styles/elements/_accordions.scss index b81a7c6e..a6e61692 100644 --- a/styles/elements/_accordions.scss +++ b/styles/elements/_accordions.scss @@ -1,148 +1,50 @@ -.triangle-box { - position: relative; - - .triangle-up { - $triangle-size: $gap * 1.5; - - position: absolute; - width: 0; - height: 0; - border-left: $triangle-size solid transparent; - border-right: $triangle-size solid transparent; - border-bottom: $triangle-size solid $color-blue-light; - bottom: -4px; - right: 50%; - } -} - .accordion { - @include block-list; - - box-shadow: 0 4px 10px 0 rgba(193, 193, 193, 0.5); - margin-bottom: 6 * $gap; - - .icon-link { - margin: (-$gap) 0; - } - - .icon-link, - .label { - &:first-child { - margin-left: -$gap; - } - - &:last-child { - margin-right: -$gap; - } - } + @include shadow-panel; + margin: $gap * 3 0; + max-width: $max-panel-width; &__header { - @include block-list-header; + padding: $gap * 2 $gap * 3; + background-color: $color-white; - border-top: 3px solid $color-blue; - border-bottom: none; - box-shadow: 0 2px 4px 0 rgba(216, 218, 222, 0.58); - - &.row { - background: $color-white; - } - } - - &__title { - @include block-list__title; - - color: $color-blue; - - @include h3; - - &.icon-link { + &-text { margin: 0; - display: block; - padding: 0 $gap; - text-decoration: none; } } - &__description { - @include block-list__description; - - font-style: italic; - font-size: $small-font-size; - color: $color-gray; + &__button { + margin: 0; } - &__actions { - margin-top: $gap; - margin-bottom: $gap * 0.5; - display: flex; - flex-direction: row; + &__content { + padding: 0 ($gap * 3) $gap; - .icon-link { - font-size: $small-font-size; + &--list-item { + border-bottom: 1px solid $color-gray-lightest; + padding: $gap 0; - svg { - width: 1rem; + &:last-child { + border-bottom: none; + padding-bottom: $gap; + } + + .col { + padding-right: $gap * 2; + + &:last-child { + padding-right: 0; + } + } + + h4 { + margin: $gap * 2 0 $gap; + } + + h5 { + font-size: 1rem; + color: $color-gray; + margin: 0; } } - - &__footer { - @include block-list__footer; - - border-top: 0; - } - } - - &__item { - @include block-list-item; - - opacity: 0.75; - background-color: $color-blue-light; - border-bottom: 1px solid rgba($color-gray-light, 0.5); - - &--selectable { - > div { - display: flex; - flex-direction: row-reverse; - - @include ie-only { - width: 100%; - } - - > label { - @include block-list-selectable-label; - } - } - - > label { - @include block-list-selectable-label; - } - - input:checked { - + label { - color: $color-primary; - } - } - - @include ie-only { - dl { - width: 100%; - padding-left: $gap * 4; - } - } - } - } - - .counter { - background-color: $color-cool-blue-light; - color: $color-white; - border-radius: 2px; - padding: ($gap / 2) $gap; - margin-left: $gap; - } - - .separator { - border: 1px solid $color-gray-medium; - opacity: 0.75; - margin: 0 (0.5 * $gap); } } diff --git a/styles/elements/_icons.scss b/styles/elements/_icons.scss index 13e958b1..c7a43414 100644 --- a/styles/elements/_icons.scss +++ b/styles/elements/_icons.scss @@ -90,4 +90,8 @@ padding: 2px; } } + + &--primary { + @include icon-color($color-primary); + } } diff --git a/styles/sections/_task_order.scss b/styles/sections/_task_order.scss index 26bb4c79..4307333a 100644 --- a/styles/sections/_task_order.scss +++ b/styles/sections/_task_order.scss @@ -1,25 +1,3 @@ -.task-order-list { - margin-top: 6 * $gap; -} - -.task-order-card { - &__buttons .usa-button { - min-width: 10rem; - } - - &__buttons .usa-button-secondary { - min-width: 14rem; - } - - .label { - font-size: $small-font-size; - margin-right: 2 * $gap; - min-width: 7rem; - display: flex; - justify-content: space-around; - } -} - .task-order { margin-top: $gap * 4; width: 900px; diff --git a/templates/applications/index.html b/templates/applications/index.html index 4ab303e4..81509be5 100644 --- a/templates/applications/index.html +++ b/templates/applications/index.html @@ -1,6 +1,7 @@ -{% from "components/icon.html" import Icon %} +{% from "components/accordion.html" import Accordion %} {% from "components/empty_state.html" import EmptyState %} {% from "components/sticky_cta.html" import StickyCTA %} +{% from "components/icon.html" import Icon %} {% extends "portfolios/base.html" %} @@ -31,59 +32,51 @@ ) }} {% else %} - -
- {{ application.description }} -
-+ {{ application.description }} +
++ {{ task_order.start_date | formattedDate(formatter="%b %d, %Y") }} + - + {{ task_order.end_date | formattedDate(formatter="%b %d, %Y") }} +
+{{ task_order.total_contract_amount | dollars }}
+{{ task_order.total_obligated_funds | dollars }}
+$0
+