Allow disabling, or per-day scheduling, of problem reports
This commit is contained in:
parent
163c65600d
commit
e4392cd00a
17
tailbone/templates/deform/problem_report_days.pt
Normal file
17
tailbone/templates/deform/problem_report_days.pt
Normal file
|
@ -0,0 +1,17 @@
|
|||
<div tal:define="name name|field.name;"
|
||||
tal:omit-tag="">
|
||||
<div tal:define="vmodel vmodel|'field_model_' + name;"
|
||||
tal:omit-tag="">
|
||||
<b-field grouped>
|
||||
<input type="hidden" name="${name}"
|
||||
tal:attributes=":value 'JSON.stringify('+vmodel+')';" />
|
||||
<b-checkbox v-model="${vmodel}.day0">${day_labels[0]['abbr']}</b-checkbox>
|
||||
<b-checkbox v-model="${vmodel}.day1">${day_labels[1]['abbr']}</b-checkbox>
|
||||
<b-checkbox v-model="${vmodel}.day2">${day_labels[2]['abbr']}</b-checkbox>
|
||||
<b-checkbox v-model="${vmodel}.day3">${day_labels[3]['abbr']}</b-checkbox>
|
||||
<b-checkbox v-model="${vmodel}.day4">${day_labels[4]['abbr']}</b-checkbox>
|
||||
<b-checkbox v-model="${vmodel}.day5">${day_labels[5]['abbr']}</b-checkbox>
|
||||
<b-checkbox v-model="${vmodel}.day6">${day_labels[6]['abbr']}</b-checkbox>
|
||||
</b-field>
|
||||
</div>
|
||||
</div>
|
|
@ -66,6 +66,10 @@
|
|||
${parent.modify_this_page_vars()}
|
||||
<script type="text/javascript">
|
||||
|
||||
% if weekdays_data is not Undefined:
|
||||
${form.component_studly}Data.weekdaysData = ${json.dumps(weekdays_data)|n}
|
||||
% endif
|
||||
|
||||
ThisPageData.runReportShowDialog = false
|
||||
ThisPageData.runReportSubmitting = false
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ Reporting views
|
|||
|
||||
from __future__ import unicode_literals, absolute_import
|
||||
|
||||
import calendar
|
||||
import json
|
||||
import re
|
||||
import datetime
|
||||
import logging
|
||||
|
@ -563,7 +565,6 @@ class ProblemReportView(MasterView):
|
|||
url_prefix = '/reports/problems'
|
||||
|
||||
creatable = False
|
||||
editable = False
|
||||
deletable = False
|
||||
filterable = False
|
||||
pageable = False
|
||||
|
@ -571,6 +572,7 @@ class ProblemReportView(MasterView):
|
|||
|
||||
labels = {
|
||||
'system_key': "System",
|
||||
'days': "Schedule",
|
||||
}
|
||||
|
||||
grid_columns = [
|
||||
|
@ -580,32 +582,17 @@ class ProblemReportView(MasterView):
|
|||
'email_recipients',
|
||||
]
|
||||
|
||||
form_fields = [
|
||||
'system_key',
|
||||
'problem_title',
|
||||
'email_key',
|
||||
'email_recipients',
|
||||
]
|
||||
|
||||
def __init__(self, request):
|
||||
super(ProblemReportView, self).__init__(request)
|
||||
|
||||
app = self.get_rattail_app()
|
||||
self.handler = app.get_problem_report_handler()
|
||||
self.problem_handler = app.get_problem_report_handler()
|
||||
# TODO: deprecate / remove this
|
||||
self.handler = self.problem_handler
|
||||
|
||||
def normalize(self, report, keep_report=True):
|
||||
data = {
|
||||
'system_key': report.system_key,
|
||||
'problem_key': report.problem_key,
|
||||
'problem_title': report.problem_title,
|
||||
'email_key': self.handler.get_email_key(report),
|
||||
}
|
||||
|
||||
app = self.get_rattail_app()
|
||||
handler = app.get_email_handler()
|
||||
email = handler.get_email(data['email_key'])
|
||||
data['email_recipients'] = email.get_recips('all')
|
||||
|
||||
data = self.problem_handler.normalize_problem_report(
|
||||
report, include_schedule=True, include_recipients=True)
|
||||
if keep_report:
|
||||
data['_report'] = report
|
||||
return data
|
||||
|
@ -653,28 +640,159 @@ class ProblemReportView(MasterView):
|
|||
def configure_form(self, f):
|
||||
super(ProblemReportView, self).configure_form(f)
|
||||
|
||||
f.set_renderer('email_key', self.render_email_key)
|
||||
f.set_renderer('email_recipients', self.render_email_recipients)
|
||||
# email_*
|
||||
if self.editing:
|
||||
f.remove('email_key',
|
||||
'email_recipients')
|
||||
else:
|
||||
f.set_renderer('email_key', self.render_email_key)
|
||||
f.set_renderer('email_recipients', self.render_email_recipients)
|
||||
|
||||
# enabled
|
||||
f.set_type('enabled', 'boolean')
|
||||
|
||||
# days
|
||||
f.set_renderer('days', self.render_days)
|
||||
f.set_widget('days', DaysWidget())
|
||||
f.set_vuejs_field_converter('days', self.convert_vuejs_days)
|
||||
f.set_helptext('days', "NB. enabling a given day means you want the "
|
||||
"report to be available that morning (assuming that "
|
||||
"reports run overnight)")
|
||||
|
||||
# only allow edit of certain fields
|
||||
if self.editing:
|
||||
editable = ('enabled', 'days')
|
||||
for field in f:
|
||||
if field not in editable:
|
||||
f.set_readonly(field)
|
||||
|
||||
def convert_vuejs_days(self, days):
|
||||
days = dict(days)
|
||||
for key in days:
|
||||
if days[key] is colander.null:
|
||||
days[key] = 'null'
|
||||
return days
|
||||
|
||||
def render_email_recipients(self, report_info, field):
|
||||
recips = report_info['email_recipients']
|
||||
return ', '.join(recips)
|
||||
|
||||
def render_days(self, report_info, field):
|
||||
g = self.get_grid_factory()('days', [],
|
||||
columns=['weekday_name', 'enabled'],
|
||||
labels={'weekday_name': "Weekday"})
|
||||
return HTML.literal(g.render_buefy_table_element(data_prop='weekdaysData'))
|
||||
|
||||
def template_kwargs_view(self, **kwargs):
|
||||
kwargs = super(ProblemReportView, self).template_kwargs_view(**kwargs)
|
||||
report_info = kwargs['instance']
|
||||
|
||||
data = []
|
||||
for i in range(7):
|
||||
data.append({
|
||||
'weekday': i,
|
||||
'weekday_name': calendar.day_name[i],
|
||||
'enabled': "Yes" if report_info['day{}'.format(i)] else "No",
|
||||
})
|
||||
kwargs['weekdays_data'] = data
|
||||
|
||||
return kwargs
|
||||
|
||||
def save_edit_form(self, form):
|
||||
app = self.get_rattail_app()
|
||||
session = self.Session()
|
||||
data = form.validated
|
||||
report = self.get_instance()
|
||||
key = '{}.{}'.format(report['system_key'],
|
||||
report['problem_key'])
|
||||
|
||||
app.save_setting(session, 'rattail.problems.{}.enabled'.format(key),
|
||||
six.text_type(data['enabled']).lower())
|
||||
|
||||
for i in range(7):
|
||||
daykey = 'day{}'.format(i)
|
||||
app.save_setting(session, 'rattail.problems.{}.{}'.format(key, daykey),
|
||||
six.text_type(data['days'][daykey]).lower())
|
||||
|
||||
def execute_instance(self, report_info, user, progress=None, **kwargs):
|
||||
report = report_info['_report']
|
||||
problems = self.handler.run_problem_report(report, progress=progress)
|
||||
problems = self.handler.run_problem_report(report, progress=progress,
|
||||
force=True)
|
||||
return "Report found {} problems".format(len(problems))
|
||||
|
||||
|
||||
class ProblemReportDays(colander.MappingSchema):
|
||||
|
||||
day0 = colander.SchemaNode(colander.Boolean(),
|
||||
title=calendar.day_abbr[0])
|
||||
day1 = colander.SchemaNode(colander.Boolean(),
|
||||
title=calendar.day_abbr[1])
|
||||
day2 = colander.SchemaNode(colander.Boolean(),
|
||||
title=calendar.day_abbr[2])
|
||||
day3 = colander.SchemaNode(colander.Boolean(),
|
||||
title=calendar.day_abbr[3])
|
||||
day4 = colander.SchemaNode(colander.Boolean(),
|
||||
title=calendar.day_abbr[4])
|
||||
day5 = colander.SchemaNode(colander.Boolean(),
|
||||
title=calendar.day_abbr[5])
|
||||
day6 = colander.SchemaNode(colander.Boolean(),
|
||||
title=calendar.day_abbr[6])
|
||||
|
||||
|
||||
class ProblemReportSchema(colander.MappingSchema):
|
||||
|
||||
system_key = colander.SchemaNode(colander.String())
|
||||
system_key = colander.SchemaNode(colander.String(),
|
||||
missing=colander.null)
|
||||
|
||||
problem_key = colander.SchemaNode(colander.String())
|
||||
problem_key = colander.SchemaNode(colander.String(),
|
||||
missing=colander.null)
|
||||
|
||||
problem_title = colander.SchemaNode(colander.String())
|
||||
problem_title = colander.SchemaNode(colander.String(),
|
||||
missing=colander.null)
|
||||
|
||||
email_key = colander.SchemaNode(colander.String())
|
||||
description = colander.SchemaNode(colander.String(),
|
||||
missing=colander.null)
|
||||
|
||||
email_key = colander.SchemaNode(colander.String(),
|
||||
missing=colander.null)
|
||||
|
||||
email_recipients = colander.SchemaNode(colander.String(),
|
||||
missing=colander.null)
|
||||
|
||||
enabled = colander.SchemaNode(colander.Boolean())
|
||||
|
||||
days = ProblemReportDays()
|
||||
|
||||
|
||||
class DaysWidget(dfwidget.Widget):
|
||||
template = 'problem_report_days'
|
||||
|
||||
def serialize(self, field, cstruct, **kw):
|
||||
if cstruct in (colander.null, None):
|
||||
cstruct = ""
|
||||
readonly = kw.get("readonly", self.readonly)
|
||||
template = self.template
|
||||
values = dict(kw)
|
||||
if 'day_labels' not in values:
|
||||
values['day_labels'] = self.get_day_labels()
|
||||
values = self.get_template_values(field, cstruct, values)
|
||||
return field.renderer(template, **values)
|
||||
|
||||
def get_day_labels(self):
|
||||
labels = {}
|
||||
for i in range(7):
|
||||
labels[i] = {'name': calendar.day_name[i],
|
||||
'abbr': calendar.day_abbr[i]}
|
||||
return labels
|
||||
|
||||
def deserialize(self, field, pstruct):
|
||||
from deform.compat import string_types
|
||||
if pstruct is colander.null:
|
||||
return colander.null
|
||||
elif not isinstance(pstruct, string_types):
|
||||
raise colander.Invalid(field.schema, "Pstruct is not a string")
|
||||
pstruct = json.loads(pstruct)
|
||||
return pstruct
|
||||
|
||||
|
||||
def add_routes(config):
|
||||
|
|
Loading…
Reference in a new issue