Commit 2789ebc9 authored by Tomáš Peterka's avatar Tomáš Peterka

[hal_json_style+renderjs_ui] Support Print actions

parent 61dcd60d
...@@ -252,7 +252,6 @@ if True: ...@@ -252,7 +252,6 @@ if True:
# now get dialog_method after skin re-selection and dialog_method mingling # now get dialog_method after skin re-selection and dialog_method mingling
dialog_form = getattr(context, dialog_method) dialog_form = getattr(context, dialog_method)
# XXX: this is a hack that should not be needed anymore with the new listbox. # XXX: this is a hack that should not be needed anymore with the new listbox.
# set the URL in request, so that we can immediatly call method # set the URL in request, so that we can immediatly call method
# that depend on it (eg. Show All). This is really related to # that depend on it (eg. Show All). This is really related to
...@@ -268,9 +267,19 @@ if True: ...@@ -268,9 +267,19 @@ if True:
# RJS: If skin selection is different than Hal* then ERP5Document_getHateoas # RJS: If skin selection is different than Hal* then ERP5Document_getHateoas
# 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 update_method was clicked and the target is the original dialog form then we must not call dialog_form directly because it returns HTML
if clean_kw.get("portal_skin", context.getPortalObject().portal_skins.getDefaultSkin()) not in ("Hal", "HalRestricted", "View"):
return dialog_form(**kw) return dialog_form(**kw)
# dialog_form can be anything from a pure python function, class method to ERP5 Form or Python Script
try:
meta_type = dialog_form.meta_type
except AttributeError:
meta_type = ""
if meta_type in ("ERP5 Form", "ERP5 Report"):
return context.ERP5Document_getHateoas(REQUEST=request, form=dialog_form, mode="form") return context.ERP5Document_getHateoas(REQUEST=request, form=dialog_form, mode="form")
return dialog_form(**kw)
return getattr(context, dialog_method)(**kw) return getattr(context, dialog_method)(**kw)
<?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_jio_print</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_jio_print</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </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_print_dialog</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>11.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>View Print Dialog</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_viewPrintDialog</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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> <string></string> </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_printout_form</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>11.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>View Printout Form</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_viewPrintoutForm</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
# This script simulates a standard Print action
#
# Print action expects the previous view to be accessible in `form_id`
# and it prints it out in both UI compatible way - as a redirect message.
context.REQUEST.form['last_form_id'] = form_id
return context.Base_renderForm('Foo_viewPrintoutForm')
<?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, **kwargs</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Foo_printLastViewName</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string>Foo_viewPrintoutForm</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Just a middle step between Print action and Print Form</string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>your_print_format</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Foo_viewPrintDialog</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>Foo_viewPrintDialog</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_dialog</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Print</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>last_form_id</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Foo_viewPrintoutForm</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>Foo_viewPrintoutForm</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="LabelField" module="Products.Formulator.StandardFields"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>last_form_id</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Last FormID</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: here.REQUEST.form.get(\'form_id\', \'No Last FormID\')</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -34,5 +34,7 @@ Foo | view_hidden_positive_only_quantity ...@@ -34,5 +34,7 @@ Foo | view_hidden_positive_only_quantity
Foo | view_listbox Foo | view_listbox
Foo | view_multiple_listbox Foo | view_multiple_listbox
Foo | view_planning Foo | view_planning
Foo | view_print_dialog
Foo | view_printout_form
Foo | view_proxy_field Foo | view_proxy_field
Foo | view_relation_field Foo | view_relation_field
\ No newline at end of file
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
"use strict"; "use strict";
/** Return true if `field` resembles non-empty and non-editable field. */ /** Return true if `field` resembles non-empty and non-editable field. */
function isGoodNonEditableField(field) { function isNonEmptyNonEditableField(field) {
if (field === undefined || field === null) {return false; } if (field === undefined || field === null) {return false; }
// ListBox and FormBox should always get a chance to render because they // ListBox and FormBox should always get a chance to render because they
// can contain editable fields // can contain editable fields
...@@ -64,23 +64,28 @@ ...@@ -64,23 +64,28 @@
// render the erp5 form // render the erp5 form
return this.getDeclaredGadget("erp5_form") return this.getDeclaredGadget("erp5_form")
.push(function (erp5_form) { .push(function (embedded_form_gadget) {
var form_options = gadget.state.erp5_form, var form_options = gadget.state.erp5_form,
rendered_form = gadget.state.erp5_document._embedded._view, embedded_form = gadget.state.erp5_document._embedded._view,
key; rendered_form = {},
key, field;
/* Remove empty non-editable fields to prevent them from displaying (business requirement). /* Remove empty non-editable fields to prevent them from displaying (business requirement).
Deleting objects inplace does not seem to be a good idea. Deleting objects inplace was not a good idea.
So we pass through only non-empty (non-editable) fields.
*/ */
for (key in rendered_form) { for (key in embedded_form) {
if (rendered_form.hasOwnProperty(key) && (key[0] !== "_")) { if (key[0] !== "_" && embedded_form.hasOwnProperty(key)) {
if (!isGoodNonEditableField(rendered_form[key])) { if (isNonEmptyNonEditableField(embedded_form[key])) {
delete rendered_form[key]; rendered_form[key] = embedded_form[key];
} }
} }
} }
form_options.erp5_document = {
form_options.erp5_document = gadget.state.erp5_document; "_embedded": {
"_view": rendered_form
}
};
form_options.form_definition = gadget.state.form_definition; form_options.form_definition = gadget.state.form_definition;
form_options.view = gadget.state.view; form_options.view = gadget.state.view;
form_options.title = gadget.state.title; form_options.title = gadget.state.title;
...@@ -88,7 +93,7 @@ ...@@ -88,7 +93,7 @@
form_options.editable = 0; // because for editable=1 there is a special form_options.editable = 0; // because for editable=1 there is a special
// page template 'pt_form_editable'. Once it is // page template 'pt_form_editable'. Once it is
// is removed, this 0 should turn into gadget.state.editable // is removed, this 0 should turn into gadget.state.editable
return erp5_form.render(form_options); return embedded_form_gadget.render(form_options);
}) })
// render the header // render the header
...@@ -100,7 +105,8 @@ ...@@ -100,7 +105,8 @@
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_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),
......
<?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 Action following <a href="https://www.erp5.com/documentation/developer/howto/erp5-developer-howto/erp5-Guideline.Never.Print.Directly">Guideline</a></td></tr>
</thead><tbody>
<tal:block metal:use-macro="here/PTZuite_CommonTemplate/macros/init" />
<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 colspan="3"><b>Go to relation field view</b></td></tr>
<tr><td>waitForElementPresent</td>
<td>//div[contains(@class, 'ui-header')]//a[@data-i18n='Views']</td><td></td></tr>
<tr><td>click</td>
<td>//div[contains(@class, 'ui-header')]//a[@data-i18n='Views']</td><td></td></tr>
<tr><td>waitForElementPresent</td>
<td>//ul[@class='document-listview']//a[@data-i18n='Relation Fields']</td><td></td></tr>
<tr><td>click</td>
<td>//ul[@class='document-listview']//a[@data-i18n='Relation Fields']</td><td></td></tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tr><td>waitForElementPresent</td>
<td>//a[@data-i18n='Export']</td><td></td></tr>
<tr><td>click</td>
<td>//a[@data-i18n='Export']</td><td></td></tr>
<tr><td>waitForElementPresent</td>
<td>//h3[text()='Print']</td><td></td></tr>
<tr><td>waitForElementPresent</td>
<td>//a[@data-i18n='View Print Dialog']</td><td></td></tr>
<tr><td>click</td>
<td>//a[@data-i18n='View Print Dialog']</td><td></td></tr>
<tr><td>waitForElementPresent</td>
<td>//div[@role="main"]//input[@type='submit']</td><td></td></tr>
<tr><td>click</td>
<td>//div[@role="main"]//input[@type='submit']</td><td></td></tr>
<tr><td>waitForElementPresent</td>
<td>//p[@id='field_last_form_id']</td><td></td></tr>
<tr><td>assertText</td>
<td>//p[@id='field_last_form_id']</td>
<td>Foo_viewRelationField</td></tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
...@@ -52,7 +52,7 @@ def addDialogIfNeeded(url): ...@@ -52,7 +52,7 @@ def addDialogIfNeeded(url):
context.absolute_url(), url_quote('%s/%s' % (absolute_url, action))) context.absolute_url(), url_quote('%s/%s' % (absolute_url, action)))
return url return url
print_action_list = actions['object_print'] print_action_list = sorted(actions.get('object_print', []) + actions.get('object_jio_print', []), key=lambda x: x["priority"])
new_print_action_list = [] new_print_action_list = []
for ai in print_action_list: for ai in print_action_list:
ai_copy = ai.copy() ai_copy = ai.copy()
......
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