cards: empty digest template when datasource custom views (#46862)
This commit is contained in:
parent
0cb5ec3cbc
commit
8b4f0fbbdc
|
@ -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()
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue