Commit 275758e6 authored by Tomáš Peterka's avatar Tomáš Peterka Committed by Tomáš Peterka

[hal_json] Render messages alongside with Forms

parent 6352d285
......@@ -24,6 +24,8 @@ return context.ERP5Document_getHateoas(
sort_on=sort_on,
local_roles=local_roles,
selection_domain=selection_domain,
restricted=1,
extra_param_json=extra_param_json,
restricted=1
portal_status_message=portal_status_message,
portal_status_level=portal_status_level
)
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None, response=None, view=None, mode=\'root\', query=None, select_list=None, limit=10, local_roles=None, form=None, relative_url=None, list_method=None, default_param_json=None, form_relative_url=None, bulk_list="[]", sort_on=None, selection_domain=None, extra_param_json=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, selection_domain=None, extra_param_json=None, portal_status_message=\'\', portal_status_level=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
"""Render form while keeping its values back to user.
This script differs from Base_redirect that it keeps the form values in place.
:param message: {str} message to be displayed at the user
:param level: {str|int} severity of the message using ERP5Type.Log levels or their names like 'info', 'warn', 'error'
:param keep_items: {dict} items to be available in the next call. They will be either added as hidden fields to the
rendered form or in case of "portal_status_message" just displayed to the user
:param REQUEST: request
:param **kwargs: should contain parameters to ERP5Document_getHateoas such as 'query' to replace Selections
"""
keep_items = keep_items or {}
form = getattr(context, form_id)
return context.ERP5Document_getHateoas(form=form, mode='form')
if not message and "portal_status_message" in keep_items:
message = keep_items.pop("portal_status_message")
if not level and "portal_status_level" in keep_items:
level = keep_items.pop("portal_status_level")
return context.ERP5Document_getHateoas(form=form, mode='form', REQUEST=REQUEST, extra_param_json=keep_items,
portal_status_message=message, portal_status_level=level, **kwargs)
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>form_id</string> </value>
<value> <string>form_id, message=\'\', level=None, keep_items=None, REQUEST=None, **kwargs</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -41,10 +41,10 @@ import time
from email.Utils import formatdate
import re
from zExceptions import Unauthorized
from Products.ERP5Type.Utils import UpperCase
from Products.ERP5Type.Log import log, DEBUG, INFO, WARNING, ERROR
from Products.ERP5Type.Message import Message
from Products.ERP5Type.Utils import UpperCase
from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery
from Products.ERP5Type.Log import log
from collections import OrderedDict
from urlparse import urlparse
......@@ -1190,33 +1190,22 @@ def renderFormDefinition(form, response_dict):
response_dict["action"] = form.action
response_dict["update_action"] = form.update_action
mime_type = 'application/hal+json'
portal = context.getPortalObject()
sql_catalog = portal.portal_catalog.getSQLCatalog()
# Calculate the site root to prevent unexpected browsing
is_web_mode = (context.REQUEST.get('current_web_section', None) is not None) or (hasattr(context, 'isWebMode') and context.isWebMode())
# is_web_mode = traversed_document.isWebMode()
if is_web_mode:
site_root = context.getWebSectionValue()
view_action_type = site_root.getLayoutProperty("configuration_view_action_category", default='object_view')
else:
site_root = portal
view_action_type = "object_view"
context.Base_prepareCorsResponse(RESPONSE=response)
# Check if traversed_document is the site_root
if relative_url:
temp_traversed_document = site_root.restrictedTraverse(relative_url, None)
if (temp_traversed_document is None):
response.setStatus(404)
return ""
else:
temp_traversed_document = context
def statusLevelToString(level):
"""Transform any level format to lowercase string representation"""
if isinstance(level, (str, unicode)):
if level.lower() == "error":
return "error"
elif level.lower().startswith("warn"):
return "error" # we might want to add another level for warning
else:
return "success"
if level == ERROR:
return "error"
elif level == WARNING:
return "error"
else:
return "success"
temp_is_site_root = (temp_traversed_document.getPath() == site_root.getPath())
temp_is_portal = (temp_traversed_document.getPath() == portal.getPath())
def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, REQUEST=None,
response=None, view=None, mode=None, query=None,
......@@ -1260,8 +1249,17 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
"name": portal.getTitle(),
}
}
# possible other attributes
# _notification {dict} form of {'message': "", 'status': ""}
# _embedded {dict} form of {"_view": <erp5_document_properties>}
}
# Inject notification into response no matter the kind of request
if portal_status_message:
result_dict['_notification'] = {
'message': str(portal_status_message),
'status': statusLevelToString(portal_status_level)
}
if (restricted == 1) and (portal.portal_membership.isAnonymousUser()):
login_relative_url = site_root.getLayoutProperty("configuration_login", default="")
......@@ -2101,6 +2099,35 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
return result_dict
mime_type = 'application/hal+json'
portal = context.getPortalObject()
sql_catalog = portal.portal_catalog.getSQLCatalog()
# Calculate the site root to prevent unexpected browsing
is_web_mode = (context.REQUEST.get('current_web_section', None) is not None) or (hasattr(context, 'isWebMode') and context.isWebMode())
# is_web_mode = traversed_document.isWebMode()
if is_web_mode:
site_root = context.getWebSectionValue()
view_action_type = site_root.getLayoutProperty("configuration_view_action_category", default='object_view')
else:
site_root = portal
view_action_type = "object_view"
context.Base_prepareCorsResponse(RESPONSE=response)
# Check if traversed_document is the site_root
if relative_url:
temp_traversed_document = site_root.restrictedTraverse(relative_url, None)
if (temp_traversed_document is None):
response.setStatus(404)
return ""
else:
temp_traversed_document = context
temp_is_site_root = (temp_traversed_document.getPath() == site_root.getPath())
temp_is_portal = (temp_traversed_document.getPath() == portal.getPath())
response.setHeader('Content-Type', mime_type)
hateoas = calculateHateoas(is_portal=temp_is_portal, is_site_root=temp_is_site_root,
traversed_document=temp_traversed_document,
......
......@@ -56,7 +56,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None, response=None, view=None, mode=\'root\', query=None, select_list=None, limit=10, local_roles=None, form=None, relative_url=None, restricted=0, list_method=None, default_param_json=None, form_relative_url=None, bulk_list="[]", sort_on=None, selection_domain=None, extra_param_json=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, selection_domain=None, extra_param_json=None, portal_status_message=\'\', portal_status_level=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -1615,6 +1615,28 @@ return portal.portal_simulation.getInventoryList(section_uid=context.getUid())
self.assertEqual(result_dict['_embedded'].get('count', None), None)
class TestERP5Document_getHateoas_mode_form(ERP5HALJSONStyleSkinsMixin):
@simulate('Base_getRequestHeader', '*args, **kwargs',
'return "application/hal+json"')
@createIndexedDocument()
@changeSkin('Hal')
def test_getHateoasForm_message(self, document):
fake_request = do_fake_request("POST")
result = self.portal.web_site_module.hateoas.ERP5Document_getHateoas(
REQUEST=fake_request, mode="form", relative_url=document.getRelativeUrl(),
form=getattr(document, 'Foo_view'), portal_status_message="Couscous", portal_status_level='error')
self.assertEquals(fake_request.RESPONSE.status, 200)
self.assertEquals(fake_request.RESPONSE.getHeader('Content-Type'),
"application/hal+json"
)
result_dict = json.loads(result)
self.assertEqual(result_dict["_notification"]["status"], "error")
self.assertEqual(result_dict["_notification"]["message"], "Couscous")
class TestERP5Document_getHateoas_mode_bulk(ERP5HALJSONStyleSkinsMixin):
@simulate('Base_getRequestHeader', '*args, **kwargs',
......
"""Render form while keeping its values back to user.
This script differs from Base_redirect that it keeps the form values in place.
:param message: {str} message to be displayed at the user
:param level: {str|int} is ignored in XHTML style - no support for message level distinction
:param keep_items: {dict} items to be available in the next call. They will be either added as hidden fields to the
rendered form or in case of "portal_status_message" just displayed to the user
:param REQUEST: request
:param **kwargs: is used to pass necessary parameters to overcome backend-held state (aka Selections)
"""
keep_items = keep_items or {}
if message and "portal_status_message" not in keep_items:
keep_items["portal_status_message"] = message
keep_items.pop("portal_status_level", None)
if REQUEST is None:
REQUEST = context.REQUEST
for key, value in keep_items.items():
REQUEST.set(key, value)
return getattr(context, form_id)()
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>form_id</string> </value>
<value> <string>form_id, message=\'\', level=None, keep_items=None, REQUEST=None, **kwargs</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
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