diff --git a/webapp/packages/core-authentication/src/UsersResource.ts b/webapp/packages/core-authentication/src/UsersResource.ts index 8155178da0..a28b2571aa 100644 --- a/webapp/packages/core-authentication/src/UsersResource.ts +++ b/webapp/packages/core-authentication/src/UsersResource.ts @@ -218,13 +218,13 @@ export class UsersResource extends CachedMapResource): Promise { + async deleteUsers(key: ResourceKeySimple): Promise { await ResourceKeyUtils.forEachAsync(key, async key => { if (this.isActiveUser(key)) { throw new Error("You can't delete current logged user"); } await this.graphQLService.sdk.deleteUser({ userId: key }); - super.delete(key); + this.delete(key); }); } diff --git a/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/DeleteUserDialog.tsx b/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/DeleteUserDialog.tsx index 014ddfc926..e402d4bea2 100644 --- a/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/DeleteUserDialog.tsx +++ b/webapp/packages/plugin-authentication-administration/src/Administration/Users/UserForm/DeleteUserDialog.tsx @@ -38,7 +38,7 @@ export const DeleteUserDialog: DialogComponent = function DeleteUserDi async function deleteUser() { try { - await usersResource.resource.delete(props.payload.userId); + await usersResource.resource.deleteUsers(props.payload.userId); notificationService.logSuccess({ title: 'authentication_administration_users_delete_user_success', message: props.payload.userId }); props.resolveDialog(); } catch (exception: any) { diff --git a/webapp/packages/plugin-codemirror6/src/theme/_base-code-editor.scss b/webapp/packages/plugin-codemirror6/src/theme/_base-code-editor.scss index 68ee4ae329..04aab00d06 100644 --- a/webapp/packages/plugin-codemirror6/src/theme/_base-code-editor.scss +++ b/webapp/packages/plugin-codemirror6/src/theme/_base-code-editor.scss @@ -86,11 +86,8 @@ } .editor .active-query { - /* disable because look too ugly */ - /* display: inline-block; @include mdc-theme-prop(background, secondary, false); - */ } .editor .cm-content ::selection { diff --git a/webapp/packages/plugin-sql-editor-new/src/SQLEditor/SQLCodeEditorPanel/useSQLCodeEditorPanel.ts b/webapp/packages/plugin-sql-editor-new/src/SQLEditor/SQLCodeEditorPanel/useSQLCodeEditorPanel.ts index 313ad44b18..89bc3e48e8 100644 --- a/webapp/packages/plugin-sql-editor-new/src/SQLEditor/SQLCodeEditorPanel/useSQLCodeEditorPanel.ts +++ b/webapp/packages/plugin-sql-editor-new/src/SQLEditor/SQLCodeEditorPanel/useSQLCodeEditorPanel.ts @@ -9,7 +9,7 @@ import { action } from 'mobx'; import { useCallback } from 'react'; import { useExecutor, useObservableRef } from '@cloudbeaver/core-blocks'; -import { throttle } from '@cloudbeaver/core-utils'; +import { debounce } from '@cloudbeaver/core-utils'; import type { ISQLEditorData } from '@cloudbeaver/plugin-sql-editor'; import type { IEditor } from '../SQLCodeEditor/useSQLCodeEditor'; @@ -21,16 +21,20 @@ interface State { } export function useSQLCodeEditorPanel(data: ISQLEditorData, editor: IEditor) { + const script = data.dataSource?.script; + const state: State = useObservableRef( () => ({ highlightActiveQuery() { - this.editor.clearActiveQueryHighlight(); + queueMicrotask(() => { + this.editor.clearActiveQueryHighlight(); - const segment = this.data.activeSegment; + const segment = this.data.activeSegment; - if (segment) { - this.editor.highlightActiveQuery(segment.begin, segment.end); - } + if (segment && data.isCursorInActiveQuerySegment) { + this.editor.highlightActiveQuery(segment.begin, segment.end); + } + }); }, onQueryChange(query: string) { this.data.setScript(query); @@ -44,13 +48,29 @@ export function useSQLCodeEditorPanel(data: ISQLEditorData, editor: IEditor) { ); const updateHighlight = useCallback( - throttle(() => state.highlightActiveQuery(), 1000), + debounce(() => state.highlightActiveQuery(), 300), [state], ); + function onUpdate() { + const newScript = data.dataSource?.script; + const isScriptChanged = script !== newScript; + + editor.clearActiveQueryHighlight(); + + if (!isScriptChanged) { + updateHighlight(); + } + } + useExecutor({ executor: data.onUpdate, - handlers: [updateHighlight], + handlers: [onUpdate], + }); + + useExecutor({ + executor: data.dataSource?.onUpdate, + handlers: [onUpdate], }); useExecutor({ diff --git a/webapp/packages/plugin-sql-editor/src/SqlEditor/ISQLEditorData.ts b/webapp/packages/plugin-sql-editor/src/SqlEditor/ISQLEditorData.ts index 185938782d..5928604881 100644 --- a/webapp/packages/plugin-sql-editor/src/SqlEditor/ISQLEditorData.ts +++ b/webapp/packages/plugin-sql-editor/src/SqlEditor/ISQLEditorData.ts @@ -29,6 +29,7 @@ export interface ISQLEditorData { readonly editing: boolean; readonly isScriptEmpty: boolean; readonly isDisabled: boolean; + readonly isCursorInActiveQuerySegment: boolean; readonly isIncomingChanges: boolean; readonly value: string; readonly incomingValue?: string; diff --git a/webapp/packages/plugin-sql-editor/src/SqlEditor/useSqlEditor.ts b/webapp/packages/plugin-sql-editor/src/SqlEditor/useSqlEditor.ts index 4370dd7fe3..9f9f3d826b 100644 --- a/webapp/packages/plugin-sql-editor/src/SqlEditor/useSqlEditor.ts +++ b/webapp/packages/plugin-sql-editor/src/SqlEditor/useSqlEditor.ts @@ -57,6 +57,7 @@ interface ISQLEditorDataPrivate extends ISQLEditorData { } const MAX_HINTS_LIMIT = 200; +const END_OF_THE_ACTIVE_QUERY_OFFSET = 2; export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData { const connectionExecutionContextService = useService(ConnectionExecutionContextService); @@ -88,6 +89,13 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData { activeSegmentMode: false, }, + get isCursorInActiveQuerySegment(): boolean { + const segment = this.activeSegment; + const cursor = this.cursorSegment; + + return !!segment && !!cursor && cursor.begin >= segment.begin && cursor.end - END_OF_THE_ACTIVE_QUERY_OFFSET <= segment.end; + }, + get activeSegment(): ISQLScriptSegment | undefined { return this.activeSegmentMode.activeSegment; }, @@ -441,16 +449,16 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData { return this.getSubQuery(); } - if (this.activeSegmentMode.activeSegmentMode) { - return this.activeSegment; - } - const result = await this.sqlEditorService.parseSQLQuery(projectId, connectionId, this.value, this.cursor.begin); if (result.end === 0 && result.start === 0) { return; } + if (this.activeSegment) { + return this.activeSegment; + } + const segment = this.parser.getSegment(result.start, result.end); return segment; },