Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
5,643 changes: 5,462 additions & 181 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion packages/compass-collection/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
"mongodb-collection-model": "^5.35.2",
"mongodb-ns": "^3.0.1",
"mongodb-schema": "^12.6.3",
"numeral": "^2.0.6",
"react": "^17.0.2",
"react-redux": "^8.1.3",
"redux": "^4.2.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
Body,
compactBytes,
css,
palette,
spacing,
Expand All @@ -9,7 +10,6 @@ import React, { useMemo } from 'react';
import { connect } from 'react-redux';
import type { CollectionState } from '../../modules/collection-tab';
import type { SchemaAnalysisState } from '../../schema-analysis-types';
import numeral from 'numeral';
import { DEFAULT_DOCUMENT_COUNT, MAX_DOCUMENT_COUNT } from './constants';

const BYTE_PRECISION_THRESHOLD = 1000;
Expand Down Expand Up @@ -40,8 +40,8 @@ const boldStyles = css({
});

const formatBytes = (bytes: number) => {
const precision = bytes <= BYTE_PRECISION_THRESHOLD ? '0' : '0.0';
return numeral(bytes).format(precision + 'b');
const decimals = bytes <= BYTE_PRECISION_THRESHOLD ? 0 : 1;
return compactBytes(bytes, true, decimals);
};

type ErrorState =
Expand Down Expand Up @@ -101,7 +101,7 @@ const DocumentCountScreen = ({
}
};

return schemaAnalysisState.status === 'complete' ? (
return (
<div>
<Body className={titleStyles}>
Specify Number of Documents to Generate
Expand Down Expand Up @@ -130,9 +130,6 @@ const DocumentCountScreen = ({
</div>
</div>
</div>
) : (
// Not reachable since schema analysis must be finished before the modal can be opened
<div>We are analyzing your collection.</div>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -706,10 +706,10 @@ describe('MockDataGeneratorModal', () => {
);
userEvent.clear(documentCountInput);
userEvent.type(documentCountInput, '1000');
expect(screen.getByText('100.0KB')).to.exist;
expect(screen.getByText('100.0 kB')).to.exist;
userEvent.clear(documentCountInput);
userEvent.type(documentCountInput, '2000');
expect(screen.getByText('200.0KB')).to.exist;
expect(screen.getByText('200.0 kB')).to.exist;
});
});

Expand Down
1 change: 1 addition & 0 deletions packages/compass-components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ export {
} from './components/links/link';
export { ChevronCollapse } from './components/chevron-collapse-icon';
export { formatDate } from './utils/format-date';
export { compactBytes, compactNumber } from './utils/format';
export {
VirtualList,
type VirtualListRef,
Expand Down
39 changes: 39 additions & 0 deletions packages/compass-components/src/utils/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Format bytes into a human-readable string with appropriate units.
*
* @param bytes - The number of bytes to format
* @param si - Use SI units (1000-based) if true, binary units (1024-based) if false
* @param decimals - Number of decimal places to show
* @returns Formatted string with units (e.g., "1.5 MB", "2.0 KiB")
*/
export function compactBytes(bytes: number, si = true, decimals = 2): string {
const threshold = si ? 1000 : 1024;
if (bytes === 0) {
return `${bytes} B`;
}
const units = si
? ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
: ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
const i = Math.floor(Math.log(bytes) / Math.log(threshold));
const num = bytes / Math.pow(threshold, i);
return `${num.toFixed(decimals)} ${units[i]}`;
Comment on lines 14 to 22
Copy link
Preview

Copilot AI Oct 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Math.log(bytes) will throw an error or return -Infinity for bytes <= 0. The function should handle negative values and zero case consistently.

Suggested change
const units = si
? ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
: ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
const i = Math.floor(Math.log(bytes) / Math.log(threshold));
const num = bytes / Math.pow(threshold, i);
return `${num.toFixed(decimals)} ${units[i]}`;
const isNegative = bytes < 0;
const absBytes = Math.abs(bytes);
const units = si
? ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
: ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
const i = Math.floor(Math.log(absBytes) / Math.log(threshold));
const num = absBytes / Math.pow(threshold, i);
return `${isNegative ? '-' : ''}${num.toFixed(decimals)} ${units[i]}`;

Copilot uses AI. Check for mistakes.

Copy link
Collaborator Author

@jcobis jcobis Oct 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do negative bytes make sense? If this is called with a negative value, my assumption is that that would indicate an error, and thus isn't something we should silently handle. Let me know if you feel otherwise though!

Copy link
Collaborator

@mabaasit mabaasit Oct 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what copilot suggested makes sense. Currently calling this function with negative bytes, returns NaN undefined. So we should handle this.

}

/**
* Format a number into a compact notation with appropriate suffix.
*
* @param number - The number to format
* @returns Formatted string with compact notation (e.g., "1.5 K", "2 M")
*/
export function compactNumber(number: number): string {
return new Intl.NumberFormat('en', {
notation: 'compact',
})
.formatToParts(number)
.reduce((acc, part) => {
if (part.type === 'compact') {
return `${acc} ${part.value}`;
}
return `${acc}${part.value}`;
}, '');
}
1 change: 0 additions & 1 deletion packages/compass-crud/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@
"mongodb-data-service": "^22.34.2",
"mongodb-ns": "^3.0.1",
"mongodb-query-parser": "^4.3.0",
"numeral": "^2.0.6",
"react": "^17.0.2",
"reflux": "^0.4.1",
"semver": "^7.6.3"
Expand Down
24 changes: 16 additions & 8 deletions packages/compass-crud/src/plugin-title.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import React, { useMemo } from 'react';
import numeral from 'numeral';
import { css, Tooltip, Badge, spacing } from '@mongodb-js/compass-components';
import {
css,
Tooltip,
Badge,
spacing,
compactBytes,
compactNumber,
} from '@mongodb-js/compass-components';
import type { CrudStore } from './stores/crud-store';
import { usePreference } from 'compass-preferences-model/provider';

Expand All @@ -22,12 +28,14 @@ const isNumber = (val: any): val is number => {
return typeof val === 'number' && !isNaN(val);
};

const format = (value: any, format = 'a') => {
const format = (value: any, formatType: 'number' | 'bytes' = 'number') => {
if (!isNumber(value)) {
return INVALID;
}
const precision = value <= 1000 ? '0' : '0.0';
return numeral(value).format(precision + format);
const decimals = value <= 1000 ? 0 : 1;
return formatType === 'bytes'
? compactBytes(value, true, decimals)
: compactNumber(value);
};

type CollectionStatsProps = {
Expand Down Expand Up @@ -84,9 +92,9 @@ export const CrudTabTitle = ({
avg_document_size = NaN,
} = collectionStats ?? {};
return {
documentCount: format(document_count),
storageSize: format(storage_size - free_storage_size, 'b'),
avgDocumentSize: format(avg_document_size, 'b'),
documentCount: format(document_count, 'number'),
storageSize: format(storage_size - free_storage_size, 'bytes'),
avgDocumentSize: format(avg_document_size, 'bytes'),
};
}, [collectionStats]);
const enableDbAndCollStats = usePreference('enableDbAndCollStats');
Expand Down
2 changes: 0 additions & 2 deletions packages/compass-indexes/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
"@mongodb-js/prettier-config-compass": "^1.2.9",
"@mongodb-js/testing-library-compass": "^1.3.16",
"@mongodb-js/tsconfig-compass": "^1.2.11",
"@types/numeral": "^2.0.5",
"chai": "^4.2.0",
"depcheck": "^1.4.1",
"electron": "^37.6.0",
Expand Down Expand Up @@ -88,7 +87,6 @@
"mongodb-mql-engines": "^0.0.4",
"mongodb-ns": "^3.0.1",
"mongodb-query-parser": "^4.3.0",
"numeral": "^2.0.6",
"react": "^17.0.2",
"react-redux": "^8.1.3",
"redux": "^4.2.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ describe('SizeField', function () {
describe('SizeField functions', function () {
it('formats size', function () {
expect(formatSize(908)).to.equal('908 B');
expect(formatSize(2020)).to.equal('2.0 KB');
expect(formatSize(202020)).to.equal('202.0 KB');
expect(formatSize(2020)).to.equal('2.0 kB');
expect(formatSize(202020)).to.equal('202.0 kB');
});

it('returns correct tooltip', function () {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import numeral from 'numeral';
import React from 'react';
import { Body, Tooltip } from '@mongodb-js/compass-components';
import { Body, Tooltip, compactBytes } from '@mongodb-js/compass-components';

type SizeFieldProps = {
size: number;
relativeSize: number;
};

export const formatSize = (size: number) => {
const precision = size <= 1000 ? '0' : '0.0';
return numeral(size).format(precision + ' b');
const decimals = size <= 1000 ? 0 : 1;
return compactBytes(size, true, decimals);
};

export const getSizeTooltip = (relativeSize: number): string => {
Expand Down
24 changes: 16 additions & 8 deletions packages/compass-indexes/src/plugin-title.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import React, { useMemo } from 'react';
import { connect } from 'react-redux';
import type { RootState } from './modules';
import { Badge, css, spacing, Tooltip } from '@mongodb-js/compass-components';
import numeral from 'numeral';
import {
Badge,
css,
spacing,
Tooltip,
compactBytes,
compactNumber,
} from '@mongodb-js/compass-components';
import { usePreference } from 'compass-preferences-model/provider';

const containerStyles = css({
Expand Down Expand Up @@ -30,12 +36,14 @@ const isNumber = (val: any): val is number => {
return typeof val === 'number' && !isNaN(val);
};

const format = (value: any, format = 'a') => {
const format = (value: any, formatType: 'number' | 'bytes' = 'number') => {
if (!isNumber(value)) {
return INVALID;
}
const precision = value <= 1000 ? '0' : '0.0';
return numeral(value).format(precision + format);
const decimals = value <= 1000 ? 0 : 1;
return formatType === 'bytes'
? compactBytes(value, true, decimals)
: compactNumber(value);
};

type CollectionStatsProps = {
Expand Down Expand Up @@ -85,9 +93,9 @@ const TabTitle = ({
const { indexCount, totalIndexSize, avgIndexSize } = useMemo(() => {
const { index_count = NaN, index_size = NaN } = collectionStats ?? {};
return {
indexCount: format(index_count),
totalIndexSize: format(index_size, 'b'),
avgIndexSize: format(avg(index_size, index_count), 'b'),
indexCount: format(index_count, 'number'),
totalIndexSize: format(index_size, 'bytes'),
avgIndexSize: format(avg(index_size, index_count), 'bytes'),
};
}, [collectionStats]);

Expand Down
1 change: 1 addition & 0 deletions packages/compass-schema/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"@types/leaflet": "^1.9.8",
"@types/leaflet-draw": "^1.0.11",
"@types/mocha": "^9.0.0",
"@types/numeral": "^2.0.5",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this intentional?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is needed because packages/compass-schema/src/components/type.tsx and packages/compass-schema/src/components/array-minichart.tsx use numeral

"@types/react": "^17.0.5",
"@types/react-dom": "^17.0.10",
"chai": "^4.3.4",
Expand Down
Loading