0001-workflows-sort-workflow-actions-in-categories-3405.patch
tests/test_admin_pages.py | ||
---|---|---|
1576 | 1576 | |
1577 | 1577 |
# create a new action |
1578 | 1578 |
resp = resp.click('new status') |
1579 |
resp.forms[0]['type'] = 'Display message'
|
|
1579 |
resp.forms[0]['action-interaction'] = 'Display message'
|
|
1580 | 1580 |
resp = resp.forms[0].submit() |
1581 | 1581 |
assert resp.location == 'http://example.net/backoffice/workflows/1/status/1/' |
1582 | 1582 |
resp = resp.follow() |
... | ... | |
1848 | 1848 |
resp = app.get('/backoffice/workflows/1/') |
1849 | 1849 |
resp = resp.click('baz') |
1850 | 1850 | |
1851 |
for action in [x[0] for x in resp.forms[0]['type'].options]: |
|
1852 |
resp.forms[0]['type'] = action |
|
1853 |
resp = resp.forms[0].submit() |
|
1854 |
resp = resp.follow() |
|
1855 | ||
1856 |
for i in range(len(resp.forms[0]['type'].options)): |
|
1857 |
resp = resp.click('Edit', href='items/%d/' % (i+1), index=0) |
|
1858 |
resp = resp.forms[0].submit('cancel') |
|
1859 |
resp = resp.follow() # redirect to items/ |
|
1860 |
resp = resp.follow() # redirect to ./ |
|
1851 |
for category in ('status-change', 'interaction', 'formdata-action', 'user-action'): |
|
1852 |
for action in [x[0] for x in resp.forms[0]['action-%s' % category].options if x[0]]: |
|
1853 |
resp.forms[0]['action-%s' % category] = action |
|
1854 |
resp = resp.forms[0].submit() |
|
1855 |
resp = resp.follow() |
|
1856 | ||
1857 |
i = 1 |
|
1858 |
for category in ('status-change', 'interaction', 'formdata-action', 'user-action'): |
|
1859 |
for action in [x[0] for x in resp.forms[0]['action-%s' % category].options if x[0]]: |
|
1860 |
resp = resp.click('Edit', href='items/%d/' % i, index=0) |
|
1861 |
resp = resp.forms[0].submit('cancel') |
|
1862 |
resp = resp.follow() # redirect to items/ |
|
1863 |
resp = resp.follow() # redirect to ./ |
|
1864 |
i += 1 |
|
1861 | 1865 | |
1862 | 1866 |
def test_workflows_check_available_actions(pub): |
1863 | 1867 |
create_superuser(pub) |
... | ... | |
1871 | 1875 |
resp = app.get('/backoffice/workflows/1/') |
1872 | 1876 |
resp = resp.click('baz') |
1873 | 1877 | |
1874 |
assert not 'Modify Criticality' in [x[0] for x in resp.forms[0]['type'].options]
|
|
1875 |
assert not 'Send SMS' in [x[0] for x in resp.forms[0]['type'].options]
|
|
1878 |
assert not 'Modify Criticality' in [x[0] for x in resp.forms[0]['action-formdata-action'].options]
|
|
1879 |
assert not 'Send SMS' in [x[0] for x in resp.forms[0]['action-interaction'].options]
|
|
1876 | 1880 | |
1877 | 1881 |
pub.cfg['sms'] = {'mode': 'foobar'} |
1878 | 1882 |
pub.write_cfg() |
... | ... | |
1880 | 1884 |
workflow.store() |
1881 | 1885 |
resp = app.get('/backoffice/workflows/1/') |
1882 | 1886 |
resp = resp.click('baz') |
1883 |
assert 'Modify Criticality' in [x[0] for x in resp.forms[0]['type'].options]
|
|
1884 |
assert 'Send SMS' in [x[0] for x in resp.forms[0]['type'].options]
|
|
1887 |
assert 'Modify Criticality' in [x[0] for x in resp.forms[0]['action-formdata-action'].options]
|
|
1888 |
assert 'Send SMS' in [x[0] for x in resp.forms[0]['action-interaction'].options]
|
|
1885 | 1889 | |
1886 | 1890 |
def test_workflows_edit_dispatch_action(pub): |
1887 | 1891 |
create_superuser(pub) |
... | ... | |
1895 | 1899 |
resp = app.get('/backoffice/workflows/1/') |
1896 | 1900 |
resp = resp.click('baz') |
1897 | 1901 | |
1898 |
resp.forms[0]['type'] = 'Assign a Function'
|
|
1902 |
resp.forms[0]['action-formdata-action'] = 'Assign a Function'
|
|
1899 | 1903 |
resp = resp.forms[0].submit() |
1900 | 1904 |
resp = resp.follow() |
1901 | 1905 | |
... | ... | |
1928 | 1932 |
resp = app.get('/backoffice/workflows/1/') |
1929 | 1933 |
resp = resp.click('baz') |
1930 | 1934 | |
1931 |
resp.forms[0]['type'] = 'Send mail'
|
|
1935 |
resp.forms[0]['action-interaction'] = 'Send mail'
|
|
1932 | 1936 |
resp = resp.forms[0].submit() |
1933 | 1937 |
resp = resp.follow() |
1934 | 1938 | |
... | ... | |
2046 | 2050 |
resp = app.get('/backoffice/workflows/1/') |
2047 | 2051 |
resp = resp.click('baz') |
2048 | 2052 | |
2049 |
resp.form['type'] = 'Send SMS'
|
|
2053 |
resp.form['action-interaction'] = 'Send SMS'
|
|
2050 | 2054 |
resp = resp.form.submit().follow() |
2051 | 2055 | |
2052 | 2056 |
resp = resp.click('Send SMS') |
... | ... | |
2064 | 2068 |
resp = app.get('/backoffice/workflows/1/') |
2065 | 2069 |
resp = resp.click('baz') |
2066 | 2070 | |
2067 |
resp.forms[0]['type'] = 'Display a form'
|
|
2071 |
resp.forms[0]['action-interaction'] = 'Display a form'
|
|
2068 | 2072 |
resp = resp.forms[0].submit() |
2069 | 2073 |
resp = resp.follow() |
2070 | 2074 | |
... | ... | |
2092 | 2096 |
resp = app.get('/backoffice/workflows/1/') |
2093 | 2097 |
resp = resp.click('baz') |
2094 | 2098 | |
2095 |
resp.forms[0]['type'] = 'Change Status'
|
|
2099 |
resp.forms[0]['action-status-change'] = 'Change Status'
|
|
2096 | 2100 |
resp = resp.forms[0].submit() |
2097 | 2101 |
resp = resp.follow() |
2098 | 2102 | |
... | ... | |
2166 | 2170 |
resp = app.get('/backoffice/workflows/1/') |
2167 | 2171 |
resp = resp.click('baz') |
2168 | 2172 | |
2169 |
resp.forms[0]['type'] = 'Send mail'
|
|
2173 |
resp.forms[0]['action-interaction'] = 'Send mail'
|
|
2170 | 2174 |
resp = resp.forms[0].submit() |
2171 | 2175 |
resp = resp.follow() |
2172 | 2176 |
assert 'Send mail' in resp.body |
... | ... | |
2296 | 2300 |
# check the "set backoffice fields" action is now available |
2297 | 2301 |
resp = app.get('/backoffice/workflows/1/') |
2298 | 2302 |
resp = resp.click('baz') |
2299 |
resp.forms[0]['type'] = 'Set Backoffice Fields'
|
|
2303 |
resp.forms[0]['action-formdata-action'] = 'Set Backoffice Fields'
|
|
2300 | 2304 |
resp = resp.forms[0].submit() |
2301 | 2305 |
resp = resp.follow() |
2302 | 2306 | |
... | ... | |
2483 | 2487 |
resp = resp.follow() |
2484 | 2488 | |
2485 | 2489 |
# test adding all actions |
2486 |
for action in [x[0] for x in resp.forms[0]['type'].options]: |
|
2487 |
resp.forms[0]['type'] = action |
|
2488 |
resp = resp.forms[0].submit() |
|
2489 |
resp = resp.follow() |
|
2490 |
for category in ('status-change', 'interaction', 'formdata-action', 'user-action'): |
|
2491 |
for action in [x[0] for x in resp.forms[0]['action-%s' % category].options if x[0]]: |
|
2492 |
resp.forms[0]['action-%s' % category] = action |
|
2493 |
resp = resp.forms[0].submit() |
|
2494 |
resp = resp.follow() |
|
2490 | 2495 | |
2491 | 2496 |
# test visiting |
2492 | 2497 |
action_id = Workflow.get(workflow.id).global_actions[0].id |
wcs/admin/workflows.py | ||
---|---|---|
497 | 497 |
r += htmltext('<li><a href="delete" rel="popup">%s</a></li>') % _('Delete') |
498 | 498 |
r += htmltext('</ul>') |
499 | 499 |
r += htmltext('<div id="new-field">') |
500 |
r += htmltext('<h3>%s</h3>') % _('New Item')
|
|
500 |
r += htmltext('<h3>%s</h3>') % _('New Action')
|
|
501 | 501 |
r += self.get_new_item_form().render() |
502 | 502 |
r += htmltext('</div>') |
503 | 503 |
return r.getvalue() |
... | ... | |
506 | 506 |
return item.is_available(workflow=self.workflow) |
507 | 507 | |
508 | 508 |
def get_new_item_form(self): |
509 |
form = Form(enctype='multipart/form-data', action = 'newitem') |
|
509 |
form = Form(enctype='multipart/form-data', action='newitem', |
|
510 |
id='new-action-form') |
|
511 |
categories = [ |
|
512 |
('status-change', _('Change Status')), |
|
513 |
('interaction', _('Interact')), |
|
514 |
('formdata-action', _('Act on Form')), |
|
515 |
('user-action', _('Act on User')), |
|
516 |
] |
|
510 | 517 |
available_items = [x for x in item_classes if self.is_item_available(x)] |
511 |
def cmp_items(x, y): |
|
512 |
t = cmp(x.category and x.category[0], y.category and y.category[0]) |
|
513 |
if t: |
|
514 |
return t |
|
515 |
return cmp(_(x.description), _(y.description)) |
|
516 | ||
517 |
available_items.sort(cmp_items) |
|
518 |
options = [(x.key, _(x.description)) for x in available_items] |
|
519 |
form.add(SingleSelectWidget, 'type', title = _('Type'), |
|
520 |
required=True, options = options) |
|
518 |
available_items.sort(key=lambda x: _(x.description)) |
|
519 | ||
520 |
for category, category_label in categories: |
|
521 |
options = [(x.key, _(x.description)) for x in available_items |
|
522 |
if x.category == category] |
|
523 |
form.add(SingleSelectWidget, 'action-%s' % category, title=category_label, |
|
524 |
required=False, options=[(None, '')] + options) |
|
521 | 525 |
form.add_submit('submit', _('Add')) |
522 | 526 |
return form |
523 | 527 | |
... | ... | |
535 | 539 |
get_session().message = ('error', _('Submitted form was not filled properly.')) |
536 | 540 |
return redirect('.') |
537 | 541 | |
538 |
if form.get_widget('type').parse(): |
|
539 |
self.status.append_item(form.get_widget('type').parse()) |
|
540 |
else: |
|
541 |
get_session().message = ('error', _('Submitted form was not filled properly.')) |
|
542 |
return redirect('.') |
|
543 | ||
544 |
self.workflow.store() |
|
542 |
for category in ('status-change', 'interaction', 'formdata-action', 'user-action'): |
|
543 |
action_type = form.get_widget('action-%s' % category).parse() |
|
544 |
if action_type: |
|
545 |
self.status.append_item(action_type) |
|
546 |
self.workflow.store() |
|
547 |
return redirect('.') |
|
545 | 548 | |
549 |
get_session().message = ('error', _('Submitted form was not filled properly.')) |
|
546 | 550 |
return redirect('.') |
547 | 551 | |
552 | ||
548 | 553 |
def delete(self): |
549 | 554 |
form = Form(enctype="multipart/form-data") |
550 | 555 |
form.widgets.append(HtmlWidget('<p>%s</p>' % _( |
wcs/qommon/static/css/dc2/admin.css | ||
---|---|---|
1620 | 1620 |
div.widget input[type=text][readonly] { |
1621 | 1621 |
background: #f0f0f0; |
1622 | 1622 |
} |
1623 | ||
1624 |
#new-action-form select[disabled] { |
|
1625 |
background: #f0f0f0; |
|
1626 |
} |
wcs/qommon/static/js/qommon.admin.js | ||
---|---|---|
87 | 87 |
$('input[type=hidden][name=submission_channel]').val($(this).val()); |
88 | 88 |
}); |
89 | 89 | |
90 |
/* new action form */ |
|
91 |
$('#new-action-form select').on('change', function() { |
|
92 |
if ($(this).val() == '') { |
|
93 |
$('#new-action-form select').prop('disabled', null) |
|
94 |
} else { |
|
95 |
$('#new-action-form select').prop('disabled', 'disabled') |
|
96 |
$(this).prop('disabled', null) |
|
97 |
} |
|
98 |
return false; |
|
99 |
}); |
|
100 | ||
90 | 101 |
/* possibility to toggle the sidebar */ |
91 | 102 |
if ($('#sidebar').length) { |
92 | 103 |
$('#main-content').after($('<span id="sidebar-toggle">⁞</span>')); |
wcs/wf/aggregation_email.py | ||
---|---|---|
29 | 29 |
class AggregationEmailWorkflowStatusItem(WorkflowStatusItem): |
30 | 30 |
description = N_('Aggregate to summary email') |
31 | 31 |
key = 'aggregationemail' |
32 |
category = 'interaction' |
|
32 | 33 |
ok_in_global_action = False |
33 | 34 | |
34 | 35 |
to = [] |
wcs/wf/anonymise.py | ||
---|---|---|
19 | 19 |
class AnonymiseWorkflowStatusItem(WorkflowStatusItem): |
20 | 20 |
description = N_('Anonymise') |
21 | 21 |
key = 'anonymise' |
22 |
category = 'formdata-action' |
|
22 | 23 | |
23 | 24 |
def perform(self, formdata): |
24 | 25 |
formdata.anonymise() |
wcs/wf/attachment.py | ||
---|---|---|
68 | 68 |
class AddAttachmentWorkflowStatusItem(WorkflowStatusItem): |
69 | 69 |
description = N_('Allow Joining a File') |
70 | 70 |
key = 'addattachment' |
71 |
category = 'interaction' |
|
71 | 72 |
endpoint = False |
72 | 73 |
waitpoint = True |
73 | 74 |
ok_in_global_action = False |
wcs/wf/backoffice_fields.py | ||
---|---|---|
67 | 67 |
class SetBackofficeFieldsWorkflowStatusItem(WorkflowStatusItem): |
68 | 68 |
description = N_('Set Backoffice Fields') |
69 | 69 |
key = 'set-backoffice-fields' |
70 |
category = 'formdata-action' |
|
70 | 71 | |
71 | 72 |
fields = None |
72 | 73 |
wcs/wf/criticality.py | ||
---|---|---|
27 | 27 |
class ModifyCriticalityWorkflowStatusItem(WorkflowStatusItem): |
28 | 28 |
description = N_('Modify Criticality') |
29 | 29 |
key = 'modify_criticality' |
30 |
category = 'formdata-action' |
|
30 | 31 | |
31 | 32 |
mode = MODE_INC |
32 | 33 |
absolute_value = None |
wcs/wf/dispatch.py | ||
---|---|---|
80 | 80 |
class DispatchWorkflowStatusItem(WorkflowStatusItem): |
81 | 81 |
description = N_('Assign a Function') |
82 | 82 |
key = 'dispatch' |
83 |
category = 'formdata-action' |
|
83 | 84 | |
84 | 85 |
role_id = None |
85 | 86 |
role_key = None |
wcs/wf/export_to_model.py | ||
---|---|---|
196 | 196 |
class ExportToModel(WorkflowStatusItem): |
197 | 197 |
description = N_('Create Document') |
198 | 198 |
key = 'export_to_model' |
199 |
category = 'formdata-action' |
|
199 | 200 |
support_substitution_variables = True |
200 | 201 |
ok_in_global_action = False |
201 | 202 |
wcs/wf/form.py | ||
---|---|---|
71 | 71 |
class FormWorkflowStatusItem(WorkflowStatusItem): |
72 | 72 |
description = N_('Display a form') |
73 | 73 |
key = 'form' |
74 |
category = 'interaction' |
|
74 | 75 |
ok_in_global_action = False |
75 | 76 |
endpoint = False |
76 | 77 |
waitpoint = True |
wcs/wf/geolocate.py | ||
---|---|---|
35 | 35 |
class GeolocateWorkflowStatusItem(WorkflowStatusItem): |
36 | 36 |
description = N_('Geolocate') |
37 | 37 |
key = 'geolocate' |
38 |
category = 'formdata-action' |
|
38 | 39 | |
39 | 40 |
method = 'address_string' |
40 | 41 |
address_string = None |
wcs/wf/profile.py | ||
---|---|---|
101 | 101 |
class UpdateUserProfileStatusItem(WorkflowStatusItem): |
102 | 102 |
description = N_('Update User Profile') |
103 | 103 |
key = 'update_user_profile' |
104 |
category = 'user-action' |
|
104 | 105 | |
105 | 106 |
fields = None |
106 | 107 |
wcs/wf/redirect_to_url.py | ||
---|---|---|
22 | 22 |
class RedirectToUrlWorkflowStatusItem(WorkflowStatusItem): |
23 | 23 |
description = N_('Redirect to URL') |
24 | 24 |
key = 'redirect_to_url' |
25 |
category = 'formdata-action' |
|
25 | 26 |
endpoint = False |
26 | 27 |
support_substitution_variables = True |
27 | 28 |
wcs/wf/register_comment.py | ||
---|---|---|
64 | 64 |
class RegisterCommenterWorkflowStatusItem(WorkflowStatusItem): |
65 | 65 |
description = N_('Record in Log') |
66 | 66 |
key = 'register-comment' |
67 |
category = 'interaction' |
|
67 | 68 | |
68 | 69 |
comment = None |
69 | 70 |
wcs/wf/remove.py | ||
---|---|---|
21 | 21 |
class RemoveWorkflowStatusItem(WorkflowStatusItem): |
22 | 22 |
description = N_('Remove') |
23 | 23 |
key = 'remove' |
24 |
category = 'formdata-action' |
|
24 | 25 | |
25 | 26 |
def perform(self, formdata): |
26 | 27 |
formdata.remove_self() |
wcs/wf/resubmit.py | ||
---|---|---|
26 | 26 |
class ResubmitWorkflowStatusItem(WorkflowStatusItem): |
27 | 27 |
description = N_('Resubmit') |
28 | 28 |
key = 'resubmit' |
29 |
category = 'formdata-action' |
|
29 | 30 |
endpoint = False |
30 | 31 |
waitpoint = True |
31 | 32 |
ok_in_global_action = False |
wcs/wf/roles.py | ||
---|---|---|
44 | 44 |
class AddRoleWorkflowStatusItem(WorkflowStatusItem): |
45 | 45 |
description = N_('Add Role to User') |
46 | 46 |
key = 'add_role' |
47 |
category = 'user-action' |
|
47 | 48 | |
48 | 49 |
role_id = None |
49 | 50 | |
... | ... | |
112 | 113 |
class RemoveRoleWorkflowStatusItem(WorkflowStatusItem): |
113 | 114 |
description = N_('Remove Role from User') |
114 | 115 |
key = 'remove_role' |
116 |
category = 'user-action' |
|
115 | 117 | |
116 | 118 |
role_id = None |
117 | 119 |
wcs/wf/wscall.py | ||
---|---|---|
94 | 94 |
class WebserviceCallStatusItem(WorkflowStatusItem): |
95 | 95 |
description = N_('Webservice Call') |
96 | 96 |
key = 'webservice_call' |
97 |
category = 'interaction' |
|
97 | 98 |
support_substitution_variables = True |
98 | 99 | |
99 | 100 |
label = None |
wcs/workflows.py | ||
---|---|---|
1705 | 1705 |
status = None |
1706 | 1706 |
endpoint = False |
1707 | 1707 |
set_marker_on_status = False |
1708 |
category = 'status-change' |
|
1708 | 1709 | |
1709 | 1710 |
def add_parameters_widgets(self, form, parameters, prefix='', formdef=None): |
1710 | 1711 |
if 'status' in parameters: |
... | ... | |
1790 | 1791 |
class CommentableWorkflowStatusItem(WorkflowStatusItem): |
1791 | 1792 |
description = N_('Allow Comment') |
1792 | 1793 |
key = 'commentable' |
1794 |
category = 'interaction' |
|
1793 | 1795 |
endpoint = False |
1794 | 1796 |
waitpoint = True |
1795 | 1797 |
ok_in_global_action = False |
... | ... | |
2010 | 2012 |
class SendmailWorkflowStatusItem(WorkflowStatusItem): |
2011 | 2013 |
description = N_('Send mail') |
2012 | 2014 |
key = 'sendmail' |
2015 |
category = 'interaction' |
|
2013 | 2016 |
support_substitution_variables = True |
2014 | 2017 | |
2015 | 2018 |
to = [] |
... | ... | |
2286 | 2289 |
class SendSMSWorkflowStatusItem(WorkflowStatusItem): |
2287 | 2290 |
description = N_('Send SMS') |
2288 | 2291 |
key = 'sendsms' |
2292 |
category = 'interaction' |
|
2289 | 2293 |
support_substitution_variables = True |
2290 | 2294 | |
2291 | 2295 |
to = [] |
... | ... | |
2355 | 2359 |
class DisplayMessageWorkflowStatusItem(WorkflowStatusItem): |
2356 | 2360 |
description = N_('Display message') |
2357 | 2361 |
key = 'displaymsg' |
2362 |
category = 'interaction' |
|
2358 | 2363 |
support_substitution_variables = True |
2359 | 2364 |
ok_in_global_action = False |
2360 | 2365 | |
... | ... | |
2456 | 2461 |
class EditableWorkflowStatusItem(WorkflowStatusItem): |
2457 | 2462 |
description = N_('Allow Edition') |
2458 | 2463 |
key = 'editable' |
2464 |
category = 'formdata-action' |
|
2459 | 2465 |
endpoint = False |
2460 | 2466 |
waitpoint = True |
2461 | 2467 |
ok_in_global_action = False |
2462 |
- |