Skip to content
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

chore(react-electron-menu): implement React based rendering for the various electron menus in the app 🦨 #5818

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
320 changes: 241 additions & 79 deletions package-lock.json

Large diffs are not rendered by default.

42 changes: 38 additions & 4 deletions packages/compass-collection/src/components/collection-tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ import {
CollectionIndexesStats,
} from './collection-tab-stats';
import type { CollectionSubtab } from '@mongodb-js/compass-workspaces';
import {
ElectronMenuItem,
ElectronMenuSeparator,
ElectronSubMenu,
} from '@mongodb-js/react-electron-menu';
import { globalAppRegistry } from 'hadron-app-registry';

function trackingIdForTabName(name: string) {
return name.toLowerCase().replace(/ /g, '_');
Expand Down Expand Up @@ -242,10 +248,38 @@ const CollectionTab = ({
}

return (
<CollectionTabWithMetadata
collectionMetadata={collectionMetadata}
{...props}
></CollectionTabWithMetadata>
<>
<ElectronSubMenu label="&Collection">
<ElectronSubMenu label={collectionMetadata.namespace}>
<ElectronMenuItem
label="&Share Schema as JSON"
accelerator="Alt+CmdOrCtrl+S"
onClick={() => {
globalAppRegistry.emit('menu-share-schema-json');
}}
></ElectronMenuItem>
<ElectronMenuSeparator></ElectronMenuSeparator>
{!collectionMetadata.isReadonly && (
<ElectronMenuItem
label="&Import Data"
onClick={() => {
globalAppRegistry.emit('open-active-namespace-import');
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This still uses these special case active-namespace events because it was the fastest way to make it work, but as we now render these contextually, we can completely drop those types of events from the code as all the context is available here

}}
></ElectronMenuItem>
)}
<ElectronMenuItem
label="&Export Collection"
onClick={() => {
globalAppRegistry.emit('open-active-namespace-export');
}}
></ElectronMenuItem>
</ElectronSubMenu>
</ElectronSubMenu>
<CollectionTabWithMetadata
collectionMetadata={collectionMetadata}
{...props}
></CollectionTabWithMetadata>
</>
);
};

Expand Down
86 changes: 55 additions & 31 deletions packages/compass-connections-navigation/src/collection-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import type {
import type { Actions } from './constants';
import { usePreference } from 'compass-preferences-model/provider';
import { getItemPaddingStyles } from './utils';
import {
ElectronMenu,
ElectronMenuItem,
} from '@mongodb-js/react-electron-menu';

const CollectionIcon: React.FunctionComponent<{
type: string;
Expand Down Expand Up @@ -156,37 +160,57 @@ export const CollectionItem: React.FunctionComponent<
}, [type, isReadOnly, isRenameCollectionEnabled]);

return (
<ItemContainer
id={id}
data-testid={`sidebar-collection-${id}`}
level={level}
setSize={setSize}
posInSet={posInSet}
isActive={isActive}
isTabbable={isTabbable}
onDefaultAction={onDefaultAction}
style={style}
className={collectionItem}
{...hoverProps}
<ElectronMenu
type="context"
trigger={(props: any) => {
return (
<ItemContainer
id={id}
data-testid={`sidebar-collection-${id}`}
level={level}
setSize={setSize}
posInSet={posInSet}
isActive={isActive}
isTabbable={isTabbable}
onDefaultAction={onDefaultAction}
style={style}
className={collectionItem}
{...hoverProps}
containerRef={props.ref}
>
<ItemWrapper>
<ItemButtonWrapper
style={itemPaddingStyles}
className={itemButtonWrapper}
>
<CollectionIcon type={type} />
<ItemLabel className={collectionItemLabel} title={name}>
{name}
</ItemLabel>
</ItemButtonWrapper>
<ItemActionControls<Actions>
onAction={onAction}
data-testid="sidebar-collection-item-actions"
iconSize="small"
isVisible={isActive || isHovered}
actions={actions}
></ItemActionControls>
</ItemWrapper>
</ItemContainer>
);
}}
>
<ItemWrapper>
<ItemButtonWrapper
style={itemPaddingStyles}
className={itemButtonWrapper}
>
<CollectionIcon type={type} />
<ItemLabel className={collectionItemLabel} title={name}>
{name}
</ItemLabel>
</ItemButtonWrapper>
<ItemActionControls<Actions>
onAction={onAction}
data-testid="sidebar-collection-item-actions"
iconSize="small"
isVisible={isActive || isHovered}
actions={actions}
></ItemActionControls>
</ItemWrapper>
</ItemContainer>
{actions.map((action) => {
return (
<ElectronMenuItem
key={action.label}
label={action.label}
onClick={() => {
onAction(action.action);
}}
></ElectronMenuItem>
);
})}
</ElectronMenu>
);
};
5 changes: 4 additions & 1 deletion packages/compass-connections-navigation/src/tree-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ export const ItemContainer: React.FunctionComponent<
| React.KeyboardEvent<HTMLDivElement>
| React.MouseEvent<HTMLDivElement>
): void;
containerRef?: React.LegacyRef<HTMLDivElement>;
} & React.HTMLProps<HTMLDivElement>
> = ({
id,
Expand All @@ -229,6 +230,7 @@ export const ItemContainer: React.FunctionComponent<
onDefaultAction,
children,
className,
containerRef,
...props
}) => {
const isMultipleConnection = usePreference(
Expand Down Expand Up @@ -258,7 +260,8 @@ export const ItemContainer: React.FunctionComponent<
},
props,
defaultActionProps,
focusRingProps
focusRingProps,
{ ref: containerRef }
);

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import React, { useContext, useEffect, useRef } from 'react';
import { useConnectionsManagerContext } from '../provider';
import {
useActiveConnections,
useConnectionsManagerContext,
} from '../provider';
import { useConnections as useConnectionsStore } from '../stores/connections-store';
import { useConnectionRepository as useConnectionsRepositoryState } from '../hooks/use-connection-repository';
import {
ElectronMenuItem,
ElectronSubMenu,
} from '@mongodb-js/react-electron-menu';
import { getConnectionTitle } from '@mongodb-js/connection-info';

const ConnectionsStoreContext = React.createContext<ReturnType<
typeof useConnectionsStore
Expand All @@ -17,10 +25,41 @@ const ConnectionsStoreProvider: React.FunctionComponent<
UseConnectionsParams
> = ({ children, ...useConnectionsParams }) => {
const connectionsStore = useConnectionsStore(useConnectionsParams);
const activeConnections = useActiveConnections();

return (
<ConnectionsStoreContext.Provider value={connectionsStore}>
{children}
</ConnectionsStoreContext.Provider>
<>
{activeConnections.length > 0 && (
<ElectronSubMenu label="&Connect">
{activeConnections.map((connectionInfo) => {
return (
<ElectronSubMenu
key={connectionInfo.id}
label={getConnectionTitle(connectionInfo)}
>
<ElectronMenuItem
label="Disconnect"
onClick={() => {
void connectionsStore.closeConnection(connectionInfo.id);
}}
></ElectronMenuItem>
<ElectronMenuItem
label="Copy Connection String"
onClick={() => {
void navigator.clipboard.writeText(
connectionInfo.connectionOptions.connectionString
);
}}
></ElectronMenuItem>
</ElectronSubMenu>
);
})}
</ElectronSubMenu>
)}
<ConnectionsStoreContext.Provider value={connectionsStore}>
{children}
</ConnectionsStoreContext.Provider>
</>
);
};

Expand Down
57 changes: 41 additions & 16 deletions packages/compass-crud/src/components/document-list-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import type { DocumentProps } from './document';
import Document from './document';
import type HadronDocument from 'hadron-document';
import type { BSONObject } from '../stores/crud-store';
import {
ElectronMenu,
ElectronMenuItem,
} from '@mongodb-js/react-electron-menu';

const listStyles = css({
listStyle: 'none',
Expand Down Expand Up @@ -51,24 +55,45 @@ class DocumentListView extends React.Component<DocumentListViewProps> {
renderDocuments() {
return this.props.docs.map((doc, index) => {
return (
<li
className={listItemStyles}
data-testid="document-list-item"
<ElectronMenu
key={index}
type="context"
trigger={(props: any) => {
return (
<li
className={listItemStyles}
data-testid="document-list-item"
{...props}
>
<KeylineCard>
<Document
doc={doc}
editable={this.props.isEditable}
isTimeSeries={this.props.isTimeSeries}
copyToClipboard={this.props.copyToClipboard}
removeDocument={this.props.removeDocument}
replaceDocument={this.props.replaceDocument}
updateDocument={this.props.updateDocument}
openInsertDocumentDialog={
this.props.openInsertDocumentDialog
}
/>
</KeylineCard>
</li>
);
}}
>
<KeylineCard>
<Document
doc={doc}
editable={this.props.isEditable}
isTimeSeries={this.props.isTimeSeries}
copyToClipboard={this.props.copyToClipboard}
removeDocument={this.props.removeDocument}
replaceDocument={this.props.replaceDocument}
updateDocument={this.props.updateDocument}
openInsertDocumentDialog={this.props.openInsertDocumentDialog}
/>
</KeylineCard>
</li>
<ElectronMenuItem
label="Copy Document"
onClick={() => {
const str =
typeof doc.toEJSON === 'function'
? doc.toEJSON()
: JSON.stringify(doc);
void navigator.clipboard.writeText(str);
}}
></ElectronMenuItem>
</ElectronMenu>
);
});
}
Expand Down
3 changes: 2 additions & 1 deletion packages/compass/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@
"@mongodb-js/compass-app-stores": "^7.13.0",
"@mongodb-js/compass-collection": "^4.26.0",
"@mongodb-js/compass-components": "^1.25.0",
"@mongodb-js/compass-connections": "^1.28.0",
"@mongodb-js/compass-connection-import-export": "^0.24.0",
"@mongodb-js/compass-connections": "^1.28.0",
"@mongodb-js/compass-crud": "^13.27.0",
"@mongodb-js/compass-databases-collections": "^1.26.0",
"@mongodb-js/compass-explain-plan": "^6.27.0",
Expand Down Expand Up @@ -215,6 +215,7 @@
"@mongodb-js/mongodb-downloader": "^0.3.0",
"@mongodb-js/my-queries-storage": "^0.8.0",
"@mongodb-js/prettier-config-compass": "^1.0.2",
"@mongodb-js/react-electron-menu": "^1.0.0",
"@mongodb-js/sbom-tools": "^0.5.3",
"@mongodb-js/tsconfig-compass": "^1.0.4",
"@mongodb-js/webpack-config-compass": "^1.3.8",
Expand Down
4 changes: 4 additions & 0 deletions packages/compass/src/app/components/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ import {
ExportConnectionsModal,
} from '@mongodb-js/compass-connection-import-export';
import { usePreference } from 'compass-preferences-model/provider';
import {
ElectronMenuItem,
ElectronSubMenu,
} from '@mongodb-js/react-electron-menu';

resetGlobalCSS();

Expand Down
Loading
Loading