Make the broadcast flow talk to the API

This commit removes the code the puts areas into the session and instead
creates and then updates a draft broadcast in the database.

This is so we can avoid session-related bugs, and potentially having a
large session when we start adding personalisation etc.

Once a broadcast is ready to go it is set to `broadcasting` straight
away with no approval. We’ll revisit this as we learn more about how
users might want to manage who can create and approve broadcasts.

The tests are a bit light in terms of checking what’s on the page, but
clicking through the pages is probably good enough for now.
This commit is contained in:
Chris Hill-Scott
2020-07-09 10:33:50 +01:00
parent 2c33325dc2
commit effe24893e
12 changed files with 436 additions and 89 deletions

View File

@@ -1,11 +1,9 @@
from flask import redirect, render_template, request, session, url_for
from notifications_utils.broadcast_areas import broadcast_area_libraries
from notifications_utils.template import BroadcastPreviewTemplate
from orderedset import OrderedSet
from flask import redirect, render_template, request, url_for
from app import current_service
from app.main import main
from app.main.forms import BroadcastAreaForm, SearchByNameForm
from app.models.broadcast_message import BroadcastMessage
from app.utils import service_has_permission, user_has_permissions
@@ -18,63 +16,63 @@ def broadcast_dashboard(service_id):
)
@main.route('/services/<uuid:service_id>/broadcast')
@main.route('/services/<uuid:service_id>/broadcast/<uuid:template_id>')
@user_has_permissions('send_messages')
@service_has_permission('broadcast')
def broadcast(service_id):
if 'broadcast_areas' in session:
session.pop('broadcast_areas')
def broadcast(service_id, template_id):
return redirect(url_for(
'.preview_broadcast_areas',
service_id=current_service.id,
broadcast_message_id=BroadcastMessage.create(
service_id=service_id,
template_id=template_id,
).id,
))
@main.route('/services/<uuid:service_id>/broadcast/areas')
@main.route('/services/<uuid:service_id>/broadcast/<uuid:broadcast_message_id>/areas')
@user_has_permissions('send_messages')
@service_has_permission('broadcast')
def preview_broadcast_areas(service_id):
selected_areas_ids = session.get('broadcast_areas', [])
def preview_broadcast_areas(service_id, broadcast_message_id):
return render_template(
'views/broadcast/preview-areas.html',
selected=list(broadcast_area_libraries.get_areas(
*selected_areas_ids
)),
area_polygons=broadcast_area_libraries.get_polygons_for_areas_lat_long(
*selected_areas_ids
)
)
@main.route('/services/<uuid:service_id>/broadcast/libraries')
@user_has_permissions('send_messages')
@service_has_permission('broadcast')
def choose_broadcast_library(service_id):
return render_template(
'views/broadcast/libraries.html',
libraries=broadcast_area_libraries,
selected=broadcast_area_libraries.get_areas(
*session.get('broadcast_areas', [])
broadcast_message=BroadcastMessage.from_id(
broadcast_message_id,
service_id=current_service.id,
),
)
@main.route('/services/<uuid:service_id>/broadcast/libraries/<library_slug>', methods=['GET', 'POST'])
@main.route('/services/<uuid:service_id>/broadcast/<uuid:broadcast_message_id>/libraries')
@user_has_permissions('send_messages')
@service_has_permission('broadcast')
def choose_broadcast_area(service_id, library_slug):
library = broadcast_area_libraries.get(library_slug)
def choose_broadcast_library(service_id, broadcast_message_id):
return render_template(
'views/broadcast/libraries.html',
libraries=BroadcastMessage.libraries,
broadcast_message_id=broadcast_message_id,
)
@main.route(
'/services/<uuid:service_id>/broadcast/<uuid:broadcast_message_id>/libraries/<library_slug>',
methods=['GET', 'POST'],
)
@user_has_permissions('send_messages')
@service_has_permission('broadcast')
def choose_broadcast_area(service_id, broadcast_message_id, library_slug):
broadcast_message = BroadcastMessage.from_id(
broadcast_message_id,
service_id=current_service.id,
)
library = BroadcastMessage.libraries.get(library_slug)
form = BroadcastAreaForm.from_library(library)
if form.validate_on_submit():
if not session.get('broadcast_areas'):
session['broadcast_areas'] = []
session['broadcast_areas'] = session['broadcast_areas'] + form.areas.data
session['broadcast_areas'] = list(OrderedSet(
session['broadcast_areas']
))
broadcast_message.add_areas(*form.areas.data)
return redirect(url_for(
'.preview_broadcast_areas',
service_id=current_service.id,
broadcast_message_id=broadcast_message.id,
))
return render_template(
'views/broadcast/areas.html',
@@ -85,35 +83,41 @@ def choose_broadcast_area(service_id, library_slug):
)
@main.route('/services/<uuid:service_id>/broadcast/remove/<area_slug>')
@main.route('/services/<uuid:service_id>/broadcast/<uuid:broadcast_message_id>/remove/<area_slug>')
@user_has_permissions('send_messages')
@service_has_permission('broadcast')
def remove_broadcast_area(service_id, area_slug):
session['broadcast_areas'] = list(filter(
lambda saved_area_id: saved_area_id != area_slug,
session.get('broadcast_areas', []),
))
def remove_broadcast_area(service_id, broadcast_message_id, area_slug):
BroadcastMessage.from_id(
broadcast_message_id,
service_id=current_service.id,
).remove_area(
area_slug
)
return redirect(url_for(
'.preview_broadcast_areas',
service_id=current_service.id,
broadcast_message_id=broadcast_message_id,
))
@main.route('/services/<uuid:service_id>/broadcast/preview', methods=['GET', 'POST'])
@main.route(
'/services/<uuid:service_id>/broadcast/<uuid:broadcast_message_id>/preview',
methods=['GET', 'POST'],
)
@user_has_permissions('send_messages')
@service_has_permission('broadcast')
def preview_broadcast_message(service_id):
def preview_broadcast_message(service_id, broadcast_message_id):
broadcast_message = BroadcastMessage.from_id(
broadcast_message_id,
service_id=current_service.id,
)
if request.method == 'POST':
return 'OK'
selected_areas = session.get('broadcast_areas', [])
broadcast_message.start_broadcast()
return redirect(url_for(
'.broadcast_dashboard',
service_id=current_service.id,
))
return render_template(
'views/broadcast/preview-message.html',
selected=list(broadcast_area_libraries.get_areas(
*selected_areas
)),
template=BroadcastPreviewTemplate({
'content': 'Message here',
'template_type': 'broadcast',
})
broadcast_message=broadcast_message,
)