mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-19 14:09:20 -04:00
Merge pull request #2033 from alphagov/selected-nav
Highlight selected navigation item
This commit is contained in:
@@ -39,6 +39,7 @@ from werkzeug.local import LocalProxy
|
||||
from app import proxy_fix
|
||||
from app.config import configs
|
||||
from app.asset_fingerprinter import AssetFingerprinter
|
||||
from app.navigation import HeaderNavigation, MainNavigation, OrgNavigation
|
||||
from app.notify_client.service_api_client import ServiceAPIClient
|
||||
from app.notify_client.api_key_api_client import ApiKeyApiClient
|
||||
from app.notify_client.invite_api_client import InviteApiClient
|
||||
@@ -89,6 +90,12 @@ current_service = LocalProxy(partial(_lookup_req_object, 'service'))
|
||||
# The current organisation attached to the request stack.
|
||||
current_organisation = LocalProxy(partial(_lookup_req_object, 'organisation'))
|
||||
|
||||
navigation = {
|
||||
'main_navigation': MainNavigation(),
|
||||
'header_navigation': HeaderNavigation(),
|
||||
'org_navigation': OrgNavigation(),
|
||||
}
|
||||
|
||||
|
||||
def create_app(application):
|
||||
setup_commands(application)
|
||||
@@ -171,6 +178,10 @@ def init_app(application):
|
||||
def _attach_current_user():
|
||||
return{'current_user': current_user}
|
||||
|
||||
@application.context_processor
|
||||
def _nav_selected():
|
||||
return navigation
|
||||
|
||||
@application.before_request
|
||||
def record_start_time():
|
||||
g.start = monotonic()
|
||||
|
||||
@@ -63,6 +63,15 @@
|
||||
color: $text-colour;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
@include bold-19;
|
||||
position: relative;
|
||||
// These two lines stop the width of the item jumping so much
|
||||
// between selected and unselected states
|
||||
left: -0.5px;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -99,7 +108,7 @@
|
||||
|
||||
&__item--active {
|
||||
@include bold-16;
|
||||
|
||||
|
||||
a:link, a:visited {
|
||||
color: $text-colour;
|
||||
}
|
||||
|
||||
687
app/navigation.py
Normal file
687
app/navigation.py
Normal file
@@ -0,0 +1,687 @@
|
||||
from itertools import chain
|
||||
|
||||
from flask import request
|
||||
|
||||
|
||||
class Navigation:
|
||||
|
||||
mapping = {}
|
||||
exclude = {}
|
||||
selected_attribute = "class=selected"
|
||||
|
||||
def __init__(self):
|
||||
self.mapping = {
|
||||
navigation: {
|
||||
'main.{}'.format(endpoint) for endpoint in endpoints
|
||||
} for navigation, endpoints in self.mapping.items()
|
||||
}
|
||||
|
||||
@property
|
||||
def endpoints_with_navigation(self):
|
||||
return tuple(chain.from_iterable((
|
||||
endpoints
|
||||
for navigation_item, endpoints in self.mapping.items()
|
||||
)))
|
||||
|
||||
@property
|
||||
def endpoints_without_navigation(self):
|
||||
return tuple(
|
||||
'main.{}'.format(endpoint) for endpoint in self.exclude
|
||||
) + ('static', 'status.show_status')
|
||||
|
||||
def is_selected(self, navigation_item):
|
||||
if request.endpoint in self.mapping[navigation_item]:
|
||||
return self.selected_attribute
|
||||
return ''
|
||||
|
||||
|
||||
class HeaderNavigation(Navigation):
|
||||
|
||||
selected_attribute = "class=active"
|
||||
|
||||
mapping = {
|
||||
'support': {
|
||||
'bat_phone',
|
||||
'feedback',
|
||||
'old_feedback',
|
||||
'old_submit_feedback',
|
||||
'support',
|
||||
'thanks',
|
||||
'triage',
|
||||
},
|
||||
'features': {
|
||||
'features',
|
||||
'roadmap',
|
||||
'security',
|
||||
'terms',
|
||||
'using_notify',
|
||||
},
|
||||
'pricing': {
|
||||
'pricing',
|
||||
},
|
||||
'documentation': {
|
||||
'documentation',
|
||||
'integration_testing',
|
||||
},
|
||||
'user-profile': {
|
||||
'user_profile',
|
||||
'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_name',
|
||||
'user_profile_password',
|
||||
},
|
||||
'platform-admin': {
|
||||
'add_organisation',
|
||||
'create_email_branding',
|
||||
'email_branding',
|
||||
'live_services',
|
||||
'organisations',
|
||||
'platform_admin',
|
||||
'suspend_service',
|
||||
'trial_services',
|
||||
'update_email_branding',
|
||||
'view_provider',
|
||||
'view_providers',
|
||||
},
|
||||
'sign-in': {
|
||||
'sign_in',
|
||||
'two_factor',
|
||||
'two_factor_email',
|
||||
'two_factor_email_sent',
|
||||
'verify',
|
||||
'verify_email',
|
||||
'verify_mobile',
|
||||
},
|
||||
}
|
||||
|
||||
exclude = {
|
||||
'accept_invite',
|
||||
'accept_org_invite',
|
||||
'action_blocked',
|
||||
'add_service',
|
||||
'add_service_template',
|
||||
'add_template_by_type',
|
||||
'agreement',
|
||||
'api_callbacks',
|
||||
'api_documentation',
|
||||
'api_integration',
|
||||
'api_keys',
|
||||
'archive_service',
|
||||
'callbacks',
|
||||
'cancel_invited_org_user',
|
||||
'cancel_invited_user',
|
||||
'cancel_job',
|
||||
'check_and_resend_text_code',
|
||||
'check_and_resend_verification_code',
|
||||
'check_messages',
|
||||
'check_messages_preview',
|
||||
'check_notification',
|
||||
'choose_account',
|
||||
'choose_service',
|
||||
'choose_template',
|
||||
'confirm_edit_organisation_name',
|
||||
'confirm_redact_template',
|
||||
'conversation',
|
||||
'conversation_reply',
|
||||
'conversation_reply_with_template',
|
||||
'conversation_updates',
|
||||
'cookies',
|
||||
'create_api_key',
|
||||
'delete_service_template',
|
||||
'delivery_and_failure',
|
||||
'delivery_status_callback',
|
||||
'design_content',
|
||||
'download_agreement',
|
||||
'download_notifications_csv',
|
||||
'edit_organisation_name',
|
||||
'edit_provider',
|
||||
'edit_service_template',
|
||||
'edit_user_org_permissions',
|
||||
'edit_user_permissions',
|
||||
'email_not_received',
|
||||
'email_template',
|
||||
'error',
|
||||
'forgot_password',
|
||||
'get_example_csv',
|
||||
'get_notifications_as_json',
|
||||
'go_to_dashboard_after_tour',
|
||||
'inbound_sms_admin',
|
||||
'inbox',
|
||||
'inbox_download',
|
||||
'inbox_updates',
|
||||
'index',
|
||||
'information_risk_management',
|
||||
'information_security',
|
||||
'invite_org_user',
|
||||
'invite_user',
|
||||
'letter_jobs',
|
||||
'link_service_to_organisation',
|
||||
'manage_org_users',
|
||||
'manage_users',
|
||||
'monthly',
|
||||
'new_password',
|
||||
'old_integration_testing',
|
||||
'old_roadmap',
|
||||
'old_service_dashboard',
|
||||
'old_terms',
|
||||
'old_using_notify',
|
||||
'organisation_dashboard',
|
||||
'organisation_settings',
|
||||
'received_text_messages_callback',
|
||||
'redact_template',
|
||||
'register',
|
||||
'register_from_invite',
|
||||
'register_from_org_invite',
|
||||
'registration_continue',
|
||||
'remove_user_from_organisation',
|
||||
'remove_user_from_service',
|
||||
'request_to_go_live',
|
||||
'resend_email_link',
|
||||
'resend_email_verification',
|
||||
'resume_service',
|
||||
'revoke_api_key',
|
||||
'send_messages',
|
||||
'send_notification',
|
||||
'send_one_off',
|
||||
'send_one_off_step',
|
||||
'send_test',
|
||||
'send_test_preview',
|
||||
'send_test_step',
|
||||
'service_add_email_reply_to',
|
||||
'service_add_letter_contact',
|
||||
'service_add_sms_sender',
|
||||
'service_dashboard',
|
||||
'service_dashboard_updates',
|
||||
'service_edit_email_reply_to',
|
||||
'service_edit_letter_contact',
|
||||
'service_edit_sms_sender',
|
||||
'service_email_reply_to',
|
||||
'service_letter_contact_details',
|
||||
'service_name_change',
|
||||
'service_name_change_confirm',
|
||||
'service_set_auth_type',
|
||||
'service_set_email',
|
||||
'service_set_email_branding',
|
||||
'service_set_inbound_number',
|
||||
'service_set_inbound_sms',
|
||||
'service_set_international_sms',
|
||||
'service_set_letter_contact_block',
|
||||
'service_set_letters',
|
||||
'service_set_reply_to_email',
|
||||
'service_set_sms',
|
||||
'service_set_sms_prefix',
|
||||
'service_settings',
|
||||
'service_sms_senders',
|
||||
'service_switch_can_send_email',
|
||||
'service_switch_can_send_precompiled_letter',
|
||||
'service_switch_can_send_sms',
|
||||
'service_switch_email_auth',
|
||||
'service_switch_live',
|
||||
'service_switch_research_mode',
|
||||
'services_or_dashboard',
|
||||
'set_free_sms_allowance',
|
||||
'set_letter_branding',
|
||||
'set_organisation_type',
|
||||
'set_sender',
|
||||
'set_template_sender',
|
||||
'show_accounts_or_dashboard',
|
||||
'sign_out',
|
||||
'start_job',
|
||||
'start_tour',
|
||||
'styleguide',
|
||||
'submit_request_to_go_live',
|
||||
'temp_service_history',
|
||||
'template_history',
|
||||
'template_usage',
|
||||
'trial_mode',
|
||||
'usage',
|
||||
'view_job',
|
||||
'view_job_csv',
|
||||
'view_job_updates',
|
||||
'view_jobs',
|
||||
'view_letter_notification_as_preview',
|
||||
'view_letter_template_preview',
|
||||
'view_notification',
|
||||
'view_notification_updates',
|
||||
'view_notifications',
|
||||
'view_notifications_csv',
|
||||
'view_template',
|
||||
'view_template_version',
|
||||
'view_template_version_preview',
|
||||
'view_template_versions',
|
||||
'whitelist',
|
||||
}
|
||||
|
||||
|
||||
class MainNavigation(Navigation):
|
||||
|
||||
mapping = {
|
||||
'dashboard': {
|
||||
'conversation',
|
||||
'inbox',
|
||||
'monthly',
|
||||
'service_dashboard',
|
||||
'template_usage',
|
||||
'view_job',
|
||||
'view_jobs',
|
||||
'view_notification',
|
||||
'view_notifications',
|
||||
},
|
||||
'templates': {
|
||||
'action_blocked',
|
||||
'add_service_template',
|
||||
'add_template_by_type',
|
||||
'check_messages',
|
||||
'check_notification',
|
||||
'choose_template',
|
||||
'confirm_redact_template',
|
||||
'conversation_reply',
|
||||
'delete_service_template',
|
||||
'edit_service_template',
|
||||
'send_messages',
|
||||
'send_one_off',
|
||||
'send_one_off_step',
|
||||
'send_test',
|
||||
'send_test_preview',
|
||||
'send_test_step',
|
||||
'set_sender',
|
||||
'set_template_sender',
|
||||
'view_template',
|
||||
'view_template_version',
|
||||
'view_template_versions',
|
||||
},
|
||||
'team-members': {
|
||||
'edit_user_permissions',
|
||||
'invite_user',
|
||||
'manage_users',
|
||||
'remove_user_from_service',
|
||||
},
|
||||
'usage': {
|
||||
'usage',
|
||||
},
|
||||
'settings': {
|
||||
'link_service_to_organisation',
|
||||
'request_to_go_live',
|
||||
'service_add_email_reply_to',
|
||||
'service_add_letter_contact',
|
||||
'service_add_sms_sender',
|
||||
'service_edit_email_reply_to',
|
||||
'service_edit_letter_contact',
|
||||
'service_edit_sms_sender',
|
||||
'service_email_reply_to',
|
||||
'service_letter_contact_details',
|
||||
'service_name_change',
|
||||
'service_name_change_confirm',
|
||||
'service_set_auth_type',
|
||||
'service_set_email',
|
||||
'service_set_email_branding',
|
||||
'service_set_inbound_number',
|
||||
'service_set_inbound_sms',
|
||||
'service_set_international_sms',
|
||||
'service_set_letter_contact_block',
|
||||
'service_set_letters',
|
||||
'service_set_reply_to_email',
|
||||
'service_set_sms',
|
||||
'service_set_sms_prefix',
|
||||
'service_settings',
|
||||
'service_sms_senders',
|
||||
'set_free_sms_allowance',
|
||||
'set_letter_branding',
|
||||
'set_organisation_type',
|
||||
'submit_request_to_go_live',
|
||||
},
|
||||
'api-integration': {
|
||||
'api_callbacks',
|
||||
'api_documentation',
|
||||
'api_integration',
|
||||
'api_keys',
|
||||
'create_api_key',
|
||||
'delivery_status_callback',
|
||||
'received_text_messages_callback',
|
||||
'revoke_api_key',
|
||||
'whitelist',
|
||||
},
|
||||
}
|
||||
|
||||
exclude = {
|
||||
'accept_invite',
|
||||
'accept_org_invite',
|
||||
'add_organisation',
|
||||
'add_service',
|
||||
'agreement',
|
||||
'archive_service',
|
||||
'bat_phone',
|
||||
'callbacks',
|
||||
'cancel_invited_org_user',
|
||||
'cancel_invited_user',
|
||||
'cancel_job',
|
||||
'check_and_resend_text_code',
|
||||
'check_and_resend_verification_code',
|
||||
'check_messages_preview',
|
||||
'choose_account',
|
||||
'choose_service',
|
||||
'confirm_edit_organisation_name',
|
||||
'conversation_reply_with_template',
|
||||
'conversation_updates',
|
||||
'cookies',
|
||||
'create_email_branding',
|
||||
'delivery_and_failure',
|
||||
'design_content',
|
||||
'documentation',
|
||||
'download_agreement',
|
||||
'download_notifications_csv',
|
||||
'edit_organisation_name',
|
||||
'edit_provider',
|
||||
'edit_user_org_permissions',
|
||||
'email_branding',
|
||||
'email_not_received',
|
||||
'email_template',
|
||||
'error',
|
||||
'features',
|
||||
'feedback',
|
||||
'forgot_password',
|
||||
'get_example_csv',
|
||||
'get_notifications_as_json',
|
||||
'go_to_dashboard_after_tour',
|
||||
'inbound_sms_admin',
|
||||
'inbox_download',
|
||||
'inbox_updates',
|
||||
'index',
|
||||
'information_risk_management',
|
||||
'information_security',
|
||||
'integration_testing',
|
||||
'invite_org_user',
|
||||
'letter_jobs',
|
||||
'live_services',
|
||||
'manage_org_users',
|
||||
'new_password',
|
||||
'old_feedback',
|
||||
'old_integration_testing',
|
||||
'old_roadmap',
|
||||
'old_service_dashboard',
|
||||
'old_submit_feedback',
|
||||
'old_terms',
|
||||
'old_using_notify',
|
||||
'organisation_dashboard',
|
||||
'organisation_settings',
|
||||
'organisations',
|
||||
'platform_admin',
|
||||
'pricing',
|
||||
'redact_template',
|
||||
'register',
|
||||
'register_from_invite',
|
||||
'register_from_org_invite',
|
||||
'registration_continue',
|
||||
'remove_user_from_organisation',
|
||||
'resend_email_link',
|
||||
'resend_email_verification',
|
||||
'resume_service',
|
||||
'roadmap',
|
||||
'security',
|
||||
'send_notification',
|
||||
'service_dashboard_updates',
|
||||
'service_switch_can_send_email',
|
||||
'service_switch_can_send_precompiled_letter',
|
||||
'service_switch_can_send_sms',
|
||||
'service_switch_email_auth',
|
||||
'service_switch_live',
|
||||
'service_switch_research_mode',
|
||||
'services_or_dashboard',
|
||||
'show_accounts_or_dashboard',
|
||||
'sign_in',
|
||||
'sign_out',
|
||||
'start_job',
|
||||
'start_tour',
|
||||
'styleguide',
|
||||
'support',
|
||||
'suspend_service',
|
||||
'temp_service_history',
|
||||
'template_history',
|
||||
'terms',
|
||||
'thanks',
|
||||
'triage',
|
||||
'trial_mode',
|
||||
'trial_services',
|
||||
'two_factor',
|
||||
'two_factor_email',
|
||||
'two_factor_email_sent',
|
||||
'update_email_branding',
|
||||
'user_profile',
|
||||
'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_name',
|
||||
'user_profile_password',
|
||||
'using_notify',
|
||||
'verify',
|
||||
'verify_email',
|
||||
'verify_mobile',
|
||||
'view_job_csv',
|
||||
'view_job_updates',
|
||||
'view_letter_notification_as_preview',
|
||||
'view_letter_template_preview',
|
||||
'view_notification_updates',
|
||||
'view_notifications_csv',
|
||||
'view_provider',
|
||||
'view_providers',
|
||||
'view_template_version_preview',
|
||||
}
|
||||
|
||||
|
||||
class OrgNavigation(Navigation):
|
||||
|
||||
mapping = {
|
||||
'dashboard': {
|
||||
'organisation_dashboard',
|
||||
},
|
||||
'settings': {
|
||||
'confirm_edit_organisation_name',
|
||||
'edit_organisation_name',
|
||||
'organisation_settings',
|
||||
},
|
||||
'team-members': {
|
||||
'edit_user_org_permissions',
|
||||
'invite_org_user',
|
||||
'manage_org_users',
|
||||
'remove_user_from_organisation',
|
||||
}
|
||||
}
|
||||
|
||||
exclude = {
|
||||
'accept_invite',
|
||||
'accept_org_invite',
|
||||
'action_blocked',
|
||||
'add_organisation',
|
||||
'add_service',
|
||||
'add_service_template',
|
||||
'add_template_by_type',
|
||||
'agreement',
|
||||
'api_callbacks',
|
||||
'api_documentation',
|
||||
'api_integration',
|
||||
'api_keys',
|
||||
'archive_service',
|
||||
'bat_phone',
|
||||
'callbacks',
|
||||
'cancel_invited_org_user',
|
||||
'cancel_invited_user',
|
||||
'cancel_job',
|
||||
'check_and_resend_text_code',
|
||||
'check_and_resend_verification_code',
|
||||
'check_messages',
|
||||
'check_messages_preview',
|
||||
'check_notification',
|
||||
'choose_account',
|
||||
'choose_service',
|
||||
'choose_template',
|
||||
'confirm_redact_template',
|
||||
'conversation',
|
||||
'conversation_reply',
|
||||
'conversation_reply_with_template',
|
||||
'conversation_updates',
|
||||
'cookies',
|
||||
'create_api_key',
|
||||
'create_email_branding',
|
||||
'delete_service_template',
|
||||
'delivery_and_failure',
|
||||
'delivery_status_callback',
|
||||
'design_content',
|
||||
'documentation',
|
||||
'download_agreement',
|
||||
'download_notifications_csv',
|
||||
'edit_provider',
|
||||
'edit_service_template',
|
||||
'edit_user_permissions',
|
||||
'email_branding',
|
||||
'email_not_received',
|
||||
'email_template',
|
||||
'error',
|
||||
'features',
|
||||
'feedback',
|
||||
'forgot_password',
|
||||
'get_example_csv',
|
||||
'get_notifications_as_json',
|
||||
'go_to_dashboard_after_tour',
|
||||
'inbound_sms_admin',
|
||||
'inbox',
|
||||
'inbox_download',
|
||||
'inbox_updates',
|
||||
'index',
|
||||
'information_risk_management',
|
||||
'information_security',
|
||||
'integration_testing',
|
||||
'invite_user',
|
||||
'letter_jobs',
|
||||
'link_service_to_organisation',
|
||||
'live_services',
|
||||
'manage_users',
|
||||
'monthly',
|
||||
'new_password',
|
||||
'old_feedback',
|
||||
'old_integration_testing',
|
||||
'old_roadmap',
|
||||
'old_service_dashboard',
|
||||
'old_submit_feedback',
|
||||
'old_terms',
|
||||
'old_using_notify',
|
||||
'organisations',
|
||||
'platform_admin',
|
||||
'pricing',
|
||||
'received_text_messages_callback',
|
||||
'redact_template',
|
||||
'register',
|
||||
'register_from_invite',
|
||||
'register_from_org_invite',
|
||||
'registration_continue',
|
||||
'remove_user_from_service',
|
||||
'request_to_go_live',
|
||||
'resend_email_link',
|
||||
'resend_email_verification',
|
||||
'resume_service',
|
||||
'revoke_api_key',
|
||||
'roadmap',
|
||||
'security',
|
||||
'send_messages',
|
||||
'send_notification',
|
||||
'send_one_off',
|
||||
'send_one_off_step',
|
||||
'send_test',
|
||||
'send_test_preview',
|
||||
'send_test_step',
|
||||
'service_add_email_reply_to',
|
||||
'service_add_letter_contact',
|
||||
'service_add_sms_sender',
|
||||
'service_dashboard',
|
||||
'service_dashboard_updates',
|
||||
'service_edit_email_reply_to',
|
||||
'service_edit_letter_contact',
|
||||
'service_edit_sms_sender',
|
||||
'service_email_reply_to',
|
||||
'service_letter_contact_details',
|
||||
'service_name_change',
|
||||
'service_name_change_confirm',
|
||||
'service_set_auth_type',
|
||||
'service_set_email',
|
||||
'service_set_email_branding',
|
||||
'service_set_inbound_number',
|
||||
'service_set_inbound_sms',
|
||||
'service_set_international_sms',
|
||||
'service_set_letter_contact_block',
|
||||
'service_set_letters',
|
||||
'service_set_reply_to_email',
|
||||
'service_set_sms',
|
||||
'service_set_sms_prefix',
|
||||
'service_settings',
|
||||
'service_sms_senders',
|
||||
'service_switch_can_send_email',
|
||||
'service_switch_can_send_precompiled_letter',
|
||||
'service_switch_can_send_sms',
|
||||
'service_switch_email_auth',
|
||||
'service_switch_live',
|
||||
'service_switch_research_mode',
|
||||
'services_or_dashboard',
|
||||
'set_free_sms_allowance',
|
||||
'set_letter_branding',
|
||||
'set_organisation_type',
|
||||
'set_sender',
|
||||
'set_template_sender',
|
||||
'show_accounts_or_dashboard',
|
||||
'sign_in',
|
||||
'sign_out',
|
||||
'start_job',
|
||||
'start_tour',
|
||||
'styleguide',
|
||||
'submit_request_to_go_live',
|
||||
'support',
|
||||
'suspend_service',
|
||||
'temp_service_history',
|
||||
'template_history',
|
||||
'template_usage',
|
||||
'terms',
|
||||
'thanks',
|
||||
'triage',
|
||||
'trial_mode',
|
||||
'trial_services',
|
||||
'two_factor',
|
||||
'two_factor_email',
|
||||
'two_factor_email_sent',
|
||||
'update_email_branding',
|
||||
'usage',
|
||||
'user_profile',
|
||||
'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_name',
|
||||
'user_profile_password',
|
||||
'using_notify',
|
||||
'verify',
|
||||
'verify_email',
|
||||
'verify_mobile',
|
||||
'view_job',
|
||||
'view_job_csv',
|
||||
'view_job_updates',
|
||||
'view_jobs',
|
||||
'view_letter_notification_as_preview',
|
||||
'view_letter_template_preview',
|
||||
'view_notification',
|
||||
'view_notification_updates',
|
||||
'view_notifications',
|
||||
'view_notifications_csv',
|
||||
'view_provider',
|
||||
'view_providers',
|
||||
'view_template',
|
||||
'view_template_version',
|
||||
'view_template_version_preview',
|
||||
'view_template_versions',
|
||||
'whitelist',
|
||||
}
|
||||
@@ -40,19 +40,19 @@
|
||||
<a href="#proposition-links" class="js-header-toggle menu">Menu</a>
|
||||
<nav id="proposition-menu">
|
||||
<ul id="proposition-links">
|
||||
<li><a href="{{ url_for('main.support') }}">Support</a></li>
|
||||
<li><a href="{{ url_for('main.support') }}" {{ header_navigation.is_selected('support') }}>Support</a></li>
|
||||
{% if current_user.is_authenticated %}
|
||||
<li><a href="{{ url_for('main.documentation') }}">Documentation</a></li>
|
||||
<li><a href="{{ url_for('main.user_profile') }}">{{ current_user.name }}</a></li>
|
||||
<li><a href="{{ url_for('main.documentation') }}" {{ header_navigation.is_selected('documentation') }}>Documentation</a></li>
|
||||
<li><a href="{{ url_for('main.user_profile') }}" {{ header_navigation.is_selected('user-profile') }}>{{ current_user.name }}</a></li>
|
||||
{% if current_user.platform_admin %}
|
||||
<li><a href="{{ url_for('main.platform_admin') }}">Platform admin</a></li>
|
||||
<li><a href="{{ url_for('main.platform_admin') }}" {{ header_navigation.is_selected('platform-admin') }}>Platform admin</a></li>
|
||||
{% endif %}
|
||||
<li><a href="{{ url_for('main.sign_out')}}">Sign out</a></li>
|
||||
{% else %}
|
||||
<li><a href="{{ url_for('main.features') }}">Features</a></li>
|
||||
<li><a href="{{ url_for('main.pricing' )}}">Pricing</a></li>
|
||||
<li><a href="{{ url_for('main.documentation') }}">Documentation</a></li>
|
||||
<li><a href="{{ url_for('main.sign_in' )}}">Sign in</a></li>
|
||||
<li><a href="{{ url_for('main.features') }}" {{ header_navigation.is_selected('features') }}>Features</a></li>
|
||||
<li><a href="{{ url_for('main.pricing' )}}" {{ header_navigation.is_selected('pricing') }}>Pricing</a></li>
|
||||
<li><a href="{{ url_for('main.documentation') }}" {{ header_navigation.is_selected('documentation') }}>Documentation</a></li>
|
||||
<li><a href="{{ url_for('main.sign_in' )}}" {{ header_navigation.is_selected('sign-in') }}>Sign in</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
@@ -43,19 +43,19 @@
|
||||
{% else %}
|
||||
<nav class="navigation">
|
||||
<ul>
|
||||
<li><a href="{{ url_for('.service_dashboard', service_id=current_service.id) }}">Dashboard</a></li>
|
||||
<li><a href="{{ url_for('.service_dashboard', service_id=current_service.id) }}" {{ main_navigation.is_selected('dashboard') }}>Dashboard</a></li>
|
||||
{% if current_user.has_permissions('view_activity') %}
|
||||
<li><a href="{{ url_for('.choose_template', service_id=current_service.id) }}">Templates</a></li>
|
||||
<li><a href="{{ url_for('.choose_template', service_id=current_service.id) }}" {{ main_navigation.is_selected('templates') }}>Templates</a></li>
|
||||
{% endif %}
|
||||
<li><a href="{{ url_for('.manage_users', service_id=current_service.id) }}">Team members</a></li>
|
||||
<li><a href="{{ url_for('.manage_users', service_id=current_service.id) }}" {{ main_navigation.is_selected('team-members') }}>Team members</a></li>
|
||||
{% if current_user.has_permissions('manage_service') %}
|
||||
<li><a href="{{ url_for('.usage', service_id=current_service.id) }}">Usage</a></li>
|
||||
<li><a href="{{ url_for('.usage', service_id=current_service.id) }}" {{ main_navigation.is_selected('usage') }}>Usage</a></li>
|
||||
{% endif %}
|
||||
{% if current_user.has_permissions('manage_api_keys', 'manage_service') %}
|
||||
<li><a href="{{ url_for('.service_settings', service_id=current_service.id) }}">Settings</a></li>
|
||||
<li><a href="{{ url_for('.service_settings', service_id=current_service.id) }}" {{ main_navigation.is_selected('settings') }}>Settings</a></li>
|
||||
{% endif %}
|
||||
{% if current_user.has_permissions('manage_api_keys') %}
|
||||
<li><a href="{{ url_for('.api_integration', service_id=current_service.id) }}">API integration</a></li>
|
||||
<li><a href="{{ url_for('.api_integration', service_id=current_service.id) }}" {{ main_navigation.is_selected('api-integration') }}>API integration</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<nav class="navigation">
|
||||
<ul>
|
||||
<li><a href="{{ url_for('.organisation_dashboard', org_id=current_org.id) }}">Dashboard</a></li>
|
||||
<li><a href="{{ url_for('.manage_org_users', org_id=current_org.id) }}">Team members</a></li>
|
||||
<li><a href="{{ url_for('.organisation_settings', org_id=current_org.id) }}">Settings</a></li>
|
||||
<li><a href="{{ url_for('.organisation_dashboard', org_id=current_org.id) }}" {{ org_navigation.is_selected('dashboard') }}>Dashboard</a></li>
|
||||
<li><a href="{{ url_for('.manage_org_users', org_id=current_org.id) }}" {{ org_navigation.is_selected('team-members') }}>Team members</a></li>
|
||||
<li><a href="{{ url_for('.organisation_settings', org_id=current_org.id) }}" {{ org_navigation.is_selected('settings') }}>Settings</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
144
tests/app/test_navigation.py
Normal file
144
tests/app/test_navigation.py
Normal file
@@ -0,0 +1,144 @@
|
||||
import pytest
|
||||
from tests.conftest import ORGANISATION_ID, SERVICE_ONE_ID, app_
|
||||
|
||||
from app.navigation import HeaderNavigation, MainNavigation, OrgNavigation
|
||||
|
||||
all_endpoints = [
|
||||
rule.endpoint for rule in next(app_(None)).url_map.iter_rules()
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('navigation_instance', [
|
||||
MainNavigation(),
|
||||
HeaderNavigation(),
|
||||
OrgNavigation(),
|
||||
])
|
||||
def test_navigation_items_are_properly_defined(navigation_instance):
|
||||
for endpoint in navigation_instance.endpoints_with_navigation:
|
||||
assert (
|
||||
endpoint in all_endpoints
|
||||
), '{} is not a real endpoint (in {}.mapping)'.format(
|
||||
endpoint,
|
||||
type(navigation_instance).__name__
|
||||
)
|
||||
assert (
|
||||
endpoint not in navigation_instance.endpoints_without_navigation
|
||||
), '{} is listed in {}.mapping and {}.exclude'.format(
|
||||
endpoint,
|
||||
type(navigation_instance).__name__,
|
||||
type(navigation_instance).__name__,
|
||||
)
|
||||
assert (
|
||||
navigation_instance.endpoints_with_navigation.count(endpoint) == 1
|
||||
), '{} found more than once in {}.mapping'.format(
|
||||
endpoint,
|
||||
type(navigation_instance).__name__
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('navigation_instance', [
|
||||
MainNavigation(),
|
||||
HeaderNavigation(),
|
||||
OrgNavigation(),
|
||||
])
|
||||
def test_excluded_navigation_items_are_properly_defined(navigation_instance):
|
||||
for endpoint in navigation_instance.endpoints_without_navigation:
|
||||
assert (
|
||||
endpoint in all_endpoints
|
||||
), '{} is not a real endpoint (in {}.exclude)'.format(
|
||||
endpoint,
|
||||
type(navigation_instance).__name__
|
||||
)
|
||||
assert (
|
||||
endpoint not in navigation_instance.endpoints_with_navigation
|
||||
), '{} is listed in {}.exclude and {}.mapping'.format(
|
||||
endpoint,
|
||||
type(navigation_instance).__name__,
|
||||
type(navigation_instance).__name__,
|
||||
)
|
||||
assert (
|
||||
navigation_instance.endpoints_without_navigation.count(endpoint) == 1
|
||||
), '{} found more than once in {}.exclude'.format(
|
||||
endpoint,
|
||||
type(navigation_instance).__name__
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('navigation_instance', [
|
||||
MainNavigation(),
|
||||
HeaderNavigation(),
|
||||
OrgNavigation(),
|
||||
])
|
||||
def test_all_endpoints_are_covered(navigation_instance):
|
||||
for endpoint in all_endpoints:
|
||||
assert endpoint in (
|
||||
navigation_instance.endpoints_with_navigation +
|
||||
navigation_instance.endpoints_without_navigation
|
||||
), '{} is not listed or excluded in {}'.format(
|
||||
endpoint,
|
||||
type(navigation_instance).__name__
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('navigation_instance', [
|
||||
MainNavigation(),
|
||||
HeaderNavigation(),
|
||||
OrgNavigation(),
|
||||
])
|
||||
@pytest.mark.xfail(raises=KeyError)
|
||||
def test_raises_on_invalid_navigation_item(
|
||||
client_request, navigation_instance
|
||||
):
|
||||
navigation_instance.is_selected('foo')
|
||||
|
||||
|
||||
@pytest.mark.parametrize('endpoint, selected_nav_item', [
|
||||
('main.choose_template', 'Templates'),
|
||||
('main.manage_users', 'Team members'),
|
||||
])
|
||||
def test_a_page_should_nave_selected_navigation_item(
|
||||
client_request,
|
||||
mock_get_service_templates,
|
||||
mock_get_users_by_service,
|
||||
mock_get_invites_for_service,
|
||||
endpoint,
|
||||
selected_nav_item,
|
||||
):
|
||||
page = client_request.get(endpoint, service_id=SERVICE_ONE_ID)
|
||||
selected_nav_items = page.select('.navigation a.selected')
|
||||
assert len(selected_nav_items) == 1
|
||||
assert selected_nav_items[0].text.strip() == selected_nav_item
|
||||
|
||||
|
||||
@pytest.mark.parametrize('endpoint, selected_nav_item', [
|
||||
('main.documentation', 'Documentation'),
|
||||
('main.support', 'Support'),
|
||||
])
|
||||
def test_a_page_should_nave_selected_header_navigation_item(
|
||||
client_request,
|
||||
endpoint,
|
||||
selected_nav_item,
|
||||
):
|
||||
page = client_request.get(endpoint, service_id=SERVICE_ONE_ID)
|
||||
selected_nav_items = page.select('#proposition-links a.active')
|
||||
assert len(selected_nav_items) == 1
|
||||
assert selected_nav_items[0].text.strip() == selected_nav_item
|
||||
|
||||
|
||||
@pytest.mark.parametrize('endpoint, selected_nav_item', [
|
||||
('main.organisation_dashboard', 'Dashboard'),
|
||||
('main.manage_org_users', 'Team members'),
|
||||
])
|
||||
def test_a_page_should_nave_selected_org_navigation_item(
|
||||
client_request,
|
||||
mock_get_organisation,
|
||||
mock_get_organisation_services,
|
||||
mock_get_users_for_organisation,
|
||||
mock_get_invited_users_for_organisation,
|
||||
endpoint,
|
||||
selected_nav_item,
|
||||
):
|
||||
page = client_request.get(endpoint, org_id=ORGANISATION_ID)
|
||||
selected_nav_items = page.select('.navigation a.selected')
|
||||
assert len(selected_nav_items) == 1
|
||||
assert selected_nav_items[0].text.strip() == selected_nav_item
|
||||
Reference in New Issue
Block a user