Skip to content

Commit

Permalink
#601 When no node is selected on the Canvas, palette double-click sho… (
Browse files Browse the repository at this point in the history
  • Loading branch information
tomlyn authored Mar 26, 2021
1 parent 768cbf4 commit adca2ff
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
import Action from "../command-stack/action.js";

export default class CreateAutoNodeAction extends Action {
constructor(data, objectModel) {
constructor(data, objectModel, autoLinkOnlyFromSelNodes) {
super(data);
this.data = data;
this.objectModel = objectModel;
this.apiPipeline = this.objectModel.getAPIPipeline(data.pipelineId);
this.srcNode = this.apiPipeline.getAutoSourceNode();
this.srcNode = this.apiPipeline.getAutoSourceNode(autoLinkOnlyFromSelNodes);
this.newNode = this.apiPipeline.createAutoNode(data, this.srcNode);
this.newLink = null;
if (this.apiPipeline.isLinkNeededWithAutoNode(this.newNode, this.srcNode)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export default class CanvasController {
enablePanIntoViewOnOpen: false,
enableZoomIntoSubFlows: false,
enableBrowserEditMenu: true,
enableAutoLinkOnlyFromSelNodes: false,
enableSaveZoom: "None",
enableSnapToGridType: "None",
enableSnapToGridX: null,
Expand Down Expand Up @@ -1947,7 +1948,7 @@ export default class CanvasController {
break;
}
case "createAutoNode": {
command = new CreateAutoNodeAction(data, this.objectModel);
command = new CreateAutoNodeAction(data, this.objectModel, this.canvasConfig.enableAutoLinkOnlyFromSelNodes);
this.commandStack.do(command);
this.panToReveal(data);
data = command.getData();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export default class SVGCanvasD3 {
this.config.enableHighlightUnavailableNodes !== config.enableHighlightUnavailableNodes ||
this.config.enablePanIntoViewOnOpen !== config.enablePanIntoViewOnOpen ||
this.config.enableRightFlyoutUnderToolbar !== config.enableRightFlyoutUnderToolbar ||
this.config.enableAutoLinkOnlyFromSelNodes !== config.enableAutoLinkOnlyFromSelNodes ||
!this.enableNodeRightFlyoutOpenExactlyMatches(this.config.enablePositionNodeOnRightFlyoutOpen, config.enablePositionNodeOnRightFlyoutOpen) ||
!this.enableCanvasLayoutExactlyMatches(this.config.enableCanvasLayout, config.enableCanvasLayout) ||
!this.enableNodeLayoutExactlyMatches(this.config.enableNodeLayout, config.enableNodeLayout)) {
Expand Down
16 changes: 13 additions & 3 deletions canvas_modules/common-canvas/src/object-model/api-pipeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,13 +271,15 @@ export default class APIPipeline {
// 1. The selected node, if only *one* node is currently selected or
// 2. The most recently added node, provided it has one or more output ports or
// 3. The most-recent-but-one added node, provided it has one or more output ports
getAutoSourceNode() {
getAutoSourceNode(autoLinkOnlyFromSelNodes) {
var sourceNode = null;
var selectedNodes = this.objectModel.getSelectedNodes();

if (selectedNodes.length === 1) {
if (selectedNodes.length === 1 &&
this.isViableAutoSourceNode(selectedNodes[0])) {
sourceNode = selectedNodes[0];
} else {

} else if (!autoLinkOnlyFromSelNodes) {
var nodesArray = this.getNodes();
if (nodesArray.length > 0) {
var lastNodeAdded = nodesArray[nodesArray.length - 1];
Expand All @@ -294,6 +296,14 @@ export default class APIPipeline {
return sourceNode;
}

// Returns true if the node passed in is OK to be used as a source node
// for a node which is to be auto-added to the canvas.
isViableAutoSourceNode(node) {
return node.outputs &&
node.outputs.length > 0 &&
!CanvasUtils.isSrcCardinalityAtMax(node.outputs[0].id, node, this.getLinks());
}

// Returns a newly created 'auto node' whose position is based on the
// source node (if one is provided) and the the other nodes on the canvas.
createAutoNode(data, sourceNode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,6 @@ describe("Test auto layout variations", function() {
", undo, redo functions", function() {
cy.clickToolbarPaletteOpen();

// Double click Object Store node on canvas
cy.clickCategory("Export");
cy.doubleClickNodeInCategory("Object Store");
cy.verifyNodeTransform("Object Store", 50, 50);
cy.verifyNumberOfNodes(1);
cy.verifyNumberOfPortDataLinks(0);

// Double click Table node on canvas
cy.clickCategory("Outputs");
cy.doubleClickNodeInCategory("Table");
cy.verifyNodeTransform("Table", 200, 50);
cy.verifyNumberOfNodes(2);
cy.verifyNumberOfPortDataLinks(0);

// Click undo
cy.clickToolbarUndo();
cy.verifyNumberOfNodes(1);
cy.verifyNumberOfPortDataLinks(0);

// Click undo
cy.clickToolbarUndo();
cy.verifyNumberOfNodes(0);
cy.verifyNumberOfPortDataLinks(0);

// Double click Var. File node on canvas
cy.clickCategory("Import");
cy.doubleClickNodeInCategory("Var. File");
Expand Down Expand Up @@ -132,7 +108,7 @@ describe("Test auto layout variations", function() {
// Double click Object Store node on canvas
cy.doubleClickNodeInCategory("Object Store");
cy.verifyNumberOfNodes(11);
cy.verifyNumberOfPortDataLinks(8);
cy.verifyNumberOfPortDataLinks(9);

// Click undo
cy.clickToolbarUndo();
Expand Down Expand Up @@ -162,7 +138,35 @@ describe("Test auto layout variations", function() {
// Click Redo
cy.clickToolbarRedo();
cy.verifyNumberOfNodes(11);
cy.verifyNumberOfPortDataLinks(8);
cy.verifyNumberOfPortDataLinks(9);
});

it("Test an execution node auto-added after a binding exit node goes on new line & undo, redo.", function() {
cy.clickToolbarPaletteOpen();

// Double click Object Store node on canvas
cy.clickCategory("Export");
cy.doubleClickNodeInCategory("Object Store");
cy.verifyNodeTransform("Object Store", 50, 50);
cy.verifyNumberOfNodes(1);
cy.verifyNumberOfPortDataLinks(0);

// Double click Table node on canvas
cy.clickCategory("Outputs");
cy.doubleClickNodeInCategory("Table");
cy.verifyNodeTransform("Table", 50, 205);
cy.verifyNumberOfNodes(2);
cy.verifyNumberOfPortDataLinks(0);

// Click undo
cy.clickToolbarUndo();
cy.verifyNumberOfNodes(1);
cy.verifyNumberOfPortDataLinks(0);

// Click undo
cy.clickToolbarUndo();
cy.verifyNumberOfNodes(0);
cy.verifyNumberOfPortDataLinks(0);
});
});

Expand Down
2 changes: 2 additions & 0 deletions canvas_modules/harness/src/client/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ class App extends React.Component {
selectedPositionNodeOnRightFlyoutOpen: false,
selectedNarrowPalette: true,
selectedSchemaValidation: true,
selectedAutoLinkOnlyFromSelNodes: false,
selectedBrowserEditMenu: true,
selectedBoundingRectangles: false,
selectedNodeLayout: null,
Expand Down Expand Up @@ -1760,6 +1761,7 @@ class App extends React.Component {
enableInsertNodeDroppedOnLink: this.state.selectedInsertNodeDroppedOnLink,
enableMoveNodesOnSupernodeResize: this.state.selectedMoveNodesOnSupernodeResize,
enablePositionNodeOnRightFlyoutOpen: this.state.selectedPositionNodeOnRightFlyoutOpen,
enableAutoLinkOnlyFromSelNodes: this.state.selectedAutoLinkOnlyFromSelNodes,
enableBrowserEditMenu: this.state.selectedBrowserEditMenu,
tipConfig: this.state.selectedTipConfig,
schemaValidation: this.state.selectedSchemaValidation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export default class DetachedCanvas extends React.Component {
enableHighlightNodeOnNewLinkDrag: true,
enableHighlightUnavailableNodes: true,
enableDisplayFullLabelOnHover: true,
enableAutoLinkOnlyFromSelNodes: true,
enableNarrowPalette: false,
paletteInitialState: true,
tipConfig: {
Expand Down
11 changes: 11 additions & 0 deletions canvas_modules/harness/src/client/components/sidepanel-canvas.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,15 @@ export default class SidePanelForms extends React.Component {
/>
</div>);

var enableAutoLinkOnlyFromSelNodes = (<div className="harness-sidepanel-children">
<Toggle
id="selectedAutoLinkOnlyFromSelNodes" // Set ID to corresponding field in App.js state
labelText="Enable Auto Link Only From Selected Nodes"
toggled={this.props.getStateValue("selectedAutoLinkOnlyFromSelNodes")}
onToggle={this.setStateValue}
/>
</div>);

var enableBrowserEditMenu = (<div className="harness-sidepanel-children">
<Toggle
id="selectedBrowserEditMenu" // Set ID to corresponding field in App.js state
Expand Down Expand Up @@ -1343,6 +1352,8 @@ export default class SidePanelForms extends React.Component {
{divider}
{enableMoveNodesOnSupernodeResize}
{divider}
{enableAutoLinkOnlyFromSelNodes}
{divider}
{enableBrowserEditMenu}
{divider}
{displayBoudingRectangles}
Expand Down

0 comments on commit adca2ff

Please sign in to comment.