Refactory Buefy templates to use WholePage and ThisPage components
plus add `GridFilter.set_choices()` method
This commit is contained in:
		
							parent
							
								
									c64fca852c
								
							
						
					
					
						commit
						1bb0330ab5
					
				
					 36 changed files with 806 additions and 613 deletions
				
			
		| 
						 | 
				
			
			@ -1003,7 +1003,10 @@ class Grid(object):
 | 
			
		|||
 | 
			
		||||
            choices = []
 | 
			
		||||
            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])
 | 
			
		||||
                choice_labels = self.enums[filtr.key]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -149,6 +149,7 @@ class GridFilter(object):
 | 
			
		|||
 | 
			
		||||
    value_renderer_factory = DefaultValueRenderer
 | 
			
		||||
    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,
 | 
			
		||||
                 default_active=False, default_verb=None, default_value=None,
 | 
			
		||||
| 
						 | 
				
			
			@ -187,6 +188,27 @@ class GridFilter(object):
 | 
			
		|||
            return verbs
 | 
			
		||||
        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):
 | 
			
		||||
        """
 | 
			
		||||
        Set the value renderer for the filter, post-construction.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -174,9 +174,3 @@ let TailboneGrid = {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
let GridPage = {
 | 
			
		||||
    template: '#grid-page-template',
 | 
			
		||||
    methods: {}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +1,19 @@
 | 
			
		|||
## -*- coding: utf-8 -*-
 | 
			
		||||
<%inherit file="/base.mako" />
 | 
			
		||||
## -*- coding: utf-8; -*-
 | 
			
		||||
<%inherit file="/page.mako" />
 | 
			
		||||
<%namespace name="base_meta" file="/base_meta.mako" />
 | 
			
		||||
 | 
			
		||||
<%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():
 | 
			
		||||
    <h3>${name} ${version}</h3>
 | 
			
		||||
% endfor
 | 
			
		||||
  % for name, version in packages.items():
 | 
			
		||||
      <h3>${name} ${version}</h3>
 | 
			
		||||
  % endfor
 | 
			
		||||
 | 
			
		||||
<br />
 | 
			
		||||
<p>Please see <a href="https://rattailproject.org/">rattailproject.org</a> for more info.</p>
 | 
			
		||||
  <br />
 | 
			
		||||
  <p>Please see <a href="https://rattailproject.org/">rattailproject.org</a> for more info.</p>
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
${parent.body()}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
## -*- coding: utf-8; -*-
 | 
			
		||||
<%inherit file="/base.mako" />
 | 
			
		||||
<%inherit file="/page.mako" />
 | 
			
		||||
 | 
			
		||||
<%def name="title()">App Settings</%def>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -33,150 +33,164 @@
 | 
			
		|||
  % endif
 | 
			
		||||
</%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:
 | 
			
		||||
    <script type="text/x-template" id="app-settings-template">
 | 
			
		||||
<%def name="page_content()">
 | 
			
		||||
  <app-settings :groups="groups" :showing-group="showingGroup"></app-settings>
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
      <div class="form">
 | 
			
		||||
        ${h.form(form.action_url, id=dform.formid, method='post', **{'@submit': 'submitForm'})}
 | 
			
		||||
        ${h.csrf_token(request)}
 | 
			
		||||
<%def name="render_this_page_template()">
 | 
			
		||||
  ${parent.render_this_page_template()}
 | 
			
		||||
  <script type="text/x-template" id="app-settings-template">
 | 
			
		||||
 | 
			
		||||
        % if dform.error:
 | 
			
		||||
            <div class="error-messages">
 | 
			
		||||
              <div class="ui-state-error ui-corner-all">
 | 
			
		||||
                <span style="float: left; margin-right: .3em;" class="ui-icon ui-icon-alert"></span>
 | 
			
		||||
                Please see errors below.
 | 
			
		||||
              </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 class="form">
 | 
			
		||||
      ${h.form(form.action_url, id=dform.formid, method='post', **{'@submit': 'submitForm'})}
 | 
			
		||||
      ${h.csrf_token(request)}
 | 
			
		||||
 | 
			
		||||
      % if dform.error:
 | 
			
		||||
          <div class="error-messages">
 | 
			
		||||
            <div class="ui-state-error ui-corner-all">
 | 
			
		||||
              <span style="float: left; margin-right: .3em;" class="ui-icon ui-icon-alert"></span>
 | 
			
		||||
              Please see errors below.
 | 
			
		||||
            </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>
 | 
			
		||||
        % 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>
 | 
			
		||||
      % endif
 | 
			
		||||
 | 
			
		||||
          <div v-for="group in groups"
 | 
			
		||||
               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 class="app-wrapper">
 | 
			
		||||
 | 
			
		||||
                <div v-if="setting.error" class="field-error">
 | 
			
		||||
                  <span v-for="msg in setting.error_messages"
 | 
			
		||||
                        class="error-msg">
 | 
			
		||||
                    {{ msg }}
 | 
			
		||||
                  </span>
 | 
			
		||||
                </div>
 | 
			
		||||
        <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 class="field-row">
 | 
			
		||||
                  <label :for="setting.field_name">{{ setting.label }}</label>
 | 
			
		||||
                  <div class="field">
 | 
			
		||||
        <div v-for="group in groups"
 | 
			
		||||
             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' : '')">
 | 
			
		||||
 | 
			
		||||
                    <input v-if="setting.data_type == 'bool'"
 | 
			
		||||
                           type="checkbox"
 | 
			
		||||
              <div v-if="setting.error" class="field-error">
 | 
			
		||||
                <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"
 | 
			
		||||
                           :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"
 | 
			
		||||
                             :id="setting.field_name"
 | 
			
		||||
                             v-model="setting.value" />
 | 
			
		||||
                  </div>
 | 
			
		||||
                           v-model="setting.value" />
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
 | 
			
		||||
                <span v-if="setting.helptext" class="instructions">
 | 
			
		||||
                  {{ setting.helptext }}
 | 
			
		||||
                </span>
 | 
			
		||||
              <span v-if="setting.helptext" class="instructions">
 | 
			
		||||
                {{ setting.helptext }}
 | 
			
		||||
              </span>
 | 
			
		||||
 | 
			
		||||
              </div><!-- field-wrapper -->
 | 
			
		||||
            </div><!-- card-content -->
 | 
			
		||||
          </div><!-- card -->
 | 
			
		||||
            </div><!-- field-wrapper -->
 | 
			
		||||
          </div><!-- card-content -->
 | 
			
		||||
        </div><!-- card -->
 | 
			
		||||
 | 
			
		||||
          <div class="buttons">
 | 
			
		||||
            <b-button type="is-primary"
 | 
			
		||||
                      native-type="submit"
 | 
			
		||||
                      :disabled="formSubmitting">
 | 
			
		||||
              {{ formButtonText }}
 | 
			
		||||
            </b-button>
 | 
			
		||||
            <once-button tag="a" href="${form.cancel_url}"
 | 
			
		||||
                         text="Cancel">
 | 
			
		||||
            </once-button>
 | 
			
		||||
          </div>
 | 
			
		||||
        <div class="buttons">
 | 
			
		||||
          <b-button type="is-primary"
 | 
			
		||||
                    native-type="submit"
 | 
			
		||||
                    :disabled="formSubmitting">
 | 
			
		||||
            {{ formButtonText }}
 | 
			
		||||
          </b-button>
 | 
			
		||||
          <once-button tag="a" href="${form.cancel_url}"
 | 
			
		||||
                       text="Cancel">
 | 
			
		||||
          </once-button>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        </div><!-- app-wrapper -->
 | 
			
		||||
      </div><!-- app-wrapper -->
 | 
			
		||||
 | 
			
		||||
        ${h.end_form()}
 | 
			
		||||
      </div>
 | 
			
		||||
    </script>
 | 
			
		||||
 | 
			
		||||
    <div id="app-settings-app">
 | 
			
		||||
      <app-settings :groups="groups" :showing-group="showingGroup"></app-settings>
 | 
			
		||||
      ${h.end_form()}
 | 
			
		||||
    </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', {
 | 
			
		||||
          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..."
 | 
			
		||||
              }
 | 
			
		||||
          }
 | 
			
		||||
      })
 | 
			
		||||
    ThisPageData.groups = ${json.dumps(buefy_data)|n}
 | 
			
		||||
    ThisPageData.showingGroup = ${json.dumps(current_group or '')|n}
 | 
			
		||||
 | 
			
		||||
      new Vue({
 | 
			
		||||
          el: '#app-settings-app',
 | 
			
		||||
          data() {
 | 
			
		||||
              return {
 | 
			
		||||
                  groups: ${json.dumps(buefy_data)|n},
 | 
			
		||||
                  showingGroup: ${json.dumps(current_group or '')|n}
 | 
			
		||||
              }
 | 
			
		||||
          }
 | 
			
		||||
      })
 | 
			
		||||
  </script>
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
    </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:
 | 
			
		||||
## legacy / not buefy
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,19 +107,15 @@
 | 
			
		|||
  % endif
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="modify_tailbone_grid()">
 | 
			
		||||
  ${parent.modify_tailbone_grid()}
 | 
			
		||||
<%def name="modify_this_page_vars()">
 | 
			
		||||
  ${parent.modify_this_page_vars()}
 | 
			
		||||
  % if master.results_executable and request.has_perm('{}.execute_multiple'.format(permission_prefix)):
 | 
			
		||||
      <script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
        TailboneForm.data = function() { return TailboneFormData }
 | 
			
		||||
 | 
			
		||||
        TailboneForm.methods.submit = function() {
 | 
			
		||||
            this.$refs.actualForm.submit()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Vue.component('tailbone-form', TailboneForm)
 | 
			
		||||
 | 
			
		||||
        TailboneGridData.hasExecutionOptions = ${json.dumps(master.has_execution_options(batch))|n}
 | 
			
		||||
        TailboneGridData.showExecutionOptions = false
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -151,12 +147,26 @@
 | 
			
		|||
  % endif
 | 
			
		||||
</%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()}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -187,16 +187,16 @@
 | 
			
		|||
  % endif
 | 
			
		||||
</%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)):
 | 
			
		||||
      ## TODO: stop using |n filter
 | 
			
		||||
      ${execute_form.render_deform(buttons=capture(execute_submit_button), form_kwargs={'@submit': 'submitExecuteForm'})|n}
 | 
			
		||||
  % endif
 | 
			
		||||
  ${parent.render_this_page_buefy()}
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="modify_this_page()">
 | 
			
		||||
  ${parent.modify_this_page()}
 | 
			
		||||
<%def name="modify_this_page_vars()">
 | 
			
		||||
  ${parent.modify_this_page_vars()}
 | 
			
		||||
  % if not batch.executed and request.has_perm('{}.execute'.format(permission_prefix)):
 | 
			
		||||
      <script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -216,8 +216,8 @@
 | 
			
		|||
  % endif
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="finalize_page_components()">
 | 
			
		||||
  ${parent.finalize_page_components()}
 | 
			
		||||
<%def name="finalize_this_page_vars()">
 | 
			
		||||
  ${parent.finalize_this_page_vars()}
 | 
			
		||||
  % if not batch.executed and request.has_perm('{}.execute'.format(permission_prefix)):
 | 
			
		||||
      <script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,13 @@
 | 
			
		|||
## -*- coding: utf-8; -*-
 | 
			
		||||
<%inherit file="/base.mako" />
 | 
			
		||||
<%inherit file="/page.mako" />
 | 
			
		||||
 | 
			
		||||
<%def name="title()">Change Password</%def>
 | 
			
		||||
 | 
			
		||||
<div class="form">
 | 
			
		||||
  ${form.render_deform()|n}
 | 
			
		||||
</div>
 | 
			
		||||
<%def name="page_content()">
 | 
			
		||||
  <div class="form">
 | 
			
		||||
    ${form.render_deform()|n}
 | 
			
		||||
  </div>
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
${parent.body()}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,8 +42,8 @@
 | 
			
		|||
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="modify_tailbone_grid()">
 | 
			
		||||
  ${parent.modify_tailbone_grid()}
 | 
			
		||||
<%def name="modify_this_page_vars()">
 | 
			
		||||
  ${parent.modify_this_page_vars()}
 | 
			
		||||
  <script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
    % if request.has_perm('datasync.restart'):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,18 @@
 | 
			
		|||
## -*- coding: utf-8 -*-
 | 
			
		||||
## -*- coding: utf-8; -*-
 | 
			
		||||
<%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()}
 | 
			
		||||
 | 
			
		||||
<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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,16 +1,10 @@
 | 
			
		|||
## -*- coding: utf-8 -*-
 | 
			
		||||
## -*- coding: utf-8; -*-
 | 
			
		||||
<%inherit file="/master/view.mako" />
 | 
			
		||||
 | 
			
		||||
<%def name="head_tags()">
 | 
			
		||||
  ${parent.head_tags()}
 | 
			
		||||
  <style type="text/css">
 | 
			
		||||
    #message {
 | 
			
		||||
        border: 1px solid #000000;
 | 
			
		||||
        height: 400px;
 | 
			
		||||
        overflow: auto;
 | 
			
		||||
        padding: 4px;
 | 
			
		||||
    }
 | 
			
		||||
  </style>
 | 
			
		||||
## TODO: this page still uses jQuery but should use Vue.js
 | 
			
		||||
 | 
			
		||||
<%def name="extra_javascript()">
 | 
			
		||||
  ${parent.extra_javascript()}
 | 
			
		||||
  <script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
    function autosize_message(scrolldown) {
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +28,18 @@
 | 
			
		|||
  </script>
 | 
			
		||||
</%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()">
 | 
			
		||||
  ${parent.context_menu_items()}
 | 
			
		||||
  % if not bounce.processed and request.has_perm('emailbounces.process'):
 | 
			
		||||
| 
						 | 
				
			
			@ -43,8 +49,12 @@
 | 
			
		|||
  % endif
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
${parent.body()}
 | 
			
		||||
<%def name="page_content()">
 | 
			
		||||
  ${parent.page_content()}
 | 
			
		||||
  <pre id="message">
 | 
			
		||||
  ${message}
 | 
			
		||||
  </pre>
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<pre id="message">
 | 
			
		||||
${message}
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
${parent.body()}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,15 +45,15 @@
 | 
			
		|||
  </div>
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="render_this_page_buefy()">
 | 
			
		||||
<%def name="render_this_page_template()">
 | 
			
		||||
  % if form is not Underined:
 | 
			
		||||
      ${self.render_form()}
 | 
			
		||||
  % endif
 | 
			
		||||
  ${parent.render_this_page_buefy()}
 | 
			
		||||
  ${parent.render_this_page_template()}
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="finalize_page_components()">
 | 
			
		||||
  ${parent.finalize_page_components()}
 | 
			
		||||
<%def name="finalize_this_page_vars()">
 | 
			
		||||
  ${parent.finalize_this_page_vars()}
 | 
			
		||||
  % if form is not Undefined:
 | 
			
		||||
      <script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
## -*- coding: utf-8; -*-
 | 
			
		||||
<%inherit file="/base.mako" />
 | 
			
		||||
<%inherit file="/page.mako" />
 | 
			
		||||
<%namespace name="base_meta" file="/base_meta.mako" />
 | 
			
		||||
 | 
			
		||||
<%def name="title()">Home</%def>
 | 
			
		||||
| 
						 | 
				
			
			@ -16,7 +16,12 @@
 | 
			
		|||
  </style>
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<div class="logo">
 | 
			
		||||
  ${h.image(image_url, "{} logo".format(capture(base_meta.app_title)), id='logo', width=500)}
 | 
			
		||||
  <h1>Welcome to ${base_meta.app_title()}</h1>
 | 
			
		||||
</div>
 | 
			
		||||
<%def name="page_content()">
 | 
			
		||||
  <div class="logo">
 | 
			
		||||
    ${h.image(image_url, "{} logo".format(capture(base_meta.app_title)), id='logo', width=500)}
 | 
			
		||||
    <h1>Welcome to ${base_meta.app_title()}</h1>
 | 
			
		||||
  </div>
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
${parent.body()}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,19 +24,24 @@
 | 
			
		|||
  % endif
 | 
			
		||||
</%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()}
 | 
			
		||||
 | 
			
		||||
<% 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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
## -*- coding: utf-8; -*-
 | 
			
		||||
<%inherit file="/base.mako" />
 | 
			
		||||
<%inherit file="/page.mako" />
 | 
			
		||||
<%namespace name="base_meta" file="/base_meta.mako" />
 | 
			
		||||
 | 
			
		||||
<%def name="title()">Login</%def>
 | 
			
		||||
| 
						 | 
				
			
			@ -24,12 +24,17 @@
 | 
			
		|||
  </div>
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
${self.logo()}
 | 
			
		||||
<%def name="page_content()">
 | 
			
		||||
  ${self.logo()}
 | 
			
		||||
 | 
			
		||||
${self.login_form()}
 | 
			
		||||
  ${self.login_form()}
 | 
			
		||||
 | 
			
		||||
% if request.rattail_config.demo():
 | 
			
		||||
    <p class="tips">
 | 
			
		||||
      Login with <strong>chuck / admin</strong> for full demo access
 | 
			
		||||
    </p>
 | 
			
		||||
% endif
 | 
			
		||||
  % if request.rattail_config.demo():
 | 
			
		||||
      <p class="tips">
 | 
			
		||||
        Login with <strong>chuck / admin</strong> for full demo access
 | 
			
		||||
      </p>
 | 
			
		||||
  % endif
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
${parent.body()}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,8 +52,8 @@
 | 
			
		|||
  ${h.end_form()}
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="modify_this_page()">
 | 
			
		||||
  ${parent.modify_this_page()}
 | 
			
		||||
<%def name="modify_this_page_vars()">
 | 
			
		||||
  ${parent.modify_this_page_vars()}
 | 
			
		||||
  <script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
    TailboneFormData.formSubmitting = false
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,8 +68,8 @@
 | 
			
		|||
  ${h.end_form()}
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="modify_this_page()">
 | 
			
		||||
  ${parent.modify_this_page()}
 | 
			
		||||
<%def name="modify_this_page_vars()">
 | 
			
		||||
  ${parent.modify_this_page_vars()}
 | 
			
		||||
  <script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
    TailboneFormData.formSubmitting = false
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,8 +26,8 @@
 | 
			
		|||
  % endif
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="modify_this_page()">
 | 
			
		||||
  ${parent.modify_this_page()}
 | 
			
		||||
<%def name="modify_this_page_vars()">
 | 
			
		||||
  ${parent.modify_this_page_vars()}
 | 
			
		||||
  % if master.deletable and instance_deletable and request.has_perm('{}.delete'.format(permission_prefix)) and master.delete_confirm == 'simple':
 | 
			
		||||
      <script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@
 | 
			
		|||
## 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>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -215,9 +215,23 @@
 | 
			
		|||
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="modify_tailbone_grid()">
 | 
			
		||||
  <script type="text/javascript">
 | 
			
		||||
<%def name="page_content()">
 | 
			
		||||
  <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)):
 | 
			
		||||
        TailboneGridData.mergeFormButtonText = "Merge 2 ${model_title_plural}"
 | 
			
		||||
        TailboneGridData.mergeFormSubmitting = false
 | 
			
		||||
| 
						 | 
				
			
			@ -226,65 +240,43 @@
 | 
			
		|||
            this.mergeFormButtonText = "Working, please wait..."
 | 
			
		||||
        }
 | 
			
		||||
    % 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':
 | 
			
		||||
 | 
			
		||||
        GridPage.methods.deleteObject = function(url) {
 | 
			
		||||
 | 
			
		||||
        ThisPage.methods.deleteObject = function(url) {
 | 
			
		||||
            if (confirm("Are you sure you wish to delete this ${model_title}?")) {
 | 
			
		||||
                let form = this.$refs.deleteObjectForm
 | 
			
		||||
                form.action = url
 | 
			
		||||
                form.submit()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    % 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({
 | 
			
		||||
        el: '#grid-page-app'
 | 
			
		||||
    })
 | 
			
		||||
    TailboneGrid.data = function() { return TailboneGridData }
 | 
			
		||||
 | 
			
		||||
    Vue.component('tailbone-grid', TailboneGrid)
 | 
			
		||||
 | 
			
		||||
  </script>
 | 
			
		||||
</%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:
 | 
			
		||||
    ## TODO: stop using |n filter
 | 
			
		||||
    ${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()}
 | 
			
		||||
    ${parent.body()}
 | 
			
		||||
 | 
			
		||||
% else:
 | 
			
		||||
    ## no buefy, so do the traditional thing
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -154,75 +154,80 @@ ${h.end_form()}
 | 
			
		|||
% endif
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="render_this_page_template()">
 | 
			
		||||
  ${parent.render_this_page_template()}
 | 
			
		||||
 | 
			
		||||
% if use_buefy:
 | 
			
		||||
<script type="text/x-template" id="merge-buttons-template">
 | 
			
		||||
  <div class="level" style="margin-top: 2em;">
 | 
			
		||||
    <div class="level-left">
 | 
			
		||||
  <script type="text/x-template" id="merge-buttons-template">
 | 
			
		||||
    <div class="level" style="margin-top: 2em;">
 | 
			
		||||
      <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 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>
 | 
			
		||||
</script>
 | 
			
		||||
  </script>
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<script type="text/javascript">
 | 
			
		||||
<%def name="make_this_page_component()">
 | 
			
		||||
  ${parent.make_this_page_component()}
 | 
			
		||||
  <script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
  const MergeButtons = {
 | 
			
		||||
      template: '#merge-buttons-template',
 | 
			
		||||
      data() {
 | 
			
		||||
          return {
 | 
			
		||||
              swapFormButtonText: "Swap which ${model_title} is kept/removed",
 | 
			
		||||
              swapFormSubmitting: false,
 | 
			
		||||
              mergeFormButtonText: "Yes, perform this merge",
 | 
			
		||||
              mergeFormSubmitting: false,
 | 
			
		||||
          }
 | 
			
		||||
      },
 | 
			
		||||
      methods: {
 | 
			
		||||
          submitSwapForm() {
 | 
			
		||||
              this.swapFormSubmitting = true
 | 
			
		||||
              this.swapFormButtonText = "Swapping, please wait..."
 | 
			
		||||
          },
 | 
			
		||||
          submitMergeForm() {
 | 
			
		||||
              this.mergeFormSubmitting = true
 | 
			
		||||
              this.mergeFormButtonText = "Merging, please wait..."
 | 
			
		||||
          },
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
    const MergeButtons = {
 | 
			
		||||
        template: '#merge-buttons-template',
 | 
			
		||||
        data() {
 | 
			
		||||
            return {
 | 
			
		||||
                swapFormButtonText: "Swap which ${model_title} is kept/removed",
 | 
			
		||||
                swapFormSubmitting: false,
 | 
			
		||||
                mergeFormButtonText: "Yes, perform this merge",
 | 
			
		||||
                mergeFormSubmitting: false,
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        methods: {
 | 
			
		||||
            submitSwapForm() {
 | 
			
		||||
                this.swapFormSubmitting = true
 | 
			
		||||
                this.swapFormButtonText = "Swapping, please wait..."
 | 
			
		||||
            },
 | 
			
		||||
            submitMergeForm() {
 | 
			
		||||
                this.mergeFormSubmitting = true
 | 
			
		||||
                this.mergeFormButtonText = "Merging, please wait..."
 | 
			
		||||
            },
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  Vue.component('merge-buttons', MergeButtons)
 | 
			
		||||
    Vue.component('merge-buttons', MergeButtons)
 | 
			
		||||
 | 
			
		||||
  </script>
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
% endif
 | 
			
		||||
 | 
			
		||||
${parent.body()}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,9 @@
 | 
			
		|||
## 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>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -21,4 +23,9 @@
 | 
			
		|||
  History for ${instance_title}
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
${grid.render_complete()|n}
 | 
			
		||||
<%def name="page_content()">
 | 
			
		||||
  ${grid.render_complete()|n}
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
${parent.body()}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -93,15 +93,15 @@
 | 
			
		|||
  % endif
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="render_this_page_buefy()">
 | 
			
		||||
<%def name="render_this_page_template()">
 | 
			
		||||
  % if master.has_rows:
 | 
			
		||||
      ## TODO: stop using |n filter
 | 
			
		||||
      ${rows_grid.render_buefy(allow_save_defaults=False, tools=capture(self.render_row_grid_tools))|n}
 | 
			
		||||
  % endif
 | 
			
		||||
  ${parent.render_this_page_buefy()}
 | 
			
		||||
  ${parent.render_this_page_template()}
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="make_this_page_app()">
 | 
			
		||||
<%def name="make_this_page_component()">
 | 
			
		||||
  <script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
    TailboneGrid.data = function() { return TailboneGridData }
 | 
			
		||||
| 
						 | 
				
			
			@ -109,7 +109,7 @@
 | 
			
		|||
    Vue.component('tailbone-grid', TailboneGrid)
 | 
			
		||||
 | 
			
		||||
  </script>
 | 
			
		||||
  ${parent.make_this_page_app()}
 | 
			
		||||
  ${parent.make_this_page_component()}
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
## -*- coding: utf-8; -*-
 | 
			
		||||
<%inherit file="/base.mako" />
 | 
			
		||||
<%inherit file="/page.mako" />
 | 
			
		||||
 | 
			
		||||
<%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
 | 
			
		||||
 | 
			
		||||
<div class="form-wrapper">
 | 
			
		||||
| 
						 | 
				
			
			@ -97,3 +98,7 @@
 | 
			
		|||
    % endif
 | 
			
		||||
 | 
			
		||||
% endfor
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
${parent.body()}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
## -*- coding: utf-8 -*-
 | 
			
		||||
## -*- coding: utf-8; -*-
 | 
			
		||||
<%inherit file="/master/view.mako" />
 | 
			
		||||
 | 
			
		||||
<%def name="extra_javascript()">
 | 
			
		||||
| 
						 | 
				
			
			@ -87,12 +87,17 @@
 | 
			
		|||
  ${instance.body}
 | 
			
		||||
</%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()}
 | 
			
		||||
 | 
			
		||||
${self.message_tools()}
 | 
			
		||||
 | 
			
		||||
<div class="message-body">
 | 
			
		||||
  ${self.message_body()}
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
${self.message_tools()}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,9 +6,9 @@
 | 
			
		|||
<%def name="page_content()"></%def>
 | 
			
		||||
 | 
			
		||||
<%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()}
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -19,23 +19,15 @@
 | 
			
		|||
  </div>
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="render_this_page_buefy()">
 | 
			
		||||
<%def name="render_this_page_template()">
 | 
			
		||||
  <script type="text/x-template" id="this-page-template">
 | 
			
		||||
    <div>
 | 
			
		||||
      ${self.render_this_page()}
 | 
			
		||||
    </div>
 | 
			
		||||
  </script>
 | 
			
		||||
 | 
			
		||||
  <div id="this-page-app">
 | 
			
		||||
    <this-page></this-page>
 | 
			
		||||
  </div>
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="modify_this_page()">
 | 
			
		||||
  ## NOTE: if you override this, must use <script> tags
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="declare_page_vars()">
 | 
			
		||||
<%def name="declare_this_page_vars()">
 | 
			
		||||
  <script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
    let ThisPage = {
 | 
			
		||||
| 
						 | 
				
			
			@ -48,31 +40,32 @@
 | 
			
		|||
  </script>
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="finalize_page_components()">
 | 
			
		||||
<%def name="modify_this_page_vars()">
 | 
			
		||||
  ## NOTE: if you override this, must use <script> tags
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="make_this_page_app()">
 | 
			
		||||
  ${self.declare_page_vars()}
 | 
			
		||||
  ${self.modify_this_page()}
 | 
			
		||||
  ${self.finalize_page_components()}
 | 
			
		||||
<%def name="finalize_this_page_vars()">
 | 
			
		||||
  ## NOTE: if you override this, must use <script> tags
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%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">
 | 
			
		||||
 | 
			
		||||
    ThisPage.data = function() { return ThisPageData }
 | 
			
		||||
 | 
			
		||||
    Vue.component('this-page', ThisPage)
 | 
			
		||||
 | 
			
		||||
    new Vue({
 | 
			
		||||
        el: '#this-page-app'
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
  </script>
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
% if use_buefy:
 | 
			
		||||
    ${self.render_this_page_buefy()}
 | 
			
		||||
    ${self.make_this_page_app()}
 | 
			
		||||
    ${self.render_this_page_template()}
 | 
			
		||||
    ${self.make_this_page_component()}
 | 
			
		||||
% else:
 | 
			
		||||
    ${self.render_this_page()}
 | 
			
		||||
% endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@
 | 
			
		|||
 | 
			
		||||
<%def name="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">
 | 
			
		||||
        ## TODO: should do this differently for Buefy themes
 | 
			
		||||
        $(function() {
 | 
			
		||||
| 
						 | 
				
			
			@ -26,12 +26,43 @@
 | 
			
		|||
  ${view_profiles_helper([instance])}
 | 
			
		||||
</%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()}
 | 
			
		||||
 | 
			
		||||
## 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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
## -*- coding: utf-8; -*-
 | 
			
		||||
<%inherit file="/base.mako" />
 | 
			
		||||
<%inherit file="/page.mako" />
 | 
			
		||||
 | 
			
		||||
<%def name="title()">Find ${model_title_plural} by Permission</%def>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -46,144 +46,149 @@
 | 
			
		|||
  % endif
 | 
			
		||||
</%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:
 | 
			
		||||
${h.form(request.current_route_url(), id='find-by-perm-form')}
 | 
			
		||||
${h.csrf_token(request)}
 | 
			
		||||
 | 
			
		||||
<div class="form">
 | 
			
		||||
  ${self.wtfield(form, 'permission_group')}
 | 
			
		||||
  ${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 class="form">
 | 
			
		||||
        ${self.wtfield(form, 'permission_group')}
 | 
			
		||||
        ${self.wtfield(form, 'permission')}
 | 
			
		||||
        <div class="buttons">
 | 
			
		||||
          ${h.submit('submit', "Find {}".format(model_title_plural))}
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div class="field-wrapper">
 | 
			
		||||
      <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>
 | 
			
		||||
      ${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>
 | 
			
		||||
    </div>
 | 
			
		||||
      % endif
 | 
			
		||||
  % endif
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
    <div class="buttons">
 | 
			
		||||
      <b-button type="is-primary"
 | 
			
		||||
                native-type="submit"
 | 
			
		||||
                :disabled="formSubmitting">
 | 
			
		||||
        {{ formButtonText }}
 | 
			
		||||
      </b-button>
 | 
			
		||||
    </div>
 | 
			
		||||
<%def name="render_this_page_template()">
 | 
			
		||||
  ${parent.render_this_page_template()}
 | 
			
		||||
  <script type="text/x-template" id="find-principals-template">
 | 
			
		||||
    <div class="app-wrapper">
 | 
			
		||||
 | 
			
		||||
    ${h.end_form()}
 | 
			
		||||
      ${h.form(request.current_route_url(), **{'@submit': 'submitForm'})}
 | 
			
		||||
      ${h.csrf_token(request)}
 | 
			
		||||
 | 
			
		||||
    % 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
 | 
			
		||||
      <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><!-- app-wrapper -->
 | 
			
		||||
</script>
 | 
			
		||||
      <div class="field-wrapper">
 | 
			
		||||
        <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', {
 | 
			
		||||
      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: {
 | 
			
		||||
      ${h.end_form()}
 | 
			
		||||
 | 
			
		||||
          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
 | 
			
		||||
              this.groupPermissions = this.permissionGroups[groupkey].permissions
 | 
			
		||||
              this.selectedPermission = this.groupPermissions[0].permkey
 | 
			
		||||
          },
 | 
			
		||||
    </div><!-- app-wrapper -->
 | 
			
		||||
  </script>
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
          submitForm() {
 | 
			
		||||
              this.formSubmitting = true
 | 
			
		||||
              this.formButtonText = "Working, please wait..."
 | 
			
		||||
          }
 | 
			
		||||
      }
 | 
			
		||||
  })
 | 
			
		||||
<%def name="modify_this_page_vars()">
 | 
			
		||||
  ${parent.modify_this_page_vars()}
 | 
			
		||||
  <script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
  new Vue({
 | 
			
		||||
      el: '#find-principals-app',
 | 
			
		||||
      data() {
 | 
			
		||||
          return {
 | 
			
		||||
              permissionGroups: ${json.dumps(buefy_perms)|n},
 | 
			
		||||
              sortedGroups: ${json.dumps(buefy_sorted_groups)|n}
 | 
			
		||||
          }
 | 
			
		||||
      }
 | 
			
		||||
  })
 | 
			
		||||
    ThisPageData.permissionGroups = ${json.dumps(buefy_perms)|n}
 | 
			
		||||
    ThisPageData.sortedGroups = ${json.dumps(buefy_sorted_groups)|n}
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
% endif
 | 
			
		||||
  </script>
 | 
			
		||||
</%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()}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
## -*- coding: utf-8; -*-
 | 
			
		||||
<%inherit file="/base.mako" />
 | 
			
		||||
<%inherit file="/page.mako" />
 | 
			
		||||
 | 
			
		||||
<%def name="title()">${index_title}</%def>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -56,19 +56,17 @@
 | 
			
		|||
  % endif
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div style="display: flex; justify-content: space-between;">
 | 
			
		||||
 | 
			
		||||
<%def name="page_content()">
 | 
			
		||||
  % if use_form:
 | 
			
		||||
  <div class="form-wrapper">
 | 
			
		||||
    <p>Please select the type of report you wish to generate.</p>
 | 
			
		||||
      <div class="form-wrapper">
 | 
			
		||||
        <p>Please select the type of report you wish to generate.</p>
 | 
			
		||||
 | 
			
		||||
    <div style="display: flex;">
 | 
			
		||||
      ${form.render()|n}
 | 
			
		||||
      <div id="report-description"></div>
 | 
			
		||||
    </div>
 | 
			
		||||
        <div style="display: flex;">
 | 
			
		||||
          ${form.render()|n}
 | 
			
		||||
          <div id="report-description"></div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
  </div><!-- form-wrapper -->
 | 
			
		||||
      </div><!-- form-wrapper -->
 | 
			
		||||
  % else:
 | 
			
		||||
      <div>
 | 
			
		||||
        <p>Please select the type of report you wish to generate.</p>
 | 
			
		||||
| 
						 | 
				
			
			@ -81,9 +79,7 @@
 | 
			
		|||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
  % endif
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
  <ul id="context-menu">
 | 
			
		||||
    ${self.context_menu_items()}
 | 
			
		||||
  </ul>
 | 
			
		||||
 | 
			
		||||
</div>
 | 
			
		||||
${parent.body()}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,17 +6,22 @@
 | 
			
		|||
  ${h.stylesheet_link(request.static_url('tailbone:static/css/perms.css'))}
 | 
			
		||||
</%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()}
 | 
			
		||||
 | 
			
		||||
<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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,94 +41,96 @@
 | 
			
		|||
  <email-preview-tools></email-preview-tools>
 | 
			
		||||
</%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'})}
 | 
			
		||||
      ${h.csrf_token(request)}
 | 
			
		||||
      ${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'):
 | 
			
		||||
      <div class="control">
 | 
			
		||||
        % if email.get_template('html'):
 | 
			
		||||
            <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">
 | 
			
		||||
              Preview TXT
 | 
			
		||||
              Preview HTML
 | 
			
		||||
            </a>
 | 
			
		||||
        % else:
 | 
			
		||||
            <button class="button is-primary"
 | 
			
		||||
                    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>
 | 
			
		||||
              Preview TXT
 | 
			
		||||
              Preview HTML
 | 
			
		||||
            </button>
 | 
			
		||||
        % endif
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
        <div class="control">
 | 
			
		||||
          or
 | 
			
		||||
        </div>
 | 
			
		||||
      <div class="control">
 | 
			
		||||
      % if email.get_template('txt'):
 | 
			
		||||
          <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">
 | 
			
		||||
          <input name="recipient" type="email" class="input" value="${request.user.email_address or ''}" />
 | 
			
		||||
        </div>
 | 
			
		||||
      <div class="control">
 | 
			
		||||
        or
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
        <div class="control">
 | 
			
		||||
          <b-button type="is-primary"
 | 
			
		||||
                    native-type="submit"
 | 
			
		||||
                    :disabled="previewFormSubmitting">
 | 
			
		||||
            {{ previewFormButtonText }}
 | 
			
		||||
          </b-button>
 | 
			
		||||
        </div>
 | 
			
		||||
      <div class="control">
 | 
			
		||||
        <input name="recipient" type="email" class="input" value="${request.user.email_address or ''}" />
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      </div><!-- field -->
 | 
			
		||||
      <div class="control">
 | 
			
		||||
        <b-button type="is-primary"
 | 
			
		||||
                  native-type="submit"
 | 
			
		||||
                  :disabled="previewFormSubmitting">
 | 
			
		||||
          {{ previewFormButtonText }}
 | 
			
		||||
        </b-button>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
    ${h.end_form()}
 | 
			
		||||
    </script>
 | 
			
		||||
    </div><!-- field -->
 | 
			
		||||
 | 
			
		||||
    <script type="text/javascript">
 | 
			
		||||
  ${h.end_form()}
 | 
			
		||||
  </script>
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
      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..."
 | 
			
		||||
              }
 | 
			
		||||
          }
 | 
			
		||||
      }
 | 
			
		||||
<%def name="make_this_page_component()">
 | 
			
		||||
  ${parent.make_this_page_component()}
 | 
			
		||||
  <script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
      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()}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
## -*- coding: utf-8 -*-
 | 
			
		||||
<%inherit file="/master/create.mako" />
 | 
			
		||||
 | 
			
		||||
<%def name="head_tags()">
 | 
			
		||||
  ${parent.head_tags()}
 | 
			
		||||
<%def name="extra_javascript()">
 | 
			
		||||
  ${parent.extra_javascript()}
 | 
			
		||||
  <script type="text/javascript">
 | 
			
		||||
    $(function() {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -146,8 +146,8 @@
 | 
			
		|||
  % endif
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="modify_this_page()">
 | 
			
		||||
  ${parent.modify_this_page()}
 | 
			
		||||
<%def name="modify_this_page_vars()">
 | 
			
		||||
  ${parent.modify_this_page_vars()}
 | 
			
		||||
  <script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
    ThisPage.data = function() { return {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -258,7 +258,20 @@
 | 
			
		|||
          % endfor
 | 
			
		||||
      % endif
 | 
			
		||||
 | 
			
		||||
      ## ##############################
 | 
			
		||||
      ## whole page
 | 
			
		||||
      ## ##############################
 | 
			
		||||
 | 
			
		||||
      ${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>
 | 
			
		||||
 | 
			
		||||
    ## Footer
 | 
			
		||||
| 
						 | 
				
			
			@ -411,6 +424,59 @@
 | 
			
		|||
 | 
			
		||||
<%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)">
 | 
			
		||||
  <div class="field-wrapper${' error' if form[name].errors else ''}">
 | 
			
		||||
    <label for="${name}">${form[name].label}</label>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,8 +67,8 @@
 | 
			
		|||
  % endif
 | 
			
		||||
</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="modify_this_page()">
 | 
			
		||||
  ${parent.modify_this_page()}
 | 
			
		||||
<%def name="modify_this_page_vars()">
 | 
			
		||||
  ${parent.modify_this_page_vars()}
 | 
			
		||||
  <script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
    TailboneFormData.showingPackages = 'diffs'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,7 +38,6 @@ from rattail.bouncer.config import get_profile_keys
 | 
			
		|||
from pyramid.response import FileResponse
 | 
			
		||||
from webhelpers2.html import HTML, tags
 | 
			
		||||
 | 
			
		||||
from tailbone import grids
 | 
			
		||||
from tailbone.views import MasterView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -76,18 +75,17 @@ class EmailBouncesView(MasterView):
 | 
			
		|||
    def configure_grid(self, 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_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_verb = 'is_null'
 | 
			
		||||
        g.filters['processed_by'] = g.make_filter('processed_by', model.User.username)
 | 
			
		||||
        g.sorters['processed_by'] = g.make_sorter(model.User.username)
 | 
			
		||||
        g.set_sort_defaults('bounced', 'desc')
 | 
			
		||||
 | 
			
		||||
        g.set_label('config_key', "Source")
 | 
			
		||||
        g.set_label('bounce_recipient_address', "Bounced To")
 | 
			
		||||
        g.set_label('intended_recipient_address', "Intended For")
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -217,8 +217,8 @@ class PeopleView(MasterView):
 | 
			
		|||
            return HTML.tag('ul', c=items)
 | 
			
		||||
        elif self.viewing and self.request.has_perm('users.create'):
 | 
			
		||||
            if use_buefy:
 | 
			
		||||
                return HTML.tag('button', type='button', class_='button is-primary',
 | 
			
		||||
                                id='make-user', c="Make User")
 | 
			
		||||
                return HTML.tag('b-button', type='is-primary', c="Make User",
 | 
			
		||||
                                **{'@click': 'clickMakeUser()'})
 | 
			
		||||
            else:
 | 
			
		||||
                return HTML.tag('button', type='button', id='make-user', c="Make User")
 | 
			
		||||
        else:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue