Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
33 changes: 33 additions & 0 deletions packages/databases-collections-list/src/collections.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -554,4 +554,37 @@ describe('Collections', () => {
'Derived from foo'
);
});

it('renders a tooltip for storage size cell with storage breakdown and data size', async function () {
renderCollectionsList({
collections: colls,
});

const fooRow = screen.getByTestId('collections-list-row-foo');
expect(fooRow).to.exist;

const storageCell = fooRow.querySelector('td:nth-child(3)');
expect(storageCell).to.exist;

// Hover over the span inside the cell (the tooltip trigger)
const span = storageCell?.querySelector('span');
expect(span).to.exist;
userEvent.hover(span as Element);

await waitFor(
function () {
expect(screen.getByRole('tooltip')).to.exist;
},
{
timeout: 5000,
}
);

const tooltipText = screen.getByRole('tooltip').textContent;
expect(tooltipText).to.include('Storage Size:');
expect(tooltipText).to.include('1.00 kB');
expect(tooltipText).to.include('Used:');
expect(tooltipText).to.include('Free:');
expect(tooltipText).to.include('Data Size:');
});
});
48 changes: 45 additions & 3 deletions packages/databases-collections-list/src/collections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,51 @@ function collectionColumns({
if (type === 'view') {
return '-';
}
return enableDbAndCollStats && collection.storage_size !== undefined
? compactBytes(collection.storage_size)
: '-';

if (!enableDbAndCollStats || collection.storage_size === undefined) {
return '-';
}

const storageSize = collection.storage_size;
const freeStorageSize = collection.free_storage_size ?? 0;
const usedStorageSize = storageSize - freeStorageSize;
const documentSize = collection.document_size;
const displayValue = compactBytes(storageSize);

return (
<Tooltip
align="top"
justify="start"
trigger={({
children,
...props
}: React.PropsWithChildren<Record<string, unknown>>) => (
<span {...props}>
{displayValue}
{children}
</span>
)}
>
<div>
<div>
<strong>Storage Size:</strong> {compactBytes(storageSize)}{' '}
(total allocated)
</div>
<div>
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

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

The storage size is displayed twice: once in the tooltip trigger (line 314) and again in the tooltip content. Consider removing the redundant display from the tooltip content since users already see this value in the cell, or make it clear why it's repeated.

Suggested change
<strong>Storage Size:</strong> {compactBytes(storageSize)}{' '}
(total allocated)
</div>
<div>

Copilot uses AI. Check for mistakes.
<strong>Used:</strong> {compactBytes(usedStorageSize)}
</div>
<div>
<strong>Free:</strong> {compactBytes(freeStorageSize)}
</div>
{documentSize !== undefined && (
<div>
<strong>Data Size:</strong> {compactBytes(documentSize)}{' '}
(uncompressed)
</div>
)}
</div>
</Tooltip>
);
},
},
/*
Expand Down
32 changes: 32 additions & 0 deletions packages/databases-collections-list/src/databases.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -272,4 +272,36 @@ describe('Databases', function () {
'Your privileges grant you access to this namespace, but it might not currently exist'
);
});

it('renders a tooltip for storage size cell with storage and data size', async function () {
renderDatabasesList({
databases: dbs,
});

const fooRow = screen.getByTestId('databases-list-row-foo');
expect(fooRow).to.exist;

const storageCell = fooRow.querySelector('td:nth-child(2)');
expect(storageCell).to.exist;

// Hover over the span inside the cell (the tooltip trigger)
const span = storageCell?.querySelector('span');
expect(span).to.exist;
userEvent.hover(span as Element);

await waitFor(
function () {
expect(screen.getByRole('tooltip')).to.exist;
},
{
timeout: 5000,
}
);

const tooltipText = screen.getByRole('tooltip').textContent;
expect(tooltipText).to.include('Storage Size:');
expect(tooltipText).to.include('5.00 kB');
expect(tooltipText).to.include('Data Size:');
expect(tooltipText).to.include('1.00 kB');
});
});
39 changes: 36 additions & 3 deletions packages/databases-collections-list/src/databases.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,42 @@ function databaseColumns({
return <Placeholder maxChar={10}></Placeholder>;
}

return enableDbAndCollStats && database.storage_size !== undefined
? compactBytes(database.storage_size)
: '-';
if (!enableDbAndCollStats || database.storage_size === undefined) {
return '-';
}

const storageSize = database.storage_size;
const dataSize = database.data_size;
const displayValue = compactBytes(storageSize);

return (
<Tooltip
align="top"
justify="start"
trigger={({
children,
...props
}: React.PropsWithChildren<Record<string, unknown>>) => (
<span {...props}>
{displayValue}
{children}
</span>
)}
>
<div>
<div>
<strong>Storage Size:</strong> {compactBytes(storageSize)}{' '}
(total allocated)
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

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

The storage size is displayed twice: once in the tooltip trigger (line 149) and again in the tooltip content. Consider removing the redundant display from the tooltip content since users already see this value in the cell, or make it clear why it's repeated.

Suggested change
<strong>Storage Size:</strong> {compactBytes(storageSize)}{' '}
(total allocated)
<strong>Storage Size:</strong> total allocated space

Copilot uses AI. Check for mistakes.
</div>
{dataSize !== undefined && (
<div>
<strong>Data Size:</strong> {compactBytes(dataSize)}{' '}
(uncompressed)
</div>
)}
</div>
</Tooltip>
);
},
},
/*
Expand Down
Loading