@elyra/canvas 12.11.1 → 12.12.1

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 (165) hide show
  1. package/dist/_baseForOwn-7d4e8506.js +2 -0
  2. package/dist/_baseForOwn-7d4e8506.js.map +1 -0
  3. package/dist/_baseForOwn-d38b560e.js +2 -0
  4. package/dist/_baseForOwn-d38b560e.js.map +1 -0
  5. package/dist/canvas-constants-34cdb7df.js +2 -0
  6. package/dist/canvas-constants-34cdb7df.js.map +1 -0
  7. package/dist/canvas-constants-3c09c7f6.js +2 -0
  8. package/dist/canvas-constants-3c09c7f6.js.map +1 -0
  9. package/dist/canvas-controller-851afae4.js +2 -0
  10. package/dist/canvas-controller-851afae4.js.map +1 -0
  11. package/dist/canvas-controller-b856cfa3.js +2 -0
  12. package/dist/canvas-controller-b856cfa3.js.map +1 -0
  13. package/dist/canvas-logger-815781bb.js.map +1 -1
  14. package/dist/canvas-logger-a0f1beaa.js.map +1 -1
  15. package/dist/common-canvas-65512584.js +2 -0
  16. package/dist/common-canvas-65512584.js.map +1 -0
  17. package/dist/common-canvas-a2d6b5af.js +2 -0
  18. package/dist/common-canvas-a2d6b5af.js.map +1 -0
  19. package/dist/common-canvas.es.js +1 -1
  20. package/dist/common-canvas.es.js.map +1 -1
  21. package/dist/common-canvas.js +1 -1
  22. package/dist/common-canvas.js.map +1 -1
  23. package/dist/common-properties-8727d6f9.js +2 -0
  24. package/dist/common-properties-8727d6f9.js.map +1 -0
  25. package/dist/common-properties-87fef545.js +2 -0
  26. package/dist/common-properties-87fef545.js.map +1 -0
  27. package/dist/{datarecord-metadata-v3-schema-d7ad05cd.js → datarecord-metadata-v3-schema-6b6384ff.js} +2 -2
  28. package/dist/{datarecord-metadata-v3-schema-d7ad05cd.js.map → datarecord-metadata-v3-schema-6b6384ff.js.map} +1 -1
  29. package/dist/{datarecord-metadata-v3-schema-bda88f2e.js → datarecord-metadata-v3-schema-81228a9a.js} +2 -2
  30. package/dist/{datarecord-metadata-v3-schema-bda88f2e.js.map → datarecord-metadata-v3-schema-81228a9a.js.map} +1 -1
  31. package/dist/en-7a0f1db1.js +2 -0
  32. package/dist/en-7a0f1db1.js.map +1 -0
  33. package/dist/en-8647c347.js +2 -0
  34. package/dist/en-8647c347.js.map +1 -0
  35. package/dist/{extends-39f57612.js → extends-cf86ca1c.js} +2 -2
  36. package/dist/{extends-39f57612.js.map → extends-cf86ca1c.js.map} +1 -1
  37. package/dist/extends-e9462902.js +7 -0
  38. package/dist/{extends-51d9ddcc.js.map → extends-e9462902.js.map} +1 -1
  39. package/dist/flexible-table-d4a68ebb.js +2 -0
  40. package/dist/flexible-table-d4a68ebb.js.map +1 -0
  41. package/dist/flexible-table-f0c164d2.js +2 -0
  42. package/dist/flexible-table-f0c164d2.js.map +1 -0
  43. package/dist/{icon-d6909a68.js → icon-c85b53bd.js} +2 -2
  44. package/dist/{icon-d6909a68.js.map → icon-c85b53bd.js.map} +1 -1
  45. package/dist/{icon-811ffddd.js → icon-caf4caca.js} +2 -2
  46. package/dist/{icon-811ffddd.js.map → icon-caf4caca.js.map} +1 -1
  47. package/dist/index-beefcd21.js +2 -0
  48. package/dist/index-beefcd21.js.map +1 -0
  49. package/dist/index-fb90b885.js +2 -0
  50. package/dist/index-fb90b885.js.map +1 -0
  51. package/dist/isArrayLikeObject-a9c7973b.js +2 -0
  52. package/dist/isArrayLikeObject-a9c7973b.js.map +1 -0
  53. package/dist/isArrayLikeObject-f3b27f64.js +2 -0
  54. package/dist/isArrayLikeObject-f3b27f64.js.map +1 -0
  55. package/dist/lib/canvas-controller.es.js +1 -1
  56. package/dist/lib/canvas-controller.js +1 -1
  57. package/dist/lib/canvas.es.js +1 -1
  58. package/dist/lib/canvas.js +1 -1
  59. package/dist/lib/command-stack.es.js +1 -1
  60. package/dist/lib/command-stack.es.js.map +1 -1
  61. package/dist/lib/command-stack.js +1 -1
  62. package/dist/lib/command-stack.js.map +1 -1
  63. package/dist/lib/context-menu.es.js +1 -1
  64. package/dist/lib/context-menu.es.js.map +1 -1
  65. package/dist/lib/context-menu.js +1 -1
  66. package/dist/lib/context-menu.js.map +1 -1
  67. package/dist/lib/properties/field-picker.es.js +1 -1
  68. package/dist/lib/properties/field-picker.js +1 -1
  69. package/dist/lib/properties/flexible-table.es.js +1 -1
  70. package/dist/lib/properties/flexible-table.js +1 -1
  71. package/dist/lib/properties.es.js +1 -1
  72. package/dist/lib/properties.js +1 -1
  73. package/dist/lib/tooltip.es.js +1 -1
  74. package/dist/lib/tooltip.es.js.map +1 -1
  75. package/dist/lib/tooltip.js +1 -1
  76. package/dist/lib/tooltip.js.map +1 -1
  77. package/dist/styles/common-canvas.min.css +1 -1
  78. package/dist/styles/common-canvas.min.css.map +1 -1
  79. package/dist/{toolbar-335252dd.js → toolbar-a5ec3435.js} +2 -2
  80. package/dist/{toolbar-85e6c77b.js.map → toolbar-a5ec3435.js.map} +1 -1
  81. package/dist/{toolbar-85e6c77b.js → toolbar-cca1d9a9.js} +2 -2
  82. package/dist/{toolbar-335252dd.js.map → toolbar-cca1d9a9.js.map} +1 -1
  83. package/locales/command-actions/locales/en.json +8 -8
  84. package/locales/command-actions/locales/eo.json +8 -8
  85. package/locales/common-canvas/locales/en.json +3 -1
  86. package/locales/common-canvas/locales/eo.json +2 -0
  87. package/package.json +9 -10
  88. package/src/command-actions/sizeAndPositionObjectsAction.js +5 -0
  89. package/src/command-stack/command-stack.js +16 -30
  90. package/src/command-stack/internal-stack.js +89 -0
  91. package/src/common-canvas/canvas-controller.js +41 -4
  92. package/src/common-canvas/cc-contents.jsx +6 -1
  93. package/src/common-canvas/cc-toolbar.jsx +14 -4
  94. package/src/common-canvas/common-canvas-utils.js +55 -1
  95. package/src/common-canvas/common-canvas.scss +3 -1
  96. package/src/common-canvas/constants/canvas-constants.js +12 -0
  97. package/src/common-canvas/svg-canvas-d3.js +8 -0
  98. package/src/common-canvas/svg-canvas-renderer.js +300 -77
  99. package/src/common-canvas/svg-canvas-utils-links.js +61 -26
  100. package/src/common-properties/actions/button/button.jsx +45 -13
  101. package/src/common-properties/actions/button/button.scss +4 -8
  102. package/src/common-properties/common-properties.jsx +2 -1
  103. package/src/common-properties/components/control-item/control-item.jsx +7 -1
  104. package/src/common-properties/components/field-picker/field-picker.jsx +7 -8
  105. package/src/common-properties/components/flexible-table/flexible-table.jsx +45 -10
  106. package/src/common-properties/components/virtualized-table/virtualized-table.jsx +72 -20
  107. package/src/common-properties/constants/constants.js +18 -0
  108. package/src/common-properties/controls/abstract-table.jsx +3 -3
  109. package/src/common-properties/controls/checkbox/checkbox.jsx +6 -0
  110. package/src/common-properties/controls/expression/expression-builder/expression-select-field-function.jsx +4 -2
  111. package/src/common-properties/controls/expression/expression.jsx +1 -1
  112. package/src/common-properties/controls/expression/expression.scss +2 -0
  113. package/src/common-properties/controls/multiselect/multiselect.jsx +4 -4
  114. package/src/common-properties/controls/someofselect/someofselect.jsx +1 -1
  115. package/src/common-properties/form/ActionInfo.js +3 -1
  116. package/src/common-properties/form/EditorForm.js +7 -3
  117. package/src/common-properties/properties-controller.js +2 -1
  118. package/src/common-properties/properties-main/properties-main.jsx +4 -2
  119. package/src/common-properties/util/L10nProvider.js +3 -0
  120. package/src/object-model/api-pipeline.js +7 -11
  121. package/src/object-model/config-utils.js +1 -0
  122. package/src/object-model/object-model.js +73 -22
  123. package/src/object-model/pipeline-in-handler.js +8 -0
  124. package/src/object-model/pipeline-out-handler.js +5 -0
  125. package/src/object-model/redux/canvas-store.js +16 -0
  126. package/src/object-model/redux/reducers/canvasinfo.js +12 -8
  127. package/src/object-model/redux/reducers/canvastoolbar.js +6 -0
  128. package/src/object-model/redux/reducers/nodes.js +11 -0
  129. package/src/toolbar/toolbar-action-item.jsx +2 -2
  130. package/src/tooltip/tooltip.jsx +30 -1
  131. package/src/tooltip/tooltip.scss +11 -0
  132. package/stats.html +1 -1
  133. package/dist/canvas-constants-7f93e705.js +0 -2
  134. package/dist/canvas-constants-7f93e705.js.map +0 -1
  135. package/dist/canvas-constants-ac5daafb.js +0 -2
  136. package/dist/canvas-constants-ac5daafb.js.map +0 -1
  137. package/dist/canvas-controller-09d0c333.js +0 -2
  138. package/dist/canvas-controller-09d0c333.js.map +0 -1
  139. package/dist/canvas-controller-c2793ca2.js +0 -2
  140. package/dist/canvas-controller-c2793ca2.js.map +0 -1
  141. package/dist/common-canvas-5b046a86.js +0 -2
  142. package/dist/common-canvas-5b046a86.js.map +0 -1
  143. package/dist/common-canvas-985cc0a2.js +0 -2
  144. package/dist/common-canvas-985cc0a2.js.map +0 -1
  145. package/dist/common-properties-4f471b2b.js +0 -2
  146. package/dist/common-properties-4f471b2b.js.map +0 -1
  147. package/dist/common-properties-9161cd27.js +0 -2
  148. package/dist/common-properties-9161cd27.js.map +0 -1
  149. package/dist/en-2ed89528.js +0 -2
  150. package/dist/en-2ed89528.js.map +0 -1
  151. package/dist/en-e93855cc.js +0 -2
  152. package/dist/en-e93855cc.js.map +0 -1
  153. package/dist/extends-51d9ddcc.js +0 -7
  154. package/dist/flexible-table-154a3359.js +0 -2
  155. package/dist/flexible-table-154a3359.js.map +0 -1
  156. package/dist/flexible-table-5e4a1e6d.js +0 -2
  157. package/dist/flexible-table-5e4a1e6d.js.map +0 -1
  158. package/dist/index-4fd90a14.js +0 -2
  159. package/dist/index-4fd90a14.js.map +0 -1
  160. package/dist/index-6d138021.js +0 -2
  161. package/dist/index-6d138021.js.map +0 -1
  162. package/dist/isArrayLikeObject-31e5e646.js +0 -2
  163. package/dist/isArrayLikeObject-31e5e646.js.map +0 -1
  164. package/dist/isArrayLikeObject-7c33c7fd.js +0 -2
  165. package/dist/isArrayLikeObject-7c33c7fd.js.map +0 -1
@@ -249,7 +249,7 @@ class ExpressionControl extends React.Component {
249
249
  } else {
250
250
  const newValue = this.editor.getValue();
251
251
  // don't validate when opening the expression builder
252
- const skipValidate = evt.relatedTarget && evt.relatedTarget.classList.contains("properties-expression-button");
252
+ const skipValidate = evt && evt.relatedTarget && evt.relatedTarget.classList.contains("properties-expression-button");
253
253
  this.props.controller.updatePropertyValue(this.props.propertyId, newValue, skipValidate);
254
254
  }
255
255
  }
@@ -47,6 +47,8 @@
47
47
 
48
48
  .cm-s-custom .cm-def { color: $support-01; }
49
49
 
50
+ .cm-s-custom .cm-comment { color: $support-02; }
51
+
50
52
  .cm-s-custom .cm-variable,
51
53
  .cm-s-custom .cm-punctuation,
52
54
  .cm-s-custom .cm-property,
@@ -72,7 +72,7 @@ class MultiSelectControl extends React.Component {
72
72
  const selectedOptions = [];
73
73
  if (values) {
74
74
  values.forEach((value) => selectedOptions.push(options.find(function(option) {
75
- return option.value === value;
75
+ return option.id === value;
76
76
  })));
77
77
  }
78
78
  return selectedOptions;
@@ -82,7 +82,7 @@ class MultiSelectControl extends React.Component {
82
82
  const options = [];
83
83
  for (let j = 0; j < this.props.controlOpts.values.length; j++) {
84
84
  options.push({
85
- value: this.props.controlOpts.values[j],
85
+ id: this.props.controlOpts.values[j],
86
86
  label: this.props.controlOpts.valueLabels[j]
87
87
  });
88
88
  }
@@ -110,7 +110,7 @@ class MultiSelectControl extends React.Component {
110
110
  handleOnChange(evt) {
111
111
  const controlValues = [];
112
112
  for (let i = 0; i < evt.selectedItems.length; i++) {
113
- controlValues.push(evt.selectedItems[i].value);
113
+ controlValues.push(evt.selectedItems[i].id);
114
114
  }
115
115
  this.props.controller.updatePropertyValue(this.props.propertyId, controlValues);
116
116
  }
@@ -163,7 +163,7 @@ class MultiSelectControl extends React.Component {
163
163
  disabled={this.props.state === STATES.DISABLED}
164
164
  translateWithId={(id) => listBoxMenuIconTranslationIds[id]}
165
165
  items={multiSelectDropdown.options}
166
- initialSelectedItems={multiSelectDropdown.selectedOptions}
166
+ selectedItems={multiSelectDropdown.selectedOptions}
167
167
  onChange={this.handleOnChange}
168
168
  label={label}
169
169
  titleText={this.props.tableControl ? null : this.props.controlItem}
@@ -90,7 +90,7 @@ class SomeofselectControl extends React.Component {
90
90
  controlValue = [];
91
91
  }
92
92
  const tableOptions = this.genSelectOptions(controlValue);
93
- const rows = this.props.control.rows ? this.props.control.rows : 4;
93
+ const rows = this.props.control.rows ? this.props.control.rows : 5.5;
94
94
  const tableLabel = (this.props.control.label && this.props.control.label.text) ? this.props.control.label.text : "";
95
95
 
96
96
  return (
@@ -18,13 +18,14 @@
18
18
  import { ResourceDef } from "../util/L10nProvider";
19
19
 
20
20
  export class Action {
21
- constructor(actionName, label, description, control, data, image) {
21
+ constructor(actionName, label, description, control, data, image, button) {
22
22
  this.name = actionName;
23
23
  this.label = label;
24
24
  this.description = description;
25
25
  this.actionType = control;
26
26
  this.data = data;
27
27
  this.image = image;
28
+ this.button = button;
28
29
  }
29
30
  }
30
31
 
@@ -38,6 +39,7 @@ class ActionDef {
38
39
  actionDef.control = action.control;
39
40
  actionDef.data = action.data;
40
41
  actionDef.image = action.image;
42
+ actionDef.button = action.button;
41
43
  return actionDef;
42
44
  }
43
45
  return null;
@@ -60,11 +60,14 @@ class Label {
60
60
  }
61
61
 
62
62
  class Description {
63
- constructor(text, placement) {
63
+ constructor(text, placement, link) {
64
64
  this.text = text;
65
65
  if (placement) {
66
66
  this.placement = placement;
67
67
  }
68
+ if (link) {
69
+ this.link = link;
70
+ }
68
71
  }
69
72
  }
70
73
 
@@ -395,7 +398,8 @@ function _makeControl(parameterMetadata, paramName, group, structureDefinition,
395
398
  let controlDesc;
396
399
  if (parameter.description) {
397
400
  controlDesc = new Description(l10nProvider.l10nDesc(parameter, parameter.name),
398
- parameter.description ? parameter.description.placement : null);
401
+ parameter.description ? parameter.description.placement : null,
402
+ parameter.description ? parameter.description.link : null);
399
403
  }
400
404
 
401
405
  // The role is used to modify the behaviour of certain controls
@@ -699,7 +703,7 @@ function _makeAction(action, l10nProvider) {
699
703
  if (action.description) {
700
704
  actionDesc = new Description(l10nProvider.l10nDesc(action, action.id));
701
705
  }
702
- return new Action(action.id, actionLabel, actionDesc, action.control, action.data, action.image);
706
+ return new Action(action.id, actionLabel, actionDesc, action.control, action.data, action.image, action.button);
703
707
  }
704
708
 
705
709
  function _makeButtons(buttonMetadata, l10nProvider) {
@@ -42,7 +42,8 @@ export default class PropertiesController {
42
42
  actionHandler: null,
43
43
  buttonHandler: null,
44
44
  buttonIconHandler: null,
45
- titleChangeHandler: null
45
+ titleChangeHandler: null,
46
+ tooltipLinkHandler: null
46
47
  };
47
48
  this.propertiesConfig = {};
48
49
  this.visibleDefinitions = {};
@@ -63,7 +63,8 @@ class PropertiesMain extends React.Component {
63
63
  buttonHandler: props.callbacks.buttonHandler,
64
64
  buttonIconHandler: props.callbacks.buttonIconHandler,
65
65
  validationHandler: props.callbacks.validationHandler,
66
- titleChangeHandler: props.callbacks.titleChangeHandler
66
+ titleChangeHandler: props.callbacks.titleChangeHandler,
67
+ tooltipLinkHandler: props.callbacks.tooltipLinkHandler
67
68
  });
68
69
  this.setForm(props.propertiesInfo);
69
70
  this.previousErrorMessages = {};
@@ -573,7 +574,8 @@ PropertiesMain.propTypes = {
573
574
  buttonIconHandler: PropTypes.func,
574
575
  validationHandler: PropTypes.func,
575
576
  titleChangeHandler: PropTypes.func,
576
- propertiesActionLabelHandler: PropTypes.func
577
+ propertiesActionLabelHandler: PropTypes.func,
578
+ tooltipLinkHandler: PropTypes.func
577
579
  }),
578
580
  customPanels: PropTypes.array, // array of custom panels
579
581
  customControls: PropTypes.array, // array of custom controls
@@ -92,6 +92,9 @@ export class ResourceDef {
92
92
  if (resourceObj.type) {
93
93
  resource.type = resourceObj.type;
94
94
  }
95
+ if (resourceObj.link) {
96
+ resource.link = resourceObj.link;
97
+ }
95
98
  }
96
99
  return resource;
97
100
  }
@@ -25,7 +25,7 @@ import PipelineOutHandler from "./pipeline-out-handler.js";
25
25
  import CanvasUtils from "../common-canvas/common-canvas-utils";
26
26
 
27
27
  import dagre from "dagre/dist/dagre.min.js";
28
- import { cloneDeep, get, has } from "lodash";
28
+ import { cloneDeep, get, has, set } from "lodash";
29
29
 
30
30
  import { ASSOCIATION_LINK, NODE_LINK, COMMENT_LINK, VERTICAL,
31
31
  DAGRE_HORIZONTAL, DAGRE_VERTICAL,
@@ -51,10 +51,6 @@ export default class APIPipeline {
51
51
  return this.objectModel.getCanvasInfoPipeline(this.pipelineId).parentUrl;
52
52
  }
53
53
 
54
- setPipelineZoom(zoom, translate) {
55
- this.store.dispatch({ type: "SET_PIPELINE_ZOOM", data: { zoom: zoom }, pipelineId: this.pipelineId });
56
- }
57
-
58
54
  // ---------------------------------------------------------------------------
59
55
  // Node AND comment methods
60
56
  // ---------------------------------------------------------------------------
@@ -423,10 +419,8 @@ export default class APIPipeline {
423
419
  node.y_pos = 0;
424
420
  node = PipelineOutHandler.createSchemaNode(node, []);
425
421
  if (node.type === SUPER_NODE) {
426
- if (!node.app_data) {
427
- node.app_data = {};
428
- }
429
- node.app_data.pipeline_data = this.objectModel.getSchemaPipelinesForSupernode(node);
422
+ const pData = this.objectModel.getSchemaPipelinesForSupernode(node);
423
+ set(node, "app_data.ui_data.sub_pipelines", pData);
430
424
  }
431
425
  newNodes.push(node);
432
426
  }
@@ -505,7 +499,7 @@ export default class APIPipeline {
505
499
  addNode(newNode) {
506
500
  if (newNode) {
507
501
  if (newNode.type === SUPER_NODE) {
508
- this.addSupernode(newNode, get(newNode, "app_data.pipeline_data"));
502
+ this.addSupernode(newNode, get(newNode, "sub_pipelines"));
509
503
  } else {
510
504
  this.store.dispatch({ type: "ADD_NODE", data: { newNode: newNode }, pipelineId: this.pipelineId });
511
505
  }
@@ -545,7 +539,9 @@ export default class APIPipeline {
545
539
  const sn = Object.assign({}, supernode);
546
540
  if (sn.app_data) {
547
541
  sn.app_data = Object.assign({}, sn.app_data);
548
- delete sn.app_data.pipeline_data;
542
+ if (sn.app_data.ui_data) {
543
+ delete sn.app_data.ui_data.sub_pipelines;
544
+ }
549
545
  }
550
546
  return sn;
551
547
  }
@@ -62,6 +62,7 @@ export default class CanvasUtils {
62
62
  enableInternalObjectModel: true,
63
63
  enablePaletteLayout: "Flyout",
64
64
  enableToolbarLayout: "Top",
65
+ enableResizableNodes: false,
65
66
  enableInsertNodeDroppedOnLink: false,
66
67
  enableHighlightNodeOnNewLinkDrag: false,
67
68
  enableHighlightUnavailableNodes: false,
@@ -35,7 +35,8 @@ import { upgradePalette, extractPaletteVersion, LATEST_PALETTE_VERSION } from ".
35
35
  import { ASSOCIATION_LINK, COMMENT_LINK, NODE_LINK, ERROR, WARNING, SUCCESS, INFO, CREATE_PIPELINE,
36
36
  CLONE_COMMENT, CLONE_COMMENT_LINK, CLONE_NODE, CLONE_NODE_LINK, CLONE_PIPELINE, SUPER_NODE,
37
37
  HIGHLIGHT_BRANCH, HIGHLIGHT_UPSTREAM, HIGHLIGHT_DOWNSTREAM,
38
- SNAP_TO_GRID_AFTER, SNAP_TO_GRID_DURING
38
+ SNAP_TO_GRID_AFTER, SNAP_TO_GRID_DURING,
39
+ SAVE_ZOOM_LOCAL_STORAGE, SAVE_ZOOM_PIPELINE_FLOW
39
40
  } from "../common-canvas/constants/canvas-constants.js";
40
41
 
41
42
  export default class ObjectModel {
@@ -227,8 +228,8 @@ export default class ObjectModel {
227
228
  if (nodeTemplate) {
228
229
  node = PipelineInHandler.convertNode(nodeTemplate, this.getCanvasLayout());
229
230
 
230
- // PipelineInHandler will not handle the app_data.pipeline_data field of
231
- // supernodes so...
231
+ // PipelineInHandler will not handle the conversion of sub_pipelines
232
+ // in supernodes to internal format so...
232
233
  if (node.type === SUPER_NODE) {
233
234
  node = this.convertPipelineData(node);
234
235
  }
@@ -238,7 +239,7 @@ export default class ObjectModel {
238
239
  }
239
240
 
240
241
  convertPipelineData(supernode) {
241
- const pd = get(supernode, "app_data.pipeline_data");
242
+ const pd = get(supernode, "sub_pipelines");
242
243
  let newPd;
243
244
  if (pd) {
244
245
  newPd = supernode.subflow_ref.url
@@ -253,24 +254,26 @@ export default class ObjectModel {
253
254
  newPd = [newPipeline];
254
255
  set(supernode, "subflow_ref.pipeline_id_ref", newPipeline.id);
255
256
  }
256
- set(supernode, "app_data.pipeline_data", newPd);
257
+ supernode.sub_pipelines = newPd;
257
258
  return supernode;
258
259
  }
259
260
 
260
261
  // Returns an object containing nodes and pipelines. The nodes are the
261
262
  // same as the array of nodes passed in except that, any supernodes within
262
- // the array will have their app_data.pipeline_data fields removed. The
263
+ // the array will have their app_data.ui_data.sub_pipelines fields removed. The
263
264
  // pipelines returned will be any pipelines that were contained within the
264
- // app_data.pipeline_data fields.
265
+ // app_data.ui_data.sub_pipelines fields.
265
266
  extractAddDataPipelines(inNodes) {
266
267
  const pipelines = [];
267
268
  const nodes = [];
268
269
  inNodes.forEach((n) => {
269
270
  if (CanvasUtils.isSupernode(n)) {
270
- const pDataArray = get(n, "app_data.pipeline_data");
271
+ const pDataArray = get(n, "sub_pipelines");
271
272
  if (pDataArray) {
272
273
  pipelines.push(...pDataArray);
273
- delete n.app_data.pipeline_data;
274
+ if (n.sub_pipelines) {
275
+ delete n.sub_pipelines;
276
+ }
274
277
  }
275
278
  }
276
279
  nodes.push(n);
@@ -776,6 +779,7 @@ export default class ObjectModel {
776
779
  : 0;
777
780
 
778
781
  node.height = Math.max(node.inputPortsHeight, node.outputPortsHeight, node.layout.defaultNodeHeight);
782
+ node.width = node.layout.defaultNodeWidth;
779
783
 
780
784
  if (node.type === SUPER_NODE && node.is_expanded) {
781
785
  node.height += canvasLayout.supernodeTopAreaHeight + canvasLayout.supernodeSVGAreaPadding;
@@ -784,12 +788,13 @@ export default class ObjectModel {
784
788
  if (node.expanded_height) {
785
789
  node.expanded_height = Math.max(node.expanded_height, node.height);
786
790
  }
787
- }
788
- node.width = node.layout.defaultNodeWidth;
789
791
 
790
- if (node.type === SUPER_NODE && node.is_expanded) {
791
792
  node.width = CanvasUtils.getSupernodeExpandedWidth(node, canvasLayout);
792
793
  node.height = CanvasUtils.getSupernodeExpandedHeight(node, canvasLayout);
794
+
795
+ } else {
796
+ node.height = node.resizeHeight ? node.resizeHeight : node.height;
797
+ node.width = node.resizeWidth ? node.resizeWidth : node.width;
793
798
  }
794
799
 
795
800
  return node;
@@ -807,21 +812,23 @@ export default class ObjectModel {
807
812
  ? (node.outputs.length * (node.layout.portArcRadius * 2)) + ((node.outputs.length - 1) * node.layout.portArcSpacing) + (node.layout.portArcOffset * 2)
808
813
  : 0;
809
814
 
815
+ node.height = node.layout.defaultNodeHeight;
810
816
  node.width = Math.max(node.inputPortsWidth, node.outputPortsWidth, node.layout.defaultNodeWidth);
811
817
 
812
818
  if (node.type === SUPER_NODE && node.is_expanded) {
813
819
  node.width += (2 * canvasLayout.supernodeSVGAreaPadding);
814
- // If an expanded height is provided make sure it is at least as big
815
- // as the node height.
820
+ // If an expanded width is provided make sure it is at least as big
821
+ // as the node width.
816
822
  if (node.expanded_width) {
817
823
  node.expanded_width = Math.max(node.expanded_width, node.width);
818
824
  }
819
- }
820
- node.height = node.layout.defaultNodeHeight;
821
825
 
822
- if (node.type === SUPER_NODE && node.is_expanded) {
823
826
  node.width = CanvasUtils.getSupernodeExpandedWidth(node, canvasLayout);
824
827
  node.height = CanvasUtils.getSupernodeExpandedHeight(node, canvasLayout);
828
+
829
+ } else {
830
+ node.height = node.resizeHeight ? node.resizeHeight : node.height;
831
+ node.width = node.resizeWidth ? node.resizeWidth : node.width;
825
832
  }
826
833
 
827
834
  return node;
@@ -1123,11 +1130,11 @@ export default class ObjectModel {
1123
1130
  }
1124
1131
 
1125
1132
  getPipelineFlowId() {
1126
- return this.getCanvasInfo().id;
1133
+ return this.store.getPipelineFlowId();
1127
1134
  }
1128
1135
 
1129
1136
  getPrimaryPipelineId() {
1130
- return this.getCanvasInfo().primary_pipeline;
1137
+ return this.store.getPrimaryPipelineId();
1131
1138
  }
1132
1139
 
1133
1140
  getPrimaryPipeline() {
@@ -1446,7 +1453,7 @@ export default class ObjectModel {
1446
1453
  if (nodes) {
1447
1454
  nodes.forEach((node) => {
1448
1455
  let clonedNode = this.cloneNode(node);
1449
- // Pipelines in app_data.pipeline_data in supernodes will be in schema
1456
+ // Pipelines in app_data.ui_data.sub_pipelines in supernodes will be in schema
1450
1457
  // format (conforming to the pipeline flow schema) so they must be converted.
1451
1458
  if (clonedNode.type === SUPER_NODE) {
1452
1459
  clonedNode = this.convertPipelineData(clonedNode);
@@ -1912,11 +1919,55 @@ export default class ObjectModel {
1912
1919
  return obj.type === NODE_LINK || obj.type === COMMENT_LINK || obj.type === ASSOCIATION_LINK;
1913
1920
  }
1914
1921
 
1915
- // Clears any saved zom values in Local Storage
1922
+ setZoom(zoom, pipelineId) {
1923
+ const enableSaveZoom = this.getCanvasConfig().enableSaveZoom;
1924
+ // This will save zoom to the pipeline if enableSaveZoom is
1925
+ // SAVE_ZOOM_PIPELINE_FLOW and also will cause the toolbar to be updated
1926
+ // so zoom icons can be enabled/disabled.
1927
+ this.store.dispatch({ type: "SET_ZOOM", data: { zoom: zoom, enableSaveZoom }, pipelineId });
1928
+
1929
+ if (enableSaveZoom === SAVE_ZOOM_LOCAL_STORAGE) {
1930
+ this.setSavedZoomLocal(zoom, pipelineId);
1931
+ }
1932
+ }
1933
+
1934
+ // Returns the saved zoom based on the enableSaveZoom config parameter.
1935
+ getSavedZoom(pipelineId) {
1936
+ const enableSaveZoom = this.getCanvasConfig().enableSaveZoom;
1937
+ if (enableSaveZoom === SAVE_ZOOM_PIPELINE_FLOW) {
1938
+ return this.store.getZoom(pipelineId);
1939
+
1940
+ } else if (enableSaveZoom === SAVE_ZOOM_LOCAL_STORAGE) {
1941
+ return this.getSavedZoomLocal(pipelineId);
1942
+ }
1943
+ return null;
1944
+ }
1945
+
1946
+ // Clears any saved zoom values in Local Storage
1916
1947
  clearSavedZoomValues() {
1917
1948
  LocalStorage.delete("canvasSavedZoomValues");
1918
1949
  }
1919
1950
 
1951
+ // Saves the zoom object passed in for this pipeline in local storage.
1952
+ // The pipeline is identified by the pipelineFlowId and pipelineId passed in.
1953
+ setSavedZoomLocal(zoom, pipelineId) {
1954
+ const canvasSavedZoomValues = LocalStorage.get("canvasSavedZoomValues");
1955
+ const savedZooms = canvasSavedZoomValues ? JSON.parse(canvasSavedZoomValues) : {};
1956
+ set(savedZooms, [this.getPipelineFlowId(), pipelineId], zoom);
1957
+ LocalStorage.set("canvasSavedZoomValues", JSON.stringify(savedZooms));
1958
+ }
1959
+
1960
+ // Returns the zoom for this pipeline saved in local storage. The pipeline is
1961
+ // identified by the pipelineFlowId and pipelineId passed in.
1962
+ getSavedZoomLocal(pipelineId) {
1963
+ const canvasSavedZoomValues = LocalStorage.get("canvasSavedZoomValues");
1964
+ if (canvasSavedZoomValues) {
1965
+ const savedZoom = JSON.parse(canvasSavedZoomValues);
1966
+ return get(savedZoom, [this.getPipelineFlowId(), pipelineId]);
1967
+ }
1968
+ return null;
1969
+ }
1970
+
1920
1971
  // ---------------------------------------------------------------------------
1921
1972
  // Add decorations in batch
1922
1973
  // ---------------------------------------------------------------------------
@@ -2246,7 +2297,7 @@ export default class ObjectModel {
2246
2297
  const supernodes = CanvasUtils.filterSupernodes(nodes);
2247
2298
  supernodes.forEach((supernode) => {
2248
2299
  pipelines = pipelines.concat(this.getSchemaPipelinesForSupernode(supernode));
2249
- set(supernode, "app_data.pipeline_data", pipelines);
2300
+ supernode.sub_pipelines = pipelines;
2250
2301
  });
2251
2302
  }
2252
2303
 
@@ -119,6 +119,11 @@ export default class PipelineInHandler {
119
119
  if (node.type === MODEL_NODE) {
120
120
  obj.model_ref = has(node, "model_ref") ? node.model_ref : "";
121
121
  }
122
+ if (has(node, "app_data.ui_data.is_resized")) {
123
+ obj.isResized = node.app_data.ui_data.is_resized;
124
+ obj.resizeHeight = node.app_data.ui_data.resize_height;
125
+ obj.resizeWidth = node.app_data.ui_data.resize_width;
126
+ }
122
127
  if (has(node, "app_data.ui_data.description")) {
123
128
  obj.description = node.app_data.ui_data.description;
124
129
  }
@@ -131,6 +136,9 @@ export default class PipelineInHandler {
131
136
  if (has(node, "app_data.ui_data.style")) {
132
137
  obj.style = node.app_data.ui_data.style;
133
138
  }
139
+ if (has(node, "app_data.ui_data.sub_pipelines")) {
140
+ obj.sub_pipelines = node.app_data.ui_data.sub_pipelines;
141
+ }
134
142
  if (has(node, "isSupernodeInputBinding")) {
135
143
  obj.isSupernodeInputBinding = true;
136
144
  }
@@ -153,6 +153,11 @@ export default class PipelineOutHandler {
153
153
  uiData.is_expanded = ciNode.is_expanded;
154
154
  uiData.expanded_width = ciNode.expanded_width;
155
155
  uiData.expanded_height = ciNode.expanded_height;
156
+
157
+ } else if (ciNode.isResized) {
158
+ uiData.is_resized = ciNode.isResized;
159
+ uiData.resize_width = ciNode.width;
160
+ uiData.resize_height = ciNode.height;
156
161
  }
157
162
 
158
163
  if (ciNode.messages && !isEmpty(ciNode.messages)) {
@@ -105,6 +105,22 @@ export default class CanavasStore {
105
105
  return cloneDeep(this.store.getState().canvasinfo);
106
106
  }
107
107
 
108
+ getPipelineFlowId() {
109
+ return this.store.getState().canvasinfo.id;
110
+ }
111
+
112
+ getPrimaryPipelineId() {
113
+ return this.store.getState().canvasinfo.primary_pipeline;
114
+ }
115
+
116
+ getZoom(pipelineId) {
117
+ const p = this.getNonClonedPipeline(pipelineId);
118
+ if (p) {
119
+ return cloneDeep(p.zoom);
120
+ }
121
+ return null;
122
+ }
123
+
108
124
  // This is a service method for retrieving the internal pipeline. It does NOT
109
125
  // clone the pipeline therefore it should NOT be called from outside this
110
126
  // class because we don't want to surface the intenal data in redux to
@@ -18,6 +18,7 @@
18
18
  import nodes from "./nodes.js";
19
19
  import comments from "./comments.js";
20
20
  import links from "./links.js";
21
+ import { SAVE_ZOOM_PIPELINE_FLOW } from "../../../common-canvas/constants/canvas-constants.js";
21
22
 
22
23
  export default (state = {}, action) => {
23
24
  switch (action.type) {
@@ -97,14 +98,17 @@ export default (state = {}, action) => {
97
98
  return Object.assign({}, state, { pipelines: canvasInfoPipelines });
98
99
  }
99
100
 
100
- case "SET_PIPELINE_ZOOM": {
101
- const canvasInfoPipelines = state.pipelines.map((pipeline) => {
102
- if (pipeline.id === action.pipelineId) {
103
- return Object.assign({}, pipeline, { zoom: { "k": action.data.zoom.k, "x": action.data.zoom.x, "y": action.data.zoom.y } });
104
- }
105
- return pipeline;
106
- });
107
- return Object.assign({}, state, { pipelines: canvasInfoPipelines });
101
+ case "SET_ZOOM": {
102
+ if (action.data.enableSaveZoom === SAVE_ZOOM_PIPELINE_FLOW) {
103
+ const canvasInfoPipelines = state.pipelines.map((pipeline) => {
104
+ if (pipeline.id === action.pipelineId) {
105
+ return Object.assign({}, pipeline, { zoom: { "k": action.data.zoom.k, "x": action.data.zoom.x, "y": action.data.zoom.y } });
106
+ }
107
+ return pipeline;
108
+ });
109
+ return Object.assign({}, state, { pipelines: canvasInfoPipelines });
110
+ }
111
+ return state;
108
112
  }
109
113
 
110
114
  case "ADD_SUPERNODES": {
@@ -16,6 +16,12 @@
16
16
 
17
17
  export default (state = {}, action) => {
18
18
  switch (action.type) {
19
+ // Setting a zoom amount needs to cause toolbar to be re-rendered to
20
+ // enable/disable zoom buttons.
21
+ case "SET_ZOOM": {
22
+ return Object.assign({}, state);
23
+ }
24
+
19
25
  case "SET_TOOLBAR_CONFIG": {
20
26
  return Object.assign({}, state, { config: action.data.toolbarConfig });
21
27
  }
@@ -75,7 +75,18 @@ export default (state = [], action) => {
75
75
  if (newNode.type === SUPER_NODE && newNode.is_expanded) {
76
76
  newNode.expanded_width = nodeObj.width;
77
77
  newNode.expanded_height = nodeObj.height;
78
+
79
+ } else if (nodeObj.isResized) {
80
+ newNode.isResized = nodeObj.isResized;
81
+ newNode.resizeWidth = nodeObj.resizeWidth;
82
+ newNode.resizeHeight = nodeObj.resizeHeight;
83
+
84
+ } else {
85
+ delete newNode.isResized;
86
+ delete newNode.resizeWidth;
87
+ delete newNode.resizeHeight;
78
88
  }
89
+
79
90
  return newNode;
80
91
  }
81
92
 
@@ -78,9 +78,9 @@ class ToolbarActionItem extends React.Component {
78
78
  case (TOOLBAR_ZOOM_FIT):
79
79
  return <SVG src={ZoomToFit} disabled={disabled} />;
80
80
  case (TOOLBAR_ARRANGE_HORIZONALLY):
81
- return <SVG src={ArrangeVertically} disabled={disabled} />;
82
- case (TOOLBAR_ARRANGE_VERTICALLY):
83
81
  return <SVG src={ArrangeHorizontally} disabled={disabled} />;
82
+ case (TOOLBAR_ARRANGE_VERTICALLY):
83
+ return <SVG src={ArrangeVertically} disabled={disabled} />;
84
84
  case (TOOLBAR_OPEN_PALETTE):
85
85
  return <SVG src={PaletteOpen} disabled={disabled} />;
86
86
  case (TOOLBAR_CLOSE_PALETTE):
@@ -20,6 +20,7 @@
20
20
  import React from "react";
21
21
  import PropTypes from "prop-types";
22
22
  import { Portal } from "react-portal";
23
+ import { Link } from "carbon-components-react";
23
24
 
24
25
  class ToolTip extends React.Component {
25
26
  constructor(props) {
@@ -325,6 +326,10 @@ class ToolTip extends React.Component {
325
326
  }
326
327
  }
327
328
 
329
+ tooltipLinkOnClick(url) {
330
+ window.open(url, "_blank", "noopener");
331
+ }
332
+
328
333
  render() {
329
334
  let tooltipContent = null;
330
335
  let triggerContent = null;
@@ -336,7 +341,13 @@ class ToolTip extends React.Component {
336
341
  // `focus` event occurs before `click`. Adding timeout in onFocus function to ensure click is executed first.
337
342
  // Ref - https://stackoverflow.com/a/49512400
338
343
  const onFocus = () => this.showTooltipWithDelay();
339
- const onBlur = () => this.setTooltipVisible(false);
344
+ const onBlur = (evt) => {
345
+ // Keep tooltip visible when clicked on a link.
346
+ // Since link is an anchor tag without "href" attribute, it has relatedTarget=null
347
+ if (evt.relatedTarget !== null) {
348
+ this.setTooltipVisible(false);
349
+ }
350
+ };
340
351
  const click = (evt) => this.toggleTooltipOnClick(evt);
341
352
 
342
353
  triggerContent = (<div
@@ -374,6 +385,21 @@ class ToolTip extends React.Component {
374
385
  tipClass += " " + this.props.className;
375
386
  }
376
387
 
388
+ let link = null;
389
+ if (this.state.isTooltipVisible && this.props.tooltipLinkHandler && this.props.link) {
390
+ const linkInformation = this.props.tooltipLinkHandler(this.props.link);
391
+ // Verify tooltipLinkHandler returns object in correct format
392
+ if (typeof linkInformation === "object" && linkInformation.label && linkInformation.url) {
393
+ link = (<Link
394
+ className="tooltip-link"
395
+ id={this.props.link.id}
396
+ onClick={this.tooltipLinkOnClick.bind(this, linkInformation.url)}
397
+ >
398
+ {linkInformation.label}
399
+ </Link>);
400
+ }
401
+ }
402
+
377
403
  return (
378
404
  <div className="tooltip-container">
379
405
  {triggerContent}
@@ -384,6 +410,7 @@ class ToolTip extends React.Component {
384
410
  <polygon points="8.1,16.1 0,8.1 8.1,0 8.1,1.4 1.4,8.1 8.1,14.7" />
385
411
  </svg>
386
412
  {tooltipContent}
413
+ {link}
387
414
  </div>
388
415
  </Portal>
389
416
  </div>
@@ -393,6 +420,8 @@ class ToolTip extends React.Component {
393
420
 
394
421
  ToolTip.propTypes = {
395
422
  tip: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired,
423
+ link: PropTypes.object,
424
+ tooltipLinkHandler: PropTypes.func,
396
425
  direction: PropTypes.oneOf(["left", "right", "top", "bottom"]),
397
426
  children: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
398
427
  targetObj: PropTypes.object,
@@ -34,6 +34,17 @@
34
34
  word-wrap: break-word;
35
35
  max-width: 228px;
36
36
  border-radius: 2px;
37
+ .bx--link {
38
+ display: block;
39
+ color: $inverse-link;
40
+ margin-top: $spacing-05;
41
+ pointer-events: auto; // To make link clickable inside tooltip
42
+ cursor: pointer;
43
+ &:hover {
44
+ color: $inverse-link;
45
+ text-decoration: underline;
46
+ }
47
+ }
37
48
  }
38
49
 
39
50
  .common-canvas-tooltip[direction="right"] {