redrawing slice view
authorThierry Parmentelat <thierry.parmentelat@inria.fr>
Mon, 9 Sep 2013 13:48:13 +0000 (15:48 +0200)
committerThierry Parmentelat <thierry.parmentelat@inria.fr>
Mon, 9 Sep 2013 13:48:13 +0000 (15:48 +0200)
portal/sliceview.py
portal/static/css/slice-view.css [new file with mode: 0644]
trash/pluginview.py
unfold/css/plugin.css
unfold/plugin.py
unfold/templates/plugin.html

index 53a77e1..78d5fb8 100644 (file)
@@ -27,12 +27,10 @@ tmp_default_slice='ple.upmc.myslicedemo'
 
 class SliceView (LoginRequiredAutoLogoutView):
 
-#    def __init__ (self, slicename=None):
-#        self.slicename = slicename or tmp_default_slice
-
     def get (self,request, slicename=tmp_default_slice):
     
         page = Page(request)
+        page.add_css_files ('css/slice-view.css')
         page.expose_js_metadata()
     
         metadata = page.get_metadata()
@@ -60,37 +58,6 @@ class SliceView (LoginRequiredAutoLogoutView):
         page.enqueue_query(query_resource_all)
         page.enqueue_query(query_user_all)
     
-        # Prepare the display according to all metadata
-        # (some parts will be pending, others can be triggered by users).
-        # 
-        # For example slice measurements will not be requested by default...
-    
-        # Create the base layout (Stack)...
-        main_plugin = Stack (
-            page=page,
-            title="Slice !!view for %s"%slicename,
-            sons=[],
-        )
-    
-        # ... responsible for the slice properties...
-    
-    
-        main_plugin.insert (
-            Raw (page=page,togglable=False, toggled=True,html="<h2> Slice page for %s</h2>"%slicename)
-        )
-    
-        main_plugin.insert(
-            Raw (page=page,togglable=False, toggled=True,html='<b>Description:</b> TODO')
-        )
-    
-        sq_plugin = Tabs (
-            page=page,
-            title="Slice view for %s"%slicename,
-            togglable=False,
-            sons=[],
-        )
-    
-    
         # ... and for the relations
         # XXX Let's hardcode resources for now
         sq_resource = aq.subquery('resource')
@@ -99,42 +66,38 @@ class SliceView (LoginRequiredAutoLogoutView):
         sq_measurement = aq.subquery('measurement')
         
     
-        ############################################################################
-        # RESOURCES
-        # 
-        # A stack inserted in the subquery tab that will hold all operations
-        # related to resources
+        # Prepare the display according to all metadata
+        # (some parts will be pending, others can be triggered by users).
         # 
-        
-        stack_resources = Stack(
-            page = page,
-            title        = 'Resources',
+        # For example slice measurements will not be requested by default...
+    
+        # Create the base layout (Stack)...
+        main_stack = Stack (
+            page=page,
+            title="Slice %s"%slicename,
             sons=[],
         )
     
-        resource_query_editor = QueryEditor(
-            page  = page,
-            query = sq_resource,
-        )
-        stack_resources.insert(resource_query_editor)
+        # ... responsible for the slice properties...
     
-        resource_active_filters = ActiveFilters(
-            page  = page,
-            query = sq_resource,
+        # a nice header
+        main_stack.insert (
+            Raw (page=page,
+                 togglable=False, 
+                 toggled=True,
+                 html="<h2 class='well well-lg'> Slice %s</h2>"%slicename)
         )
-        stack_resources.insert(resource_active_filters)
     
-        # --------------------------------------------------------------------------
-        # Different displays = DataTables + GoogleMaps
-        #
-        tab_resource_plugins = Tabs(
-            page    = page,
-            sons = []
-        )
+#        main_stack.insert(
+#            Raw (page=page,togglable=False, toggled=True,html='<b>Description:</b> TODO')
+#        )
     
-        tab_resource_plugins.insert(Hazelnut( 
+        # the resources part is made of a Stack, 
+        # with first a Tabs (List, Geographic), 
+        # and second the QueryEditor to tweak the set of attributes to show
+        resources_as_list = Hazelnut( 
             page       = page,
-            title      = 'List',
+            title      = 'Resources as a List',
             domid      = 'checkboxes',
             # this is the query at the core of the slice list
             query      = sq_resource,
@@ -146,10 +109,10 @@ class SliceView (LoginRequiredAutoLogoutView):
                 'aoColumns'      : [None, None, None, None, {'bSortable': False}],
                 'iDisplayLength' : 25,
                 'bLengthChange'  : True,
-            },
-        ))
-    
-        tab_resource_plugins.insert(GoogleMaps(
+                },
+            )
+
+        resources_as_map = GoogleMaps(
             page       = page,
             title      = 'Geographic view',
             domid      = 'gmap',
@@ -162,28 +125,83 @@ class SliceView (LoginRequiredAutoLogoutView):
             latitude   = 49.,
             longitude  = 2.2,
             zoom       = 3,
-        ))
+        )
+
+        resources_query_editor = QueryEditor(
+            page  = page,
+            query = sq_resource,
+            )
+        resources_active_filters = ActiveFilters(
+            page  = page,
+            query = sq_resource,
+            )
+
+        resources_area = Stack (
+            page=page,
+            domid="resources",
+            togglable=True,
+            title="Resources",
+            outline_complete=True,
+            sons = [
+                Tabs ( page=page, 
+                       sons=[ resources_as_list, resources_as_map, ] 
+                       ),
+                Stack ( page=page,
+                        title="Customize",
+                        togglable=True,
+                        sons = [ resources_query_editor, resources_active_filters, ]
+                        ),
+                ]
+            )
+
+        main_stack.insert (resources_area)
+
+
+#        sq_plugin = Tabs (
+#            page=page,
+#            title="Slice view for %s"%slicename,
+#            togglable=True,
+#            sons=[],
+#        )
+    
+    
+        ############################################################################
+        # RESOURCES
+        # 
+        # A stack inserted in the subquery tab that will hold all operations
+        # related to resources
+        # 
+        
+#        stack_resources = Stack(
+#            page = page,
+#            title = 'Resources',
+#            sons=[],
+#        )
     
-        stack_resources.insert(tab_resource_plugins)
+#        stack_resources.insert(resource_active_filters)
+#    
+#    
+#        stack_resources.insert(tab_resource_plugins)
     
-        sq_plugin.insert(stack_resources)
+#        sq_plugin.insert(stack_resources)
     
         ############################################################################
         # USERS
         # 
     
         tab_users = Tabs(
-            page         = page,
-            title        = 'Users',
-            domid        = 'thetabs2',
-            # activeid   = 'checkboxes',
-            active_domid = 'checkboxes2',
+            page                = page,
+            domid               = 'users',
+            outline_complete    = True,
+            togglable           = True,
+            title               = 'Users',
+            active_domid        = 'checkboxes2',
         )
-        sq_plugin.insert(tab_users)
+        main_stack.insert(tab_users)
     
         tab_users.insert(Hazelnut( 
             page        = page,
-            title       = 'List',
+            title       = 'Users List',
             domid       = 'checkboxes2',
             # tab's sons preferably turn this off
             togglable   = False,
@@ -201,17 +219,18 @@ class SliceView (LoginRequiredAutoLogoutView):
         ))
     
         tab_measurements = Tabs (
-            page         = page,
-            title        = 'Measurements',
-            domid        = 'thetabs3',
-            # activeid   = 'checkboxes',
-            active_domid = 'checkboxes3',
+            page                = page,
+            active_domid        = 'checkboxes3',
+            outline_complete    = True,
+            togglable           = True,
+            title               = 'Measurements',
+            domid               = 'measurements',
         )
-        sq_plugin.insert(tab_measurements)
+        main_stack.insert(tab_measurements)
     
         tab_measurements.insert(Hazelnut( 
             page        = page,
-            title       = 'List',
+            title       = 'Measurements',
             domid       = 'checkboxes3',
             # tab's sons preferably turn this off
             togglable   = False,
@@ -227,25 +246,27 @@ class SliceView (LoginRequiredAutoLogoutView):
             },
         ))
     
-        main_plugin.insert(sq_plugin)
+#        main_stack.insert(sq_plugin)
     
         # --------------------------------------------------------------------------
         # ResourcesSelected
         #
-        main_plugin.insert(ResourcesSelected(
+        main_stack.insert(ResourcesSelected(
             page                = page,
             title               = 'Pending operations',
             query               = main_query,
             togglable           = True,
+            domid               = 'pending',
+            outline_complete    = True,
         ))
     
-        main_plugin.insert(Messages(
+        main_stack.insert(Messages(
             page   = page,
             title  = "Runtime messages for slice %s"%slicename,
             domid  = "msgs-pre",
             levels = "ALL",
         ))
-    #    main_plugin.insert(Updater(
+    #    main_stack.insert(Updater(
     #        page   = page,
     #        title  = "wont show up as non togglable by default",
     #        query  = main_query,
@@ -258,7 +279,7 @@ class SliceView (LoginRequiredAutoLogoutView):
         template_env = {}
         
         # define 'unfold1_main' to the template engine - the main contents
-        template_env [ 'unfold1_main' ] = main_plugin.render(request)
+        template_env [ 'unfold1_main' ] = main_stack.render(request)
     
         # more general variables expected in the template
         template_env [ 'title' ] = '%(slicename)s'%locals()
diff --git a/portal/static/css/slice-view.css b/portal/static/css/slice-view.css
new file mode 100644 (file)
index 0000000..822d2cd
--- /dev/null
@@ -0,0 +1,12 @@
+#complete-resources {
+    background-color: #ffefef;
+}
+#complete-users {
+    background-color: #efffef;
+}
+#complete-measurements {
+    background-color: #efefff;
+}
+#complete-pending {
+    background-color: #efffff;
+}
index 236744f..16801d0 100644 (file)
@@ -41,29 +41,32 @@ def test_plugin_view (request):
         Stack (
         page=page,
         title='thestack',
-        togglable=False,
+        togglable=True,
         domid='stack',
         sons=[ \
-            Updater (
-                    page=page,
-                    title="wont show up as non togglable by default",
-                    query=main_query,
-                    label="Update me",
-                    domid="the-updater",
-                    ),
-            # make sure the 2 things work together
+# this updater thing never made it to production                
+#            Updater (
+#                    page=page,
+#                    title="Won't show up as non togglable",
+#                    query=main_query,
+#                    label="Update me",
+#                    domid="the-updater",
+#                ),
+        # make sure the 2 things work together
             Hazelnut (
                     page=page,
                     title="Slice %s - checkboxes interacting w/ updater"%slicename,
                     query=main_query,
                     domid="hazelnut",
                     checkboxes=True,
+                    togglable=True,
                     ),
             Messages (
                     page=page,
                     title="Runtime messages",
-                    domid="msgs-pre",
+                    domid="messages",
                     levels='ALL',
+                    togglable=True,
                     ),
             ])
 
index 02d8acf..8811332 100644 (file)
@@ -5,7 +5,12 @@ div.plugin-toggle {
     border-width:      1px;
 }
 div.plugin, div.plugin-toggle {
+}
+div.plugin-outline-complete, div.plugin-outline-body {
     border-radius:     8px;
+    border:            1px solid;
+    padding:           5px;
+    margin:            5px;
 }
 h4.plugin-show {
     cursor: s-resize;
index bcc03aa..61af0e0 100644 (file)
@@ -61,6 +61,13 @@ class Plugin:
     #                     since domid is the key for storing that data in the browser storage space
     #   .. None         : if not passed to __init__ at all, then the default_toggled() method is called
     #   ..              : anything else, defaults to True
+    # . outline_complete: whether the overall plugin (body + toggle buttons/title) needs to receive
+    #                     a border and extra space
+    # . outline_body    : same but for the plugin body only
+    #      for these 2 outline_ flags, possible values mimick the above behaviour, i.e.:
+    #   .. True:        : outline is on
+    #   .. False:       : outline is off
+    #   .. None:        : calls default_outline_complete() on the plugin object
     #
     #### internal data
     # . domid: created internally, but can be set at creation time if needed
@@ -72,7 +79,9 @@ class Plugin:
     # which will result in 'foo' being accessible to the template engine
     # 
     def __init__ (self, page, title=None, domid=None,
-                  visible=True, togglable=None, toggled=None, **settings):
+                  visible=True, togglable=None, toggled=None,
+                  outline_complete=None, outline_body=None,
+                  **settings):
         self.page = page
         # callers can provide their domid for css'ing 
         if not domid: domid=self.newdomid()
@@ -83,10 +92,14 @@ class Plugin:
         self.classname=self._py_classname()
         self.plugin_classname=self._js_classname()
         self.visible=visible
-        if togglable is None:   self.togglable=self.default_togglable()
-        else:                   self.togglable=togglable
-        if toggled is None:     self.toggled=self.default_toggled()
-        else:                   self.toggled=toggled
+        if togglable is None:           self.togglable=self.default_togglable()
+        else:                           self.togglable=togglable
+        if toggled is None:             self.toggled=self.default_toggled()
+        else:                           self.toggled=toggled
+        if outline_complete is None:    self.outline_complete=self.default_outline_complete()
+        else:                           self.outline_complete=outline_complete
+        if outline_body is None:        self.outline_body=self.default_outline_body()
+        else:                           self.outline_body=outline_body
         # what comes from subclasses
         for (k,v) in settings.iteritems():
             setattr(self,k,v)
@@ -265,6 +278,8 @@ class Plugin:
 
     def default_togglable (self):       return False
     def default_toggled (self):         return 'persistent'
+    def default_outline_complete (self):return False
+    def default_outline_body(self):     return False
 
 #    # tell the framework about requirements (for the document <header>)
 #    # the notion of 'Media' in django provides for medium-dependant
index 88a56d9..09509d7 100644 (file)
@@ -1,5 +1,5 @@
 {% if visible %}
-<div id='complete-{{ domid }}' class='{% if need_toggle %}plugin-toggle{% endif %}{% if need_spin %} need-spin{% endif %}{% if persistent_toggle %} persistent-toggle{% endif %}'>
+<div id='complete-{{ domid }}' class='{% if need_toggle %}plugin-toggle{% endif %}{% if need_spin %} need-spin{% endif %}{% if persistent_toggle %} persistent-toggle{% endif %}{% if outline_complete %} plugin-outline-complete{% endif %}'>
 {% if togglable %}
 <h4 id='show-{{ domid }}' class='plugin-show'{% if not display_show_button %} style='display:none;'{% endif %}><i class="icon-hand-right"></i>
 <a href='#' class='plugin-tooltip' data-toggle='tooltip' data-original-title='Show plugin "{{ title }}" ({{ classname }})'>{{ title }}</a></h4>
@@ -10,7 +10,7 @@
 {% endif %}{# togglable #}
 {% endif %}{# visible #}
 
-<div class='plugin {{ classname }}' id='{{ domid }}'{% if not display_body %} style='display:none;'{% endif %}>
+<div class='plugin {{ classname }}{% if outline_body %} plugin-outline-body{% endif %}' id='{{ domid }}'{% if not display_body %} style='display:none;'{% endif %}>
 {{ plugin_content|safe }}
 </div>{# plugin #}