0001-manager-use-sidetabs-to-navigate-between-cell-option.patch
combo/apps/maps/models.py | ||
---|---|---|
403 | 403 |
fields = ( |
404 | 404 |
'title', |
405 | 405 |
'initial_state', |
406 |
'initial_zoom', |
|
407 |
'min_zoom', |
|
408 |
'max_zoom', |
|
409 | 406 |
'group_markers', |
410 | 407 |
'marker_behaviour_onclick', |
411 | 408 |
) |
412 | 409 |
return forms.models.modelform_factory(self.__class__, fields=fields) |
413 | 410 | |
411 |
def get_manager_tabs(self): |
|
412 |
zoom_fields = ['initial_zoom', 'min_zoom', 'max_zoom'] |
|
413 |
tabs = super().get_manager_tabs() |
|
414 |
tabs.insert( |
|
415 |
1, |
|
416 |
{ |
|
417 |
'slug': 'zoom', |
|
418 |
'name': _('Zoom'), |
|
419 |
'form': forms.models.modelform_factory(self.__class__, fields=zoom_fields), |
|
420 |
}, |
|
421 |
) |
|
422 |
return tabs |
|
423 | ||
414 | 424 |
@classmethod |
415 | 425 |
def is_enabled(cls): |
416 | 426 |
return MapLayer.objects.exists() |
combo/data/models.py | ||
---|---|---|
781 | 781 | |
782 | 782 |
@python_2_unicode_compatible |
783 | 783 |
class CellBase(models.Model, metaclass=CellMeta): |
784 |
# noqa pylint: disable=too-many-public-methods |
|
784 | 785 | |
785 | 786 |
page = models.ForeignKey(Page, on_delete=models.CASCADE) |
786 | 787 |
placeholder = models.CharField(max_length=20) |
... | ... | |
803 | 804 |
default_form_class = None |
804 | 805 |
manager_form_factory_kwargs = {} |
805 | 806 |
manager_form_template = 'combo/cell_form.html' |
807 |
manager_visibility_template = 'combo/cell_visibility.html' |
|
808 |
manager_appearance_template = 'combo/cell_appearance.html' |
|
806 | 809 |
children_placeholder_prefix = None |
807 | 810 | |
808 | 811 |
visible = True |
... | ... | |
841 | 844 |
def get_additional_label(self): |
842 | 845 |
return '' |
843 | 846 | |
847 |
def get_manager_visibility_css_class(self): |
|
848 |
if self.public: |
|
849 |
return 'visibility-all' if not self.restricted_to_unlogged else '' |
|
850 |
elif self.restricted_to_unlogged: |
|
851 |
return 'visibility-off' |
|
852 |
return '' |
|
853 | ||
854 |
def get_manager_visibility_content(self): |
|
855 |
if self.public and not self.restricted_to_unlogged: |
|
856 |
return '' |
|
857 |
group_names = ', '.join([x.name for x in self.groups.all()]) |
|
858 |
if group_names: |
|
859 |
return group_names |
|
860 |
return _('unlogged users') if self.restricted_to_unlogged else _('logged users') |
|
861 | ||
844 | 862 |
@property |
845 | 863 |
def legacy_class_name(self): |
846 | 864 |
# legacy class name used in some themes |
... | ... | |
1063 | 1081 |
def get_label(self): |
1064 | 1082 |
return self.get_verbose_name() |
1065 | 1083 | |
1084 |
def get_manager_tabs(self): |
|
1085 |
from combo.manager.forms import CellVisibilityForm |
|
1086 | ||
1087 |
tabs = [] |
|
1088 |
form_class = self.get_default_form_class() |
|
1089 |
if form_class: |
|
1090 |
tabs.append( |
|
1091 |
{ |
|
1092 |
'slug': 'general', |
|
1093 |
'name': _('General'), |
|
1094 |
'template': self.manager_form_template, |
|
1095 |
'form': form_class, |
|
1096 |
} |
|
1097 |
) |
|
1098 |
tabs.append( |
|
1099 |
{ |
|
1100 |
'slug': 'visibility', |
|
1101 |
'name': _('Visibility'), |
|
1102 |
'template': self.manager_visibility_template, |
|
1103 |
'form': CellVisibilityForm, |
|
1104 |
} |
|
1105 |
) |
|
1106 |
tabs.append( |
|
1107 |
{ |
|
1108 |
'slug': 'appearance', |
|
1109 |
'name': _('Appearance'), |
|
1110 |
'template': self.manager_appearance_template, |
|
1111 |
'form': self.get_appearance_form_class(), |
|
1112 |
} |
|
1113 |
) |
|
1114 |
return tabs |
|
1115 | ||
1066 | 1116 |
def get_default_form_fields(self): |
1067 | 1117 |
return [ |
1068 | 1118 |
x.name |
... | ... | |
1083 | 1133 |
) |
1084 | 1134 |
] |
1085 | 1135 | |
1086 |
def get_default_form_class(self): |
|
1136 |
def get_default_form_class(self, fields=None):
|
|
1087 | 1137 |
if self.default_form_class: |
1088 | 1138 |
return self.default_form_class |
1089 | 1139 | |
1090 |
fields = self.get_default_form_fields() |
|
1091 | 1140 |
if not fields: |
1092 |
return None |
|
1141 |
fields = self.get_default_form_fields() |
|
1142 |
if not fields: |
|
1143 |
return None |
|
1093 | 1144 | |
1094 | 1145 |
return model_forms.modelform_factory( |
1095 | 1146 |
self.__class__, fields=fields, **self.manager_form_factory_kwargs |
1096 | 1147 |
) |
1097 | 1148 | |
1098 |
def get_options_form_class(self):
|
|
1149 |
def get_appearance_form_class(self):
|
|
1099 | 1150 |
fields = ['slug', 'extra_css_class'] |
1100 | 1151 |
widgets = None |
1101 | 1152 |
extra_templates = settings.COMBO_CELL_TEMPLATES.get(self.get_cell_type_str()) |
combo/manager/static/css/combo.manager.scss | ||
---|---|---|
1 |
// Only display content to screen readers |
|
2 |
@mixin sr-only { |
|
3 |
position: absolute !important; |
|
4 |
width: 1px !important; |
|
5 |
height: 1px !important; |
|
6 |
padding: 0 !important; |
|
7 |
margin: -1px !important; |
|
8 |
overflow: hidden !important; |
|
9 |
clip: rect(0, 0, 0, 0) !important; |
|
10 |
white-space: nowrap !important; |
|
11 |
border: 0 !important; |
|
12 |
} |
|
13 | ||
1 | 14 |
body.no-header #header { |
2 | 15 |
display: none; |
3 | 16 |
} |
... | ... | |
48 | 61 |
margin: 1ex 0; |
49 | 62 |
box-shadow: rgba(0, 0, 0, 0.04) 0px 1px 1px 0px; |
50 | 63 |
position: relative; |
64 |
> div { |
|
65 |
display: none; |
|
66 |
overflow: hidden; |
|
67 |
} |
|
68 |
&.toggled > div { |
|
69 |
display: block; |
|
70 |
} |
|
51 | 71 |
} |
52 | 72 | |
53 | 73 |
div.cell-list > div > div form { |
54 | 74 |
padding: 1ex; |
55 | 75 |
} |
56 | 76 | |
57 |
div.cell-list > div > div { |
|
58 |
display: none; |
|
59 |
transition: max-height linear 0.2s; |
|
60 |
overflow: hidden; |
|
61 |
} |
|
62 | ||
63 | 77 |
.cell-form textarea { |
64 | 78 |
width: 100%; |
65 | 79 |
} |
66 | 80 | |
67 |
div.cell-list > div.untoggled > div { |
|
68 |
display: block; |
|
69 |
max-height: 0; |
|
70 |
} |
|
71 | ||
72 |
div.cell-list > div.toggled > div { |
|
73 |
display: block; |
|
74 |
} |
|
75 | ||
76 | 81 |
div.cell > h3 { |
77 | 82 |
background: #fafafa; |
78 | 83 |
margin: 0; |
... | ... | |
132 | 137 | |
133 | 138 |
div.cell h3 span.visibility-summary::before, |
134 | 139 |
div.page span.visibility-summary::before { |
135 |
content: "\f06e"; /* fa-eye */ |
|
140 |
content: "\f06e "; /* fa-eye */
|
|
136 | 141 |
font-family: FontAwesome; |
137 | 142 |
} |
138 | 143 | |
139 | 144 |
div.cell h3 span.visibility-summary.visibility-off::before { |
140 |
content: "\f070"; /* fa-eye-slash */ |
|
145 |
content: "\f070 "; /* fa-eye-slash */
|
|
141 | 146 |
font-family: FontAwesome; |
142 | 147 |
} |
143 | 148 | |
149 |
div.cell h3 span.visibility-summary.visibility-all::before { |
|
150 |
content: none; |
|
151 |
} |
|
152 | ||
144 | 153 |
div.cell h3 span.visibility-summary { |
145 | 154 |
max-width: 30%; |
146 | 155 |
} |
... | ... | |
167 | 176 |
content: "\f106"; /* angle-up */ |
168 | 177 |
} |
169 | 178 | |
170 |
div.cell-list button.save { |
|
171 |
position: relative; |
|
172 |
right: 2ex; |
|
173 |
bottom: 1ex; |
|
174 |
float: right; |
|
175 |
} |
|
176 | ||
177 | ||
178 |
div.cell div.cell-buttons { |
|
179 |
clear: both; |
|
180 |
margin-top: 2em; |
|
181 |
margin-bottom: 1ex; |
|
182 |
} |
|
183 | ||
184 | 179 |
div.cell-list .empty-cell { |
185 | 180 |
list-style: none; |
186 | 181 |
margin: 0; |
... | ... | |
682 | 677 |
.search-engine-add { |
683 | 678 |
margin: 2em 0; |
684 | 679 |
} |
680 | ||
681 |
.cell-properties { |
|
682 |
.django-ckeditor-widget { |
|
683 |
display: block !important; |
|
684 |
} |
|
685 |
&--buttons { |
|
686 |
margin-top: 1em; |
|
687 |
display: flex; |
|
688 |
justify-content: space-between; |
|
689 |
} |
|
690 |
.duplicate-button { |
|
691 |
&::before { |
|
692 |
font-family: FontAwesome; |
|
693 |
content: "\f24d"; /* clone */ |
|
694 |
} |
|
695 |
span { |
|
696 |
@include sr-only(); |
|
697 |
} |
|
698 |
} |
|
699 |
.delete-button { |
|
700 |
&::before { |
|
701 |
font-family: FontAwesome; |
|
702 |
content: "\f014"; /* trash */ |
|
703 |
} |
|
704 |
span { |
|
705 |
@include sr-only(); |
|
706 |
} |
|
707 |
} |
|
708 |
} |
|
709 | ||
710 |
.cell.map .pk-tabs-container--content-panels .buttons { |
|
711 |
margin: 1em 0; |
|
712 |
} |
combo/manager/static/js/combo.manager.js | ||
---|---|---|
190 | 190 |
}); |
191 | 191 |
} |
192 | 192 | |
193 |
function compute_max_height($cell) { |
|
194 |
var cell_id = $cell.attr('id'); |
|
195 |
$('style#for-' + cell_id).remove(); |
|
196 |
var h = $cell.find('h3 + div').height() + 40; |
|
197 |
h += $cell.find('.multisort').length * 250; |
|
198 |
h += $cell.find('.django-ckeditor-widget').length * 200; |
|
199 |
var style = '<style id="for-' + cell_id + '">div#' + cell_id + '.toggled h3 + div { max-height: '+h+'px; }</style>'; |
|
200 |
$(style).appendTo('head'); |
|
201 |
} |
|
202 | ||
203 | 193 |
$(function() { |
204 | 194 |
$('div.cell-list h3').on('click', function() { |
205 | 195 |
$(this).parent().toggleClass('toggled').toggleClass('untoggled'); |
... | ... | |
270 | 260 |
$('div.cell button.save').on('click', function(event) { |
271 | 261 |
var $button = $(this); |
272 | 262 |
var $form = $(this).closest('form'); |
263 |
var $cell = $(this).closest('div.cell'); |
|
273 | 264 |
var button_label = $button.text(); |
274 | 265 |
for (instance in CKEDITOR.instances) { |
275 | 266 |
CKEDITOR.instances[instance].updateElement(); |
... | ... | |
281 | 272 |
beforeSend: function() { $button.attr('disabled', 'disabled'); }, |
282 | 273 |
success: function(data) { |
283 | 274 |
$button.attr('disabled', null); |
284 |
if (data.indexOf('ckeditortype') == -1) { |
|
285 |
/* update form with new content, unless it has a ckeditor, as |
|
286 |
* this causes an unpleasant flickering */ |
|
287 |
$button.parents('form').find('div.cell-form').html(data); |
|
288 |
compute_max_height($form.parents('div.cell')); |
|
289 |
} |
|
290 |
$form.parents('div.cell').trigger('combo:cellform-reloaded'); |
|
291 |
if (data.indexOf('class="errorlist"') == -1) { |
|
292 |
$.getJSON($form.data('label-url'), |
|
293 |
function(data) { |
|
294 |
$form.parents('div.cell').find('.additional-label i').text(data['label']); |
|
295 |
if (data['invalid_reason']) { |
|
296 |
if (! $form.parents('div.cell').find('.invalid').length) { |
|
297 |
$('<span class="invalid"></span>').insertAfter($form.parents('div.cell').find('.additional-label')); |
|
298 |
} |
|
299 |
$form.parents('div.cell').find('.invalid').text(data['invalid_reason']); |
|
300 |
} else { |
|
301 |
$form.parents('div.cell').find('.invalid').remove(); |
|
302 |
} |
|
275 |
for (const tab_slug in data.tabs) { |
|
276 |
var $tab_content = $form.find('[data-tab-slug="' + tab_slug + '"]'); |
|
277 |
if (data.tabs[tab_slug].indexOf('ckeditortype') == -1) { |
|
278 |
/* update form with new content, unless it has a ckeditor, as |
|
279 |
* this causes an unpleasant flickering */ |
|
280 |
$tab_content.html(data.tabs[tab_slug]); |
|
281 |
} else { |
|
282 |
for (const error in data.errorlist[tab_slug]) { |
|
283 |
var $widget_p = $('[name="' + data.prefix + '-' + error).closest('p'); |
|
284 |
var $widget_ul = $('<ul class="errorlist"></ul>'); |
|
285 |
for (idx in data.errorlist[form_slug][error]) { |
|
286 |
$widget_ul.append($('<li>', {text: data.errorlist[form_slug][error][idx]})); |
|
287 |
} |
|
288 |
$widget_p.before($widget_ul); |
|
303 | 289 |
} |
304 |
); |
|
290 |
} |
|
291 |
} |
|
292 |
// update title labels |
|
293 |
$cell.find('.visibility-summary').removeClass( |
|
294 |
).addClass('visibility-summary').addClass(data.visibility_css_class |
|
295 |
).text(data.visibility_content); |
|
296 |
function wrap(label, sign) { |
|
297 |
if (! label) return ''; |
|
298 |
if (sign == '(') return '(' + label + ')'; |
|
299 |
if (sign == '[') return '[' + label + ']'; |
|
300 |
return label; |
|
301 |
} |
|
302 |
$cell.find('h3 .cell-slug').text(wrap(data.slug, '[')); |
|
303 |
$cell.find('h3 .cell-template-label').text(wrap(data.template_label, '(')); |
|
304 |
$cell.find('h3 .extra-css-class').text(wrap(data.extra_css_class, '[')); |
|
305 |
$cell.find('h3 .additional-label i').text(wrap(data.additional_label)); |
|
306 |
if (data['invalid_reason']) { |
|
307 |
if (! $cell.find('.invalid').length) { |
|
308 |
$('<span class="invalid"></span>').insertAfter($cell.find('.additional-label')); |
|
309 |
} |
|
310 |
$cell.find('.invalid').text(data['invalid_reason']); |
|
311 |
} else { |
|
312 |
$cell.find('.invalid').remove(); |
|
313 |
} |
|
314 | ||
315 |
// select first panel with errors (if any) |
|
316 |
const $current_tab = $form.find('[role=tabpanel]:not([hidden])'); |
|
317 |
if ($current_tab.find('.errorlist').length == 0) { |
|
318 |
const $panel_with_error = $form.find('[role=tabpanel] .errorlist').first().parents('[role=tabpanel]').first(); |
|
319 |
if ($panel_with_error.length) { |
|
320 |
const $tab_button = $('[role=tab][aria-controls="' + $panel_with_error.attr('id') + '"]'); |
|
321 |
window.selectTab($tab_button[0]); |
|
322 |
} |
|
305 | 323 |
} |
306 | 324 |
} |
307 | 325 |
}); |
... | ... | |
334 | 352 | |
335 | 353 |
$('.cell.tipi-payment-form-cell select').on('change', function() { |
336 | 354 |
handle_tipi_form($(this)); |
337 |
compute_max_height($(this).parents('div.cell')); |
|
338 | 355 |
}); |
339 | 356 |
$('.cell.tipi-payment-form-cell select').trigger('change'); |
340 | 357 | |
... | ... | |
348 | 365 | |
349 | 366 |
$('div.cell').each(function(i, x) { |
350 | 367 |
const $cell = $(this); |
351 |
compute_max_height($cell); |
|
352 | 368 |
if (window.location.hash == '#' + $cell.attr('id')) { |
353 | 369 |
$cell.addClass('toggled'); |
354 | 370 |
} else { |
... | ... | |
720 | 736 | |
721 | 737 |
this.grid_cell__add(schema_cell); |
722 | 738 |
$(this.cell).trigger("custom_cell:change"); |
723 |
compute_max_height($(this.cell)); |
|
724 | 739 |
}, |
725 | 740 |
grid_cell__init: function() { |
726 | 741 |
if (!this.gridSchema_existing) return; |
... | ... | |
729 | 744 |
this.gridSchema.cells.forEach(function(el){ |
730 | 745 |
_self.grid_cell__add(el); |
731 | 746 |
}); |
732 | ||
733 |
$(this.cell).on("cell:open", function(){ |
|
734 |
compute_max_height($(this)); |
|
735 |
}) |
|
736 | 747 |
}, |
737 | 748 |
// Init methods |
738 | 749 |
on: function() { |
combo/manager/templates/combo/cell_appearance.html | ||
---|---|---|
1 |
{% load i18n %} |
|
2 |
{{ appearance_form.as_p }} |
|
3 |
{% if cell.can_have_assets %} |
|
4 |
<p><a rel="popup" data-selector="div#assets-listing" href="{% url 'combo-manager-slot-assets' cell_reference=cell.get_reference %}" |
|
5 |
>{% trans 'Assets' %}</a></p> |
|
6 |
{% endif %} |
combo/manager/templates/combo/cell_visibility.html | ||
---|---|---|
1 |
{% extends "combo/manager_base.html" %} |
|
2 |
{% load i18n %} |
|
3 | ||
4 |
{% block appbar %} |
|
5 |
<h2>{% trans 'Cell Visibility' %}</h2> |
|
6 |
{% endblock %} |
|
7 | ||
8 |
{% block content %} |
|
9 | ||
10 |
<form method="post" enctype="multipart/form-data" id="visibility-form"> |
|
11 |
{% csrf_token %} |
|
12 |
{{ form.as_p }} |
|
13 |
<div class="buttons"> |
|
14 |
<button class="submit-button">{% trans "Save" %}</button> |
|
15 |
{% if object.id %} |
|
16 |
<a class="cancel" href="{{ object.get_absolute_url }}">{% trans 'Cancel' %}</a> |
|
17 |
{% else %} |
|
18 |
<a class="cancel" href="{% url 'combo-manager-homepage' %}">{% trans 'Cancel' %}</a> |
|
19 |
{% endif %} |
|
20 |
</div> |
|
1 |
<div id="visibility-form-{{cell.get_reference}}"> |
|
2 |
{{ visibility_form.as_p }} |
|
21 | 3 |
<script> |
22 | 4 |
$(function() { |
23 |
var $form = $('#visibility-form'); |
|
5 |
var $form = $('#visibility-form-{{cell.get_reference}}');
|
|
24 | 6 |
$form.find('select').first().on('change', function() { |
25 | 7 |
var val = $(this).val(); |
26 | 8 |
var $groups = $form.find('select').last().parent('p'); |
... | ... | |
33 | 15 |
$form.find('select').first().trigger('change'); |
34 | 16 |
}); |
35 | 17 |
</script> |
36 |
</form> |
|
37 | ||
38 |
{% endblock %} |
|
18 |
</div> |
combo/manager/templates/combo/manager_edit_cell_block.html | ||
---|---|---|
1 | 1 |
{% load i18n %} |
2 | 2 |
{% block cell-form %} |
3 |
<form action="{{ url }}" method="post" data-label-url="{% url 'combo-manager-page-get-additional-label' page_pk=page.id cell_reference=cell.get_reference %}"> |
|
4 |
{% csrf_token %} |
|
5 |
{% if form %} |
|
6 |
<div class="cell-form"> |
|
7 |
{% block cell-form-content %} |
|
8 |
{% include cell.manager_form_template %} |
|
9 |
{% endblock %} |
|
3 |
<div class="cell-properties pk-tabs-container"> |
|
4 |
<div class="pk-tabs-container--tablist" role="tablist" aria-label="{% trans "Cell Properties" %}"> |
|
5 |
{% for tab in manager_tabs %} |
|
6 |
<button role="tab" |
|
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> |
|
11 |
{% endfor %} |
|
10 | 12 |
</div> |
11 |
{% else %} |
|
12 |
<p>{% trans "There are no options for this cell." %}</p> |
|
13 |
{% endif %} |
|
14 |
{% endblock %} |
|
15 |
<div class="cell-buttons"> |
|
13 | ||
14 |
<form class="pk-tabs-container--panels" action="{{ url }}" method="post"> |
|
15 |
{% csrf_token %} |
|
16 |
{% for tab in manager_tabs %} |
|
17 |
<div id="panel-{{cell.get_reference}}-{{forloop.counter}}" |
|
18 |
role="tabpanel" tabindex="0" {% if not forloop.first %}hidden{% endif %} |
|
19 |
data-tab-slug="{{ tab.slug }}" |
|
20 |
aria-labelledby="tab-{{cell.get_reference}}-{{ forloop.counter }}"> |
|
21 |
{% if tab.template %}{% include tab.template %}{% else %}{{ tab.form_instance.as_p }}{% endif %} |
|
22 |
</div> |
|
23 |
{% endfor %} |
|
24 |
<div class="cell-properties--buttons"> |
|
16 | 25 |
{% block cell-buttons %} |
17 |
<a rel="popup" href="{% url 'combo-manager-page-delete-cell' page_pk=page.id cell_reference=cell.get_reference %}">{% trans 'Delete' %}</a> |
|
|
18 |
<a rel="popup" href="{% url 'combo-manager-page-visibility-cell' page_pk=page.id cell_reference=cell.get_reference %}">{% trans 'Visibility' %}</a> |
|
|
19 |
<a rel="popup" href="{% url 'combo-manager-page-options-cell' page_pk=page.id cell_reference=cell.get_reference %}">{% trans 'Options' %}</a> |
|
|
20 |
{% if cell.can_have_assets %}<a rel="popup" data-selector="div#assets-listing" href="{% url 'combo-manager-slot-assets' cell_reference=cell.get_reference %}">{% trans 'Assets' %}</a> |{% endif %} |
|
21 |
<a rel="popup" href="{% url 'combo-manager-page-duplicate-cell' page_pk=page.id cell_reference=cell.get_reference %}">{% trans 'Duplicate' %}</a> | |
|
22 |
<a class="close-button" href="#">{% trans 'Close' %}</a>
|
|
23 |
{% if form %} |
|
24 |
<button class="save submit-button">{% trans 'Save' %}</button>
|
|
25 |
{% endif %} |
|
26 |
<button class="submit-button save">{% trans 'Save' %}</button>
|
|
27 |
<span>
|
|
28 |
<a class="pk-button duplicate-button" rel="popup" title="{% trans 'Duplicate' %}"
|
|
29 |
href="{% url 'combo-manager-page-duplicate-cell' page_pk=page.id cell_reference=cell.get_reference %}" |
|
30 |
><span>{% trans 'Duplicate' %}</span></a> |
|
31 |
<a class="pk-button delete-button" rel="popup" title="{% trans 'Delete' %}"
|
|
32 |
href="{% url 'combo-manager-page-delete-cell' page_pk=page.id cell_reference=cell.get_reference %}" |
|
33 |
><span>{% trans 'Delete' %}</span></a>
|
|
34 |
</span> |
|
26 | 35 |
{% endblock %} |
27 | 36 |
</div> |
28 | 37 |
</form> |
38 |
</div> |
|
39 |
{% endblock %} |
combo/manager/templates/combo/page_view.html | ||
---|---|---|
161 | 161 |
<div id="cell-{{cell.get_reference}}" class="cell {{cell.class_name}}" data-cell-reference="{{ cell.get_reference }}"> |
162 | 162 |
<h3><span class="handle">⣿</span> |
163 | 163 |
<span class="group1"> |
164 |
{{ cell.get_label }} |
|
165 |
{% if cell.template_name %} ({{cell.get_template_label}}){% endif %} |
|
166 |
{% if cell.slug %} [{{cell.slug}}] {% endif %} |
|
167 |
{% if cell.extra_css_class %} |
|
168 |
<span class="extra-css-class">[{{ cell.extra_css_class }}]</span> |
|
169 |
{% endif %} |
|
164 |
{{ cell.get_label }} |
|
165 |
<span class="cell-template-label" |
|
166 |
>{% if cell.template_name %}({{cell.get_template_label}}){% endif %}</span> |
|
167 |
<span class="cell-slug">{% if cell.slug %}[{{cell.slug}}]{% endif %}</span> |
|
168 |
<span class="extra-css-class">{% if cell.extra_css_class %}[{{ cell.extra_css_class }}]{% endif %}</span> |
|
170 | 169 |
<span class="additional-label"><i>{{cell.get_additional_label|default_if_none:""}}</i></span> |
171 | 170 |
{% if cell.get_invalid_reason %} |
172 | 171 |
<span class="invalid">{{ cell.get_invalid_reason }}{% if cell.class_name != 'link-list-cell' %} - |
... | ... | |
178 | 177 |
{% endif %}</span> |
179 | 178 |
{% endif %} |
180 | 179 |
</span> |
181 |
{% if not cell.public %} |
|
182 |
<span class="visibility-summary |
|
183 |
{% if cell.restricted_to_unlogged %}visibility-off{% endif %}" title="{% trans 'Restricted visibility' %}"> |
|
184 |
{% if cell.groups.all|length %} |
|
185 |
{% for group in cell.groups.all %}{{group.name}}{% if not forloop.last %}, {% endif %}{% endfor %} |
|
186 |
{% else %} |
|
187 |
{% trans "logged users" %} |
|
188 |
{% endif %} |
|
189 |
</span> |
|
190 |
{% elif cell.restricted_to_unlogged %} |
|
191 |
<span class="visibility-summary" title="{% trans 'Restricted visibility' %}"> |
|
192 |
{% trans "unlogged users" %} |
|
193 |
</span> |
|
194 |
{% endif %} |
|
180 |
<span class="visibility-summary {{ cell.get_manager_visibility_css_class }}" |
|
181 |
title="{% trans 'Restricted visibility' %}" |
|
182 |
>{{ cell.get_manager_visibility_content }}</span> |
|
195 | 183 |
</h3> |
196 | 184 |
<div>{% cell_form cell %}</div> |
197 | 185 |
</div> |
combo/manager/templatetags/cells.py | ||
---|---|---|
26 | 26 |
'combo-manager-page-edit-cell', |
27 | 27 |
kwargs={'page_pk': cell.page_id, 'cell_reference': cell.get_reference()}, |
28 | 28 |
) |
29 |
form_class = cell.get_default_form_class() |
|
30 |
if cell.is_enabled() and form_class: |
|
31 |
context['form'] = form_class(instance=cell, prefix='c%s' % cell.get_reference()) |
|
32 |
else: |
|
33 |
context['form'] = None |
|
29 |
context['manager_tabs'] = cell.get_manager_tabs() |
|
30 |
for tab in context['manager_tabs']: |
|
31 |
if tab['slug'] == 'general': |
|
32 |
form_name = 'form' |
|
33 |
if not cell.is_enabled(): |
|
34 |
continue |
|
35 |
else: |
|
36 |
form_name = '%s_form' % tab['slug'] |
|
37 |
tab['form_instance'] = tab['form'](initial={}, instance=cell, prefix='c%s' % cell.get_reference()) |
|
38 |
context[form_name] = tab['form_instance'] |
|
34 | 39 |
context['cell'] = cell |
35 | 40 |
cell_form_template = template.loader.get_template('combo/manager_edit_cell_block.html') |
36 | 41 |
with context.push(): |
combo/manager/urls.py | ||
---|---|---|
116 | 116 |
views.page_duplicate_cell, |
117 | 117 |
name='combo-manager-page-duplicate-cell', |
118 | 118 |
), |
119 |
url( |
|
120 |
r'^pages/(?P<page_pk>\d+)/cell/(?P<cell_reference>[\w_-]+)/options$', |
|
121 |
views.page_cell_options, |
|
122 |
name='combo-manager-page-options-cell', |
|
123 |
), |
|
124 |
url( |
|
125 |
r'^pages/(?P<page_pk>\d+)/cell/(?P<cell_reference>[\w_-]+)/visibility$', |
|
126 |
views.page_cell_visibility, |
|
127 |
name='combo-manager-page-visibility-cell', |
|
128 |
), |
|
129 |
url( |
|
130 |
r'^pages/(?P<page_pk>\d+)/cell/(?P<cell_reference>[\w_-]+)/label$', |
|
131 |
views.page_get_additional_label, |
|
132 |
name='combo-manager-page-get-additional-label', |
|
133 |
), |
|
134 | 119 |
url( |
135 | 120 |
r'^pages/(?P<page_pk>\d+)/cell/(?P<cell_reference>[\w_-]+)/add-link/(?P<link_code>[\w-]+)$', |
136 | 121 |
views.page_list_cell_add_link, |
combo/manager/views.py | ||
---|---|---|
20 | 20 |
import tarfile |
21 | 21 |
from operator import attrgetter, itemgetter |
22 | 22 | |
23 |
from django import template |
|
23 | 24 |
from django.conf import settings |
24 | 25 |
from django.contrib import messages |
25 | 26 |
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied |
26 | 27 |
from django.db import transaction |
27 |
from django.http import Http404, HttpResponse, HttpResponseRedirect |
|
28 |
from django.http import Http404, HttpResponse, HttpResponseRedirect, JsonResponse
|
|
28 | 29 |
from django.shortcuts import get_object_or_404, redirect, render |
30 |
from django.template import engines |
|
29 | 31 |
from django.urls import reverse, reverse_lazy |
30 | 32 |
from django.utils.encoding import force_bytes, force_text |
31 | 33 |
from django.utils.formats import date_format |
... | ... | |
61 | 63 | |
62 | 64 |
from .forms import ( |
63 | 65 |
CellDuplicateForm, |
64 |
CellVisibilityForm, |
|
65 | 66 |
PageAddForm, |
66 | 67 |
PageDuplicateForm, |
67 | 68 |
PageEditDescriptionForm, |
... | ... | |
664 | 665 | |
665 | 666 | |
666 | 667 |
class PageEditCellView(ManagedPageMixin, UpdateView): |
668 |
http_method_names = ['post'] |
|
669 | ||
667 | 670 |
def get_template_names(self): |
668 | 671 |
return [self.template_name or self.object.manager_form_template] |
669 | 672 | |
... | ... | |
685 | 688 |
def get_prefix(self): |
686 | 689 |
return 'c%s' % self.kwargs.get('cell_reference') |
687 | 690 | |
688 |
def get_form_class(self): |
|
689 |
return self.object.get_default_form_class() |
|
691 |
def post(self, request, *args, **kwargs): |
|
692 |
self.object = self.get_object() |
|
693 |
response = {'errorlist': {}, 'tabs': {}, 'prefix': self.get_prefix()} |
|
694 |
context = {} |
|
695 |
context['page'] = self.object.page |
|
696 |
context['cell'] = self.object |
|
697 |
context.update(self.object.get_extra_manager_context()) |
|
698 |
tab_error_forms = {} |
|
690 | 699 | |
691 |
def get_success_url(self): |
|
692 |
return ( |
|
693 |
reverse('combo-manager-page-view', kwargs={'pk': self.kwargs.get('page_pk')}) |
|
694 |
+ '#cell-' |
|
695 |
+ self.object.get_reference() |
|
696 |
) |
|
700 |
class Rollback(Exception): |
|
701 |
pass |
|
702 | ||
703 |
try: |
|
704 |
with transaction.atomic(): |
|
705 |
for tab in self.object.get_manager_tabs(): |
|
706 |
form = tab['form'](**self.get_form_kwargs()) |
|
707 |
if form.is_valid(): |
|
708 |
self.object = form.save() |
|
709 |
else: |
|
710 |
tab_error_forms[tab['slug']] = form |
|
711 |
response['errorlist'][tab['slug']] = form.errors |
|
712 |
self.object.refresh_from_db() |
|
713 |
if response['errorlist']: |
|
714 |
raise Rollback() |
|
715 |
except Rollback: |
|
716 |
pass |
|
717 | ||
718 |
for tab in self.object.get_manager_tabs(): |
|
719 |
# if current form had no errors, create it anew |
|
720 |
# so it can get new dynamic fields |
|
721 |
form = tab_error_forms.get(tab['slug']) or tab['form'](**self.get_form_kwargs()) |
|
722 |
if tab['slug'] == 'general': |
|
723 |
form_name = 'form' |
|
724 |
else: |
|
725 |
form_name = '%s_form' % tab['slug'] |
|
726 |
context[form_name] = form |
|
727 |
if tab.get('template'): |
|
728 |
cell_form_template = template.loader.get_template(tab['template']) |
|
729 |
else: |
|
730 |
cell_form_template = engines['django'].from_string('{{ %s.as_p }}' % form_name) |
|
731 |
response['tabs'][tab['slug']] = cell_form_template.render(context) |
|
732 | ||
733 |
response['visibility_css_class'] = self.object.get_manager_visibility_css_class() |
|
734 |
response['visibility_content'] = self.object.get_manager_visibility_content() |
|
735 |
response['extra_css_class'] = self.object.extra_css_class |
|
736 |
response['slug'] = self.object.slug |
|
737 |
response['template_label'] = self.object.get_template_label() |
|
738 |
response['additional_label'] = self.object.get_additional_label() |
|
739 |
response['invalid_reason'] = self.object.get_invalid_reason() |
|
740 | ||
741 |
if not response['errorlist']: |
|
742 |
PageSnapshot.take( |
|
743 |
self.object.page, request=self.request, comment=_('changed cell "%s"') % self.object |
|
744 |
) |
|
745 |
return JsonResponse(response) |
|
697 | 746 | |
698 | 747 |
def form_valid(self, form): |
699 | 748 |
if self.request.is_ajax(): |
... | ... | |
787 | 836 |
page_duplicate_cell = PageDuplicateCellView.as_view() |
788 | 837 | |
789 | 838 | |
790 |
class PageCellVisibilityView(PageEditCellView): |
|
791 |
template_name = 'combo/cell_visibility.html' |
|
792 | ||
793 |
def get_form_class(self): |
|
794 |
return CellVisibilityForm |
|
795 | ||
796 | ||
797 |
page_cell_visibility = PageCellVisibilityView.as_view() |
|
798 | ||
799 | ||
800 |
class PageCellOptionsView(PageEditCellView): |
|
801 |
template_name = 'combo/cell_options.html' |
|
802 | ||
803 |
def get_form_class(self): |
|
804 |
return self.object.get_options_form_class() |
|
805 | ||
806 | ||
807 |
page_cell_options = PageCellOptionsView.as_view() |
|
808 | ||
809 | ||
810 | 839 |
class PageCellOrder(ManagedPageMixin, View): |
811 | 840 |
def get(self, *args, **kwargs): |
812 | 841 |
request = self.request |
... | ... | |
877 | 906 |
return redirect(reverse('combo-manager-homepage')) |
878 | 907 | |
879 | 908 | |
880 |
def page_get_additional_label(request, page_pk, cell_reference): |
|
881 |
cell = CellBase.get_cell(cell_reference, page_id=page_pk) |
|
882 |
response = HttpResponse(content_type='application/json') |
|
883 |
json.dump( |
|
884 |
{ |
|
885 |
'label': force_text(cell.get_additional_label()) or '', |
|
886 |
'invalid_reason': force_text(cell.get_invalid_reason() or ''), |
|
887 |
}, |
|
888 |
response, |
|
889 |
) |
|
890 |
return response |
|
891 | ||
892 | ||
893 | 909 |
def menu_json(request): |
894 | 910 |
if settings.TEMPLATE_VARS.get('site_title'): |
895 | 911 |
label = _('Editing "%(site_title)s"') % settings.TEMPLATE_VARS |
combo/settings.py | ||
---|---|---|
186 | 186 |
], |
187 | 187 |
'toolbar': 'Own', |
188 | 188 |
'resize_enabled': False, |
189 |
'width': '100%', |
|
189 | 190 |
}, |
190 | 191 |
} |
191 | 192 |
combo/utils/forms.py | ||
---|---|---|
65 | 65 | |
66 | 66 |
def value_from_datadict(self, data, files, name): |
67 | 67 |
if isinstance(data, MultiValueDict): |
68 |
return {'data': data.getlist(name)}
|
|
68 |
return json.dumps({'data': data.getlist(name)})
|
|
69 | 69 |
return data.get(name, None) |
70 | 70 | |
71 | 71 |
def format_value(self, value): |
tests/test_dataviz.py | ||
---|---|---|
15 | 15 |
from combo.utils.spooler import refresh_statistics_data |
16 | 16 | |
17 | 17 |
from .test_public import login |
18 |
from .utils import manager_submit_cell |
|
18 | 19 | |
19 | 20 |
pytestmark = pytest.mark.django_db |
20 | 21 | |
... | ... | |
1296 | 1297 |
('combo', False, 'Combo'), |
1297 | 1298 |
] |
1298 | 1299 |
resp.form[field_prefix + 'service'] = '' |
1299 |
resp = resp.form.submit().follow()
|
|
1300 |
manager_submit_cell(resp.form)
|
|
1300 | 1301 |
assert resp.form[field_prefix + 'service'].value == '' |
1301 | 1302 | |
1302 | 1303 |
resp.form[field_prefix + 'ou'] = 'default' |
1303 |
resp = resp.form.submit().follow()
|
|
1304 |
manager_submit_cell(resp.form)
|
|
1304 | 1305 |
assert resp.form[field_prefix + 'ou'].value == 'default' |
1305 | 1306 |
cell.refresh_from_db() |
1306 | 1307 |
assert cell.get_filter_params() == {'ou': 'default', 'time_interval': 'month'} |
... | ... | |
1318 | 1319 |
] |
1319 | 1320 | |
1320 | 1321 |
resp.form[field_prefix + 'ou'] = '' |
1321 |
resp = resp.form.submit().follow()
|
|
1322 |
manager_submit_cell(resp.form)
|
|
1322 | 1323 |
assert resp.form[field_prefix + 'ou'].value == '' |
1323 | 1324 |
cell.refresh_from_db() |
1324 | 1325 |
assert cell.get_filter_params() == {'time_interval': 'month'} |
1325 | 1326 | |
1326 | 1327 |
resp.form[field_prefix + 'time_range'] = 'previous-year' |
1327 |
resp = resp.form.submit().follow()
|
|
1328 |
manager_submit_cell(resp.form)
|
|
1328 | 1329 |
cell.refresh_from_db() |
1329 | 1330 |
assert cell.time_range == 'previous-year' |
1330 | 1331 | |
1331 | 1332 |
resp.form[field_prefix + 'time_range'] = 'range' |
1332 | 1333 |
resp.form[field_prefix + 'time_range_start'] = '2020-10-01' |
1333 | 1334 |
resp.form[field_prefix + 'time_range_end'] = '2020-11-03' |
1334 |
resp = resp.form.submit().follow()
|
|
1335 |
manager_submit_cell(resp.form)
|
|
1335 | 1336 |
cell.refresh_from_db() |
1336 | 1337 |
assert cell.time_range == 'range' |
1337 | 1338 |
assert cell.time_range_start == date(year=2020, month=10, day=1) |
... | ... | |
1339 | 1340 | |
1340 | 1341 |
resp.form[field_prefix + 'time_range_start'] = '' |
1341 | 1342 |
resp.form[field_prefix + 'time_range_end'] = '' |
1342 |
resp = resp.form.submit().follow()
|
|
1343 |
manager_submit_cell(resp.form)
|
|
1343 | 1344 |
cell.refresh_from_db() |
1344 | 1345 |
assert cell.time_range_start is None |
1345 | 1346 |
assert cell.time_range_end is None |
1346 | 1347 | |
1347 | 1348 |
no_filters_stat = Statistic.objects.get(slug='two-series') |
1348 | 1349 |
resp.form[field_prefix + 'statistic'] = no_filters_stat.pk |
1349 |
resp = resp.form.submit().follow()
|
|
1350 |
manager_submit_cell(resp.form)
|
|
1350 | 1351 |
assert resp.form[field_prefix + 'statistic'].value == str(no_filters_stat.pk) |
1351 | 1352 |
assert field_prefix + 'time_interval' not in resp.form.fields |
1352 | 1353 |
assert field_prefix + 'ou' not in resp.form.fields |
... | ... | |
1356 | 1357 | |
1357 | 1358 |
filter_multiple_stat = Statistic.objects.get(slug='filter-multiple') |
1358 | 1359 |
resp.form[field_prefix + 'statistic'] = filter_multiple_stat.pk |
1359 |
resp = resp.form.submit().follow()
|
|
1360 |
manager_submit_cell(resp.form)
|
|
1360 | 1361 |
resp.form[field_prefix + 'color'].select_multiple(texts=['Blue', 'Green']) |
1361 |
resp = resp.form.submit().follow()
|
|
1362 |
manager_submit_cell(resp.form)
|
|
1362 | 1363 |
assert resp.form[field_prefix + 'color'].value == ['green', 'blue'] |
1363 | 1364 |
cell.refresh_from_db() |
1364 | 1365 |
assert cell.filter_params == {'color': ['green', 'blue']} |
... | ... | |
1376 | 1377 |
] |
1377 | 1378 | |
1378 | 1379 |
resp.form[field_prefix + 'color'].select_multiple(texts=[]) |
1379 |
resp = resp.form.submit().follow()
|
|
1380 |
manager_submit_cell(resp.form)
|
|
1380 | 1381 |
assert resp.form[field_prefix + 'color'].value is None |
1381 | 1382 |
cell.refresh_from_db() |
1382 | 1383 |
assert cell.get_filter_params() == {} |
... | ... | |
1440 | 1441 | |
1441 | 1442 |
# choice with no subfilter |
1442 | 1443 |
resp.form[field_prefix + 'form'] = 'contact' |
1443 |
resp = resp.form.submit().follow()
|
|
1444 |
manager_submit_cell(resp.form)
|
|
1444 | 1445 | |
1445 | 1446 |
assert len(new_api_mock.call['requests']) == 1 |
1446 | 1447 |
assert 'menu' not in resp.form.fields |
1447 | 1448 | |
1448 | 1449 |
resp.form[field_prefix + 'form'] = 'error' |
1449 |
resp = resp.form.submit().follow()
|
|
1450 |
manager_submit_cell(resp.form)
|
|
1450 | 1451 | |
1451 | 1452 |
assert len(new_api_mock.call['requests']) == 2 |
1452 | 1453 |
assert 'menu' not in resp.form.fields |
1453 | 1454 | |
1454 | 1455 |
# choice with subfilter |
1455 | 1456 |
resp.form[field_prefix + 'form'] = 'food-request' |
1456 |
resp = resp.form.submit().follow()
|
|
1457 |
manager_submit_cell(resp.form)
|
|
1457 | 1458 | |
1458 | 1459 |
assert len(new_api_mock.call['requests']) == 3 |
1459 | 1460 |
menu_field = resp.form[field_prefix + 'menu'] |
... | ... | |
1465 | 1466 |
] |
1466 | 1467 | |
1467 | 1468 |
resp.form[field_prefix + 'menu'] = 'meat' |
1468 |
resp = resp.form.submit().follow()
|
|
1469 |
manager_submit_cell(resp.form)
|
|
1469 | 1470 |
assert resp.form[field_prefix + 'menu'].value == 'meat' |
1470 | 1471 |
cell.refresh_from_db() |
1471 | 1472 |
assert cell.get_filter_params() == {'form': 'food-request', 'menu': 'meat'} |
1472 | 1473 | |
1473 | 1474 |
# choice with no subfilter |
1474 | 1475 |
resp.form[field_prefix + 'form'] = 'contact' |
1475 |
resp = resp.form.submit().follow()
|
|
1476 |
manager_submit_cell(resp.form)
|
|
1476 | 1477 | |
1477 | 1478 |
assert len(new_api_mock.call['requests']) == 4 |
1478 | 1479 |
assert 'menu' not in resp.form.fields |
... | ... | |
1481 | 1482 | |
1482 | 1483 |
# changing another filter doesn't trigger request |
1483 | 1484 |
resp.form[field_prefix + 'other'] = 'one' |
1484 |
resp = resp.form.submit().follow()
|
|
1485 |
resp = resp.form.submit() |
|
1485 | 1486 |
assert len(new_api_mock.call['requests']) == 4 |
1486 | 1487 | |
1487 | 1488 | |
... | ... | |
1500 | 1501 |
resp.form[field_prefix + 'time_range'] = 'range-template' |
1501 | 1502 |
resp.form[field_prefix + 'time_range_start_template'] = 'today|add_days:"7"|adjust_to_week_monday' |
1502 | 1503 |
resp.form[field_prefix + 'time_range_end_template'] = 'now|add_days:"14"|adjust_to_week_monday' |
1503 |
resp = resp.form.submit().follow()
|
|
1504 |
manager_submit_cell(resp.form)
|
|
1504 | 1505 |
cell.refresh_from_db() |
1505 | 1506 |
assert cell.time_range == 'range-template' |
1506 | 1507 |
assert cell.time_range_start_template == 'today|add_days:"7"|adjust_to_week_monday' |
... | ... | |
1508 | 1509 | |
1509 | 1510 |
resp.form[field_prefix + 'time_range_start_template'] = '' |
1510 | 1511 |
resp.form[field_prefix + 'time_range_end_template'] = '' |
1511 |
resp = resp.form.submit().follow()
|
|
1512 |
manager_submit_cell(resp.form)
|
|
1512 | 1513 |
cell.refresh_from_db() |
1513 | 1514 |
assert cell.time_range_start_template == '' |
1514 | 1515 |
assert cell.time_range_end_template == '' |
1515 | 1516 | |
1516 | 1517 |
resp.form[field_prefix + 'time_range_start_template'] = 'xxx' |
1517 |
resp = resp.form.submit()
|
|
1518 |
manager_submit_cell(resp.form, expect_errors=True)
|
|
1518 | 1519 |
assert 'Template does not evaluate to a valid date.' in resp.text |
1519 | 1520 | |
1520 | 1521 |
resp = app.get('/manage/pages/%s/' % page.id) |
1521 | 1522 |
resp.form[field_prefix + 'time_range_start_template'] = 'today|xxx' |
1522 |
resp = resp.form.submit()
|
|
1523 |
manager_submit_cell(resp.form, expect_errors=True)
|
|
1523 | 1524 |
assert 'Invalid filter' in resp.text |
1524 | 1525 | |
1525 | 1526 |
resp = app.get('/manage/pages/%s/' % page.id) |
1526 | 1527 |
resp.form[field_prefix + 'time_range_start_template'] = 'today|date:xxx' |
1527 |
resp = resp.form.submit()
|
|
1528 |
manager_submit_cell(resp.form, expect_errors=True)
|
|
1528 | 1529 |
assert 'Failed lookup for key [xxx]' in resp.text |
1529 | 1530 | |
1530 | 1531 | |
... | ... | |
1539 | 1540 |
field_prefix = 'cdataviz_chartngcell-%s-' % cell.id |
1540 | 1541 |
resp.form[field_prefix + 'statistic'] = statistic.pk |
1541 | 1542 |
resp = app.post(resp.form.action, params=resp.form.submit_fields(), xhr=True) |
1542 |
assert 'time_interval' in resp.text
|
|
1543 |
assert 'time_interval' in resp.json['tabs']['general']
|
|
1543 | 1544 | |
1544 | 1545 | |
1545 | 1546 |
@with_httmock(new_api_mock) |
... | ... | |
1575 | 1576 |
] |
1576 | 1577 | |
1577 | 1578 |
resp.form[field_prefix + 'ou'] = 'variable:foo' |
1578 |
resp = resp.form.submit().follow()
|
|
1579 |
manager_submit_cell(resp.form)
|
|
1579 | 1580 |
assert resp.form[field_prefix + 'ou'].value == 'variable:foo' |
1580 | 1581 |
cell.refresh_from_db() |
1581 | 1582 |
assert cell.filter_params['ou'] == 'variable:foo' |
... | ... | |
2043 | 2044 |
('year', False, 'Year'), |
2044 | 2045 |
('weekday', False, 'Week day'), |
2045 | 2046 |
] |
2046 |
resp.form.submit()
|
|
2047 |
manager_submit_cell(resp.form)
|
|
2047 | 2048 |
cell.refresh_from_db() |
2048 | 2049 | |
2049 | 2050 |
chart = cell.get_chart() |
... | ... | |
2053 | 2054 |
assert chart.raw_series[0][0][:8] == [0, 0, 0, 0, 0, 0, 0, 1] |
2054 | 2055 |
assert chart.raw_series[1][0][:8] == [2, 0, 0, 0, 0, 0, 0, 2] |
2055 | 2056 | |
2057 |
time_interval_field = resp.form['cdataviz_chartngcell-%s-time_interval' % cell.id] |
|
2056 | 2058 |
time_interval_field.value = 'month' |
2057 |
resp = resp.form.submit().follow()
|
|
2059 |
manager_submit_cell(resp.form)
|
|
2058 | 2060 |
time_interval_field = resp.form['cdataviz_chartngcell-%s-time_interval' % cell.id] |
2059 | 2061 |
assert time_interval_field.options == [ |
2060 | 2062 |
('day', False, 'Day'), |
... | ... | |
2075 | 2077 |
([4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], {'title': 'Serie 2'}), |
2076 | 2078 |
] |
2077 | 2079 | |
2080 |
time_interval_field = resp.form['cdataviz_chartngcell-%s-time_interval' % cell.id] |
|
2078 | 2081 |
time_interval_field.value = 'year' |
2079 | 2082 |
resp.form.submit() |
2080 | 2083 |
cell.refresh_from_db() |
... | ... | |
2087 | 2090 |
([5, 0, 0], {'title': 'Serie 2'}), |
2088 | 2091 |
] |
2089 | 2092 | |
2093 |
time_interval_field = resp.form['cdataviz_chartngcell-%s-time_interval' % cell.id] |
|
2090 | 2094 |
time_interval_field.value = 'weekday' |
2091 |
resp.form.submit()
|
|
2095 |
manager_submit_cell(resp.form)
|
|
2092 | 2096 |
cell.refresh_from_db() |
2093 | 2097 | |
2094 | 2098 |
chart = cell.get_chart() |
... | ... | |
2099 | 2103 |
([1, 4, 0, 0, 0, 0, 0], {'title': 'Serie 2'}), |
2100 | 2104 |
] |
2101 | 2105 | |
2106 |
time_interval_field = resp.form['cdataviz_chartngcell-%s-time_interval' % cell.id] |
|
2102 | 2107 |
time_interval_field.value = 'week' |
2103 |
resp.form.submit()
|
|
2108 |
manager_submit_cell(resp.form)
|
|
2104 | 2109 |
cell.refresh_from_db() |
2105 | 2110 | |
2106 | 2111 |
chart = cell.get_chart() |
... | ... | |
2115 | 2120 | |
2116 | 2121 |
cell.statistic = Statistic.objects.get(slug='leap-week') |
2117 | 2122 |
cell.save() |
2118 |
resp = app.get('/manage/pages/%s/' % page.id) |
|
2119 |
resp.form.submit() |
|
2123 |
manager_submit_cell(resp.form) |
|
2120 | 2124 |
chart = cell.get_chart() |
2121 | 2125 |
assert 'time_interval=day' in new_api_mock.call['requests'][1].url |
2122 | 2126 |
assert len(chart.x_labels) == 1 |
... | ... | |
2335 | 2339 |
# select a choice with subfilters in manager |
2336 | 2340 |
resp = app.get('/manage/pages/%s/' % page.id) |
2337 | 2341 |
resp.forms[1]['cdataviz_chartngcell-%s-form' % cell.id] = 'food-request' |
2338 |
resp = resp.forms[1].submit().follow()
|
|
2342 |
manager_submit_cell(resp.forms[1])
|
|
2339 | 2343 | |
2340 | 2344 |
resp = app.get('/') |
2341 | 2345 |
assert 'form' in resp.form.fields |
tests/test_family.py | ||
---|---|---|
9 | 9 |
from combo.data.models import Page |
10 | 10 | |
11 | 11 |
from .test_manager import login |
12 |
from .utils import manager_submit_cell |
|
12 | 13 | |
13 | 14 |
pytestmark = pytest.mark.django_db |
14 | 15 | |
... | ... | |
63 | 64 |
resp.forms[0]['c%s-agenda_categories' % cell.get_reference()].value = 'bar,foo' |
64 | 65 |
resp.forms[0]['c%s-start_date_filter' % cell.get_reference()].value = '{{ start_date }}' |
65 | 66 |
resp.forms[0]['c%s-end_date_filter' % cell.get_reference()].value = '{{ end_date }}' |
66 |
resp = resp.forms[0].submit().follow()
|
|
67 |
manager_submit_cell(resp.form)
|
|
67 | 68 |
cell.refresh_from_db() |
68 | 69 |
assert cell.agenda_type == 'subscribed' |
69 | 70 |
assert cell.agenda_references_template == '' |
... | ... | |
74 | 75 |
resp.forms[0]['c%s-agenda_type' % cell.get_reference()].value = 'manual' |
75 | 76 |
resp.forms[0]['c%s-agenda_references_template' % cell.get_reference()].value = 'foo,bar' |
76 | 77 |
resp.forms[0]['c%s-agenda_categories' % cell.get_reference()].value = 'bar,foo' |
77 |
resp = resp.forms[0].submit().follow()
|
|
78 |
manager_submit_cell(resp.form)
|
|
78 | 79 |
cell.refresh_from_db() |
79 | 80 |
assert cell.agenda_type == 'manual' |
80 | 81 |
assert cell.agenda_references_template == 'foo,bar' |
tests/test_gallery_cell.py | ||
---|---|---|
26 | 26 |
) |
27 | 27 | |
28 | 28 |
app = login(app) |
29 |
resp = app.get( |
|
30 |
reverse( |
|
31 |
'combo-manager-page-edit-cell', |
|
32 |
kwargs={'page_pk': page.id, 'cell_reference': cell.get_reference()}, |
|
33 |
), |
|
34 |
status=200, |
|
35 |
) |
|
29 |
resp = app.get('/manage/pages/%s/' % page.id) |
|
36 | 30 |
assert '<ul class="gallery"' in resp.text |
37 | 31 |
assert 'js/combo.gallery.js' in resp.text |
38 | 32 |
tests/test_kb.py | ||
---|---|---|
22 | 22 |
from combo.apps.kb.models import LatestPageUpdatesCell |
23 | 23 |
from combo.data.models import CellBase, Page, TextCell |
24 | 24 | |
25 |
from .utils import manager_submit_cell |
|
26 | ||
25 | 27 |
pytestmark = pytest.mark.django_db |
26 | 28 | |
27 | 29 | |
... | ... | |
49 | 51 |
resp = resp.follow() |
50 | 52 |
cells = CellBase.get_cells(page_id=page.id) |
51 | 53 |
assert ('data-cell-reference="%s"' % cells[0].get_reference()) in resp.text |
52 |
resp = resp.forms[0].submit() |
|
53 |
assert resp.status_int == 302 |
|
54 |
manager_submit_cell(resp.forms[0]) |
|
54 | 55 | |
55 | 56 |
resp = app.get('/example-page/', status=200) |
56 | 57 |
div = resp.html.find('div', attrs={'class': 'latest-page-updates-cell'}) |
tests/test_manager.py | ||
---|---|---|
46 | 46 |
) |
47 | 47 |
from combo.manager.forms import PageAddForm, PageSelectTemplateForm |
48 | 48 | |
49 |
from .utils import manager_submit_cell |
|
50 | ||
49 | 51 |
pytestmark = pytest.mark.django_db |
50 | 52 | |
51 | 53 |
TESTS_DATA_DIR = os.path.join(os.path.dirname(__file__), 'data') |
... | ... | |
699 | 701 |
app.get('/manage/pages/%s/' % page.pk) # load once to populate caches |
700 | 702 |
with CaptureQueriesContext(connection) as ctx: |
701 | 703 |
app.get('/manage/pages/%s/' % page.pk) |
702 |
assert len(ctx.captured_queries) == 33
|
|
704 |
assert len(ctx.captured_queries) == 41
|
|
703 | 705 | |
704 | 706 | |
705 | 707 |
def test_delete_page(app, admin_user): |
... | ... | |
1269 | 1271 |
resp = app.get('/manage/pages/%s/' % page.id) |
1270 | 1272 |
assert ('data-cell-reference="%s"' % cells[0].get_reference()) in resp.text |
1271 | 1273 |
resp.forms[0]['c%s-text' % cells[0].get_reference()].value = 'Hello world' |
1272 |
resp = resp.forms[0].submit() |
|
1273 |
assert resp.status_int == 302 |
|
1274 |
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.id, cells[0].get_reference())) |
|
1274 |
manager_submit_cell(resp.forms[0]) |
|
1275 | 1275 | |
1276 | 1276 |
resp = app.get('/manage/pages/%s/' % page.id) |
1277 | 1277 |
assert resp.forms[0]['c%s-text' % cells[0].get_reference()].value == 'Hello world' |
... | ... | |
1279 | 1279 |
resp = app.get('/manage/pages/%s/' % page.id) |
1280 | 1280 |
assert ('data-cell-reference="%s"' % cells[0].get_reference()) in resp.text |
1281 | 1281 |
resp.forms[0]['c%s-text' % cells[0].get_reference()].value = 'World Hello' |
1282 |
resp = resp.forms[0].submit(xhr=True) |
|
1283 |
assert resp.status_int == 200 |
|
1284 |
assert resp.text.strip().startswith('<p><label') |
|
1282 |
manager_submit_cell(resp.forms[0]) |
|
1283 |
assert resp.forms[0]['c%s-text' % cells[0].get_reference()].value == 'World Hello' |
|
1285 | 1284 | |
1286 | 1285 |
resp = app.get('/manage/pages/%s/' % page.id) |
1287 | 1286 |
assert resp.forms[0]['c%s-text' % cells[0].get_reference()].value == 'World Hello' |
... | ... | |
1440 | 1439 | |
1441 | 1440 |
app = login(app) |
1442 | 1441 |
resp = app.get('/manage/pages/%s/' % page.id) |
1443 |
resp = resp.click(href='/data_textcell-%s/visibility' % cell.id) |
|
1444 | 1442 |
assert resp.form['cdata_textcell-%s-visibility' % cell.id].value == 'all' |
1445 | 1443 |
resp.form['cdata_textcell-%s-visibility' % cell.id] = 'logged' |
1446 | 1444 |
resp = resp.form.submit('submit') |
... | ... | |
1449 | 1447 |
assert TextCell.objects.get(id=cell.id).groups.count() == 0 |
1450 | 1448 | |
1451 | 1449 |
resp = app.get('/manage/pages/%s/' % page.id) |
1452 |
resp = resp.click(href='/data_textcell-%s/visibility' % cell.id) |
|
1453 | 1450 |
assert resp.form['cdata_textcell-%s-visibility' % cell.id].value == 'logged' |
1454 | 1451 |
resp.form['cdata_textcell-%s-visibility' % cell.id] = 'unlogged' |
1455 | 1452 |
resp = resp.form.submit('submit') |
... | ... | |
1458 | 1455 |
assert TextCell.objects.get(id=cell.id).groups.count() == 0 |
1459 | 1456 | |
1460 | 1457 |
resp = app.get('/manage/pages/%s/' % page.id) |
1461 |
resp = resp.click(href='/data_textcell-%s/visibility' % cell.id) |
|
1462 | 1458 |
assert resp.form['cdata_textcell-%s-visibility' % cell.id].value == 'unlogged' |
1463 | 1459 |
resp.form['cdata_textcell-%s-visibility' % cell.id] = 'all' |
1464 | 1460 |
resp = resp.form.submit('submit') |
... | ... | |
1472 | 1468 |
group2.save() |
1473 | 1469 | |
1474 | 1470 |
resp = app.get('/manage/pages/%s/' % page.id) |
1475 |
resp = resp.click(href='/data_textcell-%s/visibility' % cell.id) |
|
1476 | 1471 |
resp.form['cdata_textcell-%s-visibility' % cell.id] = 'groups-any' |
1477 | 1472 |
resp.form['cdata_textcell-%s-groups' % cell.id] = [group1.id] |
1478 | 1473 |
resp = resp.form.submit('submit') |
... | ... | |
1482 | 1477 |
assert TextCell.objects.get(id=cell.id).groups.all()[0].name == 'A group' |
1483 | 1478 | |
1484 | 1479 |
resp = app.get('/manage/pages/%s/' % page.id) |
1485 |
resp = resp.click(href='/data_textcell-%s/visibility' % cell.id) |
|
1486 | 1480 |
resp.form['cdata_textcell-%s-visibility' % cell.id] = 'groups-none' |
1487 | 1481 |
resp.form['cdata_textcell-%s-groups' % cell.id] = [group2.id] |
1488 | 1482 |
resp = resp.form.submit('submit') |
... | ... | |
1501 | 1495 | |
1502 | 1496 |
app = login(app) |
1503 | 1497 |
resp = app.get('/manage/pages/%s/' % page.id) |
1504 |
resp = resp.click(href='/data_textcell-%s/options' % cell.id) |
|
1505 | 1498 |
assert resp.form['cdata_textcell-%s-slug' % cell.id].value == '' |
1506 | 1499 |
assert resp.form['cdata_textcell-%s-extra_css_class' % cell.id].value == '' |
1507 | 1500 |
resp.form['cdata_textcell-%s-slug' % cell.id] = 'SLUG' |
... | ... | |
1510 | 1503 |
assert 'SLUG' in app.get('/manage/pages/%s/' % page.id) |
1511 | 1504 | |
1512 | 1505 |
resp = app.get('/manage/pages/%s/' % page.id) |
1513 |
resp = resp.click(href='/data_textcell-%s/options' % cell.id) |
|
1514 | 1506 |
resp.form['cdata_textcell-%s-slug' % cell.id] = '' |
1515 | 1507 |
resp = resp.form.submit('submit') |
1516 | 1508 |
assert TextCell.objects.get(id=cell.id).slug == '' |
1517 | 1509 |
assert 'SLUG' not in app.get('/manage/pages/%s/' % page.id) |
1518 | 1510 | |
1519 | 1511 |
resp = app.get('/manage/pages/%s/' % page.id) |
1520 |
resp = resp.click(href='/data_textcell-%s/options' % cell.id) |
|
1521 | 1512 |
resp.form['cdata_textcell-%s-extra_css_class' % cell.id] = 'CSS' |
1522 | 1513 |
resp = resp.form.submit('submit') |
1523 | 1514 |
assert TextCell.objects.get(id=cell.id).extra_css_class == 'CSS' |
... | ... | |
1533 | 1524 | |
1534 | 1525 |
app = login(app) |
1535 | 1526 |
resp = app.get('/manage/pages/%s/' % page.id) |
1536 |
resp = resp.click(href='/data_textcell-%s/options' % cell.id) |
|
1537 | 1527 |
assert 'cdata_textcell-%s-template_name' % cell.id not in resp.form.fields |
1538 | 1528 |
assert resp.form['cdata_textcell-%s-slug' % cell.id].value == '' |
1539 | 1529 |
assert resp.form['cdata_textcell-%s-extra_css_class' % cell.id].value == '' |
1540 | 1530 | |
1541 | 1531 |
with override_settings(COMBO_CELL_TEMPLATES={'data_textcell': {'extra': {'label': 'Extra'}}}): |
1542 | 1532 |
resp = app.get('/manage/pages/%s/' % page.id) |
1543 |
resp = resp.click(href='/data_textcell-%s/options' % cell.id) |
|
1544 | 1533 |
resp.form['cdata_textcell-%s-template_name' % cell.id].value = 'extra' |
1545 | ||
1546 | 1534 |
resp = resp.form.submit('submit') |
1547 | 1535 |
assert TextCell.objects.get(id=cell.id).template_name == 'extra' |
1548 | 1536 |
assert '(Extra)' in app.get('/manage/pages/%s/' % page.id) |
... | ... | |
1661 | 1649 | |
1662 | 1650 |
resp = app.get('/manage/pages/%s/' % page.id) |
1663 | 1651 |
assert ('data-cell-reference="%s"' % cells[0].get_reference()) in resp.text |
1664 |
assert 'There are no options for this cell.' in resp.form.text |
|
1652 |
assert [x.attrib['data-tab-slug'] for x in resp.pyquery('[data-tab-slug]')] == [ |
|
1653 |
'visibility', |
|
1654 |
'appearance', |
|
1655 |
] |
|
1665 | 1656 | |
1666 | 1657 |
# make it configurable |
1667 | 1658 |
with override_settings( |
... | ... | |
1697 | 1688 |
TEMPLATES=templates_settings, |
1698 | 1689 |
): |
1699 | 1690 |
resp = app.get('/manage/pages/%s/' % page.id) |
1700 |
assert 'There are no options for this cell.' not in resp.form.text |
|
1691 |
assert [x.attrib['data-tab-slug'] for x in resp.pyquery('[data-tab-slug]')] == [ |
|
1692 |
'general', |
|
1693 |
'visibility', |
|
1694 |
'appearance', |
|
1695 |
] |
|
1701 | 1696 | |
1702 | 1697 |
resp.form['c%s-test' % cells[0].get_reference()].value = 'Hello world' |
1703 | 1698 |
resp.form['c%s-test3' % cells[0].get_reference()].value = 'Hello again' |
1704 |
resp = resp.form.submit() |
|
1705 |
assert resp.status_int == 302 |
|
1706 |
assert resp.location.endswith('/manage/pages/%s/#cell-%s' % (page.id, cells[0].get_reference())) |
|
1699 |
manager_submit_cell(resp.form) |
|
1707 | 1700 | |
1708 | 1701 |
# test form error |
1709 | 1702 |
resp = app.get('/manage/pages/%s/' % page.id) |
1710 | 1703 |
resp.form['c%s-test' % cells[0].get_reference()].value = '' |
1711 | 1704 |
resp.form['c%s-test3' % cells[0].get_reference()].value = 'Hello' |
1712 |
resp = resp.form.submit() |
|
1713 |
assert resp.status_int == 200 |
|
1705 |
resp = manager_submit_cell(resp.form, expect_errors=True) |
|
1714 | 1706 |
assert resp.context['form'].errors['test'] == ['This field is required.'] |
1715 | 1707 | |
1716 | 1708 |
resp = app.get('/manage/pages/%s/' % page.id) |
... | ... | |
1724 | 1716 |
resp.forms[0]['c%s-test2' % cells[0].get_reference()].checked = True |
1725 | 1717 |
assert resp.form['c%s-test4' % cells[0].get_reference()].tag == 'textarea' |
1726 | 1718 |
resp.forms[0]['c%s-test4' % cells[0].get_reference()].value = 'Text Area' |
1727 |
resp = resp.form.submit(xhr=True) |
|
1728 |
assert resp.status_int == 200 |
|
1729 |
assert resp.text.strip().startswith('<p><label') |
|
1719 |
resp = manager_submit_cell(resp.form) |
|
1720 |
assert resp.json['tabs']['general'].strip().startswith('<p><label') |
|
1730 | 1721 | |
1731 | 1722 |
resp = app.get('/manage/pages/%s/' % page.id) |
1732 | 1723 |
assert resp.form['c%s-test' % cells[0].get_reference()].value == 'World Hello' |
... | ... | |
2338 | 2329 | |
2339 | 2330 |
# change cell text |
2340 | 2331 |
resp.forms[0]['c%s-text' % cell1.get_reference()].value = 'Hello world' |
2341 |
resp = resp.forms[0].submit().follow()
|
|
2332 |
manager_submit_cell(resp.forms[0])
|
|
2342 | 2333 |
assert PageSnapshot.objects.all().count() == 2 |
2343 | 2334 | |
2344 | 2335 |
# reorder cells |
... | ... | |
2379 | 2370 |
cell_id = JsonCell.objects.last().id |
2380 | 2371 |
resp.forms[3]['cdata_jsoncell-%s-template_string' % cell_id].value = 'A{{json.data.0.text}}B' |
2381 | 2372 |
resp.forms[3]['cdata_jsoncell-%s-url' % cell_id].value = 'http://example.com' |
2382 |
resp = resp.forms[3].submit().follow()
|
|
2373 |
manager_submit_cell(resp.forms[3])
|
|
2383 | 2374 |
assert PageSnapshot.objects.all().count() == 5 # add + change |
2384 | 2375 | |
2385 | 2376 |
resp.forms[3]['cdata_jsoncell-%s-template_string' % cell_id].value = 'C{{json.data.0.text}}D' |
2386 |
resp = resp.forms[3].submit().follow()
|
|
2377 |
manager_submit_cell(resp.forms[3])
|
|
2387 | 2378 |
assert PageSnapshot.objects.all().count() == 6 |
2388 | 2379 | |
2389 | 2380 |
resp.forms[1]['c%s-text' % cell1.get_reference()].value = 'Foo back to 1' |
2390 |
resp = resp.forms[0].submit().follow()
|
|
2381 |
manager_submit_cell(resp.forms[1])
|
|
2391 | 2382 | |
2392 | 2383 |
resp = resp.click('History') |
2393 | 2384 |
assert 'added cell' in resp.text |
... | ... | |
2420 | 2411 |
resp = resp.click('restore', index=6) |
2421 | 2412 |
with CaptureQueriesContext(connection) as ctx: |
2422 | 2413 |
resp = resp.form.submit().follow() |
2423 |
assert len(ctx.captured_queries) == 146
|
|
2414 |
assert len(ctx.captured_queries) == 152
|
|
2424 | 2415 | |
2425 | 2416 |
resp2 = resp.click('See online') |
2426 | 2417 |
assert resp2.text.index('Foobar1') < resp2.text.index('Foobar2') < resp2.text.index('Foobar3') |
... | ... | |
2537 | 2528 |
resp.forms[0]['cdata_jsoncell-%s-template_string' % cell_id].value = '{% syntax|error %}' |
2538 | 2529 |
resp.forms[0]['cdata_jsoncell-%s-url' % cell_id].value = 'http://example.com' |
2539 | 2530 |
resp = resp.forms[0].submit() |
2540 |
assert 'syntax error: Invalid block tag' in resp.text
|
|
2531 |
assert resp.json['errorlist']['general']['template_string']
|
|
2541 | 2532 |
assert JsonCell.objects.count() == 1 |
2542 | 2533 |
assert JsonCell.objects.first().template_string is None |
2543 | 2534 |
# valid syntax |
2544 | 2535 |
resp = app.get('/manage/pages/%s/' % page.id) |
2545 | 2536 |
resp.forms[0]['cdata_jsoncell-%s-template_string' % cell_id].value = '{{ ok }}' |
2546 | 2537 |
resp.forms[0]['cdata_jsoncell-%s-url' % cell_id].value = 'http://example.com' |
2547 |
resp = resp.forms[0].submit().follow()
|
|
2538 |
manager_submit_cell(resp.forms[0])
|
|
2548 | 2539 |
assert 'syntax error' not in resp.text |
2549 | 2540 |
assert JsonCell.objects.count() == 1 |
2550 | 2541 |
assert JsonCell.objects.first().template_string == '{{ ok }}' |
tests/test_maps_manager.py | ||
---|---|---|
5 | 5 |
from combo.apps.maps.models import Map, MapLayer, MapLayerOptions |
6 | 6 |
from combo.data.models import Page |
7 | 7 | |
8 |
from .utils import manager_submit_cell |
|
9 | ||
8 | 10 |
pytestmark = pytest.mark.django_db |
9 | 11 | |
10 | 12 | |
... | ... | |
254 | 256 |
resp = resp.click('Cancel') |
255 | 257 | |
256 | 258 |
resp.form['cmaps_map-%s-marker_behaviour_onclick' % cell.pk] = 'display_data' |
257 |
resp = resp.form.submit().follow()
|
|
259 |
manager_submit_cell(resp.form)
|
|
258 | 260 |
resp = resp.click(href='.*/layer/%s/edit/$' % options.pk) |
259 | 261 |
assert 'this setting has no effect' not in resp.context['form'].fields['properties'].help_text |
260 | 262 |
resp.form['properties'] = 'a, b' |
tests/test_wcs.py | ||
---|---|---|
39 | 39 |
from combo.utils import NothingInCacheException |
40 | 40 | |
41 | 41 |
from .test_manager import login |
42 |
from .utils import manager_submit_cell |
|
42 | 43 | |
43 | 44 |
pytestmark = pytest.mark.django_db |
44 | 45 | |
... | ... | |
1532 | 1533 |
resp = app.get('/manage/pages/%s/' % page.id) |
1533 | 1534 |
assert ('data-cell-reference="%s"' % cells[0].get_reference()) in resp.text |
1534 | 1535 |
resp.forms[0]['c%s-ordering' % cells[0].get_reference()].value = 'manual' |
1535 |
resp = resp.forms[0].submit() |
|
1536 |
assert resp.status_int == 302 |
|
1536 |
manager_submit_cell(resp.forms[0]) |
|
1537 |
cells[0].refresh_from_db() |
|
1538 |
resp.forms[0]['c%s-manual_order' % cells[0].get_reference()].select_multiple( |
|
1539 |
['default::a-second-form-title', 'default::third-form-title'] |
|
1540 |
) |
|
1541 |
manager_submit_cell(resp.forms[0]) |
|
1542 |
cells[0].refresh_from_db() |
|
1543 |
assert cells[0].manual_order == {'data': ['default::a-second-form-title', 'default::third-form-title']} |
|
1537 | 1544 | |
1538 | 1545 | |
1539 | 1546 |
@mock.patch('combo.apps.wcs.utils.requests.send', side_effect=mocked_requests_send) |
... | ... | |
1554 | 1561 |
assert ('data-cell-reference="%s"' % cells[0].get_reference()) in resp.text |
1555 | 1562 |
assert len(resp.form['c%s-categories' % cells[0].get_reference()].options) == 4 |
1556 | 1563 |
resp.form['c%s-categories' % cells[0].get_reference()].value = ['default:test-3', 'default:test-9'] |
1557 |
resp = resp.form.submit().follow()
|
|
1564 |
manager_submit_cell(resp.form)
|
|
1558 | 1565 |
assert resp.form['c%s-categories' % cells[0].get_reference()].value == [ |
1559 | 1566 |
'default:test-3', |
1560 | 1567 |
'default:test-9', |
... | ... | |
1565 | 1572 |
assert 'Please choose at least one option among the following: Current Forms, Done Forms' in resp |
1566 | 1573 |
resp = app.get('/manage/pages/%s/' % page.id) |
1567 | 1574 |
resp.form['c%s-done_forms' % cells[0].get_reference()] = True |
1568 |
resp = resp.form.submit().follow()
|
|
1575 |
manager_submit_cell(resp.form)
|
|
1569 | 1576 | |
1570 | 1577 |
# check wcs_site field is a select box |
1571 | 1578 |
assert resp.form['c%s-wcs_site' % cells[0].get_reference()].tag == 'select' |
... | ... | |
1587 | 1594 |
assert cell.without_user is False |
1588 | 1595 |
assert resp.forms[0]['c%s-with_user' % cell.get_reference()].value == 'on' |
1589 | 1596 |
resp.forms[0]['c%s-with_user' % cell.get_reference()].value = False |
1590 |
resp.forms[0].submit().follow()
|
|
1597 |
manager_submit_cell(resp.forms[0])
|
|
1591 | 1598 |
cell.refresh_from_db() |
1592 | 1599 |
assert cell.without_user is True |
1593 | 1600 |
assert resp.forms[0]['c%s-with_user' % cell.get_reference()].value is None |
... | ... | |
1947 | 1954 |
resp = app.get('/manage/pages/%s/' % page.pk) |
1948 | 1955 |
assert resp.forms[0]['c%s-customize_display' % cell.get_reference()].value == 'on' |
1949 | 1956 |
resp.forms[0]['c%s-customize_display' % cell.get_reference()].value = False |
1950 |
resp.forms[0].submit().follow()
|
|
1957 |
manager_submit_cell(resp.forms[0])
|
|
1951 | 1958 |
cell.refresh_from_db() |
1952 | 1959 |
assert cell.custom_schema == {} |
1953 | 1960 | |
... | ... | |
1956 | 1963 |
resp = app.get('/manage/pages/%s/' % page.pk) |
1957 | 1964 |
assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].value == '--' |
1958 | 1965 |
resp.forms[0]['c%s-card_ids' % cell.get_reference()].value = '42' |
1959 |
resp.forms[0].submit().follow()
|
|
1966 |
manager_submit_cell(resp.forms[0])
|
|
1960 | 1967 |
cell.refresh_from_db() |
1961 | 1968 |
assert cell.related_card_path == '' |
1962 | 1969 |
assert cell.card_ids == '' |
... | ... | |
1964 | 1971 |
assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].value == '--' |
1965 | 1972 |
resp.forms[0]['c%s-related_card_path' % cell.get_reference()].value = '' |
1966 | 1973 |
resp.forms[0]['c%s-card_ids' % cell.get_reference()].value = '42' |
1967 |
resp.forms[0].submit().follow()
|
|
1974 |
manager_submit_cell(resp.forms[0])
|
|
1968 | 1975 |
cell.refresh_from_db() |
1969 | 1976 |
assert cell.related_card_path == '' |
1970 | 1977 |
assert cell.card_ids == '42' |
... | ... | |
2192 | 2199 |
assert cell.without_user is False |
2193 | 2200 |
assert resp.forms[0]['c%s-with_user' % cell.get_reference()].value == 'on' |
2194 | 2201 |
resp.forms[0]['c%s-with_user' % cell.get_reference()].value = False |
2195 |
resp = resp.forms[0].submit().follow()
|
|
2202 |
manager_submit_cell(resp.forms[0])
|
|
2196 | 2203 |
cell.refresh_from_db() |
2197 | 2204 |
assert cell.without_user is True |
2198 | 2205 |
assert resp.forms[0]['c%s-with_user' % cell.get_reference()].value is None |
tests/utils.py | ||
---|---|---|
1 |
from pyquery import PyQuery |
|
2 | ||
3 | ||
4 |
def manager_submit_cell(form, expect_errors=False): |
|
5 |
# submit cell edit form and replace current page body with |
|
6 |
# new tab contents. |
|
7 |
resp = form.response |
|
8 |
action = form.action |
|
9 |
pq = PyQuery(resp.body) |
|
10 |
resp2 = form.submit() |
|
11 |
for tab in resp2.json['tabs']: |
|
12 |
pq.find('form[action="%s"] [data-tab-slug="%s"]' % (action, tab)).html(resp2.json['tabs'][tab]) |
|
13 |
resp.text = pq.html() |
|
14 |
resp._forms_indexed = None |
|
15 |
assert expect_errors or not resp2.json['errorlist'], 'got unexpected errors' |
|
16 |
return resp2 |
|
0 |
- |