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 =
hg+https://hg.logilab.org/review/cubes/compound@649282ea05fb#egg=cubicweb-compound
hg+https://hg.logilab.org/review/cubes/relationwidget@34c224b03ff8#egg=cubicweb-relationwidget
pytest
commands = {envpython} -m pytest {posargs:{toxinidir}/test}
......
......@@ -15,6 +15,9 @@
# with this program. If not, see <http://www.gnu.org/licenses/>.
"""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
supported)
"""
if entity.has_eid():
# entity is expected to be a contained entity, not the container itself
container = entity.cw_adapt_to('IContained').container
else:
# but parent entity, retrieved through linkto, may be the container itself or a
# contained entity
try:
parent_eid = int(entity._cw.form['__linkto'].split(':')[1])
except KeyError:
# ajax created form
try:
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
else:
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:
try:
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
NO_ANNOTATIONS = set([])
_CONSTRAINTS = {
RDEF_CONSTRAINTS = {
# 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):
try:
expr = _CONSTRAINTS[(etype, rtype)]
expr = RDEF_CONSTRAINTS[(etype, rtype)]
except KeyError:
try:
expr = _CONSTRAINTS[rtype]
expr = RDEF_CONSTRAINTS[rtype]
except KeyError:
return ''
return 'RQLConstraint({0!r})'.format(expr.format(subjtype=etype))
......
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