Fixed SonarQube code smells.

pull/7579/head
Akshay Joshi 2024-06-13 18:48:02 +05:30
parent ad34ee2699
commit 5866da8194
45 changed files with 130 additions and 164 deletions

View File

@ -4,7 +4,7 @@ Version 8.9
Release date: 2024-06-27
This release contains a number of bug fixes and new features since the release of pgAdmin 4 v8.7.
This release contains a number of bug fixes and new features since the release of pgAdmin 4 v8.8.
Supported Database Servers
**************************
@ -19,8 +19,8 @@ Bundled PostgreSQL Utilities
New features
************
| `Issue #5932 <https://github.com/pgadmin-org/pgadmin4/issues/5932>`_ - Provide option to set theme based on OS theme preference.
| `Issue #5932 <https://github.com/pgadmin-org/pgadmin4/issues/5932>`_ - Provide option to set theme based on OS theme preference.
Housekeeping
************
@ -31,6 +31,11 @@ Bug fixes
*********
| `Issue #6357 <https://github.com/pgadmin-org/pgadmin4/issues/6357>`_ - Disable the query tool editor input if any SQL is being loaded to prevent users from typing.
| `Issue #7241 <https://github.com/pgadmin-org/pgadmin4/issues/7241>`_ - Fixed an issue where resizable data editors in query tool should not be allowed to resize beyond the app window bounds.
| `Issue #7295 <https://github.com/pgadmin-org/pgadmin4/issues/7295>`_ - Fixed new line indentation in query editor and add a user preference to disable it.
| `Issue #7306 <https://github.com/pgadmin-org/pgadmin4/issues/7306>`_ - Ensure that a user can connect to a server using SSL certificates and identity files from a shared storage.
| `Issue #7414 <https://github.com/pgadmin-org/pgadmin4/issues/7414>`_ - Add support for comments on RLS policy object.
| `Issue #7481 <https://github.com/pgadmin-org/pgadmin4/issues/7481>`_ - Fixed an issue where dark theme shows white background when all tabs are closed.
| `Issue #7516 <https://github.com/pgadmin-org/pgadmin4/issues/7516>`_ - Ensure preferences can be loaded using preferences.json.
| `Issue #7536 <https://github.com/pgadmin-org/pgadmin4/issues/7536>`_ - Search Objects dialog should focus on search input on open.
| `Issue #7555 <https://github.com/pgadmin-org/pgadmin4/issues/7555>`_ - Fixed an issue where query tool shortcuts for find/replace are not working.

View File

@ -165,9 +165,8 @@ export default class CollationSchema extends BaseUISchema {
else {
if (actionObj.oldState.is_deterministic) {
return { is_deterministic: false };
} else {
return { is_deterministic: true };
}
return { is_deterministic: true };
}
},
},

View File

@ -825,7 +825,7 @@ class PackageView(PGChildNodeView, SchemaDiffObjectCompare):
if sql is None:
return None
start = 0
start_position = re.search("\\s+[is|as]+\\s+", sql, flags=re.I)
start_position = re.search("\\s+(is|as)+\\s+", sql, flags=re.I)
if start_position:
start = start_position.start() + 4

View File

@ -582,7 +582,7 @@ class EdbFuncView(PGChildNodeView, DataTypeReader):
if sql is None:
return None
start = 0
start_position = re.search(r"\s+[is|as]+\s+", sql, flags=re.I)
start_position = re.search(r"\s+(is|as)+\s+", sql, flags=re.I)
if start_position:
start = start_position.start() + 4

View File

@ -128,10 +128,7 @@ export default class CompoundTriggerSchema extends BaseUISchema {
}
// Enable column only if update event is set true
let isUpdate = state.evnt_update;
if(!_.isUndefined(isUpdate) && isUpdate) {
return false;
}
return true;
return !(!_.isUndefined(isUpdate) && isUpdate);
},
readonly: function(state) { return !obj.isNew(state); },
},{

View File

@ -402,7 +402,7 @@ define('pgadmin.node.table', [
handle_cache: function() {
// Clear Table's cache as column's type is dependent on two node
// 1) Type node 2) Domain node
this.clear_cache.apply(this, null);
this.clear_cache(...null);
},
});
}

View File

@ -521,13 +521,13 @@ def parse_rule_definition(res):
# Parse data for condition
condition = ''
condition_part_match = re.search(
r"((?:ON)\s+(?:[\s\S]+?)"
r"(?:TO)\s+(?:[\s\S]+?)(?:DO))", data_def)
r"(ON\s+[\s\S]+?"
r"TO\s+[\s\S]+?DO)", data_def)
if condition_part_match is not None:
condition_part = condition_part_match.group(1)
condition_match = re.search(
r"(?:WHERE)\s+(\([\s\S]*\))\s+(?:DO)", condition_part)
r"WHERE\s+(\([\s\S]*\))\s+DO", condition_part)
if condition_match is not None:
condition = condition_match.group(1)
@ -537,7 +537,7 @@ def parse_rule_definition(res):
# Parse data for statements
statement_match = re.search(
r"(?:DO\s+)(?:INSTEAD\s+)?([\s\S]*)(?:;)", data_def)
r"DO\s+(?:INSTEAD\s+)?([\s\S]*);", data_def)
statement = ''
if statement_match is not None:

View File

@ -62,7 +62,6 @@
.wizard {
width: 100%;
/*height: 550px;*/
}
.step {

View File

@ -25,7 +25,7 @@ export function AzureCredentials(props) {
let _eventBus = React.useContext(CloudWizardEventsContext);
React.useMemo(() => {
const azureCloudDBCredSchema = new AzureCredSchema({
const azureCloudDBCredSchema = new AzureCredSchema(_eventBus, {
authenticateAzure:(auth_type, azure_tenant_id) => {
let loading_icon_url = url_for(
'static', { 'filename': 'img/loading.gif'}
@ -77,7 +77,7 @@ export function AzureCredentials(props) {
}, 1000);
});
}
}, {}, _eventBus);
}, {});
setCloudDBCredInstance(azureCloudDBCredSchema);
}, [props.cloudProvider]);

View File

@ -13,7 +13,7 @@ import { isEmptyString } from 'sources/validators';
import pgAdmin from 'sources/pgadmin';
class AzureCredSchema extends BaseUISchema {
constructor(fieldOptions = {}, initValues = {}, eventBus) {
constructor(eventBus, fieldOptions = {}, initValues = {}) {
super({
oid: null,
auth_type: 'interactive_browser_credential',

View File

@ -8,12 +8,13 @@
//////////////////////////////////////////////////////////////
import { Box } from '@mui/material';
import { styled } from '@mui/material/styles';
import React, { useState, useEffect } from 'react';
import React, { useEffect } from 'react';
import { PrimaryButton } from './components/Buttons';
import { PgMenu, PgMenuDivider, PgMenuItem, PgSubMenu } from './components/Menu';
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
import AccountCircleRoundedIcon from '@mui/icons-material/AccountCircleRounded';
import { usePgAdmin } from '../../static/js/BrowserComponent';
import { useForceUpdate } from './custom_hooks';
const StyledBox = styled(Box)(({theme}) => ({
@ -39,7 +40,7 @@ const StyledBox = styled(Box)(({theme}) => ({
alignItems: 'center',
gap: '2px',
marginLeft: '16px',
'& .MuiButton-containedPrimary': {
padding: '1px 8px',
}
@ -59,17 +60,15 @@ const StyledBox = styled(Box)(({theme}) => ({
export default function AppMenuBar() {
const [,setRefresh] = useState(false);
const forceUpdate = useForceUpdate();
const pgAdmin = usePgAdmin();
const reRenderMenus = ()=>setRefresh((prev)=>!prev);
useEffect(()=>{
pgAdmin.Browser.Events.on('pgadmin:nw-enable-disable-menu-items', _.debounce(()=>{
reRenderMenus();
forceUpdate();
}, 100));
pgAdmin.Browser.Events.on('pgadmin:nw-refresh-menu-item', _.debounce(()=>{
reRenderMenus();
forceUpdate();
}, 100));
}, []);
@ -85,7 +84,7 @@ export default function AppMenuBar() {
onClick={()=>{
menuItem.callback();
if(hasCheck) {
reRenderMenus();
forceUpdate();
}
}}
hasCheck={hasCheck}

View File

@ -23,7 +23,7 @@ export default function UrlDialogContent({ url, helpFile, onClose }) {
return (
<ModalContent>
<Box flexGrow="1">
<iframe src={url} width="100%" height="100%" onLoad={(e)=>{
<iframe src={url} title=" " width="100%" height="100%" onLoad={(e)=>{
e.target?.contentWindow?.focus();
}}/>
</Box>

View File

@ -17,6 +17,7 @@ export default function HiddenIframe({id, srcURL, onLoad}) {
<iframe
id={id}
src={srcURL}
title=" "
onLoad={onLoad}
width={'20'}
height={'20'}

View File

@ -430,12 +430,14 @@ const sessDataReducer = (state, action)=>{
data = getDepChange(action.path, data, state, action);
break;
case SCHEMA_STATE_ACTIONS.MOVE_ROW:
{
rows = _.get(data, action.path)||[];
var row = rows[action.oldIndex];
let row = rows[action.oldIndex];
rows.splice(action.oldIndex, 1);
rows.splice(action.newIndex, 0, row);
_.set(data, action.path, rows);
break;
}
case SCHEMA_STATE_ACTIONS.CLEAR_DEFERRED_QUEUE:
data.__deferred__ = [];
break;

View File

@ -818,7 +818,7 @@ function OptionView({ image, imageUrl, label }) {
return (
<Root>
{image && <span className={'Form-optionIcon ' + image}></span>}
{imageUrl && <img style={{height: '20px', marginRight: '4px'}} src={imageUrl} />}
{imageUrl && <img style={{height: '20px', marginRight: '4px'}} src={imageUrl} alt="" />}
<span>{label}</span>
</Root>
);

View File

@ -84,7 +84,7 @@ export default function KeyboardShortcuts({ value, onChange, fields, name }) {
{hasKeys &&
<>
<ToggleButtonGroup value={value?.shift ? ['shift'] : []} onChange={(e, val)=>{
onChangeButton('shift', val.length == 0 ? false : true);
onChangeButton('shift', val.length != 0 );
}}>
<ToggleCheckButton value="shift" label={gettext('Shift')} selected={value?.shift} />
</ToggleButtonGroup>
@ -93,7 +93,7 @@ export default function KeyboardShortcuts({ value, onChange, fields, name }) {
{isMac() && <ToggleCheckButton value="ctrl_is_meta" label={gettext('Cmd')} selected={ctrlValue == 'ctrl_is_meta'} />}
</ToggleButtonGroup>
<ToggleButtonGroup value={value?.alt ? ['alt'] : []} onChange={(e, val)=>{
onChangeButton('alt', val.length == 0 ? false : true);
onChangeButton('alt', val.length != 0);
}}>
<ToggleCheckButton value="alt" label={isMac() ? gettext('Option') : gettext('Alt')} selected={value?.alt} />
</ToggleButtonGroup>
@ -112,4 +112,4 @@ KeyboardShortcuts.propTypes = {
onChange: PropTypes.func,
fields: PropTypes.array,
name: PropTypes.string,
};
};

View File

@ -6,7 +6,7 @@
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import React, { useContext, useEffect } from 'react';
import React, { useContext, useEffect, useMemo } from 'react';
import ReactDataGrid, { Row } from 'react-data-grid';
import { Box } from '@mui/material';
import PropTypes from 'prop-types';
@ -108,7 +108,7 @@ export function CustomRow({inTest=false, ...props}) {
}
}, [props.selectedCellIdx]);
if(inTest) {
return <div data-test='test-div' tabIndex={0} onKeyDown={handleKeyDown}></div>;
return <div data-test='test-div' tabIndex={-1} onKeyDown={handleKeyDown}></div>;
}
const onRowClick = (...args)=>{
gridUtils.onItemClick?.(props.rowIdx);
@ -135,8 +135,9 @@ export default function PgReactDataGrid({gridRef, className, hasSelectColumn=tru
hasSelectColumn && finalClassName.push('ReactGrid-hasSelectColumn');
props.enableCellSelect && finalClassName.push('ReactGrid-cellSelection');
finalClassName.push(className);
const valObj = useMemo(() => ({onItemEnter, onItemSelect, onItemClick}), [onItemEnter, onItemSelect, onItemClick]);
return (
<GridContextUtils.Provider value={{onItemEnter, onItemSelect, onItemClick}}>
<GridContextUtils.Provider value={valObj}>
<StyledReactDataGrid
ref={gridRef}
className={finalClassName.join(' ')}

View File

@ -120,7 +120,7 @@ export default function Privilege({value, onChange, controlProps}) {
return (
<Root>
<InputText value={textValue} readOnly/>
<table className={'Privilege-table priv-table'} tabIndex="0">
<table className={'Privilege-table priv-table'} tabIndex="-1">
{(realVal.length > 1) && <thead>
<tr>
<td className='Privilege-tableCell'>

View File

@ -6,7 +6,7 @@
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import {useRef, useEffect, useState, useCallback, useLayoutEffect} from 'react';
import React, {useRef, useEffect, useState, useCallback, useLayoutEffect} from 'react';
import moment from 'moment';
import { isMac } from './keyboard_shortcuts';
@ -205,3 +205,7 @@ export function useWindowSize() {
}, []);
return size;
}
export function useForceUpdate() {
return React.useReducer(() => ({}), {})[1];
}

View File

@ -61,7 +61,7 @@ export default function LayoutIframeTab({target, src, children}) {
if(r) setIframeTarget(r.querySelector('#'+target));
}} container={document.querySelector('#layout-portal')}>
{src ?
<iframe src={src} id={target} style={{position: 'fixed', border: 0}} />:
<iframe src={src} title=" " id={target} style={{position: 'fixed', border: 0}} />:
<Frame src={src} id={target} style={{position: 'fixed', border: 0}}>
{children}
</Frame>

View File

@ -592,7 +592,7 @@ export function pgHandleItemError(error, args) {
export function fullHexColor(shortHex) {
if(shortHex?.length == 4) {
return shortHex.replace(RegExp('#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])'), '#$1$1$2$2$3$3').toUpperCase();
return shortHex.replace(/#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/, '#$1$1$2$2$3$3').toUpperCase();
}
return shortHex;
}

View File

@ -315,16 +315,7 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug,
let myObj = [];
for (let i = 0; i < argType.length; i++) {
let useDefValue = checkIsDefault(defValList[i]);
if (debuggerInfo['proargmodes'] == null) {
myObj.push({
'name': myargname[i],
'type': argType[i],
'use_default': useDefValue,
'default_value': defValList[i],
'disable_use_default': defValList[i] == DEBUGGER_ARGS.NO_DEFAULT_VALUE,
});
} else if (argMode && (argMode[i] == 'i' || argMode[i] == 'b' ||
(isEdbProc && argMode[i] == 'o'))) {
if (debuggerInfo['proargmodes'] == null || (argMode?.[i] == 'i' || argMode?.[i] == 'b' || (isEdbProc && argMode?.[i] == 'o'))) {
myObj.push({
'name': myargname[i],
'type': argType[i],

View File

@ -141,10 +141,10 @@ export default class ERDTool extends React.Component {
this.eventBus = new EventBus();
_.bindAll(this, ['onLoadDiagram', 'onSaveDiagram', 'onSaveAsDiagram', 'onSQLClick',
_.bindAll(this, ['onLoadDiagram', 'onSaveDiagram', 'onSQLClick',
'onImageClick', 'onAddNewNode', 'onEditTable', 'onCloneNode', 'onDeleteNode', 'onNoteClick',
'onNoteClose', 'onOneToManyClick', 'onManyToManyClick', 'onAutoDistribute', 'onDetailsToggle',
'onChangeColors', 'onHelpClick', 'onDropNode', 'onBeforeUnload', 'onNotationChange',
'onChangeColors', 'onDropNode', 'onBeforeUnload', 'onNotationChange',
]);
this.diagram.zoomToFit = this.diagram.zoomToFit.bind(this.diagram);
@ -568,16 +568,6 @@ export default class ERDTool extends React.Component {
this.setState({cardinality_notation: e.value});
}
onHelpClick() {
let url = url_for('help.static', {'filename': 'erd_tool.html'});
if (this.props.pgWindow) {
this.props.pgWindow.open(url, 'pgadmin_help');
}
else {
window.open(url, 'pgadmin_help');
}
}
onLoadDiagram() {
const params = {
'supported_types': ['*','pgerd'], // file types allowed
@ -622,10 +612,6 @@ export default class ERDTool extends React.Component {
}
}
onSaveAsDiagram() {
this.onSaveDiagram(true);
}
saveFile(fileName) {
this.setLoading(gettext('Saving...'));
this.apiObj.post(url_for('sqleditor.save_file'), {
@ -945,8 +931,6 @@ export default class ERDTool extends React.Component {
}
}
//export default withStyles(styles)(ERDTool);
ERDTool.propTypes = {
params:PropTypes.shape({
trans_id: PropTypes.number.isRequired,
@ -965,7 +949,6 @@ ERDTool.propTypes = {
pgAdmin: PropTypes.object.isRequired,
panelId: PropTypes.string,
panelDocker: PropTypes.object,
classes: PropTypes.object,
isTest: PropTypes.bool,
};

View File

@ -169,7 +169,7 @@ export class TableNodeModel extends DefaultNodeModel {
function RowIcon({icon}) {
return (
<div style={{padding: '0rem 0.125rem'}}>
<img src={icon} crossOrigin="anonymous"/>
<img src={icon} alt="" crossOrigin="anonymous"/>
</div>
);
}
@ -275,7 +275,7 @@ export class TableNodeWidget extends React.Component {
if(col.attlen) {
cltype += '('+ col.attlen + (col.attprecision ? ',' + col.attprecision : '') +')';
}
return (
<Box className='TableNode-columnSection' key={col.attnum} data-test="column-row">
<Box marginRight="auto" padding="0" minHeight="0" display="flex" alignItems="center">
@ -364,8 +364,7 @@ export class TableNodeWidget extends React.Component {
TableNodeWidget.propTypes = {
node: PropTypes.instanceOf(TableNodeModel),
engine: PropTypes.instanceOf(DiagramEngine),
classes: PropTypes.object,
engine: PropTypes.instanceOf(DiagramEngine)
};
export class TableNodeFactory extends AbstractReactFactory {

View File

@ -55,7 +55,8 @@ class ERDTableView(BaseTableView, DataTypeReader):
@BaseTableView.check_precondition
def traverse_related_tables(self, did=None, sid=None, scid=None,
tid=None, related={}, maxdepth=0, currdepth=0):
tid=None, related=None, maxdepth=0,
currdepth=0):
status, res = \
BaseTableView.fetch_tables(self, sid, did, scid, tid=tid,
@ -64,6 +65,9 @@ class ERDTableView(BaseTableView, DataTypeReader):
if not status:
return status, res
if related is None:
related = list()
related[tid] = res
# Max depth limit reached
if currdepth == maxdepth:

View File

@ -35,7 +35,7 @@ const StyledBox = styled(Box)(({theme}) => ({
fontSize: '13px',
'--rdg-background-color': theme.palette.default.main,
'--rdg-selection-color': theme.palette.primary.main,
'& .ResultGridComponent-gridPanel': {
'& .ResultGridComponent-gridPanel': {
'--rdg-background-color': theme.palette.default.main + ' !important',
'&.ResultGridComponent-grid': {
fontSize: '13px',
@ -256,8 +256,7 @@ CellExpanderFormatter.propTypes = {
isCellSelected: PropTypes.bool,
expanded: PropTypes.bool,
onCellExpand: PropTypes.func,
filterParams: PropTypes.array,
classes: PropTypes.object
filterParams: PropTypes.array
};

View File

@ -78,9 +78,7 @@ export function SchemaDiffButtonComponent({ sourceData, targetData, selectedRowI
useEffect(() => {
let isDisableComp = true;
if (sourceData.sid != null && sourceData.did != null && targetData.sid != null && targetData.did != null) {
if ((sourceData.scid != null && targetData.scid == null) || (sourceData.scid == null && targetData.scid != null)) {
isDisableComp = true;
} else {
if (!((sourceData.scid != null && targetData.scid == null) || (sourceData.scid == null && targetData.scid != null))) {
isDisableComp = false;
}
}

View File

@ -169,7 +169,7 @@ const FIXED_PREF = {
export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedNodeInfo, qtPanelDocker, qtPanelId, eventBusObj}) {
const containerRef = React.useRef(null);
const preferencesStore = usePreferences();
const [qtState, _setQtState] = useState({
const [qtState, setQtState] = useState({
preferences: {
browser: preferencesStore.getPreferencesForModule('browser'),
sqleditor: {...preferencesStore.getPreferencesForModule('sqleditor'), ...FIXED_PREF},
@ -211,8 +211,8 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
});
const [selectedText, setSelectedText] = useState('');
const setQtState = (state)=>{
_setQtState((prev)=>({...prev,...evalFunc(null, state, prev)}));
const setQtStatePartial = (state)=>{
setQtState((prev)=>({...prev,...evalFunc(null, state, prev)}));
};
const isDirtyRef = useRef(false); // usefull when conn change.
const eventBus = useRef(eventBusObj || (new EventBus()));
@ -233,12 +233,12 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
try {
let {data: respData} = await fetchConnectionStatus(api, qtState.params.trans_id);
if(respData.data) {
setQtState({
setQtStatePartial({
connected: true,
connection_status: respData.data.status,
});
} else {
setQtState({
setQtStatePartial({
connected: false,
connection_status: null,
connection_status_msg: gettext('An unexpected error occurred - ensure you are logged into the application.')
@ -249,7 +249,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
}
} catch (error) {
console.error(error);
setQtState({
setQtStatePartial({
connected: false,
connection_status: null,
connection_status_msg: parseApiError(error),
@ -320,11 +320,11 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
api.get(qtState.params.query_url)
.then((res) => {
eventBus.current.fireEvent(QUERY_TOOL_EVENTS.EDITOR_SET_SQL, res.data);
setQtState({ editor_disabled: false });
setQtStatePartial({ editor_disabled: false });
})
.catch((err) => {
eventBus.current.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, err);
setQtState({ editor_disabled: true });
setQtStatePartial({ editor_disabled: true });
});
} else if (qtState.params.sql_id) {
let sqlValue = localStorage.getItem(qtState.params.sql_id);
@ -332,9 +332,9 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
if (sqlValue) {
eventBus.current.fireEvent(QUERY_TOOL_EVENTS.EDITOR_SET_SQL, sqlValue);
}
setQtState({ editor_disabled: false });
setQtStatePartial({ editor_disabled: false });
} else {
setQtState({ editor_disabled: false });
setQtStatePartial({ editor_disabled: false });
}
};
@ -363,7 +363,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
dbname: selectedConn.database_name
} : JSON.stringify(qtState.params.sql_filter))
.then(()=>{
setQtState({
setQtStatePartial({
connected: true,
connected_once: true,
obtaining_conn: false,
@ -379,7 +379,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
initializeQueryTool();
})
.catch((kberr)=>{
setQtState({
setQtStatePartial({
connected: false,
obtaining_conn: false,
});
@ -389,14 +389,14 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
connectServerModal(error.response?.data?.result, (passwordData)=>{
initializeQueryTool(passwordData.password);
}, ()=>{
setQtState({
setQtStatePartial({
connected: false,
obtaining_conn: false,
connection_status_msg: gettext('Not Connected'),
});
});
} else {
setQtState({
setQtStatePartial({
connected: false,
obtaining_conn: false,
});
@ -414,7 +414,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
});
eventBus.current.registerListener(QUERY_TOOL_EVENTS.SET_CONNECTION_STATUS, (status)=>{
setQtState({connection_status: status});
setQtStatePartial({connection_status: status});
});
eventBus.current.registerListener(QUERY_TOOL_EVENTS.FORCE_CLOSE_PANEL, ()=>{
@ -431,7 +431,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
qtPanelDocker.eventBus.registerListener(LAYOUT_EVENTS.ACTIVE, _.debounce((currentTabId)=>{
/* Focus the appropriate panel on visible */
if(qtPanelId == currentTabId) {
setQtState({is_visible: true});
setQtStatePartial({is_visible: true});
if(docker.current.isTabVisible(PANELS.QUERY)) {
docker.current.focus(PANELS.QUERY);
@ -441,23 +441,23 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
eventBus.current.fireEvent(QUERY_TOOL_EVENTS.GOTO_LAST_SCROLL);
} else {
setQtState({is_visible: false});
setQtStatePartial({is_visible: false});
}
}, 100));
/* If the tab or window is not visible, applicable for open in new tab */
document.addEventListener('visibilitychange', function() {
if(document.hidden) {
setQtState({is_visible: false});
setQtStatePartial({is_visible: false});
} else {
setQtState({is_visible: true});
setQtStatePartial({is_visible: true});
}
});
}, []);
useEffect(() => usePreferences.subscribe(
state => {
setQtState({preferences: {
setQtStatePartial({preferences: {
browser: state.getPreferencesForModule('browser'),
sqleditor: {...state.getPreferencesForModule('sqleditor'), ...FIXED_PREF},
graphs: state.getPreferencesForModule('graphs'),
@ -550,7 +550,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
useEffect(()=>{
const fileDone = (fileName, success=true)=>{
if(success) {
setQtState({
setQtStatePartial({
current_file: fileName,
});
isDirtyRef.current = false;
@ -648,7 +648,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
let currConnected = qtState.connected;
const selectConn = (newConnData, connected=false, obtainingConn=true)=>{
setQtState((prevQtState)=>{
setQtStatePartial((prevQtState)=>{
let newConnList = [...prevQtState.connection_list];
/* If new, add to the list */
if(isNew) {
@ -687,7 +687,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
if(isNew) {
selectConn(connectionData);
}
setQtState((prev)=>{
setQtStatePartial((prev)=>{
return {
params: {
...prev.params,
@ -807,7 +807,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
id: 'manage-macros',
title: gettext('Manage Macros'),
content: <MacrosDialog onSave={(newMacros)=>{
setQtState((prev)=>{
setQtStatePartial((prev)=>{
return {
params: {
...prev.params,
@ -835,7 +835,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
)
.then(({ data: respData }) => {
const filteredData = respData.filter(m => Boolean(m.name));
setQtState(prev => ({
setQtStatePartial(prev => ({
...prev,
params: {
...prev.params,
@ -877,7 +877,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
preferences: qtState.preferences,
mainContainerRef: containerRef,
editor_disabled: qtState.editor_disabled,
toggleQueryTool: () => setQtState((prev)=>{
toggleQueryTool: () => setQtStatePartial((prev)=>{
return {
...prev,
params: {
@ -888,7 +888,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
}),
updateTitle: (title) => {
setPanelTitle(qtPanelDocker, qtPanelId, title, qtState, isDirtyRef.current);
setQtState((prev) => {
setQtStatePartial((prev) => {
// Update connection Title
let newConnList = [...prev.connection_list];
newConnList.forEach((conn) => {

View File

@ -132,7 +132,7 @@ function SelectAllHeaderRenderer({onAllRowsSelectionChange, isCellSelected}) {
}, [isCellSelected]);
return <div ref={cellRef} style={{width: '100%', height: '100%'}} onClick={onClick}
tabIndex="0" onKeyDown={getCopyShortcutHandler(dataGridExtras.handleCopy)}></div>;
tabIndex="-1" onKeyDown={getCopyShortcutHandler(dataGridExtras.handleCopy)}></div>;
}
SelectAllHeaderRenderer.propTypes = {
onAllRowsSelectionChange: PropTypes.func,

View File

@ -89,7 +89,7 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
if(!queryToolCtx.preferences.sqleditor.underline_query_cursor && queryToolCtx.preferences.sqleditor.underlined_query_execute_warning){
eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTE_CURSOR_WARNING);
} else {
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION,true);
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION, null, '', true);
}
}, [queryToolCtx.preferences.sqleditor]);
const executeScript = useCallback(()=>{
@ -100,7 +100,7 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
}, []);
const explain = useCallback((analyze=false)=>{
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION, false, {
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION, {
format: 'json',
analyze: analyze,
verbose: Boolean(checkedMenuItems['explain_verbose']),
@ -282,7 +282,7 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTION_START, 'ROLLBACK;', null, true);
};
const executeMacro = (m)=>{
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION,false, null, m.sql);
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION, null, m.sql);
};
const onLimitChange=(e)=>{
setLimit(e.target.value);

View File

@ -136,11 +136,11 @@ export default function Query({onTextSelect}) {
}
};
const triggerExecution = (executeCursor=false, explainObject, macroSQL)=>{
const triggerExecution = (explainObject, macroSQL, executeCursor=false)=>{
if(queryToolCtx.params.is_query_tool) {
let external = null;
let query = editor.current?.getSelection();
if(!_.isUndefined(macroSQL)) {
if(!_.isEmpty(macroSQL)) {
const regex = /\$SELECTION\$/gi;
query = macroSQL.replace(regex, query);
external = true;
@ -445,7 +445,7 @@ export default function Query({onTextSelect}) {
text={query}
onContinue={(formData)=>{
preferencesStore.setPreference(formData);
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION,true);
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION, null, '', true);
}}
onClose={()=>{
closeModal?.();

View File

@ -15,7 +15,7 @@ import { SaveDataIcon, CommitIcon, RollbackIcon, ViewDataIcon } from '../../../.
import { InputSwitch } from '../../../../../../static/js/components/FormComponents';
import CodeMirror from '../../../../../../static/js/components/ReactCodeMirror';
import { DefaultButton } from '../../../../../../static/js/components/Buttons';
import { useDelayedCaller } from '../../../../../../static/js/custom_hooks';
import { useDelayedCaller, useForceUpdate } from '../../../../../../static/js/custom_hooks';
import Loader from 'sources/components/Loader';
import { LayoutDockerContext, LAYOUT_EVENTS } from '../../../../../../static/js/helpers/Layout';
import PropTypes from 'prop-types';
@ -377,7 +377,7 @@ export function QueryHistory() {
const eventBus = React.useContext(QueryToolEventsContext);
const [selectedItemKey, setSelectedItemKey] = React.useState(1);
const [showInternal, setShowInternal] = React.useState(true);
const [, setRefresh] = React.useState(false);
const forceUpdate = useForceUpdate();
const [loaderText, setLoaderText] = React.useState('');
const selectedEntry = qhu.current.getEntry(selectedItemKey);
const layoutDocker = useContext(LayoutDockerContext);
@ -425,7 +425,7 @@ export function QueryHistory() {
};
}
qhu.current.addEntry(h);
setRefresh((prev)=>!prev);
forceUpdate();
};
listRef.current?.focus();

View File

@ -87,13 +87,12 @@ def get_user_macros():
data = []
for m in macros:
key_label = (
'Ctrl + ' + str(m[5])
if m[4] is True
else 'Alt + ' + str(m[5])
if m[5] is not None
else ''
)
key_label = ''
if m[4] is True:
key_label = 'Ctrl + ' + str(m[5])
elif m[5] is not None:
key_label = 'Alt + ' + str(m[5])
data.append({'id': m[0], 'name': m[1], 'mid': m[2], 'key': m[5],
'key_label': key_label, 'alt': 1 if m[3] else 0,
'control': 1 if m[4] else 0, 'key_code': m[6],

View File

@ -54,7 +54,6 @@ class StartRunningQuery:
can_edit = False
can_filter = False
notifies = None
trans_status = None
status = -1
result = None
if transaction_object is not None and session_obj is not None:
@ -103,8 +102,6 @@ class StartRunningQuery:
# Get the notifies
notifies = conn.get_notifies()
trans_status = conn.transaction_status()
else:
status = False
result = gettext(
@ -161,10 +158,10 @@ class StartRunningQuery:
self.logger.error(e)
return internal_server_error(errormsg=str(e))
_thread = pgAdminThread(target=asyn_exec_query,
args=(conn, sql, trans_obj, is_rollback_req,
current_app._get_current_object())
)
_thread = QueryThread(target=asyn_exec_query,
args=(conn, sql, trans_obj, is_rollback_req,
current_app._get_current_object())
)
_thread.start()
_native_id = _thread.native_id if hasattr(_thread, 'native_id'
) else _thread.ident
@ -215,7 +212,7 @@ class StartRunningQuery:
return grid_data[str(transaction_id)]
class pgAdminThread(Thread):
class QueryThread(Thread):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.app = current_app._get_current_object()

View File

@ -174,10 +174,10 @@ def register_binary_typecasters(connection):
# The new classes can be registered globally, on a connection, on a cursor
connection.adapters.register_loader(17,
pgAdminByteaLoader)
ByteaLoader)
connection.adapters.register_loader(1001,
pgAdminByteaLoader)
ByteaLoader)
def register_array_to_string_typecasters(connection=None):
@ -194,7 +194,7 @@ def register_array_to_string_typecasters(connection=None):
TextLoaderpgAdmin)
class pgAdminInetLoader(InetLoader):
class InetLoader(InetLoader):
def load(self, data):
if isinstance(data, memoryview):
data = bytes(data)
@ -206,11 +206,11 @@ class pgAdminInetLoader(InetLoader):
# The new classes can be registered globally, on a connection, on a cursor
psycopg.adapters.register_loader("inet", pgAdminInetLoader)
psycopg.adapters.register_loader("cidr", pgAdminInetLoader)
psycopg.adapters.register_loader("inet", InetLoader)
psycopg.adapters.register_loader("cidr", InetLoader)
class pgAdminByteaLoader(Loader):
class ByteaLoader(Loader):
def load(self, data):
return 'binary data' if data is not None else None

View File

@ -148,7 +148,7 @@ def suggest_type(full_text, text_before_cursor):
return suggest_based_on_last_token(stmt.last_token, stmt)
named_query_regex = re.compile(r"^\s*\\ns\s+[A-z0-9\-_]+\s+")
named_query_regex = re.compile(r"^\s*\\ns\s+[A-z0-9\-]+\s+")
def _strip_named_query(txt):
@ -163,7 +163,7 @@ def _strip_named_query(txt):
return txt
function_body_pattern = re.compile(r"(\$.*?\$)([\s\S]*?)\1", re.M)
function_body_pattern = re.compile(r"(\$[^$]*\$)([\s\S]*?)\1", re.M)
def _find_function_body(text):

View File

@ -77,8 +77,6 @@ class KeyboardShortcutFeatureTest(BaseFeatureTest):
)
)
assert True, "Keyboard shortcut change is unsuccessful."
print("OK", file=sys.stderr)
def _update_preferences(self):

View File

@ -60,7 +60,7 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
self._update_preferences()
db_id = test_utils.create_database(self.server, self.database_name)
if not db_id:
self.assertTrue(False, "Database {} is not "
self.assertEqual(0, 1, "Database {} is not "
"created".format(self.database_name))
self.page.add_server(self.server)

View File

@ -132,9 +132,10 @@ CREATE TABLE public.nonintpkey
self._perform_test_for_table('nonintpkey', data_local)
except Exception:
traceback.print_exc()
self.assertTrue(False, 'Exception occurred in run test '
'Validate Insert, Update operations in '
'View/Edit data with given test data')
self.assertEqual(0, 1,
'Exception occurred in run test Validate '
'Insert, Update operations in View/Edit data with'
' given test data')
def after(self):
self.page.remove_server(self.server)

View File

@ -7,7 +7,7 @@
//
//////////////////////////////////////////////////////////////
import React, { useRef } from 'react';
import React, { useRef, useMemo } from 'react';
import PropTypes from 'prop-types';
import {DebuggerContext, DebuggerEventsContext} from '../../../pgadmin/tools/debugger/static/js/components/DebuggerComponent';
@ -15,8 +15,9 @@ import { withBrowser } from '../genericFunctions';
function MockDebuggerComponent({value, eventsvalue, children}) {
const containerRef = useRef();
const valObj = useMemo(() => ({...value, containerRef: containerRef}), [value]);
return (
<DebuggerContext.Provider value={{...value, containerRef: containerRef}}>
<DebuggerContext.Provider value={valObj}>
<DebuggerEventsContext.Provider value={eventsvalue}>
<div ref={containerRef} style={{width: '100%', height: '100%'}}>
{children}

View File

@ -190,8 +190,8 @@ describe('ERDCore', ()=>{
it('serialize', ()=>{
let retVal = erdCoreObj.serialize();
expect(Object.prototype.hasOwnProperty.call(retVal,'version')).toBeTruthy();
expect(Object.prototype.hasOwnProperty.call(retVal,'data')).toBeTruthy();
expect(Object.hasOwn(retVal,'version')).toBeTruthy();
expect(Object.hasOwn(retVal,'data')).toBeTruthy();
expect(erdEngine.getModel().serialize).toHaveBeenCalled();
});

View File

@ -7,13 +7,6 @@
//
//////////////////////////////////////////////////////////////////////////
// define(function () {
// return {
// 'id': 'pgadmin4@pgadmin.org',
// 'current_auth_source': 'internal'
// };
// });
module.exports = {
'id': 'pgadmin4@pgadmin.org',
'current_auth_source': 'internal'

View File

@ -25,6 +25,6 @@ export class FakeModel {
}
toJSON() {
return Object.assign({}, this.values);
return {...this.values};
}
}

View File

@ -54,8 +54,7 @@ def open_process_details(tester):
time.sleep(3)
tester.page.find_by_css_selector(
"div[data-test='processes'] "
"div[role='row']:nth-child(1) "
"div[role='cell']:nth-child(3) button").click()
"button[data-label='View details']:nth-child(1)").click()
tester.page.wait_for_element_to_disappear(
lambda driver: driver.find_element(

View File

@ -193,10 +193,7 @@ let webpackShimConfig = {
},
isBrowserNode: function(module) {
if (module.rawRequest === undefined) { return false; }
if(module.rawRequest.startsWith('pgadmin.node')) {
return true;
}
return false;
return module.rawRequest.startsWith('pgadmin.node');
},
matchModules: function(module, match_modules) {
if (module.rawRequest === undefined) { return false; }