diff --git a/static/icons/chart-pie.svg b/static/icons/chart-pie.svg new file mode 100644 index 00000000..e1b476bd --- /dev/null +++ b/static/icons/chart-pie.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/icons/cog.svg b/static/icons/cog.svg new file mode 100644 index 00000000..fb5bd35a --- /dev/null +++ b/static/icons/cog.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/icons/home.svg b/static/icons/home.svg new file mode 100644 index 00000000..27ee7ab0 --- /dev/null +++ b/static/icons/home.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/styles/components/_global_layout.scss b/styles/components/_global_layout.scss index a80b4ca5..b46526b5 100644 --- a/styles/components/_global_layout.scss +++ b/styles/components/_global_layout.scss @@ -1,5 +1,5 @@ #app-root { - background-color: $color-gray-lightest; + background-color: $color-white; display: flex; flex-direction: column; justify-content: flex-start; diff --git a/styles/components/_portfolio_layout.scss b/styles/components/_portfolio_layout.scss index e74481a3..d95db7fa 100644 --- a/styles/components/_portfolio_layout.scss +++ b/styles/components/_portfolio_layout.scss @@ -2,34 +2,93 @@ @include media($large-screen) { @include grid-row; } + + .line { + box-sizing: border-box; + height: 2px; + width: 100%; + border: 1px solid $color-gray-lightest; + } } -.portfolio-navigation { - @include panel-margin; - margin-bottom: $gap * 4; +.portfolio-breadcrumbs { + margin-bottom: $gap * 2; + color: $color-gray-medium; + font-size: $h5-font-size; - ul { - display: flex; - flex-direction: column; - li { - flex-grow: 1; + .icon-link { + color: $color-gray-medium; + font-weight: normal; + } + + .icon--tiny { + padding: $gap 0; + } + + .icon { + @include icon-color($color-gray-medium); + } + + .portfolio-breadcrumbs__crumb { + .icon { + @include icon-color($color-blue); + } + + .icon-link { + color: $color-blue; + pointer-events: none; + } + } +} + +.portfolio-header { + margin: 2 * $gap 0; + + .portfolio-header__name { + @include h1; + } + + .portfolio-header__budget { + font-size: $small-font-size; + align-items: center; + + button { + margin: 0; + padding: 0; + } + + .portfolio-header__budget--dollars { + font-size: $h2-font-size; + font-weight: bold; } } - @include media($medium-screen) { - margin-bottom: $gap * 5; - } + .links { + font-size: $small-font-size; - @include media($large-screen) { - width: 20rem; - margin-right: $gap * 2; + .icon-link { + &.active { + color: $color-gray; + .icon { + @include icon-color($color-gray); + } + } - ul { - display: block; + .icon-link--icon { + text-align: center; + } + + .icon { + @include icon-size(20); + } } } } +.portfolio-content { + margin-top: 6 * $gap; +} + .portfolio-funding { .portfolio-funding__header { padding: 0; diff --git a/styles/core/_variables.scss b/styles/core/_variables.scss index 3586faa9..95cfba10 100644 --- a/styles/core/_variables.scss +++ b/styles/core/_variables.scss @@ -62,7 +62,7 @@ $color-black-light: #212121; $color-gray-dark: #323a45; $color-gray: #5b616b; -$color-gray-medium: #757575; +$color-gray-medium: #9b9b9b; $color-gray-light: #aeb0b5; $color-gray-lighter: #d6d7d9; $color-gray-lightest: #f1f1f1; diff --git a/templates/navigation/portfolio_navigation.html b/templates/navigation/portfolio_navigation.html deleted file mode 100644 index 5bfca5c6..00000000 --- a/templates/navigation/portfolio_navigation.html +++ /dev/null @@ -1,68 +0,0 @@ -{% from "components/sidenav_item.html" import SidenavItem %} - - diff --git a/templates/portfolios/activity/index.html b/templates/portfolios/activity/index.html index d3a3acf9..c28b766c 100644 --- a/templates/portfolios/activity/index.html +++ b/templates/portfolios/activity/index.html @@ -1,6 +1,8 @@ {% extends "portfolios/base.html" %} {% from "components/pagination.html" import Pagination %} +{% set secondary_breadcrumb = "navigation.portfolio_navigation.breadcrumbs.admin" | translate %} + {% block portfolio_content %}
{% include "fragments/audit_events_log.html" %} diff --git a/templates/portfolios/applications/index.html b/templates/portfolios/applications/index.html index 60e56996..06eac461 100644 --- a/templates/portfolios/applications/index.html +++ b/templates/portfolios/applications/index.html @@ -3,7 +3,6 @@ {% extends "portfolios/base.html" %} - {% block portfolio_content %} {% if not portfolio.applications %} diff --git a/templates/portfolios/base.html b/templates/portfolios/base.html index 280e0d0b..92479d0f 100644 --- a/templates/portfolios/base.html +++ b/templates/portfolios/base.html @@ -3,12 +3,18 @@ {% block content %}
-
- {% include 'navigation/portfolio_navigation.html' %} -
-
- {% block portfolio_content %}{% endblock %} + {% block portfolio_breadcrumbs %} + {% include "portfolios/breadcrumbs.html" %} + {% endblock %} +
+ {% block portfolio_header %} + {% include "portfolios/header.html" %} + {% endblock %} +
+
+ {% block portfolio_content %}{% endblock %} +
diff --git a/templates/portfolios/breadcrumbs.html b/templates/portfolios/breadcrumbs.html new file mode 100644 index 00000000..bc4c16d7 --- /dev/null +++ b/templates/portfolios/breadcrumbs.html @@ -0,0 +1,19 @@ +{% from "components/icon.html" import Icon %} + +
+ + {{ Icon("home") }} + + {{ portfolio.name }} Portfolio + + +
+ {% if secondary_breadcrumb %} + {{ Icon("caret_right", classes="icon--tiny") }} + + {% endif %} +
+
diff --git a/templates/portfolios/edit.html b/templates/portfolios/edit.html index e6e68f16..f61c7d8c 100644 --- a/templates/portfolios/edit.html +++ b/templates/portfolios/edit.html @@ -3,6 +3,8 @@ {% from "components/icon.html" import Icon %} {% from "components/text_input.html" import TextInput %} +{% set secondary_breadcrumb = "navigation.portfolio_navigation.breadcrumbs.admin" | translate %} + {% block portfolio_content %} {% include "fragments/flash.html" %} diff --git a/templates/portfolios/header.html b/templates/portfolios/header.html new file mode 100644 index 00000000..9bbe4132 --- /dev/null +++ b/templates/portfolios/header.html @@ -0,0 +1,51 @@ +{% from "components/icon.html" import Icon %} + +{% macro Link(icon, text, url, active=False) %} + +
+ + +
+
+{% endmacro %} + +
+
+
+ {{ portfolio.name }} +
+
+ Available budget + + + {{ portfolio.task_orders | sum(attribute='budget') | dollars }} + +
+
+ +
diff --git a/templates/portfolios/reports/index.html b/templates/portfolios/reports/index.html index 01aa3607..9a455ddc 100644 --- a/templates/portfolios/reports/index.html +++ b/templates/portfolios/reports/index.html @@ -4,6 +4,8 @@ {% from "components/icon.html" import Icon %} {% from "components/empty_state.html" import EmptyState %} +{% set secondary_breadcrumb = "navigation.portfolio_navigation.breadcrumbs.reports" | translate %} + {% block portfolio_content %} {{ Alert("Budget Report for Portfolio " + portfolio.name, diff --git a/templates/portfolios/task_orders/index.html b/templates/portfolios/task_orders/index.html index 18653ab1..b7a18fd9 100644 --- a/templates/portfolios/task_orders/index.html +++ b/templates/portfolios/task_orders/index.html @@ -3,6 +3,8 @@ {% extends "portfolios/base.html" %} +{% set secondary_breadcrumb = "navigation.portfolio_navigation.breadcrumbs.funding" | translate %} + {% block portfolio_content %} {% macro ViewLink(task_order) %} diff --git a/templates/portfolios/task_orders/invitations.html b/templates/portfolios/task_orders/invitations.html index 782f86b8..14a3d389 100644 --- a/templates/portfolios/task_orders/invitations.html +++ b/templates/portfolios/task_orders/invitations.html @@ -1,5 +1,7 @@ {% extends "portfolios/base.html" %} +{% set secondary_breadcrumb = "navigation.portfolio_navigation.breadcrumbs.funding" | translate %} + {% from "components/checkbox_input.html" import CheckboxInput %} {% from "components/icon.html" import Icon %} {% from "components/text_input.html" import TextInput %} diff --git a/templates/portfolios/task_orders/review.html b/templates/portfolios/task_orders/review.html index 854da35b..61b50e8c 100644 --- a/templates/portfolios/task_orders/review.html +++ b/templates/portfolios/task_orders/review.html @@ -1,5 +1,7 @@ {% extends "base.html" %} +{% set secondary_breadcrumb = "navigation.portfolio_navigation.breadcrumbs.funding" | translate %} + {% from "components/edit_link.html" import EditLink %} {% from "components/required_label.html" import RequiredLabel %} {% from "components/icon.html" import Icon %} diff --git a/templates/portfolios/task_orders/show.html b/templates/portfolios/task_orders/show.html index 04e49824..310be45c 100644 --- a/templates/portfolios/task_orders/show.html +++ b/templates/portfolios/task_orders/show.html @@ -1,5 +1,7 @@ {% extends "portfolios/base.html" %} +{% set secondary_breadcrumb = "navigation.portfolio_navigation.breadcrumbs.funding" | translate %} + {% from "components/icon.html" import Icon %} {% block portfolio_content %} diff --git a/tests/routes/portfolios/test_applications.py b/tests/routes/portfolios/test_applications.py index 724a2a6d..5fe52ddf 100644 --- a/tests/routes/portfolios/test_applications.py +++ b/tests/routes/portfolios/test_applications.py @@ -1,3 +1,4 @@ +import pytest from flask import url_for from tests.factories import ( @@ -20,7 +21,7 @@ def test_user_with_permission_has_budget_report_link(client, user_session): user_session(portfolio.owner) response = client.get("/portfolios/{}/applications".format(portfolio.id)) assert ( - 'href="/portfolios/{}/reports"'.format(portfolio.id).encode() in response.data + "href='/portfolios/{}/reports'".format(portfolio.id).encode() in response.data ) @@ -38,6 +39,7 @@ def test_user_without_permission_has_no_budget_report_link(client, user_session) ) +@pytest.mark.skip(reason="Temporarily no add activity log link") def test_user_with_permission_has_activity_log_link(client, user_session): portfolio = PortfolioFactory.create() ccpo = UserFactory.from_atat_role("ccpo") @@ -69,6 +71,7 @@ def test_user_with_permission_has_activity_log_link(client, user_session): ) +@pytest.mark.skip(reason="Temporarily no add activity log link") def test_user_without_permission_has_no_activity_log_link(client, user_session): portfolio = PortfolioFactory.create() developer = UserFactory.create() @@ -87,6 +90,7 @@ def test_user_without_permission_has_no_activity_log_link(client, user_session): ) +@pytest.mark.skip(reason="Temporarily no add application link") def test_user_with_permission_has_add_application_link(client, user_session): portfolio = PortfolioFactory.create() user_session(portfolio.owner) @@ -97,6 +101,7 @@ def test_user_with_permission_has_add_application_link(client, user_session): ) +@pytest.mark.skip(reason="Temporarily no add application link") def test_user_without_permission_has_no_add_application_link(client, user_session): user = UserFactory.create() portfolio = PortfolioFactory.create() diff --git a/tests/routes/portfolios/test_members.py b/tests/routes/portfolios/test_members.py index 5cdf33bd..c8d97b61 100644 --- a/tests/routes/portfolios/test_members.py +++ b/tests/routes/portfolios/test_members.py @@ -1,3 +1,4 @@ +import pytest from flask import url_for from tests.factories import ( @@ -36,6 +37,7 @@ def create_portfolio_and_invite_user( return portfolio +@pytest.mark.skip(reason="Temporarily no add member link") def test_user_with_permission_has_add_member_link(client, user_session): portfolio = PortfolioFactory.create() user_session(portfolio.owner) @@ -46,6 +48,7 @@ def test_user_with_permission_has_add_member_link(client, user_session): ) +@pytest.mark.skip(reason="Temporarily no add member link") def test_user_without_permission_has_no_add_member_link(client, user_session): user = UserFactory.create() portfolio = PortfolioFactory.create() diff --git a/translations.yaml b/translations.yaml index 1f5202b6..5da1c31f 100644 --- a/translations.yaml +++ b/translations.yaml @@ -305,6 +305,10 @@ navigation: applications: Applications portfolio_funding: Funding portfolio_settings: Portfolio Settings + breadcrumbs: + admin: Admin + funding: Funding + reports: Reports requests: _new: new_request: New Request