Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/modules/file-uploader/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@mendix/file-uploader",
"moduleName": "File Uploader module",
"version": "2.2.0",
"version": "2.2.1",
"copyright": "© Mendix Technology BV 2025. All rights reserved.",
"license": "Apache-2.0",
"private": true,
Expand Down
4 changes: 4 additions & 0 deletions packages/pluggableWidgets/file-uploader-web/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

### Fixed

- We updated file size display in the file uploader to show commonly used units (KB, MB, GB) instead of previously incorrect units (Kb, Mb, Gb). Instead of using technically correct binary units (KiB, MiB, GiB), we chose a format more familiar to users.

## [2.2.0] - 2025-05-07

### Added
Expand Down
3 changes: 1 addition & 2 deletions packages/pluggableWidgets/file-uploader-web/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@mendix/file-uploader-web",
"widgetName": "FileUploader",
"version": "2.2.0",
"version": "2.2.1",
"description": "",
"copyright": "© Mendix Technology BV 2025. All rights reserved.",
"license": "Apache-2.0",
Expand Down Expand Up @@ -43,7 +43,6 @@
},
"dependencies": {
"classnames": "^2.2.6",
"filesize.js": "^2.0.0",
"mime-types": "^2.1.35",
"mobx": "6.12.3",
"mobx-react-lite": "4.0.7",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { UploadInfo } from "./UploadInfo";
import { createElement, ReactElement, useCallback, MouseEvent, KeyboardEvent, ReactNode } from "react";
import { FileStatus, FileStore } from "../stores/FileStore";
import { observer } from "mobx-react-lite";
import fileSize from "filesize.js";
import { FileIcon } from "./FileIcon";
import { fileSize } from "../utils/fileSize";
import { FileUploaderContainerProps } from "../../typings/FileUploaderProps";
import { ActionsBar } from "./ActionsBar";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<package xmlns="http://www.mendix.com/package/1.0/">
<clientModule name="FileUploader" version="2.2.0" xmlns="http://www.mendix.com/clientModule/1.0/">
<clientModule name="FileUploader" version="2.2.1" xmlns="http://www.mendix.com/clientModule/1.0/">
<widgetFiles>
<widgetFile path="FileUploader.xml" />
</widgetFiles>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class FileUploaderStore {

_widgetName: string;
_uploadMode: UploadModeEnum;
_maxFileSizeMb = 0;
_maxFileSizeMiB = 0;
_maxFileSize = 0;
_ds?: ListValue;
_maxFilesPerUpload: number;
Expand All @@ -34,8 +34,8 @@ export class FileUploaderStore {

constructor(props: FileUploaderContainerProps, translations: TranslationsStore) {
this._widgetName = props.name;
this._maxFileSizeMb = props.maxFileSize;
this._maxFileSize = this._maxFileSizeMb * 1024 * 1024;
this._maxFileSizeMiB = props.maxFileSize;
this._maxFileSize = this._maxFileSizeMiB * 1024 * 1024;
this._maxFilesPerUpload = props.maxFilesPerUpload;
this._uploadMode = props.uploadMode;

Expand Down Expand Up @@ -149,7 +149,7 @@ export class FileUploaderStore {
if (e.code === "file-too-large") {
return this.translations.get(
"uploadFailureFileIsTooBigMessage",
this._maxFileSizeMb.toString()
this._maxFileSizeMiB.toString()
);
}
return e.message;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { fileSize } from "../fileSize";

describe("fileSize", () => {
it("should return '0B' for size 0", () => {
expect(fileSize(0)).toBe("0 B");
});

it("should return '1B' for size 1", () => {
expect(fileSize(1)).toBe("1 B");
});

it("should return '1KB' for size 1024", () => {
expect(fileSize(1024)).toBe("1 KB");
});

it("should return '1MB' for size 1048576 (1024 * 1024)", () => {
expect(fileSize(1024 * 1024)).toBe("1 MB");
});

it("should return '1GB' for size 1073741824 (1024 * 1024 * 1024)", () => {
expect(fileSize(1024 * 1024 * 1024)).toBe("1 GB");
});

it("should handle large sizes correctly", () => {
expect(fileSize(1024 ** 5.0001)).toBe("1 PB");
});

it("empty for negative sizes", () => {
expect(fileSize(-1)).toBe("");
});

it("should return one decimal digit for sizes less than 100", () => {
expect(fileSize(64.06 * 1024)).toBe("64.1 KB");
expect(fileSize(85.4 * 1024)).toBe("85.4 KB");
expect(fileSize(99.9 * 1024)).toBe("99.9 KB");
});

it("should return two decimal digits for sizes less than 10", () => {
expect(fileSize(5.009 * 1024)).toBe("5.01 KB");
expect(fileSize(9.11 * 1024)).toBe("9.11 KB");
expect(fileSize(1.91 * 1024)).toBe("1.91 KB");

expect(fileSize(100.91 * 1024)).toBe("100 KB");
});

it("should return the round sizes for sizes below the thresholds", () => {
expect(fileSize(85.03 * 1024)).toBe("85 KB");
expect(fileSize(7.001 * 1024)).toBe("7 KB");
expect(fileSize(70268742)).toBe("67 MB");
});

it("should return the correct unit for sizes just below the next threshold", () => {
expect(fileSize(1023)).toBe("1023 B");
expect(fileSize(1024 * 1024 - 1)).toBe("1023 KB");
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Utility function to format file size into human-readable string.
* It uses IEC 60027 standard, meaning the number is divided by 1024 for each unit.
* And prefixes are B, KB, MB, GB, TB, PB, EB, ZB, YB.
* While the prefixes are not technically correct, they are widely used in the industry.
*/
export function fileSize(size: number): string {
if (size < 0) {
return "";
}

const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
let unitIndex = 0;

while (size >= 1024 && unitIndex < units.length - 1) {
size = size / 1024;
unitIndex++;
}

const formattedSize =
size < 10 && size % 1 > 0.005
? size.toFixed(2)
: size < 100 && size % 1 > 0.05
? size.toFixed(1)
: Math.floor(size);

return `${formattedSize} ${units[unitIndex]}`;
}
31 changes: 2 additions & 29 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading