[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) <aab@odoo.com>
This commit is contained in:
luvi
2022-09-29 20:51:18 +02:00
parent f026c8a4d4
commit 8912bb4dfb
6 changed files with 61 additions and 9 deletions
@@ -0,0 +1,5 @@
/** @odoo-module **/
export function isBinarySize(value) {
return /^\d+(\.\d*)? [^0-9]+$/.test(value);
}
@@ -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");
@@ -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)
@@ -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";
@@ -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";
@@ -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: `
<tree>
<field name="document" filename="yooo"/>
</tree>`,
resId: 1,
});
assert.strictEqual(
target.querySelector(".o_data_row .o_data_cell").textContent,
"93.43 Bytes"
);
});
});