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

ce est ca

parent 444fadf1
...@@ -16,13 +16,13 @@ ...@@ -16,13 +16,13 @@
<key> <string>categories</string> </key> <key> <string>categories</string> </key>
<value> <value>
<tuple> <tuple>
<string>action_type/object_action</string> <string>action_type/object_jio_action</string>
</tuple> </tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>category</string> </key> <key> <string>category</string> </key>
<value> <string>object_action</string> </value> <value> <string>object_jio_action</string> </value>
</item> </item>
<item> <item>
<key> <string>condition</string> </key> <key> <string>condition</string> </key>
......
...@@ -16,13 +16,13 @@ ...@@ -16,13 +16,13 @@
<key> <string>categories</string> </key> <key> <string>categories</string> </key>
<value> <value>
<tuple> <tuple>
<string>action_type/object_action</string> <string>action_type/object_jio_action</string>
</tuple> </tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>category</string> </key> <key> <string>category</string> </key>
<value> <string>object_action</string> </value> <value> <string>object_jio_action</string> </value>
</item> </item>
<item> <item>
<key> <string>condition</string> </key> <key> <string>condition</string> </key>
......
...@@ -29,6 +29,15 @@ ...@@ -29,6 +29,15 @@
<key> <string>acquire_local_roles</string> </key> <key> <string>acquire_local_roles</string> </key>
<value> <int>0</int> </value> <value> <int>0</int> </value>
</item> </item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>ledger/accounting/general</string>
<string>ledger/accounting/detailed</string>
</tuple>
</value>
</item>
<item> <item>
<key> <string>content_icon</string> </key> <key> <string>content_icon</string> </key>
<value> <string>organisation_icon.gif</string> </value> <value> <string>organisation_icon.gif</string> </value>
......
...@@ -29,6 +29,12 @@ ...@@ -29,6 +29,12 @@
<key> <string>acquire_local_roles</string> </key> <key> <string>acquire_local_roles</string> </key>
<value> <int>0</int> </value> <value> <int>0</int> </value>
</item> </item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple/>
</value>
</item>
<item> <item>
<key> <string>content_icon</string> </key> <key> <string>content_icon</string> </key>
<value> <string>transaction_icon.gif</string> </value> <value> <string>transaction_icon.gif</string> </value>
......
...@@ -29,6 +29,12 @@ ...@@ -29,6 +29,12 @@
<key> <string>acquire_local_roles</string> </key> <key> <string>acquire_local_roles</string> </key>
<value> <int>0</int> </value> <value> <int>0</int> </value>
</item> </item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple/>
</value>
</item>
<item> <item>
<key> <string>content_icon</string> </key> <key> <string>content_icon</string> </key>
<value> <string>organisation_icon.gif</string> </value> <value> <string>organisation_icon.gif</string> </value>
......
...@@ -29,6 +29,12 @@ ...@@ -29,6 +29,12 @@
<key> <string>acquire_local_roles</string> </key> <key> <string>acquire_local_roles</string> </key>
<value> <int>0</int> </value> <value> <int>0</int> </value>
</item> </item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple/>
</value>
</item>
<item> <item>
<key> <string>content_icon</string> </key> <key> <string>content_icon</string> </key>
<value> <string>organisation_icon.gif</string> </value> <value> <string>organisation_icon.gif</string> </value>
......
...@@ -29,6 +29,12 @@ ...@@ -29,6 +29,12 @@
<key> <string>acquire_local_roles</string> </key> <key> <string>acquire_local_roles</string> </key>
<value> <int>0</int> </value> <value> <int>0</int> </value>
</item> </item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple/>
</value>
</item>
<item> <item>
<key> <string>content_icon</string> </key> <key> <string>content_icon</string> </key>
<value> <string>organisation_icon.gif</string> </value> <value> <string>organisation_icon.gif</string> </value>
......
...@@ -29,6 +29,12 @@ ...@@ -29,6 +29,12 @@
<key> <string>acquire_local_roles</string> </key> <key> <string>acquire_local_roles</string> </key>
<value> <int>0</int> </value> <value> <int>0</int> </value>
</item> </item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple/>
</value>
</item>
<item> <item>
<key> <string>content_icon</string> </key> <key> <string>content_icon</string> </key>
<value> <string>organisation_icon.gif</string> </value> <value> <string>organisation_icon.gif</string> </value>
......
...@@ -69,10 +69,6 @@ ...@@ -69,10 +69,6 @@
<key> <string>values</string> </key> <key> <string>values</string> </key>
<value> <value>
<dictionary> <dictionary>
<item>
<key> <string>description</string> </key>
<value> <string>Printing format</string> </value>
</item>
<item> <item>
<key> <string>field_id</string> </key> <key> <string>field_id</string> </key>
<value> <string>your_format</string> </value> <value> <string>your_format</string> </value>
...@@ -85,10 +81,6 @@ ...@@ -85,10 +81,6 @@
<key> <string>target</string> </key> <key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value> <value> <string>Click to edit the target</string> </value>
</item> </item>
<item>
<key> <string>title</string> </key>
<value> <string>Format</string> </value>
</item>
</dictionary> </dictionary>
</value> </value>
</item> </item>
......
"""Total balance of all accounting transactions having this """Total balance of all accounting transactions having this
account as node account as node
""" """
kw['node_uid'] = context.getUid() kw.update(
node_uid=context.getUid(),
selection_name=selection_name
)
return context.Node_statAccountingBalance(**kw) return context.Node_statAccountingBalance(**kw)
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>**kw</string> </value> <value> <string>selection_name=None, **kw</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
"""Total credit of all accounting transactions having this """Total credit of all accounting transactions having this
account as node account as a node
""" """
kw['node_uid'] = context.getUid() kw.update(
kw['omit_asset_increase'] = 1 node_uid = context.getUid(),
kw.update(kw['selection'].getParams()) 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" # here, or 0 is to prevent displaying "- 0"
return - context.Node_statAccountingBalance(**kw) or 0 return - context.Node_statAccountingBalance(**kw) or 0
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>**kw</string> </value> <value> <string>selection_name=None, **kw</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
"""Total debit of all accounting transactions having this """Total debit of all accounting transactions having this
account as a node account as a node
""" """
kw['node_uid'] = context.getUid()
kw['omit_asset_decrease'] = 1 kw.update(
kw.update(kw['selection'].getParams()) 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) return context.Node_statAccountingBalance(**kw)
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>**kw</string> </value> <value> <string>selection_name=None, **kw</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>name</string> </key> <key> <string>name</string> </key>
<value> <string>uid</string> </value> <value> <string>relative_url</string> </value>
</item> </item>
<item> <item>
<key> <string>null</string> </key> <key> <string>null</string> </key>
...@@ -29,11 +29,11 @@ ...@@ -29,11 +29,11 @@
</item> </item>
<item> <item>
<key> <string>type</string> </key> <key> <string>type</string> </key>
<value> <string>i</string> </value> <value> <string>t</string> </value>
</item> </item>
<item> <item>
<key> <string>width</string> </key> <key> <string>width</string> </key>
<value> <int>11</int> </value> <value> <int>0</int> </value>
</item> </item>
</dictionary> </dictionary>
<dictionary> <dictionary>
...@@ -51,7 +51,61 @@ ...@@ -51,7 +51,61 @@
</item> </item>
<item> <item>
<key> <string>width</string> </key> <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> </item>
</dictionary> </dictionary>
</list> </list>
......
...@@ -35,8 +35,9 @@ for obj in object_list: ...@@ -35,8 +35,9 @@ for obj in object_list:
if not activated: if not activated:
return context.Base_redirect(form_id, return context.Base_redirect(form_id,
keep_items=dict(portal_status_message= keep_items={
translateString('No valid transaction in your selection.'))) "portal_status_message": translateString(
'No valid transaction in your selection.')})
# activate something on the folder # activate something on the folder
context.activate(after_tag=tag).getTitle() context.activate(after_tag=tag).getTitle()
......
...@@ -154,6 +154,10 @@ ...@@ -154,6 +154,10 @@
<key> <string>hidden</string> </key> <key> <string>hidden</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>input_type</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>max_length</string> </key> <key> <string>max_length</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
......
...@@ -4,4 +4,6 @@ bank account as payment node ...@@ -4,4 +4,6 @@ bank account as payment node
kw['payment_uid'] = context.getUid() kw['payment_uid'] = context.getUid()
kw['asset_price'] = False kw['asset_price'] = False
kw['node_category'] = 'account_type/asset/cash/bank' kw['node_category'] = 'account_type/asset/cash/bank'
kw['selection_name'] = selection_name
return context.Node_statAccountingBalance(**kw) return context.Node_statAccountingBalance(**kw)
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>**kw</string> </value> <value> <string>selection_name=None, **kw</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -5,7 +5,14 @@ kw['payment_uid'] = context.getUid() ...@@ -5,7 +5,14 @@ kw['payment_uid'] = context.getUid()
kw['omit_asset_increase'] = 1 kw['omit_asset_increase'] = 1
kw['asset_price'] = False kw['asset_price'] = False
kw['node_category'] = 'account_type/asset/cash/bank' 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" # here, or 0 is to prevent displaying "- 0"
return - context.Node_statAccountingBalance(**kw) or 0 return - context.Node_statAccountingBalance(**kw) or 0
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>**kw</string> </value> <value> <string>selection_name=None, **kw</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -5,6 +5,13 @@ kw['payment_uid'] = context.getUid() ...@@ -5,6 +5,13 @@ kw['payment_uid'] = context.getUid()
kw['omit_asset_decrease'] = 1 kw['omit_asset_decrease'] = 1
kw['asset_price'] = False kw['asset_price'] = False
kw['node_category'] = 'account_type/asset/cash/bank' 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) return context.Node_statAccountingBalance(**kw)
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>**kw</string> </value> <value> <string>selection_name=None, **kw</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
"""Returns Accounting Transactions where this entity is mirror section. """Returns Accounting Transactions where this entity is mirror section.
""" """
kw['mirror_section_uid'] = context.getUid() kw.update(
kw['node_category_strict_membership'] = ['account_type/asset/receivable', # following two lines are the reason for this whole script to exist
'account_type/liability/payable'] 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) return context.Node_getAccountingTransactionList(**kw)
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>**kw</string> </value> <value> <string>selection_name=\'\', sort_on=(), **kw</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -6,7 +6,8 @@ kw['mirror_section_uid'] = context.getUid() ...@@ -6,7 +6,8 @@ kw['mirror_section_uid'] = context.getUid()
kw['omit_asset_increase'] = 1 kw['omit_asset_increase'] = 1
kw['node_category_strict_membership'] = ['account_type/asset/receivable', kw['node_category_strict_membership'] = ['account_type/asset/receivable',
'account_type/liability/payable'] '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" # here, or 0 is to prevent displaying "- 0"
return - context.Node_statAccountingBalance(**kw) or 0 return - context.Node_statAccountingBalance(**kw) or 0
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>**kw</string> </value> <value> <string>selection_name, **kw</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -5,6 +5,8 @@ kw['mirror_section_uid'] = context.getUid() ...@@ -5,6 +5,8 @@ kw['mirror_section_uid'] = context.getUid()
kw['omit_asset_decrease'] = 1 kw['omit_asset_decrease'] = 1
kw['node_category_strict_membership'] = ['account_type/asset/receivable', kw['node_category_strict_membership'] = ['account_type/asset/receivable',
'account_type/liability/payable'] '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) return context.Node_statAccountingBalance(**kw)
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>**kw</string> </value> <value> <string>selection_name, **kw</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -143,87 +143,18 @@ ...@@ -143,87 +143,18 @@
</dictionary> </dictionary>
</value> </value>
</item> </item>
<item>
<key> <string>_count</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>_identity_criterion</string> </key> <key> <string>_identity_criterion</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</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>
</value> </value>
</item> </item>
<item> <item>
<key> <string>_range_criterion</string> </key> <key> <string>_range_criterion</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAY=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>_tree</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAc=</string> </persistent>
</value> </value>
</item> </item>
<item>
<key> <string>authorization_forced</string> </key>
<value> <int>1</int> </value>
</item>
<item> <item>
<key> <string>available_language</string> </key> <key> <string>available_language</string> </key>
<value> <value>
...@@ -232,28 +163,6 @@ ...@@ -232,28 +163,6 @@
</tuple> </tuple>
</value> </value>
</item> </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> <item>
<key> <string>container_layout</string> </key> <key> <string>container_layout</string> </key>
<value> <string>ERP5Document_getHateoas</string> </value> <value> <string>ERP5Document_getHateoas</string> </value>
...@@ -278,7 +187,7 @@ ...@@ -278,7 +187,7 @@
</item> </item>
<item> <item>
<key> <string>layout_configuration_form_id</string> </key> <key> <string>layout_configuration_form_id</string> </key>
<value> <string>WebSection_viewHateoasPreference</string> </value> <value> <string>WebSection_viewDefaultThemeConfiguration</string> </value>
</item> </item>
<item> <item>
<key> <string>portal_type</string> </key> <key> <string>portal_type</string> </key>
...@@ -292,7 +201,7 @@ ...@@ -292,7 +201,7 @@
</item> </item>
<item> <item>
<key> <string>skin_selection_name</string> </key> <key> <string>skin_selection_name</string> </key>
<value> <string>HalRestricted</string> </value> <value> <string>Hal</string> </value>
</item> </item>
<item> <item>
<key> <string>static_language_selection</string> </key> <key> <string>static_language_selection</string> </key>
...@@ -309,7 +218,7 @@ ...@@ -309,7 +218,7 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAg=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -324,12 +233,6 @@ ...@@ -324,12 +233,6 @@
</pickle> </pickle>
</record> </record>
<record id="3" aka="AAAAAAAAAAM="> <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> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -344,15 +247,7 @@ ...@@ -344,15 +247,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="5" aka="AAAAAAAAAAU="> <record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="6" aka="AAAAAAAAAAY=">
<pickle> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -367,15 +262,7 @@ ...@@ -367,15 +262,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="7" aka="AAAAAAAAAAc="> <record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="8" aka="AAAAAAAAAAg=">
<pickle> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -388,13 +275,13 @@ ...@@ -388,13 +275,13 @@
<item> <item>
<key> <string>category_publication_workflow</string> </key> <key> <string>category_publication_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAk=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAY=</string> </persistent>
</value> </value>
</item> </item>
<item> <item>
<key> <string>edit_workflow</string> </key> <key> <string>edit_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAo=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAc=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -403,7 +290,7 @@ ...@@ -403,7 +290,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="9" aka="AAAAAAAAAAk="> <record id="6" aka="AAAAAAAAAAY=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle> </pickle>
...@@ -456,7 +343,7 @@ ...@@ -456,7 +343,7 @@
</tuple> </tuple>
</pickle> </pickle>
</record> </record>
<record id="10" aka="AAAAAAAAAAo="> <record id="7" aka="AAAAAAAAAAc=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle> </pickle>
...@@ -485,7 +372,7 @@ ...@@ -485,7 +372,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.45855.48292.47786</string> </value> <value> <string>932.120.18159.59989</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -503,8 +390,8 @@ ...@@ -503,8 +390,8 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1515504053.68</float> <float>1389263689.67</float>
<string>UTC</string> <string>GMT+1</string>
</tuple> </tuple>
</state> </state>
</object> </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( ...@@ -23,5 +23,6 @@ return context.ERP5Document_getHateoas(
bulk_list=bulk_list, bulk_list=bulk_list,
sort_on=sort_on, sort_on=sort_on,
local_roles=local_roles, local_roles=local_roles,
restricted=1 restricted=1,
prev_view=prev_view
) )
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <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>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -270,7 +270,6 @@ if True: ...@@ -270,7 +270,6 @@ if True:
# does not exist and we call form method directly # does not exist and we call form method directly
if clean_kw.get("portal_skin", context.getPortalObject().portal_skins.getDefaultSkin()) not in ("Hal", "HalRestricted"): if clean_kw.get("portal_skin", context.getPortalObject().portal_skins.getDefaultSkin()) not in ("Hal", "HalRestricted"):
return dialog_form(**kw) return dialog_form(**kw)
return context.ERP5Document_getHateoas(REQUEST=request, form=dialog_form, mode="form") return context.ERP5Document_getHateoas(REQUEST=request, form=dialog_form, mode="form")
return getattr(context, dialog_method)(**kw) return getattr(context, dialog_method)(**kw)
...@@ -38,7 +38,7 @@ if not silent_mode and not request.AUTHENTICATED_USER.has_permission('Modify por ...@@ -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') return context.ERP5Document_getHateoas(form=form, REQUEST=request, mode='form')
try: 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) form.validate_all_to_request(request, key_prefix=key_prefix)
except FormValidationError as validation_errors: except FormValidationError as validation_errors:
# Pack errors into the request # Pack errors into the request
...@@ -91,7 +91,10 @@ def editListBox(listbox_field, listbox): ...@@ -91,7 +91,10 @@ def editListBox(listbox_field, listbox):
def editMatrixBox(matrixbox_field, matrixbox): 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: if matrixbox is None:
return return
...@@ -146,7 +149,7 @@ def editMatrixBox(matrixbox_field, matrixbox): ...@@ -146,7 +149,7 @@ def editMatrixBox(matrixbox_field, matrixbox):
tab_ids = map(lambda x: x[0], tabs) 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] 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 1: we do 1 dimensional matrix
# Case 2: we do 2 dimensional matrix # Case 2: we do 2 dimensional matrix
# Case 3: we do 2 dimensional matrix + tabs # Case 3: we do 2 dimensional matrix + tabs
...@@ -170,7 +173,7 @@ def editMatrixBox(matrixbox_field, matrixbox): ...@@ -170,7 +173,7 @@ def editMatrixBox(matrixbox_field, matrixbox):
matrix_context.setCellRange(base_id=cell_base_id, *matrixbox_cell_range) matrix_context.setCellRange(base_id=cell_base_id, *matrixbox_cell_range)
for cell_index_tuple, cell_value_dict in matrixbox.items(): 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): if not matrix_context.hasInRange(*cell_index_tuple, **kd):
return "Cell %s does not exist" % str(cell_index_tuple) return "Cell %s does not exist" % str(cell_index_tuple)
...@@ -204,7 +207,7 @@ MARKER = [] # placeholder for an empty value ...@@ -204,7 +207,7 @@ MARKER = [] # placeholder for an empty value
message = Base_translateString("Data updated.") message = Base_translateString("Data updated.")
try: 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(): 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 # 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) 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: ...@@ -217,13 +220,14 @@ try:
edit_kwargs[field_name[len(field_prefix):]] = field_value if field_value != '' else None 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. ## 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 field_meta_type = field.meta_type
if field_meta_type == 'ProxyField': if field_meta_type == 'ProxyField':
field_meta_type = field.getRecursiveTemplateField().meta_type field_meta_type = field.getRecursiveTemplateField().meta_type
if(field_meta_type == 'ListBox'): if(field_meta_type == 'ListBox'):
editListBox(field, request.get(field.id)) editListBox(field, request.get(field.id))
if(field_meta_type == 'MatrixBox'): elif(field_meta_type == 'MatrixBox'):
editMatrixBox(field, request.get(field.id)) editMatrixBox(field, request.get(field.id))
# Return parsed values # Return parsed values
...@@ -235,6 +239,7 @@ try: ...@@ -235,6 +239,7 @@ try:
context.edit(REQUEST=request, edit_order=edit_order, **edit_kwargs) context.edit(REQUEST=request, edit_order=edit_order, **edit_kwargs)
for encapsulated_editor in encapsulated_editor_list: for encapsulated_editor in encapsulated_editor_list:
encapsulated_editor.edit(context) encapsulated_editor.edit(context)
except ActivityPendingError as e: except ActivityPendingError as e:
message = Base_translateString(str(e)) message = Base_translateString(str(e))
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
from ZTUtils import make_query from ZTUtils import make_query
import json import json
portal_status_message = "%s" % keep_items.pop("portal_status_message", "")
request_form = context.REQUEST.form request_form = context.REQUEST.form
request_form.update(kw) request_form.update(kw)
request_form = context.ERP5Site_filterParameterList(request_form) request_form = context.ERP5Site_filterParameterList(request_form)
...@@ -40,12 +42,12 @@ response.setHeader("X-Location", "urn:jio:get:%s" % context.getRelativeUrl()) ...@@ -40,12 +42,12 @@ response.setHeader("X-Location", "urn:jio:get:%s" % context.getRelativeUrl())
# therefor we don't need to be afraid of clashes # therefor we don't need to be afraid of clashes
response.setHeader("Content-type", "application/json; charset=utf-8") response.setHeader("Content-type", "application/json; charset=utf-8")
result_dict = { result_dict = {
'portal_status_message': "%s" % keep_items.pop("portal_status_message", ""), 'portal_status_message': portal_status_message,
'_links': { '_links': {
"self": { "self": {
# XXX Include query parameters "href": "{}?{}".format(context.Base_getRequestUrl(), parameters)
"href": context.Base_getRequestUrl()
} }
} }
} }
......
# 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 @@ ...@@ -62,9 +62,6 @@
<value> <value>
<list> <list>
<string>left</string> <string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
</list> </list>
</value> </value>
</item> </item>
...@@ -73,13 +70,7 @@ ...@@ -73,13 +70,7 @@
<value> <value>
<dictionary> <dictionary>
<item> <item>
<key> <string>bottom</string> </key> <key> <string>left</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value> <value>
<list> <list>
<string>your_warning</string> <string>your_warning</string>
...@@ -88,18 +79,6 @@ ...@@ -88,18 +79,6 @@
</list> </list>
</value> </value>
</item> </item>
<item>
<key> <string>left</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary> </dictionary>
</value> </value>
</item> </item>
......
...@@ -205,11 +205,11 @@ ...@@ -205,11 +205,11 @@
</item> </item>
<item> <item>
<key> <string>css_class</string> </key> <key> <string>css_class</string> </key>
<value> <string>invisible</string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>default</string> </key> <key> <string>default</string> </key>
<value> <string>Do you want to clone this document?</string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
...@@ -257,7 +257,7 @@ ...@@ -257,7 +257,7 @@
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Confirmation message</string> </value> <value> <string>Do you want to clone this document:</string> </value>
</item> </item>
<item> <item>
<key> <string>unicode</string> </key> <key> <string>unicode</string> </key>
......
...@@ -62,9 +62,6 @@ ...@@ -62,9 +62,6 @@
<value> <value>
<list> <list>
<string>left</string> <string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
</list> </list>
</value> </value>
</item> </item>
...@@ -73,13 +70,7 @@ ...@@ -73,13 +70,7 @@
<value> <value>
<dictionary> <dictionary>
<item> <item>
<key> <string>bottom</string> </key> <key> <string>left</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value> <value>
<list> <list>
<string>your_warning</string> <string>your_warning</string>
...@@ -89,18 +80,6 @@ ...@@ -89,18 +80,6 @@
</list> </list>
</value> </value>
</item> </item>
<item>
<key> <string>left</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary> </dictionary>
</value> </value>
</item> </item>
......
...@@ -205,11 +205,11 @@ ...@@ -205,11 +205,11 @@
</item> </item>
<item> <item>
<key> <string>css_class</string> </key> <key> <string>css_class</string> </key>
<value> <string>invisible</string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>default</string> </key> <key> <string>default</string> </key>
<value> <string>Do you want to delete this document?</string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
...@@ -257,7 +257,7 @@ ...@@ -257,7 +257,7 @@
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Confirmation message</string> </value> <value> <string>Do you want to Delete this document:</string> </value>
</item> </item>
<item> <item>
<key> <string>unicode</string> </key> <key> <string>unicode</string> </key>
......
...@@ -20,6 +20,7 @@ Only in mode == 'form' ...@@ -20,6 +20,7 @@ Only in mode == 'form'
:param form: :param form:
Only in mode == 'traverse' Only in mode == 'traverse'
Traverse renders arbitrary View. It can be a Form or a Script.
# Form # Form
...@@ -39,9 +40,11 @@ from email.Utils import formatdate ...@@ -39,9 +40,11 @@ from email.Utils import formatdate
import re import re
from zExceptions import Unauthorized from zExceptions import Unauthorized
from Products.ERP5Type.Utils import UpperCase from Products.ERP5Type.Utils import UpperCase
from Products.ERP5Type.Message import Message
from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery
from Products.ERP5Type.Log import log from Products.ERP5Type.Log import log
from collections import OrderedDict from collections import OrderedDict
from urlparse import urlparse
MARKER = [] MARKER = []
...@@ -51,6 +54,10 @@ if REQUEST is None: ...@@ -51,6 +54,10 @@ if REQUEST is None:
if response is None: if response is None:
response = REQUEST.RESPONSE 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): def toBasicTypes(obj):
"""Ensure that obj contains only basic types.""" """Ensure that obj contains only basic types."""
...@@ -58,14 +65,39 @@ def toBasicTypes(obj): ...@@ -58,14 +65,39 @@ def toBasicTypes(obj):
return obj return obj
if isinstance(obj, (bool, int, float, long, str, unicode)): if isinstance(obj, (bool, int, float, long, str, unicode)):
return obj return obj
if isinstance(obj, (tuple, list)): if isinstance(obj, list):
return [toBasicTypes(x) for x in obj] 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: try:
return {toBasicTypes(key): toBasicTypes(obj[key]) for key in obj} return {toBasicTypes(key): toBasicTypes(obj[key]) for key in obj}
except: except:
log('Cannot convert {!s} to basic types {!s}'.format(type(obj), obj), level=100) log('Cannot convert {!s} to basic types {!s}'.format(type(obj), obj), level=100)
return obj 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 # http://stackoverflow.com/a/13105359
def byteify(string): def byteify(string):
...@@ -375,7 +407,7 @@ def getFieldDefault(form, field, key, value=None): ...@@ -375,7 +407,7 @@ def getFieldDefault(form, field, key, value=None):
value = (REQUEST.form.get(field.id, REQUEST.form.get(key, None)) or value = (REQUEST.form.get(field.id, REQUEST.form.get(key, None)) or
field.get_value('default', request=REQUEST, REQUEST=REQUEST)) field.get_value('default', request=REQUEST, REQUEST=REQUEST))
if field.has_value("unicode") and field.get_value("unicode") and isinstance(value, 'unicode'): 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: if getattr(value, 'translate', None) is not None:
return "%s" % value return "%s" % value
return value return value
...@@ -383,7 +415,6 @@ def getFieldDefault(form, field, key, value=None): ...@@ -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): 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.""" """Extract important field's attributes into `result` dictionary."""
if selection_params is None: if selection_params is None:
selection_params = {} selection_params = {}
...@@ -421,8 +452,9 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key ...@@ -421,8 +452,9 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
if meta_type in ("ListField", "RadioField", "ParallelListField", "MultiListField"): if meta_type in ("ListField", "RadioField", "ParallelListField", "MultiListField"):
result.update({ result.update({
# XXX Message can not be converted to json as is # 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": if meta_type == "ListField":
result.update({ result.update({
"first_item": field.get_value("first_item"), "first_item": field.get_value("first_item"),
...@@ -492,7 +524,6 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key ...@@ -492,7 +524,6 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
portal_type_list = field.get_value('portal_type') portal_type_list = field.get_value('portal_type')
translated_portal_type = [] translated_portal_type = []
jump_reference_list = [] jump_reference_list = []
relation_sort = field.get_value('sort')
if portal_type_list: if portal_type_list:
portal_type_list = [x[0] for x in 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] 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 ...@@ -514,10 +545,10 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
result.update({ result.update({
"editable": False "editable": False
}) })
relation_query_kw = kw.copy()
relation_query_kw['portal_type'] = portal_type_list
query = url_template_dict["jio_search_template"] % { 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") title = field.get_value("title")
column_list = field.get_value("columns") column_list = field.get_value("columns")
...@@ -544,14 +575,10 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key ...@@ -544,14 +575,10 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
# overwrite, like Base_getRelatedObjectParameter does # overwrite, like Base_getRelatedObjectParameter does
if subfield["portal_type"] == []: if subfield["portal_type"] == []:
subfield["portal_type"] = field.get_value('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"] % { subfield["query"] = url_template_dict["jio_search_template"] % {
"query": make_query({"query": sql_catalog.buildQuery( "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)}) ).asSearchTextExpression(sql_catalog)})
} }
# Kato: why? # Kato: why?
...@@ -575,7 +602,6 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key ...@@ -575,7 +602,6 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
"translated_portal_types": translated_portal_type, "translated_portal_types": translated_portal_type,
"portal_types": portal_type_list, "portal_types": portal_type_list,
"query": query, "query": query,
"sort": relation_sort,
"catalog_index": field.get_value('catalog_index'), "catalog_index": field.get_value('catalog_index'),
"allow_jump": field.get_value('allow_jump'), "allow_jump": field.get_value('allow_jump'),
"allow_creation": field.get_value('allow_creation'), "allow_creation": field.get_value('allow_creation'),
...@@ -595,7 +621,7 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key ...@@ -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 in ("CheckBoxField", "MultiCheckBoxField"):
if meta_type == "MultiCheckBoxField": if meta_type == "MultiCheckBoxField":
result["items"] = field.get_value("items"), result["items"] = toBasicTypes(field.get_value("items")),
return result return result
if meta_type == "GadgetField": if meta_type == "GadgetField":
...@@ -816,17 +842,26 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key ...@@ -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): 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 :param selection_params: holds parameters to construct ERP5Form.Selection instance
for underlaying ListBox - since we do not use selections in RenderJS UI for underlaying ListBox - since we do not use selections in RenderJS UI
we mitigate the functionality here by overriding ListBox's own values we mitigate the functionality here by overriding ListBox's own values
for columns, editable columns, and sort with those found in `selection_params` for columns, editable columns, and sort with those found in `selection_params`
""" """
previous_request_other = { previous_request_other = {}
'form_id': REQUEST.other.pop('form_id', None),
'here': REQUEST.other.pop('here', None)
}
REQUEST.set('here', traversed_document) 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) REQUEST.set('form_id', form.id)
field_errors = REQUEST.get('field_errors', {}) field_errors = REQUEST.get('field_errors', {})
#hardcoded #hardcoded
...@@ -892,17 +927,14 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti ...@@ -892,17 +927,14 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti
# Do not crash if field configuration is wrong. # Do not crash if field configuration is wrong.
pass pass
response_dict["form_id"] = { # Edit uses form_id to recover the submitted form.
"type": "StringField", # Dialog uses 'dialog_id' instead and 'form_id' only as a parameter to the dialog form
"key": "form_id", # Beware that print_action rewrites value of form_id in callee!
"default": form.id, addHiddenFieldToForm(response_dict, 'form_id', form.id)
"editable": 0,
"css_class": "", # Form dialog (subsequent callDialogMethod) selects its form based on dialog_id, not form_id
"hidden": 1, if (form.pt == 'form_dialog'):
"description": "", addHiddenFieldToForm(response_dict, 'dialog_id', form.id)
"title": "form_id",
"required": 1,
}
if (form.pt == 'report_view'): if (form.pt == 'report_view'):
# reports are expected to return list of ReportSection which is a wrapper # 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 ...@@ -928,7 +960,8 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti
report_prefix = 'x%s' % report_index report_prefix = 'x%s' % report_index
report_title = report_item.getTitle() report_title = report_item.getTitle()
# report_class = "report_title_level_%s" % report_item.getLevel() # 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': {}} report_result = {'_links': {}}
# some reports save a lot of unserializable data (datetime.datetime) and # some reports save a lot of unserializable data (datetime.datetime) and
# key "portal_type" (don't confuse with "portal_types" in ListBox) into # 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 ...@@ -943,17 +976,19 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti
report_form_params = report_item.selection_params.copy() \ report_form_params = report_item.selection_params.copy() \
if report_item.selection_params is not None \ if report_item.selection_params is not None \
else {} else {}
# request.prefixed_selection_name maybe used in tales expression
if report_form: # request.prefixed_selection_name maybe used in tales expression to display correct title of a ListBox
listbox = getattr(getattr(report_context, report_form), 'listbox', None) if report_form is not None:
listbox = getattr(report_form, 'listbox', None)
if listbox is not None: if listbox is not None:
listbox_selection_name = report_prefix + "_" + listbox.get_value('selection_name') listbox_selection_name = report_prefix + "_" + listbox.get_value('selection_name')
REQUEST.other['prefixed_selection_name'] = listbox_selection_name REQUEST.other['prefixed_selection_name'] = listbox_selection_name
if report_form_params: if report_form_params:
params = portal.portal_selections.getSelectionParamsFor(listbox_selection_name) params = portal.portal_selections.getSelectionParamsFor(listbox_selection_name)
params.update(report_form_params) 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: if report_item.selection_name:
selection_name = report_prefix + "_" + report_item.selection_name selection_name = report_prefix + "_" + report_item.selection_name
report_form_params.update(selection_name=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 ...@@ -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 # BUT! when Report Section defines `path` that is the new context for
# form rendering and subsequent searches... # form rendering and subsequent searches...
renderForm(traversed_document if not report_item.path else report_context, renderForm(traversed_document if not report_item.path else report_context,
getattr(report_context, report_item.getFormId()), report_form,
report_result, report_result,
key_prefix=report_prefix, key_prefix=report_prefix,
selection_params=report_form_params) # used to be only report_item.selection_params selection_params=report_form_params) # used to be only report_item.selection_params
...@@ -1050,7 +1085,6 @@ def renderFormDefinition(form, response_dict): ...@@ -1050,7 +1085,6 @@ def renderFormDefinition(form, response_dict):
response_dict["title"] = Base_translateString(form.getTitle()) response_dict["title"] = Base_translateString(form.getTitle())
response_dict["pt"] = form.pt response_dict["pt"] = form.pt
response_dict["action"] = form.action response_dict["action"] = form.action
response_dict["update_action"] = form.update_action
mime_type = 'application/hal+json' mime_type = 'application/hal+json'
...@@ -1191,6 +1225,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -1191,6 +1225,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
portal.portal_actions.listFilteredActionsFor(traversed_document)) portal.portal_actions.listFilteredActionsFor(traversed_document))
embedded_url = None embedded_url = None
prev_embedded_url = None
# XXX See ERP5Type.getDefaultViewFor # XXX See ERP5Type.getDefaultViewFor
for erp5_action_key in erp5_action_dict.keys(): 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, ...@@ -1207,6 +1242,10 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
if (view == view_action['id']): if (view == view_action['id']):
embedded_url = '%s' % view_action['url'] 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", global_action_type = ("view", "workflow", "object_new_content_action",
"object_clone_action", "object_delete_action") "object_clone_action", "object_delete_action")
if (erp5_action_key == view_action_type or if (erp5_action_key == view_action_type or
...@@ -1216,7 +1255,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -1216,7 +1255,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
"root_url": site_root.absolute_url(), "root_url": site_root.absolute_url(),
"script_id": script.id, "script_id": script.id,
"relative_url": traversed_document.getRelativeUrl().replace("/", "%2F"), "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': if erp5_action_key == 'object_jump':
...@@ -1244,7 +1283,6 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -1244,7 +1283,6 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
# XXX How to handle all custom jump actions? # XXX How to handle all custom jump actions?
erp5_action_list.pop(-1) erp5_action_list.pop(-1)
if erp5_action_list: if erp5_action_list:
if len(erp5_action_list) == 1: if len(erp5_action_list) == 1:
erp5_action_list = erp5_action_list[0] erp5_action_list = erp5_action_list[0]
...@@ -1291,6 +1329,15 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -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 # Put all query parameters (?reset:int=1&workflow_action=start_action) in request to mimic usual form display
query_param_dict = {} query_param_dict = {}
query_split = embedded_url.split('?', 1) query_split = embedded_url.split('?', 1)
...@@ -1303,14 +1350,41 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -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) # set URL params into REQUEST (just like it was sent by form)
for query_key, query_value in query_param_dict.items(): for query_key, query_value in query_param_dict.items():
REQUEST.set(query_key, query_value) REQUEST.set(query_key, query_value)
# Embedded Form can be a Script or even a class method thus we mitigate here
# unfortunatelly some people use Scripts as targets for Workflow try:
# transactions - thus we need to check and mitigate
if "Script" in renderer_form.meta_type: if "Script" in renderer_form.meta_type:
# we suppose that the script takes only what is given in the URL params # we suppose that the script takes only what is given in the URL params
return renderer_form(**query_param_dict) 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) 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'] = { result_dict['_embedded'] = {
'_view': embedded_dict '_view': embedded_dict
# embedded_action_key: embedded_dict # embedded_action_key: embedded_dict
...@@ -1542,6 +1616,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -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": if source_field is not None and source_field_meta_type == "ListBox":
listbox_field_id = source_field.id 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) listbox_form = getattr(traversed_document, source_field.aq_parent.id)
# field TALES expression evaluated by Base_getRelatedObjectParameter requires that # 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, ...@@ -1820,6 +1895,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
return result_dict return result_dict
response.setHeader('Content-Type', mime_type) 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, hateoas = calculateHateoas(is_portal=temp_is_portal, is_site_root=temp_is_site_root,
traversed_document=temp_traversed_document, traversed_document=temp_traversed_document,
relative_url=relative_url, relative_url=relative_url,
...@@ -1828,7 +1904,23 @@ hateoas = calculateHateoas(is_portal=temp_is_portal, is_site_root=temp_is_site_r ...@@ -1828,7 +1904,23 @@ hateoas = calculateHateoas(is_portal=temp_is_portal, is_site_root=temp_is_site_r
restricted=restricted, list_method=list_method, restricted=restricted, list_method=list_method,
default_param_json=default_param_json, default_param_json=default_param_json,
form_relative_url=form_relative_url) 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 == "": if hateoas == "":
return hateoas return hateoas
else: else:
# deepInspection(hateoas, '')
return json.dumps(hateoas, indent=2) return json.dumps(hateoas, indent=2)
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <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>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -1150,14 +1150,16 @@ return context.getPortalObject().portal_catalog(portal_type='Foo', sort_on=[('id ...@@ -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) self.assertEqual(result_dict['_embedded']['contents'][1]['credit_price'], 0.0)
# Render a Document using Form Field template (only for field 'id') # 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, REQUEST=fake_request,
mode="search", mode="search",
local_roles=["Assignor", "Assignee"], relative_url="foo_module",
local_roles=["Assignor", "Assignee", "Manager"],
list_method='Test_listProducts', list_method='Test_listProducts',
select_list=['id'], select_list=['id'],
form_relative_url='portal_skins/erp5_ui_test/FooModule_viewFooList/listbox' form_relative_url='portal_skins/erp5_ui_test/FooModule_viewFooList/listbox'
) )
self.logMessage(result)
result_dict = json.loads(result) result_dict = json.loads(result)
self.assertEqual(2, len(result_dict['_embedded']['contents'])) self.assertEqual(2, len(result_dict['_embedded']['contents']))
self.assertIn("field_listbox", result_dict['_embedded']['contents'][0]['id']['key']) self.assertIn("field_listbox", result_dict['_embedded']['contents'][0]['id']['key'])
...@@ -1547,7 +1549,7 @@ return msg" ...@@ -1547,7 +1549,7 @@ return msg"
work_list = [x for x in result_dict['worklist'] if x['name'].startswith('daiyanzhen')] work_list = [x for x in result_dict['worklist'] if x['name'].startswith('daiyanzhen')]
self.assertEqual(len(work_list), 1) self.assertEqual(len(work_list), 1)
self.assertEqual(work_list[0]['name'], 'daiyanzhen') 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.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') 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 @@ ...@@ -29,10 +29,7 @@
editable: field_json.editable, editable: field_json.editable,
name: field_json.key, name: field_json.key,
title: field_json.title, title: field_json.title,
hidden: field_json.hidden, hidden: field_json.hidden
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
}; };
state_dict.text_content = state_dict.checked ? '' : ''; state_dict.text_content = state_dict.checked ? '' : '';
return this.changeState(state_dict); return this.changeState(state_dict);
...@@ -84,7 +81,7 @@ ...@@ -84,7 +81,7 @@
}); });
} }
return {}; return {};
}, {mutex: 'changestate'}) })
.declareMethod('checkValidity', function () { .declareMethod('checkValidity', function () {
if (this.state.editable) { if (this.state.editable) {
...@@ -94,5 +91,5 @@ ...@@ -94,5 +91,5 @@
}); });
} }
return true; return true;
}, {mutex: 'changestate'}); });
}(window, rJS)); }(window, rJS));
\ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.10615.49166.8413</string> </value> <value> <string>962.4135.1398.9574</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1517321807.6</float> <float>1505315155.72</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -57,10 +57,7 @@ ...@@ -57,10 +57,7 @@
subfield_timezone_key: field_json.subfield_timezone_key, subfield_timezone_key: field_json.subfield_timezone_key,
start_datetime: field_json.start_datetime, start_datetime: field_json.start_datetime,
end_datetime: field_json.end_datetime, end_datetime: field_json.end_datetime,
hidden: field_json.hidden, hidden: field_json.hidden
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
}; };
return this.changeState(state_dict); return this.changeState(state_dict);
}) })
...@@ -229,7 +226,7 @@ ...@@ -229,7 +226,7 @@
.push(function (gadget_list) { .push(function (gadget_list) {
var text_content = "", var text_content = "",
state_date, state_date,
offset_time_zone; options;
if (gadget.state.value) { if (gadget.state.value) {
state_date = new Date(gadget.state.value); state_date = new Date(gadget.state.value);
if (gadget.state.timezone_style) { if (gadget.state.timezone_style) {
...@@ -238,13 +235,14 @@ ...@@ -238,13 +235,14 @@
text_content += " " + state_date.toLocaleTimeString(); text_content += " " + state_date.toLocaleTimeString();
} }
} else { } else {
//get timezone difference between server and local browser // We don't know the timezone used by erp5 to store the date
offset_time_zone = timezone + (state_date.getTimezoneOffset() / 60); // display it as displayed in editable
//adjust hour in order to get correct date time string options = {timeZone: "UTC"};
state_date.setUTCHours(state_date.getUTCHours() + offset_time_zone); text_content = state_date.toLocaleDateString(undefined,
text_content = state_date.toLocaleDateString(); options);
if (!gadget.state.date_only) { if (!gadget.state.date_only) {
text_content += " " + state_date.toLocaleTimeString(); text_content += " " + state_date.toLocaleTimeString(undefined,
options);
} }
} }
} }
...@@ -367,7 +365,7 @@ ...@@ -367,7 +365,7 @@
}); });
} }
return result; return result;
}, {mutex: 'changestate'}) })
.declareMethod('checkValidity', function () { .declareMethod('checkValidity', function () {
var gadget = this; var gadget = this;
...@@ -378,6 +376,6 @@ ...@@ -378,6 +376,6 @@
}); });
} }
return true; return true;
}, {mutex: 'changestate'}); });
}(window, rJS, RSVP)); }(window, rJS, RSVP));
\ No newline at end of file
...@@ -224,7 +224,7 @@ ...@@ -224,7 +224,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.3167.36247.3959</string> </value> <value> <string>964.26946.11355.11605</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -242,7 +242,7 @@ ...@@ -242,7 +242,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1517321711.65</float> <float>1514370341.04</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -14,10 +14,7 @@ ...@@ -14,10 +14,7 @@
editable: field_json.editable, editable: field_json.editable,
name: field_json.key, name: field_json.key,
title: field_json.title, title: field_json.title,
hidden: field_json.hidden, hidden: field_json.hidden
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
}; };
state_dict.inner_html = state_dict.value; state_dict.inner_html = state_dict.value;
return this.changeState(state_dict); return this.changeState(state_dict);
......
...@@ -236,7 +236,7 @@ ...@@ -236,7 +236,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>963.11788.48702.26146</string> </value> <value> <string>955.2252.33079.47462</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -254,7 +254,7 @@ ...@@ -254,7 +254,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516702186.86</float> <float>1479375938.91</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -17,10 +17,7 @@ ...@@ -17,10 +17,7 @@
name: field_json.key, name: field_json.key,
title: field_json.title, title: field_json.title,
type: 'email', type: 'email',
hidden: field_json.hidden, hidden: field_json.hidden
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
}; };
state_dict.text_content = state_dict.value; state_dict.text_content = state_dict.value;
return this.changeState(state_dict); return this.changeState(state_dict);
...@@ -63,7 +60,7 @@ ...@@ -63,7 +60,7 @@
}); });
} }
return {}; return {};
}, {mutex: 'changestate'}) })
.declareMethod('checkValidity', function () { .declareMethod('checkValidity', function () {
if (this.state.editable) { if (this.state.editable) {
...@@ -73,6 +70,6 @@ ...@@ -73,6 +70,6 @@
}); });
} }
return true; return true;
}, {mutex: 'changestate'}); });
}(window, rJS)); }(window, rJS));
\ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value> <value> <string>955.51162.4768.35123</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1517321664.03</float> <float>1482843519.98</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -14,8 +14,7 @@ ...@@ -14,8 +14,7 @@
rJS(window) rJS(window)
.setState({ .setState({
subgadget_template: undefined, subgadget_template: undefined,
editable: undefined, editable: undefined
css_class: ''
}) })
.declareAcquiredMethod("jio_getAttachment", "jio_getAttachment") .declareAcquiredMethod("jio_getAttachment", "jio_getAttachment")
...@@ -33,7 +32,6 @@ ...@@ -33,7 +32,6 @@
title: field_json.title, title: field_json.title,
hidden: field_json.hidden, hidden: field_json.hidden,
view: field_json.view, view: field_json.view,
css_class: field_json.css_class,
// field_json._embedded is HATEOASed subobj specs included in FormBox // field_json._embedded is HATEOASed subobj specs included in FormBox
erp5_embedded_document: field_json._embedded erp5_embedded_document: field_json._embedded
}; };
...@@ -77,11 +75,6 @@ ...@@ -77,11 +75,6 @@
// do not preserve objects in the state // do not preserve objects in the state
delete gadget.state.erp5_embedded_document; 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') return gadget.getDeclaredGadget('sub')
.push(function (subgadget) { .push(function (subgadget) {
subgadget.render(form_options); subgadget.render(form_options);
......
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>961.29423.48444.21077</string> </value> <value> <string>961.56527.16709.20804</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1502977334.64</float> <float>1517248866.15</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -16,10 +16,7 @@ ...@@ -16,10 +16,7 @@
required: field_json.required, required: field_json.required,
name: field_json.key, name: field_json.key,
title: field_json.title, title: field_json.title,
hidden: field_json.hidden, hidden: field_json.hidden
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
}; };
return this.changeState(state_dict); return this.changeState(state_dict);
}) })
...@@ -61,7 +58,7 @@ ...@@ -61,7 +58,7 @@
}); });
} }
return {}; return {};
}, {mutex: 'changestate'}) })
.declareMethod('checkValidity', function () { .declareMethod('checkValidity', function () {
if (this.state.editable) { if (this.state.editable) {
...@@ -71,6 +68,6 @@ ...@@ -71,6 +68,6 @@
}); });
} }
return true; return true;
}, {mutex: 'changestate'}); });
}(window, rJS)); }(window, rJS));
\ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value> <value> <string>955.51162.4768.35123</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1517321650.56</float> <float>1482843418.41</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -41,10 +41,7 @@ ...@@ -41,10 +41,7 @@
// if unspecified we can use "any" value // if unspecified we can use "any" value
step: "any", step: "any",
// `append` is a string to display next to the field ("%", "EUR"...) // `append` is a string to display next to the field ("%", "EUR"...)
append: '', append: ''
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
}, },
tmp; tmp;
...@@ -108,7 +105,7 @@ ...@@ -108,7 +105,7 @@
}); });
} }
return {}; return {};
}, {mutex: 'changestate'}) })
.declareMethod('checkValidity', function () { .declareMethod('checkValidity', function () {
if (this.state.editable) { if (this.state.editable) {
...@@ -118,6 +115,6 @@ ...@@ -118,6 +115,6 @@
}); });
} }
return true; return true;
}, {mutex: 'changestate'}); });
}(window, rJS, Math)); }(window, rJS, Math));
\ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value> <value> <string>963.40246.8021.32017</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1517321634.14</float> <float>1512458225.4</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -225,7 +225,7 @@ ...@@ -225,7 +225,7 @@
return gadget.props.listbox_gadget.getListboxInfo(); return gadget.props.listbox_gadget.getListboxInfo();
} }
return {}; return {};
}, {mutex: 'changestate'}) })
.declareMethod("getContent", function (options) { .declareMethod("getContent", function (options) {
var form_gadget = this, var form_gadget = this,
k, k,
...@@ -259,7 +259,7 @@ ...@@ -259,7 +259,7 @@
.push(function () { .push(function () {
return data; return data;
}); });
}, {mutex: 'changestate'}) })
.declareMethod("checkValidity", function () { .declareMethod("checkValidity", function () {
var form_gadget = this, var form_gadget = this,
k, k,
...@@ -286,6 +286,6 @@ ...@@ -286,6 +286,6 @@
return result; return result;
}); });
}, {mutex: 'changestate'}); });
}(window, document, rJS, RSVP)); }(window, document, rJS, RSVP));
\ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.58561.19908.14080</string> </value> <value> <string>964.25533.41108.47530</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516274548.88</float> <float>1515496577.67</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -14,10 +14,7 @@ ...@@ -14,10 +14,7 @@
url: options.field_json.url, url: options.field_json.url,
sandbox: options.field_json.sandbox || undefined, sandbox: options.field_json.sandbox || undefined,
hidden: options.field_json.hidden, hidden: options.field_json.hidden,
css_class: options.field_json.css_class, css_class: options.field_json.css_class
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
}); });
}) })
...@@ -82,6 +79,6 @@ ...@@ -82,6 +79,6 @@
.push(function (result) { .push(function (result) {
return result.getContent(); return result.getContent();
}); });
}, {mutex: 'changestate'}); });
}(window, rJS, document)); }(window, rJS, document));
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.300.34630.14250</string> </value> <value> <string>962.24020.58652.57139</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516703954.27</float> <float>1507901872.84</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -15,4 +15,46 @@ ...@@ -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)); }(window, RSVP));
\ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>954.14461.31508.53930</string> </value> <value> <string>960.5523.58984.43537</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1476894652.41</float> <float>1517406504.9</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -18,10 +18,7 @@ ...@@ -18,10 +18,7 @@
required: field_json.required, required: field_json.required,
name: field_json.key, name: field_json.key,
title: field_json.title, title: field_json.title,
hidden: field_json.hidden, hidden: field_json.hidden
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
}; };
state_dict.text_content = state_dict.value; state_dict.text_content = state_dict.value;
return this.changeState(state_dict); return this.changeState(state_dict);
...@@ -65,7 +62,7 @@ ...@@ -65,7 +62,7 @@
}); });
} }
return {}; return {};
}, {mutex: 'changestate'}) })
.declareMethod('checkValidity', function () { .declareMethod('checkValidity', function () {
if (this.state.editable) { if (this.state.editable) {
...@@ -75,6 +72,6 @@ ...@@ -75,6 +72,6 @@
}); });
} }
return true; return true;
}, {mutex: 'changestate'}); });
}(window, rJS)); }(window, rJS));
\ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value> <value> <string>956.15712.57649.37376</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1517321585.88</float> <float>1482843064.62</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -119,7 +119,7 @@ ...@@ -119,7 +119,7 @@
this.state.label_element.setAttribute('for', gadget.state.scope); this.state.label_element.setAttribute('for', gadget.state.scope);
if (modification_dict.hasOwnProperty('css_class') && this.state.css_class) { 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')) { if (modification_dict.hasOwnProperty('error_text')) {
...@@ -185,7 +185,7 @@ ...@@ -185,7 +185,7 @@
} }
return true; return true;
}); });
}, {mutex: 'changestate'}) })
.declareMethod('getContent', function () { .declareMethod('getContent', function () {
var argument_list = arguments; var argument_list = arguments;
...@@ -196,7 +196,7 @@ ...@@ -196,7 +196,7 @@
} }
return {}; return {};
}); });
}, {mutex: 'changestate'}) })
.declareMethod('getListboxInfo', function () { .declareMethod('getListboxInfo', function () {
var argument_list = arguments; var argument_list = arguments;
...@@ -204,22 +204,14 @@ ...@@ -204,22 +204,14 @@
.push(function (gadget) { .push(function (gadget) {
return gadget.getListboxInfo.apply(gadget, argument_list); return gadget.getListboxInfo.apply(gadget, argument_list);
}); });
}, {mutex: 'changestate'}) })
.allowPublicAcquisition("notifyInvalid", function (param_list) { .allowPublicAcquisition("notifyInvalid", function (param_list) {
// Label doesn't know when a subgadget calls notifyInvalid return this.changeState({error_text: param_list[0]});
// Prevent mutex dead lock by defering the changeState call
return this.deferErrorTextRender(param_list[0]);
}) })
.allowPublicAcquisition("notifyValid", function () { .allowPublicAcquisition("notifyValid", function () {
// Label doesn't know when a subgadget calls notifyValid return this.changeState({error_text: ''});
// Prevent mutex dead lock by defering the changeState call
return this.deferErrorTextRender('');
})
.declareJob('deferErrorTextRender', function (error_text) {
return this.changeState({error_text: error_text});
}); });
}(window, document, rJS, RSVP)); }(window, document, rJS, RSVP));
\ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.59013.39016.42820</string> </value> <value> <string>965.9315.27783.1843</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516293734.37</float> <float>1517246822.2</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/*globals window, document, RSVP, rJS, /*globals window, document, RSVP, rJS,
URI, location, XMLHttpRequest, console, navigator, ProgressEvent*/ URI, location, XMLHttpRequest, console, navigator*/
/*jslint indent: 2, maxlen: 80*/ /*jslint indent: 2, maxlen: 80*/
(function (window, document, RSVP, rJS, (function (window, document, RSVP, rJS,
XMLHttpRequest, location, console, navigator, ProgressEvent) { XMLHttpRequest, location, console, navigator) {
"use strict"; "use strict";
var MAIN_SCOPE = "m"; var MAIN_SCOPE = "m";
...@@ -133,9 +133,6 @@ ...@@ -133,9 +133,6 @@
// Display it to the user for now, // Display it to the user for now,
// and allow user to go back to the frontpage // and allow user to go back to the frontpage
var error_text = ""; var error_text = "";
if (error instanceof ProgressEvent) {
error = error.target.error;
}
if (error.target instanceof XMLHttpRequest) { if (error.target instanceof XMLHttpRequest) {
error_text = error.target.toString() + " " + error_text = error.target.toString() + " " +
...@@ -650,4 +647,4 @@ ...@@ -650,4 +647,4 @@
}); });
}(window, document, RSVP, rJS, }(window, document, RSVP, rJS,
XMLHttpRequest, location, console, navigator, ProgressEvent)); XMLHttpRequest, location, console, navigator));
\ No newline at end of file \ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.44401.33443.35072</string> </value> <value> <string>964.44144.54943.18056</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516619185.21</float> <float>1515401365.21</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -21,10 +21,7 @@ ...@@ -21,10 +21,7 @@
"required": options.field_json.required, "required": options.field_json.required,
"hidden": options.field_json.hidden, "hidden": options.field_json.hidden,
"title": options.field_json.title, "title": options.field_json.title,
"key": options.field_json.key, "key": options.field_json.key
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
}; };
if (this.state.gadget_rendered === false) { if (this.state.gadget_rendered === false) {
......
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.58561.19908.14080</string> </value> <value> <string>964.54328.21867.14506</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1517321571.05</float> <float>1516015281.65</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -197,9 +197,7 @@ ...@@ -197,9 +197,7 @@
} }
} }
// Cancel previous line rendering to not conflict with the asynchronous render for now queue = RSVP.Queue();
gadget.fetchLineContent(true);
queue = new RSVP.Queue();
if (!variable.translated_records) { if (!variable.translated_records) {
queue queue
.push(function () { .push(function () {
...@@ -214,6 +212,10 @@ ...@@ -214,6 +212,10 @@
}); });
} }
queue queue
.push(function () {
// Cancel previous line rendering to not conflict with the asynchronous render for now
return gadget.fetchLineContent(true);
})
.push(function () { .push(function () {
// XXX Fix in case of multiple listboxes // XXX Fix in case of multiple listboxes
return RSVP.all([ return RSVP.all([
...@@ -295,7 +297,6 @@ ...@@ -295,7 +297,6 @@
command: field_json.command || 'index', command: field_json.command || 'index',
// Force line calculation in any case // Force line calculation in any case
render_timestamp: new Date().getTime(),
allDocs_result: undefined, allDocs_result: undefined,
// No error message // No error message
...@@ -760,7 +761,7 @@ ...@@ -760,7 +761,7 @@
data[form_gadget.props.listbox_uid_dict.key] = form_gadget.props.listbox_uid_dict.value; data[form_gadget.props.listbox_uid_dict.key] = form_gadget.props.listbox_uid_dict.value;
return data; return data;
}); });
}, {mutex: 'changestate'}) })
.onEvent('click', function (evt) { .onEvent('click', function (evt) {
var gadget = this, var gadget = this,
......
...@@ -236,7 +236,7 @@ ...@@ -236,7 +236,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.60204.10137.19421</string> </value> <value> <string>964.49926.23272.20514</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -254,7 +254,7 @@ ...@@ -254,7 +254,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516364900.78</float> <float>1515755492.39</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/*global window, rJS*/ /*global window, rJS, isEmpty, getFirstNonEmpty */
/*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80 */ /*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80 */
(function (window, rJS) { (function (window, rJS, getFirstNonEmpty) {
"use strict"; "use strict";
rJS(window) rJS(window)
...@@ -11,20 +11,17 @@ ...@@ -11,20 +11,17 @@
.declareMethod('render', function (options) { .declareMethod('render', function (options) {
var field_json = options.field_json || {}, var field_json = options.field_json || {},
state_dict = { state_dict = {
value: field_json.value || field_json.default || "", value: getFirstNonEmpty(field_json.value, field_json['default'], ""),
item_list: JSON.stringify(field_json.items), item_list: JSON.stringify(field_json.items),
editable: field_json.editable, editable: field_json.editable,
required: field_json.required, required: field_json.required,
name: field_json.key, name: field_json.key,
title: field_json.title, title: field_json.title,
first_item: field_json.first_item, first_item: field_json.first_item,
hidden: field_json.hidden, hidden: field_json.hidden
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
}; };
// first_item means to select the first item by default on empty value
if ((!state_dict.value) && (state_dict.first_item)) { if (isEmpty(state_dict.value) && (state_dict.first_item)) {
state_dict.value = field_json.items[0][1]; state_dict.value = field_json.items[0][1];
} }
return this.changeState(state_dict); return this.changeState(state_dict);
...@@ -99,7 +96,7 @@ ...@@ -99,7 +96,7 @@
}); });
} }
return {}; return {};
}, {mutex: 'changestate'}) })
.declareMethod('checkValidity', function () { .declareMethod('checkValidity', function () {
if (this.state.editable) { if (this.state.editable) {
...@@ -109,6 +106,6 @@ ...@@ -109,6 +106,6 @@
}); });
} }
return true; return true;
}, {mutex: 'changestate'}); });
}(window, rJS)); }(window, rJS, getFirstNonEmpty));
\ No newline at end of file \ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.1659.33258.11707</string> </value> <value> <string>965.10978.44363.39543</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516786204.34</float> <float>1517406625.1</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -60,10 +60,7 @@ ...@@ -60,10 +60,7 @@
name: field_json.key, name: field_json.key,
item_list: field_json.items, item_list: field_json.items,
value_list: field_json.value || field_json.default, value_list: field_json.value || field_json.default,
hidden: field_json.hidden, hidden: field_json.hidden
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
}; };
return this.changeState(state_dict); return this.changeState(state_dict);
...@@ -146,5 +143,5 @@ ...@@ -146,5 +143,5 @@
}); });
} }
return final_result; return final_result;
}, {mutex: 'changestate'}); });
}(window, rJS, RSVP, document)); }(window, rJS, RSVP, document));
\ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value> <value> <string>960.5523.58984.43537</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1517321512.62</float> <float>1505309155.21</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/*global window, rJS, document, RSVP*/ /*global window, rJS, document, RSVP, isEmpty, ensureArray */
/*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80, unparam: true */ /*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'; 'use strict';
/* Make sure that returned object is an Array instance. */ /** More robust way of writing a || b || "" because if b===0 it gets skipped.
function ensureArray(obj) { */
if (!obj) {return []; } function getNonEmpty() {
if (Array.isArray(obj)) {return obj; } var i;
return [obj]; 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) { function appendListField(gadget, value, item_list) {
...@@ -37,10 +45,11 @@ ...@@ -37,10 +45,11 @@
rJS(window) rJS(window)
.declareMethod('render', function (options) { .declareMethod('render', function (options) {
var field_json = options.field_json || {}, var field_json = options.field_json || {},
item_list = field_json.items, item_list = ensureArray(field_json.items),
state_dict = { state_dict = {
value_list: JSON.stringify( value_list: JSON.stringify(
ensureArray(field_json.value || field_json.default) ensureArray(
getNonEmpty(field_json.value, field_json['default'], []))
), ),
editable: field_json.editable, editable: field_json.editable,
required: field_json.required, required: field_json.required,
...@@ -49,11 +58,13 @@ ...@@ -49,11 +58,13 @@
key: field_json.key, key: field_json.key,
sub_select_key: field_json.sub_select_key, sub_select_key: field_json.sub_select_key,
sub_input_key: field_json.sub_input_key, sub_input_key: field_json.sub_input_key,
hidden: field_json.hidden, hidden: field_json.hidden
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
}; };
// 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] !== "")) { if ((item_list.length === 0) || (item_list[0][0] !== "")) {
item_list.unshift(["", ""]); item_list.unshift(["", ""]);
} }
...@@ -77,17 +88,13 @@ ...@@ -77,17 +88,13 @@
element.removeChild(element.firstChild); element.removeChild(element.firstChild);
} }
function enQueue() { value_list.forEach(function (value) {
var argument_list = arguments;
queue queue
.push(function () { .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; return queue;
}) })
...@@ -136,7 +143,7 @@ ...@@ -136,7 +143,7 @@
}); });
} }
return final_result; return final_result;
}, {mutex: 'changestate'}) })
.allowPublicAcquisition('notifyValid', function () { .allowPublicAcquisition('notifyValid', function () {
return; return;
...@@ -197,6 +204,6 @@ ...@@ -197,6 +204,6 @@
}); });
} }
return true; return true;
}, {mutex: 'changestate'}); });
}(window, rJS, document, RSVP)); }(window, rJS, document, RSVP, isEmpty, ensureArray));
\ No newline at end of file \ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value> <value> <string>965.11854.16357.58572</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1517321477.39</float> <float>1517406578.58</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
return input_gadget.render({ return input_gadget.render({
editable: gadget.state.editable, editable: gadget.state.editable,
query: gadget.state.query, query: gadget.state.query,
sort_list_json: gadget.state.sort_list_json,
catalog_index: gadget.state.catalog_index, catalog_index: gadget.state.catalog_index,
allow_jump: gadget.state.allow_jump, allow_jump: gadget.state.allow_jump,
// required: field_json.required, // required: field_json.required,
...@@ -48,7 +47,6 @@ ...@@ -48,7 +47,6 @@
state_dict = { state_dict = {
editable: field_json.editable, editable: field_json.editable,
query: field_json.query, query: field_json.query,
sort_list_json: JSON.stringify(field_json.sort),
catalog_index: field_json.catalog_index, catalog_index: field_json.catalog_index,
allow_jump: field_json.allow_jump, allow_jump: field_json.allow_jump,
required: field_json.required, required: field_json.required,
...@@ -60,10 +58,7 @@ ...@@ -60,10 +58,7 @@
portal_types: field_json.portal_types, portal_types: field_json.portal_types,
translated_portal_types: field_json.translated_portal_types, translated_portal_types: field_json.translated_portal_types,
relation_field_id: field_json.relation_field_id, relation_field_id: field_json.relation_field_id,
hidden: field_json.hidden, hidden: field_json.hidden
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
}; };
if (field_json.default.hasOwnProperty('value_text_list')) { if (field_json.default.hasOwnProperty('value_text_list')) {
...@@ -242,6 +237,6 @@ ...@@ -242,6 +237,6 @@
}); });
} }
return final_result; return final_result;
}, {mutex: 'changestate'}); });
}(window, rJS, RSVP, document)); }(window, rJS, RSVP, document));
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value> <value> <string>964.38497.25325.33501</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1517321450.32</float> <float>1515062767.93</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -526,13 +526,9 @@ div[data-gadget-scope='panel'] ul li a { ...@@ -526,13 +526,9 @@ div[data-gadget-scope='panel'] ul li a {
overflow: hidden; overflow: hidden;
white-space: nowrap; 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:hover,
div[data-gadget-scope='panel'] ul li a:active { div[data-gadget-scope='panel'] ul li a:active,
color: #FFFFFF; div[data-gadget-scope='panel'] ul li a.active {
background-color: #2b2b2b; background-color: #2b2b2b;
} }
div[data-gadget-scope='panel'] ul li a::before { div[data-gadget-scope='panel'] ul li a::before {
...@@ -568,13 +564,9 @@ div[data-gadget-scope='panel'] dl dd a { ...@@ -568,13 +564,9 @@ div[data-gadget-scope='panel'] dl dd a {
white-space: nowrap; white-space: nowrap;
padding-left: 36pt; 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:hover,
div[data-gadget-scope='panel'] dl dd a:active { div[data-gadget-scope='panel'] dl dd a:active,
color: #FFFFFF; div[data-gadget-scope='panel'] dl dd a.active {
background-color: #2b2b2b; background-color: #2b2b2b;
} }
div[data-gadget-scope='panel'] dl dd a::before { div[data-gadget-scope='panel'] dl dd a::before {
...@@ -983,24 +975,6 @@ div[data-gadget-scope='header'] .ui-header ul { ...@@ -983,24 +975,6 @@ div[data-gadget-scope='header'] .ui-header ul {
.gadget-content input[type='submit']:active { .gadget-content input[type='submit']:active {
background-color: #ffa366; 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) { @media not screen and (max-width: 85em) {
div[data-role='page']:not(.desktop-panel-hidden) .gadget-content { div[data-role='page']:not(.desktop-panel-hidden) .gadget-content {
margin-left: 180pt; margin-left: 180pt;
...@@ -1023,13 +997,16 @@ div[data-gadget-scope='header'] .ui-header ul { ...@@ -1023,13 +997,16 @@ div[data-gadget-scope='header'] .ui-header ul {
.gadget-content .field_container > div > div > div.ui-field-contain div { .gadget-content .field_container > div > div > div.ui-field-contain div {
width: 100%; width: 100%;
} }
.gadget-content .horizontal_align_form_box .field_container > div { .gadget-content .field_container > div > div.horizontal_align_form_box > .ui-field-contain {
/* Class .horizontal_align_form_box is here only for backward-compatibility! padding: 0;
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 > label {
padding-top: 9pt;
}
.gadget-content .field_container > div > div.horizontal_align_form_box .field_container > div {
display: flex; 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; flex: 1;
} }
.gadget-content .ui-content-header-plain { .gadget-content .ui-content-header-plain {
...@@ -1118,6 +1095,7 @@ div[data-gadget-scope='header'] .ui-header ul { ...@@ -1118,6 +1095,7 @@ div[data-gadget-scope='header'] .ui-header ul {
} }
.gadget-content .ui-field-contain > label { .gadget-content .ui-field-contain > label {
color: #777777; color: #777777;
padding: 3pt;
} }
.gadget-content .ui-field-contain > label.required { .gadget-content .ui-field-contain > label.required {
font-weight: bold; font-weight: bold;
...@@ -1125,6 +1103,9 @@ div[data-gadget-scope='header'] .ui-header ul { ...@@ -1125,6 +1103,9 @@ div[data-gadget-scope='header'] .ui-header ul {
.gadget-content .ui-field-contain > label.invisible { .gadget-content .ui-field-contain > label.invisible {
display: none; 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) { @media only screen and (min-width: 45em) and (max-width: 85em), not screen and (max-width: 85em) {
.gadget-content .ui-field-contain { .gadget-content .ui-field-contain {
display: flex; display: flex;
......
...@@ -242,7 +242,7 @@ ...@@ -242,7 +242,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.10742.13164.48827</string> </value> <value> <string>965.9378.54486.51763</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -260,7 +260,7 @@ ...@@ -260,7 +260,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1517329600.93</float> <float>1517248083.17</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/*global window, rJS, RSVP, Handlebars, calculatePageTitle */ /*global window, rJS, RSVP, Handlebars, calculatePageTitle, URL */
/*jslint nomen: true, indent: 2, maxerr: 3 */ /*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP, Handlebars, calculatePageTitle) { (function (window, rJS, RSVP, Handlebars, calculatePageTitle, URL) {
"use strict"; "use strict";
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -67,24 +67,48 @@ ...@@ -67,24 +67,48 @@
.declareAcquiredMethod("translateHtml", "translateHtml") .declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("getUrlFor", "getUrlFor") .declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("updateHeader", "updateHeader") .declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("getUrlParameter", "getUrlParameter")
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// declared methods // declared methods
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
.declareMethod("render", function (options) { .declareMethod("render", function (options) {
var gadget = this, var gadget = this,
erp5_document, erp5_document;
report_list;
return gadget.jio_getAttachment(options.jio_key, "links") return gadget.jio_getAttachment(options.jio_key, "links")
.push(function (result) { .push(function (jio_document) {
erp5_document = result; var report_list = asArray(jio_document._links.action_object_report_jio)
report_list = asArray(erp5_document._links.action_object_report_jio) .concat(asArray(jio_document._links.action_object_jio_report)),
.concat(asArray(erp5_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([ 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) { .push(function (translated_html_link_list) {
gadget.element.innerHTML = translated_html_link_list.join("\n"); gadget.element.innerHTML = translated_html_link_list.join("\n");
...@@ -101,4 +125,4 @@ ...@@ -101,4 +125,4 @@
}); });
}); });
}(window, rJS, RSVP, Handlebars, calculatePageTitle)); }(window, rJS, RSVP, Handlebars, calculatePageTitle, URL));
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>963.3162.7999.42854</string> </value> <value> <string>964.64570.61398.48110</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1509097420.01</float> <float>1516871683.64</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -42,19 +42,19 @@ ...@@ -42,19 +42,19 @@
.push(function (g) { .push(function (g) {
return g.triggerSubmit(); return g.triggerSubmit();
}); });
}, {mutex: 'changestate'}) })
.declareMethod('checkValidity', function () { .declareMethod('checkValidity', function () {
return this.getDeclaredGadget('fg') return this.getDeclaredGadget('fg')
.push(function (declared_gadget) { .push(function (declared_gadget) {
return declared_gadget.checkValidity(); return declared_gadget.checkValidity();
}); });
}, {mutex: 'changestate'}) })
.declareMethod('getContent', function () { .declareMethod('getContent', function () {
return this.getDeclaredGadget('fg') return this.getDeclaredGadget('fg')
.push(function (declared_gadget) { .push(function (declared_gadget) {
return declared_gadget.getContent(); return declared_gadget.getContent();
}); });
}, {mutex: 'changestate'}) })
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Own methods // Own methods
......
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.45640.391.48230</string> </value> <value> <string>963.49235.21851.43451</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516294817.06</float> <float>1515078479.71</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -62,6 +62,15 @@ ...@@ -62,6 +62,15 @@
filter_action: true 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) { .declareMethod("render", function (options) {
var gadget = this, var gadget = this,
select_template = options.select_template || ""; select_template = options.select_template || "";
......
...@@ -71,9 +71,7 @@ ...@@ -71,9 +71,7 @@
</item> </item>
<item> <item>
<key> <string>content_type</string> </key> <key> <string>content_type</string> </key>
<value> <value> <string>text/javascript</string> </value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
...@@ -236,7 +234,7 @@ ...@@ -236,7 +234,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.60339.56148.38212</string> </value> <value> <string>961.17732.18127.14097</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -254,7 +252,7 @@ ...@@ -254,7 +252,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516373132.37</float> <float>1502199416.77</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -330,7 +330,7 @@ ...@@ -330,7 +330,7 @@
} }
// Typing a search query should not modify the header status // Typing a search query should not modify the header status
return; return;
}, {mutex: 'changestate'}) })
.allowPublicAcquisition('notifyValid', function () { .allowPublicAcquisition('notifyValid', function () {
// Typing a search query should not modify the header status // Typing a search query should not modify the header status
return; return;
......
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.45640.391.48230</string> </value> <value> <string>964.39835.8408.1945</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516295067.02</float> <float>1515142977.99</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -17,10 +17,7 @@ ...@@ -17,10 +17,7 @@
name: field_json.key, name: field_json.key,
title: field_json.title, title: field_json.title,
type: 'password', type: 'password',
hidden: field_json.hidden, hidden: field_json.hidden
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
}; };
state_dict.text_content = state_dict.value; state_dict.text_content = state_dict.value;
return this.changeState(state_dict); return this.changeState(state_dict);
...@@ -72,7 +69,7 @@ ...@@ -72,7 +69,7 @@
}); });
} }
return {}; return {};
}, {mutex: 'changestate'}) })
.declareMethod('checkValidity', function () { .declareMethod('checkValidity', function () {
if (this.state.editable) { if (this.state.editable) {
...@@ -82,6 +79,6 @@ ...@@ -82,6 +79,6 @@
}); });
} }
return true; return true;
}, {mutex: 'changestate'}); });
}(window, rJS)); }(window, rJS));
\ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value> <value> <string>955.51162.4768.35123</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1517321403.8</float> <float>1482843530.9</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -17,15 +17,6 @@ ...@@ -17,15 +17,6 @@
<script src="rsvp.js" type="text/javascript"></script> <script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script> <script src="renderjs.js" type="text/javascript"></script>
<script src="jiodev.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 --> <!-- custom script -->
<script src="gadget_erp5_global.js" type="text/javascript"></script> <script src="gadget_erp5_global.js" type="text/javascript"></script>
...@@ -44,7 +35,8 @@ ...@@ -44,7 +35,8 @@
data-gadget-scope="erp5_form" data-gadget-scope="erp5_form"
data-gadget-sandbox="public"> data-gadget-sandbox="public">
</div> </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> </form>
</body> </body>
</html> </html>
\ No newline at end of file
...@@ -234,7 +234,7 @@ ...@@ -234,7 +234,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.10309.12229.56627</string> </value> <value> <string>962.14191.38290.31931</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -252,7 +252,7 @@ ...@@ -252,7 +252,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1517304075.06</float> <float>1506093694.63</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/*jslint nomen: true, indent: 2, maxerr: 3 */ /*jslint nomen: true, indent: 2, maxerr: 3 */
/*global 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, Handlebars) { (function (window, rJS, RSVP, URI, calculatePageTitle, Blob, URL, document, jIO, ensureArray) {
"use strict"; "use strict";
/* Make sure that returned object is an Array instance. */ rJS(window)
function ensureArray(obj) { /////////////////////////////////////////////////////////////////
if (!obj) {return []; } // acquisition
if (Array.isArray(obj)) {return obj; } /////////////////////////////////////////////////////////////////
return [obj]; .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) { for (i = 0; i < view_list.length; i += 1) {
var form_gadget = gadget, if (view_list[i].href === this.state.view) {
action = form_gadget.state.erp5_document._embedded._view._actions.put, title = view_list[i].title;
form_id = form_gadget.state.erp5_document._embedded._view.form_id, }
}
// 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; redirect_to_parent;
return form_gadget.notifySubmitting() return form_gadget.notifySubmitting()
...@@ -26,14 +181,14 @@ ...@@ -26,14 +181,14 @@
.push(function (content_dict) { .push(function (content_dict) {
var data = {}, var data = {},
key; key;
/* Fields "form_id", "dialog_id" and "selection_name" are special
data[form_id.key] = form_id['default']; because they are necessary for Base_callDialogMethod to work */
// XXX Hardcoded data[field_dict.form_id.key] = field_dict.form_id['default'];
data.dialog_id = form_id['default']; data[field_dict.dialog_id.key] = field_dict.dialog_id['default'];
data.dialog_method = form_gadget.state.form_definition[submit_action_id]; if (field_dict.hasOwnProperty('selection_name')) {
if (is_update_method) { data[field_dict.selection_name.key] = field_dict.selection_name['default'];
data.update_method = data.dialog_method;
} }
data.dialog_method = action.action;
//XXX hack for redirect, difined in form //XXX hack for redirect, difined in form
redirect_to_parent = content_dict.field_your_redirect_to_parent; redirect_to_parent = content_dict.field_your_redirect_to_parent;
for (key in content_dict) { for (key in content_dict) {
...@@ -181,7 +336,7 @@ ...@@ -181,7 +336,7 @@
.push(undefined, function (error) { .push(undefined, function (error) {
if (error.target !== undefined) { if (error.target !== undefined) {
var error_text = 'Encountered an unknown error. Try to resubmit', 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 we know what the error was, try to precise it for the user
if (error.target.status === 400) { if (error.target.status === 400) {
error_text = 'Input data has errors'; error_text = 'Input data has errors';
...@@ -189,9 +344,21 @@ ...@@ -189,9 +344,21 @@
error_text = 'You do not have the permissions to edit the object'; error_text = 'You do not have the permissions to edit the object';
} else if (error.target.status === 0) { } else if (error.target.status === 0) {
error_text = 'Document was not saved! Resubmit when you are online or the document accessible'; 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 // display translated error_text to user
promise = form_gadget.notifySubmitted() promise_queue
.push(function () {
return form_gadget.notifySubmitted();
})
.push(function () { .push(function () {
return form_gadget.translate(error_text); return form_gadget.translate(error_text);
}) })
...@@ -204,7 +371,7 @@ ...@@ -204,7 +371,7 @@
// if server validation of form data failed (indicated by response code 400) // if server validation of form data failed (indicated by response code 400)
// we parse out field errors and display them to the user // we parse out field errors and display them to the user
if (error.target.status === 400) { if (error.target.status === 400) {
promise promise_queue
.push(function () { .push(function () {
// when the server-side validation returns the error description // when the server-side validation returns the error description
if (error.target.responseType === "blob") { if (error.target.responseType === "blob") {
...@@ -217,210 +384,12 @@ ...@@ -217,210 +384,12 @@
return form_gadget.displayFormulatorValidationError(JSON.parse(event.target.result)); return form_gadget.displayFormulatorValidationError(JSON.parse(event.target.result));
}); });
} }
return promise; return promise_queue;
} }
throw error; 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) { }, false, true);
if (view_list[i].href === this.state.view) {
title = view_list[i].title;
}
}
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)); }(window, rJS, RSVP, URI, calculatePageTitle, Blob, URL, document, jIO, ensureArray));
\ No newline at end of file \ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.10338.33096.47104</string> </value> <value> <string>965.12033.58825.17254</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1517305313.45</float> <float>1517406854.12</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -21,13 +21,13 @@ ...@@ -21,13 +21,13 @@
.push(function (declared_gadget) { .push(function (declared_gadget) {
return declared_gadget.checkValidity(); return declared_gadget.checkValidity();
}); });
}, {mutex: 'changestate'}) })
.declareMethod('getContent', function () { .declareMethod('getContent', function () {
return this.getDeclaredGadget("erp5_form") return this.getDeclaredGadget("erp5_form")
.push(function (declared_gadget) { .push(function (declared_gadget) {
return declared_gadget.getContent(); return declared_gadget.getContent();
}); });
}, {mutex: 'changestate'}) })
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// declared methods // declared methods
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -101,7 +101,9 @@ ...@@ -101,7 +101,9 @@
new_content_action, new_content_action,
form_gadget.getUrlFor({command: 'change', options: {page: "action"}}), form_gadget.getUrlFor({command: 'change', options: {page: "action"}}),
form_gadget.getUrlFor({command: 'display', options: {}}), 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"}}) : form_gadget.getUrlFor({command: 'change', options: {page: "export"}}) :
"", "",
calculatePageTitle(form_gadget, form_gadget.state.erp5_document) calculatePageTitle(form_gadget, form_gadget.state.erp5_document)
...@@ -150,7 +152,7 @@ ...@@ -150,7 +152,7 @@
focus_on: focus_on focus_on: focus_on
}); });
}); });
}, {mutex: 'changestate'}) })
.onEvent('submit', function () { .onEvent('submit', function () {
var gadget = this; var gadget = this;
......
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.45640.391.48230</string> </value> <value> <string>964.64570.61398.48110</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516351087.15</float> <float>1516871753.89</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -26,13 +26,13 @@ ...@@ -26,13 +26,13 @@
.push(function (declared_gadget) { .push(function (declared_gadget) {
return declared_gadget.checkValidity(); return declared_gadget.checkValidity();
}); });
}, {mutex: 'changestate'}) })
.declareMethod('getContent', function () { .declareMethod('getContent', function () {
return this.getDeclaredGadget("erp5_form") return this.getDeclaredGadget("erp5_form")
.push(function (declared_gadget) { .push(function (declared_gadget) {
return declared_gadget.getContent(); return declared_gadget.getContent();
}); });
}, {mutex: 'changestate'}) })
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// declared methods // declared methods
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
......
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.45640.391.48230</string> </value> <value> <string>962.4168.39270.46967</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516351216.09</float> <float>1514542029.91</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -14,13 +14,13 @@ ...@@ -14,13 +14,13 @@
.push(function (declared_gadget) { .push(function (declared_gadget) {
return declared_gadget.checkValidity(); return declared_gadget.checkValidity();
}); });
}, {mutex: 'changestate'}) })
.declareMethod('getContent', function () { .declareMethod('getContent', function () {
return this.getDeclaredGadget("erp5_form") return this.getDeclaredGadget("erp5_form")
.push(function (declared_gadget) { .push(function (declared_gadget) {
return declared_gadget.getContent(); return declared_gadget.getContent();
}); });
}, {mutex: 'changestate'}) })
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// declared methods // declared methods
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
form_options.editable = form_gadget.state.editable; form_options.editable = form_gadget.state.editable;
return erp5_form.render(form_options); return erp5_form.render(form_options);
}); })
}); });
}(window, rJS)); }(window, rJS));
\ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>963.11788.48702.26146</string> </value> <value> <string>961.56888.60131.33518</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516351314.5</float> <float>1504617145.02</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -35,13 +35,13 @@ ...@@ -35,13 +35,13 @@
.push(function (declared_gadget) { .push(function (declared_gadget) {
return declared_gadget.checkValidity(); return declared_gadget.checkValidity();
}); });
}, {mutex: 'changestate'}) })
.declareMethod('getContent', function () { .declareMethod('getContent', function () {
return this.getDeclaredGadget("erp5_form") return this.getDeclaredGadget("erp5_form")
.push(function (declared_gadget) { .push(function (declared_gadget) {
return declared_gadget.getContent(); return declared_gadget.getContent();
}); });
}, {mutex: 'changestate'}) })
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// declared methods // declared methods
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -99,7 +99,9 @@ ...@@ -99,7 +99,9 @@
gadget.getUrlFor({command: 'selection_previous'}), gadget.getUrlFor({command: 'selection_previous'}),
gadget.getUrlFor({command: 'selection_next'}), gadget.getUrlFor({command: 'selection_next'}),
gadget.getUrlFor({command: 'change', options: {page: "tab"}}), 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"}}) : gadget.getUrlFor({command: 'change', options: {page: "export"}}) :
"", "",
calculatePageTitle(gadget, gadget.state.erp5_document) calculatePageTitle(gadget, gadget.state.erp5_document)
......
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.58561.19908.14080</string> </value> <value> <string>964.64570.61398.48110</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516351419.44</float> <float>1516872328.37</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -55,10 +55,7 @@ ...@@ -55,10 +55,7 @@
name: field_json.key, name: field_json.key,
title: field_json.title, title: field_json.title,
item_list: field_json.items, item_list: field_json.items,
hidden: field_json.hidden, hidden: field_json.hidden
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
}; };
//the first item will always be selected if no initial default value is supplied. //the first item will always be selected if no initial default value is supplied.
...@@ -163,5 +160,5 @@ ...@@ -163,5 +160,5 @@
}); });
} }
return final_result; return final_result;
}, {mutex: 'changestate'}); });
}(window, rJS, RSVP)); }(window, rJS, RSVP));
\ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value> <value> <string>954.58788.30707.10649</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1517321388.02</float> <float>1479375435.94</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -145,17 +145,7 @@ ...@@ -145,17 +145,7 @@
value_uid: options.value_uid, value_uid: options.value_uid,
value_text: options.value_text, value_text: options.value_text,
value_portal_type: options.value_portal_type 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); return this.changeState(state_dict);
}) })
...@@ -309,8 +299,7 @@ ...@@ -309,8 +299,7 @@
] ]
})), })),
limit: [0, 10], limit: [0, 10],
select_list: [gadget.state.catalog_index, "uid"], select_list: [gadget.state.catalog_index, "uid"]
sort_on: JSON.parse(gadget.state.sort_list_json)
}); });
}) })
.push(function (result) { .push(function (result) {
...@@ -365,7 +354,7 @@ ...@@ -365,7 +354,7 @@
}; };
} }
return result; return result;
}, {mutex: 'changestate'}) })
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
......
...@@ -236,7 +236,7 @@ ...@@ -236,7 +236,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.15380.34560.33723</string> </value> <value> <string>964.8568.54116.8601</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -254,7 +254,7 @@ ...@@ -254,7 +254,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516352011.0</float> <float>1513266821.11</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
var render_options = { var render_options = {
editable: field_json.editable, editable: field_json.editable,
query: field_json.query, query: field_json.query,
sort_list_json: JSON.stringify(field_json.sort),
catalog_index: field_json.catalog_index, catalog_index: field_json.catalog_index,
allow_jump: field_json.allow_jump, allow_jump: field_json.allow_jump,
// required: field_json.required, // required: field_json.required,
...@@ -85,6 +84,6 @@ ...@@ -85,6 +84,6 @@
} }
return result; return result;
}); });
}, {mutex: 'changestate'}); });
}(window, rJS)); }(window, rJS));
\ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>963.11788.48702.26146</string> </value> <value> <string>958.19776.55952.3225</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516352110.99</float> <float>1490691939.14</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -193,7 +193,7 @@ ...@@ -193,7 +193,7 @@
return content_dict; return content_dict;
}); });
}, {mutex: 'changestate'}) })
.declareAcquiredMethod("triggerSubmit", "triggerSubmit") .declareAcquiredMethod("triggerSubmit", "triggerSubmit")
.onEvent('click', function (evt) { .onEvent('click', function (evt) {
......
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>963.65076.53120.24439</string> </value> <value> <string>963.59679.1954.25241</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516352207.94</float> <float>1512408075.41</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -17,10 +17,7 @@ ...@@ -17,10 +17,7 @@
name: field_json.key, name: field_json.key,
title: field_json.title, title: field_json.title,
hidden: field_json.hidden, hidden: field_json.hidden,
trim: true, trim: true
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
}; };
state_dict.text_content = state_dict.value; state_dict.text_content = state_dict.value;
return this.changeState(state_dict); return this.changeState(state_dict);
...@@ -61,7 +58,7 @@ ...@@ -61,7 +58,7 @@
.push(function (gadget) { .push(function (gadget) {
return gadget.getContent(); return gadget.getContent();
}); });
}, {mutex: 'changestate'}) })
.declareMethod('checkValidity', function () { .declareMethod('checkValidity', function () {
if (this.state.editable) { if (this.state.editable) {
...@@ -71,6 +68,6 @@ ...@@ -71,6 +68,6 @@
}); });
} }
return true; return true;
}, {mutex: 'changestate'}); });
}(window, rJS)); }(window, rJS));
\ No newline at end of file
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.64440.33953.5239</string> </value> <value> <string>960.5523.58984.43537</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516627821.55</float> <float>1503499581.59</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -14,10 +14,7 @@ ...@@ -14,10 +14,7 @@
editable: field_json.editable, editable: field_json.editable,
name: field_json.key, name: field_json.key,
title: field_json.title, title: field_json.title,
hidden: field_json.hidden, hidden: field_json.hidden
// Force calling subfield render
// as user may have modified the input value
render_timestamp: new Date().getTime()
}; };
state_dict.text_content = state_dict.value; state_dict.text_content = state_dict.value;
return this.changeState(state_dict); return this.changeState(state_dict);
...@@ -58,7 +55,7 @@ ...@@ -58,7 +55,7 @@
.push(function (subgadget) { .push(function (subgadget) {
return subgadget.checkValidity(); return subgadget.checkValidity();
}); });
}, {mutex: 'changestate'}) })
.declareMethod('getContent', function () { .declareMethod('getContent', function () {
if (this.state.editable) { if (this.state.editable) {
...@@ -68,6 +65,6 @@ ...@@ -68,6 +65,6 @@
}); });
} }
return {}; return {};
}, {mutex: 'changestate'}); });
}(window, rJS)); }(window, rJS));
\ No newline at end of file
...@@ -236,7 +236,7 @@ ...@@ -236,7 +236,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>965.241.13759.3805</string> </value> <value> <string>960.5523.58984.43537</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -254,7 +254,7 @@ ...@@ -254,7 +254,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1517321833.44</float> <float>1511311791.54</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -149,7 +149,7 @@ ...@@ -149,7 +149,7 @@
// (as ERP5 does in case of formulator error) // (as ERP5 does in case of formulator error)
this.state.value = result[input.getAttribute('name')]; this.state.value = result[input.getAttribute('name')];
return result; return result;
}, {mutex: 'changestate'}) })
.declareAcquiredMethod("notifyValid", "notifyValid") .declareAcquiredMethod("notifyValid", "notifyValid")
.declareMethod('checkValidity', function () { .declareMethod('checkValidity', function () {
...@@ -180,7 +180,7 @@ ...@@ -180,7 +180,7 @@
}); });
} }
return result; return result;
}, {mutex: 'changestate'}) })
.declareAcquiredMethod("notifyChange", "notifyChange") .declareAcquiredMethod("notifyChange", "notifyChange")
.onEvent('change', function () { .onEvent('change', function () {
......
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.58989.24664.17868</string> </value> <value> <string>963.50704.60870.52872</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516352669.6</float> <float>1511969724.67</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/*global window, rJS, RSVP, Handlebars */ /*global window, rJS, RSVP, Handlebars, getFirstNonEmpty */
/*jslint indent: 2, maxerr: 3, maxlen: 80, nomen: true */ /*jslint indent: 2, maxerr: 3, maxlen: 80, nomen: true */
(function (window, rJS, RSVP, Handlebars) { (function (window, rJS, RSVP, Handlebars, getFirstNonEmpty) {
"use strict"; "use strict";
// How to change html selected option using JavaScript? // How to change html selected option using JavaScript?
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
.declareMethod('render', function (options) { .declareMethod('render', function (options) {
var state_dict = { var state_dict = {
value: options.value || "", value: getFirstNonEmpty(options.value, ""),
item_list: JSON.stringify(options.item_list), item_list: JSON.stringify(options.item_list),
editable: options.editable, editable: options.editable,
required: options.required, required: options.required,
...@@ -107,11 +107,6 @@ ...@@ -107,11 +107,6 @@
if (this.state.editable) { if (this.state.editable) {
result[select.getAttribute('name')] = result[select.getAttribute('name')] =
select.options[select.selectedIndex].value; 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; return result;
}) })
...@@ -148,4 +143,4 @@ ...@@ -148,4 +143,4 @@
return this.notifyInvalid(evt.target.validationMessage); return this.notifyInvalid(evt.target.validationMessage);
}, true, false); }, true, false);
}(window, rJS, RSVP, Handlebars)); }(window, rJS, RSVP, Handlebars, getFirstNonEmpty));
\ No newline at end of file \ No newline at end of file
...@@ -97,12 +97,6 @@ ...@@ -97,12 +97,6 @@
<none/> <none/>
</value> </value>
</item> </item>
<item>
<key> <string>subject</string> </key>
<value>
<tuple/>
</value>
</item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Gadget HTML5 Select JS</string> </value> <value> <string>Gadget HTML5 Select JS</string> </value>
...@@ -236,7 +230,7 @@ ...@@ -236,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>963.62584.36941.22510</string> </value> <value> <string>965.10979.12054.27869</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -254,7 +248,7 @@ ...@@ -254,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516785191.79</float> <float>1517406671.4</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
/*globals window*/ /*globals window*/
/*jslint indent: 2, nomen: true, maxlen: 80*/ /*jslint indent: 2, nomen: true, maxlen: 80*/
(function (window) { (function (window) {
"use strict"; "use strict";
window.translation_data = { 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)); }(window));
\ No newline at end of file
...@@ -220,7 +220,7 @@ ...@@ -220,7 +220,7 @@
</item> </item>
<item> <item>
<key> <string>actor</string> </key> <key> <string>actor</string> </key>
<value> <string>romain</string> </value> <value> <string>zope</string> </value>
</item> </item>
<item> <item>
<key> <string>comment</string> </key> <key> <string>comment</string> </key>
...@@ -234,7 +234,7 @@ ...@@ -234,7 +234,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>946.45868.14105.29764</string> </value> <value> <string>962.22770.22235.8550</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -252,8 +252,8 @@ ...@@ -252,8 +252,8 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1445935505.72</float> <float>1516717586.21</float>
<string>GMT</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
</object> </object>
......
...@@ -665,58 +665,7 @@ if (typeof document.contains !== 'function') { ...@@ -665,58 +665,7 @@ if (typeof document.contains !== 'function') {
return this.documentElement.contains(node); return this.documentElement.contains(node);
} }
} }
;(function (DOMParser) { ;/*! RenderJs */
"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 */
/*jslint nomen: true*/ /*jslint nomen: true*/
/* /*
...@@ -860,7 +809,6 @@ if (typeof document.contains !== 'function') { ...@@ -860,7 +809,6 @@ if (typeof document.contains !== 'function') {
gadget_loading_klass_list = [], gadget_loading_klass_list = [],
renderJS, renderJS,
Monitor, Monitor,
Mutex,
scope_increment = 0, scope_increment = 0,
isAbsoluteOrDataURL = new RegExp('^(?:[a-z]+:)?//|data:', 'i'), isAbsoluteOrDataURL = new RegExp('^(?:[a-z]+:)?//|data:', 'i'),
is_page_unloaded = false, is_page_unloaded = false,
...@@ -877,64 +825,6 @@ if (typeof document.contains !== 'function') { ...@@ -877,64 +825,6 @@ if (typeof document.contains !== 'function') {
is_page_unloaded = true; 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 // Helper functions
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -1361,26 +1251,15 @@ if (typeof document.contains !== 'function') { ...@@ -1361,26 +1251,15 @@ if (typeof document.contains !== 'function') {
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// RenderJSGadget.declareMethod // RenderJSGadget.declareMethod
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
RenderJSGadget.declareMethod = function declareMethod(name, callback, RenderJSGadget.declareMethod = function declareMethod(name, callback) {
options) {
this.prototype[name] = function triggerMethod() { this.prototype[name] = function triggerMethod() {
var context = this, var context = this,
argument_list = arguments, argument_list = arguments;
mutex_name;
function waitForMethodCallback() {
return callback.apply(context, argument_list);
}
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() return new RSVP.Queue()
.push(waitForMethodCallback); .push(function waitForMethodCallback() {
return callback.apply(context, argument_list);
});
}; };
// Allow chain // Allow chain
return this; return this;
...@@ -1416,8 +1295,24 @@ if (typeof document.contains !== 'function') { ...@@ -1416,8 +1295,24 @@ if (typeof document.contains !== 'function') {
return this.element; return this.element;
}) })
.declareMethod('changeState', function changeState(state_dict) { .declareMethod('changeState', function changeState(state_dict) {
var context = this, var next_onStateChange = new RSVP.Queue(),
key, 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, modified = false,
previous_cancelled = context.hasOwnProperty('__modification_dict'), previous_cancelled = context.hasOwnProperty('__modification_dict'),
modification_dict; modification_dict;
...@@ -1446,7 +1341,8 @@ if (typeof document.contains !== 'function') { ...@@ -1446,7 +1341,8 @@ if (typeof document.contains !== 'function') {
return result; return result;
}); });
} }
}, {mutex: 'changestate'}); });
});
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// RenderJSGadget.declareAcquiredMethod // RenderJSGadget.declareAcquiredMethod
...@@ -2142,7 +2038,6 @@ if (typeof document.contains !== 'function') { ...@@ -2142,7 +2038,6 @@ if (typeof document.contains !== 'function') {
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// global // global
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
renderJS.Mutex = Mutex;
window.rJS = window.renderJS = renderJS; window.rJS = window.renderJS = renderJS;
window.__RenderJSGadget = RenderJSGadget; window.__RenderJSGadget = RenderJSGadget;
window.__RenderJSEmbeddedGadget = RenderJSEmbeddedGadget; window.__RenderJSEmbeddedGadget = RenderJSEmbeddedGadget;
......
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>964.57262.9791.60330</string> </value> <value> <string>962.24020.58652.57139</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1516196938.48</float> <float>1508945098.52</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -309,6 +309,7 @@ ...@@ -309,6 +309,7 @@
<value> <value>
<tuple> <tuple>
<string>en</string> <string>en</string>
<string>wo</string>
</tuple> </tuple>
</value> </value>
</item> </item>
......
...@@ -655,14 +655,7 @@ div[data-gadget-scope='panel'] { ...@@ -655,14 +655,7 @@ div[data-gadget-scope='panel'] {
.linkpanel() { .linkpanel() {
color: @white; color: @white;
display: block; display: block;
// Define .active before :hover to ensure it hover is displayed &:hover, &:active, &.active {
// for the .active entry
&.active {
color: @colorforeground;
background-color: @colorbackground;
}
&:hover, &:active {
color: @white;
background-color: darken(@panelbackgroundcolor, 10%); background-color: darken(@panelbackgroundcolor, 10%);
} }
} }
...@@ -1112,12 +1105,17 @@ div[data-gadget-scope='header'] .ui-header { ...@@ -1112,12 +1105,17 @@ div[data-gadget-scope='header'] .ui-header {
/********************************************** /**********************************************
* Gadget: main * Gadget: main
**********************************************/ **********************************************/
.renderPageSubmitButton(@backgroundcolor) { .gadget-content {
div[data-gadget-scope='m'] {
animation: fadein @transition-timing;
}
input[type='submit'] {
padding: @margin-size; padding: @margin-size;
margin-top: @headerheight; margin-top: @headerheight;
margin-right: @double-margin-size; margin-right: @double-margin-size;
background-color: @backgroundcolor; background-color: @coloraccent;
color: @white; color: @white;
border-radius: @radius; border-radius: @radius;
...@@ -1127,26 +1125,13 @@ div[data-gadget-scope='header'] .ui-header { ...@@ -1127,26 +1125,13 @@ div[data-gadget-scope='header'] .ui-header {
min-width: 8em; min-width: 8em;
&:hover, &:focus { &:hover, &:focus {
background-color: lighten(@backgroundcolor, 10%); background-color: lighten(@coloraccent, 10%);
} }
&:active { &: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 { @media @desktop {
div[data-role='page']:not(.desktop-panel-hidden) & { div[data-role='page']:not(.desktop-panel-hidden) & {
...@@ -1176,17 +1161,28 @@ div[data-gadget-scope='header'] .ui-header { ...@@ -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! & > label {
It is used to force horizontal rendering of fields inside FormBox. padding-top: @margin-size + @half-margin-size;
The first > div represents form-group ("left", "right" ...) */ }
}
.field_container > div {
// matches form-group ("left", "right" ...)
display: flex; display: flex;
& > div { & > div {
flex: 1; flex: 1;
} }
} }
}
.ui-content-header-plain { .ui-content-header-plain {
font-size: 150%; font-size: 150%;
...@@ -1287,6 +1283,9 @@ div[data-gadget-scope='header'] .ui-header { ...@@ -1287,6 +1283,9 @@ div[data-gadget-scope='header'] .ui-header {
& > label { & > label {
color: @grey; color: @grey;
// padding to be aligned with <input>
padding: @half-margin-size;
// backward-compatibility: support for ERP5 field class defined in formulator configuration // backward-compatibility: support for ERP5 field class defined in formulator configuration
&.required { &.required {
// inform user that the field is needed by contraint, but do not prevent him to save the value // 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 { ...@@ -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 { @media @tablet, @desktop {
.ui-field-contain { .ui-field-contain {
display: flex; 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 @@ ...@@ -25,7 +25,7 @@
<td>renderjs_url</td></tr> <td>renderjs_url</td></tr>
<tr><td>open</td> <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> <tr><td>assertTextPresent</td>
<td>Created Successfully.</td><td></td></tr> <td>Created Successfully.</td><td></td></tr>
<tr><td>open</td> <tr><td>open</td>
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>testDisplayWithAndWithoutTimeZone</string> </value> <value> <string>testFastSave</string> </value>
</item> </item>
<item> <item>
<key> <string>output_encoding</string> </key> <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 @@ ...@@ -37,7 +37,7 @@
<tr> <tr>
<td>open</td> <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> <td></td>
</tr> </tr>
...@@ -66,14 +66,14 @@ ...@@ -66,14 +66,14 @@
<!-- check quanlity is display correctly --> <!-- check quanlity is display correctly -->
<tr> <tr>
<td>waitForElementPresent</td> <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> <td></td>
</tr> </tr>
<tr> <tr>
<td>verifyElementPresent</td> <td>verifyElementPresent</td>
<td>//a[@class='ui-link' and text() ='1']</td> <td>//a[@class='ui-link']//p[text()='1']</td>
<td></td> <td></td>
</tr> </tr>
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>testRelationDefaultSortAndParameterList</string> </value> <value> <string>testListBoxBasics</string> </value>
</item> </item>
<item> <item>
<key> <string>output_encoding</string> </key> <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 @@ ...@@ -42,7 +42,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>testRestoreDateTimeValueIfValidationError</string> </value> <value> <string>testSelectionColumnsPrecedence</string> </value>
</item> </item>
<item> <item>
<key> <string>output_encoding</string> </key> <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 @@ ...@@ -42,7 +42,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>testMultiRelationDefaultSortAndParameterList</string> </value> <value> <string>testTemplateFieldBackwardCompatibility</string> </value>
</item> </item>
<item> <item>
<key> <string>output_encoding</string> </key> <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 @@ ...@@ -22,6 +22,16 @@
<td>Reset Successfully.</td> <td>Reset Successfully.</td>
<td></td> <td></td>
</tr> </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 --> <!-- Initialize -->
<tr> <tr>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>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 @@ ...@@ -153,30 +153,6 @@
</tr> </tr>
</tal:block> </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"> <tal:block metal:define-macro="search_in_form_list">
<tr> <tr>
<td colspan="3"><b tal:content="python: 'Submit a form list search: %s' % search_query"></b></td> <td colspan="3"><b tal:content="python: 'Submit a form list search: %s' % search_query"></b></td>
...@@ -866,23 +842,4 @@ ...@@ -866,23 +842,4 @@
</tr> </tr>
</tal:block> </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> </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