Skip to content

Commit e3c266b

Browse files
authored
[WC-2968] Fix file size units in file uploader (#1586)
2 parents fbe879b + 059d04b commit e3c266b

File tree

9 files changed

+98
-38
lines changed

9 files changed

+98
-38
lines changed

packages/modules/file-uploader/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@mendix/file-uploader",
33
"moduleName": "File Uploader module",
4-
"version": "2.2.0",
4+
"version": "2.2.1",
55
"copyright": "© Mendix Technology BV 2025. All rights reserved.",
66
"license": "Apache-2.0",
77
"private": true,

packages/pluggableWidgets/file-uploader-web/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66

77
## [Unreleased]
88

9+
### Fixed
10+
11+
- 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.
12+
913
## [2.2.0] - 2025-05-07
1014

1115
### Added

packages/pluggableWidgets/file-uploader-web/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@mendix/file-uploader-web",
33
"widgetName": "FileUploader",
4-
"version": "2.2.0",
4+
"version": "2.2.1",
55
"description": "",
66
"copyright": "© Mendix Technology BV 2025. All rights reserved.",
77
"license": "Apache-2.0",
@@ -43,7 +43,6 @@
4343
},
4444
"dependencies": {
4545
"classnames": "^2.2.6",
46-
"filesize.js": "^2.0.0",
4746
"mime-types": "^2.1.35",
4847
"mobx": "6.12.3",
4948
"mobx-react-lite": "4.0.7",

packages/pluggableWidgets/file-uploader-web/src/components/FileEntry.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { UploadInfo } from "./UploadInfo";
44
import { createElement, ReactElement, useCallback, MouseEvent, KeyboardEvent, ReactNode } from "react";
55
import { FileStatus, FileStore } from "../stores/FileStore";
66
import { observer } from "mobx-react-lite";
7-
import fileSize from "filesize.js";
87
import { FileIcon } from "./FileIcon";
8+
import { fileSize } from "../utils/fileSize";
99
import { FileUploaderContainerProps } from "../../typings/FileUploaderProps";
1010
import { ActionsBar } from "./ActionsBar";
1111

packages/pluggableWidgets/file-uploader-web/src/package.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="utf-8" ?>
22
<package xmlns="http://www.mendix.com/package/1.0/">
3-
<clientModule name="FileUploader" version="2.2.0" xmlns="http://www.mendix.com/clientModule/1.0/">
3+
<clientModule name="FileUploader" version="2.2.1" xmlns="http://www.mendix.com/clientModule/1.0/">
44
<widgetFiles>
55
<widgetFile path="FileUploader.xml" />
66
</widgetFiles>

packages/pluggableWidgets/file-uploader-web/src/stores/FileUploaderStore.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export class FileUploaderStore {
2323

2424
_widgetName: string;
2525
_uploadMode: UploadModeEnum;
26-
_maxFileSizeMb = 0;
26+
_maxFileSizeMiB = 0;
2727
_maxFileSize = 0;
2828
_ds?: ListValue;
2929
_maxFilesPerUpload: number;
@@ -34,8 +34,8 @@ export class FileUploaderStore {
3434

3535
constructor(props: FileUploaderContainerProps, translations: TranslationsStore) {
3636
this._widgetName = props.name;
37-
this._maxFileSizeMb = props.maxFileSize;
38-
this._maxFileSize = this._maxFileSizeMb * 1024 * 1024;
37+
this._maxFileSizeMiB = props.maxFileSize;
38+
this._maxFileSize = this._maxFileSizeMiB * 1024 * 1024;
3939
this._maxFilesPerUpload = props.maxFilesPerUpload;
4040
this._uploadMode = props.uploadMode;
4141

@@ -149,7 +149,7 @@ export class FileUploaderStore {
149149
if (e.code === "file-too-large") {
150150
return this.translations.get(
151151
"uploadFailureFileIsTooBigMessage",
152-
this._maxFileSizeMb.toString()
152+
this._maxFileSizeMiB.toString()
153153
);
154154
}
155155
return e.message;
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { fileSize } from "../fileSize";
2+
3+
describe("fileSize", () => {
4+
it("should return '0B' for size 0", () => {
5+
expect(fileSize(0)).toBe("0 B");
6+
});
7+
8+
it("should return '1B' for size 1", () => {
9+
expect(fileSize(1)).toBe("1 B");
10+
});
11+
12+
it("should return '1KB' for size 1024", () => {
13+
expect(fileSize(1024)).toBe("1 KB");
14+
});
15+
16+
it("should return '1MB' for size 1048576 (1024 * 1024)", () => {
17+
expect(fileSize(1024 * 1024)).toBe("1 MB");
18+
});
19+
20+
it("should return '1GB' for size 1073741824 (1024 * 1024 * 1024)", () => {
21+
expect(fileSize(1024 * 1024 * 1024)).toBe("1 GB");
22+
});
23+
24+
it("should handle large sizes correctly", () => {
25+
expect(fileSize(1024 ** 5.0001)).toBe("1 PB");
26+
});
27+
28+
it("empty for negative sizes", () => {
29+
expect(fileSize(-1)).toBe("");
30+
});
31+
32+
it("should return one decimal digit for sizes less than 100", () => {
33+
expect(fileSize(64.06 * 1024)).toBe("64.1 KB");
34+
expect(fileSize(85.4 * 1024)).toBe("85.4 KB");
35+
expect(fileSize(99.9 * 1024)).toBe("99.9 KB");
36+
});
37+
38+
it("should return two decimal digits for sizes less than 10", () => {
39+
expect(fileSize(5.009 * 1024)).toBe("5.01 KB");
40+
expect(fileSize(9.11 * 1024)).toBe("9.11 KB");
41+
expect(fileSize(1.91 * 1024)).toBe("1.91 KB");
42+
43+
expect(fileSize(100.91 * 1024)).toBe("100 KB");
44+
});
45+
46+
it("should return the round sizes for sizes below the thresholds", () => {
47+
expect(fileSize(85.03 * 1024)).toBe("85 KB");
48+
expect(fileSize(7.001 * 1024)).toBe("7 KB");
49+
expect(fileSize(70268742)).toBe("67 MB");
50+
});
51+
52+
it("should return the correct unit for sizes just below the next threshold", () => {
53+
expect(fileSize(1023)).toBe("1023 B");
54+
expect(fileSize(1024 * 1024 - 1)).toBe("1023 KB");
55+
});
56+
});
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* Utility function to format file size into human-readable string.
3+
* It uses IEC 60027 standard, meaning the number is divided by 1024 for each unit.
4+
* And prefixes are B, KB, MB, GB, TB, PB, EB, ZB, YB.
5+
* While the prefixes are not technically correct, they are widely used in the industry.
6+
*/
7+
export function fileSize(size: number): string {
8+
if (size < 0) {
9+
return "";
10+
}
11+
12+
const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
13+
let unitIndex = 0;
14+
15+
while (size >= 1024 && unitIndex < units.length - 1) {
16+
size = size / 1024;
17+
unitIndex++;
18+
}
19+
20+
const formattedSize =
21+
size < 10 && size % 1 > 0.005
22+
? size.toFixed(2)
23+
: size < 100 && size % 1 > 0.05
24+
? size.toFixed(1)
25+
: Math.floor(size);
26+
27+
return `${formattedSize} ${units[unitIndex]}`;
28+
}

pnpm-lock.yaml

Lines changed: 2 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)