Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions web/pgadmin/tools/erd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,19 @@ def register_preferences(self):
)
)

self.preference.register(
'options', 'image_pixel_ratio',
gettext('Image Download Resolution'), 'radioModern', '1',
category_label=PREF_LABEL_OPTIONS, options=[
{'label': gettext('Good'), 'value': '1'},
{'label': gettext('High'), 'value': '3'},
{'label': gettext('Very High'), 'value': '5'},
],
help_str=gettext(
'Higher values will use higher memory and slower rendering.'
),
)

self.preference.register(
'options',
'sql_with_drop',
Expand Down
27 changes: 22 additions & 5 deletions web/pgadmin/tools/erd/static/js/erd_tool/components/ERDTool.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,16 @@ const StyledBox = styled(Box)(({theme})=>({
'& .ERDTool-html2canvasReset': {
backgroundImage: 'none !important',
overflow: 'auto !important',
textRendering: 'geometricPrecision',

'& .TableNode-tableToolbar': {
visibility: 'hidden',
},

'& .TableNode-tableContent': {
borderTopLeftRadius: theme.shape.borderRadius,
borderTopRightRadius: theme.shape.borderRadius,
},
}
}));

Expand Down Expand Up @@ -163,7 +173,6 @@ export default class ERDTool extends React.Component {
this.keyboardActionObj = null;
this.erdDialogs = new ERDDialogs(this.context);
this.apiObj = getApiInstance();
this.preferencesStore = usePreferences.getState();
this.fmUtilsObj = new FileManagerUtils(this.apiObj, {modal: this.context});
this.restore = props.params.restore == 'true';
this.eventBus = new EventBus();
Expand Down Expand Up @@ -328,17 +337,25 @@ export default class ERDTool extends React.Component {
this.setLoading(gettext('Preparing...'));
this.registerEvents();
this.diagramContainerRef.current?.focus();
const erdPref = this.preferencesStore.getPreferencesForModule('erd');
const erdPref = usePreferences.getState().getPreferencesForModule('erd');
this.setState({
preferences: erdPref,
is_new_tab: (this.preferencesStore.getPreferencesForModule('browser').new_browser_tab_open || '')
is_new_tab: (usePreferences.getState().getPreferencesForModule('browser').new_browser_tab_open || '')
.includes('erd_tool'),
is_close_tab_warning: this.preferencesStore.getPreferencesForModule('browser').confirm_on_refresh_close,
is_close_tab_warning: usePreferences.getState().getPreferencesForModule('browser').confirm_on_refresh_close,
cardinality_notation: erdPref.cardinality_notation,
}, ()=>{
this.registerKeyboardShortcuts();
if(this.state.current_file)this.setTitle(this.state.current_file);
});

usePreferences.subscribe((state)=>{
this.setState({
preferences: state.getPreferencesForModule('erd'),
is_close_tab_warning: state.getPreferencesForModule('browser').confirm_on_refresh_close,
});
});

this.registerModelEvents();
this.realignGrid({
backgroundSize: '45px 45px',
Expand Down Expand Up @@ -808,7 +825,7 @@ export default class ERDTool extends React.Component {
height = 32766;
isCut = true;
}
toPng(this.canvasEle, {width, height})
toPng(this.canvasEle, {width, height, pixelRatio: this.state.preferences.image_pixel_ratio || 1})
.then((dataUrl)=>{
DownloadUtils.downloadBase64UrlData(dataUrl, `${this.getCurrentProjectName()}.png`);
}).catch((err)=>{
Expand Down
71 changes: 39 additions & 32 deletions web/pgadmin/tools/erd/static/js/erd_tool/nodes/TableNode.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { Box } from '@mui/material';
import { styled } from '@mui/material/styles';

const TYPE = 'table';
const TABLE_WIDTH = 175;
const TABLE_WIDTH = 180;

export class TableNodeModel extends DefaultNodeModel {
constructor({otherInfo, ...options}) {
Expand Down Expand Up @@ -214,16 +214,31 @@ RowIcon.propTypes = {

const StyledDiv = styled('div')(({theme})=>({
'&.TableNode-tableNode': {
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
...theme.mixins.panelBorder.all,
borderRadius: theme.shape.borderRadius,
position: 'relative',
width: `${TABLE_WIDTH}px`,
fontSize: '0.8em',
'& div:last-child': {
borderBottomLeftRadius: 'inherit',
borderBottomRightRadius: 'inherit',

'& .TableNode-tableContent': {
backgroundColor: theme.palette.background.default,
...theme.mixins.panelBorder.all,
borderBottomLeftRadius: theme.shape.borderRadius,
borderBottomRightRadius: theme.shape.borderRadius,
},
'& .TableNode-tableToolbar': {
background: theme.otherVars.editorToolbarBg,
...theme.mixins.panelBorder.all,
borderBottom: 'none',
borderTopLeftRadius: theme.shape.borderRadius,
borderTopRightRadius: theme.shape.borderRadius,
padding: '0.125rem 0.25rem',
display: 'flex',

'& .TableNode-noteBtn': {
marginLeft: 'auto',
backgroundColor: theme.palette.warning.main,
color: theme.palette.warning.contrastText,
},
},
'& .TableNode-tableSection': {
...theme.mixins.panelBorder.bottom,
Expand All @@ -237,16 +252,6 @@ const StyledDiv = styled('div')(({theme})=>({
color: theme.palette.error.main,
},
},
'&.TableNode-tableToolbar': {
background: theme.otherVars.editorToolbarBg,
borderTopLeftRadius: 'inherit',
borderTopRightRadius: 'inherit',
},
'& .TableNode-noteBtn': {
marginLeft: 'auto',
backgroundColor: theme.palette.warning.main,
color: theme.palette.warning.contrastText,
},
},
'& .TableNode-columnSection': {
display:'flex',
Expand Down Expand Up @@ -370,7 +375,7 @@ export class TableNodeWidget extends React.Component {
return (
<StyledDiv className={['TableNode-tableNode', (this.props.node.isSelected() ? 'TableNode-tableNodeSelected': '')].join(' ')}
onDoubleClick={()=>{this.props.node.fireEvent({}, 'editTable');}} style={styles}>
<div className={'TableNode-tableSection TableNode-tableToolbar'}>
<div className={'TableNode-tableToolbar'}>
<PgIconButton size="xs" title={gettext('Show Details')} icon={this.state.show_details ? <VisibilityRoundedIcon /> : <VisibilityOffRoundedIcon />}
onClick={this.toggleShowDetails} onDoubleClick={(e)=>{e.stopPropagation();}} />
{this.props.node.getNote() &&
Expand All @@ -381,24 +386,26 @@ export class TableNodeWidget extends React.Component {
}}
/>}
</div>
{tableMetaData.is_promise &&
<div className='TableNode-tableContent'>
{tableMetaData.is_promise &&
<div className='TableNode-tableSection'>
{!tableMetaData.data_failed && <div className='TableNode-tableNameText'>{gettext('Fetching...')}</div>}
{tableMetaData.data_failed && <div className={'TableNode-tableNameText TableNode-error'}>{gettext('Failed to get data. Please delete this table.')}</div>}
</div>}
{!tableMetaData.is_promise && <>
<div className='TableNode-tableSection'>
<RowIcon icon={SchemaIcon}/>
<div className='TableNode-tableNameText' data-test="schema-name">{tableData.schema}</div>
</div>
<div className='TableNode-tableSection'>
<RowIcon icon={TableIcon} />
<div className='TableNode-tableNameText' data-test="table-name">{tableData.name}</div>
</div>
{tableData.columns.length > 0 && <div>
{_.map(tableData.columns, (col)=>this.generateColumn(col, localFkCols, localUkCols))}
</div>}
</>}
{!tableMetaData.is_promise && <>
<div className='TableNode-tableSection'>
<RowIcon icon={SchemaIcon}/>
<div className='TableNode-tableNameText' data-test="schema-name">{tableData.schema}</div>
</div>
<div className='TableNode-tableSection'>
<RowIcon icon={TableIcon} />
<div className='TableNode-tableNameText' data-test="table-name">{tableData.name}</div>
</div>
{tableData.columns.length > 0 && <div>
{_.map(tableData.columns, (col)=>this.generateColumn(col, localFkCols, localUkCols))}
</div>}
</>}
</div>
</StyledDiv>
);
}
Expand Down
Loading