admin: redesign list of form options (#8048)
This commit is contained in:
parent
d1884d84f7
commit
70d72878a0
|
@ -1,5 +1,6 @@
|
|||
import datetime
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import StringIO
|
||||
import tarfile
|
||||
|
@ -168,7 +169,13 @@ def test_forms_new():
|
|||
assert formdef.disabled == True
|
||||
assert formdef.last_modification_user_id == 'admin'
|
||||
|
||||
def assert_option_display(resp, label, value):
|
||||
option_line = re.findall('%s.*%s' % (label, value), resp.body, re.DOTALL)
|
||||
assert option_line
|
||||
assert not '</li>' in option_line
|
||||
|
||||
def test_forms_edit():
|
||||
create_superuser()
|
||||
create_role()
|
||||
|
||||
FormDef.wipe()
|
||||
|
@ -181,16 +188,101 @@ def test_forms_edit():
|
|||
resp = app.get('/backoffice/forms/1/')
|
||||
|
||||
# try changing an option
|
||||
assert 'Include confirmation page' in resp.body
|
||||
resp = resp.click(href='options')
|
||||
|
||||
# confirmation page
|
||||
assert_option_display(resp, 'Confirmation Page', 'Enabled')
|
||||
resp = resp.click('Confirmation Page')
|
||||
assert resp.forms[0]['confirmation'].checked
|
||||
resp.forms[0]['confirmation'].checked = False
|
||||
resp = resp.forms[0].submit()
|
||||
assert resp.location == 'http://example.net/backoffice/forms/1/'
|
||||
resp = resp.follow()
|
||||
assert not 'Include confirmation page' in resp.body
|
||||
assert_option_display(resp, 'Confirmation Page', 'Disabled')
|
||||
assert FormDef.get(1).confirmation == False
|
||||
|
||||
# try cancel button
|
||||
resp = resp.click('Confirmation Page')
|
||||
assert resp.forms[0]['confirmation'].checked is False
|
||||
resp.forms[0]['confirmation'].checked = True
|
||||
resp = resp.forms[0].submit('cancel')
|
||||
assert resp.location == 'http://example.net/backoffice/forms/1/'
|
||||
resp = resp.follow()
|
||||
assert_option_display(resp, 'Confirmation Page', 'Disabled')
|
||||
assert FormDef.get(1).confirmation == False
|
||||
|
||||
# history and status
|
||||
assert_option_display(resp, 'History and Status', 'Public')
|
||||
resp = resp.click('History and Status')
|
||||
assert resp.forms[0]['private_status_and_history'].checked is False
|
||||
resp.forms[0]['private_status_and_history'].checked = True
|
||||
resp = resp.forms[0].submit()
|
||||
assert resp.location == 'http://example.net/backoffice/forms/1/'
|
||||
resp = resp.follow()
|
||||
assert_option_display(resp, 'History and Status', 'Private')
|
||||
assert FormDef.get(1).private_status_and_history is True
|
||||
|
||||
# Limit to one form
|
||||
assert_option_display(resp, 'Limit to one form', 'Disabled')
|
||||
resp = resp.click('Limit to one form')
|
||||
assert resp.forms[0]['only_allow_one'].checked is False
|
||||
resp.forms[0]['only_allow_one'].checked = True
|
||||
resp = resp.forms[0].submit()
|
||||
assert resp.location == 'http://example.net/backoffice/forms/1/'
|
||||
resp = resp.follow()
|
||||
assert_option_display(resp, 'Limit to one form', 'Enabled')
|
||||
assert FormDef.get(1).only_allow_one is True
|
||||
|
||||
# Tracking code
|
||||
assert_option_display(resp, 'Tracking Code', 'Disabled')
|
||||
resp = resp.click('Tracking Code')
|
||||
assert resp.forms[0]['enable_tracking_codes'].checked is False
|
||||
resp.forms[0]['enable_tracking_codes'].checked = True
|
||||
resp = resp.forms[0].submit()
|
||||
assert resp.location == 'http://example.net/backoffice/forms/1/'
|
||||
resp = resp.follow()
|
||||
assert_option_display(resp, 'Tracking Code', 'Enabled')
|
||||
assert FormDef.get(1).enable_tracking_codes is True
|
||||
|
||||
# CAPTCHA
|
||||
assert_option_display(resp, 'CAPTCHA for anonymous users', 'Disabled')
|
||||
resp = resp.click('CAPTCHA for anonymous users')
|
||||
assert resp.forms[0]['has_captcha'].checked is False
|
||||
resp.forms[0]['has_captcha'].checked = True
|
||||
resp = resp.forms[0].submit()
|
||||
assert resp.location == 'http://example.net/backoffice/forms/1/'
|
||||
resp = resp.follow()
|
||||
assert_option_display(resp, 'CAPTCHA for anonymous users', 'Enabled')
|
||||
assert FormDef.get(1).has_captcha is True
|
||||
|
||||
# Publication
|
||||
assert_option_display(resp, 'Online Status', 'Published')
|
||||
resp = resp.click('Online Status')
|
||||
assert resp.forms[0]['disabled'].checked is False
|
||||
resp.forms[0]['disabled'].checked = True
|
||||
resp = resp.forms[0].submit()
|
||||
assert resp.location == 'http://example.net/backoffice/forms/1/'
|
||||
resp = resp.follow()
|
||||
assert_option_display(resp, 'Online Status', 'Disabled')
|
||||
assert FormDef.get(1).disabled is True
|
||||
|
||||
resp = resp.click('Online Status')
|
||||
assert resp.forms[0]['disabled'].checked is True
|
||||
resp.forms[0]['disabled_redirection'] = 'http://www.example.net'
|
||||
resp = resp.forms[0].submit()
|
||||
assert resp.location == 'http://example.net/backoffice/forms/1/'
|
||||
resp = resp.follow()
|
||||
assert_option_display(resp, 'Online Status', 'Redirected')
|
||||
assert FormDef.get(1).disabled is True
|
||||
assert FormDef.get(1).disabled_redirection == 'http://www.example.net'
|
||||
|
||||
resp = resp.click('Online Status')
|
||||
resp.forms[0]['disabled'].checked = False
|
||||
resp.forms[0]['expiration_date'] = '2000-01-01' # this is past(tm)
|
||||
resp = resp.forms[0].submit()
|
||||
assert resp.location == 'http://example.net/backoffice/forms/1/'
|
||||
resp = resp.follow()
|
||||
assert_option_display(resp, 'Online Status', 'Disabled by date')
|
||||
|
||||
# try changing title
|
||||
resp = app.get('/backoffice/forms/1/')
|
||||
resp = resp.click('change title')
|
||||
|
@ -481,18 +573,20 @@ def test_form_always_advertise():
|
|||
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/forms/1/')
|
||||
resp = resp.click(href='options')
|
||||
assert resp.forms[0]['always_advertise'].attrs.get('disabled') is None
|
||||
|
||||
# Display to unlogged users
|
||||
formdef.roles = [role.id]
|
||||
formdef.store()
|
||||
resp = app.get('/backoffice/forms/1/')
|
||||
resp = resp.click(href='options')
|
||||
assert resp.forms[0]['always_advertise'].attrs.get('disabled') is None
|
||||
assert_option_display(resp, 'Display to unlogged users', 'Disabled')
|
||||
resp = resp.click('Display to unlogged users')
|
||||
assert resp.forms[0]['always_advertise'].checked is False
|
||||
resp.forms[0]['always_advertise'].checked = True
|
||||
resp = resp.forms[0].submit()
|
||||
|
||||
assert FormDef.get(formdef.id).always_advertise is True
|
||||
assert resp.location == 'http://example.net/backoffice/forms/1/'
|
||||
resp = resp.follow()
|
||||
assert_option_display(resp, 'Display to unlogged users', 'Enabled')
|
||||
assert FormDef.get(1).always_advertise is True
|
||||
|
||||
def test_form_delete():
|
||||
create_role()
|
||||
|
|
|
@ -130,6 +130,98 @@ class FieldsDirectory(FieldsDirectory):
|
|||
return r.getvalue()
|
||||
|
||||
|
||||
class OptionsDirectory(Directory):
|
||||
_q_exports = ['confirmation', 'private_status', 'only_allow_one',
|
||||
'always_advertise', 'tracking_code', 'online_status', 'captcha']
|
||||
|
||||
def __init__(self, formdef):
|
||||
self.formdef = formdef
|
||||
|
||||
def confirmation(self):
|
||||
form = Form(enctype='multipart/form-data')
|
||||
form.add(CheckboxWidget, 'confirmation', title=_('Include confirmation page'),
|
||||
value=self.formdef.confirmation)
|
||||
return self.handle(form, _('Confirmation Page'))
|
||||
|
||||
def private_status(self):
|
||||
form = Form(enctype='multipart/form-data')
|
||||
form.add(CheckboxWidget, 'private_status_and_history',
|
||||
title=_('Keep workflow status and history private'),
|
||||
hint=_('Restrict the possibility to see status and history to the recipients'),
|
||||
value=self.formdef.private_status_and_history)
|
||||
return self.handle(form, _('History and Status'))
|
||||
|
||||
def only_allow_one(self):
|
||||
form = Form(enctype='multipart/form-data')
|
||||
form.add(CheckboxWidget, 'only_allow_one',
|
||||
title=_('Only allow one form per user'),
|
||||
value=self.formdef.only_allow_one)
|
||||
return self.handle(form, _('Limit to one form'))
|
||||
|
||||
def always_advertise(self):
|
||||
form = Form(enctype='multipart/form-data')
|
||||
form.add(CheckboxWidget, 'always_advertise',
|
||||
title=_('Advertise to unlogged users'),
|
||||
value=self.formdef.always_advertise)
|
||||
return self.handle(form, _('Display to unlogged users'))
|
||||
|
||||
def tracking_code(self):
|
||||
form = Form(enctype='multipart/form-data')
|
||||
form.add(CheckboxWidget, 'enable_tracking_codes',
|
||||
title=_('Enable support for tracking codes'),
|
||||
value=self.formdef.enable_tracking_codes)
|
||||
return self.handle(form, _('Tracking Code'))
|
||||
|
||||
def captcha(self):
|
||||
form = Form(enctype='multipart/form-data')
|
||||
form.add(CheckboxWidget, 'has_captcha',
|
||||
title=_('Prepend a CAPTCHA page for anonymous users'),
|
||||
value=self.formdef.has_captcha)
|
||||
return self.handle(form, _('CAPTCHA'))
|
||||
|
||||
def online_status(self):
|
||||
form = Form(enctype='multipart/form-data')
|
||||
form.add(CheckboxWidget, 'disabled',
|
||||
title=_('Disable access to form'),
|
||||
value=self.formdef.disabled)
|
||||
form.add(StringWidget, 'disabled_redirection',
|
||||
title=_('If disabled, redirect to this URL'), size=40,
|
||||
hint=_('Redirection will only be performed if the form is disabled and a URL is given. '\
|
||||
'Common substitution variables are available with the [variable] syntax.'),
|
||||
value=self.formdef.disabled_redirection)
|
||||
form.add(DateTimeWidget, 'publication_date',
|
||||
title=_('Publication Date'),
|
||||
value=self.formdef.publication_date)
|
||||
form.add(DateTimeWidget, 'expiration_date',
|
||||
title=_('Expiration Date'),
|
||||
value=self.formdef.expiration_date)
|
||||
return self.handle(form, _('Online Status'))
|
||||
|
||||
def handle(self, form, title):
|
||||
form.add_submit('submit', _('Submit'))
|
||||
form.add_submit('cancel', _('Cancel'))
|
||||
if form.get_widget('cancel').parse():
|
||||
return redirect('..')
|
||||
|
||||
if form.is_submitted() and not form.has_errors():
|
||||
attrs = ['confirmation', 'only_allow_one', 'disabled',
|
||||
'enable_tracking_codes', 'private_status_and_history',
|
||||
'always_advertise', 'disabled_redirection',
|
||||
'publication_date', 'expiration_date', 'has_captcha']
|
||||
for f in attrs:
|
||||
widget = form.get_widget(f)
|
||||
if widget:
|
||||
setattr(self.formdef, str(f), widget.parse())
|
||||
self.formdef.store()
|
||||
return redirect('..')
|
||||
|
||||
html_top('forms', title=self.formdef.name)
|
||||
r = TemplateIO(html=True)
|
||||
r += htmltext('<h2>%s</h2>') % title
|
||||
r += form.render()
|
||||
return r.getvalue()
|
||||
|
||||
|
||||
class WorkflowRoleDirectory(Directory):
|
||||
def __init__(self, formdef):
|
||||
self.formdef = formdef
|
||||
|
@ -189,6 +281,7 @@ class FormDefPage(Directory):
|
|||
self.fields.html_top = self.html_top
|
||||
self.role = WorkflowRoleDirectory(self.formdef)
|
||||
self.role.html_top = self.html_top
|
||||
self.options = OptionsDirectory(self.formdef)
|
||||
|
||||
def html_top(self, title):
|
||||
return html_top('forms', title)
|
||||
|
@ -318,32 +411,56 @@ class FormDefPage(Directory):
|
|||
|
||||
r += htmltext('<div class="splitcontent-right">')
|
||||
r += htmltext('<div class="bo-block">')
|
||||
r += htmltext('<h3>%s') % _('Options')
|
||||
r += htmltext(' <span class="change">(<a rel="popup" href="options">%s</a>)</span></h3>') % _('change')
|
||||
r += htmltext('<ul>')
|
||||
if self.formdef.confirmation:
|
||||
r += htmltext('<li>%s</li>') % _('Include confirmation page')
|
||||
if self.formdef.private_status_and_history:
|
||||
r += htmltext('<li>%s</li>') % _('Keep workflow status and history private')
|
||||
if self.formdef.only_allow_one:
|
||||
r += htmltext('<li>%s</li>') % _('Only allow one form per user')
|
||||
if self.formdef.roles and self.formdef.always_advertise:
|
||||
r += htmltext('<li>%s</li>') % _('Advertise to unlogged users')
|
||||
if self.formdef.enable_tracking_codes:
|
||||
r += htmltext('<li>%s</li>') % _('Has support for tracking codes')
|
||||
r += htmltext('<h3>%s</h3>') % _('Options')
|
||||
r += htmltext('<ul class="biglist optionslist">')
|
||||
|
||||
def add_option_line(link, label, current_value):
|
||||
return htmltext(
|
||||
'<li><a rel="popup" href="%(link)s">'
|
||||
'<span class="label">%(label)s</span> '
|
||||
'<span class="value">%(current_value)s</span>'
|
||||
'</a></li>' % {
|
||||
'link': link,
|
||||
'label': label,
|
||||
'current_value': current_value})
|
||||
|
||||
r += add_option_line('options/confirmation', _('Confirmation Page'),
|
||||
self.formdef.confirmation and _('Enabled') or _('Disabled'))
|
||||
|
||||
r += add_option_line('options/private_status',
|
||||
_('History and Status'),
|
||||
self.formdef.private_status_and_history and _('Private') or _('Public'))
|
||||
|
||||
r += add_option_line('options/only_allow_one',
|
||||
_('Limit to one form'),
|
||||
self.formdef.only_allow_one and _('Enabled') or _('Disabled'))
|
||||
|
||||
if self.formdef.roles:
|
||||
r += add_option_line('options/always_advertise',
|
||||
_('Display to unlogged users'),
|
||||
self.formdef.always_advertise and _('Enabled') or _('Disabled'))
|
||||
|
||||
r += add_option_line('options/tracking_code',
|
||||
_('Tracking Code'),
|
||||
self.formdef.enable_tracking_codes and _('Enabled') or _('Disabled'))
|
||||
|
||||
r += add_option_line('options/captcha',
|
||||
_('CAPTCHA for anonymous users'),
|
||||
self.formdef.has_captcha and _('Enabled') or _('Disabled'))
|
||||
|
||||
online_status = _('Published')
|
||||
if self.formdef.disabled:
|
||||
r += htmltext('<li>%s ') % _('Disabled')
|
||||
# manually disabled
|
||||
online_status = _('Disabled')
|
||||
if self.formdef.disabled_redirection:
|
||||
r += htmltext('(<a href="%s">') % self.formdef.disabled_redirection
|
||||
r += _('redirection')
|
||||
r += htmltext('</a>) ')
|
||||
r += htmltext(' (<a href="enable">%s</a>)</li>') % _('enable')
|
||||
if self.formdef.publication_date:
|
||||
r += htmltext('<li>%s</li>') % _('Publication Date: %s') % self.formdef.publication_date
|
||||
if self.formdef.expiration_date:
|
||||
r += htmltext('<li>%s</li>') % _('Expiration Date: %s') % self.formdef.expiration_date
|
||||
if self.formdef.has_captcha:
|
||||
r += htmltext('<li>%s</li>') % _('Add CAPTCHA for anonymous users')
|
||||
online_status = _('Redirected')
|
||||
elif self.formdef.is_disabled():
|
||||
# disabled by date
|
||||
online_status = _('Disabled by date')
|
||||
r += add_option_line('options/online_status',
|
||||
_('Online Status'),
|
||||
online_status)
|
||||
|
||||
r += htmltext('</ul>')
|
||||
r += htmltext('</div>')
|
||||
r += htmltext('</div>')
|
||||
|
@ -583,67 +700,6 @@ class FormDefPage(Directory):
|
|||
r += form.render()
|
||||
return r.getvalue()
|
||||
|
||||
def options(self):
|
||||
form = Form(enctype='multipart/form-data')
|
||||
form.add(CheckboxWidget, 'confirmation', title=_('Include confirmation page'),
|
||||
value=self.formdef.confirmation)
|
||||
form.add(CheckboxWidget, 'private_status_and_history',
|
||||
title=_('Keep workflow status and history private'),
|
||||
hint=_('Restrict the possibility to see status and history to the recipients'),
|
||||
value=self.formdef.private_status_and_history)
|
||||
form.add(CheckboxWidget, 'only_allow_one',
|
||||
title=_('Only allow one form per user'),
|
||||
value=self.formdef.only_allow_one)
|
||||
kwargs = {}
|
||||
form.add(CheckboxWidget, 'always_advertise',
|
||||
title=_('Advertise to unlogged users'),
|
||||
value=self.formdef.always_advertise,
|
||||
**kwargs)
|
||||
form.add(CheckboxWidget, 'enable_tracking_codes',
|
||||
title=_('Enable support for tracking codes'),
|
||||
value=self.formdef.enable_tracking_codes)
|
||||
form.add(CheckboxWidget, 'disabled',
|
||||
title=_('Disable access to form'),
|
||||
value=self.formdef.disabled)
|
||||
form.add(StringWidget, 'disabled_redirection',
|
||||
title=_('If disabled, redirect to this URL'), size=40,
|
||||
hint=_('Redirection will only be performed if the form is disabled and a URL is given. '\
|
||||
'Common substitution variables are available with the [variable] syntax.'),
|
||||
value=self.formdef.disabled_redirection)
|
||||
form.add(DateTimeWidget, 'publication_date',
|
||||
title=_('Publication Date'),
|
||||
value=self.formdef.publication_date)
|
||||
form.add(DateTimeWidget, 'expiration_date',
|
||||
title=_('Expiration Date'),
|
||||
value=self.formdef.expiration_date)
|
||||
form.add(CheckboxWidget, 'has_captcha',
|
||||
title=_('Prepend a CAPTCHA page for anonymous users'),
|
||||
value=self.formdef.has_captcha)
|
||||
|
||||
form.add_submit('submit', _('Submit'))
|
||||
form.add_submit('cancel', _('Cancel'))
|
||||
if form.get_widget('cancel').parse():
|
||||
return redirect('.')
|
||||
|
||||
if form.is_submitted() and not form.has_errors():
|
||||
attrs = ['confirmation', 'only_allow_one', 'disabled',
|
||||
'enable_tracking_codes', 'private_status_and_history',
|
||||
'disabled_redirection', 'publication_date',
|
||||
'expiration_date', 'always_advertise', 'has_captcha']
|
||||
for f in attrs:
|
||||
widget = form.get_widget(f)
|
||||
if widget:
|
||||
setattr(self.formdef, str(f), widget.parse())
|
||||
self.formdef.store()
|
||||
return redirect('.')
|
||||
|
||||
get_response().breadcrumb.append( ('options', _('Options')) )
|
||||
self.html_top(title=self.formdef.name)
|
||||
r = TemplateIO(html=True)
|
||||
r += htmltext('<h2>%s</h2>') % _('Options')
|
||||
r += form.render()
|
||||
return r.getvalue()
|
||||
|
||||
def workflow(self):
|
||||
form = Form(enctype='multipart/form-data')
|
||||
workflows = get_workflows(condition=lambda x: x.possible_status)
|
||||
|
|
|
@ -95,6 +95,10 @@ ul.biglist .details {
|
|||
padding-right: 0.5ex;
|
||||
}
|
||||
|
||||
ul.biglist.optionslist span.value {
|
||||
float: right;
|
||||
}
|
||||
|
||||
ul.themes p.details {
|
||||
display: block;
|
||||
float: none;
|
||||
|
@ -544,6 +548,12 @@ div.bo-block ul.biglist h3 {
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
div.bo-block > h3 {
|
||||
padding: 1ex 0ex;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.bo-block ul.biglist li.disabled {
|
||||
background: none;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue