Let caseworkers send one off messages

The main task that we think ‘caseworker’ users do is send one off
messages.

So this commit:
- makes sure users who don’t have the `view_activity` permission (ie
  not ‘admin’ users) can still send messages
- adds navigation so that these users have a place to go from which to
  start the process of sending a one off message
This commit is contained in:
Chris Hill-Scott
2018-06-12 16:17:20 +01:00
parent 2855cf45c7
commit 84de1c5625
11 changed files with 489 additions and 91 deletions

View File

@@ -40,7 +40,12 @@ 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.navigation import (
CaseworkNavigation,
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
@@ -96,6 +101,7 @@ current_service = LocalProxy(partial(_lookup_req_object, 'service'))
current_organisation = LocalProxy(partial(_lookup_req_object, 'organisation'))
navigation = {
'casework_navigation': CaseworkNavigation(),
'main_navigation': MainNavigation(),
'header_navigation': HeaderNavigation(),
'org_navigation': OrgNavigation(),

View File

@@ -42,7 +42,7 @@ from app.utils import (
@main.route("/services/<service_id>/notification/<uuid:notification_id>")
@login_required
@user_has_permissions('view_activity')
@user_has_permissions('view_activity', 'send_messages')
def view_notification(service_id, notification_id):
notification = notification_api_client.get_notification(service_id, str(notification_id))
notification['template'].update({'reply_to_text': notification['reply_to_text']})
@@ -126,7 +126,7 @@ def view_letter_notification_as_preview(service_id, notification_id, filetype):
@main.route("/services/<service_id>/notification/<notification_id>.json")
@user_has_permissions('view_activity')
@user_has_permissions('view_activity', 'send_messages')
def view_notification_updates(service_id, notification_id):
return jsonify(**get_single_notification_partials(
notification_api_client.get_notification(service_id, notification_id)

View File

@@ -41,8 +41,12 @@ page_headings = {
@main.route("/services/<service_id>/templates/<uuid:template_id>")
@login_required
@user_has_permissions('view_activity')
@user_has_permissions('view_activity', 'send_messages')
def view_template(service_id, template_id):
if not current_user.has_permissions('view_activity'):
return redirect(url_for(
'.send_one_off', service_id=service_id, template_id=template_id
))
template = service_api_client.get_service_template(service_id, str(template_id))['data']
if template["template_type"] == "letter":
letter_contact_details = service_api_client.get_letter_contacts(service_id)
@@ -94,7 +98,7 @@ def start_tour(service_id, template_id):
@main.route("/services/<service_id>/templates")
@main.route("/services/<service_id>/templates/<template_type>")
@login_required
@user_has_permissions('view_activity')
@user_has_permissions('view_activity', 'send_messages')
def choose_template(service_id, template_type='all'):
templates = service_api_client.get_service_templates(service_id)['data']
@@ -117,8 +121,14 @@ def choose_template(service_id, template_type='all'):
if template_type in ['all', template['template_type']]
]
if current_user.has_permissions('view_activity'):
page_title = 'Templates'
else:
page_title = 'Choose a template'
return render_template(
'views/templates/choose.html',
page_title=page_title,
templates=templates_on_page,
show_search_box=(len(templates_on_page) > 7),
show_template_nav=has_multiple_template_types and (len(templates) > 2),
@@ -130,7 +140,7 @@ def choose_template(service_id, template_type='all'):
@main.route("/services/<service_id>/templates/<template_id>.<filetype>")
@login_required
@user_has_permissions('view_activity')
@user_has_permissions('view_activity', 'send_messages')
def view_letter_template_preview(service_id, template_id, filetype):
if filetype not in ('pdf', 'png'):
abort(404)

View File

@@ -497,6 +497,225 @@ class MainNavigation(Navigation):
}
class CaseworkNavigation(Navigation):
mapping = {
'send-one-off': {
'choose_template',
'send_one_off',
'send_one_off_step',
'send_test',
'send_test_step',
'view_notification',
},
}
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',
'branding_request',
'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',
'confirm_edit_organisation_name',
'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_organisation_name',
'edit_provider',
'edit_service_template',
'edit_user_org_permissions',
'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_org_user',
'invite_user',
'letter_jobs',
'link_service_to_organisation',
'live_services',
'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',
'organisations',
'platform_admin',
'platform_admin_new',
'platform_admin_list_complaints',
'pricing',
'privacy',
'public_agreement',
'public_download_agreement',
'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',
'roadmap',
'security',
'send_messages',
'send_notification',
'send_test_preview',
'service_add_email_reply_to',
'service_add_letter_contact',
'service_add_sms_sender',
'service_confirm_delete_email_reply_to',
'service_confirm_delete_sms_sender',
'service_dashboard',
'service_dashboard_updates',
'service_delete_email_reply_to',
'service_delete_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_contact_link',
'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_can_upload_document',
'service_switch_caseworking',
'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_updates',
'view_notifications',
'view_notifications_csv',
'view_provider',
'view_providers',
'view_template',
'view_template_version',
'view_template_version_preview',
'view_template_versions',
'whitelist',
}
class OrgNavigation(Navigation):
mapping = {

View File

@@ -1,53 +1,11 @@
{% from "components/banner.html" import banner_wrapper %}
{% if help %}
{% call banner_wrapper(type='tour') %}
<p class="heading-medium">Try sending yourself this example</p>
<div class="grid-row bottom-gutter {% if help != '1' %}greyed-out-step{% endif %}">
<div class="column-one-sixth">
<p class="heading-large" style="float: left;">1.</p>
</div>
<div class="column-five-sixths">
<p>
Every message is sent from a template
</p>
</div>
</div>
<div class="grid-row bottom-gutter {% if help != '2' %}greyed-out-step{% endif %}">
<div class="column-one-sixth">
<p class="heading-large">2.</p>
</div>
<div class="column-five-sixths">
<p>
The template pulls in the data you provide
</p>
</div>
</div>
<div class="grid-row bottom-gutter {% if help != '3' %}greyed-out-step{% endif %}">
<div class="column-one-sixth">
<p class="heading-large">3.</p>
</div>
<div class="column-five-sixths">
<p>
Notify delivers the message
</p>
{% if help == '3' %}
<a href='{{ url_for(".go_to_dashboard_after_tour", service_id=current_service.id, example_template_id=template.id) }}'>
Now go to your dashboard
</a>
{% endif %}
</div>
</div>
{% endcall %}
{% else %}
{% include 'partials/tour.html' %}
{% elif current_user.has_permissions('view_activity') %}
<nav class="navigation">
<ul>
<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) }}" {{ main_navigation.is_selected('templates') }}>Templates</a></li>
{% endif %}
<li><a href="{{ url_for('.manage_users', service_id=current_service.id) }}" {{ main_navigation.is_selected('team-members') }}>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) }}" {{ main_navigation.is_selected('usage') }}>Usage</a></li>
{% endif %}
@@ -59,4 +17,10 @@
{% endif %}
</ul>
</nav>
{% else %}
<nav class="navigation">
<ul>
<li><a href="{{ url_for('.choose_template', service_id=current_service.id) }}" {{ casework_navigation.is_selected('send-one-off') }}>Send a message</a></li>
</ul>
</nav>
{% endif %}

View File

@@ -0,0 +1,40 @@
{% from "components/banner.html" import banner_wrapper %}
{% call banner_wrapper(type='tour') %}
<p class="heading-medium">Try sending yourself this example</p>
<div class="grid-row bottom-gutter {% if help != '1' %}greyed-out-step{% endif %}">
<div class="column-one-sixth">
<p class="heading-large" style="float: left;">1.</p>
</div>
<div class="column-five-sixths">
<p>
Every message is sent from a template
</p>
</div>
</div>
<div class="grid-row bottom-gutter {% if help != '2' %}greyed-out-step{% endif %}">
<div class="column-one-sixth">
<p class="heading-large">2.</p>
</div>
<div class="column-five-sixths">
<p>
The template pulls in the data you provide
</p>
</div>
</div>
<div class="grid-row bottom-gutter {% if help != '3' %}greyed-out-step{% endif %}">
<div class="column-one-sixth">
<p class="heading-large">3.</p>
</div>
<div class="column-five-sixths">
<p>
Notify delivers the message
</p>
{% if help == '3' %}
<a href='{{ url_for(".go_to_dashboard_after_tour", service_id=current_service.id, example_template_id=template.id) }}'>
Now go to your dashboard
</a>
{% endif %}
</div>
</div>
{% endcall %}

View File

@@ -5,15 +5,14 @@
{% extends "withnav_template.html" %}
{% block service_page_title %}
Templates
{{ page_title }}
{% endblock %}
{% block maincolumn_content %}
{% if not templates %}
<h1 class="heading-large">Templates</h1>
<h1 class="heading-large">{{ page_title }}</h1>
{% if current_user.has_permissions('manage_templates') %}
<p class="bottom-gutter">
You need a template before you can send
@@ -39,7 +38,7 @@
<div class="grid-row bottom-gutter-2-3">
<div class="column-two-thirds">
<h1 class="heading-large">Templates</h1>
<h1 class="heading-large">{{ page_title }}</h1>
</div>
{% if current_user.has_permissions('manage_templates') %}
<div class="column-one-third">