Projet

Général

Profil

0001-workflows-sort-workflow-actions-in-categories-3405.patch

Frédéric Péters, 22 octobre 2017 10:45

Télécharger (20,3 ko)

Voir les différences:

Subject: [PATCH] workflows: sort workflow actions in categories (#3405)

 tests/test_admin_pages.py            | 57 ++++++++++++++++++++----------------
 wcs/admin/workflows.py               | 43 +++++++++++++++------------
 wcs/qommon/static/css/dc2/admin.css  |  4 +++
 wcs/qommon/static/js/qommon.admin.js | 11 +++++++
 wcs/wf/aggregation_email.py          |  1 +
 wcs/wf/anonymise.py                  |  1 +
 wcs/wf/attachment.py                 |  1 +
 wcs/wf/backoffice_fields.py          |  1 +
 wcs/wf/criticality.py                |  1 +
 wcs/wf/dispatch.py                   |  1 +
 wcs/wf/export_to_model.py            |  1 +
 wcs/wf/form.py                       |  1 +
 wcs/wf/geolocate.py                  |  1 +
 wcs/wf/profile.py                    |  1 +
 wcs/wf/redirect_to_url.py            |  1 +
 wcs/wf/register_comment.py           |  1 +
 wcs/wf/remove.py                     |  1 +
 wcs/wf/resubmit.py                   |  1 +
 wcs/wf/roles.py                      |  2 ++
 wcs/wf/wscall.py                     |  1 +
 wcs/workflows.py                     |  6 ++++
 21 files changed, 93 insertions(+), 45 deletions(-)
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">&#8286;</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
-