Misc. template cleanup per oruga effort

This commit is contained in:
Lance Edgar 2024-04-26 11:02:22 -05:00
parent ba32422059
commit 890ec64f3c
20 changed files with 125 additions and 91 deletions

View file

@ -1043,6 +1043,14 @@ class Form(object):
if field_type: if field_type:
attrs['type'] = field_type attrs['type'] = field_type
if messages: if messages:
if len(messages) == 1:
msg = messages[0]
if msg.startswith('`') and msg.endswith('`'):
attrs[':message'] = msg
else:
attrs['message'] = msg
else:
# nb. must pass an array as JSON string
attrs[':message'] = '[{}]'.format(', '.join([ attrs[':message'] = '[{}]'.format(', '.join([
"'{}'".format(msg.replace("'", r"\'")) "'{}'".format(msg.replace("'", r"\'"))
for msg in messages])) for msg in messages]))

View file

@ -1374,6 +1374,7 @@ class Grid(object):
""" """
context = dict(kwargs) context = dict(kwargs)
context['grid'] = self context['grid'] = self
context['request'] = self.request
context['data_prop'] = data_prop context['data_prop'] = data_prop
context['empty_labels'] = empty_labels context['empty_labels'] = empty_labels
if 'grid_columns' not in context: if 'grid_columns' not in context:

View file

@ -90,6 +90,11 @@ header span.header-text {
* "object helper" panel * "object helper" panel
******************************/ ******************************/
.object-helpers .panel {
margin: 1rem;
margin-bottom: 1.5rem;
}
.object-helpers .panel-heading { .object-helpers .panel-heading {
white-space: nowrap; white-space: nowrap;
} }

View file

@ -55,12 +55,16 @@
% if form.auto_disable_save or form.auto_disable: % if form.auto_disable_save or form.auto_disable:
<b-button type="is-primary" <b-button type="is-primary"
native-type="submit" native-type="submit"
:disabled="${form.component_studly}Submitting"> :disabled="${form.component_studly}Submitting"
icon-pack="fas"
icon-left="save">
{{ ${form.component_studly}ButtonText }} {{ ${form.component_studly}ButtonText }}
</b-button> </b-button>
% else: % else:
<b-button type="is-primary" <b-button type="is-primary"
native-type="submit"> native-type="submit"
icon-pack="fas"
icon-left="save">
${getattr(form, 'submit_label', getattr(form, 'save_label', "Submit"))} ${getattr(form, 'submit_label', getattr(form, 'save_label', "Submit"))}
</b-button> </b-button>
% endif % endif

View file

@ -87,7 +87,7 @@
<div class="level-item"> <div class="level-item">
<b-button type="is-primary" <b-button type="is-primary"
icon-pack="fas" icon-pack="fas"
icon-left="fas fa-plus" icon-left="plus"
@click="addColumn()"> @click="addColumn()">
New Column New Column
</b-button> </b-button>
@ -97,7 +97,7 @@
<div class="level-item"> <div class="level-item">
<b-button type="is-danger" <b-button type="is-danger"
icon-pack="fas" icon-pack="fas"
icon-left="fas fa-trash" icon-left="trash"
@click="new_table.columns = []" @click="new_table.columns = []"
:disabled="!new_table.columns.length"> :disabled="!new_table.columns.length">
Delete All Delete All
@ -164,11 +164,13 @@
<section class="modal-card-body"> <section class="modal-card-body">
<b-field label="Name"> <b-field label="Name">
<b-input v-model="editingColumnName"></b-input> <b-input v-model="editingColumnName"
expanded />
</b-field> </b-field>
<b-field label="Data Type"> <b-field label="Data Type">
<b-input v-model="editingColumnDataType"></b-input> <b-input v-model="editingColumnDataType"
expanded />
</b-field> </b-field>
<b-field label="Nullable"> <b-field label="Nullable">
@ -179,7 +181,8 @@
</b-field> </b-field>
<b-field label="Description"> <b-field label="Description">
<b-input v-model="editingColumnDescription"></b-input> <b-input v-model="editingColumnDescription"
expanded />
</b-field> </b-field>
</section> </section>

View file

@ -8,7 +8,8 @@
<%def name="page_content()"> <%def name="page_content()">
% if project_type: % if project_type:
<b-field grouped> <b-field grouped>
<b-field horizontal expanded label="Project Type"> <b-field horizontal expanded label="Project Type"
class="is-expanded">
${project_type} ${project_type}
</b-field> </b-field>
<once-button type="is-primary" <once-button type="is-primary"

View file

@ -76,12 +76,12 @@
</b-table-column> </b-table-column>
% endif % endif
<template slot="empty"> <template #empty>
<div class="content has-text-grey has-text-centered"> <div class="content has-text-grey has-text-centered">
<p> <p>
<b-icon <b-icon
pack="fas" pack="fas"
icon="fas fa-sad-tear" icon="sad-tear"
size="is-large"> size="is-large">
</b-icon> </b-icon>
</p> </p>

View file

@ -199,7 +199,7 @@
</span> </span>
<b-select v-model="perPage" <b-select v-model="perPage"
size="is-small" size="is-small"
@input="loadAsyncData()"> @input="perPageUpdated">
% for value in grid.get_pagesize_options(): % for value in grid.get_pagesize_options():
<option value="${value}">${value}</option> <option value="${value}">${value}</option>
% endfor % endfor
@ -459,9 +459,11 @@
if (params === undefined || params === null) { if (params === undefined || params === null) {
params = new URLSearchParams(this.getBasicParams()) params = new URLSearchParams(this.getBasicParams())
} else {
params = new URLSearchParams(params)
}
params.append('partial', true) params.append('partial', true)
params = params.toString() params = params.toString()
}
this.loading = true this.loading = true
this.$http.get(`${'$'}{this.ajaxDataUrl}?${'$'}{params}`).then(({ data }) => { this.$http.get(`${'$'}{this.ajaxDataUrl}?${'$'}{params}`).then(({ data }) => {
@ -520,6 +522,12 @@
this.loadAsyncData() this.loadAsyncData()
}, },
perPageUpdated(value) {
this.loadAsyncData({
pagesize: value,
})
},
onSort(field, order, event) { onSort(field, order, event) {
if (event.ctrlKey) { if (event.ctrlKey) {

View file

@ -77,31 +77,31 @@
<b-field label="Key" <b-field label="Key"
:type="overnightTaskKey ? null : 'is-danger'"> :type="overnightTaskKey ? null : 'is-danger'">
<b-input v-model.trim="overnightTaskKey" <b-input v-model.trim="overnightTaskKey"
ref="overnightTaskKey"> ref="overnightTaskKey"
</b-input> expanded />
</b-field> </b-field>
<b-field label="Description" <b-field label="Description"
:type="overnightTaskDescription ? null : 'is-danger'"> :type="overnightTaskDescription ? null : 'is-danger'">
<b-input v-model.trim="overnightTaskDescription" <b-input v-model.trim="overnightTaskDescription"
ref="overnightTaskDescription"> ref="overnightTaskDescription"
</b-input> expanded />
</b-field> </b-field>
<b-field label="Module"> <b-field label="Module">
<b-input v-model.trim="overnightTaskModule"> <b-input v-model.trim="overnightTaskModule"
</b-input> expanded />
</b-field> </b-field>
<b-field label="Class Name"> <b-field label="Class Name">
<b-input v-model.trim="overnightTaskClass"> <b-input v-model.trim="overnightTaskClass"
</b-input> expanded />
</b-field> </b-field>
<b-field label="Script"> <b-field label="Script">
<b-input v-model.trim="overnightTaskScript"> <b-input v-model.trim="overnightTaskScript"
</b-input> expanded />
</b-field> </b-field>
<b-field label="Notes"> <b-field label="Notes">
<b-input v-model.trim="overnightTaskNotes" <b-input v-model.trim="overnightTaskNotes"
type="textarea"> type="textarea"
</b-input> expanded />
</b-field> </b-field>
</section> </section>
@ -194,19 +194,19 @@
<b-field label="Key" <b-field label="Key"
:type="backfillTaskKey ? null : 'is-danger'"> :type="backfillTaskKey ? null : 'is-danger'">
<b-input v-model.trim="backfillTaskKey" <b-input v-model.trim="backfillTaskKey"
ref="backfillTaskKey"> ref="backfillTaskKey"
</b-input> expanded />
</b-field> </b-field>
<b-field label="Description" <b-field label="Description"
:type="backfillTaskDescription ? null : 'is-danger'"> :type="backfillTaskDescription ? null : 'is-danger'">
<b-input v-model.trim="backfillTaskDescription" <b-input v-model.trim="backfillTaskDescription"
ref="backfillTaskDescription"> ref="backfillTaskDescription"
</b-input> expanded />
</b-field> </b-field>
<b-field label="Script" <b-field label="Script"
:type="backfillTaskScript ? null : 'is-danger'"> :type="backfillTaskScript ? null : 'is-danger'">
<b-input v-model.trim="backfillTaskScript"> <b-input v-model.trim="backfillTaskScript"
</b-input> expanded />
</b-field> </b-field>
<b-field grouped> <b-field grouped>
<b-field label="Orientation"> <b-field label="Orientation">
@ -222,8 +222,8 @@
</b-field> </b-field>
<b-field label="Notes"> <b-field label="Notes">
<b-input v-model.trim="backfillTaskNotes" <b-input v-model.trim="backfillTaskNotes"
type="textarea"> type="textarea"
</b-input> expanded />
</b-field> </b-field>
</section> </section>
@ -252,7 +252,8 @@
expanded> expanded>
<b-input name="rattail.luigi.url" <b-input name="rattail.luigi.url"
v-model="simpleSettings['rattail.luigi.url']" v-model="simpleSettings['rattail.luigi.url']"
@input="settingsNeedSaved = true"> @input="settingsNeedSaved = true"
expanded>
</b-input> </b-input>
</b-field> </b-field>
@ -261,7 +262,8 @@
expanded> expanded>
<b-input name="rattail.luigi.scheduler.supervisor_process_name" <b-input name="rattail.luigi.scheduler.supervisor_process_name"
v-model="simpleSettings['rattail.luigi.scheduler.supervisor_process_name']" v-model="simpleSettings['rattail.luigi.scheduler.supervisor_process_name']"
@input="settingsNeedSaved = true"> @input="settingsNeedSaved = true"
expanded>
</b-input> </b-input>
</b-field> </b-field>
@ -270,7 +272,8 @@
expanded> expanded>
<b-input name="rattail.luigi.scheduler.restart_command" <b-input name="rattail.luigi.scheduler.restart_command"
v-model="simpleSettings['rattail.luigi.scheduler.restart_command']" v-model="simpleSettings['rattail.luigi.scheduler.restart_command']"
@input="settingsNeedSaved = true"> @input="settingsNeedSaved = true"
expanded>
</b-input> </b-input>
</b-field> </b-field>

View file

@ -10,10 +10,9 @@
<%def name="render_instance_header_title_extras()"> <%def name="render_instance_header_title_extras()">
% if master.touchable and master.has_perm('touch'): % if master.touchable and master.has_perm('touch'):
<b-button title="&quot;Touch&quot; this record to trigger sync" <b-button title="&quot;Touch&quot; this record to trigger sync"
icon-pack="fas"
icon-left="hand-pointer"
@click="touchRecord()" @click="touchRecord()"
:disabled="touchSubmitting"> :disabled="touchSubmitting">
<span><i class="fa fa-hand-pointer"></i></span>
</b-button> </b-button>
% endif % endif
% if expose_versions: % if expose_versions:
@ -34,7 +33,7 @@
% if xref_buttons or xref_links: % if xref_buttons or xref_links:
<nav class="panel"> <nav class="panel">
<p class="panel-heading">Cross-Reference</p> <p class="panel-heading">Cross-Reference</p>
<div class="panel-block buttons"> <div class="panel-block">
<div style="display: flex; flex-direction: column; gap: 0.5rem;"> <div style="display: flex; flex-direction: column; gap: 0.5rem;">
% for button in xref_buttons: % for button in xref_buttons:
${button} ${button}

View file

@ -19,48 +19,39 @@
</%def> </%def>
<%def name="page_content()"> <%def name="page_content()">
## TODO: this was basically copied from Revel diff template..need to abstract
<div class="form-wrapper">
<div class="form-wrapper" style="margin: 1rem; 0;">
<div class="form"> <div class="form">
<div class="field-wrapper"> <b-field label="Changed" horizontal>
<label>Changed</label> <span>${h.pretty_datetime(request.rattail_config, changed)}</span>
<div class="field">${h.pretty_datetime(request.rattail_config, changed)}</div> </b-field>
</div>
<div class="field-wrapper"> <b-field label="Changed by" horizontal>
<label>Changed by</label> <span>${transaction.user or ''}</span>
<div class="field">${transaction.user or ''}</div> </b-field>
</div>
<div class="field-wrapper"> <b-field label="IP Address" horizontal>
<label>IP Address</label> <span>${transaction.remote_addr}</span>
<div class="field">${transaction.remote_addr}</div> </b-field>
</div>
<div class="field-wrapper"> <b-field label="Comment" horizontal>
<label>Comment</label> <span>${transaction.meta.get('comment') or ''}</span>
<div class="field">${transaction.meta.get('comment') or ''}</div> </b-field>
</div>
<div class="field-wrapper"> <b-field label="TXN ID" horizontal>
<label>TXN ID</label> <span>${transaction.id}</span>
<div class="field">${transaction.id}</div> </b-field>
</div>
</div> </div>
</div>
</div><!-- form-wrapper --> <div class="versions-wrapper">
<div class="versions-wrapper">
% for diff in version_diffs: % for diff in version_diffs:
<h4 class="is-size-4 block">${diff.title}</h4> <h4 class="is-size-4 block">${diff.title}</h4>
${diff.render_html()} ${diff.render_html()}
% endfor % endfor
</div> </div>
</%def> </%def>

View file

@ -49,10 +49,16 @@
let url = '${url('{}.toggle_hidden'.format(route_prefix))}' let url = '${url('{}.toggle_hidden'.format(route_prefix))}'
let params = { let params = {
key: row.key, key: row.key,
hidden: row.hidden == 'No'? true : false, hidden: row.hidden == 'No' ? true : false,
} }
this.submitForm(url, params, response => { this.submitForm(url, params, response => {
row.hidden = params.hidden ? 'Yes' : 'No' // must update "original" data row, since our row arg
// may just be a proxy and not trigger view refresh
for (let email of this.data) {
if (email.key == row.key) {
email.hidden = params.hidden ? 'Yes' : 'No'
}
}
}) })
} }

View file

@ -66,21 +66,21 @@
:type="upgradeSystemKey ? null : 'is-danger'"> :type="upgradeSystemKey ? null : 'is-danger'">
<b-input v-model.trim="upgradeSystemKey" <b-input v-model.trim="upgradeSystemKey"
ref="upgradeSystemKey" ref="upgradeSystemKey"
:disabled="upgradeSystemKey == 'rattail'"> :disabled="upgradeSystemKey == 'rattail'"
</b-input> expanded />
</b-field> </b-field>
<b-field label="Label" <b-field label="Label"
:type="upgradeSystemLabel ? null : 'is-danger'"> :type="upgradeSystemLabel ? null : 'is-danger'">
<b-input v-model.trim="upgradeSystemLabel" <b-input v-model.trim="upgradeSystemLabel"
ref="upgradeSystemLabel" ref="upgradeSystemLabel"
:disabled="upgradeSystemKey == 'rattail'"> :disabled="upgradeSystemKey == 'rattail'"
</b-input> expanded />
</b-field> </b-field>
<b-field label="Command" <b-field label="Command"
:type="upgradeSystemCommand ? null : 'is-danger'"> :type="upgradeSystemCommand ? null : 'is-danger'">
<b-input v-model.trim="upgradeSystemCommand" <b-input v-model.trim="upgradeSystemCommand"
ref="upgradeSystemCommand"> ref="upgradeSystemCommand"
</b-input> expanded />
</b-field> </b-field>
</section> </section>

View file

@ -40,6 +40,7 @@
<b-field label="Description" <b-field label="Description"
:type="{'is-danger': !apiNewTokenDescription}"> :type="{'is-danger': !apiNewTokenDescription}">
<b-input v-model.trim="apiNewTokenDescription" <b-input v-model.trim="apiNewTokenDescription"
expanded
ref="apiNewTokenDescription"> ref="apiNewTokenDescription">
</b-input> </b-input>
</b-field> </b-field>

View file

@ -263,7 +263,7 @@ def includeme(config):
${parent.modify_this_page_vars()} ${parent.modify_this_page_vars()}
<script type="text/javascript"> <script type="text/javascript">
ThisPageData.activeStep = null ThisPageData.activeStep = 'enter-details'
ThisPageData.modelNames = ${json.dumps(model_names)|n} ThisPageData.modelNames = ${json.dumps(model_names)|n}
ThisPageData.modelName = null ThisPageData.modelName = null

View file

@ -83,7 +83,7 @@ def get_form_data(request):
# TODO: this seems to work for our use case at least, but perhaps # TODO: this seems to work for our use case at least, but perhaps
# there is a better way? see also # there is a better way? see also
# https://docs.pylonsproject.org/projects/pyramid/en/latest/api/request.html#pyramid.request.Request.is_xhr # https://docs.pylonsproject.org/projects/pyramid/en/latest/api/request.html#pyramid.request.Request.is_xhr
if request.is_xhr and not request.POST: if (request.is_xhr or request.content_type == 'application/json') and not request.POST:
return request.json_body return request.json_body
return request.POST return request.POST

View file

@ -187,7 +187,8 @@ class CommonView(View):
data['client_ip'] = self.request.client_addr data['client_ip'] = self.request.client_addr
app.send_email('user_feedback', data=data) app.send_email('user_feedback', data=data)
return {'ok': True} return {'ok': True}
return {'error': "Form did not validate!"} dform = form.make_deform_form()
return {'error': str(dform.error)}
def consume_batch_id(self): def consume_batch_id(self):
""" """

View file

@ -3003,7 +3003,7 @@ class MasterView(View):
button = HTML.tag('b-button', **btn_kw) button = HTML.tag('b-button', **btn_kw)
button = str(button) button = str(button)
button = button.replace('<b-button ', button = button.replace('<b-button ',
'<b-button tag="a"') '<b-button tag="a" ')
button = HTML.literal(button) button = HTML.literal(button)
return button return button

View file

@ -249,6 +249,7 @@ class RoleView(PrincipalMasterView):
factory = self.get_grid_factory() factory = self.get_grid_factory()
g = factory( g = factory(
key='{}.users'.format(route_prefix), key='{}.users'.format(route_prefix),
request=self.request,
data=[], data=[],
columns=[ columns=[
'full_name', 'full_name',

View file

@ -47,6 +47,7 @@ class UserView(PrincipalMasterView):
""" """
model_class = User model_class = User
has_rows = True has_rows = True
rows_title = "User Events"
model_row_class = UserEvent model_row_class = UserEvent
has_versions = True has_versions = True
touchable = True touchable = True
@ -225,7 +226,7 @@ class UserView(PrincipalMasterView):
# f.set_required('password') # f.set_required('password')
# api_tokens # api_tokens
if self.creating or self.editing: if self.creating or self.editing or self.deleting:
f.remove('api_tokens') f.remove('api_tokens')
elif self.has_perm('manage_api_tokens'): elif self.has_perm('manage_api_tokens'):
f.set_renderer('api_tokens', self.render_api_tokens) f.set_renderer('api_tokens', self.render_api_tokens)
@ -283,6 +284,7 @@ class UserView(PrincipalMasterView):
factory = self.get_grid_factory() factory = self.get_grid_factory()
g = factory( g = factory(
request=self.request,
key='{}.api_tokens'.format(route_prefix), key='{}.api_tokens'.format(route_prefix),
data=[], data=[],
columns=['description', 'created'], columns=['description', 'created'],