From d277564dfb9fcbd2528c1a0266080326f2aaffbe Mon Sep 17 00:00:00 2001 From: MWicenec Date: Tue, 2 Jul 2024 12:43:44 +0800 Subject: [PATCH 01/17] re enabled port highlighting when drawing edge s --- src/Eagle.ts | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/Eagle.ts b/src/Eagle.ts index 2ae9f4858..3477713ee 100644 --- a/src/Eagle.ts +++ b/src/Eagle.ts @@ -3324,7 +3324,29 @@ export class Eagle { // find child nodes for (const object of data){ if (object instanceof Node){ - childNodes.push(...this._findChildren(object)); + // find children of this node + const children = this._findChildren(object); + + for (const child of children){ + // check each child is not already in selectedObjects + if (this.objectIsSelected(child)){ + continue; + } + + // check each child is not already in childNodes + let found: boolean = false; + for (const cn of childNodes){ + if (cn.getId() === child.getId()){ + found = true; + break; + } + } + + // add to childNodes + if (!found){ + childNodes.push(child); + } + } } } @@ -3332,7 +3354,12 @@ export class Eagle { for (const edge of this.logicalGraph().getEdges()){ for (const node of childNodes){ if (edge.getSrcNodeKey() === node.getKey() || edge.getDestNodeKey() === node.getKey()){ - // check if edge as already in the list + // check if edge is already in selectedObjects + if (this.objectIsSelected(edge)){ + continue; + } + + // check if edge is already in the childEdges list let found = false; for (const e of childEdges){ if (e.getId() === edge.getId()){ From cc350cb66ac19591c388e7523993e2d72d9d65f2 Mon Sep 17 00:00:00 2001 From: M-Wicenec Date: Tue, 2 Jul 2024 14:23:25 +0800 Subject: [PATCH 02/17] highlighting valid ports for the connection --- src/GraphRenderer.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/GraphRenderer.ts b/src/GraphRenderer.ts index 4b968e515..ca42f12cc 100644 --- a/src/GraphRenderer.ts +++ b/src/GraphRenderer.ts @@ -1662,6 +1662,7 @@ export class GraphRenderer { //setting up the port event listeners $('#logicalGraphParent').on('mouseup.portDrag',function(){GraphRenderer.portDragEnd()}) $('.node .body').on('mouseup.portDrag',function(){GraphRenderer.portDragEnd()}) + port.setPeek(true) // build the list of all ports in the graph that are a valid end-point for an edge starting at this port GraphRenderer.matchingPortList = GraphRenderer.findMatchingPorts(GraphRenderer.portDragSourceNode(), GraphRenderer.portDragSourcePort()); @@ -1685,7 +1686,6 @@ export class GraphRenderer { static portDragEnd() : void { const eagle = Eagle.getInstance(); - GraphRenderer.draggingPort = false; // cleaning up the port drag event listeners $('#logicalGraphParent').off('mouseup.portDrag') @@ -1734,6 +1734,7 @@ export class GraphRenderer { GraphRenderer.clearEdgeVars(); } } + GraphRenderer.portDragSourcePort().setPeek(false) } //resetting some global cached variables @@ -2031,6 +2032,7 @@ export class GraphRenderer { if (isValidIndex >= minValidityIndex){ result.push({node: node, field: port}); + port.setPeek(true) } } } From 4c32c39b123ba35a47b02ca362923a054d892810 Mon Sep 17 00:00:00 2001 From: M-Wicenec Date: Tue, 2 Jul 2024 14:55:42 +0800 Subject: [PATCH 03/17] instead of returning in a lot of cases we are now adding to the edge log --- src/Edge.ts | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/Edge.ts b/src/Edge.ts index bcba7f167..1e5df2144 100644 --- a/src/Edge.ts +++ b/src/Edge.ts @@ -278,6 +278,12 @@ export class Edge { } static isValid(eagle: Eagle, edgeId: string, sourceNodeKey : number, sourcePortId : string, destinationNodeKey : number, destinationPortId : string, loopAware: boolean, closesLoop: boolean, showNotification : boolean, showConsole : boolean, errorsWarnings: Errors.ErrorsWarnings) : Edge.Validity { + + const edgeValidityUnknown : boolean = false; + const edgeValidityWarning : boolean = false; + const edgeInvalid : boolean = false; + const edgeImpossible : boolean = false; + // check for problems if (isNaN(sourceNodeKey)){ return Edge.Validity.Unknown; @@ -289,46 +295,46 @@ export class Edge { if (sourcePortId === ""){ const issue = Errors.Fix("source port has no id", function(){Utils.fixNodeFieldIds(eagle, sourceNodeKey)}, "Generate ids for ports on source node"); - Edge.isValidLog(edgeId, Edge.Validity.Invalid, issue, showNotification, showConsole, errorsWarnings); - return Edge.Validity.Invalid; + Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + return Edge.Validity.Impossible; } if (destinationPortId === ""){ const issue = Errors.Fix("destination port has no id", function(){Utils.fixNodeFieldIds(eagle, sourceNodeKey)}, "Generate ids for ports on destination node"); - Edge.isValidLog(edgeId, Edge.Validity.Invalid, issue, showNotification, showConsole, errorsWarnings); - return Edge.Validity.Invalid; + Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + return Edge.Validity.Impossible; } if (sourcePortId === null){ const issue = Errors.Fix("source port id is null", function(){Utils.fixNodeFieldIds(eagle, sourceNodeKey)}, "Generate ids for ports on source node"); - Edge.isValidLog(edgeId, Edge.Validity.Invalid, issue, showNotification, showConsole, errorsWarnings); - return Edge.Validity.Invalid; + Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + return Edge.Validity.Impossible; } if (destinationPortId === null){ const issue = Errors.Fix("destination port id is null", function(){Utils.fixNodeFieldIds(eagle, sourceNodeKey)}, "Generate ids for ports on destination node"); - Edge.isValidLog(edgeId, Edge.Validity.Invalid, issue, showNotification, showConsole, errorsWarnings); - return Edge.Validity.Invalid; + Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + return Edge.Validity.Impossible; } // get references to actual source and destination nodes (from the keys) const sourceNode : Node = eagle.logicalGraph().findNodeByKey(sourceNodeKey); const destinationNode : Node = eagle.logicalGraph().findNodeByKey(destinationNodeKey); + if (sourceNode === null || typeof sourceNode === "undefined" || destinationNode === null || typeof destinationNode === "undefined"){ + return Edge.Validity.Unknown; + } + // check that we are not connecting two ports within the same node if (sourceNodeKey === destinationNodeKey){ Edge.isValidLog(edgeId, Edge.Validity.Impossible, Errors.Show("sourceNodeKey and destinationNodeKey are the same", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); - return Edge.Validity.Impossible; - } - - if (sourceNode === null || typeof sourceNode === "undefined" || destinationNode === null || typeof destinationNode === "undefined"){ - return Edge.Validity.Unknown; + // return Edge.Validity.Impossible; } // check that we are not connecting a Data component to a Data component, that is not supported if (sourceNode.getCategoryType() === Category.Type.Data && destinationNode.getCategoryType() === Category.Type.Data){ Edge.isValidLog(edgeId, Edge.Validity.Invalid, Errors.Show("Data nodes may not be connected directly to other Data nodes", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); - return Edge.Validity.Invalid; + // return Edge.Validity.Invalid; } // if source node or destination node is a construct, then something is wrong, constructs should not have ports @@ -357,34 +363,34 @@ export class Edge { if (sourcePort === null) { const issue: Errors.Issue = Errors.ShowFix("Source port (" + sourcePortId + ") doesn't exist on source node (" + sourceNode.getName() + ")", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.addSourcePortToSourceNode(eagle, edgeId)}, "Add source port to source node"); Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); - return Edge.Validity.Impossible; + // return Edge.Validity.Impossible; } // check if destination port was found if (destinationPort === null){ const issue: Errors.Issue = Errors.ShowFix("Destination port (" + destinationPortId + ") doesn't exist on destination node (" + destinationNode.getName() + ")", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.addDestinationPortToDestinationNode(eagle, edgeId)}, "Add destination port to destination node"); Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); - return Edge.Validity.Impossible; + // return Edge.Validity.Impossible; } // check that we are not connecting a port to itself if (sourcePortId === destinationPortId){ Edge.isValidLog(edgeId, Edge.Validity.Impossible, Errors.Show("Source port and destination port are the same", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); - return Edge.Validity.Impossible; + // return Edge.Validity.Impossible; } // check that source is output if (!sourcePort.isOutputPort()){ const issue: Errors.Issue = Errors.ShowFix("Source port is not output port (" + sourcePort.getUsage() + ")", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixFieldUsage(eagle, sourcePort, Daliuge.FieldUsage.OutputPort)}, "Add output usage to source port"); Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); - return Edge.Validity.Impossible; + // return Edge.Validity.Impossible; } // check that destination in input if (!destinationPort.isInputPort()){ const issue: Errors.Issue = Errors.ShowFix("Destination port is not input port (" + destinationPort.getUsage() + ")", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixFieldUsage(eagle, destinationPort, Daliuge.FieldUsage.InputPort)}, "Add input usage to destination port"); Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); - return Edge.Validity.Impossible; + // return Edge.Validity.Impossible; } if (sourcePort !== null && destinationPort !== null){ From c7554edc224eeb3d6ba388127c6b84ebfd712839 Mon Sep 17 00:00:00 2001 From: M-Wicenec Date: Tue, 2 Jul 2024 15:03:17 +0800 Subject: [PATCH 04/17] new edge is valid function for auto suggestions now also checks embedded apps --- src/GraphRenderer.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/GraphRenderer.ts b/src/GraphRenderer.ts index 4b968e515..ea0d4bb3a 100644 --- a/src/GraphRenderer.ts +++ b/src/GraphRenderer.ts @@ -2024,7 +2024,19 @@ export class GraphRenderer { const minValidity: Edge.Validity = Setting.findValue(Setting.AUTO_COMPLETE_EDGES_LEVEL); const minValidityIndex: number = Object.values(Edge.Validity).indexOf(minValidity); + const potentialNodes :Node[] = [] + for (const node of eagle.logicalGraph().getNodes()){ + potentialNodes.push(node) + if(node.isConstruct && node.getInputApplication()){ + potentialNodes.push(node.getInputApplication()) + } + if(node.isConstruct && node.getOutputApplication()){ + potentialNodes.push(node.getOutputApplication()) + } + } + + for(const node of potentialNodes){ for (const port of node.getPorts()){ const isValid: Edge.Validity = Edge.isValid(eagle, "", sourceNode.getKey(), sourcePort.getId(), node.getKey(), port.getId(), false, false, false, false, {errors:[], warnings:[]}); const isValidIndex: number = Object.values(Edge.Validity).indexOf(isValid); From 45f2bbc9fadca55c8bf09a51e083baa3f7f6a213 Mon Sep 17 00:00:00 2001 From: M-Wicenec Date: Tue, 2 Jul 2024 15:08:43 +0800 Subject: [PATCH 05/17] small indent change --- src/Edge.ts | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/Edge.ts b/src/Edge.ts index 1e5df2144..9521c9fbc 100644 --- a/src/Edge.ts +++ b/src/Edge.ts @@ -279,11 +279,6 @@ export class Edge { static isValid(eagle: Eagle, edgeId: string, sourceNodeKey : number, sourcePortId : string, destinationNodeKey : number, destinationPortId : string, loopAware: boolean, closesLoop: boolean, showNotification : boolean, showConsole : boolean, errorsWarnings: Errors.ErrorsWarnings) : Edge.Validity { - const edgeValidityUnknown : boolean = false; - const edgeValidityWarning : boolean = false; - const edgeInvalid : boolean = false; - const edgeImpossible : boolean = false; - // check for problems if (isNaN(sourceNodeKey)){ return Edge.Validity.Unknown; @@ -328,13 +323,11 @@ export class Edge { // check that we are not connecting two ports within the same node if (sourceNodeKey === destinationNodeKey){ Edge.isValidLog(edgeId, Edge.Validity.Impossible, Errors.Show("sourceNodeKey and destinationNodeKey are the same", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); - // return Edge.Validity.Impossible; } // check that we are not connecting a Data component to a Data component, that is not supported if (sourceNode.getCategoryType() === Category.Type.Data && destinationNode.getCategoryType() === Category.Type.Data){ Edge.isValidLog(edgeId, Edge.Validity.Invalid, Errors.Show("Data nodes may not be connected directly to other Data nodes", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); - // return Edge.Validity.Invalid; } // if source node or destination node is a construct, then something is wrong, constructs should not have ports @@ -342,6 +335,7 @@ export class Edge { const issue: Errors.Issue = Errors.ShowFix("Edge (" + edgeId + ") cannot have a source node (" + sourceNode.getName() + ") that is a construct", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.fixMoveEdgeToEmbeddedApplication(eagle, edgeId)}, "Move edge to embedded application"); Edge.isValidLog(edgeId, Edge.Validity.Invalid, issue, showNotification, showConsole, errorsWarnings); } + if (destinationNode.getCategoryType() === Category.Type.Construct){ const issue: Errors.Issue = Errors.ShowFix("Edge (" + edgeId + ") cannot have a destination node (" + destinationNode.getName() + ") that is a construct", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.fixMoveEdgeToEmbeddedApplication(eagle, edgeId)}, "Move edge to embedded application"); Edge.isValidLog(edgeId, Edge.Validity.Invalid, issue, showNotification, showConsole, errorsWarnings); @@ -363,34 +357,29 @@ export class Edge { if (sourcePort === null) { const issue: Errors.Issue = Errors.ShowFix("Source port (" + sourcePortId + ") doesn't exist on source node (" + sourceNode.getName() + ")", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.addSourcePortToSourceNode(eagle, edgeId)}, "Add source port to source node"); Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); - // return Edge.Validity.Impossible; } // check if destination port was found if (destinationPort === null){ const issue: Errors.Issue = Errors.ShowFix("Destination port (" + destinationPortId + ") doesn't exist on destination node (" + destinationNode.getName() + ")", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.addDestinationPortToDestinationNode(eagle, edgeId)}, "Add destination port to destination node"); Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); - // return Edge.Validity.Impossible; } // check that we are not connecting a port to itself if (sourcePortId === destinationPortId){ Edge.isValidLog(edgeId, Edge.Validity.Impossible, Errors.Show("Source port and destination port are the same", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); - // return Edge.Validity.Impossible; } // check that source is output if (!sourcePort.isOutputPort()){ const issue: Errors.Issue = Errors.ShowFix("Source port is not output port (" + sourcePort.getUsage() + ")", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixFieldUsage(eagle, sourcePort, Daliuge.FieldUsage.OutputPort)}, "Add output usage to source port"); Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); - // return Edge.Validity.Impossible; } // check that destination in input if (!destinationPort.isInputPort()){ const issue: Errors.Issue = Errors.ShowFix("Destination port is not input port (" + destinationPort.getUsage() + ")", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixFieldUsage(eagle, destinationPort, Daliuge.FieldUsage.InputPort)}, "Add input usage to destination port"); Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); - // return Edge.Validity.Impossible; } if (sourcePort !== null && destinationPort !== null){ From 36773ef459edde97c14a7b6fe21da74764a0bcfb Mon Sep 17 00:00:00 2001 From: M-Wicenec Date: Tue, 2 Jul 2024 16:35:10 +0800 Subject: [PATCH 06/17] wip still got a bug --- src/Edge.ts | 21 ++++++++++++++------- src/GraphRenderer.ts | 9 ++++++++- src/Utils.ts | 1 - 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/Edge.ts b/src/Edge.ts index 9521c9fbc..59b43d278 100644 --- a/src/Edge.ts +++ b/src/Edge.ts @@ -279,6 +279,8 @@ export class Edge { static isValid(eagle: Eagle, edgeId: string, sourceNodeKey : number, sourcePortId : string, destinationNodeKey : number, destinationPortId : string, loopAware: boolean, closesLoop: boolean, showNotification : boolean, showConsole : boolean, errorsWarnings: Errors.ErrorsWarnings) : Edge.Validity { + let impossibleEdge : boolean = false; + // check for problems if (isNaN(sourceNodeKey)){ return Edge.Validity.Unknown; @@ -320,11 +322,6 @@ export class Edge { return Edge.Validity.Unknown; } - // check that we are not connecting two ports within the same node - if (sourceNodeKey === destinationNodeKey){ - Edge.isValidLog(edgeId, Edge.Validity.Impossible, Errors.Show("sourceNodeKey and destinationNodeKey are the same", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); - } - // check that we are not connecting a Data component to a Data component, that is not supported if (sourceNode.getCategoryType() === Category.Type.Data && destinationNode.getCategoryType() === Category.Type.Data){ Edge.isValidLog(edgeId, Edge.Validity.Invalid, Errors.Show("Data nodes may not be connected directly to other Data nodes", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); @@ -335,7 +332,7 @@ export class Edge { const issue: Errors.Issue = Errors.ShowFix("Edge (" + edgeId + ") cannot have a source node (" + sourceNode.getName() + ") that is a construct", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.fixMoveEdgeToEmbeddedApplication(eagle, edgeId)}, "Move edge to embedded application"); Edge.isValidLog(edgeId, Edge.Validity.Invalid, issue, showNotification, showConsole, errorsWarnings); } - + if (destinationNode.getCategoryType() === Category.Type.Construct){ const issue: Errors.Issue = Errors.ShowFix("Edge (" + edgeId + ") cannot have a destination node (" + destinationNode.getName() + ") that is a construct", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.fixMoveEdgeToEmbeddedApplication(eagle, edgeId)}, "Move edge to embedded application"); Edge.isValidLog(edgeId, Edge.Validity.Invalid, issue, showNotification, showConsole, errorsWarnings); @@ -357,29 +354,34 @@ export class Edge { if (sourcePort === null) { const issue: Errors.Issue = Errors.ShowFix("Source port (" + sourcePortId + ") doesn't exist on source node (" + sourceNode.getName() + ")", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.addSourcePortToSourceNode(eagle, edgeId)}, "Add source port to source node"); Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + impossibleEdge = true; } // check if destination port was found if (destinationPort === null){ const issue: Errors.Issue = Errors.ShowFix("Destination port (" + destinationPortId + ") doesn't exist on destination node (" + destinationNode.getName() + ")", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.addDestinationPortToDestinationNode(eagle, edgeId)}, "Add destination port to destination node"); Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + impossibleEdge = true; } // check that we are not connecting a port to itself if (sourcePortId === destinationPortId){ Edge.isValidLog(edgeId, Edge.Validity.Impossible, Errors.Show("Source port and destination port are the same", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); + impossibleEdge = true; } // check that source is output if (!sourcePort.isOutputPort()){ const issue: Errors.Issue = Errors.ShowFix("Source port is not output port (" + sourcePort.getUsage() + ")", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixFieldUsage(eagle, sourcePort, Daliuge.FieldUsage.OutputPort)}, "Add output usage to source port"); Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + impossibleEdge = true; } // check that destination in input if (!destinationPort.isInputPort()){ const issue: Errors.Issue = Errors.ShowFix("Destination port is not input port (" + destinationPort.getUsage() + ")", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixFieldUsage(eagle, destinationPort, Daliuge.FieldUsage.InputPort)}, "Add input usage to destination port"); Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + impossibleEdge = true; } if (sourcePort !== null && destinationPort !== null){ @@ -474,7 +476,12 @@ export class Edge { } } - return Utils.worstEdgeError(errorsWarnings); + //the worst edge errror function can only check for entries in errors or warnings, it isnt able to distinguish impossible from invalid + if(impossibleEdge){ + return Edge.Validity.Impossible + }else{ + return Utils.worstEdgeError(errorsWarnings); + } } private static isValidLog(edgeId : string, linkValid : Edge.Validity, issue: Errors.Issue, showNotification : boolean, showConsole : boolean, errorsWarnings: Errors.ErrorsWarnings) : void { diff --git a/src/GraphRenderer.ts b/src/GraphRenderer.ts index ea0d4bb3a..af35bf159 100644 --- a/src/GraphRenderer.ts +++ b/src/GraphRenderer.ts @@ -2038,7 +2038,13 @@ export class GraphRenderer { for(const node of potentialNodes){ for (const port of node.getPorts()){ - const isValid: Edge.Validity = Edge.isValid(eagle, "", sourceNode.getKey(), sourcePort.getId(), node.getKey(), port.getId(), false, false, false, false, {errors:[], warnings:[]}); + let isValid: Edge.Validity + if(sourcePort.isInputPort()){ + isValid = Edge.isValid(eagle, "", sourceNode.getKey(), sourcePort.getId(), node.getKey(), port.getId(), false, false, false, false, {errors:[], warnings:[]}); + }else{ + isValid = Edge.isValid(eagle, "", node.getKey(), port.getId(), sourceNode.getKey(), sourcePort.getId(), false, false, false, false, {errors:[], warnings:[]}); + } + console.log(node.getName(),port.getDisplayText(),isValid) const isValidIndex: number = Object.values(Edge.Validity).indexOf(isValid); if (isValidIndex >= minValidityIndex){ @@ -2091,6 +2097,7 @@ export class GraphRenderer { if (minDistance Date: Wed, 3 Jul 2024 16:34:21 +0800 Subject: [PATCH 07/17] various changes to fix edge dragging, changing edge validity to an array on each edge --- src/Eagle.ts | 4 ++-- src/Edge.ts | 10 +++++++--- src/GraphRenderer.ts | 14 ++++++-------- src/Utils.ts | 2 +- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/Eagle.ts b/src/Eagle.ts index 3477713ee..ac19477ff 100644 --- a/src/Eagle.ts +++ b/src/Eagle.ts @@ -2854,7 +2854,7 @@ export class Eagle { } // validate edge - const isValid: Edge.Validity = Edge.isValid(this, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, true, null); + const isValid: Edge.Validity = Edge.isValid(this,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, true, null); if (isValid === Edge.Validity.Impossible || isValid === Edge.Validity.Invalid || isValid === Edge.Validity.Unknown){ Utils.showUserMessage("Error", "Invalid edge"); return; @@ -2899,7 +2899,7 @@ export class Eagle { } // validate edge - const isValid: Edge.Validity = Edge.isValid(this, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, true, null); + const isValid: Edge.Validity = Edge.isValid(this,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, true, null); if (isValid === Edge.Validity.Impossible || isValid === Edge.Validity.Invalid || isValid === Edge.Validity.Unknown){ Utils.showUserMessage("Error", "Invalid edge"); return; diff --git a/src/Edge.ts b/src/Edge.ts index 59b43d278..414e2a36e 100644 --- a/src/Edge.ts +++ b/src/Edge.ts @@ -43,6 +43,7 @@ export class Edge { private closesLoop : boolean; // indicates that this is a special type of edge that can be drawn in eagle to specify the start/end of groups. private selectionRelative : boolean // indicates if the edge is either selected or attached to a selected node private isShortEdge : ko.Observable; + private errors : {issue:Errors.Issue, validity:Edge.Validity}[] constructor(srcNodeKey : number, srcPortId : string, destNodeKey : number, destPortId : string, loopAware: boolean, closesLoop: boolean, selectionRelative : boolean){ this._id = Utils.uuidv4(); @@ -56,6 +57,7 @@ export class Edge { this.closesLoop = closesLoop; this.selectionRelative = selectionRelative; this.isShortEdge = ko.observable(false) + this.errors = []; } getId = () : string => { @@ -171,7 +173,7 @@ export class Edge { getErrorsWarnings = (eagle: Eagle): Errors.ErrorsWarnings => { const result: {warnings: Errors.Issue[], errors: Errors.Issue[]} = {warnings: [], errors: []}; - Edge.isValid(eagle, this._id, this.srcNodeKey, this.srcPortId, this.destNodeKey, this.destPortId, this.loopAware, this.closesLoop, false, false, result); + Edge.isValid(eagle,false, this._id, this.srcNodeKey, this.srcPortId, this.destNodeKey, this.destPortId, this.loopAware, this.closesLoop, false, false, result); return result; } @@ -277,7 +279,7 @@ export class Edge { return new Edge(edgeData.from, edgeData.fromPort, edgeData.to, edgeData.toPort, edgeData.loopAware, edgeData.closesLoop, false); } - static isValid(eagle: Eagle, edgeId: string, sourceNodeKey : number, sourcePortId : string, destinationNodeKey : number, destinationPortId : string, loopAware: boolean, closesLoop: boolean, showNotification : boolean, showConsole : boolean, errorsWarnings: Errors.ErrorsWarnings) : Edge.Validity { + static isValid(eagle: Eagle,autoSuggestMode:boolean, edgeId: string, sourceNodeKey : number, sourcePortId : string, destinationNodeKey : number, destinationPortId : string, loopAware: boolean, closesLoop: boolean, showNotification : boolean, showConsole : boolean, errorsWarnings: Errors.ErrorsWarnings) : Edge.Validity { let impossibleEdge : boolean = false; @@ -365,7 +367,7 @@ export class Edge { } // check that we are not connecting a port to itself - if (sourcePortId === destinationPortId){ + if (sourceNodeKey === destinationNodeKey){ Edge.isValidLog(edgeId, Edge.Validity.Impossible, Errors.Show("Source port and destination port are the same", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); impossibleEdge = true; } @@ -523,6 +525,7 @@ export class Edge { if (type === "warning" && errorsWarnings !== null){ errorsWarnings.warnings.push(issue); } + Eagle.getInstance().logicalGraph().findEdgeById(edgeId)?.errors.push({issue:issue, validity:linkValid}) } } @@ -532,6 +535,7 @@ export namespace Edge { Impossible = "Impossible", // never useful or valid Invalid = "Invalid", // invalid, but possibly useful for expert users? Warning = "Warning", // valid, but some issue that the user should be aware of + Fixable = "Fixable", // there is an issue with the connection but for drawing edges eagle will fix this for you Valid = "Valid" // fine } } diff --git a/src/GraphRenderer.ts b/src/GraphRenderer.ts index af35bf159..b1cfd0a56 100644 --- a/src/GraphRenderer.ts +++ b/src/GraphRenderer.ts @@ -1762,7 +1762,7 @@ export class GraphRenderer { } // check if link is valid - const linkValid : Edge.Validity = Edge.isValid(eagle, null, realSourceNode.getKey(), realSourcePort.getId(), realDestinationNode.getKey(), realDestinationPort.getId(), false, false, true, true, {errors:[], warnings:[]}); + const linkValid : Edge.Validity = Edge.isValid(eagle,false, null, realSourceNode.getKey(), realSourcePort.getId(), realDestinationNode.getKey(), realDestinationPort.getId(), false, false, true, true, {errors:[], warnings:[]}); // abort if edge is invalid if ((Setting.findValue(Setting.ALLOW_INVALID_EDGES) && linkValid === Edge.Validity.Invalid) || linkValid === Edge.Validity.Valid || linkValid === Edge.Validity.Warning){ @@ -2039,12 +2039,11 @@ export class GraphRenderer { for(const node of potentialNodes){ for (const port of node.getPorts()){ let isValid: Edge.Validity - if(sourcePort.isInputPort()){ - isValid = Edge.isValid(eagle, "", sourceNode.getKey(), sourcePort.getId(), node.getKey(), port.getId(), false, false, false, false, {errors:[], warnings:[]}); + if(!GraphRenderer.portDragSourcePortIsInput){ + isValid = Edge.isValid(eagle,true, "", sourceNode.getKey(), sourcePort.getId(), node.getKey(), port.getId(), false, false, false, false, {errors:[], warnings:[]}); }else{ - isValid = Edge.isValid(eagle, "", node.getKey(), port.getId(), sourceNode.getKey(), sourcePort.getId(), false, false, false, false, {errors:[], warnings:[]}); + isValid = Edge.isValid(eagle,true, "", node.getKey(), port.getId(), sourceNode.getKey(), sourcePort.getId(), false, false, false, false, {errors:[], warnings:[]}); } - console.log(node.getName(),port.getDisplayText(),isValid) const isValidIndex: number = Object.values(Edge.Validity).indexOf(isValid); if (isValidIndex >= minValidityIndex){ @@ -2097,7 +2096,6 @@ export class GraphRenderer { if (minDistance Date: Thu, 4 Jul 2024 13:19:25 +0800 Subject: [PATCH 08/17] wip commit --- src/Edge.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Edge.ts b/src/Edge.ts index 414e2a36e..303dcb6b8 100644 --- a/src/Edge.ts +++ b/src/Edge.ts @@ -529,11 +529,13 @@ export class Edge { } } +//change data structure of each nodes, fields and edges and new logicalgraph is valid function to be {issue, validity}[] +// move to errors, use for nodes,fields and edges export namespace Edge { export enum Validity { Unknown = "Unknown", // validity of the edge is unknown Impossible = "Impossible", // never useful or valid - Invalid = "Invalid", // invalid, but possibly useful for expert users? + Invalid = "Invalid", // invalid, but possibly useful for expert users? change to error Warning = "Warning", // valid, but some issue that the user should be aware of Fixable = "Fixable", // there is an issue with the connection but for drawing edges eagle will fix this for you Valid = "Valid" // fine From 77263e34ec0dbb7d7257301f6eaae6d87dce218f Mon Sep 17 00:00:00 2001 From: MWicenec Date: Fri, 5 Jul 2024 14:24:19 +0800 Subject: [PATCH 09/17] moved some enums to errors ts. --- src/Eagle.ts | 18 +++++----- src/Edge.ts | 85 +++++++++++++++++++------------------------- src/Errors.ts | 27 +++++++++++--- src/GraphRenderer.ts | 36 +++++++++---------- src/Setting.ts | 9 ++--- src/Utils.ts | 10 +++--- 6 files changed, 92 insertions(+), 93 deletions(-) diff --git a/src/Eagle.ts b/src/Eagle.ts index ac19477ff..f36860796 100644 --- a/src/Eagle.ts +++ b/src/Eagle.ts @@ -104,7 +104,7 @@ export class Eagle { draggingNode : ko.Observable; draggingPaletteNode : boolean; - errorsMode : ko.Observable; + errorsMode : ko.Observable; graphWarnings : ko.ObservableArray; graphErrors : ko.ObservableArray; loadingWarnings : ko.ObservableArray; @@ -194,7 +194,7 @@ export class Eagle { this.isDragging = ko.observable(false); this.draggingNode = ko.observable(null); this.draggingPaletteNode = false; - this.errorsMode = ko.observable(Setting.ErrorsMode.Loading); + this.errorsMode = ko.observable(Errors.Mode.Loading); this.graphWarnings = ko.observableArray([]); this.graphErrors = ko.observableArray([]); this.loadingWarnings = ko.observableArray([]); @@ -947,7 +947,7 @@ export class Eagle { this.loadingErrors(errorsWarnings.errors); this.loadingWarnings(errorsWarnings.warnings); - this.errorsMode(Setting.ErrorsMode.Loading); + this.errorsMode(Errors.Mode.Loading); Utils.showErrorsModal("Loading File"); } } else { @@ -1875,7 +1875,7 @@ export class Eagle { this.loadingErrors(errorsWarnings.errors); this.loadingWarnings(errorsWarnings.warnings); - this.errorsMode(Setting.ErrorsMode.Loading); + this.errorsMode(Errors.Mode.Loading); Utils.showErrorsModal("Loading File"); } @@ -2854,8 +2854,8 @@ export class Eagle { } // validate edge - const isValid: Edge.Validity = Edge.isValid(this,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, true, null); - if (isValid === Edge.Validity.Impossible || isValid === Edge.Validity.Invalid || isValid === Edge.Validity.Unknown){ + const isValid: Errors.Validity = Edge.isValid(this,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, true, null); + if (isValid === Errors.Validity.Impossible || isValid === Errors.Validity.Invalid || isValid === Errors.Validity.Unknown){ Utils.showUserMessage("Error", "Invalid edge"); return; } @@ -2899,8 +2899,8 @@ export class Eagle { } // validate edge - const isValid: Edge.Validity = Edge.isValid(this,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, true, null); - if (isValid === Edge.Validity.Impossible || isValid === Edge.Validity.Invalid || isValid === Edge.Validity.Unknown){ + const isValid: Errors.Validity = Edge.isValid(this,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, true, null); + if (isValid === Errors.Validity.Impossible || isValid === Errors.Validity.Invalid || isValid === Errors.Validity.Unknown){ Utils.showUserMessage("Error", "Invalid edge"); return; } @@ -4576,7 +4576,7 @@ export class Eagle { if (this.graphWarnings().length > 0 || this.graphErrors().length > 0){ // switch to graph errors mode - this.errorsMode(Setting.ErrorsMode.Graph); + this.errorsMode(Errors.Mode.Graph); // show graph modal this.smartToggleModal('errorsModal') diff --git a/src/Edge.ts b/src/Edge.ts index 303dcb6b8..6f7e7b69b 100644 --- a/src/Edge.ts +++ b/src/Edge.ts @@ -43,7 +43,7 @@ export class Edge { private closesLoop : boolean; // indicates that this is a special type of edge that can be drawn in eagle to specify the start/end of groups. private selectionRelative : boolean // indicates if the edge is either selected or attached to a selected node private isShortEdge : ko.Observable; - private errors : {issue:Errors.Issue, validity:Edge.Validity}[] + private errors : {issue:Errors.Issue, validity:Errors.Validity}[] constructor(srcNodeKey : number, srcPortId : string, destNodeKey : number, destPortId : string, loopAware: boolean, closesLoop: boolean, selectionRelative : boolean){ this._id = Utils.uuidv4(); @@ -279,41 +279,41 @@ export class Edge { return new Edge(edgeData.from, edgeData.fromPort, edgeData.to, edgeData.toPort, edgeData.loopAware, edgeData.closesLoop, false); } - static isValid(eagle: Eagle,autoSuggestMode:boolean, edgeId: string, sourceNodeKey : number, sourcePortId : string, destinationNodeKey : number, destinationPortId : string, loopAware: boolean, closesLoop: boolean, showNotification : boolean, showConsole : boolean, errorsWarnings: Errors.ErrorsWarnings) : Edge.Validity { + static isValid(eagle: Eagle,autoSuggestMode:boolean, edgeId: string, sourceNodeKey : number, sourcePortId : string, destinationNodeKey : number, destinationPortId : string, loopAware: boolean, closesLoop: boolean, showNotification : boolean, showConsole : boolean, errorsWarnings: Errors.ErrorsWarnings) : Errors.Validity { let impossibleEdge : boolean = false; // check for problems if (isNaN(sourceNodeKey)){ - return Edge.Validity.Unknown; + return Errors.Validity.Unknown; } if (isNaN(destinationNodeKey)){ - return Edge.Validity.Unknown; + return Errors.Validity.Unknown; } if (sourcePortId === ""){ const issue = Errors.Fix("source port has no id", function(){Utils.fixNodeFieldIds(eagle, sourceNodeKey)}, "Generate ids for ports on source node"); - Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); - return Edge.Validity.Impossible; + Edge.isValidLog(edgeId, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + return Errors.Validity.Impossible; } if (destinationPortId === ""){ const issue = Errors.Fix("destination port has no id", function(){Utils.fixNodeFieldIds(eagle, sourceNodeKey)}, "Generate ids for ports on destination node"); - Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); - return Edge.Validity.Impossible; + Edge.isValidLog(edgeId, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + return Errors.Validity.Impossible; } if (sourcePortId === null){ const issue = Errors.Fix("source port id is null", function(){Utils.fixNodeFieldIds(eagle, sourceNodeKey)}, "Generate ids for ports on source node"); - Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); - return Edge.Validity.Impossible; + Edge.isValidLog(edgeId, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + return Errors.Validity.Impossible; } if (destinationPortId === null){ const issue = Errors.Fix("destination port id is null", function(){Utils.fixNodeFieldIds(eagle, sourceNodeKey)}, "Generate ids for ports on destination node"); - Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); - return Edge.Validity.Impossible; + Edge.isValidLog(edgeId, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + return Errors.Validity.Impossible; } // get references to actual source and destination nodes (from the keys) @@ -321,23 +321,23 @@ export class Edge { const destinationNode : Node = eagle.logicalGraph().findNodeByKey(destinationNodeKey); if (sourceNode === null || typeof sourceNode === "undefined" || destinationNode === null || typeof destinationNode === "undefined"){ - return Edge.Validity.Unknown; + return Errors.Validity.Unknown; } // check that we are not connecting a Data component to a Data component, that is not supported if (sourceNode.getCategoryType() === Category.Type.Data && destinationNode.getCategoryType() === Category.Type.Data){ - Edge.isValidLog(edgeId, Edge.Validity.Invalid, Errors.Show("Data nodes may not be connected directly to other Data nodes", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Invalid, Errors.Show("Data nodes may not be connected directly to other Data nodes", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); } // if source node or destination node is a construct, then something is wrong, constructs should not have ports if (sourceNode.getCategoryType() === Category.Type.Construct){ const issue: Errors.Issue = Errors.ShowFix("Edge (" + edgeId + ") cannot have a source node (" + sourceNode.getName() + ") that is a construct", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.fixMoveEdgeToEmbeddedApplication(eagle, edgeId)}, "Move edge to embedded application"); - Edge.isValidLog(edgeId, Edge.Validity.Invalid, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Invalid, issue, showNotification, showConsole, errorsWarnings); } if (destinationNode.getCategoryType() === Category.Type.Construct){ const issue: Errors.Issue = Errors.ShowFix("Edge (" + edgeId + ") cannot have a destination node (" + destinationNode.getName() + ") that is a construct", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.fixMoveEdgeToEmbeddedApplication(eagle, edgeId)}, "Move edge to embedded application"); - Edge.isValidLog(edgeId, Edge.Validity.Invalid, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Invalid, issue, showNotification, showConsole, errorsWarnings); } // if source node is a memory, and destination is a BashShellApp, OR @@ -346,7 +346,7 @@ export class Edge { if ((sourceNode.getCategory() === Category.Memory && destinationNode.getCategory() === Category.BashShellApp) || (sourceNode.getCategory() === Category.Memory && destinationNode.isGroup() && destinationNode.getInputApplication() !== undefined && destinationNode.hasInputApplication() && destinationNode.getInputApplication().getCategory() === Category.BashShellApp)){ const issue: Errors.Issue = Errors.ShowFix("output from Memory Node cannot be input into a BashShellApp or input into a Group Node with a BashShellApp inputApplicationType", function(){Utils.showNode(eagle, sourceNode.getId())}, function(){Utils.fixNodeCategory(eagle, sourceNode, Category.File, Category.Type.Data)}, "Change data component type to File"); - Edge.isValidLog(edgeId, Edge.Validity.Invalid, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Invalid, issue, showNotification, showConsole, errorsWarnings); } const sourcePort : Field = sourceNode.findFieldById(sourcePortId); @@ -355,41 +355,41 @@ export class Edge { // check if source port was found if (sourcePort === null) { const issue: Errors.Issue = Errors.ShowFix("Source port (" + sourcePortId + ") doesn't exist on source node (" + sourceNode.getName() + ")", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.addSourcePortToSourceNode(eagle, edgeId)}, "Add source port to source node"); - Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); impossibleEdge = true; } // check if destination port was found if (destinationPort === null){ const issue: Errors.Issue = Errors.ShowFix("Destination port (" + destinationPortId + ") doesn't exist on destination node (" + destinationNode.getName() + ")", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.addDestinationPortToDestinationNode(eagle, edgeId)}, "Add destination port to destination node"); - Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); impossibleEdge = true; } // check that we are not connecting a port to itself if (sourceNodeKey === destinationNodeKey){ - Edge.isValidLog(edgeId, Edge.Validity.Impossible, Errors.Show("Source port and destination port are the same", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Impossible, Errors.Show("Source port and destination port are the same", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); impossibleEdge = true; } // check that source is output if (!sourcePort.isOutputPort()){ const issue: Errors.Issue = Errors.ShowFix("Source port is not output port (" + sourcePort.getUsage() + ")", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixFieldUsage(eagle, sourcePort, Daliuge.FieldUsage.OutputPort)}, "Add output usage to source port"); - Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); impossibleEdge = true; } // check that destination in input if (!destinationPort.isInputPort()){ const issue: Errors.Issue = Errors.ShowFix("Destination port is not input port (" + destinationPort.getUsage() + ")", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixFieldUsage(eagle, destinationPort, Daliuge.FieldUsage.InputPort)}, "Add input usage to destination port"); - Edge.isValidLog(edgeId, Edge.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); impossibleEdge = true; } if (sourcePort !== null && destinationPort !== null){ // check that source and destination port are both event, or both not event if ((sourcePort.getIsEvent() && !destinationPort.getIsEvent()) || (!sourcePort.getIsEvent() && destinationPort.getIsEvent())){ - Edge.isValidLog(edgeId, Edge.Validity.Invalid, Errors.Show("Source port and destination port are mix of event and non-event ports", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Invalid, Errors.Show("Source port and destination port are mix of event and non-event ports", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); } } @@ -419,7 +419,7 @@ export class Edge { // abort if source port and destination port have different data types if (!Utils.portsMatch(sourcePort, destinationPort)){ const x = Errors.ShowFix("Source and destination ports don't match data types: sourcePort (" + sourcePort.getDisplayText() + ":" + sourcePort.getType() + ") destinationPort (" + destinationPort.getDisplayText() + ":" + destinationPort.getType() + ")", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixPortType(eagle, sourcePort, destinationPort);}, "Overwrite destination port type with source port type"); - Edge.isValidLog(edgeId, Edge.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); } } @@ -432,12 +432,12 @@ export class Edge { || associatedConstructType !== Category.Loop && loopAware ){ const x = Errors.ShowFix("An edge between two siblings should not be loop aware", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixDisableEdgeLoopAware(eagle, edgeId);}, "Disable loop aware on the edge."); - Edge.isValidLog(edgeId, Edge.Validity.Warning, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Warning, x, showNotification, showConsole, errorsWarnings); } // if link is not a parent, child or sibling, then warn user if (associatedConstructType !== Category.ExclusiveForceNode && associatedConstructType !== Category.Loop && !isSibling && !isParentOfConstruct && !isChildOfConstruct && !destPortIsEmbeddedAppOfSibling && !srcPortIsEmbeddedAppOfSibling){ - Edge.isValidLog(edgeId, Edge.Validity.Warning, Errors.Show("Edge is not between siblings, or between a child and its parent's embedded Application. It could be incorrect or computationally expensive", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Warning, Errors.Show("Edge is not between siblings, or between a child and its parent's embedded Application. It could be incorrect or computationally expensive", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); } // check if the edge already exists in the graph, there is no point in a duplicate @@ -447,7 +447,7 @@ export class Edge { if ( isSrcMatch && isDestMatch && edge.getId() !== edgeId){ const x = Errors.ShowFix("Edge is a duplicate. Another edge with the same source port and destination port already exists", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixDeleteEdge(eagle, edgeId);}, "Delete edge"); - Edge.isValidLog(edgeId, Edge.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); } } @@ -459,49 +459,49 @@ export class Edge { if (closesLoop){ if (!sourceNode.isData()){ const x = Errors.Show("Closes Loop Edge (" + edgeId + ") does not start from a Data component.", function(){Utils.showEdge(eagle, edgeId);}); - Edge.isValidLog(edgeId, Edge.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); } if (!destinationNode.isApplication()){ const x = Errors.Show("Closes Loop Edge (" + edgeId + ") does not end at an Application component.", function(){Utils.showEdge(eagle, edgeId);}); - Edge.isValidLog(edgeId, Edge.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); } if (!sourceNode.hasFieldWithDisplayText(Daliuge.FieldName.GROUP_END) || !Utils.asBool(sourceNode.getFieldByDisplayText(Daliuge.FieldName.GROUP_END).getValue())){ const x = Errors.ShowFix("'Closes Loop' Edge (" + edgeId + ") start node (" + sourceNode.getName() + ") does not have 'group_end' set to true.", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixFieldValue(eagle, sourceNode, Daliuge.groupEndField, "true")}, "Set 'group_end' to true"); - Edge.isValidLog(edgeId, Edge.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); } if (!destinationNode.hasFieldWithDisplayText(Daliuge.FieldName.GROUP_START) || !Utils.asBool(destinationNode.getFieldByDisplayText(Daliuge.FieldName.GROUP_START).getValue())){ const x = Errors.ShowFix("'Closes Loop' Edge (" + edgeId + ") end node (" + destinationNode.getName() + ") does not have 'group_start' set to true.", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixFieldValue(eagle, destinationNode, Daliuge.groupStartField, "true")}, "Set 'group_start' to true"); - Edge.isValidLog(edgeId, Edge.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); } } //the worst edge errror function can only check for entries in errors or warnings, it isnt able to distinguish impossible from invalid if(impossibleEdge){ - return Edge.Validity.Impossible + return Errors.Validity.Impossible }else{ return Utils.worstEdgeError(errorsWarnings); } } - private static isValidLog(edgeId : string, linkValid : Edge.Validity, issue: Errors.Issue, showNotification : boolean, showConsole : boolean, errorsWarnings: Errors.ErrorsWarnings) : void { + private static isValidLog(edgeId : string, linkValid : Errors.Validity, issue: Errors.Issue, showNotification : boolean, showConsole : boolean, errorsWarnings: Errors.ErrorsWarnings) : void { // determine correct title let title = "Edge Valid"; let type : "success" | "info" | "warning" | "danger" = "success"; let message = ""; switch (linkValid){ - case Edge.Validity.Warning: + case Errors.Validity.Warning: title = "Edge Warning"; type = "warning"; break; - case Edge.Validity.Impossible: + case Errors.Validity.Impossible: title = "Edge Impossible"; type = "danger"; break; - case Edge.Validity.Invalid: + case Errors.Validity.Invalid: title = "Edge Invalid"; type = "danger"; break; @@ -528,16 +528,3 @@ export class Edge { Eagle.getInstance().logicalGraph().findEdgeById(edgeId)?.errors.push({issue:issue, validity:linkValid}) } } - -//change data structure of each nodes, fields and edges and new logicalgraph is valid function to be {issue, validity}[] -// move to errors, use for nodes,fields and edges -export namespace Edge { - export enum Validity { - Unknown = "Unknown", // validity of the edge is unknown - Impossible = "Impossible", // never useful or valid - Invalid = "Invalid", // invalid, but possibly useful for expert users? change to error - Warning = "Warning", // valid, but some issue that the user should be aware of - Fixable = "Fixable", // there is an issue with the connection but for drawing edges eagle will fix this for you - Valid = "Valid" // fine - } -} diff --git a/src/Errors.ts b/src/Errors.ts index 45851b8c4..292dbe95c 100644 --- a/src/Errors.ts +++ b/src/Errors.ts @@ -1,7 +1,6 @@ import * as ko from "knockout"; import {Eagle} from './Eagle'; -import {Setting} from './Setting'; import {Utils} from './Utils'; export class Errors { @@ -69,9 +68,9 @@ export class Errors { const eagle: Eagle = Eagle.getInstance(); switch (eagle.errorsMode()){ - case Setting.ErrorsMode.Loading: + case Errors.Mode.Loading: return eagle.loadingWarnings(); - case Setting.ErrorsMode.Graph: + case Errors.Mode.Graph: return eagle.graphWarnings(); default: console.warn("Unknown errorsMode (" + eagle.errorsMode() + "). Unable to getWarnings()"); @@ -83,9 +82,9 @@ export class Errors { const eagle: Eagle = Eagle.getInstance(); switch (eagle.errorsMode()){ - case Setting.ErrorsMode.Loading: + case Errors.Mode.Loading: return eagle.loadingErrors(); - case Setting.ErrorsMode.Graph: + case Errors.Mode.Graph: return eagle.graphErrors(); default: console.warn("Unknown errorsMode (" + eagle.errorsMode() + "). Unable to getErrors()"); @@ -120,4 +119,22 @@ export namespace Errors { export type Issue = {message: string, show: () => void, fix: () => void, fixDescription: string}; export type ErrorsWarnings = {warnings: Issue[], errors: Issue[]}; + + export enum Validity { + Unknown = "Unknown", // validity of the edge is unknown + Impossible = "Impossible", // never useful or valid + Invalid = "Invalid", // invalid, but possibly useful for expert users? change to error + Warning = "Warning", // valid, but some issue that the user should be aware of + Fixable = "Fixable", // there is an issue with the connection but for drawing edges eagle will fix this for you + Valid = "Valid" // fine + } + + export enum Mode { + Loading = "Loading", + Graph = "Graph" + } } + + +//change data structure of each nodes, fields and edges and new logicalgraph is valid function to be {issue, validity}[] +// move to errors, use for nodes,fields and edges diff --git a/src/GraphRenderer.ts b/src/GraphRenderer.ts index b1cfd0a56..076e88376 100644 --- a/src/GraphRenderer.ts +++ b/src/GraphRenderer.ts @@ -27,13 +27,13 @@ import * as ko from "knockout"; import { Category } from './Category'; import { Daliuge } from "./Daliuge"; import { Eagle } from './Eagle'; +import { Errors } from './Errors'; import { Edge } from "./Edge"; import { Field } from './Field'; import { GraphConfig } from './graphConfig'; import { LogicalGraph } from './LogicalGraph'; import { Node } from './Node'; import { Utils } from './Utils'; -import { CategoryData} from './CategoryData'; import { Setting } from './Setting'; import { RightClick } from "./RightClick"; @@ -302,7 +302,7 @@ export class GraphRenderer { //port drag handler globals static draggingPort : boolean = false; - static isDraggingPortValid: ko.Observable = ko.observable(Edge.Validity.Unknown); + static isDraggingPortValid: ko.Observable = ko.observable(Errors.Validity.Unknown); static destinationNode : Node = null; static destinationPort : Field = null; @@ -1762,11 +1762,11 @@ export class GraphRenderer { } // check if link is valid - const linkValid : Edge.Validity = Edge.isValid(eagle,false, null, realSourceNode.getKey(), realSourcePort.getId(), realDestinationNode.getKey(), realDestinationPort.getId(), false, false, true, true, {errors:[], warnings:[]}); + const linkValid : Errors.Validity = Edge.isValid(eagle,false, null, realSourceNode.getKey(), realSourcePort.getId(), realDestinationNode.getKey(), realDestinationPort.getId(), false, false, true, true, {errors:[], warnings:[]}); // abort if edge is invalid - if ((Setting.findValue(Setting.ALLOW_INVALID_EDGES) && linkValid === Edge.Validity.Invalid) || linkValid === Edge.Validity.Valid || linkValid === Edge.Validity.Warning){ - if (linkValid === Edge.Validity.Warning){ + if ((Setting.findValue(Setting.ALLOW_INVALID_EDGES) && linkValid === Errors.Validity.Invalid) || linkValid === Errors.Validity.Valid || linkValid === Errors.Validity.Warning){ + if (linkValid === Errors.Validity.Warning){ GraphRenderer.addEdge(realSourceNode, realSourcePort, realDestinationNode, realDestinationPort, true, false); } else { GraphRenderer.addEdge(realSourceNode, realSourcePort, realDestinationNode, realDestinationPort, false, false); @@ -2021,8 +2021,8 @@ export class GraphRenderer { const eagle = Eagle.getInstance(); const result: {node: Node, field: Field}[] = []; - const minValidity: Edge.Validity = Setting.findValue(Setting.AUTO_COMPLETE_EDGES_LEVEL); - const minValidityIndex: number = Object.values(Edge.Validity).indexOf(minValidity); + const minValidity: Errors.Validity = Setting.findValue(Setting.AUTO_COMPLETE_EDGES_LEVEL); + const minValidityIndex: number = Object.values(Errors.Validity).indexOf(minValidity); const potentialNodes :Node[] = [] @@ -2038,13 +2038,13 @@ export class GraphRenderer { for(const node of potentialNodes){ for (const port of node.getPorts()){ - let isValid: Edge.Validity + let isValid: Errors.Validity if(!GraphRenderer.portDragSourcePortIsInput){ isValid = Edge.isValid(eagle,true, "", sourceNode.getKey(), sourcePort.getId(), node.getKey(), port.getId(), false, false, false, false, {errors:[], warnings:[]}); }else{ isValid = Edge.isValid(eagle,true, "", node.getKey(), port.getId(), sourceNode.getKey(), sourcePort.getId(), false, false, false, false, {errors:[], warnings:[]}); } - const isValidIndex: number = Object.values(Edge.Validity).indexOf(isValid); + const isValidIndex: number = Object.values(Errors.Validity).indexOf(isValid); if (isValidIndex >= minValidityIndex){ result.push({node: node, field: port}); @@ -2117,19 +2117,19 @@ export class GraphRenderer { GraphRenderer.destinationPort = null; GraphRenderer.destinationNode = null; - GraphRenderer.isDraggingPortValid(Edge.Validity.Unknown); + GraphRenderer.isDraggingPortValid(Errors.Validity.Unknown); } static draggingEdgeGetStrokeColor: ko.PureComputed = ko.pureComputed(() => { switch (GraphRenderer.isDraggingPortValid()){ - case Edge.Validity.Unknown: + case Errors.Validity.Unknown: return "black"; - case Edge.Validity.Impossible: - case Edge.Validity.Invalid: + case Errors.Validity.Impossible: + case Errors.Validity.Invalid: return GraphConfig.getColor("edgeInvalid"); - case Edge.Validity.Warning: + case Errors.Validity.Warning: return GraphConfig.getColor("edgeWarning"); - case Edge.Validity.Valid: + case Errors.Validity.Valid: return GraphConfig.getColor("edgeValid"); default: return GraphConfig.getColor("edgeDefault"); @@ -2248,14 +2248,14 @@ export class GraphRenderer { } // check if link has a warning or is invalid - const linkValid : Edge.Validity = Edge.isValid(eagle,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, false, {errors:[], warnings:[]}); + const linkValid : Errors.Validity = Edge.isValid(eagle,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, false, {errors:[], warnings:[]}); - if (linkValid === Edge.Validity.Invalid || linkValid === Edge.Validity.Impossible){ + if (linkValid === Errors.Validity.Invalid || linkValid === Errors.Validity.Impossible){ normalColor = GraphConfig.getColor('edgeInvalid'); selectedColor = GraphConfig.getColor('edgeInvalidSelected'); } - if (linkValid === Edge.Validity.Warning){ + if (linkValid === Errors.Validity.Warning){ normalColor = GraphConfig.getColor('edgeWarning'); selectedColor = GraphConfig.getColor('edgeWarningSelected'); } diff --git a/src/Setting.ts b/src/Setting.ts index 2dd5d7c8b..08899d3a8 100644 --- a/src/Setting.ts +++ b/src/Setting.ts @@ -1,7 +1,7 @@ import * as ko from "knockout"; import { Eagle } from './Eagle'; -import { Edge } from "./Edge"; +import { Errors } from './Errors'; import { Repository } from "./Repository"; import { UiModeSystem } from './UiModes'; import { Utils } from './Utils'; @@ -342,11 +342,6 @@ export namespace Setting { ReadOnly = "Readonly" } - export enum ErrorsMode { - Loading = "Loading", - Graph = "Graph" - } - export enum TranslatorMode { Minimal = "minimal", Normal = "normal", @@ -402,7 +397,7 @@ const settings : SettingsGroup[] = [ new Setting(true, "Filter Node Suggestions", Setting.FILTER_NODE_SUGGESTIONS, "Filter Node Options When Drawing Edges Into Empty Space", false, Setting.Type.Boolean,true,true,true,true,false), new Setting(false, "STUDENT_SETTINGS_MODE", Setting.STUDENT_SETTINGS_MODE, "Mode disabling setting editing for students.", false, Setting.Type.Boolean, true, false,false, false, false), new Setting(true, "Value Editing", Setting.VALUE_EDITING_PERMS, "Set which values are allowed to be edited.", false, Setting.Type.Select, Setting.valueEditingPerms.KeyOnly,Setting.valueEditingPerms.Normal,Setting.valueEditingPerms.Normal,Setting.valueEditingPerms.ReadOnly,Setting.valueEditingPerms.ReadOnly, Object.values(Setting.valueEditingPerms)), - new Setting(true, "Auto-complete edges level", Setting.AUTO_COMPLETE_EDGES_LEVEL, "Specifies the minimum validity level of auto-complete edges displayed when dragging a new edge", false, Setting.Type.Select, Edge.Validity.Valid, Edge.Validity.Valid, Edge.Validity.Warning, Edge.Validity.Warning, Edge.Validity.Invalid, [Edge.Validity.Invalid, Edge.Validity.Warning, Edge.Validity.Valid]), + new Setting(true, "Auto-complete edges level", Setting.AUTO_COMPLETE_EDGES_LEVEL, "Specifies the minimum validity level of auto-complete edges displayed when dragging a new edge", false, Setting.Type.Select, Errors.Validity.Valid, Errors.Validity.Valid, Errors.Validity.Warning, Errors.Validity.Warning, Errors.Validity.Invalid, [Errors.Validity.Invalid, Errors.Validity.Warning, Errors.Validity.Valid]), ] ), new SettingsGroup( diff --git a/src/Utils.ts b/src/Utils.ts index 9378628fc..3d48bc190 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -2178,21 +2178,21 @@ export class Utils { } // only update result if it is worse that current result - static worstEdgeError(errorsWarnings: Errors.ErrorsWarnings) : Edge.Validity { + static worstEdgeError(errorsWarnings: Errors.ErrorsWarnings) : Errors.Validity { if (errorsWarnings === null){ console.warn("errorsWarnings is null"); - return Edge.Validity.Valid; + return Errors.Validity.Valid; } if (errorsWarnings.warnings.length === 0 && errorsWarnings.errors.length === 0){ - return Edge.Validity.Valid; + return Errors.Validity.Valid; } if (errorsWarnings.errors.length !== 0){ - return Edge.Validity.Invalid; + return Errors.Validity.Invalid; } - return Edge.Validity.Warning; + return Errors.Validity.Warning; } static printCategories() : void { From a84a702e026465e6e50124ede85e56419cb33f8c Mon Sep 17 00:00:00 2001 From: MWicenec Date: Fri, 5 Jul 2024 16:32:03 +0800 Subject: [PATCH 10/17] wip commit --- src/Edge.ts | 11 +++++++---- src/LogicalGraph.ts | 4 ++++ src/Utils.ts | 3 ++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/Edge.ts b/src/Edge.ts index 6f7e7b69b..4c6c6676d 100644 --- a/src/Edge.ts +++ b/src/Edge.ts @@ -31,7 +31,6 @@ import { Field } from './Field'; import { Utils } from './Utils'; import { Errors } from './Errors'; import * as ko from "knockout"; -import { CategoryData } from './CategoryData'; export class Edge { private _id : string @@ -43,7 +42,7 @@ export class Edge { private closesLoop : boolean; // indicates that this is a special type of edge that can be drawn in eagle to specify the start/end of groups. private selectionRelative : boolean // indicates if the edge is either selected or attached to a selected node private isShortEdge : ko.Observable; - private errors : {issue:Errors.Issue, validity:Errors.Validity}[] + private errorsArray : {issue:Errors.Issue, validity:Errors.Validity}[] constructor(srcNodeKey : number, srcPortId : string, destNodeKey : number, destPortId : string, loopAware: boolean, closesLoop: boolean, selectionRelative : boolean){ this._id = Utils.uuidv4(); @@ -57,7 +56,7 @@ export class Edge { this.closesLoop = closesLoop; this.selectionRelative = selectionRelative; this.isShortEdge = ko.observable(false) - this.errors = []; + this.errorsArray = []; } getId = () : string => { @@ -178,6 +177,10 @@ export class Edge { return result; } + getErrorsArray = () : {issue:Errors.Issue, validity:Errors.Validity}[] => { + return this.errorsArray; + } + static toOJSJson(edge : Edge) : object { return { from: edge.srcNodeKey, @@ -525,6 +528,6 @@ export class Edge { if (type === "warning" && errorsWarnings !== null){ errorsWarnings.warnings.push(issue); } - Eagle.getInstance().logicalGraph().findEdgeById(edgeId)?.errors.push({issue:issue, validity:linkValid}) + Eagle.getInstance().logicalGraph().findEdgeById(edgeId)?.errorsArray.push({issue:issue, validity:linkValid}) } } diff --git a/src/LogicalGraph.ts b/src/LogicalGraph.ts index 3b2d52979..543092286 100644 --- a/src/LogicalGraph.ts +++ b/src/LogicalGraph.ts @@ -784,4 +784,8 @@ export class LogicalGraph { return radius; } + + static isValid () : void { + //here should be the higher level graph wide checks for graph validity + } } diff --git a/src/Utils.ts b/src/Utils.ts index 3d48bc190..3e6840d71 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -1404,6 +1404,7 @@ export class Utils { static checkGraph(eagle: Eagle): Errors.ErrorsWarnings { const errorsWarnings: Errors.ErrorsWarnings = {warnings: [], errors: []}; + const graph: LogicalGraph = eagle.logicalGraph(); @@ -1446,7 +1447,7 @@ export class Utils { // check all edges are valid for (const edge of graph.getEdges()){ - Edge.isValid(eagle,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, false, errorsWarnings); + Edge.isValid(eagle,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, false, {warnings: [], errors: []}); } // check that all node, edge, field ids are unique From 3d29bdcb29b1ad9b683e9436e2871ec88bcac83d Mon Sep 17 00:00:00 2001 From: M-Wicenec Date: Mon, 8 Jul 2024 15:58:18 +0800 Subject: [PATCH 11/17] tons of changes to how the errors system works --- src/Eagle.ts | 12 +-- src/Edge.ts | 24 ++--- src/Errors.ts | 2 +- src/Field.ts | 40 +++++--- src/GraphRenderer.ts | 6 +- src/GraphUpdater.ts | 3 +- src/LogicalGraph.ts | 58 ++++++++++++ src/Node.ts | 61 ++++++++---- src/Setting.ts | 2 +- src/Utils.ts | 214 ++++++++++++++++++++++++++++--------------- 10 files changed, 291 insertions(+), 131 deletions(-) diff --git a/src/Eagle.ts b/src/Eagle.ts index f36860796..70035eb9c 100644 --- a/src/Eagle.ts +++ b/src/Eagle.ts @@ -2855,7 +2855,7 @@ export class Eagle { // validate edge const isValid: Errors.Validity = Edge.isValid(this,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, true, null); - if (isValid === Errors.Validity.Impossible || isValid === Errors.Validity.Invalid || isValid === Errors.Validity.Unknown){ + if (isValid === Errors.Validity.Impossible || isValid === Errors.Validity.Error || isValid === Errors.Validity.Unknown){ Utils.showUserMessage("Error", "Invalid edge"); return; } @@ -2900,7 +2900,7 @@ export class Eagle { // validate edge const isValid: Errors.Validity = Edge.isValid(this,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, true, null); - if (isValid === Errors.Validity.Impossible || isValid === Errors.Validity.Invalid || isValid === Errors.Validity.Unknown){ + if (isValid === Errors.Validity.Impossible || isValid === Errors.Validity.Error || isValid === Errors.Validity.Unknown){ Utils.showUserMessage("Error", "Invalid edge"); return; } @@ -4566,10 +4566,10 @@ export class Eagle { } checkGraph = (): void => { - const checkResult = Utils.checkGraph(this); - - this.graphWarnings(checkResult.warnings); - this.graphErrors(checkResult.errors); + Utils.checkGraph(this);//validate the graph + const graphErrors = Utils.gatherGraphErrors() //gather all the errors from all of the components + this.graphWarnings(graphErrors.warnings); + this.graphErrors(graphErrors.errors); }; showGraphErrors = (): void => { diff --git a/src/Edge.ts b/src/Edge.ts index 4c6c6676d..8b4322a33 100644 --- a/src/Edge.ts +++ b/src/Edge.ts @@ -329,18 +329,18 @@ export class Edge { // check that we are not connecting a Data component to a Data component, that is not supported if (sourceNode.getCategoryType() === Category.Type.Data && destinationNode.getCategoryType() === Category.Type.Data){ - Edge.isValidLog(edgeId, Errors.Validity.Invalid, Errors.Show("Data nodes may not be connected directly to other Data nodes", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Error, Errors.Show("Data nodes may not be connected directly to other Data nodes", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); } // if source node or destination node is a construct, then something is wrong, constructs should not have ports if (sourceNode.getCategoryType() === Category.Type.Construct){ const issue: Errors.Issue = Errors.ShowFix("Edge (" + edgeId + ") cannot have a source node (" + sourceNode.getName() + ") that is a construct", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.fixMoveEdgeToEmbeddedApplication(eagle, edgeId)}, "Move edge to embedded application"); - Edge.isValidLog(edgeId, Errors.Validity.Invalid, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Error, issue, showNotification, showConsole, errorsWarnings); } if (destinationNode.getCategoryType() === Category.Type.Construct){ const issue: Errors.Issue = Errors.ShowFix("Edge (" + edgeId + ") cannot have a destination node (" + destinationNode.getName() + ") that is a construct", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.fixMoveEdgeToEmbeddedApplication(eagle, edgeId)}, "Move edge to embedded application"); - Edge.isValidLog(edgeId, Errors.Validity.Invalid, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Error, issue, showNotification, showConsole, errorsWarnings); } // if source node is a memory, and destination is a BashShellApp, OR @@ -349,7 +349,7 @@ export class Edge { if ((sourceNode.getCategory() === Category.Memory && destinationNode.getCategory() === Category.BashShellApp) || (sourceNode.getCategory() === Category.Memory && destinationNode.isGroup() && destinationNode.getInputApplication() !== undefined && destinationNode.hasInputApplication() && destinationNode.getInputApplication().getCategory() === Category.BashShellApp)){ const issue: Errors.Issue = Errors.ShowFix("output from Memory Node cannot be input into a BashShellApp or input into a Group Node with a BashShellApp inputApplicationType", function(){Utils.showNode(eagle, sourceNode.getId())}, function(){Utils.fixNodeCategory(eagle, sourceNode, Category.File, Category.Type.Data)}, "Change data component type to File"); - Edge.isValidLog(edgeId, Errors.Validity.Invalid, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Error, issue, showNotification, showConsole, errorsWarnings); } const sourcePort : Field = sourceNode.findFieldById(sourcePortId); @@ -392,7 +392,7 @@ export class Edge { if (sourcePort !== null && destinationPort !== null){ // check that source and destination port are both event, or both not event if ((sourcePort.getIsEvent() && !destinationPort.getIsEvent()) || (!sourcePort.getIsEvent() && destinationPort.getIsEvent())){ - Edge.isValidLog(edgeId, Errors.Validity.Invalid, Errors.Show("Source port and destination port are mix of event and non-event ports", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Error, Errors.Show("Source port and destination port are mix of event and non-event ports", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); } } @@ -422,7 +422,7 @@ export class Edge { // abort if source port and destination port have different data types if (!Utils.portsMatch(sourcePort, destinationPort)){ const x = Errors.ShowFix("Source and destination ports don't match data types: sourcePort (" + sourcePort.getDisplayText() + ":" + sourcePort.getType() + ") destinationPort (" + destinationPort.getDisplayText() + ":" + destinationPort.getType() + ")", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixPortType(eagle, sourcePort, destinationPort);}, "Overwrite destination port type with source port type"); - Edge.isValidLog(edgeId, Errors.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); } } @@ -450,7 +450,7 @@ export class Edge { if ( isSrcMatch && isDestMatch && edge.getId() !== edgeId){ const x = Errors.ShowFix("Edge is a duplicate. Another edge with the same source port and destination port already exists", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixDeleteEdge(eagle, edgeId);}, "Delete edge"); - Edge.isValidLog(edgeId, Errors.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); } } @@ -462,22 +462,22 @@ export class Edge { if (closesLoop){ if (!sourceNode.isData()){ const x = Errors.Show("Closes Loop Edge (" + edgeId + ") does not start from a Data component.", function(){Utils.showEdge(eagle, edgeId);}); - Edge.isValidLog(edgeId, Errors.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); } if (!destinationNode.isApplication()){ const x = Errors.Show("Closes Loop Edge (" + edgeId + ") does not end at an Application component.", function(){Utils.showEdge(eagle, edgeId);}); - Edge.isValidLog(edgeId, Errors.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); } if (!sourceNode.hasFieldWithDisplayText(Daliuge.FieldName.GROUP_END) || !Utils.asBool(sourceNode.getFieldByDisplayText(Daliuge.FieldName.GROUP_END).getValue())){ const x = Errors.ShowFix("'Closes Loop' Edge (" + edgeId + ") start node (" + sourceNode.getName() + ") does not have 'group_end' set to true.", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixFieldValue(eagle, sourceNode, Daliuge.groupEndField, "true")}, "Set 'group_end' to true"); - Edge.isValidLog(edgeId, Errors.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); } if (!destinationNode.hasFieldWithDisplayText(Daliuge.FieldName.GROUP_START) || !Utils.asBool(destinationNode.getFieldByDisplayText(Daliuge.FieldName.GROUP_START).getValue())){ const x = Errors.ShowFix("'Closes Loop' Edge (" + edgeId + ") end node (" + destinationNode.getName() + ") does not have 'group_start' set to true.", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixFieldValue(eagle, destinationNode, Daliuge.groupStartField, "true")}, "Set 'group_start' to true"); - Edge.isValidLog(edgeId, Errors.Validity.Invalid, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edgeId, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); } } @@ -504,7 +504,7 @@ export class Edge { title = "Edge Impossible"; type = "danger"; break; - case Errors.Validity.Invalid: + case Errors.Validity.Error: title = "Edge Invalid"; type = "danger"; break; diff --git a/src/Errors.ts b/src/Errors.ts index 292dbe95c..3833ce668 100644 --- a/src/Errors.ts +++ b/src/Errors.ts @@ -123,7 +123,7 @@ export namespace Errors export enum Validity { Unknown = "Unknown", // validity of the edge is unknown Impossible = "Impossible", // never useful or valid - Invalid = "Invalid", // invalid, but possibly useful for expert users? change to error + Error = "Error", // invalid, but possibly useful for expert users? change to error Warning = "Warning", // valid, but some issue that the user should be aware of Fixable = "Fixable", // there is an issue with the connection but for drawing edges eagle will fix this for you Valid = "Valid" // fine diff --git a/src/Field.ts b/src/Field.ts index 30a798f40..1ed74f0de 100644 --- a/src/Field.ts +++ b/src/Field.ts @@ -41,6 +41,7 @@ export class Field { private inputAngle : number; private outputAngle : number; + private errorsArray : {issue:Errors.Issue, validity:Errors.Validity}[] private errorsWarnings : ko.Observable; constructor(id: string, displayText: string, value: string, defaultValue: string, description: string, readonly: boolean, type: string, precious: boolean, options: string[], positional: boolean, parameterType: Daliuge.FieldType, usage: Daliuge.FieldUsage, keyAttribute: boolean){ @@ -73,6 +74,7 @@ export class Field { this.inputAngle = 0; this.outputAngle = 0; + this.errorsArray = []; this.errorsWarnings = ko.observable({warnings: [], errors: []}); } @@ -348,6 +350,10 @@ export class Field { return this.errorsWarnings(); } + getErrors = (): {issue:Errors.Issue, validity:Errors.Validity}[] => { + return this.errorsArray; + } + addErrorsWarnings(issue:Errors.Issue, issueType:string) : void { if(issueType === 'error'){ this.errorsWarnings().errors.push(issue) @@ -803,7 +809,7 @@ export class Field { static isValid(node:Node, field:Field, selectedLocation:Eagle.FileType, fieldIndex:number){ const eagle = Eagle.getInstance() - const errorsWarnings : Errors.ErrorsWarnings = {warnings: [], errors: []}; + // const errorsWarnings : Errors.ErrorsWarnings = {warnings: [], errors: []}; //checks for input ports if(field.isInputPort()){ @@ -827,7 +833,9 @@ export class Field { issue = Errors.ShowFix("Node " + node.getKey() + " (" + parentNode.getName() + ") has output application (" + node.getName() + ") with input port (" + field.getDisplayText() + ") whose type is not specified", function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixFieldType(eagle, field)}, ""); } } - errorsWarnings.warnings.push(issue); + + field.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + // errorsWarnings.warnings.push(issue); } @@ -855,7 +863,8 @@ export class Field { issue = Errors.ShowFix("Node " + node.getKey() + " (" + parentNode.getName() + ") has output application (" + node.getName() + ") with output port (" + field.getDisplayText() + ") whose type is not specified", function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixFieldType(eagle, field)}, ""); } } - errorsWarnings.warnings.push(issue); + field.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + // errorsWarnings.warnings.push(issue); } @@ -864,25 +873,29 @@ export class Field { //check that the field has an id if (field.getId() === "" || field.getId() === null){ const issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has field (" + field.getDisplayText() + ") with no id", function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixFieldId(eagle, field)}, "Generate id for field"); - errorsWarnings.errors.push(issue); + field.errorsArray.push({issue:issue,validity:Errors.Validity.Error}) + // errorsWarnings.errors.push(issue); } // check that the field has a default value if (field.getDefaultValue() === "" && !field.isType(Daliuge.DataType.String) && !field.isType(Daliuge.DataType.Password) && !field.isType(Daliuge.DataType.Object) && !field.isType(Daliuge.DataType.Unknown)) { const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has a component parameter (" + field.getDisplayText() + ") whose default value is not specified", function(){Utils.showField(eagle, node.getId(),field)}, function(){Utils.fixFieldDefaultValue(eagle, field)}, "Generate default value for parameter"); - errorsWarnings.warnings.push(issue); + field.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + // errorsWarnings.warnings.push(issue); } //chack that the field has a known type if (!Utils.validateType(field.getType())) { const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has a component parameter (" + field.getDisplayText() + ") whose type (" + field.getType() + ") is unknown", function(){Utils.showField(eagle, node.getId(),field)}, function(){Utils.fixFieldType(eagle, field)}, "Prepend existing type (" + field.getType() + ") with 'Object.'"); - errorsWarnings.warnings.push(issue); + field.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + // errorsWarnings.warnings.push(issue); } // check that the fields "key" is the same as the key of the node it belongs to if (field.getNodeKey() !== node.getKey()) { const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has a field (" + field.getDisplayText() + ") whose key (" + field.getNodeKey() + ") doesn't match the node (" + node.getKey() + ")", function(){Utils.showField(eagle, node.getId(),field)}, function(){Utils.fixFieldKey(eagle, node, field)}, "Set field node key correctly"); - errorsWarnings.errors.push(issue); + field.errorsArray.push({issue:issue,validity:Errors.Validity.Error}) + // errorsWarnings.errors.push(issue); } //check that the field has a unique display text on the node @@ -895,10 +908,12 @@ export class Field { if (field.getDisplayText() === field1.getDisplayText() && field.getParameterType() === field1.getParameterType()){ if (field.getId() === field1.getId()){ const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has multiple attributes with the same display text and id (" + field.getDisplayText() + ").", function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixNodeMergeFieldsByIndex(eagle, node, fieldIndex, j)}, "Merge fields"); - errorsWarnings.warnings.push(issue); + field.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + // errorsWarnings.warnings.push(issue); } else { const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has multiple attributes with the same display text (" + field.getDisplayText() + ").", function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixNodeMergeFields(eagle, node, field, field1)}, "Merge fields"); - errorsWarnings.warnings.push(issue); + field.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + // errorsWarnings.warnings.push(issue); } } } @@ -929,13 +944,14 @@ export class Field { const message = "Node " + node.getKey() + " (" + node.getName() + ") with category " + node.getCategory() + " contains field (" + field.getDisplayText() + ") with unsuitable type (" + field.getParameterType() + ")."; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixFieldParameterType(eagle, node, field, suitableType)}, "Switch to suitable type, or remove if no suitable type"); - errorsWarnings.warnings.push(issue); + field.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + // errorsWarnings.warnings.push(issue); } } - field.errorsWarnings(errorsWarnings) + // field.errorsWarnings(errorsWarnings) - return errorsWarnings + // return errorsWarnings } public static sortFunc(a: Field, b: Field) : number { diff --git a/src/GraphRenderer.ts b/src/GraphRenderer.ts index 076e88376..21fe0c65c 100644 --- a/src/GraphRenderer.ts +++ b/src/GraphRenderer.ts @@ -1765,7 +1765,7 @@ export class GraphRenderer { const linkValid : Errors.Validity = Edge.isValid(eagle,false, null, realSourceNode.getKey(), realSourcePort.getId(), realDestinationNode.getKey(), realDestinationPort.getId(), false, false, true, true, {errors:[], warnings:[]}); // abort if edge is invalid - if ((Setting.findValue(Setting.ALLOW_INVALID_EDGES) && linkValid === Errors.Validity.Invalid) || linkValid === Errors.Validity.Valid || linkValid === Errors.Validity.Warning){ + if ((Setting.findValue(Setting.ALLOW_INVALID_EDGES) && linkValid === Errors.Validity.Error) || linkValid === Errors.Validity.Valid || linkValid === Errors.Validity.Warning){ if (linkValid === Errors.Validity.Warning){ GraphRenderer.addEdge(realSourceNode, realSourcePort, realDestinationNode, realDestinationPort, true, false); } else { @@ -2125,7 +2125,7 @@ export class GraphRenderer { case Errors.Validity.Unknown: return "black"; case Errors.Validity.Impossible: - case Errors.Validity.Invalid: + case Errors.Validity.Error: return GraphConfig.getColor("edgeInvalid"); case Errors.Validity.Warning: return GraphConfig.getColor("edgeWarning"); @@ -2250,7 +2250,7 @@ export class GraphRenderer { // check if link has a warning or is invalid const linkValid : Errors.Validity = Edge.isValid(eagle,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, false, {errors:[], warnings:[]}); - if (linkValid === Errors.Validity.Invalid || linkValid === Errors.Validity.Impossible){ + if (linkValid === Errors.Validity.Error || linkValid === Errors.Validity.Impossible){ normalColor = GraphConfig.getColor('edgeInvalid'); selectedColor = GraphConfig.getColor('edgeInvalidSelected'); } diff --git a/src/GraphUpdater.ts b/src/GraphUpdater.ts index bf1f49dcb..815278f09 100644 --- a/src/GraphUpdater.ts +++ b/src/GraphUpdater.ts @@ -200,7 +200,8 @@ export class GraphUpdater { row.lastModified = date.toLocaleDateString() + " " + date.toLocaleTimeString() // check the graph once loaded - const results: Errors.ErrorsWarnings = Utils.checkGraph(eagle); + Utils.checkGraph(eagle); + const results: Errors.ErrorsWarnings = Utils.gatherGraphErrors(); row.numCheckWarnings = results.warnings.length; row.numCheckErrors = results.errors.length; } diff --git a/src/LogicalGraph.ts b/src/LogicalGraph.ts index 543092286..b86d2cee3 100644 --- a/src/LogicalGraph.ts +++ b/src/LogicalGraph.ts @@ -42,12 +42,14 @@ export class LogicalGraph { fileInfo : ko.Observable; private nodes : ko.ObservableArray; private edges : ko.ObservableArray; + private errorsArray : {issue:Errors.Issue, validity:Errors.Validity}[] constructor(){ this.fileInfo = ko.observable(new FileInfo()); this.fileInfo().type = Eagle.FileType.Graph; this.nodes = ko.observableArray([]); this.edges = ko.observableArray([]); + this.errorsArray = [] } static toOJSJson(graph : LogicalGraph, forTranslation : boolean) : object { @@ -313,6 +315,10 @@ export class LogicalGraph { return result; } + getErrors = (): {issue:Errors.Issue, validity:Errors.Validity}[] => { + return this.errorsArray; + } + /** * Opens a dialog for selecting a data component type. */ @@ -787,5 +793,57 @@ export class LogicalGraph { static isValid () : void { //here should be the higher level graph wide checks for graph validity + const eagle = Eagle.getInstance() + const graph = eagle.logicalGraph() + + // check that all node, edge, field ids are unique + // { + const ids : string[] = []; + + // loop over graph nodes + for (const node of graph.getNodes()){ + //check for unique ids + if (ids.includes(node.getId())){ + const issue: Errors.Issue = Errors.ShowFix( + "Node (" + node.getName() + ") does not have a unique id", + function(){Utils.showNode(eagle, node.getId())}, + function(){Utils.newId(node)}, + "Assign node a new id" + ); + graph.errorsArray.push({issue : issue, validity : Errors.Validity.Error}) + // errorsWarnings.errors.push(issue); + } + ids.push(node.getId()); + + for (const field of node.getFields()){ + if (ids.includes(field.getId())){ + const issue: Errors.Issue = Errors.ShowFix( + "Field (" + field.getDisplayText() + ") on node (" + node.getName() + ") does not have a unique id", + function(){Utils.showNode(eagle, node.getId())}, + function(){Utils.newFieldId(eagle, node, field)}, + "Assign field a new id" + ); + graph.errorsArray.push({issue : issue, validity : Errors.Validity.Error}) + // errorsWarnings.errors.push(issue); + } + ids.push(field.getId()); + } + } + + // loop over graph edges + for (const edge of graph.getEdges()){ + if (ids.includes(edge.getId())){ + const issue: Errors.Issue = Errors.ShowFix( + "Edge (" + edge.getId() + ") does not have a unique id", + function(){Utils.showEdge(eagle, edge.getId())}, + function(){Utils.newId(edge)}, + "Assign edge a new id" + ); + graph.errorsArray.push({issue : issue, validity : Errors.Validity.Error}) + // errorsWarnings.errors.push(issue); + } + ids.push(edge.getId()); + } + // } } } diff --git a/src/Node.ts b/src/Node.ts index 72ee452af..6e3256c19 100644 --- a/src/Node.ts +++ b/src/Node.ts @@ -63,6 +63,7 @@ export class Node { private paletteDownloadUrl : ko.Observable; private dataHash : ko.Observable; + private errorsArray : {issue:Errors.Issue, validity:Errors.Validity}[] private errorsWarnings : ko.Observable; public static readonly DEFAULT_COLOR : string = "ffffff"; @@ -113,6 +114,7 @@ export class Node { this.paletteDownloadUrl = ko.observable(""); this.dataHash = ko.observable(""); + this.errorsArray = []; this.errorsWarnings = ko.observable({warnings: [], errors: []}); //graph related things @@ -1136,6 +1138,10 @@ export class Node { return this.errorsWarnings(); } + getErrors = (): {issue:Errors.Issue, validity:Errors.Validity}[] => { + return this.errorsArray; + } + getAllErrorsWarnings = (): Errors.ErrorsWarnings => { const errorsWarnings : Errors.ErrorsWarnings = {warnings: [], errors: []}; errorsWarnings.errors.push(...this.errorsWarnings().errors) @@ -1942,19 +1948,21 @@ export class Node { return x } - static isValid(node: Node, selectedLocation: Eagle.FileType) : Errors.ErrorsWarnings { + static isValid(node: Node, selectedLocation: Eagle.FileType) : void { const eagle = Eagle.getInstance() - const errorsWarnings : Errors.ErrorsWarnings = {warnings: [], errors: []}; + // const errorsWarnings : Errors.ErrorsWarnings = {warnings: [], errors: []}; // check that node has modern (not legacy) category if (node.getCategory() === Category.Component){ const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has legacy category (" + node.getCategory() + ")", function(){Utils.showNode(eagle, node.getId());}, function(){Utils.fixNodeCategory(eagle, node, Category.PythonApp, Category.Type.Application)}, ""); - errorsWarnings.warnings.push(issue); + // errorsWarnings.warnings.push(issue); + node.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) } + // looping through and checking all the fields on the node for (let i = 0 ; i < node.getFields().length ; i++){ const field:Field = node.getFields()[i] - const fieldErrorsWarnings = Field.isValid(node,field,selectedLocation,i) + Field.isValid(node,field,selectedLocation,i) } // check that all nodes have correct numbers of inputs and outputs @@ -1963,22 +1971,26 @@ export class Node { if (node.getInputPorts().length < cData.minInputs){ const message: string = "Node " + node.getKey() + " (" + node.getName() + ") may have too few input ports. A " + node.getCategory() + " component would typically have at least " + cData.minInputs; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId())}, null, ""); - errorsWarnings.warnings.push(issue); + node.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + // errorsWarnings.warnings.push(issue); } if ((node.getInputPorts().length - node.getInputEventPorts().length) > cData.maxInputs){ const message: string = "Node " + node.getKey() + " (" + node.getName() + ") has too many input ports. Should have at most " + cData.maxInputs; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId())}, null, ""); - errorsWarnings.warnings.push(issue); + node.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + // errorsWarnings.warnings.push(issue); } if (node.getOutputPorts().length < cData.minOutputs){ const message: string = "Node " + node.getKey() + " (" + node.getName() + ") may have too few output ports. A " + node.getCategory() + " component would typically have at least " + cData.minOutputs; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId())}, null, ""); - errorsWarnings.warnings.push(issue); + node.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + // errorsWarnings.warnings.push(issue); } if ((node.getOutputPorts().length - node.getOutputEventPorts().length) > cData.maxOutputs){ const message: string = "Node " + node.getKey() + " (" + node.getName() + ") may have too many output ports. Should have at most " + cData.maxOutputs; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId())}, null, ""); - errorsWarnings.warnings.push(issue); + node.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + // errorsWarnings.warnings.push(issue); } // check that all nodes should have at least one connected edge, otherwise what purpose do they serve? @@ -1994,27 +2006,34 @@ export class Node { // only check this if the component has been selected in the graph. If it was selected from the palette, it doesn't make sense to complain that it is not connected. if (!isConnected && !(cData.maxInputs === 0 && cData.maxOutputs === 0) && selectedLocation === Eagle.FileType.Graph){ const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has no connected edges. It should be connected to the graph in some way", function(){Utils.showNode(eagle, node.getId())}, null, ""); - errorsWarnings.warnings.push(issue); + node.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + // errorsWarnings.warnings.push(issue); } // check embedded application categories are not 'None' if (node.hasInputApplication() && node.getInputApplication().getCategory() === Category.None){ - errorsWarnings.errors.push(Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has input application with category 'None'.")); + const issue: Errors.Issue = Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has input application with category 'None'.") + // errorsWarnings.errors.push(Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has input application with category 'None'.")); + node.errorsArray.push({issue:issue,validity:Errors.Validity.Error}); } if (node.hasOutputApplication() && node.getOutputApplication().getCategory() === Category.None){ - errorsWarnings.errors.push(Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has output application with category 'None'.")); + const issue : Errors.Issue = Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has output application with category 'None'.") + // errorsWarnings.errors.push(Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has output application with category 'None'.")); + node.errorsArray.push({issue:issue,validity:Errors.Validity.Error}); } // check that Service nodes have inputApplications with no output ports! if (node.getCategory() === Category.Service && node.hasInputApplication() && node.getInputApplication().getOutputPorts().length > 0){ - errorsWarnings.errors.push(Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") is a Service node, but has an input application with at least one output.")); + const issue : Errors.Issue = Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") is a Service node, but has an input application with at least one output.") + // errorsWarnings.errors.push(Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") is a Service node, but has an input application with at least one output.")); + node.errorsArray.push({issue:issue,validity:Errors.Validity.Error}); } // check that this category of node contains all the fields it requires for (const requirement of Daliuge.categoryFieldsRequired){ if (requirement.categories.includes(node.getCategory())){ for (const requiredField of requirement.fields){ - Node._checkForField(eagle, node, requiredField, errorsWarnings); + Node._checkForField(eagle, node, requiredField); } } } @@ -2023,17 +2042,17 @@ export class Node { for (const requirement of Daliuge.categoryTypeFieldsRequired){ if (requirement.categoryTypes.includes(node.getCategoryType())){ for (const requiredField of requirement.fields){ - Node._checkForField(eagle, node, requiredField, errorsWarnings); + Node._checkForField(eagle, node, requiredField); } } } - node.errorsWarnings(errorsWarnings) + // node.errorsWarnings(errorsWarnings) - return errorsWarnings + // return errorsWarnings } - private static _checkForField(eagle: Eagle, node: Node, field: Field, errorsWarnings: Errors.ErrorsWarnings) : void { + private static _checkForField(eagle: Eagle, node: Node, field: Field) : void { // check if the node already has this field const existingField = node.getFieldByDisplayText(field.getDisplayText()); @@ -2041,11 +2060,15 @@ export class Node { // if so, check the attributes of the field match if (existingField === null){ const message = "Node " + node.getKey() + " (" + node.getName() + ":" + node.category() + ":" + node.categoryType() + ") does not have the required '" + field.getDisplayText() + "' field"; - errorsWarnings.errors.push(Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId());}, function(){Utils.addMissingRequiredField(eagle, node, field);}, "Add missing " + field.getDisplayText() + " field.")); + const issue : Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId());}, function(){Utils.addMissingRequiredField(eagle, node, field);}, "Add missing " + field.getDisplayText() + " field.") + // errorsWarnings.errors.push(Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId());}, function(){Utils.addMissingRequiredField(eagle, node, field);}, "Add missing " + field.getDisplayText() + " field.")); + node.errorsArray.push({issue:issue,validity:Errors.Validity.Error}); } else { if (existingField.getParameterType() !== field.getParameterType()){ const message = "Node " + node.getKey() + " (" + node.getName() + ") has a '" + field.getDisplayText() + "' field with the wrong parameter type (" + existingField.getParameterType() + "), should be a " + field.getParameterType(); - existingField.addErrorsWarnings(Errors.ShowFix(message, function(){Utils.showField(eagle, node.getId(),existingField);}, function(){Utils.fixFieldParameterType(eagle, node, existingField, field.getParameterType())}, "Switch type of field to '" + field.getParameterType()),'error'); + const issue : Errors.Issue = Errors.ShowFix(message, function(){Utils.showField(eagle, node.getId(),existingField);}, function(){Utils.fixFieldParameterType(eagle, node, existingField, field.getParameterType())}, "Switch type of field to '" + field.getParameterType()) + // existingField.addErrorsWarnings(Errors.ShowFix(message, function(){Utils.showField(eagle, node.getId(),existingField);}, function(){Utils.fixFieldParameterType(eagle, node, existingField, field.getParameterType())}, "Switch type of field to '" + field.getParameterType()),'error'); + node.errorsArray.push({issue:issue,validity:Errors.Validity.Error}); } } } diff --git a/src/Setting.ts b/src/Setting.ts index 08899d3a8..df718e86c 100644 --- a/src/Setting.ts +++ b/src/Setting.ts @@ -397,7 +397,7 @@ const settings : SettingsGroup[] = [ new Setting(true, "Filter Node Suggestions", Setting.FILTER_NODE_SUGGESTIONS, "Filter Node Options When Drawing Edges Into Empty Space", false, Setting.Type.Boolean,true,true,true,true,false), new Setting(false, "STUDENT_SETTINGS_MODE", Setting.STUDENT_SETTINGS_MODE, "Mode disabling setting editing for students.", false, Setting.Type.Boolean, true, false,false, false, false), new Setting(true, "Value Editing", Setting.VALUE_EDITING_PERMS, "Set which values are allowed to be edited.", false, Setting.Type.Select, Setting.valueEditingPerms.KeyOnly,Setting.valueEditingPerms.Normal,Setting.valueEditingPerms.Normal,Setting.valueEditingPerms.ReadOnly,Setting.valueEditingPerms.ReadOnly, Object.values(Setting.valueEditingPerms)), - new Setting(true, "Auto-complete edges level", Setting.AUTO_COMPLETE_EDGES_LEVEL, "Specifies the minimum validity level of auto-complete edges displayed when dragging a new edge", false, Setting.Type.Select, Errors.Validity.Valid, Errors.Validity.Valid, Errors.Validity.Warning, Errors.Validity.Warning, Errors.Validity.Invalid, [Errors.Validity.Invalid, Errors.Validity.Warning, Errors.Validity.Valid]), + new Setting(true, "Auto-complete edges level", Setting.AUTO_COMPLETE_EDGES_LEVEL, "Specifies the minimum validity level of auto-complete edges displayed when dragging a new edge", false, Setting.Type.Select, Errors.Validity.Valid, Errors.Validity.Valid, Errors.Validity.Warning, Errors.Validity.Warning, Errors.Validity.Error, [Errors.Validity.Error, Errors.Validity.Warning, Errors.Validity.Valid]), ] ), new SettingsGroup( diff --git a/src/Utils.ts b/src/Utils.ts index 3e6840d71..1d056e24a 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -1379,7 +1379,7 @@ export class Utils { static checkPalette(palette: Palette): Errors.ErrorsWarnings { const errorsWarnings: Errors.ErrorsWarnings = {warnings: [], errors: []}; - + const paletteErrors : {issue:Errors.Issue, validity:Errors.Validity}[]=[] // check for duplicate keys const keys: number[] = []; @@ -1394,55 +1394,63 @@ export class Utils { // check all nodes are valid for (const node of palette.getNodes()){ - const nodeErrorsWarnings = Node.isValid(node, Eagle.FileType.Palette); - errorsWarnings.errors.push(...nodeErrorsWarnings.errors) - errorsWarnings.warnings.push(...nodeErrorsWarnings.warnings) + Node.isValid(node, Eagle.FileType.Palette); + paletteErrors.push(...node.getErrors()) + // errorsWarnings.errors.push(...nodeErrorsWarnings.errors) + // errorsWarnings.warnings.push(...nodeErrorsWarnings.warnings) + } + + for(const error of paletteErrors){ + if(error.validity === Errors.Validity.Error){ + errorsWarnings.errors.push(error.issue) + }else{ + errorsWarnings.warnings.push(error.issue) + } } return errorsWarnings; } - static checkGraph(eagle: Eagle): Errors.ErrorsWarnings { - const errorsWarnings: Errors.ErrorsWarnings = {warnings: [], errors: []}; - + static checkGraph(eagle: Eagle): void { + // const errorsWarnings: Errors.ErrorsWarnings = {warnings: [], errors: []}; const graph: LogicalGraph = eagle.logicalGraph(); // check all nodes are valid for (const node of graph.getNodes()){ - const nodeErrorsWarnings = Node.isValid(node, Eagle.FileType.Graph); - errorsWarnings.errors.push(...nodeErrorsWarnings.errors) - errorsWarnings.warnings.push(...nodeErrorsWarnings.warnings) + Node.isValid(node, Eagle.FileType.Graph); + // errorsWarnings.errors.push(...nodeErrorsWarnings.errors) + // errorsWarnings.warnings.push(...nodeErrorsWarnings.warnings) //get the node's field errorswarnings - for(const field of node.getFields()){ - errorsWarnings.errors.push(...field.getErrorsWarnings().errors) - errorsWarnings.warnings.push(...field.getErrorsWarnings().warnings) - } + // for(const field of node.getFields()){ + // errorsWarnings.errors.push(...field.getErrorsWarnings().errors) + // errorsWarnings.warnings.push(...field.getErrorsWarnings().warnings) + // } // check the embedded applications - if (node.hasInputApplication()){ - const inputNodeErrorsWarnings = Node.isValid(node.getInputApplication(),Eagle.FileType.Graph) - errorsWarnings.errors.push(...inputNodeErrorsWarnings.errors) - errorsWarnings.warnings.push(...inputNodeErrorsWarnings.warnings) - - //get the input application's field errorswarnings - for(const field of node.getInputApplication().getFields()){ - errorsWarnings.errors.push(...field.getErrorsWarnings().errors) - errorsWarnings.warnings.push(...field.getErrorsWarnings().warnings) - } - } - if (node.hasOutputApplication()){ - const outputNodeErrorsWarnings = Node.isValid(node.getOutputApplication(),Eagle.FileType.Graph) - errorsWarnings.errors.push(...outputNodeErrorsWarnings.errors) - errorsWarnings.warnings.push(...outputNodeErrorsWarnings.warnings) + // if (node.hasInputApplication()){ + // const inputNodeErrorsWarnings = Node.isValid(node.getInputApplication(),Eagle.FileType.Graph) + // // errorsWarnings.errors.push(...inputNodeErrorsWarnings.errors) + // // errorsWarnings.warnings.push(...inputNodeErrorsWarnings.warnings) + + // //get the input application's field errorswarnings + // for(const field of node.getInputApplication().getFields()){ + // // errorsWarnings.errors.push(...field.getErrorsWarnings().errors) + // // errorsWarnings.warnings.push(...field.getErrorsWarnings().warnings) + // } + // } + // if (node.hasOutputApplication()){ + // const outputNodeErrorsWarnings = Node.isValid(node.getOutputApplication(),Eagle.FileType.Graph) + // // errorsWarnings.errors.push(...outputNodeErrorsWarnings.errors) + // // errorsWarnings.warnings.push(...outputNodeErrorsWarnings.warnings) - //get the output application's field errorswarnings - for(const field of node.getOutputApplication().getFields()){ - errorsWarnings.errors.push(...field.getErrorsWarnings().errors) - errorsWarnings.warnings.push(...field.getErrorsWarnings().warnings) - } - } + // //get the output application's field errorswarnings + // for(const field of node.getOutputApplication().getFields()){ + // // errorsWarnings.errors.push(...field.getErrorsWarnings().errors) + // // errorsWarnings.warnings.push(...field.getErrorsWarnings().warnings) + // } + // } } // check all edges are valid @@ -1450,50 +1458,104 @@ export class Utils { Edge.isValid(eagle,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, false, {warnings: [], errors: []}); } - // check that all node, edge, field ids are unique - { - const ids : string[] = []; - - // loop over graph nodes - for (const node of graph.getNodes()){ - //check for unique ids - if (ids.includes(node.getId())){ - const issue: Errors.Issue = Errors.ShowFix( - "Node (" + node.getName() + ") does not have a unique id", - function(){Utils.showNode(eagle, node.getId())}, - function(){Utils.newId(node)}, - "Assign node a new id" - ); - errorsWarnings.errors.push(issue); - } - ids.push(node.getId()); - - for (const field of node.getFields()){ - if (ids.includes(field.getId())){ - const issue: Errors.Issue = Errors.ShowFix( - "Field (" + field.getDisplayText() + ") on node (" + node.getName() + ") does not have a unique id", - function(){Utils.showNode(eagle, node.getId())}, - function(){Utils.newFieldId(eagle, node, field)}, - "Assign field a new id" - ); - errorsWarnings.errors.push(issue); - } - ids.push(field.getId()); + // // check that all node, edge, field ids are unique + // { + // const ids : string[] = []; + + // // loop over graph nodes + // for (const node of graph.getNodes()){ + // //check for unique ids + // if (ids.includes(node.getId())){ + // const issue: Errors.Issue = Errors.ShowFix( + // "Node (" + node.getName() + ") does not have a unique id", + // function(){Utils.showNode(eagle, node.getId())}, + // function(){Utils.newId(node)}, + // "Assign node a new id" + // ); + // // errorsWarnings.errors.push(issue); + // } + // ids.push(node.getId()); + + // for (const field of node.getFields()){ + // if (ids.includes(field.getId())){ + // const issue: Errors.Issue = Errors.ShowFix( + // "Field (" + field.getDisplayText() + ") on node (" + node.getName() + ") does not have a unique id", + // function(){Utils.showNode(eagle, node.getId())}, + // function(){Utils.newFieldId(eagle, node, field)}, + // "Assign field a new id" + // ); + // // errorsWarnings.errors.push(issue); + // } + // ids.push(field.getId()); + // } + // } + + // // loop over graph edges + // for (const edge of graph.getEdges()){ + // if (ids.includes(edge.getId())){ + // const issue: Errors.Issue = Errors.ShowFix( + // "Edge (" + edge.getId() + ") does not have a unique id", + // function(){Utils.showEdge(eagle, edge.getId())}, + // function(){Utils.newId(edge)}, + // "Assign edge a new id" + // ); + // // errorsWarnings.errors.push(issue); + // } + // ids.push(edge.getId()); + // } + // } + + // return errorsWarnings; + } + + static gatherGraphErrors(): Errors.ErrorsWarnings { + const eagle = Eagle.getInstance() + const errorsWarnings: Errors.ErrorsWarnings = {warnings: [], errors: []}; + const graphErrors : {issue:Errors.Issue, validity:Errors.Validity}[] = [] + const graph : LogicalGraph = eagle.logicalGraph() + + //gather all the errors + //from nodes + for(const node of graph.getNodes()){ + graphErrors.push(...node.getErrors()) + + //fields + for( const field of node.getFields()){ + graphErrors.push(...field.getErrors()) + } + + //embedded input applications and their fields + if(node.hasInputApplication()){ + graphErrors.push(...node.getInputApplication().getErrors()) + + for( const field of node.getInputApplication().getFields()){ + graphErrors.push(...field.getErrors()) } } - // loop over graph edges - for (const edge of graph.getEdges()){ - if (ids.includes(edge.getId())){ - const issue: Errors.Issue = Errors.ShowFix( - "Edge (" + edge.getId() + ") does not have a unique id", - function(){Utils.showEdge(eagle, edge.getId())}, - function(){Utils.newId(edge)}, - "Assign edge a new id" - ); - errorsWarnings.errors.push(issue); + //embedded output applications and their fields + if(node.hasOutputApplication()){ + graphErrors.push(...node.getOutputApplication().getErrors()) + + for( const field of node.getOutputApplication().getFields()){ + graphErrors.push(...field.getErrors()) } - ids.push(edge.getId()); + } + } + + // from edges + for (const edge of graph.getEdges()){ + graphErrors.push(...edge.getErrorsArray()) + } + + //from logical graph + graphErrors.push(...graph.getErrors()) + + for(const error of graphErrors){ + if(error.validity === Errors.Validity.Error || error.validity === Errors.Validity.Impossible || error.validity === Errors.Validity.Unknown){ + errorsWarnings.errors.push(error.issue) + }else{ + errorsWarnings.warnings.push(error.issue) } } @@ -2190,7 +2252,7 @@ export class Utils { } if (errorsWarnings.errors.length !== 0){ - return Errors.Validity.Invalid; + return Errors.Validity.Error; } return Errors.Validity.Warning; From cb2150dfa90ba5420c8bc96e1bd890a785d9e1c4 Mon Sep 17 00:00:00 2001 From: M-Wicenec Date: Mon, 8 Jul 2024 16:07:48 +0800 Subject: [PATCH 12/17] fixing an error, embedded appas are now also validated --- src/Node.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Node.ts b/src/Node.ts index 6e3256c19..a6d96060d 100644 --- a/src/Node.ts +++ b/src/Node.ts @@ -1965,6 +1965,18 @@ export class Node { Field.isValid(node,field,selectedLocation,i) } + if(node.isConstruct()){ + //checking the input application if one is present + if(node.hasInputApplication()){ + Node.isValid(node.getInputApplication(),selectedLocation) + } + + //checking the output application if one is present + if(node.hasOutputApplication()){ + Node.isValid(node.getOutputApplication(),selectedLocation) + } + } + // check that all nodes have correct numbers of inputs and outputs const cData: Category.CategoryData = CategoryData.getCategoryData(node.getCategory()); From 9221d84c4cb4ae5321453fe811655380cea601d2 Mon Sep 17 00:00:00 2001 From: MWicenec Date: Wed, 10 Jul 2024 14:13:34 +0800 Subject: [PATCH 13/17] made get warningerrors functions pure computed --- src/Field.ts | 40 ++++++++++++++++++++------------- src/Node.ts | 63 ++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 71 insertions(+), 32 deletions(-) diff --git a/src/Field.ts b/src/Field.ts index 1ed74f0de..ac9ed3103 100644 --- a/src/Field.ts +++ b/src/Field.ts @@ -42,7 +42,7 @@ export class Field { private outputAngle : number; private errorsArray : {issue:Errors.Issue, validity:Errors.Validity}[] - private errorsWarnings : ko.Observable; + // private errorsWarnings : ko.Observable; constructor(id: string, displayText: string, value: string, defaultValue: string, description: string, readonly: boolean, type: string, precious: boolean, options: string[], positional: boolean, parameterType: Daliuge.FieldType, usage: Daliuge.FieldUsage, keyAttribute: boolean){ this.displayText = ko.observable(displayText); @@ -75,7 +75,7 @@ export class Field { this.outputAngle = 0; this.errorsArray = []; - this.errorsWarnings = ko.observable({warnings: [], errors: []}); + // this.errorsWarnings = ko.observable({warnings: [], errors: []}); } getId = () : string => { @@ -346,26 +346,34 @@ export class Field { return this.nodeKey(); } - getErrorsWarnings = (): Errors.ErrorsWarnings => { - return this.errorsWarnings(); - } + getErrorsWarnings : ko.PureComputed = ko.pureComputed(() => { + const errorsWarnings : Errors.ErrorsWarnings = {warnings: [], errors: []}; + + this.getErrors().forEach(function(error){ + if(error.validity === Errors.Validity.Error || error.validity === Errors.Validity.Unknown){ + errorsWarnings.errors.push(error.issue) + }else{ + errorsWarnings.warnings.push(error.issue) + } + }) + + return errorsWarnings; + }, this); getErrors = (): {issue:Errors.Issue, validity:Errors.Validity}[] => { return this.errorsArray; } - addErrorsWarnings(issue:Errors.Issue, issueType:string) : void { - if(issueType === 'error'){ - this.errorsWarnings().errors.push(issue) - }else{ - this.errorsWarnings().warnings.push(issue) - } + addError(issue:Errors.Issue, validity:Errors.Validity){ + this.errorsArray.push({issue:issue,validity:validity}) } getBackgroundColor : ko.PureComputed = ko.pureComputed(() => { - if(this.errorsWarnings().errors.length>0 && Setting.findValue(Setting.SHOW_GRAPH_WARNINGS) != Setting.ShowErrorsMode.None){ + const errorsWarnings = this.getErrorsWarnings() + + if(errorsWarnings.errors.length>0 && Setting.findValue(Setting.SHOW_GRAPH_WARNINGS) != Setting.ShowErrorsMode.None){ return '#ea2727' - }else if(this.errorsWarnings().warnings.length>0 && Setting.findValue(Setting.SHOW_GRAPH_WARNINGS) === Setting.ShowErrorsMode.Warnings){ + }else if(errorsWarnings.warnings.length>0 && Setting.findValue(Setting.SHOW_GRAPH_WARNINGS) === Setting.ShowErrorsMode.Warnings){ return '#ffa500' }else{ return '' @@ -373,11 +381,13 @@ export class Field { }, this); getHasErrors = () : boolean => { - return this.errorsWarnings().errors.length>0; + const errorsWarnings = this.getErrorsWarnings() + return errorsWarnings.errors.length>0; } getHasOnlyWarnings = () : boolean => { - return this.errorsWarnings().warnings.length>0 && this.errorsWarnings().errors.length === 0; + const errorsWarnings = this.getErrorsWarnings() + return errorsWarnings.warnings.length>0 && errorsWarnings.errors.length === 0; } setNodeKey = (key : number) : void => { diff --git a/src/Node.ts b/src/Node.ts index a6d96060d..72dc94c6c 100644 --- a/src/Node.ts +++ b/src/Node.ts @@ -64,7 +64,7 @@ export class Node { private dataHash : ko.Observable; private errorsArray : {issue:Errors.Issue, validity:Errors.Validity}[] - private errorsWarnings : ko.Observable; + // private errorsWarnings : ko.Observable; public static readonly DEFAULT_COLOR : string = "ffffff"; @@ -115,7 +115,7 @@ export class Node { this.dataHash = ko.observable(""); this.errorsArray = []; - this.errorsWarnings = ko.observable({warnings: [], errors: []}); + // this.errorsWarnings = ko.observable({warnings: [], errors: []}); //graph related things this.expanded = ko.observable(true); @@ -1134,33 +1134,59 @@ export class Node { return result; } - getErrorsWarnings = (): Errors.ErrorsWarnings => { - return this.errorsWarnings(); - } - getErrors = (): {issue:Errors.Issue, validity:Errors.Validity}[] => { return this.errorsArray; } - getAllErrorsWarnings = (): Errors.ErrorsWarnings => { + getAllErrors = () : {issue:Errors.Issue, validity:Errors.Validity}[] => { + const allNodeErrors : {issue:Errors.Issue, validity:Errors.Validity}[] = [] + + allNodeErrors.push(...this.getErrors()) + this.getFields().forEach(function(field){ + allNodeErrors.push(...field.getErrors()) + }) + + return allNodeErrors + } + + getErrorsWarnings : ko.PureComputed = ko.pureComputed(() => { + const errorsWarnings : Errors.ErrorsWarnings = {warnings: [], errors: []}; + + this.getErrors().forEach(function(error){ + if(error.validity === Errors.Validity.Error || error.validity === Errors.Validity.Unknown){ + errorsWarnings.errors.push(error.issue) + }else{ + errorsWarnings.warnings.push(error.issue) + } + }) + + return errorsWarnings; + }, this); + + getAllErrorsWarnings : ko.PureComputed = ko.pureComputed(() => { const errorsWarnings : Errors.ErrorsWarnings = {warnings: [], errors: []}; - errorsWarnings.errors.push(...this.errorsWarnings().errors) - errorsWarnings.warnings.push(...this.errorsWarnings().warnings) + const nodeErrors = this.getErrorsWarnings() + + errorsWarnings.errors.push(...nodeErrors.errors) + errorsWarnings.warnings.push(...nodeErrors.warnings) this.getFields().forEach((field) =>{ - errorsWarnings.errors.push(...field.getErrorsWarnings().errors) - errorsWarnings.warnings.push(...field.getErrorsWarnings().warnings) + const fieldErrors = field.getErrorsWarnings() + errorsWarnings.errors.push(...fieldErrors.errors) + errorsWarnings.warnings.push(...fieldErrors.warnings) }) return errorsWarnings - } + }, this); getBorderColor : ko.PureComputed = ko.pureComputed(() => { + const errorsWarnings = this.getErrorsWarnings() + if(this.isEmbedded()){ return '' //returning nothing lets the means we are not over writing the default css behaviour - }else if(this.errorsWarnings().errors.length>0 && Setting.findValue(Setting.SHOW_GRAPH_WARNINGS) != Setting.ShowErrorsMode.None){ + }else if(errorsWarnings.errors.length>0 && Setting.findValue(Setting.SHOW_GRAPH_WARNINGS) != Setting.ShowErrorsMode.None){ return '#ea2727' - }else if(this.errorsWarnings().warnings.length>0 && Setting.findValue(Setting.SHOW_GRAPH_WARNINGS) === Setting.ShowErrorsMode.Warnings){ + }else if(errorsWarnings.warnings.length>0 && Setting.findValue(Setting.SHOW_GRAPH_WARNINGS) === Setting.ShowErrorsMode.Warnings){ return '#ffa500' }else{ return '#2e3192' @@ -1168,10 +1194,12 @@ export class Node { }, this); getBackgroundColor : ko.PureComputed = ko.pureComputed(() => { + const errorsWarnings = this.getErrorsWarnings() const eagle = Eagle.getInstance() - if(this.errorsWarnings().errors.length>0 && Setting.findValue(Setting.SHOW_GRAPH_WARNINGS) != Setting.ShowErrorsMode.None){ + + if(errorsWarnings.errors.length>0 && Setting.findValue(Setting.SHOW_GRAPH_WARNINGS) != Setting.ShowErrorsMode.None){ return '#ffdcdc' - }else if(this.errorsWarnings().warnings.length>0 && Setting.findValue(Setting.SHOW_GRAPH_WARNINGS) === Setting.ShowErrorsMode.Warnings){ + }else if(errorsWarnings.warnings.length>0 && Setting.findValue(Setting.SHOW_GRAPH_WARNINGS) === Setting.ShowErrorsMode.Warnings){ return '#ffeac4' }else if(this.isBranch()){ //for some reason branch nodes dont want to behave like other nodes, i need to return their background or selected color manually @@ -2080,7 +2108,8 @@ export class Node { const message = "Node " + node.getKey() + " (" + node.getName() + ") has a '" + field.getDisplayText() + "' field with the wrong parameter type (" + existingField.getParameterType() + "), should be a " + field.getParameterType(); const issue : Errors.Issue = Errors.ShowFix(message, function(){Utils.showField(eagle, node.getId(),existingField);}, function(){Utils.fixFieldParameterType(eagle, node, existingField, field.getParameterType())}, "Switch type of field to '" + field.getParameterType()) // existingField.addErrorsWarnings(Errors.ShowFix(message, function(){Utils.showField(eagle, node.getId(),existingField);}, function(){Utils.fixFieldParameterType(eagle, node, existingField, field.getParameterType())}, "Switch type of field to '" + field.getParameterType()),'error'); - node.errorsArray.push({issue:issue,validity:Errors.Validity.Error}); + // node.errorsArray.push({issue:issue,validity:Errors.Validity.Error}); + existingField.addError(issue,Errors.Validity.Error) } } } From 29d95c7d68fb109f14db6cac3025dcfe7303926c Mon Sep 17 00:00:00 2001 From: MWicenec Date: Thu, 11 Jul 2024 14:05:06 +0800 Subject: [PATCH 14/17] renamed errorsArrays to be issues instead, fixed a bug with the issues in the errors array not being cleared --- src/Eagle.ts | 1 + src/Edge.ts | 16 ++++--- src/Field.ts | 32 +++++++------- src/LogicalGraph.ts | 14 +++--- src/Node.ts | 38 ++++++++--------- src/Utils.ts | 101 +++++--------------------------------------- 6 files changed, 63 insertions(+), 139 deletions(-) diff --git a/src/Eagle.ts b/src/Eagle.ts index 70035eb9c..dea45148a 100644 --- a/src/Eagle.ts +++ b/src/Eagle.ts @@ -4568,6 +4568,7 @@ export class Eagle { checkGraph = (): void => { Utils.checkGraph(this);//validate the graph const graphErrors = Utils.gatherGraphErrors() //gather all the errors from all of the components + this.graphWarnings(graphErrors.warnings); this.graphErrors(graphErrors.errors); }; diff --git a/src/Edge.ts b/src/Edge.ts index 8b4322a33..5eafbbb50 100644 --- a/src/Edge.ts +++ b/src/Edge.ts @@ -42,7 +42,7 @@ export class Edge { private closesLoop : boolean; // indicates that this is a special type of edge that can be drawn in eagle to specify the start/end of groups. private selectionRelative : boolean // indicates if the edge is either selected or attached to a selected node private isShortEdge : ko.Observable; - private errorsArray : {issue:Errors.Issue, validity:Errors.Validity}[] + private issues : {issue:Errors.Issue, validity:Errors.Validity}[] constructor(srcNodeKey : number, srcPortId : string, destNodeKey : number, destPortId : string, loopAware: boolean, closesLoop: boolean, selectionRelative : boolean){ this._id = Utils.uuidv4(); @@ -56,7 +56,7 @@ export class Edge { this.closesLoop = closesLoop; this.selectionRelative = selectionRelative; this.isShortEdge = ko.observable(false) - this.errorsArray = []; + this.issues = []; } getId = () : string => { @@ -177,8 +177,8 @@ export class Edge { return result; } - getErrorsArray = () : {issue:Errors.Issue, validity:Errors.Validity}[] => { - return this.errorsArray; + getissues = () : {issue:Errors.Issue, validity:Errors.Validity}[] => { + return this.issues; } static toOJSJson(edge : Edge) : object { @@ -285,7 +285,11 @@ export class Edge { static isValid(eagle: Eagle,autoSuggestMode:boolean, edgeId: string, sourceNodeKey : number, sourcePortId : string, destinationNodeKey : number, destinationPortId : string, loopAware: boolean, closesLoop: boolean, showNotification : boolean, showConsole : boolean, errorsWarnings: Errors.ErrorsWarnings) : Errors.Validity { let impossibleEdge : boolean = false; - + const edge = eagle.logicalGraph().findEdgeById(edgeId) + if(edge){ + edge.issues = [] //clear old issues + } + // check for problems if (isNaN(sourceNodeKey)){ return Errors.Validity.Unknown; @@ -528,6 +532,6 @@ export class Edge { if (type === "warning" && errorsWarnings !== null){ errorsWarnings.warnings.push(issue); } - Eagle.getInstance().logicalGraph().findEdgeById(edgeId)?.errorsArray.push({issue:issue, validity:linkValid}) + Eagle.getInstance().logicalGraph().findEdgeById(edgeId)?.issues.push({issue:issue, validity:linkValid}) } } diff --git a/src/Field.ts b/src/Field.ts index ac9ed3103..5964df4f9 100644 --- a/src/Field.ts +++ b/src/Field.ts @@ -41,7 +41,7 @@ export class Field { private inputAngle : number; private outputAngle : number; - private errorsArray : {issue:Errors.Issue, validity:Errors.Validity}[] + private issues : {issue:Errors.Issue, validity:Errors.Validity}[] // private errorsWarnings : ko.Observable; constructor(id: string, displayText: string, value: string, defaultValue: string, description: string, readonly: boolean, type: string, precious: boolean, options: string[], positional: boolean, parameterType: Daliuge.FieldType, usage: Daliuge.FieldUsage, keyAttribute: boolean){ @@ -74,7 +74,7 @@ export class Field { this.inputAngle = 0; this.outputAngle = 0; - this.errorsArray = []; + this.issues = []; // this.errorsWarnings = ko.observable({warnings: [], errors: []}); } @@ -349,7 +349,7 @@ export class Field { getErrorsWarnings : ko.PureComputed = ko.pureComputed(() => { const errorsWarnings : Errors.ErrorsWarnings = {warnings: [], errors: []}; - this.getErrors().forEach(function(error){ + this.getIssues().forEach(function(error){ if(error.validity === Errors.Validity.Error || error.validity === Errors.Validity.Unknown){ errorsWarnings.errors.push(error.issue) }else{ @@ -360,12 +360,12 @@ export class Field { return errorsWarnings; }, this); - getErrors = (): {issue:Errors.Issue, validity:Errors.Validity}[] => { - return this.errorsArray; + getIssues = (): {issue:Errors.Issue, validity:Errors.Validity}[] => { + return this.issues; } addError(issue:Errors.Issue, validity:Errors.Validity){ - this.errorsArray.push({issue:issue,validity:validity}) + this.issues.push({issue:issue,validity:validity}) } getBackgroundColor : ko.PureComputed = ko.pureComputed(() => { @@ -819,7 +819,7 @@ export class Field { static isValid(node:Node, field:Field, selectedLocation:Eagle.FileType, fieldIndex:number){ const eagle = Eagle.getInstance() - // const errorsWarnings : Errors.ErrorsWarnings = {warnings: [], errors: []}; + field.issues = [] //clear old issues //checks for input ports if(field.isInputPort()){ @@ -844,7 +844,7 @@ export class Field { } } - field.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + field.issues.push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } @@ -873,7 +873,7 @@ export class Field { issue = Errors.ShowFix("Node " + node.getKey() + " (" + parentNode.getName() + ") has output application (" + node.getName() + ") with output port (" + field.getDisplayText() + ") whose type is not specified", function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixFieldType(eagle, field)}, ""); } } - field.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + field.issues.push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } @@ -883,28 +883,28 @@ export class Field { //check that the field has an id if (field.getId() === "" || field.getId() === null){ const issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has field (" + field.getDisplayText() + ") with no id", function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixFieldId(eagle, field)}, "Generate id for field"); - field.errorsArray.push({issue:issue,validity:Errors.Validity.Error}) + field.issues.push({issue:issue,validity:Errors.Validity.Error}) // errorsWarnings.errors.push(issue); } // check that the field has a default value if (field.getDefaultValue() === "" && !field.isType(Daliuge.DataType.String) && !field.isType(Daliuge.DataType.Password) && !field.isType(Daliuge.DataType.Object) && !field.isType(Daliuge.DataType.Unknown)) { const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has a component parameter (" + field.getDisplayText() + ") whose default value is not specified", function(){Utils.showField(eagle, node.getId(),field)}, function(){Utils.fixFieldDefaultValue(eagle, field)}, "Generate default value for parameter"); - field.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + field.issues.push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } //chack that the field has a known type if (!Utils.validateType(field.getType())) { const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has a component parameter (" + field.getDisplayText() + ") whose type (" + field.getType() + ") is unknown", function(){Utils.showField(eagle, node.getId(),field)}, function(){Utils.fixFieldType(eagle, field)}, "Prepend existing type (" + field.getType() + ") with 'Object.'"); - field.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + field.issues.push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } // check that the fields "key" is the same as the key of the node it belongs to if (field.getNodeKey() !== node.getKey()) { const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has a field (" + field.getDisplayText() + ") whose key (" + field.getNodeKey() + ") doesn't match the node (" + node.getKey() + ")", function(){Utils.showField(eagle, node.getId(),field)}, function(){Utils.fixFieldKey(eagle, node, field)}, "Set field node key correctly"); - field.errorsArray.push({issue:issue,validity:Errors.Validity.Error}) + field.issues.push({issue:issue,validity:Errors.Validity.Error}) // errorsWarnings.errors.push(issue); } @@ -918,11 +918,11 @@ export class Field { if (field.getDisplayText() === field1.getDisplayText() && field.getParameterType() === field1.getParameterType()){ if (field.getId() === field1.getId()){ const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has multiple attributes with the same display text and id (" + field.getDisplayText() + ").", function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixNodeMergeFieldsByIndex(eagle, node, fieldIndex, j)}, "Merge fields"); - field.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + field.issues.push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } else { const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has multiple attributes with the same display text (" + field.getDisplayText() + ").", function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixNodeMergeFields(eagle, node, field, field1)}, "Merge fields"); - field.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + field.issues.push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } } @@ -954,7 +954,7 @@ export class Field { const message = "Node " + node.getKey() + " (" + node.getName() + ") with category " + node.getCategory() + " contains field (" + field.getDisplayText() + ") with unsuitable type (" + field.getParameterType() + ")."; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixFieldParameterType(eagle, node, field, suitableType)}, "Switch to suitable type, or remove if no suitable type"); - field.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + field.issues.push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } } diff --git a/src/LogicalGraph.ts b/src/LogicalGraph.ts index b86d2cee3..82d079fb6 100644 --- a/src/LogicalGraph.ts +++ b/src/LogicalGraph.ts @@ -42,14 +42,14 @@ export class LogicalGraph { fileInfo : ko.Observable; private nodes : ko.ObservableArray; private edges : ko.ObservableArray; - private errorsArray : {issue:Errors.Issue, validity:Errors.Validity}[] + private issues : {issue:Errors.Issue, validity:Errors.Validity}[] constructor(){ this.fileInfo = ko.observable(new FileInfo()); this.fileInfo().type = Eagle.FileType.Graph; this.nodes = ko.observableArray([]); this.edges = ko.observableArray([]); - this.errorsArray = [] + this.issues = [] } static toOJSJson(graph : LogicalGraph, forTranslation : boolean) : object { @@ -315,8 +315,8 @@ export class LogicalGraph { return result; } - getErrors = (): {issue:Errors.Issue, validity:Errors.Validity}[] => { - return this.errorsArray; + getIssues = (): {issue:Errors.Issue, validity:Errors.Validity}[] => { + return this.issues; } /** @@ -810,7 +810,7 @@ export class LogicalGraph { function(){Utils.newId(node)}, "Assign node a new id" ); - graph.errorsArray.push({issue : issue, validity : Errors.Validity.Error}) + graph.issues.push({issue : issue, validity : Errors.Validity.Error}) // errorsWarnings.errors.push(issue); } ids.push(node.getId()); @@ -823,7 +823,7 @@ export class LogicalGraph { function(){Utils.newFieldId(eagle, node, field)}, "Assign field a new id" ); - graph.errorsArray.push({issue : issue, validity : Errors.Validity.Error}) + graph.issues.push({issue : issue, validity : Errors.Validity.Error}) // errorsWarnings.errors.push(issue); } ids.push(field.getId()); @@ -839,7 +839,7 @@ export class LogicalGraph { function(){Utils.newId(edge)}, "Assign edge a new id" ); - graph.errorsArray.push({issue : issue, validity : Errors.Validity.Error}) + graph.issues.push({issue : issue, validity : Errors.Validity.Error}) // errorsWarnings.errors.push(issue); } ids.push(edge.getId()); diff --git a/src/Node.ts b/src/Node.ts index 72dc94c6c..e9c7b81a4 100644 --- a/src/Node.ts +++ b/src/Node.ts @@ -63,7 +63,7 @@ export class Node { private paletteDownloadUrl : ko.Observable; private dataHash : ko.Observable; - private errorsArray : {issue:Errors.Issue, validity:Errors.Validity}[] + private issues : {issue:Errors.Issue, validity:Errors.Validity}[] // private errorsWarnings : ko.Observable; public static readonly DEFAULT_COLOR : string = "ffffff"; @@ -114,7 +114,7 @@ export class Node { this.paletteDownloadUrl = ko.observable(""); this.dataHash = ko.observable(""); - this.errorsArray = []; + this.issues = []; // this.errorsWarnings = ko.observable({warnings: [], errors: []}); //graph related things @@ -1134,16 +1134,16 @@ export class Node { return result; } - getErrors = (): {issue:Errors.Issue, validity:Errors.Validity}[] => { - return this.errorsArray; + getIssues = (): {issue:Errors.Issue, validity:Errors.Validity}[] => { + return this.issues; } getAllErrors = () : {issue:Errors.Issue, validity:Errors.Validity}[] => { const allNodeErrors : {issue:Errors.Issue, validity:Errors.Validity}[] = [] - allNodeErrors.push(...this.getErrors()) + allNodeErrors.push(...this.getIssues()) this.getFields().forEach(function(field){ - allNodeErrors.push(...field.getErrors()) + allNodeErrors.push(...field.getIssues()) }) return allNodeErrors @@ -1152,7 +1152,7 @@ export class Node { getErrorsWarnings : ko.PureComputed = ko.pureComputed(() => { const errorsWarnings : Errors.ErrorsWarnings = {warnings: [], errors: []}; - this.getErrors().forEach(function(error){ + this.getIssues().forEach(function(error){ if(error.validity === Errors.Validity.Error || error.validity === Errors.Validity.Unknown){ errorsWarnings.errors.push(error.issue) }else{ @@ -1978,13 +1978,13 @@ export class Node { static isValid(node: Node, selectedLocation: Eagle.FileType) : void { const eagle = Eagle.getInstance() - // const errorsWarnings : Errors.ErrorsWarnings = {warnings: [], errors: []}; + node.issues = []//clear old issues // check that node has modern (not legacy) category if (node.getCategory() === Category.Component){ const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has legacy category (" + node.getCategory() + ")", function(){Utils.showNode(eagle, node.getId());}, function(){Utils.fixNodeCategory(eagle, node, Category.PythonApp, Category.Type.Application)}, ""); // errorsWarnings.warnings.push(issue); - node.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + node.issues.push({issue:issue,validity:Errors.Validity.Warning}) } // looping through and checking all the fields on the node @@ -2011,25 +2011,25 @@ export class Node { if (node.getInputPorts().length < cData.minInputs){ const message: string = "Node " + node.getKey() + " (" + node.getName() + ") may have too few input ports. A " + node.getCategory() + " component would typically have at least " + cData.minInputs; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId())}, null, ""); - node.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + node.issues.push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } if ((node.getInputPorts().length - node.getInputEventPorts().length) > cData.maxInputs){ const message: string = "Node " + node.getKey() + " (" + node.getName() + ") has too many input ports. Should have at most " + cData.maxInputs; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId())}, null, ""); - node.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + node.issues.push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } if (node.getOutputPorts().length < cData.minOutputs){ const message: string = "Node " + node.getKey() + " (" + node.getName() + ") may have too few output ports. A " + node.getCategory() + " component would typically have at least " + cData.minOutputs; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId())}, null, ""); - node.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + node.issues.push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } if ((node.getOutputPorts().length - node.getOutputEventPorts().length) > cData.maxOutputs){ const message: string = "Node " + node.getKey() + " (" + node.getName() + ") may have too many output ports. Should have at most " + cData.maxOutputs; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId())}, null, ""); - node.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + node.issues.push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } @@ -2046,7 +2046,7 @@ export class Node { // only check this if the component has been selected in the graph. If it was selected from the palette, it doesn't make sense to complain that it is not connected. if (!isConnected && !(cData.maxInputs === 0 && cData.maxOutputs === 0) && selectedLocation === Eagle.FileType.Graph){ const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has no connected edges. It should be connected to the graph in some way", function(){Utils.showNode(eagle, node.getId())}, null, ""); - node.errorsArray.push({issue:issue,validity:Errors.Validity.Warning}) + node.issues.push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } @@ -2054,19 +2054,19 @@ export class Node { if (node.hasInputApplication() && node.getInputApplication().getCategory() === Category.None){ const issue: Errors.Issue = Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has input application with category 'None'.") // errorsWarnings.errors.push(Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has input application with category 'None'.")); - node.errorsArray.push({issue:issue,validity:Errors.Validity.Error}); + node.issues.push({issue:issue,validity:Errors.Validity.Error}); } if (node.hasOutputApplication() && node.getOutputApplication().getCategory() === Category.None){ const issue : Errors.Issue = Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has output application with category 'None'.") // errorsWarnings.errors.push(Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has output application with category 'None'.")); - node.errorsArray.push({issue:issue,validity:Errors.Validity.Error}); + node.issues.push({issue:issue,validity:Errors.Validity.Error}); } // check that Service nodes have inputApplications with no output ports! if (node.getCategory() === Category.Service && node.hasInputApplication() && node.getInputApplication().getOutputPorts().length > 0){ const issue : Errors.Issue = Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") is a Service node, but has an input application with at least one output.") // errorsWarnings.errors.push(Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") is a Service node, but has an input application with at least one output.")); - node.errorsArray.push({issue:issue,validity:Errors.Validity.Error}); + node.issues.push({issue:issue,validity:Errors.Validity.Error}); } // check that this category of node contains all the fields it requires @@ -2102,13 +2102,13 @@ export class Node { const message = "Node " + node.getKey() + " (" + node.getName() + ":" + node.category() + ":" + node.categoryType() + ") does not have the required '" + field.getDisplayText() + "' field"; const issue : Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId());}, function(){Utils.addMissingRequiredField(eagle, node, field);}, "Add missing " + field.getDisplayText() + " field.") // errorsWarnings.errors.push(Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId());}, function(){Utils.addMissingRequiredField(eagle, node, field);}, "Add missing " + field.getDisplayText() + " field.")); - node.errorsArray.push({issue:issue,validity:Errors.Validity.Error}); + node.issues.push({issue:issue,validity:Errors.Validity.Error}); } else { if (existingField.getParameterType() !== field.getParameterType()){ const message = "Node " + node.getKey() + " (" + node.getName() + ") has a '" + field.getDisplayText() + "' field with the wrong parameter type (" + existingField.getParameterType() + "), should be a " + field.getParameterType(); const issue : Errors.Issue = Errors.ShowFix(message, function(){Utils.showField(eagle, node.getId(),existingField);}, function(){Utils.fixFieldParameterType(eagle, node, existingField, field.getParameterType())}, "Switch type of field to '" + field.getParameterType()) // existingField.addErrorsWarnings(Errors.ShowFix(message, function(){Utils.showField(eagle, node.getId(),existingField);}, function(){Utils.fixFieldParameterType(eagle, node, existingField, field.getParameterType())}, "Switch type of field to '" + field.getParameterType()),'error'); - // node.errorsArray.push({issue:issue,validity:Errors.Validity.Error}); + // node.issues.push({issue:issue,validity:Errors.Validity.Error}); existingField.addError(issue,Errors.Validity.Error) } } diff --git a/src/Utils.ts b/src/Utils.ts index 1d056e24a..b8b3dc18e 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -456,6 +456,7 @@ export class Utils { } static showErrorsModal(title: string){ + //maybe const errors: Errors.Issue[] = Errors.getErrors(); const warnings: Errors.Issue[] = Errors.getWarnings(); @@ -1395,7 +1396,7 @@ export class Utils { // check all nodes are valid for (const node of palette.getNodes()){ Node.isValid(node, Eagle.FileType.Palette); - paletteErrors.push(...node.getErrors()) + paletteErrors.push(...node.getIssues()) // errorsWarnings.errors.push(...nodeErrorsWarnings.errors) // errorsWarnings.warnings.push(...nodeErrorsWarnings.warnings) } @@ -1419,93 +1420,12 @@ export class Utils { // check all nodes are valid for (const node of graph.getNodes()){ Node.isValid(node, Eagle.FileType.Graph); - // errorsWarnings.errors.push(...nodeErrorsWarnings.errors) - // errorsWarnings.warnings.push(...nodeErrorsWarnings.warnings) - - //get the node's field errorswarnings - // for(const field of node.getFields()){ - // errorsWarnings.errors.push(...field.getErrorsWarnings().errors) - // errorsWarnings.warnings.push(...field.getErrorsWarnings().warnings) - // } - - // check the embedded applications - // if (node.hasInputApplication()){ - // const inputNodeErrorsWarnings = Node.isValid(node.getInputApplication(),Eagle.FileType.Graph) - // // errorsWarnings.errors.push(...inputNodeErrorsWarnings.errors) - // // errorsWarnings.warnings.push(...inputNodeErrorsWarnings.warnings) - - // //get the input application's field errorswarnings - // for(const field of node.getInputApplication().getFields()){ - // // errorsWarnings.errors.push(...field.getErrorsWarnings().errors) - // // errorsWarnings.warnings.push(...field.getErrorsWarnings().warnings) - // } - // } - // if (node.hasOutputApplication()){ - // const outputNodeErrorsWarnings = Node.isValid(node.getOutputApplication(),Eagle.FileType.Graph) - // // errorsWarnings.errors.push(...outputNodeErrorsWarnings.errors) - // // errorsWarnings.warnings.push(...outputNodeErrorsWarnings.warnings) - - // //get the output application's field errorswarnings - // for(const field of node.getOutputApplication().getFields()){ - // // errorsWarnings.errors.push(...field.getErrorsWarnings().errors) - // // errorsWarnings.warnings.push(...field.getErrorsWarnings().warnings) - // } - // } } // check all edges are valid for (const edge of graph.getEdges()){ Edge.isValid(eagle,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, false, {warnings: [], errors: []}); } - - // // check that all node, edge, field ids are unique - // { - // const ids : string[] = []; - - // // loop over graph nodes - // for (const node of graph.getNodes()){ - // //check for unique ids - // if (ids.includes(node.getId())){ - // const issue: Errors.Issue = Errors.ShowFix( - // "Node (" + node.getName() + ") does not have a unique id", - // function(){Utils.showNode(eagle, node.getId())}, - // function(){Utils.newId(node)}, - // "Assign node a new id" - // ); - // // errorsWarnings.errors.push(issue); - // } - // ids.push(node.getId()); - - // for (const field of node.getFields()){ - // if (ids.includes(field.getId())){ - // const issue: Errors.Issue = Errors.ShowFix( - // "Field (" + field.getDisplayText() + ") on node (" + node.getName() + ") does not have a unique id", - // function(){Utils.showNode(eagle, node.getId())}, - // function(){Utils.newFieldId(eagle, node, field)}, - // "Assign field a new id" - // ); - // // errorsWarnings.errors.push(issue); - // } - // ids.push(field.getId()); - // } - // } - - // // loop over graph edges - // for (const edge of graph.getEdges()){ - // if (ids.includes(edge.getId())){ - // const issue: Errors.Issue = Errors.ShowFix( - // "Edge (" + edge.getId() + ") does not have a unique id", - // function(){Utils.showEdge(eagle, edge.getId())}, - // function(){Utils.newId(edge)}, - // "Assign edge a new id" - // ); - // // errorsWarnings.errors.push(issue); - // } - // ids.push(edge.getId()); - // } - // } - - // return errorsWarnings; } static gatherGraphErrors(): Errors.ErrorsWarnings { @@ -1517,39 +1437,38 @@ export class Utils { //gather all the errors //from nodes for(const node of graph.getNodes()){ - graphErrors.push(...node.getErrors()) - + graphErrors.push(...node.getIssues()) //fields for( const field of node.getFields()){ - graphErrors.push(...field.getErrors()) + graphErrors.push(...field.getIssues()) } //embedded input applications and their fields if(node.hasInputApplication()){ - graphErrors.push(...node.getInputApplication().getErrors()) + graphErrors.push(...node.getInputApplication().getIssues()) for( const field of node.getInputApplication().getFields()){ - graphErrors.push(...field.getErrors()) + graphErrors.push(...field.getIssues()) } } //embedded output applications and their fields if(node.hasOutputApplication()){ - graphErrors.push(...node.getOutputApplication().getErrors()) + graphErrors.push(...node.getOutputApplication().getIssues()) for( const field of node.getOutputApplication().getFields()){ - graphErrors.push(...field.getErrors()) + graphErrors.push(...field.getIssues()) } } } // from edges for (const edge of graph.getEdges()){ - graphErrors.push(...edge.getErrorsArray()) + graphErrors.push(...edge.getissues()) } //from logical graph - graphErrors.push(...graph.getErrors()) + graphErrors.push(...graph.getIssues()) for(const error of graphErrors){ if(error.validity === Errors.Validity.Error || error.validity === Errors.Validity.Impossible || error.validity === Errors.Validity.Unknown){ From 2a9a80f548a65f1255b6952b99de837a797f2ee4 Mon Sep 17 00:00:00 2001 From: MWicenec Date: Thu, 11 Jul 2024 16:21:25 +0800 Subject: [PATCH 15/17] fixed a major issue with a looping function chekc graph function more reliable --- src/Eagle.ts | 5 +++++ src/Edge.ts | 28 +++++++++++++++++----------- src/Field.ts | 30 ++++++++++++++---------------- src/GraphRenderer.ts | 15 +++++++-------- src/LogicalGraph.ts | 6 +++--- src/Node.ts | 30 ++++++++++++++---------------- src/Utils.ts | 8 ++++---- 7 files changed, 64 insertions(+), 58 deletions(-) diff --git a/src/Eagle.ts b/src/Eagle.ts index dea45148a..41e08b603 100644 --- a/src/Eagle.ts +++ b/src/Eagle.ts @@ -652,6 +652,11 @@ export class Eagle { setSelection = (rightWindowMode : Eagle.RightWindowMode, selection : Node | Edge, selectedLocation: Eagle.FileType) : void => { Eagle.selectedLocation(selectedLocation); GraphRenderer.clearPortPeek() + + // if(selection === null && this.selectedObjects().length === 0){ + // return + // } + if (selection === null){ this.selectedObjects([]); this.rightWindow().mode(rightWindowMode); diff --git a/src/Edge.ts b/src/Edge.ts index 5eafbbb50..ce7db80b7 100644 --- a/src/Edge.ts +++ b/src/Edge.ts @@ -42,7 +42,7 @@ export class Edge { private closesLoop : boolean; // indicates that this is a special type of edge that can be drawn in eagle to specify the start/end of groups. private selectionRelative : boolean // indicates if the edge is either selected or attached to a selected node private isShortEdge : ko.Observable; - private issues : {issue:Errors.Issue, validity:Errors.Validity}[] + private issues : ko.ObservableArray<{issue:Errors.Issue, validity:Errors.Validity}> //keeps track of edge errors constructor(srcNodeKey : number, srcPortId : string, destNodeKey : number, destPortId : string, loopAware: boolean, closesLoop: boolean, selectionRelative : boolean){ this._id = Utils.uuidv4(); @@ -56,7 +56,7 @@ export class Edge { this.closesLoop = closesLoop; this.selectionRelative = selectionRelative; this.isShortEdge = ko.observable(false) - this.issues = []; + this.issues = ko.observableArray([]); } getId = () : string => { @@ -169,16 +169,23 @@ export class Edge { return result; } - getErrorsWarnings = (eagle: Eagle): Errors.ErrorsWarnings => { - const result: {warnings: Errors.Issue[], errors: Errors.Issue[]} = {warnings: [], errors: []}; + getErrorsWarnings = (): Errors.ErrorsWarnings => { + const errorsWarnings : Errors.ErrorsWarnings = {warnings: [], errors: []}; + + this.getIssues().forEach(function(error){ + if(error.validity === Errors.Validity.Error || error.validity === Errors.Validity.Unknown){ + errorsWarnings.errors.push(error.issue) + }else{ + errorsWarnings.warnings.push(error.issue) + } + }) - Edge.isValid(eagle,false, this._id, this.srcNodeKey, this.srcPortId, this.destNodeKey, this.destPortId, this.loopAware, this.closesLoop, false, false, result); + return errorsWarnings; - return result; } - getissues = () : {issue:Errors.Issue, validity:Errors.Validity}[] => { - return this.issues; + getIssues = () : {issue:Errors.Issue, validity:Errors.Validity}[] => { + return this.issues(); } static toOJSJson(edge : Edge) : object { @@ -283,11 +290,10 @@ export class Edge { } static isValid(eagle: Eagle,autoSuggestMode:boolean, edgeId: string, sourceNodeKey : number, sourcePortId : string, destinationNodeKey : number, destinationPortId : string, loopAware: boolean, closesLoop: boolean, showNotification : boolean, showConsole : boolean, errorsWarnings: Errors.ErrorsWarnings) : Errors.Validity { - let impossibleEdge : boolean = false; const edge = eagle.logicalGraph().findEdgeById(edgeId) if(edge){ - edge.issues = [] //clear old issues + edge.issues([]) //clear old issues } // check for problems @@ -532,6 +538,6 @@ export class Edge { if (type === "warning" && errorsWarnings !== null){ errorsWarnings.warnings.push(issue); } - Eagle.getInstance().logicalGraph().findEdgeById(edgeId)?.issues.push({issue:issue, validity:linkValid}) + Eagle.getInstance().logicalGraph().findEdgeById(edgeId)?.issues().push({issue:issue, validity:linkValid}) } } diff --git a/src/Field.ts b/src/Field.ts index 5964df4f9..e3c351af5 100644 --- a/src/Field.ts +++ b/src/Field.ts @@ -41,8 +41,7 @@ export class Field { private inputAngle : number; private outputAngle : number; - private issues : {issue:Errors.Issue, validity:Errors.Validity}[] - // private errorsWarnings : ko.Observable; + private issues : ko.ObservableArray<{issue:Errors.Issue, validity:Errors.Validity}>//keeps track of issues on the field constructor(id: string, displayText: string, value: string, defaultValue: string, description: string, readonly: boolean, type: string, precious: boolean, options: string[], positional: boolean, parameterType: Daliuge.FieldType, usage: Daliuge.FieldUsage, keyAttribute: boolean){ this.displayText = ko.observable(displayText); @@ -74,8 +73,7 @@ export class Field { this.inputAngle = 0; this.outputAngle = 0; - this.issues = []; - // this.errorsWarnings = ko.observable({warnings: [], errors: []}); + this.issues = ko.observableArray([]) } getId = () : string => { @@ -361,11 +359,11 @@ export class Field { }, this); getIssues = (): {issue:Errors.Issue, validity:Errors.Validity}[] => { - return this.issues; + return this.issues(); } addError(issue:Errors.Issue, validity:Errors.Validity){ - this.issues.push({issue:issue,validity:validity}) + this.issues().push({issue:issue,validity:validity}) } getBackgroundColor : ko.PureComputed = ko.pureComputed(() => { @@ -819,7 +817,7 @@ export class Field { static isValid(node:Node, field:Field, selectedLocation:Eagle.FileType, fieldIndex:number){ const eagle = Eagle.getInstance() - field.issues = [] //clear old issues + field.issues([]) //clear old issues //checks for input ports if(field.isInputPort()){ @@ -844,7 +842,7 @@ export class Field { } } - field.issues.push({issue:issue,validity:Errors.Validity.Warning}) + field.issues().push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } @@ -873,7 +871,7 @@ export class Field { issue = Errors.ShowFix("Node " + node.getKey() + " (" + parentNode.getName() + ") has output application (" + node.getName() + ") with output port (" + field.getDisplayText() + ") whose type is not specified", function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixFieldType(eagle, field)}, ""); } } - field.issues.push({issue:issue,validity:Errors.Validity.Warning}) + field.issues().push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } @@ -883,28 +881,28 @@ export class Field { //check that the field has an id if (field.getId() === "" || field.getId() === null){ const issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has field (" + field.getDisplayText() + ") with no id", function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixFieldId(eagle, field)}, "Generate id for field"); - field.issues.push({issue:issue,validity:Errors.Validity.Error}) + field.issues().push({issue:issue,validity:Errors.Validity.Error}) // errorsWarnings.errors.push(issue); } // check that the field has a default value if (field.getDefaultValue() === "" && !field.isType(Daliuge.DataType.String) && !field.isType(Daliuge.DataType.Password) && !field.isType(Daliuge.DataType.Object) && !field.isType(Daliuge.DataType.Unknown)) { const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has a component parameter (" + field.getDisplayText() + ") whose default value is not specified", function(){Utils.showField(eagle, node.getId(),field)}, function(){Utils.fixFieldDefaultValue(eagle, field)}, "Generate default value for parameter"); - field.issues.push({issue:issue,validity:Errors.Validity.Warning}) + field.issues().push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } //chack that the field has a known type if (!Utils.validateType(field.getType())) { const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has a component parameter (" + field.getDisplayText() + ") whose type (" + field.getType() + ") is unknown", function(){Utils.showField(eagle, node.getId(),field)}, function(){Utils.fixFieldType(eagle, field)}, "Prepend existing type (" + field.getType() + ") with 'Object.'"); - field.issues.push({issue:issue,validity:Errors.Validity.Warning}) + field.issues().push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } // check that the fields "key" is the same as the key of the node it belongs to if (field.getNodeKey() !== node.getKey()) { const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has a field (" + field.getDisplayText() + ") whose key (" + field.getNodeKey() + ") doesn't match the node (" + node.getKey() + ")", function(){Utils.showField(eagle, node.getId(),field)}, function(){Utils.fixFieldKey(eagle, node, field)}, "Set field node key correctly"); - field.issues.push({issue:issue,validity:Errors.Validity.Error}) + field.issues().push({issue:issue,validity:Errors.Validity.Error}) // errorsWarnings.errors.push(issue); } @@ -918,11 +916,11 @@ export class Field { if (field.getDisplayText() === field1.getDisplayText() && field.getParameterType() === field1.getParameterType()){ if (field.getId() === field1.getId()){ const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has multiple attributes with the same display text and id (" + field.getDisplayText() + ").", function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixNodeMergeFieldsByIndex(eagle, node, fieldIndex, j)}, "Merge fields"); - field.issues.push({issue:issue,validity:Errors.Validity.Warning}) + field.issues().push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } else { const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has multiple attributes with the same display text (" + field.getDisplayText() + ").", function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixNodeMergeFields(eagle, node, field, field1)}, "Merge fields"); - field.issues.push({issue:issue,validity:Errors.Validity.Warning}) + field.issues().push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } } @@ -954,7 +952,7 @@ export class Field { const message = "Node " + node.getKey() + " (" + node.getName() + ") with category " + node.getCategory() + " contains field (" + field.getDisplayText() + ") with unsuitable type (" + field.getParameterType() + ")."; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixFieldParameterType(eagle, node, field, suitableType)}, "Switch to suitable type, or remove if no suitable type"); - field.issues.push({issue:issue,validity:Errors.Validity.Warning}) + field.issues().push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } } diff --git a/src/GraphRenderer.ts b/src/GraphRenderer.ts index 21fe0c65c..c732f8462 100644 --- a/src/GraphRenderer.ts +++ b/src/GraphRenderer.ts @@ -1122,7 +1122,6 @@ export class GraphRenderer { const oldParent: Node = eagle.logicalGraph().findNodeByKeyQuiet(outerMostNode.getParentKey()); // keep track of whether we would update any node parents - const updated = {parent: false}; const allowGraphEditing = Setting.findValue(Setting.ALLOW_GRAPH_EDITING); //construct resizing if(outerMostNode.getParentKey() != null){ @@ -1140,13 +1139,13 @@ export class GraphRenderer { // if a parent was found, update if (parent !== null && outerMostNode.getParentKey() !== parent.getKey() && outerMostNode.getKey() !== parent.getKey() && !ancestorOfParent && !outerMostNode.isEmbedded()){ - GraphRenderer._updateNodeParent(outerMostNode, parent.getKey(), updated, allowGraphEditing); + GraphRenderer.updateNodeParent(outerMostNode, parent.getKey(), allowGraphEditing); GraphRenderer.NodeParentRadiusPreDrag = eagle.logicalGraph().findNodeByKeyQuiet(parent.getKey()).getRadius() } // if no parent found, update if (parent === null && outerMostNode.getParentKey() !== null && !outerMostNode.isEmbedded()){ - GraphRenderer._updateNodeParent(outerMostNode, null, updated, allowGraphEditing); + GraphRenderer.updateNodeParent(outerMostNode, null, allowGraphEditing); } if (oldParent !== null){ @@ -1594,14 +1593,13 @@ export class GraphRenderer { } // update the parent of the given node - // however, if allGraphEditing is false, then don't update - // always keep track of whether an update would have happened, sp we can warn user - static _updateNodeParent(node: Node, parentKey: number, updated: {parent: boolean}, allowGraphEditing: boolean): void { + // however, if allowGraphEditing is false, then don't update + static updateNodeParent(node: Node, parentKey: number, allowGraphEditing: boolean): void { if (node.getParentKey() !== parentKey){ if (allowGraphEditing){ node.setParentKey(parentKey); + Eagle.getInstance().checkGraph() } - updated.parent = true; } } @@ -2248,7 +2246,8 @@ export class GraphRenderer { } // check if link has a warning or is invalid - const linkValid : Errors.Validity = Edge.isValid(eagle,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, false, {errors:[], warnings:[]}); + // const linkValid : Errors.Validity = Edge.isValid(eagle,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, false, {errors:[], warnings:[]}); + const linkValid : Errors.Validity = Utils.worstEdgeError(edge.getErrorsWarnings()); if (linkValid === Errors.Validity.Error || linkValid === Errors.Validity.Impossible){ normalColor = GraphConfig.getColor('edgeInvalid'); diff --git a/src/LogicalGraph.ts b/src/LogicalGraph.ts index 82d079fb6..b3179a939 100644 --- a/src/LogicalGraph.ts +++ b/src/LogicalGraph.ts @@ -42,14 +42,14 @@ export class LogicalGraph { fileInfo : ko.Observable; private nodes : ko.ObservableArray; private edges : ko.ObservableArray; - private issues : {issue:Errors.Issue, validity:Errors.Validity}[] + private issues : ko.ObservableArray<{issue:Errors.Issue, validity:Errors.Validity}> //keeps track of higher level errors on the graph constructor(){ this.fileInfo = ko.observable(new FileInfo()); this.fileInfo().type = Eagle.FileType.Graph; this.nodes = ko.observableArray([]); this.edges = ko.observableArray([]); - this.issues = [] + this.issues = ko.observableArray([]) } static toOJSJson(graph : LogicalGraph, forTranslation : boolean) : object { @@ -316,7 +316,7 @@ export class LogicalGraph { } getIssues = (): {issue:Errors.Issue, validity:Errors.Validity}[] => { - return this.issues; + return this.issues(); } /** diff --git a/src/Node.ts b/src/Node.ts index e9c7b81a4..5017984e3 100644 --- a/src/Node.ts +++ b/src/Node.ts @@ -63,8 +63,7 @@ export class Node { private paletteDownloadUrl : ko.Observable; private dataHash : ko.Observable; - private issues : {issue:Errors.Issue, validity:Errors.Validity}[] - // private errorsWarnings : ko.Observable; + private issues : ko.ObservableArray<{issue:Errors.Issue, validity:Errors.Validity}>//keeps track of node level errors public static readonly DEFAULT_COLOR : string = "ffffff"; @@ -114,8 +113,7 @@ export class Node { this.paletteDownloadUrl = ko.observable(""); this.dataHash = ko.observable(""); - this.issues = []; - // this.errorsWarnings = ko.observable({warnings: [], errors: []}); + this.issues = ko.observableArray([]); //graph related things this.expanded = ko.observable(true); @@ -1135,7 +1133,7 @@ export class Node { } getIssues = (): {issue:Errors.Issue, validity:Errors.Validity}[] => { - return this.issues; + return this.issues(); } getAllErrors = () : {issue:Errors.Issue, validity:Errors.Validity}[] => { @@ -1978,13 +1976,13 @@ export class Node { static isValid(node: Node, selectedLocation: Eagle.FileType) : void { const eagle = Eagle.getInstance() - node.issues = []//clear old issues + node.issues([])//clear old issues // check that node has modern (not legacy) category if (node.getCategory() === Category.Component){ const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has legacy category (" + node.getCategory() + ")", function(){Utils.showNode(eagle, node.getId());}, function(){Utils.fixNodeCategory(eagle, node, Category.PythonApp, Category.Type.Application)}, ""); // errorsWarnings.warnings.push(issue); - node.issues.push({issue:issue,validity:Errors.Validity.Warning}) + node.issues().push({issue:issue,validity:Errors.Validity.Warning}) } // looping through and checking all the fields on the node @@ -2011,25 +2009,25 @@ export class Node { if (node.getInputPorts().length < cData.minInputs){ const message: string = "Node " + node.getKey() + " (" + node.getName() + ") may have too few input ports. A " + node.getCategory() + " component would typically have at least " + cData.minInputs; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId())}, null, ""); - node.issues.push({issue:issue,validity:Errors.Validity.Warning}) + node.issues().push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } if ((node.getInputPorts().length - node.getInputEventPorts().length) > cData.maxInputs){ const message: string = "Node " + node.getKey() + " (" + node.getName() + ") has too many input ports. Should have at most " + cData.maxInputs; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId())}, null, ""); - node.issues.push({issue:issue,validity:Errors.Validity.Warning}) + node.issues().push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } if (node.getOutputPorts().length < cData.minOutputs){ const message: string = "Node " + node.getKey() + " (" + node.getName() + ") may have too few output ports. A " + node.getCategory() + " component would typically have at least " + cData.minOutputs; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId())}, null, ""); - node.issues.push({issue:issue,validity:Errors.Validity.Warning}) + node.issues().push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } if ((node.getOutputPorts().length - node.getOutputEventPorts().length) > cData.maxOutputs){ const message: string = "Node " + node.getKey() + " (" + node.getName() + ") may have too many output ports. Should have at most " + cData.maxOutputs; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId())}, null, ""); - node.issues.push({issue:issue,validity:Errors.Validity.Warning}) + node.issues().push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } @@ -2046,7 +2044,7 @@ export class Node { // only check this if the component has been selected in the graph. If it was selected from the palette, it doesn't make sense to complain that it is not connected. if (!isConnected && !(cData.maxInputs === 0 && cData.maxOutputs === 0) && selectedLocation === Eagle.FileType.Graph){ const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has no connected edges. It should be connected to the graph in some way", function(){Utils.showNode(eagle, node.getId())}, null, ""); - node.issues.push({issue:issue,validity:Errors.Validity.Warning}) + node.issues().push({issue:issue,validity:Errors.Validity.Warning}) // errorsWarnings.warnings.push(issue); } @@ -2054,19 +2052,19 @@ export class Node { if (node.hasInputApplication() && node.getInputApplication().getCategory() === Category.None){ const issue: Errors.Issue = Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has input application with category 'None'.") // errorsWarnings.errors.push(Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has input application with category 'None'.")); - node.issues.push({issue:issue,validity:Errors.Validity.Error}); + node.issues().push({issue:issue,validity:Errors.Validity.Error}); } if (node.hasOutputApplication() && node.getOutputApplication().getCategory() === Category.None){ const issue : Errors.Issue = Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has output application with category 'None'.") // errorsWarnings.errors.push(Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has output application with category 'None'.")); - node.issues.push({issue:issue,validity:Errors.Validity.Error}); + node.issues().push({issue:issue,validity:Errors.Validity.Error}); } // check that Service nodes have inputApplications with no output ports! if (node.getCategory() === Category.Service && node.hasInputApplication() && node.getInputApplication().getOutputPorts().length > 0){ const issue : Errors.Issue = Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") is a Service node, but has an input application with at least one output.") // errorsWarnings.errors.push(Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") is a Service node, but has an input application with at least one output.")); - node.issues.push({issue:issue,validity:Errors.Validity.Error}); + node.issues().push({issue:issue,validity:Errors.Validity.Error}); } // check that this category of node contains all the fields it requires @@ -2102,7 +2100,7 @@ export class Node { const message = "Node " + node.getKey() + " (" + node.getName() + ":" + node.category() + ":" + node.categoryType() + ") does not have the required '" + field.getDisplayText() + "' field"; const issue : Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId());}, function(){Utils.addMissingRequiredField(eagle, node, field);}, "Add missing " + field.getDisplayText() + " field.") // errorsWarnings.errors.push(Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId());}, function(){Utils.addMissingRequiredField(eagle, node, field);}, "Add missing " + field.getDisplayText() + " field.")); - node.issues.push({issue:issue,validity:Errors.Validity.Error}); + node.issues().push({issue:issue,validity:Errors.Validity.Error}); } else { if (existingField.getParameterType() !== field.getParameterType()){ const message = "Node " + node.getKey() + " (" + node.getName() + ") has a '" + field.getDisplayText() + "' field with the wrong parameter type (" + existingField.getParameterType() + "), should be a " + field.getParameterType(); diff --git a/src/Utils.ts b/src/Utils.ts index b8b3dc18e..39a691380 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -1413,8 +1413,6 @@ export class Utils { } static checkGraph(eagle: Eagle): void { - // const errorsWarnings: Errors.ErrorsWarnings = {warnings: [], errors: []}; - const graph: LogicalGraph = eagle.logicalGraph(); // check all nodes are valid @@ -1438,7 +1436,8 @@ export class Utils { //from nodes for(const node of graph.getNodes()){ graphErrors.push(...node.getIssues()) - //fields + + //from fields for( const field of node.getFields()){ graphErrors.push(...field.getIssues()) } @@ -1464,12 +1463,13 @@ export class Utils { // from edges for (const edge of graph.getEdges()){ - graphErrors.push(...edge.getissues()) + graphErrors.push(...edge.getIssues()) } //from logical graph graphErrors.push(...graph.getIssues()) + //sort all issues into warnings or errors for(const error of graphErrors){ if(error.validity === Errors.Validity.Error || error.validity === Errors.Validity.Impossible || error.validity === Errors.Validity.Unknown){ errorsWarnings.errors.push(error.issue) From 4040c9e1577121a7ebe362de7f8e0dabf26afb01 Mon Sep 17 00:00:00 2001 From: M-Wicenec Date: Fri, 12 Jul 2024 16:10:56 +0800 Subject: [PATCH 16/17] code clean up and sourcery ai chagnes --- src/Eagle.ts | 4 ---- src/GraphRenderer.ts | 8 +++----- src/Node.ts | 26 ++++---------------------- src/Utils.ts | 27 +++++++++++++-------------- 4 files changed, 20 insertions(+), 45 deletions(-) diff --git a/src/Eagle.ts b/src/Eagle.ts index 0ed749f9d..8f7541157 100644 --- a/src/Eagle.ts +++ b/src/Eagle.ts @@ -653,10 +653,6 @@ export class Eagle { Eagle.selectedLocation(selectedLocation); GraphRenderer.clearPortPeek() - // if(selection === null && this.selectedObjects().length === 0){ - // return - // } - if (selection === null){ this.selectedObjects([]); this.rightWindow().mode(rightWindowMode); diff --git a/src/GraphRenderer.ts b/src/GraphRenderer.ts index bb0dde239..4a8963c22 100644 --- a/src/GraphRenderer.ts +++ b/src/GraphRenderer.ts @@ -1580,11 +1580,9 @@ export class GraphRenderer { // update the parent of the given node // however, if allowGraphEditing is false, then don't update static updateNodeParent(node: Node, parentKey: number, allowGraphEditing: boolean): void { - if (node.getParentKey() !== parentKey){ - if (allowGraphEditing){ - node.setParentKey(parentKey); - Eagle.getInstance().checkGraph() - } + if (node.getParentKey() !== parentKey && allowGraphEditing){ + node.setParentKey(parentKey); + Eagle.getInstance().checkGraph() } } diff --git a/src/Node.ts b/src/Node.ts index ef6dc44f0..c3d6847eb 100644 --- a/src/Node.ts +++ b/src/Node.ts @@ -1980,7 +1980,6 @@ export class Node { // check that node has modern (not legacy) category if (node.getCategory() === Category.Component){ const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has legacy category (" + node.getCategory() + ")", function(){Utils.showNode(eagle, node.getId());}, function(){Utils.fixNodeCategory(eagle, node, Category.PythonApp, Category.Type.Application)}, ""); - // errorsWarnings.warnings.push(issue); node.issues().push({issue:issue,validity:Errors.Validity.Warning}) } @@ -2009,25 +2008,21 @@ export class Node { const message: string = "Node " + node.getKey() + " (" + node.getName() + ") may have too few input ports. A " + node.getCategory() + " component would typically have at least " + cData.minInputs; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId())}, null, ""); node.issues().push({issue:issue,validity:Errors.Validity.Warning}) - // errorsWarnings.warnings.push(issue); } if ((node.getInputPorts().length - node.getInputEventPorts().length) > cData.maxInputs){ const message: string = "Node " + node.getKey() + " (" + node.getName() + ") has too many input ports. Should have at most " + cData.maxInputs; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId())}, null, ""); node.issues().push({issue:issue,validity:Errors.Validity.Warning}) - // errorsWarnings.warnings.push(issue); } if (node.getOutputPorts().length < cData.minOutputs){ const message: string = "Node " + node.getKey() + " (" + node.getName() + ") may have too few output ports. A " + node.getCategory() + " component would typically have at least " + cData.minOutputs; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId())}, null, ""); node.issues().push({issue:issue,validity:Errors.Validity.Warning}) - // errorsWarnings.warnings.push(issue); } if ((node.getOutputPorts().length - node.getOutputEventPorts().length) > cData.maxOutputs){ const message: string = "Node " + node.getKey() + " (" + node.getName() + ") may have too many output ports. Should have at most " + cData.maxOutputs; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId())}, null, ""); node.issues().push({issue:issue,validity:Errors.Validity.Warning}) - // errorsWarnings.warnings.push(issue); } // check that all nodes should have at least one connected edge, otherwise what purpose do they serve? @@ -2044,25 +2039,21 @@ export class Node { if (!isConnected && !(cData.maxInputs === 0 && cData.maxOutputs === 0) && selectedLocation === Eagle.FileType.Graph){ const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has no connected edges. It should be connected to the graph in some way", function(){Utils.showNode(eagle, node.getId())}, null, ""); node.issues().push({issue:issue,validity:Errors.Validity.Warning}) - // errorsWarnings.warnings.push(issue); } // check embedded application categories are not 'None' if (node.hasInputApplication() && node.getInputApplication().getCategory() === Category.None){ const issue: Errors.Issue = Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has input application with category 'None'.") - // errorsWarnings.errors.push(Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has input application with category 'None'.")); node.issues().push({issue:issue,validity:Errors.Validity.Error}); } if (node.hasOutputApplication() && node.getOutputApplication().getCategory() === Category.None){ const issue : Errors.Issue = Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has output application with category 'None'.") - // errorsWarnings.errors.push(Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") has output application with category 'None'.")); node.issues().push({issue:issue,validity:Errors.Validity.Error}); } // check that Service nodes have inputApplications with no output ports! if (node.getCategory() === Category.Service && node.hasInputApplication() && node.getInputApplication().getOutputPorts().length > 0){ const issue : Errors.Issue = Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") is a Service node, but has an input application with at least one output.") - // errorsWarnings.errors.push(Errors.Message("Node " + node.getKey() + " (" + node.getName() + ") is a Service node, but has an input application with at least one output.")); node.issues().push({issue:issue,validity:Errors.Validity.Error}); } @@ -2083,10 +2074,6 @@ export class Node { } } } - - // node.errorsWarnings(errorsWarnings) - - // return errorsWarnings } private static _checkForField(eagle: Eagle, node: Node, field: Field) : void { @@ -2098,16 +2085,11 @@ export class Node { if (existingField === null){ const message = "Node " + node.getKey() + " (" + node.getName() + ":" + node.category() + ":" + node.categoryType() + ") does not have the required '" + field.getDisplayText() + "' field"; const issue : Errors.Issue = Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId());}, function(){Utils.addMissingRequiredField(eagle, node, field);}, "Add missing " + field.getDisplayText() + " field.") - // errorsWarnings.errors.push(Errors.ShowFix(message, function(){Utils.showNode(eagle, node.getId());}, function(){Utils.addMissingRequiredField(eagle, node, field);}, "Add missing " + field.getDisplayText() + " field.")); node.issues().push({issue:issue,validity:Errors.Validity.Error}); - } else { - if (existingField.getParameterType() !== field.getParameterType()){ - const message = "Node " + node.getKey() + " (" + node.getName() + ") has a '" + field.getDisplayText() + "' field with the wrong parameter type (" + existingField.getParameterType() + "), should be a " + field.getParameterType(); - const issue : Errors.Issue = Errors.ShowFix(message, function(){Utils.showField(eagle, node.getId(),existingField);}, function(){Utils.fixFieldParameterType(eagle, node, existingField, field.getParameterType())}, "Switch type of field to '" + field.getParameterType()) - // existingField.addErrorsWarnings(Errors.ShowFix(message, function(){Utils.showField(eagle, node.getId(),existingField);}, function(){Utils.fixFieldParameterType(eagle, node, existingField, field.getParameterType())}, "Switch type of field to '" + field.getParameterType()),'error'); - // node.issues.push({issue:issue,validity:Errors.Validity.Error}); - existingField.addError(issue,Errors.Validity.Error) - } + } else if (existingField.getParameterType() !== field.getParameterType()){ + const message = "Node " + node.getKey() + " (" + node.getName() + ") has a '" + field.getDisplayText() + "' field with the wrong parameter type (" + existingField.getParameterType() + "), should be a " + field.getParameterType(); + const issue : Errors.Issue = Errors.ShowFix(message, function(){Utils.showField(eagle, node.getId(),existingField);}, function(){Utils.fixFieldParameterType(eagle, node, existingField, field.getParameterType())}, "Switch type of field to '" + field.getParameterType()) + existingField.addError(issue,Errors.Validity.Error) } } } diff --git a/src/Utils.ts b/src/Utils.ts index 39a691380..3f8c1da3e 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -456,7 +456,6 @@ export class Utils { } static showErrorsModal(title: string){ - //maybe const errors: Errors.Issue[] = Errors.getErrors(); const warnings: Errors.Issue[] = Errors.getWarnings(); @@ -1380,7 +1379,7 @@ export class Utils { static checkPalette(palette: Palette): Errors.ErrorsWarnings { const errorsWarnings: Errors.ErrorsWarnings = {warnings: [], errors: []}; - const paletteErrors : {issue:Errors.Issue, validity:Errors.Validity}[]=[] + const paletteIssues : {issue:Errors.Issue, validity:Errors.Validity}[]=[] // check for duplicate keys const keys: number[] = []; @@ -1396,12 +1395,12 @@ export class Utils { // check all nodes are valid for (const node of palette.getNodes()){ Node.isValid(node, Eagle.FileType.Palette); - paletteErrors.push(...node.getIssues()) + paletteIssues.push(...node.getIssues()) // errorsWarnings.errors.push(...nodeErrorsWarnings.errors) // errorsWarnings.warnings.push(...nodeErrorsWarnings.warnings) } - for(const error of paletteErrors){ + for(const error of paletteIssues){ if(error.validity === Errors.Validity.Error){ errorsWarnings.errors.push(error.issue) }else{ @@ -1429,48 +1428,48 @@ export class Utils { static gatherGraphErrors(): Errors.ErrorsWarnings { const eagle = Eagle.getInstance() const errorsWarnings: Errors.ErrorsWarnings = {warnings: [], errors: []}; - const graphErrors : {issue:Errors.Issue, validity:Errors.Validity}[] = [] + const graphIssues : {issue:Errors.Issue, validity:Errors.Validity}[] = [] const graph : LogicalGraph = eagle.logicalGraph() //gather all the errors //from nodes for(const node of graph.getNodes()){ - graphErrors.push(...node.getIssues()) + graphIssues.push(...node.getIssues()) //from fields for( const field of node.getFields()){ - graphErrors.push(...field.getIssues()) + graphIssues.push(...field.getIssues()) } //embedded input applications and their fields if(node.hasInputApplication()){ - graphErrors.push(...node.getInputApplication().getIssues()) + graphIssues.push(...node.getInputApplication().getIssues()) for( const field of node.getInputApplication().getFields()){ - graphErrors.push(...field.getIssues()) + graphIssues.push(...field.getIssues()) } } //embedded output applications and their fields if(node.hasOutputApplication()){ - graphErrors.push(...node.getOutputApplication().getIssues()) + graphIssues.push(...node.getOutputApplication().getIssues()) for( const field of node.getOutputApplication().getFields()){ - graphErrors.push(...field.getIssues()) + graphIssues.push(...field.getIssues()) } } } // from edges for (const edge of graph.getEdges()){ - graphErrors.push(...edge.getIssues()) + graphIssues.push(...edge.getIssues()) } //from logical graph - graphErrors.push(...graph.getIssues()) + graphIssues.push(...graph.getIssues()) //sort all issues into warnings or errors - for(const error of graphErrors){ + for(const error of graphIssues){ if(error.validity === Errors.Validity.Error || error.validity === Errors.Validity.Impossible || error.validity === Errors.Validity.Unknown){ errorsWarnings.errors.push(error.issue) }else{ From cf32f2bcd2ca3de99c146f6bdeea535c61936942 Mon Sep 17 00:00:00 2001 From: M-Wicenec Date: Mon, 15 Jul 2024 13:53:37 +0800 Subject: [PATCH 17/17] fixed a few small changes requested by james --- src/Eagle.ts | 4 ++-- src/Edge.ts | 54 ++++++++++++++++++++++---------------------- src/Field.ts | 12 ---------- src/GraphRenderer.ts | 8 +++---- src/Utils.ts | 2 +- 5 files changed, 34 insertions(+), 46 deletions(-) diff --git a/src/Eagle.ts b/src/Eagle.ts index 8f7541157..6f0737667 100644 --- a/src/Eagle.ts +++ b/src/Eagle.ts @@ -2853,7 +2853,7 @@ export class Eagle { } // validate edge - const isValid: Errors.Validity = Edge.isValid(this,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, true, null); + const isValid: Errors.Validity = Edge.isValid(this, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, true, null); if (isValid === Errors.Validity.Impossible || isValid === Errors.Validity.Error || isValid === Errors.Validity.Unknown){ Utils.showUserMessage("Error", "Invalid edge"); return; @@ -2898,7 +2898,7 @@ export class Eagle { } // validate edge - const isValid: Errors.Validity = Edge.isValid(this,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, true, null); + const isValid: Errors.Validity = Edge.isValid(this, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, true, null); if (isValid === Errors.Validity.Impossible || isValid === Errors.Validity.Error || isValid === Errors.Validity.Unknown){ Utils.showUserMessage("Error", "Invalid edge"); return; diff --git a/src/Edge.ts b/src/Edge.ts index ce7db80b7..a02c3525c 100644 --- a/src/Edge.ts +++ b/src/Edge.ts @@ -289,7 +289,7 @@ export class Edge { return new Edge(edgeData.from, edgeData.fromPort, edgeData.to, edgeData.toPort, edgeData.loopAware, edgeData.closesLoop, false); } - static isValid(eagle: Eagle,autoSuggestMode:boolean, edgeId: string, sourceNodeKey : number, sourcePortId : string, destinationNodeKey : number, destinationPortId : string, loopAware: boolean, closesLoop: boolean, showNotification : boolean, showConsole : boolean, errorsWarnings: Errors.ErrorsWarnings) : Errors.Validity { + static isValid(eagle: Eagle, edgeId: string, sourceNodeKey : number, sourcePortId : string, destinationNodeKey : number, destinationPortId : string, loopAware: boolean, closesLoop: boolean, showNotification : boolean, showConsole : boolean, errorsWarnings: Errors.ErrorsWarnings) : Errors.Validity { let impossibleEdge : boolean = false; const edge = eagle.logicalGraph().findEdgeById(edgeId) if(edge){ @@ -307,25 +307,25 @@ export class Edge { if (sourcePortId === ""){ const issue = Errors.Fix("source port has no id", function(){Utils.fixNodeFieldIds(eagle, sourceNodeKey)}, "Generate ids for ports on source node"); - Edge.isValidLog(edgeId, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); return Errors.Validity.Impossible; } if (destinationPortId === ""){ const issue = Errors.Fix("destination port has no id", function(){Utils.fixNodeFieldIds(eagle, sourceNodeKey)}, "Generate ids for ports on destination node"); - Edge.isValidLog(edgeId, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); return Errors.Validity.Impossible; } if (sourcePortId === null){ const issue = Errors.Fix("source port id is null", function(){Utils.fixNodeFieldIds(eagle, sourceNodeKey)}, "Generate ids for ports on source node"); - Edge.isValidLog(edgeId, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); return Errors.Validity.Impossible; } if (destinationPortId === null){ const issue = Errors.Fix("destination port id is null", function(){Utils.fixNodeFieldIds(eagle, sourceNodeKey)}, "Generate ids for ports on destination node"); - Edge.isValidLog(edgeId, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); return Errors.Validity.Impossible; } @@ -339,18 +339,18 @@ export class Edge { // check that we are not connecting a Data component to a Data component, that is not supported if (sourceNode.getCategoryType() === Category.Type.Data && destinationNode.getCategoryType() === Category.Type.Data){ - Edge.isValidLog(edgeId, Errors.Validity.Error, Errors.Show("Data nodes may not be connected directly to other Data nodes", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Error, Errors.Show("Data nodes may not be connected directly to other Data nodes", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); } // if source node or destination node is a construct, then something is wrong, constructs should not have ports if (sourceNode.getCategoryType() === Category.Type.Construct){ const issue: Errors.Issue = Errors.ShowFix("Edge (" + edgeId + ") cannot have a source node (" + sourceNode.getName() + ") that is a construct", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.fixMoveEdgeToEmbeddedApplication(eagle, edgeId)}, "Move edge to embedded application"); - Edge.isValidLog(edgeId, Errors.Validity.Error, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Error, issue, showNotification, showConsole, errorsWarnings); } if (destinationNode.getCategoryType() === Category.Type.Construct){ const issue: Errors.Issue = Errors.ShowFix("Edge (" + edgeId + ") cannot have a destination node (" + destinationNode.getName() + ") that is a construct", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.fixMoveEdgeToEmbeddedApplication(eagle, edgeId)}, "Move edge to embedded application"); - Edge.isValidLog(edgeId, Errors.Validity.Error, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Error, issue, showNotification, showConsole, errorsWarnings); } // if source node is a memory, and destination is a BashShellApp, OR @@ -359,7 +359,7 @@ export class Edge { if ((sourceNode.getCategory() === Category.Memory && destinationNode.getCategory() === Category.BashShellApp) || (sourceNode.getCategory() === Category.Memory && destinationNode.isGroup() && destinationNode.getInputApplication() !== undefined && destinationNode.hasInputApplication() && destinationNode.getInputApplication().getCategory() === Category.BashShellApp)){ const issue: Errors.Issue = Errors.ShowFix("output from Memory Node cannot be input into a BashShellApp or input into a Group Node with a BashShellApp inputApplicationType", function(){Utils.showNode(eagle, sourceNode.getId())}, function(){Utils.fixNodeCategory(eagle, sourceNode, Category.File, Category.Type.Data)}, "Change data component type to File"); - Edge.isValidLog(edgeId, Errors.Validity.Error, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Error, issue, showNotification, showConsole, errorsWarnings); } const sourcePort : Field = sourceNode.findFieldById(sourcePortId); @@ -368,41 +368,41 @@ export class Edge { // check if source port was found if (sourcePort === null) { const issue: Errors.Issue = Errors.ShowFix("Source port (" + sourcePortId + ") doesn't exist on source node (" + sourceNode.getName() + ")", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.addSourcePortToSourceNode(eagle, edgeId)}, "Add source port to source node"); - Edge.isValidLog(edgeId, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); impossibleEdge = true; } // check if destination port was found if (destinationPort === null){ const issue: Errors.Issue = Errors.ShowFix("Destination port (" + destinationPortId + ") doesn't exist on destination node (" + destinationNode.getName() + ")", function(){Utils.showEdge(eagle, edgeId)}, function(){Utils.addDestinationPortToDestinationNode(eagle, edgeId)}, "Add destination port to destination node"); - Edge.isValidLog(edgeId, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); impossibleEdge = true; } // check that we are not connecting a port to itself if (sourceNodeKey === destinationNodeKey){ - Edge.isValidLog(edgeId, Errors.Validity.Impossible, Errors.Show("Source port and destination port are the same", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Impossible, Errors.Show("Source port and destination port are the same", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); impossibleEdge = true; } // check that source is output if (!sourcePort.isOutputPort()){ const issue: Errors.Issue = Errors.ShowFix("Source port is not output port (" + sourcePort.getUsage() + ")", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixFieldUsage(eagle, sourcePort, Daliuge.FieldUsage.OutputPort)}, "Add output usage to source port"); - Edge.isValidLog(edgeId, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); impossibleEdge = true; } // check that destination in input if (!destinationPort.isInputPort()){ const issue: Errors.Issue = Errors.ShowFix("Destination port is not input port (" + destinationPort.getUsage() + ")", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixFieldUsage(eagle, destinationPort, Daliuge.FieldUsage.InputPort)}, "Add input usage to destination port"); - Edge.isValidLog(edgeId, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Impossible, issue, showNotification, showConsole, errorsWarnings); impossibleEdge = true; } if (sourcePort !== null && destinationPort !== null){ // check that source and destination port are both event, or both not event if ((sourcePort.getIsEvent() && !destinationPort.getIsEvent()) || (!sourcePort.getIsEvent() && destinationPort.getIsEvent())){ - Edge.isValidLog(edgeId, Errors.Validity.Error, Errors.Show("Source port and destination port are mix of event and non-event ports", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Error, Errors.Show("Source port and destination port are mix of event and non-event ports", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); } } @@ -432,7 +432,7 @@ export class Edge { // abort if source port and destination port have different data types if (!Utils.portsMatch(sourcePort, destinationPort)){ const x = Errors.ShowFix("Source and destination ports don't match data types: sourcePort (" + sourcePort.getDisplayText() + ":" + sourcePort.getType() + ") destinationPort (" + destinationPort.getDisplayText() + ":" + destinationPort.getType() + ")", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixPortType(eagle, sourcePort, destinationPort);}, "Overwrite destination port type with source port type"); - Edge.isValidLog(edgeId, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); } } @@ -445,12 +445,12 @@ export class Edge { || associatedConstructType !== Category.Loop && loopAware ){ const x = Errors.ShowFix("An edge between two siblings should not be loop aware", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixDisableEdgeLoopAware(eagle, edgeId);}, "Disable loop aware on the edge."); - Edge.isValidLog(edgeId, Errors.Validity.Warning, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Warning, x, showNotification, showConsole, errorsWarnings); } // if link is not a parent, child or sibling, then warn user if (associatedConstructType !== Category.ExclusiveForceNode && associatedConstructType !== Category.Loop && !isSibling && !isParentOfConstruct && !isChildOfConstruct && !destPortIsEmbeddedAppOfSibling && !srcPortIsEmbeddedAppOfSibling){ - Edge.isValidLog(edgeId, Errors.Validity.Warning, Errors.Show("Edge is not between siblings, or between a child and its parent's embedded Application. It could be incorrect or computationally expensive", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Warning, Errors.Show("Edge is not between siblings, or between a child and its parent's embedded Application. It could be incorrect or computationally expensive", function(){Utils.showEdge(eagle, edgeId);}), showNotification, showConsole, errorsWarnings); } // check if the edge already exists in the graph, there is no point in a duplicate @@ -460,7 +460,7 @@ export class Edge { if ( isSrcMatch && isDestMatch && edge.getId() !== edgeId){ const x = Errors.ShowFix("Edge is a duplicate. Another edge with the same source port and destination port already exists", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixDeleteEdge(eagle, edgeId);}, "Delete edge"); - Edge.isValidLog(edgeId, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); } } @@ -472,22 +472,22 @@ export class Edge { if (closesLoop){ if (!sourceNode.isData()){ const x = Errors.Show("Closes Loop Edge (" + edgeId + ") does not start from a Data component.", function(){Utils.showEdge(eagle, edgeId);}); - Edge.isValidLog(edgeId, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); } if (!destinationNode.isApplication()){ const x = Errors.Show("Closes Loop Edge (" + edgeId + ") does not end at an Application component.", function(){Utils.showEdge(eagle, edgeId);}); - Edge.isValidLog(edgeId, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); } if (!sourceNode.hasFieldWithDisplayText(Daliuge.FieldName.GROUP_END) || !Utils.asBool(sourceNode.getFieldByDisplayText(Daliuge.FieldName.GROUP_END).getValue())){ const x = Errors.ShowFix("'Closes Loop' Edge (" + edgeId + ") start node (" + sourceNode.getName() + ") does not have 'group_end' set to true.", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixFieldValue(eagle, sourceNode, Daliuge.groupEndField, "true")}, "Set 'group_end' to true"); - Edge.isValidLog(edgeId, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); } if (!destinationNode.hasFieldWithDisplayText(Daliuge.FieldName.GROUP_START) || !Utils.asBool(destinationNode.getFieldByDisplayText(Daliuge.FieldName.GROUP_START).getValue())){ const x = Errors.ShowFix("'Closes Loop' Edge (" + edgeId + ") end node (" + destinationNode.getName() + ") does not have 'group_start' set to true.", function(){Utils.showEdge(eagle, edgeId);}, function(){Utils.fixFieldValue(eagle, destinationNode, Daliuge.groupStartField, "true")}, "Set 'group_start' to true"); - Edge.isValidLog(edgeId, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); + Edge.isValidLog(edge, Errors.Validity.Error, x, showNotification, showConsole, errorsWarnings); } } @@ -499,7 +499,7 @@ export class Edge { } } - private static isValidLog(edgeId : string, linkValid : Errors.Validity, issue: Errors.Issue, showNotification : boolean, showConsole : boolean, errorsWarnings: Errors.ErrorsWarnings) : void { + private static isValidLog(edge : Edge, linkValid : Errors.Validity, issue: Errors.Issue, showNotification : boolean, showConsole : boolean, errorsWarnings: Errors.ErrorsWarnings) : void { // determine correct title let title = "Edge Valid"; let type : "success" | "info" | "warning" | "danger" = "success"; @@ -521,8 +521,8 @@ export class Edge { } // add edge id to message, if id is known - if (edgeId !== null){ - message = "Edge (" + edgeId + ") " + issue.message; + if (edge !== null){ + message = "Edge (" + edge.getId() + ") " + issue.message; } else { message = issue.message; } @@ -538,6 +538,6 @@ export class Edge { if (type === "warning" && errorsWarnings !== null){ errorsWarnings.warnings.push(issue); } - Eagle.getInstance().logicalGraph().findEdgeById(edgeId)?.issues().push({issue:issue, validity:linkValid}) + edge.issues().push({issue:issue, validity:linkValid}) } } diff --git a/src/Field.ts b/src/Field.ts index c15bda368..cd69e57d0 100644 --- a/src/Field.ts +++ b/src/Field.ts @@ -841,9 +841,7 @@ export class Field { issue = Errors.ShowFix("Node " + node.getKey() + " (" + parentNode.getName() + ") has output application (" + node.getName() + ") with input port (" + field.getDisplayText() + ") whose type is not specified", function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixFieldType(eagle, field)}, ""); } } - field.issues().push({issue:issue,validity:Errors.Validity.Warning}) - // errorsWarnings.warnings.push(issue); } @@ -872,7 +870,6 @@ export class Field { } } field.issues().push({issue:issue,validity:Errors.Validity.Warning}) - // errorsWarnings.warnings.push(issue); } @@ -882,28 +879,24 @@ export class Field { if (field.getId() === "" || field.getId() === null){ const issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has field (" + field.getDisplayText() + ") with no id", function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixFieldId(eagle, field)}, "Generate id for field"); field.issues().push({issue:issue,validity:Errors.Validity.Error}) - // errorsWarnings.errors.push(issue); } // check that the field has a default value if (field.getDefaultValue() === "" && !field.isType(Daliuge.DataType.String) && !field.isType(Daliuge.DataType.Password) && !field.isType(Daliuge.DataType.Object) && !field.isType(Daliuge.DataType.Unknown)) { const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has a component parameter (" + field.getDisplayText() + ") whose default value is not specified", function(){Utils.showField(eagle, node.getId(),field)}, function(){Utils.fixFieldDefaultValue(eagle, field)}, "Generate default value for parameter"); field.issues().push({issue:issue,validity:Errors.Validity.Warning}) - // errorsWarnings.warnings.push(issue); } // check that the field has a known type if (!Utils.validateType(field.getType())) { const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has a component parameter (" + field.getDisplayText() + ") whose type (" + field.getType() + ") is unknown", function(){Utils.showField(eagle, node.getId(),field)}, function(){Utils.fixFieldType(eagle, field)}, "Prepend existing type (" + field.getType() + ") with 'Object.'"); field.issues().push({issue:issue,validity:Errors.Validity.Warning}) - // errorsWarnings.warnings.push(issue); } // check that the fields "key" is the same as the key of the node it belongs to if (field.getNodeKey() !== node.getKey()) { const issue: Errors.Issue = Errors.ShowFix("Node " + node.getKey() + " (" + node.getName() + ") has a field (" + field.getDisplayText() + ") whose key (" + field.getNodeKey() + ") doesn't match the node (" + node.getKey() + ")", function(){Utils.showField(eagle, node.getId(),field)}, function(){Utils.fixFieldKey(eagle, node, field)}, "Set field node key correctly"); field.issues().push({issue:issue,validity:Errors.Validity.Error}) - // errorsWarnings.errors.push(issue); } // check that the field has a unique display text on the node @@ -968,13 +961,8 @@ export class Field { const message = "Node " + node.getKey() + " (" + node.getName() + ") with category " + node.getCategory() + " contains field (" + field.getDisplayText() + ") with unsuitable type (" + field.getParameterType() + ")."; const issue: Errors.Issue = Errors.ShowFix(message, function(){Utils.showField(eagle, node.getId(),field);}, function(){Utils.fixFieldParameterType(eagle, node, field, suitableType)}, "Switch to suitable type, or remove if no suitable type"); field.issues().push({issue:issue,validity:Errors.Validity.Warning}) - // errorsWarnings.warnings.push(issue); } } - - // field.errorsWarnings(errorsWarnings) - - // return errorsWarnings } public static sortFunc(a: Field, b: Field) : number { diff --git a/src/GraphRenderer.ts b/src/GraphRenderer.ts index 4a8963c22..79a22b92c 100644 --- a/src/GraphRenderer.ts +++ b/src/GraphRenderer.ts @@ -1744,7 +1744,7 @@ export class GraphRenderer { } // check if link is valid - const linkValid : Errors.Validity = Edge.isValid(eagle,false, null, realSourceNode.getKey(), realSourcePort.getId(), realDestinationNode.getKey(), realDestinationPort.getId(), false, false, true, true, {errors:[], warnings:[]}); + const linkValid : Errors.Validity = Edge.isValid(eagle, null, realSourceNode.getKey(), realSourcePort.getId(), realDestinationNode.getKey(), realDestinationPort.getId(), false, false, true, true, {errors:[], warnings:[]}); // abort if edge is invalid if ((Setting.findValue(Setting.ALLOW_INVALID_EDGES) && linkValid === Errors.Validity.Error) || linkValid === Errors.Validity.Valid || linkValid === Errors.Validity.Warning){ @@ -2022,9 +2022,9 @@ export class GraphRenderer { for (const port of node.getPorts()){ let isValid: Errors.Validity if(!GraphRenderer.portDragSourcePortIsInput){ - isValid = Edge.isValid(eagle,true, "", sourceNode.getKey(), sourcePort.getId(), node.getKey(), port.getId(), false, false, false, false, {errors:[], warnings:[]}); + isValid = Edge.isValid(eagle, "", sourceNode.getKey(), sourcePort.getId(), node.getKey(), port.getId(), false, false, false, false, {errors:[], warnings:[]}); }else{ - isValid = Edge.isValid(eagle,true, "", node.getKey(), port.getId(), sourceNode.getKey(), sourcePort.getId(), false, false, false, false, {errors:[], warnings:[]}); + isValid = Edge.isValid(eagle, "", node.getKey(), port.getId(), sourceNode.getKey(), sourcePort.getId(), false, false, false, false, {errors:[], warnings:[]}); } const isValidIndex: number = Object.values(Errors.Validity).indexOf(isValid); @@ -2092,7 +2092,7 @@ export class GraphRenderer { GraphRenderer.destinationPort = port; GraphRenderer.destinationNode = eagle.logicalGraph().findNodeByKey(port.getNodeKey()); - const isValid = Edge.isValid(eagle,true, null, GraphRenderer.portDragSourceNode().getKey(), GraphRenderer.portDragSourcePort().getId(), GraphRenderer.destinationNode.getKey(), GraphRenderer.destinationPort.getId(), false, false, false, false, {errors:[], warnings:[]}); + const isValid = Edge.isValid(eagle, null, GraphRenderer.portDragSourceNode().getKey(), GraphRenderer.portDragSourcePort().getId(), GraphRenderer.destinationNode.getKey(), GraphRenderer.destinationPort.getId(), false, false, false, false, {errors:[], warnings:[]}); GraphRenderer.isDraggingPortValid(isValid); } diff --git a/src/Utils.ts b/src/Utils.ts index 3f8c1da3e..a4f63bbee 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -1421,7 +1421,7 @@ export class Utils { // check all edges are valid for (const edge of graph.getEdges()){ - Edge.isValid(eagle,false, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, false, {warnings: [], errors: []}); + Edge.isValid(eagle, edge.getId(), edge.getSrcNodeKey(), edge.getSrcPortId(), edge.getDestNodeKey(), edge.getDestPortId(), edge.isLoopAware(), edge.isClosesLoop(), false, false, {warnings: [], errors: []}); } }