[PATCH 1 of 2 saem_ref v2] Add a custom "noresult" view with an invite to create the first entity (CONSEJIRA-511)

Denis Laxalde denis.laxalde at logilab.fr
Wed Sep 19 11:58:04 CEST 2018


# HG changeset patch
# User Denis Laxalde <denis.laxalde at logilab.fr>
# Date 1537348842 -7200
#      Wed Sep 19 11:20:42 2018 +0200
# Node ID 330d7061dda4171e520e366f42a00938798ebac7
# Parent  6a8cc01c6ba71a7612af26ab5202d7c8ceea6219
# Available At http://hg.logilab.org/review/cubes/saem_ref
#              hg pull http://hg.logilab.org/review/cubes/saem_ref -r 330d7061dda4
# EXP-Topic CONSEJIRA-511
Add a custom "noresult" view with an invite to create the first entity (CONSEJIRA-511)

We add a custom "noresult" view and replace the default one that,
instead of displaying "no result matching query", will display a more
specific message when the query concerns a single entity type (for
instance, the /sedalib route corresponds to 'Any X WHERE X is
SEDAArchiveUnit' RQL query). This message is complemented by an invite
to create the first entity if permission is granted.

This helps bootstrapping the instance after db-creation.

diff --git a/cubicweb_saem_ref/i18n/en.po b/cubicweb_saem_ref/i18n/en.po
--- a/cubicweb_saem_ref/i18n/en.po
+++ b/cubicweb_saem_ref/i18n/en.po
@@ -75,6 +75,9 @@ msgstr ""
 msgid "Citation_plural"
 msgstr "Citations"
 
+msgid "Create one?"
+msgstr ""
+
 msgid "Edit authority settings"
 msgstr ""
 
@@ -121,6 +124,10 @@ msgstr ""
 msgid "New OrganizationUnit"
 msgstr ""
 
+#, python-brace-format
+msgid "No entity of type \"{etype}\" yet."
+msgstr ""
+
 msgid "Organization"
 msgstr ""
 
diff --git a/cubicweb_saem_ref/i18n/fr.po b/cubicweb_saem_ref/i18n/fr.po
--- a/cubicweb_saem_ref/i18n/fr.po
+++ b/cubicweb_saem_ref/i18n/fr.po
@@ -81,6 +81,9 @@ msgstr ""
 msgid "Citation_plural"
 msgstr "Citations"
 
+msgid "Create one?"
+msgstr "En créer une ?"
+
 msgid "Edit authority settings"
 msgstr "Configurer l'autorité administrative"
 
@@ -127,6 +130,10 @@ msgstr "Nouvelle autorité administrative"
 msgid "New OrganizationUnit"
 msgstr "Nouvelle unité administrative"
 
+#, python-brace-format
+msgid "No entity of type \"{etype}\" yet."
+msgstr "Aucune entité de type \"{etype}\" pour l'instant."
+
 msgid "Organization"
 msgstr "Autorité administrative"
 
diff --git a/cubicweb_saem_ref/views/__init__.py b/cubicweb_saem_ref/views/__init__.py
--- a/cubicweb_saem_ref/views/__init__.py
+++ b/cubicweb_saem_ref/views/__init__.py
@@ -29,7 +29,14 @@ from cubicweb.view import EntityView
 from cubicweb.predicates import (has_permission, is_instance, multi_lines_rset, match_kwargs,
                                  partial_has_related_entities)
 from cubicweb.web import component, formwidgets as fw
-from cubicweb.web.views import basecomponents, uicfg, urlrewrite, tabs, primary
+from cubicweb.web.views import (
+    basecomponents,
+    baseviews,
+    primary,
+    tabs,
+    uicfg,
+    urlrewrite,
+)
 
 from cubes.squareui.views.basetemplates import basetemplates
 from cubicweb_seda.views import dropdown_button, has_rel_perm, widgets as sedawidgets
@@ -429,11 +436,45 @@ class URLAttributeView(primary.URLAttrib
             self.w(u'<a href="%s">%s</a>' % (url, url))
 
 
+class SAEMNoResultView(baseviews.NoResultView):
+    """Enhanced "noresult" view with a nicer message and an invite to create
+    an entity when permission is granted.
+    """
+
+    def call(self, **kwargs):
+        vreg = self._cw.vreg
+        try:
+            etype = self.cw_rset.description[0][0]
+        except IndexError:
+            # rset probably comes from a user RQL query, fall back to default
+            # behavior.
+            return super(SAEMNoResultView, self).call(**kwargs)
+        if etype not in vreg['etypes']:
+            # Or the first select query variable is not the entity type.
+            return super(SAEMNoResultView, self).call(**kwargs)
+        msg = self._cw._('No entity of type "{etype}" yet.').format(
+            etype=self._cw.__(etype)
+        )
+        self.w(u'<div class="searchMessage">{}'.format(
+            xml_escape(msg)))
+        if vreg.schema[etype].has_perm(self._cw, 'add'):
+            self.w(u' <a href="{url}">{invite}</a>'.format(
+                url=vreg['etypes'].etype_class(etype).cw_create_url(self._cw),
+                invite=xml_escape(self._cw._('Create one?')),
+            ))
+        self.w(u'</div>')
+
+
 def registration_callback(vreg):
     from cubicweb.web.views import actions, cwuser, tableview, undohistory
-    vreg.register_all(globals().values(), __name__, (URLAttributeView, SAEMHTMLPageFooter,))
+    vreg.register_all(globals().values(), __name__, (
+        SAEMHTMLPageFooter,
+        SAEMNoResultView,
+        URLAttributeView,
+    ))
     vreg.register_and_replace(URLAttributeView, primary.URLAttributeView)
     vreg.register_and_replace(SAEMHTMLPageFooter, basetemplates.HTMLPageFooter)
+    vreg.register_and_replace(SAEMNoResultView, baseviews.NoResultView)
     vreg.unregister(tableview.TableView)
     vreg.unregister(undohistory.UndoHistoryView)
     vreg.unregister(basecomponents.ApplicationName)
diff --git a/test/test_views.py b/test/test_views.py
--- a/test/test_views.py
+++ b/test/test_views.py
@@ -625,5 +625,29 @@ class TimelineViewsTC(CubicWebTC):
                                    ar1.view('incontext', w=None)])
 
 
+class BaseViewsTC(CubicWebTC):
+    """Test for non-business views."""
+    configcls = PostgresApptestConfiguration
+
+    def expected_notfound_html(self, etype, addlink=False):
+        parts = [
+            '<div class="searchMessage">No entity of type "{}" yet.'.format(etype)
+        ]
+        if addlink:
+            parts.append(
+                ' <a href="http://testing.fr/cubicweb/add/{}">Create one?</a>'.format(etype)
+            )
+        parts.append('</div>')
+        return ''.join(parts)
+
+    def test_noresult_sedalib(self):
+        with self.admin_access.web_request() as req:
+            result = self.app_handle_request(req, path='/sedalib')
+            self.assertIn(self.expected_notfound_html('SEDAArchiveUnit', True), result)
+        with self.new_access('anon').web_request() as req:
+            result = self.app_handle_request(req, path='/sedalib')
+            self.assertIn(self.expected_notfound_html('SEDAArchiveUnit'), result)
+
+
 if __name__ == '__main__':
     unittest.main()


More information about the saem-devel mailing list