mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Continue fixing multiple UI and SonarQube issues found when testing wcDocker changes. #6479
This commit is contained in:
@@ -207,8 +207,7 @@ Front End
|
|||||||
|
|
||||||
pgAdmin uses javascript extensively for the front-end implementation. It uses
|
pgAdmin uses javascript extensively for the front-end implementation. It uses
|
||||||
require.js to allow the lazy loading (or, say load only when required),
|
require.js to allow the lazy loading (or, say load only when required),
|
||||||
bootstrap and MaterialUI for UI look and feel, React for generating
|
ReactJS with CSS and MaterialUI for UI look and feel. We have
|
||||||
properties/create dialog for selected node. We have
|
|
||||||
divided each module in small chunks as much as possible. Not all javascript
|
divided each module in small chunks as much as possible. Not all javascript
|
||||||
modules are required to be loaded (i.e. loading a javascript module for
|
modules are required to be loaded (i.e. loading a javascript module for
|
||||||
database will make sense only when a server node is loaded completely.) Please
|
database will make sense only when a server node is loaded completely.) Please
|
||||||
|
|||||||
@@ -22,14 +22,12 @@ purpose or how it works if not obvious from a quick review of the code itself.
|
|||||||
CSS 3
|
CSS 3
|
||||||
*****
|
*****
|
||||||
|
|
||||||
CSS3 is used for styling and layout throughout the application. Extensive use is
|
CSS3 is used for styling and layout throughout the application.
|
||||||
made of the Bootstrap Framework to aid in that process, however additional
|
|
||||||
styles must still be created from time to time.
|
|
||||||
|
|
||||||
Most custom styling comes from individual modules which may advertise static
|
Most custom styling comes from individual modules which may advertise static
|
||||||
stylesheets to be included in the module that is loading them via hooks.
|
stylesheets to be included in the module that is loading them via hooks.
|
||||||
|
|
||||||
Styling overrides (for example, to alter the Bootstrap look and feel) will
|
Styling overrides (for example, to alter the look and feel) will
|
||||||
typically be found in the **overrides.css** file in the main static file
|
typically be found in the **overrides.css** file in the main static file
|
||||||
directory for the application.
|
directory for the application.
|
||||||
|
|
||||||
|
|||||||
@@ -5,3 +5,5 @@ logFilters:
|
|||||||
level: discard
|
level: discard
|
||||||
|
|
||||||
nodeLinker: node-modules
|
nodeLinker: node-modules
|
||||||
|
|
||||||
|
yarnPath: .yarn/releases/yarn-3.6.4.cjs
|
||||||
|
|||||||
@@ -230,8 +230,8 @@ PROXY_X_PREFIX_COUNT = 0
|
|||||||
|
|
||||||
# COMPRESSION
|
# COMPRESSION
|
||||||
COMPRESS_MIMETYPES = [
|
COMPRESS_MIMETYPES = [
|
||||||
'text/html', 'text/css', 'text/xml', 'application/json',
|
'text/html', 'text/css', 'text/xml', 'text/javascript',
|
||||||
'application/javascript'
|
'application/json', 'application/javascript'
|
||||||
]
|
]
|
||||||
COMPRESS_LEVEL = 9
|
COMPRESS_LEVEL = 9
|
||||||
COMPRESS_MIN_SIZE = 500
|
COMPRESS_MIN_SIZE = 500
|
||||||
|
|||||||
@@ -314,7 +314,6 @@ define('pgadmin.browser', [
|
|||||||
'pgadmin:server:disconnect', stop_heartbeat.bind(obj)
|
'pgadmin:server:disconnect', stop_heartbeat.bind(obj)
|
||||||
);
|
);
|
||||||
|
|
||||||
obj.set_master_password('');
|
|
||||||
obj.check_corrupted_db_file();
|
obj.check_corrupted_db_file();
|
||||||
obj.Events.on('pgadmin:browser:tree:add', obj.onAddTreeNode.bind(obj));
|
obj.Events.on('pgadmin:browser:tree:add', obj.onAddTreeNode.bind(obj));
|
||||||
obj.Events.on('pgadmin:browser:tree:update', obj.onUpdateTreeNode.bind(obj));
|
obj.Events.on('pgadmin:browser:tree:update', obj.onUpdateTreeNode.bind(obj));
|
||||||
@@ -328,6 +327,7 @@ define('pgadmin.browser', [
|
|||||||
obj.start_inactivity_timeout_daemon();
|
obj.start_inactivity_timeout_daemon();
|
||||||
},
|
},
|
||||||
uiloaded: function() {
|
uiloaded: function() {
|
||||||
|
this.set_master_password('');
|
||||||
this.check_version_update();
|
this.check_version_update();
|
||||||
},
|
},
|
||||||
check_corrupted_db_file: function() {
|
check_corrupted_db_file: function() {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import gettext from 'sources/gettext';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { makeStyles } from '@material-ui/core/styles';
|
import { makeStyles } from '@material-ui/core/styles';
|
||||||
import { BgProcessManagerEvents, BgProcessManagerProcessState } from './BgProcessConstants';
|
import { BgProcessManagerEvents, BgProcessManagerProcessState } from './BgProcessConstants';
|
||||||
import { PgIconButton } from '../../../../static/js/components/Buttons';
|
import { PgButtonGroup, PgIconButton } from '../../../../static/js/components/Buttons';
|
||||||
import CancelIcon from '@material-ui/icons/Cancel';
|
import CancelIcon from '@material-ui/icons/Cancel';
|
||||||
import DescriptionOutlinedIcon from '@material-ui/icons/DescriptionOutlined';
|
import DescriptionOutlinedIcon from '@material-ui/icons/DescriptionOutlined';
|
||||||
import DeleteIcon from '@material-ui/icons/Delete';
|
import DeleteIcon from '@material-ui/icons/Delete';
|
||||||
@@ -282,27 +282,27 @@ export default function Processes() {
|
|||||||
CustomHeader={()=>{
|
CustomHeader={()=>{
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<PgIconButton
|
<PgButtonGroup>
|
||||||
className={classes.dropButton}
|
<PgIconButton
|
||||||
icon={<DeleteIcon/>}
|
icon={<DeleteIcon style={{height: '1.4rem'}}/>}
|
||||||
aria-label="Acknowledge and Remove"
|
aria-label="Acknowledge and Remove"
|
||||||
title={gettext('Acknowledge and Remove')}
|
title={gettext('Acknowledge and Remove')}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
pgAdmin.Browser.notifier.confirm(gettext('Remove Processes'), gettext('Are you sure you want to remove the selected processes?'), ()=>{
|
pgAdmin.Browser.notifier.confirm(gettext('Remove Processes'), gettext('Are you sure you want to remove the selected processes?'), ()=>{
|
||||||
pgAdmin.Browser.BgProcessManager.acknowledge(selectedRows.map((p)=>p.original.id));
|
pgAdmin.Browser.BgProcessManager.acknowledge(selectedRows.map((p)=>p.original.id));
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
disabled={selectedRows.length <= 0}
|
disabled={selectedRows.length <= 0}
|
||||||
></PgIconButton>
|
></PgIconButton>
|
||||||
<PgIconButton
|
<PgIconButton
|
||||||
icon={<HelpIcon/>}
|
icon={<HelpIcon style={{height: '1.4rem'}}/>}
|
||||||
aria-label="Help"
|
aria-label="Help"
|
||||||
title={gettext('Help')}
|
title={gettext('Help')}
|
||||||
style={{marginLeft: '8px'}}
|
onClick={() => {
|
||||||
onClick={() => {
|
window.open(url_for('help.static', {'filename': 'processes.html'}));
|
||||||
window.open(url_for('help.static', {'filename': 'processes.html'}));
|
}}
|
||||||
}}
|
></PgIconButton>
|
||||||
></PgIconButton>
|
</PgButtonGroup>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -154,6 +154,7 @@ function Dependencies({ nodeData, nodeItem, node, treeNodeInfo, isActive, isStal
|
|||||||
if (message != '') {
|
if (message != '') {
|
||||||
setMsg(message);
|
setMsg(message);
|
||||||
setLoaderText('');
|
setLoaderText('');
|
||||||
|
setTableData([]);
|
||||||
}
|
}
|
||||||
setIsStale(false);
|
setIsStale(false);
|
||||||
}, [isActive, isStale]);
|
}, [isActive, isStale]);
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ function Dependents({ nodeData, nodeItem, node, treeNodeInfo, isActive, isStale,
|
|||||||
}
|
}
|
||||||
if (message != '') {
|
if (message != '') {
|
||||||
setLoaderText('');
|
setLoaderText('');
|
||||||
|
setTableData([]);
|
||||||
setMsg(message);
|
setMsg(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import gettext from 'sources/gettext';
|
|||||||
import PgTable from 'sources/components/PgTable';
|
import PgTable from 'sources/components/PgTable';
|
||||||
import Theme from 'sources/Theme';
|
import Theme from 'sources/Theme';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { PgIconButton } from '../../static/js/components/Buttons';
|
import { PgButtonGroup, PgIconButton } from '../../static/js/components/Buttons';
|
||||||
import DeleteIcon from '@material-ui/icons/Delete';
|
import DeleteIcon from '@material-ui/icons/Delete';
|
||||||
import DeleteSweepIcon from '@material-ui/icons/DeleteSweep';
|
import DeleteSweepIcon from '@material-ui/icons/DeleteSweep';
|
||||||
import DeleteForeverIcon from '@material-ui/icons/DeleteForever';
|
import DeleteForeverIcon from '@material-ui/icons/DeleteForever';
|
||||||
@@ -64,9 +64,6 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
overflow: 'hidden !important',
|
overflow: 'hidden !important',
|
||||||
overflowX: 'auto !important'
|
overflowX: 'auto !important'
|
||||||
},
|
},
|
||||||
dropButton: {
|
|
||||||
marginRight: '8px !important'
|
|
||||||
},
|
|
||||||
readOnlySwitch: {
|
readOnlySwitch: {
|
||||||
opacity: 0.75,
|
opacity: 0.75,
|
||||||
'& .MuiSwitch-track': {
|
'& .MuiSwitch-track': {
|
||||||
@@ -291,48 +288,47 @@ export default function CollectionNodeProperties({
|
|||||||
const canDropForce = evalFunc(node, node.canDropForce, nodeData, nodeItem, treeNodeInfo);
|
const canDropForce = evalFunc(node, node.canDropForce, nodeData, nodeItem, treeNodeInfo);
|
||||||
return (
|
return (
|
||||||
<Box >
|
<Box >
|
||||||
<PgIconButton
|
<PgButtonGroup size="small">
|
||||||
className={classes.dropButton}
|
|
||||||
icon={<DeleteIcon/>}
|
|
||||||
aria-label="Delete"
|
|
||||||
title={gettext('Delete')}
|
|
||||||
onClick={() => {
|
|
||||||
onDrop('drop');
|
|
||||||
}}
|
|
||||||
disabled={
|
|
||||||
(selectedObject.length > 0)
|
|
||||||
? !canDrop
|
|
||||||
: true
|
|
||||||
}
|
|
||||||
></PgIconButton>
|
|
||||||
{node.type !== 'coll-database' ? <PgIconButton
|
|
||||||
className={classes.dropButton}
|
|
||||||
icon={<DeleteSweepIcon />}
|
|
||||||
aria-label="Delete Cascade"
|
|
||||||
title={gettext('Delete (Cascade)')}
|
|
||||||
onClick={() => {
|
|
||||||
onDrop('dropCascade');
|
|
||||||
}}
|
|
||||||
disabled={
|
|
||||||
(selectedObject.length > 0)
|
|
||||||
? !canDropCascade
|
|
||||||
: true
|
|
||||||
}
|
|
||||||
></PgIconButton> :
|
|
||||||
<PgIconButton
|
<PgIconButton
|
||||||
className={classes.dropButton}
|
icon={<DeleteIcon style={{height: '1.35rem'}}/>}
|
||||||
icon={<DeleteForeverIcon />}
|
aria-label="Delete"
|
||||||
aria-label="Delete Force"
|
title={gettext('Delete')}
|
||||||
title={gettext('Delete (Force)')}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onDrop('dropForce');
|
onDrop('drop');
|
||||||
}}
|
}}
|
||||||
disabled={
|
disabled={
|
||||||
(selectedObject.length > 0)
|
(selectedObject.length > 0)
|
||||||
? !canDropForce
|
? !canDrop
|
||||||
: true
|
: true
|
||||||
}
|
}
|
||||||
></PgIconButton>}
|
></PgIconButton>
|
||||||
|
{node.type !== 'coll-database' ? <PgIconButton
|
||||||
|
icon={<DeleteSweepIcon style={{height: '1.5rem'}} />}
|
||||||
|
aria-label="Delete Cascade"
|
||||||
|
title={gettext('Delete (Cascade)')}
|
||||||
|
onClick={() => {
|
||||||
|
onDrop('dropCascade');
|
||||||
|
}}
|
||||||
|
disabled={
|
||||||
|
(selectedObject.length > 0)
|
||||||
|
? !canDropCascade
|
||||||
|
: true
|
||||||
|
}
|
||||||
|
></PgIconButton> :
|
||||||
|
<PgIconButton
|
||||||
|
icon={<DeleteForeverIcon style={{height: '1.4rem'}} />}
|
||||||
|
aria-label="Delete Force"
|
||||||
|
title={gettext('Delete (Force)')}
|
||||||
|
onClick={() => {
|
||||||
|
onDrop('dropForce');
|
||||||
|
}}
|
||||||
|
disabled={
|
||||||
|
(selectedObject.length > 0)
|
||||||
|
? !canDropForce
|
||||||
|
: true
|
||||||
|
}
|
||||||
|
></PgIconButton>}
|
||||||
|
</PgButtonGroup>
|
||||||
</Box>);
|
</Box>);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -356,9 +352,7 @@ export default function CollectionNodeProperties({
|
|||||||
:
|
:
|
||||||
(
|
(
|
||||||
<div className={classes.emptyPanel}>
|
<div className={classes.emptyPanel}>
|
||||||
{loaderText ? (<Loader message={loaderText}/>) :
|
<EmptyPanelMessage text={gettext(infoMsg)}/>
|
||||||
<EmptyPanelMessage text={gettext(infoMsg)}/>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ function SQL({nodeData, node, treeNodeInfo, isActive, isStale, setIsStale}) {
|
|||||||
setNodeSQL(sql);
|
setNodeSQL(sql);
|
||||||
}
|
}
|
||||||
setIsStale(false);
|
setIsStale(false);
|
||||||
}, [isStale, isActive]);
|
}, [isStale, isActive, nodeData?.id]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -237,10 +237,11 @@ function Statistics({ nodeData, nodeItem, node, treeNodeInfo, isActive, isStale,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (message != '') {
|
if (message != '') {
|
||||||
|
setTableData([]);
|
||||||
setMsg(message);
|
setMsg(message);
|
||||||
}
|
}
|
||||||
setIsStale(false);
|
setIsStale(false);
|
||||||
}, [isStale, isActive]);
|
}, [isStale, isActive, nodeData?.id]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, {useLayoutEffect, useMemo } from 'react';
|
import React, {useEffect, useMemo, useState } from 'react';
|
||||||
import AppMenuBar from './AppMenuBar';
|
import AppMenuBar from './AppMenuBar';
|
||||||
import ObjectBreadcrumbs from './components/ObjectBreadcrumbs';
|
import ObjectBreadcrumbs from './components/ObjectBreadcrumbs';
|
||||||
import Layout, { LayoutDocker, getDefaultGroup } from './helpers/Layout';
|
import Layout, { LayoutDocker, getDefaultGroup } from './helpers/Layout';
|
||||||
@@ -35,27 +35,27 @@ const mainPanelGroup = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const processesPanelData = {
|
export const processesPanelData = {
|
||||||
id: BROWSER_PANELS.PROCESSES, title: gettext('Processes'), content: <Processes />, closable: true, group: 'main'
|
id: BROWSER_PANELS.PROCESSES, title: gettext('Processes'), content: <Processes />, closable: true, group: 'playground'
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultTabsData = [
|
export const defaultTabsData = [
|
||||||
{
|
{
|
||||||
id: BROWSER_PANELS.DASHBOARD, title: gettext('Dashboard'), content: <Dashboard />, closable: true, group: 'main'
|
id: BROWSER_PANELS.DASHBOARD, title: gettext('Dashboard'), content: <Dashboard />, closable: true, group: 'playground'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: BROWSER_PANELS.PROPERTIES, title: gettext('Properties'), content: <Properties />, closable: true, group: 'main'
|
id: BROWSER_PANELS.PROPERTIES, title: gettext('Properties'), content: <Properties />, closable: true, group: 'playground'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: BROWSER_PANELS.SQL, title: gettext('SQL'), content: <SQL />, closable: true, group: 'main'
|
id: BROWSER_PANELS.SQL, title: gettext('SQL'), content: <SQL />, closable: true, group: 'playground'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: BROWSER_PANELS.STATISTICS, title: gettext('Statistics'), content: <Statistics />, closable: true, group: 'main'
|
id: BROWSER_PANELS.STATISTICS, title: gettext('Statistics'), content: <Statistics />, closable: true, group: 'playground'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: BROWSER_PANELS.DEPENDENCIES, title: gettext('Dependencies'), content: <Dependencies />, closable: true, group: 'main'
|
id: BROWSER_PANELS.DEPENDENCIES, title: gettext('Dependencies'), content: <Dependencies />, closable: true, group: 'playground'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: BROWSER_PANELS.DEPENDENTS, title: gettext('Dependents'), content: <Dependents />, closable: true, group: 'main'
|
id: BROWSER_PANELS.DEPENDENTS, title: gettext('Dependents'), content: <Dependents />, closable: true, group: 'playground'
|
||||||
},
|
},
|
||||||
processesPanelData,
|
processesPanelData,
|
||||||
];
|
];
|
||||||
@@ -81,9 +81,9 @@ export default function BrowserComponent({pgAdmin}) {
|
|||||||
{
|
{
|
||||||
size: 80,
|
size: 80,
|
||||||
id: BROWSER_PANELS.MAIN,
|
id: BROWSER_PANELS.MAIN,
|
||||||
group: 'main',
|
group: 'playground',
|
||||||
tabs: defaultTabsData.map((t)=>LayoutDocker.getPanel(t)),
|
tabs: defaultTabsData.map((t)=>LayoutDocker.getPanel(t)),
|
||||||
panelLock: {panelStyle: 'main'},
|
panelLock: {panelStyle: 'playground'},
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -92,10 +92,13 @@ export default function BrowserComponent({pgAdmin}) {
|
|||||||
};
|
};
|
||||||
const {isLoading, failed} = usePreferences();
|
const {isLoading, failed} = usePreferences();
|
||||||
let { name: browser } = useMemo(()=>getBrowser(), []);
|
let { name: browser } = useMemo(()=>getBrowser(), []);
|
||||||
|
const [uiReady, setUiReady] = useState(false);
|
||||||
|
|
||||||
useLayoutEffect(()=>{
|
useEffect(()=>{
|
||||||
pgAdmin?.Browser?.uiloaded?.();
|
if(uiReady) {
|
||||||
}, []);
|
pgAdmin?.Browser?.uiloaded?.();
|
||||||
|
}
|
||||||
|
}, [uiReady]);
|
||||||
|
|
||||||
if(isLoading) {
|
if(isLoading) {
|
||||||
return <></>;
|
return <></>;
|
||||||
@@ -107,9 +110,9 @@ export default function BrowserComponent({pgAdmin}) {
|
|||||||
return (
|
return (
|
||||||
<PgAdminContext.Provider value={pgAdmin}>
|
<PgAdminContext.Provider value={pgAdmin}>
|
||||||
<ModalProvider>
|
<ModalProvider>
|
||||||
<NotifierProvider pgAdmin={pgAdmin} />
|
<NotifierProvider pgAdmin={pgAdmin} onReady={()=>setUiReady(true)}/>
|
||||||
{browser != 'Nwjs' && <AppMenuBar />}
|
{browser != 'Nwjs' && <AppMenuBar />}
|
||||||
<div style={{height: 'calc(100% - 32px)'}}>
|
<div style={{height: 'calc(100% - 30px)'}}>
|
||||||
<Layout
|
<Layout
|
||||||
getLayoutInstance={(obj)=>{
|
getLayoutInstance={(obj)=>{
|
||||||
pgAdmin.Browser.docker = obj;
|
pgAdmin.Browser.docker = obj;
|
||||||
@@ -119,7 +122,7 @@ export default function BrowserComponent({pgAdmin}) {
|
|||||||
savedLayout={pgAdmin.Browser.utils.layout}
|
savedLayout={pgAdmin.Browser.utils.layout}
|
||||||
groups={{
|
groups={{
|
||||||
'object-explorer': objectExplorerGroup,
|
'object-explorer': objectExplorerGroup,
|
||||||
'main': mainPanelGroup,
|
'playground': mainPanelGroup,
|
||||||
}}
|
}}
|
||||||
noContextGroups={['object-explorer']}
|
noContextGroups={['object-explorer']}
|
||||||
resetToTabPanel={BROWSER_PANELS.MAIN}
|
resetToTabPanel={BROWSER_PANELS.MAIN}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import DataGridView from './DataGridView';
|
|||||||
import { useIsMounted } from '../custom_hooks';
|
import { useIsMounted } from '../custom_hooks';
|
||||||
import ErrorBoundary from '../helpers/ErrorBoundary';
|
import ErrorBoundary from '../helpers/ErrorBoundary';
|
||||||
import { usePgAdmin } from '../BrowserComponent';
|
import { usePgAdmin } from '../BrowserComponent';
|
||||||
|
import { PgButtonGroup } from '../components/Buttons';
|
||||||
|
|
||||||
const useDialogStyles = makeStyles((theme)=>({
|
const useDialogStyles = makeStyles((theme)=>({
|
||||||
root: {
|
root: {
|
||||||
@@ -866,7 +867,7 @@ const usePropsStyles = makeStyles((theme)=>({
|
|||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
},
|
},
|
||||||
toolbar: {
|
toolbar: {
|
||||||
padding: theme.spacing(0.5, 1),
|
padding: theme.spacing(1),
|
||||||
background: theme.palette.background.default,
|
background: theme.palette.background.default,
|
||||||
...theme.mixins.panelBorder.bottom,
|
...theme.mixins.panelBorder.bottom,
|
||||||
},
|
},
|
||||||
@@ -1000,11 +1001,13 @@ function SchemaPropertiesView({
|
|||||||
<Box className={classes.root}>
|
<Box className={classes.root}>
|
||||||
<Loader message={loaderText}/>
|
<Loader message={loaderText}/>
|
||||||
<Box className={classes.toolbar}>
|
<Box className={classes.toolbar}>
|
||||||
<PgIconButton
|
<PgButtonGroup size="small">
|
||||||
data-test="help" onClick={()=>props.onHelp(true, false)} icon={<InfoIcon />} disabled={props.disableSqlHelp}
|
<PgIconButton
|
||||||
title="SQL help for this object type." className={classes.buttonMargin} />
|
data-test="help" onClick={()=>props.onHelp(true, false)} icon={<InfoIcon />} disabled={props.disableSqlHelp}
|
||||||
<PgIconButton data-test="edit"
|
title="SQL help for this object type." />
|
||||||
onClick={props.onEdit} icon={<EditIcon />} title={gettext('Edit object...')} />
|
<PgIconButton data-test="edit"
|
||||||
|
onClick={props.onEdit} icon={<EditIcon />} title={gettext('Edit object...')} />
|
||||||
|
</PgButtonGroup>
|
||||||
</Box>
|
</Box>
|
||||||
<Box className={clsx(classes.form, classes.formProperties)}>
|
<Box className={clsx(classes.form, classes.formProperties)}>
|
||||||
<Box>
|
<Box>
|
||||||
|
|||||||
@@ -413,6 +413,9 @@ function getFinalTheme(baseTheme) {
|
|||||||
MuiAccordion: {
|
MuiAccordion: {
|
||||||
root: {
|
root: {
|
||||||
...mixins.panelBorder,
|
...mixins.panelBorder,
|
||||||
|
'&.Mui-expanded': {
|
||||||
|
marginBottom: '8px',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
MuiAccordionSummary: {
|
MuiAccordionSummary: {
|
||||||
|
|||||||
@@ -41,10 +41,14 @@ export default function rcdockOverride(theme) {
|
|||||||
},
|
},
|
||||||
'& .dock-tab-active': {
|
'& .dock-tab-active': {
|
||||||
color: theme.palette.text.primary,
|
color: theme.palette.text.primary,
|
||||||
|
cursor: 'move',
|
||||||
'&::hover': {
|
'&::hover': {
|
||||||
color: theme.palette.text.primary,
|
color: theme.palette.text.primary,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
'& .dock-tab-btn': {
|
||||||
|
pointerEvents: 'none',
|
||||||
|
}
|
||||||
},
|
},
|
||||||
'&.dock-style-dialogs': {
|
'&.dock-style-dialogs': {
|
||||||
borderRadius: theme.shape.borderRadius,
|
borderRadius: theme.shape.borderRadius,
|
||||||
@@ -159,7 +163,30 @@ export default function rcdockOverride(theme) {
|
|||||||
},
|
},
|
||||||
'& .drag-accept-reject::after': {
|
'& .drag-accept-reject::after': {
|
||||||
content: '',
|
content: '',
|
||||||
|
},
|
||||||
|
'& .dock-nav-more': {
|
||||||
|
color: theme.custom.icon.contrastText
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
'.dock-dropdown': {
|
||||||
|
zIndex: 1004,
|
||||||
|
|
||||||
|
'& .dock-dropdown-menu': {
|
||||||
|
padding: '4px 0px',
|
||||||
|
backgroundColor: theme.palette.background.default,
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
border: `1px solid ${theme.otherVars.borderColor}`,
|
||||||
|
},
|
||||||
|
'& .dock-dropdown-menu-item': {
|
||||||
|
display: 'flex',
|
||||||
|
padding: '3px 12px',
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
transition: 'none',
|
||||||
|
'&.dock-dropdown-menu-item-active, &:hover': {
|
||||||
|
backgroundColor: theme.palette.primary.main,
|
||||||
|
color: theme.palette.primary.contrastText,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ export default function ToolView() {
|
|||||||
manualClose: true,
|
manualClose: true,
|
||||||
...tabParams,
|
...tabParams,
|
||||||
cache: false,
|
cache: false,
|
||||||
group: 'main'
|
group: 'playground'
|
||||||
}, BROWSER_PANELS.MAIN, 'middle', true);
|
}, BROWSER_PANELS.MAIN, 'middle', true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -81,11 +81,11 @@ const useStyles = makeStyles((theme)=>({
|
|||||||
},
|
},
|
||||||
noBorder: {
|
noBorder: {
|
||||||
border: 0,
|
border: 0,
|
||||||
color: 'inherit',
|
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: 'transparent',
|
||||||
|
color: theme.custom.icon.contrastText,
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
border: 0,
|
border: 0,
|
||||||
color: 'inherit',
|
color: theme.custom.icon.contrastText,
|
||||||
backgroundColor: 'inherit',
|
backgroundColor: 'inherit',
|
||||||
filter: 'brightness(85%)',
|
filter: 'brightness(85%)',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
pgTableHeader: {
|
pgTableHeader: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
background: theme.palette.background.default,
|
background: theme.palette.background.default,
|
||||||
padding: '4px 8px',
|
padding: '8px 8px 4px',
|
||||||
},
|
},
|
||||||
tableRowContent:{
|
tableRowContent:{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
|
|||||||
@@ -118,7 +118,6 @@ export class FileTreeX extends React.Component<IFileTreeXProps> {
|
|||||||
setPseudoActiveFile: this.setPseudoActiveFile,
|
setPseudoActiveFile: this.setPseudoActiveFile,
|
||||||
toggleDirectory: this.toggleDirectory,
|
toggleDirectory: this.toggleDirectory,
|
||||||
closeDir: this.closeDir,
|
closeDir: this.closeDir,
|
||||||
remove: this.removeDir,
|
|
||||||
newFile: async (dirOrPath: Directory | string) => this.supervisePrompt(await handle.promptNewFile(dirOrPath as string)),
|
newFile: async (dirOrPath: Directory | string) => this.supervisePrompt(await handle.promptNewFile(dirOrPath as string)),
|
||||||
newFolder: async (dirOrPath: Directory | string) => this.supervisePrompt(await handle.promptNewDirectory(dirOrPath as string)),
|
newFolder: async (dirOrPath: Directory | string) => this.supervisePrompt(await handle.promptNewDirectory(dirOrPath as string)),
|
||||||
onBlur: (callback) => this.events.add(FileTreeXEvent.OnBlur, callback),
|
onBlur: (callback) => this.events.add(FileTreeXEvent.OnBlur, callback),
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ export function getDefaultGroup() {
|
|||||||
closable: false,
|
closable: false,
|
||||||
maximizable: false,
|
maximizable: false,
|
||||||
floatable: false,
|
floatable: false,
|
||||||
moreIcon: <ExpandMoreIcon style={{height: '0.9em'}} />,
|
moreIcon: <ExpandMoreIcon style={{height: '0.9em', marginTop: '4px'}} />,
|
||||||
panelExtra: (panelData, context) => {
|
panelExtra: (panelData, context) => {
|
||||||
let icon = <ExpandDialogIcon style={{width: '0.7em'}}/>;
|
let icon = <ExpandDialogIcon style={{width: '0.7em'}}/>;
|
||||||
let title = gettext('Maximise');
|
let title = gettext('Maximise');
|
||||||
|
|||||||
@@ -183,13 +183,14 @@ class Notifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function NotifierProvider({ pgAdmin, pgWindow, getInstance, children }) {
|
export function NotifierProvider({ pgAdmin, pgWindow, getInstance, children, onReady }) {
|
||||||
const modal = useModal();
|
const modal = useModal();
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
// if open in an iframe then use top pgAdmin
|
// if open in an iframe then use top pgAdmin
|
||||||
if(window.self != window.top) {
|
if(window.self != window.top) {
|
||||||
pgAdmin.Browser.notifier = new Notifier(modal, pgWindow.pgAdmin.Browser.notifier.snackbar);
|
pgAdmin.Browser.notifier = new Notifier(modal, pgWindow.pgAdmin.Browser.notifier.snackbar);
|
||||||
|
onReady?.();
|
||||||
getInstance?.(pgAdmin.Browser.notifier);
|
getInstance?.(pgAdmin.Browser.notifier);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
@@ -203,6 +204,7 @@ export function NotifierProvider({ pgAdmin, pgWindow, getInstance, children }) {
|
|||||||
ref={(obj)=>{
|
ref={(obj)=>{
|
||||||
pgAdmin.Browser.notifier = new Notifier(modal, new SnackbarNotifier(obj));
|
pgAdmin.Browser.notifier = new Notifier(modal, new SnackbarNotifier(obj));
|
||||||
getInstance?.(pgAdmin.Browser.notifier);
|
getInstance?.(pgAdmin.Browser.notifier);
|
||||||
|
onReady?.();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
@@ -221,6 +223,7 @@ NotifierProvider.propTypes = {
|
|||||||
pgWindow: PropTypes.object,
|
pgWindow: PropTypes.object,
|
||||||
getInstance: PropTypes.func,
|
getInstance: PropTypes.func,
|
||||||
children: CustomPropTypes.children,
|
children: CustomPropTypes.children,
|
||||||
|
onReady: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Notifier;
|
export default Notifier;
|
||||||
|
|||||||
@@ -960,6 +960,7 @@ table.table-empty-rows{
|
|||||||
.dialog-node-icon {
|
.dialog-node-icon {
|
||||||
margin-right: 2px !important;
|
margin-right: 2px !important;
|
||||||
padding: 0px 10px;
|
padding: 0px 10px;
|
||||||
|
background-position: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
|
|||||||
@@ -75,10 +75,10 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<script type="application/javascript" src="{{ url_for('static', filename='js/generated/vendor.main.js') }}" ></script>
|
<script type="application/javascript" src="{{ url_for('static', filename='js/generated/vendor.react.js') }}" ></script>
|
||||||
<!-- View specified scripts -->
|
|
||||||
<script type="application/javascript" src="{{ url_for('static', filename='js/generated/vendor.main.js') }}" ></script>
|
<script type="application/javascript" src="{{ url_for('static', filename='js/generated/vendor.main.js') }}" ></script>
|
||||||
<script type="application/javascript" src="{{ url_for('static', filename='js/generated/vendor.others.js') }}" ></script>
|
<script type="application/javascript" src="{{ url_for('static', filename='js/generated/vendor.others.js') }}" ></script>
|
||||||
|
<script type="application/javascript" src="{{ url_for('static', filename='js/generated/vendor.sqleditor.js') }}"></script>
|
||||||
<script type="application/javascript" src="{{ url_for('static', filename='js/generated/pgadmin_commons.js') }}" ></script>
|
<script type="application/javascript" src="{{ url_for('static', filename='js/generated/pgadmin_commons.js') }}" ></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -824,6 +824,7 @@ export default function DebuggerArgumentComponent({ debuggerInfo, restartDebug,
|
|||||||
schema={debuggerArgsSchema.current}
|
schema={debuggerArgsSchema.current}
|
||||||
showFooter={false}
|
showFooter={false}
|
||||||
isTabView={false}
|
isTabView={false}
|
||||||
|
Notifier={pgAdmin.Browser.notifier}
|
||||||
onDataChange={(isChanged, changedData) => {
|
onDataChange={(isChanged, changedData) => {
|
||||||
let isValid = false;
|
let isValid = false;
|
||||||
let skipStep = false;
|
let skipStep = false;
|
||||||
|
|||||||
@@ -393,19 +393,19 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros}) {
|
|||||||
{
|
{
|
||||||
shortcut: queryToolPref.execute_query,
|
shortcut: queryToolPref.execute_query,
|
||||||
options: {
|
options: {
|
||||||
callback: ()=>{!buttonsDisabled['execute']?executeQuery():null;}
|
callback: ()=>{!buttonsDisabled['execute']&&executeQuery();}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
shortcut: queryToolPref.explain_query,
|
shortcut: queryToolPref.explain_query,
|
||||||
options: {
|
options: {
|
||||||
callback: (e)=>{e.preventDefault(); !buttonsDisabled['explain']?explain():null;}
|
callback: (e)=>{e.preventDefault(); !buttonsDisabled['explain']&&explain();}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
shortcut: queryToolPref.explain_analyze_query,
|
shortcut: queryToolPref.explain_analyze_query,
|
||||||
options: {
|
options: {
|
||||||
callback: ()=>{!buttonsDisabled['explain_analyse']?explainAnalyse():null;}
|
callback: ()=>{!buttonsDisabled['explain_analyse']&&explainAnalyse();}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -580,6 +580,30 @@ module.exports = [{
|
|||||||
] : [],
|
] : [],
|
||||||
splitChunks: {
|
splitChunks: {
|
||||||
cacheGroups: {
|
cacheGroups: {
|
||||||
|
vendor_sqleditor: {
|
||||||
|
name: 'vendor_sqleditor',
|
||||||
|
filename: 'vendor.sqleditor.js',
|
||||||
|
chunks: 'all',
|
||||||
|
reuseExistingChunk: true,
|
||||||
|
priority: 9,
|
||||||
|
minChunks: 2,
|
||||||
|
enforce: true,
|
||||||
|
test(module) {
|
||||||
|
return webpackShimConfig.matchModules(module, ['jsoneditor', 'leaflet']);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
vendor_react: {
|
||||||
|
name: 'vendor_react',
|
||||||
|
filename: 'vendor.react.js',
|
||||||
|
chunks: 'all',
|
||||||
|
reuseExistingChunk: true,
|
||||||
|
priority: 8,
|
||||||
|
minChunks: 2,
|
||||||
|
enforce: true,
|
||||||
|
test(module) {
|
||||||
|
return webpackShimConfig.matchModules(module, ['react', 'react-dom']);
|
||||||
|
},
|
||||||
|
},
|
||||||
vendor_main: {
|
vendor_main: {
|
||||||
name: 'vendor_main',
|
name: 'vendor_main',
|
||||||
filename: 'vendor.main.js',
|
filename: 'vendor.main.js',
|
||||||
@@ -589,7 +613,7 @@ module.exports = [{
|
|||||||
minChunks: 2,
|
minChunks: 2,
|
||||||
enforce: true,
|
enforce: true,
|
||||||
test(module) {
|
test(module) {
|
||||||
return webpackShimConfig.matchModules(module, ['react', 'react-dom', 'bootstrap', 'popper']);
|
return webpackShimConfig.matchModules(module, ['codemirror', 'rc-', '@material-ui']);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
vendor_others: {
|
vendor_others: {
|
||||||
|
|||||||
Reference in New Issue
Block a user