Commit dba67306 authored by Tomáš Peterka's avatar Tomáš Peterka Committed by Tomáš Peterka

[hal_json] Move all parameter introspection/initialization to getHateoas

parent 985fac5f
...@@ -200,42 +200,15 @@ if len(listbox_id_list): ...@@ -200,42 +200,15 @@ if len(listbox_id_list):
kw[listbox_id] = request_form[listbox_id] = listbox_line_list kw[listbox_id] = request_form[listbox_id] = listbox_line_list
# Handle selection the new way # Handle selection the new way
# First check for an query in form parameters - if they are there # We expect selection-related parameters (query, uids...) in extra_param_json
# that means previous view was a listbox with selected stuff so recover here # thus it is enough to update dialog_method parameters with it
query = extra_param.get("query", None) kw.update(**extra_param)
select_all = extra_param.get("basedialog_select_all", 0) kw.update(keep_items=extra_param) # better backward compatibility
# inject `uids` into Scripts **kwargs when we got any `query` (empty or filled)
if query is not None:
listbox = getattr(context, form_id).Base_getListbox()
if listbox is not None:
kw['uids'] = [int(getattr(document, "uid"))
for document in context.Base_searchUsingListbox(listbox, query)]
else:
log('Action {} should not specify `uids` as its parameters when it does not take object list from the previous view!'.format(dialog_method), level=ERROR)
# early-stop if user selected all documents
if query == "" and select_all == 0 and dialog_method != update_method: # do not interrupt on UPDATE
extra_param["basedialog_select_all"] = 1
return context.Base_renderForm(
dialog_id,
message=translate("All documents are selected! Submit again to proceed or Cancel and narrow down your search."),
level=WARNING,
keep_items=extra_param,
query=query,
form_data=form_data)
# The old way was to set inquire kw for "list_selection_name" and update
# it with kw["uids"] which means a long URL to call this script
# if dialog_category is object_search, then edit the selection # if dialog_category is object_search, then edit the selection
if dialog_category == "object_search" : if dialog_category == "object_search" :
portal.portal_selections.setSelectionParamsFor(kw['selection_name'], kw) portal.portal_selections.setSelectionParamsFor(kw['selection_name'], kw)
# Add rest of extra param into arguments of the target method
kw.update(**extra_param)
kw.update(keep_items=extra_param) # better backward compatibility
# Finally we will call the Dialog Method # Finally we will call the Dialog Method
# Handle deferred style, unless we are executing the update action # Handle deferred style, unless we are executing the update action
if dialog_method != update_method and kw.get('deferred_style', 0): if dialog_method != update_method and kw.get('deferred_style', 0):
......
...@@ -275,11 +275,7 @@ def selectKwargsForCallable(func, initial_kwargs, kwargs_dict): ...@@ -275,11 +275,7 @@ def selectKwargsForCallable(func, initial_kwargs, kwargs_dict):
continue continue
# move necessary parameters from kwargs_dict to initial_kwargs # move necessary parameters from kwargs_dict to initial_kwargs
if func_param_name not in initial_kwargs and func_param_name in kwargs_dict: if func_param_name not in initial_kwargs and func_param_name in kwargs_dict:
func_param_value = kwargs_dict.get(func_param_name) initial_kwargs[func_param_name] = kwargs_dict.get(func_param_name)
if hasattr(func_param_value, "__call__"):
initial_kwargs[func_param_name] = func_param_value() # evaluate lazy attributes
else:
initial_kwargs[func_param_name] = func_param_value
# MIDDLE-DANGEROUS! # MIDDLE-DANGEROUS!
# In case of reports (later even exports) substitute None for unknown # In case of reports (later even exports) substitute None for unknown
# parameters. We suppose Python syntax for parameters! # parameters. We suppose Python syntax for parameters!
...@@ -504,12 +500,6 @@ default_document_uri_template = url_template_dict["jio_get_template"] ...@@ -504,12 +500,6 @@ default_document_uri_template = url_template_dict["jio_get_template"]
Base_translateString = context.getPortalObject().Base_translateString Base_translateString = context.getPortalObject().Base_translateString
def lazyUidList(traversed_document, listbox, query):
"""Clojure providing lazy list of UIDs selected from a previous Listbox."""
return lambda: [int(getattr(document, "uid"))
for document in traversed_document.Base_searchUsingListbox(listbox, query)]
def getRealRelativeUrl(document): def getRealRelativeUrl(document):
return '/'.join(portal.portal_url.getRelativeContentPath(document)) return '/'.join(portal.portal_url.getRelativeContentPath(document))
...@@ -1051,15 +1041,9 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti ...@@ -1051,15 +1041,9 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti
if last_form_id: if last_form_id:
last_form = getattr(context, last_form_id) last_form = getattr(context, last_form_id)
last_listbox = last_form.Base_getListbox() last_listbox = last_form.Base_getListbox()
# In order not to use Selections we need to pass all search attributes to *a listbox inside the form dialog*
# in case there was a listbox in the previous form. No other case!
if last_listbox:
# If a Lisbox's list_method takes `uid` as input parameter then it will be ready in the request. But the actual
# computation is too expensive so we make it lazy (and evaluate any callable at `selectKwargsForCallable`)
# UID will be used in (Listbox's|RelationField's) list_method as a constraint if defined in parameters
REQUEST.set("uid", lazyUidList(traversed_document, last_listbox, query))
except AttributeError: except AttributeError:
pass pass
REQUEST.set("form_id", last_form_id) # to be accessible in field rendering (namely ListBox)
# Form traversed_document # Form traversed_document
response_dict['_links']['traversed_document'] = { response_dict['_links']['traversed_document'] = {
...@@ -1107,7 +1091,7 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti ...@@ -1107,7 +1091,7 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti
if form.pt == 'form_dialog': if form.pt == 'form_dialog':
# overwrite "form_id" field's value because old UI does that by passing # overwrite "form_id" field's value because old UI does that by passing
# the form_id in query string and hidden fields # the form_id in query string and hidden fields
renderHiddenField(response_dict, "form_id", last_form_id or REQUEST.get('form_id', '') or form.id) renderHiddenField(response_dict, "form_id", last_form_id)
# dialog_id is a mandatory field in any form_dialog # dialog_id is a mandatory field in any form_dialog
renderHiddenField(response_dict, 'dialog_id', form.id) renderHiddenField(response_dict, 'dialog_id', form.id)
# some dialog actions use custom cancel_url # some dialog actions use custom cancel_url
...@@ -1115,17 +1099,15 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti ...@@ -1115,17 +1099,15 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti
renderHiddenField(response_dict, "cancel_url", REQUEST.get('cancel_url')) renderHiddenField(response_dict, "cancel_url", REQUEST.get('cancel_url'))
# Let's support Selections! # Let's support Selections!
# There are two things needed # If extra_param_json already contains necessary arrtibutes: mandatory `query` and optional `uids`
# - `uid` parameter of list_method of listbox (if present) in this dialog # then our job is done! If not we need to generate them to become parameters for Dialog method.
# - `uids` or `brain` to a Dialog Form Action Method if "uids" not in extra_param_json:
# method_args = selectKwargsForCallable(getattr(traversed_document, form.action), {}, {'uids': None})
# We can serialize `uids` into a hidden form field but we cannot do it with brain so we if "uids" in method_args:
# simply put "query" in a hidden field and construct `brain` from it in Base_callDialogMethod extra_param_json["uids"] = [int(getattr(document, "uid"))
dialog_method_kwargs = selectKwargsForCallable(getattr(traversed_document, form.action), {}, {'brain': None, 'uids': None}) for document in traversed_document.Base_searchUsingListbox(last_listbox, query or extra_param_json.get("query", None))]
if 'uids' in dialog_method_kwargs: if query is not None:
# If we do not have "query" in the REQUEST but the Dialog Method requires uids extra_param_json["query"] = query
# then we still should inject empty "query" in the dialog call
extra_param_json["query"] = query or extra_param_json.get("query", "") or REQUEST.get("query", "")
else: else:
# In form_view we place only form_id in the request form # In form_view we place only form_id in the request form
renderHiddenField(response_dict, 'form_id', form.id) renderHiddenField(response_dict, 'form_id', form.id)
...@@ -1719,7 +1701,6 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -1719,7 +1701,6 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
catalog_kw = { catalog_kw = {
"local_roles": local_roles, "local_roles": local_roles,
"limit": limit,
"sort_on": () # default is an empty tuple "sort_on": () # default is an empty tuple
} }
if default_param_json is not None: if default_param_json is not None:
...@@ -1727,9 +1708,19 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None, ...@@ -1727,9 +1708,19 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
ensureDeserialized( ensureDeserialized(
byteify( byteify(
json.loads(urlsafe_b64decode(default_param_json))))) json.loads(urlsafe_b64decode(default_param_json)))))
if query:
if catalog_kw.get("uid", MARKER) is None and extra_param_json.get("form_id", MARKER) is not MARKER:
# a UID == None is a bit hack-ish way of signaling that the list_method
# needs list of UID instead of a regular query
catalog_kw["uid"] = [int(getattr(document, "uid"))
for document in traversed_document.Base_searchUsingListbox(context.Base_getListbox(extra_param_json["form_id"]), query, limit=1000, **catalog_kw)]
elif query:
catalog_kw["full_text"] = query catalog_kw["full_text"] = query
# add limit after resolving possible UID because that call (unfortunately) must be unrestricted
if limit:
catalog_kw["limit"] = limit
if selection_domain is not None: if selection_domain is not None:
selection_domain_dict = ensureDeserialized( selection_domain_dict = ensureDeserialized(
byteify(json.loads(selection_domain))) byteify(json.loads(selection_domain)))
......
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