Skip to content

feat: update atlas cluster states COMPASS-8228 #6884

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
May 6, 2025
Prev Previous commit
Next Next commit
refactor
  • Loading branch information
syn-zhu committed May 1, 2025
commit 2860e70bbed9fe96db6aca0ce3a3797ba79f60fe
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useCallback, useMemo } from 'react';
import AutoSizer from 'react-virtualized-auto-sizer';
import { clusterIsConnectable, getVirtualTreeItems } from './tree-data';
import { getConnectionId, getVirtualTreeItems } from './tree-data';
import { ROW_HEIGHT } from './constants';
import type { Actions } from './constants';
import { VirtualTree } from './virtual-list/virtual-list';
Expand All @@ -18,10 +18,10 @@ import {
spacing,
useId,
} from '@mongodb-js/compass-components';
import { useConnectableRef } from '@mongodb-js/compass-connections/provider';
import type { WorkspaceTab } from '@mongodb-js/compass-workspaces';
import { usePreference } from 'compass-preferences-model/provider';
import type { NavigationItemActions } from './item-actions';
import { useConnectionsListRef } from '@mongodb-js/compass-connections/provider';
import {
collectionItemActions,
connectedConnectionItemActions,
Expand Down Expand Up @@ -58,7 +58,7 @@ const ConnectionsNavigationTree: React.FunctionComponent<
);

const id = useId();
const { getConnectionById } = useConnectionsListRef();
const { getConnectable } = useConnectableRef();

const treeData = useMemo(() => {
return getVirtualTreeItems({
Expand All @@ -71,11 +71,8 @@ const ConnectionsNavigationTree: React.FunctionComponent<

const onDefaultAction: OnDefaultAction<SidebarActionableItem> = useCallback(
(item, evt) => {
const isConnectableCluster = clusterIsConnectable(
item,
getConnectionById
);
if (!isConnectableCluster) {
const connectionId = getConnectionId(item);
if (!getConnectable(connectionId)) {
return;
}

Expand All @@ -93,7 +90,7 @@ const ConnectionsNavigationTree: React.FunctionComponent<
}
}
},
[onItemAction, getConnectionById]
[onItemAction, getConnectable]
);

const activeItemId = useMemo(() => {
Expand Down Expand Up @@ -154,11 +151,8 @@ const ConnectionsNavigationTree: React.FunctionComponent<

const getItemActionsAndConfig = useCallback(
(item: SidebarTreeItem) => {
const isConnectableCluster = clusterIsConnectable(
item,
getConnectionById
);
if (!isConnectableCluster) {
const connectionId = getConnectionId(item);
if (!getConnectable(connectionId)) {
return {
actions: [],
};
Expand Down Expand Up @@ -214,7 +208,7 @@ const ConnectionsNavigationTree: React.FunctionComponent<
[
isRenameCollectionEnabled,
getCollapseAfterForConnectedItem,
getConnectionById,
getConnectable,
]
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import {
DefaultColorCode,
} from '@mongodb-js/connection-form';
import { palette, useDarkMode } from '@mongodb-js/compass-components';
import { clusterIsConnectable, type SidebarTreeItem } from './tree-data';
import { useConnectionsListRef } from '@mongodb-js/compass-connections/provider';
import { getConnectionId, type SidebarTreeItem } from './tree-data';
import { useConnectable } from '@mongodb-js/compass-connections/provider';

type AcceptedStyles = {
'--item-bg-color'?: string;
Expand All @@ -30,8 +30,9 @@ export default function StyledNavigationItem({
() => (isDarkMode ? palette.gray.light1 : palette.gray.dark1),
[isDarkMode]
);
const { getConnectionById } = useConnectionsListRef();
const isConnectableCluster = clusterIsConnectable(item, getConnectionById);

const connectionId = getConnectionId(item);
const isConnectable = useConnectable(connectionId);

const style: React.CSSProperties & AcceptedStyles = useMemo(() => {
const style: AcceptedStyles = {};
Expand All @@ -47,22 +48,18 @@ export default function StyledNavigationItem({
style['--item-bg-color-active'] = connectionColorToHexActive(colorCode);
}

if (
isDisconnectedConnection ||
isNonExistentNamespace ||
!isConnectableCluster
) {
if (isDisconnectedConnection || isNonExistentNamespace || !isConnectable) {
style['--item-color'] = inactiveColor;
}

// We always show these as inactive
if (isNonExistentNamespace || !isConnectableCluster) {
if (isNonExistentNamespace || !isConnectable) {
style['--item-color-active'] = inactiveColor;
}
return style;
}, [
inactiveColor,
isConnectableCluster,
isConnectable,
item,
colorCode,
connectionColorToHex,
Expand Down
22 changes: 7 additions & 15 deletions packages/compass-connections-navigation/src/tree-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,22 +124,14 @@ export type SidebarActionableItem =

export type SidebarTreeItem = PlaceholderTreeItem | SidebarActionableItem;

export function clusterIsConnectable(
item: SidebarTreeItem,
getConnectionById: any
): boolean {
if (item.type === 'connection') {
const clusterState = item.connectionInfo.atlasMetadata?.clusterState;
return !['DELETING', 'DELETED', 'CREATING', 'PAUSED'].includes(
clusterState
);
} else if (item.type === 'database' || item.type === 'collection') {
const connection = getConnectionById(item.connectionId);
return !['DELETING', 'DELETED', 'CREATING', 'PAUSED'].includes(
connection.info.atlasMetadata?.clusterState
);
export function getConnectionId(item: SidebarTreeItem): string {
if (item.type === 'placeholder') {
return '';
} else if (item.type === 'connection') {
return item.connectionInfo.id;
} else {
return item.connectionId;
}
return true;
}

const notConnectedConnectionToItems = ({
Expand Down
34 changes: 34 additions & 0 deletions packages/compass-connections/src/hooks/use-connectable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useSelector, useStore } from '../stores/store-context';
import { useRef, useState } from 'react';
import { connectable } from '../utils/connection-supports';

export function useConnectable(connectionId: string): boolean {
return useSelector((state) => {
const connection = state.connections.byId[connectionId];

if (!connection) {
return false;
}

return connectable(connection.info);
});
}

export function useConnectableRef(): {
getConnectable(this: void, connectionId: string): boolean;
} {
const storeRef = useRef(useStore());
const [ref] = useState(() => {
Copy link
Member

Choose a reason for hiding this comment

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

Would this be a cleaner way to write this?

  const store = useStore();
  const getConnectable = useCallback((connectionId: string) => {
    // ...
  }, [store]);

Fine as is too I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, would that have the same outcome?

return {
getConnectable(connectionId: string) {
const conn = storeRef.current.getState().connections.byId[connectionId];
if (!conn) {
return false;
}

return connectable(conn.info);
},
};
});
return ref;
}
2 changes: 1 addition & 1 deletion packages/compass-connections/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
ConnectionActionsProvider,
} from './stores/store-context';
export type { ConnectionFeature } from './utils/connection-supports';
export { connectionSupports } from './utils/connection-supports';
export { connectionSupports, connectable } from './utils/connection-supports';

const ConnectionsComponent: React.FunctionComponent<{
/**
Expand Down
2 changes: 2 additions & 0 deletions packages/compass-connections/src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ export type { ConnectionsService } from './stores/store-context';

export { useConnectionSupports } from './hooks/use-connection-supports';

export { useConnectable, useConnectableRef } from './hooks/use-connectable';

const ConnectionStatus = {
/**
* @deprecated use a string literal directly
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import EventEmitter from 'events';
import { showNonGenuineMongoDBWarningModal as _showNonGenuineMongoDBWarningModal } from '../components/non-genuine-connection-modal';
import ConnectionString from 'mongodb-connection-string-url';
import type { ExtraConnectionData as ExtraConnectionDataForTelemetry } from '@mongodb-js/compass-telemetry';
import { connectable } from '../utils/connection-supports';

export type ConnectionsEventMap = {
connected: (
Expand Down Expand Up @@ -563,6 +564,7 @@ function mergeConnections(
}
}

// If an Atlas connection was removed, it means that the cluster was deleted
for (const connectionId of removedConnectionIds) {
const removedConnection = newConnectionsById[connectionId];
if (removedConnection.info.atlasMetadata) {
Expand Down Expand Up @@ -1511,13 +1513,7 @@ const connectWithOptions = (
return;
}

const atlasClusterState = connectionInfo.atlasMetadata?.clusterState;
if (
atlasClusterState === 'DELETED' ||
atlasClusterState === 'DELETING' ||
atlasClusterState === 'CREATING' ||
atlasClusterState === 'PAUSED'
) {
if (!connectable(connectionInfo)) {
return;
}

Expand Down
13 changes: 13 additions & 0 deletions packages/compass-connections/src/utils/connection-supports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ function supportsRollingIndexCreation(connectionInfo: ConnectionInfo) {
return atlasMetadata.supports.rollingIndexes;
}

export function connectable(connectionInfo: ConnectionInfo) {
const atlasClusterState = connectionInfo.atlasMetadata?.clusterState;
if (
atlasClusterState === 'DELETED' ||
atlasClusterState === 'DELETING' ||
atlasClusterState === 'CREATING' ||
atlasClusterState === 'PAUSED'
) {
return false;
}
return true;
}

function supportsGlobalWrites(connectionInfo: ConnectionInfo) {
const atlasMetadata = connectionInfo.atlasMetadata;

Expand Down
Loading