notifications listing fully operative with marking notifications as read and filtering

This commit is contained in:
Helmut Merz 2015-10-30 10:50:05 +01:00
parent d09e2a9d0a
commit 4a0b31b34d
4 changed files with 67 additions and 28 deletions

View file

@ -35,4 +35,11 @@
class="loops.organize.personal.browser.notification.NotificationsListing" class="loops.organize.personal.browser.notification.NotificationsListing"
permission="zope.View" /> permission="zope.View" />
<zope:adapter
name="notification_read"
for="loops.browser.node.NodeView
zope.publisher.interfaces.browser.IBrowserRequest"
factory="loops.organize.personal.browser.notification.ReadNotification"
permission="zope.View" />
</configure> </configure>

View file

@ -24,7 +24,8 @@ from zope import component
from zope.app.pagetemplate import ViewPageTemplateFile from zope.app.pagetemplate import ViewPageTemplateFile
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from cybertools.util.date import formatTimeStamp from cybertools.browser.form import FormController
from cybertools.util.date import formatTimeStamp, getTimeStamp
from loops.browser.concept import ConceptView from loops.browser.concept import ConceptView
from loops.common import adapted, baseObject from loops.common import adapted, baseObject
from loops.organize.personal.notification import Notifications from loops.organize.personal.notification import Notifications
@ -49,11 +50,12 @@ class NotificationsListing(ConceptView):
def notifications(self): def notifications(self):
return Notifications(self.person) return Notifications(self.person)
def getNotifications(self, unreadOnly=True): def getNotifications(self, unreadOnly):
tracks = self.notifications.listTracks() tracks = self.notifications.listTracks(unreadOnly)
return tracks return tracks
def getNotificationsFormatted(self, unreadOnly=True): def getNotificationsFormatted(self):
unreadOnly = not self.request.form.get('show_all')
result = [] result = []
for track in self.getNotifications(unreadOnly): for track in self.getNotifications(unreadOnly):
data = track.data data = track.data
@ -61,8 +63,11 @@ class NotificationsListing(ConceptView):
sender = dict(label=s.title, sender = dict(label=s.title,
url=self.nodeView.getUrlForTarget(baseObject(s))) url=self.nodeView.getUrlForTarget(baseObject(s)))
obj = util.getObjectForUid(track.taskId) obj = util.getObjectForUid(track.taskId)
object = dict(label=obj.title, ov = self.nodeView.getViewForTarget(obj)
url=self.nodeView.getUrlForTarget(baseObject(obj))) url = '%s?form.action=notification_read&track=%s' % (
self.nodeView.getUrlForTarget(obj),
util.getUidForObject(track))
object = dict(label=ov.title, url=url)
read_ts = self.formatTimeStamp(data.get('read_ts')) read_ts = self.formatTimeStamp(data.get('read_ts'))
item = dict(timeStamp=self.formatTimeStamp(track.timeStamp), item = dict(timeStamp=self.formatTimeStamp(track.timeStamp),
sender=sender, sender=sender,
@ -71,3 +76,17 @@ class NotificationsListing(ConceptView):
read_ts=read_ts) read_ts=read_ts)
result.append(item) result.append(item)
return result return result
class ReadNotification(FormController):
def update(self):
form = self.request.form
trackId = form.get('track')
track = util.getObjectForUid(trackId)
data = track.data
alreadyRead = data.get('read_ts')
if not alreadyRead:
data['read_ts'] = getTimeStamp()
track.data = data
return True

View file

@ -50,25 +50,35 @@
<metal:block define-macro="notifications"> <metal:block define-macro="notifications">
<div tal:attributes="class string:content-$level;"> <div tal:attributes="class string:content-$level;">
<metal:title use-macro="item/concept_macros/concepttitle" /> <metal:title use-macro="item/concept_macros/concepttitle" />
<table class="listing"> <form name="notifications" method="post">
<tr class="header"> <input type="checkbox" name="show_all" id="notifications.show_all"
<th>Date/Time</th> title="Show all notifications"
<th>Sender</th> i18n:attributes="title"
<th>Object</th> onclick="submit()"
<th>Text</th> tal:attributes="checked request/form/show_all|nothing" />
<th>Date/Time read</th> <label for="notifications.show_all"
</tr> i18n:translate="">Show all notifications</label>
<tr tal:repeat="notif item/getNotificationsFormatted"> <br />&nbsp;
<td tal:content="notif/timeStamp" /> <table class="listing">
<td tal:define="sender notif/sender"> <tr class="header">
<a tal:attributes="href sender/url" <th i18n:translate="">Date/Time</th>
tal:content="sender/label" /></td> <th i18n:translate="">Sender</th>
<td tal:define="object notif/object"> <th i18n:translate="">Object</th>
<a tal:attributes="href object/url" <th i18n:translate="">Message</th>
tal:content="object/label" /></td> <th i18n:translate="">Date/Time read</th>
<td tal:content="notif/text" /> </tr>
<td tal:content="notif/read_ts" /> <tr tal:repeat="notif item/getNotificationsFormatted">
</tr> <td tal:content="notif/timeStamp" />
</table> <td tal:define="sender notif/sender">
<a tal:attributes="href sender/url"
tal:content="sender/label" /></td>
<td tal:define="object notif/object">
<a tal:attributes="href object/url"
tal:content="object/label" /></td>
<td tal:content="notif/text" />
<td tal:content="notif/read_ts" />
</tr>
</table>
</form>
</div> </div>
</metal:block> </metal:block>

View file

@ -33,9 +33,12 @@ class Notifications(Favorites):
self.context = (baseObject(person). self.context = (baseObject(person).
getLoopsRoot().getRecordManager()['favorites']) getLoopsRoot().getRecordManager()['favorites'])
def listTracks(self): def listTracks(self, unreadOnly=False):
return super(Notifications, self).listTracks( tracks = super(Notifications, self).listTracks(
baseObject(self.person), type='notification') baseObject(self.person), type='notification')
if unreadOnly:
tracks = [t for t in tracks if not t.data.get('read_ts')]
return tracks
def add(self, obj, sender, text): def add(self, obj, sender, text):
senderUid = util.getUidForObject(baseObject(sender)) senderUid = util.getUidForObject(baseObject(sender))