global action trigger confirmation (#58122) #776
|
@ -835,6 +835,45 @@ def test_backoffice_multi_actions_some_status(pub):
|
|||
assert len(resp.pyquery('[data-status_accepted]')) == 5
|
||||
|
||||
|
||||
def test_backoffice_multi_actions_confirmation(pub):
|
||||
create_superuser(pub)
|
||||
Workflow.wipe()
|
||||
FormDef.wipe()
|
||||
|
||||
workflow = Workflow.get_default_workflow()
|
||||
workflow.id = '2'
|
||||
action = workflow.add_global_action('FOOBAR')
|
||||
jump = action.add_action('jump')
|
||||
jump.status = 'finished'
|
||||
trigger = action.triggers[0]
|
||||
trigger.statuses = ['new']
|
||||
trigger.roles = ['_receiver']
|
||||
trigger.require_confirmation = True
|
||||
workflow.store()
|
||||
|
||||
formdef = FormDef()
|
||||
formdef.name = 'form title'
|
||||
formdef.workflow_roles = {'_receiver': 1}
|
||||
formdef.workflow_id = workflow.id
|
||||
formdef.store()
|
||||
|
||||
formdata = formdef.data_class()()
|
||||
formdata.just_created()
|
||||
formdata.jump_status('accepted')
|
||||
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/management/form-title/?filter=all')
|
||||
assert resp.pyquery('#multi-actions button').attr('data-ask-for-confirmation') == 'true'
|
||||
|
||||
trigger.confirmation_text = 'Ok?'
|
||||
workflow.store()
|
||||
resp = app.get('/backoffice/management/form-title/?filter=all')
|
||||
assert (
|
||||
resp.pyquery('#multi-actions button[ data-ask-for-confirmation]').attr('data-ask-for-confirmation')
|
||||
== 'Ok?'
|
||||
)
|
||||
|
||||
|
||||
def test_backoffice_multi_actions_jump(pub):
|
||||
create_superuser(pub)
|
||||
FormDef.wipe()
|
||||
|
@ -903,6 +942,14 @@ def test_backoffice_multi_actions_jump(pub):
|
|||
assert len(resp.pyquery('[data-status_finished]')) == 7
|
||||
assert len(resp.pyquery('[data-status_accepted]')) == 8
|
||||
|
||||
workflow.get_status('new').items[2].confirmation_text = 'Ok?'
|
||||
workflow.store()
|
||||
resp = app.get('/backoffice/management/form-title/?filter=all')
|
||||
assert (
|
||||
resp.pyquery('#multi-actions button[data-ask-for-confirmation]').attr('data-ask-for-confirmation')
|
||||
== 'Ok?'
|
||||
)
|
||||
|
||||
|
||||
def test_backoffice_multi_actions_jump_same_identifier(pub):
|
||||
create_superuser(pub)
|
||||
|
|
|
@ -2338,7 +2338,9 @@ class FormPage(Directory, TempfileDirectoryMixin):
|
|||
else:
|
||||
attrs['data-visible_all_status'] = 'true'
|
||||
if getattr(action['action'], 'require_confirmation', False):
|
||||
attrs['data-ask-for-confirmation'] = 'true'
|
||||
attrs['data-ask-for-confirmation'] = (
|
||||
getattr(action['action'], 'confirmation_text', None) or 'true'
|
||||
)
|
||||
multi_form.add_submit(
|
||||
'button-action-%s' % action['action'].id, action['action'].name, attrs=attrs
|
||||
)
|
||||
|
|
|
@ -966,6 +966,8 @@ class Workflow(StorableObject):
|
|||
statuses.extend(trigger.statuses or [])
|
||||
functions = [x for x in roles if x in self.roles]
|
||||
roles = [x for x in roles if x not in self.roles]
|
||||
action.require_confirmation = trigger.require_confirmation
|
||||
action.confirmation_text = trigger.confirmation_text
|
||||
if functions or roles:
|
||||
actions.append(
|
||||
{'action': action, 'roles': roles, 'functions': functions, 'statuses': statuses}
|
||||
|
@ -980,6 +982,7 @@ class Workflow(StorableObject):
|
|||
self.name = action.get_label()
|
||||
self.status_action = True
|
||||
self.require_confirmation = action.require_confirmation
|
||||
self.confirmation_text = action.confirmation_text
|
||||
self.action = action
|
||||
|
||||
def is_interactive(self):
|
||||
|
@ -1625,9 +1628,11 @@ class WorkflowGlobalActionManualTrigger(WorkflowGlobalActionTrigger):
|
|||
roles = None
|
||||
statuses = None
|
||||
allow_as_mass_action = True
|
||||
require_confirmation = False
|
||||
confirmation_text = None
|
||||
|
||||
def get_parameters(self):
|
||||
return ('roles', 'statuses', 'allow_as_mass_action')
|
||||
return ('roles', 'statuses', 'allow_as_mass_action', 'require_confirmation', 'confirmation_text')
|
||||
|
||||
def render_as_line(self):
|
||||
parts = [_('Manual')]
|
||||
|
@ -1650,6 +1655,18 @@ class WorkflowGlobalActionManualTrigger(WorkflowGlobalActionTrigger):
|
|||
_(':'),
|
||||
_('Yes') if self.allow_as_mass_action else _('No'),
|
||||
)
|
||||
r += htmltext('<li>%s%s %s</li>') % (
|
||||
_('Require confirmation'),
|
||||
_(':'),
|
||||
_('Yes') if self.require_confirmation else _('No'),
|
||||
)
|
||||
if self.require_confirmation and self.confirmation_text:
|
||||
r += htmltext('<li>%s%s %s</li>') % (
|
||||
_('Custom text for confirmation popup'),
|
||||
_(':'),
|
||||
self.confirmation_text,
|
||||
)
|
||||
|
||||
r += htmltext('</ul>')
|
||||
return r.getvalue()
|
||||
|
||||
|
@ -1683,6 +1700,25 @@ class WorkflowGlobalActionManualTrigger(WorkflowGlobalActionTrigger):
|
|||
title=_('Allow as mass action'),
|
||||
value=self.allow_as_mass_action,
|
||||
)
|
||||
form.add(
|
||||
CheckboxWidget,
|
||||
'require_confirmation',
|
||||
title=_('Require confirmation'),
|
||||
value=self.require_confirmation,
|
||||
attrs={'data-dynamic-display-parent': 'true'},
|
||||
)
|
||||
form.add(
|
||||
StringWidget,
|
||||
'confirmation_text',
|
||||
title=_('Custom text for confirmation popup'),
|
||||
size=100,
|
||||
value=self.confirmation_text,
|
||||
attrs={
|
||||
'data-dynamic-display-child-of': 'require_confirmation',
|
||||
'data-dynamic-display-checked': 'true',
|
||||
},
|
||||
)
|
||||
|
||||
return form
|
||||
|
||||
def roles_export_to_xml(self, item, charset, include_id=False):
|
||||
|
@ -2376,6 +2412,7 @@ class WorkflowGlobalAction(SerieOfActionsMixin):
|
|||
# check action is executable for given formdata and user (appropriate status and roles)
|
||||
current_status_id = (formdata.status or '').removeprefix('wf-')
|
||||
for trigger in self.triggers or []:
|
||||
self.trigger = trigger # attach trigger to action, to have trigger options available in form
|
||||
if trigger.key == 'manual':
|
||||
if trigger.statuses and current_status_id not in trigger.statuses:
|
||||
continue
|
||||
|
@ -2454,6 +2491,9 @@ class WorkflowStatus(SerieOfActionsMixin):
|
|||
widget.backoffice_info_text = action.backoffice_info_text
|
||||
widget.ignore_form_errors = True
|
||||
widget.attrs['formnovalidate'] = 'formnovalidate'
|
||||
if action.trigger.require_confirmation:
|
||||
get_response().add_javascript(['jquery.js', '../../i18n.js', 'qommon.js'])
|
||||
widget.attrs = {'data-ask-for-confirmation': action.trigger.confirmation_text or 'true'}
|
||||
|
||||
if form.widgets or form.submit_widgets:
|
||||
return form
|
||||
|
|
Loading…
Reference in New Issue