cards: add status operator support to custom card data sources (#65248)
This commit is contained in:
parent
613dec5d33
commit
7be05db469
|
@ -5897,6 +5897,97 @@ def test_item_field_from_custom_view_on_cards(pub):
|
|||
assert formdef.data_class().select()[0].data['0_display'] == 'Xattr%sY' % baz_id
|
||||
|
||||
|
||||
def test_item_field_from_custom_view_on_cards_filter_status(pub):
|
||||
pub.role_class.wipe()
|
||||
pub.custom_view_class.wipe()
|
||||
|
||||
user = create_user(pub)
|
||||
role = pub.role_class(name='xxx')
|
||||
role.store()
|
||||
user.roles = [role.id]
|
||||
user.is_admin = True
|
||||
user.store()
|
||||
|
||||
formdef = create_formdef()
|
||||
formdef.data_class().wipe()
|
||||
|
||||
card_workflow = CardDef.get_default_workflow()
|
||||
st1 = card_workflow.add_status('Status1', 'st1')
|
||||
card_workflow.id = None
|
||||
card_workflow.store()
|
||||
|
||||
CardDef.wipe()
|
||||
carddef = CardDef()
|
||||
carddef.workflow_id = card_workflow.id
|
||||
carddef.name = 'items'
|
||||
carddef.digest_templates = {'default': '{{form_var_attr}}'}
|
||||
carddef.workflow_roles = {'_editor': user.roles[0]}
|
||||
carddef.fields = [
|
||||
fields.ItemField(id='0', type='item', label='item', varname='item', items=['foo', 'bar', 'baz']),
|
||||
fields.StringField(id='1', type='string', label='string', varname='attr'),
|
||||
]
|
||||
carddef.store()
|
||||
carddef.data_class().wipe()
|
||||
for i, value in enumerate(['foo', 'bar', 'baz']):
|
||||
carddata = carddef.data_class()()
|
||||
carddata.data = {
|
||||
'0': value,
|
||||
'0_display': value,
|
||||
'1': 'attr%s' % (i + 1),
|
||||
}
|
||||
carddata.just_created()
|
||||
carddata.store()
|
||||
|
||||
carddata.jump_status(st1.id)
|
||||
carddata.store()
|
||||
|
||||
# create custom view
|
||||
app = login(get_app(pub), username='foo', password='foo')
|
||||
|
||||
resp = app.get('/backoffice/data/items/')
|
||||
resp.forms['listing-settings']['filter-status'].checked = True
|
||||
resp = resp.forms['listing-settings'].submit()
|
||||
resp.forms['listing-settings']['filter-operator'].value = 'ne'
|
||||
resp.forms['listing-settings']['filter'].value = 'st1'
|
||||
resp = resp.forms['listing-settings'].submit()
|
||||
assert resp.pyquery('tbody tr').length == 2
|
||||
|
||||
resp.forms['save-custom-view']['title'] = 'as data source'
|
||||
resp.forms['save-custom-view']['visibility'] = 'datasource'
|
||||
resp = resp.forms['save-custom-view'].submit()
|
||||
|
||||
custom_view = pub.custom_view_class.select()[0]
|
||||
assert custom_view.filters == {'filter-operator': 'ne', 'filter': 'st1', 'filter-status': 'on'}
|
||||
|
||||
# use custom view as source
|
||||
ds = {'type': 'carddef:%s:%s' % (carddef.url_name, custom_view.slug)}
|
||||
formdef.fields = [
|
||||
fields.ItemField(id='0', label='string', type='item', data_source=ds, display_disabled_items=True)
|
||||
]
|
||||
formdef.store()
|
||||
|
||||
resp = get_app(pub).get('/test/')
|
||||
assert len(resp.form['f0'].options) == 2
|
||||
assert {x[2] for x in resp.form['f0'].options} == {'attr1', 'attr2'}
|
||||
|
||||
custom_view.filters['filter-operator'] = 'eq'
|
||||
custom_view.store()
|
||||
resp = get_app(pub).get('/test/')
|
||||
assert [x[2] for x in resp.form['f0'].options] == ['attr3']
|
||||
|
||||
custom_view.filters['filter'] = 'all'
|
||||
custom_view.store()
|
||||
resp = get_app(pub).get('/test/')
|
||||
assert len(resp.form['f0'].options) == 3
|
||||
|
||||
custom_view.filters['filter'] = 'all'
|
||||
custom_view.filters['filter-operator'] = 'ne'
|
||||
custom_view.store()
|
||||
resp = get_app(pub).get('/test/')
|
||||
assert len(resp.form['f0'].options) == 1
|
||||
assert [x[2] for x in resp.form['f0'].options] == ['---']
|
||||
|
||||
|
||||
@pytest.mark.parametrize('filter_value', ['{{ "foo" }}', 'foo'])
|
||||
def test_items_field_from_custom_view_on_cards(pub, filter_value):
|
||||
pub.role_class.wipe()
|
||||
|
|
|
@ -1767,7 +1767,7 @@ class FormPage(Directory):
|
|||
def get_filter_operator_from_query(self):
|
||||
default_filter_operator = 'eq'
|
||||
if self.view:
|
||||
default_filter_operator = self.view.filters.get('filter-operator', 'eq')
|
||||
default_filter_operator = self.view.get_status_filter_operator()
|
||||
operator = get_request().form.get('filter-operator') or default_filter_operator
|
||||
if operator not in ['eq', 'ne']:
|
||||
raise RequestError('Invalid operator "%s" for "filter-operator"' % operator)
|
||||
|
|
|
@ -23,7 +23,7 @@ from quixote import get_publisher
|
|||
from wcs.carddef import CardDef
|
||||
from wcs.formdef import FormDef
|
||||
from wcs.qommon.misc import simplify
|
||||
from wcs.qommon.storage import Contains, Equal, StorableObject
|
||||
from wcs.qommon.storage import Contains, Equal, NotContains, StorableObject
|
||||
|
||||
from .qommon.misc import xml_node_text
|
||||
|
||||
|
@ -144,6 +144,9 @@ class CustomView(StorableObject):
|
|||
def get_filter(self):
|
||||
return self.filters.get('filter')
|
||||
|
||||
def get_status_filter_operator(self):
|
||||
return self.filters.get('filter-operator', 'eq')
|
||||
|
||||
def get_filters_dict(self):
|
||||
return self.filters
|
||||
|
||||
|
@ -166,7 +169,11 @@ class CustomView(StorableObject):
|
|||
)
|
||||
|
||||
selected_filter = self.get_filter()
|
||||
if selected_filter and selected_filter != 'all':
|
||||
selected_status_filter_operator = self.get_status_filter_operator()
|
||||
if selected_filter and selected_filter == 'all':
|
||||
if selected_status_filter_operator == 'ne':
|
||||
criterias.append(Equal('status', '_none'))
|
||||
elif selected_filter:
|
||||
if selected_filter == 'pending':
|
||||
applied_filters = ['wf-%s' % x.id for x in formdef.workflow.get_not_endpoint_status()]
|
||||
elif selected_filter == 'done':
|
||||
|
@ -174,7 +181,10 @@ class CustomView(StorableObject):
|
|||
else:
|
||||
applied_filters = ['wf-%s' % selected_filter]
|
||||
if applied_filters:
|
||||
criterias.append(Contains('status', applied_filters))
|
||||
if selected_status_filter_operator == 'eq':
|
||||
criterias.append(Contains('status', applied_filters))
|
||||
elif selected_status_filter_operator == 'ne':
|
||||
criterias.append(NotContains('status', applied_filters))
|
||||
|
||||
return criterias
|
||||
|
||||
|
|
Loading…
Reference in New Issue