mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2024-11-29 17:06:58 +00:00
tinker with an "Execute Query" action in Monaco
This commit is contained in:
parent
44d886b4a0
commit
2598760a11
@ -1,6 +1,6 @@
|
|||||||
import { Spinner, SpinnerSize } from "@fluentui/react";
|
import { Spinner, SpinnerSize } from "@fluentui/react";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { loadMonaco, monaco } from "../../LazyMonaco";
|
import { MonacoNamespace, loadMonaco, monaco } from "../../LazyMonaco";
|
||||||
// import "./EditorReact.less";
|
// import "./EditorReact.less";
|
||||||
|
|
||||||
interface EditorReactStates {
|
interface EditorReactStates {
|
||||||
@ -21,6 +21,7 @@ export interface EditorReactProps {
|
|||||||
minimap?: monaco.editor.IEditorOptions["minimap"];
|
minimap?: monaco.editor.IEditorOptions["minimap"];
|
||||||
scrollBeyondLastLine?: monaco.editor.IEditorOptions["scrollBeyondLastLine"];
|
scrollBeyondLastLine?: monaco.editor.IEditorOptions["scrollBeyondLastLine"];
|
||||||
monacoContainerStyles?: React.CSSProperties;
|
monacoContainerStyles?: React.CSSProperties;
|
||||||
|
configureEditor?: (monaco: MonacoNamespace, editor: monaco.editor.IStandaloneCodeEditor) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EditorReact extends React.Component<EditorReactProps, EditorReactStates> {
|
export class EditorReact extends React.Component<EditorReactProps, EditorReactStates> {
|
||||||
@ -69,7 +70,7 @@ export class EditorReact extends React.Component<EditorReactProps, EditorReactSt
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected configureEditor(editor: monaco.editor.IStandaloneCodeEditor) {
|
protected configureEditor(monaco: MonacoNamespace, editor: monaco.editor.IStandaloneCodeEditor) {
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
const queryEditorModel = this.editor.getModel();
|
const queryEditorModel = this.editor.getModel();
|
||||||
if (!this.props.isReadOnly && this.props.onContentChanged) {
|
if (!this.props.isReadOnly && this.props.onContentChanged) {
|
||||||
@ -87,12 +88,16 @@ export class EditorReact extends React.Component<EditorReactProps, EditorReactSt
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.props.configureEditor) {
|
||||||
|
this.props.configureEditor(monaco, this.editor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the monaco editor and attach to DOM
|
* Create the monaco editor and attach to DOM
|
||||||
*/
|
*/
|
||||||
private async createEditor(createCallback: (e: monaco.editor.IStandaloneCodeEditor) => void) {
|
private async createEditor(createCallback: (monaco: MonacoNamespace, e: monaco.editor.IStandaloneCodeEditor) => void) {
|
||||||
const options: monaco.editor.IStandaloneEditorConstructionOptions = {
|
const options: monaco.editor.IStandaloneEditorConstructionOptions = {
|
||||||
language: this.props.language,
|
language: this.props.language,
|
||||||
value: this.props.content,
|
value: this.props.content,
|
||||||
@ -111,7 +116,7 @@ export class EditorReact extends React.Component<EditorReactProps, EditorReactSt
|
|||||||
|
|
||||||
this.rootNode.innerHTML = "";
|
this.rootNode.innerHTML = "";
|
||||||
const monaco = await loadMonaco();
|
const monaco = await loadMonaco();
|
||||||
createCallback(monaco?.editor?.create(this.rootNode, options));
|
createCallback(monaco, monaco?.editor?.create(this.rootNode, options));
|
||||||
|
|
||||||
if (this.rootNode.innerHTML) {
|
if (this.rootNode.innerHTML) {
|
||||||
this.setState({
|
this.setState({
|
||||||
|
37
src/Explorer/Controls/Editor/QueryEditor.tsx
Normal file
37
src/Explorer/Controls/Editor/QueryEditor.tsx
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { EditorReact } from "Explorer/Controls/Editor/EditorReact";
|
||||||
|
import { MonacoNamespace, monaco } from "Explorer/LazyMonaco";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export type QueryEditorProps = {
|
||||||
|
content: string
|
||||||
|
onContentChanged: (newContent: string) => void;
|
||||||
|
onContentSelected: (selectedContent: string) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback that will run when the "Execute Query" command is invoked.
|
||||||
|
*/
|
||||||
|
onExecuteQuery: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const QueryEditor: React.FunctionComponent<QueryEditorProps> = (props) => {
|
||||||
|
const configureEditor = (monaco: MonacoNamespace, editor: monaco.editor.IStandaloneCodeEditor) => {
|
||||||
|
editor.addAction({
|
||||||
|
id: "execute-query",
|
||||||
|
label: "Execute Query",
|
||||||
|
keybindings: [monaco.KeyMod.Shift | monaco.KeyCode.Enter],
|
||||||
|
run: props.onExecuteQuery,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return <EditorReact
|
||||||
|
language={"sql"}
|
||||||
|
content={props.content}
|
||||||
|
isReadOnly={false}
|
||||||
|
wordWrap={"on"}
|
||||||
|
ariaLabel={"Editing Query"}
|
||||||
|
lineNumbers={"on"}
|
||||||
|
onContentChanged={props.onContentChanged}
|
||||||
|
onContentSelected={props.onContentSelected}
|
||||||
|
configureEditor={configureEditor}
|
||||||
|
/>;
|
||||||
|
}
|
@ -3,3 +3,4 @@ export type { monaco };
|
|||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
export const loadMonaco = () => import(/* webpackChunkName: "lazy-monaco" */ "monaco-editor/esm/vs/editor/editor.api");
|
export const loadMonaco = () => import(/* webpackChunkName: "lazy-monaco" */ "monaco-editor/esm/vs/editor/editor.api");
|
||||||
|
export type MonacoNamespace = Awaited<ReturnType<typeof loadMonaco>>;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import { Stack } from "@fluentui/react";
|
import { Stack } from "@fluentui/react";
|
||||||
import { QueryCopilotSampleContainerId, QueryCopilotSampleDatabaseId } from "Common/Constants";
|
import { QueryCopilotSampleContainerId, QueryCopilotSampleDatabaseId } from "Common/Constants";
|
||||||
import { CommandButtonComponentProps } from "Explorer/Controls/CommandButton/CommandButtonComponent";
|
import { CommandButtonComponentProps } from "Explorer/Controls/CommandButton/CommandButtonComponent";
|
||||||
import { EditorReact } from "Explorer/Controls/Editor/EditorReact";
|
import { QueryEditor } from "Explorer/Controls/Editor/QueryEditor";
|
||||||
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
|
||||||
import { SaveQueryPane } from "Explorer/Panes/SaveQueryPane/SaveQueryPane";
|
import { SaveQueryPane } from "Explorer/Panes/SaveQueryPane/SaveQueryPane";
|
||||||
import { QueryCopilotPromptbar } from "Explorer/QueryCopilot/QueryCopilotPromptbar";
|
import { QueryCopilotPromptbar } from "Explorer/QueryCopilot/QueryCopilotPromptbar";
|
||||||
@ -104,15 +104,11 @@ export const QueryCopilotTab: React.FC<QueryCopilotProps> = ({ explorer }: Query
|
|||||||
)}
|
)}
|
||||||
<Stack className="tabPaneContentContainer">
|
<Stack className="tabPaneContentContainer">
|
||||||
<SplitterLayout percentage={true} vertical={true} primaryIndex={0} primaryMinSize={30} secondaryMinSize={70}>
|
<SplitterLayout percentage={true} vertical={true} primaryIndex={0} primaryMinSize={30} secondaryMinSize={70}>
|
||||||
<EditorReact
|
<QueryEditor
|
||||||
language={"sql"}
|
|
||||||
content={query}
|
content={query}
|
||||||
isReadOnly={false}
|
|
||||||
wordWrap={"on"}
|
|
||||||
ariaLabel={"Editing Query"}
|
|
||||||
lineNumbers={"on"}
|
|
||||||
onContentChanged={(newQuery: string) => setQuery(newQuery)}
|
onContentChanged={(newQuery: string) => setQuery(newQuery)}
|
||||||
onContentSelected={(selectedQuery: string) => setSelectedQuery(selectedQuery)}
|
onContentSelected={(selectedQuery: string) => setSelectedQuery(selectedQuery)}
|
||||||
|
onExecuteQuery={() => OnExecuteQueryClick(useQueryCopilot as Partial<QueryCopilotState>)}
|
||||||
/>
|
/>
|
||||||
<QueryCopilotResults />
|
<QueryCopilotResults />
|
||||||
</SplitterLayout>
|
</SplitterLayout>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
import { FeedOptions, QueryOperationOptions } from "@azure/cosmos";
|
import { FeedOptions, QueryOperationOptions } from "@azure/cosmos";
|
||||||
import { Platform, configContext } from "ConfigContext";
|
import { Platform, configContext } from "ConfigContext";
|
||||||
import { useDialog } from "Explorer/Controls/Dialog";
|
import { useDialog } from "Explorer/Controls/Dialog";
|
||||||
|
import { QueryEditor } from "Explorer/Controls/Editor/QueryEditor";
|
||||||
import { QueryCopilotFeedbackModal } from "Explorer/QueryCopilot/Modal/QueryCopilotFeedbackModal";
|
import { QueryCopilotFeedbackModal } from "Explorer/QueryCopilot/Modal/QueryCopilotFeedbackModal";
|
||||||
import { useCopilotStore } from "Explorer/QueryCopilot/QueryCopilotContext";
|
import { useCopilotStore } from "Explorer/QueryCopilot/QueryCopilotContext";
|
||||||
import { QueryCopilotPromptbar } from "Explorer/QueryCopilot/QueryCopilotPromptbar";
|
import { QueryCopilotPromptbar } from "Explorer/QueryCopilot/QueryCopilotPromptbar";
|
||||||
@ -39,7 +40,6 @@ import { userContext } from "../../../UserContext";
|
|||||||
import * as QueryUtils from "../../../Utils/QueryUtils";
|
import * as QueryUtils from "../../../Utils/QueryUtils";
|
||||||
import { useSidePanel } from "../../../hooks/useSidePanel";
|
import { useSidePanel } from "../../../hooks/useSidePanel";
|
||||||
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||||
import { EditorReact } from "../../Controls/Editor/EditorReact";
|
|
||||||
import Explorer from "../../Explorer";
|
import Explorer from "../../Explorer";
|
||||||
import { useCommandBar } from "../../Menus/CommandBar/CommandBarComponentAdapter";
|
import { useCommandBar } from "../../Menus/CommandBar/CommandBarComponentAdapter";
|
||||||
import { BrowseQueriesPane } from "../../Panes/BrowseQueriesPane/BrowseQueriesPane";
|
import { BrowseQueriesPane } from "../../Panes/BrowseQueriesPane/BrowseQueriesPane";
|
||||||
@ -599,15 +599,11 @@ export default class QueryTabComponent extends React.Component<IQueryTabComponen
|
|||||||
<SplitterLayout vertical={true} primaryIndex={0} primaryMinSize={100} secondaryMinSize={200}>
|
<SplitterLayout vertical={true} primaryIndex={0} primaryMinSize={100} secondaryMinSize={200}>
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<div className="queryEditor" style={{ height: "100%" }}>
|
<div className="queryEditor" style={{ height: "100%" }}>
|
||||||
<EditorReact
|
<QueryEditor
|
||||||
language={"sql"}
|
|
||||||
content={this.setEditorContent()}
|
content={this.setEditorContent()}
|
||||||
isReadOnly={false}
|
|
||||||
wordWrap={"on"}
|
|
||||||
ariaLabel={"Editing Query"}
|
|
||||||
lineNumbers={"on"}
|
|
||||||
onContentChanged={(newContent: string) => this.onChangeContent(newContent)}
|
onContentChanged={(newContent: string) => this.onChangeContent(newContent)}
|
||||||
onContentSelected={(selectedContent: string) => this.onSelectedContent(selectedContent)}
|
onContentSelected={(selectedContent: string) => this.onSelectedContent(selectedContent)}
|
||||||
|
onExecuteQuery={() => this.onExecuteQueryClick()}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
Loading…
Reference in New Issue
Block a user