backoffice: inspect, link to action for button wf trace (#86575) #1107

Merged
lguerin merged 1 commits from wip/86575-display-action-id-in-trace into main 2024-02-09 11:56:57 +01:00
6 changed files with 71 additions and 9 deletions

View File

@ -734,7 +734,7 @@ def test_inspect_page_with_related_objects(pub):
def test_inspect_page_actions_traces(pub):
create_user(pub, is_admin=True)
user = create_user(pub, is_admin=True)
FormDef.wipe()
target_formdef = FormDef()
@ -793,6 +793,10 @@ def test_inspect_page_actions_traces(pub):
edit_carddata2.varname = 'edited_card_wrong_target_id'
edit_carddata2.mappings = [Mapping(field_id='0', expression='foo bar blah')]
choice = st1.items[2]
assert choice.key == 'choice'
choice.by = ['logged-users']
workflow.store()
formdef = FormDef()
@ -802,12 +806,19 @@ def test_inspect_page_actions_traces(pub):
formdef.data_class().wipe()
formdata = formdef.data_class()()
formdata.user_id = user.id
formdata.data = {}
formdata.just_created()
formdata.store()
formdata.record_workflow_event('frontoffice-created')
formdata.perform_workflow()
formdata.store()
app = login(get_app(pub))
resp = app.get(formdata.get_url())
resp = resp.form.submit('button_accept')
resp = resp.follow()
formdata.refresh_from_storage()
assert formdata.status == 'wf-accepted'
# change receipt time to get global timeout to run
formdata.receipt_time = time.localtime(time.time() - 3 * 86400)
@ -816,7 +827,6 @@ def test_inspect_page_actions_traces(pub):
formdata.refresh_from_storage()
assert formdata.get_criticality_level_object().name == 'yellow'
app = login(get_app(pub))
resp = app.get(formdata.get_url(backoffice=True), status=200)
resp = resp.click('Data Inspector')
assert '>Actions Tracing</' in resp
@ -826,9 +836,10 @@ def test_inspect_page_actions_traces(pub):
'Created form - target form #1-1',
'Created card - target card #1-1',
'Edited card - target card #1-1',
'Action button - Manual Jump Accept',
'Global action timeout',
]
assert [x.text for x in resp.pyquery('#inspect-timeline strong')] == ['Just Submitted', 'New']
assert [x.text for x in resp.pyquery('#inspect-timeline strong')] == ['Just Submitted', 'New', 'Accepted']
assert [x.text for x in resp.pyquery('#inspect-timeline a.tracing-link') if x.text] == [
'Email',
'Email',
@ -837,6 +848,8 @@ def test_inspect_page_actions_traces(pub):
'Create Card Data',
'Edit Card Data',
'Edit Card Data',
'Email',
'Email',
'Criticality Levels',
]
event_links = [x.attrib['href'] for x in resp.pyquery('#inspect-timeline .event a')]
@ -844,6 +857,7 @@ def test_inspect_page_actions_traces(pub):
'http://example.net/backoffice/management/target-form/1/', # Created form
'http://example.net/backoffice/data/target-card/1/', # Created card
'http://example.net/backoffice/data/target-card/1/', # Edited card
'http://example.net/backoffice/workflows/2/status/new/items/_accept/', # Accept manual jump
'http://example.net/backoffice/workflows/2/global-actions/1/#trigger-%s' % trigger.id,
]
# check all links are valid
@ -853,19 +867,21 @@ def test_inspect_page_actions_traces(pub):
'Created form - target form #1-1',
'Created card - target card #1-1',
'Edited card - target card #1-1',
'Action button - Manual Jump Accept',
'Global action timeout',
]
assert [x.text for x in resp.pyquery('#inspect-timeline .event-error')] == ['Nothing edited']
action_links = [x.attrib['href'] for x in resp.pyquery('#inspect-timeline a.tracing-link')]
assert len(action_links) == 13
assert action_links[0] == 'http://example.net/backoffice/workflows/2/status/just_submitted/'
assert (
action_links[1]
== 'http://example.net/backoffice/workflows/2/status/just_submitted/items/_notify_new_receiver_email/'
)
assert action_links[-5] == 'http://example.net/backoffice/workflows/2/status/new/items/_create/'
assert action_links[-4] == 'http://example.net/backoffice/workflows/2/status/new/items/_create_card/'
assert action_links[-3] == 'http://example.net/backoffice/workflows/2/status/new/items/_edit_card/'
assert action_links[-2] == 'http://example.net/backoffice/workflows/2/status/new/items/_edit_card2/'
assert action_links[-8] == 'http://example.net/backoffice/workflows/2/status/new/items/_create/'
assert action_links[-7] == 'http://example.net/backoffice/workflows/2/status/new/items/_create_card/'
assert action_links[-6] == 'http://example.net/backoffice/workflows/2/status/new/items/_edit_card/'
assert action_links[-5] == 'http://example.net/backoffice/workflows/2/status/new/items/_edit_card2/'
assert action_links[-1] == 'http://example.net/backoffice/workflows/2/global-actions/1/items/1/'
# check details are available
@ -890,6 +906,7 @@ def test_inspect_page_actions_traces(pub):
'Created form - target form #1-1',
'Created card - deleted',
'Edited card - deleted',
'Action button - Manual Jump Accept',
'Global action timeout',
]

View File

@ -578,7 +578,7 @@ def test_timeout_tracing(pub, admin_user):
assert [PyQuery(x).text() for x in resp.pyquery('#inspect-timeline li > *:nth-child(2)')] == [
'Created (backoffice submission)',
'Status1',
'Timeout jump',
'Timeout jump - Change Status on Timeout',

Ça fait un peu redondant/inutile mais ne complexifions pas juste pour ça.

Ça fait un peu redondant/inutile mais ne complexifions pas juste pour ça.
'Status2',
'History Message',
]

View File

@ -88,6 +88,9 @@ class ChoiceWorkflowStatusItem(WorkflowStatusJumpItem):
else:
return _('not completed')
def get_line_short_details(self):

pour ne pas avoir tout le détail du statut cible, des rôles, etc

pour ne pas avoir tout le détail du statut cible, des rôles, etc
return self.label
def get_computed_strings(self):
yield from super().get_computed_strings()
if self.get_expression(self.label, allow_python=False, allow_ezt=False)['type'] != 'text':

View File

@ -197,6 +197,9 @@ class JumpWorkflowStatusItem(WorkflowStatusJumpItem):
# override parent method to avoid mentioning the condition twice.
return '%s (%s)' % (self.description, self.get_line_details())
def render_as_short_line(self):
return self.description
def get_line_details(self):
if not self.status:
return _('not completed')

View File

@ -148,7 +148,7 @@ class WorkflowTrace(sql.WorkflowTrace):
status = workflow.get_status(status_id)
return status.get_admin_url()
def get_real_action(self, workflow, status_id, action_id, global_event):
def get_real_action(self, workflow, status_id, action_id, global_event=None):
if global_event:
if not global_event.event_args:
return None
@ -205,6 +205,28 @@ class WorkflowTrace(sql.WorkflowTrace):
self.event_args.get('trigger_id'),
self.get_event_label(),
)
elif self.event_args and self.event_args.get('action_item_id'):
try:
url = '%sitems/%s/' % (
self.get_base_url(formdata.formdef.workflow, self.status_id),
self.event_args.get('action_item_id'),
)
except KeyError:
url = '#missing-%s' % self.event_args['action_item_id']
label = self.get_event_label()
real_action = self.get_real_action(
formdata.formdef.workflow,
self.status_id,
self.event_args['action_item_id'],
)
if real_action and hasattr(real_action, 'render_as_short_line'):
label += ' - %s' % real_action.render_as_short_line()
elif real_action and hasattr(real_action, 'render_as_line'):
label += ' - %s' % real_action.render_as_line()
event_item += htmltext('<span class="event"><a href="%s">%s</a></span>') % (
url,
label,
)
elif self.event == 'workflow-edited-carddata':
# it would usually have external_formdef_id/external_formdata_id and be handled
# earlier; this matches the case when no targetted card could be found.

View File

@ -1734,6 +1734,9 @@ class WorkflowGlobalActionManualTrigger(WorkflowGlobalActionTrigger):
parts.append(_('not assigned'))
return ', '.join([str(x) for x in parts])
def render_as_short_line(self):
return _('Manual')
def get_inspect_view(self):
r = TemplateIO(html=True)
r += htmlescape(self.render_as_line())
@ -1887,6 +1890,9 @@ class WorkflowGlobalActionTimeoutTrigger(WorkflowGlobalActionTrigger):
else:
return _('Automatic (not configured)')
def render_as_short_line(self):
return _('Automatic')
def get_inspect_view(self):
r = TemplateIO(html=True)
r += htmlescape(self.render_as_line())
@ -2267,6 +2273,9 @@ class WorkflowGlobalActionWebserviceTrigger(WorkflowGlobalActionManualTrigger):
else:
return _('External call (not configured)')
def render_as_short_line(self):
return _('External call')
def get_inspect_view(self):
r = TemplateIO(html=True)
r += htmlescape(self.render_as_line())
@ -3017,6 +3026,14 @@ class WorkflowStatusItem(XmlSerialisable):
label += ' (%s)' % _('conditional')
return label
def render_as_short_line(self):
label = self.description
if hasattr(self, 'get_line_short_details'):
details = self.get_line_short_details()
if details:
label += ' %s' % details
return label
def get_line_details(self):
return ''