wcs: card cell and custom schema for table display (#68721)
gitea-wip/combo/pipeline/head There was a failure building this commit Details
gitea/combo/pipeline/head Something is wrong with the build of this commit Details

This commit is contained in:
Lauréline Guérin 2022-09-06 09:41:57 +02:00
parent c44808a83c
commit 612555a697
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
9 changed files with 960 additions and 250 deletions

View File

@ -155,8 +155,6 @@ class WcsCardCellDisplayForm(forms.ModelForm):
super().save(*args, **kwargs)
if not self.cleaned_data.get('customize_display'):
self.instance.custom_schema = {}
if self.cleaned_data.get('display_mode') == 'table':
self.instance.custom_schema = {}
self.instance.save()
return self.instance

View File

@ -1372,8 +1372,59 @@ class WcsCardCell(CardMixin, CellBase):
if self.title_type in ['auto', 'manual']:
# card mode: default value used if card is not found
extra_context['title'] = self.cached_title
extra_context['fields_by_varnames'] = {
i['varname']: i for i in (self.cached_json.get('fields') or []) if i.get('varname')
}
return getattr(self, 'get_cell_extra_context_%s_mode' % self.display_mode)(context, extra_context)
def complete_card_data(self, card_data, custom_context):
def render_template(item, template_key, template_context, target_key, target_context):
if not item.get(template_key):
return
try:
target_context[target_key][item[template_key]] = Template(item[template_key]).render(
template_context
)
except (VariableDoesNotExist, TemplateSyntaxError):
return
card_data['custom_fields'] = {}
card_data['urls'] = {}
if self.custom_schema:
for item in self.get_custom_schema().get('cells') or []:
if item.get('varname') not in ['@custom@', '@link@']:
continue
if not item.get('template'):
continue
render_template(
item=item,
template_key='template',
template_context=custom_context,
target_key='custom_fields',
target_context=card_data,
)
if item['varname'] == '@link@':
if item.get('page'):
if item['page'] in card_data['urls']:
pass
try:
target = Page.objects.get(pk=item['page'])
card_data['urls'][item['page']] = '%s%s/' % (
target.get_online_url(),
card_data['id'],
)
except Page.DoesNotExist:
pass
else:
render_template(
item=item,
template_key='url_template',
template_context=custom_context,
target_key='urls',
target_context=card_data,
)
def get_cell_extra_context_table_mode(self, context, extra_context):
if not context.get('synchronous'):
raise NothingInCacheException()
@ -1396,13 +1447,16 @@ class WcsCardCell(CardMixin, CellBase):
else:
extra_context['card_objects'] = self.get_cards_from_ids(card_ids, context)
custom_context = Context(extra_context, autoescape=False)
custom_context.update(context)
for card_data in extra_context['card_objects']:
custom_context['card'] = card_data
self.complete_card_data(card_data, custom_context)
return extra_context
def get_cell_extra_context_card_mode(self, context, extra_context):
extra_context['schema'] = self.cached_json
extra_context['fields_by_varnames'] = {
i['varname']: i for i in (self.cached_json.get('fields') or []) if i.get('varname')
}
card_id = self.get_card_id(context)
if not card_id:
@ -1429,52 +1483,7 @@ class WcsCardCell(CardMixin, CellBase):
if self.title_type == 'auto' or self.title_type == 'manual' and not extra_context['title']:
extra_context['title'] = '%s - %s' % (self.cached_title, extra_context['card'].get('text'))
def render_template(item, template_key, template_context, target_key, target_context):
if not item.get(template_key):
return
try:
target_context['card'][target_key][item[template_key]] = Template(item[template_key]).render(
template_context
)
except (VariableDoesNotExist, TemplateSyntaxError):
return
extra_context['card']['custom_fields'] = {}
extra_context['card']['urls'] = {}
if self.custom_schema:
for item in self.custom_schema.get('cells') or []:
if item.get('varname') not in ['@custom@', '@link@']:
continue
if not item.get('template'):
continue
render_template(
item=item,
template_key='template',
template_context=custom_context,
target_key='custom_fields',
target_context=extra_context,
)
if item['varname'] == '@link@':
if item.get('page'):
if item['page'] in extra_context['card']['urls']:
pass
try:
target = Page.objects.get(pk=item['page'])
extra_context['card']['urls'][item['page']] = '%s%s/' % (
target.get_online_url(),
card_id,
)
except Page.DoesNotExist:
pass
else:
render_template(
item=item,
template_key='url_template',
template_context=custom_context,
target_key='urls',
target_context=extra_context,
)
self.complete_card_data(extra_context['card'], custom_context)
return extra_context
@ -1506,21 +1515,36 @@ class WcsCardCell(CardMixin, CellBase):
return tabs
def get_custom_schema(self):
custom_schema = self.custom_schema or {}
custom_schema = copy.deepcopy(self.custom_schema or {})
# migrate old formats
if self.display_mode == 'table':
# missing default values
if custom_schema.get('cells') and not custom_schema.get('grid_headers'):
custom_schema['grid_headers'] = False
# clean values from card mode
for cell in custom_schema.get('cells') or []:
if cell.get('varname') not in ['@custom@', '@link@']:
if cell.get('empty_value') in ['@skip@', '@empty@']:
cell['empty_value'] = ''
return custom_schema
# missing default values
if custom_schema.get('cells') and not custom_schema.get('grid_class'):
custom_schema['grid_class'] = 'fx-grid--auto'
for cell in custom_schema.get('cells') or []:
# migrate old formats
if cell.get('varname') == '@custom@':
if cell.get('display_mode') == 'value':
cell['display_mode'] = 'text'
else:
elif not cell.get('varname') == '@link@':
if not cell.get('field_content'):
if cell.get('display_mode') == 'title':
cell['field_content'] = 'value'
else:
cell['field_content'] = cell.get('display_mode') or 'value'
if cell.get('display_mode') in ['label', 'value', 'label-and-value']:
cell['display_mode'] = 'text'
cell['field_content'] = cell.get('display_mode') or 'label-and-value'
if cell.get('display_mode') in ['label', 'value', 'label-and-value', None]:
cell['display_mode'] = 'text'
# clean values from table mode
if not cell.get('empty_value'):
cell['empty_value'] = '@empty@'

View File

@ -0,0 +1,31 @@
{% spaceless %}
{% if item.varname == "@custom@" %}
{% if item.template %}
{% with card.custom_fields|get:item.template|force_escape as value %}
{% if not ul_display %}<td>{% endif %}{{ value }}{% if not ul_display %}</td>{% endif %}
{% endwith %}
{% endif %}
{% elif item.varname == "@link@" %}
{% if item.template and item.page|default:item.url_template %}
{% with item.page|default:item.url_template as url_key %}
{% with card.custom_fields|get:item.template|force_escape as link_label and card.urls|get:url_key|force_escape as link_url %}
{% if not ul_display %}<td>{% endif %}<a href="{{ link_url }}"{% if item.display_mode == 'button' %} class="pk-button"{% endif %}>{{ link_label }}</a>{% if not ul_display %}</td>{% endif %}
{% endwith %}
{% endwith %}
{% endif %}
{% else %}
{% if item.varname %}
{% with fields_by_varnames|get:item.varname as field %}
{% if field %}
{% with card.fields|get:item.varname as value %}
{% if value %}
{% if not ul_display %}<td>{% endif %}{% include "combo/wcs/card-field-value.html" with mode='inline' %}{% if not ul_display %}</td>{% endif %}
{% else %}
{% if not ul_display %}<td>{% endif %}{% include "combo/wcs/card-field-value.html" with mode='inline' value=item.empty_value %}{% if not ul_display %}</td>{% endif %}
{% endif %}
{% endwith %}
{% endif %}
{% endwith %}
{% endif %}
{% endif %}
{% endspaceless %}

View File

@ -8,16 +8,57 @@
{% endblock %}
{% if card_objects %}
{% with cell.get_custom_schema as custom_schema %}
{% if cell.custom_schema and cell.custom_schema.cells|length > 1 %}
<div class="{% if not is_portal_agent %}pk-table-wrapper{% endif %}">
<table class="{% if is_portal_agent %}main{% else %}pk-data-table{% endif %}">
{% if custom_schema.grid_headers %}
<thead>
{% for item in custom_schema.cells %}
{% if item.varname == "@custom@" or item.varname == "@link@" %}
<th>{{ item.header|default:"" }}</th>
{% else %}
{% if item.varname %}
{% with fields_by_varnames|get:item.varname as field %}
{% if field %}
<th>{{ field.label }}</th>
{% endif %}
{% endwith %}
{% endif %}
{% endif %}
{% endfor %}
</thead>
{% endif %}
<tbody>
{% for card in card_objects %}
<tr>
{% for item in custom_schema.cells %}
{% include "combo/wcs/cards-field.html" %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="links-list cards-{{ cell.card_slug }} list-of-cards">
<ul>
{% for data in card_objects %}
{% for card in card_objects %}
<li>
<a href="{% if card_page_base_url %}{{ card_page_base_url }}{{ data.id }}/{% else %}{{ data.url }}{% endif %}"><span class="card-title">{{ data.text }}</span></a>
{% spaceless %}
{% if custom_schema %}
{% include "combo/wcs/cards-field.html" with item=custom_schema.cells.0 ul_display=True %}
{% else %}
<a href="{% if card_page_base_url %}{{ card_page_base_url }}{{ card.id }}/{% else %}{{ card.url }}{% endif %}"><span class="card-title">{{ card.text }}</span></a>
{% endif %}
{% endspaceless %}
</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% include "combo/pagination.html" %}
{% endwith %}
{% else %}
<div class="cell--body"><p class="empty-message">{% trans "There are no cards." %}</p></div>
{% endif %}

View File

@ -1,43 +1,30 @@
{% load i18n %}
{{ display_form.as_p }}
<script>
{# display/hide custom_schema fields #}
$('#id_cwcs_wcscardcell-{{ cell.pk }}-display_mode').on('change', function() {
if ($(this).val() == 'card') {
$('#id_cwcs_wcscardcell-{{ cell.pk }}-customize_display').parent().show();
if ($('#id_cwcs_wcscardcell-{{ cell.pk }}-customize_display').val()) {
$('.wcs-cards-cell--grid', $('#id_cwcs_wcscardcell-{{ cell.pk }}-customize_display').parents('.cell')).show();
}
} else {
$('#id_cwcs_wcscardcell-{{ cell.pk }}-customize_display').parent().hide();
$('.wcs-cards-cell--grid', $('#id_cwcs_wcscardcell-{{ cell.pk }}-customize_display').parents('.cell')).hide();
}
});
$('#id_cwcs_wcscardcell-{{ cell.pk }}-display_mode').change();
</script>
{% if card_schema %}
{{ card_schema|json_script:card_schema_id }}
{# display mode as card #}
{# UI to customize content layout #}
<div class="wcs-cards-cell--grid">
<div class="wcs-cards-cell--grid-options">
<span class="wcs-cards-cell--grid-layout-label">{% trans "Grid Layout:" %}</span>
<span class="wcs-cards-cell--grid-layout-mode">{% trans "Automatic" %}</span>
<a role="button" class="wcs-cards-cell--grid-layout-btn">
<div class="as-card wcs-cards-cell--grid">
<div class="as-card wcs-cards-cell--grid-options">
<span class="as-card wcs-cards-cell--grid-layout-label">{% trans "Grid Layout:" %}</span>
<span class="as-card wcs-cards-cell--grid-layout-mode"></span>
<a role="button" class="as-card wcs-cards-cell--grid-layout-btn">
{% trans "Edit" %}
</a>
</div>
<div class="wcs-cards-cell--grid-cells">
<div class="as-card wcs-cards-cell--grid-cells">
</div>
<div class="wcs-cards-cell--grid-buttons">
<button type="button" class="wcs-cards-cell--add-grid-cell-btn">{% trans "Add" %}</button>
<div class="as-card wcs-cards-cell--grid-buttons">
<button type="button" class="as-card wcs-cards-cell--add-grid-cell-btn">{% trans "Add" %}</button>
</div>
</div>
{# templates for JS #}
<script type="text/template" class="wcs-cards-cell--grid-form-tpl">
<script type="text/template" class="as-card wcs-cards-cell--grid-form-tpl">
<form>
<p>
{% trans "Layout" %}
@ -50,7 +37,7 @@
</p>
</form>
</script>
<script type="text/template" class="wcs-cards-cell--grid-cell-form-tpl">
<script type="text/template" class="as-card wcs-cards-cell--grid-cell-form-tpl">
<form>
<p>
<label>
@ -179,14 +166,137 @@
</p>
</form>
</script>
<script type="text/template" class="wcs-cards-cell--grid-cell-tpl">
<div class="wcs-cards-cell--grid-cell">
<div class="wcs-cards-cell--grid-cell-content"></div>
<div class="wcs-cards-cell--grid-cell-buttons">
<a role="button" class="wcs-cards-cell--grid-cell-edit">{% trans "Edit" %}</a>
<a role="button" class="wcs-cards-cell--grid-cell-delete">{% trans "Delete" %}</a>
<script type="text/template" class="as-card wcs-cards-cell--grid-cell-tpl">
<div class="as-card wcs-cards-cell--grid-cell">
<div class="as-card wcs-cards-cell--grid-cell-content"></div>
<div class="as-card wcs-cards-cell--grid-cell-buttons">
<a role="button" class="as-card wcs-cards-cell--grid-cell-edit">{% trans "Edit" %}</a>
<a role="button" class="as-card wcs-cards-cell--grid-cell-delete">{% trans "Delete" %}</a>
</div>
</div>
</script>
{# display mode as table #}
{# UI to customize content layout #}
<div class="as-table wcs-cards-cell--grid">
<div class="as-table wcs-cards-cell--grid-options">
<span class="as-table wcs-cards-cell--grid-headers-label">{% trans "Display headers:" %}</span>
<span class="as-table wcs-cards-cell--grid-headers-mode"></span>
<a role="button" class="as-table wcs-cards-cell--grid-headers-btn">
{% trans "Edit" %}
</a>
</div>
<div class="as-table wcs-cards-cell--grid-cells">
</div>
<div class="as-table wcs-cards-cell--grid-buttons">
<button type="button" class="as-table wcs-cards-cell--add-grid-cell-btn">{% trans "Add" %}</button>
</div>
</div>
{# templates for JS #}
<script type="text/template" class="as-table wcs-cards-cell--grid-form-tpl">
<form>
<p>
{% trans "Display headers" %}
<input name="grid-headers" type="checkbox" />
</p>
</form>
</script>
<script type="text/template" class="as-table wcs-cards-cell--grid-cell-form-tpl">
<form>
<p>
<label>
{% trans "Content type" %}
<select name="entry_type" data-dynamic-display-parent="true">
<option value="@field@">{% trans "Card field" %}</option>
<option value="@custom@">{% trans "Custom" %}</option>
<option value="@link@">{% trans "Link" %}</option>
</select>
</label>
</p>
{# fields group for "content type == @field@ " #}
<div data-dynamic-display-child-of="entry_type" data-dynamic-display-value="@field@">
<p>
<label>
{% trans "Card Fields" %}
<select name="field_varname"></select>
</label>
</p>
<p>
<label>
{% trans "Custom text to replace empty value" %}
<input name="field_empty_text" />
</label>
</p>
</div>
{# fields group for "content type == @custom@" #}
<div data-dynamic-display-child-of="entry_type" data-dynamic-display-value="@custom@">
<p>
<label>
{% trans "Header" %}
<input name="custom_header" />
</label>
</p>
<p>
<label>
{% trans "Value template" %}
<textarea name="custom_template" style="resize: vertical;"></textarea>
</label>
</p>
</div>
{# fields group for "content type == @link@" #}
<div data-dynamic-display-child-of="entry_type" data-dynamic-display-value="@link@">
<p>
<label>
{% trans "Header" %}
<input name="link_header" />
</label>
</p>
<p>
<label>
{% trans "Label template" %}
<textarea name="link_label_template" style="resize: vertical;"></textarea>
</label>
</p>
<p>
<label>
{% trans "URL" %}
<select name="link_page" data-dynamic-display-parent="true">
{% for page in cell.get_matching_pages %}
<option value="{{ page.pk }}">{{ page.get_full_path_titles }}</option>
{% endfor %}
<option value="">{% trans "URL template" %}</option>
</select>
</label>
</p>
<p data-dynamic-display-child-of="link_page" data-dynamic-display-value="">
<label>
<textarea name="link_url_template" style="resize: vertical;"></textarea>
</label>
</p>
<p>
<label>
{% trans "Display mode" %}
<select name="link_display_mode">
<option value="link">{% trans "Link" %}</option>
<option value="button">{% trans "Button" %}</option>
</select>
</label>
</p>
</div>
</form>
</script>
<script type="text/template" class="as-table wcs-cards-cell--grid-cell-tpl">
<div class="as-table wcs-cards-cell--grid-cell">
<div class="as-table wcs-cards-cell--grid-cell-content"></div>
<div class="as-table wcs-cards-cell--grid-cell-buttons">
<a role="button" class="as-table wcs-cards-cell--grid-cell-edit">{% trans "Edit" %}</a>
<a role="button" class="as-table wcs-cards-cell--grid-cell-delete">{% trans "Delete" %}</a>
</div>
</div>
</script>
{% endif %}

View File

@ -660,15 +660,15 @@ form .choices {
font-weight: bold;
}
.wcs-cards-cell--grid-cell-content .cell-size-label {
.wcs-cards-cell--grid-cell-content .cell-size-label, .wcs-cards-cell--grid-cell-content .cell-header {
color: #666;
}
.wcs-cards-cell--grid-cell-content .cell-size-label::before {
.wcs-cards-cell--grid-cell-content .cell-size-label::before, .wcs-cards-cell--grid-cell-content .cell-header::before {
content: " [ ";
}
.wcs-cards-cell--grid-cell-content .cell-size-label::after {
.wcs-cards-cell--grid-cell-content .cell-size-label::after, .wcs-cards-cell--grid-cell-content .cell-header::after {
content: " ]";
}

View File

@ -460,14 +460,31 @@ $(function() {
// UI to customize the layout of the content of a wcs-card-cell
const Card_cell_custom = function(cell) {
const Card_cell_custom = function(cell, display_mode) {
this.cell = cell;
this.gridSchema_default = {
"grid_class": "fx-grid--auto",
"cells": []
this.display_mode = display_mode;
var selector = (this.display_mode == 'card') ? '.as-card' : '.as-table';
if (display_mode == 'card') {
this.gridSchema_default = {
"grid_class": "fx-grid--auto",
"cells": []
}
this.event_name = 'custom_cell:change';
} else {
this.gridSchema_default = {
"grid_headers": false,
"cells": []
}
this.event_name = 'custom_cell_as_table:change';
}
this.deletBtn_selector = selector + '.wcs-cards-cell--grid-cell-delete';
this.editBtn_selector = selector + '.wcs-cards-cell--grid-cell-edit';
this.contentEl_selector = selector + '.wcs-cards-cell--grid-cell-content';
this.grid_cell_selector = selector + '.wcs-cards-cell--grid-cell';
this.grid_cell_placeholder_selector = selector + '.wcs-cards-cell--grid-cell-placeholder';
this.init();
}
Card_cell_custom.prototype = {
parse_string_tpl: function(string_tpl) {
const wrapper = document.createElement('div');
@ -486,6 +503,13 @@ Card_cell_custom.prototype = {
$(this.grid_form).dialog({
modal: true,
width: 'auto',
open: function( event, ui ) {
if (_self.display_mode == 'card') {
$(_self.grid_form[0]).val(_self.gridSchema.grid_class || 'fx-grid--auto');
} else {
$(_self.grid_form[0]).prop('checked', _self.gridSchema.grid_headers || false);
}
},
buttons: [
{
text: gettext('Cancel'),
@ -498,9 +522,13 @@ Card_cell_custom.prototype = {
class: "submit-button",
click: function() {
const form_datas = {};
const select_layout = _self.grid_form[0];
form_datas.grid_class = select_layout.value;
form_datas.label = select_layout[select_layout.selectedIndex].text;
if (_self.display_mode == 'card') {
const select_layout = _self.grid_form[0];
form_datas.grid_class = select_layout.value;
} else {
const with_headers = _self.grid_form[0];
form_datas.grid_headers = with_headers.checked;
}
callback(form_datas);
$(this).dialog("close");
}
@ -509,41 +537,64 @@ Card_cell_custom.prototype = {
});
},
grid__set_schema: function(form_datas){
this.gridSchema.grid_class = form_datas.grid_class;
this.gridSchema.grid_layout_label = form_datas.label;
if (this.display_mode == 'card') {
this.gridSchema.grid_class = form_datas.grid_class;
} else {
this.gridSchema.grid_headers = form_datas.grid_headers;
}
this.grid__set_layout();
$(this.cell).trigger("custom_cell:change");
$(this.cell).trigger(this.event_name);
},
grid__set_layout: function() {
this.grid_layout_label.textContent = $(this.grid_form).find('select[name="grid-layout"] option[value="' + this.gridSchema.grid_class + '"]').text();
if (this.grid_wrapper.dataset.grid_layout) {
this.grid_wrapper.classList.remove(this.grid_wrapper.dataset.grid_layout); }
this.grid_wrapper.classList.add(this.gridSchema.grid_class);
this.grid_wrapper.dataset.grid_layout = this.gridSchema.grid_class;
if (this.display_mode == 'card') {
this.grid_layout_label.textContent = $(this.grid_form).find('select[name="grid-layout"] option[value="' + (this.gridSchema.grid_class || 'fx-grid--auto') + '"]').text();
if (this.grid_wrapper.dataset.grid_layout) {
this.grid_wrapper.classList.remove(this.grid_wrapper.dataset.grid_layout); }
this.grid_wrapper.classList.add(this.gridSchema.grid_class);
this.grid_wrapper.dataset.grid_layout = this.gridSchema.grid_class;
} else {
this.grid_layout_label.textContent = this.gridSchema.grid_headers ? gettext('yes') : gettext('no');
}
},
grid_toggle: function() {
if (this.toggleBtn.checked) {
if (this.toggleBtn.checked && $(this.displayModeSelect).val() == this.display_mode) {
this.grid.hidden = false;
} else {
this.grid.hidden = true;
}
},
// Grid cell methods
grid_cell__init_form_fields: function () {
if (this.display_mode == 'card') {
this.grid_cell_form.entry_type = this.grid_cell_form[0];
this.grid_cell_form.field_varname= this.grid_cell_form[1];
this.grid_cell_form.field_content = this.grid_cell_form[2];
this.grid_cell_form.field_display_mode = this.grid_cell_form[3];
this.grid_cell_form.field_empty_display_mode = this.grid_cell_form[4];
this.grid_cell_form.field_empty_text = this.grid_cell_form[5];
this.grid_cell_form.custom_template = this.grid_cell_form[6];
this.grid_cell_form.custom_display_mode = this.grid_cell_form[7];
this.grid_cell_form.link_label_template = this.grid_cell_form[8];
this.grid_cell_form.link_page = this.grid_cell_form[9];
this.grid_cell_form.link_url_template = this.grid_cell_form[10];
this.grid_cell_form.link_display_mode = this.grid_cell_form[11];
this.grid_cell_form.size = this.grid_cell_form[12];
} else {
this.grid_cell_form.entry_type = this.grid_cell_form[0];
this.grid_cell_form.field_varname= this.grid_cell_form[1];
this.grid_cell_form.field_empty_text = this.grid_cell_form[2];
this.grid_cell_form.custom_header = this.grid_cell_form[3];
this.grid_cell_form.custom_template = this.grid_cell_form[4];
this.grid_cell_form.linke_header = this.grid_cell_form[5];
this.grid_cell_form.link_label_template = this.grid_cell_form[6];
this.grid_cell_form.link_page = this.grid_cell_form[7];
this.grid_cell_form.link_url_template = this.grid_cell_form[8];
this.grid_cell_form.link_display_mode = this.grid_cell_form[9];
}
},
grid_cell__init_form: function() {
const _self = this;
this.grid_cell_form.entry_type = this.grid_cell_form[0];
this.grid_cell_form.field_varname= this.grid_cell_form[1];
this.grid_cell_form.field_content = this.grid_cell_form[2];
this.grid_cell_form.field_display_mode = this.grid_cell_form[3];
this.grid_cell_form.field_empty_display_mode = this.grid_cell_form[4];
this.grid_cell_form.field_empty_text = this.grid_cell_form[5];
this.grid_cell_form.custom_template = this.grid_cell_form[6];
this.grid_cell_form.custom_display_mode = this.grid_cell_form[7];
this.grid_cell_form.link_label_template = this.grid_cell_form[8];
this.grid_cell_form.link_page = this.grid_cell_form[9];
this.grid_cell_form.link_url_template = this.grid_cell_form[10];
this.grid_cell_form.link_display_mode = this.grid_cell_form[11];
this.grid_cell_form.size = this.grid_cell_form[12];
this.grid_cell__init_form_fields();
const varname_select = this.grid_cell_form.field_varname;
this.cardSchema.fields.forEach(function(el, id) {
if (el.varname) {
@ -589,9 +640,9 @@ Card_cell_custom.prototype = {
},
grid_cell__new: function() {
const el = this.grid_cell_tpl.cloneNode(true);
el.deletBtn = el.querySelector('.wcs-cards-cell--grid-cell-delete');
el.editBtn = el.querySelector('.wcs-cards-cell--grid-cell-edit');
el.contentEl = el.querySelector('.wcs-cards-cell--grid-cell-content');
el.deletBtn = el.querySelector(this.deletBtn_selector);
el.editBtn = el.querySelector(this.editBtn_selector);
el.contentEl = el.querySelector(this.contentEl_selector);
return el;
},
grid_cell__set: function(grid_cell, schema_cell) {
@ -627,19 +678,26 @@ Card_cell_custom.prototype = {
cell_text += '<span class="cell-meta">';
let cell_display_mode_label = '';
if (schema_cell.varname == '@custom@') {
cell_display_mode_label = $(this.grid_cell_form).find('select[name="custom_display_mode"] option[value="' + schema_cell.display_mode + '"]').text();
cell_display_mode_label = $(this.grid_cell_form).find('select[name="custom_display_mode"] option[value="' + (schema_cell.display_mode || 'label') + '"]').text();
} else if (schema_cell.varname == '@link@') {
cell_display_mode_label = $(this.grid_cell_form).find('select[name="link_display_mode"] option[value="' + schema_cell.display_mode + '"]').text();
} else {
cell_display_mode_label = $(this.grid_cell_form).find('select[name="field_content"] option[value="' + schema_cell.field_content + '"]').text();
if (schema_cell.field_content != 'label-and-value') {
cell_display_mode_label = $(this.grid_cell_form).find('select[name="field_content"] option[value="' + (schema_cell.field_content || 'label-and-value') + '"]').text();
if ((schema_cell.field_content || 'label-and-value') != 'label-and-value') {
cell_display_mode_label += ' - ';
cell_display_mode_label += $(this.grid_cell_form).find('select[name="field_display_mode"] option[value="' + schema_cell.display_mode + '"]').text();
cell_display_mode_label += $(this.grid_cell_form).find('select[name="field_display_mode"] option[value="' + (schema_cell.display_mode || 'text') + '"]').text();
}
}
cell_text += '<span class="cell-display-mode-label">' + cell_display_mode_label + '</span>';
let cell_size_label = $(this.grid_cell_form).find('select[name="cell_size"] option[value="' + schema_cell.cell_size + '"]').text();
cell_text += '<span class="cell-size-label">' + gettext('Size:') + ' ' + cell_size_label + '</span>';
if (this.display_mode == 'card' || schema_cell.varname == '@link@') {
cell_text += '<span class="cell-display-mode-label">' + cell_display_mode_label + '</span>';
}
if (this.display_mode == 'table' && ['@link@', '@custom@'].includes(schema_cell.varname)) {
cell_text += '<span class="cell-header">' + gettext('Header:') + ' ' + (schema_cell.header || '') + '</span>';
}
if (this.display_mode == 'card') {
let cell_size_label = $(this.grid_cell_form).find('select[name="cell_size"] option[value="' + (schema_cell.cell_size || '') + '"]').text();
cell_text += '<span class="cell-size-label">' + gettext('Size:') + ' ' + cell_size_label + '</span>';
}
cell_text += '</span>';
} else {
cell_text += '<span class="warning">' + gettext('Deleted field:') + ' ' + schema_cell.varname + '</span>';
@ -660,102 +718,172 @@ Card_cell_custom.prototype = {
return i !== cell_id;
});
$(grid_cell).remove();
$(this.cell).trigger("custom_cell:change");
$(this.cell).trigger(this.event_name);
},
grid_cell__edit_set_fields: function(grid_cell) {
if (this.display_mode == 'card') {
if (grid_cell.dataset.varname == '@custom@') {
this.grid_cell_form.entry_type.value = '@custom@';
this.grid_cell_form.field_varname.value = '';
this.grid_cell_form.field_content.value = '';
this.grid_cell_form.field_display_mode.value = '';
this.grid_cell_form.field_empty_display_mode.value = '';
this.grid_cell_form.field_empty_text.value = '';
this.grid_cell_form.custom_template.value = grid_cell.dataset.template || '';
this.grid_cell_form.custom_display_mode.value = grid_cell.dataset.display_mode || 'label';
this.grid_cell_form.link_label_template.value = '';
this.grid_cell_form.link_page.value = '';
this.grid_cell_form.link_url_template.value = '';
this.grid_cell_form.link_display_mode.value = '';
} else if (grid_cell.dataset.varname == '@link@') {
this.grid_cell_form.entry_type.value = '@link@';
this.grid_cell_form.field_varname.value = '';
this.grid_cell_form.field_content.value = '';
this.grid_cell_form.field_display_mode.value = '';
this.grid_cell_form.field_empty_display_mode.value = '';
this.grid_cell_form.field_empty_text.value = '';
this.grid_cell_form.custom_template.value = '';
this.grid_cell_form.custom_display_mode.value = '';
this.grid_cell_form.link_label_template.value = grid_cell.dataset.template || '';
this.grid_cell_form.link_page.value = grid_cell.dataset.page || '';
this.grid_cell_form.link_url_template.value = grid_cell.dataset.url_template || '';
this.grid_cell_form.link_display_mode.value = grid_cell.dataset.display_mode;
} else {
this.grid_cell_form.entry_type.value = '@field@';
this.grid_cell_form.field_varname.value = grid_cell.dataset.varname;
this.grid_cell_form.field_content.value = grid_cell.dataset.field_content || 'label-and-value';
if ((grid_cell.dataset.field_content || 'label-and-value') == 'label-and-value') {
this.grid_cell_form.field_display_mode.value = 'text';
} else {
this.grid_cell_form.field_display_mode.value = grid_cell.dataset.display_mode || 'text';
}
if (grid_cell.dataset.empty_value != '@skip@' && grid_cell.dataset.empty_value != '@empty@') {
this.grid_cell_form.field_empty_display_mode.value = '@custom@';
this.grid_cell_form.field_empty_text.value = grid_cell.dataset.empty_value || '';
} else {
this.grid_cell_form.field_empty_display_mode.value = grid_cell.dataset.empty_value;
this.grid_cell_form.field_empty_text.value = '';
}
this.grid_cell_form.custom_template.value = '';
this.grid_cell_form.custom_display_mode.value = '';
this.grid_cell_form.link_label_template.value = '';
this.grid_cell_form.link_page.value = '';
this.grid_cell_form.link_url_template.value = '';
this.grid_cell_form.link_display_mode.value = '';
}
this.grid_cell_form.size.value = grid_cell.dataset.cell_size || '';
} else {
if (grid_cell.dataset.varname == '@custom@') {
this.grid_cell_form.entry_type.value = '@custom@';
this.grid_cell_form.field_varname.value = '';
this.grid_cell_form.field_empty_text.value = '';
this.grid_cell_form.custom_header.value = grid_cell.dataset.header || '';
this.grid_cell_form.custom_template.value = grid_cell.dataset.template || '';
this.grid_cell_form.link_label_template.value = '';
this.grid_cell_form.link_page.value = '';
this.grid_cell_form.link_url_template.value = '';
this.grid_cell_form.link_display_mode.value = '';
} else if (grid_cell.dataset.varname == '@link@') {
this.grid_cell_form.entry_type.value = '@link@';
this.grid_cell_form.field_varname.value = '';
this.grid_cell_form.field_empty_text.value = '';
this.grid_cell_form.custom_header.value = '';
this.grid_cell_form.custom_template.value = '';
this.grid_cell_form.link_header.value = grid_cell.dataset.header || '';
this.grid_cell_form.link_label_template.value = grid_cell.dataset.template || '';
this.grid_cell_form.link_page.value = grid_cell.dataset.page || '';
this.grid_cell_form.link_url_template.value = grid_cell.dataset.url_template || '';
this.grid_cell_form.link_display_mode.value = grid_cell.dataset.display_mode;
} else {
this.grid_cell_form.entry_type.value = '@field@';
this.grid_cell_form.field_varname.value = grid_cell.dataset.varname;
this.grid_cell_form.field_empty_text.value = grid_cell.dataset.empty_value || '';
if (['@skip@', '@empty@'].includes(this.grid_cell_form.field_empty_text.value)) {
this.grid_cell_form.field_empty_text.value = '';
}
this.grid_cell_form.custom_header.value = '';
this.grid_cell_form.custom_template.value = '';
this.grid_cell_form.link_header.value = '';
this.grid_cell_form.link_label_template.value = '';
this.grid_cell_form.link_page.value = '';
this.grid_cell_form.link_url_template.value = '';
this.grid_cell_form.link_display_mode.value = '';
}
}
},
grid_cell__edit: function(grid_cell) {
const _self = this;
if (grid_cell.dataset.varname == '@custom@') {
this.grid_cell_form.entry_type.value = '@custom@';
this.grid_cell_form.field_varname.value = '';
this.grid_cell_form.field_content.value = '';
this.grid_cell_form.field_display_mode.value = '';
this.grid_cell_form.field_empty_display_mode.value = '';
this.grid_cell_form.field_empty_text.value = '';
this.grid_cell_form.custom_template.value = grid_cell.dataset.template || '';
this.grid_cell_form.custom_display_mode.value = grid_cell.dataset.display_mode;
this.grid_cell_form.link_label_template.value = '';
this.grid_cell_form.link_page.value = '';
this.grid_cell_form.link_url_template.value = '';
this.grid_cell_form.link_display_mode.value = '';
} else if (grid_cell.dataset.varname == '@link@') {
this.grid_cell_form.entry_type.value = '@link@';
this.grid_cell_form.field_varname.value = '';
this.grid_cell_form.field_content.value = '';
this.grid_cell_form.field_display_mode.value = '';
this.grid_cell_form.field_empty_display_mode.value = '';
this.grid_cell_form.field_empty_text.value = '';
this.grid_cell_form.custom_template.value = '';
this.grid_cell_form.custom_display_mode.value = '';
this.grid_cell_form.link_label_template.value = grid_cell.dataset.template || '';
this.grid_cell_form.link_page.value = grid_cell.dataset.page || '';
this.grid_cell_form.link_url_template.value = grid_cell.dataset.url_template || '';
this.grid_cell_form.link_display_mode.value = grid_cell.dataset.display_mode;
} else {
this.grid_cell_form.entry_type.value = '@field@';
this.grid_cell_form.field_varname.value = grid_cell.dataset.varname;
this.grid_cell_form.field_content.value = grid_cell.dataset.field_content;
if (grid_cell.dataset.field_content == 'label-and-value') {
this.grid_cell_form.field_display_mode.value = 'text';
} else {
this.grid_cell_form.field_display_mode.value = grid_cell.dataset.display_mode;
}
if (grid_cell.dataset.empty_value != '@skip@' && grid_cell.dataset.empty_value != '@empty@') {
this.grid_cell_form.field_empty_display_mode.value = '@custom@';
this.grid_cell_form.field_empty_text.value = grid_cell.dataset.empty_value || '';
} else {
this.grid_cell_form.field_empty_display_mode.value = grid_cell.dataset.empty_value;
this.grid_cell_form.field_empty_text.value = '';
}
this.grid_cell_form.custom_template.value = '';
this.grid_cell_form.custom_display_mode.value = '';
this.grid_cell_form.link_label_template.value = '';
this.grid_cell_form.link_page.value = '';
this.grid_cell_form.link_url_template.value = '';
this.grid_cell_form.link_display_mode.value = '';
}
this.grid_cell_form.size.value = grid_cell.dataset.cell_size;
this.grid_cell__edit_set_fields(grid_cell);
const cell_id = $(grid_cell).index();
const grid_cell_schema = this.gridSchema.cells[cell_id];
const _self = this;
this.grid_cell__form_dialog(gettext('Edit'), function(form_datas){
const grid_cell_schema_mod = _self.grid_cell__set_schema(form_datas, grid_cell_schema);
_self.grid_cell__set(grid_cell, grid_cell_schema_mod);
$(_self.cell).trigger("custom_cell:change");
$(_self.cell).trigger(_self.event_name);
});
},
grid_cell__set_schema: function(form_datas, schema_cell) {
if (form_datas.entry_type == '@custom@') {
schema_cell.varname = '@custom@';
delete schema_cell.field_content;
delete schema_cell.empty_value;
schema_cell.display_mode = form_datas.custom_display_mode;
schema_cell.template = form_datas.custom_template;
delete schema_cell.page;
delete schema_cell.url_template;
} else if (form_datas.entry_type == '@link@') {
schema_cell.varname = '@link@';
delete schema_cell.field_content;
schema_cell.display_mode = form_datas.link_display_mode;
schema_cell.template = form_datas.link_label_template;
schema_cell.page = form_datas.link_page;
if (form_datas.link_page) {
schema_cell.url_template = '';
if (this.display_mode == 'card') {
if (form_datas.entry_type == '@custom@') {
schema_cell.varname = '@custom@';
delete schema_cell.field_content;
delete schema_cell.empty_value;
schema_cell.display_mode = form_datas.custom_display_mode;
schema_cell.template = form_datas.custom_template;
delete schema_cell.page;
delete schema_cell.url_template;
} else if (form_datas.entry_type == '@link@') {
schema_cell.varname = '@link@';
delete schema_cell.field_content;
schema_cell.display_mode = form_datas.link_display_mode;
schema_cell.template = form_datas.link_label_template;
schema_cell.page = form_datas.link_page;
if (form_datas.link_page) {
schema_cell.url_template = '';
} else {
schema_cell.url_template = form_datas.link_url_template;
}
} else {
schema_cell.url_template = form_datas.link_url_template;
schema_cell.varname = form_datas.field_varname;
schema_cell.field_content = form_datas.field_content;
schema_cell.display_mode = form_datas.field_display_mode;
if (form_datas.field_empty_display_mode == '@custom@') {
schema_cell.empty_value = form_datas.field_empty_text;
} else {
schema_cell.empty_value = form_datas.field_empty_display_mode;
}
delete schema_cell.template;
delete schema_cell.page;
delete schema_cell.url_template;
}
schema_cell.cell_size = form_datas.cell_size;
} else {
schema_cell.varname = form_datas.field_varname;
schema_cell.field_content = form_datas.field_content;
schema_cell.display_mode = form_datas.field_display_mode;
if (form_datas.field_empty_display_mode == '@custom@') {
schema_cell.empty_value = form_datas.field_empty_text;
if (form_datas.entry_type == '@custom@') {
schema_cell.varname = '@custom@';
delete schema_cell.empty_value;
schema_cell.header = form_datas.custom_header;
schema_cell.template = form_datas.custom_template;
delete schema_cell.page;
delete schema_cell.url_template;
} else if (form_datas.entry_type == '@link@') {
schema_cell.varname = '@link@';
schema_cell.header = form_datas.link_header;
schema_cell.display_mode = form_datas.link_display_mode;
schema_cell.template = form_datas.link_label_template;
schema_cell.page = form_datas.link_page;
if (form_datas.link_page) {
schema_cell.url_template = '';
} else {
schema_cell.url_template = form_datas.link_url_template;
}
} else {
schema_cell.empty_value = form_datas.field_empty_display_mode;
schema_cell.varname = form_datas.field_varname;
schema_cell.empty_value = form_datas.field_empty_text;
delete schema_cell.template;
delete schema_cell.page;
delete schema_cell.url_template;
}
delete schema_cell.template;
delete schema_cell.page;
delete schema_cell.url_template;
}
schema_cell.cell_size = form_datas.cell_size;
return schema_cell
},
grid_cell__add_schema: function(form_datas) {
@ -765,7 +893,7 @@ Card_cell_custom.prototype = {
this.gridSchema.cells.push(schema_cell);
this.grid_cell__add(schema_cell);
$(this.cell).trigger("custom_cell:change");
$(this.cell).trigger(this.event_name);
},
grid_cell__init: function() {
if (!this.gridSchema_existing) return;
@ -777,7 +905,7 @@ Card_cell_custom.prototype = {
},
// Init methods
on: function() {
if (!(this.toggleBtn.checked && !this.is_on)) {
if (!(this.toggleBtn.checked && $(this.displayModeSelect).val() == this.display_mode && !this.is_on)) {
return false;
}
@ -806,14 +934,14 @@ Card_cell_custom.prototype = {
});
// Grid cells sortable
$(_self.grid_wrapper).sortable({
items: "> .wcs-cards-cell--grid-cell",
placeholder: "wcs-cards-cell--grid-cell-placeholder",
items: "> " + this.grid_cell_selector,
placeholder: this.grid_cell_placeholder_selector,
update: function(event, ui) {
ui.item.data('update_index', ui.item.index());
const moved_cell_schema = _self.gridSchema.cells[ui.item.data('start_index')];
_self.gridSchema.cells.splice(ui.item.data('start_index'), 1);
_self.gridSchema.cells.splice(ui.item.data('update_index'), 0, moved_cell_schema);
$(_self.cell).trigger("custom_cell:change");
$(_self.cell).trigger(_self.event_name);
},
start: function(event, ui) {
ui.item.data("start_index", ui.item.index());
@ -821,16 +949,40 @@ Card_cell_custom.prototype = {
}
});
// when schema change
$(this.cell).on("custom_cell:change", function() {
$(this.cell).on(this.event_name, function() {
_self.store.value = JSON.stringify(_self.gridSchema);
})
this.is_on = true;
},
init_elements: function() {
var selector = (this.display_mode == 'card') ? '.as-card' : '.as-table';
this.grid = this.cell.querySelector(selector + '.wcs-cards-cell--grid');
if (this.display_mode == 'card') {
this.edit_grid_btn = this.cell.querySelector(selector + '.wcs-cards-cell--grid-layout-btn');
this.grid_layout_label = this.cell.querySelector(selector + '.wcs-cards-cell--grid-layout-mode');
} else {
this.edit_grid_btn = this.cell.querySelector(selector + '.wcs-cards-cell--grid-headers-btn');
this.grid_layout_label = this.cell.querySelector(selector + '.wcs-cards-cell--grid-headers-mode');
}
const grid_form_tpl_string = this.cell.querySelector(selector + '.wcs-cards-cell--grid-form-tpl').innerText;
this.grid_form = this.parse_string_tpl(grid_form_tpl_string);
this.add_grid_cell_btn = this.cell.querySelector(selector + '.wcs-cards-cell--add-grid-cell-btn');
const grid_cell_form_tpl_string = this.cell.querySelector(selector + '.wcs-cards-cell--grid-cell-form-tpl').innerText;
this.grid_cell_form = this.parse_string_tpl(grid_cell_form_tpl_string);
const grid_cell_tpl_string = this.cell.querySelector(selector + '.wcs-cards-cell--grid-cell-tpl').innerText;
this.grid_cell_tpl = this.parse_string_tpl(grid_cell_tpl_string);
this.grid_wrapper = this.cell.querySelector(selector + '.wcs-cards-cell--grid-cells');
},
init: function() {
const cell = this.cell;
const cardSchema_el = cell.querySelector('[id*="card-schema-eservices"]');
const cardSchema_el = this.cell.querySelector('[id*="card-schema-eservices"]');
this.cardSchema = cardSchema_el ? JSON.parse(cardSchema_el.innerText) : undefined;
if (!this.cardSchema) {
@ -838,39 +990,34 @@ Card_cell_custom.prototype = {
}
this.is_on = false;
this.grid = cell.querySelector('.wcs-cards-cell--grid');
this.edit_grid_btn = cell.querySelector('.wcs-cards-cell--grid-layout-btn');
this.grid_layout_label = cell.querySelector('.wcs-cards-cell--grid-layout-mode');
const grid_form_tpl_string = cell.querySelector('.wcs-cards-cell--grid-form-tpl').innerText;
this.grid_form = this.parse_string_tpl(grid_form_tpl_string);
this.add_grid_cell_btn = cell.querySelector('.wcs-cards-cell--add-grid-cell-btn');
const grid_cell_form_tpl_string = cell.querySelector('.wcs-cards-cell--grid-cell-form-tpl').innerText;
this.grid_cell_form = this.parse_string_tpl(grid_cell_form_tpl_string);
const grid_cell_tpl_string = cell.querySelector('.wcs-cards-cell--grid-cell-tpl').innerText;
this.grid_cell_tpl = this.parse_string_tpl(grid_cell_tpl_string);
this.grid_wrapper = cell.querySelector('.wcs-cards-cell--grid-cells');
this.init_elements();
this.toggleBtn = this.cell.querySelector('input[id$="-customize_display"]');
this.displayModeSelect = this.cell.querySelector('select[id$="-display_mode"]');
const _self = this;
$(this.toggleBtn).on('change', function(e) {
_self.on();
_self.grid_toggle();
}).change();
$(this.displayModeSelect).on('change', function(e) {
_self.on();
_self.grid_toggle();
}).change();
}
}
// Active custom card UI for each card cell
$(function() {
$('.wcs-card-cell').each(function(i, el) {
const custom_card = new Card_cell_custom(el);
const custom_card_as_card = new Card_cell_custom(el, 'card');
$(el).on('combo:cellform-reloaded', function() {
custom_card.init();
custom_card_as_card.init();
});
const custom_card_as_table = new Card_cell_custom(el, 'table');
$(el).on('combo:cellform-reloaded', function() {
custom_card_as_table.init();
});
})
});

View File

@ -410,7 +410,7 @@ $(function() {
// different <ul>
var wrapper = $pagination.parent();
wrapper.attr('tabindex', -1)
var items = $pagination.parent().find('li');
var items = $pagination.parent().find('li, tbody tr');
paginate($pagination, items, true);
});

View File

@ -92,9 +92,10 @@ def test_card_cell_setup(mock_send, app, admin_user):
assert 'custom_schema' in form_display.fields
assert form_display.initial['customize_display'] is True
assert form_display.initial['custom_schema'] == {
'grid_class': 'fx-grid--auto',
'cells': [
{'varname': 'foo', 'field_content': 'value', 'display_mode': 'text', 'empty_value': '@empty@'}
]
],
}
WcsCardCell.objects.all().delete()
@ -110,9 +111,10 @@ def test_card_cell_setup(mock_send, app, admin_user):
# check getting back to uncustomized display reset the schema
cell.custom_schema = {
'grid_class': 'fx-grid--auto',
'cells': [
{'varname': 'foo', 'field_content': 'value', 'display_mode': 'text', 'empty_value': '@empty@'}
]
],
}
cell.save()
@ -124,9 +126,10 @@ def test_card_cell_setup(mock_send, app, admin_user):
assert cell.custom_schema == {}
cell.custom_schema = {
'grid_class': 'fx-grid--auto',
'cells': [
{'varname': 'foo', 'field_content': 'value', 'display_mode': 'text', 'empty_value': '@empty@'}
]
],
}
cell.save()
resp = app.get('/manage/pages/%s/' % page.pk)
@ -134,7 +137,12 @@ def test_card_cell_setup(mock_send, app, admin_user):
resp.forms[0]['c%s-display_mode' % cell.get_reference()].value = 'table'
manager_submit_cell(resp.forms[0])
cell.refresh_from_db()
assert cell.custom_schema == {}
assert cell.custom_schema == {
'grid_class': 'fx-grid--auto',
'cells': [
{'varname': 'foo', 'field_content': 'value', 'display_mode': 'text', 'empty_value': '@empty@'}
],
}
assert cell.related_card_path == ''
assert cell.card_ids == ''
@ -190,12 +198,39 @@ def test_card_cell_setup(mock_send, app, admin_user):
def test_card_cell_custom_schema_migration():
cell = WcsCardCell()
cell = WcsCardCell(display_mode='table')
cell.custom_schema = {'cells': [{'varname': 'some-field', 'empty_value': '@empty@'}]}
assert cell.get_custom_schema() == {
'grid_headers': False,
'cells': [
{
'varname': 'some-field',
'empty_value': '',
}
],
}
cell.custom_schema = {
'cells': [{'varname': 'some-field', 'display_mode': 'label', 'cell_size': 'foobar'}]
}
assert cell.get_custom_schema() == {
'grid_headers': False,
'cells': [
{
'varname': 'some-field',
'display_mode': 'label',
'cell_size': 'foobar',
}
],
}
cell.display_mode = 'card'
cell.custom_schema = {
'cells': [{'varname': 'some-field', 'display_mode': 'label', 'cell_size': 'foobar'}]
}
assert cell.get_custom_schema() == {
'grid_class': 'fx-grid--auto',
'cells': [
{
'varname': 'some-field',
@ -204,10 +239,11 @@ def test_card_cell_custom_schema_migration():
'empty_value': '@empty@',
'cell_size': 'foobar',
}
]
],
}
cell.custom_schema = {'cells': [{'varname': 'some-field', 'display_mode': 'value'}]}
assert cell.get_custom_schema() == {
'grid_class': 'fx-grid--auto',
'cells': [
{
'varname': 'some-field',
@ -215,10 +251,11 @@ def test_card_cell_custom_schema_migration():
'display_mode': 'text',
'empty_value': '@empty@',
}
]
],
}
cell.custom_schema = {'cells': [{'varname': 'some-field', 'display_mode': 'label-and-value'}]}
assert cell.get_custom_schema() == {
'grid_class': 'fx-grid--auto',
'cells': [
{
'varname': 'some-field',
@ -226,10 +263,23 @@ def test_card_cell_custom_schema_migration():
'display_mode': 'text',
'empty_value': '@empty@',
}
]
],
}
cell.custom_schema = {'cells': [{'varname': 'some-field'}]}
assert cell.get_custom_schema() == {
'grid_class': 'fx-grid--auto',
'cells': [
{
'varname': 'some-field',
'field_content': 'label-and-value',
'display_mode': 'text',
'empty_value': '@empty@',
}
],
}
cell.custom_schema = {'cells': [{'varname': 'some-field', 'display_mode': 'title'}]}
assert cell.get_custom_schema() == {
'grid_class': 'fx-grid--auto',
'cells': [
{
'varname': 'some-field',
@ -237,7 +287,7 @@ def test_card_cell_custom_schema_migration():
'display_mode': 'title',
'empty_value': '@empty@',
}
]
],
}
cell.custom_schema = {
@ -246,17 +296,20 @@ def test_card_cell_custom_schema_migration():
]
}
assert cell.get_custom_schema() == {
'grid_class': 'fx-grid--auto',
'cells': [
{'varname': '@custom@', 'template': 'foobar', 'display_mode': 'label', 'cell_size': 'foobar'}
]
],
}
cell.custom_schema = {'cells': [{'varname': '@custom@', 'template': 'foobar', 'display_mode': 'value'}]}
assert cell.get_custom_schema() == {
'cells': [{'varname': '@custom@', 'template': 'foobar', 'display_mode': 'text'}]
'grid_class': 'fx-grid--auto',
'cells': [{'varname': '@custom@', 'template': 'foobar', 'display_mode': 'text'}],
}
cell.custom_schema = {'cells': [{'varname': '@custom@', 'template': 'foobar', 'display_mode': 'title'}]}
assert cell.get_custom_schema() == {
'cells': [{'varname': '@custom@', 'template': 'foobar', 'display_mode': 'title'}]
'grid_class': 'fx-grid--auto',
'cells': [{'varname': '@custom@', 'template': 'foobar', 'display_mode': 'title'}],
}
@ -715,6 +768,312 @@ def test_card_cell_table_mode_render(mock_send, context, app):
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://127.0.0.1:8999/'
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
def test_card_cell_table_mode_render_custom_schema_card_field(mock_send, context):
page = Page.objects.create(title='xxx', template_name='standard')
cell = WcsCardCell.objects.create(
page=page,
placeholder='content',
order=0,
carddef_reference='default:card_model_1',
custom_schema={'cells': [{'varname': 'fielda'}]},
display_mode='table',
related_card_path='__all__',
)
request = RequestFactory().get('/')
context['synchronous'] = True # to get fresh content
cell.modify_global_context(context, request)
# only one cell, render as ul/li
result = cell.render(context)
assert PyQuery(result).find('table tr td') == []
assert len(PyQuery(result).find('ul li')) == 3
assert [PyQuery(li).text() for li in PyQuery(result).find('ul li')[:1]] == ['<i>a</i>']
# more than one cell, render as table
cell.custom_schema['cells'] += [
{'varname': 'fieldb'},
]
cell.save()
result = cell.render(context)
assert PyQuery(result).find('ul li') == []
assert len(PyQuery(result).find('table tr td')) == 2 * 3
assert [PyQuery(td).text() for td in PyQuery(result).find('table tr td')[:2]] == ['<i>a</i>', 'yes']
cell.custom_schema['cells'] += [
{'varname': 'fieldc'},
{'varname': 'related'},
{'varname': 'fieldd'},
{'varname': 'fielde'},
{'varname': 'fieldf'},
{'varname': 'fieldg'},
{'varname': 'fieldh'},
{}, # missing varname
]
cell.save()
result = cell.render(context)
assert PyQuery(result).find('ul li') == []
assert len(PyQuery(result).find('table tr td')) == 9 * 3
assert [PyQuery(td).text() for td in PyQuery(result).find('table tr td')[:9]] == [
'<i>a</i>',
'yes',
'Sept. 28, 2020',
'Foo Bar',
'file.pdf',
"lorem<strong>ipsum hello'world", # no multiline support for now
"lorem<strong>ipsum hello world",
'test@localhost',
'https://www.example.net/',
]
assert PyQuery(result).find('table tr:first-child td:nth-child(8) a').text().strip() == 'test@localhost'
assert (
PyQuery(result).find('table tr:first-child td:nth-child(8) a').attr['href'] == 'mailto:test@localhost'
)
assert (
PyQuery(result).find('table tr:first-child td:nth-child(9) a').text().strip()
== 'https://www.example.net/'
)
assert (
PyQuery(result).find('table tr:first-child td:nth-child(9) a').attr['href']
== 'https://www.example.net/'
)
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
@pytest.mark.parametrize('nb_cells', [1, 2])
def test_card_cell_table_mode_render_custom_schema_card_empty_field(mock_send, context, nb_cells):
page = Page.objects.create(title='xxx', template_name='standard')
cell = WcsCardCell.objects.create(
page=page,
placeholder='content',
order=0,
carddef_reference='default:card_model_1',
custom_schema={'cells': [{'varname': 'empty', 'empty_value': ''}]},
display_mode='table',
related_card_path='__all__',
)
if nb_cells > 1:
cell.custom_schema['cells'] += [
{'varname': 'fieldb'},
]
cell.save()
request = RequestFactory().get('/')
context['synchronous'] = True # to get fresh content
cell.modify_global_context(context, request)
def test(value):
result = cell.render(context)
if nb_cells > 1:
assert PyQuery(result).find('ul li') == []
assert PyQuery(result).find('table tr:first-child td:first-child').text() == value
else:
assert PyQuery(result).find('table tr td') == []
assert PyQuery(result).find('ul li:first-child').text() == value
test('')
cell.custom_schema['cells'][0] = {
'varname': 'empty',
'empty_value': 'Custom text',
}
cell.save()
test('Custom text')
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
@pytest.mark.parametrize('nb_cells', [1, 2])
def test_card_cell_table_mode_render_custom_schema_custom_entry(mock_send, context, nb_cells):
page = Page.objects.create(title='xxx', template_name='standard')
cell = WcsCardCell.objects.create(
page=page,
placeholder='content',
order=0,
carddef_reference='default:card_model_1',
custom_schema={
'cells': [
{'varname': '@custom@', 'template': "<b>Foo</b> bar'baz {{ card.fields.fielde }}"},
]
},
display_mode='table',
related_card_path='__all__',
)
if nb_cells > 1:
cell.custom_schema['cells'] += [
{'varname': 'fieldb'},
]
cell.save()
request = RequestFactory().get('/')
cell.modify_global_context(context, request)
context['synchronous'] = True # to get fresh content
def test(value):
result = cell.render(context)
if nb_cells > 1:
assert PyQuery(result).find('ul li') == []
assert PyQuery(result).find('table tr:first-child td:first-child').text() == value
else:
assert PyQuery(result).find('table tr td') == []
assert PyQuery(result).find('ul li:first-child').text() == value
test("<b>Foo</b> bar'baz lorem<strong>ipsum hello'world")
# test context
cell.custom_schema['cells'][0][
'template'
] = '{{ card.fields.fielda }} - {{ card.fields.related }} ({{ card.fields.related_structured.id }})'
cell.save()
test('<i>a</i> - Foo Bar (42)')
# test filters in template
cell.custom_schema['cells'][0]['template'] = '{{ card.fields.related|split:" "|join:"," }}'
cell.save()
test('Foo,Bar')
# test available context
cell.custom_schema['cells'][0][
'template'
] = 'Foo bar baz {% make_public_url url="http://127.0.0.1:8999/" %}'
cell.save()
result = cell.render(context)
if nb_cells > 1:
assert '/api/wcs/file/' in PyQuery(result).find('table tr:first-child td:first-child').text()
else:
assert '/api/wcs/file/' in PyQuery(result).find('ul li:first-child').text()
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
@pytest.mark.parametrize('nb_cells', [1, 2])
def test_card_cell_table_mode_render_custom_schema_link_entry(mock_send, context, nb_cells):
page = Page.objects.create(title='xxx', template_name='standard')
cell = WcsCardCell.objects.create(
page=page,
placeholder='content',
order=0,
carddef_reference='default:card_model_1',
custom_schema={
'cells': [
{
'varname': '@link@',
'url_template': '/foo/bar/{{ card.fields.related_structured.id }}/',
'template': '{{ card.fields.fielda }} - {{ card.fields.related }}',
'display_mode': 'link',
},
]
},
display_mode='table',
related_card_path='__all__',
)
if nb_cells > 1:
cell.custom_schema['cells'] += [
{'varname': 'fieldb'},
]
cell.save()
request = RequestFactory().get('/')
cell.modify_global_context(context, request)
context['synchronous'] = True # to get fresh content
def test(value, href, class_name):
result = cell.render(context)
if nb_cells > 1:
assert PyQuery(result).find('ul li') == []
assert PyQuery(result).find('table tr:first-child td:first-child a').text() == value
assert PyQuery(result).find('table tr:first-child td:first-child a').attr['href'] == href
assert PyQuery(result).find('table tr:first-child td:first-child a').attr['class'] == class_name
else:
assert PyQuery(result).find('table tr td') == []
assert PyQuery(result).find('ul li:first-child a').text() == value
assert PyQuery(result).find('ul li:first-child a').attr['href'] == href
assert PyQuery(result).find('ul li:first-child a').attr['class'] == class_name
test('<i>a</i> - Foo Bar', '/foo/bar/42/', None)
cell.custom_schema['cells'][0]['display_mode'] = 'button'
cell.save()
test('<i>a</i> - Foo Bar', '/foo/bar/42/', 'pk-button')
# check with page link
root_page = Page.objects.create(title='Root', slug='root', template_name='standard')
page1 = Page.objects.create(
title='Card',
slug='card',
template_name='standard',
sub_slug='card_model_1_id',
parent=root_page,
)
other_root_page = Page.objects.create(title='Other root', slug='other-root', template_name='standard')
page2 = Page.objects.create(
title='Card (bis)',
slug='card-bis',
template_name='standard',
sub_slug='card_model_1_id',
parent=other_root_page,
)
cell.custom_schema['cells'][0]['page'] = page1.pk
cell.save()
test('<i>a</i> - Foo Bar', '/root/card/11/', 'pk-button')
cell.custom_schema['cells'][0]['page'] = page2.pk
cell.save()
test('<i>a</i> - Foo Bar', '/other-root/card-bis/11/', 'pk-button')
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
@pytest.mark.parametrize('with_headers', [True, False])
def test_card_cell_table_mode_render_with_headers(mock_send, context, with_headers):
page = Page.objects.create(title='xxx', template_name='standard')
cell = WcsCardCell.objects.create(
page=page,
placeholder='content',
order=0,
carddef_reference='default:card_model_1',
custom_schema={
'grid_headers': with_headers,
'cells': [
{'varname': '@custom@', 'template': "<b>Foo</b> bar'baz {{ card.fields.fielde }}"},
{'varname': 'fieldb'},
],
},
display_mode='table',
related_card_path='__all__',
)
request = RequestFactory().get('/')
cell.modify_global_context(context, request)
context['synchronous'] = True # to get fresh content
def test(value):
result = cell.render(context)
if with_headers:
assert PyQuery(result).find('table thead th:first-child').text() == value
else:
assert PyQuery(result).find('table thead') == []
test('')
cell.custom_schema['cells'][0]['header'] = 'My custom header'
cell.save()
test('My custom header')
cell.custom_schema['cells'][0] = {
'varname': '@link@',
'url_template': '/foo/bar/',
'template': 'Foo bar',
'display_mode': 'link',
}
cell.save()
test('')
cell.custom_schema['cells'][0]['header'] = 'My custom header'
cell.save()
test('My custom header')
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
def test_card_cell_table_mode_render_all_cards(mock_send, nocache, app):
page = Page.objects.create(title='xxx', slug='foo', template_name='standard')