@elyra/canvas 12.42.0 → 12.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/dist/{canvas-constants-ff5cf88e.js → canvas-constants-089e7830.js} +2 -2
  2. package/dist/{canvas-constants-ff5cf88e.js.map → canvas-constants-089e7830.js.map} +1 -1
  3. package/dist/{canvas-constants-13b58448.js → canvas-constants-69e90162.js} +2 -2
  4. package/dist/{canvas-constants-13b58448.js.map → canvas-constants-69e90162.js.map} +1 -1
  5. package/dist/canvas-controller-3e6b8ce4.js +2 -0
  6. package/dist/canvas-controller-3e6b8ce4.js.map +1 -0
  7. package/dist/canvas-controller-c6274fad.js +2 -0
  8. package/dist/canvas-controller-c6274fad.js.map +1 -0
  9. package/dist/{canvas-logger-295dafe4.js → canvas-logger-6f4b2551.js} +2 -2
  10. package/dist/{canvas-logger-295dafe4.js.map → canvas-logger-6f4b2551.js.map} +1 -1
  11. package/dist/{canvas-logger-e07a0b4a.js → canvas-logger-ab9d9048.js} +2 -2
  12. package/dist/{canvas-logger-e07a0b4a.js.map → canvas-logger-ab9d9048.js.map} +1 -1
  13. package/dist/common-canvas-6ed21ab6.js +2 -0
  14. package/dist/common-canvas-6ed21ab6.js.map +1 -0
  15. package/dist/common-canvas-8abf016c.js +2 -0
  16. package/dist/common-canvas-8abf016c.js.map +1 -0
  17. package/dist/common-canvas.es.js +1 -1
  18. package/dist/common-canvas.es.js.map +1 -1
  19. package/dist/common-canvas.js +1 -1
  20. package/dist/common-canvas.js.map +1 -1
  21. package/dist/common-properties-88377242.js +2 -0
  22. package/dist/common-properties-88377242.js.map +1 -0
  23. package/dist/common-properties-b295acc8.js +2 -0
  24. package/dist/common-properties-b295acc8.js.map +1 -0
  25. package/dist/context-menu-wrapper-949393c7.js +2 -0
  26. package/dist/context-menu-wrapper-949393c7.js.map +1 -0
  27. package/dist/context-menu-wrapper-f62dfcdb.js +2 -0
  28. package/dist/context-menu-wrapper-f62dfcdb.js.map +1 -0
  29. package/dist/{createClass-440000a3.js → createClass-02596015.js} +2 -2
  30. package/dist/createClass-02596015.js.map +1 -0
  31. package/dist/createClass-155bf7da.js +2 -0
  32. package/dist/createClass-155bf7da.js.map +1 -0
  33. package/dist/datarecord-metadata-v3-schema-07d18e19.js +2 -0
  34. package/dist/{datarecord-metadata-v3-schema-98ec66e9.js.map → datarecord-metadata-v3-schema-07d18e19.js.map} +1 -1
  35. package/dist/datarecord-metadata-v3-schema-df939dd1.js +2 -0
  36. package/dist/{datarecord-metadata-v3-schema-dba0b214.js.map → datarecord-metadata-v3-schema-df939dd1.js.map} +1 -1
  37. package/dist/defineProperty-ad55dbff.js +2 -0
  38. package/dist/{defineProperty-3dc7d8d0.js.map → defineProperty-ad55dbff.js.map} +1 -1
  39. package/dist/{defineProperty-6d406743.js → defineProperty-bcc9968d.js} +2 -2
  40. package/dist/{defineProperty-6d406743.js.map → defineProperty-bcc9968d.js.map} +1 -1
  41. package/dist/flexible-table-c6a8b402.js +2 -0
  42. package/dist/{flexible-table-7c7de0f9.js.map → flexible-table-c6a8b402.js.map} +1 -1
  43. package/dist/flexible-table-f7b294a0.js +2 -0
  44. package/dist/{flexible-table-35e9922a.js.map → flexible-table-f7b294a0.js.map} +1 -1
  45. package/dist/{icon-9edff40c.js → icon-56b27c4f.js} +2 -2
  46. package/dist/{icon-9edff40c.js.map → icon-56b27c4f.js.map} +1 -1
  47. package/dist/{icon-e622f99b.js → icon-8ec2f0ec.js} +2 -2
  48. package/dist/{icon-e622f99b.js.map → icon-8ec2f0ec.js.map} +1 -1
  49. package/dist/index-01cbacf9.js +2 -0
  50. package/dist/{index-e2f8a935.js.map → index-01cbacf9.js.map} +1 -1
  51. package/dist/index-79543d41.js +2 -0
  52. package/dist/{index-94fec521.js.map → index-79543d41.js.map} +1 -1
  53. package/dist/inherits-42ae8426.js +2 -0
  54. package/dist/inherits-42ae8426.js.map +1 -0
  55. package/dist/inherits-75817f22.js +2 -0
  56. package/dist/inherits-75817f22.js.map +1 -0
  57. package/dist/isArrayLikeObject-04f333a5.js +1 -1
  58. package/dist/isArrayLikeObject-04f333a5.js.map +1 -1
  59. package/dist/isArrayLikeObject-7a30aa4b.js +1 -1
  60. package/dist/isArrayLikeObject-7a30aa4b.js.map +1 -1
  61. package/dist/lib/canvas-controller.es.js +1 -1
  62. package/dist/lib/canvas-controller.js +1 -1
  63. package/dist/lib/canvas.es.js +1 -1
  64. package/dist/lib/canvas.js +1 -1
  65. package/dist/lib/command-stack.es.js +1 -1
  66. package/dist/lib/command-stack.es.js.map +1 -1
  67. package/dist/lib/command-stack.js +1 -1
  68. package/dist/lib/command-stack.js.map +1 -1
  69. package/dist/lib/context-menu.es.js +1 -1
  70. package/dist/lib/context-menu.js +1 -1
  71. package/dist/lib/properties/clem.es.js +2 -0
  72. package/dist/lib/properties/clem.es.js.map +1 -0
  73. package/dist/lib/properties/clem.js +2 -0
  74. package/dist/lib/properties/clem.js.map +1 -0
  75. package/dist/lib/properties/field-picker.es.js +1 -1
  76. package/dist/lib/properties/field-picker.js +1 -1
  77. package/dist/lib/properties/flexible-table.es.js +1 -1
  78. package/dist/lib/properties/flexible-table.js +1 -1
  79. package/dist/lib/properties/getPythonHints.es.js +2 -0
  80. package/dist/lib/properties/getPythonHints.es.js.map +1 -0
  81. package/dist/lib/properties/getPythonHints.js +2 -0
  82. package/dist/lib/properties/getPythonHints.js.map +1 -0
  83. package/dist/lib/properties.es.js +1 -1
  84. package/dist/lib/properties.js +1 -1
  85. package/dist/lib/tooltip.es.js +1 -1
  86. package/dist/lib/tooltip.es.js.map +1 -1
  87. package/dist/lib/tooltip.js +1 -1
  88. package/dist/lib/tooltip.js.map +1 -1
  89. package/dist/styles/common-canvas.min.css +1 -1
  90. package/dist/styles/common-canvas.min.css.map +1 -1
  91. package/dist/toolbar-235dfb9d.js +2 -0
  92. package/dist/toolbar-235dfb9d.js.map +1 -0
  93. package/dist/toolbar-6607e35c.js +2 -0
  94. package/dist/toolbar-6607e35c.js.map +1 -0
  95. package/package.json +3 -3
  96. package/rollup.config.js +2 -0
  97. package/src/color-picker/color-picker.jsx +5 -1
  98. package/src/common-canvas/canvas-controller.js +56 -1
  99. package/src/common-canvas/cc-central-items.jsx +0 -4
  100. package/src/common-canvas/cc-toolbar.jsx +35 -13
  101. package/src/common-canvas/common-canvas-utils.js +73 -2
  102. package/src/common-canvas/common-canvas.scss +8 -8
  103. package/src/common-canvas/constants/canvas-constants.js +1 -0
  104. package/src/common-canvas/svg-canvas-d3.scss +3 -2
  105. package/src/common-canvas/svg-canvas-renderer.js +184 -94
  106. package/src/common-canvas/svg-canvas-utils-external.js +1 -1
  107. package/src/common-canvas/svg-canvas-utils-links.js +28 -32
  108. package/src/common-canvas/svg-canvas-utils-nodes.js +5 -13
  109. package/src/common-properties/components/field-picker/field-picker.jsx +4 -0
  110. package/src/common-properties/controls/checkbox/checkbox.scss +0 -1
  111. package/src/common-properties/controls/expression/expression.jsx +3 -5
  112. package/src/common-properties/controls/expression/languages/python-hint.js +18 -30
  113. package/src/common-properties/controls/expression/languages/r-hint.js +16 -8
  114. package/src/common-properties/index.js +4 -2
  115. package/src/icons/icon.scss +1 -1
  116. package/src/index.js +2 -2
  117. package/src/notification-panel/notification-panel.jsx +82 -56
  118. package/src/notification-panel/notification-panel.scss +42 -40
  119. package/src/object-model/config-utils.js +2 -2
  120. package/src/object-model/layout-dimensions.js +82 -87
  121. package/src/object-model/object-model-utils.js +271 -0
  122. package/src/object-model/object-model.js +47 -245
  123. package/src/object-model/redux/reducers/canvasinfo.js +7 -11
  124. package/src/object-model/redux/reducers/canvastoolbar.js +5 -6
  125. package/src/palette/palette-dialog-topbar.jsx +27 -38
  126. package/src/palette/palette-flyout-content-category.jsx +25 -6
  127. package/src/palette/palette.scss +8 -40
  128. package/src/toolbar/index.js +18 -0
  129. package/src/toolbar/toolbar-action-item.jsx +42 -11
  130. package/src/toolbar/toolbar-button-item.jsx +49 -21
  131. package/src/toolbar/toolbar-divider-item.jsx +1 -1
  132. package/src/toolbar/toolbar-overflow-item.jsx +14 -6
  133. package/src/toolbar/toolbar-sub-menu-item.jsx +6 -5
  134. package/src/toolbar/toolbar-sub-menu.jsx +4 -6
  135. package/src/toolbar/toolbar-sub-panel.jsx +31 -18
  136. package/src/toolbar/toolbar-sub-utils.js +21 -12
  137. package/src/toolbar/toolbar.jsx +83 -26
  138. package/src/toolbar/toolbar.scss +47 -47
  139. package/src/tooltip/tooltip.jsx +56 -10
  140. package/stats.html +1 -1
  141. package/assets/images/palette/close_32.svg +0 -1
  142. package/assets/images/palette/palette_close.svg +0 -4
  143. package/assets/images/palette/palette_grid_deselected.svg +0 -2
  144. package/assets/images/palette/palette_grid_hover.svg +0 -2
  145. package/assets/images/palette/palette_grid_selected.svg +0 -2
  146. package/assets/images/palette/palette_list_deselected.svg +0 -1
  147. package/assets/images/palette/palette_list_hover.svg +0 -1
  148. package/assets/images/palette/palette_list_selected.svg +0 -1
  149. package/assets/images/palette/palette_open.svg +0 -4
  150. package/assets/images/zoom_to_fit.svg +0 -8
  151. package/dist/canvas-controller-a53943e4.js +0 -2
  152. package/dist/canvas-controller-a53943e4.js.map +0 -1
  153. package/dist/canvas-controller-cb1d7420.js +0 -2
  154. package/dist/canvas-controller-cb1d7420.js.map +0 -1
  155. package/dist/common-canvas-42027a3f.js +0 -2
  156. package/dist/common-canvas-42027a3f.js.map +0 -1
  157. package/dist/common-canvas-f758ff42.js +0 -2
  158. package/dist/common-canvas-f758ff42.js.map +0 -1
  159. package/dist/common-properties-2e1b7ec7.js +0 -2
  160. package/dist/common-properties-2e1b7ec7.js.map +0 -1
  161. package/dist/common-properties-5e8870e3.js +0 -2
  162. package/dist/common-properties-5e8870e3.js.map +0 -1
  163. package/dist/context-menu-wrapper-49f9a1af.js +0 -2
  164. package/dist/context-menu-wrapper-49f9a1af.js.map +0 -1
  165. package/dist/context-menu-wrapper-5d6a399f.js +0 -2
  166. package/dist/context-menu-wrapper-5d6a399f.js.map +0 -1
  167. package/dist/createClass-440000a3.js.map +0 -1
  168. package/dist/createClass-5ca26865.js +0 -2
  169. package/dist/createClass-5ca26865.js.map +0 -1
  170. package/dist/datarecord-metadata-v3-schema-98ec66e9.js +0 -2
  171. package/dist/datarecord-metadata-v3-schema-dba0b214.js +0 -2
  172. package/dist/defineProperty-3dc7d8d0.js +0 -2
  173. package/dist/flexible-table-35e9922a.js +0 -2
  174. package/dist/flexible-table-7c7de0f9.js +0 -2
  175. package/dist/index-94fec521.js +0 -2
  176. package/dist/index-e2f8a935.js +0 -2
  177. package/dist/inherits-226dfdb2.js +0 -2
  178. package/dist/inherits-226dfdb2.js.map +0 -1
  179. package/dist/inherits-41673c87.js +0 -2
  180. package/dist/inherits-41673c87.js.map +0 -1
  181. package/dist/toolbar-6acda0a2.js +0 -2
  182. package/dist/toolbar-6acda0a2.js.map +0 -1
  183. package/dist/toolbar-d5647da2.js +0 -2
  184. package/dist/toolbar-d5647da2.js.map +0 -1
  185. package/src/palette/palette-dialog-topbar-three-way-icon.jsx +0 -82
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2017-2023 Elyra Authors
2
+ * Copyright 2017-2024 Elyra Authors
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -339,20 +339,12 @@ export default class SvgCanvasNodes {
339
339
  return node.layout.errorHeight;
340
340
  }
341
341
 
342
- getNodeInputPortLeftPosX(node) {
343
- return this.getElementPosX(node.width, node.layout.inputPortLeftPosX, node.layout.inputPortLeftPosition);
342
+ getNodePortPosX(posInfo, node) {
343
+ return this.getElementPosX(node.width, posInfo.x_pos, posInfo.pos);
344
344
  }
345
345
 
346
- getNodeInputPortLeftPosY(node) {
347
- return this.getElementPosY(node.height, node.layout.inputPortLeftPosY, node.layout.inputPortLeftPosition);
348
- }
349
-
350
- getNodeOutputPortRightPosX(node) {
351
- return this.getElementPosX(node.width, node.layout.outputPortRightPosX, node.layout.outputPortRightPosition);
352
- }
353
-
354
- getNodeOutputPortRightPosY(node) {
355
- return this.getElementPosY(node.height, node.layout.outputPortRightPosY, node.layout.outputPortRightPosition);
346
+ getNodePortPosY(posInfo, node) {
347
+ return this.getElementPosY(node.height, posInfo.y_pos, posInfo.pos);
356
348
  }
357
349
 
358
350
  getElementPosX(width, xOffset = 0, position = "topLeft") {
@@ -315,9 +315,13 @@ export default class FieldPicker extends React.Component {
315
315
  _genResetButton() {
316
316
  const resetLabel = PropertyUtils.formatMessage(this.props.controller.getReactIntl(),
317
317
  MESSAGE_KEYS.FIELDPICKER_RESETBUTTON_LABEL);
318
+ const defaultSelections = this.props.currentFields;
319
+ const selectedFields = this.state.selectedFields;
320
+ const isSelectionEqual = defaultSelections.length === selectedFields.length && defaultSelections.every((field) => selectedFields.indexOf(field) > -1);
318
321
  return (
319
322
  <Button
320
323
  className="properties-fp-reset-button-container"
324
+ disabled={isSelectionEqual}
321
325
  onClick={this.handleReset}
322
326
  renderIcon={Reset24}
323
327
  iconDescription={resetLabel}
@@ -17,7 +17,6 @@
17
17
  .properties-checkbox {
18
18
  display: flex;
19
19
  align-items: center;
20
- flex-wrap: wrap;
21
20
  .tooltip-container {
22
21
  margin-left: $spacing-03;
23
22
  cursor: pointer;
@@ -41,12 +41,11 @@ import { Compartment } from "@codemirror/state";
41
41
  import { tags } from "@lezer/highlight";
42
42
  import { HighlightStyle, syntaxHighlighting } from "@codemirror/language";
43
43
  import { python } from "@codemirror/lang-python";
44
- import { r } from "codemirror-lang-r";
45
44
  import { sql } from "@codemirror/lang-sql";
46
45
  import { javascript } from "@codemirror/lang-javascript";
47
46
 
48
47
  import { getPythonHints } from "./languages/python-hint";
49
- import { getRHints } from "./languages/r-hint";
48
+ import { rLanguage } from "./languages/r-hint";
50
49
  import { clem } from "./languages/CLEM-hint";
51
50
 
52
51
  const pxPerChar = 8.5;
@@ -168,14 +167,13 @@ class ExpressionControl extends React.Component {
168
167
  this.origHint = getPythonHints();
169
168
  break;
170
169
  case "text/x-rsrc":
171
- language = r();
172
- this.origHint = getRHints();
170
+ language = rLanguage(); // custom language
173
171
  break;
174
172
  case "javascript":
175
173
  language = javascript();
176
174
  break;
177
175
  default:
178
- language = clem();
176
+ language = clem(); // custom language
179
177
  }
180
178
 
181
179
  // Custom completions add to the language completions
@@ -14,48 +14,36 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
+ // Ref: https://docs.python.org/3.12/reference/lexical_analysis.html#keywords
17
18
  const pythonKeywords = [
18
- "and",
19
- "del",
20
- "not",
21
- "as",
22
- "elif",
23
- "global",
24
- "or",
25
- "with",
26
- "assert",
19
+ "await",
27
20
  "else",
28
21
  "pass",
29
- "yield",
30
22
  "break",
31
23
  "except",
32
- "print",
33
24
  "in",
34
25
  "raise",
35
- "continue",
36
26
  "finally",
37
27
  "is",
38
28
  "return",
39
- "lambda"
29
+ "and",
30
+ "continue",
31
+ "lambda",
32
+ "as",
33
+ "nonlocal",
34
+ "assert",
35
+ "del",
36
+ "global",
37
+ "not",
38
+ "with",
39
+ "async",
40
+ "elif",
41
+ "or",
42
+ "yield"
40
43
  ];
41
44
 
42
- const pythonFunctions = [
43
- "basestring()",
44
- "execfile()",
45
- "file()",
46
- "raw_input()",
47
- "unichr()",
48
- "reduce()",
49
- "unicode()",
50
- "long()",
51
- "reload()",
52
- "xrange()",
53
- "cmp()",
54
- "apply()",
55
- "buffer()",
56
- "coerce()",
57
- "intern()",
58
- ];
45
+ // Ref: https://docs.python.org/3/library/functions.html
46
+ const pythonFunctions = [];
59
47
 
60
48
  function getPythonHints() {
61
49
  const pythonHints = [];
@@ -14,11 +14,9 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- const keywords = "function|if|in|break|next|repeat|else|for" +
18
- "|return|switch|while|try|tryCatch|stop|warning|require|library" +
19
- "|attach|detach|source|setMethod|setGeneric|setGroupGeneric|setClass";
20
-
21
- const rKeywords = keywords.split("|");
17
+ import { LanguageSupport, StreamLanguage } from "@codemirror/language";
18
+ import { completeFromList } from "@codemirror/autocomplete";
19
+ import { r } from "@codemirror/legacy-modes/mode/r";
22
20
 
23
21
  const builtIns = "zapsmall xzfile xtfrm xor writeLines writeChar writeBin write withVisible withRestarts within" +
24
22
  " withCallingHandlers withAutoprint with while which weekdays warnings warning version Vectorize vector vapply" +
@@ -69,13 +67,23 @@ const rBuiltIns = builtIns.split(" ");
69
67
  function getRHints() {
70
68
  const rHints = [];
71
69
 
72
- rKeywords.forEach((keyword) => rHints.push({ label: keyword, type: "keyword" }));
73
-
74
70
  rBuiltIns.forEach((builtIn) => rHints.push({ label: builtIn, type: "keyword" }));
75
71
 
76
72
  return rHints;
77
73
  }
78
74
 
75
+ // Define R language
76
+ const rLan = StreamLanguage.define(r);
77
+
78
+ // Autocompletions
79
+ const rCompletion = rLan.data.of({
80
+ autocomplete: completeFromList(getRHints())
81
+ });
82
+
83
+ function rLanguage() {
84
+ return new LanguageSupport(rLan, [rCompletion]);
85
+ }
86
+
79
87
  export {
80
- getRHints
88
+ rLanguage
81
89
  };
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2017-2023 Elyra Authors
2
+ * Copyright 2017-2024 Elyra Authors
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -18,5 +18,7 @@ import CommonProperties from "./common-properties";
18
18
  import PropertiesController from "./properties-controller";
19
19
  import FlexibleTable from "./components/flexible-table";
20
20
  import FieldPicker from "./components/field-picker";
21
+ import { clem } from "./controls/expression/languages/CLEM-hint";
22
+ import { getPythonHints } from "./controls/expression/languages/python-hint";
21
23
 
22
- export { CommonProperties, PropertiesController, FlexibleTable, FieldPicker };
24
+ export { CommonProperties, PropertiesController, FlexibleTable, FieldPicker, clem, getPythonHints };
@@ -51,5 +51,5 @@ svg.canvas-state-icon-info {
51
51
  }
52
52
 
53
53
  svg.canvas-state-icon-information-hollow {
54
- fill: $icon-01;
54
+ fill: $icon-02;
55
55
  }
package/src/index.js CHANGED
@@ -15,7 +15,7 @@
15
15
  */
16
16
 
17
17
  import { CommonCanvas, CanvasController } from "./common-canvas/index";
18
- import { CommonProperties, PropertiesController, FieldPicker, FlexibleTable } from "./common-properties/index";
18
+ import { CommonProperties, PropertiesController, FieldPicker, FlexibleTable, clem, getPythonHints } from "./common-properties/index";
19
19
  import CommandStack from "./command-stack/command-stack";
20
20
  import * as FlowValidation from "./flow-validation/validate-flow";
21
21
  import ContextMenuWrapper from "./context-menu/context-menu-wrapper";
@@ -30,6 +30,6 @@ import DisconnectObjectsAction from "../src/command-actions/disconnectObjectsAct
30
30
  import PasteAction from "../src/command-actions/pasteAction";
31
31
 
32
32
 
33
- export { CommonCanvas, CanvasController, CommonProperties, PropertiesController, FieldPicker, FlexibleTable,
33
+ export { CommonCanvas, CanvasController, CommonProperties, PropertiesController, FieldPicker, FlexibleTable, clem, getPythonHints,
34
34
  CommandStack, FlowValidation, ContextMenuWrapper, ToolTip, ColorPicker,
35
35
  CreateAutoNodeAction, CreateNodeAction, CreateNodeLinkAction, DeleteObjectsAction, DisconnectObjectsAction, PasteAction };
@@ -25,6 +25,9 @@ import Logger from "../logging/canvas-logger.js";
25
25
  import { DEFAULT_NOTIFICATION_HEADER } from "./../common-canvas/constants/canvas-constants.js";
26
26
  import defaultMessages from "../../locales/notification-panel/locales/en.json";
27
27
 
28
+ const TAB_KEY = 9;
29
+ const RETURN_KEY = 13;
30
+ const SPACE_KEY = 32;
28
31
 
29
32
  class NotificationPanel extends React.Component {
30
33
  static getDerivedStateFromProps(nextProps, prevState) {
@@ -38,18 +41,18 @@ class NotificationPanel extends React.Component {
38
41
  super(props);
39
42
  this.state = {};
40
43
 
41
- this.firstTime = true;
42
44
  this.logger = new Logger("NotificationPanel");
43
- this.handleNotificationPanelClickOutside = this.handleNotificationPanelClickOutside.bind(this);
44
- this.closeNotificationPanel = this.closeNotificationPanel.bind(this);
45
+ this.keyDownOnPanel = this.keyDownOnPanel.bind(this);
45
46
  }
46
47
 
47
48
  componentDidMount() {
48
- document.addEventListener("click", this.handleNotificationPanelClickOutside, true);
49
+ this.setFocusOnFirstItem();
49
50
  }
50
51
 
51
- componentWillUnmount() {
52
- document.removeEventListener("click", this.handleNotificationPanelClickOutside, true);
52
+ setFocusOnFirstItem() {
53
+ if (this.allRefs.length > 0) {
54
+ this.allRefs[0].focus();
55
+ }
53
56
  }
54
57
 
55
58
  getNotifications() {
@@ -79,9 +82,14 @@ class NotificationPanel extends React.Component {
79
82
  : null;
80
83
 
81
84
  const closeMessage = message.closeMessage
82
- ? (<div className = "notification-message-close" onClick={this.deleteNotification.bind(this, message.id)}>
83
- {message.closeMessage}
84
- </div>)
85
+ ? (
86
+ <div tabIndex={0} ref={(ref) => (!ref || this.allRefs.push(ref))}
87
+ className = "notification-message-close"
88
+ onClick={this.clickOnCloseButton.bind(this, message)}
89
+ onKeyDown={this.keyDownOnCloseButton.bind(this, message)}
90
+ >
91
+ {message.closeMessage}
92
+ </div>)
85
93
  : null;
86
94
 
87
95
  const timestamp = message.timestamp
@@ -99,6 +107,8 @@ class NotificationPanel extends React.Component {
99
107
  <div
100
108
  className={"notifications " + className + message.type}
101
109
  onClick={this.notificationCallback.bind(this, message.id, message.callback)}
110
+ tabIndex={0}
111
+ ref={(ref) => (!ref || this.allRefs.push(ref))}
102
112
  >
103
113
  {type}
104
114
  <div className="notification-message-details">
@@ -117,65 +127,95 @@ class NotificationPanel extends React.Component {
117
127
  return notifications;
118
128
  }
119
129
 
120
- handleNotificationPanelClickOutside(e) {
121
- if (this.props.isNotificationOpen &&
122
- this.props.notificationConfig &&
123
- !this.props.notificationConfig.keepOpen &&
124
- this.isClickOutsideNotificationPanel(e)) {
125
- this.props.canvasController.toolbarActionHandler("closeNotificationPanel");
126
- e.stopPropagation(); // Prevent D3 canvas code from clearing the selections.
130
+ notificationCallback(id, messageCallback) {
131
+ if (messageCallback) {
132
+ messageCallback(id);
127
133
  }
128
134
  }
129
135
 
130
- isClickOutsideNotificationPanel(e) {
131
- return !e.target.closest(".notification-panel");
136
+ clickOnCloseButton(message) {
137
+ this.deleteNotification(message.id);
132
138
  }
133
139
 
134
- notificationCallback(id, messageCallback) {
135
- if (messageCallback) {
136
- messageCallback(id);
140
+ keyDownOnCloseButton(message, evt) {
141
+ if (evt.keyCode === SPACE_KEY || evt.keyCode === RETURN_KEY) {
142
+ this.deleteNotification(message.id);
137
143
  }
138
144
  }
139
145
 
140
146
  deleteNotification(id) {
141
- this.props.canvasController.deleteNotificationMessages(id);
147
+ this.props.subPanelData.canvasController.deleteNotificationMessages(id);
142
148
  }
143
149
 
144
150
  clearNotificationMessages() {
145
- this.props.canvasController.clearNotificationMessages();
151
+ this.props.subPanelData.canvasController.clearNotificationMessages();
152
+ this.setFocusOnFirstItem();
153
+
146
154
  if (typeof this.props.notificationConfig.clearAllCallback === "function") {
147
155
  this.props.notificationConfig.clearAllCallback();
148
156
  }
149
157
  }
150
158
 
151
- closeNotificationPanel() {
152
- this.props.canvasController.toolbarActionHandler("closeNotificationPanel");
159
+ keyDownOnPanel(evt) {
160
+ if (evt.keyCode === TAB_KEY && !evt.shiftKey) {
161
+ const lastElement = this.allRefs[this.allRefs.length - 1];
162
+ if (evt.target === lastElement) {
163
+ evt.stopPropagation();
164
+ evt.preventDefault();
165
+ this.allRefs[0].focus();
166
+ }
167
+ } else if (evt.keyCode === TAB_KEY && evt.shiftKey) {
168
+ const lastElement = this.allRefs[this.allRefs.length - 1];
169
+ if (evt.target === this.allRefs[0]) {
170
+ evt.stopPropagation();
171
+ evt.preventDefault();
172
+ lastElement.focus();
173
+ }
174
+ }
153
175
  }
154
176
 
155
177
  render() {
156
178
  this.logger.log("render");
179
+ this.allRefs = [];
157
180
 
158
181
  if (!this.props.notificationConfig) {
159
182
  return null;
160
183
  }
161
184
 
162
- let notificationPanelClassName = this.props.isNotificationOpen ? "" : "panel-hidden";
163
- notificationPanelClassName += this.firstTime ? "" : " panel-transition";
164
- this.firstTime = false;
165
-
166
- const notificationHeader = this.props.notificationConfig && this.props.notificationConfig.notificationHeader
185
+ const headerText = this.props.notificationConfig && this.props.notificationConfig.notificationHeader
167
186
  ? this.props.notificationConfig.notificationHeader
168
187
  : DEFAULT_NOTIFICATION_HEADER;
169
188
 
189
+ const notificationHeader = (<div className="notification-panel-header">{headerText}</div>);
190
+
170
191
  const notificationSubtitle = this.props.notificationConfig && this.props.notificationConfig.notificationSubtitle
171
192
  ? (<div className="notification-panel-subtitle">
172
193
  {this.props.notificationConfig.notificationSubtitle}
173
194
  </div>)
174
195
  : null;
175
196
 
197
+ const closeButton = (
198
+ <div className="notification-panel-close-button">
199
+ <Button
200
+ ref={(ref) => (!ref || this.allRefs.push(ref))}
201
+ size="sm"
202
+ kind="ghost"
203
+ renderIcon={Close16}
204
+ hasIconOnly
205
+ iconDescription={this.props.intl.formatMessage({
206
+ id: "notification.panel.close.button.description",
207
+ defaultMessage: defaultMessages["notification.panel.close.button.description"]
208
+ })}
209
+ onClick={this.props.closeSubPanel}
210
+ tooltipAlignment="end"
211
+ tooltipPosition="bottom"
212
+ />
213
+ </div>
214
+ );
215
+
176
216
  const notificationPanelMessages = this.props.messages.length > 0
177
217
  ? this.getNotifications()
178
- : (<div className="notification-panel-empty-message-container">
218
+ : (<div tabIndex={0} ref={(ref) => (!ref || this.allRefs.push(ref))} className="notification-panel-empty-message-container">
179
219
  <div className="notification-panel-empty-message">
180
220
  {this.props.notificationConfig && this.props.notificationConfig.emptyMessage ? this.props.notificationConfig.emptyMessage : null}
181
221
  </div>
@@ -184,6 +224,7 @@ class NotificationPanel extends React.Component {
184
224
  const clearAll = this.props.notificationConfig && this.props.notificationConfig.clearAllMessage
185
225
  ? (<div className="notification-panel-clear-all-container">
186
226
  <Button
227
+ ref={(ref) => (!ref || this.props.messages.length === 0 || this.allRefs.push(ref))}
187
228
  className="notification-panel-clear-all"
188
229
  onClick={this.clearNotificationMessages.bind(this)}
189
230
  kind="ghost"
@@ -200,6 +241,7 @@ class NotificationPanel extends React.Component {
200
241
  this.props.notificationConfig.secondaryButtonCallback
201
242
  ? (<div className="notification-panel-secondary-button-container">
202
243
  <Button
244
+ ref={(ref) => (!ref || this.props.secondaryButtonDisabled || this.allRefs.push(ref))}
203
245
  className="notification-panel-secondary-button"
204
246
  onClick={this.props.notificationConfig.secondaryButtonCallback.bind(this)}
205
247
  kind="ghost"
@@ -211,28 +253,13 @@ class NotificationPanel extends React.Component {
211
253
  </div>)
212
254
  : null;
213
255
 
214
- return (<div className={"notification-panel-container " + notificationPanelClassName} >
215
- <div className="notification-panel">
216
- <div className="notification-panel-header-container">
217
- <div className="notification-panel-header">
218
- {notificationHeader}
219
- <Button
220
- className="notification-panel-close-button"
221
- size="sm"
222
- kind="ghost"
223
- renderIcon={Close16}
224
- hasIconOnly
225
- iconDescription={this.props.intl.formatMessage({
226
- id: "notification.panel.close.button.description",
227
- defaultMessage: defaultMessages["notification.panel.close.button.description"]
228
- })}
229
- onClick={this.closeNotificationPanel}
230
- tooltipAlignment="end"
231
- tooltipPosition="bottom"
232
- />
233
- </div>
256
+ return (
257
+ <div className="notification-panel" onKeyDown={this.keyDownOnPanel}>
258
+ <div className="notification-panel-header-container" tabIndex={0} ref={(ref) => (!ref || this.allRefs.push(ref))}>
259
+ {notificationHeader}
234
260
  {notificationSubtitle}
235
261
  </div>
262
+ {closeButton}
236
263
  <div className="notification-panel-messages">
237
264
  {notificationPanelMessages}
238
265
  </div>
@@ -241,13 +268,14 @@ class NotificationPanel extends React.Component {
241
268
  {secondaryButton}
242
269
  </div>
243
270
  </div>
244
- </div>);
271
+ );
245
272
  }
246
273
  }
247
274
 
248
275
  NotificationPanel.propTypes = {
249
- // Provided by CommonCanvas
250
- canvasController: PropTypes.object,
276
+ // Provided by toolbar
277
+ closeSubPanel: PropTypes.func,
278
+ subPanelData: PropTypes.object,
251
279
 
252
280
  // Provided by Redux
253
281
  notificationConfig: PropTypes.shape({
@@ -277,7 +305,6 @@ NotificationPanel.propTypes = {
277
305
  secondaryButtonDisabled: PropTypes.bool
278
306
  }),
279
307
  secondaryButtonDisabled: PropTypes.bool,
280
- isNotificationOpen: PropTypes.bool,
281
308
  messages: PropTypes.array,
282
309
  intl: PropTypes.object.isRequired
283
310
  };
@@ -285,7 +312,6 @@ NotificationPanel.propTypes = {
285
312
  const mapStateToProps = (state, ownProps) => ({
286
313
  notificationConfig: state.notificationpanel.config,
287
314
  secondaryButtonDisabled: state.notificationpanel.config ? state.notificationpanel.config.secondaryButtonDisabled : false,
288
- isNotificationOpen: state.notificationpanel.isOpen,
289
315
  messages: state.notifications
290
316
  });
291
317
 
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2017-2023 Elyra Authors
2
+ * Copyright 2017-2024 Elyra Authors
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -18,31 +18,9 @@ $notification-panel-header-height: 33px;
18
18
  $notification-message-height: 48px;
19
19
  $notification-left-border-color-width: 4px;
20
20
  $notification-panel-button-container-height: 49px;
21
- $toolbar-button-height: 41px; // Allow one extra pixel for the toolbar border
22
-
23
- // This section adds an ease-in ease-out effect for the notification-panel-container
24
- .notification-panel-container {
25
- opacity: 1;
26
- margin-top: 0;
27
- z-index: 2; // Ensure panel appears on top of bottom panel.
28
-
29
- &.panel-hidden {
30
- display: block;
31
- opacity: 0;
32
- visibility: hidden;
33
- }
34
-
35
- &.panel-transition {
36
- transition: 0.25s ease-in-out;
37
- }
38
- }
39
21
 
40
22
  .notification-panel {
41
- position: absolute;
42
- top: $toolbar-button-height;
43
- right: 0;
44
-
45
- width: 320px;
23
+ width: 318px;
46
24
  height: fit-content;
47
25
  min-height: calc(#{$notification-panel-header-height} + #{$notification-panel-button-container-height} + #{$notification-message-height});
48
26
  max-height: calc(100% - 53px);
@@ -60,23 +38,33 @@ $toolbar-button-height: 41px; // Allow one extra pixel for the toolbar border
60
38
  display: flex;
61
39
  flex-direction: column;
62
40
  justify-content: center;
63
- border: 1px solid $ui-03;
64
41
  border-bottom: 0;
65
42
  padding: $spacing-05;
43
+ outline: none; // Turn outline off and use carbon style for focus below.
44
+
45
+ &:focus {
46
+ border-color: $interactive-03;
47
+ box-shadow: inset 0 0 0 2px $interactive-03;
48
+ }
49
+
66
50
  .notification-panel-header {
67
51
  @include carbon--type-style("productive-heading-02");
68
52
  display: flex;
69
53
  justify-content: space-between;
70
54
  align-items: center;
71
55
  }
56
+
72
57
  .notification-panel-subtitle {
73
58
  @include carbon--type-style("helper-text-01");
74
59
  color: $text-02;
75
60
  padding-top: $spacing-02;
76
61
  }
77
- .notification-panel-close-button {
78
- left: $spacing-02;
79
- }
62
+ }
63
+
64
+ .notification-panel-close-button {
65
+ position: absolute;
66
+ top: 12px;
67
+ right: 12px;
80
68
  }
81
69
 
82
70
  .notification-panel-button-container {
@@ -85,7 +73,6 @@ $toolbar-button-height: 41px; // Allow one extra pixel for the toolbar border
85
73
  background-color: $ui-01;
86
74
  display: flex;
87
75
  justify-content: space-between;
88
- border: 1px solid $ui-03;
89
76
  border-top: 0;
90
77
  padding: $spacing-03 0;
91
78
  font-weight: 400;
@@ -95,17 +82,27 @@ $toolbar-button-height: 41px; // Allow one extra pixel for the toolbar border
95
82
  overflow-y: auto;
96
83
  line-height: normal;
97
84
  background-color: $ui-01;
98
- border: 1px solid $ui-03;
85
+ border-top: 1px solid $ui-03;
86
+ border-bottom: 1px solid $ui-03;
99
87
  max-height: 448px;
88
+
100
89
  .notifications-button-container {
101
90
  border-bottom: 1px solid $ui-03;
102
91
  min-height: $notification-message-height;
103
92
  }
93
+
104
94
  .notification-panel-empty-message-container {
105
95
  min-height: $notification-message-height;
106
96
  display: flex;
107
97
  justify-content: center;
108
98
  align-items: center;
99
+ outline: none; // Turn outline off and use carbon style for focus below.
100
+
101
+ &:focus {
102
+ border-color: $interactive-03;
103
+ box-shadow: inset 0 0 0 2px $interactive-03;
104
+ }
105
+
109
106
  .notification-panel-empty-message {
110
107
  @include carbon--type-style("body-short-01");
111
108
  text-align: center;
@@ -129,21 +126,19 @@ $toolbar-button-height: 41px; // Allow one extra pixel for the toolbar border
129
126
  cursor: default;
130
127
  margin-top: 0; // Required for Safari
131
128
  margin-bottom: 0; // Required for Safari
129
+ outline: none; // Turn outline off and use carbon style for focus below.
132
130
 
133
- &.clickable {
134
- cursor: pointer;
135
- }
136
-
137
- &:active,
138
131
  &:focus {
139
- outline: none;
140
- border-style: none;
141
- border-left: $notification-left-border-color-width solid $ui-01;
132
+ border-color: $interactive-03;
133
+ box-shadow: inset 0 0 0 2px $interactive-03;
142
134
  }
143
135
 
144
136
  &:hover {
145
137
  background-color: $hover-ui;
138
+ }
146
139
 
140
+ &:focus,
141
+ &:hover {
147
142
  &.unspecified {
148
143
  border-left: $notification-left-border-color-width solid $field-01;
149
144
  }
@@ -161,6 +156,10 @@ $toolbar-button-height: 41px; // Allow one extra pixel for the toolbar border
161
156
  }
162
157
  }
163
158
 
159
+ &.clickable {
160
+ cursor: pointer;
161
+ }
162
+
164
163
  .notification-message-type {
165
164
  display: flex;
166
165
  justify-content: center;
@@ -226,6 +225,9 @@ $toolbar-button-height: 41px; // Allow one extra pixel for the toolbar border
226
225
  }
227
226
  }
228
227
 
229
- .notification-message-close:hover {
230
- text-decoration: underline;
228
+ .notification-message-close {
229
+ width: fit-content;
230
+ &:hover {
231
+ text-decoration: underline;
232
+ }
231
233
  }
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2017-2023 Elyra Authors
2
+ * Copyright 2017-2024 Elyra Authors
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ import { isMatch, isMatchWith, omit } from "lodash";
21
21
  import LayoutDimensions from "./layout-dimensions.js";
22
22
  import { ASSOC_STRAIGHT, LINK_SELECTION_NONE } from "../common-canvas/constants/canvas-constants";
23
23
 
24
- export default class CanvasUtils {
24
+ export default class ConfigUtils {
25
25
 
26
26
  // Returns a config object which is the result of merging config into
27
27
  // startConfig.