improve display of rows in work items listing

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3106 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2009-01-01 19:17:51 +00:00
parent be71f62a6e
commit ed35bcf5af
7 changed files with 147 additions and 21 deletions

View file

@ -3,6 +3,23 @@ Change Log
$Id$ $Id$
1.0
---
New features
- work items (work in progress): activate by adding option
``action.portlet:createWorkitem`` to type; work items listing is shown
automatically in standard concept view.
- my work items: a query view (``userworkitems.html``); assign the query
to the person as a standard child
Bug fixes
- external collection: now works correctly (without creating empty files
in the var directory); resource type of generated object controlled by
mime type; automatically executes transformation steps on media assets
0.9 0.9
--- ---

View file

@ -235,6 +235,10 @@ class BaseView(GenericView, I18NView):
def typePredicate(self): def typePredicate(self):
return self.conceptManager.getTypePredicate() return self.conceptManager.getTypePredicate()
@Lazy
def defaultPredicate(self):
return self.conceptManager.getDefaultPredicate()
@Lazy @Lazy
def url(self): def url(self):
return absoluteURL(self.context, self.request) return absoluteURL(self.context, self.request)

View file

@ -80,6 +80,11 @@ table.listing td.checkbox {
padding-right: 2px; padding-right: 2px;
} }
table.listing td.headline {
font-weight: bold;
border: 1px solid lightgrey;
}
table.listing-details td { table.listing-details td {
white-space: normal; white-space: normal;
border: 1px solid lightgrey; border: 1px solid lightgrey;

View file

@ -196,6 +196,17 @@ class TrackDetails(BaseView):
self.view = view self.view = view
self.track = track self.track = track
@Lazy
def month(self):
ts = datetime.fromtimestamp(self.track.timeStamp)
return formatAsMonth(date(ts.year, ts.month, 1))
@property
def monthChanged(self):
result = self.view.lastMonth != self.month
self.view.lastMonth = self.month
return result
@Lazy @Lazy
def authentication(self): def authentication(self):
return component.getUtility(IAuthentication) return component.getUtility(IAuthentication)

View file

@ -17,7 +17,7 @@
# #
""" """
View class(es) for change tracks. View class(es) for work items.
$Id$ $Id$
""" """
@ -33,6 +33,7 @@ from zope.traversing.api import getName
from cybertools.browser.action import actions from cybertools.browser.action import actions
from cybertools.organize.interfaces import IWorkItems from cybertools.organize.interfaces import IWorkItems
from loops.browser.action import DialogAction from loops.browser.action import DialogAction
from loops.browser.concept import ConceptView
from loops.browser.form import ObjectForm, EditObject from loops.browser.form import ObjectForm, EditObject
from loops.browser.node import NodeView from loops.browser.node import NodeView
from loops.organize.party import getPersonForUser from loops.organize.party import getPersonForUser
@ -45,18 +46,35 @@ from loops.util import _
work_macros = ViewPageTemplateFile('work_macros.pt') work_macros = ViewPageTemplateFile('work_macros.pt')
class WorkItemsView(NodeView): # work item collections
class BaseWorkItemsView(object):
columns = set(['Task', 'User', 'Title', 'Start', 'End', 'Duration'])
lastMonth = None
def __init__(self, context, request): def __init__(self, context, request):
self.context = context self.context = context
self.request = request self.request = request
@Lazy
def work_macros(self):
return work_macros.macros
@Lazy @Lazy
def workItems(self): def workItems(self):
ts = self.loopsRoot.getRecordManager().get('work') ts = self.loopsRoot.getRecordManager().get('work')
if ts is not None: if ts is not None:
return IWorkItems(ts) return IWorkItems(ts)
class WorkItemsView(BaseWorkItemsView, NodeView):
""" Standard view for showing work items for a node's target.
"""
columns = set(['User', 'Title', 'Start', 'End', 'Duration'])
@Lazy @Lazy
def allWorkItems(self): def allWorkItems(self):
result = [] result = []
@ -69,7 +87,33 @@ class WorkItemsView(NodeView):
return result return result
class UserWorkItems(BaseWorkItemsView, ConceptView):
""" A query view showing work items for a person, the query's parent.
"""
columns = set(['Task', 'Title', 'Start', 'End', 'Duration'])
@property
def macro(self):
return self.work_macros['userworkitems']
@Lazy
def allWorkItems(self):
workItems = self.workItems
if self.workItems is None:
return []
result = []
for target in self.context.getParents([self.defaultPredicate]):
for wi in workItems.query(userName=util.getUidForObject(target)):
result.append(WorkItemDetails(self, wi))
return result
# single work items
class WorkItemDetails(TrackDetails): class WorkItemDetails(TrackDetails):
""" Render a single work item.
"""
@Lazy @Lazy
def description(self): def description(self):
@ -81,13 +125,30 @@ class WorkItemDetails(TrackDetails):
@Lazy @Lazy
def end(self): def end(self):
return self.formatTimeStamp(self.track.end)[-5:] ts = self.formatTimeStamp(self.track.end)
return ts and ts[-5:] or ''
@Lazy
def duration(self):
return self.formatTimeDelta(self.track.duration)
@Lazy
def effort(self):
return self.formatTimeDelta(self.track.effort)
def formatTimeDelta(self, value):
if not value:
return ''
h, m = divmod(int(value) / 60, 60)
return '%02i:%02i' % (h, m)
class WorkItemView(BaseTrackView): class WorkItemView(BaseTrackView):
""" Show a single work item in the management view.
"""
pass
# forms and form controllers
class CreateWorkItemForm(ObjectForm, BaseTrackView): class CreateWorkItemForm(ObjectForm, BaseTrackView):

View file

@ -28,6 +28,14 @@
class="loops.organize.work.browser.WorkItemsView" class="loops.organize.work.browser.WorkItemsView"
permission="zope.View" /> permission="zope.View" />
<zope:adapter
name="userworkitems.html"
for="loops.interfaces.IConcept
zope.publisher.interfaces.browser.IBrowserRequest"
provides="zope.interface.Interface"
factory="loops.organize.work.browser.UserWorkItems"
permission="zope.View" />
<browser:page <browser:page
name="create_workitem.html" name="create_workitem.html"
for="loops.interfaces.INode" for="loops.interfaces.INode"

View file

@ -2,37 +2,57 @@
<!-- $Id$ --> <!-- $Id$ -->
<!-- listings -->
<metal:work define-macro="workitems" <metal:work define-macro="workitems"
tal:define="workItems nocall:view/workItems" tal:define="work nocall:view/workItems"
tal:condition="workItems/allWorkItems"> tal:condition="work/allWorkItems">
<br /> <br />
<h2 i18n:translate="">Work Items</h2> <h2 i18n:translate="">Work Items</h2>
<metal:workitems define-macro="workitems_listing" <metal:workitems define-macro="workitems_listing"
tal:define="workItems nocall:workItems|nocall:view/workItems;"> tal:define="work nocall:work|nocall:view/workItems;">
<table class="listing"> <table class="listing">
<tr> <tr>
<th i18n:translate="">Title</th> <tal:colheader repeat="column python:
<th i18n:translate="">User</th> ('Start', 'End', 'Duration', 'Task', 'User', 'Title')">
<th i18n:translate="">Start</th> <th tal:condition="python: column in work.columns"
<th i18n:translate="">End</th> tal:content="column"
i18n:translate="">Task</th>
</tal:colheader>
</tr> </tr>
<tal:workitem tal:repeat="workItem workItems/allWorkItems"> <tal:workitem tal:repeat="row work/allWorkItems">
<tr tal:condition="row/monthChanged">
<td class="headline"
tal:attributes="colspan python: len(work.columns)"
tal:content="row/month">2009-01</td></tr>
<tr tal:attributes="class python: <tr tal:attributes="class python:
repeat['workItem'].odd() and 'even' or 'odd'"> repeat['row'].odd() and 'even' or 'odd'">
<td> <td class="nowrap center" tal:content="row/start">2007-03-30</td>
<span tal:content="workItem/track/title">Title</span></td> <td class="nowrap center" tal:content="row/end">2007-03-30</td>
<td> <td class="nowrap center" tal:content="row/duration">2:30</td>
<span tal:replace="workItem/user/title">John</span></td> <td tal:condition="python: 'Task' in work.columns">
<td class="nowrap"> <a tal:attributes="href row/objectData/url"
<span tal:replace="workItem/start">2007-03-30</span></td> tal:content="row/objectData/title">Task</a></td>
<td class="nowrap"> <td tal:condition="python: 'User' in work.columns">
<span tal:replace="workItem/end">2007-03-30</span></td> <a tal:attributes="href row/user/url"
tal:content="row/user/title">John</a></td>
<td tal:content="row/track/title"
tal:attributes="title row/track/description">Title</td>
</tr> </tr>
</tal:workitem> </tal:workitem>
</table> </table>
</metal:workitems> </metal:workitems>
</metal:work> </metal:work>
<metal:work define-macro="userworkitems"
tal:define="work nocall:item">
<br />
<h2 i18n:translate="" tal:content="item/title">Work Items</h2>
<metal:workitems use-macro="item/work_macros/workitems_listing" />
</metal:work>
<!-- forms -->
<metal:block define-macro="create_workitem"> <metal:block define-macro="create_workitem">
<form method="post" id="addWorkitem_form" class="dialog" <form method="post" id="addWorkitem_form" class="dialog"