Migrate Mongo Shell tab to React (#900)
This commit is contained in:
parent
f9bd12eaa6
commit
f255387ccd
|
@ -143,7 +143,7 @@ src/Explorer/Tabs/DocumentsTab.ts
|
|||
src/Explorer/Tabs/GraphTab.ts
|
||||
src/Explorer/Tabs/MongoDocumentsTab.ts
|
||||
# src/Explorer/Tabs/MongoQueryTab.ts
|
||||
src/Explorer/Tabs/MongoShellTab.ts
|
||||
# src/Explorer/Tabs/MongoShellTab.ts
|
||||
src/Explorer/Tabs/NotebookV2Tab.ts
|
||||
src/Explorer/Tabs/ScriptTabBase.ts
|
||||
src/Explorer/Tabs/StoredProcedureTab.ts
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
<iframe
|
||||
name="explorer"
|
||||
class="iframe"
|
||||
style="width: 100%; height: 100%; border: 0px; padding: 0px; margin: 0px; overflow: hidden"
|
||||
data-bind="
|
||||
attr: {
|
||||
src: url,
|
||||
id: tabId
|
||||
},
|
||||
event:{
|
||||
load: setContentFocus(event)
|
||||
}"
|
||||
title="Mongo Shell"
|
||||
role="tabpanel"
|
||||
></iframe>
|
|
@ -0,0 +1,39 @@
|
|||
import React from "react";
|
||||
import * as DataModels from "../../../Contracts/DataModels";
|
||||
import type { TabOptions } from "../../../Contracts/ViewModels";
|
||||
import Explorer from "../../Explorer";
|
||||
import TabsBase from "../TabsBase";
|
||||
import MongoShellTabComponent, { IMongoShellTabAccessor, IMongoShellTabComponentProps } from "./MongoShellTabComponent";
|
||||
|
||||
export interface IMongoShellTabProps {
|
||||
container: Explorer;
|
||||
}
|
||||
|
||||
export class NewMongoShellTab extends TabsBase {
|
||||
public queryText: string;
|
||||
public currentQuery: string;
|
||||
public partitionKey: DataModels.PartitionKey;
|
||||
public iMongoShellTabComponentProps: IMongoShellTabComponentProps;
|
||||
public iMongoShellTabAccessor: IMongoShellTabAccessor;
|
||||
|
||||
constructor(options: TabOptions, private props: IMongoShellTabProps) {
|
||||
super(options);
|
||||
this.iMongoShellTabComponentProps = {
|
||||
collection: this.collection,
|
||||
tabsBaseInstance: this,
|
||||
container: this.props.container,
|
||||
onMongoShellTabAccessor: (instance: IMongoShellTabAccessor) => {
|
||||
this.iMongoShellTabAccessor = instance;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
return <MongoShellTabComponent {...this.iMongoShellTabComponentProps} />;
|
||||
}
|
||||
|
||||
public onTabClick(): void {
|
||||
this.manager?.activateTab(this);
|
||||
this.iMongoShellTabAccessor.onTabClickEvent();
|
||||
}
|
||||
}
|
|
@ -1,28 +1,71 @@
|
|||
import * as ko from "knockout";
|
||||
import * as Constants from "../../Common/Constants";
|
||||
import { configContext, Platform } from "../../ConfigContext";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "../../UserContext";
|
||||
import { isInvalidParentFrameOrigin, isReadyMessage } from "../../Utils/MessageValidation";
|
||||
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
|
||||
import Explorer from "../Explorer";
|
||||
import template from "./MongoShellTab.html";
|
||||
import TabsBase from "./TabsBase";
|
||||
import React, { Component } from "react";
|
||||
import * as Constants from "../../../Common/Constants";
|
||||
import { configContext, Platform } from "../../../ConfigContext";
|
||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "../../../UserContext";
|
||||
import { isInvalidParentFrameOrigin, isReadyMessage } from "../../../Utils/MessageValidation";
|
||||
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../../Utils/NotificationConsoleUtils";
|
||||
import Explorer from "../../Explorer";
|
||||
import TabsBase from "../TabsBase";
|
||||
|
||||
export default class MongoShellTab extends TabsBase {
|
||||
public readonly html = template;
|
||||
public url: ko.Computed<string>;
|
||||
private _container: Explorer;
|
||||
//eslint-disable-next-line
|
||||
class MessageType {
|
||||
static IframeReady = "iframeready";
|
||||
static Notification = "notification";
|
||||
static Log = "log";
|
||||
}
|
||||
|
||||
//eslint-disable-next-line
|
||||
class LogType {
|
||||
static Information = "information";
|
||||
static Warning = "warning";
|
||||
static Verbose = "verbose";
|
||||
static InProgress = "inprogress";
|
||||
static StartTrace = "start";
|
||||
static SuccessTrace = "success";
|
||||
static FailureTrace = "failure";
|
||||
}
|
||||
|
||||
export interface IMongoShellTabAccessor {
|
||||
onTabClickEvent: () => void;
|
||||
}
|
||||
|
||||
export interface IMongoShellTabComponentStates {
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface IMongoShellTabComponentProps {
|
||||
collection: ViewModels.CollectionBase;
|
||||
tabsBaseInstance: TabsBase;
|
||||
container: Explorer;
|
||||
onMongoShellTabAccessor: (instance: IMongoShellTabAccessor) => void;
|
||||
}
|
||||
|
||||
export default class MongoShellTabComponent extends Component<
|
||||
IMongoShellTabComponentProps,
|
||||
IMongoShellTabComponentStates
|
||||
> {
|
||||
private _runtimeEndpoint: string;
|
||||
private _logTraces: Map<string, number>;
|
||||
|
||||
constructor(options: ViewModels.TabOptions) {
|
||||
super(options);
|
||||
constructor(props: IMongoShellTabComponentProps) {
|
||||
super(props);
|
||||
this._logTraces = new Map();
|
||||
this._container = options.collection.container;
|
||||
this.url = ko.computed<string>(() => {
|
||||
|
||||
this.state = {
|
||||
url: this.getURL(),
|
||||
};
|
||||
|
||||
props.onMongoShellTabAccessor({
|
||||
onTabClickEvent: this.onTabClick.bind(this),
|
||||
});
|
||||
|
||||
window.addEventListener("message", this.handleMessage.bind(this), false);
|
||||
}
|
||||
|
||||
public getURL(): string {
|
||||
const { databaseAccount: account } = userContext;
|
||||
const resourceId = account?.id;
|
||||
const accountName = account?.name;
|
||||
|
@ -36,32 +79,23 @@ export default class MongoShellTab extends TabsBase {
|
|||
}
|
||||
|
||||
return `${extensionEndpoint}${baseUrl}index.html?resourceId=${resourceId}&accountName=${accountName}&mongoEndpoint=${mongoEndpoint}`;
|
||||
});
|
||||
|
||||
window.addEventListener("message", this.handleMessage.bind(this), false);
|
||||
}
|
||||
|
||||
public setContentFocus(event: any): any {
|
||||
// TODO: Work around cross origin security issue in Hosted Data Explorer by using Shell <-> Data Explorer messaging (253527)
|
||||
// if(event.type === "load" && window.dataExplorerPlatform != PlatformType.Hosted) {
|
||||
// let activeShell = event.target.contentWindow && event.target.contentWindow.mongo && event.target.contentWindow.mongo.shells && event.target.contentWindow.mongo.shells[0];
|
||||
// activeShell && setTimeout(function(){
|
||||
// activeShell.focus();
|
||||
// },2000);
|
||||
// }
|
||||
}
|
||||
//eslint-disable-next-line
|
||||
public setContentFocus(event: React.SyntheticEvent<HTMLIFrameElement, Event>): void {}
|
||||
|
||||
public onTabClick(): void {
|
||||
super.onTabClick();
|
||||
this.collection.selectedSubnodeKind(ViewModels.CollectionTabKind.Documents);
|
||||
this.props.collection.selectedSubnodeKind(ViewModels.CollectionTabKind.Documents);
|
||||
}
|
||||
|
||||
public handleMessage(event: MessageEvent) {
|
||||
public handleMessage(event: MessageEvent): void {
|
||||
if (isInvalidParentFrameOrigin(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const shellIframe: HTMLIFrameElement = <HTMLIFrameElement>document.getElementById(this.tabId);
|
||||
const shellIframe: HTMLIFrameElement = document.getElementById(
|
||||
this.props.tabsBaseInstance.tabId
|
||||
) as HTMLIFrameElement;
|
||||
|
||||
if (!shellIframe) {
|
||||
return;
|
||||
|
@ -73,9 +107,9 @@ export default class MongoShellTab extends TabsBase {
|
|||
return;
|
||||
}
|
||||
|
||||
if (event.data.eventType == MessageType.IframeReady) {
|
||||
if (event.data.eventType === MessageType.IframeReady) {
|
||||
this.handleReadyMessage(event, shellIframe);
|
||||
} else if (event.data.eventType == MessageType.Notification) {
|
||||
} else if (event.data.eventType === MessageType.Notification) {
|
||||
this.handleNotificationMessage(event, shellIframe);
|
||||
} else {
|
||||
this.handleLogMessage(event, shellIframe);
|
||||
|
@ -98,8 +132,8 @@ export default class MongoShellTab extends TabsBase {
|
|||
documentEndpoint.length -
|
||||
(Constants.MongoDBAccounts.protocol.length + 2 + Constants.MongoDBAccounts.defaultPort.length)
|
||||
) + Constants.MongoDBAccounts.defaultPort.toString();
|
||||
const databaseId = this.collection.databaseId;
|
||||
const collectionId = this.collection.id();
|
||||
const databaseId = this.props.collection.databaseId;
|
||||
const collectionId = this.props.collection.id();
|
||||
const apiEndpoint = configContext.BACKEND_ENDPOINT;
|
||||
const encryptedAuthToken: string = userContext.accessToken;
|
||||
|
||||
|
@ -121,6 +155,7 @@ export default class MongoShellTab extends TabsBase {
|
|||
);
|
||||
}
|
||||
|
||||
//eslint-disable-next-line
|
||||
private handleLogMessage(event: MessageEvent, shellIframe: HTMLIFrameElement) {
|
||||
if (!("logType" in event.data.data) || typeof event.data.data["logType"] !== "string") {
|
||||
return;
|
||||
|
@ -144,6 +179,7 @@ export default class MongoShellTab extends TabsBase {
|
|||
TelemetryProcessor.trace(Action.MongoShell, ActionModifiers.Mark, dataToLog);
|
||||
break;
|
||||
case LogType.StartTrace:
|
||||
//eslint-disable-next-line
|
||||
const telemetryTraceId: number = TelemetryProcessor.traceStart(Action.MongoShell, dataToLog);
|
||||
this._logTraces.set(shellTraceId, telemetryTraceId);
|
||||
break;
|
||||
|
@ -168,6 +204,7 @@ export default class MongoShellTab extends TabsBase {
|
|||
}
|
||||
}
|
||||
|
||||
//eslint-disable-next-line
|
||||
private handleNotificationMessage(event: MessageEvent, shellIframe: HTMLIFrameElement) {
|
||||
if (!("logType" in event.data.data) || typeof event.data.data["logType"] !== "string") {
|
||||
return;
|
||||
|
@ -188,20 +225,19 @@ export default class MongoShellTab extends TabsBase {
|
|||
return logConsoleProgress(dataToLog);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MessageType {
|
||||
static IframeReady: string = "iframeready";
|
||||
static Notification: string = "notification";
|
||||
static Log: string = "log";
|
||||
render(): JSX.Element {
|
||||
return (
|
||||
<iframe
|
||||
name="explorer"
|
||||
className="iframe"
|
||||
style={{ width: "100%", height: "100%", border: 0, padding: 0, margin: 0, overflow: "hidden" }}
|
||||
src={this.state.url}
|
||||
id={this.props.tabsBaseInstance.tabId}
|
||||
onLoad={(event) => this.setContentFocus(event)}
|
||||
title="Mongo Shell"
|
||||
role="tabpanel"
|
||||
></iframe>
|
||||
);
|
||||
}
|
||||
|
||||
class LogType {
|
||||
static Information: string = "information";
|
||||
static Warning: string = "warning";
|
||||
static Verbose: string = "verbose";
|
||||
static InProgress: string = "inprogress";
|
||||
static StartTrace: string = "start";
|
||||
static SuccessTrace: string = "success";
|
||||
static FailureTrace: string = "failure";
|
||||
}
|
|
@ -29,7 +29,7 @@ import DocumentsTab from "../Tabs/DocumentsTab";
|
|||
import GraphTab from "../Tabs/GraphTab";
|
||||
import MongoDocumentsTab from "../Tabs/MongoDocumentsTab";
|
||||
import { NewMongoQueryTab } from "../Tabs/MongoQueryTab/MongoQueryTab";
|
||||
import MongoShellTab from "../Tabs/MongoShellTab";
|
||||
import { NewMongoShellTab } from "../Tabs/MongoShellTab/MongoShellTab";
|
||||
import { NewQueryTab } from "../Tabs/QueryTab/QueryTab";
|
||||
import QueryTablesTab from "../Tabs/QueryTablesTab";
|
||||
import { CollectionSettingsTabV2 } from "../Tabs/SettingsTabV2";
|
||||
|
@ -703,14 +703,15 @@ export default class Collection implements ViewModels.Collection {
|
|||
public onNewMongoShellClick() {
|
||||
const mongoShellTabs = this.container.tabsManager.getTabs(
|
||||
ViewModels.CollectionTabKind.MongoShell
|
||||
) as MongoShellTab[];
|
||||
) as NewMongoShellTab[];
|
||||
|
||||
let index = 1;
|
||||
if (mongoShellTabs.length > 0) {
|
||||
index = mongoShellTabs[mongoShellTabs.length - 1].index + 1;
|
||||
}
|
||||
|
||||
const mongoShellTab: MongoShellTab = new MongoShellTab({
|
||||
const mongoShellTab: NewMongoShellTab = new NewMongoShellTab(
|
||||
{
|
||||
tabKind: ViewModels.CollectionTabKind.MongoShell,
|
||||
title: "Shell " + index,
|
||||
tabPath: "",
|
||||
|
@ -718,7 +719,11 @@ export default class Collection implements ViewModels.Collection {
|
|||
node: this,
|
||||
hashLocation: `${Constants.HashRoutePrefixes.collectionsWithIds(this.databaseId, this.id())}/mongoShell`,
|
||||
index: index,
|
||||
});
|
||||
},
|
||||
{
|
||||
container: this.container,
|
||||
}
|
||||
);
|
||||
|
||||
this.container.tabsManager.activateNewTab(mongoShellTab);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue