misc: add support for dynamic views filtered on dates (#64991) #1175
|
@ -1777,6 +1777,102 @@ def test_dynamic_item_field_from_custom_view_on_cards(pub, field_type):
|
|||
assert logged_error.summary == '[DATASOURCE] Unknown custom view "as-data-source" for CardDef "items"'
|
||||
|
||||
|
||||
def test_dynamic_date_field_from_custom_view_on_cards(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.wipe()
|
||||
formdef = FormDef()
|
||||
formdef.name = 'test'
|
||||
formdef.fields = []
|
||||
formdef.store()
|
||||
formdef.data_class().wipe()
|
||||
|
||||
CardDef.wipe()
|
||||
carddef = CardDef()
|
||||
carddef.name = 'items'
|
||||
carddef.digest_templates = {'default': '{{form_var_attr}}'}
|
||||
carddef.workflow_roles = {'_editor': user.roles[0]}
|
||||
carddef.fields = [
|
||||
fields.StringField(id='1', label='string', varname='attr'),
|
||||
fields.DateField(id='2', label='date'),
|
||||
]
|
||||
carddef.store()
|
||||
carddef.data_class().wipe()
|
||||
for i, value in enumerate(['foo', 'bar', 'baz']):
|
||||
carddata = carddef.data_class()()
|
||||
carddata.data = {
|
||||
'1': value,
|
||||
'2': datetime.date(2024, 1, 1 + i).timetuple(),
|
||||
}
|
||||
carddata.just_created()
|
||||
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-2'].checked = True
|
||||
resp.forms['listing-settings']['filter-status'].checked = True
|
||||
resp = resp.forms['listing-settings'].submit()
|
||||
|
||||
resp.forms['listing-settings']['filter'].value = 'recorded'
|
||||
resp = resp.forms['listing-settings'].submit()
|
||||
|
||||
resp.forms['save-custom-view']['title'] = 'as data source'
|
||||
resp.forms['save-custom-view']['visibility'] = 'datasource'
|
||||
resp = resp.forms['save-custom-view'].submit().follow()
|
||||
|
||||
# make sure <input type=date> is not used, so a template can be entered
|
||||
assert resp.pyquery('[name="filter-2-value"]')[0].attrib['type'] == 'text'
|
||||
resp.forms['listing-settings']['filter-2-value'] = '{{ form_var_blah }}'
|
||||
resp.forms['listing-settings']['filter-2-operator'].value = 'gte'
|
||||
|
||||
resp = resp.forms['listing-settings'].submit()
|
||||
assert resp.forms['listing-settings']['filter-2-value'].value == '{{ form_var_blah }}'
|
||||
assert resp.text.count('<tr') == 1 # thead only
|
||||
|
||||
# save custom view with filter
|
||||
resp = resp.forms['save-custom-view'].submit().follow()
|
||||
|
||||
custom_view = pub.custom_view_class.select()[0]
|
||||
|
||||
# use custom view as source
|
||||
ds = {'type': 'carddef:%s:%s' % (carddef.url_name, custom_view.slug)}
|
||||
formdef.fields = [
|
||||
fields.PageField(id='2', label='1st page'),
|
||||
fields.ItemField(
|
||||
id='0', label='item', varname='blah', items=['2023-01-02', '2024-01-02', '2025-01-02']
|
||||
),
|
||||
fields.ItemField(id='1', label='string', data_source=ds, display_disabled_items=True),
|
||||
]
|
||||
formdef.store()
|
||||
|
||||
resp = get_app(pub).get('/test/')
|
||||
assert resp.form['f1'].options == [('', False, '---')]
|
||||
resp.form['f0'] = '2024-01-02'
|
||||
live_resp = app.post('/test/live?modified_field_id[]=0', params=resp.form.submit_fields())
|
||||
assert live_resp.json['result']['1']['items'] == [
|
||||
{'attr': 'bar', 'id': 2, 'text': 'bar'},
|
||||
{'attr': 'baz', 'id': 3, 'text': 'baz'},
|
||||
]
|
||||
|
||||
resp.form['f0'] = '2023-01-02'
|
||||
live_resp = app.post('/test/live?modified_field_id[]=0', params=resp.form.submit_fields())
|
||||
assert len(live_resp.json['result']['1']['items']) == 3
|
||||
|
||||
resp.form['f0'] = '2025-01-02'
|
||||
live_resp = app.post('/test/live?modified_field_id[]=0', params=resp.form.submit_fields())
|
||||
assert len(live_resp.json['result']['1']['items']) == 0
|
||||
|
||||
|
||||
def test_dynamic_item_fields_from_custom_view_on_cards(pub):
|
||||
pub.role_class.wipe()
|
||||
pub.custom_view_class.wipe()
|
||||
|
|
|
@ -1454,18 +1454,12 @@ class FormPage(Directory, TempfileDirectoryMixin):
|
|||
)
|
||||
r += render_widget(widget, operators)
|
||||
|
||||
elif filter_field.key in ('string', 'text', 'email', 'numeric'):
|
||||
elif filter_field.key in ('string', 'text', 'email', 'numeric', 'date'):
|
||||
widget = StringWidget(
|
||||
filter_field_key, title=filter_field.label, value=filter_field_value, render_br=False
|
||||
)
|
||||
r += render_widget(widget, operators)
|
||||
|
||||
elif filter_field.key == 'date':
|
||||
widget = DateWidget(
|
||||
filter_field_key, title=filter_field.label, value=filter_field_value, render_br=False
|
||||
)
|
||||
r += render_widget(widget, operators)
|
||||
|
||||
|
||||
# field filter dialog content
|
||||
r += htmltext('<div style="display: none;">')
|
||||
r += htmltext('<ul id="field-filter" class="objects-list">')
|
||||
|
@ -2215,7 +2209,7 @@ class FormPage(Directory, TempfileDirectoryMixin):
|
|||
filter_field_value = False
|
||||
else:
|
||||
raise RequestError('Invalid value "%s" for "%s"' % (filter_field_value, filter_field_key))
|
||||
elif filter_field.key in ('item', 'items', 'string', 'email', 'numeric'):
|
||||
elif filter_field.key in ('item', 'items', 'string', 'email', 'numeric', 'date'):
|
||||
if Template.is_template_string(filter_field_value, ezt_support=False):
|
||||
if keep_templates:
|
||||
# use Equal criteria here, the only use is in CardDef.get_data_source_referenced_varnames
|
||||
|
|
Loading…
Reference in New Issue
Cette partie n'était plus effective avec l'ajout des opérateurs, le render_widget() appelle directement render_content(), qui ne passait pas par le gabarit HTML du widget, et fournissait déjà un input type="text" (mais avec un maxlength à 12, pas opportun pour les gabarits).