Projet

Général

Profil

0001-backoffice-add-button-link-to-jump-to-selected-optio.patch

Frédéric Péters, 27 mai 2022 08:07

Télécharger (13,6 ko)

Voir les différences:

Subject: [PATCH] backoffice: add button/link to jump to selected option admin
 page (#65681)

 tests/admin_pages/test_form.py       |  8 ++++++++
 tests/admin_pages/test_workflow.py   | 13 +++++++++++--
 tests/test_fields.py                 |  1 +
 wcs/data_sources.py                  | 17 ++++++++++++++++-
 wcs/qommon/static/css/dc2/admin.scss |  7 +++++++
 wcs/qommon/static/js/qommon.admin.js | 17 +++++++++++++++++
 wcs/wf/create_formdata.py            |  7 +++++--
 wcs/wf/editable.py                   |  6 +++++-
 wcs/wf/external_workflow.py          | 10 ++++++++--
 wcs/wf/wscall.py                     |  9 +++++++--
 wcs/workflows.py                     |  9 ++++++---
 11 files changed, 91 insertions(+), 13 deletions(-)
tests/admin_pages/test_form.py
2154 2154
        ('jsonp', False, 'JSONP URL'),
2155 2155
        ('python', False, 'Python Expression'),
2156 2156
    ]
2157
    assert (
2158
        resp.pyquery('select[id="form_data_source$type"] option')[1].attrib['data-goto-url']
2159
        == carddef.get_admin_url()
2160
    )
2161
    assert (
2162
        resp.pyquery('select[id="form_data_source$type"] option')[2].attrib['data-goto-url']
2163
        == data_source.get_admin_url()
2164
    )
2157 2165

  
2158 2166
    resp.form['data_source$type'].value = 'carddef:%s' % carddef.url_name
2159 2167
    resp = resp.form.submit('submit').follow()
tests/admin_pages/test_workflow.py
1432 1432
    create_superuser(pub)
1433 1433
    Workflow.wipe()
1434 1434
    workflow = Workflow(name='foo')
1435
    workflow.add_status(name='baz')
1435
    baz_status = workflow.add_status(name='baz')
1436 1436
    workflow.store()
1437 1437

  
1438 1438
    app = login(get_app(pub))
......
1444 1444
    resp = resp.follow()
1445 1445

  
1446 1446
    resp = resp.click(href='items/1/', index=0)
1447
    assert (
1448
        resp.pyquery('select#form_status option')[1].attrib['data-goto-url']
1449
        == 'http://example.net/backoffice/workflows/1/status/1/'
1450
    )
1447 1451
    assert 'Previously Marked Status' not in [x[2] for x in resp.form['status'].options]
1448
    resp.form['status'].value = 'baz'
1452
    resp.form['status'].value = baz_status.id
1449 1453
    resp = resp.form.submit('submit')
1450 1454
    resp = resp.follow()
1451 1455
    resp = resp.follow()
......
1457 1461
    resp = resp.follow()
1458 1462

  
1459 1463
    resp = resp.click(href='items/1/', index=0)
1464
    assert 'data-goto-url' not in resp.pyquery('select#form_status option')[2].attrib
1460 1465
    assert 'Previously Marked Status' in [x[2] for x in resp.form['status'].options]
1461 1466

  
1462 1467

  
......
2446 2451
    resp = resp.forms[0].submit('submit')
2447 2452
    assert "required field" in resp.text
2448 2453
    resp.forms[0]['slug'] = 'formdef:%s' % formdef.url_name
2454
    assert (
2455
        resp.pyquery('select#form_slug option')[1].attrib['data-goto-url']
2456
        == 'http://example.net/backoffice/forms/1/'
2457
    )
2449 2458
    resp = resp.forms[0].submit('submit')
2450 2459
    assert "required field" in resp.text
2451 2460
    resp = resp.forms[0].submit('submit')
tests/test_fields.py
33 33

  
34 34

  
35 35
def test_fill_admin_form(pub):
36
    pub.root_directory.backoffice = pub.backoffice_directory_class()
36 37
    for klass in fields.field_classes:
37 38
        form = Form(use_tokens=False)
38 39
        klass().fill_admin_form(form)
wcs/data_sources.py
67 67
        if allow_named_sources:
68 68
            from wcs.carddef import CardDef
69 69

  
70
            cards_options = [(t[2], t[1], t[2]) for t in CardDef.get_carddefs_as_data_source()]
70
            cards_options = [
71
                (t[2], t[1], t[2], {'data-goto-url': t[0].get_admin_url()})
72
                for t in CardDef.get_carddefs_as_data_source()
73
            ]
74
            if not get_publisher().get_backoffice_root().is_accessible('cards'):
75
                cards_options = [x[:3] for x in cards_options]
71 76
            cards_options.sort(key=lambda x: misc.simplify(x[1]))
72 77
            if cards_options:
73 78
                options.append(OptGroup(_('Cards')))
74 79
                options.extend(cards_options)
75 80

  
81
            admin_accessible = NamedDataSource.is_admin_accessible()
76 82
            nds_options = []
77 83
            nds_agenda_options = []
78 84
            nds_users_options = []
......
86 92
                        'data-maybe-datetimes': 'true' if ds.maybe_datetimes() else 'false',
87 93
                    },
88 94
                ]
95
                if admin_accessible:
96
                    option[-1]['data-goto-url'] = ds.get_admin_url()
89 97
                if ds.external == 'agenda':
90 98
                    nds_agenda_options.append(option)
91 99
                elif ds.type == 'wcs:users':
......
595 603
                instance=self, comment=comment, store_user=snapshot_store_user
596 604
            )
597 605

  
606
    @classmethod
607
    def is_admin_accessible(cls):
608
        for section in ('settings', 'forms', 'workflows'):
609
            if get_publisher().get_backoffice_root().is_accessible(section):
610
                return True
611
        return False
612

  
598 613
    def get_admin_url(self):
599 614
        base_url = get_publisher().get_backoffice_url()
600 615
        if get_request():
wcs/qommon/static/css/dc2/admin.scss
2442 2442
		margin-top: 0;
2443 2443
	}
2444 2444
}
2445

  
2446
a.button.button--go-to-option {
2447
	margin-left: 2px;
2448
	display: inline;
2449
	padding-left: 10px;
2450
	padding-right: 10px;
2451
}
wcs/qommon/static/js/qommon.admin.js
7 7
    });
8 8
    $('h4.foldable.folded').next().hide();
9 9

  
10
    $('option[data-goto-url]').parents('select').on('change', function() {
11
      var jumpto_button = this.jumpto_button;
12
      if (typeof jumpto_button == 'undefined') {
13
        this.jumpto_button = $('<a>', {'class': 'button button--go-to-option', text: '↗'});
14
        this.jumpto_button.hide();
15
        this.jumpto_button.insertAfter($(this));
16
      }
17
      var option = $(this).find('option:selected');
18
      var data_url = option.data('goto-url');
19
      if (data_url) {
20
        this.jumpto_button.attr('href', data_url);
21
        this.jumpto_button.show();
22
      } else {
23
        this.jumpto_button.hide();
24
      }
25
    }).trigger('change');
26

  
10 27
    /* focus tab from #open:<tab slug> anchor, used in documentation links
11 28
     * to point to open panel */
12 29
    if (document.location.hash && document.location.hash.indexOf('#open:') == 0) {
wcs/wf/create_formdata.py
343 343
    def add_parameters_widgets(self, form, parameters, prefix='', formdef=None, **kwargs):
344 344
        super().add_parameters_widgets(form, parameters, prefix=prefix, formdef=formdef, **kwargs)
345 345
        if 'formdef_slug' in parameters:
346
            list_forms = [(None, '---', '')]
346
            list_forms = [(None, '---', '', {})]
347 347
            list_forms += [
348
                (x.url_name, x.name, x.url_name)
348
                (x.url_name, x.name, x.url_name, {'data-goto-url': x.get_admin_url()})
349 349
                for x in self.formdef_class.select(order_by='name')
350 350
                if not x.disabled or x.url_name == self.formdef_slug
351 351
            ]
352
            if not get_publisher().get_backoffice_root().is_accessible(self.formdef_class.backoffice_section):
353
                # do not include goto url if section is not accessible
354
                list_forms = [(x[0], x[1], x[2], {}) for x in list_forms]
352 355
            form.add(
353 356
                SingleSelectWidget,
354 357
                '%sformdef_slug' % prefix,
wcs/wf/editable.py
75 75
                title=_('Status After Edit'),
76 76
                value=self.status,
77 77
                hint=_("Don't select any if you don't want status change processing"),
78
                options=[(None, '---')] + [(x.id, x.name) for x in self.parent.parent.possible_status],
78
                options=[(None, '---', '', {})]
79
                + [
80
                    (x.id, x.name, x.id, {'data-goto-url': x.get_admin_url()})
81
                    for x in self.parent.parent.possible_status
82
                ],
79 83
            )
80 84
        if 'label' in parameters:
81 85
            form.add(StringWidget, '%slabel' % prefix, title=_('Button Label'), value=self.label)
wcs/wf/external_workflow.py
109 109
        super().add_parameters_widgets(form, parameters, prefix=prefix, formdef=formdef, **kwargs)
110 110

  
111 111
        if 'slug' in parameters:
112
            objects = [(None, '---', '')]
112
            objects = [(None, '---', '', {})]
113
            is_admin_accessible = {
114
                'forms': get_publisher().get_backoffice_root().is_accessible('forms'),
115
                'cards': get_publisher().get_backoffice_root().is_accessible('cards'),
116
            }
113 117
            for wf in Workflow.select():
114 118
                if any(self.get_workflow_webservice_triggers(wf)):
115 119
                    for objectdef in wf.formdefs(lightweight=True) + wf.carddefs(lightweight=True):
116 120
                        object_slug = '%s:%s' % (objectdef.__class__.__name__.lower(), objectdef.url_name)
117
                        objects.append((object_slug, objectdef.name, object_slug))
121
                        objects.append((object_slug, objectdef.name, object_slug, {}))
122
                        if is_admin_accessible[objectdef.backoffice_section]:
123
                            objects[-1][-1]['data-goto-url'] = objectdef.get_admin_url()
118 124
            if len(objects) == 1:
119 125
                form.add_global_errors([_('No workflow with external triggerable global action.')])
120 126
                return
wcs/wf/wscall.py
309 309
                    tab=('response', _('Response')),
310 310
                )
311 311

  
312
        error_actions = [(':stop', _('Stop')), (':pass', _('Ignore'))]
313
        error_actions.extend([(x.id, _('Jump to %s') % x.name) for x in self.parent.parent.possible_status])
312
        error_actions = [(':stop', _('Stop'), ':stop', {}), (':pass', _('Ignore'), ':pass', {})]
313
        error_actions.extend(
314
            [
315
                (x.id, _('Jump to %s') % x.name, str(x.id), {'data-goto-url': x.get_admin_url()})
316
                for x in self.parent.parent.possible_status
317
            ]
318
        )
314 319
        for attribute in (
315 320
            'action_on_app_error',
316 321
            'action_on_4xx',
wcs/workflows.py
2661 2661
    def add_parameters_widgets(self, form, parameters, prefix='', formdef=None, **kwargs):
2662 2662
        super().add_parameters_widgets(form, parameters, prefix=prefix, formdef=formdef, **kwargs)
2663 2663
        if 'status' in parameters:
2664
            destinations = [(x.id, x.name) for x in self.parent.parent.possible_status]
2664
            destinations = [
2665
                (x.id, x.name, x.id, {'data-goto-url': x.get_admin_url()})
2666
                for x in self.parent.parent.possible_status
2667
            ]
2665 2668

  
2666 2669
            # look for existing jumps that are dropping a mark
2667 2670
            workflow = self.parent.parent
......
2670 2673
            for status in statuses + global_actions:
2671 2674
                for item in status.items:
2672 2675
                    if getattr(item, 'set_marker_on_status', False):
2673
                        destinations.append(('_previous', _('Previously Marked Status')))
2676
                        destinations.append(('_previous', _('Previously Marked Status'), '_previous', {}))
2674 2677
                        break
2675 2678
                else:
2676 2679
                    continue
......
2681 2684
                '%sstatus' % prefix,
2682 2685
                title=_('Status'),
2683 2686
                value=self.status,
2684
                options=[(None, '---')] + destinations,
2687
                options=[(None, '---', '', {})] + destinations,
2685 2688
            )
2686 2689

  
2687 2690
        if 'set_marker_on_status' in parameters:
2688
-