[views] Now, use tabs for entities
authorVincent Michel <vincent.michel@logilab.fr>
Wed, 17 Jul 2013 11:32:39 +0200
changeset 270 312bc5dba074
parent 269 3dfafb4debd5
child 271 1c275b5d6168
[views] Now, use tabs for entities
views/basetemplates.py
views/components.py
views/primary.py
--- a/views/basetemplates.py	Mon Jul 08 16:33:56 2013 +0200
+++ b/views/basetemplates.py	Wed Jul 17 11:32:39 2013 +0200
@@ -68,15 +68,11 @@
         self._cw, rset=self.cw_rset, view=view, context=context))
     if boxes:
         getlayout = self._cw.vreg['components'].select
-        self.w(u'<div id="aside-main-%s" class="span3">\n'
-               u'<div class="well">\n' %
-               context) # XXX Should arrange Facets soon
+        self.w(u'<div id="aside-main-%s" class="span3">\n' % context)
         self.w(u'<div class="navboxes" id="navColumn%s">\n' % context.capitalize())
         for box in boxes:
             box.render(w=self.w, view=view)
-        self.w(u'</div>'
-               u'</div>'
-               u'</div>')
+        self.w(u'</div></div>')
     return len(boxes)
 
 
--- a/views/components.py	Mon Jul 08 16:33:56 2013 +0200
+++ b/views/components.py	Wed Jul 17 11:32:39 2013 +0200
@@ -61,40 +61,60 @@
 ###############################################################################
 ### NAVIGATION BOXES ##########################################################
 ###############################################################################
-class BrainomicsNavToolbarDropdown(component.CtxComponent):
-    """ Abstractcomponent used to display related informations in navtoolbar
+class BrainomicsLinksCtx(component.EntityCtxComponent):
+    """ Component used to display related informations and links,
+    referenced by the registry 'ctx-related-links'.
+    """
+    context = 'left'
+    __regid__ = 'links-ctx'
+    order = 1
+
+    def render(self, w, **kwargs):
+        links = list(self._cw.vreg['ctx-related-links'].possible_objects(self._cw, rset=self.cw_rset))
+        if not links:
+            return
+        w(u'<div class="well">')
+        w(u'<div class="btn-toolbar">')
+        # Render links
+        for link in links:
+            infos = link.related_infos(self.cw_rset)
+            if infos:
+                w(u'<div class="btn-group-vertical btn-block">')
+                w(u'<div class="btn-group">')
+                w(u'<a class="btn btn-primary dropdown-toggle" '
+                  u'data-toggle="dropdown" href="#">')
+                w(u'%s <span class="caret"></span></a>' % link.get_title())
+                w(u'<ul class="dropdown-menu">')
+                for ahref, title in infos:
+                    w(u'<li><a href="%s">%s</a></li>' % (ahref, title))
+                w(u'</ul>')
+                w(u'</div>')
+                w(u'</div>')
+        w(u'</div>')
+        w(u'</div>')
+
+
+class BrainomicsLinksDropdown(component.EntityCtxComponent):
+    """ Component used to display related informations and links,
+    referenced by the registry 'ctx-links'.
     """
     __abstract__ = True
-    __select__ = component.CtxComponent.__select__
-    context = 'nav-toolbar'
+    __registry__ = 'ctx-related-links'
 
-    def display_title(self):
-        raise NotImplementedError
+    def get_title(self):
+        return
 
     def related_infos(self, rset):
         return []
 
-    def render(self, w, **kwargs):
-        infos = self.related_infos(self.cw_rset)
-        if not infos:
-            return
-        w(u'<div class="btn-group">')
-        w(u'<a class="btn dropdown-toggle btn-primary" data-toggle="dropdown" href="#">')
-        w(u'%s <span class="caret"></span></a>' % self.display_title())
-        w(u'<ul class="dropdown-menu">')
-        for ahref, title in infos:
-            w(u'<li><a href="%s">%s</a></li>' % (ahref, title))
-        w(u'</ul>')
-        w(u'</div>')
 
-
-class BrainomicsNabToolbarStudies(BrainomicsNavToolbarDropdown):
+class BrainomicsLinksStudies(BrainomicsLinksDropdown):
     """ Component used to display related studies
     """
-    __select__ = BrainomicsNavToolbarDropdown.__select__ & is_instance('Subject') & one_line_rset()
+    __select__ = BrainomicsLinksDropdown.__select__ & is_instance('Subject')
     __regid__ = 'navtoolbar-studies-ctx'
 
-    def display_title(self):
+    def get_title(self):
         return self._cw._('Related studies')
 
     def related_infos(self, rset):
@@ -105,13 +125,13 @@
         return studies
 
 
-class BrainomicsNabToolbarGroups(BrainomicsNavToolbarDropdown):
+class BrainomicsLinksGroups(BrainomicsLinksDropdown):
     """ Component used to display related groups
     """
-    __select__ = BrainomicsNavToolbarDropdown.__select__ & is_instance('Subject') & one_line_rset()
+    __select__ = BrainomicsLinksDropdown.__select__ & is_instance('Subject')
     __regid__ = 'navtoolbar-groups-ctx'
 
-    def display_title(self):
+    def get_title(self):
         return self._cw._('Related groups')
 
     def related_infos(self, rset):
@@ -122,13 +142,13 @@
         return groups
 
 
-class BrainomicsNabToolbarCenters(BrainomicsNavToolbarDropdown):
+class BrainomicsLinksCenters(BrainomicsLinksDropdown):
     """ Component used to display related centers
     """
-    __select__ = BrainomicsNavToolbarDropdown.__select__ & is_instance('Subject') & one_line_rset()
+    __select__ = BrainomicsLinksDropdown.__select__ & is_instance('Subject')
     __regid__ = 'navtoolbar-centers-ctx'
 
-    def display_title(self):
+    def get_title(self):
         return self._cw._('Related centers')
 
     def related_infos(self, rset):
@@ -140,78 +160,117 @@
 
 
 ###############################################################################
+### TABBLABLE COMPONENTS ######################################################
+###############################################################################
+class BrainomicsTabblableSelectionComponent(component.CtxComponent):
+    """ Component of selection of the different tabs
+    """
+    __select__ = component.CtxComponent.__select__ & nonempty_rset()
+    context = 'nav-toolbar'
+    __regid__ = 'tabblable-select-ctx'
+
+    def render(self, w, **kwargs):
+        if 'ctx-entity-tabs' in self._cw.vreg:
+            tabs = list(self._cw.vreg['ctx-entity-tabs'].possible_objects(self._cw,
+                                                                          rset=self.cw_rset))
+        else:
+            tabs = []
+        if tabs:
+            w(u'<ul class="nav nav-pills" id="entity-tab">')
+            # Main info
+            w(u'<li class="active"><a href="#entity-mainview" data-toggle="pill" '
+              'class="bnt btn-warning">%s</a></li>' % xml_escape(self._cw._('Main info')))
+            # Other tabs
+            for tab in tabs:
+                w(u'<li><a href="#%s" data-toggle="pill" class="bnt btn-warning">%s</a></li>'
+                  % (tab.__regid__, tab.get_title()))
+            w(u'</ul>')
+
+
+class AbstractBrainomicsTabblable(component.EntityCtxComponent):
+    """ Component used to display a tab. """
+    __abstract__ = True
+    __registry__ = 'ctx-entity-tabs'
+
+    def get_title(self):
+        return
+
+    def render_content(self, w, **kwargs):
+        return
+
+    def render(self, w, **kwargs):
+        w(u'<div class="tab-pane" id="%s">' % self.__regid__)
+        self.render_content(w)
+        w(u'</div>')
+
+
+###############################################################################
 ### DOWNLOAD BOXES ############################################################
 ###############################################################################
 class BrainomicsAbstractDownloadBox(component.CtxComponent):
-    __abstract__ = True
     __select__ = component.CtxComponent.__select__ & nonempty_rset()
     context = 'left'
     always_available = False
+    order = 1
+    __regid__ = 'ctx-download-box'
 
     def render(self, w, **kwargs):
         demo = self._cw.vreg.config.get('demo-site')
         if demo and not self.always_available:
-            self.render_demo(w)
+            return
         else:
-            self.render_download(w)
-
-    def render_download(self, w):
-        """ Normal rendering """
-        url = self._cw.build_url(rql=self.cw_rset.printable_rql(), vid=self.download_vid)
-        _id = self.download_vid
-        w(u'<div><a class="btn btn-primary download-ctx" id="%s" href="%s"><i class="icon-download icon-white">'
-          '</i>%s</a></div></br>' % (_id, url, self._cw._(self.title)))
-        # Add on load the rql facet change
-        self._cw.add_onload("$(cw).bind('facets-content-loaded', cw.cubes.brainomics.changeDownloadUrls);")
-
-    def render_demo(self, w):
-        """ Render for demo """
-        w(u'<div><a href="#" class="btn btn-primary disabled" rel="popover" data-content="%s" '
-          'type="button" id="download_box_%s">'
-          '<i class="icon-download icon-white"></i>%s</a></div></br>'
-          % (self._cw._('This is a demo site. This feature is deactivated for now.'),
-             self.__regid__, self._cw._(self.title)))
-        self._cw.add_onload("$('#download_box_%s').popover()" % self.__regid__)
+            links = list(self._cw.vreg['ctx-download-links'].possible_objects(self._cw,
+                                                                              rset=self.cw_rset))
+            if links:
+                w(u'<div class="well">')
+                for link in links:
+                    url = self._cw.build_url(rql=self.cw_rset.printable_rql(), vid=link.download_vid)
+                    _id = link.download_vid
+                    w(u'<a class="btn btn-primary btn-block download-ctx" id="%s" href="%s">'
+                      % (_id, url))
+                    w(u'<i class="icon-download icon-white"></i>%s</a>'
+                      % xml_escape(self._cw._(link.title)))
+                w(u'</div>')
+                # Add on load the rql facet change
+                self._cw.add_onload("""$(cw).bind('facets-content-loaded',
+                cw.cubes.brainomics.changeDownloadUrls);""")
 
 
-class ScanZipFileBox(BrainomicsAbstractDownloadBox):
+class BrainomicsAbstractDownloadLink(component.CtxComponent):
+    __abstract__ = True
+    __select__ = component.CtxComponent.__select__ & nonempty_rset()
+    context = 'left'
+    always_available = False
+    __registry__ = 'ctx-download-links'
+
+
+class ScanZipFileBox(BrainomicsAbstractDownloadLink):
     __regid__ = 'scan_zipfile'
-    __select__ = BrainomicsAbstractDownloadBox.__select__  & is_instance('Scan', 'GenomicMeasure')
+    __select__ = BrainomicsAbstractDownloadLink.__select__  & is_instance('Scan', 'GenomicMeasure')
     title = _('Download Zip')
     download_vid = 'data-zip'
-    order = 0
 
 
-class CsvFileBox(BrainomicsAbstractDownloadBox):
+class CsvFileBox(BrainomicsAbstractDownloadLink):
     __regid__ = 'measure_csvfile'
     __select__ = component.CtxComponent.__select__  & is_instance('Subject', 'Scan',
                                                                   'ScoreDef',
                                                                   'QuestionnaireRun', 'Answer',
                                                                   'GenomicMeasure', 'Snp')
     title = _('Download CSV')
-    order = 0
     always_available = True
     download_vid = 'csvexport'
 
 
-class XcedeBox(BrainomicsAbstractDownloadBox):
+class XcedeBox(BrainomicsAbstractDownloadLink):
     __regid__ = 'xcede_file'
     __select__ = component.CtxComponent.__select__  & is_instance('Subject', 'Scan', 'GenomicMeasure',
                                                                   'QuestionnaireRun', 'Questionnaire')
     title = _('Download Xcede')
-    order = 0
     always_available = True
     download_vid = 'xcede'
 
 
-class SeeSlicesBox(BrainomicsAbstractDownloadBox):
-    __regid__ = 'see_slices'
-    __select__ = BrainomicsAbstractDownloadBox.__select__  & is_instance('Scan')
-    title = _('View images')
-    download_vid = 'slices-view'
-    order = 0
-
-
 ###############################################################################
 ### REGISTRATION CALLBACK #####################################################
 ###############################################################################
--- a/views/primary.py	Mon Jul 08 16:33:56 2013 +0200
+++ b/views/primary.py	Wed Jul 17 11:32:39 2013 +0200
@@ -85,12 +85,24 @@
     def call(self, rset=None):
         entity = self.cw_rset.get_entity(0,0)
         w = self.w
+        # Tabblables
+        w(u'<div class="tab-content">')
+        # Mainn table
+        w(u'<div class="tab-pane active" id="entity-mainview">')
         # Header
         self.display_header(entity)
         # Main col
         w(u'<div class="row-fluid">')
         self.display_main_col(entity)
         w(u'</div>')
+        # Close table
+        w(u'</div>')
+        # Add other tables
+        if 'ctx-entity-tabs' in self._cw.vreg:
+            tabs = self._cw.vreg['ctx-entity-tabs'].possible_objects(self._cw, rset=self.cw_rset)
+            for tab in tabs:
+                tab.render(self.w)
+        w(u'</div>')
 
 
 ###############################################################################