wcs: card cell, display option for file field (#60371) #9

Merged
lguerin merged 1 commits from wip/60371-wcs-card-file-field-option into main 2023-02-17 08:52:06 +01:00
5 changed files with 180 additions and 37 deletions

View File

@ -16,10 +16,20 @@
{% elif field.type == "email" and value is not None and not empty %}
<a class="pk-card-field-email" href="mailto:{{ value }}">{{ value }}</a>
{% elif field.type == 'file' and value %}
{% if value.content_type|startswith:"image/" %}
<img alt="" src="{% make_public_url url=value.url %}">
{% if item and item.file_display_mode == 'thumbnail' %}
<a class="pk-card-field-filename" href="{% make_public_url url=value.url %}" download="{{ value.filename }}">
{% if value.thumbnail_url %}
Review
Il faut https://dev.entrouvert.org/issues/74511 en face
<img alt="" src="{% make_public_url url=value.thumbnail_url %}">
{% else %}
{{ value.filename }}
{% endif %}
lguerin marked this conversation as resolved Outdated

Param thumbnail seulement si ce n'est pas une image, pour avoir le comportement précédent avec une image.
Mais peut-être qu'on veut toujours avoir le thumbnail ?

Param thumbnail seulement si ce n'est pas une image, pour avoir le comportement précédent avec une image. Mais peut-être qu'on veut toujours avoir le thumbnail ?

(oui thumbnail)

(oui thumbnail)

code revu

code revu
</a>
{% else %}
lguerin marked this conversation as resolved
Review

Block else: c'est le mode sans custo, j'ai remis le comportement précédent:
si image, alors balise img, sinon lien.
Mais peut-être qu'on veut afficher une vignette tout le temps ?

Block else: c'est le mode sans custo, j'ai remis le comportement précédent: si image, alors balise img, sinon lien. Mais peut-être qu'on veut afficher une vignette tout le temps ?
Review

Mais peut-être qu'on veut afficher une vignette tout le temps ?

Je pense que oui, tout le temps vignette.

> Mais peut-être qu'on veut afficher une vignette tout le temps ? Je pense que oui, tout le temps vignette.
Review

vu sur jabber, incompréhension de ma part sur le mode vignette, je reprends mon code

vu sur jabber, incompréhension de ma part sur le mode vignette, je reprends mon code
Review

code revu

code revu
<a class="pk-card-field-filename" href="{% make_public_url url=value.url %}" download="{{ value.filename }}">{{ value.filename }}</a>
{% if value.content_type|startswith:"image/" %}
<img alt="" src="{% make_public_url url=value.url %}">
{% else %}
<a class="pk-card-field-filename" href="{% make_public_url url=value.url %}" download="{{ value.filename }}">{{ value.filename }}</a>
{% endif %}
{% endif %}
{% else %}
{{ value|default:""|urlize }}

View File

@ -55,7 +55,7 @@
<p>
<label>
{% trans "Card Fields" %}
<select name="field_varname"></select>
<select name="field_varname" data-dynamic-display-parent="true"></select>
</label>
</p>
<p>
@ -68,7 +68,7 @@
</select>
</label>
</p>
<p data-dynamic-display-child-of="field_content" data-dynamic-display-value-in="label value">
<p data-dynamic-display-child-of="field_content" data-dynamic-display-value-in=" label value ">
<label>
{% trans "Display mode" %}
<select name="field_display_mode">
@ -78,6 +78,15 @@
</select>
</label>
</p>
<p data-dynamic-display-child-of="field_varname" data-dynamic-display-value-in=" {% for field in card_schema.fields %}{% if field.type == 'file' %}{{ field.varname }} {% endif %}{% endfor %} ">

Trop compliqué de gérer un affichage conditionnel de la forme: si display_mode est "value" ou "label-and-value" ET si c'est un champ fichier.
Du coup, pour un champ fichier, on affiche toujours l'option "File display mode", même si l'agent a choisi "label" seulement.

Trop compliqué de gérer un affichage conditionnel de la forme: si display_mode est "value" ou "label-and-value" ET si c'est un champ fichier. Du coup, pour un champ fichier, on affiche toujours l'option "File display mode", même si l'agent a choisi "label" seulement.
<label>
{% trans "File display mode" %}
<select name="file_field_display_mode">
<option value="link">{% trans "Link" %}</option>
<option value="thumbnail">{% trans "Thumbnail" %}</option>
</select>
</label>
</p>
<p>
<label>
{% trans "Empty value display mode" %}
@ -221,7 +230,16 @@
<p>
<label>
{% trans "Card Fields" %}
<select name="field_varname"></select>
<select name="field_varname" data-dynamic-display-parent="true"></select>
</label>
</p>
<p data-dynamic-display-child-of="field_varname" data-dynamic-display-value-in=" {% for field in card_schema.fields %}{% if field.type == 'file' %}{{ field.varname }} {% endif %}{% endfor %} ">
<label>
{% trans "File display mode" %}
<select name="file_field_display_mode">
<option value="link">{% trans "Link" %}</option>
<option value="thumbnail">{% trans "Thumbnail" %}</option>
</select>
</label>
</p>
<p>

View File

@ -430,7 +430,7 @@ $(function() {
$('[data-dynamic-display-parent]').off('change input').on('change input', function() {
var sel1 = '[data-dynamic-display-child-of="' + $(this).attr('name') + '"]';
var sel2 = '[data-dynamic-display-value="' + $(this).val() + '"]';
var sel3 = '[data-dynamic-display-value-in*="' + $(this).val() + '"]';
var sel3 = '[data-dynamic-display-value-in*=" ' + $(this).val() + ' "]';
$(sel1).addClass('field-hidden').hide();
Review

C'était quoi le bug sans les espaces ? (dans wcs on a une version de ce code sans espace)

C'était quoi le bug sans les espaces ? (dans wcs on a une version de ce code sans espace)
Review

Pour éviter de matcher 'label' et 'label-and-value' si on a écrit data-dynamic-display-value-in*=label par exemple.
Et pour éviter de matcher le varname 'foobar' alors que je veux matcher seulement 'foo':

<p data-dynamic-display-child-of="field_varname" data-dynamic-display-value-in=" {% for field in card_schema.fields %}{% if field.type == 'file' %}{{ field.varname }} {% endif %}{% endfor %} ">
Pour éviter de matcher 'label' et 'label-and-value' si on a écrit `data-dynamic-display-value-in*=label` par exemple. Et pour éviter de matcher le varname 'foobar' alors que je veux matcher seulement 'foo': ``` <p data-dynamic-display-child-of="field_varname" data-dynamic-display-value-in=" {% for field in card_schema.fields %}{% if field.type == 'file' %}{{ field.varname }} {% endif %}{% endfor %} "> ```
$(sel1 + sel2).removeClass('field-hidden').show();
$(sel1 + sel3).removeClass('field-hidden').show();
@ -583,26 +583,28 @@ Card_cell_custom.prototype = {
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_form.file_field_display_mode = this.grid_cell_form[4];
this.grid_cell_form.field_empty_display_mode = this.grid_cell_form[5];
this.grid_cell_form.field_empty_text = this.grid_cell_form[6];
this.grid_cell_form.custom_template = this.grid_cell_form[7];
this.grid_cell_form.custom_display_mode = this.grid_cell_form[8];
this.grid_cell_form.link_label_template = this.grid_cell_form[9];
this.grid_cell_form.link_page = this.grid_cell_form[10];
this.grid_cell_form.link_url_template = this.grid_cell_form[11];
this.grid_cell_form.link_display_mode = this.grid_cell_form[12];
this.grid_cell_form.size = this.grid_cell_form[13];
} 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];
this.grid_cell_form.file_field_display_mode = this.grid_cell_form[2];
this.grid_cell_form.field_empty_text = this.grid_cell_form[3];
this.grid_cell_form.custom_header = this.grid_cell_form[4];
this.grid_cell_form.custom_template = this.grid_cell_form[5];
this.grid_cell_form.linke_header = this.grid_cell_form[6];
this.grid_cell_form.link_label_template = this.grid_cell_form[7];
this.grid_cell_form.link_page = this.grid_cell_form[8];
this.grid_cell_form.link_url_template = this.grid_cell_form[9];
this.grid_cell_form.link_display_mode = this.grid_cell_form[10];
}
},
grid_cell__init_form: function() {
@ -698,7 +700,7 @@ Card_cell_custom.prototype = {
} else if (schema_cell.link_field) {
let link_field = _self.field_with_varname(schema_cell.link_field)
if (link_field) {
cell_content += link_field.label + ' ( ' + gettext('File') + ')';
cell_content += link_field.label + ' (' + gettext('File') + ')';
}
} else {
cell_content += (schema_cell.url_template || '');
@ -723,8 +725,11 @@ Card_cell_custom.prototype = {
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') + '"]').text();
}
if (schema_field && schema_field.type == 'file') {
cell_display_mode_label += ' (' + $(this.grid_cell_form).find('select[name="file_field_display_mode"] option[value="' + (schema_cell.file_display_mode || 'link') + '"]').text() + ')';
}
}
if (this.display_mode == 'card' || schema_cell.varname == '@link@') {
if (cell_display_mode_label) {
cell_text += '<span class="cell-display-mode-label">' + cell_display_mode_label + '</span>';
}
if (this.display_mode == 'table' && ['@link@', '@custom@'].includes(schema_cell.varname)) {
@ -763,6 +768,7 @@ Card_cell_custom.prototype = {
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.file_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 || '';
@ -776,6 +782,7 @@ Card_cell_custom.prototype = {
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.file_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 = '';
@ -798,6 +805,8 @@ Card_cell_custom.prototype = {
} else {
this.grid_cell_form.field_display_mode.value = grid_cell.dataset.display_mode || 'text';
}
let schema_field = this.field_with_varname(grid_cell.dataset.varname);
this.grid_cell_form.file_field_display_mode.value = grid_cell.dataset.file_display_mode || 'link';
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 || '';
@ -817,6 +826,7 @@ Card_cell_custom.prototype = {
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.file_field_display_mode.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 || '';
@ -827,6 +837,7 @@ Card_cell_custom.prototype = {
} 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.file_field_display_mode.value = '';
this.grid_cell_form.field_empty_text.value = '';
this.grid_cell_form.custom_header.value = '';
this.grid_cell_form.custom_template.value = '';
@ -843,6 +854,8 @@ Card_cell_custom.prototype = {
} else {
this.grid_cell_form.entry_type.value = '@field@';
this.grid_cell_form.field_varname.value = grid_cell.dataset.varname;
let schema_field = this.field_with_varname(grid_cell.dataset.varname);
this.grid_cell_form.file_field_display_mode.value = grid_cell.dataset.file_display_mode || 'link';
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 = '';
@ -887,6 +900,7 @@ Card_cell_custom.prototype = {
delete schema_cell.field_content;
delete schema_cell.empty_value;
schema_cell.display_mode = form_datas.custom_display_mode;
delete schema_cell.file_display_mode;
schema_cell.template = form_datas.custom_template;
delete schema_cell.page;
delete schema_cell.url_template;
@ -895,6 +909,7 @@ Card_cell_custom.prototype = {
schema_cell.varname = '@link@';
delete schema_cell.field_content;
schema_cell.display_mode = form_datas.link_display_mode;
delete schema_cell.file_display_mode;
schema_cell.template = form_datas.link_label_template;
if (form_datas.link_page.startsWith('field:')) {
schema_cell.page = '';
@ -913,6 +928,12 @@ Card_cell_custom.prototype = {
schema_cell.varname = form_datas.field_varname;
schema_cell.field_content = form_datas.field_content;
schema_cell.display_mode = form_datas.field_display_mode;
let schema_field = this.field_with_varname(schema_cell.varname);
if (schema_field && schema_field.type == 'file') {
schema_cell.file_display_mode = form_datas.file_field_display_mode;
} else {
delete schema_cell.file_display_mode;
}
if (form_datas.field_content == 'label-and-value') {
schema_cell.display_mode = 'text';
}
@ -930,6 +951,7 @@ Card_cell_custom.prototype = {
} else {
if (form_datas.entry_type == '@custom@') {
schema_cell.varname = '@custom@';
delete schema_cell.file_display_mode;
delete schema_cell.empty_value;
schema_cell.header = form_datas.custom_header;
schema_cell.template = form_datas.custom_template;
@ -937,6 +959,7 @@ Card_cell_custom.prototype = {
delete schema_cell.url_template;
} else if (form_datas.entry_type == '@link@') {
schema_cell.varname = '@link@';
delete schema_cell.file_display_mode;
schema_cell.header = form_datas.link_header;
schema_cell.display_mode = form_datas.link_display_mode;
schema_cell.template = form_datas.link_label_template;
@ -955,6 +978,12 @@ Card_cell_custom.prototype = {
}
} else {
schema_cell.varname = form_datas.field_varname;
let schema_field = this.field_with_varname(schema_cell.varname);
if (schema_field && schema_field.type == 'file') {
schema_cell.file_display_mode = form_datas.file_field_display_mode;
} else {
delete schema_cell.file_display_mode;
}
schema_cell.empty_value = form_datas.field_empty_text;
delete schema_cell.template;
delete schema_cell.page;

View File

@ -863,6 +863,9 @@ def test_card_cell_table_mode_render_custom_schema_card_field(mock_send, context
{'varname': 'fieldc'},
{'varname': 'related'},
{'varname': 'fieldd'},
{'varname': 'fieldd', 'file_display_mode': 'thumbnail'},
{'varname': 'fieldd2'},
{'varname': 'fieldd2', 'file_display_mode': 'thumbnail'},
{'varname': 'fielde'},
{'varname': 'fieldf'},
{'varname': 'fieldg'},
@ -880,13 +883,16 @@ def test_card_cell_table_mode_render_custom_schema_card_field(mock_send, context
result = cell.render(context)
assert PyQuery(result).find('ul li') == []
assert len(PyQuery(result).find('table tr td')) == 14 * 3
assert len(PyQuery(result).find('table tr td')) == 17 * 3
assert [PyQuery(td).text() for td in PyQuery(result).find('table tr:first-child td')] == [
'<i>a</i>',
'yes',
'Sept. 28, 2020',
'Foo Bar',
'file.pdf',
'file.pdf',
'file.pdf',
'', # it's an image !
"lorem<strong>ipsum hello'world", # no multiline support for now
"lorem<strong>ipsum hello world",
'test@localhost',
@ -897,26 +903,57 @@ def test_card_cell_table_mode_render_custom_schema_card_field(mock_send, context
'User',
'Foo Bar',
]
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'
PyQuery(result)
.find('table tr:first-child td:nth-child(5) a')
.attr['href']
.startswith('/api/wcs/file/')
)
assert (
PyQuery(result).find('table tr:first-child td:nth-child(9) a').text().strip()
PyQuery(result)
.find('table tr:first-child td:nth-child(6) a')
.attr['href']
.startswith('/api/wcs/file/')
)
assert (
PyQuery(result)
.find('table tr:first-child td:nth-child(7) a')
.attr['href']
.startswith('/api/wcs/file/')
)
assert (
PyQuery(result)
.find('table tr:first-child td:nth-child(8) a')
.attr['href']
.startswith('/api/wcs/file/')
)
assert (
PyQuery(result)
.find('table tr:first-child td:nth-child(8) a img')
.attr['src']
.startswith('/api/wcs/file/')
)
assert PyQuery(result).find('table tr:first-child td:nth-child(11) a').text().strip() == 'test@localhost'
assert (
PyQuery(result).find('table tr:first-child td:nth-child(11) a').attr['href']
== 'mailto:test@localhost'
)
assert (
PyQuery(result).find('table tr:first-child td:nth-child(12) a').text().strip()
== 'https://www.example.net/'
)
assert (
PyQuery(result).find('table tr:first-child td:nth-child(9) a').attr['href']
PyQuery(result).find('table tr:first-child td:nth-child(12) a').attr['href']
== 'https://www.example.net/'
)
assert PyQuery(result).find('table tr:first-child td:nth-child(10) p:first-child').text() == 'loremipsum'
assert PyQuery(result).find('table tr:first-child td:nth-child(13) p:first-child').text() == 'loremipsum'
assert (
PyQuery(result).find('table tr:first-child td:nth-child(10) p:first-child strong').text() == 'ipsum'
PyQuery(result).find('table tr:first-child td:nth-child(13) p:first-child strong').text() == 'ipsum'
)
assert PyQuery(result).find('table tr:first-child td:nth-child(10) p:last-child').text() == "hello'world"
assert PyQuery(result).find('table tr:first-child td:nth-child(12) a').text().strip() == 'foo@bar.com'
assert PyQuery(result).find('table tr:first-child td:nth-child(13) p:last-child').text() == "hello'world"
assert PyQuery(result).find('table tr:first-child td:nth-child(15) a').text().strip() == 'foo@bar.com'
assert (
PyQuery(result).find('table tr:first-child td:nth-child(12) a').attr['href'] == 'mailto:foo@bar.com'
PyQuery(result).find('table tr:first-child td:nth-child(15) a').attr['href'] == 'mailto:foo@bar.com'
)
@ -1555,7 +1592,10 @@ def test_card_cell_card_mode_render(mock_send, context, app):
assert PyQuery(result).find('.label:contains("Related") + .value').text() == 'Foo Bar'
assert 'related_raw' not in result
assert 'related_structured' not in result
assert PyQuery(result).find('.label:contains("Field D") + .value a').text() == 'file.pdf'
assert (
PyQuery(result).find('.label:contains("Field D") + .value a').text() == 'file.pdf file.pdf'
) # Field D2 is matching ...
assert PyQuery(result).find('.label:contains("Field D2") + .value a').text() == 'file.pdf'
context.pop('title')
cell.title_type = 'manual'
@ -1832,6 +1872,46 @@ def test_card_cell_card_mode_render_custom_schema_card_field(mock_send, context)
result = cell.render(context)
assert PyQuery(result).find('.label').text() == 'Field D'
assert PyQuery(result).find('.value').text() == 'file.pdf'
assert PyQuery(result).find('.value a').attr['href'].startswith('/api/wcs/file/')
cell.custom_schema['cells'][0]['file_display_mode'] = 'link'
cell.save()
result = cell.render(context)
assert PyQuery(result).find('.label').text() == 'Field D'
assert PyQuery(result).find('.value').text() == 'file.pdf'
assert PyQuery(result).find('.value a').attr['href'].startswith('/api/wcs/file/')
cell.custom_schema['cells'][0]['file_display_mode'] = 'thumbnail'
cell.save()
result = cell.render(context)
assert PyQuery(result).find('.label').text() == 'Field D'
assert PyQuery(result).find('.value').text() == 'file.pdf'
assert PyQuery(result).find('.value a').attr['href'].startswith('/api/wcs/file/')
cell.custom_schema['cells'][0] = {
'varname': 'fieldd2',
'field_content': 'label-and-value',
'display_mode': 'text',
}
cell.save()
result = cell.render(context)
assert PyQuery(result).find('.label').text() == 'Field D2'
assert PyQuery(result).find('.value').text() == 'file.pdf'
assert PyQuery(result).find('.value a').attr['href'].startswith('/api/wcs/file/')
cell.custom_schema['cells'][0]['file_display_mode'] = 'link'
cell.save()
result = cell.render(context)
assert PyQuery(result).find('.label').text() == 'Field D2'
assert PyQuery(result).find('.value').text() == 'file.pdf'
assert PyQuery(result).find('.value a').attr['href'].startswith('/api/wcs/file/')
cell.custom_schema['cells'][0]['file_display_mode'] = 'thumbnail'
cell.save()
result = cell.render(context)
assert PyQuery(result).find('.label').text() == 'Field D2'
assert PyQuery(result).find('.value a').attr['href'].startswith('/api/wcs/file/')
assert PyQuery(result).find('.value a img').attr['src'].startswith('/api/wcs/file/')
cell.custom_schema['cells'][0] = {
'varname': 'fielde',

View File

@ -115,6 +115,11 @@ WCS_CARDS_DATA = {
'fieldb': True,
'fieldc': '2020-09-28',
'fieldd': {'filename': 'file.pdf', 'url': 'http://127.0.0.1:8999/download?f=42'},
'fieldd2': {
'filename': 'file.pdf',
'url': 'http://127.0.0.1:8999/download?f=42',
'thumbnail_url': 'http://127.0.0.1:8999/download?f=42&thumbnail=1',
},
'fielde': "lorem<strong>ipsum\n\nhello'world",
'fieldf': 'lorem<strong>ipsum\n\nhello world',
'fieldg': 'test@localhost',
@ -240,6 +245,7 @@ WCS_CARDDEF_SCHEMAS = {
{'label': 'Field B', 'varname': 'fieldb', 'type': 'bool'},
{'label': 'Field C', 'varname': 'fieldc', 'type': 'date'},
{'label': 'Field D', 'varname': 'fieldd', 'type': 'file'},
{'label': 'Field D2', 'varname': 'fieldd2', 'type': 'file'},
{'label': 'Field E', 'varname': 'fielde', 'type': 'text'},
{'label': 'Field F', 'varname': 'fieldf', 'type': 'text', 'display_mode': 'pre'},
{'label': 'Field G', 'varname': 'fieldg', 'type': 'email'},