add activity field to report, is also used as query field with vocabulary
This commit is contained in:
parent
354dfeda7f
commit
17f15429c8
6 changed files with 92 additions and 30 deletions
|
@ -262,6 +262,12 @@ table.records th, table.records td {
|
|||
border: 1px solid lightgrey;
|
||||
}
|
||||
|
||||
table.report {
|
||||
position: relative;
|
||||
z-index: 99;
|
||||
background: white;
|
||||
}
|
||||
|
||||
table.report th {
|
||||
border-bottom: 1px solid #bbbbbb;
|
||||
font-weight: bold;
|
||||
|
|
|
@ -141,7 +141,14 @@
|
|||
|
||||
|
||||
<metal:field define-macro="selection">
|
||||
<metal:use use-macro="item/report_macros/textline" />
|
||||
<select tal:attributes="name name">
|
||||
<option />
|
||||
<option tal:repeat="opt python:field.getVocabularyItems(
|
||||
context=item.adapted, request=request)"
|
||||
tal:attributes="value opt/token;
|
||||
selected python:value == opt['token']"
|
||||
tal:content="opt/title" />
|
||||
</select>
|
||||
</metal:field>
|
||||
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ class IntegerField(Field):
|
|||
|
||||
class DateField(Field):
|
||||
|
||||
fieldType='date',
|
||||
fieldType='date'
|
||||
format = ('date', 'short')
|
||||
renderer = cssClass = 'center'
|
||||
dbtype = 'date'
|
||||
|
@ -192,6 +192,8 @@ class WorkItemStateField(Field):
|
|||
class VocabularyField(Field):
|
||||
|
||||
vocabulary = None
|
||||
sourceList = None
|
||||
fieldType = 'selection'
|
||||
|
||||
def getDisplayValue(self, row):
|
||||
value = self.getRawValue(row)
|
||||
|
@ -202,9 +204,11 @@ class VocabularyField(Field):
|
|||
if str(item['token']) == str(value):
|
||||
return item['title']
|
||||
|
||||
def getVocabularyItems(self, row):
|
||||
context = row.context
|
||||
request = row.parent.context.view.request
|
||||
def getVocabularyItems(self, row=None, context=None, request=None):
|
||||
if context is None:
|
||||
context = row.context
|
||||
if request is None:
|
||||
request = row.parent.context.view.request
|
||||
voc = self.vocabulary
|
||||
if isinstance(voc, basestring):
|
||||
terms = self.getVocabularyTerms(voc, context, request)
|
||||
|
@ -213,7 +217,10 @@ class VocabularyField(Field):
|
|||
voc = voc.splitlines()
|
||||
return [dict(token=t, title=t) for t in voc if t.strip()]
|
||||
elif IContextSourceBinder.providedBy(voc):
|
||||
source = voc(row.parent.context)
|
||||
if row is not None:
|
||||
source = voc(row.parent.context)
|
||||
else:
|
||||
source = voc(context)
|
||||
terms = component.queryMultiAdapter((source, request), ITerms)
|
||||
if terms is not None:
|
||||
termsList = [terms.getTerm(value) for value in source]
|
||||
|
|
|
@ -232,7 +232,7 @@ The user interface is a ReportConceptView subclass that is directly associated w
|
|||
... print
|
||||
08/12/28 19:00 20:15
|
||||
{'url': '.../home/.36', 'title': u'loops Development'}
|
||||
{'url': '.../home/.33', 'title': u'john'} 01:15 00:15
|
||||
{'url': '.../home/.33', 'title': u'john'} 00:15
|
||||
{'actions': [...]}
|
||||
|
||||
>>> results.totals.data
|
||||
|
@ -247,8 +247,8 @@ Export of work data
|
|||
|
||||
>>> output = reportView()
|
||||
>>> print output
|
||||
Day;Start;End;Task;Party;Title;Duration;Effort;State
|
||||
08/12/28;19:00;20:15;loops Development;john;;1.2500;0.2500;finished
|
||||
Day;Start;End;Task;Party;Title;LA;Effort;State
|
||||
08/12/28;19:00;20:15;loops Development;john;;;0.2500;finished
|
||||
|
||||
|
||||
Meeting Minutes
|
||||
|
|
|
@ -39,11 +39,13 @@ from loops.common import adapted, baseObject
|
|||
from loops.expert.browser.export import ResultsConceptCSVExport
|
||||
from loops.expert.browser.report import ReportConceptView
|
||||
from loops.expert.field import Field, TargetField, DateField, StateField, \
|
||||
StringField, TextField, HtmlTextField, UrlField
|
||||
StringField, TextField, HtmlTextField, \
|
||||
UrlField, VocabularyField
|
||||
from loops.expert.field import SubReport, SubReportField
|
||||
from loops.expert.field import TrackDateField, TrackTimeField, TrackDateTimeField
|
||||
from loops.expert.field import WorkItemStateField
|
||||
from loops.expert.report import ReportInstance
|
||||
from loops.table import DataTableSourceBinder, DataTableSourceListByValue
|
||||
from loops import util
|
||||
|
||||
|
||||
|
@ -114,6 +116,28 @@ class PartyStateField(StateField):
|
|||
return None
|
||||
|
||||
|
||||
class ActivityField(VocabularyField):
|
||||
|
||||
tableName = 'organize.work.activities'
|
||||
vocabulary = DataTableSourceBinder(tableName,
|
||||
sourceList=DataTableSourceListByValue)
|
||||
|
||||
def getDisplayValue(self, row):
|
||||
if row.context is None:
|
||||
return u'-'
|
||||
value = row.context.data.get('activity', '')#[:3]
|
||||
if not value:
|
||||
return u''
|
||||
dt = row.parent.context.view.conceptManager.get(self.tableName)
|
||||
if dt is None:
|
||||
return u''
|
||||
for row in adapted(dt).data.values():
|
||||
if row[0] == value:
|
||||
value = row[3]
|
||||
break
|
||||
return value
|
||||
|
||||
|
||||
def daysAgoByOption(context):
|
||||
days = 7
|
||||
opt = context.view.typeOptions('workitem_dayfrom_default')
|
||||
|
@ -193,7 +217,10 @@ partyState = PartyStateField('partyState', u'Party State',
|
|||
cssClass='center',
|
||||
statesDefinition='contact_states',
|
||||
executionSteps=['query', 'output'])
|
||||
# activity
|
||||
activity = ActivityField('activity', u'LA',
|
||||
description=u'The activity assigned to the work item.',
|
||||
fieldType='selection',
|
||||
executionSteps=['query', 'sort', 'output'])
|
||||
# process
|
||||
|
||||
|
||||
|
@ -233,7 +260,7 @@ class WorkRow(BaseRow):
|
|||
attributeHandlers = dict(day=getDay,
|
||||
dayStart=getStart, dayEnd=getEnd,
|
||||
dayFrom=getDay, dayTo=getDay,
|
||||
duration=getDuration, effort=getEffort,)
|
||||
duration=getDuration, effort=getEffort)
|
||||
|
||||
|
||||
class WorkReportInstance(ReportInstance):
|
||||
|
@ -246,9 +273,11 @@ class WorkReportInstance(ReportInstance):
|
|||
fields = Jeep((dayFrom, dayTo, tasks,
|
||||
day, timeStart, timeEnd, task, party, workTitle,
|
||||
#description,
|
||||
duration, effort, state))
|
||||
activity,
|
||||
#duration,
|
||||
effort, state))
|
||||
|
||||
userSettings = (dayFrom, dayTo, party)
|
||||
userSettings = (dayFrom, dayTo, party, activity)
|
||||
defaultOutputFields = fields
|
||||
defaultSortCriteria = (day, timeStart,)
|
||||
defaultStates = ('done', 'done_x', 'finished')
|
||||
|
|
45
table.py
45
table.py
|
@ -138,22 +138,6 @@ def getRowValue(k, v):
|
|||
def getRowValueWithKey(k, v):
|
||||
return u' '.join((unicode(k), v[0]))
|
||||
|
||||
class DataTableSourceBinder(object):
|
||||
|
||||
implements(IContextSourceBinder)
|
||||
|
||||
def __init__(self, tableName, valueProvider=getRowValue):
|
||||
self.tableName = tableName
|
||||
self.valueProvider = valueProvider
|
||||
|
||||
def __call__(self, instance):
|
||||
if IInstance.providedBy(instance):
|
||||
context = instance.view.nodeView.context
|
||||
else:
|
||||
context = baseObject(instance.context)
|
||||
dt = context.getLoopsRoot().getConceptManager()[self.tableName]
|
||||
return DataTableSourceList(adapted(dt), self.valueProvider)
|
||||
|
||||
|
||||
class DataTableSourceList(object):
|
||||
|
||||
|
@ -170,3 +154,32 @@ class DataTableSourceList(object):
|
|||
|
||||
def __len__(self):
|
||||
return len(self.context.data)
|
||||
|
||||
|
||||
class DataTableSourceListByValue(DataTableSourceList):
|
||||
|
||||
def __iter__(self):
|
||||
items = [(k, v[0], v[1])
|
||||
for k, v in self.context.data.items()]
|
||||
items.sort()
|
||||
return iter([(i[1], i[2]) for i in items])
|
||||
|
||||
|
||||
class DataTableSourceBinder(object):
|
||||
|
||||
implements(IContextSourceBinder)
|
||||
|
||||
def __init__(self, tableName, valueProvider=getRowValue,
|
||||
sourceList=None):
|
||||
self.tableName = tableName
|
||||
self.valueProvider = valueProvider
|
||||
self.sourceList = sourceList or DataTableSourceList
|
||||
|
||||
def __call__(self, instance):
|
||||
if IInstance.providedBy(instance):
|
||||
context = instance.view.nodeView.context
|
||||
else:
|
||||
context = baseObject(instance.context)
|
||||
dt = context.getLoopsRoot().getConceptManager()[self.tableName]
|
||||
return self.sourceList(adapted(dt), self.valueProvider)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue