Projet

Général

Profil

0001-backoffice-get-items-filter-options-from-existing-ca.patch

Frédéric Péters, 25 mai 2022 21:50

Télécharger (7,97 ko)

Voir les différences:

Subject: [PATCH] backoffice: get items filter options from existing cards
 (#48881)

 tests/backoffice_pages/test_filters.py | 98 ++++++++++++++++++++++++++
 wcs/backoffice/management.py           |  8 +--
 wcs/fields.py                          | 48 +++++++++----
 3 files changed, 135 insertions(+), 19 deletions(-)
tests/backoffice_pages/test_filters.py
6 6

  
7 7
from wcs import fields
8 8
from wcs.blocks import BlockDef
9
from wcs.carddef import CardDef
9 10
from wcs.data_sources import NamedDataSource
10 11
from wcs.formdef import FormDef
11 12
from wcs.qommon.http_request import HTTPRequest
......
699 700
        assert resp.text.count('data-link') == 0  # no rows
700 701

  
701 702

  
703
def test_backoffice_items_cards_filter(pub):
704
    pub.user_class.wipe()
705
    create_superuser(pub)
706
    pub.role_class.wipe()
707
    role = pub.role_class(name='test')
708
    role.store()
709

  
710
    CardDef.wipe()
711
    carddef = CardDef()
712
    carddef.name = 'foo'
713
    carddef.fields = [
714
        fields.StringField(id='1', label='Test', type='string', varname='foo'),
715
    ]
716
    carddef.digest_templates = {'default': 'card {{ form_var_foo }}'}
717
    carddef.store()
718

  
719
    card_ids = {}
720
    for label in ('foo', 'bar', 'baz', 'foo, bar'):
721
        card = carddef.data_class()()
722
        card.data = {'1': label}
723
        card.just_created()
724
        card.store()
725
        card_ids[label] = str(card.id)
726

  
727
    FormDef.wipe()
728
    formdef = FormDef()
729
    formdef.name = 'form-title'
730
    formdef.fields = [
731
        fields.ItemsField(
732
            id='1',
733
            label='items',
734
            type='items',
735
            data_source={'type': 'carddef:foo', 'value': ''},
736
        )
737
    ]
738
    formdef.workflow_roles = {'_receiver': role.id}
739
    formdef.store()
740

  
741
    data_class = formdef.data_class()
742
    data_class.wipe()
743

  
744
    formdata = data_class()
745
    formdata.data = {'1': [card_ids['foo']]}
746
    formdata.data['1_display'] = formdef.fields[0].store_display_value(formdata.data, '1')
747
    formdata.data['1_structured'] = formdef.fields[0].store_structured_value(formdata.data, '1')
748
    formdata.just_created()
749
    formdata.jump_status('new')
750
    formdata.store()
751

  
752
    formdata = data_class()
753
    formdata.data = {'1': [card_ids['foo'], card_ids['baz']]}
754
    formdata.data['1_display'] = formdef.fields[0].store_display_value(formdata.data, '1')
755
    formdata.data['1_structured'] = formdef.fields[0].store_structured_value(formdata.data, '1')
756
    formdata.just_created()
757
    formdata.jump_status('new')
758
    formdata.store()
759

  
760
    formdata = data_class()
761
    formdata.data = {'1': [card_ids['foo, bar']]}
762
    formdata.data['1_display'] = formdef.fields[0].store_display_value(formdata.data, '1')
763
    formdata.data['1_structured'] = formdef.fields[0].store_structured_value(formdata.data, '1')
764
    formdata.just_created()
765
    formdata.jump_status('new')
766
    formdata.store()
767

  
768
    app = login(get_app(pub))
769
    resp = app.get('/backoffice/management/%s/' % formdef.url_name)
770
    assert resp.pyquery('tbody tr').length == 3
771
    resp.forms['listing-settings']['filter-1'].checked = True
772
    resp = resp.forms['listing-settings'].submit()
773

  
774
    if pub.is_using_postgresql():
775
        # option 'bar' is never used so not even listed
776
        assert [x[2] for x in resp.forms['listing-settings']['filter-1-value'].options] == [
777
            '',
778
            'card baz',
779
            'card foo',
780
            'card foo, bar',
781
        ]
782
    else:
783
        assert [x[2] for x in resp.forms['listing-settings']['filter-1-value'].options] == [
784
            '',
785
            'card bar',
786
            'card baz',
787
            'card foo',
788
            'card foo, bar',
789
        ]
790

  
791
    resp.forms['listing-settings']['filter-1-value'].value = card_ids['foo']
792
    resp = resp.forms['listing-settings'].submit()
793
    assert resp.pyquery('tbody tr').length == 2
794

  
795
    resp.forms['listing-settings']['filter-1-value'].value = card_ids['baz']
796
    resp = resp.forms['listing-settings'].submit()
797
    assert resp.pyquery('tbody tr').length == 1
798

  
799

  
702 800
def test_backoffice_string_filter(pub):
703 801
    pub.user_class.wipe()
704 802
    create_superuser(pub)
wcs/backoffice/management.py
1002 1002
            )
1003 1003

  
1004 1004
        if filter_field.type == 'items':
1005
            # unnest key/values
1006
            exploded_options = {}
1007
            for option_keys, option_label in options:
1008
                if option_keys and option_label:
1009
                    for option_key, option_label in zip(option_keys, option_label.split(', ')):
1010
                        exploded_options[option_key] = option_label
1011
            options = list(sorted(exploded_options.items(), key=lambda x: x[1]))
1005
            options = list(sorted(filter_field.get_exploded_options(options), key=lambda x: x[1]))
1012 1006

  
1013 1007
        options = [(force_str(x), force_str(y)) for x, y in options if x and y]
1014 1008

  
wcs/fields.py
84 84
)
85 85
from .qommon.ods import NS as OD_NS
86 86
from .qommon.ods import clean_text as od_clean_text
87
from .qommon.storage import Contains
87 88
from .qommon.template import Template, TemplateError
88 89
from .qommon.upload_storage import PicklableUpload
89 90
from .sessions import BasicSession
......
2049 2050
    def get_data_source_parameter_view_label(self):
2050 2051
        return str(_('Data source'))
2051 2052

  
2053
    def get_carddef(self):
2054
        from wcs.carddef import CardDef
2055

  
2056
        if (
2057
            not self.data_source
2058
            or not self.data_source.get('type')
2059
            or not self.data_source['type'].startswith('carddef:')
2060
        ):
2061
            return None
2062

  
2063
        carddef_slug = self.data_source['type'].split(':')[1]
2064
        try:
2065
            return CardDef.get_by_urlname(carddef_slug)
2066
        except KeyError:
2067
            return None
2068

  
2052 2069

  
2053 2070
class ItemField(WidgetField, MapOptionsMixin, ItemFieldMixin):
2054 2071
    key = 'item'
......
2123 2140

  
2124 2141
        return self.display_mode
2125 2142

  
2126
    def get_carddef(self):
2127
        from wcs.carddef import CardDef
2128

  
2129
        if not self.data_source['type'].startswith('carddef:'):
2130
            return None
2131

  
2132
        carddef_slug = self.data_source['type'].split(':')[1]
2133
        try:
2134
            return CardDef.get_by_urlname(carddef_slug)
2135
        except KeyError:
2136
            return None
2137

  
2138 2143
    def perform_more_widget_changes(self, form, kwargs, edit=True):
2139 2144
        data_source = data_sources.get_object(self.data_source)
2140 2145
        display_mode = self.get_display_mode(data_source)
......
2698 2703
            return value
2699 2704
        return []
2700 2705

  
2706
    def get_exploded_options(self, options):
2707
        carddef = self.get_carddef()
2708
        if not carddef:
2709
            # unnest key/values
2710
            exploded_options = {}
2711
            for option_keys, option_label in options:
2712
                if option_keys and option_label:
2713
                    for option_key, option_label in zip(option_keys, option_label.split(', ')):
2714
                        exploded_options[option_key] = option_label
2715
            return exploded_options.items()
2716

  
2717
        options_ids = set()
2718
        for option in options:
2719
            options_ids.update(set(option[0]))
2720

  
2721
        cards = carddef.data_class().select([Contains('id', options_ids)])
2722

  
2723
        return [(str(x.id), x.get_display_label()) for x in cards]
2724

  
2701 2725

  
2702 2726
register_field_class(ItemsField)
2703 2727

  
2704
-