diff --git a/web/pgadmin/tools/erd/__init__.py b/web/pgadmin/tools/erd/__init__.py index b951ecb53..260b5a70e 100644 --- a/web/pgadmin/tools/erd/__init__.py +++ b/web/pgadmin/tools/erd/__init__.py @@ -547,8 +547,10 @@ def translate_foreign_keys(tab_fks, tab_data, all_nodes): for tab_fk in tab_fks: if 'columns' not in tab_fk: continue - print(tab_data) - remote_table = all_nodes[tab_fk['columns'][0]['references']] + try: + remote_table = all_nodes[tab_fk['columns'][0]['references']] + except KeyError: + continue tab_fk['schema'] = tab_data['schema'] tab_fk['table'] = tab_data['name'] tab_fk['remote_schema'] = remote_table['schema'] diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/ERDCore.js b/web/pgadmin/tools/erd/static/js/erd_tool/ERDCore.js index e3de3670a..0265668a9 100644 --- a/web/pgadmin/tools/erd/static/js/erd_tool/ERDCore.js +++ b/web/pgadmin/tools/erd/static/js/erd_tool/ERDCore.js @@ -210,6 +210,26 @@ export default class ERDCore { return newNode; } + removeNode(node) { + let self = this; + node.setSelected(false); + Object.values(node.getPorts()).forEach((port)=>{ + Object.values(port.getLinks()).forEach((link)=>{ + self.removeOneToManyLink(link); + }); + }); + node.remove(); + } + + anyDuplicateNodeName(newNodeData, oldNodeData) { + if(newNodeData.name == oldNodeData?.name && newNodeData.schema == oldNodeData?.schema) { + return false; + } + return _.filter(this.getNodesData(), (n)=>{ + return n.name==newNodeData.name && n.schema==newNodeData.schema; + }).length > 0; + } + addLink(data, type) { let tableNodesDict = this.getModel().getNodesDict(); let sourceNode = tableNodesDict[data.referenced_table_uid]; diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/DialogWrapper.js b/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/DialogWrapper.js index 4fe960f45..c46bde715 100644 --- a/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/DialogWrapper.js +++ b/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/DialogWrapper.js @@ -69,11 +69,15 @@ export default class DialogWrapper { }; } - onSaveClick(isNew, data) { - return new Promise((resolve)=>{ - this.okCallback(data); - this.close(); - resolve(); + onSaveClick(_isNew, data) { + return new Promise((resolve, reject)=>{ + let errorMsg = this.okCallback(data); + if(errorMsg) { + reject(errorMsg); + } else { + this.close(); + resolve(); + } }); } diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx index afd3689b4..2b598d808 100644 --- a/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx +++ b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx @@ -347,14 +347,20 @@ export default class BodyWidget extends React.Component { let dialog = this.getDialog('table_dialog'); if(node) { let [schema, table] = node.getSchemaTableName(); - dialog(gettext('Table: %s (%s)', _.escape(table),_.escape(schema)), node.getData(), false, (newData)=>{ - let oldData = node.getData(); + let oldData = node.getData(); + dialog(gettext('Table: %s (%s)', _.escape(table),_.escape(schema)), oldData, false, (newData)=>{ + if(this.diagram.anyDuplicateNodeName(newData, oldData)) { + return gettext('Table name already exists'); + } node.setData(newData); this.diagram.syncTableLinks(node, oldData); this.diagram.repaint(); }); } else { dialog(gettext('New table'), {}, true, (newData)=>{ + if(this.diagram.anyDuplicateNodeName(newData)) { + return gettext('Table name already exists'); + } let newNode = this.diagram.addNode(newData); this.diagram.syncTableLinks(newNode); newNode.setSelected(true); @@ -424,8 +430,7 @@ export default class BodyWidget extends React.Component { + '
' + gettext('Are you sure you want to delete ?'), () => { this.diagram.getSelectedNodes().forEach((node)=>{ - node.setSelected(false); - node.remove(); + this.diagram.removeNode(node); }); this.diagram.getSelectedLinks().forEach((link)=>{ this.diagram.removeOneToManyLink(link);