[web/views] show composite entities in delete view
authorPhilippe Pepiot <philippe.pepiot@logilab.fr>
Wed, 25 Jan 2017 14:28:20 +0100
changeset 11964 01eeea97e549
parent 11963 64ecd4d96ac7
child 11965 fb03a4113979
[web/views] show composite entities in delete view Disabled by default, can be activated with show_composite = True Display first level of composite entities in a treeview, limited to the current (page_size - 1), so the maximum of displayed entities bump to page_size * (page_size - 1).
cubicweb/i18n/de.po
cubicweb/i18n/en.po
cubicweb/i18n/es.po
cubicweb/i18n/fr.po
cubicweb/web/test/unittest_views_editforms.py
cubicweb/web/views/editforms.py
--- a/cubicweb/i18n/de.po	Mon May 11 13:57:34 2015 +0200
+++ b/cubicweb/i18n/de.po	Wed Jan 25 14:28:20 2017 +0100
@@ -198,6 +198,9 @@
 msgid "Added relation : %(entity_from)s %(rtype)s %(entity_to)s"
 msgstr ""
 
+msgid "And more composite entities"
+msgstr ""
+
 msgid "Attributes permissions:"
 msgstr "Rechte der Attribute"
 
--- a/cubicweb/i18n/en.po	Mon May 11 13:57:34 2015 +0200
+++ b/cubicweb/i18n/en.po	Wed Jan 25 14:28:20 2017 +0100
@@ -187,6 +187,9 @@
 msgid "Added relation : %(entity_from)s %(rtype)s %(entity_to)s"
 msgstr ""
 
+msgid "And more composite entities"
+msgstr ""
+
 msgid "Attributes permissions:"
 msgstr ""
 
--- a/cubicweb/i18n/es.po	Mon May 11 13:57:34 2015 +0200
+++ b/cubicweb/i18n/es.po	Wed Jan 25 14:28:20 2017 +0100
@@ -201,6 +201,9 @@
 msgid "Added relation : %(entity_from)s %(rtype)s %(entity_to)s"
 msgstr "Relación agregada : %(entity_from)s %(rtype)s %(entity_to)s"
 
+msgid "And more composite entities"
+msgstr ""
+
 msgid "Attributes permissions:"
 msgstr "Permisos de atributos:"
 
--- a/cubicweb/i18n/fr.po	Mon May 11 13:57:34 2015 +0200
+++ b/cubicweb/i18n/fr.po	Wed Jan 25 14:28:20 2017 +0100
@@ -195,6 +195,9 @@
 msgid "Added relation : %(entity_from)s %(rtype)s %(entity_to)s"
 msgstr "Relation ajoutée : %(entity_from)s %(rtype)s %(entity_to)s"
 
+msgid "And more composite entities"
+msgstr "Et d'autres entités"
+
 msgid "Attributes permissions:"
 msgstr "Permissions des attributs"
 
--- a/cubicweb/web/test/unittest_views_editforms.py	Mon May 11 13:57:34 2015 +0200
+++ b/cubicweb/web/test/unittest_views_editforms.py	Wed Jan 25 14:28:20 2017 +0100
@@ -20,7 +20,9 @@
 from logilab.common import tempattr
 
 from cubicweb.devtools.testlib import CubicWebTC
+from cubicweb.predicates import is_instance
 from cubicweb.web.views import uicfg
+from cubicweb.web.views.editforms import DeleteConfFormView
 from cubicweb.web.formwidgets import AutoCompletionWidget
 from cubicweb.schema import RRQLExpression
 
@@ -239,6 +241,59 @@
             rset = req.execute('CWGroup X')
             self.view('deleteconf', rset, template=None, req=req).source
 
+    def test_delete_conf_formview_composite(self):
+        with self.admin_access.cnx() as cnx:
+            d1 = cnx.create_entity('Directory', name=u'dtest1')
+            d2 = cnx.create_entity('Directory', name=u'dtest2', parent=d1)
+            d3 = cnx.create_entity('Directory', name=u'dtest3', parent=d2)
+            d4 = cnx.create_entity('Directory', name=u'dtest4', parent=d1)
+            for i in range(3):
+                cnx.create_entity('Directory', name=u'child%s' % (i,),
+                                  parent=d3)
+            cnx.commit()
+
+        class DirectoryDeleteView(DeleteConfFormView):
+            __select__ = (DeleteConfFormView.__select__ &
+                          is_instance('Directory'))
+            show_composite = True
+
+        self.vreg['propertyvalues']['navigation.page-size'] = 3
+        with self.admin_access.web_request() as req, \
+                self.temporary_appobjects(DirectoryDeleteView):
+            rset = req.execute('Directory X WHERE X name "dtest1"')
+            source = self.view('deleteconf', rset,
+                               template=None, req=req).source.decode('utf-8')
+            # Show composite object at depth 1
+            # Don't display "And more composite entities" since their are equal
+            # to page size
+            expected = (
+                '<li>'
+                '<a href="http://testing.fr/cubicweb/directory/%s">dtest1</a>'
+                '<ul class="treeview"><li>'
+                '<a href="http://testing.fr/cubicweb/directory/%s">dtest4</a>'
+                '</li><li class="last">'
+                '<a href="http://testing.fr/cubicweb/directory/%s">dtest2</a>'
+                '</li></ul></li>') % (d1.eid, d4.eid, d2.eid)
+            self.assertIn(expected, source)
+
+            # Page size is reached, show "And more composite entities"
+            rset = req.execute('Directory X WHERE X name "dtest3"')
+            source = self.view('deleteconf', rset,
+                               template=None, req=req).source.decode('utf-8')
+            expected = (
+                '<li>'
+                '<a href="http://testing.fr/cubicweb/directory/%s">dtest3</a>'
+                '<ul class="treeview"><li>'
+                '<a href="http://testing.fr/cubicweb/directory/%s">child2</a>'
+                '</li><li>'
+                '<a href="http://testing.fr/cubicweb/directory/%s">child1</a>'
+                '</li><li class="last">And more composite entities</li>'
+                '</ul></li>') % (
+                    d3.eid,
+                    req.find('Directory', name='child2').one().eid,
+                    req.find('Directory', name='child1').one().eid)
+            self.assertIn(expected, source)
+
     def test_automatic_edition_formview(self):
         with self.admin_access.web_request() as req:
             rset = req.execute('CWUser X')
--- a/cubicweb/web/views/editforms.py	Mon May 11 13:57:34 2015 +0200
+++ b/cubicweb/web/views/editforms.py	Wed Jan 25 14:28:20 2017 +0100
@@ -71,11 +71,23 @@
     # don't use navigation, all entities asked to be deleted should be displayed
     # else we will only delete the displayed page
     paginable = False
+    # show first level of composite relations in a treeview
+    show_composite = False
+
+    @staticmethod
+    def _iter_composite_entities(entity, limit=None):
+        for rdef, role in entity.e_schema.composite_rdef_roles:
+            for centity in entity.related(
+                rdef.rtype, role, limit=limit
+            ).entities():
+                yield centity
 
     def call(self, onsubmit=None):
         """ask for confirmation before real deletion"""
         req, w = self._cw, self.w
         _ = req._
+        if self.show_composite:
+            req.add_css(('jquery-treeview/jquery.treeview.css', 'cubicweb.treeview.css'))
         w(u'<script type="text/javascript">updateMessage(\'%s\');</script>\n'
           % _('this action is not reversible!'))
         # XXX above message should have style of a warning
@@ -84,11 +96,30 @@
                                              rset=self.cw_rset,
                                              onsubmit=onsubmit)
         w(u'<ul>\n')
+        page_size = req.property_value('navigation.page-size')
         for entity in self.cw_rset.entities():
             # don't use outofcontext view or any other that may contain inline
             # edition form
-            w(u'<li>%s</li>' % tags.a(entity.view('textoutofcontext'),
-                                      href=entity.absolute_url()))
+            w(u'<li>%s' % tags.a(entity.view('textoutofcontext'),
+                                 href=entity.absolute_url()))
+            if self.show_composite:
+                content = None
+                for count, centity in enumerate(self._iter_composite_entities(
+                    entity, limit=page_size,
+                )):
+                    if count == 0:
+                        w(u'<ul class="treeview">')
+                    if content is not None:
+                        w(u'<li>%s</li>' % content)
+                    if count == page_size - 1:
+                        w(u'<li class="last">%s</li></ul>' % _(
+                            'And more composite entities'))
+                        break
+                    content = tags.a(centity.view('textoutofcontext'),
+                                     href=centity.absolute_url())
+                else:
+                    w(u'<li class="last">%s</li></ul>' % content)
+            w(u'</li>\n')
         w(u'</ul>\n')
         form.render(w=self.w)