Refactor magic recipients field when sending new message.

Uses local cache of user mappings instead of AJAX calls; has just enough
customization hooks to allow for a department/user mapping for MJ...
This commit is contained in:
Lance Edgar 2016-02-11 17:05:56 -06:00
parent ad9cd8be8e
commit c65bc6f229
3 changed files with 86 additions and 66 deletions

View file

@ -63,6 +63,9 @@ class AutocompleteView(View):
"""
return instance.uuid
def get_data(self, term):
return self.query(term).all()
def __call__(self):
"""
View implementation.
@ -73,5 +76,5 @@ class AutocompleteView(View):
term = self.prepare_term(term)
if not term:
return []
results = self.query(term).all()
results = self.get_data(term)
return [{'label': self.display(x), 'value': self.value(x)} for x in results]

View file

@ -26,6 +26,7 @@ Message Views
from __future__ import unicode_literals, absolute_import
import json
import pytz
from rattail import enum
@ -39,7 +40,7 @@ from webhelpers.html import tags, HTML
from tailbone import forms
from tailbone.db import Session
from tailbone.views import MasterView, AutocompleteView
from tailbone.views import MasterView
class SubjectFieldRenderer(formalchemy.FieldRenderer):
@ -80,7 +81,7 @@ class RecipientsFieldRenderer(formalchemy.FieldRenderer):
def render(self, **kwargs):
uuids = self.value
value = ','.join(uuids) if uuids else ''
return text_field(self.name, value=value, maxlength=self.length, **kwargs)
return text_field(self.name, value=value, **kwargs)
def deserialize(self):
value = self.params.getone(self.name).split(',')
@ -150,8 +151,8 @@ class MessagesView(MasterView):
def query(self, session):
return session.query(model.Message)\
.outerjoin(model.MessageRecipient)\
.filter(model.MessageRecipient.recipient == self.request.user)
.outerjoin(model.MessageRecipient)\
.filter(model.MessageRecipient.recipient == self.request.user)
def configure_grid(self, g):
@ -206,9 +207,9 @@ class MessagesView(MasterView):
message.subject = "Re: {}".format(old_message.subject)
message.body = self.get_reply_body(old_message)
if self.replying == 'all':
value = [(r.recipient_uuid, r.recipient.person.display_name)
value = [(r.recipient.uuid, r.recipient.person.display_name)
for r in old_message.recipients
if r.recipient.active]
if self.filter_reply_recipient(r.recipient)]
value = dict(value)
value.pop(self.request.user.uuid, None)
value = sorted(value.iteritems(), key=lambda r: r[1])
@ -216,8 +217,8 @@ class MessagesView(MasterView):
if old_message.sender is not self.request.user and old_message.sender.active:
value.insert(0, old_message.sender_uuid)
fs.recipients.set(value=value)
else:
fs.recipients.set(value=[old_message.sender_uuid])
elif self.filter_reply_recipient(old_message.sender):
fs.recipients.set(value=[old_message.sender.uuid])
fs.focus = fs.body
elif self.viewing:
@ -228,6 +229,9 @@ class MessagesView(MasterView):
fs.subject,
])
def filter_reply_recipient(self, user):
return user.active
def get_reply_header(self, message):
sent = pytz.utc.localize(message.sent)
sent = localtime(self.rattail_config, sent)
@ -247,22 +251,34 @@ class MessagesView(MasterView):
return '\n'.join(lines)
def get_recipient(self, message):
for recip in message.recipients:
if recip.recipient is self.request.user:
return recip
"""
Fetch the recipient from the given message, which corresponds to the
current (request) user.
"""
for recipient in message.recipients:
if recipient.recipient is self.request.user:
return recipient
def template_kwargs_create(self, **kwargs):
kwargs['available_recipients'] = self.get_available_recipients()
kwargs['json'] = json
if self.replying:
message = self.get_instance()
kwargs['original_message'] = message
names = {message.sender_uuid: message.sender.person.display_name}
if self.replying == 'all':
for recip in message.recipients:
if recip.recipient is not message.sender:
names[recip.recipient_uuid] = recip.recipient.person.display_name
kwargs['initial_recipient_names'] = names
kwargs['original_message'] = self.get_instance()
return kwargs
def get_available_recipients(self):
"""
Return the full mapping of recipients which may be included in a
message sent by the current user.
"""
recips = {}
users = Session.query(model.User)\
.join(model.Person)\
.filter(model.User.active == True)
for user in users:
recips[user.uuid] = user.person.display_name
return recips
def template_kwargs_view(self, **kwargs):
message = kwargs['instance']
return {'message': message,
@ -395,29 +411,13 @@ class SentView(MessagesView):
def query(self, session):
return session.query(model.Message)\
.filter(model.Message.sender == self.request.user)
.filter(model.Message.sender == self.request.user)
def configure_grid(self, g):
super(SentView, self).configure_grid(g)
g.filters['sender'].default_active = False
class RecipientsAutocomplete(AutocompleteView):
"""
Autocomplete AJAX view for the recipients field when sending a new message.
"""
def query(self, term):
return Session.query(model.User)\
.join(model.Person)\
.filter(model.User.active == True)\
.filter(model.Person.display_name.ilike('%{}%'.format(term)))\
.order_by(model.Person.display_name)
def display(self, user):
return user.person.display_name
def includeme(config):
config.add_tailbone_permission('messages', 'messages.list', "List/Search Messages")
@ -437,9 +437,4 @@ def includeme(config):
config.add_view(SentView, attr='index', route_name='messages.sent',
permission='messages.list')
# recipients autocomplete
config.add_route('messages.recipients', '/messages/recipients')
config.add_view(RecipientsAutocomplete, route_name='messages.recipients',
renderer='json', permission='messages.create')
MessagesView.defaults(config)