workflows: be explicit about global actions not supporting live forms (#89412)
gitea/wcs/pipeline/head This commit looks good Details

This commit is contained in:
Frédéric Péters 2024-04-11 09:43:34 +02:00
parent 291fea5b8b
commit b25d2b9d75
9 changed files with 73 additions and 7 deletions

View File

@ -2144,6 +2144,63 @@ def test_backoffice_global_interactive_form_with_block(pub):
}
def test_backoffice_global_interactive_no_live_form(pub):
create_user(pub)
FormDef.wipe()
Workflow.wipe()
formdef = FormDef()
formdef.name = 'test global action'
formdef.fields = []
workflow = Workflow(name='test global action jump')
workflow.add_status('st1')
action = workflow.add_global_action('FOOBAR')
trigger = action.triggers[0]
trigger.roles = [x.id for x in pub.role_class.select() if x.name == 'foobar']
form_action = action.add_action('form')
form_action.by = trigger.roles
form_action.varname = 'blah'
form_action.formdef = WorkflowFormFieldsFormDef(item=form_action)
form_action.formdef.fields = [
fields.StringField(id='1', label='Str1', varname='str1'),
fields.StringField(
id='2',
label='Str2',
varname='str2',
condition={'type': 'django', 'value': 'form_workflow_form_blah_var_str1 == "test"'},
),
]
form_action.hide_submit_button = False
workflow.store()
formdef.workflow_id = workflow.id
formdef.workflow_roles = {'_receiver': 1}
formdef.store()
formdata = formdef.data_class()()
formdata.just_created()
formdata.store()
app = login(get_app(pub))
resp = app.get(formdata.get_url(backoffice=True))
resp = resp.form.submit('button-action-1')
resp = resp.follow()
assert 'qommon.forms.js' in resp.text
assert resp.pyquery('form[data-js-features]:not([data-live-url])')
resp.form['fblah_1'] = 'test'
assert 'fblah_2' not in resp.form.fields # not in HTML but hidden with CSS
resp = resp.form.submit('submit').follow()
formdata.refresh_from_storage()
part = list(formdata.iter_evolution_parts(WorkflowFormEvolutionPart))[0]
assert part.data == {'blah_1': 'test'}
def test_backoffice_submission_context(pub):
user = create_user(pub)
create_environment(pub)

View File

@ -1273,7 +1273,8 @@ class FormDefPage(Directory, TempfileDirectoryMixin, DocumentableMixin):
def get_preview(self):
form = Form(action='#', use_tokens=False)
form.attrs['data-backoffice-preview'] = 'on'
form.attrs['data-backoffice-preview'] = 'true'
form.attrs['data-js-features'] = 'true'
on_page = 0
for field in self.formdef.fields:
if getattr(field, 'add_to_form', None):

View File

@ -1125,7 +1125,7 @@ class TestUsersDirectory(Directory):
value='empty',
attrs={'data-dynamic-display-parent': 'true'},
)
form.attrs['data-enable-select2'] = 'on'
form.attrs['data-js-features'] = 'true'
form.add(
JsonpSingleSelectWidget,
'user_id',

View File

@ -928,7 +928,9 @@ class FormDef(StorableObject):
continue
visible = field.is_visible(form_data, self)
if not visible:
if not field.has_live_conditions(self, hidden_varnames=hidden_varnames):
if not getattr(form, 'has_live_form_support', True) or not field.has_live_conditions(
self, hidden_varnames=hidden_varnames
):
# ignore field.varname when checking later conditions for liveness
if field.varname:
hidden_varnames.add(field.varname)

View File

@ -182,9 +182,8 @@ class GlobalInteractiveActionDirectory(Directory, FormTemplateMixin):
# button doesn't match a submit button (for example a "add row" button in a
# fields block)
messages = self.action.get_messages()
form.attrs['data-live-url'] = (
self.formdata.get_url(backoffice=get_request().is_in_backoffice()) + 'live'
)
get_response().add_javascript(['jquery.js', 'qommon.forms.js'])
form.attrs['data-js-features'] = 'true'
context = {
'html_form': form,
'action': self.action,

View File

@ -433,6 +433,7 @@ class FormStatusPage(Directory, FormTemplateMixin):
if form:
form.attrs['data-live-url'] = self.filled.get_url() + 'live'
form.attrs['data-js-features'] = 'true'
return form
def check_submitted_form(self, form):

View File

@ -1044,6 +1044,7 @@ class FormPage(Directory, TempfileDirectoryMixin, FormTemplateMixin):
# and no confirmation page, add native quixote CSRF protection.
form.add(FormTokenWidget, form.TOKEN_NAME)
form.add_hidden('previous-page-id', '')
form.attrs['data-js-features'] = 'true'
form.attrs['data-live-url'] = self.formdef.get_url(language=get_publisher().current_language) + 'live'
form.attrs['data-live-validation-url'] = (
self.formdef.get_url(language=get_publisher().current_language) + 'live-validation'

View File

@ -458,7 +458,7 @@ $(function() {
var known_domains = WCS_VALID_KNOWN_DOMAINS;
}
add_js_behaviours($('form[data-live-url], form[data-backoffice-preview], form[data-enable-select2]'));
add_js_behaviours($('form[data-js-features]'));
last_auto_save = $('form[data-has-draft]').serialize();
// Form with error

View File

@ -2390,6 +2390,7 @@ class WorkflowGlobalActionWebserviceTrigger(WorkflowGlobalActionManualTrigger):
class SerieOfActionsMixin:
items = None
has_live_form_support = True # support for live evaluation in forms
def add_action(self, type, id=None, prepend=False):
if not self.items:
@ -2435,6 +2436,7 @@ class SerieOfActionsMixin:
def get_action_form(self, filled, user, displayed_fields=None):
form = Form(enctype='multipart/form-data', use_tokens=False)
form.has_live_form_support = self.has_live_form_support
form.attrs['id'] = 'wf-actions'
form.add_hidden('_ts', str(filled.last_update_time.timestamp()))
for item in self.items:
@ -2517,6 +2519,7 @@ class WorkflowGlobalAction(SerieOfActionsMixin):
triggers = None
backoffice_info_text = None
documentation = None
has_live_form_support = False
def __init__(self, name=None):
self.name = name
@ -2698,6 +2701,8 @@ class WorkflowStatus(SerieOfActionsMixin):
loop_items_template = None
after_loop_status = None
has_live_form_support = True
def __init__(self, name=None):
self.name = name
self.items = []