You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bloodhound.apache.org by gj...@apache.org on 2012/04/01 03:26:51 UTC

svn commit: r1307981 - in /incubator/bloodhound/trunk/bloodhound_dashboard: ./ bhdashboard/ bhdashboard/layouts/ bhdashboard/layouts/templates/ bhdashboard/templates/ bhdashboard/widgets/

Author: gjm
Date: Sun Apr  1 01:26:50 2012
New Revision: 1307981

URL: http://svn.apache.org/viewvc?rev=1307981&view=rev
Log:
Dashboard code import: BH_Dashboard: Towards a more elaborate solution introducing ILayoutProvider interface

Added:
    incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/
    incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/__init__.py   (with props)
    incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/bootstrap.py   (with props)
    incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/
    incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/bootstrap.html   (with props)
Removed:
    incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/templates/
Modified:
    incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/api.py
    incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py
    incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/ticket.py
    incubator/bloodhound/trunk/bloodhound_dashboard/setup.py

Modified: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/api.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/api.py?rev=1307981&r1=1307980&r2=1307981&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/api.py (original)
+++ incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/api.py Sun Apr  1 01:26:50 2012
@@ -62,6 +62,33 @@ class IWidgetProvider(Interface):
 
     # TODO: Add methods to specify widget metadata (e.g. parameters)
 
+class ILayoutProvider(Interface):
+    """Extension point interface implemented by components adding layouts
+    to the dashboard.
+
+    PS: Such components should implement `trac.mimeview.api.IContentConverter`
+    interface so as to save and load layout definition when necessary.
+    The pseudo-mimetype identifying layout data will be
+    `application/x-trac-layout-<layout_name>`.
+    Nonetheless they can delegate that task to other components too.
+    Let's all hail the Trac component model !
+    """
+    def get_layouts():
+        """Return an iterable listing the names of the provided layouts."""
+
+    def get_layout_description(name):
+        """Return plain text description of the layout with specified name."""
+
+    def expand_layout(name, context, options):
+        """Provide the information needed to render layout identified by
+        `name`.
+        
+        :param context: rendering context
+        :param options: additional options supplied in so as to adapt layout
+                considering data specific to this request. This allows to 
+                customize (parts of) the layout for a given request.
+        """
+
 class DashboardSystem(Component):
     implements(IPermissionRequestor)
 

Added: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/__init__.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/__init__.py?rev=1307981&view=auto
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/__init__.py (added)
+++ incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/__init__.py Sun Apr  1 01:26:50 2012
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+
+r"""Project dashboard for Apache(TM) Bloodhound
+
+Available layouts.
+"""
+

Propchange: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/__init__.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/bootstrap.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/bootstrap.py?rev=1307981&view=auto
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/bootstrap.py (added)
+++ incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/bootstrap.py Sun Apr  1 01:26:50 2012
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+
+r"""Project dashboard for Apache(TM) Bloodhound
+
+Widgets displaying ticket data.
+"""
+
+from trac.core import Component, implements, TracError
+from trac.web.chrome import add_stylesheet
+
+from bhdashboard.api import ILayoutProvider
+
+class BootstrapLayout(Component):
+    """Display a tag cloud representing frequency of values assigned to 
+    ticket fields.
+    """
+    implements(ILayoutProvider)
+
+    # ILayoutProvider methods
+    def get_layouts(self):
+        """Supported layouts.
+        """
+        yield 'bootstrap'
+
+    def get_layout_description(self, name):
+        """Return plain text description of the layout with specified name.
+        """
+        return "Bootstrap grid system " \
+                "http://twitter.github.com/bootstrap/scaffolding.html#layouts"
+
+    def expand_layout(self, name, context, options):
+        """Specify bootstrap layout template
+        """
+        req = context.req
+        add_stylesheet(req, 'dashboard/bootstrap.css')
+        return {
+              'template' : 'bootstrap.html',
+            }
+

Propchange: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/bootstrap.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/bootstrap.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/bootstrap.html?rev=1307981&view=auto
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/bootstrap.html (added)
+++ incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/bootstrap.html Sun Apr  1 01:26:50 2012
@@ -0,0 +1,61 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:py="http://genshi.edgewall.org/"
+      xmlns:xi="http://www.w3.org/2001/XInclude">
+  <xi:include href="layout.html" />
+  <head>
+    <title>$title</title>
+  </head>
+
+  <div py:def="widget_container(w)" role="application">
+    <h1 style="display: inline;">${w.title}</h1>
+    <py:if test="w.ctxtnav">
+      <py:for each="itm in w.ctxtnav">
+        &nbsp;&nbsp;$itm
+      </py:for>
+    </py:if>
+    &nbsp;&nbsp;
+    <div class="btn-group" py:if="w.altlinks" style="display: inline-block;">
+      <a class="btn btn-mini dropdown-toggle" href="#" data-toggle="dropdown">
+        <i class="icon-download-alt"></i>Download<b class="caret"></b>
+      </a>
+      <ul class="dropdown-menu">
+        <li py:for="idx, link in enumerate(w.altlinks)"
+            class="${first_last(idx, w.altlinks)}">
+          <a rel="nofollow" href="${link.href}" class="link.class"
+              py:content="link.title"></a>
+        </li>
+      </ul>
+    </div>
+    <br/>
+    ${w.content}
+  </div>
+
+  <body>
+    <div class="row">
+      <div class="span8">
+        <py:for each="(i, w) in enumerate(widgets)">
+          <py:if test="i &amp; 1 == 0">
+            ${widget_container(w)}
+          </py:if>
+        </py:for>
+      </div>
+      <div class="span4">
+        <py:for each="(i, w) in enumerate(widgets)">
+          <py:if test="i &amp; 1 == 1">
+            ${widget_container(w)}
+          </py:if>
+        </py:for>
+      </div>
+    </div>
+    <div id="ft" class="row">
+      <div id="help">
+        <strong>Note:</strong> See 
+        <a href="${href.wiki('BloodhoundDashboard')}">BloodhoundDashboard</a>
+        for help on using the dashboard.
+      </div>
+    </div>  
+  </body>
+</html>

Propchange: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/bootstrap.html
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/layouts/templates/bootstrap.html
------------------------------------------------------------------------------
    svn:mime-type = text/html

Modified: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py?rev=1307981&r1=1307980&r2=1307981&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py (original)
+++ incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py Sun Apr  1 01:26:50 2012
@@ -60,17 +60,17 @@ class DashboardModule(Component):
             add_ctxtnav(req, _('Custom Query'), req.href.query())
         if self.env[ReportModule] is not None:
             add_ctxtnav(req, _('Reports'), req.href.report())
-        add_stylesheet(req, 'dashboard/bootstrap.css')
-        return 'bootstrap_two_col_2_1.html', \
-                {
+        template, layout_data = self.expand_layout_data(req)
+        widgets = self.expand_widget_data(req, layout_data) 
+        return template, {
                     'context' : Context.from_request(req),
-                    'widgets' : self.expand_widget_data(req), 
+                    'layout' : layout_data,
+                    'widgets' : widgets,
                     'title' : _(self.mainnav_label),
                     'default' : {
                             'height' : self.default_widget_height or None
                         }
-                }, \
-                None
+                }, None
 
     # INavigationContributor methods
     def get_active_navigation_item(self, req):
@@ -99,17 +99,20 @@ class DashboardModule(Component):
         """List `templates` folders for dashboard and widgets.
         """
         resource_filename = pkg_resources.resource_filename
-        return [resource_filename('bhdashboard', 'templates'),
+        return [resource_filename('bhdashboard.layouts', 'templates'),
                 resource_filename('bhdashboard.widgets', 'templates')]
 
     # Public API
-    def expand_widget_data(self, req):
-        """Expand raw widget data and format it for use in template
+    def expand_layout_data(self, req):
+        """Determine the template needed to render a specific layout
+        and the data needed to place the widgets at expected
+        location.
 
-        Notes: So far it only renders a single report widget and there's no
-        chance to customize this at all.
+        Notes: So far it only renders a few widgets and there's no
+        chance to customize this view at all.
         """
-        # TODO: Implement dynamic dashboard specification
+        # TODO: Retrieve layout definition from somewhere
+        from bhdashboard.layouts.bootstrap import BootstrapLayout
         from bhdashboard.widgets.query import TicketQueryWidget
         from bhdashboard.widgets.ticket import TicketFieldCloudWidget
         from bhdashboard.widgets.timeline import TimelineWidget
@@ -118,28 +121,60 @@ class DashboardModule(Component):
         dashboard_query = 'status=accepted&status=assigned&status=new' \
                 '&status=reopened&group=time&col=id&col=summary&col=owner' \
                 '&col=status&col=priority&order=priority&groupdesc=1&desc=1'
-        widgets_spec = [
-                {
-                    'c' : TicketQueryWidget(self.env), 
-                    'args' : ['TicketQuery', ctx, 
-                            {'args' : {'max' : 10,
-                                    'query' : dashboard_query,
-                                    'title' : 'Dashboard'}
-                            }],
-                    'altlinks' : False
-                },
-                {
-                    'c' : TimelineWidget(self.env),
-                    'args' : ['Timeline', ctx, {'args' : {}}]
-                },
-                {
-                    'c' : TicketFieldCloudWidget(self.env),
-                    'args' : ['TicketFieldCloud', ctx, 
-                            {'args' : {'field' : 'component',
-                                    'verbose' : True}
-                            }]
-                },
-            ]
+        layout = BootstrapLayout(self.env)
+        schema = {
+                'div' : [
+                        {
+                            'class' : 'row',
+                            'div' : [
+                                    {
+                                        'class' : 'span8',
+                                        'widgets' : [1,3]
+                                    },
+                                    {
+                                        'class' : 'span4',
+                                        'widgets' : [2]
+                                    }
+                                ]
+                        }
+                    ],
+                'widgets' : [
+                        {
+                            'c' : TicketQueryWidget(self.env), 
+                            'args' : ['TicketQuery', ctx, 
+                                    {'args' : {'max' : 10,
+                                            'query' : dashboard_query,
+                                            'title' : 'Dashboard'}
+                                    }],
+                            'altlinks' : False
+                        },
+                        {
+                            'c' : TimelineWidget(self.env),
+                            'args' : ['Timeline', ctx, {'args' : {}}]
+                        },
+                        {
+                            'c' : TicketFieldCloudWidget(self.env),
+                            'args' : ['TicketFieldCloud', ctx, 
+                                    {'args' : {'field' : 'component',
+                                            'verbose' : True}
+                                    }]
+                        },
+                    ]
+            }
+
+        template = layout.expand_layout('bootstrap', ctx, {
+                'schema' : schema
+            })['template']
+        return template, schema
+
+    def expand_widget_data(self, req, schema):
+        """Expand raw widget data and format it for use in template
+
+        Notes: So far it only renders a few widgets and there's no
+        chance to customize this view at all.
+        """
+        # TODO: Implement dynamic dashboard specification
+        widgets_spec = schema.pop('widgets', [])
         chrome = Chrome(self.env)
         render = chrome.render_template
         data_strm = (w['c'].render_widget(*w['args']) for w in widgets_spec)

Modified: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/ticket.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/ticket.py?rev=1307981&r1=1307980&r2=1307981&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/ticket.py (original)
+++ incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/ticket.py Sun Apr  1 01:26:50 2012
@@ -21,7 +21,7 @@
 
 r"""Project dashboard for Apache(TM) Bloodhound
 
-Widgets displaying timeline data.
+Widgets displaying ticket data.
 """
 
 from itertools import imap, islice

Modified: incubator/bloodhound/trunk/bloodhound_dashboard/setup.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_dashboard/setup.py?rev=1307981&r1=1307980&r2=1307981&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_dashboard/setup.py (original)
+++ incubator/bloodhound/trunk/bloodhound_dashboard/setup.py Sun Apr  1 01:26:50 2012
@@ -88,13 +88,16 @@ DIST_NM = 'BloodhoundDashboardPlugin'
 PKG_INFO = {'bhdashboard' : ('bhdashboard',                     # Package dir
                             # Package data
                             ['../CHANGES', '../TODO', '../COPYRIGHT', 
-                              '../NOTICE', '../README', '../TESTING_README'
-                              'templates/*', 'htdocs/*'],
+                              '../NOTICE', '../README', '../TESTING_README'],
                           ), 
             'bhdashboard.widgets' : ('bhdashboard/widgets',     # Package dir
                             # Package data
                             ['templates/*', 'htdocs/*'],
                           ), 
+            'bhdashboard.layouts' : ('bhdashboard/layouts',     # Package dir
+                            # Package data
+                            ['templates/*', 'htdocs/*'],
+                          ), 
             'bhdashboard.tests' : ('bhdashboard/tests',     # Package dir
                             # Package data
                             ['data/**'],
@@ -104,6 +107,7 @@ PKG_INFO = {'bhdashboard' : ('bhdashboar
 ENTRY_POINTS = r"""
                [trac.plugins]
                bhdashboard.api = bhdashboard.api
+               bhdashboard.layouts.bootstrap = bhdashboard.layouts.bootstrap
                bhdashboard.web_ui = bhdashboard.web_ui
                bhdashboard.widgets.query = bhdashboard.widgets.query
                bhdashboard.widgets.report = bhdashboard.widgets.report