mirror of https://github.com/apache/superset.git
feat: Stop editor scrolling to top (#26754)
Co-authored-by: Puridach Wutthihathaithamrong <> Co-authored-by: JUST.in DO IT <justin.park@airbnb.com>
This commit is contained in:
parent
11f0dd91db
commit
ed934a93e1
|
@ -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_TITLE = 'QUERY_EDITOR_SET_TITLE';
|
||||||
export const QUERY_EDITOR_SET_AUTORUN = 'QUERY_EDITOR_SET_AUTORUN';
|
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_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_QUERY_LIMIT = 'QUERY_EDITOR_SET_QUERY_LIMIT';
|
||||||
export const QUERY_EDITOR_SET_TEMPLATE_PARAMS =
|
export const QUERY_EDITOR_SET_TEMPLATE_PARAMS =
|
||||||
'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 };
|
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) {
|
export function queryEditorSetAndSaveSql(targetQueryEditor, sql, queryId) {
|
||||||
return function (dispatch, getState) {
|
return function (dispatch, getState) {
|
||||||
const queryEditor = getUpToDateQuery(getState(), targetQueryEditor);
|
const queryEditor = getUpToDateQuery(getState(), targetQueryEditor);
|
||||||
|
|
|
@ -51,6 +51,7 @@ const setup = (queryEditor: QueryEditor, store?: Store) =>
|
||||||
onChange={jest.fn()}
|
onChange={jest.fn()}
|
||||||
onBlur={jest.fn()}
|
onBlur={jest.fn()}
|
||||||
autocomplete
|
autocomplete
|
||||||
|
onCursorPositionChange={jest.fn()}
|
||||||
/>,
|
/>,
|
||||||
{
|
{
|
||||||
useRedux: true,
|
useRedux: true,
|
||||||
|
|
|
@ -25,6 +25,7 @@ import { queryEditorSetSelectedText } from 'src/SqlLab/actions/sqlLab';
|
||||||
import { FullSQLEditor as AceEditor } from 'src/components/AsyncAceEditor';
|
import { FullSQLEditor as AceEditor } from 'src/components/AsyncAceEditor';
|
||||||
import type { KeyboardShortcut } from 'src/SqlLab/components/KeyboardShortcutButton';
|
import type { KeyboardShortcut } from 'src/SqlLab/components/KeyboardShortcutButton';
|
||||||
import useQueryEditor from 'src/SqlLab/hooks/useQueryEditor';
|
import useQueryEditor from 'src/SqlLab/hooks/useQueryEditor';
|
||||||
|
import type { CursorPosition } from 'src/SqlLab/types';
|
||||||
import { useAnnotations } from './useAnnotations';
|
import { useAnnotations } from './useAnnotations';
|
||||||
import { useKeywords } from './useKeywords';
|
import { useKeywords } from './useKeywords';
|
||||||
|
|
||||||
|
@ -40,6 +41,7 @@ type AceEditorWrapperProps = {
|
||||||
onBlur: (sql: string) => void;
|
onBlur: (sql: string) => void;
|
||||||
onChange: (sql: string) => void;
|
onChange: (sql: string) => void;
|
||||||
queryEditorId: string;
|
queryEditorId: string;
|
||||||
|
onCursorPositionChange: (position: CursorPosition) => void;
|
||||||
height: string;
|
height: string;
|
||||||
hotkeys: HotKey[];
|
hotkeys: HotKey[];
|
||||||
};
|
};
|
||||||
|
@ -69,6 +71,7 @@ const AceEditorWrapper = ({
|
||||||
onBlur = () => {},
|
onBlur = () => {},
|
||||||
onChange = () => {},
|
onChange = () => {},
|
||||||
queryEditorId,
|
queryEditorId,
|
||||||
|
onCursorPositionChange,
|
||||||
height,
|
height,
|
||||||
hotkeys,
|
hotkeys,
|
||||||
}: AceEditorWrapperProps) => {
|
}: AceEditorWrapperProps) => {
|
||||||
|
@ -79,10 +82,11 @@ const AceEditorWrapper = ({
|
||||||
'sql',
|
'sql',
|
||||||
'schema',
|
'schema',
|
||||||
'templateParams',
|
'templateParams',
|
||||||
|
'cursorPosition',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const currentSql = queryEditor.sql ?? '';
|
const currentSql = queryEditor.sql ?? '';
|
||||||
|
const cursorPosition = queryEditor.cursorPosition ?? { row: 0, column: 0 };
|
||||||
const [sql, setSql] = useState(currentSql);
|
const [sql, setSql] = useState(currentSql);
|
||||||
|
|
||||||
// The editor changeSelection is called multiple times in a row,
|
// The editor changeSelection is called multiple times in a row,
|
||||||
|
@ -143,6 +147,15 @@ const AceEditorWrapper = ({
|
||||||
|
|
||||||
currentSelectionCache.current = selectedText;
|
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) => {
|
const onChangeText = (text: string) => {
|
||||||
|
|
|
@ -42,7 +42,11 @@ import {
|
||||||
QueryResponse,
|
QueryResponse,
|
||||||
Query,
|
Query,
|
||||||
} from '@superset-ui/core';
|
} 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 type { DatabaseObject } from 'src/features/databases/types';
|
||||||
import { debounce, throttle, isBoolean, isEmpty } from 'lodash';
|
import { debounce, throttle, isBoolean, isEmpty } from 'lodash';
|
||||||
import Modal from 'src/components/Modal';
|
import Modal from 'src/components/Modal';
|
||||||
|
@ -63,6 +67,7 @@ import {
|
||||||
postStopQuery,
|
postStopQuery,
|
||||||
queryEditorSetAutorun,
|
queryEditorSetAutorun,
|
||||||
queryEditorSetSql,
|
queryEditorSetSql,
|
||||||
|
queryEditorSetCursorPosition,
|
||||||
queryEditorSetAndSaveSql,
|
queryEditorSetAndSaveSql,
|
||||||
queryEditorSetTemplateParams,
|
queryEditorSetTemplateParams,
|
||||||
runQueryFromSqlEditor,
|
runQueryFromSqlEditor,
|
||||||
|
@ -757,6 +762,10 @@ const SqlEditor: React.FC<Props> = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleCursorPositionChange = (newPosition: CursorPosition) => {
|
||||||
|
dispatch(queryEditorSetCursorPosition(queryEditor, newPosition));
|
||||||
|
};
|
||||||
|
|
||||||
const queryPane = () => {
|
const queryPane = () => {
|
||||||
const { aceEditorHeight, southPaneHeight } =
|
const { aceEditorHeight, southPaneHeight } =
|
||||||
getAceEditorAndSouthPaneHeights(height, northPercent, southPercent);
|
getAceEditorAndSouthPaneHeights(height, northPercent, southPercent);
|
||||||
|
@ -787,6 +796,7 @@ const SqlEditor: React.FC<Props> = ({
|
||||||
onBlur={onSqlChanged}
|
onBlur={onSqlChanged}
|
||||||
onChange={onSqlChanged}
|
onChange={onSqlChanged}
|
||||||
queryEditorId={queryEditor.id}
|
queryEditorId={queryEditor.id}
|
||||||
|
onCursorPositionChange={handleCursorPositionChange}
|
||||||
height={`${aceEditorHeight}px`}
|
height={`${aceEditorHeight}px`}
|
||||||
hotkeys={hotkeys}
|
hotkeys={hotkeys}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -65,6 +65,7 @@ export default function getInitialState({
|
||||||
queryLimit: common.conf.DEFAULT_SQLLAB_LIMIT,
|
queryLimit: common.conf.DEFAULT_SQLLAB_LIMIT,
|
||||||
hideLeftBar: false,
|
hideLeftBar: false,
|
||||||
remoteId: null,
|
remoteId: null,
|
||||||
|
cursorPosition: { row: 0, column: 0 },
|
||||||
};
|
};
|
||||||
let unsavedQueryEditor: UnsavedQueryEditor = {};
|
let unsavedQueryEditor: UnsavedQueryEditor = {};
|
||||||
|
|
||||||
|
|
|
@ -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]() {
|
[actions.QUERY_EDITOR_SET_QUERY_LIMIT]() {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
|
|
@ -35,6 +35,11 @@ export enum QueryEditorVersion {
|
||||||
|
|
||||||
export const LatestQueryEditorVersion = QueryEditorVersion.v1;
|
export const LatestQueryEditorVersion = QueryEditorVersion.v1;
|
||||||
|
|
||||||
|
export interface CursorPosition {
|
||||||
|
row: number;
|
||||||
|
column: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface QueryEditor {
|
export interface QueryEditor {
|
||||||
version: QueryEditorVersion;
|
version: QueryEditorVersion;
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -56,6 +61,7 @@ export interface QueryEditor {
|
||||||
northPercent?: number;
|
northPercent?: number;
|
||||||
southPercent?: number;
|
southPercent?: number;
|
||||||
updatedAt?: number;
|
updatedAt?: number;
|
||||||
|
cursorPosition?: CursorPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type toastState = {
|
export type toastState = {
|
||||||
|
|
Loading…
Reference in New Issue