Commit 3cd1b20e authored by Tristan Cavelier's avatar Tristan Cavelier Committed by Romain Courteaud

[erp5_web_renderjs_ui] Add "Equal to (at least one)" operator in filter editor

- the "Equal to (at least one)" operator is displayed in the same listbox as "Equal to" and "Contains" ;
- this filter item can have multiple input value field ;
- one input value field has to be filled (required) like on the other filter items ;
- when extended_search is `title: ( "One" OR "Two" )`, behavior changed :

    ________before________  ______________now______________

         Filter Editor               Filter Editor
    [ At least one (OR) v]  [ All criterions (AND)______ v]
    [-][ Title_________ v]  [-][ Title__________________ v]
       [ Equal to______ v]     [ Equal to (at least one) v]
       [ One___________ x]     [ One____________________ x]
    [-][ Title_________ v]     [ Two____________________ x]
       [ Equal to______ v]     [ _______________________  ]
       [ Two___________ x]  [+]
    [+]

         Search bar                  Search bar
    [One][Two][ _______  ]  [One][Two][ ________________  ]
parent e22aebf1
......@@ -5,6 +5,7 @@
data-i18n=At least one (OR)
data-i18n=Contains
data-i18n=Equal to
data-i18n=Equal to (at least one)
data-i18n=Greater than
data-i18n=Less than
data-i18n=Less than or Equal to
......@@ -47,7 +48,13 @@
{{/each}}
</select>
{{else}}
{{#if input_list}}
{{#each input_list}}
<input type="{{type}}" value="{{value}}" {{required}}></input>
{{/each}}
{{else}}
<input type="{{input_type}}" value="{{input_value}}" required></input>
{{/if}}
{{/if}}
</div>
</script>
......
......@@ -232,7 +232,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>970.21317.37622.46984</string> </value>
<value> <string>971.30474.16448.375</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -250,7 +250,7 @@
</tuple>
<state>
<tuple>
<float>1537370335.59</float>
<float>1550073322.86</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -228,7 +228,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>972.18557.43984.10752</string> </value>
<value> <string>973.42226.24018.7099</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -246,7 +246,7 @@
</tuple>
<state>
<tuple>
<float>1546525761.18</float>
<float>1550070921.26</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -135,6 +135,27 @@
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_search_in_form_list" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/triggle_filter_and" />
<tal:block tal:define="filter_section_configuration python: {'key': 'COLUMN_id', 'value': '0', 'index': 0}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/set_filter_section" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/add_new_filter_section" />
<tal:block tal:define="filter_section_configuration python: {'key': 'COLUMN_title', 'operator': 'at_least_one_exact_match', 'value': ['Title 0', 'Title 1'], 'index': 1}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/set_filter_section" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_filter" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tal:block tal:define="parsed_query python: '( id:&nbsp; &#34;0&#34; AND title: (&nbsp; &#34;Title 0&#34; OR&nbsp; &#34;Title 1&#34; ) )';
search_query python: ''">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_search_in_form_list" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/triggle_filter_and" />
<tal:block tal:define="filter_section_configuration python: {'key': 'COLUMN_title', 'operator': 'at_least_one_exact_match', 'value': ['Title 0', 'Title 1'], 'index': 1}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_filter_section" />
</tal:block>
</tbody></table>
</body>
</html>
\ No newline at end of file
......@@ -94,12 +94,17 @@
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[@class='filter_item_container']/div[1]//select[2]//option[2][@value='keyword' and text()='Contains']</td>
<td>//div[@class='filter_item_container']/div[1]//select[2]//option[2][@value='at_least_one_exact_match' and text()='Equal to (at least one)']</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[@class='filter_item_container']/div[1]//select[2]//option[3][@value='keyword' and text()='Contains']</td>
<td></td>
</tr>
<tr>
<td>assertElementNotPresent</td>
<td>//div[@class='filter_item_container']/div[1]//select[2]//option[3]</td>
<td>//div[@class='filter_item_container']/div[1]//select[2]//option[4]</td>
<td></td>
</tr>
<tr>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testFilterMultiValuedOperator</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test RenderJS UI</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test RenderJS UI</td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/init" />
<!-- Clean Up -->
<tr>
<td>open</td>
<td>&#36;{base_url}/bar_module/ListBoxZuite_reset</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Reset Successfully.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>&#36;{base_url}/foo_module/FooModule_createObjects</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Created Successfully.</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/wait_for_activities" />
<!-- Initialize -->
<tr>
<td>open</td>
<td>&#36;{base_url}/web_site_module/renderjs_runner/#/bar_module</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n='Previous']</td>
<td></td>
</tr>
<!-- Prepare panel with a multi-valued operator -->
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/triggle_filter_and" />
<tal:block tal:define="filter_section_configuration python: {'key': 'COLUMN_title', 'operator': 'at_least_one_exact_match', 'value': ['a', 'b'], 'index': 0}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/set_filter_section" />
</tal:block>
<!-- Select a non-multi-valued operator -->
<tal:block tal:define="filter_section_configuration python: {'operator': 'keyword', 'index': 0}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/set_filter_section" />
</tal:block>
<!-- Check if the multi-valued fields are gone and submit -->
<tal:block tal:define="filter_section_configuration python: {'key': 'COLUMN_title', 'value': ['a', None], 'index': 0}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_filter_section" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_filter" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<!-- Prepare panel with a multi-valued operator -->
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/triggle_filter_and" />
<tal:block tal:define="filter_section_configuration python: {'key': 'COLUMN_title', 'operator': 'at_least_one_exact_match', 'value': ['a', 'b'], 'index': 0}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/set_filter_section" />
</tal:block>
<!-- Select a non-multi-valued operator -->
<tal:block tal:define="filter_section_configuration python: {'key': 'COLUMN_id', 'index': 0}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/set_filter_section" />
</tal:block>
<!-- Check if the multi-valued fields are still present and submit -->
<tal:block tal:define="filter_section_configuration python: {'key': 'COLUMN_id', 'value': ['a', 'b'], 'index': 0}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_filter_section" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_filter" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
</tbody></table>
</body>
</html>
\ No newline at end of file
......@@ -55,7 +55,7 @@
<!-- Open the panel and submit it. Check that the new query string is not to much changed -->
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/triggle_filter_and" />
<tal:block tal:define="filter_section_configuration python: {'key': 'RAW', 'value': 'id: (&nbsp; &#34;2&#34; OR&nbsp; &#34;3&#34; )', 'index': 0}">
<tal:block tal:define="filter_section_configuration python: {'key': 'COLUMN_id', 'value': ['2', '3'], 'index': 0}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_filter_section" />
</tal:block>
<tal:block tal:define="filter_section_configuration python: {'key': 'TEXT', 'value': 'title', 'index': 1}">
......
......@@ -73,6 +73,36 @@
</tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/triggle_filter_and" />
<tal:block tal:define="filter_section_configuration python: {'key': 'RAW', 'value': 'foo: (&nbsp; &#34;31085&#34; OR&nbsp; &#34;31086&#34; )', 'index': 0}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/set_filter_section" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_filter" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tal:block tal:define="parsed_query python: 'foo: (&nbsp; &#34;31085&#34; OR&nbsp; &#34;31086&#34; )';
search_query python: ''">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_search_in_form_list" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/triggle_filter_or" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/change_filter_to_and" />
<tal:block tal:define="filter_section_configuration python: {'key': 'RAW', 'value': 'bar:&nbsp; &#34;31084&#34;', 'index': 0}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/set_filter_section" />
</tal:block>
<tal:block tal:define="filter_section_configuration python: {'key': 'RAW', 'value': 'foo: (&nbsp; &#34;31085&#34; OR&nbsp; &#34;31086&#34; )', 'index': 1}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/set_filter_section" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_filter" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tal:block tal:define="parsed_query python: '( bar:&nbsp; &#34;31084&#34; AND foo: (&nbsp; &#34;31085&#34; OR&nbsp; &#34;31086&#34; ) )';
search_query python: ''">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_search_in_form_list" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/triggle_filter_and" />
<tal:block tal:define="filter_section_configuration python: {'index': 1}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/remove_filter_section" />
</tal:block>
<tal:block tal:define="filter_section_configuration python: {'index': 0}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/remove_filter_section" />
</tal:block>
......
......@@ -124,17 +124,8 @@
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/triggle_filter_or" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/triggle_filter_and" />
<tal:block tal:define="filter_section_configuration python: {'index': 3}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/remove_filter_section" />
</tal:block>
<tal:block tal:define="filter_section_configuration python: {'index': 2}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/remove_filter_section" />
</tal:block>
<tal:block tal:define="filter_section_configuration python: {'index': 1}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/remove_filter_section" />
</tal:block>
<tal:block tal:define="filter_section_configuration python: {'index': 0}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/remove_filter_section" />
</tal:block>
......
......@@ -66,7 +66,7 @@
<tr>
<td>verifySelectOptions</td>
<td>//div[@class="filter_item_container"]/div[1]//select[2]</td>
<td>dengyu,baohang</td>
<td>dengyu,dengyu(zhishaoyige),baohang</td>
</tr>
......
......@@ -5,6 +5,7 @@ param_dict = [
{ 'message': 'Proceed', 'translation': 'jixu', 'language': 'wo'},
{ 'message': 'Title', 'translation': 'biaoti', 'language': 'wo'},
{ 'message': 'Equal to', 'translation': 'dengyu', 'language': 'wo'},
{ 'message': 'Equal to (at least one)', 'translation': 'dengyu(zhishaoyige)', 'language': 'wo'},
{ 'message': 'Contains', 'translation': 'baohang', 'language': 'wo'},
{ 'message': 'Search', 'translation': 'soushuo', 'language': 'wo'},
{ 'message': 'Next', 'translation': 'houyige', 'language': 'wo'},
......
......@@ -921,23 +921,38 @@
<tal:block metal:define-macro="set_filter_section">
<tr>
<td colspan="3"><b tal:content="python: 'Set the filter section %(index)i to %(key)s - %(value)s' % filter_section_configuration"></b></td>
<td colspan="3"><b tal:content="python: 'Set the filter section %i to %s %s %s' % (filter_section_configuration.get('index', '?'), filter_section_configuration.get('key', '-'), filter_section_configuration.get('operator', '-'), filter_section_configuration.get('value', '-'))"></b></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td tal:content="python: '//div[contains(@data-gadget-url, \'gadget_erp5_search_editor.html\')]//div[@class=\'filter_item_container\']/div[%i]//select' % (filter_section_configuration['index'] + 1)"></td>
<td></td>
</tr>
<tr>
<tr tal:condition="python: filter_section_configuration.get('key')">
<td>select</td>
<td tal:content="python: '//div[contains(@data-gadget-url, \'gadget_erp5_search_editor.html\')]//div[@class=\'filter_item_container\']/div[%i]//select' % (filter_section_configuration['index'] + 1)"></td>
<td tal:content="python: '//div[contains(@data-gadget-url, \'gadget_erp5_search_editor.html\')]//div[@class=\'filter_item_container\']/div[%i]//select[@class=\'column\']' % (filter_section_configuration['index'] + 1)"></td>
<td tal:content="python: 'value=%s' % filter_section_configuration['key']"></td>
</tr>
<tr tal:condition="python: filter_section_configuration.get('operator')">
<td>select</td>
<td tal:content="python: '//div[contains(@data-gadget-url, \'gadget_erp5_search_editor.html\')]//div[@class=\'filter_item_container\']/div[%i]//select[2]' % (filter_section_configuration['index'] + 1)"></td>
<td tal:content="python: 'value=%s' % filter_section_configuration['operator']"></td>
</tr>
<tal:block tal:condition="python: 'value' in filter_section_configuration">
<tal:block tal:define="_set_filter_section_value_list python: filter_section_configuration['value'] if isinstance(filter_section_configuration['value'], (tuple, list)) else [filter_section_configuration['value']]"
tal:repeat="_set_filter_section_index python: range(len(_set_filter_section_value_list))">
<tr>
<td>waitForElementPresent</td>
<td tal:content="python: '//div[contains(@data-gadget-url, \'gadget_erp5_search_editor.html\')]//div[@class=\'filter_item_container\']/div[%i]//input[%i]' % (filter_section_configuration['index'] + 1, _set_filter_section_index + 1)"></td>
<td></td>
</tr>
<tr>
<td>type</td>
<td tal:content="python: '//div[contains(@data-gadget-url, \'gadget_erp5_search_editor.html\')]//div[@class=\'filter_item_container\']/div[%i]//input' % (filter_section_configuration['index'] + 1)"></td>
<td tal:content="python: filter_section_configuration['value']"></td>
<td tal:content="python: '//div[contains(@data-gadget-url, \'gadget_erp5_search_editor.html\')]//div[@class=\'filter_item_container\']/div[%i]//input[%i]' % (filter_section_configuration['index'] + 1, _set_filter_section_index + 1)"></td>
<td tal:content="python: _set_filter_section_value_list[_set_filter_section_index]"></td>
</tr>
</tal:block>
</tal:block>
<tr>
<td colspan="3"><p></p></td>
</tr>
......@@ -957,6 +972,30 @@
</tr>
</tal:block>
<tal:block metal:define-macro="change_filter_to_and">
<tr>
<td colspan="3"><b>Change the filter to AND mode</b></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_search_editor.html')]//select[@name='heard_about']</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_search_editor.html')]//select[@name='heard_about']</td>
<td>index=0</td>
</tr>
<tr>
<td>verifyValue</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_search_editor.html')]//select[@name='heard_about']</td>
<td>AND</td>
</tr>
<tr>
<td colspan="3"><p></p></td>
</tr>
</tal:block>
<tal:block metal:define-macro="change_filter_to_or">
<tr>
<td colspan="3"><b>Change the filter to OR mode</b></td>
......@@ -1017,14 +1056,27 @@
</tr>
<tr>
<td>verifyValue</td>
<td tal:content="python: '//div[contains(@data-gadget-url, \'gadget_erp5_search_editor.html\')]//div[@class=\'filter_item_container\']/div[%i]//select' % (filter_section_configuration['index'] + 1)"></td>
<td tal:content="python: '//div[contains(@data-gadget-url, \'gadget_erp5_search_editor.html\')]//div[@class=\'filter_item_container\']/div[%i]//select[@class=\'column\']' % (filter_section_configuration['index'] + 1)"></td>
<td tal:content="python: filter_section_configuration['key']"></td>
</tr>
<tr>
<tr tal:condition="python: filter_section_configuration.get('operator')">
<td>verifyValue</td>
<td tal:content="python: '//div[contains(@data-gadget-url, \'gadget_erp5_search_editor.html\')]//div[@class=\'filter_item_container\']/div[%i]//input' % (filter_section_configuration['index'] + 1)"></td>
<td tal:content="python: filter_section_configuration['value']"></td>
<td tal:content="python: '//div[contains(@data-gadget-url, \'gadget_erp5_search_editor.html\')]//div[@class=\'filter_item_container\']/div[%i]//select[2]' % (filter_section_configuration['index'] + 1)"></td>
<td tal:content="python: filter_section_configuration['operator']"></td>
</tr>
<tal:block tal:define="_check_filter_section_value_list python: filter_section_configuration['value'] if isinstance(filter_section_configuration['value'], (tuple, list)) else [filter_section_configuration['value']]"
tal:repeat="_check_filter_section_index python: range(len(_check_filter_section_value_list))">
<tr tal:condition="python: _check_filter_section_value_list[_check_filter_section_index] is not None">
<td>verifyValue</td>
<td tal:content="python: '//div[contains(@data-gadget-url, \'gadget_erp5_search_editor.html\')]//div[@class=\'filter_item_container\']/div[%i]//input[%i]' % (filter_section_configuration['index'] + 1, _check_filter_section_index + 1)"></td>
<td tal:content="python: _check_filter_section_value_list[_check_filter_section_index]"></td>
</tr>
<tr tal:condition="python: _check_filter_section_value_list[_check_filter_section_index] is None">
<td>verifyElementNotPresent</td>
<td tal:content="python: '//div[contains(@data-gadget-url, \'gadget_erp5_search_editor.html\')]//div[@class=\'filter_item_container\']/div[%i]//input[%i]' % (filter_section_configuration['index'] + 1, _check_filter_section_index + 1)"></td>
<td></td>
</tr>
</tal:block>
<tr>
<td colspan="3"><p></p></td>
</tr>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment