Skip to content

Commit b89d084

Browse files
authored
feat(QueryEditor): add error highlighting (#1833)
1 parent 5c722dd commit b89d084

File tree

6 files changed

+79
-0
lines changed

6 files changed

+79
-0
lines changed

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

Lines changed: 4 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 {useUpdateErrorsHighlighting} from '../../../../utils/monaco/highlightErrors';
4546
import {QUERY_ACTIONS} from '../../../../utils/query';
4647
import type {InitialPaneState} from '../../utils/paneVisibilityToggleHelpers';
4748
import {
@@ -89,6 +90,8 @@ export default function QueryEditor(props: QueryEditorProps) {
8990
const input = useTypedSelector(selectUserInput);
9091
const showPreview = useTypedSelector(selectShowPreview);
9192

93+
const updateErrorsHighlighting = useUpdateErrorsHighlighting();
94+
9295
const isResultLoaded = Boolean(result);
9396

9497
const [querySettings] = useQueryExecutionSettings();
@@ -294,6 +297,7 @@ export default function QueryEditor(props: QueryEditorProps) {
294297
};
295298

296299
const onChange = (newValue: string) => {
300+
updateErrorsHighlighting();
297301
changeUserInput({input: newValue});
298302
};
299303

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() {

src/utils/hooks/useCancellable.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import React from 'react';
2+
3+
export function useCancellableFunction<T extends {cancel: () => void}>(cancellable: T) {
4+
React.useEffect(() => {
5+
return () => {
6+
cancellable.cancel();
7+
};
8+
}, [cancellable]);
9+
return cancellable;
10+
}

src/utils/monaco/highlightErrors.ts

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

src/utils/monaco/i18n/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"context_syntax-error": "Syntax error"
3+
}

src/utils/monaco/i18n/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import {registerKeysets} from '../../i18n';
2+
3+
import en from './en.json';
4+
5+
const COMPONENT = 'ydb-monaco';
6+
7+
export default registerKeysets(COMPONENT, {en});

0 commit comments

Comments
 (0)