0001-workflow-add-a-trace-on-update-carddata-by-wf-action.patch
tests/workflow/test_carddata.py | ||
---|---|---|
634 | 634 |
assert data.data['2'] == 'c' |
635 | 635 |
assert data.data['2_display'] == 'cook' |
636 | 636 |
assert data.data['2_structured'] == {'id': 'c', 'text': 'cook', 'extra': 'plop2'} |
637 |
# check evolutions & tracing |
|
638 |
assert isinstance(data.evolution[0].parts[0], ActionsTracingEvolutionPart) |
|
639 |
assert data.evolution[0].parts[0].external_workflow_id == wf.id |
|
640 |
assert data.evolution[0].parts[0].external_status_id == 'st1' |
|
641 |
assert data.evolution[0].parts[0].external_item_id == 'edit' |
|
637 | 642 | |
638 | 643 |
formdata = formdef.data_class()() |
639 | 644 |
formdata.data = {'0': '1', '1': 'b'} |
wcs/backoffice/management.py | ||
---|---|---|
3721 | 3721 |
if evolution.status and evolution.status != wf_status: |
3722 | 3722 |
for part in evolution.parts or []: |
3723 | 3723 |
if isinstance(part, ActionsTracingEvolutionPart): |
3724 |
if part.external_workflow and part.external_status_id and part.external_item_id: |
|
3725 |
r += htmltext('<li><span class="event"><a href="%s">%s</a></span></li>') % ( |
|
3726 |
part.get_external_url(), |
|
3727 |
part.get_event_label(), |
|
3728 |
) |
|
3729 |
last_event_line = part |
|
3730 |
break |
|
3724 | 3731 |
if part.actions: |
3725 | 3732 |
r += htmltext('<li><span class="event">%s</span></li>') % part.get_event_label() |
3726 | 3733 |
last_event_line = part |
... | ... | |
3744 | 3751 |
wf_status = evolution.status |
3745 | 3752 |
for part in evolution.parts or []: |
3746 | 3753 |
if isinstance(part, ActionsTracingEvolutionPart): |
3747 |
if part.actions and part != last_event_line: |
|
3748 |
last_event_line = part |
|
3749 |
r += htmltext('<li><span class="event">%s</span></li>') % part.get_event_label() |
|
3754 |
if part != last_event_line: |
|
3755 |
if part.external_workflow and part.external_status_id and part.external_item_id: |
|
3756 |
last_event_line = part |
|
3757 |
r += htmltext('<li><span class="event"><a href="%s">%s</a></span></li>') % ( |
|
3758 |
part.get_external_url(), |
|
3759 |
part.get_event_label(), |
|
3760 |
) |
|
3761 |
elif part.actions: |
|
3762 |
last_event_line = part |
|
3763 |
r += htmltext('<li><span class="event">%s</span></li>') % part.get_event_label() |
|
3750 | 3764 |
for action_ts, action_key, action_id in part.actions: |
3751 | 3765 |
action_label = action_classes.get(action_key, action_key) |
3752 | 3766 |
try: |
wcs/qommon/static/css/dc2/admin.scss | ||
---|---|---|
1797 | 1797 | |
1798 | 1798 |
span.event { |
1799 | 1799 |
font-style: italic; |
1800 |
a { |
|
1801 |
border-bottom: none; |
|
1802 |
color: #215D9C; |
|
1803 |
&:hover { |
|
1804 |
background: transparent; |
|
1805 |
text-decoration: underline; |
|
1806 |
} |
|
1807 |
} |
|
1800 | 1808 |
} |
1801 | 1809 | |
1802 | 1810 |
a.tracing-link { |
... | ... | |
2502 | 2510 |
#workflow-fullscreen-schema { |
2503 | 2511 |
height: 95vh; |
2504 | 2512 |
width: 100%; |
2505 |
} |
|
2513 |
} |
wcs/wf/edit_carddata.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU General Public License |
15 | 15 |
# along with this program; if not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
import time |
|
18 | ||
17 | 19 |
from quixote import get_publisher |
18 | 20 | |
21 |
from wcs.formdata import Evolution |
|
19 | 22 |
from wcs.qommon import _ |
20 | 23 |
from wcs.wf.create_carddata import CreateCarddataWorkflowStatusItem |
21 | 24 |
from wcs.wf.external_workflow import ExternalWorkflowGlobalAction |
22 |
from wcs.workflows import register_item_class |
|
25 |
from wcs.workflows import ActionsTracingEvolutionPart, register_item_class
|
|
23 | 26 | |
24 | 27 | |
25 | 28 |
class EditCarddataWorkflowStatusItem(CreateCarddataWorkflowStatusItem, ExternalWorkflowGlobalAction): |
... | ... | |
51 | 54 |
for target_data in self.iter_target_datas(formdata, carddef): |
52 | 55 |
self.apply_mappings(dest=target_data, src=formdata) |
53 | 56 |
with get_publisher().substitutions.freeze(): |
57 |
# store an ActionsTracingEvolutionPart with a link to current workflow & action |
|
58 |
evo = Evolution() |
|
59 |
evo.time = time.localtime() |
|
60 |
evo.status = target_data.status |
|
61 |
evo.add_part( |
|
62 |
ActionsTracingEvolutionPart( |
|
63 |
'workflow-edited', |
|
64 |
[], |
|
65 |
external_workflow_id=self.parent.parent.id, |
|
66 |
external_status_id=self.parent.id, |
|
67 |
external_item_id=self.id, |
|
68 |
) |
|
69 |
) |
|
70 |
target_data.evolution.append(evo) |
|
54 | 71 |
target_data.store() |
55 | 72 | |
56 | 73 |
# update local object as it may have modified itself |
wcs/workflows.py | ||
---|---|---|
390 | 390 | |
391 | 391 | |
392 | 392 |
class ActionsTracingEvolutionPart(EvolutionPart): |
393 |
def __init__(self, event, actions): |
|
393 |
def __init__( |
|
394 |
self, event, actions, external_workflow_id=None, external_status_id=None, external_item_id=None |
|
395 |
): |
|
394 | 396 |
if isinstance(event, tuple): |
395 | 397 |
self.event = event[0] |
396 | 398 |
self.event_args = event[1:] |
... | ... | |
398 | 400 |
self.event = event |
399 | 401 |
self.event_args = None |
400 | 402 |
self.actions = actions |
403 |
self.external_workflow_id = external_workflow_id |
|
404 |
self.external_status_id = external_status_id |
|
405 |
self.external_item_id = external_item_id |
|
401 | 406 | |
402 | 407 |
def get_event_label(self): |
403 | 408 |
return { |
... | ... | |
419 | 424 |
'json-import-created': _('Created (by JSON import)'), |
420 | 425 |
'timeout-jump': _('Timeout jump'), |
421 | 426 |
'workflow-created': _('Created (by workflow action)'), |
427 |
'workflow-edited': _('Edited (by workflow action)'), |
|
422 | 428 |
'workflow-form-submit': _('Action in workflow form'), |
423 | 429 |
}.get(self.event, self.event) |
424 | 430 | |
425 | 431 |
def is_global_event(self): |
426 | 432 |
return bool(self.event and self.event.startswith('global-')) |
427 | 433 | |
434 |
@property |
|
435 |
def external_workflow(self): |
|
436 |
if not hasattr(self, '_external_workflow'): |
|
437 |
self._external_workflow = None |
|
438 |
if self.external_workflow_id: |
|
439 |
self._external_workflow = Workflow.get(self.external_workflow_id, ignore_errors=True) |
|
440 |
return self._external_workflow |
|
441 | ||
442 |
def get_external_url(self): |
|
443 |
try: |
|
444 |
return '%sitems/%s/' % ( |
|
445 |
self.get_base_url( |
|
446 |
self.external_workflow, |
|
447 |
self.external_status_id, |
|
448 |
), |
|
449 |
self.external_item_id, |
|
450 |
) |
|
451 |
except KeyError: |
|
452 |
return '#missing-%s' % self.external_item_id |
|
453 | ||
428 | 454 |
def get_base_url(self, workflow, status_id): |
429 | 455 |
if self.is_global_event(): |
430 | 456 |
return '%sglobal-actions/%s/' % (workflow.get_admin_url(), self.event_args[0]) |
431 |
- |