Refactory Buefy templates to use WholePage and ThisPage components

plus add `GridFilter.set_choices()` method
This commit is contained in:
Lance Edgar 2019-08-03 16:57:13 -05:00
parent c64fca852c
commit 1bb0330ab5
36 changed files with 806 additions and 613 deletions

View file

@ -1003,7 +1003,10 @@ class Grid(object):
choices = [] choices = []
choice_labels = {} choice_labels = {}
if self.enums and filtr.key in self.enums: if filtr.choices:
choices = list(filtr.choices)
choices_labels = dict(filtr.choices)
elif self.enums and filtr.key in self.enums:
choices = list(self.enums[filtr.key]) choices = list(self.enums[filtr.key])
choice_labels = self.enums[filtr.key] choice_labels = self.enums[filtr.key]

View file

@ -149,6 +149,7 @@ class GridFilter(object):
value_renderer_factory = DefaultValueRenderer value_renderer_factory = DefaultValueRenderer
data_type = 'string' # default, but will be set from value renderer data_type = 'string' # default, but will be set from value renderer
choices = {}
def __init__(self, key, label=None, verbs=None, value_enum=None, value_renderer=None, def __init__(self, key, label=None, verbs=None, value_enum=None, value_renderer=None,
default_active=False, default_verb=None, default_value=None, default_active=False, default_verb=None, default_value=None,
@ -187,6 +188,27 @@ class GridFilter(object):
return verbs return verbs
return ['equal', 'not_equal', 'is_null', 'is_not_null', 'is_any'] return ['equal', 'not_equal', 'is_null', 'is_not_null', 'is_any']
def set_choices(self, choices):
"""
Set the value choices for the filter, post-construction. Note that
this also will set the value renderer to one which supports choices.
"""
# first must normalize choices
if isinstance(choices, OrderedDict):
normalized = choices
elif isinstance(choices, dict):
normalized = OrderedDict([
(key, choices[value])
for key in sorted(choices)])
elif isinstance(choices, list):
normalized = OrderedDict([
(key, key)
for key in choices])
# store normalized choices, and set renderer
self.choices = normalized
self.set_value_renderer(ChoiceValueRenderer(self.choices))
def set_value_renderer(self, renderer): def set_value_renderer(self, renderer):
""" """
Set the value renderer for the filter, post-construction. Set the value renderer for the filter, post-construction.

View file

@ -174,9 +174,3 @@ let TailboneGrid = {
} }
} }
} }
let GridPage = {
template: '#grid-page-template',
methods: {}
}

View file

@ -1,14 +1,19 @@
## -*- coding: utf-8 -*- ## -*- coding: utf-8; -*-
<%inherit file="/base.mako" /> <%inherit file="/page.mako" />
<%namespace name="base_meta" file="/base_meta.mako" /> <%namespace name="base_meta" file="/base_meta.mako" />
<%def name="title()">About ${base_meta.app_title()}</%def> <%def name="title()">About ${base_meta.app_title()}</%def>
<h2>${project_title} ${project_version}</h2> <%def name="page_content()">
<h2>${project_title} ${project_version}</h2>
% for name, version in packages.items(): % for name, version in packages.items():
<h3>${name} ${version}</h3> <h3>${name} ${version}</h3>
% endfor % endfor
<br /> <br />
<p>Please see <a href="https://rattailproject.org/">rattailproject.org</a> for more info.</p> <p>Please see <a href="https://rattailproject.org/">rattailproject.org</a> for more info.</p>
</%def>
${parent.body()}

View file

@ -1,5 +1,5 @@
## -*- coding: utf-8; -*- ## -*- coding: utf-8; -*-
<%inherit file="/base.mako" /> <%inherit file="/page.mako" />
<%def name="title()">App Settings</%def> <%def name="title()">App Settings</%def>
@ -33,150 +33,164 @@
% endif % endif
</%def> </%def>
<%def name="context_menu_items()">
% if request.has_perm('settings.list'):
<li>${h.link_to("View Raw Settings", url('settings'))}</li>
% endif
</%def>
% if use_buefy: <%def name="page_content()">
<script type="text/x-template" id="app-settings-template"> <app-settings :groups="groups" :showing-group="showingGroup"></app-settings>
</%def>
<div class="form"> <%def name="render_this_page_template()">
${h.form(form.action_url, id=dform.formid, method='post', **{'@submit': 'submitForm'})} ${parent.render_this_page_template()}
${h.csrf_token(request)} <script type="text/x-template" id="app-settings-template">
% if dform.error: <div class="form">
<div class="error-messages"> ${h.form(form.action_url, id=dform.formid, method='post', **{'@submit': 'submitForm'})}
<div class="ui-state-error ui-corner-all"> ${h.csrf_token(request)}
<span style="float: left; margin-right: .3em;" class="ui-icon ui-icon-alert"></span>
Please see errors below. % if dform.error:
</div> <div class="error-messages">
<div class="ui-state-error ui-corner-all"> <div class="ui-state-error ui-corner-all">
<span style="float: left; margin-right: .3em;" class="ui-icon ui-icon-alert"></span> <span style="float: left; margin-right: .3em;" class="ui-icon ui-icon-alert"></span>
${dform.error} Please see errors below.
</div> </div>
<div class="ui-state-error ui-corner-all">
<span style="float: left; margin-right: .3em;" class="ui-icon ui-icon-alert"></span>
${dform.error}
</div> </div>
% endif
<div class="app-wrapper">
<div class="field-wrapper">
<label for="settings-group">Showing Group</label>
<b-select name="settings-group"
v-model="showingGroup">
<option value="">(All)</option>
<option v-for="group in groups"
:key="group.label"
:value="group.label">
{{ group.label }}
</option>
</b-select>
</div> </div>
% endif
<div v-for="group in groups" <div class="app-wrapper">
class="card"
v-show="!showingGroup || showingGroup == group.label"
style="margin-bottom: 1rem;">
<header class="card-header">
<p class="card-header-title">{{ group.label }}</p>
</header>
<div class="card-content">
<div v-for="setting in group.settings"
:class="'field-wrapper' + (setting.error ? ' with-error' : '')">
<div v-if="setting.error" class="field-error"> <div class="field-wrapper">
<span v-for="msg in setting.error_messages" <label for="settings-group">Showing Group</label>
class="error-msg"> <b-select name="settings-group"
{{ msg }} v-model="showingGroup">
</span> <option value="">(All)</option>
</div> <option v-for="group in groups"
:key="group.label"
:value="group.label">
{{ group.label }}
</option>
</b-select>
</div>
<div class="field-row"> <div v-for="group in groups"
<label :for="setting.field_name">{{ setting.label }}</label> class="card"
<div class="field"> v-show="!showingGroup || showingGroup == group.label"
style="margin-bottom: 1rem;">
<header class="card-header">
<p class="card-header-title">{{ group.label }}</p>
</header>
<div class="card-content">
<div v-for="setting in group.settings"
:class="'field-wrapper' + (setting.error ? ' with-error' : '')">
<input v-if="setting.data_type == 'bool'" <div v-if="setting.error" class="field-error">
type="checkbox" <span v-for="msg in setting.error_messages"
class="error-msg">
{{ msg }}
</span>
</div>
<div class="field-row">
<label :for="setting.field_name">{{ setting.label }}</label>
<div class="field">
<input v-if="setting.data_type == 'bool'"
type="checkbox"
:name="setting.field_name"
:id="setting.field_name"
v-model="setting.value"
value="true" />
<b-select v-else-if="setting.choices"
:name="setting.field_name"
:id="setting.field_name"
v-model="setting.value">
<option v-for="choice in setting.choices"
:value="choice">
{{ choice }}
</option>
</b-select>
<b-input v-else
:name="setting.field_name" :name="setting.field_name"
:id="setting.field_name" :id="setting.field_name"
v-model="setting.value" v-model="setting.value" />
value="true" />
<b-select v-else-if="setting.choices"
:name="setting.field_name"
:id="setting.field_name"
v-model="setting.value">
<option v-for="choice in setting.choices"
:value="choice">
{{ choice }}
</option>
</b-select>
<b-input v-else
:name="setting.field_name"
:id="setting.field_name"
v-model="setting.value" />
</div>
</div> </div>
</div>
<span v-if="setting.helptext" class="instructions"> <span v-if="setting.helptext" class="instructions">
{{ setting.helptext }} {{ setting.helptext }}
</span> </span>
</div><!-- field-wrapper --> </div><!-- field-wrapper -->
</div><!-- card-content --> </div><!-- card-content -->
</div><!-- card --> </div><!-- card -->
<div class="buttons"> <div class="buttons">
<b-button type="is-primary" <b-button type="is-primary"
native-type="submit" native-type="submit"
:disabled="formSubmitting"> :disabled="formSubmitting">
{{ formButtonText }} {{ formButtonText }}
</b-button> </b-button>
<once-button tag="a" href="${form.cancel_url}" <once-button tag="a" href="${form.cancel_url}"
text="Cancel"> text="Cancel">
</once-button> </once-button>
</div> </div>
</div><!-- app-wrapper --> </div><!-- app-wrapper -->
${h.end_form()} ${h.end_form()}
</div>
</script>
<div id="app-settings-app">
<app-settings :groups="groups" :showing-group="showingGroup"></app-settings>
</div> </div>
</script>
</%def>
<script type="text/javascript"> <%def name="modify_this_page_vars()">
${parent.modify_this_page_vars()}
<script type="text/javascript">
Vue.component('app-settings', { ThisPageData.groups = ${json.dumps(buefy_data)|n}
template: '#app-settings-template', ThisPageData.showingGroup = ${json.dumps(current_group or '')|n}
props: {
groups: Array,
showingGroup: String
},
data() {
return {
formSubmitting: false,
formButtonText: ${json.dumps(getattr(form, 'submit_label', getattr(form, 'save_label', "Submit")))|n},
}
},
methods: {
submitForm() {
this.formSubmitting = true
this.formButtonText = "Working, please wait..."
}
}
})
new Vue({ </script>
el: '#app-settings-app', </%def>
data() {
return {
groups: ${json.dumps(buefy_data)|n},
showingGroup: ${json.dumps(current_group or '')|n}
}
}
})
</script> <%def name="make_this_page_component()">
${parent.make_this_page_component()}
<script type="text/javascript">
Vue.component('app-settings', {
template: '#app-settings-template',
props: {
groups: Array,
showingGroup: String
},
data() {
return {
formSubmitting: false,
formButtonText: ${json.dumps(getattr(form, 'submit_label', getattr(form, 'save_label', "Submit")))|n},
}
},
methods: {
submitForm() {
this.formSubmitting = true
this.formButtonText = "Working, please wait..."
}
}
})
</script>
</%def>
% if use_buefy:
${parent.body()}
% else: % else:
## legacy / not buefy ## legacy / not buefy

View file

@ -107,19 +107,15 @@
% endif % endif
</%def> </%def>
<%def name="modify_tailbone_grid()"> <%def name="modify_this_page_vars()">
${parent.modify_tailbone_grid()} ${parent.modify_this_page_vars()}
% if master.results_executable and request.has_perm('{}.execute_multiple'.format(permission_prefix)): % if master.results_executable and request.has_perm('{}.execute_multiple'.format(permission_prefix)):
<script type="text/javascript"> <script type="text/javascript">
TailboneForm.data = function() { return TailboneFormData }
TailboneForm.methods.submit = function() { TailboneForm.methods.submit = function() {
this.$refs.actualForm.submit() this.$refs.actualForm.submit()
} }
Vue.component('tailbone-form', TailboneForm)
TailboneGridData.hasExecutionOptions = ${json.dumps(master.has_execution_options(batch))|n} TailboneGridData.hasExecutionOptions = ${json.dumps(master.has_execution_options(batch))|n}
TailboneGridData.showExecutionOptions = false TailboneGridData.showExecutionOptions = false
@ -151,12 +147,26 @@
% endif % endif
</%def> </%def>
<%def name="make_this_page_component()">
${parent.make_this_page_component()}
% if master.results_executable and request.has_perm('{}.execute_multiple'.format(permission_prefix)):
<script type="text/javascript">
TailboneForm.data = function() { return TailboneFormData }
Vue.component('tailbone-form', TailboneForm)
</script>
% endif
</%def>
<%def name="render_this_page_template()">
${parent.render_this_page_template()}
% if master.results_executable and request.has_perm('{}.execute_multiple'.format(permission_prefix)):
${execute_form.render_deform(form_kwargs={'ref': 'actualForm'}, buttons=False)|n}
% endif
</%def>
% if use_buefy:
% if master.results_executable and request.has_perm('{}.execute_multiple'.format(permission_prefix)):
${execute_form.render_deform(form_kwargs={'ref': 'actualForm'}, buttons=False)|n}
% endif
% endif
${parent.body()} ${parent.body()}

View file

@ -187,16 +187,16 @@
% endif % endif
</%def> </%def>
<%def name="render_this_page_buefy()"> <%def name="render_this_page_template()">
${parent.render_this_page_template()}
% if use_buefy and master.handler.executable(batch) and request.has_perm('{}.execute'.format(permission_prefix)): % if use_buefy and master.handler.executable(batch) and request.has_perm('{}.execute'.format(permission_prefix)):
## TODO: stop using |n filter ## TODO: stop using |n filter
${execute_form.render_deform(buttons=capture(execute_submit_button), form_kwargs={'@submit': 'submitExecuteForm'})|n} ${execute_form.render_deform(buttons=capture(execute_submit_button), form_kwargs={'@submit': 'submitExecuteForm'})|n}
% endif % endif
${parent.render_this_page_buefy()}
</%def> </%def>
<%def name="modify_this_page()"> <%def name="modify_this_page_vars()">
${parent.modify_this_page()} ${parent.modify_this_page_vars()}
% if not batch.executed and request.has_perm('{}.execute'.format(permission_prefix)): % if not batch.executed and request.has_perm('{}.execute'.format(permission_prefix)):
<script type="text/javascript"> <script type="text/javascript">
@ -216,8 +216,8 @@
% endif % endif
</%def> </%def>
<%def name="finalize_page_components()"> <%def name="finalize_this_page_vars()">
${parent.finalize_page_components()} ${parent.finalize_this_page_vars()}
% if not batch.executed and request.has_perm('{}.execute'.format(permission_prefix)): % if not batch.executed and request.has_perm('{}.execute'.format(permission_prefix)):
<script type="text/javascript"> <script type="text/javascript">

View file

@ -1,8 +1,13 @@
## -*- coding: utf-8; -*- ## -*- coding: utf-8; -*-
<%inherit file="/base.mako" /> <%inherit file="/page.mako" />
<%def name="title()">Change Password</%def> <%def name="title()">Change Password</%def>
<div class="form"> <%def name="page_content()">
${form.render_deform()|n} <div class="form">
</div> ${form.render_deform()|n}
</div>
</%def>
${parent.body()}

View file

@ -42,8 +42,8 @@
</%def> </%def>
<%def name="modify_tailbone_grid()"> <%def name="modify_this_page_vars()">
${parent.modify_tailbone_grid()} ${parent.modify_this_page_vars()}
<script type="text/javascript"> <script type="text/javascript">
% if request.has_perm('datasync.restart'): % if request.has_perm('datasync.restart'):

View file

@ -1,13 +1,18 @@
## -*- coding: utf-8 -*- ## -*- coding: utf-8; -*-
<%inherit file="/master/view.mako" /> <%inherit file="/master/view.mako" />
<%def name="page_content()">
${parent.page_content()}
<h2>Employees</h2>
% if employees:
<p>The following employees are assigned to this department:</p>
${employees.render_grid()|n}
% else:
<p>No employees are assigned to this department.</p>
% endif
</%def>
${parent.body()} ${parent.body()}
<h2>Employees</h2>
% if employees:
<p>The following employees are assigned to this department:</p>
${employees.render_grid()|n}
% else:
<p>No employees are assigned to this department.</p>
% endif

View file

@ -1,16 +1,10 @@
## -*- coding: utf-8 -*- ## -*- coding: utf-8; -*-
<%inherit file="/master/view.mako" /> <%inherit file="/master/view.mako" />
<%def name="head_tags()"> ## TODO: this page still uses jQuery but should use Vue.js
${parent.head_tags()}
<style type="text/css"> <%def name="extra_javascript()">
#message { ${parent.extra_javascript()}
border: 1px solid #000000;
height: 400px;
overflow: auto;
padding: 4px;
}
</style>
<script type="text/javascript"> <script type="text/javascript">
function autosize_message(scrolldown) { function autosize_message(scrolldown) {
@ -34,6 +28,18 @@
</script> </script>
</%def> </%def>
<%def name="extra_styles()">
${parent.extra_styles()}
<style type="text/css">
#message {
border: 1px solid #000000;
height: 400px;
overflow: auto;
padding: 4px;
}
</style>
</%def>
<%def name="context_menu_items()"> <%def name="context_menu_items()">
${parent.context_menu_items()} ${parent.context_menu_items()}
% if not bounce.processed and request.has_perm('emailbounces.process'): % if not bounce.processed and request.has_perm('emailbounces.process'):
@ -43,8 +49,12 @@
% endif % endif
</%def> </%def>
${parent.body()} <%def name="page_content()">
${parent.page_content()}
<pre id="message">
${message}
</pre>
</%def>
<pre id="message">
${message} ${parent.body()}
</pre>

View file

@ -45,15 +45,15 @@
</div> </div>
</%def> </%def>
<%def name="render_this_page_buefy()"> <%def name="render_this_page_template()">
% if form is not Underined: % if form is not Underined:
${self.render_form()} ${self.render_form()}
% endif % endif
${parent.render_this_page_buefy()} ${parent.render_this_page_template()}
</%def> </%def>
<%def name="finalize_page_components()"> <%def name="finalize_this_page_vars()">
${parent.finalize_page_components()} ${parent.finalize_this_page_vars()}
% if form is not Undefined: % if form is not Undefined:
<script type="text/javascript"> <script type="text/javascript">

View file

@ -1,5 +1,5 @@
## -*- coding: utf-8; -*- ## -*- coding: utf-8; -*-
<%inherit file="/base.mako" /> <%inherit file="/page.mako" />
<%namespace name="base_meta" file="/base_meta.mako" /> <%namespace name="base_meta" file="/base_meta.mako" />
<%def name="title()">Home</%def> <%def name="title()">Home</%def>
@ -16,7 +16,12 @@
</style> </style>
</%def> </%def>
<div class="logo"> <%def name="page_content()">
${h.image(image_url, "{} logo".format(capture(base_meta.app_title)), id='logo', width=500)} <div class="logo">
<h1>Welcome to ${base_meta.app_title()}</h1> ${h.image(image_url, "{} logo".format(capture(base_meta.app_title)), id='logo', width=500)}
</div> <h1>Welcome to ${base_meta.app_title()}</h1>
</div>
</%def>
${parent.body()}

View file

@ -24,19 +24,24 @@
% endif % endif
</%def> </%def>
<%def name="page_content()">
${parent.page_content()}
<% printer = instance.get_printer(request.rattail_config) %>
% if printer and printer.required_settings:
<h2>Printer Settings</h2>
<div class="form">
% for name, display in printer.required_settings.items():
<div class="field-wrapper">
<label>${display}</label>
<div class="field">${instance.get_printer_setting(name) or ''}</div>
</div>
% endfor
</div>
% endif
</%def>
${parent.body()} ${parent.body()}
<% printer = instance.get_printer(request.rattail_config) %>
% if printer and printer.required_settings:
<h2>Printer Settings</h2>
<div class="form">
% for name, display in printer.required_settings.items():
<div class="field-wrapper">
<label>${display}</label>
<div class="field">${instance.get_printer_setting(name) or ''}</div>
</div>
% endfor
</div>
% endif

View file

@ -1,5 +1,5 @@
## -*- coding: utf-8; -*- ## -*- coding: utf-8; -*-
<%inherit file="/base.mako" /> <%inherit file="/page.mako" />
<%namespace name="base_meta" file="/base_meta.mako" /> <%namespace name="base_meta" file="/base_meta.mako" />
<%def name="title()">Login</%def> <%def name="title()">Login</%def>
@ -24,12 +24,17 @@
</div> </div>
</%def> </%def>
${self.logo()} <%def name="page_content()">
${self.logo()}
${self.login_form()} ${self.login_form()}
% if request.rattail_config.demo(): % if request.rattail_config.demo():
<p class="tips"> <p class="tips">
Login with <strong>chuck / admin</strong> for full demo access Login with <strong>chuck / admin</strong> for full demo access
</p> </p>
% endif % endif
</%def>
${parent.body()}

View file

@ -52,8 +52,8 @@
${h.end_form()} ${h.end_form()}
</%def> </%def>
<%def name="modify_this_page()"> <%def name="modify_this_page_vars()">
${parent.modify_this_page()} ${parent.modify_this_page_vars()}
<script type="text/javascript"> <script type="text/javascript">
TailboneFormData.formSubmitting = false TailboneFormData.formSubmitting = false

View file

@ -68,8 +68,8 @@
${h.end_form()} ${h.end_form()}
</%def> </%def>
<%def name="modify_this_page()"> <%def name="modify_this_page_vars()">
${parent.modify_this_page()} ${parent.modify_this_page_vars()}
<script type="text/javascript"> <script type="text/javascript">
TailboneFormData.formSubmitting = false TailboneFormData.formSubmitting = false

View file

@ -26,8 +26,8 @@
% endif % endif
</%def> </%def>
<%def name="modify_this_page()"> <%def name="modify_this_page_vars()">
${parent.modify_this_page()} ${parent.modify_this_page_vars()}
% if master.deletable and instance_deletable and request.has_perm('{}.delete'.format(permission_prefix)) and master.delete_confirm == 'simple': % if master.deletable and instance_deletable and request.has_perm('{}.delete'.format(permission_prefix)) and master.delete_confirm == 'simple':
<script type="text/javascript"> <script type="text/javascript">

View file

@ -6,7 +6,7 @@
## include a "tools" section, just above the grid on the right. ## include a "tools" section, just above the grid on the right.
## ##
## ############################################################################## ## ##############################################################################
<%inherit file="/base.mako" /> <%inherit file="/page.mako" />
<%def name="title()">${index_title}</%def> <%def name="title()">${index_title}</%def>
@ -215,9 +215,23 @@
</%def> </%def>
<%def name="modify_tailbone_grid()"> <%def name="page_content()">
<script type="text/javascript"> <tailbone-grid
% if master.deletable and request.has_perm('{}.delete'.format(permission_prefix)) and master.delete_confirm == 'simple':
@deleteActionClicked="deleteObject"
% endif
>
</tailbone-grid>
% if master.deletable and request.has_perm('{}.delete'.format(permission_prefix)) and master.delete_confirm == 'simple':
${h.form('#', ref='deleteObjectForm')}
${h.csrf_token(request)}
${h.end_form()}
% endif
</%def>
<%def name="modify_this_page_vars()">
${parent.modify_this_page_vars()}
<script type="text/javascript">
% if master.mergeable and request.has_perm('{}.merge'.format(permission_prefix)): % if master.mergeable and request.has_perm('{}.merge'.format(permission_prefix)):
TailboneGridData.mergeFormButtonText = "Merge 2 ${model_title_plural}" TailboneGridData.mergeFormButtonText = "Merge 2 ${model_title_plural}"
TailboneGridData.mergeFormSubmitting = false TailboneGridData.mergeFormSubmitting = false
@ -226,65 +240,43 @@
this.mergeFormButtonText = "Working, please wait..." this.mergeFormButtonText = "Working, please wait..."
} }
% endif % endif
</script>
</%def>
<%def name="make_tailbone_grid_app()">
${self.modify_tailbone_grid()}
<script type="text/javascript">
TailboneGrid.data = function() { return TailboneGridData }
Vue.component('tailbone-grid', TailboneGrid)
% if master.deletable and request.has_perm('{}.delete'.format(permission_prefix)) and master.delete_confirm == 'simple': % if master.deletable and request.has_perm('{}.delete'.format(permission_prefix)) and master.delete_confirm == 'simple':
ThisPage.methods.deleteObject = function(url) {
GridPage.methods.deleteObject = function(url) {
if (confirm("Are you sure you wish to delete this ${model_title}?")) { if (confirm("Are you sure you wish to delete this ${model_title}?")) {
let form = this.$refs.deleteObjectForm let form = this.$refs.deleteObjectForm
form.action = url form.action = url
form.submit() form.submit()
} }
} }
% endif % endif
</script>
</%def>
Vue.component('grid-page', GridPage) <%def name="make_this_page_component()">
${parent.make_this_page_component()}
<script type="text/javascript">
new Vue({ TailboneGrid.data = function() { return TailboneGridData }
el: '#grid-page-app'
}) Vue.component('tailbone-grid', TailboneGrid)
</script> </script>
</%def> </%def>
<%def name="render_this_page()">
${self.page_content()}
</%def>
<%def name="render_this_page_template()">
${parent.render_this_page_template()}
## TODO: stop using |n filter
${grid.render_buefy(tools=capture(self.grid_tools).strip(), context_menu=capture(self.context_menu_items).strip())|n}
</%def>
% if use_buefy: % if use_buefy:
## TODO: stop using |n filter ${parent.body()}
${grid.render_buefy(tools=capture(self.grid_tools).strip(), context_menu=capture(self.context_menu_items).strip())|n}
<script type="text/x-template" id="grid-page-template">
<div>
<tailbone-grid
% if master.deletable and request.has_perm('{}.delete'.format(permission_prefix)) and master.delete_confirm == 'simple':
@deleteActionClicked="deleteObject"
% endif
>
</tailbone-grid>
% if master.deletable and request.has_perm('{}.delete'.format(permission_prefix)) and master.delete_confirm == 'simple':
${h.form('#', ref='deleteObjectForm')}
${h.csrf_token(request)}
${h.end_form()}
% endif
</div>
</script>
<div id="grid-page-app">
<grid-page></grid-page>
</div>
${self.make_tailbone_grid_app()}
% else: % else:
## no buefy, so do the traditional thing ## no buefy, so do the traditional thing

View file

@ -154,75 +154,80 @@ ${h.end_form()}
% endif % endif
</%def> </%def>
<%def name="render_this_page_template()">
${parent.render_this_page_template()}
% if use_buefy: <script type="text/x-template" id="merge-buttons-template">
<script type="text/x-template" id="merge-buttons-template"> <div class="level" style="margin-top: 2em;">
<div class="level" style="margin-top: 2em;"> <div class="level-left">
<div class="level-left">
<div class="level-item">
<a class="button" href="${index_url}">Whoops, nevermind</a>
</div>
<div class="level-item">
${h.form(request.current_route_url(), **{'@submit': 'submitSwapForm'})}
${h.csrf_token(request)}
${h.hidden('uuids', value='{},{}'.format(object_to_keep.uuid, object_to_remove.uuid))}
<b-button native-type="submit"
:disabled="swapFormSubmitting">
{{ swapFormButtonText }}
</b-button>
${h.end_form()}
</div>
<div class="level-item">
% if use_buefy:
${h.form(request.current_route_url(), **{'@submit': 'submitMergeForm'})}
% else:
${h.form(request.current_route_url())}
% endif
${h.csrf_token(request)}
${h.hidden('uuids', value='{},{}'.format(object_to_remove.uuid, object_to_keep.uuid))}
${h.hidden('commit-merge', value='yes')}
<b-button type="is-primary"
native-type="submit"
:disabled="mergeFormSubmitting">
{{ mergeFormButtonText }}
</b-button>
${h.end_form()}
</div>
<div class="level-item">
<a class="button" href="${index_url}">Whoops, nevermind</a>
</div> </div>
<div class="level-item">
${h.form(request.current_route_url(), **{'@submit': 'submitSwapForm'})}
${h.csrf_token(request)}
${h.hidden('uuids', value='{},{}'.format(object_to_keep.uuid, object_to_remove.uuid))}
<b-button native-type="submit"
:disabled="swapFormSubmitting">
{{ swapFormButtonText }}
</b-button>
${h.end_form()}
</div>
<div class="level-item">
% if use_buefy:
${h.form(request.current_route_url(), **{'@submit': 'submitMergeForm'})}
% else:
${h.form(request.current_route_url())}
% endif
${h.csrf_token(request)}
${h.hidden('uuids', value='{},{}'.format(object_to_remove.uuid, object_to_keep.uuid))}
${h.hidden('commit-merge', value='yes')}
<b-button type="is-primary"
native-type="submit"
:disabled="mergeFormSubmitting">
{{ mergeFormButtonText }}
</b-button>
${h.end_form()}
</div>
</div> </div>
</div> </script>
</script> </%def>
<script type="text/javascript"> <%def name="make_this_page_component()">
${parent.make_this_page_component()}
<script type="text/javascript">
const MergeButtons = { const MergeButtons = {
template: '#merge-buttons-template', template: '#merge-buttons-template',
data() { data() {
return { return {
swapFormButtonText: "Swap which ${model_title} is kept/removed", swapFormButtonText: "Swap which ${model_title} is kept/removed",
swapFormSubmitting: false, swapFormSubmitting: false,
mergeFormButtonText: "Yes, perform this merge", mergeFormButtonText: "Yes, perform this merge",
mergeFormSubmitting: false, mergeFormSubmitting: false,
} }
}, },
methods: { methods: {
submitSwapForm() { submitSwapForm() {
this.swapFormSubmitting = true this.swapFormSubmitting = true
this.swapFormButtonText = "Swapping, please wait..." this.swapFormButtonText = "Swapping, please wait..."
}, },
submitMergeForm() { submitMergeForm() {
this.mergeFormSubmitting = true this.mergeFormSubmitting = true
this.mergeFormButtonText = "Merging, please wait..." this.mergeFormButtonText = "Merging, please wait..."
}, },
} }
} }
Vue.component('merge-buttons', MergeButtons) Vue.component('merge-buttons', MergeButtons)
</script>
</%def>
</script>
% endif
${parent.body()} ${parent.body()}

View file

@ -4,7 +4,9 @@
## Default master 'versions' template, for showing an object's version history. ## Default master 'versions' template, for showing an object's version history.
## ##
## ############################################################################## ## ##############################################################################
<%inherit file="/base.mako" /> <%inherit file="/page.mako" />
## TODO: this page still uses old-style grid but should use Buefy grid
<%def name="title()">${model_title_plural} » ${instance_title} » history</%def> <%def name="title()">${model_title_plural} » ${instance_title} » history</%def>
@ -21,4 +23,9 @@
History for ${instance_title} History for ${instance_title}
</%def> </%def>
${grid.render_complete()|n} <%def name="page_content()">
${grid.render_complete()|n}
</%def>
${parent.body()}

View file

@ -93,15 +93,15 @@
% endif % endif
</%def> </%def>
<%def name="render_this_page_buefy()"> <%def name="render_this_page_template()">
% if master.has_rows: % if master.has_rows:
## TODO: stop using |n filter ## TODO: stop using |n filter
${rows_grid.render_buefy(allow_save_defaults=False, tools=capture(self.render_row_grid_tools))|n} ${rows_grid.render_buefy(allow_save_defaults=False, tools=capture(self.render_row_grid_tools))|n}
% endif % endif
${parent.render_this_page_buefy()} ${parent.render_this_page_template()}
</%def> </%def>
<%def name="make_this_page_app()"> <%def name="make_this_page_component()">
<script type="text/javascript"> <script type="text/javascript">
TailboneGrid.data = function() { return TailboneGridData } TailboneGrid.data = function() { return TailboneGridData }
@ -109,7 +109,7 @@
Vue.component('tailbone-grid', TailboneGrid) Vue.component('tailbone-grid', TailboneGrid)
</script> </script>
${parent.make_this_page_app()} ${parent.make_this_page_component()}
</%def> </%def>

View file

@ -1,8 +1,9 @@
## -*- coding: utf-8; -*- ## -*- coding: utf-8; -*-
<%inherit file="/base.mako" /> <%inherit file="/page.mako" />
<%def name="title()">${instance_title_normal} @ ver ${transaction.id}</%def> <%def name="title()">${instance_title_normal} @ ver ${transaction.id}</%def>
<%def name="page_content()">
## TODO: this was basically copied from Revel diff template..need to abstract ## TODO: this was basically copied from Revel diff template..need to abstract
<div class="form-wrapper"> <div class="form-wrapper">
@ -97,3 +98,7 @@
% endif % endif
% endfor % endfor
</%def>
${parent.body()}

View file

@ -1,4 +1,4 @@
## -*- coding: utf-8 -*- ## -*- coding: utf-8; -*-
<%inherit file="/master/view.mako" /> <%inherit file="/master/view.mako" />
<%def name="extra_javascript()"> <%def name="extra_javascript()">
@ -87,12 +87,17 @@
${instance.body} ${instance.body}
</%def> </%def>
<%def name="page_content()">
${parent.page_content()}
${self.message_tools()}
<div class="message-body">
${self.message_body()}
</div>
${self.message_tools()}
</%def>
${parent.body()} ${parent.body()}
${self.message_tools()}
<div class="message-body">
${self.message_body()}
</div>
${self.message_tools()}

View file

@ -6,9 +6,9 @@
<%def name="page_content()"></%def> <%def name="page_content()"></%def>
<%def name="render_this_page()"> <%def name="render_this_page()">
<div style="display: flex; justify-content: space-between;"> <div style="display: flex;">
<div class="this-page-content"> <div class="this-page-content" style="flex-grow: 1;">
${self.page_content()} ${self.page_content()}
</div> </div>
@ -19,23 +19,15 @@
</div> </div>
</%def> </%def>
<%def name="render_this_page_buefy()"> <%def name="render_this_page_template()">
<script type="text/x-template" id="this-page-template"> <script type="text/x-template" id="this-page-template">
<div> <div>
${self.render_this_page()} ${self.render_this_page()}
</div> </div>
</script> </script>
<div id="this-page-app">
<this-page></this-page>
</div>
</%def> </%def>
<%def name="modify_this_page()"> <%def name="declare_this_page_vars()">
## NOTE: if you override this, must use <script> tags
</%def>
<%def name="declare_page_vars()">
<script type="text/javascript"> <script type="text/javascript">
let ThisPage = { let ThisPage = {
@ -48,31 +40,32 @@
</script> </script>
</%def> </%def>
<%def name="finalize_page_components()"> <%def name="modify_this_page_vars()">
## NOTE: if you override this, must use <script> tags ## NOTE: if you override this, must use <script> tags
</%def> </%def>
<%def name="make_this_page_app()"> <%def name="finalize_this_page_vars()">
${self.declare_page_vars()} ## NOTE: if you override this, must use <script> tags
${self.modify_this_page()} </%def>
${self.finalize_page_components()}
<%def name="make_this_page_component()">
${self.declare_this_page_vars()}
${self.modify_this_page_vars()}
${self.finalize_this_page_vars()}
<script type="text/javascript"> <script type="text/javascript">
ThisPage.data = function() { return ThisPageData } ThisPage.data = function() { return ThisPageData }
Vue.component('this-page', ThisPage) Vue.component('this-page', ThisPage)
new Vue({
el: '#this-page-app'
})
</script> </script>
</%def> </%def>
% if use_buefy: % if use_buefy:
${self.render_this_page_buefy()} ${self.render_this_page_template()}
${self.make_this_page_app()} ${self.make_this_page_component()}
% else: % else:
${self.render_this_page()} ${self.render_this_page()}
% endif % endif

View file

@ -4,7 +4,7 @@
<%def name="extra_javascript()"> <%def name="extra_javascript()">
${parent.extra_javascript()} ${parent.extra_javascript()}
% if not instance.users and request.has_perm('users.create'): % if not use_buefy and not instance.users and request.has_perm('users.create'):
<script type="text/javascript"> <script type="text/javascript">
## TODO: should do this differently for Buefy themes ## TODO: should do this differently for Buefy themes
$(function() { $(function() {
@ -26,12 +26,43 @@
${view_profiles_helper([instance])} ${view_profiles_helper([instance])}
</%def> </%def>
<%def name="render_buefy_form()">
<div class="form">
<tailbone-form v-on:make-user="makeUser"></tailbone-form>
</div>
</%def>
<%def name="modify_this_page_vars()">
${parent.modify_this_page_vars()}
<script type="text/javascript">
TailboneForm.methods.clickMakeUser = function(event) {
this.$emit('make-user')
}
ThisPage.methods.makeUser = function(event) {
if (confirm("Really make a user account for this person?")) {
this.$refs.makeUserForm.submit()
}
}
</script>
</%def>
<%def name="page_content()">
${parent.page_content()}
% if not instance.users and request.has_perm('users.create'):
% if use_buefy:
${h.form(url('people.make_user'), ref='makeUserForm')}
% else:
${h.form(url('people.make_user'), name='make-user-form')}
% endif
${h.csrf_token(request)}
${h.hidden('person_uuid', value=instance.uuid)}
${h.end_form()}
% endif
</%def>
${parent.body()} ${parent.body()}
## TODO: should do this differently for Buefy themes
% if not instance.users and request.has_perm('users.create'):
${h.form(url('people.make_user'), name='make-user-form')}
${h.csrf_token(request)}
${h.hidden('person_uuid', value=instance.uuid)}
${h.end_form()}
% endif

View file

@ -1,5 +1,5 @@
## -*- coding: utf-8; -*- ## -*- coding: utf-8; -*-
<%inherit file="/base.mako" /> <%inherit file="/page.mako" />
<%def name="title()">Find ${model_title_plural} by Permission</%def> <%def name="title()">Find ${model_title_plural} by Permission</%def>
@ -46,144 +46,149 @@
% endif % endif
</%def> </%def>
<%def name="page_content()">
% if use_buefy:
<find-principals :permission-groups="permissionGroups"
:sorted-groups="sortedGroups">
</find-principals>
% else:
## not buefy
${h.form(request.current_route_url(), id='find-by-perm-form')}
${h.csrf_token(request)}
% if not use_buefy: <div class="form">
${h.form(request.current_route_url(), id='find-by-perm-form')} ${self.wtfield(form, 'permission_group')}
${h.csrf_token(request)} ${self.wtfield(form, 'permission')}
<div class="buttons">
<div class="form"> ${h.submit('submit', "Find {}".format(model_title_plural))}
${self.wtfield(form, 'permission_group')} </div>
${self.wtfield(form, 'permission')}
<div class="buttons">
${h.submit('submit', "Find {}".format(model_title_plural))}
</div>
</div>
${h.end_form()}
% if principals is not None:
<div class="grid half">
<br />
<h2>${model_title_plural} with that permission (${len(principals)} total):</h2>
${self.principal_table()}
</div>
% endif
% else:
## use_buefy!
<div id="find-principals-app">
<find-principals :permission-groups="permissionGroups"
:sorted-groups="sortedGroups">
</find-principals>
</div>
<script type="text/x-template" id="find-principals-template">
<div class="app-wrapper">
${h.form(request.current_route_url(), **{'@submit': 'submitForm'})}
${h.csrf_token(request)}
<div class="field-wrapper">
<label for="permission_group">${form['permission_group'].label}</label>
<div class="field">
<b-select name="permission_group"
id="permission_group"
v-model="selectedGroup"
@input="selectGroup">
<option v-for="groupkey in sortedGroups"
:key="groupkey"
:value="groupkey">
{{ permissionGroups[groupkey].label }}
</option>
</b-select>
</div> </div>
</div>
<div class="field-wrapper"> ${h.end_form()}
<label for="permission">${form['permission'].label}</label>
<div class="field"> % if principals is not None:
<b-select name="permission" <div class="grid half">
v-model="selectedPermission"> <br />
<option v-for="perm in groupPermissions" <h2>${model_title_plural} with that permission (${len(principals)} total):</h2>
:key="perm.permkey" ${self.principal_table()}
:value="perm.permkey">
{{ perm.label }}
</option>
</b-select>
</div> </div>
</div> % endif
% endif
</%def>
<div class="buttons"> <%def name="render_this_page_template()">
<b-button type="is-primary" ${parent.render_this_page_template()}
native-type="submit" <script type="text/x-template" id="find-principals-template">
:disabled="formSubmitting"> <div class="app-wrapper">
{{ formButtonText }}
</b-button>
</div>
${h.end_form()} ${h.form(request.current_route_url(), **{'@submit': 'submitForm'})}
${h.csrf_token(request)}
% if principals is not None: <div class="field-wrapper">
<div class="grid half"> <label for="permission_group">${form['permission_group'].label}</label>
<br /> <div class="field">
<h2>${model_title_plural} with that permission (${len(principals)} total):</h2> <b-select name="permission_group"
${self.principal_table()} id="permission_group"
</div> v-model="selectedGroup"
% endif @input="selectGroup">
<option v-for="groupkey in sortedGroups"
:key="groupkey"
:value="groupkey">
{{ permissionGroups[groupkey].label }}
</option>
</b-select>
</div>
</div>
</div><!-- app-wrapper --> <div class="field-wrapper">
</script> <label for="permission">${form['permission'].label}</label>
<div class="field">
<b-select name="permission"
v-model="selectedPermission">
<option v-for="perm in groupPermissions"
:key="perm.permkey"
:value="perm.permkey">
{{ perm.label }}
</option>
</b-select>
</div>
</div>
<script type="text/javascript"> <div class="buttons">
<b-button type="is-primary"
native-type="submit"
:disabled="formSubmitting">
{{ formButtonText }}
</b-button>
</div>
Vue.component('find-principals', { ${h.end_form()}
template: '#find-principals-template',
props: {
permissionGroups: Object,
sortedGroups: Array
},
data() {
return {
groupPermissions: ${json.dumps(buefy_perms.get(selected_group, {}).get('permissions', []))|n},
selectedGroup: ${json.dumps(selected_group)|n},
% if selected_permission:
selectedPermission: ${json.dumps(selected_permission)|n},
% elif selected_group in buefy_perms:
selectedPermission: ${json.dumps(buefy_perms[selected_group]['permissions'][0]['permkey'])|n},
% else:
selectedPermission: null,
% endif
formButtonText: "Find ${model_title_plural}",
formSubmitting: false,
}
},
methods: {
selectGroup(groupkey) { % if principals is not None:
<div class="grid half">
<br />
<h2>Found ${len(principals)} ${model_title_plural} with permission: ${selected_permission}</h2>
${self.principal_table()}
</div>
% endif
// re-populate Permission dropdown, auto-select first option </div><!-- app-wrapper -->
this.groupPermissions = this.permissionGroups[groupkey].permissions </script>
this.selectedPermission = this.groupPermissions[0].permkey </%def>
},
submitForm() { <%def name="modify_this_page_vars()">
this.formSubmitting = true ${parent.modify_this_page_vars()}
this.formButtonText = "Working, please wait..." <script type="text/javascript">
}
}
})
new Vue({ ThisPageData.permissionGroups = ${json.dumps(buefy_perms)|n}
el: '#find-principals-app', ThisPageData.sortedGroups = ${json.dumps(buefy_sorted_groups)|n}
data() {
return {
permissionGroups: ${json.dumps(buefy_perms)|n},
sortedGroups: ${json.dumps(buefy_sorted_groups)|n}
}
}
})
</script> </script>
% endif </%def>
<%def name="make_this_page_component()">
${parent.make_this_page_component()}
<script type="text/javascript">
Vue.component('find-principals', {
template: '#find-principals-template',
props: {
permissionGroups: Object,
sortedGroups: Array
},
data() {
return {
groupPermissions: ${json.dumps(buefy_perms.get(selected_group, {}).get('permissions', []))|n},
selectedGroup: ${json.dumps(selected_group)|n},
% if selected_permission:
selectedPermission: ${json.dumps(selected_permission)|n},
% elif selected_group in buefy_perms:
selectedPermission: ${json.dumps(buefy_perms[selected_group]['permissions'][0]['permkey'])|n},
% else:
selectedPermission: null,
% endif
formButtonText: "Find ${model_title_plural}",
formSubmitting: false,
}
},
methods: {
selectGroup(groupkey) {
// re-populate Permission dropdown, auto-select first option
this.groupPermissions = this.permissionGroups[groupkey].permissions
this.selectedPermission = this.groupPermissions[0].permkey
},
submitForm() {
this.formSubmitting = true
this.formButtonText = "Working, please wait..."
}
}
})
</script>
</%def>
${parent.body()}

View file

@ -1,5 +1,5 @@
## -*- coding: utf-8; -*- ## -*- coding: utf-8; -*-
<%inherit file="/base.mako" /> <%inherit file="/page.mako" />
<%def name="title()">${index_title}</%def> <%def name="title()">${index_title}</%def>
@ -56,19 +56,17 @@
% endif % endif
</%def> </%def>
<%def name="page_content()">
<div style="display: flex; justify-content: space-between;">
% if use_form: % if use_form:
<div class="form-wrapper"> <div class="form-wrapper">
<p>Please select the type of report you wish to generate.</p> <p>Please select the type of report you wish to generate.</p>
<div style="display: flex;"> <div style="display: flex;">
${form.render()|n} ${form.render()|n}
<div id="report-description"></div> <div id="report-description"></div>
</div> </div>
</div><!-- form-wrapper --> </div><!-- form-wrapper -->
% else: % else:
<div> <div>
<p>Please select the type of report you wish to generate.</p> <p>Please select the type of report you wish to generate.</p>
@ -81,9 +79,7 @@
</div> </div>
</div> </div>
% endif % endif
</%def>
<ul id="context-menu">
${self.context_menu_items()}
</ul>
</div> ${parent.body()}

View file

@ -6,17 +6,22 @@
${h.stylesheet_link(request.static_url('tailbone:static/css/perms.css'))} ${h.stylesheet_link(request.static_url('tailbone:static/css/perms.css'))}
</%def> </%def>
<%def name="page_content()">
${parent.page_content()}
<h2>Users</h2>
% if instance is guest_role:
<p>The guest role is implied for all anonymous users, i.e. when not logged in.</p>
% elif instance is authenticated_role:
<p>The authenticated role is implied for all users, but only when logged in.</p>
% elif users:
<p>The following users are assigned to this role:</p>
${users.render_grid()|n}
% else:
<p>There are no users assigned to this role.</p>
% endif
</%def>
${parent.body()} ${parent.body()}
<h2>Users</h2>
% if instance is guest_role:
<p>The guest role is implied for all anonymous users, i.e. when not logged in.</p>
% elif instance is authenticated_role:
<p>The authenticated role is implied for all users, but only when logged in.</p>
% elif users:
<p>The following users are assigned to this role:</p>
${users.render_grid()|n}
% else:
<p>There are no users assigned to this role.</p>
% endif

View file

@ -41,94 +41,96 @@
<email-preview-tools></email-preview-tools> <email-preview-tools></email-preview-tools>
</%def> </%def>
<%def name="render_this_page_template()">
${parent.render_this_page_template()}
<script type="text/x-template" id="email-preview-tools-template">
% if use_buefy: ${h.form(url('email.preview'), **{'@submit': 'submitPreviewForm'})}
${h.csrf_token(request)}
${h.hidden('email_key', value=instance['key'])}
<script type="text/x-template" id="email-preview-tools-template"> <div class="field is-grouped">
${h.form(url('email.preview'), **{'@submit': 'submitPreviewForm'})} <div class="control">
${h.csrf_token(request)} % if email.get_template('html'):
${h.hidden('email_key', value=instance['key'])}
<div class="field is-grouped">
<div class="control">
% if email.get_template('html'):
<a class="button is-primary"
href="${url('email.preview')}?key=${instance['key']}&type=html"
target="_blank">
Preview HTML
</a>
% else:
<button class="button is-primary"
type="button"
title="There is no HTML template on file for this email."
disabled>
Preview HTML
</button>
% endif
</div>
<div class="control">
% if email.get_template('txt'):
<a class="button is-primary" <a class="button is-primary"
href="${url('email.preview')}?key=${instance['key']}&type=txt" href="${url('email.preview')}?key=${instance['key']}&type=html"
target="_blank"> target="_blank">
Preview TXT Preview HTML
</a> </a>
% else: % else:
<button class="button is-primary" <button class="button is-primary"
type="button" type="button"
title="There is no TXT template on file for this email." title="There is no HTML template on file for this email."
disabled> disabled>
Preview TXT Preview HTML
</button> </button>
% endif % endif
</div> </div>
<div class="control"> <div class="control">
or % if email.get_template('txt'):
</div> <a class="button is-primary"
href="${url('email.preview')}?key=${instance['key']}&type=txt"
target="_blank">
Preview TXT
</a>
% else:
<button class="button is-primary"
type="button"
title="There is no TXT template on file for this email."
disabled>
Preview TXT
</button>
% endif
</div>
<div class="control"> <div class="control">
<input name="recipient" type="email" class="input" value="${request.user.email_address or ''}" /> or
</div> </div>
<div class="control"> <div class="control">
<b-button type="is-primary" <input name="recipient" type="email" class="input" value="${request.user.email_address or ''}" />
native-type="submit" </div>
:disabled="previewFormSubmitting">
{{ previewFormButtonText }}
</b-button>
</div>
</div><!-- field --> <div class="control">
<b-button type="is-primary"
native-type="submit"
:disabled="previewFormSubmitting">
{{ previewFormButtonText }}
</b-button>
</div>
${h.end_form()} </div><!-- field -->
</script>
<script type="text/javascript"> ${h.end_form()}
</script>
</%def>
const EmailPreviewTools = { <%def name="make_this_page_component()">
template: '#email-preview-tools-template', ${parent.make_this_page_component()}
data() { <script type="text/javascript">
return {
previewFormButtonText: "Send Preview Email",
previewFormSubmitting: false,
}
},
methods: {
submitPreviewForm() {
this.previewFormSubmitting = true
this.previewFormButtonText = "Working, please wait..."
}
}
}
Vue.component('email-preview-tools', EmailPreviewTools) const EmailPreviewTools = {
template: '#email-preview-tools-template',
data() {
return {
previewFormButtonText: "Send Preview Email",
previewFormSubmitting: false,
}
},
methods: {
submitPreviewForm() {
this.previewFormSubmitting = true
this.previewFormButtonText = "Working, please wait..."
}
}
}
</script> Vue.component('email-preview-tools', EmailPreviewTools)
</script>
</%def>
% endif
${parent.body()} ${parent.body()}

View file

@ -1,8 +1,8 @@
## -*- coding: utf-8 -*- ## -*- coding: utf-8 -*-
<%inherit file="/master/create.mako" /> <%inherit file="/master/create.mako" />
<%def name="head_tags()"> <%def name="extra_javascript()">
${parent.head_tags()} ${parent.extra_javascript()}
<script type="text/javascript"> <script type="text/javascript">
$(function() { $(function() {

View file

@ -146,8 +146,8 @@
% endif % endif
</%def> </%def>
<%def name="modify_this_page()"> <%def name="modify_this_page_vars()">
${parent.modify_this_page()} ${parent.modify_this_page_vars()}
<script type="text/javascript"> <script type="text/javascript">
ThisPage.data = function() { return { ThisPage.data = function() { return {

View file

@ -258,7 +258,20 @@
% endfor % endfor
% endif % endif
## ##############################
## whole page
## ##############################
${self.body()} ${self.body()}
<div id="whole-page-app">
<whole-page></whole-page>
</div>
${self.render_whole_page_template()}
${self.make_whole_page_component()}
${self.make_whole_page_app()}
</section> </section>
## Footer ## Footer
@ -411,6 +424,59 @@
<%def name="head_tags()"></%def> <%def name="head_tags()"></%def>
<%def name="render_whole_page_template()">
<script type="text/x-template" id="whole-page-template">
<div>
<this-page></this-page>
</div>
</script>
</%def>
<%def name="declare_whole_page_vars()">
<script type="text/javascript">
let WholePage = {
template: '#whole-page-template',
methods: {}
}
let WholePageData = {}
</script>
</%def>
<%def name="modify_whole_page_vars()">
## NOTE: if you override this, must use <script> tags
</%def>
<%def name="finalize_whole_page_vars()">
## NOTE: if you override this, must use <script> tags
</%def>
<%def name="make_whole_page_component()">
${self.declare_whole_page_vars()}
${self.modify_whole_page_vars()}
${self.finalize_whole_page_vars()}
<script type="text/javascript">
WholePage.data = function() { return WholePageData }
Vue.component('whole-page', WholePage)
</script>
</%def>
<%def name="make_whole_page_app()">
<script type="text/javascript">
new Vue({
el: '#whole-page-app'
})
</script>
</%def>
<%def name="wtfield(form, name, **kwargs)"> <%def name="wtfield(form, name, **kwargs)">
<div class="field-wrapper${' error' if form[name].errors else ''}"> <div class="field-wrapper${' error' if form[name].errors else ''}">
<label for="${name}">${form[name].label}</label> <label for="${name}">${form[name].label}</label>

View file

@ -67,8 +67,8 @@
% endif % endif
</%def> </%def>
<%def name="modify_this_page()"> <%def name="modify_this_page_vars()">
${parent.modify_this_page()} ${parent.modify_this_page_vars()}
<script type="text/javascript"> <script type="text/javascript">
TailboneFormData.showingPackages = 'diffs' TailboneFormData.showingPackages = 'diffs'

View file

@ -38,7 +38,6 @@ from rattail.bouncer.config import get_profile_keys
from pyramid.response import FileResponse from pyramid.response import FileResponse
from webhelpers2.html import HTML, tags from webhelpers2.html import HTML, tags
from tailbone import grids
from tailbone.views import MasterView from tailbone.views import MasterView
@ -76,18 +75,17 @@ class EmailBouncesView(MasterView):
def configure_grid(self, g): def configure_grid(self, g):
super(EmailBouncesView, self).configure_grid(g) super(EmailBouncesView, self).configure_grid(g)
g.joiners['processed_by'] = lambda q: q.outerjoin(model.User) g.filters['config_key'].set_choices(self.handler_options)
g.filters['config_key'].default_active = True g.filters['config_key'].default_active = True
g.filters['config_key'].default_verb = 'equal' g.filters['config_key'].default_verb = 'equal'
g.filters['config_key'].set_value_renderer(grids.filters.ChoiceValueRenderer(self.handler_options)) g.joiners['processed_by'] = lambda q: q.outerjoin(model.User)
g.filters['processed'].default_active = True g.filters['processed'].default_active = True
g.filters['processed'].default_verb = 'is_null' g.filters['processed'].default_verb = 'is_null'
g.filters['processed_by'] = g.make_filter('processed_by', model.User.username) g.filters['processed_by'] = g.make_filter('processed_by', model.User.username)
g.sorters['processed_by'] = g.make_sorter(model.User.username) g.sorters['processed_by'] = g.make_sorter(model.User.username)
g.set_sort_defaults('bounced', 'desc') g.set_sort_defaults('bounced', 'desc')
g.set_label('config_key', "Source")
g.set_label('bounce_recipient_address', "Bounced To") g.set_label('bounce_recipient_address', "Bounced To")
g.set_label('intended_recipient_address', "Intended For") g.set_label('intended_recipient_address', "Intended For")

View file

@ -217,8 +217,8 @@ class PeopleView(MasterView):
return HTML.tag('ul', c=items) return HTML.tag('ul', c=items)
elif self.viewing and self.request.has_perm('users.create'): elif self.viewing and self.request.has_perm('users.create'):
if use_buefy: if use_buefy:
return HTML.tag('button', type='button', class_='button is-primary', return HTML.tag('b-button', type='is-primary', c="Make User",
id='make-user', c="Make User") **{'@click': 'clickMakeUser()'})
else: else:
return HTML.tag('button', type='button', id='make-user', c="Make User") return HTML.tag('button', type='button', id='make-user', c="Make User")
else: else: