Allow setting of caseworking on a user

This commit changes the form that the user sees when inviting or editing
another user, if the service has the ‘caseworking’ permission set.

This will allow creating a new type of user, one who only has the
`send_messages` permission, without the `view_activity` permission.

We are doing this because we think there are a number of services with a
lot of users who don’t need to see the dashboard, or the other team
members, and that we can make a simpler interface for these users.
This commit is contained in:
Chris Hill-Scott
2018-06-12 14:29:47 +01:00
parent d952b5ca3c
commit f4d2958d58
13 changed files with 436 additions and 47 deletions

View File

@@ -0,0 +1,25 @@
(function(Modules) {
"use strict";
Modules.ConditionalRadios = function() {
this.start = function(component) {
const $radios = $('[type=radio]', $(component)),
showHidePanels = function() {
$radios.each(function() {
$('#panel-' + $(this).attr('value'))
.toggleClass(
'js-hidden',
!$(this).is(":checked")
);
});
};
$radios.on('click', showHidePanels);
showHidePanels();
};
};
})(window.GOVUK.Modules);

View File

@@ -0,0 +1,26 @@
$border-thickness: 9px;
.multiple-choice {
z-index: 10;
.block-label {
&:before {
box-shadow: 0 4px 0 0 $white;
}
}
}
.conditional-radios {
&-panel {
border-left: $border-thickness solid $border-colour;
margin: 0 0 0 ($border-thickness + 6px);
padding: $gutter-one-third 0 0 ($gutter - 3px);
position: relative;
top: -$gutter-one-third;
z-index: 1;
}
}

View File

@@ -58,6 +58,7 @@ $path: '/static/images/';
@import 'components/live-search';
@import 'components/stick-at-top-when-scrolling';
@import 'components/fullscreen-table';
@import 'components/conditional-radios';
@import 'components/vendor/breadcrumbs';
@import 'components/vendor/responsive-embed';

View File

@@ -287,6 +287,28 @@ class AdminPermissionsForm(AbstractPermissionsForm):
self.view_activity.data = True
class CaseworkingPermissionsForm(AbstractPermissionsForm):
def process(self, *args, **kwargs):
super().process(*args, **kwargs)
if self.user_type.data == 'admin':
self.view_activity.data = True
elif self.user_type.data == 'caseworker':
self.view_activity.data = False
self.manage_templates.data = False
self.manage_service.data = False
self.manage_api_keys.data = False
self.send_messages.data = True
user_type = RadioField(
'User type',
choices=[
('caseworker', 'Caseworker'),
('admin', 'Admin'),
],
)
class AbstractInviteUserForm(StripWhitespaceForm):
email_address = email_address(gov_user=False)
@@ -303,6 +325,10 @@ class AdminInviteUserForm(AbstractInviteUserForm, AdminPermissionsForm):
pass
class CaseworkingInviteUserForm(AbstractInviteUserForm, CaseworkingPermissionsForm):
pass
class InviteOrgUserForm(StripWhitespaceForm):
email_address = email_address(gov_user=False)

View File

@@ -1,3 +1,5 @@
from functools import partial
from flask import abort, flash, redirect, render_template, request, url_for
from flask_login import current_user, login_required
from notifications_python_client.errors import HTTPError
@@ -12,6 +14,8 @@ from app.main import main
from app.main.forms import (
AdminInviteUserForm,
AdminPermissionsForm,
CaseworkingInviteUserForm,
CaseworkingPermissionsForm,
SearchUsersForm,
)
from app.notify_client.models import roles
@@ -44,9 +48,12 @@ def manage_users(service_id):
@user_has_permissions('manage_service')
def invite_user(service_id):
form = AdminInviteUserForm(
invalid_email_address=current_user.email_address
)
if 'caseworking' in current_service['permissions']:
form = CaseworkingInviteUserForm
else:
form = AdminInviteUserForm
form = form(invalid_email_address=current_user.email_address)
service_has_email_auth = 'email_auth' in current_service['permissions']
if not service_has_email_auth:
@@ -82,10 +89,19 @@ def edit_user_permissions(service_id, user_id):
user = user_api_client.get_user(user_id)
user_has_no_mobile_number = user.mobile_number is None
form = AdminPermissionsForm(
if 'caseworking' in current_service['permissions']:
form = partial(
CaseworkingPermissionsForm,
user_type='admin' if user.has_permission_for_service(service_id, 'view_activity') else 'caseworker',
)
else:
form = AdminPermissionsForm
form = form(
**{role: user.has_permission_for_service(service_id, role) for role in roles.keys()},
login_authentication=user.auth_type
)
if form.validate_on_submit():
user_api_client.set_user_permissions(
user_id, service_id,

View File

@@ -185,7 +185,9 @@ class InvitedUser(object):
return set(self.permissions) > set(permissions)
def has_permission_for_service(self, service_id, permission):
return self.status != 'cancelled' and self.service == service_id and permission in self.permissions
if self.status == 'cancelled' and permission != 'view_activity':
return False
return self.service == service_id and permission in self.permissions
def __eq__(self, other):
return ((self.id,

View File

@@ -135,3 +135,9 @@
</fieldset>
</div>
{% endmacro %}
{% macro conditional_radio_panel(id) %}
<div class="js-hidden panel panel-border-wide conditional-radios-panel" id="panel-{{ id }}">
{{ caller() }}
</div>
{% endmacro %}

View File

@@ -63,22 +63,35 @@
</h3>
<ul class="tick-cross-list">
<div class="tick-cross-list-permissions">
{{ tick_cross(
user.has_permission_for_service(current_service.id, 'send_messages'),
'Send messages'
) }}
{{ tick_cross(
user.has_permission_for_service(current_service.id, 'manage_templates'),
'Add and edit templates'
) }}
{{ tick_cross(
user.has_permission_for_service(current_service.id, 'manage_service'),
'Manage service'
) }}
{{ tick_cross(
user.has_permission_for_service(current_service.id, 'manage_api_keys'),
'Access API keys'
) }}
{% if user.has_permission_for_service(current_service.id, 'view_activity') %}
{% if 'caseworking' in current_service.permissions %}
{{ tick_cross(
user.status != 'cancelled',
'Admin'
) }}
{% endif %}
{{ tick_cross(
user.has_permission_for_service(current_service.id, 'send_messages'),
'Send messages'
) }}
{{ tick_cross(
user.has_permission_for_service(current_service.id, 'manage_templates'),
'Add and edit templates'
) }}
{{ tick_cross(
user.has_permission_for_service(current_service.id, 'manage_service'),
'Manage service'
) }}
{{ tick_cross(
user.has_permission_for_service(current_service.id, 'manage_api_keys'),
'Access API keys'
) }}
{% else %}
{{ tick_cross(
True,
'Caseworker'
) }}
{% endif %}
{% if 'email_auth' in current_service['permissions'] %}
<div class="tick-cross-list-hint">
{% if user.auth_type == 'sms_auth' %}

View File

@@ -1,26 +1,58 @@
{% from "components/checkbox.html" import checkbox %}
{% from "components/radios.html" import radios %}
{% from "components/radios.html" import radio, radios, radios_wrapper, conditional_radio_panel %}
<fieldset class="form-group">
<legend class="form-label">
Permissions
</legend>
{{ checkbox(form.send_messages) }}
{{ checkbox(form.manage_templates) }}
{{ checkbox(form.manage_service) }}
{{ checkbox(form.manage_api_keys) }}
</fieldset>
<div class="bottom-gutter">
<p class="form-label">
All team members can see
</p>
<ul class="list list-bullet">
<li>templates</li>
<li>history of sent messages</li>
<li>who the other team members are</li>
</ul>
</div>
{% if 'caseworking' in current_service.permissions %}
<div data-module="conditional-radios">
{% call radios_wrapper(form.user_type, hide_legend=True) %}
{% for option in form.user_type %}
{{ radio(option) }}
{% if option.data == 'admin' %}
{% call conditional_radio_panel(option.data) %}
<div class="bottom-gutter-1-2">
<p class="form-label">
All admin users can see
</p>
<ul class="list list-bullet">
<li>templates</li>
<li>history of sent messages</li>
<li>who the other team members are</li>
</ul>
</div>
<fieldset class="form-group">
<legend class="form-label">
Permissions
</legend>
{{ checkbox(form.send_messages) }}
{{ checkbox(form.manage_templates) }}
{{ checkbox(form.manage_service) }}
{{ checkbox(form.manage_api_keys) }}
</fieldset>
{% endcall %}
{% endif %}
{% endfor %}
{% endcall %}
</div>
{% else %}
<fieldset class="form-group">
<legend class="form-label">
Permissions
</legend>
{{ checkbox(form.send_messages) }}
{{ checkbox(form.manage_templates) }}
{{ checkbox(form.manage_service) }}
{{ checkbox(form.manage_api_keys) }}
</fieldset>
<div class="bottom-gutter">
<p class="form-label">
All team members can see
</p>
<ul class="list list-bullet">
<li>templates</li>
<li>history of sent messages</li>
<li>who the other team members are</li>
</ul>
</div>
{% endif %}
{% if service_has_email_auth %}
{% if user_has_no_mobile_number %}