Refactor "send new message" form, esp. recipients field, per Vue.js
This commit is contained in:
parent
e153e530a8
commit
86695c9dc7
8 changed files with 274 additions and 20 deletions
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2018 Lance Edgar
|
||||
# Copyright © 2010-2019 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -36,6 +36,7 @@ from deform import widget as dfwidget
|
|||
from pyramid import httpexceptions
|
||||
from webhelpers2.html import tags, HTML
|
||||
|
||||
# from tailbone import forms
|
||||
from tailbone.db import Session
|
||||
from tailbone.views import MasterView
|
||||
from tailbone.util import raw_datetime
|
||||
|
@ -140,6 +141,8 @@ class MessagesView(MasterView):
|
|||
return six.text_type(sender)
|
||||
|
||||
def render_subject_bold(self, message, field):
|
||||
if not message.subject:
|
||||
return ""
|
||||
return HTML.tag('span', c=message.subject, style='font-weight: bold;')
|
||||
|
||||
def render_recipients(self, message, column_name):
|
||||
|
@ -212,9 +215,12 @@ class MessagesView(MasterView):
|
|||
super(MessagesView, self).configure_form(f)
|
||||
use_buefy = self.get_use_buefy()
|
||||
|
||||
# we have custom logic to disable submit button
|
||||
f.auto_disable = False
|
||||
f.auto_disable_save = False
|
||||
f.submit_label = "Send Message"
|
||||
|
||||
if not use_buefy:
|
||||
# we have custom logic to disable submit button
|
||||
f.auto_disable = False
|
||||
f.auto_disable_save = False
|
||||
|
||||
# TODO: A fair amount of this still seems hacky...
|
||||
|
||||
|
@ -223,22 +229,34 @@ class MessagesView(MasterView):
|
|||
|
||||
f.set_type('sent', 'datetime')
|
||||
|
||||
# recipients
|
||||
f.set_renderer('recipients', self.render_recipients_full)
|
||||
f.set_label('recipients', "To")
|
||||
|
||||
# subject
|
||||
if use_buefy:
|
||||
f.set_renderer('subject', self.render_subject_bold)
|
||||
if self.creating:
|
||||
f.set_widget('subject', dfwidget.TextInputWidget(
|
||||
placeholder="please enter a subject",
|
||||
autocomplete='off'))
|
||||
f.set_required('subject')
|
||||
|
||||
# body
|
||||
f.set_widget('body', dfwidget.TextAreaWidget(cols=50, rows=15))
|
||||
|
||||
if self.creating:
|
||||
f.remove('sender', 'sent')
|
||||
|
||||
f.insert_after('recipients', 'recipients_')
|
||||
# recipients
|
||||
f.insert_after('recipients', 'set_recipients')
|
||||
f.remove('recipients')
|
||||
f.set_node('recipients_', colander.SchemaNode(colander.Set()))
|
||||
f.set_widget('recipients_', RecipientsWidget())
|
||||
f.set_label('recipients_', "To")
|
||||
f.set_node('set_recipients', colander.SchemaNode(colander.Set()))
|
||||
if use_buefy:
|
||||
f.set_widget('set_recipients', RecipientsWidgetBuefy())
|
||||
else:
|
||||
f.set_widget('set_recipients', RecipientsWidget())
|
||||
f.set_label('set_recipients', "To")
|
||||
|
||||
if self.replying:
|
||||
old_message = self.get_instance()
|
||||
|
@ -259,11 +277,11 @@ class MessagesView(MasterView):
|
|||
value = [r[0] for r in value]
|
||||
if old_message.sender is not self.request.user and old_message.sender.active:
|
||||
value.insert(0, old_message.sender_uuid)
|
||||
f.set_default('recipients_', ','.join(value))
|
||||
f.set_default('set_recipients', ','.join(value))
|
||||
|
||||
# Just a normal reply, to sender only.
|
||||
elif self.filter_reply_recipient(old_message.sender):
|
||||
f.set_default('recipients_', old_message.sender.uuid)
|
||||
f.set_default('set_recipients', old_message.sender.uuid)
|
||||
|
||||
# TODO?
|
||||
# # Set focus to message body instead of recipients, when replying.
|
||||
|
@ -281,7 +299,7 @@ class MessagesView(MasterView):
|
|||
if self.request.user:
|
||||
message.sender = self.request.user
|
||||
|
||||
for uuid in data['recipients_']:
|
||||
for uuid in data['set_recipients']:
|
||||
user = self.Session.query(model.User).get(uuid)
|
||||
if user:
|
||||
message.add_recipient(user, status=self.enum.MESSAGE_STATUS_INBOX)
|
||||
|
@ -322,11 +340,21 @@ class MessagesView(MasterView):
|
|||
return recipient
|
||||
|
||||
def template_kwargs_create(self, **kwargs):
|
||||
recips = list(self.get_available_recipients().items())
|
||||
use_buefy = self.get_use_buefy()
|
||||
|
||||
recips = self.get_available_recipients()
|
||||
if use_buefy:
|
||||
kwargs['recipient_display_map'] = recips
|
||||
recips = list(recips.items())
|
||||
recips.sort(key=self.recipient_sortkey)
|
||||
kwargs['available_recipients'] = recips
|
||||
|
||||
if self.replying:
|
||||
kwargs['original_message'] = self.get_instance()
|
||||
|
||||
if use_buefy:
|
||||
kwargs['index_url'] = None
|
||||
kwargs['index_title'] = "New Message"
|
||||
return kwargs
|
||||
|
||||
def recipient_sortkey(self, recip):
|
||||
|
@ -355,7 +383,7 @@ class MessagesView(MasterView):
|
|||
kwargs['message'] = message
|
||||
kwargs['recipient'] = recipient
|
||||
|
||||
if recipient.status == self.enum.MESSAGE_STATUS_ARCHIVE:
|
||||
if recipient and recipient.status == self.enum.MESSAGE_STATUS_ARCHIVE:
|
||||
kwargs['index_url'] = self.request.route_url('messages.archive')
|
||||
|
||||
return kwargs
|
||||
|
@ -514,6 +542,30 @@ class RecipientsWidget(dfwidget.TextInputWidget):
|
|||
return pstruct.split(',')
|
||||
|
||||
|
||||
class RecipientsWidgetBuefy(dfwidget.Widget):
|
||||
"""
|
||||
Custom "message recipients" widget, for use with Buefy / Vue.js themes.
|
||||
"""
|
||||
template = 'message_recipients_buefy'
|
||||
|
||||
def deserialize(self, field, pstruct):
|
||||
if pstruct is colander.null:
|
||||
return colander.null
|
||||
if not isinstance(pstruct, six.string_types):
|
||||
raise colander.Invalid(field.schema, "Pstruct is not a string")
|
||||
if not pstruct:
|
||||
return colander.null
|
||||
pstruct = pstruct.split(',')
|
||||
return pstruct
|
||||
|
||||
def serialize(self, field, cstruct, **kw):
|
||||
if cstruct in (colander.null, None):
|
||||
cstruct = ""
|
||||
template = self.template
|
||||
values = self.get_template_values(field, cstruct, kw)
|
||||
return field.renderer(template, **values)
|
||||
|
||||
|
||||
def includeme(config):
|
||||
|
||||
config.add_tailbone_permission('messages', 'messages.list', "List/Search Messages")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue