Merge pull request #1063 from GSA/1043-move-account-info-into-utility-nav

1043 move account info into utility nav
This commit is contained in:
Carlo Costino
2024-01-09 11:40:29 -05:00
committed by GitHub
15 changed files with 260 additions and 108 deletions

View File

@@ -89,6 +89,7 @@ from app.navigation import (
HeaderNavigation,
MainNavigation,
OrgNavigation,
SecondaryNavigation,
)
from app.notify_client import InviteTokenError
from app.notify_client.api_key_api_client import api_key_api_client
@@ -129,6 +130,7 @@ navigation = {
"main_navigation": MainNavigation(),
"header_navigation": HeaderNavigation(),
"org_navigation": OrgNavigation(),
"secondary_navigation": SecondaryNavigation(),
}

View File

@@ -22,16 +22,26 @@ i.e.
@use "uswds-core" as *;
.usa-header--extended .usa-logo {
font-family: family("sans");
margin: units(4) 0;
@include at-media-max('mobile-lg') {
margin: units(4) 0 units(4) units(2);
.usa-header--extended {
.usa-logo {
font-family: family("sans");
margin: units(4) 0;
@include at-media-max('mobile-lg') {
margin: units(4) 0 units(4) units(2);
}
img {
@include at-media($theme-header-min-width) {
width: 80px;
height: 70px;
}
}
}
img {
@include at-media($theme-header-min-width) {
width: 80px;
height: 70px;
.usa-nav__secondary {
.usa-nav__link {
padding: 0;
&.usa-current {
text-decoration: underline;
}
}
}
}
@@ -44,15 +54,12 @@ i.e.
&> .usa-nav__primary-item > a {
font-size: size("body", 4);
}
&> .usa-nav__primary-item:last-child {
margin-left: auto;
@include u-margin-right(-4);
}
// &> .usa-nav__primary-item:last-child {
// margin-left: auto;
// @include u-margin-right(-4);
// }
}
.usa-nav__primary
h1 {
font-weight: bold !important;
}
@@ -270,7 +277,7 @@ td.table-empty-message {
}
.navigation-service.usa-breadcrumb {
-bottom: 0;
bottom: 0;
}
// Dashboard

View File

@@ -87,39 +87,7 @@ class HeaderNavigation(Navigation):
"uploads",
"view_job",
"view_jobs",
"confirm_edit_user_email",
"confirm_edit_user_mobile_number",
"edit_user_email",
"edit_user_mobile_number",
"edit_user_permissions",
"invite_user",
"manage_users",
"remove_user_from_service",
"usage",
"link_service_to_organization",
"service_add_email_reply_to",
"service_add_sms_sender",
"service_confirm_delete_email_reply_to",
"service_confirm_delete_sms_sender",
"service_edit_email_reply_to",
"service_edit_sms_sender",
"service_email_reply_to",
"service_name_change",
"service_set_auth_type",
"service_set_channel",
"send_files_by_email_contact_details",
"service_set_inbound_number",
"service_set_inbound_sms",
"service_set_international_sms",
"service_set_reply_to_email",
"service_set_sms_prefix",
"service_verify_reply_to_address",
"service_verify_reply_to_address_updates",
"service_settings",
"service_sms_senders",
"set_free_sms_allowance",
"set_message_limit",
"set_rate_limit",
},
"pricing": {
"how_to_pay",
@@ -236,6 +204,21 @@ class MainNavigation(Navigation):
"usage": {
"usage",
},
"user-profile": {
"user_profile",
"user_profile_confirm_delete_mobile_number",
"user_profile_email",
"user_profile_email_authenticate",
"user_profile_email_confirm",
"user_profile_mobile_number",
"user_profile_mobile_number_authenticate",
"user_profile_mobile_number_confirm",
"user_profile_mobile_number_delete",
"user_profile_name",
"user_profile_password",
"user_profile_preferred_timezone",
"user_profile_disable_platform_admin_view",
},
"settings": {
"link_service_to_organization",
"service_add_email_reply_to",
@@ -297,6 +280,58 @@ class CaseworkNavigation(Navigation):
}
class SecondaryNavigation(Navigation):
mapping = {
"settings": {
"link_service_to_organization",
"service_add_email_reply_to",
"service_add_sms_sender",
"service_confirm_delete_email_reply_to",
"service_confirm_delete_sms_sender",
"service_edit_email_reply_to",
"service_edit_sms_sender",
"service_email_reply_to",
"service_name_change",
"service_set_auth_type",
"service_set_channel",
"send_files_by_email_contact_details",
"service_set_inbound_number",
"service_set_inbound_sms",
"service_set_international_sms",
"service_set_reply_to_email",
"service_set_sms_prefix",
"service_verify_reply_to_address",
"service_verify_reply_to_address_updates",
"service_settings",
"service_sms_senders",
"set_free_sms_allowance",
"set_message_limit",
"set_rate_limit",
"confirm_edit_user_email",
"confirm_edit_user_mobile_number",
"edit_user_email",
"edit_user_mobile_number",
"edit_user_permissions",
"invite_user",
"manage_users",
"remove_user_from_service",
"user_profile",
"user_profile_confirm_delete_mobile_number",
"user_profile_email",
"user_profile_email_authenticate",
"user_profile_email_confirm",
"user_profile_mobile_number",
"user_profile_mobile_number_authenticate",
"user_profile_mobile_number_confirm",
"user_profile_mobile_number_delete",
"user_profile_name",
"user_profile_password",
"user_profile_preferred_timezone",
"user_profile_disable_platform_admin_view",
},
}
class OrgNavigation(Navigation):
mapping = {
"dashboard": {

View File

@@ -58,26 +58,37 @@
"text": "Features",
"active": header_navigation.is_selected('features')
},
{
"href": url_for('main.user_profile'),
"text": current_user.name,
"active": header_navigation.is_selected('user-profile')
},
{
"href": url_for('main.platform_admin_splash_page'),
"text": "Platform admin",
"active": header_navigation.is_selected('platform-admin')
},
{
"href": url_for('main.sign_out'),
"text": "Sign out"
},
{
"href": url_for('main.support'),
"text": "Contact us",
"active": header_navigation.is_selected('support')
}
] %}
{% if current_service %}
{% set secondaryNavigation = [
{
"href": url_for('main.service_settings', service_id=current_service.id),
"text": "Settings",
"active": secondary_navigation.is_selected('settings')
},
{
"href": url_for('main.sign_out'),
"text": "Sign out"
}
] %}
{% else %}
{% set secondaryNavigation = [
{
"href": url_for('main.sign_out'),
"text": "Sign out"
}
] %}
{% endif %}
{% else %}
{% set navigation = [
{
@@ -104,13 +115,29 @@
"href": url_for('main.user_profile'),
"text": "User profile",
"active": header_navigation.is_selected('user-profile')
},
{
"href": url_for('main.sign_out'),
"text": "Sign out"
}
] %}
{% endif %}
{% if current_service %}
{% set secondaryNavigation = [
{
"href": url_for('main.service_settings', service_id=current_service.id),
"text": "Settings",
"active": secondary_navigation.is_selected('settings')
},
{
"href": url_for('main.sign_out'),
"text": "Sign out"
}
] %}
{% else %}
{% set secondaryNavigation = [
{
"href": url_for('main.sign_out'),
"text": "Sign out"
}
] %}
{% endif %}
{% endif %}
{% else %}
<!-- Add navigation back after pilot -->
{# {% set navigation = [
@@ -142,6 +169,7 @@
"productName": "Notify",
"navigation": navigation,
"navigationClasses": "govuk-header__navigation--end",
"secondaryNavigation": secondaryNavigation,
"assetsPath": asset_path + "images"
}) }}
{% endblock %}
@@ -236,7 +264,7 @@
<span class="usa-sr-only">Please choose to extend your session or sign out. Your session will expire in 5 minutes or less.</span>
</h2>
<div class="usa-prose">
<p>You have been inactive for too long.
<p>You have been inactive for too long.
Your session will expire in <span id="timeLeft" role="timer"></span>.
</p>
</div>
@@ -273,5 +301,3 @@
<!--<![endif]-->
{% endblock %}

View File

@@ -76,23 +76,18 @@
{% endif %}
{% endfor %}
</ul>
<div class="usa-nav__secondary">
<div class="usa-nav__secondary margin-bottom-2">
<ul class="usa-nav__secondary-links">
{% for item in params.secondaryNavigation %}
{% if item.href and item.text %}
<li class="usa-nav__secondary-item{{ ' is-current' if item.active }}">
<a class="usa-nav__link {{ ' usa-current' if item.active }}" href="{{ item.href }}" {% for attribute, value
in item.attributes %} {{attribute}}="{{value}}" {% endfor %}>
<span>{{ item.text }}</span>
</a>
</li>
{% endif %}
{% endfor %}
<!-- <li class="usa-nav__secondary-item">
<a href="javascript:void(0)">
Sign in
</a>
</li> -->
<li class="usa-nav__secondary-item{{ ' is-current' if item.active }}">
<a class="usa-nav__link {{ ' usa-current' if item.active }}" href="{{ item.href }}" {% for attribute, value in
item.attributes %} {{attribute}}="{{value}}" {% endfor %}>
<span>{{ item.text }}</span>
</a>
</li>
{% endif %}
{% endfor %}
</ul>
<!-- <section aria-label="Search component">
<form class="usa-search usa-search--small margin-bottom-2" role="search">

View File

@@ -13,13 +13,12 @@
{% if not current_user.has_permissions('view_activity') %}
<li class="usa-sidenav__item"><a class="{{ casework_navigation.is_selected('sent-messages') }}" href="{{ url_for('.view_notifications', service_id=current_service.id, status='sending,delivered,failed') }}">Sent messages</a></li>
{% endif %}
<li class="usa-sidenav__item"><a class="{{ main_navigation.is_selected('team-members') }}" href="{{ url_for('.manage_users', service_id=current_service.id) }}">Team members</a></li>
{% if current_user.has_permissions('manage_service', allow_org_user=True) %}
<li class="usa-sidenav__item"><a class="{{ main_navigation.is_selected('usage') }}" href="{{ url_for('.usage', service_id=current_service.id) }}">Usage</a></li>
{% endif %}
{% if current_user.has_permissions('manage_api_keys', 'manage_service') %}
<!-- {% if current_user.has_permissions('manage_api_keys', 'manage_service') %}
<li class="usa-sidenav__item"><a class="{{ main_navigation.is_selected('settings') }}" href="{{ url_for('.service_settings', service_id=current_service.id) }}">Settings</a></li>
{% endif %}
{% endif %} -->
{% if current_user.has_permissions('manage_api_keys') %}
<!-- <li><a class="usa-link{{ main_navigation.is_selected('api-integration') }}" href="{{ url_for('.api_integration', service_id=current_service.id) }}">API integration</a></li> -->
{% endif %}

View File

@@ -0,0 +1,16 @@
{% if help %}
{% include 'partials/tour.html' %}
{% else %}
<nav class="nav">
<ul class="usa-sidenav">
{# {% if current_user.has_permissions() %} #}
<li class="usa-sidenav__item"><a class="{{ main_navigation.is_selected('settings') }}"
href="{{ url_for('main.service_settings', service_id=current_service.id) }}">General</a></li>
<li class="usa-sidenav__item"><a class="{{ main_navigation.is_selected('user-profile') }}"
href="{{ url_for('main.user_profile', service_id=current_service.id) }}">User profile</a></li>
<li class="usa-sidenav__item"><a class="{{ main_navigation.is_selected('team-members') }}"
href="{{ url_for('main.manage_users', service_id=current_service.id) }}">Team members</a></li>
{# {% endif %} #}
</ul>
</nav>
{% endif %}

View File

@@ -0,0 +1,34 @@
{% extends "admin_template.html" %}
{% block per_page_title %}
{% block service_page_title %}{% endblock %} {{ current_service.name }}
{% endblock %}
{% block main %}
<div class="grid-container">
<div class="grid-row margin-top-5">
{% if help %}
<div class="grid-col-3">
{% else %}
<div class="grid-col-3">
{% endif %}
{% include "settings_nav.html" %}
</div>
{% if help %}
<div class="grid-col-8">
{% else %}
<div class="grid-col-9 padding-left-4">
{% endif %}
{% block beforeContent %}
{% block backLink %}{% endblock %}
{% endblock %}
<main id="main-content" role="main" class="usa-prose site-prose margin-bottom-10">
{% block content %}
{% include 'flash_messages.html' %}
{% block maincolumn_content %}{% endblock %}
{% endblock %}
</main>
</div>
</div>
</div>
{% endblock %}

View File

@@ -1,4 +1,4 @@
{% extends "withnav_template.html" %}
{% extends "settings_template.html" %}
{% from "components/tick-cross.html" import tick_cross %}
{% from "components/live-search.html" import live_search %}
{% from "components/components/button/macro.njk" import usaButton %}
@@ -10,9 +10,9 @@
{% block maincolumn_content %}
<div class="button-flex-header">
<h1 class="font-body-xl margin-0">
Team members
</h1>
<h1 class="font-body-2xl margin-0">
Team members
</h1>
{% if current_user.has_permissions('manage_service') %}
{{ usaButton({
"element": "a",

View File

@@ -1,4 +1,4 @@
{% extends "withnav_template.html" %}
{% extends "settings_template.html" %}
{% from "components/banner.html" import banner_wrapper %}
{% from "components/table.html" import mapping_table, row, settings_row, text_field, optional_text_field, edit_field, field, boolean_field with context %}

View File

@@ -1,4 +1,4 @@
{% extends "withoutnav_template.html" %}
{% extends "settings_template.html" %}
{% from "components/table.html" import list_table, row, field %}
{% from "components/table.html" import mapping_table, row, text_field, optional_text_field, edit_field, field, boolean_field with context %}

View File

@@ -125,7 +125,6 @@ def test_service_navigation_for_org_user(
(
"Send messages",
"Sent messages",
"Team members",
),
403,
),
@@ -134,7 +133,6 @@ def test_service_navigation_for_org_user(
(
"Send messages",
"Sent messages",
"Team members",
"Usage",
),
200,

View File

@@ -363,7 +363,7 @@ def test_should_show_back_to_service_if_user_belongs_to_service(
):
mock_get_service.return_value = service_one
expected_page_text = (
"Test Service Switch service " "Send messages " "Dashboard " "Team members"
"Test Service Switch service " "Send messages " "Dashboard " "Usage"
) # TODO: set sidebar variables in common test module
page = client_request.get(

View File

@@ -1020,6 +1020,20 @@ def _test_dashboard_menu(client_request, mocker, usr, service, permissions):
return client_request.get("main.service_dashboard", service_id=service["id"])
def _test_settings_menu(client_request, mocker, usr, service, permissions):
usr["permissions"][str(service["id"])] = permissions
usr["services"] = [service["id"]]
mocker.patch("app.user_api_client.check_verify_code", return_value=(True, ""))
mocker.patch(
"app.service_api_client.get_services", return_value={"data": [service]}
)
mocker.patch("app.user_api_client.get_user", return_value=usr)
mocker.patch("app.user_api_client.get_user_by_email", return_value=usr)
mocker.patch("app.service_api_client.get_service", return_value={"data": service})
client_request.login(usr)
return client_request.get("main.service_dashboard", service_id=service["id"])
def test_menu_send_messages(
client_request,
mocker,
@@ -1051,11 +1065,8 @@ def test_menu_send_messages(
)
in page
)
# assert url_for('main.uploads', service_id=service_one['id']) in page
assert url_for("main.manage_users", service_id=service_one["id"]) in page
assert url_for("main.service_settings", service_id=service_one["id"]) not in page
# assert url_for('main.api_keys', service_id=service_one['id']) not in page
assert url_for("main.manage_users", service_id=service_one["id"]) not in page
assert url_for("main.service_settings", service_id=service_one["id"]) in page
def test_menu_manage_service(
@@ -1086,10 +1097,39 @@ def test_menu_manage_service(
)
in page
)
assert url_for("main.manage_users", service_id=service_one["id"]) in page
assert url_for("main.service_settings", service_id=service_one["id"]) in page
assert url_for(".service_dashboard", service_id=service_one["id"]) in page
assert url_for(".choose_template", service_id=service_one["id"]) in page
# assert url_for('main.api_keys', service_id=service_one['id']) not in page
def test_menu_main_settings(
client_request,
mocker,
api_user_active,
service_one,
mock_get_service_templates,
mock_has_no_jobs,
mock_get_template_statistics,
mock_get_service_statistics,
mock_get_annual_usage_for_service,
mock_get_inbound_sms_summary,
mock_get_free_sms_fragment_limit,
):
page = _test_settings_menu(
client_request,
mocker,
api_user_active,
service_one,
["view_activity", "user_profile", "manage_users", "manage_settings"],
)
page = str(page)
assert (
url_for(
"main.service_settings",
service_id=service_one["id"],
)
in page
)
assert url_for("main.service_settings", service_id=service_one["id"]) in page
def test_menu_manage_api_keys(
@@ -1122,8 +1162,8 @@ def test_menu_manage_api_keys(
)
in page
)
assert url_for("main.manage_users", service_id=service_one["id"]) in page
assert url_for("main.service_settings", service_id=service_one["id"]) in page
# assert url_for("main.manage_users", service_id=service_one["id"]) not in page
# assert url_for("main.service_settings", service_id=service_one["id"]) not in page
assert url_for("main.api_integration", service_id=service_one["id"]) in page
@@ -1145,8 +1185,8 @@ def test_menu_all_services_for_platform_admin_user(
)
page = str(page)
assert url_for("main.choose_template", service_id=service_one["id"]) in page
assert url_for("main.manage_users", service_id=service_one["id"]) in page
assert url_for("main.service_settings", service_id=service_one["id"]) in page
# assert url_for("main.manage_users", service_id=service_one["id"]) in page
# assert url_for("main.service_settings", service_id=service_one["id"]) in page
# assert url_for('main.view_notifications', service_id=service_one['id'], message_type='email') in page
assert (
url_for(

View File

@@ -400,9 +400,9 @@ def test_navigation_urls(
assert [a["href"] for a in page.select(".nav a")] == [
"/services/{}/templates".format(SERVICE_ONE_ID),
"/services/{}".format(SERVICE_ONE_ID),
"/services/{}/users".format(SERVICE_ONE_ID),
"/services/{}/usage".format(SERVICE_ONE_ID),
"/services/{}/service-settings".format(SERVICE_ONE_ID),
# "/services/{}/users".format(SERVICE_ONE_ID),
# "/services/{}/service-settings".format(SERVICE_ONE_ID),
# '/services/{}/api'.format(SERVICE_ONE_ID),
]
@@ -418,7 +418,7 @@ def test_caseworkers_get_caseworking_navigation(
client_request.login(active_caseworking_user)
page = client_request.get("main.choose_template", service_id=SERVICE_ONE_ID)
assert normalize_spaces(page.select_one("header + .grid-container nav").text) == (
"Send messages Sent messages Team members"
"Send messages Sent messages"
)
@@ -433,5 +433,5 @@ def test_caseworkers_see_jobs_nav_if_jobs_exist(
client_request.login(active_caseworking_user)
page = client_request.get("main.choose_template", service_id=SERVICE_ONE_ID)
assert normalize_spaces(page.select_one("header + .grid-container nav").text) == (
"Send messages Sent messages Team members"
"Send messages Sent messages"
)