Switch VCore Mongo quickstart to use CloudShell terminal

- Replace NotebookTerminalComponent with CloudShellTerminalComponent in VCoreMongoQuickstartTab
- Refactor useTerminal hook to send messages via WebSocket instead of postRobot/iframe
- Register CloudShellTerminalComponent socket with useTerminal store
- Remove notebook dependencies (useNotebook, allocateContainer) from VCoreMongoQuickstartTab
- Remove useTerminal reference from NotebookTerminalComponent (dead code)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Jade Welton
2026-05-21 10:19:13 -07:00
parent 5989c77ccf
commit c7f9d7e305
5 changed files with 28 additions and 57 deletions
@@ -3,7 +3,6 @@
*/
import { AuthType } from "../../../AuthType";
import { useTerminal } from "hooks/useTerminal";
import postRobot from "post-robot";
import * as React from "react";
import * as DataModels from "../../../Contracts/DataModels";
@@ -55,7 +54,6 @@ export class NotebookTerminalComponent extends React.Component<NotebookTerminalC
handleFrameLoad(event: React.SyntheticEvent<HTMLIFrameElement, Event>): void {
this.terminalWindow = (event.target as HTMLIFrameElement).contentWindow;
useTerminal.getState().setTerminal(this.terminalWindow);
this.sendPropsToTerminalFrame();
}
@@ -1,3 +1,4 @@
import { useTerminal } from "hooks/useTerminal";
import React, { useEffect, useRef } from "react";
import { Terminal } from "xterm";
import { FitAddon } from "xterm-addon-fit";
@@ -59,7 +60,14 @@ export const CloudShellTerminalComponent: React.FC<CloudShellTerminalComponentPr
});
resizeObserver.observe(terminalRef.current);
socketRef.current = startCloudShellTerminal(terminal, props.shellType);
const initTerminal = async () => {
const socket = await startCloudShellTerminal(terminal, props.shellType);
socketRef.current = socket;
if (socket) {
useTerminal.getState().setSocket(socket);
}
};
initTerminal();
// Cleanup function to close WebSocket and dispose terminal
return () => {
@@ -73,6 +81,7 @@ export const CloudShellTerminalComponent: React.FC<CloudShellTerminalComponentPr
resizeObserver.unobserve(terminalRef.current);
}
terminal.dispose(); // Clean up XTerm instance
useTerminal.getState().setSocket(undefined);
};
}, []);
+1 -1
View File
@@ -315,7 +315,7 @@ const getReactTabContent = (activeReactTab: ReactTabKind, explorer: Explorer): J
}
case ReactTabKind.Quickstart:
return userContext.apiType === "VCoreMongo" ? (
<VcoreMongoQuickstartTab explorer={explorer} />
<VcoreMongoQuickstartTab />
) : (
<QuickstartTab explorer={explorer} />
);
+8 -38
View File
@@ -1,10 +1,8 @@
import { Spinner, SpinnerSize, Stack, Text } from "@fluentui/react";
import { Stack } from "@fluentui/react";
import { NotebookWorkspaceConnectionInfo } from "Contracts/DataModels";
import { MessageTypes } from "Contracts/ExplorerContracts";
import { NotebookTerminalComponent } from "Explorer/Controls/Notebook/NotebookTerminalComponent";
import Explorer from "Explorer/Explorer";
import { useNotebook } from "Explorer/Notebook/useNotebook";
import { TerminalKind } from "Contracts/ViewModels";
import { CloudShellTerminalComponent } from "Explorer/Tabs/CloudShellTab/CloudShellTerminalComponent";
import { QuickstartFirewallNotification } from "Explorer/Quickstart/QuickstartFirewallNotification";
import { VcoreMongoQuickstartGuide } from "Explorer/Quickstart/VCoreMongoQuickstartGuide";
import { checkFirewallRules } from "Explorer/Tabs/Shared/CheckFirewallRules";
@@ -12,22 +10,9 @@ import { userContext } from "UserContext";
import React, { useEffect, useState } from "react";
import FirewallRuleScreenshot from "../../../images/vcoreMongoFirewallRule.png";
interface VCoreMongoQuickstartTabProps {
explorer: Explorer;
}
export const VcoreMongoQuickstartTab: React.FC<VCoreMongoQuickstartTabProps> = ({
explorer,
}: VCoreMongoQuickstartTabProps): JSX.Element => {
const notebookServerInfo = useNotebook((state) => state.notebookServerInfo);
export const VcoreMongoQuickstartTab: React.FC = (): JSX.Element => {
const [isAllPublicIPAddressEnabled, setIsAllPublicIPAddressEnabled] = useState<boolean>(true);
const getNotebookServerInfo = (): NotebookWorkspaceConnectionInfo => ({
authToken: notebookServerInfo.authToken,
notebookServerEndpoint: `${notebookServerInfo.notebookServerEndpoint?.replace(/\/+$/, "")}/mongovcore`,
forwardingId: notebookServerInfo.forwardingId,
});
useEffect(() => {
checkFirewallRules(
"2023-03-01-preview",
@@ -38,10 +23,6 @@ export const VcoreMongoQuickstartTab: React.FC<VCoreMongoQuickstartTabProps> = (
);
});
useEffect(() => {
explorer.allocateContainer();
}, []);
return (
<Stack style={{ width: "100%" }} horizontal>
<Stack style={{ width: "50%" }}>
@@ -55,25 +36,14 @@ export const VcoreMongoQuickstartTab: React.FC<VCoreMongoQuickstartTabProps> = (
shellName="MongoDB"
/>
)}
{isAllPublicIPAddressEnabled && notebookServerInfo?.notebookServerEndpoint && (
<NotebookTerminalComponent
notebookServerInfo={getNotebookServerInfo()}
{isAllPublicIPAddressEnabled && (
<CloudShellTerminalComponent
databaseAccount={userContext.databaseAccount}
tabId="QuickstartVcoreMongoShell"
username={userContext.vcoreMongoConnectionParams.adminLogin}
username={userContext.vcoreMongoConnectionParams?.adminLogin}
shellType={TerminalKind.VCoreMongo}
/>
)}
{isAllPublicIPAddressEnabled && !notebookServerInfo?.notebookServerEndpoint && (
<Stack style={{ margin: "auto 0" }}>
<Text block style={{ margin: "auto" }}>
Connecting to the Mongo shell.
</Text>
<Text block style={{ margin: "auto" }}>
If the cluster was just created, this could take up to a minute.
</Text>
<Spinner styles={{ root: { marginTop: 16 } }} size={SpinnerSize.large}></Spinner>
</Stack>
)}
</Stack>
</Stack>
);
+9 -15
View File
@@ -1,26 +1,20 @@
import postRobot from "post-robot";
import create, { UseStore } from "zustand";
interface TerminalState {
terminalWindow: Window;
setTerminal: (terminalWindow: Window) => void;
socket: WebSocket | undefined;
setSocket: (socket: WebSocket) => void;
sendMessage: (message: string) => void;
}
export const useTerminal: UseStore<TerminalState> = create((set, get) => ({
terminalWindow: undefined,
setTerminal: (terminalWindow: Window) => {
set({ terminalWindow });
socket: undefined,
setSocket: (socket: WebSocket) => {
set({ socket });
},
sendMessage: (message: string) => {
const terminalWindow = get().terminalWindow;
postRobot.send(
terminalWindow,
"sendMessage",
{ type: "stdin", content: [message] },
{
domain: window.location.origin,
},
);
const socket = get().socket;
if (socket && socket.readyState === WebSocket.OPEN) {
socket.send(message + "\r");
}
},
}));