0001-wcs-add-display_mode-option-for-card-cell-68063.patch
combo/apps/wcs/forms.py | ||
---|---|---|
77 | 77 |
with_user = forms.BooleanField( |
78 | 78 |
label=_('Restrict to cards accessible to the user'), required=False, initial=True |
79 | 79 |
) |
80 |
customize_display = forms.BooleanField(label=_('Customize display'), required=False) |
|
81 | 80 |
related_card_path = forms.ChoiceField(label=_('Card Identifier'), required=False) |
82 | 81 | |
83 | 82 |
class Meta: |
... | ... | |
86 | 85 |
'carddef_reference', |
87 | 86 |
'related_card_path', |
88 | 87 |
'card_ids', |
89 |
'limit', |
|
90 | 88 |
'only_for_user', |
91 |
'custom_schema', |
|
92 | 89 |
) |
93 | 90 |
widgets = { |
94 | 91 |
'card_ids': forms.TextInput(attrs={'class': 'text-wide'}), |
95 |
'custom_schema': forms.HiddenInput(), |
|
96 | 92 |
} |
97 | 93 | |
98 | 94 |
def __init__(self, *args, **kwargs): |
99 | 95 |
instance = kwargs['instance'] |
100 | 96 |
initial = kwargs.pop('initial', {}) |
101 | 97 |
initial['with_user'] = not instance.without_user |
102 |
if kwargs.get('data'): |
|
103 |
kwargs['data'] = kwargs['data'].copy() # QueryDict -> dict |
|
104 |
# make sure there's a value for custom_schema as postgres.forms.jsonb |
|
105 |
# would crash on None. |
|
106 |
custom_schema_name = '%s-custom_schema' % kwargs.get('prefix') |
|
107 |
if custom_schema_name not in kwargs['data']: |
|
108 |
kwargs['data'][custom_schema_name] = '{}' |
|
109 | 98 |
super().__init__(initial=initial, *args, **kwargs) |
110 | 99 |
card_models = get_wcs_options('/api/cards/@list', include_custom_views=True) |
111 | 100 |
self.fields['carddef_reference'].widget = forms.Select(choices=card_models) |
112 |
if self.instance.custom_schema: |
|
113 |
self.initial['customize_display'] = True |
|
114 |
self.initial['custom_schema'] = self.instance.get_custom_schema() |
|
115 |
if not self.instance.cached_json: |
|
116 |
del self.fields['customize_display'] |
|
117 |
del self.fields['custom_schema'] |
|
118 | 101 | |
119 | 102 |
self.fields['related_card_path'].choices = [] |
120 | 103 |
with_sub_slug = any(p.sub_slug for p in self.instance.page.get_parents_and_self()) |
... | ... | |
132 | 115 | |
133 | 116 |
def save(self, *args, **kwargs): |
134 | 117 |
super().save(*args, **kwargs) |
135 |
if not self.cleaned_data.get('customize_display'): |
|
136 |
self.instance.custom_schema = {} |
|
137 | 118 |
if self.instance.related_card_path: |
138 | 119 |
self.instance.card_ids = '' |
139 | 120 |
if self.instance.related_card_path == '--': |
... | ... | |
151 | 132 |
return cleaned_data |
152 | 133 | |
153 | 134 | |
135 |
class WcsCardInfoCellDisplayForm(forms.ModelForm): |
|
136 |
customize_display = forms.BooleanField(label=_('Customize display'), required=False) |
|
137 | ||
138 |
class Meta: |
|
139 |
model = WcsCardInfosCell |
|
140 |
fields = ( |
|
141 |
'limit', |
|
142 |
'display_mode', |
|
143 |
'custom_schema', |
|
144 |
) |
|
145 |
widgets = { |
|
146 |
'custom_schema': forms.HiddenInput(), |
|
147 |
} |
|
148 | ||
149 |
def __init__(self, *args, **kwargs): |
|
150 |
if kwargs.get('data'): |
|
151 |
kwargs['data'] = kwargs['data'].copy() # QueryDict -> dict |
|
152 |
# make sure there's a value for custom_schema as postgres.forms.jsonb |
|
153 |
# would crash on None. |
|
154 |
custom_schema_name = '%s-custom_schema' % kwargs.get('prefix') |
|
155 |
if custom_schema_name not in kwargs['data']: |
|
156 |
kwargs['data'][custom_schema_name] = '{}' |
|
157 |
super().__init__(*args, **kwargs) |
|
158 |
if callable(self.fields['custom_schema'].initial): |
|
159 |
self.fields['custom_schema'].initial = {} |
|
160 |
if self.instance.custom_schema: |
|
161 |
self.initial['customize_display'] = True |
|
162 |
self.initial['custom_schema'] = self.instance.get_custom_schema() |
|
163 |
if not self.instance.cached_json: |
|
164 |
del self.fields['customize_display'] |
|
165 |
del self.fields['custom_schema'] |
|
166 | ||
167 |
def save(self, *args, **kwargs): |
|
168 |
super().save(*args, **kwargs) |
|
169 |
if not self.cleaned_data.get('customize_display'): |
|
170 |
self.instance.custom_schema = {} |
|
171 |
if self.cleaned_data.get('display_mode') == 'table': |
|
172 |
self.instance.custom_schema = {} |
|
173 |
self.instance.save() |
|
174 |
return self.instance |
|
175 | ||
176 | ||
154 | 177 |
class WcsCategoryCellForm(forms.ModelForm): |
155 | 178 |
class Meta: |
156 | 179 |
model = WcsCategoryCell |
combo/apps/wcs/migrations/0050_card_display_mode.py | ||
---|---|---|
1 |
from django.db import migrations, models |
|
2 | ||
3 | ||
4 |
class Migration(migrations.Migration): |
|
5 | ||
6 |
dependencies = [ |
|
7 |
('wcs', '0049_card_pagination'), |
|
8 |
] |
|
9 | ||
10 |
operations = [ |
|
11 |
migrations.AddField( |
|
12 |
model_name='wcscardinfoscell', |
|
13 |
name='display_mode', |
|
14 |
field=models.CharField( |
|
15 |
choices=[('card', 'Card'), ('table', 'Table')], |
|
16 |
default='card', |
|
17 |
max_length=10, |
|
18 |
verbose_name='Display mode', |
|
19 |
), |
|
20 |
), |
|
21 |
] |
combo/apps/wcs/models.py | ||
---|---|---|
946 | 946 |
_('Number of cards per page (default 10)'), null=True, blank=True |
947 | 947 |
) |
948 | 948 |
custom_schema = JSONField(blank=True, default=dict) |
949 |
display_mode = models.CharField( |
|
950 |
_('Display mode'), |
|
951 |
max_length=10, |
|
952 |
default='card', |
|
953 |
choices=[ |
|
954 |
('card', _('Card')), |
|
955 |
('table', _('Table')), |
|
956 |
], |
|
957 |
) |
|
949 | 958 | |
950 | 959 |
title_type = models.CharField( |
951 | 960 |
_('Title'), |
... | ... | |
966 | 975 |
is_enabled = classmethod(is_wcs_enabled) |
967 | 976 | |
968 | 977 |
default_template_name = 'combo/wcs/card.html' |
969 |
manager_form_template = 'combo/wcs/manager/card-infos-cell-form.html' |
|
970 | 978 |
manager_appearance_template = 'combo/wcs/manager/card-infos-cell-form-appearance.html' |
971 | 979 | |
972 | 980 |
class Meta: |
... | ... | |
1507 | 1515 |
def get_appearance_fields(self): |
1508 | 1516 |
return ['title_type', 'custom_title'] |
1509 | 1517 | |
1518 |
def get_manager_tabs(self): |
|
1519 |
from .forms import WcsCardInfoCellDisplayForm |
|
1520 | ||
1521 |
tabs = super().get_manager_tabs() |
|
1522 |
tabs.append( |
|
1523 |
{ |
|
1524 |
'slug': 'display', |
|
1525 |
'name': _('Display'), |
|
1526 |
'template': 'combo/wcs/manager/card-infos-cell-form-display.html', |
|
1527 |
'form': WcsCardInfoCellDisplayForm, |
|
1528 |
}, |
|
1529 |
) |
|
1530 |
return tabs |
|
1531 | ||
1510 | 1532 |
def get_custom_schema(self): |
1511 | 1533 |
custom_schema = self.custom_schema or {} |
1512 | 1534 |
combo/apps/wcs/templates/combo/wcs/manager/card-infos-cell-form.html → combo/apps/wcs/templates/combo/wcs/manager/card-infos-cell-form-display.html | ||
---|---|---|
1 |
{% extends "combo/cell_form.html" %} |
|
2 | 1 |
{% load i18n %} |
3 | 2 | |
4 |
{% block cell-form %} |
|
5 |
{{ block.super }} |
|
3 |
{{ display_form.as_p }} |
|
4 |
<script> |
|
5 |
{# display/hide custom_schema fields #} |
|
6 |
$('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-display_mode').on('change', function() { |
|
7 |
if ($(this).val() == 'card') { |
|
8 |
$('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-customize_display').parent().show(); |
|
9 |
if ($('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-customize_display').val()) { |
|
10 |
$('.wcs-cards-cell--grid', $('#id_cwcs_wcscardinfoscell-4-customize_display').parents('.cell')).show(); |
|
11 |
} |
|
12 |
} else { |
|
13 |
$('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-customize_display').parent().hide(); |
|
14 |
$('.wcs-cards-cell--grid', $('#id_cwcs_wcscardinfoscell-4-customize_display').parents('.cell')).hide(); |
|
15 |
} |
|
16 |
}); |
|
17 |
$('#id_cwcs_wcscardinfoscell-{{ cell.pk }}-display_mode').change(); |
|
18 |
</script> |
|
19 | ||
6 | 20 |
{% if card_schema %} |
7 | 21 |
{{ card_schema|json_script:card_schema_id }} |
8 | 22 | |
... | ... | |
166 | 180 |
</script> |
167 | 181 | |
168 | 182 |
{% endif %} |
169 |
{% endblock %} |
tests/test_wcs.py | ||
---|---|---|
21 | 21 |
from combo.apps.search.engines import engines |
22 | 22 |
from combo.apps.search.models import SearchCell |
23 | 23 |
from combo.apps.search.utils import index_site, search_site |
24 |
from combo.apps.wcs.forms import WcsCardInfoCellDisplayForm |
|
24 | 25 |
from combo.apps.wcs.models import ( |
25 | 26 |
BackofficeSubmissionCell, |
26 | 27 |
CategoriesCell, |
... | ... | |
2015 | 2016 |
('other:card_d', 'test2 : Card D'), |
2016 | 2017 |
('other:card_e', 'test2 : Card E'), |
2017 | 2018 |
] |
2018 |
assert 'customize_display' not in form.fields |
|
2019 |
assert 'custom_schema' not in form.fields |
|
2019 | ||
2020 |
form_display = WcsCardInfoCellDisplayForm(instance=cell) |
|
2021 |
assert 'customize_display' not in form_display.fields |
|
2022 |
assert 'custom_schema' not in form_display.fields |
|
2020 | 2023 | |
2021 | 2024 |
cell.save() |
2022 |
assert 'customize_display' not in form.fields |
|
2023 |
assert 'custom_schema' not in form.fields |
|
2025 |
assert 'customize_display' not in form_display.fields
|
|
2026 |
assert 'custom_schema' not in form_display.fields
|
|
2024 | 2027 | |
2025 | 2028 |
cell.carddef_reference = 'default:card_model_1' |
2026 | 2029 |
cell.save() |
2027 |
form = form_class(instance=cell)
|
|
2028 |
assert 'customize_display' in form.fields |
|
2029 |
assert 'custom_schema' in form.fields |
|
2030 |
assert 'customize_display' not in form.initial |
|
2031 |
assert form.initial['custom_schema'] == {} |
|
2030 |
form_display = WcsCardInfoCellDisplayForm(instance=cell)
|
|
2031 |
assert 'customize_display' in form_display.fields
|
|
2032 |
assert 'custom_schema' in form_display.fields
|
|
2033 |
assert 'customize_display' not in form_display.initial
|
|
2034 |
assert form_display.initial['custom_schema'] == {}
|
|
2032 | 2035 | |
2033 | 2036 |
cell.carddef_reference = 'default:card_model_1:foo' |
2034 | 2037 |
cell.save() |
2035 |
form = form_class(instance=cell)
|
|
2036 |
assert 'customize_display' in form.fields |
|
2037 |
assert 'custom_schema' in form.fields |
|
2038 |
assert 'customize_display' not in form.initial |
|
2039 |
assert form.initial['custom_schema'] == {} |
|
2038 |
form_display = WcsCardInfoCellDisplayForm(instance=cell)
|
|
2039 |
assert 'customize_display' in form_display.fields
|
|
2040 |
assert 'custom_schema' in form_display.fields
|
|
2041 |
assert 'customize_display' not in form_display.initial
|
|
2042 |
assert form_display.initial['custom_schema'] == {}
|
|
2040 | 2043 | |
2041 | 2044 |
cell.carddef_reference = 'default:card_model_1' |
2042 | 2045 |
cell.save() |
2043 | 2046 | |
2044 | 2047 |
cell.custom_schema = {'cells': [{'varname': 'foo', 'display_mode': 'value'}]} |
2045 | 2048 |
cell.save() |
2046 |
form = form_class(instance=cell)
|
|
2047 |
assert 'customize_display' in form.fields |
|
2048 |
assert 'custom_schema' in form.fields |
|
2049 |
assert form.initial['customize_display'] is True |
|
2050 |
assert form.initial['custom_schema'] == { |
|
2049 |
form_display = WcsCardInfoCellDisplayForm(instance=cell)
|
|
2050 |
assert 'customize_display' in form_display.fields
|
|
2051 |
assert 'custom_schema' in form_display.fields
|
|
2052 |
assert form_display.initial['customize_display'] is True
|
|
2053 |
assert form_display.initial['custom_schema'] == {
|
|
2051 | 2054 |
'cells': [ |
2052 | 2055 |
{'varname': 'foo', 'field_content': 'value', 'display_mode': 'text', 'empty_value': '@empty@'} |
2053 | 2056 |
] |
... | ... | |
2067 | 2070 |
cell.refresh_from_db() |
2068 | 2071 | |
2069 | 2072 |
# check getting back to uncustomized display reset the schema |
2070 |
cell.customize_display = True |
|
2071 | 2073 |
cell.custom_schema = { |
2072 | 2074 |
'cells': [ |
2073 | 2075 |
{'varname': 'foo', 'field_content': 'value', 'display_mode': 'text', 'empty_value': '@empty@'} |
... | ... | |
2082 | 2084 |
cell.refresh_from_db() |
2083 | 2085 |
assert cell.custom_schema == {} |
2084 | 2086 | |
2087 |
cell.custom_schema = { |
|
2088 |
'cells': [ |
|
2089 |
{'varname': 'foo', 'field_content': 'value', 'display_mode': 'text', 'empty_value': '@empty@'} |
|
2090 |
] |
|
2091 |
} |
|
2092 |
cell.save() |
|
2093 |
resp = app.get('/manage/pages/%s/' % page.pk) |
|
2094 |
assert resp.forms[0]['c%s-display_mode' % cell.get_reference()].value == 'card' |
|
2095 |
resp.forms[0]['c%s-display_mode' % cell.get_reference()].value = 'table' |
|
2096 |
manager_submit_cell(resp.forms[0]) |
|
2097 |
cell.refresh_from_db() |
|
2098 |
assert cell.custom_schema == {} |
|
2099 | ||
2085 | 2100 |
assert cell.related_card_path == '' |
2086 | 2101 |
assert cell.card_ids == '' |
2087 | 2102 |
resp = app.get('/manage/pages/%s/' % page.pk) |
... | ... | |
2541 | 2556 |
] |
2542 | 2557 | |
2543 | 2558 | |
2544 |
def test_manager_card_cell_tabs(app, admin_user): |
|
2559 |
@mock.patch('requests.Session.send', side_effect=mocked_requests_send) |
|
2560 |
def test_manager_card_cell_tabs(mock_send, app, admin_user): |
|
2545 | 2561 |
page = Page.objects.create(title='xxx', slug='test_cards', template_name='standard', sub_slug='foobar') |
2546 | 2562 |
cell = WcsCardInfosCell.objects.create(page=page, placeholder='content', order=0) |
2547 | 2563 | |
2548 | 2564 |
app = login(app) |
2549 | 2565 |
resp = app.get('/manage/pages/%s/' % page.pk) |
2550 | ||
2551 | 2566 |
assert not resp.pyquery('[data-tab-slug="general"] select[name$="title_type"]') |
2552 | 2567 |
assert not resp.pyquery('[data-tab-slug="general"] input[name$="custom_title"]') |
2568 |
assert not resp.pyquery('[data-tab-slug="general"] input[name$="limit"]') |
|
2553 | 2569 |
assert not resp.pyquery('#tab-%s-general.pk-tabs--button-marker' % cell.get_reference()) |
2554 | 2570 |
assert resp.pyquery('[data-tab-slug="appearance"] select[name$="title_type"]') |
2555 | 2571 |
assert resp.pyquery('[data-tab-slug="appearance"] input[name$="custom_title"]') |
2572 |
assert not resp.pyquery('[data-tab-slug="appearance"] input[name$="customize_display"]') |
|
2573 |
assert resp.pyquery('[data-tab-slug="display"] input[name$="limit"]') |
|
2574 | ||
2575 |
cell.carddef_reference = 'default:card_model_1' |
|
2576 |
cell.save() |
|
2577 |
resp = app.get('/manage/pages/%s/' % page.pk) |
|
2578 |
assert resp.pyquery('#tab-%s-general.pk-tabs--button-marker' % cell.get_reference()) |
|
2579 |
assert resp.pyquery('[data-tab-slug="display"] input[name$="customize_display"]') |
|
2556 | 2580 | |
2557 | 2581 | |
2558 | 2582 |
@mock.patch('requests.Session.send', side_effect=mocked_requests_send) |
2559 |
- |