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
	
	 Lance Edgar
						Lance Edgar