[views] change schema views: remove view eschema and use tabs for cwetype
authorNicolas Chauvat <nicolas.chauvat@logilab.fr>
Thu, 28 May 2009 22:57:52 +0200
changeset 1998 12040c090aa4
parent 1997 554eb4dd533d
child 1999 b9a8f5995658
[views] change schema views: remove view eschema and use tabs for cwetype
entities/schemaobjs.py
schemaviewer.py
web/views/schema.py
web/views/startup.py
--- a/entities/schemaobjs.py	Thu May 28 22:56:38 2009 +0200
+++ b/entities/schemaobjs.py	Thu May 28 22:57:52 2009 +0200
@@ -20,7 +20,7 @@
     fetch_attrs, fetch_order = fetch_config(['name'])
 
     def dc_title(self):
-        return self.req._(self.name)
+        return u'%s (%s)' % (self.name, self.req._(self.name))
 
     def dc_long_title(self):
         stereotypes = []
@@ -43,7 +43,7 @@
     fetch_attrs, fetch_order = fetch_config(['name'])
 
     def dc_title(self):
-        return self.req._(self.name)
+        return u'%s (%s)' % (self.name, self.req._(self.name))
 
     def dc_long_title(self):
         stereotypes = []
--- a/schemaviewer.py	Thu May 28 22:56:38 2009 +0200
+++ b/schemaviewer.py	Thu May 28 22:57:52 2009 +0200
@@ -94,10 +94,10 @@
         return data
 
     def eschema_link_url(self, eschema):
-        return self.req.build_url('cwetype/%s?vid=eschema' % eschema)
+        return self.req.build_url('cwetype/%s' % eschema)
 
     def rschema_link_url(self, rschema):
-        return self.req.build_url('cwrtype/%s?vid=eschema' % rschema)
+        return self.req.build_url('cwrtype/%s' % rschema)
 
     def possible_views(self, etype):
         rset = self.req.etype_rset(etype)
--- a/web/views/schema.py	Thu May 28 22:56:38 2009 +0200
+++ b/web/views/schema.py	Thu May 28 22:57:52 2009 +0200
@@ -17,7 +17,8 @@
 from cubicweb.view import EntityView, StartupView
 from cubicweb.common import tags, uilib
 from cubicweb.web import action
-from cubicweb.web.views import TmpFileViewMixin, primary, baseviews
+from cubicweb.web.views import TmpFileViewMixin, primary, baseviews, tabs
+from cubicweb.web.facet import AttributeFacet
 
 
 class ViewSchemaAction(action.Action):
@@ -32,8 +33,6 @@
         return self.build_url(self.id)
 
 
-# schema entity types views ###################################################
-
 class CWRDEFPrimaryView(primary.PrimaryView):
     __select__ = implements('CWAttribute', 'CWRelation')
     cache_max_age = 60*60*2 # stay in http cache for 2 hours by default
@@ -43,6 +42,7 @@
                % (entity.dc_type().capitalize(),
                   html_escape(entity.dc_long_title())))
 
+# CWEType ######################################################################
 
 class CWETypeOneLineView(baseviews.OneLineView):
     __select__ = implements('CWEType')
@@ -56,32 +56,118 @@
         if final:
             self.w(u'</em>')
 
-
-# in memory schema views (yams class instances) ###############################
 SKIPPED_RELS = ('is', 'is_instance_of', 'identity', 'created_by', 'owned_by',
                 'has_text',)
 
-class CWETypeSchemaView(primary.PrimaryView):
-    id = 'eschema'
+class CWETypePrimaryView(tabs.TabsMixin, primary.PrimaryView):
     __select__ = implements('CWEType')
     title = _('in memory entity schema')
     main_related_section = False
     skip_rels = SKIPPED_RELS
+    tabs = [_('cwetype-schema-text'), _('cwetype-schema-image'), 
+            _('cwetype-schema-permissions'), _('cwetype-workflow')]
+    default_tab = 'cwetype-schema-text'
 
-    def render_entity_attributes(self, entity):
-        super(CWETypeSchemaView, self).render_entity_attributes(entity)
-        eschema = self.vreg.schema.eschema(entity.name)
-        viewer = SchemaViewer(self.req)
-        layout = viewer.visit_entityschema(eschema, skiprels=self.skip_rels)
-        self.w(uilib.ureport_as_html(layout))
-        if not eschema.is_final():
-            msg = self.req._('graphical schema for %s') % entity.name
-            self.w(tags.img(src=entity.absolute_url(vid='eschemagraph'),
-                            alt=msg))
+    def render_entity(self, entity):
+        self.render_entity_title(entity)
+        self.w(u'<div>%s</div>' % entity.description)
+        self.render_tabs(self.tabs, self.default_tab, entity)
+
+
+class CWETypeSTextView(EntityView):
+    id = 'cwetype-schema-text'
+    __select__ = EntityView.__select__ & implements('CWEType')
+
+    def cell_call(self, row, col):
+        entity = self.entity(row, col)
+        self.w(u'<h2>%s</h2>' % _('Attributes'))
+        rset = self.req.execute('Any N,F,D,GROUP_CONCAT(C),I,J,DE,A '
+                                'GROUPBY N,F,D,AA,A,I,J,DE '
+                                'ORDERBY AA WHERE A is CWAttribute, '
+                                'A ordernum AA, A defaultval D, '
+                                'A constrained_by C?, A description DE, '
+                                'A fulltextindexed I, A internationalizable J, '
+                                'A relation_type R, R name N, '
+                                'A to_entity O, O name F, '
+                                'A from_entity S, S eid %(x)s',
+                                {'x': entity.eid})
+        self.wview('editable-table', rset, 'null', displayfilter=True)
+        self.w(u'<h2>%s</h2>' % _('Relations'))
+        rset = self.req.execute('Any N,C,F,M,K,D,A ORDERBY N '
+                                'WITH N,C,F,M,D,K,A BEING ('
+                                '(Any N,C,F,M,K,D,A '
+                                'ORDERBY N WHERE A is CWRelation, '
+                                'A description D, A composite K?, '
+                                'A relation_type R, R name N, '
+                                'A to_entity O, O name F, '
+                                'A cardinality C, O meta M, '
+                                'A from_entity S, S eid %(x)s)'
+                                ' UNION '
+                                '(Any N,C,F,M,K,D,A '
+                                'ORDERBY N WHERE A is CWRelation, '
+                                'A description D, A composite K?, '
+                                'A relation_type R, R name N, '
+                                'A from_entity S, S name F, '
+                                'A cardinality C, S meta M, '
+                                'A to_entity O, O eid %(x)s))'
+                                ,{'x': entity.eid})
+        self.wview('editable-table', rset, 'null', displayfilter=True)
 
 
+class CWETypeSImageView(EntityView):
+    id = 'cwetype-schema-image'
+    __select__ = EntityView.__select__ & implements('CWEType')
+
+    def cell_call(self, row, col):
+        entity = self.entity(row, col)
+        url = entity.absolute_url(vid='schemagraph')
+        self.w(u'<img src="%s" alt="%s"/>' % (
+            html_escape(url),
+            html_escape(self.req._('graphical schema for %s') % entity.name)))
+
+class CWETypeSPermView(EntityView):
+    id = 'cwetype-schema-permissions'
+    __select__ = EntityView.__select__ & implements('CWEType')
+
+    def cell_call(self, row, col):
+        entity = self.entity(row, col)
+        self.w(u'<h2>%s</h2>' % _('Add permissions'))
+        rset = self.req.execute('Any P WHERE X add_permission P, '
+                                'X eid %(x)s', 
+                                {'x': entity.eid})
+        self.wview('outofcontext', rset, 'null')
+        self.w(u'<h2>%s</h2>' % _('Read permissions'))
+        rset = self.req.execute('Any P WHERE X read_permission P, '
+                                'X eid %(x)s', 
+                                {'x': entity.eid})
+        self.wview('outofcontext', rset, 'null')
+        self.w(u'<h2>%s</h2>' % _('Update permissions'))
+        rset = self.req.execute('Any P WHERE X update_permission P, '
+                                'X eid %(x)s', 
+                                {'x': entity.eid})
+        self.wview('outofcontext', rset, 'null')
+        self.w(u'<h2>%s</h2>' % _('Delete permissions'))
+        rset = self.req.execute('Any P WHERE X delete_permission P, '
+                                'X eid %(x)s', 
+                                {'x': entity.eid})
+        self.wview('outofcontext', rset, 'null')
+
+class CWETypeSWorkflowView(EntityView):
+    id = 'cwetype-workflow'
+    __select__ = EntityView.__select__ & implements('CWEType')
+
+    def cell_call(self, row, col):
+        entity = self.entity(row, col)
+        if entity.reverse_state_of:
+            self.w(u'<img src="%s" alt="%s"/>' % (
+                    html_escape(entity.absolute_url(vid='ewfgraph')),
+                    html_escape(self.req._('graphical workflow for %s') % entity.name)))
+        else:
+            self.w(u'<p>%s</p>' % _('There is no workflow defined for this entity.'))
+
+# CWRType ######################################################################
+
 class CWRTypeSchemaView(primary.PrimaryView):
-    id = 'eschema'
     __select__ = implements('CWRType')
     title = _('in memory relation schema')
     main_related_section = False
@@ -94,25 +180,12 @@
         self.w(uilib.ureport_as_html(layout))
         if not rschema.is_final():
             msg = self.req._('graphical schema for %s') % entity.name
-            self.w(tags.img(src=entity.absolute_url(vid='eschemagraph'),
+            self.w(tags.img(src=entity.absolute_url(vid='schemagraph'),
                             alt=msg))
 
 
 # schema images ###############################################################
 
-class ImageView(EntityView):
-    __select__ = implements('CWEType')
-    id = 'image'
-    title = _('image')
-
-    def cell_call(self, row, col):
-        entity = self.entity(row, col)
-        url = entity.absolute_url(vid='eschemagraph')
-        self.w(u'<img src="%s" alt="%s"/>' % (
-            html_escape(url),
-            html_escape(self.req._('graphical schema for %s') % entity.name)))
-
-
 class RestrictedSchemaDotPropsHandler(s2d.SchemaDotPropsHandler):
     def __init__(self, req):
         # FIXME: colors are arbitrary
@@ -188,7 +261,7 @@
                        prophdlr=RestrictedSchemaDotPropsHandler(self.req))
 
 class CWETypeSchemaImageView(TmpFileViewMixin, EntityView):
-    id = 'eschemagraph'
+    id = 'schemagraph'
     __select__ = implements('CWEType')
 
     content_type = 'image/png'
@@ -212,3 +285,15 @@
         visitor = OneHopRSchemaVisitor(self.req, rschema)
         s2d.schema2dot(outputfile=tmpfile, visitor=visitor,
                        prophdlr=RestrictedSchemaDotPropsHandler(self.req))
+
+### facets
+
+class CWMetaFacet(AttributeFacet):
+    id = 'cwmeta-facet'
+    __select__ = AttributeFacet.__select__ & implements('CWEType')
+    rtype = 'meta'
+
+class CWFinalFacet(AttributeFacet):
+    id = 'cwfinal-facet'
+    __select__ = AttributeFacet.__select__ & implements('CWEType')
+    rtype = 'final'
--- a/web/views/startup.py	Thu May 28 22:56:38 2009 +0200
+++ b/web/views/startup.py	Thu May 28 22:57:52 2009 +0200
@@ -13,12 +13,12 @@
 from logilab.mtconverter import html_escape
 
 from cubicweb.view import StartupView
-from cubicweb.selectors import match_user_groups
+from cubicweb.selectors import match_user_groups, implements
 from cubicweb.common.uilib import ureport_as_html
 from cubicweb.web import ajax_replace_url, uicfg, httpcache
+from cubicweb.web.views import tabs
 from cubicweb.web.views.management import SecurityViewMixIn
 
-
 class ManageView(StartupView):
     id = 'manage'
     title = _('manage')
@@ -164,42 +164,44 @@
     def display_folders(self):
         return 'Folder' in self.schema and self.req.execute('Any COUNT(X) WHERE X is Folder')[0][0]
 
-
-
-class SchemaView(StartupView):
+class SchemaView(tabs.TabsMixin, StartupView):
     id = 'schema'
     title = _('application schema')
+    tabs = [_('schema-text'), _('schema-image')]
+    default_tab = 'schema-image'
 
     def call(self):
         """display schema information"""
         self.req.add_js('cubicweb.ajax.js')
         self.req.add_css(('cubicweb.schema.css','cubicweb.acl.css'))
-        withmeta = int(self.req.form.get('withmeta', 0))
-        section = self.req.form.get('sec', '')
+        self.w(u'<h1>%s</h1>' % _('Schema of the data model'))
+        self.render_tabs(self.tabs, self.default_tab)
+
+class SchemaTabImageView(StartupView):
+    id = 'schema-image'
+
+    def call(self):
+        self.w(_(u'<div>This schema of the data model <em>excludes</em> the '
+                 u'meta-data, but you can also display a <a href="%s">complete '
+                 u'schema with meta-data</a>.</div>')
+               % html_escape(self.build_url('view', vid='schemagraph', withmeta=1)))
         self.w(u'<img src="%s" alt="%s"/>\n' % (
-            html_escape(self.req.build_url('view', vid='schemagraph', withmeta=withmeta)),
+            html_escape(self.req.build_url('view', vid='schemagraph', withmeta=0)),
             self.req._("graphical representation of the application'schema")))
-        if withmeta:
-            self.w(u'<div><a href="%s">%s</a></div>' % (
-                html_escape(self.build_url('schema', withmeta=0, sec=section)),
-                self.req._('hide meta-data')))
-        else:
-            self.w(u'<div><a href="%s">%s</a></div>' % (
-                html_escape(self.build_url('schema', withmeta=1, sec=section)),
-                self.req._('show meta-data')))
-        self.w(u'<a href="%s">%s</a><br/>' %
-               (html_escape(ajax_replace_url('detailed_schema', '', 'schematext',
-                                             skipmeta=int(not withmeta))),
-                self.req._('detailed schema view')))
-        if self.req.user.matching_groups('managers'):
-            self.w(u'<a href="%s">%s</a>' %
-                   (html_escape(ajax_replace_url('detailed_schema', '', 'schema_security',
-                                                 skipmeta=int(not withmeta))),
-                self.req._('security')))
-        self.w(u'<div id="detailed_schema">')
-        if section:
-            self.wview(section, None)
-        self.w(u'</div>')
+
+class SchemaTabTextView(StartupView):
+    id = 'schema-text'
+
+    def call(self):
+        self.w(u'<p>%s</p>' % _('This is the list of types defined in the data '
+                                'model ofin this application.'))
+        self.w(u'<p>%s</p>' % _('<em>meta</em> is True for types that are defined by the '
+                                'framework itself (e.g. User and Group). '
+                                '<em>final</em> is True for types that can not be the '
+                                'subject of a relation (e.g. Int and String).'))
+        rset = self.req.execute('Any X,M,F ORDERBY N WHERE X is CWEType, X name N, '
+                                'X meta M, X final F')
+        self.wview('editable-table', rset, displayfilter=True)
 
 
 class ManagerSchemaPermissionsView(StartupView, SecurityViewMixIn):
@@ -315,3 +317,4 @@
                                      skipmeta=skipmeta)
         self.w(ureport_as_html(layout))
 
+