[FIX] base: ir_ui_view: factorize inlining of default subview of x2many

The new get_views API inlines every subview into the main view in an effort to
optimize client/server communication.

In the situation:
```
<form>
  <field name="my_one_to_many" />
</form>
```

The server algorithm will fetch kanban or list views to display that x2many and inline them
in the final arch that is sent to the client.

This commit aims at factorizing the code which does just that in order for studio (or other modules)
to be able to detect whether the subview it receives is "real" or inlined

closes odoo/odoo#106504

X-original-commit: fcf71e51e80b54d709ffbfc5639cc913746ac684
Related: odoo/enterprise#34376
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
This commit is contained in:
Lucas Perais
2022-11-25 17:56:24 +01:00
parent 5172efc434
commit 681e0ea044
+28 -17
View File
@@ -1216,6 +1216,31 @@ actual arch.
if not node.get('on_change'):
node.set('on_change', '1')
def _get_x2many_missing_view_archs(self, field, field_node, node_info):
"""
For x2many fields that require to have some multi-record arch (kanban or list) to display the records
be available, this function fetches all arch that are needed and return them.
The caller function is responsible to do what it needs with them.
"""
current_view_types = [el.tag for el in field_node.xpath("./*[descendant::field]")]
missing_view_types = []
if not any(view_type in current_view_types for view_type in field_node.get('mode', 'kanban,tree').split(',')):
missing_view_types.append(
field_node.get('mode', 'kanban' if node_info.get('mobile') else 'tree').split(',')[0]
)
if not missing_view_types:
return []
comodel = self.env[field.comodel_name].sudo(False)
refs = self._get_view_refs(field_node)
# Do not propagate <view_type>_view_ref of parent call to `_get_view`
comodel = comodel.with_context(**{
f'{view_type}_view_ref': refs.get(f'{view_type}_view_ref')
for view_type in missing_view_types
})
return [comodel._get_view(view_type=view_type) for view_type in missing_view_types]
#------------------------------------------------------
# Specific node postprocessors
@@ -1260,23 +1285,9 @@ actual arch.
# if no widget or the widget requires it.
# So the web client doesn't have to call `get_views` for x2many fields not embedding their view
# in the main form view.
current_view_types = [el.tag for el in node.xpath("./*[descendant::field]")]
missing_view_types = []
if not any(view_type in current_view_types for view_type in node.get('mode', 'kanban,tree').split(',')):
missing_view_types.append(
node.get('mode', 'kanban' if node_info.get('mobile') else 'tree').split(',')[0]
)
if missing_view_types:
comodel = self.env[field.comodel_name].sudo(False)
refs = self._get_view_refs(node)
# Do not propagate <view_type>_view_ref of parent call to `_get_view`
comodel = comodel.with_context(**{
f'{view_type}_view_ref': refs.get(f'{view_type}_view_ref')
for view_type in missing_view_types
})
for view_type in missing_view_types:
subarch, _subview = comodel._get_view(view_type=view_type)
node.append(subarch)
for arch, _view in self._get_x2many_missing_view_archs(field, node, node_info):
node.append(arch)
for child in node:
if child.tag in ('form', 'tree', 'graph', 'kanban', 'calendar'):
node_info['children'] = []