refactor: move formatting related code into separate file (#4568)
Co-authored-by: Alexandr <qwerty541zxc@gmail.com>
This commit is contained in:
committed by
martin-mfg
co-authored by
Alexandr
parent
f5916427f1
commit
e29ac4b338
@@ -4,7 +4,6 @@ import {
|
||||
parseEmojis,
|
||||
wrapTextMultiline,
|
||||
encodeHTML,
|
||||
kFormatter,
|
||||
measureText,
|
||||
flexLayout,
|
||||
iconWithLabel,
|
||||
@@ -12,6 +11,7 @@ import {
|
||||
} from "../common/utils.js";
|
||||
import Card from "../common/Card.js";
|
||||
import { getCardColors } from "../common/color.js";
|
||||
import { kFormatter } from "../common/fmt.js";
|
||||
import { icons } from "../common/icons.js";
|
||||
import languageColors from "../common/languageColors.json" with { type: "json" };
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
import { Card } from "../common/Card.js";
|
||||
import { getCardColors } from "../common/color.js";
|
||||
import { kFormatter } from "../common/fmt.js";
|
||||
import { I18n } from "../common/I18n.js";
|
||||
import { icons } from "../common/icons.js";
|
||||
import {
|
||||
encodeHTML,
|
||||
flexLayout,
|
||||
kFormatter,
|
||||
measureText,
|
||||
parseEmojis,
|
||||
wrapTextMultiline,
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
import { Card } from "../common/Card.js";
|
||||
import { getCardColors } from "../common/color.js";
|
||||
import { CustomError } from "../common/error.js";
|
||||
import { kFormatter } from "../common/fmt.js";
|
||||
import { I18n } from "../common/I18n.js";
|
||||
import { icons, rankIcon } from "../common/icons.js";
|
||||
import {
|
||||
clampValue,
|
||||
flexLayout,
|
||||
kFormatter,
|
||||
measureText,
|
||||
buildSearchFilter,
|
||||
} from "../common/utils.js";
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { Card } from "../common/Card.js";
|
||||
import { getCardColors } from "../common/color.js";
|
||||
import { createProgressNode } from "../common/createProgressNode.js";
|
||||
import { formatBytes } from "../common/fmt.js";
|
||||
import { I18n } from "../common/I18n.js";
|
||||
import {
|
||||
chunkArray,
|
||||
@@ -10,7 +11,6 @@ import {
|
||||
flexLayout,
|
||||
lowercaseTrim,
|
||||
measureText,
|
||||
formatBytes,
|
||||
} from "../common/utils.js";
|
||||
import { langCardLocales } from "../translations.js";
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Retrieves num with suffix k(thousands) precise to given decimal places.
|
||||
*
|
||||
* @param {number} num The number to format.
|
||||
* @param {number=} precision The number of decimal places to include.
|
||||
* @returns {string|number} The formatted number.
|
||||
*/
|
||||
const kFormatter = (num, precision) => {
|
||||
const abs = Math.abs(num);
|
||||
const sign = Math.sign(num);
|
||||
|
||||
if (typeof precision === "number" && !isNaN(precision)) {
|
||||
return (sign * (abs / 1000)).toFixed(precision) + "k";
|
||||
}
|
||||
|
||||
if (abs < 1000) {
|
||||
return sign * abs;
|
||||
}
|
||||
|
||||
return sign * parseFloat((abs / 1000).toFixed(1)) + "k";
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert bytes to a human-readable string representation.
|
||||
*
|
||||
* @param {number} bytes The number of bytes to convert.
|
||||
* @returns {string} The human-readable representation of bytes.
|
||||
* @throws {Error} If bytes is negative or too large.
|
||||
*/
|
||||
const formatBytes = (bytes) => {
|
||||
if (bytes < 0) {
|
||||
throw new Error("Bytes must be a non-negative number");
|
||||
}
|
||||
|
||||
if (bytes === 0) {
|
||||
return "0 B";
|
||||
}
|
||||
|
||||
const sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB"];
|
||||
const base = 1024;
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(base));
|
||||
|
||||
if (i >= sizes.length) {
|
||||
throw new Error("Bytes is too large to convert to a human-readable string");
|
||||
}
|
||||
|
||||
return `${(bytes / Math.pow(base, i)).toFixed(1)} ${sizes[i]}`;
|
||||
};
|
||||
|
||||
export { kFormatter, formatBytes };
|
||||
@@ -10,7 +10,6 @@ export {
|
||||
ERROR_CARD_LENGTH,
|
||||
renderError,
|
||||
encodeHTML,
|
||||
kFormatter,
|
||||
parseBoolean,
|
||||
parseArray,
|
||||
clampValue,
|
||||
|
||||
@@ -78,28 +78,6 @@ const iconWithLabel = (icon, label, testid, iconSize) => {
|
||||
return flexLayout({ items: [iconSvg, text], gap: 20 }).join("");
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves num with suffix k(thousands) precise to given decimal places.
|
||||
*
|
||||
* @param {number} num The number to format.
|
||||
* @param {number=} precision The number of decimal places to include.
|
||||
* @returns {string|number} The formatted number.
|
||||
*/
|
||||
const kFormatter = (num, precision) => {
|
||||
const abs = Math.abs(num);
|
||||
const sign = Math.sign(num);
|
||||
|
||||
if (typeof precision === "number" && !isNaN(precision)) {
|
||||
return (sign * (abs / 1000)).toFixed(precision) + "k";
|
||||
}
|
||||
|
||||
if (abs < 1000) {
|
||||
return sign * abs;
|
||||
}
|
||||
|
||||
return sign * parseFloat((abs / 1000).toFixed(1)) + "k";
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns boolean if value is either "true" or "false" else the value as it is.
|
||||
*
|
||||
@@ -443,40 +421,12 @@ const dateDiff = (d1, d2) => {
|
||||
return Math.round(diff / (1000 * 60));
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert bytes to a human-readable string representation.
|
||||
*
|
||||
* @param {number} bytes The number of bytes to convert.
|
||||
* @returns {string} The human-readable representation of bytes.
|
||||
* @throws {Error} If bytes is negative or too large.
|
||||
*/
|
||||
const formatBytes = (bytes) => {
|
||||
if (bytes < 0) {
|
||||
throw new Error("Bytes must be a non-negative number");
|
||||
}
|
||||
|
||||
if (bytes === 0) {
|
||||
return "0 B";
|
||||
}
|
||||
|
||||
const sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB"];
|
||||
const base = 1024;
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(base));
|
||||
|
||||
if (i >= sizes.length) {
|
||||
throw new Error("Bytes is too large to convert to a human-readable string");
|
||||
}
|
||||
|
||||
return `${(bytes / Math.pow(base, i)).toFixed(1)} ${sizes[i]}`;
|
||||
};
|
||||
|
||||
export {
|
||||
ERROR_CARD_LENGTH,
|
||||
renderError,
|
||||
createLanguageNode,
|
||||
iconWithLabel,
|
||||
encodeHTML,
|
||||
kFormatter,
|
||||
parseBoolean,
|
||||
parseArray,
|
||||
clampValue,
|
||||
@@ -492,5 +442,4 @@ export {
|
||||
parseEmojis,
|
||||
parseOwnerAffiliations,
|
||||
dateDiff,
|
||||
formatBytes,
|
||||
};
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
// @ts-check
|
||||
|
||||
import { describe, expect, it } from "@jest/globals";
|
||||
import { queryByTestId } from "@testing-library/dom";
|
||||
import "@testing-library/jest-dom";
|
||||
import {
|
||||
encodeHTML,
|
||||
formatBytes,
|
||||
kFormatter,
|
||||
parseBoolean,
|
||||
renderError,
|
||||
wrapTextMultiline,
|
||||
} from "../src/common/utils.js";
|
||||
import { formatBytes, kFormatter } from "../src/common/fmt.js";
|
||||
|
||||
describe("Test utils.js", () => {
|
||||
it("should test kFormatter default behavior", () => {
|
||||
|
||||
Reference in New Issue
Block a user