Skip to content

Commit

Permalink
fix(compass-connections, sidebar): move all connection related logic …
Browse files Browse the repository at this point in the history
…and state to compass-connections COMPASS-8067 (#6059)

* fix(compass-connections, sidebar): move all connection related logic and state to compass-connections

* fix(connections): add missing dependency

* chore(connections): fix active connections count

* chore(sidebar): fix test failures

* chore(connections): more tests

* fix(connections): adjust regex to handle multi digit numbers and to not grab number from the middle of the string; reduce algo complexity by doing just one pass over array

* fix(connections): fix electron tests

* chore(connections): add more tests

* chore(connections): different fix for a test

* chore(connections): fix typos

* fix(connections): correctly use existing connection info for single connection mode after connection
  • Loading branch information
gribnoysup authored Jul 29, 2024
1 parent 886646e commit d5fe7d7
Show file tree
Hide file tree
Showing 32 changed files with 1,618 additions and 1,755 deletions.
6 changes: 4 additions & 2 deletions package-lock.json

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

3 changes: 2 additions & 1 deletion packages/compass-connections/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@
"dependencies": {
"@mongodb-js/compass-components": "^1.28.1",
"@mongodb-js/compass-logging": "^1.4.2",
"@mongodb-js/compass-telemetry": "^1.1.2",
"@mongodb-js/compass-maybe-protect-connection-string": "^0.23.1",
"@mongodb-js/compass-telemetry": "^1.1.2",
"@mongodb-js/compass-utils": "^0.6.7",
"@mongodb-js/connection-form": "^1.35.0",
"@mongodb-js/connection-info": "^0.5.2",
"@mongodb-js/connection-storage": "^0.16.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import React, { useCallback } from 'react';
import { css, Link, spacing, useToast } from '@mongodb-js/compass-components';
import type { ConnectionInfo } from '@mongodb-js/connection-info';
import { getConnectionTitle } from '@mongodb-js/connection-info';
import { usePreference } from 'compass-preferences-model/provider';
import ConnectionString from 'mongodb-connection-string-url';
import { isCancelError } from '@mongodb-js/compass-utils';

export function isOIDCAuth(connectionString: string): boolean {
const authMechanismString = (
new ConnectionString(connectionString).searchParams.get('authMechanism') ||
''
).toUpperCase();

return authMechanismString === 'MONGODB-OIDC';
}

export function getConnectionErrorMessage(err?: any) {
return isCancelError(err) ? null : err?.message ?? null;
}

export function getConnectingStatusText(connectionInfo: ConnectionInfo) {
const connectionTitle = getConnectionTitle(connectionInfo);
const isOIDC = isOIDCAuth(connectionInfo.connectionOptions.connectionString);
return {
title: `Connecting to ${connectionTitle}`,
description: isOIDC ? 'Go to the browser to complete authentication' : '',
};
}

type ConnectionErrorToastBodyProps = {
info?: ConnectionInfo | null;
onReview: () => void;
};

const connectionErrorToastBodyStyles = css({
display: 'flex',
alignItems: 'start',
gap: spacing[2],
});

const connectionErrorToastActionMessageStyles = css({
marginTop: spacing[1],
flexGrow: 0,
});

function ConnectionErrorToastBody({
info,
onReview,
}: ConnectionErrorToastBodyProps): React.ReactElement {
return (
<span className={connectionErrorToastBodyStyles}>
<span data-testid="connection-error-text">
There was a problem connecting{' '}
{info ? `to ${getConnectionTitle(info)}` : ''}
</span>
{info && (
<Link
className={connectionErrorToastActionMessageStyles}
hideExternalIcon={true}
onClick={onReview}
data-testid="connection-error-review"
>
REVIEW
</Link>
)}
</span>
);
}

const noop = () => undefined;

export function useConnectionStatusToasts() {
const enableNewMultipleConnectionSystem = usePreference(
'enableNewMultipleConnectionSystem'
);
const { openToast, closeToast } = useToast('connection-status');

const openConnectionStartedToast = useCallback(
(connectionInfo: ConnectionInfo, onCancelClick: () => void) => {
const { title, description } = getConnectingStatusText(connectionInfo);
openToast(connectionInfo.id, {
title,
description,
dismissible: true,
variant: 'progress',
actionElement: (
<Link
hideExternalIcon={true}
onClick={() => {
closeToast(connectionInfo.id);
onCancelClick();
}}
>
CANCEL
</Link>
),
});
},
[closeToast, openToast]
);

const openConnectionSucceededToast = useCallback(
(connectionInfo: ConnectionInfo) => {
openToast(connectionInfo.id, {
title: `Connected to ${getConnectionTitle(connectionInfo)}`,
variant: 'success',
timeout: 3_000,
});
},
[openToast]
);

const openConnectionFailedToast = useCallback(
(
// Connection info might be missing if we failed connecting before we
// could even resolve connection info. Currently the only case where this
// can happen is autoconnect flow
connectionInfo: ConnectionInfo | null | undefined,
error: Error,
onReviewClick: () => void
) => {
const failedToastId = connectionInfo?.id ?? 'failed';

openToast(failedToastId, {
title: error.message,
description: (
<ConnectionErrorToastBody
info={connectionInfo}
onReview={() => {
closeToast(failedToastId);
onReviewClick();
}}
/>
),
variant: 'warning',
});
},
[closeToast, openToast]
);

const openMaximumConnectionsReachedToast = useCallback(
(maxConcurrentConnections: number) => {
const message = `Only ${maxConcurrentConnections} connection${
maxConcurrentConnections > 1 ? 's' : ''
} can be connected to at the same time. First disconnect from another connection.`;

openToast('max-connections-reached', {
title: 'Maximum concurrent connections limit reached',
description: message,
variant: 'warning',
timeout: 5_000,
});
},
[openToast]
);

return enableNewMultipleConnectionSystem
? {
openConnectionStartedToast,
openConnectionSucceededToast,
openConnectionFailedToast,
openMaximumConnectionsReachedToast,
closeConnectionStatusToast: closeToast,
}
: {
openConnectionStartedToast: noop,
openConnectionSucceededToast: noop,
openConnectionFailedToast: noop,
openMaximumConnectionsReachedToast: noop,
closeConnectionStatusToast: noop,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
import { ConnectionsManager, ConnectionsManagerProvider } from '../provider';
import type { DataService } from 'mongodb-data-service';
import { createNoopLogger } from '@mongodb-js/compass-logging/provider';
import { ConnectionsProvider } from './connections-provider';

function getConnectionsManager(mockTestConnectFn?: typeof connect) {
const { log } = createNoopLogger();
Expand Down Expand Up @@ -75,7 +76,9 @@ describe('Connections Component', function () {
<PreferencesProvider value={preferences}>
<ConnectionStorageProvider value={mockStorage}>
<ConnectionsManagerProvider value={getConnectionsManager()}>
<Connections appRegistry={{} as any} />
<ConnectionsProvider>
<Connections appRegistry={{} as any} />
</ConnectionsProvider>
</ConnectionsManagerProvider>
</ConnectionStorageProvider>
</PreferencesProvider>
Expand Down
Loading

0 comments on commit d5fe7d7

Please sign in to comment.