Skip to content

Commit

Permalink
chore(web): adjust url-builder and add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
gribnoysup committed Sep 2, 2024
1 parent dd7190e commit 86c98fa
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 26 deletions.
2 changes: 2 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,10 @@ function Tab({
return (
<Tooltip
enabled={!!tooltip}
// To make sure that tooltips are always on the bottom of the tab in
// compass-web and are not hidden by the mms top navigation bar
align="bottom"
justify="start"
trigger={
<div
ref={setNodeRef}
Expand Down
1 change: 1 addition & 0 deletions packages/compass-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
"mongodb": "^6.8.0",
"mongodb-connection-string-url": "^3.0.1",
"mongodb-data-service": "^22.23.1",
"mongodb-ns": "^2.4.2",
"nyc": "^15.1.0",
"os-browserify": "^0.3.0",
"path-browserify": "^1.0.1",
Expand Down
97 changes: 97 additions & 0 deletions packages/compass-web/src/url-builder.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { expect } from 'chai';
import {
getRouteFromWorkspaceTab,
getWorkspaceTabFromRoute,
} from './url-builder';

describe('url builder helpers', function () {
describe('getRouteFromWorkspaceTab', function () {
const specs = [
['Welcome', '/', null],
['Databases', '/Cluster0', null],
['Collections', '/Cluster0/%23db', { namespace: '#db' }],
['Collection', '/Cluster0/%23db/coll', { namespace: '#db.coll' }],
[
'Collection',
'/Cluster0/%23db/coll/find',
{ namespace: '#db.coll', initialSubtab: 'Documents' },
],
[
'Collection',
'/Cluster0/%23db/coll/aggregation',
{ namespace: '#db.coll', initialSubtab: 'Aggregations' },
],
[
'Collection',
'/Cluster0/%23db/coll/schema',
{ namespace: '#db.coll', initialSubtab: 'Schema' },
],
[
'Collection',
'/Cluster0/%23db/coll/indexes',
{ namespace: '#db.coll', initialSubtab: 'Indexes' },
],
[
'Collection',
'/Cluster0/%23db/coll/validation',
{ namespace: '#db.coll', initialSubtab: 'Validation' },
],
['Collection', '/Cluster0/%23db/coll/foobar', { namespace: '#db.coll' }],
] as const;

for (const [type, route, extraParams] of specs) {
it(`should return ${type} workspace when initial route is ${route}`, function () {
expect(getWorkspaceTabFromRoute(route)).to.deep.eq({
type,
...(type !== 'Welcome' && { connectionId: 'Cluster0' }),
...extraParams,
});
});
}
});

describe('getRouteFromWorkspaceTab', function () {
const specs = [
['/', { type: 'Welcome' }],
['/Cluster0', { type: 'Databases' }],
['/Cluster0/db', { type: 'Collections', namespace: 'db' }],
['/Cluster0/db/%23coll', { type: 'Collection', namespace: 'db.#coll' }],
[
'/Cluster0/db/%23coll/find',
{ type: 'Collection', namespace: 'db.#coll', subTab: 'Documents' },
],
[
'/Cluster0/db/%23coll/aggregation',
{ type: 'Collection', namespace: 'db.#coll', subTab: 'Aggregations' },
],
[
'/Cluster0/db/%23coll/schema',
{ type: 'Collection', namespace: 'db.#coll', subTab: 'Schema' },
],
[
'/Cluster0/db/%23coll/indexes',
{ type: 'Collection', namespace: 'db.#coll', subTab: 'Indexes' },
],
[
'/Cluster0/db/%23coll/validation',
{ type: 'Collection', namespace: 'db.#coll', subTab: 'Validation' },
],
[
'/Cluster0/db/%23coll',
{ type: 'Collection', namespace: 'db.#coll', subTab: 'FooBar' },
],
] as const;

for (const [route, workspace] of specs) {
it(`should return ${route} route when workspace is ${workspace.type}`, function () {
expect(
getRouteFromWorkspaceTab(
workspace.type === 'Welcome'
? workspace
: ({ ...workspace, connectionId: 'Cluster0' } as any)
)
).to.eq(route);
});
}
});
});
81 changes: 55 additions & 26 deletions packages/compass-web/src/url-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,67 @@ import type {
OpenWorkspaceOptions,
WorkspaceTab,
} from '@mongodb-js/compass-workspaces';
import toNS from 'mongodb-ns';

function getCollectionSubTabFromRoute(subTab?: string): CollectionSubtab {
switch (subTab?.toLowerCase() ?? '') {
/**
* This is specifically mapping from existing data explorer route params to
* compass types, hence some routes not exactly matching the tab names
*/
function getCollectionSubTabFromRoute(
routeSubTab: string | undefined
): CollectionSubtab | undefined {
switch (routeSubTab) {
case 'find':
return 'Documents';
case 'aggregation':
return 'Aggregations';
case 'schema':
return 'Schema';
case 'indexes':
return 'Indexes';
case 'aggregations':
return 'Aggregations';
case 'validation':
return 'Validation';
default:
return 'Documents';
return undefined;
}
}

function getRouteFromCollectionSubTab(subTab: CollectionSubtab): string {
switch (subTab) {
case 'Documents':
return 'find';
case 'Aggregations':
return 'aggregation';
case 'Schema':
return 'schema';
case 'Indexes':
return 'indexes';
case 'Validation':
return 'validation';
default:
return '';
}
}

export function getWorkspaceTabFromRoute(
route: string
): OpenWorkspaceOptions | null {
const [, connectionId, tab, namespace = '', subTab] =
const [, connectionId, db, coll, subTab] =
decodeURIComponent(route).split('/');

if (namespace) {
if (tab === 'collection') {
return {
type: 'Collection',
connectionId,
namespace,
initialSubtab: getCollectionSubTabFromRoute(subTab),
};
}
if (tab === 'collections') {
return { type: 'Collections', connectionId, namespace };
}
if (connectionId && db && coll) {
const maybeSubTab = getCollectionSubTabFromRoute(subTab);
return {
type: 'Collection',
connectionId,
namespace: `${db}.${coll}`,
...(maybeSubTab && { initialSubtab: maybeSubTab }),
};
}
if (connectionId && (tab === 'databases' || !tab)) {
if (connectionId && db) {
return { type: 'Collections', connectionId, namespace: db };
}
if (connectionId) {
return { type: 'Databases', connectionId };
}
return { type: 'Welcome' };
Expand All @@ -51,6 +76,7 @@ function buildAbsoluteURL(...parts: string[]) {
.map((part) => {
return encodeURIComponent(part);
})
.filter(Boolean)
.join('/')
);
}
Expand All @@ -59,19 +85,22 @@ export function getRouteFromWorkspaceTab(tab: WorkspaceTab | null) {
let route: string;
switch (tab?.type) {
case 'Databases':
route = buildAbsoluteURL(tab.connectionId, 'databases');
route = buildAbsoluteURL(tab.connectionId);
break;
case 'Collections':
route = buildAbsoluteURL(tab.connectionId, 'collections', tab.namespace);
case 'Collections': {
route = buildAbsoluteURL(tab.connectionId, tab.namespace);
break;
case 'Collection':
}
case 'Collection': {
const { database, collection } = toNS(tab.namespace);
route = buildAbsoluteURL(
tab.connectionId,
'collection',
tab.namespace,
tab.subTab.toLowerCase()
database,
collection,
getRouteFromCollectionSubTab(tab.subTab)
);
break;
}
default:
route = '/';
}
Expand Down

0 comments on commit 86c98fa

Please sign in to comment.