backoffice: add submission lateral template for from/card (#50436)

This commit is contained in:
Lauréline Guérin 2021-01-25 09:22:55 +01:00
parent 9f80066e0e
commit 2f00983ec3
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
7 changed files with 115 additions and 63 deletions

View File

@ -214,15 +214,18 @@ def test_card_templates(pub):
carddef = CardDef.get(carddef.id)
assert carddef.digest_template == 'X{{form_var_test}}Y'
assert carddef.lateral_template is None
assert carddef.submission_lateral_template is None
assert 'Existing cards will be updated in the background.' in resp.text
resp = app.get('/backoffice/cards/1/options/templates')
resp.form['lateral_template'] = 'X{{form_var_test}}Y'
resp.form['submission_lateral_template'] = 'X{{form_var_test}}YZ'
resp = resp.form.submit().follow()
assert_option_display(resp, 'Templates', 'Custom')
carddef = CardDef.get(carddef.id)
assert carddef.digest_template == 'X{{form_var_test}}Y'
assert carddef.lateral_template == 'X{{form_var_test}}Y'
assert carddef.submission_lateral_template == 'X{{form_var_test}}YZ'
assert 'Existing cards will be updated in the background.' not in resp.text

View File

@ -844,6 +844,7 @@ def test_form_templates(pub):
formdef = FormDef.get(formdef.id)
assert formdef.digest_template == 'X{{form_var_test}}Y'
assert formdef.lateral_template is None
assert formdef.submission_lateral_template is None
assert 'Existing forms will be updated in the background.' in resp.text
# afterjobs are actually run synchronously during tests; we don't have
@ -852,11 +853,13 @@ def test_form_templates(pub):
resp = app.get('/backoffice/forms/1/options/templates')
resp.form['lateral_template'] = 'X{{form_var_test}}Y'
resp.form['submission_lateral_template'] = 'X{{form_var_test}}YZ'
resp = resp.form.submit().follow()
assert_option_display(resp, 'Templates', 'Custom')
formdef = FormDef.get(formdef.id)
assert formdef.digest_template == 'X{{form_var_test}}Y'
assert formdef.lateral_template == 'X{{form_var_test}}Y'
assert formdef.submission_lateral_template == 'X{{form_var_test}}YZ'
assert 'Existing forms will be updated in the background.' not in resp.text

View File

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
import datetime
import os
import re
import time
import pytest
@ -1425,12 +1426,15 @@ def test_backoffice_submission_user_selection_then_live(pub):
fields.PageField(id='0', label='1st page', type='page'),
fields.StringField(id='1', label='Field on 1st page', type='string'),
fields.PageField(id='2', label='2nd page', type='page'),
fields.StringField(id='3', label='Field on 2nd page', type='string',
fields.StringField(
id='3', label='Field on 2nd page', type='string',
varname='plop',
prefill={'type': 'user', 'value': 'email'}),
fields.StringField(id='4', label='2nd field on 2nd page', type='string',
fields.StringField(
id='4', label='2nd field on 2nd page', type='string',
prefill={'type': 'string', 'value': '{{form_user_email}}', 'locked': True}),
fields.StringField(id='5', label='field with condition', type='string',
fields.StringField(
id='5', label='field with condition', type='string',
condition={'type': 'django', 'value': 'form_var_plop == "bye"'}),
]
formdef.backoffice_submission_roles = user.roles[:]
@ -1458,3 +1462,28 @@ def test_backoffice_submission_user_selection_then_live(pub):
resp = resp.form.submit('submit') # -> validation page
assert 'Check values then click submit.' in resp
assert 'altered value' not in resp
def test_backoffice_submission_sidebar_lateral_block(pub):
user = create_user(pub)
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.backoffice_submission_roles = user.roles[:]
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/submission/form-title/')
assert '/lateral-block' not in resp.text
formdef.submission_lateral_template = 'foo bar blah'
formdef.store()
resp = app.get('/backoffice/submission/form-title/')
assert '/lateral-block' in resp.text
lateral_block_url = re.findall('data-async-url="(.*/lateral-block)"', resp.text)[0]
partial_resp = app.get(lateral_block_url)
assert partial_resp.text == '<div class="lateral-block">foo bar blah</div>'

View File

@ -299,6 +299,8 @@ class OptionsDirectory(Directory):
value=self.formdef.digest_template, size=50)
form.add(WysiwygTextWidget, 'lateral_template', title=_('Lateral Block'),
value=self.formdef.lateral_template)
form.add(WysiwygTextWidget, 'submission_lateral_template', title=_('Submission Lateral Block'),
value=self.formdef.submission_lateral_template)
result = self.handle(form, _('Templates'))
if self.changed and self.formdef.data_class().count():
get_response().add_after_job(UpdateDigestAfterJob(formdef=self.formdef))
@ -334,7 +336,8 @@ class OptionsDirectory(Directory):
'description', 'keywords', 'category_id',
'skip_from_360_view', 'geoloc_label', 'appearance_keywords',
'include_download_all_button',
'digest_template', 'lateral_template', 'drafts_lifespan', 'user_support']
'digest_template', 'lateral_template', 'submission_lateral_template',
'drafts_lifespan', 'user_support']
for attr in attrs:
widget = form.get_widget(attr)
if widget:
@ -467,6 +470,17 @@ class FormDefPage(Directory):
def html_top(self, title):
return html_top('forms', title)
def add_option_line(self, link, label, current_value, popup=True):
return htmltext(
'<li><a rel="%(popup)s" href="%(link)s">'
'<span class="label">%(label)s</span> '
'<span class="value">%(current_value)s</span>'
'</a></li>' % {
'popup': 'popup' if popup else '',
'link': link,
'label': label,
'current_value': current_value})
def _q_index(self):
self.html_top(title = self.formdef.name)
r = TemplateIO(html=True)
@ -485,28 +499,17 @@ class FormDefPage(Directory):
r += utils.last_modification_block(obj=self.formdef)
r += get_session().display_message()
def add_option_line(link, label, current_value, popup=True):
return htmltext(
'<li><a rel="%(popup)s" href="%(link)s">'
'<span class="label">%(label)s</span> '
'<span class="value">%(current_value)s</span>'
'</a></li>' % {
'popup': 'popup' if popup else '',
'link': link,
'label': label,
'current_value': current_value})
r += htmltext('<div class="bo-block">')
r += htmltext('<h3>%s</h3>') % _('Information')
r += htmltext('<ul class="biglist optionslist">')
r += add_option_line('options/description', _('Description'),
r += self.add_option_line('options/description', _('Description'),
self.formdef.description and
C_('description|On') or C_('description|None'))
r += add_option_line('options/keywords', _('Keywords'),
r += self.add_option_line('options/keywords', _('Keywords'),
self.formdef.keywords and
self.formdef.keywords or C_('keywords|None'))
r += add_option_line('options/category', _('Category'),
r += self.add_option_line('options/category', _('Category'),
self.formdef.category_id and self.formdef.category and
self.formdef.category.name or C_('category|None'))
r += htmltext('</ul>')
@ -532,18 +535,18 @@ class FormDefPage(Directory):
'workflow_url': self.formdef.workflow.get_admin_url(),
'current_value': self.formdef.workflow.name or '-'})
else:
r += add_option_line('workflow', _('Workflow'),
r += self.add_option_line('workflow', _('Workflow'),
self.formdef.workflow and self.formdef.workflow.name or '-')
if self.formdef.workflow_id:
pristine_workflow = Workflow.get(self.formdef.workflow_id, ignore_errors=True)
if pristine_workflow and pristine_workflow.variables_formdef:
r += add_option_line('workflow-variables', _('Options'), '')
r += self.add_option_line('workflow-variables', _('Options'), '')
elif self.formdef.workflow_options:
# there are no variables defined but there are some values
# in workflow_options, this is probably the legacy stuff.
if any((x for x in self.formdef.workflow_options if '*' in x)):
r += add_option_line('workflow-options', _('Options'), '')
r += self.add_option_line('workflow-options', _('Options'), '')
if self.formdef.workflow.roles:
if not self.formdef.workflow_roles:
@ -561,12 +564,12 @@ class FormDefPage(Directory):
role_label = _('Unknown role (%s)') % role_id
else:
role_label = '-'
r += add_option_line('role/%s' % wf_role_id,
r += self.add_option_line('role/%s' % wf_role_id,
wf_role_label, role_label)
r += add_option_line('roles', _('User Roles'),
r += self.add_option_line('roles', _('User Roles'),
self._get_roles_label_and_auth_context('roles'))
r += add_option_line('backoffice-submission-roles',
r += self.add_option_line('backoffice-submission-roles',
_('Backoffice Submission Role'),
self._get_roles_label('backoffice_submission_roles'))
@ -579,54 +582,53 @@ class FormDefPage(Directory):
r += htmltext('<h3>%s</h3>') % _('Options')
r += htmltext('<ul class="biglist optionslist">')
r += add_option_line('options/confirmation', _('Confirmation Page'),
r += self.add_option_line('options/confirmation', _('Confirmation Page'),
self.formdef.confirmation and
C_('confirmation page|Enabled') or C_('confirmation page|Disabled'))
r += add_option_line('options/only_allow_one',
r += self.add_option_line('options/only_allow_one',
_('Limit to one form'),
self.formdef.only_allow_one and
C_('limit to one|Enabled') or C_('limit to one|Disabled'))
if self.formdef.roles:
r += add_option_line('options/always_advertise',
r += self.add_option_line('options/always_advertise',
_('Display to unlogged users'),
self.formdef.always_advertise and
C_('display to unlogged|Enabled') or C_('display to unlogged|Disabled'))
r += add_option_line('options/management',
r += self.add_option_line('options/management',
_('Management'),
_('Custom') if (self.formdef.skip_from_360_view or
self.formdef.include_download_all_button) else _('Default'))
r += add_option_line('options/tracking_code',
r += self.add_option_line('options/tracking_code',
_('Tracking Code'),
self.formdef.enable_tracking_codes and
C_('tracking code|Enabled') or C_('tracking code|Disabled'))
r += add_option_line('options/geolocations',
r += self.add_option_line('options/geolocations',
_('Geolocation'),
self.formdef.geolocations and
C_('geolocation|Enabled') or C_('geolocation|Disabled'))
if get_publisher().has_site_option('formdef-captcha-option'):
r += add_option_line('options/captcha',
r += self.add_option_line('options/captcha',
_('CAPTCHA for anonymous users'),
self.formdef.has_captcha and
C_('captcha|Enabled') or C_('captcha|Disabled'))
if get_publisher().has_site_option('formdef-appearance-keywords'):
r += add_option_line('options/appearance',
r += self.add_option_line('options/appearance',
_('Appearance'),
self.formdef.appearance_keywords and
self.formdef.appearance_keywords or C_('appearance|Standard'))
if self.formdef.digest_template or self.formdef.lateral_template:
digest_template_status = C_('template|Custom')
if self.formdef.digest_template or self.formdef.lateral_template or self.formdef.submission_lateral_template:
template_status = C_('template|Custom')
else:
digest_template_status = C_('template|None')
r += add_option_line('options/templates',
_('Templates'), digest_template_status, popup=False)
template_status = C_('template|None')
r += self.add_option_line('options/templates', _('Templates'), template_status, popup=False)
online_status = C_('online status|Active')
if self.formdef.disabled:
@ -637,7 +639,7 @@ class FormDefPage(Directory):
elif self.formdef.is_disabled():
# disabled by date
online_status = C_('online status|Inactive by date')
r += add_option_line('options/online_status',
r += self.add_option_line('options/online_status',
_('Online Status'), online_status)
r += htmltext('</ul>')

View File

@ -81,22 +81,11 @@ class CardDefPage(FormDefPage):
r += utils.last_modification_block(obj=self.formdef)
r += get_session().display_message()
def add_option_line(link, label, current_value, popup=True):
return htmltext(
'<li><a rel="%(popup)s" href="%(link)s">'
'<span class="label">%(label)s</span> '
'<span class="value">%(current_value)s</span>'
'</a></li>' % {
'popup': 'popup' if popup else '',
'link': link,
'label': label,
'current_value': current_value})
r += htmltext('<div class="bo-block">')
r += htmltext('<h3>%s</h3>') % _('Information')
r += htmltext('<ul class="biglist optionslist">')
r += add_option_line(
r += self.add_option_line(
'options/category', _('Category'),
self.formdef.category_id and self.formdef.category and
self.formdef.category.name or C_('category|None'))
@ -123,15 +112,15 @@ class CardDefPage(FormDefPage):
'workflow_url': self.formdef.workflow.get_admin_url(),
'current_value': self.formdef.workflow.name or '-'})
else:
r += add_option_line('workflow', _('Workflow'),
r += self.add_option_line('workflow', _('Workflow'),
self.formdef.workflow and self.formdef.workflow.name or '-')
if self.formdef.workflow_id:
pristine_workflow = Workflow.get(self.formdef.workflow_id)
if pristine_workflow.variables_formdef:
r += add_option_line('workflow-variables', _('Options'), '')
r += self.add_option_line('workflow-variables', _('Options'), '')
r += add_option_line('backoffice-submission-roles',
r += self.add_option_line('backoffice-submission-roles',
_('Creation Role'),
self._get_roles_label('backoffice_submission_roles'))
@ -149,7 +138,7 @@ class CardDefPage(FormDefPage):
role_label = _('Unknown role (%s)') % role_id
else:
role_label = '-'
r += add_option_line('role/%s' % wf_role_id,
r += self.add_option_line('role/%s' % wf_role_id,
wf_role_label, role_label)
r += htmltext('</ul>')
@ -161,22 +150,21 @@ class CardDefPage(FormDefPage):
r += htmltext('<h3>%s</h3>') % _('Options')
r += htmltext('<ul class="biglist optionslist">')
r += add_option_line('options/geolocations',
r += self.add_option_line('options/geolocations',
_('Geolocation'),
self.formdef.geolocations and
C_('geolocation|Enabled') or C_('geolocation|Disabled'))
if self.formdef.digest_template or self.formdef.lateral_template:
digest_template_status = C_('template|Custom')
if self.formdef.digest_template or self.formdef.lateral_template or self.formdef.submission_lateral_template:
template_status = C_('template|Custom')
else:
digest_template_status = C_('template|None')
r += add_option_line('options/templates',
_('Templates'), digest_template_status, popup=False)
template_status = C_('template|None')
r += self.add_option_line('options/templates', _('Templates'), template_status, popup=False)
if self.formdef.user_support == 'optional':
user_support_status = C_('user_support|Optional')
else:
user_support_status = C_('user_support|No')
r += add_option_line('options/user_support', _('User support'), user_support_status)
r += self.add_option_line('options/user_support', _('User support'), user_support_status)
r += htmltext('</ul>')
r += htmltext('</div>')

View File

@ -90,7 +90,8 @@ class SubmissionFormStatusPage(FormStatusPage):
class FormFillPage(PublicFormFillPage):
_q_exports = ['', 'tempfile', 'autosave', 'code',
('remove', 'remove_draft'), 'live']
('remove', 'remove_draft'), 'live',
('lateral-block', 'lateral_block')]
filling_templates = ['wcs/formdata_filling.html']
validation_templates = ['wcs/formdata_validation.html']
@ -140,6 +141,11 @@ class FormFillPage(PublicFormFillPage):
self.selected_user_id = get_request().form.get('user_id')
return super(FormFillPage, self)._q_index(*args, **kwargs)
def lateral_block(self):
get_response().filter = {'raw': True}
response = self.get_lateral_block()
return response
def get_transient_formdata(self, magictoken=Ellipsis):
formdata = super().get_transient_formdata(magictoken=magictoken)
if self.selected_user_id:
@ -253,7 +259,18 @@ class FormFillPage(PublicFormFillPage):
)
r += htmltext('</select>')
r += htmltext('</div>')
print('bouh')
if self.formdef.submission_lateral_template:
r += htmltext('<div data-async-url="%slateral-block"></div>' % self.formdef.get_backoffice_submission_url())
return r.getvalue()
def get_lateral_block(self):
r = TemplateIO(html=True)
lateral_block = self.formdef.get_submission_lateral_block()
if lateral_block:
r += htmltext('<div class="lateral-block">')
r += htmltext(lateral_block)
r += htmltext('</div>')
return r.getvalue()
def create_view_form(self, *args, **kwargs):

View File

@ -118,6 +118,7 @@ class FormDef(StorableObject):
appearance_keywords = None
digest_template = None
lateral_template = None
submission_lateral_template = None
drafts_lifespan = None
user_support = None
@ -135,7 +136,8 @@ class FormDef(StorableObject):
TEXT_ATTRIBUTES = ['name', 'url_name', 'description', 'keywords',
'publication_date', 'expiration_date', 'internal_identifier',
'disabled_redirection', 'appearance_keywords',
'digest_template', 'lateral_template', 'drafts_lifespan', 'user_support']
'digest_template', 'lateral_template', 'submission_lateral_template',
'drafts_lifespan', 'user_support']
BOOLEAN_ATTRIBUTES = ['discussion', 'detailed_emails', 'disabled',
'only_allow_one', 'enable_tracking_codes', 'confirmation',
'always_advertise', 'include_download_all_button',
@ -557,6 +559,14 @@ class FormDef(StorableObject):
def get_display_id_format(self):
return '[formdef_id]-[form_number_raw]'
def get_submission_lateral_block(self):
context = self.get_substitution_variables()
if self.submission_lateral_template is None:
new_value = None
else:
new_value = Template(self.submission_lateral_template, autoescape=False).render(context)
return new_value
def create_form(self, page=None, displayed_fields=None, transient_formdata=None):
form = Form(enctype="multipart/form-data", use_tokens=False)
if self.appearance_keywords: