Add support for toggling visibility of email profile settings
This commit is contained in:
parent
7d3f2e6bdf
commit
d52a186e12
|
@ -1492,6 +1492,12 @@ class GridAction(object):
|
|||
return self.url(row, i)
|
||||
return self.url
|
||||
|
||||
def render_icon(self):
|
||||
"""
|
||||
Render the HTML snippet for the action link icon.
|
||||
"""
|
||||
return HTML.tag('i', class_='fas fa-{}'.format(self.icon))
|
||||
|
||||
def render_label(self):
|
||||
"""
|
||||
Render the label "text" within the actions column of a grid
|
||||
|
|
|
@ -135,7 +135,7 @@
|
|||
</div>
|
||||
|
||||
<b-table
|
||||
:data="data"
|
||||
:data="visibleData"
|
||||
## :columns="columns"
|
||||
:loading="loading"
|
||||
:row-class="getRowClass"
|
||||
|
@ -211,7 +211,7 @@
|
|||
@click.prevent="${action.click_handler}"
|
||||
% endif
|
||||
>
|
||||
<i class="fas fa-${action.icon}"></i>
|
||||
${action.render_icon()|n}
|
||||
${action.render_label()|n}
|
||||
</a>
|
||||
|
||||
|
@ -296,15 +296,24 @@
|
|||
let ${grid.component_studly} = {
|
||||
template: '#${grid.component}-template',
|
||||
|
||||
mixins: [FormPosterMixin],
|
||||
|
||||
props: {
|
||||
csrftoken: String,
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
||||
// note, can use this with v-model for hidden 'uuids' fields
|
||||
selected_uuids: function() {
|
||||
return this.checkedRowUUIDs().join(',')
|
||||
},
|
||||
|
||||
// nb. this can be overridden if needed, e.g. to dynamically
|
||||
// show/hide certain records in a static data set
|
||||
visibleData() {
|
||||
return this.data
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
|
|
@ -481,7 +481,7 @@
|
|||
</%def>
|
||||
|
||||
<%def name="render_grid_component()">
|
||||
<${grid.component} :csrftoken="csrftoken"
|
||||
<${grid.component} ref="grid" :csrftoken="csrftoken"
|
||||
% if master.deletable and request.has_perm('{}.delete'.format(permission_prefix)) and master.delete_confirm == 'simple':
|
||||
@deleteActionClicked="deleteObject"
|
||||
% endif
|
||||
|
|
63
tailbone/templates/settings/email/index.mako
Normal file
63
tailbone/templates/settings/email/index.mako
Normal file
|
@ -0,0 +1,63 @@
|
|||
## -*- coding: utf-8; -*-
|
||||
<%inherit file="/master/index.mako" />
|
||||
|
||||
<%def name="render_grid_component()">
|
||||
% if master.has_perm('configure'):
|
||||
<b-field horizontal label="Showing:">
|
||||
<b-select v-model="showEmails" @input="updateVisibleEmails()">
|
||||
<option value="available">Available Emails</option>
|
||||
<option value="all">All Emails</option>
|
||||
<option value="hidden">Hidden Emails</option>
|
||||
</b-select>
|
||||
</b-field>
|
||||
% endif
|
||||
|
||||
${parent.render_grid_component()}
|
||||
</%def>
|
||||
|
||||
<%def name="modify_this_page_vars()">
|
||||
${parent.modify_this_page_vars()}
|
||||
% if master.has_perm('configure'):
|
||||
<script type="text/javascript">
|
||||
|
||||
ThisPageData.showEmails = 'available'
|
||||
|
||||
ThisPage.methods.updateVisibleEmails = function() {
|
||||
this.$refs.grid.showEmails = this.showEmails
|
||||
}
|
||||
|
||||
${grid.component_studly}Data.showEmails = 'available'
|
||||
|
||||
${grid.component_studly}.computed.visibleData = function() {
|
||||
|
||||
if (this.showEmails == 'available') {
|
||||
return this.data.filter(email => email.hidden == 'No')
|
||||
|
||||
} else if (this.showEmails == 'hidden') {
|
||||
return this.data.filter(email => email.hidden == 'Yes')
|
||||
}
|
||||
|
||||
// showing all
|
||||
return this.data
|
||||
}
|
||||
|
||||
${grid.component_studly}.methods.renderLabelToggleHidden = function(row) {
|
||||
return row.hidden == 'Yes' ? "Un-hide" : "Hide"
|
||||
}
|
||||
|
||||
${grid.component_studly}.methods.toggleHidden = function(row) {
|
||||
let url = '${url('{}.toggle_hidden'.format(route_prefix))}'
|
||||
let params = {
|
||||
key: row.key,
|
||||
hidden: row.hidden == 'No'? true : false,
|
||||
}
|
||||
this.submitForm(url, params, response => {
|
||||
row.hidden = params.hidden ? 'Yes' : 'No'
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
|
@ -27,6 +27,7 @@ Email Views
|
|||
from __future__ import unicode_literals, absolute_import
|
||||
|
||||
import re
|
||||
import warnings
|
||||
|
||||
import six
|
||||
|
||||
|
@ -38,6 +39,7 @@ import colander
|
|||
from deform import widget as dfwidget
|
||||
from webhelpers2.html import HTML
|
||||
|
||||
from tailbone import grids
|
||||
from tailbone.db import Session
|
||||
from tailbone.views import View, MasterView
|
||||
|
||||
|
@ -63,6 +65,7 @@ class EmailSettingView(MasterView):
|
|||
'subject',
|
||||
'to',
|
||||
'enabled',
|
||||
'hidden',
|
||||
]
|
||||
|
||||
form_fields = [
|
||||
|
@ -77,11 +80,19 @@ class EmailSettingView(MasterView):
|
|||
'cc',
|
||||
'bcc',
|
||||
'enabled',
|
||||
'hidden',
|
||||
]
|
||||
|
||||
def __init__(self, request):
|
||||
super(EmailSettingView, self).__init__(request)
|
||||
self.handler = self.get_handler()
|
||||
self.email_handler = self.get_handler()
|
||||
|
||||
@property
|
||||
def handler(self):
|
||||
warnings.warn("the `handler` property is deprecated! "
|
||||
"please use `email_handler` instead",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
return self.email_handler
|
||||
|
||||
def get_handler(self):
|
||||
app = self.get_rattail_app()
|
||||
|
@ -89,9 +100,12 @@ class EmailSettingView(MasterView):
|
|||
|
||||
def get_data(self, session=None):
|
||||
data = []
|
||||
for email in self.handler.iter_emails():
|
||||
key = email.key or email.__name__
|
||||
email = email(self.rattail_config, key)
|
||||
if self.has_perm('configure'):
|
||||
emails = self.email_handler.get_all_emails()
|
||||
else:
|
||||
emails = self.email_handler.get_available_emails()
|
||||
for key, Email in six.iteritems(emails):
|
||||
email = Email(self.rattail_config, key)
|
||||
data.append(self.normalize(email))
|
||||
return data
|
||||
|
||||
|
@ -112,6 +126,20 @@ class EmailSettingView(MasterView):
|
|||
g.set_renderer('to', self.render_to_short)
|
||||
g.sorters['to'] = g.make_simple_sorter('to', foldcase=True)
|
||||
|
||||
# hidden
|
||||
if self.has_perm('configure'):
|
||||
g.sorters['hidden'] = g.make_simple_sorter('hidden')
|
||||
g.set_type('hidden', 'boolean')
|
||||
else:
|
||||
g.remove('hidden')
|
||||
|
||||
# toggle hidden
|
||||
if self.has_perm('configure'):
|
||||
g.main_actions.append(
|
||||
self.make_action('toggle_hidden', url='#', icon='ban',
|
||||
click_handler='toggleHidden(props.row)',
|
||||
factory=ToggleHidden))
|
||||
|
||||
def render_to_short(self, email, column):
|
||||
profile = email['_email']
|
||||
if self.rattail_config.production():
|
||||
|
@ -133,7 +161,7 @@ class EmailSettingView(MasterView):
|
|||
if recips:
|
||||
return ', '.join(recips)
|
||||
data = email.obtain_sample_data(self.request)
|
||||
return {
|
||||
normal = {
|
||||
'_email': email,
|
||||
'key': email.key,
|
||||
'fallback_key': email.fallback_key,
|
||||
|
@ -147,10 +175,13 @@ class EmailSettingView(MasterView):
|
|||
'bcc': get_recips('bcc') or '',
|
||||
'enabled': email.get_enabled(),
|
||||
}
|
||||
if self.has_perm('configure'):
|
||||
normal['hidden'] = self.email_handler.email_is_hidden(email.key)
|
||||
return normal
|
||||
|
||||
def get_instance(self):
|
||||
key = self.request.matchdict['key']
|
||||
return self.normalize(self.handler.get_email(key))
|
||||
return self.normalize(self.email_handler.get_email(key))
|
||||
|
||||
def get_instance_title(self, email):
|
||||
return email['_email'].get_complete_subject(render=False)
|
||||
|
@ -207,8 +238,20 @@ class EmailSettingView(MasterView):
|
|||
# enabled
|
||||
f.set_type('enabled', 'boolean')
|
||||
|
||||
# hidden
|
||||
if self.has_perm('configure'):
|
||||
f.set_type('hidden', 'boolean')
|
||||
else:
|
||||
f.remove('hidden')
|
||||
|
||||
def make_form_schema(self):
|
||||
return EmailProfileSchema()
|
||||
schema = EmailProfileSchema()
|
||||
|
||||
if not self.has_perm('configure'):
|
||||
hidden = schema.get('hidden')
|
||||
schema.children.remove(hidden)
|
||||
|
||||
return schema
|
||||
|
||||
def save_edit_form(self, form):
|
||||
key = self.request.matchdict['key']
|
||||
|
@ -223,11 +266,13 @@ class EmailSettingView(MasterView):
|
|||
app.save_setting(session, 'rattail.mail.{}.cc'.format(key), (data['cc'] or '').replace('\n', ', '))
|
||||
app.save_setting(session, 'rattail.mail.{}.bcc'.format(key), (data['bcc'] or '').replace('\n', ', '))
|
||||
app.save_setting(session, 'rattail.mail.{}.enabled'.format(key), six.text_type(data['enabled']).lower())
|
||||
if self.has_perm('configure'):
|
||||
app.save_setting(session, 'rattail.mail.{}.hidden'.format(key), six.text_type(data['hidden']).lower())
|
||||
return data
|
||||
|
||||
def template_kwargs_view(self, **kwargs):
|
||||
key = self.request.matchdict['key']
|
||||
kwargs['email'] = self.handler.get_email(key)
|
||||
kwargs['email'] = self.email_handler.get_email(key)
|
||||
return kwargs
|
||||
|
||||
def configure_get_simple_settings(self):
|
||||
|
@ -240,10 +285,48 @@ class EmailSettingView(MasterView):
|
|||
'type': bool},
|
||||
]
|
||||
|
||||
def toggle_hidden(self):
|
||||
app = self.get_rattail_app()
|
||||
data = self.request.json_body
|
||||
name = 'rattail.mail.{}.hidden'.format(data['key'])
|
||||
app.save_setting(self.Session(), name,
|
||||
'true' if data['hidden'] else 'false')
|
||||
return {'ok': True}
|
||||
|
||||
@classmethod
|
||||
def defaults(cls, config):
|
||||
cls._email_defaults(config)
|
||||
cls._defaults(config)
|
||||
|
||||
@classmethod
|
||||
def _email_defaults(cls, config):
|
||||
route_prefix = cls.get_route_prefix()
|
||||
url_prefix = cls.get_url_prefix()
|
||||
permission_prefix = cls.get_permission_prefix()
|
||||
model_title_plural = cls.get_model_title_plural()
|
||||
|
||||
# toggle hidden
|
||||
config.add_route('{}.toggle_hidden'.format(route_prefix),
|
||||
'{}/toggle-hidden'.format(url_prefix),
|
||||
request_method='POST')
|
||||
config.add_view(cls, attr='toggle_hidden',
|
||||
route_name='{}.toggle_hidden'.format(route_prefix),
|
||||
permission='{}.configure'.format(permission_prefix),
|
||||
renderer='json')
|
||||
|
||||
# TODO: deprecate / remove this
|
||||
ProfilesView = EmailSettingView
|
||||
|
||||
|
||||
class ToggleHidden(grids.GridAction):
|
||||
"""
|
||||
Grid action for toggling the 'hidden' flag for an email profile.
|
||||
"""
|
||||
|
||||
def render_label(self):
|
||||
return '{{ renderLabelToggleHidden(props.row) }}'
|
||||
|
||||
|
||||
class RecipientsType(colander.String):
|
||||
"""
|
||||
Custom schema type for email recipients. This is used to present the
|
||||
|
@ -284,6 +367,8 @@ class EmailProfileSchema(colander.MappingSchema):
|
|||
|
||||
enabled = colander.SchemaNode(colander.Boolean())
|
||||
|
||||
hidden = colander.SchemaNode(colander.Boolean())
|
||||
|
||||
|
||||
class EmailPreview(View):
|
||||
"""
|
||||
|
@ -292,7 +377,14 @@ class EmailPreview(View):
|
|||
|
||||
def __init__(self, request):
|
||||
super(EmailPreview, self).__init__(request)
|
||||
self.handler = self.get_handler()
|
||||
self.email_handler = self.get_handler()
|
||||
|
||||
@property
|
||||
def handler(self):
|
||||
warnings.warn("the `handler` property is deprecated! "
|
||||
"please use `email_handler` instead",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
return self.email_handler
|
||||
|
||||
def get_handler(self):
|
||||
app = self.get_rattail_app()
|
||||
|
@ -319,10 +411,10 @@ class EmailPreview(View):
|
|||
if recipient:
|
||||
key = self.request.POST.get('email_key')
|
||||
if key:
|
||||
email = self.handler.get_email(key)
|
||||
email = self.email_handler.get_email(key)
|
||||
data = email.obtain_sample_data(self.request)
|
||||
|
||||
self.handler.send_message(email, data,
|
||||
self.email_handler.send_message(email, data,
|
||||
subject_prefix="[PREVIEW] ",
|
||||
to=[recipient],
|
||||
cc=None, bcc=None)
|
||||
|
@ -332,7 +424,7 @@ class EmailPreview(View):
|
|||
key, recipient))
|
||||
|
||||
def preview_template(self, key, type_):
|
||||
email = self.handler.get_email(key)
|
||||
email = self.email_handler.get_email(key)
|
||||
template = email.get_template(type_)
|
||||
data = email.obtain_sample_data(self.request)
|
||||
self.request.response.text = template.render(**data)
|
||||
|
|
Loading…
Reference in a new issue