Skip to content

Commit 3cf0cc1

Browse files
committed
feat(QueryEditor): add error highlighting
1 parent dec5b95 commit 3cf0cc1

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

src/containers/Tenant/Query/QueryEditor/QueryEditor.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import {
4242
import {useChangedQuerySettings} from '../../../../utils/hooks/useChangedQuerySettings';
4343
import {useLastQueryExecutionSettings} from '../../../../utils/hooks/useLastQueryExecutionSettings';
4444
import {YQL_LANGUAGE_ID} from '../../../../utils/monaco/constats';
45+
import {updateErrorsHighlighting} from '../../../../utils/monaco/highlightErrors';
4546
import {QUERY_ACTIONS} from '../../../../utils/query';
4647
import type {InitialPaneState} from '../../utils/paneVisibilityToggleHelpers';
4748
import {
@@ -294,6 +295,7 @@ export default function QueryEditor(props: QueryEditorProps) {
294295
};
295296

296297
const onChange = (newValue: string) => {
298+
updateErrorsHighlighting();
297299
changeUserInput({input: newValue});
298300
};
299301

src/containers/Tenant/Query/QueryEditor/helpers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const EDITOR_OPTIONS: EditorOptions = {
1313
minimap: {
1414
enabled: false,
1515
},
16+
fixedOverflowWidgets: true,
1617
};
1718

1819
export function useEditorOptions() {
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import {parseYqlQueryWithoutCursor} from '@gravity-ui/websql-autocomplete/yql';
2+
import {MarkerSeverity, editor} from 'monaco-editor';
3+
4+
const owner = 'ydb';
5+
6+
let errorsHighlightingTimeoutId: ReturnType<typeof setTimeout>;
7+
8+
export function disableErrorsHighlighting(): void {
9+
unHighlightErrors();
10+
}
11+
12+
export function updateErrorsHighlighting(): void {
13+
disableErrorsHighlighting();
14+
15+
clearTimeout(errorsHighlightingTimeoutId);
16+
errorsHighlightingTimeoutId = setTimeout(() => highlightErrors(), 500);
17+
}
18+
19+
function highlightErrors(): void {
20+
const model = window.ydbEditor?.getModel();
21+
if (!model) {
22+
console.error('unable to retrieve model when highlighting errors');
23+
return;
24+
}
25+
26+
const errors = parseYqlQueryWithoutCursor(model.getValue()).errors;
27+
if (!errors.length) {
28+
unHighlightErrors();
29+
return;
30+
}
31+
32+
const markers = errors.map(
33+
(error): editor.IMarkerData => ({
34+
message: 'Syntax error',
35+
source: error.message,
36+
severity: MarkerSeverity.Error,
37+
startLineNumber: error.startLine,
38+
startColumn: convertAutocompleteErrorLocationIndexToMonacoIndex(error.startColumn),
39+
endLineNumber: error.endLine,
40+
endColumn: convertAutocompleteErrorLocationIndexToMonacoIndex(error.endColumn),
41+
}),
42+
);
43+
editor.setModelMarkers(model, owner, markers);
44+
}
45+
46+
function unHighlightErrors(): void {
47+
editor.removeAllMarkers(owner);
48+
}
49+
50+
function convertAutocompleteErrorLocationIndexToMonacoIndex(
51+
autocompleteLocationIndex: number,
52+
): number {
53+
return autocompleteLocationIndex + 1;
54+
}

0 commit comments

Comments
 (0)