launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #07003
lp:~linaro-infrastructure/launchpad/upcoming-work-progress-bars into lp:launchpad
Guilherme Salgado has proposed merging lp:~linaro-infrastructure/launchpad/upcoming-work-progress-bars into lp:launchpad with lp:~linaro-infrastructure/launchpad/team-engineering-view-ui as a prerequisite.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #973443 in Launchpad itself: "Add progress bars to the new +upcomingwork page"
https://bugs.launchpad.net/launchpad/+bug/973443
For more details, see:
https://code.launchpad.net/~linaro-infrastructure/launchpad/upcoming-work-progress-bars/+merge/100808
This branch adds progress bars to the new +upcomingwork page, as shown on https://dev.launchpad.net/Projects/WorkItems
--
https://code.launchpad.net/~linaro-infrastructure/launchpad/upcoming-work-progress-bars/+merge/100808
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~linaro-infrastructure/launchpad/upcoming-work-progress-bars into lp:launchpad.
=== modified file 'lib/lp/registry/browser/team.py'
--- lib/lp/registry/browser/team.py 2012-04-04 14:52:31 +0000
+++ lib/lp/registry/browser/team.py 2012-04-04 14:52:33 +0000
@@ -2173,11 +2173,16 @@
self.workitem_counts = {}
self.bugtask_counts = {}
self.milestones_per_date = {}
+ self.progress_per_date = {}
for date, containers in self.work_item_containers:
+ total_items = 0
+ total_done = 0
milestones = set()
self.bugtask_counts[date] = 0
self.workitem_counts[date] = 0
for container in containers:
+ total_items += len(container.items)
+ total_done += len(container.done_items)
if isinstance(container, AggregatedBugsContainer):
self.bugtask_counts[date] += len(container.items)
else:
@@ -2186,6 +2191,8 @@
milestones.add(item.milestone)
self.milestones_per_date[date] = sorted(
milestones, key=attrgetter('displayname'))
+ self.progress_per_date[date] = '{0:.0f}'.format(
+ 100.0 * total_done / float(total_items))
@property
def label(self):
@@ -2231,9 +2238,13 @@
raise NotImplementedError("Must be implemented in subclasses")
@property
- def progress_text(self):
- done_items = [item for item in self._items if item.is_complete]
- return '{0:.0f}%'.format(100.0 * len(done_items) / len(self._items))
+ def done_items(self):
+ return [item for item in self._items if item.is_complete]
+
+ @property
+ def percent_done(self):
+ return '{0:.0f}'.format(
+ 100.0 * len(self.done_items) / len(self._items))
def append(self, item):
self._items.append(item)
=== modified file 'lib/lp/registry/browser/tests/test_team_upcomingwork.py'
--- lib/lp/registry/browser/tests/test_team_upcomingwork.py 2012-04-04 14:52:31 +0000
+++ lib/lp/registry/browser/tests/test_team_upcomingwork.py 2012-04-04 14:52:33 +0000
@@ -11,6 +11,7 @@
from zope.security.proxy import removeSecurityProxy
+from lp.blueprints.enums import SpecificationWorkItemStatus
from lp.registry.browser.team import (
GenericWorkItem,
getWorkItemsDueBefore,
@@ -25,6 +26,7 @@
from lp.testing.layers import DatabaseFunctionalLayer
from lp.testing.pages import (
extract_text,
+ find_tag_by_id,
find_tags_by_class,
)
from lp.testing.views import create_initialized_view
@@ -161,12 +163,12 @@
def __init__(self, is_complete):
self.is_complete = is_complete
- def test_progress_text(self):
+ def test_percent_done(self):
container = WorkItemContainer()
container.append(self.MockWorkItem(True))
container.append(self.MockWorkItem(False))
container.append(self.MockWorkItem(True))
- self.assertEqual('67%', container.progress_text)
+ self.assertEqual('67', container.percent_done)
class TestTeamUpcomingWork(BrowserTestCase):
@@ -214,6 +216,38 @@
with anonymous_logged_in():
self.assertIn(bugtask2.bug.title, tomorrows_group)
+ def test_overall_progressbar(self):
+ self.factory.makeSpecificationWorkItem(
+ assignee=self.team.teamowner, milestone=self.today_milestone,
+ status=SpecificationWorkItemStatus.DONE)
+ self.factory.makeSpecificationWorkItem(
+ assignee=self.team.teamowner, milestone=self.today_milestone,
+ status=SpecificationWorkItemStatus.INPROGRESS)
+
+ browser = self.getViewBrowser(
+ self.team, view_name='+upcomingwork', no_login=True)
+
+ progressbar = find_tag_by_id(browser.contents, 'progressbar_0')
+ self.assertEqual('50%', progressbar.get('width'))
+
+ def test_container_progressbar(self):
+ self.factory.makeSpecificationWorkItem(
+ assignee=self.team.teamowner, milestone=self.today_milestone,
+ status=SpecificationWorkItemStatus.DONE)
+ self.factory.makeSpecificationWorkItem(
+ assignee=self.team.teamowner, milestone=self.today_milestone,
+ status=SpecificationWorkItemStatus.TODO)
+
+ browser = self.getViewBrowser(
+ self.team, view_name='+upcomingwork', no_login=True)
+
+ container1_progressbar = find_tag_by_id(
+ browser.contents, 'container_progressbar_0')
+ container2_progressbar = find_tag_by_id(
+ browser.contents, 'container_progressbar_1')
+ self.assertEqual('100%', container1_progressbar.get('width'))
+ self.assertEqual('0%', container2_progressbar.get('width'))
+
class TestTeamUpcomingWorkView(TestCaseWithFactory):
=== modified file 'lib/lp/registry/templates/team-upcomingwork.pt'
--- lib/lp/registry/templates/team-upcomingwork.pt 2012-04-04 14:52:31 +0000
+++ lib/lp/registry/templates/team-upcomingwork.pt 2012-04-04 14:52:33 +0000
@@ -41,6 +41,21 @@
<div tal:repeat="pair view/work_item_containers" class="workitems-group">
<div tal:define="date python: pair[0]; containers python: pair[1]">
<h2>Work items due in <span tal:replace="date/fmt:date" /></h2>
+
+ <div>
+ <div style="float: left">Overall completion: </div>
+ <div tal:define="percent_done python: view.progress_per_date[date]"
+ tal:attributes="title string:${percent_done}% of items completed;"
+ style="border: 1px solid gray; width: 300px; float:left">
+ <img tal:attributes="id string:progressbar_${repeat/pair/index};
+ width string:${percent_done}%"
+ style="display: block"
+ src="/@@/green-bar"
+ height="15"/>
+ </div>
+ <div style="clear: both" />
+ </div>
+
<p>
From
<tal:milestones repeat="milestone python: view.milestones_per_date[date]">
@@ -77,7 +92,17 @@
<td tal:content="structure container/target_link" />
<td tal:content="structure container/assignee_link" />
<td tal:content="container/priority_title" />
- <td><span tal:replace="container/progress_text" /> done</td>
+ <td>
+ <div tal:attributes="title string:${container/percent_done}% of items completed;"
+ style="border: 1px solid gray; width: 60px">
+ <img tal:attributes="
+ id string:container_progressbar_${repeat/container/index};
+ width string:${container/percent_done}%"
+ style="display: block"
+ src="/@@/green-bar"
+ height="10"/>
+ </div>
+ </td>
</tr>
</tbody>
<tbody class="collapsible-body">