workflows: add and use the possibility to know about "waitpoint" status

A waitpoint status is a status waiting for an event (be it user
interaction or something else), but can also be an endpoint (where the
user would wait, infinitely).

This is used to avoid "technical status" (that are just there to execute
some actions and redirect the user elsewhere) in different places, such
as the status filter for forms (because theorically it's not possible
to have forms with that status), or when reassigning status on workflow
changes (to avoid putting the form in a "stuck" situation).
This commit is contained in:
Frédéric Péters 2012-08-17 10:01:51 +02:00
parent f7cb44eccc
commit b1e529be50
7 changed files with 33 additions and 6 deletions

View File

@ -545,7 +545,7 @@ class FormDefPage(Directory):
new_workflow = Workflow.get(get_request().form.get('new'))
if get_request().get_method() == 'GET':
get_request().form = None # do not be considered submitted already
new_workflow_status = [(x.id, x.name) for x in new_workflow.possible_status]
new_workflow_status = [(x.id, x.name) for x in new_workflow.get_waitpoint_status()]
form = Form(enctype='multipart/form-data')
for status in self.formdef.workflow.possible_status:
default = status.id

View File

@ -425,7 +425,7 @@ class WorkflowStatusPage(Directory):
def reassign [html] (self):
options = [(None, 'Do nothing'), ('remove', _('Remove'))]
for status in self.workflow.possible_status:
for status in self.workflow.get_waitpoint_status():
if status.id == self.status.id:
continue
options.append(('reassign-%s' % status.id, _('Change to "%s"') % status.name))

View File

@ -252,11 +252,12 @@ class FormPage(Directory):
def get_fields_sidebar [html] (self, selected_filter, fields):
'<form>'
if self.formdef.workflow.possible_status:
waitpoint_status = self.formdef.workflow.get_waitpoint_status()
if waitpoint_status:
'<h3>%s</h3>' % _('Filters')
'<ul>'
filters = [('all', _('All')), ('pending', _('Pending')), ('done', _('Done'))]
for status in self.formdef.workflow.possible_status:
for status in waitpoint_status:
filters.append((status.id, status.name))
for filter_id, filter_label in filters:
if filter_id == selected_filter:

View File

@ -120,6 +120,8 @@ class AttachmentEvolutionPart:
class AddAttachmentWorkflowStatusItem(WorkflowStatusItem):
description = N_('Allow Addition of an Attachment')
key = 'addattachment'
endpoint = False
waitpoint = True
title = None
display_title = True

View File

@ -24,6 +24,7 @@ from wcs.workflows import WorkflowStatusJumpItem, register_item_class
class JumpWorkflowStatusItem(WorkflowStatusJumpItem):
description = N_('Change Status Automatically')
key = 'jump'
waitpoint = False
condition = None

View File

@ -27,7 +27,7 @@ from qommon.cron import CronJob
class TimeoutWorkflowStatusItem(WorkflowStatusJumpItem):
description = N_('Change Status on Timeout')
key = 'timeout'
endpoint = False
waitpoint = True
timeout = None

View File

@ -125,6 +125,21 @@ class Workflow(StorableObject):
if not item.id:
item.id = '%d' % (i+1)
def get_waitpoint_status(self):
# a waitpoint status is a status waiting for an event (be it user
# interaction or something else), but can also be an endpoint (where
# the user would wait, infinitely).
waitpoint_status = []
for status in self.possible_status:
waitpoint = False
endpoint = True
for item in status.items:
endpoint = item.endpoint and endpoint
waitpoint = item.waitpoint or waitpoint
if endpoint or waitpoint:
waitpoint_status.append(status)
return waitpoint_status
def get_endpoint_status(self):
not_endpoint_status = self.get_not_endpoint_status()
endpoint_status = [x for x in self.possible_status if x not in not_endpoint_status]
@ -442,7 +457,8 @@ class WorkflowStatus:
class WorkflowStatusItem:
description = 'XX'
id = None
endpoint = True
endpoint = True # means it's not possible to interact, and/or cause a status change
waitpoint = False # means it's possible to wait (user interaction, or other event)
directory_name = None
directory_class = None
support_substitution_variables = False
@ -577,6 +593,7 @@ class WorkflowStatusItem:
class WorkflowStatusJumpItem(WorkflowStatusItem):
status = None
endpoint = False
def get_status(self):
if not self.status:
@ -636,6 +653,7 @@ class CommentableWorkflowStatusItem(WorkflowStatusItem):
description = N_('Allow Comment')
key = 'commentable'
endpoint = False
waitpoint = True
label = None
button_label = 0 # hack to handle legacy commentable items
@ -712,6 +730,7 @@ class ChoiceWorkflowStatusItem(WorkflowStatusJumpItem):
description = N_('Change Status')
key = 'choice'
endpoint = False
waitpoint = True
label = None
by = []
@ -1058,6 +1077,7 @@ class EditableWorkflowStatusItem(WorkflowStatusItem):
description = N_('Allow Edition')
key = 'editable'
endpoint = False
waitpoint = True
by = []
status = None
@ -1144,6 +1164,9 @@ class ExportToModel(WorkflowStatusItem):
key = 'export_to_model'
support_substitution_variables = True
endpoint = False
waitpoint = True
label = None
model_file = None
directory_class = ExportToModelDirectory