Commit dbece842 authored by Tomáš Peterka's avatar Tomáš Peterka

ce est ca

parent 444fadf1
......@@ -16,13 +16,13 @@
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_action</string>
<string>action_type/object_jio_action</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_action</string> </value>
<value> <string>object_jio_action</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
......
......@@ -16,13 +16,13 @@
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_action</string>
<string>action_type/object_jio_action</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_action</string> </value>
<value> <string>object_jio_action</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
......
......@@ -29,6 +29,15 @@
<key> <string>acquire_local_roles</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>ledger/accounting/general</string>
<string>ledger/accounting/detailed</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_icon</string> </key>
<value> <string>organisation_icon.gif</string> </value>
......
......@@ -29,6 +29,12 @@
<key> <string>acquire_local_roles</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>content_icon</string> </key>
<value> <string>transaction_icon.gif</string> </value>
......
......@@ -29,6 +29,12 @@
<key> <string>acquire_local_roles</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>content_icon</string> </key>
<value> <string>organisation_icon.gif</string> </value>
......
......@@ -29,6 +29,12 @@
<key> <string>acquire_local_roles</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>content_icon</string> </key>
<value> <string>organisation_icon.gif</string> </value>
......
......@@ -29,6 +29,12 @@
<key> <string>acquire_local_roles</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>content_icon</string> </key>
<value> <string>organisation_icon.gif</string> </value>
......
......@@ -29,6 +29,12 @@
<key> <string>acquire_local_roles</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>content_icon</string> </key>
<value> <string>organisation_icon.gif</string> </value>
......
......@@ -69,10 +69,6 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>description</string> </key>
<value> <string>Printing format</string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>your_format</string> </value>
......@@ -85,10 +81,6 @@
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Format</string> </value>
</item>
</dictionary>
</value>
</item>
......
"""Total balance of all accounting transactions having this
account as node
"""
kw['node_uid'] = context.getUid()
kw.update(
node_uid=context.getUid(),
selection_name=selection_name
)
return context.Node_statAccountingBalance(**kw)
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
<value> <string>selection_name=None, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
"""Total credit of all accounting transactions having this
account as node
account as a node
"""
kw['node_uid'] = context.getUid()
kw['omit_asset_increase'] = 1
kw.update(kw['selection'].getParams())
kw.update(
node_uid = context.getUid(),
omit_asset_increase = 1,
selection_name=selection_name
)
# force second update to overwrite anything by selection params
if selection_name is not None:
kw.update(
**context.getPortalObject().portal_selections.getSelectionParamsFor(selection_name))
elif "selection" in kw:
# note that passing selection object via parameters is obsolete
kw.update(kw['selection'].getParams())
# here, or 0 is to prevent displaying "- 0"
return - context.Node_statAccountingBalance(**kw) or 0
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
<value> <string>selection_name=None, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
"""Total debit of all accounting transactions having this
account as a node
"""
kw['node_uid'] = context.getUid()
kw['omit_asset_decrease'] = 1
kw.update(kw['selection'].getParams())
kw.update(
node_uid=context.getUid(),
omit_asset_decrease=1,
selection_name=selection_name
)
# force second update to overwrite anything by selection params
if selection_name is not None:
kw.update(
**context.getPortalObject().portal_selections.getSelectionParamsFor(selection_name))
elif "selection" in kw:
# note that passing selection object via parameters is obsolete
kw.update(kw['selection'].getParams())
return context.Node_statAccountingBalance(**kw)
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
<value> <string>selection_name=None, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -21,7 +21,7 @@
<dictionary>
<item>
<key> <string>name</string> </key>
<value> <string>uid</string> </value>
<value> <string>relative_url</string> </value>
</item>
<item>
<key> <string>null</string> </key>
......@@ -29,11 +29,11 @@
</item>
<item>
<key> <string>type</string> </key>
<value> <string>i</string> </value>
<value> <string>t</string> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <int>11</int> </value>
<value> <int>0</int> </value>
</item>
</dictionary>
<dictionary>
......@@ -51,7 +51,61 @@
</item>
<item>
<key> <string>width</string> </key>
<value> <int>50</int> </value>
<value> <int>0</int> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>name</string> </key>
<value> <string>title</string> </value>
</item>
<item>
<key> <string>null</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>t</string> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <int>0</int> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>name</string> </key>
<value> <string>portal_type</string> </value>
</item>
<item>
<key> <string>null</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>t</string> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <int>0</int> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>name</string> </key>
<value> <string>validation_state</string> </value>
</item>
<item>
<key> <string>null</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>t</string> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <int>0</int> </value>
</item>
</dictionary>
</list>
......
......@@ -35,8 +35,9 @@ for obj in object_list:
if not activated:
return context.Base_redirect(form_id,
keep_items=dict(portal_status_message=
translateString('No valid transaction in your selection.')))
keep_items={
"portal_status_message": translateString(
'No valid transaction in your selection.')})
# activate something on the folder
context.activate(after_tag=tag).getTitle()
......
......@@ -154,6 +154,10 @@
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>input_type</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
......
......@@ -4,4 +4,6 @@ bank account as payment node
kw['payment_uid'] = context.getUid()
kw['asset_price'] = False
kw['node_category'] = 'account_type/asset/cash/bank'
kw['selection_name'] = selection_name
return context.Node_statAccountingBalance(**kw)
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
<value> <string>selection_name=None, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -5,7 +5,14 @@ kw['payment_uid'] = context.getUid()
kw['omit_asset_increase'] = 1
kw['asset_price'] = False
kw['node_category'] = 'account_type/asset/cash/bank'
kw.update(kw['selection'].getParams())
kw['selection_name'] = selection_name
if selection_name is not None:
kw.update(
**context.getPortalObject().portal_selections.getSelectionParamsFor(selection_name))
elif "selection" in kw:
# note that passing selection object via parameters is obsolete
kw.update(kw['selection'].getParams())
# here, or 0 is to prevent displaying "- 0"
return - context.Node_statAccountingBalance(**kw) or 0
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
<value> <string>selection_name=None, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -5,6 +5,13 @@ kw['payment_uid'] = context.getUid()
kw['omit_asset_decrease'] = 1
kw['asset_price'] = False
kw['node_category'] = 'account_type/asset/cash/bank'
kw.update(kw['selection'].getParams())
kw['selection_name'] = selection_name
if selection_name is not None:
kw.update(
**context.getPortalObject().portal_selections.getSelectionParamsFor(selection_name))
elif "selection" in kw:
# note that passing selection object via parameters is obsolete
kw.update(kw['selection'].getParams())
return context.Node_statAccountingBalance(**kw)
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
<value> <string>selection_name=None, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
"""Returns Accounting Transactions where this entity is mirror section.
"""
kw['mirror_section_uid'] = context.getUid()
kw['node_category_strict_membership'] = ['account_type/asset/receivable',
'account_type/liability/payable']
kw.update(
# following two lines are the reason for this whole script to exist
mirror_section_uid=context.getUid(),
node_category_strict_membership=['account_type/asset/receivable',
'account_type/liability/payable'],
# the rest is to explicitely state which parameters are needed
sort_on=sort_on,
selection_name=selection_name,
)
return context.Node_getAccountingTransactionList(**kw)
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
<value> <string>selection_name=\'\', sort_on=(), **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -6,7 +6,8 @@ kw['mirror_section_uid'] = context.getUid()
kw['omit_asset_increase'] = 1
kw['node_category_strict_membership'] = ['account_type/asset/receivable',
'account_type/liability/payable']
kw.update(kw['selection'].getParams())
kw.update(
**context.getPortalObject().portal_selections.getSelectionParamsFor(selection_name, REQUEST=kw.get('REQUEST', None)))
# here, or 0 is to prevent displaying "- 0"
return - context.Node_statAccountingBalance(**kw) or 0
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
<value> <string>selection_name, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -5,6 +5,8 @@ kw['mirror_section_uid'] = context.getUid()
kw['omit_asset_decrease'] = 1
kw['node_category_strict_membership'] = ['account_type/asset/receivable',
'account_type/liability/payable']
kw.update(kw['selection'].getParams())
kw.update(
**context.getPortalObject().portal_selections.getSelectionParamsFor(selection_name, REQUEST=kw.get('REQUEST', None)))
return context.Node_statAccountingBalance(**kw)
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
<value> <string>selection_name, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -143,87 +143,18 @@
</dictionary>
</value>
</item>
<item>
<key> <string>_count</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>_identity_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>_local_properties</string> </key>
<value>
<tuple>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>configuration_x_frame_options</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>string</string> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>configuration_content_security_policy</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>string</string> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>configuration_login</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>string</string> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>configuration_logout</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>string</string> </value>
</item>
</dictionary>
</tuple>
</value>
</item>
<item>
<key> <string>_mt_index</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>_range_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAY=</string> </persistent>
</value>
</item>
<item>
<key> <string>_tree</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAc=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>authorization_forced</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>available_language</string> </key>
<value>
......@@ -232,28 +163,6 @@
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>configuration_content_security_policy</string> </key>
<value> <string>default-src \'self\'; img-src \'self\' data:; media-src \'self\' blob:; connect-src \'self\' https://localhost:5000 mail.tiolive.com data: *.host.vifib.net *.node.vifib.com *.erp5.net *.erp5.ru; script-src \'self\' \'unsafe-eval\'; font-src netdna.bootstrapcdn.com; style-src \'self\' netdna.bootstrapcdn.com \'unsafe-inline\' data:; frame-src \'self\' data: *.app.officejs.com</string> </value>
</item>
<item>
<key> <string>configuration_login</string> </key>
<value> <string>connection/login_form{?came_from}</string> </value>
</item>
<item>
<key> <string>configuration_logout</string> </key>
<value> <string>connection/WebSite_logout{?came_from}</string> </value>
</item>
<item>
<key> <string>configuration_x_frame_options</string> </key>
<value> <string>ALLOW-FROM-ALL</string> </value>
</item>
<item>
<key> <string>container_layout</string> </key>
<value> <string>ERP5Document_getHateoas</string> </value>
......@@ -278,7 +187,7 @@
</item>
<item>
<key> <string>layout_configuration_form_id</string> </key>
<value> <string>WebSection_viewHateoasPreference</string> </value>
<value> <string>WebSection_viewDefaultThemeConfiguration</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
......@@ -292,7 +201,7 @@
</item>
<item>
<key> <string>skin_selection_name</string> </key>
<value> <string>HalRestricted</string> </value>
<value> <string>Hal</string> </value>
</item>
<item>
<key> <string>static_language_selection</string> </key>
......@@ -309,7 +218,7 @@
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAg=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -324,12 +233,6 @@
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="Length" module="BTrees.Length"/>
</pickle>
<pickle> <int>0</int> </pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......@@ -344,15 +247,7 @@
</dictionary>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="6" aka="AAAAAAAAAAY=">
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......@@ -367,15 +262,7 @@
</dictionary>
</pickle>
</record>
<record id="7" aka="AAAAAAAAAAc=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="8" aka="AAAAAAAAAAg=">
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......@@ -388,13 +275,13 @@
<item>
<key> <string>category_publication_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAk=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAY=</string> </persistent>
</value>
</item>
<item>
<key> <string>edit_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAo=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAc=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -403,7 +290,7 @@
</dictionary>
</pickle>
</record>
<record id="9" aka="AAAAAAAAAAk=">
<record id="6" aka="AAAAAAAAAAY=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
......@@ -456,7 +343,7 @@
</tuple>
</pickle>
</record>
<record id="10" aka="AAAAAAAAAAo=">
<record id="7" aka="AAAAAAAAAAc=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
......@@ -485,7 +372,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.45855.48292.47786</string> </value>
<value> <string>932.120.18159.59989</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -503,8 +390,8 @@
</tuple>
<state>
<tuple>
<float>1515504053.68</float>
<string>UTC</string>
<float>1389263689.67</float>
<string>GMT+1</string>
</tuple>
</state>
</object>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Web Section" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_folders_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Copy_or_Move_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>__before_publishing_traverse__</string> </key>
<value>
<object>
<klass>
<global name="MultiHook" module="ZPublisher.BeforeTraverse"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_defined_in_class</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>_hookname</string> </key>
<value> <string>__before_publishing_traverse__</string> </value>
</item>
<item>
<key> <string>_list</string> </key>
<value>
<list>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</list>
</value>
</item>
<item>
<key> <string>_prior</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>__before_traverse__</string> </key>
<value>
<dictionary>
<item>
<key>
<tuple>
<int>99</int>
<string>ERP5 Web Section/connection</string>
</tuple>
</key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>_identity_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>_range_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>caching_policy/no-cache</string>
</tuple>
</value>
</item>
<item>
<key> <string>container_layout</string> </key>
<value> <string>WebSection_renderDefaultPageAsGadget</string> </value>
</item>
<item>
<key> <string>content_layout</string> </key>
<value> <string>WebSection_renderDefaultPageAsGadget</string> </value>
</item>
<item>
<key> <string>custom_render_method_id</string> </key>
<value> <string>WebSection_renderDefaultPageAsGadget</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>empty_criterion_valid</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>connection</string> </value>
</item>
<item>
<key> <string>layout_configuration_form_id</string> </key>
<value> <string>WebSection_viewRenderJSPreference</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Web Section</string> </value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>skin_selection_name</string> </key>
<value> <string>RJS</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Connection</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>0</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="WebSectionTraversalHook" module="Products.ERP5.Document.WebSection"/>
</pickle>
<pickle>
<dictionary/>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -23,5 +23,6 @@ return context.ERP5Document_getHateoas(
bulk_list=bulk_list,
sort_on=sort_on,
local_roles=local_roles,
restricted=1
restricted=1,
prev_view=prev_view
)
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None, response=None, view=None, mode=\'root\', query=None, select_list=None, limit=10, local_roles=None, form=None, relative_url=None, list_method=None, default_param_json=None, form_relative_url=None, bulk_list="[]", sort_on=None</string> </value>
<value> <string>REQUEST=None, response=None, view=None, mode=\'root\', query=None, select_list=None, limit=10, local_roles=None, form=None, relative_url=None, list_method=None, default_param_json=None, form_relative_url=None, bulk_list="[]", sort_on=None, prev_view=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -270,7 +270,6 @@ if True:
# does not exist and we call form method directly
if clean_kw.get("portal_skin", context.getPortalObject().portal_skins.getDefaultSkin()) not in ("Hal", "HalRestricted"):
return dialog_form(**kw)
return context.ERP5Document_getHateoas(REQUEST=request, form=dialog_form, mode="form")
return getattr(context, dialog_method)(**kw)
......@@ -38,7 +38,7 @@ if not silent_mode and not request.AUTHENTICATED_USER.has_permission('Modify por
return context.ERP5Document_getHateoas(form=form, REQUEST=request, mode='form')
try:
# Validate
# Validate and insert field value into REQUEST under their IDs (no "field_" prefix)
form.validate_all_to_request(request, key_prefix=key_prefix)
except FormValidationError as validation_errors:
# Pack errors into the request
......@@ -91,7 +91,10 @@ def editListBox(listbox_field, listbox):
def editMatrixBox(matrixbox_field, matrixbox):
""" Function called to edit a Matrix box
"""Go through every field in matrix and call edit on it.
Most of the code is just a copy&paste from ERP5Form/MatrixBox:render and
should be in (non-yet-existing) MatrixBoxEditor instead of here (XXX TODO).
"""
if matrixbox is None:
return
......@@ -146,7 +149,7 @@ def editMatrixBox(matrixbox_field, matrixbox):
tab_ids = map(lambda x: x[0], tabs)
extra_dimension_category_list_list = [[category for category, label in dimension_list] for dimension_list in extra_dimension_list_list]
# There are 3 cases
# There are 4 cases
# Case 1: we do 1 dimensional matrix
# Case 2: we do 2 dimensional matrix
# Case 3: we do 2 dimensional matrix + tabs
......@@ -170,7 +173,7 @@ def editMatrixBox(matrixbox_field, matrixbox):
matrix_context.setCellRange(base_id=cell_base_id, *matrixbox_cell_range)
for cell_index_tuple, cell_value_dict in matrixbox.items():
# Only update cells which still exist
# after constructing the cell-range we can edit all existing cells
if not matrix_context.hasInRange(*cell_index_tuple, **kd):
return "Cell %s does not exist" % str(cell_index_tuple)
......@@ -204,7 +207,7 @@ MARKER = [] # placeholder for an empty value
message = Base_translateString("Data updated.")
try:
# extract all listbox's object form fields from the request and `edit` the object
# Extract all form fields from the request and call `edit` on them
for field in form.get_fields():
# Dispatch field either to `edit_kwargs` (in case of simple fields) or to `encapsulated_editor_list` in case of editors
field_name = field.id if not field.has_value('alternate_name') else (field.get_value('alternate_name') or field.id)
......@@ -217,13 +220,14 @@ try:
edit_kwargs[field_name[len(field_prefix):]] = field_value if field_value != '' else None
## XXX We need to find a way not to use meta_type.
# Kato: can be done simply by implementing 'Editors' for fields which are here
field_meta_type = field.meta_type
if field_meta_type == 'ProxyField':
field_meta_type = field.getRecursiveTemplateField().meta_type
if(field_meta_type == 'ListBox'):
editListBox(field, request.get(field.id))
if(field_meta_type == 'MatrixBox'):
elif(field_meta_type == 'MatrixBox'):
editMatrixBox(field, request.get(field.id))
# Return parsed values
......@@ -235,6 +239,7 @@ try:
context.edit(REQUEST=request, edit_order=edit_order, **edit_kwargs)
for encapsulated_editor in encapsulated_editor_list:
encapsulated_editor.edit(context)
except ActivityPendingError as e:
message = Base_translateString(str(e))
......
......@@ -9,6 +9,8 @@
from ZTUtils import make_query
import json
portal_status_message = "%s" % keep_items.pop("portal_status_message", "")
request_form = context.REQUEST.form
request_form.update(kw)
request_form = context.ERP5Site_filterParameterList(request_form)
......@@ -40,12 +42,12 @@ response.setHeader("X-Location", "urn:jio:get:%s" % context.getRelativeUrl())
# therefor we don't need to be afraid of clashes
response.setHeader("Content-type", "application/json; charset=utf-8")
result_dict = {
'portal_status_message': "%s" % keep_items.pop("portal_status_message", ""),
'portal_status_message': portal_status_message,
'_links': {
"self": {
# XXX Include query parameters
"href": context.Base_getRequestUrl()
"href": "{}?{}".format(context.Base_getRequestUrl(), parameters)
}
}
}
......
# request.RESPONSE.setStatus(200)
form = getattr(context, form_id)
return context.ERP5Document_getHateoas(form=form, mode='form')
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<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_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<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>_params</string> </key>
<value> <string>form_id</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_renderForm</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -62,9 +62,6 @@
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
</list>
</value>
</item>
......@@ -73,13 +70,7 @@
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>center</string> </key>
<key> <string>left</string> </key>
<value>
<list>
<string>your_warning</string>
......@@ -88,18 +79,6 @@
</list>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
......
......@@ -205,11 +205,11 @@
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string>invisible</string> </value>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string>Do you want to clone this document?</string> </value>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -257,7 +257,7 @@
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Confirmation message</string> </value>
<value> <string>Do you want to clone this document:</string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
......
......@@ -62,9 +62,6 @@
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
</list>
</value>
</item>
......@@ -73,13 +70,7 @@
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>center</string> </key>
<key> <string>left</string> </key>
<value>
<list>
<string>your_warning</string>
......@@ -89,18 +80,6 @@
</list>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
......
......@@ -205,11 +205,11 @@
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string>invisible</string> </value>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string>Do you want to delete this document?</string> </value>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -257,7 +257,7 @@
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Confirmation message</string> </value>
<value> <string>Do you want to Delete this document:</string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
......
......@@ -20,6 +20,7 @@ Only in mode == 'form'
:param form:
Only in mode == 'traverse'
Traverse renders arbitrary View. It can be a Form or a Script.
# Form
......@@ -39,9 +40,11 @@ from email.Utils import formatdate
import re
from zExceptions import Unauthorized
from Products.ERP5Type.Utils import UpperCase
from Products.ERP5Type.Message import Message
from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery
from Products.ERP5Type.Log import log
from collections import OrderedDict
from urlparse import urlparse
MARKER = []
......@@ -51,6 +54,10 @@ if REQUEST is None:
if response is None:
response = REQUEST.RESPONSE
def isFieldType(field, type_name):
if field.meta_type == 'ProxyField':
field = field.getRecursiveTemplateField()
return field.meta_type == type_name
def toBasicTypes(obj):
"""Ensure that obj contains only basic types."""
......@@ -58,14 +65,39 @@ def toBasicTypes(obj):
return obj
if isinstance(obj, (bool, int, float, long, str, unicode)):
return obj
if isinstance(obj, (tuple, list)):
if isinstance(obj, list):
return [toBasicTypes(x) for x in obj]
if isinstance(obj, tuple):
return tuple(toBasicTypes(x) for x in obj)
if isinstance(obj, Message):
return obj.translate()
try:
return {toBasicTypes(key): toBasicTypes(obj[key]) for key in obj}
except:
log('Cannot convert {!s} to basic types {!s}'.format(type(obj), obj), level=100)
return obj
def addHiddenFieldToForm(form, name, value):
if form == {}:
form['_embedded'] = {}
form['_embedded']['_view'] = {}
if '_embedded' in form:
field_dict = form['_embedded']['_view']
else:
field_dict = form
field_dict[name] = {
"type": "StringField",
"key": name,
"default": value,
"editable": 0,
"css_class": "",
"hidden": 1,
"description": "",
"title": name,
"required": 1,
}
# http://stackoverflow.com/a/13105359
def byteify(string):
......@@ -375,7 +407,7 @@ def getFieldDefault(form, field, key, value=None):
value = (REQUEST.form.get(field.id, REQUEST.form.get(key, None)) or
field.get_value('default', request=REQUEST, REQUEST=REQUEST))
if field.has_value("unicode") and field.get_value("unicode") and isinstance(value, 'unicode'):
value = unicode(value, self.get_form_encoding())
value = unicode(value, form.get_form_encoding())
if getattr(value, 'translate', None) is not None:
return "%s" % value
return value
......@@ -383,7 +415,6 @@ def getFieldDefault(form, field, key, value=None):
def renderField(traversed_document, field, form, value=None, meta_type=None, key=None, key_prefix=None, selection_params=None):
"""Extract important field's attributes into `result` dictionary."""
if selection_params is None:
selection_params = {}
......@@ -421,8 +452,9 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
if meta_type in ("ListField", "RadioField", "ParallelListField", "MultiListField"):
result.update({
# XXX Message can not be converted to json as is
"items": field.get_value("items"),
"items": toBasicTypes(field.get_value("items")),
})
context.log('{!s}.items: {!s}'.format(field.id, field.get_value("items")))
if meta_type == "ListField":
result.update({
"first_item": field.get_value("first_item"),
......@@ -492,7 +524,6 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
portal_type_list = field.get_value('portal_type')
translated_portal_type = []
jump_reference_list = []
relation_sort = field.get_value('sort')
if portal_type_list:
portal_type_list = [x[0] for x in portal_type_list]
translated_portal_type = [Base_translateString(x) for x in portal_type_list]
......@@ -514,10 +545,10 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
result.update({
"editable": False
})
relation_query_kw = kw.copy()
relation_query_kw['portal_type'] = portal_type_list
query = url_template_dict["jio_search_template"] % {
"query": make_query({"query": sql_catalog.buildQuery(relation_query_kw).asSearchTextExpression(sql_catalog)})
"query": make_query({"query": sql_catalog.buildQuery(
{"portal_type": portal_type_list}
).asSearchTextExpression(sql_catalog)})
}
title = field.get_value("title")
column_list = field.get_value("columns")
......@@ -544,14 +575,10 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
# overwrite, like Base_getRelatedObjectParameter does
if subfield["portal_type"] == []:
subfield["portal_type"] = field.get_value('portal_type')
if relation_sort:
subfield["sort"] = relation_sort
listbox_query_kw = kw.copy()
listbox_query_kw.update(dict(portal_type = [x[-1] for x in subfield["portal_type"]],
**subfield["default_params"]))
subfield["query"] = url_template_dict["jio_search_template"] % {
"query": make_query({"query": sql_catalog.buildQuery(
listbox_query_kw, ignore_unknown_columns=True
dict(portal_type = [x[-1] for x in subfield["portal_type"]],
**subfield["default_params"]), ignore_unknown_columns=True
).asSearchTextExpression(sql_catalog)})
}
# Kato: why?
......@@ -575,7 +602,6 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
"translated_portal_types": translated_portal_type,
"portal_types": portal_type_list,
"query": query,
"sort": relation_sort,
"catalog_index": field.get_value('catalog_index'),
"allow_jump": field.get_value('allow_jump'),
"allow_creation": field.get_value('allow_creation'),
......@@ -595,7 +621,7 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
if meta_type in ("CheckBoxField", "MultiCheckBoxField"):
if meta_type == "MultiCheckBoxField":
result["items"] = field.get_value("items"),
result["items"] = toBasicTypes(field.get_value("items")),
return result
if meta_type == "GadgetField":
......@@ -816,17 +842,26 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
def renderForm(traversed_document, form, response_dict, key_prefix=None, selection_params=None):
"""
Render a `form` in plain python dict.
This function sets varibles 'here' and 'form_id' rest. 'dialog_id' for forms resp. form dialogs to REQUEST.
Any other REQUEST mingling are at the responsability of the callee.
:param selection_params: holds parameters to construct ERP5Form.Selection instance
for underlaying ListBox - since we do not use selections in RenderJS UI
we mitigate the functionality here by overriding ListBox's own values
for columns, editable columns, and sort with those found in `selection_params`
"""
previous_request_other = {
'form_id': REQUEST.other.pop('form_id', None),
'here': REQUEST.other.pop('here', None)
}
previous_request_other = {}
REQUEST.set('here', traversed_document)
if form.pt == "form_dialog":
previous_request_other['dialog_id'] = REQUEST.other.pop('dialog_id', None)
REQUEST.set('dialog_id', form.id)
else:
previous_request_other['form_id'] = REQUEST.other.pop('form_id', None)
REQUEST.set('form_id', form.id)
field_errors = REQUEST.get('field_errors', {})
#hardcoded
......@@ -892,17 +927,14 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti
# Do not crash if field configuration is wrong.
pass
response_dict["form_id"] = {
"type": "StringField",
"key": "form_id",
"default": form.id,
"editable": 0,
"css_class": "",
"hidden": 1,
"description": "",
"title": "form_id",
"required": 1,
}
# Edit uses form_id to recover the submitted form.
# Dialog uses 'dialog_id' instead and 'form_id' only as a parameter to the dialog form
# Beware that print_action rewrites value of form_id in callee!
addHiddenFieldToForm(response_dict, 'form_id', form.id)
# Form dialog (subsequent callDialogMethod) selects its form based on dialog_id, not form_id
if (form.pt == 'form_dialog'):
addHiddenFieldToForm(response_dict, 'dialog_id', form.id)
if (form.pt == 'report_view'):
# reports are expected to return list of ReportSection which is a wrapper
......@@ -928,7 +960,8 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti
report_prefix = 'x%s' % report_index
report_title = report_item.getTitle()
# report_class = "report_title_level_%s" % report_item.getLevel()
report_form = report_item.getFormId()
report_form_id = report_item.getFormId()
report_form = getattr(report_context, report_form_id)
report_result = {'_links': {}}
# some reports save a lot of unserializable data (datetime.datetime) and
# key "portal_type" (don't confuse with "portal_types" in ListBox) into
......@@ -943,17 +976,19 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti
report_form_params = report_item.selection_params.copy() \
if report_item.selection_params is not None \
else {}
# request.prefixed_selection_name maybe used in tales expression
if report_form:
listbox = getattr(getattr(report_context, report_form), 'listbox', None)
# request.prefixed_selection_name maybe used in tales expression to display correct title of a ListBox
if report_form is not None:
listbox = getattr(report_form, 'listbox', None)
if listbox is not None:
listbox_selection_name = report_prefix + "_" + listbox.get_value('selection_name')
REQUEST.other['prefixed_selection_name'] = listbox_selection_name
if report_form_params:
params = portal.portal_selections.getSelectionParamsFor(listbox_selection_name)
params.update(report_form_params)
portal.portal_selections.setSelectionParamsFor(listbox_selection_name,params)
portal.portal_selections.setSelectionParamsFor(listbox_selection_name, params)
# report can have its own selection apart from embedded listboxes who have their own selections as well
if report_item.selection_name:
selection_name = report_prefix + "_" + report_item.selection_name
report_form_params.update(selection_name=selection_name)
......@@ -978,7 +1013,7 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti
# BUT! when Report Section defines `path` that is the new context for
# form rendering and subsequent searches...
renderForm(traversed_document if not report_item.path else report_context,
getattr(report_context, report_item.getFormId()),
report_form,
report_result,
key_prefix=report_prefix,
selection_params=report_form_params) # used to be only report_item.selection_params
......@@ -1050,7 +1085,6 @@ def renderFormDefinition(form, response_dict):
response_dict["title"] = Base_translateString(form.getTitle())
response_dict["pt"] = form.pt
response_dict["action"] = form.action
response_dict["update_action"] = form.update_action
mime_type = 'application/hal+json'
......@@ -1191,6 +1225,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
portal.portal_actions.listFilteredActionsFor(traversed_document))
embedded_url = None
prev_embedded_url = None
# XXX See ERP5Type.getDefaultViewFor
for erp5_action_key in erp5_action_dict.keys():
......@@ -1207,6 +1242,10 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
if (view == view_action['id']):
embedded_url = '%s' % view_action['url']
# Print action requires Form ID of the previous view - thus if we receive prev_view, resolve it
if prev_view == view_action['id']:
prev_embedded_url = '%s' % view_action['url']
global_action_type = ("view", "workflow", "object_new_content_action",
"object_clone_action", "object_delete_action")
if (erp5_action_key == view_action_type or
......@@ -1216,7 +1255,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
"root_url": site_root.absolute_url(),
"script_id": script.id,
"relative_url": traversed_document.getRelativeUrl().replace("/", "%2F"),
"view": erp5_action_list[-1]['name']
"view": erp5_action_list[-1]['name'],
}
if erp5_action_key == 'object_jump':
......@@ -1244,7 +1283,6 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
# XXX How to handle all custom jump actions?
erp5_action_list.pop(-1)
if erp5_action_list:
if len(erp5_action_list) == 1:
erp5_action_list = erp5_action_list[0]
......@@ -1291,6 +1329,15 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
}
}
}
prev_form_id = None
if (prev_embedded_url is not None and renderer_form.pt == "form_dialog"):
# Resolve Form ID of previous view and make it accessible inside embedded !dialog! form as form_id
# because old UI does that by passing the form_id in query string and hidden fields
prev_form_id = prev_embedded_url.split('?', 1)[0].split("/")[-1]
# if there is a previous view defined then we are in an action (e.g. print) that
# is stateful - requires not even the last view but even view's Selection name
REQUEST.set('form_id', prev_form_id)
# Put all query parameters (?reset:int=1&workflow_action=start_action) in request to mimic usual form display
query_param_dict = {}
query_split = embedded_url.split('?', 1)
......@@ -1303,14 +1350,41 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
# set URL params into REQUEST (just like it was sent by form)
for query_key, query_value in query_param_dict.items():
REQUEST.set(query_key, query_value)
# unfortunatelly some people use Scripts as targets for Workflow
# transactions - thus we need to check and mitigate
# Embedded Form can be a Script or even a class method thus we mitigate here
try:
if "Script" in renderer_form.meta_type:
# we suppose that the script takes only what is given in the URL params
return renderer_form(**query_param_dict)
except AttributeError:
# if renderer form does not have attr meta_type then it is not a document
# but most likely bound instance method. Some form_ids do actually point to methods.
returned_value = renderer_form(**query_param_dict)
# returned value is usually REQUEST.RESPONSE.redirect()
log('ERP5Document_getHateoas', 'HAL_JSON cannot handle returned value "{!s}" from {}({!s})'.format(
returned_value, form_id, query_param_dict), 100)
status_message = Base_translateString('Operation executed')
if isinstance(returned_value, (str, unicode)):
parsed_url = urlparse(returned_value)
parsed_query = parse_qs(parsed_url.query)
if len(parsed_query.get('portal_status_message', ())) > 0:
status_message = parsed_query.get('portal_status_message')[0]
return traversed_document.Base_redirect(keep_items={
'portal_status_message': status_message})
renderForm(traversed_document, renderer_form, embedded_dict)
if (prev_form_id is not None):
# overwrite "form_id" field's value because old UI does that by passing
# the form_id in query string and hidden fields
addHiddenFieldToForm(embedded_dict, "form_id", prev_form_id)
# New UI should not use Selection but it needs to be backward compatible thus
# instead of passing the selection view in a URL parameter, which equals capitulation agains Selections,
# we "temporarily" introduce selection ame guessing from listbox included in previous view
for field in getattr(traversed_document, prev_form_id).get_fields():
if isFieldType(field, "ListBox") and field.get_value('selection_name'):
addHiddenFieldToForm(embedded_dict, "selection_name", field.get_value('selection_name'))
break # one selection name is enough
result_dict['_embedded'] = {
'_view': embedded_dict
# embedded_action_key: embedded_dict
......@@ -1542,6 +1616,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
if source_field is not None and source_field_meta_type == "ListBox":
listbox_field_id = source_field.id
# XXX Proxy field are not correctly handled in traversed_document of web site
listbox_form = getattr(traversed_document, source_field.aq_parent.id)
# field TALES expression evaluated by Base_getRelatedObjectParameter requires that
......@@ -1820,6 +1895,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
return result_dict
response.setHeader('Content-Type', mime_type)
context.log('calculateHateoas(traversed_document={!s}, mode="{}", view="{!s}", prev_view="{!s}"'.format(temp_traversed_document, mode, view, prev_view))
hateoas = calculateHateoas(is_portal=temp_is_portal, is_site_root=temp_is_site_root,
traversed_document=temp_traversed_document,
relative_url=relative_url,
......@@ -1828,7 +1904,23 @@ hateoas = calculateHateoas(is_portal=temp_is_portal, is_site_root=temp_is_site_r
restricted=restricted, list_method=list_method,
default_param_json=default_param_json,
form_relative_url=form_relative_url)
def deepInspection(obj, prefix):
if isinstance(obj, dict):
for key, value in obj.items():
if type(key) != str:
log('{} key "{!s}": type {!s}'.format(prefix, key, type(key)))
deepInspection(value, prefix + '.' + str(key))
elif isinstance(obj, (tuple, list)):
for value in obj:
deepInspection(value, prefix)
elif obj is None or isinstance(obj, (str, int)):
return
else:
log('{} value "{!s}", type {!s}'.format(prefix, obj, type(obj)))
if hateoas == "":
return hateoas
else:
# deepInspection(hateoas, '')
return json.dumps(hateoas, indent=2)
......@@ -56,7 +56,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None, response=None, view=None, mode=\'root\', query=None, select_list=None, limit=10, local_roles=None, form=None, relative_url=None, restricted=0, list_method=None, default_param_json=None, form_relative_url=None, bulk_list="[]", sort_on=None</string> </value>
<value> <string>REQUEST=None, response=None, view=None, mode=\'root\', query=None, select_list=None, limit=10, local_roles=None, form=None, relative_url=None, restricted=0, list_method=None, default_param_json=None, form_relative_url=None, bulk_list="[]", sort_on=None, prev_view=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -1150,14 +1150,16 @@ return context.getPortalObject().portal_catalog(portal_type='Foo', sort_on=[('id
self.assertEqual(result_dict['_embedded']['contents'][1]['credit_price'], 0.0)
# Render a Document using Form Field template (only for field 'id')
result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(
result = self.portal.foo_module.__of__(self.portal.web_site_module.hateoas.web_site_module.hateoas).ERP5Document_getHateoas(
REQUEST=fake_request,
mode="search",
local_roles=["Assignor", "Assignee"],
relative_url="foo_module",
local_roles=["Assignor", "Assignee", "Manager"],
list_method='Test_listProducts',
select_list=['id'],
form_relative_url='portal_skins/erp5_ui_test/FooModule_viewFooList/listbox'
)
self.logMessage(result)
result_dict = json.loads(result)
self.assertEqual(2, len(result_dict['_embedded']['contents']))
self.assertIn("field_listbox", result_dict['_embedded']['contents'][0]['id']['key'])
......@@ -1547,7 +1549,7 @@ return msg"
work_list = [x for x in result_dict['worklist'] if x['name'].startswith('daiyanzhen')]
self.assertEqual(len(work_list), 1)
self.assertEqual(work_list[0]['name'], 'daiyanzhen')
self.assertEqual(work_list[0]['count'], 1)
self.assertTrue(work_list[0]['count'] > 0)
self.assertFalse('module' in work_list[0])
self.assertEqual(work_list[0]['href'], 'urn:jio:allDocs?query=portal_type%3A%28%22Bar%22%20OR%20%22Foo%22%29%20AND%20simulation_state%3A%22draft%22')
......
......@@ -29,10 +29,7 @@
editable: field_json.editable,
name: field_json.key,
title: field_json.title,
hidden: field_json.hidden,
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
hidden: field_json.hidden
};
state_dict.text_content = state_dict.checked ? '' : '';
return this.changeState(state_dict);
......@@ -84,7 +81,7 @@
});
}
return {};
}, {mutex: 'changestate'})
})
.declareMethod('checkValidity', function () {
if (this.state.editable) {
......@@ -94,5 +91,5 @@
});
}
return true;
}, {mutex: 'changestate'});
});
}(window, rJS));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.10615.49166.8413</string> </value>
<value> <string>962.4135.1398.9574</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1517321807.6</float>
<float>1505315155.72</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -57,10 +57,7 @@
subfield_timezone_key: field_json.subfield_timezone_key,
start_datetime: field_json.start_datetime,
end_datetime: field_json.end_datetime,
hidden: field_json.hidden,
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
hidden: field_json.hidden
};
return this.changeState(state_dict);
})
......@@ -229,7 +226,7 @@
.push(function (gadget_list) {
var text_content = "",
state_date,
offset_time_zone;
options;
if (gadget.state.value) {
state_date = new Date(gadget.state.value);
if (gadget.state.timezone_style) {
......@@ -238,13 +235,14 @@
text_content += " " + state_date.toLocaleTimeString();
}
} else {
//get timezone difference between server and local browser
offset_time_zone = timezone + (state_date.getTimezoneOffset() / 60);
//adjust hour in order to get correct date time string
state_date.setUTCHours(state_date.getUTCHours() + offset_time_zone);
text_content = state_date.toLocaleDateString();
// We don't know the timezone used by erp5 to store the date
// display it as displayed in editable
options = {timeZone: "UTC"};
text_content = state_date.toLocaleDateString(undefined,
options);
if (!gadget.state.date_only) {
text_content += " " + state_date.toLocaleTimeString();
text_content += " " + state_date.toLocaleTimeString(undefined,
options);
}
}
}
......@@ -367,7 +365,7 @@
});
}
return result;
}, {mutex: 'changestate'})
})
.declareMethod('checkValidity', function () {
var gadget = this;
......@@ -378,6 +376,6 @@
});
}
return true;
}, {mutex: 'changestate'});
});
}(window, rJS, RSVP));
\ No newline at end of file
......@@ -224,7 +224,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.3167.36247.3959</string> </value>
<value> <string>964.26946.11355.11605</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -242,7 +242,7 @@
</tuple>
<state>
<tuple>
<float>1517321711.65</float>
<float>1514370341.04</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -14,10 +14,7 @@
editable: field_json.editable,
name: field_json.key,
title: field_json.title,
hidden: field_json.hidden,
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
hidden: field_json.hidden
};
state_dict.inner_html = state_dict.value;
return this.changeState(state_dict);
......
......@@ -236,7 +236,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>963.11788.48702.26146</string> </value>
<value> <string>955.2252.33079.47462</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -254,7 +254,7 @@
</tuple>
<state>
<tuple>
<float>1516702186.86</float>
<float>1479375938.91</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -17,10 +17,7 @@
name: field_json.key,
title: field_json.title,
type: 'email',
hidden: field_json.hidden,
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
hidden: field_json.hidden
};
state_dict.text_content = state_dict.value;
return this.changeState(state_dict);
......@@ -63,7 +60,7 @@
});
}
return {};
}, {mutex: 'changestate'})
})
.declareMethod('checkValidity', function () {
if (this.state.editable) {
......@@ -73,6 +70,6 @@
});
}
return true;
}, {mutex: 'changestate'});
});
}(window, rJS));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value>
<value> <string>955.51162.4768.35123</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1517321664.03</float>
<float>1482843519.98</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -14,8 +14,7 @@
rJS(window)
.setState({
subgadget_template: undefined,
editable: undefined,
css_class: ''
editable: undefined
})
.declareAcquiredMethod("jio_getAttachment", "jio_getAttachment")
......@@ -33,7 +32,6 @@
title: field_json.title,
hidden: field_json.hidden,
view: field_json.view,
css_class: field_json.css_class,
// field_json._embedded is HATEOASed subobj specs included in FormBox
erp5_embedded_document: field_json._embedded
};
......@@ -77,11 +75,6 @@
// do not preserve objects in the state
delete gadget.state.erp5_embedded_document;
// pass CSS class to the DIV element
if (modification_dict.hasOwnProperty('css_class')) {
gadget.element.classList.add(modification_dict.css_class);
}
return gadget.getDeclaredGadget('sub')
.push(function (subgadget) {
subgadget.render(form_options);
......
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>961.29423.48444.21077</string> </value>
<value> <string>961.56527.16709.20804</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1502977334.64</float>
<float>1517248866.15</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -16,10 +16,7 @@
required: field_json.required,
name: field_json.key,
title: field_json.title,
hidden: field_json.hidden,
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
hidden: field_json.hidden
};
return this.changeState(state_dict);
})
......@@ -61,7 +58,7 @@
});
}
return {};
}, {mutex: 'changestate'})
})
.declareMethod('checkValidity', function () {
if (this.state.editable) {
......@@ -71,6 +68,6 @@
});
}
return true;
}, {mutex: 'changestate'});
});
}(window, rJS));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value>
<value> <string>955.51162.4768.35123</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1517321650.56</float>
<float>1482843418.41</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -41,10 +41,7 @@
// if unspecified we can use "any" value
step: "any",
// `append` is a string to display next to the field ("%", "EUR"...)
append: '',
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
append: ''
},
tmp;
......@@ -108,7 +105,7 @@
});
}
return {};
}, {mutex: 'changestate'})
})
.declareMethod('checkValidity', function () {
if (this.state.editable) {
......@@ -118,6 +115,6 @@
});
}
return true;
}, {mutex: 'changestate'});
});
}(window, rJS, Math));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value>
<value> <string>963.40246.8021.32017</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1517321634.14</float>
<float>1512458225.4</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -225,7 +225,7 @@
return gadget.props.listbox_gadget.getListboxInfo();
}
return {};
}, {mutex: 'changestate'})
})
.declareMethod("getContent", function (options) {
var form_gadget = this,
k,
......@@ -259,7 +259,7 @@
.push(function () {
return data;
});
}, {mutex: 'changestate'})
})
.declareMethod("checkValidity", function () {
var form_gadget = this,
k,
......@@ -286,6 +286,6 @@
return result;
});
}, {mutex: 'changestate'});
});
}(window, document, rJS, RSVP));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.58561.19908.14080</string> </value>
<value> <string>964.25533.41108.47530</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1516274548.88</float>
<float>1515496577.67</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -14,10 +14,7 @@
url: options.field_json.url,
sandbox: options.field_json.sandbox || undefined,
hidden: options.field_json.hidden,
css_class: options.field_json.css_class,
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
css_class: options.field_json.css_class
});
})
......@@ -82,6 +79,6 @@
.push(function (result) {
return result.getContent();
});
}, {mutex: 'changestate'});
});
}(window, rJS, document));
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.300.34630.14250</string> </value>
<value> <string>962.24020.58652.57139</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1516703954.27</float>
<float>1507901872.84</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -15,4 +15,46 @@
});
};
/** Return true if the value truly represents an empty value.
Calling isEmpty(x) is more robust than expression !x.
*/
function isEmpty(value) {
return (value === undefined ||
value === null ||
value.length === 0);
}
window.isEmpty = isEmpty;
/** Make sure that returned object is an Array instance.
*/
function ensureArray(obj) {
if (Array.isArray(obj)) {return obj; }
if (isEmpty(obj)) {return []; }
return [obj];
}
window.ensureArray = ensureArray;
/** Return first non-empty variable or the last one.
Calling getNonEmpy(a, b, "") is more robust way of writing a || b || "".
Variables coercing to false (e.g 0) do not get skipped anymore.
*/
function getFirstNonEmpty() {
var i;
if (arguments.length === 0) {
return null;
}
for (i = 0; i < arguments.length; i++) {
if (!isEmpty(arguments[i])) {
return arguments[i];
}
}
if (arguments.length === 1) {
return arguments[0];
}
return arguments[arguments.length - 1];
}
window.getFirstNonEmpty = getFirstNonEmpty;
}(window, RSVP));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>954.14461.31508.53930</string> </value>
<value> <string>960.5523.58984.43537</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1476894652.41</float>
<float>1517406504.9</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -18,10 +18,7 @@
required: field_json.required,
name: field_json.key,
title: field_json.title,
hidden: field_json.hidden,
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
hidden: field_json.hidden
};
state_dict.text_content = state_dict.value;
return this.changeState(state_dict);
......@@ -65,7 +62,7 @@
});
}
return {};
}, {mutex: 'changestate'})
})
.declareMethod('checkValidity', function () {
if (this.state.editable) {
......@@ -75,6 +72,6 @@
});
}
return true;
}, {mutex: 'changestate'});
});
}(window, rJS));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value>
<value> <string>956.15712.57649.37376</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1517321585.88</float>
<float>1482843064.62</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -119,7 +119,7 @@
this.state.label_element.setAttribute('for', gadget.state.scope);
if (modification_dict.hasOwnProperty('css_class') && this.state.css_class) {
this.state.label_element.classList.add(this.state.css_class);
this.element.classList.add(this.state.css_class);
}
if (modification_dict.hasOwnProperty('error_text')) {
......@@ -185,7 +185,7 @@
}
return true;
});
}, {mutex: 'changestate'})
})
.declareMethod('getContent', function () {
var argument_list = arguments;
......@@ -196,7 +196,7 @@
}
return {};
});
}, {mutex: 'changestate'})
})
.declareMethod('getListboxInfo', function () {
var argument_list = arguments;
......@@ -204,22 +204,14 @@
.push(function (gadget) {
return gadget.getListboxInfo.apply(gadget, argument_list);
});
}, {mutex: 'changestate'})
})
.allowPublicAcquisition("notifyInvalid", function (param_list) {
// Label doesn't know when a subgadget calls notifyInvalid
// Prevent mutex dead lock by defering the changeState call
return this.deferErrorTextRender(param_list[0]);
return this.changeState({error_text: param_list[0]});
})
.allowPublicAcquisition("notifyValid", function () {
// Label doesn't know when a subgadget calls notifyValid
// Prevent mutex dead lock by defering the changeState call
return this.deferErrorTextRender('');
})
.declareJob('deferErrorTextRender', function (error_text) {
return this.changeState({error_text: error_text});
return this.changeState({error_text: ''});
});
}(window, document, rJS, RSVP));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.59013.39016.42820</string> </value>
<value> <string>965.9315.27783.1843</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1516293734.37</float>
<float>1517246822.2</float>
<string>UTC</string>
</tuple>
</state>
......
/*globals window, document, RSVP, rJS,
URI, location, XMLHttpRequest, console, navigator, ProgressEvent*/
URI, location, XMLHttpRequest, console, navigator*/
/*jslint indent: 2, maxlen: 80*/
(function (window, document, RSVP, rJS,
XMLHttpRequest, location, console, navigator, ProgressEvent) {
XMLHttpRequest, location, console, navigator) {
"use strict";
var MAIN_SCOPE = "m";
......@@ -133,9 +133,6 @@
// Display it to the user for now,
// and allow user to go back to the frontpage
var error_text = "";
if (error instanceof ProgressEvent) {
error = error.target.error;
}
if (error.target instanceof XMLHttpRequest) {
error_text = error.target.toString() + " " +
......@@ -650,4 +647,4 @@
});
}(window, document, RSVP, rJS,
XMLHttpRequest, location, console, navigator, ProgressEvent));
\ No newline at end of file
XMLHttpRequest, location, console, navigator));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.44401.33443.35072</string> </value>
<value> <string>964.44144.54943.18056</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1516619185.21</float>
<float>1515401365.21</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -21,10 +21,7 @@
"required": options.field_json.required,
"hidden": options.field_json.hidden,
"title": options.field_json.title,
"key": options.field_json.key,
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
"key": options.field_json.key
};
if (this.state.gadget_rendered === false) {
......
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.58561.19908.14080</string> </value>
<value> <string>964.54328.21867.14506</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1517321571.05</float>
<float>1516015281.65</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -197,9 +197,7 @@
}
}
// Cancel previous line rendering to not conflict with the asynchronous render for now
gadget.fetchLineContent(true);
queue = new RSVP.Queue();
queue = RSVP.Queue();
if (!variable.translated_records) {
queue
.push(function () {
......@@ -214,6 +212,10 @@
});
}
queue
.push(function () {
// Cancel previous line rendering to not conflict with the asynchronous render for now
return gadget.fetchLineContent(true);
})
.push(function () {
// XXX Fix in case of multiple listboxes
return RSVP.all([
......@@ -295,7 +297,6 @@
command: field_json.command || 'index',
// Force line calculation in any case
render_timestamp: new Date().getTime(),
allDocs_result: undefined,
// No error message
......@@ -760,7 +761,7 @@
data[form_gadget.props.listbox_uid_dict.key] = form_gadget.props.listbox_uid_dict.value;
return data;
});
}, {mutex: 'changestate'})
})
.onEvent('click', function (evt) {
var gadget = this,
......
......@@ -236,7 +236,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.60204.10137.19421</string> </value>
<value> <string>964.49926.23272.20514</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -254,7 +254,7 @@
</tuple>
<state>
<tuple>
<float>1516364900.78</float>
<float>1515755492.39</float>
<string>UTC</string>
</tuple>
</state>
......
/*global window, rJS*/
/*global window, rJS, isEmpty, getFirstNonEmpty */
/*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80 */
(function (window, rJS) {
(function (window, rJS, getFirstNonEmpty) {
"use strict";
rJS(window)
......@@ -11,20 +11,17 @@
.declareMethod('render', function (options) {
var field_json = options.field_json || {},
state_dict = {
value: field_json.value || field_json.default || "",
value: getFirstNonEmpty(field_json.value, field_json['default'], ""),
item_list: JSON.stringify(field_json.items),
editable: field_json.editable,
required: field_json.required,
name: field_json.key,
title: field_json.title,
first_item: field_json.first_item,
hidden: field_json.hidden,
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
hidden: field_json.hidden
};
if ((!state_dict.value) && (state_dict.first_item)) {
// first_item means to select the first item by default on empty value
if (isEmpty(state_dict.value) && (state_dict.first_item)) {
state_dict.value = field_json.items[0][1];
}
return this.changeState(state_dict);
......@@ -99,7 +96,7 @@
});
}
return {};
}, {mutex: 'changestate'})
})
.declareMethod('checkValidity', function () {
if (this.state.editable) {
......@@ -109,6 +106,6 @@
});
}
return true;
}, {mutex: 'changestate'});
});
}(window, rJS));
\ No newline at end of file
}(window, rJS, getFirstNonEmpty));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.1659.33258.11707</string> </value>
<value> <string>965.10978.44363.39543</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1516786204.34</float>
<float>1517406625.1</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -60,10 +60,7 @@
name: field_json.key,
item_list: field_json.items,
value_list: field_json.value || field_json.default,
hidden: field_json.hidden,
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
hidden: field_json.hidden
};
return this.changeState(state_dict);
......@@ -146,5 +143,5 @@
});
}
return final_result;
}, {mutex: 'changestate'});
});
}(window, rJS, RSVP, document));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value>
<value> <string>960.5523.58984.43537</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1517321512.62</float>
<float>1505309155.21</float>
<string>UTC</string>
</tuple>
</state>
......
/*global window, rJS, document, RSVP*/
/*global window, rJS, document, RSVP, isEmpty, ensureArray */
/*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80, unparam: true */
(function (window, rJS, document, RSVP) {
(function (window, rJS, document, RSVP, isEmpty, ensureArray) {
'use strict';
/* Make sure that returned object is an Array instance. */
function ensureArray(obj) {
if (!obj) {return []; }
if (Array.isArray(obj)) {return obj; }
return [obj];
/** More robust way of writing a || b || "" because if b===0 it gets skipped.
*/
function getNonEmpty() {
var i;
for (i = 0; i < arguments.length; i++) {
if (!isEmpty(arguments[i])) {
return arguments[i];
}
}
if (arguments.length === 1) {
return arguments[0];
}
return arguments[arguments.length - 1];
}
function appendListField(gadget, value, item_list) {
......@@ -37,10 +45,11 @@
rJS(window)
.declareMethod('render', function (options) {
var field_json = options.field_json || {},
item_list = field_json.items,
item_list = ensureArray(field_json.items),
state_dict = {
value_list: JSON.stringify(
ensureArray(field_json.value || field_json.default)
ensureArray(
getNonEmpty(field_json.value, field_json['default'], []))
),
editable: field_json.editable,
required: field_json.required,
......@@ -49,11 +58,13 @@
key: field_json.key,
sub_select_key: field_json.sub_select_key,
sub_input_key: field_json.sub_input_key,
hidden: field_json.hidden,
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
hidden: field_json.hidden
};
// Items can be simply an array of values. It is a valid input produced
// usually by TALES expression
if (item_list.length > 0 && !Array.isArray(item_list[0])) {
item_list = item_list.map(function (item) {return [item, item]; });
}
if ((item_list.length === 0) || (item_list[0][0] !== "")) {
item_list.unshift(["", ""]);
}
......@@ -77,17 +88,13 @@
element.removeChild(element.firstChild);
}
function enQueue() {
var argument_list = arguments;
value_list.forEach(function (value) {
queue
.push(function () {
return appendListField.apply(this, argument_list);
return appendListField(gadget, value, item_list);
});
});
}
for (i = 0; i < value_list.length; i += 1) {
enQueue(gadget, value_list[i], item_list);
}
return queue;
})
......@@ -136,7 +143,7 @@
});
}
return final_result;
}, {mutex: 'changestate'})
})
.allowPublicAcquisition('notifyValid', function () {
return;
......@@ -197,6 +204,6 @@
});
}
return true;
}, {mutex: 'changestate'});
});
}(window, rJS, document, RSVP));
\ No newline at end of file
}(window, rJS, document, RSVP, isEmpty, ensureArray));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value>
<value> <string>965.11854.16357.58572</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1517321477.39</float>
<float>1517406578.58</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -14,7 +14,6 @@
return input_gadget.render({
editable: gadget.state.editable,
query: gadget.state.query,
sort_list_json: gadget.state.sort_list_json,
catalog_index: gadget.state.catalog_index,
allow_jump: gadget.state.allow_jump,
// required: field_json.required,
......@@ -48,7 +47,6 @@
state_dict = {
editable: field_json.editable,
query: field_json.query,
sort_list_json: JSON.stringify(field_json.sort),
catalog_index: field_json.catalog_index,
allow_jump: field_json.allow_jump,
required: field_json.required,
......@@ -60,10 +58,7 @@
portal_types: field_json.portal_types,
translated_portal_types: field_json.translated_portal_types,
relation_field_id: field_json.relation_field_id,
hidden: field_json.hidden,
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
hidden: field_json.hidden
};
if (field_json.default.hasOwnProperty('value_text_list')) {
......@@ -242,6 +237,6 @@
});
}
return final_result;
}, {mutex: 'changestate'});
});
}(window, rJS, RSVP, document));
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value>
<value> <string>964.38497.25325.33501</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1517321450.32</float>
<float>1515062767.93</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -526,13 +526,9 @@ div[data-gadget-scope='panel'] ul li a {
overflow: hidden;
white-space: nowrap;
}
div[data-gadget-scope='panel'] ul li a.active {
color: #1F1F1F;
background-color: #FFFFFF;
}
div[data-gadget-scope='panel'] ul li a:hover,
div[data-gadget-scope='panel'] ul li a:active {
color: #FFFFFF;
div[data-gadget-scope='panel'] ul li a:active,
div[data-gadget-scope='panel'] ul li a.active {
background-color: #2b2b2b;
}
div[data-gadget-scope='panel'] ul li a::before {
......@@ -568,13 +564,9 @@ div[data-gadget-scope='panel'] dl dd a {
white-space: nowrap;
padding-left: 36pt;
}
div[data-gadget-scope='panel'] dl dd a.active {
color: #1F1F1F;
background-color: #FFFFFF;
}
div[data-gadget-scope='panel'] dl dd a:hover,
div[data-gadget-scope='panel'] dl dd a:active {
color: #FFFFFF;
div[data-gadget-scope='panel'] dl dd a:active,
div[data-gadget-scope='panel'] dl dd a.active {
background-color: #2b2b2b;
}
div[data-gadget-scope='panel'] dl dd a::before {
......@@ -983,24 +975,6 @@ div[data-gadget-scope='header'] .ui-header ul {
.gadget-content input[type='submit']:active {
background-color: #ffa366;
}
.gadget-content button[name='action_update'] {
padding: 6pt;
margin-top: 30pt;
margin-right: 12pt;
background-color: #777777;
color: #FFFFFF;
border-radius: 0.325em;
border-width: 1px;
border-style: solid;
min-width: 8em;
}
.gadget-content button[name='action_update']:hover,
.gadget-content button[name='action_update']:focus {
background-color: #919191;
}
.gadget-content button[name='action_update']:active {
background-color: #aaaaaa;
}
@media not screen and (max-width: 85em) {
div[data-role='page']:not(.desktop-panel-hidden) .gadget-content {
margin-left: 180pt;
......@@ -1023,13 +997,16 @@ div[data-gadget-scope='header'] .ui-header ul {
.gadget-content .field_container > div > div > div.ui-field-contain div {
width: 100%;
}
.gadget-content .horizontal_align_form_box .field_container > div {
/* Class .horizontal_align_form_box is here only for backward-compatibility!
It is used to force horizontal rendering of fields inside FormBox.
The first > div represents form-group ("left", "right" ...) */
.gadget-content .field_container > div > div.horizontal_align_form_box > .ui-field-contain {
padding: 0;
}
.gadget-content .field_container > div > div.horizontal_align_form_box > .ui-field-contain > label {
padding-top: 9pt;
}
.gadget-content .field_container > div > div.horizontal_align_form_box .field_container > div {
display: flex;
}
.gadget-content .horizontal_align_form_box .field_container > div > div {
.gadget-content .field_container > div > div.horizontal_align_form_box .field_container > div > div {
flex: 1;
}
.gadget-content .ui-content-header-plain {
......@@ -1118,6 +1095,7 @@ div[data-gadget-scope='header'] .ui-header ul {
}
.gadget-content .ui-field-contain > label {
color: #777777;
padding: 3pt;
}
.gadget-content .ui-field-contain > label.required {
font-weight: bold;
......@@ -1125,6 +1103,9 @@ div[data-gadget-scope='header'] .ui-header ul {
.gadget-content .ui-field-contain > label.invisible {
display: none;
}
.gadget-content .ui-field-contain p {
padding: 3pt;
}
@media only screen and (min-width: 45em) and (max-width: 85em), not screen and (max-width: 85em) {
.gadget-content .ui-field-contain {
display: flex;
......
......@@ -242,7 +242,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.10742.13164.48827</string> </value>
<value> <string>965.9378.54486.51763</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -260,7 +260,7 @@
</tuple>
<state>
<tuple>
<float>1517329600.93</float>
<float>1517248083.17</float>
<string>UTC</string>
</tuple>
</state>
......
/*global window, rJS, RSVP, Handlebars, calculatePageTitle */
/*global window, rJS, RSVP, Handlebars, calculatePageTitle, URL */
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP, Handlebars, calculatePageTitle) {
(function (window, rJS, RSVP, Handlebars, calculatePageTitle, URL) {
"use strict";
/////////////////////////////////////////////////////////////////
......@@ -67,24 +67,48 @@
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("getUrlParameter", "getUrlParameter")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod("render", function (options) {
var gadget = this,
erp5_document,
report_list;
erp5_document;
return gadget.jio_getAttachment(options.jio_key, "links")
.push(function (result) {
erp5_document = result;
report_list = asArray(erp5_document._links.action_object_report_jio)
.concat(asArray(erp5_document._links.action_object_jio_report));
.push(function (jio_document) {
var report_list = asArray(jio_document._links.action_object_report_jio)
.concat(asArray(jio_document._links.action_object_jio_report)),
print_list = asArray(jio_document._links.action_object_jio_print),
exchange_list = asArray(jio_document._links.action_object_jio_exchange);
erp5_document = jio_document;
return new RSVP.Queue()
.push(function () {
return gadget.getUrlParameter("view");
})
.push(function (prev_view) {
// prev_view can have two forms
// 1/ action name like "view", "detail"...
// 2/ absolute script URL like "https://erp5.com/erp5/web_site_module/renderjs_runner/hateoas/ERP5Document_getHateoas?mode=traverse&relative_url=account_module%2Fbank&view=transaction_list"
if (prev_view.startsWith('http')) {
prev_view = new URL(prev_view).searchParams.get("view");
}
print_list.forEach(function (link) {
if (link.href.search(/\?/) > 0) {
link.href += "&";
} else {
link.href += "?";
}
link.href += "prev_view=" + prev_view;
});
return RSVP.all([
renderLinkList(gadget, "Reports", "bar-chart-o", report_list)
renderLinkList(gadget, "Exchange", "file", exchange_list),
renderLinkList(gadget, "Reports", "bar-chart-o", report_list),
renderLinkList(gadget, "Print", "print", print_list)
]);
});
})
.push(function (translated_html_link_list) {
gadget.element.innerHTML = translated_html_link_list.join("\n");
......@@ -101,4 +125,4 @@
});
});
}(window, rJS, RSVP, Handlebars, calculatePageTitle));
}(window, rJS, RSVP, Handlebars, calculatePageTitle, URL));
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>963.3162.7999.42854</string> </value>
<value> <string>964.64570.61398.48110</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1509097420.01</float>
<float>1516871683.64</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -42,19 +42,19 @@
.push(function (g) {
return g.triggerSubmit();
});
}, {mutex: 'changestate'})
})
.declareMethod('checkValidity', function () {
return this.getDeclaredGadget('fg')
.push(function (declared_gadget) {
return declared_gadget.checkValidity();
});
}, {mutex: 'changestate'})
})
.declareMethod('getContent', function () {
return this.getDeclaredGadget('fg')
.push(function (declared_gadget) {
return declared_gadget.getContent();
});
}, {mutex: 'changestate'})
})
/////////////////////////////////////////////////////////////////
// Own methods
......
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.45640.391.48230</string> </value>
<value> <string>963.49235.21851.43451</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1516294817.06</float>
<float>1515078479.71</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -62,6 +62,15 @@
filter_action: true
});
})
.allowPublicAcquisition('getUrlParameter', function (argument_list) {
return this.getUrlParameter(argument_list)
.push(function (result) {
if ((result === undefined) && (argument_list[0] === 'field_listbox_sort_list:json')) {
return [];
}
return result;
});
})
.declareMethod("render", function (options) {
var gadget = this,
select_template = options.select_template || "";
......
......@@ -71,9 +71,7 @@
</item>
<item>
<key> <string>content_type</string> </key>
<value>
<none/>
</value>
<value> <string>text/javascript</string> </value>
</item>
<item>
<key> <string>default_reference</string> </key>
......@@ -236,7 +234,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.60339.56148.38212</string> </value>
<value> <string>961.17732.18127.14097</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -254,7 +252,7 @@
</tuple>
<state>
<tuple>
<float>1516373132.37</float>
<float>1502199416.77</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -330,7 +330,7 @@
}
// Typing a search query should not modify the header status
return;
}, {mutex: 'changestate'})
})
.allowPublicAcquisition('notifyValid', function () {
// Typing a search query should not modify the header status
return;
......
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.45640.391.48230</string> </value>
<value> <string>964.39835.8408.1945</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1516295067.02</float>
<float>1515142977.99</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -17,10 +17,7 @@
name: field_json.key,
title: field_json.title,
type: 'password',
hidden: field_json.hidden,
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
hidden: field_json.hidden
};
state_dict.text_content = state_dict.value;
return this.changeState(state_dict);
......@@ -72,7 +69,7 @@
});
}
return {};
}, {mutex: 'changestate'})
})
.declareMethod('checkValidity', function () {
if (this.state.editable) {
......@@ -82,6 +79,6 @@
});
}
return true;
}, {mutex: 'changestate'});
});
}(window, rJS));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value>
<value> <string>955.51162.4768.35123</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1517321403.8</float>
<float>1482843530.9</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -17,15 +17,6 @@
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="jiodev.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script id="dialog-button-template" type="text/x-handlebars-template">
{{#if show_update_button}}
<button name="action_update" type="submit" data-i18n="Update">Update</button>
{{/if}}
<input name="action_confirm" class="dialogconfirm" data-theme="b" data-inline="true" type="submit" data-i18n="[value]Proceed" value="Proceed" data-icon="check" />
<a class="dialogcancel" data-i18n="Cancel">Cancel</a>
</script>
<!-- custom script -->
<script src="gadget_erp5_global.js" type="text/javascript"></script>
......@@ -44,7 +35,8 @@
data-gadget-scope="erp5_form"
data-gadget-sandbox="public">
</div>
<div class="dialog_button_container"></div>
<input class="dialogconfirm" data-theme="b" data-inline="true" type="submit" data-i18n="[value]Proceed" value="Proceed" data-icon="check" />
<a class="dialogcancel" data-i18n="Cancel">Cancel</a>
</form>
</body>
</html>
\ No newline at end of file
......@@ -234,7 +234,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.10309.12229.56627</string> </value>
<value> <string>962.14191.38290.31931</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -252,7 +252,7 @@
</tuple>
<state>
<tuple>
<float>1517304075.06</float>
<float>1506093694.63</float>
<string>UTC</string>
</tuple>
</state>
......
/*jslint nomen: true, indent: 2, maxerr: 3 */
/*global window, rJS, RSVP, URI, calculatePageTitle, Blob, URL, document, jIO, Handlebars */
(function (window, rJS, RSVP, URI, calculatePageTitle, Blob, URL, document, jIO, Handlebars) {
/*global window, rJS, RSVP, URI, calculatePageTitle, Blob, URL, document, jIO, ensureArray */
(function (window, rJS, RSVP, URI, calculatePageTitle, Blob, URL, document, jIO, ensureArray) {
"use strict";
/* Make sure that returned object is an Array instance. */
function ensureArray(obj) {
if (!obj) {return []; }
if (Array.isArray(obj)) {return obj; }
return [obj];
rJS(window)
/////////////////////////////////////////////////////////////////
// acquisition
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("jio_putAttachment", "jio_putAttachment")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("notifySubmitting", "notifySubmitting")
.declareAcquiredMethod("notifySubmitted", "notifySubmitted")
.declareAcquiredMethod("translate", "translate")
.declareAcquiredMethod("notifyChange", "notifyChange")
.declareAcquiredMethod("updateForm", "updateForm")
.declareAcquiredMethod("displayFormulatorValidationError", "displayFormulatorValidationError")
/////////////////////////////////////////////////////////////////
// Proxy methods to the child gadget
/////////////////////////////////////////////////////////////////
.declareMethod('checkValidity', function () {
return this.getDeclaredGadget("erp5_form")
.push(function (declared_gadget) {
return declared_gadget.checkValidity();
});
})
.declareMethod('getContent', function () {
return this.getDeclaredGadget("erp5_form")
.push(function (declared_gadget) {
return declared_gadget.getContent();
});
})
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod('triggerSubmit', function () {
this.element.querySelector('input[type="submit"]').click();
})
.declareMethod('render', function (options) {
// copy out wanted items from options and pass it to `changeState`
return this.changeState({
jio_key: options.jio_key,
view: options.view,
// ignore options.editable because dialog is always editable
erp5_document: options.erp5_document,
form_definition: options.form_definition,
erp5_form: options.erp5_form || {}
// ignore global editable state (be always editable)
});
})
.onStateChange(function () {
var form_gadget = this,
icon,
selector = form_gadget.element.querySelector("h3"),
title,
i,
view_list = ensureArray(this.state.erp5_document._links.action_workflow);
title = this.state.form_definition.title;
// XXX hardcoded...
switch (title) {
case "Create User":
icon = " ui-icon-user";
break;
case "Create Document":
icon = " ui-icon-file-o";
break;
case "Validate Workflow Action":
icon = " ui-icon-share-alt";
break;
case "Submit":
icon = " ui-icon-check";
break;
default:
icon = " ui-icon-random";
break;
}
function submitDialog(gadget, submit_action_id, is_update_method) {
var form_gadget = gadget,
action = form_gadget.state.erp5_document._embedded._view._actions.put,
form_id = form_gadget.state.erp5_document._embedded._view.form_id,
for (i = 0; i < view_list.length; i += 1) {
if (view_list[i].href === this.state.view) {
title = view_list[i].title;
}
}
// Calculate the h3 properties
return new RSVP.Queue()
.push(function () {
return RSVP.all([
form_gadget.translate(form_gadget.state.form_definition.title),
form_gadget.translate(title)
]);
})
.push(function (translated_title_list) {
form_gadget.element.querySelector('input.dialogconfirm').value = translated_title_list[1];
selector.textContent = "\u00A0" + translated_title_list[0];
selector.className = "ui-content-title ui-body-c ui-icon ui-icon-custom" + icon;
// Render the erp5_from
return form_gadget.getDeclaredGadget("erp5_form");
})
.push(function (erp5_form) {
var form_options = form_gadget.state.erp5_form;
// pass own form options to the embedded form
form_options.erp5_document = form_gadget.state.erp5_document;
form_options.form_definition = form_gadget.state.form_definition;
form_options.view = form_gadget.state.view;
form_options.jio_key = form_gadget.state.jio_key;
form_options.editable = true; // dialog is always editable
return erp5_form.render(form_options);
})
.push(function () {
// Render the headers
return RSVP.all([
form_gadget.getUrlFor({command: 'change', options: {page: undefined, view: undefined}}),
calculatePageTitle(form_gadget, form_gadget.state.erp5_document)
]);
})
.push(function (all_result) {
form_gadget.element.querySelector('a.dialogcancel').href = all_result[0];
return form_gadget.updateHeader({
cancel_url: all_result[0],
page_title: all_result[1]
});
});
})
/** The only way how to force download from javascript (working everywhere)
* is unfortunately constructing <a> and clicking on it
*/
.declareJob("forceDownload", function (attachment) {
var attachment_data = attachment.target.response,
filename = /(?:^|;)\s*filename\s*=\s*"?([^";]+)/i.exec(
attachment.target.getResponseHeader("Content-Disposition") || ""
),
a_tag = document.createElement("a");
if (attachment.target.responseType !== "blob") {
attachment_data = new Blob(
[attachment.target.response],
{type: attachment.target.getResponseHeader("Content-Type")}
);
}
a_tag.style = "display: none";
a_tag.href = URL.createObjectURL(attachment_data);
a_tag.download = filename ? filename[1].trim() : "untitled";
document.body.appendChild(a_tag);
a_tag.click();
return new RSVP.Queue()
.push(function () {
return RSVP.delay(10);
})
.push(function () {
URL.revokeObjectURL(a_tag.href);
document.body.removeChild(a_tag);
});
})
.onEvent('submit', function () {
var form_gadget = this,
action = this.state.erp5_document._embedded._view._actions.put,
field_dict = this.state.erp5_document._embedded._view,
redirect_to_parent;
return form_gadget.notifySubmitting()
......@@ -26,14 +181,14 @@
.push(function (content_dict) {
var data = {},
key;
data[form_id.key] = form_id['default'];
// XXX Hardcoded
data.dialog_id = form_id['default'];
data.dialog_method = form_gadget.state.form_definition[submit_action_id];
if (is_update_method) {
data.update_method = data.dialog_method;
/* Fields "form_id", "dialog_id" and "selection_name" are special
because they are necessary for Base_callDialogMethod to work */
data[field_dict.form_id.key] = field_dict.form_id['default'];
data[field_dict.dialog_id.key] = field_dict.dialog_id['default'];
if (field_dict.hasOwnProperty('selection_name')) {
data[field_dict.selection_name.key] = field_dict.selection_name['default'];
}
data.dialog_method = action.action;
//XXX hack for redirect, difined in form
redirect_to_parent = content_dict.field_your_redirect_to_parent;
for (key in content_dict) {
......@@ -181,7 +336,7 @@
.push(undefined, function (error) {
if (error.target !== undefined) {
var error_text = 'Encountered an unknown error. Try to resubmit',
promise;
promise_queue = new RSVP.Queue();
// if we know what the error was, try to precise it for the user
if (error.target.status === 400) {
error_text = 'Input data has errors';
......@@ -189,9 +344,21 @@
error_text = 'You do not have the permissions to edit the object';
} else if (error.target.status === 0) {
error_text = 'Document was not saved! Resubmit when you are online or the document accessible';
} else if (error.target.status === 500 && error.target.response.type === "application/json") {
promise_queue
.push(function () {
return jIO.util.readBlobAsText(error.target.response);
})
.push(function (response_text) {
var response = JSON.parse(response_text.target.result);
error_text = response.portal_status_message;
});
}
// display translated error_text to user
promise = form_gadget.notifySubmitted()
promise_queue
.push(function () {
return form_gadget.notifySubmitted();
})
.push(function () {
return form_gadget.translate(error_text);
})
......@@ -204,7 +371,7 @@
// if server validation of form data failed (indicated by response code 400)
// we parse out field errors and display them to the user
if (error.target.status === 400) {
promise
promise_queue
.push(function () {
// when the server-side validation returns the error description
if (error.target.responseType === "blob") {
......@@ -217,210 +384,12 @@
return form_gadget.displayFormulatorValidationError(JSON.parse(event.target.result));
});
}
return promise;
return promise_queue;
}
throw error;
});
}
var gadget_klass = rJS(window),
dialog_button_source = gadget_klass.__template_element
.getElementById("dialog-button-template")
.innerHTML,
dialog_button_template = Handlebars.compile(dialog_button_source);
gadget_klass
/////////////////////////////////////////////////////////////////
// acquisition
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("jio_putAttachment", "jio_putAttachment")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("notifySubmitting", "notifySubmitting")
.declareAcquiredMethod("notifySubmitted", "notifySubmitted")
.declareAcquiredMethod("translate", "translate")
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("notifyChange", "notifyChange")
.declareAcquiredMethod("updateForm", "updateForm")
.declareAcquiredMethod("displayFormulatorValidationError", "displayFormulatorValidationError")
/////////////////////////////////////////////////////////////////
// Proxy methods to the child gadget
/////////////////////////////////////////////////////////////////
.declareMethod('checkValidity', function () {
return this.getDeclaredGadget("erp5_form")
.push(function (declared_gadget) {
return declared_gadget.checkValidity();
});
}, {mutex: 'changestate'})
.declareMethod('getContent', function () {
return this.getDeclaredGadget("erp5_form")
.push(function (declared_gadget) {
return declared_gadget.getContent();
});
}, {mutex: 'changestate'})
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod('triggerSubmit', function () {
this.element.querySelector('input[type="submit"]').click();
}, {mutex: 'changestate'})
.declareMethod('render', function (options) {
// copy out wanted items from options and pass it to `changeState`
return this.changeState({
jio_key: options.jio_key,
view: options.view,
// ignore options.editable because dialog is always editable
erp5_document: options.erp5_document,
form_definition: options.form_definition,
erp5_form: options.erp5_form || {},
// ignore global editable state (be always editable)
show_update_button: Boolean(options.form_definition.update_action)
});
})
.onStateChange(function (modification_dict) {
var form_gadget = this,
icon,
selector = form_gadget.element.querySelector("h3"),
title,
i,
view_list = ensureArray(this.state.erp5_document._links.action_workflow);
title = this.state.form_definition.title;
// XXX hardcoded...
switch (title) {
case "Create User":
icon = " ui-icon-user";
break;
case "Create Document":
icon = " ui-icon-file-o";
break;
case "Validate Workflow Action":
icon = " ui-icon-share-alt";
break;
case "Submit":
icon = " ui-icon-check";
break;
default:
icon = " ui-icon-random";
break;
}
for (i = 0; i < view_list.length; i += 1) {
if (view_list[i].href === this.state.view) {
title = view_list[i].title;
}
}
}, false, true);
return new RSVP.Queue()
.push(function () {
// Set the dialog button
if (modification_dict.hasOwnProperty('show_update_button')) {
return form_gadget.translateHtml(dialog_button_template({
show_update_button: form_gadget.state.show_update_button
}))
.push(function (html) {
form_gadget.element.querySelector('.dialog_button_container')
.innerHTML = html;
});
}
})
.push(function () {
// Calculate the h3 properties
return RSVP.all([
form_gadget.translate(form_gadget.state.form_definition.title),
form_gadget.translate(title)
]);
})
.push(function (translated_title_list) {
form_gadget.element.querySelector('input.dialogconfirm').value = translated_title_list[1];
selector.textContent = "\u00A0" + translated_title_list[0];
selector.className = "ui-content-title ui-body-c ui-icon ui-icon-custom" + icon;
// Render the erp5_from
return form_gadget.getDeclaredGadget("erp5_form");
})
.push(function (erp5_form) {
var form_options = form_gadget.state.erp5_form;
// pass own form options to the embedded form
form_options.erp5_document = form_gadget.state.erp5_document;
form_options.form_definition = form_gadget.state.form_definition;
form_options.view = form_gadget.state.view;
form_options.jio_key = form_gadget.state.jio_key;
form_options.editable = true; // dialog is always editable
return erp5_form.render(form_options);
})
.push(function () {
// Render the headers
return RSVP.all([
form_gadget.getUrlFor({command: 'change', options: {page: undefined, view: undefined}}),
calculatePageTitle(form_gadget, form_gadget.state.erp5_document)
]);
})
.push(function (all_result) {
form_gadget.element.querySelector('a.dialogcancel').href = all_result[0];
return form_gadget.updateHeader({
cancel_url: all_result[0],
page_title: all_result[1]
});
});
})
/** The only way how to force download from javascript (working everywhere)
* is unfortunately constructing <a> and clicking on it
*/
.declareJob("forceDownload", function (attachment) {
var attachment_data = attachment.target.response,
filename = /(?:^|;)\s*filename\s*=\s*"?([^";]+)/i.exec(
attachment.target.getResponseHeader("Content-Disposition") || ""
),
a_tag = document.createElement("a");
if (attachment.target.responseType !== "blob") {
attachment_data = new Blob(
[attachment.target.response],
{type: attachment.target.getResponseHeader("Content-Type")}
);
}
a_tag.style = "display: none";
a_tag.href = URL.createObjectURL(attachment_data);
a_tag.download = filename ? filename[1].trim() : "untitled";
document.body.appendChild(a_tag);
a_tag.click();
return new RSVP.Queue()
.push(function () {
return RSVP.delay(10);
})
.push(function () {
URL.revokeObjectURL(a_tag.href);
document.body.removeChild(a_tag);
});
})
.onEvent('submit', function () {
if (this.state.has_update_action === true) {
return submitDialog(this, "update_action", true);
}
return submitDialog(this, "action");
}, false, true)
.onEvent('click', function (evt) {
if (evt.target.name === "action_confirm") {
evt.preventDefault();
return submitDialog(this, "action");
}
if (evt.target.name === "action_update") {
evt.preventDefault();
return submitDialog(this, "update_action", true);
}
}, false, false);
}(window, rJS, RSVP, URI, calculatePageTitle, Blob, URL, document, jIO, Handlebars));
\ No newline at end of file
}(window, rJS, RSVP, URI, calculatePageTitle, Blob, URL, document, jIO, ensureArray));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.10338.33096.47104</string> </value>
<value> <string>965.12033.58825.17254</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1517305313.45</float>
<float>1517406854.12</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -21,13 +21,13 @@
.push(function (declared_gadget) {
return declared_gadget.checkValidity();
});
}, {mutex: 'changestate'})
})
.declareMethod('getContent', function () {
return this.getDeclaredGadget("erp5_form")
.push(function (declared_gadget) {
return declared_gadget.getContent();
});
}, {mutex: 'changestate'})
})
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
......@@ -101,7 +101,9 @@
new_content_action,
form_gadget.getUrlFor({command: 'change', options: {page: "action"}}),
form_gadget.getUrlFor({command: 'display', options: {}}),
form_gadget.state.erp5_document._links.action_object_jio_report ?
(form_gadget.state.erp5_document._links.action_object_jio_exchange ||
form_gadget.state.erp5_document._links.action_object_jio_report ||
form_gadget.state.erp5_document._links.action_object_jio_print) ?
form_gadget.getUrlFor({command: 'change', options: {page: "export"}}) :
"",
calculatePageTitle(form_gadget, form_gadget.state.erp5_document)
......@@ -150,7 +152,7 @@
focus_on: focus_on
});
});
}, {mutex: 'changestate'})
})
.onEvent('submit', function () {
var gadget = this;
......
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.45640.391.48230</string> </value>
<value> <string>964.64570.61398.48110</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1516351087.15</float>
<float>1516871753.89</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -26,13 +26,13 @@
.push(function (declared_gadget) {
return declared_gadget.checkValidity();
});
}, {mutex: 'changestate'})
})
.declareMethod('getContent', function () {
return this.getDeclaredGadget("erp5_form")
.push(function (declared_gadget) {
return declared_gadget.getContent();
});
}, {mutex: 'changestate'})
})
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
......
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.45640.391.48230</string> </value>
<value> <string>962.4168.39270.46967</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1516351216.09</float>
<float>1514542029.91</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -14,13 +14,13 @@
.push(function (declared_gadget) {
return declared_gadget.checkValidity();
});
}, {mutex: 'changestate'})
})
.declareMethod('getContent', function () {
return this.getDeclaredGadget("erp5_form")
.push(function (declared_gadget) {
return declared_gadget.getContent();
});
}, {mutex: 'changestate'})
})
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
......@@ -55,7 +55,7 @@
form_options.editable = form_gadget.state.editable;
return erp5_form.render(form_options);
});
})
});
}(window, rJS));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>963.11788.48702.26146</string> </value>
<value> <string>961.56888.60131.33518</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1516351314.5</float>
<float>1504617145.02</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -35,13 +35,13 @@
.push(function (declared_gadget) {
return declared_gadget.checkValidity();
});
}, {mutex: 'changestate'})
})
.declareMethod('getContent', function () {
return this.getDeclaredGadget("erp5_form")
.push(function (declared_gadget) {
return declared_gadget.getContent();
});
}, {mutex: 'changestate'})
})
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
......@@ -99,7 +99,9 @@
gadget.getUrlFor({command: 'selection_previous'}),
gadget.getUrlFor({command: 'selection_next'}),
gadget.getUrlFor({command: 'change', options: {page: "tab"}}),
gadget.state.erp5_document._links.action_object_jio_report ?
(gadget.state.erp5_document._links.action_object_jio_exchange ||
gadget.state.erp5_document._links.action_object_jio_report ||
gadget.state.erp5_document._links.action_object_jio_print) ?
gadget.getUrlFor({command: 'change', options: {page: "export"}}) :
"",
calculatePageTitle(gadget, gadget.state.erp5_document)
......
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.58561.19908.14080</string> </value>
<value> <string>964.64570.61398.48110</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1516351419.44</float>
<float>1516872328.37</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -55,10 +55,7 @@
name: field_json.key,
title: field_json.title,
item_list: field_json.items,
hidden: field_json.hidden,
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
hidden: field_json.hidden
};
//the first item will always be selected if no initial default value is supplied.
......@@ -163,5 +160,5 @@
});
}
return final_result;
}, {mutex: 'changestate'});
});
}(window, rJS, RSVP));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value>
<value> <string>954.58788.30707.10649</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1517321388.02</float>
<float>1479375435.94</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -145,17 +145,7 @@
value_uid: options.value_uid,
value_text: options.value_text,
value_portal_type: options.value_portal_type
},
sort_list = JSON.parse(options.sort_list_json);
sort_list.map(function (sort) {
var order = sort[1].toLowerCase();
if (order.startsWith('asc')) {
sort[1] = 'ascending';
} else if (order.startsWith('desc')) {
sort[1] = 'descending';
}
});
state_dict.sort_list_json = JSON.stringify(sort_list);
};
return this.changeState(state_dict);
})
......@@ -309,8 +299,7 @@
]
})),
limit: [0, 10],
select_list: [gadget.state.catalog_index, "uid"],
sort_on: JSON.parse(gadget.state.sort_list_json)
select_list: [gadget.state.catalog_index, "uid"]
});
})
.push(function (result) {
......@@ -365,7 +354,7 @@
};
}
return result;
}, {mutex: 'changestate'})
})
/////////////////////////////////////////////////////////////////
......
......@@ -236,7 +236,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.15380.34560.33723</string> </value>
<value> <string>964.8568.54116.8601</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -254,7 +254,7 @@
</tuple>
<state>
<tuple>
<float>1516352011.0</float>
<float>1513266821.11</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -15,7 +15,6 @@
var render_options = {
editable: field_json.editable,
query: field_json.query,
sort_list_json: JSON.stringify(field_json.sort),
catalog_index: field_json.catalog_index,
allow_jump: field_json.allow_jump,
// required: field_json.required,
......@@ -85,6 +84,6 @@
}
return result;
});
}, {mutex: 'changestate'});
});
}(window, rJS));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>963.11788.48702.26146</string> </value>
<value> <string>958.19776.55952.3225</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1516352110.99</float>
<float>1490691939.14</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -193,7 +193,7 @@
return content_dict;
});
}, {mutex: 'changestate'})
})
.declareAcquiredMethod("triggerSubmit", "triggerSubmit")
.onEvent('click', function (evt) {
......
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>963.65076.53120.24439</string> </value>
<value> <string>963.59679.1954.25241</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1516352207.94</float>
<float>1512408075.41</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -17,10 +17,7 @@
name: field_json.key,
title: field_json.title,
hidden: field_json.hidden,
trim: true,
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
trim: true
};
state_dict.text_content = state_dict.value;
return this.changeState(state_dict);
......@@ -61,7 +58,7 @@
.push(function (gadget) {
return gadget.getContent();
});
}, {mutex: 'changestate'})
})
.declareMethod('checkValidity', function () {
if (this.state.editable) {
......@@ -71,6 +68,6 @@
});
}
return true;
}, {mutex: 'changestate'});
});
}(window, rJS));
\ No newline at end of file
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.64440.33953.5239</string> </value>
<value> <string>960.5523.58984.43537</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1516627821.55</float>
<float>1503499581.59</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -14,10 +14,7 @@
editable: field_json.editable,
name: field_json.key,
title: field_json.title,
hidden: field_json.hidden,
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
hidden: field_json.hidden
};
state_dict.text_content = state_dict.value;
return this.changeState(state_dict);
......@@ -58,7 +55,7 @@
.push(function (subgadget) {
return subgadget.checkValidity();
});
}, {mutex: 'changestate'})
})
.declareMethod('getContent', function () {
if (this.state.editable) {
......@@ -68,6 +65,6 @@
});
}
return {};
}, {mutex: 'changestate'});
});
}(window, rJS));
\ No newline at end of file
......@@ -236,7 +236,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value>
<value> <string>960.5523.58984.43537</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -254,7 +254,7 @@
</tuple>
<state>
<tuple>
<float>1517321833.44</float>
<float>1511311791.54</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -149,7 +149,7 @@
// (as ERP5 does in case of formulator error)
this.state.value = result[input.getAttribute('name')];
return result;
}, {mutex: 'changestate'})
})
.declareAcquiredMethod("notifyValid", "notifyValid")
.declareMethod('checkValidity', function () {
......@@ -180,7 +180,7 @@
});
}
return result;
}, {mutex: 'changestate'})
})
.declareAcquiredMethod("notifyChange", "notifyChange")
.onEvent('change', function () {
......
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.58989.24664.17868</string> </value>
<value> <string>963.50704.60870.52872</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1516352669.6</float>
<float>1511969724.67</float>
<string>UTC</string>
</tuple>
</state>
......
/*global window, rJS, RSVP, Handlebars */
/*global window, rJS, RSVP, Handlebars, getFirstNonEmpty */
/*jslint indent: 2, maxerr: 3, maxlen: 80, nomen: true */
(function (window, rJS, RSVP, Handlebars) {
(function (window, rJS, RSVP, Handlebars, getFirstNonEmpty) {
"use strict";
// How to change html selected option using JavaScript?
......@@ -32,7 +32,7 @@
.declareMethod('render', function (options) {
var state_dict = {
value: options.value || "",
value: getFirstNonEmpty(options.value, ""),
item_list: JSON.stringify(options.item_list),
editable: options.editable,
required: options.required,
......@@ -107,11 +107,6 @@
if (this.state.editable) {
result[select.getAttribute('name')] =
select.options[select.selectedIndex].value;
// Change the value state in place
// This will prevent the gadget to be changed if
// its parent call render with the same value
// (as ERP5 does in case of formulator error)
this.state.value = result[select.getAttribute('name')];
}
return result;
})
......@@ -148,4 +143,4 @@
return this.notifyInvalid(evt.target.validationMessage);
}, true, false);
}(window, rJS, RSVP, Handlebars));
\ No newline at end of file
}(window, rJS, RSVP, Handlebars, getFirstNonEmpty));
\ No newline at end of file
......@@ -97,12 +97,6 @@
<none/>
</value>
</item>
<item>
<key> <string>subject</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Gadget HTML5 Select JS</string> </value>
......@@ -236,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>963.62584.36941.22510</string> </value>
<value> <string>965.10979.12054.27869</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -254,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1516785191.79</float>
<float>1517406671.4</float>
<string>UTC</string>
</tuple>
</state>
......
/*globals window*/
/*jslint indent: 2, nomen: true, maxlen: 80*/
(function (window) {
"use strict";
window.translation_data = {
en: {
"wo": {
"Equals To": "dengyu",
"Workflow-Transitions": "Workflow-Transitions",
"Proceed": "jixu",
"Title": "biaoti",
"text": "text",
"Contains": "baohang",
"Submit": "Submit",
"Next": "houyige",
"data-i18n": "data-i18n",
"i18n": "i18n",
"Add": "zhenjia",
"Cut": "jianque",
"Breadcrumb": "Breadcrumb",
"New": "New",
"Hide Rows": "yanchanlie",
"Save": "baochun",
"Type": "leixing",
"No records": "meiyoujilu",
"Preferences": "pianai",
"Sort": "paixu",
"definition_i18n": "definition_i18n",
"Worklist": "gongzhuoliebiao",
"Viewable": "shitujiemian",
"Configure": "peizhi",
"Configure Editor": "peizhibianjiqi",
"Jumps": "Jumps",
"Confirm": "queren",
"Editable": "bianxue",
"Less Than": "xiaoyu",
"submit": "submit",
"Close": "guangbi",
"Records": "jilu",
"All criterions (AND)": "fuheshuoyou",
"Logout": "tuichu",
"User": "yonghu",
"Front": "Front",
"Input data has errors": "Input data has errors",
"All work caught up!": "All work caught up!",
"Delete": "shangchu",
"record": "record",
"Reset": "Reset",
"Filter Editor": "guolvbianjiqi",
"Search": "soushuo",
"Worklists": "gongzhuoliebiao",
"title": "title",
"Language": "yuyan",
"Action succeeded": "Action succeeded",
"Document was not saved! Resubmit when you are online or the document accessible": "Document was not saved! Resubmit when you are online or the document accessible",
"Modules": "mokuai",
"You do not have the permissions to edit the object": "You do not have the permissions to edit the object",
"ascending": "shangshen",
"Loading": "jiazhaizhong",
"Report": "Report",
"descending": "xiajiang",
"Home": "zhuye",
"Greater Than": "dayu",
"Explore the Search Result List": "liulangjieguo",
"Search Expression": "soushuo",
"History": "lishi",
"Filter": "guolv",
"Invalid Search Criteria": "Invalid Search Criteria",
"Reference": "chankao",
"Searchable Text": "soushuowenben",
"Back": "Back",
"this": "this",
"Select Template": "xuanzhemoban",
"Views": "shitu",
"Data received": "Data received",
"State": "zhuangtai",
"Actions": "caozhuo",
"This page contains unsaved changes, do you really want to leave the page ?": "querenlikai?",
"Jump": "tiaozhuan",
"Encountered an unknown error. Try to resubmit": "Encountered an unknown error. Try to resubmit",
"hide_button_text": "hide_button_text",
"Sort Editor": "paixubianyiqi",
"At least one (OR)": "zhishaoyige",
"Cancel": "Cancel",
"Create New": "tianjia",
"Not Less Than": "dayudengyu",
"Description": "miaoshu",
"Decisions": "Decisions",
"Export": "daochu",
"Not Greater Than": "xiaoyudengyu",
"Previous": "qianyige"
},
"en": {
"Equals To": "Equals To",
"Workflow-Transitions": "Workflow-Transitions",
"Proceed": "Proceed",
"Title": "Title",
"text": "text",
"Contains": "Contains",
"Submit": "Submit",
"Next": "Next",
"data-i18n": "data-i18n",
"i18n": "i18n",
"Add": "Add",
"Cut": "Cut",
"Breadcrumb": "Breadcrumb",
"New": "New",
"Hide Rows": "Hide Rows",
"Save": "Save",
"Type": "Type",
"No records": "No records",
"Preferences": "Preferences",
"Sort": "Sort",
"definition_i18n": "definition_i18n",
"Worklist": "Worklist",
"Viewable": "Viewable",
"Configure": "Configure",
"Configure Editor": "Configure Editor",
"Jumps": "Jumps",
"Confirm": "Confirm",
"Editable": "Editable",
"Less Than": "Less Than",
"submit": "submit",
"Close": "Close",
"Records": "Records",
"All criterions (AND)": "All criterions (AND)",
"Logout": "Logout",
"User": "User",
"Front": "Front",
"Input data has errors": "Input data has errors",
"All work caught up!": "All work caught up!",
"Delete": "Delete",
"record": "record",
"Reset": "Reset",
"Filter Editor": "Filter Editor",
"Search": "Search",
"Worklists": "Worklists",
"title": "title",
"Language": "Language",
"Action succeeded": "Action succeeded",
"Document was not saved! Resubmit when you are online or the document accessible": "Document was not saved! Resubmit when you are online or the document accessible",
"Modules": "Modules",
"You do not have the permissions to edit the object": "You do not have the permissions to edit the object",
"ascending": "ascending",
"Loading": "Loading",
"Report": "Report",
"descending": "descending",
"Home": "Home",
"Greater Than": "Greater Than",
"Explore the Search Result List": "Explore the Search Result List",
"Search Expression": "Search Expression",
"History": "History",
"Filter": "Filter",
"Invalid Search Criteria": "Invalid Search Criteria",
"Reference": "Reference",
"Searchable Text": "Searchable Text",
"Back": "Back",
"this": "this",
"Select Template": "Select Template",
"Views": "Views",
"Data received": "Data received",
"State": "State",
"Actions": "Actions",
"This page contains unsaved changes, do you really want to leave the page ?": "This page contains unsaved changes, do you really want to leave the page ?",
"Jump": "Jump",
"Encountered an unknown error. Try to resubmit": "Encountered an unknown error. Try to resubmit",
"hide_button_text": "hide_button_text",
"Sort Editor": "Sort Editor",
"At least one (OR)": "At least one (OR)",
"Cancel": "Cancel",
"Create New": "Create New",
"Not Less Than": "Not Less Than",
"Description": "Description",
"Decisions": "Decisions",
"Export": "Export",
"Not Greater Than": "Not Greater Than",
"Previous": "Previous"
}
};
};
}(window));
\ No newline at end of file
......@@ -220,7 +220,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>romain</string> </value>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -234,7 +234,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>946.45868.14105.29764</string> </value>
<value> <string>962.22770.22235.8550</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -252,8 +252,8 @@
</tuple>
<state>
<tuple>
<float>1445935505.72</float>
<string>GMT</string>
<float>1516717586.21</float>
<string>UTC</string>
</tuple>
</state>
</object>
......
......@@ -665,58 +665,7 @@ if (typeof document.contains !== 'function') {
return this.documentElement.contains(node);
}
}
;(function (DOMParser) {
"use strict";
try {
if ((new window.URL("../a", "https://example.com/")).href === "https://example.com/a") {
return;
}
} catch (ignore) {}
var isAbsoluteOrDataURL = /^(?:[a-z]+:)?\/\/|data:/i;
function resolveUrl(url, base_url) {
var doc, base, link,
html = "<!doctype><html><head></head></html>";
if (url && base_url) {
doc = (new DOMParser()).parseFromString(html, 'text/html');
base = doc.createElement('base');
link = doc.createElement('link');
doc.head.appendChild(base);
doc.head.appendChild(link);
base.href = base_url;
link.href = url;
return link.href;
}
return url;
}
function URL(url, base) {
if (base !== undefined) {
if (!isAbsoluteOrDataURL.test(base)) {
throw new TypeError("Failed to construct 'URL': Invalid base URL");
}
url = resolveUrl(url, base);
}
if (!isAbsoluteOrDataURL.test(url)) {
throw new TypeError("Failed to construct 'URL': Invalid URL");
}
this.href = url;
}
URL.prototype.href = "";
if (window.URL && window.URL.createObjectURL) {
URL.createObjectURL = window.URL.createObjectURL;
}
if (window.URL && window.URL.revokeObjectURL) {
URL.revokeObjectURL = window.URL.revokeObjectURL;
}
window.URL = URL;
}(DOMParser));;/*! RenderJs */
;/*! RenderJs */
/*jslint nomen: true*/
/*
......@@ -860,7 +809,6 @@ if (typeof document.contains !== 'function') {
gadget_loading_klass_list = [],
renderJS,
Monitor,
Mutex,
scope_increment = 0,
isAbsoluteOrDataURL = new RegExp('^(?:[a-z]+:)?//|data:', 'i'),
is_page_unloaded = false,
......@@ -877,64 +825,6 @@ if (typeof document.contains !== 'function') {
is_page_unloaded = true;
});
/////////////////////////////////////////////////////////////////
// Mutex
/////////////////////////////////////////////////////////////////
Mutex = function createMutex() {
if (!(this instanceof Mutex)) {
return new Mutex();
}
this._latest_defer = null;
};
Mutex.prototype = {
constructor: Mutex,
lock: function lockMutex() {
var previous_defer = this._latest_defer,
current_defer = RSVP.defer(),
queue = new RSVP.Queue();
this._latest_defer = current_defer;
if (previous_defer !== null) {
queue.push(function acquireMutex() {
return previous_defer.promise;
});
}
// Create a new promise (.then) not cancellable
// to allow external cancellation of the callback
// without breaking the mutex implementation
queue
.fail(current_defer.resolve.bind(current_defer));
return queue
.push(function generateMutexUnlock() {
return function runAndUnlock(callback) {
return new RSVP.Queue()
.push(function executeMutexCallback() {
return callback();
})
.push(function releaseMutexAfterSuccess(result) {
current_defer.resolve(result);
return result;
}, function releaseMutexAfterError(error) {
current_defer.resolve(error);
throw error;
});
};
});
},
lockAndRun: function (callback) {
return this.lock()
.push(function executeLockAndRunCallback(runAndUnlock) {
return runAndUnlock(callback);
});
}
};
/////////////////////////////////////////////////////////////////
// Helper functions
/////////////////////////////////////////////////////////////////
......@@ -1361,26 +1251,15 @@ if (typeof document.contains !== 'function') {
/////////////////////////////////////////////////////////////////
// RenderJSGadget.declareMethod
/////////////////////////////////////////////////////////////////
RenderJSGadget.declareMethod = function declareMethod(name, callback,
options) {
RenderJSGadget.declareMethod = function declareMethod(name, callback) {
this.prototype[name] = function triggerMethod() {
var context = this,
argument_list = arguments,
mutex_name;
function waitForMethodCallback() {
return callback.apply(context, argument_list);
}
argument_list = arguments;
if ((options !== undefined) && (options.hasOwnProperty('mutex'))) {
mutex_name = '__mutex_' + options.mutex;
if (!context.hasOwnProperty(mutex_name)) {
context[mutex_name] = new Mutex();
}
return context[mutex_name].lockAndRun(waitForMethodCallback);
}
return new RSVP.Queue()
.push(waitForMethodCallback);
.push(function waitForMethodCallback() {
return callback.apply(context, argument_list);
});
};
// Allow chain
return this;
......@@ -1416,8 +1295,24 @@ if (typeof document.contains !== 'function') {
return this.element;
})
.declareMethod('changeState', function changeState(state_dict) {
var context = this,
key,
var next_onStateChange = new RSVP.Queue(),
previous_onStateCHange,
context = this;
if (context.hasOwnProperty('__previous_onStateChange')) {
previous_onStateCHange = context.__previous_onStateChange;
next_onStateChange
.push(function waitForPreviousStateChange() {
return previous_onStateCHange;
})
.push(undefined, function handlePreviousStateChangeError() {
// Run callback even if previous failed
return;
});
}
context.__previous_onStateChange = next_onStateChange;
return next_onStateChange
.push(function checkStateModification() {
var key,
modified = false,
previous_cancelled = context.hasOwnProperty('__modification_dict'),
modification_dict;
......@@ -1446,7 +1341,8 @@ if (typeof document.contains !== 'function') {
return result;
});
}
}, {mutex: 'changestate'});
});
});
/////////////////////////////////////////////////////////////////
// RenderJSGadget.declareAcquiredMethod
......@@ -2142,7 +2038,6 @@ if (typeof document.contains !== 'function') {
/////////////////////////////////////////////////////////////////
// global
/////////////////////////////////////////////////////////////////
renderJS.Mutex = Mutex;
window.rJS = window.renderJS = renderJS;
window.__RenderJSGadget = RenderJSGadget;
window.__RenderJSEmbeddedGadget = RenderJSEmbeddedGadget;
......
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.57262.9791.60330</string> </value>
<value> <string>962.24020.58652.57139</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1516196938.48</float>
<float>1508945098.52</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -309,6 +309,7 @@
<value>
<tuple>
<string>en</string>
<string>wo</string>
</tuple>
</value>
</item>
......
......@@ -655,14 +655,7 @@ div[data-gadget-scope='panel'] {
.linkpanel() {
color: @white;
display: block;
// Define .active before :hover to ensure it hover is displayed
// for the .active entry
&.active {
color: @colorforeground;
background-color: @colorbackground;
}
&:hover, &:active {
color: @white;
&:hover, &:active, &.active {
background-color: darken(@panelbackgroundcolor, 10%);
}
}
......@@ -1112,12 +1105,17 @@ div[data-gadget-scope='header'] .ui-header {
/**********************************************
* Gadget: main
**********************************************/
.renderPageSubmitButton(@backgroundcolor) {
.gadget-content {
div[data-gadget-scope='m'] {
animation: fadein @transition-timing;
}
input[type='submit'] {
padding: @margin-size;
margin-top: @headerheight;
margin-right: @double-margin-size;
background-color: @backgroundcolor;
background-color: @coloraccent;
color: @white;
border-radius: @radius;
......@@ -1127,26 +1125,13 @@ div[data-gadget-scope='header'] .ui-header {
min-width: 8em;
&:hover, &:focus {
background-color: lighten(@backgroundcolor, 10%);
background-color: lighten(@coloraccent, 10%);
}
&:active {
background-color: lighten(@backgroundcolor, 20%);
background-color: lighten(@coloraccent, 20%);
}
}
.gadget-content {
div[data-gadget-scope='m'] {
animation: fadein @transition-timing;
}
// Dialog page template main submit button
input[type='submit'] {
.renderPageSubmitButton(@coloraccent);
}
// Dialog page template update button
button[name='action_update'] {
.renderPageSubmitButton(@grey);
}
@media @desktop {
div[data-role='page']:not(.desktop-panel-hidden) & {
......@@ -1176,17 +1161,28 @@ div[data-gadget-scope='header'] .ui-header {
}
}
.horizontal_align_form_box .field_container > div {
.field_container > div > div.horizontal_align_form_box {
// Class .horizontal_align_form_box is here only for backward-compatibility!
// It is used to force horizontal rendering of fields inside FormBox.
// we need to overwrite the padding above this statement
& > .ui-field-contain {
// makes field to high
padding: 0;
/* Class .horizontal_align_form_box is here only for backward-compatibility!
It is used to force horizontal rendering of fields inside FormBox.
The first > div represents form-group ("left", "right" ...) */
& > label {
padding-top: @margin-size + @half-margin-size;
}
}
.field_container > div {
// matches form-group ("left", "right" ...)
display: flex;
& > div {
flex: 1;
}
}
}
.ui-content-header-plain {
font-size: 150%;
......@@ -1287,6 +1283,9 @@ div[data-gadget-scope='header'] .ui-header {
& > label {
color: @grey;
// padding to be aligned with <input>
padding: @half-margin-size;
// backward-compatibility: support for ERP5 field class defined in formulator configuration
&.required {
// inform user that the field is needed by contraint, but do not prevent him to save the value
......@@ -1299,6 +1298,11 @@ div[data-gadget-scope='header'] .ui-header {
}
}
.ui-field-contain p {
// non-editable fields are rendered using <p> so they deserve the same padding as <input>s
padding: @half-margin-size;
}
@media @tablet, @desktop {
.ui-field-contain {
display: flex;
......
<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>${base_url}/bar_module/ListBoxZuite_reset</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Reset Successfully.</td>
<td></td>
</tr>
<!-- Initialize -->
<tr>
<td>open</td>
<td>${base_url}/web_site_module/renderjs_runner/#/bar_module</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n='Add']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>link=Add</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_dialog" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/go_to_bar_datetime_field_view" />
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-scope='field_my_start_date']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//div[@data-gadget-scope='field_my_start_date']//input</td>
<td>2015-12-21T11:00</td>
</tr>
<tr>
<td>type</td>
<td>//div[@data-gadget-scope='field_my_stop_date']//input</td>
<td>2016-12-21T12:00</td>
</tr>
<tr>
<td>select</td>
<td>//div[@data-gadget-scope='field_my_stop_date']//select</td>
<td>GMT+5</td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/save" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/toggle_editable_mode" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tr>
<td>assertElementPresent</td>
<td>//div[@data-gadget-scope='field_my_start_date']//div[@data-gadget-scope='field']//p[contains(text(), '11:00:00')]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[@data-gadget-scope='field_my_start_date']//div[@data-gadget-scope='field']//p[@data-date='2015-12-21T11:00:00']</td>
<td></td>
</tr>
<tr>
<td>storeLocation</td>
<td>url</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Foo_viewDateTimeField/my_stop_date/manage_main</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name='field_timezone_style']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//input[@name='field_timezone_style']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//input[@value='Save Changes']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@class='system-msg']</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${url}</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-scope='field_my_stop_date']//div[@data-gadget-scope='field']//p[@data-date='2016-12-21T12:00:00']</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Foo_viewDateTimeField/my_stop_date/manage_main</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name='field_timezone_style']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//input[@name='field_timezone_style']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//input[@value='Save Changes']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@class='system-msg']</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
<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>${base_url}/bar_module/ListBoxZuite_reset</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Reset Successfully.</td>
<td></td>
</tr>
<!-- Initialize -->
<tr>
<td>open</td>
<td>${base_url}/Foo_viewDateTimeField/my_start_date/manage_main</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name='subfield_field_start_datetime_year']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='subfield_field_start_datetime_year']</td>
<td>2018</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='subfield_field_start_datetime_month']</td>
<td>11</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='subfield_field_start_datetime_day']</td>
<td>11</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='subfield_field_start_datetime_hour']</td>
<td>11</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='subfield_field_start_datetime_minute']</td>
<td>11</td>
</tr>
<tr>
<td>click</td>
<td>//input[@value='Save Changes']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@class='system-msg']</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/web_site_module/renderjs_runner/#/bar_module</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n='Add']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>link=Add</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_dialog" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/go_to_bar_datetime_field_view" />
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-scope='field_my_start_date']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//div[@data-gadget-scope='field_my_start_date']//input</td>
<td>2017-02-22T22:22</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//button[@data-i18n='Save']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//button[@data-i18n='Save']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//button[@class='error']</td>
<td></td>
</tr>
<!--XXXXXX wait render -->
<tr>
<td>pause</td>
<td>3000</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@value='2017-02-22T22:22:00']</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Foo_viewDateTimeField/my_start_date/manage_main</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name='subfield_field_start_datetime_year']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='subfield_field_start_datetime_year']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='subfield_field_start_datetime_month']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='subfield_field_start_datetime_day']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='subfield_field_start_datetime_hour']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='subfield_field_start_datetime_minute']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//input[@value='Save Changes']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@class='system-msg']</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
......@@ -25,7 +25,7 @@
<td>renderjs_url</td></tr>
<tr><td>open</td>
<td>${base_url}/foo_module/FooModule_createObjects?num:int=1</td><td></td></tr>
<td>${base_url}/foo_module/FooModule_createObjects?num:int=1&amp;create_line:int=1</td><td></td></tr>
<tr><td>assertTextPresent</td>
<td>Created Successfully.</td><td></td></tr>
<tr><td>open</td>
......
......@@ -42,7 +42,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testDisplayWithAndWithoutTimeZone</string> </value>
<value> <string>testFastSave</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
......
<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 ListBox Fast Save</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test fast saving without enough time to render listbox data</td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/PTZuite_CommonTemplate/macros/init" />
<!-- Clean Up -->
<tr><td>open</td>
<td>${base_url}/foo_module/ListBoxZuite_reset</td><td></td></tr>
<tr><td>assertTextPresent</td>
<td>Reset Successfully.</td><td></td></tr>
<!-- Create Foo objects with IDs 0-9 -->
<tr><td>open</td>
<td>${base_url}/foo_module/FooModule_createObjects?start:int=1&amp;num:int=3&amp;create_line:int=1</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" />
<!-- Shortcut for full renderjs url -->
<tr><td>store</td>
<td>${base_url}/web_site_module/renderjs_runner</td>
<td>renderjs_url</td></tr>
<tr><td>open</td>
<td>${renderjs_url}/#/foo_module/1?editable=1</td><td></td></tr>
<tr><td>waitForElementPresent</td>
<td>//input[@name="field_my_quantity"]</td><td></td></tr>
<tr><td>type</td>
<td>field_my_quantity</td>
<td>1.00</td></tr>
<tr><td>click</td>
<td>//div[@data-gadget-scope='header']//button[@data-i18n='Save']</td><td></td></tr>
<tr><td>waitForElementPresent</td>
<td>//button[text()="Input data has errors."]</td><td></td></tr>
<tr><td>waitForElementPresent</td>
<td>//div[@data-gadget-scope="field_my_quantity"]//span[text()='The number you input has too large precision.']</td><td></td></tr>
<tr><td>type</td>
<td>field_my_quantity</td>
<td>1000000000.0</td></tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/save" />
<tr><td>verifyValue</td>
<td>field_my_quantity</td>
<td>1000000000.0</td></tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
......@@ -37,7 +37,7 @@
<tr>
<td>open</td>
<td>${base_url}/foo_module/FooModule_viewFooList/listbox/ListBox_setPropertyList?field_columns=id%7CID%0Atitle%7CTitle%0Adelivery.quantity%7CQuantity&amp;field_sort=id+%7C+DESC</td>
<td>${base_url}/foo_module/FooModule_viewFooList/listbox/ListBox_setPropertyList?field_columns=id%7CID%0Atitle%7CTitle%0Adelivery.quantity%7CQuantity&amp;field_sort=id+%7C+ASC</td>
<td></td>
</tr>
......@@ -66,14 +66,14 @@
<!-- check quanlity is display correctly -->
<tr>
<td>waitForElementPresent</td>
<td>//a[@class='ui-link' and text() ='1']</td>
<td>//a[@class='ui-link']//p[text()='1']</td><!-- cell has field template thus rendered inside html5_element_gadget -->
<td></td>
</tr>
<tr>
<td>verifyElementPresent</td>
<td>//a[@class='ui-link' and text() ='1']</td>
<td>//a[@class='ui-link']//p[text()='1']</td>
<td></td>
</tr>
......
......@@ -42,7 +42,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testRelationDefaultSortAndParameterList</string> </value>
<value> <string>testListBoxBasics</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
......
<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal">
<!--
Ensure stat_method gets executed and result displayed in tfoot element of the listbox table.
- if anchor, then text "Total" is present
- columns for which stat_method does not return any data remain empty
-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test RenderJS UI ListBox Stat Method</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test RenderJS UI ListBox Stat Method</td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/init" />
<!-- Clean Up -->
<tr><td>open</td>
<td>${base_url}/foo_module/ListBoxZuite_reset</td><td></td></tr>
<tr><td>assertTextPresent</td>
<td>Reset Successfully.</td><td></td></tr>
<!-- Shortcut for full renderjs url -->
<tr><td>store</td>
<td>${base_url}/web_site_module/renderjs_runner</td>
<td>renderjs_url</td></tr>
<!-- Create Foo objects with IDs 0-9 -->
<tr><td>open</td>
<td>${base_url}/foo_module/FooModule_createObjects?start:int=1&amp;num:int=3</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" />
<!-- Let's set up the default sort correctly: id | ASC -->
<tr><td>open</td>
<td>${base_url}/FooModule_viewFooList/listbox/ListBox_setPropertyList?field_stat_method=FooModule_statMethod</td><td></td></tr>
<tr><td>assertTextPresent</td>
<td>Set Successfully.</td><td></td></tr>
<tr><td>open</td>
<td>${renderjs_url}/#/foo_module</td><td></td></tr>
<tr><td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//nav/span[@data-i18n="3 Records"]</td><td></td></tr>
<tr><td>store</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//table</td>
<td>listbox_table</td></tr>
<!-- Default sort on ID column has to be ASCENDING -->
<tr><td>assertFloat</td>
<td>${listbox_table}/tbody/tr[1]/td[3]/a</td>
<td>9</td></tr>
<tr><td>assertFloat</td>
<td>${listbox_table}/tbody/tr[2]/td[3]/a</td>
<td>8</td></tr>
<tr><td>assertFloat</td>
<td>${listbox_table}/tbody/tr[3]/td[3]/a</td>
<td>7</td></tr>
<tr><td>assertFloat</td><!-- This tests that "Total" does not appear when first column has stat defined -->
<td>${listbox_table}/tfoot/tr[1]/td[1]</td>
<td>6</td></tr>
<tr><td>assertFloat</td>
<td>${listbox_table}/tfoot/tr[1]/td[3]</td>
<td>24</td></tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
......@@ -42,7 +42,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testRestoreDateTimeValueIfValidationError</string> </value>
<value> <string>testSelectionColumnsPrecedence</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
......
<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal">
<!--
Ensure backward compatibility with Selections.
- only two columns must be present because Selection has precedence
-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test RenderJS UI ListBox Selection Column Precede Listbox's</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test RenderJS UI ListBox Selection Column Precede Listbox's</td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/init" />
<!-- Clean Up -->
<tr><td>open</td>
<td>${base_url}/foo_module/ListBoxZuite_reset</td><td></td></tr>
<tr><td>assertTextPresent</td>
<td>Reset Successfully.</td><td></td></tr>
<!-- Shortcut for full renderjs url -->
<tr><td>store</td>
<td>${base_url}/web_site_module/renderjs_runner</td>
<td>renderjs_url</td></tr>
<!-- Create Foo objects with IDs 0-9 -->
<tr><td>open</td>
<td>${base_url}/foo_module/FooModule_createObjects?start:int=1&amp;num:int=1</td><td></td></tr>
<tr><td>assertTextPresent</td>
<td>Created Successfully.</td><td></td></tr>
<!-- Let's set up the default sort correctly: id | ASC -->
<tr><td>open</td>
<td>${base_url}/FooModule_viewFooList/listbox/ListBox_setPropertyList?field_selection_name=foo_selection</td><td></td></tr>
<tr><td>assertTextPresent</td>
<td>Set Successfully.</td><td></td></tr>
<tr><td>open</td>
<td>${base_url}/FooModule_viewFooList/listbox/Selection_setPropertyList?columns=id+%7C+Selection+ID&amp;columns=title+%7C+Selection+Title</td><td></td></tr>
<tr><td>assertTextPresent</td>
<td>Set Successfully.</td><td></td></tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/wait_for_activities" />
<tr><td>open</td>
<td>${renderjs_url}/#/foo_module</td><td></td></tr>
<tr><td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//nav/span[@data-i18n="1 Records"]</td><td></td></tr>
<tr><td>store</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//table</td>
<td>listbox_table</td></tr>
<!-- Default sort on ID column has to be ASCENDING -->
<tr><td>assertText</td>
<td>${listbox_table}/thead/tr[1]/th[1]</td>
<td>Selection ID</td></tr>
<tr><td>assertText</td>
<td>${listbox_table}/thead/tr[1]/th[2]</td>
<td>Selection Title</td></tr>
<tr><td>assertElementNotPresent</td>
<td>${listbox_table}/thead/tr[1]/th[3]</td><td></td></tr>
<tr><td>assertText</td>
<td>${listbox_table}/tbody/tr[1]/td[1]/a</td>
<td>1</td></tr>
<tr><td>assertText</td>
<td>${listbox_table}/tbody/tr[1]/td[2]/a</td>
<td>Title 1</td></tr>
<tr><td>assertElementNotPresent</td>
<td>${listbox_table}/tbody/tr[1]/td[3]</td><td></td></tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
......@@ -42,7 +42,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testMultiRelationDefaultSortAndParameterList</string> </value>
<value> <string>testTemplateFieldBackwardCompatibility</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
......
<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 ListBox Fast Save</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test custom "default" value rendering inside editor field</td></tr>
</thead><tbody>
<tr><td>store</td>
<td>https://softinst81338.host.vifib.net/erp5</td>
<td>base_url</td></tr>
<tal:block metal:use-macro="here/PTZuite_CommonTemplate/macros/init" />
<tr><td>open</td>
<td>${base_url}/foo_module/ListBoxZuite_reset</td><td></td></tr>
<tr><td>assertTextPresent</td>
<td>Reset Successfully.</td><td></td></tr>
<tr><td>open</td>
<td>${base_url}/foo_module/FooModule_createObjects?start:int=1&amp;num:int=2&amp;create_line:int=0</td><td></td></tr>
<tr><td>assertTextPresent</td>
<td>Created Successfully.</td><td></td></tr>
<tr><td>open</td>
<td>${base_url}/foo_module/1/Foo_createObjects?start:int=5&amp;num:int=2&amp;portal_type=Foo</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" />
<tr><td>open</td>
<td>${base_url}/foo_module/1/5/Foo_setCausality?value=foo_module/1/6</td><td></td></tr>
<tr><td>assertTextPresent</td>
<td>Set Successfully.</td><td></td></tr>
<!-- Shortcut for full renderjs url -->
<tr><td>store</td>
<td>${base_url}/web_site_module/renderjs_runner</td>
<td>renderjs_url</td></tr>
<tr><td>open</td>
<td>${renderjs_url}/#/foo_module/1</td><td></td></tr>
<tr><td>waitForElementPresent</td>
<td>//a[@data-i18n="Views"]</td><td></td></tr>
<tr><td>click</td>
<td>//a[@data-i18n="Views"]</td><td></td></tr>
<tr><td>waitForElementPresent</td>
<td>//a[@data-i18n="Proxy Listbox"]</td><td></td></tr>
<tr><td>click</td>
<td>//a[@data-i18n="Proxy Listbox"]</td><td></td></tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_listbox_loaded" />
<!-- Proxy listbox does not have template field for causality -->
<!-- Foo 1 with causality set -->
<tr><td>waitForElementPresent</td>
<td>//div[@data-gadget-scope="field_proxy_listbox"]//table/tbody/tr[1]/td[2]//a</td><td></td></tr>
<tr><td>assertText</td>
<td>//div[@data-gadget-scope="field_proxy_listbox"]//table/tbody/tr[1]/td[2]//a</td>
<td>Title 6</td></tr>
<!-- Pure listbox does have template field for causality BUT does declare it in "editable columns" -->
<!-- Foo 2 without causality set -->
<tr><td>waitForElementPresent</td>
<td>//div[@data-gadget-scope="field_listbox"]//table/tbody/tr[1]/td[2]//div[@class="hello"]</td><td></td></tr>
<tr><td>assertText</td>
<td>//div[@data-gadget-scope="field_listbox"]//table/tbody/tr[1]/td[2]//div[@class="hello"]</td>
<td>Couscous</td></tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
......@@ -22,6 +22,16 @@
<td>Reset Successfully.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/FooViewDummyMultiListFieldDialog_setFieldPropertyList</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Set Successfully.</td>
<td></td>
</tr>
<!-- Initialize -->
<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>testIntegersMultiListField</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 MultiList</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test int:0 in items and as default</td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/init" />
<!-- Clean Up -->
<tr>
<td>open</td>
<td>${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>${base_url}/foo_module/Foo_createObjects?num:int=1&amp;start:int=1</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Created Successfully.</td>
<td></td>
</tr>
<tr><th colspan="3">Set MultiList's items to python:[("0", 0), ("1", 1)] and default=python:0</th></tr>
<tr>
<td>open</td>
<td>${base_url}/FooViewDummyMultiListFieldDialog_setFieldPropertyList?your_dummy__default_tales=python%3A0&amp;your_dummy__items_tales=python%3A%20%5B(%220%22%2C%200)%2C(%221%22%2C1)%5D</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Set Successfully.</td>
<td></td>
</tr>
<!-- Initialize -->
<tr>
<td>open</td>
<td>${base_url}/web_site_module/renderjs_runner/#/foo_module/1</td>
<td></td>
</tr>
<!-- Go to test form -->
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/go_to_foo_dummy_multilist_field_report_view" />
<tr><td cellspan="3">The option 1 must be selected</td></tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, "gadget_erp5_field_multilist.html")]/div[1]//option[@value="0" and @selected="selected"]</td>
<td></td>
</tr>
<!-- Run test form & check -->
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_dialog" />
<tr>
<td>waitForTextPresent</td>
<td>repr [0]</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
<?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>testPrintActions</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 Print Actions</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test Print Actions</td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/PTZuite_CommonTemplate/macros/init" />
<tr>
<td>open</td>
<td tal:content="string: ${here/portal_url}/portal_types/Foo/PortalType_addAction?id=test_action&name=Print Portal&category=object_print&action=string:%24{portal_url}/view">Create a dummy action that redirects to the portal</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td tal:content="string: ${here/portal_url}/portal_types/Foo/PortalType_addAction?id=test_action2&name=Print Portal 2&category=object_print&action=string:%24{portal_url}/view%3Fportal_status_message=This%20was%20second%20action">Create another dummy action that redirects to the portal</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td tal:content="string: ${here/portal_url}/foo_module/1/view">/erp5/foo_module/1/view</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>//button[@title='Print']</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//select[@name='select_dialog']</td>
<td></td>
</tr>
<tr>
<td>assertSelected</td>
<td>//select[@name='select_dialog']</td>
<td>Print Portal</td>
</tr>
<tr>
<td>selectAndWait</td>
<td>//select[@name='select_dialog']</td>
<td>label=Print Portal 2</td>
</tr>
<tr>
<td>assertSelected</td>
<td>//select[@name='select_dialog']</td>
<td>Print Portal 2</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>dialog_submit_button</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Welcome to ERP5</td>
<td></td>
</tr>
<tr>
<td>assertPortalStatusMessage</td>
<td>This was second action</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td tal:content="string: ${here/portal_url}/portal_types/Foo/PortalType_deleteAction?id=test_action"></td>
<td></td>
</tr>
<tr>
<td>open</td>
<td tal:content="string: ${here/portal_url}/portal_types/Foo/PortalType_deleteAction?id=test_action2"></td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Set Successfully.</td>
<td></td>
</tr>
</body>
</html>
<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>${base_url}/foo_module/ListBoxZuite_reset</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Reset Successfully.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Foo_viewRelationField/my_bar_category_title_list/manage_main</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//textarea[@name='field_sort']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//textarea[@name='field_sort']</td>
<td>id | DESC</td>
</tr>
<tr>
<td>click</td>
<td>//input[@value='Save Changes']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@class='system-msg']</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Foo_viewRelationField/my_bar_category_title_list/manage_talesForm</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name='field_parameter_list']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='field_parameter_list']</td>
<td>python: [('id', '<5 AND >2')]</td>
</tr>
<tr>
<td>click</td>
<td>//input[@value='Save Changes']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@class='system-msg']</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${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>${base_url}/web_site_module/renderjs_runner/#/foo_module</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n='Add']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>link=Add</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_dialog" />
<tr>
<td>waitForTextPresent</td>
<td>Save</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Quantity</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/go_to_foo_relation_field_view" />
<tr>
<td>waitForElementPresent</td>
<td>//input[@name='field_my_bar_category_title_list']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='field_my_bar_category_title_list']</td>
<td>%</td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name='field_my_bar_category_title_list']</td>
<td>input</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-scope='field_my_bar_category_title_list']//ul[@class='ui-listview ui-corner-all search_ul']//li</td>
<td></td>
</tr>
<!-- test sort -->
<tr>
<td>verifyAttribute</td>
<td>//div[@data-gadget-scope='field_my_bar_category_title_list']//ul[@class='ui-listview ui-corner-all search_ul']/li[1]@data-relative-url</td>
<td>foo_module/4</td>
</tr>
<tr>
<td>verifyAttribute</td>
<td>//div[@data-gadget-scope='field_my_bar_category_title_list']//ul[@class='ui-listview ui-corner-all search_ul']/li[2]@data-relative-url</td>
<td>foo_module/3</td>
</tr>
<!-- test parameter list -->
<tr>
<td>verifyElementNotPresent</td>
<td>//div[@data-gadget-scope='field_my_bar_category_title_list']//ul[@class='ui-listview ui-corner-all search_ul']//li[@data-relative-url='foo_module/5']</td>
<td></td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name="field_my_bar_category_title_list"]</td>
<td>blur</td>
</tr>
<tr>
<td>click</td>
<td>//li[@data-explore="true"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n="Previous"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-scope='field_listbox']//tbody/tr[1]</td>
<td></td>
</tr>
<!-- test sort -->
<tr>
<td>verifyElementPresent</td>
<td>//div[@data-gadget-scope='field_listbox']//tbody/tr[1]//a[contains(text(), '4')]</td>
<td></td>
</tr>
<tr>
<td>verifyElementPresent</td>
<td>//div[@data-gadget-scope='field_listbox']//tbody/tr[2]//a[contains(text(), '3')]</td>
<td></td>
</tr>
<tr>
<td>verifyElementNotPresent</td>
<td>//div[@data-gadget-scope='field_listbox']//a[contains(text(), '5')]</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Foo_viewRelationField/my_bar_category_title_list/manage_main</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//textarea[@name='field_sort']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//textarea[@name='field_sort']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//input[@value='Save Changes']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@class='system-msg']</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Foo_viewRelationField/my_bar_category_title_list/manage_talesForm</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name='field_parameter_list']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='field_parameter_list']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//input[@value='Save Changes']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@class='system-msg']</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
<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>${base_url}/foo_module/ListBoxZuite_reset</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Reset Successfully.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Foo_viewRelationField/my_successor_title/manage_main</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//textarea[@name='field_sort']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//textarea[@name='field_sort']</td>
<td>id | DESC</td>
</tr>
<tr>
<td>click</td>
<td>//input[@value='Save Changes']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@class='system-msg']</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Foo_viewRelationField/my_successor_title/manage_talesForm</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name='field_parameter_list']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='field_parameter_list']</td>
<td>python: [('id', '<5 AND >2')]</td>
</tr>
<tr>
<td>click</td>
<td>//input[@value='Save Changes']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@class='system-msg']</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${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>${base_url}/web_site_module/renderjs_runner/#/foo_module</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n='Add']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>link=Add</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_dialog" />
<tr>
<td>waitForTextPresent</td>
<td>Save</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Quantity</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/go_to_foo_relation_field_view" />
<tr>
<td>waitForElementPresent</td>
<td>//input[@name='field_my_successor_title']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='field_my_successor_title']</td>
<td>%</td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name='field_my_successor_title']</td>
<td>input</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-scope='field_my_successor_title']//ul[@class='ui-listview ui-corner-all search_ul']//li</td>
<td></td>
</tr>
<!-- test sort -->
<tr>
<td>verifyAttribute</td>
<td>//div[@data-gadget-scope='field_my_successor_title']//ul[@class='ui-listview ui-corner-all search_ul']/li[1]@data-relative-url</td>
<td>foo_module/4</td>
</tr>
<tr>
<td>verifyAttribute</td>
<td>//div[@data-gadget-scope='field_my_successor_title']//ul[@class='ui-listview ui-corner-all search_ul']/li[2]@data-relative-url</td>
<td>foo_module/3</td>
</tr>
<!-- test parameter list -->
<tr>
<td>verifyElementNotPresent</td>
<td>//div[@data-gadget-scope='field_my_successor_title']//ul[@class='ui-listview ui-corner-all search_ul']//li[@data-relative-url='foo_module/5']</td>
<td></td>
</tr>
<tr>
<td>fireEvent</td>
<td>//input[@name="field_my_successor_title"]</td>
<td>blur</td>
</tr>
<tr>
<td>click</td>
<td>//li[@data-explore="true"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n="Previous"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-scope='field_listbox']//tbody/tr[1]</td>
<td></td>
</tr>
<!-- test sort -->
<tr>
<td>verifyElementPresent</td>
<td>//div[@data-gadget-scope='field_listbox']//tbody/tr[1]//a[contains(text(), '4')]</td>
<td></td>
</tr>
<tr>
<td>verifyElementPresent</td>
<td>//div[@data-gadget-scope='field_listbox']//tbody/tr[2]//a[contains(text(), '3')]</td>
<td></td>
</tr>
<tr>
<td>verifyElementNotPresent</td>
<td>//div[@data-gadget-scope='field_listbox']//a[contains(text(), '5')]</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Foo_viewRelationField/my_successor_title/manage_main</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//textarea[@name='field_sort']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//textarea[@name='field_sort']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//input[@value='Save Changes']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@class='system-msg']</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Foo_viewRelationField/my_successor_title/manage_talesForm</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//input[@name='field_parameter_list']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name='field_parameter_list']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//input[@value='Save Changes']</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@class='system-msg']</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
......@@ -153,30 +153,6 @@
</tr>
</tal:block>
<tal:block metal:define-macro="update_dialog">
<tr>
<td colspan="3"><b>Update the dialog</b></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_pt_form_dialog.html')]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_pt_form_dialog.html')]//button[@name='action_update' and @type='submit']</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_pt_form_dialog.html')]//button[@name='action_update' and @type='submit']</td>
<td></td>
</tr>
<tr>
<td colspan="3"><p></p></td>
</tr>
</tal:block>
<tal:block metal:define-macro="search_in_form_list">
<tr>
<td colspan="3"><b tal:content="python: 'Submit a form list search: %s' % search_query"></b></td>
......@@ -866,23 +842,4 @@
</tr>
</tal:block>
<tal:block metal:define-macro="wait_for_notification">
<tr>
<td colspan="3"><b>Wait for the notification message</b></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td tal:content="python: '//div[@data-gadget-scope=\'notification\']//button[@class=\'%(class)s\' and text()=\'%(text)s\']' % notification_configuration"></td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td tal:content="python: '//div[@data-gadget-scope=\'notification\']//button[@class=\'%(class)s\' and text()=\'%(text)s\']' % notification_configuration"></td>
<td></td>
</tr>
<tr>
<td colspan="3"><p></p></td>
</tr>
</tal:block>
</tal:block>
\ No newline at end of file
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