Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
4e37ed6
export more leafygreen table components
lerouxb Sep 29, 2025
e952447
databases & collections tables
lerouxb Sep 30, 2025
4907992
Merge branch 'main' into table-not-cards
lerouxb Oct 10, 2025
fa5add7
remove the item grid
lerouxb Oct 10, 2025
c20b2fd
name column changes
lerouxb Oct 10, 2025
ba9091a
port the inferred_from_privileges code to the new tables
lerouxb Oct 13, 2025
2f953b2
port perf insights to the table
lerouxb Oct 13, 2025
93eed90
outdated comment
lerouxb Oct 14, 2025
9410a73
resize the columns
lerouxb Oct 14, 2025
a094b6b
more column fixes
lerouxb Oct 14, 2025
35005a7
let's not add data size before speaking to someone
lerouxb Oct 14, 2025
6ac88e6
Merge branch 'main' into table-not-cards
lerouxb Oct 14, 2025
3f36c86
add delete button support
lerouxb Oct 15, 2025
e4360f3
add placeholders
lerouxb Oct 15, 2025
363856e
size to fit
lerouxb Oct 15, 2025
0e7e802
remove the databases/collections lists unit tests for now because vir…
lerouxb Oct 16, 2025
9c015e0
Merge branch 'main' into table-not-cards
lerouxb Oct 16, 2025
d17f9ec
should be optional
lerouxb Oct 16, 2025
71e8286
port the e2e tests
lerouxb Oct 16, 2025
0d598de
Merge branch 'main' into table-not-cards
lerouxb Oct 16, 2025
401e436
cleanup
lerouxb Oct 16, 2025
a28ec52
yay copilot
lerouxb Oct 16, 2025
53767c3
will add these back in a second
lerouxb Oct 16, 2025
833ef80
dummy tests to make CI happy for now
lerouxb Oct 17, 2025
f9ff633
scroll the workspace, not the table
lerouxb Oct 17, 2025
14fb71a
more typesafe without casting
lerouxb Oct 17, 2025
8549d4f
ignore some more
lerouxb Oct 17, 2025
d23b4ec
properties column to match indexes table until told otherwise
lerouxb Oct 17, 2025
589d5be
debug the virtual scrolling
lerouxb Oct 17, 2025
5eda9b0
fix the virtual scrolling e2e helper
lerouxb Oct 17, 2025
1885ff9
actually just the table height
lerouxb Oct 17, 2025
2fc1ce7
remove TODOs
lerouxb Oct 17, 2025
a722b41
turns out you need accessorKey for sorting to work
lerouxb Oct 17, 2025
f60913e
scroll some more just in case
lerouxb Oct 20, 2025
b262ba2
also sort by Properties
lerouxb Oct 20, 2025
6945d1b
make it possible to opt out of virual rendering (for tests)
lerouxb Oct 20, 2025
ea9d0d1
don't use browser scrolling since we already scrolled using scrollToV…
lerouxb Oct 20, 2025
050722f
don't screenshot. things aren't cards anymore anyway
lerouxb Oct 20, 2025
d10a156
database list unit tests
lerouxb Oct 20, 2025
2918acc
add unit tests for collections
lerouxb Oct 20, 2025
a80bbc4
Merge branch 'main' into table-not-cards
lerouxb Oct 20, 2025
6c8ecfe
more fixes for virtual scrolling
lerouxb Oct 20, 2025
8f90b67
just pause for now
lerouxb Oct 21, 2025
2879ab5
separate out the screenshots and debugging
lerouxb Oct 21, 2025
d6e76ca
do scroll 'past' the end
lerouxb Oct 21, 2025
8d1127a
don't call them cards
lerouxb Oct 21, 2025
fdc9199
add test for the inferred from privileges tooltip in collections view
lerouxb Oct 21, 2025
00325c3
test the view badge tooltip
lerouxb Oct 21, 2025
1e35fe8
use the virtual table properly..
lerouxb Oct 21, 2025
c57427f
comment
lerouxb Oct 21, 2025
8bf7b35
don't need that key because it is in a fragment
lerouxb Oct 21, 2025
5a0c493
adding data-index ourselves shuts up the unit tests
lerouxb Oct 21, 2025
4e2e041
oof
lerouxb Oct 21, 2025
71a8740
disable virtual scrolling in e2e tests for now
lerouxb Oct 21, 2025
b405ad7
factor out ItemsTable and use the correct hook for virtual vs normal
lerouxb Oct 21, 2025
d730e79
todo ticket
lerouxb Oct 21, 2025
4590dd9
bring back the databases-collections plugin tests
lerouxb Oct 21, 2025
cb1c770
undo depcheck changes
lerouxb Oct 21, 2025
50d4a98
better env var name
lerouxb Oct 21, 2025
e294fc2
remove redundant type constituent comments
lerouxb Oct 21, 2025
ded586b
don't set data-index
lerouxb Oct 21, 2025
074b846
meant to use that as a component
lerouxb Oct 21, 2025
70d9b32
generic
lerouxb Oct 21, 2025
977c598
Merge branch 'main' into table-not-cards
lerouxb Oct 21, 2025
c61ade4
also disable virtual rendering in web tests
lerouxb Oct 21, 2025
a337de6
Update packages/databases-collections-list/src/items-table.tsx
lerouxb Oct 21, 2025
a75e6e9
looser generic types
lerouxb Oct 21, 2025
f002242
don't remove readonly badges
lerouxb Oct 21, 2025
b8f9c33
clicking on a tr is flaky
lerouxb Oct 21, 2025
8ed3962
align the bottom of the element to the bottom of the view so it does …
lerouxb Oct 21, 2025
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
21 changes: 11 additions & 10 deletions packages/compass-assistant/src/@ai-sdk/react/use-chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,21 @@ export type UseChatHelpers<UI_MESSAGE extends UIMessage> = {
| 'clearError'
>;

export type UseChatOptions<UI_MESSAGE extends UIMessage> =
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
({ chat: Chat<UI_MESSAGE> } | ChatInit<UI_MESSAGE>) & {
/**
export type UseChatOptions<UI_MESSAGE extends UIMessage> = (
| { chat: Chat<UI_MESSAGE> }
| ChatInit<UI_MESSAGE>
) & {
/**
Custom throttle wait in ms for the chat messages and data updates.
Default is undefined, which disables throttling.
*/
experimental_throttle?: number;
experimental_throttle?: number;

/**
* Whether to resume an ongoing chat generation stream.
*/
resume?: boolean;
};
/**
* Whether to resume an ongoing chat generation stream.
*/
resume?: boolean;
};

export function useChat<UI_MESSAGE extends UIMessage = UIMessage>({
experimental_throttle: throttleWaitMs,
Expand Down
9 changes: 9 additions & 0 deletions packages/compass-components/src/components/leafygreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,25 @@ import {
TableBody,
flexRender,
useLeafyGreenTable,
useLeafyGreenVirtualTable,
type LeafyGreenVirtualItem,
getExpandedRowModel,
getFilteredRowModel,
type TableProps,
} from '@leafygreen-ui/table';
import type { Row as LgTableRowType } from '@tanstack/table-core'; // TODO(COMPASS-8437): import from LG

export type {
LGColumnDef,
HeaderGroup,
LeafyGreenVirtualTable,
LeafyGreenTable,
LeafyGreenTableCell,
LeafyGreenTableRow,
LGTableDataType,
LGRowData,
SortingState,
CellContext,
} from '@leafygreen-ui/table';
import { Tabs, Tab } from '@leafygreen-ui/tabs';
import TextArea from '@leafygreen-ui/text-area';
Expand Down Expand Up @@ -200,6 +206,9 @@ export {
InfoSprinkle,
flexRender,
useLeafyGreenTable,
useLeafyGreenVirtualTable,
type LeafyGreenVirtualItem,
type TableProps,
getExpandedRowModel,
getFilteredRowModel,
type LgTableRowType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export async function navigateToDatabaseCollectionsTab(
dbName: string
): Promise<void> {
await browser.navigateToConnectionTab(connectionName, 'Databases');
await browser.clickVisible(Selectors.databaseCardClickable(dbName));
await browser.clickVisible(`${Selectors.databaseRow(dbName)} td:first-child`);
await waitUntilActiveDatabaseTab(browser, connectionName, dbName);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,33 @@ export async function scrollToVirtualItem(
browser: CompassBrowser,
containerSelector: string,
targetSelector: string,
role: 'grid' | 'tree'
role: 'grid' | 'tree' | 'table'
): Promise<boolean> {
if (role === 'table') {
// we disable virtual scrolling for tables for now
const expectedRowCount = parseInt(
await browser
.$(`${containerSelector} table`)
.getAttribute('aria-rowcount'),
10
);
const rowCount = await browser.$$('tbody tr').length;

if (rowCount !== expectedRowCount) {
throw new Error(
`${rowCount} rows found, but expected ${expectedRowCount}. Is virtual rendering of the table disabled as expected?`
);
}

const targetElement = browser.$(targetSelector);
await targetElement.waitForExist();
// align the bottom of the element to the bottom of the view so it doesn't
// sit under the sticky header
await targetElement.scrollIntoView(false);
await targetElement.waitForDisplayed();
return true;
}

const config = role === 'tree' ? treeConfig : gridConfig;

let found = false;
Expand Down
4 changes: 4 additions & 0 deletions packages/compass-e2e-tests/helpers/compass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,10 @@ async function startCompassElectron(
// Making sure end-of-life connection modal is not shown, simplify any test connecting to such a server
process.env.COMPASS_DISABLE_END_OF_LIFE_CONNECTION_MODAL = 'true';

// TODO(COMPASS-9977) Turn off virtual scrolling in e2e tests until we can fix
// browser.scrollToVirtualItem() to work with it
process.env.COMPASS_DISABLE_VIRTUAL_TABLE_RENDERING = 'true';

const options = {
automationProtocol: 'webdriver' as const,
capabilities: {
Expand Down
41 changes: 16 additions & 25 deletions packages/compass-e2e-tests/helpers/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -503,56 +503,47 @@ export const ShellInput = '[data-testid="shell-input"]';
export const ShellOutput = '[data-testid="shell-output"]';

// Instance screen
export const DatabasesTable = '[data-testid="database-grid"]';
export const DatabasesTable = '[data-testid="databases-list"]';
export const InstanceCreateDatabaseButton =
'[data-testid="create-controls"] button';
export const InstanceRefreshDatabaseButton =
'[data-testid="refresh-controls"] button';
export const DatabaseCard = '[data-testid="database-grid-item"]';
// assume that there's only one hovered card at a time and that the first and only button is the drop button
export const DatabaseCardDrop =
'[data-testid="database-grid"] [data-testid="namespace-card-actions"] button';
export const ServerStats = '.serverstats';
export const DatabaseStatLoader = `${DatabaseCard} [data-testid="namespace-param-fallback"][data-ready=false]`;
export const DatabaseStatLoader =
'[data-testid="databases-list"] [data-testid="placeholder"]';

export const databaseCard = (dbName: string): string => {
return `${DatabaseCard}[data-id="${dbName}"]`;
export const databaseRow = (dbName: string): string => {
return `[data-testid="databases-list-row-${dbName}"]`;
};

export const databaseCardClickable = (dbName: string): string => {
// webdriver does not like clicking on the card even though the card has the
// click handler, so click on the title
return `${databaseCard(dbName)} [title="${dbName}"]`;
export const databaseRowDrop = (dbName: string): string => {
return `${databaseRow(dbName)} button[data-action="delete"]`;
};

// Performance screen
export const ServerStats = '.serverstats';

// Database screen
export const CollectionsGrid = '[data-testid="collection-grid"]';
export const CollectionsTable = '[data-testid="collections-list"]';
export const DatabaseCreateCollectionButton =
'[data-testid="create-controls"] button';
export const DatabaseRefreshCollectionButton =
'[data-testid="refresh-controls"] button';
export const CollectionCard = '[data-testid="collection-grid-item"]';
// assume that there's only one hovered card at a time and that the first and only button is the drop button
export const CollectionCardDrop =
'[data-testid="collection-grid"] [data-testid="namespace-card-actions"] button';

export const collectionCard = (
export const collectionRow = (
dbName: string,
collectionName: string
): string => {
return `${CollectionCard}[data-id="${dbName}.${collectionName}"]`;
return `[data-testid="collections-list-row-${collectionName}"]`;
};

export const collectionCardClickable = (
export const collectionRowDrop = (
dbName: string,
collectionName: string
): string => {
// webdriver does not like clicking on the card even though the card has the
// click handler, so click on the title
return `${collectionCard(
return `${collectionRow(
dbName,
collectionName
)} [title="${collectionName}"]`;
)} button[data-action="delete"]`;
};

// Collection screen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ export async function mochaGlobalSetup(this: Mocha.Runner) {

if (isTestingWeb(context) && !isTestingAtlasCloudExternal(context)) {
debug('Starting Compass Web server ...');

// TODO(COMPASS-9977) Turn off virtual scrolling in e2e tests until we can fix
// browser.scrollToVirtualItem() to work with it
process.env.COMPASS_DISABLE_VIRTUAL_TABLE_RENDERING = 'true';

if (isTestingAtlasCloudSandbox(context)) {
const compassWeb = await spawnCompassWebSandboxAndSignInToAtlas(
{
Expand Down
11 changes: 10 additions & 1 deletion packages/compass-e2e-tests/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,16 @@ const FIRST_TEST = 'tests/time-to-first-query.test.ts';
async function cleanupOnInterrupt() {
// First trigger an abort on the mocha runner
abortRunner?.();
await runnerPromise;
// Don't wait when bailing because it can take minutes of retries before it
// finally times out, the process exits back to the terminal but some zombie
// child stays around and keeps logging.. We only use bail locally when
// working on tests manually and in that case we probably don't care about the
// cleanup. If you see a test you're working on waiting for something that's
Comment on lines +32 to +33
Copy link
Collaborator

Choose a reason for hiding this comment

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

probably don't care about the cleanup

I actually added this specifically so that mocha gets the best chance of cleaning up via global hooks instead of leaving zombie processes that are hard to find and kill 😆 Don't mind that change, just thought I'd provide the context for why this is waiting here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It seems to have the opposite effect 😆

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmmm, cleans up for me just fine, weird 😕

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To reproduce:

~/mongo/compass/packages/compass-e2e-tests % DEBUG=compass-e2e-tests:scroll-to-virtual-item npm run test -- --disable-start-stop --mocha-bail

Then once the tests start running press ctrl-c. It helps if you have a test that's going to fail by retrying forever and eventually timing out, though.

// never going to happen then you probably want to kill it and get back
// control immediately.
if (!context.mochaBail) {
await runnerPromise;
}
}

function terminateOnTimeout() {
Expand Down
6 changes: 3 additions & 3 deletions packages/compass-e2e-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
"stop-server-2": "mongodb-runner stop --id=e2e-2",
"start-servers": "npm run start-server-1 && npm run start-server-2",
"stop-servers": "npm run stop-server-1 && npm run stop-server-2",
"test-noserver": "env DEBUG=hadron*,mongo*,compass*,xvfb-maybe* npm run test -- --disable-start-stop --bail",
"test-noserver-nocompile": "env DEBUG=hadron*,mongo*,compass*,xvfb-maybe* npm run test -- --no-native-modules --no-compile --disable-start-stop --bail",
"test-noserver": "env DEBUG=hadron*,mongo*,compass*,xvfb-maybe* npm run test -- --disable-start-stop --mocha-bail",
"test-noserver-nocompile": "env DEBUG=hadron*,mongo*,compass*,xvfb-maybe* npm run test -- --no-native-modules --no-compile --disable-start-stop --mocha-bail",
"test-web": "env DEBUG=hadron*,mongo*,compass*,xvfb-maybe* npm run test web",
"test-web-noserver": "env DEBUG=hadron*,mongo*,compass*,xvfb-maybe* npm run test web -- --disable-start-stop --bail",
"test-web-noserver": "env DEBUG=hadron*,mongo*,compass*,xvfb-maybe* npm run test web -- --disable-start-stop --mocha-bail",
"coverage-merge": "nyc merge .log/coverage .nyc_output/coverage.json",
"coverage-report": "npm run coverage-merge && nyc report"
},
Expand Down
71 changes: 35 additions & 36 deletions packages/compass-e2e-tests/tests/database-collections-tab.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,23 @@ async function waitForCollectionAndBadge(
collectionName: string,
badgeSelector: string
) {
const cardSelector = Selectors.collectionCard(dbName, collectionName);
const rowSelector = Selectors.collectionRow(dbName, collectionName);
await browser.scrollToVirtualItem(
Selectors.CollectionsGrid,
cardSelector,
'grid'
Selectors.CollectionsTable,
rowSelector,
'table'
);

// Hit refresh because depending on timing the card might appear without the
// Hit refresh because depending on timing the row might appear without the
// badge at first. Especially in Firefox for whatever reason.
await browser.clickVisible(Selectors.DatabaseRefreshCollectionButton);

await browser.scrollToVirtualItem(
Selectors.CollectionsGrid,
cardSelector,
'grid'
Selectors.CollectionsTable,
rowSelector,
'table'
);
await browser.$(cardSelector).$(badgeSelector).waitForDisplayed();
await browser.$(rowSelector).$(badgeSelector).waitForDisplayed();
}

describe('Database collections tab', function () {
Expand Down Expand Up @@ -71,7 +71,7 @@ describe('Database collections tab', function () {
});

it('contains a list of collections', async function () {
const collectionsGrid = browser.$(Selectors.CollectionsGrid);
const collectionsGrid = browser.$(Selectors.CollectionsTable);
await collectionsGrid.waitForDisplayed();

for (const collectionName of [
Expand All @@ -80,29 +80,28 @@ describe('Database collections tab', function () {
'json-file',
'numbers',
]) {
const collectionSelector = Selectors.collectionCard(
const collectionSelector = Selectors.collectionRow(
'test',
collectionName
);
const found = await browser.scrollToVirtualItem(
Selectors.CollectionsGrid,
Selectors.CollectionsTable,
collectionSelector,
'grid'
'table'
);
expect(found, collectionSelector).to.be.true;
}
});

it('links collection cards to the collection documents tab', async function () {
it('links collection rows to the collection documents tab', async function () {
await browser.scrollToVirtualItem(
Selectors.CollectionsGrid,
Selectors.collectionCard('test', 'json-array'),
'grid'
Selectors.CollectionsTable,
Selectors.collectionRow('test', 'json-array'),
'table'
);

await browser.clickVisible(
Selectors.collectionCardClickable('test', 'json-array'),
{ scroll: true }
`${Selectors.collectionRow('test', 'json-array')} td:first-child`
);

// lands on the collection screen with all its tabs
Expand Down Expand Up @@ -137,22 +136,20 @@ describe('Database collections tab', function () {
'test'
);

const selector = Selectors.collectionCard('test', collectionName);
const selector = Selectors.collectionRow('test', collectionName);
await browser.scrollToVirtualItem(
Selectors.CollectionsGrid,
Selectors.CollectionsTable,
selector,
'grid'
'table'
);

const collectionCard = browser.$(selector);
await collectionCard.waitForDisplayed();

await collectionCard.scrollIntoView(false);
const collectionRow = browser.$(selector);
await collectionRow.waitForDisplayed();

await browser.waitUntil(async () => {
// open the drop collection modal from the collection card
await browser.hover(`${selector} [title="${collectionName}"]`);
const el = browser.$(Selectors.CollectionCardDrop);
// open the drop collection modal from the collection row
await browser.hover(`${selector}`);
const el = browser.$(Selectors.collectionRowDrop('test', collectionName));
if (await el.isDisplayed()) {
return true;
}
Expand All @@ -162,12 +159,14 @@ describe('Database collections tab', function () {
return false;
});

await browser.clickVisible(Selectors.CollectionCardDrop);
await browser.clickVisible(
Selectors.collectionRowDrop('test', collectionName)
);

await browser.dropNamespace(collectionName);

// wait for it to be gone
await collectionCard.waitForExist({ reverse: true });
await collectionRow.waitForExist({ reverse: true });

// the app should still be on the database Collections tab because there are
// other collections in this database
Expand Down Expand Up @@ -345,13 +344,13 @@ describe('Database collections tab', function () {
);
await browser.clickVisible(Selectors.DatabaseRefreshCollectionButton);

const collSelector = Selectors.collectionCard(db, coll);
const collSelector = Selectors.collectionRow(db, coll);
await browser.scrollToVirtualItem(
Selectors.CollectionsGrid,
Selectors.CollectionsTable,
collSelector,
'grid'
'table'
);
const coll2Card = browser.$(collSelector);
await coll2Card.waitForDisplayed();
const coll2Row = browser.$(collSelector);
await coll2Row.waitForDisplayed();
});
});
Loading
Loading