mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-20 09:20:16 +00:00
Initial Move from Azure DevOps to GitHub
This commit is contained in:
63
src/Explorer/Controls/Editor/EditorComponent.ts
Normal file
63
src/Explorer/Controls/Editor/EditorComponent.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { JsonEditorParams, JsonEditorViewModel } from "../JsonEditor/JsonEditorComponent";
|
||||
import template from "./editor-component.html";
|
||||
import * as monaco from "monaco-editor";
|
||||
import { SqlCompletionItemProvider, ErrorMarkProvider } from "@azure/cosmos-language-service";
|
||||
|
||||
/**
|
||||
* Helper class for ko component registration
|
||||
*/
|
||||
export class EditorComponent {
|
||||
constructor() {
|
||||
return {
|
||||
viewModel: EditorViewModel,
|
||||
template
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for this component
|
||||
*/
|
||||
export interface EditorParams extends JsonEditorParams {
|
||||
contentType: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a generic editor component that builds on top of the pre-existing JsonEditorComponent.
|
||||
*/
|
||||
// TODO: Ideally, JsonEditorViewModel should extend EditorViewModel and not the other way around
|
||||
class EditorViewModel extends JsonEditorViewModel {
|
||||
public params: EditorParams;
|
||||
private static providerRegistered: string[] = [];
|
||||
|
||||
public constructor(params: EditorParams) {
|
||||
super(params);
|
||||
this.params = params;
|
||||
super.createEditor.bind(this);
|
||||
|
||||
/**
|
||||
* setTimeout is needed as creating the edtior manipulates the dom directly and expects
|
||||
* Knockout to have completed all of the initial bindings for the component
|
||||
*/
|
||||
this.params.content() != null &&
|
||||
setTimeout(() => {
|
||||
this.createEditor(this.params.content(), this.configureEditor.bind(this));
|
||||
});
|
||||
}
|
||||
|
||||
protected getEditorLanguage(): string {
|
||||
return this.params.contentType;
|
||||
}
|
||||
|
||||
protected registerCompletionItemProvider() {
|
||||
let sqlCompletionItemProvider = new SqlCompletionItemProvider();
|
||||
if (EditorViewModel.providerRegistered.indexOf("sql") < 0) {
|
||||
monaco.languages.registerCompletionItemProvider("sql", sqlCompletionItemProvider);
|
||||
EditorViewModel.providerRegistered.push("sql");
|
||||
}
|
||||
}
|
||||
|
||||
protected getErrorMarkers(input: string): Q.Promise<monaco.editor.IMarkerData[]> {
|
||||
return ErrorMarkProvider.getErrorMark(input);
|
||||
}
|
||||
}
|
||||
83
src/Explorer/Controls/Editor/EditorReact.tsx
Normal file
83
src/Explorer/Controls/Editor/EditorReact.tsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import * as React from "react";
|
||||
import * as monaco from "monaco-editor";
|
||||
|
||||
export interface EditorReactProps {
|
||||
language: string;
|
||||
content: string;
|
||||
isReadOnly: boolean;
|
||||
ariaLabel: string; // Sets what will be read to the user to define the control
|
||||
onContentSelected?: (selectedContent: string) => void; // Called when text is selected
|
||||
onContentChanged?: (newContent: string) => void; // Called when text is changed
|
||||
lineNumbers?: monaco.editor.IEditorOptions["lineNumbers"];
|
||||
theme?: string; // Monaco editor theme
|
||||
}
|
||||
|
||||
export class EditorReact extends React.Component<EditorReactProps> {
|
||||
private rootNode: HTMLElement;
|
||||
private editor: monaco.editor.IStandaloneCodeEditor;
|
||||
private selectionListener: monaco.IDisposable;
|
||||
|
||||
public constructor(props: EditorReactProps) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
public componentDidMount(): void {
|
||||
this.createEditor(this.configureEditor.bind(this));
|
||||
}
|
||||
|
||||
public shouldComponentUpdate(): boolean {
|
||||
// Prevents component re-rendering
|
||||
return false;
|
||||
}
|
||||
|
||||
public componentWillUnmount(): void {
|
||||
this.selectionListener && this.selectionListener.dispose();
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
return <div className="jsonEditor" ref={(elt: HTMLElement) => this.setRef(elt)} />;
|
||||
}
|
||||
|
||||
protected configureEditor(editor: monaco.editor.IStandaloneCodeEditor) {
|
||||
this.editor = editor;
|
||||
const queryEditorModel = this.editor.getModel();
|
||||
if (!this.props.isReadOnly && this.props.onContentChanged) {
|
||||
queryEditorModel.onDidChangeContent((e: monaco.editor.IModelContentChangedEvent) => {
|
||||
const queryEditorModel = this.editor.getModel();
|
||||
this.props.onContentChanged(queryEditorModel.getValue());
|
||||
});
|
||||
}
|
||||
|
||||
if (this.props.onContentSelected) {
|
||||
this.selectionListener = this.editor.onDidChangeCursorSelection(
|
||||
(event: monaco.editor.ICursorSelectionChangedEvent) => {
|
||||
const selectedContent: string = this.editor.getModel().getValueInRange(event.selection);
|
||||
this.props.onContentSelected(selectedContent);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the monaco editor and attach to DOM
|
||||
*/
|
||||
private createEditor(createCallback: (e: monaco.editor.IStandaloneCodeEditor) => void) {
|
||||
const options: monaco.editor.IEditorConstructionOptions = {
|
||||
value: this.props.content,
|
||||
language: this.props.language,
|
||||
readOnly: this.props.isReadOnly,
|
||||
lineNumbers: this.props.lineNumbers || "off",
|
||||
fontSize: 12,
|
||||
ariaLabel: this.props.ariaLabel,
|
||||
theme: this.props.theme,
|
||||
automaticLayout: true
|
||||
};
|
||||
|
||||
this.rootNode.innerHTML = "";
|
||||
createCallback(monaco.editor.create(this.rootNode, options));
|
||||
}
|
||||
|
||||
private setRef(element: HTMLElement): void {
|
||||
this.rootNode = element;
|
||||
}
|
||||
}
|
||||
1
src/Explorer/Controls/Editor/editor-component.html
Normal file
1
src/Explorer/Controls/Editor/editor-component.html
Normal file
@@ -0,0 +1 @@
|
||||
<div class="jsonEditor" data-bind="attr:{ id: getEditorId() }"></div>
|
||||
Reference in New Issue
Block a user