workflows: add "previously marked status" option as target after edit (#21398) #758

Merged
fpeters merged 1 commits from wip/21398-jump-to-previous-mark-after-edit into main 2023-10-05 09:16:35 +02:00
3 changed files with 74 additions and 24 deletions

View File

@ -2095,6 +2095,58 @@ def test_form_edit_with_internal_id_condition(pub):
assert 'f2' in resp.form.fields
def test_form_edit_action_jump_to_previously_marked(pub):
create_user(pub)
workflow = Workflow(name='test')
st1 = workflow.add_status('Status1')
st2 = workflow.add_status('Status2')
choice = st1.add_action('choice')
choice.label = 'go to status2'
choice.by = ['_submitter']
choice.status = st2.id
choice.set_marker_on_status = True
editable = st2.add_action('editable')
editable.by = ['_submitter']
editable.label = 'edit'
editable.status = '_previous'
workflow.store()
formdef = create_formdef()
formdef.fields = [
fields.StringField(id='1', label='string'),
]
formdef.workflow_id = workflow.id
formdef.store()
formdef.data_class().wipe()
resp = login(get_app(pub), username='foo', password='foo').get('/test/')
resp.forms[0]['f1'] = 'foo'
resp = resp.forms[0].submit('submit') # -> validation
resp = resp.forms[0].submit('submit') # -> submit
resp = resp.follow()
assert 'The form has been recorded' in resp.text
formdata = formdef.data_class().select()[0]
resp = login(get_app(pub), username='foo', password='foo').get(formdata.get_url())
resp = resp.forms[0].submit('button1').follow() # jump
formdata.refresh_from_storage()
assert formdata.status == f'wf-{st2.id}'
resp = resp.forms[0].submit('button1') # edit
resp = resp.follow()
resp.forms[0]['f1'] = 'foo2'
resp = resp.forms[0].submit('submit')
resp = resp.follow()
formdata.refresh_from_storage()
assert formdata.status == f'wf-{st1.id}'
def test_form_count_dispatching(pub):
create_user(pub)

View File

@ -107,11 +107,7 @@ class EditableWorkflowStatusItem(WorkflowStatusItem):
title=_('Status After Edit'),
value=self.status,
hint=_("Don't select any if you don't want status change processing"),
options=[(None, '---', '', {})]
+ [
(x.id, x.name, x.id, {'data-goto-url': x.get_admin_url()})
for x in self.get_workflow().possible_status
],
options=[(None, '---', '', {})] + self.get_possible_target_options(),
)
if 'label' in parameters:
form.add(StringWidget, '%slabel' % prefix, title=_('Button Label'), value=self.label)

View File

@ -3223,6 +3223,26 @@ class WorkflowStatusItem(XmlSerialisable):
markers_stack.append({'status_id': formdata.status[3:]})
formdata.update_workflow_data({'_markers_stack': markers_stack})
def get_possible_target_options(self):
destinations = [
(x.id, x.name, x.id, {'data-goto-url': x.get_admin_url()})
for x in self.get_workflow().possible_status
]
# look for existing jumps that are dropping a mark
workflow = self.get_workflow()
statuses = getattr(workflow, 'possible_status') or []
global_actions = getattr(workflow, 'global_actions') or []
for status in statuses + global_actions:
for item in status.items:
if getattr(item, 'set_marker_on_status', False):
destinations.append(('_previous', _('Previously Marked Status'), '_previous', {}))
break
else:
continue
break
return destinations
def __repr__(self):
parent = getattr(self, 'parent', None) # status or global action
parts = [self.__class__.__name__, str(self.id)]
@ -3245,30 +3265,12 @@ class WorkflowStatusJumpItem(WorkflowStatusItem):
def add_parameters_widgets(self, form, parameters, prefix='', formdef=None, **kwargs):
super().add_parameters_widgets(form, parameters, prefix=prefix, formdef=formdef, **kwargs)
if 'status' in parameters:
destinations = [
(x.id, x.name, x.id, {'data-goto-url': x.get_admin_url()})
for x in self.get_workflow().possible_status
]
# look for existing jumps that are dropping a mark
workflow = self.get_workflow()
statuses = getattr(workflow, 'possible_status') or []
global_actions = getattr(workflow, 'global_actions') or []
for status in statuses + global_actions:
for item in status.items:
if getattr(item, 'set_marker_on_status', False):
destinations.append(('_previous', _('Previously Marked Status'), '_previous', {}))
break
else:
continue
break
form.add(
SingleSelectWidget,
'%sstatus' % prefix,
title=_('Status'),
value=self.status,
options=[(None, '---', '', {})] + destinations,
options=[(None, '---', '', {})] + self.get_possible_target_options(),
)
if 'set_marker_on_status' in parameters: