mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Fixed SonarQube code smells.
This commit is contained in:
parent
ad34ee2699
commit
5866da8194
@ -4,7 +4,7 @@ Version 8.9
|
|||||||
|
|
||||||
Release date: 2024-06-27
|
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
|
Supported Database Servers
|
||||||
**************************
|
**************************
|
||||||
@ -19,8 +19,8 @@ Bundled PostgreSQL Utilities
|
|||||||
|
|
||||||
New features
|
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
|
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 #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 #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 #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 #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.
|
||||||
|
@ -165,9 +165,8 @@ export default class CollationSchema extends BaseUISchema {
|
|||||||
else {
|
else {
|
||||||
if (actionObj.oldState.is_deterministic) {
|
if (actionObj.oldState.is_deterministic) {
|
||||||
return { is_deterministic: false };
|
return { is_deterministic: false };
|
||||||
} else {
|
|
||||||
return { is_deterministic: true };
|
|
||||||
}
|
}
|
||||||
|
return { is_deterministic: true };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -825,7 +825,7 @@ class PackageView(PGChildNodeView, SchemaDiffObjectCompare):
|
|||||||
if sql is None:
|
if sql is None:
|
||||||
return None
|
return None
|
||||||
start = 0
|
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:
|
if start_position:
|
||||||
start = start_position.start() + 4
|
start = start_position.start() + 4
|
||||||
|
@ -582,7 +582,7 @@ class EdbFuncView(PGChildNodeView, DataTypeReader):
|
|||||||
if sql is None:
|
if sql is None:
|
||||||
return None
|
return None
|
||||||
start = 0
|
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:
|
if start_position:
|
||||||
start = start_position.start() + 4
|
start = start_position.start() + 4
|
||||||
|
@ -128,10 +128,7 @@ export default class CompoundTriggerSchema extends BaseUISchema {
|
|||||||
}
|
}
|
||||||
// Enable column only if update event is set true
|
// Enable column only if update event is set true
|
||||||
let isUpdate = state.evnt_update;
|
let isUpdate = state.evnt_update;
|
||||||
if(!_.isUndefined(isUpdate) && isUpdate) {
|
return !(!_.isUndefined(isUpdate) && isUpdate);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
readonly: function(state) { return !obj.isNew(state); },
|
readonly: function(state) { return !obj.isNew(state); },
|
||||||
},{
|
},{
|
||||||
|
@ -402,7 +402,7 @@ define('pgadmin.node.table', [
|
|||||||
handle_cache: function() {
|
handle_cache: function() {
|
||||||
// Clear Table's cache as column's type is dependent on two node
|
// Clear Table's cache as column's type is dependent on two node
|
||||||
// 1) Type node 2) Domain node
|
// 1) Type node 2) Domain node
|
||||||
this.clear_cache.apply(this, null);
|
this.clear_cache(...null);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -521,13 +521,13 @@ def parse_rule_definition(res):
|
|||||||
# Parse data for condition
|
# Parse data for condition
|
||||||
condition = ''
|
condition = ''
|
||||||
condition_part_match = re.search(
|
condition_part_match = re.search(
|
||||||
r"((?:ON)\s+(?:[\s\S]+?)"
|
r"(ON\s+[\s\S]+?"
|
||||||
r"(?:TO)\s+(?:[\s\S]+?)(?:DO))", data_def)
|
r"TO\s+[\s\S]+?DO)", data_def)
|
||||||
if condition_part_match is not None:
|
if condition_part_match is not None:
|
||||||
condition_part = condition_part_match.group(1)
|
condition_part = condition_part_match.group(1)
|
||||||
|
|
||||||
condition_match = re.search(
|
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:
|
if condition_match is not None:
|
||||||
condition = condition_match.group(1)
|
condition = condition_match.group(1)
|
||||||
@ -537,7 +537,7 @@ def parse_rule_definition(res):
|
|||||||
|
|
||||||
# Parse data for statements
|
# Parse data for statements
|
||||||
statement_match = re.search(
|
statement_match = re.search(
|
||||||
r"(?:DO\s+)(?:INSTEAD\s+)?([\s\S]*)(?:;)", data_def)
|
r"DO\s+(?:INSTEAD\s+)?([\s\S]*);", data_def)
|
||||||
|
|
||||||
statement = ''
|
statement = ''
|
||||||
if statement_match is not None:
|
if statement_match is not None:
|
||||||
|
@ -62,7 +62,6 @@
|
|||||||
|
|
||||||
.wizard {
|
.wizard {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
/*height: 550px;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.step {
|
.step {
|
||||||
|
@ -25,7 +25,7 @@ export function AzureCredentials(props) {
|
|||||||
|
|
||||||
let _eventBus = React.useContext(CloudWizardEventsContext);
|
let _eventBus = React.useContext(CloudWizardEventsContext);
|
||||||
React.useMemo(() => {
|
React.useMemo(() => {
|
||||||
const azureCloudDBCredSchema = new AzureCredSchema({
|
const azureCloudDBCredSchema = new AzureCredSchema(_eventBus, {
|
||||||
authenticateAzure:(auth_type, azure_tenant_id) => {
|
authenticateAzure:(auth_type, azure_tenant_id) => {
|
||||||
let loading_icon_url = url_for(
|
let loading_icon_url = url_for(
|
||||||
'static', { 'filename': 'img/loading.gif'}
|
'static', { 'filename': 'img/loading.gif'}
|
||||||
@ -77,7 +77,7 @@ export function AzureCredentials(props) {
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, {}, _eventBus);
|
}, {});
|
||||||
setCloudDBCredInstance(azureCloudDBCredSchema);
|
setCloudDBCredInstance(azureCloudDBCredSchema);
|
||||||
}, [props.cloudProvider]);
|
}, [props.cloudProvider]);
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ import { isEmptyString } from 'sources/validators';
|
|||||||
import pgAdmin from 'sources/pgadmin';
|
import pgAdmin from 'sources/pgadmin';
|
||||||
|
|
||||||
class AzureCredSchema extends BaseUISchema {
|
class AzureCredSchema extends BaseUISchema {
|
||||||
constructor(fieldOptions = {}, initValues = {}, eventBus) {
|
constructor(eventBus, fieldOptions = {}, initValues = {}) {
|
||||||
super({
|
super({
|
||||||
oid: null,
|
oid: null,
|
||||||
auth_type: 'interactive_browser_credential',
|
auth_type: 'interactive_browser_credential',
|
||||||
|
@ -8,12 +8,13 @@
|
|||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
import { Box } from '@mui/material';
|
import { Box } from '@mui/material';
|
||||||
import { styled } from '@mui/material/styles';
|
import { styled } from '@mui/material/styles';
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { PrimaryButton } from './components/Buttons';
|
import { PrimaryButton } from './components/Buttons';
|
||||||
import { PgMenu, PgMenuDivider, PgMenuItem, PgSubMenu } from './components/Menu';
|
import { PgMenu, PgMenuDivider, PgMenuItem, PgSubMenu } from './components/Menu';
|
||||||
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
||||||
import AccountCircleRoundedIcon from '@mui/icons-material/AccountCircleRounded';
|
import AccountCircleRoundedIcon from '@mui/icons-material/AccountCircleRounded';
|
||||||
import { usePgAdmin } from '../../static/js/BrowserComponent';
|
import { usePgAdmin } from '../../static/js/BrowserComponent';
|
||||||
|
import { useForceUpdate } from './custom_hooks';
|
||||||
|
|
||||||
|
|
||||||
const StyledBox = styled(Box)(({theme}) => ({
|
const StyledBox = styled(Box)(({theme}) => ({
|
||||||
@ -39,7 +40,7 @@ const StyledBox = styled(Box)(({theme}) => ({
|
|||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
gap: '2px',
|
gap: '2px',
|
||||||
marginLeft: '16px',
|
marginLeft: '16px',
|
||||||
|
|
||||||
'& .MuiButton-containedPrimary': {
|
'& .MuiButton-containedPrimary': {
|
||||||
padding: '1px 8px',
|
padding: '1px 8px',
|
||||||
}
|
}
|
||||||
@ -59,17 +60,15 @@ const StyledBox = styled(Box)(({theme}) => ({
|
|||||||
|
|
||||||
export default function AppMenuBar() {
|
export default function AppMenuBar() {
|
||||||
|
|
||||||
const [,setRefresh] = useState(false);
|
const forceUpdate = useForceUpdate();
|
||||||
const pgAdmin = usePgAdmin();
|
const pgAdmin = usePgAdmin();
|
||||||
|
|
||||||
const reRenderMenus = ()=>setRefresh((prev)=>!prev);
|
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
pgAdmin.Browser.Events.on('pgadmin:nw-enable-disable-menu-items', _.debounce(()=>{
|
pgAdmin.Browser.Events.on('pgadmin:nw-enable-disable-menu-items', _.debounce(()=>{
|
||||||
reRenderMenus();
|
forceUpdate();
|
||||||
}, 100));
|
}, 100));
|
||||||
pgAdmin.Browser.Events.on('pgadmin:nw-refresh-menu-item', _.debounce(()=>{
|
pgAdmin.Browser.Events.on('pgadmin:nw-refresh-menu-item', _.debounce(()=>{
|
||||||
reRenderMenus();
|
forceUpdate();
|
||||||
}, 100));
|
}, 100));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@ -85,7 +84,7 @@ export default function AppMenuBar() {
|
|||||||
onClick={()=>{
|
onClick={()=>{
|
||||||
menuItem.callback();
|
menuItem.callback();
|
||||||
if(hasCheck) {
|
if(hasCheck) {
|
||||||
reRenderMenus();
|
forceUpdate();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
hasCheck={hasCheck}
|
hasCheck={hasCheck}
|
||||||
|
@ -23,7 +23,7 @@ export default function UrlDialogContent({ url, helpFile, onClose }) {
|
|||||||
return (
|
return (
|
||||||
<ModalContent>
|
<ModalContent>
|
||||||
<Box flexGrow="1">
|
<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();
|
e.target?.contentWindow?.focus();
|
||||||
}}/>
|
}}/>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -17,6 +17,7 @@ export default function HiddenIframe({id, srcURL, onLoad}) {
|
|||||||
<iframe
|
<iframe
|
||||||
id={id}
|
id={id}
|
||||||
src={srcURL}
|
src={srcURL}
|
||||||
|
title=" "
|
||||||
onLoad={onLoad}
|
onLoad={onLoad}
|
||||||
width={'20'}
|
width={'20'}
|
||||||
height={'20'}
|
height={'20'}
|
||||||
|
@ -430,12 +430,14 @@ const sessDataReducer = (state, action)=>{
|
|||||||
data = getDepChange(action.path, data, state, action);
|
data = getDepChange(action.path, data, state, action);
|
||||||
break;
|
break;
|
||||||
case SCHEMA_STATE_ACTIONS.MOVE_ROW:
|
case SCHEMA_STATE_ACTIONS.MOVE_ROW:
|
||||||
|
{
|
||||||
rows = _.get(data, action.path)||[];
|
rows = _.get(data, action.path)||[];
|
||||||
var row = rows[action.oldIndex];
|
let row = rows[action.oldIndex];
|
||||||
rows.splice(action.oldIndex, 1);
|
rows.splice(action.oldIndex, 1);
|
||||||
rows.splice(action.newIndex, 0, row);
|
rows.splice(action.newIndex, 0, row);
|
||||||
_.set(data, action.path, rows);
|
_.set(data, action.path, rows);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case SCHEMA_STATE_ACTIONS.CLEAR_DEFERRED_QUEUE:
|
case SCHEMA_STATE_ACTIONS.CLEAR_DEFERRED_QUEUE:
|
||||||
data.__deferred__ = [];
|
data.__deferred__ = [];
|
||||||
break;
|
break;
|
||||||
|
@ -818,7 +818,7 @@ function OptionView({ image, imageUrl, label }) {
|
|||||||
return (
|
return (
|
||||||
<Root>
|
<Root>
|
||||||
{image && <span className={'Form-optionIcon ' + image}></span>}
|
{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>
|
<span>{label}</span>
|
||||||
</Root>
|
</Root>
|
||||||
);
|
);
|
||||||
|
@ -84,7 +84,7 @@ export default function KeyboardShortcuts({ value, onChange, fields, name }) {
|
|||||||
{hasKeys &&
|
{hasKeys &&
|
||||||
<>
|
<>
|
||||||
<ToggleButtonGroup value={value?.shift ? ['shift'] : []} onChange={(e, val)=>{
|
<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} />
|
<ToggleCheckButton value="shift" label={gettext('Shift')} selected={value?.shift} />
|
||||||
</ToggleButtonGroup>
|
</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'} />}
|
{isMac() && <ToggleCheckButton value="ctrl_is_meta" label={gettext('Cmd')} selected={ctrlValue == 'ctrl_is_meta'} />}
|
||||||
</ToggleButtonGroup>
|
</ToggleButtonGroup>
|
||||||
<ToggleButtonGroup value={value?.alt ? ['alt'] : []} onChange={(e, val)=>{
|
<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} />
|
<ToggleCheckButton value="alt" label={isMac() ? gettext('Option') : gettext('Alt')} selected={value?.alt} />
|
||||||
</ToggleButtonGroup>
|
</ToggleButtonGroup>
|
||||||
@ -112,4 +112,4 @@ KeyboardShortcuts.propTypes = {
|
|||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
fields: PropTypes.array,
|
fields: PropTypes.array,
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
// This software is released under the PostgreSQL Licence
|
// 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 ReactDataGrid, { Row } from 'react-data-grid';
|
||||||
import { Box } from '@mui/material';
|
import { Box } from '@mui/material';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
@ -108,7 +108,7 @@ export function CustomRow({inTest=false, ...props}) {
|
|||||||
}
|
}
|
||||||
}, [props.selectedCellIdx]);
|
}, [props.selectedCellIdx]);
|
||||||
if(inTest) {
|
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)=>{
|
const onRowClick = (...args)=>{
|
||||||
gridUtils.onItemClick?.(props.rowIdx);
|
gridUtils.onItemClick?.(props.rowIdx);
|
||||||
@ -135,8 +135,9 @@ export default function PgReactDataGrid({gridRef, className, hasSelectColumn=tru
|
|||||||
hasSelectColumn && finalClassName.push('ReactGrid-hasSelectColumn');
|
hasSelectColumn && finalClassName.push('ReactGrid-hasSelectColumn');
|
||||||
props.enableCellSelect && finalClassName.push('ReactGrid-cellSelection');
|
props.enableCellSelect && finalClassName.push('ReactGrid-cellSelection');
|
||||||
finalClassName.push(className);
|
finalClassName.push(className);
|
||||||
|
const valObj = useMemo(() => ({onItemEnter, onItemSelect, onItemClick}), [onItemEnter, onItemSelect, onItemClick]);
|
||||||
return (
|
return (
|
||||||
<GridContextUtils.Provider value={{onItemEnter, onItemSelect, onItemClick}}>
|
<GridContextUtils.Provider value={valObj}>
|
||||||
<StyledReactDataGrid
|
<StyledReactDataGrid
|
||||||
ref={gridRef}
|
ref={gridRef}
|
||||||
className={finalClassName.join(' ')}
|
className={finalClassName.join(' ')}
|
||||||
|
@ -120,7 +120,7 @@ export default function Privilege({value, onChange, controlProps}) {
|
|||||||
return (
|
return (
|
||||||
<Root>
|
<Root>
|
||||||
<InputText value={textValue} readOnly/>
|
<InputText value={textValue} readOnly/>
|
||||||
<table className={'Privilege-table priv-table'} tabIndex="0">
|
<table className={'Privilege-table priv-table'} tabIndex="-1">
|
||||||
{(realVal.length > 1) && <thead>
|
{(realVal.length > 1) && <thead>
|
||||||
<tr>
|
<tr>
|
||||||
<td className='Privilege-tableCell'>
|
<td className='Privilege-tableCell'>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
// This software is released under the PostgreSQL Licence
|
// 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 moment from 'moment';
|
||||||
import { isMac } from './keyboard_shortcuts';
|
import { isMac } from './keyboard_shortcuts';
|
||||||
|
|
||||||
@ -205,3 +205,7 @@ export function useWindowSize() {
|
|||||||
}, []);
|
}, []);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useForceUpdate() {
|
||||||
|
return React.useReducer(() => ({}), {})[1];
|
||||||
|
}
|
||||||
|
@ -61,7 +61,7 @@ export default function LayoutIframeTab({target, src, children}) {
|
|||||||
if(r) setIframeTarget(r.querySelector('#'+target));
|
if(r) setIframeTarget(r.querySelector('#'+target));
|
||||||
}} container={document.querySelector('#layout-portal')}>
|
}} container={document.querySelector('#layout-portal')}>
|
||||||
{src ?
|
{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}}>
|
<Frame src={src} id={target} style={{position: 'fixed', border: 0}}>
|
||||||
{children}
|
{children}
|
||||||
</Frame>
|
</Frame>
|
||||||
|
@ -592,7 +592,7 @@ export function pgHandleItemError(error, args) {
|
|||||||
|
|
||||||
export function fullHexColor(shortHex) {
|
export function fullHexColor(shortHex) {
|
||||||
if(shortHex?.length == 4) {
|
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;
|
return shortHex;
|
||||||
}
|
}
|
||||||
|
@ -315,16 +315,7 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug,
|
|||||||
let myObj = [];
|
let myObj = [];
|
||||||
for (let i = 0; i < argType.length; i++) {
|
for (let i = 0; i < argType.length; i++) {
|
||||||
let useDefValue = checkIsDefault(defValList[i]);
|
let useDefValue = checkIsDefault(defValList[i]);
|
||||||
if (debuggerInfo['proargmodes'] == null) {
|
if (debuggerInfo['proargmodes'] == null || (argMode?.[i] == 'i' || argMode?.[i] == 'b' || (isEdbProc && argMode?.[i] == 'o'))) {
|
||||||
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'))) {
|
|
||||||
myObj.push({
|
myObj.push({
|
||||||
'name': myargname[i],
|
'name': myargname[i],
|
||||||
'type': argType[i],
|
'type': argType[i],
|
||||||
|
@ -141,10 +141,10 @@ export default class ERDTool extends React.Component {
|
|||||||
|
|
||||||
this.eventBus = new EventBus();
|
this.eventBus = new EventBus();
|
||||||
|
|
||||||
_.bindAll(this, ['onLoadDiagram', 'onSaveDiagram', 'onSaveAsDiagram', 'onSQLClick',
|
_.bindAll(this, ['onLoadDiagram', 'onSaveDiagram', 'onSQLClick',
|
||||||
'onImageClick', 'onAddNewNode', 'onEditTable', 'onCloneNode', 'onDeleteNode', 'onNoteClick',
|
'onImageClick', 'onAddNewNode', 'onEditTable', 'onCloneNode', 'onDeleteNode', 'onNoteClick',
|
||||||
'onNoteClose', 'onOneToManyClick', 'onManyToManyClick', 'onAutoDistribute', 'onDetailsToggle',
|
'onNoteClose', 'onOneToManyClick', 'onManyToManyClick', 'onAutoDistribute', 'onDetailsToggle',
|
||||||
'onChangeColors', 'onHelpClick', 'onDropNode', 'onBeforeUnload', 'onNotationChange',
|
'onChangeColors', 'onDropNode', 'onBeforeUnload', 'onNotationChange',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this.diagram.zoomToFit = this.diagram.zoomToFit.bind(this.diagram);
|
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});
|
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() {
|
onLoadDiagram() {
|
||||||
const params = {
|
const params = {
|
||||||
'supported_types': ['*','pgerd'], // file types allowed
|
'supported_types': ['*','pgerd'], // file types allowed
|
||||||
@ -622,10 +612,6 @@ export default class ERDTool extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onSaveAsDiagram() {
|
|
||||||
this.onSaveDiagram(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
saveFile(fileName) {
|
saveFile(fileName) {
|
||||||
this.setLoading(gettext('Saving...'));
|
this.setLoading(gettext('Saving...'));
|
||||||
this.apiObj.post(url_for('sqleditor.save_file'), {
|
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 = {
|
ERDTool.propTypes = {
|
||||||
params:PropTypes.shape({
|
params:PropTypes.shape({
|
||||||
trans_id: PropTypes.number.isRequired,
|
trans_id: PropTypes.number.isRequired,
|
||||||
@ -965,7 +949,6 @@ ERDTool.propTypes = {
|
|||||||
pgAdmin: PropTypes.object.isRequired,
|
pgAdmin: PropTypes.object.isRequired,
|
||||||
panelId: PropTypes.string,
|
panelId: PropTypes.string,
|
||||||
panelDocker: PropTypes.object,
|
panelDocker: PropTypes.object,
|
||||||
classes: PropTypes.object,
|
|
||||||
isTest: PropTypes.bool,
|
isTest: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ export class TableNodeModel extends DefaultNodeModel {
|
|||||||
function RowIcon({icon}) {
|
function RowIcon({icon}) {
|
||||||
return (
|
return (
|
||||||
<div style={{padding: '0rem 0.125rem'}}>
|
<div style={{padding: '0rem 0.125rem'}}>
|
||||||
<img src={icon} crossOrigin="anonymous"/>
|
<img src={icon} alt="" crossOrigin="anonymous"/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -275,7 +275,7 @@ export class TableNodeWidget extends React.Component {
|
|||||||
if(col.attlen) {
|
if(col.attlen) {
|
||||||
cltype += '('+ col.attlen + (col.attprecision ? ',' + col.attprecision : '') +')';
|
cltype += '('+ col.attlen + (col.attprecision ? ',' + col.attprecision : '') +')';
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box className='TableNode-columnSection' key={col.attnum} data-test="column-row">
|
<Box className='TableNode-columnSection' key={col.attnum} data-test="column-row">
|
||||||
<Box marginRight="auto" padding="0" minHeight="0" display="flex" alignItems="center">
|
<Box marginRight="auto" padding="0" minHeight="0" display="flex" alignItems="center">
|
||||||
@ -364,8 +364,7 @@ export class TableNodeWidget extends React.Component {
|
|||||||
|
|
||||||
TableNodeWidget.propTypes = {
|
TableNodeWidget.propTypes = {
|
||||||
node: PropTypes.instanceOf(TableNodeModel),
|
node: PropTypes.instanceOf(TableNodeModel),
|
||||||
engine: PropTypes.instanceOf(DiagramEngine),
|
engine: PropTypes.instanceOf(DiagramEngine)
|
||||||
classes: PropTypes.object,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export class TableNodeFactory extends AbstractReactFactory {
|
export class TableNodeFactory extends AbstractReactFactory {
|
||||||
|
@ -55,7 +55,8 @@ class ERDTableView(BaseTableView, DataTypeReader):
|
|||||||
|
|
||||||
@BaseTableView.check_precondition
|
@BaseTableView.check_precondition
|
||||||
def traverse_related_tables(self, did=None, sid=None, scid=None,
|
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 = \
|
status, res = \
|
||||||
BaseTableView.fetch_tables(self, sid, did, scid, tid=tid,
|
BaseTableView.fetch_tables(self, sid, did, scid, tid=tid,
|
||||||
@ -64,6 +65,9 @@ class ERDTableView(BaseTableView, DataTypeReader):
|
|||||||
if not status:
|
if not status:
|
||||||
return status, res
|
return status, res
|
||||||
|
|
||||||
|
if related is None:
|
||||||
|
related = list()
|
||||||
|
|
||||||
related[tid] = res
|
related[tid] = res
|
||||||
# Max depth limit reached
|
# Max depth limit reached
|
||||||
if currdepth == maxdepth:
|
if currdepth == maxdepth:
|
||||||
|
@ -35,7 +35,7 @@ const StyledBox = styled(Box)(({theme}) => ({
|
|||||||
fontSize: '13px',
|
fontSize: '13px',
|
||||||
'--rdg-background-color': theme.palette.default.main,
|
'--rdg-background-color': theme.palette.default.main,
|
||||||
'--rdg-selection-color': theme.palette.primary.main,
|
'--rdg-selection-color': theme.palette.primary.main,
|
||||||
'& .ResultGridComponent-gridPanel': {
|
'& .ResultGridComponent-gridPanel': {
|
||||||
'--rdg-background-color': theme.palette.default.main + ' !important',
|
'--rdg-background-color': theme.palette.default.main + ' !important',
|
||||||
'&.ResultGridComponent-grid': {
|
'&.ResultGridComponent-grid': {
|
||||||
fontSize: '13px',
|
fontSize: '13px',
|
||||||
@ -256,8 +256,7 @@ CellExpanderFormatter.propTypes = {
|
|||||||
isCellSelected: PropTypes.bool,
|
isCellSelected: PropTypes.bool,
|
||||||
expanded: PropTypes.bool,
|
expanded: PropTypes.bool,
|
||||||
onCellExpand: PropTypes.func,
|
onCellExpand: PropTypes.func,
|
||||||
filterParams: PropTypes.array,
|
filterParams: PropTypes.array
|
||||||
classes: PropTypes.object
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,9 +78,7 @@ export function SchemaDiffButtonComponent({ sourceData, targetData, selectedRowI
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let isDisableComp = true;
|
let isDisableComp = true;
|
||||||
if (sourceData.sid != null && sourceData.did != null && targetData.sid != null && targetData.did != null) {
|
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)) {
|
if (!((sourceData.scid != null && targetData.scid == null) || (sourceData.scid == null && targetData.scid != null))) {
|
||||||
isDisableComp = true;
|
|
||||||
} else {
|
|
||||||
isDisableComp = false;
|
isDisableComp = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ const FIXED_PREF = {
|
|||||||
export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedNodeInfo, qtPanelDocker, qtPanelId, eventBusObj}) {
|
export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedNodeInfo, qtPanelDocker, qtPanelId, eventBusObj}) {
|
||||||
const containerRef = React.useRef(null);
|
const containerRef = React.useRef(null);
|
||||||
const preferencesStore = usePreferences();
|
const preferencesStore = usePreferences();
|
||||||
const [qtState, _setQtState] = useState({
|
const [qtState, setQtState] = useState({
|
||||||
preferences: {
|
preferences: {
|
||||||
browser: preferencesStore.getPreferencesForModule('browser'),
|
browser: preferencesStore.getPreferencesForModule('browser'),
|
||||||
sqleditor: {...preferencesStore.getPreferencesForModule('sqleditor'), ...FIXED_PREF},
|
sqleditor: {...preferencesStore.getPreferencesForModule('sqleditor'), ...FIXED_PREF},
|
||||||
@ -211,8 +211,8 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||||||
});
|
});
|
||||||
const [selectedText, setSelectedText] = useState('');
|
const [selectedText, setSelectedText] = useState('');
|
||||||
|
|
||||||
const setQtState = (state)=>{
|
const setQtStatePartial = (state)=>{
|
||||||
_setQtState((prev)=>({...prev,...evalFunc(null, state, prev)}));
|
setQtState((prev)=>({...prev,...evalFunc(null, state, prev)}));
|
||||||
};
|
};
|
||||||
const isDirtyRef = useRef(false); // usefull when conn change.
|
const isDirtyRef = useRef(false); // usefull when conn change.
|
||||||
const eventBus = useRef(eventBusObj || (new EventBus()));
|
const eventBus = useRef(eventBusObj || (new EventBus()));
|
||||||
@ -233,12 +233,12 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||||||
try {
|
try {
|
||||||
let {data: respData} = await fetchConnectionStatus(api, qtState.params.trans_id);
|
let {data: respData} = await fetchConnectionStatus(api, qtState.params.trans_id);
|
||||||
if(respData.data) {
|
if(respData.data) {
|
||||||
setQtState({
|
setQtStatePartial({
|
||||||
connected: true,
|
connected: true,
|
||||||
connection_status: respData.data.status,
|
connection_status: respData.data.status,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setQtState({
|
setQtStatePartial({
|
||||||
connected: false,
|
connected: false,
|
||||||
connection_status: null,
|
connection_status: null,
|
||||||
connection_status_msg: gettext('An unexpected error occurred - ensure you are logged into the application.')
|
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) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
setQtState({
|
setQtStatePartial({
|
||||||
connected: false,
|
connected: false,
|
||||||
connection_status: null,
|
connection_status: null,
|
||||||
connection_status_msg: parseApiError(error),
|
connection_status_msg: parseApiError(error),
|
||||||
@ -320,11 +320,11 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||||||
api.get(qtState.params.query_url)
|
api.get(qtState.params.query_url)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
eventBus.current.fireEvent(QUERY_TOOL_EVENTS.EDITOR_SET_SQL, res.data);
|
eventBus.current.fireEvent(QUERY_TOOL_EVENTS.EDITOR_SET_SQL, res.data);
|
||||||
setQtState({ editor_disabled: false });
|
setQtStatePartial({ editor_disabled: false });
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
eventBus.current.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, 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) {
|
} else if (qtState.params.sql_id) {
|
||||||
let sqlValue = localStorage.getItem(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) {
|
if (sqlValue) {
|
||||||
eventBus.current.fireEvent(QUERY_TOOL_EVENTS.EDITOR_SET_SQL, sqlValue);
|
eventBus.current.fireEvent(QUERY_TOOL_EVENTS.EDITOR_SET_SQL, sqlValue);
|
||||||
}
|
}
|
||||||
setQtState({ editor_disabled: false });
|
setQtStatePartial({ editor_disabled: false });
|
||||||
} else {
|
} 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
|
dbname: selectedConn.database_name
|
||||||
} : JSON.stringify(qtState.params.sql_filter))
|
} : JSON.stringify(qtState.params.sql_filter))
|
||||||
.then(()=>{
|
.then(()=>{
|
||||||
setQtState({
|
setQtStatePartial({
|
||||||
connected: true,
|
connected: true,
|
||||||
connected_once: true,
|
connected_once: true,
|
||||||
obtaining_conn: false,
|
obtaining_conn: false,
|
||||||
@ -379,7 +379,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||||||
initializeQueryTool();
|
initializeQueryTool();
|
||||||
})
|
})
|
||||||
.catch((kberr)=>{
|
.catch((kberr)=>{
|
||||||
setQtState({
|
setQtStatePartial({
|
||||||
connected: false,
|
connected: false,
|
||||||
obtaining_conn: false,
|
obtaining_conn: false,
|
||||||
});
|
});
|
||||||
@ -389,14 +389,14 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||||||
connectServerModal(error.response?.data?.result, (passwordData)=>{
|
connectServerModal(error.response?.data?.result, (passwordData)=>{
|
||||||
initializeQueryTool(passwordData.password);
|
initializeQueryTool(passwordData.password);
|
||||||
}, ()=>{
|
}, ()=>{
|
||||||
setQtState({
|
setQtStatePartial({
|
||||||
connected: false,
|
connected: false,
|
||||||
obtaining_conn: false,
|
obtaining_conn: false,
|
||||||
connection_status_msg: gettext('Not Connected'),
|
connection_status_msg: gettext('Not Connected'),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setQtState({
|
setQtStatePartial({
|
||||||
connected: false,
|
connected: false,
|
||||||
obtaining_conn: 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)=>{
|
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, ()=>{
|
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)=>{
|
qtPanelDocker.eventBus.registerListener(LAYOUT_EVENTS.ACTIVE, _.debounce((currentTabId)=>{
|
||||||
/* Focus the appropriate panel on visible */
|
/* Focus the appropriate panel on visible */
|
||||||
if(qtPanelId == currentTabId) {
|
if(qtPanelId == currentTabId) {
|
||||||
setQtState({is_visible: true});
|
setQtStatePartial({is_visible: true});
|
||||||
|
|
||||||
if(docker.current.isTabVisible(PANELS.QUERY)) {
|
if(docker.current.isTabVisible(PANELS.QUERY)) {
|
||||||
docker.current.focus(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);
|
eventBus.current.fireEvent(QUERY_TOOL_EVENTS.GOTO_LAST_SCROLL);
|
||||||
} else {
|
} else {
|
||||||
setQtState({is_visible: false});
|
setQtStatePartial({is_visible: false});
|
||||||
}
|
}
|
||||||
}, 100));
|
}, 100));
|
||||||
|
|
||||||
/* If the tab or window is not visible, applicable for open in new tab */
|
/* If the tab or window is not visible, applicable for open in new tab */
|
||||||
document.addEventListener('visibilitychange', function() {
|
document.addEventListener('visibilitychange', function() {
|
||||||
if(document.hidden) {
|
if(document.hidden) {
|
||||||
setQtState({is_visible: false});
|
setQtStatePartial({is_visible: false});
|
||||||
} else {
|
} else {
|
||||||
setQtState({is_visible: true});
|
setQtStatePartial({is_visible: true});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => usePreferences.subscribe(
|
useEffect(() => usePreferences.subscribe(
|
||||||
state => {
|
state => {
|
||||||
setQtState({preferences: {
|
setQtStatePartial({preferences: {
|
||||||
browser: state.getPreferencesForModule('browser'),
|
browser: state.getPreferencesForModule('browser'),
|
||||||
sqleditor: {...state.getPreferencesForModule('sqleditor'), ...FIXED_PREF},
|
sqleditor: {...state.getPreferencesForModule('sqleditor'), ...FIXED_PREF},
|
||||||
graphs: state.getPreferencesForModule('graphs'),
|
graphs: state.getPreferencesForModule('graphs'),
|
||||||
@ -550,7 +550,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
const fileDone = (fileName, success=true)=>{
|
const fileDone = (fileName, success=true)=>{
|
||||||
if(success) {
|
if(success) {
|
||||||
setQtState({
|
setQtStatePartial({
|
||||||
current_file: fileName,
|
current_file: fileName,
|
||||||
});
|
});
|
||||||
isDirtyRef.current = false;
|
isDirtyRef.current = false;
|
||||||
@ -648,7 +648,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||||||
let currConnected = qtState.connected;
|
let currConnected = qtState.connected;
|
||||||
|
|
||||||
const selectConn = (newConnData, connected=false, obtainingConn=true)=>{
|
const selectConn = (newConnData, connected=false, obtainingConn=true)=>{
|
||||||
setQtState((prevQtState)=>{
|
setQtStatePartial((prevQtState)=>{
|
||||||
let newConnList = [...prevQtState.connection_list];
|
let newConnList = [...prevQtState.connection_list];
|
||||||
/* If new, add to the list */
|
/* If new, add to the list */
|
||||||
if(isNew) {
|
if(isNew) {
|
||||||
@ -687,7 +687,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||||||
if(isNew) {
|
if(isNew) {
|
||||||
selectConn(connectionData);
|
selectConn(connectionData);
|
||||||
}
|
}
|
||||||
setQtState((prev)=>{
|
setQtStatePartial((prev)=>{
|
||||||
return {
|
return {
|
||||||
params: {
|
params: {
|
||||||
...prev.params,
|
...prev.params,
|
||||||
@ -807,7 +807,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||||||
id: 'manage-macros',
|
id: 'manage-macros',
|
||||||
title: gettext('Manage Macros'),
|
title: gettext('Manage Macros'),
|
||||||
content: <MacrosDialog onSave={(newMacros)=>{
|
content: <MacrosDialog onSave={(newMacros)=>{
|
||||||
setQtState((prev)=>{
|
setQtStatePartial((prev)=>{
|
||||||
return {
|
return {
|
||||||
params: {
|
params: {
|
||||||
...prev.params,
|
...prev.params,
|
||||||
@ -835,7 +835,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||||||
)
|
)
|
||||||
.then(({ data: respData }) => {
|
.then(({ data: respData }) => {
|
||||||
const filteredData = respData.filter(m => Boolean(m.name));
|
const filteredData = respData.filter(m => Boolean(m.name));
|
||||||
setQtState(prev => ({
|
setQtStatePartial(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
params: {
|
params: {
|
||||||
...prev.params,
|
...prev.params,
|
||||||
@ -877,7 +877,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||||||
preferences: qtState.preferences,
|
preferences: qtState.preferences,
|
||||||
mainContainerRef: containerRef,
|
mainContainerRef: containerRef,
|
||||||
editor_disabled: qtState.editor_disabled,
|
editor_disabled: qtState.editor_disabled,
|
||||||
toggleQueryTool: () => setQtState((prev)=>{
|
toggleQueryTool: () => setQtStatePartial((prev)=>{
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
params: {
|
params: {
|
||||||
@ -888,7 +888,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||||||
}),
|
}),
|
||||||
updateTitle: (title) => {
|
updateTitle: (title) => {
|
||||||
setPanelTitle(qtPanelDocker, qtPanelId, title, qtState, isDirtyRef.current);
|
setPanelTitle(qtPanelDocker, qtPanelId, title, qtState, isDirtyRef.current);
|
||||||
setQtState((prev) => {
|
setQtStatePartial((prev) => {
|
||||||
// Update connection Title
|
// Update connection Title
|
||||||
let newConnList = [...prev.connection_list];
|
let newConnList = [...prev.connection_list];
|
||||||
newConnList.forEach((conn) => {
|
newConnList.forEach((conn) => {
|
||||||
|
@ -132,7 +132,7 @@ function SelectAllHeaderRenderer({onAllRowsSelectionChange, isCellSelected}) {
|
|||||||
}, [isCellSelected]);
|
}, [isCellSelected]);
|
||||||
|
|
||||||
return <div ref={cellRef} style={{width: '100%', height: '100%'}} onClick={onClick}
|
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 = {
|
SelectAllHeaderRenderer.propTypes = {
|
||||||
onAllRowsSelectionChange: PropTypes.func,
|
onAllRowsSelectionChange: PropTypes.func,
|
||||||
|
@ -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){
|
if(!queryToolCtx.preferences.sqleditor.underline_query_cursor && queryToolCtx.preferences.sqleditor.underlined_query_execute_warning){
|
||||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTE_CURSOR_WARNING);
|
eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTE_CURSOR_WARNING);
|
||||||
} else {
|
} else {
|
||||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION,true);
|
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION, null, '', true);
|
||||||
}
|
}
|
||||||
}, [queryToolCtx.preferences.sqleditor]);
|
}, [queryToolCtx.preferences.sqleditor]);
|
||||||
const executeScript = useCallback(()=>{
|
const executeScript = useCallback(()=>{
|
||||||
@ -100,7 +100,7 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const explain = useCallback((analyze=false)=>{
|
const explain = useCallback((analyze=false)=>{
|
||||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION, false, {
|
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION, {
|
||||||
format: 'json',
|
format: 'json',
|
||||||
analyze: analyze,
|
analyze: analyze,
|
||||||
verbose: Boolean(checkedMenuItems['explain_verbose']),
|
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);
|
eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTION_START, 'ROLLBACK;', null, true);
|
||||||
};
|
};
|
||||||
const executeMacro = (m)=>{
|
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)=>{
|
const onLimitChange=(e)=>{
|
||||||
setLimit(e.target.value);
|
setLimit(e.target.value);
|
||||||
|
@ -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) {
|
if(queryToolCtx.params.is_query_tool) {
|
||||||
let external = null;
|
let external = null;
|
||||||
let query = editor.current?.getSelection();
|
let query = editor.current?.getSelection();
|
||||||
if(!_.isUndefined(macroSQL)) {
|
if(!_.isEmpty(macroSQL)) {
|
||||||
const regex = /\$SELECTION\$/gi;
|
const regex = /\$SELECTION\$/gi;
|
||||||
query = macroSQL.replace(regex, query);
|
query = macroSQL.replace(regex, query);
|
||||||
external = true;
|
external = true;
|
||||||
@ -445,7 +445,7 @@ export default function Query({onTextSelect}) {
|
|||||||
text={query}
|
text={query}
|
||||||
onContinue={(formData)=>{
|
onContinue={(formData)=>{
|
||||||
preferencesStore.setPreference(formData);
|
preferencesStore.setPreference(formData);
|
||||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION,true);
|
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION, null, '', true);
|
||||||
}}
|
}}
|
||||||
onClose={()=>{
|
onClose={()=>{
|
||||||
closeModal?.();
|
closeModal?.();
|
||||||
|
@ -15,7 +15,7 @@ import { SaveDataIcon, CommitIcon, RollbackIcon, ViewDataIcon } from '../../../.
|
|||||||
import { InputSwitch } from '../../../../../../static/js/components/FormComponents';
|
import { InputSwitch } from '../../../../../../static/js/components/FormComponents';
|
||||||
import CodeMirror from '../../../../../../static/js/components/ReactCodeMirror';
|
import CodeMirror from '../../../../../../static/js/components/ReactCodeMirror';
|
||||||
import { DefaultButton } from '../../../../../../static/js/components/Buttons';
|
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 Loader from 'sources/components/Loader';
|
||||||
import { LayoutDockerContext, LAYOUT_EVENTS } from '../../../../../../static/js/helpers/Layout';
|
import { LayoutDockerContext, LAYOUT_EVENTS } from '../../../../../../static/js/helpers/Layout';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
@ -377,7 +377,7 @@ export function QueryHistory() {
|
|||||||
const eventBus = React.useContext(QueryToolEventsContext);
|
const eventBus = React.useContext(QueryToolEventsContext);
|
||||||
const [selectedItemKey, setSelectedItemKey] = React.useState(1);
|
const [selectedItemKey, setSelectedItemKey] = React.useState(1);
|
||||||
const [showInternal, setShowInternal] = React.useState(true);
|
const [showInternal, setShowInternal] = React.useState(true);
|
||||||
const [, setRefresh] = React.useState(false);
|
const forceUpdate = useForceUpdate();
|
||||||
const [loaderText, setLoaderText] = React.useState('');
|
const [loaderText, setLoaderText] = React.useState('');
|
||||||
const selectedEntry = qhu.current.getEntry(selectedItemKey);
|
const selectedEntry = qhu.current.getEntry(selectedItemKey);
|
||||||
const layoutDocker = useContext(LayoutDockerContext);
|
const layoutDocker = useContext(LayoutDockerContext);
|
||||||
@ -425,7 +425,7 @@ export function QueryHistory() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
qhu.current.addEntry(h);
|
qhu.current.addEntry(h);
|
||||||
setRefresh((prev)=>!prev);
|
forceUpdate();
|
||||||
};
|
};
|
||||||
|
|
||||||
listRef.current?.focus();
|
listRef.current?.focus();
|
||||||
|
@ -87,13 +87,12 @@ def get_user_macros():
|
|||||||
data = []
|
data = []
|
||||||
|
|
||||||
for m in macros:
|
for m in macros:
|
||||||
key_label = (
|
key_label = ''
|
||||||
'Ctrl + ' + str(m[5])
|
if m[4] is True:
|
||||||
if m[4] is True
|
key_label = 'Ctrl + ' + str(m[5])
|
||||||
else 'Alt + ' + str(m[5])
|
elif m[5] is not None:
|
||||||
if m[5] is not None
|
key_label = 'Alt + ' + str(m[5])
|
||||||
else ''
|
|
||||||
)
|
|
||||||
data.append({'id': m[0], 'name': m[1], 'mid': m[2], 'key': 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,
|
'key_label': key_label, 'alt': 1 if m[3] else 0,
|
||||||
'control': 1 if m[4] else 0, 'key_code': m[6],
|
'control': 1 if m[4] else 0, 'key_code': m[6],
|
||||||
|
@ -54,7 +54,6 @@ class StartRunningQuery:
|
|||||||
can_edit = False
|
can_edit = False
|
||||||
can_filter = False
|
can_filter = False
|
||||||
notifies = None
|
notifies = None
|
||||||
trans_status = None
|
|
||||||
status = -1
|
status = -1
|
||||||
result = None
|
result = None
|
||||||
if transaction_object is not None and session_obj is not None:
|
if transaction_object is not None and session_obj is not None:
|
||||||
@ -103,8 +102,6 @@ class StartRunningQuery:
|
|||||||
|
|
||||||
# Get the notifies
|
# Get the notifies
|
||||||
notifies = conn.get_notifies()
|
notifies = conn.get_notifies()
|
||||||
trans_status = conn.transaction_status()
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
status = False
|
status = False
|
||||||
result = gettext(
|
result = gettext(
|
||||||
@ -161,10 +158,10 @@ class StartRunningQuery:
|
|||||||
self.logger.error(e)
|
self.logger.error(e)
|
||||||
return internal_server_error(errormsg=str(e))
|
return internal_server_error(errormsg=str(e))
|
||||||
|
|
||||||
_thread = pgAdminThread(target=asyn_exec_query,
|
_thread = QueryThread(target=asyn_exec_query,
|
||||||
args=(conn, sql, trans_obj, is_rollback_req,
|
args=(conn, sql, trans_obj, is_rollback_req,
|
||||||
current_app._get_current_object())
|
current_app._get_current_object())
|
||||||
)
|
)
|
||||||
_thread.start()
|
_thread.start()
|
||||||
_native_id = _thread.native_id if hasattr(_thread, 'native_id'
|
_native_id = _thread.native_id if hasattr(_thread, 'native_id'
|
||||||
) else _thread.ident
|
) else _thread.ident
|
||||||
@ -215,7 +212,7 @@ class StartRunningQuery:
|
|||||||
return grid_data[str(transaction_id)]
|
return grid_data[str(transaction_id)]
|
||||||
|
|
||||||
|
|
||||||
class pgAdminThread(Thread):
|
class QueryThread(Thread):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.app = current_app._get_current_object()
|
self.app = current_app._get_current_object()
|
||||||
|
@ -174,10 +174,10 @@ def register_binary_typecasters(connection):
|
|||||||
# The new classes can be registered globally, on a connection, on a cursor
|
# The new classes can be registered globally, on a connection, on a cursor
|
||||||
|
|
||||||
connection.adapters.register_loader(17,
|
connection.adapters.register_loader(17,
|
||||||
pgAdminByteaLoader)
|
ByteaLoader)
|
||||||
|
|
||||||
connection.adapters.register_loader(1001,
|
connection.adapters.register_loader(1001,
|
||||||
pgAdminByteaLoader)
|
ByteaLoader)
|
||||||
|
|
||||||
|
|
||||||
def register_array_to_string_typecasters(connection=None):
|
def register_array_to_string_typecasters(connection=None):
|
||||||
@ -194,7 +194,7 @@ def register_array_to_string_typecasters(connection=None):
|
|||||||
TextLoaderpgAdmin)
|
TextLoaderpgAdmin)
|
||||||
|
|
||||||
|
|
||||||
class pgAdminInetLoader(InetLoader):
|
class InetLoader(InetLoader):
|
||||||
def load(self, data):
|
def load(self, data):
|
||||||
if isinstance(data, memoryview):
|
if isinstance(data, memoryview):
|
||||||
data = bytes(data)
|
data = bytes(data)
|
||||||
@ -206,11 +206,11 @@ class pgAdminInetLoader(InetLoader):
|
|||||||
|
|
||||||
|
|
||||||
# The new classes can be registered globally, on a connection, on a cursor
|
# The new classes can be registered globally, on a connection, on a cursor
|
||||||
psycopg.adapters.register_loader("inet", pgAdminInetLoader)
|
psycopg.adapters.register_loader("inet", InetLoader)
|
||||||
psycopg.adapters.register_loader("cidr", pgAdminInetLoader)
|
psycopg.adapters.register_loader("cidr", InetLoader)
|
||||||
|
|
||||||
|
|
||||||
class pgAdminByteaLoader(Loader):
|
class ByteaLoader(Loader):
|
||||||
def load(self, data):
|
def load(self, data):
|
||||||
return 'binary data' if data is not None else None
|
return 'binary data' if data is not None else None
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ def suggest_type(full_text, text_before_cursor):
|
|||||||
return suggest_based_on_last_token(stmt.last_token, stmt)
|
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):
|
def _strip_named_query(txt):
|
||||||
@ -163,7 +163,7 @@ def _strip_named_query(txt):
|
|||||||
return 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):
|
def _find_function_body(text):
|
||||||
|
@ -77,8 +77,6 @@ class KeyboardShortcutFeatureTest(BaseFeatureTest):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
assert True, "Keyboard shortcut change is unsuccessful."
|
|
||||||
|
|
||||||
print("OK", file=sys.stderr)
|
print("OK", file=sys.stderr)
|
||||||
|
|
||||||
def _update_preferences(self):
|
def _update_preferences(self):
|
||||||
|
@ -60,7 +60,7 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
|
|||||||
self._update_preferences()
|
self._update_preferences()
|
||||||
db_id = test_utils.create_database(self.server, self.database_name)
|
db_id = test_utils.create_database(self.server, self.database_name)
|
||||||
if not db_id:
|
if not db_id:
|
||||||
self.assertTrue(False, "Database {} is not "
|
self.assertEqual(0, 1, "Database {} is not "
|
||||||
"created".format(self.database_name))
|
"created".format(self.database_name))
|
||||||
self.page.add_server(self.server)
|
self.page.add_server(self.server)
|
||||||
|
|
||||||
|
@ -132,9 +132,10 @@ CREATE TABLE public.nonintpkey
|
|||||||
self._perform_test_for_table('nonintpkey', data_local)
|
self._perform_test_for_table('nonintpkey', data_local)
|
||||||
except Exception:
|
except Exception:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
self.assertTrue(False, 'Exception occurred in run test '
|
self.assertEqual(0, 1,
|
||||||
'Validate Insert, Update operations in '
|
'Exception occurred in run test Validate '
|
||||||
'View/Edit data with given test data')
|
'Insert, Update operations in View/Edit data with'
|
||||||
|
' given test data')
|
||||||
|
|
||||||
def after(self):
|
def after(self):
|
||||||
self.page.remove_server(self.server)
|
self.page.remove_server(self.server)
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
import React, { useRef } from 'react';
|
import React, { useRef, useMemo } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import {DebuggerContext, DebuggerEventsContext} from '../../../pgadmin/tools/debugger/static/js/components/DebuggerComponent';
|
import {DebuggerContext, DebuggerEventsContext} from '../../../pgadmin/tools/debugger/static/js/components/DebuggerComponent';
|
||||||
@ -15,8 +15,9 @@ import { withBrowser } from '../genericFunctions';
|
|||||||
|
|
||||||
function MockDebuggerComponent({value, eventsvalue, children}) {
|
function MockDebuggerComponent({value, eventsvalue, children}) {
|
||||||
const containerRef = useRef();
|
const containerRef = useRef();
|
||||||
|
const valObj = useMemo(() => ({...value, containerRef: containerRef}), [value]);
|
||||||
return (
|
return (
|
||||||
<DebuggerContext.Provider value={{...value, containerRef: containerRef}}>
|
<DebuggerContext.Provider value={valObj}>
|
||||||
<DebuggerEventsContext.Provider value={eventsvalue}>
|
<DebuggerEventsContext.Provider value={eventsvalue}>
|
||||||
<div ref={containerRef} style={{width: '100%', height: '100%'}}>
|
<div ref={containerRef} style={{width: '100%', height: '100%'}}>
|
||||||
{children}
|
{children}
|
||||||
|
@ -190,8 +190,8 @@ describe('ERDCore', ()=>{
|
|||||||
|
|
||||||
it('serialize', ()=>{
|
it('serialize', ()=>{
|
||||||
let retVal = erdCoreObj.serialize();
|
let retVal = erdCoreObj.serialize();
|
||||||
expect(Object.prototype.hasOwnProperty.call(retVal,'version')).toBeTruthy();
|
expect(Object.hasOwn(retVal,'version')).toBeTruthy();
|
||||||
expect(Object.prototype.hasOwnProperty.call(retVal,'data')).toBeTruthy();
|
expect(Object.hasOwn(retVal,'data')).toBeTruthy();
|
||||||
expect(erdEngine.getModel().serialize).toHaveBeenCalled();
|
expect(erdEngine.getModel().serialize).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -7,13 +7,6 @@
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// define(function () {
|
|
||||||
// return {
|
|
||||||
// 'id': 'pgadmin4@pgadmin.org',
|
|
||||||
// 'current_auth_source': 'internal'
|
|
||||||
// };
|
|
||||||
// });
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
'id': 'pgadmin4@pgadmin.org',
|
'id': 'pgadmin4@pgadmin.org',
|
||||||
'current_auth_source': 'internal'
|
'current_auth_source': 'internal'
|
||||||
|
@ -25,6 +25,6 @@ export class FakeModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toJSON() {
|
toJSON() {
|
||||||
return Object.assign({}, this.values);
|
return {...this.values};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,8 +54,7 @@ def open_process_details(tester):
|
|||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
tester.page.find_by_css_selector(
|
tester.page.find_by_css_selector(
|
||||||
"div[data-test='processes'] "
|
"div[data-test='processes'] "
|
||||||
"div[role='row']:nth-child(1) "
|
"button[data-label='View details']:nth-child(1)").click()
|
||||||
"div[role='cell']:nth-child(3) button").click()
|
|
||||||
|
|
||||||
tester.page.wait_for_element_to_disappear(
|
tester.page.wait_for_element_to_disappear(
|
||||||
lambda driver: driver.find_element(
|
lambda driver: driver.find_element(
|
||||||
|
@ -193,10 +193,7 @@ let webpackShimConfig = {
|
|||||||
},
|
},
|
||||||
isBrowserNode: function(module) {
|
isBrowserNode: function(module) {
|
||||||
if (module.rawRequest === undefined) { return false; }
|
if (module.rawRequest === undefined) { return false; }
|
||||||
if(module.rawRequest.startsWith('pgadmin.node')) {
|
return module.rawRequest.startsWith('pgadmin.node');
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
matchModules: function(module, match_modules) {
|
matchModules: function(module, match_modules) {
|
||||||
if (module.rawRequest === undefined) { return false; }
|
if (module.rawRequest === undefined) { return false; }
|
||||||
|
Loading…
Reference in New Issue
Block a user