Continue fixing multiple UI and SonarQube issues found when testing wcDocker changes. #6479

This commit is contained in:
Aditya Toshniwal 2023-10-30 16:57:01 +05:30
parent 4bc6dcca67
commit e30d2eca90
10 changed files with 65 additions and 57 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -33,6 +33,7 @@ Bug fixes
*********
| `Issue #2986 <https://github.com/pgadmin-org/pgadmin4/issues/2986>`_ - Fix an issue where the scroll position of panels was not remembered on Firefox.
| `Issue #6459 <https://github.com/pgadmin-org/pgadmin4/issues/6459>`_ - Fix the sorting of size on the statistics panel.
| `Issue #6602 <https://github.com/pgadmin-org/pgadmin4/issues/6602>`_ - Fix an issue where the default server-group is being deleted if the load-server json file contains no servers.
| `Issue #6720 <https://github.com/pgadmin-org/pgadmin4/issues/6720>`_ - Fix an issue of the incorrect format (no indent) of SQL stored functions/procedures.
| `Issue #6784 <https://github.com/pgadmin-org/pgadmin4/issues/6784>`_ - Fixed an issue where Schema Diff does not work when the user language is set to any language other than English in Preferences.

View File

@ -5,9 +5,9 @@
****************
The pgAdmin toolbar provides shortcut buttons for frequently used features like
View Data and the Query Tool which are most frequently used in pgAdmin. This
toolbar is visible on the Browser panel. Buttons get enabled/disabled based on
the selected browser node.
the Query Tool, View/Edit Data, Search Object and the PSQL Tool. This
toolbar is visible on the Object explorer panel. Buttons get enabled/disabled based on
the selected object node.
.. image:: /images/toolbar.png
:alt: pgAdmin Toolbar

View File

@ -4,8 +4,8 @@
`Tree Control`:index:
*********************
The left pane of the main window displays a tree control (the *pgAdmin* tree
control) that provides access to the objects that reside on a server.
The left pane of the main window displays a tree control (Object explorer)
that provides access to the objects that reside on a server.
.. image:: /images/main_left_pane.png
:alt: object explorer panel

View File

@ -55,29 +55,17 @@ const useStyles = makeStyles((theme) => ({
}));
function getColumn(data, singleLineStatistics, prettifyFields=[]) {
let columns = [], column;
let columns = [];
if (!singleLineStatistics) {
if (!_.isUndefined(data)) {
data.forEach((row) => {
if (row.name == gettext('Total Size')) {
column = {
Header: row.name,
accessor: row.name,
sortable: true,
resizable: true,
disableGlobalFilter: false,
};
}else{
column = {
Header: row.name,
accessor: row.name,
sortable: true,
resizable: true,
disableGlobalFilter: false,
};
}
columns.push(column);
columns.push({
Header: row.name,
accessor: row.name,
sortable: true,
resizable: true,
disableGlobalFilter: false,
});
});
}
} else {

View File

@ -77,6 +77,9 @@ const useStyles = makeStyles((theme)=>({
minWidth: '24px',
'& .MuiSvgIcon-root': {
height: '0.8em',
},
'.MuiButtonGroup-root &': {
minWidth: '30px',
}
},
noBorder: {

View File

@ -1,4 +1,4 @@
import React, { useRef, useMemo, useEffect, useCallback } from 'react';
import React, { useRef, useMemo, useEffect, useCallback, useState } from 'react';
import DockLayout from 'rc-dock';
import PropTypes from 'prop-types';
import EventBus from '../EventBus';
@ -17,8 +17,12 @@ import usePreferences from '../../../../preferences/static/js/store';
import _ from 'lodash';
function TabTitle({id, icon, title, closable, tooltip}) {
const [attrs, setAttrs] = useState({
icon: icon,
title: title,
tooltip: tooltip??title,
});
const layoutDocker = React.useContext(LayoutDockerContext);
const onContextMenu = useCallback((e)=>{
const g = layoutDocker.find(id)?.group??'';
if((layoutDocker.noContextGroups??[]).includes(g)) return;
@ -27,10 +31,24 @@ function TabTitle({id, icon, title, closable, tooltip}) {
layoutDocker.eventBus.fireEvent(LAYOUT_EVENTS.CONTEXT, e, id);
}, []);
useEffect(()=>{
const deregister = layoutDocker.eventBus.registerListener(LAYOUT_EVENTS.REFRESH_TITLE, _.debounce((panelId)=>{
if(panelId == id) {
const p = layoutDocker.find(id)?.internal??{};
setAttrs({
icon: p.icon,
title: p.title,
tooltip: p.tooltip??p.title
});
}
}, 100));
return deregister;
}, []);
return (
<Box display="flex" alignItems="center" title={tooltip??title} onContextMenu={onContextMenu} width="100%">
{icon && <span style={{fontSize: '1rem', marginRight: '4px'}} className={icon}></span>}
<span style={{textOverflow: 'ellipsis', overflow: 'hidden', whiteSpace: 'nowrap'}} data-visible={layoutDocker.isTabVisible(id)}>{title}</span>
<Box display="flex" alignItems="center" title={attrs.tooltip} onContextMenu={onContextMenu} width="100%">
{attrs.icon && <span style={{fontSize: '1rem', marginRight: '4px'}} className={attrs.icon}></span>}
<span style={{textOverflow: 'ellipsis', overflow: 'hidden', whiteSpace: 'nowrap'}} data-visible={layoutDocker.isTabVisible(id)}>{attrs.title}</span>
{closable && <PgIconButton title={gettext('Close')} icon={<CloseIcon style={{height: '0.7em'}} />} size="xs" noBorder onClick={()=>{
layoutDocker.close(id);
}} style={{margin: '-1px -10px -1px 0'}} />}
@ -99,7 +117,7 @@ export class LayoutDocker {
}
find(...args) {
return this.layoutObj.find(...args);
return this.layoutObj?.find(...args);
}
setTitle(panelId, title, icon, tooltip) {
@ -116,22 +134,17 @@ export class LayoutDocker {
if(tooltip) {
internal.tooltip = tooltip;
}
this.layoutObj.updateTab(panelId, {
...panelData,
internal: internal,
title: <TabTitle id={panelData.id} icon={internal.icon} title={internal.title} closable={internal.closable} tooltip={internal.tooltip} />
}, false);
panelData.internal = internal;
this.eventBus.fireEvent(LAYOUT_EVENTS.REFRESH_TITLE, panelId);
}
setInternalAttrs(panelId, attrs) {
const panelData = this.find(panelId);
this.layoutObj.updateTab(panelId, {
...panelData,
internal: {
...panelData.internal,
...attrs,
},
}, false);
panelData.internal = {
...panelData.internal,
...attrs,
};
this.eventBus.fireEvent(LAYOUT_EVENTS.REFRESH_TITLE, panelId);
}
getInternalAttrs(panelId) {
@ -449,12 +462,12 @@ export default function Layout({groups, noContextGroups, getLayoutInstance, layo
}}
groups={defaultGroups}
onLayoutChange={(l, currentTabId, direction)=>{
layoutDockerObj.saveLayout(l);
direction = direction == 'update' ? 'active' : direction;
if(Object.values(LAYOUT_EVENTS).indexOf(direction) > -1) {
layoutDockerObj.eventBus.fireEvent(LAYOUT_EVENTS[direction.toUpperCase()], currentTabId);
} else if(direction) {
layoutDockerObj.saveLayout(l);
} else if(direction && direction != 'update') {
layoutDockerObj.eventBus.fireEvent(LAYOUT_EVENTS.CHANGE, currentTabId);
layoutDockerObj.saveLayout(l);
}
}}
{...props}
@ -486,5 +499,6 @@ export const LAYOUT_EVENTS = {
MOVE: 'move',
CLOSING: 'closing',
CONTEXT: 'context',
CHANGE: 'change'
CHANGE: 'change',
REFRESH_TITLE: 'refresh-title'
};

View File

@ -3,15 +3,15 @@ import { usePgAdmin } from '../BrowserComponent';
import { Box } from '@material-ui/core';
import { QueryToolIcon, RowFilterIcon, TerminalIcon, ViewDataIcon } from '../components/ExternalIcon';
import SearchOutlinedIcon from '@material-ui/icons/SearchOutlined';
import { PgIconButton } from '../components/Buttons';
import { PgButtonGroup, PgIconButton } from '../components/Buttons';
import _ from 'lodash';
import PropTypes from 'prop-types';
import CustomPropTypes from '../custom_prop_types';
function ToolbarButton({menuItem, icon}) {
function ToolbarButton({menuItem, icon, ...props}) {
return (
<PgIconButton title={menuItem?.label??''} icon={icon} size="xs"
<PgIconButton title={menuItem?.label??''} icon={icon} {...props} size="xs"
disabled={menuItem?.isDisabled??true} onClick={()=>menuItem?.callback()} />
);
}
@ -60,11 +60,13 @@ export default function ObjectExplorerToolbar() {
return (
<Box display="flex" alignItems="center" gridGap={'2px'}>
<ToolbarButton icon={<QueryToolIcon />} menuItem={menus['query_tool']} />
<ToolbarButton icon={<ViewDataIcon />} menuItem={menus['view_all_rows_context_table']} />
<ToolbarButton icon={<RowFilterIcon />} menuItem={menus['view_filtered_rows_context_table']} />
<ToolbarButton icon={<SearchOutlinedIcon style={{height: '1.4rem'}} />} menuItem={menus['search_objects']} />
<ToolbarButton icon={<TerminalIcon />} menuItem={menus['psql']} />
<PgButtonGroup size="small">
<ToolbarButton icon={<QueryToolIcon />} menuItem={menus['query_tool']} />
<ToolbarButton icon={<ViewDataIcon />} menuItem={menus['view_all_rows_context_table']} />
<ToolbarButton icon={<RowFilterIcon />} menuItem={menus['view_filtered_rows_context_table']} />
<ToolbarButton icon={<SearchOutlinedIcon style={{height: '1.4rem'}} />} menuItem={menus['search_objects']} />
<ToolbarButton icon={<TerminalIcon />} menuItem={menus['psql']} />
</PgButtonGroup>
</Box>
);
}

View File

@ -498,11 +498,11 @@ export default function Query() {
const isDirty = ()=>(queryToolCtx.params.is_query_tool && lastSavedText.current !== editor.current.getValue());
const cursorActivity = useCallback((cmObj)=>{
const cursorActivity = useCallback(_.debounce((cmObj)=>{
const c = cmObj.getCursor();
lastCursorPos.current = c;
eventBus.fireEvent(QUERY_TOOL_EVENTS.CURSOR_ACTIVITY, [c.line+1, c.ch+1]);
}, []);
}, 100), []);
const change = useCallback(()=>{
eventBus.fireEvent(QUERY_TOOL_EVENTS.QUERY_CHANGED, isDirty());