0001-wip-criticality-levels.patch
wcs/admin/workflows.py | ||
---|---|---|
949 | 949 |
return redirect('..') |
950 | 950 | |
951 | 951 | |
952 |
class CriticalityLevelsDirectory(Directory): |
|
953 |
_q_exports = ['', 'new'] |
|
954 | ||
955 |
def __init__(self, workflow): |
|
956 |
self.workflow = workflow |
|
957 | ||
958 |
def _q_traverse(self, path): |
|
959 |
get_response().breadcrumb.append( |
|
960 |
('criticality-levels/', _('Criticality Levels'))) |
|
961 |
return Directory._q_traverse(self, path) |
|
962 | ||
963 |
def new(self): |
|
964 |
form = Form(enctype='multipart/form-data') |
|
965 |
form.add(StringWidget, 'name', title=_('Name'), required=True, size=50) |
|
966 |
form.add(ColourWidget, 'colour', title=_('Colour'), required=False) |
|
967 |
form.add_submit('submit', _('Add')) |
|
968 |
form.add_submit('cancel', _('Cancel')) |
|
969 |
if form.get_widget('cancel').parse(): |
|
970 |
return redirect('..') |
|
971 | ||
972 |
if form.is_submitted() and not form.has_errors(): |
|
973 |
if not self.workflow.criticality_levels: |
|
974 |
self.workflow.criticality_levels = [] |
|
975 |
level = WorkflowCriticalityLevel() |
|
976 |
level.name = form.get_widget('name').parse() |
|
977 |
level.colour = form.get_widget('colour').parse() |
|
978 |
self.workflow.criticality_levels.append(level) |
|
979 |
self.workflow.store() |
|
980 |
return redirect('..') |
|
981 | ||
982 |
get_response().breadcrumb.append(('new', _('New Criticality Level'))) |
|
983 |
html_top('workflows', title=_('New Criticality level')) |
|
984 |
r = TemplateIO(html=True) |
|
985 |
r += htmltext('<h2>%s</h2>') % _('New Criticality Level') |
|
986 |
r += form.render() |
|
987 |
return r.getvalue() |
|
988 | ||
989 |
def _q_lookup(self, component): |
|
990 |
for level in (self.workflow.criticality_levels or []): |
|
991 |
if level.id == component: |
|
992 |
break |
|
993 |
else: |
|
994 |
raise errors.TraversalError() |
|
995 | ||
996 |
form = Form(enctype='multipart/form-data') |
|
997 |
form.add(StringWidget, 'name', title=_('Name'), required=True, size=50, |
|
998 |
value=level.name) |
|
999 |
form.add(ColourWidget, 'colour', title=_('Colour'), required=False, |
|
1000 |
value=level.colour) |
|
1001 |
form.add_submit('submit', _('Submit')) |
|
1002 |
form.add_submit('cancel', _('Cancel')) |
|
1003 |
form.add_submit('delete', _('Delete')) |
|
1004 | ||
1005 |
if form.get_widget('cancel').parse(): |
|
1006 |
return redirect('..') |
|
1007 | ||
1008 |
if form.get_submit() == 'delete': |
|
1009 |
self.workflow.criticality_levels.remove(level) |
|
1010 |
self.workflow.store() |
|
1011 |
return redirect('..') |
|
1012 | ||
1013 |
if form.is_submitted() and not form.has_errors(): |
|
1014 |
level.name = form.get_widget('name').parse() |
|
1015 |
level.colour = form.get_widget('colour').parse() |
|
1016 |
self.workflow.store() |
|
1017 |
return redirect('..') |
|
1018 | ||
1019 |
get_response().breadcrumb.append(('new', _('Edit Criticality Level'))) |
|
1020 |
html_top('workflows', title=_('Edit Criticality Level')) |
|
1021 |
r = TemplateIO(html=True) |
|
1022 |
r += htmltext('<h2>%s</h2>') % _('Edit Criticality Level') |
|
1023 |
r += form.render() |
|
1024 |
return r.getvalue() |
|
1025 | ||
1026 |
def _q_index(self): |
|
1027 |
return redirect('..') |
|
1028 | ||
1029 | ||
952 | 1030 |
class GlobalActionPage(WorkflowStatusPage): |
953 | 1031 |
_q_exports = ['', 'new', 'delete', 'newitem', ('items', 'items_dir'), |
954 | 1032 |
'edit', ('triggers', 'triggers_dir'), |
... | ... | |
1139 | 1217 |
class WorkflowPage(Directory): |
1140 | 1218 |
_q_exports = ['', 'edit', 'delete', 'newstatus', ('status', 'status_dir'), 'update_order', |
1141 | 1219 |
'duplicate', 'export', 'svg', ('variables', 'variables_dir'), |
1142 |
'update_actions_order', |
|
1143 |
('functions', 'functions_dir'), ('global-actions', 'global_actions_dir')] |
|
1220 |
'update_actions_order', 'update_criticality_levels_order', |
|
1221 |
('functions', 'functions_dir'), ('global-actions', 'global_actions_dir'), |
|
1222 |
('criticality-levels', 'criticality_levels_dir'), |
|
1223 |
] |
|
1144 | 1224 | |
1145 | 1225 |
def __init__(self, component, html_top): |
1146 | 1226 |
try: |
... | ... | |
1153 | 1233 |
self.variables_dir = VariablesDirectory(self.workflow) |
1154 | 1234 |
self.functions_dir = FunctionsDirectory(self.workflow) |
1155 | 1235 |
self.global_actions_dir = GlobalActionsDirectory(self.workflow, html_top) |
1236 |
self.criticality_levels_dir = CriticalityLevelsDirectory(self.workflow) |
|
1156 | 1237 |
get_response().breadcrumb.append((component + '/', self.workflow.name)) |
1157 | 1238 | |
1158 | 1239 |
def _q_index(self): |
... | ... | |
1257 | 1338 |
r += htmltext('<ul id="status-list" class="biglist sortable" ' |
1258 | 1339 |
'data-order-function="update_actions_order">') |
1259 | 1340 |
else: |
1260 |
r += htmltext('<ul id="status-list" class="biglist">')
|
|
1341 |
r += htmltext('<ul class="biglist">') |
|
1261 | 1342 | |
1262 | 1343 |
for action in (self.workflow.global_actions or []): |
1263 | 1344 |
r += htmltext('<li class="biglistitem" id="itemId_%s">' % action.id) |
... | ... | |
1270 | 1351 |
r += htmltext('</ul>') |
1271 | 1352 |
r += htmltext('</div>') |
1272 | 1353 | |
1354 |
if not str(self.workflow.id).startswith('_') and get_publisher().has_site_option('workflow-criticality-levels'): |
|
1355 |
r += htmltext('<div class="bo-block">') |
|
1356 |
r += htmltext('<h3>%s') % _('Criticality Levels') |
|
1357 |
if not str(self.workflow.id).startswith('_'): |
|
1358 |
r += htmltext(' <span class="change">' |
|
1359 |
'(<a rel="popup" href="criticality-levels/new">' |
|
1360 |
'%s</a>)</span>') % _('add criticality level') |
|
1361 |
r += htmltext('</h3>') |
|
1362 |
r += htmltext('<ul class="biglist sortable" ' |
|
1363 |
'data-order-function="update_criticality_levels_order">') |
|
1364 |
for level in (self.workflow.criticality_levels or []): |
|
1365 |
r += htmltext('<li class="biglistitem" id="itemId_%s">' % level.id) |
|
1366 |
if not str(self.workflow.id).startswith('_'): |
|
1367 |
r += htmltext('<a rel="popup" href="criticality-levels/%s">%s</a>') % ( |
|
1368 |
level.id, level.name) |
|
1369 |
else: |
|
1370 |
r += htmltext('<a>%s</a>') % level.name |
|
1371 |
r += htmltext('</li>') |
|
1372 |
r += htmltext('</ul>') |
|
1373 |
r += htmltext('</div>') |
|
1374 | ||
1273 | 1375 |
r += htmltext('</div>') # .splitcontent-right |
1274 | 1376 | |
1275 | 1377 |
r += htmltext('<br style="clear:both;"/>') |
... | ... | |
1355 | 1457 |
self.workflow.store() |
1356 | 1458 |
return 'ok' |
1357 | 1459 | |
1460 |
def update_criticality_levels_order(self): |
|
1461 |
request = get_request() |
|
1462 |
new_order = request.form['order'].strip(';').split(';') |
|
1463 |
self.workflow.criticality_levels = [ |
|
1464 |
[x for x in self.workflow.criticality_levels if x.id == y][0] for y in new_order] |
|
1465 |
self.workflow.store() |
|
1466 |
return 'ok' |
|
1467 | ||
1358 | 1468 |
def newstatus(self): |
1359 | 1469 |
form = Form(enctype='multipart/form-data', action = 'newstatus') |
1360 | 1470 |
form.add(StringWidget, 'name', title = _('Name'), size = 50) |
wcs/backoffice/management.py | ||
---|---|---|
688 | 688 |
order_by=order_by, limit=limit, offset=offset) |
689 | 689 |
include_submission_channel = bool( |
690 | 690 |
get_publisher().get_site_option('welco_url', 'variables')) |
691 |
include_criticality_level = get_publisher().has_site_option('workflow-criticality-levels') |
|
691 | 692 | |
692 | 693 |
r = TemplateIO(html=True) |
693 | 694 |
r += htmltext('<table id="listing" class="main">') |
694 | 695 |
r += htmltext('<thead>') |
695 | 696 |
r += htmltext('<th></th>') # lock |
697 |
if include_criticality_level: |
|
698 |
r += htmltext('<th data-field-sort-key="criticality_level"><span></span></th>') |
|
696 | 699 |
if include_submission_channel: |
697 | 700 |
r += htmltext('<th data-field-sort-key="submission_channel"><span>%s</span></th>') % _('Channel') |
698 | 701 |
r += htmltext('<th data-field-sort-key="formdef_name"><span>%s</span></th>') % _('Form') |
... | ... | |
713 | 716 |
object_key = 'formdata-%s-%s' % (formdata.formdef.url_name, formdata.id) |
714 | 717 |
if object_key in visited_objects: |
715 | 718 |
classes.append('advisory-lock') |
716 |
r += htmltext('<tr class="%s" data-link="%s">' % ( |
|
719 |
style = '' |
|
720 |
if include_criticality_level: |
|
721 |
try: |
|
722 |
level = formdata.formdef.workflow.criticality_levels[formdata.criticality_level] |
|
723 |
except (IndexError, TypeError): |
|
724 |
pass |
|
725 |
else: |
|
726 |
classes.append('criticality-level') |
|
727 |
style = 'style="border-color: #%s;"' % level.colour |
|
728 |
r += htmltext('<tr class="%s" data-link="%s" %s>' % ( |
|
717 | 729 |
' '.join(classes), |
718 |
formdata.get_url(backoffice=True))) |
|
730 |
formdata.get_url(backoffice=True), |
|
731 |
style)) |
|
719 | 732 |
r += htmltext('<td></td>') # lock |
733 |
if include_criticality_level: |
|
734 |
r += htmltext('<td></td>') |
|
720 | 735 |
if include_submission_channel: |
721 | 736 |
r += htmltext('<td>%s</td>') % formdata.get_submission_channel_label() |
722 | 737 |
r += htmltext('<td>%s</td>') % formdata.formdef.name |
... | ... | |
1642 | 1657 |
formdata = self.filled |
1643 | 1658 | |
1644 | 1659 |
r = TemplateIO(html=True) |
1660 | ||
1661 |
if formdata.receipt_time: |
|
1662 |
r += htmltext('<div class="extra-context">') |
|
1663 |
r += htmltext('<h3>%s</h3>') % _('General Information') |
|
1664 |
r += htmltext('<p>') |
|
1665 |
tm = misc.localstrftime(formdata.receipt_time) |
|
1666 |
r += _('The form has been recorded on %(date)s with the number %(number)s.') % { |
|
1667 |
'date': tm, 'number': formdata.get_display_id()} |
|
1668 |
r += htmltext('</p>') |
|
1669 |
try: |
|
1670 |
status_colour = formdata.get_status().colour |
|
1671 |
except AttributeError: |
|
1672 |
status_colour = 'ffffff' |
|
1673 |
fg_colour = misc.get_foreground_colour(status_colour) |
|
1674 | ||
1675 |
r += htmltext('<p class="current-status"><span class="item" style="background: #%s; color: %s;"></span>' % |
|
1676 |
(status_colour, fg_colour)) |
|
1677 |
r += htmltext('<span>%s %s</span></p>') % (_('Status:'), formdata.get_status_label()) |
|
1678 |
if formdata.formdef.workflow.criticality_levels: |
|
1679 |
try: |
|
1680 |
level = formdata.formdef.workflow.criticality_levels[formdata.criticality_level] |
|
1681 |
except IndexError: |
|
1682 |
pass |
|
1683 |
else: |
|
1684 |
fg_colour = misc.get_foreground_colour(level.colour) |
|
1685 |
r += htmltext('<p class="current-level"><span class="item" style="background: #%s; color: %s;"></span>' % |
|
1686 |
(level.colour, fg_colour)) |
|
1687 |
r += htmltext('<span>%s %s</span></p>') % (_('Criticality Level:'), level.name) |
|
1688 | ||
1689 |
if formdata.anonymised: |
|
1690 |
r += htmltext('<div class="infonotice">') |
|
1691 |
r += htmltext(_('This form has been anonymised on %(date)s.')) % { |
|
1692 |
'date': formdata.anonymised.strftime(misc.date_format())} |
|
1693 |
r += htmltext('</div>') |
|
1694 | ||
1695 |
r += htmltext('</div>') |
|
1696 | ||
1645 | 1697 |
if formdata.submission_context or formdata.submission_channel: |
1646 | 1698 |
extra_context = formdata.submission_context or {} |
1647 | 1699 |
r += htmltext('<div class="extra-context">') |
wcs/formdata.py | ||
---|---|---|
171 | 171 |
backoffice_submission = False |
172 | 172 |
submission_context = None |
173 | 173 |
submission_channel = None |
174 |
criticality_level = 0 |
|
174 | 175 | |
175 | 176 |
workflow_data = None |
176 | 177 |
workflow_roles = None |
... | ... | |
408 | 409 |
'form_url': self.get_url(), |
409 | 410 |
'form_url_backoffice': self.get_url(backoffice=True), |
410 | 411 |
'form_uri': '%s/%s/' % (self.formdef.url_name, self.id), |
412 |
'form_criticality_level': self.criticality_level, |
|
411 | 413 |
}) |
412 | 414 | |
413 | 415 |
d['form_status'] = self.get_status_label() |
wcs/forms/backoffice.py | ||
---|---|---|
75 | 75 |
r += htmltext('<col />') |
76 | 76 |
r += htmltext('</colgroup>') |
77 | 77 | |
78 |
include_criticality_level = get_publisher().has_site_option('workflow-criticality-levels') |
|
78 | 79 |
r += htmltext('<thead><tr>') |
79 |
r += htmltext('<td></td>') # lock |
|
80 |
if include_criticality_level: |
|
81 |
r += htmltext('<th style="width: 4ex;" data-field-sort-key="criticality_level"><span></span>') |
|
82 |
else: |
|
83 |
r += htmltext('<td></td>') # lock |
|
80 | 84 |
for f in fields: |
81 | 85 |
field_sort_key = None |
82 | 86 |
if getattr(f, 'fake', False): |
... | ... | |
209 | 213 |
url_action = '' |
210 | 214 |
root_url = get_publisher().get_root_url() |
211 | 215 |
visited_objects = get_publisher().get_visited_objects(exclude_user=get_session().user) |
216 |
include_criticality_level = get_publisher().has_site_option('workflow-criticality-levels') |
|
217 |
if include_criticality_level: |
|
218 |
include_criticality_level = bool(self.formdef.workflow.criticality_levels) |
|
212 | 219 |
for i, filled in enumerate(items): |
213 | 220 |
classes = ['status-%s-%s' % (filled.formdef.workflow.id, filled.status)] |
214 | 221 |
if i%2: |
... | ... | |
220 | 227 |
if object_key in visited_objects: |
221 | 228 |
classes.append('advisory-lock') |
222 | 229 | |
230 |
style = '' |
|
231 |
if include_criticality_level: |
|
232 |
try: |
|
233 |
level = filled.formdef.workflow.criticality_levels[filled.criticality_level] |
|
234 |
except (IndexError, TypeError): |
|
235 |
style = '' |
|
236 |
else: |
|
237 |
classes.append('criticality-level') |
|
238 |
style = ' style="border-color: #%s;"' % level.colour |
|
239 | ||
223 | 240 |
link = str(filled.id) + '/' |
224 | 241 |
data = ' data-link="%s"' % link |
225 | 242 |
if filled.anonymised: |
226 | 243 |
data += ' data-anonymised="true"' |
227 | 244 |
r += htmltext('<tr class="%s"%s>' % (' '.join(classes), data)) |
228 |
r += htmltext('<td></td>') # lock |
|
245 |
if include_criticality_level: |
|
246 |
r += htmltext('<td %s></td>' % style) # criticality_level |
|
247 |
else: |
|
248 |
r += htmltext('<td></td>') # lock |
|
229 | 249 |
for i, f in enumerate(fields): |
230 | 250 |
if f.type == 'id': |
231 | 251 |
r += htmltext('<td class="cell-id"><a href="%s%s">%s</a></td>') % (link, url_action, |
wcs/forms/common.py | ||
---|---|---|
497 | 497 |
get_logger().info('form %s - id: %s - view status' % (self.formdef.name, self.filled.id)) |
498 | 498 |
self.html_top('%s - %s' % (self.formdef.name, self.filled.id)) |
499 | 499 |
r = TemplateIO(html=True) |
500 |
if self.filled.receipt_time is not None: |
|
501 |
tm = misc.localstrftime(self.filled.receipt_time) |
|
502 |
else: |
|
503 |
tm = '???' |
|
504 |
r += htmltext("<p>") |
|
505 |
r += _('The form has been recorded on %(date)s with the number %(number)s.') % { |
|
506 |
'date': tm, 'number': self.filled.get_display_id()} |
|
507 |
r += htmltext("</p>") |
|
508 | ||
509 |
if self.filled.anonymised: |
|
510 |
r += htmltext('<div class="infonotice">') |
|
511 |
r += htmltext(_('This form has been anonymised on %(date)s.')) % { |
|
512 |
'date': self.filled.anonymised.strftime(misc.date_format())} |
|
513 |
r += htmltext('</div>') |
|
514 | 500 | |
515 | 501 |
r += htmltext(self.workflow_messages()) |
516 | 502 |
wcs/qommon/static/css/dc2/admin.css | ||
---|---|---|
1251 | 1251 |
.c-360-user-view li > span { |
1252 | 1252 |
padding-left: 1ex; |
1253 | 1253 |
} |
1254 | ||
1255 |
p.current-level span, |
|
1256 |
p.current-status span { |
|
1257 |
line-height: 40px; |
|
1258 |
} |
|
1259 | ||
1260 |
p.current-level .item, |
|
1261 |
p.current-status .item { |
|
1262 |
float: left; |
|
1263 |
display: inline-block; |
|
1264 |
width: 40px; |
|
1265 |
height: 40px; |
|
1266 |
border-radius: 20px; |
|
1267 |
border: 1px solid #aaa; |
|
1268 |
margin-right: 1ex; |
|
1269 |
margin-bottom: 1ex; |
|
1270 |
} |
|
1271 | ||
1272 |
p.current-level .item { |
|
1273 |
border-radius: 0; |
|
1274 |
} |
|
1275 | ||
1276 |
tr.criticality-level { |
|
1277 |
border-left-width: 5px; |
|
1278 |
border-left-style: solid; |
|
1279 |
} |
|
1280 | ||
1281 |
table#listing tr.criticality-level td:first-child { |
|
1282 |
border-left-width: 5px; |
|
1283 |
border-left-style: solid; |
|
1284 |
} |
wcs/qommon/static/js/biglist.js | ||
---|---|---|
9 | 9 |
{ |
10 | 10 |
accept: 'biglistitem', |
11 | 11 |
scroll: true, |
12 |
helper: 'clone', |
|
12 | 13 |
helperclass: 'sortHelper', |
13 | 14 |
activeclass : 'sortableactive', |
14 | 15 |
hoverclass : 'sortablehover', |
wcs/sql.py | ||
---|---|---|
325 | 325 |
'anonymised', 'workflow_roles', 'workflow_roles_array', |
326 | 326 |
'concerned_roles_array', 'tracking_code', |
327 | 327 |
'actions_roles_array', 'backoffice_submission', |
328 |
'submission_context', 'submission_channel']) |
|
328 |
'submission_context', 'submission_channel', |
|
329 |
'criticality_level']) |
|
329 | 330 | |
330 | 331 |
# migrations |
331 | 332 |
if not 'fts' in existing_fields: |
... | ... | |
360 | 361 |
if not 'submission_channel' in existing_fields: |
361 | 362 |
cur.execute('''ALTER TABLE %s ADD COLUMN submission_channel varchar''' % table_name) |
362 | 363 | |
364 |
if not 'criticality_level' in existing_fields: |
|
365 |
cur.execute('''ALTER TABLE %s ADD COLUMN criticality_level integer NOT NULL DEFAULT(0)''' % table_name) |
|
366 | ||
363 | 367 |
# add new fields |
364 | 368 |
for field in formdef.fields: |
365 | 369 |
assert field.id is not None |
... | ... | |
565 | 569 |
view_fields.append(("int '%s'" % (formdef.category_id or 0), 'category_id')) |
566 | 570 |
view_fields.append(("int '%s'" % (formdef.id or 0), 'formdef_id')) |
567 | 571 |
for field in ('id', 'user_id', 'user_hash', 'receipt_time', 'status', |
568 |
'id_display', 'submission_channel', 'backoffice_submission'): |
|
572 |
'id_display', 'submission_channel', 'backoffice_submission', |
|
573 |
'criticality_level'): |
|
569 | 574 |
view_fields.append((field, field)) |
570 | 575 |
return view_fields |
571 | 576 | |
... | ... | |
994 | 999 |
('backoffice_submission', 'boolean'), |
995 | 1000 |
('submission_context', 'bytea'), |
996 | 1001 |
('submission_channel', 'varchar'), |
1002 |
('criticality_level', 'int'), |
|
997 | 1003 |
] |
998 | 1004 | |
999 | 1005 |
def __init__(self, id=None): |
... | ... | |
1088 | 1094 |
'backoffice_submission': self.backoffice_submission, |
1089 | 1095 |
'submission_context': self.submission_context, |
1090 | 1096 |
'submission_channel': self.submission_channel, |
1097 |
'criticality_level': self.criticality_level, |
|
1091 | 1098 |
} |
1092 | 1099 |
if self.receipt_time: |
1093 | 1100 |
sql_dict['receipt_time'] = datetime.datetime.fromtimestamp(time.mktime(self.receipt_time)), |
... | ... | |
1786 | 1793 |
return result |
1787 | 1794 | |
1788 | 1795 | |
1789 |
SQL_LEVEL = 13
|
|
1796 |
SQL_LEVEL = 14
|
|
1790 | 1797 | |
1791 | 1798 |
def migrate_global_views(conn, cur): |
1792 | 1799 |
cur.execute('''SELECT COUNT(*) FROM information_schema.tables |
... | ... | |
1820 | 1827 |
raise RuntimeError() |
1821 | 1828 |
if sql_level < 1: # 1: introduction of tracking_code table |
1822 | 1829 |
do_tracking_code_table() |
1823 |
if sql_level < 13:
|
|
1830 |
if sql_level < 14:
|
|
1824 | 1831 |
# 2: introduction of formdef_id in views |
1825 | 1832 |
# 5: add concerned_roles_array, is_at_endpoint and fts to views |
1826 | 1833 |
# 7: add backoffice_submission to tables |
... | ... | |
1829 | 1836 |
# 10: add submission_channel to tables |
1830 | 1837 |
# 11: add formdef_name and user_name to views |
1831 | 1838 |
# 13: add backoffice_submission to views |
1839 |
# 14: add criticality_level to tables & views |
|
1832 | 1840 |
migrate_views(conn, cur) |
1833 | 1841 |
if sql_level < 12: |
1834 | 1842 |
# 3: introduction of _structured for user fields |
wcs/wf/criticality.py | ||
---|---|---|
1 |
# w.c.s. - web application for online forms |
|
2 |
# Copyright (C) 2005-2016 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software; you can redistribute it and/or modify |
|
5 |
# it under the terms of the GNU General Public License as published by |
|
6 |
# the Free Software Foundation; either version 2 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU General Public License |
|
15 |
# along with this program; if not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
from quixote import get_publisher |
|
18 | ||
19 |
from wcs.qommon.form import SingleSelectWidget |
|
20 |
from wcs.workflows import WorkflowStatusItem, register_item_class |
|
21 | ||
22 |
MODE_INC = '1' |
|
23 |
MODE_DEC = '2' |
|
24 |
MODE_SET = '3' |
|
25 | ||
26 |
class ModifyCriticalityWorkflowStatusItem(WorkflowStatusItem): |
|
27 |
description = N_('Modify Criticality') |
|
28 |
key = 'modify_criticality' |
|
29 | ||
30 |
mode = None |
|
31 |
absolute_value = None |
|
32 | ||
33 |
def get_parameters(self): |
|
34 |
return ('mode', 'absolute_value') |
|
35 | ||
36 |
@classmethod |
|
37 |
def is_available(cls): |
|
38 |
# TODO: if we had per-workflow availability we could show this action |
|
39 |
# only on the workflow where criticality levels are set. |
|
40 |
return get_publisher().has_site_option('workflow-criticality-levels') |
|
41 | ||
42 |
def add_parameters_widgets(self, form, parameters, prefix='', formdef=None): |
|
43 |
if 'mode' in parameters: |
|
44 |
form.add(SingleSelectWidget, '%smode' % prefix, |
|
45 |
title=_('Modification Mode'), value=self.mode, |
|
46 |
required=True, |
|
47 |
options=[ |
|
48 |
(MODE_INC, _('Increase Level')), |
|
49 |
(MODE_DEC, _('Decrease Level')), |
|
50 |
(MODE_SET, _('Set Level'))], |
|
51 |
attrs={'data-dynamic-display-parent': 'true'}) |
|
52 |
if 'absolute_value' in parameters: |
|
53 |
form.add(SingleSelectWidget, '%sabsolute_value' % prefix, |
|
54 |
title=_('Value'), value=self.absolute_value, |
|
55 |
options=[(str(i), x.name) for i, x in enumerate(self.parent.parent.criticality_levels)], |
|
56 |
attrs={ |
|
57 |
'data-dynamic-display-child-of': '%smode' % prefix, |
|
58 |
'data-dynamic-display-value': _('Set Level'), |
|
59 |
} |
|
60 |
) |
|
61 | ||
62 |
def perform(self, formdata): |
|
63 |
levels = formdata.formdef.workflow.criticality_levels |
|
64 |
current_level = formdata.criticality_level or 0 |
|
65 |
if self.mode == MODE_INC: |
|
66 |
new_level = current_level + 1 |
|
67 |
elif self.mode == MODE_DEC: |
|
68 |
new_level = current_level - 1 |
|
69 |
elif self.mode == MODE_SET: |
|
70 |
new_level = int(self.absolute_value) |
|
71 |
if new_level < 0: |
|
72 |
new_level = 0 |
|
73 |
if new_level >= len(levels): |
|
74 |
new_level = len(levels) - 1 |
|
75 |
if new_level != formdata.criticality_level: |
|
76 |
formdata.criticality_level = new_level |
|
77 |
formdata.store() |
|
78 | ||
79 |
register_item_class(ModifyCriticalityWorkflowStatusItem) |
wcs/workflows.py | ||
---|---|---|
251 | 251 |
roles = None |
252 | 252 |
variables_formdef = None |
253 | 253 |
global_actions = None |
254 |
criticality_levels = None |
|
254 | 255 | |
255 | 256 |
last_modification_time = None |
256 | 257 |
last_modification_user_id = None |
... | ... | |
261 | 262 |
self.possible_status = [] |
262 | 263 |
self.roles = {'_receiver': _('Recipient')} |
263 | 264 |
self.global_actions = [] |
265 |
self.criticality_levels = [] |
|
264 | 266 | |
265 | 267 |
def migrate(self): |
266 | 268 |
changed = False |
... | ... | |
941 | 943 |
trigger_o.init_with_xml(trigger, charset, include_id=include_id) |
942 | 944 | |
943 | 945 | |
946 |
class WorkflowCriticalityLevel(object): |
|
947 |
id = None |
|
948 |
name = None |
|
949 |
colour = None |
|
950 | ||
951 |
def __init__(self, name=None): |
|
952 |
self.name = name |
|
953 |
self.id = str(random.randint(0, 100000)) |
|
954 | ||
955 |
def export_to_xml(self, charset, include_id=False): |
|
956 |
level = ET.Element('criticality-level') |
|
957 |
ET.SubElement(level, 'id').text = unicode(self.id, charset) |
|
958 |
ET.SubElement(level, 'name').text = unicode(self.name, charset) |
|
959 |
ET.SubElement(level, 'colour').text = unicode(self.colour, charset) |
|
960 |
return level |
|
961 | ||
962 |
def init_with_xml(self, elem, charset, include_id=False): |
|
963 |
self.id = elem.find('id').text.encode(charset) |
|
964 |
self.name = elem.find('name').text.encode(charset) |
|
965 |
self.colour = elem.find('colour').text.encode(charset) |
|
966 | ||
967 | ||
944 | 968 |
class WorkflowStatus(object): |
945 | 969 |
id = None |
946 | 970 |
name = None |
... | ... | |
1961 | 1985 |
import wf.anonymise |
1962 | 1986 |
import wf.export_to_model |
1963 | 1987 |
import wf.resubmit |
1988 |
import wf.criticality |
|
1964 | 1989 | |
1965 | 1990 |
from wf.export_to_model import ExportToModel |
1966 |
- |