merge branch master
This commit is contained in:
commit
f9dca48cde
22 changed files with 349 additions and 36 deletions
|
@ -77,6 +77,7 @@ from loops.versioning.interfaces import IVersionable
|
|||
concept_macros = ViewPageTemplateFile('concept_macros.pt')
|
||||
conceptMacrosTemplate = concept_macros
|
||||
resource_macros = ViewPageTemplateFile('resource_macros.pt')
|
||||
form_macros = ViewPageTemplateFile('form_macros.pt')
|
||||
|
||||
|
||||
class NameField(schema.ASCIILine):
|
||||
|
@ -161,7 +162,10 @@ class BaseView(GenericView, I18NView):
|
|||
@Lazy
|
||||
def resource_macros(self):
|
||||
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):
|
||||
return []
|
||||
|
|
|
@ -45,7 +45,8 @@
|
|||
values python: [v for v in data.values() if v];
|
||||
fields item/fields"
|
||||
tal:condition="values">
|
||||
<table tal:attributes="ondblclick item/openEditWindow">
|
||||
<table class="fields"
|
||||
tal:attributes="ondblclick item/openEditWindow">
|
||||
<tal:row repeat="field fields">
|
||||
<tr tal:define="fieldName field/name;
|
||||
value nocall:data/?fieldName;
|
||||
|
|
|
@ -147,6 +147,10 @@ table.records th, table.records td {
|
|||
border: 1px solid black;
|
||||
}
|
||||
|
||||
table.report td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
dl.docutils dt {
|
||||
font-weight: bold;
|
||||
margin-top: 0.3em;
|
||||
|
@ -422,6 +426,19 @@ img.notselected {
|
|||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.header-1 {
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* comments */
|
||||
|
||||
div.comment {
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
<div id="content" class="span-6"
|
||||
metal:define-macro="content">
|
||||
<metal:breadcrumbs define-slot="breadcrumbs">
|
||||
<table tal:define="crumbs view/breadcrumbs"
|
||||
<table class="breadcrumbs"
|
||||
tal:define="crumbs view/breadcrumbs"
|
||||
tal:condition="crumbs">
|
||||
<tr>
|
||||
<td style="white-space: nowrap; vertical-align: top; width: 10%"
|
||||
|
|
|
@ -100,18 +100,30 @@ textarea {
|
|||
font-size: 100%;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
thead th {
|
||||
background: none;
|
||||
}
|
||||
|
||||
/* class-specific */
|
||||
|
||||
.breadcrumbs td {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-style: italic;
|
||||
/* margin-top: 0.5em;*/
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
|
||||
.fields td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.dialog div.heading {
|
||||
font-weight: bold;
|
||||
font-size: 140%;
|
||||
|
@ -136,7 +148,6 @@ table.listing {
|
|||
margin: 1px;
|
||||
/*margin-top: 0.5em; */
|
||||
margin-bottom: 1em;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table.listing th {
|
||||
|
@ -206,10 +217,6 @@ table.listing th span.descending {
|
|||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
table.records {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table.records input, table.records textarea {
|
||||
border: none;
|
||||
padding: 0;
|
||||
|
@ -490,6 +497,11 @@ img.notselected {
|
|||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.header-1 {
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
|
|
@ -166,8 +166,8 @@ class AdapterBase(object):
|
|||
def uid(self):
|
||||
return util.getUidForObject(self.context)
|
||||
|
||||
def getChildren(self):
|
||||
for c in self.context.getChildren():
|
||||
def getChildren(self, predicates=None):
|
||||
for c in self.context.getChildren(predicates):
|
||||
yield adapted(c, self.languageInfo)
|
||||
|
||||
def getLongTitle(self):
|
||||
|
|
|
@ -27,7 +27,9 @@ from zope.cachedescriptors.property import Lazy
|
|||
|
||||
from cybertools.typology.interfaces import IType
|
||||
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.common import adapted, baseObject
|
||||
|
||||
|
@ -36,7 +38,24 @@ standard_template = standard.standard_template
|
|||
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):
|
||||
parts = ['headline', 'keyquestions', 'quote', 'maintext',
|
||||
|
|
|
@ -17,6 +17,14 @@
|
|||
|
||||
<!-- 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
|
||||
name="page_layout"
|
||||
for="loops.interfaces.IConcept
|
||||
|
|
|
@ -7,7 +7,7 @@ type(u'book', u'Buch', viewName=u'', typeInterface=u'',
|
|||
type(u'page', u'Seite', viewName=u'page_layout',
|
||||
typeInterface=u'loops.compound.book.interfaces.IPage',
|
||||
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')
|
||||
|
||||
concept(u'system', u'System', u'domain')
|
||||
|
|
|
@ -42,6 +42,8 @@ results_template = ViewPageTemplateFile('results.pt')
|
|||
|
||||
|
||||
class ReportView(ConceptView):
|
||||
""" A view for defining (editing) a report.
|
||||
"""
|
||||
|
||||
@Lazy
|
||||
def report_macros(self):
|
||||
|
@ -107,3 +109,51 @@ class ResultsView(NodeView):
|
|||
def getColumnRenderer(self, col):
|
||||
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]
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
<div metal:define-macro="main"
|
||||
tal:define="item nocall:item/virtualTarget;
|
||||
report view/reportInstance">
|
||||
report view/reportInstance;
|
||||
reportView nocall:view">
|
||||
<div tal:attributes="class string:content-$level;">
|
||||
<metal:block use-macro="view/concept_macros/concepttitle" />
|
||||
</div>
|
||||
|
@ -14,9 +15,19 @@
|
|||
</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">
|
||||
<table class="report"
|
||||
tal:define="results view/results">
|
||||
tal:define="results reportView/results">
|
||||
<tr>
|
||||
<th tal:repeat="col results/displayedColumns"
|
||||
tal:content="col/title"
|
||||
|
@ -25,14 +36,16 @@
|
|||
</tr>
|
||||
<tr tal:repeat="row results">
|
||||
<td tal:repeat="col results/displayedColumns">
|
||||
<metal:column use-macro="python:view.getColumnRenderer(col)" />
|
||||
<metal:column use-macro="python:
|
||||
reportView.getColumnRenderer(col)" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr tal:define="row nocall:results/totals"
|
||||
tal:condition="nocall:row">
|
||||
<td tal:repeat="col results/displayedColumns"
|
||||
tal:attributes="class col/cssClass">
|
||||
<metal:column use-macro="python:view.getColumnRenderer(col)" />
|
||||
<metal:column use-macro="python:
|
||||
reportView.getColumnRenderer(col)" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -76,7 +89,6 @@
|
|||
|
||||
|
||||
<div metal:define-macro="subreport">
|
||||
<tal:column>
|
||||
<table class="subreport"
|
||||
tal:define="results python:col.getValue(row)">
|
||||
<tr>
|
||||
|
@ -86,17 +98,18 @@
|
|||
</tr>
|
||||
<tr tal:repeat="row results">
|
||||
<td tal:repeat="col results/displayedColumns">
|
||||
<metal:column use-macro="python:view.getColumnRenderer(col)" />
|
||||
<metal:column use-macro="python:
|
||||
reportView.getColumnRenderer(col)" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr tal:define="row nocall:results/totals"
|
||||
tal:condition="nocall:row">
|
||||
<td tal:repeat="col results/displayedColumns">
|
||||
<metal:column use-macro="python:view.getColumnRenderer(col)" />
|
||||
<metal:column use-macro="python:
|
||||
reportView.getColumnRenderer(col)" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</tal:column>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ class DecimalField(Field):
|
|||
styleData = {'text-align':'right'}
|
||||
styleData = dict(Field.style.data, **styleData)
|
||||
style = TableCellStyle(**styleData)
|
||||
cssClass = 'number'
|
||||
|
||||
def getDisplayValue(self, row):
|
||||
value = self.getRawValue(row)
|
||||
|
@ -228,6 +229,7 @@ class SubReportField(Field):
|
|||
baseReport = row.parent.context
|
||||
instance = self.reportFactory(baseReport.context)
|
||||
instance.view = baseReport.view
|
||||
instance.parentRow = row
|
||||
return instance
|
||||
|
||||
def getValue(self, row):
|
||||
|
|
|
@ -98,7 +98,7 @@ class ReportInstance(BaseReport):
|
|||
if dynaParams is not None:
|
||||
for k, v in dynaParams.items():
|
||||
if k in crit.parts.keys():
|
||||
crit.parts[k].value = v
|
||||
crit.parts[k].comparisonValue = v
|
||||
parts = Jeep(crit.parts)
|
||||
result = list(self.selectObjects(parts)) # may modify parts
|
||||
qc = CompoundQueryCriteria(parts)
|
||||
|
|
Binary file not shown.
|
@ -3,7 +3,7 @@ msgstr ""
|
|||
|
||||
"Project-Id-Version: $Id$\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"
|
||||
"Language-Team: loops developers <helmutm@cy55.de>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -266,6 +266,24 @@ msgstr "Daten des Video-Objekts bearbeiten"
|
|||
msgid "Play Movie"
|
||||
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"
|
||||
msgstr "Lesezeichen"
|
||||
|
||||
|
@ -398,6 +416,9 @@ msgstr "Status"
|
|||
msgid "Save"
|
||||
msgstr "Speichern"
|
||||
|
||||
msgid "Save Changes"
|
||||
msgstr "Änderungen speichern"
|
||||
|
||||
msgid "Cancel"
|
||||
msgstr "Abbrechen"
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ class MemberRegistrationManager(object):
|
|||
if pfName is None:
|
||||
pfName = options(self.principalfolder_key,
|
||||
(self.default_principalfolder,))[0]
|
||||
self.createPrincipal(pfName, userId, password, lastName, firstName)
|
||||
self.createPrincipal(pfName, userId, password, lastName, firstName, useExisting=useExisting)
|
||||
if not groups:
|
||||
groups = options(self.groups_key, ())
|
||||
self.setGroupsForPrincipal(pfName, userId, groups=groups)
|
||||
|
|
|
@ -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
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -18,8 +18,6 @@
|
|||
|
||||
"""
|
||||
View class(es) for work items.
|
||||
|
||||
$Id$
|
||||
"""
|
||||
|
||||
from datetime import date
|
||||
|
@ -235,9 +233,9 @@ class BaseWorkItemsView(object):
|
|||
result['timeFromTo'] = (tsFrom, tsTo)
|
||||
state = form.get('wi_state') or self.options.wi_state
|
||||
if not state:
|
||||
result['state'] = ['planned', 'accepted', 'running', 'done', 'done_x',
|
||||
'finished', 'delegated', 'moved',
|
||||
'cancelled']
|
||||
result['state'] = ['planned', 'accepted', 'running', 'done',
|
||||
'done_x', 'finished', 'delegated', 'moved', 'cancelled']
|
||||
#, 'closed']
|
||||
elif state != 'all':
|
||||
result['state'] = state
|
||||
return result
|
||||
|
|
|
@ -97,6 +97,12 @@
|
|||
set_schema="loops.expert.report.IReportInstance" />
|
||||
</zope:class>
|
||||
|
||||
<browser:page
|
||||
name="meeting_minutes.html"
|
||||
for="loops.interfaces.IConceptSchema"
|
||||
class="loops.organize.work.meeting.MeetingMinutes"
|
||||
permission="zope.View" />
|
||||
|
||||
<!-- setup -->
|
||||
|
||||
<zope:adapter factory="loops.organize.work.setup.SetupManager"
|
||||
|
|
62
organize/work/meeting.pt
Normal file
62
organize/work/meeting.pt
Normal 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
61
organize/work/meeting.py
Normal 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]
|
|
@ -33,11 +33,17 @@ from cybertools.util.date import timeStamp2Date
|
|||
from cybertools.util.format import formatDate
|
||||
from cybertools.util.jeep import Jeep
|
||||
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 import util
|
||||
|
||||
|
||||
class StateField(Field):
|
||||
def getDisplayValue(self, row):
|
||||
value = self.getValue(row)
|
||||
return util._(value)
|
||||
|
||||
class DateField(Field):
|
||||
|
||||
part = 'date'
|
||||
|
@ -101,6 +107,7 @@ dayTo = Field('dayTo', u'End Day',
|
|||
executionSteps=['query'])
|
||||
day = DateField('day', u'Day',
|
||||
description=u'The day the work was done.',
|
||||
cssClass='center',
|
||||
executionSteps=['sort', 'output'])
|
||||
timeStart = TimeField('start', u'Start',
|
||||
description=u'The time the unit of work was started.',
|
||||
|
@ -126,8 +133,9 @@ duration = DurationField('duration', u'Duration',
|
|||
effort = DurationField('effort', u'Effort',
|
||||
description=u'The effort of the work.',
|
||||
executionSteps=['output', 'totals'])
|
||||
state = Field('state', u'State',
|
||||
state = StateField('state', u'State',
|
||||
description=u'The state of the work.',
|
||||
cssClass='center',
|
||||
executionSteps=['query', 'output'])
|
||||
|
||||
|
||||
|
@ -237,15 +245,44 @@ class WorkReportInstance(ReportInstance):
|
|||
|
||||
# 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',
|
||||
description=u'The short description of the task.',
|
||||
cssClass='header-1',
|
||||
executionSteps=['output'])
|
||||
taskDescription = TextField('description', u'Description',
|
||||
description=u'The long description of the task.',
|
||||
cssClass='header-2',
|
||||
executionSteps=['output'])
|
||||
workItems = SubReportField('workItems', u'Work Items',
|
||||
description=u'A list of work items belonging to the task.',
|
||||
reportFactory=WorkReportInstance,
|
||||
reportFactory=MeetingMinutesWork,
|
||||
executionSteps=['output'])
|
||||
|
||||
|
||||
|
@ -274,3 +311,4 @@ class MeetingMinutes(WorkReportInstance):
|
|||
def selectObjects(self, parts):
|
||||
return self.getTasks(parts)[1:]
|
||||
|
||||
|
||||
|
|
|
@ -213,20 +213,20 @@
|
|||
(<span tal:content="python:
|
||||
item.getUserForUserName(item.track.creator)['title']" />)</td>
|
||||
</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><a tal:define="party python:view.getObjectForUid(item.targetWorkItem.party)"
|
||||
tal:attributes="href python:view.getUrlForTarget(party)"
|
||||
tal:content="party/title" /></td>
|
||||
</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><a tal:define="task python:view.getObjectForUid(item.targetWorkItem.taskId)"
|
||||
tal:attributes="href python:view.getUrlForTarget(task)"
|
||||
tal:content="task/title" /></td>
|
||||
</tr>
|
||||
<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">
|
||||
<td>
|
||||
<span tal:condition="isDelegated"
|
||||
|
|
Loading…
Add table
Reference in a new issue