Refactor batch execution options to use colander/deform
This commit is contained in:
parent
2cbacd6187
commit
dd04459748
|
@ -697,7 +697,7 @@ class Form(object):
|
|||
context = kwargs
|
||||
context['form'] = self
|
||||
context['dform'] = dform
|
||||
context['form_kwargs'] = {}
|
||||
context.setdefault('form_kwargs', {})
|
||||
# TODO: deprecate / remove the latter option here
|
||||
if self.auto_disable_save or self.auto_disable:
|
||||
context['form_kwargs']['class_'] = 'autodisable'
|
||||
|
|
12
tailbone/static/js/jquery.ui.tailbone.js
vendored
12
tailbone/static/js/jquery.ui.tailbone.js
vendored
|
@ -261,6 +261,18 @@
|
|||
that.grid.gridcore();
|
||||
that.element.unmask();
|
||||
});
|
||||
},
|
||||
|
||||
results_count: function(as_text) {
|
||||
var count = null;
|
||||
var match = /showing \d+ thru \d+ of (\S+)/.exec(this.element.find('.pager .showing').text());
|
||||
if (match) {
|
||||
count = match[1];
|
||||
if (!as_text) {
|
||||
count = parseInt(count, 10);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
|
||||
$(function() {
|
||||
|
||||
$('.grid-wrapper').gridwrapper();
|
||||
|
||||
$('#execute-batch').click(function() {
|
||||
if (has_execution_options) {
|
||||
$('#execution-options-dialog').dialog({
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
${h.javascript_link(request.static_url('tailbone:static/js/tailbone.batch.js'))}
|
||||
<script type="text/javascript">
|
||||
|
||||
var has_execution_options = ${'true' if master.has_execution_options(batch) else 'false'};
|
||||
|
||||
$(function() {
|
||||
|
||||
$('#save-refresh').click(function() {
|
||||
|
@ -55,13 +53,3 @@
|
|||
<div class="form-wrapper">
|
||||
${form.render()|n}
|
||||
</div>
|
||||
|
||||
<div id="execution-options-dialog" style="display: none;">
|
||||
|
||||
${h.form(url('{}.execute'.format(route_prefix), uuid=batch.uuid), name='batch-execution')}
|
||||
% if master.has_execution_options(batch):
|
||||
${rendered_execution_options|n}
|
||||
% endif
|
||||
${h.end_form()}
|
||||
|
||||
</div>
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
|
||||
${form.field_div('action', form.select('action', options=ACTION_OPTIONS), label="Action to Perform")}
|
|
@ -12,6 +12,11 @@
|
|||
$(function() {
|
||||
|
||||
$('#execute-results-button').click(function() {
|
||||
var count = $('.grid-wrapper').gridwrapper('results_count');
|
||||
if (!count) {
|
||||
alert("There are no batch results to execute.");
|
||||
return;
|
||||
}
|
||||
var form = $('form[name="execute-results"]');
|
||||
if (has_execution_options) {
|
||||
$('#execution-options-dialog').dialog({
|
||||
|
@ -66,16 +71,11 @@ ${parent.body()}
|
|||
|
||||
% if master.results_executable and request.has_perm('{}.execute_multiple'.format(permission_prefix)):
|
||||
<div id="execution-options-dialog" style="display: none;">
|
||||
${h.form(url('{}.execute_results'.format(route_prefix)), name='execute-results')}
|
||||
${h.csrf_token(request)}
|
||||
<br />
|
||||
<p>
|
||||
Please be advised, you are about to execute multiple batches!
|
||||
</p>
|
||||
<br />
|
||||
% if master.has_execution_options(batch):
|
||||
${rendered_execution_options|n}
|
||||
% endif
|
||||
${h.end_form()}
|
||||
${execute_form.render_deform(form_kwargs={'name': 'execute-results'}, buttons=False)|n}
|
||||
</div>
|
||||
% endif
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
<%def name="extra_javascript()">
|
||||
${parent.extra_javascript()}
|
||||
${h.javascript_link(request.static_url('tailbone:static/js/tailbone.batch.js'))}
|
||||
${h.javascript_link(request.static_url('tailbone:static/js/tailbone.batch.js') + '?ver={}'.format(tailbone.__version__))}
|
||||
<script type="text/javascript">
|
||||
|
||||
var has_execution_options = ${'true' if master.has_execution_options(batch) else 'false'};
|
||||
|
@ -84,13 +84,6 @@ ${rows_grid|n}
|
|||
|
||||
% if not batch.executed:
|
||||
<div id="execution-options-dialog" style="display: none;">
|
||||
|
||||
${h.form(url('{}.execute'.format(route_prefix), uuid=batch.uuid), name='batch-execution')}
|
||||
${h.csrf_token(request)}
|
||||
% if master.has_execution_options(batch):
|
||||
${rendered_execution_options|n}
|
||||
% endif
|
||||
${h.end_form()}
|
||||
|
||||
${execute_form.render_deform(form_kwargs={'name': 'batch-execution'}, buttons=False)|n}
|
||||
</div>
|
||||
% endif
|
||||
|
|
|
@ -43,11 +43,8 @@
|
|||
% if master.bulk_deletable and request.has_perm('{}.bulk_delete'.format(permission_prefix)):
|
||||
|
||||
$('form[name="bulk-delete"] button').click(function() {
|
||||
var count = 0;
|
||||
var match = /showing \d+ thru \d+ of (\S+)/.exec($('.pager .showing').text());
|
||||
if (match) {
|
||||
count = match[1];
|
||||
} else {
|
||||
var count = $('.grid-wrapper').gridwrapper('results_count', true);
|
||||
if (count === null) {
|
||||
alert("There don't seem to be any results to delete!");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ from __future__ import unicode_literals, absolute_import
|
|||
import os
|
||||
import datetime
|
||||
import logging
|
||||
import tempfile
|
||||
from cStringIO import StringIO
|
||||
|
||||
import six
|
||||
|
@ -39,13 +40,16 @@ from rattail.db import model, Session as RattailSession
|
|||
from rattail.threads import Thread
|
||||
from rattail.util import load_object, prettify
|
||||
|
||||
import colander
|
||||
import deform
|
||||
from deform import widget as dfwidget
|
||||
from pyramid import httpexceptions
|
||||
from pyramid.renderers import render_to_response
|
||||
from pyramid.response import FileResponse
|
||||
from pyramid_simpleform import Form
|
||||
from pyramid_deform import SessionFileUploadTempStore
|
||||
from webhelpers2.html import HTML, tags
|
||||
|
||||
from tailbone import forms, grids
|
||||
from tailbone import forms2 as forms, grids
|
||||
from tailbone.db import Session
|
||||
from tailbone.views import MasterView
|
||||
from tailbone.progress import SessionProgress
|
||||
|
@ -133,8 +137,9 @@ class BatchMasterView(MasterView):
|
|||
kwargs['handler'] = self.handler
|
||||
kwargs['execute_title'] = self.get_execute_title(batch)
|
||||
kwargs['execute_enabled'] = self.instance_executable(batch)
|
||||
if kwargs['execute_enabled'] and self.has_execution_options(batch):
|
||||
kwargs['rendered_execution_options'] = self.render_execution_options(batch)
|
||||
if kwargs['execute_enabled']:
|
||||
url = self.get_action_url('execute', batch)
|
||||
kwargs['execute_form'] = self.make_execute_form(batch, action_url=url)
|
||||
return kwargs
|
||||
|
||||
def allow_worksheet(self, batch):
|
||||
|
@ -179,22 +184,12 @@ class BatchMasterView(MasterView):
|
|||
return batch.id_str
|
||||
|
||||
def template_kwargs_index(self, **kwargs):
|
||||
kwargs['execute_enabled'] = self.instance_executable(None)
|
||||
if kwargs['execute_enabled'] and self.has_execution_options():
|
||||
kwargs['rendered_execution_options'] = self.render_execution_options()
|
||||
route_prefix = self.get_route_prefix()
|
||||
if self.results_executable:
|
||||
url = self.request.route_url('{}.execute_results'.format(route_prefix))
|
||||
kwargs['execute_form'] = self.make_execute_form(action_url=url)
|
||||
return kwargs
|
||||
|
||||
def render_execution_options(self, batch=None):
|
||||
if batch is None:
|
||||
batch = self.model_class
|
||||
form = self.make_execution_options_form(batch)
|
||||
kwargs = {
|
||||
'batch': batch,
|
||||
'form': forms.FormRenderer(form),
|
||||
}
|
||||
kwargs = self.get_exec_options_kwargs(**kwargs)
|
||||
return self.render('exec_options', kwargs)
|
||||
|
||||
def get_exec_options_kwargs(self, **kwargs):
|
||||
return kwargs
|
||||
|
||||
|
@ -422,10 +417,6 @@ class BatchMasterView(MasterView):
|
|||
def template_kwargs_edit(self, **kwargs):
|
||||
batch = kwargs['instance']
|
||||
kwargs['batch'] = batch
|
||||
kwargs['execute_title'] = self.get_execute_title(batch)
|
||||
kwargs['execute_enabled'] = self.instance_executable(batch)
|
||||
if kwargs['execute_enabled'] and self.has_execution_options(batch):
|
||||
kwargs['rendered_execution_options'] = self.render_execution_options(batch)
|
||||
return kwargs
|
||||
|
||||
def mobile_mark_complete(self):
|
||||
|
@ -609,19 +600,28 @@ class BatchMasterView(MasterView):
|
|||
# TODO
|
||||
execution_options_schema = None
|
||||
|
||||
def make_execution_options_form(self, batch=None):
|
||||
def make_execute_schema(self):
|
||||
return self.execution_options_schema()
|
||||
|
||||
def make_execute_form(self, batch=None, **kwargs):
|
||||
"""
|
||||
Return a proper Form for execution options.
|
||||
"""
|
||||
defaults = {}
|
||||
route_prefix = self.get_route_prefix()
|
||||
|
||||
if self.has_execution_options(batch):
|
||||
if batch is None:
|
||||
batch = self.model_class
|
||||
defaults = {}
|
||||
for field in self.execution_options_schema.fields:
|
||||
key = 'batch.{}.execute_option.{}'.format(batch.batch_key, field)
|
||||
schema = self.make_execute_schema()
|
||||
for field in schema:
|
||||
key = 'batch.{}.execute_option.{}'.format(batch.batch_key, field.name)
|
||||
if key in self.request.session:
|
||||
defaults[field] = self.request.session[key]
|
||||
return Form(self.request, schema=self.execution_options_schema,
|
||||
defaults=defaults or None)
|
||||
defaults[field.name] = self.request.session[key]
|
||||
else:
|
||||
schema = colander.Schema()
|
||||
|
||||
return forms.Form(schema=schema, request=self.request, defaults=defaults, **kwargs)
|
||||
|
||||
def get_execute_title(self, batch):
|
||||
if hasattr(self.handler, 'get_execute_title'):
|
||||
|
@ -855,6 +855,7 @@ class BatchMasterView(MasterView):
|
|||
"""
|
||||
batch = self.get_instance()
|
||||
query = self.get_effective_row_data(sort=False)
|
||||
if batch.rowcount is not None:
|
||||
batch.rowcount -= query.count()
|
||||
query.update({'removed': True}, synchronize_session=False)
|
||||
return self.redirect(self.get_action_url('view', batch))
|
||||
|
@ -865,16 +866,13 @@ class BatchMasterView(MasterView):
|
|||
displays a progress indicator page.
|
||||
"""
|
||||
batch = self.get_instance()
|
||||
if self.request.method == 'POST':
|
||||
|
||||
kwargs = {}
|
||||
if self.has_execution_options(batch):
|
||||
form = self.make_execution_options_form(batch)
|
||||
assert form.validate() # TODO
|
||||
kwargs.update(form.data)
|
||||
self.executing = True
|
||||
form = self.make_execute_form(batch)
|
||||
if form.validate(newstyle=True):
|
||||
kwargs = dict(form.validated)
|
||||
|
||||
# cache options to use as defaults next time
|
||||
for key, value in form.data.iteritems():
|
||||
for key, value in form.validated.items():
|
||||
self.request.session['batch.{}.execute_option.{}'.format(batch.batch_key, key)] = value
|
||||
|
||||
key = '{}.execute'.format(self.model_class.__tablename__)
|
||||
|
@ -888,7 +886,7 @@ class BatchMasterView(MasterView):
|
|||
'cancel_msg': "Batch execution was canceled.",
|
||||
})
|
||||
|
||||
self.request.session.flash("Sorry, you must POST to execute a batch.", 'error')
|
||||
self.request.session.flash("Invalid request: {}".format(form.make_deform_form().error), 'error')
|
||||
return self.redirect(self.get_action_url('view', batch))
|
||||
|
||||
def execute_error_message(self, error):
|
||||
|
@ -949,17 +947,12 @@ class BatchMasterView(MasterView):
|
|||
Starts a separate thread for the execution, and displays a progress
|
||||
indicator page.
|
||||
"""
|
||||
if self.request.method == 'POST':
|
||||
|
||||
kwargs = {}
|
||||
if self.has_execution_options():
|
||||
form = self.make_execution_options_form()
|
||||
if not form.validate():
|
||||
raise RuntimeError("Execution options form did not validate")
|
||||
kwargs.update(form.data)
|
||||
form = self.make_execute_form()
|
||||
if form.validate(newstyle=True):
|
||||
kwargs = dict(form.validated)
|
||||
|
||||
# cache options to use as defaults next time
|
||||
for key, value in form.data.iteritems():
|
||||
for key, value in form.validated.items():
|
||||
self.request.session['batch.{}.execute_option.{}'.format(self.model_class.batch_key, key)] = value
|
||||
|
||||
key = '{}.execute_results'.format(self.model_class.__tablename__)
|
||||
|
@ -974,7 +967,7 @@ class BatchMasterView(MasterView):
|
|||
'cancel_msg': "Batch execution was canceled",
|
||||
})
|
||||
|
||||
self.request.session.flash("Sorry, you must POST to execute batches", 'error')
|
||||
self.request.session.flash("Invalid request: {}".format(form.make_deform_form().error), 'error')
|
||||
return self.redirect(self.get_index_url())
|
||||
|
||||
def execute_results_thread(self, batches, user_uuid, progress=None, **kwargs):
|
||||
|
|
|
@ -31,9 +31,10 @@ import os
|
|||
from rattail.db import model
|
||||
from rattail.util import OrderedDict
|
||||
|
||||
import formencode as fe
|
||||
import colander
|
||||
from webhelpers2.html import tags
|
||||
|
||||
from tailbone import forms2 as forms
|
||||
from tailbone.db import Session
|
||||
from tailbone.views.batch import FileBatchMasterView
|
||||
|
||||
|
@ -44,10 +45,12 @@ ACTION_OPTIONS = OrderedDict([
|
|||
])
|
||||
|
||||
|
||||
class ExecutionOptions(fe.Schema):
|
||||
allow_extra_fields = True
|
||||
filter_extra_fields = True
|
||||
action = fe.validators.OneOf(ACTION_OPTIONS)
|
||||
class ExecutionOptions(colander.Schema):
|
||||
|
||||
action = colander.SchemaNode(
|
||||
colander.String(),
|
||||
validator=colander.OneOf(ACTION_OPTIONS),
|
||||
widget=forms.widgets.PlainSelectWidget(values=ACTION_OPTIONS.items()))
|
||||
|
||||
|
||||
class HandheldBatchView(FileBatchMasterView):
|
||||
|
@ -207,6 +210,9 @@ class HandheldBatchView(FileBatchMasterView):
|
|||
return super(HandheldBatchView, self).get_execute_success_url(batch)
|
||||
|
||||
def get_execute_results_success_url(self, result, **kwargs):
|
||||
if result is True:
|
||||
# no batches were actually executed
|
||||
return self.get_index_url()
|
||||
batch = result
|
||||
return self.get_execute_success_url(batch, result, **kwargs)
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ class MasterView(View):
|
|||
viewing = False
|
||||
editing = False
|
||||
deleting = False
|
||||
executing = False
|
||||
has_pk_fields = False
|
||||
|
||||
row_attrs = {}
|
||||
|
|
5
tailbone/views/vendors/catalogs.py
vendored
5
tailbone/views/vendors/catalogs.py
vendored
|
@ -58,23 +58,26 @@ class VendorCatalogsView(FileBatchMasterView):
|
|||
rows_bulk_deletable = True
|
||||
|
||||
grid_columns = [
|
||||
'id',
|
||||
'created',
|
||||
'created_by',
|
||||
'vendor',
|
||||
'effective',
|
||||
'filename',
|
||||
'rowcount',
|
||||
'executed',
|
||||
]
|
||||
|
||||
form_fields = [
|
||||
'id',
|
||||
'vendor',
|
||||
'filename',
|
||||
'effective',
|
||||
'created',
|
||||
'created_by',
|
||||
'rowcount',
|
||||
'executed',
|
||||
'executed_by',
|
||||
'rowcount',
|
||||
]
|
||||
|
||||
row_grid_columns = [
|
||||
|
|
Loading…
Reference in a new issue