@elyra/canvas 12.33.0 → 12.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/{canvas-constants-72222288.js → canvas-constants-29b7f65c.js} +2 -2
  2. package/dist/{canvas-constants-72222288.js.map → canvas-constants-29b7f65c.js.map} +1 -1
  3. package/dist/{canvas-constants-903046ab.js → canvas-constants-85883d4c.js} +2 -2
  4. package/dist/{canvas-constants-903046ab.js.map → canvas-constants-85883d4c.js.map} +1 -1
  5. package/dist/{canvas-controller-c0b65951.js → canvas-controller-273d4b5b.js} +2 -2
  6. package/dist/{canvas-controller-c0b65951.js.map → canvas-controller-273d4b5b.js.map} +1 -1
  7. package/dist/{canvas-controller-2df80dc3.js → canvas-controller-96abce12.js} +2 -2
  8. package/dist/{canvas-controller-2df80dc3.js.map → canvas-controller-96abce12.js.map} +1 -1
  9. package/dist/{canvas-logger-6f90b136.js → canvas-logger-34ca361a.js} +2 -2
  10. package/dist/{canvas-logger-6f90b136.js.map → canvas-logger-34ca361a.js.map} +1 -1
  11. package/dist/{canvas-logger-3bfbcf85.js → canvas-logger-fec87cd1.js} +2 -2
  12. package/dist/{canvas-logger-3bfbcf85.js.map → canvas-logger-fec87cd1.js.map} +1 -1
  13. package/dist/common-canvas-5ccce28e.js +2 -0
  14. package/dist/common-canvas-5ccce28e.js.map +1 -0
  15. package/dist/common-canvas-f471a9f3.js +2 -0
  16. package/dist/common-canvas-f471a9f3.js.map +1 -0
  17. package/dist/common-canvas.es.js +1 -1
  18. package/dist/common-canvas.js +1 -1
  19. package/dist/{common-properties-c6bc9d53.js → common-properties-51bd2ecc.js} +2 -2
  20. package/dist/{common-properties-c6bc9d53.js.map → common-properties-51bd2ecc.js.map} +1 -1
  21. package/dist/{common-properties-e3da18c4.js → common-properties-e82771ef.js} +2 -2
  22. package/dist/{common-properties-e3da18c4.js.map → common-properties-e82771ef.js.map} +1 -1
  23. package/dist/{context-menu-wrapper-5846a20e.js → context-menu-wrapper-19a1cf72.js} +2 -2
  24. package/dist/{context-menu-wrapper-5846a20e.js.map → context-menu-wrapper-19a1cf72.js.map} +1 -1
  25. package/dist/{context-menu-wrapper-ac5e8c7a.js → context-menu-wrapper-c3a98c63.js} +2 -2
  26. package/dist/{context-menu-wrapper-ac5e8c7a.js.map → context-menu-wrapper-c3a98c63.js.map} +1 -1
  27. package/dist/{createClass-826941b3.js → createClass-09bc08f7.js} +1 -1
  28. package/dist/createClass-09bc08f7.js.map +1 -0
  29. package/dist/{createClass-be661622.js → createClass-ffbbe837.js} +1 -1
  30. package/dist/createClass-ffbbe837.js.map +1 -0
  31. package/dist/{datarecord-metadata-v3-schema-64329ae4.js → datarecord-metadata-v3-schema-531c7b07.js} +2 -2
  32. package/dist/{datarecord-metadata-v3-schema-64329ae4.js.map → datarecord-metadata-v3-schema-531c7b07.js.map} +1 -1
  33. package/dist/{datarecord-metadata-v3-schema-dd7370da.js → datarecord-metadata-v3-schema-db5150c5.js} +2 -2
  34. package/dist/{datarecord-metadata-v3-schema-dd7370da.js.map → datarecord-metadata-v3-schema-db5150c5.js.map} +1 -1
  35. package/dist/{flexible-table-a7325a4e.js → flexible-table-8c6db0fc.js} +2 -2
  36. package/dist/{flexible-table-a7325a4e.js.map → flexible-table-8c6db0fc.js.map} +1 -1
  37. package/dist/{flexible-table-11488132.js → flexible-table-b9c08069.js} +2 -2
  38. package/dist/{flexible-table-11488132.js.map → flexible-table-b9c08069.js.map} +1 -1
  39. package/dist/{getPrototypeOf-3751add9.js → getPrototypeOf-012c454b.js} +2 -2
  40. package/dist/{getPrototypeOf-3751add9.js.map → getPrototypeOf-012c454b.js.map} +1 -1
  41. package/dist/{getPrototypeOf-1e698126.js → getPrototypeOf-5f227292.js} +2 -2
  42. package/dist/{getPrototypeOf-1e698126.js.map → getPrototypeOf-5f227292.js.map} +1 -1
  43. package/dist/{icon-cc184f86.js → icon-a9c3f51e.js} +2 -2
  44. package/dist/{icon-cc184f86.js.map → icon-a9c3f51e.js.map} +1 -1
  45. package/dist/{icon-111df69c.js → icon-de9c6b33.js} +2 -2
  46. package/dist/{icon-111df69c.js.map → icon-de9c6b33.js.map} +1 -1
  47. package/dist/{index-d75b9194.js → index-9960d3bf.js} +2 -2
  48. package/dist/{index-d75b9194.js.map → index-9960d3bf.js.map} +1 -1
  49. package/dist/{index-e76525b3.js → index-d4a58ddb.js} +2 -2
  50. package/dist/{index-e76525b3.js.map → index-d4a58ddb.js.map} +1 -1
  51. package/dist/lib/canvas-controller.es.js +1 -1
  52. package/dist/lib/canvas-controller.js +1 -1
  53. package/dist/lib/canvas.es.js +1 -1
  54. package/dist/lib/canvas.js +1 -1
  55. package/dist/lib/command-stack.es.js +1 -1
  56. package/dist/lib/command-stack.js +1 -1
  57. package/dist/lib/context-menu.es.js +1 -1
  58. package/dist/lib/context-menu.js +1 -1
  59. package/dist/lib/properties/field-picker.es.js +1 -1
  60. package/dist/lib/properties/field-picker.js +1 -1
  61. package/dist/lib/properties/flexible-table.es.js +1 -1
  62. package/dist/lib/properties/flexible-table.js +1 -1
  63. package/dist/lib/properties.es.js +1 -1
  64. package/dist/lib/properties.js +1 -1
  65. package/dist/lib/tooltip.es.js +1 -1
  66. package/dist/lib/tooltip.js +1 -1
  67. package/dist/styles/common-canvas.min.css +1 -1
  68. package/dist/styles/common-canvas.min.css.map +1 -1
  69. package/dist/toolbar-233c09a8.js +2 -0
  70. package/dist/toolbar-233c09a8.js.map +1 -0
  71. package/dist/toolbar-cdb38f4a.js +2 -0
  72. package/dist/toolbar-cdb38f4a.js.map +1 -0
  73. package/package.json +3 -3
  74. package/src/common-canvas/cc-central-items.jsx +81 -17
  75. package/src/common-canvas/cc-contents.jsx +3 -19
  76. package/src/common-canvas/cc-right-flyout.jsx +1 -1
  77. package/src/common-canvas/common-canvas.jsx +1 -50
  78. package/src/common-canvas/common-canvas.scss +23 -45
  79. package/src/common-canvas/svg-canvas-d3.js +2 -1
  80. package/src/common-canvas/svg-canvas-renderer.js +166 -79
  81. package/src/common-canvas/svg-canvas-utils-nodes.js +0 -4
  82. package/src/common-properties/controls/dropdown/dropdown.jsx +8 -1
  83. package/src/notification-panel/notification-panel.scss +1 -0
  84. package/src/toolbar/toolbar-action-item.jsx +1 -1
  85. package/stats.html +1 -1
  86. package/dist/common-canvas-da94213a.js +0 -2
  87. package/dist/common-canvas-da94213a.js.map +0 -1
  88. package/dist/common-canvas-dcc564f1.js +0 -2
  89. package/dist/common-canvas-dcc564f1.js.map +0 -1
  90. package/dist/createClass-826941b3.js.map +0 -1
  91. package/dist/createClass-be661622.js.map +0 -1
  92. package/dist/toolbar-556dad41.js +0 -2
  93. package/dist/toolbar-556dad41.js.map +0 -1
  94. package/dist/toolbar-df55ee97.js +0 -2
  95. package/dist/toolbar-df55ee97.js.map +0 -1
@@ -210,19 +210,35 @@ export default class SVGCanvasRenderer {
210
210
  // no link is currently being drawn.
211
211
  this.drawingNewLinkData = null;
212
212
 
213
- // Create a drag object for use with nodes and comments.
214
- this.drag = d3.drag()
213
+ // Create a drag handler for use with nodes and comments.
214
+ this.dragHandler = d3.drag()
215
215
  .on("start", this.dragStart.bind(this))
216
216
  .on("drag", this.dragMove.bind(this))
217
217
  .on("end", this.dragEnd.bind(this));
218
218
 
219
+ // Create a drag handler that will switch off the drag behavior of nodes
220
+ // and comments, for use when editing actions are not allowed.
221
+ this.noDragHandler = d3.drag()
222
+ .on("start", null)
223
+ .on("drag", null)
224
+ .on("end", null);
225
+
219
226
  this.draggingLinkData = null;
220
227
 
221
- this.dragSelectionHandle = d3.drag()
228
+ // Create a drag handler that can be used with draggable ends of
229
+ // detached links.
230
+ this.dragLinkHandler = d3.drag()
222
231
  .on("start", this.dragStartLinkHandle.bind(this))
223
232
  .on("drag", this.dragMoveLinkHandle.bind(this))
224
233
  .on("end", this.dragEndLinkHandle.bind(this));
225
234
 
235
+ // Create a drag handler that will switch off the drag behavior of
236
+ // detached links, for use when editing actions are not allowed.
237
+ this.noDragLinkHandler = d3.drag()
238
+ .on("start", null)
239
+ .on("drag", null)
240
+ .on("end", null);
241
+
226
242
  // Create a zoom object for use with the canvas.
227
243
  this.zoom =
228
244
  d3.zoom()
@@ -328,8 +344,9 @@ export default class SVGCanvasRenderer {
328
344
  this.zoomTransform = d3.zoomIdentity.translate(0, 0).scale(1);
329
345
  }
330
346
 
331
- setCanvasInfoRenderer(canvasInfo, selectionInfo, breadcrumbs, nodeLayout, canvasLayout) {
347
+ setCanvasInfoRenderer(canvasInfo, selectionInfo, breadcrumbs, nodeLayout, canvasLayout, config) {
332
348
  this.logger.logStartTimer("setCanvasInfoRenderer" + this.pipelineId.substring(0, 5));
349
+ this.config = config;
333
350
  this.canvasInfo = canvasInfo;
334
351
  this.selectionInfo = selectionInfo;
335
352
  this.breadcrumbs = breadcrumbs;
@@ -338,6 +355,23 @@ export default class SVGCanvasRenderer {
338
355
 
339
356
  this.activePipeline.initialize(this.pipelineId, canvasInfo, selectionInfo);
340
357
 
358
+ // Must recreate these utils objects because they use the config object
359
+ // which may have changed.
360
+ this.linkUtils = new SvgCanvasLinks(this.config, this.canvasLayout, this.nodeUtils, this.commentUtils);
361
+ this.svgCanvasTextArea = new SvgCanvasTextArea(
362
+ this.config,
363
+ this.dispUtils,
364
+ this.nodeUtils,
365
+ this.decUtils,
366
+ this.canvasController,
367
+ this.canvasDiv,
368
+ this.activePipeline,
369
+ this.displayComments.bind(this), // Function
370
+ this.displayLinks.bind(this), // Function
371
+ this.getCommentToolbarPos.bind(this) // Function
372
+ );
373
+
374
+
341
375
  // Set the display state incase we changed from in-place to full-page
342
376
  // sub-flow display.
343
377
  this.dispUtils.setDisplayState();
@@ -2703,7 +2737,7 @@ export default class SVGCanvasRenderer {
2703
2737
  .attr("transform", (d) => `translate(${d.x_pos}, ${d.y_pos})`)
2704
2738
  .attr("class", (d) => this.getNodeGroupClass(d))
2705
2739
  .attr("style", (d) => this.getNodeGrpStyle(d))
2706
- .call((joinedNodeGrps) => this.updateNodes(joinedNodeGrps));
2740
+ .call((joinedNodeGrps) => this.updateNodes(joinedNodeGrps, data));
2707
2741
  }
2708
2742
 
2709
2743
  createNodes(enter) {
@@ -2714,79 +2748,75 @@ export default class SVGCanvasRenderer {
2714
2748
  .attr("data-id", (d) => this.getId("node_grp", d.id))
2715
2749
  .call(this.attachNodeGroupListeners.bind(this));
2716
2750
 
2717
- if (this.config.enableEditingActions) {
2718
- newNodeGroups
2719
- .call(this.drag); // Must put drag after mousedown listener so mousedown gets called first.
2720
- }
2721
-
2722
- // Node Sizing Area.
2723
- newNodeGroups.filter((d) => this.shouldDisplayNodeSizingArea(d))
2724
- .append("path")
2725
- .attr("class", "d3-node-sizing")
2726
- .call(this.attachNodeSizingListeners.bind(this));
2727
-
2728
- // Node Selection Highlighting Outline.
2729
- newNodeGroups.filter((d) => !CanvasUtils.isSuperBindingNode(d))
2730
- .append("path")
2731
- .attr("class", "d3-node-selection-highlight");
2732
-
2733
- // Node Body
2734
- newNodeGroups.filter((d) => !CanvasUtils.isSuperBindingNode(d) && d.layout.nodeShapeDisplay)
2735
- .append("path")
2736
- .attr("class", "d3-node-body-outline");
2737
-
2738
- // Optional foreign object to contain a React object
2739
- newNodeGroups.filter((d) => d.layout.nodeExternalObject)
2740
- .append("foreignObject")
2741
- .attr("class", "d3-foreign-object-external-node");
2742
-
2743
- // Node Image
2744
- newNodeGroups.filter((d) => !CanvasUtils.isSuperBindingNode(d) && d.layout.imageDisplay)
2745
- .each((node, i, nodeGrps) => {
2746
- const nodeImage = this.getNodeImage(node);
2747
- const nodeImageType = this.getImageType(nodeImage);
2748
- d3.select(nodeGrps[i])
2749
- .append(nodeImageType)
2750
- .attr("class", (d) => this.nodeUtils.getNodeImageClass(d));
2751
- });
2752
-
2753
- // Node Label
2754
- newNodeGroups.filter((d) => !CanvasUtils.isSuperBindingNode(d) && d.layout.labelDisplay)
2755
- .append("foreignObject")
2756
- .attr("class", "d3-foreign-object-node-label")
2757
- .call(this.attachNodeLabelListeners.bind(this))
2758
- .append("xhtml:div") // Provide a namespace when div is inside foreignObject
2759
- .append("xhtml:span") // Provide a namespace when span is inside foreignObject
2760
- .call(this.attachNodeLabelSpanListeners.bind(this));
2761
-
2762
2751
  this.logger.logEndTimer("createNodes");
2763
2752
 
2764
2753
  return newNodeGroups;
2765
2754
  }
2766
2755
 
2767
- updateNodes(joinedNodeGrps) {
2756
+ updateNodes(joinedNodeGrps, data) {
2768
2757
  this.logger.logStartTimer("updateNodes");
2769
2758
 
2759
+ const nonBindingNodeGrps = joinedNodeGrps.filter((node) => !CanvasUtils.isSuperBindingNode(node));
2760
+
2770
2761
  // Node Sizing Area
2771
- joinedNodeGrps.selectChildren(".d3-node-sizing")
2762
+ nonBindingNodeGrps
2763
+ .selectChildren(".d3-node-sizing")
2764
+ .data((d) => (this.shouldDisplayNodeSizingArea(d) ? [d] : []), (d) => d.id)
2765
+ .join(
2766
+ (enter) =>
2767
+ enter
2768
+ .append("path")
2769
+ .attr("class", "d3-node-sizing")
2770
+ .call(this.attachNodeSizingListeners.bind(this))
2771
+ )
2772
2772
  .datum((d) => this.activePipeline.getNode(d.id))
2773
2773
  .attr("d", (d) => this.getNodeShapePathSizing(d));
2774
2774
 
2775
+
2775
2776
  // Node Selection Highlighting Outline.
2776
- joinedNodeGrps.selectChildren(".d3-node-selection-highlight")
2777
+ nonBindingNodeGrps
2778
+ .selectChildren(".d3-node-selection-highlight")
2779
+ .data((d) => ([d]), (d) => d.id)
2780
+ .join(
2781
+ (enter) =>
2782
+ enter
2783
+ .append("path")
2784
+ .attr("class", "d3-node-selection-highlight")
2785
+ )
2777
2786
  .datum((d) => this.activePipeline.getNode(d.id))
2778
2787
  .attr("d", (d) => this.getNodeSelectionOutline(d))
2779
2788
  .attr("data-selected", (d) => (this.activePipeline.isSelected(d.id) ? "yes" : "no"))
2780
2789
  .attr("style", (d) => this.getNodeSelectionOutlineStyle(d, "default"));
2781
2790
 
2782
2791
  // Node Body
2783
- joinedNodeGrps.selectChildren(".d3-node-body-outline")
2792
+ nonBindingNodeGrps
2793
+ .selectChildren(".d3-node-body-outline")
2794
+ .data((d) => (d.layout.nodeShapeDisplay ? [d] : []), (d) => d.id)
2795
+ .join(
2796
+ (enter) =>
2797
+ enter
2798
+ .append("path")
2799
+ .attr("class", "d3-node-body-outline")
2800
+ )
2784
2801
  .datum((d) => this.activePipeline.getNode(d.id))
2785
2802
  .attr("d", (d) => this.getNodeShapePath(d))
2786
2803
  .attr("style", (d) => this.getNodeBodyStyle(d, "default"));
2787
2804
 
2788
2805
  // Optional foreign object to contain a React object
2789
- joinedNodeGrps.selectChildren(".d3-foreign-object-external-node")
2806
+ nonBindingNodeGrps
2807
+ .selectChildren(".d3-foreign-object-external-node")
2808
+ .data((d) => (d.layout.nodeExternalObject ? [d] : []), (d) => d.id)
2809
+ .join(
2810
+ (enter) =>
2811
+ enter
2812
+ .append("foreignObject")
2813
+ .attr("class", "d3-foreign-object-external-node"),
2814
+ null,
2815
+ (exit) => {
2816
+ exit.each(removeExternalObject.bind(this));
2817
+ exit.remove();
2818
+ }
2819
+ )
2790
2820
  .datum((d) => this.activePipeline.getNode(d.id))
2791
2821
  .attr("width", (d) => d.width)
2792
2822
  .attr("height", (d) => d.height)
@@ -2795,9 +2825,17 @@ export default class SVGCanvasRenderer {
2795
2825
  .each(addNodeExternalObject.bind(this));
2796
2826
 
2797
2827
  // Node Image
2798
- joinedNodeGrps.selectChildren(".d3-node-image")
2828
+ nonBindingNodeGrps
2829
+ .selectChildren(".d3-node-image")
2830
+ .data((d) => (d.layout.imageDisplay ? [d] : []), (d) => d.id)
2831
+ .join(
2832
+ (enter) =>
2833
+ enter
2834
+ .append((d) => this.getImageElement(d))
2835
+ .attr("class", "d3-node-image")
2836
+ )
2799
2837
  .datum((d) => this.activePipeline.getNode(d.id))
2800
- .each((d, i, nodeGrps) => this.setNodeImageContent(nodeGrps[i], d))
2838
+ .each((d, idx, imgs) => this.setNodeImageContent(imgs[idx], d))
2801
2839
  .attr("x", (d) => this.nodeUtils.getNodeImagePosX(d))
2802
2840
  .attr("y", (d) => this.nodeUtils.getNodeImagePosY(d))
2803
2841
  .attr("width", (d) => this.nodeUtils.getNodeImageWidth(d))
@@ -2805,7 +2843,22 @@ export default class SVGCanvasRenderer {
2805
2843
  .attr("style", (d) => this.getNodeImageStyle(d, "default"));
2806
2844
 
2807
2845
  // Node Label
2808
- joinedNodeGrps.selectChildren(".d3-foreign-object-node-label")
2846
+ nonBindingNodeGrps
2847
+ .selectChildren(".d3-foreign-object-node-label")
2848
+ .data((d) => (d.layout.labelDisplay ? [d] : []), (d) => d.id)
2849
+ .join(
2850
+ (enter) => {
2851
+ const labelFOSel = enter
2852
+ .append("foreignObject")
2853
+ .attr("class", "d3-foreign-object-node-label")
2854
+ .call(this.attachNodeLabelListeners.bind(this));
2855
+ labelFOSel
2856
+ .append("xhtml:div") // Provide a namespace when div is inside foreignObject
2857
+ .append("xhtml:span") // Provide a namespace when span is inside foreignObject
2858
+ .call(this.attachNodeLabelSpanListeners.bind(this));
2859
+ return labelFOSel;
2860
+ }
2861
+ )
2809
2862
  .datum((d) => this.activePipeline.getNode(d.id))
2810
2863
  .attr("x", (d) => this.nodeUtils.getNodeLabelPosX(d))
2811
2864
  .attr("y", (d) => this.nodeUtils.getNodeLabelPosY(d))
@@ -2818,11 +2871,11 @@ export default class SVGCanvasRenderer {
2818
2871
  .html((d) => escapeText(d.label));
2819
2872
 
2820
2873
  // Node Ellipsis Icon - if one exists
2821
- joinedNodeGrps.selectChildren(".d3-node-ellipsis-group")
2874
+ nonBindingNodeGrps.selectChildren(".d3-node-ellipsis-group")
2822
2875
  .attr("transform", (d) => this.nodeUtils.getNodeEllipsisTranslate(d));
2823
2876
 
2824
2877
  // Node (Supernode) Expansion Icon - if one exists
2825
- joinedNodeGrps.selectChildren(".d3-node-super-expand-icon-group")
2878
+ nonBindingNodeGrps.selectChildren(".d3-node-super-expand-icon-group")
2826
2879
  .attr("transform", (d) => this.nodeUtils.getNodeExpansionIconTranslate(d));
2827
2880
 
2828
2881
  // Ports display; Supernode sub-flow display; Error marker display; and
@@ -2845,6 +2898,16 @@ export default class SVGCanvasRenderer {
2845
2898
  this.displayDecorations(d, DEC_NODE, nodeGrp, decorations);
2846
2899
  }
2847
2900
  });
2901
+
2902
+ // Add or remove drag behavior as appropriate
2903
+ if (this.config.enableEditingActions) {
2904
+ nonBindingNodeGrps
2905
+ .call(this.dragHandler);
2906
+ } else {
2907
+ nonBindingNodeGrps
2908
+ .call(this.noDragHandler);
2909
+ }
2910
+
2848
2911
  this.logger.logEndTimer("updateNodes");
2849
2912
  }
2850
2913
 
@@ -2874,7 +2937,8 @@ export default class SVGCanvasRenderer {
2874
2937
  this.selectionInfo,
2875
2938
  this.breadcrumbs,
2876
2939
  this.nodeLayout,
2877
- this.canvasLayout
2940
+ this.canvasLayout,
2941
+ this.config
2878
2942
  );
2879
2943
  }
2880
2944
  } else {
@@ -3798,6 +3862,16 @@ export default class SVGCanvasRenderer {
3798
3862
  return nodeImage && nodeImage.endsWith(".svg") && this.config.enableImageDisplay !== "SVGAsImage" ? "svg" : "image";
3799
3863
  }
3800
3864
 
3865
+ // Returns a DOM element for the image of the node passed in.
3866
+ getImageElement(node) {
3867
+ const nodeImage = this.getNodeImage(node);
3868
+ const imageType = this.getImageType(nodeImage);
3869
+ if (imageType === "image") {
3870
+ return d3.create("svg:image").node();
3871
+ }
3872
+ return d3.create("svg").node();
3873
+ }
3874
+
3801
3875
  setNodeStyles(d, type, nodeGrp) {
3802
3876
  this.setNodeBodyStyles(d, type, nodeGrp);
3803
3877
  this.setNodeSelectionOutlineStyles(d, type, nodeGrp);
@@ -3931,7 +4005,10 @@ export default class SVGCanvasRenderer {
3931
4005
 
3932
4006
  addDynamicNodeIcons(d3Event, d, nodeGrp) {
3933
4007
  if (!this.nodeSizing && !CanvasUtils.isSuperBindingNode(d)) {
3934
- this.addEllipsisIcon(d, nodeGrp);
4008
+ // Add the ellipsis icon if requested by layout config.
4009
+ if (d.layout.ellipsisDisplay) {
4010
+ this.addEllipsisIcon(d, nodeGrp);
4011
+ }
3935
4012
 
3936
4013
  // Add Supernode expansion icon and background for expanded supernodes
3937
4014
  if (CanvasUtils.isExpandedSupernode(d)) {
@@ -3976,7 +4053,6 @@ export default class SVGCanvasRenderer {
3976
4053
  addEllipsisIcon(d, nodeGrp) {
3977
4054
  const ellipsisGrp = nodeGrp
3978
4055
  .append("g")
3979
- .filter(() => d.layout.ellipsisDisplay)
3980
4056
  .attr("class", "d3-node-ellipsis-group")
3981
4057
  .attr("transform", (nd) => this.nodeUtils.getNodeEllipsisTranslate(nd))
3982
4058
  .on("mousedown", (d3Event) => {
@@ -5471,11 +5547,6 @@ export default class SVGCanvasRenderer {
5471
5547
  .attr("data-id", (c) => this.getId("comment_grp", c.id))
5472
5548
  .call(this.attachCommentGroupListeners.bind(this));
5473
5549
 
5474
- if (this.config.enableEditingActions) {
5475
- newCommentGroups
5476
- .call(this.drag); // Must put drag after mousedown listener so mousedown gets called first.
5477
- }
5478
-
5479
5550
  // Comment Sizing Area
5480
5551
  newCommentGroups
5481
5552
  .append("rect")
@@ -5551,6 +5622,15 @@ export default class SVGCanvasRenderer {
5551
5622
  this.config.enableMarkdownInComments
5552
5623
  ? markdownIt.render(c.content)
5553
5624
  : escapeText(c.content)));
5625
+
5626
+ // Add or remove drag behavior as appropriate
5627
+ if (this.config.enableEditingActions) {
5628
+ joinedCommentGrps
5629
+ .call(this.dragHandler);
5630
+ } else {
5631
+ joinedCommentGrps
5632
+ .call(this.noDragHandler);
5633
+ }
5554
5634
  }
5555
5635
 
5556
5636
  // Attaches the appropriate listeners to the comment groups.
@@ -6327,7 +6407,7 @@ export default class SVGCanvasRenderer {
6327
6407
  // Creates a new start handle and a new end handle for the link groups
6328
6408
  // passed in.
6329
6409
  createNewHandles(handlesGrp) {
6330
- const startHandle = handlesGrp
6410
+ handlesGrp
6331
6411
  .append(this.canvasLayout.linkStartHandleObject)
6332
6412
  .attr("class", (d) => "d3-link-handle-start")
6333
6413
  // Use mouse down instead of click because it gets called before drag start.
@@ -6339,11 +6419,7 @@ export default class SVGCanvasRenderer {
6339
6419
  this.logger.log("Link end handle - finished mouse down");
6340
6420
  });
6341
6421
 
6342
- if (this.config.enableEditingActions) {
6343
- startHandle.call(this.dragSelectionHandle);
6344
- }
6345
-
6346
- const endHandle = handlesGrp
6422
+ handlesGrp
6347
6423
  .append(this.canvasLayout.linkEndHandleObject)
6348
6424
  .attr("class", (d) => "d3-link-handle-end")
6349
6425
  // Use mouse down instead of click because it gets called before drag start.
@@ -6355,14 +6431,11 @@ export default class SVGCanvasRenderer {
6355
6431
  this.logger.log("Link end handle - finished mouse down");
6356
6432
  });
6357
6433
 
6358
- if (this.config.enableEditingActions) {
6359
- endHandle.call(this.dragSelectionHandle);
6360
- }
6361
6434
  }
6362
6435
 
6363
6436
  // Updates the start and end link handles for the handle groups passed in.
6364
6437
  updateHandles(handlesGrp, lineArray) {
6365
- handlesGrp
6438
+ const startHandle = handlesGrp
6366
6439
  .selectAll(".d3-link-handle-start")
6367
6440
  .datum((d) => this.activePipeline.getLink(d.id))
6368
6441
  .each((datum, index, linkHandles) => {
@@ -6383,7 +6456,14 @@ export default class SVGCanvasRenderer {
6383
6456
  }
6384
6457
  });
6385
6458
 
6386
- handlesGrp
6459
+ // Add or remove drag behavior as appropriate
6460
+ if (this.config.enableEditingActions) {
6461
+ startHandle.call(this.dragLinkHandler);
6462
+ } else {
6463
+ startHandle.call(this.noDragLinkHandler);
6464
+ }
6465
+
6466
+ const endHandle = handlesGrp
6387
6467
  .selectAll(".d3-link-handle-end")
6388
6468
  .datum((d) => this.activePipeline.getLink(d.id))
6389
6469
  .each((datum, index, linkHandles) => {
@@ -6404,6 +6484,13 @@ export default class SVGCanvasRenderer {
6404
6484
  .attr("cy", (d) => d.y2);
6405
6485
  }
6406
6486
  });
6487
+
6488
+ // Add or remove drag behavior as appropriate
6489
+ if (this.config.enableEditingActions) {
6490
+ endHandle.call(this.dragLinkHandler);
6491
+ } else {
6492
+ endHandle.call(this.noDragLinkHandler);
6493
+ }
6407
6494
  }
6408
6495
 
6409
6496
  // Sets the custom inline styles on the link object passed in.
@@ -30,10 +30,6 @@ export default class SvgCanvasNodes {
30
30
  pos.y <= node.y_pos + node.height;
31
31
  }
32
32
 
33
- getNodeImageClass(node) {
34
- return "d3-node-image";
35
- }
36
-
37
33
  getNodeLabelClass(node) {
38
34
  if (CanvasUtils.isExpandedSupernode(node)) {
39
35
  return "d3-node-label d3-label-single-line " + this.getMessageLabelClass(node.messages);
@@ -178,7 +178,14 @@ class DropDown extends React.Component {
178
178
 
179
179
  // evt is null when onBlur, empty string when clicking the 'x' to clear input
180
180
  handleOnInputChange(evt) {
181
- if (evt !== null) {
181
+ const currentValue = this.props.controller.getPropertyValue(this.props.propertyId);
182
+
183
+ // Don't update property value during initial render
184
+ if ((typeof currentValue === "undefined" || currentValue === null) && evt === "") {
185
+ return;
186
+ }
187
+
188
+ if (evt !== null && evt !== currentValue) {
182
189
  const value = evt;
183
190
  this.props.controller.updatePropertyValue(this.props.propertyId, value);
184
191
  }
@@ -24,6 +24,7 @@ $toolbar-button-height: 41px; // Allow one extra pixel for the toolbar border
24
24
  transition: 0.25s ease-in-out;
25
25
  opacity: 1;
26
26
  margin-top: 0;
27
+ z-index: 2; // Ensure panel appears on top of bottom panel.
27
28
 
28
29
  &.panel-hidden {
29
30
  transition: 0.25s ease-in-out;
@@ -267,7 +267,7 @@ class ToolbarActionItem extends React.Component {
267
267
  const chevronIcon = this.generateChevronIcon(actionObj);
268
268
 
269
269
  let buttonContent = (
270
- <div id={"open-action-item"} className={itemContentClassName}>
270
+ <div className={itemContentClassName}>
271
271
  {labelBefore}
272
272
  {icon}
273
273
  {labelAfter}