Fixed an issue where ERD auto-layout should: #6592 (#8167)

- Always generate right-angled links
- Switch port to Left/Right for the best link route.
pull/8172/head
Aditya Toshniwal 2024-11-22 16:26:50 +05:30 committed by GitHub
parent ec197c68b8
commit 042888f5d7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 53 additions and 22 deletions

View File

@ -13,6 +13,7 @@ const jest = require('eslint-plugin-jest');
const babel = require('@babel/eslint-plugin'); const babel = require('@babel/eslint-plugin');
const babelParser = require('@babel/eslint-parser'); const babelParser = require('@babel/eslint-parser');
const ts = require('typescript-eslint'); const ts = require('typescript-eslint');
const unusedImports = require('eslint-plugin-unused-imports');
module.exports = [ module.exports = [
@ -63,6 +64,7 @@ module.exports = [
'plugins': { 'plugins': {
'react': reactjs, 'react': reactjs,
'@babel': babel, '@babel': babel,
'unused-imports': unusedImports,
}, },
'rules': { 'rules': {
'indent': [ 'indent': [
@ -91,7 +93,18 @@ module.exports = [
...reactjs.configs.recommended.rules, ...reactjs.configs.recommended.rules,
...reactjs.configs['jsx-runtime'].rules, ...reactjs.configs['jsx-runtime'].rules,
'react/jsx-uses-react': 'error', 'react/jsx-uses-react': 'error',
'react/jsx-uses-vars': 'error' 'react/jsx-uses-vars': 'error',
'no-unused-vars': 'off',
'unused-imports/no-unused-imports': 'error',
'unused-imports/no-unused-vars': [
'warn',
{
'vars': 'all',
'varsIgnorePattern': '^_',
'args': 'after-used',
'argsIgnorePattern': '^_',
},
]
}, },
'settings': { 'settings': {
'react': { 'react': {

View File

@ -37,6 +37,7 @@
"eslint": "^9.11.1", "eslint": "^9.11.1",
"eslint-plugin-jest": "^28.8.0", "eslint-plugin-jest": "^28.8.0",
"eslint-plugin-react": "^7.34.3", "eslint-plugin-react": "^7.34.3",
"eslint-plugin-unused-imports": "^4.1.4",
"exports-loader": "^5.0.0", "exports-loader": "^5.0.0",
"globals": "^15.8.0", "globals": "^15.8.0",
"html-react-parser": "^5.0.6", "html-react-parser": "^5.0.6",

View File

@ -49,7 +49,7 @@ export default class ERDCore {
marginx: 5, marginx: 5,
marginy: 5, marginy: 5,
}, },
includeLinks: true, includeLinks: false,
}); });
this.engine.getNodeFactories().registerFactory(new TableNodeFactory()); this.engine.getNodeFactories().registerFactory(new TableNodeFactory());
@ -645,12 +645,10 @@ export default class ERDCore {
}); });
} }
}); });
setTimeout(this.dagreDistributeNodes.bind(this), 250);
} }
repaint() { async repaint() {
this.getEngine().repaintCanvas(); await this.getEngine().repaintCanvas(true);
} }
clearSelection() { clearSelection() {
@ -679,9 +677,15 @@ export default class ERDCore {
.filter(entity => entity instanceof OneToManyLinkModel); .filter(entity => entity instanceof OneToManyLinkModel);
} }
dagreDistributeNodes() { async dagreDistributeNodes() {
this.dagre_engine.redistribute(this.getModel()); this.dagre_engine.redistribute(this.getModel());
this.repaint();
// Swith left/right ports.
this.getModel().getNodes().forEach((node)=>{
this.optimizePortsPosition(node);
});
await this.repaint();
} }
zoomIn() { zoomIn() {

View File

@ -512,7 +512,7 @@ export default class ERDTool extends React.Component {
}); });
if (this.diagram.getNodesData().length === 0){ if (this.diagram.getNodesData().length === 0){
this.setState({dirty: false}); this.setState({dirty: false});
this.eventBus.fireEvent(ERD_EVENTS.DIRTY, false); this.eventBus.fireEvent(ERD_EVENTS.DIRTY, false);
} }
this.diagram.repaint(); this.diagram.repaint();
}, },
@ -520,8 +520,10 @@ export default class ERDTool extends React.Component {
); );
} }
onAutoDistribute() { async onAutoDistribute() {
this.diagram.dagreDistributeNodes(); this.setLoading('Auto distributing...');
await this.diagram.dagreDistributeNodes();
this.setLoading();
} }
onChangeColors(fillColor, textColor) { onChangeColors(fillColor, textColor) {
@ -883,7 +885,9 @@ export default class ERDTool extends React.Component {
} catch (error) { } catch (error) {
this.handleAxiosCatch(error); this.handleAxiosCatch(error);
} }
this.setLoading(null); setTimeout(()=>{
this.onAutoDistribute();
}, 250);
} }
render() { render() {

View File

@ -281,7 +281,7 @@ export class OneToManyLinkWidget extends RightAngleLinkWidget {
} }
// If there is existing link which has two points add one // If there is existing link which has two points add one
if (points.length === 2 && !this.state.canDrag) { if (points.length === 2 && !this.state.canDrag && onePoint.point.getX() != manyPoint.point.getX()) {
this.props.link.addPoint( this.props.link.addPoint(
new PointModel({ new PointModel({
link: this.props.link, link: this.props.link,
@ -291,6 +291,7 @@ export class OneToManyLinkWidget extends RightAngleLinkWidget {
} }
paths.push(this.generateCustomEndWidget(onePoint)); paths.push(this.generateCustomEndWidget(onePoint));
for (let j = 0; j < points.length - 1; j++) { for (let j = 0; j < points.length - 1; j++) {
paths.push( paths.push(
this.generateLink( this.generateLink(
@ -319,7 +320,6 @@ export class OneToManyLinkWidget extends RightAngleLinkWidget {
} }
paths.push(this.generateCustomEndWidget(manyPoint)); paths.push(this.generateCustomEndWidget(manyPoint));
this.refPaths = []; this.refPaths = [];
return <StyledG data-default-link-test={this.props.link.getOptions().testName}>{paths}</StyledG>; return <StyledG data-default-link-test={this.props.link.getOptions().testName}>{paths}</StyledG>;
} }

View File

@ -3,7 +3,7 @@ import CustomPropTypes from '../../../../pgadmin/static/js/custom_prop_types';
export * from '@mui/material'; export * from '@mui/material';
// mock popper // mock popper
// eslint-disable-next-line no-unused-vars
export const Popper = React.forwardRef((props, _ref)=>{ export const Popper = React.forwardRef((props, _ref)=>{
const ele = useRef(); const ele = useRef();
return <div ref={ele} data-test="material-popper">{props.children}</div>; return <div ref={ele} data-test="material-popper">{props.children}</div>;

View File

@ -2,7 +2,7 @@ import React, { useRef } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
export * from 'react-data-grid'; export * from 'react-data-grid';
// eslint-disable-next-line no-unused-vars
const ReactDataGrid = React.forwardRef((props, _ref)=>{ const ReactDataGrid = React.forwardRef((props, _ref)=>{
const ele = useRef(); const ele = useRef();
return <div id={props.id} ref={ele} data-test="react-data-grid"/>; return <div id={props.id} ref={ele} data-test="react-data-grid"/>;

View File

@ -230,7 +230,7 @@ describe('ERDCore', ()=>{
})); }));
}); });
it('deserializeData', (done)=>{ it('deserializeData', ()=>{
let nodesDict = {}; let nodesDict = {};
TEST_TABLES_DATA.forEach((table)=>{ TEST_TABLES_DATA.forEach((table)=>{
nodesDict[`id-${table.name}`] = { nodesDict[`id-${table.name}`] = {
@ -269,11 +269,6 @@ describe('ERDCore', ()=>{
erdCoreObj.deserializeData(TEST_TABLES_DATA); erdCoreObj.deserializeData(TEST_TABLES_DATA);
expect(erdCoreObj.addNode).toHaveBeenCalledTimes(TEST_TABLES_DATA.length); expect(erdCoreObj.addNode).toHaveBeenCalledTimes(TEST_TABLES_DATA.length);
expect(erdCoreObj.addLink).toHaveBeenCalledTimes(1); expect(erdCoreObj.addLink).toHaveBeenCalledTimes(1);
setTimeout(()=>{
expect(erdCoreObj.dagreDistributeNodes).toHaveBeenCalled();
done();
}, 500);
}); });
it('clearSelection', ()=>{ it('clearSelection', ()=>{

View File

@ -6845,6 +6845,19 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"eslint-plugin-unused-imports@npm:^4.1.4":
version: 4.1.4
resolution: "eslint-plugin-unused-imports@npm:4.1.4"
peerDependencies:
"@typescript-eslint/eslint-plugin": ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0
eslint: ^9.0.0 || ^8.0.0
peerDependenciesMeta:
"@typescript-eslint/eslint-plugin":
optional: true
checksum: 1f4ce3e3972699345513840f3af1b783033dbc3a3e85b62ce12b3f6a89fd8c92afe46d0c00af40bacb14465445983ba0ccc326a6fd5132553061fb0e47bcba19
languageName: node
linkType: hard
"eslint-rule-composer@npm:^0.3.0": "eslint-rule-composer@npm:^0.3.0":
version: 0.3.0 version: 0.3.0
resolution: "eslint-rule-composer@npm:0.3.0" resolution: "eslint-rule-composer@npm:0.3.0"
@ -13320,6 +13333,7 @@ __metadata:
eslint: ^9.11.1 eslint: ^9.11.1
eslint-plugin-jest: ^28.8.0 eslint-plugin-jest: ^28.8.0
eslint-plugin-react: ^7.34.3 eslint-plugin-react: ^7.34.3
eslint-plugin-unused-imports: ^4.1.4
exports-loader: ^5.0.0 exports-loader: ^5.0.0
globals: ^15.8.0 globals: ^15.8.0
hotkeys-js: ^3.13.3 hotkeys-js: ^3.13.3