Skip to content

Commit

Permalink
Merge branch 'main' into Properties_editor_fix
Browse files Browse the repository at this point in the history
  • Loading branch information
Jerinjk14 authored Dec 3, 2024
2 parents d60ed75 + 640f291 commit 91d7756
Show file tree
Hide file tree
Showing 10 changed files with 5,943 additions and 0 deletions.
9 changes: 9 additions & 0 deletions canvas_modules/harness/src/client/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import FlowsCanvas from "./components/custom-canvases/flows/flows-canvas";
import TablesCanvas from "./components/custom-canvases/tables/tables-canvas";
import StagesCanvas from "./components/custom-canvases/stages/stages-canvas";
import StagesCardNodeCanvas from "./components/custom-canvases/stages-card-node/stages-card-node-canvas";
import PromptCanvas from "./components/custom-canvases/prompt/prompt-canvas";
import LogicCanvas from "./components/custom-canvases/logic/logic-canvas";
import ReadOnlyCanvas from "./components/custom-canvases/read-only/read-only-canvas";
import ProgressCanvas from "./components/custom-canvases/progress/progress-canvas";
Expand Down Expand Up @@ -103,6 +104,7 @@ import {
EXAMPLE_APP_FLOWS,
EXAMPLE_APP_STAGES,
EXAMPLE_APP_STAGES_CARD_NODE,
EXAMPLE_APP_PROMPT,
EXAMPLE_APP_EXPLAIN,
EXAMPLE_APP_EXPLAIN2,
EXAMPLE_APP_STREAMS,
Expand Down Expand Up @@ -2788,6 +2790,13 @@ class App extends React.Component {
config={commonCanvasConfig}
/>
);
} else if (this.state.selectedExampleApp === EXAMPLE_APP_PROMPT) {
firstCanvas = (
<PromptCanvas
ref={this.canvasRef}
config={commonCanvasConfig}
/>
);
} else if (this.state.selectedExampleApp === EXAMPLE_APP_LOGIC) {
firstCanvas = (
<LogicCanvas
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
/*
* Copyright 2024 Elyra Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import React from "react";
import PropTypes from "prop-types";

import { CommonCanvas, CanvasController } from "common-canvas"; // eslint-disable-line import/no-unresolved
import { Menu } from "@carbon/react/icons";
import Flow from "./prompt-flow.json";
import Palette from "./prompt-palette.json";
import Template from "./prompt-template.json";
import PromptReactNode from "./prompt-react.jsx";

export default class PromptCanvas extends React.Component {
constructor(props) {
super(props);
this.propertiesRef = React.createRef();
this.canvasController = new CanvasController();
this.canvasController.setPipelineFlow(Flow);
this.canvasController.setPipelineFlowPalette(Palette);

this.getConfig = this.getConfig.bind(this);
this.addNodeHandler = this.addNodeHandler.bind(this);
this.editActionHandler = this.editActionHandler.bind(this);
this.clickActionHandler = this.clickActionHandler.bind(this);
}

getConfig() {
const config = Object.assign({}, this.props.config, {
enableParentClass: "prompt",
enableNodeFormatType: "Vertical",
enableLinkType: "Straight",
enableLinkMethod: "Freeform",
enableLinkDirection: "LeftRight",
enableSnapToGridType: "After",
enableLinkSelection: "None",
enableMarkdownInComments: true,
enableContextToolbar: true,
tipConfig: {
palette: true,
nodes: false,
ports: false,
links: false
},
enableNodeLayout: {
drawNodeLinkLineFromTo: "image_center",
drawCommentLinkLineTo: "image_center",
defaultNodeWidth: 72,
defaultNodeHeight: 72,
selectionPath: "M 8 0 L 64 0 64 56 8 56 8 0",
imageWidth: 48,
imageHeight: 48,
imagePosX: 12,
imagePosY: 4,
labelEditable: true,
labelPosX: 36,
labelPosY: 56,
labelWidth: 120,
labelHeight: 18,
portRadius: 10,
inputPortDisplay: false,
outputPortRightPosX: 5,
outputPortRightPosY: 30,
outputPortObject: "image",
outputPortImage: "/images/custom-canvases/flows/decorations/dragStateArrow.svg",
outputPortWidth: 20,
outputPortHeight: 20,
outputPortGuideObject: "image",
outputPortGuideImage: "/images/custom-canvases/flows/decorations/dragStateArrow.svg"
},
enableCanvasLayout: {
dataLinkArrowHead: true,
linkGap: 4,
displayLinkOnOverlap: false
}
});
return config;
}

clickActionHandler(source) {
// this.addPromptNode();
}

layoutHandler(node) {
if (node.op === "prompt_node") {
return {
defaultNodeHeight: 220,
defaultNodeWidth: 150,
nodeExternalObject: PromptReactNode,
imageDisplay: false,
labelDisplay: false,
nodeShapeDisplay: true,
selectionPath: null
};
}
return {};
}

editActionHandler(data) {
if (data.editType === "app_addPropmpt") {
this.addPromptNode(data.targetObject);
}
}

contextMenuHandler(source, defaultMenu) {
if (source.type === "node") {
if (source.targetObject.op === "prompt_node") {
return [];
}
defaultMenu.push({
action: "app_addPropmpt",
label: "Add node with prompt",
enable: true,
toolbarItem: true,
icon: (<Menu />)
});
}
return defaultMenu;
}

addNodeHandler(nodeTemplate) {
const promptNode = this.canvasController.getNode(this.promptNodeId);
this.canvasController.deleteNode(this.promptNodeId);
this.canvasController.deleteLink("link_to_prompt");

const newNode = this.canvasController.createNode({
nodeTemplate: nodeTemplate,
offsetX: promptNode.x_pos,
offsetY: promptNode.y_pos
});
this.canvasController.addNode(newNode);

const linksToAdd = this.canvasController.createNodeLinks({
type: "nodeLink",
nodes: [{ id: this.sourceNodeId }],
targetNodes: [{ id: newNode.id }]
});

this.canvasController.addLinks(linksToAdd);

}

addPromptNode(sourceNode) {
this.sourceNodeId = sourceNode.id;

const template = Template;
template.app_data.prompt_data = {
addNodeCallback: this.addNodeHandler.bind(this)
};
const newNode = this.canvasController.createNode({
nodeTemplate: template,
offsetX: sourceNode.x_pos + 200, // Position prompt 200px to right of source node
offsetY: sourceNode.y_pos
});

// Make sure prompt doesn't overlap other nodes.
this.adjustNodePosition(newNode, 100);

// Save the ID of the prompt node for removal, later
this.promptNodeId = newNode.id;

// Add the prompt node to the canvas with a link
this.canvasController.addNode(newNode);
const linksToAdd = this.canvasController.createNodeLinks({
id: "link_to_prompt",
type: "nodeLink",
nodes: [{ id: sourceNode.id }],
targetNodes: [{ id: this.promptNodeId }]
});

this.canvasController.addLinks(linksToAdd);
}

adjustNodePosition(node, yInc) {
let overlapNode = true;
while (overlapNode) {
overlapNode = this.canvasController.getNodes().find((n) => n.x_pos === node.x_pos && n.y_pos === node.y_pos);
if (overlapNode) {
node.y_pos += yInc;
}
}
}

render() {
const config = this.getConfig();

return (
<CommonCanvas
canvasController={this.canvasController}
config={config}
clickActionHandler={this.clickActionHandler}
layoutHandler={this.layoutHandler}
contextMenuHandler={this.contextMenuHandler}
editActionHandler={this.editActionHandler}
/>
);
}
}

PromptCanvas.propTypes = {
config: PropTypes.object
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{
"doc_type": "pipeline",
"version": "3.0",
"json_schema": "https://api.dataplatform.ibm.com/schemas/common-pipeline/pipeline-flow/pipeline-flow-v3-schema.json",
"id": "prompt-pipeline-flow",
"primary_pipeline": "primary-prompt-pipeline",
"pipelines": [
{
"id": "primary-prompt-pipeline",
"nodes": [
{
"id": "1af18594-86db-4b21-8f40-16afad1ece0b",
"type": "execution_node",
"op": "type",
"app_data": {
"ui_data": {
"label": "Type",
"image": "images/custom-canvases/flows/palette/icons/type.svg",
"x_pos": 54,
"y_pos": 250,
"description": "Type node."
}
},
"inputs": [
{
"id": "inPort",
"app_data": {
"ui_data": {
"cardinality": {
"min": 0,
"max": 1
},
"label": "Input Port"
}
}
}
],
"outputs": [
{
"id": "outPort",
"app_data": {
"ui_data": {
"cardinality": {
"min": 0,
"max": -1
},
"label": "Output Port"
}
}
}
]
}
],
"app_data": {
"ui_data": {
"comments": [
{
"id": "0b123469-7d21-43a5-ae84-cbc999990033",
"x_pos": 54,
"y_pos": 43.2,
"width": 288,
"height": 158.4,
"class_name": "d3-comment-rect bkg-col-green-20",
"content": "### Prompt Canvas\n\nThis canvas provides a method to add new nodes to the flow with a prompt. To do this:\n1. Hover over the Type node\n2. In the context toolbar, click the \"Add node with prompt\" button\n3. Select a node type from the prompt. ",
"associated_id_refs": []
}
]
}
},
"runtime_ref": ""
}
],
"schemas": []
}
Loading

0 comments on commit 91d7756

Please sign in to comment.