forms: add option to control max number of drafts per user (#88237)
gitea/wcs/pipeline/head There was a failure building this commit
Details
gitea/wcs/pipeline/head There was a failure building this commit
Details
This commit is contained in:
parent
0ed9d5d0a0
commit
955f012b3d
|
@ -386,6 +386,7 @@ Une API existe pour récupérer le schéma de données d’un modèle de fiches.
|
||||||
"disabled_redirection" : null,
|
"disabled_redirection" : null,
|
||||||
"discussion" : false,
|
"discussion" : false,
|
||||||
"drafts_lifespan" : null,
|
"drafts_lifespan" : null,
|
||||||
|
"drafts_max_per_user" : null,
|
||||||
"enable_tracking_codes" : false,
|
"enable_tracking_codes" : false,
|
||||||
"expiration_date" : null,
|
"expiration_date" : null,
|
||||||
"fields" : [
|
"fields" : [
|
||||||
|
|
|
@ -284,6 +284,7 @@ def test_forms_edit_tracking_code(pub, formdef):
|
||||||
|
|
||||||
resp = resp.click('Form Tracking')
|
resp = resp.click('Form Tracking')
|
||||||
assert resp.forms[0]['drafts_lifespan'].value == ''
|
assert resp.forms[0]['drafts_lifespan'].value == ''
|
||||||
|
assert resp.forms[0]['drafts_max_per_user'].value == ''
|
||||||
resp = resp.forms[0].submit().follow() # check empty value is ok
|
resp = resp.forms[0].submit().follow() # check empty value is ok
|
||||||
|
|
||||||
resp = resp.click('Form Tracking')
|
resp = resp.click('Form Tracking')
|
||||||
|
@ -297,6 +298,20 @@ def test_forms_edit_tracking_code(pub, formdef):
|
||||||
resp = resp.forms[0].submit().follow()
|
resp = resp.forms[0].submit().follow()
|
||||||
assert FormDef.get(1).drafts_lifespan == '5'
|
assert FormDef.get(1).drafts_lifespan == '5'
|
||||||
|
|
||||||
|
resp = resp.click('Form Tracking')
|
||||||
|
resp.forms[0]['drafts_max_per_user'].value = 'xxx'
|
||||||
|
resp = resp.forms[0].submit()
|
||||||
|
assert 'Maximum must be between 2 and 100 drafts.' in resp
|
||||||
|
resp.forms[0]['drafts_max_per_user'].value = '120'
|
||||||
|
resp = resp.forms[0].submit()
|
||||||
|
assert 'Maximum must be between 2 and 100 drafts.' in resp
|
||||||
|
resp.forms[0]['drafts_max_per_user'].value = '1'
|
||||||
|
resp = resp.forms[0].submit()
|
||||||
|
assert 'Maximum must be between 2 and 100 drafts.' in resp
|
||||||
|
resp.forms[0]['drafts_max_per_user'].value = '3'
|
||||||
|
resp = resp.forms[0].submit().follow()
|
||||||
|
assert FormDef.get(1).drafts_max_per_user == '3'
|
||||||
|
|
||||||
formdef.fields = [
|
formdef.fields = [
|
||||||
fields.StringField(id='1', label='VerifyString'),
|
fields.StringField(id='1', label='VerifyString'),
|
||||||
fields.DateField(id='2', label='VerifyDate'),
|
fields.DateField(id='2', label='VerifyDate'),
|
||||||
|
|
|
@ -414,6 +414,14 @@ def test_form_max_drafts(pub):
|
||||||
|
|
||||||
assert not formdef.data_class().has_key(drafts[0].id) # oldest draft was removed
|
assert not formdef.data_class().has_key(drafts[0].id) # oldest draft was removed
|
||||||
|
|
||||||
|
formdef.drafts_max_per_user = '3'
|
||||||
|
formdef.store()
|
||||||
|
|
||||||
|
resp = app.get('/test/')
|
||||||
|
resp.form['f0'] = 'hello2'
|
||||||
|
resp = resp.form.submit('submit')
|
||||||
|
assert formdef.data_class().count([Equal('status', 'draft')]) == 4
|
||||||
|
|
||||||
|
|
||||||
def test_form_draft_temporary_access_url(pub):
|
def test_form_draft_temporary_access_url(pub):
|
||||||
FormDef.wipe()
|
FormDef.wipe()
|
||||||
|
|
|
@ -30,6 +30,7 @@ from wcs.carddef import CardDef
|
||||||
from wcs.categories import Category
|
from wcs.categories import Category
|
||||||
from wcs.formdef import (
|
from wcs.formdef import (
|
||||||
DRAFTS_DEFAULT_LIFESPAN,
|
DRAFTS_DEFAULT_LIFESPAN,
|
||||||
|
DRAFTS_DEFAULT_MAX_PER_USER,
|
||||||
FormDef,
|
FormDef,
|
||||||
FormdefImportError,
|
FormdefImportError,
|
||||||
FormdefImportRecoverableError,
|
FormdefImportRecoverableError,
|
||||||
|
@ -290,6 +291,23 @@ class OptionsDirectory(Directory):
|
||||||
widget.validation_function = check_lifespan
|
widget.validation_function = check_lifespan
|
||||||
widget.validation_function_error_message = _('Lifespan must be between 2 and 100 days.')
|
widget.validation_function_error_message = _('Lifespan must be between 2 and 100 days.')
|
||||||
|
|
||||||
|
widget = form.add(
|
||||||
|
WcsExtraStringWidget,
|
||||||
|
'drafts_max_per_user',
|
||||||
|
title=_('Maximum number of drafts per user (between 2 and 100)'),
|
||||||
|
value=self.formdef.drafts_max_per_user,
|
||||||
|
hint=_('%s drafts per user by default') % DRAFTS_DEFAULT_MAX_PER_USER,
|
||||||
|
)
|
||||||
|
|
||||||
|
def check_max_per_user(value):
|
||||||
|
try:
|
||||||
|
return bool(int(value) >= 2 and int(value) <= 100)
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
return False
|
||||||
|
|
||||||
|
widget.validation_function = check_max_per_user
|
||||||
|
widget.validation_function_error_message = _('Maximum must be between 2 and 100 drafts.')
|
||||||
|
|
||||||
form.widgets.append(HtmlWidget(htmltext('<h3>%s</h3>') % _('Tracking Code')))
|
form.widgets.append(HtmlWidget(htmltext('<h3>%s</h3>') % _('Tracking Code')))
|
||||||
form.add(
|
form.add(
|
||||||
CheckboxWidget,
|
CheckboxWidget,
|
||||||
|
@ -495,6 +513,7 @@ class OptionsDirectory(Directory):
|
||||||
'id_template',
|
'id_template',
|
||||||
'submission_lateral_template',
|
'submission_lateral_template',
|
||||||
'drafts_lifespan',
|
'drafts_lifespan',
|
||||||
|
'drafts_max_per_user',
|
||||||
'user_support',
|
'user_support',
|
||||||
'management_sidebar_items',
|
'management_sidebar_items',
|
||||||
]
|
]
|
||||||
|
|
|
@ -61,6 +61,7 @@ from .qommon.upload_storage import PicklableUpload
|
||||||
from .roles import logged_users_role
|
from .roles import logged_users_role
|
||||||
|
|
||||||
DRAFTS_DEFAULT_LIFESPAN = 100 # days
|
DRAFTS_DEFAULT_LIFESPAN = 100 # days
|
||||||
|
DRAFTS_DEFAULT_MAX_PER_USER = 5
|
||||||
|
|
||||||
if not hasattr(types, 'ClassType'):
|
if not hasattr(types, 'ClassType'):
|
||||||
types.ClassType = type
|
types.ClassType = type
|
||||||
|
@ -190,6 +191,7 @@ class FormDef(StorableObject):
|
||||||
submission_lateral_template = None
|
submission_lateral_template = None
|
||||||
id_template = None
|
id_template = None
|
||||||
drafts_lifespan = None
|
drafts_lifespan = None
|
||||||
|
drafts_max_per_user = None
|
||||||
user_support = None
|
user_support = None
|
||||||
|
|
||||||
geolocations = None
|
geolocations = None
|
||||||
|
@ -220,6 +222,7 @@ class FormDef(StorableObject):
|
||||||
'submission_lateral_template',
|
'submission_lateral_template',
|
||||||
'id_template',
|
'id_template',
|
||||||
'drafts_lifespan',
|
'drafts_lifespan',
|
||||||
|
'drafts_max_per_user',
|
||||||
'user_support',
|
'user_support',
|
||||||
]
|
]
|
||||||
BOOLEAN_ATTRIBUTES = [
|
BOOLEAN_ATTRIBUTES = [
|
||||||
|
@ -634,6 +637,9 @@ class FormDef(StorableObject):
|
||||||
def get_drafts_lifespan(self):
|
def get_drafts_lifespan(self):
|
||||||
return int(self.drafts_lifespan or DRAFTS_DEFAULT_LIFESPAN)
|
return int(self.drafts_lifespan or DRAFTS_DEFAULT_LIFESPAN)
|
||||||
|
|
||||||
|
def get_drafts_max_per_user(self):
|
||||||
|
return int(self.drafts_max_per_user or DRAFTS_DEFAULT_MAX_PER_USER)
|
||||||
|
|
||||||
_workflow = None
|
_workflow = None
|
||||||
|
|
||||||
def get_workflow(self):
|
def get_workflow(self):
|
||||||
|
|
|
@ -1778,11 +1778,11 @@ class FormPage(Directory, TempfileDirectoryMixin, FormTemplateMixin):
|
||||||
if get_session().mark_anonymous_formdata(filled):
|
if get_session().mark_anonymous_formdata(filled):
|
||||||
get_session().store()
|
get_session().store()
|
||||||
elif new_draft:
|
elif new_draft:
|
||||||
# keep at most 5 drafts per user
|
# keep at most "max_per_user" drafts per user
|
||||||
data_class = self.formdef.data_class()
|
data_class = self.formdef.data_class()
|
||||||
for id in data_class.get_sorted_ids(
|
for id in data_class.get_sorted_ids(
|
||||||
'-last_update_time', [Equal('status', 'draft'), Equal('user_id', str(filled.user_id))]
|
'-last_update_time', [Equal('status', 'draft'), Equal('user_id', str(filled.user_id))]
|
||||||
)[5:]:
|
)[self.formdef.get_drafts_max_per_user() :]:
|
||||||
data_class.remove_object(id)
|
data_class.remove_object(id)
|
||||||
|
|
||||||
if new_draft:
|
if new_draft:
|
||||||
|
|
|
@ -67,6 +67,7 @@
|
||||||
<li><span class="parameter">{% trans "Fields to check after entering the tracking code" %}{% trans ":" %}</span> {{ tracking_code_verify_fields_labels|default:"-" }}</li>
|
<li><span class="parameter">{% trans "Fields to check after entering the tracking code" %}{% trans ":" %}</span> {{ tracking_code_verify_fields_labels|default:"-" }}</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li><span class="parameter">{% trans "Lifespan of drafts (in days)" %}{% trans ":" %}</span> {{ formdef.get_drafts_lifespan }}</li>
|
<li><span class="parameter">{% trans "Lifespan of drafts (in days)" %}{% trans ":" %}</span> {{ formdef.get_drafts_lifespan }}</li>
|
||||||
|
<li><span class="parameter">{% trans "Maximum number of drafts per user" %}{% trans ":" %}</span> {{ formdef.get_drafts_max_per_user }}</li>
|
||||||
<li><span class="parameter">{% trans "Templates" %}</span>
|
<li><span class="parameter">{% trans "Templates" %}</span>
|
||||||
<ul>
|
<ul>
|
||||||
<li><span class="parameter">{% trans "Digest" %}{% trans ":" %}</span> {{ formdef.default_digest_template|default:"-" }}</li>
|
<li><span class="parameter">{% trans "Digest" %}{% trans ":" %}</span> {{ formdef.default_digest_template|default:"-" }}</li>
|
||||||
|
|
Loading…
Reference in New Issue