Projet

Général

Profil

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

Frédéric Péters, 06 mai 2022 11:24

Télécharger (7,57 ko)

Voir les différences:

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

 tests/backoffice_pages/test_filters.py | 88 ++++++++++++++++++++++++++
 wcs/backoffice/management.py           |  8 +--
 wcs/fields.py                          | 48 ++++++++++----
 3 files changed, 125 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'):
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
    app = login(get_app(pub))
761
    resp = app.get('/backoffice/management/%s/' % formdef.url_name)
762
    assert resp.pyquery('tbody tr').length == 2
763
    resp.forms['listing-settings']['filter-1'].checked = True
764
    resp = resp.forms['listing-settings'].submit()
765

  
766
    if pub.is_using_postgresql():
767
        # option 'bar' is never used so not even listed
768
        assert [x[2] for x in resp.forms['listing-settings']['filter-1-value'].options] == [
769
            '',
770
            'card baz',
771
            'card foo',
772
        ]
773
    else:
774
        assert [x[2] for x in resp.forms['listing-settings']['filter-1-value'].options] == [
775
            '',
776
            'card bar',
777
            'card baz',
778
            'card foo',
779
        ]
780

  
781
    resp.forms['listing-settings']['filter-1-value'].value = card_ids['foo']
782
    resp = resp.forms['listing-settings'].submit()
783
    assert resp.pyquery('tbody tr').length == 2
784

  
785
    resp.forms['listing-settings']['filter-1-value'].value = card_ids['baz']
786
    resp = resp.forms['listing-settings'].submit()
787
    assert resp.pyquery('tbody tr').length == 1
788

  
789

  
702 790
def test_backoffice_string_filter(pub):
703 791
    pub.user_class.wipe()
704 792
    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
82 82
)
83 83
from .qommon.ods import NS as OD_NS
84 84
from .qommon.ods import clean_text as od_clean_text
85
from .qommon.storage import Contains
85 86
from .qommon.template import Template, TemplateError
86 87
from .qommon.upload_storage import PicklableUpload
87 88
from .sessions import BasicSession
......
1906 1907
            data_source_type.set_value(None)
1907 1908
            data_source_type.transfer_form_value(get_request())
1908 1909

  
1910
    def get_carddef(self):
1911
        from wcs.carddef import CardDef
1912

  
1913
        if (
1914
            not self.data_source
1915
            or not self.data_source.get('type')
1916
            or not self.data_source['type'].startswith('carddef:')
1917
        ):
1918
            return None
1919

  
1920
        carddef_slug = self.data_source['type'].split(':')[1]
1921
        try:
1922
            return CardDef.get_by_urlname(carddef_slug)
1923
        except KeyError:
1924
            return None
1925

  
1909 1926

  
1910 1927
class ItemField(WidgetField, MapOptionsMixin, ItemFieldMixin):
1911 1928
    key = 'item'
......
1980 1997

  
1981 1998
        return self.display_mode
1982 1999

  
1983
    def get_carddef(self):
1984
        from wcs.carddef import CardDef
1985

  
1986
        if not self.data_source['type'].startswith('carddef:'):
1987
            return None
1988

  
1989
        carddef_slug = self.data_source['type'].split(':')[1]
1990
        try:
1991
            return CardDef.get_by_urlname(carddef_slug)
1992
        except KeyError:
1993
            return None
1994

  
1995 2000
    def perform_more_widget_changes(self, form, kwargs, edit=True):
1996 2001
        data_source = data_sources.get_object(self.data_source)
1997 2002
        display_mode = self.get_display_mode(data_source)
......
2537 2542
            return value
2538 2543
        return []
2539 2544

  
2545
    def get_exploded_options(self, options):
2546
        carddef = self.get_carddef()
2547
        if not carddef:
2548
            # unnest key/values
2549
            exploded_options = {}
2550
            for option_keys, option_label in options:
2551
                if option_keys and option_label:
2552
                    for option_key, option_label in zip(option_keys, option_label.split(', ')):
2553
                        exploded_options[option_key] = option_label
2554
            return exploded_options.items()
2555

  
2556
        options_ids = set()
2557
        for option in options:
2558
            options_ids.update(set(option[0]))
2559

  
2560
        cards = carddef.data_class().select([Contains('id', options_ids)])
2561

  
2562
        return [(str(x.id), x.get_display_label()) for x in cards]
2563

  
2540 2564

  
2541 2565
register_field_class(ItemsField)
2542 2566

  
2543
-