* 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);
|
||||
}
|
||||
|
||||
public componentDidUpdate(previous: EditorReactProps) {
|
||||
if (this.props.content !== previous.content) {
|
||||
this.editor?.setValue(this.props.content);
|
||||
public componentDidUpdate() {
|
||||
if (!this.editor) {
|
||||
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) {
|
||||
this.editor = editor;
|
||||
const queryEditorModel = this.editor.getModel();
|
||||
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();
|
||||
this.props.onContentChanged(queryEditorModel.getValue());
|
||||
});
|
||||
|
|
|
@ -496,13 +496,16 @@ export default class QueryTabComponent extends React.Component<IQueryTabComponen
|
|||
};
|
||||
|
||||
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({
|
||||
sqlQueryEditorContent: newContent,
|
||||
queryCopilotGeneratedQuery: "",
|
||||
});
|
||||
if (this.state.copilotActive) {
|
||||
this.props.copilotStore?.setQuery(newContent);
|
||||
}
|
||||
if (this.isPreferredApiMongoDB) {
|
||||
if (newContent.length > 0) {
|
||||
this.executeQueryButton = {
|
||||
|
@ -544,7 +547,7 @@ export default class QueryTabComponent extends React.Component<IQueryTabComponen
|
|||
useCommandBar.getState().setContextButtons(this.getTabsButtons());
|
||||
}
|
||||
|
||||
public setEditorContent(): string {
|
||||
public getEditorContent(): string {
|
||||
if (this.isCopilotTabActive && 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%" }}>
|
||||
<EditorReact
|
||||
language={"sql"}
|
||||
content={this.setEditorContent()}
|
||||
content={this.getEditorContent()}
|
||||
isReadOnly={false}
|
||||
wordWrap={"on"}
|
||||
ariaLabel={"Editing Query"}
|
||||
|
|
Loading…
Reference in New Issue