mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2024-11-25 15:06:55 +00:00
Migrate Query Tab to React (#852)
Co-authored-by: Steve Faulkner <southpolesteve@gmail.com>
This commit is contained in:
parent
baa3252ba8
commit
999fad3bad
38
package-lock.json
generated
38
package-lock.json
generated
@ -5650,6 +5650,15 @@
|
|||||||
"redux": "^4.0.0"
|
"redux": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/react-splitter-layout": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-splitter-layout/-/react-splitter-layout-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-NsKq32LdG11G/Uj+xo2QmC9S8YSe8JRtxkBhsBE7ODFs0zcnzNEqFAQirP0H7rPe2WFGiu+d/44xbHsew7QAJw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/react-table": {
|
"@types/react-table": {
|
||||||
"version": "6.8.7",
|
"version": "6.8.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-6.8.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-6.8.7.tgz",
|
||||||
@ -17690,12 +17699,6 @@
|
|||||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.21",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"supports-color": {
|
"supports-color": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
@ -18499,9 +18502,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "4.17.20",
|
"version": "4.17.21",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
},
|
},
|
||||||
"lodash-es": {
|
"lodash-es": {
|
||||||
"version": "4.17.20",
|
"version": "4.17.20",
|
||||||
@ -18728,9 +18731,9 @@
|
|||||||
"integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg=="
|
"integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg=="
|
||||||
},
|
},
|
||||||
"marked": {
|
"marked": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/marked/-/marked-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/marked/-/marked-2.0.6.tgz",
|
||||||
"integrity": "sha512-5otztIIcJfPc2qGTN8cVtOJEjNJZ0jwa46INMagrYfk0EvqtRuEHLsEe0LrFS0/q+ZRKT0+kXK7P2T1AN5lWRA==",
|
"integrity": "sha512-S2mYj0FzTQa0dLddssqwRVW4EOJOVJ355Xm2Vcbm+LU7GQRGWvwbO5K87OaPSOux2AwTSgtPPaXmc8sDPrhn2A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"martinez-polygon-clipping": {
|
"martinez-polygon-clipping": {
|
||||||
@ -21635,6 +21638,11 @@
|
|||||||
"react-is": "^16.9.0"
|
"react-is": "^16.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-splitter-layout": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-splitter-layout/-/react-splitter-layout-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-SLqOjBOxRuizWUa83w6q5/u9cDWa9/yj9Iko9V9JFN8x+cqIXiDlUFWSx+icz3IIgvsN/oRIw3za5/32RjIwrA=="
|
||||||
|
},
|
||||||
"react-syntax-highlighter": {
|
"react-syntax-highlighter": {
|
||||||
"version": "12.2.1",
|
"version": "12.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-12.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-12.2.1.tgz",
|
||||||
@ -24367,12 +24375,6 @@
|
|||||||
"universalify": "^2.0.0"
|
"universalify": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.21",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"universalify": {
|
"universalify": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||||
|
@ -89,6 +89,7 @@
|
|||||||
"react-i18next": "11.8.5",
|
"react-i18next": "11.8.5",
|
||||||
"react-notification-system": "0.2.17",
|
"react-notification-system": "0.2.17",
|
||||||
"react-redux": "7.1.3",
|
"react-redux": "7.1.3",
|
||||||
|
"react-splitter-layout": "4.0.0",
|
||||||
"redux": "4.0.4",
|
"redux": "4.0.4",
|
||||||
"reflect-metadata": "0.1.13",
|
"reflect-metadata": "0.1.13",
|
||||||
"rx-jupyter": "5.5.12",
|
"rx-jupyter": "5.5.12",
|
||||||
@ -123,6 +124,7 @@
|
|||||||
"@types/react-dom": "17.0.3",
|
"@types/react-dom": "17.0.3",
|
||||||
"@types/react-notification-system": "0.2.39",
|
"@types/react-notification-system": "0.2.39",
|
||||||
"@types/react-redux": "7.1.7",
|
"@types/react-redux": "7.1.7",
|
||||||
|
"@types/react-splitter-layout": "3.0.1",
|
||||||
"@types/sanitize-html": "1.27.2",
|
"@types/sanitize-html": "1.27.2",
|
||||||
"@types/sinon": "2.3.3",
|
"@types/sinon": "2.3.3",
|
||||||
"@types/styled-components": "5.1.1",
|
"@types/styled-components": "5.1.1",
|
||||||
|
@ -12,7 +12,7 @@ import {
|
|||||||
QueriesGridComponentProps,
|
QueriesGridComponentProps,
|
||||||
} from "../../Controls/QueriesGridReactComponent/QueriesGridComponent";
|
} from "../../Controls/QueriesGridReactComponent/QueriesGridComponent";
|
||||||
import Explorer from "../../Explorer";
|
import Explorer from "../../Explorer";
|
||||||
import QueryTab from "../../Tabs/QueryTab";
|
import { NewQueryTab } from "../../Tabs/QueryTab/QueryTab";
|
||||||
|
|
||||||
interface BrowseQueriesPaneProps {
|
interface BrowseQueriesPaneProps {
|
||||||
explorer: Explorer;
|
explorer: Explorer;
|
||||||
@ -31,13 +31,13 @@ export const BrowseQueriesPane: FunctionComponent<BrowseQueriesPaneProps> = ({
|
|||||||
} else if (userContext.apiType === "Mongo") {
|
} else if (userContext.apiType === "Mongo") {
|
||||||
selectedCollection.onNewMongoQueryClick(selectedCollection, undefined);
|
selectedCollection.onNewMongoQueryClick(selectedCollection, undefined);
|
||||||
} else {
|
} else {
|
||||||
selectedCollection.onNewQueryClick(selectedCollection, undefined);
|
selectedCollection.onNewQueryClick(selectedCollection, undefined, savedQuery.query);
|
||||||
}
|
}
|
||||||
const queryTab = explorer.tabsManager.activeTab() as QueryTab;
|
|
||||||
|
const queryTab = explorer && (explorer.tabsManager.activeTab() as NewQueryTab);
|
||||||
queryTab.tabTitle(savedQuery.queryName);
|
queryTab.tabTitle(savedQuery.queryName);
|
||||||
queryTab.tabPath(`${selectedCollection.databaseId}>${selectedCollection.id()}>${savedQuery.queryName}`);
|
queryTab.tabPath(`${selectedCollection.databaseId}>${selectedCollection.id()}>${savedQuery.queryName}`);
|
||||||
queryTab.initialEditorContent(savedQuery.query);
|
|
||||||
queryTab.sqlQueryEditorContent(savedQuery.query);
|
|
||||||
trace(Action.LoadSavedQuery, ActionModifiers.Mark, {
|
trace(Action.LoadSavedQuery, ActionModifiers.Mark, {
|
||||||
dataExplorerArea: Areas.ContextualPane,
|
dataExplorerArea: Areas.ContextualPane,
|
||||||
queryName: savedQuery.queryName,
|
queryName: savedQuery.queryName,
|
||||||
|
@ -8,7 +8,6 @@ import { useSidePanel } from "../../../hooks/useSidePanel";
|
|||||||
import { userContext } from "../../../UserContext";
|
import { userContext } from "../../../UserContext";
|
||||||
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../../Utils/NotificationConsoleUtils";
|
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../../Utils/NotificationConsoleUtils";
|
||||||
import Explorer from "../../Explorer";
|
import Explorer from "../../Explorer";
|
||||||
import QueryTab from "../../Tabs/QueryTab";
|
|
||||||
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
||||||
|
|
||||||
interface LoadQueryPaneProps {
|
interface LoadQueryPaneProps {
|
||||||
@ -60,20 +59,19 @@ export const LoadQueryPane: FunctionComponent<LoadQueryPaneProps> = ({ explorer
|
|||||||
|
|
||||||
const loadQueryFromFile = async (file: File): Promise<void> => {
|
const loadQueryFromFile = async (file: File): Promise<void> => {
|
||||||
const selectedCollection: Collection = explorer?.findSelectedCollection();
|
const selectedCollection: Collection = explorer?.findSelectedCollection();
|
||||||
|
const reader = new FileReader();
|
||||||
|
let fileData: string;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
reader.onload = (evt: any): void => {
|
||||||
|
fileData = evt.target.result;
|
||||||
|
|
||||||
if (!selectedCollection) {
|
if (!selectedCollection) {
|
||||||
logError("No collection was selected", "LoadQueryPane.loadQueryFromFile");
|
logError("No collection was selected", "LoadQueryPane.loadQueryFromFile");
|
||||||
} else if (userContext.apiType === "Mongo") {
|
} else if (userContext.apiType === "Mongo") {
|
||||||
selectedCollection.onNewMongoQueryClick(selectedCollection, undefined);
|
selectedCollection.onNewMongoQueryClick(selectedCollection, undefined);
|
||||||
} else {
|
} else {
|
||||||
selectedCollection.onNewQueryClick(selectedCollection, undefined);
|
selectedCollection.onNewQueryClick(selectedCollection, undefined, fileData);
|
||||||
}
|
}
|
||||||
const reader = new FileReader();
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
reader.onload = (evt: any): void => {
|
|
||||||
const fileData: string = evt.target.result;
|
|
||||||
const queryTab = explorer.tabsManager.activeTab() as QueryTab;
|
|
||||||
queryTab.initialEditorContent(fileData);
|
|
||||||
queryTab.sqlQueryEditorContent(fileData);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
reader.onerror = (): void => {
|
reader.onerror = (): void => {
|
||||||
|
@ -9,7 +9,7 @@ import { Action } from "../../../Shared/Telemetry/TelemetryConstants";
|
|||||||
import { traceFailure, traceStart, traceSuccess } from "../../../Shared/Telemetry/TelemetryProcessor";
|
import { traceFailure, traceStart, traceSuccess } from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import { logConsoleError } from "../../../Utils/NotificationConsoleUtils";
|
import { logConsoleError } from "../../../Utils/NotificationConsoleUtils";
|
||||||
import Explorer from "../../Explorer";
|
import Explorer from "../../Explorer";
|
||||||
import QueryTab from "../../Tabs/QueryTab";
|
import { NewQueryTab } from "../../Tabs/QueryTab/QueryTab";
|
||||||
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
||||||
|
|
||||||
interface SaveQueryPaneProps {
|
interface SaveQueryPaneProps {
|
||||||
@ -33,8 +33,9 @@ export const SaveQueryPane: FunctionComponent<SaveQueryPaneProps> = ({ explorer
|
|||||||
logConsoleError("Failed to save query: account not setup to save queries");
|
logConsoleError("Failed to save query: account not setup to save queries");
|
||||||
}
|
}
|
||||||
|
|
||||||
const queryTab = explorer && (explorer.tabsManager.activeTab() as QueryTab);
|
const queryTab = explorer && (explorer.tabsManager.activeTab() as NewQueryTab);
|
||||||
const query: string = queryTab && queryTab.sqlQueryEditorContent();
|
const query: string = queryTab && queryTab.iTabAccessor.onSaveClickEvent();
|
||||||
|
|
||||||
if (!queryName || queryName.length === 0) {
|
if (!queryName || queryName.length === 0) {
|
||||||
setFormError("No query name specified");
|
setFormError("No query name specified");
|
||||||
logConsoleError("Could not save query -- No query name specified. Please specify a query name.");
|
logConsoleError("Could not save query -- No query name specified. Please specify a query name.");
|
||||||
|
@ -281,7 +281,7 @@ export default class MongoDocumentsTab extends DocumentsTab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Renders a Javascript object to be displayed inside Monaco Editor */
|
/** Renders a Javascript object to be displayed inside Monaco Editor */
|
||||||
protected renderObjectForEditor(value: any, replacer: any, space: string | number): string {
|
public renderObjectForEditor(value: any, replacer: any, space: string | number): string {
|
||||||
return MongoUtility.tojson(value, null, false);
|
return MongoUtility.tojson(value, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
|
||||||
import Q from "q";
|
import Q from "q";
|
||||||
import MongoUtility from "../../Common/MongoUtility";
|
|
||||||
import QueryTab from "./QueryTab";
|
|
||||||
import * as HeadersUtility from "../../Common/HeadersUtility";
|
import * as HeadersUtility from "../../Common/HeadersUtility";
|
||||||
import { queryIterator } from "../../Common/MongoProxyClient";
|
|
||||||
import { MinimalQueryIterator } from "../../Common/IteratorUtilities";
|
import { MinimalQueryIterator } from "../../Common/IteratorUtilities";
|
||||||
|
import { queryIterator } from "../../Common/MongoProxyClient";
|
||||||
|
import MongoUtility from "../../Common/MongoUtility";
|
||||||
|
import * as ViewModels from "../../Contracts/ViewModels";
|
||||||
|
import QueryTab from "./QueryTab";
|
||||||
|
|
||||||
export default class MongoQueryTab extends QueryTab {
|
export default class MongoQueryTab extends QueryTab {
|
||||||
public collection: ViewModels.Collection;
|
public collection: ViewModels.Collection;
|
||||||
@ -16,7 +16,7 @@ export default class MongoQueryTab extends QueryTab {
|
|||||||
this.monacoSettings = new ViewModels.MonacoEditorSettings("plaintext", false);
|
this.monacoSettings = new ViewModels.MonacoEditorSettings("plaintext", false);
|
||||||
}
|
}
|
||||||
/** Renders a Javascript object to be displayed inside Monaco Editor */
|
/** Renders a Javascript object to be displayed inside Monaco Editor */
|
||||||
protected renderObjectForEditor(value: any, replacer: any, space: string | number): string {
|
public renderObjectForEditor(value: any, replacer: any, space: string | number): string {
|
||||||
return MongoUtility.tojson(value, null, false);
|
return MongoUtility.tojson(value, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
54
src/Explorer/Tabs/QueryTab/QueryTab.tsx
Normal file
54
src/Explorer/Tabs/QueryTab/QueryTab.tsx
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import React from "react";
|
||||||
|
import * as DataModels from "../../../Contracts/DataModels";
|
||||||
|
import type { QueryTabOptions } from "../../../Contracts/ViewModels";
|
||||||
|
import Explorer from "../../Explorer";
|
||||||
|
import { IQueryTabComponentProps, ITabAccessor } from "../../Tabs/QueryTab/QueryTabComponent";
|
||||||
|
import TabsBase from "../TabsBase";
|
||||||
|
import QueryTabComponent from "./QueryTabComponent";
|
||||||
|
|
||||||
|
export interface IQueryTabProps {
|
||||||
|
container: Explorer;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class NewQueryTab extends TabsBase {
|
||||||
|
public queryText: string;
|
||||||
|
public currentQuery: string;
|
||||||
|
public partitionKey: DataModels.PartitionKey;
|
||||||
|
public iQueryTabComponentProps: IQueryTabComponentProps;
|
||||||
|
public iTabAccessor: ITabAccessor;
|
||||||
|
|
||||||
|
constructor(options: QueryTabOptions, private props: IQueryTabProps) {
|
||||||
|
super(options);
|
||||||
|
this.partitionKey = options.partitionKey;
|
||||||
|
this.iQueryTabComponentProps = {
|
||||||
|
collection: this.collection,
|
||||||
|
isExecutionError: this.isExecutionError(),
|
||||||
|
tabId: this.tabId,
|
||||||
|
tabsBaseInstance: this,
|
||||||
|
queryText: options.queryText,
|
||||||
|
partitionKey: this.partitionKey,
|
||||||
|
container: this.props.container,
|
||||||
|
onTabAccessor: (instance: ITabAccessor): void => {
|
||||||
|
this.iTabAccessor = instance;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): JSX.Element {
|
||||||
|
return <QueryTabComponent {...this.iQueryTabComponentProps} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
public onTabClick(): void {
|
||||||
|
this.manager?.activateTab(this);
|
||||||
|
this.iTabAccessor.onTabClickEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public onCloseTabButtonClick(): void {
|
||||||
|
this.manager?.closeTab(this);
|
||||||
|
this.iTabAccessor.onCloseClickEvent(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getContainer(): Explorer {
|
||||||
|
return this.props.container;
|
||||||
|
}
|
||||||
|
}
|
285
src/Explorer/Tabs/QueryTab/QueryTabComponent.less
Normal file
285
src/Explorer/Tabs/QueryTab/QueryTabComponent.less
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
@import "../../../../less/Common/Constants.less";
|
||||||
|
@import "../../../../less/Common/TabCommon.less";
|
||||||
|
|
||||||
|
@MongoQueryEditorHeight: 50px;
|
||||||
|
@ResultsTextFontWeight: 600;
|
||||||
|
@ToggleHeight: 30px;
|
||||||
|
@ToggleWidth: 250px;
|
||||||
|
@QueryEngineExeInfo: 305px;
|
||||||
|
|
||||||
|
.tab-pane {
|
||||||
|
.tabContentContainer();
|
||||||
|
|
||||||
|
.tabPaneContentContainer {
|
||||||
|
position: relative;
|
||||||
|
.tabContentContainer();
|
||||||
|
|
||||||
|
.mongoQueryHelper {
|
||||||
|
margin: @DefaultSpace 0px 0px 44px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.splitter-layout {
|
||||||
|
.layout-pane-primary {
|
||||||
|
overflow: hidden !important;
|
||||||
|
.queryEditor {
|
||||||
|
.flex-display();
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: @SmallSpace;
|
||||||
|
|
||||||
|
.jsonEditor {
|
||||||
|
border: none;
|
||||||
|
margin-top: @SmallSpace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.queryEditor.mongoQueryEditor {
|
||||||
|
margin-top: 32px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.queryEditorHorizontalSplitter {
|
||||||
|
margin: auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.queryErrorsHeaderContainer {
|
||||||
|
padding: 24px @LargeSpace 0px @MediumSpace;
|
||||||
|
|
||||||
|
.queryErrors {
|
||||||
|
font-size: @mediumFontSize;
|
||||||
|
list-style-type: none;
|
||||||
|
color: @BaseDark;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-left: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.queryResultErrorContentContainer {
|
||||||
|
.flex-display();
|
||||||
|
.flex-direction();
|
||||||
|
font-size: @DefaultFontSize;
|
||||||
|
padding: @DefaultSpace;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.queryEditorWatermark {
|
||||||
|
text-align: center;
|
||||||
|
margin: auto;
|
||||||
|
height: 25vh; // this is to align the water mark in center of the layout.
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: @LargeSpace;
|
||||||
|
color: @BaseHigh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.queryEditorWatermarkText {
|
||||||
|
color: @BaseHigh;
|
||||||
|
font-size: @DefaultFontSize;
|
||||||
|
font-family: @DataExplorerFont;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.queryResultsErrorsContent {
|
||||||
|
height: 100%;
|
||||||
|
margin-left: @MediumSpace;
|
||||||
|
.flex-display();
|
||||||
|
.flex-direction();
|
||||||
|
|
||||||
|
div[role="tabpanel"] {
|
||||||
|
height: 100%;
|
||||||
|
div:nth-child(1) {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-metadata {
|
||||||
|
padding: @LargeSpace @SmallSpace @MediumSpace @MediumSpace;
|
||||||
|
height: auto !important;
|
||||||
|
.queryResultDivider {
|
||||||
|
margin-left: @SmallSpace;
|
||||||
|
margin-right: @SmallSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.queryResultNextEnable {
|
||||||
|
color: @AccentMediumHigh;
|
||||||
|
font-size: @mediumFontSize;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: @ImgHeight;
|
||||||
|
width: @ImgWidth;
|
||||||
|
margin-left: @SmallSpace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.queryResultNextDisable {
|
||||||
|
color: @BaseMediumHigh;
|
||||||
|
opacity: 0.5;
|
||||||
|
font-size: @mediumFontSize;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: @ImgHeight;
|
||||||
|
width: @ImgWidth;
|
||||||
|
margin-left: @SmallSpace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-pane.active {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.errorContent {
|
||||||
|
.flex-display();
|
||||||
|
width: 60%;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: @mediumFontSize;
|
||||||
|
padding: 0px @MediumSpace 0px @MediumSpace;
|
||||||
|
|
||||||
|
.errorMessage {
|
||||||
|
padding: @SmallSpace;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.errorDetailsLink {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: @SmallSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.queryMetricsSummaryContainer {
|
||||||
|
.flex-display();
|
||||||
|
.flex-direction();
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.queryMetricsSummary {
|
||||||
|
margin: @LargeSpace @LargeSpace 0px @DefaultSpace;
|
||||||
|
table-layout: fixed;
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
|
||||||
|
caption {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.queryMetricsSummaryHead {
|
||||||
|
.flex-display();
|
||||||
|
}
|
||||||
|
|
||||||
|
.queryMetricsSummaryHeader.queryMetricsSummaryTuple {
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.queryMetricsSummaryBody {
|
||||||
|
.flex-display();
|
||||||
|
.flex-direction();
|
||||||
|
}
|
||||||
|
|
||||||
|
.queryMetricsSummaryTuple {
|
||||||
|
border-bottom: 1px solid @BaseMedium;
|
||||||
|
height: 32px;
|
||||||
|
font-size: 12px;
|
||||||
|
width: 100%;
|
||||||
|
.flex-display();
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
padding: @DefaultSpace;
|
||||||
|
|
||||||
|
&:nth-child(1) {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
flex: 0 0 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(3) {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
flex: 0 0 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.queryMetricInfoTooltip {
|
||||||
|
.infoTooltip();
|
||||||
|
|
||||||
|
&:hover .queryMetricTooltipText {
|
||||||
|
.tooltipVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus .queryMetricTooltipText {
|
||||||
|
.tooltipVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
.queryMetricTooltipText {
|
||||||
|
top: -50px;
|
||||||
|
width: auto;
|
||||||
|
white-space: nowrap;
|
||||||
|
left: 6px;
|
||||||
|
visibility: hidden;
|
||||||
|
background-color: @BaseHigh;
|
||||||
|
color: @BaseLight;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
padding: @MediumSpace;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
border-width: (2 * @MediumSpace) (2 * @MediumSpace) 0px 0px;
|
||||||
|
bottom: -14px;
|
||||||
|
.tooltipTextAfter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.queryEngineExeTimeInfo {
|
||||||
|
width: @QueryEngineExeInfo;
|
||||||
|
top: -85px;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.downloadMetricsLinkContainer {
|
||||||
|
margin: 24px 0px 50px @MediumSpace;
|
||||||
|
position: sticky;
|
||||||
|
#downloadMetricsLink {
|
||||||
|
color: @BaseHigh;
|
||||||
|
padding: @DefaultSpace;
|
||||||
|
font-size: @mediumFontSize;
|
||||||
|
border: @ButtonBorderWidth solid @BaseLight;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.hover();
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
border: @ButtonBorderWidth dashed @AccentMedium;
|
||||||
|
.active();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
json-editor {
|
||||||
|
.flex-display();
|
||||||
|
.flex-direction();
|
||||||
|
overflow: hidden;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
padding: @SmallSpace 0px @SmallSpace @MediumSpace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1090
src/Explorer/Tabs/QueryTab/QueryTabComponent.tsx
Normal file
1090
src/Explorer/Tabs/QueryTab/QueryTabComponent.tsx
Normal file
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,6 @@ import Explorer from "../Explorer";
|
|||||||
import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
||||||
import { WaitsForTemplateViewModel } from "../WaitsForTemplateViewModel";
|
import { WaitsForTemplateViewModel } from "../WaitsForTemplateViewModel";
|
||||||
import { TabsManager } from "./TabsManager";
|
import { TabsManager } from "./TabsManager";
|
||||||
|
|
||||||
// TODO: Use specific actions for logging telemetry data
|
// TODO: Use specific actions for logging telemetry data
|
||||||
export default class TabsBase extends WaitsForTemplateViewModel {
|
export default class TabsBase extends WaitsForTemplateViewModel {
|
||||||
private static id = 0;
|
private static id = 0;
|
||||||
@ -149,7 +148,7 @@ export default class TabsBase extends WaitsForTemplateViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Renders a Javascript object to be displayed inside Monaco Editor */
|
/** Renders a Javascript object to be displayed inside Monaco Editor */
|
||||||
protected renderObjectForEditor(value: any, replacer: any, space: string | number): string {
|
public renderObjectForEditor(value: any, replacer: any, space: string | number): string {
|
||||||
return JSON.stringify(value, replacer, space);
|
return JSON.stringify(value, replacer, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +163,7 @@ export default class TabsBase extends WaitsForTemplateViewModel {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updateNavbarWithTabsButtons = (): void => {
|
public updateNavbarWithTabsButtons = (): void => {
|
||||||
if (this.isActive()) {
|
if (this.isActive()) {
|
||||||
useCommandBar.getState().setContextButtons(this.getTabsButtons());
|
useCommandBar.getState().setContextButtons(this.getTabsButtons());
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ import GraphTab from "../Tabs/GraphTab";
|
|||||||
import MongoDocumentsTab from "../Tabs/MongoDocumentsTab";
|
import MongoDocumentsTab from "../Tabs/MongoDocumentsTab";
|
||||||
import MongoQueryTab from "../Tabs/MongoQueryTab";
|
import MongoQueryTab from "../Tabs/MongoQueryTab";
|
||||||
import MongoShellTab from "../Tabs/MongoShellTab";
|
import MongoShellTab from "../Tabs/MongoShellTab";
|
||||||
import QueryTab from "../Tabs/QueryTab";
|
import { NewQueryTab } from "../Tabs/QueryTab/QueryTab";
|
||||||
import QueryTablesTab from "../Tabs/QueryTablesTab";
|
import QueryTablesTab from "../Tabs/QueryTablesTab";
|
||||||
import { CollectionSettingsTabV2 } from "../Tabs/SettingsTabV2";
|
import { CollectionSettingsTabV2 } from "../Tabs/SettingsTabV2";
|
||||||
import ConflictId from "./ConflictId";
|
import ConflictId from "./ConflictId";
|
||||||
@ -617,7 +617,9 @@ export default class Collection implements ViewModels.Collection {
|
|||||||
tabTitle: title,
|
tabTitle: title,
|
||||||
});
|
});
|
||||||
|
|
||||||
const queryTab: QueryTab = new QueryTab({
|
this.container.tabsManager.activateNewTab(
|
||||||
|
new NewQueryTab(
|
||||||
|
{
|
||||||
tabKind: ViewModels.CollectionTabKind.Query,
|
tabKind: ViewModels.CollectionTabKind.Query,
|
||||||
title: title,
|
title: title,
|
||||||
tabPath: "",
|
tabPath: "",
|
||||||
@ -627,9 +629,10 @@ export default class Collection implements ViewModels.Collection {
|
|||||||
queryText: queryText,
|
queryText: queryText,
|
||||||
partitionKey: collection.partitionKey,
|
partitionKey: collection.partitionKey,
|
||||||
onLoadStartKey: startKey,
|
onLoadStartKey: startKey,
|
||||||
});
|
},
|
||||||
|
{ container: this.container }
|
||||||
this.container.tabsManager.activateNewTab(queryTab);
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onNewMongoQueryClick(source: any, event: MouseEvent, queryText?: string) {
|
public onNewMongoQueryClick(source: any, event: MouseEvent, queryText?: string) {
|
||||||
|
Loading…
Reference in New Issue
Block a user