From 17ccce90ce39e61118c5e23a960f20805f56008d Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Wed, 2 May 2012 16:44:11 +0200 Subject: [PATCH 01/15] add 'cssClass' property for controlling display of report fields; remove 'td' tags from field renderers for more flexibility --- browser/common.py | 6 ++++- browser/node.py | 1 + common.py | 4 +-- expert/browser/results.pt | 55 ++++++++++++++++++++++++--------------- expert/field.py | 3 ++- 5 files changed, 44 insertions(+), 25 deletions(-) diff --git a/browser/common.py b/browser/common.py index 540433e..507cab4 100644 --- a/browser/common.py +++ b/browser/common.py @@ -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 [] diff --git a/browser/node.py b/browser/node.py index 595e18f..0092518 100644 --- a/browser/node.py +++ b/browser/node.py @@ -468,6 +468,7 @@ class NodeView(BaseView): def getViewForTarget(self, obj, setup=True): if obj is not None: + obj = baseObject(obj) basicView = component.getMultiAdapter((obj, self.request)) if obj == self.targetObject: basicView._viewName = self.context.viewName diff --git a/common.py b/common.py index 61b9a89..f31aca5 100644 --- a/common.py +++ b/common.py @@ -162,8 +162,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): diff --git a/expert/browser/results.pt b/expert/browser/results.pt index adb9060..1b4ebac 100644 --- a/expert/browser/results.pt +++ b/expert/browser/results.pt @@ -20,50 +20,63 @@ - - - + + + - - - + + + - + - + - + - + + tal:content="value/title" /> + + + + + + +
+
+
+
+
+ +
- + @@ -72,18 +85,18 @@ i18n:translate="" /> - - - + - - - +
+ +
+ +
- +
diff --git a/expert/field.py b/expert/field.py index c4b94cf..d01918e 100644 --- a/expert/field.py +++ b/expert/field.py @@ -56,7 +56,7 @@ class DecimalField(Field): format = 'decimal' pattern = u'#,##0.00;-#,##0.00' - renderer = 'right' + cssClass = 'number' def getDisplayValue(self, row): value = self.getRawValue(row) @@ -76,6 +76,7 @@ class DecimalField(Field): class DateField(Field): format = ('date', 'short') + cssClass = 'center' def getDisplayValue(self, row): value = self.getRawValue(row) From 058de979d89fdece64f9c8351b9a426dbc706d8c Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Fri, 4 May 2012 16:13:02 +0200 Subject: [PATCH 02/15] work in progress: meeting minutes: selection and output working --- expert/browser/report.py | 4 ++-- expert/field.py | 1 + organize/work/report.py | 25 +++++++++++++++++++++++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/expert/browser/report.py b/expert/browser/report.py index 8fdb035..d7bb768 100644 --- a/expert/browser/report.py +++ b/expert/browser/report.py @@ -104,5 +104,5 @@ class ResultsView(NodeView): def displayedColumns(self): return self.reportInstance.getActiveOutputFields() - def getColumnRenderer(self, name): - return self.result_macros[name] + def getColumnRenderer(self, col): + return self.result_macros[col.renderer] diff --git a/expert/field.py b/expert/field.py index d01918e..9bdd7d1 100644 --- a/expert/field.py +++ b/expert/field.py @@ -194,6 +194,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): diff --git a/organize/work/report.py b/organize/work/report.py index 1851464..be2ff82 100644 --- a/organize/work/report.py +++ b/organize/work/report.py @@ -33,7 +33,8 @@ 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 @@ -237,6 +238,25 @@ class WorkReportInstance(ReportInstance): # meeting minutes +class MeetingMinutesWorkRow(WorkRow): + + pass + + +class MeetingMinutesWork(WorkReportInstance, SubReport): + + rowFactory = MeetingMinutesWorkRow + + states = ('planned',) + + 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.', executionSteps=['output']) @@ -245,7 +265,7 @@ taskDescription = TextField('description', u'Description', 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 +294,4 @@ class MeetingMinutes(WorkReportInstance): def selectObjects(self, parts): return self.getTasks(parts)[1:] + From 2f9fbb215e5b30df5b4313edadfde6b43b7c6046 Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Sat, 5 May 2012 10:35:22 +0200 Subject: [PATCH 03/15] work in progress: meeting minutes: view + corresponding portlet action --- expert/browser/report.py | 51 +++++++++++++++++++++++++++++++++++ expert/browser/results.pt | 27 ++++++++++++++----- expert/report.py | 2 +- organize/work/configure.zcml | 6 +++++ organize/work/meeting.pt | 15 +++++++++++ organize/work/meeting.py | 52 ++++++++++++++++++++++++++++++++++++ organize/work/report.py | 6 +++++ 7 files changed, 152 insertions(+), 7 deletions(-) create mode 100644 organize/work/meeting.pt create mode 100644 organize/work/meeting.py diff --git a/expert/browser/report.py b/expert/browser/report.py index d7bb768..79b5641 100644 --- a/expert/browser/report.py +++ b/expert/browser/report.py @@ -42,6 +42,8 @@ results_template = ViewPageTemplateFile('results.pt') class ReportView(ConceptView): + """ A view for defining (editing) a report. + """ @Lazy def report_macros(self): @@ -106,3 +108,52 @@ 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] diff --git a/expert/browser/results.pt b/expert/browser/results.pt index 1b4ebac..0f87f8d 100644 --- a/expert/browser/results.pt +++ b/expert/browser/results.pt @@ -3,7 +3,8 @@
+ report view/reportInstance; + reportView nocall:view">
@@ -14,9 +15,19 @@
+
+
+ +
+
+
+ +
+ tal:define="results reportView/results">
- +
- +
@@ -86,13 +99,15 @@ - + - + diff --git a/expert/report.py b/expert/report.py index c89a2cd..516b21a 100644 --- a/expert/report.py +++ b/expert/report.py @@ -97,7 +97,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) diff --git a/organize/work/configure.zcml b/organize/work/configure.zcml index e6040c4..a0df764 100644 --- a/organize/work/configure.zcml +++ b/organize/work/configure.zcml @@ -97,6 +97,12 @@ set_schema="loops.expert.report.IReportInstance" /> + + + + +
+
+ + +
+
+
+ + + diff --git a/organize/work/meeting.py b/organize/work/meeting.py new file mode 100644 index 0000000..f03783d --- /dev/null +++ b/organize/work/meeting.py @@ -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'] + diff --git a/organize/work/report.py b/organize/work/report.py index be2ff82..e750dfe 100644 --- a/organize/work/report.py +++ b/organize/work/report.py @@ -247,8 +247,14 @@ class MeetingMinutesWork(WorkReportInstance, SubReport): rowFactory = MeetingMinutesWorkRow + fields = Jeep((workTitle, party, day, state)) #description, + defaultOutputFields = fields states = ('planned',) + @property + def queryCriteria(self): + return CompoundQueryCriteria([]) + def selectObjects(self, parts): parts.pop('tasks', None) t = self.parentRow.context From 2412688b0e59323ac4b31b38b70fd170600377c7 Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Sat, 5 May 2012 18:28:58 +0200 Subject: [PATCH 04/15] meeting minutes: layout improvements --- browser/skin/lobo/lobo.css | 22 ++++++++++++++----- expert/browser/results.pt | 2 -- organize/work/meeting.pt | 44 ++++++++++++++++++++++++++++++++++++-- organize/work/meeting.py | 9 ++++++++ organize/work/report.py | 4 ++++ 5 files changed, 72 insertions(+), 9 deletions(-) diff --git a/browser/skin/lobo/lobo.css b/browser/skin/lobo/lobo.css index 712e4ca..65d4826 100644 --- a/browser/skin/lobo/lobo.css +++ b/browser/skin/lobo/lobo.css @@ -100,6 +100,10 @@ textarea { font-size: 100%; } +table { + border-collapse: collapse; +} + thead th { background: none; } @@ -136,7 +140,6 @@ table.listing { margin: 1px; /*margin-top: 0.5em; */ margin-bottom: 1em; - border-collapse: collapse; } table.listing th { @@ -206,10 +209,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 +489,19 @@ img.notselected { margin-bottom: 4px; } +.header-1 { + font-size: 120%; + font-weight: bold; +} + +.center { + text-align: center; +} + +.right { + text-align: right; +} + /* lobo layout-specific classes */ .legend { diff --git a/expert/browser/results.pt b/expert/browser/results.pt index 0f87f8d..b40267c 100644 --- a/expert/browser/results.pt +++ b/expert/browser/results.pt @@ -89,7 +89,6 @@
- @@ -111,7 +110,6 @@
-
diff --git a/organize/work/meeting.pt b/organize/work/meeting.pt index 9e5fe40..75ba4d9 100644 --- a/organize/work/meeting.pt +++ b/organize/work/meeting.pt @@ -7,8 +7,48 @@
-
-
+

+
+
+ + +
+ + + + + + + + + + + + + +
Task/ActionWho/When
+ +
+
+ + +
+ + + + +
diff --git a/organize/work/meeting.py b/organize/work/meeting.py index f03783d..cf4abf9 100644 --- a/organize/work/meeting.py +++ b/organize/work/meeting.py @@ -50,3 +50,12 @@ class MeetingMinutes(ResultsConceptView): 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] diff --git a/organize/work/report.py b/organize/work/report.py index e750dfe..69e2541 100644 --- a/organize/work/report.py +++ b/organize/work/report.py @@ -102,6 +102,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.', @@ -129,6 +130,7 @@ effort = DurationField('effort', u'Effort', executionSteps=['output', 'totals']) state = Field('state', u'State', description=u'The state of the work.', + cssClass='center', executionSteps=['query', 'output']) @@ -265,9 +267,11 @@ class MeetingMinutesWork(WorkReportInstance, SubReport): 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.', From afe357770c87470d02d29abf555b1977de4c3349 Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Sun, 6 May 2012 18:19:06 +0200 Subject: [PATCH 05/15] provide translations for meeting minutes; reporting styles for Loopz skin --- browser/loops.css | 17 +++++++++++++++++ locales/de/LC_MESSAGES/loops.mo | Bin 16782 -> 17053 bytes locales/de/LC_MESSAGES/loops.po | 14 +++++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/browser/loops.css b/browser/loops.css index a58473d..963101c 100644 --- a/browser/loops.css +++ b/browser/loops.css @@ -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 { diff --git a/locales/de/LC_MESSAGES/loops.mo b/locales/de/LC_MESSAGES/loops.mo index 8bbd48c5f73bbe52a1b5b4cb1c41180f586cedb8..b947388849edfb1a55cf99f29fadd84d51036d07 100644 GIT binary patch delta 6688 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 VXSla0&6Ccore+nCzmOK>|39y#w~GJ( delta 6434 zcmYk=37Aji9>DQqhA|`CSZ1s zOSXwNt`tZE>G%JT z)*wF`9q42ni8tT?`j5&;*if~GQB(=D(29-F@)jZA25q2pe|Z359{FRXuZMcicLhHpN_6v zG5Y*6^ttsR{}!^F(H=}VlOIU9#FZLHQFW}1&Y&6EaXYl(LS(U`k!Xig&;iU2`GshE zYtaF|iR@mq7n|abp*$-me!d`w^`|WALxCeLLOZ%XuHli!G1D)VkX#HOjBy8xECh?LrMrYCyt#Ag~&=7Qs#-inu(T-=J z<#%Hhd?e(bK(}fYI-s}FneRnc=yPEQAV8dLpy6AwKq7M|HE7CcX zcSjpM3+-SaI>VvZ87GAD611Jg=zy0ayOD_2li20jY;Z_!i# zJGw$y&Epw0Ltm@*=zs=cDh@~MjY20h4qbuE&C`E$BMA@5E$9sHMfY|t=HU`_(z7(sFUxT){A>_-@ zmD|~t_4hRHp}>ZYpab{?t6^%p__SuC_w&&e>KN>fHq;yK=xlW6Bhdk0f&LYo8S?YP z{Wa)W+T4!yH}UUK;Q;zU@jL30H9!a00c~&q=HjL3b2HHnA3&d5iq_v4%HI#}M>Alibp$nQh9;QLUX-Z@^{9CWEWp)(y4@{`d& zzq8Q}7oqL0!%WUwyk4{({2ca{)B;=={TQv(E*fMnHub}Vu z8^JBeF^aaM6Zs8Y(VC~n9cQD5`82Fd|4}y*E>&;zH5q_@f`_9Ij>H-`8vQa(Mmt`P zZpmtNW-nng+=6*{DBREN8n@E`9ca^FJ|-MV0SP}OUC{ybL>ulO9EuL`LbTo`n2qDn z8BRwBI0x(ELUaY!qFYji+4w0s(4Rs+tsDFA-sE(PPj7p)!E@0=RD{mxT685IKnGBQ z9=^xW=a-{f^)fopZRl3*L|5u4+VKf2z$)G2Ej+zD>+ej5P+)@>pr>;pT0RAb;>~D7 zW$2-L7oG7p*c^|eE7`b5+;D4jz`fB44Md+GjYT*CeZ5~#kZ{R9Ln|H&`HY_N3gn_& z(gqz^SG1wNq5K@QqfzJp#-KC35}m+JX!{BD`FUu)C1`(%6(r6eu?g$rujpQ7QOGwY zYKwL_4((_Xx;58@{B6P6*og9b(Jfex9^#eg^J~yE@lwcdk4;3oNH~&D&XJ~yZ1JB00>MO5$sBY7qG zXBCO&AuHz-6Nm+7xTX;o5|0y{t*8_6CgEW!zqXV3YslP+)j|hrNOvLXg?pz^{ub%a zh!-uR|7Z{KD&h4ykwT@Jc))^i72rDJQQ|Q1HqnxL$M6vG1n~e-eqBbwvonKeOucKd z0eYPslU(URF8greN#b(ipM;nDdrmUNzm9@(A2Ec;q_OMqZ^T{1V!QIG0G}{&(orgmioCO}OFzBg(IKBwiveBKDRS;z#jn z#wD|%5wVlViHoB1@CKqE@j3Bd;$z|qVgr#yJWt$1JVKOTUy_&@GUI|Z8Q|EEu1C5e z>A$#}Q%I~0H@?QzL>|$M@H1C_?IY2LXhK{`%p<)1PV7pi`1azdAzhVDPLh5)KeX<9_&P&gNFAs!@_5`I&+5ibx=5f2ew^{IPDoJ{^!y4P?Zx4QdBYq5JMOcRhp22RRtejya z1{3cSCx}morqq1}|3i4C5FeKBe>yksOcwKJDA*MJU))~b69dL)-h2P%5NgQKIEl) zNDstR;%1^Fv4!~KbvK#!LP15^=}$V*FcfUXzQo9ozXX>N*ATxFD~Uf|kCACXBQ5X> z;%eeFqB&)0M19hWiK)cJ#JfZ#%Bx}<;u|8@m+UBs(M0+6Lr7E!E-7tXe@eBvTk~g> p4sY2frF22-Rw)%bwdvTcw5*_4=G=>VO)K5i>xGok$9kuv{2w|aTl4?` diff --git a/locales/de/LC_MESSAGES/loops.po b/locales/de/LC_MESSAGES/loops.po index f684b84..98800d1 100644 --- a/locales/de/LC_MESSAGES/loops.po +++ b/locales/de/LC_MESSAGES/loops.po @@ -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-06 12:00 CET\n" "Last-Translator: Helmut Merz \n" "Language-Team: loops developers \n" "MIME-Version: 1.0\n" @@ -266,6 +266,18 @@ 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 "Favorites" msgstr "Lesezeichen" From f0bc424168697f4f31eecbafedbcc1e7ad267c71 Mon Sep 17 00:00:00 2001 From: hplattner Date: Mon, 7 May 2012 17:14:58 +0200 Subject: [PATCH 06/15] fix: useExisting in MemberRegistration --- organize/member.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/organize/member.py b/organize/member.py index 73f3a5c..99cc5b3 100644 --- a/organize/member.py +++ b/organize/member.py @@ -72,7 +72,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 len(groups)==0: groups = options(self.groups_key, ()) self.setGroupsForPrincipal(pfName, userId, groups=groups) From 0a72c9bda92dccb8700ab3827e05246d7712eeb0 Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Mon, 7 May 2012 17:57:19 +0200 Subject: [PATCH 07/15] fix states list for meeting minutes --- organize/member.py | 4 +--- organize/work/report.py | 4 +++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/organize/member.py b/organize/member.py index 99cc5b3..9753bd6 100644 --- a/organize/member.py +++ b/organize/member.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2009 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 @@ """ Member registration adapter(s). - -$Id$ """ from zope import interface, component, schema diff --git a/organize/work/report.py b/organize/work/report.py index 69e2541..bd558cf 100644 --- a/organize/work/report.py +++ b/organize/work/report.py @@ -251,7 +251,9 @@ class MeetingMinutesWork(WorkReportInstance, SubReport): fields = Jeep((workTitle, party, day, state)) #description, defaultOutputFields = fields - states = ('planned',) + defaultSortCriteria = (day,) + states = ('planned', 'accepted', 'running', 'done', + 'finished', 'closed', 'moved') @property def queryCriteria(self): From 095fd9b0327bb04eb92705b86037f65087f7fe25 Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Tue, 8 May 2012 07:45:31 +0200 Subject: [PATCH 08/15] meeting minutes: translate state, improve layout --- locales/de/LC_MESSAGES/loops.mo | Bin 17053 -> 17139 bytes locales/de/LC_MESSAGES/loops.po | 8 +++++++- organize/work/meeting.pt | 13 ++++++++++--- organize/work/report.py | 7 ++++++- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/locales/de/LC_MESSAGES/loops.mo b/locales/de/LC_MESSAGES/loops.mo index b947388849edfb1a55cf99f29fadd84d51036d07..e6bb0c4d75545b02bad138dde77f99d99b6da4f1 100644 GIT binary patch delta 6583 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 NjW5cso8Kud^}j*~dny0` delta 6509 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 X8`mMD^N2e#?iw_DbivV%sYU(|Xb5&1 diff --git a/locales/de/LC_MESSAGES/loops.po b/locales/de/LC_MESSAGES/loops.po index 98800d1..8b1d4f8 100644 --- a/locales/de/LC_MESSAGES/loops.po +++ b/locales/de/LC_MESSAGES/loops.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: $Id$\n" "POT-Creation-Date: 2007-05-22 12:00 CET\n" -"PO-Revision-Date: 2012-05-06 12:00 CET\n" +"PO-Revision-Date: 2012-05-08 12:00 CET\n" "Last-Translator: Helmut Merz \n" "Language-Team: loops developers \n" "MIME-Version: 1.0\n" @@ -278,6 +278,12 @@ msgstr "Aufgabe" msgid "Who/When" msgstr "Wer? Bis wann?" +msgid "Who?" +msgstr "Wer?" + +msgid "When?" +msgstr "Wann?" + msgid "Favorites" msgstr "Lesezeichen" diff --git a/organize/work/meeting.pt b/organize/work/meeting.pt index 75ba4d9..acd924b 100644 --- a/organize/work/meeting.pt +++ b/organize/work/meeting.pt @@ -18,17 +18,24 @@ Task/Action - Who/When + Who? + When? + - + + + \n" "Language-Team: loops developers \n" "MIME-Version: 1.0\n" @@ -416,6 +416,9 @@ msgstr "Status" msgid "Save" msgstr "Speichern" +msgid "Save Changes" +msgstr "Änderungen speichern" + msgid "Cancel" msgstr "Abbrechen" From 1ba43979a850228731b7432ac9f57a1047e4a9f2 Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Wed, 9 May 2012 09:28:56 +0200 Subject: [PATCH 10/15] show 'closed' state by default in listings --- organize/work/browser.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/organize/work/browser.py b/organize/work/browser.py index 890b4f2..f2aafcb 100644 --- a/organize/work/browser.py +++ b/organize/work/browser.py @@ -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', + 'closed', 'cancelled'] elif state != 'all': result['state'] = state return result From b289b4180792f6590228c0369b00a30b2ed4be03 Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Wed, 9 May 2012 09:36:15 +0200 Subject: [PATCH 11/15] inactivate last change (show 'closed' state by default in listings), seems not to be really useful --- organize/work/browser.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/organize/work/browser.py b/organize/work/browser.py index f2aafcb..dfcc9d1 100644 --- a/organize/work/browser.py +++ b/organize/work/browser.py @@ -234,8 +234,8 @@ class BaseWorkItemsView(object): state = form.get('wi_state') or self.options.wi_state if not state: result['state'] = ['planned', 'accepted', 'running', 'done', - 'done_x', 'finished', 'delegated', 'moved', - 'closed', 'cancelled'] + 'done_x', 'finished', 'delegated', 'moved', 'cancelled'] + #, 'closed'] elif state != 'all': result['state'] = state return result From a930ec1f63da862e5ba52cac07540aab597bc73d Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Wed, 9 May 2012 09:44:38 +0200 Subject: [PATCH 12/15] check also for '_x' states when displaying source or target work items --- organize/work/work_macros.pt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/organize/work/work_macros.pt b/organize/work/work_macros.pt index 95a010d..0dde42f 100644 --- a/organize/work/work_macros.pt +++ b/organize/work/work_macros.pt @@ -213,20 +213,20 @@ () - + Delegated to:
- + Moved To: Date: Sun, 13 May 2012 15:36:10 +0200 Subject: [PATCH 13/15] improve breadcrumbs position --- browser/skin/lobo/body.pt | 3 ++- browser/skin/lobo/lobo.css | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/browser/skin/lobo/body.pt b/browser/skin/lobo/body.pt index 50577c5..076c015 100644 --- a/browser/skin/lobo/body.pt +++ b/browser/skin/lobo/body.pt @@ -27,7 +27,8 @@
-