Commit caff57e9 authored by Sylvain Thénault's avatar Sylvain Thénault
Browse files

[ui] Customize relation widget to pass through container information

This is needed to properly handle e.g. scheme constraints.

Depends on to-be-release refactoring in relationwidget cube.

Related to #11447483
parent 302ae5401811
......@@ -8,6 +8,7 @@ envlist = py27, flake8-jenkins
sitepackages = True
deps =
commands = {envpython} -m pytest {posargs:{toxinidir}/test}
......@@ -15,6 +15,9 @@
# with this program. If not, see <>.
"""cubicweb-seda views for data objects (BinaryDataObject / PhysicalDataObject)"""
import json
from cubicweb.predicates import match_form_params
from cubicweb.web import formwidgets as fw
from cubicweb.web.views import uicfg
......@@ -30,6 +33,76 @@ for etype in ('SEDABinaryDataObject', 'SEDAPhysicalDataObject'):
affk.set_field_kwargs('*', 'id', widget=fw.TextInput({'size': 80}))
for rtype in ('seda_mime_type_to', 'seda_encoding_to', 'seda_format_id_to', 'seda_algorithm'):
affk.tag_subject_of(('*', rtype, '*'),
{'widget': rwdg.RelationFacetWidget(dialog_options={'width': 800})})
def _container_eid(entity):
"""Attempt to return the container eid from the entity, handling case where entity is being
created and container information will be find through linkto or parent form (partially
if entity.has_eid():
# entity is expected to be a contained entity, not the container itself
container = entity.cw_adapt_to('IContained').container
# but parent entity, retrieved through linkto, may be the container itself or a
# contained entity
parent_eid = int(entity._cw.form['__linkto'].split(':')[1])
except KeyError:
# ajax created form
parent_eid = int(json.loads(entity._cw.form['arg'][0]))
except ValueError:
# unable to get parent eid for now :()
return None
parent = entity._cw.entity_from_eid(parent_eid)
icontainer = parent.cw_adapt_to('IContainer')
if icontainer is None:
container = parent.cw_adapt_to('IContained').container
container = icontainer.container
return container.eid
class ContainedRelationFacetWidget(rwdg.RelationFacetWidget):
def trigger_search_url(self, entity, url_params):
"""Overriden to add information about who is the container
This information will be used later for proper vocabulary computation.
# first retrieve the container entity
container_eid = _container_eid(entity)
# and put it as an extra url param
if container_eid is not None:
url_params['container'] = unicode(container_eid)
return super(ContainedRelationFacetWidget, self).trigger_search_url(entity, url_params)
class ContainedSearchForRelatedEntitiesView(rwdg.SearchForRelatedEntitiesView):
__select__ = rwdg.SearchForRelatedEntitiesView.__select__ & match_form_params('container')
def linkable_rset(self):
"""Return rset of entities to be displayed as possible values for the
edited relation. You may want to override this.
entity = self.compute_entity()
rtype, tetype, role = self.rdef
rdef = entity.e_schema.rdef(rtype, role, tetype)
assert len(rdef.constraints) == 1 and 'S container AT' in rdef.constraints[0].expression
baserql = rdef.constraints[0].expression
baserql.replace('S container AT', 'AT eid %(at)s')
rql = 'Any O WHERE ' + baserql
return self._cw.execute(rql, {'at': int(self._cw.form['container'])})
from cubes.seda.xsd2yams import RDEF_CONSTRAINTS
for key, rql_expr in RDEF_CONSTRAINTS.items():
if 'S container AT' in rql_expr:
etype, rtype = key
except ValueError:
etype = '*'
rtype = key
affk.tag_subject_of((etype, rtype, '*'),
{'widget': ContainedRelationFacetWidget(dialog_options={'width': 800})})
......@@ -284,7 +284,7 @@ SKIP_ETYPES = set(['SEDAid'])
SKIP_ATTRS = set(['date', 'message_identifier', 'size', 'uri', 'filename'])
# elements for which we don't care to have some annotation
# x-ref constraints
'seda_data_object_reference_id': 'S container C, O container C',
'seda_archive_unit_ref_id_to': 'S container C, O container C',
......@@ -356,10 +356,10 @@ _CONSTRAINTS = {
def _constraint(etype, rtype):
expr = _CONSTRAINTS[(etype, rtype)]
expr = RDEF_CONSTRAINTS[(etype, rtype)]
except KeyError:
expr = _CONSTRAINTS[rtype]
expr = RDEF_CONSTRAINTS[rtype]
except KeyError:
return ''
return 'RQLConstraint({0!r})'.format(expr.format(subjtype=etype))
Supports Markdown
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