0001-backoffice-set-listing-as-main-form-page-with-a-fiel.patch
| wcs/backoffice/root.ptl | ||
|---|---|---|
| 212 | 212 |
return FormPage(component) |
| 213 | 213 | |
| 214 | 214 | |
| 215 |
class FakeField: |
|
| 216 |
def __init__(self, id, type_, label): |
|
| 217 |
self.id = id |
|
| 218 |
self.type = type_ |
|
| 219 |
self.label = label |
|
| 220 | ||
| 221 |
def get_view_value(self, value): |
|
| 222 |
# just here to quack like a duck |
|
| 223 |
return None |
|
| 224 | ||
| 225 | ||
| 215 | 226 |
class FormPage(Directory): |
| 216 | 227 |
_q_exports = ['', 'listing', 'csv', 'stats', 'xls', 'pending'] |
| 217 | 228 | |
| ... | ... | |
| 235 | 246 |
raise errors.AccessUnauthorizedError() |
| 236 | 247 |
get_response().breadcrumb.append( (component + '/', self.formdef.name) ) |
| 237 | 248 | |
| 238 |
def _q_index [html] (self): |
|
| 239 |
get_logger().info('backoffice - form %s' % self.formdef.name)
|
|
| 240 |
html_top('%s - %s' % (_('Back Office'), self.formdef.name))
|
|
| 241 |
get_session().display_message() |
|
| 242 |
'<h2>%s</h2>' % self.formdef.name |
|
| 243 | 249 | |
| 250 |
def get_formdata_sidebar [html] (self, qs=''): |
|
| 244 | 251 |
'<ul>' |
| 245 |
'<li><a href="listing">%s</a></li>' % _('Listing')
|
|
| 246 |
'<li><a href="csv">%s</a></li>' % _('Listing in CSV format')
|
|
| 252 |
#' <li><a href="list%s">%s</a></li>' % (qs, _('List of results'))
|
|
| 253 |
' <li><a href="csv">%s</a></li>' % _('CSV Export')
|
|
| 247 | 254 |
if xlwt: |
| 248 |
'<li><a href="xls">%s</a></li>' % _('Listing in Excel format')
|
|
| 249 |
'<li><a href="pending">%s</a></li>' % _('Pending Forms')
|
|
| 250 |
'<li><a href="stats">%s</a></li>' % _('Statistics')
|
|
| 255 |
'<li><a href="xls">%s</a></li>' % _('Excel Export')
|
|
| 256 |
' <li><a href="stats">%s</a></li>' % _('Statistics')
|
|
| 257 |
'</ul>' |
|
| 258 | ||
| 259 |
def get_fields_sidebar [html] (self, fields): |
|
| 260 |
'<h3>%s</h3>' % _('Fields to display')
|
|
| 261 |
'<form>' |
|
| 262 |
'<ul>' |
|
| 263 |
for field in self.get_formdef_fields(): |
|
| 264 |
if not hasattr(field, str('get_view_value')):
|
|
| 265 |
continue |
|
| 266 |
'<li><input type="checkbox" name="%s"' % field.id |
|
| 267 |
if field.id in [x.id for x in fields]: |
|
| 268 |
' checked="checked"' |
|
| 269 |
'/>' |
|
| 270 |
'<label for="%s">%s</label>' % (field.id, field.label) |
|
| 271 |
'</li>' |
|
| 251 | 272 |
'</ul>' |
| 273 |
'<input type="submit" value="%s"/>' % _('Reload')
|
|
| 274 |
'</form>' |
|
| 275 | ||
| 276 |
def get_formdef_fields(self): |
|
| 277 |
fields = [] |
|
| 278 |
fields.append(FakeField('id', 'id', _('Identifier')))
|
|
| 279 |
fields.append(FakeField('time', 'time', _('Time')))
|
|
| 280 |
fields.append(FakeField('user-label', 'user-label', _('User Label')))
|
|
| 281 | ||
| 282 |
fields.extend(self.formdef.fields) |
|
| 252 | 283 | |
| 253 |
'<a href="..">%s</a>' % _('Back')
|
|
| 284 |
if self.formdef.workflow is None or len( |
|
| 285 |
self.formdef.workflow.possible_status) > 1: |
|
| 286 |
fields.append(FakeField('status', 'status', _('Status')))
|
|
| 254 | 287 | |
| 288 |
return fields |
|
| 255 | 289 | |
| 256 |
def listing [html] (self): |
|
| 290 |
def get_fields_from_query(self): |
|
| 291 |
field_ids = [x for x in get_request().form.keys()] |
|
| 292 |
if not field_ids: |
|
| 293 |
for field in self.formdef.fields: |
|
| 294 |
if not hasattr(field, str('get_view_value')):
|
|
| 295 |
continue |
|
| 296 |
field_ids = ['id', 'time', 'user-label', field.id, 'status'] |
|
| 297 |
break |
|
| 298 | ||
| 299 |
fields = [] |
|
| 300 |
for field in self.get_formdef_fields(): |
|
| 301 |
if field.id in field_ids: |
|
| 302 |
fields.append(field) |
|
| 303 | ||
| 304 |
return fields |
|
| 305 | ||
| 306 | ||
| 307 |
def _q_index [html] (self): |
|
| 257 | 308 |
get_logger().info('backoffice - form %s - listing' % self.formdef.name)
|
| 309 | ||
| 310 |
fields = self.get_fields_from_query() |
|
| 311 |
qs = '' |
|
| 312 |
if get_request().get_query(): |
|
| 313 |
qs = '?' + get_request().get_query() |
|
| 314 | ||
| 258 | 315 |
get_response().breadcrumb.append( ('listing', _('Listing')) )
|
| 259 | 316 |
html_top('forms', '%s - %s' % (_('Listing'), self.formdef.name))
|
| 260 | 317 |
'<h2>%s - %s</h2>' % (self.formdef.name, _('Listing'))
|
| 261 |
FormDefUI(self.formdef).listing(include_form = True) |
|
| 262 |
'<a href=".">%s</a>' % _('Back')
|
|
| 318 |
FormDefUI(self.formdef).listing(fields=fields, include_form=True) |
|
| 319 | ||
| 320 |
get_response().filter['sidebar'] = self.get_formdata_sidebar(qs) + self.get_fields_sidebar(fields) |
|
| 263 | 321 | |
| 264 | 322 |
def pending [html] (self): |
| 265 | 323 |
get_logger().info('backoffice - form %s - pending' % self.formdef.name)
|
| wcs/forms/backoffice.ptl | ||
|---|---|---|
| 27 | 27 |
def __init__(self, formdef): |
| 28 | 28 |
self.formdef = formdef |
| 29 | 29 | |
| 30 | ||
| 31 |
def get_listing_fields(self): |
|
| 32 |
fields = [] |
|
| 33 |
for f in self.formdef.fields: |
|
| 34 |
if f.type in ('title', 'subtitle', 'comment'):
|
|
| 35 |
continue |
|
| 36 |
if f.in_listing: |
|
| 37 |
fields.append(f) |
|
| 38 |
return fields |
|
| 39 | ||
| 40 | ||
| 41 |
def listing [html] (self, url_action = None, include_form = False, items = None): |
|
| 30 |
def listing [html] (self, fields, url_action=None, include_form=False, items=None): |
|
| 42 | 31 |
get_response().add_javascript(['jquery.js', |
| 43 |
'tablesorter/jquery.tablesorter.min.js', |
|
| 44 |
'jquery.event.drag-1.4.js', |
|
| 45 |
'jquery.kiketable.colsizable-1.1.js']) |
|
| 32 |
'tablesorter/jquery.tablesorter.min.js']) |
|
| 46 | 33 |
get_response().add_javascript_code( |
| 47 |
str('''$(function() {
|
|
| 48 |
$("table.sortable").tablesorter(
|
|
| 49 |
).kiketable_colsizable({dragMove:false,dragProxy: 'line'}); });'''))
|
|
| 34 |
str('''$(function() { $("table.sortable").tablesorter(); });'''))
|
|
| 50 | 35 |
get_response().add_css_include('../js/tablesorter/themes/blue/style.css')
|
| 51 |
get_response().add_css_include('../js/jquery.kiketable.colsizable.css')
|
|
| 52 | ||
| 53 |
if self.formdef.workflow is None or len( |
|
| 54 |
self.formdef.workflow.possible_status) > 1: |
|
| 55 |
include_status_column = True |
|
| 56 |
else: |
|
| 57 |
include_status_column = False |
|
| 58 | 36 | |
| 59 | 37 |
'<table id="listing" class="sortable tablesorter">' |
| 60 |
fields = self.get_listing_fields() |
|
| 61 | 38 |
'<colgroup>' |
| 62 | 39 |
'<col/>' |
| 63 | 40 |
'<col/>' |
| 64 | 41 |
for f in fields: |
| 65 | 42 |
'<col />' |
| 66 |
if include_status_column: |
|
| 67 |
'<col />' |
|
| 68 | 43 |
'</colgroup>' |
| 69 | 44 | |
| 70 | 45 |
'<thead><tr>' |
| 71 |
'<th></th>' |
|
| 72 |
'<th>%s</th>' % _('Creation Time')
|
|
| 73 | 46 |
for f in fields: |
| 74 | 47 |
'<th>' |
| 75 | 48 |
if len(f.label) < 20: |
| ... | ... | |
| 78 | 51 |
'<span title="%s">%s</span>' % ( |
| 79 | 52 |
f.label, misc.ellipsize(f.label, 20)) |
| 80 | 53 |
'</th>' |
| 81 |
if include_status_column: |
|
| 82 |
'<th>%s</th>' % _('Status')
|
|
| 83 | 54 |
'</tr></thead>' |
| 84 | 55 |
if include_form: |
| 85 | 56 |
'<thead style="display: none">' # will be displayed by javascript |
| 86 | 57 |
'<tr>' |
| 87 |
'<td></td>' |
|
| 88 |
'<td></td>' # creation time |
|
| 89 | 58 |
for f in fields: |
| 90 |
if f.type in ('title', 'subtitle', 'comment'):
|
|
| 91 |
continue |
|
| 92 | 59 |
'<td>' |
| 93 | 60 |
if f.type == 'item' and f.items: |
| 94 | 61 |
'<select onchange="updateListing()" name="f-%s">' % f.id |
| ... | ... | |
| 96 | 63 |
for item in f.items: |
| 97 | 64 |
'<option value="%s">%s</option>' % (item, misc.ellipsize(item, 20)) |
| 98 | 65 |
'</select>' |
| 66 |
if f.type == 'status': |
|
| 67 |
'<select name="status" onchange="updateListing()"' |
|
| 68 |
'<option value="">%s</option>' % _('All')
|
|
| 69 |
if self.formdef.workflow: |
|
| 70 |
for status in self.formdef.workflow.possible_status: |
|
| 71 |
'<option value="wf-%s">%s</option>' % (status.id, status.name) |
|
| 72 |
else: # COMPAT (behaviour when no workflow) |
|
| 73 |
for label in ('new', 'accepted', 'finished', 'rejected'):
|
|
| 74 |
'<option value="%s">%s</option>' % (label, _(status_labels[label])) |
|
| 75 |
'</select>' |
|
| 99 | 76 |
'</td>' |
| 100 |
if include_status_column: |
|
| 101 |
'<td><select name="status" onchange="updateListing()"' |
|
| 102 |
'<option value="">%s</option>' % _('All')
|
|
| 103 |
if self.formdef.workflow: |
|
| 104 |
for status in self.formdef.workflow.possible_status: |
|
| 105 |
'<option value="wf-%s">%s</option>' % (status.id, status.name) |
|
| 106 |
else: # COMPAT (behaviour when no workflow) |
|
| 107 |
for label in ('new', 'accepted', 'finished', 'rejected'):
|
|
| 108 |
'<option value="%s">%s</option>' % (label, _(status_labels[label])) |
|
| 109 |
'</select></td>' |
|
| 110 | 77 |
'</tr>' |
| 111 | 78 |
'</thead>' |
| 112 |
'<script src="%sjs/listing.js"></script>' % get_publisher().get_root_url() |
|
| 113 | 79 | |
| 114 | 80 |
'<tbody>' |
| 115 | 81 |
self.tbody(fields = fields, items = items, url_action = url_action) |
| 116 | 82 |
'</tbody>' |
| 117 | 83 |
"</table>" |
| 118 | 84 | |
| 119 |
def tbody [html] (self, fields = None, items = None, url_action = None): |
|
| 120 |
if self.formdef.workflow is None or len( |
|
| 121 |
self.formdef.workflow.possible_status) > 1: |
|
| 122 |
include_status_column = True |
|
| 123 |
else: |
|
| 124 |
include_status_column = False |
|
| 125 | ||
| 126 |
if not fields: |
|
| 127 |
fields = self.get_listing_fields() |
|
| 128 | ||
| 85 |
def tbody [html] (self, fields=None, items=None, url_action=None): |
|
| 129 | 86 |
if items is None: |
| 130 | 87 |
items = self.formdef.data_class().select(order_by = '-receipt_time') |
| 131 | 88 |
if url_action: |
| ... | ... | |
| 143 | 100 |
style = 'odd' |
| 144 | 101 |
'<tr class="status-%s %s">' % (filled.status, style) |
| 145 | 102 |
link = str(filled.id) + '/' |
| 146 |
'<td><a href="%s%s">%s</a></td>' % (link, url_action, filled.id) |
|
| 147 |
'<td>%s</td>' % misc.localstrftime(filled.receipt_time) |
|
| 148 | 103 |
for i, f in enumerate(fields): |
| 149 |
if f.type in ('title', 'subtitle', 'comment'):
|
|
| 150 |
continue |
|
| 151 |
'<td>' |
|
| 152 |
value = filled.data.get(f.id) |
|
| 153 |
if value is not None: |
|
| 154 |
s = f.get_view_short_value(value, min(120/len(fields), 30)) |
|
| 155 |
s = s.replace(str('[download]'), str('%sdownload' % link))
|
|
| 156 |
s |
|
| 157 |
'</td>' |
|
| 158 |
if include_status_column: |
|
| 159 |
'<td>%s</td>' % filled.get_status_label() |
|
| 104 |
if f.type == 'id': |
|
| 105 |
'<td><a href="%s%s">%s</a></td>' % (link, url_action, filled.id) |
|
| 106 |
elif f.type == 'time': |
|
| 107 |
'<td>%s</td>' % misc.localstrftime(filled.receipt_time) |
|
| 108 |
elif f.type == 'user-label': |
|
| 109 |
try: |
|
| 110 |
value = User.get(result.user_id).display_name |
|
| 111 |
'<td>%s</td>' % value |
|
| 112 |
except: |
|
| 113 |
'<td>-</td>' |
|
| 114 |
elif f.type == 'status': |
|
| 115 |
'<td>%s</td>' % filled.get_status_label() |
|
| 116 |
else: |
|
| 117 |
'<td>' |
|
| 118 |
value = filled.data.get(f.id) |
|
| 119 |
if value is not None: |
|
| 120 |
s = f.get_view_short_value(value, min(120/len(fields), 30)) |
|
| 121 |
s = s.replace(str('[download]'), str('%sdownload' % link))
|
|
| 122 |
s |
|
| 123 |
'</td>' |
|
| 160 | 124 |
'</tr>\n' |
| 161 | 125 | |
| 162 |
- |
|