Author: rjollos Date: Fri Jul 12 02:40:41 2013 New Revision: 1502410 URL: http://svn.apache.org/r1502410 Log: Improve alignment of product widgets on the global dashboard. Fixes #566.
Clear the float with an empty div after each row to ensure that the product widgets are properly aligned on the global dashboard. Previously a single widget in the last row could move to the right. Patch by Olemis. Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/product.py bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_product.html Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py?rev=1502410&r1=1502409&r2=1502410&view=diff ============================================================================== --- bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py (original) +++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py Fri Jul 12 02:40:41 2013 @@ -224,7 +224,8 @@ class DashboardModule(Component): 'args': ['Timeline', None, {'args': {}}] }, 'products': { - 'args': ['Product', None, {'args': {'max': 3}}] + 'args': ['Product', None, {'args': {'max': 3, + 'cols': 2}}] }, } } Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/product.py URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/product.py?rev=1502410&r1=1502409&r2=1502410&view=diff ============================================================================== --- bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/product.py (original) +++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/product.py Fri Jul 12 02:40:41 2013 @@ -48,12 +48,11 @@ class ProductWidget(WidgetBase): """Return a dictionary containing arguments specification for the widget with specified name. """ - return { - 'max' : { - 'desc' : """Limit the number of products displayed""", - 'type' : int - }, - } + return {'max' : {'desc' : """Limit the number of products displayed""", + 'type' : int}, + 'cols' : {'desc' : """Number of columns""", + 'type' : int} + } get_widget_params = pretty_wrapper(get_widget_params, check_widget_name) @@ -116,8 +115,8 @@ class ProductWidget(WidgetBase): data = {} req = context.req title = '' - params = ('max', ) - max_, = self.bind_params(name, options, *params) + params = ('max', 'cols') + max_, cols = self.bind_params(name, options, *params) if not isinstance(req.perm.env, ProductEnvironment): for p in Product.select(self.env): @@ -136,6 +135,9 @@ class ProductWidget(WidgetBase): data.setdefault('product_list', []).append(p) title = _('Products') + data['colseq'] = itertools.cycle(xrange(cols - 1, -1, -1)) if cols \ + else itertools.repeat(1) + return 'widget_product.html', \ { 'title': title, Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_product.html URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_product.html?rev=1502410&r1=1502409&r2=1502410&view=diff ============================================================================== --- bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_product.html (original) +++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_product.html Fri Jul 12 02:40:41 2013 @@ -22,60 +22,63 @@ xmlns:py="http://genshi.edgewall.org/" xmlns:xi="http://www.w3.org/2001/XInclude"> <div py:if="product_list" class="row" id="products"> - <div py:for="p in product_list" class="span4"> - <div class="well product-well"> - <h4> - ☆ <a href="${req.href.products(p.prefix)}">$p.name ($p.prefix)</a> - <py:if test="p.owner_link"> - <br /> - <small>owned by - <a href="$p.owner_link">${authorinfo(p._data['owner']) if p._data['owner'] else _('(nobody)')}</a> - </small> - </py:if> - </h4> - - <h5>Milestones</h5> - <py:choose test=""> - <py:when test="p.milestones"> - <ul class="subset"> - <li py:for="m in p.milestones"> - <a href="$m.url">$m.name<py:if test="m.ticket_count is not None"> ($m.ticket_count)</py:if></a> - </li> - </ul> - </py:when> - <py:otherwise> - (No milestones for this product) - </py:otherwise> - </py:choose> - - <h5>Components</h5> - <py:choose test=""> - <py:when test="p.components"> - <ul class="subset"> - <li py:for="c in p.components"> - <a href="$c.url">$c.name<py:if test="c.ticket_count is not None"> ($c.ticket_count)</py:if></a> - </li> - </ul> - </py:when> - <py:otherwise> - (No components for this product) - </py:otherwise> - </py:choose> - - <h5>Versions</h5> - <py:choose test=""> - <py:when test="p.versions"> - <ul class="subset"> - <li py:for="v in p.versions"> - <a href="$v.url">$v.name<py:if test="v.ticket_count is not None"> ($v.ticket_count)</py:if></a> - </li> - </ul> - </py:when> - <py:otherwise> - (No versions for this product) - </py:otherwise> - </py:choose> + <py:for each="i, p in zip(colseq, product_list)"> + <div class="span4"> + <div class="well product-well"> + <h4> + ☆ <a href="${req.href.products(p.prefix)}">$p.name ($p.prefix)</a> + <py:if test="p.owner_link"> + <br /> + <small>owned by + <a href="$p.owner_link">${authorinfo(p._data['owner']) if p._data['owner'] else _('(nobody)')}</a> + </small> + </py:if> + </h4> + + <h5>Milestones</h5> + <py:choose test=""> + <py:when test="p.milestones"> + <ul class="subset"> + <li py:for="m in p.milestones"> + <a href="$m.url">$m.name<py:if test="m.ticket_count is not None"> ($m.ticket_count)</py:if></a> + </li> + </ul> + </py:when> + <py:otherwise> + (No milestones for this product) + </py:otherwise> + </py:choose> + + <h5>Components</h5> + <py:choose test=""> + <py:when test="p.components"> + <ul class="subset"> + <li py:for="c in p.components"> + <a href="$c.url">$c.name<py:if test="c.ticket_count is not None"> ($c.ticket_count)</py:if></a> + </li> + </ul> + </py:when> + <py:otherwise> + (No components for this product) + </py:otherwise> + </py:choose> + + <h5>Versions</h5> + <py:choose test=""> + <py:when test="p.versions"> + <ul class="subset"> + <li py:for="v in p.versions"> + <a href="$v.url">$v.name<py:if test="v.ticket_count is not None"> ($v.ticket_count)</py:if></a> + </li> + </ul> + </py:when> + <py:otherwise> + (No versions for this product) + </py:otherwise> + </py:choose> + </div> </div> - </div> + <div class="clearfix" py:if="i == 0" /> + </py:for> </div> </div>