Remove Phoenix & Notebooks — Phase 1: Decouple database shells to CloudShell (#2513)

* Add implementation plan for removing Phoenix and notebooks

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Phase 1: Decouple database shells from Phoenix to CloudShell-only

Migrate all shell terminals to the CloudShell path and remove the legacy Phoenix notebook-server terminal code so shells no longer depend on notebook provisioning.

- TerminalTab now always uses CloudShellTerminalComponentAdapter; removed the notebook-server adapter branch, getNotebookServerInfo, and the dead VCoreMongo firewall check
- Migrate Postgres and VCore Mongo quickstart tabs to CloudShellTerminalComponent (drop allocateContainer/useNotebook dependencies)
- Refactor useTerminal to send input via the CloudShell WebSocket instead of postRobot/iframe; register the socket from CloudShellTerminalComponent
- Simplify Explorer.openNotebookTerminal to always open a CloudShell terminal
- Delete NotebookTerminalComponent(+test/less/snapshot), NotebookTerminalComponentAdapter, and the src/Terminal/ entry point
- Remove the terminal.html webpack entry/HTML plugin and src/Terminal from tsconfig.strict.json

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
jawelton74
2026-06-15 06:29:14 -07:00
committed by GitHub
parent 74b6a92219
commit d19c7e0cb7
23 changed files with 259 additions and 1078 deletions
@@ -1,13 +0,0 @@
@import "../../../../less/Common/Constants";
.notebookTerminalContainer {
padding: @DefaultSpace;
height: 100%;
width: 100%;
iframe {
border: none;
height: 100%;
width: 100%;
}
}
@@ -1,146 +0,0 @@
import { shallow } from "enzyme";
import React from "react";
import * as DataModels from "../../../Contracts/DataModels";
import { NotebookTerminalComponent, NotebookTerminalComponentProps } from "./NotebookTerminalComponent";
const testAccount: DataModels.DatabaseAccount = {
id: "id",
kind: "kind",
location: "location",
name: "name",
properties: {
documentEndpoint: "https://testDocumentEndpoint.azure.com/",
},
type: "type",
};
const testMongo32Account: DataModels.DatabaseAccount = {
...testAccount,
};
const testMongo36Account: DataModels.DatabaseAccount = {
...testAccount,
properties: {
mongoEndpoint: "https://testMongoEndpoint.azure.com/",
},
};
const testCassandraAccount: DataModels.DatabaseAccount = {
...testAccount,
properties: {
cassandraEndpoint: "https://testCassandraEndpoint.azure.com/",
},
};
const testPostgresAccount: DataModels.DatabaseAccount = {
...testAccount,
properties: {
postgresqlEndpoint: "https://testPostgresEndpoint.azure.com/",
},
};
const testVCoreMongoAccount: DataModels.DatabaseAccount = {
...testAccount,
properties: {
vcoreMongoEndpoint: "https://testVCoreMongoEndpoint.azure.com/",
},
};
const testNotebookServerInfo: DataModels.NotebookWorkspaceConnectionInfo = {
authToken: "authToken",
notebookServerEndpoint: "https://testNotebookServerEndpoint.azure.com",
forwardingId: "Id",
};
const testMongoNotebookServerInfo: DataModels.NotebookWorkspaceConnectionInfo = {
authToken: "authToken",
notebookServerEndpoint: "https://testNotebookServerEndpoint.azure.com/mongo",
forwardingId: "Id",
};
const testCassandraNotebookServerInfo: DataModels.NotebookWorkspaceConnectionInfo = {
authToken: "authToken",
notebookServerEndpoint: "https://testNotebookServerEndpoint.azure.com/cassandra",
forwardingId: "Id",
};
const testPostgresNotebookServerInfo: DataModels.NotebookWorkspaceConnectionInfo = {
authToken: "authToken",
notebookServerEndpoint: "https://testNotebookServerEndpoint.azure.com/postgresql",
forwardingId: "Id",
};
const testVCoreMongoNotebookServerInfo: DataModels.NotebookWorkspaceConnectionInfo = {
authToken: "authToken",
notebookServerEndpoint: "https://testNotebookServerEndpoint.azure.com/mongovcore",
forwardingId: "Id",
};
describe("NotebookTerminalComponent", () => {
it("renders terminal", () => {
const props: NotebookTerminalComponentProps = {
databaseAccount: testAccount,
notebookServerInfo: testNotebookServerInfo,
tabId: undefined,
};
const wrapper = shallow(<NotebookTerminalComponent {...props} />);
expect(wrapper).toMatchSnapshot();
});
it("renders mongo 3.2 shell", () => {
const props: NotebookTerminalComponentProps = {
databaseAccount: testMongo32Account,
notebookServerInfo: testMongoNotebookServerInfo,
tabId: undefined,
};
const wrapper = shallow(<NotebookTerminalComponent {...props} />);
expect(wrapper).toMatchSnapshot();
});
it("renders mongo 3.6 shell", () => {
const props: NotebookTerminalComponentProps = {
databaseAccount: testMongo36Account,
notebookServerInfo: testMongoNotebookServerInfo,
tabId: undefined,
};
const wrapper = shallow(<NotebookTerminalComponent {...props} />);
expect(wrapper).toMatchSnapshot();
});
it("renders cassandra shell", () => {
const props: NotebookTerminalComponentProps = {
databaseAccount: testCassandraAccount,
notebookServerInfo: testCassandraNotebookServerInfo,
tabId: undefined,
};
const wrapper = shallow(<NotebookTerminalComponent {...props} />);
expect(wrapper).toMatchSnapshot();
});
it("renders Postgres shell", () => {
const props: NotebookTerminalComponentProps = {
databaseAccount: testPostgresAccount,
notebookServerInfo: testPostgresNotebookServerInfo,
tabId: undefined,
};
const wrapper = shallow(<NotebookTerminalComponent {...props} />);
expect(wrapper).toMatchSnapshot();
});
it("renders vCore Mongo shell", () => {
const props: NotebookTerminalComponentProps = {
databaseAccount: testVCoreMongoAccount,
notebookServerInfo: testVCoreMongoNotebookServerInfo,
tabId: undefined,
username: "username",
};
const wrapper = shallow(<NotebookTerminalComponent {...props} />);
expect(wrapper).toMatchSnapshot();
});
});
@@ -1,99 +0,0 @@
/**
* Wrapper around Notebook server terminal
*/
import { useTerminal } from "hooks/useTerminal";
import postRobot from "post-robot";
import * as React from "react";
import * as DataModels from "../../../Contracts/DataModels";
import { TerminalProps } from "../../../Terminal/TerminalProps";
import { userContext } from "../../../UserContext";
import * as StringUtils from "../../../Utils/StringUtils";
export interface NotebookTerminalComponentProps {
notebookServerInfo: DataModels.NotebookWorkspaceConnectionInfo;
databaseAccount: DataModels.DatabaseAccount;
tabId: string;
username?: string;
}
export class NotebookTerminalComponent extends React.Component<NotebookTerminalComponentProps> {
private terminalWindow: Window;
constructor(props: NotebookTerminalComponentProps) {
super(props);
}
componentDidMount(): void {
this.sendPropsToTerminalFrame();
}
public render(): JSX.Element {
return (
<div className="notebookTerminalContainer">
<iframe
title="Terminal to Notebook Server"
onLoad={(event) => this.handleFrameLoad(event)}
src="terminal.html"
/>
</div>
);
}
handleFrameLoad(event: React.SyntheticEvent<HTMLIFrameElement, Event>): void {
this.terminalWindow = (event.target as HTMLIFrameElement).contentWindow;
useTerminal.getState().setTerminal(this.terminalWindow);
this.sendPropsToTerminalFrame();
}
sendPropsToTerminalFrame(): void {
if (!this.terminalWindow) {
return;
}
let props: TerminalProps = {
terminalEndpoint: this.tryGetTerminalEndpoint(),
notebookServerEndpoint: this.props.notebookServerInfo?.notebookServerEndpoint,
authToken: this.props.notebookServerInfo?.authToken,
subscriptionId: userContext.subscriptionId,
apiType: userContext.apiType,
authType: userContext.authType,
databaseAccount: userContext.databaseAccount,
tabId: this.props.tabId,
};
if (this.props.username) {
props = {
...props,
username: this.props.username,
};
}
postRobot.send(this.terminalWindow, "props", props, {
domain: window.location.origin,
});
}
public tryGetTerminalEndpoint(): string | undefined {
let terminalEndpoint: string | undefined;
const notebookServerEndpoint = this.props.notebookServerInfo?.notebookServerEndpoint;
if (StringUtils.endsWith(notebookServerEndpoint, "mongo")) {
// mongoEndpoint is only available for Mongo 3.6 and higher, fallback to documentEndpoint otherwise
terminalEndpoint =
this.props.databaseAccount?.properties.mongoEndpoint || this.props.databaseAccount?.properties.documentEndpoint;
} else if (StringUtils.endsWith(notebookServerEndpoint, "cassandra")) {
terminalEndpoint = this.props.databaseAccount?.properties.cassandraEndpoint;
} else if (StringUtils.endsWith(notebookServerEndpoint, "postgresql")) {
return this.props.databaseAccount?.properties.postgresqlEndpoint;
} else if (StringUtils.endsWith(notebookServerEndpoint, "mongovcore")) {
return this.props.databaseAccount?.properties.vcoreMongoEndpoint;
}
if (terminalEndpoint) {
return new URL(terminalEndpoint).host;
}
return undefined;
}
}
@@ -1,73 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`NotebookTerminalComponent renders Postgres shell 1`] = `
<div
className="notebookTerminalContainer"
>
<iframe
onLoad={[Function]}
src="terminal.html"
title="Terminal to Notebook Server"
/>
</div>
`;
exports[`NotebookTerminalComponent renders cassandra shell 1`] = `
<div
className="notebookTerminalContainer"
>
<iframe
onLoad={[Function]}
src="terminal.html"
title="Terminal to Notebook Server"
/>
</div>
`;
exports[`NotebookTerminalComponent renders mongo 3.2 shell 1`] = `
<div
className="notebookTerminalContainer"
>
<iframe
onLoad={[Function]}
src="terminal.html"
title="Terminal to Notebook Server"
/>
</div>
`;
exports[`NotebookTerminalComponent renders mongo 3.6 shell 1`] = `
<div
className="notebookTerminalContainer"
>
<iframe
onLoad={[Function]}
src="terminal.html"
title="Terminal to Notebook Server"
/>
</div>
`;
exports[`NotebookTerminalComponent renders terminal 1`] = `
<div
className="notebookTerminalContainer"
>
<iframe
onLoad={[Function]}
src="terminal.html"
title="Terminal to Notebook Server"
/>
</div>
`;
exports[`NotebookTerminalComponent renders vCore Mongo shell 1`] = `
<div
className="notebookTerminalContainer"
>
<iframe
onLoad={[Function]}
src="terminal.html"
title="Terminal to Notebook Server"
/>
</div>
`;
+2 -19
View File
@@ -959,25 +959,8 @@ export default class Explorer {
await this.notebookManager?.notebookContentClient.updateItemChildrenInPlace(item);
}
public async openNotebookTerminal(kind: ViewModels.TerminalKind): Promise<void> {
if (userContext.features.enableCloudShell) {
this.connectToNotebookTerminal(kind);
} else if (useNotebook.getState().isPhoenixFeatures) {
await this.allocateContainer();
const notebookServerInfo = useNotebook.getState().notebookServerInfo;
if (notebookServerInfo && notebookServerInfo.notebookServerEndpoint !== undefined) {
this.connectToNotebookTerminal(kind);
} else {
useDialog
.getState()
.showOkModalDialog(
"Failed to connect",
"Failed to connect to temporary workspace. This could happen because of network issues. Please refresh the page and try again.",
);
}
} else {
this.connectToNotebookTerminal(kind);
}
public openNotebookTerminal(kind: ViewModels.TerminalKind): void {
this.connectToNotebookTerminal(kind);
}
private connectToNotebookTerminal(kind: ViewModels.TerminalKind): void {
@@ -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);
};
}, []);
+7 -35
View File
@@ -1,31 +1,18 @@
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 { QuickstartFirewallNotification } from "Explorer/Quickstart/QuickstartFirewallNotification";
import { QuickstartGuide } from "Explorer/Quickstart/QuickstartGuide";
import { CloudShellTerminalComponent } from "Explorer/Tabs/CloudShellTab/CloudShellTerminalComponent";
import { checkFirewallRules } from "Explorer/Tabs/Shared/CheckFirewallRules";
import { userContext } from "UserContext";
import React, { useEffect, useState } from "react";
import FirewallRuleScreenshot from "../../../images/firewallRule.png";
interface QuickstartTabProps {
explorer: Explorer;
}
export const QuickstartTab: React.FC<QuickstartTabProps> = ({ explorer }: QuickstartTabProps): JSX.Element => {
const notebookServerInfo = useNotebook((state) => state.notebookServerInfo);
export const QuickstartTab: React.FC = (): JSX.Element => {
const [isAllPublicIPAddressEnabled, setIsAllPublicIPAddressEnabled] = useState<boolean>(true);
const getNotebookServerInfo = (): NotebookWorkspaceConnectionInfo => ({
authToken: notebookServerInfo.authToken,
notebookServerEndpoint: `${notebookServerInfo.notebookServerEndpoint?.replace(/\/+$/, "")}/postgresql`,
forwardingId: notebookServerInfo.forwardingId,
});
useEffect(() => {
checkFirewallRules(
"2022-11-08",
@@ -34,10 +21,6 @@ export const QuickstartTab: React.FC<QuickstartTabProps> = ({ explorer }: Quicks
);
});
useEffect(() => {
explorer.allocateContainer();
}, []);
return (
<Stack style={{ width: "100%" }} horizontal>
<Stack style={{ width: "50%" }}>
@@ -51,24 +34,13 @@ export const QuickstartTab: React.FC<QuickstartTabProps> = ({ explorer }: Quicks
shellName="PostgreSQL"
/>
)}
{isAllPublicIPAddressEnabled && notebookServerInfo?.notebookServerEndpoint && (
<NotebookTerminalComponent
notebookServerInfo={getNotebookServerInfo()}
{isAllPublicIPAddressEnabled && (
<CloudShellTerminalComponent
databaseAccount={userContext.databaseAccount}
tabId="QuickstartPSQLShell"
shellType={TerminalKind.Postgres}
/>
)}
{isAllPublicIPAddressEnabled && !notebookServerInfo?.notebookServerEndpoint && (
<Stack style={{ margin: "auto 0" }}>
<Text block style={{ margin: "auto" }}>
Connecting to the PostgreSQL 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>
);
@@ -1,32 +0,0 @@
import { NotebookTerminalComponent } from "Explorer/Controls/Notebook/NotebookTerminalComponent";
import * as React from "react";
import * as DataModels from "../../../Contracts/DataModels";
import * as ViewModels from "../../../Contracts/ViewModels";
import { BaseTerminalComponentAdapter } from "./BaseTerminalComponentAdapter";
/**
* Notebook terminal tab
*/
export class NotebookTerminalComponentAdapter extends BaseTerminalComponentAdapter {
constructor(
private getNotebookServerInfo: () => DataModels.NotebookWorkspaceConnectionInfo,
getDatabaseAccount: () => DataModels.DatabaseAccount,
getTabId: () => string,
getUsername: () => string,
isAllPublicIPAddressesEnabled: ko.Observable<boolean>,
kind: ViewModels.TerminalKind,
) {
super(getDatabaseAccount, getTabId, getUsername, isAllPublicIPAddressesEnabled, kind);
}
protected renderTerminalComponent(): JSX.Element {
return (
<NotebookTerminalComponent
notebookServerInfo={this.getNotebookServerInfo()}
databaseAccount={this.getDatabaseAccount()}
tabId={this.getTabId()}
username={this.getUsername()}
/>
);
}
}
+1 -5
View File
@@ -333,11 +333,7 @@ const getReactTabContent = (activeReactTab: ReactTabKind, explorer: Explorer): J
return <SplashScreen explorer={explorer} />;
}
case ReactTabKind.Quickstart:
return userContext.apiType === "VCoreMongo" ? (
<VcoreMongoQuickstartTab explorer={explorer} />
) : (
<QuickstartTab explorer={explorer} />
);
return userContext.apiType === "VCoreMongo" ? <VcoreMongoQuickstartTab /> : <QuickstartTab />;
default:
throw new Error(`Unsupported tab kind ${ReactTabKind[activeReactTab]}`);
}
+5 -77
View File
@@ -7,8 +7,6 @@ import * as ViewModels from "../../Contracts/ViewModels";
import { userContext } from "../../UserContext";
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
import Explorer from "../Explorer";
import { useNotebook } from "../Notebook/useNotebook";
import { NotebookTerminalComponentAdapter } from "./ShellAdapters/NotebookTerminalComponentAdapter";
import TabsBase from "./TabsBase";
export interface TerminalTabOptions extends ViewModels.TabOptions {
@@ -29,41 +27,17 @@ export default class TerminalTab extends TabsBase {
this.container = options.container;
this.isAllPublicIPAddressesEnabled = ko.observable(true);
const commonArgs: [
() => DataModels.DatabaseAccount,
() => string,
() => string,
ko.Observable<boolean>,
ViewModels.TerminalKind,
] = [
this.notebookTerminalComponentAdapter = new CloudShellTerminalComponentAdapter(
() => userContext?.databaseAccount,
() => this.tabId,
() => this.getUsername(),
this.isAllPublicIPAddressesEnabled,
options.kind,
];
);
if (userContext.features.enableCloudShell) {
this.notebookTerminalComponentAdapter = new CloudShellTerminalComponentAdapter(...commonArgs);
this.notebookTerminalComponentAdapter.parameters = ko.computed<boolean>(() => {
return this.isTemplateReady() && this.isAllPublicIPAddressesEnabled();
});
} else {
this.notebookTerminalComponentAdapter = new NotebookTerminalComponentAdapter(
() => this.getNotebookServerInfo(options),
...commonArgs,
);
this.notebookTerminalComponentAdapter.parameters = ko.computed<boolean>(() => {
return (
this.isTemplateReady() &&
useNotebook.getState().isNotebookEnabled &&
useNotebook.getState().notebookServerInfo?.notebookServerEndpoint &&
this.isAllPublicIPAddressesEnabled()
);
});
}
this.notebookTerminalComponentAdapter.parameters = ko.computed<boolean>(() => {
return this.isTemplateReady() && this.isAllPublicIPAddressesEnabled();
});
if (options.kind === ViewModels.TerminalKind.Postgres) {
checkFirewallRules(
@@ -72,16 +46,6 @@ export default class TerminalTab extends TabsBase {
this.isAllPublicIPAddressesEnabled,
);
}
if (options.kind === ViewModels.TerminalKind.VCoreMongo) {
checkFirewallRules(
"2023-03-01-preview",
(rule) =>
rule.name.startsWith("AllowAllAzureServicesAndResourcesWithinAzureIps") ||
(rule.properties.startIpAddress === "0.0.0.0" && rule.properties.endIpAddress === "255.255.255.255"),
this.isAllPublicIPAddressesEnabled,
);
}
}
public getContainer(): Explorer {
@@ -96,42 +60,6 @@ export default class TerminalTab extends TabsBase {
this.updateNavbarWithTabsButtons();
}
private getNotebookServerInfo(options: TerminalTabOptions): DataModels.NotebookWorkspaceConnectionInfo {
let endpointSuffix: string;
switch (options.kind) {
case ViewModels.TerminalKind.Default:
endpointSuffix = "";
break;
case ViewModels.TerminalKind.Mongo:
endpointSuffix = "mongo";
break;
case ViewModels.TerminalKind.Cassandra:
endpointSuffix = "cassandra";
break;
case ViewModels.TerminalKind.Postgres:
endpointSuffix = "postgresql";
break;
case ViewModels.TerminalKind.VCoreMongo:
endpointSuffix = "mongovcore";
break;
default:
throw new Error(`Terminal kind: ${options.kind} not supported`);
}
const info: DataModels.NotebookWorkspaceConnectionInfo = useNotebook.getState().notebookServerInfo;
return {
authToken: info.authToken,
notebookServerEndpoint: `${info.notebookServerEndpoint.replace(/\/+$/, "")}/${endpointSuffix}`,
forwardingId: info.forwardingId,
};
}
private getUsername(): string {
if (userContext.apiType !== "VCoreMongo" || !userContext?.vcoreMongoConnectionParams?.adminLogin) {
return undefined;
+11 -66
View File
@@ -1,79 +1,24 @@
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 { QuickstartFirewallNotification } from "Explorer/Quickstart/QuickstartFirewallNotification";
import { TerminalKind } from "Contracts/ViewModels";
import { VcoreMongoQuickstartGuide } from "Explorer/Quickstart/VCoreMongoQuickstartGuide";
import { checkFirewallRules } from "Explorer/Tabs/Shared/CheckFirewallRules";
import { CloudShellTerminalComponent } from "Explorer/Tabs/CloudShellTab/CloudShellTerminalComponent";
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);
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",
(rule) =>
rule.name.startsWith("AllowAllAzureServicesAndResourcesWithinAzureIps") ||
(rule.properties.startIpAddress === "0.0.0.0" && rule.properties.endIpAddress === "255.255.255.255"),
setIsAllPublicIPAddressEnabled,
);
});
useEffect(() => {
explorer.allocateContainer();
}, []);
import React from "react";
export const VcoreMongoQuickstartTab: React.FC = (): JSX.Element => {
return (
<Stack style={{ width: "100%" }} horizontal>
<Stack style={{ width: "50%" }}>
<VcoreMongoQuickstartGuide />
</Stack>
<Stack style={{ width: "50%", borderLeft: "black solid 1px" }}>
{!isAllPublicIPAddressEnabled && (
<QuickstartFirewallNotification
messageType={MessageTypes.OpenVCoreMongoNetworkingBlade}
screenshot={FirewallRuleScreenshot}
shellName="MongoDB"
/>
)}
{isAllPublicIPAddressEnabled && notebookServerInfo?.notebookServerEndpoint && (
<NotebookTerminalComponent
notebookServerInfo={getNotebookServerInfo()}
databaseAccount={userContext.databaseAccount}
tabId="QuickstartVcoreMongoShell"
username={userContext.vcoreMongoConnectionParams.adminLogin}
/>
)}
{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>
)}
<CloudShellTerminalComponent
databaseAccount={userContext.databaseAccount}
tabId="QuickstartVcoreMongoShell"
username={userContext.vcoreMongoConnectionParams?.adminLogin}
shellType={TerminalKind.VCoreMongo}
/>
</Stack>
</Stack>
);