Skip to content

Commit 38ea87f

Browse files
authored
fix: code assistant option (#1922)
1 parent f648f08 commit 38ea87f

File tree

8 files changed

+104
-57
lines changed

8 files changed

+104
-57
lines changed

package-lock.json

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"@hookform/resolvers": "^3.10.0",
2929
"@reduxjs/toolkit": "^2.5.0",
3030
"@tanstack/react-table": "^8.20.6",
31-
"@ydb-platform/monaco-ghost": "^0.4.0",
31+
"@ydb-platform/monaco-ghost": "^0.6.1",
3232
"axios": "^1.7.9",
3333
"axios-retry": "^4.5.0",
3434
"colord": "^2.9.3",

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

+23-30
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import React from 'react';
2+
13
import NiceModal from '@ebay/nice-modal-react';
2-
import {useMonacoGhost} from '@ydb-platform/monaco-ghost';
4+
import {createMonacoGhostInstance} from '@ydb-platform/monaco-ghost';
35
import throttle from 'lodash/throttle';
46
import type Monaco from 'monaco-editor';
57

@@ -11,7 +13,7 @@ import {
1113
selectUserInput,
1214
} from '../../../../store/reducers/query/query';
1315
import type {QueryAction} from '../../../../types/store/query';
14-
import {LAST_USED_QUERY_ACTION_KEY} from '../../../../utils/constants';
16+
import {ENABLE_CODE_ASSISTANT, LAST_USED_QUERY_ACTION_KEY} from '../../../../utils/constants';
1517
import {
1618
useEventHandler,
1719
useSetting,
@@ -23,9 +25,8 @@ import {useUpdateErrorsHighlighting} from '../../../../utils/monaco/highlightErr
2325
import {QUERY_ACTIONS} from '../../../../utils/query';
2426
import {SAVE_QUERY_DIALOG} from '../SaveQuery/SaveQuery';
2527
import i18n from '../i18n';
26-
import {useSavedQueries} from '../utils/useSavedQueries';
2728

28-
import {useCodeAssist, useEditorOptions} from './helpers';
29+
import {useCodeAssistHelpers, useEditorOptions} from './helpers';
2930
import {getKeyBindings} from './keybindings';
3031

3132
const CONTEXT_MENU_GROUP_ID = 'navigation';
@@ -45,8 +46,11 @@ export function YqlEditor({
4546
}: YqlEditorProps) {
4647
const input = useTypedSelector(selectUserInput);
4748
const dispatch = useTypedDispatch();
49+
const [monacoGhostInstance, setMonacoGhostInstance] =
50+
React.useState<ReturnType<typeof createMonacoGhostInstance>>();
4851
const historyQueries = useTypedSelector(selectQueriesHistory);
49-
const savedQueries = useSavedQueries();
52+
const [isCodeAssistEnabled] = useSetting(ENABLE_CODE_ASSISTANT);
53+
5054
const editorOptions = useEditorOptions();
5155
const updateErrorsHighlighting = useUpdateErrorsHighlighting();
5256

@@ -71,20 +75,18 @@ export function YqlEditor({
7175
window.ydbEditor = undefined;
7276
};
7377

74-
const codeAssist = useCodeAssist();
75-
const {registerMonacoGhost} = useMonacoGhost({
76-
api: {
77-
getCodeAssistSuggestions: codeAssist.getCodeAssistSuggestions,
78-
},
79-
eventHandlers: {
80-
onCompletionAccept: codeAssist.onCompletionAccept,
81-
onCompletionDecline: codeAssist.onCompletionDecline,
82-
onCompletionIgnore: codeAssist.onCompletionIgnore,
83-
},
84-
config: {
85-
language: YQL_LANGUAGE_ID,
86-
},
87-
});
78+
const {monacoGhostConfig, prepareUserQueriesCache} = useCodeAssistHelpers();
79+
80+
React.useEffect(() => {
81+
if (monacoGhostInstance && isCodeAssistEnabled) {
82+
monacoGhostInstance.register(monacoGhostConfig);
83+
prepareUserQueriesCache();
84+
}
85+
86+
return () => {
87+
monacoGhostInstance?.unregister();
88+
};
89+
}, [isCodeAssistEnabled, monacoGhostConfig, monacoGhostInstance, prepareUserQueriesCache]);
8890

8991
const editorDidMount = (editor: Monaco.editor.IStandaloneCodeEditor, monaco: typeof Monaco) => {
9092
window.ydbEditor = editor;
@@ -100,18 +102,9 @@ export function YqlEditor({
100102
});
101103

102104
if (window.api.codeAssist) {
103-
registerMonacoGhost(editor);
104-
codeAssist.prepareUserQueriesCache([
105-
...historyQueries.map((query, index) => ({
106-
name: `query${index}.yql`,
107-
text: query.queryText,
108-
})),
109-
...savedQueries.map((query) => ({
110-
name: query.name,
111-
text: query.body,
112-
})),
113-
]);
105+
setMonacoGhostInstance(createMonacoGhostInstance(editor));
114106
}
107+
115108
initResizeHandler(editor);
116109
initUserPrompt(editor, getLastQueryText);
117110
editor.focus();

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

+48-20
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ import type {AcceptEvent, DeclineEvent, IgnoreEvent, PromptFile} from '@ydb-plat
44
import type Monaco from 'monaco-editor';
55

66
import {codeAssistApi} from '../../../../store/reducers/codeAssist/codeAssist';
7+
import {selectQueriesHistory} from '../../../../store/reducers/query/query';
78
import type {TelemetryOpenTabs} from '../../../../types/api/codeAssist';
89
import {AUTOCOMPLETE_ON_ENTER, ENABLE_AUTOCOMPLETE} from '../../../../utils/constants';
9-
import {useSetting} from '../../../../utils/hooks';
10+
import {useSetting, useTypedSelector} from '../../../../utils/hooks';
11+
import {YQL_LANGUAGE_ID} from '../../../../utils/monaco/constats';
12+
import {useSavedQueries} from '../utils/useSavedQueries';
1013

1114
export type EditorOptions = Monaco.editor.IEditorOptions & Monaco.editor.IGlobalEditorOptions;
1215

@@ -36,12 +39,14 @@ export function useEditorOptions() {
3639
return options;
3740
}
3841

39-
export function useCodeAssist() {
42+
export function useCodeAssistHelpers() {
4043
const [sendCodeAssistPrompt] = codeAssistApi.useLazyGetCodeAssistSuggestionsQuery();
4144
const [acceptSuggestion] = codeAssistApi.useAcceptSuggestionMutation();
4245
const [discardSuggestion] = codeAssistApi.useDiscardSuggestionMutation();
4346
const [ignoreSuggestion] = codeAssistApi.useIgnoreSuggestionMutation();
4447
const [sendUserQueriesData] = codeAssistApi.useSendUserQueriesDataMutation();
48+
const historyQueries = useTypedSelector(selectQueriesHistory);
49+
const savedQueries = useSavedQueries();
4550

4651
const getCodeAssistSuggestions = React.useCallback(
4752
async (promptFiles: PromptFile[]) => sendCodeAssistPrompt(promptFiles).unwrap(),
@@ -63,26 +68,49 @@ export function useCodeAssist() {
6368
[ignoreSuggestion],
6469
);
6570

66-
const prepareUserQueriesCache = React.useCallback(
67-
async (queries: {text: string; name?: string}[]) => {
68-
const preparedData: TelemetryOpenTabs = queries.map((query, index) => ({
69-
FileName: query.name || `query${index}.yql`,
70-
Text: query.text,
71-
}));
72-
try {
73-
return sendUserQueriesData(preparedData).unwrap();
74-
} catch {
75-
return {items: []};
76-
}
77-
},
78-
[sendUserQueriesData],
79-
);
71+
const userQueries = React.useMemo(() => {
72+
return [
73+
...historyQueries.map((query, index) => ({
74+
name: `query${index}.yql`,
75+
text: query.queryText,
76+
})),
77+
...savedQueries.map((query) => ({
78+
name: query.name,
79+
text: query.body,
80+
})),
81+
];
82+
}, [historyQueries, savedQueries]);
83+
84+
const prepareUserQueriesCache = React.useCallback(async () => {
85+
const preparedData: TelemetryOpenTabs = userQueries.map((query, index) => ({
86+
FileName: query.name || `query${index}.yql`,
87+
Text: query.text,
88+
}));
89+
try {
90+
return await sendUserQueriesData(preparedData).unwrap();
91+
} catch {
92+
return {items: []};
93+
}
94+
}, [sendUserQueriesData, userQueries]);
95+
96+
const monacoGhostConfig = React.useMemo(() => {
97+
return {
98+
api: {
99+
getCodeAssistSuggestions,
100+
},
101+
eventHandlers: {
102+
onCompletionAccept,
103+
onCompletionDecline,
104+
onCompletionIgnore,
105+
},
106+
config: {
107+
language: YQL_LANGUAGE_ID,
108+
},
109+
};
110+
}, [getCodeAssistSuggestions, onCompletionAccept, onCompletionDecline, onCompletionIgnore]);
80111

81112
return {
82-
getCodeAssistSuggestions,
83-
onCompletionAccept,
84-
onCompletionDecline,
85-
onCompletionIgnore,
86113
prepareUserQueriesCache,
114+
monacoGhostConfig,
87115
};
88116
}

src/containers/UserSettings/i18n/en.json

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
"settings.editor.autocomplete.title": "Enable autocomplete",
1515
"settings.editor.autocomplete.description": "You're always able to get suggestions by pressing Ctrl+Space.",
1616

17+
"settings.editor.codeAssistant.title": "Code Assistant",
18+
"settings.editor.codeAssistant.description": "Use Code Assistant for autocomplete.",
19+
1720
"settings.editor.autocomplete-on-enter.title": "Accept suggestion on Enter",
1821
"settings.editor.autocomplete-on-enter.description": "Controls whether suggestions should be accepted on Enter, in addition to Tab. Helps to avoid ambiguity between inserting new lines or accepting suggestions.",
1922

src/containers/UserSettings/settings.tsx

+21-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
AUTOCOMPLETE_ON_ENTER,
77
BINARY_DATA_IN_PLAIN_TEXT_DISPLAY,
88
ENABLE_AUTOCOMPLETE,
9+
ENABLE_CODE_ASSISTANT,
910
ENABLE_NETWORK_TABLE_KEY,
1011
INVERTED_DISKS_KEY,
1112
LANGUAGE_KEY,
@@ -120,6 +121,12 @@ export const enableAutocompleteSetting: SettingProps = {
120121
description: i18n('settings.editor.autocomplete.description'),
121122
};
122123

124+
export const enableCodeAssistantSetting: SettingProps = {
125+
settingKey: ENABLE_CODE_ASSISTANT,
126+
title: i18n('settings.editor.codeAssistant.title'),
127+
description: i18n('settings.editor.codeAssistant.description'),
128+
};
129+
123130
export const autocompleteOnEnterSetting: SettingProps = {
124131
settingKey: AUTOCOMPLETE_ON_ENTER,
125132
title: i18n('settings.editor.autocomplete-on-enter.title'),
@@ -192,14 +199,26 @@ export const aboutPage: SettingsPage = {
192199
showTitle: false,
193200
};
194201

195-
export function getUserSettings({singleClusterMode}: {singleClusterMode: boolean}) {
202+
export function getUserSettings({
203+
singleClusterMode,
204+
codeAssistantConfigured,
205+
}: {
206+
singleClusterMode: boolean;
207+
codeAssistantConfigured?: boolean;
208+
}) {
196209
const experiments = singleClusterMode
197210
? experimentsPage
198211
: createNextState(experimentsPage, (draft) => {
199212
draft.sections[0].settings.push(useClusterBalancerAsBackendSetting);
200213
});
201214

202-
const settings: YDBEmbeddedUISettings = [generalPage, editorPage, experiments, aboutPage];
215+
const editor = codeAssistantConfigured
216+
? createNextState(editorPage, (draft) => {
217+
draft.sections[0].settings.push(enableCodeAssistantSetting);
218+
})
219+
: editorPage;
220+
221+
const settings: YDBEmbeddedUISettings = [generalPage, editor, experiments, aboutPage];
203222

204223
return settings;
205224
}

src/services/settings.ts

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
BINARY_DATA_IN_PLAIN_TEXT_DISPLAY,
77
CASE_SENSITIVE_JSON_SEARCH,
88
ENABLE_AUTOCOMPLETE,
9+
ENABLE_CODE_ASSISTANT,
910
ENABLE_NETWORK_TABLE_KEY,
1011
INVERTED_DISKS_KEY,
1112
IS_HOTKEYS_HELP_HIDDEN_KEY,
@@ -42,6 +43,7 @@ export const DEFAULT_USER_SETTINGS = {
4243
[USE_SHOW_PLAN_SVG_KEY]: false,
4344
[USE_CLUSTER_BALANCER_AS_BACKEND_KEY]: true,
4445
[ENABLE_AUTOCOMPLETE]: true,
46+
[ENABLE_CODE_ASSISTANT]: true,
4547
[AUTOCOMPLETE_ON_ENTER]: true,
4648
[IS_HOTKEYS_HELP_HIDDEN_KEY]: false,
4749
[AUTO_REFRESH_INTERVAL]: 0,

src/utils/constants.ts

+2
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ export const USE_CLUSTER_BALANCER_AS_BACKEND_KEY = 'useClusterBalancerAsBacked';
117117

118118
export const ENABLE_AUTOCOMPLETE = 'enableAutocomplete';
119119

120+
export const ENABLE_CODE_ASSISTANT = 'enableCodeAssistant';
121+
120122
export const AUTOCOMPLETE_ON_ENTER = 'autocompleteOnEnter';
121123

122124
export const IS_HOTKEYS_HELP_HIDDEN_KEY = 'isHotKeysHelpHidden';

0 commit comments

Comments
 (0)