diff --git a/browser/concept_macros.pt b/browser/concept_macros.pt index 9113abc..d48f238 100644 --- a/browser/concept_macros.pt +++ b/browser/concept_macros.pt @@ -101,7 +101,7 @@ Resource Title - Type Type Type @@ -162,7 +162,8 @@
Resource Title
- Type + + Type diff --git a/browser/node.py b/browser/node.py index df2180f..794f646 100644 --- a/browser/node.py +++ b/browser/node.py @@ -117,6 +117,7 @@ class NodeView(BaseView): if not IUnauthenticatedPrincipal.providedBy(self.request.principal): mi = self.controller.memberInfo title = mi.title.value or _(u'Personal Informations') + url=None obj = mi.get('object') if obj is not None: query = self.conceptManager.get('personal_info') @@ -125,11 +126,11 @@ class NodeView(BaseView): url = self.getUrlForTarget(obj.value) else: url = self.getUrlForTarget(query) - cm.register('portlet_right', 'personal', title=title, - subMacro=node_macros.macros['personal'], - icon='cybertools.icons/user.png', - url=url, - priority=10) + cm.register('portlet_right', 'personal', title=title, + subMacro=node_macros.macros['personal'], + icon='cybertools.icons/user.png', + url=url, + priority=10) # force early portlet registrations by target by setting up target view self.virtualTarget diff --git a/organize/tracking/report.py b/organize/tracking/report.py index 4fef072..c547c7f 100644 --- a/organize/tracking/report.py +++ b/organize/tracking/report.py @@ -269,7 +269,9 @@ class TrackDetails(BaseView): @Lazy def user(self): - userName = self.track.userName + return self.getUserForUserName(self.track.userName) + + def getUserForUserName(self, userName): obj = util.getObjectForUid(userName) if obj is None: try: @@ -292,9 +294,6 @@ class TrackDetails(BaseView): @Lazy def timeStamp(self): return self.formatTimeStamp(self.track.timeStamp) - #value = datetime.fromtimestamp(self.track.timeStamp) - #return format.formatDate(value, 'dateTime', self.timeStampFormat, - # self.view.languageInfo.language) def formatTimeStamp(self, ts, f='dateTime'): if not ts: diff --git a/organize/work/browser.py b/organize/work/browser.py index c2a8d7e..f45a25a 100644 --- a/organize/work/browser.py +++ b/organize/work/browser.py @@ -30,6 +30,7 @@ from zope.app.pagetemplate import ViewPageTemplateFile from zope.traversing.browser import absoluteURL from zope.traversing.api import getName +from cybertools.ajax import innerHtml from cybertools.browser.action import actions from cybertools.organize.interfaces import IWorkItems from loops.browser.action import DialogAction @@ -37,6 +38,7 @@ from loops.browser.concept import ConceptView from loops.browser.form import ObjectForm, EditObject from loops.browser.node import NodeView from loops.organize.party import getPersonForUser +from loops.organize.stateful.browser import StateAction from loops.organize.tracking.browser import BaseTrackView from loops.organize.tracking.report import TrackDetails from loops import util @@ -50,7 +52,7 @@ work_macros = ViewPageTemplateFile('work_macros.pt') class BaseWorkItemsView(object): - columns = set(['Task', 'User', 'Title', 'Start', 'End', 'Duration']) + columns = set(['Task', 'User', 'Title', 'Start', 'End', 'Duration', 'Info']) lastMonth = lastDay = None @@ -85,7 +87,7 @@ class WorkItemsView(BaseWorkItemsView, NodeView): """ Standard view for showing work items for a node's target. """ - columns = set(['User', 'Title', 'Day', 'Start', 'End', 'Duration']) + columns = set(['User', 'Title', 'Day', 'Start', 'End', 'Duration', 'Info']) @Lazy def allWorkItems(self): @@ -105,7 +107,7 @@ class UserWorkItems(BaseWorkItemsView, ConceptView): """ A query view showing work items for a person, the query's parent. """ - columns = set(['Task', 'Title', 'Day', 'Start', 'End', 'Duration']) + columns = set(['Task', 'Title', 'Day', 'Start', 'End', 'Duration', 'Info']) @property def macro(self): @@ -152,12 +154,73 @@ class WorkItemDetails(TrackDetails): def effort(self): return self.formatTimeDelta(self.track.effort) + @Lazy + def startDay(self): + return self.formatTimeStamp(self.track.timeStamp, 'date') + + @Lazy + def created(self): + return self.formatTimeStamp(self.track.created, 'dateTime') + def formatTimeDelta(self, value): if not value: return '' h, m = divmod(int(value) / 60, 60) return '%02i:%02i' % (h, m) + @Lazy + def isLastInRun(self): + currentWorkItems = list(self.view.workItems.query(runId=self.track.runId)) + return self.track == currentWorkItems[-1] + + def actions(self): + info = DialogAction(self.view, + description=_(u'Information about this work item.'), + viewName='workitem_info.html', + dialogName='', + icon='cybertools.icons/info.png', + cssClass='icon-action', + page=self.view.nodeView, + target=self.object, + addParams=dict(id=self.track.__name__)) + actions = [info, WorkItemStateAction(self)] + if self.isLastInRun: + self.view.registerDojoDateWidget() + self.view.registerDojoNumberWidget() + actions.append(DialogAction(self.view, + description=_(u'Create a work item.'), + viewName='create_workitem.html', + dialogName='', + icon='edit.gif', + cssClass='icon-action', + page=self.view.nodeView, + target=self.object, + addParams=dict(id=self.track.__name__))) + return actions + + +class WorkItemInfo(NodeView): + """ Provides info box. + """ + + __call__ = innerHtml + + @property + def macro(self): + return work_macros.macros['workitem_info'] + + @Lazy + def dialog_name(self): + return self.request.get('dialog', 'workitem_info') + + @Lazy + def track(self): + id = self.request.form.get('id') + if id is not None: + workItems = self.loopsRoot.getRecordManager()['work'] + track = workItems.get(id) + return WorkItemDetails(self, track) + class WorkItemView(BaseTrackView): """ Show a single work item in the management view. @@ -174,6 +237,21 @@ class CreateWorkItemForm(ObjectForm, BaseTrackView): def macro(self): return self.template.macros['create_workitem'] + @Lazy + def track(self): + id = self.request.form.get('id') + if id is not None: + workItems = self.loopsRoot.getRecordManager()['work'] + return workItems.get(id) + + @Lazy + def title(self): + return self.track is not None and self.track.title or u'' + + @Lazy + def description(self): + return self.track is not None and self.track.description or u'' + @Lazy def defaultDate(self): return time.strftime('%Y-%m-%d') @@ -185,6 +263,13 @@ class CreateWorkItemForm(ObjectForm, BaseTrackView): class CreateWorkItem(EditObject, BaseTrackView): + @Lazy + def track(self): + id = self.request.form.get('id') + if id is not None: + workItems = self.loopsRoot.getRecordManager()['work'] + return workItems.get(id) + @Lazy def personId(self): p = getPersonForUser(self.context, self.request) @@ -229,7 +314,10 @@ class CreateWorkItem(EditObject, BaseTrackView): action, data = self.processForm() if not action: return True - wi = workItems.add(util.getUidForObject(self.object), self.personId) + if self.track is not None: + wi = self.track + else: + wi = workItems.add(util.getUidForObject(self.object), self.personId) wi.doAction(action, self.personId, **data) url = self.view.virtualTargetUrl + '?version=this' self.request.response.redirect(url) @@ -247,6 +335,19 @@ actions.register('createWorkitem', 'portlet', DialogAction, ) +class WorkItemStateAction(StateAction): + + cssClass = 'icon-action' + + @Lazy + def stateful(self): + return self.view.track + + @Lazy + def description(self): + return _(self.stateObject.title) + + # auxiliary functions def parseTime(s): diff --git a/organize/work/configure.zcml b/organize/work/configure.zcml index 0b19ec6..78b95a3 100644 --- a/organize/work/configure.zcml +++ b/organize/work/configure.zcml @@ -49,6 +49,12 @@ factory="loops.organize.work.browser.CreateWorkItem" permission="zope.View" /> + + + tal:define="work nocall:view/workItems" + tal:condition="work/allWorkItems">

Work Items

+ ('Day', 'Start', 'End', 'Duration', 'Task', 'User', 'Title', 'Info')"> Task @@ -39,6 +39,11 @@ tal:content="row/user/title">John Title + + + + + @@ -60,20 +65,22 @@ dojoType="dijit.form.Form"> +
Add Work Item
-
+ tal:attributes="value view/title" />
+ dojoType="dijit.form.SimpleTextarea" style="width: 60em" + tal:content="view/description">
@@ -115,4 +122,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Work Item Information


Title:
Description:
Party:
Task:
Start - End: + - +
Duration/Effort: / +
Comment:
State:
Created: + ()

+ +
+
+ + diff --git a/search/search.pt b/search/search.pt index 0fdfe35..73c1473 100644 --- a/search/search.pt +++ b/search/search.pt @@ -80,10 +80,10 @@ tal:attributes="src icon/src" />
- Type - 1.1 - + Size modified John -