misc: add support for live block conditions in workflow forms (#86798)

This commit is contained in:
Frédéric Péters 2024-02-09 12:22:41 +01:00
parent 2c68356878
commit ea2744dbc4
3 changed files with 90 additions and 2 deletions

View File

@ -829,3 +829,77 @@ def test_workflow_form_line_details(pub):
fields.BlockField(id='1', label='test', block_slug='foobar', varname='fooblock'),
]
assert display_form.get_line_details() == 'by foorole'
def test_workflow_form_block_condition(pub):
FormDef.wipe()
Workflow.wipe()
BlockDef.wipe()
user = create_user(pub)
block = BlockDef()
block.name = 'foobar'
block.fields = [
fields.StringField(id='123', required=True, label='One', varname='one'),
fields.StringField(
id='234',
required=True,
label='Two',
condition={'type': 'django', 'value': 'block_var_one|startswith:"test"'},
),
]
block.store()
wf = Workflow(name='test')
status = wf.add_status('New', 'st1')
status.items = []
display_form = status.add_action('form', id='_display_form')
display_form.by = ['_submitter']
display_form.varname = 'blah'
display_form.hide_submit_button = False
display_form.formdef = WorkflowFormFieldsFormDef(item=display_form)
display_form.formdef.fields = [
fields.BlockField(id='1', label='test', block_slug='foobar', varname='fooblock', max_items=3),
]
jump = status.add_action('jumponsubmit', id='_jump')
jump.status = status.id
wf.store()
formdef = create_formdef()
formdef.workflow_id = wf.id
formdef.fields = []
formdef.store()
formdef.data_class().wipe()
formdata = formdef.data_class()()
formdata.user_id = user.id
formdata.just_created()
formdata.store()
app = login(get_app(pub), username='foo', password='foo')
resp = app.get(formdata.get_url(backoffice=False))
assert resp.pyquery('[data-widget-name="fblah_1$element0$f234"]').attr.style == 'display: none'
live_url = resp.html.find('form').attrs['data-live-url']
live_resp = app.post(live_url + '?modified_field_id[]=123', params=resp.form.submit_fields())
assert live_resp.json['result']['blah_1-234-0']['visible'] is False
resp.form['fblah_1$element0$f123'] = 'test'
live_resp = app.post(live_url + '?modified_field_id[]=123', params=resp.form.submit_fields())
assert live_resp.json['result']['blah_1-234-0']['visible'] is True
resp = resp.form.submit('fblah_1$add_element')
resp = resp.form.submit('fblah_1$add_element')
live_resp = app.post(live_url + '?modified_field_id[]=123', params=resp.form.submit_fields())
assert live_resp.json['result']['blah_1-234-0']['visible'] is True
assert live_resp.json['result']['blah_1-234-1']['visible'] is False
assert live_resp.json['result']['blah_1-234-2']['visible'] is False
resp.form['fblah_1$element2$f123'] = 'test3'
live_resp = app.post(live_url + '?modified_field_id[]=123', params=resp.form.submit_fields())
assert live_resp.json['result']['blah_1-234-0']['visible'] is True
assert live_resp.json['result']['blah_1-234-1']['visible'] is False
assert live_resp.json['result']['blah_1-234-2']['visible'] is True

View File

@ -916,11 +916,13 @@ class FormStatusPage(Directory, FormTemplateMixin):
yield (widget.field, block_row, field_widget.field, field_widget)
block_row += 1
# get dictionary with blocks data, from workflow form, or defaults to formdata
blocks_formdata_data = getattr(form, 'blocks_formdata_data', formdata.data)
for block, block_row, field, widget in get_all_field_widgets(form):
t0 = time.time()
if block:
try:
block_data = formdata.data.get(block.id)['data'][block_row]
block_data = blocks_formdata_data.get(block.id)['data'][block_row]
except (IndexError, TypeError):
block_data = {}
@ -1015,7 +1017,8 @@ class FormStatusPage(Directory, FormTemplateMixin):
if form is None:
return result_error('no more form')
self.filled.evaluate_live_workflow_form(user, form)
with get_publisher().keep_all_block_rows():
self.filled.evaluate_live_workflow_form(user, form)
get_publisher().substitutions.unfeed(lambda x: x is self.filled)
get_publisher().substitutions.feed(self.filled)
# reevaluate workflow form according to possible new content

View File

@ -327,6 +327,16 @@ class FormWorkflowStatusItem(WorkflowStatusItem):
self.formdef.set_live_condition_sources(form, self.formdef.fields)
if (
formdata.evolution
and formdata.evolution[-1].parts
and isinstance(formdata.evolution[-1].parts[-1], WorkflowFormEvolutionPart)
and formdata.evolution[-1].parts[-1].live
):
# attach live evaluated data to form object, to be used in live_process_fields
# for block conditions.
form.blocks_formdata_data = formdata.evolution[-1].parts[-1].data
if form.is_submitted():
# skip prefilling part when form is being submitted
return
@ -356,6 +366,7 @@ class FormWorkflowStatusItem(WorkflowStatusItem):
formdata.evolution[-1].add_part(
WorkflowFormEvolutionPart(self, formdef_data, live=bool(not submit))
)
form.formdata_data = formdef_data
def submit_form(self, form, formdata, user, evo):
if not self.formdef: