43 lines
1.6 KiB
TypeScript
43 lines
1.6 KiB
TypeScript
/**
|
|
* Central binary (1024) data-size formatting for the UI.
|
|
*
|
|
* - Use formatBinaryDataSizeBytes for raw byte counts (files, RAG totals, …).
|
|
* - Use formatBinaryDataSizeFromMebibytes for API fields stored as MB (mebibytes), e.g. maxDataVolumeMB.
|
|
*/
|
|
|
|
const BINARY_BASE = 1024;
|
|
const BINARY_UNITS = ['B', 'KB', 'MB', 'GB', 'TB'] as const;
|
|
|
|
function _maxFractionDigits(value: number): number {
|
|
if (value >= 100 || Number.isInteger(value)) return 0;
|
|
if (value >= 10) return 1;
|
|
return 2;
|
|
}
|
|
|
|
/**
|
|
* Human-readable size from a byte count; picks B … TB automatically (1024-based).
|
|
*/
|
|
export function formatBinaryDataSizeBytes(bytes: number, localeId = 'de-CH'): string {
|
|
if (!Number.isFinite(bytes)) return '—';
|
|
if (bytes < 0) return '—';
|
|
if (bytes === 0) return `0 ${BINARY_UNITS[0]}`;
|
|
|
|
const rawExp = Math.floor(Math.log(bytes) / Math.log(BINARY_BASE));
|
|
const exp = Math.max(0, Math.min(BINARY_UNITS.length - 1, rawExp));
|
|
const value = bytes / BINARY_BASE ** exp;
|
|
const maxFrac = _maxFractionDigits(value);
|
|
const formatted = new Intl.NumberFormat(localeId, {
|
|
maximumFractionDigits: maxFrac,
|
|
minimumFractionDigits: 0,
|
|
}).format(value);
|
|
return `${formatted} ${BINARY_UNITS[exp]}`;
|
|
}
|
|
|
|
/**
|
|
* Same as formatBinaryDataSizeBytes, but input is mebibytes (API convention for plan limits).
|
|
*/
|
|
export function formatBinaryDataSizeFromMebibytes(mebibytes: number, localeId = 'de-CH'): string {
|
|
if (!Number.isFinite(mebibytes) || mebibytes < 0) return '—';
|
|
if (mebibytes === 0) return `0 ${BINARY_UNITS[0]}`;
|
|
return formatBinaryDataSizeBytes(mebibytes * BINARY_BASE * BINARY_BASE, localeId);
|
|
}
|