0001-manager-add-a-visual-mark-to-cell-tabs-with-configur.patch
combo/apps/wcs/forms.py | ||
---|---|---|
50 | 50 | |
51 | 51 | |
52 | 52 |
class WcsCardsCellForm(forms.ModelForm): |
53 |
with_user = forms.BooleanField(label=_('Restrict to cards accessible to the user'), required=False) |
|
53 |
with_user = forms.BooleanField( |
|
54 |
label=_('Restrict to cards accessible to the user'), required=False, initial=True |
|
55 |
) |
|
54 | 56 | |
55 | 57 |
class Meta: |
56 | 58 |
model = WcsCardsCell |
... | ... | |
72 | 74 | |
73 | 75 | |
74 | 76 |
class WcsCardInfoCellForm(forms.ModelForm): |
75 |
with_user = forms.BooleanField(label=_('Restrict to cards accessible to the user'), required=False) |
|
77 |
with_user = forms.BooleanField( |
|
78 |
label=_('Restrict to cards accessible to the user'), required=False, initial=True |
|
79 |
) |
|
76 | 80 |
customize_display = forms.BooleanField(label=_('Customize display'), required=False) |
77 | 81 |
related_card_path = forms.ChoiceField(label=_('Card Identifier'), required=False) |
78 | 82 | |
... | ... | |
116 | 120 |
self.fields['related_card_path'].choices += [ |
117 | 121 |
('--', _('Identifier from page URL')), |
118 | 122 |
] |
123 |
self.fields['related_card_path'].initial = '--' |
|
119 | 124 |
if not self.instance.card_ids and not self.instance.related_card_path: |
120 | 125 |
self.initial['related_card_path'] = '--' |
121 | 126 |
self.fields['related_card_path'].choices += [ |
combo/data/forms.py | ||
---|---|---|
62 | 62 | |
63 | 63 |
def __init__(self, *args, **kwargs): |
64 | 64 |
super().__init__(*args, **kwargs) |
65 |
if self.instance.get_items_with_prefetch(): |
|
66 |
self.is_not_default = True |
|
65 | 67 | |
66 | 68 | |
67 | 69 |
class ConfigJsonForm(forms.ModelForm): |
combo/data/models.py | ||
---|---|---|
1784 | 1784 |
) |
1785 | 1785 | |
1786 | 1786 |
def get_items_with_prefetch(self): |
1787 |
return self.get_items(prefetch_validity_info=True) |
|
1787 |
if not hasattr(self, '_items_with_prefetch_cache'): |
|
1788 |
self._items_with_prefetch_cache = self.get_items(prefetch_validity_info=True) |
|
1789 |
return self._items_with_prefetch_cache |
|
1788 | 1790 | |
1789 | 1791 |
def get_additional_label(self): |
1790 | 1792 |
title = self.title |
combo/manager/forms.py | ||
---|---|---|
60 | 60 |
return templates |
61 | 61 | |
62 | 62 | |
63 |
def build_tab_is_not_default(form): |
|
64 |
if getattr(form, 'is_not_default', None) is True: |
|
65 |
return True |
|
66 |
for field_name, field in form.fields.items(): |
|
67 |
if field.initial is not None: |
|
68 |
if field.initial != form.initial.get(field_name): |
|
69 |
return True |
|
70 |
else: |
|
71 |
if bool(form.initial.get(field_name)): |
|
72 |
return True |
|
73 |
return False |
|
74 | ||
75 | ||
63 | 76 |
class PageDuplicateForm(forms.Form): |
64 | 77 |
title = forms.CharField(label=_('New title'), max_length=150, required=False) |
65 | 78 | |
... | ... | |
274 | 287 |
('groups-any', _('Users with one of these groups')), |
275 | 288 |
('groups-none', _('Users with none of these groups')), |
276 | 289 |
], |
290 |
initial='all', |
|
277 | 291 |
) |
278 | 292 |
groups = forms.MultipleChoiceField(label=_('Groups'), required=False, choices=get_groups_as_choices) |
279 | 293 |
combo/manager/static/js/combo.manager.js | ||
---|---|---|
275 | 275 |
$button.attr('disabled', null); |
276 | 276 |
for (const tab_slug in data.tabs) { |
277 | 277 |
var $tab_content = $form.find('[data-tab-slug="' + tab_slug + '"]'); |
278 |
if (data.tabs[tab_slug].indexOf('ckeditortype') == -1) { |
|
278 |
if (data.tabs[tab_slug].form.indexOf('ckeditortype') == -1) {
|
|
279 | 279 |
/* update form with new content, unless it has a ckeditor, as |
280 | 280 |
* this causes an unpleasant flickering */ |
281 |
$tab_content.html(data.tabs[tab_slug]); |
|
281 |
$tab_content.html(data.tabs[tab_slug].form);
|
|
282 | 282 |
} else { |
283 | 283 |
for (const error in data.errorlist[tab_slug]) { |
284 | 284 |
var $widget_p = $('[name="' + data.prefix + '-' + error).closest('p'); |
... | ... | |
289 | 289 |
$widget_p.before($widget_ul); |
290 | 290 |
} |
291 | 291 |
} |
292 |
if (data.tabs[tab_slug].is_not_default) { |
|
293 |
$('#tab-' + $cell.data('cell-reference') + '-' + tab_slug).addClass('pk-tabs--button-marker'); |
|
294 |
} else { |
|
295 |
$('#tab-' + $cell.data('cell-reference') + '-' + tab_slug).removeClass('pk-tabs--button-marker'); |
|
296 |
} |
|
292 | 297 |
} |
293 | 298 |
// update title labels |
294 | 299 |
$cell.find('.visibility-summary').removeClass( |
combo/manager/templates/combo/manager_edit_cell_block.html | ||
---|---|---|
5 | 5 |
{% for tab in manager_tabs %} |
6 | 6 |
<button role="tab" |
7 | 7 |
aria-selected="{{ forloop.first|yesno:"true,false" }}" |
8 |
aria-controls="panel-{{cell.get_reference}}-{{ forloop.counter }}" |
|
9 |
id="tab-{{cell.get_reference}}-{{ forloop.counter }}" |
|
10 |
tabindex="{{ forloop.first|yesno:"0,-1" }}">{{ tab.name }}</button> |
|
8 |
aria-controls="panel-{{ cell.get_reference }}-{{ tab.slug }}" |
|
9 |
id="tab-{{ cell.get_reference }}-{{ tab.slug }}" |
|
10 |
tabindex="{{ forloop.first|yesno:"0,-1" }}" |
|
11 |
{% if tab.is_not_default %}class="pk-tabs--button-marker"{% endif %}>{{ tab.name }}</button> |
|
11 | 12 |
{% endfor %} |
12 | 13 |
</div> |
13 | 14 | |
14 | 15 |
<form class="pk-tabs--container" action="{{ url }}" method="post"> |
15 | 16 |
{% csrf_token %} |
16 | 17 |
{% for tab in manager_tabs %} |
17 |
<div id="panel-{{cell.get_reference}}-{{forloop.counter}}"
|
|
18 |
<div id="panel-{{ cell.get_reference }}-{{ tab.slug }}"
|
|
18 | 19 |
role="tabpanel" tabindex="0" {% if not forloop.first %}hidden{% endif %} |
19 | 20 |
data-tab-slug="{{ tab.slug }}" |
20 |
aria-labelledby="tab-{{cell.get_reference}}-{{ forloop.counter }}">
|
|
21 |
aria-labelledby="tab-{{ cell.get_reference }}-{{ tab.slug }}">
|
|
21 | 22 |
{% if tab.template %}{% include tab.template %}{% else %}{{ tab.form_instance.as_p }}{% endif %} |
22 | 23 |
</div> |
23 | 24 |
{% endfor %} |
combo/manager/templatetags/cells.py | ||
---|---|---|
17 | 17 |
from django import forms, template |
18 | 18 |
from django.urls import reverse |
19 | 19 | |
20 |
from combo.manager.forms import build_tab_is_not_default |
|
21 | ||
20 | 22 |
register = template.Library() |
21 | 23 | |
22 | 24 | |
... | ... | |
37 | 39 |
if tab.get('fields'): |
38 | 40 |
tab['form'] = forms.models.modelform_factory(cell.__class__, fields=tab['fields']) |
39 | 41 |
tab['form_instance'] = tab['form'](initial={}, instance=cell, prefix='c%s' % cell.get_reference()) |
42 |
tab['is_not_default'] = build_tab_is_not_default(tab['form_instance']) |
|
40 | 43 |
context[form_name] = tab['form_instance'] |
41 | 44 |
context['cell'] = cell |
42 | 45 |
cell_form_template = template.loader.get_template('combo/manager_edit_cell_block.html') |
combo/manager/views.py | ||
---|---|---|
88 | 88 |
SiteExportForm, |
89 | 89 |
SiteImportForm, |
90 | 90 |
SiteSettingsForm, |
91 |
build_tab_is_not_default, |
|
91 | 92 |
) |
92 | 93 | |
93 | 94 | |
... | ... | |
736 | 737 |
form = tab_error_forms.get(tab['slug']) or tab['form']( |
737 | 738 |
instance=self.object, prefix=self.get_prefix(), initial={} |
738 | 739 |
) |
740 |
is_not_default = build_tab_is_not_default(form) |
|
739 | 741 |
if tab['slug'] == 'general': |
740 | 742 |
form_name = 'form' |
741 | 743 |
else: |
... | ... | |
745 | 747 |
cell_form_template = template.loader.get_template(tab['template']) |
746 | 748 |
else: |
747 | 749 |
cell_form_template = engines['django'].from_string('{{ %s.as_p }}' % form_name) |
748 |
response['tabs'][tab['slug']] = cell_form_template.render(context) |
|
750 |
response['tabs'][tab['slug']] = { |
|
751 |
'form': cell_form_template.render(context), |
|
752 |
'is_not_default': is_not_default, |
|
753 |
} |
|
749 | 754 | |
750 | 755 |
response['visibility_css_class'] = self.object.get_manager_visibility_css_class() |
751 | 756 |
response['visibility_content'] = self.object.get_manager_visibility_content() |
tests/test_dataviz.py | ||
---|---|---|
1624 | 1624 |
field_prefix = 'cdataviz_chartngcell-%s-' % cell.id |
1625 | 1625 |
resp.form[field_prefix + 'statistic'] = statistic.pk |
1626 | 1626 |
resp = app.post(resp.form.action, params=resp.form.submit_fields(), xhr=True) |
1627 |
assert 'time_interval' in resp.json['tabs']['general'] |
|
1628 |
assert 'This field is required.' not in resp.json['tabs']['general'] |
|
1627 |
assert 'time_interval' in resp.json['tabs']['general']['form']
|
|
1628 |
assert 'This field is required.' not in resp.json['tabs']['general']['form']
|
|
1629 | 1629 | |
1630 | 1630 | |
1631 | 1631 |
@with_httmock(new_api_mock) |
tests/test_manager.py | ||
---|---|---|
1778 | 1778 |
assert resp.form['c%s-test4' % cells[0].get_reference()].tag == 'textarea' |
1779 | 1779 |
resp.forms[0]['c%s-test4' % cells[0].get_reference()].value = 'Text Area' |
1780 | 1780 |
resp = manager_submit_cell(resp.form) |
1781 |
assert resp.json['tabs']['general'].strip().startswith('<p><label') |
|
1781 |
assert resp.json['tabs']['general']['form'].strip().startswith('<p><label')
|
|
1782 | 1782 | |
1783 | 1783 |
resp = app.get('/manage/pages/%s/' % page.id) |
1784 | 1784 |
assert resp.form['c%s-test' % cells[0].get_reference()].value == 'World Hello' |
... | ... | |
2628 | 2628 | |
2629 | 2629 |
def test_manager_link_cell_tabs(app, admin_user): |
2630 | 2630 |
page = Page.objects.create(title='One', slug='one', template_name='standard') |
2631 |
LinkCell.objects.create(order=0, placeholder='content', page=page) |
|
2631 |
cell = LinkCell.objects.create(order=0, placeholder='content', page=page) |
|
2632 | ||
2632 | 2633 |
app = login(app) |
2633 | 2634 |
resp = app.get('/manage/pages/%s/' % page.pk) |
2634 | ||
2635 |
assert not resp.pyquery('#tab-%s-general.pk-tabs--button-marker' % cell.get_reference()) |
|
2635 | 2636 |
assert resp.pyquery('[data-tab-slug="general"] input[name$="title"]') |
2637 |
assert not resp.pyquery('#tab-%s-visibility.pk-tabs--button-marker' % cell.get_reference()) |
|
2636 | 2638 |
assert not resp.pyquery('[data-tab-slug="appearance"] input[name$="title"]') |
2637 | 2639 | |
2640 |
cell.title = "Custom" |
|
2641 |
cell.public = False |
|
2642 |
cell.save() |
|
2643 |
resp = app.get('/manage/pages/%s/' % page.pk) |
|
2644 |
assert resp.pyquery('#tab-%s-general.pk-tabs--button-marker' % cell.get_reference()) |
|
2645 |
assert resp.pyquery('#tab-%s-visibility.pk-tabs--button-marker' % cell.get_reference()) |
|
2646 | ||
2638 | 2647 | |
2639 | 2648 |
def test_link_cell_validation(): |
2640 | 2649 |
form = LinkCellForm(data={'url': 'http://example.com'}) |
tests/test_wcs.py | ||
---|---|---|
35 | 35 |
WcsFormsOfCategoryCell, |
36 | 36 |
) |
37 | 37 |
from combo.data.library import get_cell_classes |
38 |
from combo.data.models import CellBase, LinkListCell, Page, ValidityInfo |
|
38 |
from combo.data.models import CellBase, LinkCell, LinkListCell, Page, ValidityInfo
|
|
39 | 39 |
from combo.utils import NothingInCacheException |
40 | 40 | |
41 | 41 |
from .test_manager import login |
... | ... | |
1649 | 1649 | |
1650 | 1650 |
def test_manager_cards_cell_tabs(app, admin_user): |
1651 | 1651 |
page = Page.objects.create(title='xxx', slug='test_cards_cell_save_cache', template_name='standard') |
1652 |
WcsCardsCell.objects.create(page=page, placeholder='content', order=0) |
|
1652 |
cell = WcsCardsCell.objects.create(page=page, placeholder='content', order=0)
|
|
1653 | 1653 |
login(app) |
1654 | 1654 | |
1655 | 1655 |
resp = app.get('/manage/pages/%s/' % page.pk) |
1656 | 1656 | |
1657 | 1657 |
assert not resp.pyquery('[data-tab-slug="general"] input[name$="custom_title"]') |
1658 |
assert not resp.pyquery('#tab-%s-general.pk-tabs--button-marker' % cell.get_reference()) |
|
1658 | 1659 |
assert resp.pyquery('[data-tab-slug="appearance"] input[name$="custom_title"]') |
1659 | 1660 | |
1660 | 1661 | |
... | ... | |
2481 | 2482 | |
2482 | 2483 |
def test_manager_card_cell_tabs(app, admin_user): |
2483 | 2484 |
page = Page.objects.create(title='xxx', slug='test_cards', template_name='standard', sub_slug='foobar') |
2484 |
WcsCardInfosCell.objects.create(page=page, placeholder='content', order=0) |
|
2485 |
cell = WcsCardInfosCell.objects.create(page=page, placeholder='content', order=0)
|
|
2485 | 2486 | |
2486 | 2487 |
app = login(app) |
2487 | 2488 |
resp = app.get('/manage/pages/%s/' % page.pk) |
2488 | 2489 | |
2489 | 2490 |
assert not resp.pyquery('[data-tab-slug="general"] select[name$="title_type"]') |
2490 | 2491 |
assert not resp.pyquery('[data-tab-slug="general"] input[name$="custom_title"]') |
2492 |
assert not resp.pyquery('#tab-%s-general.pk-tabs--button-marker' % cell.get_reference()) |
|
2491 | 2493 |
assert resp.pyquery('[data-tab-slug="appearance"] select[name$="title_type"]') |
2492 | 2494 |
assert resp.pyquery('[data-tab-slug="appearance"] input[name$="custom_title"]') |
2493 | 2495 | |
... | ... | |
4247 | 4249 | |
4248 | 4250 |
def test_manager_link_list_tabs(app, admin_user): |
4249 | 4251 |
page = Page.objects.create(title='One', slug='one', template_name='standard') |
4250 |
LinkListCell.objects.create(order=0, placeholder='content', page=page) |
|
4252 |
cell = LinkListCell.objects.create(order=0, placeholder='content', page=page)
|
|
4251 | 4253 |
app = login(app) |
4252 | 4254 |
resp = app.get('/manage/pages/%s/' % page.pk) |
4253 | 4255 | |
4254 | 4256 |
assert not resp.pyquery('[data-tab-slug="general"] input[name$="title"]') |
4257 |
assert not resp.pyquery('#tab-%s-general.pk-tabs--button-marker' % cell.get_reference()) |
|
4255 | 4258 |
assert resp.pyquery('[data-tab-slug="appearance"] input[name$="title"]') |
4256 | 4259 | |
4260 |
LinkCell.objects.create( |
|
4261 |
page=page, |
|
4262 |
placeholder=cell.link_placeholder, |
|
4263 |
title='Example Site', |
|
4264 |
url='http://example.net/', |
|
4265 |
link_page=page, |
|
4266 |
order=1, |
|
4267 |
) |
|
4268 |
resp = app.get('/manage/pages/%s/' % page.id) |
|
4269 |
assert resp.pyquery('#tab-%s-general.pk-tabs--button-marker' % cell.get_reference()) |
|
4270 | ||
4257 | 4271 | |
4258 | 4272 |
def test_import_export_pages_with_links(): |
4259 | 4273 |
page = Page(title='bar', slug='bar', order=1) |
tests/utils.py | ||
---|---|---|
9 | 9 |
pq = PyQuery(resp.body) |
10 | 10 |
resp2 = form.submit() |
11 | 11 |
for tab in resp2.json['tabs']: |
12 |
pq.find('form[action="%s"] [data-tab-slug="%s"]' % (action, tab)).html(resp2.json['tabs'][tab]) |
|
12 |
pq.find('form[action="%s"] [data-tab-slug="%s"]' % (action, tab)).html( |
|
13 |
resp2.json['tabs'][tab]['form'] |
|
14 |
) |
|
13 | 15 |
resp.text = pq.html() |
14 | 16 |
resp._forms_indexed = None |
15 | 17 |
assert expect_errors or not resp2.json['errorlist'], 'got unexpected errors' |
16 |
- |