work in progress: meeting minutes: view + corresponding portlet action

This commit is contained in:
Helmut Merz 2012-05-05 10:35:22 +02:00
parent 058de979d8
commit 2f9fbb215e
7 changed files with 152 additions and 7 deletions

View file

@ -42,6 +42,8 @@ results_template = ViewPageTemplateFile('results.pt')
class ReportView(ConceptView): class ReportView(ConceptView):
""" A view for defining (editing) a report.
"""
@Lazy @Lazy
def report_macros(self): def report_macros(self):
@ -106,3 +108,52 @@ class ResultsView(NodeView):
def getColumnRenderer(self, col): def getColumnRenderer(self, col):
return self.result_macros[col.renderer] return self.result_macros[col.renderer]
class ResultsConceptView(ConceptView):
""" View on a concept using a report.
"""
reportName = None # define in subclass if applicable
@Lazy
def result_macros(self):
return self.controller.getTemplateMacros('results', results_template)
@Lazy
def resultsRenderer(self):
return self.reportInstance.getResultsRenderer(
'results', self.result_macros)
@Lazy
def macro(self):
return self.result_macros['content']
@Lazy
def hasReportPredicate(self):
return self.conceptManager['hasreport']
@Lazy
def report(self):
if self.reportName:
return adapted(self.conceptManager[self.reportName])
type = self.context.conceptType
reports = type.getParents([self.hasReportPredicate])
return adapted(reports[0])
@Lazy
def reportInstance(self):
ri = component.getAdapter(self.report, IReportInstance,
name=self.report.reportType)
ri.view = self.nodeView
return ri
def results(self):
return self.reportInstance.getResults(dict(tasks=util.getUidForObject(self.context)))
@Lazy
def displayedColumns(self):
return self.reportInstance.getActiveOutputFields()
def getColumnRenderer(self, col):
return self.result_macros[col.renderer]

View file

@ -3,7 +3,8 @@
<div metal:define-macro="main" <div metal:define-macro="main"
tal:define="item nocall:item/virtualTarget; tal:define="item nocall:item/virtualTarget;
report view/reportInstance"> report view/reportInstance;
reportView nocall:view">
<div tal:attributes="class string:content-$level;"> <div tal:attributes="class string:content-$level;">
<metal:block use-macro="view/concept_macros/concepttitle" /> <metal:block use-macro="view/concept_macros/concepttitle" />
</div> </div>
@ -14,9 +15,19 @@
</div> </div>
<div metal:define-macro="content"
tal:define="report item/reportInstance;
reportView nocall:item">
<div tal:attributes="class string:content-$level;">
<metal:block use-macro="view/concept_macros/concepttitle" />
</div>
<div metal:use-macro="item/resultsRenderer" />
</div>
<div metal:define-macro="results"> <div metal:define-macro="results">
<table class="report" <table class="report"
tal:define="results view/results"> tal:define="results reportView/results">
<tr> <tr>
<th tal:repeat="col results/displayedColumns" <th tal:repeat="col results/displayedColumns"
tal:content="col/title" tal:content="col/title"
@ -25,14 +36,16 @@
</tr> </tr>
<tr tal:repeat="row results"> <tr tal:repeat="row results">
<td tal:repeat="col results/displayedColumns"> <td tal:repeat="col results/displayedColumns">
<metal:column use-macro="python:view.getColumnRenderer(col)" /> <metal:column use-macro="python:
reportView.getColumnRenderer(col)" />
</td> </td>
</tr> </tr>
<tr tal:define="row nocall:results/totals" <tr tal:define="row nocall:results/totals"
tal:condition="nocall:row"> tal:condition="nocall:row">
<td tal:repeat="col results/displayedColumns" <td tal:repeat="col results/displayedColumns"
tal:attributes="class col/cssClass"> tal:attributes="class col/cssClass">
<metal:column use-macro="python:view.getColumnRenderer(col)" /> <metal:column use-macro="python:
reportView.getColumnRenderer(col)" />
</td> </td>
</tr> </tr>
</table> </table>
@ -86,13 +99,15 @@
</tr> </tr>
<tr tal:repeat="row results"> <tr tal:repeat="row results">
<td tal:repeat="col results/displayedColumns"> <td tal:repeat="col results/displayedColumns">
<metal:column use-macro="python:view.getColumnRenderer(col)" /> <metal:column use-macro="python:
reportView.getColumnRenderer(col)" />
</td> </td>
</tr> </tr>
<tr tal:define="row nocall:results/totals" <tr tal:define="row nocall:results/totals"
tal:condition="nocall:row"> tal:condition="nocall:row">
<td tal:repeat="col results/displayedColumns"> <td tal:repeat="col results/displayedColumns">
<metal:column use-macro="python:view.getColumnRenderer(col)" /> <metal:column use-macro="python:
reportView.getColumnRenderer(col)" />
</td> </td>
</tr> </tr>
</table> </table>

View file

@ -97,7 +97,7 @@ class ReportInstance(BaseReport):
if dynaParams is not None: if dynaParams is not None:
for k, v in dynaParams.items(): for k, v in dynaParams.items():
if k in crit.parts.keys(): if k in crit.parts.keys():
crit.parts[k].value = v crit.parts[k].comparisonValue = v
parts = Jeep(crit.parts) parts = Jeep(crit.parts)
result = list(self.selectObjects(parts)) # may modify parts result = list(self.selectObjects(parts)) # may modify parts
qc = CompoundQueryCriteria(parts) qc = CompoundQueryCriteria(parts)

View file

@ -97,6 +97,12 @@
set_schema="loops.expert.report.IReportInstance" /> set_schema="loops.expert.report.IReportInstance" />
</zope:class> </zope:class>
<browser:page
name="meeting_minutes.html"
for="loops.interfaces.IConceptSchema"
class="loops.organize.work.meeting.MeetingMinutes"
permission="zope.View" />
<!-- setup --> <!-- setup -->
<zope:adapter factory="loops.organize.work.setup.SetupManager" <zope:adapter factory="loops.organize.work.setup.SetupManager"

15
organize/work/meeting.pt Normal file
View file

@ -0,0 +1,15 @@
<html i18n:domain="loops">
<div metal:define-macro="content"
tal:define="report item/reportInstance;
reportView nocall:item">
<div tal:attributes="class string:content-$level;">
<metal:block use-macro="view/concept_macros/concepttitle" />
<metal:block use-macro="view/concept_macros/conceptfields" />
</div>
<div metal:use-macro="item/resultsRenderer" />
</div>
</html>

52
organize/work/meeting.py Normal file
View file

@ -0,0 +1,52 @@
#
# Copyright (c) 2012 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
View class(es) for accessing tasks and work items as meeting minutes.
"""
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.cachedescriptors.property import Lazy
from cybertools.browser.action import actions
from loops.browser.action import TargetAction
from loops.expert.browser.report import ResultsConceptView
from loops.util import _
meeting_template = ViewPageTemplateFile('meeting.pt')
actions.register('meeting_minutes', 'portlet', TargetAction,
title=_(u'Show Meeting Minutes...'),
description=_(u'Show meeting minutes for this object.'),
viewName='meeting_minutes.html',
)
class MeetingMinutes(ResultsConceptView):
reportName = 'meeting_minutes'
@Lazy
def meeting_macros(self):
return meeting_template.macros
@Lazy
def macro(self):
return self.meeting_macros['content']

View file

@ -247,8 +247,14 @@ class MeetingMinutesWork(WorkReportInstance, SubReport):
rowFactory = MeetingMinutesWorkRow rowFactory = MeetingMinutesWorkRow
fields = Jeep((workTitle, party, day, state)) #description,
defaultOutputFields = fields
states = ('planned',) states = ('planned',)
@property
def queryCriteria(self):
return CompoundQueryCriteria([])
def selectObjects(self, parts): def selectObjects(self, parts):
parts.pop('tasks', None) parts.pop('tasks', None)
t = self.parentRow.context t = self.parentRow.context