provide work item infos: icon with link, info popup
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3149 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
b5b4270f58
commit
6ff94ad004
7 changed files with 198 additions and 26 deletions
|
@ -101,7 +101,7 @@
|
||||||
<span tal:replace="related/title">Resource Title</span>
|
<span tal:replace="related/title">Resource Title</span>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td><span tal:content="related/typeTitle"
|
<td class="center"><span tal:content="related/typeTitle"
|
||||||
i18n:translate="">Type</span></td>
|
i18n:translate="">Type</span></td>
|
||||||
<td><span tal:replace="related/modified">Type</span></td>
|
<td><span tal:replace="related/modified">Type</span></td>
|
||||||
<td><span tal:replace="related/creators">Type</span></td>
|
<td><span tal:replace="related/creators">Type</span></td>
|
||||||
|
@ -162,7 +162,8 @@
|
||||||
<div tal:content="related/title">Resource Title</div>
|
<div tal:content="related/title">Resource Title</div>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td><span tal:replace="related/longTypeTitle">Type</span></td>
|
<td class="center">
|
||||||
|
<span tal:replace="related/longTypeTitle">Type</span></td>
|
||||||
<tal:version tal:condition="view/useVersioning">
|
<tal:version tal:condition="view/useVersioning">
|
||||||
<td class="center"
|
<td class="center"
|
||||||
tal:define="versionId related/versionId">
|
tal:define="versionId related/versionId">
|
||||||
|
|
|
@ -117,6 +117,7 @@ class NodeView(BaseView):
|
||||||
if not IUnauthenticatedPrincipal.providedBy(self.request.principal):
|
if not IUnauthenticatedPrincipal.providedBy(self.request.principal):
|
||||||
mi = self.controller.memberInfo
|
mi = self.controller.memberInfo
|
||||||
title = mi.title.value or _(u'Personal Informations')
|
title = mi.title.value or _(u'Personal Informations')
|
||||||
|
url=None
|
||||||
obj = mi.get('object')
|
obj = mi.get('object')
|
||||||
if obj is not None:
|
if obj is not None:
|
||||||
query = self.conceptManager.get('personal_info')
|
query = self.conceptManager.get('personal_info')
|
||||||
|
@ -125,11 +126,11 @@ class NodeView(BaseView):
|
||||||
url = self.getUrlForTarget(obj.value)
|
url = self.getUrlForTarget(obj.value)
|
||||||
else:
|
else:
|
||||||
url = self.getUrlForTarget(query)
|
url = self.getUrlForTarget(query)
|
||||||
cm.register('portlet_right', 'personal', title=title,
|
cm.register('portlet_right', 'personal', title=title,
|
||||||
subMacro=node_macros.macros['personal'],
|
subMacro=node_macros.macros['personal'],
|
||||||
icon='cybertools.icons/user.png',
|
icon='cybertools.icons/user.png',
|
||||||
url=url,
|
url=url,
|
||||||
priority=10)
|
priority=10)
|
||||||
# force early portlet registrations by target by setting up target view
|
# force early portlet registrations by target by setting up target view
|
||||||
self.virtualTarget
|
self.virtualTarget
|
||||||
|
|
||||||
|
|
|
@ -269,7 +269,9 @@ class TrackDetails(BaseView):
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def user(self):
|
def user(self):
|
||||||
userName = self.track.userName
|
return self.getUserForUserName(self.track.userName)
|
||||||
|
|
||||||
|
def getUserForUserName(self, userName):
|
||||||
obj = util.getObjectForUid(userName)
|
obj = util.getObjectForUid(userName)
|
||||||
if obj is None:
|
if obj is None:
|
||||||
try:
|
try:
|
||||||
|
@ -292,9 +294,6 @@ class TrackDetails(BaseView):
|
||||||
@Lazy
|
@Lazy
|
||||||
def timeStamp(self):
|
def timeStamp(self):
|
||||||
return self.formatTimeStamp(self.track.timeStamp)
|
return self.formatTimeStamp(self.track.timeStamp)
|
||||||
#value = datetime.fromtimestamp(self.track.timeStamp)
|
|
||||||
#return format.formatDate(value, 'dateTime', self.timeStampFormat,
|
|
||||||
# self.view.languageInfo.language)
|
|
||||||
|
|
||||||
def formatTimeStamp(self, ts, f='dateTime'):
|
def formatTimeStamp(self, ts, f='dateTime'):
|
||||||
if not ts:
|
if not ts:
|
||||||
|
|
|
@ -30,6 +30,7 @@ from zope.app.pagetemplate import ViewPageTemplateFile
|
||||||
from zope.traversing.browser import absoluteURL
|
from zope.traversing.browser import absoluteURL
|
||||||
from zope.traversing.api import getName
|
from zope.traversing.api import getName
|
||||||
|
|
||||||
|
from cybertools.ajax import innerHtml
|
||||||
from cybertools.browser.action import actions
|
from cybertools.browser.action import actions
|
||||||
from cybertools.organize.interfaces import IWorkItems
|
from cybertools.organize.interfaces import IWorkItems
|
||||||
from loops.browser.action import DialogAction
|
from loops.browser.action import DialogAction
|
||||||
|
@ -37,6 +38,7 @@ from loops.browser.concept import ConceptView
|
||||||
from loops.browser.form import ObjectForm, EditObject
|
from loops.browser.form import ObjectForm, EditObject
|
||||||
from loops.browser.node import NodeView
|
from loops.browser.node import NodeView
|
||||||
from loops.organize.party import getPersonForUser
|
from loops.organize.party import getPersonForUser
|
||||||
|
from loops.organize.stateful.browser import StateAction
|
||||||
from loops.organize.tracking.browser import BaseTrackView
|
from loops.organize.tracking.browser import BaseTrackView
|
||||||
from loops.organize.tracking.report import TrackDetails
|
from loops.organize.tracking.report import TrackDetails
|
||||||
from loops import util
|
from loops import util
|
||||||
|
@ -50,7 +52,7 @@ work_macros = ViewPageTemplateFile('work_macros.pt')
|
||||||
|
|
||||||
class BaseWorkItemsView(object):
|
class BaseWorkItemsView(object):
|
||||||
|
|
||||||
columns = set(['Task', 'User', 'Title', 'Start', 'End', 'Duration'])
|
columns = set(['Task', 'User', 'Title', 'Start', 'End', 'Duration', 'Info'])
|
||||||
|
|
||||||
lastMonth = lastDay = None
|
lastMonth = lastDay = None
|
||||||
|
|
||||||
|
@ -85,7 +87,7 @@ class WorkItemsView(BaseWorkItemsView, NodeView):
|
||||||
""" Standard view for showing work items for a node's target.
|
""" Standard view for showing work items for a node's target.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
columns = set(['User', 'Title', 'Day', 'Start', 'End', 'Duration'])
|
columns = set(['User', 'Title', 'Day', 'Start', 'End', 'Duration', 'Info'])
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def allWorkItems(self):
|
def allWorkItems(self):
|
||||||
|
@ -105,7 +107,7 @@ class UserWorkItems(BaseWorkItemsView, ConceptView):
|
||||||
""" A query view showing work items for a person, the query's parent.
|
""" A query view showing work items for a person, the query's parent.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
columns = set(['Task', 'Title', 'Day', 'Start', 'End', 'Duration'])
|
columns = set(['Task', 'Title', 'Day', 'Start', 'End', 'Duration', 'Info'])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def macro(self):
|
def macro(self):
|
||||||
|
@ -152,12 +154,73 @@ class WorkItemDetails(TrackDetails):
|
||||||
def effort(self):
|
def effort(self):
|
||||||
return self.formatTimeDelta(self.track.effort)
|
return self.formatTimeDelta(self.track.effort)
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def startDay(self):
|
||||||
|
return self.formatTimeStamp(self.track.timeStamp, 'date')
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def created(self):
|
||||||
|
return self.formatTimeStamp(self.track.created, 'dateTime')
|
||||||
|
|
||||||
def formatTimeDelta(self, value):
|
def formatTimeDelta(self, value):
|
||||||
if not value:
|
if not value:
|
||||||
return ''
|
return ''
|
||||||
h, m = divmod(int(value) / 60, 60)
|
h, m = divmod(int(value) / 60, 60)
|
||||||
return '%02i:%02i' % (h, m)
|
return '%02i:%02i' % (h, m)
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def isLastInRun(self):
|
||||||
|
currentWorkItems = list(self.view.workItems.query(runId=self.track.runId))
|
||||||
|
return self.track == currentWorkItems[-1]
|
||||||
|
|
||||||
|
def actions(self):
|
||||||
|
info = DialogAction(self.view,
|
||||||
|
description=_(u'Information about this work item.'),
|
||||||
|
viewName='workitem_info.html',
|
||||||
|
dialogName='',
|
||||||
|
icon='cybertools.icons/info.png',
|
||||||
|
cssClass='icon-action',
|
||||||
|
page=self.view.nodeView,
|
||||||
|
target=self.object,
|
||||||
|
addParams=dict(id=self.track.__name__))
|
||||||
|
actions = [info, WorkItemStateAction(self)]
|
||||||
|
if self.isLastInRun:
|
||||||
|
self.view.registerDojoDateWidget()
|
||||||
|
self.view.registerDojoNumberWidget()
|
||||||
|
actions.append(DialogAction(self.view,
|
||||||
|
description=_(u'Create a work item.'),
|
||||||
|
viewName='create_workitem.html',
|
||||||
|
dialogName='',
|
||||||
|
icon='edit.gif',
|
||||||
|
cssClass='icon-action',
|
||||||
|
page=self.view.nodeView,
|
||||||
|
target=self.object,
|
||||||
|
addParams=dict(id=self.track.__name__)))
|
||||||
|
return actions
|
||||||
|
|
||||||
|
|
||||||
|
class WorkItemInfo(NodeView):
|
||||||
|
""" Provides info box.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__call__ = innerHtml
|
||||||
|
|
||||||
|
@property
|
||||||
|
def macro(self):
|
||||||
|
return work_macros.macros['workitem_info']
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def dialog_name(self):
|
||||||
|
return self.request.get('dialog', 'workitem_info')
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def track(self):
|
||||||
|
id = self.request.form.get('id')
|
||||||
|
if id is not None:
|
||||||
|
workItems = self.loopsRoot.getRecordManager()['work']
|
||||||
|
track = workItems.get(id)
|
||||||
|
return WorkItemDetails(self, track)
|
||||||
|
|
||||||
|
|
||||||
class WorkItemView(BaseTrackView):
|
class WorkItemView(BaseTrackView):
|
||||||
""" Show a single work item in the management view.
|
""" Show a single work item in the management view.
|
||||||
|
@ -174,6 +237,21 @@ class CreateWorkItemForm(ObjectForm, BaseTrackView):
|
||||||
def macro(self):
|
def macro(self):
|
||||||
return self.template.macros['create_workitem']
|
return self.template.macros['create_workitem']
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def track(self):
|
||||||
|
id = self.request.form.get('id')
|
||||||
|
if id is not None:
|
||||||
|
workItems = self.loopsRoot.getRecordManager()['work']
|
||||||
|
return workItems.get(id)
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def title(self):
|
||||||
|
return self.track is not None and self.track.title or u''
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def description(self):
|
||||||
|
return self.track is not None and self.track.description or u''
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def defaultDate(self):
|
def defaultDate(self):
|
||||||
return time.strftime('%Y-%m-%d')
|
return time.strftime('%Y-%m-%d')
|
||||||
|
@ -185,6 +263,13 @@ class CreateWorkItemForm(ObjectForm, BaseTrackView):
|
||||||
|
|
||||||
class CreateWorkItem(EditObject, BaseTrackView):
|
class CreateWorkItem(EditObject, BaseTrackView):
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def track(self):
|
||||||
|
id = self.request.form.get('id')
|
||||||
|
if id is not None:
|
||||||
|
workItems = self.loopsRoot.getRecordManager()['work']
|
||||||
|
return workItems.get(id)
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def personId(self):
|
def personId(self):
|
||||||
p = getPersonForUser(self.context, self.request)
|
p = getPersonForUser(self.context, self.request)
|
||||||
|
@ -229,7 +314,10 @@ class CreateWorkItem(EditObject, BaseTrackView):
|
||||||
action, data = self.processForm()
|
action, data = self.processForm()
|
||||||
if not action:
|
if not action:
|
||||||
return True
|
return True
|
||||||
wi = workItems.add(util.getUidForObject(self.object), self.personId)
|
if self.track is not None:
|
||||||
|
wi = self.track
|
||||||
|
else:
|
||||||
|
wi = workItems.add(util.getUidForObject(self.object), self.personId)
|
||||||
wi.doAction(action, self.personId, **data)
|
wi.doAction(action, self.personId, **data)
|
||||||
url = self.view.virtualTargetUrl + '?version=this'
|
url = self.view.virtualTargetUrl + '?version=this'
|
||||||
self.request.response.redirect(url)
|
self.request.response.redirect(url)
|
||||||
|
@ -247,6 +335,19 @@ actions.register('createWorkitem', 'portlet', DialogAction,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class WorkItemStateAction(StateAction):
|
||||||
|
|
||||||
|
cssClass = 'icon-action'
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def stateful(self):
|
||||||
|
return self.view.track
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def description(self):
|
||||||
|
return _(self.stateObject.title)
|
||||||
|
|
||||||
|
|
||||||
# auxiliary functions
|
# auxiliary functions
|
||||||
|
|
||||||
def parseTime(s):
|
def parseTime(s):
|
||||||
|
|
|
@ -49,6 +49,12 @@
|
||||||
factory="loops.organize.work.browser.CreateWorkItem"
|
factory="loops.organize.work.browser.CreateWorkItem"
|
||||||
permission="zope.View" />
|
permission="zope.View" />
|
||||||
|
|
||||||
|
<browser:page
|
||||||
|
name="workitem_info.html"
|
||||||
|
for="loops.interfaces.INode"
|
||||||
|
class="loops.organize.work.browser.WorkItemInfo"
|
||||||
|
permission="zope.View" />
|
||||||
|
|
||||||
<!-- setup -->
|
<!-- setup -->
|
||||||
|
|
||||||
<zope:adapter factory="loops.organize.work.setup.SetupManager"
|
<zope:adapter factory="loops.organize.work.setup.SetupManager"
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
<!-- listings -->
|
<!-- listings -->
|
||||||
|
|
||||||
<metal:work define-macro="workitems"
|
<metal:work define-macro="workitems"
|
||||||
tal:define="work nocall:view/workItems"
|
tal:define="work nocall:view/workItems"
|
||||||
tal:condition="work/allWorkItems">
|
tal:condition="work/allWorkItems">
|
||||||
<br />
|
<br />
|
||||||
<h2 i18n:translate="">Work Items</h2>
|
<h2 i18n:translate="">Work Items</h2>
|
||||||
<metal:workitems define-macro="workitems_listing"
|
<metal:workitems define-macro="workitems_listing"
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
<table class="listing">
|
<table class="listing">
|
||||||
<tr>
|
<tr>
|
||||||
<tal:colheader repeat="column python:
|
<tal:colheader repeat="column python:
|
||||||
('Day', 'Start', 'End', 'Duration', 'Task', 'User', 'Title')">
|
('Day', 'Start', 'End', 'Duration', 'Task', 'User', 'Title', 'Info')">
|
||||||
<th tal:condition="python: column in work.columns"
|
<th tal:condition="python: column in work.columns"
|
||||||
tal:content="column"
|
tal:content="column"
|
||||||
i18n:translate="">Task</th>
|
i18n:translate="">Task</th>
|
||||||
|
@ -39,6 +39,11 @@
|
||||||
tal:content="row/user/title">John</a></td>
|
tal:content="row/user/title">John</a></td>
|
||||||
<td tal:content="row/track/title"
|
<td tal:content="row/track/title"
|
||||||
tal:attributes="title row/track/description">Title</td>
|
tal:attributes="title row/track/description">Title</td>
|
||||||
|
<td class="nowrap">
|
||||||
|
<tal:actions repeat="action row/actions">
|
||||||
|
<metal:action use-macro="action/macro" />
|
||||||
|
</tal:actions>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tal:workitem>
|
</tal:workitem>
|
||||||
</table>
|
</table>
|
||||||
|
@ -60,20 +65,22 @@
|
||||||
dojoType="dijit.form.Form">
|
dojoType="dijit.form.Form">
|
||||||
<input type="hidden" name="form.action" value="create_workitem" />
|
<input type="hidden" name="form.action" value="create_workitem" />
|
||||||
<input type="hidden" name="workitem.action" value="finish" />
|
<input type="hidden" name="workitem.action" value="finish" />
|
||||||
|
<input type="hidden" name="id"
|
||||||
|
tal:attributes="value request/form/id|nothing" />
|
||||||
<div class="heading" i18n:translate="">Add Work Item</div>
|
<div class="heading" i18n:translate="">Add Work Item</div>
|
||||||
<div>
|
<div>
|
||||||
<label i18n:translate="" for="title">Title</label>
|
<label i18n:translate="" for="title">Title</label>
|
||||||
<div>
|
<div>
|
||||||
<input name="title" id="title"
|
<input name="title" id="title" style="width: 60em"
|
||||||
dojoType="dijit.form.ValidationTextBox" required
|
dojoType="dijit.form.ValidationTextBox" required
|
||||||
style="width: 60em" /></div>
|
tal:attributes="value view/title" /></div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label i18n:translate="" for="description">Description</label>
|
<label i18n:translate="" for="description">Description</label>
|
||||||
<div>
|
<div>
|
||||||
<textarea name="description" cols="80" rows="4" id="description"
|
<textarea name="description" cols="80" rows="4" id="description"
|
||||||
dojoType="dijit.form.SimpleTextarea"
|
dojoType="dijit.form.SimpleTextarea" style="width: 60em"
|
||||||
style="width: 60em"></textarea></div>
|
tal:content="view/description"></textarea></div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label i18n:translate="" for="start-end">Start - End</label>
|
<label i18n:translate="" for="start-end">Start - End</label>
|
||||||
|
@ -115,4 +122,61 @@
|
||||||
</metal:block>
|
</metal:block>
|
||||||
|
|
||||||
|
|
||||||
|
<metal:info define-macro="workitem_info"
|
||||||
|
tal:define="item nocall:view/track">
|
||||||
|
<table class="object_info" width="400">
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"><h2 i18n:translate="">Work Item Information</h2><br /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><span i18n:translate="">Title</span>:</td>
|
||||||
|
<td tal:content="item/track/title"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top"><span i18n:translate="">Description</span>:</td>
|
||||||
|
<td tal:content="item/description"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><span i18n:translate="">Party</span>:</td>
|
||||||
|
<td tal:content="item/user/title"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><span i18n:translate="">Task</span>:</td>
|
||||||
|
<td tal:content="item/object/title"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><span i18n:translate="">Start - End</span>:</td>
|
||||||
|
<td><span tal:content="item/startDay" />
|
||||||
|
<span tal:content="item/start" /> -
|
||||||
|
<span tal:content="item/end" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><span i18n:translate="">Duration/Effort</span>:</td>
|
||||||
|
<td><span tal:content="item/duration" /> /
|
||||||
|
<span tal:content="item/effort" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td valign="top"><span i18n:translate="">Comment</span>:</td>
|
||||||
|
<td tal:content="item/track/comment"></td>
|
||||||
|
</tr>
|
||||||
|
<tr tal:define="state item/track/getStateObject">
|
||||||
|
<td><span i18n:translate="">State</span>:</td>
|
||||||
|
<td tal:content="state/title"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><span i18n:translate="">Created</span>:</td>
|
||||||
|
<td><span tal:content="item/created" />
|
||||||
|
(<span tal:content="python:
|
||||||
|
item.getUserForUserName(item.track.creator)['title']" />)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"><br />
|
||||||
|
<input type="button" value="Close" onclick="closeDialog()"
|
||||||
|
i18n:attributes="value" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</metal:info>
|
||||||
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -80,10 +80,10 @@
|
||||||
tal:attributes="src icon/src" />
|
tal:attributes="src icon/src" />
|
||||||
<div tal:content="row/title" /></a>
|
<div tal:content="row/title" /></a>
|
||||||
</td>
|
</td>
|
||||||
<td i18n:translate=""
|
<td i18n:translate="" class="center"
|
||||||
tal:content="row/longTypeTitle|row/typeTitle">Type</td>
|
tal:content="row/longTypeTitle|row/typeTitle">Type</td>
|
||||||
<tal:version condition="view/useVersioning">
|
<tal:version condition="view/useVersioning">
|
||||||
<td style="text-align: center"
|
<td class="center"
|
||||||
tal:define="versionId row/versionId|string:">
|
tal:define="versionId row/versionId|string:">
|
||||||
<a href="#"
|
<a href="#"
|
||||||
tal:content="versionId"
|
tal:content="versionId"
|
||||||
|
@ -91,12 +91,12 @@
|
||||||
tal:attributes="href string:${view/url}/.target${row/uniqueId}?loops.viewName=listversions">1.1</a>
|
tal:attributes="href string:${view/url}/.target${row/uniqueId}?loops.viewName=listversions">1.1</a>
|
||||||
</td>
|
</td>
|
||||||
</tal:version>
|
</tal:version>
|
||||||
<td style="text-align: right; white-space: nowrap">
|
<td class="nowrap number">
|
||||||
<span tal:replace="row/context/sizeForDisplay|string:">Size</span>
|
<span tal:replace="row/context/sizeForDisplay|string:">Size</span>
|
||||||
</td>
|
</td>
|
||||||
<td><span tal:replace="row/modified">modified</span></td>
|
<td><span tal:replace="row/modified">modified</span></td>
|
||||||
<td><span tal:replace="row/creators">John</span></td>
|
<td><span tal:replace="row/creators">John</span></td>
|
||||||
<td style="white-space: nowrap"
|
<td class="nowrap center"
|
||||||
tal:define="target nocall:row;
|
tal:define="target nocall:row;
|
||||||
style nothing"
|
style nothing"
|
||||||
tal:condition="view/showObjectActions">
|
tal:condition="view/showObjectActions">
|
||||||
|
|
Loading…
Add table
Reference in a new issue