Skip to content

Commit f89e838

Browse files
committed
Add enableConnectInNewWindow preference controlling connect button
1 parent 0e1af64 commit f89e838

File tree

5 files changed

+151
-96
lines changed

5 files changed

+151
-96
lines changed

packages/compass-components/src/components/actions/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export type ItemComponentProps<Action extends string> = Omit<
2727
iconClassName?: string;
2828
iconStyle?: React.CSSProperties;
2929
'data-testid'?: string;
30-
onClick(evt: React.MouseEvent<unknown>): void;
30+
onClick: (evt: React.MouseEvent<HTMLElement>) => void;
3131
setHidable?(hidable: boolean): void;
3232
};
3333

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import React, { useState, useEffect } from 'react';
2+
import {
3+
css,
4+
Icon,
5+
MenuItem,
6+
SplitButton,
7+
type GlyphName,
8+
type ItemComponentProps,
9+
type PolymorphicProps,
10+
type MenuItemProps,
11+
} from '@mongodb-js/compass-components';
12+
import type { Actions } from './constants';
13+
14+
const menuItemStyles = css({
15+
minWidth: 'max-content',
16+
});
17+
18+
type ConnectMenuItemProps = {
19+
action: Actions;
20+
glyph: GlyphName;
21+
} & PolymorphicProps<'button', Omit<MenuItemProps, 'glyph'>>;
22+
23+
function ConnectMenuItem({ action, glyph, ...rest }: ConnectMenuItemProps) {
24+
return (
25+
<MenuItem
26+
data-action={action}
27+
className={menuItemStyles}
28+
glyph={<Icon glyph={glyph} />}
29+
{...rest}
30+
/>
31+
);
32+
}
33+
34+
// Hack to make SplitButton consider this as a MenuItem
35+
ConnectMenuItem.displayName = 'MenuItem';
36+
37+
export function ConnectButtonWithMenu({
38+
setHidable,
39+
action,
40+
tooltip,
41+
label,
42+
iconSize,
43+
iconStyle,
44+
isDisabled,
45+
onClick,
46+
className,
47+
'data-testid': testId,
48+
}: ItemComponentProps<Actions>) {
49+
const [isOpen, setOpen] = useState(false);
50+
51+
// Opening the menu should keep it visible
52+
useEffect(() => {
53+
if (setHidable) {
54+
setHidable(!isOpen);
55+
}
56+
}, [setHidable, isOpen]);
57+
58+
return (
59+
<SplitButton
60+
key={action}
61+
title={!tooltip ? label : undefined}
62+
label={label}
63+
size={iconSize}
64+
data-action={action}
65+
data-testid={testId}
66+
onClick={onClick}
67+
className={className}
68+
style={iconStyle}
69+
disabled={isDisabled}
70+
renderDarkMenu={false}
71+
darkMode={false}
72+
open={isOpen}
73+
setOpen={setOpen}
74+
triggerAriaLabel="see more connection options"
75+
menuItems={[
76+
<ConnectMenuItem
77+
key="connection-connect"
78+
action="connection-connect"
79+
glyph="Connect"
80+
onClick={onClick}
81+
>
82+
Connect Here
83+
</ConnectMenuItem>,
84+
<ConnectMenuItem
85+
key="connection-connect-in-new-window"
86+
action="connection-connect-in-new-window"
87+
glyph="OpenNewTab"
88+
onClick={onClick}
89+
>
90+
Connect in a New Window
91+
</ConnectMenuItem>,
92+
]}
93+
>
94+
{label}
95+
</SplitButton>
96+
);
97+
}
Lines changed: 37 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,42 @@
1-
import React, { useState, useEffect } from 'react';
1+
import React from 'react';
22
import {
3-
css,
4-
Icon,
5-
MenuItem,
6-
SplitButton,
7-
type GlyphName,
3+
Button,
84
type ItemComponentProps,
9-
type PolymorphicProps,
10-
type MenuItemProps,
115
} from '@mongodb-js/compass-components';
126
import type { Actions } from './constants';
13-
14-
const menuItemStyles = css({
15-
minWidth: 'max-content',
16-
});
17-
18-
type ConnectMenuItemProps = {
19-
action: Actions;
20-
glyph: GlyphName;
21-
} & PolymorphicProps<'button', Omit<MenuItemProps, 'glyph'>>;
22-
23-
function ConnectMenuItem({ action, glyph, ...rest }: ConnectMenuItemProps) {
24-
return (
25-
<MenuItem
26-
data-action={action}
27-
className={menuItemStyles}
28-
glyph={<Icon glyph={glyph} />}
29-
{...rest}
30-
/>
31-
);
32-
}
33-
34-
// Hack to make SplitButton consider this as a MenuItem
35-
ConnectMenuItem.displayName = 'MenuItem';
36-
37-
type ConnectButtonProps = ItemComponentProps<Actions>;
38-
39-
export function ConnectButton({
40-
setHidable,
41-
action,
42-
tooltip,
43-
label,
44-
iconSize,
45-
iconStyle,
46-
isDisabled,
47-
onClick,
48-
className,
49-
'data-testid': testId,
50-
}: ConnectButtonProps) {
51-
const [isOpen, setOpen] = useState(false);
52-
53-
// Opening the menu should keep it visible
54-
useEffect(() => {
55-
if (setHidable) {
56-
setHidable(!isOpen);
57-
}
58-
}, [setHidable, isOpen]);
59-
60-
return (
61-
<SplitButton
62-
key={action}
63-
title={!tooltip ? label : undefined}
64-
label={label}
65-
size={iconSize}
66-
data-action={action}
67-
data-testid={testId}
68-
onClick={onClick}
69-
className={className}
70-
style={iconStyle}
71-
disabled={isDisabled}
72-
renderDarkMenu={false}
73-
darkMode={false}
74-
open={isOpen}
75-
setOpen={setOpen}
76-
triggerAriaLabel="see more connection options"
77-
menuItems={[
78-
<ConnectMenuItem
79-
key="connection-connect"
80-
action="connection-connect"
81-
glyph="Connect"
82-
onClick={onClick}
83-
>
84-
Connect Here
85-
</ConnectMenuItem>,
86-
<ConnectMenuItem
87-
key="connection-connect-in-new-window"
88-
action="connection-connect-in-new-window"
89-
glyph="OpenNewTab"
90-
onClick={onClick}
91-
>
92-
Connect in a New Window
93-
</ConnectMenuItem>,
94-
]}
95-
>
96-
{label}
97-
</SplitButton>
98-
);
7+
import { usePreference } from 'compass-preferences-model/provider';
8+
import { ConnectButtonWithMenu } from './connect-button-with-menu';
9+
10+
export function ConnectButton(props: ItemComponentProps<Actions>) {
11+
const connectInNewWindowEnabled = usePreference('enableConnectInNewWindow');
12+
if (connectInNewWindowEnabled) {
13+
return <ConnectButtonWithMenu {...props} />;
14+
} else {
15+
const {
16+
action,
17+
tooltip,
18+
label,
19+
iconSize,
20+
iconStyle,
21+
isDisabled,
22+
onClick,
23+
className,
24+
'data-testid': testId,
25+
} = props;
26+
return (
27+
<Button
28+
key={action}
29+
title={!tooltip ? label : undefined}
30+
size={iconSize}
31+
data-action={action}
32+
data-testid={testId}
33+
onClick={onClick}
34+
className={className}
35+
style={iconStyle}
36+
disabled={isDisabled}
37+
>
38+
{label}
39+
</Button>
40+
);
41+
}
9942
}

packages/compass-preferences-model/src/preferences-schema.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,10 @@ export type UserConfigurablePreferences = PermanentFeatureFlags &
8484
proxy: string;
8585
};
8686

87+
/**
88+
* Internally used preferences that are not configurable
89+
*/
8790
export type InternalUserPreferences = {
88-
// These are internally used preferences that are not configurable
8991
// by users.
9092
showedNetworkOptIn: boolean; // Has the settings dialog been shown before.
9193
id: string;
@@ -98,6 +100,7 @@ export type InternalUserPreferences = {
98100
telemetryAnonymousId?: string;
99101
telemetryAtlasUserId?: string;
100102
userCreatedAt: number;
103+
enableConnectInNewWindow: boolean;
101104
};
102105

103106
// UserPreferences contains all preferences stored to disk.
@@ -404,6 +407,17 @@ export const storedUserPreferencesProps: Required<{
404407
validator: z.number().default(Date.now()),
405408
type: 'number',
406409
},
410+
/**
411+
* Enables a dropdown in the connections sidebar to connect in a new window.
412+
*/
413+
enableConnectInNewWindow: {
414+
ui: false,
415+
cli: false,
416+
global: false,
417+
description: null,
418+
validator: z.boolean().default(true),
419+
type: 'boolean',
420+
},
407421
/**
408422
* Enable/disable the AI services. This is currently set
409423
* in the atlas-service initialization where we make a request to the

packages/compass-web/src/preferences.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export function useCompassWebPreferences(
5656
enableCreatingNewConnections: false,
5757
enableGlobalWrites: false,
5858
optInDataExplorerGenAIFeatures: false,
59+
enableConnectInNewWindow: false,
5960
...initialPreferences,
6061
})
6162
);

0 commit comments

Comments
 (0)