@elyra/canvas 12.28.2 → 12.30.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.
- package/dist/canvas-controller-6fe261d9.js +2 -0
- package/dist/canvas-controller-6fe261d9.js.map +1 -0
- package/dist/canvas-controller-ea7d4a8f.js +2 -0
- package/dist/canvas-controller-ea7d4a8f.js.map +1 -0
- package/dist/common-canvas-2953ff65.js +2 -0
- package/dist/common-canvas-2953ff65.js.map +1 -0
- package/dist/common-canvas-fbd62592.js +2 -0
- package/dist/common-canvas-fbd62592.js.map +1 -0
- package/dist/common-canvas.es.js +1 -1
- package/dist/common-canvas.js +1 -1
- package/dist/common-properties-0df4ed36.js +2 -0
- package/dist/common-properties-0df4ed36.js.map +1 -0
- package/dist/common-properties-8409565f.js +2 -0
- package/dist/common-properties-8409565f.js.map +1 -0
- package/dist/flexible-table-3a78cdf3.js +2 -0
- package/dist/{flexible-table-a3180c2b.js.map → flexible-table-3a78cdf3.js.map} +1 -1
- package/dist/flexible-table-6e801de4.js +2 -0
- package/dist/{flexible-table-25f1f3a4.js.map → flexible-table-6e801de4.js.map} +1 -1
- package/dist/index-92422c18.js +2 -0
- package/dist/index-92422c18.js.map +1 -0
- package/dist/index-aee893ad.js +2 -0
- package/dist/index-aee893ad.js.map +1 -0
- package/dist/lib/canvas-controller.es.js +1 -1
- package/dist/lib/canvas-controller.js +1 -1
- package/dist/lib/canvas.es.js +1 -1
- package/dist/lib/canvas.js +1 -1
- package/dist/lib/properties/field-picker.es.js +1 -1
- package/dist/lib/properties/field-picker.js +1 -1
- package/dist/lib/properties/flexible-table.es.js +1 -1
- package/dist/lib/properties/flexible-table.js +1 -1
- package/dist/lib/properties.es.js +1 -1
- package/dist/lib/properties.js +1 -1
- package/dist/lib/tooltip.es.js +1 -1
- package/dist/lib/tooltip.es.js.map +1 -1
- package/dist/lib/tooltip.js +1 -1
- package/dist/lib/tooltip.js.map +1 -1
- package/dist/styles/common-canvas.min.css +1 -1
- package/dist/styles/common-canvas.min.css.map +1 -1
- package/dist/{toolbar-2bbc9542.js → toolbar-3fdd090b.js} +1 -1
- package/dist/{toolbar-2bbc9542.js.map → toolbar-3fdd090b.js.map} +1 -1
- package/dist/{toolbar-c173e22a.js → toolbar-5437484a.js} +1 -1
- package/dist/{toolbar-c173e22a.js.map → toolbar-5437484a.js.map} +1 -1
- package/locales/common-properties/locales/en.json +1 -1
- package/locales/common-properties/locales/eo.json +1 -1
- package/package.json +2 -2
- package/src/common-canvas/canvas-controller.js +19 -15
- package/src/common-canvas/svg-canvas-d3.scss +5 -0
- package/src/common-canvas/svg-canvas-pipeline.js +12 -6
- package/src/common-canvas/svg-canvas-renderer.js +156 -103
- package/src/common-canvas/svg-canvas-utils-external.js +34 -0
- package/src/common-properties/actions/button/button.jsx +2 -1
- package/src/common-properties/actions/image/image.jsx +2 -1
- package/src/common-properties/components/title-editor/title-editor.jsx +3 -0
- package/src/common-properties/components/virtualized-table/virtualized-table.scss +2 -4
- package/src/common-properties/controls/datepicker/datepicker.scss +9 -0
- package/src/common-properties/controls/passwordfield/passwordfield.jsx +16 -18
- package/src/common-properties/form/ActionInfo.js +3 -1
- package/src/common-properties/form/EditorForm.js +1 -1
- package/src/common-properties/form/PropertyDef.js +1 -1
- package/src/common-properties/panels/subtabs/subtabs.jsx +4 -2
- package/src/common-properties/panels/tearsheet/tearsheet.jsx +21 -16
- package/src/common-properties/panels/tearsheet/tearsheet.scss +1 -1
- package/src/common-properties/ui-conditions/ui-conditions.js +6 -1
- package/src/object-model/layout-dimensions.js +20 -2
- package/src/object-model/object-model.js +1 -1
- package/src/object-model/pipeline-out-handler.js +1 -1
- package/src/palette/palette-content-list-item.jsx +3 -2
- package/src/palette/palette-dialog-content-grid-node.jsx +3 -2
- package/src/tooltip/tooltip.jsx +1 -1
- package/stats.html +1 -1
- package/dist/canvas-controller-1bbd9c0e.js +0 -2
- package/dist/canvas-controller-1bbd9c0e.js.map +0 -1
- package/dist/canvas-controller-d6aa7d4d.js +0 -2
- package/dist/canvas-controller-d6aa7d4d.js.map +0 -1
- package/dist/common-canvas-9c735f47.js +0 -2
- package/dist/common-canvas-9c735f47.js.map +0 -1
- package/dist/common-canvas-a02e75c1.js +0 -2
- package/dist/common-canvas-a02e75c1.js.map +0 -1
- package/dist/common-properties-21c4c338.js +0 -2
- package/dist/common-properties-21c4c338.js.map +0 -1
- package/dist/common-properties-80e20c2a.js +0 -2
- package/dist/common-properties-80e20c2a.js.map +0 -1
- package/dist/flexible-table-25f1f3a4.js +0 -2
- package/dist/flexible-table-a3180c2b.js +0 -2
- package/dist/index-501de495.js +0 -2
- package/dist/index-501de495.js.map +0 -1
- package/dist/index-8c2f3663.js +0 -2
- package/dist/index-8c2f3663.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright 2017-
|
|
2
|
+
* Copyright 2017-2023 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.
|
|
@@ -33,6 +33,7 @@ const markdownIt = require("markdown-it")({
|
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
import { cloneDeep, escape as escapeText, forOwn, get } from "lodash";
|
|
36
|
+
import { addNodeExternalObject, addDecExternalObject, removeExternalObject } from "./svg-canvas-utils-external.js";
|
|
36
37
|
import { ASSOC_RIGHT_SIDE_CURVE, ASSOCIATION_LINK, NODE_LINK, COMMENT_LINK,
|
|
37
38
|
ASSOC_VAR_CURVE_LEFT, ASSOC_VAR_CURVE_RIGHT, ASSOC_VAR_DOUBLE_BACK_RIGHT,
|
|
38
39
|
LINK_TYPE_CURVE, LINK_TYPE_ELBOW, LINK_TYPE_STRAIGHT,
|
|
@@ -417,7 +418,9 @@ export default class SVGCanvasRenderer {
|
|
|
417
418
|
|
|
418
419
|
if (this.config.enablePositionNodeOnRightFlyoutOpen &&
|
|
419
420
|
this.canvasController.isRightFlyoutOpen()) {
|
|
420
|
-
const posInfo = this.config.enablePositionNodeOnRightFlyoutOpen
|
|
421
|
+
const posInfo = (typeof this.config.enablePositionNodeOnRightFlyoutOpen === "boolean")
|
|
422
|
+
? { x: 50, y: 50 }
|
|
423
|
+
: this.config.enablePositionNodeOnRightFlyoutOpen;
|
|
421
424
|
const x = posInfo.x ? posInfo.x : 50;
|
|
422
425
|
const y = posInfo.y ? posInfo.y : 50;
|
|
423
426
|
const selNodeIds = this.activePipeline.getSelectedNodeIds();
|
|
@@ -866,29 +869,16 @@ export default class SVGCanvasRenderer {
|
|
|
866
869
|
// plus its width and height. This needs to be called each time a new node
|
|
867
870
|
// is dragged from the palette, in case the dimensions of the ghost node
|
|
868
871
|
// have changed because the canvas has been zoomed.
|
|
869
|
-
getGhostNode(
|
|
872
|
+
getGhostNode(node) {
|
|
870
873
|
const that = this;
|
|
871
|
-
const ghost = this.getGhostDimensions();
|
|
872
|
-
const node = this.canvasController.convertNodeTemplate(nodeTemplate);
|
|
873
|
-
node.layout = this.nodeLayout;
|
|
874
|
-
if (node.is_expanded) {
|
|
875
|
-
node.width = node.expanded_width;
|
|
876
|
-
node.height = node.expanded_height;
|
|
877
|
-
} else if (node.isResized) {
|
|
878
|
-
node.width = node.resizeWidth;
|
|
879
|
-
node.height = node.resizeHeight;
|
|
880
|
-
} else {
|
|
881
|
-
node.width = ghost.width;
|
|
882
|
-
node.height = ghost.height;
|
|
883
|
-
}
|
|
884
|
-
const nodeImage = this.getNodeImage(node);
|
|
885
|
-
const nodeImageType = this.getImageType(nodeImage);
|
|
886
874
|
const ghostDivSel = this.getGhostDivSel();
|
|
887
875
|
|
|
888
876
|
// Calculate the ghost area width which is the maximum of either the node
|
|
889
877
|
// label or the default node width.
|
|
890
878
|
const ghostAreaWidth = Math.max(this.nodeLayout.labelWidth, node.width);
|
|
891
879
|
|
|
880
|
+
let xOffset = 0;
|
|
881
|
+
|
|
892
882
|
// Remove any existing SVG object from the div
|
|
893
883
|
ghostDivSel
|
|
894
884
|
.selectAll(".d3-ghost-svg")
|
|
@@ -915,75 +905,82 @@ export default class SVGCanvasRenderer {
|
|
|
915
905
|
.attr("width", node.width)
|
|
916
906
|
.attr("height", node.height);
|
|
917
907
|
|
|
918
|
-
|
|
919
|
-
.
|
|
920
|
-
.
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
.
|
|
970
|
-
|
|
971
|
-
|
|
908
|
+
if (!this.nodeLayout.nodeExternalObject) {
|
|
909
|
+
const nodeImage = this.getNodeImage(node);
|
|
910
|
+
const nodeImageType = this.getImageType(nodeImage);
|
|
911
|
+
|
|
912
|
+
ghostGrp
|
|
913
|
+
.append(nodeImageType)
|
|
914
|
+
.attr("class", "d3-node-image")
|
|
915
|
+
.each(function() { that.setNodeImageContent(this, node); })
|
|
916
|
+
.attr("x", this.nodeUtils.getNodeImagePosX(node))
|
|
917
|
+
.attr("y", this.nodeUtils.getNodeImagePosY(node))
|
|
918
|
+
.attr("width", this.nodeUtils.getNodeImageWidth(node))
|
|
919
|
+
.attr("height", this.nodeUtils.getNodeImageHeight(node));
|
|
920
|
+
|
|
921
|
+
const fObject = ghostGrp
|
|
922
|
+
.append("foreignObject")
|
|
923
|
+
.attr("x", this.nodeUtils.getNodeLabelPosX(node))
|
|
924
|
+
.attr("y", this.nodeUtils.getNodeLabelPosY(node))
|
|
925
|
+
.attr("width", this.nodeUtils.getNodeLabelWidth(node))
|
|
926
|
+
.attr("height", this.nodeUtils.getNodeLabelHeight(node))
|
|
927
|
+
.attr("class", "d3-foreign-object-ghost-label");
|
|
928
|
+
|
|
929
|
+
const fObjectDiv = fObject
|
|
930
|
+
.append("xhtml:div")
|
|
931
|
+
.attr("class", this.nodeUtils.getNodeLabelClass(node));
|
|
932
|
+
|
|
933
|
+
const fObjectSpan = fObjectDiv
|
|
934
|
+
.append("xhtml:span")
|
|
935
|
+
.html(node.label);
|
|
936
|
+
|
|
937
|
+
// At the time of writing, Firefox takes the ghost image from only those
|
|
938
|
+
// objects that are visible (ignoring any invisible objects like the div
|
|
939
|
+
// and SVG area) consequently we position the node and label so the label
|
|
940
|
+
// (if bigger than the node width) is positioned up against the left edge
|
|
941
|
+
// of the invisible div and SVG area. If the label is shorter than the node
|
|
942
|
+
// width, the node is positioned up against the left edge of the SVG. We do
|
|
943
|
+
// this by translating the group object in the x direction.
|
|
944
|
+
|
|
945
|
+
// First calculate the display width of the label. The span will be the
|
|
946
|
+
// full text but it may be constricted by the label width in the layout.
|
|
947
|
+
const labelSpanWidth = fObjectSpan.node().getBoundingClientRect().width + 4; // Include border for label
|
|
948
|
+
const nodeLabelWidth = this.nodeUtils.getNodeLabelWidth(node);
|
|
949
|
+
const labelDisplayLength = Math.min(nodeLabelWidth, labelSpanWidth);
|
|
950
|
+
|
|
951
|
+
// Next calculate the amount, if any, the label protrudes beyond the edge
|
|
952
|
+
// of the node width and move the ghost group by that amount.
|
|
953
|
+
xOffset = Math.max(0, (labelDisplayLength - node.width) / 2) * this.zoomTransform.k;
|
|
954
|
+
|
|
955
|
+
// If the label is center justified, restrict the label width to the
|
|
956
|
+
// display amount and adjust the x coordinate to compensate for the change
|
|
957
|
+
// in width.
|
|
958
|
+
if (node.layout.labelAlign === "center") {
|
|
959
|
+
const labelDiff = Math.max(0, (nodeLabelWidth - labelDisplayLength) / 2);
|
|
960
|
+
|
|
961
|
+
fObject
|
|
962
|
+
.attr("width", labelDisplayLength)
|
|
963
|
+
.attr("x", this.nodeUtils.getNodeLabelPosX(node) + labelDiff);
|
|
964
|
+
fObjectDiv.attr("width", labelDisplayLength);
|
|
965
|
+
}
|
|
972
966
|
}
|
|
973
967
|
|
|
968
|
+
ghostGrp.attr("transform", `translate(${xOffset}, 0) scale(${this.zoomTransform.k})`);
|
|
969
|
+
|
|
974
970
|
// Get the amount the actual browser page is 'zoomed'. This is differet
|
|
975
971
|
// to the zoom amount for the canvas objects.
|
|
976
972
|
const browserZoom = this.getBrowserZoom();
|
|
977
973
|
|
|
978
974
|
// Calculate the center of the node area for positioning the mouse pointer
|
|
979
975
|
// on the image when it is being dragged.
|
|
980
|
-
const centerX = (xOffset + ((
|
|
981
|
-
const centerY = ((
|
|
976
|
+
const centerX = (xOffset + ((node.width / 2) * this.zoomTransform.k)) * browserZoom;
|
|
977
|
+
const centerY = ((node.height / 2) * this.zoomTransform.k) * browserZoom;
|
|
982
978
|
|
|
983
979
|
return {
|
|
984
980
|
element: ghostDivSel.node(),
|
|
985
981
|
centerX: centerX,
|
|
986
|
-
centerY: centerY
|
|
982
|
+
centerY: centerY,
|
|
983
|
+
nodeTemplate: node
|
|
987
984
|
};
|
|
988
985
|
}
|
|
989
986
|
|
|
@@ -1010,17 +1007,6 @@ export default class SVGCanvasRenderer {
|
|
|
1010
1007
|
return browserZoom;
|
|
1011
1008
|
}
|
|
1012
1009
|
|
|
1013
|
-
// Returns an object containing the dimensions of the ghost node that hovers
|
|
1014
|
-
// over canvas when a node is being dragged from the palette. The ghost node
|
|
1015
|
-
// is based on the default node width and height so any change to these values
|
|
1016
|
-
// that might be made to a node by the layoutHandler will not be reflected here.
|
|
1017
|
-
getGhostDimensions() {
|
|
1018
|
-
return {
|
|
1019
|
-
width: this.nodeLayout.defaultNodeWidth,
|
|
1020
|
-
height: this.nodeLayout.defaultNodeHeight
|
|
1021
|
-
};
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
1010
|
nodeTemplateDragStart(nodeTemplate) {
|
|
1025
1011
|
if (this.isNodeTemplateInsertableIntoLink(nodeTemplate)) {
|
|
1026
1012
|
this.setDataLinkSelectionAreaWider(true);
|
|
@@ -1049,12 +1035,11 @@ export default class SVGCanvasRenderer {
|
|
|
1049
1035
|
|
|
1050
1036
|
if (this.isNodeTemplateAttachableToDetachedLinks(nodeTemplate)) {
|
|
1051
1037
|
const mousePos = this.convertPageCoordsToCanvasCoords(x, y);
|
|
1052
|
-
const ghost = this.getGhostDimensions();
|
|
1053
1038
|
const ghostArea = {
|
|
1054
|
-
x1: mousePos.x - (
|
|
1055
|
-
y1: mousePos.y - (
|
|
1056
|
-
x2: mousePos.x + (
|
|
1057
|
-
y2: mousePos.y + (
|
|
1039
|
+
x1: mousePos.x - (nodeTemplate.width / 2),
|
|
1040
|
+
y1: mousePos.y - (nodeTemplate.height / 2),
|
|
1041
|
+
x2: mousePos.x + (nodeTemplate.width / 2),
|
|
1042
|
+
y2: mousePos.y + (nodeTemplate.height / 2)
|
|
1058
1043
|
};
|
|
1059
1044
|
const template = this.canvasController.convertNodeTemplate(nodeTemplate);
|
|
1060
1045
|
const links = this.getAttachableLinksForNodeAtPos(template, ghostArea);
|
|
@@ -1204,12 +1189,13 @@ export default class SVGCanvasRenderer {
|
|
|
1204
1189
|
this.dragNewLinkOverNode = null;
|
|
1205
1190
|
}
|
|
1206
1191
|
|
|
1207
|
-
// Processes the drop of a palette node template onto the canvas.
|
|
1192
|
+
// Processes the drop of a palette node template onto the canvas. The
|
|
1193
|
+
// nodeTemplate is in internal format.
|
|
1208
1194
|
nodeTemplateDropped(nodeTemplate, x, y) {
|
|
1209
1195
|
if (nodeTemplate === null) {
|
|
1210
1196
|
return;
|
|
1211
1197
|
}
|
|
1212
|
-
const transPos = this.transformMousePosForNode(x, y);
|
|
1198
|
+
const transPos = this.transformMousePosForNode(x, y, nodeTemplate);
|
|
1213
1199
|
|
|
1214
1200
|
// If the node template was dropped on a link
|
|
1215
1201
|
if (this.dragOverLink) {
|
|
@@ -1242,13 +1228,17 @@ export default class SVGCanvasRenderer {
|
|
|
1242
1228
|
|
|
1243
1229
|
// Transforms the mouse position passed in to be appropriate for a palette
|
|
1244
1230
|
// node or external object being dragged over the canvas.
|
|
1245
|
-
transformMousePosForNode(x, y) {
|
|
1231
|
+
transformMousePosForNode(x, y, node) {
|
|
1246
1232
|
const mousePos = this.convertPageCoordsToCanvasCoords(x, y);
|
|
1247
1233
|
|
|
1248
1234
|
// Offset mousePos so new node appears in center of mouse location.
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1235
|
+
if (node && node.width && node.height) {
|
|
1236
|
+
mousePos.x -= node.width / 2;
|
|
1237
|
+
mousePos.y -= node.height / 2;
|
|
1238
|
+
} else {
|
|
1239
|
+
mousePos.x -= this.nodeLayout.defaultNodeWidth / 2;
|
|
1240
|
+
mousePos.y -= this.nodeLayout.defaultNodeHeight / 2;
|
|
1241
|
+
}
|
|
1252
1242
|
|
|
1253
1243
|
return this.getMousePosSnapToGrid(mousePos);
|
|
1254
1244
|
}
|
|
@@ -2670,7 +2660,9 @@ export default class SVGCanvasRenderer {
|
|
|
2670
2660
|
selection
|
|
2671
2661
|
.data(data, (d) => d.id)
|
|
2672
2662
|
.join(
|
|
2673
|
-
(enter) => this.createNodes(enter)
|
|
2663
|
+
(enter) => this.createNodes(enter),
|
|
2664
|
+
null,
|
|
2665
|
+
(remove) => this.removeNodes(remove)
|
|
2674
2666
|
)
|
|
2675
2667
|
.attr("transform", (d) => `translate(${d.x_pos}, ${d.y_pos})`)
|
|
2676
2668
|
.attr("class", (d) => this.getNodeGroupClass(d))
|
|
@@ -2703,10 +2695,15 @@ export default class SVGCanvasRenderer {
|
|
|
2703
2695
|
.attr("class", "d3-node-selection-highlight");
|
|
2704
2696
|
|
|
2705
2697
|
// Node Body
|
|
2706
|
-
newNodeGroups.filter((d) => !CanvasUtils.isSuperBindingNode(d))
|
|
2698
|
+
newNodeGroups.filter((d) => !CanvasUtils.isSuperBindingNode(d) && d.layout.nodeShapeDisplay)
|
|
2707
2699
|
.append("path")
|
|
2708
2700
|
.attr("class", "d3-node-body-outline");
|
|
2709
2701
|
|
|
2702
|
+
// Optional foreign object to contain a React object
|
|
2703
|
+
newNodeGroups.filter((d) => d.layout.nodeExternalObject)
|
|
2704
|
+
.append("foreignObject")
|
|
2705
|
+
.attr("class", "d3-foreign-object-external-node");
|
|
2706
|
+
|
|
2710
2707
|
// Node Image
|
|
2711
2708
|
newNodeGroups.filter((d) => !CanvasUtils.isSuperBindingNode(d) && d.layout.imageDisplay)
|
|
2712
2709
|
.each((node, i, nodeGrps) => {
|
|
@@ -2718,7 +2715,7 @@ export default class SVGCanvasRenderer {
|
|
|
2718
2715
|
});
|
|
2719
2716
|
|
|
2720
2717
|
// Node Label
|
|
2721
|
-
newNodeGroups.filter((d) => !CanvasUtils.isSuperBindingNode(d))
|
|
2718
|
+
newNodeGroups.filter((d) => !CanvasUtils.isSuperBindingNode(d) && d.layout.labelDisplay)
|
|
2722
2719
|
.append("foreignObject")
|
|
2723
2720
|
.attr("class", "d3-foreign-object-node-label")
|
|
2724
2721
|
.call(this.attachNodeLabelListeners.bind(this))
|
|
@@ -2752,6 +2749,15 @@ export default class SVGCanvasRenderer {
|
|
|
2752
2749
|
.attr("d", (d) => this.getNodeShapePath(d))
|
|
2753
2750
|
.attr("style", (d) => this.getNodeBodyStyle(d, "default"));
|
|
2754
2751
|
|
|
2752
|
+
// Optional foreign object to contain a React object
|
|
2753
|
+
joinedNodeGrps.selectChildren(".d3-foreign-object-external-node")
|
|
2754
|
+
.datum((d) => this.activePipeline.getNode(d.id))
|
|
2755
|
+
.attr("width", (d) => d.width)
|
|
2756
|
+
.attr("height", (d) => d.height)
|
|
2757
|
+
.attr("x", 0)
|
|
2758
|
+
.attr("y", 0)
|
|
2759
|
+
.each(addNodeExternalObject.bind(this));
|
|
2760
|
+
|
|
2755
2761
|
// Node Image
|
|
2756
2762
|
joinedNodeGrps.selectChildren(".d3-node-image")
|
|
2757
2763
|
.datum((d) => this.activePipeline.getNode(d.id))
|
|
@@ -2806,6 +2812,20 @@ export default class SVGCanvasRenderer {
|
|
|
2806
2812
|
this.logger.logEndTimer("updateNodes");
|
|
2807
2813
|
}
|
|
2808
2814
|
|
|
2815
|
+
removeNodes(removeSel) {
|
|
2816
|
+
// Remove any foreign objects for react nodes, if necessary.
|
|
2817
|
+
removeSel
|
|
2818
|
+
.selectChildren(".d3-foreign-object-external-node")
|
|
2819
|
+
.each(removeExternalObject.bind(this));
|
|
2820
|
+
|
|
2821
|
+
// Remove all nodes in the selection.
|
|
2822
|
+
removeSel.remove();
|
|
2823
|
+
}
|
|
2824
|
+
|
|
2825
|
+
onClick() {
|
|
2826
|
+
window.console.log("onClick");
|
|
2827
|
+
}
|
|
2828
|
+
|
|
2809
2829
|
// Handles the display of a supernode sub-flow contents or hides the contents
|
|
2810
2830
|
// as necessary.
|
|
2811
2831
|
displaySupernodeContents(d, supernodeD3Object) {
|
|
@@ -3138,6 +3158,10 @@ export default class SVGCanvasRenderer {
|
|
|
3138
3158
|
attachInputPortListeners(inputPorts, node) {
|
|
3139
3159
|
inputPorts
|
|
3140
3160
|
.on("mousedown", (d3Event, port) => {
|
|
3161
|
+
if (!this.config.enableEditingActions) {
|
|
3162
|
+
CanvasUtils.stopPropagationAndPreventDefault(d3Event);
|
|
3163
|
+
return;
|
|
3164
|
+
}
|
|
3141
3165
|
if (this.config.enableAssocLinkCreation) {
|
|
3142
3166
|
// Make sure this is just a left mouse button click - we don't want context menu click starting a line being drawn
|
|
3143
3167
|
if (d3Event.button === 0) {
|
|
@@ -3197,6 +3221,10 @@ export default class SVGCanvasRenderer {
|
|
|
3197
3221
|
attachOutputPortListeners(outputPorts, node) {
|
|
3198
3222
|
outputPorts
|
|
3199
3223
|
.on("mousedown", (d3Event, port) => {
|
|
3224
|
+
if (!this.config.enableEditingActions) {
|
|
3225
|
+
CanvasUtils.stopPropagationAndPreventDefault(d3Event);
|
|
3226
|
+
return;
|
|
3227
|
+
}
|
|
3200
3228
|
// Make sure this is just a left mouse button click - we don't want context menu click starting a line being drawn
|
|
3201
3229
|
if (d3Event.button === 0) {
|
|
3202
3230
|
CanvasUtils.stopPropagationAndPreventDefault(d3Event); // Stops the node drag behavior when clicking on the handle/circle
|
|
@@ -3452,12 +3480,13 @@ export default class SVGCanvasRenderer {
|
|
|
3452
3480
|
this.updateDecPaths(dec, decSel, objType);
|
|
3453
3481
|
this.updateDecImages(dec, decSel, objType, d);
|
|
3454
3482
|
this.updateDecLabels(dec, decSel, objType, d);
|
|
3483
|
+
this.updateDecJsxObjs(dec, decSel, objType, d);
|
|
3455
3484
|
}
|
|
3456
3485
|
|
|
3457
3486
|
updateDecOutlines(dec, decSel, objType, d) {
|
|
3458
3487
|
let outlnSel = decSel.selectChild("rect");
|
|
3459
3488
|
|
|
3460
|
-
if (!dec.label && !dec.path && dec.outline !== false) {
|
|
3489
|
+
if (!dec.label && !dec.path && !dec.jsx && dec.outline !== false) {
|
|
3461
3490
|
outlnSel = outlnSel.empty() ? decSel.append("rect") : outlnSel;
|
|
3462
3491
|
outlnSel
|
|
3463
3492
|
.attr("class", this.decUtils.getDecClass(dec, `d3-${objType}-dec-outline`))
|
|
@@ -3505,7 +3534,7 @@ export default class SVGCanvasRenderer {
|
|
|
3505
3534
|
}
|
|
3506
3535
|
|
|
3507
3536
|
updateDecLabels(dec, decSel, objType, d) {
|
|
3508
|
-
let labelSel = decSel.selectChild("
|
|
3537
|
+
let labelSel = decSel.selectChild(".d3-foreign-object-dec-label");
|
|
3509
3538
|
|
|
3510
3539
|
if (dec.label) {
|
|
3511
3540
|
if (labelSel.empty()) {
|
|
@@ -3532,6 +3561,29 @@ export default class SVGCanvasRenderer {
|
|
|
3532
3561
|
}
|
|
3533
3562
|
}
|
|
3534
3563
|
|
|
3564
|
+
updateDecJsxObjs(dec, decSel, objType, d) {
|
|
3565
|
+
let extSel = decSel.selectChild(".d3-foreign-object-dec-jsx");
|
|
3566
|
+
|
|
3567
|
+
if (dec.jsx) {
|
|
3568
|
+
if (extSel.empty()) {
|
|
3569
|
+
extSel = decSel
|
|
3570
|
+
.append("foreignObject")
|
|
3571
|
+
.attr("class", "d3-foreign-object-dec-jsx")
|
|
3572
|
+
.attr("tabindex", -1)
|
|
3573
|
+
.attr("x", 0)
|
|
3574
|
+
.attr("y", 0)
|
|
3575
|
+
.call(this.attachDecLabelListeners.bind(this, d, objType));
|
|
3576
|
+
}
|
|
3577
|
+
extSel
|
|
3578
|
+
.attr("width", this.decUtils.getDecWidth(dec, d, objType))
|
|
3579
|
+
.attr("height", this.decUtils.getDecHeight(dec, d, objType))
|
|
3580
|
+
.each(addDecExternalObject.bind(this));
|
|
3581
|
+
} else {
|
|
3582
|
+
extSel.each(removeExternalObject.bind(this));
|
|
3583
|
+
extSel.remove();
|
|
3584
|
+
}
|
|
3585
|
+
}
|
|
3586
|
+
|
|
3535
3587
|
attachDecLabelListeners(obj, objType, decLabels) {
|
|
3536
3588
|
decLabels
|
|
3537
3589
|
.on("dblclick", (d3Event, dec) => {
|
|
@@ -6859,7 +6911,8 @@ export default class SVGCanvasRenderer {
|
|
|
6859
6911
|
// "Curve" link to make it look presentable. I know, I tried!
|
|
6860
6912
|
getArrowHeadTransform(d) {
|
|
6861
6913
|
const angle =
|
|
6862
|
-
this.canvasLayout.linkType === LINK_TYPE_ELBOW
|
|
6914
|
+
this.canvasLayout.linkType === LINK_TYPE_ELBOW ||
|
|
6915
|
+
this.canvasLayout.linkType === LINK_TYPE_CURVE
|
|
6863
6916
|
? this.getAngleBasedOnLinkDirection()
|
|
6864
6917
|
: Math.atan2((d.y2 - d.y1), (d.x2 - d.x1)) * (180 / Math.PI);
|
|
6865
6918
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 Elyra Authors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import React from "react";
|
|
17
|
+
import ReactDOM from "react-dom";
|
|
18
|
+
|
|
19
|
+
export const addNodeExternalObject = (node, i, foreignObjects) => {
|
|
20
|
+
ReactDOM.render(
|
|
21
|
+
<node.layout.nodeExternalObject
|
|
22
|
+
nodeData={node}
|
|
23
|
+
/>,
|
|
24
|
+
foreignObjects[i]
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const addDecExternalObject = (dec, i, foreignObjects) => {
|
|
29
|
+
ReactDOM.render(dec.jsx, foreignObjects[i]);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const removeExternalObject = (obj, i, foreignObjects) => {
|
|
33
|
+
ReactDOM.unmountComponentAtNode(foreignObjects[i]);
|
|
34
|
+
};
|
|
@@ -70,7 +70,8 @@ class ButtonAction extends React.Component {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
render() {
|
|
73
|
-
const
|
|
73
|
+
const customClassName = this.props.action.className ? this.props.action.className : "";
|
|
74
|
+
const className = classNames("properties-action-button", { "hide": this.props.state === STATES.HIDDEN }, customClassName);
|
|
74
75
|
const disabled = this.props.state === STATES.DISABLED;
|
|
75
76
|
const actionButtonKind = this.getActionButtonKind();
|
|
76
77
|
const actionButtonSize = this.getActionButtonSize();
|
|
@@ -49,9 +49,10 @@ class ImageAction extends React.Component {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
const disabled = this.props.state === STATES.DISABLED;
|
|
52
|
+
const customClassName = this.props.action.className ? this.props.action.className : "";
|
|
52
53
|
const className = classNames("properties-action-image", { "left": this.props.action.image.placement === "left" },
|
|
53
54
|
{ "right": this.props.action.image.placement === "right" }, { "hide": this.props.state === STATES.HIDDEN },
|
|
54
|
-
{ "disabled": disabled });
|
|
55
|
+
{ "disabled": disabled }, customClassName);
|
|
55
56
|
|
|
56
57
|
const image = (
|
|
57
58
|
<div data-id={this.props.action.name}>
|
|
@@ -93,6 +93,9 @@ class TitleEditor extends Component {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
render() {
|
|
96
|
+
if (this.props.title === null) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
96
99
|
const propertiesTitleEditButtonLabel = PropertyUtils.formatMessage(this.props.controller.getReactIntl(), MESSAGE_KEYS.TITLE_EDITOR_LABEL);
|
|
97
100
|
const helpButtonLabel = PropertyUtils.formatMessage(this.props.controller.getReactIntl(), MESSAGE_KEYS.TITLE_EDITOR_HELPBUTTON_LABEL);
|
|
98
101
|
const closeButtonLabel = PropertyUtils.formatMessage(this.props.controller.getReactIntl(), MESSAGE_KEYS.PROPERTIESEDIT_CLOSEBUTTON_LABEL);
|
|
@@ -171,11 +171,9 @@
|
|
|
171
171
|
margin-left: 0;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
// Override padding for sortable columns to show space between column label and sort icon
|
|
175
174
|
.ReactVirtualized__Table__sortableHeaderColumn {
|
|
176
|
-
.properties-
|
|
177
|
-
padding:
|
|
178
|
-
padding-left: $spacing-05;
|
|
175
|
+
.properties-vt-label-tip-icon {
|
|
176
|
+
padding-right: $spacing-03; // spacing between column label and sort icon
|
|
179
177
|
}
|
|
180
178
|
&:hover {
|
|
181
179
|
background-color: $active-ui;
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
import React from "react";
|
|
18
18
|
import PropTypes from "prop-types";
|
|
19
19
|
import { connect } from "react-redux";
|
|
20
|
-
import { PasswordInput
|
|
20
|
+
import { PasswordInput } from "carbon-components-react";
|
|
21
21
|
import ValidationMessage from "./../../components/validation-message";
|
|
22
22
|
import * as ControlUtils from "./../../util/control-utils";
|
|
23
23
|
import { STATES, MESSAGE_KEYS } from "./../../constants/constants.js";
|
|
@@ -49,23 +49,21 @@ class PasswordControl extends React.Component {
|
|
|
49
49
|
const validationProps = ControlUtils.getValidationProps(this.props.messageInfo, this.props.tableControl);
|
|
50
50
|
return (
|
|
51
51
|
<div className={className} data-id={ControlUtils.getDataId(this.props.propertyId)}>
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
/>
|
|
68
|
-
</Form>
|
|
52
|
+
<PasswordInput
|
|
53
|
+
{...validationProps}
|
|
54
|
+
autoComplete="off"
|
|
55
|
+
id={this.id}
|
|
56
|
+
disabled={this.props.state === STATES.DISABLED}
|
|
57
|
+
placeholder={this.props.control.additionalText}
|
|
58
|
+
onChange={this.handleChange.bind(this)}
|
|
59
|
+
value={value}
|
|
60
|
+
labelText={this.props.controlItem}
|
|
61
|
+
hideLabel={this.props.tableControl}
|
|
62
|
+
light={this.props.controller.getLight() && this.props.control.light}
|
|
63
|
+
tooltipAlignment="end"
|
|
64
|
+
showPasswordLabel={showPasswordLabel}
|
|
65
|
+
hidePasswordLabel={hidePasswordLabel}
|
|
66
|
+
/>
|
|
69
67
|
<ValidationMessage inTable={this.props.tableControl} tableOnly state={this.props.state} messageInfo={this.props.messageInfo} />
|
|
70
68
|
</div>);
|
|
71
69
|
}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import { ResourceDef } from "../util/L10nProvider";
|
|
19
19
|
|
|
20
20
|
export class Action {
|
|
21
|
-
constructor(actionName, label, description, control, data, image, button) {
|
|
21
|
+
constructor(actionName, label, description, control, data, image, button, className) {
|
|
22
22
|
this.name = actionName;
|
|
23
23
|
this.label = label;
|
|
24
24
|
this.description = description;
|
|
@@ -26,6 +26,7 @@ export class Action {
|
|
|
26
26
|
this.data = data;
|
|
27
27
|
this.image = image;
|
|
28
28
|
this.button = button;
|
|
29
|
+
this.className = className;
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
32
|
|
|
@@ -40,6 +41,7 @@ class ActionDef {
|
|
|
40
41
|
actionDef.data = action.data;
|
|
41
42
|
actionDef.image = action.image;
|
|
42
43
|
actionDef.button = action.button;
|
|
44
|
+
actionDef.className = action.class_name;
|
|
43
45
|
return actionDef;
|
|
44
46
|
}
|
|
45
47
|
return null;
|
|
@@ -763,7 +763,7 @@ function _makeAction(action, l10nProvider) {
|
|
|
763
763
|
if (action.description) {
|
|
764
764
|
actionDesc = new Description(l10nProvider.l10nDesc(action, action.id));
|
|
765
765
|
}
|
|
766
|
-
return new Action(action.id, actionLabel, actionDesc, action.control, action.data, action.image, action.button);
|
|
766
|
+
return new Action(action.id, actionLabel, actionDesc, action.control, action.data, action.image, action.button, action.className);
|
|
767
767
|
}
|
|
768
768
|
|
|
769
769
|
function _makeButtons(buttonMetadata, l10nProvider) {
|
|
@@ -62,7 +62,7 @@ export class PropertyDef {
|
|
|
62
62
|
const actionMetadata = ActionMetadata.makeActionMetadata(propertyOf(uihints)("action_info"));
|
|
63
63
|
const groupMetadata = GroupMetadata.makeGroupMetadata(propertyOf(uihints)("group_info"), parameterMetadata.getParameters());
|
|
64
64
|
|
|
65
|
-
const label = titleDefinition && titleDefinition.title ? titleDefinition.title :
|
|
65
|
+
const label = titleDefinition && titleDefinition.title ? titleDefinition.title : null;
|
|
66
66
|
const labelEditable = titleDefinition && typeof titleDefinition.editable !== "undefined" ? titleDefinition.editable : DEFAULT_LABEL_EDITABLE;
|
|
67
67
|
|
|
68
68
|
return new PropertyDef(
|
|
@@ -20,6 +20,7 @@ import classNames from "classnames";
|
|
|
20
20
|
import { Tabs, Tab } from "carbon-components-react";
|
|
21
21
|
import { getDataId } from "./../../util/control-utils";
|
|
22
22
|
import { STATES } from "./../../constants/constants.js";
|
|
23
|
+
import { v4 as uuid4 } from "uuid";
|
|
23
24
|
|
|
24
25
|
class Subtabs extends React.Component {
|
|
25
26
|
constructor(props) {
|
|
@@ -27,6 +28,7 @@ class Subtabs extends React.Component {
|
|
|
27
28
|
this.state = {
|
|
28
29
|
activeTabId: ""
|
|
29
30
|
};
|
|
31
|
+
this.uuid = uuid4();
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
onClick(tabId) {
|
|
@@ -50,8 +52,8 @@ class Subtabs extends React.Component {
|
|
|
50
52
|
|
|
51
53
|
subTabs.push(
|
|
52
54
|
<Tab
|
|
53
|
-
id={
|
|
54
|
-
key={
|
|
55
|
+
id={`subtabs.tab.${i}-${this.uuid}`}
|
|
56
|
+
key={`subtabs.tab.${i}-${this.uuid}`}
|
|
55
57
|
disabled={panelState === STATES.DISABLED}
|
|
56
58
|
className={classNames("properties-subtab", { "properties-leftnav-subtab-item": this.props.leftnav })}
|
|
57
59
|
tabIndex={tabIdx}
|