@elyra/canvas 12.42.0 → 12.44.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 (185) hide show
  1. package/dist/{canvas-constants-ff5cf88e.js → canvas-constants-089e7830.js} +2 -2
  2. package/dist/{canvas-constants-ff5cf88e.js.map → canvas-constants-089e7830.js.map} +1 -1
  3. package/dist/{canvas-constants-13b58448.js → canvas-constants-69e90162.js} +2 -2
  4. package/dist/{canvas-constants-13b58448.js.map → canvas-constants-69e90162.js.map} +1 -1
  5. package/dist/canvas-controller-3e6b8ce4.js +2 -0
  6. package/dist/canvas-controller-3e6b8ce4.js.map +1 -0
  7. package/dist/canvas-controller-c6274fad.js +2 -0
  8. package/dist/canvas-controller-c6274fad.js.map +1 -0
  9. package/dist/{canvas-logger-295dafe4.js → canvas-logger-6f4b2551.js} +2 -2
  10. package/dist/{canvas-logger-295dafe4.js.map → canvas-logger-6f4b2551.js.map} +1 -1
  11. package/dist/{canvas-logger-e07a0b4a.js → canvas-logger-ab9d9048.js} +2 -2
  12. package/dist/{canvas-logger-e07a0b4a.js.map → canvas-logger-ab9d9048.js.map} +1 -1
  13. package/dist/common-canvas-6ed21ab6.js +2 -0
  14. package/dist/common-canvas-6ed21ab6.js.map +1 -0
  15. package/dist/common-canvas-8abf016c.js +2 -0
  16. package/dist/common-canvas-8abf016c.js.map +1 -0
  17. package/dist/common-canvas.es.js +1 -1
  18. package/dist/common-canvas.es.js.map +1 -1
  19. package/dist/common-canvas.js +1 -1
  20. package/dist/common-canvas.js.map +1 -1
  21. package/dist/common-properties-88377242.js +2 -0
  22. package/dist/common-properties-88377242.js.map +1 -0
  23. package/dist/common-properties-b295acc8.js +2 -0
  24. package/dist/common-properties-b295acc8.js.map +1 -0
  25. package/dist/context-menu-wrapper-949393c7.js +2 -0
  26. package/dist/context-menu-wrapper-949393c7.js.map +1 -0
  27. package/dist/context-menu-wrapper-f62dfcdb.js +2 -0
  28. package/dist/context-menu-wrapper-f62dfcdb.js.map +1 -0
  29. package/dist/{createClass-440000a3.js → createClass-02596015.js} +2 -2
  30. package/dist/createClass-02596015.js.map +1 -0
  31. package/dist/createClass-155bf7da.js +2 -0
  32. package/dist/createClass-155bf7da.js.map +1 -0
  33. package/dist/datarecord-metadata-v3-schema-07d18e19.js +2 -0
  34. package/dist/{datarecord-metadata-v3-schema-98ec66e9.js.map → datarecord-metadata-v3-schema-07d18e19.js.map} +1 -1
  35. package/dist/datarecord-metadata-v3-schema-df939dd1.js +2 -0
  36. package/dist/{datarecord-metadata-v3-schema-dba0b214.js.map → datarecord-metadata-v3-schema-df939dd1.js.map} +1 -1
  37. package/dist/defineProperty-ad55dbff.js +2 -0
  38. package/dist/{defineProperty-3dc7d8d0.js.map → defineProperty-ad55dbff.js.map} +1 -1
  39. package/dist/{defineProperty-6d406743.js → defineProperty-bcc9968d.js} +2 -2
  40. package/dist/{defineProperty-6d406743.js.map → defineProperty-bcc9968d.js.map} +1 -1
  41. package/dist/flexible-table-c6a8b402.js +2 -0
  42. package/dist/{flexible-table-7c7de0f9.js.map → flexible-table-c6a8b402.js.map} +1 -1
  43. package/dist/flexible-table-f7b294a0.js +2 -0
  44. package/dist/{flexible-table-35e9922a.js.map → flexible-table-f7b294a0.js.map} +1 -1
  45. package/dist/{icon-9edff40c.js → icon-56b27c4f.js} +2 -2
  46. package/dist/{icon-9edff40c.js.map → icon-56b27c4f.js.map} +1 -1
  47. package/dist/{icon-e622f99b.js → icon-8ec2f0ec.js} +2 -2
  48. package/dist/{icon-e622f99b.js.map → icon-8ec2f0ec.js.map} +1 -1
  49. package/dist/index-01cbacf9.js +2 -0
  50. package/dist/{index-e2f8a935.js.map → index-01cbacf9.js.map} +1 -1
  51. package/dist/index-79543d41.js +2 -0
  52. package/dist/{index-94fec521.js.map → index-79543d41.js.map} +1 -1
  53. package/dist/inherits-42ae8426.js +2 -0
  54. package/dist/inherits-42ae8426.js.map +1 -0
  55. package/dist/inherits-75817f22.js +2 -0
  56. package/dist/inherits-75817f22.js.map +1 -0
  57. package/dist/isArrayLikeObject-04f333a5.js +1 -1
  58. package/dist/isArrayLikeObject-04f333a5.js.map +1 -1
  59. package/dist/isArrayLikeObject-7a30aa4b.js +1 -1
  60. package/dist/isArrayLikeObject-7a30aa4b.js.map +1 -1
  61. package/dist/lib/canvas-controller.es.js +1 -1
  62. package/dist/lib/canvas-controller.js +1 -1
  63. package/dist/lib/canvas.es.js +1 -1
  64. package/dist/lib/canvas.js +1 -1
  65. package/dist/lib/command-stack.es.js +1 -1
  66. package/dist/lib/command-stack.es.js.map +1 -1
  67. package/dist/lib/command-stack.js +1 -1
  68. package/dist/lib/command-stack.js.map +1 -1
  69. package/dist/lib/context-menu.es.js +1 -1
  70. package/dist/lib/context-menu.js +1 -1
  71. package/dist/lib/properties/clem.es.js +2 -0
  72. package/dist/lib/properties/clem.es.js.map +1 -0
  73. package/dist/lib/properties/clem.js +2 -0
  74. package/dist/lib/properties/clem.js.map +1 -0
  75. package/dist/lib/properties/field-picker.es.js +1 -1
  76. package/dist/lib/properties/field-picker.js +1 -1
  77. package/dist/lib/properties/flexible-table.es.js +1 -1
  78. package/dist/lib/properties/flexible-table.js +1 -1
  79. package/dist/lib/properties/getPythonHints.es.js +2 -0
  80. package/dist/lib/properties/getPythonHints.es.js.map +1 -0
  81. package/dist/lib/properties/getPythonHints.js +2 -0
  82. package/dist/lib/properties/getPythonHints.js.map +1 -0
  83. package/dist/lib/properties.es.js +1 -1
  84. package/dist/lib/properties.js +1 -1
  85. package/dist/lib/tooltip.es.js +1 -1
  86. package/dist/lib/tooltip.es.js.map +1 -1
  87. package/dist/lib/tooltip.js +1 -1
  88. package/dist/lib/tooltip.js.map +1 -1
  89. package/dist/styles/common-canvas.min.css +1 -1
  90. package/dist/styles/common-canvas.min.css.map +1 -1
  91. package/dist/toolbar-235dfb9d.js +2 -0
  92. package/dist/toolbar-235dfb9d.js.map +1 -0
  93. package/dist/toolbar-6607e35c.js +2 -0
  94. package/dist/toolbar-6607e35c.js.map +1 -0
  95. package/package.json +3 -3
  96. package/rollup.config.js +2 -0
  97. package/src/color-picker/color-picker.jsx +5 -1
  98. package/src/common-canvas/canvas-controller.js +56 -1
  99. package/src/common-canvas/cc-central-items.jsx +0 -4
  100. package/src/common-canvas/cc-toolbar.jsx +35 -13
  101. package/src/common-canvas/common-canvas-utils.js +73 -2
  102. package/src/common-canvas/common-canvas.scss +8 -8
  103. package/src/common-canvas/constants/canvas-constants.js +1 -0
  104. package/src/common-canvas/svg-canvas-d3.scss +3 -2
  105. package/src/common-canvas/svg-canvas-renderer.js +184 -94
  106. package/src/common-canvas/svg-canvas-utils-external.js +1 -1
  107. package/src/common-canvas/svg-canvas-utils-links.js +28 -32
  108. package/src/common-canvas/svg-canvas-utils-nodes.js +5 -13
  109. package/src/common-properties/components/field-picker/field-picker.jsx +4 -0
  110. package/src/common-properties/controls/checkbox/checkbox.scss +0 -1
  111. package/src/common-properties/controls/expression/expression.jsx +3 -5
  112. package/src/common-properties/controls/expression/languages/python-hint.js +18 -30
  113. package/src/common-properties/controls/expression/languages/r-hint.js +16 -8
  114. package/src/common-properties/index.js +4 -2
  115. package/src/icons/icon.scss +1 -1
  116. package/src/index.js +2 -2
  117. package/src/notification-panel/notification-panel.jsx +82 -56
  118. package/src/notification-panel/notification-panel.scss +42 -40
  119. package/src/object-model/config-utils.js +2 -2
  120. package/src/object-model/layout-dimensions.js +82 -87
  121. package/src/object-model/object-model-utils.js +271 -0
  122. package/src/object-model/object-model.js +47 -245
  123. package/src/object-model/redux/reducers/canvasinfo.js +7 -11
  124. package/src/object-model/redux/reducers/canvastoolbar.js +5 -6
  125. package/src/palette/palette-dialog-topbar.jsx +27 -38
  126. package/src/palette/palette-flyout-content-category.jsx +25 -6
  127. package/src/palette/palette.scss +8 -40
  128. package/src/toolbar/index.js +18 -0
  129. package/src/toolbar/toolbar-action-item.jsx +42 -11
  130. package/src/toolbar/toolbar-button-item.jsx +49 -21
  131. package/src/toolbar/toolbar-divider-item.jsx +1 -1
  132. package/src/toolbar/toolbar-overflow-item.jsx +14 -6
  133. package/src/toolbar/toolbar-sub-menu-item.jsx +6 -5
  134. package/src/toolbar/toolbar-sub-menu.jsx +4 -6
  135. package/src/toolbar/toolbar-sub-panel.jsx +31 -18
  136. package/src/toolbar/toolbar-sub-utils.js +21 -12
  137. package/src/toolbar/toolbar.jsx +83 -26
  138. package/src/toolbar/toolbar.scss +47 -47
  139. package/src/tooltip/tooltip.jsx +56 -10
  140. package/stats.html +1 -1
  141. package/assets/images/palette/close_32.svg +0 -1
  142. package/assets/images/palette/palette_close.svg +0 -4
  143. package/assets/images/palette/palette_grid_deselected.svg +0 -2
  144. package/assets/images/palette/palette_grid_hover.svg +0 -2
  145. package/assets/images/palette/palette_grid_selected.svg +0 -2
  146. package/assets/images/palette/palette_list_deselected.svg +0 -1
  147. package/assets/images/palette/palette_list_hover.svg +0 -1
  148. package/assets/images/palette/palette_list_selected.svg +0 -1
  149. package/assets/images/palette/palette_open.svg +0 -4
  150. package/assets/images/zoom_to_fit.svg +0 -8
  151. package/dist/canvas-controller-a53943e4.js +0 -2
  152. package/dist/canvas-controller-a53943e4.js.map +0 -1
  153. package/dist/canvas-controller-cb1d7420.js +0 -2
  154. package/dist/canvas-controller-cb1d7420.js.map +0 -1
  155. package/dist/common-canvas-42027a3f.js +0 -2
  156. package/dist/common-canvas-42027a3f.js.map +0 -1
  157. package/dist/common-canvas-f758ff42.js +0 -2
  158. package/dist/common-canvas-f758ff42.js.map +0 -1
  159. package/dist/common-properties-2e1b7ec7.js +0 -2
  160. package/dist/common-properties-2e1b7ec7.js.map +0 -1
  161. package/dist/common-properties-5e8870e3.js +0 -2
  162. package/dist/common-properties-5e8870e3.js.map +0 -1
  163. package/dist/context-menu-wrapper-49f9a1af.js +0 -2
  164. package/dist/context-menu-wrapper-49f9a1af.js.map +0 -1
  165. package/dist/context-menu-wrapper-5d6a399f.js +0 -2
  166. package/dist/context-menu-wrapper-5d6a399f.js.map +0 -1
  167. package/dist/createClass-440000a3.js.map +0 -1
  168. package/dist/createClass-5ca26865.js +0 -2
  169. package/dist/createClass-5ca26865.js.map +0 -1
  170. package/dist/datarecord-metadata-v3-schema-98ec66e9.js +0 -2
  171. package/dist/datarecord-metadata-v3-schema-dba0b214.js +0 -2
  172. package/dist/defineProperty-3dc7d8d0.js +0 -2
  173. package/dist/flexible-table-35e9922a.js +0 -2
  174. package/dist/flexible-table-7c7de0f9.js +0 -2
  175. package/dist/index-94fec521.js +0 -2
  176. package/dist/index-e2f8a935.js +0 -2
  177. package/dist/inherits-226dfdb2.js +0 -2
  178. package/dist/inherits-226dfdb2.js.map +0 -1
  179. package/dist/inherits-41673c87.js +0 -2
  180. package/dist/inherits-41673c87.js.map +0 -1
  181. package/dist/toolbar-6acda0a2.js +0 -2
  182. package/dist/toolbar-6acda0a2.js.map +0 -1
  183. package/dist/toolbar-d5647da2.js +0 -2
  184. package/dist/toolbar-d5647da2.js.map +0 -1
  185. package/src/palette/palette-dialog-topbar-three-way-icon.jsx +0 -82
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2017-2023 Elyra Authors
2
+ * Copyright 2017-2024 Elyra Authors
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
18
18
  // objects stored in redux and also the copy of canvas objects maintained by
19
19
  // the CanvasRender objects.
20
20
 
21
- import { get, set } from "lodash";
21
+ import { get, has, isNumber, set } from "lodash";
22
22
  import { ASSOCIATION_LINK, ASSOC_STRAIGHT, COMMENT_LINK, NODE_LINK,
23
23
  LINK_TYPE_STRAIGHT, SUPER_NODE, NORTH, SOUTH, EAST, WEST }
24
24
  from "../common-canvas/constants/canvas-constants.js";
@@ -1237,4 +1237,75 @@ export default class CanvasUtils {
1237
1237
  return el.classList && el.classList.contains(className);
1238
1238
  }
1239
1239
 
1240
+ // Returns the ID of the pipeline referenced by the supernode
1241
+ // passed in.
1242
+ static getSupernodePipelineId(supernode) {
1243
+ if (supernode.type === SUPER_NODE &&
1244
+ has(supernode, "subflow_ref.pipeline_id_ref")) {
1245
+ return supernode.subflow_ref.pipeline_id_ref;
1246
+ }
1247
+ return null;
1248
+ }
1249
+
1250
+ // Convert now deprecated layout fields to the port positions arrays. The layout fields are
1251
+ // expected to provided in pairs. For example: inputPortTopPosX and inputPortTopPosY. However,
1252
+ // if they are not and only one of the pair is provided the functions in svg-canvas-utils.nodes.js
1253
+ // that calculate a x, y coordinate for the port will default to 0 if a value provided is undefined.
1254
+ // TODO - Remove this in a future major release.
1255
+ static convertPortPosInfo(layout) {
1256
+ const newLayout = layout;
1257
+
1258
+ if (!layout) {
1259
+ return newLayout;
1260
+ }
1261
+
1262
+ // If custom fields exist for input ports, write the values into the
1263
+ // inputPortPositions array and delete the redundant fields.
1264
+ if (isNumber(newLayout.inputPortTopPosX) || isNumber(newLayout.inputPortTopPosY)) {
1265
+ newLayout.inputPortPositions = [
1266
+ { x_pos: newLayout.inputPortTopPosX, y_pos: newLayout.inputPortTopPosY, pos: "topLeft" }
1267
+ ];
1268
+ delete newLayout.inputPortTopPosX;
1269
+ delete newLayout.inputPortTopPosY;
1270
+
1271
+ } else if (isNumber(newLayout.inputPortBottomPosX) || isNumber(newLayout.inputPortBottomPosY)) {
1272
+ newLayout.inputPortPositions = [
1273
+ { x_pos: newLayout.inputPortBottomPosX, y_pos: newLayout.inputPortBottomPosY, pos: "bottomLeft" }
1274
+ ];
1275
+ delete newLayout.inputPortBottomPosX;
1276
+ delete newLayout.inputPortBottomPosY;
1277
+
1278
+ } else if (isNumber(newLayout.inputPortLeftPosX) || isNumber(newLayout.inputPortLeftPosY)) {
1279
+ newLayout.inputPortPositions = [
1280
+ { x_pos: newLayout.inputPortLeftPosX, y_pos: newLayout.inputPortLeftPosY, pos: "topLeft" }
1281
+ ];
1282
+ delete newLayout.inputPortLeftPosX;
1283
+ delete newLayout.inputPortLeftPosY;
1284
+ }
1285
+
1286
+ // If custom fields exist for output ports, write the values into the
1287
+ // outputPortPositions array and delete the redundant fields.
1288
+ if (isNumber(newLayout.outputPortTopPosX) || isNumber(newLayout.outputPortTopPosY)) {
1289
+ newLayout.outputPortPositions = [
1290
+ { x_pos: newLayout.outputPortTopPosX, y_pos: newLayout.outputPortTopPosY, pos: "topLeft" }
1291
+ ];
1292
+ delete newLayout.outputPortTopPosX;
1293
+ delete newLayout.outputPortTopPosY;
1294
+
1295
+ } else if (isNumber(newLayout.outputPortBottomPosX) || isNumber(newLayout.outputPortBottomPosY)) {
1296
+ newLayout.outputPortPositions = [
1297
+ { x_pos: newLayout.outputPortBottomPosX, y_pos: newLayout.outputPortBottomPosY, pos: "bottomLeft" }
1298
+ ];
1299
+ delete newLayout.outputPortBottomPosX;
1300
+ delete newLayout.outputPortBottomPosY;
1301
+
1302
+ } else if (isNumber(newLayout.outputPortRightPosX) || isNumber(newLayout.outputPortRightPosY)) {
1303
+ newLayout.outputPortPositions = [
1304
+ { x_pos: newLayout.outputPortRightPosX, y_pos: newLayout.outputPortRightPosY, pos: "topRight" }
1305
+ ];
1306
+ delete newLayout.outputPortRightPosX;
1307
+ delete newLayout.outputPortRightPosY;
1308
+ }
1309
+ return newLayout;
1310
+ }
1240
1311
  }
@@ -83,7 +83,7 @@ $panel-border-color: $ui-03;
83
83
  background: $ui-01;
84
84
  transition: all 0.2s ease-in;
85
85
  &:hover {
86
- background: $interactive-01;
86
+ background: $interactive-03;
87
87
  }
88
88
  }
89
89
 
@@ -119,7 +119,7 @@ $panel-border-color: $ui-03;
119
119
  .toolbar-overflow-item {
120
120
  button:focus {
121
121
  border-color: transparent;
122
- box-shadow: inset 2px 2px $interactive-01, inset -6px -2px $interactive-01;
122
+ box-shadow: inset 2px 2px $interactive-03, inset -6px -2px $interactive-03;
123
123
  }
124
124
  // Set padding so overflow icon appears in the center (horizontally). This
125
125
  // offsets the 5px which are set in the code to make the overflow icon
@@ -252,7 +252,7 @@ $panel-border-color: $ui-03;
252
252
  & button:hover,
253
253
  & button:focus {
254
254
  background-color: $ui-03;
255
- color: $interactive-01;
255
+ color: $interactive-03;
256
256
  }
257
257
  & .return-to-previous-content {
258
258
  display: flex;
@@ -295,17 +295,17 @@ $panel-border-color: $ui-03;
295
295
  border-width: 2px;
296
296
  }
297
297
 
298
- .toolbar-item-content.notificationCounterIcon {
299
- &.error > div > svg > .dot {
298
+ .toolbar-item.notificationCounterIcon {
299
+ &.error .toolbar-icon .dot {
300
300
  fill: $support-01;
301
301
  }
302
- &.warning > div > svg > .dot {
302
+ &.warning .toolbar-icon .dot {
303
303
  fill: $support-03;
304
304
  }
305
- &.success > div > svg > .dot {
305
+ &.success .toolbar-icon .dot {
306
306
  fill: $support-02;
307
307
  }
308
- &.info > div > svg > .dot {
308
+ &.info .toolbar-icon .dot {
309
309
  fill: $support-04;
310
310
  }
311
311
  }
@@ -190,6 +190,7 @@ export const TOOLBAR_ARRANGE_VERTICALLY = "arrangeVertically";
190
190
  export const TOOLBAR_TOGGLE_NOTIFICATION_PANEL = "toggleNotificationPanel";
191
191
  export const TOOLBAR_OPEN_PALETTE = "paletteOpen";
192
192
  export const TOOLBAR_CLOSE_PALETTE = "paletteClose";
193
+ export const TOOLBAR_TOGGLE_PALETTE = "paletteToggle";
193
194
  export const TOOLBAR_EXPAND_SUPERNODE_IN_PLACE = "expandSuperNodeInPlace";
194
195
  export const TOOLBAR_COLLAPSE_SUPERNODE_IN_PLACE = "collapseSuperNodeInPlace";
195
196
  export const TOOLBAR_EXPAND_SUPERNODE_FULL_PAGE = "displaySubPipeline";
@@ -82,7 +82,7 @@ $comment-text-color: $text-01;
82
82
 
83
83
  // Comment properties
84
84
  $comment-text-font-size: 12px;
85
- $comment-text-font-weight: 400;
85
+ $comment-text-font-weight: 500;
86
86
  $comment-text-font-family: "ibm-plex-sans", Helvetica Neue, Arial, sans-serif;
87
87
  $comment-text-line-height: 14px;
88
88
  $comment-text-display-border: 8px;
@@ -123,7 +123,7 @@ $link-highlight-color: $support-04;
123
123
  // Supress the default focus highlighting with non-carbon color and round corners.
124
124
  outline: none;
125
125
  // Add our own focus highlighting with our own color and square corners
126
- box-shadow: 0 0 0 2px $interactive-01;
126
+ box-shadow: 0 0 0 2px $interactive-03;
127
127
  }
128
128
 
129
129
  /* Pull-out region rectangle used for object selection */
@@ -549,6 +549,7 @@ $link-highlight-color: $support-04;
549
549
  stroke: $node-port-input-arrow-connected-stroke-color;
550
550
  stroke-width: 1;
551
551
  fill: $node-port-input-arrow-connected-fill-color;
552
+ pointer-events: none;
552
553
  }
553
554
  }
554
555
 
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2017-2023 Elyra Authors
2
+ * Copyright 2017-2024 Elyra Authors
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1975,15 +1975,26 @@ export default class SVGCanvasRenderer {
1975
1975
  } else {
1976
1976
  this.addDynamicNodeIcons(d3Event, d, nodeGrp);
1977
1977
  }
1978
+ })
1979
+ // This will be called when the mouse cursor enters the node or moves out of
1980
+ // child elements of the node. Some child elements, like decorations, may have
1981
+ // their own tooltips so this will redisplay the node tooltip on exiting the decoration.
1982
+ .on("mouseover", (d3Event, d) => {
1983
+ d3Event.stopPropagation(); // Stop propagation in case we are in a sub-flow
1978
1984
  if (this.canOpenTip(TIP_TYPE_NODE)) {
1979
- this.canvasController.closeTip(); // Ensure existing tip is removed when moving pointer within an in-place supernode
1980
- this.canvasController.openTip({
1981
- id: this.getId("node_tip", d.id),
1982
- type: TIP_TYPE_NODE,
1983
- targetObj: d3Event.currentTarget,
1984
- pipelineId: this.activePipeline.id,
1985
- node: d
1986
- });
1985
+ const tipId = this.canvasController.getTipId(); // Id of current tip or null
1986
+ const nodeTipId = this.getId("node_tip", d.id);
1987
+
1988
+ if (tipId === null || tipId !== nodeTipId) {
1989
+ this.canvasController.closeTip();
1990
+ this.canvasController.openTip({
1991
+ id: nodeTipId,
1992
+ type: TIP_TYPE_NODE,
1993
+ targetObj: d3Event.currentTarget,
1994
+ pipelineId: this.activePipeline.id,
1995
+ node: d
1996
+ });
1997
+ }
1987
1998
  }
1988
1999
  })
1989
2000
  .on("mouseleave", (d3Event, d) => {
@@ -2507,7 +2518,7 @@ export default class SVGCanvasRenderer {
2507
2518
  attachDecGroupListeners(decGrps) {
2508
2519
  decGrps
2509
2520
  .on("mouseenter", (d3Event, dec) => {
2510
- if (this.canOpenTip(TIP_TYPE_DEC)) {
2521
+ if (this.canOpenTip(TIP_TYPE_DEC) && dec.tooltip) {
2511
2522
  this.canvasController.closeTip(); // Ensure any existing tip is removed
2512
2523
  this.canvasController.openTip({
2513
2524
  id: this.getId("dec_tip", dec.id),
@@ -2518,8 +2529,10 @@ export default class SVGCanvasRenderer {
2518
2529
  });
2519
2530
  }
2520
2531
  })
2521
- .on("mouseleave", (d3Event, d) => {
2522
- this.canvasController.closeTip();
2532
+ .on("mouseleave", (d3Event, dec) => {
2533
+ if (this.canOpenTip(TIP_TYPE_DEC) && dec.tooltip) {
2534
+ this.canvasController.closeTip();
2535
+ }
2523
2536
  });
2524
2537
  }
2525
2538
 
@@ -3371,135 +3384,202 @@ export default class SVGCanvasRenderer {
3371
3384
  }
3372
3385
 
3373
3386
  setPortPositionsForNode(node) {
3374
- if (this.canvasLayout.linkDirection === LINK_DIR_TOP_BOTTOM) {
3375
- this.setPortPositionsVertical(node, node.inputs, node.inputPortsWidth, node.layout.inputPortTopPosX, node.layout.inputPortTopPosY);
3376
- this.setPortPositionsVertical(node, node.outputs, node.outputPortsWidth, node.layout.outputPortBottomPosX, this.getOutputPortBottomPosY(node));
3377
- } else if (this.canvasLayout.linkDirection === LINK_DIR_BOTTOM_TOP) {
3378
- this.setPortPositionsVertical(node, node.inputs, node.inputPortsWidth, node.layout.inputPortBottomPosX, this.getInputPortBottomPosY(node));
3379
- this.setPortPositionsVertical(node, node.outputs, node.outputPortsWidth, node.layout.outputPortTopPosX, node.layout.outputPortTopPosY);
3387
+ if (this.canvasLayout.linkDirection === LINK_DIR_TOP_BOTTOM ||
3388
+ this.canvasLayout.linkDirection === LINK_DIR_BOTTOM_TOP) {
3389
+ this.setPortPositionsVertical(
3390
+ node, node.inputs, node.inputPortsWidth,
3391
+ node.layout.inputPortPositions,
3392
+ node.layout.inputPortAutoPosition);
3393
+ this.setPortPositionsVertical(
3394
+ node, node.outputs, node.outputPortsWidth,
3395
+ node.layout.outputPortPositions,
3396
+ node.layout.outputPortAutoPosition,
3397
+ this.config.enableSingleOutputPortDisplay);
3398
+
3380
3399
  } else {
3381
- this.setPortPositionsLeftRight(node, node.inputs, node.inputPortsHeight, node.layout.inputPortLeftPosX, node.layout.inputPortLeftPosY);
3382
- this.setPortPositionsLeftRight(node, node.outputs, node.outputPortsHeight,
3383
- this.nodeUtils.getNodeOutputPortRightPosX(node),
3384
- this.nodeUtils.getNodeOutputPortRightPosY(node),
3400
+ this.setPortPositionsHoriz(
3401
+ node, node.inputs, node.inputPortsHeight,
3402
+ node.layout.inputPortPositions,
3403
+ node.layout.inputPortAutoPosition);
3404
+ this.setPortPositionsHoriz(
3405
+ node, node.outputs, node.outputPortsHeight,
3406
+ node.layout.outputPortPositions,
3407
+ node.layout.outputPortAutoPosition,
3385
3408
  this.config.enableSingleOutputPortDisplay);
3386
3409
  }
3387
3410
  }
3388
3411
 
3389
- getOutputPortBottomPosY(node) {
3390
- return node.height + node.layout.outputPortBottomPosY;
3391
- }
3392
-
3393
- getInputPortBottomPosY(node) {
3394
- return node.height + node.layout.inputPortBottomPosY;
3395
- }
3396
-
3397
- setPortPositionsVertical(data, ports, portsWidth, xPos, yPos) {
3412
+ setPortPositionsVertical(node, ports, portsWidth, portPositions, autoPosition, displaySinglePort = false) {
3398
3413
  if (ports && ports.length > 0) {
3399
- if (data.width <= data.layout.defaultNodeWidth &&
3414
+ const xPos = this.nodeUtils.getNodePortPosX(portPositions[0], node);
3415
+ const yPos = this.nodeUtils.getNodePortPosY(portPositions[0], node);
3416
+
3417
+ if (node.width <= node.layout.defaultNodeWidth &&
3400
3418
  ports.length === 1) {
3401
3419
  ports[0].cx = xPos;
3402
3420
  ports[0].cy = yPos;
3403
3421
  } else {
3404
- let xPosition = 0;
3422
+ // If we are only going to display a single port, we set all the
3423
+ // port positions to be the same as if there is only one port.
3424
+ if (displaySinglePort) {
3425
+ this.setPortPositionsVerticalDisplaySingle(node, ports, xPos, yPos);
3405
3426
 
3406
- if (CanvasUtils.isExpandedSupernode(data)) {
3407
- const widthSvgArea = data.width - (2 * this.canvasLayout.supernodeSVGAreaPadding);
3408
- const remainingSpace = widthSvgArea - portsWidth;
3409
- xPosition = (2 * this.canvasLayout.supernodeSVGAreaPadding) + (remainingSpace / 2);
3427
+ } else if (autoPosition || CanvasUtils.isExpandedSupernode(node)) {
3428
+ this.setPortPositionsVerticalAuto(node, ports, portsWidth, yPos);
3410
3429
 
3411
- } else if (portsWidth < data.width) {
3412
- xPosition = (data.width - portsWidth) / 2;
3430
+ } else {
3431
+ this.setPortPositionsCustom(ports, portPositions, node, xPos, yPos);
3413
3432
  }
3433
+ }
3434
+ }
3435
+ }
3414
3436
 
3415
- xPosition += data.layout.portArcOffset;
3437
+ // If only a single port is to be displayed, this methods sets the x and y
3438
+ // coordinates of all the ports to the same values appropriately for either
3439
+ // regular nodes or expanded supernodes.
3440
+ setPortPositionsVerticalDisplaySingle(node, ports, xPos, yPos) {
3441
+ let xPosition = 0;
3442
+ if (CanvasUtils.isExpandedSupernode(node)) {
3443
+ const widthSvgArea = node.width - (2 * this.canvasLayout.supernodeSVGAreaPadding);
3444
+ xPosition = widthSvgArea / 2;
3416
3445
 
3417
- // Sub-flow binding node ports need to be spaced by the inverse of the
3418
- // zoom amount so that, after zoomToFit on the in-place sub-flow the
3419
- // binding node ports line up with those on the supernode. This is only
3420
- // necessary with binding nodes with mutiple ports.
3421
- let multiplier = 1;
3422
- if (CanvasUtils.isSuperBindingNode(data)) {
3423
- multiplier = 1 / this.zoomUtils.getZoomScale();
3424
- }
3446
+ } else {
3447
+ xPosition = xPos;
3448
+ }
3425
3449
 
3426
- ports.forEach((p) => {
3427
- xPosition += (data.layout.portArcRadius * multiplier);
3428
- p.cx = xPosition;
3429
- p.cy = yPos;
3430
- xPosition += ((data.layout.portArcRadius + data.layout.portArcSpacing) * multiplier);
3431
- });
3432
- }
3450
+ ports.forEach((p) => {
3451
+ p.cx = xPosition;
3452
+ p.cy = yPos;
3453
+ });
3454
+ }
3455
+
3456
+ // Sets the ports x and y coordinates for regular and expanded supernodes
3457
+ // when all ports are displayed in a normal manner (as opposed to when a
3458
+ // single port is displayed).
3459
+ setPortPositionsVerticalAuto(node, ports, portsWidth, yPos) {
3460
+ let xPosition = 0;
3461
+
3462
+ if (CanvasUtils.isExpandedSupernode(node)) {
3463
+ const widthSvgArea = node.width - (2 * this.canvasLayout.supernodeSVGAreaPadding);
3464
+ const remainingSpace = widthSvgArea - portsWidth;
3465
+ xPosition = this.canvasLayout.supernodeSVGAreaPadding + (remainingSpace / 2);
3466
+
3467
+ } else if (portsWidth < node.width) {
3468
+ xPosition = (node.width - portsWidth) / 2;
3433
3469
  }
3470
+
3471
+ xPosition += node.layout.portArcOffset;
3472
+
3473
+ // Sub-flow binding node ports need to be spaced by the inverse of the
3474
+ // zoom amount so that, after zoomToFit on the in-place sub-flow the
3475
+ // binding node ports line up with those on the supernode. This is only
3476
+ // necessary with binding nodes with mutiple ports.
3477
+ let multiplier = 1;
3478
+ if (CanvasUtils.isSuperBindingNode(node)) {
3479
+ multiplier = 1 / this.zoomUtils.getZoomScale();
3480
+ }
3481
+ ports.forEach((p) => {
3482
+ xPosition += (node.layout.portArcRadius * multiplier);
3483
+ p.cx = xPosition;
3484
+ p.cy = yPos;
3485
+ xPosition += ((node.layout.portArcRadius + node.layout.portArcSpacing) * multiplier);
3486
+ });
3434
3487
  }
3435
3488
 
3436
- setPortPositionsLeftRight(data, ports, portsHeight, xPos, yPos, displaySinglePort = false) {
3489
+ setPortPositionsHoriz(node, ports, portsHeight, portPositions, autoPosition, displaySinglePort = false) {
3437
3490
  if (ports && ports.length > 0) {
3438
- if (data.height <= data.layout.defaultNodeHeight &&
3491
+ const xPos = this.nodeUtils.getNodePortPosX(portPositions[0], node);
3492
+ const yPos = this.nodeUtils.getNodePortPosY(portPositions[0], node);
3493
+
3494
+ if (node.height <= node.layout.defaultNodeHeight &&
3439
3495
  ports.length === 1) {
3440
3496
  ports[0].cx = xPos;
3441
3497
  ports[0].cy = yPos;
3498
+
3442
3499
  } else {
3443
- // If we are only going to display a single port, we can set all the
3500
+ // If we are only going to display a single port, we set all the
3444
3501
  // port positions to be the same as if there is only one port.
3445
3502
  if (displaySinglePort) {
3446
- this.setPortPositionsLeftRightSinglePort(data, ports, xPos, yPos);
3503
+ this.setPortPositionsHorizDisplaySingle(node, ports, xPos, yPos);
3504
+
3505
+ } else if (autoPosition || CanvasUtils.isExpandedSupernode(node)) {
3506
+ this.setPortPositionsHorizAuto(node, ports, portsHeight, xPos);
3507
+
3447
3508
  } else {
3448
- this.setPortPositionsLeftRightAllPorts(data, ports, portsHeight, xPos, yPos);
3509
+ this.setPortPositionsCustom(ports, portPositions, node, xPos, yPos);
3449
3510
  }
3450
3511
  }
3451
3512
  }
3452
3513
  }
3453
3514
 
3515
+ // If only a single port is to be displayed, this methods sets the x and y
3516
+ // coordinates of all the ports to the same values appropriately for either
3517
+ // regular nodes or expanded supernodes.
3518
+ setPortPositionsHorizDisplaySingle(node, ports, xPos, yPos) {
3519
+ let yPosition = 0;
3520
+ if (CanvasUtils.isExpandedSupernode(node)) {
3521
+ const heightSvgArea = node.height - this.canvasLayout.supernodeTopAreaHeight - this.canvasLayout.supernodeSVGAreaPadding;
3522
+ yPosition = this.canvasLayout.supernodeTopAreaHeight + (heightSvgArea / 2);
3523
+
3524
+ } else {
3525
+ yPosition = yPos;
3526
+ }
3527
+
3528
+ ports.forEach((p) => {
3529
+ p.cx = xPos;
3530
+ p.cy = yPosition;
3531
+ });
3532
+ }
3533
+
3454
3534
  // Sets the ports x and y coordinates for regular and expanded supernodes
3455
3535
  // when all ports are displayed in a normal manner (as opposed to when a
3456
3536
  // single port is displayed).
3457
- setPortPositionsLeftRightAllPorts(data, ports, portsHeight, xPos, yPos) {
3537
+ setPortPositionsHorizAuto(node, ports, portsHeight, xPos) {
3458
3538
  let yPosition = 0;
3459
3539
 
3460
- if (CanvasUtils.isExpandedSupernode(data)) {
3461
- const heightSvgArea = data.height - this.canvasLayout.supernodeTopAreaHeight - this.canvasLayout.supernodeSVGAreaPadding;
3540
+ if (CanvasUtils.isExpandedSupernode(node)) {
3541
+ const heightSvgArea = node.height - this.canvasLayout.supernodeTopAreaHeight - this.canvasLayout.supernodeSVGAreaPadding;
3462
3542
  const remainingSpace = heightSvgArea - portsHeight;
3463
- yPosition = this.canvasLayout.supernodeTopAreaHeight + this.canvasLayout.supernodeSVGAreaPadding + (remainingSpace / 2);
3543
+ yPosition = this.canvasLayout.supernodeTopAreaHeight + (remainingSpace / 2);
3464
3544
 
3465
- } else if (portsHeight < data.height) {
3466
- yPosition = (data.height - portsHeight) / 2;
3545
+ } else if (portsHeight < node.height) {
3546
+ yPosition = (node.height - portsHeight) / 2;
3467
3547
  }
3468
3548
 
3469
- yPosition += data.layout.portArcOffset;
3549
+ yPosition += node.layout.portArcOffset;
3470
3550
 
3471
3551
  // Sub-flow binding node ports need to be spaced by the inverse of the
3472
3552
  // zoom amount so that, after zoomToFit on the in-place sub-flow the
3473
3553
  // binding node ports line up with those on the supernode. This is only
3474
3554
  // necessary with binding nodes with mutiple ports.
3475
3555
  let multiplier = 1;
3476
- if (CanvasUtils.isSuperBindingNode(data)) {
3556
+ if (CanvasUtils.isSuperBindingNode(node)) {
3477
3557
  multiplier = 1 / this.zoomUtils.getZoomScale();
3478
3558
  }
3479
3559
  ports.forEach((p) => {
3480
- yPosition += (data.layout.portArcRadius * multiplier);
3560
+ yPosition += (node.layout.portArcRadius * multiplier);
3481
3561
  p.cx = xPos;
3482
3562
  p.cy = yPosition;
3483
- yPosition += ((data.layout.portArcRadius + data.layout.portArcSpacing) * multiplier);
3563
+ yPosition += ((node.layout.portArcRadius + node.layout.portArcSpacing) * multiplier);
3484
3564
  });
3485
3565
  }
3486
3566
 
3487
- // If only a single port is to be displayed, this methods sets the x and y
3488
- // coordinates of all the ports to the same values appropriately for either
3489
- // regular nodes or expanded supernodes.
3490
- setPortPositionsLeftRightSinglePort(data, ports, xPos, yPos) {
3491
- let yPosition = 0;
3492
- if (CanvasUtils.isExpandedSupernode(data)) {
3493
- const heightSvgArea = data.height - this.canvasLayout.supernodeTopAreaHeight - this.canvasLayout.supernodeSVGAreaPadding;
3494
- yPosition = this.canvasLayout.supernodeTopAreaHeight + (heightSvgArea / 2);
3567
+ // Sets the node's port positions based on the custom positions provided
3568
+ // by the application in the portPositions array.
3569
+ setPortPositionsCustom(ports, portPositions, node, zerothX, zerothY) {
3570
+ let xPos = zerothX;
3571
+ let yPos = zerothY;
3495
3572
 
3496
- } else {
3497
- yPosition = yPos;
3498
- }
3499
-
3500
- ports.forEach((p) => {
3573
+ ports.forEach((p, i) => {
3574
+ // No need to recalculate the zeroth position AND if there are more
3575
+ // ports than portPositions just use the last port position for all
3576
+ // subsequent ports.
3577
+ if (i > 0 && i < portPositions.length) {
3578
+ xPos = this.nodeUtils.getNodePortPosX(portPositions[i], node);
3579
+ yPos = this.nodeUtils.getNodePortPosY(portPositions[i], node);
3580
+ }
3501
3581
  p.cx = xPos;
3502
- p.cy = yPosition;
3582
+ p.cy = yPos;
3503
3583
  });
3504
3584
  }
3505
3585
 
@@ -4054,17 +4134,27 @@ export default class SVGCanvasRenderer {
4054
4134
  if (this.config.enableContextToolbar) {
4055
4135
  this.addContextToolbar(d3Event, link, "link");
4056
4136
  }
4057
-
4137
+ })
4138
+ // This will be called when the mouse cursor enters the link or moves out of
4139
+ // child elements of the link. Some child elements, like decorations, may have
4140
+ // their own tooltips so this will redisplay the link tooltip on exiting the decoration.
4141
+ .on("mouseover", (d3Event, link) => {
4142
+ d3Event.stopPropagation(); // Stop propagation in case we are in a sub-flow
4058
4143
  if (this.canOpenTip(TIP_TYPE_LINK)) {
4059
- this.canvasController.closeTip();
4060
- this.canvasController.openTip({
4061
- id: this.getId("link_tip", link.id),
4062
- type: TIP_TYPE_LINK,
4063
- targetObj: targetObj,
4064
- mousePos: { x: d3Event.clientX, y: d3Event.clientY },
4065
- pipelineId: this.activePipeline.id,
4066
- link: link
4067
- });
4144
+ const tipId = this.canvasController.getTipId(); // Id of current tip or null
4145
+ const linkTipId = this.getId("link_tip", link.id);
4146
+
4147
+ if (tipId === null || tipId !== linkTipId) {
4148
+ this.canvasController.closeTip();
4149
+ this.canvasController.openTip({
4150
+ id: linkTipId,
4151
+ type: TIP_TYPE_LINK,
4152
+ targetObj: d3Event.currentTarget,
4153
+ mousePos: { x: d3Event.clientX, y: d3Event.clientY },
4154
+ pipelineId: this.activePipeline.id,
4155
+ link: link
4156
+ });
4157
+ }
4068
4158
  }
4069
4159
  })
4070
4160
  .on("mouseleave", (d3Event, link) => {
@@ -69,7 +69,7 @@ export default class SvgCanvasExternal {
69
69
  out.cy = outputPos.cy / k;
70
70
  });
71
71
  }
72
- this.ren.displayLinks();
72
+ this.ren.displayMovedLinks();
73
73
  }
74
74
 
75
75
  setNodesProperties(newProps) {
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2017-2023 Elyra Authors
2
+ * Copyright 2017-2024 Elyra Authors
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -245,34 +245,29 @@ export default class SvgCanvasLinks {
245
245
  }
246
246
 
247
247
  getNodeLinkCoordsForPorts(srcNode, srcPortId, trgNode, trgPortId) {
248
- let srcX = srcNode.width + srcNode.layout.outputPortRightPosX;
249
- let srcY = srcNode.layout.outputPortRightPosY;
250
- let trgX = trgNode.layout.inputPortLeftPosX;
251
- let trgY = trgNode.layout.inputPortLeftPosY;
252
-
253
- if (this.canvasLayout.linkDirection === LINK_DIR_TOP_BOTTOM) {
254
- srcX = srcNode.layout.outputPortBottomPosX;
255
- srcY = srcNode.height + srcNode.layout.outputPortBottomPosY;
256
- trgX = trgNode.layout.inputPortTopPosX;
257
- trgY = trgNode.layout.inputPortTopPosY;
258
-
259
- } else if (this.canvasLayout.linkDirection === LINK_DIR_BOTTOM_TOP) {
260
- srcX = srcNode.layout.outputPortBottomPosX;
261
- srcY = srcNode.layout.outputPortBottomPosY;
262
- trgX = trgNode.layout.inputPortTopPosX;
263
- trgY = trgNode.height + trgNode.layout.inputPortTopPosY;
264
- }
248
+ let srcX;
249
+ let srcY;
250
+ let trgX;
251
+ let trgY;
265
252
 
266
253
  if (srcNode.outputs && srcNode.outputs.length > 0) {
267
254
  const port = srcNode.outputs.find((srcPort) => srcPort.id === srcPortId);
268
255
  srcX = port ? port.cx : srcX;
269
256
  srcY = port ? port.cy : srcY;
257
+
258
+ } else {
259
+ srcX = this.nodeUtils.getNodePortPosX(srcNode.layout.outputPortPositions[0], srcNode);
260
+ srcY = this.nodeUtils.getNodePortPosY(srcNode.layout.outputPortPositions[0], srcNode);
270
261
  }
271
262
 
272
263
  if (trgNode.inputs && trgNode.inputs.length > 0) {
273
264
  const port = trgNode.inputs.find((trgPort) => trgPort.id === trgPortId);
274
265
  trgX = port ? port.cx : trgX;
275
266
  trgY = port ? port.cy : trgY;
267
+
268
+ } else {
269
+ trgX = this.nodeUtils.getNodePortPosX(trgNode.layout.inputPortPositions[0], trgNode);
270
+ trgY = this.nodeUtils.getNodePortPosY(trgNode.layout.inputPortPositions[0], trgNode);
276
271
  }
277
272
 
278
273
  return {
@@ -284,31 +279,32 @@ export default class SvgCanvasLinks {
284
279
  }
285
280
 
286
281
  getAssociationCurveLinkCoords(srcNode, trgNode, assocLinkVariation) {
287
- let x1 = 0;
288
- let x2 = 0;
282
+ let srcX = 0;
283
+ let trgX = 0;
289
284
 
290
285
  if (assocLinkVariation === ASSOC_VAR_CURVE_RIGHT) {
291
- x1 = srcNode.x_pos + srcNode.width;
292
- x2 = trgNode.x_pos;
286
+ srcX = srcNode.width;
287
+ trgX = 0;
293
288
 
294
289
  } else if (assocLinkVariation === ASSOC_VAR_CURVE_LEFT) {
295
- x1 = srcNode.x_pos;
296
- x2 = trgNode.x_pos + trgNode.width;
290
+ srcX = 0;
291
+ trgX = trgNode.width;
297
292
 
298
293
  } else if (assocLinkVariation === ASSOC_VAR_DOUBLE_BACK_LEFT) {
299
- x1 = srcNode.x_pos;
300
- x2 = trgNode.x_pos;
294
+ srcX = 0;
295
+ trgX = 0;
301
296
 
302
297
  } else {
303
- x1 = srcNode.x_pos + srcNode.width;
304
- x2 = trgNode.x_pos + trgNode.width;
298
+ srcX = srcNode.width;
299
+ trgX = trgNode.width;
305
300
  }
306
301
 
307
302
  return {
308
- x1: x1,
309
- y1: srcNode.y_pos + srcNode.layout.outputPortRightPosY,
310
- x2: x2,
311
- y2: trgNode.y_pos + trgNode.layout.inputPortLeftPosY };
303
+ x1: srcNode.x_pos + srcX,
304
+ y1: srcNode.y_pos + this.nodeUtils.getNodePortPosY(srcNode.layout.outputPortPositions[0], srcNode),
305
+ x2: trgNode.x_pos + trgX,
306
+ y2: trgNode.y_pos + this.nodeUtils.getNodePortPosY(trgNode.layout.inputPortPositions[0], trgNode)
307
+ };
312
308
  }
313
309
 
314
310
  getCommentLinkCoords(srcComment, trgNode) {