@elyra/canvas 12.23.1 → 12.24.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 (195) hide show
  1. package/dist/canvas-constants-07dbe4b7.js +2 -0
  2. package/dist/{canvas-constants-ab55d0fd.js.map → canvas-constants-07dbe4b7.js.map} +1 -1
  3. package/dist/canvas-constants-ba465147.js +2 -0
  4. package/dist/canvas-constants-ba465147.js.map +1 -0
  5. package/dist/canvas-controller-60ed1f25.js +2 -0
  6. package/dist/canvas-controller-60ed1f25.js.map +1 -0
  7. package/dist/canvas-controller-6239cacc.js +2 -0
  8. package/dist/canvas-controller-6239cacc.js.map +1 -0
  9. package/dist/{canvas-logger-fa8cef5b.js → canvas-logger-27d3180d.js} +2 -2
  10. package/dist/{canvas-logger-fa8cef5b.js.map → canvas-logger-27d3180d.js.map} +1 -1
  11. package/dist/{canvas-logger-3459dfc2.js → canvas-logger-bb537fb3.js} +2 -2
  12. package/dist/{canvas-logger-3459dfc2.js.map → canvas-logger-bb537fb3.js.map} +1 -1
  13. package/dist/common-canvas-4ae99af6.js +2 -0
  14. package/dist/common-canvas-4ae99af6.js.map +1 -0
  15. package/dist/common-canvas-86633e44.js +2 -0
  16. package/dist/common-canvas-86633e44.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-2bc0b14a.js +2 -0
  20. package/dist/common-properties-2bc0b14a.js.map +1 -0
  21. package/dist/common-properties-56bf68a6.js +2 -0
  22. package/dist/common-properties-56bf68a6.js.map +1 -0
  23. package/dist/createClass-826941b3.js +2 -0
  24. package/dist/createClass-826941b3.js.map +1 -0
  25. package/dist/createClass-be661622.js +2 -0
  26. package/dist/createClass-be661622.js.map +1 -0
  27. package/dist/{datarecord-metadata-v3-schema-03db5d5d.js → datarecord-metadata-v3-schema-3323a91e.js} +2 -2
  28. package/dist/{datarecord-metadata-v3-schema-03db5d5d.js.map → datarecord-metadata-v3-schema-3323a91e.js.map} +1 -1
  29. package/dist/{datarecord-metadata-v3-schema-07d7682c.js → datarecord-metadata-v3-schema-93ec5562.js} +2 -2
  30. package/dist/{datarecord-metadata-v3-schema-07d7682c.js.map → datarecord-metadata-v3-schema-93ec5562.js.map} +1 -1
  31. package/dist/en-7201b548.js +2 -0
  32. package/dist/{en-8647c347.js.map → en-7201b548.js.map} +1 -1
  33. package/dist/en-a08356c8.js +2 -0
  34. package/dist/{en-7a0f1db1.js.map → en-a08356c8.js.map} +1 -1
  35. package/dist/extends-11efb86b.js +7 -0
  36. package/dist/extends-11efb86b.js.map +1 -0
  37. package/dist/extends-bb395e42.js +7 -0
  38. package/dist/extends-bb395e42.js.map +1 -0
  39. package/dist/flexible-table-989859ec.js +2 -0
  40. package/dist/flexible-table-989859ec.js.map +1 -0
  41. package/dist/flexible-table-d51a7d72.js +2 -0
  42. package/dist/flexible-table-d51a7d72.js.map +1 -0
  43. package/dist/getPrototypeOf-1e698126.js +2 -0
  44. package/dist/getPrototypeOf-1e698126.js.map +1 -0
  45. package/dist/getPrototypeOf-3751add9.js +2 -0
  46. package/dist/getPrototypeOf-3751add9.js.map +1 -0
  47. package/dist/icon-037ad6d1.js +2 -0
  48. package/dist/{icon-816af0e7.js.map → icon-037ad6d1.js.map} +1 -1
  49. package/dist/icon-b619470c.js +2 -0
  50. package/dist/{icon-2c16236a.js.map → icon-b619470c.js.map} +1 -1
  51. package/dist/{index-2f6be19d.js → index-46a80c08.js} +2 -2
  52. package/dist/{index-2f6be19d.js.map → index-46a80c08.js.map} +1 -1
  53. package/dist/index-b527a82d.js +2 -0
  54. package/dist/{index-6f739fa1.js.map → index-b527a82d.js.map} +1 -1
  55. package/dist/isArrayLikeObject-a9c7973b.js +1 -1
  56. package/dist/isArrayLikeObject-a9c7973b.js.map +1 -1
  57. package/dist/isArrayLikeObject-f3b27f64.js +1 -1
  58. package/dist/isArrayLikeObject-f3b27f64.js.map +1 -1
  59. package/dist/lib/canvas-controller.es.js +1 -1
  60. package/dist/lib/canvas-controller.js +1 -1
  61. package/dist/lib/canvas.es.js +1 -1
  62. package/dist/lib/canvas.js +1 -1
  63. package/dist/lib/command-stack.es.js +1 -1
  64. package/dist/lib/command-stack.js +1 -1
  65. package/dist/lib/context-menu.es.js +1 -1
  66. package/dist/lib/context-menu.js +1 -1
  67. package/dist/lib/properties/field-picker.es.js +1 -1
  68. package/dist/lib/properties/field-picker.js +1 -1
  69. package/dist/lib/properties/flexible-table.es.js +1 -1
  70. package/dist/lib/properties/flexible-table.js +1 -1
  71. package/dist/lib/properties.es.js +1 -1
  72. package/dist/lib/properties.js +1 -1
  73. package/dist/lib/tooltip.es.js +1 -1
  74. package/dist/lib/tooltip.js +1 -1
  75. package/dist/styles/common-canvas.min.css +1 -1
  76. package/dist/styles/common-canvas.min.css.map +1 -1
  77. package/dist/toolbar-3f93ec4b.js +2 -0
  78. package/dist/toolbar-3f93ec4b.js.map +1 -0
  79. package/dist/toolbar-e4c551ae.js +2 -0
  80. package/dist/toolbar-e4c551ae.js.map +1 -0
  81. package/locales/command-actions/locales/en.json +1 -1
  82. package/locales/command-actions/locales/eo.json +41 -41
  83. package/locales/common-canvas/locales/en.json +1 -0
  84. package/locales/common-canvas/locales/eo.json +1 -0
  85. package/locales/common-properties/locales/de.json +10 -1
  86. package/locales/common-properties/locales/en.json +4 -1
  87. package/locales/common-properties/locales/eo.json +23 -18
  88. package/locales/common-properties/locales/es.json +10 -1
  89. package/locales/common-properties/locales/fr.json +10 -1
  90. package/locales/common-properties/locales/it.json +10 -1
  91. package/locales/common-properties/locales/ja.json +10 -1
  92. package/locales/common-properties/locales/ko.json +10 -1
  93. package/locales/common-properties/locales/pt-br.json +10 -1
  94. package/locales/common-properties/locales/sv.json +10 -1
  95. package/locales/common-properties/locales/zh-CN.json +10 -1
  96. package/locales/common-properties/locales/zh-TW.json +10 -1
  97. package/package.json +1 -1
  98. package/src/common-canvas/canvas-controller.js +38 -4
  99. package/src/common-canvas/svg-canvas-d3.js +12 -0
  100. package/src/common-canvas/svg-canvas-renderer.js +244 -66
  101. package/src/common-canvas/svg-canvas-utils-links.js +37 -7
  102. package/src/common-canvas/svg-canvas-utils-markdown.js +0 -2
  103. package/src/common-canvas/svg-canvas-utils-textarea.js +56 -43
  104. package/src/common-properties/components/editor-form/editor-form.jsx +19 -5
  105. package/src/common-properties/components/editor-form/editor-form.scss +30 -3
  106. package/src/common-properties/components/field-picker/field-picker.jsx +18 -59
  107. package/src/common-properties/components/field-picker/field-picker.scss +15 -24
  108. package/src/common-properties/components/flexible-table/flexible-table.jsx +32 -16
  109. package/src/common-properties/components/flexible-table/flexible-table.scss +6 -12
  110. package/src/common-properties/components/properties-modal/properties-modal.jsx +3 -1
  111. package/src/common-properties/components/properties-modal/properties-modal.scss +1 -0
  112. package/src/common-properties/components/table-buttons/table-buttons.jsx +1 -0
  113. package/src/common-properties/components/table-buttons/table-buttons.scss +4 -26
  114. package/src/common-properties/components/virtualized-table/virtualized-table.jsx +6 -5
  115. package/src/common-properties/constants/constants.js +11 -2
  116. package/src/common-properties/controls/abstract-table.jsx +12 -4
  117. package/src/common-properties/controls/datefield/datefield.jsx +1 -1
  118. package/src/common-properties/controls/dropdown/dropdown.jsx +3 -3
  119. package/src/common-properties/controls/expression/expression-builder/expression-select-field-function.jsx +11 -2
  120. package/src/common-properties/controls/expression/expression-toggle/expression-toggle.jsx +5 -6
  121. package/src/common-properties/controls/expression/expression.jsx +3 -1
  122. package/src/common-properties/controls/expression/expression.scss +1 -2
  123. package/src/common-properties/controls/list/list.jsx +1 -1
  124. package/src/common-properties/controls/multiselect/multiselect.jsx +2 -2
  125. package/src/common-properties/controls/numberfield/numberfield.jsx +30 -6
  126. package/src/common-properties/controls/passwordfield/passwordfield.jsx +13 -2
  127. package/src/common-properties/controls/radioset/radioset.scss +1 -5
  128. package/src/common-properties/controls/selectcolumns/selectcolumns.jsx +1 -1
  129. package/src/common-properties/controls/someofselect/someofselect.jsx +1 -1
  130. package/src/common-properties/controls/textarea/textarea.jsx +2 -2
  131. package/src/common-properties/controls/textfield/textfield.jsx +1 -1
  132. package/src/common-properties/controls/timefield/timefield.jsx +1 -1
  133. package/src/common-properties/form/ControlInfo.js +3 -1
  134. package/src/common-properties/form/EditorForm.js +11 -11
  135. package/src/common-properties/index.scss +2 -4
  136. package/src/common-properties/panels/control/control.jsx +1 -0
  137. package/src/common-properties/panels/control/control.scss +12 -0
  138. package/src/common-properties/panels/sub-panel/invoker.jsx +2 -0
  139. package/src/common-properties/panels/sub-panel/sub-panel.scss +6 -0
  140. package/src/common-properties/panels/subtabs/subtabs.jsx +13 -3
  141. package/src/common-properties/panels/subtabs/subtabs.scss +62 -0
  142. package/src/common-properties/panels/tearsheet/tearsheet.jsx +64 -7
  143. package/src/common-properties/panels/tearsheet/tearsheet.scss +84 -18
  144. package/src/common-properties/properties-controller.js +4 -0
  145. package/src/common-properties/properties-main/properties-main.jsx +17 -1
  146. package/src/object-model/api-pipeline.js +1 -6
  147. package/src/object-model/canvas-in-handler.js +6 -3
  148. package/src/object-model/layout-dimensions.js +12 -0
  149. package/src/object-model/object-model.js +7 -39
  150. package/src/object-model/redux/canvas-store.js +55 -0
  151. package/src/toolbar/toolbar-action-item.jsx +3 -1
  152. package/src/toolbar/toolbar-overflow-item.jsx +3 -1
  153. package/src/toolbar/toolbar.jsx +6 -2
  154. package/src/toolbar/toolbar.scss +21 -0
  155. package/stats.html +1 -1
  156. package/dist/canvas-constants-09ffa4d4.js +0 -2
  157. package/dist/canvas-constants-09ffa4d4.js.map +0 -1
  158. package/dist/canvas-constants-ab55d0fd.js +0 -2
  159. package/dist/canvas-controller-3a399ae6.js +0 -2
  160. package/dist/canvas-controller-3a399ae6.js.map +0 -1
  161. package/dist/canvas-controller-c046093c.js +0 -2
  162. package/dist/canvas-controller-c046093c.js.map +0 -1
  163. package/dist/common-canvas-088c1a4b.js +0 -2
  164. package/dist/common-canvas-088c1a4b.js.map +0 -1
  165. package/dist/common-canvas-7676cc1b.js +0 -2
  166. package/dist/common-canvas-7676cc1b.js.map +0 -1
  167. package/dist/common-properties-9d77f8e1.js +0 -2
  168. package/dist/common-properties-9d77f8e1.js.map +0 -1
  169. package/dist/common-properties-a31de521.js +0 -2
  170. package/dist/common-properties-a31de521.js.map +0 -1
  171. package/dist/createClass-72b049bc.js +0 -2
  172. package/dist/createClass-72b049bc.js.map +0 -1
  173. package/dist/createClass-d5cac0b7.js +0 -2
  174. package/dist/createClass-d5cac0b7.js.map +0 -1
  175. package/dist/en-7a0f1db1.js +0 -2
  176. package/dist/en-8647c347.js +0 -2
  177. package/dist/extends-87da7df3.js +0 -7
  178. package/dist/extends-87da7df3.js.map +0 -1
  179. package/dist/extends-dc95dba8.js +0 -7
  180. package/dist/extends-dc95dba8.js.map +0 -1
  181. package/dist/flexible-table-59ad2c83.js +0 -2
  182. package/dist/flexible-table-59ad2c83.js.map +0 -1
  183. package/dist/flexible-table-5c4fbb7b.js +0 -2
  184. package/dist/flexible-table-5c4fbb7b.js.map +0 -1
  185. package/dist/getPrototypeOf-4e282dd3.js +0 -2
  186. package/dist/getPrototypeOf-4e282dd3.js.map +0 -1
  187. package/dist/getPrototypeOf-b3806813.js +0 -2
  188. package/dist/getPrototypeOf-b3806813.js.map +0 -1
  189. package/dist/icon-2c16236a.js +0 -2
  190. package/dist/icon-816af0e7.js +0 -2
  191. package/dist/index-6f739fa1.js +0 -2
  192. package/dist/toolbar-2ef99bd8.js +0 -2
  193. package/dist/toolbar-2ef99bd8.js.map +0 -1
  194. package/dist/toolbar-cb967e26.js +0 -2
  195. package/dist/toolbar-cb967e26.js.map +0 -1
@@ -87,7 +87,11 @@ export default class SvgCanvasLinks {
87
87
  // Returns the lineArray passed in with connection path info added to it.
88
88
  addConnectionPaths(links) {
89
89
  links.forEach((link) => {
90
- link.pathInfo = this.getConnectorPathInfo(link);
90
+ // Only necessary to get the path info, if the start and end coords of
91
+ // the link have changed.
92
+ if (link.coordsUpdated) {
93
+ link.pathInfo = this.getConnectorPathInfo(link);
94
+ }
91
95
  });
92
96
  return links;
93
97
  }
@@ -592,11 +596,13 @@ export default class SvgCanvasLinks {
592
596
  elements.push(
593
597
  { p: "M", x: data.x1, y: data.y1 },
594
598
  { p: "L", x: (corner1X - this.canvasLayout.elbowSize), y: corner1Y },
595
- { p: "Q", x: corner1X, y: corner1Y, x2: corner1X, y2: (corner1Y + elbowYOffset) }
596
599
  );
597
600
 
598
601
  if (extraSegments === false) {
599
- elements.push({ p: "L", x: corner2X, y: (corner2Y - elbowYOffset) });
602
+ elements.push(
603
+ { p: "Q", x: corner1X, y: corner1Y, x2: corner1X, y2: (corner1Y + elbowYOffset) },
604
+ { p: "L", x: corner2X, y: (corner2Y - elbowYOffset) }
605
+ );
600
606
 
601
607
  centerPoint.x = corner2X;
602
608
  centerPoint.y = corner2Y;
@@ -606,6 +612,14 @@ export default class SvgCanvasLinks {
606
612
  ? this.calculateMidY(data, topSrc, bottomSrc, topTrg, bottomTrg)
607
613
  : corner2Y - (corner2Y - corner1Y) / 2;
608
614
 
615
+ if (xDiff < 0) {
616
+ if (midY >= bottomSrc) {
617
+ elbowYOffset = this.canvasLayout.elbowSize;
618
+ } else {
619
+ elbowYOffset = -this.canvasLayout.elbowSize;
620
+ }
621
+ }
622
+
609
623
  let corner2Ya;
610
624
  let corner2Yb;
611
625
 
@@ -613,12 +627,14 @@ export default class SvgCanvasLinks {
613
627
  (midY > bottomTrg && midY > bottomSrc)) {
614
628
  corner2Ya = midY - elbowYOffset;
615
629
  corner2Yb = corner2Y + elbowYOffset;
630
+
616
631
  } else {
617
632
  corner2Ya = midY + elbowYOffset;
618
633
  corner2Yb = corner2Y - elbowYOffset;
619
634
  }
620
635
 
621
636
  elements.push(
637
+ { p: "Q", x: corner1X, y: corner1Y, x2: corner1X, y2: (corner1Y + elbowYOffset) },
622
638
  { p: "L", x: corner1X, y: (midY - elbowYOffset) },
623
639
  { p: "Q", x: corner1X, y: midY, x2: (corner1X - elbowXOffset), y2: midY },
624
640
  { p: "L", x: (corner2X + elbowXOffset), y: midY },
@@ -643,19 +659,33 @@ export default class SvgCanvasLinks {
643
659
  // the target node is to the left of the source node. This is either the
644
660
  // center point between the source and target nodes, if there is room to draw
645
661
  // the line between them, or it is the coordinate of a wrap-around line to be
646
- // drawn around the outside of the source and target nodes.
662
+ // drawn around the outside of the source and target nodes. The direction of
663
+ // the wrap around line is chosen based on which is the shortest route from
664
+ // the source port to the target port.
647
665
  calculateMidY(data, topSrc, bottomSrc, topTrg, bottomTrg) {
648
666
  let midY;
649
667
 
650
668
  if (topTrg >= bottomSrc + this.canvasLayout.wrapAroundNodePadding) {
651
669
  midY = bottomSrc + ((topTrg - bottomSrc) / 2);
670
+
652
671
  } else if (bottomTrg <= topSrc - this.canvasLayout.wrapAroundNodePadding) {
653
672
  midY = bottomTrg + ((topSrc - bottomTrg) / 2);
673
+
654
674
  } else {
655
- if (data.y1 > data.y2) {
656
- midY = Math.min(topSrc, topTrg) - this.canvasLayout.wrapAroundSpacing;
675
+ const maxBottom = Math.max(bottomSrc, bottomTrg);
676
+ const srcBottomInc = maxBottom - data.y1;
677
+ const trgBottomInc = maxBottom - data.y2;
678
+
679
+ const minTop = Math.min(topSrc, topTrg);
680
+ const srcTopInc = data.y1 - minTop;
681
+ const trgTopInc = data.y2 - minTop;
682
+
683
+ // Set the mid-point based in the shortest distance from the source port
684
+ // on the source node to the target port on the target node.
685
+ if (srcBottomInc + trgBottomInc > srcTopInc + trgTopInc) {
686
+ midY = minTop - this.canvasLayout.wrapAroundSpacing;
657
687
  } else {
658
- midY = Math.max(bottomSrc, bottomTrg) + this.canvasLayout.wrapAroundSpacing;
688
+ midY = maxBottom + this.canvasLayout.wrapAroundSpacing;
659
689
  }
660
690
  }
661
691
 
@@ -502,8 +502,6 @@ export default class SvgCanvasUtilsComments {
502
502
  finished = true; // As soon as we hit a line without a number we finished renumbering
503
503
  }
504
504
  }
505
-
506
- newText += "\n";
507
505
  });
508
506
  return newText;
509
507
  }
@@ -127,7 +127,7 @@ export default class SvgCanvasTextArea {
127
127
  // When Cypress tests are running a call to focus() in addTextToTextArea()
128
128
  // can cause an incorrect blur event to be generated for the text toolbar
129
129
  // (where relatedTarget is null). This flag therefore allows us to avoid
130
- // thus blue events that occur while addTextToTextArea() is executing.
130
+ // that blur event that occurs while addTextToTextArea() is executing.
131
131
  if (this.addingTextToTextArea) {
132
132
  return;
133
133
  }
@@ -143,11 +143,7 @@ export default class SvgCanvasTextArea {
143
143
 
144
144
  // If the blur event is ocurring for an object outside of the textarea and
145
145
  // text toolbar we save the current text and close the textarea.
146
- const commentParent = d3.select(this.editingTextData.parentDomObj);
147
- const foreignObject = commentParent.selectAll(".d3-foreign-object-text-entry");
148
- const commentEntry = this.canvasDiv.selectAll(".d3-comment-entry");
149
- const commentEntryElement = commentEntry.node();
150
- this.saveAndCloseTextArea(foreignObject, this.editingTextData, commentEntryElement.value, evt);
146
+ this.completeEditing(evt);
151
147
  }
152
148
 
153
149
  // Applies a markdown action to the comment text being edited using
@@ -207,13 +203,13 @@ export default class SvgCanvasTextArea {
207
203
  this.addingTextToTextArea = false;
208
204
  }
209
205
 
210
- autoSizeComment(textArea, foreignObject, data) {
206
+ autoSizeComment(textArea, data) {
211
207
  this.logger.log("autoSizeComment - textAreaHt = " + this.textAreaHeight + " scroll ht = " + textArea.scrollHeight);
212
208
 
213
209
  const scrollHeight = textArea.scrollHeight + SCROLL_PADDING;
214
210
  if (this.textAreaHeight < scrollHeight) {
215
211
  this.textAreaHeight = scrollHeight;
216
- foreignObject.style("height", this.textAreaHeight + "px");
212
+ this.foreignObject.style("height", this.textAreaHeight + "px");
217
213
  this.activePipeline.getComment(data.id).height = this.textAreaHeight;
218
214
  this.displayCommentsCallback();
219
215
  this.displayLinksCallback();
@@ -241,9 +237,12 @@ export default class SvgCanvasTextArea {
241
237
  }
242
238
 
243
239
  displayNodeLabelTextArea(node, parentDomObj) {
244
- d3.select(parentDomObj)
245
- .selectAll("div")
246
- .attr("style", "display:none;");
240
+ // Save the current style for the display <div> and set the style so the
241
+ // <div> is hidden while the text area is displayed on top of it. This
242
+ // prevents the <div> from protruding below the text area.
243
+ this.displayDiv = d3.select(parentDomObj).selectAll(".d3-foreign-object-node-label div");
244
+ this.displayDivStyle = this.displayDiv.attr("style");
245
+ this.displayDiv.attr("style", "display:none;");
247
246
 
248
247
  this.editingTextData = {
249
248
  id: node.id,
@@ -260,7 +259,7 @@ export default class SvgCanvasTextArea {
260
259
  parentDomObj: parentDomObj,
261
260
  autoSizeCallback: this.autoSizeMultiLineLabel.bind(this),
262
261
  saveTextChangesCallback: this.saveNodeLabelChanges.bind(this),
263
- closeTextAreaCallback: this.closeNodeLabelTextArea.bind(this)
262
+ closeTextAreaCallback: this.closeEntryTextArea.bind(this)
264
263
  };
265
264
  this.displayTextArea(this.editingTextData);
266
265
  }
@@ -270,7 +269,7 @@ export default class SvgCanvasTextArea {
270
269
  // characters for the label, if one is provided, is not exceeded.
271
270
  // This callback works for editable multi-line node labels and also
272
271
  // editable multi-line text decorations for either nodes or links.
273
- autoSizeMultiLineLabel(textArea, foreignObject, data) {
272
+ autoSizeMultiLineLabel(textArea, data) {
274
273
  this.logger.log("autoSizeNodeLabel - textAreaHt = " + this.textAreaHeight + " scroll ht = " + textArea.scrollHeight);
275
274
 
276
275
  // Restrict max characters in case text was pasted in to the text area.
@@ -281,10 +280,10 @@ export default class SvgCanvasTextArea {
281
280
  // Temporarily set the height to zero so the scrollHeight will get set to
282
281
  // the full height of the text in the textarea. This allows us to close up
283
282
  // the text area when the lines of text reduce.
284
- foreignObject.style("height", 0);
283
+ this.foreignObject.style("height", 0);
285
284
  const scrollHeight = textArea.scrollHeight + SCROLL_PADDING;
286
285
  this.textAreaHeight = scrollHeight;
287
- foreignObject.style("height", this.textAreaHeight + "px");
286
+ this.foreignObject.style("height", this.textAreaHeight + "px");
288
287
  }
289
288
 
290
289
  saveNodeLabelChanges(id, newText, newHeight, taData) {
@@ -298,19 +297,24 @@ export default class SvgCanvasTextArea {
298
297
  this.canvasController.editActionHandler(data);
299
298
  }
300
299
 
301
- // Called when the node label text area is closed. Sets the style of the
302
- // div for the node label so the label is displayed (because it was hidden
303
- // when the text area opened).
304
- closeNodeLabelTextArea(nodeId) {
305
- d3.select(this.editingTextData.parentDomObj)
306
- .selectAll("div")
307
- .attr("style", null);
300
+ // Called when the node label or decoration label text area is closing.
301
+ // Resets the inline style of the <div>, that displays the text, back
302
+ // to what is was before it was hidden when the entry text area opened.
303
+ closeEntryTextArea() {
304
+ this.displayDiv.attr("style", this.displayDivStyle);
308
305
  }
309
306
 
310
307
  // Displays a text area for an editable text decoration on either a node
311
308
  // or link.
312
309
  displayDecLabelTextArea(dec, obj, objType, parentDomObj) {
313
- this.displayTextArea({
310
+ // Save the current style for the display <div> and set the style so the
311
+ // <div> is hidden while the text area is displayed on top of it. This
312
+ // prevents the <div> from protruding below the text area.
313
+ this.displayDiv = d3.select(parentDomObj).selectAll(".d3-foreign-object-dec-label div");
314
+ this.displayDivStyle = this.displayDiv.attr("style");
315
+ this.displayDiv.attr("style", "display:none;");
316
+
317
+ this.editingTextData = {
314
318
  id: dec.id,
315
319
  text: dec.label,
316
320
  singleLine: dec.label_single_line || false,
@@ -327,8 +331,9 @@ export default class SvgCanvasTextArea {
327
331
  objType: objType,
328
332
  autoSizeCallback: this.autoSizeMultiLineLabel.bind(this),
329
333
  saveTextChangesCallback: this.saveDecLabelChanges.bind(this),
330
- closeTextAreaCallback: null
331
- });
334
+ closeTextAreaCallback: this.closeEntryTextArea.bind(this)
335
+ };
336
+ this.displayTextArea(this.editingTextData);
332
337
  }
333
338
 
334
339
  // Handles saved changes to editable text decorations.
@@ -352,7 +357,7 @@ export default class SvgCanvasTextArea {
352
357
  this.editingText = true;
353
358
  this.editingTextId = data.id;
354
359
 
355
- const foreignObject = d3.select(data.parentDomObj)
360
+ this.foreignObject = d3.select(data.parentDomObj)
356
361
  .append("foreignObject")
357
362
  .attr("class", "d3-foreign-object-text-entry")
358
363
  .attr("width", data.width)
@@ -360,7 +365,7 @@ export default class SvgCanvasTextArea {
360
365
  .attr("x", data.xPos)
361
366
  .attr("y", data.yPos);
362
367
 
363
- const textArea = foreignObject
368
+ const textArea = this.foreignObject
364
369
  .append("xhtml:textarea")
365
370
  .attr("class", data.className)
366
371
  .text(unescapeText(data.text))
@@ -368,8 +373,8 @@ export default class SvgCanvasTextArea {
368
373
  // If user hits return/enter
369
374
  if (d3Event.keyCode === RETURN_KEY) {
370
375
  if (data.allowReturnKey === "save") {
371
- this.textAreaLabelSaved = true;
372
- this.saveAndCloseTextArea(foreignObject, data, d3Event.target.value, d3Event);
376
+ this.textContentSaved = true;
377
+ this.saveAndCloseTextArea(data, d3Event.target.value, d3Event);
373
378
  return;
374
379
 
375
380
  // Don't accept return key press when text is all on one line or
@@ -383,7 +388,7 @@ export default class SvgCanvasTextArea {
383
388
  if (d3Event.keyCode === ESC_KEY) {
384
389
  CanvasUtils.stopPropagationAndPreventDefault(d3Event);
385
390
  this.textAreaEscKeyPressed = true;
386
- this.closeTextArea(foreignObject, data);
391
+ this.closeTextArea(data);
387
392
  }
388
393
  // Prevent user entering more than any allowed maximum for characters.
389
394
  if (data.maxCharacters &&
@@ -398,14 +403,14 @@ export default class SvgCanvasTextArea {
398
403
  }
399
404
  })
400
405
  .on("keyup", (d3Event) => {
401
- data.autoSizeCallback(d3Event.target, foreignObject, data);
406
+ data.autoSizeCallback(d3Event.target, data);
402
407
  })
403
408
  .on("paste", (d3Event) => {
404
409
  this.logger.log("Text area - Paste - Scroll Ht = " + d3Event.target.scrollHeight);
405
410
  // Allow some time for pasted text (from context menu) to be
406
411
  // loaded into the text area. Otherwise the text is not there
407
412
  // and the auto size does not increase the height correctly.
408
- setTimeout(data.autoSizeCallback, 500, d3Event.target, foreignObject, data);
413
+ setTimeout(data.autoSizeCallback, 500, d3Event.target, data);
409
414
  })
410
415
  .on("blur", (d3Event, d) => {
411
416
  this.logger.log("Text area - blur");
@@ -418,8 +423,8 @@ export default class SvgCanvasTextArea {
418
423
 
419
424
  // If the text label has been saved by the user hitting the return key
420
425
  // we just return since there's nothing further to do.
421
- if (this.textAreaLabelSaved) {
422
- this.textAreaLabelSaved = false;
426
+ if (this.textContentSaved) {
427
+ this.textContentSaved = false;
423
428
  return;
424
429
  }
425
430
 
@@ -429,11 +434,11 @@ export default class SvgCanvasTextArea {
429
434
  return;
430
435
  }
431
436
 
432
- this.saveAndCloseTextArea(foreignObject, data, d3Event.target.value, d3Event);
437
+ this.saveAndCloseTextArea(data, d3Event.target.value, d3Event);
433
438
  })
434
439
  .on("focus", (d3Event, d) => {
435
440
  this.logger.log("Text area - focus");
436
- data.autoSizeCallback(d3Event.target, foreignObject, data);
441
+ data.autoSizeCallback(d3Event.target, data);
437
442
  })
438
443
  .on("mousedown click dblclick contextmenu", (d3Event, d) => {
439
444
  d3Event.stopPropagation(); // Allow default behavior to show system contenxt menu
@@ -445,29 +450,37 @@ export default class SvgCanvasTextArea {
445
450
  textArea.node().setSelectionRange(data.text.length, data.text.length);
446
451
  }
447
452
 
448
- saveAndCloseTextArea(foreignObject, data, newValue, d3Event) {
453
+ // Complete the text editing. evt may be undefined when called from the
454
+ // canvas renderer.
455
+ completeEditing(evt) {
456
+ // const commentEntry = this.canvasDiv.selectAll(".d3-comment-entry");
457
+ const commentEntry = this.foreignObject.selectAll("textarea");
458
+ const commentEntryElement = commentEntry.node();
459
+ this.textContentSaved = true;
460
+ this.saveAndCloseTextArea(this.editingTextData, commentEntryElement.value, evt);
461
+ }
462
+
463
+ saveAndCloseTextArea(data, newValue, d3Event) {
449
464
  // If there is no text for the label and textCanBeEmpty is false
450
465
  // just return, so label returns to what it was before editing started.
451
466
  if (!newValue && !data.textCanBeEmpty) {
452
467
  CanvasUtils.stopPropagationAndPreventDefault(d3Event);
453
- this.closeTextArea(foreignObject, data);
468
+ this.closeTextArea(data);
454
469
  return;
455
470
  }
456
471
  const newText = newValue; // Save the text before closing the foreign object
457
- this.closeTextArea(foreignObject, data);
472
+ this.closeTextArea(data);
458
473
  if (data.text !== newText || this.textAreaHeight !== data.height) {
459
- this.isCommentBeingUpdated = true;
460
474
  data.saveTextChangesCallback(data.id, newText, this.textAreaHeight, data);
461
- this.isCommentBeingUpdatd = false;
462
475
  }
463
476
  }
464
477
 
465
478
  // Closes the text area and resets the flags.
466
- closeTextArea(foreignObject, data) {
479
+ closeTextArea(data) {
467
480
  if (data.closeTextAreaCallback) {
468
481
  data.closeTextAreaCallback(data.id);
469
482
  }
470
- foreignObject.remove();
483
+ this.foreignObject.remove();
471
484
  this.editingText = false;
472
485
  this.editingTextId = "";
473
486
  }
@@ -155,7 +155,7 @@ class EditorForm extends React.Component {
155
155
  // if total non-tearsheet tabs is 1; don't show any tabs
156
156
  if (totalTabs.length === 1 && nonTearsheetTabs.length === 1) {
157
157
  return (
158
- <div key={"cat." + key} className="properties-category">
158
+ <div key={"cat." + key} className="properties-single-category">
159
159
  {panelItems}
160
160
  {additionalComponent}
161
161
  </div>
@@ -170,7 +170,7 @@ class EditorForm extends React.Component {
170
170
  }
171
171
  if (tab.content.itemType !== ItemType.TEARSHEET && nonTearsheetTabs.length === 1) {
172
172
  tabContent.push(
173
- <div key={"cat." + key} className="properties-category">
173
+ <div key={"cat." + key} className="properties-single-category">
174
174
  {panelItems}
175
175
  {additionalComponent}
176
176
  </div>
@@ -202,6 +202,7 @@ class EditorForm extends React.Component {
202
202
  key={this._getContainerIndex(hasAlertsTab, i) + "-" + key}
203
203
  tabIndex={i}
204
204
  label={tab.text}
205
+ title={tab.text}
205
206
  className={classNames({ "properties-hidden-container": tab.content.itemType === ItemType.TEARSHEET })}
206
207
  onClick={this._modalTabsOnClick.bind(this, tab.group)}
207
208
  >
@@ -220,7 +221,12 @@ class EditorForm extends React.Component {
220
221
  );
221
222
  }
222
223
  return (
223
- <Tabs key={"tab." + key} className="properties-primaryTabs" selected={modalSelected} light={this.props.controller.getLight()}>
224
+ <Tabs key={"tab." + key}
225
+ className="properties-primaryTabs"
226
+ selected={modalSelected}
227
+ light={this.props.controller.getLight()}
228
+ tabContentClassName={classNames("properties-primary-tab-panel", { "tearsheet-container": this.props.controller.isTearsheetContainer() })}
229
+ >
224
230
  {tabContent}
225
231
  </Tabs>
226
232
  );
@@ -342,6 +348,7 @@ class EditorForm extends React.Component {
342
348
  case ("tearsheet"):
343
349
  return this.genPanel(key, uiItem.panel, inPropertyId, indexof);
344
350
  case ("subTabs"):
351
+ // All Subtabs will become a LeftNav if displayed inside a Tearsheet container
345
352
  return (<Subtabs key={"subtabs." + key}
346
353
  tabs={uiItem.tabs}
347
354
  className={uiItem.className}
@@ -349,6 +356,7 @@ class EditorForm extends React.Component {
349
356
  rightFlyout={this.props.rightFlyout}
350
357
  genUIItem={this.genUIItem}
351
358
  nestedPanel={uiItem.nestedPanel}
359
+ leftnav={this.props.controller.isTearsheetContainer()}
352
360
  />);
353
361
  case ("primaryTabs"):
354
362
  return this.genPrimaryTabs(key, uiItem.tabs, inPropertyId, indexof);
@@ -467,11 +475,14 @@ class EditorForm extends React.Component {
467
475
  }
468
476
  if (!this.FIRST_TEARSHEET_ID || this.FIRST_TEARSHEET_ID === panel.id) {
469
477
  this.FIRST_TEARSHEET_ID = panel.id;
478
+ const onCloseCallback = () => {
479
+ this.props.controller.clearActiveTearsheet();
480
+ };
470
481
  return (
471
482
  <TearSheet
472
483
  open={this.props.controller.getActiveTearsheet() !== null}
484
+ onCloseCallback={onCloseCallback}
473
485
  key={panel.id}
474
- controller={this.props.controller}
475
486
  tearsheet={this.visibleTearsheet}
476
487
  />
477
488
  );
@@ -622,7 +633,10 @@ class EditorForm extends React.Component {
622
633
  }
623
634
 
624
635
  return (
625
- <div className="properties-editor-form">
636
+ <div className={classNames("properties-editor-form",
637
+ { "tearsheet-container": this.props.controller.isTearsheetContainer() },
638
+ { "field-picker": this.state.showFieldPicker })}
639
+ >
626
640
  {content}
627
641
  {wideFly}
628
642
  </div>
@@ -14,6 +14,8 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
+ $primary-tab-height: $spacing-08;
18
+
17
19
  .properties-primaryTabs {
18
20
  .bx--tabs__nav-item {
19
21
  margin-left: 1rem;
@@ -21,7 +23,7 @@
21
23
  }
22
24
 
23
25
  // styling when there is only 1 tab
24
- .properties-category {
26
+ .properties-single-category {
25
27
  padding: $spacing-05;
26
28
  }
27
29
 
@@ -107,8 +109,8 @@
107
109
  svg {
108
110
  margin-right: $spacing-05;
109
111
  margin-top: 1px;
110
- width: 16px;
111
- height: 16px;
112
+ width: $spacing-05;
113
+ height: $spacing-05;
112
114
  flex-shrink: 0;
113
115
  }
114
116
  .properties-link-text {
@@ -123,3 +125,28 @@
123
125
  .properties-custom-panel + .properties-control-panel {
124
126
  padding-top: $spacing-05; // padding between the two classes
125
127
  }
128
+
129
+ // Display in full height if inside a tearsheet
130
+ .properties-editor-form.tearsheet-container {
131
+ height: 100%;
132
+ overflow: hidden;
133
+
134
+ .properties-primaryTabs {
135
+ position: absolute;
136
+ height: $primary-tab-height;
137
+ padding-left: $spacing-05;
138
+ }
139
+
140
+ .properties-primary-tab-panel.tearsheet-container {
141
+ height: calc(100% - #{$primary-tab-height});
142
+ position: relative;
143
+ top: $primary-tab-height;
144
+ overflow-y: auto;
145
+ overflow-x: hidden;
146
+ }
147
+
148
+ &.field-picker {
149
+ border-top: 1px solid $ui-03;
150
+ padding: $spacing-05;
151
+ }
152
+ }
@@ -27,7 +27,7 @@ import { Button } from "carbon-components-react";
27
27
 
28
28
  import { MESSAGE_KEYS, DATA_TYPE, SORT_DIRECTION, ROW_SELECTION } from "./../../constants/constants";
29
29
  import Icon from "./../../../icons/icon.jsx";
30
- import { ArrowLeft24, Reset24 } from "@carbon/icons-react";
30
+ import { Reset24 } from "@carbon/icons-react";
31
31
 
32
32
  import { has, isEmpty, sortBy, isEqual } from "lodash";
33
33
 
@@ -298,50 +298,20 @@ export default class FieldPicker extends React.Component {
298
298
  }
299
299
 
300
300
  _genBackButton() {
301
- if (this.props.rightFlyout) {
302
- const applyLabel = PropertyUtils.formatMessage(this.props.controller.getReactIntl(), MESSAGE_KEYS.APPLYBUTTON_LABEL);
303
- const rejectLabel = PropertyUtils.formatMessage(this.props.controller.getReactIntl(), MESSAGE_KEYS.REJECTBUTTON_LABEL);
304
-
305
- return (<PropertiesButtons
306
- okHandler={this.handleSave}
307
- cancelHandler={this.handleCancel}
308
- showPropertiesButtons
309
- applyLabel={applyLabel}
310
- rejectLabel={rejectLabel}
311
- />);
312
- }
301
+ let applyLabel = PropertyUtils.formatMessage(this.props.controller.getReactIntl(), MESSAGE_KEYS.APPLYBUTTON_LABEL);
302
+ const rejectLabel = PropertyUtils.formatMessage(this.props.controller.getReactIntl(), MESSAGE_KEYS.REJECTBUTTON_LABEL);
313
303
 
314
- const saveTooltip = PropertyUtils.formatMessage(this.props.controller.getReactIntl(),
315
- MESSAGE_KEYS.FIELDPICKER_SAVEBUTTON_TOOLTIP);
316
- const tooltipId = uuid4() + "-tooltip-fp";
317
- const tooltip = (
318
- <div className="properties-tooltips">
319
- {saveTooltip}
320
- </div>
321
- );
304
+ if (!this.props.rightFlyout) {
305
+ applyLabel = PropertyUtils.formatMessage(this.props.controller.getReactIntl(), MESSAGE_KEYS.FIELDPICKER_SAVEBUTTON_MODAL_LABEL);
306
+ }
322
307
 
323
- return (
324
- <div>
325
- <Tooltip
326
- id={tooltipId}
327
- tip={tooltip}
328
- direction="left"
329
- className="properties-tooltips"
330
- >
331
- <div>
332
- <Button
333
- className="properties-fp-back-button"
334
- renderIcon={ArrowLeft24}
335
- iconDescription={this.props.title}
336
- size="small"
337
- kind="primary"
338
- onClick={this.handleSave}
339
- />
340
- <label className="properties-fp-button-label">{this.props.title}</label>
341
- </div>
342
- </Tooltip>
343
- </div>
344
- );
308
+ return (<PropertiesButtons
309
+ okHandler={this.handleSave}
310
+ cancelHandler={this.handleCancel}
311
+ showPropertiesButtons
312
+ applyLabel={applyLabel}
313
+ rejectLabel={rejectLabel}
314
+ />);
345
315
  }
346
316
 
347
317
  _genResetButton() {
@@ -449,7 +419,7 @@ export default class FieldPicker extends React.Component {
449
419
  selectedRows={this.selectedRowsIndex}
450
420
  updateRowSelections={this.updateFieldSelections}
451
421
  rowSelection={ROW_SELECTION.MULTIPLE}
452
- light={this.props.controller.getLight()}
422
+ light={this.props.controller.getLight() && !this.props.controller.isTearsheetContainer()}
453
423
  />
454
424
  );
455
425
  }
@@ -460,25 +430,14 @@ export default class FieldPicker extends React.Component {
460
430
  const filterTypes = this._genFilterTypes();
461
431
  const table = this._genTable();
462
432
 
463
- if (this.props.rightFlyout) {
464
- return (<React.Fragment>
465
- <div className="properties-fp-top-row">
466
- {filterTypes}
467
- {resetButton}
468
- </div>
469
- {table}
470
- {backButton}
471
- </React.Fragment>);
472
- }
473
-
474
- return (<div>
433
+ return (<React.Fragment>
475
434
  <div className="properties-fp-top-row">
476
- {backButton}
435
+ {filterTypes}
477
436
  {resetButton}
478
437
  </div>
479
- {filterTypes}
480
438
  {table}
481
- </div>);
439
+ {backButton}
440
+ </React.Fragment>);
482
441
  }
483
442
  }
484
443
 
@@ -90,35 +90,26 @@
90
90
  }
91
91
  }
92
92
  }
93
+
94
+ // This only happens when all rows of the table are filtered. The field-picker should never be empty elsewise
95
+ .properties-ft-empty-table {
96
+ display: none;
97
+ }
93
98
  }
94
99
 
95
- // This is for field-picker in properties-modal instead of flyout
96
- .properties-modal {
97
- .properties-fp-top-row {
98
- width: 100%;
99
- margin-bottom: $spacing-03;
100
- display: flex;
101
- justify-content: space-between;
100
+ // This is for field-picker in properties-modal, containerType="Modal"
101
+ .properties-modal, .properties-tearsheet-panel.bx--modal {
102
+ .properties-fp-table {
103
+ padding-bottom: $spacing-06;
104
+ margin-bottom: $spacing-10; // Accommodate footer buttons
102
105
 
103
- .properties-fp-button-label {
104
- position: relative;
105
- top: $spacing-03;
106
+ .properties-fp-top-row {
107
+ display: flex;
108
+ justify-content: flex-end;
106
109
  }
107
110
 
108
- // This back button is used in common-properties modal format
109
- .properties-fp-back-button {
110
- height: $spacing-07;
111
- width: $spacing-07;
112
- padding: 0;
113
- margin-right: $spacing-03;
114
-
115
- > svg {
116
- left: $spacing-03;
117
- }
111
+ .properties-modal-buttons {
112
+ width: 100%;
118
113
  }
119
114
  }
120
-
121
- .properties-fp-filter-list {
122
- float: right;
123
- }
124
115
  }