cards: empty digest template when datasource custom views (#46862)

This commit is contained in:
Lauréline Guérin 2020-10-20 16:57:37 +02:00
parent 0cb5ec3cbc
commit 8b4f0fbbdc
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
4 changed files with 110 additions and 28 deletions

View File

@ -137,6 +137,66 @@ def test_card_workflow_change(pub, studio):
resp = resp.form.submit('submit').follow()
def test_card_digest_template(pub, studio):
create_superuser(pub)
CardDef.wipe()
carddef = CardDef()
carddef.name = 'foo'
carddef.fields = [
fields.StringField(id='1', label='Test', type='string', varname='foo'),
]
carddef.digest_template = 'X{{ form_var_foo }}Y'
carddef.store()
carddef.data_class().wipe()
carddata = carddef.data_class()()
carddata.data = {'1': 'bar'}
carddata.store()
custom_view = pub.custom_view_class()
custom_view.title = 'card view'
custom_view.formdef = carddef
custom_view.columns = {'list': [{'id': 'id'}]}
custom_view.filters = {'filter-1': True, 'filter-1-value': 'FOO'}
custom_view.visibility = 'datasource'
custom_view.store()
# carddef not used in formdef, it's ok to empty digest_template
FormDef.wipe()
app = login(get_app(pub))
resp = app.get('/backoffice/cards/%s/options/templates' % carddef.id)
resp.form['digest_template'] = ''
resp = resp.form.submit().follow()
carddef = CardDef.get(carddef.id)
assert carddef.digest_template is None
assert 'Existing cards will be updated in the background.' in resp.text
carddef.digest_template = '{{ form_var_foo }}'
carddef.store()
# a formdef using the carddef as datasource
FormDef.wipe()
formdef = FormDef()
formdef.name = 'test card def on data source'
formdef.fields = [
fields.ItemField(id='1', label='item', data_source={'type': 'carddef:foo'})
]
formdef.store()
# carddef used in formdef, can not empty digest_template
resp = app.get('/backoffice/cards/%s/options/templates' % carddef.id)
resp.form['digest_template'] = ''
resp = resp.form.submit()
assert 'Can not empty digest template: this card model is used as data source in some forms.' in resp.text
carddef = CardDef.get(carddef.id)
assert carddef.digest_template is not None
# error: not stored, and no after jobs
resp = app.get('/backoffice/cards/%s/' % carddef.id)
assert 'Existing cards will be updated in the background.' not in resp.text
def test_card_custom_view_data_source(pub, studio):
user = create_superuser(pub)
Role.wipe()

View File

@ -40,6 +40,7 @@ from wcs.qommon.misc import C_
from wcs.qommon.afterjobs import AfterJob
from wcs.formdef import FormDef, FormdefImportError, FormdefImportRecoverableError
from wcs.carddef import CardDef
from wcs.categories import Category
from wcs.roles import Role, logged_users_role, get_user_roles
from wcs.workflows import Workflow
@ -279,8 +280,12 @@ class OptionsDirectory(Directory):
for formdata in self.formdef.data_class().select(order_by='id'):
formdata.store()
job = get_response().add_after_job(N_('Updating digests'), update)
get_session().message = ('info',
_('Existing forms will be updated in the background.'))
if isinstance(self.formdef, CardDef):
get_session().message = ('info',
_('Existing cards will be updated in the background.'))
else:
get_session().message = ('info',
_('Existing forms will be updated in the background.'))
return result
def handle(self, form, title):
@ -302,6 +307,10 @@ class OptionsDirectory(Directory):
for attr in attrs:
widget = form.get_widget(attr)
if widget:
if hasattr(self, 'clean_%s' % attr):
has_error = getattr(self, 'clean_%s' % attr)(form)
if has_error:
continue
if attr == 'geoloc_label':
if widget.parse():
self.formdef.geolocations = {'base': widget.parse()}
@ -312,8 +321,9 @@ class OptionsDirectory(Directory):
if getattr(self.formdef, attr, None) != new_value:
self.changed = True
setattr(self.formdef, attr, new_value)
self.formdef.store(comment=_('Changed "%s" parameters') % title)
return redirect('..')
if not form.has_errors():
self.formdef.store(comment=_('Changed "%s" parameters') % title)
return redirect('..')
html_top('forms', title=self.formdef.name)
r = TemplateIO(html=True)
@ -321,6 +331,21 @@ class OptionsDirectory(Directory):
r += form.render()
return r.getvalue()
def clean_digest_template(self, form):
if not isinstance(self.formdef, CardDef):
return False
widget = form.get_widget('digest_template')
new_value = widget.parse()
if new_value:
return False
if any(self.formdef.usage_in_formdefs()):
widget.set_error(_('Can not empty digest template: this card model is used as data source in some forms.'))
return True
return False
class WorkflowRoleDirectory(Directory):
def __init__(self, formdef):

View File

@ -27,7 +27,6 @@ from ..qommon.misc import C_
from ..qommon.storage import NotEqual, Null
from wcs.carddef import CardDef
from wcs.formdef import get_formdefs_of_all_kinds
from wcs.roles import Role
from wcs.workflows import Workflow
from wcs.admin.forms import FormsDirectory, FormDefPage, FormDefUI, html_top
@ -167,8 +166,9 @@ class CardDefPage(FormDefPage):
r += self.get_preview()
r += htmltext('</div>')
formdefs = self.usage_in_formdefs()
formdefs = list(self.formdef.usage_in_formdefs())
if formdefs:
formdefs.sort(key=lambda x: x.name.lower())
r += htmltext('<div class="bo-block">')
r += htmltext('<h3>%s</h3>') % _('Forms')
r += htmltext('<p>%s ') % _('This card model is used as data source in the following forms:')
@ -177,27 +177,6 @@ class CardDefPage(FormDefPage):
r += htmltext('</div>')
return r.getvalue()
def usage_in_formdefs(self):
def is_used_in_formdef(formdef):
for field in formdef.fields or []:
data_source = getattr(field, 'data_source', None)
if not (data_source and data_source.get('type')):
continue
data_source_id = 'carddef:%s' % self.formdef.url_name
if data_source.get('type') == data_source_id:
return True
if data_source.get('type').startswith('%s:' % data_source_id):
# custom view
return True
return False
formdefs = []
for formdef in get_formdefs_of_all_kinds():
if is_used_in_formdef(formdef):
formdefs.append(formdef)
formdefs.sort(key=lambda x: x.name.lower())
return formdefs
def duplicate(self):
response = super(CardDefPage, self).duplicate()
self.formdefui.formdef.disabled = False

View File

@ -22,7 +22,7 @@ from .qommon import _, N_, misc
from .qommon.storage import Contains, Equal, NotEqual, ILike
from wcs.carddata import CardData
from wcs.formdef import FormDef
from wcs.formdef import FormDef, get_formdefs_of_all_kinds
if not hasattr(types, 'ClassType'):
types.ClassType = type
@ -209,3 +209,21 @@ class CardDef(FormDef):
if order_by is None:
items.sort(key=lambda x: misc.simplify(x['text']))
return items
def usage_in_formdefs(self):
def is_used_in_formdef(formdef):
for field in formdef.fields or []:
data_source = getattr(field, 'data_source', None)
if not (data_source and data_source.get('type')):
continue
data_source_id = 'carddef:%s' % self.url_name
if data_source.get('type') == data_source_id:
return True
if data_source.get('type').startswith('%s:' % data_source_id):
# custom view
return True
return False
for formdef in get_formdefs_of_all_kinds():
if is_used_in_formdef(formdef):
yield formdef