@elyra/canvas 12.14.0 → 12.20.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 (178) hide show
  1. package/dist/_baseForOwn-7d4e8506.js.map +1 -1
  2. package/dist/_baseForOwn-d38b560e.js.map +1 -1
  3. package/dist/canvas-constants-34cdb7df.js.map +1 -1
  4. package/dist/canvas-constants-3c09c7f6.js.map +1 -1
  5. package/dist/canvas-controller-ccb05f9f.js +2 -0
  6. package/dist/canvas-controller-ccb05f9f.js.map +1 -0
  7. package/dist/canvas-controller-feabad26.js +2 -0
  8. package/dist/canvas-controller-feabad26.js.map +1 -0
  9. package/dist/common-canvas-0c35f64f.js +2 -0
  10. package/dist/common-canvas-0c35f64f.js.map +1 -0
  11. package/dist/common-canvas-b60fe77c.js +2 -0
  12. package/dist/common-canvas-b60fe77c.js.map +1 -0
  13. package/dist/common-canvas.es.js +1 -1
  14. package/dist/common-canvas.es.js.map +1 -1
  15. package/dist/common-canvas.js +1 -1
  16. package/dist/common-canvas.js.map +1 -1
  17. package/dist/common-properties-5d20f9bf.js +2 -0
  18. package/dist/common-properties-5d20f9bf.js.map +1 -0
  19. package/dist/common-properties-80b89ad2.js +2 -0
  20. package/dist/common-properties-80b89ad2.js.map +1 -0
  21. package/dist/createClass-32a0cf0f.js.map +1 -1
  22. package/dist/createClass-6db89a23.js.map +1 -1
  23. package/dist/datarecord-metadata-v3-schema-6b6384ff.js.map +1 -1
  24. package/dist/datarecord-metadata-v3-schema-81228a9a.js.map +1 -1
  25. package/dist/en-7a0f1db1.js.map +1 -1
  26. package/dist/en-8647c347.js.map +1 -1
  27. package/dist/{extends-1139e06f.js → extends-42886b42.js} +2 -2
  28. package/dist/extends-42886b42.js.map +1 -0
  29. package/dist/{extends-8d17c85c.js → extends-634d1af7.js} +2 -2
  30. package/dist/extends-634d1af7.js.map +1 -0
  31. package/dist/flexible-table-72146c49.js +2 -0
  32. package/dist/flexible-table-72146c49.js.map +1 -0
  33. package/dist/flexible-table-fa8e4aa4.js +2 -0
  34. package/dist/flexible-table-fa8e4aa4.js.map +1 -0
  35. package/dist/getPrototypeOf-a1c3fe64.js.map +1 -1
  36. package/dist/getPrototypeOf-bf88242f.js.map +1 -1
  37. package/dist/{icon-918d2dd3.js → icon-079f1f09.js} +2 -2
  38. package/dist/{icon-918d2dd3.js.map → icon-079f1f09.js.map} +1 -1
  39. package/dist/{icon-4882a57f.js → icon-4ba4a133.js} +2 -2
  40. package/dist/{icon-4882a57f.js.map → icon-4ba4a133.js.map} +1 -1
  41. package/dist/index-ddc2e031.js +2 -0
  42. package/dist/index-ddc2e031.js.map +1 -0
  43. package/dist/{index-669f95a7.js → index-e0fcee5d.js} +2 -2
  44. package/dist/index-e0fcee5d.js.map +1 -0
  45. package/dist/isArrayLikeObject-a9c7973b.js.map +1 -1
  46. package/dist/isArrayLikeObject-f3b27f64.js.map +1 -1
  47. package/dist/lib/canvas-controller.es.js +1 -1
  48. package/dist/lib/canvas-controller.js +1 -1
  49. package/dist/lib/canvas.es.js +1 -1
  50. package/dist/lib/canvas.js +1 -1
  51. package/dist/lib/context-menu.es.js +1 -1
  52. package/dist/lib/context-menu.js +1 -1
  53. package/dist/lib/properties/field-picker.es.js +1 -1
  54. package/dist/lib/properties/field-picker.js +1 -1
  55. package/dist/lib/properties/flexible-table.es.js +1 -1
  56. package/dist/lib/properties/flexible-table.js +1 -1
  57. package/dist/lib/properties.es.js +1 -1
  58. package/dist/lib/properties.js +1 -1
  59. package/dist/styles/common-canvas.min.css +1 -1
  60. package/dist/styles/common-canvas.min.css.map +1 -1
  61. package/dist/{toolbar-3f4b173f.js → toolbar-011cf35e.js} +2 -2
  62. package/dist/{toolbar-3f4b173f.js.map → toolbar-011cf35e.js.map} +1 -1
  63. package/dist/{toolbar-29ec7983.js → toolbar-91cb4665.js} +2 -2
  64. package/dist/{toolbar-29ec7983.js.map → toolbar-91cb4665.js.map} +1 -1
  65. package/locales/command-actions/locales/de.json +8 -8
  66. package/locales/command-actions/locales/es.json +8 -8
  67. package/locales/command-actions/locales/fr.json +9 -9
  68. package/locales/command-actions/locales/index.js +3 -1
  69. package/locales/command-actions/locales/it.json +13 -13
  70. package/locales/command-actions/locales/ja.json +8 -8
  71. package/locales/command-actions/locales/ko.json +8 -8
  72. package/locales/command-actions/locales/pt-br.json +10 -10
  73. package/locales/command-actions/locales/sv.json +51 -0
  74. package/locales/command-actions/locales/zh-CN.json +8 -8
  75. package/locales/command-actions/locales/zh-TW.json +10 -10
  76. package/locales/common-canvas/locales/de.json +18 -4
  77. package/locales/common-canvas/locales/es.json +16 -2
  78. package/locales/common-canvas/locales/fr.json +16 -2
  79. package/locales/common-canvas/locales/index.js +3 -1
  80. package/locales/common-canvas/locales/it.json +17 -3
  81. package/locales/common-canvas/locales/ja.json +19 -5
  82. package/locales/common-canvas/locales/ko.json +25 -11
  83. package/locales/common-canvas/locales/pt-br.json +18 -4
  84. package/locales/common-canvas/locales/sv.json +51 -0
  85. package/locales/common-canvas/locales/zh-CN.json +15 -1
  86. package/locales/common-canvas/locales/zh-TW.json +15 -1
  87. package/locales/common-properties/locales/de.json +22 -22
  88. package/locales/common-properties/locales/en.json +3 -1
  89. package/locales/common-properties/locales/eo.json +2 -0
  90. package/locales/common-properties/locales/es.json +12 -12
  91. package/locales/common-properties/locales/fr.json +22 -22
  92. package/locales/common-properties/locales/index.js +3 -1
  93. package/locales/common-properties/locales/it.json +13 -13
  94. package/locales/common-properties/locales/ja.json +28 -28
  95. package/locales/common-properties/locales/ko.json +10 -10
  96. package/locales/common-properties/locales/pt-br.json +16 -16
  97. package/locales/common-properties/locales/sv.json +93 -0
  98. package/locales/common-properties/locales/zh-CN.json +28 -28
  99. package/locales/common-properties/locales/zh-TW.json +26 -26
  100. package/locales/palette/locales/index.js +3 -1
  101. package/locales/palette/locales/it.json +1 -1
  102. package/locales/palette/locales/ja.json +1 -1
  103. package/locales/palette/locales/pt-br.json +1 -1
  104. package/locales/palette/locales/sv.json +10 -0
  105. package/locales/palette/locales/zh-CN.json +4 -4
  106. package/locales/palette/locales/zh-TW.json +2 -2
  107. package/locales/toolbar/locales/es.json +1 -1
  108. package/locales/toolbar/locales/index.js +3 -1
  109. package/locales/toolbar/locales/it.json +2 -2
  110. package/locales/toolbar/locales/pt-br.json +1 -1
  111. package/locales/toolbar/locales/sv.json +8 -0
  112. package/package.json +2 -2
  113. package/src/command-actions/createCommentAction.js +5 -9
  114. package/src/command-actions/createSuperNodeAction.js +358 -268
  115. package/src/common-canvas/canvas-controller.js +20 -5
  116. package/src/common-canvas/common-canvas-utils.js +38 -5
  117. package/src/common-canvas/svg-canvas-d3.js +2 -2
  118. package/src/common-canvas/svg-canvas-d3.scss +17 -11
  119. package/src/common-canvas/svg-canvas-pipeline.js +10 -3
  120. package/src/common-canvas/svg-canvas-renderer.js +93 -493
  121. package/src/common-canvas/svg-canvas-utils-decs.js +0 -5
  122. package/src/common-canvas/svg-canvas-utils-links.js +5 -1
  123. package/src/common-canvas/svg-canvas-utils-nodes.js +23 -5
  124. package/src/common-canvas/svg-canvas-utils-textarea.js +472 -0
  125. package/src/common-properties/actions.js +5 -0
  126. package/src/common-properties/components/title-editor/title-editor.jsx +2 -2
  127. package/src/common-properties/components/title-editor/title-editor.scss +1 -16
  128. package/src/common-properties/components/virtualized-table/virtualized-table.jsx +5 -5
  129. package/src/common-properties/components/wide-flyout/wide-flyout.jsx +5 -2
  130. package/src/common-properties/constants/constants.js +8 -1
  131. package/src/common-properties/constants/form-constants.js +1 -0
  132. package/src/common-properties/controls/abstract-table.jsx +2 -2
  133. package/src/common-properties/controls/control-factory.js +5 -0
  134. package/src/common-properties/controls/controls.scss +1 -0
  135. package/src/common-properties/controls/dropdown/dropdown.jsx +7 -5
  136. package/src/common-properties/controls/expression/expression.jsx +2 -1
  137. package/src/common-properties/controls/expression/expression.scss +60 -33
  138. package/src/common-properties/controls/radioset/radioset.jsx +16 -14
  139. package/src/common-properties/controls/radioset/radioset.scss +13 -11
  140. package/src/common-properties/controls/someofselect/someofselect.jsx +4 -4
  141. package/src/common-properties/controls/toggle/index.jsx +18 -0
  142. package/src/common-properties/controls/toggle/toggle.jsx +89 -0
  143. package/src/common-properties/controls/toggle/toggle.scss +23 -0
  144. package/src/common-properties/panels/summary/summary.jsx +5 -2
  145. package/src/common-properties/properties-controller.js +31 -13
  146. package/src/common-properties/properties-main/properties-main.jsx +1 -0
  147. package/src/common-properties/properties-store.js +19 -2
  148. package/src/common-properties/reducers/wide-flyout-primary-button-disable.jsx +31 -0
  149. package/src/common-properties/ui-conditions/condition-ops/colDoesExists.js +9 -3
  150. package/src/common-properties/ui-conditions/conditions-utils.js +10 -16
  151. package/src/object-model/api-pipeline.js +30 -10
  152. package/src/object-model/config-utils.js +1 -0
  153. package/src/object-model/layout-dimensions.js +9 -5
  154. package/src/palette/palette-content-list-item.jsx +3 -1
  155. package/src/palette/palette-flyout-content-category.jsx +73 -42
  156. package/src/palette/palette.scss +1 -1
  157. package/stats.html +1 -1
  158. package/dist/canvas-controller-8e2bb291.js +0 -2
  159. package/dist/canvas-controller-8e2bb291.js.map +0 -1
  160. package/dist/canvas-controller-bd0d8d59.js +0 -2
  161. package/dist/canvas-controller-bd0d8d59.js.map +0 -1
  162. package/dist/common-canvas-69fe4a67.js +0 -2
  163. package/dist/common-canvas-69fe4a67.js.map +0 -1
  164. package/dist/common-canvas-f5e4af65.js +0 -2
  165. package/dist/common-canvas-f5e4af65.js.map +0 -1
  166. package/dist/common-properties-40648163.js +0 -2
  167. package/dist/common-properties-40648163.js.map +0 -1
  168. package/dist/common-properties-6d839df1.js +0 -2
  169. package/dist/common-properties-6d839df1.js.map +0 -1
  170. package/dist/extends-1139e06f.js.map +0 -1
  171. package/dist/extends-8d17c85c.js.map +0 -1
  172. package/dist/flexible-table-d3598aa8.js +0 -2
  173. package/dist/flexible-table-d3598aa8.js.map +0 -1
  174. package/dist/flexible-table-fe7fbc13.js +0 -2
  175. package/dist/flexible-table-fe7fbc13.js.map +0 -1
  176. package/dist/index-669f95a7.js.map +0 -1
  177. package/dist/index-6d3404e1.js +0 -2
  178. package/dist/index-6d3404e1.js.map +0 -1
@@ -30,11 +30,6 @@ export default class SvgCanvasDecs {
30
30
  return null;
31
31
  }
32
32
 
33
- getDecLabelForeignClass(dec) {
34
- const outlineClass = dec.label_outline ? " d3-node-label-outline" : "";
35
- return "d3-foreign-object" + outlineClass;
36
- }
37
-
38
33
  getDecLabelClass(dec, objType) {
39
34
  const lineTypeClass = dec.label_single_line ? " d3-label-single-line" : " d3-label-multi-line";
40
35
  const justificationClass = dec.label_align === "center" ? " d3-label-center" : "";
@@ -212,7 +212,11 @@ export default class SvgCanvasLinks {
212
212
  srcCenterX,
213
213
  srcCenterY);
214
214
 
215
- return { x1: startPos.x, y1: startPos.y, x2: endPos.x, y2: endPos.y };
215
+ return {
216
+ originX: startPos.originX, originY: startPos.originY,
217
+ x1: startPos.x, y1: startPos.y,
218
+ x2: endPos.x, y2: endPos.y
219
+ };
216
220
  }
217
221
 
218
222
  getCenterOffset(node, originInfo) {
@@ -23,13 +23,15 @@ export default class SvgCanvasNodes {
23
23
  this.canvasLayout = canvasLayout;
24
24
  }
25
25
 
26
- getNodeImageClass(node) {
27
- return "d3-node-image";
26
+ isPointInNodeBoundary(pos, node) {
27
+ return pos.x >= node.x_pos &&
28
+ pos.x <= node.x_pos + node.width &&
29
+ pos.y >= node.y_pos &&
30
+ pos.y <= node.y_pos + node.height;
28
31
  }
29
32
 
30
- getNodeLabelForeignClass(node) {
31
- const outlineClass = node.layout.labelOutline ? " d3-node-label-outline" : "";
32
- return "d3-foreign-object" + outlineClass;
33
+ getNodeImageClass(node) {
34
+ return "d3-node-image";
33
35
  }
34
36
 
35
37
  getNodeLabelClass(node) {
@@ -341,6 +343,22 @@ export default class SvgCanvasNodes {
341
343
  return node.layout.errorHeight;
342
344
  }
343
345
 
346
+ getNodeInputPortLeftPosX(node) {
347
+ return this.getElementPosX(node.width, node.layout.inputPortLeftPosX, node.layout.inputPortLeftPosition);
348
+ }
349
+
350
+ getNodeInputPortLeftPosY(node) {
351
+ return this.getElementPosY(node.height, node.layout.inputPortLeftPosY, node.layout.inputPortLeftPosition);
352
+ }
353
+
354
+ getNodeOutputPortRightPosX(node) {
355
+ return this.getElementPosX(node.width, node.layout.outputPortRightPosX, node.layout.outputPortRightPosition);
356
+ }
357
+
358
+ getNodeOutputPortRightPosY(node) {
359
+ return this.getElementPosY(node.height, node.layout.outputPortRightPosY, node.layout.outputPortRightPosition);
360
+ }
361
+
344
362
  getElementPosX(width, xOffset = 0, position = "topLeft") {
345
363
  let x = 0;
346
364
 
@@ -0,0 +1,472 @@
1
+ /*
2
+ * Copyright 2017-2022 Elyra Authors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /* eslint no-invalid-this: "off" */
17
+
18
+ import * as d3Selection from "d3-selection";
19
+ const d3 = Object.assign({}, d3Selection);
20
+
21
+ import { unescape as unescapeText } from "lodash";
22
+
23
+ import Logger from "../logging/canvas-logger.js";
24
+ import CanvasUtils from "./common-canvas-utils.js";
25
+ import SvgCanvasMarkdown from "./svg-canvas-utils-markdown.js";
26
+
27
+ const BACKSPACE_KEY = 8;
28
+ const RETURN_KEY = 13;
29
+ const ESC_KEY = 27;
30
+ const LEFT_ARROW_KEY = 37;
31
+ const UP_ARROW_KEY = 38;
32
+ const RIGHT_ARROW_KEY = 39;
33
+ const DOWN_ARROW_KEY = 40;
34
+ const DELETE_KEY = 46;
35
+ const A_KEY = 65;
36
+ const B_KEY = 66;
37
+ const E_KEY = 69;
38
+ const I_KEY = 73;
39
+ const K_KEY = 75;
40
+ const X_KEY = 88;
41
+ const LAB_KEY = 188; // Left angle bracket <
42
+ const RAB_KEY = 190; // Right angle bracket >
43
+ const SEVEN_KEY = 55;
44
+ const EIGHT_KEY = 56;
45
+
46
+ const SCROLL_PADDING = 12;
47
+
48
+ export default class SvgCanvasTextArea {
49
+
50
+ constructor(config, dispUtils, nodeUtils, decUtils, canvasController,
51
+ canvasDiv, activePipeline, displayCommentsCallback, displayLinksCallback, getCommentToolbarPosCallback) {
52
+
53
+ this.config = config;
54
+ this.dispUtils = dispUtils;
55
+ this.nodeUtils = nodeUtils;
56
+ this.decUtils = decUtils;
57
+ this.canvasController = canvasController;
58
+ this.canvasDiv = canvasDiv;
59
+ this.activePipeline = activePipeline;
60
+ this.displayCommentsCallback = displayCommentsCallback;
61
+ this.displayLinksCallback = displayLinksCallback;
62
+ this.getCommentToolbarPosCallback = getCommentToolbarPosCallback;
63
+
64
+ this.logger = new Logger("SvgCanvasTextArea");
65
+
66
+ // Allows us to track the editing of text (either comments or node labels)
67
+ this.editingText = false;
68
+ this.editingTextId = "";
69
+
70
+ // Keeps track of when text is in the process of being added.
71
+ this.addingTextToTextArea = false;
72
+
73
+ // Keeps track of textarea height.
74
+ this.textAreaHeight = null;
75
+ }
76
+
77
+ isEditingText() {
78
+ return this.editingText;
79
+ }
80
+
81
+ getEditingTextId() {
82
+ return this.editingTextId;
83
+ }
84
+
85
+ displayCommentTextArea(d, parentDomObj) {
86
+ this.editingTextData = {
87
+ id: d.id,
88
+ text: d.content,
89
+ singleLine: false,
90
+ maxCharacters: null,
91
+ allowReturnKey: true,
92
+ textCanBeEmpty: true,
93
+ xPos: 0,
94
+ yPos: 0,
95
+ width: d.width,
96
+ height: d.height,
97
+ className: "d3-comment-entry",
98
+ parentDomObj: parentDomObj,
99
+ keyboardInputCallback: this.config.enableMarkdownInComments ? this.commentKeyboardHandler.bind(this) : null,
100
+ autoSizeCallback: this.autoSizeComment.bind(this),
101
+ saveTextChangesCallback: this.saveCommentChanges.bind(this),
102
+ closeTextAreaCallback: this.closeCommentTextArea.bind(this)
103
+ };
104
+ this.displayTextArea(this.editingTextData);
105
+
106
+ if (this.config.enableMarkdownInComments && this.dispUtils.isDisplayingFullPage()) {
107
+ const pos = this.getCommentToolbarPosCallback(d);
108
+ this.canvasController.openTextToolbar(pos.x, pos.y,
109
+ this.markdownActionHandler.bind(this),
110
+ this.blurInTextToolbar.bind(this));
111
+ }
112
+ }
113
+
114
+ // Handles markdown actions initiated through the keyboard.
115
+ commentKeyboardHandler(d3Event) {
116
+ const action = this.getMarkdownAction(d3Event);
117
+ if (action) {
118
+ if (action !== "return") {
119
+ CanvasUtils.stopPropagationAndPreventDefault(d3Event);
120
+ }
121
+ this.markdownActionHandler(action, d3Event);
122
+ }
123
+ }
124
+
125
+ // Called when the blur event occurs for the text toolbar.
126
+ blurInTextToolbar(evt) {
127
+ // When Cypress tests are running a call to focus() in addTextToTextArea()
128
+ // can cause an incorrect blur event to be generated for the text toolbar
129
+ // (where relatedTarget is null). This flag therefore allows us to avoid
130
+ // thus blue events that occur while addTextToTextArea() is executing.
131
+ if (this.addingTextToTextArea) {
132
+ return;
133
+ }
134
+
135
+ // If there is a relatedTarget and it is set to one of the elements for the
136
+ // textarea, texttoolbar, etc we ignore the blur event.
137
+ if (evt.relatedTarget &&
138
+ (CanvasUtils.getParentElementWithClass(evt.relatedTarget, "d3-comment-entry") ||
139
+ CanvasUtils.getParentElementWithClass(evt.relatedTarget, "text-toolbar") ||
140
+ CanvasUtils.getParentElementWithClass(evt.relatedTarget, "bx--overflow-menu-options__btn"))) {
141
+ return;
142
+ }
143
+
144
+ // If the blur event is ocurring for an object outside of the textarea and
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);
151
+ }
152
+
153
+ // Applies a markdown action to the comment text being edited using
154
+ // the same commands as the toolbar.
155
+ getMarkdownAction(d3Event) {
156
+ if (CanvasUtils.isCmndCtrlPressed(d3Event)) {
157
+ switch (d3Event.keyCode) {
158
+ case B_KEY: return "bold";
159
+ case I_KEY: return "italics";
160
+ case X_KEY: return d3Event.shiftKey ? "strikethrough" : null;
161
+ case SEVEN_KEY: return d3Event.shiftKey ? "numberedList" : null;
162
+ case EIGHT_KEY: return d3Event.shiftKey ? "bulletedList" : null;
163
+ case E_KEY: return "code";
164
+ case K_KEY: return "link";
165
+ case LAB_KEY: return "decreaseHashes";
166
+ case RAB_KEY: return d3Event.shiftKey ? "quote" : "increaseHashes";
167
+ default:
168
+ }
169
+ } else if (d3Event.keyCode === RETURN_KEY) {
170
+ return "return";
171
+ }
172
+
173
+ return null;
174
+ }
175
+
176
+ // Handles any actions requested on the comment text to add markdown
177
+ // characters to the text. evt can be either a d3Event object from D3 when
178
+ // this method is called from keyboard entry in the textarea or it can be
179
+ // a synthetic event object from React when called from the text toolbar.
180
+ markdownActionHandler(action, evt) {
181
+ this.logger.log("markdownActionHandler - action = " + action);
182
+
183
+ const commentEntry = this.canvasDiv.selectAll(".d3-comment-entry");
184
+ const commentEntryElement = commentEntry.node();
185
+ const start = commentEntryElement.selectionStart;
186
+ const end = commentEntryElement.selectionEnd;
187
+ const text = commentEntryElement.value;
188
+
189
+ const mdObj = SvgCanvasMarkdown.processMarkdownAction(action, text, start, end);
190
+ if (mdObj) {
191
+ CanvasUtils.stopPropagationAndPreventDefault(evt);
192
+ this.addTextToTextArea(mdObj, commentEntryElement);
193
+ }
194
+ }
195
+
196
+ // Replaces the text in the currently displayed textarea with the text
197
+ // passed in. We use execCommand because this adds the inserted text to the
198
+ // textarea's undo/redo stack whereas setting the text directly into the
199
+ // textarea control does not.
200
+ addTextToTextArea(mdObj, commentEntryElement) {
201
+ this.addingTextToTextArea = true;
202
+ const text = unescapeText(mdObj.newText);
203
+ commentEntryElement.focus();
204
+ commentEntryElement.select();
205
+ document.execCommand("insertText", false, text);
206
+ commentEntryElement.setSelectionRange(mdObj.newStart, mdObj.newEnd);
207
+ this.addingTextToTextArea = false;
208
+ }
209
+
210
+ autoSizeComment(textArea, foreignObject, data) {
211
+ this.logger.log("autoSizeComment - textAreaHt = " + this.textAreaHeight + " scroll ht = " + textArea.scrollHeight);
212
+
213
+ const scrollHeight = textArea.scrollHeight + SCROLL_PADDING;
214
+ if (this.textAreaHeight < scrollHeight) {
215
+ this.textAreaHeight = scrollHeight;
216
+ foreignObject.style("height", this.textAreaHeight + "px");
217
+ this.activePipeline.getComment(data.id).height = this.textAreaHeight;
218
+ this.displayCommentsCallback();
219
+ this.displayLinksCallback();
220
+ }
221
+ }
222
+
223
+ saveCommentChanges(id, newText, newHeight) {
224
+ const comment = this.activePipeline.getComment(id);
225
+ const data = {
226
+ editType: "editComment",
227
+ editSource: "canvas",
228
+ id: comment.id,
229
+ content: newText,
230
+ width: comment.width,
231
+ height: newHeight,
232
+ x_pos: comment.x_pos,
233
+ y_pos: comment.y_pos,
234
+ pipelineId: this.activePipeline.id
235
+ };
236
+ this.canvasController.editActionHandler(data);
237
+ }
238
+
239
+ closeCommentTextArea() {
240
+ this.canvasController.closeTextToolbar();
241
+ }
242
+
243
+ displayNodeLabelTextArea(node, parentDomObj) {
244
+ d3.select(parentDomObj)
245
+ .selectAll("div")
246
+ .attr("style", "display:none;");
247
+
248
+ this.editingTextData = {
249
+ id: node.id,
250
+ text: node.label,
251
+ singleLine: node.layout.labelSingleLine,
252
+ maxCharacters: node.layout.labelMaxCharacters,
253
+ allowReturnKey: node.layout.labelAllowReturnKey,
254
+ textCanBeEmpty: false,
255
+ xPos: this.nodeUtils.getNodeLabelTextAreaPosX(node),
256
+ yPos: this.nodeUtils.getNodeLabelTextAreaPosY(node),
257
+ width: this.nodeUtils.getNodeLabelTextAreaWidth(node),
258
+ height: this.nodeUtils.getNodeLabelTextAreaHeight(node),
259
+ className: this.nodeUtils.getNodeLabelTextAreaClass(node),
260
+ parentDomObj: parentDomObj,
261
+ autoSizeCallback: this.autoSizeMultiLineLabel.bind(this),
262
+ saveTextChangesCallback: this.saveNodeLabelChanges.bind(this),
263
+ closeTextAreaCallback: this.closeNodeLabelTextArea.bind(this)
264
+ };
265
+ this.displayTextArea(this.editingTextData);
266
+ }
267
+
268
+ // Increases the size of the editable multi-line text area for a label based
269
+ // on the characters entered, and also ensures the maximum number of
270
+ // characters for the label, if one is provided, is not exceeded.
271
+ // This callback works for editable multi-line node labels and also
272
+ // editable multi-line text decorations for either nodes or links.
273
+ autoSizeMultiLineLabel(textArea, foreignObject, data) {
274
+ this.logger.log("autoSizeNodeLabel - textAreaHt = " + this.textAreaHeight + " scroll ht = " + textArea.scrollHeight);
275
+
276
+ // Restrict max characters in case text was pasted in to the text area.
277
+ if (data.maxCharacters &&
278
+ textArea.value.length > data.maxCharacters) {
279
+ textArea.value = textArea.value.substring(0, data.maxCharacters);
280
+ }
281
+ // Temporarily set the height to zero so the scrollHeight will get set to
282
+ // the full height of the text in the textarea. This allows us to close up
283
+ // the text area when the lines of text reduce.
284
+ foreignObject.style("height", 0);
285
+ const scrollHeight = textArea.scrollHeight + SCROLL_PADDING;
286
+ this.textAreaHeight = scrollHeight;
287
+ foreignObject.style("height", this.textAreaHeight + "px");
288
+ }
289
+
290
+ saveNodeLabelChanges(id, newText, newHeight, taData) {
291
+ const data = {
292
+ editType: "setNodeLabel",
293
+ editSource: "canvas",
294
+ nodeId: id,
295
+ label: newText,
296
+ pipelineId: this.activePipeline.id
297
+ };
298
+ this.canvasController.editActionHandler(data);
299
+ }
300
+
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);
308
+ }
309
+
310
+ // Displays a text area for an editable text decoration on either a node
311
+ // or link.
312
+ displayDecLabelTextArea(dec, obj, objType, parentDomObj) {
313
+ this.displayTextArea({
314
+ id: dec.id,
315
+ text: dec.label,
316
+ singleLine: dec.label_single_line || false,
317
+ maxCharacters: dec.label_max_characters || null,
318
+ allowReturnKey: dec.label_allow_return_key || false,
319
+ textCanBeEmpty: false,
320
+ xPos: this.decUtils.getDecLabelTextAreaPosX(),
321
+ yPos: this.decUtils.getDecLabelTextAreaPosY(),
322
+ width: this.decUtils.getDecLabelTextAreaWidth(dec, obj, objType),
323
+ height: this.decUtils.getDecLabelTextAreaHeight(dec, obj, objType),
324
+ className: this.decUtils.getDecLabelTextAreaClass(dec),
325
+ parentDomObj: parentDomObj,
326
+ objId: obj.id,
327
+ objType: objType,
328
+ autoSizeCallback: this.autoSizeMultiLineLabel.bind(this),
329
+ saveTextChangesCallback: this.saveDecLabelChanges.bind(this),
330
+ closeTextAreaCallback: null
331
+ });
332
+ }
333
+
334
+ // Handles saved changes to editable text decorations.
335
+ saveDecLabelChanges(id, newText, newHeight, taData) {
336
+ const data = {
337
+ editType: "editDecorationLabel",
338
+ editSource: "canvas",
339
+ decId: id,
340
+ objId: taData.objId,
341
+ objType: taData.objType,
342
+ label: newText,
343
+ pipelineId: this.activePipeline.id
344
+ };
345
+ this.canvasController.editActionHandler(data);
346
+ }
347
+
348
+ // Displays a text area to allow text entry and editing for: comments;
349
+ // node labels; or text decorations on either a node or link.
350
+ displayTextArea(data) {
351
+ this.textAreaHeight = data.height; // Save for comparison during auto-resize
352
+ this.editingText = true;
353
+ this.editingTextId = data.id;
354
+
355
+ const foreignObject = d3.select(data.parentDomObj)
356
+ .append("foreignObject")
357
+ .attr("class", "d3-foreign-object-text-entry")
358
+ .attr("width", data.width)
359
+ .attr("height", data.height)
360
+ .attr("x", data.xPos)
361
+ .attr("y", data.yPos);
362
+
363
+ const textArea = foreignObject
364
+ .append("xhtml:textarea")
365
+ .attr("class", data.className)
366
+ .text(unescapeText(data.text))
367
+ .on("keydown", (d3Event) => {
368
+ // Don't accept return key press when text is all on one line or
369
+ // if application doesn't want line feeds inserted in the label.
370
+ if ((data.singleLine || !data.allowReturnKey) &&
371
+ d3Event.keyCode === RETURN_KEY) {
372
+ CanvasUtils.stopPropagationAndPreventDefault(d3Event);
373
+ }
374
+ // If user presses ESC key revert back to original text by just
375
+ // closing the text area.
376
+ if (d3Event.keyCode === ESC_KEY) {
377
+ CanvasUtils.stopPropagationAndPreventDefault(d3Event);
378
+ this.textAreaEscKeyPressed = true;
379
+ this.closeTextArea(foreignObject, data);
380
+ }
381
+ // Prevent user entering more than any allowed maximum for characters.
382
+ if (data.maxCharacters &&
383
+ d3Event.target.value.length >= data.maxCharacters &&
384
+ !this.textAreaAllowedKeys(d3Event)) {
385
+ CanvasUtils.stopPropagationAndPreventDefault(d3Event);
386
+ }
387
+ // Call any specific keyboard handler for the type of
388
+ // text being edited.
389
+ if (data.keyboardInputCallback) {
390
+ data.keyboardInputCallback(d3Event);
391
+ }
392
+ })
393
+ .on("keyup", (d3Event) => {
394
+ data.autoSizeCallback(d3Event.target, foreignObject, data);
395
+ })
396
+ .on("paste", (d3Event) => {
397
+ this.logger.log("Text area - Paste - Scroll Ht = " + d3Event.target.scrollHeight);
398
+ // Allow some time for pasted text (from context menu) to be
399
+ // loaded into the text area. Otherwise the text is not there
400
+ // and the auto size does not increase the height correctly.
401
+ setTimeout(data.autoSizeCallback, 500, d3Event.target, foreignObject, data);
402
+ })
403
+ .on("blur", (d3Event, d) => {
404
+ this.logger.log("Text area - blur");
405
+ // If the esc key was pressed to cause the blur event just return
406
+ // so label returns to what it was before editing started.
407
+ if (this.textAreaEscKeyPressed) {
408
+ this.textAreaEscKeyPressed = false;
409
+ return;
410
+ }
411
+
412
+ // If the user clicked on an element in the text toolbar to cause the
413
+ // blur event, just return.
414
+ if (d3Event.relatedTarget && CanvasUtils.getParentElementWithClass(d3Event.relatedTarget, "text-toolbar")) {
415
+ return;
416
+ }
417
+
418
+ this.saveAndCloseTextArea(foreignObject, data, d3Event.target.value, d3Event);
419
+ })
420
+ .on("focus", (d3Event, d) => {
421
+ this.logger.log("Text area - focus");
422
+ data.autoSizeCallback(d3Event.target, foreignObject, data);
423
+ })
424
+ .on("mousedown click dblclick contextmenu", (d3Event, d) => {
425
+ d3Event.stopPropagation(); // Allow default behavior to show system contenxt menu
426
+ });
427
+
428
+ textArea.node().focus();
429
+
430
+ // Set the cusrsor to the end of the text.
431
+ textArea.node().setSelectionRange(data.text.length, data.text.length);
432
+ }
433
+
434
+ saveAndCloseTextArea(foreignObject, data, newValue, d3Event) {
435
+ // If there is no text for the label and textCanBeEmpty is false
436
+ // just return, so label returns to what it was before editing started.
437
+ if (!newValue && !data.textCanBeEmpty) {
438
+ CanvasUtils.stopPropagationAndPreventDefault(d3Event);
439
+ this.closeTextArea(foreignObject, data);
440
+ return;
441
+ }
442
+ const newText = newValue; // Save the text before closing the foreign object
443
+ this.closeTextArea(foreignObject, data);
444
+ if (data.text !== newText || this.textAreaHeight !== data.height) {
445
+ this.isCommentBeingUpdated = true;
446
+ data.saveTextChangesCallback(data.id, newText, this.textAreaHeight, data);
447
+ this.isCommentBeingUpdatd = false;
448
+ }
449
+ }
450
+
451
+ // Closes the text area and resets the flags.
452
+ closeTextArea(foreignObject, data) {
453
+ if (data.closeTextAreaCallback) {
454
+ data.closeTextAreaCallback(data.id);
455
+ }
456
+ foreignObject.remove();
457
+ this.editingText = false;
458
+ this.editingTextId = "";
459
+ }
460
+
461
+ // Returns true if one of the keys that are allowed in the text area, when
462
+ // checking for maximum characters, has been pressed.
463
+ textAreaAllowedKeys(d3Event) {
464
+ return d3Event.keyCode === DELETE_KEY ||
465
+ d3Event.keyCode === BACKSPACE_KEY ||
466
+ d3Event.keyCode === LEFT_ARROW_KEY ||
467
+ d3Event.keyCode === RIGHT_ARROW_KEY ||
468
+ d3Event.keyCode === UP_ARROW_KEY ||
469
+ d3Event.keyCode === DOWN_ARROW_KEY ||
470
+ (d3Event.keyCode === A_KEY && CanvasUtils.isCmndCtrlPressed(d3Event));
471
+ }
472
+ }
@@ -37,6 +37,7 @@ export const SET_TITLE = "SET_TITLE";
37
37
  export const SET_ACTIVE_TAB = "SET_ACTIVE_TAB";
38
38
  export const DISABLE_ROW_MOVE_BUTTONS = "DISABLE_ROW_MOVE_BUTTONS";
39
39
  export const SET_SAVE_BUTTON_DISABLE = "SET_SAVE_BUTTON_DISABLE";
40
+ export const SET_WIDE_FLYOUT_PRIMARY_BUTTON_DISABLED = "SET_WIDE_FLYOUT_PRIMARY_BUTTON_DISABLED";
40
41
  export const SET_ADD_REMOVE_ROWS = "SET_ADD_REMOVE_ROWS";
41
42
  export const UPDATE_STATIC_ROWS = "UPDATE_STATIC_ROWS";
42
43
  export const CLEAR_STATIC_ROWS = "CLEAR_STATIC_ROWS";
@@ -129,6 +130,10 @@ export function setSaveButtonDisable(disableState) {
129
130
  return { type: SET_SAVE_BUTTON_DISABLE, disableState };
130
131
  }
131
132
 
133
+ export function setWideFlyoutPrimaryButtonDisabled(info) {
134
+ return { type: SET_WIDE_FLYOUT_PRIMARY_BUTTON_DISABLED, info };
135
+ }
136
+
132
137
  export function setAddRemoveRows(info) {
133
138
  return { type: SET_ADD_REMOVE_ROWS, info };
134
139
  }
@@ -24,7 +24,7 @@ import { TextInput, Button } from "carbon-components-react";
24
24
  import { MESSAGE_KEYS, CONDITION_MESSAGE_TYPE } from "./../../constants/constants";
25
25
  import * as PropertyUtils from "./../../util/property-utils";
26
26
  import classNames from "classnames";
27
- import { Information16, Edit16, Close16 } from "@carbon/icons-react";
27
+ import { Help16, Edit16, Close16 } from "@carbon/icons-react";
28
28
 
29
29
 
30
30
  class TitleEditor extends Component {
@@ -121,7 +121,7 @@ class TitleEditor extends Component {
121
121
  data-id="help"
122
122
  onClick={this.helpClickHandler}
123
123
  tooltipPosition="bottom"
124
- renderIcon={Information16}
124
+ renderIcon={Help16}
125
125
  size="small"
126
126
  iconDescription={helpButtonLabel}
127
127
  hasIconOnly
@@ -34,7 +34,7 @@
34
34
  }
35
35
  .properties-title-editor-btn.help {
36
36
  &.help {
37
- margin: 0 0 0 $spacing-02; // spacing between heading label and help button
37
+ margin-left: $spacing-02; // spacing between heading label and help button
38
38
  }
39
39
  }
40
40
  }
@@ -84,21 +84,6 @@
84
84
  width: calc(100% - 2px); // subtract 2px for input active right border
85
85
  }
86
86
 
87
- .properties-title-editor-btn.help, .properties-title-editor-btn.edit {
88
- fill: $icon-02;
89
- // edit & help buttons size - 32x32
90
- width: $spacing-07;
91
- min-height: $spacing-07;
92
- padding-left: $spacing-04;
93
- padding-right: $spacing-04;
94
- &:hover {
95
- background-color: $ui-03;
96
- }
97
- &:active {
98
- background-color: $ui-03;
99
- }
100
- }
101
-
102
87
  // Close icon without heading
103
88
  .properties-close-button {
104
89
  position: relative;
@@ -396,6 +396,11 @@ class VirtualizedTable extends React.Component {
396
396
  onMouseLeave={(evt) => this.overSelectOption(evt)}
397
397
  onFocus={(evt) => this.overSelectOption(evt)}
398
398
  onBlur={(evt) => this.overSelectOption(evt)}
399
+ onKeyDown={(evt) => {
400
+ if (evt.code === "Space" || evt.code === "Enter") {
401
+ this.onRowClick(evt, rowData, index);
402
+ }
403
+ }}
399
404
  >
400
405
  <Checkbox
401
406
  id={`properties-vt-row-cb-${scrollKey}-${index}`}
@@ -442,11 +447,6 @@ class VirtualizedTable extends React.Component {
442
447
  role="row"
443
448
  style={newStyle}
444
449
  onMouseDown={(evt) => this.onRowClick(evt, rowData, index)}
445
- onKeyPress={(evt) => {
446
- if (evt.code === "Space" || evt.code === "Enter") {
447
- this.onRowClick(evt, rowData, index);
448
- }
449
- }}
450
450
  >
451
451
  {selectOption}
452
452
  {columns}
@@ -82,6 +82,7 @@ export default class WideFlyout extends Component {
82
82
  showPropertiesButtons={this.props.showPropertiesButtons}
83
83
  applyLabel={this.props.applyLabel}
84
84
  rejectLabel={this.props.rejectLabel}
85
+ applyButtonEnabled={this.props.okButtonEnabled}
85
86
  />);
86
87
  children = (<div className="properties-wf-children"> {this.props.children} </div>);
87
88
  }
@@ -109,9 +110,11 @@ WideFlyout.propTypes = {
109
110
  applyLabel: PropTypes.string,
110
111
  rejectLabel: PropTypes.string,
111
112
  title: PropTypes.string,
112
- light: PropTypes.bool
113
+ light: PropTypes.bool,
114
+ okButtonEnabled: PropTypes.bool
113
115
  };
114
116
 
115
117
  WideFlyout.defaultProps = {
116
- show: false
118
+ show: false,
119
+ okButtonEnabled: true
117
120
  };
@@ -100,7 +100,9 @@ export const MESSAGE_KEYS = {
100
100
  TOGGLETEXT_ICON_DESCRIPTION: "toggletext.icon.description",
101
101
  MULTISELECT_DROPDOWN_EMPTY_LABEL: "multiselect.dropdown.empty.label",
102
102
  MULTISELECT_DROPDOWN_OPTIONS_SELECTED_LABEL: "multiselect.dropdown.options.selected.label",
103
- PROPERTIES_EMPTY_TABLE_TEXT: "properties.empty.table.text"
103
+ PROPERTIES_EMPTY_TABLE_TEXT: "properties.empty.table.text",
104
+ TOGGLE_ON_LABEL: "toggle.on.label",
105
+ TOGGLE_OFF_LABEL: "toggle.off.label"
104
106
  };
105
107
 
106
108
  export const TRUNCATE_LIMIT = 10000;
@@ -124,6 +126,11 @@ export const CONDITION_MESSAGE_TYPE = {
124
126
 
125
127
  export const SPINNER = "spinner";
126
128
 
129
+
130
+ export const UPDATE_TYPE = {
131
+ INITIAL_LOAD: "initial_load"
132
+ };
133
+
127
134
  export const DATA_TYPE = {
128
135
  INTEGER: "integer",
129
136
  DOUBLE: "double",
@@ -78,6 +78,7 @@ const ControlType = {
78
78
  TIMEFIELD: "timefield",
79
79
  TIMESTAMP: "timestampfield",
80
80
  CHECKBOX: "checkbox",
81
+ TOGGLE: "toggle",
81
82
  RADIOSET: "radioset",
82
83
  CHECKBOXSET: "checkboxset",
83
84
  ONEOFSELECT: "oneofselect",