Projet

Général

Profil

0002-backoffice-also-allow-importing-fields-from-cards-61.patch

Frédéric Péters, 28 décembre 2022 16:38

Télécharger (11,7 ko)

Voir les différences:

Subject: [PATCH 2/2] backoffice: also allow importing fields from cards
 (#61416)

 tests/admin_pages/test_form.py | 89 ++++++++++++++++++++++++++++++
 wcs/admin/blocks.py            |  4 +-
 wcs/admin/fields.py            | 99 ++++++++++++++++++----------------
 3 files changed, 145 insertions(+), 47 deletions(-)
tests/admin_pages/test_form.py
3644 3644
        block.get_admin_url() + 'inspect'
3645 3645
    )
3646 3646
    assert resp.pyquery('[data-field-id="14"] .parameter-data_source a').attr['href'] == '#invalid-xxx'
3647

  
3648

  
3649
def test_form_import_fields(pub):
3650
    create_superuser(pub)
3651
    create_role(pub)
3652

  
3653
    CardDef.wipe()
3654
    FormDef.wipe()
3655

  
3656
    formdef1 = FormDef()
3657
    formdef1.name = 'form title'
3658
    formdef1.fields = [
3659
        fields.StringField(id='1', label='field 1', type='string'),
3660
        fields.StringField(id='2', label='field 2', type='string'),
3661
    ]
3662
    formdef1.store()
3663

  
3664
    formdef2 = FormDef()
3665
    formdef2.name = 'form2 title'
3666
    formdef2.fields = [
3667
        fields.StringField(id='1', label='field A', type='string'),
3668
    ]
3669
    formdef2.store()
3670

  
3671
    app = login(get_app(pub))
3672
    resp = app.get('/backoffice/forms/%s/fields/' % formdef2.id)
3673

  
3674
    resp = app.get('/backoffice/forms/%s/fields/new' % formdef2.id, status=302).follow()
3675
    assert 'Submitted form was not filled properly.' in resp.text
3676

  
3677
    assert len(resp.forms['import-fields']['form'].options) == 3  # (empty, form1, form2)
3678
    assert resp.pyquery('#import-fields optgroup').length == 0
3679

  
3680
    carddef = CardDef()
3681
    carddef.name = 'card title'
3682
    carddef.fields = [
3683
        fields.StringField(id='1', label='field 3', type='string'),
3684
        fields.StringField(id='2', label='field 4', type='string'),
3685
    ]
3686
    carddef.store()
3687

  
3688
    resp = app.get('/backoffice/forms/%s/fields/' % formdef2.id)
3689
    assert len(resp.forms['import-fields']['form'].options) == 4  # (empty, form1, form2, card1)
3690
    assert resp.pyquery('#import-fields optgroup').length == 2
3691

  
3692
    resp.forms['import-fields']['form'] = 'form:%s' % formdef1.id
3693
    resp = resp.forms['import-fields'].submit().follow()
3694
    assert 'Submitted form was not filled properly.' not in resp.text
3695

  
3696
    formdef2.refresh_from_storage()
3697
    assert [(x.id, x.label) for x in formdef2.fields] == [
3698
        ('1', 'field A'),
3699
        ('2', 'field 1'),
3700
        ('3', 'field 2'),
3701
    ]
3702

  
3703
    # import a card
3704
    resp.forms['import-fields']['form'] = 'card:%s' % carddef.id
3705
    resp = resp.forms['import-fields'].submit().follow()
3706
    formdef2.refresh_from_storage()
3707
    assert [(x.id, x.label) for x in formdef2.fields] == [
3708
        ('1', 'field A'),
3709
        ('2', 'field 1'),
3710
        ('3', 'field 2'),
3711
        ('4', 'field 3'),
3712
        ('5', 'field 4'),
3713
    ]
3714

  
3715
    # import while on a specific page
3716
    formdef3 = FormDef()
3717
    formdef3.name = 'form3 title'
3718
    formdef3.fields = [
3719
        fields.PageField(id='1', label='Page 1', type='page'),
3720
        fields.StringField(id='2', label='field 1', type='string'),
3721
        fields.PageField(id='3', label='Page 2', type='page'),
3722
    ]
3723
    formdef3.store()
3724

  
3725
    resp = app.get('/backoffice/forms/%s/fields/pages/1/' % formdef3.id)
3726
    resp.forms['import-fields']['form'] = 'card:%s' % carddef.id
3727
    resp = resp.forms['import-fields'].submit().follow()
3728
    formdef3.refresh_from_storage()
3729
    assert [(x.id, x.label) for x in formdef3.fields] == [
3730
        ('1', 'Page 1'),
3731
        ('2', 'field 1'),
3732
        ('4', 'field 3'),
3733
        ('5', 'field 4'),
3734
        ('3', 'Page 2'),
3735
    ]
wcs/admin/blocks.py
98 98
        r += htmltext('</div>')
99 99
        return r.getvalue()
100 100

  
101
    def get_new_field_form(self, page_id):
101
    def get_new_field_form_sidebar(self, page_id):
102 102
        r = TemplateIO(html=True)
103 103
        r += htmltext('<ul id="sidebar-actions">')
104 104
        r += htmltext('<li><a href="delete" rel="popup">%s</a></li>') % _('Delete')
......
110 110
        r += htmltext('<li><a href="inspect">%s</a></li>') % _('Inspector')
111 111
        r += htmltext('<li><a href="settings" rel="popup">%s</a></li>') % _('Settings')
112 112
        r += htmltext('</ul>')
113
        r += super().get_new_field_form(page_id=page_id)
113
        r += super().get_new_field_form_sidebar(page_id=page_id)
114 114
        return r.getvalue()
115 115

  
116 116
    def delete(self):
wcs/admin/fields.py
23 23

  
24 24
from wcs import fields
25 25
from wcs.admin import utils
26
from wcs.carddef import CardDef
26 27
from wcs.fields import BlockField, get_field_options
27 28
from wcs.formdef import FormDef
28 29
from wcs.qommon import _, errors, get_cfg, misc
29 30
from wcs.qommon.admin.menu import command_icon
30 31
from wcs.qommon.backoffice.menu import html_top
31
from wcs.qommon.form import CheckboxWidget, Form, HtmlWidget, SingleSelectWidget, StringWidget
32
from wcs.qommon.form import CheckboxWidget, Form, HtmlWidget, OptGroup, SingleSelectWidget, StringWidget
32 33
from wcs.qommon.substitution import CompatibilityNamesDict
33 34

  
34 35

  
......
480 481
                    snapshot=self.objectdef.snapshot_object, url_prefix=url_prefix, url_suffix=url_suffix
481 482
                )
482 483
        else:
483
            get_response().filter['sidebar'] = str(self.get_new_field_form(self.page_id))
484
            get_response().filter['sidebar'] = str(self.get_new_field_form_sidebar(self.page_id))
484 485
        r += self.index_bottom()
485 486
        return r.getvalue()
486 487

  
487
    def get_new_field_form(self, page_id):
488
    def get_new_field_form_sidebar(self, page_id):
488 489
        r = TemplateIO(html=True)
489 490
        ignore_hard_limits = get_publisher().has_site_option('ignore-hard-limits', default=False)
490 491

  
......
499 500
        r += htmltext('<div id="new-field">')
500 501
        r += htmltext('<h3>%s</h3>') % _('New Field')
501 502
        get_request().form = None  # ignore the eventual ?page=x
502
        form = Form(enctype='multipart/form-data', action='new')
503
        form = self.get_new_field_form(page_id)
504
        r += form.render()
505
        if self.support_import:
506
            form = self.get_import_fields_from(page_id)
507
            if form:
508
                r += form.render()
509
        r += htmltext('</div>')
510
        return r.getvalue()
511

  
512
    def get_new_field_form(self, page_id):
513
        form = Form(enctype='multipart/form-data', action='new', id='new-field')
503 514
        if page_id:
504 515
            form.add_hidden('page_id', page_id)
505 516
        form.add(StringWidget, 'label', title=_('Label'), required=True, size=50)
......
511 522
            options=get_field_options(self.blacklisted_types),
512 523
        )
513 524
        form.add_submit('submit', _('Add'))
514
        r += form.render()
515
        if self.support_import:
516
            form = Form(enctype='multipart/form-data', action='new')
517
            if page_id:
518
                form.add_hidden('page_id', page_id)
519
            form.add(
520
                SingleSelectWidget,
521
                'form',
522
                title=_('Or import fields from:'),
523
                required=True,
524
                options=[(None, '----', None)]
525
                + [
526
                    (x.id, x.name, x.id)
527
                    for x in FormDef.select(order_by='name', lightweight=True, ignore_errors=True)
528
                ],
529
            )
530
            form.add_submit('submit', _('Submit'))
531
            r += form.render()
532
        r += htmltext('</div>')
533
        return r.getvalue()
525
        return form
526

  
527
    def get_import_fields_from(self, page_id):
528
        formdefs = FormDef.select(order_by='name', lightweight=True, ignore_errors=True)
529
        carddefs = CardDef.select(order_by='name', lightweight=True, ignore_errors=True)
530
        if not (formdefs or carddefs):
531
            return
532
        options = [(None, '\u2500' * 5, None)]
533
        if formdefs and carddefs:
534
            options.append(OptGroup(_('Forms')))
535
        options.extend([(f'form:{x.id}', x.name, f'form:{x.id}') for x in formdefs])
536
        if formdefs and carddefs:
537
            options.append(OptGroup(_('Card Models')))
538
        options.extend([(f'card:{x.id}', x.name, f'card:{x.id}') for x in carddefs])
539
        form = Form(enctype='multipart/form-data', action='new', id='import-fields')
540
        if page_id:
541
            form.add_hidden('page_id', page_id)
542
        form.add(
543
            SingleSelectWidget,
544
            'form',
545
            title=_('Or import fields from:'),
546
            required=True,
547
            options=options,
548
        )
549
        form.add_submit('submit', _('Submit'))
550
        return form
534 551

  
535 552
    def index_top(self):
536 553
        r = TemplateIO(html=True)
......
640 657
        return redirect('.')
641 658

  
642 659
    def new(self):
643
        form = Form(enctype='multipart/form-data', action='new')
644
        form.add(StringWidget, 'page_id')
645
        form.add(StringWidget, 'label', title=_('Label'), size=50)
646
        form.add(
647
            SingleSelectWidget, 'type', title=_('Type'), options=get_field_options(self.blacklisted_types)
648
        )
649
        if FormDef.count():
650
            form.add(
651
                SingleSelectWidget,
652
                'form',
653
                title=_('Or import fields from:'),
654
                options=[(x.id, x.name, x.id) for x in FormDef.select(order_by='name', ignore_errors=True)],
655
            )
660
        form = Form(enctype='multipart/form-data')
661
        form.add_hidden('page_id')
662
        form.add_hidden('label')
663
        form.add_hidden('type')
664
        form.add_hidden('form')
656 665

  
657
        if not form.is_submitted() or form.has_errors():
666
        if not form.is_submitted():
658 667
            get_session().message = ('error', _('Submitted form was not filled properly.'))
659 668
            return redirect('.')
660 669

  
661
        try:
662
            page_id = form.get_widget('page_id').parse()
663
        except (TypeError, ValueError):
664
            page_id = None
670
        page_id = form.get_widget('page_id').parse()
665 671

  
666 672
        redirect_url = '.'
667
        if page_id is not None:
673
        if page_id:
668 674
            redirect_url = './?page=%s' % page_id
669 675
            on_page = False
670 676
            for i, field in enumerate(self.objectdef.fields):
......
690 696
            self.objectdef.fields.insert(insertion_point, field)
691 697
            self.objectdef.store(comment=self.new_field_history_message % field.ellipsized_label)
692 698
        elif form.get_widget('form') and form.get_widget('form').parse():
693
            formdef = FormDef.get(form.get_widget('form').parse())
699
            form_class, form_id = form.get_widget('form').parse().split(':')
700
            if form_class == 'form':
701
                formdef = FormDef.get(form_id)
702
            else:
703
                formdef = CardDef.get(form_id)
694 704
            for j, field in enumerate(formdef.fields):
695 705
                field.id = self.objectdef.get_new_field_id()
696 706
                self.objectdef.fields.insert(insertion_point + j, field)
697 707
            self.objectdef.store(comment=_('Import of fields from "%s"') % formdef.name)
698 708
        else:
699 709
            get_session().message = ('error', _('Submitted form was not filled properly.'))
700
            return redirect(redirect_url)
701 710

  
702 711
        return redirect(redirect_url)
703
-