You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ru...@apache.org on 2024/01/25 21:04:26 UTC

(superset) branch master updated: feat: Stop editor scrolling to top (#26754)

This is an automated email from the ASF dual-hosted git repository.

rusackas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new ed934a93e1 feat: Stop editor scrolling to top (#26754)
ed934a93e1 is described below

commit ed934a93e16ee6f69139307b4fde1cd0c38a5543
Author: Puridach wutthihathaithamrong <76...@users.noreply.github.com>
AuthorDate: Fri Jan 26 04:04:20 2024 +0700

    feat: Stop editor scrolling to top (#26754)
    
    Co-authored-by: Puridach Wutthihathaithamrong <>
    Co-authored-by: JUST.in DO IT <ju...@airbnb.com>
---
 superset-frontend/src/SqlLab/actions/sqlLab.js            |  6 ++++++
 .../components/AceEditorWrapper/AceEditorWrapper.test.tsx |  1 +
 .../src/SqlLab/components/AceEditorWrapper/index.tsx      | 15 ++++++++++++++-
 .../src/SqlLab/components/SqlEditor/index.tsx             | 12 +++++++++++-
 superset-frontend/src/SqlLab/reducers/getInitialState.ts  |  1 +
 superset-frontend/src/SqlLab/reducers/sqlLab.js           | 12 ++++++++++++
 superset-frontend/src/SqlLab/types.ts                     |  6 ++++++
 7 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/superset-frontend/src/SqlLab/actions/sqlLab.js b/superset-frontend/src/SqlLab/actions/sqlLab.js
index 2ee82b1552..223ca16591 100644
--- a/superset-frontend/src/SqlLab/actions/sqlLab.js
+++ b/superset-frontend/src/SqlLab/actions/sqlLab.js
@@ -59,6 +59,8 @@ export const QUERY_EDITOR_SET_SCHEMA = 'QUERY_EDITOR_SET_SCHEMA';
 export const QUERY_EDITOR_SET_TITLE = 'QUERY_EDITOR_SET_TITLE';
 export const QUERY_EDITOR_SET_AUTORUN = 'QUERY_EDITOR_SET_AUTORUN';
 export const QUERY_EDITOR_SET_SQL = 'QUERY_EDITOR_SET_SQL';
+export const QUERY_EDITOR_SET_CURSOR_POSITION =
+  'QUERY_EDITOR_SET_CURSOR_POSITION';
 export const QUERY_EDITOR_SET_QUERY_LIMIT = 'QUERY_EDITOR_SET_QUERY_LIMIT';
 export const QUERY_EDITOR_SET_TEMPLATE_PARAMS =
   'QUERY_EDITOR_SET_TEMPLATE_PARAMS';
@@ -881,6 +883,10 @@ export function queryEditorSetSql(queryEditor, sql, queryId) {
   return { type: QUERY_EDITOR_SET_SQL, queryEditor, sql, queryId };
 }
 
+export function queryEditorSetCursorPosition(queryEditor, position) {
+  return { type: QUERY_EDITOR_SET_CURSOR_POSITION, queryEditor, position };
+}
+
 export function queryEditorSetAndSaveSql(targetQueryEditor, sql, queryId) {
   return function (dispatch, getState) {
     const queryEditor = getUpToDateQuery(getState(), targetQueryEditor);
diff --git a/superset-frontend/src/SqlLab/components/AceEditorWrapper/AceEditorWrapper.test.tsx b/superset-frontend/src/SqlLab/components/AceEditorWrapper/AceEditorWrapper.test.tsx
index 27950a98b1..72daff7602 100644
--- a/superset-frontend/src/SqlLab/components/AceEditorWrapper/AceEditorWrapper.test.tsx
+++ b/superset-frontend/src/SqlLab/components/AceEditorWrapper/AceEditorWrapper.test.tsx
@@ -51,6 +51,7 @@ const setup = (queryEditor: QueryEditor, store?: Store) =>
       onChange={jest.fn()}
       onBlur={jest.fn()}
       autocomplete
+      onCursorPositionChange={jest.fn()}
     />,
     {
       useRedux: true,
diff --git a/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx b/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx
index 8529f49d4f..6069d6c69e 100644
--- a/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx
+++ b/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx
@@ -25,6 +25,7 @@ import { queryEditorSetSelectedText } from 'src/SqlLab/actions/sqlLab';
 import { FullSQLEditor as AceEditor } from 'src/components/AsyncAceEditor';
 import type { KeyboardShortcut } from 'src/SqlLab/components/KeyboardShortcutButton';
 import useQueryEditor from 'src/SqlLab/hooks/useQueryEditor';
+import type { CursorPosition } from 'src/SqlLab/types';
 import { useAnnotations } from './useAnnotations';
 import { useKeywords } from './useKeywords';
 
@@ -40,6 +41,7 @@ type AceEditorWrapperProps = {
   onBlur: (sql: string) => void;
   onChange: (sql: string) => void;
   queryEditorId: string;
+  onCursorPositionChange: (position: CursorPosition) => void;
   height: string;
   hotkeys: HotKey[];
 };
@@ -69,6 +71,7 @@ const AceEditorWrapper = ({
   onBlur = () => {},
   onChange = () => {},
   queryEditorId,
+  onCursorPositionChange,
   height,
   hotkeys,
 }: AceEditorWrapperProps) => {
@@ -79,10 +82,11 @@ const AceEditorWrapper = ({
     'sql',
     'schema',
     'templateParams',
+    'cursorPosition',
   ]);
 
   const currentSql = queryEditor.sql ?? '';
-
+  const cursorPosition = queryEditor.cursorPosition ?? { row: 0, column: 0 };
   const [sql, setSql] = useState(currentSql);
 
   // The editor changeSelection is called multiple times in a row,
@@ -143,6 +147,15 @@ const AceEditorWrapper = ({
 
       currentSelectionCache.current = selectedText;
     });
+    editor.selection.on('changeCursor', () => {
+      const cursor = editor.getCursorPosition();
+      onCursorPositionChange(cursor);
+    });
+
+    const { row, column } = cursorPosition;
+    editor.moveCursorToPosition({ row, column });
+    editor.focus();
+    editor.scrollToLine(row, true, true);
   };
 
   const onChangeText = (text: string) => {
diff --git a/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx b/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
index e09f0c2889..0e6a4845d5 100644
--- a/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
+++ b/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx
@@ -42,7 +42,11 @@ import {
   QueryResponse,
   Query,
 } from '@superset-ui/core';
-import type { QueryEditor, SqlLabRootState } from 'src/SqlLab/types';
+import type {
+  QueryEditor,
+  SqlLabRootState,
+  CursorPosition,
+} from 'src/SqlLab/types';
 import type { DatabaseObject } from 'src/features/databases/types';
 import { debounce, throttle, isBoolean, isEmpty } from 'lodash';
 import Modal from 'src/components/Modal';
@@ -63,6 +67,7 @@ import {
   postStopQuery,
   queryEditorSetAutorun,
   queryEditorSetSql,
+  queryEditorSetCursorPosition,
   queryEditorSetAndSaveSql,
   queryEditorSetTemplateParams,
   runQueryFromSqlEditor,
@@ -757,6 +762,10 @@ const SqlEditor: React.FC<Props> = ({
     );
   };
 
+  const handleCursorPositionChange = (newPosition: CursorPosition) => {
+    dispatch(queryEditorSetCursorPosition(queryEditor, newPosition));
+  };
+
   const queryPane = () => {
     const { aceEditorHeight, southPaneHeight } =
       getAceEditorAndSouthPaneHeights(height, northPercent, southPercent);
@@ -787,6 +796,7 @@ const SqlEditor: React.FC<Props> = ({
             onBlur={onSqlChanged}
             onChange={onSqlChanged}
             queryEditorId={queryEditor.id}
+            onCursorPositionChange={handleCursorPositionChange}
             height={`${aceEditorHeight}px`}
             hotkeys={hotkeys}
           />
diff --git a/superset-frontend/src/SqlLab/reducers/getInitialState.ts b/superset-frontend/src/SqlLab/reducers/getInitialState.ts
index 8d72a313b2..8f21a3ff10 100644
--- a/superset-frontend/src/SqlLab/reducers/getInitialState.ts
+++ b/superset-frontend/src/SqlLab/reducers/getInitialState.ts
@@ -65,6 +65,7 @@ export default function getInitialState({
     queryLimit: common.conf.DEFAULT_SQLLAB_LIMIT,
     hideLeftBar: false,
     remoteId: null,
+    cursorPosition: { row: 0, column: 0 },
   };
   let unsavedQueryEditor: UnsavedQueryEditor = {};
 
diff --git a/superset-frontend/src/SqlLab/reducers/sqlLab.js b/superset-frontend/src/SqlLab/reducers/sqlLab.js
index 59bd0558a1..1d799c559d 100644
--- a/superset-frontend/src/SqlLab/reducers/sqlLab.js
+++ b/superset-frontend/src/SqlLab/reducers/sqlLab.js
@@ -544,6 +544,18 @@ export default function sqlLabReducer(state = {}, action) {
         ),
       };
     },
+    [actions.QUERY_EDITOR_SET_CURSOR_POSITION]() {
+      return {
+        ...state,
+        ...alterUnsavedQueryEditorState(
+          state,
+          {
+            cursorPosition: action.position,
+          },
+          action.queryEditor.id,
+        ),
+      };
+    },
     [actions.QUERY_EDITOR_SET_QUERY_LIMIT]() {
       return {
         ...state,
diff --git a/superset-frontend/src/SqlLab/types.ts b/superset-frontend/src/SqlLab/types.ts
index 6eb42718f0..ec2580f870 100644
--- a/superset-frontend/src/SqlLab/types.ts
+++ b/superset-frontend/src/SqlLab/types.ts
@@ -35,6 +35,11 @@ export enum QueryEditorVersion {
 
 export const LatestQueryEditorVersion = QueryEditorVersion.v1;
 
+export interface CursorPosition {
+  row: number;
+  column: number;
+}
+
 export interface QueryEditor {
   version: QueryEditorVersion;
   id: string;
@@ -56,6 +61,7 @@ export interface QueryEditor {
   northPercent?: number;
   southPercent?: number;
   updatedAt?: number;
+  cursorPosition?: CursorPosition;
 }
 
 export type toastState = {