general: redo the workflow options mecanism with targeted variables (#6170)
The current system is kept in place but not advertised anymore.
This commit is contained in:
parent
c54ff30be0
commit
ce8254372a
|
@ -16,7 +16,7 @@ from wcs.qommon.http_request import HTTPRequest
|
|||
from wcs.qommon.template import get_current_theme
|
||||
from wcs.categories import Category
|
||||
from wcs.roles import Role
|
||||
from wcs.workflows import Workflow
|
||||
from wcs.workflows import Workflow, DisplayMessageWorkflowStatusItem
|
||||
from wcs.formdef import FormDef
|
||||
from wcs import fields
|
||||
|
||||
|
@ -298,6 +298,68 @@ def test_form_workflow_role():
|
|||
resp = resp.forms[0].submit('submit')
|
||||
assert FormDef.get(1).workflow_roles == {'_receiver': 1}
|
||||
|
||||
def test_form_workflow_options():
|
||||
create_superuser()
|
||||
create_role()
|
||||
|
||||
Workflow.wipe()
|
||||
workflow = Workflow(name='Workflow One')
|
||||
workflow.store()
|
||||
|
||||
FormDef.wipe()
|
||||
formdef = FormDef()
|
||||
formdef.name = 'form title'
|
||||
formdef.fields = []
|
||||
formdef.workflow_id = workflow.id
|
||||
formdef.workflow_options = {'2*1*body': 'xxx'}
|
||||
formdef.store()
|
||||
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/admin/forms/1/')
|
||||
assert '"workflow-options"' in resp.body
|
||||
|
||||
def test_form_workflow_variables():
|
||||
create_superuser()
|
||||
create_role()
|
||||
|
||||
Workflow.wipe()
|
||||
workflow = Workflow(name='Workflow One')
|
||||
from wcs.workflows import WorkflowVariablesFieldsFormDef
|
||||
workflow.variables_formdef = WorkflowVariablesFieldsFormDef(workflow=workflow)
|
||||
workflow.variables_formdef.fields.append(
|
||||
fields.StringField(id='1', varname='test', label='Test', type='string'))
|
||||
workflow.store()
|
||||
|
||||
FormDef.wipe()
|
||||
formdef = FormDef()
|
||||
formdef.name = 'form title'
|
||||
formdef.fields = []
|
||||
formdef.workflow_id = workflow.id
|
||||
formdef.store()
|
||||
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/admin/forms/1/')
|
||||
assert '"workflow-variables"' in resp.body
|
||||
|
||||
# visit the variables page
|
||||
resp = resp.click(href='workflow-variables')
|
||||
|
||||
# and set a value
|
||||
resp.forms[0]['f1'] = 'foobar'
|
||||
resp = resp.forms[0].submit()
|
||||
assert resp.location == 'http://example.net/admin/forms/1/'
|
||||
|
||||
# check the value has been correctly saved
|
||||
assert FormDef.get(formdef.id).workflow_options == {'test': 'foobar'}
|
||||
|
||||
# go back to the variables page, also check value
|
||||
resp = resp.follow()
|
||||
resp = resp.click(href='workflow-variables')
|
||||
assert resp.forms[0]['f1'].value == 'foobar'
|
||||
resp.forms[0]['f1'] = 'barbaz'
|
||||
resp = resp.forms[0].submit('cancel')
|
||||
assert resp.location == 'http://example.net/admin/forms/1/'
|
||||
|
||||
def test_form_acl_read():
|
||||
create_superuser()
|
||||
create_role()
|
||||
|
@ -694,6 +756,64 @@ def test_workflows_add_all_actions():
|
|||
resp = resp.follow() # redirect to items/
|
||||
resp = resp.follow() # redirect to ./
|
||||
|
||||
def test_workflows_variables():
|
||||
create_superuser()
|
||||
create_role()
|
||||
|
||||
Workflow.wipe()
|
||||
workflow = Workflow(name='foo')
|
||||
workflow.store()
|
||||
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/admin/workflows/1/')
|
||||
resp = resp.click(href='variables/')
|
||||
assert resp.location == 'http://example.net/admin/workflows/1/variables/fields/'
|
||||
resp = resp.follow()
|
||||
|
||||
# makes sure we can't add page fields
|
||||
assert 'value="New Page"' not in resp.body
|
||||
|
||||
# add a simple field
|
||||
resp.forms[0]['label'] = 'foobar'
|
||||
resp.forms[0]['type'] = 'Text (line)'
|
||||
resp = resp.forms[0].submit()
|
||||
assert resp.location == 'http://example.net/admin/workflows/1/variables/fields/'
|
||||
resp = resp.follow()
|
||||
|
||||
# check it's been saved correctly
|
||||
assert 'foobar' in resp.body
|
||||
assert len(Workflow.get(1).variables_formdef.fields) == 1
|
||||
assert Workflow.get(1).variables_formdef.fields[0].key == 'string'
|
||||
assert Workflow.get(1).variables_formdef.fields[0].label == 'foobar'
|
||||
|
||||
def test_workflows_variables_edit():
|
||||
test_workflows_variables()
|
||||
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/admin/workflows/1/')
|
||||
resp = resp.click(href='variables/')
|
||||
assert resp.location == 'http://example.net/admin/workflows/1/variables/fields/'
|
||||
resp = resp.follow()
|
||||
resp = resp.click('Edit', href='1/')
|
||||
assert resp.forms[0]['varname$name'].value == 'foobar'
|
||||
assert not 'varname$select' in resp.forms[0].fields
|
||||
|
||||
workflow = Workflow.get(1)
|
||||
baz_status = workflow.add_status(name='baz')
|
||||
display_message = DisplayMessageWorkflowStatusItem()
|
||||
display_message.parent = baz_status
|
||||
baz_status.items.append(display_message)
|
||||
workflow.store()
|
||||
|
||||
resp = app.get('/admin/workflows/1/variables/fields/')
|
||||
resp = resp.click('Edit', href='1/')
|
||||
assert 'varname$select' in resp.forms[0].fields
|
||||
resp.forms[0]['varname$select'].value = '1*1*message'
|
||||
resp = resp.forms[0].submit('submit')
|
||||
|
||||
assert Workflow.get(1).variables_formdef.fields[0].key == 'string'
|
||||
assert Workflow.get(1).variables_formdef.fields[0].varname == '1*1*message'
|
||||
|
||||
def test_users():
|
||||
create_superuser()
|
||||
app = login(get_app(pub))
|
||||
|
|
|
@ -5,6 +5,8 @@ import shutil
|
|||
from quixote import cleanup
|
||||
from wcs import formdef
|
||||
from wcs.formdef import FormDef
|
||||
from wcs.workflows import Workflow
|
||||
from wcs.fields import StringField
|
||||
|
||||
from utilities import create_temporary_pub
|
||||
|
||||
|
@ -89,3 +91,20 @@ def test_title_change():
|
|||
formdef.store()
|
||||
assert FormDef.get(formdef.id).name == 'baz'
|
||||
assert FormDef.get(formdef.id).url_name == 'bar' # didn't change
|
||||
|
||||
def test_substitution_variables():
|
||||
formdef = FormDef()
|
||||
formdef.name = 'foo'
|
||||
formdef.store()
|
||||
|
||||
from wcs.workflows import WorkflowVariablesFieldsFormDef
|
||||
wf = Workflow(name='variables')
|
||||
wf.variables_formdef = WorkflowVariablesFieldsFormDef(workflow=wf)
|
||||
wf.variables_formdef.fields.append(
|
||||
StringField(label='Test', type='string', varname='foo'))
|
||||
wf.store()
|
||||
formdef.workflow_id = wf.id
|
||||
|
||||
assert formdef.get_substitution_variables() == {'form_name': 'foo'}
|
||||
formdef.workflow_options = {'foo': 'bar'}
|
||||
assert formdef.get_substitution_variables() == {'form_name': 'foo', 'form_option_foo': 'bar'}
|
||||
|
|
|
@ -135,3 +135,12 @@ def test_modification_time():
|
|||
assert_xml_import_export_works(formdef)
|
||||
f2 = assert_json_import_export_works(formdef)
|
||||
assert tuple(f2.last_modification_time)[:6] == tuple(formdef.last_modification_time)[:6]
|
||||
|
||||
def test_workflow_options():
|
||||
formdef = FormDef()
|
||||
formdef.name = 'workflow options'
|
||||
formdef.workflow_options = {'foo': 'bar'}
|
||||
fd2 = assert_xml_import_export_works(formdef)
|
||||
assert fd2.workflow_options == formdef.workflow_options
|
||||
fd2 = assert_json_import_export_works(formdef)
|
||||
assert fd2.workflow_options == formdef.workflow_options
|
||||
|
|
|
@ -265,3 +265,12 @@ def test_commentable_action():
|
|||
|
||||
wf2 = assert_import_export_works(wf)
|
||||
assert wf2.possible_status[0].items[0].button_label is None
|
||||
|
||||
|
||||
def test_variables_formdef():
|
||||
wf = Workflow(name='variables')
|
||||
from wcs.workflows import WorkflowVariablesFieldsFormDef
|
||||
wf.variables_formdef = WorkflowVariablesFieldsFormDef(workflow=wf)
|
||||
wf.variables_formdef.fields.append(StringField(label='Test', type='string'))
|
||||
wf2 = assert_import_export_works(wf)
|
||||
assert wf2.variables_formdef.fields[0].label == 'Test'
|
||||
|
|
|
@ -171,6 +171,7 @@ class FormDefPage(Directory):
|
|||
_q_exports = ['', 'fields', 'delete', 'duplicate', 'export',
|
||||
'anonymise', 'archive', 'invite', 'enable', 'workflow',
|
||||
'category', 'role', ('workflow-options', 'workflow_options'),
|
||||
('workflow-variables', 'workflow_variables'),
|
||||
('workflow-status-remapping', 'workflow_status_remapping'),
|
||||
'roles', 'title', 'options', ('acl-read', 'acl_read'),
|
||||
'overwrite', 'qrcode', 'information']
|
||||
|
@ -260,8 +261,14 @@ class FormDefPage(Directory):
|
|||
r += '-'
|
||||
if self.formdef.workflow_id:
|
||||
pristine_workflow = Workflow.get(self.formdef.workflow_id)
|
||||
if pristine_workflow.has_options():
|
||||
r += htmltext(' (<a href="workflow-options">%s</a>)') % _('options')
|
||||
if pristine_workflow.variables_formdef:
|
||||
r += htmltext(' (<a rel="popup" href="workflow-variables">%s</a>)') % _('options')
|
||||
elif self.formdef.workflow_options:
|
||||
# there are no variables defined but there are some values
|
||||
# in workflow_options, this is probably the legacy stuff.
|
||||
if any((x for x in self.formdef.workflow_options if '*' in x)):
|
||||
r += htmltext(' (<a rel="popup" href="workflow-options">%s</a>)') % _('options')
|
||||
|
||||
r += ' '
|
||||
r += htmltext('(<a href="workflow" rel="popup">%s</a>)') % _('change')
|
||||
r += htmltext('</li>')
|
||||
|
@ -1300,6 +1307,28 @@ class FormDefPage(Directory):
|
|||
return redirect('fields/')
|
||||
return redirect('.')
|
||||
|
||||
def workflow_variables(self):
|
||||
self.html_top(title=_('Options'))
|
||||
|
||||
form = Form(enctype='multipart/form-data')
|
||||
self.formdef.workflow.variables_formdef.add_fields_to_form(form,
|
||||
form_data=self.formdef.get_variable_options_for_form())
|
||||
form.add_submit('submit', _('Submit'))
|
||||
form.add_submit('cancel', _('Cancel'))
|
||||
|
||||
if form.get_widget('cancel').parse():
|
||||
return redirect('.')
|
||||
|
||||
if form.is_submitted() and not form.has_errors():
|
||||
self.formdef.set_variable_options(form)
|
||||
self.formdef.store()
|
||||
return redirect('.')
|
||||
|
||||
r = TemplateIO(html=True)
|
||||
r += htmltext('<h2>%s</h2>') % _('Options')
|
||||
r += form.render()
|
||||
return r.getvalue()
|
||||
|
||||
def workflow_options(self):
|
||||
request = get_request()
|
||||
if request.get_method() == 'GET' and request.form.get('file'):
|
||||
|
|
|
@ -35,6 +35,7 @@ from qommon import get_logger
|
|||
from wcs.workflows import *
|
||||
from wcs.formdef import FormDef
|
||||
from wcs.formdata import Evolution
|
||||
from .fields import FieldDefPage, FieldsDirectory
|
||||
|
||||
|
||||
def svg(tag):
|
||||
|
@ -658,9 +659,97 @@ class WorkflowStatusDirectory(Directory):
|
|||
return redirect('..')
|
||||
|
||||
|
||||
class WorkflowVariableWidget(CompositeWidget):
|
||||
def __init__(self, name, value=None, workflow=None, **kwargs):
|
||||
CompositeWidget.__init__(self, name, **kwargs)
|
||||
if value and '*' in value:
|
||||
varname = None
|
||||
else:
|
||||
varname = value
|
||||
self.add(VarnameWidget, 'name', render_br=False, value=varname)
|
||||
options = []
|
||||
if workflow:
|
||||
for status in workflow.possible_status:
|
||||
for item in status.items:
|
||||
prefix = '%s*%s*' % (status.id, item.id)
|
||||
parameters = [x for x in item.get_parameters() if not getattr(item, x)]
|
||||
label = getattr(item, 'label', None) or _(item.description)
|
||||
for parameter in parameters:
|
||||
key = prefix + parameter
|
||||
fake_form = Form()
|
||||
item.add_parameters_widgets(fake_form, [parameter])
|
||||
parameter_label = fake_form.widgets[0].title
|
||||
option_value = '%s / %s / %s' % (status.name, label, parameter_label)
|
||||
options.append((key, option_value, key))
|
||||
if not options:
|
||||
return
|
||||
options = [('', '---', '')] + options
|
||||
self.widgets.append(HtmlWidget(
|
||||
_('or you can use this field to directly replace a workflow parameter:')))
|
||||
self.add(SingleSelectWidget, 'select', options=options,
|
||||
value=value,
|
||||
hint=_('This takes priority over a variable name'))
|
||||
|
||||
def _parse(self, request):
|
||||
super(WorkflowVariableWidget, self)._parse(request)
|
||||
if self.get('select'):
|
||||
self.value = self.get('select')
|
||||
elif self.get('name'):
|
||||
self.value = self.get('name')
|
||||
|
||||
|
||||
class WorkflowVariablesFieldDefPage(FieldDefPage):
|
||||
section = 'workflows'
|
||||
|
||||
def form(self):
|
||||
form = super(WorkflowVariablesFieldDefPage, self).form()
|
||||
form.remove('varname')
|
||||
form.add(WorkflowVariableWidget, 'varname', title=_('Variable'),
|
||||
value=self.field.varname, advanced=False, required=True,
|
||||
workflow=self.objectdef.workflow)
|
||||
return form
|
||||
|
||||
|
||||
class WorkflowVariablesFieldsDirectory(FieldsDirectory):
|
||||
_q_exports = ['', 'update_order', 'new']
|
||||
|
||||
section = 'settings'
|
||||
field_def_page_class = WorkflowVariablesFieldDefPage
|
||||
support_import = False
|
||||
blacklisted_types = ['page']
|
||||
|
||||
def index_top(self):
|
||||
r = TemplateIO(html=True)
|
||||
r += htmltext('<h2>%s - %s - %s</h2>') % (_('Workflow'),
|
||||
self.objectdef.name, _('Variables'))
|
||||
r += get_session().display_message()
|
||||
if not self.objectdef.fields:
|
||||
r += htmltext('<p>%s</p>') % _('There are not yet any variables.')
|
||||
return r.getvalue()
|
||||
|
||||
def index_bottom(self):
|
||||
pass
|
||||
|
||||
|
||||
class VariablesDirectory(Directory):
|
||||
_q_exports = ['', 'fields']
|
||||
|
||||
def __init__(self, workflow):
|
||||
self.workflow = workflow
|
||||
|
||||
def _q_index(self):
|
||||
return redirect('fields/')
|
||||
|
||||
def _q_traverse(self, path):
|
||||
get_response().breadcrumb.append(('variables/', _('Variables')))
|
||||
self.fields = WorkflowVariablesFieldsDirectory(
|
||||
WorkflowVariablesFieldsFormDef(self.workflow))
|
||||
return Directory._q_traverse(self, path)
|
||||
|
||||
|
||||
class WorkflowPage(Directory):
|
||||
_q_exports = ['', 'edit', 'delete', 'newstatus', ('status', 'status_dir'), 'update_order',
|
||||
'duplicate', 'export', 'svg']
|
||||
'duplicate', 'export', 'svg', ('variables', 'variables_dir')]
|
||||
|
||||
def __init__(self, component, html_top):
|
||||
try:
|
||||
|
@ -670,6 +759,7 @@ class WorkflowPage(Directory):
|
|||
self.html_top = html_top
|
||||
self.workflow_ui = WorkflowUI(self.workflow)
|
||||
self.status_dir = WorkflowStatusDirectory(self.workflow, html_top)
|
||||
self.variables_dir = VariablesDirectory(self.workflow)
|
||||
get_response().breadcrumb.append((component + '/', self.workflow.name))
|
||||
|
||||
def _q_index(self):
|
||||
|
@ -735,6 +825,23 @@ class WorkflowPage(Directory):
|
|||
r += htmltext('</li>')
|
||||
r += htmltext('</ul>')
|
||||
r += htmltext('</div>')
|
||||
|
||||
if not str(self.workflow.id).startswith('_'):
|
||||
r += htmltext('<div class="bo-block">')
|
||||
r += htmltext('<h3>%s') % _('Workflow Variables')
|
||||
r += htmltext(' <span class="change">(<a href="variables/">%s</a>)</span></h3>') % _('change')
|
||||
if self.workflow.variables_formdef:
|
||||
r += htmltext('<ul>')
|
||||
for field in self.workflow.variables_formdef.fields:
|
||||
if field.varname:
|
||||
if '*' in field.varname:
|
||||
r += htmltext('<li>%s</li>') % field.label
|
||||
else:
|
||||
r += htmltext('<li>%s (<code>%s</code>)</li>') % (field.label,
|
||||
field.varname)
|
||||
r += htmltext('</ul>')
|
||||
r += htmltext('</div>')
|
||||
|
||||
r += htmltext('</div>') # .splitcontent-right
|
||||
|
||||
r += htmltext('<br style="clear:both;"/>')
|
||||
|
|
|
@ -31,7 +31,6 @@ from qommon.substitution import Substitutions
|
|||
from formdata import FormData
|
||||
from roles import logged_users_role
|
||||
from categories import Category
|
||||
from wcs.workflows import Workflow, get_role_translation
|
||||
import fields
|
||||
|
||||
|
||||
|
@ -260,6 +259,7 @@ class FormDef(StorableObject):
|
|||
def get_workflow(self):
|
||||
if self._workflow:
|
||||
return self._workflow
|
||||
from wcs.workflows import Workflow
|
||||
if self.workflow_id:
|
||||
try:
|
||||
workflow = Workflow.get(self.workflow_id)
|
||||
|
@ -291,6 +291,41 @@ class FormDef(StorableObject):
|
|||
self.workflow_id = None
|
||||
workflow = property(get_workflow, set_workflow)
|
||||
|
||||
def get_variable_options(self):
|
||||
variables = {}
|
||||
if not self.workflow.variables_formdef:
|
||||
return variables
|
||||
if not self.workflow_options:
|
||||
return variables
|
||||
for field in self.workflow.variables_formdef.fields:
|
||||
if not field.varname:
|
||||
continue
|
||||
variables['form_option_' + field.varname] = self.workflow_options.get(field.varname)
|
||||
return variables
|
||||
|
||||
def get_variable_options_for_form(self):
|
||||
variables = {}
|
||||
if not self.workflow.variables_formdef:
|
||||
return variables
|
||||
if not self.workflow_options:
|
||||
return {}
|
||||
for field in self.workflow.variables_formdef.fields:
|
||||
if not field.varname:
|
||||
continue
|
||||
variables[str(field.id)] = self.workflow_options.get(field.varname)
|
||||
return variables
|
||||
|
||||
def set_variable_options(self, form):
|
||||
data = self.workflow.variables_formdef.get_data(form)
|
||||
variables = {}
|
||||
for field in self.workflow.variables_formdef.fields:
|
||||
if not field.varname:
|
||||
continue
|
||||
variables[field.varname] = data.get(field.id)
|
||||
if not self.workflow_options:
|
||||
self.workflow_options = {}
|
||||
self.workflow_options.update(variables)
|
||||
|
||||
def get_by_urlname(cls, url_name, ignore_migration=False):
|
||||
return cls.get_on_index(url_name, 'url_name', ignore_migration=ignore_migration)
|
||||
get_by_urlname = classmethod(get_by_urlname)
|
||||
|
@ -430,6 +465,9 @@ class FormDef(StorableObject):
|
|||
for field in self.fields:
|
||||
root['fields'].append(field.export_to_json(include_id=include_id))
|
||||
|
||||
if self.workflow_options:
|
||||
root['options'] = self.workflow_options
|
||||
|
||||
return json.dumps(root, indent=indent)
|
||||
|
||||
def import_from_json(cls, fd, charset=None, include_id=False):
|
||||
|
@ -466,6 +504,7 @@ class FormDef(StorableObject):
|
|||
formdef.workflow_id = value.get('workflow_id')
|
||||
elif 'workflow' in value:
|
||||
workflow = value.get('workflow')
|
||||
from wcs.workflows import Workflow
|
||||
for w in Workflow.select():
|
||||
if w.name == workflow:
|
||||
formdef.workflow_id = w.id
|
||||
|
@ -497,6 +536,9 @@ class FormDef(StorableObject):
|
|||
if formdef.fields and not formdef.max_field_id:
|
||||
formdef.max_field_id = max([lax_int(x.id) for x in formdef.fields])+1
|
||||
|
||||
if value.get('options'):
|
||||
formdef.workflow_options = value.get('options')
|
||||
|
||||
return formdef
|
||||
import_from_json = classmethod(import_from_json)
|
||||
|
||||
|
@ -548,6 +590,16 @@ class FormDef(StorableObject):
|
|||
for field in self.fields or []:
|
||||
fields.append(field.export_to_xml(charset=charset, include_id=include_id))
|
||||
|
||||
options = ET.SubElement(root, 'options')
|
||||
for option in self.workflow_options or []:
|
||||
element = ET.SubElement(options, 'option')
|
||||
element.attrib['varname'] = option
|
||||
option_value = self.workflow_options.get(option)
|
||||
if isinstance(option_value, basestring):
|
||||
element.text = self.workflow_options.get(option)
|
||||
else:
|
||||
pass # TODO: extend support to other types
|
||||
|
||||
return root
|
||||
|
||||
def import_from_xml(cls, fd, charset=None, include_id=False):
|
||||
|
@ -607,6 +659,10 @@ class FormDef(StorableObject):
|
|||
else:
|
||||
formdef.max_field_id = max([lax_int(x.id) for x in formdef.fields])+1
|
||||
|
||||
formdef.workflow_options = {}
|
||||
for option in tree.find('options') or []:
|
||||
formdef.workflow_options[option.attrib.get('varname')] = option.text
|
||||
|
||||
if tree.find('last_modification') is not None:
|
||||
node = tree.find('last_modification')
|
||||
formdef.last_modification_time = time.strptime(node.text, '%Y-%m-%d %H:%M:%S')
|
||||
|
@ -630,6 +686,7 @@ class FormDef(StorableObject):
|
|||
formdef.workflow_id = workflow_node.attrib.get('workflow_id')
|
||||
else:
|
||||
workflow = workflow_node.text.encode(charset)
|
||||
from wcs.workflows import Workflow
|
||||
for w in Workflow.select():
|
||||
if w.name == workflow:
|
||||
formdef.workflow_id = w.id
|
||||
|
@ -715,9 +772,9 @@ class FormDef(StorableObject):
|
|||
}
|
||||
if self.category:
|
||||
d.update(self.category.get_substitution_variables(minimal=minimal))
|
||||
d.update(self.get_variable_options())
|
||||
return d
|
||||
|
||||
|
||||
def get_detailed_evolution(self, formdata):
|
||||
if not formdata.evolution:
|
||||
return None
|
||||
|
@ -790,6 +847,7 @@ class FormDef(StorableObject):
|
|||
if self.acl_read == 'roles':
|
||||
form_roles = (self.roles or [])
|
||||
if formdata:
|
||||
from wcs.workflows import get_role_translation
|
||||
form_roles.extend([get_role_translation(formdata, x)
|
||||
for x in self.workflow_roles.keys() if x])
|
||||
form_roles = ensure_role_are_strings(form_roles)
|
||||
|
|
|
@ -683,6 +683,10 @@ class PicklableUpload(Upload):
|
|||
self.fp = cStringIO.StringIO(self.data)
|
||||
del self.data
|
||||
|
||||
def get_file(self):
|
||||
# quack like UploadedFile
|
||||
return self.get_file_pointer()
|
||||
|
||||
|
||||
class EmailWidget(StringWidget):
|
||||
HTML_TYPE = 'email'
|
||||
|
|
|
@ -33,6 +33,7 @@ from quixote.html import htmltext
|
|||
import qommon.errors
|
||||
|
||||
from wcs.roles import Role, logged_users_role, get_user_roles
|
||||
from wcs.formdef import FormDef
|
||||
from wcs.formdata import Evolution
|
||||
from wcs.fields import SubtitleField, TitleField, CommentField, PageField
|
||||
|
||||
|
@ -130,11 +131,35 @@ def get_varnames(fields):
|
|||
return varnames
|
||||
|
||||
|
||||
class WorkflowVariablesFieldsFormDef(FormDef):
|
||||
'''Class to handle workflow variables, it loads and saves from/to
|
||||
the workflow object 'variables_formdef' attribute.'''
|
||||
|
||||
def __init__(self, workflow):
|
||||
self.id = None
|
||||
self.name = workflow.name
|
||||
self.workflow = workflow
|
||||
if workflow.variables_formdef:
|
||||
self.fields = self.workflow.variables_formdef.fields
|
||||
self.max_field_id = self.workflow.variables_formdef.max_field_id
|
||||
else:
|
||||
self.fields = []
|
||||
|
||||
def store(self):
|
||||
for field in self.fields:
|
||||
if hasattr(field, 'widget_class'):
|
||||
if not field.varname:
|
||||
field.varname = misc.simplify(field.label, space='_')
|
||||
self.workflow.variables_formdef = self
|
||||
self.workflow.store()
|
||||
|
||||
|
||||
class Workflow(StorableObject):
|
||||
_names = 'workflows'
|
||||
name = None
|
||||
possible_status = None
|
||||
roles = None
|
||||
variables_formdef = None
|
||||
|
||||
last_modification_time = None
|
||||
last_modification_user_id = None
|
||||
|
@ -280,6 +305,15 @@ class Workflow(StorableObject):
|
|||
for status in self.possible_status:
|
||||
possible_status.append(status.export_to_xml(charset=charset,
|
||||
include_id=include_id))
|
||||
|
||||
if self.variables_formdef:
|
||||
variables = ET.SubElement(root, 'variables')
|
||||
formdef = ET.SubElement(variables, 'formdef')
|
||||
ET.SubElement(formdef, 'name').text = '-' # required by formdef xml import
|
||||
fields = ET.SubElement(formdef, 'fields')
|
||||
for field in self.variables_formdef.fields:
|
||||
fields.append(field.export_to_xml(charset=charset, include_id=include_id))
|
||||
|
||||
return root
|
||||
|
||||
def import_from_xml(cls, fd, include_id=False):
|
||||
|
@ -326,6 +360,13 @@ class Workflow(StorableObject):
|
|||
status_o.parent = workflow
|
||||
status_o.init_with_xml(status, charset, include_id=include_id)
|
||||
workflow.possible_status.append(status_o)
|
||||
|
||||
variables = tree.find('variables')
|
||||
if variables is not None:
|
||||
formdef = variables.find('formdef')
|
||||
imported_formdef = FormDef.import_from_xml_tree(formdef, include_id=True)
|
||||
workflow.variables_formdef = WorkflowVariablesFieldsFormDef(workflow=workflow)
|
||||
workflow.variables_formdef.fields = imported_formdef.fields
|
||||
return workflow
|
||||
import_from_xml_tree = classmethod(import_from_xml_tree)
|
||||
|
||||
|
|
Loading…
Reference in New Issue