workflows: add some options to add attachement action (#37860)

This commit is contained in:
Emmanuel Cazenave 2020-09-03 11:10:56 +02:00
parent f4ced75dd4
commit 809bc203e2
4 changed files with 107 additions and 47 deletions

View File

@ -3419,7 +3419,7 @@ def test_formdata_attachment_download(pub):
resp = resp.follow()
assert 'The form has been recorded' in resp.text
resp.forms[0]['attachment_attach'] = Upload('test.txt', b'foobar', 'text/plain')
resp.forms[0]['attachment_attach$file'] = Upload('test.txt', b'foobar', 'text/plain')
resp = resp.forms[0].submit('button_attach')
assert formdef.data_class().count() == 1
@ -3463,7 +3463,7 @@ def test_formdata_attachment_download_with_substitution_variable(pub):
resp = resp.follow()
assert 'The form has been recorded' in resp.text
resp.forms[0]['attachment_attach'] = Upload('test.txt', b'foobar', 'text/plain')
resp.forms[0]['attachment_attach$file'] = Upload('test.txt', b'foobar', 'text/plain')
resp = resp.forms[0].submit('button_attach')
assert formdef.data_class().count() == 1
@ -3529,7 +3529,7 @@ def test_formdata_attachment_download_to_backoffice_file_field(pub):
resp = resp.follow()
assert 'The form has been recorded' in resp.text
resp.forms[0]['attachment_attach'] = Upload('test.txt', b'foobar', 'text/plain')
resp.forms[0]['attachment_attach$file'] = Upload('test.txt', b'foobar', 'text/plain')
resp = resp.forms[0].submit('button_attach')
# backoffice file field is set
@ -3581,7 +3581,7 @@ def test_formdata_attachment_download_to_backoffice_file_field_only(pub):
resp = resp.follow()
assert 'The form has been recorded' in resp.text
resp.forms[0]['attachment_attach'] = Upload('test.txt', b'foobar', 'text/plain')
resp.forms[0]['attachment_attach$file'] = Upload('test.txt', b'foobar', 'text/plain')
resp = resp.forms[0].submit('button_attach')
# backoffice file field is set
@ -3598,6 +3598,39 @@ def test_formdata_attachment_download_to_backoffice_file_field_only(pub):
assert not evo.parts
def test_formdata_attachment_file_options(pub):
create_user(pub)
wf = Workflow(name='status')
st1 = wf.add_status('Status1', 'st1')
attach = AddAttachmentWorkflowStatusItem()
attach.id = '_attach'
attach.by = ['_submitter']
attach.document_type = {'label': 'Fichiers vidéo', 'mimetypes': ['video/*'], 'id': '_video'}
attach.max_file_size = '3Mo'
st1.items.append(attach)
attach.parent = st1
wf.store()
formdef = create_formdef()
formdef.workflow_id = wf.id
formdef.fields = []
formdef.store()
formdef.data_class().wipe()
resp = login(get_app(pub), username='foo', password='foo').get('/test/')
resp = resp.forms[0].submit('submit')
assert 'Check values then click submit.' in resp.text
resp = resp.forms[0].submit('submit')
assert resp.status_int == 302
resp = resp.follow()
assert 'The form has been recorded' in resp.text
file_input = resp.forms[0]['attachment_attach$file']
assert file_input.attrs['accept'] == 'video/*'
assert file_input.attrs['data-max-file-size'] == '3000000'
def test_formdata_generated_document_download(pub):
create_user(pub)
wf = Workflow(name='status')

View File

@ -38,7 +38,7 @@ from django.utils.six.moves.html_parser import HTMLParser
from .qommon import _, N_, force_str
from .qommon import evalutils
from .qommon.form import *
from .qommon.misc import localstrftime, strftime, date_format, ellipsize, xml_node_text, get_as_datetime
from .qommon.misc import localstrftime, strftime, date_format, ellipsize, xml_node_text, get_as_datetime, get_document_types, get_document_type_value_options
from .qommon.ods import NS as OD_NS, clean_text as od_clean_text
from .qommon.template import Template, TemplateError
from .qommon import get_cfg, get_logger
@ -1081,20 +1081,10 @@ class FileField(WidgetField):
def fill_admin_form(self, form):
WidgetField.fill_admin_form(self, form)
document_types = self.get_document_types()
cur_dt = self.document_type or {}
# SingleSelectWidget compare the value and not the keys, so if we want
# the current value not to be hidden, we must reset it with the corresponding
# value from settings based on the 'id'
document_type_id = cur_dt.get('id')
if document_type_id in document_types \
and cur_dt != document_types[document_type_id]:
cur_dt = document_types[document_type_id]
options = [(None, '---', {})]
options += [(doc_type, doc_type['label'], key) for key, doc_type in document_types.items()]
value, options = get_document_type_value_options(self.document_type)
form.add(SingleSelectWidget, 'document_type', title=_('File type suggestion'),
value=cur_dt, options=options,
advanced=not(cur_dt))
value=value, options=options,
advanced=not(value))
form.add(FileSizeWidget, 'max_file_size', title=_('Max file size'),
value=self.max_file_size,
advanced=not(self.max_file_size))
@ -1229,38 +1219,13 @@ class FileField(WidgetField):
if value and hasattr(value, 'token'):
get_request().form[self.field_key + '$token'] = value.token
def get_document_types(self):
document_types = {
'_audio': {
'label': _('Sound files'),
'mimetypes': ['audio/*'],
},
'_video': {
'label': _('Video files'),
'mimetypes': ['video/*'],
},
'_image': {
'label': _('Image files'),
'mimetypes': ['image/*'],
}
}
# Local document types
document_types.update(get_cfg('filetypes', {}))
for key, document_type in document_types.items():
document_type['id'] = key
# add current file type if it does not exist anymore in the settings
cur_dt = self.document_type or {}
if cur_dt and cur_dt['id'] not in document_types:
document_types[cur_dt['id']] = cur_dt
return document_types
def migrate(self):
changed = super(FileField, self).migrate()
if 'file_type' in self.__dict__:
self.document_type = {}
if self.__dict__['file_type']:
file_type = self.__dict__['file_type']
document_types = self.get_document_types()
document_types = get_document_types(self.document_type)
parts = []
for key, value in document_types.items():
if file_type == value.get('mimetypes'):

View File

@ -837,3 +837,44 @@ class QLookupRedirect:
def _q_traverse(self, path):
return redirect(self.url)
def get_document_types(document_type):
document_types = {
'_audio': {
'label': _('Sound files'),
'mimetypes': ['audio/*'],
},
'_video': {
'label': _('Video files'),
'mimetypes': ['video/*'],
},
'_image': {
'label': _('Image files'),
'mimetypes': ['image/*'],
}
}
# Local document types
document_types.update(get_cfg('filetypes', {}))
for key, document_type in document_types.items():
document_type['id'] = key
# add current file type if it does not exist anymore in the settings
cur_dt = document_type or {}
if cur_dt and cur_dt['id'] not in document_types:
document_types[cur_dt['id']] = cur_dt
return document_types
def get_document_type_value_options(document_type):
document_types = get_document_types(document_type)
cur_dt = document_type or {}
# SingleSelectWidget compare the value and not the keys, so if we want
# the current value not to be hidden, we must reset it with the corresponding
# value from settings based on the 'id'
document_type_id = cur_dt.get('id')
if document_type_id in document_types \
and cur_dt != document_types[document_type_id]:
cur_dt = document_types[document_type_id]
options = [(None, '---', {})]
options += [(doc_type, doc_type['label'], key) for key, doc_type in document_types.items()]
return cur_dt, options

View File

@ -20,7 +20,9 @@ from quixote import redirect
from ..qommon import _, N_
from wcs.workflows import *
from ..qommon import get_cfg
from ..qommon.errors import *
from ..qommon.misc import get_document_type_value_options
from wcs.forms.common import FormStatusPage, FileDirectory
from wcs.portfolio import has_portfolio, push_document
@ -86,6 +88,12 @@ class AddAttachmentWorkflowStatusItem(WorkflowStatusItem):
backoffice_filefield_id = None
attach_to_history = True # legacy choice
push_to_portfolio = False
document_type = None
max_file_size = None
def __init__(self, *args, **kwargs):
super(AddAttachmentWorkflowStatusItem, self).__init__(*args, **kwargs)
self.document_type = self.document_type or {}
@classmethod
def init(cls):
@ -106,8 +114,10 @@ class AddAttachmentWorkflowStatusItem(WorkflowStatusItem):
title = self.title or _('Upload File')
else:
title = None
form.add(FileWidget, 'attachment%s' % self.id, title=title,
required=self.required, hint=self.hint)
file_type = self.document_type.get('mimetypes')
form.add(FileWithPreviewWidget, 'attachment%s' % self.id, title=title,
required=self.required, hint=self.hint, file_type=file_type,
max_file_size=self.max_file_size)
if self.display_button:
form.add_submit('button%s' % self.id, self.button_label or _('Upload File'))
form.get_widget('button%s' % self.id).backoffice_info_text = self.backoffice_info_text
@ -139,7 +149,8 @@ class AddAttachmentWorkflowStatusItem(WorkflowStatusItem):
def get_parameters(self):
parameters = ('by', 'required', 'title', 'display_title', 'button_label',
'display_button', 'hint', 'backoffice_info_text',
'backoffice_filefield_id', 'varname', 'attach_to_history')
'backoffice_filefield_id', 'varname', 'attach_to_history', 'document_type',
'max_file_size')
if has_portfolio():
parameters += ('push_to_portfolio',)
parameters += ('condition',)
@ -191,6 +202,16 @@ class AddAttachmentWorkflowStatusItem(WorkflowStatusItem):
form.add(CheckboxWidget, '%spush_to_portfolio' % prefix,
title=_('Push to portfolio'),
value=self.push_to_portfolio)
if 'document_type' in parameters:
value, options = get_document_type_value_options(self.document_type)
form.add(SingleSelectWidget, 'document_type', title=_('File type suggestion'),
value=value, options=options,
advanced=not(value))
if 'max_file_size' in parameters:
form.add(FileSizeWidget, 'max_file_size', title=_('Max file size'),
value=self.max_file_size,
advanced=not(self.max_file_size))
register_item_class(AddAttachmentWorkflowStatusItem)