diff --git a/doc/guide/cockpit-util.xml b/doc/guide/cockpit-util.xml
index 9bff53e62e4..c2db7ea6719 100644
--- a/doc/guide/cockpit-util.xml
+++ b/doc/guide/cockpit-util.xml
@@ -44,75 +44,44 @@ string = cockpit.format_number(number, [precision])
cockpit.format_bytes()
-string = cockpit.format_bytes(number, [factor])
-array = cockpit.format_bytes(number, [factor, options])
+string = cockpit.format_bytes(number, [options])
Formats number
into a displayable string
with a suffix, such as
- KB or MB. Returns an array
of the
- formatted number and the suffix if options.separate
is set to true
.
+ KB or MB.
- If specifying 1000 or 1024 is specified as a factor
then an appropriate suffix
- will be chosen. By default the factor
is 1000. You can pass a string suffix as a
- factor
in which case the resulting number will be formatted with the same suffix.
-
- If the number
is less than the factor
or an unknown factor
- was passed in, then the formatted number is returned without a suffix. If options.separate
- is true, returns an array of [formatted_number, suffix]
or
- [formatted_number]
if returned without a suffix.
+ By default, SI units are used. IEC units (1024-based) can be requested by including
+ base2: true
in options
.
By default, non-integer numbers will be formatted with 3 digits of precision. This can be changed
with options.precision
.
- If number
is null
or undefined
an empty string or
- an array without a suffix will be returned.
+ If number
is null
or undefined
an empty string will be
+ returned.
cockpit.format_bytes_per_sec()
- string = cockpit.format_bytes_per_sec(number, [factor])
- array = cockpit.format_bytes_per_sec(number, [factor, options])
+string = cockpit.format_bytes_per_sec(number, [options])
Format number
of bytes into a displayable speed string
.
- If specifying 1000 or 1024 is specified as a factor
then an appropriate suffix
- will be chosen. By default the factor
is 1000. You can pass a string suffix as a
- factor
in which case the resulting number will be formatted with the same suffix.
-
- If the number
is less than the factor
or an unknown factor
- was passed in, then the formatted number is returned without a suffix. If options.separate
- is true, returns an array of [formatted_number, suffix]
or
- [formatted_number]
if returned without a suffix.
-
- By default, non-integer numbers will be formatted with 3 digits of precision. This can be changed
- with options.precision
.
-
- If number
is null
or undefined
an empty string or array
- will be returned.
+ This function is mostly equivalent to cockpit.format_bytes()
but the returned
+ value contains a unit like KB/s or MB/s.
cockpit.format_bits_per_sec()
- string = cockpit.format_bits_per_sec(number, [factor])
- array = cockpit.format_bytes_per_sec(number, [factor, options])
+string = cockpit.format_bits_per_sec(number, [options])
Format number
of bits into a displayable speed string
.
- If specifying 1000 or 1024 is specified as a factor
then an appropriate suffix
- will be chosen. By default the factor
is 1000. You can pass a string suffix as a
- factor
in which case the resulting number will be formatted with the same suffix.
-
- If the number
is less than the factor
or an unknown factor
- was passed in, then the formatted number is returned without a suffix. If options.separate
- is true, returns an array of [formatted_number, suffix]
or
- [formatted_number]
if returned without a suffix.
-
- By default, non-integer numbers will be formatted with 3 digits of precision. This can be changed
- with options.precision
.
+ This function is mostly equivalent to cockpit.format_bytes()
but the returned
+ value contains a unit like kbps or Mbps.
- If number
is null
or undefined
an empty string or array
- will be returned.
+ This function does not support IEC units. base2
may not be passed as part of
+ options
.
diff --git a/files.js b/files.js
index 32fe3e834c3..45254199952 100644
--- a/files.js
+++ b/files.js
@@ -53,7 +53,7 @@ const info = {
"base1/test-events.js",
"base1/test-external.js",
"base1/test-file.js",
- "base1/test-format.js",
+ "base1/test-format.ts",
"base1/test-framed-cache.js",
"base1/test-framed.js",
"base1/test-http.js",
diff --git a/pkg/base1/test-format.js b/pkg/base1/test-format.ts
similarity index 74%
rename from pkg/base1/test-format.js
rename to pkg/base1/test-format.ts
index 0294fcd6c80..ce60c18a116 100644
--- a/pkg/base1/test-format.js
+++ b/pkg/base1/test-format.ts
@@ -1,5 +1,5 @@
import cockpit from "cockpit";
-import QUnit from "qunit-tests";
+import QUnit, { f } from "qunit-tests";
QUnit.test("format", function (assert) {
assert.equal(cockpit.format("My $adj message with ${amount} of things", { adj: "special", amount: "lots" }),
@@ -42,7 +42,7 @@ QUnit.test("format_number", function (assert) {
[-123.01, "-123", "-123"],
[null, "", ""],
[undefined, "", ""],
- ];
+ ] as const;
const saved_language = cockpit.language;
@@ -51,19 +51,22 @@ QUnit.test("format_number", function (assert) {
cockpit.language = 'en';
for (let i = 0; i < checks.length; i++) {
assert.strictEqual(cockpit.format_number(checks[i][0]), checks[i][1],
- "format_number@en(" + checks[i][0] + ") = " + checks[i][1]);
+ f`format_number@en(${checks[i][0]})`
+ );
}
cockpit.language = 'de';
for (let i = 0; i < checks.length; i++) {
assert.strictEqual(cockpit.format_number(checks[i][0]), checks[i][2],
- "format_number@de(" + checks[i][0] + ") = " + checks[i][2]);
+ f`format_number@de(${checks[i][0]})`
+ );
}
cockpit.language = 'pt_BR';
for (let i = 0; i < checks.length; i++) {
assert.strictEqual(cockpit.format_number(checks[i][0]), checks[i][2],
- "format_number@pt_BR(" + checks[i][0] + ") = " + checks[i][2]);
+ f`format_number@pt_BR(${checks[i][0]})`
+ );
}
/* restore this as not to break the other tests */
@@ -101,17 +104,30 @@ QUnit.test("format_bytes", function (assert) {
[0, "KB", "0 KB"],
[undefined, "KB", ""],
[null, "KB", ""],
- ];
+ ] as const;
- assert.expect(checks.length * 2 + 2);
+ for (let i = 0; i < checks.length; i++) {
+ if (typeof checks[i][1] === 'string') {
+ // these tests are for backwards compatibility only
+ continue;
+ }
+
+ const base2 = checks[i][1] == 1024;
+ assert.strictEqual(cockpit.format_bytes(checks[i][0], { base2 }), checks[i][2],
+ f`format_bytes(${checks[i][0]}, ${{ base2 }})`);
+ }
+
+ // old API style (deprecated)
for (let i = 0; i < checks.length; i++) {
assert.strictEqual(cockpit.format_bytes(checks[i][0], checks[i][1]), checks[i][2],
- "format_bytes(" + checks[i][0] + ", " + String(checks[i][1]) + ") = " + checks[i][2]);
+ f`format_bytes(${checks[i][0]}, ${checks[i][1]})`
+ );
}
for (let i = 0; i < checks.length; i++) {
const split = checks[i][2].split(" ");
assert.deepEqual(cockpit.format_bytes(checks[i][0], checks[i][1], { separate: true }), split,
- "format_bytes(" + checks[i][0] + ", " + String(checks[i][1]) + ", true) = " + split);
+ f`format_bytes(${checks[i][0]}, ${checks[i][1]}, ${{ separate: true }})`
+ );
}
// backwards compatible API: format_bytes with a boolean options (used to be a single "separate" flag)
@@ -119,38 +135,6 @@ QUnit.test("format_bytes", function (assert) {
assert.deepEqual(cockpit.format_bytes(2500000, 1000, true), ["2.50", "MB"]);
});
-QUnit.test("get_byte_units", function (assert) {
- const mib = 1024 * 1024;
- const gib = mib * 1024;
- const tib = gib * 1024;
-
- const mib_unit = { factor: mib, name: "MiB" };
- const gib_unit = { factor: gib, name: "GiB" };
- const tib_unit = { factor: tib, name: "TiB" };
-
- function selected(unit) {
- return { factor: unit.factor, name: unit.name, selected: true };
- }
-
- const checks = [
- [0 * mib, 1024, [selected(mib_unit), gib_unit, tib_unit]],
- [20 * mib, 1024, [selected(mib_unit), gib_unit, tib_unit]],
- [200 * mib, 1024, [selected(mib_unit), gib_unit, tib_unit]],
- [2000 * mib, 1024, [selected(mib_unit), gib_unit, tib_unit]],
- [20000 * mib, 1024, [mib_unit, selected(gib_unit), tib_unit]],
- [20 * gib, 1024, [mib_unit, selected(gib_unit), tib_unit]],
- [200 * gib, 1024, [mib_unit, selected(gib_unit), tib_unit]],
- [2000 * gib, 1024, [mib_unit, selected(gib_unit), tib_unit]],
- [20000 * gib, 1024, [mib_unit, gib_unit, selected(tib_unit)]]
- ];
-
- assert.expect(checks.length);
- for (let i = 0; i < checks.length; i++) {
- assert.deepEqual(cockpit.get_byte_units(checks[i][0], checks[i][1]), checks[i][2],
- "get_byte_units(" + checks[i][0] + ", " + checks[i][1] + ") = " + JSON.stringify(checks[i][2]));
- }
-});
-
QUnit.test("format_bytes_per_sec", function (assert) {
const checks = [
// default unit
@@ -171,18 +155,28 @@ QUnit.test("format_bytes_per_sec", function (assert) {
// significant integer digits exceed custom precision
[25555000, "kB/s", { precision: 2 }, "25555 kB/s"],
[25555678, "kB/s", { precision: 2 }, "25556 kB/s"],
- ];
+ ] as const;
- assert.expect(checks.length + 2);
for (let i = 0; i < checks.length; i++) {
- assert.strictEqual(cockpit.format_bytes_per_sec(checks[i][0], checks[i][1], checks[i][2]), checks[i][3],
- `format_bytes_per_sec(${checks[i][0]}, ${checks[i][1]}, ${checks[i][2]}) = ${checks[i][3]}`);
+ if (typeof checks[i][1] === 'string') {
+ // these tests are for backwards compatibility only
+ continue;
+ }
+
+ const base2 = checks[i][1] == 1024;
+ assert.strictEqual(cockpit.format_bytes_per_sec(checks[i][0], { base2, ...checks[i][2] }), checks[i][3],
+ f`format_bytes_per_sec(${checks[i][0]}, ${{ base2, ...checks[i][2] }})`);
}
- // separate unit
+ // old API style (deprecated)
+ for (let i = 0; i < checks.length; i++) {
+ assert.strictEqual(cockpit.format_bytes_per_sec(checks[i][0], checks[i][1], checks[i][2]), checks[i][3],
+ f`format_bytes_per_sec(${checks[i][0]}, ${checks[i][1]}, ${checks[i][2]})`);
+ }
+ // separate unit (very deprecated)
assert.deepEqual(cockpit.format_bytes_per_sec(2555, 1024, { separate: true }),
["2.50", "KiB/s"]);
- // backwards compatible API for separate flag
+ // backwards compatible API for separate flag (oh so very deprecated)
assert.deepEqual(cockpit.format_bytes_per_sec(2555, 1024, true),
["2.50", "KiB/s"]);
});
@@ -195,12 +189,12 @@ QUnit.test("format_bits_per_sec", function (assert) {
[2555, "2.56 Kbps"],
[2000, "2 Kbps"],
[2003, "2.00 Kbps"]
- ];
+ ] as const;
assert.expect(checks.length);
for (let i = 0; i < checks.length; i++) {
assert.strictEqual(cockpit.format_bits_per_sec(checks[i][0]), checks[i][1],
- "format_bits_per_sec(" + checks[i][0] + ") = " + checks[i][1]);
+ f`format_bits_per_sec(${checks[i][0]})`);
}
});
diff --git a/pkg/lib/cockpit.d.ts b/pkg/lib/cockpit.d.ts
index 4a95c0f09a5..54100f1c9ae 100644
--- a/pkg/lib/cockpit.d.ts
+++ b/pkg/lib/cockpit.d.ts
@@ -28,6 +28,8 @@ declare module 'cockpit' {
function assert(predicate: unknown, message?: string): asserts predicate;
+ export let language: string;
+
/* === Events mix-in ========================= */
interface EventMap {
@@ -193,17 +195,6 @@ declare module 'cockpit' {
/* === String helpers ======================== */
- type FormatOptions = {
- precision?: number;
- separate?: boolean;
- };
-
- type ByteUnit = {
- name: string | null;
- factor: number;
- selected?: boolean;
- };
-
function message(problem: string | JsonObject): string;
function gettext(message: string): string;
@@ -212,12 +203,21 @@ declare module 'cockpit' {
function ngettext(context: string, message1: string, messageN: string, n: number): string;
function format(format_string: string, ...args: unknown[]): string;
- function format_number(n: number, precision?: number): string
- function format_bytes(n: number, factor?: 1000 | 1024, options?: FormatOptions & { separate?: false }): string;
- function format_bytes(n: number, factor: 1000 | 1024, options: FormatOptions & { separate: true }): string[];
- function format_bytes_per_sec(n: number, factor?: 1000 | 1024, options?: FormatOptions & { separate?: false }): string;
- function format_bytes_per_sec(n: number, factor: 1000 | 1024, options: FormatOptions & { separate: true }): string[];
- function format_bits_per_sec(n: number, factor?: 1000 | 1024, options?: FormatOptions & { separate?: false }): string;
- function format_bits_per_sec(n: number, factor: 1000 | 1024, options: FormatOptions & { separate: true }): string[];
- function get_byte_units(guide_value: number, factor?: 1000 | 1024): ByteUnit[];
+
+ /* === Number formatting ===================== */
+
+ type FormatOptions = {
+ precision?: number;
+ base2?: boolean;
+ };
+ type MaybeNumber = number | null | undefined;
+
+ function format_number(n: MaybeNumber, precision?: number): string
+ function format_bytes(n: MaybeNumber, options?: FormatOptions): string;
+ function format_bytes_per_sec(n: MaybeNumber, options?: FormatOptions): string;
+ function format_bits_per_sec(n: MaybeNumber, options?: FormatOptions & { base2?: false }): string;
+
+ /** @deprecated */ function format_bytes(n: MaybeNumber, factor: unknown, options?: object | boolean): string | string[];
+ /** @deprecated */ function format_bytes_per_sec(n: MaybeNumber, factor: unknown, options?: object | boolean): string | string[];
+ /** @deprecated */ function format_bits_per_sec(n: MaybeNumber, factor: unknown, options?: object | boolean): string | string[];
}
diff --git a/pkg/lib/cockpit.js b/pkg/lib/cockpit.js
index 427660de901..79677062ea8 100644
--- a/pkg/lib/cockpit.js
+++ b/pkg/lib/cockpit.js
@@ -1483,10 +1483,24 @@ function factory() {
});
};
- function format_units(number, suffixes, factor, options) {
- // backwards compat: "options" argument position used to be a boolean flag "separate"
- if (!is_object(options))
- options = { separate: options };
+ let deprecated_format_warned = false;
+ function format_units(suffixes, number, second_arg, third_arg) {
+ let options = second_arg;
+ let factor = options?.base2 ? 1024 : 1000;
+
+ // compat API: we used to accept 'factor' as a separate second arg
+ if (third_arg || (second_arg && !is_object(second_arg))) {
+ if (!deprecated_format_warned) {
+ console.warn(`cockpit.format_{bytes,bits}[_per_sec](..., ${second_arg}, ${third_arg}) is deprecated.`);
+ deprecated_format_warned = true;
+ }
+
+ factor = second_arg || 1000;
+ options = third_arg;
+ // double backwards compat: "options" argument position used to be a boolean flag "separate"
+ if (!is_object(options))
+ options = { separate: options };
+ }
let suffix = null;
@@ -1525,7 +1539,7 @@ function factory() {
}
}
- const string_representation = cockpit.format_number(number, options.precision);
+ const string_representation = cockpit.format_number(number, options?.precision);
let ret;
if (string_representation && suffix)
@@ -1533,7 +1547,7 @@ function factory() {
else
ret = [string_representation];
- if (!options.separate)
+ if (!options?.separate)
ret = ret.join(" ");
return ret;
@@ -1544,36 +1558,8 @@ function factory() {
1024: [null, "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB"]
};
- cockpit.format_bytes = function format_bytes(number, factor, options) {
- if (factor === undefined)
- factor = 1000;
- return format_units(number, byte_suffixes, factor, options);
- };
-
- cockpit.get_byte_units = function get_byte_units(guide_value, factor) {
- if (factor === undefined || !(factor in byte_suffixes))
- factor = 1000;
-
- function unit(index) {
- return {
- name: byte_suffixes[factor][index],
- factor: Math.pow(factor, index)
- };
- }
-
- const units = [unit(2), unit(3), unit(4)];
-
- // The default unit is the largest one that gives us at least
- // two decimal digits in front of the comma.
-
- for (let i = units.length - 1; i >= 0; i--) {
- if (i === 0 || (guide_value / units[i].factor) >= 10) {
- units[i].selected = true;
- break;
- }
- }
-
- return units;
+ cockpit.format_bytes = function format_bytes(number, ...args) {
+ return format_units(byte_suffixes, number, ...args);
};
const byte_sec_suffixes = {
@@ -1581,20 +1567,16 @@ function factory() {
1024: ["B/s", "KiB/s", "MiB/s", "GiB/s", "TiB/s", "PiB/s", "EiB/s", "ZiB/s"]
};
- cockpit.format_bytes_per_sec = function format_bytes_per_sec(number, factor, options) {
- if (factor === undefined)
- factor = 1000;
- return format_units(number, byte_sec_suffixes, factor, options);
+ cockpit.format_bytes_per_sec = function format_bytes_per_sec(number, ...args) {
+ return format_units(byte_sec_suffixes, number, ...args);
};
const bit_suffixes = {
1000: ["bps", "Kbps", "Mbps", "Gbps", "Tbps", "Pbps", "Ebps", "Zbps"]
};
- cockpit.format_bits_per_sec = function format_bits_per_sec(number, factor, options) {
- if (factor === undefined)
- factor = 1000;
- return format_units(number, bit_suffixes, factor, options);
+ cockpit.format_bits_per_sec = function format_bits_per_sec(number, ...args) {
+ return format_units(bit_suffixes, number, ...args);
};
/* ---------------------------------------------------------------------
diff --git a/pkg/lib/qunit-tests.ts b/pkg/lib/qunit-tests.ts
index 8dc1e835211..48ba2f1d761 100644
--- a/pkg/lib/qunit-tests.ts
+++ b/pkg/lib/qunit-tests.ts
@@ -87,4 +87,22 @@ qunitTap(QUnit, function(message: string, ...args: unknown[]) {
console.log(message, args);
});
+export function f(format: TemplateStringsArray, ...args: unknown[]) {
+ const strings = [...format].reverse();
+ args.reverse();
+
+ const parts = [strings.pop()];
+ if (strings.length !== args.length) {
+ throw new Error('unequal strings and args in f-string');
+ }
+
+ while (args.length !== 0) {
+ const arg = args.pop();
+ parts.push(JSON.stringify(arg) || String(arg));
+ parts.push(strings.pop());
+ }
+
+ return parts.join('');
+}
+
export default QUnit;
diff --git a/pkg/storaged/dialog.jsx b/pkg/storaged/dialog.jsx
index fe5f64f1390..3f33ea00895 100644
--- a/pkg/storaged/dialog.jsx
+++ b/pkg/storaged/dialog.jsx
@@ -240,7 +240,7 @@ import { show_modal_dialog, apply_modal_dialog } from "cockpit-components-dialog
import { ListingTable } from "cockpit-components-table.jsx";
import { FormHelper } from "cockpit-components-form-helper";
-import { fmt_size, block_name, format_size_and_text, format_delay, for_each_async } from "./utils.js";
+import { fmt_size, block_name, format_size_and_text, format_delay, for_each_async, get_byte_units } from "./utils.js";
import { fmt_to_fragments } from "utils.jsx";
import client from "./client.js";
@@ -977,7 +977,7 @@ function size_slider_round(value, round) {
class SizeSliderElement extends React.Component {
constructor(props) {
super();
- this.units = cockpit.get_byte_units(props.value || props.max);
+ this.units = get_byte_units(props.value || props.max);
this.state = { unit: this.units.find(u => u.selected).factor };
}
diff --git a/pkg/storaged/test-util.js b/pkg/storaged/test-util.js
index 2a53d3d43da..55cb668cc08 100644
--- a/pkg/storaged/test-util.js
+++ b/pkg/storaged/test-util.js
@@ -18,7 +18,7 @@
*/
import * as utils from "./utils.js";
-import QUnit from "qunit-tests";
+import QUnit, { f } from "qunit-tests";
QUnit.test("format_delay", function (assert) {
const checks = [
@@ -81,6 +81,79 @@ QUnit.test("mdraid_name_local_transient", function (assert) {
utils.mock_hostnamed(null);
});
+QUnit.test("get_byte_units", function (assert) {
+ const mb = 1000 * 1000;
+ const gb = mb * 1000;
+ const tb = gb * 1000;
+
+ const mb_unit = { factor: mb, name: "MB" };
+ const gb_unit = { factor: gb, name: "GB" };
+ const tb_unit = { factor: tb, name: "TB" };
+
+ function selected(unit) {
+ return { factor: unit.factor, name: unit.name, selected: true };
+ }
+
+ const checks = [
+ [0 * mb, [selected(mb_unit), gb_unit, tb_unit]],
+ [20 * mb, [selected(mb_unit), gb_unit, tb_unit]],
+ [200 * mb, [selected(mb_unit), gb_unit, tb_unit]],
+ [2000 * mb, [selected(mb_unit), gb_unit, tb_unit]],
+ [20000 * mb, [mb_unit, selected(gb_unit), tb_unit]],
+ [20 * gb, [mb_unit, selected(gb_unit), tb_unit]],
+ [200 * gb, [mb_unit, selected(gb_unit), tb_unit]],
+ [2000 * gb, [mb_unit, selected(gb_unit), tb_unit]],
+ [20000 * gb, [mb_unit, gb_unit, selected(tb_unit)]]
+ ];
+
+ assert.expect(checks.length);
+ for (let i = 0; i < checks.length; i++) {
+ assert.deepEqual(utils.get_byte_units(checks[i][0]), checks[i][1],
+ "get_byte_units(" + checks[i][0] + ") = " + JSON.stringify(checks[i][1]));
+ }
+});
+
+QUnit.test("format_fsys_usage", function (assert) {
+ const [k, M, G, T] = [1_000, 1_000_000, 1_000_000_000, 1_000_000_000_000];
+
+ const sizes = [5, 200, 5 * k, 200 * k, 5 * M, 200 * M, 5 * G, 200 * G, 5 * T, 200 * T];
+ /* For each "total" size, format all of the "used" sizes less than or equal to it.
+ * The results table lists the part that should come after and before the slash, respectively.
+ * For example: ["5 KB", ["0.01", "0.20", "5"]]
+ * means 5, 200 and 5k out of 5k are displayed as "0.01 / 5KB", "0.20 / 5KB" and "5 / 5KB"
+ */
+ const results = [
+ ["5", ["5"]],
+ ["200", ["5", "200"]],
+ ["5 KB", ["0.01", "0.20", "5"]],
+ ["200 KB", ["0.01", "0.20", "5", "200"]],
+ ["5 MB", ["0.01", "0.01", "0.01", "0.20", "5"]],
+ ["200 MB", ["0.01", "0.01", "0.01", "0.20", "5", "200"]],
+ ["5 GB", ["0.01", "0.01", "0.01", "0.01", "0.01", "0.20", "5"]],
+ ["200 GB", ["0.01", "0.01", "0.01", "0.01", "0.01", "0.20", "5", "200"]],
+ ["5 TB", ["0.01", "0.01", "0.01", "0.01", "0.01", "0.01", "0.01", "0.20", "5"]],
+ ["200 TB", ["0.01", "0.01", "0.01", "0.01", "0.01", "0.01", "0.01", "0.20", "5", "200"]],
+ ];
+
+ for (let total_i = 0; total_i < results.length; total_i++) {
+ const [total_string, used_strings] = results[total_i];
+ assert.strictEqual(used_strings.length, total_i + 1);
+ for (let used_i = 0; used_i < used_strings.length; used_i++) {
+ const used_string = used_strings[used_i];
+
+ const used = sizes[used_i];
+ const total = sizes[total_i];
+ const expected_string = used_string + " / " + total_string;
+
+ assert.strictEqual(
+ utils.format_fsys_usage(used, total),
+ expected_string,
+ f`format_fsys_usage(${used}, ${total})`
+ );
+ }
+ }
+});
+
/* Wait until the hostnamed dbus proxy is actually ready; otherwise the test
* finishes and kills the bridge before it can respond to the dbus channel open
* request for the hostnamed connection, which can cause hangs in
diff --git a/pkg/storaged/utils.js b/pkg/storaged/utils.js
index f09a444f257..600af8b49b7 100644
--- a/pkg/storaged/utils.js
+++ b/pkg/storaged/utils.js
@@ -1140,3 +1140,16 @@ export function get_mount_points(client, block_fsys, subvol) {
return mounted_at;
}
+
+export function get_byte_units(guide_value) {
+ const units = [
+ { factor: 1000 ** 2, name: "MB" },
+ { factor: 1000 ** 3, name: "GB" },
+ { factor: 1000 ** 4, name: "TB" },
+ ];
+ // Find the biggest unit which gives two digits left of the decimal point (>= 10)
+ const unit = units.findLastIndex(unit => guide_value / unit.factor >= 10);
+ // Mark it selected. If we couldn't find one (-1), then use MB.
+ units[Math.max(0, unit)].selected = true;
+ return units;
+}