diff --git a/atst/models/application.py b/atst/models/application.py index 02c7185a..050b13d7 100644 --- a/atst/models/application.py +++ b/atst/models/application.py @@ -17,6 +17,14 @@ class Application(Base, mixins.TimestampsMixin, mixins.AuditableMixin): portfolio = relationship("Portfolio") environments = relationship("Environment", back_populates="application") + @property + def users(self): + return set([user for env in self.environments for user in env.users]) + + @property + def num_users(self): + return len(self.users) + @property def displayname(self): return self.name diff --git a/static/icons/minus.svg b/static/icons/minus.svg new file mode 100644 index 00000000..ac83426d --- /dev/null +++ b/static/icons/minus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/styles/atat.scss b/styles/atat.scss index f2e91d6e..6ef73f66 100644 --- a/styles/atat.scss +++ b/styles/atat.scss @@ -12,6 +12,7 @@ @import 'elements/buttons'; @import 'elements/panels'; @import 'elements/block_lists'; +@import 'elements/accordians'; @import 'elements/tables'; @import 'elements/sidenav'; @import 'elements/action_group'; diff --git a/styles/components/_portfolio_layout.scss b/styles/components/_portfolio_layout.scss index d95db7fa..c15027ab 100644 --- a/styles/components/_portfolio_layout.scss +++ b/styles/components/_portfolio_layout.scss @@ -86,7 +86,60 @@ } .portfolio-content { - margin-top: 6 * $gap; + margin: 6 * $gap $gap 0 $gap; +} + +.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; + } + + .portfolio-applications__header--actions { + color: $color-blue; + font-size: $small-font-size; + .icon { + @include icon-color($color-blue); + @include icon-size(14); + } + } + } + + .application-list { + .toggle-link { + background-color: $color-blue-light; + .icon { + margin: $gap / 2; + } + } + + .application-list-item { + border-radius: 5px; + box-shadow: 0 4px 8px 1px rgba(230,230,230,0.5), -4px 4px 8px 1px rgba(230,230,230,0.5); + + .col { + max-width: 95%; + } + + .application-list-item__environment__name { + } + + .application-list-item__environment__csp_link { + font-size: $small-font-size; + font-weight: normal; + &:hover { + background-color: $color-aqua-light; + } + } + } + } } .portfolio-funding { diff --git a/styles/core/_variables.scss b/styles/core/_variables.scss index 95cfba10..3917fa5e 100644 --- a/styles/core/_variables.scss +++ b/styles/core/_variables.scss @@ -43,6 +43,7 @@ $font-bold: 700; $color-blue: #0071bc; $color-blue-darker: #205493; $color-blue-darkest: #112e51; +$color-blue-light: #e5f1ff; $color-aqua: #02bfe7; $color-aqua-dark: #00a6d2; @@ -83,7 +84,7 @@ $color-green-lighter: #94bfa2; $color-green-lightest: #e7f4e4; $color-cool-blue: #205493; -$color-cool-blue-light: #4773aa; +$color-cool-blue-light: #4190e2; $color-cool-blue-lighter: #8ba6ca; $color-cool-blue-lightest: #dce4ef; diff --git a/styles/elements/_accordians.scss b/styles/elements/_accordians.scss new file mode 100644 index 00000000..77727c2a --- /dev/null +++ b/styles/elements/_accordians.scss @@ -0,0 +1,110 @@ +.accordian { + @include block-list; + + box-shadow: 0 4px 10px 0 rgba(193,193,193,0.5); + + .icon-link { + margin: -$gap 0; + } + + .icon-link, + .label { + &:first-child { + margin-left: -$gap; + } + + &:last-child { + margin-right: -$gap; + } + + } +} + +.accordian__header { + @include block-list-header; + border-top: 3px solid $color-blue; + border-bottom: none; + box-shadow: 0 2px 4px 0 rgba(216,218,222,0.58); +} + +.accordian__title { + @include block-list__title; + color: $color-blue; + @include h3; +} + +.accordian__description { + @include block-list__description; + font-style: italic; + font-size: $small-font-size; + color: $color-gray; +} + +.accordian__actions { + margin-top: $gap; + display: flex; + flex-direction: row; + + .icon-link { + font-size: $small-font-size; + } + + .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; + } +} + +.accordian__item { + @include block-list-item; + + opacity: 0.75; + background-color: $color-blue-light; + border-bottom: 1px solid rgba($color-gray-light, 0.5); + + &.accordian__item--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; + } + } + + } +} + +.accordian__footer { + @include block-list__footer; + border-top: 0; +} diff --git a/templates/portfolios/applications/index.html b/templates/portfolios/applications/index.html index 06eac461..e89ff12c 100644 --- a/templates/portfolios/applications/index.html +++ b/templates/portfolios/applications/index.html @@ -3,52 +3,88 @@ {% extends "portfolios/base.html" %} +{% set can_create_applications = user_can(permissions.ADD_APPLICATION_IN_PORTFOLIO) %} + {% block portfolio_content %} -{% if not portfolio.applications %} - - {% set can_create_applications = user_can(permissions.ADD_APPLICATION_IN_PORTFOLIO) %} - - {{ EmptyState( - 'This portfolio doesn’t have any applications yet.', - action_label='Add a New Application' if can_create_applications else None, - action_href=url_for('portfolios.new_application', portfolio_id=portfolio.id) if can_create_applications else None, - icon='cloud', - sub_message=None if can_create_applications else 'Please contact your JEDI Cloud portfolio administrator to set up a new application.' - ) }} - -{% else %} - - {% for application in portfolio.applications %} -