Commit d06674a2 authored by Romain Courteaud's avatar Romain Courteaud

erp5_web_renderjs_ui: router: do not crash when navigating back to an hidden view

Some erp5 view action use a TALES expression to be visible only in draft state.
When validation a workflow transition dialog, ERP5JS tries to go back to the previous view which is now hidden.

In such case, switch back to the default document view.
parent bb9765da
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_view</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_view</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>view_draft</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Action Information</string> </value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>20.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>View Draft</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/Foo_view</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>python: object.getSimulationState() == \'draft\'</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -41,6 +41,7 @@ Foo | view_crash_on_save ...@@ -41,6 +41,7 @@ Foo | view_crash_on_save
Foo | view_developer_mode_action Foo | view_developer_mode_action
Foo | view_dialog_with_only_update Foo | view_dialog_with_only_update
Foo | view_dialog_with_validation_error Foo | view_dialog_with_validation_error
Foo | view_draft
Foo | view_duration_field Foo | view_duration_field
Foo | view_editor_field Foo | view_editor_field
Foo | view_float_field Foo | view_float_field
......
...@@ -224,6 +224,16 @@ and handling data send&receive. ...@@ -224,6 +224,16 @@ and handling data send&receive.
} }
return result; return result;
}) })
.push(undefined, function (error) {
if ((error instanceof jIO.util.jIOError) &&
(error.status_code === 404) &&
(options.is_cancelled)) {
// If the view does not exist when coming back with the navigation history
// Switch back to the default view
return {};
}
throw error;
})
.push(function (result) { .push(function (result) {
new_state.erp5_document = result; new_state.erp5_document = result;
......
...@@ -234,7 +234,7 @@ ...@@ -234,7 +234,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>987.8562.40237.45909</string> </value> <value> <string>991.63595.43060.43997</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>1602064490.97</float> <float>1620724931.09</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -556,6 +556,8 @@ ...@@ -556,6 +556,8 @@
var next_options; var next_options;
if (previous_options.hasOwnProperty('cancel')) { if (previous_options.hasOwnProperty('cancel')) {
next_options = JSON.parse(previous_options.cancel); next_options = JSON.parse(previous_options.cancel);
// cancel may be outdated
gadget.props.is_cancelled = true;
} else { } else {
next_options = {jio_key: previous_options.jio_key}; next_options = {jio_key: previous_options.jio_key};
} }
...@@ -1167,9 +1169,13 @@ ...@@ -1167,9 +1169,13 @@
.push(function (route_result) { .push(function (route_result) {
if ((route_result !== undefined) && (route_result.url !== undefined)) { if ((route_result !== undefined) && (route_result.url !== undefined)) {
gadget.props.modified = false; gadget.props.modified = false;
if (gadget.props.is_cancelled) {
route_result.options.is_cancelled = true;
}
return gadget.renderApplication(route_result, gadget.props.keep_message) return gadget.renderApplication(route_result, gadget.props.keep_message)
.push(function (result) { .push(function (result) {
gadget.props.keep_message = false; gadget.props.keep_message = false;
gadget.props.is_cancelled = false;
return result; return result;
}); });
} }
......
...@@ -236,7 +236,7 @@ ...@@ -236,7 +236,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>991.63474.14071.31470</string> </value> <value> <string>991.63596.55319.30839</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>1620656308.36</float> <float>1620663195.92</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
<?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>testPageAccessViewNotExist</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 Page Front</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test Page Draft View Fallback</td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/PTZuite_CommonTemplate/macros/init" />
<tr>
<td>open</td>
<td>${base_url}/web_site_module/renderjs_runner/#/foo_module/1?view=${base_url}%2Fweb_site_module%2Frenderjs_runner%2Fhateoas%2FERP5Document_getHateoas%3Fmode%3Dtraverse%26relative_url%3Dfoo_module%252F1%26view%3Dnot_existing_view</td>
<td></td>
</tr>
<tr>
<td>waitForTextPresent</td>
<td>Cannot find attachment: ${base_url}/web_site_module/renderjs_runner/hateoas/ERP5Document_getHateoas?mode=traverse</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>view=not_existing_view</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>testPageDraftViewValidation</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 Page Front</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test Page Draft View Fallback</td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/PTZuite_CommonTemplate/macros/init" />
<tr>
<td>open</td>
<td>${base_url}/web_site_module/renderjs_runner/#/foo_module/1?view=view</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_app_loaded" />
<tr>
<td>assertElementPresent</td>
<td>//a[contains(text(), "View Draft")]</td>
<td></td>
</tr>
<tr>
<td colspan="3"><tal:block tal:define="click_configuration python: {'text': 'View Draft'}"> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/click_on_panel_link" /> </tal:block></td>
</tr>
<tr>
<td colspan="3"><tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded"> </tal:block></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/open_menu_panel" />
<tr>
<td>assertElementPresent</td>
<td>//div[@data-gadget-scope='panel']//a[text()='View Draft' and contains(@class, 'active')]</td>
<td></td>
</tr>
<tr>
<td colspan="3"><tal:block tal:define="click_configuration python: {'text': 'Validate Action'}"> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/click_on_panel_link" /> </tal:block></td>
</tr>
<tr>
<td colspan="3"><tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_dialog"> </tal:block></td>
</tr>
<tal:block tal:define="notification_configuration python: {'class': 'success',
'text': 'Status changed.'}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_notification" />
</tal:block>
<!-- Action does not exist, page_form redirect to the default view -->
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_no_notification" />
<tr>
<td colspan="3"><tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded"> </tal:block></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/open_menu_panel" />
<tr>
<td>assertElementPresent</td>
<td>//div[@data-gadget-scope='panel']//a[text()='View' and contains(@class, 'active')]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//p[text()="Title 1"]</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
...@@ -1242,6 +1242,25 @@ ...@@ -1242,6 +1242,25 @@
</tr> </tr>
</tal:block> </tal:block>
<tal:block metal:define-macro="wait_for_no_notification">
<tr>
<td colspan="3"><b>Wait for the notification message to be hidden</b></td>
</tr>
<tr>
<td>waitForElementNotPresent</td>
<td>//div[@data-gadget-scope='notification' and @class='visible']</td>
<td></td>
</tr>
<tr>
<td>assertElementNotPresent</td>
<td>//div[@data-gadget-scope='notification' and @class='visible']</td>
<td></td>
</tr>
<tr>
<td colspan="3"><p></p></td>
</tr>
</tal:block>
<tal:block metal:define-macro="verify_ckeditor_text_content"><tal:comment tal:replace="nothing"><!-- <tal:block metal:define-macro="verify_ckeditor_text_content"><tal:comment tal:replace="nothing"><!--
this macro needs globals: text_content this macro needs globals: text_content
......
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