merge branch master

This commit is contained in:
Helmut Merz 2012-05-15 16:52:55 +02:00
commit f9dca48cde
22 changed files with 349 additions and 36 deletions

View file

@ -77,6 +77,7 @@ from loops.versioning.interfaces import IVersionable
concept_macros = ViewPageTemplateFile('concept_macros.pt') concept_macros = ViewPageTemplateFile('concept_macros.pt')
conceptMacrosTemplate = concept_macros conceptMacrosTemplate = concept_macros
resource_macros = ViewPageTemplateFile('resource_macros.pt') resource_macros = ViewPageTemplateFile('resource_macros.pt')
form_macros = ViewPageTemplateFile('form_macros.pt')
class NameField(schema.ASCIILine): class NameField(schema.ASCIILine):
@ -161,7 +162,10 @@ class BaseView(GenericView, I18NView):
@Lazy @Lazy
def resource_macros(self): def resource_macros(self):
return self.controller.getTemplateMacros('resource', resource_macros) return self.controller.getTemplateMacros('resource', resource_macros)
#return resource_macros.macros
@Lazy
def form_macros(self):
return self.controller.getTemplateMacros('form', form_macros)
def breadcrumbs(self): def breadcrumbs(self):
return [] return []

View file

@ -45,7 +45,8 @@
values python: [v for v in data.values() if v]; values python: [v for v in data.values() if v];
fields item/fields" fields item/fields"
tal:condition="values"> tal:condition="values">
<table tal:attributes="ondblclick item/openEditWindow"> <table class="fields"
tal:attributes="ondblclick item/openEditWindow">
<tal:row repeat="field fields"> <tal:row repeat="field fields">
<tr tal:define="fieldName field/name; <tr tal:define="fieldName field/name;
value nocall:data/?fieldName; value nocall:data/?fieldName;

View file

@ -147,6 +147,10 @@ table.records th, table.records td {
border: 1px solid black; border: 1px solid black;
} }
table.report td {
vertical-align: top;
}
dl.docutils dt { dl.docutils dt {
font-weight: bold; font-weight: bold;
margin-top: 0.3em; margin-top: 0.3em;
@ -422,6 +426,19 @@ img.notselected {
margin-bottom: 4px; margin-bottom: 4px;
} }
.header-1 {
font-size: 120%;
font-weight: bold;
}
.center {
text-align: center;
}
.right {
text-align: right;
}
/* comments */ /* comments */
div.comment { div.comment {

View file

@ -27,7 +27,8 @@
<div id="content" class="span-6" <div id="content" class="span-6"
metal:define-macro="content"> metal:define-macro="content">
<metal:breadcrumbs define-slot="breadcrumbs"> <metal:breadcrumbs define-slot="breadcrumbs">
<table tal:define="crumbs view/breadcrumbs" <table class="breadcrumbs"
tal:define="crumbs view/breadcrumbs"
tal:condition="crumbs"> tal:condition="crumbs">
<tr> <tr>
<td style="white-space: nowrap; vertical-align: top; width: 10%" <td style="white-space: nowrap; vertical-align: top; width: 10%"

View file

@ -100,18 +100,30 @@ textarea {
font-size: 100%; font-size: 100%;
} }
table {
border-collapse: collapse;
}
thead th { thead th {
background: none; background: none;
} }
/* class-specific */ /* class-specific */
.breadcrumbs td {
padding-left: 0;
}
.description { .description {
font-style: italic; font-style: italic;
/* margin-top: 0.5em;*/ /* margin-top: 0.5em;*/
margin-bottom: 0.3em; margin-bottom: 0.3em;
} }
.fields td {
vertical-align: top;
}
.dialog div.heading { .dialog div.heading {
font-weight: bold; font-weight: bold;
font-size: 140%; font-size: 140%;
@ -136,7 +148,6 @@ table.listing {
margin: 1px; margin: 1px;
/*margin-top: 0.5em; */ /*margin-top: 0.5em; */
margin-bottom: 1em; margin-bottom: 1em;
border-collapse: collapse;
} }
table.listing th { table.listing th {
@ -206,10 +217,6 @@ table.listing th span.descending {
background-repeat: no-repeat; background-repeat: no-repeat;
} }
table.records {
border-collapse: collapse;
}
table.records input, table.records textarea { table.records input, table.records textarea {
border: none; border: none;
padding: 0; padding: 0;
@ -490,6 +497,11 @@ img.notselected {
margin-bottom: 4px; margin-bottom: 4px;
} }
.header-1 {
font-size: 120%;
font-weight: bold;
}
.center { .center {
text-align: center; text-align: center;
} }

View file

@ -166,8 +166,8 @@ class AdapterBase(object):
def uid(self): def uid(self):
return util.getUidForObject(self.context) return util.getUidForObject(self.context)
def getChildren(self): def getChildren(self, predicates=None):
for c in self.context.getChildren(): for c in self.context.getChildren(predicates):
yield adapted(c, self.languageInfo) yield adapted(c, self.languageInfo)
def getLongTitle(self): def getLongTitle(self):

View file

@ -27,7 +27,9 @@ from zope.cachedescriptors.property import Lazy
from cybertools.typology.interfaces import IType from cybertools.typology.interfaces import IType
from loops.browser.lobo import standard from loops.browser.lobo import standard
from loops.browser.concept import ConceptRelationView as BaseConceptRelationView from loops.browser.concept import ConceptView
from loops.browser.concept import ConceptRelationView as \
BaseConceptRelationView
from loops.browser.resource import ResourceView as BaseResourceView from loops.browser.resource import ResourceView as BaseResourceView
from loops.common import adapted, baseObject from loops.common import adapted, baseObject
@ -36,7 +38,24 @@ standard_template = standard.standard_template
book_template = ViewPageTemplateFile('view_macros.pt') book_template = ViewPageTemplateFile('view_macros.pt')
class PageLayout(standard.Layout): class Base(object):
@Lazy
def isPartOfPredicate(self):
return self.conceptManager['ispartof']
@Lazy
def breadcrumbsParent(self):
for p in self.context.getParents([self.isPartOfPredicate]):
return self.nodeView.getViewForTarget(p)
class SectionView(Base, ConceptView):
pass
class PageLayout(Base, standard.Layout):
def getParts(self): def getParts(self):
parts = ['headline', 'keyquestions', 'quote', 'maintext', parts = ['headline', 'keyquestions', 'quote', 'maintext',

View file

@ -17,6 +17,14 @@
<!-- Views --> <!-- Views -->
<zope:adapter
name="section_view"
for="loops.interfaces.IConcept
loops.browser.skin.Lobo"
provides="zope.interface.Interface"
factory="loops.compound.book.browser.SectionView"
permission="zope.View" />
<zope:adapter <zope:adapter
name="page_layout" name="page_layout"
for="loops.interfaces.IConcept for="loops.interfaces.IConcept

View file

@ -7,7 +7,7 @@ type(u'book', u'Buch', viewName=u'', typeInterface=u'',
type(u'page', u'Seite', viewName=u'page_layout', type(u'page', u'Seite', viewName=u'page_layout',
typeInterface=u'loops.compound.book.interfaces.IPage', typeInterface=u'loops.compound.book.interfaces.IPage',
options=u'action.portlet:edit_concept') options=u'action.portlet:edit_concept')
type(u'section', u'Kapitel', viewName=u'', typeInterface=u'', type(u'section', u'Kapitel', viewName=u'section_view', typeInterface=u'',
options=u'action.portlet:create_subtype,edit_concept') options=u'action.portlet:create_subtype,edit_concept')
concept(u'system', u'System', u'domain') concept(u'system', u'System', u'domain')

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):
@ -107,3 +109,51 @@ 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>
@ -76,7 +89,6 @@
<div metal:define-macro="subreport"> <div metal:define-macro="subreport">
<tal:column>
<table class="subreport" <table class="subreport"
tal:define="results python:col.getValue(row)"> tal:define="results python:col.getValue(row)">
<tr> <tr>
@ -86,17 +98,18 @@
</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>
</tal:column>
</div> </div>

View file

@ -60,6 +60,7 @@ class DecimalField(Field):
styleData = {'text-align':'right'} styleData = {'text-align':'right'}
styleData = dict(Field.style.data, **styleData) styleData = dict(Field.style.data, **styleData)
style = TableCellStyle(**styleData) style = TableCellStyle(**styleData)
cssClass = 'number'
def getDisplayValue(self, row): def getDisplayValue(self, row):
value = self.getRawValue(row) value = self.getRawValue(row)
@ -228,6 +229,7 @@ class SubReportField(Field):
baseReport = row.parent.context baseReport = row.parent.context
instance = self.reportFactory(baseReport.context) instance = self.reportFactory(baseReport.context)
instance.view = baseReport.view instance.view = baseReport.view
instance.parentRow = row
return instance return instance
def getValue(self, row): def getValue(self, row):

View file

@ -98,7 +98,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)

Binary file not shown.

View file

@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: $Id$\n" "Project-Id-Version: $Id$\n"
"POT-Creation-Date: 2007-05-22 12:00 CET\n" "POT-Creation-Date: 2007-05-22 12:00 CET\n"
"PO-Revision-Date: 2012-03-28 12:00 CET\n" "PO-Revision-Date: 2012-05-09 12:00 CET\n"
"Last-Translator: Helmut Merz <helmutm@cy55.de>\n" "Last-Translator: Helmut Merz <helmutm@cy55.de>\n"
"Language-Team: loops developers <helmutm@cy55.de>\n" "Language-Team: loops developers <helmutm@cy55.de>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -266,6 +266,24 @@ msgstr "Daten des Video-Objekts bearbeiten"
msgid "Play Movie" msgid "Play Movie"
msgstr "Video abspielen" msgstr "Video abspielen"
msgid "Show Meeting Minutes..."
msgstr "Besprechungsprotokoll anzeigen..."
msgid "Show meeting minutes for this object."
msgstr "Besprechungsprotokoll für dieses Objekt anzeigen."
msgid "Task/Action"
msgstr "Aufgabe"
msgid "Who/When"
msgstr "Wer? Bis wann?"
msgid "Who?"
msgstr "Wer?"
msgid "When?"
msgstr "Wann?"
msgid "Favorites" msgid "Favorites"
msgstr "Lesezeichen" msgstr "Lesezeichen"
@ -398,6 +416,9 @@ msgstr "Status"
msgid "Save" msgid "Save"
msgstr "Speichern" msgstr "Speichern"
msgid "Save Changes"
msgstr "Änderungen speichern"
msgid "Cancel" msgid "Cancel"
msgstr "Abbrechen" msgstr "Abbrechen"

View file

@ -70,7 +70,7 @@ class MemberRegistrationManager(object):
if pfName is None: if pfName is None:
pfName = options(self.principalfolder_key, pfName = options(self.principalfolder_key,
(self.default_principalfolder,))[0] (self.default_principalfolder,))[0]
self.createPrincipal(pfName, userId, password, lastName, firstName) self.createPrincipal(pfName, userId, password, lastName, firstName, useExisting=useExisting)
if not groups: if not groups:
groups = options(self.groups_key, ()) groups = options(self.groups_key, ())
self.setGroupsForPrincipal(pfName, userId, groups=groups) self.setGroupsForPrincipal(pfName, userId, groups=groups)

View file

@ -1,5 +1,5 @@
# #
# Copyright (c) 2011 Helmut Merz helmutm@cy55.de # Copyright (c) 2012 Helmut Merz helmutm@cy55.de
# #
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@ -18,8 +18,6 @@
""" """
View class(es) for work items. View class(es) for work items.
$Id$
""" """
from datetime import date from datetime import date
@ -235,9 +233,9 @@ class BaseWorkItemsView(object):
result['timeFromTo'] = (tsFrom, tsTo) result['timeFromTo'] = (tsFrom, tsTo)
state = form.get('wi_state') or self.options.wi_state state = form.get('wi_state') or self.options.wi_state
if not state: if not state:
result['state'] = ['planned', 'accepted', 'running', 'done', 'done_x', result['state'] = ['planned', 'accepted', 'running', 'done',
'finished', 'delegated', 'moved', 'done_x', 'finished', 'delegated', 'moved', 'cancelled']
'cancelled'] #, 'closed']
elif state != 'all': elif state != 'all':
result['state'] = state result['state'] = state
return result return result

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"

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

@ -0,0 +1,62 @@
<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><br />
<div metal:use-macro="reportView/resultsRenderer" />
</div>
<div metal:define-macro="results">
<table class="report"
tal:define="results reportView/results">
<tr>
<th i18n:translate=""
style="border: 1px solid grey">Task/Action</th>
<th style="border: 1px solid grey"
i18n:translate="">Who?</th>
<th style="border: 1px solid grey"
i18n:translate="">When?</th>
<th style="border: 1px solid grey"
i18n:translate=""></th>
</tr>
<tal:task repeat="row results">
<tr tal:repeat="colname python: ('title', 'description',)">
<td style="border: 1px solid grey"
tal:define="col report/fields/?colname"
tal:attributes="class col/cssClass">
<metal:column use-macro="python:
reportView.getColumnRenderer(col)" />
</td>
<td style="border: 1px solid grey" />
<td style="border: 1px solid grey" />
<td style="border: 1px solid grey" />
</tr>
<tal:workitems define="col report/fields/workItems">
<metal:column use-macro="python:
reportView.getColumnRenderer(col)" />
</tal:workitems>
</tal:task>
</table>
</div>
<div metal:define-macro="subreport"
tal:define="results python:col.getValue(row)">
<tr class="listing" tal:repeat="row results">
<td tal:repeat="col results/displayedColumns"
tal:attributes="class col/cssClass"
style="border: 1px solid grey">
<metal:column use-macro="python:
reportView.getColumnRenderer(col)" />
</td>
</tr>
</div>
</html>

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

@ -0,0 +1,61 @@
#
# 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']
@Lazy
def resultsRenderer(self):
return self.meeting_macros['results']
def getColumnRenderer(self, col):
renderer = col.renderer
if renderer == 'subreport':
return self.meeting_macros[renderer]
return self.result_macros[renderer]

View file

@ -33,11 +33,17 @@ from cybertools.util.date import timeStamp2Date
from cybertools.util.format import formatDate from cybertools.util.format import formatDate
from cybertools.util.jeep import Jeep from cybertools.util.jeep import Jeep
from loops.common import adapted, baseObject from loops.common import adapted, baseObject
from loops.expert.field import TargetField, TextField, UrlField, SubReportField from loops.expert.field import TargetField, TextField, UrlField
from loops.expert.field import SubReport, SubReportField
from loops.expert.report import ReportInstance from loops.expert.report import ReportInstance
from loops import util from loops import util
class StateField(Field):
def getDisplayValue(self, row):
value = self.getValue(row)
return util._(value)
class DateField(Field): class DateField(Field):
part = 'date' part = 'date'
@ -101,6 +107,7 @@ dayTo = Field('dayTo', u'End Day',
executionSteps=['query']) executionSteps=['query'])
day = DateField('day', u'Day', day = DateField('day', u'Day',
description=u'The day the work was done.', description=u'The day the work was done.',
cssClass='center',
executionSteps=['sort', 'output']) executionSteps=['sort', 'output'])
timeStart = TimeField('start', u'Start', timeStart = TimeField('start', u'Start',
description=u'The time the unit of work was started.', description=u'The time the unit of work was started.',
@ -126,8 +133,9 @@ duration = DurationField('duration', u'Duration',
effort = DurationField('effort', u'Effort', effort = DurationField('effort', u'Effort',
description=u'The effort of the work.', description=u'The effort of the work.',
executionSteps=['output', 'totals']) executionSteps=['output', 'totals'])
state = Field('state', u'State', state = StateField('state', u'State',
description=u'The state of the work.', description=u'The state of the work.',
cssClass='center',
executionSteps=['query', 'output']) executionSteps=['query', 'output'])
@ -237,15 +245,44 @@ class WorkReportInstance(ReportInstance):
# meeting minutes # meeting minutes
class MeetingMinutesWorkRow(WorkRow):
pass
class MeetingMinutesWork(WorkReportInstance, SubReport):
rowFactory = MeetingMinutesWorkRow
fields = Jeep((workTitle, party, day, state)) #description,
defaultOutputFields = fields
defaultSortCriteria = (day,)
states = ('planned', 'accepted', 'running', 'done',
'finished', 'closed', 'moved')
@property
def queryCriteria(self):
return CompoundQueryCriteria([])
def selectObjects(self, parts):
parts.pop('tasks', None)
t = self.parentRow.context
if t is not None:
return self.selectWorkItems(t, parts)
return []
taskTitle = UrlField('title', u'Title', taskTitle = UrlField('title', u'Title',
description=u'The short description of the task.', description=u'The short description of the task.',
cssClass='header-1',
executionSteps=['output']) executionSteps=['output'])
taskDescription = TextField('description', u'Description', taskDescription = TextField('description', u'Description',
description=u'The long description of the task.', description=u'The long description of the task.',
cssClass='header-2',
executionSteps=['output']) executionSteps=['output'])
workItems = SubReportField('workItems', u'Work Items', workItems = SubReportField('workItems', u'Work Items',
description=u'A list of work items belonging to the task.', description=u'A list of work items belonging to the task.',
reportFactory=WorkReportInstance, reportFactory=MeetingMinutesWork,
executionSteps=['output']) executionSteps=['output'])
@ -274,3 +311,4 @@ class MeetingMinutes(WorkReportInstance):
def selectObjects(self, parts): def selectObjects(self, parts):
return self.getTasks(parts)[1:] return self.getTasks(parts)[1:]

View file

@ -213,20 +213,20 @@
(<span tal:content="python: (<span tal:content="python:
item.getUserForUserName(item.track.creator)['title']" />)</td> item.getUserForUserName(item.track.creator)['title']" />)</td>
</tr> </tr>
<tr tal:condition="python:state.name == 'delegated'"> <tr tal:condition="python:state.name in ('delegated', 'delegated_x')">
<td><span i18n:translate="">Delegated to</span>:</td> <td><span i18n:translate="">Delegated to</span>:</td>
<td><a tal:define="party python:view.getObjectForUid(item.targetWorkItem.party)" <td><a tal:define="party python:view.getObjectForUid(item.targetWorkItem.party)"
tal:attributes="href python:view.getUrlForTarget(party)" tal:attributes="href python:view.getUrlForTarget(party)"
tal:content="party/title" /></td> tal:content="party/title" /></td>
</tr> </tr>
<tr tal:condition="python:state.name == 'moved'"> <tr tal:condition="python:state.name in ('moved', 'moved_x')">
<td><span i18n:translate="">Moved To</span>:</td> <td><span i18n:translate="">Moved To</span>:</td>
<td><a tal:define="task python:view.getObjectForUid(item.targetWorkItem.taskId)" <td><a tal:define="task python:view.getObjectForUid(item.targetWorkItem.taskId)"
tal:attributes="href python:view.getUrlForTarget(task)" tal:attributes="href python:view.getUrlForTarget(task)"
tal:content="task/title" /></td> tal:content="task/title" /></td>
</tr> </tr>
<tr tal:define="source item/sourceWorkItem; <tr tal:define="source item/sourceWorkItem;
isDelegated python:source and source.state == 'delegated'" isDelegated python:source and source.state in ('delegated', 'delegated_x')"
tal:condition="source"> tal:condition="source">
<td> <td>
<span tal:condition="isDelegated" <span tal:condition="isDelegated"