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 #7452pull/90/head
parent
c8ef4733d0
commit
306b184e11
|
@ -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.
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 || [],
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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]);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
|
@ -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 />}
|
||||||
|
|
|
@ -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',
|
||||||
|
|
Loading…
Reference in New Issue