1. Fixed an issue where Alt-Shift-Q didn't work after creating a new query. Fixes #7575

2. Fixed an issue where the Query Editor loses focus when saving a query (Alt+s). Fixes #7521
3. Ensure that an error is thrown if clipboard access is not provided and change the copy rows shortcut. Fixes #7452
pull/90/head
Aditya Toshniwal 2022-08-17 17:23:11 +05:30 committed by Akshay Joshi
parent c8ef4733d0
commit 306b184e11
10 changed files with 55 additions and 21 deletions

View File

@ -28,11 +28,14 @@ Housekeeping
Bug fixes Bug fixes
********* *********
| `Issue #7452 <https://redmine.postgresql.org/issues/7452>`_ - Ensure that an error is thrown if clipboard access is not provided and change the copy rows shortcut.
| `Issue #7497 <https://redmine.postgresql.org/issues/7497>`_ - Fixed an issue with the error message being displayed at the right place for Azure deployments. | `Issue #7497 <https://redmine.postgresql.org/issues/7497>`_ - Fixed an issue with the error message being displayed at the right place for Azure deployments.
| `Issue #7521 <https://redmine.postgresql.org/issues/7521>`_ - Fixed an issue where the Query Editor loses focus when saving a query (Alt+s).
| `Issue #7527 <https://redmine.postgresql.org/issues/7527>`_ - Fixed API test cases for Postgres 14.4. | `Issue #7527 <https://redmine.postgresql.org/issues/7527>`_ - Fixed API test cases for Postgres 14.4.
| `Issue #7540 <https://redmine.postgresql.org/issues/7540>`_ - Ensure that rename panel should work on view/edit panels. | `Issue #7540 <https://redmine.postgresql.org/issues/7540>`_ - Ensure that rename panel should work on view/edit panels.
| `Issue #7563 <https://redmine.postgresql.org/issues/7563>`_ - Fixed an issue where autocomplete is not working after clearing the query editor. | `Issue #7563 <https://redmine.postgresql.org/issues/7563>`_ - Fixed an issue where autocomplete is not working after clearing the query editor.
| `Issue #7573 <https://redmine.postgresql.org/issues/7573>`_ - Ensure that autocomplete does not appear when navigating code using arrow keys. | `Issue #7573 <https://redmine.postgresql.org/issues/7573>`_ - Ensure that autocomplete does not appear when navigating code using arrow keys.
| `Issue #7575 <https://redmine.postgresql.org/issues/7575>`_ - Fixed an issue where Alt-Shift-Q didn't work after creating a new query.
| `Issue #7586 <https://redmine.postgresql.org/issues/7586>`_ - Fixed an issue with rendering geometry when selecting a complete column. | `Issue #7586 <https://redmine.postgresql.org/issues/7586>`_ - Fixed an issue with rendering geometry when selecting a complete column.
| `Issue #7587 <https://redmine.postgresql.org/issues/7587>`_ - Ensure that the children of information_schema and pg_catalog node should be displayed. | `Issue #7587 <https://redmine.postgresql.org/issues/7587>`_ - Ensure that the children of information_schema and pg_catalog node should be displayed.
| `Issue #7608 <https://redmine.postgresql.org/issues/7608>`_ - Fixed an issue where the cloud deployment wizard creates the cluster with the High Availability even if that option is not selected. | `Issue #7608 <https://redmine.postgresql.org/issues/7608>`_ - Fixed an issue where the cloud deployment wizard creates the cluster with the High Availability even if that option is not selected.

View File

@ -21,6 +21,7 @@ import DeleteIcon from '@material-ui/icons/Delete';
import HelpIcon from '@material-ui/icons/HelpRounded'; import HelpIcon from '@material-ui/icons/HelpRounded';
import url_for from 'sources/url_for'; import url_for from 'sources/url_for';
import { Box } from '@material-ui/core'; import { Box } from '@material-ui/core';
import { useMemo } from 'react';
const useStyles = makeStyles((theme) => ({ const useStyles = makeStyles((theme) => ({
@ -98,7 +99,7 @@ export default function Processes() {
const [tableData, setTableData] = React.useState([]); const [tableData, setTableData] = React.useState([]);
const [selectedRows, setSelectedRows] = React.useState([]); const [selectedRows, setSelectedRows] = React.useState([]);
let columns = [ let columns = useMemo(()=>[
{ {
accessor: 'stop_process', accessor: 'stop_process',
Header: () => null, Header: () => null,
@ -224,7 +225,7 @@ export default function Processes() {
resizable: true, resizable: true,
disableGlobalFilter: true, disableGlobalFilter: true,
}, },
]; ], []);
const updateList = ()=>{ const updateList = ()=>{
if(pgAdmin.Browser.BgProcessManager.procList) { if(pgAdmin.Browser.BgProcessManager.procList) {

View File

@ -1,9 +1,11 @@
import Notifier from './helpers/Notifier';
export async function copyToClipboard(text) { export async function copyToClipboard(text) {
try { try {
await navigator.clipboard.writeText(text); await navigator.clipboard.writeText(text);
} catch { } catch(err) {
/* Suppress error */ /* Suppress error */
console.error('Does not have clipboard acccess'); Notifier.error('Does not have clipboard acccess');
} }
localStorage.setItem('clipboard', text); localStorage.setItem('clipboard', text);
} }

View File

@ -269,6 +269,7 @@ export default function PgTable({ columns, data, isSelectRow, caveTable=true, sc
defaultColumn, defaultColumn,
isSelectRow, isSelectRow,
autoResetSortBy: false, autoResetSortBy: false,
autoResetSelectedRows: false,
initialState: { initialState: {
sortBy: sortOptions || [], sortBy: sortOptions || [],
} }

View File

@ -408,6 +408,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
isDirtyRef.current = false; isDirtyRef.current = false;
setPanelTitle(panel, fileName, {...qtState, current_file: fileName}); setPanelTitle(panel, fileName, {...qtState, current_file: fileName});
} }
eventBus.current.fireEvent(QUERY_TOOL_EVENTS.EDITOR_LAST_FOCUS);
}; };
const events = [ const events = [
[QUERY_TOOL_EVENTS.TRIGGER_LOAD_FILE, ()=>{ [QUERY_TOOL_EVENTS.TRIGGER_LOAD_FILE, ()=>{
@ -699,6 +700,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
onNewQueryToolClick={onNewQueryToolClick} onNewQueryToolClick={onNewQueryToolClick}
onResetLayout={onResetLayout} onResetLayout={onResetLayout}
docker={docker.current} docker={docker.current}
containerRef={containerRef}
/> />
{React.useMemo(()=>( {React.useMemo(()=>(
<MainToolBar <MainToolBar

View File

@ -56,6 +56,7 @@ export const QUERY_TOOL_EVENTS = {
SET_FILTER_INFO: 'SET_FILTER_INFO', SET_FILTER_INFO: 'SET_FILTER_INFO',
FETCH_MORE_ROWS: 'FETCH_MORE_ROWS', FETCH_MORE_ROWS: 'FETCH_MORE_ROWS',
EDITOR_LAST_FOCUS: 'EDITOR_LAST_FOCUS',
EDITOR_FIND_REPLACE: 'EDITOR_FIND_REPLACE', EDITOR_FIND_REPLACE: 'EDITOR_FIND_REPLACE',
EDITOR_EXEC_CMD: 'EDITOR_EXEC_CMD', EDITOR_EXEC_CMD: 'EDITOR_EXEC_CMD',
EDITOR_SET_SQL: 'EDITOR_SET_SQL', EDITOR_SET_SQL: 'EDITOR_SET_SQL',

View File

@ -22,6 +22,8 @@ import { PgMenu, PgMenuItem } from '../../../../../../static/js/components/Menu'
import gettext from 'sources/gettext'; import gettext from 'sources/gettext';
import RotateLeftRoundedIcon from '@material-ui/icons/RotateLeftRounded'; import RotateLeftRoundedIcon from '@material-ui/icons/RotateLeftRounded';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useKeyboardShortcuts } from '../../../../../../static/js/custom_hooks';
import CustomPropTypes from '../../../../../../static/js/custom_prop_types';
const useStyles = makeStyles((theme)=>({ const useStyles = makeStyles((theme)=>({
root: { root: {
@ -79,7 +81,7 @@ ConnectionStatusIcon.propTypes = {
}; };
export function ConnectionBar({connected, connecting, connectionStatus, connectionStatusMsg, export function ConnectionBar({connected, connecting, connectionStatus, connectionStatusMsg,
connectionList, onConnectionChange, onNewConnClick, onNewQueryToolClick, onResetLayout}) { connectionList, onConnectionChange, onNewConnClick, onNewQueryToolClick, onResetLayout, containerRef}) {
const classes = useStyles(); const classes = useStyles();
const connMenuRef = React.useRef(); const connMenuRef = React.useRef();
const [connDropdownOpen, setConnDropdownOpen] = React.useState(false); const [connDropdownOpen, setConnDropdownOpen] = React.useState(false);
@ -91,6 +93,15 @@ export function ConnectionBar({connected, connecting, connectionStatus, connecti
e.keepOpen = false; e.keepOpen = false;
}; };
useKeyboardShortcuts([
{
shortcut: queryToolCtx.preferences?.browser?.sub_menu_query_tool,
options: {
callback: onNewQueryToolClick
}
},
], containerRef);
const connTitle = React.useMemo(()=>_.find(connectionList, (c)=>c.is_selected)?.conn_title, [connectionList]); const connTitle = React.useMemo(()=>_.find(connectionList, (c)=>c.is_selected)?.conn_title, [connectionList]);
return ( return (
<> <>
@ -111,7 +122,8 @@ export function ConnectionBar({connected, connecting, connectionStatus, connecti
</Box> </Box>
</Tooltip> </Tooltip>
</DefaultButton> </DefaultButton>
<PgIconButton title={gettext('New query tool for current connection')} icon={<QueryToolIcon />} onClick={onNewQueryToolClick}/> <PgIconButton title={gettext('New query tool for current connection')} icon={<QueryToolIcon />}
shortcut={queryToolCtx.preferences?.browser?.sub_menu_query_tool} onClick={onNewQueryToolClick}/>
</PgButtonGroup> </PgButtonGroup>
<PgButtonGroup size="small" variant="text" style={{marginLeft: 'auto'}}> <PgButtonGroup size="small" variant="text" style={{marginLeft: 'auto'}}>
<PgIconButton title={gettext('Reset layout')} icon={<RotateLeftRoundedIcon />} onClick={onResetLayout}/> <PgIconButton title={gettext('Reset layout')} icon={<RotateLeftRoundedIcon />} onClick={onResetLayout}/>
@ -145,4 +157,5 @@ ConnectionBar.propTypes = {
onNewConnClick: PropTypes.func, onNewConnClick: PropTypes.func,
onNewQueryToolClick: PropTypes.func, onNewQueryToolClick: PropTypes.func,
onResetLayout: PropTypes.func, onResetLayout: PropTypes.func,
containerRef: CustomPropTypes.ref,
}; };

View File

@ -240,6 +240,7 @@ export default function Query() {
const eventBus = useContext(QueryToolEventsContext); const eventBus = useContext(QueryToolEventsContext);
const queryToolCtx = useContext(QueryToolContext); const queryToolCtx = useContext(QueryToolContext);
const layoutEvenBus = useContext(LayoutEventsContext); const layoutEvenBus = useContext(LayoutEventsContext);
const lastCursorPos = React.useRef();
const lastSavedText = React.useRef(''); const lastSavedText = React.useRef('');
const markedLine = React.useRef(0); const markedLine = React.useRef(0);
const marker = React.useRef(); const marker = React.useRef();
@ -470,7 +471,16 @@ export default function Query() {
} }
}); });
editor.current.focus(); const lastFocus = ()=>{
editor.current.focus();
if(lastCursorPos.current) {
editor.current.setCursor(lastCursorPos.current.line, lastCursorPos.current.ch);
}
};
eventBus.registerListener(QUERY_TOOL_EVENTS.EDITOR_LAST_FOCUS, lastFocus);
setTimeout(()=>{
editor.current.focus();
}, 250);
}, []); }, []);
useEffect(()=>{ useEffect(()=>{
@ -483,6 +493,7 @@ export default function Query() {
const cursorActivity = useCallback((cmObj)=>{ const cursorActivity = useCallback((cmObj)=>{
const c = cmObj.getCursor(); const c = cmObj.getCursor();
lastCursorPos.current = c;
eventBus.fireEvent(QUERY_TOOL_EVENTS.CURSOR_ACTIVITY, [c.line+1, c.ch+1]); eventBus.fireEvent(QUERY_TOOL_EVENTS.CURSOR_ACTIVITY, [c.line+1, c.ch+1]);
}, []); }, []);

View File

@ -123,6 +123,19 @@ export function ResultSetToolbar({containerRef, canEdit, totalRowCount}) {
return ()=>eventBus.deregisterListener(QUERY_TOOL_EVENTS.TRIGGER_COPY_DATA, copyData); return ()=>eventBus.deregisterListener(QUERY_TOOL_EVENTS.TRIGGER_COPY_DATA, copyData);
}, [checkedMenuItems['copy_with_headers']]); }, [checkedMenuItems['copy_with_headers']]);
const FIXED_PREF = {
copy: {
'control': true,
ctrl_is_meta: true,
'shift': false,
'alt': false,
'key': {
'key_code': 67,
'char': 'C',
},
},
};
useKeyboardShortcuts([ useKeyboardShortcuts([
{ {
shortcut: queryToolPref.save_data, shortcut: queryToolPref.save_data,
@ -145,7 +158,7 @@ export function ResultSetToolbar({containerRef, canEdit, totalRowCount}) {
<PgIconButton title={gettext('Add row')} icon={<PlaylistAddRoundedIcon style={{height: 'unset'}}/>} <PgIconButton title={gettext('Add row')} icon={<PlaylistAddRoundedIcon style={{height: 'unset'}}/>}
accesskey={shortcut_key(queryToolPref.btn_add_row)} disabled={!canEdit} onClick={addRow} /> accesskey={shortcut_key(queryToolPref.btn_add_row)} disabled={!canEdit} onClick={addRow} />
<PgIconButton title={gettext('Copy')} icon={<FileCopyRoundedIcon />} <PgIconButton title={gettext('Copy')} icon={<FileCopyRoundedIcon />}
accesskey={shortcut_key(queryToolPref.btn_copy_row)} disabled={buttonsDisabled['copy-rows']} onClick={copyData} /> shortcut={FIXED_PREF.copy} disabled={buttonsDisabled['copy-rows']} onClick={copyData} />
<PgIconButton title={gettext('Copy options')} icon={<KeyboardArrowDownIcon />} splitButton <PgIconButton title={gettext('Copy options')} icon={<KeyboardArrowDownIcon />} splitButton
name="menu-copyheader" ref={copyMenuRef} onClick={openMenu} /> name="menu-copyheader" ref={copyMenuRef} onClick={openMenu} />
<PgIconButton title={gettext('Paste')} icon={<PasteIcon />} <PgIconButton title={gettext('Paste')} icon={<PasteIcon />}

View File

@ -521,19 +521,6 @@ def register_query_tool_preferences(self):
fields=accesskey_fields fields=accesskey_fields
) )
self.preference.register(
'keyboard_shortcuts', 'btn_copy_row',
gettext('Accesskey (Copy rows)'), 'keyboardshortcut',
{
'key': {
'key_code': 67,
'char': 'c'
}
},
category_label=PREF_LABEL_KEYBOARD_SHORTCUTS,
fields=accesskey_fields
)
self.preference.register( self.preference.register(
'keyboard_shortcuts', 'btn_paste_row', 'keyboard_shortcuts', 'btn_paste_row',
gettext('Accesskey (Paste rows)'), 'keyboardshortcut', gettext('Accesskey (Paste rows)'), 'keyboardshortcut',