mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-19 17:01:13 +00:00
Migrate Query Tab to React (#852)
Co-authored-by: Steve Faulkner <southpolesteve@gmail.com>
This commit is contained in:
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
Reference in New Issue
Block a user