wcs: add option to limit current forms cell to some categories (#17202)

This commit is contained in:
Frédéric Péters 2018-01-21 14:39:28 +01:00
parent 1f4cc0dc47
commit bb00745ced
3 changed files with 104 additions and 24 deletions

View File

@ -18,9 +18,11 @@ import django
from django import forms
from django.utils.datastructures import MultiValueDict
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from .models import WcsFormCell, WcsCategoryCell, WcsFormsOfCategoryCell
from .utils import get_wcs_options
from .models import (WcsFormCell, WcsCategoryCell, WcsFormsOfCategoryCell,
WcsCurrentFormsCell)
from .utils import get_wcs_options, get_wcs_services
class WcsFormCellForm(forms.ModelForm):
class Meta:
@ -98,3 +100,42 @@ class WcsFormsOfCategoryCellForm(forms.ModelForm):
self.fields['category_reference'].widget = forms.Select(choices=references,
attrs={'class': 'category-select'})
self.fields['manual_order'].widget = MultiSortWidget(choices=formdef_references)
class CategoriesSelectMultiple(forms.SelectMultiple):
def format_value(self, value):
# this converts data dictionary to list, for django >=1.11
return super(CategoriesSelectMultiple, self).format_value(
value.get('data') or [])
def render_options(self, choices, value):
# this converts data dictionary to list, for django <1.11
value = value.get('data') or []
return super(CategoriesSelectMultiple, self).render_options(choices, value)
def value_from_datadict(self, data, files, name):
if isinstance(data, MultiValueDict):
return {'data': data.getlist(name)}
return data.get(name, None)
class WcsCurrentFormsCellForm(forms.ModelForm):
class Meta:
model = WcsCurrentFormsCell
fields = ['wcs_site', 'categories', 'current_forms', 'done_forms']
def __init__(self, *args, **kwargs):
super(WcsCurrentFormsCellForm, self).__init__(*args, **kwargs)
if len(get_wcs_services()) == 1:
self.fields['wcs_site'].widget = forms.HiddenInput()
else:
combo_wcs_sites = [('', _('All'))]
wcs_sites = [(x, y.get('title')) for x, y in get_wcs_services().items()]
wcs_sites.sort(key=lambda x: x[1])
combo_wcs_sites.extend(wcs_sites)
self.fields['wcs_site'].widget = forms.Select(choices=combo_wcs_sites,
attrs={'class': 'wcs-site-select'})
categories = get_wcs_options('/api/categories/')
self.fields['categories'].help_text = _('By default forms from all categories are displayed.')
self.fields['categories'].widget = CategoriesSelectMultiple(choices=categories,
attrs={'class': 'categories-select'})

View File

@ -263,16 +263,16 @@ class WcsCurrentFormsCell(WcsUserDataBaseCell):
api_url = '/api/user/forms'
variable_name = 'user_forms'
categories = JSONField(blank=True)
current_forms = models.BooleanField(_('Current Forms'), default=True)
done_forms = models.BooleanField(_('Done Forms'), default=False)
class Meta:
verbose_name = _('User Forms')
def get_form_fields(self):
fields = super(WcsCurrentFormsCell, self).get_form_fields()
fields.extend(['current_forms', 'done_forms'])
return fields
def get_default_form_class(self):
from .forms import WcsCurrentFormsCellForm
return WcsCurrentFormsCellForm
@property
def template_name(self):
@ -296,18 +296,27 @@ class WcsCurrentFormsCell(WcsUserDataBaseCell):
def get_cell_extra_context(self, context):
context = super(WcsCurrentFormsCell, self).get_cell_extra_context(context)
categories_filter = {}
if self.categories:
for category in self.categories.get('data', []):
categories_filter[tuple(category.split(':'))] = True
if not (self.current_forms and self.done_forms):
for wcs_site in context['user_forms']:
if not context['user_forms'].get(wcs_site):
continue
if not context['user_forms'][wcs_site].get('data'):
continue
forms = context['user_forms'][wcs_site]['data']
if categories_filter:
forms = [x for x in forms if (wcs_site, x.get('category_slug')) in categories_filter]
if self.current_forms:
context['user_forms'][wcs_site]['data'] = [x for x in
context['user_forms'][wcs_site]['data'] if not x.get('form_status_is_endpoint')]
forms = [x for x in forms if not x.get('form_status_is_endpoint')]
elif self.done_forms:
context['user_forms'][wcs_site]['data'] = [x for x in
context['user_forms'][wcs_site]['data'] if x.get('form_status_is_endpoint')]
forms = [x for x in forms if x.get('form_status_is_endpoint')]
context['user_forms'][wcs_site]['data'] = forms # put it back
context['current_forms'] = context['user_forms'] # legacy
# regroup all forms in a flat list

View File

@ -294,20 +294,6 @@ def test_current_forms_cell_setup():
cell.done_forms = True
assert cell.get_additional_label() == 'All Sites - Done Forms'
try:
# check there is not wcs_site field if there's a single one defined in
# the configuration
temp_settings = settings.KNOWN_SERVICES.copy()
default = settings.KNOWN_SERVICES['wcs']['default']
settings.KNOWN_SERVICES = {'wcs': {'default': default}}
form_class = cell.get_default_form_class()
form = form_class()
assert not 'wcs_site' in form.fields.keys()
assert cell.get_additional_label() == 'Done Forms'
finally:
# restore original settings
settings.KNOWN_SERVICES = temp_settings
@wcsctl_present
def test_current_forms_cell_render(context):
page = Page(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
@ -354,6 +340,14 @@ def test_current_forms_cell_render(context):
assert len([x for x in extra_context['forms'] if x['site_slug'] == 'default']) == 5
assert len([x for x in extra_context['forms'] if x['site_slug'] == 'other']) == 5
# limit to a category
cell.categories = {'data': ['default:test-3']}
extra_context = cell.get_cell_extra_context(context)
assert len(extra_context['forms']) == 0
cell.categories = {'data': ['default:test-9']}
extra_context = cell.get_cell_extra_context(context)
assert len(extra_context['forms']) == 5
@wcsctl_present
def test_current_forms_cell_render_single_site(context):
page = Page(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
@ -493,3 +487,39 @@ def test_manager_forms_of_category_cell(app, admin_user):
resp.forms[0]['c%s-ordering' % cells[0].get_reference()].value = 'manual'
resp = resp.forms[0].submit()
assert resp.status_int == 302
@wcsctl_present
def test_manager_current_forms(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')
page.save()
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id)
resp = app.get(resp.html.find('option',
**{'data-add-url': re.compile('wcscurrentformscell')})['data-add-url'])
cells = page.get_cells()
assert len(cells) == 1
assert isinstance(cells[0], WcsCurrentFormsCell)
resp = app.get('/manage/pages/%s/' % page.id)
assert ('data-cell-reference="%s"' % cells[0].get_reference()) in resp.body
assert len(resp.form['c%s-categories' % cells[0].get_reference()].options) == 4
resp.form['c%s-categories' % cells[0].get_reference()].value = ['default:test-3', 'default:test-9']
resp = resp.form.submit().follow()
assert resp.form['c%s-categories' % cells[0].get_reference()].value == ['default:test-3', 'default:test-9']
# check wcs_site field is a select box
assert resp.form['c%s-wcs_site' % cells[0].get_reference()].tag == 'select'
try:
# check the wcs_site field is hidden if there's a single one defined in
# the configuration
temp_settings = settings.KNOWN_SERVICES.copy()
default = settings.KNOWN_SERVICES['wcs']['default']
settings.KNOWN_SERVICES = {'wcs': {'default': default}}
resp = app.get('/manage/pages/%s/' % page.id)
assert resp.form['c%s-wcs_site' % cells[0].get_reference()].attrs['type'] == 'hidden'
finally:
# restore original settings
settings.KNOWN_SERVICES = temp_settings