@elyra/canvas 12.11.0 → 12.12.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 (166) 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-d9da9919.js +2 -0
  10. package/dist/canvas-controller-d9da9919.js.map +1 -0
  11. package/dist/canvas-controller-e023521c.js +2 -0
  12. package/dist/canvas-controller-e023521c.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-3c5daa65.js +2 -0
  16. package/dist/common-canvas-3c5daa65.js.map +1 -0
  17. package/dist/common-canvas-bdfb8c87.js +2 -0
  18. package/dist/common-canvas-bdfb8c87.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 +89 -13
  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 +497 -287
  99. package/src/common-canvas/svg-canvas-utils-links.js +61 -26
  100. package/src/common-canvas/svg-canvas-utils-nodes.js +0 -10
  101. package/src/common-properties/actions/button/button.jsx +45 -13
  102. package/src/common-properties/actions/button/button.scss +4 -8
  103. package/src/common-properties/common-properties.jsx +2 -1
  104. package/src/common-properties/components/control-item/control-item.jsx +7 -1
  105. package/src/common-properties/components/field-picker/field-picker.jsx +7 -8
  106. package/src/common-properties/components/flexible-table/flexible-table.jsx +45 -10
  107. package/src/common-properties/components/virtualized-table/virtualized-table.jsx +72 -20
  108. package/src/common-properties/constants/constants.js +18 -0
  109. package/src/common-properties/controls/abstract-table.jsx +3 -3
  110. package/src/common-properties/controls/checkbox/checkbox.jsx +6 -0
  111. package/src/common-properties/controls/expression/expression-builder/expression-select-field-function.jsx +4 -2
  112. package/src/common-properties/controls/expression/expression.jsx +1 -1
  113. package/src/common-properties/controls/expression/expression.scss +3 -1
  114. package/src/common-properties/controls/multiselect/multiselect.jsx +4 -4
  115. package/src/common-properties/controls/someofselect/someofselect.jsx +1 -1
  116. package/src/common-properties/form/ActionInfo.js +3 -1
  117. package/src/common-properties/form/EditorForm.js +7 -3
  118. package/src/common-properties/properties-controller.js +2 -1
  119. package/src/common-properties/properties-main/properties-main.jsx +4 -2
  120. package/src/common-properties/util/L10nProvider.js +3 -0
  121. package/src/object-model/api-pipeline.js +1 -5
  122. package/src/object-model/config-utils.js +1 -0
  123. package/src/object-model/object-model.js +61 -12
  124. package/src/object-model/pipeline-in-handler.js +5 -0
  125. package/src/object-model/pipeline-out-handler.js +5 -0
  126. package/src/object-model/redux/canvas-store.js +16 -0
  127. package/src/object-model/redux/reducers/canvasinfo.js +12 -8
  128. package/src/object-model/redux/reducers/canvastoolbar.js +3 -0
  129. package/src/object-model/redux/reducers/nodes.js +11 -0
  130. package/src/toolbar/toolbar-action-item.jsx +2 -2
  131. package/src/tooltip/tooltip.jsx +30 -1
  132. package/src/tooltip/tooltip.scss +11 -0
  133. package/stats.html +1 -1
  134. package/dist/canvas-constants-7f93e705.js +0 -2
  135. package/dist/canvas-constants-7f93e705.js.map +0 -1
  136. package/dist/canvas-constants-ac5daafb.js +0 -2
  137. package/dist/canvas-constants-ac5daafb.js.map +0 -1
  138. package/dist/canvas-controller-183ff6a7.js +0 -2
  139. package/dist/canvas-controller-183ff6a7.js.map +0 -1
  140. package/dist/canvas-controller-d70a731e.js +0 -2
  141. package/dist/canvas-controller-d70a731e.js.map +0 -1
  142. package/dist/common-canvas-3e832a84.js +0 -2
  143. package/dist/common-canvas-3e832a84.js.map +0 -1
  144. package/dist/common-canvas-c50cb3f3.js +0 -2
  145. package/dist/common-canvas-c50cb3f3.js.map +0 -1
  146. package/dist/common-properties-4f471b2b.js +0 -2
  147. package/dist/common-properties-4f471b2b.js.map +0 -1
  148. package/dist/common-properties-9161cd27.js +0 -2
  149. package/dist/common-properties-9161cd27.js.map +0 -1
  150. package/dist/en-2ed89528.js +0 -2
  151. package/dist/en-2ed89528.js.map +0 -1
  152. package/dist/en-e93855cc.js +0 -2
  153. package/dist/en-e93855cc.js.map +0 -1
  154. package/dist/extends-51d9ddcc.js +0 -7
  155. package/dist/flexible-table-154a3359.js +0 -2
  156. package/dist/flexible-table-154a3359.js.map +0 -1
  157. package/dist/flexible-table-5e4a1e6d.js +0 -2
  158. package/dist/flexible-table-5e4a1e6d.js.map +0 -1
  159. package/dist/index-4fd90a14.js +0 -2
  160. package/dist/index-4fd90a14.js.map +0 -1
  161. package/dist/index-6d138021.js +0 -2
  162. package/dist/index-6d138021.js.map +0 -1
  163. package/dist/isArrayLikeObject-31e5e646.js +0 -2
  164. package/dist/isArrayLikeObject-31e5e646.js.map +0 -1
  165. package/dist/isArrayLikeObject-7c33c7fd.js +0 -2
  166. package/dist/isArrayLikeObject-7c33c7fd.js.map +0 -1
@@ -142,13 +142,15 @@ export default class ExpressionSelectFieldOrFunction extends React.Component {
142
142
  onValueTableDblClick(evt, rowKey, index) {
143
143
  if (this.props.onChange) {
144
144
  const field = this.state.currentFieldDataset[this.state.fieldSelected];
145
+ const quote = "\"";
145
146
  if (field.values) {
146
- const quote = "\"";
147
147
  const value = field.values[rowKey].value;
148
148
  const fieldValue = (typeof value === "string") ? quote + value + quote : value;
149
149
  this.props.onChange(fieldValue);
150
150
  } else if (field.range) {
151
- this.props.onChange(rowKey === 0 ? field.range.min.value : field.range.max.value);
151
+ const minValue = (typeof field.range.min.value === "string") ? (quote + field.range.min.value + quote) : field.range.min.value;
152
+ const maxValue = (typeof field.range.max.value === "string") ? (quote + field.range.max.value + quote) : field.range.max.value;
153
+ this.props.onChange(rowKey === 0 ? minValue : maxValue);
152
154
  }
153
155
  }
154
156
  this.setState({
@@ -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
  }
@@ -45,7 +45,9 @@
45
45
 
46
46
  .cm-s-custom .cm-number { color: $text-02; }
47
47
 
48
- .cm-s-custom .cm-def { color: $ui-01; }
48
+ .cm-s-custom .cm-def { color: $support-01; }
49
+
50
+ .cm-s-custom .cm-comment { color: $support-02; }
49
51
 
50
52
  .cm-s-custom .cm-variable,
51
53
  .cm-s-custom .cm-punctuation,
@@ -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
  }
@@ -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
  // ---------------------------------------------------------------------------
@@ -307,7 +303,7 @@ export default class APIPipeline {
307
303
  createNode(data) {
308
304
  let nodeTemplate = data.nodeTemplate;
309
305
  // If the nodeTemplate has app_data.ui_data field then it will be a
310
- // teamplate that conforms to the pipelineFlow schema and needs to be
306
+ // template that conforms to the pipelineFlow schema and needs to be
311
307
  // converted to the internal format for a node.
312
308
  if (has(data.nodeTemplate, "app_data.ui_data")) {
313
309
  nodeTemplate = this.objectModel.convertNodeTemplate(nodeTemplate);
@@ -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 {
@@ -776,6 +777,7 @@ export default class ObjectModel {
776
777
  : 0;
777
778
 
778
779
  node.height = Math.max(node.inputPortsHeight, node.outputPortsHeight, node.layout.defaultNodeHeight);
780
+ node.width = node.layout.defaultNodeWidth;
779
781
 
780
782
  if (node.type === SUPER_NODE && node.is_expanded) {
781
783
  node.height += canvasLayout.supernodeTopAreaHeight + canvasLayout.supernodeSVGAreaPadding;
@@ -784,12 +786,13 @@ export default class ObjectModel {
784
786
  if (node.expanded_height) {
785
787
  node.expanded_height = Math.max(node.expanded_height, node.height);
786
788
  }
787
- }
788
- node.width = node.layout.defaultNodeWidth;
789
789
 
790
- if (node.type === SUPER_NODE && node.is_expanded) {
791
790
  node.width = CanvasUtils.getSupernodeExpandedWidth(node, canvasLayout);
792
791
  node.height = CanvasUtils.getSupernodeExpandedHeight(node, canvasLayout);
792
+
793
+ } else {
794
+ node.height = node.resizeHeight ? node.resizeHeight : node.height;
795
+ node.width = node.resizeWidth ? node.resizeWidth : node.width;
793
796
  }
794
797
 
795
798
  return node;
@@ -807,21 +810,23 @@ export default class ObjectModel {
807
810
  ? (node.outputs.length * (node.layout.portArcRadius * 2)) + ((node.outputs.length - 1) * node.layout.portArcSpacing) + (node.layout.portArcOffset * 2)
808
811
  : 0;
809
812
 
813
+ node.height = node.layout.defaultNodeHeight;
810
814
  node.width = Math.max(node.inputPortsWidth, node.outputPortsWidth, node.layout.defaultNodeWidth);
811
815
 
812
816
  if (node.type === SUPER_NODE && node.is_expanded) {
813
817
  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.
818
+ // If an expanded width is provided make sure it is at least as big
819
+ // as the node width.
816
820
  if (node.expanded_width) {
817
821
  node.expanded_width = Math.max(node.expanded_width, node.width);
818
822
  }
819
- }
820
- node.height = node.layout.defaultNodeHeight;
821
823
 
822
- if (node.type === SUPER_NODE && node.is_expanded) {
823
824
  node.width = CanvasUtils.getSupernodeExpandedWidth(node, canvasLayout);
824
825
  node.height = CanvasUtils.getSupernodeExpandedHeight(node, canvasLayout);
826
+
827
+ } else {
828
+ node.height = node.resizeHeight ? node.resizeHeight : node.height;
829
+ node.width = node.resizeWidth ? node.resizeWidth : node.width;
825
830
  }
826
831
 
827
832
  return node;
@@ -1123,11 +1128,11 @@ export default class ObjectModel {
1123
1128
  }
1124
1129
 
1125
1130
  getPipelineFlowId() {
1126
- return this.getCanvasInfo().id;
1131
+ return this.store.getPipelineFlowId();
1127
1132
  }
1128
1133
 
1129
1134
  getPrimaryPipelineId() {
1130
- return this.getCanvasInfo().primary_pipeline;
1135
+ return this.store.getPrimaryPipelineId();
1131
1136
  }
1132
1137
 
1133
1138
  getPrimaryPipeline() {
@@ -1912,11 +1917,55 @@ export default class ObjectModel {
1912
1917
  return obj.type === NODE_LINK || obj.type === COMMENT_LINK || obj.type === ASSOCIATION_LINK;
1913
1918
  }
1914
1919
 
1915
- // Clears any saved zom values in Local Storage
1920
+ setZoom(zoom, pipelineId) {
1921
+ const enableSaveZoom = this.getCanvasConfig().enableSaveZoom;
1922
+ // This will save zoom to the pipeline if enableSaveZoom is
1923
+ // SAVE_ZOOM_PIPELINE_FLOW and also will cause the toolbar to be updated
1924
+ // so zoom icons can be enabled/disabled.
1925
+ this.store.dispatch({ type: "SET_ZOOM", data: { zoom: zoom, enableSaveZoom }, pipelineId });
1926
+
1927
+ if (enableSaveZoom === SAVE_ZOOM_LOCAL_STORAGE) {
1928
+ this.setSavedZoomLocal(zoom, pipelineId);
1929
+ }
1930
+ }
1931
+
1932
+ // Returns the saved zoom based on the enableSaveZoom config parameter.
1933
+ getSavedZoom(pipelineId) {
1934
+ const enableSaveZoom = this.getCanvasConfig().enableSaveZoom;
1935
+ if (enableSaveZoom === SAVE_ZOOM_PIPELINE_FLOW) {
1936
+ return this.store.getZoom(pipelineId);
1937
+
1938
+ } else if (enableSaveZoom === SAVE_ZOOM_LOCAL_STORAGE) {
1939
+ return this.getSavedZoomLocal(pipelineId);
1940
+ }
1941
+ return null;
1942
+ }
1943
+
1944
+ // Clears any saved zoom values in Local Storage
1916
1945
  clearSavedZoomValues() {
1917
1946
  LocalStorage.delete("canvasSavedZoomValues");
1918
1947
  }
1919
1948
 
1949
+ // Saves the zoom object passed in for this pipeline in local storage.
1950
+ // The pipeline is identified by the pipelineFlowId and pipelineId passed in.
1951
+ setSavedZoomLocal(zoom, pipelineId) {
1952
+ const canvasSavedZoomValues = LocalStorage.get("canvasSavedZoomValues");
1953
+ const savedZooms = canvasSavedZoomValues ? JSON.parse(canvasSavedZoomValues) : {};
1954
+ set(savedZooms, [this.getPipelineFlowId(), pipelineId], zoom);
1955
+ LocalStorage.set("canvasSavedZoomValues", JSON.stringify(savedZooms));
1956
+ }
1957
+
1958
+ // Returns the zoom for this pipeline saved in local storage. The pipeline is
1959
+ // identified by the pipelineFlowId and pipelineId passed in.
1960
+ getSavedZoomLocal(pipelineId) {
1961
+ const canvasSavedZoomValues = LocalStorage.get("canvasSavedZoomValues");
1962
+ if (canvasSavedZoomValues) {
1963
+ const savedZoom = JSON.parse(canvasSavedZoomValues);
1964
+ return get(savedZoom, [this.getPipelineFlowId(), pipelineId]);
1965
+ }
1966
+ return null;
1967
+ }
1968
+
1920
1969
  // ---------------------------------------------------------------------------
1921
1970
  // Add decorations in batch
1922
1971
  // ---------------------------------------------------------------------------
@@ -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
  }
@@ -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,9 @@
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":
19
22
  case "SET_TOOLBAR_CONFIG": {
20
23
  return Object.assign({}, state, { config: action.data.toolbarConfig });
21
24
  }
@@ -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"] {