Projet

Général

Profil

0002-cards-add-status-operator-support-to-custom-card-dat.patch

Frédéric Péters, 14 mai 2022 14:39

Télécharger (6,79 ko)

Voir les différences:

Subject: [PATCH 2/2] cards: add status operator support to custom card data
 sources (#65248)

 tests/form_pages/test_all.py | 91 ++++++++++++++++++++++++++++++++++++
 wcs/backoffice/management.py |  2 +-
 wcs/custom_views.py          | 16 +++++--
 3 files changed, 105 insertions(+), 4 deletions(-)
tests/form_pages/test_all.py
5897 5897
    assert formdef.data_class().select()[0].data['0_display'] == 'Xattr%sY' % baz_id
5898 5898

  
5899 5899

  
5900
def test_item_field_from_custom_view_on_cards_filter_status(pub):
5901
    pub.role_class.wipe()
5902
    pub.custom_view_class.wipe()
5903

  
5904
    user = create_user(pub)
5905
    role = pub.role_class(name='xxx')
5906
    role.store()
5907
    user.roles = [role.id]
5908
    user.is_admin = True
5909
    user.store()
5910

  
5911
    formdef = create_formdef()
5912
    formdef.data_class().wipe()
5913

  
5914
    card_workflow = CardDef.get_default_workflow()
5915
    st1 = card_workflow.add_status('Status1', 'st1')
5916
    card_workflow.id = None
5917
    card_workflow.store()
5918

  
5919
    CardDef.wipe()
5920
    carddef = CardDef()
5921
    carddef.workflow_id = card_workflow.id
5922
    carddef.name = 'items'
5923
    carddef.digest_templates = {'default': '{{form_var_attr}}'}
5924
    carddef.workflow_roles = {'_editor': user.roles[0]}
5925
    carddef.fields = [
5926
        fields.ItemField(id='0', type='item', label='item', varname='item', items=['foo', 'bar', 'baz']),
5927
        fields.StringField(id='1', type='string', label='string', varname='attr'),
5928
    ]
5929
    carddef.store()
5930
    carddef.data_class().wipe()
5931
    for i, value in enumerate(['foo', 'bar', 'baz']):
5932
        carddata = carddef.data_class()()
5933
        carddata.data = {
5934
            '0': value,
5935
            '0_display': value,
5936
            '1': 'attr%s' % (i + 1),
5937
        }
5938
        carddata.just_created()
5939
        carddata.store()
5940

  
5941
    carddata.jump_status(st1.id)
5942
    carddata.store()
5943

  
5944
    # create custom view
5945
    app = login(get_app(pub), username='foo', password='foo')
5946

  
5947
    resp = app.get('/backoffice/data/items/')
5948
    resp.forms['listing-settings']['filter-status'].checked = True
5949
    resp = resp.forms['listing-settings'].submit()
5950
    resp.forms['listing-settings']['filter-operator'].value = 'ne'
5951
    resp.forms['listing-settings']['filter'].value = 'st1'
5952
    resp = resp.forms['listing-settings'].submit()
5953
    assert resp.pyquery('tbody tr').length == 2
5954

  
5955
    resp.forms['save-custom-view']['title'] = 'as data source'
5956
    resp.forms['save-custom-view']['visibility'] = 'datasource'
5957
    resp = resp.forms['save-custom-view'].submit()
5958

  
5959
    custom_view = pub.custom_view_class.select()[0]
5960
    assert custom_view.filters == {'filter-operator': 'ne', 'filter': 'st1', 'filter-status': 'on'}
5961

  
5962
    # use custom view as source
5963
    ds = {'type': 'carddef:%s:%s' % (carddef.url_name, custom_view.slug)}
5964
    formdef.fields = [
5965
        fields.ItemField(id='0', label='string', type='item', data_source=ds, display_disabled_items=True)
5966
    ]
5967
    formdef.store()
5968

  
5969
    resp = get_app(pub).get('/test/')
5970
    assert len(resp.form['f0'].options) == 2
5971
    assert {x[2] for x in resp.form['f0'].options} == {'attr1', 'attr2'}
5972

  
5973
    custom_view.filters['filter-operator'] = 'eq'
5974
    custom_view.store()
5975
    resp = get_app(pub).get('/test/')
5976
    assert [x[2] for x in resp.form['f0'].options] == ['attr3']
5977

  
5978
    custom_view.filters['filter'] = 'all'
5979
    custom_view.store()
5980
    resp = get_app(pub).get('/test/')
5981
    assert len(resp.form['f0'].options) == 3
5982

  
5983
    custom_view.filters['filter'] = 'all'
5984
    custom_view.filters['filter-operator'] = 'ne'
5985
    custom_view.store()
5986
    resp = get_app(pub).get('/test/')
5987
    assert len(resp.form['f0'].options) == 1
5988
    assert [x[2] for x in resp.form['f0'].options] == ['---']
5989

  
5990

  
5900 5991
@pytest.mark.parametrize('filter_value', ['{{ "foo" }}', 'foo'])
5901 5992
def test_items_field_from_custom_view_on_cards(pub, filter_value):
5902 5993
    pub.role_class.wipe()
wcs/backoffice/management.py
1767 1767
    def get_filter_operator_from_query(self):
1768 1768
        default_filter_operator = 'eq'
1769 1769
        if self.view:
1770
            default_filter_operator = self.view.filters.get('filter-operator', 'eq')
1770
            default_filter_operator = self.view.get_status_filter_operator()
1771 1771
        operator = get_request().form.get('filter-operator') or default_filter_operator
1772 1772
        if operator not in ['eq', 'ne']:
1773 1773
            raise RequestError('Invalid operator "%s" for "filter-operator"' % operator)
wcs/custom_views.py
23 23
from wcs.carddef import CardDef
24 24
from wcs.formdef import FormDef
25 25
from wcs.qommon.misc import simplify
26
from wcs.qommon.storage import Contains, Equal, StorableObject
26
from wcs.qommon.storage import Contains, Equal, NotContains, StorableObject
27 27

  
28 28
from .qommon.misc import xml_node_text
29 29

  
......
144 144
    def get_filter(self):
145 145
        return self.filters.get('filter')
146 146

  
147
    def get_status_filter_operator(self):
148
        return self.filters.get('filter-operator', 'eq')
149

  
147 150
    def get_filters_dict(self):
148 151
        return self.filters
149 152

  
......
166 169
        )
167 170

  
168 171
        selected_filter = self.get_filter()
169
        if selected_filter and selected_filter != 'all':
172
        selected_status_filter_operator = self.get_status_filter_operator()
173
        if selected_filter and selected_filter == 'all':
174
            if selected_status_filter_operator == 'ne':
175
                criterias.append(Equal('status', '_none'))
176
        elif selected_filter:
170 177
            if selected_filter == 'pending':
171 178
                applied_filters = ['wf-%s' % x.id for x in formdef.workflow.get_not_endpoint_status()]
172 179
            elif selected_filter == 'done':
......
174 181
            else:
175 182
                applied_filters = ['wf-%s' % selected_filter]
176 183
            if applied_filters:
177
                criterias.append(Contains('status', applied_filters))
184
                if selected_status_filter_operator == 'eq':
185
                    criterias.append(Contains('status', applied_filters))
186
                elif selected_status_filter_operator == 'ne':
187
                    criterias.append(NotContains('status', applied_filters))
178 188

  
179 189
        return criterias
180 190

  
181
-