From 8912bb4dfb1a2c6af01fde9c4b63b5b593984c30 Mon Sep 17 00:00:00 2001 From: luvi Date: Tue, 20 Sep 2022 12:57:59 +0000 Subject: [PATCH] [FIX] web: add binaryFormatter for files This commit fixes the display of files in list and in the BinaryField, which was displaying the complete file value instead of a human readable size. A new formatter has been added, and the isBinSize utils has been added to its own utils file instead of depending from the field. A test has been added to verify the correct visibility of a file in a list view instead of showing the file content. closes odoo/odoo#101673 X-original-commit: ff8485b2289a1157cdae608bd4223012fc67b77c Signed-off-by: Aaron Bohy (aab) --- addons/web/static/src/core/utils/binary.js | 5 +++ .../src/views/fields/binary/binary_field.js | 6 +--- .../web/static/src/views/fields/formatters.js | 32 +++++++++++++++++-- .../src/views/fields/image/image_field.js | 2 +- .../views/fields/signature/signature_field.js | 2 +- .../tests/views/fields/binary_field_tests.js | 23 +++++++++++++ 6 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 addons/web/static/src/core/utils/binary.js diff --git a/addons/web/static/src/core/utils/binary.js b/addons/web/static/src/core/utils/binary.js new file mode 100644 index 00000000000..719612e6c5e --- /dev/null +++ b/addons/web/static/src/core/utils/binary.js @@ -0,0 +1,5 @@ +/** @odoo-module **/ + +export function isBinarySize(value) { + return /^\d+(\.\d*)? [^0-9]+$/.test(value); +} diff --git a/addons/web/static/src/views/fields/binary/binary_field.js b/addons/web/static/src/views/fields/binary/binary_field.js index a93b21818f1..92088cea4dc 100644 --- a/addons/web/static/src/views/fields/binary/binary_field.js +++ b/addons/web/static/src/views/fields/binary/binary_field.js @@ -2,17 +2,13 @@ import { registry } from "@web/core/registry"; import { useService } from "@web/core/utils/hooks"; +import { isBinarySize } from "@web/core/utils/binary"; import { download } from "@web/core/network/download"; import { standardFieldProps } from "../standard_field_props"; import { FileUploader } from "../file_handler"; import { _lt } from "@web/core/l10n/translation"; const { Component, onWillUpdateProps, useState } = owl; - -export function isBinarySize(value) { - return /^\d+(\.\d*)? [^0-9]+$/.test(value); -} - export class BinaryField extends Component { setup() { this.notification = useService("notification"); diff --git a/addons/web/static/src/views/fields/formatters.js b/addons/web/static/src/views/fields/formatters.js index d2e0f3c39af..d84fcc9c9c9 100644 --- a/addons/web/static/src/views/fields/formatters.js +++ b/addons/web/static/src/views/fields/formatters.js @@ -5,6 +5,7 @@ import { localization as l10n } from "@web/core/l10n/localization"; import { _t } from "@web/core/l10n/translation"; import { registry } from "@web/core/registry"; import { escape, intersperse, nbsp, sprintf } from "@web/core/utils/strings"; +import { isBinarySize } from "@web/core/utils/binary"; import { session } from "@web/session"; // ----------------------------------------------------------------------------- @@ -85,10 +86,36 @@ function humanNumber(number, options = { decimals: 0, minDigits: 1 }) { return int + decimalPoint + decimalPart + symbol; } +function humanSize(value) { + if (!value) { + return ""; + } + const suffix = value < 1024 ? " " + _t("Bytes") : "b"; + return ( + humanNumber(value, { + decimals: 2, + }) + suffix + ); +} + // ----------------------------------------------------------------------------- // Exports // ----------------------------------------------------------------------------- +/** + * @param {string} [value] base64 representation of the binary + * @returns {string} + */ +export function formatBinary(value) { + if (!isBinarySize(value)) { + // Computing approximate size out of base64 encoded string + // http://en.wikipedia.org/wiki/Base64#MIME + return humanSize(value.length / 1.37); + } + // already bin_size + return value; +} + /** * @param {boolean} value * @returns {string} @@ -369,9 +396,9 @@ export function formatPercentage(value, options = {}) { */ function formatProperties(value, field) { if (!value || !value.length) { - return ''; + return ""; } - return value.map(property => property['string']).join(', '); + return value.map((property) => property["string"]).join(", "); } /** @@ -411,6 +438,7 @@ export function formatText(value) { registry .category("formatters") + .add("binary", formatBinary) .add("boolean", formatBoolean) .add("char", formatChar) .add("date", formatDate) diff --git a/addons/web/static/src/views/fields/image/image_field.js b/addons/web/static/src/views/fields/image/image_field.js index ec32b3e4b83..dbc37384e26 100644 --- a/addons/web/static/src/views/fields/image/image_field.js +++ b/addons/web/static/src/views/fields/image/image_field.js @@ -5,7 +5,7 @@ import { _lt } from "@web/core/l10n/translation"; import { registry } from "@web/core/registry"; import { useService } from "@web/core/utils/hooks"; import { url } from "@web/core/utils/urls"; -import { isBinarySize } from "@web/views/fields/binary/binary_field"; +import { isBinarySize } from "@web/core/utils/binary"; import { FileUploader } from "../file_handler"; import { standardFieldProps } from "../standard_field_props"; diff --git a/addons/web/static/src/views/fields/signature/signature_field.js b/addons/web/static/src/views/fields/signature/signature_field.js index 1345ba5f8d3..8548bb6f619 100644 --- a/addons/web/static/src/views/fields/signature/signature_field.js +++ b/addons/web/static/src/views/fields/signature/signature_field.js @@ -4,7 +4,7 @@ import { registry } from "@web/core/registry"; import { SignatureDialog } from "@web/core/signature/signature_dialog"; import { useService } from "@web/core/utils/hooks"; import { url } from "@web/core/utils/urls"; -import { isBinarySize } from "@web/views/fields/binary/binary_field"; +import { isBinarySize } from "@web/core/utils/binary"; import { fileTypeMagicWordMap, imageCacheKey } from "@web/views/fields/image/image_field"; import { standardFieldProps } from "@web/views/fields/standard_field_props"; diff --git a/addons/web/static/tests/views/fields/binary_field_tests.js b/addons/web/static/tests/views/fields/binary_field_tests.js index edd77e93518..aa0f447c7c4 100644 --- a/addons/web/static/tests/views/fields/binary_field_tests.js +++ b/addons/web/static/tests/views/fields/binary_field_tests.js @@ -13,6 +13,9 @@ import { import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; import { browser } from "@web/core/browser/browser"; +const BINARY_FILE = + "R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP///wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMlWLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA7"; + let serverData; let target; @@ -376,4 +379,24 @@ QUnit.module("Fields", (hooks) => { assert.verifySteps([], "We shouldn't have passed through steps"); } ); + + QUnit.test("Binary field in list view", async function (assert) { + serverData.models.partner.records[0].document = BINARY_FILE; + + await makeView({ + type: "list", + resModel: "partner", + serverData, + arch: ` + + + `, + resId: 1, + }); + + assert.strictEqual( + target.querySelector(".o_data_row .o_data_cell").textContent, + "93.43 Bytes" + ); + }); });