@elyra/canvas 12.25.0 → 12.26.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 (130) hide show
  1. package/assets/images/supernode_ext.svg +0 -9
  2. package/dist/canvas-controller-df16f0fa.js +2 -0
  3. package/dist/canvas-controller-df16f0fa.js.map +1 -0
  4. package/dist/canvas-controller-fefee807.js +2 -0
  5. package/dist/canvas-controller-fefee807.js.map +1 -0
  6. package/dist/common-canvas-55d075fe.js +2 -0
  7. package/dist/common-canvas-55d075fe.js.map +1 -0
  8. package/dist/common-canvas-e8a7a840.js +2 -0
  9. package/dist/common-canvas-e8a7a840.js.map +1 -0
  10. package/dist/common-canvas.es.js +1 -1
  11. package/dist/common-canvas.js +1 -1
  12. package/dist/common-properties-97261017.js +2 -0
  13. package/dist/common-properties-97261017.js.map +1 -0
  14. package/dist/common-properties-f596260f.js +2 -0
  15. package/dist/common-properties-f596260f.js.map +1 -0
  16. package/dist/datarecord-metadata-v3-schema-6a3754ce.js +1 -1
  17. package/dist/datarecord-metadata-v3-schema-6a3754ce.js.map +1 -1
  18. package/dist/datarecord-metadata-v3-schema-ba1f2849.js +1 -1
  19. package/dist/datarecord-metadata-v3-schema-ba1f2849.js.map +1 -1
  20. package/dist/en-7201b548.js +1 -1
  21. package/dist/en-7201b548.js.map +1 -1
  22. package/dist/en-a08356c8.js +1 -1
  23. package/dist/en-a08356c8.js.map +1 -1
  24. package/dist/{extends-3cb3faa3.js → extends-841b39ac.js} +2 -2
  25. package/dist/extends-841b39ac.js.map +1 -0
  26. package/dist/{extends-858c1544.js → extends-a9c1b4cd.js} +2 -2
  27. package/dist/extends-a9c1b4cd.js.map +1 -0
  28. package/dist/flexible-table-d4bd5c25.js +2 -0
  29. package/dist/flexible-table-d4bd5c25.js.map +1 -0
  30. package/dist/flexible-table-f7b58f99.js +2 -0
  31. package/dist/flexible-table-f7b58f99.js.map +1 -0
  32. package/dist/icon-4a6f3dad.js +2 -0
  33. package/dist/icon-4a6f3dad.js.map +1 -0
  34. package/dist/icon-f6f2bffc.js +2 -0
  35. package/dist/icon-f6f2bffc.js.map +1 -0
  36. package/dist/index-5d62eee8.js +2 -0
  37. package/dist/index-5d62eee8.js.map +1 -0
  38. package/dist/index-c8a96051.js +2 -0
  39. package/dist/index-c8a96051.js.map +1 -0
  40. package/dist/isArrayLikeObject-a9c7973b.js +1 -1
  41. package/dist/isArrayLikeObject-a9c7973b.js.map +1 -1
  42. package/dist/isArrayLikeObject-f3b27f64.js +1 -1
  43. package/dist/isArrayLikeObject-f3b27f64.js.map +1 -1
  44. package/dist/lib/canvas-controller.es.js +1 -1
  45. package/dist/lib/canvas-controller.js +1 -1
  46. package/dist/lib/canvas.es.js +1 -1
  47. package/dist/lib/canvas.js +1 -1
  48. package/dist/lib/context-menu.es.js +1 -1
  49. package/dist/lib/context-menu.js +1 -1
  50. package/dist/lib/properties/field-picker.es.js +1 -1
  51. package/dist/lib/properties/field-picker.js +1 -1
  52. package/dist/lib/properties/flexible-table.es.js +1 -1
  53. package/dist/lib/properties/flexible-table.js +1 -1
  54. package/dist/lib/properties.es.js +1 -1
  55. package/dist/lib/properties.js +1 -1
  56. package/dist/styles/common-canvas.min.css +1 -1
  57. package/dist/styles/common-canvas.min.css.map +1 -1
  58. package/dist/toolbar-96922752.js +2 -0
  59. package/dist/toolbar-96922752.js.map +1 -0
  60. package/dist/toolbar-c8779b93.js +2 -0
  61. package/dist/toolbar-c8779b93.js.map +1 -0
  62. package/locales/common-properties/locales/en.json +4 -1
  63. package/locales/common-properties/locales/eo.json +4 -1
  64. package/package.json +1 -1
  65. package/src/common-canvas/canvas-controller.js +17 -11
  66. package/src/common-canvas/cc-toolbar.jsx +2 -2
  67. package/src/common-canvas/common-canvas-utils.js +28 -12
  68. package/src/common-canvas/common-canvas.scss +3 -3
  69. package/src/common-canvas/svg-canvas-pipeline.js +22 -0
  70. package/src/common-canvas/svg-canvas-renderer.js +43 -38
  71. package/src/common-properties/common-properties.jsx +6 -2
  72. package/src/common-properties/components/control-item/control-item.jsx +16 -5
  73. package/src/common-properties/components/control-item/control-item.scss +3 -2
  74. package/src/common-properties/components/editor-form/editor-form.jsx +3 -3
  75. package/src/common-properties/components/editor-form/editor-form.scss +3 -6
  76. package/src/common-properties/components/flexible-table/flexible-table.jsx +5 -2
  77. package/src/common-properties/components/moveable-table-rows/moveable-table-rows.jsx +2 -2
  78. package/src/common-properties/constants/constants.js +4 -1
  79. package/src/common-properties/controls/control-factory.js +8 -4
  80. package/src/common-properties/controls/controls.scss +0 -3
  81. package/src/common-properties/controls/dropdown/dropdown.jsx +17 -6
  82. package/src/common-properties/controls/selectcolumns/selectcolumns.jsx +2 -2
  83. package/src/common-properties/form/ControlInfo.js +3 -0
  84. package/src/common-properties/form/EditorForm.js +1 -0
  85. package/src/common-properties/form/Form.js +9 -2
  86. package/src/common-properties/form/ParameterInfo.js +18 -1
  87. package/src/common-properties/properties-controller.js +2 -1
  88. package/src/common-properties/properties-main/properties-main.jsx +3 -2
  89. package/src/common-properties/reducers/{save-button-disable.jsx → save-button-disable.js} +0 -0
  90. package/src/common-properties/reducers/{wide-flyout-primary-button-disable.jsx → wide-flyout-primary-button-disable.js} +0 -0
  91. package/src/common-properties/ui-conditions/condition-ops/isEmpty.js +2 -1
  92. package/src/common-properties/ui-conditions/condition-ops/isNotEmpty.js +2 -1
  93. package/src/common-properties/util/property-utils.js +43 -1
  94. package/src/notification-panel/notification-panel.jsx +29 -2
  95. package/src/notification-panel/notification-panel.scss +5 -11
  96. package/src/palette/palette-content-list-item.jsx +13 -10
  97. package/src/palette/palette-flyout-content-category.jsx +8 -2
  98. package/src/palette/palette.scss +9 -2
  99. package/src/toolbar/toolbar-action-item.jsx +5 -1
  100. package/stats.html +1 -1
  101. package/dist/canvas-controller-1cf8e066.js +0 -2
  102. package/dist/canvas-controller-1cf8e066.js.map +0 -1
  103. package/dist/canvas-controller-873a2800.js +0 -2
  104. package/dist/canvas-controller-873a2800.js.map +0 -1
  105. package/dist/common-canvas-4c204462.js +0 -2
  106. package/dist/common-canvas-4c204462.js.map +0 -1
  107. package/dist/common-canvas-9e2687b3.js +0 -2
  108. package/dist/common-canvas-9e2687b3.js.map +0 -1
  109. package/dist/common-properties-478094f0.js +0 -2
  110. package/dist/common-properties-478094f0.js.map +0 -1
  111. package/dist/common-properties-648d23a3.js +0 -2
  112. package/dist/common-properties-648d23a3.js.map +0 -1
  113. package/dist/extends-3cb3faa3.js.map +0 -1
  114. package/dist/extends-858c1544.js.map +0 -1
  115. package/dist/flexible-table-8d16ca9e.js +0 -2
  116. package/dist/flexible-table-8d16ca9e.js.map +0 -1
  117. package/dist/flexible-table-984c1cb1.js +0 -2
  118. package/dist/flexible-table-984c1cb1.js.map +0 -1
  119. package/dist/icon-18729ae8.js +0 -2
  120. package/dist/icon-18729ae8.js.map +0 -1
  121. package/dist/icon-53450584.js +0 -2
  122. package/dist/icon-53450584.js.map +0 -1
  123. package/dist/index-621d121a.js +0 -2
  124. package/dist/index-621d121a.js.map +0 -1
  125. package/dist/index-d2d9aa72.js +0 -2
  126. package/dist/index-d2d9aa72.js.map +0 -1
  127. package/dist/toolbar-245632a5.js +0 -2
  128. package/dist/toolbar-245632a5.js.map +0 -1
  129. package/dist/toolbar-9f4bb202.js +0 -2
  130. package/dist/toolbar-9f4bb202.js.map +0 -1
@@ -957,7 +957,11 @@ export default class CanvasUtils {
957
957
  // all properties set to zero if no valid objects were provided.
958
958
  // nodeHighlightGap may be 0 or undefined. If it is undefined we use the
959
959
  // nodeHighlightGap in the node's layout.
960
- static getCanvasDimensions(nodes, comments, links, commentHighlightGap, nodeHighlightGap) {
960
+ // If allLinks is set to true, we include the start and end coordinates of all
961
+ // links passed in. If set to false (or is undefined), we only inlcude
962
+ // the unconnected ends of semi-detached or fully-detached links. That is,
963
+ // where the link has a srcPos and/or a trgPos field.
964
+ static getCanvasDimensions(nodes, comments, links, commentHighlightGap, nodeHighlightGap, allLinks) {
961
965
  var canvLeft = Infinity;
962
966
  let canvTop = Infinity;
963
967
  var canvRight = -Infinity;
@@ -988,17 +992,29 @@ export default class CanvasUtils {
988
992
  // Take into account semi-detached and fully-detached links, if any.
989
993
  if (links) {
990
994
  links.forEach((link) => {
991
- if (link.srcPos) {
992
- canvLeft = Math.min(canvLeft, link.srcPos.x_pos);
993
- canvTop = Math.min(canvTop, link.srcPos.y_pos);
994
- canvRight = Math.max(canvRight, link.srcPos.x_pos);
995
- canvBottom = Math.max(canvBottom, link.srcPos.y_pos);
996
- }
997
- if (link.trgPos) {
998
- canvLeft = Math.min(canvLeft, link.trgPos.x_pos);
999
- canvTop = Math.min(canvTop, link.trgPos.y_pos);
1000
- canvRight = Math.max(canvRight, link.trgPos.x_pos);
1001
- canvBottom = Math.max(canvBottom, link.trgPos.y_pos);
995
+ if (allLinks) {
996
+ canvLeft = Math.min(canvLeft, link.x1);
997
+ canvTop = Math.min(canvTop, link.y1);
998
+ canvRight = Math.max(canvRight, link.x1);
999
+ canvBottom = Math.max(canvBottom, link.y1);
1000
+
1001
+ canvLeft = Math.min(canvLeft, link.x2);
1002
+ canvTop = Math.min(canvTop, link.y2);
1003
+ canvRight = Math.max(canvRight, link.x2);
1004
+ canvBottom = Math.max(canvBottom, link.y2);
1005
+ } else {
1006
+ if (link.srcPos) {
1007
+ canvLeft = Math.min(canvLeft, link.srcPos.x_pos);
1008
+ canvTop = Math.min(canvTop, link.srcPos.y_pos);
1009
+ canvRight = Math.max(canvRight, link.srcPos.x_pos);
1010
+ canvBottom = Math.max(canvBottom, link.srcPos.y_pos);
1011
+ }
1012
+ if (link.trgPos) {
1013
+ canvLeft = Math.min(canvLeft, link.trgPos.x_pos);
1014
+ canvTop = Math.min(canvTop, link.trgPos.y_pos);
1015
+ canvRight = Math.max(canvRight, link.trgPos.x_pos);
1016
+ canvBottom = Math.max(canvBottom, link.trgPos.y_pos);
1017
+ }
1002
1018
  }
1003
1019
  });
1004
1020
  }
@@ -197,7 +197,7 @@ $bottom-panel-border-color: $ui-03;
197
197
 
198
198
  .empty-canvas-image {
199
199
  color: $text-03; // Picked up by fill attribute in the icon.
200
- opacity: 0.4;
200
+ opacity: 0.75;
201
201
  display: block;
202
202
  text-align: center;
203
203
  & svg {
@@ -209,7 +209,7 @@ $bottom-panel-border-color: $ui-03;
209
209
  .empty-canvas-text1 {
210
210
  @include carbon--type-style("productive-heading-03");
211
211
  padding-top: $spacing-02;
212
- color: $text-03;
212
+ color: $text-02;
213
213
  display: block;
214
214
  text-align: center;
215
215
  }
@@ -217,7 +217,7 @@ $bottom-panel-border-color: $ui-03;
217
217
  .empty-canvas-text2 {
218
218
  @include carbon--type-style("body-short-02");
219
219
  padding-top: $spacing-03;
220
- color: $text-03;
220
+ color: $text-02;
221
221
  display: block;
222
222
  text-align: center;
223
223
  }
@@ -106,6 +106,17 @@ export default class SVGCanvasPipeline {
106
106
  return (typeof com === "undefined") ? null : com;
107
107
  }
108
108
 
109
+ getComments(commentIds) {
110
+ const comments = [];
111
+ commentIds.forEach((cId) => {
112
+ const c = this.getComment(cId);
113
+ if (c) {
114
+ comments.push(c);
115
+ }
116
+ });
117
+ return comments;
118
+ }
119
+
109
120
  getNodesAndComments() {
110
121
  return this.pipeline.nodes.concat(this.pipeline.comments);
111
122
  }
@@ -123,6 +134,17 @@ export default class SVGCanvasPipeline {
123
134
  return (typeof link === "undefined") ? null : link;
124
135
  }
125
136
 
137
+ getLinks(linkIds) {
138
+ const links = [];
139
+ linkIds.forEach((lId) => {
140
+ const l = this.getLink(lId);
141
+ if (l) {
142
+ links.push(l);
143
+ }
144
+ });
145
+ return links;
146
+ }
147
+
126
148
  // Replaces the link in the links array with the one passed in.
127
149
  replaceLink(oldLink) {
128
150
  const index = this.pipeline.links.findIndex((l) => l.id === oldLink.id);
@@ -184,7 +184,7 @@ export default class SVGCanvasRenderer {
184
184
 
185
185
  // Keep track of when text editing has been closed, so we don't remove
186
186
  // selections when that happens during a zoom gesture.
187
- this.textEditingClosedfOnZoom = false;
187
+ this.textEditingClosedOnZoom = false;
188
188
 
189
189
  // Used to monitor the region selection rectangle.
190
190
  this.regionSelect = false;
@@ -1789,41 +1789,46 @@ export default class SVGCanvasRenderer {
1789
1789
  return this.zoomTransform ? this.zoomTransform.k === this.minScaleExtent : false;
1790
1790
  }
1791
1791
 
1792
- getZoomToReveal(nodeIDs, xPos, yPos) {
1792
+ getZoomToReveal(objectIDs, xPos, yPos) {
1793
1793
  const transformedSVGRect = this.getTransformedViewportDimensions();
1794
- const nodes = this.activePipeline.getNodes(nodeIDs);
1795
- const canvasDimensions = CanvasUtils.getCanvasDimensions(nodes, [], [], 0);
1796
- const canv = this.convertCanvasDimensionsAdjustedForScaleWithPadding(canvasDimensions, 1, 10);
1797
- const xPosInt = parseInt(xPos, 10);
1798
- const yPosInt = typeof yPos === "undefined" ? xPosInt : parseInt(yPos, 10);
1794
+ const nodes = this.activePipeline.getNodes(objectIDs);
1795
+ const comments = this.activePipeline.getComments(objectIDs);
1796
+ const links = this.activePipeline.getLinks(objectIDs);
1799
1797
 
1800
- if (canv) {
1801
- let xOffset;
1802
- let yOffset;
1798
+ if (nodes.length > 0 || comments.length > 0 || links.length > 0) {
1799
+ const canvasDimensions = CanvasUtils.getCanvasDimensions(nodes, comments, links, 0, 0, true);
1800
+ const canv = this.convertCanvasDimensionsAdjustedForScaleWithPadding(canvasDimensions, 1, 10);
1801
+ const xPosInt = parseInt(xPos, 10);
1802
+ const yPosInt = typeof yPos === "undefined" ? xPosInt : parseInt(yPos, 10);
1803
1803
 
1804
- if (!Number.isNaN(xPosInt) && !Number.isNaN(yPosInt)) {
1805
- xOffset = transformedSVGRect.x + (transformedSVGRect.width * (xPosInt / 100)) - (canv.left + (canv.width / 2));
1806
- yOffset = transformedSVGRect.y + (transformedSVGRect.height * (yPosInt / 100)) - (canv.top + (canv.height / 2));
1804
+ if (canv) {
1805
+ let xOffset;
1806
+ let yOffset;
1807
1807
 
1808
- } else {
1809
- if (canv.right > transformedSVGRect.x + transformedSVGRect.width) {
1810
- xOffset = transformedSVGRect.x + transformedSVGRect.width - canv.right;
1811
- }
1812
- if (canv.left < transformedSVGRect.x) {
1813
- xOffset = transformedSVGRect.x - canv.left;
1814
- }
1815
- if (canv.bottom > transformedSVGRect.y + transformedSVGRect.height) {
1816
- yOffset = transformedSVGRect.y + transformedSVGRect.height - canv.bottom;
1817
- }
1818
- if (canv.top < transformedSVGRect.y) {
1819
- yOffset = transformedSVGRect.y - canv.top;
1808
+ if (!Number.isNaN(xPosInt) && !Number.isNaN(yPosInt)) {
1809
+ xOffset = transformedSVGRect.x + (transformedSVGRect.width * (xPosInt / 100)) - (canv.left + (canv.width / 2));
1810
+ yOffset = transformedSVGRect.y + (transformedSVGRect.height * (yPosInt / 100)) - (canv.top + (canv.height / 2));
1811
+
1812
+ } else {
1813
+ if (canv.right > transformedSVGRect.x + transformedSVGRect.width) {
1814
+ xOffset = transformedSVGRect.x + transformedSVGRect.width - canv.right;
1815
+ }
1816
+ if (canv.left < transformedSVGRect.x) {
1817
+ xOffset = transformedSVGRect.x - canv.left;
1818
+ }
1819
+ if (canv.bottom > transformedSVGRect.y + transformedSVGRect.height) {
1820
+ yOffset = transformedSVGRect.y + transformedSVGRect.height - canv.bottom;
1821
+ }
1822
+ if (canv.top < transformedSVGRect.y) {
1823
+ yOffset = transformedSVGRect.y - canv.top;
1824
+ }
1820
1825
  }
1821
- }
1822
1826
 
1823
- if (typeof xOffset !== "undefined" || typeof yOffset !== "undefined") {
1824
- const x = this.zoomTransform.x + ((xOffset || 0)) * this.zoomTransform.k;
1825
- const y = this.zoomTransform.y + ((yOffset || 0)) * this.zoomTransform.k;
1826
- return { x: x || 0, y: y || 0, k: this.zoomTransform.k };
1827
+ if (typeof xOffset !== "undefined" || typeof yOffset !== "undefined") {
1828
+ const x = this.zoomTransform.x + ((xOffset || 0)) * this.zoomTransform.k;
1829
+ const y = this.zoomTransform.y + ((yOffset || 0)) * this.zoomTransform.k;
1830
+ return { x: x || 0, y: y || 0, k: this.zoomTransform.k };
1831
+ }
1827
1832
  }
1828
1833
  }
1829
1834
 
@@ -1882,7 +1887,7 @@ export default class SVGCanvasRenderer {
1882
1887
  // if the user clicks on the canvas background. So we set this flag to
1883
1888
  // prevent the selection being lost in the zoomEnd (mouseup) event.
1884
1889
  if (this.svgCanvasTextArea.isEditingText()) {
1885
- this.textEditingClosedfOnZoom = true;
1890
+ this.textEditingClosedOnZoom = true;
1886
1891
  }
1887
1892
 
1888
1893
  this.regionSelect = this.shouldDoRegionSelect(d3Event);
@@ -1890,15 +1895,15 @@ export default class SVGCanvasRenderer {
1890
1895
  if (this.regionSelect) {
1891
1896
  // Add a delay so, if the user just clicks, they don't see the crosshair.
1892
1897
  // This will be cleared in zoomEnd if the user's click takes less than 200 ms.
1893
- this.addingCrossHairCursor = setTimeout(() => this.addTempCursorOverlay("crosshair"), 200);
1898
+ this.addingCursorOverlay = setTimeout(() => this.addTempCursorOverlay("crosshair"), 200);
1894
1899
  this.regionStartTransformX = d3Event.transform.x;
1895
1900
  this.regionStartTransformY = d3Event.transform.y;
1896
1901
 
1897
1902
  } else {
1898
1903
  if (this.isDragActivated(d3Event)) {
1899
- this.addTempCursorOverlay("grabbing");
1904
+ this.addingCursorOverlay = setTimeout(() => this.addTempCursorOverlay("grabbing"), 200);
1900
1905
  } else {
1901
- this.addTempCursorOverlay("default");
1906
+ this.addingCursorOverlay = setTimeout(() => this.addTempCursorOverlay("default"), 200);
1902
1907
  }
1903
1908
  }
1904
1909
 
@@ -1933,8 +1938,8 @@ export default class SVGCanvasRenderer {
1933
1938
  zoomEnd(d3Event) {
1934
1939
  this.logger.log("zoomEnd - " + JSON.stringify(d3Event.transform));
1935
1940
 
1936
- // Clears the display of the crosshair cursor if the user clicks within 200 ms
1937
- clearTimeout(this.addingCrossHairCursor);
1941
+ // Clears the display of the cursor overlay if the user clicks within 200 ms
1942
+ clearTimeout(this.addingCursorOverlay);
1938
1943
 
1939
1944
  const transPos = this.getTransformedMousePos(d3Event);
1940
1945
 
@@ -1962,7 +1967,7 @@ export default class SVGCanvasRenderer {
1962
1967
  this.resetCanvasCursor(d3Event);
1963
1968
  this.removeTempCursorOverlay();
1964
1969
  this.contextMenuClosedOnZoom = false;
1965
- this.textEditingClosedfOnZoom = false;
1970
+ this.textEditingClosedOnZoom = false;
1966
1971
  this.regionSelect = false;
1967
1972
  }
1968
1973
 
@@ -2032,7 +2037,7 @@ export default class SVGCanvasRenderer {
2032
2037
  // Clicking the canvas of an expanded supernode will select that node.
2033
2038
  // Also, don't clear selections if we have closed a context menu or
2034
2039
  // closed text editing.
2035
- if (this.dispUtils.isDisplayingCurrentPipeline() && !this.contextMenuClosedOnZoom && !this.textEditingClosedfOnZoom) {
2040
+ if (this.dispUtils.isDisplayingCurrentPipeline() && !this.contextMenuClosedOnZoom && !this.textEditingClosedOnZoom) {
2036
2041
  this.canvasController.clearSelections();
2037
2042
  }
2038
2043
  }
@@ -231,6 +231,7 @@ CommonProperties.propTypes = {
231
231
  propertiesInfo: PropTypes.object.isRequired,
232
232
  propertiesConfig: PropTypes.shape({
233
233
  applyOnBlur: PropTypes.bool,
234
+ trimSpaces: PropTypes.bool,
234
235
  disableSaveOnRequiredErrors: PropTypes.bool,
235
236
  rightFlyout: PropTypes.bool,
236
237
  containerType: PropTypes.string,
@@ -245,7 +246,8 @@ CommonProperties.propTypes = {
245
246
  conditionHiddenPropertyHandling: PropTypes.oneOf(["null", "value"]),
246
247
  conditionDisabledPropertyHandling: PropTypes.oneOf(["null", "value"]),
247
248
  maxLengthForMultiLineControls: PropTypes.number,
248
- maxLengthForSingleLineControls: PropTypes.number
249
+ maxLengthForSingleLineControls: PropTypes.number,
250
+ convertValueDataTypes: PropTypes.bool
249
251
  }),
250
252
  callbacks: PropTypes.shape({
251
253
  controllerHandler: PropTypes.func,
@@ -273,13 +275,15 @@ CommonProperties.defaultProps = {
273
275
  containerType: "Custom",
274
276
  rightFlyout: true,
275
277
  applyOnBlur: false,
278
+ trimSpaces: true,
276
279
  disableSaveOnRequiredErrors: false,
277
280
  enableResize: true,
278
281
  conditionReturnValueHandling: "value",
279
282
  schemaValidation: false,
280
283
  applyPropertiesWithoutEdit: false,
281
284
  maxLengthForMultiLineControls: 1024,
282
- maxLengthForSingleLineControls: 128
285
+ maxLengthForSingleLineControls: 128,
286
+ convertValueDataTypes: false
283
287
  },
284
288
  callbacks: {
285
289
  },
@@ -18,13 +18,14 @@ import React from "react";
18
18
  import PropTypes from "prop-types";
19
19
  import { connect } from "react-redux";
20
20
  import classNames from "classnames";
21
- import { STATES, CARBON_ICONS } from "./../../constants/constants.js";
21
+ import { STATES, CARBON_ICONS, MESSAGE_KEYS } from "./../../constants/constants.js";
22
22
  import { ControlType } from "./../../constants/form-constants";
23
23
  import Tooltip from "./../../../tooltip/tooltip.jsx";
24
24
  import { isEmpty } from "lodash";
25
25
  import { v4 as uuid4 } from "uuid";
26
26
  import Icon from "./../../../icons/icon.jsx";
27
27
  import ActionFactory from "./../../actions/action-factory.js";
28
+ import { formatMessage } from "./../../util/property-utils";
28
29
 
29
30
  class ControlItem extends React.Component {
30
31
  constructor(props) {
@@ -66,14 +67,24 @@ class ControlItem extends React.Component {
66
67
  </Tooltip>);
67
68
  }
68
69
  }
69
- let requiredIndicator;
70
- if (this.props.control.required) {
71
- requiredIndicator = <span className="properties-required-indicator">*</span>;
70
+ let indicator;
71
+ if (this.props.control.showRequiredLabel && this.props.control.required) {
72
+ indicator = (
73
+ <span className="properties-indicator">
74
+ {formatMessage(this.props.controller.getReactIntl(), MESSAGE_KEYS.LABEL_INDICATOR_REQUIRED)}
75
+ </span>
76
+ );
77
+ } else if (!this.props.control.showRequiredLabel && !("required" in this.props.control)) {
78
+ indicator = (
79
+ <span className="properties-indicator">
80
+ {formatMessage(this.props.controller.getReactIntl(), MESSAGE_KEYS.LABEL_INDICATOR_OPTIONAL)}
81
+ </span>
82
+ );
72
83
  }
73
84
  label = (
74
85
  <div className={classNames("properties-label-container", { "table-control": this.props.tableControl === true })}>
75
86
  <label className="properties-control-label">{this.props.control.label.text}</label>
76
- {requiredIndicator}
87
+ {indicator}
77
88
  {tooltip}
78
89
  </div>);
79
90
  }
@@ -40,12 +40,13 @@
40
40
  display: flex;
41
41
  align-items: center;
42
42
  padding-bottom: $spacing-03;
43
- label, .properties-required-indicator {
43
+ label, .properties-indicator {
44
44
  @include carbon--type-style("label-01");
45
45
  color: $text-02;
46
+ padding-left: $spacing-02;
46
47
  }
47
48
  &.table-control {
48
- label, .properties-required-indicator {
49
+ label, .properties-indicator {
49
50
  @include carbon--type-style("productive-heading-01");
50
51
  color: $text-01;
51
52
  }
@@ -18,7 +18,7 @@ import React from "react";
18
18
  import PropTypes from "prop-types";
19
19
  import { connect } from "react-redux";
20
20
  import { setActiveTab } from "./../../actions";
21
- import { Tab, Tabs } from "carbon-components-react";
21
+ import { Tab, Tabs, Link } from "carbon-components-react";
22
22
  import * as PropertyUtil from "./../../util/property-utils";
23
23
  import { MESSAGE_KEYS, CARBON_ICONS, CONDITION_MESSAGE_TYPE, STATES } from "./../../constants/constants";
24
24
  import { cloneDeep, isEmpty, sortBy, get } from "lodash";
@@ -338,9 +338,9 @@ class EditorForm extends React.Component {
338
338
  icon = <Icon type={CONDITION_MESSAGE_TYPE.ERROR} />;
339
339
  }
340
340
  text = (
341
- <a className="properties-link-text" onClick={this._handleMessageClick.bind(this, uiItem.controlId)}>
341
+ <Link className="properties-link-text" onClick={this._handleMessageClick.bind(this, uiItem.controlId)} >
342
342
  {PropertyUtil.evaluateText(uiItem.text, this.props.controller)}
343
- </a>);
343
+ </Link>);
344
344
  return <div key={"link-text." + key} className={textClass} >{icon}{text}</div>;
345
345
  case ("hSeparator"):
346
346
  return <hr key={"h-separator." + key} className="properties-h-separator" />;
@@ -105,16 +105,13 @@ $primary-tab-height: $spacing-08;
105
105
 
106
106
  .properties-link-text-container {
107
107
  display: flex;
108
+ align-items: center;
108
109
  padding: $spacing-04 0 0 0;
109
110
  svg {
110
- margin-right: $spacing-05;
111
- margin-top: 1px;
112
- width: $spacing-05;
113
- height: $spacing-05;
114
- flex-shrink: 0;
111
+ margin-right: $spacing-03;
115
112
  }
116
113
  .properties-link-text {
117
- @include carbon--type-style("body-short-01");
114
+ cursor: pointer;
118
115
  }
119
116
  }
120
117
 
@@ -113,6 +113,9 @@ class FlexibleTable extends React.Component {
113
113
  if (row.columns && has(row.columns[0], "content.props.children.props.propertyId.propertyId")) {
114
114
  // this is a nested control
115
115
  rowIndex = this.getLastChildPropertyIdRow(row.columns[0].content.props.children.props.propertyId, index);
116
+ } else if (row.columns && has(row.columns[0], "content.props.children.props.propertyId.index")) {
117
+ // for rows that have multi-select controls in them
118
+ rowIndex = row.columns[0].content.props.children.props.propertyId.index;
116
119
  } else if (row.columns && has(row.columns[0], "content.props.children.props.propertyId.row")) {
117
120
  rowIndex = row.columns[0].content.props.children.props.propertyId.row;
118
121
  } else if (typeof row.rowKey === "number") { // expression tables uses rowKey
@@ -354,7 +357,7 @@ class FlexibleTable extends React.Component {
354
357
  const checked = data.selected;
355
358
  const overSelectOption = data.isOverSelectOption;
356
359
 
357
- if (!this.props.data[displayedRowIndex].disabled) {
360
+ if (!this.props.data[displayedRowIndex].disabled && typeof this.props.updateRowSelections === "function") {
358
361
  if (overSelectOption) { // Checkbox is clicked
359
362
  let current = this.props.selectedRows ? this.props.selectedRows : [];
360
363
  if (data.selectMultipleRows) { // multiple rows selected/deselected using shift key
@@ -372,7 +375,7 @@ class FlexibleTable extends React.Component {
372
375
  // Sort ascending because we want to add selected rows in the same order as they're displayed in the table
373
376
  current.sort((a, b) => a - b);
374
377
  this.props.updateRowSelections(current);
375
- } else if (this.props.rowSelection === ROW_SELECTION.SINGLE && typeof this.props.updateRowSelections !== "undefined") { // Table row is clicked
378
+ } else if (this.props.rowSelection === ROW_SELECTION.SINGLE) { // Table row is clicked
376
379
  this.props.updateRowSelections(data.index, evt, this.props.data[data.index].rowKey);
377
380
  }
378
381
  }
@@ -39,7 +39,7 @@ class MoveableTableRows extends React.Component {
39
39
  }
40
40
 
41
41
  getMoveableTableRows() {
42
- var moveCol = null;
42
+ let moveCol = null;
43
43
  if (typeof this.props.control.moveableRows !== "undefined" && this.props.control.moveableRows) {
44
44
  const moveImages = this.getTableRowMoveImages();
45
45
  moveCol = (
@@ -52,7 +52,7 @@ class MoveableTableRows extends React.Component {
52
52
  }
53
53
 
54
54
  // Added role presentation to fix a11y violation - no headers in the table
55
- var content = (<table role="presentation" className="properties-mr-table-container">
55
+ const content = (<table role="presentation" className="properties-mr-table-container">
56
56
  <tbody>
57
57
  <tr className={classNames("properties-mr-table-content", { "disabled": this.props.disabled })}>
58
58
  <td>
@@ -112,7 +112,10 @@ export const MESSAGE_KEYS = {
112
112
  TOGGLE_ON_LABEL: "toggle.on.label",
113
113
  TOGGLE_OFF_LABEL: "toggle.off.label",
114
114
  SHOW_PASSWORD_TOOLTIP: "passwordShow.tooltip",
115
- HIDE_PASSWORD_TOOLTIP: "passwordHide.tooltip"
115
+ HIDE_PASSWORD_TOOLTIP: "passwordHide.tooltip",
116
+ LABEL_INDICATOR_REQUIRED: "label.indicator.required",
117
+ LABEL_INDICATOR_OPTIONAL: "label.indicator.optional",
118
+ EMPTY_LIST_PLACEHOLDER: "emptyList.placeholder"
116
119
  };
117
120
 
118
121
  export const TRUNCATE_LIMIT = 10000;
@@ -49,7 +49,7 @@ import ReadonlyTableControl from "./readonlytable";
49
49
 
50
50
  import ControlItem from "./../components/control-item";
51
51
  import ActionFactory from "./../actions/action-factory.js";
52
- import { has } from "lodash";
52
+ import { has, get } from "lodash";
53
53
 
54
54
  /*
55
55
  * <ControlItem /> should be called from every control.
@@ -93,7 +93,7 @@ const tableControls = [
93
93
  export default class ControlFactory {
94
94
 
95
95
  constructor(controller) {
96
- this.rightFlyout = true;
96
+ this.rightFlyout = controller ? get(controller.getPropertiesConfig(), "rightFlyout", false) : false;
97
97
  this.controller = controller;
98
98
  this.actionFactory = new ActionFactory(this.controller);
99
99
  }
@@ -113,8 +113,12 @@ export default class ControlFactory {
113
113
  * @param tableInfo
114
114
  */
115
115
  createControlItem(control, propertyId, tableInfo) {
116
- const controlObj = this.createControl(control, propertyId, tableInfo);
117
116
  const hidden = this.controller.getControlState(propertyId) === STATES.HIDDEN;
117
+ if (hidden) {
118
+ return null; // Do not render hidden controls
119
+ }
120
+
121
+ const controlObj = this.createControl(control, propertyId, tableInfo);
118
122
  const className = control.className ? control.className : "";
119
123
 
120
124
  /*
@@ -128,7 +132,7 @@ export default class ControlFactory {
128
132
  // When control-item displays other controls, add padding on control-item
129
133
  return (
130
134
  <div key={"properties-ctrl-" + control.name} data-id={"properties-ctrl-" + control.name}
131
- className={classNames("properties-ctrl-wrapper", { "hide": hidden }, className)}
135
+ className={classNames("properties-ctrl-wrapper", className)}
132
136
  >
133
137
  <ControlItem
134
138
  key={"ctrl-item-" + control.name}
@@ -39,7 +39,4 @@
39
39
  width: 100%;
40
40
  }
41
41
  }
42
- &.hide {
43
- display: none;
44
- }
45
42
  }
@@ -18,7 +18,7 @@ import React from "react";
18
18
  import PropTypes from "prop-types";
19
19
  import { connect } from "react-redux";
20
20
  import { SelectItem, Select, Dropdown, ComboBox } from "carbon-components-react";
21
- import { isEqual } from "lodash";
21
+ import { isEqual, isEmpty } from "lodash";
22
22
  import * as ControlUtils from "./../../util/control-utils";
23
23
  import ValidationMessage from "./../../components/validation-message";
24
24
  import classNames from "classnames";
@@ -30,11 +30,22 @@ import { formatMessage } from "./../../util/property-utils";
30
30
  class DropDown extends React.Component {
31
31
  constructor(props) {
32
32
  super(props);
33
+ this.reactIntl = props.controller.getReactIntl();
33
34
  this.emptyLabel = "...";
34
- if (props.control.additionalText) {
35
+ this.disableEmptyListDropdown = false;
36
+ if (isEmpty(props.controlOpts)) {
37
+ // For empty dropdown, get placeholder text from resources
38
+ const overrideEmptyListPlaceholder = `${this.props.control.name}.emptyList.placeholder`;
39
+ const defaultEmptyListPlaceholder = formatMessage(this.reactIntl, MESSAGE_KEYS.EMPTY_LIST_PLACEHOLDER);
40
+ this.emptyLabel = props.controller.getResource(overrideEmptyListPlaceholder, defaultEmptyListPlaceholder);
41
+ // Disable empty dropdown when [property_id].emptyList.placeholder is set in resources
42
+ if (this.emptyLabel !== defaultEmptyListPlaceholder) {
43
+ this.disableEmptyListDropdown = true;
44
+ }
45
+ } else if (props.control.additionalText) {
46
+ // For non-empty dropdown, get placeholder text from place_holder_text in parameter_info
35
47
  this.emptyLabel = props.control.additionalText;
36
48
  }
37
- this.reactIntl = props.controller.getReactIntl();
38
49
  this.id = ControlUtils.getControlId(this.props.propertyId);
39
50
  this.handleChange = this.handleChange.bind(this);
40
51
  this.handleComboOnChange = this.handleComboOnChange.bind(this);
@@ -205,7 +216,7 @@ class DropDown extends React.Component {
205
216
  hideLabel
206
217
  inline
207
218
  labelText={this.props.control.label ? this.props.control.label.text : ""}
208
- disabled={this.props.state === STATES.DISABLED}
219
+ disabled={this.props.state === STATES.DISABLED || this.disableEmptyListDropdown}
209
220
  onChange={this.handleChange}
210
221
  value={selection}
211
222
  light={this.props.controller.getLight() && this.props.control.light}
@@ -217,7 +228,7 @@ class DropDown extends React.Component {
217
228
  {...validationProps}
218
229
  ariaLabel={this.props.control.label ? this.props.control.label.text : ""}
219
230
  id={`${ControlUtils.getDataId(this.props.propertyId)}-dropdown`}
220
- disabled={this.props.state === STATES.DISABLED}
231
+ disabled={this.props.state === STATES.DISABLED || this.disableEmptyListDropdown}
221
232
  placeholder={dropDown.selectedOption.label}
222
233
  selectedItem={dropDown.selectedOption.label}
223
234
  items={dropDown.options}
@@ -231,7 +242,7 @@ class DropDown extends React.Component {
231
242
  dropdownComponent = (<Dropdown
232
243
  {...validationProps}
233
244
  id={`${ControlUtils.getDataId(this.props.propertyId)}-dropdown`}
234
- disabled={this.props.state === STATES.DISABLED}
245
+ disabled={this.props.state === STATES.DISABLED || this.disableEmptyListDropdown}
235
246
  type="default"
236
247
  items={dropDown.options}
237
248
  onChange={this.handleChange}
@@ -43,7 +43,7 @@ class SelectColumnsControl extends AbstractTable {
43
43
  makeRows(controlValue, tableState) {
44
44
  const rows = [];
45
45
  if (controlValue) {
46
- for (var rowIndex = 0; rowIndex < controlValue.length; rowIndex++) {
46
+ for (let rowIndex = 0; rowIndex < controlValue.length; rowIndex++) {
47
47
  const columns = [];
48
48
  // If the propertyId contains 'row' then this selectcolumns control is part of a table.
49
49
  // Need to add an additional 'index' to retrieve the correct value from the control within a table.
@@ -141,7 +141,7 @@ class SelectColumnsControl extends AbstractTable {
141
141
  emptyTablePlaceholder={this.props.control.additionalText}
142
142
  />);
143
143
 
144
- var content = (
144
+ const content = (
145
145
  <div>
146
146
  <div className="properties-column-select-table">
147
147
  {table}
@@ -183,6 +183,9 @@ export class Control {
183
183
  if (settings.className) {
184
184
  this.className = settings.className;
185
185
  }
186
+ if (settings.showRequiredLabel) {
187
+ this.showRequiredLabel = settings.showRequiredLabel;
188
+ }
186
189
  if (settings.buttons) {
187
190
  this.buttons = settings.buttons;
188
191
  }
@@ -649,6 +649,7 @@ function _makeControl(parameterMetadata, paramName, group, structureDefinition,
649
649
  settings.action = action;
650
650
  settings.customValueAllowed = parameter.customValueAllowed;
651
651
  settings.className = parameter.className;
652
+ settings.showRequiredLabel = parameter.showRequiredLabel;
652
653
  settings.buttons = buttons;
653
654
  settings.light = _isControlLight(additionalInfo.light, additionalInfo.containerType, parameter.isSubPanelEdit());
654
655
  if (isSubControl) {
@@ -20,6 +20,7 @@ import { makePrimaryTab } from "./EditorForm";
20
20
  import { UIItem } from "./UIItem";
21
21
  import { L10nProvider } from "../util/L10nProvider";
22
22
  import { translateMessages } from "./Conditions";
23
+ import { convertValueDataTypes } from "../util/property-utils";
23
24
  import { Size } from "../constants/form-constants";
24
25
  import { CONTAINER_TYPE } from "../constants/constants";
25
26
 
@@ -44,8 +45,9 @@ export default class Form {
44
45
  * Returns a new Form
45
46
  * @param paramDef Parameter definition
46
47
  * @param containerType Type of container common properties will be displayed in, set in propertiesConfig
48
+ * @param shouldConvertValueDataTypes Boolean, if true, convert the currentParameters values into the type defined in parameterDef
47
49
  */
48
- static makeForm(paramDef, containerType) {
50
+ static makeForm(paramDef, containerType, shouldConvertValueDataTypes) {
49
51
  const propDef = PropertyDef.makePropertyDef(propertyOf(paramDef)("titleDefinition"), propertyOf(paramDef)("parameters"), propertyOf(paramDef)("complex_types"),
50
52
  propertyOf(paramDef)("uihints"));
51
53
  const resources = propertyOf(paramDef)("resources");
@@ -59,8 +61,13 @@ export default class Form {
59
61
  }
60
62
  }
61
63
 
64
+ let currentParameters = propertyOf(paramDef)("current_parameters");
65
+ if (shouldConvertValueDataTypes) {
66
+ currentParameters = convertValueDataTypes(currentParameters, propDef.parameterMetadata.paramDefs);
67
+ }
68
+
62
69
  const data = {
63
- currentParameters: propertyOf(paramDef)("current_parameters"),
70
+ currentParameters: currentParameters,
64
71
  uiCurrentParameters: propertyOf(paramDef)("current_ui_parameters"),
65
72
  datasetMetadata: propertyOf(paramDef)("dataset_metadata")
66
73
  };