* fix #3061771 by correcting render order issues on undo * clarifying comment * fix lints * push an undo stop before executing edits * tidy up some unnecessary comments
This commit is contained in:
parent
f533eeb0fc
commit
db50f42832
|
@ -46,9 +46,21 @@ export class EditorReact extends React.Component<EditorReactProps, EditorReactSt
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentDidUpdate(previous: EditorReactProps) {
|
public componentDidUpdate() {
|
||||||
if (this.props.content !== previous.content) {
|
if (!this.editor) {
|
||||||
this.editor?.setValue(this.props.content);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const existingContent = this.editor.getModel().getValue();
|
||||||
|
|
||||||
|
if (this.props.content !== existingContent) {
|
||||||
|
this.editor.pushUndoStop();
|
||||||
|
this.editor.executeEdits("", [
|
||||||
|
{
|
||||||
|
range: this.editor.getModel().getFullModelRange(),
|
||||||
|
text: this.props.content,
|
||||||
|
},
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,9 +83,14 @@ export class EditorReact extends React.Component<EditorReactProps, EditorReactSt
|
||||||
|
|
||||||
protected configureEditor(editor: monaco.editor.IStandaloneCodeEditor) {
|
protected configureEditor(editor: monaco.editor.IStandaloneCodeEditor) {
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
const queryEditorModel = this.editor.getModel();
|
|
||||||
if (!this.props.isReadOnly && this.props.onContentChanged) {
|
if (!this.props.isReadOnly && this.props.onContentChanged) {
|
||||||
queryEditorModel.onDidChangeContent(() => {
|
// Hooking the model's onDidChangeContent event because of some event ordering issues.
|
||||||
|
// If a single user input causes BOTH the editor content to change AND the cursor selection to change (which is likely),
|
||||||
|
// then there are some inconsistencies as to which event fires first.
|
||||||
|
// But the editor.onDidChangeModelContent event seems to always fire before the cursor selection event.
|
||||||
|
// (This is NOT true for the model's onDidChangeContent event, which sometimes fires after the cursor selection event.)
|
||||||
|
// If the cursor selection event fires first, then the calling component may re-render the component with old content, so we want to ensure the model content changed event always fires first.
|
||||||
|
this.editor.onDidChangeModelContent(() => {
|
||||||
const queryEditorModel = this.editor.getModel();
|
const queryEditorModel = this.editor.getModel();
|
||||||
this.props.onContentChanged(queryEditorModel.getValue());
|
this.props.onContentChanged(queryEditorModel.getValue());
|
||||||
});
|
});
|
||||||
|
|
|
@ -496,13 +496,16 @@ export default class QueryTabComponent extends React.Component<IQueryTabComponen
|
||||||
};
|
};
|
||||||
|
|
||||||
public onChangeContent(newContent: string): void {
|
public onChangeContent(newContent: string): void {
|
||||||
|
// The copilot store's active query takes precedence over the local state,
|
||||||
|
// and we can't update both states in a single operation.
|
||||||
|
// So, we update the copilot store's state first, then update the local state.
|
||||||
|
if (this.state.copilotActive) {
|
||||||
|
this.props.copilotStore?.setQuery(newContent);
|
||||||
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
sqlQueryEditorContent: newContent,
|
sqlQueryEditorContent: newContent,
|
||||||
queryCopilotGeneratedQuery: "",
|
queryCopilotGeneratedQuery: "",
|
||||||
});
|
});
|
||||||
if (this.state.copilotActive) {
|
|
||||||
this.props.copilotStore?.setQuery(newContent);
|
|
||||||
}
|
|
||||||
if (this.isPreferredApiMongoDB) {
|
if (this.isPreferredApiMongoDB) {
|
||||||
if (newContent.length > 0) {
|
if (newContent.length > 0) {
|
||||||
this.executeQueryButton = {
|
this.executeQueryButton = {
|
||||||
|
@ -544,7 +547,7 @@ export default class QueryTabComponent extends React.Component<IQueryTabComponen
|
||||||
useCommandBar.getState().setContextButtons(this.getTabsButtons());
|
useCommandBar.getState().setContextButtons(this.getTabsButtons());
|
||||||
}
|
}
|
||||||
|
|
||||||
public setEditorContent(): string {
|
public getEditorContent(): string {
|
||||||
if (this.isCopilotTabActive && this.state.queryCopilotGeneratedQuery) {
|
if (this.isCopilotTabActive && this.state.queryCopilotGeneratedQuery) {
|
||||||
return this.state.queryCopilotGeneratedQuery;
|
return this.state.queryCopilotGeneratedQuery;
|
||||||
}
|
}
|
||||||
|
@ -601,7 +604,7 @@ export default class QueryTabComponent extends React.Component<IQueryTabComponen
|
||||||
<div className="queryEditor" style={{ height: "100%" }}>
|
<div className="queryEditor" style={{ height: "100%" }}>
|
||||||
<EditorReact
|
<EditorReact
|
||||||
language={"sql"}
|
language={"sql"}
|
||||||
content={this.setEditorContent()}
|
content={this.getEditorContent()}
|
||||||
isReadOnly={false}
|
isReadOnly={false}
|
||||||
wordWrap={"on"}
|
wordWrap={"on"}
|
||||||
ariaLabel={"Editing Query"}
|
ariaLabel={"Editing Query"}
|
||||||
|
|
Loading…
Reference in New Issue