diff options
| author | Alexandre Kühn <alex.e.kuhn@gmail.com> | 2018-01-05 15:00:57 +0100 |
|---|---|---|
| committer | Alexandre Kühn <alex.e.kuhn@gmail.com> | 2018-01-08 10:17:44 +0100 |
| commit | 255e8ca3d92e3a77d7c2a145677623518bc2f978 (patch) | |
| tree | 921f15c6eadbc8a2a726711c2d492b30ee3b1034 /addons | |
| parent | bd2e783d30ece1f2b56d492ed1dc704d96d548a0 (diff) | |
[FIX] web: binary field format in list view
Binary fields were simply shown simply by their textual representation in list views,
e.g. the base64 string.
There was no formatter for binary fields, therefore it has been implemented so that
it displays its estimated size.
Binary fields in list views had a download link in v10.0.
We provide this feature back by means of a widget called 'download_link'.
It is also possible to define an option to set the field name having the filename as its value.
Example:
<tree>
<field name="fname"/>
<field name="datas" widget="download_link" options="{'filename': 'fname'}"/>
</tree>
with the following record: {fname: 'document.txt', datas: 'Cg=='},
we get a file named "document.txt" by clicking on the download link.
Closes #21996
Diffstat (limited to 'addons')
| -rw-r--r-- | addons/web/static/src/js/fields/basic_fields.js | 20 | ||||
| -rw-r--r-- | addons/web/static/src/js/fields/field_registry.js | 1 | ||||
| -rw-r--r-- | addons/web/static/src/js/fields/field_utils.js | 16 | ||||
| -rw-r--r-- | addons/web/static/src/xml/base.xml | 3 | ||||
| -rw-r--r-- | addons/web/static/tests/fields/basic_fields_tests.js | 34 | ||||
| -rw-r--r-- | addons/web/static/tests/fields/field_utils_tests.js | 9 |
6 files changed, 82 insertions, 1 deletions
diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index 09406b43711..38fc0cad439 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -1298,6 +1298,25 @@ var FieldBinaryFile = AbstractFieldBinary.extend({ }, }); +var FieldBinaryDownloadLink = AbstractFieldBinary.extend({ + template: 'FieldBinaryDownloadLink', + events: _.extend({}, AbstractFieldBinary.prototype.events, { + 'click': function (ev) { + ev.stopPropagation(); + }, + }), + supportedFieldTypes: ['binary'], + init: function () { + this._super.apply(this, arguments); + this.filename = _t("Binary File"); + if (this.nodeOptions.filename && this.recordData[this.nodeOptions.filename]) { + this.filename = this.recordData[this.nodeOptions.filename]; + } + this.url = "data:application/octet-stream;base64," + this.value; + this.text = _t("Download"); + }, +}); + var PriorityWidget = AbstractField.extend({ // the current implementation of this widget makes it // only usable for fields of type selection @@ -2528,6 +2547,7 @@ return { TranslatableFieldMixin: TranslatableFieldMixin, DebouncedField: DebouncedField, FieldEmail: FieldEmail, + FieldBinaryDownloadLink: FieldBinaryDownloadLink, FieldBinaryFile: FieldBinaryFile, FieldBinaryImage: FieldBinaryImage, FieldBoolean: FieldBoolean, diff --git a/addons/web/static/src/js/fields/field_registry.js b/addons/web/static/src/js/fields/field_registry.js index 6692663d5f9..85b4fc1187f 100644 --- a/addons/web/static/src/js/fields/field_registry.js +++ b/addons/web/static/src/js/fields/field_registry.js @@ -33,6 +33,7 @@ registry .add('email', basic_fields.FieldEmail) .add('phone', basic_fields.FieldPhone) .add('url', basic_fields.UrlWidget) + .add('download_link', basic_fields.FieldBinaryDownloadLink) .add('image', basic_fields.FieldBinaryImage) .add('binary', basic_fields.FieldBinaryFile) .add('monetary', basic_fields.FieldMonetary) diff --git a/addons/web/static/src/js/fields/field_utils.js b/addons/web/static/src/js/fields/field_utils.js index 6a6ad5a7a98..812a7f380f7 100644 --- a/addons/web/static/src/js/fields/field_utils.js +++ b/addons/web/static/src/js/fields/field_utils.js @@ -28,6 +28,20 @@ var _t = core._t; //------------------------------------------------------------------------------ /** + * + * @param {string} value base64 representation of the binary + * @param {Object} [field] + * a description of the field (note: this parameter is ignored) + * @param {Object} [options] additional options (note: this parameter is ignored) + */ +function formatBinary(value, field, options) { + if (!value) { + return ''; + } + return utils.human_size(value.length / 1.37); // base64 estimated size: http://en.wikipedia.org/wiki/Base64#MIME +} + +/** * @todo Really? it returns a jQuery element... We should try to avoid this and * let DOM utility functions handle this directly. And replace this with a * function that returns a string so we can get rid of the forceString. @@ -561,7 +575,7 @@ function parseMany2one(value) { return { format: { - binary: _.identity, // todo + binary: formatBinary, boolean: formatBoolean, char: formatChar, date: formatDate, diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 5df2c0ec3f7..8c69bb3439a 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -924,6 +924,9 @@ </t> </div> </t> +<t t-name="FieldBinaryDownloadLink"> + <a t-att-download="widget.filename" t-att-href="widget.url"><t t-esc="widget.text"/></a> +</t> <t t-name="HiddenInputFile"> <div t-attf-class="o_hidden_input_file #{fileupload_class or ''}" t-att-style="fileupload_style"> <form class="o_form_binary_form" t-att-target="fileupload_id" diff --git a/addons/web/static/tests/fields/basic_fields_tests.js b/addons/web/static/tests/fields/basic_fields_tests.js index 9ea423250e4..a2f59a68e2a 100644 --- a/addons/web/static/tests/fields/basic_fields_tests.js +++ b/addons/web/static/tests/fields/basic_fields_tests.js @@ -1481,6 +1481,40 @@ QUnit.module('basic_fields', { session.get_file = oldGetFile; }); + QUnit.test('download_link widget in list view', function (assert) { + assert.expect(5); + + this.data.partner.fields.filename = { string: "Filename", type: "char" }; + this.data.partner.records[0].filename = "document.txt"; + + var form = createView({ + View: ListView, + model: 'partner', + data: this.data, + arch: '<tree string="Partners">' + + '<field name="document" widget="download_link" options="{\'filename\': \'filename\'}"/>' + + '<field name="filename"/>' + + '</tree>', + res_id: 1, + }); + + assert.ok(form.$('.o_data_cell').first().hasClass("o_download_link_cell"), + "this should be a download link cell"); + assert.ok(form.$('.o_data_cell').first().find('a').eq(0), + "there should be a link in the cell"); + assert.strictEqual(form.$('.o_data_cell').first().find('a').eq(0).attr('download'), + "document.txt", + "it should download a file named 'document.txt'"); + assert.strictEqual(form.$('.o_data_cell').first().find('a').eq(0).attr('href').trim(), + "data:application/octet-stream;base64,coucou==", + "it should have the appropriate link of a binary"); + assert.strictEqual(form.$('.o_data_cell').first().find('a').eq(0).text(), + "Download", + "the text of the link should be 'Download'"); + + form.destroy(); + }); + QUnit.test('text field rendering in list view', function (assert) { assert.expect(1); diff --git a/addons/web/static/tests/fields/field_utils_tests.js b/addons/web/static/tests/fields/field_utils_tests.js index 1f8c27e7192..e24571ea1d8 100644 --- a/addons/web/static/tests/fields/field_utils_tests.js +++ b/addons/web/static/tests/fields/field_utils_tests.js @@ -127,6 +127,15 @@ QUnit.test('format one2many', function(assert) { assert.strictEqual(fieldUtils.format.one2many({data: [1, 2]}), '2 records'); }); +QUnit.test('format binary', function (assert) { + assert.expect(1); + + // base64 estimated size (bytes) = value.length / 1.37 (http://en.wikipedia.org/wiki/Base64#MIME) + // Here: 4 / 1.37 = 2.91970800 => 2.92 (rounded 2 decimals by utils.human_size) + assert.strictEqual(fieldUtils.format.binary('Cg=='), '2.92 Bytes'); + +}); + QUnit.test('parse float', function(assert) { assert.expect(10); |
