From 3dd94685cbdba580761e177c0e2af82080b99c9b Mon Sep 17 00:00:00 2001
From: james-strauss-uwa <james.strauss@uwa.edu.au>
Date: Fri, 13 Oct 2023 12:04:07 +0800
Subject: [PATCH] Fix bug when adding new node by clicking on a component icon
 in a palette

---
 src/Eagle.ts                             | 27 +++++++++++--------
 src/RightClick.ts                        | 33 ++++++++++++------------
 static/components/palette-component.html |  2 +-
 3 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/src/Eagle.ts b/src/Eagle.ts
index a78f5b4dd..707e48d0d 100644
--- a/src/Eagle.ts
+++ b/src/Eagle.ts
@@ -3104,8 +3104,8 @@ export class Eagle {
         }
     }
 
-    addNodeToLogicalGraphAndConnect = (newNode:Node) : void => {
-        this.addNodeToLogicalGraph(newNode,(node: Node)=>{
+    addNodeToLogicalGraphAndConnect = (newNodeId: string) : void => {
+        this.addNodeToLogicalGraph(null, newNodeId, Eagle.AddNodeMode.ContextMenu, (node: Node)=>{
             const realSourceNode = RightClick.edgeDropSrcNode;
             const realSourcePort = RightClick.edgeDropSrcPort;
             const realDestNode = node;
@@ -3122,10 +3122,10 @@ export class Eagle {
             } else {    
                 this.addEdge(realDestNode, realDestPort, realSourceNode, realSourcePort, false, false, null);
             }
-        },'contextMenu')
+        });
     }
 
-    addNodeToLogicalGraph = (node : any, callback: (node: Node) => void, mode:string) : void => {
+    addNodeToLogicalGraph = (node: Node, nodeId: string, mode: Eagle.AddNodeMode, callback: (node: Node) => void) : void => {
         let pos : {x:number, y:number};
         pos = {x:0,y:0}
         
@@ -3136,19 +3136,19 @@ export class Eagle {
             return;
         }
 
-        if(mode === 'contextMenu'){
+        if(mode === Eagle.AddNodeMode.ContextMenu){
             let nodeFound = false 
 
             pos = Eagle.selectedRightClickPosition;
             this.palettes().forEach(function(palette){
-                if(palette.findNodeById(node)!==null){
-                    node = palette.findNodeById(node)
+                if(palette.findNodeById(nodeId)!==null){
+                    node = palette.findNodeById(nodeId)
                     nodeFound = true
                 }
             })
 
             if (!nodeFound){
-                node = this.logicalGraph().findNodeById(node)
+                node = this.logicalGraph().findNodeById(nodeId)
             }
             $('#customContextMenu').remove()
         }
@@ -3162,7 +3162,7 @@ export class Eagle {
         if(pos.x === 0 && pos.y === 0){
             // get new position for node
             if (Eagle.nodeDropLocation.x === 0 && Eagle.nodeDropLocation.y === 0){
-                pos = this.getNewNodePosition(node.getWidth(), node.getHeight());
+                pos = this.getNewNodePosition(node.getRadius(), node.getRadius());
             } else {
                 pos = Eagle.nodeDropLocation;
             }
@@ -3849,7 +3849,7 @@ export class Eagle {
 
         // add each of the nodes we are moving
         for (const sourceComponent of sourceComponents){
-            this.addNodeToLogicalGraph(sourceComponent, null,'');
+            this.addNodeToLogicalGraph(sourceComponent, "", Eagle.AddNodeMode.Default, null);
 
             // to avoid placing all the selected nodes on top of each other at the same spot, we increment the nodeDropLocation after each node
             Eagle.nodeDropLocation.x += 20;
@@ -4212,7 +4212,7 @@ export class Eagle {
         });
     }
 
-    getNewNodePosition = (width:number, height:number) : {x:number, y:number} => {
+    getNewNodePosition = (width: number, height: number) : {x:number, y:number} => {
         const MARGIN = 100; // buffer to keep new nodes away from the maxX and maxY sides of the LG display area
         let suitablePositionFound = false;
         let numIterations = 0;
@@ -4605,6 +4605,11 @@ export namespace Eagle
         Hierarchy = "Hierarchy"
     }
 
+    export enum AddNodeMode {
+        ContextMenu = "ContextMenu",
+        Default = "Default"
+    }
+
     export enum FileType {
         Graph = "Graph",
         Palette = "Palette",
diff --git a/src/RightClick.ts b/src/RightClick.ts
index 920f3bbd8..c41ee13dd 100644
--- a/src/RightClick.ts
+++ b/src/RightClick.ts
@@ -1,8 +1,7 @@
-import {Eagle} from './Eagle';
-import {Edge} from './Edge';
-import {Node} from './Node';
+import { Eagle } from './Eagle';
+import { Edge } from './Edge';
+import { Node } from './Node';
 import { Palette } from './Palette';
-import { TutorialSystem } from './Tutorial';
 import { Setting } from './Setting';
 
 
@@ -148,7 +147,7 @@ export class RightClick {
 
         //toggling showing only filtered nodes or showing all
         if(!Setting.findValue(Setting.FILTER_NODE_SUGGESTIONS)){
-            let x : Node[] = []
+            const x : Node[] = []
             palettes.forEach(function(palette){
 
                 palette.getNodes().forEach(function(node){
@@ -218,13 +217,13 @@ export class RightClick {
             collectionOfNodes.forEach(function(node){
                 //this mode is the simplest version for right click adding a node on the graph canvas
                 if(node.isData()){
-                    dataHtml = dataHtml+`<a id='rightclickNode_`+node.getId()+`' onclick='eagle.addNodeToLogicalGraph("`+node.getId()+`",null,"contextMenu")' class='contextMenuDropdownOption rightClickPaletteNode `+originClass+`'>`+node.getName()+'</a>'
+                    dataHtml = dataHtml+`<a id='rightclickNode_`+node.getId()+`' onclick='eagle.addNodeToLogicalGraph(null,"`+node.getId()+`",Eagle.AddNodeMode.ContextMenu, null)' class='contextMenuDropdownOption rightClickPaletteNode `+originClass+`'>`+node.getName()+'</a>'
                     dataFound = true
                 }else if (node.isApplication()){
-                    appHtml = appHtml+`<a id='rightclickNode_`+node.getId()+`' onclick='eagle.addNodeToLogicalGraph("`+node.getId()+`",null,"contextMenu")' class='contextMenuDropdownOption rightClickPaletteNode `+originClass+`'>`+node.getName()+'</a>'
+                    appHtml = appHtml+`<a id='rightclickNode_`+node.getId()+`' onclick='eagle.addNodeToLogicalGraph(null,"`+node.getId()+`",Eagle.AddNodeMode.ContextMenu, null)' class='contextMenuDropdownOption rightClickPaletteNode `+originClass+`'>`+node.getName()+'</a>'
                     appFound = true
                 }else{
-                    otherHtml = otherHtml+`<a id='rightclickNode_`+node.getId()+`' onclick='eagle.addNodeToLogicalGraph("`+node.getId()+`",null,"contextMenu")' class='contextMenuDropdownOption rightClickPaletteNode `+originClass+`'>`+node.getName()+'</a>'
+                    otherHtml = otherHtml+`<a id='rightclickNode_`+node.getId()+`' onclick='eagle.addNodeToLogicalGraph(null,"`+node.getId()+`",Eagle.AddNodeMode.ContextMenu, null)' class='contextMenuDropdownOption rightClickPaletteNode `+originClass+`'>`+node.getName()+'</a>'
                     otherFound = true
                 }
                 nodeFound = true
@@ -428,8 +427,8 @@ export class RightClick {
             Eagle.selectedRightClickPosition = {x:x, y:y};
         }
         
-        var selectedObjectAmount = eagle.selectedObjects().length
-        var rightClickObjectInSelection = false
+        const selectedObjectAmount = eagle.selectedObjects().length
+        let rightClickObjectInSelection = false
         if (selectedObjectAmount > 1){
             //if more than one node is selected
             eagle.selectedObjects().forEach(function(selectedObject){
@@ -452,7 +451,7 @@ export class RightClick {
             //append function options depending on the right click object
             if(passedObjectClass === 'rightClick_logicalGraph'){
                 if(Setting.findValue(Setting.ALLOW_GRAPH_EDITING)){
-                    var searchbar = `<div class="searchBarContainer" data-bind="clickBubble:false, click:function(){}">
+                    const searchbar = `<div class="searchBarContainer" data-bind="clickBubble:false, click:function(){}">
                         <i class="material-icons md-18 searchBarIcon">search</i>
                         <a onclick="RightClick.clearSearchField()">
                             <i class="material-icons md-18 searchBarIconClose">close</i>
@@ -463,7 +462,7 @@ export class RightClick {
                     $('#customContextMenu').append(searchbar)
     
                     $('#customContextMenu').append('<div id="rightClickPaletteList"></div>')
-                    var paletteList = RightClick.createHtmlPaletteList()
+                    const paletteList = RightClick.createHtmlPaletteList()
     
                     $('#rightClickPaletteList').append(paletteList)
     
@@ -471,12 +470,12 @@ export class RightClick {
                     $('#rightClickSearchBar').focus()
                     RightClick.initiateQuickSelect()
                 }else{
-                    var message = '<span>Lacking graph editing permissions</span>'
+                    const message = '<span>Lacking graph editing permissions</span>'
                     $('#customContextMenu').append(message)
                 }
             }else if(passedObjectClass === 'edgeDropCreate'){
                 if(Setting.findValue(Setting.ALLOW_GRAPH_EDITING)){
-                    var searchbar = `<div class="searchBarContainer" data-bind="clickBubble:false, click:function(){}">
+                    const searchbar = `<div class="searchBarContainer" data-bind="clickBubble:false, click:function(){}">
                         <i class="material-icons md-18 searchBarIcon">search</i>
                         <a onclick="RightClick.clearSearchField()">
                             <i class="material-icons md-18 searchBarIconClose">close</i>
@@ -487,14 +486,14 @@ export class RightClick {
                     $('#customContextMenu').append(searchbar)
     
                     $('#customContextMenu').append('<div id="rightClickPaletteList"></div>')
-                    var paletteList = RightClick.createHtmlEdgeDragList(data)
+                    const paletteList = RightClick.createHtmlEdgeDragList(data)
                     $('#rightClickPaletteList').append(paletteList)
     
                     Eagle.selectedRightClickLocation(Eagle.FileType.Graph)
                     $('#rightClickSearchBar').focus()
                     RightClick.initiateQuickSelect()
                 }else{
-                    var message = '<span>Lacking graph editing permissions</span>'
+                    const message = '<span>Lacking graph editing permissions</span>'
                     $('#customContextMenu').append(message)
                 }
             }else if(passedObjectClass === 'rightClick_paletteComponent'){
@@ -559,7 +558,7 @@ export class RightClick {
             }
         }
         // adding a listener to function options that closes the menu if an option is clicked
-        $('#customContextMenu a').on('click',function(){if($(event.target).parents('.searchBarContainer').length){return};RightClick.closeCustomContextMenu(true)})
+        $('#customContextMenu a').on('click',function(){if($(event.target).parents('.searchBarContainer').length){return}RightClick.closeCustomContextMenu(true)})
     }
 
 }
diff --git a/static/components/palette-component.html b/static/components/palette-component.html
index bdf3a4550..1aa9c06a9 100644
--- a/static/components/palette-component.html
+++ b/static/components/palette-component.html
@@ -2,7 +2,7 @@
     <div class="col"  draggable="true" data-bind="event: {dragstart: SideWindow.nodeDragStart, dragend: SideWindow.nodeDragEnd}, attr: {'data-palette-index': $parentContext.$parentContext.$index, 'data-component-index': $index}">
         <div class="input-group mb-1 rightClick_paletteComponent"  data-bind="attr: {id: 'palette_'  + $parentContext.$parentContext.$index() + '_' + $data.getPaletteComponentId()}, click: $root.paletteComponentClick, eagleTooltip: $data.getHelpHTML(), eagleRightClick: {data:$data,type:'rightClick_paletteComponent'}">
             <div class="input-group-prepend">
-                <button class="nodeBtn" type="button" data-bind="click: function(){$root.addNodeToLogicalGraph($data, null,'')}, clickBubble: false, attr: {id: 'addPaletteNode' + $data.getNoWhiteSpaceName()}">
+                <button class="nodeBtn" type="button" data-bind="click: function(){$root.addNodeToLogicalGraph($data, '', Eagle.AddNodeMode.Default, null)}, clickBubble: false, attr: {id: 'addPaletteNode' + $data.getNoWhiteSpaceName()}">
                     <span class="input-group-text" data-bind="style: {'background-color': $data.color}">
                         <i data-bind="class: $data.getIcon()"></i>
                     </span>