workflows: add option for alert position (#19612)

This commit is contained in:
Frédéric Péters 2018-02-11 11:44:28 +01:00
parent 550f2b1465
commit 77c0778f11
7 changed files with 150 additions and 33 deletions

View File

@ -1692,14 +1692,14 @@ def test_workflows_new(pub):
# create a new action
resp = resp.click('new status')
resp.forms[0]['action-interaction'] = 'Top Alert'
resp.forms[0]['action-interaction'] = 'Alert'
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/workflows/1/status/1/'
resp = resp.follow()
assert 'Use drag and drop' in resp.body
# fill action
resp = resp.click('Top Alert')
resp = resp.click('Alert')
resp.forms[0]['message'] = 'bla bla bla'
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/workflows/1/status/1/items/'

View File

@ -3896,3 +3896,65 @@ query_string_allowed_vars = foo,bar
assert resp.location.endswith('/backoffice/submission/test/')
resp = resp.follow()
assert '<p class="comment-field ">django</p>' in resp.body
def test_backoffice_display_message(pub):
user = create_user(pub)
create_environment(pub)
workflow = Workflow(name='test')
st1 = workflow.add_status('Status1', 'st1')
display1 = DisplayMessageWorkflowStatusItem()
display1.message = 'message-to-all'
display1.to = []
st1.items.append(display1)
display1.parent = st1
display2 = DisplayMessageWorkflowStatusItem()
display2.message = 'message-to-submitter'
display2.to = ['_submitter']
st1.items.append(display2)
display2.parent = st1
display3 = DisplayMessageWorkflowStatusItem()
display3.message = 'message-to-receiver'
display3.to = [user.roles[0]]
st1.items.append(display3)
display3.parent = st1
workflow.store()
formdef = FormDef.get_by_urlname('form-title')
formdef.workflow = workflow
formdef.store()
formdata = formdef.data_class().select()[0]
formdata.status = 'wf-st1'
formdata.store()
app = login(get_app(pub))
resp = app.get(formdata.get_url(backoffice=True))
assert 'message-to-all' in resp.body
assert 'message-to-submitter' not in resp.body
assert 'message-to-receiver' in resp.body
# display first message on top of actions
display1.position = 'actions'
workflow.store()
resp = app.get(formdata.get_url(backoffice=True))
assert not 'message-to-all' in resp.body # no actions no message
again = ChoiceWorkflowStatusItem()
again.id = '_again'
again.label = 'Again'
again.by = ['_receiver']
again.status = st1.id
st1.items.append(again)
again.parent = st1
workflow.store()
resp = app.get(formdata.get_url(backoffice=True))
assert 'message-to-all' in resp.body
assert resp.body.index('message-to-all') > resp.body.index('message-to-receiver')

View File

@ -3515,7 +3515,8 @@ def test_display_message(pub):
formdef.data_class().wipe()
page = login(get_app(pub), username='foo', password='foo').get('/test/')
app = login(get_app(pub), username='foo', password='foo')
page = app.get('/test/')
page = page.forms[0].submit('submit') # form page
page = page.forms[0].submit('submit') # confirmation page
page = page.follow()
@ -3524,6 +3525,42 @@ def test_display_message(pub):
assert 'message-to-submitter' in page.body
assert 'message-to-nobody' not in page.body
assert 'message-to-xxx-and-submitter' in page.body
assert page.body.index('message-to-submitter') < page.body.index('message-to-xxx-and-submitter')
assert formdef.data_class().count() == 1
formdata = formdef.data_class().select()[0]
# actions alert vs top alert
display2.position = 'actions'
workflow.store()
page = app.get(formdata.get_url())
assert 'message-to-all' in page.body
assert 'message-to-submitter' not in page.body
assert 'message-to-xxx-and-submitter' in page.body
# add an action, so display2 will appear again
jump1 = ChoiceWorkflowStatusItem()
jump1.id = '_jump1'
jump1.label = 'Jump 1'
jump1.by = ['_submitter']
jump1.status = st1.id
jump1.parent = st1
st1.items.append(jump1)
workflow.store()
page = app.get(formdata.get_url())
assert 'message-to-all' in page.body
assert 'message-to-submitter' in page.body
assert 'message-to-xxx-and-submitter' in page.body
assert page.body.index('message-to-submitter') > page.body.index('message-to-xxx-and-submitter')
jump1.by = ['xxx']
workflow.store()
page = app.get(formdata.get_url())
assert 'message-to-all' in page.body
assert 'message-to-submitter' not in page.body
assert 'message-to-xxx-and-submitter' in page.body
def test_session_cookie_flags(pub):
formdef = create_formdef()

View File

@ -435,14 +435,14 @@ class FormData(StorableObject):
url = perform_items(wf_status.items, self)
return url
def get_workflow_messages(self):
def get_workflow_messages(self, position='top'):
wf_status = self.get_status()
if not wf_status:
return []
messages = []
for item in wf_status.items:
if hasattr(item, 'get_message'):
message = item.get_message(self)
message = item.get_message(self, position=position)
if message:
messages.append(message)
return messages

View File

@ -157,12 +157,15 @@ class FormStatusPage(Directory):
anonymise = 'anonymise' in get_request().form
return self.export_to_json(anonymise=anonymise)
def workflow_messages(self):
def workflow_messages(self, position='top'):
if self.formdef.workflow:
workflow_messages = self.filled.get_workflow_messages()
workflow_messages = self.filled.get_workflow_messages(position=position)
if workflow_messages:
r = TemplateIO(html=True)
r += htmltext('<div id="receipt-intro">')
if position == 'top':
r += htmltext('<div id="receipt-intro" class="workflow-messages %s">' % position)
else:
r += htmltext('<div class="workflow-messages %s">' % position)
for workflow_message in workflow_messages:
if workflow_message.startswith('<'):
r += htmltext(workflow_message)
@ -172,6 +175,9 @@ class FormStatusPage(Directory):
return r.getvalue()
return ''
def actions_workflow_messages(self):
return self.workflow_messages(position='actions')
def recorded_message(self):
r = TemplateIO(html=True)
# behaviour if workflow doesn't display any message
@ -490,6 +496,7 @@ class FormStatusPage(Directory):
) % _('(unlock actions)')
r += htmltext('</div>')
if not visitors or me_in_visitors:
r += htmltext(self.actions_workflow_messages())
r += form.render()
self.filled.mark_as_being_visited()
related_user_forms = getattr(self.filled, 'related_user_forms', None) or []

View File

@ -21,7 +21,10 @@
{{ view.receipt|safe }}
{{ view.history|safe }}
{{ workflow_form.render|safe }}
{% if workflow_form %}
{{ view.actions_workflow_messages|safe }}
{{ workflow_form.render|safe }}
{% endif %}
{% if not response.iframe_mode %}
<div class="back-home-button">

View File

@ -2390,41 +2390,46 @@ register_item_class(SendSMSWorkflowStatusItem)
class DisplayMessageWorkflowStatusItem(WorkflowStatusItem):
description = N_('Top Alert')
description = N_('Alert')
key = 'displaymsg'
category = 'interaction'
support_substitution_variables = True
ok_in_global_action = False
to = None
position = 'top'
message = None
def get_line_details(self):
parts = []
if self.position == 'top':
parts.append(_('top of page'))
elif self.position == 'actions':
parts.append(_('top of actions'))
if self.to:
return _('to %s') % self.render_list_of_roles(self.to)
else:
return None
parts.append(_('to %s') % self.render_list_of_roles(self.to))
return ', '.join(parts)
def get_message(self, filled):
if not self.message:
def is_for_current_user(self, filled):
if not self.to:
return True
if not get_request():
return False
user = get_request().user
for role in self.to or []:
if role == '_submitter':
if filled.is_submitter(user):
return True
elif user:
role = get_role_translation(filled, role)
if role in (user.roles or []):
return True
return False
def get_message(self, filled, position='top'):
if not (self.message and self.position == position and self.is_for_current_user(filled)):
return ''
if self.to:
if not get_request():
return ''
user = get_request().user
for role in self.to or []:
if role == '_submitter':
if filled.is_submitter(user):
break
elif user:
role = get_role_translation(filled, role)
if role in (user.roles or []):
break
else:
return ''
dict = {}
dict.update(get_publisher().substitutions.get_context_variables())
dict['date'] = misc.localstrftime(filled.receipt_time)
@ -2435,12 +2440,15 @@ class DisplayMessageWorkflowStatusItem(WorkflowStatusItem):
return Template(self.message, ezt_format=ezt.FORMAT_HTML).render(dict)
def add_parameters_widgets(self, form, parameters, prefix='', formdef=None):
if 'message' in parameters:
form.add(TextWidget, '%smessage' % prefix, title = _('Message'),
value=self.message, cols=80, rows=10,
validation_function=ComputedExpressionWidget.validate_template)
if 'position' in parameters:
form.add(SingleSelectWidget, '%sposition' % prefix, title=_('Position'),
value=self.position,
options=[('top', _('Top of page')), ('actions', _('Top of actions'))])
if 'to' in parameters:
form.add(WidgetList, '%sto' % prefix, title=_('To'),
element_type=SingleSelectWidget,
@ -2451,7 +2459,7 @@ class DisplayMessageWorkflowStatusItem(WorkflowStatusItem):
self.get_list_of_roles(include_logged_in_users=False)})
def get_parameters(self):
return ('message', 'to')
return ('message', 'position', 'to')
def get_message_parameter_view_value(self):
if self.message.startswith('<'):