From bb00745cedcefabe3e403293630af9b23829148c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Sun, 21 Jan 2018 14:39:28 +0100 Subject: [PATCH] wcs: add option to limit current forms cell to some categories (#17202) --- combo/apps/wcs/forms.py | 45 +++++++++++++++++++++++++++++++++++-- combo/apps/wcs/models.py | 25 ++++++++++++++------- tests/test_wcs.py | 58 ++++++++++++++++++++++++++++++++++++------------ 3 files changed, 104 insertions(+), 24 deletions(-) diff --git a/combo/apps/wcs/forms.py b/combo/apps/wcs/forms.py index ca92074..c8ea33b 100644 --- a/combo/apps/wcs/forms.py +++ b/combo/apps/wcs/forms.py @@ -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'}) diff --git a/combo/apps/wcs/models.py b/combo/apps/wcs/models.py index 989b4eb..9658dd9 100644 --- a/combo/apps/wcs/models.py +++ b/combo/apps/wcs/models.py @@ -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 diff --git a/tests/test_wcs.py b/tests/test_wcs.py index 8a6a599..27e22e9 100644 --- a/tests/test_wcs.py +++ b/tests/test_wcs.py @@ -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 -- 2.15.1