Skip to content

Commit

Permalink
Merge branch 'main' into add-table-toolbar
Browse files Browse the repository at this point in the history
  • Loading branch information
nmgokhale authored May 17, 2024
2 parents e59eb4e + 6396271 commit fdbb0d8
Show file tree
Hide file tree
Showing 24 changed files with 995 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2294,6 +2294,14 @@ export default class CanvasController {
data.editType === "deconstructSuperNode" ||
data.editType === "convertSuperNodeExternalToLocal") {
data = this.preProcessForExternalPipelines(data);

} else if (data.editType === "paste") {
const pasteObjects = this.objectModel.getObjectsToPaste();
if (pasteObjects) {
data.objects = pasteObjects;
} else {
return false;
}
}

// Check with host application if it wants to proceed with the command
Expand Down Expand Up @@ -2618,13 +2626,9 @@ export default class CanvasController {
break;
}
case "paste": {
const pasteObjects = this.objectModel.getObjectsToPaste();
if (pasteObjects) {
data.objects = pasteObjects;
command = new PasteAction(data, this);
this.commandStack.do(command);
data = command.getData();
}
command = new PasteAction(data, this);
this.commandStack.do(command);
data = command.getData();
break;
}
case "undo": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ $panel-border-color: $border-subtle-01;
.toolbar-overflow-item {
button:focus {
border-color: transparent;
box-shadow: inset 2px 2px $button-tertiary, inset -6px -2px $button-tertiary;
box-shadow: inset 2px 2px $focus, inset -6px -2px $focus;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ $node-warning-color: $support-warning; // Warning yellow
// Node label properties
$node-label-color: $text-primary;
$node-label-font-size: 12px;
$node-label-font-weight: 500;
$node-label-font-weight: 600;
$node-label-display-border: 2px;
$node-label-entry-border: 6px;
$node-label-edit-icon-hover-color: $layer-accent-01;
Expand Down Expand Up @@ -434,6 +434,19 @@ $link-highlight-color: $support-info;
color: $icon-primary;
}

// Styles for JSX node and decoration image. Making the svg
// inherit the width and height from the containing foreignObject
// will cause the SVG to stretch to whatever dimensions the app
// has set for the node or decoration image.
.d3-foreign-object-node-image,
.d3-foreign-object-dec-jsx {
outline: none;
svg {
width: inherit;
height: inherit;
}
}

// Remove the foreign object outline when the foreign object has focus.
.d3-foreign-object-dec-ext:focus {
outline: none;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,6 @@ export default class SVGCanvasRenderer {
// is dragged from the palette, in case the dimensions of the ghost node
// have changed because the canvas has been zoomed.
getGhostNode(node) {
const that = this;
const ghostDivSel = this.getGhostDivSel();
const zoomScale = this.zoomUtils.getZoomScale();

Expand Down Expand Up @@ -823,13 +822,9 @@ export default class SVGCanvasRenderer {
.attr("height", node.height);

if (!this.nodeLayout.nodeExternalObject) {
const nodeImage = this.getNodeImage(node);
const nodeImageType = this.getImageType(nodeImage);

ghostGrp
.append(nodeImageType)
.attr("class", "d3-node-image")
.each(function() { that.setNodeImageContent(this, node); })
.append(() => this.getImageElement(node))
.each((d, idx, imgs) => this.setNodeImageContent(node, idx, imgs))
.attr("x", this.nodeUtils.getNodeImagePosX(node))
.attr("y", this.nodeUtils.getNodeImagePosY(node))
.attr("width", this.nodeUtils.getNodeImageWidth(node))
Expand Down Expand Up @@ -1682,12 +1677,10 @@ export default class SVGCanvasRenderer {
.data((d) => (d.layout.imageDisplay ? [d] : []), (d) => d.id)
.join(
(enter) =>
enter
.append((d) => this.getImageElement(d))
.attr("class", "d3-node-image")
enter.append((d) => this.getImageElement(d))
)
.datum((d) => this.activePipeline.getNode(d.id))
.each((d, idx, imgs) => this.setNodeImageContent(imgs[idx], d))
.each((d, idx, imgs) => this.setNodeImageContent(d, idx, imgs))
.attr("x", (d) => this.nodeUtils.getNodeImagePosX(d))
.attr("y", (d) => this.nodeUtils.getNodeImagePosY(d))
.attr("width", (d) => this.nodeUtils.getNodeImageWidth(d))
Expand Down Expand Up @@ -1765,6 +1758,13 @@ export default class SVGCanvasRenderer {
}

removeNodes(removeSel) {
// Remove any JSX images for the nodes being removed to
// unmount their React objects.
removeSel
.selectAll(".d3-foreign-object-node-image")
.each((d, idx, exts) =>
this.externalUtils.removeExternalObject(d, idx, exts));

// Remove any JSX decorations for the nodes being removed to
// unmount their React objects.
removeSel
Expand Down Expand Up @@ -2438,7 +2438,7 @@ export default class SVGCanvasRenderer {
.attr("y", this.decUtils.getDecPadding(dec, d, objType))
.attr("width", this.decUtils.getDecWidth(dec, d, objType) - (2 * this.decUtils.getDecPadding(dec, d, objType)))
.attr("height", this.decUtils.getDecHeight(dec, d, objType) - (2 * this.decUtils.getDecPadding(dec, d, objType)))
.each(() => this.setImageContent(imageSel, dec.image));
.each(() => this.setDecImageContent(imageSel, dec.image));
} else {
imageSel.remove();
}
Expand Down Expand Up @@ -2584,21 +2584,33 @@ export default class SVGCanvasRenderer {
}

// Sets the image specified in the node passed in into the DOM image object
// passed in.
setNodeImageContent(imageObj, node) {
const nodeImage = this.getNodeImage(node);
const imageSel = d3.select(imageObj);
this.setImageContent(imageSel, nodeImage);
// passed in specified by imgs[i].
setNodeImageContent(node, i, imgs) {
const image = this.getNodeImage(node);
const imageType = this.getImageType(image);

if (imageType === "jsx") {
this.externalUtils.addNodeImageExternalObject(image, i, imgs);
} else {
const imageSel = d3.select(imgs[i]);
this.setImageContent(imageSel, image, imageType);
}
}

// Sets the image specified for the decoration into the D3 selection
// of the decoration image.
setDecImageContent(imageSel, image) {
const imageType = this.getImageType(image);
this.setImageContent(imageSel, image, imageType);
}

// Sets the image passed in into the D3 image selection passed in. This loads
// svg files as inline SVG while other image files are loaded with href.
setImageContent(imageSel, image) {
setImageContent(imageSel, image, imageType) {
if (image !== imageSel.attr("data-image")) {
const nodeImageType = this.getImageType(image);
// Save image field in DOM object to avoid unnecessary image refreshes.
imageSel.attr("data-image", image);
if (nodeImageType === "svg") {
if (imageType === "svg") {
if (this.config.enableImageDisplay === "LoadSVGToDefs") {
this.loadSVGToDefs(imageSel, image);

Expand Down Expand Up @@ -2663,20 +2675,44 @@ export default class SVGCanvasRenderer {
return d.image;
}

// Returns the type of image passed in, either "svg" or "image". This will
// be used to append an svg or image element to the DOM.
// Returns the type of image passed in, either "svg" or "image" or
// "jsx" or null (if no image was provided).
// This will be used to append an svg or image element to the DOM.
getImageType(nodeImage) {
return nodeImage && nodeImage.endsWith(".svg") && this.config.enableImageDisplay !== "SVGAsImage" ? "svg" : "image";
if (nodeImage) {
if (typeof nodeImage === "object") {
if (this.externalUtils.isValidJsxElement(nodeImage)) {
return "jsx";
}
} else if (typeof nodeImage === "string") {
return nodeImage.endsWith(".svg") && this.config.enableImageDisplay !== "SVGAsImage" ? "svg" : "image";
}
}
return null;
}

// Returns a DOM element for the image of the node passed in.
// Returns a DOM element for the image of the node passed in to be appended
// to the node element.
getImageElement(node) {
const nodeImage = this.getNodeImage(node);
const imageType = this.getImageType(nodeImage);
if (imageType === "image") {
return d3.create("svg:image").node();

if (imageType === "jsx") {
return d3.create("svg:foreignObject")
.attr("tabindex", -1)
.attr("class", "d3-foreign-object-node-image d3-node-image")
.node();

} else if (imageType === "svg") {
return d3.create("svg")
.attr("class", "d3-node-image")
.node();

}
return d3.create("svg").node();
// If imageType is "image" or null, we create an image element
return d3.create("svg:image")
.attr("class", "d3-node-image")
.node();
}

setNodeStyles(d, type, nodeGrp) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ export default class SvgCanvasExternal {
this.ren = renderer;
}

isValidJsxElement(el) {
return React.isValidElement(el);
}

addNodeExternalObject(node, i, foreignObjects) {
const jsx = (
<node.layout.nodeExternalObject
Expand All @@ -35,28 +39,32 @@ export default class SvgCanvasExternal {
this.renderExternalObject(jsx, foreignObjects[i]);
}

addNodeImageExternalObject(image, i, foreignObjects) {
this.renderExternalObject(image, foreignObjects[i]);
}

addDecExternalObject(dec, i, foreignObjects) {
this.renderExternalObject(dec.jsx, foreignObjects[i]);
}

renderExternalObject(jsx, container) {
if (!container.root) {
container.root = createRoot(container);
if (!container.ccExtRoot) {
container.ccExtRoot = createRoot(container);
}
container.root.render(jsx);
container.ccExtRoot.render(jsx);
}

removeExternalObject(obj, i, foreignObjects) {
const container = foreignObjects[i];
if (!container.root) {
container.root = createRoot(container);
if (!container.ccExtRoot) {
container.ccExtRoot = createRoot(container);
}
// Unmount in Timeout to stop this warning from appearing:
// "Warning: Attempted to synchronously unmount a root while
// React was already rendering."
setTimeout(() => {
container.root.unmount();
container.root = null;
container.ccExtRoot.unmount();
container.ccExtRoot = null;
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export default class PipelineOutHandler {
static createNodeUiData(ciNode) {
const uiData = {
label: ciNode.label,
image: ciNode.image,
image: (typeof ciNode.image === "object" ? "" : ciNode.image),
x_pos: ciNode.x_pos,
y_pos: ciNode.y_pos
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class PaletteContentListItem extends React.Component {
this.onMouseOver = this.onMouseOver.bind(this);
this.onMouseLeave = this.onMouseLeave.bind(this);
this.onMouseDown = this.onMouseDown.bind(this);
this.onKeyPress = this.onKeyPress.bind(this);
this.onKeyDown = this.onKeyDown.bind(this);
}

onMouseDown() {
Expand All @@ -74,7 +74,7 @@ class PaletteContentListItem extends React.Component {
}
}

onKeyPress(e) {
onKeyDown(e) {
// e.key === " " is needed to allow Cypress test in palette.js to run on the build machine!
if (e.key === " " || e.code === "Space" || e.keyCode === 32) {
this.onDoubleClick();
Expand Down Expand Up @@ -279,9 +279,14 @@ class PaletteContentListItem extends React.Component {
} else if (image === USE_DEFAULT_EXT_ICON) {
image = SUPERNODE_EXT_ICON;
}
icon = image.endsWith(".svg")
? <SVG src={image} className="palette-list-item-icon" draggable="false" />
: <img src={image} className="palette-list-item-icon" draggable="false" alt={""} />;

if (typeof image === "object" && React.isValidElement(image)) {
icon = image;
} else if (typeof image === "string") {
icon = image.endsWith(".svg")
? <SVG src={image} className="palette-list-item-icon" draggable="false" />
: <img src={image} className="palette-list-item-icon" draggable="false" alt={""} />;
}
}

if (labelText && (this.props.isPaletteOpen || !icon)) {
Expand Down Expand Up @@ -330,7 +335,7 @@ class PaletteContentListItem extends React.Component {
className={mainDivClass}
onMouseOver={this.onMouseOver}
onMouseLeave={this.onMouseLeave}
onKeyPress={this.props.isEditingEnabled ? this.onKeyPress : null}
onKeyDown={this.props.isEditingEnabled ? this.onKeyDown : null}
onMouseDown={this.props.isEditingEnabled ? this.onMouseDown : null}
onDragStart={this.props.isEditingEnabled ? this.onDragStart : null}
onDragEnd={this.props.isEditingEnabled ? this.onDragEnd : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,14 @@ class PaletteDialogContentGridNode extends React.Component {
image = SUPERNODE_EXT_ICON;
}

icon = image.endsWith(".svg")
? <SVG src={image} className="node-icon" alt={label} />
: <img src={image} className="node-icon" alt={label} />;
if (typeof image === "object" && React.isValidElement(image)) {
icon = image;

} else if (typeof image === "string") {
icon = image.endsWith(".svg")
? <SVG src={image} className="node-icon" alt={label} />
: <img src={image} className="node-icon" alt={label} />;
}
}

let draggable = this.props.isEditingEnabled ? "true" : "false";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,10 @@ class PaletteFlyoutContentCategory extends React.Component {
getItemImage() {
let itemImage = null;
if (this.props.category.image && this.props.category.image !== "") {
if (this.props.category.image.endsWith(".svg")) {
if (typeof this.props.category.image === "object" && React.isValidElement(this.props.category.image)) {
itemImage = this.props.category.image;

} else if (this.props.category.image.endsWith(".svg")) {
itemImage = (
<div>
<SVG src={this.props.category.image} className="palette-flyout-category-item-icon" draggable="false" />
Expand Down
9 changes: 7 additions & 2 deletions canvas_modules/common-canvas/src/toolbar/toolbar-sub-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@ export function adjustSubAreaPosition(areaRef, containingDivId, expandDirection,

const thisAreaRect = areaRef.getBoundingClientRect();

const outsideBottom = thisAreaRect.bottom - containingDivRect.bottom;
const outsideRight = thisAreaRect.right - containingDivRect.right;
// Calculate the amount that the panel/menu is outside of the containing div
// edges. Positive value means it is outside. Negative is inside.
const outsideBottom = actionItemRect.bottom + thisAreaRect.height - containingDivRect.bottom;

if (expandDirection === "vertical") {
const outsideRight = actionItemRect.left + thisAreaRect.width - containingDivRect.right;

if (outsideBottom > 0) {
const topGap = actionItemRect.top - containingDivRect.top;
const newTop = (topGap > thisAreaRect.height)
Expand All @@ -54,6 +57,8 @@ export function adjustSubAreaPosition(areaRef, containingDivId, expandDirection,
}

} else {
const outsideRight = actionItemRect.right + thisAreaRect.width - containingDivRect.right;

if (outsideBottom > 0) {
const newTop = thisAreaRect.top - outsideBottom - 2;
areaRef.style.top = newTop + "px";
Expand Down
Loading

0 comments on commit fdbb0d8

Please sign in to comment.