From b19c58575f02763fcd23cbc7a7c1cab9ce73a8f1 Mon Sep 17 00:00:00 2001 From: Paul-Kawalkowski Date: Mon, 24 Jul 2023 08:33:12 -0700 Subject: [PATCH 01/20] feat: new guide Signed-off-by: Paul-Kawalkowski --- README.md | 2 +- .../src/object-model/layout-dimensions.js | 4 +- .../common-properties-components.jsx | 6 +- .../sidepanel/api/sidepanel-api.jsx | 2 +- guide/2.0-Common-Canvas-Documentation.md | 234 +++++ guide/2.0.1-Canvas-Editor.md | 1 + guide/2.0.2-Palette.md | 38 + guide/2.0.3-Context-Menu.md | 5 + guide/2.0.4-Context-Toolbar.md | 36 + guide/2.1-Config-Objects.md | 594 +++++++++++ guide/2.2-Common-Canvas-callbacks.md | 676 +++++++++++++ ...ling-node-creation-from-external-object.md | 75 ++ guide/2.4-Canvas-Controller-API.md | 944 ++++++++++++++++++ ...2.4.0-Calling-the-Canvas-Controller-API.md | 39 + guide/2.4.1-Style-Specification.md | 64 ++ guide/2.4.2-Decoration-Specification.md | 195 ++++ guide/2.4.3-Object-structure-used-by-API.md | 49 + ....4.4-Notification-Message-Specification.md | 30 + ...grammatically-creating-new-canvas-nodes.md | 64 ++ ...nstructing-a-read-only-or-locked-canvas.md | 56 ++ guide/2.5-Command-Stack-API.md | 65 ++ guide/2.6-Flow-Validation-API.md | 62 ++ .../2.7-Customizing-Node-Layout-Properties.md | 375 +++++++ .../2.8-Context-Menu-Wrapper-Documentation.md | 64 ++ guide/2.9-External-Subflows-support.md | 71 ++ guide/3.0-Common-Properties-documentation.md | 316 ++++++ ...-Common-Properties-Parameter-Definition.md | 261 +++++ guide/3.2-Common-Properties-UI-Hints.md | 343 +++++++ guide/3.3-Common-Properties-Controls.md | 110 ++ guide/3.4-Common-Properties-Conditions.md | 353 +++++++ ...3.5-Common-Properties-Custom-Components.md | 177 ++++ guide/3.6-Common-Properties-Controller.md | 336 +++++++ guide/4.0-Accessibility.md | 3 + guide/5.0-Styling.md | 54 + .../6.0-Testing-Guidelines-for-Development.md | 52 + guide/css/styles.css | 7 + guide/images/DELETEME | 1 + guide/index.md | 90 ++ guide/js/links-in-new-tabs.js | 10 + mkdocs.yml | 78 ++ requirements.txt | 2 + 41 files changed, 5937 insertions(+), 7 deletions(-) create mode 100644 guide/2.0-Common-Canvas-Documentation.md create mode 100644 guide/2.0.1-Canvas-Editor.md create mode 100644 guide/2.0.2-Palette.md create mode 100644 guide/2.0.3-Context-Menu.md create mode 100644 guide/2.0.4-Context-Toolbar.md create mode 100644 guide/2.1-Config-Objects.md create mode 100644 guide/2.2-Common-Canvas-callbacks.md create mode 100644 guide/2.3-Enabling-node-creation-from-external-object.md create mode 100644 guide/2.4-Canvas-Controller-API.md create mode 100644 guide/2.4.0-Calling-the-Canvas-Controller-API.md create mode 100644 guide/2.4.1-Style-Specification.md create mode 100644 guide/2.4.2-Decoration-Specification.md create mode 100644 guide/2.4.3-Object-structure-used-by-API.md create mode 100644 guide/2.4.4-Notification-Message-Specification.md create mode 100644 guide/2.4.5-Programmatically-creating-new-canvas-nodes.md create mode 100644 guide/2.4.6-Constructing-a-read-only-or-locked-canvas.md create mode 100644 guide/2.5-Command-Stack-API.md create mode 100644 guide/2.6-Flow-Validation-API.md create mode 100644 guide/2.7-Customizing-Node-Layout-Properties.md create mode 100644 guide/2.8-Context-Menu-Wrapper-Documentation.md create mode 100644 guide/2.9-External-Subflows-support.md create mode 100644 guide/3.0-Common-Properties-documentation.md create mode 100644 guide/3.1-Common-Properties-Parameter-Definition.md create mode 100644 guide/3.2-Common-Properties-UI-Hints.md create mode 100644 guide/3.3-Common-Properties-Controls.md create mode 100644 guide/3.4-Common-Properties-Conditions.md create mode 100644 guide/3.5-Common-Properties-Custom-Components.md create mode 100644 guide/3.6-Common-Properties-Controller.md create mode 100644 guide/4.0-Accessibility.md create mode 100644 guide/5.0-Styling.md create mode 100644 guide/6.0-Testing-Guidelines-for-Development.md create mode 100644 guide/css/styles.css create mode 100644 guide/images/DELETEME create mode 100644 guide/index.md create mode 100644 guide/js/links-in-new-tabs.js create mode 100644 mkdocs.yml create mode 100644 requirements.txt diff --git a/README.md b/README.md index d9b7a780c8..91424c56c6 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ npm install -g grunt-cli sass ``` In your application's package.json replace ``` -"@elyra/canvas": "" +"@elyra/canvas": "" ``` with ``` diff --git a/canvas_modules/common-canvas/src/object-model/layout-dimensions.js b/canvas_modules/common-canvas/src/object-model/layout-dimensions.js index 764dd56434..a9c5ca7470 100644 --- a/canvas_modules/common-canvas/src/object-model/layout-dimensions.js +++ b/canvas_modules/common-canvas/src/object-model/layout-dimensions.js @@ -73,7 +73,7 @@ const portsHorizontalDefaultLayout = { labelAllowReturnKey: false, // true allows line feed to be inserted into label, "save" to make the return key save the label. // An array of decorations to be applied to the node. For details see: - // https://github.com/elyra-ai/canvas/wiki/2.4.2-Decoration-Specification + // https://github.com/elyra-ai/canvas/tree/main/guide/2.4.2-Decoration-Specification.md // These are added to the node at run time and will not be saved into // the pipeline flow. decorations: [], @@ -483,7 +483,7 @@ const portsVerticalDefaultLayout = { labelAllowReturnKey: false, // true allows line feed to be inserted into label, "save" to make the return key save the label. // An array of decorations to be applied to the node. For details see: - // https://github.com/elyra-ai/canvas/wiki/2.4.2-Decoration-Specification + // https://github.com/elyra-ai/canvas/tree/main/guide/2.4.2-Decoration-Specification.md // These are added to the node at run time and will not be saved into // the pipeline flow. decorations: [], diff --git a/canvas_modules/harness/src/client/components/common-properties-components.jsx b/canvas_modules/harness/src/client/components/common-properties-components.jsx index 415e86e1a3..b3f2a63eb0 100644 --- a/canvas_modules/harness/src/client/components/common-properties-components.jsx +++ b/canvas_modules/harness/src/client/components/common-properties-components.jsx @@ -504,7 +504,7 @@ class CommonPropertiesComponents extends React.Component { to Custom and rightFlyout set to true. Below is the minimum specifications to render CommonProperties. More options and details are listed in the  Common Properties wiki . @@ -527,7 +527,7 @@ class CommonPropertiesComponents extends React.Component {

For more information with using CommonCanvas right-flyout for the properties editor, refer to the documentation in the  Common Properties wiki @@ -2069,7 +2069,7 @@ class CommonPropertiesComponents extends React.Component { to More than ten fields... This placeholder text can be configured through   custom labels.

diff --git a/canvas_modules/harness/src/client/components/sidepanel/api/sidepanel-api.jsx b/canvas_modules/harness/src/client/components/sidepanel/api/sidepanel-api.jsx index 895a188b5a..033c3fe939 100644 --- a/canvas_modules/harness/src/client/components/sidepanel/api/sidepanel-api.jsx +++ b/canvas_modules/harness/src/client/components/sidepanel/api/sidepanel-api.jsx @@ -476,7 +476,7 @@ export default class SidePanelAPI extends React.Component { if (this.state.appendLink) { messageLink = (); } diff --git a/guide/2.0-Common-Canvas-Documentation.md b/guide/2.0-Common-Canvas-Documentation.md new file mode 100644 index 0000000000..a785ba7640 --- /dev/null +++ b/guide/2.0-Common-Canvas-Documentation.md @@ -0,0 +1,234 @@ +# Introduction +Common canvas displays a flow of data operations as nodes and links which the user can create and edit to get the flow they want. These visual flows of data operations are translated into data processing steps performed by a back-end server. Common canvas provides functionality for the visual display of flows in the browser and leaves persistence and execution of data flows to the application. +Within common canvas the user can perform operations such as: +* Create a new node by dragging a node definition from a palette onto the canvas. +* Create a new node by dragging a node from outside the canvas onto the canvas (you'll have to do some programming to get this to work). +* Delete a node by clicking a context menu option. +* Create a link by dragging a line from one node to another. +* Delete a link by clicking a context menu option. +* Add a comment to the canvas and draw a link from it to one or more nodes. +* Edit a comment. +* Move nodes and comments around in the canvas to get the desired arrangement. +* And more! ... + +# Architecture + +## Common Canvas react object + Common-canvas is a react component that can be used in your react application to display a fully-functional canvas user interface including the function mentioned above. The `` component is displayed in a `
` provided by your application. + +Common-canvas has these constituent parts that are visible to the user: +* [Canvas editor](/2.0.1-Canvas-Editor/) - the main area of the UI where the flow is displayed and edited +* [Palette](/2.0.2-Palette/) - a set of node templates that can be dragged to the canvas to create new nodes +* [Context menu](/2.0.3-Context-Menu/) - a menu of options for nodes, comments, etc +* [Context toolbar](/2.0.4-Context-Toolbar/) - a menu of options for nodes, comments, etc presented as a small toolbar +* Toolbar - a set of tools across the top of the UI +* Notification panel - a panel for displaying runtime and other messages to your user +* Right side flyout - a panel, often used to display node properties +* Top panel - a panel which can be used to display other app related information +* Bottom panel - a panel which can be used to display other app related information + +and it handles: + 1. the visual display of the flow of operations; + 2. any user gestures on the canvas; + 3. display of context menus; + 4. display and handling of the palette. + 5. provision of callbacks to tell your code what operations the user is performing on the canvas + 6. and much much more. + +## Canvas Controller + +The only mandatory parameter for the `` component is a regular JavaScript object called the [CanvasController](/2.4-Canvas-Controller-API/). + + The CanvasController routes handles calls from the host application and actions performed by the user. It then updates the internal object model which stores: + 1. the data that describes the flow of nodes, links and comments (called a pipelineFlow); + 2. the data that describes the definition of the palette which contains node templates that can dragged to add nodes to the canvas; + 3. the set of currently selected objects. + 4. notification messages + 5. breadcrumbs that indicate which sub-flow is being viewed + 6. layout information + + The [CanvasController](/2.4-Canvas-Controller-API/) provides an API which allows your code to: + + 1. set a new pipelineFlow; + 2. get the current pipelineFlow (after the user has edited it); + 3. update and edit objects in the canvas (for example, add node, delete link etc.); + 4. set the node definition data (for display of nodes in the palette) + +# Getting started with common canvas programming + +## Hello Canvas! + You can start by looking at these two 'hello world' examples for using common canvas: + +* This first one called [app-tiny.js](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/client/app-tiny.js) has the bare minimum necessary to get a fully functioning common-canvas to appear including all the basic functionality, a palette and a flow of nodes and links. +* The second, called [app-small.js](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/client/app-small.js), shows many of the options available to a common-canvas developer such as configurations and callback handlers. + +You can also look at the [App.js](https://github.com/elyra-ai/canvas/blob/49ed634e3353d8f5c58eb8409ed8e1009f19c87a/canvas_modules/harness/src/client/App.js) file in the test harness section of this repo to see examples of code that uses the common canvas component. + + Now let's walk through the different steps to get common-canvas working: + + +## Step 1 : Install Elyra Canvas NPM module + +Enter: +``` + npm install @elyra/canvas +``` + +## Step 2 : Import Common-canvas + +To use common canvas in your react application you need to do the following. First import the CommonCanvas react component and CanvasController class from the Elyra Canvas library. Elyra Canvas produces both `esm` and `cjs` outputs. By default `esm` will be used when webpack is used to build the consuming application. + +**All Components** +```js + import { CommonCanvas, CanvasController } from "@elyra/canvas"; +``` +**Canvas only** + + To import only canvas functionality in `cjs` format use: +```js + import { CommonCanvas, CanvasController } from "@elyra/canvas/dist/lib/canvas"; +``` + +In addition you'll need to import `` from the `react-intl` library. +```js + import { IntlProvider } from "react-intl"; +``` + + +## Step 3 : Create an instance of the canvas controller +To control the canvas you'll need an instance of the canvas controller so create an instance of it like this (probably in the constructor of your object). +```js + this.canvasController = new CanvasController(); +``` +## Step 4 : Set the palette data +Next you'll need to populate the palette data. This will specify the nodes (split into categories) that will appear in the palette. The user can drag them from the palette to build their flow. This is done by calling CanvasController with: +```js + this.canvasController.setPipelineFlowPalette(pipelineFlowPalette); +``` +The pipelineFlowPalette object should conform to the JSON schema found here: +https://github.com/elyra-ai/pipeline-schemas/tree/master/common-canvas/palette + +Some examples of palette JSON files can be found here: +https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/test_resources/palettes + +## Step 5 : (Optional) Set the flow data +This is an optional step. If you want a previously saved flow to be shown in the canvas editor so the user can start to edit it, you will need to call the CanvasController with: +```js + this.canvasController.setPipelineFlow(pipelineFlow); +``` + +The pipelineFlow object should conform to the JSON schema found here: +https://github.com/elyra-ai/pipeline-schemas/tree/master/common-pipeline/pipeline-flow + +Some examples of pipeline flow JSON files can be found here: +https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/test_resources/diagrams + +## Step 6 : Pull in the CSS +Check this section to find info on what CSS to include in your application's CSS. +/5.0-Styling + +## Step 7 : Display the canvas + +Finally you'll need to display the canvas object inside an `` object. Inside your render code, add the following: +```html +
+ + + +
+``` +The div should have the dimensions you want for your canvas to display in your page. For the canvasController property, pass the instance of canvas controller you created earlier. This is the only mandatory property. After providing this and running your code you will have a fully functioning canvas including: a palette; default toolbar; context menus; direct manipulation (move and resize) etc. To customize these behaviors and presentation continue with the sections below. + +## Common Canvas customization +If you want to customize the behavior of common canvas you can specify any combination of the following optional settings: +```html +
+ + +
+``` + +### Config objects +Common canvas has five **optional** configuration objects: config, toolbarConfig, notificationConfig, contextMenuConfig and keyboardConfig. +They are documented here: +/2.1-Config-Objects + +### Handlers +There are several **optional** handlers implemented as callback functions. They are contextMenuHandler, editActionHandler, beforeEditActionHandler, clickActionHandler, decorationActionHandler, layoutHandler, tipHandler, idGeneratorHandler, selectionChangeHandler and actionLabelHandler. They are documented here: +/2.2-Common-Canvas-callbacks + +### Right-flyout panel parameters +The right flyout panel appears on the right of the canvas area. You can add whatever content you like to this panel. Typically, it is used to display properties of nodes on the canvas. There are two **optional** parameters to let you manage the right flyout panel These are: +- showRightFlyout: This can be true or false to indicate whether the flyout panel is shown or not. The default is false. +- rightFlyoutContent: content to display in the right flyout which is a JSX object. Nothing is displayed by default. + +### Bottom panel parameters +The bottom panel appears below the canvas area and between the palette and the right flyout panel. You can add whatever content you like to this panel. There are two **optional** parameters to let you manage the bottom panel. These are: +- showBottomPanel: This can be true or false to indicate whether the bottom panel is shown or not. The default is false. +- bottomPanelContent: content to display in the bottom panel which is a JSX object. Nothing is displayed by default. + +### Top panel parameters +The top panel appears below the toolbar and between the palette and the right flyout panel. You can add whatever content you like to this panel. There are two **optional** parameters to let you manage the top panel. These are: +- showTopPanel: This can be true or false to indicate whether the top panel is shown or not. The default is false. +- topPanelContent: content to display in the top panel which is a JSX object. Nothing is displayed by default. + +### Localization +You can customize `` using the `` object to [display translated test](/#localization) + +## Creating nodes on the canvas + +Nodes can be created on the canvas by the user in two ways: +* By dragging a node from the palette onto the canvas background +* By dragging a node from outside the canvas + +The first technique is provided by Common canvas. The second requires some development work which is documented here: +/2.3-Enabling-node-creation-from-external-object + + +## Keyboard support + +Common canvas supports a number of keyboard interactions as follows: + +|Keyboard Shortcut|Action|Description| +|---|---|---| +|Ctrl/Cmnd + a|selectAll|Select All objects +|delete|deleteSelectedObjects|Delete currently selected objects| +|Ctrl/Cmnd + x|cut|Cut selected objects to the clipboard| +|Ctrl/Cmnd + c|copy|Copy selected objects to the clipboard| +|Ctrl/Cmnd + v|paste|Paste objects from the clipboard. If the mouse cursor is over
the canvas, objects will be pasted at the cursor position or,
if not, at a default position| +|Ctrl/Cmnd + z|undo|Undo last command| +|Ctrl/Cmnd + Shift + z|redo|Redo last undone command| +|Ctrl/Cmnd + y|redo|Redo last undone command| + + +Your application can disable any or all of these actions by providing the [keyboard config object](/2.1-Config-Objects#keyboard-config-object) to the CommonCanvas react component. + +When any of the shortcut keys are pressed the common-canvas object model will be updated and then the [editActionHandler](/2.2-Common-Canvas-callbacks#editactionhandler) callback will be called with the `data.editType` parameter set to the action above and the `data.editSource` parameter set to "keyboard". diff --git a/guide/2.0.1-Canvas-Editor.md b/guide/2.0.1-Canvas-Editor.md new file mode 100644 index 0000000000..bedcb0af63 --- /dev/null +++ b/guide/2.0.1-Canvas-Editor.md @@ -0,0 +1 @@ +[Under construction] \ No newline at end of file diff --git a/guide/2.0.2-Palette.md b/guide/2.0.2-Palette.md new file mode 100644 index 0000000000..d246caf40f --- /dev/null +++ b/guide/2.0.2-Palette.md @@ -0,0 +1,38 @@ +## Introduction +By default, common-canvas includes a palette which appears in the left flyout panel. The palette displays a set of node templates split into different categories. The user can drag any of the node templates from the palette onto the canvas to create a new instance of a node on the canvas. The user can then join nodes together by creating link lines. + +## Populating the palette +The host application must tell common-canvas what node templates and categories it wants the user to see in the palette. This is done by providing common-canvas with a palette (JavaScript) object by calling the canvas-controller `setPipelineFlowPalette(palette)` method. The palette object is often read from a JSON document stored in the host application's repository or it can be automatically generated. + +The palette object should conform to the [palette schema](https://github.com/elyra-ai/pipeline-schemas/blob/412d70176953ed9ac2e6a03f7135b09b7565fc5d/common-canvas/palette/palette-v3-schema.json). The host application can ensure that palette conforms to the schema by switching on [schema validation](/2.1-Config-Objects#schemavalidation) in the canvas configuration. + +## Auto-join +Instead of dragging node templates from the palette, the user can double click node templates to add, and automatically join, them to the current flow. When a node template is double clicked, common-canvas will look for the node at the end of the current flow of nodes and will add the node to the canvas to the right of the end node in the flow. Common-canvas will also automatically join the nodes together by creating a new link line. + +## Palette configuration +There are a number of configuration options that control the palette that are specified in the canvas config object: +* [enablePaletteLayout](/2.1-Config-Objects#enablepalettelayout) +* [enableNarrowPalette](/2.1-Config-Objects#enablenarrowpalette) +* [enableAutoLinkOnlyFromSelNodes](/2.1-Config-Objects#enableautolinkonlyfromselnodes) +* Deprecated - [paletteInitialState](/2.1-Config-Objects#paletteinitialstate) + +## Palette operation +The palette contents can be manipulated calling these canvas-controller [palette methods](/2.4-Canvas-Controller-API#palette-methods) + +The palette can be opened and closed using these canvas-controller [operational methods](/2.4-Canvas-Controller-API#palette-methods-1) + +## Search +The user can enter a search string into the Search field at the top of the palette. The behavior is as follows: +1. When the search field is empty, the palette shows categories which can be expanded to show the node templates within the expanded category. +2. As the user enters characters into the search field, common-canvas immediately searches through the node template labels, node template descriptions and category labels for the characters entered and finds a subset of the node templates that match the search string. Common-canvas then replaces the category-based view of the palette with a list of node templates that match the search criteria. In this view the node templates also include the node description under the node label. +3. The search is case insensitive. +4. The search text is highlighted wherever it appears in the labels, descriptions or category labels. +5. Common-canvas uses a ranking algorithm to order the display of node templates so those most relevant to the search text are positioned at the top of the list. The ranking algorithm puts more weight on those node templates where the search text appears in the label than if the text appears in the description or the category label. +6. If the user enters words into the search field (separated by spaces), common-canvas searches for each word separately. Therefore, if say the user entered "data import" into the search field, common-canvas would find a node with "`Import` `Data`" as the label or even a node with a description that said "This node does lots of things and also `data` can be `import`ed." +7. Nodes that have text which have hits on multiple words are ranked more highly than node templates whose text only contains one search word. +8. Common-canvas uses a debounce function so that, if the user types the search string very quickly, common-canvas does not perform multiple searches for each key press but only runs a full search when rapid typing has ended. + +## Recommendation +According to the schema, node template descriptions are not mandatory in the palette object. However, it is recommended you provide descriptions for each of your node templates. The reason for this is that, the search function searches through node template descriptions, as well as node template labels and category labels. This means you can write your node template descriptions to contain appropriate keywords that a user might search for when looking for a node. + +For example, if there is a node template called ‘Import Data’ and that node could import comma-separated files you could add ‘comma-separated’ and ‘csv’ into your description for that node template. If the user entered `comma` in the search field the ‘Import Data’ node template would be shown in the search results even though `comma` does not appear in the node template label. \ No newline at end of file diff --git a/guide/2.0.3-Context-Menu.md b/guide/2.0.3-Context-Menu.md new file mode 100644 index 0000000000..993829a9a4 --- /dev/null +++ b/guide/2.0.3-Context-Menu.md @@ -0,0 +1,5 @@ +A context menu is a small window containing a list of options applicable to an object or set of selected objects. + +When [`enableContextToolbar`](/2.1-Config-Objects#enablecontexttoolbar) is set to `false` (or omitted) from the canvas config, and a right-click is performed on a node, link, comment or the canvas background, a traditional context menu is displayed like this: + +image \ No newline at end of file diff --git a/guide/2.0.4-Context-Toolbar.md b/guide/2.0.4-Context-Toolbar.md new file mode 100644 index 0000000000..3cd4b1fa85 --- /dev/null +++ b/guide/2.0.4-Context-Toolbar.md @@ -0,0 +1,36 @@ +Context toolbars can be enabled in common-canvas as an alternative to traditional context menus. + +A context toolbar is a small toolbar that appears above nodes, links and comments as the mouse cursor is hovered over them. A context toolbar for the canvas background can also be displayed by right-clicking on the canvas background. + +The context toolbar displays a set of icons that represent the most likely actions the user would want to perform on the object under the mouse cursor. If necessary, the toolbar can also show an overflow (horizontal ellipsis) icon that, when clicked, reveals additional actions that can be performed on the object. + +For a "vertical" style node the context toolbar looks like this: + +image + +For a “horizontal” style node it looks like this: + +image + +when the user clicks the overflow icon it looks like this: + +image + +Note: Since the mouse cursor can be hovered over a node, comment or link that is NOT currently selected, the actions shown in the context toolbar will apply to just that object, even if there is one or more currently selected objects. + +If the mouse cursor is hovered over a selected object when there are other selected objects, the actions in the context toolbar will be applicable to all the selected objects. This is the same as how a traditional content menu shows actions that are applicable to the set of selected objects. + + +The context toolbar behavior can be switched on by setting the [`enableContextToolbar`](/2.1-Config-Objects#enablecontexttoolbar) canvas configuration field to true. + +``` + const config = { + enableContextToolbar: true + }; + + ... + ... + +``` + + diff --git a/guide/2.1-Config-Objects.md b/guide/2.1-Config-Objects.md new file mode 100644 index 0000000000..c38c20dbaa --- /dev/null +++ b/guide/2.1-Config-Objects.md @@ -0,0 +1,594 @@ +# Canvas Config object + +The canvas config object is optional. If it is not provided, or any of the properties within it are not provided, common-canvas will use reasonable defaults. Here's an example of a canvas config object: +```js + const commonCanvasConfig = { + "enableNodeFormatType": "Vertical", + "enableLinkType": "Straight" + } + }; +``` +and this is how it is specified to common-canvas: +```js + render() { + return ( + + ); + } + +``` + +## Canvas Config fields + +#### **enableInteractionType** +This can be "Mouse", "Carbon" or "Trackpad". The default is "Mouse". +***"Trackpad" has been deprecated and will be removed in the future.*** + +* With this set to "Mouse" the following interaction is enabled: + * Zoom canvas = Rotate mouse wheel. +(Can be simulated with a trackpad with two finger up and down scroll) + * Pan canvas = Left mouse key down on canvas background + drag. +(Can be simulated with a trackpad with press down on trackpad and drag.) + * Region select on canvas = Shift key + left mouse key down on canvas background + drag. +(Can be simulated with a trackpad with Shift + finger down on trackpad + drag across canvas background) + +* With this set to "Carbon" the following interaction is enabled: + * Zoom canvas = Rotate mouse wheel. +(Can be simulated with a trackpad with two finger up and down scroll) + * Pan canvas = Press and hold space bar then left mouse key down on canvas background + drag. +(Can be simulated with a trackpad by press and hold space bar then press down on trackpad and drag.) + * Region select on canvas = Left mouse key down on canvas background + drag. +(Can be simulated with a trackpad with press down on trackpad and drag.) + +* **This setting is now deprecated** With this set to "Trackpad" the following interactions are enabled: + * Zoom canvas = Two finger pinch or two finger spread gesture. +(Can be simulated with a mouse as follows: Ctrl + rotate mouse wheel.) + * Pan canvas = Two finger horizontal or vertical scroll gesture. +(Can be simulated with a mouse as follows: Vertical pan is rotate mouse wheel; Horizontal pan is Shift + rotate mouse wheel) + * Region select on canvas = Finger down + drag. +(Can be simulated with a mouse as follows: Left button down + drag on canvas background) + +#### **enableNodeFormatType** +This can be "Horizontal" or "Vertical". "Horizontal" is the default. "Horizontal" will display a node with an image and the label to the right of the image. "Vertical" will display the node with the label underneath the image.See the section called [Customizing Node Layout Properties](/2.7-Customizing-Node-Layout-Properties) for details on what this will do. + +#### **enableLinkType** +This can be "Curve", "Elbow", or "Straight". "Curve" is the default. This will set the link style used to connect nodes. + +#### **enableLinkDirection** +This can be "LeftRight", "TopBottom", or "BottomTop". "LeftRight" is the default. This will set the input and output port positions on nodes to facilitate links being drawn in the direction specified. +* For "LeftRight" output ports will be on the right and input ports will be on the left of the nodes +* For "TopBottom" output ports will be on the bottom and input ports will be on the top of the nodes +* For "BottomTop" output ports will be on the top and input ports will be on the bottom of the nodes + +#### **enableLinkSelection** +This can be: "None", "LinkOnly", "Handles" or "Detachable". The default is "None". These have the following affect on the canvas: +* "None" - no selection of links is possible however user can right click on a link to get a context menu. +* "LinkOnly" - a link may be selected and added to the set of currently selected objects (nodes and/or comments). +* "Handles" - This includes the "LinkOnly" function. In addition, when a link is selected a handle (either a circle or an image) is displayed at the start and end of the link. The link handle can be dragged to a new node/port position to rewire the flow. +* "Detachable" - This includes the "LinkOnly" and "Handles" function. In addition, this option enables detachable links for the canvas. This means a link can exist either: + * between a source node and an arbitrary point on the canvas (semi-detached) OR + * between an arbitrary point on the canvas and a target node (semi-detached) OR + * between two arbitrary points on the canvas (detached) + + Additionally, "Detachable" mode, allows: + - semi-detached or fully-detached links to be stored in and retrieved from the pipeline flow document. + - semi-detached or fully-detached links to be manipulated with link handles. The link handles can be used to drag the end of the link away from its connecting source or target nodes and onto the canvas. Or semi-detached or fully detached links can be reattached to nodes/ports. + - a new detached link to be created by drawing out a new link from a node and dropping it onto the canvas. + - palette and canvas nodes, when they are dragged, to be dropped onto the ends of detached links to automatically attach them to the node being dragged. + +#### **enableLinkReplaceOnNewConnection** +This can be true or false. The default is false. If set to true, the user can drag a new connection to a target node, and if the input port on the target node has a maximum cardinality of one AND there is currently a connection to that port, the existing connection will be removed and the new connection is created; essentially this gesture replaces the existing link with the new one. If set to false the new connection will not be completed and the existing link will remain in place. + +When set to true and a link is replaced, common-canvas will call the `beforeEditActionHandler` the `editActionHandler` callback functions, if either are provided by the host application, with a `data` object parameter with the `editType` field set to `"linkNodesAndReplace"`. + +#### **enableParentClass** +This is a string which is a class name. The default is empty string. If a class name is provided it is applied to the top-most DOM element for common-canvas. This can be used to make you CSS override rules more specific which means they will be used in preference to any default styles. For example, if you specify "my-app-styles" for this field then CSS like this: +```css + .my-app-styles .d3-node-body-outline { + fill: orange; + } +``` +will override the style from the common-canvas CSS +```css + .d3-node-body-outline { + fill: white; + } +``` + +#### **enableInternalObjectModel** +This is a boolean. The default is `true`. You should use `true` for this all the time. If you set this to `false` your code will be responsible for handling the object model, which is NOT recommended. When `false`, changes are not set into the object model, and consumers are expected to listen to events and update the internal object model themselves (again, *not* recommended). + +#### **enablePaletteLayout** +This can be: "Modal" or "Flyout" or "None". The default is "Flyout". "Flyout" displays a panel on the left side of the canvas containing the palette icons and "Modal" shows the palette icons in a dialog window. "None" stops the palette from appearing. + +#### **enableToolbarLayout** +This can be: "Top" or "None". The default is "Top". "Top" displays a toolbar at the top of the canvas area. See the [toolbar configuration object docs](/2.1-Config-Objects#toolbar-config-object) for details on how to customize the toolbar. "None" stops the toolbar from appearing. + +#### **enableResizableNodes** +This can be true or false. The default is false. If set to true, the user can resize nodes by dragging the edges of the node to increase or decrease the width and/or height of the node. When hovering the mouse cursor over the edge of the node the user will see a sizing cursor to indicate the resize function is available. This option works best when the node has a background rectangle that shows the extend of the sizing area. + +#### **enableInsertNodeDroppedOnLink** +This can be true or false. The default is false. If set to true, the user can drag nodes from the palette or from the canvas and drop them onto existing links in the flow. This causes the dropped node to be inserted between the two nodes joined by the link, meaning new links are created that join the new node to the previously joined nodes and the old link is removed. When the user performs the drop common-canvas will call the editActionHandler with one of two possible commands: +* "createNodeOnLink" - when a node is being dragged from the palette leading to node creation & insertion +* "insertNodeIntoLink" - when an existing node is dragged from the canvas leading to insertion of the existing node into the link + +#### **enableRightFlyoutUnderToolbar** +This can be true or false. The default is false. If set to true the right flyout panel, when opened, will appear below the toolbar and will not cause the toolbar to compress. The default behavior is that the right flyout panel, when opened, will appear at the side of the toolbar and will compress the space available for the toolbar to be displayed. Warning: the notifications panel which is tied to the notifications icon in the toolbar will appear over the top of the right-side flyout with this option set to true. + +#### **enablePositionNodeOnRightFlyoutOpen** +This can be a boolean or an object. The default is false. If set to true, when the right-side flyout is open the currently selected node (assuming there is one) will be automatically positioned in the center of the viewport (canvas area). Instead of true this field can also be set to a simple JavaScript object like this `{ x: 30, y: 40 }` where x and y indicate the position where the node will be positioned as a percentage of the width and height of the viewport respectively. + +#### **enableHighlightNodeOnNewLinkDrag** +This can be true or false. The default is false. If set to true common-canvas will add the "data-new-link-over" attribute to the node's group `` element, when the end of a new link is dragged to be close to and over a target node. This allows applications to alter the appearance of the target node as a new link is dragged towards it. + +#### **enableHighlightUnavailableNodes** +This can be true or false. The default is false. If set to true, when the user begins to drag a new link line, common-canvas will add a new class called `d3-node-unavailable` to all nodes which cannot accept the link as input. The class will be applied to each node's group `` element in the DOM. This class can be used for styling the unavailable nodes as desired using CSS. The default styling will 'gray out' the node label, node outline rectangle (if there is one) and the node icon (provided it is an SVG image). These styles can be overridden in the applications CSS if different styling is needed. This behavior also applies if the end of a partially or fully detached link is dragged. + +#### **enableAutoLinkOnlyFromSelNodes** +This can be true or false. The default is false. When set to true the auto-add function (where double clicking a node in the palette automatically adds it to the canvas) will only link up nodes when a node is already selected on the canvas and then, only if the selected node can be linked to the node that was double clicked. If false, the auto-add function will make a best guess at which node the double-clicked node should be added to. + +#### **enableMoveNodesOnSupernodeResize** +This can be true or false. The default is true. If true, nodes surrounding a supernode will be moved when the supernode is expanded or manually resized so that the supernode does not overlay them. When set to false, the nodes surrounding a supernode will stay in their current positions when the supernode is expanded or manually resized. This may result in the nodes being overlaid by the supernode. + +#### **enableExternalPipelineFlows** +This can be true or false. The default is false. If true, the context menu will include a `Create External Supernode` option when a set of objects are selected from which a supernode can be created. + +Waring: The host application must implement some of the common-canvas callbacks for external pipeline flow support to work correctly. See the Wiki section on [external pipeline flow support](/2.9-External-Subflows-support) for more details. + +#### **enableDisplayFullLabelOnHover** +This can be true or false. The default is false. If set to true, any abbreviated node label will be displayed in full when the pointer hovers over the label. If set to false, abbreviated node labels will remain the same when the pointer hovers over them. + +#### **enableSingleOutputPortDisplay** +This can be true or false. The default is false. If set to true, only the last of the ports from the array of output ports will be displayed for each node. This config property is only applicable to applications with very specialized styling and handling of ports. If set to true with regular applications, it may result in a confusing display to the user. The single port is displayed at a position specified by outputPortRightPosX and outputPortRightPosY layout properties. For exmaple: +```js +config = { + enableSingleOutputPortDisplay: true, + enableNodeLayout: { + outputPortRightPosX: 0, + outputPortRightPosY: 20 +}; +``` +#### **enableDragWithoutSelect** +This can be either true or false. The default is false. If set to true, the user can drag and drop a single node or a single comment without that gesture removing selection on any other nodes or comments. If the node being dragged was selected prior to the drag gesture then it and any other objects that are currently selected will be moved. With this parameter set to false (or missing) a drag and drop gesture will select the node or comment being dragged and will deselect any currently selected objects. + +#### **enableMarkdownInComments** +This can be true or false. The default is false. When set to true the user may enter markdown syntax into comments on the canvas when in edit mode for the comment. When the editing ends, the comment is shown in presentation mode and the markdown syntax is converted to HTML which is displayed in the comment and is styled by CSS. + +#### **enableStateTag** +This can be either "None", "Locked" or "ReadOnly". The default is "None". When set to either "Locked" or "ReadOnly", a 'state tag' object will be shown permanently over the top of the canvas. The state tag will be positioned in the center and towards the top of the canvas. The state tag consists of a black background rectangle with rounded corners overlaid with an icon and a text label. A tooltip is displayed when the mouse pointer is hovered over the state tag. The icon, label and default tooltip will be set appropriately based on the value ("Locked" or "ReadOnly") for this setting. The host application can override the tooltip by implementing the [tipHandler callback](/2.2-Common-Canvas-callbacks#tiphandler). + +#### **enableEditingActions** +This can be true or false. The default is true. If set to false, various editing actions on the canvas will be prevented, as follows: +1. Nodes cannot be created on the canvas using any of the following: + + (a) dragging and dropping a node template from the palette onto the canvas or + + (b) dragging and dropping an object onto the canvas from outside the canvas area, such as a file being dragged from the computer desktop onto the canvas (see note below), or + + (c) double clicking a node in the palette to create a node + + Note: It is not possible for common-canvas to prevent an object being dragged from the computer desktop to the canvas so it is recommended the drop zone (which provides visual feedback about the drop) should be switched off by setting the [enableDropZoneOnExternalDrag](/2.1-Config-Objects#enabledropzoneonexternaldrag) config field to `false`. +2. Nodes and comments cannot be dragged and moved. +3. The end points of Links, when [enableLinkSelection](/2.1-Config-Objects#enablelinkselection) is set to `"Detachable"` or `"Handles"`, cannot be dragged and moved. +4. Links from nodes and comments cannot be created by dragging from the port object on the source node or comment to the target node. +5. Comments, node labels and text decorations cannot be edited, neither by clicking the edit icon (which does not appear) nor by double clicking the text. +6. Context menu options that alter the canvas objects will be removed from the context menu before it is displayed by common-canvas. The options that will be removed are: + + |Option Text|Action Identifier| + |---|---| + |New Comment|createComment| + |Disconnect|disconnectNode| + |Edit->Cut|cut| + |Edit->Copy|copy| + |Edit-Paste|paste| + |Undo|undo| + |Redo|redo| + |Delete|deleteSelectedObjects| + |Create supernode|createSuperNode| + |Create external supernode|createSuperNodeExternal| + |Deconstruct supernode|deconstructSuperNode| + |Collapse supernode|collapseSuperNodeInPlace| + |Expand supernode|expandSuperNodeInPlace| + |Convert external to local|convertSuperNodeExternalToLocal| + |Convert local to external |convertSupernodeLocalToExternal| + |Delete|deleteLink| + |Save to palette|saveToPalette| + + If your application adds its own editing actions to the context menu your code must remove them if they are not needed in some situations (e.g. you are displaying a read-only canvas). +7. Any default toolbar actions (tools) that alter the canvas objects will be disabled regardless of their specified enablement status. These actions are: + + |Default Tooltip|Action| + |---|---| + |Undo|undo| + |Redo|redo| + |Cut|cut| + |Copy|copy| + |Paste|paste| + |Delete|deleteSelectedObjects| + |New comment|createAutoComment| + |Arrange Horizontally|arrangeHorizontally| + |Arrange Vertically|arrangeVertically| +8. Keyboard shortcuts that alter the canvas will not work. These are: + + |Shortcut|Action| + |---|---| + |delete|delete| + |Ctrl/Cmd + x|cut| + |Ctrl/Cmd + c|copy| + |Ctrl/Cmd + v|paste| + |Ctrl/Cmd + z|undo| + |Ctrl/Cmd + Shift + z|redo| + |Ctrl/Cmd + y|redo| +9. The browser's Edit menu options (cut, copy, paste) will not work with the canvas objects regardless of the setting for [enableBrowserEditMenu](/2.1-Config-Objects#enablebrowsereditmenu). + +#### **enableDropZoneOnExternalDrag** +This can be true or false. The default is false. If set to true a graphic overlay will be displayed over the canvas when a data object icon is dragged from the desktop over the canvas. The default graphic overlay will be an image and a message saying: "Drop to add to canvas and project" unless the `dropZoneCanvasContent` configuration parameter is provided. + +See the [Dragging an object from the desktop](/2.3-Enabling-node-creation-from-external-object#dragging-object-from-the-desktop-or-another-application) section of the Wiki for details on how to handle the drop of an external object onto the canvas. + +#### **enableNodeLayout** +This is a simple Javascript object, the properties of which override the default node layout properties. For more details see: [Customizing Node Layout Properties](/2.7-Customizing-Node-Layout-Properties) + +#### **enableSaveZoom** +This can be: "None", "LocalStorage" or "Pipelineflow". The default is "None". +* "None" - When the canvas is zoomed, the zoom (scale and x/y pan) are not saved anywhere so if the canvas is closed and reopened it reopens with the default zoom which is a scale of 1 and x/y pan values of 0. +* "LocalStorage" - The zoom for the canvas is stored in the browser's local storage and will be reapplied to the canvas each time that canvas is shown in that browser. This applies to sub-flows, when the user displays them full-screen, as well as the primary flow. Sub-flows and the primary flow each have their own zoom amounts stored in local storage. Note: Zoom amounts stored in local storage can be cleared from storage by calling the `canvasController.clearSavedZoomValues()` API method. +* "Pipelineflow" - The zoom is serialized into the pipeline flow document and when a pipeline flow document is provided to common canvas through the API the zoom will be applied to the canvas display. Zoom amounts can be stored for both primary and sub pipelines. (See the pipelineFlow schema specification). + +#### **enablePanIntoViewOnOpen** +This can be either true or false. The default is false. If set to true, the canvas will be panned so as much of the canvas area (the area containing the nodes and comments) is visible in the viewport as possible. This will only happen when enableSaveZoom === "None" or if there is no saved zoom available either in local storage (when enableSaveZoom === "LocalStorage") or in the pipelineFlow (when enableSaveZoom === "Pipelineflow"). + +#### **enableZoomIntoSubFlows** +This is a boolean. The default is false. When set to true, common-canvas will override the maximum zoom extent value which, by default is used for the entire canvas, to allow the user to zoom in on in-place sub-flows further than they can do on containing flows. This means the user can zoom in on multi-nested sub-flows so they are easier to view. To see this effect, the user must position the mouse pointer over the sub-flow before performing the zoom gesture. + +#### **enableContextToolbar** +This is a boolean. The default is false. When set to true, common-canvas will display a context toolbar instead of a context menu for performing actions on canvas objects. A context toolbar is a small toolbar that appears above nodes, links and comments as the mouse cursor is hovered over them. The toolbar shows icons for actions the user is most likely to want to perform on the object. An overflow icon is displayed which, when clicked, shows a menu of additional actions. A context toolbar for the canvas background can also be displayed by right-clicking on the background. Common-canvas will display default context toolbars for nodes, links comments and the canvas background however the default actions can be customized by implementing the [`contextMenuHanlder`](/2.2-Common-Canvas-callbacks#contextmenuhandler) callback. + +#### **enableSnapToGridType** +This can be: "None", "During" or "After". The default is "None". +* "None" - there is no snap to grid and objects can be moved to any position on the canvas. +* "During" - when nodes or comments are moved or sized, the objects snap to an imaginary grid while the objects are being dragged or sized. This gives a somewhat jerky effect as the move or size is happening but has the advantage of telling the user exactly where the object will be when they release the mouse button to end the action. +* "After" - nodes or comments snap to a grid when the drag or size event ends. This gives a smooth dragging and sizing effect but the user does not see the final position until they release the mouse button at the end of the action. By default the canvas uses reasonable values for the grid increments. + +#### **enableSnapToGridX** +This optional value overrides the default horizontal increment of the snap-to-grid grid. It can be either a numeric value which is a number of pixels or it can be a numeric value followed by a % sign (e.g. "25%") which indicates the grid will be a percentage of the default node width. Its default is dependent on whatever is set for enableNodeFormatType. That is for "Horizontal" it will be "20%" and for "Vertical" it will be "25%". + +#### **enableSnapToGridY** +This optional value overrides the default vertical increment of the snap-to-grid grid. It can be either a numeric value which is a number of pixels or it can be a numeric value followed by a % sign (e.g. "25%") which indicates the grid will be a percentage of the default node height. Its default is dependent on whatever is set for enableNodeFormatType. That is for "Horizontal" it will be "33.33%" and for "Vertical" it will be "20%". + +#### **enableAutoLayoutVerticalSpacing** +This is the spacing in pixels which is used to separate nodes vertically when either the vertical or horizontal auto layout action is used. + +#### **enableAutoLayoutHorizontalSpacing** +This is the spacing in pixels which is used to separate nodes horizontally when either the vertical or horizontal auto layout action is used. For horizontal auto layout, common-canvas may override this value if it decides that more space is needed to prevent connecting lines from doubling back on themselves. + +#### **enableAssocLinkCreation** +This is a Boolean. The default is `false`. If set to `true` it changes the nature of links that are created between nodes as follows: +- The user is able to pull out a link from either port on the node and drag it to another node +- When a link is completed an `association` link is created rather than the regular data flow link that is created when this field is set to `true`. Association links describe an association between pairs of nodes and do not indicate any kind of data flow between those nodes. + +#### **enableAssocLinkType** +This can be "Straight" or "RightSideCurve". The default it "Straight". This field changes the way association links are drawn on the canvas. + +#### **enableBrowserEditMenu** +This can be true or false. true is the default. If true, the Cut/Copy/Paste items in the Browser's `Edit` menu, including keyboard input for those actions, can be used for performing those actions on objects (e.g. Nodes) in the canvas. When false, those items in the Browser's edit menu, including keyboard input for those actions, will not work for objects in the canvas. This will not prevent those actions working in the canvas when, say, invoked with the toolbar or canvas context menus, but this property can be used if the keyboard input for those actions into the canvas is disabled for common-canvas using the [keyboard config](/2.1-Config-Objects#keyboard-config-object) object. + +#### **enableNarrowPalette** +This can be true or false. true is the default. If true when the palette is closed the narrow palette will be shown. When false the palette completely closes. + +#### **paletteInitialState** +Deprecated -- This option is deprecated and will be removed soon. Use `CanvasController.openPalette()` to display an opened palette at start-up. This `openPalette()` can be called immediately after creating the canvas controller. + +paletteInitialState can be true or false. false is the default. If set to true the palette will be opened when common canvas first appears to its full (non-narrow) state. + +#### **emptyCanvasContent** +This is a JSX or HTML snippet that contains some text or any elements (such as an image) that you want to display when the canvas is empty, that is, when it doesn't have any nodes or comments. The default behavior if this config parameter is not provided is that common canvas will display an image and message saying: "Your flow is empty!". + +#### **dropZoneCanvasContent** +This is a JSX or HTML snippet that contains some text or any elements (such as an image) that you want to display when a data object is dragged from the desktop over the canvas. The default behavior if this config parameter is not provided is that common canvas will display an image and a message saying: "Drop to add to canvas and project". The content will not be displayed unless the `enableDropZoneOnExternalDrag` configuration parameter (see above) is set to true. + +#### **schemaValidation** +This can be true or false. false is the default. It tells common canvas whether you want pipleineFlow and palette objects to be validated against the schema files when they are submitted to the canvas controller, using the `setPipelineFlow(pFlow)` or `setPipelineFlowPalette(palette)` methods. If any validation errors are found messages are displayed in the browser console. It is recommended this option be set to true during development and testing but switched off in production since schema validation can be somewhat slow for large objects. + +#### **tipConfig** +This is a simple JavaScript object that configures whether tips for palette items, nodes, ports, links, decorations or the state tag are enabled (value set to true) or disabled (value set to false). By default, all tips are enabled. The following would switch off tips for ports and links. +```js + "tipConfig": { + "palette": true, + "nodes": true, + "ports": false, + "links": false, + "decorations": true, + "stateTag": true + } +``` +The tips displayed by the palette can be further refined. For example, this would prevent tips for palette categories from being displayed, but would still display tips for node templates in the categories: +```js + "tipConfig": { + "palette": { + "categories": false, + "nodeTemplates": true + }, + "nodes": true, + "ports": false, + "links": false, + "decorations": true, + "stateTag": true + } +``` + +Note: The default content of tips can be overwritten by implementing the [tipHandler callback](/2.2-Common-Canvas-callbacks#tiphandler). + +# Toolbar Config object + +The toolbar config object is optional. If it is not provided common-canvas will display a reasonable default toolbar. If provided, it configures which action items (tools) and dividers are shown in the canvas toolbar. A toolbar will only be displayed for common-canvas if the canvas configuration field [`enableToolbarLayout`](/2.1-Config-Objects#enabletoolbarlayout) is set to "Top" (which is the default). + +If you do specify a toolbar config object, you can specify actions for the left and right side of the toolbar to override the default toolbar. You can also optionally tell the toolbar not to handle the enable/disable state for the standard toolbar buttons using `overrideAutoEnableDisable`. The `leftBar` and `rightBar` fields contain an array of objects: one element for each toolbar item. Here is an example, toolbar configuration object: + +```js + const toolbarConfig = { + leftBar: [ + { action: "undo", label: "Undo", enable: true }, + { action: "redo", label: "Redo", enable: true }, + { divider: true }, + { action: "cut", label: "Cut", enable: false }, + { action: "copy", label: "Copy", enable: false }, + { action: "paste", label: "Paste", enable: false }, + { divider: true }, + { action: "createAutoComment", label: "Add Comment", enable: true }, + { action: "deleteSelectedObjects", label: "Delete", enable: true }, + { action: "arrangeHorizontally", label: "Arrange Horizontally", enable: true } + { divider: true }, + { action: "insaneMode", label: "Switch on insane mode", enable: true, isSelected: true } + ], + rightBar: [ + { action: "stop", label: "Stop Execution", enable: false }, + { divider: true }, + { action: "run", label: "Run Pipeline", enable: false } + ], + overrideAutoEnableDisable: false + }; +``` +Where: +* **leftBar** - an array of action items to specify what is displayed on the left side of the toolbar. + +* **rightBar** - an array of action items to specify what is displayed on the right side of the toolbar. If this is omitted, common-canvas will automatically populate the right side of the toolbar with zoom-in, zoom-out, and zoom-to-fit actions. To suppress these right side actions, specify the `rightBar` field as an empty array or an array containing the actions you want on the right. + +* **overrideAutoEnableDisable** - a boolean. The default is false. By default common-canvas has an auto-enablement feature that controls the enablement of common tools in the toolbar based on user actions (e.g enable the `Delete` icon when items are selected). If `overrideAutoEnableDisable` set to true it will switch off the auto-enablement feature. This is useful if the host application wants to disable all the nodes under certain circumstances. If set to true, the `enable` property in the action items for each tool is used to decide whether to display the icon as enabled or disabled. If set to false or omitted, common-canvas will handle the auto-enablement of common actions. (See the `action`section below for more details.) + +Two toolbar items are automatically added to the toolbar: +- A palette action which is used for opening and closing the node palette. This is added to the left side of the left side of the toolbar if the [`enablePaletteLayout`](/2.1-Config-Objects#enablepalettelayout) field is set to either "Flyout" (the default) or "Modal" in the canvas configuration. +- A notification panel action which is used to open and close the notifications panel. This will be added to the right side of the toolbar if a [notification configuration](/2.1-Config-Objects#notification-config-object) object is specified to the `` react object. + +The toolbar will display the objects in the same order they are defined in the arrays. + +Here is an example of an action object which must contain a unique `action` field as a minimum. +```js + { + action: "run", + label: "Run", + enable: true, + iconEnabled: "/image/myOwnEnabledIcon.svg", + iconDisabled: "/image/myOwnDisabledIcon.svg", + incLabelWithIcon: "before", + kind: "primary", + tooltip: "Run the flow", + isSelected: false + } +``` +* **action** - a unique identifier and the name of the action to be performed. This action name will be passed in the `data` parameter of the [editActionHandler](/2.2-Common-Canvas-callbacks#editactionhandler) callback method so you can detect when the user clicks an action in the toolbar. + + If you are using the recommended (and default) [internal object model](/2.1-Config-Objects#enableinternalobjectmodel), the following built in actions will be automatically handled by common-canvas: `undo`, `redo`, `cut`, `copy`, `paste`, `createAutoComment`, `deleteSelectedObjects`, `arrangeHorizontally`, `arrangeVertically`, `zoomIn`, `zoomOut`, and `zoomToFit`. So for example, if the `deleteSelectedObjects` action (shown as a trash can) is clicked, any selected objects will be deleted from the internal object model. + + Disablement of some of these built in actions is also handled by common-canvas so, for example, when no canvas objects are selected the `deleteSelectedObjects` action (trash can icon) will be automatically disabled. You can switch off this automatic enable/disable function by setting `overrideAutoEnableDisable` field in the toolbar config to `true`. When set to true, the `enable` field in the action objects will be used to set the enablement appearance of the toolbar item. + +* **label** - the Tooltip label to display (and optionally the text to display next to the icon if `incLabelWithIcon` is specified). + +* **enable** - Icon will have hover effect and is clickable when set to true. If false, icon will be disabled and unclickable. If not set, it will default to disabled (false). If `overrideAutoEnableDisable` is set to false, or omitted, this field is ignored for the standard action items (like cut, copy, paste) because common canvas handles their enable/disable appearance. If `overrideAutoEnableDisable` is set to true, this field will be used for standard action items. + +* **iconEnabled** - specifies the icon to display when `enable` is true. Common-canvas will provide icons for the following actions so you don't need to specify `iconEnabled` or `iconDisabled` for them: `stop`, `run`, `undo`, `redo`, `cut`, `copy`, `paste`, `createAutoComment`, `deleteSelectedObjects`, `arrangeHorizontally`, `arrangeVertically`, `commentsShow`, `commentsHide`, `zoomIn`, `zoomOut`, and `zoomToFit`. + + It can be either: + - a string containing the path to a custom SVG file to display or + - a JSX expression, for example `()` where Edit32 is an icon imported from carbon icons. It is recommended to only pass very simple JSX expressions. + +* **iconDisabled** - specifies the icon to display when `enable` is false. If `iconDisabled` is *not* specified `iconEnabled` will be used instead. It can be omitted for any of the standard actions (see `iconEnabled` above). + + It can be either: + - a string containing the path to a custom SVG file to display or + - a JSX expression, for example `()` where Edit32 is an icon imported from carbon icons. It is recommended to only pass very simple JSX expressions. + +* **incLabelWithIcon** - can be set to "no", "before" or "after". The default is "no". This field specifies whether the label should be displayed in the toolbar with the icon and if so, where it is displayed with respect to the icon. + +* **kind** - can be set to "default", "primary", "danger", "secondary", "tertiary" or "ghost". The default it "default". These give the action the same styling as the equivalent kind's of [buttons in the carbon library](https://carbondesignsystem.com/components/button/usage#button-types). + +* **tooltip** - A string or JSX object. The tooltip that will be displayed for the action. If this is not provided the label will be displayed as the tooltip instead. + +* **isSelected** - A boolean. When set to true the toolbar button displays a selection highlight (which is a blue bar along the bottom border of the toolbar item). This is useful if you have a button that switches on and off a mode in your interface, as opposed to a regular button, which does not have any state, that would typically execute a command of some sort. For example, if your product has a 'Turbo boost' setting, which can be on or off, you could add a 'Turbo Boost' button to the toolbar and use `isSelected` to indicate when the option is active. When the user clicks the button it would switch `isSelected` for the 'Turbo Boost' button to true or false as appropriate. (This would give behavior like a checkbox.) + + You can also use this property to indicate a current state between a number of mutually exclusive settings. In this case, you would add one button to the toolbar for each setting and then set the `isSelected` property to true for the setting that is currently active. Then, when the user clicks a different option in the set, your code would set `isSelected` to true for that button and set it to false for the previously selected button. (This would give behavior like a radio button set.) + + +You can add dividers to separate groups of actions from other actions. This is displayed as a thin gray line. The divider object has one attribute: +```js + { + divider: true + } +``` +* **divider** - To show a divider in the toolbar, add an object with `divider` attribute set to true. + +### Deprecated toolbar config + + The old toolbar configuration is still supported for now (but is deprecated). This allows the config to be provided as an array that defines just the left side of the toolbar. The right side will always show the zoom actions (zoomIn, zoomOut, zoomToFit) and a notifications panel icon (if a notification configuration object is provided in the CommonCanvas react object). These right side actions will always show on the right-hand side of the toolbar and are handled internally by the canvas. The entries in the array follow the same definition as described above. Note: there is no need to provide a `palette` action in the array because a palette icon and following divider will automatically be added to the toolbar when a palette is specified for the canvas. + +An example of the toolbar config array should look like this: +```js + const toolbarConfig = [ + { action: "stop", label: "Stop Execution", enable: false }, + { action: "run", label: "Run Pipeline", enable: false }, + { action: "undo", label: "Undo", enable: true }, + { action: "redo", label: "Redo", enable: true }, + { action: "cut", label: "Cut", enable: false }, + { action: "copy", label: "Copy", enable: false }, + { action: "paste", label: "Paste", enable: false }, + { action: "createAutoComment", label: "Add Comment", enable: true }, + { action: "deleteSelectedObjects", label: "Delete", enable: true }, + { action: "arrangeHorizontally", label: "Arrange Horizontally", enable: true } + ]; +``` + +### Advanced: JSX actions +Regular toolbar buttons, explained above, are displayed as set of Carbon `Button`s. If you _don't_ want your content wrappered in a button, you can provide your own JSX to display as an action in the toolbar. Be aware however that, because of the way the toolbar is designed, there are restrictions on what the toolbar can do to display your JSX. For example, it cannot display anything with a height greater than the toolbar height. + +If you provide your own JSX object it is displayed in a simple `div` in the toolbar. Some attributes are applied to the `div` to allow the action to work correctly within the toolbar - these cannot be changed. You are responsible for styling your JSX object to get it to appear the way you want. + +Also be aware that, if the width of the toolbar reduces (maybe by the user sizing the page) your action may get moved into the overflow menu. It is also your responsibility to style the button so it appears as you want in the overflow menu as well as the toolbar. + +The JSX can be provided in the `jsx` field. Here is an example. The only other fields that are recognized with the `jsx` field are `action` and `tooltip`, all other fields will be ignored. + +```js + { + action: "custom-loading", + jsx: (
), + tooltip: "Loading the thing you wanted." + } +``` +* **action** - a unique identifier and the name of the action to be performed. + +* **jsx** - A JSX object. This will be displayed as the action in the toolbar. + +* **tooltip** - A string or JSX object. This will be displayed as the tooltip for the action in the toolbar. If `tooltip` is omitted no tooltip will be added to your action. If `tooltip` is specified the `jsx` will be inside a tooltip `div` which is in the toolbar `div` mentioned above. + +Here's an example toolbar that includes some Carbon React components +```js + toolbarConfig = { + leftBar: [ + { action: "custom-loading", + jsx: ( +
+ +
+ ) + }, + { divider: true }, + { action: "custom-checkbox", + jsx: ( +
+ +
+ ) + }, + { divider: true }, + { action: "custom-button", + tooltip: "A custom button of type primary!", + jsx: ( +
+ +
+ ) + }, + { divider: true }, + { action: "custom-dropdown", + tooltip: "A drop down using the overflow menu!", + jsx: ( +
+ + + + + +
) }, + { divider: true } + ] + }; +``` + +# Notification Config object + +The notification config object configures whether or not the notification icon will be shown in the canvas toolbar. It will appear to the far right of the zoom actions in the toolbar. +Similar to a toolbar action object, the notificationConfig object looks like this: +```js + const notificationConfig = { + action: "notification", + label: "Notifications", + enable: true, + notificationHeader: "Notification Messages", + notificationSubtitle: "subtitle", + emptyMessage: "You don't have any notifications right now.", + clearAllMessage: "Clear all", + keepOpen: true, + clearAllCallback: () => { console.log("Clear All clicked"); } + }; +``` +* **action** - "notification" enables the notifications icon to appear in the far right of the toolbar. + +* **label** - the Tooltip label to display for the notifications icon in the toolbar. + +* **enable** - Icon will have hover effect and is clickable when set to true. If false, icon will be disabled and unclickable. If not set, it will default to disabled (enable: false) + +* **notificationHeader** - String to display in the notification panel header. If not set, it will default to "Notifications". + +* **notificationSubtitle** - String to be displayed as a sub-title in the panel header. If not set panel header will be sized to only contain the `notificationHeader` string. + +* **emptyMessage** - String to be displayed when there are no notification messages to display. + +* **clearAllMessage** - String to be displayed on a button displayed at the bottom of the panel. The button can be clicked to clear all the messages from the panel. If omitted the button, and the footer area of the panel it appears in, will not be displayed. + +* **keepOpen** - A boolean which indicates when the panel will close. The default is false. If set to false, the panel will close when the user clicks on the page somewhere outside the panel. If set to true the panel will remain open when the user clicks somewhere on the page outside of the panel. With the option the user must click the `x` icon in the top right of the panel, or click the notification toolbar icon, to close the panel. + +* **clearAllCallback** - An optional callback function that will be called every time the "clear all" button is clicked. + +* **secondaryButtonLabel** - Label for the optional secondary button to be displayed in the notification panel. Both `secondaryButtonLabel` and `secondaryButtonCallback` must be specified for the button to appear. +* **secondaryButtonCallback** - A callback function that will be called when the secondary button is clicked. +* **secondaryButtonDisabled** - Specify whether the secondary button is disabled or not. + + +The notification icon state is determined by the type of messages in the notification message array. By default, a notifications icon in ready state will be shown if there are messages in the notification message array. If any message in the array is of type 'warning', a notifications icon in warning state will be shown. If any message in the array is of type 'error', a notifications icon in error state will be shown. A number will be shown within the notifications icon to indicate the number of messages. + +For information about the structure of notification messages, refer to the [message specification documentation](/2.4.4-Notification-Message-Specification). Notification messages can be added and removed from the notification panel by calling the canvas controller API. Refer to the canvas controller API documentation for information on how to [add/set messages in the notification message array](/2.4-Canvas-Controller-API#notification-messages-methods). + +# Context Menu Config object + +The context menu config object configures whether certain actions are available in the default context menu. + +```js + const contextMenuConfig = { + enableCreateSupernodeNonContiguous: false, + defaultMenuEntries: { + saveToPalette: true, + createSupernode: false, + displaySupernodeFullPage: true, + colorBackground: false + } + }; +``` +* **enableCreateSupernodeNonContiguous** - Allows the creation of supernodes from non-contiguous nodes. When set to `true`, the "Create supernode" menu item will be added to the default context menu when the currently selected nodes are contiguous or non-contiguous. When set to `false`, the "Create supernode" menu item is only added to the default context menu when the selected nodes are contiguous. The default value is `false`. + +* **defaultMenuEntries** - Controls what entries are generated in the default context menu generated by common canvas. This has the following properties: + * 'saveToPalette' - This is a boolean. The default is false. If set to true, common canvas will add a 'Save to palette' option to the default node context menu. + * 'createSupernode' - This is a boolean. The default is true. If set to false, common canvas will not show the 'Create Supernode' option in the default context menu for nodes. + * 'displaySupernodeFullPage' - This is a boolean. The default is true. If set to false, common canvas will not show the 'Display full page' option in the default context menu for supernodes. When true, the option will be displayed. Clicking that option navigates the user to the full page view of the supernode's pipeline as if the user had clicked the expansion icon of the expanded in-place supernode view. + * 'colorBackground' - This is a boolean. The default is true. If set to false, common canvas will not show the 'Color background' option in the default context menu for comments. When true, the option will be displayed. + +[Note: If any host app wants more control over the default context menu here, please open an issue.] + +# Keyboard Config object + +The keyboard config object configures whether certain actions are available from the keyboard. +See this section for what [key combinations are supported](/2.0-Common-Canvas-Documentation#keyboard-support) +```js + const keyboardConfig = { + actions: { + delete: false, + undo: false, + redo: false, + selectAll: false, + cutToClipboard: false, + copyToClipboard: false, + pasteFromClipboard: false + }; +``` +All actions are `true` by default so it is only necessary to specify those actions you don't want as `false`. \ No newline at end of file diff --git a/guide/2.2-Common-Canvas-callbacks.md b/guide/2.2-Common-Canvas-callbacks.md new file mode 100644 index 0000000000..46c8bc63f4 --- /dev/null +++ b/guide/2.2-Common-Canvas-callbacks.md @@ -0,0 +1,676 @@ +# Event listener callbacks + +You can *optionally* provide callback listeners. These will be called when the user interacts with the canvas. + +These listeners are as follows: + +## contextMenuHandler +```js + contextMenuHandler(source, defaultMenu) +``` +This callback is used for both 'context menus' and, if the [`enableContextToolbar`](/2.1-Config-Objects#enablecontexttoolbar) canvas config option is set to `true`, for 'context toolbars'. + +If this callback is not provided common canvas will handle context menu/toolbars, and their actions, internally. You only need to implement this callback if you want to add or remove options to/from the context menu/toolbar. + +The job of this callback is to tell common canvas what items to display in the context menu/toolbar. + +### For Context Menu + +For context menus this will be dependent on what object or set of objects the context menu was requested for by the user. + +This callback will be called if the user performs a context menu gesture (such as mouse 'right click') on a: +* node +* link +* comment +* port +* on the canvas background or +* if a number of objects are selected, the combination of objects. + +This callback must return an array that defines the menu to be displayed. If the callback is *not* provided, a default context menu (the defaultMenu passed into the handler) will be displayed by the common canvas. + +The source object passed in looks like this: +```js + { + type: "node", + targetObject: {}, + selectedObjectIds: ["node_1", "node_2"], + mousePos: {x: "10", y:"20"} + } +``` +**type** - Indicates type of object for which the context menu was selected. Can be "node", "port", "link", "canvas" or "comment" + +**targetObject** - The object for which the context menu was requested. Only provided when type is "node" or "comment" + +**selectedObjectIds** - An array containing the IDs of all currently selected nodes and/or comments + +**mousePos** - An object containing the coords of the mouse when the context menu was requested + +The callback would need to return an array, that describes the context menu to be displayed, that looks something like this: +```js + [ + {action: "deleteSelectedObjects", label: "Delete"}, + {divider: true}, + {action: "myAction", label: "My Action"} + {action: "myUnavailableAction", label: "A test disabled item", enable: false} + ] +``` +There is one element in the array for each entry in the context menu. An entry can be either a context menu item, which consists of a label and an action, or a divider, whose field would need to be set to true. + +Actions can be either internal (implemented inside the common canvas, like "deleteSelectedObjects" above) or external (like "myAction"). + +Existing internal actions are: + +* selectAll +* cut +* copy +* paste +* undo +* redo +* createSupernode +* expandSupernode +* collapseSupernode +* deleteSelectedObjects +* createComment +* deleteLink +* disconnectNode +* highlightBranch +* highlightDownstream +* highlightUpstream +* unhighlight + +External actions are custom actions you want common canvas to display for your application. To get common canvas to display your action you would need to return an array from the callback that includes a menu item for the action. + +When the user clicks the option in the context menu matching your action common canvas will call the [editActionHandler](#editactionhandler) callback so you'll need to implement some code in that callback to execute the intended action. If you want to simply add your action to the default context menu provided by common canvas you can take the defaultMenu parameter provided to the callback and add your menu item to it. Alternatively, you can provide a complete new context menu of your own. + +Here is a sample implementation of contextMenuHandler, which takes a source object (described above) and the defaultMenu as parameters, and adds a custom action to the default menu when the user 'right clicks' the canvas background. + +```js + contextMenuHandler(source, defaultMenu) { + let customMenu = defaultMenu; + if (source.type === "canvas") { + customMenu = customMenu.concat({ action: "myAction", label: "My Action" }); + } + return customMenu; + } +``` +In addition to adding the context menu item, you would also need to implement the editActionHandler callback to execute the action, like this: +```js + editActionHandler(data) { + if (data.editType === "myAction") { + // Execute my action code here. + } + } +``` +Tip: To avoid any future name clashes with internal actions you should make sure you action names are unique. For example, you could add a prefix to your action names eg. `$MyApp_action` where `$MayApp_` is the prefix for all your actions. + +### For Context Toolbar + +For context toolbars, this will be dependent on which object the mouse cursor is currently hovering over (which may be different to any of the currently selected objects). + + +## editActionHandler +```js + editActionHandler(data, command) +``` +This callback is optional. You don't *need* to implement anything for it and it doesn't return anything. It is called whenever the user does the following types of action on the canvas: + +* Clicks a tool in the toolbar. +* Clicks an option in the context menu. +* Presses a [key combination](/2.0-Common-Canvas-Documentation#keyboard-support) on the keyboard to cause the canvas to change. +* Performs some direct manipulation on the canvas such as: + - Creates a node (createNode) + - Moves one or a set of nodes/comments (moveObjects) + - Edits a comment (editComment) + - Links two nodes together (linkNodes) + - Links a comment to a node (linkComment) + - Resizes a supernode (resizeObjects) + - Resizes a comment (editComment) + - Expands a supernode in place (expandSuperNodeInPlace) + - Navigates into a sub-flow in a supernode (displaySubPipeline) + - Navigates out of a sub-flow in a supernode (displayPreviousPipeline) + + +This callback is called *after* the common-canvas internal object model has been updated. This callback is provided with two parameters: `data` and `command`. + +1. **data parameter** - that looks like this. The data provided can vary depending on the action the user performed. +```js + { + editType: "createComment", + editSource: "contextmenu", + selectedObjects: [], + selectedObjectIds: [], + offsetX: 100, + offsetY: 42 + } +``` + + ***editType*** - This is the action that originates from either the toolbar, context menu, keyboard action or direct manipulation on the canvas. If you specified your own action in the context menu or in the toolbar this field will be your action's name. + + + ***editSource*** - This is the source of the action. It can be set to "toolbar", "contextmenu", "keyboard" or "canvas" (for an action caused by direct manipulation on the canvas). + + + ***selectedObjects*** - An array of the currently selected objects. + + + ***selectedObjectIds*** - An array of the IDs of currently selected objects. Included for backward compatibility. + + + ***Other fields*** - Numerous other fields which vary based on the action and the source of the action. + +2. **command parameter** - This is a Javascript class which is the command object that was added to the command stack and executed to run the action 'requested' by the user. If the user performed an `undo` action this will be the command that has been undone. If the user performed a `redo` action this will be the command that was redone. The command object may contain fields which are connected with the execution of the command. + +## beforeEditActionHandler +```js + beforeEditActionHandler(data, command) +``` +This callback is optional. You don't *need* to implement anything for it but if you do implement it you **must** return either a data object or null. This callback is called in all the same instances where `editActionHandler` is called. The difference is that this callback is called *before* the internal object model is updated. This gives your application the opportunity to examine the action that is about to be performed and either: let it continue; modify it and let it continue; or cancel it. + + This callback is provided with two parameters: `data` and `command`. +1. **data parameter** - this is the same as the data object described for `editActionHandler` (see above) +2. **command parameter** - typically this will be null but for `undo` operations (that is where data.editType === "undo") this will be the command that is about to be undone. For `redo` operations (that is where data.editType === "redo") this will be the command that is about to be redone. + +This callback *must* return either the data object that was passed in or null. `beforeEditActionHandler` will behave as follows based on what is returned: +* If the data object is returned unmodified: the action will be performed as normal. +* If the data object is returned modified: the action will be performed based on the modified data object. This means your application can alter the behavior of the action that will be performed. For example, you could intercept a `createNode` command and change the label for the new node in the nodeTemplate to something different. Then when the node is created the new label will be used. It is recommended you be **very** **very** careful when updating this object since there is no error checking in common-canvas to ensure you modified the object correctly. +* If `null` is returned: the action will be cancelled and not performed on the internal object model nor will `editActionHandler` be called. + +If you need to do any asynchronous activity in the beforeEditActionHandler callback you can: +* Return null from the callback - which will cancel the current action +* Do your asynchronous activity. While this is happening, the user ought to be prevented from modifying the canvas so you should display some sort of progress indicator or modal dialog to inform the user that some activity is occurring. +* Then call `CanvasController.editActionHandler(data)` passing in the `data` object as a parameter with the modified properties. This will then execute the action as before. Note: This means the `beforeEditActionHandler` will be called a second time so be sure you put in a check to make sure you don't get into a loop. + +## clickActionHandler +```js + clickActionHandler(source) +``` +This callback is provided for your information. You don't need to implement anything for it and it doesn't need to return anything to common canvas. It is called whenever the user clicks or double clicks on something on the canvas. You could use this callback to implement opening a properties dialog when the user double clicks a node. + +Note: When handling selections, it is recommended the selectionChangeHandler be used in preference to this handler when possible. selectionChangeHandler will notify you of all selection changes regardless of how they occur, such as when the user presses Ctrl+A on the keyboard to select all objects. + +At the moment only click/double-click on nodes and the canvas background are returned. It is provided with one parameter that looks like this: +```js + { + clickType: "DOUBLE_CLICK" + id: "node_1", + objectType: "node", + selectedObjectIds: ["node_1", "node_2"] + } +``` +The fields can be: +* clickType - This can be either "SINGLE_CLICK", "SINGLE_CLICK_CONTEXTMENU" or "DOUBLE_CLICK" +* objectType - Can be either "node", "comment", "canvas" or "region". "region" is specified when the user pulls out a selection rectangle around a set of objects that might include nodes and comments. +* id - The ID of the node or comment clicked. Only provided when objectType is "node" or "comment" +* selectedObjectIds - An array of the selected objects (after the click action was performed). + +Note: "SINGLE_CLICK_CONTEXTMENU" indicates that the user performed a contextmenu gesture when doing the click such as pressing the right-side mouse button or a two finger tap on a trackpad. + +## decorationActionHandler +```js + decorationActionHandler(object, id, pipelineId) +``` +Decorations are small images that can be displayed on or near to your nodes and links. They can be for display only or actionable (so the user can click on them). See the canvas JSON schema for information on how to define decorations for your nodes. + +This callback is called when the user clicks on an actionable decoration. You don't need to implement anything for this callback unless you added actionable decorations to your nodes. It doesn't return anything. It is called whenever the user clicks on a decoration that you added to a node in the canvas JSON. + +It is provided with two parameters: +* object -- the node or link with which the decoration is associated. +* id -- the ID of the decoration that you provided in the canvas JSON +* pipelineId -- the ID of the pipeline for the node. + +## tipHandler +```js + tipHandler(tipType, data) +``` +Note: The display of tooltips (or not) can be controlled using the [`tipConfig`](/2.1-Config-Objects#tipconfig) field of the canvas config object. + +This optional callback can be implemented to override the tooltip content that is displayed by default for each canvas object. It is called before tips are shown for: palette categories, palette node templates, node, ports, links, decorations and the state tag. Common-canvas provides default implementations for all of the tips except for links and decorations, as follows: + +|Object | Default tip behavior | +|:--------|:----------------------| +| Palette category | Contains the category name and the category description. | +| Palette node template | Contains the category name, the node type and node description. | +| Node | Contains the name, description and status icon and optionally, if the name was modified from the original name, the original node type. | +| Port | The port label is shown | +| Link | No tip is shown by default | +| Decoration | No tip is shown by default | +| State tag | An appropriate explanation for the state displayed by the tag| + +To override the content, you can return either a string or JSX object. If your code returns `null` for a particular type of tip, common-canvas will display the default tip for that object. For an example of an implementation for a `tipHandler`, see App.js in the test harness code (https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/client/App.js). + +Common-canvas calls the `tipHandler` callback with two parameters: +- tipType - the type of the tip +- data - an object that describes the canvas element for which the tip was requested + +Here are some specific examples: + +#### Palette categories: + - tipType: "tipTypePaletteCategory" + - data: An object with category information, like this: + +```js +{ + category: { + id: "1234", + label: "Import", + description: "Category for import nodes", + image: "/images/import.svg" + } +} +``` + +#### Palette nodes templates: + - tipType: "tipTypePaletteItem" + - data: An object with node template information: +```js +{ + nodeTemplate: { + label: "C50", + description: "C50 Model", + operator_id_ref: "com.ibm.commonicons.models.c50", + type: "model_node", + image: "/images/common_node_icons/models/model_c50.svg", + input_ports: [{...}], + output_ports: [] + } +} +``` +#### Nodes: + - tipType: "tipTypeNode" + - data: An object with pipelineId and node information: +```js +{ + pipelineId: "153651d6-9b88-423c-b01b-861f12d01489", + node: { + id: "idGWRVT47XDV", + type: "execution_node", + operator_id_ref: "type", + output_ports: [...], + input_ports: [...], + label: "Define Types", + description: "", + image: "", + x_pos: 445, + y_pos: 219 + } +} +``` + +#### Ports: + - tipType: "tipTypePort" + - data: An object with pipelineId, node and port information: +```js +{ + pipelineId: "153651d6-9b88-423c-b01b-861f12d01489", + node: { + id: "idGWRVT47XDV", + type: "execution_node", + operator_id_ref: "type", + output_ports: [{...}], + input_ports: [{...}], + label: "Define Types", + description: "", + image: "", + x_pos: 445, + y_pos: 219 + }, + port: { + id: "outPort", + label: "Output Port" + } +} +``` + +#### Links + - tipType: "tipTypeLink" + - data: An object with pipelineId and link information. +```js +{ + pipelineId: "153651d6-9b88-423c-b01b-861f12d01489", + link: { + id: "canvas_link_3", + x1: 515, + y1: 248, + x2: 611, + y2: 180, + class_name: "canvas-data-link", + type: "nodeLink", + src: { + id: "idGWRVT47XDV", + type: "execution_node", + operator_id_ref: "type", + output_ports: [{...}], + input_ports: [{...}], + label: "Define Types", + description: "", + image: "", + x_pos: 445, + y_pos: 219 + }, + srcPortId: "outPort", + trg: { + id: "id8I6RH2V91XW", + type: "binding", + operator_id_ref: "c50", + output_ports: [], + input_ports: [{...}], + label: "C5.0", + description: "", + image: "", + x_pos: 611, + y_pos: 151 + }, + trgPortId: "inPort" + } +} +``` + +#### Decorations + - tipType: "tipTypeDec" + - data: An object with pipelineId and decoration information. +```js +{ + pipelineId: "153651d6-9b88-423c-b01b-861f12d01489", + decoration: { + "id": "2016", + "position": "topRight", + "label": "LCFC", + "tooltip": "Foxes never quit" + } +} +``` + +#### State tag + - tipType: "tipTypeStateTag" + - data: An object with pipelineId and decoration information. +```js +{ + stateTagText: "This flow is locked and cannot be edited.", + stateTagType: "Locked" +} +``` + + + +## idGeneratorHandler +```js + idGeneratorHandler(action, data) +``` +This callback is called when new objects are created in the canvas and allows the user to provide their own method to generate a unique id for the object. If no idGeneratorHandler is set or the method returns null, a UUID is generated by common-canvas. The method is called with a string for the action that was performed (create node/comment/link, clone node/comment/link) and a JSON object with additional data. +- create node: + * action: create_node + * data: +```js +nodeType: +{ + "label":"C50", + "description":"C50 Model", + "operator_id_ref":"com.ibm.commonicons.models.c50", + "type":"model_node", + "image":"/images/common_node_icons/models/model_c50.svg", + "input_ports":[ + { + "id":"inPort", + "label":"Input Port", + "cardinality":{ + "min":0, + "max":1 + } + } + ], + "output_ports":[ + + ] +} +``` +- create comment: + * action: create_comment + * data: n/a + +- create node link: + * action: create_node_link + * data: +```js +sourceNode: { + "id":"6a547456-f1ea-48a6-9721-45d6ae70dd6b", + "label":"Aggregate", + "type":"execution_node", + "operator_id_ref":"com.ibm.commonicons.operations.aggregate", + "image":"/images/common_node_icons/operations/operation_aggregate.svg", + "class_name":"d3-node-body", + "input_ports":[...], + "output_ports":[...], + "x_pos":55, + "y_pos":97.5, + "inputPortsHeight":20, + "outputPortsHeight":20, + "height":75, + "width":70 +}, +targetNode: { + "id":"71c96629-be46-418b-be63-0a02ef2fe2e0", + "label":"Append", + "type":"execution_node", + "operator_id_ref":"com.ibm.commonicons.operations.append", + "image":"/images/common_node_icons/operations/operation_append.svg", + "class_name":"d3-node-body", + "input_ports":[...], + "output_ports":[...], + "x_pos":264, + "y_pos":83.5, + "inputPortsHeight":20, + "outputPortsHeight":20, + "height":75, + "width":70 +} +``` +- create comment link: + * action: create_comment_link + * data: +```js +comment: { + "id":"8c81aac7-ebe5-4f96-9d63-eabc22b09635", + "class_name":"d3-comment-rect", + "content":"", + "height":42, + "width":175, + "x_pos":50, + "y_pos":50 +}, +targetNode: { + "id":"71c96629-be46-418b-be63-0a02ef2fe2e0", + "label":"Append", + "type":"execution_node", + "operator_id_ref":"com.ibm.commonicons.operations.append", + "image":"/images/common_node_icons/operations/operation_append.svg", + "class_name":"d3-node-body", + "input_ports":[...], + "output_ports":[...], + "x_pos":264, + "y_pos":83.5, + "inputPortsHeight":20, + "outputPortsHeight":20, + "height":75, + "width":70 +} +``` +- clone node: triggered when copying&pasting a node + * action: clone_node + * data: +```js +node: { + "id":"56d30c83-3a08-4147-933e-b01d3c348ac1", + "label":"Append", + "type":"execution_node", + "operator_id_ref":"com.ibm.commonicons.operations.append", + "image":"/images/common_node_icons/operations/operation_append.svg", + "class_name":"d3-node-body", + "input_ports":[...], + "output_ports":[...], + "x_pos":265, + "y_pos":177.5, + "inputPortsHeight":20, + "outputPortsHeight":20, + "height":75, + "width":70 +} +``` +- clone comment: triggered when copying&pasting a comment + * action: clone_comment + * data: +```js +comment: { + "id":"8c81aac7-ebe5-4f96-9d63-eabc22b09635", + "class_name":"d3-comment-rect", + "content":"", + "height":42, + "width":175, + "x_pos":50, + "y_pos":50 +} +``` +- clone node link: triggered when copying&pasting two connected nodes + * action: clone_node_link + * data: +```js +link: { + "id":"12c4308e-f572-402a-8dd3-604d438539d4", + "class_name":"d3-data-link", + "srcNodeId":"2b1af6c2-f98b-4728-97b3-416d40224bce", + "trgNodeId":"b43fffe6-dc01-4d30-8b6d-abd977850a2e", + "type":"nodeLink" +}, +sourceNodeId: "56d30c83-3a08-4147-933e-b01d3c348ac1", +targetNodeId: "815271f0-f4da-4793-ab8f-c4c32d3dd7e0" +``` +Note that the link to be cloned has references to the original source and target nodes, while the sourceNodeId and targetNodeId are the new node ids for the copied nodes. The new nodes are not part of the model yet. +- clone comment link: triggered when copying&pasting a comment and a node that are connected + * action: clone_comment_link + * data: +```js +link: { + "id":"12c4308e-f572-402a-8dd3-604d438539d4", + "class_name":"d3-comment-link", + "srcNodeId":"2b1af6c2-f98b-4728-97b3-416d40224bce", + "trgNodeId":"b43fffe6-dc01-4d30-8b6d-abd977850a2e", + "type":"commentLink" +}, +sourceNodeId: "56d30c83-3a08-4147-933e-b01d3c348ac1", +targetNodeId: "815271f0-f4da-4793-ab8f-c4c32d3dd7e0" +``` +Note that the link to be cloned has references to the original comment and target node, while the sourceNodeId and targetNodeId are the new ids for the copied comment and node. The new node and comment are not part of the model yet. + +## selectionChangeHandler +```js + selectionChangeHandler(data) +``` +The selectionChangeHandler callback is triggered whenever the selection in the canvas changes. The callback contains a JSON object with the following format: +``` +{ + "selection": [ + "id6PXRG57DGIV" + ], + "selectedNodes": [ + { + "id": "id6PXRG57DGIV", + "type": "binding", + "operator_id_ref": "variablefile", + "output_ports": [...], + "input_ports": [], + "label": "DRUG1n", + "description": "", + "image": "", + "x_pos": 96, + "y_pos": 219, + "class_name": "canvas-node", + "decorations": [], + "parameters": [], + "messages": [], + "inputPortsHeight": 0, + "outputPortsHeight": 20, + "height": 75, + "width": 70 + } + ], + "selectedComments": [], + "addedNodes": [ + { + "id": "id6PXRG57DGIV", + "type": "binding", + "operator_id_ref": "variablefile", + "output_ports": [...], + "input_ports": [], + "label": "DRUG1n", + "description": "", + "image": "", + "x_pos": 96, + "y_pos": 219, + "class_name": "canvas-node", + "decorations": [], + "parameters": [], + "messages": [], + "inputPortsHeight": 0, + "outputPortsHeight": 20, + "height": 75, + "width": 70 + } + ], + "addedComments": [], + "deselectedNodes": [ + { + "id": "id2PZSCTRPRIJ", + "type": "execution_node", + "operator_id_ref": "derive", + "output_ports": [...], + "input_ports": [...], + "label": "Na_to_K", + "description": "", + "image": "", + "x_pos": 219.01116943359375, + "y_pos": 162.3754425048828, + "class_name": "canvas-node", + "decorations": [], + "parameters": [], + "messages": [...], + "inputPortsHeight": 20, + "outputPortsHeight": 20, + "height": 75, + "width": 70 + } + ], + "deselectedComments": [ + { + "id": "id42ESQA3VPXB", + "content": " comment 1", + "height": 34, + "width": 128, + "x_pos": 132, + "y_pos": 103, + "class_name": "canvas-comment-1" + } + ], + previousPipelineId: "123-456", + selectedPipelineId: "789-012" +} +``` +- selection: Array with ids of selected nodes and comments +- selectedNodes: Array of selected node objects +- selectedComments: Array of selected comment objects +- addedNodes: Array with node objects that were added to the selection +- addedComments: Array with comment objects that were added to the selection +- deselectedNodes: Array with node objects that were removed from the selection +- deselectedComments: Array with comment objects that were removed from the selection +- previousPipelineId: The ID of the Pipeline for the selected objects prior to the selection action +- selectedPipelineId: The ID of the Pipeline for the newly selected objects + + +## layoutHandler +```js + layoutHandler(data) +``` +This is an optional handler you don't need to implement anything for it unless you want to. The layoutHandler callback, when provided, is called for each node on the canvas. The callback should return a Javascript object whose properties will override the default properties for node layout. The callback is provided with a parameter `data` which is the node object. Your code can look at the node properties and decide which properties it needs to override. This can be used to change the node shape, styling and position and size of node elements like the image, main label etc. + +For more details see: [Customizing Node Layout Properties](/2.7-Customizing-Node-Layout-Properties) + +## actionLabelHandler +```js + actionLabelHandler(action) +``` +This is an optional handler you don't need to implement anything for it unless you want to. This callback allows your code to override the default tooltip text for the `Undo` and `Redo` buttons. + +The `actionLabelHandler` callback, when provided, is called for each action that is performed in common-canvas. The `action` object parameter, passed in to the callback, contains details of the action being performed. This callback should return either a string or null. If a string is returned it will be shown in the tooltip for the `Undo` button in the toolbar preceded by "Undo:" and the string will also appear in the tooltip for the `Redo` button (when appropriate) preceded by "Redo:". If null is returned, common-canvas will display the default text for the `Undo` and `Redo` buttons. \ No newline at end of file diff --git a/guide/2.3-Enabling-node-creation-from-external-object.md b/guide/2.3-Enabling-node-creation-from-external-object.md new file mode 100644 index 0000000000..ddc100633f --- /dev/null +++ b/guide/2.3-Enabling-node-creation-from-external-object.md @@ -0,0 +1,75 @@ +# Dragging object from within the browser +Common canvas supports the ability for an object from the your browser page to be dragged onto the canvas to initiate the creation of a node on the canvas. To do this you need to set the object you want to drag into the canvas to be draggable: + +```html +
+ .... + .... +
+``` +and then specify the on drag behavior like this +```js + onDragStart(ev) { + const evData = { + operation: "addToCanvas", + data: { + editType: "createExternalNode", + field1: "field_val_1", + field2: "field_val_2" + .... + .... + } + }; + ev.dataTransfer.setData("text", JSON.stringify(evData)); + } +``` +where +* operation - is always set to "addToCanvas" +* data - is the object that will be passed to the editActionHandler callback +* editType - this is the type of editing operation. You can set it to anything except any of the reserved settings which are: 'createNode', 'createNodeOnLink', 'createAutoNode' and 'createFromExternalObject'. +* fields - an optional number of fields can be provided that describe the object you are dragging onto the canvas. For example, if it is a data object the fields might describe the data source details. + +After the object has been dropped on the canvas your editActionHandler() callback method will be called with a parameter data object that contains the fields you specified in `data` in the drag data along with three additional fields, called pipelineId, offsetX and offsetY, containing the x,y co-ordinates of where the drop occurred. In your editActionHandler() method you can use the CanvasController API to add a node to the pipeline flow and get common canvas to display it. + +# Dragging object from the desktop or another application +If an object from the desktop or another application is dropped on the canvas your editActionHandler(data) method will be called with the `data` parameter set to an object like this: +```js + { + dataTransfer: , + editType: "createFromExternalObject", + editSource: "canvas", + offsetX: 200, + offsetY: 100, + pipelineId: "1234-5678" + } +``` +Your code can examine the `dataTransfer` object to see what object was dragged onto the canvas and then take appropriate action. + +If you want a new node to appear on the canvas as a result of the object being dropped your code will need to create that node at the point where the drop occurred, using the Canvas Controller API. Here is some sample code that will +* create a new node template based on the "variablefile" node in the palette data +* set the label of the node to be created to the name of the file being dropped +* create a new node on the canvas at the offsetX, offsetY position +* the command will be added to the command-stack so the user can click undo to undo the addition of the node + +`data` is the parameter passed into your `editActionHandler` method. +```js + if (data.editType === "createFromExternalObject") { + const nodeTemplate = canvasController.getPaletteNode("variablefile"); + if (nodeTemplate) { + const convertedTemplate = canvasController.convertNodeTemplate(nodeTemplate); + convertedTemplate.label = data.dataTransfer.files[0].name; + const action = { + editType: "createNode", + nodeTemplate: convertedTemplate, + pipelineId: data.pipelineId, + offsetX: data.offsetX, + offsetY: data.offsetY + }; + canvasController.editActionHandler(action); + } +``` + +Tip: You can optionally instruct common canvas to display a graphic over the canvas as the external object is being dragged over it. To do this you need to specify the [`enableDropZoneOnExternalDrag`](/2.1-Config-Objects#enabledropzoneonexternaldrag) configuration parameter. \ No newline at end of file diff --git a/guide/2.4-Canvas-Controller-API.md b/guide/2.4-Canvas-Controller-API.md new file mode 100644 index 0000000000..f09c8c3a48 --- /dev/null +++ b/guide/2.4-Canvas-Controller-API.md @@ -0,0 +1,944 @@ +# Canvas Controller API + +Your application code can programmatically perform many of the actions that the user can do in the common canvas using the Canvas Controller API. +Note: See this section for differences between [the structure of objects in the API and the schema.](/2.4.3-Object-structure-used-by-API#api-differences-with-schema) + +Also, this section discusses different [techniques for calling the canvas controller API](/2.4.0-Calling-the-Canvas-Controller-API). + +In most cases within the API, the pipelineId parameter is optional. If pipelineId is omitted, the method will default to the pipeline that is currently displayed in the main canvas viewport. + +Warning 1: Do not alter the IDs of objects that currently exist on the canvas. Changing object IDs can cause internal problems, in particular with the command stack. + +Warning 2: When using external pipeline flows, Pipeline IDs must be globally unique identifiers. + +The API provides the following: +## Pipeline Flow methods +```js +// Loads the pipelineFlow document provided into common-canvas and displays it. +// The document must conform to the pipelineFlow schema as documented in the +// elyra-ai pipeline-schemas repo. Documents conforming to older versions may be +// provided but they will be upgraded to the most recent version. +setPipelineFlow(flow) + +// Clears the pipleine flow and displays an empty canvas. +clearPipelineFlow() + +// Returns the current pipelineFlow document in the latest version of the +// pipelineFlow schema as documented in the elyra-ai pipeline-schemas repo. +getPipelineFlow() + +// Returns the current pipelineFlow document ID. +getPipelineFlowId() + +// Returns the ID of the primary pipeline from the pipelineFlow. +getPrimaryPipelineId() + +// Returns the external pipeline flow for the url passed in. The external +// flow must have been loaded through some common canvas action for this +// method to be able to return anything. +getExternalPipelineFlow(url) + +// Returns the internal format of all canvas data stored in memory by +// common-canvas. Nodes, comments and links are returned in the internal +// format. +getCanvasInfo() + +// Returns the IDs of the ancestor pipleline of the pipeline ID passed in. +getAncestorPipelineIds(pipelineId) + +// Removes all styles from nodes, comments and links. See the setObjectsStyle +// and setLinkStyle methods for details on setting styles. +// temporary - is a boolean that indicates whether temporary or permanent +// styles should be removed. +removeAllStyles(temporary) + +// Specifies the new styles for objects that are not highlighted during +// branch highlighting. +// newStyle - is a style specification object. See wiki for details. +setSubdueStyle(newStyle) + +``` + +## Pipeline methods +```js +// Returns the pipeline object for the pipeline Id passed in. +getPipeline(pipelineId) + +// Returns the ID of the pipeline object which is currently on display +// in the canvas. Typically, this is the primary pipeline but will be +// different if the user has navigated into one or more supernodes; in +// which case it will be the ID of the pipeline at the level in the +// supernode hierarchy that is currently on display. +getCurrentPipelineId() + +// Returns truty if the pipeline is external (that is it is part of an +// external pipeline flow). Otherwise, return falsy to indicate the pipeline +// is local. +isPipelineExternal(pipelineId) + +// Returns the flow validation messages for the pipeline ID passed in. +getFlowMessages(pipelineId) + +// Returns a boolean to indicate whether there are any messages of +// includeMsgsType in the pipeline identified by the pipeline ID passed in. +// includeMsgsType - can be either "error" or "warning" +isFlowValid(includeMsgTypes, pipelineId) + +// Rearranges the nodes in the canvas in the direction specified for the +// pipeline ID passed in. +// layoutDirection - can be "horizontal" or "vertical" +autoLayout(layoutDirection, pipelineId) +``` + +## Palette methods +```js +// Loads the palette data as described in the palette schema in +// elyra-ai pipeline-schemas repo. Any version can be loaded and it will be +// upgraded to the latest version. +setPipelineFlowPalette(palette) + +// Clears the palette data from common-canvas. +clearPaletteData() + +// Sets the loading text of the category. If set to a non-empty string the +// category will show an InlineLoading control in the palette category div +// with this text as the label. If set to falsey the palette category +// will display as normal. +setCategoryLoadingText(categoryId, loadingText) + +// Sets the empty text of the category. If set to a non-empty string and the +// category does not have any nodes, the palette will show a warning icon with +// this text as a message under the category title when the category is opened. +// This message will not be displayed if the field is set to falsey or if +// nodetypes are added to the category. +setCategoryEmptyText(categoryId, emptyText) + +// Adds a new node into the palette: +// nodeTypeObj - must conform to the style of node used by the palette as +// described in the palette schema. See objects in nodeTypes array in the +// palette schema: +// https://github.com/elyra-ai/pipeline-schemas/blob/master/common-canvas/palette/palette-v3-schema.json +// category - is the name of the palette category where the node will be +// added. If the category doesn't exist it will be created. +// categoryLabel - Is an optional param. If a new category is created it will +// be displayed with this label. +// categoryDescription - Is an optional param. If a new category is created +// it will be displayed with this description. +// categoryImage - Is an optional param. The image displayed for the category provided as a +// reference to an image or the image itself. +addNodeTypeToPalette(nodeTypeObj, categoryId, categoryLabel, categoryDescription, categoryImage) + +// Adds an array of new node into the palette: +// nodeTypeObjs - an array of nodetypes that must conform to the style of +// nodes used by the palette as described in the palette schema. See objects +// in nodeTypes array in the palette schema: +// https://github.com/elyra-ai/pipeline-schemas/blob/master/common-canvas/palette/palette-v3-schema.json +// category - is the name of the palette category where the node will be +// added. If the category doesn't exist it will be created. +// categoryLabel - is an optional param. If a new category is created it will +// be displayed with this label. +// categoryImage - the image displayed for the category provided as a +// reference to an image or the image itself. +// categoryDescription - Is an optional param. If a new category is created +// it will be displayed with this description. +// categoryImage - Is an optional param. The image displayed for the category provided as a +// reference to an image or the image itself. +addNodeTypesToPalette(nodeTypeObjs, categoryId, categoryLabel, categoryDescription, categoryImage) + +// Removes nodetypes from a palette category +// selObjectIds - an array of object IDs to identify the nodetypes to be +// removed +// categoryId - the ID of teh category from which the nodes will be removed +removeNodesFromPalette(selObjectIds, categoryId) + +// Returns the palette data document which will conform to the latest version +// of the palette schema. +getPaletteData() + +// Returns the palette node identified by the operator ID passed in. +getPaletteNode(operatorId) + +// Returns the palette node identified by the node ID passed in. +getPaletteNodeById(nodeId) + +// Returns the category of the palette node identified by the operator passed in +getCategoryForNode(nodeOpIdRef) + +// Converts a node template from the format use in the palette (that conforms +// to the schema) to the internal node format. +convertNodeTemplate(nodeTemplate) + +// Opens the palette category identified by the category ID passed in. +openPaletteCategory(categoryId) + +// Closes the palette category idetified by the category ID passed in. +closePaletteCategory(categoryId) + +// Opens all the palette categories. +openAllPaletteCategories() + +// Closes all the palette categories. +closeAllPaletteCategories() + +// Returns true or false to indicate whether a palette category is open or not. +isPaletteCategoryOpen(categoryId) +``` + +## Selections methods +```js +// Sets the currently selected objects replacing any current selections. +// newSelection - An array of object IDs for nodes and/or comments +// pipelineId - Optional. The ID of the pipeline where the objects exist. +// Selected objects can only be in one pipeline. If this parameter is omitted +// it is assumed the selections will be for objects in the 'top-level' pipeline +// being displayed. +setSelections(newSelection, pipelineId) + +// Clears all the current selections from the canvas. +clearSelections() + +// Selects all the objects on the canvas. +selectAll() + +// Returns an array of the IDs of the currently selected objects. +getSelectedObjectIds() + +// Returns the currently selected Nodes. +getSelectedNodes() + +// Returns the currently selected Comments. +getSelectedComments() + +// Returns the ID of the pipeline in which the currently selected objects +// exist. Only one pipeline may contain selected objects. +getSelectedPipelineId() + +// Deletes all currently selected objects. +deleteSelectedObjects() + +// Returns true if the currently selected objects are all linked together. +// This is used when deciding to creating a supernode. +areSelectedNodesContiguous() +``` + +## Notification messages methods + +The notification panel is displayed by the user by clicking the notifications icon in the toolbar. Your application can display whatever messages it wants in the notification panel. See the [Notification Messages Specification](/2.4.4-Notification-Message-Specification) documentation for the structure of message objects. The contents of the notification panel can be managed using the methods below: +```js +// Overwrites the array of notification messages shown in the notification +// panel. +// newMessage - An array of messages (see getNotificationMessages) +setNotificationMessages(newMessages) + +// Deletes all notification messages shown in the notification panel. +clearNotificationMessages() + +// Removes the notification messages from the given array of ids +deleteNotificationMessages(ids) + +// Returns the array of current notification messages. If the messageType is +// provided only messages of that type will be returned. If messageType is +// not provided, all messages will be returned. The format of a notification +// message is an object with these fields: +// { +// "id": string (Required), +// "type" : enum, oneOf ["info", "success", "warning", "error"] (Required), +// "callback": function, the callback function when a message is clicked (Required), +// "title": string (Optional), +// "content": string, html, JSX Object (Optional), +// "timestamp": string (Optional), +// "closeMessage": string (Optional) +// } +getNotificationMessages(messageType) + +// Returns the maximum notification message type present in the current set +// of notification messages. For this: ("error" > "warning" > "success" > "info") +getNotificationMessagesMaxType() +``` + +## Node AND comment methods +In common-canvas nodes and comments are collectively known as objects. The following methods may be used to manage either collections of comments or nodes or a mixture of both. +Note: +* See this sections if you are working with [styles.](/2.4.1-Style-Specification) +* See this section if you are working with [decorations.](/2.4.2-Decoration-Specification) +* See this section for differences between [the structure of objects in the API and the schema.](/2.4.3-Object-structure-used-by-API#api-differences-with-schema) +```js +// Moves the objects identified in the data object which must be in the +// pipeline identified by the pipeline ID. +// data - A javascript object like this: +// { +// nodes: [] // An array of node and comment IDs +// offsetX: number // Offset in pixels the objects will move in the X dir +// offsetY: number // Offset in pixels the objects will move in the Y dir +// } +moveObjects(data, pipelineId) + +// Deletes the objects specified in objectIds array. +// objectIds - An array of node and comment IDs +deleteObjects(objectIds, pipelineId) + +// Removes the links to and from the objects specified in the objectIds array. +// objectIds - An array of node and comment IDs +disconnectObjects(objectIds, pipelineId) + +// Deletes the object specified by the id in the pipleine specified by +// pipeline ID. +// @Deprecated Use deleteNode or deleteComment as appropriate instead. +deleteObject(id, pipelineId) + +// Sets the style of the objects specified by pipelineObjectIds to be +// the newStyle which will be either temporary or permanent. +// pipelineObjectIds: This identified the objects to be styles. It is a +// javascript object like this: +// { +// : [ +// , +// +// ], +// : [ +// , +// +// ] +// } +// newStyles - This is a style specification. See the wiki for details. +// temporary - A boolean to indicate if the style is serialized when +// getPipelineFlow() method is called or not. +setObjectsStyle(pipelineObjectIds, newStyle, temporary) + +// Sets the styles of multiple objects at once. +// pipelineObjStyles - Specified the objects and the styles each should be +// set to. It is a javascript array like this: +// [ +// { pipelineId: , objId: , style: }, +// { pipelineId: , objId: , style: }, +// { pipelineId: , objId: , style: } +// ] +// temporary - A boolean to indicate if the styles are serialized when +// getPipelineFlow() method is called or not. +setObjectsMultiStyle(pipelineObjStyles, temporary) +``` +## Node methods +```js +// Retuns an array of nodes for the pipeline specified by the pipelineId. +getNodes(pipelineId) + +// Returns a new node created from the data parameter in the pipeline +// identified by the pipelineId. +// The data parameter must contain: +// nodeTemplate - a node template from the palette. The nodeTemplate +// can be retrieved from the palette using with Canvas +// Controller methods: getPaletteNode or getPaletteNodeById. +// offsetX - the x coordinate of the new node +// offsetY - the y coordinate of the new node +createNode(data, pipelineId) + +// Adds a new node into the pipeline specified by the pipelineId. +addNode(node, pipelineId) + +// Creates a node using the data parameter provided in the pipeline specified +// by pipelineId and adds the command to the command stack (so the user can +// undo/redo the command). This will also cause the beforeEditActionHandler +// and editActionHandler callbacks to be called. +// The data parameter must contain: +// nodeTemplate - a node template from the palette. The nodeTemplate +// can be retrieved from the palette using with Canvas +// Controller methods: getPaletteNode or getPaletteNodeById. +// offsetX - the x coordinate of the new node +// offsetY - the y coordinate of the new node +// +// If pipelineId is omitted the node will be created in the current +// "top-level" pipeline. +createNodeCommand(data, pipelineId) + +// Deletes the node specified. +// nodeId - The ID of the node +// pipelineId - The ID of the pipeline +deleteNode(nodeId, pipelineId) + +// Sets the node properties +// nodeId - The ID of the node +// properties - An object containing properties to be overriden in the node +// pipelineId - The ID of the pipeline +setNodeProperties(nodeId, properties, pipelineId) + +// Sets the node parameters +// nodeId - The ID of the node +// parameters - An array of parameters +// pipelineId - The ID of the pipeline +setNodeParameters(nodeId, parameters, pipelineId) + +// Sets the node UI parameters +// nodeId - The ID of the node +// parameters - An array of UI parameters +// pipelineId - The ID of the pipeline +setNodeUiParameters(nodeId, uiParameters, pipelineId) + +// Sets the node messages +// nodeId - The ID of the node +// messages - An array of messages +// pipelineId - The ID of the pipeline +setNodeMessages(nodeId, messages, pipelineId) + +// Sets a single message on a node +// nodeId - The ID of the node +// message - A message +// pipelineId - The ID of the pipeline +setNodeMessage(nodeId, message, pipelineId) + +// Sets the lable for a node +// nodeId - The ID of the node +// ndeLabel - The label +// pipelineId - The ID of the pipeline +setNodeLabel(nodeId, newLabel, pipelineId) + +// Sets the class name to newClassName of the nodes identified by nodeIds +// array in the pipleine specified by pipeline ID. The class name will be +// applied to the node body path. +setNodesClassName(nodeIds, newClassName, pipelineId) + +// Sets the decorations on a node. The decorations array passed in +// will replace any decorations currently applied to the node. +// nodeId - The ID of the node +// newDecorations - An array of decorations. See Wiki for details. +// pipelineId - The ID of the pipeline +setNodeDecorations(nodeId, newDecorations, pipelineId) + +// Sets the input ports on a node. The inputs array of ports provided will +// replace any input ports for a node. +// nodeId - The ID of the node +// inputs - An array of input port objects. +// pipelineId - The ID of the pipeline +setNodeInputPorts(nodeId, inputs, pipelineId) + +// Sets the output ports on a node. The outputs array of ports provided will +// replace any output ports for a node. +// nodeId - The ID of the node +// outputs - An array of output port objects. +// pipelineId - The ID of the pipeline +setNodeOutputPorts(nodeId, outputs, pipelineId) + +// Sets the decorations of multiple nodes at once. The decorations array +// passed in will replace any decorations currently applied to the nodes. +// pipelineNodeDecorations - Specifies the nodes and their decorations. +// It is a JavaScript array like this: +// [ +// { pipelineId: , nodeId: , decorations: }, +// { pipelineId: , nodeId: , decorations: }, +// { pipelineId: , nodeId: , decorations: } +// ] +setNodesMultiDecorations(pipelineNodeDecorations) + +// Sets the input port label on a node +// nodeId - The ID of the node +// portId - The ID of the input port +// newLabel - The label +// pipelineId - The ID of the pipeline +setInputPortLabel(nodeId, portId, newLabel, pipelineId) + +// Sets the output port label on a node +// nodeId - The ID of the node +// portId - The ID of the output port +// newLabel - The label +// pipelineId - The ID of the pipeline +setOutputPortLabel(nodeId, portId, newLabel, pipelineId) + +// Gets a node +// nodeId - The ID of the node +// pipelineId - The ID of the pipeline +getNode(nodeId, pipelineId) + +// Gets the UI parameters for a node +// nodeId - The ID of the node +// pipelineId - The ID of the pipeline +getNodeUiParameters(nodeId, pipelineId) + +// Gets the supernodes for a pipeline. +// pipelineId - The ID of the pipeline +getSupernodes(pipelineId) + +// Returns supernode ID that has a subflow_ref to the given pipelineId. +getSupernodeObjReferencing(pipelineId) + +// Gets the messages for a node +// nodeId - The ID of the node +// pipelineId - The ID of the pipeline +getNodeMessages(nodeId, pipelineId) + +// Gets the array of input ports for the node or null if the node ID is +// not recognized. +// nodeId - The ID of the node +// pipelineId - The ID of the pipeline +getNodeInputPorts(nodeId, pipelineId) + +// Gets the array of output ports for the node or null if the node ID is +// not recognized. +// nodeId - The ID of the node +// pipelineId - The ID of the pipeline +getNodeOutputPorts(nodeId, pipelineId) + +// Gets a message for a specific control for a node +// nodeId - The ID of the node +// controlName - The control name +// pipelineId - The ID of the pipeline +getNodeMessage(nodeId, controlName, pipelineId) + +// Gets an array of decorations for a node +// nodeId - The ID of the node +// pipelineId - The ID of the pipeline +getNodeDecorations(nodeId, pipelineId) + +// Gets the class name associated with the node specified by nodeId in the +// pipeline specified by pipelineId. +getNodeClassName(nodeId, pipelineId) + +// Gets the style spcification (see Wiki) for a node +// nodeId - The ID of the node +// temporary - A boolean to indicate if the style is serialized when +// getPipelineFlow() method is called or not. +// pipelineId - The ID of the pipeline +getNodeStyle(nodeId, temporary, pipelineId) + +// Returns an array of nodes that are for the branch(es) that the nodes, +// identified by the node IDs passed in, are within. +// nodeIds - An array of node Ids +// pipelineId - The ID of the pipeline where the nodes exist +getBranchNodes(nodeIds, pipelineId) + +// Returns an array of nodes that are upstream from the nodes +// identified by the node IDs passed in. +// nodeIds - An array of node Ids +// pipelineId - The ID of the pipeline where the nodes exist +getUpstreamNodes(nodeIds, pipelineId) + +// Returns an array of nodes that are downstream from the nodes +// identified by the node IDs passed in. +// nodeIds - An array of node Ids +// pipelineId - The ID of the pipeline where the nodes exist +getDownstreamNodes(nodeIds, pipelineId) + +// Returns a boolean to indicate whether the supernode is expanded in place. +// nodeId - The ID of the node +// pipelineId - The ID of the pipeline +isSuperNodeExpandedInPlace(nodeId, pipelineId) + +// Sets the label, for the node identified, to edit mode, provided the node +// label is editable. This allows the user to edite the label text. +setNodeLabelEditingMode(nodeId, pipelineId) + +// Sets the decoration label, for the decoration in the node identified, to edit +// mode, provided the node label is editable. This allows the user to edit the +// label text. +setNodeDecorationLabelEditingMode(decId, nodeId, pipelineId) +``` +The format of the message object is described in [Pipeline Flow UI schema](https://github.com/elyra-ai/pipeline-schemas/blob/master/common-pipeline/pipeline-flow/pipeline-flow-ui-v1-schema.json) +## Comment methods +```js +// Returns the comments from the pipeline. +// pipelineId - The ID of the pipeline +getComments(pipelineId) + +// Returns a comment from the pipeline. +// comId - The ID of the comment +// pipelineId - The ID of the pipeline +getComment(comId, pipelineId) + +// Returns a position object which indicates the position of where a new +// comment should be placed in a situation where the mouse position cannot be +// used (e.g. the toolbar button was clicked). +// pipelineId - The ID of the pipeline +getNewCommentPosition(pipelineId) + +// Creates a comment for the pipeline. +// source - Input data +// pipelineId - The ID of the pipeline +createComment(source, pipelineId) + +// Adds a comment to the pipeline. +// data - the data describing the comment +// pipelineId - The ID of the pipeline +addComment(data, pipelineId) + +// Edits a comment with the data. +// data - the comment +// pipelineId - The ID of the pipeline +editComment(data, pipelineId) + +// Sets the properties in the comment identified by the commentId. The +// commentProperties is an object containing one or more properties that will +// replace the corresponding properties in the comment. For example: if +// commentProperties is { x_pos: 50, y_pos: 70 } the comment +// will be set to that position. +setCommentProperties(commentId, commentProperties, pipelineId) + +// Sets the class name to newClassName of the comments identified by commentIds +// array in the pipleine specified by pipeline ID. The class name will be +// applied to the comment body path. +setCommentsClassName(commentIds, newClassName, pipelineId) + +// Deletes a comment +// comId - The ID of the comment +// pipelineId - The ID of the pipeline +deleteComment(comId, pipelineId) + +// Gets the class name associated with the comment specified by commentId in the +// pipeline specified by pipelineId. +getCommentClassName(commentId, pipelineId) + +// Gets the style spcification (see Wiki) for a comment +// commentId - The ID of the node +// temporary - A boolean to indicate if the style is serialized when +// getPipelineFlow() method is called or not. +// pipelineId - The ID of the pipeline +getCommentStyle(commentId, temporary, pipelineId) + +// Hides all comments on the canvas. +hideComments() + +// Shows all comments on the canvas - if they were previously hiding. +showComments() + +// Returns true if comments are currently hiding. +isHidingComments() + +// Sets the comment identified, to edit mode so the user can +// edit the comment. +setCommentEditingMode(commentId, pipelineId) + +``` +## Link methods +```js +// Gets a link +// linkId - The ID of the link +// pipelineId - The ID of the pipeline +getLink(linkId, pipelineId) + +// Returns an array of link objects for the pipelineId passed in. +// pipelineId - The ID of the pipeline +getLinks(pipelineId) + +// Sets the properties in the link identified by the linkId. The +// linkProperties is an object containing one or more properties that will +// replace the corresponding properties in the link. For exam`ple: if +// linkProperties is { trgNodeId: "123", trgNodePortId: "789" } the target +// node ID will be set to "123" and the target port ID set to "789". +setLinkProperties(linkId, linkProperties, pipelineId) + +// Sets the source properties in the data link identified by the linkId. The +// srcNodeId and srcNodePortId will be set to the values provided. If +// srcNodePortId is set to null the current srcNodePortId will be removed +// from the link. Also, if the link has a srcPos property (because its +// source end is detached) that will be removed. +setNodeDataLinkSrcInfo(linkId, srcNodeId, srcNodePortId, pipelineId) + +// Sets the target properties in the data link identified by the linkId. The +// trgNodeId and trgNodePortId will be set to the values provided. If +// trgNodePortId is set to null the current trgNodePortId will be removed +// from the link. Also, if the link has a trgPos property (because its +// target end is detached) that will be removed. +setNodeDataLinkTrgInfo(linkId, trgNodeId, trgNodePortId, pipelineId) + +// Gets a node to node data link +// srcNodeId - The ID of the source node +// srcNodePortId - The ID of the source node port +// trgNodeId - The ID of the target node +// trgNodePortId - The ID of the target node port +// pipelineId - The ID of the pipeline +getNodeDataLinkFromInfo(srcNodeId, srcNodePortId, trgNodeId, trgNodePortId, pipelineId) + +// Gets a comment to node link +// id1 - The ID of the comment +// id2 - The ID of the node +// pipelineId - The ID of the pipeline +getCommentLinkFromInfo(id1, id2, pipelineId) + +// Gets a node to node association link +// id1 - The ID of one of the node +// id2 - The ID of one of the node +// pipelineId - The ID of the pipeline +getNodeAssocLinkFromInfo(id1, id2, pipelineId) + +// Adds links to a pipeline +// linkList - An array of links +// pipelineId - The ID of the pipeline +addLinks(linkList, pipelineId) + +// Deletes a link +// source - An array of links +// pipelineId - The ID of the pipeline +deleteLink(link, pipelineId) + +// Creates node to node links +// data - Data describing the links +// pipelineId - The ID of the pipeline +createNodeLinks(data, pipelineId) + +// Creates comment links +// data - Data describing the links +// pipelineId - The ID of the pipeline +createCommentLinks(data, pipelineId) + +// Sets the class name to newClassName of the links identified by linkIds +// array in the pipleine specified by pipeline ID. The class name will be +// applied to the link line path. +setLinksClassName(linkIds, newClassName, pipelineId) + +// Sets the style of the links specified by pipelineLinkIds to be +// the newStyle which will be either temporary or permanent. +// pipelineLinkIds - This identifies the objects to be styles. It is a +// javascript object like this: +// { +// : [ +// , +// +// ], +// : [ +// , +// +// ] +// } +// newStyle - This is a style specification. See the wiki for details. +// temporary - A boolean to indicate if the style is serialized when +// getPipelineFlow() method is called or not. +setLinksStyle(pipelineLinkIds, newStyle, temporary) + +// Sets the styles of multiple links at once. +// pipelineObjStyles - Specified the links and the styles each should be +// set to. It is a javascript array like this: +// [ +// { pipelineId: , objId: , style: }, +// { pipelineId: , objId: , style: }, +// { pipelineId: , objId: , style: } +// ] +// temporary - A boolean to indicate if the styles are serialized when +// getPipelineFlow() method is called or not. +setLinksMultiStyle(pipelineObjStyles, temporary) + +// Gets the class name associated with the link specified by linkId in the +// pipeline specified by pipelineId. +getLinkClassName(linkId, pipelineId) + +// Returns the style specification for a link. +// linkIds - An array of links +// temporary - A boolean to indicate if the style is serialized when +// getPipelineFlow() method is called or not. +// pipelineId - The ID of the pipeline +getLinkStyle(linkId, temporary, pipelineId) + +// Sets the decorations on a link. The decorations array passed in +// will replace any decorations currently applied to the link. +// linkId - The ID of the link +// newDecorations - An array of decorations. See Wiki for details. +// pipelineId - The ID of the pipeline +setLinkDecorations(linkId, newDecorations, pipelineId) + +// Sets the decorations of multiple links at once. The decorations array +// passed in will replace any decorations currently applied to the links. +// pipelineLinkDecorations - Specifies the links and their decorations. +// It is a javascript array like this: +// [ +// { pipelineId: , linkId: , decorations: }, +// { pipelineId: , linkId: , decorations: }, +// { pipelineId: , linkId: , decorations: } +// ] +setLinksMultiDecorations(pipelineLinkDecorations) + +// Gets an array of decorations for a link +// linkId - The ID of the link +// pipelineId - The ID of the pipeline +getLinkDecorations(linkId, pipelineId) + +// Sets the decoration label, for the decoration in the link identified, to edit +// mode provided the link label is editable. This allows the user to edit the +// label text. +setLinkDecorationLabelEditingMode(decId, linkId, pipelineId) +``` + +## Breadcrumbs methods +```js +// Returns the current array of breadcrumbs. There will one breadcrumb object +// for each level of supernode that the user has navigated into. This array +// can be used to display breadcrumbs to the user to show where they are +// within the navigation hierarchy within common canvas. +getBreadcrumbs() + +// Returns the last breadcrumb which represents the level with supernode +// hierarchy that the user has currently navigated to. +getCurrentBreadcrumb() +``` + +## Branch Highlight methods +```js +// Highlights the branch(s) (both upstream and downstream) from the node +// IDs passed in and returns the highlighted object Ids. +// nodeIds - An array of node Ids +// pipelineId - The ID of the pipeline +highlightBranch(nodeIds, pipelineId) + +// Highlights the upstream nodes from the node IDs passed in +// and returns the returns the highlighted object Ids. +// nodeIds - An array of node Ids +// pipelineId - The ID of the pipeline +highlightUpstream(nodeIds, pipelineId) + +// Highlights the downstream nodes from the node IDs passed in +// and returns highlighted object Ids. +// nodeIds - An array of node Ids +// pipelineId - The ID of the pipeline +highlightDownstream(nodeIds, pipelineId) +``` +## Operational methods +These are general purpose methods for operation of the common-canvas components: + +### Logging methods +```js +// Returns a Boolean to indicate whether canvas logging is switched on or off. +getLoggingState() + +// Sets canvas logging based on the Boolean passed in. +setLoggingState(state) +``` + +### Palette methods +```js +// Opens the palette +openPalette() + +// Closes the palette +closePalette() + +// Returns true if the palette is currently open +isPaletteOpen() +``` + +### Context menu methods +```js +// Opens the context menu +openContextMenu(menuDef) + +// Closes the context menu +closeContextMenu() +``` + +### Notification Panel methods +```js +// Opens the notification panel +openNotificationPanel() + +// Closes the notification panel +closeNotificationPanel() + +// Either opens or closes the notifictaion panel based on its current status +toggleNotificationPanel() +``` + +### Right Flyout methods +```js +// Returns a boolean to indicate if the right flyout is open or not +isRightFlyoutOpen() +``` + +### Top panel methods +```js +// Returns a boolean to indicate if the top pnel is open or not +isTopPanelOpen() +``` + +### Bottom panel methods +```js +// Returns a boolean to indicate if the bottom panel is open or not +isBottomPanelOpen() + +// Sets the height of the bottom panel in pixels. This can be called +// immediately after the CanvasController has been created, if the bottom +// panel should be displayed at a specific height when it first opens. +setBottomPanelHeight(height) +``` + +### Canvas/pipeline navigation methods +```js +// Displays a pipeline (identified by the pipelineId passed in). This must be +// one of the pipelines referenced by the current set of breadcrumbs. It +// cannot be used to open a new pipeline outside the current set of breadcruumbs. +displaySubPipeline(pipelineId) + +// Displays a pipeline for the supernode (identifid by the supernodeId +// parameter) in the pipeline (identifid by the pipelineId parameter). For +// correct breadcrumb generation this pipeline should be the one in the last +// of the current set of breadcrumbs. That is, the pipeline currently shown +// "full page" in the canvas. +displaySubPipelineForSupernode(supernodeId, pipelineId) + +// Displays full-page the previous pipeline from the one currently being displayed +displayPreviousPipeline() +``` + +### Zoom methods +```js +// Centers the canvas contents and zooms in +zoomIn() + +// Centers the canvas contents and zooms out +zoomOut() + +// Zooms the canvas contents to fit within the viewport +zoomToFit() + +// Changes the zoom amounts for the canvas. This method does not alter the +// pipelineFlow document. zoomObject is an object with three fields: +// x: Is the horizontal translate amount which is a number indicating the +// pixel amount to move. Negative left and positive right +// y: Is the vertical translate amount which is a number indicating the +// pixel amount to move. Negative up and positive down. +// k: is the scale amount which is a number greater than 0 where 1 is the +// default scale size. +zoomTo(zoomObject) + +// Increments the translation of the canvas by the x and y increment +// amounts. The optional animateTime parameter can be provided to animate the +// movement of the canvas. It is a time for the animation in milliseconds. +// If omitted the movement happens immediately. +translateBy(x, y, animateTime) + +// Returns the current zoom object for the currently displayed canvas or null +// if the canvas is not yet rendered for the first time. +getZoom() + +// Returns a zoom object required to pan the objects (nodes and/or comments +// and/or links) identified by the objectIds array to 'reveal' the objects +// in the viewport. Returns null if no nodes, comments or links can be found +// using the IDs passed in. Note: node, comment and link IDs must be unique. +// The zoom object returned can be provided to the CanvasController.zoomTo() +// method to perform the zoom/pan action. +// If the xPos and yPos parameters are provided it will return a zoom object +// to pan the center of the objects specified, to a location where, xPos +// is the percentage of the viewport width and yPos is the percentage of the +// viewport height. So if you want the center of the objects specified to be +// in the center of the viewport set xPos to 50 and yPos to 50. +// If the xPos and yPos parameters are undefined (omitted) and all the +// objects are currently fully within the canvas viewport, this method will +// return null. This can be used to detect whether the objects are fully +// visible or not. +// If the xPos and yPos parameters are undefined and the objects are outside +// the viewport, a zoom object will be returned that can be used to zoom them +// so they appear at the nearest side of the viewport to where they are +// currently positioned. +// The zoom object retuurned has three fields: +// x: Is the horizontal translate amount which is a number indicating the +// pixel amount to move. Negative left and positive right +// y: Is the vertical translate amount which is a number indicating the +// pixel amount to move. Negative up and positive down. +// k: is the scale amount which is a number greater than 0 where 1 is the +// default scale size. +// Parameters: +// objectIds - An array of nodes and/or comment IDs. +// xPos - Optional. Can be set to percentage offset of the viewport width. +// yPos - Optional. Can be set to percentage offset of the viewport height. +getZoomToReveal(objectIds, xPos, yPos) + +// Clears any saved zoom values stored in local storage. This means +// newly opened flows will appear with the default zoom. This method +// is only applicable when the `enableSaveZoom` config parameter is +// set to "LocalStorage". +clearSavedZoomValues() + +``` diff --git a/guide/2.4.0-Calling-the-Canvas-Controller-API.md b/guide/2.4.0-Calling-the-Canvas-Controller-API.md new file mode 100644 index 0000000000..cebad931a4 --- /dev/null +++ b/guide/2.4.0-Calling-the-Canvas-Controller-API.md @@ -0,0 +1,39 @@ + +## Techniques for calling Canvas Controller API + +There are a couple of techniques you can use to update the object model using the Canvas Controller. + +### Incremental Updates +Once the pipeline flow is loaded into common-canvas using: +``` +canvasController.setPipelineFlow(pFlow) +``` +the pipeline flow is held in memory “inside” the object model of common-canvas. Thereafter, you can update that in-memory pipeline flow by calling canvas controller API such as: `deleteComment` or `createNode`, etc. The canvas controller will directly update the in-memory object model based on these calls, and it will cause the canvas view to refresh to reflect the change your code requested with the API call. + +It’s best to use the above technique when making small incremental changes to the object model often based on user requests. + +### Extensive Updates + +An alternative to making these individual API calls is to use `canvasController.getPipelineFlow(pFlow)` +which will return the full contents of the current state of the object model into a variable e.g. +``` +const currentPF = this.canvasController.getPipelineFlow(); +``` +You can then make changes to the pipeline flow using you own code. +For example: + +``` +// Wipe out all the comments in the zeroth pipeline +currentPF.pipelines[0].comments = []; +``` + +and then set the pipeline flow back into common canvas with this: + +``` +this.canvasController.setPipelineFlow(currentPF); +``` + +Note: the updating of the pipeline flow (currentPF) is entirely done by your code — there is no API to help you — so you have to understand the [pipeline flow schema](https://github.com/elyra-ai/pipeline-schemas/blob/main/common-pipeline/pipeline-flow/pipeline-flow-v3-schema.json) to understand what to do. + +This technique is probably most useful when doing extensive changes to the pipeline flow where you don’t want each change to cause a refresh of the canvas. This is because the only refresh of the canvas will be when you do the final `setPipelineFlow()` call. + diff --git a/guide/2.4.1-Style-Specification.md b/guide/2.4.1-Style-Specification.md new file mode 100644 index 0000000000..e16875da8c --- /dev/null +++ b/guide/2.4.1-Style-Specification.md @@ -0,0 +1,64 @@ +There are multiple was to specify the styles for the objects common-canvas displays: +* A class name can be provided for nodes either within the pipelineFlow document or +* The common-canvas default styes can be overriden within your CSS or SCSS file + +For more precise styling of objects the style specification object can be used to provide a number of styles to common canvas to set the inline styles on numerous elements of an object. For example, a node is made up of: a selection outline; a node body (rectangle); an image, a label etc. + +Style specifications may be applied to common-canvas objects using the following [Canvas Controller](/2.4-Canvas-Controller-API) methods: +```js +setObjectsStyle() +setObjectsMultiStyle() +setLinksStyle() +setLinksMultiStyle() +setSubdueStyle() +``` +and may be retrieved for objects using: +```js +getNodeStyle() +getCommentStyle() +getLinkStyle() +``` + +The style spec for a node can set the styles for all these elements in one shot. Here is a template of a style spec for a node: +```js +{ + body: { default: , hover: }, + image: { default: }, + label: { default: }, + selection_outline: { default: } +} + ``` +And here is a real example: +```js +{ + body: { + default: "fill: coral; stroke: red;", + hover: "fill: cornflowerblue; stroke: blue;" + } +}; +``` +Here is a template for styling a comment: +```js +{ + body: { default: , hover: }, + text: { default: }, + selection_outline: { default: }, +} + ``` +And here is a template for styling a link: +```js +{ + line: { default: , hover: } +} + ``` +* **** - is a string containing any CSS code that can be added inline to an SVG object. That means, for example, you need to use fill and stroke for colors etc It is recommended NOT to change the sizes of text fonts. + +The CSS will be applied to the element of the object specified, either as the default inline style or as the style when the pointer hovers over the object. + +When a hover style is applied to a graphical element it is applied in addition to the default style so there is no need to repeat styles in the hover because they will augment the default style. + +Because styles are applied as in-line styles they will override any styles provided in your application's CSS and specified to common-canvas through the class_name field of canvas objects. + +If the is specified as null the current style will be removed from the specified element of the object. + +Finally, styles can be applied to your nodes, comments and links as either temporary or permanent styles by specifying the `temporary` boolean in the API methods. A temporary style is just applied for the duration of the session and are not persisted. You should use `temporary=true` styles that represent transient attributes of an object that should not be persisted in the pipelineFlow document. Use `temporary=false` styles for styles that you want to persist in the pipelineFlow document. diff --git a/guide/2.4.2-Decoration-Specification.md b/guide/2.4.2-Decoration-Specification.md new file mode 100644 index 0000000000..8aa7cbdbf6 --- /dev/null +++ b/guide/2.4.2-Decoration-Specification.md @@ -0,0 +1,195 @@ +# Decorations +Your application can add Decorations -- additional icons, text labels, shapes or JSX objects -- to nodes or links in the canvas to indicate special status or attributes of the node or link. Decorations can be static (for display only) or interactive (a hotspot) so the user can click them to initiate some action. + +# Adding Decorations +Decorations can be added to the nodes and/or links in four different ways: + +1. By using the following `CanvasController` methods: + ```js + setNodeDecorations(nodeId, newDecorations, pipelineId) + setNodesMultiDecorations(pipelineNodeDecorations) + setLinkDecorations(linkId, newDecorations, pipelineId) + setLinksMultiDecorations(pipelineLinkDecorations) + ``` + and can be retrieved using these `CanvasController` methods: + ```js + getNodeDecorations(nodeId, pipelineId) + getLinkDecorations(linkId, pipelineId) + ``` + See the [CanvasController API documentation](/2.4-Canvas-Controller-API) for more details. + +2. Node decorations can be specified in the [nodeLayout object](/2.1-Config-Objects#enablenodelayout) in the canvas config. Decorations specified in this way are applied to all nodes on the canvas. + +3. Decorations can be applied to, and retrieved from, nodes or links in the pipelineFlow in the `app_data.ui_data` section for the node or link. (Note: JSX objects are not supported in the pipelineFlow document). + +4. Decorations can be returned in the layout information returned from the [layoutHandler](/2.2-Common-Canvas-callbacks#layouthandler) CommonCanvas callback method. + +# Specification + +The decoration specification used by these methods and the pipelineFlow is a JavaScript object with these possible properties: + +These properties are applicable to an image decoration: +```js + { + id: , + image: , + position: , + distance: + x_pos: , + y_pos: , + width: , + height: , + hotspot: , + class_name: , + outline: , + tooltip: , + temporary: + } +``` +These properties are applicable to a label decoration: +```js + { + id: , + label: , + label_editable: , + label_align: , + label_single_line: , + label_max_characters: , + label_allow_return_key: , + position: , + distance: + x_pos: , + y_pos: , + width: , + height: , + hotspot: , + class_name: , + tooltip: , + temporary: + } +``` +These properties are applicable to a shape decoration: +```js + { + id: , + path: , + position: , + distance: + x_pos: , + y_pos: , + width: , + height: , + hotspot: , + class_name: , + tooltip: , + temporary: + } +``` +These properties are applicable to a JSX decoration: +```js + { + id: , + jsx: , + position: , + distance: + x_pos: , + y_pos: , + width: , + height: , + hotspot: , + class_name: , + tooltip: , + } +``` + +where: + +#### **id** +A unique ID for the decoration within the context of the node or link to which the decorator is attached. + +#### **image** +A reference to an image to display for the decoration. If an image is specified the image is displayed within an outline rectangle unless `outline` is set to false. The image should be a reference to your image like: "/images/decorations/zoom-in_32.svg". Do not set label or path or jsx when this field is set. + +#### **path** +An SVG shape that is displayed using this string as it's SVG path. eg. "M 0 0 L 10 10 -10 10 Z" could be specified to draw a triangle. Do not set image or label or jsx when this field is set. + +#### **jsx** +A JSX object that is is displayed at the specified decoration location. Do not set image or path or label when this field is set. Note JSX decorations are not supported in the pipelineFlow document. + +#### **label** +A text string that is displayed at the specified decoration location. Do not set image or path or jsx when this field is set. + +#### **label_editable** +A boolean that defaults to `false`. When set to `true`, if the mouse pointer is hovered over the label an edit icon is displayed next to the label which, when clicked, opens the label for editing. The label can also for double clicked to go to edit mode. + +When editing is completed (by clicking outside the text area) an `editDecorationLabel` action is executed which results in calls to first the `beforeEditActionHandler` and then the `editActionHandler` callbacks. + +#### **label_align** +Can be either "center" or "left". When set to center the label will be centered on the point defined by the `position`, `distance`, `x_pos` and `y_pos` properties. + +#### **label_single_line** +A boolean that defaults to `false`. When set to `true` the label is displayed on a single line and is truncated at the width of the label (specified in the `width` property for the decoration) and does not word wrap. If it is truncated an ellipsis (...) is displayed at the end of the truncated text. + +If this property is set to `false`, long label text is displayed over a number of lines with word wrapping being controlled by the `width` set for the decoration. If the text extends beyond a second line an ellipsis (..) is displayed at the end of the second line. This is controlled by the `-webkit-line-clamp: 2;` CSS property. You can override this if you want the ellipsis to be displayed on a different line. + +Note: For both single and multi-line labels you may need to set the `height` property for the decoration to show the text fully. + +#### **label_max_characters** +A number or null. Defaults to null. If set to a number the label will be restricted to that number of characters. If the label in the pipeline flow document is longer than the max number it will be displayed but when it is edited the user will not be able to do anything except delete characters until the label is shorter than the max number. If this property is set to `null` or omitted an unlimited number of characters may be entered by the user. + +#### **label_allow_return_key** +A boolean that defaults to `false`. When `false`, if the user presses the return key nothing will happen. This means multi-line labels will only word-wrap at the `width` of the decorator. Preventing newline insertion is useful if the label text appears elsewhere in the UI which is not able to show text with newline characters. When set to `"save"`, if the user presses the return key, the editing will be completed and the label saved -- this is the equivalent of clicking on the canvas background to complete the edit. If set to `true`, a new line character will be inserted in the label when the user presses return. + +#### **position** +This is the anchor point to which the decoration is attached. For a node, this can be one of these 9 enumerated values: +``` + "topLeft", "topCenter", "topRight", + "middleLeft", "middleCenter", "middleRight", + "bottomLeft", "bottomCenter", "bottomRight". +``` +If omitted it will default to "topLeft". + +For a link, this can be one of these 3 enumerated values: +``` + "source" + "middle" + "target" +``` +`source` will position the decoration at the start point of the line and `target` will position it at the end point of the line. If omitted it will default to `middle`. + +#### **distance** +A number of pixels. This is only applicable when the decoration is for a link line and then, only with straight connecting lines. That is, for node to node connections when the config property `enableLinkType` is set to `"straight"`. When specified, it will move the anchor point for the decoration to a new position along the connecting line relative to the initial position specified in the decoration's `position` property. A positive number moves the decoration along the line from the starting position towards the target of the link and a negative number backwards towards the source of the link. For example, if a straight link decoration has `position` of `source` and a `distance` of `20` the decoration's anchor point will be 20 pixels along the link line from the source (start) point of the line. After the `distance` value has been applied to the anchor point of the decoration, any `x_pos` and `y_pos` adjustment will be applied to fine tune the decoration's final position. + +#### **x_pos** +This is the number of pixels horizontally from the anchor point that the decoration is positioned. It can be positive or negative. If omitted it takes a default value from the [node layout properties](/2.7-Customizing-Node-Layout-Properties#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default). x_pos is not applicable if you specify an SVG path using the `path` field, because the SVG path can be used to position the shape. + +#### **y_pos** +This is the number of pixels vertically from the anchor point that the decoration is positioned. It can be positive or negative. If omitted it takes a default value from the [node layout properties](/2.7-Customizing-Node-Layout-Properties#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default). y_pos is not applicable if you specify an SVG path using the `path` field, because the SVG path can be used to position the shape. + +#### **width** +This is the width for the decorator in pixels. For an image decorator, it is the width of the rectangle surrounding the image. For a label decorator it is the width allowed for display of the label text. If omitted it takes a default value from the [node layout properties](/2.7-Customizing-Node-Layout-Properties#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default) for Node decorations and from the canvas layout properties for Link properties. + +#### **height** +This is the height for the decorator in pixels. For an image decorator, it is the height of the rectangle surrounding the image. For a label decorator it is the height allowed for display of the label text. If omitted it takes a default value from the [node layout properties](/2.7-Customizing-Node-Layout-Properties#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default) for Node decorations and from the canvas layout properties for Link properties. + +#### **hotspot** +A Boolean. It defaults to false. When set to true the decoration becomes clickable and when it is clicked the [decorationCallbackHandler](/2.2-Common-Canvas-callbacks#decorationactionhandler) is called with the ID of the decoration passed as a parameter. + +#### **class_name** +An optional class that will be applied to the decoration. You can add a style rule that references that class in your CSS to style the decoration and override the default styles. + +#### **outline** +A Boolean. It defaults to true. When a decoration is specified with an image field the image is typically displayed with a outline rectangle around it and with an offset within the rectangle to improve presentation. If `outline` is set to `false` the outline rectangle is **not** displayed and the image is displayed without any offset from its specified `x_pos` and `y_pos`. + +#### **tooltip** +A String. When specified, the string will be shown in a tooltip when the pointer is hovered over the decoration. No tip will be displayed if the `tooltip` property is omitted. Note: for decoration tooltips to be displayed on the canvas, the `decorations` property of the `tipConfig` object in the canvas config must be set to true (which is its default setting). + +#### **temporary** +A Boolean. It defaults to false. When set to true the decoration object will _not_ be saved in the pipelineFlow document returned by the `CanvasController.getPipelineFlow()` method. Typically, this should be set to `true` when adding decorations programmatically to the nodes and links on the canvas. + +### Notes: + +1. Using `x_pos` and `y_pos`, decorations can be displayed outside the node boundary. +2. If no image or label or path is provided, the default decoration is a rectangle displayed with the class_name provided. +3. You can specify as many decorations as you want by providing extra entries in the decorations array. +4. Images and labels are positioned differently. For images, the position defined for the decoration is the top left corner of the image. For labels it is anchor point for the label which is the base line of the string in the vertical direction and is dependent on the text-anchor CSS property applied to the text. So if you apply the `text-anchor: middle` CSS property to the label in the style related to class_name the label will be centered on the point calculated for the position of the decoration. \ No newline at end of file diff --git a/guide/2.4.3-Object-structure-used-by-API.md b/guide/2.4.3-Object-structure-used-by-API.md new file mode 100644 index 0000000000..48828c0c70 --- /dev/null +++ b/guide/2.4.3-Object-structure-used-by-API.md @@ -0,0 +1,49 @@ +# API differences with schema +Because historically common-canvas has had to deal with different external flow definitions, there are some differences between the nodes, comments and links that the CanvasController API handles internally and those specified in the pipelineFlow schema. As follows: + +## Object structure + For the API methods that involve nodes, comments and links, those objects are passed in and out by the API in their internal formats rather than the formats defined in the schema files. + +The internal structure is a somewhat flattened version of that in the schema definition. That means, properties that are in `.app_data.ui_data` are flattened out and appear as properties in the `` itself. So for example a node that conforms to the schema might look like this: +```js + { + id: "1234", + op: "select", + ... + app_data : { + ui_data: { + label: "Selection node", + image: "/images/select.svg", + description: "A node for selection" + ... + }, + other_data: { + prop1: "Something interesting" + } + } + } +``` +whereas when it is passed through the API it looks like this: +```js + { + id: "1234", + op: "select", + label: "Selection node", + image: "/images/select.svg", + description: "A node for selection" + ... + app_data : { + other_data: { + prop1: "Something interesting" + } + } + } +``` +Note that, any properties in `app_data`, other than `ui_data`, are preserved in the internal format. So in the example, `app_data.other_data` in the schema format is preserved in the internal format. + +## Links handing in the API +The other difference between the API and the schema formats is with links. + +In the pipeline flow schema, links are typically defined as properties within another object, for example, a node to node link is defined within a `links` array inside the `inputs` field of the target node and contains references to the `node id` and `port` of the source node. Also, links from comments to nodes are stored as an array in the comment object. + +However, in the API and internally in common-canvas, links are treated as a top level object; that is, there is an array of links stored internally which can be manipulated using the API methods. Each link has a unique ID. Consequently, links can be retrieved from the API by their ID field and properties of the links can be updated again by identifying the links using their ID. If you do not specify an ID for links in your pipelineFlow document a unique global ID will be generated for each link when the pipeline flow is loaded. \ No newline at end of file diff --git a/guide/2.4.4-Notification-Message-Specification.md b/guide/2.4.4-Notification-Message-Specification.md new file mode 100644 index 0000000000..fe2f986238 --- /dev/null +++ b/guide/2.4.4-Notification-Message-Specification.md @@ -0,0 +1,30 @@ +### Notification Message structure. + +Notification messages are displayed in the notification panel which the user can access by clicking the Notifications icon in the toolbar. Each notification message is described by a simple JavaScript object like this: +```js + { + id: , + type: , + title: , + content: , + timestamp: , + callback: , + closeMessage: +} +``` +where: + * **id** (string, required): this is a unique ID assigned to the notification message. This is passed as a parameter in the callback (see below) and is used to reference messages when deleting them through the `CanvasController` API. + +* **type** (string, required): this must be one of four values: "info", "success", "warning", or "error". If `type` is null, empty string, or undefined, the message type will be "unspecified". + +* **title** (string or JSX object): the title of the notification message + +* **content** (string or JSX object): the body of the notification message + +* **callback** (function): an optional callback function that will be called when the notification message is clicked. Callback function is called with one parameter, `id` + +* **timestamp** (string or JSX object): an optional timestamp that will be rendered in a separate section with different formatting, if passed in + +* **closeMessage** (string or React object): an optional message that, if passed in, will display as clickable. Clicking on this will delete this individual message. If none is passed in, no delete option will be shown. + + diff --git a/guide/2.4.5-Programmatically-creating-new-canvas-nodes.md b/guide/2.4.5-Programmatically-creating-new-canvas-nodes.md new file mode 100644 index 0000000000..89dc8a5928 --- /dev/null +++ b/guide/2.4.5-Programmatically-creating-new-canvas-nodes.md @@ -0,0 +1,64 @@ +## Introduction + +The host application code can programmatically create nodes on the canvas in two ways: + +* By calling CanvasController API methods to create and add the node to the canvas. + +* Creating and adding a node to the Pipeline Flow document + + +## Creating and adding a node to the Canvas Controller API + +The following code will programmatically add a node to the canvas. These commands will update the common-canvas object model directly and will not be added to the command stack so the user will not be able to `undo` / `redo` these actions. Also, the `beforeEditActionHandler` and `editActionHandler` callbacks will not be called for these actions. + +First you can get a node template from the canvas by calling +```js + const template = canvasController.getPaletteNode("sort"); +``` +where the parameter is the operation (`op` field) for the palette node. Alternatively, you can retrieve a node template using this method: +```js + const template = canvasController.getPaletteNodeById(nodeId) +``` +which returns the node template based on the node ID. This can be useful if you have supernodes in your palette because supernodes do not have an `op` field. After creating the node template your code can alter fields (for example, the label) within the template. If you do change any fields be careful because common-canvas doesn't do any error checking on your fields. + +Next you create the node: +```js + const newNode = canvasController.createNode({ + nodeTemplate: template, + offsetX: 200, + offsetY: 400 +}); +``` +This will work correctly for regular nodes, and also supernodes, that have been pulled from the palette. + +Next you add the node object to the canvas. +```js + canvasController.addNode(newNode); +``` +The node will appear at the offsetX, offseY position within the coordinate system for the canvas. + +### If command stack is needed + +This method allows the host application to create a node, or supernode, from a palette template object by creating and executing a command which will be added to the command stack (so the user can `undo` / `redo` it) and will also cause the `beforeEditActionHandler` and `editActionHandler` callbacks to be called. + + +First your code retrieves a node template from the palette as described above and then calls this method: +```js + const data = { + nodeTemplate: template, + offsetX: 200, + offsetY: 400 + }; + + canvasController.createNodeCommand(data, pipelineId) +``` + +Note: If `pipelineId` is omitted the node will be created in the current "top-level" pipeline. + +## Creating and adding a node using Pipeline Flow document + +This approach works by your code adding one or more JSON objects directly to the pipeline flow object, either before the pipeline flow document is loaded into common-canvas using `CanvasController.setPipelineFlow(pFlow)`, or afterwards by retrieving the pipeline flow object from common-canvas using `CanvasController.getPipelineFlow()` and then updating the nodes array of whichever pipeline you want to modify. This would require your code to navigate to the `pipeline` object (that you want to update) in the `pipelines` array of the pipeline flow and then add the node object to the `nodes` array in the pipeline object. + +After updating the pipeline flow object your code would need to reload it into common-canvas using `CanvasController.setPipelineFlow(pFlow)`. + +To use this approach you would need a good understanding of the [pipeline flow schema](https://github.com/elyra-ai/pipeline-schemas/blob/412d70176953ed9ac2e6a03f7135b09b7565fc5d/common-pipeline/pipeline-flow/pipeline-flow-v3-schema.json) and [pipeline flow UI schema](https://github.com/elyra-ai/pipeline-schemas/blob/412d70176953ed9ac2e6a03f7135b09b7565fc5d/common-pipeline/pipeline-flow/pipeline-flow-ui-v3-schema.json). diff --git a/guide/2.4.6-Constructing-a-read-only-or-locked-canvas.md b/guide/2.4.6-Constructing-a-read-only-or-locked-canvas.md new file mode 100644 index 0000000000..bd42ffd309 --- /dev/null +++ b/guide/2.4.6-Constructing-a-read-only-or-locked-canvas.md @@ -0,0 +1,56 @@ +# Introduction + +Some host applications need to display flows that cannot be edited by the user. This might be because the flow artifact is currently being edited by another user (locked) or because the user does not have authority to edit the flow (read-only) or some other reason. We'll use the term 'read-only' below to refer to both locked and read-only canvases. + +There are many aspects of common-canvas components that need to considered for a read-only canvas. Since common-canvas is highly customizable it is not possible for the common-canvas code to manage components of the canvas that have been customized by the host application. For example, if the host app code added tools to the toolbar, common-canvas does not know whether those tools should be disabled when displaying a read-only canvas or not. So the host application code will need to manage that. Let's look at each element of common-canvas and see what needs to be done. + +# General Config +There is one main canvas configuration property that will change the common-canvas behavior to implement a read-only canvas. This is [`enableEditingActions`](/2.1-Config-Objects#enableeditingactions) which defaults to true and needs to be set to `false` for read-only canvases. The sections below will cover what effect this will have on the different components of common-canvas and what you need to do for any customizations you have made. + +# Canvas +Setting `enableEditingActions` to false will prevent nodes and comments (and detachable links) from being moved relative to one another. It will also prevent new links from being created and prevent text (like comments or node labels) from being edited. + +With `enableEditingActions` set to false, the canvas can still be panned (left/right and up/down) and also zoomed in and out. Nodes, comments and links can still be clicked (to select) and right clicked (to display a context menu) and double clicked (usually to show properties). If you implemented any behavior for these interactions, using the [`clickActionHandler`](/2.2-Common-Canvas-callbacks#clickactionhandler), you'll need to review what your code is doing and make sure it is appropriate when a read-only canvas is being displayed. + +Common-canvas allows objects from outside the canvas to be dropped onto the canvas to create a new node. For example, a file can be dragged from the operating system desktop onto the canvas to create a data node. With `enableEditingActions` set to false, the drag/drop gesture (which common-canvas cannot prevent) will prevent a new node from being created. It is recommended you switch the [`enableDropZoneOnExternalDrag`](/2.1-Config-Objects#enabledropzoneonexternaldrag) config property to false when displaying a read-only canvas. This will prevent a 'drop zone' graphic from appearing over the canvas when the object is dragged over the top of the canvas. + +Some applications need to show a tag (called a 'state tag') over the canvas to emphasize the 'read-only' or 'locked' state of the canvas. This can be displayed using the [`enableStateTag`](/2.1-Config-Objects#enablestatetag) canvas config property. The tooltip of the 'state tag' can be provided by implementing the [`tipHandler`](/2.2-Common-Canvas-callbacks#tiphandler) callback function. + +Since there are numerous possible styles for nodes and links when displaying a read-only canvas, it isn't possible for common-canvas to style the canvas objects appropriately for all different designs. You will need to override any styles for nodes and links to fit your design. To help with this common-canvas sets a class called `config-edit-actions-false` on the top-level div that contains the common-canvas components. You can use this to build specific selectors in your CSS/SCSS that will override the styles applied to nodes and links by default. For example, to override node icon and label colors you could specify the following in your SCSS file: +``` + .editing-actions-false { + .d3-node-group { + & .d3-node-label, + & svg path { + color: $disabled-02; + stroke: $disabled-02; + fill: $disabled-03; + } + } + } +``` + +# Context menu +Setting `enableEditingActions` to false will prevent any options, that would edit the canvas objects, from being displayed in the common-canvas default context menu. For example, `Delete` will not show up in the context menu. See the [`enableEditingActions` documentation](/2.1-Config-Objects#enableeditingactions) for a list of options that are disabled. + +Your application code can add your own options to the context menu by implementing the [`contextMenuHandler`](/2.2-Common-Canvas-callbacks#contextmenuhandler) callback function. If you have added your own options, you should review your code and ensure options that might change the canvas objects are not added to the context menu when you are displaying a read-only canvas. + +Note: The common-canvas default menu, passed as the second parameter to the `contextMenuHandler` callback, will still contain editing options. This means, if your code relies on them for some reason, (for example for calculating the position of your added options) your application code will still work OK. The editing options will be removed after your code returns the array of items that describe the desired menu from the `contextMenuHandler` callback. + +# Toolbar +The toolbar can display buttons for standard common-canvas actions and also buttons for any application-specific actions added by your code. Setting `enableEditingActions` to false will cause buttons for any standard common-canvas actions, that edit the canvas objects, to be disabled regardless of the setting for the `enable` property for each action. See the [`enableEditingActions` documentation](/2.1-Config-Objects#enableeditingactions) for a list of actions that are disabled. + +You should review any application-specific action buttons you have added to the toolbar and decide if they need to be disabled or removed from the toolbar when displaying a read-only canvas. + +# Keyboard +Common-canvas supports a number of keyboard shortcuts. Setting `enableEditingActions` to false, disables any keyboard shortcuts that edit the canvas objects (such as Delete). See the [`enableEditingActions` documentation](/2.1-Config-Objects#enableeditingactions) for a list of keyboard shortcuts that are disabled. + +# Palette +Setting `enableEditingActions` to false: +* prevents node templates from being dragged from the palette and +* disables the double-click action on node templates which automatically adds a node to the canvas. + +You should decide if your application should display the palette when displaying a read-only canvas or not. The palette can be hidden by setting the canvas config property [`enablePaletteLayout`](/2.1-Config-Objects#enablepalettelayout) to "None". + +# Test Harness: Sample Read-Only application +The test harness contains a sample application called "Read-Only" which shows how a read-only canvas can be built using the `enableEditingActions` config option. In the application there are three toolbar buttons which can be used to navigate between Editable state, Read-Only state and Locked state. You can review the `.jsx` and `.scss` files in the [application code](https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/src/client/components/custom-canvases/read-only) to see how the application is implemented and styled. diff --git a/guide/2.5-Command-Stack-API.md b/guide/2.5-Command-Stack-API.md new file mode 100644 index 0000000000..b132f3826e --- /dev/null +++ b/guide/2.5-Command-Stack-API.md @@ -0,0 +1,65 @@ +# Command Stack API + + The CommandStack is a JavaScript class that provides the functionality to support do/undo/redo of commands. It maintains an internal stack of commands with a cursor that moves up and down when commands are undone or redone. Commands are also Javascript classes that implement a simple interface. + +The CommandStack API allows application code to programmatically add commands to the command stack. You can get the Command Stack by calling the `CanvasController.getCommandStack()` method. The CommandStack API provides the following methods: + +```js + do(command) - push the command onto the command stack and then invoke command.do() + undo() - pop a command from the command stack and then invoke command.undo() + redo() - push last undo command onto the command stack and then invoke command.redo() + canUndo() - returns true if there is a command on the command stack. + canRedo() - returns true if there is an undo command that can be redo. + clearCommandStack() + getUndoCommand() - returns the next command to be undone or null. + getRedoCommand() - returns the next command to be redone or null. +``` + +Each commands that is added to the command stack is a Javascript class that need to implement these methods: + +```js + constructor() + do() + undo() + redo() +``` +constructor() - Initial setup +do() - Performs all actions necessary to execute the command +undo() - Performs all actions necessary to reverse the actions performed in do() +redo() - Performs all actions necessary to re-execute the command. For some commands this is the same as do() but others it is different. + + + Here is some sample code that shows how a create-node command might be written: + +```js + export default class CreateNodeAction extends Action { + constructor(data) { + super(data); + this.newNode = createNode(data); + } + + do() { + ObjectModel.addNode(this.newNode); + } + + undo() { + ObjectModel.removeNode(this.newNode.id); + } + + redo() { + ObjectModel.addNode(this.newNode); + } + } +``` + + Here is an example of using the CommandStack API to create a command action and push it on the stack: + +```js + const command = new CreateNodeAction(data); + CommandStack.do(command); +``` + + When using CommonCanvas, the canvas-controller creates an instance of the command stack. CommonCanvas provides command objects for each of the commands that are performed by the user, such as: create node, delete comment, link nodes together, etc. Common canvas also provides undo/redo options in its default context menu, on the toolbar and via keystrokes ctrl+z (undo) and ctrl+shift+z (redo). You can implement your own undo and redo UI if required using the API. + + + diff --git a/guide/2.6-Flow-Validation-API.md b/guide/2.6-Flow-Validation-API.md new file mode 100644 index 0000000000..2a0b940a7a --- /dev/null +++ b/guide/2.6-Flow-Validation-API.md @@ -0,0 +1,62 @@ +# Flow Validation API + + The Flow Validation API allows application code to programmatically validate the nodes in the flow against it's property values. The API can be invoked after setting the Canvas Controller pipeline flow, when opening a new flow, or associated with a canvas context menu item. To use the Flow Validation API import the FlowValidation object fro common-canvas: +``` +import { FlowValidation } from "@elyra/canvas"; +``` +then call the API on the object, for example: +``` +FlowValidation.validateFlow( ... ); +``` + +The Flow Validation object provides the following API: + +``` +validateFlow(canvasController, parameterDataCallback, setNodeMessagesCallback, includeMsgTypes) + canvasController - an instance of the canvas controller + parameterDataCallback – function to get the parameter data or form data for a node + setNodeMessagesCallback – function to set the validation messages for a node. (optional) + includeMsgTypes - array[strings] Return invalid only if messages are found of types contained + in the array. If not specified then any message type causes invalid return. (optional) + return - boolean If flow is valid returns true, otherwise returns false. +``` +where the two callbacks are defined as follows: +``` +parameterDataCallback(nodeId) + nodeId – string node Id. + function must return this object: + { + type: “parameterDef” | “form”, + data: Json_object + } + +/* The setNodeMessagesCallback is optional and only useful if not using internal object model. +setNodeMessagesCallback(nodeId, messages) + nodeId – string node Id. + an array of message objects generated from the validation of the node. +``` + +The validateFlow() API will traverse the current flow and for each node invoke the parameterDataCallback() to get with a form data JSON or a parameterDef JSON. It will validate the JSON for the node and store any messages in the node objects within the model. The setNodeMessagesCallback() function will be called with all the messages generated for the node. This is only useful if the application is not using the internal object model. +The format of the message object is described in [Pipeline Flow UI schema](https://github.com/elyra-ai/wdp-pipeline-schemas/blob/master/common-pipeline/pipeline-flow/pipeline-flow-ui-v1-schema.json) + +Here is an example of using the FlowValidation API to validate a flow on opening: + +``` +import { CanvasController, FlowValidation } from "@elyra/canvas"; + +getNodeForm(nodeId) { + const parameterDef = getParameterDefJSON(nodeId); + return { type: "parameterDef", data: parameterDef }; +} + +setNodeMessages(nodeId, messages) { + // code to persist messages in a store in addition to the internal model. +} + +openCanvas(canvasJson) { + const canvasController = new CanvasController(); + canvasController.setPipelineFlow(canvasJson); + FlowValidation.validateFlow(canvasController, this.getNodeForm, this.setNodeMessages); +} + +``` diff --git a/guide/2.7-Customizing-Node-Layout-Properties.md b/guide/2.7-Customizing-Node-Layout-Properties.md new file mode 100644 index 0000000000..5bb144645c --- /dev/null +++ b/guide/2.7-Customizing-Node-Layout-Properties.md @@ -0,0 +1,375 @@ +## Node layout properties +Node layout properties define how all the elements of a node are displayed such as: the position and size of the icon image; the position of the main label; even the shape of the node itself! You can change just about anything to do with the way the nodes appear in your canvas. So you can get a very different looking canvas to suit your needs. + +There are two possible sets of node layout properties provided by common-canvas, these are controlled by the `enableNodeFormatType` canvas configuration property which can be set to either "Horizontal" or "Vertical". "Horizontal" will display a node with an image and the label to the right of the image. "Vertical" will display the node with the label underneath the image. + +## Default values for node layout properties +The possible node layout properties are shown below with the values they have when `enableNodeFormatType = "Horizontal"`. You can see the values for both sets of properties by looking at the [layout-dimensions.js program](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/common-canvas/src/object-model/layout-dimensions.js) + +``` +// Default node sizes. The height might be overridden for nodes with more ports +// than will fit in the default size. +defaultNodeWidth: 160, +defaultNodeHeight: 40, + +// A space separated list of classes that will be added to the group +// DOM element for the node. +className: "", + +// Default node shape. Can be "rectangle" or "port-arcs" +nodeShape: "port-arcs", + +// SVG path strings to define the shape of your node and its +// selection highlighting. If set to null the paths will be set by default +// based on the nodeShape setting. +bodyPath: null, +selectionPath: null, + +// Display image +imageDisplay: true, + +// Image dimensions +imageWidth: 26, +imageHeight: 26, + +// Image position +imagePosition: "topLeft", +imagePosX: 6, +imagePosY: 7, + +// Label dimensions +labelWidth: 112, +labelHeight: 19, + +// Label position +labelPosition: "topLeft", +labelPosX: 36, +labelPosY: 12, + +// Label appearance +labelEditable: false, +labelAlign: "left", // can be "left" or "center" +labelSingleLine: true, // false allow multi-line labels +labelOutline: false, +labelMaxCharacters: null, // null allows unlimited characters +labelAllowReturnKey: false, // true allows line feed to be inserted into label, "save" to make the return key save the label. + +// An array of decorations to be applied to the node. For details see: +// /2.4.2-Decoration-Specification +// These are added to the node at run time and will not be saved into +// the pipeline flow. +decorations: [], + +// Positions and dimensions for 9 enumerated default decorator positions. +// decoratorWidth and decoratorHeight are the dimensions of the outline +// rectangle and decoratorPadding is the padding for the image within the +// outline rectangle. +decoratorTopY: 2, +decoratorMiddleY: -8, +decoratorBottomY: -18, + +decoratorLeftX: 2, +decoratorCenterX: -8, +decoratorRightX: -30, + +// Width, height and padding for image decorators +decoratorWidth: 16, +decoratorHeight: 16, +decoratorPadding: 2, + +// Width and height for label decorators +decoratorLabelWidth: 80, +decoratorLabelHeight: 30, + +// Display drop shadow under and round the nodes +dropShadow: true, + +// The gap between a node and its selection highlight rectangle +nodeHighlightGap: 1, + +// The size of the node sizing area that extends around the node, over +// which the mouse pointer will change to the sizing arrows. +nodeSizingArea: 10, + +// Error indicator dimensions +errorPosition: "topLeft", +errorXPos: 24, +errorYPos: 5, +errorWidth: 10.5, +errorHeight: 10.5, + +// When sizing a supernode this decides the size of the corner area for +// diagonal sizing. +nodeCornerResizeArea: 10, + +// What point to draw the data links from and to when enableLinkType is set +// to "Straight". Possible values are "image_center" or "node_center". +drawNodeLinkLineFromTo: "node_center", + +// What point to draw the comment to node link line to. Possible values +// are "image_center" or "node_center". +drawCommentLinkLineTo: "node_center", + +// This is the size of the horizontal line protruding from the +// port on the source node when drawing an elbow or straight connection line. +minInitialLine: 30, + +// For the elbow connection type with nodes with multiple output ports, +// this is used to increment the minInitialLine so that connection lines +// do not overlap each other when they turn up or down after the elbow. +minInitialLineIncrement: 8, + +// This is the minimum size of the horizontal line entering the +// target port on the target node when drawing an Elbow connection line. +minFinalLine: 30, + +// Display input ports. +inputPortDisplay: true, + +// Object for input port can be "circle" or "image". +inputPortObject: "circle", + +// If input port object is "image" use this image. +inputPortImage: "", + +// If input port dimensions for "image". +inputPortWidth: 12, +inputPortHeight: 12, + +// Position of left single input port. Multiple input ports will be +// automatically positioned with the Y coordinate being overriden. These +// values are an offset from the top left corner of the node outline. +// Used when linkDirection is "LeftRight". +inputPortLeftPosX: 0, +inputPortLeftPosY: 20, + +// Position of top single input port. Multiple input ports will be +// automatically positioned with the X coordinate being overriden. These +// values are an offset from the top left corner of the node outline. +// Used when linkDirection is "TopBottom". +inputPortTopPosX: 80, +inputPortTopPosY: 0, + +// Position of bottom single input port. Multiple input ports will be +// automatically positioned with the X coordinate being overriden. These +// values are an offset from the bottom left corner of the node outline. +// Used when linkDirection is "BottomTop". +inputPortBottomPosX: 80, +inputPortBottomPosY: 0, + +// The 'guide' is the object drawn at the mouse position as a new line +// is being dragged outwards. +// Object for input port guide can be "circle" or "image". +inputPortGuideObject: "circle", + +// If input port guide object is "image" use this image. +inputPortGuideImage: "", + +// Display output ports. +outputPortDisplay: true, + +// Object for output port can be "circle" or "image". +outputPortObject: "circle", + +// If output port object is "image" use this image. +outputPortImage: "", + +// Output port dimensions for "image". +outputPortWidth: 12, +outputPortHeight: 12, + +// Position of right single output port. Multiple input ports will be +// automatically positioned with the Y coordinate being overriden. These +// values are an offset from the top right corner of the node outline. +// Used when linkDirection is "LeftRight". +outputPortRightPosition: "topRight", +outputPortRightPosX: 0, +outputPortRightPosY: 20, + +// Position of top single output port. Multiple input ports will be +// automatically positioned with the X coordinate being overriden. These +// values are an offset from the top left corner of the node outline. +// Used when linkDirection is "BottomTop". +outputPortTopPosX: 80, +outputPortTopPosY: 0, + +// Position of bottom single output port. Multiple input ports will be +// automatically positioned with the X coordinate being overriden. These +// values are an offset from the bottom left corner of the node outline. +// Used when linkDirection is "TopBottom". +outputPortBottomPosX: 80, +outputPortBottomPosY: 0, + +// The 'guide' is the object drawn at the mouse position as a new line +// is being dragged outwards. +// Object for output port guide can be "circle" or "image". +outputPortGuideObject: "circle", + +// If output port guide object is "image" use this image. +outputPortGuideImage: "", + +// Radius of the either the input or output ports when they are set to "circle" +portRadius: 3, + +// Size of an offset above and below the set of port arcs. +portArcOffset: 3, + +// Radius of an imaginary circle around the port. This controls the +// spacing of ports and the size of port arcs when nodeShape is set to +// port-arcs. +portArcRadius: 6, + +// Spacing between the port arcs around the ports. +portArcSpacing: 3, + +// Position of the context toolbar relative to the node. Some adjustment +// will be made to account for the width of the toolbar. +contextToolbarPosition: "topRight", + +// Display of vertical ellipsis to show context menu +ellipsisDisplay: true, +ellipsisPosition: "topLeft", +ellipsisWidth: 10, +ellipsisHeight: 22, +ellipsisPosX: 145, +ellipsisPosY: 9, +ellipsisHoverAreaPadding: 2 + +``` +### Positioning objects +If you have nodes of varying sizes or if you have enabled re-sizeable nodes, by setting the canvas config property `enableResizableNodes` to true, it is important to note the following. + +All coordinate positions for elements are based on one of nine anchor positions around the node: +``` + "topLeft", "topCenter", "topRight", + "middleLeft", "middleCenter", "middleRight", + "bottomLeft", "bottomCenter", "bottomRight". +``` + +The PosX and PosY properties for each element is an offset from the associated anchor position where PosX is the number of pixels **to the right** of the anchor position and PosY is a number of pixels **down from** the anchor position. Negative values can be provided to specify an offset **to the left** and **up from** the anchor position. The default anchor position for all elements is `topLeft`. By the way, the top left corner of the node is also the point that the node will be positioned at based on its `x_pos` and `y_pos` fields in the pipelineFlow document. + +For example, these settings: +``` + { + imagePosition: "middleCenter", + imagePosX: -10, + imagePosY: -10, + imageWidth: 20, + imageHeight: 20 + } +}; +``` +would position the image 10 pixels left and 10 pixels above the very center of the node. Since the image is 20 x 20 pixels this would position the center of the image at the center of the node. If you have enabled re-sizeable nodes, this would keep the image centrally positioned while the node is being resized by the user. + +Elements like the node image and vertical ellipsis are positioned based on the top left corner of that element. Text is positioned based on the top left corner of its containing `
`. + +The values for `bodyPath` and `selectionPath` must be [SVG path strings](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths) which describe how to draw the node body shape and its selection highlight shape. For example, the following would draw a triangular node body and a triangular selection outline 5 pixels away from it: + +```js + bodyPath: " M 0 0 L 70 35 0 70 Z", + selectionPath: "M -5 -5 L 75 35 -5 75 Z", +``` + +## Overriding the default node layout properties +There are a couple of ways to do this depending on your needs. First, if you just want to change the appearance of **all** nodes on your canvas you can specify the `enableNodeLayout` configuration parameter in the [main canvas configuration object](/2.1-Config-Objects#config-object). The properties from this object will replace any properties in the default set, which was chosen based on the settings of `enableNodeFormatType`. So you don't need to provide all of the properties; just the ones you want to replace. + +Let's say you want your nodes to be displayed as ellipses. You could provide the following settings in `enableNodeLayout` in the canvas config: +```js +const canvasConfig = { + enableNodeLayout: { + bodyPath: " M 0 30 Q 0 0 60 0 Q 120 0 120 30 Q 120 60 60 60 Q 0 60 0 30 Z", + selectionPath: "M -5 30 Q -5 -5 60 -5 Q 125 -5 125 30 Q 125 65 60 65 Q -5 65 -5 30 Z", + defaultNodeWidth: 120, + defaultNodeHeight: 60, + imageWidth: 30, + imageHeight: 30, + imagePosX: 20, + imagePosY: 10, + labelEditable: true, + labelPosX: 60, + labelPosY: 37, + labelWidth: 90, + labelHeight: 17, // Should match the font size specified in css + padding + ellipsisDisplay: true, + ellipsisPosX: 100, + ellipsisPosY: 20, + portPosY: 30 + } +}; +``` + +## Customizing individual nodes or categories of nodes +If you want each node, or category of nodes, to have a different layout based on some criteria you can use the second method for overriding the node layout properties. This uses the [layoutHandler callback method](/2.2-Common-Canvas-callbacks#layouthandler). When you specify this callback method to common canvas, it will be called for each node on the canvas, during initialization and, occasionally, at other times. + +The method should return a simple JavaScript object that contains any node layout properties you want to override from the defaults and the ones specified in the `enableNodeLayout` field in the canvas config. This is an important point: there are three levels of properties provided where each overrides the previous set: +1. First we take the full default set of node layout properties based on the value for `enableNodeFormatType`. +2. Then we override these with the properties from the `enableNodeLayout` field in the canvas config object, if any are provided. +3. Finally we override the combined set with any properties from the object returned from the `layoutHandler` method if one is specified. + +The callback is provided with a `data` parameter which is the node object from the pipelineFlow so your code can examine the node object and return node layout properties as appropriate. + +Note: The `layoutHandler` callback is called while the canvas is being displayed, therefore it must return very quickly each time it is called otherwise your canvas display speed will be slowed down. + +Here is a simple example of a `layoutHandler` callback method which will override the width of the node based on the width of the main label for any node where the node's `op` field is set to `Sort`: +```js +layoutHandler(data) { + let customNodeLayout = {}; + if (data.op === "Sort") { + const labLen = data.label ? data.label.length : 0; + const width = (labLen * 9) + 30; // Allow 9 pixels for each character and a bit extra for padding + customNodeLayout = { + defaultNodeWidth: width // Override default width with calculated width + }; + } + return customNodeLayout; +``` +OK, it's not a very complicated example but hopefully you get the message :) + +In the test harness, you can see an example application that use the [layoutHandler callback method](/2.2-Common-Canvas-callbacks#layouthandler). In the test harness: +1. Open the Common Canvas side panel (click the hamburger icon) +2. Select the `Explain` sample application + +You will see the nodes have different shapes and colors based on their type. +You can examine the [Explain sample app code](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/client/components/custom-canvases/explain/explain-canvas.jsx) to see how it works. This involves these parts: + +1. [This line](https://github.com/elyra-ai/canvas/blob/64af90b1f8a1179478f3ea32749681b851d897a4/canvas_modules/harness/src/client/components/custom-canvases/explain/explain-canvas.jsx#L36) sets the `enableNodeFormatType` in the canvas config to "Vertical". This will set all of the node layout properties to their defaults for "Vertical" nodes. +2. [This line](https://github.com/elyra-ai/canvas/blob/64af90b1f8a1179478f3ea32749681b851d897a4/canvas_modules/harness/src/client/components/custom-canvases/explain/explain-canvas.jsx#L37) will override the default node layout properties with a few different values which apply to all nodes. +3. [The layout handler](https://github.com/elyra-ai/canvas/blob/64af90b1f8a1179478f3ea32749681b851d897a4/canvas_modules/harness/src/client/components/custom-canvases/explain/explain-canvas.jsx#L145) will override layout properties on a node by node basis. It calls some utility functions to translate data retrieved from the node to the appropriate layout properties. The returned node layout properties contains an array of decorations that are used to display data values from the node. +4. [This line](https://github.com/elyra-ai/canvas/blob/64af90b1f8a1179478f3ea32749681b851d897a4/canvas_modules/harness/src/client/components/custom-canvases/explain/explain-canvas.jsx#L192) specifies the `layoutHandler` to the `` object. + +## Customizing node colors and styles + +The DOM elements that make up a node can be customized using CSS styles. This is done by assigning a class name to the group `` element that is the container for all the node elements. The class can be applied to the group object is a number of different ways: +1. By specifying it in the `app_data.ui_data.class_name` field of the node in the pipeline flow document that is provided to common-canvas using `CanvasController.setPipelineFlow(pFlow)` +2. By specifying it using the following API methods: + * CanvasController.setNodeProperties(nodeId, properties, pipelineId) + * CanvasController.setNodesClassName(nodeIds, newClassName, pipelineId) +3. By specifying a class name in the `className` field of the node layout properties in the canvas config. Like this +``` +const canvasConfig = { + enableNodeLayout: { + className: "my-node-class" + } +}; +``` +4. By specifying a class name in the `className` field of the node layout properties returned from the `layoutHandler`. + + +You can see the [svg-canvas-d3.scss file](https://github.com/elyra-ai/canvas/blob/main/canvas_modules/common-canvas/src/common-canvas/svg-canvas-d3.scss) for full details about what elements in the node can be styled but here are a list of some basic parts of the node: + +| Element | DOM Element | Class Name | +|-----------------------|-------------------|------------------------------| +| Group | `` | d3-node-group | +| --> Body Shape | `` | d3-node-body-outline | +| --> Selection Outline | `` | d3-node-selection-highlight | +| --> Label Container | `` | d3-foreign-object-node-label | +| -----> Label | `
` | d3-node-label | + +So for example if you want the node body (the rectangle) to be colored orange you would provide a class name to the group element using one of the techniques mentioned above and then put this in you CSS: + +``` +.my-node-class .d3-node-body-outline { + fill: orange; +} +``` +Note: You can use the [`enableParentClass`](/2.1-Config-Objects#enableparentclass) canvas config field to make you CSS rulesets specific so your styles are picked up in preference to the common-canvas default styles. diff --git a/guide/2.8-Context-Menu-Wrapper-Documentation.md b/guide/2.8-Context-Menu-Wrapper-Documentation.md new file mode 100644 index 0000000000..22b15d92d5 --- /dev/null +++ b/guide/2.8-Context-Menu-Wrapper-Documentation.md @@ -0,0 +1,64 @@ +# Context Menu Wrapper + +The context menu in common-canvas can be used in your application by importing the `ContextMenuWrapper` React component. Aside from providing a standard context menu to allow users to select different actions, this context menu also allows for configuration of submenus as a menu item, as well as a visual dividers. + +# Getting started with Context Menu +## Step 1: Import Context Menu Wrapper +To use Context Menu Wrapper in your React application you need to import the `ContextMenuWrapper` React component from the common-canvas library. It's recommended to use All Components if common-canvas is also being imported, otherwise use ContextMenuWrapper only option. + +**All Components** +```js + import {ContextMenuWrapper} from "@elyra/canvas"; +``` + +**ContextMenuWrapper only** +```js + import ContextMenuWrapper from "@elyra/canvas/dist/lib/context-menu"; +``` + +## Step 2: Pass in the correct props +* **contextMenuDef** `array` (required): an array of menu item objects consisting of action and label. You can also pass in a divider item. + +```js + const menuDef = [ + { action: ACTION.BUILD, label: "Build" }, + { action: ACTION.EXTEND, label: "Extend" }, + { action: ACTION.CLEAR, label: "Clear" }, + { divider: true }, + { action: ACTION.SCORE, label: "Score" }, + ]; + +``` +* **containingDivId** `string` (required): the id of the element that the context menu will be absolutely positioned inside. typically, the page element is used. +* **contextMenuPos** `object` (required): the position of the context menu within the containing div. +```js + const menuPos = { x: 500 , y: 300 }; +``` + +* **contextMenuActionHandler** `func` (required): this handler is where context menu actions are defined. +```js + contextMenuActionHandler(action) { + switch (action) { + case "BUILD": + break; + case "EXTEND": + break; + default: + } + } +``` +* **closeContextMenu** `func` (required): this handler will be called when the context menu is closed. +* **stopPropagation** `bool` (optional): this is optional and only for very specific, uncommon use cases. When this flag is set, if a user clicks outside the context menu, the event will not bubble to parent elements, preventing parent event handlers from being called. + +## Example +```js + const contextMenuWrapper = ( + + ); +``` diff --git a/guide/2.9-External-Subflows-support.md b/guide/2.9-External-Subflows-support.md new file mode 100644 index 0000000000..46cedb73bc --- /dev/null +++ b/guide/2.9-External-Subflows-support.md @@ -0,0 +1,71 @@ +# Introduction + +The pipeline flow schema describes two ways of storing a sub-flow pipelines for a supernode: local or external. Local sub-flows are stored within the pipeline flow document whereas external pipelines are stored in a separate pipeline flow document (usually as the primary pipeline in that pipeline flow). The supernode that references an external pipeline contains a `url` property (in `.subflow_ref.url`) and a `pipeline ID` property (in `.subflow_ref.pipeline_id_ref`) to identify the external pipeline flow and the pipeline within it. + +Common-canvas supports external pipelines but the host application UI code needs to manage the storage and retrieval of any external pipeline flows. To do this the app UI code needs to: +* Manage the storage of newly created external pipeline flows. +* Respond to calls from common-canvas to provide the external pipeline flow(s) when requested. +* Respond to call from common-canvas when a local pipeline is changed to external or an external is changed to local. + +Common-canvas supports lazy loading of external pipeline flows so they will only be requested from your code when the user performs some gesture that requires the pipeline (from within the external pipeline flow) to be displayed. + +## Creating an external sub-flow +When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true the default common-canvas context menu will include a `Create External Supernode` option when a set of objects are selected from which a super node can be created. + +When the `Create External Supernode` option is clicked the `createSuperNodeExternal` action is executed. + +If your application doesn't use the default context menu you can define your own context menu (returned from `contextMenuHandler`) to contain an option which maps to the `createSuperNodeExternal` action. See the section on the [contextMenuHandler](/2.2-Common-Canvas-callbacks#contextmenuhandler) for details on how to do this. + +When the `createSuperNodeExternal` action is executed, the `beforeEditActionHandler` callback is called before the external sub-flow is created. The `beforeEditActionHandler` is called where the first parameter `data` has two properties `externalUrl` and `externalPipelineFlowId` which will both be set to empty string. Your code must set these to whatever values you want for the url and pipeline flow ID. The url will be assigned to the `subflow_ref.url` property of the supernode that is being created. The pipeline flow ID will be assigned to the newly created pipeline flow. + +Your code must return the `data` parameter from the `beforeEditActionHandler` callback if you want the action to proceed and create the sub-flow. If you need to do any asynchronous activity at this point see the documentation on the [beforeEditActionHanlder](/2.2-Common-Canvas-callbacks#beforeeditactionhandler) for details on how to do that. + + +When the sub-flow has been created common-canvas will call the `editActionHandler` callback. In this callback you can, if you wish, retrieve the pipeline flow document that has been created internally in common-canvas using `CanvasController.getExternalPipelineFlow(url)`. Your code can then save it to your repository. Alternatively, you can wait until some later time, like perhaps during an auto-save, to retrieve and store the pipeline flow externally in your repository. + +## Loading an external sub-flow +When the main pipeline flow, displayed by common-canvas, contains a super node that references an external sub-flow it may need to be loaded whenever the user performs a gesture that causes it to be displayed - like opening it 'in-place'. An external sub-flow may also need to be loaded if the top-level pipeline being displayed has a supernode, that refers to an external pipeline, that is already expanded in-place in the saved pipeline flow JSON document being displayed. So, actions that can cause the external pipeline to be loaded are: + +* loadPipelineFlow +* expandSuperNodeInPlace +* displaySubPipeline +* convertSuperNodeExternalToLocal +* deconstructSuperNode + +When any of these actions are performed common-canvas will call the `beforeEditActionHandler` callback with the data parameter as the first parameter. The data object will have the following properties: +* editType - The name of the action being performed. +* externalPipelineFlowLoad - This is a boolean which indicates whether the pipeline flow needs to be provided by your code. +* externalUrl - This is the string which identifies the external pipeline flow document. +* externalPipelineId - This is the ID of the pipeline being loaded +* externalPipelineFlow - If `externalPipelineFlowLoad` if true this will be undefined. Otherwise it will be contain the previously loaded external pipeline flow. + +You need to implement the `beforeEditActionHandler` so that: +* when the actions above are being performed and externalPipelineFlowLoad is true, you retrieve the external pipeline flow from your repository +* you then assign it to the `externalPipelineFlow` property of the data object +* you then return the data object from the callback. + +Your code must return the `data` parameter from the `beforeEditActionHandler` callback if you want the action to proceed and load the external pipeline flow. If you need to do any asynchronous activity at this point see the documentation on the [beforeEditActionHanlder](/2.2-Common-Canvas-callbacks#beforeeditactionhandler) for details on how to do that. + +## Converting a local supernode to an external supernode +When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true, and a local supernode is right clicked, the default common-canvas context menu will include a `Convert local to external` option. This will execute the `convertSuperNodeLocalToExternal` action. + +The `convertSuperNodeLocalToExternal` action is similar to the `createSuperNodeExternal` action in that a new external pipeline flow is being created. Consequently, you can follow the instructions in the [Creating an external sub-flow](/2.9-External-Subflows-support#creating-an-external-sub-flow) section for providing the appropriate properties of the `data` object in the `beforeEditActionHandler` and `editActionHandler` callbacks. + +## Converting an external supernode to a local supernode +When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true, and an external supernode is right clicked, the default common-canvas context menu will include a `Convert external to local` option. This will execute the `convertSuperNodeExternalToLocal` action. + +The `convertSuperNodeExternalToLocal` action is similar to the `expandSuperNodeInPlace` action in that an external pipeline flow may need to be retrieved from your repository. Consequently, you can follow the instructions in the [Loading an external sub-flow](/2.9-External-Subflows-support#loading-an-external-sub-flow) section for providing the appropriate properties of the `data` object in the `beforeEditActionHandler` callback. + +## Deleting an external supernode/sub-flow +When the user deletes an external supernode/sub-flow the supernode will be removed from the canvas. You code does not need to do anything unless you want to also remove the external pipeline flow from your repository. + +## Clipboard support +When a supernode, that refers to an external pipeline, is cut/copied and pasted, the pasted supernode refers to the same external pipeline as the supernode that was cut or copied. This means that if an external supernode is copied to the clipboard and then pasted into the same canvas the result will be two supernodes that refer to the same external pipeline.   + +The same situation can occur if a supernode, that refers to an external pipeline, is in the palette and that node is dragged multiple times from the palette onto the canvas. + +## Manipulating objects in external pipelines using the Canvas Controller API +Objects (nodes, links comments, etc.) in an external pipeline can be updated by the host application calling the `CanvasController` API. However, such changes are only effective within common-canvas. It is the host application's responsibility to make sure these changes are persisted in the external pipeline flow document (if that is the behavior that is required). This can be done by the host application calling `CanvasController.getExternalPipelineFlow(url)` and then saving the returned document to the appropriate repository. + +## External pipelines in the Elyra Canvas Test Harness +The Test Harness supports external pipeline flows but will only persist any saved flows for the current session. (It just stores them in memory). You can examine the `beforeEditActionHandler` and `editActionHandler` in App.js in the test harness to see how it handles the different actions for managing external pipeline flows. \ No newline at end of file diff --git a/guide/3.0-Common-Properties-documentation.md b/guide/3.0-Common-Properties-documentation.md new file mode 100644 index 0000000000..21b1346454 --- /dev/null +++ b/guide/3.0-Common-Properties-documentation.md @@ -0,0 +1,316 @@ +# Introduction +Common properties displays controls to view and set property values. + +You can look at the harness/src/client/App.js file of this repo to see examples of code that uses the common properties component. + + +# Getting started with Common Properties programming + +_Note: There are two ways one can use the Common Properties tooling: Either by allowing the form to be built dynamically from a parameterDef JSON (which is comprised of the base property set, ui-hints, conditions, and resources), or by explicitly providing the dialog form for rendering (deprecated). The first approach is recommended as an easier and clearer interface_ + + This takes 3 easy steps: + +## Step 1 : Import +To use Common Properties in your React application you need to do the following. First import the CommonProperties React component from the common-canvas library. Elyra Canvas produces both esm and cjs outputs. By default esm will be used when webpack is used to build the consuming application. + +```js + import { CommonProperties } from "@elyra/canvas"; +``` +**Properties Only** + +To import only common properties functionality in `cjs` format use: + +```js + import { CommonProperties } from "@elyra/canvas/dist/lib/properties"; +``` + + +## Step 2 : Set the data +Next you'll need to populate propertiesInfo with: + +```js +propertiesInfo: { + parameterDef: this.parameterDef, // Parameter definitions/hints/conditions + appData: "{user-defined}", // User data returned in applyPropertyChanges [optional] + additionalComponents: "{components}", // Additional component(s) to display [optional] + messages: "[node_messages]", // Node messages array [optional] + expressionInfo: this.expressionInfo, // Information for expression builder [optional], + initialEditorSize: "{size}" // This value will override the value of editor_size in uiHints. This can have a value of "small", "medium", "large", or null [optional] +} +``` +[parameterDef schema and examples](https://github.com/elyra-ai/pipeline-schemas/tree/master/common-canvas/parameter-defs) +[3.1 Common Properties Parameter Definition](/3.1-Common-Properties-Parameter-Definition) +[`expressionInfo` schema and examples](https://github.com/elyra-ai/pipeline-schemas/tree/master) + +or... + +(Deprecated) +```js +propertiesInfo: { + formData: this.formData, + appData: "{user data returned back in applyPropertyChanges}", //optional + additionalComponents: "{additional control(s) to display}", //optional + messages: "[node_messages]", // Node messages array [optional] + expressionInfo: this.expressionInfo, // Information for expression builder [optional] + initialEditorSize: "{size}" // This value will override the value of editor_size in uiHints. This can have a value of "small", "medium", "large", or null [optional] +} +``` +formData [schema](https://github.com/elyra-ai/pipeline-schemas/tree/master/common-canvas/form) +form information [wiki](https://github.com/elyra-ai/wml-canvas-service/wiki/2.-Runtimes-And-Operators) + +The optional messages attribute can be used to set validation messages associated with a node. The format of the message objects is defined in [Pipelin Flow UI schema](https://github.com/elyra-ai/pipeline-schemas/blob/master/common-pipeline/pipeline-flow/pipeline-flow-ui-v1-schema.json) + +## Step 3 : Display the properties editor + +Finally you'll need to display the editor. Inside your render code, add the following: +```html +import { IntlProvider } from "react-intl"; +var i18nData = require("../intl/en.js"); + +var locale = "en"; +var messages = i18nData.messages; + + { + this.CommonProperties = instance; + }} + propertiesInfo={this.propertiesInfo} // required + propertiesConfig={this.propertiesConfig} // optional + callbacks={this.callbacks} // required + customPanels={[CustomSliderPanel, CustomTogglePanel]} //optional + customControls={[CustomSliderControl]} // optional + light // optional + /> + +``` +**Properties** +- propertiesInfo `object`: See above +- propertiesConfig `object`: + - containerType `string`: type of container to display the properties, can be "Modal", "Tearsheet", or "Custom". default: `"Custom"` + - rightFlyout `boolean`: if custom container is a right-flyout, set to true. default: `false` + - applyOnBlur `boolean`: calls applyPropertyChanges when focus leave common-properties. default: `false` + - disableSaveOnRequiredErrors `boolean`: Disable the properties editor "save" button if there are required errors + - enableResize `boolean`: adds a button that allows the right-side fly-out editor to expand/collapse between small and medium sizes. default: `true` + - conditionReturnValueHandling `string`: used to determine how hidden or disabled control values are returned in applyPropertyChanges callback. Current options are "value" or "null". default: `"value"` + - buttonLabels `object`: + - primary `string`: Label to use for the primary button of the properties dialog + - secondary `string`: Label to use for the secondary button of the properties dialog + - heading `boolean`: show heading and heading icon in right-side fly-out panels. default: `false` + - schemaValidation `boolean`: If set to true, schema validation will be enabled when a parameter definition has been set in CommonProperties. Any errors found will be reported on the browser dev console. It is recommended you run with schema validation switched on while in development mode. + - applyPropertiesWithoutEdit `boolean`: When true, will always call `applyPropertyChanges` even if no changes were made. default: `false` + - maxLengthForMultiLineControls `number` - maximum characters allowed for multi-line string controls like textarea. default: 1024 + - maxLengthForSingleLineControls `number` - maximum characters allowed for single-line string controls like textfield. default: 128 + - convertValueDataTypes `boolean` - Default false. If set to true, currentParameter values whose data type does not match what is defined in the parameter definitions will be converted to the specified data type. + - trimSpaces `boolean` - Default true. If set to false, condition ops(`isEmpty`, `isNotEmpty`) and `required` fields are allowed to only contain spaces without triggering condition errors. + - showRequiredIndicator `boolean` - Default true to show `(required)` indicator. If set to false, show `(optional)` indicator next to properties label. + - returnValueFiltering `array` - Default []. When set this will filter out any values in the array in the parameters returned when `applyPropertyChanges` is call. Only primitive data types are currently supported. + - categoryView `string` - View categories in right-flyout. Can be `"accordions"` or `"tabs"`. default: `"accordions"`. +- callbacks `object` - See below for more details on each callback method + - applyPropertyChanges // required + - closePropertiesDialog // required + - helpClickHandler // optional + - controllerHandler // optional + - propertyListener // optional + - actionHandler // optional + - buttonHandler // optional + - buttonIconHandler // optional + - titleChangeHandler // optional +- customPanels `array`: array of custom panels. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-panels) for more details. +- customControls `array`: array of custom controls. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-controls) for more details. +- customConditionOps `array`: array of custom condition operators. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-condition-operators) +- light `boolean`: Carbon controls in common-properties will use light mode. When the `light` option is disabled, the background color will be the same as the Carbon theme background. When the `light` option is enabled, the background color is set to $ui-01. Defaults to `true` + +**Internationalization and override of labels in CommonProperties** +The CommonProperties dialogs have a set of labels that can have customized and internationalized values. CommonProperties uses the react-intl package to provide internationalization of these labels. This requires the `IntlProvider` element to wrap the `CommonProperties` element. +You can look at the **harness/src/intl/en.js** file of this repo to see the list of labels and the default values. + +**Reference methods** +```js +/* +* @closeEditor (boolean) - determines if closePropertiesDialog is called or not +*/ +applyPropertiesEditing(closeEditor) +``` + + +### Using CommonProperties in CommonCanvas right-flyout panel + +[Common Canvas](/2.0-Common-Canvas-Documentation#step-3--display-the-canvas) has a right-flyout panel that can render a React object. It can be used to render Common Properties in a flyout panel. + +Create a CommonProperties object with containerType set to "Custom" and rightFlyout set to true. +```html + const rightFlyoutContent =(); +``` +Pass the CommonProperties object into CommonCanvas's rightFlyoutContent props. Also set the showRightFlyout boolean to tell CommonCanvas when to show the rightFlyout. +```html + +``` + +# Callbacks + +### applyPropertyChanges(propertySet, appData, additionalInfo, undoInfo, uiProperties) +Executes when the user clicks `OK` in the property dialog. This callback allows users to save the current property values. + +- propertySet: The set of current property values +- appData: (optional) application data that was passed in to `propertiesInfo` +- additionalInfo: Object with additional information returned: + - messages: (optional) An array of messages associated with the nodes current property values. + - title: The title of the properties editor +- undoInfo: Object with information needed to undo this apply: + - properties: Set of property values; + - messages: (optional) An array of messages associated with the nodes property values. + - uiProperties: (optional) Set of UI only properties values +- uiProperties: The set of UI only property values (optional) + +```js +applyPropertyChanges(propertySet, appData, additionalInfo, undoInfo, uiProperties) { + var data = { + propertySet: propertySet, + appData: appData, + additionalInfo: { + messages: messages, + title: title + } + }; +} +``` + +### closePropertiesDialog(closeSource) +Executes when user clicks `Save` or `Cancel` in the property editor dialog. This callback is used to control the visibility of the property editor dialog. `closeSource` identifies where this call was initiated from. It will equal "apply" if the user clicked on "Save" when no changes were made, or "cancel" if the user clicked on "Cancel" + +```js +closePropertiesDialog() { + this.setState({ showPropertiesDialog: false, propertiesInfo: {} }); +} +``` + +### propertyListener() +Executes when a user property values are updated. + +```js +propertyListener(data) { + +} +``` + +### controllerHandler() +Executes when the property controller is created. Returns the property controller. See [here](/3.6-Common-Properties-Controller) for APIs + +```js +controllerHandler(propertyController) { + +} +``` + +### actionHandler() +Called whenever an action is ran. `id` and `data` come from uihints and appData is passed in with propertiesInfo. + +```js +actionHandler(id, appData, data) { + +} +``` + +### buttonHandler() +Called when the edit button is clicked on in a `readonlyTable` control, or if a custom table button is clicked. The callback provides the following data: +- data: an object that consists of + - type: of button the click was invoked from. + - `edit` is returned from the edit button click of a `readonlyTable` control. + - `custom_button` is returned from the custom button click of a complex type control. + - propertyId: of the control that was clicked. + - buttonId: of the button that was clicked from a custom table button. + +```js +buttonHandler(data) { + +} +``` + +### buttonIconHandler() +Called when there is a `buttons` uihints set in the `complex_type_info` section of the parameter definition. This buttonIconHandler expects a Carbon Icon jsx object as the return value from the callback. This is used to display the Carbon icon in the custom table button. The buttonIconHandler provides the following data: +- data: an object that consists of + - type: `customButtonIcon` + - propertyId: of the control that was clicked. + - buttonId: of the button that was clicked from a custom table button. + - carbonIcon: The name of the Carbon icon specified in the uihints. The corresponding jsx object is expected to be returned in the callback. + +```js +buttonIconHandler(data, callbackIcon) { + if (data.type === "customButtonIcon" && data.carbonIcon === "Edit32") { + callbackIcon(); + } +} +``` + +### helpClickHandler() +Executes when user clicks the help icon in the property editor dialog. The callback provides the following data: +- nodeTypeId: in case of parameterDef, id property of uihints; in case formData, the componentId. +- helpData: Optional helpData specified in paramDef/formData (see below). +- appData: Optional application data that was passed in to `propertiesInfo` +```js +helpClickHandler(nodeTypeId, helpData, appData) { + +} +``` +To control whether a node shows the help icon in the right fly-out, a help object with optional helpData needs to be provided in the paramDef or formData: +- paramDef: Provide help object in operator's uihints. If help object exists, the icon will be shown. Optionally, provide a helpData object within the help object, which will be passed in the helpClickHandler callback. +https://github.com/elyra-ai/pipeline-schemas/blob/master/common-pipeline/operators/uihints-v2-schema.json#L64 +- formData: add help object to form definition. The +https://github.com/elyra-ai/pipeline-schemas/blob/master/common-canvas/form/form-v2-schema.json#L51 + +If no help object is found, no help link will be shown. + + +### titleChangeHandler() +Called on properties title change. This callback can be used to validate the new title and return warning or error message if the new title is invalid. This callback is optional. + +In case of error or warning, titleChangeHandler should call callbackFunction with an object having type and message. If the new title is valid, no need to call the callbackFunction. +```js +titleChangeHandler(title, callbackFunction) { + // If Title is valid. No need to send anything in callbackFunction + if (title.length > 15) { + callbackFunction({ + type: "error", + message: "Only 15 characters are allowed in title." + }); + } +} +``` +where: +- type (string, required): This must be one of two values: "warning" or "error". +- message(string, required): Error or warning message. There is no restriction on length of the message. + + + +### propertiesActionLabelHandler() +```js +propertiesActionLabelHandler() +``` +This is an optional handler you don't need to implement anything for it unless you want to. This callback allows your code to override the default tooltip text for the `Undo` and `Redo` buttons. +The `propertiesActionLabelHandler` callback, when provided, is called for the save properties action that is performed in common-properties. This callback should return a string or null. If a string is returned it will be shown in the tooltip for the `Undo` button in the toolbar preceded by "Undo:" and the string will also appear in the tooltip for the `Redo` button (when appropriate) preceded by "Redo:". If null is returned, common-properties will display the default text `Save {node_name} node properties` for the Undo and Redo buttons. + +### tooltipLinkHandler() +Optional callback used for adding a link in properties tooltips. link object must be defined under description in uiHints parameter info. Common-properties internally pass the link object to tooltipLinkHandler callback. +This callback must return an object having url and label. + +```js +tooltipLinkHandler(link) { + return { url: "https://www.google.com/", label: "More info" }; +} +``` + diff --git a/guide/3.1-Common-Properties-Parameter-Definition.md b/guide/3.1-Common-Properties-Parameter-Definition.md new file mode 100644 index 0000000000..31ec395383 --- /dev/null +++ b/guide/3.1-Common-Properties-Parameter-Definition.md @@ -0,0 +1,261 @@ +# Parameter Definitions +The parameter definition json files is an easy way to provide input for controlling the common properties dialog. It consists of information that is available in the operator json combined with UI hints, information on data sets, and resources. + +The parameter definition has a defined schema and set of examples located here: +[schema and examples](https://github.com/elyra-ai/wdp-pipeline-schemas/tree/master/common-canvas/parameter-defs) + +The parameter definition consists of eight sections. + +## Title Definition + +The title of the properties editor. If `editable` is set to true (default), the title can be edited. If set to false, the title will be readonly. + +```js +"titleDefinition": { + "title": "Properties Title", + "editable": true + } +``` + +## Current Parameters + +A list of input parameters and initial values upon input. The list is a set of key/value pairs with the key being the field name and the value is the initial value. + +Example +```js +"current_parameters": { + "targetField": [], + "inputFieldList": [], + "elasticNetParam": 0.0, + "fitIntercept": false, + "maxIter": 75, + "regParam": 0.1, + "standardization": true, + "threshold": 0.5, + "tol": 0.0000010 + } +``` + +## Parameter Definitions +The list of parameters definitions for this property dialog. The list contains the name of the parameter, the data type of the parameter, the role and the default value. The information provided is as needed by the backend engine, i.e. the parameter name should be the name of the parameter that is expected for the backend engine. + +The list of parameter definitions has the following attributes. +* `id` (*string*) **Required** Parameter identifier as consumed by the backend engine. +* `default` (*any*) The default value of the parameter. +* `enum` (*array[string]*) A restricted list of string values that are valid for the field. +* `type` (*string*) Parameter type as consumed by the backend engine. +* `role` (*string*) Parameter role, which is an optional specialization of the type. +* `required` (*boolean*) Indication whether parameter is required or optional. + + +Parameter types have one of a fixed set of basic types. These are: + +* `integer` +* `double` +* `string` +* `date` +* `time` +* `timestamp` +* `custom` + +These can be used as maps or arrays e.g.: + + array[]: a sequence or list of values + +Parameter roles defined by the role attribute can be one of: + +* `expression`: an expression assumed to be in the expression language for the run time +* `column`: value represents one or more columns from the data model visible to this operator +* `new_column`: value represents the name of a new column to be added to the data model and must therefore not match an existing column and conform to existing syntactic restrictions. + + +Example +```js +"parameters": [ + { + "id":"targetField", + "type":"string", + "default":"", + "role":"column" + }, + { + "id":"inputFieldList", + "type":"array[string]", + "default":[], + "role":"column" + }, + { + "id": "impurity", + "enum": [ + "gini", + "entropy" + ], + "default": "gini" + }, + { + "id":"elasticNetParam", + "type":"double", + "default":0.0 + } +] +``` +## UI-only Parameters +A list of input parameters and initial values upon input. This set of parameters are separated from the backend parameters (current parameters). The idea is that these parameters are not passed into the backend engine by the common properties consumer. + +Example +```js +"current_ui_parameters": { + "databaseResource": true, + "tol": 0.0000010 + } +``` + +UI-only parameters require information about the parameters same as the parameter definition information used for the backend parameters. The UI-only parameter definition information is stored in the UI-hints section in the sub-section named `ui_parameters`. A description of the UI hints specifications can be found here: [3.2 Common Properties UI Hints](/3.2-Common-Properties--UI-Hints) + + +UI-only properties are returned to the consuming application via a separate parameter on the applyPropertiesChanges callback. See the `Callbacks` section of [3.1 Common Properties Documentation section.](/3.0-Common-Properties-documentation) + + +## Complex Types +The complex types section is an array of + +The complex types have the following attributes. +* `id` (*string*) **Required** Identifier of complex type, can be referenced in other places. +* `type` (*string*) If `object` is specified, common properties will return the values as an array of objects consisting of key value pairs. This defaults to `array`. +* `key_definition` (*object*) A parameter definition attribute on the key parameter field. +* `parameters` (*object*) **Required** List of parameters fields. Each parameter can be defined as a parameter definition attribute or a complex type attribute. + + +Example of complex types +```js +"complex_types": [ + { + "id": "SortEntry", + "type": "object", + "key_definition": { + "id": "field", + "type": "string", + "role": "column", + "default": "" + }, + "parameters": [ + { + "id": "sort_order", + "enum": [ + "Ascending", + "Descending" + ], + "default": "Ascending" + } + ] + } + ] +``` + +### A Note on Parameters and Complex Types: +Note that both parameter and complex type definitions are in the exact same format as defined in the operator schema. Therefore the contents of operator JSON files can be used for these two sections. + + +## UI Hints +A set of specifications for controlling the layout and flow of the common properties. A description of the UI hints specifications can be found here: [3.2 Common Properties UI Hints](/3.2-Common-Properties--UI-Hints) + +## Conditions +A set of specifications for controlling validation checking of parameters during the common properties dialog. A description of the Conditions specifications can be found here: +[3.4 Common Properties Conditions](/3.4-Common-Properties-Conditions) + +## Data Set Metadata +The data set metadata is an array of datarecord-metadata objects as defined in the datarecord-metadata JSON schema. Each datarecord-metadata object contains and array of fields that provide column information on the input data set. [schema and examples](https://github.com/elyra-ai/pipeline-schemas/tree/main/common-pipeline/datarecord-metadata) + +The fields have the following attributes. +* `name` (*string*) **Required** Field name. Must be unique within the dataset. +* `type` (*string*) **Required** Field type. Can be a primitive type (string, integer, double, date, time, timestamp), or a vector, map, or struct containing those types. Required. +* `nullable` (*boolean*) Indicates whether or not one can place null values into the field. Default: False. +* `metadata` (*object*) A set of additional metadata attributes. + +The additional metadata attributes are as follows. +* `description` (*string*) A description of the field. +* `measure` (*string*) The field measurement type. The value can be one of the following. `range, discrete, flag, set, ordered-set, typeless, collection, geospatial, default` +* `role` (*string*) Field role for modeling. The value can be one of the following. +`input, +target, +both, +none, +partition, +split, +frequency, +record-id` +* `max_string_length` (*number*) Maximum character length for string fields. Length is unlimited when not present. +* `values` (*array[string]*) Array of unique categorical values for the column. +* `ranges` (*object*) Minimum and maximum discovered values for scalar data. + +Example +```js +"dataset_metadata": [ + { + "name": "Schema-1", + "fields": [ + { + "name": "Age", + "type": "integer", + "metadata": { + "description": "", + "measure": "range", + "role": "input" + } + }, + { + "name": "Sex", + "type": "string", + "metadata": { + "description": "", + "measure": "discrete", + "role": "input" + } + }, + { + "name": "BP", + "type": "string", + "metadata": { + "description": "", + "measure": "discrete", + "role": "input" + } + } + ] + }, + { + "name": "Schema-2", + "fields": [ + { + "name": "Birthdate", + "type": "date", + "metadata": { + "description": "Date of birth", + "measure": "range", + "role": "input" + } + } + ] + } +] + +``` + +## Resources +This is a map of string resources. + +Example: +```js +"resources":{ + "org.apache.spark.ml.classification.DecisionTreeClassifier.label":"Random Forest Classifier", + "org.apache.spark.ml.classification.DecisionTreeClassifier.desc":"Fitted Random Forest Classification Model", + "inputFieldList.label":"Input columns", + "inputFieldList.desc":"Select one or more input columns", + "targetField.label":"Target column", + "targetField.desc":"Select a target column", + "max_depth_not_valid":"The max depth parameter must be greater than or equal to zero", + "max_iter_not_valid": "The max iterations parameter must be greater than or equal to zero", + "min_instances_per_node_not_valid": "The minimum instances per node value must be >= 1", + "subsampling_rate_not_valid": "The subsampling rate value must be > 0 and <= 1" +} +``` \ No newline at end of file diff --git a/guide/3.2-Common-Properties-UI-Hints.md b/guide/3.2-Common-Properties-UI-Hints.md new file mode 100644 index 0000000000..e0461d8d02 --- /dev/null +++ b/guide/3.2-Common-Properties-UI-Hints.md @@ -0,0 +1,343 @@ +# UI Hints +UI hints is a section of the property definition json and contains specifications to assist in the presentation and flow of the property dialog. The specifications indicate which controls to use to display and gather input on the fields. +[uihints schema](https://github.com/elyra-ai/wdp-pipeline-schemas/blob/master/common-pipeline/operators/uihints-v1-schema.json) + +The UI Hints section consists a set of simple and complex attributes. + +**The simple attributes are:** + +* `id` (*string*) Dialog id. +* `label` (*object*) External name of dialog. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) +* `description` (*object*) Description of dialog. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) +* `editor_size` (*string*) The width of the properties editor panel. This can have a value of `"small"`, `"medium"`, `"large"` or `"max"`. The default is `"small"`. + - When `"small"` is specified the properties panel is displayed with a default width of 320px and with a resize button that allows the panel to be increased in size up to the `"medium"` size which is 480px. + - When `"medium"` is specified the properties panel has a width of 480px and with a resize button that allows the panel to be increased in size up to the `"large"` size which is 640px. + - When `"large"` is specified the properties panel has a width of 640px and with a resize button that allows the panel to be increased in size up to the `"max"` size which is 900px. + - When `"max"` is specified the properties panel has a width of 900px and no resize button is displayed. +* `pixel_width` (*object*) This optional property gives finer control over the minimum and maximum sizes of the properties editor panel. If this is omitted the properties editor width is controlled by the `editor_size` property. `pixel_width` is an object with two properties `min` and `max` which are both numbers. + - If `min` is specified it overrides the default size of the shrunken panel and `max` is based on the `editor_size` value. + - If `max` is specified it overrides the default size of the expanded panel and `min` is based on the `editor_size` value. + - If `editor_size` is set to `"large"` only the `max` value will be used to specify the size of the panel and no resize button will be displayed. + + A warning will be displayed in the console if you specify an invalid value for either `min` or `max` such as making `min` greater than `max`. + +Example of the simple attributes: +```js +"uihints": { + "id":"org.apache.spark.ml.ibm.transformers.Distinct", + "icon": "images/transformationspark.svg", + "label": { + "default": "Distinct" + }, + "editor_size": "medium", + "pixel_width": { + "min": 400, + "max": 800 + }, + "description": { + "default": "Remove rows to leave only rows with distinct combinations of rows" +} +``` + + + +**The complex attributes of the UI hints section are:** +## Group-info + +Group info attributes. +* `id` (*string*) **Required** Panel id +* `type` (*string*) The group type to be displayed. see Group/Panel Controls in [3.3 Common Properties Controls](/3.3-Common-Properties-Controls). +* `depends_on_ref` (*string*) Property name this group depends upon. Valid for panelSelector groups only. +* `label` (*object*) Group label. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) +* `description` (*object*) Group description. Only used with `textPanel` and `actionPanel`. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) + + `link` (object) Optional link in the description. [tooltipLinkHandler callback](/3.0-Common-Properties-documentation#tooltiplinkhandler) must be defined whenever link object is added in uiHints.. + + `id` (string) Required unique link id. + + `data` (object) Data passed to the tooltipLinkHandler callback. +* `parameter_refs` (*array[string]*) List of parameter to be displayed. +* `action_refs` (*array[string]*) List of action to be displayed. Used with `actionPanel` only. +* `group_info` (*object*) List of additional group information. +* `data` (*any*) Returned in custom panel constructor without any changes. +* `insert_panels` (*boolean*) Indicates whether panels, contained with a panelSelector, should be inserted between the radio buttons of a radio button set indicated by the depends_on_ref parameter. +* `nested_panel` (*boolean*) Indicate whether panel should be nested. Nested panels are indented by 16px from the left and display left border. Default is false. +* `class_name` (*string*) Optional classname for this group +* `open` (*boolean*) Optional used to determine if a panel should be open or not by default. Used with `twistyPanel` only. Default is `false`. + + +Example group info section: +```js +"group_info": [ + { + "id": "settings", + "label": { + "default": "Settings" + }, + "type": "columnSelection", + "parameter_refs": [ + "keys" + ] + } + ] +``` + +## UI-only Parameters +UI-only parameters require information about the parameters same as the parameter definition information used for the backend parameters. The UI-only parameter definition information is stored in the UI-hints section in the sub-section named `ui_parameters`. The format of the information in the `ui_parameters` sub-section is documented in the `Parameter Definition` section of [Common Properties Parameter Definition](/3.1-Common-Properties-Parameter-Definition/). + +Example +```js +"ui_parameters": [ + { + "id":"databaseResource", + "type":"boolean", + "default":true + }, + { + "id":"toi", + "type":"double", + "default":0.0 + } +] +``` + +The UI-only parameters need to be added to other UI Hints sections (for example `Group Info` and canbe refered to by the `parameter_ref` field just like backend parameters. + +## Parameter Info +The parameter info section contains the list of parameters to gather values on through the property dialogs and UI hints about each parameter. The UI hints provide information to facilitate the UI controls used to display the parameter in the property dialogs. + +Parameter info attributes. + +* `parameter_ref` (*string*) **Required** Parameter name. +* `label` (*object*) External name for parameter. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) +* `label_visible` (*boolean*) Determines whether to display the label for a control. +* `description` (*object*) Description of parameter with optional placement context. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + `placement` (*string*) Placement context for the text. Valid values are `as_tooltip, on_panel`. + + `link` (*object*) Optional link in the description. [tooltipLinkHandler callback](/3.0-Common-Properties-documentation#tooltiplinkhandler) must be defined whenever link object is added in uiHints.. + + `id` (*string*) Required unique link id. + + `data` (*object*) Data passed to the tooltipLinkHandler callback. +* `control` (*string*) Which control to use. see Parameter Controls in [3.3 Common Properties Controls](/3.3-Common-Properties-Controls). +* `increment` (*number*) Determines the increment/decrement value for the spinner control only. The default value is `1`. +* `orientation` (*string*) Determines how the control is displayed. Valid values are `vertical, horizontal`. +* `width` (*number*) Column width for tables. The widths provided for table columns are used to calculate relative widths for each table column. So for example a 3 column table with widths of 20, 30, and 50 would use 20%, 30%, and 50% of the overall table width, respectively. +* `char_limit` (*number*) Limits the number of characters a user can enter into the control for string parameters only. +* `display_chars` (*number*) This has been deprecated and is subject to removal. Limits the number of characters displayed for a text field in a column in a table. The text will have an ellipsis appended at this limit. Defaults to 64 characters. +* `separator` (*string*) Determines where to put a separator relative to the current control. Valid values are ` after, before`. +* `visible` (*boolean*) Determines whether to display control in a table cell. Used in complex types only. +* `place_holder_text` (*object*) Text hint for the user displayed input controls. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) +* `resource_key` (*string*) Used as a key for enum value labels in the resources section of property definition. +* `edit_style` (*string*) Editing style of elements in a table. Valid values are `subpanel, inline, on_panel`. +* `value_icons` (*array[string]*) For enumerated types, this defines the set of icons for the valid values. The ordering must be consistent with the order in the parameter enum attribute. +* `filterable` (*boolean*) Determines if this column values can be filtered so that only rows that match the filter in column values are shown in the table. Applies to complex parameters only. +* `sortable` (*boolean*) Determines if this column values can be sorted into ascending/descending order in a table. Applies to complex parameters only. +* `number_generator` (*object*) Describes a number generator button beside numeric control. The 'label' element is a standard resource item, and the 'range' element contains 'min' and 'max' attributes to constrain the range of generated numbers. +* `dm_default` (*string*) Data record metadata field to be used for default values in table cell columns. Typically this is used with parameters in complex structures in which the key field is a column name. Valid values are `type`, `description`, `measure`, and `modeling_role`. +* `dm_image` (*string*) This can be set to display an icon of the corresponding dm type in the `role`:`column` field of a table. Valid values are `measure`, `type`, `none` +* `summary` (*boolean*) Determines if parameter should be shown in the summary when using a `summaryPanel`. +* `text_before` (*object*) Text to be displayed before the control + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + `type` (*string*) Adds a icon and additional formatting to the text. Only `info` is support at this time. + + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) +* `text_after` (*object*) Text to be displayed after the control + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + `type` (*string*) Adds a icon and additional formatting to the text. Only `info` is support at this time. + + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) +* `custom_control_id` (*string*) Id that is used to determine which custom control to use when `control=custom` +* `data` (*any*) Returned in custom control constructor without any changes. +* `rows` (*integer*) Number of rows to show in a table before scrolling starts. If one table in a panel is set to -1, that table will use the remaining available vertical space, down to a minimum of 2 rows. Used in expression and code controls to determine the number of rows to show for those controls. +* `moveable_rows` (*boolean*) Determines if rows can be moved up or down in a table or array of strings. +* `action_ref` (*string*) An action to be displayed. +* `date_format` (*string*) A format string such as YYYY-MM-DD which describes the display and entry format for a date field. +* `time_format` (*string*) A format string such as HH:mm:ss which describes the display and entry format for a time field. +* `custom_value_allowed` (*boolean*) Determines if a dropdown, outside of a table, can allow a custom value to be entered. +* `class_name` (*string*) Optional classname for this parameter +* `resizable` (*boolean*) Determines if this column can be resized in a table. When a column is resized, width of all the columns to the right of resized column is adjusted. Applies to structure parameters only. Default is `false`. + +Example parameter info section: +```js + "parameter_info": [ + { + "parameter_ref": "keys", + "label": { + "resource_key": "sort.keys.label" + }, + "description": { + "resource_key": "sort.keys.desc", + "placement": "on_panel" + }, + "rows": -1 + } + ] +``` + +## Complex Type Info +The complex_type_info section defines complex data types. This section is needed if in the `parameters` section of the parameter definition, one of the parameters has a type that is not the base type (i.e. an array or map of base types). The type of control used for this definition depends on the group info type value. + +Complex Type info attributes. +* `complex_type_ref` (*string*) **Required** Name of complex type, can be referenced in other places. +* `key_definition` (*string*) A set of parameter info attributes about the key parameter. +* `label` (*object*) External name of subpanel. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) +* `parameters` (*object*) **Required** List of parameters that are part of this complex parameter. This parameter can either have a set of parameter_info attributes or other nested complex_type_info attributes. +* `header` (*boolean*) If `true` then the table has a header row with column names. Defaults to `true`. +* `add_remove_rows` (*boolean*) If `true` then the table can have rows added and removed. Defaults to `true`. +* `include_all_fields` (*boolean*) When `true` and `add_remove_rows` is `false`, ensures that all fields are included in the control at all times. +* `row_selection` (*string enum*) How many rows in a table can be selected at a time. + + `single`: only one row at a time is able to be selected. + + `multiple`: multiple rows at a time are able to be selected. + + `multiple-edit`: select multiple rows and allow the editing of column values of all selected rows. +* `buttons` (*array*) An array of objects that define custom buttons to be displayed in this complex structure, overriding any default buttons. Each button object contains the following properties: + + `id` (*string*) **Required**: Unique identifier used to identify the button in the callback function. + + `label` (*object*): Button label to display. If an icon is specified as well, the icon will be shown to the right of the label. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + `description` (*object*): Tooltip text to display when the button is hovered. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + `icon` (*string*): URL to .svg image to display. + + `carbon_icon` (*string*): Host provided name of Carbon icon to display. A callback function is required for the host application to return the jsx icon object imported from @carbon/icons-react library. + + `enabled` (*boolean*): Button will be enabled if true, disabled if false. + + `divider` (*string enum*): Display a divider before or after this button. Defaults to `after` + + `before` Display divider before this button + + `after` Display divider after this button + +Example complex_type_info section: +```js + "complex_type_info": [ + { + "complex_type_ref": "SortEntry", + "row_selection": "multiple", + "moveable_rows": true, + "add_remove_rows": false, + "include_all_fields": true, + "key_definition": { + "parameter_ref": "field", + "width": 28, + "label": { + "resource_key": "SortEntry.field.label" + } + }, + "parameters": [ + { + "parameter_ref": "sort_order", + "width": 16, + "resource_key": "SortEntry.sort_order", + "label": { + "resource_key": "SortEntry.sort_order.label" + }, + "control": "toggletext", + "value_icons": [ + "/images/up-triangle.svg", + "/images/down-triangle.svg" + ] + } + ] + }, + { + "complex_type_ref": "FieldStorageEntry", + "key_definition": { + "parameter_ref": "field", + "label": { + "default": "", + "resource_key": "FieldStorageEntry.field" + }, + "width": 26, + "sortable": true, + "filterable": true + }, + "parameters": [ + { + "parameter_ref": "override", + "label": { + "default": "", + "resource_key": "FieldStorageEntry.override" + }, + "width": 16, + "edit_style": "inline", + "sortable": true + }, + { + "parameter_ref": "storage", + "label": { + "default": "", + "resource_key": "FieldStorageEntry.storage" + }, + "width": 26, + "edit_style": "inline", + "dm_default": "type" + } + ], + "buttons": [ + { + "id": "icon_button_1", + "carbon_icon": "Edit32", + "label": { + "resource_key": "table.somekey.label" + }, + "description": { + "default": "This renders a button that has a label and Carbon icon to the right of the label. + }, + "enabled": true + } + ] + } + ] +``` +## Action Info +The action_info section defines an action. Actions are used to callback to the application to perform an operation. + +Action info attributes. +* `id` (*string*) **Required** Id of the action. +* `label` (*object*) **Required** External name of action. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) +* `control` (*string*) **Required** The type of action. Currently `button` and `image` are supported. +* `class_name` (*string*) Optional classname for this action +* `image` (*object*) Properties associate with an `image` action. + * `url` (*string*) Location of the image to display. + * `placement` (*string*) Placement of image relative to a property. Values are `right` or `left`. + * `size` (*object*) Pixel size of the image. + * `height` (*number*) Image height in pixels. + * `width` (*number*) Image width in pixels. + * `tooltip_direction` (*string*) Set tooltip direction for action image. Values are `right`, `left`, `top`, or `bottom`. Default is `bottom`. +* `button` (*object*) Properties associated with action button. + * `kind` (*string*) Button kind. Values are same as carbon button kind values. Default is `tertiary`. + * `size` (*string*) Button size. Values are sm, md, lg, xl. Default is `sm`. +* `data` (*any*) Returned back in action callback. + +```js +{ + "id": "increment", + "label": { + "default": "Increment" + }, + "control": "button", + "data": { + "parameter_ref": "number" + } +} +``` + +## Resource Definition +Used for user facing text. Allows for default values if no translations are provided. +* `default` (*string*) Default value if `resource_key` not defined. +* `resource_key` (*string*) Used as a key for enum value labels in the resources section of property definition. + +## Dynamic text expressions +Used to dynamically set text based on a parameter value change. If parameter id is used then then current value for that parameter will be passed into the function. +* `percent(, )` Return the percent of the 1st parameter. The optional 2nd parameter determines the number of decimal places. +* `sum(, , ...)` Returns the sum of all parameters + +```js +{ + "parameter_ref": "numberfield", + "label": { + "default": "Number" + }, + "text_after": { + "default": "Sum: ${sum(numberfield, 2)} with (numberfield, 2, numberfield). Percent: ${percent(numberfield,2)}" + } +} +``` diff --git a/guide/3.3-Common-Properties-Controls.md b/guide/3.3-Common-Properties-Controls.md new file mode 100644 index 0000000000..f29493e47c --- /dev/null +++ b/guide/3.3-Common-Properties-Controls.md @@ -0,0 +1,110 @@ +# Common Properties Element Types +The editor determines the most appropriate control and panel type for each parameter based on the context (parameter type, role, group type, etc.). Although an author can specify a desired control for a given parameter via its `uihints`, this should be used sparingly and carefully - specifying an inappropriate control for a parameter will lead to undefined behavior. + +A visual documentation containing examples of the following group/panels and control types are available at https://wdp-common-canvas-dev.stage1.mybluemix.net/#/properties. + +## Group/Panel Controls +Controls are grouped and arranged on panels and sub-panels within the "group_info" section of operator uihints. Some panels appear as tab controls, others are for managing shared dataset metadata, while still others contain nested sub-panels. + +### Group Types +* `controls` A general panel type containing parameter controls. +* `tabs` A tabbed control, each tab containing sub-panels and controls. +* `subTabs` A horizontal sub-tabbed control, each tab containing sub-panels and controls. If displayed within a Tearsheet container, subtabs will be displayed vertically. +* `panels` A panel type that contains sub-panels. +* `panelSelector` A panel containing sub-panels that are shown or hidden based upon a controlling radio selection. +* `columnSelection` A panel type containing field-selection controls that share a common set of fields. +* `customPanel` A custom panel for displaying user defined control. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-panels) for more details. +* `summaryPanel` A panel used in the flyout editor that will provide a link to open a wide flyout that can contain panels and parameter. +* `actionPanel` A panel used for containing action controls. +* `textPanel` A panel used to display static label and/or description. +* `twistyPanel` A panel used to display a panel title that expands to the panel content when clicked. +* `columnPanel` A panel used to display children side by side. +* `tearsheetPanel` A tearsheet panel. The panel can be opened/closed using the propertyController methods `setActiveTearsheet(groupId)` and `clearActiveTearsheet()` + +## Parameter Controls +The following controls are supported in the Common Properties editor. Control types are intended for use with particular parameter types: + +### Control Types +* `readonly` A read only text field. Used for fields users shouldn't edit. +* `hidden` A control that has no UI to display. +* `textfield` A single line editable text field. +* `passwordfield` A masked single line text field with tooltip. The tooltip text can be customized by setting `[parameter_id].passwordHide.tooltip` and `[parameter_id].passwordShow.tooltip` in resources section. +* `textarea` A multi-line text area. +* `list` A single column table for editing a list of values. +* `expression` An expression editing field that provides language specific syntax highlighting and text auto complete. An expression builder addon is available with the expression control. You must provide the `expressionInfo` field for the `propertiesInfo` config. See [3.0 Common Properties Documentation](/3.0-Common-Properties-documentation) for more details. To maximize in a tearsheet add this attribute and define a `tearsheetPanel` in `group_info`. + ``` + "data": { + "tearsheet_ref": "" + } + ``` +* `code` An code editing field that provides language specific syntax highlighting and text auto complete. To maximize in a tearsheet add this attribute and define a `tearsheetPanel` in `group_info`. + ``` + "data": { + "tearsheet_ref": "" + } + ``` +* `numberfield` A numeric text field. Number fields can also optionally display a random number generator button beside the control. See the uihints schema for details. +* `datefield` A date input control whose date format tokens follow [date-fns](https://date-fns.org/v2.29.3/docs/format). Defaults to `yyyy-mm-dd` +* `timefield` A time input control whose time format tokens follow [date-fns](https://date-fns.org/v2.29.3/docs/format). Defautls to `H:m:s` +* `datepicker` A date input control with calendar picker whose date format tokens follow [Flatpickr](https://flatpickr.js.org/formatting/#date-formatting-tokens). Defaults to `Y-m-d`. Helper text can be included by adding `[parameter_id].helper` in the resources section. +* `datepickerRange` A date input control with calendar picker for a range of dates. This follow the same rules as the `datepicker` control. Start and end labels defaults to `Start` and `End` respectively. Start, end, and helper labels can be customized by adding the following in the resources section: + ``` + "resources": { + [parameter_id].range.start.label: "Custom start label", + [parameter_id].range.start.desc: "Custom start description that will appear as tooltip next to the label", + [parameter_id].range.start.helper: "Custom start helper that will appear as text below the input", + [parameter_id].range.end.label: "Custom end label", + [parameter_id].range.end.desc: "Custom end description that will appear as tooltip next to the label", + [parameter_id].range.end.helper: "Custom end helper that will appear as text below the input"` + } + ``` +* `spinner` A standard spinner control to increment/decrement the number value. +* `checkbox` A standard checkbox control. +* `radioset` A radio set where a parameter value is selected from a small range of options. See the Conditions wiki page for special radio button disabling options. +* `checkboxset` A checkbox set for list type parameters with enumerated options where the count is less than 5. +* `oneofselect` A standard dropdown list control. +* `multiselect` A standard dropdown list control that allows for multiple selection. +* `someofselect` A multi-selection control for enumerated list parameters where the count is greater than 4. +* `selectcolumn` A dropdown list control that selects from available column names. When dropdown list is empty, `selectcolumn` control will display default placeholder text `"..."`. This placeholder text can be customized by setting `[parameter_id].emptyList.placeholder` in resources section. When custom empty list placeholder text is provided, common-properties will disable the empty list control. +* `selectcolumns` A multi-select control for column selections. +* `selectschema` A dropdown control that contains the available schemas in `dataset_metadata`. The `name` of the schema will be displayed if provided. If `name` is not provided, the index (zero-based) of the schema will be used instead. When dropdown list is empty, `selectschema` control will display default placeholder text `"..."`. This placeholder text can be customized by setting `[parameter_id].emptyList.placeholder` in resources section. When custom empty list placeholder text is provided, common-properties will disable the empty list control. +* `toggle` A standard toggle control with default On/Off states. This text can be customized by setting `[parameter_id].toggle.on.label` and `[parameter_id].toggle.off.label` in resources section. +* `toggletext` A two-state control with optional icons that can exist on its own or within table cells. +* `structuretable` Table control for editing lists or maps of complex types that have field names in the first column. +* `structurelisteditor` For lists or maps of complex types that are *not* field-oriented parameters. +* `structureeditor` Allows one to define a structure and use it directly on a panel. Each structure member is surfaced as an individual control. Supports a `layout` setting that allows one to position structureeditor controls in a grid (see below). +* `readonlyTable` A read only table. Used for tables to display fields that users shouldn't edit. +* `custom` A custom control for displaying a user defined control. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-controls) for more details. + + +### A Note on Field Name Storage +When a given node can accept more than a single datarecord-metadata object as input, it becomes necessary to store the schema name (a.k.a. 'link_name') along with each field name that is stored in parameter sets. In those cases, instead of using strings to store field names, they are represented in parameter sets as compound objects containing both 'link_ref' and 'field_name' elements: + + "current_parameters": { + "field": { "link_ref": "Schema-1", "field_name": "Age" }, + ... + +In order to indicate that a given node can potentially accept multiple input data links and would thus require compound field name storage, all parameter definitions within the node that contain `"role": "column"`, whether located at the top level or within complex types, should declare their data types as "object" instead of "string": + + "parameters": [ + { + "id": "fields", + "type": "array[object]", + "role": "column", + "required": true + }, + ... + +### edit_style +When editing complex type values in tables one can either edit cell values inline or in a sub panel: +* `subpanel` A small sub-dialog is launched to edit cell values. +* `inline` Controls appear inline within table cells for editing values. +* `on_panel` Control appears below the table when the row is selected. + +### Miscellaneous +* `moveable_rows` *boolean* A value that appears in "complex_type_definition" sections. If set to `true` allows rows in the table to be moved up and down for reordering. +* `row_selection` *enum ["single", "multiple"]* Determines how many rows can be selected in a table at one time. Defaults to *multiple*. +* `sortable` *boolean* Both sortable and filterable apply to table columns. When set within the "key_definition" or the "parameters" sections of a structure definition, those columns are sortable and/or can be filtered upon. +* `filterable` *boolean* _(see sortable above)_ +* `language` *enum ["CLEM", "text/x-hive"]* The language for the expression control syntax highlight and text auto complete feature. If not specified, the expression control does not have syntax highlighting or text auto complete. +* `layout` A two-dimensional string array value that appears in "complex_type_definition" sections and allows one to layout structureeditor controls in a two dimensional grid. diff --git a/guide/3.4-Common-Properties-Conditions.md b/guide/3.4-Common-Properties-Conditions.md new file mode 100644 index 0000000000..33f19068e1 --- /dev/null +++ b/guide/3.4-Common-Properties-Conditions.md @@ -0,0 +1,353 @@ +# Conditions +Conditions define a set of specifications for evaluating parameter values. The specifications support complex interdependency checking such as relationships between multiple parameters (i.e. Valid values for parameter one depend upon the value of parameter two). +[conditions schema](https://github.com/elyra-ai/wdp-pipeline-schemas/blob/master/common-pipeline/operators/conditions-v1-schema.json) + +Visual documentation containing examples of the following conditions for the different controls we support are available at https://wdp-common-canvas-dev.stage1.mybluemix.net/#/conditions + + +A conditions file contains an array of conditions. Each condition takes one of the following forms: + +## Validation definition +A single validation. The fail_message is displayed upon validation failure. + +The attributes for the validation definition are: +* `id` (*string*) A unique identifier for the validation. This is required if multiple validations have the same `focus_parameter_ref` value. +* `fail_message` (*object*) **Required** The message to display if the validation fails. Each fail_message consist of the following attributes + + `message` (*object*) **Required** The message to display. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + `focus_parameter_ref` (*string*) **Required** The parameter control to get focus after displaying the error/warning. If the validation refers to a table cell, then control must have the column indicator. For example if the validation is for `MyTable` cell column 2 then `MyTable[2]`. + + `type` (*string*) Type of messages. Valid values are `error, warning, info`. + +* `evaluate` (*object*) Specification for how to evaluate the validity of the parameter. The evaluate attribute can be one of the following structures. + + `condition` (*object*) This is a single condition that evaluates to true or false. + - `op` (*string*) **Required** A single operator for the properties of the condition. Valid values are: +`isEmpty`, +`isNotEmpty`, +`greaterThan`, +`lessThan`, +`equals`, +`notEquals`, +`matches`, +`notMatches`, +`contains`, +`notContains`, +`colNotExists`, +`isDateTime`, +`dmTypeEquals`, +`dmTypeNotEquals`, +`dmMeasurementEquals`, +`dmMeasurementNotEquals`, +`dmRoleEquals`, +`dmRoleNotEquals` +`lengthEquals`, +`lengthGreaterThan`, +`lengthLessThan`. + - `parameter_ref` (*string*) **Required** The primary parameter. + - `parameter_2_ref` (*string*) Second parameter for multi-parameter validation. + - `value` (*string, boolean, number*) Value against which to compare the primary parameter value. + - `values` (*array[string]*) Values against which to compare the primary parameter value is in. Used only in `filter` conditions. + + `or` (*object*) This is a container of 'or' conditions. Evaluates to true if ANY sub-condition evaluates to true. Can nest any number of additional conditional types. + + `and` (*object*) This is a container of 'and' conditions. Evaluates to true if ALL sub-condition evaluates to true. Can nest any number of additional conditional types. + +## Enabled definition +Enablement test. Disables controls if evaluate is false. + +The attributes for the enabled definition are: +* `parameter_refs` (*array[string]*) Array of parameter names affected by this operation. If evaluate is false, then the controls associated with these parameters are disabled. Note that individual radio buttons can be disabled by using the radio button value name instead of the overall property name in the parameter_refs array. +* `action_refs` (*array[string]*) Array of action names affected by this operation. If evaluate is false, then the action button or image associated with these action names are disabled. +* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. + +## Visible definition +Visibility test. Hides controls if evaluate is false. + +The attributes for the visible definition are: +* `parameter_refs` (*array[string]*) Array of parameter names affected by this operation. If evaluate is false, then hide the controls associated with these parameters. +* `action_refs` (*array[string]*) Array of action names affected by this operation. If evaluate is false, then the action button or image associated with these action names are disabled. +* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. + +## Filter definition +Filter test. The filter will determine which data record fields to include in a control. + +The attributes for the filter definition are: +* `parameter_ref` (*string*) Parameter id affected by this operation. This must be a parameter that operates upon datarecord-metadata columns. +* `parameter_refs` (*string*) Exclusive with `parameter_ref` and used with `dmSharedFields`. Parameter ids affected by this operation. They must be parameters that operate upon datarecord-metadata columns. +* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. + +Supported operations (`op`): +* `dmType` - filters `type` value from schema. +* `dmMeasurement` - filters `measurement` value from schema. +* `dmModelingRole` - filters `modeling_role` value from schema. +* `dmSharedFields` - shares source fields with all field chooser property names found in the `parameter_refs` array. + +**Examples**: +```js +{ + "filter": { + "parameter_ref": "fields_filter_measurement", + "evaluate": { + "condition": { + "op": "dmMeasurement", + "value": "discrete" + } + } + } +} +``` +```js +{ + "filter": { + "parameter_ref": "fields_filter_type", + "evaluate": { + "condition": { + "op": "dmType", + "values": ["integer", "double"] + } + } + } +} +``` +```js +{ + "filter": { + "parameter_refs": [ + "fields_filter_type", + "multi_field_chooser_table", + "field_chooser_in_another_panel" + ], + "evaluate": { + "condition": { + "op": "dmSharedFields" + } + } + } +} +``` + +## Enum Filter definition +Filters the available options for enumeration parameters. Reduces the available enumeration items if evaluate is true. + +The attributes for the enum_filter definition are: +* `target` (*object*) Contains a target *parameter_ref* reference and a replacement *values* array. +* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. + +**Example**: +```js +{ + "enum_filter": { + "target": { + "parameter_ref": "radioset_filtered", + "values": [ + "red", + "yellow", + "green" + ] + }, + "evaluate": { + "condition": { + "parameter_ref": "filter_radios", + "op": "equals", + "value": true + } + } +} +``` + +## Allow Change definition +Allow change validates that a change is allowed on a property. If it evaluates to true then the value for the property is changed. This is typically used to restrict values that are invalid in one property based on the value in another property. For example, if the property represents a storage type with a value of `string`, then a property that represents a measurement type should not be allowed to be set to `continuous`. + +The attributes for the allow_change definition are: +* `parameter_refs` (*array[string]*) Array of parameter names affected by this operation. +* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. + +**Example**: +```js +{ + "allow_change": { + "parameter_refs": [ + "ST_mse_table[2]" + ], + "evaluate": { + "or": [ + { + "condition": { + "parameter_ref": "ST_mse_table[2]", + "op": "notEquals", + "value": "Football" + } + }, + { + "condition": { + "parameter_ref": "ST_mse_table[5]", + "op": "notEquals", + "value": "European" + } + } + ] + } + } + } +``` + +## Default value definition +Sets the default value on the `parameter_ref` property if condition evaluates to true. If multiple conditions evaluate to true only the first condition is used. Default value condition is evaluated only once when loading properties. If user updates the value of `parameter_ref`, default value will be overwritten by the new value. + +The attributes for the default_value definition are: +* `parameter_ref` (*string*) Parameter whose default value is to be set. +* `value` (*string, boolean, number, object, array*) This will be the default value of parameter_ref if condition evaluates to true. +* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. + +**Example**: +```js +{ + "default_value": { + "parameter_ref": "conditional_default", + "value": "Value defined in default_value condition. You will see this sentence when default value of mode equals Include.", + "evaluate": { + "condition": { + "parameter_ref": "mode", + "op": "equals", + "value": "Include" + } + } + } +}, +{ + "default_value": { + "parameter_ref": "conditional_default", + "value": ["This is a second condition for conditional_default. You should never see this value."], + "evaluate": { + "condition": { + "parameter_ref": "mode", + "op": "equals", + "value": "Include" + } + } + } +} +``` + + +## A note on table cell conditions +Support for table cell conditions is achieved via the use of the array subscript operator, `[]`. When evaluating table cells, one uses the table identifier with an array subscript indicating the zero-based table column being operated upon (which also corresponds to the sub-control index as defined in `complex_types`). + +So for example if one has a StructureTable property named _myTable_, column conditions on that table are referred to using `myTable[1]`, `myTable[3]`, etc. + +## Example + +Example of a condition section. +```js + "conditions": [ + { + "validation": { + "fail_message": { + "type": "error", + "focus_parameter_ref": "inputFieldList", + "message": { + "resource_key": "input_field_list_not_empty" + } + }, + "evaluate": { + "condition": { + "parameter_ref": "inputFieldList", + "op": "isNotEmpty" + } + } + } + }, + { + "visible": { + "parameter_refs": [ + "oneofselectPets" + ], + "evaluate": { + "condition": { + "parameter_ref": "oneofselectAnimals", + "op": "notContains", + "value": "lion" + } + } + } + }, + { + "visible": { + "action_refs": [ + "action_button" + ], + "evaluate": { + "condition": { + "parameter_ref": "button_hide_checkbox", + "op": "equals", + "value": false + } + } + } + }, + { + "enabled": { + "parameter_refs": [ + "radiosetColor" + ], + "evaluate": { + "condition": { + "parameter_ref": "checkboxEnable", + "op": "checked" + } + } + } + }, + { + "validation": { + "fail_message": { + "type": "error", + "focus_parameter_ref": "subsamplingRate", + "message": { + "resource_key": "subsampling_rate_not_valid" + } + }, + "evaluate": { + "and": [ + { + "condition": { + "parameter_ref": "subsamplingRate", + "op": "greaterThan", + "value": 0 + } + }, + { + "or": [ + { + "condition": { + "parameter_ref": "subsamplingRate", + "op": "lessThan", + "value": 1 + } + }, + { + "condition": { + "parameter_ref": "subsamplingRate", + "op": "equals", + "value": 1 + } + } + ] + } + ] + } + } + }, + { + "enabled": { + "parameter_refs": [ + "field_types[2]" + ], + "evaluate": { + "condition": { + "parameter_ref": "field_types[1]", + "op": "checked" + } + } + } + } + } + ] +``` \ No newline at end of file diff --git a/guide/3.5-Common-Properties-Custom-Components.md b/guide/3.5-Common-Properties-Custom-Components.md new file mode 100644 index 0000000000..e57655740a --- /dev/null +++ b/guide/3.5-Common-Properties-Custom-Components.md @@ -0,0 +1,177 @@ +# Custom Components Overview +Custom components allows applications to use custom code to drive different parts of the common-properties user interface. For some panels and controls it might be necessary to listen to different types of redux state changes to cause the panel/control to rerender. +Here is an example of a textfield listening to 3 state changes: +```js +import { connect } from "react-redux"; + +// ... application code + +render() { + const value = this.props.value; // value passed by redux as a property + + // ... rest of component render code + +} + +TextfieldControl.propTypes = { + // ... application props + state: PropTypes.string, // pass in by redux + value: PropTypes.string, // pass in by redux + messageInfo: PropTypes.object // pass in by redux +}; + +const mapStateToProps = (state, ownProps) => ({ + value: ownProps.controller.getPropertyValue(ownProps.propertyId), + state: ownProps.controller.getControlState(ownProps.propertyId), + messageInfo: ownProps.controller.getErrorMessage(ownProps.propertyId) +}); +export default connect(mapStateToProps, null)(TextfieldControl); +``` + + +## Custom Panels +Custom panels allow applications to create their own panels and controls that can live in the same dialogs as common-property panels and controls. + +### Custom panel interface +```js +// Returns the 'id' for the group defined in uihints +static id() + +constructor(parameters, controller, data) + +// Returns the content users want to display +renderPanel() +``` +- **parameters** - String array of parameters set under the customPanel group in uihints +- **controller** - See [here](/3.6-Common-Properties-Controller) for API information. +- **data** - Optional parameter. Returns values stored in `data` attribute of a group `customPanel`. +- **renderPanel()** - Called on all Redux store changes: + - property value changes ([property APIs](/3.6-Common-Properties-Controller#property-methods)) + - state changes ([state APIs](/3.6-Common-Properties-Controller#state-methods-disableenabled--hiddenvisible)) + - schema changes ([schema APIs](/3.6-Common-Properties-Controller#datasetmetadata-methods)) + - row selection changes ([selection APIs](/3.6-Common-Properties-Controller#row-selection-methods)) + - messages changes ([message APIs](/3.6-Common-Properties-Controller#message-methods)) + +### Custom react components + +Example +```js +renderPanel() { + const controlId = this.parameters[0]; + return ( + + ); +} +``` + +### Examples +https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/src/client/components/custom-panels + + +## Custom Controls +Custom controls allow applications to create their own controls that can live in the same dialogs as common-property panels and controls. + +### Custom control interface +```js +// Returns the 'custom_control_id' for the parameter defined in uihints +static id() + +constructor(propertyId, controller, data, tableInfo) + +// Returns the content users want to display +renderControl() +``` +- **propertyId** - See [propertyId](/3.6-Common-Properties-Controller#common-properties-controller-api) for definition. +- **controller** - See [here](/3.6-Common-Properties-Controller) for API information. +- **data** - Returns values stored in `data` attribute of a parameter in uihints. +- **tableInfo** - Set when custom control is a cell in a table. + - table (boolean) Set to true when in a table cell + - editStyle (string) Valid values are "summary" and "inline". "summary" is set when the control will display either below the table ("on_panel") or in a "subpanel". This allows the custom control to display a summary value in the cell and something else for the custom control. +- **renderControl()** - Called on all Redux store changes: + - property value changes ([property APIs](/3.6-Common-Properties-Controller#property-methods)) + - state changes ([state APIs](/3.6-Common-Properties-Controller#state-methods-disableenabled--hiddenvisible)) + - schema changes ([schema APIs](/3.6-Common-Properties-Controller#datasetmetadata-methods)) + - row selection changes ([selection APIs](/3.6-Common-Properties-Controller#row-selection-methods)) + - messages changes ([message APIs](/3.6-Common-Properties-Controller#message-methods)) + +### Custom react components + +Example +```js +renderControl() { + return ( + + ); +} +``` + +### Examples +https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/src/client/components/custom-controls + +## Custom Condition Operators +Custom condition operators allow users to create their own operators that can then be used for enablement, visibility, validation, and enum filtering. The condition operators should always return a `boolean` value. + +### Custom operator interface + +```js +/** +* This is the key used to determine if the operator should be ran. Maps to the `op` defined in the +* `condition` in uihints +* @return string +*/ +function op() + +/** +* @param see below +* @return boolean +*/ +function evaluate(paramInfo, param2Info, value, controller) +``` +- paramInfo (object) - `parameter_ref` set in the `condition` in uihints + - control (object) - contains information about the control. + - value (any) - current property value +- param2Info (object) - `parameter_2_ref` set in the `condition` in uihints. See `paramInfo` for object info +- value - `value` set in the `condition` in uihints. If no value specific this will be `undefined` +- **controller** - See [here](/3.6-Common-Properties-Controller) for API information. + +Example +```js +function op() { + return "customMax"; +} + +function evaluate(paramInfo, param2Info, value, controller) { + const supportedControls = ["numberfield"]; + if (supportedControls.indexOf(paramInfo.control.controlType) >= 0) { + return paramInfo.value < value; + } + return true; +} + +module.exports.op = op; +module.exports.evaluate = evaluate; +``` +```json +{ + "evaluate": { + "condition": { + "parameter_ref": "custom_op_num", + "op": "customMax", + "value": 100 + } + } +} +``` + +### Examples +https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/src/client/custom/condition-ops +https://github.com/elyra-ai/canvas/tree/master/canvas_modules/common-canvas/src/common-properties/ui-conditions/condition-ops + diff --git a/guide/3.6-Common-Properties-Controller.md b/guide/3.6-Common-Properties-Controller.md new file mode 100644 index 0000000000..908b7dd569 --- /dev/null +++ b/guide/3.6-Common-Properties-Controller.md @@ -0,0 +1,336 @@ +## Common Properties Controller API + +**propertyId** +```js +const propertyId = { + name: {parameter name defined in operator definition}, + row: {row in table/array}, // optional when col not set + col: {col in table}, // optional + propertyId: {propertyId of the nested structure} // optional +} +``` +### Property methods +```js +setPropertyValues(values) +updatePropertyValue(propertyId, value) +/* + * options - optional object of config options where + * filterHiddenDisabled (boolean): when set to true, filter out data values with a state of disabled or hidden + * filterHiddenControls (boolean): when set to true, filter out data values having control type hidden + * applyProperties (boolean): when set to true, will return data values in the format expected by the `applyPropertyChanges` callback. If unset or false, will return the internal format used by common properties. +*/ +getPropertyValue(propertyId, options) +/* + * options - optional object of config options where + * filterHiddenDisabled (boolean): when set to true, filter out data values with a state of disabled or hidden + * filterHiddenControls (boolean): when set to true, filter out data values having control type hidden + * applyProperties (boolean): when set to true, will return data values in the format expected by the `applyPropertyChanges` callback. If unset or false, will return the internal format used by common properties. +*/ +getPropertyValues(options) +``` +### Message methods +```js +/* + * Returns current list of error messages + * @filteredPipeline (boolean) optional + * @filterHiddenDisable (boolean) optional. If true, will not return error messages from controls that are hidden or disabled + * @filterDisplayError (boolean) optional. If true, will not return error messages that are not displayed in the editor + * when filteredPipeline=true returns enabled/visible control messages and only 1 per control. + */ +getAllErrorMessages() +getErrorMessages(filteredPipeline, filterHiddenDisable, filterSuccess, filterDisplayError = true) +getErrorMessage(propertyId, filterHiddenDisable = false, filterSuccess = false, filterDisplayError = true) +getRequiredErrorMessages() +setErrorMessages(messages) +updateErrorMessage(propertyId, message) + + +``` +### State methods (disable/enabled & hidden/visible) +```js +getControlState(propertyId) +getControlStates() +setControlStates(states) + +/* + * @propertyId - see above + * @state - valid values are "enabled", "disabled", "visible", "hidden" + */ +updateControlState(propertyId, state) +``` +### DatasetMetadata methods +```js +getDatasetMetadata() + +/* + * @datasetMetadata - see [schema](https://github.com/elyra-ai/pipeline-schemas/blob/master/common-pipeline/datarecord-metadata/datarecord-metadata-v1-schema.json) + */ +setDatasetMetadata(datasetMetadata) +``` + +### Row selection methods +```js +/* + * Returns table row selection indices as an array of integers. + * @propertyId - see above + */ +getSelectedRows(propertyId) + +/* + * Updates table row selections for the given table control. + * @propertyId - see above + * @selection - A zero-based array of integer selection indices + */ +updateSelectedRows(propertyId, selection) + +/* + * Clears selected table rows for the given table. + * @propertyId - see above + * If the propertyId is omitted all table row selections are cleared + */ +clearSelectedRows(propertyId) + +/* + * Adds a row selection listener for a table or list. + * @propertyId - see above + * @listener - callback function for when a selection is made in the table or list + */ +addRowSelectionListener(propertyId, listener) + +/* + * Removes the row selection listener from a table or list. + * @propertyId - see above + */ +removeRowSelectionListener(propertyId) +``` + +### Validation methods + +```js +/* + * Runs validation conditions on all controls + */ +validatePropertiesValues() + + + +/* + * Validates a specific propertyId + * @propertyId - see above + */ +validateInput(propertyId) +``` + +### Control methods +```js +/* + * Update the enum values for a given control. Used when enum values aren't static + * @propertyId - see above + * @valuesObj (array) [{ value: , label: "" }] + */ +updateControlEnumValues(propertyId, valuesObj) +``` + +### General methods +```js +/* +* Returns the current size of the RHS flyout. +*/ +getEditorSize() + +/* +* Sets default property values from parameter definition in the propertiesController. +* Note - These values won't be displayed on the UI. Host applications can call getPropertyValues() to retrieve the values. +* @paramDef - Follows the format of https://github.com/elyra-ai/pipeline-schemas/blob/master/common-canvas/parameter-defs/parameter-defs-v3-schema.json +*/ +setParamDef(paramDef) +``` + +### Disable move row buttons methods +```js +/** + * Disable table row move buttons for all propertyIds in given array + * @param propertyIds Array of propertyIds + * + */ +setDisableRowMoveButtons(propertyIds) +/** +* Returns array of propertyIds for which row move buttons will be disabled +* @return Array of propertyIds +*/ +getDisableRowMoveButtons() +/** +* Check if row move buttons should be disabled for given propertyId +* @param propertyId The unique property identifier +* @return boolean +*/ +isDisableRowMoveButtons(propertyId) +``` + + +### Custom panel and control methods +```js +/* + * Only used in custom panel to allow for custom property summary values to be displayed + * Displays the value set in propertiesReducer for that parameter + * @propertyId - see above + * @label (string) + * @inSummary (boolean) + */ +setControlInSummary(propertyId, label, inSummary) + +/* + * Sets the content to be displayed in the summaryPanel for a customPanel property. + * The summary panel will directly display the content. + * @propertyId - see above + * @content = { value: , label: "" } + */ +updateCustPropSumPanelValue(propertyId, content) + +/* + * Returns a standard control that can then be used in a customPanel. + * @propertyId - See above + * @paramDef - Follows the format of https://github.com/elyra-ai/pipeline-schemas/blob/master/common-canvas/parameter-defs/parameter-defs-v1-schema.json). titleDefinition, current_parameters, conditions, dataset_metadata are ignored and are optional. + * @parameter - This is the parameter from the paramDef to create the control for. + */ +createControl(propertyId, paramDef, parameter) + +/* + * Returns the translated text for a control given a resource key. + * Users should be able to use the values from resources that has been uploaded as part of paramDef. + * @key - Resource key + * @value - Default value returned when no resource or key has been found. + */ +getResource(key, value) + +``` + +### maxLength for single-line and multi-line control methods +```js +/* + * Returns the maximum characters allowed for multi-line string controls + * Default value is 1024 + */ +getMaxLengthForMultiLineControls() + +/* + * Returns the maximum characters allowed for single-line string controls + * Default value is 128 + */ +getMaxLengthForSingleLineControls() +``` + +### Enabling/disabling addRemoveRows methods +```js +/* + * Set the addRemoveRows attribute to 'enabled' for the given propertyId + * @param propertyId The unique property identifier + * @param enabled boolean value to enable or disable addRemoveRows + */ +setAddRemoveRows(propertyId, enabled) + +/* + * Returns the true if addRemoveRows is enabled for the given propertyID + * @param propertyId The unique property identifier + * @return boolean + */ +getAddRemoveRows(propertyId) +``` + +### Enabling/disabling properties editor "save" button methods +```js +/* + * Set the main "save" button to disabled(true) or enabled(false) + * @param saveDisable (boolean) + */ +setSaveButtonDisable(saveDisable) + +/* + * Returns the true if the main "save" button is disabled, false otherwise + * @return boolean + */ +getSaveButtonDisable() +``` + + +### Add static rows for table controls which will disable the re-ordering of the rows that are set as static for the given propertyId +```js +/* + * Set static rows for the given propertyId + * @param propertyId The unique property identifier + * @param staticRowsArr Array of first n row indexes or last n row indexes + */ +updateStaticRows(propertyId, staticRowsArr) + +/* + * Returns the static rows set for the given propertyId + * @param propertyId The unique property identifier + */ +getStaticRows(propertyId) + +/* + * Removes the static rows set for the given propertyId + * @param propertyId The unique property identifier + */ +clearStaticRows(propertyId) +``` + +### Enabling/disabling custom table buttons +```js +/* + * Set the table button to 'enabled' for the given propertyId + * @param propertyId The unique property identifier + * @param buttonId The unique button identifier + * @param enabled boolean value to enable or disable the button + */ +setTableButtonEnabled(propertyId, buttonId, enabled) + +/* + * Returns the table button states for the given propertyID + * @param propertyId The unique property identifier + * @return object An object of buttonIds mapped to their enabled state + */ +getTableButtons(propertyId) + +/* + * Returns the true if the table button is enabled for the given propertyID and buttonId + * @param propertyId The unique property identifier + * @param buttonId The unique button identifier + * @return boolean + */ +getTableButtonEnabled(propertyId, buttonId) +``` + + +### Column visibility methods +```js +/* + * Check if given column is visible in the table + * @param propertyId The unique property identifier + * @param columnIndex Column index in the table + */ +getColumnVisibility(propertyId, columnIndex) + +/* + * Set column visibility + * @param propertyId The unique property identifier + * @param columnIndex Column index in the table + * @param value Boolean value to set column visible/invisible + */ +toggleColumnVisibility(propertyId, columnIndex, value) +``` + +### Enabling/disabling wide flyout "OK" button methods +```js +/** +* Set the "OK" button in Wide Flyout to disabled(true) or enabled(false) for given summary panel +* @param panelId {name: panel.id} +* @param wideFlyoutPrimaryButtonDisable boolean +*/ +setWideFlyoutPrimaryButtonDisabled(panelId, wideFlyoutPrimaryButtonDisable) + +/** +* @param panelId {name: panel.id} +*/ +getWideFlyoutPrimaryButtonDisabled(panelId) +``` \ No newline at end of file diff --git a/guide/4.0-Accessibility.md b/guide/4.0-Accessibility.md new file mode 100644 index 0000000000..5fd27c0020 --- /dev/null +++ b/guide/4.0-Accessibility.md @@ -0,0 +1,3 @@ +## Tips +- All input elements need to have a visual indication `focus` is set. This is different then selection. +- Use the correct html element for inputs. For example don't use a `div` with a click event. Use a `button` or `a` instead. \ No newline at end of file diff --git a/guide/5.0-Styling.md b/guide/5.0-Styling.md new file mode 100644 index 0000000000..cdc82431ad --- /dev/null +++ b/guide/5.0-Styling.md @@ -0,0 +1,54 @@ +## Overriding Styles and Color Themes + +### CSS styling for quick start + +If you just want to get up and running and don't care about scss then import these regular css files: + - carbon-components/css/carbon-components.min.css + - @elyra/canvas/dist/styles/common-canvas.min.css + - version 8.x and older @elyra/canvas/dist/common-canvas.min.css + +More information about carbon components can be found here http://www.carbondesignsystem.com/getting-started/developers + + +### SCSS styling (recommended) + +If you want to use the full power of scss styling with variable overrides etc then include these imports in your main scss file: +```sass +@import "carbon-components/scss/globals/scss/styles"; +@import "@elyra/canvas/src/index.scss"; +``` + - use `autoprefixer` when building + - if using webpack under the `sass-loader` and make sure to include +```js +options: { includePaths: ["node_modules"] } +``` +Again, you can refer to the test harness [index.scss file](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/styles/index.scss) for sample code. + + +### Loading Fonts +You may find that there is a pause in common canvas behavior, such as when the context menu is first displayed, which is caused by fonts being loaded. This can be fixed by adding the following to the `.scss` file for your application: +``` +$font-path: "/fonts"; +@import "carbon-components/scss/globals/scss/styles"; +``` +The fonts will need to be imported from carbon before carbon styles and placed in a public `/fonts` directory. +You can see an example of this in the common-canvas test harness (which is the equivalent of a host application) in this repo. That is, the [index.scss file](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/styles/index.scss) contains the lines above and the grunt build files ensures the fonts are copied from`node_modules/carbon-components/src/globals/` to the `` directory. + + +### 3rd party styling + +If you are using the expression builder in common-properties then also include these libraries: + - codemirror/addon/hint/show-hint.css + - codemirror/lib/codemirror.css + +If you are using common-properties then also include the react-virtualized styles: + - react-virtualized/styles.css + +## Elyra Canvas styling guidelines +- Used the `data-id` attribute on inputs to be used for automated tests. Format for common properties should be `properties-` +- **className** format format for common-properties should be `properties-` +- Limit the use of html(DOM) ids +- Minimum inline styling. This allows for consumers to easily override styling. +- scss/sass styling should be added to the component's folder +- No `important!` in styling +- Use variables for all colors(preferably from carbon) diff --git a/guide/6.0-Testing-Guidelines-for-Development.md b/guide/6.0-Testing-Guidelines-for-Development.md new file mode 100644 index 0000000000..f524c3d632 --- /dev/null +++ b/guide/6.0-Testing-Guidelines-for-Development.md @@ -0,0 +1,52 @@ +# Testing Guidelines for Development +## Unit Testing +The Canvas unit tests are automated with the primary purpose of providing rapid feedback to the developers. The test cases are run during every development build. Unit test cases are written using Jest [Jest Tutorial](https://facebook.github.io/jest/docs/en/tutorial-react.html). The test cases should be written and delivered at the time that a feature or enhancement is delivered. + +Unit test cases should focus on good coverage of a function/service. We are current investigating code coverage analysis tools and will update this doc when it is implemented. + +Unit test case coverage should focus on these areas: + + * All APIs and all UI elements. + * All component properties. + * A variety of input data. + +Here is a good blog on [JavaScript Unit Testing](https://medium.com/javascript-scene/what-every-unit-test-needs-f6cd34d9836d) + + +## Functional Testing +The Canvas Functional Test cases will be automated and run during code delivery. The function test case will be automated and written using [Cypress](https://docs.cypress.io). + +Functional Testing coverage includes the following types of tests. + +* Core functionality +* Inter-operate with other Canvas elements. +* Need to test both forward and backwards compatibility +* Negative / bounds +* Globalization / Localization + * Handling of all strings using UTF-8 + * Verifying non-English unicode data is handled appropriately + * Externalizing all strings that may be presented for the user (e.g., error messages, UI labels, etc.) +* Access control security (roles / permissions / tenant management) +* Malicious and security (code scans such as AppScan, ethical hacking) +* Accessibility for UI + +## Debugging Tests + +### Jest tests (unit) +https://facebook.github.io/jest/docs/troubleshooting.html + +**With node 8 or newer** +- Add `debugger;` statement to your Jest test suite program where you want to stop and begin debugging. +- If you want to run just a single test within your test program (rather than all of them) temporarily change the it() method for the test to be it.only(). For example, change: + + `it("should add a node", () => { ... })` + + to be: + + `it.only("should add a node", () => { ... })` + +- In the console enter: `npm run debug` or `npm run debug ` +- Open Chrome debugging tools by pasting this into the Chrome address field: [chrome://inspect/](chrome://inspect/#devices) +- You should see a 'remote' target for `node_modules/.bin/jest`. Click on the `inspect` link below it. +- Click on sources and then click the play button (right pointing blue triangle icon). +- The code should run to the point where your debugger statement was added. diff --git a/guide/css/styles.css b/guide/css/styles.css new file mode 100644 index 0000000000..675155171d --- /dev/null +++ b/guide/css/styles.css @@ -0,0 +1,7 @@ +th { + font-weight: bold; +} + +.md-grid { + max-width: initial; +} \ No newline at end of file diff --git a/guide/images/DELETEME b/guide/images/DELETEME new file mode 100644 index 0000000000..0fa15e4e80 --- /dev/null +++ b/guide/images/DELETEME @@ -0,0 +1 @@ +Images for the guide go here. \ No newline at end of file diff --git a/guide/index.md b/guide/index.md new file mode 100644 index 0000000000..fbb3d8dda6 --- /dev/null +++ b/guide/index.md @@ -0,0 +1,90 @@ +# Welcome to the Elyra Canvas Wiki + +The elyra-ai/canvas repo contains three main components: + +* [Common Canvas](/2.0-Common-Canvas-Documentation/) - This contains canvas functionality which is packaged into the [elyra/canvas NPM module](https://www.npmjs.com/package/@elyra/canvas) and deployed on the NPM registry. It provides a way for an application to display a flow of data operations (shown as a set of nodes connected with links) defined in a pipeline flow JSON document, to the user and to allows the user to interact with the display to modify the flow. Common canvas is a react component which can be imported, and is assisted by a regular JavaScript class called `CanvasController` which provides an API and handles the internal data model of the flow. Common canvas is highly customizable where node shape and appearance, colors, styles layout etc can all be customized by your application code. + +* [Common Properties](/3.0-Common-Properties-documentation/) - This contains properties functionality which is packaged into the [elyra/canvas NPM module](https://www.npmjs.com/package/@elyra/canvas) and deployed on the NPM registry. It provides a way to translate a JSON document, which describes a set of properties with UI hints, into working properties dialog panel. Common properties is a react component and has an associated properties controller object. + +* [Test Harness](https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness#test-harness) - This provides a node.js app which displays a UI which allows you to try out various features of the common canvas and common properties components. Bear in mind this is not supposed to be a fully functional app but is, as the name suggests, a framework for testing. To get select one of the sample applications or select `None` as the sample app and then select a test canvas file from the `Canvas Diagram` drop down list and a test palette from the `Canvas palette` drop down list. + +## Installation + +You'll need to build your application with common canvas. + +* common-canvas requires react, react-dom, react-intl, and react-redux libraries to be installed. See peerDependencies in package.json for versions requirements. + +Use the command: +```sh +npm install @elyra/canvas --save-dev +``` +or add this to your package.json file: + +``` + "@elyra/canvas": "x.x.x" +``` +where x.x.x is the latest build and then run: +```sh +npm install +``` + +## Localization +You must wrapper `` and `` in an `` object. + +If you want to display translated text, the sample code below shows how `` should be initialized. Your code can set `this.locale` to indicate which language should override the default which, in this sample code, is set to English `en`. The default locale will be used if `this.locale` is set to a language which is not currently supported. + +If you want to provide translations for your own application's text you can import your own bundles and load them into the `this.messages` object along with the common canvas and common properties text. If you do this you will have to move `` so that it wrappers your React objects as well as `` and/or ``. + +```js +import { IntlProvider } from "react-intl"; +import CommandActionsBundles from "@elyra/canvas/locales/command-actions/locales"; +import CommonCanvasBundles from "@elyra/canvas/locales/common-canvas/locales"; +import CommonPropsBundles from "@elyra/canvas/locales/common-properties/locales"; +import PaletteBundles from "@elyra/canvas/locales/palette/locales"; +import ToolbarBundles from "@elyra/canvas/locales/toolbar/locales"; + +class App extends React.Component { + +constructor() { + this.locale = "en"; + // Create messages object once (here in constructor) - do not create messages + // in the render method, otherwise unnecessary renders inside + // common-canvas/common-properties will be performed. + this.messages = this._getMessages( + this.locale, + [CommandActionsBundles, CommonCanvasBundles, CommonPropsBundles, + PaletteBundles, ToolbarBundles] + ); +} + +_getMessages(locale, bundles) { + const messages = {}; + for (const bundle of bundles) { + Object.assign(messages, bundle[locale]); + } + return messages; +} + +render() { + + {Add your or element here.} + +} +``` + +## Notes +When building your application you will need to load fonts and override styles can be found here: +/5.0-Styling + +## Testing +When testing your application with Jest, this error might show up: `crypto.getRandomValues() not supported`. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported for details. + +To fix, added this to your jest setup file: +```js +const cryptoJest = require("crypto"); +Object.defineProperty(global.self, "crypto", { + value: { + getRandomValues: (arr) => cryptoJest.randomBytes(arr.length) + } +}); +``` diff --git a/guide/js/links-in-new-tabs.js b/guide/js/links-in-new-tabs.js new file mode 100644 index 0000000000..f269f65134 --- /dev/null +++ b/guide/js/links-in-new-tabs.js @@ -0,0 +1,10 @@ +// This takes any external links and adds _blank to make sure they open in a new tab. Links to other +// pages within the documentation will remain in the same tab +// Source: https://stackoverflow.com/questions/4425198/can-i-create-links-with-target-blank-in-markdown#answer-4425214 + +var links = document.links; +for (var i = 0, linksLength = links.length; i < linksLength; i++) { + if (links[i].hostname != window.location.hostname) { + links[i].target = '_blank'; + } +} diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000000..9c86144342 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,78 @@ +site_name: Elyra Guide +repo_url: https://github.com/elyra-ai/canvas +docs_dir: guide + +theme: + name: material + highlightjs: true + palette: + scheme: default + features: + - content.code.copy + - content.action.edit + +plugins: + - search + - awesome-pages + +extra_css: + - css/styles.css + +extra_javascript: + - js/links-in-new-tabs.js + +edit_uri: edit/main/guide/ + +# Documentation and theme +copyright: 'Copyright © 2023 IBM Watson Team, an open source project and all are welcome to contribute!
Maintained by the SPSS Modeler Team' + +nav: + - Home: index.md + - Common Canvas Documentation: 2.0-Common-Canvas-Documentation.md + - Canvas Editor: 2.0.1-Canvas-Editor.md + - Palette: 2.0.2-Palette.md + - Context Menu: 2.0.3-Context-Menu.md + - Context Toolbar: 2.0.4-Context-Toolbar.md + - Config Objects: 2.1-Config-Objects.md + - Common Canvas Callbacks: 2.2-Common-Canvas-callbacks.md + - Enabling Node Creation from External Object: 2.3-Enabling-node-creation-from-external-object.md + - Canvas Controller API: 2.4-Canvas-Controller-API.md + - Calling the Canvas Controller API: 2.4.0-Calling-the-Canvas-Controller-API.md + - Style Specification: 2.4.1-Style-Specification.md + - Decoration Specification: 2.4.2-Decoration-Specification.md + - Object Structure used by API: 2.4.3-Object-structure-used-by-API.md + - Notification Message Specification: 2.4.4-Notification-Message-Specification.md + - Programmatically Creating new Canvas Nodes: 2.4.5-Programmatically-creating-new-canvas-nodes.md + - Constructing a Read Only or Locked Canvas: 2.4.6-Constructing-a-read-only-or-locked-canvas.md + - Commmand Stack API: 2.5-Command-Stack-API.md + - Flow Validation API: 2.6-Flow-Validation-API.md + - Customizing Node Layout Properties: 2.7-Customizing-Node-Layout-Properties.md + - Context Menu Wrapper Documentation: 2.8-Context-Menu-Wrapper-Documentation.md + - External Subflows Support: 2.9-External-Subflows-support.md + - Common Properties Documentation: 3.0-Common-Properties-documentation.md + - Common Properties Parameter Definition: 3.1-Common-Properties-Parameter-Definition.md + - Common Properties UI Hints: 3.2-Common-Properties-UI-Hints.md + - Common Properties Controls: 3.3-Common-Properties-Controls.md + - Common Properties Conditions: 3.4-Common-Properties-Conditions.md + - Common Properties Custom Components: 3.5-Common-Properties-Custom-Components.md + - Common Properties Controller: 3.6-Common-Properties-Controller.md + - Accessibility: 4.0-Accessibility.md + - Styling: 5.0-Styling.md + - Testing Guidelines for Development: 6.0-Testing-Guidelines-for-Development.md + +markdown_extensions: + - admonition: + - codehilite: + - extra: + - pymdownx.magiclink: + - pymdownx.inlinehilite: + - pymdownx.highlight: + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format + - sane_lists: + - smarty: + - toc: + permalink: True diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000..80c8e8446b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +mkdocs-material +mkdocs-awesome-pages-plugin From 559de91bb052a92b4afaa539f36b2317fce82b09 Mon Sep 17 00:00:00 2001 From: srikant Date: Mon, 19 Feb 2024 20:24:25 +0530 Subject: [PATCH 02/20] #1701 : New Elyra Canvas Documentation using mkdocs setup Signed-off-by: srikant --- guide/2.0-Common-Canvas-Documentation.md | 19 ++-- guide/2.0.1-Canvas-Editor.md | 12 ++- guide/2.0.1.1-Nodes.md | 1 + guide/2.0.1.2-Links.md | 62 +++++++++++++ guide/2.0.2-Palette.md | 2 + guide/2.0.4-Context-Toolbar.md | 3 +- guide/2.1-Config-Objects.md | 45 +++++++-- guide/2.2-Common-Canvas-callbacks.md | 88 ++++++++++++------ ...ling-node-creation-from-external-object.md | 6 +- guide/2.4-Canvas-Controller-API.md | 1 + guide/2.4.1-Style-Specification.md | 15 ++- guide/2.4.2-Decoration-Specification.md | 4 +- ....4.4-Notification-Message-Specification.md | 1 + ...nstructing-a-read-only-or-locked-canvas.md | 3 +- guide/2.5-Command-Stack-API.md | 26 ++++-- guide/2.6-Flow-Validation-API.md | 6 +- .../2.7-Customizing-Node-Layout-Properties.md | 25 ++++- .../2.8-Context-Menu-Wrapper-Documentation.md | 15 +-- guide/2.9-External-Subflows-support.md | 14 ++- guide/3.0-Common-Properties-documentation.md | 83 +++++++++-------- guide/3.2-Common-Properties-UI-Hints.md | 91 ++++++++++--------- guide/3.3-Common-Properties-Controls.md | 1 + guide/3.4-Common-Properties-Conditions.md | 14 ++- ...3.5-Common-Properties-Custom-Components.md | 31 ++++--- guide/3.6-Common-Properties-Controller.md | 17 +++- guide/5.0-Styling.md | 6 ++ .../6.0-Testing-Guidelines-for-Development.md | 7 +- mkdocs.yml | 2 + 28 files changed, 416 insertions(+), 184 deletions(-) create mode 100644 guide/2.0.1.1-Nodes.md create mode 100644 guide/2.0.1.2-Links.md diff --git a/guide/2.0-Common-Canvas-Documentation.md b/guide/2.0-Common-Canvas-Documentation.md index a785ba7640..a98fbbd221 100644 --- a/guide/2.0-Common-Canvas-Documentation.md +++ b/guide/2.0-Common-Canvas-Documentation.md @@ -1,6 +1,7 @@ -# Introduction +## Introduction Common canvas displays a flow of data operations as nodes and links which the user can create and edit to get the flow they want. These visual flows of data operations are translated into data processing steps performed by a back-end server. Common canvas provides functionality for the visual display of flows in the browser and leaves persistence and execution of data flows to the application. Within common canvas the user can perform operations such as: + * Create a new node by dragging a node definition from a palette onto the canvas. * Create a new node by dragging a node from outside the canvas onto the canvas (you'll have to do some programming to get this to work). * Delete a node by clicking a context menu option. @@ -17,6 +18,7 @@ Within common canvas the user can perform operations such as: Common-canvas is a react component that can be used in your react application to display a fully-functional canvas user interface including the function mentioned above. The `` component is displayed in a `
` provided by your application. Common-canvas has these constituent parts that are visible to the user: + * [Canvas editor](/2.0.1-Canvas-Editor/) - the main area of the UI where the flow is displayed and edited * [Palette](/2.0.2-Palette/) - a set of node templates that can be dragged to the canvas to create new nodes * [Context menu](/2.0.3-Context-Menu/) - a menu of options for nodes, comments, etc @@ -28,6 +30,7 @@ Common-canvas has these constituent parts that are visible to the user: * Bottom panel - a panel which can be used to display other app related information and it handles: + 1. the visual display of the flow of operations; 2. any user gestures on the canvas; 3. display of context menus; @@ -40,6 +43,7 @@ and it handles: The only mandatory parameter for the `` component is a regular JavaScript object called the [CanvasController](/2.4-Canvas-Controller-API/). The CanvasController routes handles calls from the host application and actions performed by the user. It then updates the internal object model which stores: + 1. the data that describes the flow of nodes, links and comments (called a pipelineFlow); 2. the data that describes the definition of the palette which contains node templates that can dragged to add nodes to the canvas; 3. the set of currently selected objects. @@ -124,8 +128,7 @@ Some examples of pipeline flow JSON files can be found here: https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/test_resources/diagrams ## Step 6 : Pull in the CSS -Check this section to find info on what CSS to include in your application's CSS. -/5.0-Styling +Check this section to find info on what CSS to include in your application's CSS. [Styling](./5.0-Styling.md). ## Step 7 : Display the canvas @@ -179,24 +182,27 @@ If you want to customize the behavior of common canvas you can specify any combi ### Config objects Common canvas has five **optional** configuration objects: config, toolbarConfig, notificationConfig, contextMenuConfig and keyboardConfig. They are documented here: -/2.1-Config-Objects +[Config Objects](/2.1-Config-Objects) ### Handlers There are several **optional** handlers implemented as callback functions. They are contextMenuHandler, editActionHandler, beforeEditActionHandler, clickActionHandler, decorationActionHandler, layoutHandler, tipHandler, idGeneratorHandler, selectionChangeHandler and actionLabelHandler. They are documented here: -/2.2-Common-Canvas-callbacks +[Common Canvas Callback](/2.2-Common-Canvas-callbacks) ### Right-flyout panel parameters The right flyout panel appears on the right of the canvas area. You can add whatever content you like to this panel. Typically, it is used to display properties of nodes on the canvas. There are two **optional** parameters to let you manage the right flyout panel These are: + - showRightFlyout: This can be true or false to indicate whether the flyout panel is shown or not. The default is false. - rightFlyoutContent: content to display in the right flyout which is a JSX object. Nothing is displayed by default. ### Bottom panel parameters The bottom panel appears below the canvas area and between the palette and the right flyout panel. You can add whatever content you like to this panel. There are two **optional** parameters to let you manage the bottom panel. These are: + - showBottomPanel: This can be true or false to indicate whether the bottom panel is shown or not. The default is false. - bottomPanelContent: content to display in the bottom panel which is a JSX object. Nothing is displayed by default. ### Top panel parameters The top panel appears below the toolbar and between the palette and the right flyout panel. You can add whatever content you like to this panel. There are two **optional** parameters to let you manage the top panel. These are: + - showTopPanel: This can be true or false to indicate whether the top panel is shown or not. The default is false. - topPanelContent: content to display in the top panel which is a JSX object. Nothing is displayed by default. @@ -206,11 +212,12 @@ You can customize `` using the `` object to [display ## Creating nodes on the canvas Nodes can be created on the canvas by the user in two ways: + * By dragging a node from the palette onto the canvas background * By dragging a node from outside the canvas The first technique is provided by Common canvas. The second requires some development work which is documented here: -/2.3-Enabling-node-creation-from-external-object +[Enabling node creation from external object](/2.3-Enabling-node-creation-from-external-object) ## Keyboard support diff --git a/guide/2.0.1-Canvas-Editor.md b/guide/2.0.1-Canvas-Editor.md index bedcb0af63..728db155b4 100644 --- a/guide/2.0.1-Canvas-Editor.md +++ b/guide/2.0.1-Canvas-Editor.md @@ -1 +1,11 @@ -[Under construction] \ No newline at end of file +The Canvas Editor displays the flow to the user and allows the user to interact with the flow using the mouse/trackpad and the keyboard. + +The editor displays the following object types which the user can interact with: + +## Nodes +## Links +## Comments +## The Canvas background + + +[Still under construction] \ No newline at end of file diff --git a/guide/2.0.1.1-Nodes.md b/guide/2.0.1.1-Nodes.md new file mode 100644 index 0000000000..bedcb0af63 --- /dev/null +++ b/guide/2.0.1.1-Nodes.md @@ -0,0 +1 @@ +[Under construction] \ No newline at end of file diff --git a/guide/2.0.1.2-Links.md b/guide/2.0.1.2-Links.md new file mode 100644 index 0000000000..1adca82cd6 --- /dev/null +++ b/guide/2.0.1.2-Links.md @@ -0,0 +1,62 @@ +## Introduction +Common-canvas is designed to display one link line on the canvas for each link defined in the pipeline flow. There are three types of link supported by common canvas: data links; association links; and comment links. Links can be enhanced by: + +* Overriding the CSS styles applied to the elements of the link line +* By specifying decorations for the link + +## Data Links +Data links are designed to model a flow from a source node to a target node. Data links are defined in the pipeline flow to connect a port on the source node to a port on the target node. The host application can choose whether or not to display ports on the nodes. Data links are typically displayed with an arrow head to display the flow along the link from source to target. + +If a data link is retrieved from the canvas controller API it will have the following important fields: + +* id - the unique identifier for the link. +* type - set to "nodeLink". +* srcNodeId - the ID of the node the link is connected from. +* srcNodePortId - the ID of the output port on the source node the link is connected from. Note: If this is undefined it indicates the node is connected to the first output port of the source node. +* trgNodeId - the ID of the node the link is connected to. +* trgNodePortId - the ID of the input port on the target node the link is connected to. Note: If this is undefined it indicates the node is connected to the first input port of the target node. +* decorations - an array of decorations specified for the link. +* app_data - any application specific data that was previously specified for the link in the pipeline flow or through the canvas controller API. + +Note: Typically data links must be drawn between nodes however, if the config field `enableLinkSelectionType` is set to `Detachable`, the links are allowed to be drawn to and/or from arbitrary points on the canvas. If a link is drawn either semi-detached (from one node) or fully-detached (from both nodes) the following fields will be in the link object: + +* srcPos - this is an object with two fields x_pos and y_pos. These provide the coordinates of the point on the canvas that the link is drawn from. If this exist then srcNodeId and srnNodePortId are not specified in the link object. +* trgPos - this is an object with two fields x_pos and y_pos. These provide the coordinates of the point on the canvas that the link is drawn to. If this exist then srcNodeId and srnNodePortId are not specified in the link object. + +## Association Links + +Association links are designed to capture a relationship between two nodes where there is no implied direction. By default these are displayed as a single straight link line in a dashed style. There are no arrow heads by default for that type of link. (Note : internally, association links do have a `srcNodeId` and `trgNodeId` but that is just to keep the field names consistent with the data links.) Association links do not reference ports. + +If an association link is retrieved from the canvas controller API it will have the following important fields: + +* id - the unique identifier for the link. +* type - set to "associationLink". +* srcNodeId - the ID of one of the nodes in the association. +* trgNodeId - the ID of the other node in the association. +* decorations - an array of decorations specified for the link. +* app_data - any application specific data that was previously specified for the link in the pipeline flow or through the canvas controller API. + +## Comment Links +Comment links connect a comment to one or more nodes. They can be created by the user by: (a) pulling out the small handle/circle that appears below a comment and dropping it on a node. (2) by selecting nodes before the comment is selected and then creating the comment. This will automatically create a comment link from the selected nodes to the newly created comment. + +If a comment link is retrieved from the canvas controller API it will have the following important fields: + +* id - the unique identifier for the link +* type - set to "commentLink" +* srcNodeId - the ID of comment. +* trgNodeId - the ID of the node the comment is connected to. +* app_data - any application specific data that was previously specified for the link in the pipeline flow or through the canvas controller API. + + +## Display of links +Links are drawn on the canvas using SVG elements in the DOM. Each link has a top level group `` element and inside it some SVG paths. The first displayed path is the selection area. This is invisible but provides a selection/hover area for mouse interactions on the link. The second is a path to represent the link itself which is drawn over the top of the selection area path: + +| Purpose | DOM tag | Classes | Notes | +| :---------- | :----------------------------------- | :---------- | :----------------------------------- | +|Group | g | d3-link group | Classes specified for the link in the class_name field of the link object will be added here. | +|⮕ Selection area| path | d3-link-selection-area | | +|⮕ Link line | path | d3-link-line | | +|⮕ Arrow head | path | d3-link-line-arrow-head | Only when enableLinkType is set to "Straight" | +|⮕ Decorations | g | d3-link-decorations-group | Will contain decoration elements, for example, image, path etc | + +Note: The main link group will also have one of these classes: d3-node-link (for data links), d3-object-link (for association links) or d3-comment-link (for comment links). \ No newline at end of file diff --git a/guide/2.0.2-Palette.md b/guide/2.0.2-Palette.md index d246caf40f..6369b28b60 100644 --- a/guide/2.0.2-Palette.md +++ b/guide/2.0.2-Palette.md @@ -11,6 +11,7 @@ Instead of dragging node templates from the palette, the user can double click n ## Palette configuration There are a number of configuration options that control the palette that are specified in the canvas config object: + * [enablePaletteLayout](/2.1-Config-Objects#enablepalettelayout) * [enableNarrowPalette](/2.1-Config-Objects#enablenarrowpalette) * [enableAutoLinkOnlyFromSelNodes](/2.1-Config-Objects#enableautolinkonlyfromselnodes) @@ -23,6 +24,7 @@ The palette can be opened and closed using these canvas-controller [operational ## Search The user can enter a search string into the Search field at the top of the palette. The behavior is as follows: + 1. When the search field is empty, the palette shows categories which can be expanded to show the node templates within the expanded category. 2. As the user enters characters into the search field, common-canvas immediately searches through the node template labels, node template descriptions and category labels for the characters entered and finds a subset of the node templates that match the search string. Common-canvas then replaces the category-based view of the palette with a list of node templates that match the search criteria. In this view the node templates also include the node description under the node label. 3. The search is case insensitive. diff --git a/guide/2.0.4-Context-Toolbar.md b/guide/2.0.4-Context-Toolbar.md index 3cd4b1fa85..89279bf163 100644 --- a/guide/2.0.4-Context-Toolbar.md +++ b/guide/2.0.4-Context-Toolbar.md @@ -2,7 +2,8 @@ Context toolbars can be enabled in common-canvas as an alternative to traditiona A context toolbar is a small toolbar that appears above nodes, links and comments as the mouse cursor is hovered over them. A context toolbar for the canvas background can also be displayed by right-clicking on the canvas background. -The context toolbar displays a set of icons that represent the most likely actions the user would want to perform on the object under the mouse cursor. If necessary, the toolbar can also show an overflow (horizontal ellipsis) icon that, when clicked, reveals additional actions that can be performed on the object. +The context toolbar displays a set of icons that represent the most likely actions the user would want to perform on the object under the mouse cursor. If necessary, the toolbar can also show an overflow (vertical ellipsis) icon that, when clicked, reveals additional actions that can be performed on the object. + For a "vertical" style node the context toolbar looks like this: diff --git a/guide/2.1-Config-Objects.md b/guide/2.1-Config-Objects.md index c38c20dbaa..5c3fffbe99 100644 --- a/guide/2.1-Config-Objects.md +++ b/guide/2.1-Config-Objects.md @@ -58,13 +58,15 @@ This can be "Horizontal" or "Vertical". "Horizontal" is the default. "Horizontal This can be "Curve", "Elbow", or "Straight". "Curve" is the default. This will set the link style used to connect nodes. #### **enableLinkDirection** -This can be "LeftRight", "TopBottom", or "BottomTop". "LeftRight" is the default. This will set the input and output port positions on nodes to facilitate links being drawn in the direction specified. +This can be "LeftRight", "TopBottom", or "BottomTop". "LeftRight" is the default. This will set the input and output port positions on nodes to facilitate links being drawn in the direction specified. + * For "LeftRight" output ports will be on the right and input ports will be on the left of the nodes * For "TopBottom" output ports will be on the bottom and input ports will be on the top of the nodes * For "BottomTop" output ports will be on the top and input ports will be on the bottom of the nodes #### **enableLinkSelection** This can be: "None", "LinkOnly", "Handles" or "Detachable". The default is "None". These have the following affect on the canvas: + * "None" - no selection of links is possible however user can right click on a link to get a context menu. * "LinkOnly" - a link may be selected and added to the set of currently selected objects (nodes and/or comments). * "Handles" - This includes the "LinkOnly" function. In addition, when a link is selected a handle (either a circle or an image) is displayed at the start and end of the link. The link handle can be dragged to a new node/port position to rewire the flow. @@ -74,6 +76,7 @@ This can be: "None", "LinkOnly", "Handles" or "Detachable". The default is "None * between two arbitrary points on the canvas (detached) Additionally, "Detachable" mode, allows: + - semi-detached or fully-detached links to be stored in and retrieved from the pipeline flow document. - semi-detached or fully-detached links to be manipulated with link handles. The link handles can be used to drag the end of the link away from its connecting source or target nodes and onto the canvas. Or semi-detached or fully detached links can be reattached to nodes/ports. - a new detached link to be created by drawing out a new link from a node and dropping it onto the canvas. @@ -98,6 +101,14 @@ will override the style from the common-canvas CSS } ``` +## enableImageDisplay + +This can be set to: "SVGInline", "LoadSVGToDefs" or "SVGAsImage". The default is "SVGInline". This field controls the display of SVG image files (that is, files with a `.svg` extension) on the canvas, such as those displayed for node icons or decoration images. This option can be useful to improve performance when images are repeated a large number of times on the canvas and particularly when the browser cache is disabled. Note: this does not affect the display behavior of non-SVG files which are always displayed inside an `` tag. The behavior for SVG image files is as follows: + +* "SVGInline" - This is the default. With this setting, the image file is read in -- from the server or cache (if available) -- and the SVG tags within the file displayed in-line in the DOM. This means elements within the SVG can be customized using CSS on a node-by-node basis. +* "LoadSVGToDefs" - With this option, each unique SVG file is read from the server (or cache) and written into a `` element within the `` element of the canvas SVG area. A `` element is then written to the place in the DOM for each place where the image should be displayed. Using this option means the SVG file for each image is only read once which should improve performance if images are repeated a lot on the canvas. However, it does limit the customization possibilities for the images on a node-by-node basis. Customization colors can be passed into the images using CSS inheritance, or the `currentColor` keyword, provided there are no internal classes applied to the elements in the SVG. +* "SVGAsImage" - This option causes the SVG file to be displayed within an `` element in the DOM. The file loading is handled internally by the browser. Again, with this option customization capabilities on a node-by-node basis are limited. Customization colors can be passed into the images using CSS inheritance, or the `currentColor` keyword, provided there are no internal classes applied to the elements in the SVG. + #### **enableInternalObjectModel** This is a boolean. The default is `true`. You should use `true` for this all the time. If you set this to `false` your code will be responsible for handling the object model, which is NOT recommended. When `false`, changes are not set into the object model, and consumers are expected to listen to events and update the internal object model themselves (again, *not* recommended). @@ -108,10 +119,11 @@ This can be: "Modal" or "Flyout" or "None". The default is "Flyout". "Flyout" di This can be: "Top" or "None". The default is "Top". "Top" displays a toolbar at the top of the canvas area. See the [toolbar configuration object docs](/2.1-Config-Objects#toolbar-config-object) for details on how to customize the toolbar. "None" stops the toolbar from appearing. #### **enableResizableNodes** -This can be true or false. The default is false. If set to true, the user can resize nodes by dragging the edges of the node to increase or decrease the width and/or height of the node. When hovering the mouse cursor over the edge of the node the user will see a sizing cursor to indicate the resize function is available. This option works best when the node has a background rectangle that shows the extend of the sizing area. +This can be true or false. The default is false. If set to true, the user can resize nodes by dragging the edges of the node to increase or decrease the width and/or height of the node. When hovering the mouse cursor over the edge of the node the user will see a sizing cursor to indicate the resize function is available. This option works best when the node has a background rectangle that shows the extent of the sizing area. #### **enableInsertNodeDroppedOnLink** This can be true or false. The default is false. If set to true, the user can drag nodes from the palette or from the canvas and drop them onto existing links in the flow. This causes the dropped node to be inserted between the two nodes joined by the link, meaning new links are created that join the new node to the previously joined nodes and the old link is removed. When the user performs the drop common-canvas will call the editActionHandler with one of two possible commands: + * "createNodeOnLink" - when a node is being dragged from the palette leading to node creation & insertion * "insertNodeIntoLink" - when an existing node is dragged from the canvas leading to insertion of the existing node into the link @@ -127,6 +139,10 @@ This can be true or false. The default is false. If set to true common-canvas wi #### **enableHighlightUnavailableNodes** This can be true or false. The default is false. If set to true, when the user begins to drag a new link line, common-canvas will add a new class called `d3-node-unavailable` to all nodes which cannot accept the link as input. The class will be applied to each node's group `` element in the DOM. This class can be used for styling the unavailable nodes as desired using CSS. The default styling will 'gray out' the node label, node outline rectangle (if there is one) and the node icon (provided it is an SVG image). These styles can be overridden in the applications CSS if different styling is needed. This behavior also applies if the end of a partially or fully detached link is dragged. +#### **enableRaiseNodesToTopOnHover** +This can be true or false. The default is true. If set to false the nodes will be left in their original place in the DOM. If set to true, when the user moves the mouse cursor over a node, that node will be moved in the DOM so that the node appears on top of all other nodes. This is only really noticeable if nodes, or parts of nodes, overlap other nodes. It can be useful if your nodes have protruding ports or decorations and your users sometimes position nodes very close to one another. Note: the 'true' setting can adversely affect the behavior of scroll areas in a node that are displayed using a React object (using the `nodeExternalObject` node layout option) because when the node is moved in the DOM the scroll area gets reset to its initial position. Set this to false if you are displaying nodes using React objects. + + #### **enableAutoLinkOnlyFromSelNodes** This can be true or false. The default is false. When set to true the auto-add function (where double clicking a node in the palette automatically adds it to the canvas) will only link up nodes when a node is already selected on the canvas and then, only if the selected node can be linked to the node that was double clicked. If false, the auto-add function will make a best guess at which node the double-clicked node should be added to. @@ -162,6 +178,7 @@ This can be either "None", "Locked" or "ReadOnly". The default is "None". When s #### **enableEditingActions** This can be true or false. The default is true. If set to false, various editing actions on the canvas will be prevented, as follows: + 1. Nodes cannot be created on the canvas using any of the following: (a) dragging and dropping a node template from the palette onto the canvas or @@ -171,6 +188,7 @@ This can be true or false. The default is true. If set to false, various editing (c) double clicking a node in the palette to create a node Note: It is not possible for common-canvas to prevent an object being dragged from the computer desktop to the canvas so it is recommended the drop zone (which provides visual feedback about the drop) should be switched off by setting the [enableDropZoneOnExternalDrag](/2.1-Config-Objects#enabledropzoneonexternaldrag) config field to `false`. + 2. Nodes and comments cannot be dragged and moved. 3. The end points of Links, when [enableLinkSelection](/2.1-Config-Objects#enablelinkselection) is set to `"Detachable"` or `"Handles"`, cannot be dragged and moved. 4. Links from nodes and comments cannot be created by dragging from the port object on the source node or comment to the target node. @@ -198,6 +216,7 @@ This can be true or false. The default is true. If set to false, various editing |Save to palette|saveToPalette| If your application adds its own editing actions to the context menu your code must remove them if they are not needed in some situations (e.g. you are displaying a read-only canvas). + 7. Any default toolbar actions (tools) that alter the canvas objects will be disabled regardless of their specified enablement status. These actions are: |Default Tooltip|Action| @@ -211,6 +230,7 @@ This can be true or false. The default is true. If set to false, various editing |New comment|createAutoComment| |Arrange Horizontally|arrangeHorizontally| |Arrange Vertically|arrangeVertically| + 8. Keyboard shortcuts that alter the canvas will not work. These are: |Shortcut|Action| @@ -222,6 +242,7 @@ This can be true or false. The default is true. If set to false, various editing |Ctrl/Cmd + z|undo| |Ctrl/Cmd + Shift + z|redo| |Ctrl/Cmd + y|redo| + 9. The browser's Edit menu options (cut, copy, paste) will not work with the canvas objects regardless of the setting for [enableBrowserEditMenu](/2.1-Config-Objects#enablebrowsereditmenu). #### **enableDropZoneOnExternalDrag** @@ -233,7 +254,8 @@ See the [Dragging an object from the desktop](/2.3-Enabling-node-creation-from-e This is a simple Javascript object, the properties of which override the default node layout properties. For more details see: [Customizing Node Layout Properties](/2.7-Customizing-Node-Layout-Properties) #### **enableSaveZoom** -This can be: "None", "LocalStorage" or "Pipelineflow". The default is "None". +This can be: "None", "LocalStorage" or "Pipelineflow". The default is "None". + * "None" - When the canvas is zoomed, the zoom (scale and x/y pan) are not saved anywhere so if the canvas is closed and reopened it reopens with the default zoom which is a scale of 1 and x/y pan values of 0. * "LocalStorage" - The zoom for the canvas is stored in the browser's local storage and will be reapplied to the canvas each time that canvas is shown in that browser. This applies to sub-flows, when the user displays them full-screen, as well as the primary flow. Sub-flows and the primary flow each have their own zoom amounts stored in local storage. Note: Zoom amounts stored in local storage can be cleared from storage by calling the `canvasController.clearSavedZoomValues()` API method. * "Pipelineflow" - The zoom is serialized into the pipeline flow document and when a pipeline flow document is provided to common canvas through the API the zoom will be applied to the canvas display. Zoom amounts can be stored for both primary and sub pipelines. (See the pipelineFlow schema specification). @@ -248,7 +270,8 @@ This is a boolean. The default is false. When set to true, common-canvas will ov This is a boolean. The default is false. When set to true, common-canvas will display a context toolbar instead of a context menu for performing actions on canvas objects. A context toolbar is a small toolbar that appears above nodes, links and comments as the mouse cursor is hovered over them. The toolbar shows icons for actions the user is most likely to want to perform on the object. An overflow icon is displayed which, when clicked, shows a menu of additional actions. A context toolbar for the canvas background can also be displayed by right-clicking on the background. Common-canvas will display default context toolbars for nodes, links comments and the canvas background however the default actions can be customized by implementing the [`contextMenuHanlder`](/2.2-Common-Canvas-callbacks#contextmenuhandler) callback. #### **enableSnapToGridType** -This can be: "None", "During" or "After". The default is "None". +This can be: "None", "During" or "After". The default is "None". + * "None" - there is no snap to grid and objects can be moved to any position on the canvas. * "During" - when nodes or comments are moved or sized, the objects snap to an imaginary grid while the objects are being dragged or sized. This gives a somewhat jerky effect as the move or size is happening but has the advantage of telling the user exactly where the object will be when they release the mouse button to end the action. * "After" - nodes or comments snap to a grid when the drag or size event ends. This gives a smooth dragging and sizing effect but the user does not see the final position until they release the mouse button at the end of the action. By default the canvas uses reasonable values for the grid increments. @@ -267,6 +290,7 @@ This is the spacing in pixels which is used to separate nodes horizontally when #### **enableAssocLinkCreation** This is a Boolean. The default is `false`. If set to `true` it changes the nature of links that are created between nodes as follows: + - The user is able to pull out a link from either port on the node and drag it to another node - When a link is completed an `association` link is created rather than the regular data flow link that is created when this field is set to `true`. Association links describe an association between pairs of nodes and do not indicate any kind of data flow between those nodes. @@ -353,6 +377,7 @@ If you do specify a toolbar config object, you can specify actions for the left }; ``` Where: + * **leftBar** - an array of action items to specify what is displayed on the left side of the toolbar. * **rightBar** - an array of action items to specify what is displayed on the right side of the toolbar. If this is omitted, common-canvas will automatically populate the right side of the toolbar with zoom-in, zoom-out, and zoom-to-fit actions. To suppress these right side actions, specify the `rightBar` field as an empty array or an array containing the actions you want on the right. @@ -360,6 +385,7 @@ Where: * **overrideAutoEnableDisable** - a boolean. The default is false. By default common-canvas has an auto-enablement feature that controls the enablement of common tools in the toolbar based on user actions (e.g enable the `Delete` icon when items are selected). If `overrideAutoEnableDisable` set to true it will switch off the auto-enablement feature. This is useful if the host application wants to disable all the nodes under certain circumstances. If set to true, the `enable` property in the action items for each tool is used to decide whether to display the icon as enabled or disabled. If set to false or omitted, common-canvas will handle the auto-enablement of common actions. (See the `action`section below for more details.) Two toolbar items are automatically added to the toolbar: + - A palette action which is used for opening and closing the node palette. This is added to the left side of the left side of the toolbar if the [`enablePaletteLayout`](/2.1-Config-Objects#enablepalettelayout) field is set to either "Flyout" (the default) or "Modal" in the canvas configuration. - A notification panel action which is used to open and close the notifications panel. This will be added to the right side of the toolbar if a [notification configuration](/2.1-Config-Objects#notification-config-object) object is specified to the `` react object. @@ -379,10 +405,11 @@ Here is an example of an action object which must contain a unique `action` fiel isSelected: false } ``` -* **action** - a unique identifier and the name of the action to be performed. This action name will be passed in the `data` parameter of the [editActionHandler](/2.2-Common-Canvas-callbacks#editactionhandler) callback method so you can detect when the user clicks an action in the toolbar. +* **action** - a unique identifier and the name of the action to be performed. This action name will be passed in the `data` parameter of the [editActionHandler](/2.2-Common-Canvas-callbacks#editactionhandler) callback method so you can detect when the user clicks an action in the toolbar. + If you are using the recommended (and default) [internal object model](/2.1-Config-Objects#enableinternalobjectmodel), the following built in actions will be automatically handled by common-canvas: `undo`, `redo`, `cut`, `copy`, `paste`, `createAutoComment`, `deleteSelectedObjects`, `arrangeHorizontally`, `arrangeVertically`, `zoomIn`, `zoomOut`, and `zoomToFit`. So for example, if the `deleteSelectedObjects` action (shown as a trash can) is clicked, any selected objects will be deleted from the internal object model. - + Disablement of some of these built in actions is also handled by common-canvas so, for example, when no canvas objects are selected the `deleteSelectedObjects` action (trash can icon) will be automatically disabled. You can switch off this automatic enable/disable function by setting `overrideAutoEnableDisable` field in the toolbar config to `true`. When set to true, the `enable` field in the action objects will be used to set the enablement appearance of the toolbar item. * **label** - the Tooltip label to display (and optionally the text to display next to the icon if `incLabelWithIcon` is specified). @@ -392,12 +419,14 @@ Here is an example of an action object which must contain a unique `action` fiel * **iconEnabled** - specifies the icon to display when `enable` is true. Common-canvas will provide icons for the following actions so you don't need to specify `iconEnabled` or `iconDisabled` for them: `stop`, `run`, `undo`, `redo`, `cut`, `copy`, `paste`, `createAutoComment`, `deleteSelectedObjects`, `arrangeHorizontally`, `arrangeVertically`, `commentsShow`, `commentsHide`, `zoomIn`, `zoomOut`, and `zoomToFit`. It can be either: + - a string containing the path to a custom SVG file to display or - a JSX expression, for example `()` where Edit32 is an icon imported from carbon icons. It is recommended to only pass very simple JSX expressions. * **iconDisabled** - specifies the icon to display when `enable` is false. If `iconDisabled` is *not* specified `iconEnabled` will be used instead. It can be omitted for any of the standard actions (see `iconEnabled` above). It can be either: + - a string containing the path to a custom SVG file to display or - a JSX expression, for example `()` where Edit32 is an icon imported from carbon icons. It is recommended to only pass very simple JSX expressions. @@ -418,6 +447,7 @@ You can add dividers to separate groups of actions from other actions. This is d divider: true } ``` + * **divider** - To show a divider in the toolbar, add an object with `divider` attribute set to true. ### Deprecated toolbar config @@ -456,6 +486,7 @@ The JSX can be provided in the `jsx` field. Here is an example. The only other f tooltip: "Loading the thing you wanted." } ``` + * **action** - a unique identifier and the name of the action to be performed. * **jsx** - A JSX object. This will be displayed as the action in the toolbar. @@ -523,6 +554,7 @@ Similar to a toolbar action object, the notificationConfig object looks like thi clearAllCallback: () => { console.log("Clear All clicked"); } }; ``` + * **action** - "notification" enables the notifications icon to appear in the far right of the toolbar. * **label** - the Tooltip label to display for the notifications icon in the toolbar. @@ -565,6 +597,7 @@ The context menu config object configures whether certain actions are available } }; ``` + * **enableCreateSupernodeNonContiguous** - Allows the creation of supernodes from non-contiguous nodes. When set to `true`, the "Create supernode" menu item will be added to the default context menu when the currently selected nodes are contiguous or non-contiguous. When set to `false`, the "Create supernode" menu item is only added to the default context menu when the selected nodes are contiguous. The default value is `false`. * **defaultMenuEntries** - Controls what entries are generated in the default context menu generated by common canvas. This has the following properties: diff --git a/guide/2.2-Common-Canvas-callbacks.md b/guide/2.2-Common-Canvas-callbacks.md index 46c8bc63f4..e957901eca 100644 --- a/guide/2.2-Common-Canvas-callbacks.md +++ b/guide/2.2-Common-Canvas-callbacks.md @@ -19,6 +19,7 @@ The job of this callback is to tell common canvas what items to display in the c For context menus this will be dependent on what object or set of objects the context menu was requested for by the user. This callback will be called if the user performs a context menu gesture (such as mouse 'right click') on a: + * node * link * comment @@ -117,17 +118,17 @@ This callback is optional. You don't *need* to implement anything for it and it * Clicks a tool in the toolbar. * Clicks an option in the context menu. * Presses a [key combination](/2.0-Common-Canvas-Documentation#keyboard-support) on the keyboard to cause the canvas to change. -* Performs some direct manipulation on the canvas such as: - - Creates a node (createNode) - - Moves one or a set of nodes/comments (moveObjects) - - Edits a comment (editComment) - - Links two nodes together (linkNodes) - - Links a comment to a node (linkComment) - - Resizes a supernode (resizeObjects) - - Resizes a comment (editComment) - - Expands a supernode in place (expandSuperNodeInPlace) - - Navigates into a sub-flow in a supernode (displaySubPipeline) - - Navigates out of a sub-flow in a supernode (displayPreviousPipeline) +* Performs some direct manipulation on the canvas such as: + * Creates a node (createNode) + * Moves one or a set of nodes/comments (moveObjects) + * Edits a comment (editComment) + * Links two nodes together (linkNodes) + * Links a comment to a node (linkComment) + * Resizes a supernode (resizeObjects) + * Resizes a comment (editComment) + * Expands a supernode in place (expandSuperNodeInPlace) + * Navigates into a sub-flow in a supernode (displaySubPipeline) + * Navigates out of a sub-flow in a supernode (displayPreviousPipeline) This callback is called *after* the common-canvas internal object model has been updated. This callback is provided with two parameters: `data` and `command`. @@ -143,6 +144,7 @@ This callback is called *after* the common-canvas internal object model has been offsetY: 42 } ``` + + ***editType*** - This is the action that originates from either the toolbar, context menu, keyboard action or direct manipulation on the canvas. If you specified your own action in the context menu or in the toolbar this field will be your action's name. + ***editSource*** - This is the source of the action. It can be set to "toolbar", "contextmenu", "keyboard" or "canvas" (for an action caused by direct manipulation on the canvas). @@ -162,15 +164,18 @@ This callback is called *after* the common-canvas internal object model has been This callback is optional. You don't *need* to implement anything for it but if you do implement it you **must** return either a data object or null. This callback is called in all the same instances where `editActionHandler` is called. The difference is that this callback is called *before* the internal object model is updated. This gives your application the opportunity to examine the action that is about to be performed and either: let it continue; modify it and let it continue; or cancel it. This callback is provided with two parameters: `data` and `command`. + 1. **data parameter** - this is the same as the data object described for `editActionHandler` (see above) 2. **command parameter** - typically this will be null but for `undo` operations (that is where data.editType === "undo") this will be the command that is about to be undone. For `redo` operations (that is where data.editType === "redo") this will be the command that is about to be redone. This callback *must* return either the data object that was passed in or null. `beforeEditActionHandler` will behave as follows based on what is returned: + * If the data object is returned unmodified: the action will be performed as normal. * If the data object is returned modified: the action will be performed based on the modified data object. This means your application can alter the behavior of the action that will be performed. For example, you could intercept a `createNode` command and change the label for the new node in the nodeTemplate to something different. Then when the node is created the new label will be used. It is recommended you be **very** **very** careful when updating this object since there is no error checking in common-canvas to ensure you modified the object correctly. * If `null` is returned: the action will be cancelled and not performed on the internal object model nor will `editActionHandler` be called. If you need to do any asynchronous activity in the beforeEditActionHandler callback you can: + * Return null from the callback - which will cancel the current action * Do your asynchronous activity. While this is happening, the user ought to be prevented from modifying the canvas so you should display some sort of progress indicator or modal dialog to inform the user that some activity is occurring. * Then call `CanvasController.editActionHandler(data)` passing in the `data` object as a parameter with the modified properties. This will then execute the action as before. Note: This means the `beforeEditActionHandler` will be called a second time so be sure you put in a check to make sure you don't get into a loop. @@ -193,6 +198,7 @@ At the moment only click/double-click on nodes and the canvas background are ret } ``` The fields can be: + * clickType - This can be either "SINGLE_CLICK", "SINGLE_CLICK_CONTEXTMENU" or "DOUBLE_CLICK" * objectType - Can be either "node", "comment", "canvas" or "region". "region" is specified when the user pulls out a selection rectangle around a set of objects that might include nodes and comments. * id - The ID of the node or comment clicked. Only provided when objectType is "node" or "comment" @@ -209,6 +215,7 @@ Decorations are small images that can be displayed on or near to your nodes and This callback is called when the user clicks on an actionable decoration. You don't need to implement anything for this callback unless you added actionable decorations to your nodes. It doesn't return anything. It is called whenever the user clicks on a decoration that you added to a node in the canvas JSON. It is provided with two parameters: + * object -- the node or link with which the decoration is associated. * id -- the ID of the decoration that you provided in the canvas JSON * pipelineId -- the ID of the pipeline for the node. @@ -234,12 +241,14 @@ This optional callback can be implemented to override the tooltip content that i To override the content, you can return either a string or JSX object. If your code returns `null` for a particular type of tip, common-canvas will display the default tip for that object. For an example of an implementation for a `tipHandler`, see App.js in the test harness code (https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/client/App.js). Common-canvas calls the `tipHandler` callback with two parameters: + - tipType - the type of the tip - data - an object that describes the canvas element for which the tip was requested Here are some specific examples: #### Palette categories: + - tipType: "tipTypePaletteCategory" - data: An object with category information, like this: @@ -255,6 +264,7 @@ Here are some specific examples: ``` #### Palette nodes templates: + - tipType: "tipTypePaletteItem" - data: An object with node template information: ```js @@ -292,6 +302,7 @@ Here are some specific examples: ``` #### Ports: + - tipType: "tipTypePort" - data: An object with pipelineId, node and port information: ```js @@ -392,9 +403,12 @@ Here are some specific examples: idGeneratorHandler(action, data) ``` This callback is called when new objects are created in the canvas and allows the user to provide their own method to generate a unique id for the object. If no idGeneratorHandler is set or the method returns null, a UUID is generated by common-canvas. The method is called with a string for the action that was performed (create node/comment/link, clone node/comment/link) and a JSON object with additional data. -- create node: - * action: create_node - * data: + +* create node: + * action: create_node + * data: + + ```js nodeType: { @@ -418,13 +432,16 @@ nodeType: ] } ``` -- create comment: - * action: create_comment - * data: n/a -- create node link: - * action: create_node_link - * data: +* create comment: + + * action: create_comment + * data: n/a + +* create node link: + * action: create_node_link + * data: + ```js sourceNode: { "id":"6a547456-f1ea-48a6-9721-45d6ae70dd6b", @@ -459,9 +476,11 @@ targetNode: { "width":70 } ``` + - create comment link: - * action: create_comment_link - * data: + * action: create_comment_link + * data: + ```js comment: { "id":"8c81aac7-ebe5-4f96-9d63-eabc22b09635", @@ -489,9 +508,11 @@ targetNode: { "width":70 } ``` + - clone node: triggered when copying&pasting a node - * action: clone_node - * data: + * action: clone_node + * data: + ```js node: { "id":"56d30c83-3a08-4147-933e-b01d3c348ac1", @@ -510,9 +531,11 @@ node: { "width":70 } ``` + - clone comment: triggered when copying&pasting a comment - * action: clone_comment - * data: + * action: clone_comment + * data: + ```js comment: { "id":"8c81aac7-ebe5-4f96-9d63-eabc22b09635", @@ -524,9 +547,11 @@ comment: { "y_pos":50 } ``` + - clone node link: triggered when copying&pasting two connected nodes - * action: clone_node_link - * data: + * action: clone_node_link + * data: + ```js link: { "id":"12c4308e-f572-402a-8dd3-604d438539d4", @@ -539,9 +564,11 @@ sourceNodeId: "56d30c83-3a08-4147-933e-b01d3c348ac1", targetNodeId: "815271f0-f4da-4793-ab8f-c4c32d3dd7e0" ``` Note that the link to be cloned has references to the original source and target nodes, while the sourceNodeId and targetNodeId are the new node ids for the copied nodes. The new nodes are not part of the model yet. + - clone comment link: triggered when copying&pasting a comment and a node that are connected - * action: clone_comment_link - * data: + * action: clone_comment_link + * data: + ```js link: { "id":"12c4308e-f572-402a-8dd3-604d438539d4", @@ -648,6 +675,7 @@ The selectionChangeHandler callback is triggered whenever the selection in the c selectedPipelineId: "789-012" } ``` + - selection: Array with ids of selected nodes and comments - selectedNodes: Array of selected node objects - selectedComments: Array of selected comment objects diff --git a/guide/2.3-Enabling-node-creation-from-external-object.md b/guide/2.3-Enabling-node-creation-from-external-object.md index ddc100633f..146b622591 100644 --- a/guide/2.3-Enabling-node-creation-from-external-object.md +++ b/guide/2.3-Enabling-node-creation-from-external-object.md @@ -1,4 +1,4 @@ -# Dragging object from within the browser +## Dragging object from within the browser Common canvas supports the ability for an object from the your browser page to be dragged onto the canvas to initiate the creation of a node on the canvas. To do this you need to set the object you want to drag into the canvas to be draggable: ```html @@ -27,6 +27,7 @@ and then specify the on drag behavior like this } ``` where + * operation - is always set to "addToCanvas" * data - is the object that will be passed to the editActionHandler callback * editType - this is the type of editing operation. You can set it to anything except any of the reserved settings which are: 'createNode', 'createNodeOnLink', 'createAutoNode' and 'createFromExternalObject'. @@ -34,7 +35,7 @@ where After the object has been dropped on the canvas your editActionHandler() callback method will be called with a parameter data object that contains the fields you specified in `data` in the drag data along with three additional fields, called pipelineId, offsetX and offsetY, containing the x,y co-ordinates of where the drop occurred. In your editActionHandler() method you can use the CanvasController API to add a node to the pipeline flow and get common canvas to display it. -# Dragging object from the desktop or another application +## Dragging object from the desktop or another application If an object from the desktop or another application is dropped on the canvas your editActionHandler(data) method will be called with the `data` parameter set to an object like this: ```js { @@ -49,6 +50,7 @@ If an object from the desktop or another application is dropped on the canvas yo Your code can examine the `dataTransfer` object to see what object was dragged onto the canvas and then take appropriate action. If you want a new node to appear on the canvas as a result of the object being dropped your code will need to create that node at the point where the drop occurred, using the Canvas Controller API. Here is some sample code that will + * create a new node template based on the "variablefile" node in the palette data * set the label of the node to be created to the name of the file being dropped * create a new node on the canvas at the offsetX, offsetY position diff --git a/guide/2.4-Canvas-Controller-API.md b/guide/2.4-Canvas-Controller-API.md index f09c8c3a48..ce8cd4626a 100644 --- a/guide/2.4-Canvas-Controller-API.md +++ b/guide/2.4-Canvas-Controller-API.md @@ -259,6 +259,7 @@ getNotificationMessagesMaxType() ## Node AND comment methods In common-canvas nodes and comments are collectively known as objects. The following methods may be used to manage either collections of comments or nodes or a mixture of both. Note: + * See this sections if you are working with [styles.](/2.4.1-Style-Specification) * See this section if you are working with [decorations.](/2.4.2-Decoration-Specification) * See this section for differences between [the structure of objects in the API and the schema.](/2.4.3-Object-structure-used-by-API#api-differences-with-schema) diff --git a/guide/2.4.1-Style-Specification.md b/guide/2.4.1-Style-Specification.md index e16875da8c..3a91c893bf 100644 --- a/guide/2.4.1-Style-Specification.md +++ b/guide/2.4.1-Style-Specification.md @@ -1,4 +1,5 @@ There are multiple was to specify the styles for the objects common-canvas displays: + * A class name can be provided for nodes either within the pipelineFlow document or * The common-canvas default styes can be overriden within your CSS or SCSS file @@ -37,28 +38,32 @@ And here is a real example: } }; ``` + Here is a template for styling a comment: + ```js { body: { default: , hover: }, text: { default: }, selection_outline: { default: }, } - ``` +``` + And here is a template for styling a link: ```js { line: { default: , hover: } } - ``` -* **** - is a string containing any CSS code that can be added inline to an SVG object. That means, for example, you need to use fill and stroke for colors etc It is recommended NOT to change the sizes of text fonts. +``` + +* **``** - is a string containing any CSS code that can be added inline to an SVG object. That means, for example, you need to use fill and stroke for colors etc It is recommended NOT to change the sizes of text fonts. The CSS will be applied to the element of the object specified, either as the default inline style or as the style when the pointer hovers over the object. -When a hover style is applied to a graphical element it is applied in addition to the default style so there is no need to repeat styles in the hover because they will augment the default style. +When a hover style is applied to a graphical element it is applied in addition to the default style so there is no need to repeat styles in the hover `` because they will augment the default style. Because styles are applied as in-line styles they will override any styles provided in your application's CSS and specified to common-canvas through the class_name field of canvas objects. -If the is specified as null the current style will be removed from the specified element of the object. +If the `` is specified as null the current style will be removed from the specified element of the object. Finally, styles can be applied to your nodes, comments and links as either temporary or permanent styles by specifying the `temporary` boolean in the API methods. A temporary style is just applied for the duration of the session and are not persisted. You should use `temporary=true` styles that represent transient attributes of an object that should not be persisted in the pipelineFlow document. Use `temporary=false` styles for styles that you want to persist in the pipelineFlow document. diff --git a/guide/2.4.2-Decoration-Specification.md b/guide/2.4.2-Decoration-Specification.md index 8aa7cbdbf6..cd096cf8c5 100644 --- a/guide/2.4.2-Decoration-Specification.md +++ b/guide/2.4.2-Decoration-Specification.md @@ -1,7 +1,7 @@ -# Decorations +## Decorations Your application can add Decorations -- additional icons, text labels, shapes or JSX objects -- to nodes or links in the canvas to indicate special status or attributes of the node or link. Decorations can be static (for display only) or interactive (a hotspot) so the user can click them to initiate some action. -# Adding Decorations +## Adding Decorations Decorations can be added to the nodes and/or links in four different ways: 1. By using the following `CanvasController` methods: diff --git a/guide/2.4.4-Notification-Message-Specification.md b/guide/2.4.4-Notification-Message-Specification.md index fe2f986238..b7e1b9ccb7 100644 --- a/guide/2.4.4-Notification-Message-Specification.md +++ b/guide/2.4.4-Notification-Message-Specification.md @@ -13,6 +13,7 @@ Notification messages are displayed in the notification panel which the user can } ``` where: + * **id** (string, required): this is a unique ID assigned to the notification message. This is passed as a parameter in the callback (see below) and is used to reference messages when deleting them through the `CanvasController` API. * **type** (string, required): this must be one of four values: "info", "success", "warning", or "error". If `type` is null, empty string, or undefined, the message type will be "unspecified". diff --git a/guide/2.4.6-Constructing-a-read-only-or-locked-canvas.md b/guide/2.4.6-Constructing-a-read-only-or-locked-canvas.md index bd42ffd309..7043437621 100644 --- a/guide/2.4.6-Constructing-a-read-only-or-locked-canvas.md +++ b/guide/2.4.6-Constructing-a-read-only-or-locked-canvas.md @@ -1,4 +1,4 @@ -# Introduction +## Introduction Some host applications need to display flows that cannot be edited by the user. This might be because the flow artifact is currently being edited by another user (locked) or because the user does not have authority to edit the flow (read-only) or some other reason. We'll use the term 'read-only' below to refer to both locked and read-only canvases. @@ -47,6 +47,7 @@ Common-canvas supports a number of keyboard shortcuts. Setting `enableEditingAct # Palette Setting `enableEditingActions` to false: + * prevents node templates from being dragged from the palette and * disables the double-click action on node templates which automatically adds a node to the canvas. diff --git a/guide/2.5-Command-Stack-API.md b/guide/2.5-Command-Stack-API.md index b132f3826e..1e6998d6ab 100644 --- a/guide/2.5-Command-Stack-API.md +++ b/guide/2.5-Command-Stack-API.md @@ -2,7 +2,11 @@ The CommandStack is a JavaScript class that provides the functionality to support do/undo/redo of commands. It maintains an internal stack of commands with a cursor that moves up and down when commands are undone or redone. Commands are also Javascript classes that implement a simple interface. -The CommandStack API allows application code to programmatically add commands to the command stack. You can get the Command Stack by calling the `CanvasController.getCommandStack()` method. The CommandStack API provides the following methods: + The canvas-controller creates an instance of the command stack. Common-canvas provides command objects for each of the commands that are performed by the user, such as: create node, delete comment, link nodes together, etc. + + To activate the undo and redo actions, common-canvas provides undo/redo options in its default context menu, on the default toolbar and via keystrokes ctrl+z (undo) and ctrl+shift+z (redo). You can implement your own undo and redo UI if required using the API. + + The CommandStack API allows application code to programmatically add commands to the command stack. You can get the Command Stack by calling the canvas-controller's `getCommandStack()` method. The CommandStack API provides the following methods: ```js do(command) - push the command onto the command stack and then invoke command.do() @@ -15,7 +19,10 @@ The CommandStack API allows application code to programmatically add commands to getRedoCommand() - returns the next command to be redone or null. ``` -Each commands that is added to the command stack is a Javascript class that need to implement these methods: +Many of these have equivalent methods in the canvas-controller. + +Each command that is added to the command stack is a Javascript class that needs to implement these methods: + ```js constructor() @@ -23,16 +30,20 @@ Each commands that is added to the command stack is a Javascript class that need undo() redo() ``` + constructor() - Initial setup + do() - Performs all actions necessary to execute the command + undo() - Performs all actions necessary to reverse the actions performed in do() + redo() - Performs all actions necessary to re-execute the command. For some commands this is the same as do() but others it is different. Here is some sample code that shows how a create-node command might be written: ```js - export default class CreateNodeAction extends Action { + export default class CreateNodeAction extends Action { constructor(data) { super(data); this.newNode = createNode(data); @@ -49,6 +60,11 @@ redo() - Performs all actions necessary to re-execute the command. For some comm redo() { ObjectModel.addNode(this.newNode); } + + getLabel() { + return "Add 1 node" + } + } ``` @@ -56,10 +72,8 @@ redo() - Performs all actions necessary to re-execute the command. For some comm ```js const command = new CreateNodeAction(data); - CommandStack.do(command); + this.canvasController.getCommandStack().do(command); ``` - When using CommonCanvas, the canvas-controller creates an instance of the command stack. CommonCanvas provides command objects for each of the commands that are performed by the user, such as: create node, delete comment, link nodes together, etc. Common canvas also provides undo/redo options in its default context menu, on the toolbar and via keystrokes ctrl+z (undo) and ctrl+shift+z (redo). You can implement your own undo and redo UI if required using the API. - diff --git a/guide/2.6-Flow-Validation-API.md b/guide/2.6-Flow-Validation-API.md index 2a0b940a7a..159fdda93f 100644 --- a/guide/2.6-Flow-Validation-API.md +++ b/guide/2.6-Flow-Validation-API.md @@ -16,9 +16,9 @@ validateFlow(canvasController, parameterDataCallback, setNodeMessagesCallback, i canvasController - an instance of the canvas controller parameterDataCallback – function to get the parameter data or form data for a node setNodeMessagesCallback – function to set the validation messages for a node. (optional) - includeMsgTypes - array[strings] Return invalid only if messages are found of types contained - in the array. If not specified then any message type causes invalid return. (optional) - return - boolean If flow is valid returns true, otherwise returns false. + includeMsgTypes - array[strings] Return invalid only if messages are found of types contained + in the array. If not specified then any message type causes invalid return. (optional) + return - boolean If flow is valid returns true, otherwise returns false. ``` where the two callbacks are defined as follows: ``` diff --git a/guide/2.7-Customizing-Node-Layout-Properties.md b/guide/2.7-Customizing-Node-Layout-Properties.md index 5bb144645c..64c033441b 100644 --- a/guide/2.7-Customizing-Node-Layout-Properties.md +++ b/guide/2.7-Customizing-Node-Layout-Properties.md @@ -16,7 +16,10 @@ defaultNodeHeight: 40, // DOM element for the node. className: "", -// Default node shape. Can be "rectangle" or "port-arcs" +// Displays the node outline shape underneath the image and label. +nodeShapeDisplay: true, + +// Default node shape. Can be "rectangle" or "port-arcs". Used when nodeOutlineDisplay is true. nodeShape: "port-arcs", // SVG path strings to define the shape of your node and its @@ -25,6 +28,9 @@ nodeShape: "port-arcs", bodyPath: null, selectionPath: null, +// Displays the external object specified, as the body of the node +nodeExternalObject: false, + // Display image imageDisplay: true, @@ -37,6 +43,9 @@ imagePosition: "topLeft", imagePosX: 6, imagePosY: 7, +// Display label +labelDisplay: true, + // Label dimensions labelWidth: 112, labelHeight: 19, @@ -55,7 +64,7 @@ labelMaxCharacters: null, // null allows unlimited characters labelAllowReturnKey: false, // true allows line feed to be inserted into label, "save" to make the return key save the label. // An array of decorations to be applied to the node. For details see: -// /2.4.2-Decoration-Specification +// https://github.com/elyra-ai/canvas/wiki/2.4.2-Decoration-Specification // These are added to the node at run time and will not be saved into // the pipeline flow. decorations: [], @@ -208,6 +217,11 @@ outputPortGuideObject: "circle", // If output port guide object is "image" use this image. outputPortGuideImage: "", +// Automatically increases the node size to accommodate its ports so both +// input and output ports can be shown within the dimensions of +// the node. +autoSizeNode: true, + // Radius of the either the input or output ports when they are set to "circle" portRadius: 3, @@ -222,7 +236,7 @@ portArcRadius: 6, // Spacing between the port arcs around the ports. portArcSpacing: 3, -// Position of the context toolbar relative to the node. Some adjustment +// Position of the context toolbar realtive to the node. Some adjustment // will be made to account for the width of the toolbar. contextToolbarPosition: "topRight", @@ -301,7 +315,8 @@ const canvasConfig = { ## Customizing individual nodes or categories of nodes If you want each node, or category of nodes, to have a different layout based on some criteria you can use the second method for overriding the node layout properties. This uses the [layoutHandler callback method](/2.2-Common-Canvas-callbacks#layouthandler). When you specify this callback method to common canvas, it will be called for each node on the canvas, during initialization and, occasionally, at other times. -The method should return a simple JavaScript object that contains any node layout properties you want to override from the defaults and the ones specified in the `enableNodeLayout` field in the canvas config. This is an important point: there are three levels of properties provided where each overrides the previous set: +The method should return a simple JavaScript object that contains any node layout properties you want to override from the defaults and the ones specified in the `enableNodeLayout` field in the canvas config. This is an important point: there are three levels of properties provided where each overrides the previous set: + 1. First we take the full default set of node layout properties based on the value for `enableNodeFormatType`. 2. Then we override these with the properties from the `enableNodeLayout` field in the canvas config object, if any are provided. 3. Finally we override the combined set with any properties from the object returned from the `layoutHandler` method if one is specified. @@ -326,6 +341,7 @@ layoutHandler(data) { OK, it's not a very complicated example but hopefully you get the message :) In the test harness, you can see an example application that use the [layoutHandler callback method](/2.2-Common-Canvas-callbacks#layouthandler). In the test harness: + 1. Open the Common Canvas side panel (click the hamburger icon) 2. Select the `Explain` sample application @@ -340,6 +356,7 @@ You can examine the [Explain sample app code](https://github.com/elyra-ai/canvas ## Customizing node colors and styles The DOM elements that make up a node can be customized using CSS styles. This is done by assigning a class name to the group `` element that is the container for all the node elements. The class can be applied to the group object is a number of different ways: + 1. By specifying it in the `app_data.ui_data.class_name` field of the node in the pipeline flow document that is provided to common-canvas using `CanvasController.setPipelineFlow(pFlow)` 2. By specifying it using the following API methods: * CanvasController.setNodeProperties(nodeId, properties, pipelineId) diff --git a/guide/2.8-Context-Menu-Wrapper-Documentation.md b/guide/2.8-Context-Menu-Wrapper-Documentation.md index 22b15d92d5..a5c55ce237 100644 --- a/guide/2.8-Context-Menu-Wrapper-Documentation.md +++ b/guide/2.8-Context-Menu-Wrapper-Documentation.md @@ -1,4 +1,6 @@ -# Context Menu Wrapper +## Context Menu Wrapper + +Context Menu Wrapper is now deprecated. Carbon 11 supports a context menu component The context menu in common-canvas can be used in your application by importing the `ContextMenuWrapper` React component. Aside from providing a standard context menu to allow users to select different actions, this context menu also allows for configuration of submenus as a menu item, as well as a visual dividers. @@ -29,6 +31,7 @@ To use Context Menu Wrapper in your React application you need to import the `Co ]; ``` + * **containingDivId** `string` (required): the id of the element that the context menu will be absolutely positioned inside. typically, the page element is used. * **contextMenuPos** `object` (required): the position of the context menu within the containing div. ```js @@ -40,9 +43,9 @@ To use Context Menu Wrapper in your React application you need to import the `Co contextMenuActionHandler(action) { switch (action) { case "BUILD": - break; + break; case "EXTEND": - break; + break; default: } } @@ -54,11 +57,11 @@ To use Context Menu Wrapper in your React application you need to import the `Co ```js const contextMenuWrapper = ( + /> ); ``` diff --git a/guide/2.9-External-Subflows-support.md b/guide/2.9-External-Subflows-support.md index 46cedb73bc..45b62557f0 100644 --- a/guide/2.9-External-Subflows-support.md +++ b/guide/2.9-External-Subflows-support.md @@ -3,6 +3,7 @@ The pipeline flow schema describes two ways of storing a sub-flow pipelines for a supernode: local or external. Local sub-flows are stored within the pipeline flow document whereas external pipelines are stored in a separate pipeline flow document (usually as the primary pipeline in that pipeline flow). The supernode that references an external pipeline contains a `url` property (in `.subflow_ref.url`) and a `pipeline ID` property (in `.subflow_ref.pipeline_id_ref`) to identify the external pipeline flow and the pipeline within it. Common-canvas supports external pipelines but the host application UI code needs to manage the storage and retrieval of any external pipeline flows. To do this the app UI code needs to: + * Manage the storage of newly created external pipeline flows. * Respond to calls from common-canvas to provide the external pipeline flow(s) when requested. * Respond to call from common-canvas when a local pipeline is changed to external or an external is changed to local. @@ -10,7 +11,7 @@ Common-canvas supports external pipelines but the host application UI code needs Common-canvas supports lazy loading of external pipeline flows so they will only be requested from your code when the user performs some gesture that requires the pipeline (from within the external pipeline flow) to be displayed. ## Creating an external sub-flow -When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true the default common-canvas context menu will include a `Create External Supernode` option when a set of objects are selected from which a super node can be created. +When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true (the default) and, when a set of objects are selected from which a super node can be created, the default common-canvas context menu will include a `Create External Supernode` option. When the `Create External Supernode` option is clicked the `createSuperNodeExternal` action is executed. @@ -21,10 +22,11 @@ When the `createSuperNodeExternal` action is executed, the `beforeEditActionHand Your code must return the `data` parameter from the `beforeEditActionHandler` callback if you want the action to proceed and create the sub-flow. If you need to do any asynchronous activity at this point see the documentation on the [beforeEditActionHanlder](/2.2-Common-Canvas-callbacks#beforeeditactionhandler) for details on how to do that. -When the sub-flow has been created common-canvas will call the `editActionHandler` callback. In this callback you can, if you wish, retrieve the pipeline flow document that has been created internally in common-canvas using `CanvasController.getExternalPipelineFlow(url)`. Your code can then save it to your repository. Alternatively, you can wait until some later time, like perhaps during an auto-save, to retrieve and store the pipeline flow externally in your repository. +When the sub-flow has been created common-canvas will call the `editActionHandler` callback with the `createSuperNodeExternal` action. In this callback you can, if you wish, retrieve the pipeline flow document that has been created internally in common-canvas using `CanvasController.getExternalPipelineFlow(url)`. Your code can then save it to your repository. Alternatively, you can wait until some later time, like perhaps during an auto-save, to retrieve and store the pipeline flow externally in your repository. + ## Loading an external sub-flow -When the main pipeline flow, displayed by common-canvas, contains a super node that references an external sub-flow it may need to be loaded whenever the user performs a gesture that causes it to be displayed - like opening it 'in-place'. An external sub-flow may also need to be loaded if the top-level pipeline being displayed has a supernode, that refers to an external pipeline, that is already expanded in-place in the saved pipeline flow JSON document being displayed. So, actions that can cause the external pipeline to be loaded are: +When the main pipeline flow, displayed by common-canvas, contains a super node that references an external sub-flow it will need to be loaded whenever the user performs a gesture that causes it to be displayed or processed in some way - for example displaying it 'in-place' or converting it from an external to a local supernode. An external sub-flow will also need to be loaded if the top-level pipeline being displayed has a supernode, that refers to an external pipeline, that is already expanded in-place in the saved pipeline flow JSON document being displayed. So, actions that can cause the external pipeline to be loaded are: * loadPipelineFlow * expandSuperNodeInPlace @@ -33,6 +35,7 @@ When the main pipeline flow, displayed by common-canvas, contains a super node t * deconstructSuperNode When any of these actions are performed common-canvas will call the `beforeEditActionHandler` callback with the data parameter as the first parameter. The data object will have the following properties: + * editType - The name of the action being performed. * externalPipelineFlowLoad - This is a boolean which indicates whether the pipeline flow needs to be provided by your code. * externalUrl - This is the string which identifies the external pipeline flow document. @@ -40,6 +43,7 @@ When any of these actions are performed common-canvas will call the `beforeEditA * externalPipelineFlow - If `externalPipelineFlowLoad` if true this will be undefined. Otherwise it will be contain the previously loaded external pipeline flow. You need to implement the `beforeEditActionHandler` so that: + * when the actions above are being performed and externalPipelineFlowLoad is true, you retrieve the external pipeline flow from your repository * you then assign it to the `externalPipelineFlow` property of the data object * you then return the data object from the callback. @@ -47,12 +51,12 @@ You need to implement the `beforeEditActionHandler` so that: Your code must return the `data` parameter from the `beforeEditActionHandler` callback if you want the action to proceed and load the external pipeline flow. If you need to do any asynchronous activity at this point see the documentation on the [beforeEditActionHanlder](/2.2-Common-Canvas-callbacks#beforeeditactionhandler) for details on how to do that. ## Converting a local supernode to an external supernode -When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true, and a local supernode is right clicked, the default common-canvas context menu will include a `Convert local to external` option. This will execute the `convertSuperNodeLocalToExternal` action. +When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true, and a local supernode's is right clicked, the default common-canvas context menu will include a `Convert local to external` option. This will execute the `convertSuperNodeLocalToExternal` action. The `convertSuperNodeLocalToExternal` action is similar to the `createSuperNodeExternal` action in that a new external pipeline flow is being created. Consequently, you can follow the instructions in the [Creating an external sub-flow](/2.9-External-Subflows-support#creating-an-external-sub-flow) section for providing the appropriate properties of the `data` object in the `beforeEditActionHandler` and `editActionHandler` callbacks. ## Converting an external supernode to a local supernode -When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true, and an external supernode is right clicked, the default common-canvas context menu will include a `Convert external to local` option. This will execute the `convertSuperNodeExternalToLocal` action. +When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true, and an external supernode's is right clicked, the default common-canvas context menu will include a `Convert external to local` option. This will execute the `convertSuperNodeExternalToLocal` action. The `convertSuperNodeExternalToLocal` action is similar to the `expandSuperNodeInPlace` action in that an external pipeline flow may need to be retrieved from your repository. Consequently, you can follow the instructions in the [Loading an external sub-flow](/2.9-External-Subflows-support#loading-an-external-sub-flow) section for providing the appropriate properties of the `data` object in the `beforeEditActionHandler` callback. diff --git a/guide/3.0-Common-Properties-documentation.md b/guide/3.0-Common-Properties-documentation.md index 21b1346454..cd8397502f 100644 --- a/guide/3.0-Common-Properties-documentation.md +++ b/guide/3.0-Common-Properties-documentation.md @@ -1,4 +1,4 @@ -# Introduction +## Introduction Common properties displays controls to view and set property values. You can look at the harness/src/client/App.js file of this repo to see examples of code that uses the common properties component. @@ -35,7 +35,8 @@ propertiesInfo: { additionalComponents: "{components}", // Additional component(s) to display [optional] messages: "[node_messages]", // Node messages array [optional] expressionInfo: this.expressionInfo, // Information for expression builder [optional], - initialEditorSize: "{size}" // This value will override the value of editor_size in uiHints. This can have a value of "small", "medium", "large", or null [optional] + initialEditorSize: "{size}", // This value will override the value of editor_size in uiHints. This can have a value of "small", "medium", "large", or null [optional] + id: "{id}" // Unique parameter definition ID [Optional] } ``` [parameterDef schema and examples](https://github.com/elyra-ai/pipeline-schemas/tree/master/common-canvas/parameter-defs) @@ -52,7 +53,8 @@ propertiesInfo: { additionalComponents: "{additional control(s) to display}", //optional messages: "[node_messages]", // Node messages array [optional] expressionInfo: this.expressionInfo, // Information for expression builder [optional] - initialEditorSize: "{size}" // This value will override the value of editor_size in uiHints. This can have a value of "small", "medium", "large", or null [optional] + initialEditorSize: "{size}", // This value will override the value of editor_size in uiHints. This can have a value of "small", "medium", "large", or null [optional] + id: "{id}" // Unique parameter definition ID [Optional] } ``` formData [schema](https://github.com/elyra-ai/pipeline-schemas/tree/master/common-canvas/form) @@ -83,38 +85,31 @@ var messages = i18nData.messages; /> ``` -**Properties** +**Properties** + - propertiesInfo `object`: See above - propertiesConfig `object`: - - containerType `string`: type of container to display the properties, can be "Modal", "Tearsheet", or "Custom". default: `"Custom"` - - rightFlyout `boolean`: if custom container is a right-flyout, set to true. default: `false` - - applyOnBlur `boolean`: calls applyPropertyChanges when focus leave common-properties. default: `false` - - disableSaveOnRequiredErrors `boolean`: Disable the properties editor "save" button if there are required errors - - enableResize `boolean`: adds a button that allows the right-side fly-out editor to expand/collapse between small and medium sizes. default: `true` - - conditionReturnValueHandling `string`: used to determine how hidden or disabled control values are returned in applyPropertyChanges callback. Current options are "value" or "null". default: `"value"` - - buttonLabels `object`: - - primary `string`: Label to use for the primary button of the properties dialog - - secondary `string`: Label to use for the secondary button of the properties dialog - - heading `boolean`: show heading and heading icon in right-side fly-out panels. default: `false` - - schemaValidation `boolean`: If set to true, schema validation will be enabled when a parameter definition has been set in CommonProperties. Any errors found will be reported on the browser dev console. It is recommended you run with schema validation switched on while in development mode. - - applyPropertiesWithoutEdit `boolean`: When true, will always call `applyPropertyChanges` even if no changes were made. default: `false` - - maxLengthForMultiLineControls `number` - maximum characters allowed for multi-line string controls like textarea. default: 1024 - - maxLengthForSingleLineControls `number` - maximum characters allowed for single-line string controls like textfield. default: 128 - - convertValueDataTypes `boolean` - Default false. If set to true, currentParameter values whose data type does not match what is defined in the parameter definitions will be converted to the specified data type. - - trimSpaces `boolean` - Default true. If set to false, condition ops(`isEmpty`, `isNotEmpty`) and `required` fields are allowed to only contain spaces without triggering condition errors. - - showRequiredIndicator `boolean` - Default true to show `(required)` indicator. If set to false, show `(optional)` indicator next to properties label. - - returnValueFiltering `array` - Default []. When set this will filter out any values in the array in the parameters returned when `applyPropertyChanges` is call. Only primitive data types are currently supported. - - categoryView `string` - View categories in right-flyout. Can be `"accordions"` or `"tabs"`. default: `"accordions"`. -- callbacks `object` - See below for more details on each callback method - - applyPropertyChanges // required - - closePropertiesDialog // required - - helpClickHandler // optional - - controllerHandler // optional - - propertyListener // optional - - actionHandler // optional - - buttonHandler // optional - - buttonIconHandler // optional - - titleChangeHandler // optional + - containerType `string`: type of container to display the properties, can be "Modal", "Tearsheet", or "Custom". default: `"Custom"` + - rightFlyout `boolean`: If set to true, groups will be displayed as an accordion. If false, groups are displayed as tabs. default: `false` + - applyOnBlur `boolean`: calls applyPropertyChanges when focus leave common-properties. default: `false` + - disableSaveOnRequiredErrors `boolean`: Disable the properties editor "save" button if there are required errors + - enableResize `boolean`: adds a button that allows the right-side fly-out editor to expand/collapse between small and medium sizes. default: `true` + - conditionReturnValueHandling `string`: used to determine how hidden or disabled control values are returned in applyPropertyChanges callback. Current options are "value" or "null". default: `"value"` + - buttonLabels `object`: + - primary `string`: Label to use for the primary button of the properties dialog + - secondary `string`: Label to use for the secondary button of the properties dialog + - heading `boolean`: show heading and heading icon in right-side fly-out panels. default: `false` + - schemaValidation `boolean`: If set to true, schema validation will be enabled when a parameter definition has been set in CommonProperties. Any errors found will be reported on the browser dev console. It is recommended you run with schema validation switched on while in development mode. + - applyPropertiesWithoutEdit `boolean`: When true, will always call `applyPropertyChanges` even if no changes were made. default: `false` + - maxLengthForMultiLineControls `number` - maximum characters allowed for multi-line string controls like textarea. default: 1024 + - maxLengthForSingleLineControls `number` - maximum characters allowed for single-line string controls like textfield. default: 128 + - convertValueDataTypes `boolean` - Default false. If set to true, currentParameter values whose data type does not match what is defined in the parameter definitions will be converted to the specified data type. + - trimSpaces `boolean` - Default true. If set to false, condition ops(`isEmpty`, `isNotEmpty`) and `required` fields are allowed to only contain spaces without triggering condition errors. + - showRequiredIndicator `boolean` - Default true to show `(required)` indicator. If set to false, show `(optional)` indicator next to properties label. + - showAlertsTab `boolean` - Default true to show "Alerts" tab whenever there are error or warning messages. If set to false, Alerts tab won't be displayed. + - returnValueFiltering `array` - Default []. When set this will filter out any values in the array in the parameters returned when `applyPropertyChanges` is call. Only primitive data types are currently supported. + - categoryView `string` - View categories in right-flyout. Can be `"accordions"` or `"tabs"`. default: `"accordions"`. +- callbacks object - See [callbacks](#callbacks) section for more details on each callback method. - customPanels `array`: array of custom panels. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-panels) for more details. - customControls `array`: array of custom controls. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-controls) for more details. - customConditionOps `array`: array of custom condition operators. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-condition-operators) @@ -228,12 +223,13 @@ actionHandler(id, appData, data) { ### buttonHandler() Called when the edit button is clicked on in a `readonlyTable` control, or if a custom table button is clicked. The callback provides the following data: + - data: an object that consists of - - type: of button the click was invoked from. - - `edit` is returned from the edit button click of a `readonlyTable` control. - - `custom_button` is returned from the custom button click of a complex type control. - - propertyId: of the control that was clicked. - - buttonId: of the button that was clicked from a custom table button. + - type: of button the click was invoked from. + - `edit` is returned from the edit button click of a `readonlyTable` control. + - `custom_button` is returned from the custom button click of a complex type control. + - propertyId: of the control that was clicked. + - buttonId: of the button that was clicked from a custom table button. ```js buttonHandler(data) { @@ -243,11 +239,12 @@ buttonHandler(data) { ### buttonIconHandler() Called when there is a `buttons` uihints set in the `complex_type_info` section of the parameter definition. This buttonIconHandler expects a Carbon Icon jsx object as the return value from the callback. This is used to display the Carbon icon in the custom table button. The buttonIconHandler provides the following data: + - data: an object that consists of - - type: `customButtonIcon` - - propertyId: of the control that was clicked. - - buttonId: of the button that was clicked from a custom table button. - - carbonIcon: The name of the Carbon icon specified in the uihints. The corresponding jsx object is expected to be returned in the callback. + - type: `customButtonIcon` + - propertyId: of the control that was clicked. + - buttonId: of the button that was clicked from a custom table button. + - carbonIcon: The name of the Carbon icon specified in the uihints. The corresponding jsx object is expected to be returned in the callback. ```js buttonIconHandler(data, callbackIcon) { @@ -259,6 +256,7 @@ buttonIconHandler(data, callbackIcon) { ### helpClickHandler() Executes when user clicks the help icon in the property editor dialog. The callback provides the following data: + - nodeTypeId: in case of parameterDef, id property of uihints; in case formData, the componentId. - helpData: Optional helpData specified in paramDef/formData (see below). - appData: Optional application data that was passed in to `propertiesInfo` @@ -292,6 +290,7 @@ titleChangeHandler(title, callbackFunction) { } ``` where: + - type (string, required): This must be one of two values: "warning" or "error". - message(string, required): Error or warning message. There is no restriction on length of the message. diff --git a/guide/3.2-Common-Properties-UI-Hints.md b/guide/3.2-Common-Properties-UI-Hints.md index e0461d8d02..014d2a617e 100644 --- a/guide/3.2-Common-Properties-UI-Hints.md +++ b/guide/3.2-Common-Properties-UI-Hints.md @@ -8,18 +8,18 @@ The UI Hints section consists a set of simple and complex attributes. * `id` (*string*) Dialog id. * `label` (*object*) External name of dialog. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) * `description` (*object*) Description of dialog. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) * `editor_size` (*string*) The width of the properties editor panel. This can have a value of `"small"`, `"medium"`, `"large"` or `"max"`. The default is `"small"`. - - When `"small"` is specified the properties panel is displayed with a default width of 320px and with a resize button that allows the panel to be increased in size up to the `"medium"` size which is 480px. - - When `"medium"` is specified the properties panel has a width of 480px and with a resize button that allows the panel to be increased in size up to the `"large"` size which is 640px. - - When `"large"` is specified the properties panel has a width of 640px and with a resize button that allows the panel to be increased in size up to the `"max"` size which is 900px. - - When `"max"` is specified the properties panel has a width of 900px and no resize button is displayed. + - When `"small"` is specified the properties panel is displayed with a default width of 320px and with a resize button that allows the panel to be increased in size up to the `"medium"` size which is 480px. + - When `"medium"` is specified the properties panel has a width of 480px and with a resize button that allows the panel to be increased in size up to the `"large"` size which is 640px. + - When `"large"` is specified the properties panel has a width of 640px and with a resize button that allows the panel to be increased in size up to the `"max"` size which is 900px. + - When `"max"` is specified the properties panel has a width of 900px and no resize button is displayed. * `pixel_width` (*object*) This optional property gives finer control over the minimum and maximum sizes of the properties editor panel. If this is omitted the properties editor width is controlled by the `editor_size` property. `pixel_width` is an object with two properties `min` and `max` which are both numbers. - - If `min` is specified it overrides the default size of the shrunken panel and `max` is based on the `editor_size` value. - - If `max` is specified it overrides the default size of the expanded panel and `min` is based on the `editor_size` value. - - If `editor_size` is set to `"large"` only the `max` value will be used to specify the size of the panel and no resize button will be displayed. + - If `min` is specified it overrides the default size of the shrunken panel and `max` is based on the `editor_size` value. + - If `max` is specified it overrides the default size of the expanded panel and `min` is based on the `editor_size` value. + - If `editor_size` is set to `"large"` only the `max` value will be used to specify the size of the panel and no resize button will be displayed. A warning will be displayed in the console if you specify an invalid value for either `min` or `max` such as making `min` greater than `max`. @@ -47,17 +47,18 @@ Example of the simple attributes: ## Group-info Group info attributes. + * `id` (*string*) **Required** Panel id * `type` (*string*) The group type to be displayed. see Group/Panel Controls in [3.3 Common Properties Controls](/3.3-Common-Properties-Controls). * `depends_on_ref` (*string*) Property name this group depends upon. Valid for panelSelector groups only. * `label` (*object*) Group label. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) * `description` (*object*) Group description. Only used with `textPanel` and `actionPanel`. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) - + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) - + `link` (object) Optional link in the description. [tooltipLinkHandler callback](/3.0-Common-Properties-documentation#tooltiplinkhandler) must be defined whenever link object is added in uiHints.. - + `id` (string) Required unique link id. - + `data` (object) Data passed to the tooltipLinkHandler callback. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) + + `link` (object) Optional link in the description. [tooltipLinkHandler callback](/3.0-Common-Properties-documentation#tooltiplinkhandler) must be defined whenever link object is added in uiHints.. + + `id` (string) Required unique link id. + + `data` (object) Data passed to the tooltipLinkHandler callback. * `parameter_refs` (*array[string]*) List of parameter to be displayed. * `action_refs` (*array[string]*) List of action to be displayed. Used with `actionPanel` only. * `group_info` (*object*) List of additional group information. @@ -115,11 +116,11 @@ Parameter info attributes. + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) * `label_visible` (*boolean*) Determines whether to display the label for a control. * `description` (*object*) Description of parameter with optional placement context. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) - + `placement` (*string*) Placement context for the text. Valid values are `as_tooltip, on_panel`. - + `link` (*object*) Optional link in the description. [tooltipLinkHandler callback](/3.0-Common-Properties-documentation#tooltiplinkhandler) must be defined whenever link object is added in uiHints.. - + `id` (*string*) Required unique link id. - + `data` (*object*) Data passed to the tooltipLinkHandler callback. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + `placement` (*string*) Placement context for the text. Valid values are `as_tooltip, on_panel`. + + `link` (*object*) Optional link in the description. [tooltipLinkHandler callback](/3.0-Common-Properties-documentation#tooltiplinkhandler) must be defined whenever link object is added in uiHints.. + + `id` (*string*) Required unique link id. + + `data` (*object*) Data passed to the tooltipLinkHandler callback. * `control` (*string*) Which control to use. see Parameter Controls in [3.3 Common Properties Controls](/3.3-Common-Properties-Controls). * `increment` (*number*) Determines the increment/decrement value for the spinner control only. The default value is `1`. * `orientation` (*string*) Determines how the control is displayed. Valid values are `vertical, horizontal`. @@ -129,7 +130,7 @@ Parameter info attributes. * `separator` (*string*) Determines where to put a separator relative to the current control. Valid values are ` after, before`. * `visible` (*boolean*) Determines whether to display control in a table cell. Used in complex types only. * `place_holder_text` (*object*) Text hint for the user displayed input controls. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) * `resource_key` (*string*) Used as a key for enum value labels in the resources section of property definition. * `edit_style` (*string*) Editing style of elements in a table. Valid values are `subpanel, inline, on_panel`. * `value_icons` (*array[string]*) For enumerated types, this defines the set of icons for the valid values. The ordering must be consistent with the order in the parameter enum attribute. @@ -140,13 +141,13 @@ Parameter info attributes. * `dm_image` (*string*) This can be set to display an icon of the corresponding dm type in the `role`:`column` field of a table. Valid values are `measure`, `type`, `none` * `summary` (*boolean*) Determines if parameter should be shown in the summary when using a `summaryPanel`. * `text_before` (*object*) Text to be displayed before the control - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) - + `type` (*string*) Adds a icon and additional formatting to the text. Only `info` is support at this time. - + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + `type` (*string*) Adds a icon and additional formatting to the text. Only `info` is support at this time. + + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) * `text_after` (*object*) Text to be displayed after the control - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) - + `type` (*string*) Adds a icon and additional formatting to the text. Only `info` is support at this time. - + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + `type` (*string*) Adds a icon and additional formatting to the text. Only `info` is support at this time. + + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) * `custom_control_id` (*string*) Id that is used to determine which custom control to use when `control=custom` * `data` (*any*) Returned in custom control constructor without any changes. * `rows` (*integer*) Number of rows to show in a table before scrolling starts. If one table in a panel is set to -1, that table will use the remaining available vertical space, down to a minimum of 2 rows. Used in expression and code controls to determine the number of rows to show for those controls. @@ -179,24 +180,25 @@ Example parameter info section: The complex_type_info section defines complex data types. This section is needed if in the `parameters` section of the parameter definition, one of the parameters has a type that is not the base type (i.e. an array or map of base types). The type of control used for this definition depends on the group info type value. Complex Type info attributes. + * `complex_type_ref` (*string*) **Required** Name of complex type, can be referenced in other places. * `key_definition` (*string*) A set of parameter info attributes about the key parameter. * `label` (*object*) External name of subpanel. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) * `parameters` (*object*) **Required** List of parameters that are part of this complex parameter. This parameter can either have a set of parameter_info attributes or other nested complex_type_info attributes. * `header` (*boolean*) If `true` then the table has a header row with column names. Defaults to `true`. * `add_remove_rows` (*boolean*) If `true` then the table can have rows added and removed. Defaults to `true`. * `include_all_fields` (*boolean*) When `true` and `add_remove_rows` is `false`, ensures that all fields are included in the control at all times. * `row_selection` (*string enum*) How many rows in a table can be selected at a time. - + `single`: only one row at a time is able to be selected. - + `multiple`: multiple rows at a time are able to be selected. - + `multiple-edit`: select multiple rows and allow the editing of column values of all selected rows. + + `single`: only one row at a time is able to be selected. + + `multiple`: multiple rows at a time are able to be selected. + + `multiple-edit`: select multiple rows and allow the editing of column values of all selected rows. * `buttons` (*array*) An array of objects that define custom buttons to be displayed in this complex structure, overriding any default buttons. Each button object contains the following properties: - + `id` (*string*) **Required**: Unique identifier used to identify the button in the callback function. - + `label` (*object*): Button label to display. If an icon is specified as well, the icon will be shown to the right of the label. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) - + `description` (*object*): Tooltip text to display when the button is hovered. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + `id` (*string*) **Required**: Unique identifier used to identify the button in the callback function. + + `label` (*object*): Button label to display. If an icon is specified as well, the icon will be shown to the right of the label. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + `description` (*object*): Tooltip text to display when the button is hovered. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + `icon` (*string*): URL to .svg image to display. + `carbon_icon` (*string*): Host provided name of Carbon icon to display. A callback function is required for the host application to return the jsx icon object imported from @carbon/icons-react library. + `enabled` (*boolean*): Button will be enabled if true, disabled if false. @@ -290,18 +292,19 @@ Example complex_type_info section: The action_info section defines an action. Actions are used to callback to the application to perform an operation. Action info attributes. + * `id` (*string*) **Required** Id of the action. * `label` (*object*) **Required** External name of action. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) * `control` (*string*) **Required** The type of action. Currently `button` and `image` are supported. * `class_name` (*string*) Optional classname for this action * `image` (*object*) Properties associate with an `image` action. - * `url` (*string*) Location of the image to display. - * `placement` (*string*) Placement of image relative to a property. Values are `right` or `left`. - * `size` (*object*) Pixel size of the image. - * `height` (*number*) Image height in pixels. - * `width` (*number*) Image width in pixels. - * `tooltip_direction` (*string*) Set tooltip direction for action image. Values are `right`, `left`, `top`, or `bottom`. Default is `bottom`. + * `url` (*string*) Location of the image to display. + * `placement` (*string*) Placement of image relative to a property. Values are `right` or `left`. + * `size` (*object*) Pixel size of the image. + * `height` (*number*) Image height in pixels. + * `width` (*number*) Image width in pixels. + * `tooltip_direction` (*string*) Set tooltip direction for action image. Values are `right`, `left`, `top`, or `bottom`. Default is `bottom`. * `button` (*object*) Properties associated with action button. * `kind` (*string*) Button kind. Values are same as carbon button kind values. Default is `tertiary`. * `size` (*string*) Button size. Values are sm, md, lg, xl. Default is `sm`. @@ -322,11 +325,13 @@ Action info attributes. ## Resource Definition Used for user facing text. Allows for default values if no translations are provided. + * `default` (*string*) Default value if `resource_key` not defined. * `resource_key` (*string*) Used as a key for enum value labels in the resources section of property definition. ## Dynamic text expressions Used to dynamically set text based on a parameter value change. If parameter id is used then then current value for that parameter will be passed into the function. + * `percent(, )` Return the percent of the 1st parameter. The optional 2nd parameter determines the number of decimal places. * `sum(, , ...)` Returns the sum of all parameters diff --git a/guide/3.3-Common-Properties-Controls.md b/guide/3.3-Common-Properties-Controls.md index f29493e47c..37123d60f7 100644 --- a/guide/3.3-Common-Properties-Controls.md +++ b/guide/3.3-Common-Properties-Controls.md @@ -97,6 +97,7 @@ In order to indicate that a given node can potentially accept multiple input dat ### edit_style When editing complex type values in tables one can either edit cell values inline or in a sub panel: + * `subpanel` A small sub-dialog is launched to edit cell values. * `inline` Controls appear inline within table cells for editing values. * `on_panel` Control appears below the table when the row is selected. diff --git a/guide/3.4-Common-Properties-Conditions.md b/guide/3.4-Common-Properties-Conditions.md index 33f19068e1..bccd0f01b8 100644 --- a/guide/3.4-Common-Properties-Conditions.md +++ b/guide/3.4-Common-Properties-Conditions.md @@ -11,16 +11,17 @@ A conditions file contains an array of conditions. Each condition takes one of t A single validation. The fail_message is displayed upon validation failure. The attributes for the validation definition are: + * `id` (*string*) A unique identifier for the validation. This is required if multiple validations have the same `focus_parameter_ref` value. * `fail_message` (*object*) **Required** The message to display if the validation fails. Each fail_message consist of the following attributes + `message` (*object*) **Required** The message to display. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + `focus_parameter_ref` (*string*) **Required** The parameter control to get focus after displaying the error/warning. If the validation refers to a table cell, then control must have the column indicator. For example if the validation is for `MyTable` cell column 2 then `MyTable[2]`. + `type` (*string*) Type of messages. Valid values are `error, warning, info`. * `evaluate` (*object*) Specification for how to evaluate the validity of the parameter. The evaluate attribute can be one of the following structures. - + `condition` (*object*) This is a single condition that evaluates to true or false. - - `op` (*string*) **Required** A single operator for the properties of the condition. Valid values are: + + `condition` (*object*) This is a single condition that evaluates to true or false. + - `op` (*string*) **Required** A single operator for the properties of the condition. Valid values are: `isEmpty`, `isNotEmpty`, `greaterThan`, @@ -53,6 +54,7 @@ The attributes for the validation definition are: Enablement test. Disables controls if evaluate is false. The attributes for the enabled definition are: + * `parameter_refs` (*array[string]*) Array of parameter names affected by this operation. If evaluate is false, then the controls associated with these parameters are disabled. Note that individual radio buttons can be disabled by using the radio button value name instead of the overall property name in the parameter_refs array. * `action_refs` (*array[string]*) Array of action names affected by this operation. If evaluate is false, then the action button or image associated with these action names are disabled. * `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. @@ -61,6 +63,7 @@ The attributes for the enabled definition are: Visibility test. Hides controls if evaluate is false. The attributes for the visible definition are: + * `parameter_refs` (*array[string]*) Array of parameter names affected by this operation. If evaluate is false, then hide the controls associated with these parameters. * `action_refs` (*array[string]*) Array of action names affected by this operation. If evaluate is false, then the action button or image associated with these action names are disabled. * `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. @@ -69,11 +72,13 @@ The attributes for the visible definition are: Filter test. The filter will determine which data record fields to include in a control. The attributes for the filter definition are: + * `parameter_ref` (*string*) Parameter id affected by this operation. This must be a parameter that operates upon datarecord-metadata columns. * `parameter_refs` (*string*) Exclusive with `parameter_ref` and used with `dmSharedFields`. Parameter ids affected by this operation. They must be parameters that operate upon datarecord-metadata columns. * `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. Supported operations (`op`): + * `dmType` - filters `type` value from schema. * `dmMeasurement` - filters `measurement` value from schema. * `dmModelingRole` - filters `modeling_role` value from schema. @@ -127,6 +132,7 @@ Supported operations (`op`): Filters the available options for enumeration parameters. Reduces the available enumeration items if evaluate is true. The attributes for the enum_filter definition are: + * `target` (*object*) Contains a target *parameter_ref* reference and a replacement *values* array. * `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. @@ -156,6 +162,7 @@ The attributes for the enum_filter definition are: Allow change validates that a change is allowed on a property. If it evaluates to true then the value for the property is changed. This is typically used to restrict values that are invalid in one property based on the value in another property. For example, if the property represents a storage type with a value of `string`, then a property that represents a measurement type should not be allowed to be set to `continuous`. The attributes for the allow_change definition are: + * `parameter_refs` (*array[string]*) Array of parameter names affected by this operation. * `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. @@ -192,6 +199,7 @@ The attributes for the allow_change definition are: Sets the default value on the `parameter_ref` property if condition evaluates to true. If multiple conditions evaluate to true only the first condition is used. Default value condition is evaluated only once when loading properties. If user updates the value of `parameter_ref`, default value will be overwritten by the new value. The attributes for the default_value definition are: + * `parameter_ref` (*string*) Parameter whose default value is to be set. * `value` (*string, boolean, number, object, array*) This will be the default value of parameter_ref if condition evaluates to true. * `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. diff --git a/guide/3.5-Common-Properties-Custom-Components.md b/guide/3.5-Common-Properties-Custom-Components.md index e57655740a..cf2dcd29fc 100644 --- a/guide/3.5-Common-Properties-Custom-Components.md +++ b/guide/3.5-Common-Properties-Custom-Components.md @@ -42,15 +42,16 @@ constructor(parameters, controller, data) // Returns the content users want to display renderPanel() ``` + - **parameters** - String array of parameters set under the customPanel group in uihints - **controller** - See [here](/3.6-Common-Properties-Controller) for API information. - **data** - Optional parameter. Returns values stored in `data` attribute of a group `customPanel`. - **renderPanel()** - Called on all Redux store changes: - - property value changes ([property APIs](/3.6-Common-Properties-Controller#property-methods)) - - state changes ([state APIs](/3.6-Common-Properties-Controller#state-methods-disableenabled--hiddenvisible)) - - schema changes ([schema APIs](/3.6-Common-Properties-Controller#datasetmetadata-methods)) - - row selection changes ([selection APIs](/3.6-Common-Properties-Controller#row-selection-methods)) - - messages changes ([message APIs](/3.6-Common-Properties-Controller#message-methods)) + - property value changes ([property APIs](/3.6-Common-Properties-Controller#property-methods)) + - state changes ([state APIs](/3.6-Common-Properties-Controller#state-methods-disableenabled--hiddenvisible)) + - schema changes ([schema APIs](/3.6-Common-Properties-Controller#datasetmetadata-methods)) + - row selection changes ([selection APIs](/3.6-Common-Properties-Controller#row-selection-methods)) + - messages changes ([message APIs](/3.6-Common-Properties-Controller#message-methods)) ### Custom react components @@ -85,18 +86,19 @@ constructor(propertyId, controller, data, tableInfo) // Returns the content users want to display renderControl() ``` + - **propertyId** - See [propertyId](/3.6-Common-Properties-Controller#common-properties-controller-api) for definition. - **controller** - See [here](/3.6-Common-Properties-Controller) for API information. - **data** - Returns values stored in `data` attribute of a parameter in uihints. - **tableInfo** - Set when custom control is a cell in a table. - - table (boolean) Set to true when in a table cell - - editStyle (string) Valid values are "summary" and "inline". "summary" is set when the control will display either below the table ("on_panel") or in a "subpanel". This allows the custom control to display a summary value in the cell and something else for the custom control. + - table (boolean) Set to true when in a table cell + - editStyle (string) Valid values are "summary" and "inline". "summary" is set when the control will display either below the table ("on_panel") or in a "subpanel". This allows the custom control to display a summary value in the cell and something else for the custom control. - **renderControl()** - Called on all Redux store changes: - - property value changes ([property APIs](/3.6-Common-Properties-Controller#property-methods)) - - state changes ([state APIs](/3.6-Common-Properties-Controller#state-methods-disableenabled--hiddenvisible)) - - schema changes ([schema APIs](/3.6-Common-Properties-Controller#datasetmetadata-methods)) - - row selection changes ([selection APIs](/3.6-Common-Properties-Controller#row-selection-methods)) - - messages changes ([message APIs](/3.6-Common-Properties-Controller#message-methods)) + - property value changes ([property APIs](/3.6-Common-Properties-Controller#property-methods)) + - state changes ([state APIs](/3.6-Common-Properties-Controller#state-methods-disableenabled--hiddenvisible)) + - schema changes ([schema APIs](/3.6-Common-Properties-Controller#datasetmetadata-methods)) + - row selection changes ([selection APIs](/3.6-Common-Properties-Controller#row-selection-methods)) + - messages changes ([message APIs](/3.6-Common-Properties-Controller#message-methods)) ### Custom react components @@ -135,9 +137,10 @@ function op() */ function evaluate(paramInfo, param2Info, value, controller) ``` + - paramInfo (object) - `parameter_ref` set in the `condition` in uihints - - control (object) - contains information about the control. - - value (any) - current property value + - control (object) - contains information about the control. + - value (any) - current property value - param2Info (object) - `parameter_2_ref` set in the `condition` in uihints. See `paramInfo` for object info - value - `value` set in the `condition` in uihints. If no value specific this will be `undefined` - **controller** - See [here](/3.6-Common-Properties-Controller) for API information. diff --git a/guide/3.6-Common-Properties-Controller.md b/guide/3.6-Common-Properties-Controller.md index 908b7dd569..c2ce85b539 100644 --- a/guide/3.6-Common-Properties-Controller.md +++ b/guide/3.6-Common-Properties-Controller.md @@ -11,7 +11,11 @@ const propertyId = { ``` ### Property methods ```js -setPropertyValues(values) +/* + * options - optional object of config options where + * setDefaultValues (boolean): when set to true, set default values from parameter definition +*/ +setPropertyValues(values, options) updatePropertyValue(propertyId, value) /* * options - optional object of config options where @@ -144,6 +148,17 @@ getEditorSize() * @paramDef - Follows the format of https://github.com/elyra-ai/pipeline-schemas/blob/master/common-canvas/parameter-defs/parameter-defs-v3-schema.json */ setParamDef(paramDef) + +/* +* Returns the id of top-level active tab or accordion +*/ +getTopLevelActiveGroupId() + + +/* +* Makes the passed in groupId active. Only works for top-level groups +*/ +setTopLevelActiveGroupId(groupId) ``` ### Disable move row buttons methods diff --git a/guide/5.0-Styling.md b/guide/5.0-Styling.md index cdc82431ad..37efa794e0 100644 --- a/guide/5.0-Styling.md +++ b/guide/5.0-Styling.md @@ -3,6 +3,7 @@ ### CSS styling for quick start If you just want to get up and running and don't care about scss then import these regular css files: + - carbon-components/css/carbon-components.min.css - @elyra/canvas/dist/styles/common-canvas.min.css - version 8.x and older @elyra/canvas/dist/common-canvas.min.css @@ -17,11 +18,14 @@ If you want to use the full power of scss styling with variable overrides etc th @import "carbon-components/scss/globals/scss/styles"; @import "@elyra/canvas/src/index.scss"; ``` + - use `autoprefixer` when building - if using webpack under the `sass-loader` and make sure to include + ```js options: { includePaths: ["node_modules"] } ``` + Again, you can refer to the test harness [index.scss file](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/styles/index.scss) for sample code. @@ -38,10 +42,12 @@ You can see an example of this in the common-canvas test harness (which is the e ### 3rd party styling If you are using the expression builder in common-properties then also include these libraries: + - codemirror/addon/hint/show-hint.css - codemirror/lib/codemirror.css If you are using common-properties then also include the react-virtualized styles: + - react-virtualized/styles.css ## Elyra Canvas styling guidelines diff --git a/guide/6.0-Testing-Guidelines-for-Development.md b/guide/6.0-Testing-Guidelines-for-Development.md index f524c3d632..9f0866c268 100644 --- a/guide/6.0-Testing-Guidelines-for-Development.md +++ b/guide/6.0-Testing-Guidelines-for-Development.md @@ -23,9 +23,9 @@ Functional Testing coverage includes the following types of tests. * Need to test both forward and backwards compatibility * Negative / bounds * Globalization / Localization - * Handling of all strings using UTF-8 - * Verifying non-English unicode data is handled appropriately - * Externalizing all strings that may be presented for the user (e.g., error messages, UI labels, etc.) + * Handling of all strings using UTF-8 + * Verifying non-English unicode data is handled appropriately + * Externalizing all strings that may be presented for the user (e.g., error messages, UI labels, etc.) * Access control security (roles / permissions / tenant management) * Malicious and security (code scans such as AppScan, ethical hacking) * Accessibility for UI @@ -36,6 +36,7 @@ Functional Testing coverage includes the following types of tests. https://facebook.github.io/jest/docs/troubleshooting.html **With node 8 or newer** + - Add `debugger;` statement to your Jest test suite program where you want to stop and begin debugging. - If you want to run just a single test within your test program (rather than all of them) temporarily change the it() method for the test to be it.only(). For example, change: diff --git a/mkdocs.yml b/mkdocs.yml index 9c86144342..fbb3a8e2a5 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -30,6 +30,8 @@ nav: - Home: index.md - Common Canvas Documentation: 2.0-Common-Canvas-Documentation.md - Canvas Editor: 2.0.1-Canvas-Editor.md + - Nodes: 2.0.1.1-Nodes.md + - Links: 2.0.1.2-Links.md - Palette: 2.0.2-Palette.md - Context Menu: 2.0.3-Context-Menu.md - Context Toolbar: 2.0.4-Context-Toolbar.md From 5dae51d69c5277c0feaf75807bc1baddd8fd7c1e Mon Sep 17 00:00:00 2001 From: srikant Date: Wed, 21 Feb 2024 20:23:57 +0530 Subject: [PATCH 03/20] Add instructions related to mkdocs setup in Readme Signed-off-by: srikant --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 91424c56c6..21045760a3 100644 --- a/README.md +++ b/README.md @@ -50,3 +50,15 @@ Delete @elyra/canvas from node_modules of your application # Run npm install to get local copy of common-canvas and/or common-properties npm install ``` + +### Contribute to the Elyra Canvas documentation (mkdocs) +1. Python v3 needs to be available. +2. Install required mkdocs packages using pip3. +``` +pip3 install -r requirements.txt` +``` +3. Run below command to start mkdocs server +``` +mkdocs serve +``` +4. When complete, open the browser: http://127.0.0.1:8000/ From a129d9b762a6c192a5c62be988ebac794ee8e256 Mon Sep 17 00:00:00 2001 From: srikant Date: Thu, 22 Feb 2024 12:06:46 +0530 Subject: [PATCH 04/20] Update Readme, mkdocs.yml and Styling.md as per feedback Signed-off-by: srikant --- README.md | 10 +++++++--- guide/5.0-Styling.md | 4 ---- mkdocs.yml | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 21045760a3..165d0edecf 100644 --- a/README.md +++ b/README.md @@ -53,12 +53,16 @@ npm install ### Contribute to the Elyra Canvas documentation (mkdocs) 1. Python v3 needs to be available. -2. Install required mkdocs packages using pip3. +2. Go to canvas directory. + +3. Install required mkdocs packages using pip3. ``` pip3 install -r requirements.txt` ``` -3. Run below command to start mkdocs server + +4. Run below command to start mkdocs server. ``` mkdocs serve ``` -4. When complete, open the browser: http://127.0.0.1:8000/ + +5. When complete, open the browser: http://127.0.0.1:8000/ diff --git a/guide/5.0-Styling.md b/guide/5.0-Styling.md index 37efa794e0..d106a33aed 100644 --- a/guide/5.0-Styling.md +++ b/guide/5.0-Styling.md @@ -41,10 +41,6 @@ You can see an example of this in the common-canvas test harness (which is the e ### 3rd party styling -If you are using the expression builder in common-properties then also include these libraries: - - - codemirror/addon/hint/show-hint.css - - codemirror/lib/codemirror.css If you are using common-properties then also include the react-virtualized styles: diff --git a/mkdocs.yml b/mkdocs.yml index fbb3a8e2a5..edf52c1ef9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,4 +1,4 @@ -site_name: Elyra Guide +site_name: Elyra Canvas Guide repo_url: https://github.com/elyra-ai/canvas docs_dir: guide @@ -24,7 +24,7 @@ extra_javascript: edit_uri: edit/main/guide/ # Documentation and theme -copyright: 'Copyright © 2023 IBM Watson Team, an open source project and all are welcome to contribute!
Maintained by the SPSS Modeler Team' +copyright: 'Copyright © 2024. Maintained by the Elyra Canvas Team., an open source project and all are welcome to contribute!
Maintained by the SPSS Modeler Team' nav: - Home: index.md From 4b0322a326daa8a82eeff8477ee73733a7a289c6 Mon Sep 17 00:00:00 2001 From: srikant Date: Fri, 23 Feb 2024 12:15:59 +0530 Subject: [PATCH 05/20] Update new documentation as per comments and include github action file for deployment Signed-off-by: srikant --- .github/workflows/ci.yml | 29 +++++++++++++++++++ guide/2.0-Common-Canvas-Documentation.md | 2 +- guide/4.0-Accessibility.md | 3 -- guide/{5.0-Styling.md => 4.0-Styling.md} | 0 ...5.0-Testing-Guidelines-for-Development.md} | 0 guide/index.md | 8 ++--- mkdocs.yml | 9 +++--- 7 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 guide/4.0-Accessibility.md rename guide/{5.0-Styling.md => 4.0-Styling.md} (100%) rename guide/{6.0-Testing-Guidelines-for-Development.md => 5.0-Testing-Guidelines-for-Development.md} (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..c712c2f3c7 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,29 @@ +name: ci +on: + push: + branches: + - master + - main +permissions: + contents: write +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Configure Git Credentials + run: | + git config user.name github-actions[bot] + git config user.email 41898282+github-actions[bot]@users.noreply.github.com + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV + - uses: actions/cache@v4 + with: + key: mkdocs-material-${{ env.cache_id }} + path: .cache + restore-keys: | + mkdocs-material- + - run: pip install mkdocs-material + - run: mkdocs gh-deploy --force \ No newline at end of file diff --git a/guide/2.0-Common-Canvas-Documentation.md b/guide/2.0-Common-Canvas-Documentation.md index a98fbbd221..04d984121b 100644 --- a/guide/2.0-Common-Canvas-Documentation.md +++ b/guide/2.0-Common-Canvas-Documentation.md @@ -128,7 +128,7 @@ Some examples of pipeline flow JSON files can be found here: https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/test_resources/diagrams ## Step 6 : Pull in the CSS -Check this section to find info on what CSS to include in your application's CSS. [Styling](./5.0-Styling.md). +Check this section to find info on what CSS to include in your application's CSS. [Styling](./4.0-Styling.md). ## Step 7 : Display the canvas diff --git a/guide/4.0-Accessibility.md b/guide/4.0-Accessibility.md deleted file mode 100644 index 5fd27c0020..0000000000 --- a/guide/4.0-Accessibility.md +++ /dev/null @@ -1,3 +0,0 @@ -## Tips -- All input elements need to have a visual indication `focus` is set. This is different then selection. -- Use the correct html element for inputs. For example don't use a `div` with a click event. Use a `button` or `a` instead. \ No newline at end of file diff --git a/guide/5.0-Styling.md b/guide/4.0-Styling.md similarity index 100% rename from guide/5.0-Styling.md rename to guide/4.0-Styling.md diff --git a/guide/6.0-Testing-Guidelines-for-Development.md b/guide/5.0-Testing-Guidelines-for-Development.md similarity index 100% rename from guide/6.0-Testing-Guidelines-for-Development.md rename to guide/5.0-Testing-Guidelines-for-Development.md diff --git a/guide/index.md b/guide/index.md index fbb3d8dda6..8d5dea28c3 100644 --- a/guide/index.md +++ b/guide/index.md @@ -1,4 +1,4 @@ -# Welcome to the Elyra Canvas Wiki +# Welcome to the Elyra Canvas Documentation The elyra-ai/canvas repo contains three main components: @@ -10,9 +10,9 @@ The elyra-ai/canvas repo contains three main components: ## Installation -You'll need to build your application with common canvas. +You'll need to build your application with Elyra Canvas. -* common-canvas requires react, react-dom, react-intl, and react-redux libraries to be installed. See peerDependencies in package.json for versions requirements. +* Elyra Canvas requires react, react-dom, react-intl, and react-redux libraries to be installed. See peerDependencies in package.json for versions requirements. Use the command: ```sh @@ -74,7 +74,7 @@ render() { ## Notes When building your application you will need to load fonts and override styles can be found here: -/5.0-Styling +[Styling](./4.0-Styling) ## Testing When testing your application with Jest, this error might show up: `crypto.getRandomValues() not supported`. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported for details. diff --git a/mkdocs.yml b/mkdocs.yml index edf52c1ef9..fe932cee25 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,4 +1,4 @@ -site_name: Elyra Canvas Guide +site_name: Elyra Canvas Documentation repo_url: https://github.com/elyra-ai/canvas docs_dir: guide @@ -24,7 +24,7 @@ extra_javascript: edit_uri: edit/main/guide/ # Documentation and theme -copyright: 'Copyright © 2024. Maintained by the Elyra Canvas Team., an open source project and all are welcome to contribute!
Maintained by the SPSS Modeler Team' +copyright: 'Copyright © 2024 Elyra Authors, an open source project and all are welcome to contribute! Maintained by the Elyra Authors Team' nav: - Home: index.md @@ -58,9 +58,8 @@ nav: - Common Properties Conditions: 3.4-Common-Properties-Conditions.md - Common Properties Custom Components: 3.5-Common-Properties-Custom-Components.md - Common Properties Controller: 3.6-Common-Properties-Controller.md - - Accessibility: 4.0-Accessibility.md - - Styling: 5.0-Styling.md - - Testing Guidelines for Development: 6.0-Testing-Guidelines-for-Development.md + - Styling: 4.0-Styling.md + - Testing Guidelines for Development: 5.0-Testing-Guidelines-for-Development.md markdown_extensions: - admonition: From 32f0f38f6e5921eacc9f96f219001a6561d9a5d7 Mon Sep 17 00:00:00 2001 From: srikant Date: Fri, 23 Feb 2024 12:20:42 +0530 Subject: [PATCH 06/20] Update username and id in ci.yml for github pages Signed-off-by: srikant --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c712c2f3c7..32e300b107 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,8 +13,8 @@ jobs: - uses: actions/checkout@v4 - name: Configure Git Credentials run: | - git config user.name github-actions[bot] - git config user.email 41898282+github-actions[bot]@users.noreply.github.com + git config srikant-ch5 github-actions[bot] + git config srksriks123@gmail.com 41898282+github-actions[bot]@users.noreply.github.com - uses: actions/setup-python@v5 with: python-version: 3.x From c6aab846543bac6abb3607da1be97acd13cb4fb1 Mon Sep 17 00:00:00 2001 From: srikant Date: Fri, 23 Feb 2024 12:48:24 +0530 Subject: [PATCH 07/20] Update username and id as default Signed-off-by: srikant --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 32e300b107..c712c2f3c7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,8 +13,8 @@ jobs: - uses: actions/checkout@v4 - name: Configure Git Credentials run: | - git config srikant-ch5 github-actions[bot] - git config srksriks123@gmail.com 41898282+github-actions[bot]@users.noreply.github.com + git config user.name github-actions[bot] + git config user.email 41898282+github-actions[bot]@users.noreply.github.com - uses: actions/setup-python@v5 with: python-version: 3.x From d88a8d7c8cedaedc907789f06797f0caabc164e4 Mon Sep 17 00:00:00 2001 From: srikant Date: Fri, 23 Feb 2024 12:51:32 +0530 Subject: [PATCH 08/20] Update new-guide branch in ci.yml Signed-off-by: srikant --- .github/workflows/ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c712c2f3c7..56064889fd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,8 +2,7 @@ name: ci on: push: branches: - - master - - main + - new-guide permissions: contents: write jobs: From 7252eb7feca5a8da0d6d4ea57720d3cd965c3900 Mon Sep 17 00:00:00 2001 From: srikant Date: Fri, 23 Feb 2024 15:15:36 +0530 Subject: [PATCH 09/20] Test using readthedocs theme Signed-off-by: srikant --- docs/2.0-Common-Canvas-Documentation.md | 241 +++++ docs/2.0.1-Canvas-Editor.md | 11 + docs/2.0.1.1-Nodes.md | 1 + docs/2.0.1.2-Links.md | 62 ++ docs/2.0.2-Palette.md | 40 + docs/2.0.3-Context-Menu.md | 5 + docs/2.0.4-Context-Toolbar.md | 37 + docs/2.1-Config-Objects.md | 627 ++++++++++++ docs/2.2-Common-Canvas-callbacks.md | 704 +++++++++++++ ...ling-node-creation-from-external-object.md | 77 ++ docs/2.4-Canvas-Controller-API.md | 945 ++++++++++++++++++ ...2.4.0-Calling-the-Canvas-Controller-API.md | 39 + docs/2.4.1-Style-Specification.md | 69 ++ docs/2.4.2-Decoration-Specification.md | 195 ++++ docs/2.4.3-Object-structure-used-by-API.md | 49 + ....4.4-Notification-Message-Specification.md | 31 + ...grammatically-creating-new-canvas-nodes.md | 64 ++ ...nstructing-a-read-only-or-locked-canvas.md | 57 ++ docs/2.5-Command-Stack-API.md | 79 ++ docs/2.6-Flow-Validation-API.md | 62 ++ .../2.7-Customizing-Node-Layout-Properties.md | 392 ++++++++ .../2.8-Context-Menu-Wrapper-Documentation.md | 67 ++ docs/2.9-External-Subflows-support.md | 75 ++ docs/3.0-Common-Properties-documentation.md | 315 ++++++ ...-Common-Properties-Parameter-Definition.md | 261 +++++ docs/3.2-Common-Properties-UI-Hints.md | 348 +++++++ docs/3.3-Common-Properties-Controls.md | 111 ++ docs/3.4-Common-Properties-Conditions.md | 361 +++++++ ...3.5-Common-Properties-Custom-Components.md | 180 ++++ docs/3.6-Common-Properties-Controller.md | 351 +++++++ docs/4.0-Styling.md | 56 ++ .../5.0-Testing-Guidelines-for-Development.md | 53 + docs/css/styles.css | 7 + docs/index.md | 90 ++ mkdocs.yml | 14 +- 35 files changed, 6066 insertions(+), 10 deletions(-) create mode 100644 docs/2.0-Common-Canvas-Documentation.md create mode 100644 docs/2.0.1-Canvas-Editor.md create mode 100644 docs/2.0.1.1-Nodes.md create mode 100644 docs/2.0.1.2-Links.md create mode 100644 docs/2.0.2-Palette.md create mode 100644 docs/2.0.3-Context-Menu.md create mode 100644 docs/2.0.4-Context-Toolbar.md create mode 100644 docs/2.1-Config-Objects.md create mode 100644 docs/2.2-Common-Canvas-callbacks.md create mode 100644 docs/2.3-Enabling-node-creation-from-external-object.md create mode 100644 docs/2.4-Canvas-Controller-API.md create mode 100644 docs/2.4.0-Calling-the-Canvas-Controller-API.md create mode 100644 docs/2.4.1-Style-Specification.md create mode 100644 docs/2.4.2-Decoration-Specification.md create mode 100644 docs/2.4.3-Object-structure-used-by-API.md create mode 100644 docs/2.4.4-Notification-Message-Specification.md create mode 100644 docs/2.4.5-Programmatically-creating-new-canvas-nodes.md create mode 100644 docs/2.4.6-Constructing-a-read-only-or-locked-canvas.md create mode 100644 docs/2.5-Command-Stack-API.md create mode 100644 docs/2.6-Flow-Validation-API.md create mode 100644 docs/2.7-Customizing-Node-Layout-Properties.md create mode 100644 docs/2.8-Context-Menu-Wrapper-Documentation.md create mode 100644 docs/2.9-External-Subflows-support.md create mode 100644 docs/3.0-Common-Properties-documentation.md create mode 100644 docs/3.1-Common-Properties-Parameter-Definition.md create mode 100644 docs/3.2-Common-Properties-UI-Hints.md create mode 100644 docs/3.3-Common-Properties-Controls.md create mode 100644 docs/3.4-Common-Properties-Conditions.md create mode 100644 docs/3.5-Common-Properties-Custom-Components.md create mode 100644 docs/3.6-Common-Properties-Controller.md create mode 100644 docs/4.0-Styling.md create mode 100644 docs/5.0-Testing-Guidelines-for-Development.md create mode 100644 docs/css/styles.css create mode 100644 docs/index.md diff --git a/docs/2.0-Common-Canvas-Documentation.md b/docs/2.0-Common-Canvas-Documentation.md new file mode 100644 index 0000000000..04d984121b --- /dev/null +++ b/docs/2.0-Common-Canvas-Documentation.md @@ -0,0 +1,241 @@ +## Introduction +Common canvas displays a flow of data operations as nodes and links which the user can create and edit to get the flow they want. These visual flows of data operations are translated into data processing steps performed by a back-end server. Common canvas provides functionality for the visual display of flows in the browser and leaves persistence and execution of data flows to the application. +Within common canvas the user can perform operations such as: + +* Create a new node by dragging a node definition from a palette onto the canvas. +* Create a new node by dragging a node from outside the canvas onto the canvas (you'll have to do some programming to get this to work). +* Delete a node by clicking a context menu option. +* Create a link by dragging a line from one node to another. +* Delete a link by clicking a context menu option. +* Add a comment to the canvas and draw a link from it to one or more nodes. +* Edit a comment. +* Move nodes and comments around in the canvas to get the desired arrangement. +* And more! ... + +# Architecture + +## Common Canvas react object + Common-canvas is a react component that can be used in your react application to display a fully-functional canvas user interface including the function mentioned above. The `` component is displayed in a `
` provided by your application. + +Common-canvas has these constituent parts that are visible to the user: + +* [Canvas editor](/2.0.1-Canvas-Editor/) - the main area of the UI where the flow is displayed and edited +* [Palette](/2.0.2-Palette/) - a set of node templates that can be dragged to the canvas to create new nodes +* [Context menu](/2.0.3-Context-Menu/) - a menu of options for nodes, comments, etc +* [Context toolbar](/2.0.4-Context-Toolbar/) - a menu of options for nodes, comments, etc presented as a small toolbar +* Toolbar - a set of tools across the top of the UI +* Notification panel - a panel for displaying runtime and other messages to your user +* Right side flyout - a panel, often used to display node properties +* Top panel - a panel which can be used to display other app related information +* Bottom panel - a panel which can be used to display other app related information + +and it handles: + + 1. the visual display of the flow of operations; + 2. any user gestures on the canvas; + 3. display of context menus; + 4. display and handling of the palette. + 5. provision of callbacks to tell your code what operations the user is performing on the canvas + 6. and much much more. + +## Canvas Controller + +The only mandatory parameter for the `` component is a regular JavaScript object called the [CanvasController](/2.4-Canvas-Controller-API/). + + The CanvasController routes handles calls from the host application and actions performed by the user. It then updates the internal object model which stores: + + 1. the data that describes the flow of nodes, links and comments (called a pipelineFlow); + 2. the data that describes the definition of the palette which contains node templates that can dragged to add nodes to the canvas; + 3. the set of currently selected objects. + 4. notification messages + 5. breadcrumbs that indicate which sub-flow is being viewed + 6. layout information + + The [CanvasController](/2.4-Canvas-Controller-API/) provides an API which allows your code to: + + 1. set a new pipelineFlow; + 2. get the current pipelineFlow (after the user has edited it); + 3. update and edit objects in the canvas (for example, add node, delete link etc.); + 4. set the node definition data (for display of nodes in the palette) + +# Getting started with common canvas programming + +## Hello Canvas! + You can start by looking at these two 'hello world' examples for using common canvas: + +* This first one called [app-tiny.js](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/client/app-tiny.js) has the bare minimum necessary to get a fully functioning common-canvas to appear including all the basic functionality, a palette and a flow of nodes and links. +* The second, called [app-small.js](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/client/app-small.js), shows many of the options available to a common-canvas developer such as configurations and callback handlers. + +You can also look at the [App.js](https://github.com/elyra-ai/canvas/blob/49ed634e3353d8f5c58eb8409ed8e1009f19c87a/canvas_modules/harness/src/client/App.js) file in the test harness section of this repo to see examples of code that uses the common canvas component. + + Now let's walk through the different steps to get common-canvas working: + + +## Step 1 : Install Elyra Canvas NPM module + +Enter: +``` + npm install @elyra/canvas +``` + +## Step 2 : Import Common-canvas + +To use common canvas in your react application you need to do the following. First import the CommonCanvas react component and CanvasController class from the Elyra Canvas library. Elyra Canvas produces both `esm` and `cjs` outputs. By default `esm` will be used when webpack is used to build the consuming application. + +**All Components** +```js + import { CommonCanvas, CanvasController } from "@elyra/canvas"; +``` +**Canvas only** + + To import only canvas functionality in `cjs` format use: +```js + import { CommonCanvas, CanvasController } from "@elyra/canvas/dist/lib/canvas"; +``` + +In addition you'll need to import `` from the `react-intl` library. +```js + import { IntlProvider } from "react-intl"; +``` + + +## Step 3 : Create an instance of the canvas controller +To control the canvas you'll need an instance of the canvas controller so create an instance of it like this (probably in the constructor of your object). +```js + this.canvasController = new CanvasController(); +``` +## Step 4 : Set the palette data +Next you'll need to populate the palette data. This will specify the nodes (split into categories) that will appear in the palette. The user can drag them from the palette to build their flow. This is done by calling CanvasController with: +```js + this.canvasController.setPipelineFlowPalette(pipelineFlowPalette); +``` +The pipelineFlowPalette object should conform to the JSON schema found here: +https://github.com/elyra-ai/pipeline-schemas/tree/master/common-canvas/palette + +Some examples of palette JSON files can be found here: +https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/test_resources/palettes + +## Step 5 : (Optional) Set the flow data +This is an optional step. If you want a previously saved flow to be shown in the canvas editor so the user can start to edit it, you will need to call the CanvasController with: +```js + this.canvasController.setPipelineFlow(pipelineFlow); +``` + +The pipelineFlow object should conform to the JSON schema found here: +https://github.com/elyra-ai/pipeline-schemas/tree/master/common-pipeline/pipeline-flow + +Some examples of pipeline flow JSON files can be found here: +https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/test_resources/diagrams + +## Step 6 : Pull in the CSS +Check this section to find info on what CSS to include in your application's CSS. [Styling](./4.0-Styling.md). + +## Step 7 : Display the canvas + +Finally you'll need to display the canvas object inside an `` object. Inside your render code, add the following: +```html +
+ + + +
+``` +The div should have the dimensions you want for your canvas to display in your page. For the canvasController property, pass the instance of canvas controller you created earlier. This is the only mandatory property. After providing this and running your code you will have a fully functioning canvas including: a palette; default toolbar; context menus; direct manipulation (move and resize) etc. To customize these behaviors and presentation continue with the sections below. + +## Common Canvas customization +If you want to customize the behavior of common canvas you can specify any combination of the following optional settings: +```html +
+ + +
+``` + +### Config objects +Common canvas has five **optional** configuration objects: config, toolbarConfig, notificationConfig, contextMenuConfig and keyboardConfig. +They are documented here: +[Config Objects](/2.1-Config-Objects) + +### Handlers +There are several **optional** handlers implemented as callback functions. They are contextMenuHandler, editActionHandler, beforeEditActionHandler, clickActionHandler, decorationActionHandler, layoutHandler, tipHandler, idGeneratorHandler, selectionChangeHandler and actionLabelHandler. They are documented here: +[Common Canvas Callback](/2.2-Common-Canvas-callbacks) + +### Right-flyout panel parameters +The right flyout panel appears on the right of the canvas area. You can add whatever content you like to this panel. Typically, it is used to display properties of nodes on the canvas. There are two **optional** parameters to let you manage the right flyout panel These are: + +- showRightFlyout: This can be true or false to indicate whether the flyout panel is shown or not. The default is false. +- rightFlyoutContent: content to display in the right flyout which is a JSX object. Nothing is displayed by default. + +### Bottom panel parameters +The bottom panel appears below the canvas area and between the palette and the right flyout panel. You can add whatever content you like to this panel. There are two **optional** parameters to let you manage the bottom panel. These are: + +- showBottomPanel: This can be true or false to indicate whether the bottom panel is shown or not. The default is false. +- bottomPanelContent: content to display in the bottom panel which is a JSX object. Nothing is displayed by default. + +### Top panel parameters +The top panel appears below the toolbar and between the palette and the right flyout panel. You can add whatever content you like to this panel. There are two **optional** parameters to let you manage the top panel. These are: + +- showTopPanel: This can be true or false to indicate whether the top panel is shown or not. The default is false. +- topPanelContent: content to display in the top panel which is a JSX object. Nothing is displayed by default. + +### Localization +You can customize `` using the `` object to [display translated test](/#localization) + +## Creating nodes on the canvas + +Nodes can be created on the canvas by the user in two ways: + +* By dragging a node from the palette onto the canvas background +* By dragging a node from outside the canvas + +The first technique is provided by Common canvas. The second requires some development work which is documented here: +[Enabling node creation from external object](/2.3-Enabling-node-creation-from-external-object) + + +## Keyboard support + +Common canvas supports a number of keyboard interactions as follows: + +|Keyboard Shortcut|Action|Description| +|---|---|---| +|Ctrl/Cmnd + a|selectAll|Select All objects +|delete|deleteSelectedObjects|Delete currently selected objects| +|Ctrl/Cmnd + x|cut|Cut selected objects to the clipboard| +|Ctrl/Cmnd + c|copy|Copy selected objects to the clipboard| +|Ctrl/Cmnd + v|paste|Paste objects from the clipboard. If the mouse cursor is over
the canvas, objects will be pasted at the cursor position or,
if not, at a default position| +|Ctrl/Cmnd + z|undo|Undo last command| +|Ctrl/Cmnd + Shift + z|redo|Redo last undone command| +|Ctrl/Cmnd + y|redo|Redo last undone command| + + +Your application can disable any or all of these actions by providing the [keyboard config object](/2.1-Config-Objects#keyboard-config-object) to the CommonCanvas react component. + +When any of the shortcut keys are pressed the common-canvas object model will be updated and then the [editActionHandler](/2.2-Common-Canvas-callbacks#editactionhandler) callback will be called with the `data.editType` parameter set to the action above and the `data.editSource` parameter set to "keyboard". diff --git a/docs/2.0.1-Canvas-Editor.md b/docs/2.0.1-Canvas-Editor.md new file mode 100644 index 0000000000..728db155b4 --- /dev/null +++ b/docs/2.0.1-Canvas-Editor.md @@ -0,0 +1,11 @@ +The Canvas Editor displays the flow to the user and allows the user to interact with the flow using the mouse/trackpad and the keyboard. + +The editor displays the following object types which the user can interact with: + +## Nodes +## Links +## Comments +## The Canvas background + + +[Still under construction] \ No newline at end of file diff --git a/docs/2.0.1.1-Nodes.md b/docs/2.0.1.1-Nodes.md new file mode 100644 index 0000000000..bedcb0af63 --- /dev/null +++ b/docs/2.0.1.1-Nodes.md @@ -0,0 +1 @@ +[Under construction] \ No newline at end of file diff --git a/docs/2.0.1.2-Links.md b/docs/2.0.1.2-Links.md new file mode 100644 index 0000000000..1adca82cd6 --- /dev/null +++ b/docs/2.0.1.2-Links.md @@ -0,0 +1,62 @@ +## Introduction +Common-canvas is designed to display one link line on the canvas for each link defined in the pipeline flow. There are three types of link supported by common canvas: data links; association links; and comment links. Links can be enhanced by: + +* Overriding the CSS styles applied to the elements of the link line +* By specifying decorations for the link + +## Data Links +Data links are designed to model a flow from a source node to a target node. Data links are defined in the pipeline flow to connect a port on the source node to a port on the target node. The host application can choose whether or not to display ports on the nodes. Data links are typically displayed with an arrow head to display the flow along the link from source to target. + +If a data link is retrieved from the canvas controller API it will have the following important fields: + +* id - the unique identifier for the link. +* type - set to "nodeLink". +* srcNodeId - the ID of the node the link is connected from. +* srcNodePortId - the ID of the output port on the source node the link is connected from. Note: If this is undefined it indicates the node is connected to the first output port of the source node. +* trgNodeId - the ID of the node the link is connected to. +* trgNodePortId - the ID of the input port on the target node the link is connected to. Note: If this is undefined it indicates the node is connected to the first input port of the target node. +* decorations - an array of decorations specified for the link. +* app_data - any application specific data that was previously specified for the link in the pipeline flow or through the canvas controller API. + +Note: Typically data links must be drawn between nodes however, if the config field `enableLinkSelectionType` is set to `Detachable`, the links are allowed to be drawn to and/or from arbitrary points on the canvas. If a link is drawn either semi-detached (from one node) or fully-detached (from both nodes) the following fields will be in the link object: + +* srcPos - this is an object with two fields x_pos and y_pos. These provide the coordinates of the point on the canvas that the link is drawn from. If this exist then srcNodeId and srnNodePortId are not specified in the link object. +* trgPos - this is an object with two fields x_pos and y_pos. These provide the coordinates of the point on the canvas that the link is drawn to. If this exist then srcNodeId and srnNodePortId are not specified in the link object. + +## Association Links + +Association links are designed to capture a relationship between two nodes where there is no implied direction. By default these are displayed as a single straight link line in a dashed style. There are no arrow heads by default for that type of link. (Note : internally, association links do have a `srcNodeId` and `trgNodeId` but that is just to keep the field names consistent with the data links.) Association links do not reference ports. + +If an association link is retrieved from the canvas controller API it will have the following important fields: + +* id - the unique identifier for the link. +* type - set to "associationLink". +* srcNodeId - the ID of one of the nodes in the association. +* trgNodeId - the ID of the other node in the association. +* decorations - an array of decorations specified for the link. +* app_data - any application specific data that was previously specified for the link in the pipeline flow or through the canvas controller API. + +## Comment Links +Comment links connect a comment to one or more nodes. They can be created by the user by: (a) pulling out the small handle/circle that appears below a comment and dropping it on a node. (2) by selecting nodes before the comment is selected and then creating the comment. This will automatically create a comment link from the selected nodes to the newly created comment. + +If a comment link is retrieved from the canvas controller API it will have the following important fields: + +* id - the unique identifier for the link +* type - set to "commentLink" +* srcNodeId - the ID of comment. +* trgNodeId - the ID of the node the comment is connected to. +* app_data - any application specific data that was previously specified for the link in the pipeline flow or through the canvas controller API. + + +## Display of links +Links are drawn on the canvas using SVG elements in the DOM. Each link has a top level group `` element and inside it some SVG paths. The first displayed path is the selection area. This is invisible but provides a selection/hover area for mouse interactions on the link. The second is a path to represent the link itself which is drawn over the top of the selection area path: + +| Purpose | DOM tag | Classes | Notes | +| :---------- | :----------------------------------- | :---------- | :----------------------------------- | +|Group | g | d3-link group | Classes specified for the link in the class_name field of the link object will be added here. | +|⮕ Selection area| path | d3-link-selection-area | | +|⮕ Link line | path | d3-link-line | | +|⮕ Arrow head | path | d3-link-line-arrow-head | Only when enableLinkType is set to "Straight" | +|⮕ Decorations | g | d3-link-decorations-group | Will contain decoration elements, for example, image, path etc | + +Note: The main link group will also have one of these classes: d3-node-link (for data links), d3-object-link (for association links) or d3-comment-link (for comment links). \ No newline at end of file diff --git a/docs/2.0.2-Palette.md b/docs/2.0.2-Palette.md new file mode 100644 index 0000000000..6369b28b60 --- /dev/null +++ b/docs/2.0.2-Palette.md @@ -0,0 +1,40 @@ +## Introduction +By default, common-canvas includes a palette which appears in the left flyout panel. The palette displays a set of node templates split into different categories. The user can drag any of the node templates from the palette onto the canvas to create a new instance of a node on the canvas. The user can then join nodes together by creating link lines. + +## Populating the palette +The host application must tell common-canvas what node templates and categories it wants the user to see in the palette. This is done by providing common-canvas with a palette (JavaScript) object by calling the canvas-controller `setPipelineFlowPalette(palette)` method. The palette object is often read from a JSON document stored in the host application's repository or it can be automatically generated. + +The palette object should conform to the [palette schema](https://github.com/elyra-ai/pipeline-schemas/blob/412d70176953ed9ac2e6a03f7135b09b7565fc5d/common-canvas/palette/palette-v3-schema.json). The host application can ensure that palette conforms to the schema by switching on [schema validation](/2.1-Config-Objects#schemavalidation) in the canvas configuration. + +## Auto-join +Instead of dragging node templates from the palette, the user can double click node templates to add, and automatically join, them to the current flow. When a node template is double clicked, common-canvas will look for the node at the end of the current flow of nodes and will add the node to the canvas to the right of the end node in the flow. Common-canvas will also automatically join the nodes together by creating a new link line. + +## Palette configuration +There are a number of configuration options that control the palette that are specified in the canvas config object: + +* [enablePaletteLayout](/2.1-Config-Objects#enablepalettelayout) +* [enableNarrowPalette](/2.1-Config-Objects#enablenarrowpalette) +* [enableAutoLinkOnlyFromSelNodes](/2.1-Config-Objects#enableautolinkonlyfromselnodes) +* Deprecated - [paletteInitialState](/2.1-Config-Objects#paletteinitialstate) + +## Palette operation +The palette contents can be manipulated calling these canvas-controller [palette methods](/2.4-Canvas-Controller-API#palette-methods) + +The palette can be opened and closed using these canvas-controller [operational methods](/2.4-Canvas-Controller-API#palette-methods-1) + +## Search +The user can enter a search string into the Search field at the top of the palette. The behavior is as follows: + +1. When the search field is empty, the palette shows categories which can be expanded to show the node templates within the expanded category. +2. As the user enters characters into the search field, common-canvas immediately searches through the node template labels, node template descriptions and category labels for the characters entered and finds a subset of the node templates that match the search string. Common-canvas then replaces the category-based view of the palette with a list of node templates that match the search criteria. In this view the node templates also include the node description under the node label. +3. The search is case insensitive. +4. The search text is highlighted wherever it appears in the labels, descriptions or category labels. +5. Common-canvas uses a ranking algorithm to order the display of node templates so those most relevant to the search text are positioned at the top of the list. The ranking algorithm puts more weight on those node templates where the search text appears in the label than if the text appears in the description or the category label. +6. If the user enters words into the search field (separated by spaces), common-canvas searches for each word separately. Therefore, if say the user entered "data import" into the search field, common-canvas would find a node with "`Import` `Data`" as the label or even a node with a description that said "This node does lots of things and also `data` can be `import`ed." +7. Nodes that have text which have hits on multiple words are ranked more highly than node templates whose text only contains one search word. +8. Common-canvas uses a debounce function so that, if the user types the search string very quickly, common-canvas does not perform multiple searches for each key press but only runs a full search when rapid typing has ended. + +## Recommendation +According to the schema, node template descriptions are not mandatory in the palette object. However, it is recommended you provide descriptions for each of your node templates. The reason for this is that, the search function searches through node template descriptions, as well as node template labels and category labels. This means you can write your node template descriptions to contain appropriate keywords that a user might search for when looking for a node. + +For example, if there is a node template called ‘Import Data’ and that node could import comma-separated files you could add ‘comma-separated’ and ‘csv’ into your description for that node template. If the user entered `comma` in the search field the ‘Import Data’ node template would be shown in the search results even though `comma` does not appear in the node template label. \ No newline at end of file diff --git a/docs/2.0.3-Context-Menu.md b/docs/2.0.3-Context-Menu.md new file mode 100644 index 0000000000..993829a9a4 --- /dev/null +++ b/docs/2.0.3-Context-Menu.md @@ -0,0 +1,5 @@ +A context menu is a small window containing a list of options applicable to an object or set of selected objects. + +When [`enableContextToolbar`](/2.1-Config-Objects#enablecontexttoolbar) is set to `false` (or omitted) from the canvas config, and a right-click is performed on a node, link, comment or the canvas background, a traditional context menu is displayed like this: + +image \ No newline at end of file diff --git a/docs/2.0.4-Context-Toolbar.md b/docs/2.0.4-Context-Toolbar.md new file mode 100644 index 0000000000..89279bf163 --- /dev/null +++ b/docs/2.0.4-Context-Toolbar.md @@ -0,0 +1,37 @@ +Context toolbars can be enabled in common-canvas as an alternative to traditional context menus. + +A context toolbar is a small toolbar that appears above nodes, links and comments as the mouse cursor is hovered over them. A context toolbar for the canvas background can also be displayed by right-clicking on the canvas background. + +The context toolbar displays a set of icons that represent the most likely actions the user would want to perform on the object under the mouse cursor. If necessary, the toolbar can also show an overflow (vertical ellipsis) icon that, when clicked, reveals additional actions that can be performed on the object. + + +For a "vertical" style node the context toolbar looks like this: + +image + +For a “horizontal” style node it looks like this: + +image + +when the user clicks the overflow icon it looks like this: + +image + +Note: Since the mouse cursor can be hovered over a node, comment or link that is NOT currently selected, the actions shown in the context toolbar will apply to just that object, even if there is one or more currently selected objects. + +If the mouse cursor is hovered over a selected object when there are other selected objects, the actions in the context toolbar will be applicable to all the selected objects. This is the same as how a traditional content menu shows actions that are applicable to the set of selected objects. + + +The context toolbar behavior can be switched on by setting the [`enableContextToolbar`](/2.1-Config-Objects#enablecontexttoolbar) canvas configuration field to true. + +``` + const config = { + enableContextToolbar: true + }; + + ... + ... + +``` + + diff --git a/docs/2.1-Config-Objects.md b/docs/2.1-Config-Objects.md new file mode 100644 index 0000000000..5c3fffbe99 --- /dev/null +++ b/docs/2.1-Config-Objects.md @@ -0,0 +1,627 @@ +# Canvas Config object + +The canvas config object is optional. If it is not provided, or any of the properties within it are not provided, common-canvas will use reasonable defaults. Here's an example of a canvas config object: +```js + const commonCanvasConfig = { + "enableNodeFormatType": "Vertical", + "enableLinkType": "Straight" + } + }; +``` +and this is how it is specified to common-canvas: +```js + render() { + return ( + + ); + } + +``` + +## Canvas Config fields + +#### **enableInteractionType** +This can be "Mouse", "Carbon" or "Trackpad". The default is "Mouse". +***"Trackpad" has been deprecated and will be removed in the future.*** + +* With this set to "Mouse" the following interaction is enabled: + * Zoom canvas = Rotate mouse wheel. +(Can be simulated with a trackpad with two finger up and down scroll) + * Pan canvas = Left mouse key down on canvas background + drag. +(Can be simulated with a trackpad with press down on trackpad and drag.) + * Region select on canvas = Shift key + left mouse key down on canvas background + drag. +(Can be simulated with a trackpad with Shift + finger down on trackpad + drag across canvas background) + +* With this set to "Carbon" the following interaction is enabled: + * Zoom canvas = Rotate mouse wheel. +(Can be simulated with a trackpad with two finger up and down scroll) + * Pan canvas = Press and hold space bar then left mouse key down on canvas background + drag. +(Can be simulated with a trackpad by press and hold space bar then press down on trackpad and drag.) + * Region select on canvas = Left mouse key down on canvas background + drag. +(Can be simulated with a trackpad with press down on trackpad and drag.) + +* **This setting is now deprecated** With this set to "Trackpad" the following interactions are enabled: + * Zoom canvas = Two finger pinch or two finger spread gesture. +(Can be simulated with a mouse as follows: Ctrl + rotate mouse wheel.) + * Pan canvas = Two finger horizontal or vertical scroll gesture. +(Can be simulated with a mouse as follows: Vertical pan is rotate mouse wheel; Horizontal pan is Shift + rotate mouse wheel) + * Region select on canvas = Finger down + drag. +(Can be simulated with a mouse as follows: Left button down + drag on canvas background) + +#### **enableNodeFormatType** +This can be "Horizontal" or "Vertical". "Horizontal" is the default. "Horizontal" will display a node with an image and the label to the right of the image. "Vertical" will display the node with the label underneath the image.See the section called [Customizing Node Layout Properties](/2.7-Customizing-Node-Layout-Properties) for details on what this will do. + +#### **enableLinkType** +This can be "Curve", "Elbow", or "Straight". "Curve" is the default. This will set the link style used to connect nodes. + +#### **enableLinkDirection** +This can be "LeftRight", "TopBottom", or "BottomTop". "LeftRight" is the default. This will set the input and output port positions on nodes to facilitate links being drawn in the direction specified. + +* For "LeftRight" output ports will be on the right and input ports will be on the left of the nodes +* For "TopBottom" output ports will be on the bottom and input ports will be on the top of the nodes +* For "BottomTop" output ports will be on the top and input ports will be on the bottom of the nodes + +#### **enableLinkSelection** +This can be: "None", "LinkOnly", "Handles" or "Detachable". The default is "None". These have the following affect on the canvas: + +* "None" - no selection of links is possible however user can right click on a link to get a context menu. +* "LinkOnly" - a link may be selected and added to the set of currently selected objects (nodes and/or comments). +* "Handles" - This includes the "LinkOnly" function. In addition, when a link is selected a handle (either a circle or an image) is displayed at the start and end of the link. The link handle can be dragged to a new node/port position to rewire the flow. +* "Detachable" - This includes the "LinkOnly" and "Handles" function. In addition, this option enables detachable links for the canvas. This means a link can exist either: + * between a source node and an arbitrary point on the canvas (semi-detached) OR + * between an arbitrary point on the canvas and a target node (semi-detached) OR + * between two arbitrary points on the canvas (detached) + + Additionally, "Detachable" mode, allows: + + - semi-detached or fully-detached links to be stored in and retrieved from the pipeline flow document. + - semi-detached or fully-detached links to be manipulated with link handles. The link handles can be used to drag the end of the link away from its connecting source or target nodes and onto the canvas. Or semi-detached or fully detached links can be reattached to nodes/ports. + - a new detached link to be created by drawing out a new link from a node and dropping it onto the canvas. + - palette and canvas nodes, when they are dragged, to be dropped onto the ends of detached links to automatically attach them to the node being dragged. + +#### **enableLinkReplaceOnNewConnection** +This can be true or false. The default is false. If set to true, the user can drag a new connection to a target node, and if the input port on the target node has a maximum cardinality of one AND there is currently a connection to that port, the existing connection will be removed and the new connection is created; essentially this gesture replaces the existing link with the new one. If set to false the new connection will not be completed and the existing link will remain in place. + +When set to true and a link is replaced, common-canvas will call the `beforeEditActionHandler` the `editActionHandler` callback functions, if either are provided by the host application, with a `data` object parameter with the `editType` field set to `"linkNodesAndReplace"`. + +#### **enableParentClass** +This is a string which is a class name. The default is empty string. If a class name is provided it is applied to the top-most DOM element for common-canvas. This can be used to make you CSS override rules more specific which means they will be used in preference to any default styles. For example, if you specify "my-app-styles" for this field then CSS like this: +```css + .my-app-styles .d3-node-body-outline { + fill: orange; + } +``` +will override the style from the common-canvas CSS +```css + .d3-node-body-outline { + fill: white; + } +``` + +## enableImageDisplay + +This can be set to: "SVGInline", "LoadSVGToDefs" or "SVGAsImage". The default is "SVGInline". This field controls the display of SVG image files (that is, files with a `.svg` extension) on the canvas, such as those displayed for node icons or decoration images. This option can be useful to improve performance when images are repeated a large number of times on the canvas and particularly when the browser cache is disabled. Note: this does not affect the display behavior of non-SVG files which are always displayed inside an `` tag. The behavior for SVG image files is as follows: + +* "SVGInline" - This is the default. With this setting, the image file is read in -- from the server or cache (if available) -- and the SVG tags within the file displayed in-line in the DOM. This means elements within the SVG can be customized using CSS on a node-by-node basis. +* "LoadSVGToDefs" - With this option, each unique SVG file is read from the server (or cache) and written into a `` element within the `` element of the canvas SVG area. A `` element is then written to the place in the DOM for each place where the image should be displayed. Using this option means the SVG file for each image is only read once which should improve performance if images are repeated a lot on the canvas. However, it does limit the customization possibilities for the images on a node-by-node basis. Customization colors can be passed into the images using CSS inheritance, or the `currentColor` keyword, provided there are no internal classes applied to the elements in the SVG. +* "SVGAsImage" - This option causes the SVG file to be displayed within an `` element in the DOM. The file loading is handled internally by the browser. Again, with this option customization capabilities on a node-by-node basis are limited. Customization colors can be passed into the images using CSS inheritance, or the `currentColor` keyword, provided there are no internal classes applied to the elements in the SVG. + +#### **enableInternalObjectModel** +This is a boolean. The default is `true`. You should use `true` for this all the time. If you set this to `false` your code will be responsible for handling the object model, which is NOT recommended. When `false`, changes are not set into the object model, and consumers are expected to listen to events and update the internal object model themselves (again, *not* recommended). + +#### **enablePaletteLayout** +This can be: "Modal" or "Flyout" or "None". The default is "Flyout". "Flyout" displays a panel on the left side of the canvas containing the palette icons and "Modal" shows the palette icons in a dialog window. "None" stops the palette from appearing. + +#### **enableToolbarLayout** +This can be: "Top" or "None". The default is "Top". "Top" displays a toolbar at the top of the canvas area. See the [toolbar configuration object docs](/2.1-Config-Objects#toolbar-config-object) for details on how to customize the toolbar. "None" stops the toolbar from appearing. + +#### **enableResizableNodes** +This can be true or false. The default is false. If set to true, the user can resize nodes by dragging the edges of the node to increase or decrease the width and/or height of the node. When hovering the mouse cursor over the edge of the node the user will see a sizing cursor to indicate the resize function is available. This option works best when the node has a background rectangle that shows the extent of the sizing area. + +#### **enableInsertNodeDroppedOnLink** +This can be true or false. The default is false. If set to true, the user can drag nodes from the palette or from the canvas and drop them onto existing links in the flow. This causes the dropped node to be inserted between the two nodes joined by the link, meaning new links are created that join the new node to the previously joined nodes and the old link is removed. When the user performs the drop common-canvas will call the editActionHandler with one of two possible commands: + +* "createNodeOnLink" - when a node is being dragged from the palette leading to node creation & insertion +* "insertNodeIntoLink" - when an existing node is dragged from the canvas leading to insertion of the existing node into the link + +#### **enableRightFlyoutUnderToolbar** +This can be true or false. The default is false. If set to true the right flyout panel, when opened, will appear below the toolbar and will not cause the toolbar to compress. The default behavior is that the right flyout panel, when opened, will appear at the side of the toolbar and will compress the space available for the toolbar to be displayed. Warning: the notifications panel which is tied to the notifications icon in the toolbar will appear over the top of the right-side flyout with this option set to true. + +#### **enablePositionNodeOnRightFlyoutOpen** +This can be a boolean or an object. The default is false. If set to true, when the right-side flyout is open the currently selected node (assuming there is one) will be automatically positioned in the center of the viewport (canvas area). Instead of true this field can also be set to a simple JavaScript object like this `{ x: 30, y: 40 }` where x and y indicate the position where the node will be positioned as a percentage of the width and height of the viewport respectively. + +#### **enableHighlightNodeOnNewLinkDrag** +This can be true or false. The default is false. If set to true common-canvas will add the "data-new-link-over" attribute to the node's group `` element, when the end of a new link is dragged to be close to and over a target node. This allows applications to alter the appearance of the target node as a new link is dragged towards it. + +#### **enableHighlightUnavailableNodes** +This can be true or false. The default is false. If set to true, when the user begins to drag a new link line, common-canvas will add a new class called `d3-node-unavailable` to all nodes which cannot accept the link as input. The class will be applied to each node's group `` element in the DOM. This class can be used for styling the unavailable nodes as desired using CSS. The default styling will 'gray out' the node label, node outline rectangle (if there is one) and the node icon (provided it is an SVG image). These styles can be overridden in the applications CSS if different styling is needed. This behavior also applies if the end of a partially or fully detached link is dragged. + +#### **enableRaiseNodesToTopOnHover** +This can be true or false. The default is true. If set to false the nodes will be left in their original place in the DOM. If set to true, when the user moves the mouse cursor over a node, that node will be moved in the DOM so that the node appears on top of all other nodes. This is only really noticeable if nodes, or parts of nodes, overlap other nodes. It can be useful if your nodes have protruding ports or decorations and your users sometimes position nodes very close to one another. Note: the 'true' setting can adversely affect the behavior of scroll areas in a node that are displayed using a React object (using the `nodeExternalObject` node layout option) because when the node is moved in the DOM the scroll area gets reset to its initial position. Set this to false if you are displaying nodes using React objects. + + +#### **enableAutoLinkOnlyFromSelNodes** +This can be true or false. The default is false. When set to true the auto-add function (where double clicking a node in the palette automatically adds it to the canvas) will only link up nodes when a node is already selected on the canvas and then, only if the selected node can be linked to the node that was double clicked. If false, the auto-add function will make a best guess at which node the double-clicked node should be added to. + +#### **enableMoveNodesOnSupernodeResize** +This can be true or false. The default is true. If true, nodes surrounding a supernode will be moved when the supernode is expanded or manually resized so that the supernode does not overlay them. When set to false, the nodes surrounding a supernode will stay in their current positions when the supernode is expanded or manually resized. This may result in the nodes being overlaid by the supernode. + +#### **enableExternalPipelineFlows** +This can be true or false. The default is false. If true, the context menu will include a `Create External Supernode` option when a set of objects are selected from which a supernode can be created. + +Waring: The host application must implement some of the common-canvas callbacks for external pipeline flow support to work correctly. See the Wiki section on [external pipeline flow support](/2.9-External-Subflows-support) for more details. + +#### **enableDisplayFullLabelOnHover** +This can be true or false. The default is false. If set to true, any abbreviated node label will be displayed in full when the pointer hovers over the label. If set to false, abbreviated node labels will remain the same when the pointer hovers over them. + +#### **enableSingleOutputPortDisplay** +This can be true or false. The default is false. If set to true, only the last of the ports from the array of output ports will be displayed for each node. This config property is only applicable to applications with very specialized styling and handling of ports. If set to true with regular applications, it may result in a confusing display to the user. The single port is displayed at a position specified by outputPortRightPosX and outputPortRightPosY layout properties. For exmaple: +```js +config = { + enableSingleOutputPortDisplay: true, + enableNodeLayout: { + outputPortRightPosX: 0, + outputPortRightPosY: 20 +}; +``` +#### **enableDragWithoutSelect** +This can be either true or false. The default is false. If set to true, the user can drag and drop a single node or a single comment without that gesture removing selection on any other nodes or comments. If the node being dragged was selected prior to the drag gesture then it and any other objects that are currently selected will be moved. With this parameter set to false (or missing) a drag and drop gesture will select the node or comment being dragged and will deselect any currently selected objects. + +#### **enableMarkdownInComments** +This can be true or false. The default is false. When set to true the user may enter markdown syntax into comments on the canvas when in edit mode for the comment. When the editing ends, the comment is shown in presentation mode and the markdown syntax is converted to HTML which is displayed in the comment and is styled by CSS. + +#### **enableStateTag** +This can be either "None", "Locked" or "ReadOnly". The default is "None". When set to either "Locked" or "ReadOnly", a 'state tag' object will be shown permanently over the top of the canvas. The state tag will be positioned in the center and towards the top of the canvas. The state tag consists of a black background rectangle with rounded corners overlaid with an icon and a text label. A tooltip is displayed when the mouse pointer is hovered over the state tag. The icon, label and default tooltip will be set appropriately based on the value ("Locked" or "ReadOnly") for this setting. The host application can override the tooltip by implementing the [tipHandler callback](/2.2-Common-Canvas-callbacks#tiphandler). + +#### **enableEditingActions** +This can be true or false. The default is true. If set to false, various editing actions on the canvas will be prevented, as follows: + +1. Nodes cannot be created on the canvas using any of the following: + + (a) dragging and dropping a node template from the palette onto the canvas or + + (b) dragging and dropping an object onto the canvas from outside the canvas area, such as a file being dragged from the computer desktop onto the canvas (see note below), or + + (c) double clicking a node in the palette to create a node + + Note: It is not possible for common-canvas to prevent an object being dragged from the computer desktop to the canvas so it is recommended the drop zone (which provides visual feedback about the drop) should be switched off by setting the [enableDropZoneOnExternalDrag](/2.1-Config-Objects#enabledropzoneonexternaldrag) config field to `false`. + +2. Nodes and comments cannot be dragged and moved. +3. The end points of Links, when [enableLinkSelection](/2.1-Config-Objects#enablelinkselection) is set to `"Detachable"` or `"Handles"`, cannot be dragged and moved. +4. Links from nodes and comments cannot be created by dragging from the port object on the source node or comment to the target node. +5. Comments, node labels and text decorations cannot be edited, neither by clicking the edit icon (which does not appear) nor by double clicking the text. +6. Context menu options that alter the canvas objects will be removed from the context menu before it is displayed by common-canvas. The options that will be removed are: + + |Option Text|Action Identifier| + |---|---| + |New Comment|createComment| + |Disconnect|disconnectNode| + |Edit->Cut|cut| + |Edit->Copy|copy| + |Edit-Paste|paste| + |Undo|undo| + |Redo|redo| + |Delete|deleteSelectedObjects| + |Create supernode|createSuperNode| + |Create external supernode|createSuperNodeExternal| + |Deconstruct supernode|deconstructSuperNode| + |Collapse supernode|collapseSuperNodeInPlace| + |Expand supernode|expandSuperNodeInPlace| + |Convert external to local|convertSuperNodeExternalToLocal| + |Convert local to external |convertSupernodeLocalToExternal| + |Delete|deleteLink| + |Save to palette|saveToPalette| + + If your application adds its own editing actions to the context menu your code must remove them if they are not needed in some situations (e.g. you are displaying a read-only canvas). + +7. Any default toolbar actions (tools) that alter the canvas objects will be disabled regardless of their specified enablement status. These actions are: + + |Default Tooltip|Action| + |---|---| + |Undo|undo| + |Redo|redo| + |Cut|cut| + |Copy|copy| + |Paste|paste| + |Delete|deleteSelectedObjects| + |New comment|createAutoComment| + |Arrange Horizontally|arrangeHorizontally| + |Arrange Vertically|arrangeVertically| + +8. Keyboard shortcuts that alter the canvas will not work. These are: + + |Shortcut|Action| + |---|---| + |delete|delete| + |Ctrl/Cmd + x|cut| + |Ctrl/Cmd + c|copy| + |Ctrl/Cmd + v|paste| + |Ctrl/Cmd + z|undo| + |Ctrl/Cmd + Shift + z|redo| + |Ctrl/Cmd + y|redo| + +9. The browser's Edit menu options (cut, copy, paste) will not work with the canvas objects regardless of the setting for [enableBrowserEditMenu](/2.1-Config-Objects#enablebrowsereditmenu). + +#### **enableDropZoneOnExternalDrag** +This can be true or false. The default is false. If set to true a graphic overlay will be displayed over the canvas when a data object icon is dragged from the desktop over the canvas. The default graphic overlay will be an image and a message saying: "Drop to add to canvas and project" unless the `dropZoneCanvasContent` configuration parameter is provided. + +See the [Dragging an object from the desktop](/2.3-Enabling-node-creation-from-external-object#dragging-object-from-the-desktop-or-another-application) section of the Wiki for details on how to handle the drop of an external object onto the canvas. + +#### **enableNodeLayout** +This is a simple Javascript object, the properties of which override the default node layout properties. For more details see: [Customizing Node Layout Properties](/2.7-Customizing-Node-Layout-Properties) + +#### **enableSaveZoom** +This can be: "None", "LocalStorage" or "Pipelineflow". The default is "None". + +* "None" - When the canvas is zoomed, the zoom (scale and x/y pan) are not saved anywhere so if the canvas is closed and reopened it reopens with the default zoom which is a scale of 1 and x/y pan values of 0. +* "LocalStorage" - The zoom for the canvas is stored in the browser's local storage and will be reapplied to the canvas each time that canvas is shown in that browser. This applies to sub-flows, when the user displays them full-screen, as well as the primary flow. Sub-flows and the primary flow each have their own zoom amounts stored in local storage. Note: Zoom amounts stored in local storage can be cleared from storage by calling the `canvasController.clearSavedZoomValues()` API method. +* "Pipelineflow" - The zoom is serialized into the pipeline flow document and when a pipeline flow document is provided to common canvas through the API the zoom will be applied to the canvas display. Zoom amounts can be stored for both primary and sub pipelines. (See the pipelineFlow schema specification). + +#### **enablePanIntoViewOnOpen** +This can be either true or false. The default is false. If set to true, the canvas will be panned so as much of the canvas area (the area containing the nodes and comments) is visible in the viewport as possible. This will only happen when enableSaveZoom === "None" or if there is no saved zoom available either in local storage (when enableSaveZoom === "LocalStorage") or in the pipelineFlow (when enableSaveZoom === "Pipelineflow"). + +#### **enableZoomIntoSubFlows** +This is a boolean. The default is false. When set to true, common-canvas will override the maximum zoom extent value which, by default is used for the entire canvas, to allow the user to zoom in on in-place sub-flows further than they can do on containing flows. This means the user can zoom in on multi-nested sub-flows so they are easier to view. To see this effect, the user must position the mouse pointer over the sub-flow before performing the zoom gesture. + +#### **enableContextToolbar** +This is a boolean. The default is false. When set to true, common-canvas will display a context toolbar instead of a context menu for performing actions on canvas objects. A context toolbar is a small toolbar that appears above nodes, links and comments as the mouse cursor is hovered over them. The toolbar shows icons for actions the user is most likely to want to perform on the object. An overflow icon is displayed which, when clicked, shows a menu of additional actions. A context toolbar for the canvas background can also be displayed by right-clicking on the background. Common-canvas will display default context toolbars for nodes, links comments and the canvas background however the default actions can be customized by implementing the [`contextMenuHanlder`](/2.2-Common-Canvas-callbacks#contextmenuhandler) callback. + +#### **enableSnapToGridType** +This can be: "None", "During" or "After". The default is "None". + +* "None" - there is no snap to grid and objects can be moved to any position on the canvas. +* "During" - when nodes or comments are moved or sized, the objects snap to an imaginary grid while the objects are being dragged or sized. This gives a somewhat jerky effect as the move or size is happening but has the advantage of telling the user exactly where the object will be when they release the mouse button to end the action. +* "After" - nodes or comments snap to a grid when the drag or size event ends. This gives a smooth dragging and sizing effect but the user does not see the final position until they release the mouse button at the end of the action. By default the canvas uses reasonable values for the grid increments. + +#### **enableSnapToGridX** +This optional value overrides the default horizontal increment of the snap-to-grid grid. It can be either a numeric value which is a number of pixels or it can be a numeric value followed by a % sign (e.g. "25%") which indicates the grid will be a percentage of the default node width. Its default is dependent on whatever is set for enableNodeFormatType. That is for "Horizontal" it will be "20%" and for "Vertical" it will be "25%". + +#### **enableSnapToGridY** +This optional value overrides the default vertical increment of the snap-to-grid grid. It can be either a numeric value which is a number of pixels or it can be a numeric value followed by a % sign (e.g. "25%") which indicates the grid will be a percentage of the default node height. Its default is dependent on whatever is set for enableNodeFormatType. That is for "Horizontal" it will be "33.33%" and for "Vertical" it will be "20%". + +#### **enableAutoLayoutVerticalSpacing** +This is the spacing in pixels which is used to separate nodes vertically when either the vertical or horizontal auto layout action is used. + +#### **enableAutoLayoutHorizontalSpacing** +This is the spacing in pixels which is used to separate nodes horizontally when either the vertical or horizontal auto layout action is used. For horizontal auto layout, common-canvas may override this value if it decides that more space is needed to prevent connecting lines from doubling back on themselves. + +#### **enableAssocLinkCreation** +This is a Boolean. The default is `false`. If set to `true` it changes the nature of links that are created between nodes as follows: + +- The user is able to pull out a link from either port on the node and drag it to another node +- When a link is completed an `association` link is created rather than the regular data flow link that is created when this field is set to `true`. Association links describe an association between pairs of nodes and do not indicate any kind of data flow between those nodes. + +#### **enableAssocLinkType** +This can be "Straight" or "RightSideCurve". The default it "Straight". This field changes the way association links are drawn on the canvas. + +#### **enableBrowserEditMenu** +This can be true or false. true is the default. If true, the Cut/Copy/Paste items in the Browser's `Edit` menu, including keyboard input for those actions, can be used for performing those actions on objects (e.g. Nodes) in the canvas. When false, those items in the Browser's edit menu, including keyboard input for those actions, will not work for objects in the canvas. This will not prevent those actions working in the canvas when, say, invoked with the toolbar or canvas context menus, but this property can be used if the keyboard input for those actions into the canvas is disabled for common-canvas using the [keyboard config](/2.1-Config-Objects#keyboard-config-object) object. + +#### **enableNarrowPalette** +This can be true or false. true is the default. If true when the palette is closed the narrow palette will be shown. When false the palette completely closes. + +#### **paletteInitialState** +Deprecated -- This option is deprecated and will be removed soon. Use `CanvasController.openPalette()` to display an opened palette at start-up. This `openPalette()` can be called immediately after creating the canvas controller. + +paletteInitialState can be true or false. false is the default. If set to true the palette will be opened when common canvas first appears to its full (non-narrow) state. + +#### **emptyCanvasContent** +This is a JSX or HTML snippet that contains some text or any elements (such as an image) that you want to display when the canvas is empty, that is, when it doesn't have any nodes or comments. The default behavior if this config parameter is not provided is that common canvas will display an image and message saying: "Your flow is empty!". + +#### **dropZoneCanvasContent** +This is a JSX or HTML snippet that contains some text or any elements (such as an image) that you want to display when a data object is dragged from the desktop over the canvas. The default behavior if this config parameter is not provided is that common canvas will display an image and a message saying: "Drop to add to canvas and project". The content will not be displayed unless the `enableDropZoneOnExternalDrag` configuration parameter (see above) is set to true. + +#### **schemaValidation** +This can be true or false. false is the default. It tells common canvas whether you want pipleineFlow and palette objects to be validated against the schema files when they are submitted to the canvas controller, using the `setPipelineFlow(pFlow)` or `setPipelineFlowPalette(palette)` methods. If any validation errors are found messages are displayed in the browser console. It is recommended this option be set to true during development and testing but switched off in production since schema validation can be somewhat slow for large objects. + +#### **tipConfig** +This is a simple JavaScript object that configures whether tips for palette items, nodes, ports, links, decorations or the state tag are enabled (value set to true) or disabled (value set to false). By default, all tips are enabled. The following would switch off tips for ports and links. +```js + "tipConfig": { + "palette": true, + "nodes": true, + "ports": false, + "links": false, + "decorations": true, + "stateTag": true + } +``` +The tips displayed by the palette can be further refined. For example, this would prevent tips for palette categories from being displayed, but would still display tips for node templates in the categories: +```js + "tipConfig": { + "palette": { + "categories": false, + "nodeTemplates": true + }, + "nodes": true, + "ports": false, + "links": false, + "decorations": true, + "stateTag": true + } +``` + +Note: The default content of tips can be overwritten by implementing the [tipHandler callback](/2.2-Common-Canvas-callbacks#tiphandler). + +# Toolbar Config object + +The toolbar config object is optional. If it is not provided common-canvas will display a reasonable default toolbar. If provided, it configures which action items (tools) and dividers are shown in the canvas toolbar. A toolbar will only be displayed for common-canvas if the canvas configuration field [`enableToolbarLayout`](/2.1-Config-Objects#enabletoolbarlayout) is set to "Top" (which is the default). + +If you do specify a toolbar config object, you can specify actions for the left and right side of the toolbar to override the default toolbar. You can also optionally tell the toolbar not to handle the enable/disable state for the standard toolbar buttons using `overrideAutoEnableDisable`. The `leftBar` and `rightBar` fields contain an array of objects: one element for each toolbar item. Here is an example, toolbar configuration object: + +```js + const toolbarConfig = { + leftBar: [ + { action: "undo", label: "Undo", enable: true }, + { action: "redo", label: "Redo", enable: true }, + { divider: true }, + { action: "cut", label: "Cut", enable: false }, + { action: "copy", label: "Copy", enable: false }, + { action: "paste", label: "Paste", enable: false }, + { divider: true }, + { action: "createAutoComment", label: "Add Comment", enable: true }, + { action: "deleteSelectedObjects", label: "Delete", enable: true }, + { action: "arrangeHorizontally", label: "Arrange Horizontally", enable: true } + { divider: true }, + { action: "insaneMode", label: "Switch on insane mode", enable: true, isSelected: true } + ], + rightBar: [ + { action: "stop", label: "Stop Execution", enable: false }, + { divider: true }, + { action: "run", label: "Run Pipeline", enable: false } + ], + overrideAutoEnableDisable: false + }; +``` +Where: + +* **leftBar** - an array of action items to specify what is displayed on the left side of the toolbar. + +* **rightBar** - an array of action items to specify what is displayed on the right side of the toolbar. If this is omitted, common-canvas will automatically populate the right side of the toolbar with zoom-in, zoom-out, and zoom-to-fit actions. To suppress these right side actions, specify the `rightBar` field as an empty array or an array containing the actions you want on the right. + +* **overrideAutoEnableDisable** - a boolean. The default is false. By default common-canvas has an auto-enablement feature that controls the enablement of common tools in the toolbar based on user actions (e.g enable the `Delete` icon when items are selected). If `overrideAutoEnableDisable` set to true it will switch off the auto-enablement feature. This is useful if the host application wants to disable all the nodes under certain circumstances. If set to true, the `enable` property in the action items for each tool is used to decide whether to display the icon as enabled or disabled. If set to false or omitted, common-canvas will handle the auto-enablement of common actions. (See the `action`section below for more details.) + +Two toolbar items are automatically added to the toolbar: + +- A palette action which is used for opening and closing the node palette. This is added to the left side of the left side of the toolbar if the [`enablePaletteLayout`](/2.1-Config-Objects#enablepalettelayout) field is set to either "Flyout" (the default) or "Modal" in the canvas configuration. +- A notification panel action which is used to open and close the notifications panel. This will be added to the right side of the toolbar if a [notification configuration](/2.1-Config-Objects#notification-config-object) object is specified to the `` react object. + +The toolbar will display the objects in the same order they are defined in the arrays. + +Here is an example of an action object which must contain a unique `action` field as a minimum. +```js + { + action: "run", + label: "Run", + enable: true, + iconEnabled: "/image/myOwnEnabledIcon.svg", + iconDisabled: "/image/myOwnDisabledIcon.svg", + incLabelWithIcon: "before", + kind: "primary", + tooltip: "Run the flow", + isSelected: false + } +``` + +* **action** - a unique identifier and the name of the action to be performed. This action name will be passed in the `data` parameter of the [editActionHandler](/2.2-Common-Canvas-callbacks#editactionhandler) callback method so you can detect when the user clicks an action in the toolbar. + + If you are using the recommended (and default) [internal object model](/2.1-Config-Objects#enableinternalobjectmodel), the following built in actions will be automatically handled by common-canvas: `undo`, `redo`, `cut`, `copy`, `paste`, `createAutoComment`, `deleteSelectedObjects`, `arrangeHorizontally`, `arrangeVertically`, `zoomIn`, `zoomOut`, and `zoomToFit`. So for example, if the `deleteSelectedObjects` action (shown as a trash can) is clicked, any selected objects will be deleted from the internal object model. + + Disablement of some of these built in actions is also handled by common-canvas so, for example, when no canvas objects are selected the `deleteSelectedObjects` action (trash can icon) will be automatically disabled. You can switch off this automatic enable/disable function by setting `overrideAutoEnableDisable` field in the toolbar config to `true`. When set to true, the `enable` field in the action objects will be used to set the enablement appearance of the toolbar item. + +* **label** - the Tooltip label to display (and optionally the text to display next to the icon if `incLabelWithIcon` is specified). + +* **enable** - Icon will have hover effect and is clickable when set to true. If false, icon will be disabled and unclickable. If not set, it will default to disabled (false). If `overrideAutoEnableDisable` is set to false, or omitted, this field is ignored for the standard action items (like cut, copy, paste) because common canvas handles their enable/disable appearance. If `overrideAutoEnableDisable` is set to true, this field will be used for standard action items. + +* **iconEnabled** - specifies the icon to display when `enable` is true. Common-canvas will provide icons for the following actions so you don't need to specify `iconEnabled` or `iconDisabled` for them: `stop`, `run`, `undo`, `redo`, `cut`, `copy`, `paste`, `createAutoComment`, `deleteSelectedObjects`, `arrangeHorizontally`, `arrangeVertically`, `commentsShow`, `commentsHide`, `zoomIn`, `zoomOut`, and `zoomToFit`. + + It can be either: + + - a string containing the path to a custom SVG file to display or + - a JSX expression, for example `()` where Edit32 is an icon imported from carbon icons. It is recommended to only pass very simple JSX expressions. + +* **iconDisabled** - specifies the icon to display when `enable` is false. If `iconDisabled` is *not* specified `iconEnabled` will be used instead. It can be omitted for any of the standard actions (see `iconEnabled` above). + + It can be either: + + - a string containing the path to a custom SVG file to display or + - a JSX expression, for example `()` where Edit32 is an icon imported from carbon icons. It is recommended to only pass very simple JSX expressions. + +* **incLabelWithIcon** - can be set to "no", "before" or "after". The default is "no". This field specifies whether the label should be displayed in the toolbar with the icon and if so, where it is displayed with respect to the icon. + +* **kind** - can be set to "default", "primary", "danger", "secondary", "tertiary" or "ghost". The default it "default". These give the action the same styling as the equivalent kind's of [buttons in the carbon library](https://carbondesignsystem.com/components/button/usage#button-types). + +* **tooltip** - A string or JSX object. The tooltip that will be displayed for the action. If this is not provided the label will be displayed as the tooltip instead. + +* **isSelected** - A boolean. When set to true the toolbar button displays a selection highlight (which is a blue bar along the bottom border of the toolbar item). This is useful if you have a button that switches on and off a mode in your interface, as opposed to a regular button, which does not have any state, that would typically execute a command of some sort. For example, if your product has a 'Turbo boost' setting, which can be on or off, you could add a 'Turbo Boost' button to the toolbar and use `isSelected` to indicate when the option is active. When the user clicks the button it would switch `isSelected` for the 'Turbo Boost' button to true or false as appropriate. (This would give behavior like a checkbox.) + + You can also use this property to indicate a current state between a number of mutually exclusive settings. In this case, you would add one button to the toolbar for each setting and then set the `isSelected` property to true for the setting that is currently active. Then, when the user clicks a different option in the set, your code would set `isSelected` to true for that button and set it to false for the previously selected button. (This would give behavior like a radio button set.) + + +You can add dividers to separate groups of actions from other actions. This is displayed as a thin gray line. The divider object has one attribute: +```js + { + divider: true + } +``` + +* **divider** - To show a divider in the toolbar, add an object with `divider` attribute set to true. + +### Deprecated toolbar config + + The old toolbar configuration is still supported for now (but is deprecated). This allows the config to be provided as an array that defines just the left side of the toolbar. The right side will always show the zoom actions (zoomIn, zoomOut, zoomToFit) and a notifications panel icon (if a notification configuration object is provided in the CommonCanvas react object). These right side actions will always show on the right-hand side of the toolbar and are handled internally by the canvas. The entries in the array follow the same definition as described above. Note: there is no need to provide a `palette` action in the array because a palette icon and following divider will automatically be added to the toolbar when a palette is specified for the canvas. + +An example of the toolbar config array should look like this: +```js + const toolbarConfig = [ + { action: "stop", label: "Stop Execution", enable: false }, + { action: "run", label: "Run Pipeline", enable: false }, + { action: "undo", label: "Undo", enable: true }, + { action: "redo", label: "Redo", enable: true }, + { action: "cut", label: "Cut", enable: false }, + { action: "copy", label: "Copy", enable: false }, + { action: "paste", label: "Paste", enable: false }, + { action: "createAutoComment", label: "Add Comment", enable: true }, + { action: "deleteSelectedObjects", label: "Delete", enable: true }, + { action: "arrangeHorizontally", label: "Arrange Horizontally", enable: true } + ]; +``` + +### Advanced: JSX actions +Regular toolbar buttons, explained above, are displayed as set of Carbon `Button`s. If you _don't_ want your content wrappered in a button, you can provide your own JSX to display as an action in the toolbar. Be aware however that, because of the way the toolbar is designed, there are restrictions on what the toolbar can do to display your JSX. For example, it cannot display anything with a height greater than the toolbar height. + +If you provide your own JSX object it is displayed in a simple `div` in the toolbar. Some attributes are applied to the `div` to allow the action to work correctly within the toolbar - these cannot be changed. You are responsible for styling your JSX object to get it to appear the way you want. + +Also be aware that, if the width of the toolbar reduces (maybe by the user sizing the page) your action may get moved into the overflow menu. It is also your responsibility to style the button so it appears as you want in the overflow menu as well as the toolbar. + +The JSX can be provided in the `jsx` field. Here is an example. The only other fields that are recognized with the `jsx` field are `action` and `tooltip`, all other fields will be ignored. + +```js + { + action: "custom-loading", + jsx: (
), + tooltip: "Loading the thing you wanted." + } +``` + +* **action** - a unique identifier and the name of the action to be performed. + +* **jsx** - A JSX object. This will be displayed as the action in the toolbar. + +* **tooltip** - A string or JSX object. This will be displayed as the tooltip for the action in the toolbar. If `tooltip` is omitted no tooltip will be added to your action. If `tooltip` is specified the `jsx` will be inside a tooltip `div` which is in the toolbar `div` mentioned above. + +Here's an example toolbar that includes some Carbon React components +```js + toolbarConfig = { + leftBar: [ + { action: "custom-loading", + jsx: ( +
+ +
+ ) + }, + { divider: true }, + { action: "custom-checkbox", + jsx: ( +
+ +
+ ) + }, + { divider: true }, + { action: "custom-button", + tooltip: "A custom button of type primary!", + jsx: ( +
+ +
+ ) + }, + { divider: true }, + { action: "custom-dropdown", + tooltip: "A drop down using the overflow menu!", + jsx: ( +
+ + + + + +
) }, + { divider: true } + ] + }; +``` + +# Notification Config object + +The notification config object configures whether or not the notification icon will be shown in the canvas toolbar. It will appear to the far right of the zoom actions in the toolbar. +Similar to a toolbar action object, the notificationConfig object looks like this: +```js + const notificationConfig = { + action: "notification", + label: "Notifications", + enable: true, + notificationHeader: "Notification Messages", + notificationSubtitle: "subtitle", + emptyMessage: "You don't have any notifications right now.", + clearAllMessage: "Clear all", + keepOpen: true, + clearAllCallback: () => { console.log("Clear All clicked"); } + }; +``` + +* **action** - "notification" enables the notifications icon to appear in the far right of the toolbar. + +* **label** - the Tooltip label to display for the notifications icon in the toolbar. + +* **enable** - Icon will have hover effect and is clickable when set to true. If false, icon will be disabled and unclickable. If not set, it will default to disabled (enable: false) + +* **notificationHeader** - String to display in the notification panel header. If not set, it will default to "Notifications". + +* **notificationSubtitle** - String to be displayed as a sub-title in the panel header. If not set panel header will be sized to only contain the `notificationHeader` string. + +* **emptyMessage** - String to be displayed when there are no notification messages to display. + +* **clearAllMessage** - String to be displayed on a button displayed at the bottom of the panel. The button can be clicked to clear all the messages from the panel. If omitted the button, and the footer area of the panel it appears in, will not be displayed. + +* **keepOpen** - A boolean which indicates when the panel will close. The default is false. If set to false, the panel will close when the user clicks on the page somewhere outside the panel. If set to true the panel will remain open when the user clicks somewhere on the page outside of the panel. With the option the user must click the `x` icon in the top right of the panel, or click the notification toolbar icon, to close the panel. + +* **clearAllCallback** - An optional callback function that will be called every time the "clear all" button is clicked. + +* **secondaryButtonLabel** - Label for the optional secondary button to be displayed in the notification panel. Both `secondaryButtonLabel` and `secondaryButtonCallback` must be specified for the button to appear. +* **secondaryButtonCallback** - A callback function that will be called when the secondary button is clicked. +* **secondaryButtonDisabled** - Specify whether the secondary button is disabled or not. + + +The notification icon state is determined by the type of messages in the notification message array. By default, a notifications icon in ready state will be shown if there are messages in the notification message array. If any message in the array is of type 'warning', a notifications icon in warning state will be shown. If any message in the array is of type 'error', a notifications icon in error state will be shown. A number will be shown within the notifications icon to indicate the number of messages. + +For information about the structure of notification messages, refer to the [message specification documentation](/2.4.4-Notification-Message-Specification). Notification messages can be added and removed from the notification panel by calling the canvas controller API. Refer to the canvas controller API documentation for information on how to [add/set messages in the notification message array](/2.4-Canvas-Controller-API#notification-messages-methods). + +# Context Menu Config object + +The context menu config object configures whether certain actions are available in the default context menu. + +```js + const contextMenuConfig = { + enableCreateSupernodeNonContiguous: false, + defaultMenuEntries: { + saveToPalette: true, + createSupernode: false, + displaySupernodeFullPage: true, + colorBackground: false + } + }; +``` + +* **enableCreateSupernodeNonContiguous** - Allows the creation of supernodes from non-contiguous nodes. When set to `true`, the "Create supernode" menu item will be added to the default context menu when the currently selected nodes are contiguous or non-contiguous. When set to `false`, the "Create supernode" menu item is only added to the default context menu when the selected nodes are contiguous. The default value is `false`. + +* **defaultMenuEntries** - Controls what entries are generated in the default context menu generated by common canvas. This has the following properties: + * 'saveToPalette' - This is a boolean. The default is false. If set to true, common canvas will add a 'Save to palette' option to the default node context menu. + * 'createSupernode' - This is a boolean. The default is true. If set to false, common canvas will not show the 'Create Supernode' option in the default context menu for nodes. + * 'displaySupernodeFullPage' - This is a boolean. The default is true. If set to false, common canvas will not show the 'Display full page' option in the default context menu for supernodes. When true, the option will be displayed. Clicking that option navigates the user to the full page view of the supernode's pipeline as if the user had clicked the expansion icon of the expanded in-place supernode view. + * 'colorBackground' - This is a boolean. The default is true. If set to false, common canvas will not show the 'Color background' option in the default context menu for comments. When true, the option will be displayed. + +[Note: If any host app wants more control over the default context menu here, please open an issue.] + +# Keyboard Config object + +The keyboard config object configures whether certain actions are available from the keyboard. +See this section for what [key combinations are supported](/2.0-Common-Canvas-Documentation#keyboard-support) +```js + const keyboardConfig = { + actions: { + delete: false, + undo: false, + redo: false, + selectAll: false, + cutToClipboard: false, + copyToClipboard: false, + pasteFromClipboard: false + }; +``` +All actions are `true` by default so it is only necessary to specify those actions you don't want as `false`. \ No newline at end of file diff --git a/docs/2.2-Common-Canvas-callbacks.md b/docs/2.2-Common-Canvas-callbacks.md new file mode 100644 index 0000000000..e957901eca --- /dev/null +++ b/docs/2.2-Common-Canvas-callbacks.md @@ -0,0 +1,704 @@ +# Event listener callbacks + +You can *optionally* provide callback listeners. These will be called when the user interacts with the canvas. + +These listeners are as follows: + +## contextMenuHandler +```js + contextMenuHandler(source, defaultMenu) +``` +This callback is used for both 'context menus' and, if the [`enableContextToolbar`](/2.1-Config-Objects#enablecontexttoolbar) canvas config option is set to `true`, for 'context toolbars'. + +If this callback is not provided common canvas will handle context menu/toolbars, and their actions, internally. You only need to implement this callback if you want to add or remove options to/from the context menu/toolbar. + +The job of this callback is to tell common canvas what items to display in the context menu/toolbar. + +### For Context Menu + +For context menus this will be dependent on what object or set of objects the context menu was requested for by the user. + +This callback will be called if the user performs a context menu gesture (such as mouse 'right click') on a: + +* node +* link +* comment +* port +* on the canvas background or +* if a number of objects are selected, the combination of objects. + +This callback must return an array that defines the menu to be displayed. If the callback is *not* provided, a default context menu (the defaultMenu passed into the handler) will be displayed by the common canvas. + +The source object passed in looks like this: +```js + { + type: "node", + targetObject: {}, + selectedObjectIds: ["node_1", "node_2"], + mousePos: {x: "10", y:"20"} + } +``` +**type** - Indicates type of object for which the context menu was selected. Can be "node", "port", "link", "canvas" or "comment" + +**targetObject** - The object for which the context menu was requested. Only provided when type is "node" or "comment" + +**selectedObjectIds** - An array containing the IDs of all currently selected nodes and/or comments + +**mousePos** - An object containing the coords of the mouse when the context menu was requested + +The callback would need to return an array, that describes the context menu to be displayed, that looks something like this: +```js + [ + {action: "deleteSelectedObjects", label: "Delete"}, + {divider: true}, + {action: "myAction", label: "My Action"} + {action: "myUnavailableAction", label: "A test disabled item", enable: false} + ] +``` +There is one element in the array for each entry in the context menu. An entry can be either a context menu item, which consists of a label and an action, or a divider, whose field would need to be set to true. + +Actions can be either internal (implemented inside the common canvas, like "deleteSelectedObjects" above) or external (like "myAction"). + +Existing internal actions are: + +* selectAll +* cut +* copy +* paste +* undo +* redo +* createSupernode +* expandSupernode +* collapseSupernode +* deleteSelectedObjects +* createComment +* deleteLink +* disconnectNode +* highlightBranch +* highlightDownstream +* highlightUpstream +* unhighlight + +External actions are custom actions you want common canvas to display for your application. To get common canvas to display your action you would need to return an array from the callback that includes a menu item for the action. + +When the user clicks the option in the context menu matching your action common canvas will call the [editActionHandler](#editactionhandler) callback so you'll need to implement some code in that callback to execute the intended action. If you want to simply add your action to the default context menu provided by common canvas you can take the defaultMenu parameter provided to the callback and add your menu item to it. Alternatively, you can provide a complete new context menu of your own. + +Here is a sample implementation of contextMenuHandler, which takes a source object (described above) and the defaultMenu as parameters, and adds a custom action to the default menu when the user 'right clicks' the canvas background. + +```js + contextMenuHandler(source, defaultMenu) { + let customMenu = defaultMenu; + if (source.type === "canvas") { + customMenu = customMenu.concat({ action: "myAction", label: "My Action" }); + } + return customMenu; + } +``` +In addition to adding the context menu item, you would also need to implement the editActionHandler callback to execute the action, like this: +```js + editActionHandler(data) { + if (data.editType === "myAction") { + // Execute my action code here. + } + } +``` +Tip: To avoid any future name clashes with internal actions you should make sure you action names are unique. For example, you could add a prefix to your action names eg. `$MyApp_action` where `$MayApp_` is the prefix for all your actions. + +### For Context Toolbar + +For context toolbars, this will be dependent on which object the mouse cursor is currently hovering over (which may be different to any of the currently selected objects). + + +## editActionHandler +```js + editActionHandler(data, command) +``` +This callback is optional. You don't *need* to implement anything for it and it doesn't return anything. It is called whenever the user does the following types of action on the canvas: + +* Clicks a tool in the toolbar. +* Clicks an option in the context menu. +* Presses a [key combination](/2.0-Common-Canvas-Documentation#keyboard-support) on the keyboard to cause the canvas to change. +* Performs some direct manipulation on the canvas such as: + * Creates a node (createNode) + * Moves one or a set of nodes/comments (moveObjects) + * Edits a comment (editComment) + * Links two nodes together (linkNodes) + * Links a comment to a node (linkComment) + * Resizes a supernode (resizeObjects) + * Resizes a comment (editComment) + * Expands a supernode in place (expandSuperNodeInPlace) + * Navigates into a sub-flow in a supernode (displaySubPipeline) + * Navigates out of a sub-flow in a supernode (displayPreviousPipeline) + + +This callback is called *after* the common-canvas internal object model has been updated. This callback is provided with two parameters: `data` and `command`. + +1. **data parameter** - that looks like this. The data provided can vary depending on the action the user performed. +```js + { + editType: "createComment", + editSource: "contextmenu", + selectedObjects: [], + selectedObjectIds: [], + offsetX: 100, + offsetY: 42 + } +``` + + + ***editType*** - This is the action that originates from either the toolbar, context menu, keyboard action or direct manipulation on the canvas. If you specified your own action in the context menu or in the toolbar this field will be your action's name. + + + ***editSource*** - This is the source of the action. It can be set to "toolbar", "contextmenu", "keyboard" or "canvas" (for an action caused by direct manipulation on the canvas). + + + ***selectedObjects*** - An array of the currently selected objects. + + + ***selectedObjectIds*** - An array of the IDs of currently selected objects. Included for backward compatibility. + + + ***Other fields*** - Numerous other fields which vary based on the action and the source of the action. + +2. **command parameter** - This is a Javascript class which is the command object that was added to the command stack and executed to run the action 'requested' by the user. If the user performed an `undo` action this will be the command that has been undone. If the user performed a `redo` action this will be the command that was redone. The command object may contain fields which are connected with the execution of the command. + +## beforeEditActionHandler +```js + beforeEditActionHandler(data, command) +``` +This callback is optional. You don't *need* to implement anything for it but if you do implement it you **must** return either a data object or null. This callback is called in all the same instances where `editActionHandler` is called. The difference is that this callback is called *before* the internal object model is updated. This gives your application the opportunity to examine the action that is about to be performed and either: let it continue; modify it and let it continue; or cancel it. + + This callback is provided with two parameters: `data` and `command`. + +1. **data parameter** - this is the same as the data object described for `editActionHandler` (see above) +2. **command parameter** - typically this will be null but for `undo` operations (that is where data.editType === "undo") this will be the command that is about to be undone. For `redo` operations (that is where data.editType === "redo") this will be the command that is about to be redone. + +This callback *must* return either the data object that was passed in or null. `beforeEditActionHandler` will behave as follows based on what is returned: + +* If the data object is returned unmodified: the action will be performed as normal. +* If the data object is returned modified: the action will be performed based on the modified data object. This means your application can alter the behavior of the action that will be performed. For example, you could intercept a `createNode` command and change the label for the new node in the nodeTemplate to something different. Then when the node is created the new label will be used. It is recommended you be **very** **very** careful when updating this object since there is no error checking in common-canvas to ensure you modified the object correctly. +* If `null` is returned: the action will be cancelled and not performed on the internal object model nor will `editActionHandler` be called. + +If you need to do any asynchronous activity in the beforeEditActionHandler callback you can: + +* Return null from the callback - which will cancel the current action +* Do your asynchronous activity. While this is happening, the user ought to be prevented from modifying the canvas so you should display some sort of progress indicator or modal dialog to inform the user that some activity is occurring. +* Then call `CanvasController.editActionHandler(data)` passing in the `data` object as a parameter with the modified properties. This will then execute the action as before. Note: This means the `beforeEditActionHandler` will be called a second time so be sure you put in a check to make sure you don't get into a loop. + +## clickActionHandler +```js + clickActionHandler(source) +``` +This callback is provided for your information. You don't need to implement anything for it and it doesn't need to return anything to common canvas. It is called whenever the user clicks or double clicks on something on the canvas. You could use this callback to implement opening a properties dialog when the user double clicks a node. + +Note: When handling selections, it is recommended the selectionChangeHandler be used in preference to this handler when possible. selectionChangeHandler will notify you of all selection changes regardless of how they occur, such as when the user presses Ctrl+A on the keyboard to select all objects. + +At the moment only click/double-click on nodes and the canvas background are returned. It is provided with one parameter that looks like this: +```js + { + clickType: "DOUBLE_CLICK" + id: "node_1", + objectType: "node", + selectedObjectIds: ["node_1", "node_2"] + } +``` +The fields can be: + +* clickType - This can be either "SINGLE_CLICK", "SINGLE_CLICK_CONTEXTMENU" or "DOUBLE_CLICK" +* objectType - Can be either "node", "comment", "canvas" or "region". "region" is specified when the user pulls out a selection rectangle around a set of objects that might include nodes and comments. +* id - The ID of the node or comment clicked. Only provided when objectType is "node" or "comment" +* selectedObjectIds - An array of the selected objects (after the click action was performed). + +Note: "SINGLE_CLICK_CONTEXTMENU" indicates that the user performed a contextmenu gesture when doing the click such as pressing the right-side mouse button or a two finger tap on a trackpad. + +## decorationActionHandler +```js + decorationActionHandler(object, id, pipelineId) +``` +Decorations are small images that can be displayed on or near to your nodes and links. They can be for display only or actionable (so the user can click on them). See the canvas JSON schema for information on how to define decorations for your nodes. + +This callback is called when the user clicks on an actionable decoration. You don't need to implement anything for this callback unless you added actionable decorations to your nodes. It doesn't return anything. It is called whenever the user clicks on a decoration that you added to a node in the canvas JSON. + +It is provided with two parameters: + +* object -- the node or link with which the decoration is associated. +* id -- the ID of the decoration that you provided in the canvas JSON +* pipelineId -- the ID of the pipeline for the node. + +## tipHandler +```js + tipHandler(tipType, data) +``` +Note: The display of tooltips (or not) can be controlled using the [`tipConfig`](/2.1-Config-Objects#tipconfig) field of the canvas config object. + +This optional callback can be implemented to override the tooltip content that is displayed by default for each canvas object. It is called before tips are shown for: palette categories, palette node templates, node, ports, links, decorations and the state tag. Common-canvas provides default implementations for all of the tips except for links and decorations, as follows: + +|Object | Default tip behavior | +|:--------|:----------------------| +| Palette category | Contains the category name and the category description. | +| Palette node template | Contains the category name, the node type and node description. | +| Node | Contains the name, description and status icon and optionally, if the name was modified from the original name, the original node type. | +| Port | The port label is shown | +| Link | No tip is shown by default | +| Decoration | No tip is shown by default | +| State tag | An appropriate explanation for the state displayed by the tag| + +To override the content, you can return either a string or JSX object. If your code returns `null` for a particular type of tip, common-canvas will display the default tip for that object. For an example of an implementation for a `tipHandler`, see App.js in the test harness code (https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/client/App.js). + +Common-canvas calls the `tipHandler` callback with two parameters: + +- tipType - the type of the tip +- data - an object that describes the canvas element for which the tip was requested + +Here are some specific examples: + +#### Palette categories: + + - tipType: "tipTypePaletteCategory" + - data: An object with category information, like this: + +```js +{ + category: { + id: "1234", + label: "Import", + description: "Category for import nodes", + image: "/images/import.svg" + } +} +``` + +#### Palette nodes templates: + + - tipType: "tipTypePaletteItem" + - data: An object with node template information: +```js +{ + nodeTemplate: { + label: "C50", + description: "C50 Model", + operator_id_ref: "com.ibm.commonicons.models.c50", + type: "model_node", + image: "/images/common_node_icons/models/model_c50.svg", + input_ports: [{...}], + output_ports: [] + } +} +``` +#### Nodes: + - tipType: "tipTypeNode" + - data: An object with pipelineId and node information: +```js +{ + pipelineId: "153651d6-9b88-423c-b01b-861f12d01489", + node: { + id: "idGWRVT47XDV", + type: "execution_node", + operator_id_ref: "type", + output_ports: [...], + input_ports: [...], + label: "Define Types", + description: "", + image: "", + x_pos: 445, + y_pos: 219 + } +} +``` + +#### Ports: + + - tipType: "tipTypePort" + - data: An object with pipelineId, node and port information: +```js +{ + pipelineId: "153651d6-9b88-423c-b01b-861f12d01489", + node: { + id: "idGWRVT47XDV", + type: "execution_node", + operator_id_ref: "type", + output_ports: [{...}], + input_ports: [{...}], + label: "Define Types", + description: "", + image: "", + x_pos: 445, + y_pos: 219 + }, + port: { + id: "outPort", + label: "Output Port" + } +} +``` + +#### Links + - tipType: "tipTypeLink" + - data: An object with pipelineId and link information. +```js +{ + pipelineId: "153651d6-9b88-423c-b01b-861f12d01489", + link: { + id: "canvas_link_3", + x1: 515, + y1: 248, + x2: 611, + y2: 180, + class_name: "canvas-data-link", + type: "nodeLink", + src: { + id: "idGWRVT47XDV", + type: "execution_node", + operator_id_ref: "type", + output_ports: [{...}], + input_ports: [{...}], + label: "Define Types", + description: "", + image: "", + x_pos: 445, + y_pos: 219 + }, + srcPortId: "outPort", + trg: { + id: "id8I6RH2V91XW", + type: "binding", + operator_id_ref: "c50", + output_ports: [], + input_ports: [{...}], + label: "C5.0", + description: "", + image: "", + x_pos: 611, + y_pos: 151 + }, + trgPortId: "inPort" + } +} +``` + +#### Decorations + - tipType: "tipTypeDec" + - data: An object with pipelineId and decoration information. +```js +{ + pipelineId: "153651d6-9b88-423c-b01b-861f12d01489", + decoration: { + "id": "2016", + "position": "topRight", + "label": "LCFC", + "tooltip": "Foxes never quit" + } +} +``` + +#### State tag + - tipType: "tipTypeStateTag" + - data: An object with pipelineId and decoration information. +```js +{ + stateTagText: "This flow is locked and cannot be edited.", + stateTagType: "Locked" +} +``` + + + +## idGeneratorHandler +```js + idGeneratorHandler(action, data) +``` +This callback is called when new objects are created in the canvas and allows the user to provide their own method to generate a unique id for the object. If no idGeneratorHandler is set or the method returns null, a UUID is generated by common-canvas. The method is called with a string for the action that was performed (create node/comment/link, clone node/comment/link) and a JSON object with additional data. + +* create node: + * action: create_node + * data: + + +```js +nodeType: +{ + "label":"C50", + "description":"C50 Model", + "operator_id_ref":"com.ibm.commonicons.models.c50", + "type":"model_node", + "image":"/images/common_node_icons/models/model_c50.svg", + "input_ports":[ + { + "id":"inPort", + "label":"Input Port", + "cardinality":{ + "min":0, + "max":1 + } + } + ], + "output_ports":[ + + ] +} +``` + +* create comment: + + * action: create_comment + * data: n/a + +* create node link: + * action: create_node_link + * data: + +```js +sourceNode: { + "id":"6a547456-f1ea-48a6-9721-45d6ae70dd6b", + "label":"Aggregate", + "type":"execution_node", + "operator_id_ref":"com.ibm.commonicons.operations.aggregate", + "image":"/images/common_node_icons/operations/operation_aggregate.svg", + "class_name":"d3-node-body", + "input_ports":[...], + "output_ports":[...], + "x_pos":55, + "y_pos":97.5, + "inputPortsHeight":20, + "outputPortsHeight":20, + "height":75, + "width":70 +}, +targetNode: { + "id":"71c96629-be46-418b-be63-0a02ef2fe2e0", + "label":"Append", + "type":"execution_node", + "operator_id_ref":"com.ibm.commonicons.operations.append", + "image":"/images/common_node_icons/operations/operation_append.svg", + "class_name":"d3-node-body", + "input_ports":[...], + "output_ports":[...], + "x_pos":264, + "y_pos":83.5, + "inputPortsHeight":20, + "outputPortsHeight":20, + "height":75, + "width":70 +} +``` + +- create comment link: + * action: create_comment_link + * data: + +```js +comment: { + "id":"8c81aac7-ebe5-4f96-9d63-eabc22b09635", + "class_name":"d3-comment-rect", + "content":"", + "height":42, + "width":175, + "x_pos":50, + "y_pos":50 +}, +targetNode: { + "id":"71c96629-be46-418b-be63-0a02ef2fe2e0", + "label":"Append", + "type":"execution_node", + "operator_id_ref":"com.ibm.commonicons.operations.append", + "image":"/images/common_node_icons/operations/operation_append.svg", + "class_name":"d3-node-body", + "input_ports":[...], + "output_ports":[...], + "x_pos":264, + "y_pos":83.5, + "inputPortsHeight":20, + "outputPortsHeight":20, + "height":75, + "width":70 +} +``` + +- clone node: triggered when copying&pasting a node + * action: clone_node + * data: + +```js +node: { + "id":"56d30c83-3a08-4147-933e-b01d3c348ac1", + "label":"Append", + "type":"execution_node", + "operator_id_ref":"com.ibm.commonicons.operations.append", + "image":"/images/common_node_icons/operations/operation_append.svg", + "class_name":"d3-node-body", + "input_ports":[...], + "output_ports":[...], + "x_pos":265, + "y_pos":177.5, + "inputPortsHeight":20, + "outputPortsHeight":20, + "height":75, + "width":70 +} +``` + +- clone comment: triggered when copying&pasting a comment + * action: clone_comment + * data: + +```js +comment: { + "id":"8c81aac7-ebe5-4f96-9d63-eabc22b09635", + "class_name":"d3-comment-rect", + "content":"", + "height":42, + "width":175, + "x_pos":50, + "y_pos":50 +} +``` + +- clone node link: triggered when copying&pasting two connected nodes + * action: clone_node_link + * data: + +```js +link: { + "id":"12c4308e-f572-402a-8dd3-604d438539d4", + "class_name":"d3-data-link", + "srcNodeId":"2b1af6c2-f98b-4728-97b3-416d40224bce", + "trgNodeId":"b43fffe6-dc01-4d30-8b6d-abd977850a2e", + "type":"nodeLink" +}, +sourceNodeId: "56d30c83-3a08-4147-933e-b01d3c348ac1", +targetNodeId: "815271f0-f4da-4793-ab8f-c4c32d3dd7e0" +``` +Note that the link to be cloned has references to the original source and target nodes, while the sourceNodeId and targetNodeId are the new node ids for the copied nodes. The new nodes are not part of the model yet. + +- clone comment link: triggered when copying&pasting a comment and a node that are connected + * action: clone_comment_link + * data: + +```js +link: { + "id":"12c4308e-f572-402a-8dd3-604d438539d4", + "class_name":"d3-comment-link", + "srcNodeId":"2b1af6c2-f98b-4728-97b3-416d40224bce", + "trgNodeId":"b43fffe6-dc01-4d30-8b6d-abd977850a2e", + "type":"commentLink" +}, +sourceNodeId: "56d30c83-3a08-4147-933e-b01d3c348ac1", +targetNodeId: "815271f0-f4da-4793-ab8f-c4c32d3dd7e0" +``` +Note that the link to be cloned has references to the original comment and target node, while the sourceNodeId and targetNodeId are the new ids for the copied comment and node. The new node and comment are not part of the model yet. + +## selectionChangeHandler +```js + selectionChangeHandler(data) +``` +The selectionChangeHandler callback is triggered whenever the selection in the canvas changes. The callback contains a JSON object with the following format: +``` +{ + "selection": [ + "id6PXRG57DGIV" + ], + "selectedNodes": [ + { + "id": "id6PXRG57DGIV", + "type": "binding", + "operator_id_ref": "variablefile", + "output_ports": [...], + "input_ports": [], + "label": "DRUG1n", + "description": "", + "image": "", + "x_pos": 96, + "y_pos": 219, + "class_name": "canvas-node", + "decorations": [], + "parameters": [], + "messages": [], + "inputPortsHeight": 0, + "outputPortsHeight": 20, + "height": 75, + "width": 70 + } + ], + "selectedComments": [], + "addedNodes": [ + { + "id": "id6PXRG57DGIV", + "type": "binding", + "operator_id_ref": "variablefile", + "output_ports": [...], + "input_ports": [], + "label": "DRUG1n", + "description": "", + "image": "", + "x_pos": 96, + "y_pos": 219, + "class_name": "canvas-node", + "decorations": [], + "parameters": [], + "messages": [], + "inputPortsHeight": 0, + "outputPortsHeight": 20, + "height": 75, + "width": 70 + } + ], + "addedComments": [], + "deselectedNodes": [ + { + "id": "id2PZSCTRPRIJ", + "type": "execution_node", + "operator_id_ref": "derive", + "output_ports": [...], + "input_ports": [...], + "label": "Na_to_K", + "description": "", + "image": "", + "x_pos": 219.01116943359375, + "y_pos": 162.3754425048828, + "class_name": "canvas-node", + "decorations": [], + "parameters": [], + "messages": [...], + "inputPortsHeight": 20, + "outputPortsHeight": 20, + "height": 75, + "width": 70 + } + ], + "deselectedComments": [ + { + "id": "id42ESQA3VPXB", + "content": " comment 1", + "height": 34, + "width": 128, + "x_pos": 132, + "y_pos": 103, + "class_name": "canvas-comment-1" + } + ], + previousPipelineId: "123-456", + selectedPipelineId: "789-012" +} +``` + +- selection: Array with ids of selected nodes and comments +- selectedNodes: Array of selected node objects +- selectedComments: Array of selected comment objects +- addedNodes: Array with node objects that were added to the selection +- addedComments: Array with comment objects that were added to the selection +- deselectedNodes: Array with node objects that were removed from the selection +- deselectedComments: Array with comment objects that were removed from the selection +- previousPipelineId: The ID of the Pipeline for the selected objects prior to the selection action +- selectedPipelineId: The ID of the Pipeline for the newly selected objects + + +## layoutHandler +```js + layoutHandler(data) +``` +This is an optional handler you don't need to implement anything for it unless you want to. The layoutHandler callback, when provided, is called for each node on the canvas. The callback should return a Javascript object whose properties will override the default properties for node layout. The callback is provided with a parameter `data` which is the node object. Your code can look at the node properties and decide which properties it needs to override. This can be used to change the node shape, styling and position and size of node elements like the image, main label etc. + +For more details see: [Customizing Node Layout Properties](/2.7-Customizing-Node-Layout-Properties) + +## actionLabelHandler +```js + actionLabelHandler(action) +``` +This is an optional handler you don't need to implement anything for it unless you want to. This callback allows your code to override the default tooltip text for the `Undo` and `Redo` buttons. + +The `actionLabelHandler` callback, when provided, is called for each action that is performed in common-canvas. The `action` object parameter, passed in to the callback, contains details of the action being performed. This callback should return either a string or null. If a string is returned it will be shown in the tooltip for the `Undo` button in the toolbar preceded by "Undo:" and the string will also appear in the tooltip for the `Redo` button (when appropriate) preceded by "Redo:". If null is returned, common-canvas will display the default text for the `Undo` and `Redo` buttons. \ No newline at end of file diff --git a/docs/2.3-Enabling-node-creation-from-external-object.md b/docs/2.3-Enabling-node-creation-from-external-object.md new file mode 100644 index 0000000000..146b622591 --- /dev/null +++ b/docs/2.3-Enabling-node-creation-from-external-object.md @@ -0,0 +1,77 @@ +## Dragging object from within the browser +Common canvas supports the ability for an object from the your browser page to be dragged onto the canvas to initiate the creation of a node on the canvas. To do this you need to set the object you want to drag into the canvas to be draggable: + +```html +
+ .... + .... +
+``` +and then specify the on drag behavior like this +```js + onDragStart(ev) { + const evData = { + operation: "addToCanvas", + data: { + editType: "createExternalNode", + field1: "field_val_1", + field2: "field_val_2" + .... + .... + } + }; + ev.dataTransfer.setData("text", JSON.stringify(evData)); + } +``` +where + +* operation - is always set to "addToCanvas" +* data - is the object that will be passed to the editActionHandler callback +* editType - this is the type of editing operation. You can set it to anything except any of the reserved settings which are: 'createNode', 'createNodeOnLink', 'createAutoNode' and 'createFromExternalObject'. +* fields - an optional number of fields can be provided that describe the object you are dragging onto the canvas. For example, if it is a data object the fields might describe the data source details. + +After the object has been dropped on the canvas your editActionHandler() callback method will be called with a parameter data object that contains the fields you specified in `data` in the drag data along with three additional fields, called pipelineId, offsetX and offsetY, containing the x,y co-ordinates of where the drop occurred. In your editActionHandler() method you can use the CanvasController API to add a node to the pipeline flow and get common canvas to display it. + +## Dragging object from the desktop or another application +If an object from the desktop or another application is dropped on the canvas your editActionHandler(data) method will be called with the `data` parameter set to an object like this: +```js + { + dataTransfer: , + editType: "createFromExternalObject", + editSource: "canvas", + offsetX: 200, + offsetY: 100, + pipelineId: "1234-5678" + } +``` +Your code can examine the `dataTransfer` object to see what object was dragged onto the canvas and then take appropriate action. + +If you want a new node to appear on the canvas as a result of the object being dropped your code will need to create that node at the point where the drop occurred, using the Canvas Controller API. Here is some sample code that will + +* create a new node template based on the "variablefile" node in the palette data +* set the label of the node to be created to the name of the file being dropped +* create a new node on the canvas at the offsetX, offsetY position +* the command will be added to the command-stack so the user can click undo to undo the addition of the node + +`data` is the parameter passed into your `editActionHandler` method. +```js + if (data.editType === "createFromExternalObject") { + const nodeTemplate = canvasController.getPaletteNode("variablefile"); + if (nodeTemplate) { + const convertedTemplate = canvasController.convertNodeTemplate(nodeTemplate); + convertedTemplate.label = data.dataTransfer.files[0].name; + const action = { + editType: "createNode", + nodeTemplate: convertedTemplate, + pipelineId: data.pipelineId, + offsetX: data.offsetX, + offsetY: data.offsetY + }; + canvasController.editActionHandler(action); + } +``` + +Tip: You can optionally instruct common canvas to display a graphic over the canvas as the external object is being dragged over it. To do this you need to specify the [`enableDropZoneOnExternalDrag`](/2.1-Config-Objects#enabledropzoneonexternaldrag) configuration parameter. \ No newline at end of file diff --git a/docs/2.4-Canvas-Controller-API.md b/docs/2.4-Canvas-Controller-API.md new file mode 100644 index 0000000000..ce8cd4626a --- /dev/null +++ b/docs/2.4-Canvas-Controller-API.md @@ -0,0 +1,945 @@ +# Canvas Controller API + +Your application code can programmatically perform many of the actions that the user can do in the common canvas using the Canvas Controller API. +Note: See this section for differences between [the structure of objects in the API and the schema.](/2.4.3-Object-structure-used-by-API#api-differences-with-schema) + +Also, this section discusses different [techniques for calling the canvas controller API](/2.4.0-Calling-the-Canvas-Controller-API). + +In most cases within the API, the pipelineId parameter is optional. If pipelineId is omitted, the method will default to the pipeline that is currently displayed in the main canvas viewport. + +Warning 1: Do not alter the IDs of objects that currently exist on the canvas. Changing object IDs can cause internal problems, in particular with the command stack. + +Warning 2: When using external pipeline flows, Pipeline IDs must be globally unique identifiers. + +The API provides the following: +## Pipeline Flow methods +```js +// Loads the pipelineFlow document provided into common-canvas and displays it. +// The document must conform to the pipelineFlow schema as documented in the +// elyra-ai pipeline-schemas repo. Documents conforming to older versions may be +// provided but they will be upgraded to the most recent version. +setPipelineFlow(flow) + +// Clears the pipleine flow and displays an empty canvas. +clearPipelineFlow() + +// Returns the current pipelineFlow document in the latest version of the +// pipelineFlow schema as documented in the elyra-ai pipeline-schemas repo. +getPipelineFlow() + +// Returns the current pipelineFlow document ID. +getPipelineFlowId() + +// Returns the ID of the primary pipeline from the pipelineFlow. +getPrimaryPipelineId() + +// Returns the external pipeline flow for the url passed in. The external +// flow must have been loaded through some common canvas action for this +// method to be able to return anything. +getExternalPipelineFlow(url) + +// Returns the internal format of all canvas data stored in memory by +// common-canvas. Nodes, comments and links are returned in the internal +// format. +getCanvasInfo() + +// Returns the IDs of the ancestor pipleline of the pipeline ID passed in. +getAncestorPipelineIds(pipelineId) + +// Removes all styles from nodes, comments and links. See the setObjectsStyle +// and setLinkStyle methods for details on setting styles. +// temporary - is a boolean that indicates whether temporary or permanent +// styles should be removed. +removeAllStyles(temporary) + +// Specifies the new styles for objects that are not highlighted during +// branch highlighting. +// newStyle - is a style specification object. See wiki for details. +setSubdueStyle(newStyle) + +``` + +## Pipeline methods +```js +// Returns the pipeline object for the pipeline Id passed in. +getPipeline(pipelineId) + +// Returns the ID of the pipeline object which is currently on display +// in the canvas. Typically, this is the primary pipeline but will be +// different if the user has navigated into one or more supernodes; in +// which case it will be the ID of the pipeline at the level in the +// supernode hierarchy that is currently on display. +getCurrentPipelineId() + +// Returns truty if the pipeline is external (that is it is part of an +// external pipeline flow). Otherwise, return falsy to indicate the pipeline +// is local. +isPipelineExternal(pipelineId) + +// Returns the flow validation messages for the pipeline ID passed in. +getFlowMessages(pipelineId) + +// Returns a boolean to indicate whether there are any messages of +// includeMsgsType in the pipeline identified by the pipeline ID passed in. +// includeMsgsType - can be either "error" or "warning" +isFlowValid(includeMsgTypes, pipelineId) + +// Rearranges the nodes in the canvas in the direction specified for the +// pipeline ID passed in. +// layoutDirection - can be "horizontal" or "vertical" +autoLayout(layoutDirection, pipelineId) +``` + +## Palette methods +```js +// Loads the palette data as described in the palette schema in +// elyra-ai pipeline-schemas repo. Any version can be loaded and it will be +// upgraded to the latest version. +setPipelineFlowPalette(palette) + +// Clears the palette data from common-canvas. +clearPaletteData() + +// Sets the loading text of the category. If set to a non-empty string the +// category will show an InlineLoading control in the palette category div +// with this text as the label. If set to falsey the palette category +// will display as normal. +setCategoryLoadingText(categoryId, loadingText) + +// Sets the empty text of the category. If set to a non-empty string and the +// category does not have any nodes, the palette will show a warning icon with +// this text as a message under the category title when the category is opened. +// This message will not be displayed if the field is set to falsey or if +// nodetypes are added to the category. +setCategoryEmptyText(categoryId, emptyText) + +// Adds a new node into the palette: +// nodeTypeObj - must conform to the style of node used by the palette as +// described in the palette schema. See objects in nodeTypes array in the +// palette schema: +// https://github.com/elyra-ai/pipeline-schemas/blob/master/common-canvas/palette/palette-v3-schema.json +// category - is the name of the palette category where the node will be +// added. If the category doesn't exist it will be created. +// categoryLabel - Is an optional param. If a new category is created it will +// be displayed with this label. +// categoryDescription - Is an optional param. If a new category is created +// it will be displayed with this description. +// categoryImage - Is an optional param. The image displayed for the category provided as a +// reference to an image or the image itself. +addNodeTypeToPalette(nodeTypeObj, categoryId, categoryLabel, categoryDescription, categoryImage) + +// Adds an array of new node into the palette: +// nodeTypeObjs - an array of nodetypes that must conform to the style of +// nodes used by the palette as described in the palette schema. See objects +// in nodeTypes array in the palette schema: +// https://github.com/elyra-ai/pipeline-schemas/blob/master/common-canvas/palette/palette-v3-schema.json +// category - is the name of the palette category where the node will be +// added. If the category doesn't exist it will be created. +// categoryLabel - is an optional param. If a new category is created it will +// be displayed with this label. +// categoryImage - the image displayed for the category provided as a +// reference to an image or the image itself. +// categoryDescription - Is an optional param. If a new category is created +// it will be displayed with this description. +// categoryImage - Is an optional param. The image displayed for the category provided as a +// reference to an image or the image itself. +addNodeTypesToPalette(nodeTypeObjs, categoryId, categoryLabel, categoryDescription, categoryImage) + +// Removes nodetypes from a palette category +// selObjectIds - an array of object IDs to identify the nodetypes to be +// removed +// categoryId - the ID of teh category from which the nodes will be removed +removeNodesFromPalette(selObjectIds, categoryId) + +// Returns the palette data document which will conform to the latest version +// of the palette schema. +getPaletteData() + +// Returns the palette node identified by the operator ID passed in. +getPaletteNode(operatorId) + +// Returns the palette node identified by the node ID passed in. +getPaletteNodeById(nodeId) + +// Returns the category of the palette node identified by the operator passed in +getCategoryForNode(nodeOpIdRef) + +// Converts a node template from the format use in the palette (that conforms +// to the schema) to the internal node format. +convertNodeTemplate(nodeTemplate) + +// Opens the palette category identified by the category ID passed in. +openPaletteCategory(categoryId) + +// Closes the palette category idetified by the category ID passed in. +closePaletteCategory(categoryId) + +// Opens all the palette categories. +openAllPaletteCategories() + +// Closes all the palette categories. +closeAllPaletteCategories() + +// Returns true or false to indicate whether a palette category is open or not. +isPaletteCategoryOpen(categoryId) +``` + +## Selections methods +```js +// Sets the currently selected objects replacing any current selections. +// newSelection - An array of object IDs for nodes and/or comments +// pipelineId - Optional. The ID of the pipeline where the objects exist. +// Selected objects can only be in one pipeline. If this parameter is omitted +// it is assumed the selections will be for objects in the 'top-level' pipeline +// being displayed. +setSelections(newSelection, pipelineId) + +// Clears all the current selections from the canvas. +clearSelections() + +// Selects all the objects on the canvas. +selectAll() + +// Returns an array of the IDs of the currently selected objects. +getSelectedObjectIds() + +// Returns the currently selected Nodes. +getSelectedNodes() + +// Returns the currently selected Comments. +getSelectedComments() + +// Returns the ID of the pipeline in which the currently selected objects +// exist. Only one pipeline may contain selected objects. +getSelectedPipelineId() + +// Deletes all currently selected objects. +deleteSelectedObjects() + +// Returns true if the currently selected objects are all linked together. +// This is used when deciding to creating a supernode. +areSelectedNodesContiguous() +``` + +## Notification messages methods + +The notification panel is displayed by the user by clicking the notifications icon in the toolbar. Your application can display whatever messages it wants in the notification panel. See the [Notification Messages Specification](/2.4.4-Notification-Message-Specification) documentation for the structure of message objects. The contents of the notification panel can be managed using the methods below: +```js +// Overwrites the array of notification messages shown in the notification +// panel. +// newMessage - An array of messages (see getNotificationMessages) +setNotificationMessages(newMessages) + +// Deletes all notification messages shown in the notification panel. +clearNotificationMessages() + +// Removes the notification messages from the given array of ids +deleteNotificationMessages(ids) + +// Returns the array of current notification messages. If the messageType is +// provided only messages of that type will be returned. If messageType is +// not provided, all messages will be returned. The format of a notification +// message is an object with these fields: +// { +// "id": string (Required), +// "type" : enum, oneOf ["info", "success", "warning", "error"] (Required), +// "callback": function, the callback function when a message is clicked (Required), +// "title": string (Optional), +// "content": string, html, JSX Object (Optional), +// "timestamp": string (Optional), +// "closeMessage": string (Optional) +// } +getNotificationMessages(messageType) + +// Returns the maximum notification message type present in the current set +// of notification messages. For this: ("error" > "warning" > "success" > "info") +getNotificationMessagesMaxType() +``` + +## Node AND comment methods +In common-canvas nodes and comments are collectively known as objects. The following methods may be used to manage either collections of comments or nodes or a mixture of both. +Note: + +* See this sections if you are working with [styles.](/2.4.1-Style-Specification) +* See this section if you are working with [decorations.](/2.4.2-Decoration-Specification) +* See this section for differences between [the structure of objects in the API and the schema.](/2.4.3-Object-structure-used-by-API#api-differences-with-schema) +```js +// Moves the objects identified in the data object which must be in the +// pipeline identified by the pipeline ID. +// data - A javascript object like this: +// { +// nodes: [] // An array of node and comment IDs +// offsetX: number // Offset in pixels the objects will move in the X dir +// offsetY: number // Offset in pixels the objects will move in the Y dir +// } +moveObjects(data, pipelineId) + +// Deletes the objects specified in objectIds array. +// objectIds - An array of node and comment IDs +deleteObjects(objectIds, pipelineId) + +// Removes the links to and from the objects specified in the objectIds array. +// objectIds - An array of node and comment IDs +disconnectObjects(objectIds, pipelineId) + +// Deletes the object specified by the id in the pipleine specified by +// pipeline ID. +// @Deprecated Use deleteNode or deleteComment as appropriate instead. +deleteObject(id, pipelineId) + +// Sets the style of the objects specified by pipelineObjectIds to be +// the newStyle which will be either temporary or permanent. +// pipelineObjectIds: This identified the objects to be styles. It is a +// javascript object like this: +// { +// : [ +// , +// +// ], +// : [ +// , +// +// ] +// } +// newStyles - This is a style specification. See the wiki for details. +// temporary - A boolean to indicate if the style is serialized when +// getPipelineFlow() method is called or not. +setObjectsStyle(pipelineObjectIds, newStyle, temporary) + +// Sets the styles of multiple objects at once. +// pipelineObjStyles - Specified the objects and the styles each should be +// set to. It is a javascript array like this: +// [ +// { pipelineId: , objId: , style: }, +// { pipelineId: , objId: , style: }, +// { pipelineId: , objId: , style: } +// ] +// temporary - A boolean to indicate if the styles are serialized when +// getPipelineFlow() method is called or not. +setObjectsMultiStyle(pipelineObjStyles, temporary) +``` +## Node methods +```js +// Retuns an array of nodes for the pipeline specified by the pipelineId. +getNodes(pipelineId) + +// Returns a new node created from the data parameter in the pipeline +// identified by the pipelineId. +// The data parameter must contain: +// nodeTemplate - a node template from the palette. The nodeTemplate +// can be retrieved from the palette using with Canvas +// Controller methods: getPaletteNode or getPaletteNodeById. +// offsetX - the x coordinate of the new node +// offsetY - the y coordinate of the new node +createNode(data, pipelineId) + +// Adds a new node into the pipeline specified by the pipelineId. +addNode(node, pipelineId) + +// Creates a node using the data parameter provided in the pipeline specified +// by pipelineId and adds the command to the command stack (so the user can +// undo/redo the command). This will also cause the beforeEditActionHandler +// and editActionHandler callbacks to be called. +// The data parameter must contain: +// nodeTemplate - a node template from the palette. The nodeTemplate +// can be retrieved from the palette using with Canvas +// Controller methods: getPaletteNode or getPaletteNodeById. +// offsetX - the x coordinate of the new node +// offsetY - the y coordinate of the new node +// +// If pipelineId is omitted the node will be created in the current +// "top-level" pipeline. +createNodeCommand(data, pipelineId) + +// Deletes the node specified. +// nodeId - The ID of the node +// pipelineId - The ID of the pipeline +deleteNode(nodeId, pipelineId) + +// Sets the node properties +// nodeId - The ID of the node +// properties - An object containing properties to be overriden in the node +// pipelineId - The ID of the pipeline +setNodeProperties(nodeId, properties, pipelineId) + +// Sets the node parameters +// nodeId - The ID of the node +// parameters - An array of parameters +// pipelineId - The ID of the pipeline +setNodeParameters(nodeId, parameters, pipelineId) + +// Sets the node UI parameters +// nodeId - The ID of the node +// parameters - An array of UI parameters +// pipelineId - The ID of the pipeline +setNodeUiParameters(nodeId, uiParameters, pipelineId) + +// Sets the node messages +// nodeId - The ID of the node +// messages - An array of messages +// pipelineId - The ID of the pipeline +setNodeMessages(nodeId, messages, pipelineId) + +// Sets a single message on a node +// nodeId - The ID of the node +// message - A message +// pipelineId - The ID of the pipeline +setNodeMessage(nodeId, message, pipelineId) + +// Sets the lable for a node +// nodeId - The ID of the node +// ndeLabel - The label +// pipelineId - The ID of the pipeline +setNodeLabel(nodeId, newLabel, pipelineId) + +// Sets the class name to newClassName of the nodes identified by nodeIds +// array in the pipleine specified by pipeline ID. The class name will be +// applied to the node body path. +setNodesClassName(nodeIds, newClassName, pipelineId) + +// Sets the decorations on a node. The decorations array passed in +// will replace any decorations currently applied to the node. +// nodeId - The ID of the node +// newDecorations - An array of decorations. See Wiki for details. +// pipelineId - The ID of the pipeline +setNodeDecorations(nodeId, newDecorations, pipelineId) + +// Sets the input ports on a node. The inputs array of ports provided will +// replace any input ports for a node. +// nodeId - The ID of the node +// inputs - An array of input port objects. +// pipelineId - The ID of the pipeline +setNodeInputPorts(nodeId, inputs, pipelineId) + +// Sets the output ports on a node. The outputs array of ports provided will +// replace any output ports for a node. +// nodeId - The ID of the node +// outputs - An array of output port objects. +// pipelineId - The ID of the pipeline +setNodeOutputPorts(nodeId, outputs, pipelineId) + +// Sets the decorations of multiple nodes at once. The decorations array +// passed in will replace any decorations currently applied to the nodes. +// pipelineNodeDecorations - Specifies the nodes and their decorations. +// It is a JavaScript array like this: +// [ +// { pipelineId: , nodeId: , decorations: }, +// { pipelineId: , nodeId: , decorations: }, +// { pipelineId: , nodeId: , decorations: } +// ] +setNodesMultiDecorations(pipelineNodeDecorations) + +// Sets the input port label on a node +// nodeId - The ID of the node +// portId - The ID of the input port +// newLabel - The label +// pipelineId - The ID of the pipeline +setInputPortLabel(nodeId, portId, newLabel, pipelineId) + +// Sets the output port label on a node +// nodeId - The ID of the node +// portId - The ID of the output port +// newLabel - The label +// pipelineId - The ID of the pipeline +setOutputPortLabel(nodeId, portId, newLabel, pipelineId) + +// Gets a node +// nodeId - The ID of the node +// pipelineId - The ID of the pipeline +getNode(nodeId, pipelineId) + +// Gets the UI parameters for a node +// nodeId - The ID of the node +// pipelineId - The ID of the pipeline +getNodeUiParameters(nodeId, pipelineId) + +// Gets the supernodes for a pipeline. +// pipelineId - The ID of the pipeline +getSupernodes(pipelineId) + +// Returns supernode ID that has a subflow_ref to the given pipelineId. +getSupernodeObjReferencing(pipelineId) + +// Gets the messages for a node +// nodeId - The ID of the node +// pipelineId - The ID of the pipeline +getNodeMessages(nodeId, pipelineId) + +// Gets the array of input ports for the node or null if the node ID is +// not recognized. +// nodeId - The ID of the node +// pipelineId - The ID of the pipeline +getNodeInputPorts(nodeId, pipelineId) + +// Gets the array of output ports for the node or null if the node ID is +// not recognized. +// nodeId - The ID of the node +// pipelineId - The ID of the pipeline +getNodeOutputPorts(nodeId, pipelineId) + +// Gets a message for a specific control for a node +// nodeId - The ID of the node +// controlName - The control name +// pipelineId - The ID of the pipeline +getNodeMessage(nodeId, controlName, pipelineId) + +// Gets an array of decorations for a node +// nodeId - The ID of the node +// pipelineId - The ID of the pipeline +getNodeDecorations(nodeId, pipelineId) + +// Gets the class name associated with the node specified by nodeId in the +// pipeline specified by pipelineId. +getNodeClassName(nodeId, pipelineId) + +// Gets the style spcification (see Wiki) for a node +// nodeId - The ID of the node +// temporary - A boolean to indicate if the style is serialized when +// getPipelineFlow() method is called or not. +// pipelineId - The ID of the pipeline +getNodeStyle(nodeId, temporary, pipelineId) + +// Returns an array of nodes that are for the branch(es) that the nodes, +// identified by the node IDs passed in, are within. +// nodeIds - An array of node Ids +// pipelineId - The ID of the pipeline where the nodes exist +getBranchNodes(nodeIds, pipelineId) + +// Returns an array of nodes that are upstream from the nodes +// identified by the node IDs passed in. +// nodeIds - An array of node Ids +// pipelineId - The ID of the pipeline where the nodes exist +getUpstreamNodes(nodeIds, pipelineId) + +// Returns an array of nodes that are downstream from the nodes +// identified by the node IDs passed in. +// nodeIds - An array of node Ids +// pipelineId - The ID of the pipeline where the nodes exist +getDownstreamNodes(nodeIds, pipelineId) + +// Returns a boolean to indicate whether the supernode is expanded in place. +// nodeId - The ID of the node +// pipelineId - The ID of the pipeline +isSuperNodeExpandedInPlace(nodeId, pipelineId) + +// Sets the label, for the node identified, to edit mode, provided the node +// label is editable. This allows the user to edite the label text. +setNodeLabelEditingMode(nodeId, pipelineId) + +// Sets the decoration label, for the decoration in the node identified, to edit +// mode, provided the node label is editable. This allows the user to edit the +// label text. +setNodeDecorationLabelEditingMode(decId, nodeId, pipelineId) +``` +The format of the message object is described in [Pipeline Flow UI schema](https://github.com/elyra-ai/pipeline-schemas/blob/master/common-pipeline/pipeline-flow/pipeline-flow-ui-v1-schema.json) +## Comment methods +```js +// Returns the comments from the pipeline. +// pipelineId - The ID of the pipeline +getComments(pipelineId) + +// Returns a comment from the pipeline. +// comId - The ID of the comment +// pipelineId - The ID of the pipeline +getComment(comId, pipelineId) + +// Returns a position object which indicates the position of where a new +// comment should be placed in a situation where the mouse position cannot be +// used (e.g. the toolbar button was clicked). +// pipelineId - The ID of the pipeline +getNewCommentPosition(pipelineId) + +// Creates a comment for the pipeline. +// source - Input data +// pipelineId - The ID of the pipeline +createComment(source, pipelineId) + +// Adds a comment to the pipeline. +// data - the data describing the comment +// pipelineId - The ID of the pipeline +addComment(data, pipelineId) + +// Edits a comment with the data. +// data - the comment +// pipelineId - The ID of the pipeline +editComment(data, pipelineId) + +// Sets the properties in the comment identified by the commentId. The +// commentProperties is an object containing one or more properties that will +// replace the corresponding properties in the comment. For example: if +// commentProperties is { x_pos: 50, y_pos: 70 } the comment +// will be set to that position. +setCommentProperties(commentId, commentProperties, pipelineId) + +// Sets the class name to newClassName of the comments identified by commentIds +// array in the pipleine specified by pipeline ID. The class name will be +// applied to the comment body path. +setCommentsClassName(commentIds, newClassName, pipelineId) + +// Deletes a comment +// comId - The ID of the comment +// pipelineId - The ID of the pipeline +deleteComment(comId, pipelineId) + +// Gets the class name associated with the comment specified by commentId in the +// pipeline specified by pipelineId. +getCommentClassName(commentId, pipelineId) + +// Gets the style spcification (see Wiki) for a comment +// commentId - The ID of the node +// temporary - A boolean to indicate if the style is serialized when +// getPipelineFlow() method is called or not. +// pipelineId - The ID of the pipeline +getCommentStyle(commentId, temporary, pipelineId) + +// Hides all comments on the canvas. +hideComments() + +// Shows all comments on the canvas - if they were previously hiding. +showComments() + +// Returns true if comments are currently hiding. +isHidingComments() + +// Sets the comment identified, to edit mode so the user can +// edit the comment. +setCommentEditingMode(commentId, pipelineId) + +``` +## Link methods +```js +// Gets a link +// linkId - The ID of the link +// pipelineId - The ID of the pipeline +getLink(linkId, pipelineId) + +// Returns an array of link objects for the pipelineId passed in. +// pipelineId - The ID of the pipeline +getLinks(pipelineId) + +// Sets the properties in the link identified by the linkId. The +// linkProperties is an object containing one or more properties that will +// replace the corresponding properties in the link. For exam`ple: if +// linkProperties is { trgNodeId: "123", trgNodePortId: "789" } the target +// node ID will be set to "123" and the target port ID set to "789". +setLinkProperties(linkId, linkProperties, pipelineId) + +// Sets the source properties in the data link identified by the linkId. The +// srcNodeId and srcNodePortId will be set to the values provided. If +// srcNodePortId is set to null the current srcNodePortId will be removed +// from the link. Also, if the link has a srcPos property (because its +// source end is detached) that will be removed. +setNodeDataLinkSrcInfo(linkId, srcNodeId, srcNodePortId, pipelineId) + +// Sets the target properties in the data link identified by the linkId. The +// trgNodeId and trgNodePortId will be set to the values provided. If +// trgNodePortId is set to null the current trgNodePortId will be removed +// from the link. Also, if the link has a trgPos property (because its +// target end is detached) that will be removed. +setNodeDataLinkTrgInfo(linkId, trgNodeId, trgNodePortId, pipelineId) + +// Gets a node to node data link +// srcNodeId - The ID of the source node +// srcNodePortId - The ID of the source node port +// trgNodeId - The ID of the target node +// trgNodePortId - The ID of the target node port +// pipelineId - The ID of the pipeline +getNodeDataLinkFromInfo(srcNodeId, srcNodePortId, trgNodeId, trgNodePortId, pipelineId) + +// Gets a comment to node link +// id1 - The ID of the comment +// id2 - The ID of the node +// pipelineId - The ID of the pipeline +getCommentLinkFromInfo(id1, id2, pipelineId) + +// Gets a node to node association link +// id1 - The ID of one of the node +// id2 - The ID of one of the node +// pipelineId - The ID of the pipeline +getNodeAssocLinkFromInfo(id1, id2, pipelineId) + +// Adds links to a pipeline +// linkList - An array of links +// pipelineId - The ID of the pipeline +addLinks(linkList, pipelineId) + +// Deletes a link +// source - An array of links +// pipelineId - The ID of the pipeline +deleteLink(link, pipelineId) + +// Creates node to node links +// data - Data describing the links +// pipelineId - The ID of the pipeline +createNodeLinks(data, pipelineId) + +// Creates comment links +// data - Data describing the links +// pipelineId - The ID of the pipeline +createCommentLinks(data, pipelineId) + +// Sets the class name to newClassName of the links identified by linkIds +// array in the pipleine specified by pipeline ID. The class name will be +// applied to the link line path. +setLinksClassName(linkIds, newClassName, pipelineId) + +// Sets the style of the links specified by pipelineLinkIds to be +// the newStyle which will be either temporary or permanent. +// pipelineLinkIds - This identifies the objects to be styles. It is a +// javascript object like this: +// { +// : [ +// , +// +// ], +// : [ +// , +// +// ] +// } +// newStyle - This is a style specification. See the wiki for details. +// temporary - A boolean to indicate if the style is serialized when +// getPipelineFlow() method is called or not. +setLinksStyle(pipelineLinkIds, newStyle, temporary) + +// Sets the styles of multiple links at once. +// pipelineObjStyles - Specified the links and the styles each should be +// set to. It is a javascript array like this: +// [ +// { pipelineId: , objId: , style: }, +// { pipelineId: , objId: , style: }, +// { pipelineId: , objId: , style: } +// ] +// temporary - A boolean to indicate if the styles are serialized when +// getPipelineFlow() method is called or not. +setLinksMultiStyle(pipelineObjStyles, temporary) + +// Gets the class name associated with the link specified by linkId in the +// pipeline specified by pipelineId. +getLinkClassName(linkId, pipelineId) + +// Returns the style specification for a link. +// linkIds - An array of links +// temporary - A boolean to indicate if the style is serialized when +// getPipelineFlow() method is called or not. +// pipelineId - The ID of the pipeline +getLinkStyle(linkId, temporary, pipelineId) + +// Sets the decorations on a link. The decorations array passed in +// will replace any decorations currently applied to the link. +// linkId - The ID of the link +// newDecorations - An array of decorations. See Wiki for details. +// pipelineId - The ID of the pipeline +setLinkDecorations(linkId, newDecorations, pipelineId) + +// Sets the decorations of multiple links at once. The decorations array +// passed in will replace any decorations currently applied to the links. +// pipelineLinkDecorations - Specifies the links and their decorations. +// It is a javascript array like this: +// [ +// { pipelineId: , linkId: , decorations: }, +// { pipelineId: , linkId: , decorations: }, +// { pipelineId: , linkId: , decorations: } +// ] +setLinksMultiDecorations(pipelineLinkDecorations) + +// Gets an array of decorations for a link +// linkId - The ID of the link +// pipelineId - The ID of the pipeline +getLinkDecorations(linkId, pipelineId) + +// Sets the decoration label, for the decoration in the link identified, to edit +// mode provided the link label is editable. This allows the user to edit the +// label text. +setLinkDecorationLabelEditingMode(decId, linkId, pipelineId) +``` + +## Breadcrumbs methods +```js +// Returns the current array of breadcrumbs. There will one breadcrumb object +// for each level of supernode that the user has navigated into. This array +// can be used to display breadcrumbs to the user to show where they are +// within the navigation hierarchy within common canvas. +getBreadcrumbs() + +// Returns the last breadcrumb which represents the level with supernode +// hierarchy that the user has currently navigated to. +getCurrentBreadcrumb() +``` + +## Branch Highlight methods +```js +// Highlights the branch(s) (both upstream and downstream) from the node +// IDs passed in and returns the highlighted object Ids. +// nodeIds - An array of node Ids +// pipelineId - The ID of the pipeline +highlightBranch(nodeIds, pipelineId) + +// Highlights the upstream nodes from the node IDs passed in +// and returns the returns the highlighted object Ids. +// nodeIds - An array of node Ids +// pipelineId - The ID of the pipeline +highlightUpstream(nodeIds, pipelineId) + +// Highlights the downstream nodes from the node IDs passed in +// and returns highlighted object Ids. +// nodeIds - An array of node Ids +// pipelineId - The ID of the pipeline +highlightDownstream(nodeIds, pipelineId) +``` +## Operational methods +These are general purpose methods for operation of the common-canvas components: + +### Logging methods +```js +// Returns a Boolean to indicate whether canvas logging is switched on or off. +getLoggingState() + +// Sets canvas logging based on the Boolean passed in. +setLoggingState(state) +``` + +### Palette methods +```js +// Opens the palette +openPalette() + +// Closes the palette +closePalette() + +// Returns true if the palette is currently open +isPaletteOpen() +``` + +### Context menu methods +```js +// Opens the context menu +openContextMenu(menuDef) + +// Closes the context menu +closeContextMenu() +``` + +### Notification Panel methods +```js +// Opens the notification panel +openNotificationPanel() + +// Closes the notification panel +closeNotificationPanel() + +// Either opens or closes the notifictaion panel based on its current status +toggleNotificationPanel() +``` + +### Right Flyout methods +```js +// Returns a boolean to indicate if the right flyout is open or not +isRightFlyoutOpen() +``` + +### Top panel methods +```js +// Returns a boolean to indicate if the top pnel is open or not +isTopPanelOpen() +``` + +### Bottom panel methods +```js +// Returns a boolean to indicate if the bottom panel is open or not +isBottomPanelOpen() + +// Sets the height of the bottom panel in pixels. This can be called +// immediately after the CanvasController has been created, if the bottom +// panel should be displayed at a specific height when it first opens. +setBottomPanelHeight(height) +``` + +### Canvas/pipeline navigation methods +```js +// Displays a pipeline (identified by the pipelineId passed in). This must be +// one of the pipelines referenced by the current set of breadcrumbs. It +// cannot be used to open a new pipeline outside the current set of breadcruumbs. +displaySubPipeline(pipelineId) + +// Displays a pipeline for the supernode (identifid by the supernodeId +// parameter) in the pipeline (identifid by the pipelineId parameter). For +// correct breadcrumb generation this pipeline should be the one in the last +// of the current set of breadcrumbs. That is, the pipeline currently shown +// "full page" in the canvas. +displaySubPipelineForSupernode(supernodeId, pipelineId) + +// Displays full-page the previous pipeline from the one currently being displayed +displayPreviousPipeline() +``` + +### Zoom methods +```js +// Centers the canvas contents and zooms in +zoomIn() + +// Centers the canvas contents and zooms out +zoomOut() + +// Zooms the canvas contents to fit within the viewport +zoomToFit() + +// Changes the zoom amounts for the canvas. This method does not alter the +// pipelineFlow document. zoomObject is an object with three fields: +// x: Is the horizontal translate amount which is a number indicating the +// pixel amount to move. Negative left and positive right +// y: Is the vertical translate amount which is a number indicating the +// pixel amount to move. Negative up and positive down. +// k: is the scale amount which is a number greater than 0 where 1 is the +// default scale size. +zoomTo(zoomObject) + +// Increments the translation of the canvas by the x and y increment +// amounts. The optional animateTime parameter can be provided to animate the +// movement of the canvas. It is a time for the animation in milliseconds. +// If omitted the movement happens immediately. +translateBy(x, y, animateTime) + +// Returns the current zoom object for the currently displayed canvas or null +// if the canvas is not yet rendered for the first time. +getZoom() + +// Returns a zoom object required to pan the objects (nodes and/or comments +// and/or links) identified by the objectIds array to 'reveal' the objects +// in the viewport. Returns null if no nodes, comments or links can be found +// using the IDs passed in. Note: node, comment and link IDs must be unique. +// The zoom object returned can be provided to the CanvasController.zoomTo() +// method to perform the zoom/pan action. +// If the xPos and yPos parameters are provided it will return a zoom object +// to pan the center of the objects specified, to a location where, xPos +// is the percentage of the viewport width and yPos is the percentage of the +// viewport height. So if you want the center of the objects specified to be +// in the center of the viewport set xPos to 50 and yPos to 50. +// If the xPos and yPos parameters are undefined (omitted) and all the +// objects are currently fully within the canvas viewport, this method will +// return null. This can be used to detect whether the objects are fully +// visible or not. +// If the xPos and yPos parameters are undefined and the objects are outside +// the viewport, a zoom object will be returned that can be used to zoom them +// so they appear at the nearest side of the viewport to where they are +// currently positioned. +// The zoom object retuurned has three fields: +// x: Is the horizontal translate amount which is a number indicating the +// pixel amount to move. Negative left and positive right +// y: Is the vertical translate amount which is a number indicating the +// pixel amount to move. Negative up and positive down. +// k: is the scale amount which is a number greater than 0 where 1 is the +// default scale size. +// Parameters: +// objectIds - An array of nodes and/or comment IDs. +// xPos - Optional. Can be set to percentage offset of the viewport width. +// yPos - Optional. Can be set to percentage offset of the viewport height. +getZoomToReveal(objectIds, xPos, yPos) + +// Clears any saved zoom values stored in local storage. This means +// newly opened flows will appear with the default zoom. This method +// is only applicable when the `enableSaveZoom` config parameter is +// set to "LocalStorage". +clearSavedZoomValues() + +``` diff --git a/docs/2.4.0-Calling-the-Canvas-Controller-API.md b/docs/2.4.0-Calling-the-Canvas-Controller-API.md new file mode 100644 index 0000000000..cebad931a4 --- /dev/null +++ b/docs/2.4.0-Calling-the-Canvas-Controller-API.md @@ -0,0 +1,39 @@ + +## Techniques for calling Canvas Controller API + +There are a couple of techniques you can use to update the object model using the Canvas Controller. + +### Incremental Updates +Once the pipeline flow is loaded into common-canvas using: +``` +canvasController.setPipelineFlow(pFlow) +``` +the pipeline flow is held in memory “inside” the object model of common-canvas. Thereafter, you can update that in-memory pipeline flow by calling canvas controller API such as: `deleteComment` or `createNode`, etc. The canvas controller will directly update the in-memory object model based on these calls, and it will cause the canvas view to refresh to reflect the change your code requested with the API call. + +It’s best to use the above technique when making small incremental changes to the object model often based on user requests. + +### Extensive Updates + +An alternative to making these individual API calls is to use `canvasController.getPipelineFlow(pFlow)` +which will return the full contents of the current state of the object model into a variable e.g. +``` +const currentPF = this.canvasController.getPipelineFlow(); +``` +You can then make changes to the pipeline flow using you own code. +For example: + +``` +// Wipe out all the comments in the zeroth pipeline +currentPF.pipelines[0].comments = []; +``` + +and then set the pipeline flow back into common canvas with this: + +``` +this.canvasController.setPipelineFlow(currentPF); +``` + +Note: the updating of the pipeline flow (currentPF) is entirely done by your code — there is no API to help you — so you have to understand the [pipeline flow schema](https://github.com/elyra-ai/pipeline-schemas/blob/main/common-pipeline/pipeline-flow/pipeline-flow-v3-schema.json) to understand what to do. + +This technique is probably most useful when doing extensive changes to the pipeline flow where you don’t want each change to cause a refresh of the canvas. This is because the only refresh of the canvas will be when you do the final `setPipelineFlow()` call. + diff --git a/docs/2.4.1-Style-Specification.md b/docs/2.4.1-Style-Specification.md new file mode 100644 index 0000000000..3a91c893bf --- /dev/null +++ b/docs/2.4.1-Style-Specification.md @@ -0,0 +1,69 @@ +There are multiple was to specify the styles for the objects common-canvas displays: + +* A class name can be provided for nodes either within the pipelineFlow document or +* The common-canvas default styes can be overriden within your CSS or SCSS file + +For more precise styling of objects the style specification object can be used to provide a number of styles to common canvas to set the inline styles on numerous elements of an object. For example, a node is made up of: a selection outline; a node body (rectangle); an image, a label etc. + +Style specifications may be applied to common-canvas objects using the following [Canvas Controller](/2.4-Canvas-Controller-API) methods: +```js +setObjectsStyle() +setObjectsMultiStyle() +setLinksStyle() +setLinksMultiStyle() +setSubdueStyle() +``` +and may be retrieved for objects using: +```js +getNodeStyle() +getCommentStyle() +getLinkStyle() +``` + +The style spec for a node can set the styles for all these elements in one shot. Here is a template of a style spec for a node: +```js +{ + body: { default: , hover: }, + image: { default: }, + label: { default: }, + selection_outline: { default: } +} + ``` +And here is a real example: +```js +{ + body: { + default: "fill: coral; stroke: red;", + hover: "fill: cornflowerblue; stroke: blue;" + } +}; +``` + +Here is a template for styling a comment: + +```js +{ + body: { default: , hover: }, + text: { default: }, + selection_outline: { default: }, +} +``` + +And here is a template for styling a link: +```js +{ + line: { default: , hover: } +} +``` + +* **``** - is a string containing any CSS code that can be added inline to an SVG object. That means, for example, you need to use fill and stroke for colors etc It is recommended NOT to change the sizes of text fonts. + +The CSS will be applied to the element of the object specified, either as the default inline style or as the style when the pointer hovers over the object. + +When a hover style is applied to a graphical element it is applied in addition to the default style so there is no need to repeat styles in the hover `` because they will augment the default style. + +Because styles are applied as in-line styles they will override any styles provided in your application's CSS and specified to common-canvas through the class_name field of canvas objects. + +If the `` is specified as null the current style will be removed from the specified element of the object. + +Finally, styles can be applied to your nodes, comments and links as either temporary or permanent styles by specifying the `temporary` boolean in the API methods. A temporary style is just applied for the duration of the session and are not persisted. You should use `temporary=true` styles that represent transient attributes of an object that should not be persisted in the pipelineFlow document. Use `temporary=false` styles for styles that you want to persist in the pipelineFlow document. diff --git a/docs/2.4.2-Decoration-Specification.md b/docs/2.4.2-Decoration-Specification.md new file mode 100644 index 0000000000..cd096cf8c5 --- /dev/null +++ b/docs/2.4.2-Decoration-Specification.md @@ -0,0 +1,195 @@ +## Decorations +Your application can add Decorations -- additional icons, text labels, shapes or JSX objects -- to nodes or links in the canvas to indicate special status or attributes of the node or link. Decorations can be static (for display only) or interactive (a hotspot) so the user can click them to initiate some action. + +## Adding Decorations +Decorations can be added to the nodes and/or links in four different ways: + +1. By using the following `CanvasController` methods: + ```js + setNodeDecorations(nodeId, newDecorations, pipelineId) + setNodesMultiDecorations(pipelineNodeDecorations) + setLinkDecorations(linkId, newDecorations, pipelineId) + setLinksMultiDecorations(pipelineLinkDecorations) + ``` + and can be retrieved using these `CanvasController` methods: + ```js + getNodeDecorations(nodeId, pipelineId) + getLinkDecorations(linkId, pipelineId) + ``` + See the [CanvasController API documentation](/2.4-Canvas-Controller-API) for more details. + +2. Node decorations can be specified in the [nodeLayout object](/2.1-Config-Objects#enablenodelayout) in the canvas config. Decorations specified in this way are applied to all nodes on the canvas. + +3. Decorations can be applied to, and retrieved from, nodes or links in the pipelineFlow in the `app_data.ui_data` section for the node or link. (Note: JSX objects are not supported in the pipelineFlow document). + +4. Decorations can be returned in the layout information returned from the [layoutHandler](/2.2-Common-Canvas-callbacks#layouthandler) CommonCanvas callback method. + +# Specification + +The decoration specification used by these methods and the pipelineFlow is a JavaScript object with these possible properties: + +These properties are applicable to an image decoration: +```js + { + id: , + image: , + position: , + distance: + x_pos: , + y_pos: , + width: , + height: , + hotspot: , + class_name: , + outline: , + tooltip: , + temporary: + } +``` +These properties are applicable to a label decoration: +```js + { + id: , + label: , + label_editable: , + label_align: , + label_single_line: , + label_max_characters: , + label_allow_return_key: , + position: , + distance: + x_pos: , + y_pos: , + width: , + height: , + hotspot: , + class_name: , + tooltip: , + temporary: + } +``` +These properties are applicable to a shape decoration: +```js + { + id: , + path: , + position: , + distance: + x_pos: , + y_pos: , + width: , + height: , + hotspot: , + class_name: , + tooltip: , + temporary: + } +``` +These properties are applicable to a JSX decoration: +```js + { + id: , + jsx: , + position: , + distance: + x_pos: , + y_pos: , + width: , + height: , + hotspot: , + class_name: , + tooltip: , + } +``` + +where: + +#### **id** +A unique ID for the decoration within the context of the node or link to which the decorator is attached. + +#### **image** +A reference to an image to display for the decoration. If an image is specified the image is displayed within an outline rectangle unless `outline` is set to false. The image should be a reference to your image like: "/images/decorations/zoom-in_32.svg". Do not set label or path or jsx when this field is set. + +#### **path** +An SVG shape that is displayed using this string as it's SVG path. eg. "M 0 0 L 10 10 -10 10 Z" could be specified to draw a triangle. Do not set image or label or jsx when this field is set. + +#### **jsx** +A JSX object that is is displayed at the specified decoration location. Do not set image or path or label when this field is set. Note JSX decorations are not supported in the pipelineFlow document. + +#### **label** +A text string that is displayed at the specified decoration location. Do not set image or path or jsx when this field is set. + +#### **label_editable** +A boolean that defaults to `false`. When set to `true`, if the mouse pointer is hovered over the label an edit icon is displayed next to the label which, when clicked, opens the label for editing. The label can also for double clicked to go to edit mode. + +When editing is completed (by clicking outside the text area) an `editDecorationLabel` action is executed which results in calls to first the `beforeEditActionHandler` and then the `editActionHandler` callbacks. + +#### **label_align** +Can be either "center" or "left". When set to center the label will be centered on the point defined by the `position`, `distance`, `x_pos` and `y_pos` properties. + +#### **label_single_line** +A boolean that defaults to `false`. When set to `true` the label is displayed on a single line and is truncated at the width of the label (specified in the `width` property for the decoration) and does not word wrap. If it is truncated an ellipsis (...) is displayed at the end of the truncated text. + +If this property is set to `false`, long label text is displayed over a number of lines with word wrapping being controlled by the `width` set for the decoration. If the text extends beyond a second line an ellipsis (..) is displayed at the end of the second line. This is controlled by the `-webkit-line-clamp: 2;` CSS property. You can override this if you want the ellipsis to be displayed on a different line. + +Note: For both single and multi-line labels you may need to set the `height` property for the decoration to show the text fully. + +#### **label_max_characters** +A number or null. Defaults to null. If set to a number the label will be restricted to that number of characters. If the label in the pipeline flow document is longer than the max number it will be displayed but when it is edited the user will not be able to do anything except delete characters until the label is shorter than the max number. If this property is set to `null` or omitted an unlimited number of characters may be entered by the user. + +#### **label_allow_return_key** +A boolean that defaults to `false`. When `false`, if the user presses the return key nothing will happen. This means multi-line labels will only word-wrap at the `width` of the decorator. Preventing newline insertion is useful if the label text appears elsewhere in the UI which is not able to show text with newline characters. When set to `"save"`, if the user presses the return key, the editing will be completed and the label saved -- this is the equivalent of clicking on the canvas background to complete the edit. If set to `true`, a new line character will be inserted in the label when the user presses return. + +#### **position** +This is the anchor point to which the decoration is attached. For a node, this can be one of these 9 enumerated values: +``` + "topLeft", "topCenter", "topRight", + "middleLeft", "middleCenter", "middleRight", + "bottomLeft", "bottomCenter", "bottomRight". +``` +If omitted it will default to "topLeft". + +For a link, this can be one of these 3 enumerated values: +``` + "source" + "middle" + "target" +``` +`source` will position the decoration at the start point of the line and `target` will position it at the end point of the line. If omitted it will default to `middle`. + +#### **distance** +A number of pixels. This is only applicable when the decoration is for a link line and then, only with straight connecting lines. That is, for node to node connections when the config property `enableLinkType` is set to `"straight"`. When specified, it will move the anchor point for the decoration to a new position along the connecting line relative to the initial position specified in the decoration's `position` property. A positive number moves the decoration along the line from the starting position towards the target of the link and a negative number backwards towards the source of the link. For example, if a straight link decoration has `position` of `source` and a `distance` of `20` the decoration's anchor point will be 20 pixels along the link line from the source (start) point of the line. After the `distance` value has been applied to the anchor point of the decoration, any `x_pos` and `y_pos` adjustment will be applied to fine tune the decoration's final position. + +#### **x_pos** +This is the number of pixels horizontally from the anchor point that the decoration is positioned. It can be positive or negative. If omitted it takes a default value from the [node layout properties](/2.7-Customizing-Node-Layout-Properties#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default). x_pos is not applicable if you specify an SVG path using the `path` field, because the SVG path can be used to position the shape. + +#### **y_pos** +This is the number of pixels vertically from the anchor point that the decoration is positioned. It can be positive or negative. If omitted it takes a default value from the [node layout properties](/2.7-Customizing-Node-Layout-Properties#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default). y_pos is not applicable if you specify an SVG path using the `path` field, because the SVG path can be used to position the shape. + +#### **width** +This is the width for the decorator in pixels. For an image decorator, it is the width of the rectangle surrounding the image. For a label decorator it is the width allowed for display of the label text. If omitted it takes a default value from the [node layout properties](/2.7-Customizing-Node-Layout-Properties#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default) for Node decorations and from the canvas layout properties for Link properties. + +#### **height** +This is the height for the decorator in pixels. For an image decorator, it is the height of the rectangle surrounding the image. For a label decorator it is the height allowed for display of the label text. If omitted it takes a default value from the [node layout properties](/2.7-Customizing-Node-Layout-Properties#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default) for Node decorations and from the canvas layout properties for Link properties. + +#### **hotspot** +A Boolean. It defaults to false. When set to true the decoration becomes clickable and when it is clicked the [decorationCallbackHandler](/2.2-Common-Canvas-callbacks#decorationactionhandler) is called with the ID of the decoration passed as a parameter. + +#### **class_name** +An optional class that will be applied to the decoration. You can add a style rule that references that class in your CSS to style the decoration and override the default styles. + +#### **outline** +A Boolean. It defaults to true. When a decoration is specified with an image field the image is typically displayed with a outline rectangle around it and with an offset within the rectangle to improve presentation. If `outline` is set to `false` the outline rectangle is **not** displayed and the image is displayed without any offset from its specified `x_pos` and `y_pos`. + +#### **tooltip** +A String. When specified, the string will be shown in a tooltip when the pointer is hovered over the decoration. No tip will be displayed if the `tooltip` property is omitted. Note: for decoration tooltips to be displayed on the canvas, the `decorations` property of the `tipConfig` object in the canvas config must be set to true (which is its default setting). + +#### **temporary** +A Boolean. It defaults to false. When set to true the decoration object will _not_ be saved in the pipelineFlow document returned by the `CanvasController.getPipelineFlow()` method. Typically, this should be set to `true` when adding decorations programmatically to the nodes and links on the canvas. + +### Notes: + +1. Using `x_pos` and `y_pos`, decorations can be displayed outside the node boundary. +2. If no image or label or path is provided, the default decoration is a rectangle displayed with the class_name provided. +3. You can specify as many decorations as you want by providing extra entries in the decorations array. +4. Images and labels are positioned differently. For images, the position defined for the decoration is the top left corner of the image. For labels it is anchor point for the label which is the base line of the string in the vertical direction and is dependent on the text-anchor CSS property applied to the text. So if you apply the `text-anchor: middle` CSS property to the label in the style related to class_name the label will be centered on the point calculated for the position of the decoration. \ No newline at end of file diff --git a/docs/2.4.3-Object-structure-used-by-API.md b/docs/2.4.3-Object-structure-used-by-API.md new file mode 100644 index 0000000000..48828c0c70 --- /dev/null +++ b/docs/2.4.3-Object-structure-used-by-API.md @@ -0,0 +1,49 @@ +# API differences with schema +Because historically common-canvas has had to deal with different external flow definitions, there are some differences between the nodes, comments and links that the CanvasController API handles internally and those specified in the pipelineFlow schema. As follows: + +## Object structure + For the API methods that involve nodes, comments and links, those objects are passed in and out by the API in their internal formats rather than the formats defined in the schema files. + +The internal structure is a somewhat flattened version of that in the schema definition. That means, properties that are in `.app_data.ui_data` are flattened out and appear as properties in the `` itself. So for example a node that conforms to the schema might look like this: +```js + { + id: "1234", + op: "select", + ... + app_data : { + ui_data: { + label: "Selection node", + image: "/images/select.svg", + description: "A node for selection" + ... + }, + other_data: { + prop1: "Something interesting" + } + } + } +``` +whereas when it is passed through the API it looks like this: +```js + { + id: "1234", + op: "select", + label: "Selection node", + image: "/images/select.svg", + description: "A node for selection" + ... + app_data : { + other_data: { + prop1: "Something interesting" + } + } + } +``` +Note that, any properties in `app_data`, other than `ui_data`, are preserved in the internal format. So in the example, `app_data.other_data` in the schema format is preserved in the internal format. + +## Links handing in the API +The other difference between the API and the schema formats is with links. + +In the pipeline flow schema, links are typically defined as properties within another object, for example, a node to node link is defined within a `links` array inside the `inputs` field of the target node and contains references to the `node id` and `port` of the source node. Also, links from comments to nodes are stored as an array in the comment object. + +However, in the API and internally in common-canvas, links are treated as a top level object; that is, there is an array of links stored internally which can be manipulated using the API methods. Each link has a unique ID. Consequently, links can be retrieved from the API by their ID field and properties of the links can be updated again by identifying the links using their ID. If you do not specify an ID for links in your pipelineFlow document a unique global ID will be generated for each link when the pipeline flow is loaded. \ No newline at end of file diff --git a/docs/2.4.4-Notification-Message-Specification.md b/docs/2.4.4-Notification-Message-Specification.md new file mode 100644 index 0000000000..b7e1b9ccb7 --- /dev/null +++ b/docs/2.4.4-Notification-Message-Specification.md @@ -0,0 +1,31 @@ +### Notification Message structure. + +Notification messages are displayed in the notification panel which the user can access by clicking the Notifications icon in the toolbar. Each notification message is described by a simple JavaScript object like this: +```js + { + id: , + type: , + title: , + content: , + timestamp: , + callback: , + closeMessage: +} +``` +where: + + * **id** (string, required): this is a unique ID assigned to the notification message. This is passed as a parameter in the callback (see below) and is used to reference messages when deleting them through the `CanvasController` API. + +* **type** (string, required): this must be one of four values: "info", "success", "warning", or "error". If `type` is null, empty string, or undefined, the message type will be "unspecified". + +* **title** (string or JSX object): the title of the notification message + +* **content** (string or JSX object): the body of the notification message + +* **callback** (function): an optional callback function that will be called when the notification message is clicked. Callback function is called with one parameter, `id` + +* **timestamp** (string or JSX object): an optional timestamp that will be rendered in a separate section with different formatting, if passed in + +* **closeMessage** (string or React object): an optional message that, if passed in, will display as clickable. Clicking on this will delete this individual message. If none is passed in, no delete option will be shown. + + diff --git a/docs/2.4.5-Programmatically-creating-new-canvas-nodes.md b/docs/2.4.5-Programmatically-creating-new-canvas-nodes.md new file mode 100644 index 0000000000..89dc8a5928 --- /dev/null +++ b/docs/2.4.5-Programmatically-creating-new-canvas-nodes.md @@ -0,0 +1,64 @@ +## Introduction + +The host application code can programmatically create nodes on the canvas in two ways: + +* By calling CanvasController API methods to create and add the node to the canvas. + +* Creating and adding a node to the Pipeline Flow document + + +## Creating and adding a node to the Canvas Controller API + +The following code will programmatically add a node to the canvas. These commands will update the common-canvas object model directly and will not be added to the command stack so the user will not be able to `undo` / `redo` these actions. Also, the `beforeEditActionHandler` and `editActionHandler` callbacks will not be called for these actions. + +First you can get a node template from the canvas by calling +```js + const template = canvasController.getPaletteNode("sort"); +``` +where the parameter is the operation (`op` field) for the palette node. Alternatively, you can retrieve a node template using this method: +```js + const template = canvasController.getPaletteNodeById(nodeId) +``` +which returns the node template based on the node ID. This can be useful if you have supernodes in your palette because supernodes do not have an `op` field. After creating the node template your code can alter fields (for example, the label) within the template. If you do change any fields be careful because common-canvas doesn't do any error checking on your fields. + +Next you create the node: +```js + const newNode = canvasController.createNode({ + nodeTemplate: template, + offsetX: 200, + offsetY: 400 +}); +``` +This will work correctly for regular nodes, and also supernodes, that have been pulled from the palette. + +Next you add the node object to the canvas. +```js + canvasController.addNode(newNode); +``` +The node will appear at the offsetX, offseY position within the coordinate system for the canvas. + +### If command stack is needed + +This method allows the host application to create a node, or supernode, from a palette template object by creating and executing a command which will be added to the command stack (so the user can `undo` / `redo` it) and will also cause the `beforeEditActionHandler` and `editActionHandler` callbacks to be called. + + +First your code retrieves a node template from the palette as described above and then calls this method: +```js + const data = { + nodeTemplate: template, + offsetX: 200, + offsetY: 400 + }; + + canvasController.createNodeCommand(data, pipelineId) +``` + +Note: If `pipelineId` is omitted the node will be created in the current "top-level" pipeline. + +## Creating and adding a node using Pipeline Flow document + +This approach works by your code adding one or more JSON objects directly to the pipeline flow object, either before the pipeline flow document is loaded into common-canvas using `CanvasController.setPipelineFlow(pFlow)`, or afterwards by retrieving the pipeline flow object from common-canvas using `CanvasController.getPipelineFlow()` and then updating the nodes array of whichever pipeline you want to modify. This would require your code to navigate to the `pipeline` object (that you want to update) in the `pipelines` array of the pipeline flow and then add the node object to the `nodes` array in the pipeline object. + +After updating the pipeline flow object your code would need to reload it into common-canvas using `CanvasController.setPipelineFlow(pFlow)`. + +To use this approach you would need a good understanding of the [pipeline flow schema](https://github.com/elyra-ai/pipeline-schemas/blob/412d70176953ed9ac2e6a03f7135b09b7565fc5d/common-pipeline/pipeline-flow/pipeline-flow-v3-schema.json) and [pipeline flow UI schema](https://github.com/elyra-ai/pipeline-schemas/blob/412d70176953ed9ac2e6a03f7135b09b7565fc5d/common-pipeline/pipeline-flow/pipeline-flow-ui-v3-schema.json). diff --git a/docs/2.4.6-Constructing-a-read-only-or-locked-canvas.md b/docs/2.4.6-Constructing-a-read-only-or-locked-canvas.md new file mode 100644 index 0000000000..7043437621 --- /dev/null +++ b/docs/2.4.6-Constructing-a-read-only-or-locked-canvas.md @@ -0,0 +1,57 @@ +## Introduction + +Some host applications need to display flows that cannot be edited by the user. This might be because the flow artifact is currently being edited by another user (locked) or because the user does not have authority to edit the flow (read-only) or some other reason. We'll use the term 'read-only' below to refer to both locked and read-only canvases. + +There are many aspects of common-canvas components that need to considered for a read-only canvas. Since common-canvas is highly customizable it is not possible for the common-canvas code to manage components of the canvas that have been customized by the host application. For example, if the host app code added tools to the toolbar, common-canvas does not know whether those tools should be disabled when displaying a read-only canvas or not. So the host application code will need to manage that. Let's look at each element of common-canvas and see what needs to be done. + +# General Config +There is one main canvas configuration property that will change the common-canvas behavior to implement a read-only canvas. This is [`enableEditingActions`](/2.1-Config-Objects#enableeditingactions) which defaults to true and needs to be set to `false` for read-only canvases. The sections below will cover what effect this will have on the different components of common-canvas and what you need to do for any customizations you have made. + +# Canvas +Setting `enableEditingActions` to false will prevent nodes and comments (and detachable links) from being moved relative to one another. It will also prevent new links from being created and prevent text (like comments or node labels) from being edited. + +With `enableEditingActions` set to false, the canvas can still be panned (left/right and up/down) and also zoomed in and out. Nodes, comments and links can still be clicked (to select) and right clicked (to display a context menu) and double clicked (usually to show properties). If you implemented any behavior for these interactions, using the [`clickActionHandler`](/2.2-Common-Canvas-callbacks#clickactionhandler), you'll need to review what your code is doing and make sure it is appropriate when a read-only canvas is being displayed. + +Common-canvas allows objects from outside the canvas to be dropped onto the canvas to create a new node. For example, a file can be dragged from the operating system desktop onto the canvas to create a data node. With `enableEditingActions` set to false, the drag/drop gesture (which common-canvas cannot prevent) will prevent a new node from being created. It is recommended you switch the [`enableDropZoneOnExternalDrag`](/2.1-Config-Objects#enabledropzoneonexternaldrag) config property to false when displaying a read-only canvas. This will prevent a 'drop zone' graphic from appearing over the canvas when the object is dragged over the top of the canvas. + +Some applications need to show a tag (called a 'state tag') over the canvas to emphasize the 'read-only' or 'locked' state of the canvas. This can be displayed using the [`enableStateTag`](/2.1-Config-Objects#enablestatetag) canvas config property. The tooltip of the 'state tag' can be provided by implementing the [`tipHandler`](/2.2-Common-Canvas-callbacks#tiphandler) callback function. + +Since there are numerous possible styles for nodes and links when displaying a read-only canvas, it isn't possible for common-canvas to style the canvas objects appropriately for all different designs. You will need to override any styles for nodes and links to fit your design. To help with this common-canvas sets a class called `config-edit-actions-false` on the top-level div that contains the common-canvas components. You can use this to build specific selectors in your CSS/SCSS that will override the styles applied to nodes and links by default. For example, to override node icon and label colors you could specify the following in your SCSS file: +``` + .editing-actions-false { + .d3-node-group { + & .d3-node-label, + & svg path { + color: $disabled-02; + stroke: $disabled-02; + fill: $disabled-03; + } + } + } +``` + +# Context menu +Setting `enableEditingActions` to false will prevent any options, that would edit the canvas objects, from being displayed in the common-canvas default context menu. For example, `Delete` will not show up in the context menu. See the [`enableEditingActions` documentation](/2.1-Config-Objects#enableeditingactions) for a list of options that are disabled. + +Your application code can add your own options to the context menu by implementing the [`contextMenuHandler`](/2.2-Common-Canvas-callbacks#contextmenuhandler) callback function. If you have added your own options, you should review your code and ensure options that might change the canvas objects are not added to the context menu when you are displaying a read-only canvas. + +Note: The common-canvas default menu, passed as the second parameter to the `contextMenuHandler` callback, will still contain editing options. This means, if your code relies on them for some reason, (for example for calculating the position of your added options) your application code will still work OK. The editing options will be removed after your code returns the array of items that describe the desired menu from the `contextMenuHandler` callback. + +# Toolbar +The toolbar can display buttons for standard common-canvas actions and also buttons for any application-specific actions added by your code. Setting `enableEditingActions` to false will cause buttons for any standard common-canvas actions, that edit the canvas objects, to be disabled regardless of the setting for the `enable` property for each action. See the [`enableEditingActions` documentation](/2.1-Config-Objects#enableeditingactions) for a list of actions that are disabled. + +You should review any application-specific action buttons you have added to the toolbar and decide if they need to be disabled or removed from the toolbar when displaying a read-only canvas. + +# Keyboard +Common-canvas supports a number of keyboard shortcuts. Setting `enableEditingActions` to false, disables any keyboard shortcuts that edit the canvas objects (such as Delete). See the [`enableEditingActions` documentation](/2.1-Config-Objects#enableeditingactions) for a list of keyboard shortcuts that are disabled. + +# Palette +Setting `enableEditingActions` to false: + +* prevents node templates from being dragged from the palette and +* disables the double-click action on node templates which automatically adds a node to the canvas. + +You should decide if your application should display the palette when displaying a read-only canvas or not. The palette can be hidden by setting the canvas config property [`enablePaletteLayout`](/2.1-Config-Objects#enablepalettelayout) to "None". + +# Test Harness: Sample Read-Only application +The test harness contains a sample application called "Read-Only" which shows how a read-only canvas can be built using the `enableEditingActions` config option. In the application there are three toolbar buttons which can be used to navigate between Editable state, Read-Only state and Locked state. You can review the `.jsx` and `.scss` files in the [application code](https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/src/client/components/custom-canvases/read-only) to see how the application is implemented and styled. diff --git a/docs/2.5-Command-Stack-API.md b/docs/2.5-Command-Stack-API.md new file mode 100644 index 0000000000..1e6998d6ab --- /dev/null +++ b/docs/2.5-Command-Stack-API.md @@ -0,0 +1,79 @@ +# Command Stack API + + The CommandStack is a JavaScript class that provides the functionality to support do/undo/redo of commands. It maintains an internal stack of commands with a cursor that moves up and down when commands are undone or redone. Commands are also Javascript classes that implement a simple interface. + + The canvas-controller creates an instance of the command stack. Common-canvas provides command objects for each of the commands that are performed by the user, such as: create node, delete comment, link nodes together, etc. + + To activate the undo and redo actions, common-canvas provides undo/redo options in its default context menu, on the default toolbar and via keystrokes ctrl+z (undo) and ctrl+shift+z (redo). You can implement your own undo and redo UI if required using the API. + + The CommandStack API allows application code to programmatically add commands to the command stack. You can get the Command Stack by calling the canvas-controller's `getCommandStack()` method. The CommandStack API provides the following methods: + +```js + do(command) - push the command onto the command stack and then invoke command.do() + undo() - pop a command from the command stack and then invoke command.undo() + redo() - push last undo command onto the command stack and then invoke command.redo() + canUndo() - returns true if there is a command on the command stack. + canRedo() - returns true if there is an undo command that can be redo. + clearCommandStack() + getUndoCommand() - returns the next command to be undone or null. + getRedoCommand() - returns the next command to be redone or null. +``` + +Many of these have equivalent methods in the canvas-controller. + +Each command that is added to the command stack is a Javascript class that needs to implement these methods: + + +```js + constructor() + do() + undo() + redo() +``` + +constructor() - Initial setup + +do() - Performs all actions necessary to execute the command + +undo() - Performs all actions necessary to reverse the actions performed in do() + +redo() - Performs all actions necessary to re-execute the command. For some commands this is the same as do() but others it is different. + + + Here is some sample code that shows how a create-node command might be written: + +```js + export default class CreateNodeAction extends Action { + constructor(data) { + super(data); + this.newNode = createNode(data); + } + + do() { + ObjectModel.addNode(this.newNode); + } + + undo() { + ObjectModel.removeNode(this.newNode.id); + } + + redo() { + ObjectModel.addNode(this.newNode); + } + + getLabel() { + return "Add 1 node" + } + + } +``` + + Here is an example of using the CommandStack API to create a command action and push it on the stack: + +```js + const command = new CreateNodeAction(data); + this.canvasController.getCommandStack().do(command); +``` + + + diff --git a/docs/2.6-Flow-Validation-API.md b/docs/2.6-Flow-Validation-API.md new file mode 100644 index 0000000000..159fdda93f --- /dev/null +++ b/docs/2.6-Flow-Validation-API.md @@ -0,0 +1,62 @@ +# Flow Validation API + + The Flow Validation API allows application code to programmatically validate the nodes in the flow against it's property values. The API can be invoked after setting the Canvas Controller pipeline flow, when opening a new flow, or associated with a canvas context menu item. To use the Flow Validation API import the FlowValidation object fro common-canvas: +``` +import { FlowValidation } from "@elyra/canvas"; +``` +then call the API on the object, for example: +``` +FlowValidation.validateFlow( ... ); +``` + +The Flow Validation object provides the following API: + +``` +validateFlow(canvasController, parameterDataCallback, setNodeMessagesCallback, includeMsgTypes) + canvasController - an instance of the canvas controller + parameterDataCallback – function to get the parameter data or form data for a node + setNodeMessagesCallback – function to set the validation messages for a node. (optional) + includeMsgTypes - array[strings] Return invalid only if messages are found of types contained + in the array. If not specified then any message type causes invalid return. (optional) + return - boolean If flow is valid returns true, otherwise returns false. +``` +where the two callbacks are defined as follows: +``` +parameterDataCallback(nodeId) + nodeId – string node Id. + function must return this object: + { + type: “parameterDef” | “form”, + data: Json_object + } + +/* The setNodeMessagesCallback is optional and only useful if not using internal object model. +setNodeMessagesCallback(nodeId, messages) + nodeId – string node Id. + an array of message objects generated from the validation of the node. +``` + +The validateFlow() API will traverse the current flow and for each node invoke the parameterDataCallback() to get with a form data JSON or a parameterDef JSON. It will validate the JSON for the node and store any messages in the node objects within the model. The setNodeMessagesCallback() function will be called with all the messages generated for the node. This is only useful if the application is not using the internal object model. +The format of the message object is described in [Pipeline Flow UI schema](https://github.com/elyra-ai/wdp-pipeline-schemas/blob/master/common-pipeline/pipeline-flow/pipeline-flow-ui-v1-schema.json) + +Here is an example of using the FlowValidation API to validate a flow on opening: + +``` +import { CanvasController, FlowValidation } from "@elyra/canvas"; + +getNodeForm(nodeId) { + const parameterDef = getParameterDefJSON(nodeId); + return { type: "parameterDef", data: parameterDef }; +} + +setNodeMessages(nodeId, messages) { + // code to persist messages in a store in addition to the internal model. +} + +openCanvas(canvasJson) { + const canvasController = new CanvasController(); + canvasController.setPipelineFlow(canvasJson); + FlowValidation.validateFlow(canvasController, this.getNodeForm, this.setNodeMessages); +} + +``` diff --git a/docs/2.7-Customizing-Node-Layout-Properties.md b/docs/2.7-Customizing-Node-Layout-Properties.md new file mode 100644 index 0000000000..64c033441b --- /dev/null +++ b/docs/2.7-Customizing-Node-Layout-Properties.md @@ -0,0 +1,392 @@ +## Node layout properties +Node layout properties define how all the elements of a node are displayed such as: the position and size of the icon image; the position of the main label; even the shape of the node itself! You can change just about anything to do with the way the nodes appear in your canvas. So you can get a very different looking canvas to suit your needs. + +There are two possible sets of node layout properties provided by common-canvas, these are controlled by the `enableNodeFormatType` canvas configuration property which can be set to either "Horizontal" or "Vertical". "Horizontal" will display a node with an image and the label to the right of the image. "Vertical" will display the node with the label underneath the image. + +## Default values for node layout properties +The possible node layout properties are shown below with the values they have when `enableNodeFormatType = "Horizontal"`. You can see the values for both sets of properties by looking at the [layout-dimensions.js program](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/common-canvas/src/object-model/layout-dimensions.js) + +``` +// Default node sizes. The height might be overridden for nodes with more ports +// than will fit in the default size. +defaultNodeWidth: 160, +defaultNodeHeight: 40, + +// A space separated list of classes that will be added to the group +// DOM element for the node. +className: "", + +// Displays the node outline shape underneath the image and label. +nodeShapeDisplay: true, + +// Default node shape. Can be "rectangle" or "port-arcs". Used when nodeOutlineDisplay is true. +nodeShape: "port-arcs", + +// SVG path strings to define the shape of your node and its +// selection highlighting. If set to null the paths will be set by default +// based on the nodeShape setting. +bodyPath: null, +selectionPath: null, + +// Displays the external object specified, as the body of the node +nodeExternalObject: false, + +// Display image +imageDisplay: true, + +// Image dimensions +imageWidth: 26, +imageHeight: 26, + +// Image position +imagePosition: "topLeft", +imagePosX: 6, +imagePosY: 7, + +// Display label +labelDisplay: true, + +// Label dimensions +labelWidth: 112, +labelHeight: 19, + +// Label position +labelPosition: "topLeft", +labelPosX: 36, +labelPosY: 12, + +// Label appearance +labelEditable: false, +labelAlign: "left", // can be "left" or "center" +labelSingleLine: true, // false allow multi-line labels +labelOutline: false, +labelMaxCharacters: null, // null allows unlimited characters +labelAllowReturnKey: false, // true allows line feed to be inserted into label, "save" to make the return key save the label. + +// An array of decorations to be applied to the node. For details see: +// https://github.com/elyra-ai/canvas/wiki/2.4.2-Decoration-Specification +// These are added to the node at run time and will not be saved into +// the pipeline flow. +decorations: [], + +// Positions and dimensions for 9 enumerated default decorator positions. +// decoratorWidth and decoratorHeight are the dimensions of the outline +// rectangle and decoratorPadding is the padding for the image within the +// outline rectangle. +decoratorTopY: 2, +decoratorMiddleY: -8, +decoratorBottomY: -18, + +decoratorLeftX: 2, +decoratorCenterX: -8, +decoratorRightX: -30, + +// Width, height and padding for image decorators +decoratorWidth: 16, +decoratorHeight: 16, +decoratorPadding: 2, + +// Width and height for label decorators +decoratorLabelWidth: 80, +decoratorLabelHeight: 30, + +// Display drop shadow under and round the nodes +dropShadow: true, + +// The gap between a node and its selection highlight rectangle +nodeHighlightGap: 1, + +// The size of the node sizing area that extends around the node, over +// which the mouse pointer will change to the sizing arrows. +nodeSizingArea: 10, + +// Error indicator dimensions +errorPosition: "topLeft", +errorXPos: 24, +errorYPos: 5, +errorWidth: 10.5, +errorHeight: 10.5, + +// When sizing a supernode this decides the size of the corner area for +// diagonal sizing. +nodeCornerResizeArea: 10, + +// What point to draw the data links from and to when enableLinkType is set +// to "Straight". Possible values are "image_center" or "node_center". +drawNodeLinkLineFromTo: "node_center", + +// What point to draw the comment to node link line to. Possible values +// are "image_center" or "node_center". +drawCommentLinkLineTo: "node_center", + +// This is the size of the horizontal line protruding from the +// port on the source node when drawing an elbow or straight connection line. +minInitialLine: 30, + +// For the elbow connection type with nodes with multiple output ports, +// this is used to increment the minInitialLine so that connection lines +// do not overlap each other when they turn up or down after the elbow. +minInitialLineIncrement: 8, + +// This is the minimum size of the horizontal line entering the +// target port on the target node when drawing an Elbow connection line. +minFinalLine: 30, + +// Display input ports. +inputPortDisplay: true, + +// Object for input port can be "circle" or "image". +inputPortObject: "circle", + +// If input port object is "image" use this image. +inputPortImage: "", + +// If input port dimensions for "image". +inputPortWidth: 12, +inputPortHeight: 12, + +// Position of left single input port. Multiple input ports will be +// automatically positioned with the Y coordinate being overriden. These +// values are an offset from the top left corner of the node outline. +// Used when linkDirection is "LeftRight". +inputPortLeftPosX: 0, +inputPortLeftPosY: 20, + +// Position of top single input port. Multiple input ports will be +// automatically positioned with the X coordinate being overriden. These +// values are an offset from the top left corner of the node outline. +// Used when linkDirection is "TopBottom". +inputPortTopPosX: 80, +inputPortTopPosY: 0, + +// Position of bottom single input port. Multiple input ports will be +// automatically positioned with the X coordinate being overriden. These +// values are an offset from the bottom left corner of the node outline. +// Used when linkDirection is "BottomTop". +inputPortBottomPosX: 80, +inputPortBottomPosY: 0, + +// The 'guide' is the object drawn at the mouse position as a new line +// is being dragged outwards. +// Object for input port guide can be "circle" or "image". +inputPortGuideObject: "circle", + +// If input port guide object is "image" use this image. +inputPortGuideImage: "", + +// Display output ports. +outputPortDisplay: true, + +// Object for output port can be "circle" or "image". +outputPortObject: "circle", + +// If output port object is "image" use this image. +outputPortImage: "", + +// Output port dimensions for "image". +outputPortWidth: 12, +outputPortHeight: 12, + +// Position of right single output port. Multiple input ports will be +// automatically positioned with the Y coordinate being overriden. These +// values are an offset from the top right corner of the node outline. +// Used when linkDirection is "LeftRight". +outputPortRightPosition: "topRight", +outputPortRightPosX: 0, +outputPortRightPosY: 20, + +// Position of top single output port. Multiple input ports will be +// automatically positioned with the X coordinate being overriden. These +// values are an offset from the top left corner of the node outline. +// Used when linkDirection is "BottomTop". +outputPortTopPosX: 80, +outputPortTopPosY: 0, + +// Position of bottom single output port. Multiple input ports will be +// automatically positioned with the X coordinate being overriden. These +// values are an offset from the bottom left corner of the node outline. +// Used when linkDirection is "TopBottom". +outputPortBottomPosX: 80, +outputPortBottomPosY: 0, + +// The 'guide' is the object drawn at the mouse position as a new line +// is being dragged outwards. +// Object for output port guide can be "circle" or "image". +outputPortGuideObject: "circle", + +// If output port guide object is "image" use this image. +outputPortGuideImage: "", + +// Automatically increases the node size to accommodate its ports so both +// input and output ports can be shown within the dimensions of +// the node. +autoSizeNode: true, + +// Radius of the either the input or output ports when they are set to "circle" +portRadius: 3, + +// Size of an offset above and below the set of port arcs. +portArcOffset: 3, + +// Radius of an imaginary circle around the port. This controls the +// spacing of ports and the size of port arcs when nodeShape is set to +// port-arcs. +portArcRadius: 6, + +// Spacing between the port arcs around the ports. +portArcSpacing: 3, + +// Position of the context toolbar realtive to the node. Some adjustment +// will be made to account for the width of the toolbar. +contextToolbarPosition: "topRight", + +// Display of vertical ellipsis to show context menu +ellipsisDisplay: true, +ellipsisPosition: "topLeft", +ellipsisWidth: 10, +ellipsisHeight: 22, +ellipsisPosX: 145, +ellipsisPosY: 9, +ellipsisHoverAreaPadding: 2 + +``` +### Positioning objects +If you have nodes of varying sizes or if you have enabled re-sizeable nodes, by setting the canvas config property `enableResizableNodes` to true, it is important to note the following. + +All coordinate positions for elements are based on one of nine anchor positions around the node: +``` + "topLeft", "topCenter", "topRight", + "middleLeft", "middleCenter", "middleRight", + "bottomLeft", "bottomCenter", "bottomRight". +``` + +The PosX and PosY properties for each element is an offset from the associated anchor position where PosX is the number of pixels **to the right** of the anchor position and PosY is a number of pixels **down from** the anchor position. Negative values can be provided to specify an offset **to the left** and **up from** the anchor position. The default anchor position for all elements is `topLeft`. By the way, the top left corner of the node is also the point that the node will be positioned at based on its `x_pos` and `y_pos` fields in the pipelineFlow document. + +For example, these settings: +``` + { + imagePosition: "middleCenter", + imagePosX: -10, + imagePosY: -10, + imageWidth: 20, + imageHeight: 20 + } +}; +``` +would position the image 10 pixels left and 10 pixels above the very center of the node. Since the image is 20 x 20 pixels this would position the center of the image at the center of the node. If you have enabled re-sizeable nodes, this would keep the image centrally positioned while the node is being resized by the user. + +Elements like the node image and vertical ellipsis are positioned based on the top left corner of that element. Text is positioned based on the top left corner of its containing `
`. + +The values for `bodyPath` and `selectionPath` must be [SVG path strings](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths) which describe how to draw the node body shape and its selection highlight shape. For example, the following would draw a triangular node body and a triangular selection outline 5 pixels away from it: + +```js + bodyPath: " M 0 0 L 70 35 0 70 Z", + selectionPath: "M -5 -5 L 75 35 -5 75 Z", +``` + +## Overriding the default node layout properties +There are a couple of ways to do this depending on your needs. First, if you just want to change the appearance of **all** nodes on your canvas you can specify the `enableNodeLayout` configuration parameter in the [main canvas configuration object](/2.1-Config-Objects#config-object). The properties from this object will replace any properties in the default set, which was chosen based on the settings of `enableNodeFormatType`. So you don't need to provide all of the properties; just the ones you want to replace. + +Let's say you want your nodes to be displayed as ellipses. You could provide the following settings in `enableNodeLayout` in the canvas config: +```js +const canvasConfig = { + enableNodeLayout: { + bodyPath: " M 0 30 Q 0 0 60 0 Q 120 0 120 30 Q 120 60 60 60 Q 0 60 0 30 Z", + selectionPath: "M -5 30 Q -5 -5 60 -5 Q 125 -5 125 30 Q 125 65 60 65 Q -5 65 -5 30 Z", + defaultNodeWidth: 120, + defaultNodeHeight: 60, + imageWidth: 30, + imageHeight: 30, + imagePosX: 20, + imagePosY: 10, + labelEditable: true, + labelPosX: 60, + labelPosY: 37, + labelWidth: 90, + labelHeight: 17, // Should match the font size specified in css + padding + ellipsisDisplay: true, + ellipsisPosX: 100, + ellipsisPosY: 20, + portPosY: 30 + } +}; +``` + +## Customizing individual nodes or categories of nodes +If you want each node, or category of nodes, to have a different layout based on some criteria you can use the second method for overriding the node layout properties. This uses the [layoutHandler callback method](/2.2-Common-Canvas-callbacks#layouthandler). When you specify this callback method to common canvas, it will be called for each node on the canvas, during initialization and, occasionally, at other times. + +The method should return a simple JavaScript object that contains any node layout properties you want to override from the defaults and the ones specified in the `enableNodeLayout` field in the canvas config. This is an important point: there are three levels of properties provided where each overrides the previous set: + +1. First we take the full default set of node layout properties based on the value for `enableNodeFormatType`. +2. Then we override these with the properties from the `enableNodeLayout` field in the canvas config object, if any are provided. +3. Finally we override the combined set with any properties from the object returned from the `layoutHandler` method if one is specified. + +The callback is provided with a `data` parameter which is the node object from the pipelineFlow so your code can examine the node object and return node layout properties as appropriate. + +Note: The `layoutHandler` callback is called while the canvas is being displayed, therefore it must return very quickly each time it is called otherwise your canvas display speed will be slowed down. + +Here is a simple example of a `layoutHandler` callback method which will override the width of the node based on the width of the main label for any node where the node's `op` field is set to `Sort`: +```js +layoutHandler(data) { + let customNodeLayout = {}; + if (data.op === "Sort") { + const labLen = data.label ? data.label.length : 0; + const width = (labLen * 9) + 30; // Allow 9 pixels for each character and a bit extra for padding + customNodeLayout = { + defaultNodeWidth: width // Override default width with calculated width + }; + } + return customNodeLayout; +``` +OK, it's not a very complicated example but hopefully you get the message :) + +In the test harness, you can see an example application that use the [layoutHandler callback method](/2.2-Common-Canvas-callbacks#layouthandler). In the test harness: + +1. Open the Common Canvas side panel (click the hamburger icon) +2. Select the `Explain` sample application + +You will see the nodes have different shapes and colors based on their type. +You can examine the [Explain sample app code](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/client/components/custom-canvases/explain/explain-canvas.jsx) to see how it works. This involves these parts: + +1. [This line](https://github.com/elyra-ai/canvas/blob/64af90b1f8a1179478f3ea32749681b851d897a4/canvas_modules/harness/src/client/components/custom-canvases/explain/explain-canvas.jsx#L36) sets the `enableNodeFormatType` in the canvas config to "Vertical". This will set all of the node layout properties to their defaults for "Vertical" nodes. +2. [This line](https://github.com/elyra-ai/canvas/blob/64af90b1f8a1179478f3ea32749681b851d897a4/canvas_modules/harness/src/client/components/custom-canvases/explain/explain-canvas.jsx#L37) will override the default node layout properties with a few different values which apply to all nodes. +3. [The layout handler](https://github.com/elyra-ai/canvas/blob/64af90b1f8a1179478f3ea32749681b851d897a4/canvas_modules/harness/src/client/components/custom-canvases/explain/explain-canvas.jsx#L145) will override layout properties on a node by node basis. It calls some utility functions to translate data retrieved from the node to the appropriate layout properties. The returned node layout properties contains an array of decorations that are used to display data values from the node. +4. [This line](https://github.com/elyra-ai/canvas/blob/64af90b1f8a1179478f3ea32749681b851d897a4/canvas_modules/harness/src/client/components/custom-canvases/explain/explain-canvas.jsx#L192) specifies the `layoutHandler` to the `` object. + +## Customizing node colors and styles + +The DOM elements that make up a node can be customized using CSS styles. This is done by assigning a class name to the group `` element that is the container for all the node elements. The class can be applied to the group object is a number of different ways: + +1. By specifying it in the `app_data.ui_data.class_name` field of the node in the pipeline flow document that is provided to common-canvas using `CanvasController.setPipelineFlow(pFlow)` +2. By specifying it using the following API methods: + * CanvasController.setNodeProperties(nodeId, properties, pipelineId) + * CanvasController.setNodesClassName(nodeIds, newClassName, pipelineId) +3. By specifying a class name in the `className` field of the node layout properties in the canvas config. Like this +``` +const canvasConfig = { + enableNodeLayout: { + className: "my-node-class" + } +}; +``` +4. By specifying a class name in the `className` field of the node layout properties returned from the `layoutHandler`. + + +You can see the [svg-canvas-d3.scss file](https://github.com/elyra-ai/canvas/blob/main/canvas_modules/common-canvas/src/common-canvas/svg-canvas-d3.scss) for full details about what elements in the node can be styled but here are a list of some basic parts of the node: + +| Element | DOM Element | Class Name | +|-----------------------|-------------------|------------------------------| +| Group | `` | d3-node-group | +| --> Body Shape | `` | d3-node-body-outline | +| --> Selection Outline | `` | d3-node-selection-highlight | +| --> Label Container | `` | d3-foreign-object-node-label | +| -----> Label | `
` | d3-node-label | + +So for example if you want the node body (the rectangle) to be colored orange you would provide a class name to the group element using one of the techniques mentioned above and then put this in you CSS: + +``` +.my-node-class .d3-node-body-outline { + fill: orange; +} +``` +Note: You can use the [`enableParentClass`](/2.1-Config-Objects#enableparentclass) canvas config field to make you CSS rulesets specific so your styles are picked up in preference to the common-canvas default styles. diff --git a/docs/2.8-Context-Menu-Wrapper-Documentation.md b/docs/2.8-Context-Menu-Wrapper-Documentation.md new file mode 100644 index 0000000000..a5c55ce237 --- /dev/null +++ b/docs/2.8-Context-Menu-Wrapper-Documentation.md @@ -0,0 +1,67 @@ +## Context Menu Wrapper + +Context Menu Wrapper is now deprecated. Carbon 11 supports a context menu component + +The context menu in common-canvas can be used in your application by importing the `ContextMenuWrapper` React component. Aside from providing a standard context menu to allow users to select different actions, this context menu also allows for configuration of submenus as a menu item, as well as a visual dividers. + +# Getting started with Context Menu +## Step 1: Import Context Menu Wrapper +To use Context Menu Wrapper in your React application you need to import the `ContextMenuWrapper` React component from the common-canvas library. It's recommended to use All Components if common-canvas is also being imported, otherwise use ContextMenuWrapper only option. + +**All Components** +```js + import {ContextMenuWrapper} from "@elyra/canvas"; +``` + +**ContextMenuWrapper only** +```js + import ContextMenuWrapper from "@elyra/canvas/dist/lib/context-menu"; +``` + +## Step 2: Pass in the correct props +* **contextMenuDef** `array` (required): an array of menu item objects consisting of action and label. You can also pass in a divider item. + +```js + const menuDef = [ + { action: ACTION.BUILD, label: "Build" }, + { action: ACTION.EXTEND, label: "Extend" }, + { action: ACTION.CLEAR, label: "Clear" }, + { divider: true }, + { action: ACTION.SCORE, label: "Score" }, + ]; + +``` + +* **containingDivId** `string` (required): the id of the element that the context menu will be absolutely positioned inside. typically, the page element is used. +* **contextMenuPos** `object` (required): the position of the context menu within the containing div. +```js + const menuPos = { x: 500 , y: 300 }; +``` + +* **contextMenuActionHandler** `func` (required): this handler is where context menu actions are defined. +```js + contextMenuActionHandler(action) { + switch (action) { + case "BUILD": + break; + case "EXTEND": + break; + default: + } + } +``` +* **closeContextMenu** `func` (required): this handler will be called when the context menu is closed. +* **stopPropagation** `bool` (optional): this is optional and only for very specific, uncommon use cases. When this flag is set, if a user clicks outside the context menu, the event will not bubble to parent elements, preventing parent event handlers from being called. + +## Example +```js + const contextMenuWrapper = ( + + ); +``` diff --git a/docs/2.9-External-Subflows-support.md b/docs/2.9-External-Subflows-support.md new file mode 100644 index 0000000000..45b62557f0 --- /dev/null +++ b/docs/2.9-External-Subflows-support.md @@ -0,0 +1,75 @@ +# Introduction + +The pipeline flow schema describes two ways of storing a sub-flow pipelines for a supernode: local or external. Local sub-flows are stored within the pipeline flow document whereas external pipelines are stored in a separate pipeline flow document (usually as the primary pipeline in that pipeline flow). The supernode that references an external pipeline contains a `url` property (in `.subflow_ref.url`) and a `pipeline ID` property (in `.subflow_ref.pipeline_id_ref`) to identify the external pipeline flow and the pipeline within it. + +Common-canvas supports external pipelines but the host application UI code needs to manage the storage and retrieval of any external pipeline flows. To do this the app UI code needs to: + +* Manage the storage of newly created external pipeline flows. +* Respond to calls from common-canvas to provide the external pipeline flow(s) when requested. +* Respond to call from common-canvas when a local pipeline is changed to external or an external is changed to local. + +Common-canvas supports lazy loading of external pipeline flows so they will only be requested from your code when the user performs some gesture that requires the pipeline (from within the external pipeline flow) to be displayed. + +## Creating an external sub-flow +When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true (the default) and, when a set of objects are selected from which a super node can be created, the default common-canvas context menu will include a `Create External Supernode` option. + +When the `Create External Supernode` option is clicked the `createSuperNodeExternal` action is executed. + +If your application doesn't use the default context menu you can define your own context menu (returned from `contextMenuHandler`) to contain an option which maps to the `createSuperNodeExternal` action. See the section on the [contextMenuHandler](/2.2-Common-Canvas-callbacks#contextmenuhandler) for details on how to do this. + +When the `createSuperNodeExternal` action is executed, the `beforeEditActionHandler` callback is called before the external sub-flow is created. The `beforeEditActionHandler` is called where the first parameter `data` has two properties `externalUrl` and `externalPipelineFlowId` which will both be set to empty string. Your code must set these to whatever values you want for the url and pipeline flow ID. The url will be assigned to the `subflow_ref.url` property of the supernode that is being created. The pipeline flow ID will be assigned to the newly created pipeline flow. + +Your code must return the `data` parameter from the `beforeEditActionHandler` callback if you want the action to proceed and create the sub-flow. If you need to do any asynchronous activity at this point see the documentation on the [beforeEditActionHanlder](/2.2-Common-Canvas-callbacks#beforeeditactionhandler) for details on how to do that. + + +When the sub-flow has been created common-canvas will call the `editActionHandler` callback with the `createSuperNodeExternal` action. In this callback you can, if you wish, retrieve the pipeline flow document that has been created internally in common-canvas using `CanvasController.getExternalPipelineFlow(url)`. Your code can then save it to your repository. Alternatively, you can wait until some later time, like perhaps during an auto-save, to retrieve and store the pipeline flow externally in your repository. + + +## Loading an external sub-flow +When the main pipeline flow, displayed by common-canvas, contains a super node that references an external sub-flow it will need to be loaded whenever the user performs a gesture that causes it to be displayed or processed in some way - for example displaying it 'in-place' or converting it from an external to a local supernode. An external sub-flow will also need to be loaded if the top-level pipeline being displayed has a supernode, that refers to an external pipeline, that is already expanded in-place in the saved pipeline flow JSON document being displayed. So, actions that can cause the external pipeline to be loaded are: + +* loadPipelineFlow +* expandSuperNodeInPlace +* displaySubPipeline +* convertSuperNodeExternalToLocal +* deconstructSuperNode + +When any of these actions are performed common-canvas will call the `beforeEditActionHandler` callback with the data parameter as the first parameter. The data object will have the following properties: + +* editType - The name of the action being performed. +* externalPipelineFlowLoad - This is a boolean which indicates whether the pipeline flow needs to be provided by your code. +* externalUrl - This is the string which identifies the external pipeline flow document. +* externalPipelineId - This is the ID of the pipeline being loaded +* externalPipelineFlow - If `externalPipelineFlowLoad` if true this will be undefined. Otherwise it will be contain the previously loaded external pipeline flow. + +You need to implement the `beforeEditActionHandler` so that: + +* when the actions above are being performed and externalPipelineFlowLoad is true, you retrieve the external pipeline flow from your repository +* you then assign it to the `externalPipelineFlow` property of the data object +* you then return the data object from the callback. + +Your code must return the `data` parameter from the `beforeEditActionHandler` callback if you want the action to proceed and load the external pipeline flow. If you need to do any asynchronous activity at this point see the documentation on the [beforeEditActionHanlder](/2.2-Common-Canvas-callbacks#beforeeditactionhandler) for details on how to do that. + +## Converting a local supernode to an external supernode +When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true, and a local supernode's is right clicked, the default common-canvas context menu will include a `Convert local to external` option. This will execute the `convertSuperNodeLocalToExternal` action. + +The `convertSuperNodeLocalToExternal` action is similar to the `createSuperNodeExternal` action in that a new external pipeline flow is being created. Consequently, you can follow the instructions in the [Creating an external sub-flow](/2.9-External-Subflows-support#creating-an-external-sub-flow) section for providing the appropriate properties of the `data` object in the `beforeEditActionHandler` and `editActionHandler` callbacks. + +## Converting an external supernode to a local supernode +When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true, and an external supernode's is right clicked, the default common-canvas context menu will include a `Convert external to local` option. This will execute the `convertSuperNodeExternalToLocal` action. + +The `convertSuperNodeExternalToLocal` action is similar to the `expandSuperNodeInPlace` action in that an external pipeline flow may need to be retrieved from your repository. Consequently, you can follow the instructions in the [Loading an external sub-flow](/2.9-External-Subflows-support#loading-an-external-sub-flow) section for providing the appropriate properties of the `data` object in the `beforeEditActionHandler` callback. + +## Deleting an external supernode/sub-flow +When the user deletes an external supernode/sub-flow the supernode will be removed from the canvas. You code does not need to do anything unless you want to also remove the external pipeline flow from your repository. + +## Clipboard support +When a supernode, that refers to an external pipeline, is cut/copied and pasted, the pasted supernode refers to the same external pipeline as the supernode that was cut or copied. This means that if an external supernode is copied to the clipboard and then pasted into the same canvas the result will be two supernodes that refer to the same external pipeline.   + +The same situation can occur if a supernode, that refers to an external pipeline, is in the palette and that node is dragged multiple times from the palette onto the canvas. + +## Manipulating objects in external pipelines using the Canvas Controller API +Objects (nodes, links comments, etc.) in an external pipeline can be updated by the host application calling the `CanvasController` API. However, such changes are only effective within common-canvas. It is the host application's responsibility to make sure these changes are persisted in the external pipeline flow document (if that is the behavior that is required). This can be done by the host application calling `CanvasController.getExternalPipelineFlow(url)` and then saving the returned document to the appropriate repository. + +## External pipelines in the Elyra Canvas Test Harness +The Test Harness supports external pipeline flows but will only persist any saved flows for the current session. (It just stores them in memory). You can examine the `beforeEditActionHandler` and `editActionHandler` in App.js in the test harness to see how it handles the different actions for managing external pipeline flows. \ No newline at end of file diff --git a/docs/3.0-Common-Properties-documentation.md b/docs/3.0-Common-Properties-documentation.md new file mode 100644 index 0000000000..cd8397502f --- /dev/null +++ b/docs/3.0-Common-Properties-documentation.md @@ -0,0 +1,315 @@ +## Introduction +Common properties displays controls to view and set property values. + +You can look at the harness/src/client/App.js file of this repo to see examples of code that uses the common properties component. + + +# Getting started with Common Properties programming + +_Note: There are two ways one can use the Common Properties tooling: Either by allowing the form to be built dynamically from a parameterDef JSON (which is comprised of the base property set, ui-hints, conditions, and resources), or by explicitly providing the dialog form for rendering (deprecated). The first approach is recommended as an easier and clearer interface_ + + This takes 3 easy steps: + +## Step 1 : Import +To use Common Properties in your React application you need to do the following. First import the CommonProperties React component from the common-canvas library. Elyra Canvas produces both esm and cjs outputs. By default esm will be used when webpack is used to build the consuming application. + +```js + import { CommonProperties } from "@elyra/canvas"; +``` +**Properties Only** + +To import only common properties functionality in `cjs` format use: + +```js + import { CommonProperties } from "@elyra/canvas/dist/lib/properties"; +``` + + +## Step 2 : Set the data +Next you'll need to populate propertiesInfo with: + +```js +propertiesInfo: { + parameterDef: this.parameterDef, // Parameter definitions/hints/conditions + appData: "{user-defined}", // User data returned in applyPropertyChanges [optional] + additionalComponents: "{components}", // Additional component(s) to display [optional] + messages: "[node_messages]", // Node messages array [optional] + expressionInfo: this.expressionInfo, // Information for expression builder [optional], + initialEditorSize: "{size}", // This value will override the value of editor_size in uiHints. This can have a value of "small", "medium", "large", or null [optional] + id: "{id}" // Unique parameter definition ID [Optional] +} +``` +[parameterDef schema and examples](https://github.com/elyra-ai/pipeline-schemas/tree/master/common-canvas/parameter-defs) +[3.1 Common Properties Parameter Definition](/3.1-Common-Properties-Parameter-Definition) +[`expressionInfo` schema and examples](https://github.com/elyra-ai/pipeline-schemas/tree/master) + +or... + +(Deprecated) +```js +propertiesInfo: { + formData: this.formData, + appData: "{user data returned back in applyPropertyChanges}", //optional + additionalComponents: "{additional control(s) to display}", //optional + messages: "[node_messages]", // Node messages array [optional] + expressionInfo: this.expressionInfo, // Information for expression builder [optional] + initialEditorSize: "{size}", // This value will override the value of editor_size in uiHints. This can have a value of "small", "medium", "large", or null [optional] + id: "{id}" // Unique parameter definition ID [Optional] +} +``` +formData [schema](https://github.com/elyra-ai/pipeline-schemas/tree/master/common-canvas/form) +form information [wiki](https://github.com/elyra-ai/wml-canvas-service/wiki/2.-Runtimes-And-Operators) + +The optional messages attribute can be used to set validation messages associated with a node. The format of the message objects is defined in [Pipelin Flow UI schema](https://github.com/elyra-ai/pipeline-schemas/blob/master/common-pipeline/pipeline-flow/pipeline-flow-ui-v1-schema.json) + +## Step 3 : Display the properties editor + +Finally you'll need to display the editor. Inside your render code, add the following: +```html +import { IntlProvider } from "react-intl"; +var i18nData = require("../intl/en.js"); + +var locale = "en"; +var messages = i18nData.messages; + + { + this.CommonProperties = instance; + }} + propertiesInfo={this.propertiesInfo} // required + propertiesConfig={this.propertiesConfig} // optional + callbacks={this.callbacks} // required + customPanels={[CustomSliderPanel, CustomTogglePanel]} //optional + customControls={[CustomSliderControl]} // optional + light // optional + /> + +``` +**Properties** + +- propertiesInfo `object`: See above +- propertiesConfig `object`: + - containerType `string`: type of container to display the properties, can be "Modal", "Tearsheet", or "Custom". default: `"Custom"` + - rightFlyout `boolean`: If set to true, groups will be displayed as an accordion. If false, groups are displayed as tabs. default: `false` + - applyOnBlur `boolean`: calls applyPropertyChanges when focus leave common-properties. default: `false` + - disableSaveOnRequiredErrors `boolean`: Disable the properties editor "save" button if there are required errors + - enableResize `boolean`: adds a button that allows the right-side fly-out editor to expand/collapse between small and medium sizes. default: `true` + - conditionReturnValueHandling `string`: used to determine how hidden or disabled control values are returned in applyPropertyChanges callback. Current options are "value" or "null". default: `"value"` + - buttonLabels `object`: + - primary `string`: Label to use for the primary button of the properties dialog + - secondary `string`: Label to use for the secondary button of the properties dialog + - heading `boolean`: show heading and heading icon in right-side fly-out panels. default: `false` + - schemaValidation `boolean`: If set to true, schema validation will be enabled when a parameter definition has been set in CommonProperties. Any errors found will be reported on the browser dev console. It is recommended you run with schema validation switched on while in development mode. + - applyPropertiesWithoutEdit `boolean`: When true, will always call `applyPropertyChanges` even if no changes were made. default: `false` + - maxLengthForMultiLineControls `number` - maximum characters allowed for multi-line string controls like textarea. default: 1024 + - maxLengthForSingleLineControls `number` - maximum characters allowed for single-line string controls like textfield. default: 128 + - convertValueDataTypes `boolean` - Default false. If set to true, currentParameter values whose data type does not match what is defined in the parameter definitions will be converted to the specified data type. + - trimSpaces `boolean` - Default true. If set to false, condition ops(`isEmpty`, `isNotEmpty`) and `required` fields are allowed to only contain spaces without triggering condition errors. + - showRequiredIndicator `boolean` - Default true to show `(required)` indicator. If set to false, show `(optional)` indicator next to properties label. + - showAlertsTab `boolean` - Default true to show "Alerts" tab whenever there are error or warning messages. If set to false, Alerts tab won't be displayed. + - returnValueFiltering `array` - Default []. When set this will filter out any values in the array in the parameters returned when `applyPropertyChanges` is call. Only primitive data types are currently supported. + - categoryView `string` - View categories in right-flyout. Can be `"accordions"` or `"tabs"`. default: `"accordions"`. +- callbacks object - See [callbacks](#callbacks) section for more details on each callback method. +- customPanels `array`: array of custom panels. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-panels) for more details. +- customControls `array`: array of custom controls. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-controls) for more details. +- customConditionOps `array`: array of custom condition operators. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-condition-operators) +- light `boolean`: Carbon controls in common-properties will use light mode. When the `light` option is disabled, the background color will be the same as the Carbon theme background. When the `light` option is enabled, the background color is set to $ui-01. Defaults to `true` + +**Internationalization and override of labels in CommonProperties** +The CommonProperties dialogs have a set of labels that can have customized and internationalized values. CommonProperties uses the react-intl package to provide internationalization of these labels. This requires the `IntlProvider` element to wrap the `CommonProperties` element. +You can look at the **harness/src/intl/en.js** file of this repo to see the list of labels and the default values. + +**Reference methods** +```js +/* +* @closeEditor (boolean) - determines if closePropertiesDialog is called or not +*/ +applyPropertiesEditing(closeEditor) +``` + + +### Using CommonProperties in CommonCanvas right-flyout panel + +[Common Canvas](/2.0-Common-Canvas-Documentation#step-3--display-the-canvas) has a right-flyout panel that can render a React object. It can be used to render Common Properties in a flyout panel. + +Create a CommonProperties object with containerType set to "Custom" and rightFlyout set to true. +```html + const rightFlyoutContent =(); +``` +Pass the CommonProperties object into CommonCanvas's rightFlyoutContent props. Also set the showRightFlyout boolean to tell CommonCanvas when to show the rightFlyout. +```html + +``` + +# Callbacks + +### applyPropertyChanges(propertySet, appData, additionalInfo, undoInfo, uiProperties) +Executes when the user clicks `OK` in the property dialog. This callback allows users to save the current property values. + +- propertySet: The set of current property values +- appData: (optional) application data that was passed in to `propertiesInfo` +- additionalInfo: Object with additional information returned: + - messages: (optional) An array of messages associated with the nodes current property values. + - title: The title of the properties editor +- undoInfo: Object with information needed to undo this apply: + - properties: Set of property values; + - messages: (optional) An array of messages associated with the nodes property values. + - uiProperties: (optional) Set of UI only properties values +- uiProperties: The set of UI only property values (optional) + +```js +applyPropertyChanges(propertySet, appData, additionalInfo, undoInfo, uiProperties) { + var data = { + propertySet: propertySet, + appData: appData, + additionalInfo: { + messages: messages, + title: title + } + }; +} +``` + +### closePropertiesDialog(closeSource) +Executes when user clicks `Save` or `Cancel` in the property editor dialog. This callback is used to control the visibility of the property editor dialog. `closeSource` identifies where this call was initiated from. It will equal "apply" if the user clicked on "Save" when no changes were made, or "cancel" if the user clicked on "Cancel" + +```js +closePropertiesDialog() { + this.setState({ showPropertiesDialog: false, propertiesInfo: {} }); +} +``` + +### propertyListener() +Executes when a user property values are updated. + +```js +propertyListener(data) { + +} +``` + +### controllerHandler() +Executes when the property controller is created. Returns the property controller. See [here](/3.6-Common-Properties-Controller) for APIs + +```js +controllerHandler(propertyController) { + +} +``` + +### actionHandler() +Called whenever an action is ran. `id` and `data` come from uihints and appData is passed in with propertiesInfo. + +```js +actionHandler(id, appData, data) { + +} +``` + +### buttonHandler() +Called when the edit button is clicked on in a `readonlyTable` control, or if a custom table button is clicked. The callback provides the following data: + +- data: an object that consists of + - type: of button the click was invoked from. + - `edit` is returned from the edit button click of a `readonlyTable` control. + - `custom_button` is returned from the custom button click of a complex type control. + - propertyId: of the control that was clicked. + - buttonId: of the button that was clicked from a custom table button. + +```js +buttonHandler(data) { + +} +``` + +### buttonIconHandler() +Called when there is a `buttons` uihints set in the `complex_type_info` section of the parameter definition. This buttonIconHandler expects a Carbon Icon jsx object as the return value from the callback. This is used to display the Carbon icon in the custom table button. The buttonIconHandler provides the following data: + +- data: an object that consists of + - type: `customButtonIcon` + - propertyId: of the control that was clicked. + - buttonId: of the button that was clicked from a custom table button. + - carbonIcon: The name of the Carbon icon specified in the uihints. The corresponding jsx object is expected to be returned in the callback. + +```js +buttonIconHandler(data, callbackIcon) { + if (data.type === "customButtonIcon" && data.carbonIcon === "Edit32") { + callbackIcon(); + } +} +``` + +### helpClickHandler() +Executes when user clicks the help icon in the property editor dialog. The callback provides the following data: + +- nodeTypeId: in case of parameterDef, id property of uihints; in case formData, the componentId. +- helpData: Optional helpData specified in paramDef/formData (see below). +- appData: Optional application data that was passed in to `propertiesInfo` +```js +helpClickHandler(nodeTypeId, helpData, appData) { + +} +``` +To control whether a node shows the help icon in the right fly-out, a help object with optional helpData needs to be provided in the paramDef or formData: +- paramDef: Provide help object in operator's uihints. If help object exists, the icon will be shown. Optionally, provide a helpData object within the help object, which will be passed in the helpClickHandler callback. +https://github.com/elyra-ai/pipeline-schemas/blob/master/common-pipeline/operators/uihints-v2-schema.json#L64 +- formData: add help object to form definition. The +https://github.com/elyra-ai/pipeline-schemas/blob/master/common-canvas/form/form-v2-schema.json#L51 + +If no help object is found, no help link will be shown. + + +### titleChangeHandler() +Called on properties title change. This callback can be used to validate the new title and return warning or error message if the new title is invalid. This callback is optional. + +In case of error or warning, titleChangeHandler should call callbackFunction with an object having type and message. If the new title is valid, no need to call the callbackFunction. +```js +titleChangeHandler(title, callbackFunction) { + // If Title is valid. No need to send anything in callbackFunction + if (title.length > 15) { + callbackFunction({ + type: "error", + message: "Only 15 characters are allowed in title." + }); + } +} +``` +where: + +- type (string, required): This must be one of two values: "warning" or "error". +- message(string, required): Error or warning message. There is no restriction on length of the message. + + + +### propertiesActionLabelHandler() +```js +propertiesActionLabelHandler() +``` +This is an optional handler you don't need to implement anything for it unless you want to. This callback allows your code to override the default tooltip text for the `Undo` and `Redo` buttons. +The `propertiesActionLabelHandler` callback, when provided, is called for the save properties action that is performed in common-properties. This callback should return a string or null. If a string is returned it will be shown in the tooltip for the `Undo` button in the toolbar preceded by "Undo:" and the string will also appear in the tooltip for the `Redo` button (when appropriate) preceded by "Redo:". If null is returned, common-properties will display the default text `Save {node_name} node properties` for the Undo and Redo buttons. + +### tooltipLinkHandler() +Optional callback used for adding a link in properties tooltips. link object must be defined under description in uiHints parameter info. Common-properties internally pass the link object to tooltipLinkHandler callback. +This callback must return an object having url and label. + +```js +tooltipLinkHandler(link) { + return { url: "https://www.google.com/", label: "More info" }; +} +``` + diff --git a/docs/3.1-Common-Properties-Parameter-Definition.md b/docs/3.1-Common-Properties-Parameter-Definition.md new file mode 100644 index 0000000000..31ec395383 --- /dev/null +++ b/docs/3.1-Common-Properties-Parameter-Definition.md @@ -0,0 +1,261 @@ +# Parameter Definitions +The parameter definition json files is an easy way to provide input for controlling the common properties dialog. It consists of information that is available in the operator json combined with UI hints, information on data sets, and resources. + +The parameter definition has a defined schema and set of examples located here: +[schema and examples](https://github.com/elyra-ai/wdp-pipeline-schemas/tree/master/common-canvas/parameter-defs) + +The parameter definition consists of eight sections. + +## Title Definition + +The title of the properties editor. If `editable` is set to true (default), the title can be edited. If set to false, the title will be readonly. + +```js +"titleDefinition": { + "title": "Properties Title", + "editable": true + } +``` + +## Current Parameters + +A list of input parameters and initial values upon input. The list is a set of key/value pairs with the key being the field name and the value is the initial value. + +Example +```js +"current_parameters": { + "targetField": [], + "inputFieldList": [], + "elasticNetParam": 0.0, + "fitIntercept": false, + "maxIter": 75, + "regParam": 0.1, + "standardization": true, + "threshold": 0.5, + "tol": 0.0000010 + } +``` + +## Parameter Definitions +The list of parameters definitions for this property dialog. The list contains the name of the parameter, the data type of the parameter, the role and the default value. The information provided is as needed by the backend engine, i.e. the parameter name should be the name of the parameter that is expected for the backend engine. + +The list of parameter definitions has the following attributes. +* `id` (*string*) **Required** Parameter identifier as consumed by the backend engine. +* `default` (*any*) The default value of the parameter. +* `enum` (*array[string]*) A restricted list of string values that are valid for the field. +* `type` (*string*) Parameter type as consumed by the backend engine. +* `role` (*string*) Parameter role, which is an optional specialization of the type. +* `required` (*boolean*) Indication whether parameter is required or optional. + + +Parameter types have one of a fixed set of basic types. These are: + +* `integer` +* `double` +* `string` +* `date` +* `time` +* `timestamp` +* `custom` + +These can be used as maps or arrays e.g.: + + array[]: a sequence or list of values + +Parameter roles defined by the role attribute can be one of: + +* `expression`: an expression assumed to be in the expression language for the run time +* `column`: value represents one or more columns from the data model visible to this operator +* `new_column`: value represents the name of a new column to be added to the data model and must therefore not match an existing column and conform to existing syntactic restrictions. + + +Example +```js +"parameters": [ + { + "id":"targetField", + "type":"string", + "default":"", + "role":"column" + }, + { + "id":"inputFieldList", + "type":"array[string]", + "default":[], + "role":"column" + }, + { + "id": "impurity", + "enum": [ + "gini", + "entropy" + ], + "default": "gini" + }, + { + "id":"elasticNetParam", + "type":"double", + "default":0.0 + } +] +``` +## UI-only Parameters +A list of input parameters and initial values upon input. This set of parameters are separated from the backend parameters (current parameters). The idea is that these parameters are not passed into the backend engine by the common properties consumer. + +Example +```js +"current_ui_parameters": { + "databaseResource": true, + "tol": 0.0000010 + } +``` + +UI-only parameters require information about the parameters same as the parameter definition information used for the backend parameters. The UI-only parameter definition information is stored in the UI-hints section in the sub-section named `ui_parameters`. A description of the UI hints specifications can be found here: [3.2 Common Properties UI Hints](/3.2-Common-Properties--UI-Hints) + + +UI-only properties are returned to the consuming application via a separate parameter on the applyPropertiesChanges callback. See the `Callbacks` section of [3.1 Common Properties Documentation section.](/3.0-Common-Properties-documentation) + + +## Complex Types +The complex types section is an array of + +The complex types have the following attributes. +* `id` (*string*) **Required** Identifier of complex type, can be referenced in other places. +* `type` (*string*) If `object` is specified, common properties will return the values as an array of objects consisting of key value pairs. This defaults to `array`. +* `key_definition` (*object*) A parameter definition attribute on the key parameter field. +* `parameters` (*object*) **Required** List of parameters fields. Each parameter can be defined as a parameter definition attribute or a complex type attribute. + + +Example of complex types +```js +"complex_types": [ + { + "id": "SortEntry", + "type": "object", + "key_definition": { + "id": "field", + "type": "string", + "role": "column", + "default": "" + }, + "parameters": [ + { + "id": "sort_order", + "enum": [ + "Ascending", + "Descending" + ], + "default": "Ascending" + } + ] + } + ] +``` + +### A Note on Parameters and Complex Types: +Note that both parameter and complex type definitions are in the exact same format as defined in the operator schema. Therefore the contents of operator JSON files can be used for these two sections. + + +## UI Hints +A set of specifications for controlling the layout and flow of the common properties. A description of the UI hints specifications can be found here: [3.2 Common Properties UI Hints](/3.2-Common-Properties--UI-Hints) + +## Conditions +A set of specifications for controlling validation checking of parameters during the common properties dialog. A description of the Conditions specifications can be found here: +[3.4 Common Properties Conditions](/3.4-Common-Properties-Conditions) + +## Data Set Metadata +The data set metadata is an array of datarecord-metadata objects as defined in the datarecord-metadata JSON schema. Each datarecord-metadata object contains and array of fields that provide column information on the input data set. [schema and examples](https://github.com/elyra-ai/pipeline-schemas/tree/main/common-pipeline/datarecord-metadata) + +The fields have the following attributes. +* `name` (*string*) **Required** Field name. Must be unique within the dataset. +* `type` (*string*) **Required** Field type. Can be a primitive type (string, integer, double, date, time, timestamp), or a vector, map, or struct containing those types. Required. +* `nullable` (*boolean*) Indicates whether or not one can place null values into the field. Default: False. +* `metadata` (*object*) A set of additional metadata attributes. + +The additional metadata attributes are as follows. +* `description` (*string*) A description of the field. +* `measure` (*string*) The field measurement type. The value can be one of the following. `range, discrete, flag, set, ordered-set, typeless, collection, geospatial, default` +* `role` (*string*) Field role for modeling. The value can be one of the following. +`input, +target, +both, +none, +partition, +split, +frequency, +record-id` +* `max_string_length` (*number*) Maximum character length for string fields. Length is unlimited when not present. +* `values` (*array[string]*) Array of unique categorical values for the column. +* `ranges` (*object*) Minimum and maximum discovered values for scalar data. + +Example +```js +"dataset_metadata": [ + { + "name": "Schema-1", + "fields": [ + { + "name": "Age", + "type": "integer", + "metadata": { + "description": "", + "measure": "range", + "role": "input" + } + }, + { + "name": "Sex", + "type": "string", + "metadata": { + "description": "", + "measure": "discrete", + "role": "input" + } + }, + { + "name": "BP", + "type": "string", + "metadata": { + "description": "", + "measure": "discrete", + "role": "input" + } + } + ] + }, + { + "name": "Schema-2", + "fields": [ + { + "name": "Birthdate", + "type": "date", + "metadata": { + "description": "Date of birth", + "measure": "range", + "role": "input" + } + } + ] + } +] + +``` + +## Resources +This is a map of string resources. + +Example: +```js +"resources":{ + "org.apache.spark.ml.classification.DecisionTreeClassifier.label":"Random Forest Classifier", + "org.apache.spark.ml.classification.DecisionTreeClassifier.desc":"Fitted Random Forest Classification Model", + "inputFieldList.label":"Input columns", + "inputFieldList.desc":"Select one or more input columns", + "targetField.label":"Target column", + "targetField.desc":"Select a target column", + "max_depth_not_valid":"The max depth parameter must be greater than or equal to zero", + "max_iter_not_valid": "The max iterations parameter must be greater than or equal to zero", + "min_instances_per_node_not_valid": "The minimum instances per node value must be >= 1", + "subsampling_rate_not_valid": "The subsampling rate value must be > 0 and <= 1" +} +``` \ No newline at end of file diff --git a/docs/3.2-Common-Properties-UI-Hints.md b/docs/3.2-Common-Properties-UI-Hints.md new file mode 100644 index 0000000000..014d2a617e --- /dev/null +++ b/docs/3.2-Common-Properties-UI-Hints.md @@ -0,0 +1,348 @@ +# UI Hints +UI hints is a section of the property definition json and contains specifications to assist in the presentation and flow of the property dialog. The specifications indicate which controls to use to display and gather input on the fields. +[uihints schema](https://github.com/elyra-ai/wdp-pipeline-schemas/blob/master/common-pipeline/operators/uihints-v1-schema.json) + +The UI Hints section consists a set of simple and complex attributes. + +**The simple attributes are:** + +* `id` (*string*) Dialog id. +* `label` (*object*) External name of dialog. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) +* `description` (*object*) Description of dialog. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) +* `editor_size` (*string*) The width of the properties editor panel. This can have a value of `"small"`, `"medium"`, `"large"` or `"max"`. The default is `"small"`. + - When `"small"` is specified the properties panel is displayed with a default width of 320px and with a resize button that allows the panel to be increased in size up to the `"medium"` size which is 480px. + - When `"medium"` is specified the properties panel has a width of 480px and with a resize button that allows the panel to be increased in size up to the `"large"` size which is 640px. + - When `"large"` is specified the properties panel has a width of 640px and with a resize button that allows the panel to be increased in size up to the `"max"` size which is 900px. + - When `"max"` is specified the properties panel has a width of 900px and no resize button is displayed. +* `pixel_width` (*object*) This optional property gives finer control over the minimum and maximum sizes of the properties editor panel. If this is omitted the properties editor width is controlled by the `editor_size` property. `pixel_width` is an object with two properties `min` and `max` which are both numbers. + - If `min` is specified it overrides the default size of the shrunken panel and `max` is based on the `editor_size` value. + - If `max` is specified it overrides the default size of the expanded panel and `min` is based on the `editor_size` value. + - If `editor_size` is set to `"large"` only the `max` value will be used to specify the size of the panel and no resize button will be displayed. + + A warning will be displayed in the console if you specify an invalid value for either `min` or `max` such as making `min` greater than `max`. + +Example of the simple attributes: +```js +"uihints": { + "id":"org.apache.spark.ml.ibm.transformers.Distinct", + "icon": "images/transformationspark.svg", + "label": { + "default": "Distinct" + }, + "editor_size": "medium", + "pixel_width": { + "min": 400, + "max": 800 + }, + "description": { + "default": "Remove rows to leave only rows with distinct combinations of rows" +} +``` + + + +**The complex attributes of the UI hints section are:** +## Group-info + +Group info attributes. + +* `id` (*string*) **Required** Panel id +* `type` (*string*) The group type to be displayed. see Group/Panel Controls in [3.3 Common Properties Controls](/3.3-Common-Properties-Controls). +* `depends_on_ref` (*string*) Property name this group depends upon. Valid for panelSelector groups only. +* `label` (*object*) Group label. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) +* `description` (*object*) Group description. Only used with `textPanel` and `actionPanel`. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) + + `link` (object) Optional link in the description. [tooltipLinkHandler callback](/3.0-Common-Properties-documentation#tooltiplinkhandler) must be defined whenever link object is added in uiHints.. + + `id` (string) Required unique link id. + + `data` (object) Data passed to the tooltipLinkHandler callback. +* `parameter_refs` (*array[string]*) List of parameter to be displayed. +* `action_refs` (*array[string]*) List of action to be displayed. Used with `actionPanel` only. +* `group_info` (*object*) List of additional group information. +* `data` (*any*) Returned in custom panel constructor without any changes. +* `insert_panels` (*boolean*) Indicates whether panels, contained with a panelSelector, should be inserted between the radio buttons of a radio button set indicated by the depends_on_ref parameter. +* `nested_panel` (*boolean*) Indicate whether panel should be nested. Nested panels are indented by 16px from the left and display left border. Default is false. +* `class_name` (*string*) Optional classname for this group +* `open` (*boolean*) Optional used to determine if a panel should be open or not by default. Used with `twistyPanel` only. Default is `false`. + + +Example group info section: +```js +"group_info": [ + { + "id": "settings", + "label": { + "default": "Settings" + }, + "type": "columnSelection", + "parameter_refs": [ + "keys" + ] + } + ] +``` + +## UI-only Parameters +UI-only parameters require information about the parameters same as the parameter definition information used for the backend parameters. The UI-only parameter definition information is stored in the UI-hints section in the sub-section named `ui_parameters`. The format of the information in the `ui_parameters` sub-section is documented in the `Parameter Definition` section of [Common Properties Parameter Definition](/3.1-Common-Properties-Parameter-Definition/). + +Example +```js +"ui_parameters": [ + { + "id":"databaseResource", + "type":"boolean", + "default":true + }, + { + "id":"toi", + "type":"double", + "default":0.0 + } +] +``` + +The UI-only parameters need to be added to other UI Hints sections (for example `Group Info` and canbe refered to by the `parameter_ref` field just like backend parameters. + +## Parameter Info +The parameter info section contains the list of parameters to gather values on through the property dialogs and UI hints about each parameter. The UI hints provide information to facilitate the UI controls used to display the parameter in the property dialogs. + +Parameter info attributes. + +* `parameter_ref` (*string*) **Required** Parameter name. +* `label` (*object*) External name for parameter. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) +* `label_visible` (*boolean*) Determines whether to display the label for a control. +* `description` (*object*) Description of parameter with optional placement context. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + `placement` (*string*) Placement context for the text. Valid values are `as_tooltip, on_panel`. + + `link` (*object*) Optional link in the description. [tooltipLinkHandler callback](/3.0-Common-Properties-documentation#tooltiplinkhandler) must be defined whenever link object is added in uiHints.. + + `id` (*string*) Required unique link id. + + `data` (*object*) Data passed to the tooltipLinkHandler callback. +* `control` (*string*) Which control to use. see Parameter Controls in [3.3 Common Properties Controls](/3.3-Common-Properties-Controls). +* `increment` (*number*) Determines the increment/decrement value for the spinner control only. The default value is `1`. +* `orientation` (*string*) Determines how the control is displayed. Valid values are `vertical, horizontal`. +* `width` (*number*) Column width for tables. The widths provided for table columns are used to calculate relative widths for each table column. So for example a 3 column table with widths of 20, 30, and 50 would use 20%, 30%, and 50% of the overall table width, respectively. +* `char_limit` (*number*) Limits the number of characters a user can enter into the control for string parameters only. +* `display_chars` (*number*) This has been deprecated and is subject to removal. Limits the number of characters displayed for a text field in a column in a table. The text will have an ellipsis appended at this limit. Defaults to 64 characters. +* `separator` (*string*) Determines where to put a separator relative to the current control. Valid values are ` after, before`. +* `visible` (*boolean*) Determines whether to display control in a table cell. Used in complex types only. +* `place_holder_text` (*object*) Text hint for the user displayed input controls. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) +* `resource_key` (*string*) Used as a key for enum value labels in the resources section of property definition. +* `edit_style` (*string*) Editing style of elements in a table. Valid values are `subpanel, inline, on_panel`. +* `value_icons` (*array[string]*) For enumerated types, this defines the set of icons for the valid values. The ordering must be consistent with the order in the parameter enum attribute. +* `filterable` (*boolean*) Determines if this column values can be filtered so that only rows that match the filter in column values are shown in the table. Applies to complex parameters only. +* `sortable` (*boolean*) Determines if this column values can be sorted into ascending/descending order in a table. Applies to complex parameters only. +* `number_generator` (*object*) Describes a number generator button beside numeric control. The 'label' element is a standard resource item, and the 'range' element contains 'min' and 'max' attributes to constrain the range of generated numbers. +* `dm_default` (*string*) Data record metadata field to be used for default values in table cell columns. Typically this is used with parameters in complex structures in which the key field is a column name. Valid values are `type`, `description`, `measure`, and `modeling_role`. +* `dm_image` (*string*) This can be set to display an icon of the corresponding dm type in the `role`:`column` field of a table. Valid values are `measure`, `type`, `none` +* `summary` (*boolean*) Determines if parameter should be shown in the summary when using a `summaryPanel`. +* `text_before` (*object*) Text to be displayed before the control + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + `type` (*string*) Adds a icon and additional formatting to the text. Only `info` is support at this time. + + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) +* `text_after` (*object*) Text to be displayed after the control + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + `type` (*string*) Adds a icon and additional formatting to the text. Only `info` is support at this time. + + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) +* `custom_control_id` (*string*) Id that is used to determine which custom control to use when `control=custom` +* `data` (*any*) Returned in custom control constructor without any changes. +* `rows` (*integer*) Number of rows to show in a table before scrolling starts. If one table in a panel is set to -1, that table will use the remaining available vertical space, down to a minimum of 2 rows. Used in expression and code controls to determine the number of rows to show for those controls. +* `moveable_rows` (*boolean*) Determines if rows can be moved up or down in a table or array of strings. +* `action_ref` (*string*) An action to be displayed. +* `date_format` (*string*) A format string such as YYYY-MM-DD which describes the display and entry format for a date field. +* `time_format` (*string*) A format string such as HH:mm:ss which describes the display and entry format for a time field. +* `custom_value_allowed` (*boolean*) Determines if a dropdown, outside of a table, can allow a custom value to be entered. +* `class_name` (*string*) Optional classname for this parameter +* `resizable` (*boolean*) Determines if this column can be resized in a table. When a column is resized, width of all the columns to the right of resized column is adjusted. Applies to structure parameters only. Default is `false`. + +Example parameter info section: +```js + "parameter_info": [ + { + "parameter_ref": "keys", + "label": { + "resource_key": "sort.keys.label" + }, + "description": { + "resource_key": "sort.keys.desc", + "placement": "on_panel" + }, + "rows": -1 + } + ] +``` + +## Complex Type Info +The complex_type_info section defines complex data types. This section is needed if in the `parameters` section of the parameter definition, one of the parameters has a type that is not the base type (i.e. an array or map of base types). The type of control used for this definition depends on the group info type value. + +Complex Type info attributes. + +* `complex_type_ref` (*string*) **Required** Name of complex type, can be referenced in other places. +* `key_definition` (*string*) A set of parameter info attributes about the key parameter. +* `label` (*object*) External name of subpanel. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) +* `parameters` (*object*) **Required** List of parameters that are part of this complex parameter. This parameter can either have a set of parameter_info attributes or other nested complex_type_info attributes. +* `header` (*boolean*) If `true` then the table has a header row with column names. Defaults to `true`. +* `add_remove_rows` (*boolean*) If `true` then the table can have rows added and removed. Defaults to `true`. +* `include_all_fields` (*boolean*) When `true` and `add_remove_rows` is `false`, ensures that all fields are included in the control at all times. +* `row_selection` (*string enum*) How many rows in a table can be selected at a time. + + `single`: only one row at a time is able to be selected. + + `multiple`: multiple rows at a time are able to be selected. + + `multiple-edit`: select multiple rows and allow the editing of column values of all selected rows. +* `buttons` (*array*) An array of objects that define custom buttons to be displayed in this complex structure, overriding any default buttons. Each button object contains the following properties: + + `id` (*string*) **Required**: Unique identifier used to identify the button in the callback function. + + `label` (*object*): Button label to display. If an icon is specified as well, the icon will be shown to the right of the label. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + `description` (*object*): Tooltip text to display when the button is hovered. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + `icon` (*string*): URL to .svg image to display. + + `carbon_icon` (*string*): Host provided name of Carbon icon to display. A callback function is required for the host application to return the jsx icon object imported from @carbon/icons-react library. + + `enabled` (*boolean*): Button will be enabled if true, disabled if false. + + `divider` (*string enum*): Display a divider before or after this button. Defaults to `after` + + `before` Display divider before this button + + `after` Display divider after this button + +Example complex_type_info section: +```js + "complex_type_info": [ + { + "complex_type_ref": "SortEntry", + "row_selection": "multiple", + "moveable_rows": true, + "add_remove_rows": false, + "include_all_fields": true, + "key_definition": { + "parameter_ref": "field", + "width": 28, + "label": { + "resource_key": "SortEntry.field.label" + } + }, + "parameters": [ + { + "parameter_ref": "sort_order", + "width": 16, + "resource_key": "SortEntry.sort_order", + "label": { + "resource_key": "SortEntry.sort_order.label" + }, + "control": "toggletext", + "value_icons": [ + "/images/up-triangle.svg", + "/images/down-triangle.svg" + ] + } + ] + }, + { + "complex_type_ref": "FieldStorageEntry", + "key_definition": { + "parameter_ref": "field", + "label": { + "default": "", + "resource_key": "FieldStorageEntry.field" + }, + "width": 26, + "sortable": true, + "filterable": true + }, + "parameters": [ + { + "parameter_ref": "override", + "label": { + "default": "", + "resource_key": "FieldStorageEntry.override" + }, + "width": 16, + "edit_style": "inline", + "sortable": true + }, + { + "parameter_ref": "storage", + "label": { + "default": "", + "resource_key": "FieldStorageEntry.storage" + }, + "width": 26, + "edit_style": "inline", + "dm_default": "type" + } + ], + "buttons": [ + { + "id": "icon_button_1", + "carbon_icon": "Edit32", + "label": { + "resource_key": "table.somekey.label" + }, + "description": { + "default": "This renders a button that has a label and Carbon icon to the right of the label. + }, + "enabled": true + } + ] + } + ] +``` +## Action Info +The action_info section defines an action. Actions are used to callback to the application to perform an operation. + +Action info attributes. + +* `id` (*string*) **Required** Id of the action. +* `label` (*object*) **Required** External name of action. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) +* `control` (*string*) **Required** The type of action. Currently `button` and `image` are supported. +* `class_name` (*string*) Optional classname for this action +* `image` (*object*) Properties associate with an `image` action. + * `url` (*string*) Location of the image to display. + * `placement` (*string*) Placement of image relative to a property. Values are `right` or `left`. + * `size` (*object*) Pixel size of the image. + * `height` (*number*) Image height in pixels. + * `width` (*number*) Image width in pixels. + * `tooltip_direction` (*string*) Set tooltip direction for action image. Values are `right`, `left`, `top`, or `bottom`. Default is `bottom`. +* `button` (*object*) Properties associated with action button. + * `kind` (*string*) Button kind. Values are same as carbon button kind values. Default is `tertiary`. + * `size` (*string*) Button size. Values are sm, md, lg, xl. Default is `sm`. +* `data` (*any*) Returned back in action callback. + +```js +{ + "id": "increment", + "label": { + "default": "Increment" + }, + "control": "button", + "data": { + "parameter_ref": "number" + } +} +``` + +## Resource Definition +Used for user facing text. Allows for default values if no translations are provided. + +* `default` (*string*) Default value if `resource_key` not defined. +* `resource_key` (*string*) Used as a key for enum value labels in the resources section of property definition. + +## Dynamic text expressions +Used to dynamically set text based on a parameter value change. If parameter id is used then then current value for that parameter will be passed into the function. + +* `percent(, )` Return the percent of the 1st parameter. The optional 2nd parameter determines the number of decimal places. +* `sum(, , ...)` Returns the sum of all parameters + +```js +{ + "parameter_ref": "numberfield", + "label": { + "default": "Number" + }, + "text_after": { + "default": "Sum: ${sum(numberfield, 2)} with (numberfield, 2, numberfield). Percent: ${percent(numberfield,2)}" + } +} +``` diff --git a/docs/3.3-Common-Properties-Controls.md b/docs/3.3-Common-Properties-Controls.md new file mode 100644 index 0000000000..37123d60f7 --- /dev/null +++ b/docs/3.3-Common-Properties-Controls.md @@ -0,0 +1,111 @@ +# Common Properties Element Types +The editor determines the most appropriate control and panel type for each parameter based on the context (parameter type, role, group type, etc.). Although an author can specify a desired control for a given parameter via its `uihints`, this should be used sparingly and carefully - specifying an inappropriate control for a parameter will lead to undefined behavior. + +A visual documentation containing examples of the following group/panels and control types are available at https://wdp-common-canvas-dev.stage1.mybluemix.net/#/properties. + +## Group/Panel Controls +Controls are grouped and arranged on panels and sub-panels within the "group_info" section of operator uihints. Some panels appear as tab controls, others are for managing shared dataset metadata, while still others contain nested sub-panels. + +### Group Types +* `controls` A general panel type containing parameter controls. +* `tabs` A tabbed control, each tab containing sub-panels and controls. +* `subTabs` A horizontal sub-tabbed control, each tab containing sub-panels and controls. If displayed within a Tearsheet container, subtabs will be displayed vertically. +* `panels` A panel type that contains sub-panels. +* `panelSelector` A panel containing sub-panels that are shown or hidden based upon a controlling radio selection. +* `columnSelection` A panel type containing field-selection controls that share a common set of fields. +* `customPanel` A custom panel for displaying user defined control. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-panels) for more details. +* `summaryPanel` A panel used in the flyout editor that will provide a link to open a wide flyout that can contain panels and parameter. +* `actionPanel` A panel used for containing action controls. +* `textPanel` A panel used to display static label and/or description. +* `twistyPanel` A panel used to display a panel title that expands to the panel content when clicked. +* `columnPanel` A panel used to display children side by side. +* `tearsheetPanel` A tearsheet panel. The panel can be opened/closed using the propertyController methods `setActiveTearsheet(groupId)` and `clearActiveTearsheet()` + +## Parameter Controls +The following controls are supported in the Common Properties editor. Control types are intended for use with particular parameter types: + +### Control Types +* `readonly` A read only text field. Used for fields users shouldn't edit. +* `hidden` A control that has no UI to display. +* `textfield` A single line editable text field. +* `passwordfield` A masked single line text field with tooltip. The tooltip text can be customized by setting `[parameter_id].passwordHide.tooltip` and `[parameter_id].passwordShow.tooltip` in resources section. +* `textarea` A multi-line text area. +* `list` A single column table for editing a list of values. +* `expression` An expression editing field that provides language specific syntax highlighting and text auto complete. An expression builder addon is available with the expression control. You must provide the `expressionInfo` field for the `propertiesInfo` config. See [3.0 Common Properties Documentation](/3.0-Common-Properties-documentation) for more details. To maximize in a tearsheet add this attribute and define a `tearsheetPanel` in `group_info`. + ``` + "data": { + "tearsheet_ref": "" + } + ``` +* `code` An code editing field that provides language specific syntax highlighting and text auto complete. To maximize in a tearsheet add this attribute and define a `tearsheetPanel` in `group_info`. + ``` + "data": { + "tearsheet_ref": "" + } + ``` +* `numberfield` A numeric text field. Number fields can also optionally display a random number generator button beside the control. See the uihints schema for details. +* `datefield` A date input control whose date format tokens follow [date-fns](https://date-fns.org/v2.29.3/docs/format). Defaults to `yyyy-mm-dd` +* `timefield` A time input control whose time format tokens follow [date-fns](https://date-fns.org/v2.29.3/docs/format). Defautls to `H:m:s` +* `datepicker` A date input control with calendar picker whose date format tokens follow [Flatpickr](https://flatpickr.js.org/formatting/#date-formatting-tokens). Defaults to `Y-m-d`. Helper text can be included by adding `[parameter_id].helper` in the resources section. +* `datepickerRange` A date input control with calendar picker for a range of dates. This follow the same rules as the `datepicker` control. Start and end labels defaults to `Start` and `End` respectively. Start, end, and helper labels can be customized by adding the following in the resources section: + ``` + "resources": { + [parameter_id].range.start.label: "Custom start label", + [parameter_id].range.start.desc: "Custom start description that will appear as tooltip next to the label", + [parameter_id].range.start.helper: "Custom start helper that will appear as text below the input", + [parameter_id].range.end.label: "Custom end label", + [parameter_id].range.end.desc: "Custom end description that will appear as tooltip next to the label", + [parameter_id].range.end.helper: "Custom end helper that will appear as text below the input"` + } + ``` +* `spinner` A standard spinner control to increment/decrement the number value. +* `checkbox` A standard checkbox control. +* `radioset` A radio set where a parameter value is selected from a small range of options. See the Conditions wiki page for special radio button disabling options. +* `checkboxset` A checkbox set for list type parameters with enumerated options where the count is less than 5. +* `oneofselect` A standard dropdown list control. +* `multiselect` A standard dropdown list control that allows for multiple selection. +* `someofselect` A multi-selection control for enumerated list parameters where the count is greater than 4. +* `selectcolumn` A dropdown list control that selects from available column names. When dropdown list is empty, `selectcolumn` control will display default placeholder text `"..."`. This placeholder text can be customized by setting `[parameter_id].emptyList.placeholder` in resources section. When custom empty list placeholder text is provided, common-properties will disable the empty list control. +* `selectcolumns` A multi-select control for column selections. +* `selectschema` A dropdown control that contains the available schemas in `dataset_metadata`. The `name` of the schema will be displayed if provided. If `name` is not provided, the index (zero-based) of the schema will be used instead. When dropdown list is empty, `selectschema` control will display default placeholder text `"..."`. This placeholder text can be customized by setting `[parameter_id].emptyList.placeholder` in resources section. When custom empty list placeholder text is provided, common-properties will disable the empty list control. +* `toggle` A standard toggle control with default On/Off states. This text can be customized by setting `[parameter_id].toggle.on.label` and `[parameter_id].toggle.off.label` in resources section. +* `toggletext` A two-state control with optional icons that can exist on its own or within table cells. +* `structuretable` Table control for editing lists or maps of complex types that have field names in the first column. +* `structurelisteditor` For lists or maps of complex types that are *not* field-oriented parameters. +* `structureeditor` Allows one to define a structure and use it directly on a panel. Each structure member is surfaced as an individual control. Supports a `layout` setting that allows one to position structureeditor controls in a grid (see below). +* `readonlyTable` A read only table. Used for tables to display fields that users shouldn't edit. +* `custom` A custom control for displaying a user defined control. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-controls) for more details. + + +### A Note on Field Name Storage +When a given node can accept more than a single datarecord-metadata object as input, it becomes necessary to store the schema name (a.k.a. 'link_name') along with each field name that is stored in parameter sets. In those cases, instead of using strings to store field names, they are represented in parameter sets as compound objects containing both 'link_ref' and 'field_name' elements: + + "current_parameters": { + "field": { "link_ref": "Schema-1", "field_name": "Age" }, + ... + +In order to indicate that a given node can potentially accept multiple input data links and would thus require compound field name storage, all parameter definitions within the node that contain `"role": "column"`, whether located at the top level or within complex types, should declare their data types as "object" instead of "string": + + "parameters": [ + { + "id": "fields", + "type": "array[object]", + "role": "column", + "required": true + }, + ... + +### edit_style +When editing complex type values in tables one can either edit cell values inline or in a sub panel: + +* `subpanel` A small sub-dialog is launched to edit cell values. +* `inline` Controls appear inline within table cells for editing values. +* `on_panel` Control appears below the table when the row is selected. + +### Miscellaneous +* `moveable_rows` *boolean* A value that appears in "complex_type_definition" sections. If set to `true` allows rows in the table to be moved up and down for reordering. +* `row_selection` *enum ["single", "multiple"]* Determines how many rows can be selected in a table at one time. Defaults to *multiple*. +* `sortable` *boolean* Both sortable and filterable apply to table columns. When set within the "key_definition" or the "parameters" sections of a structure definition, those columns are sortable and/or can be filtered upon. +* `filterable` *boolean* _(see sortable above)_ +* `language` *enum ["CLEM", "text/x-hive"]* The language for the expression control syntax highlight and text auto complete feature. If not specified, the expression control does not have syntax highlighting or text auto complete. +* `layout` A two-dimensional string array value that appears in "complex_type_definition" sections and allows one to layout structureeditor controls in a two dimensional grid. diff --git a/docs/3.4-Common-Properties-Conditions.md b/docs/3.4-Common-Properties-Conditions.md new file mode 100644 index 0000000000..bccd0f01b8 --- /dev/null +++ b/docs/3.4-Common-Properties-Conditions.md @@ -0,0 +1,361 @@ +# Conditions +Conditions define a set of specifications for evaluating parameter values. The specifications support complex interdependency checking such as relationships between multiple parameters (i.e. Valid values for parameter one depend upon the value of parameter two). +[conditions schema](https://github.com/elyra-ai/wdp-pipeline-schemas/blob/master/common-pipeline/operators/conditions-v1-schema.json) + +Visual documentation containing examples of the following conditions for the different controls we support are available at https://wdp-common-canvas-dev.stage1.mybluemix.net/#/conditions + + +A conditions file contains an array of conditions. Each condition takes one of the following forms: + +## Validation definition +A single validation. The fail_message is displayed upon validation failure. + +The attributes for the validation definition are: + +* `id` (*string*) A unique identifier for the validation. This is required if multiple validations have the same `focus_parameter_ref` value. +* `fail_message` (*object*) **Required** The message to display if the validation fails. Each fail_message consist of the following attributes + + `message` (*object*) **Required** The message to display. + + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + `focus_parameter_ref` (*string*) **Required** The parameter control to get focus after displaying the error/warning. If the validation refers to a table cell, then control must have the column indicator. For example if the validation is for `MyTable` cell column 2 then `MyTable[2]`. + + `type` (*string*) Type of messages. Valid values are `error, warning, info`. + +* `evaluate` (*object*) Specification for how to evaluate the validity of the parameter. The evaluate attribute can be one of the following structures. + + `condition` (*object*) This is a single condition that evaluates to true or false. + - `op` (*string*) **Required** A single operator for the properties of the condition. Valid values are: +`isEmpty`, +`isNotEmpty`, +`greaterThan`, +`lessThan`, +`equals`, +`notEquals`, +`matches`, +`notMatches`, +`contains`, +`notContains`, +`colNotExists`, +`isDateTime`, +`dmTypeEquals`, +`dmTypeNotEquals`, +`dmMeasurementEquals`, +`dmMeasurementNotEquals`, +`dmRoleEquals`, +`dmRoleNotEquals` +`lengthEquals`, +`lengthGreaterThan`, +`lengthLessThan`. + - `parameter_ref` (*string*) **Required** The primary parameter. + - `parameter_2_ref` (*string*) Second parameter for multi-parameter validation. + - `value` (*string, boolean, number*) Value against which to compare the primary parameter value. + - `values` (*array[string]*) Values against which to compare the primary parameter value is in. Used only in `filter` conditions. + + `or` (*object*) This is a container of 'or' conditions. Evaluates to true if ANY sub-condition evaluates to true. Can nest any number of additional conditional types. + + `and` (*object*) This is a container of 'and' conditions. Evaluates to true if ALL sub-condition evaluates to true. Can nest any number of additional conditional types. + +## Enabled definition +Enablement test. Disables controls if evaluate is false. + +The attributes for the enabled definition are: + +* `parameter_refs` (*array[string]*) Array of parameter names affected by this operation. If evaluate is false, then the controls associated with these parameters are disabled. Note that individual radio buttons can be disabled by using the radio button value name instead of the overall property name in the parameter_refs array. +* `action_refs` (*array[string]*) Array of action names affected by this operation. If evaluate is false, then the action button or image associated with these action names are disabled. +* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. + +## Visible definition +Visibility test. Hides controls if evaluate is false. + +The attributes for the visible definition are: + +* `parameter_refs` (*array[string]*) Array of parameter names affected by this operation. If evaluate is false, then hide the controls associated with these parameters. +* `action_refs` (*array[string]*) Array of action names affected by this operation. If evaluate is false, then the action button or image associated with these action names are disabled. +* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. + +## Filter definition +Filter test. The filter will determine which data record fields to include in a control. + +The attributes for the filter definition are: + +* `parameter_ref` (*string*) Parameter id affected by this operation. This must be a parameter that operates upon datarecord-metadata columns. +* `parameter_refs` (*string*) Exclusive with `parameter_ref` and used with `dmSharedFields`. Parameter ids affected by this operation. They must be parameters that operate upon datarecord-metadata columns. +* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. + +Supported operations (`op`): + +* `dmType` - filters `type` value from schema. +* `dmMeasurement` - filters `measurement` value from schema. +* `dmModelingRole` - filters `modeling_role` value from schema. +* `dmSharedFields` - shares source fields with all field chooser property names found in the `parameter_refs` array. + +**Examples**: +```js +{ + "filter": { + "parameter_ref": "fields_filter_measurement", + "evaluate": { + "condition": { + "op": "dmMeasurement", + "value": "discrete" + } + } + } +} +``` +```js +{ + "filter": { + "parameter_ref": "fields_filter_type", + "evaluate": { + "condition": { + "op": "dmType", + "values": ["integer", "double"] + } + } + } +} +``` +```js +{ + "filter": { + "parameter_refs": [ + "fields_filter_type", + "multi_field_chooser_table", + "field_chooser_in_another_panel" + ], + "evaluate": { + "condition": { + "op": "dmSharedFields" + } + } + } +} +``` + +## Enum Filter definition +Filters the available options for enumeration parameters. Reduces the available enumeration items if evaluate is true. + +The attributes for the enum_filter definition are: + +* `target` (*object*) Contains a target *parameter_ref* reference and a replacement *values* array. +* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. + +**Example**: +```js +{ + "enum_filter": { + "target": { + "parameter_ref": "radioset_filtered", + "values": [ + "red", + "yellow", + "green" + ] + }, + "evaluate": { + "condition": { + "parameter_ref": "filter_radios", + "op": "equals", + "value": true + } + } +} +``` + +## Allow Change definition +Allow change validates that a change is allowed on a property. If it evaluates to true then the value for the property is changed. This is typically used to restrict values that are invalid in one property based on the value in another property. For example, if the property represents a storage type with a value of `string`, then a property that represents a measurement type should not be allowed to be set to `continuous`. + +The attributes for the allow_change definition are: + +* `parameter_refs` (*array[string]*) Array of parameter names affected by this operation. +* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. + +**Example**: +```js +{ + "allow_change": { + "parameter_refs": [ + "ST_mse_table[2]" + ], + "evaluate": { + "or": [ + { + "condition": { + "parameter_ref": "ST_mse_table[2]", + "op": "notEquals", + "value": "Football" + } + }, + { + "condition": { + "parameter_ref": "ST_mse_table[5]", + "op": "notEquals", + "value": "European" + } + } + ] + } + } + } +``` + +## Default value definition +Sets the default value on the `parameter_ref` property if condition evaluates to true. If multiple conditions evaluate to true only the first condition is used. Default value condition is evaluated only once when loading properties. If user updates the value of `parameter_ref`, default value will be overwritten by the new value. + +The attributes for the default_value definition are: + +* `parameter_ref` (*string*) Parameter whose default value is to be set. +* `value` (*string, boolean, number, object, array*) This will be the default value of parameter_ref if condition evaluates to true. +* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. + +**Example**: +```js +{ + "default_value": { + "parameter_ref": "conditional_default", + "value": "Value defined in default_value condition. You will see this sentence when default value of mode equals Include.", + "evaluate": { + "condition": { + "parameter_ref": "mode", + "op": "equals", + "value": "Include" + } + } + } +}, +{ + "default_value": { + "parameter_ref": "conditional_default", + "value": ["This is a second condition for conditional_default. You should never see this value."], + "evaluate": { + "condition": { + "parameter_ref": "mode", + "op": "equals", + "value": "Include" + } + } + } +} +``` + + +## A note on table cell conditions +Support for table cell conditions is achieved via the use of the array subscript operator, `[]`. When evaluating table cells, one uses the table identifier with an array subscript indicating the zero-based table column being operated upon (which also corresponds to the sub-control index as defined in `complex_types`). + +So for example if one has a StructureTable property named _myTable_, column conditions on that table are referred to using `myTable[1]`, `myTable[3]`, etc. + +## Example + +Example of a condition section. +```js + "conditions": [ + { + "validation": { + "fail_message": { + "type": "error", + "focus_parameter_ref": "inputFieldList", + "message": { + "resource_key": "input_field_list_not_empty" + } + }, + "evaluate": { + "condition": { + "parameter_ref": "inputFieldList", + "op": "isNotEmpty" + } + } + } + }, + { + "visible": { + "parameter_refs": [ + "oneofselectPets" + ], + "evaluate": { + "condition": { + "parameter_ref": "oneofselectAnimals", + "op": "notContains", + "value": "lion" + } + } + } + }, + { + "visible": { + "action_refs": [ + "action_button" + ], + "evaluate": { + "condition": { + "parameter_ref": "button_hide_checkbox", + "op": "equals", + "value": false + } + } + } + }, + { + "enabled": { + "parameter_refs": [ + "radiosetColor" + ], + "evaluate": { + "condition": { + "parameter_ref": "checkboxEnable", + "op": "checked" + } + } + } + }, + { + "validation": { + "fail_message": { + "type": "error", + "focus_parameter_ref": "subsamplingRate", + "message": { + "resource_key": "subsampling_rate_not_valid" + } + }, + "evaluate": { + "and": [ + { + "condition": { + "parameter_ref": "subsamplingRate", + "op": "greaterThan", + "value": 0 + } + }, + { + "or": [ + { + "condition": { + "parameter_ref": "subsamplingRate", + "op": "lessThan", + "value": 1 + } + }, + { + "condition": { + "parameter_ref": "subsamplingRate", + "op": "equals", + "value": 1 + } + } + ] + } + ] + } + } + }, + { + "enabled": { + "parameter_refs": [ + "field_types[2]" + ], + "evaluate": { + "condition": { + "parameter_ref": "field_types[1]", + "op": "checked" + } + } + } + } + } + ] +``` \ No newline at end of file diff --git a/docs/3.5-Common-Properties-Custom-Components.md b/docs/3.5-Common-Properties-Custom-Components.md new file mode 100644 index 0000000000..cf2dcd29fc --- /dev/null +++ b/docs/3.5-Common-Properties-Custom-Components.md @@ -0,0 +1,180 @@ +# Custom Components Overview +Custom components allows applications to use custom code to drive different parts of the common-properties user interface. For some panels and controls it might be necessary to listen to different types of redux state changes to cause the panel/control to rerender. +Here is an example of a textfield listening to 3 state changes: +```js +import { connect } from "react-redux"; + +// ... application code + +render() { + const value = this.props.value; // value passed by redux as a property + + // ... rest of component render code + +} + +TextfieldControl.propTypes = { + // ... application props + state: PropTypes.string, // pass in by redux + value: PropTypes.string, // pass in by redux + messageInfo: PropTypes.object // pass in by redux +}; + +const mapStateToProps = (state, ownProps) => ({ + value: ownProps.controller.getPropertyValue(ownProps.propertyId), + state: ownProps.controller.getControlState(ownProps.propertyId), + messageInfo: ownProps.controller.getErrorMessage(ownProps.propertyId) +}); +export default connect(mapStateToProps, null)(TextfieldControl); +``` + + +## Custom Panels +Custom panels allow applications to create their own panels and controls that can live in the same dialogs as common-property panels and controls. + +### Custom panel interface +```js +// Returns the 'id' for the group defined in uihints +static id() + +constructor(parameters, controller, data) + +// Returns the content users want to display +renderPanel() +``` + +- **parameters** - String array of parameters set under the customPanel group in uihints +- **controller** - See [here](/3.6-Common-Properties-Controller) for API information. +- **data** - Optional parameter. Returns values stored in `data` attribute of a group `customPanel`. +- **renderPanel()** - Called on all Redux store changes: + - property value changes ([property APIs](/3.6-Common-Properties-Controller#property-methods)) + - state changes ([state APIs](/3.6-Common-Properties-Controller#state-methods-disableenabled--hiddenvisible)) + - schema changes ([schema APIs](/3.6-Common-Properties-Controller#datasetmetadata-methods)) + - row selection changes ([selection APIs](/3.6-Common-Properties-Controller#row-selection-methods)) + - messages changes ([message APIs](/3.6-Common-Properties-Controller#message-methods)) + +### Custom react components + +Example +```js +renderPanel() { + const controlId = this.parameters[0]; + return ( + + ); +} +``` + +### Examples +https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/src/client/components/custom-panels + + +## Custom Controls +Custom controls allow applications to create their own controls that can live in the same dialogs as common-property panels and controls. + +### Custom control interface +```js +// Returns the 'custom_control_id' for the parameter defined in uihints +static id() + +constructor(propertyId, controller, data, tableInfo) + +// Returns the content users want to display +renderControl() +``` + +- **propertyId** - See [propertyId](/3.6-Common-Properties-Controller#common-properties-controller-api) for definition. +- **controller** - See [here](/3.6-Common-Properties-Controller) for API information. +- **data** - Returns values stored in `data` attribute of a parameter in uihints. +- **tableInfo** - Set when custom control is a cell in a table. + - table (boolean) Set to true when in a table cell + - editStyle (string) Valid values are "summary" and "inline". "summary" is set when the control will display either below the table ("on_panel") or in a "subpanel". This allows the custom control to display a summary value in the cell and something else for the custom control. +- **renderControl()** - Called on all Redux store changes: + - property value changes ([property APIs](/3.6-Common-Properties-Controller#property-methods)) + - state changes ([state APIs](/3.6-Common-Properties-Controller#state-methods-disableenabled--hiddenvisible)) + - schema changes ([schema APIs](/3.6-Common-Properties-Controller#datasetmetadata-methods)) + - row selection changes ([selection APIs](/3.6-Common-Properties-Controller#row-selection-methods)) + - messages changes ([message APIs](/3.6-Common-Properties-Controller#message-methods)) + +### Custom react components + +Example +```js +renderControl() { + return ( + + ); +} +``` + +### Examples +https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/src/client/components/custom-controls + +## Custom Condition Operators +Custom condition operators allow users to create their own operators that can then be used for enablement, visibility, validation, and enum filtering. The condition operators should always return a `boolean` value. + +### Custom operator interface + +```js +/** +* This is the key used to determine if the operator should be ran. Maps to the `op` defined in the +* `condition` in uihints +* @return string +*/ +function op() + +/** +* @param see below +* @return boolean +*/ +function evaluate(paramInfo, param2Info, value, controller) +``` + +- paramInfo (object) - `parameter_ref` set in the `condition` in uihints + - control (object) - contains information about the control. + - value (any) - current property value +- param2Info (object) - `parameter_2_ref` set in the `condition` in uihints. See `paramInfo` for object info +- value - `value` set in the `condition` in uihints. If no value specific this will be `undefined` +- **controller** - See [here](/3.6-Common-Properties-Controller) for API information. + +Example +```js +function op() { + return "customMax"; +} + +function evaluate(paramInfo, param2Info, value, controller) { + const supportedControls = ["numberfield"]; + if (supportedControls.indexOf(paramInfo.control.controlType) >= 0) { + return paramInfo.value < value; + } + return true; +} + +module.exports.op = op; +module.exports.evaluate = evaluate; +``` +```json +{ + "evaluate": { + "condition": { + "parameter_ref": "custom_op_num", + "op": "customMax", + "value": 100 + } + } +} +``` + +### Examples +https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/src/client/custom/condition-ops +https://github.com/elyra-ai/canvas/tree/master/canvas_modules/common-canvas/src/common-properties/ui-conditions/condition-ops + diff --git a/docs/3.6-Common-Properties-Controller.md b/docs/3.6-Common-Properties-Controller.md new file mode 100644 index 0000000000..c2ce85b539 --- /dev/null +++ b/docs/3.6-Common-Properties-Controller.md @@ -0,0 +1,351 @@ +## Common Properties Controller API + +**propertyId** +```js +const propertyId = { + name: {parameter name defined in operator definition}, + row: {row in table/array}, // optional when col not set + col: {col in table}, // optional + propertyId: {propertyId of the nested structure} // optional +} +``` +### Property methods +```js +/* + * options - optional object of config options where + * setDefaultValues (boolean): when set to true, set default values from parameter definition +*/ +setPropertyValues(values, options) +updatePropertyValue(propertyId, value) +/* + * options - optional object of config options where + * filterHiddenDisabled (boolean): when set to true, filter out data values with a state of disabled or hidden + * filterHiddenControls (boolean): when set to true, filter out data values having control type hidden + * applyProperties (boolean): when set to true, will return data values in the format expected by the `applyPropertyChanges` callback. If unset or false, will return the internal format used by common properties. +*/ +getPropertyValue(propertyId, options) +/* + * options - optional object of config options where + * filterHiddenDisabled (boolean): when set to true, filter out data values with a state of disabled or hidden + * filterHiddenControls (boolean): when set to true, filter out data values having control type hidden + * applyProperties (boolean): when set to true, will return data values in the format expected by the `applyPropertyChanges` callback. If unset or false, will return the internal format used by common properties. +*/ +getPropertyValues(options) +``` +### Message methods +```js +/* + * Returns current list of error messages + * @filteredPipeline (boolean) optional + * @filterHiddenDisable (boolean) optional. If true, will not return error messages from controls that are hidden or disabled + * @filterDisplayError (boolean) optional. If true, will not return error messages that are not displayed in the editor + * when filteredPipeline=true returns enabled/visible control messages and only 1 per control. + */ +getAllErrorMessages() +getErrorMessages(filteredPipeline, filterHiddenDisable, filterSuccess, filterDisplayError = true) +getErrorMessage(propertyId, filterHiddenDisable = false, filterSuccess = false, filterDisplayError = true) +getRequiredErrorMessages() +setErrorMessages(messages) +updateErrorMessage(propertyId, message) + + +``` +### State methods (disable/enabled & hidden/visible) +```js +getControlState(propertyId) +getControlStates() +setControlStates(states) + +/* + * @propertyId - see above + * @state - valid values are "enabled", "disabled", "visible", "hidden" + */ +updateControlState(propertyId, state) +``` +### DatasetMetadata methods +```js +getDatasetMetadata() + +/* + * @datasetMetadata - see [schema](https://github.com/elyra-ai/pipeline-schemas/blob/master/common-pipeline/datarecord-metadata/datarecord-metadata-v1-schema.json) + */ +setDatasetMetadata(datasetMetadata) +``` + +### Row selection methods +```js +/* + * Returns table row selection indices as an array of integers. + * @propertyId - see above + */ +getSelectedRows(propertyId) + +/* + * Updates table row selections for the given table control. + * @propertyId - see above + * @selection - A zero-based array of integer selection indices + */ +updateSelectedRows(propertyId, selection) + +/* + * Clears selected table rows for the given table. + * @propertyId - see above + * If the propertyId is omitted all table row selections are cleared + */ +clearSelectedRows(propertyId) + +/* + * Adds a row selection listener for a table or list. + * @propertyId - see above + * @listener - callback function for when a selection is made in the table or list + */ +addRowSelectionListener(propertyId, listener) + +/* + * Removes the row selection listener from a table or list. + * @propertyId - see above + */ +removeRowSelectionListener(propertyId) +``` + +### Validation methods + +```js +/* + * Runs validation conditions on all controls + */ +validatePropertiesValues() + + + +/* + * Validates a specific propertyId + * @propertyId - see above + */ +validateInput(propertyId) +``` + +### Control methods +```js +/* + * Update the enum values for a given control. Used when enum values aren't static + * @propertyId - see above + * @valuesObj (array) [{ value: , label: "" }] + */ +updateControlEnumValues(propertyId, valuesObj) +``` + +### General methods +```js +/* +* Returns the current size of the RHS flyout. +*/ +getEditorSize() + +/* +* Sets default property values from parameter definition in the propertiesController. +* Note - These values won't be displayed on the UI. Host applications can call getPropertyValues() to retrieve the values. +* @paramDef - Follows the format of https://github.com/elyra-ai/pipeline-schemas/blob/master/common-canvas/parameter-defs/parameter-defs-v3-schema.json +*/ +setParamDef(paramDef) + +/* +* Returns the id of top-level active tab or accordion +*/ +getTopLevelActiveGroupId() + + +/* +* Makes the passed in groupId active. Only works for top-level groups +*/ +setTopLevelActiveGroupId(groupId) +``` + +### Disable move row buttons methods +```js +/** + * Disable table row move buttons for all propertyIds in given array + * @param propertyIds Array of propertyIds + * + */ +setDisableRowMoveButtons(propertyIds) +/** +* Returns array of propertyIds for which row move buttons will be disabled +* @return Array of propertyIds +*/ +getDisableRowMoveButtons() +/** +* Check if row move buttons should be disabled for given propertyId +* @param propertyId The unique property identifier +* @return boolean +*/ +isDisableRowMoveButtons(propertyId) +``` + + +### Custom panel and control methods +```js +/* + * Only used in custom panel to allow for custom property summary values to be displayed + * Displays the value set in propertiesReducer for that parameter + * @propertyId - see above + * @label (string) + * @inSummary (boolean) + */ +setControlInSummary(propertyId, label, inSummary) + +/* + * Sets the content to be displayed in the summaryPanel for a customPanel property. + * The summary panel will directly display the content. + * @propertyId - see above + * @content = { value: , label: "" } + */ +updateCustPropSumPanelValue(propertyId, content) + +/* + * Returns a standard control that can then be used in a customPanel. + * @propertyId - See above + * @paramDef - Follows the format of https://github.com/elyra-ai/pipeline-schemas/blob/master/common-canvas/parameter-defs/parameter-defs-v1-schema.json). titleDefinition, current_parameters, conditions, dataset_metadata are ignored and are optional. + * @parameter - This is the parameter from the paramDef to create the control for. + */ +createControl(propertyId, paramDef, parameter) + +/* + * Returns the translated text for a control given a resource key. + * Users should be able to use the values from resources that has been uploaded as part of paramDef. + * @key - Resource key + * @value - Default value returned when no resource or key has been found. + */ +getResource(key, value) + +``` + +### maxLength for single-line and multi-line control methods +```js +/* + * Returns the maximum characters allowed for multi-line string controls + * Default value is 1024 + */ +getMaxLengthForMultiLineControls() + +/* + * Returns the maximum characters allowed for single-line string controls + * Default value is 128 + */ +getMaxLengthForSingleLineControls() +``` + +### Enabling/disabling addRemoveRows methods +```js +/* + * Set the addRemoveRows attribute to 'enabled' for the given propertyId + * @param propertyId The unique property identifier + * @param enabled boolean value to enable or disable addRemoveRows + */ +setAddRemoveRows(propertyId, enabled) + +/* + * Returns the true if addRemoveRows is enabled for the given propertyID + * @param propertyId The unique property identifier + * @return boolean + */ +getAddRemoveRows(propertyId) +``` + +### Enabling/disabling properties editor "save" button methods +```js +/* + * Set the main "save" button to disabled(true) or enabled(false) + * @param saveDisable (boolean) + */ +setSaveButtonDisable(saveDisable) + +/* + * Returns the true if the main "save" button is disabled, false otherwise + * @return boolean + */ +getSaveButtonDisable() +``` + + +### Add static rows for table controls which will disable the re-ordering of the rows that are set as static for the given propertyId +```js +/* + * Set static rows for the given propertyId + * @param propertyId The unique property identifier + * @param staticRowsArr Array of first n row indexes or last n row indexes + */ +updateStaticRows(propertyId, staticRowsArr) + +/* + * Returns the static rows set for the given propertyId + * @param propertyId The unique property identifier + */ +getStaticRows(propertyId) + +/* + * Removes the static rows set for the given propertyId + * @param propertyId The unique property identifier + */ +clearStaticRows(propertyId) +``` + +### Enabling/disabling custom table buttons +```js +/* + * Set the table button to 'enabled' for the given propertyId + * @param propertyId The unique property identifier + * @param buttonId The unique button identifier + * @param enabled boolean value to enable or disable the button + */ +setTableButtonEnabled(propertyId, buttonId, enabled) + +/* + * Returns the table button states for the given propertyID + * @param propertyId The unique property identifier + * @return object An object of buttonIds mapped to their enabled state + */ +getTableButtons(propertyId) + +/* + * Returns the true if the table button is enabled for the given propertyID and buttonId + * @param propertyId The unique property identifier + * @param buttonId The unique button identifier + * @return boolean + */ +getTableButtonEnabled(propertyId, buttonId) +``` + + +### Column visibility methods +```js +/* + * Check if given column is visible in the table + * @param propertyId The unique property identifier + * @param columnIndex Column index in the table + */ +getColumnVisibility(propertyId, columnIndex) + +/* + * Set column visibility + * @param propertyId The unique property identifier + * @param columnIndex Column index in the table + * @param value Boolean value to set column visible/invisible + */ +toggleColumnVisibility(propertyId, columnIndex, value) +``` + +### Enabling/disabling wide flyout "OK" button methods +```js +/** +* Set the "OK" button in Wide Flyout to disabled(true) or enabled(false) for given summary panel +* @param panelId {name: panel.id} +* @param wideFlyoutPrimaryButtonDisable boolean +*/ +setWideFlyoutPrimaryButtonDisabled(panelId, wideFlyoutPrimaryButtonDisable) + +/** +* @param panelId {name: panel.id} +*/ +getWideFlyoutPrimaryButtonDisabled(panelId) +``` \ No newline at end of file diff --git a/docs/4.0-Styling.md b/docs/4.0-Styling.md new file mode 100644 index 0000000000..d106a33aed --- /dev/null +++ b/docs/4.0-Styling.md @@ -0,0 +1,56 @@ +## Overriding Styles and Color Themes + +### CSS styling for quick start + +If you just want to get up and running and don't care about scss then import these regular css files: + + - carbon-components/css/carbon-components.min.css + - @elyra/canvas/dist/styles/common-canvas.min.css + - version 8.x and older @elyra/canvas/dist/common-canvas.min.css + +More information about carbon components can be found here http://www.carbondesignsystem.com/getting-started/developers + + +### SCSS styling (recommended) + +If you want to use the full power of scss styling with variable overrides etc then include these imports in your main scss file: +```sass +@import "carbon-components/scss/globals/scss/styles"; +@import "@elyra/canvas/src/index.scss"; +``` + + - use `autoprefixer` when building + - if using webpack under the `sass-loader` and make sure to include + +```js +options: { includePaths: ["node_modules"] } +``` + +Again, you can refer to the test harness [index.scss file](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/styles/index.scss) for sample code. + + +### Loading Fonts +You may find that there is a pause in common canvas behavior, such as when the context menu is first displayed, which is caused by fonts being loaded. This can be fixed by adding the following to the `.scss` file for your application: +``` +$font-path: "/fonts"; +@import "carbon-components/scss/globals/scss/styles"; +``` +The fonts will need to be imported from carbon before carbon styles and placed in a public `/fonts` directory. +You can see an example of this in the common-canvas test harness (which is the equivalent of a host application) in this repo. That is, the [index.scss file](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/styles/index.scss) contains the lines above and the grunt build files ensures the fonts are copied from`node_modules/carbon-components/src/globals/` to the `` directory. + + +### 3rd party styling + + +If you are using common-properties then also include the react-virtualized styles: + + - react-virtualized/styles.css + +## Elyra Canvas styling guidelines +- Used the `data-id` attribute on inputs to be used for automated tests. Format for common properties should be `properties-` +- **className** format format for common-properties should be `properties-` +- Limit the use of html(DOM) ids +- Minimum inline styling. This allows for consumers to easily override styling. +- scss/sass styling should be added to the component's folder +- No `important!` in styling +- Use variables for all colors(preferably from carbon) diff --git a/docs/5.0-Testing-Guidelines-for-Development.md b/docs/5.0-Testing-Guidelines-for-Development.md new file mode 100644 index 0000000000..9f0866c268 --- /dev/null +++ b/docs/5.0-Testing-Guidelines-for-Development.md @@ -0,0 +1,53 @@ +# Testing Guidelines for Development +## Unit Testing +The Canvas unit tests are automated with the primary purpose of providing rapid feedback to the developers. The test cases are run during every development build. Unit test cases are written using Jest [Jest Tutorial](https://facebook.github.io/jest/docs/en/tutorial-react.html). The test cases should be written and delivered at the time that a feature or enhancement is delivered. + +Unit test cases should focus on good coverage of a function/service. We are current investigating code coverage analysis tools and will update this doc when it is implemented. + +Unit test case coverage should focus on these areas: + + * All APIs and all UI elements. + * All component properties. + * A variety of input data. + +Here is a good blog on [JavaScript Unit Testing](https://medium.com/javascript-scene/what-every-unit-test-needs-f6cd34d9836d) + + +## Functional Testing +The Canvas Functional Test cases will be automated and run during code delivery. The function test case will be automated and written using [Cypress](https://docs.cypress.io). + +Functional Testing coverage includes the following types of tests. + +* Core functionality +* Inter-operate with other Canvas elements. +* Need to test both forward and backwards compatibility +* Negative / bounds +* Globalization / Localization + * Handling of all strings using UTF-8 + * Verifying non-English unicode data is handled appropriately + * Externalizing all strings that may be presented for the user (e.g., error messages, UI labels, etc.) +* Access control security (roles / permissions / tenant management) +* Malicious and security (code scans such as AppScan, ethical hacking) +* Accessibility for UI + +## Debugging Tests + +### Jest tests (unit) +https://facebook.github.io/jest/docs/troubleshooting.html + +**With node 8 or newer** + +- Add `debugger;` statement to your Jest test suite program where you want to stop and begin debugging. +- If you want to run just a single test within your test program (rather than all of them) temporarily change the it() method for the test to be it.only(). For example, change: + + `it("should add a node", () => { ... })` + + to be: + + `it.only("should add a node", () => { ... })` + +- In the console enter: `npm run debug` or `npm run debug ` +- Open Chrome debugging tools by pasting this into the Chrome address field: [chrome://inspect/](chrome://inspect/#devices) +- You should see a 'remote' target for `node_modules/.bin/jest`. Click on the `inspect` link below it. +- Click on sources and then click the play button (right pointing blue triangle icon). +- The code should run to the point where your debugger statement was added. diff --git a/docs/css/styles.css b/docs/css/styles.css new file mode 100644 index 0000000000..675155171d --- /dev/null +++ b/docs/css/styles.css @@ -0,0 +1,7 @@ +th { + font-weight: bold; +} + +.md-grid { + max-width: initial; +} \ No newline at end of file diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000000..8d5dea28c3 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,90 @@ +# Welcome to the Elyra Canvas Documentation + +The elyra-ai/canvas repo contains three main components: + +* [Common Canvas](/2.0-Common-Canvas-Documentation/) - This contains canvas functionality which is packaged into the [elyra/canvas NPM module](https://www.npmjs.com/package/@elyra/canvas) and deployed on the NPM registry. It provides a way for an application to display a flow of data operations (shown as a set of nodes connected with links) defined in a pipeline flow JSON document, to the user and to allows the user to interact with the display to modify the flow. Common canvas is a react component which can be imported, and is assisted by a regular JavaScript class called `CanvasController` which provides an API and handles the internal data model of the flow. Common canvas is highly customizable where node shape and appearance, colors, styles layout etc can all be customized by your application code. + +* [Common Properties](/3.0-Common-Properties-documentation/) - This contains properties functionality which is packaged into the [elyra/canvas NPM module](https://www.npmjs.com/package/@elyra/canvas) and deployed on the NPM registry. It provides a way to translate a JSON document, which describes a set of properties with UI hints, into working properties dialog panel. Common properties is a react component and has an associated properties controller object. + +* [Test Harness](https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness#test-harness) - This provides a node.js app which displays a UI which allows you to try out various features of the common canvas and common properties components. Bear in mind this is not supposed to be a fully functional app but is, as the name suggests, a framework for testing. To get select one of the sample applications or select `None` as the sample app and then select a test canvas file from the `Canvas Diagram` drop down list and a test palette from the `Canvas palette` drop down list. + +## Installation + +You'll need to build your application with Elyra Canvas. + +* Elyra Canvas requires react, react-dom, react-intl, and react-redux libraries to be installed. See peerDependencies in package.json for versions requirements. + +Use the command: +```sh +npm install @elyra/canvas --save-dev +``` +or add this to your package.json file: + +``` + "@elyra/canvas": "x.x.x" +``` +where x.x.x is the latest build and then run: +```sh +npm install +``` + +## Localization +You must wrapper `` and `` in an `` object. + +If you want to display translated text, the sample code below shows how `` should be initialized. Your code can set `this.locale` to indicate which language should override the default which, in this sample code, is set to English `en`. The default locale will be used if `this.locale` is set to a language which is not currently supported. + +If you want to provide translations for your own application's text you can import your own bundles and load them into the `this.messages` object along with the common canvas and common properties text. If you do this you will have to move `` so that it wrappers your React objects as well as `` and/or ``. + +```js +import { IntlProvider } from "react-intl"; +import CommandActionsBundles from "@elyra/canvas/locales/command-actions/locales"; +import CommonCanvasBundles from "@elyra/canvas/locales/common-canvas/locales"; +import CommonPropsBundles from "@elyra/canvas/locales/common-properties/locales"; +import PaletteBundles from "@elyra/canvas/locales/palette/locales"; +import ToolbarBundles from "@elyra/canvas/locales/toolbar/locales"; + +class App extends React.Component { + +constructor() { + this.locale = "en"; + // Create messages object once (here in constructor) - do not create messages + // in the render method, otherwise unnecessary renders inside + // common-canvas/common-properties will be performed. + this.messages = this._getMessages( + this.locale, + [CommandActionsBundles, CommonCanvasBundles, CommonPropsBundles, + PaletteBundles, ToolbarBundles] + ); +} + +_getMessages(locale, bundles) { + const messages = {}; + for (const bundle of bundles) { + Object.assign(messages, bundle[locale]); + } + return messages; +} + +render() { + + {Add your or element here.} + +} +``` + +## Notes +When building your application you will need to load fonts and override styles can be found here: +[Styling](./4.0-Styling) + +## Testing +When testing your application with Jest, this error might show up: `crypto.getRandomValues() not supported`. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported for details. + +To fix, added this to your jest setup file: +```js +const cryptoJest = require("crypto"); +Object.defineProperty(global.self, "crypto", { + value: { + getRandomValues: (arr) => cryptoJest.randomBytes(arr.length) + } +}); +``` diff --git a/mkdocs.yml b/mkdocs.yml index fe932cee25..8128fccdf8 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,15 +1,9 @@ site_name: Elyra Canvas Documentation repo_url: https://github.com/elyra-ai/canvas -docs_dir: guide +docs_dir: docs + +theme: readthedocs -theme: - name: material - highlightjs: true - palette: - scheme: default - features: - - content.code.copy - - content.action.edit plugins: - search @@ -21,7 +15,7 @@ extra_css: extra_javascript: - js/links-in-new-tabs.js -edit_uri: edit/main/guide/ +edit_uri: edit/main/docs/ # Documentation and theme copyright: 'Copyright © 2024 Elyra Authors, an open source project and all are welcome to contribute! Maintained by the Elyra Authors Team' From 62ed2887ab998f1875c40489fdfc0a868af2fc4c Mon Sep 17 00:00:00 2001 From: srikant Date: Fri, 23 Feb 2024 15:19:22 +0530 Subject: [PATCH 10/20] Revert theme change Signed-off-by: srikant --- guide/2.0-Common-Canvas-Documentation.md | 241 ----- guide/2.0.1-Canvas-Editor.md | 11 - guide/2.0.1.1-Nodes.md | 1 - guide/2.0.1.2-Links.md | 62 -- guide/2.0.2-Palette.md | 40 - guide/2.0.3-Context-Menu.md | 5 - guide/2.0.4-Context-Toolbar.md | 37 - guide/2.1-Config-Objects.md | 627 ------------ guide/2.2-Common-Canvas-callbacks.md | 704 ------------- ...ling-node-creation-from-external-object.md | 77 -- guide/2.4-Canvas-Controller-API.md | 945 ------------------ ...2.4.0-Calling-the-Canvas-Controller-API.md | 39 - guide/2.4.1-Style-Specification.md | 69 -- guide/2.4.2-Decoration-Specification.md | 195 ---- guide/2.4.3-Object-structure-used-by-API.md | 49 - ....4.4-Notification-Message-Specification.md | 31 - ...grammatically-creating-new-canvas-nodes.md | 64 -- ...nstructing-a-read-only-or-locked-canvas.md | 57 -- guide/2.5-Command-Stack-API.md | 79 -- guide/2.6-Flow-Validation-API.md | 62 -- .../2.7-Customizing-Node-Layout-Properties.md | 392 -------- .../2.8-Context-Menu-Wrapper-Documentation.md | 67 -- guide/2.9-External-Subflows-support.md | 75 -- guide/3.0-Common-Properties-documentation.md | 315 ------ ...-Common-Properties-Parameter-Definition.md | 261 ----- guide/3.2-Common-Properties-UI-Hints.md | 348 ------- guide/3.3-Common-Properties-Controls.md | 111 -- guide/3.4-Common-Properties-Conditions.md | 361 ------- ...3.5-Common-Properties-Custom-Components.md | 180 ---- guide/3.6-Common-Properties-Controller.md | 351 ------- guide/4.0-Styling.md | 56 -- .../5.0-Testing-Guidelines-for-Development.md | 53 - guide/css/styles.css | 7 - guide/images/DELETEME | 1 - guide/index.md | 90 -- guide/js/links-in-new-tabs.js | 10 - mkdocs.yml | 10 +- 37 files changed, 8 insertions(+), 6075 deletions(-) delete mode 100644 guide/2.0-Common-Canvas-Documentation.md delete mode 100644 guide/2.0.1-Canvas-Editor.md delete mode 100644 guide/2.0.1.1-Nodes.md delete mode 100644 guide/2.0.1.2-Links.md delete mode 100644 guide/2.0.2-Palette.md delete mode 100644 guide/2.0.3-Context-Menu.md delete mode 100644 guide/2.0.4-Context-Toolbar.md delete mode 100644 guide/2.1-Config-Objects.md delete mode 100644 guide/2.2-Common-Canvas-callbacks.md delete mode 100644 guide/2.3-Enabling-node-creation-from-external-object.md delete mode 100644 guide/2.4-Canvas-Controller-API.md delete mode 100644 guide/2.4.0-Calling-the-Canvas-Controller-API.md delete mode 100644 guide/2.4.1-Style-Specification.md delete mode 100644 guide/2.4.2-Decoration-Specification.md delete mode 100644 guide/2.4.3-Object-structure-used-by-API.md delete mode 100644 guide/2.4.4-Notification-Message-Specification.md delete mode 100644 guide/2.4.5-Programmatically-creating-new-canvas-nodes.md delete mode 100644 guide/2.4.6-Constructing-a-read-only-or-locked-canvas.md delete mode 100644 guide/2.5-Command-Stack-API.md delete mode 100644 guide/2.6-Flow-Validation-API.md delete mode 100644 guide/2.7-Customizing-Node-Layout-Properties.md delete mode 100644 guide/2.8-Context-Menu-Wrapper-Documentation.md delete mode 100644 guide/2.9-External-Subflows-support.md delete mode 100644 guide/3.0-Common-Properties-documentation.md delete mode 100644 guide/3.1-Common-Properties-Parameter-Definition.md delete mode 100644 guide/3.2-Common-Properties-UI-Hints.md delete mode 100644 guide/3.3-Common-Properties-Controls.md delete mode 100644 guide/3.4-Common-Properties-Conditions.md delete mode 100644 guide/3.5-Common-Properties-Custom-Components.md delete mode 100644 guide/3.6-Common-Properties-Controller.md delete mode 100644 guide/4.0-Styling.md delete mode 100644 guide/5.0-Testing-Guidelines-for-Development.md delete mode 100644 guide/css/styles.css delete mode 100644 guide/images/DELETEME delete mode 100644 guide/index.md delete mode 100644 guide/js/links-in-new-tabs.js diff --git a/guide/2.0-Common-Canvas-Documentation.md b/guide/2.0-Common-Canvas-Documentation.md deleted file mode 100644 index 04d984121b..0000000000 --- a/guide/2.0-Common-Canvas-Documentation.md +++ /dev/null @@ -1,241 +0,0 @@ -## Introduction -Common canvas displays a flow of data operations as nodes and links which the user can create and edit to get the flow they want. These visual flows of data operations are translated into data processing steps performed by a back-end server. Common canvas provides functionality for the visual display of flows in the browser and leaves persistence and execution of data flows to the application. -Within common canvas the user can perform operations such as: - -* Create a new node by dragging a node definition from a palette onto the canvas. -* Create a new node by dragging a node from outside the canvas onto the canvas (you'll have to do some programming to get this to work). -* Delete a node by clicking a context menu option. -* Create a link by dragging a line from one node to another. -* Delete a link by clicking a context menu option. -* Add a comment to the canvas and draw a link from it to one or more nodes. -* Edit a comment. -* Move nodes and comments around in the canvas to get the desired arrangement. -* And more! ... - -# Architecture - -## Common Canvas react object - Common-canvas is a react component that can be used in your react application to display a fully-functional canvas user interface including the function mentioned above. The `` component is displayed in a `
` provided by your application. - -Common-canvas has these constituent parts that are visible to the user: - -* [Canvas editor](/2.0.1-Canvas-Editor/) - the main area of the UI where the flow is displayed and edited -* [Palette](/2.0.2-Palette/) - a set of node templates that can be dragged to the canvas to create new nodes -* [Context menu](/2.0.3-Context-Menu/) - a menu of options for nodes, comments, etc -* [Context toolbar](/2.0.4-Context-Toolbar/) - a menu of options for nodes, comments, etc presented as a small toolbar -* Toolbar - a set of tools across the top of the UI -* Notification panel - a panel for displaying runtime and other messages to your user -* Right side flyout - a panel, often used to display node properties -* Top panel - a panel which can be used to display other app related information -* Bottom panel - a panel which can be used to display other app related information - -and it handles: - - 1. the visual display of the flow of operations; - 2. any user gestures on the canvas; - 3. display of context menus; - 4. display and handling of the palette. - 5. provision of callbacks to tell your code what operations the user is performing on the canvas - 6. and much much more. - -## Canvas Controller - -The only mandatory parameter for the `` component is a regular JavaScript object called the [CanvasController](/2.4-Canvas-Controller-API/). - - The CanvasController routes handles calls from the host application and actions performed by the user. It then updates the internal object model which stores: - - 1. the data that describes the flow of nodes, links and comments (called a pipelineFlow); - 2. the data that describes the definition of the palette which contains node templates that can dragged to add nodes to the canvas; - 3. the set of currently selected objects. - 4. notification messages - 5. breadcrumbs that indicate which sub-flow is being viewed - 6. layout information - - The [CanvasController](/2.4-Canvas-Controller-API/) provides an API which allows your code to: - - 1. set a new pipelineFlow; - 2. get the current pipelineFlow (after the user has edited it); - 3. update and edit objects in the canvas (for example, add node, delete link etc.); - 4. set the node definition data (for display of nodes in the palette) - -# Getting started with common canvas programming - -## Hello Canvas! - You can start by looking at these two 'hello world' examples for using common canvas: - -* This first one called [app-tiny.js](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/client/app-tiny.js) has the bare minimum necessary to get a fully functioning common-canvas to appear including all the basic functionality, a palette and a flow of nodes and links. -* The second, called [app-small.js](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/client/app-small.js), shows many of the options available to a common-canvas developer such as configurations and callback handlers. - -You can also look at the [App.js](https://github.com/elyra-ai/canvas/blob/49ed634e3353d8f5c58eb8409ed8e1009f19c87a/canvas_modules/harness/src/client/App.js) file in the test harness section of this repo to see examples of code that uses the common canvas component. - - Now let's walk through the different steps to get common-canvas working: - - -## Step 1 : Install Elyra Canvas NPM module - -Enter: -``` - npm install @elyra/canvas -``` - -## Step 2 : Import Common-canvas - -To use common canvas in your react application you need to do the following. First import the CommonCanvas react component and CanvasController class from the Elyra Canvas library. Elyra Canvas produces both `esm` and `cjs` outputs. By default `esm` will be used when webpack is used to build the consuming application. - -**All Components** -```js - import { CommonCanvas, CanvasController } from "@elyra/canvas"; -``` -**Canvas only** - - To import only canvas functionality in `cjs` format use: -```js - import { CommonCanvas, CanvasController } from "@elyra/canvas/dist/lib/canvas"; -``` - -In addition you'll need to import `` from the `react-intl` library. -```js - import { IntlProvider } from "react-intl"; -``` - - -## Step 3 : Create an instance of the canvas controller -To control the canvas you'll need an instance of the canvas controller so create an instance of it like this (probably in the constructor of your object). -```js - this.canvasController = new CanvasController(); -``` -## Step 4 : Set the palette data -Next you'll need to populate the palette data. This will specify the nodes (split into categories) that will appear in the palette. The user can drag them from the palette to build their flow. This is done by calling CanvasController with: -```js - this.canvasController.setPipelineFlowPalette(pipelineFlowPalette); -``` -The pipelineFlowPalette object should conform to the JSON schema found here: -https://github.com/elyra-ai/pipeline-schemas/tree/master/common-canvas/palette - -Some examples of palette JSON files can be found here: -https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/test_resources/palettes - -## Step 5 : (Optional) Set the flow data -This is an optional step. If you want a previously saved flow to be shown in the canvas editor so the user can start to edit it, you will need to call the CanvasController with: -```js - this.canvasController.setPipelineFlow(pipelineFlow); -``` - -The pipelineFlow object should conform to the JSON schema found here: -https://github.com/elyra-ai/pipeline-schemas/tree/master/common-pipeline/pipeline-flow - -Some examples of pipeline flow JSON files can be found here: -https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/test_resources/diagrams - -## Step 6 : Pull in the CSS -Check this section to find info on what CSS to include in your application's CSS. [Styling](./4.0-Styling.md). - -## Step 7 : Display the canvas - -Finally you'll need to display the canvas object inside an `` object. Inside your render code, add the following: -```html -
- - - -
-``` -The div should have the dimensions you want for your canvas to display in your page. For the canvasController property, pass the instance of canvas controller you created earlier. This is the only mandatory property. After providing this and running your code you will have a fully functioning canvas including: a palette; default toolbar; context menus; direct manipulation (move and resize) etc. To customize these behaviors and presentation continue with the sections below. - -## Common Canvas customization -If you want to customize the behavior of common canvas you can specify any combination of the following optional settings: -```html -
- - -
-``` - -### Config objects -Common canvas has five **optional** configuration objects: config, toolbarConfig, notificationConfig, contextMenuConfig and keyboardConfig. -They are documented here: -[Config Objects](/2.1-Config-Objects) - -### Handlers -There are several **optional** handlers implemented as callback functions. They are contextMenuHandler, editActionHandler, beforeEditActionHandler, clickActionHandler, decorationActionHandler, layoutHandler, tipHandler, idGeneratorHandler, selectionChangeHandler and actionLabelHandler. They are documented here: -[Common Canvas Callback](/2.2-Common-Canvas-callbacks) - -### Right-flyout panel parameters -The right flyout panel appears on the right of the canvas area. You can add whatever content you like to this panel. Typically, it is used to display properties of nodes on the canvas. There are two **optional** parameters to let you manage the right flyout panel These are: - -- showRightFlyout: This can be true or false to indicate whether the flyout panel is shown or not. The default is false. -- rightFlyoutContent: content to display in the right flyout which is a JSX object. Nothing is displayed by default. - -### Bottom panel parameters -The bottom panel appears below the canvas area and between the palette and the right flyout panel. You can add whatever content you like to this panel. There are two **optional** parameters to let you manage the bottom panel. These are: - -- showBottomPanel: This can be true or false to indicate whether the bottom panel is shown or not. The default is false. -- bottomPanelContent: content to display in the bottom panel which is a JSX object. Nothing is displayed by default. - -### Top panel parameters -The top panel appears below the toolbar and between the palette and the right flyout panel. You can add whatever content you like to this panel. There are two **optional** parameters to let you manage the top panel. These are: - -- showTopPanel: This can be true or false to indicate whether the top panel is shown or not. The default is false. -- topPanelContent: content to display in the top panel which is a JSX object. Nothing is displayed by default. - -### Localization -You can customize `` using the `` object to [display translated test](/#localization) - -## Creating nodes on the canvas - -Nodes can be created on the canvas by the user in two ways: - -* By dragging a node from the palette onto the canvas background -* By dragging a node from outside the canvas - -The first technique is provided by Common canvas. The second requires some development work which is documented here: -[Enabling node creation from external object](/2.3-Enabling-node-creation-from-external-object) - - -## Keyboard support - -Common canvas supports a number of keyboard interactions as follows: - -|Keyboard Shortcut|Action|Description| -|---|---|---| -|Ctrl/Cmnd + a|selectAll|Select All objects -|delete|deleteSelectedObjects|Delete currently selected objects| -|Ctrl/Cmnd + x|cut|Cut selected objects to the clipboard| -|Ctrl/Cmnd + c|copy|Copy selected objects to the clipboard| -|Ctrl/Cmnd + v|paste|Paste objects from the clipboard. If the mouse cursor is over
the canvas, objects will be pasted at the cursor position or,
if not, at a default position| -|Ctrl/Cmnd + z|undo|Undo last command| -|Ctrl/Cmnd + Shift + z|redo|Redo last undone command| -|Ctrl/Cmnd + y|redo|Redo last undone command| - - -Your application can disable any or all of these actions by providing the [keyboard config object](/2.1-Config-Objects#keyboard-config-object) to the CommonCanvas react component. - -When any of the shortcut keys are pressed the common-canvas object model will be updated and then the [editActionHandler](/2.2-Common-Canvas-callbacks#editactionhandler) callback will be called with the `data.editType` parameter set to the action above and the `data.editSource` parameter set to "keyboard". diff --git a/guide/2.0.1-Canvas-Editor.md b/guide/2.0.1-Canvas-Editor.md deleted file mode 100644 index 728db155b4..0000000000 --- a/guide/2.0.1-Canvas-Editor.md +++ /dev/null @@ -1,11 +0,0 @@ -The Canvas Editor displays the flow to the user and allows the user to interact with the flow using the mouse/trackpad and the keyboard. - -The editor displays the following object types which the user can interact with: - -## Nodes -## Links -## Comments -## The Canvas background - - -[Still under construction] \ No newline at end of file diff --git a/guide/2.0.1.1-Nodes.md b/guide/2.0.1.1-Nodes.md deleted file mode 100644 index bedcb0af63..0000000000 --- a/guide/2.0.1.1-Nodes.md +++ /dev/null @@ -1 +0,0 @@ -[Under construction] \ No newline at end of file diff --git a/guide/2.0.1.2-Links.md b/guide/2.0.1.2-Links.md deleted file mode 100644 index 1adca82cd6..0000000000 --- a/guide/2.0.1.2-Links.md +++ /dev/null @@ -1,62 +0,0 @@ -## Introduction -Common-canvas is designed to display one link line on the canvas for each link defined in the pipeline flow. There are three types of link supported by common canvas: data links; association links; and comment links. Links can be enhanced by: - -* Overriding the CSS styles applied to the elements of the link line -* By specifying decorations for the link - -## Data Links -Data links are designed to model a flow from a source node to a target node. Data links are defined in the pipeline flow to connect a port on the source node to a port on the target node. The host application can choose whether or not to display ports on the nodes. Data links are typically displayed with an arrow head to display the flow along the link from source to target. - -If a data link is retrieved from the canvas controller API it will have the following important fields: - -* id - the unique identifier for the link. -* type - set to "nodeLink". -* srcNodeId - the ID of the node the link is connected from. -* srcNodePortId - the ID of the output port on the source node the link is connected from. Note: If this is undefined it indicates the node is connected to the first output port of the source node. -* trgNodeId - the ID of the node the link is connected to. -* trgNodePortId - the ID of the input port on the target node the link is connected to. Note: If this is undefined it indicates the node is connected to the first input port of the target node. -* decorations - an array of decorations specified for the link. -* app_data - any application specific data that was previously specified for the link in the pipeline flow or through the canvas controller API. - -Note: Typically data links must be drawn between nodes however, if the config field `enableLinkSelectionType` is set to `Detachable`, the links are allowed to be drawn to and/or from arbitrary points on the canvas. If a link is drawn either semi-detached (from one node) or fully-detached (from both nodes) the following fields will be in the link object: - -* srcPos - this is an object with two fields x_pos and y_pos. These provide the coordinates of the point on the canvas that the link is drawn from. If this exist then srcNodeId and srnNodePortId are not specified in the link object. -* trgPos - this is an object with two fields x_pos and y_pos. These provide the coordinates of the point on the canvas that the link is drawn to. If this exist then srcNodeId and srnNodePortId are not specified in the link object. - -## Association Links - -Association links are designed to capture a relationship between two nodes where there is no implied direction. By default these are displayed as a single straight link line in a dashed style. There are no arrow heads by default for that type of link. (Note : internally, association links do have a `srcNodeId` and `trgNodeId` but that is just to keep the field names consistent with the data links.) Association links do not reference ports. - -If an association link is retrieved from the canvas controller API it will have the following important fields: - -* id - the unique identifier for the link. -* type - set to "associationLink". -* srcNodeId - the ID of one of the nodes in the association. -* trgNodeId - the ID of the other node in the association. -* decorations - an array of decorations specified for the link. -* app_data - any application specific data that was previously specified for the link in the pipeline flow or through the canvas controller API. - -## Comment Links -Comment links connect a comment to one or more nodes. They can be created by the user by: (a) pulling out the small handle/circle that appears below a comment and dropping it on a node. (2) by selecting nodes before the comment is selected and then creating the comment. This will automatically create a comment link from the selected nodes to the newly created comment. - -If a comment link is retrieved from the canvas controller API it will have the following important fields: - -* id - the unique identifier for the link -* type - set to "commentLink" -* srcNodeId - the ID of comment. -* trgNodeId - the ID of the node the comment is connected to. -* app_data - any application specific data that was previously specified for the link in the pipeline flow or through the canvas controller API. - - -## Display of links -Links are drawn on the canvas using SVG elements in the DOM. Each link has a top level group `` element and inside it some SVG paths. The first displayed path is the selection area. This is invisible but provides a selection/hover area for mouse interactions on the link. The second is a path to represent the link itself which is drawn over the top of the selection area path: - -| Purpose | DOM tag | Classes | Notes | -| :---------- | :----------------------------------- | :---------- | :----------------------------------- | -|Group | g | d3-link group | Classes specified for the link in the class_name field of the link object will be added here. | -|⮕ Selection area| path | d3-link-selection-area | | -|⮕ Link line | path | d3-link-line | | -|⮕ Arrow head | path | d3-link-line-arrow-head | Only when enableLinkType is set to "Straight" | -|⮕ Decorations | g | d3-link-decorations-group | Will contain decoration elements, for example, image, path etc | - -Note: The main link group will also have one of these classes: d3-node-link (for data links), d3-object-link (for association links) or d3-comment-link (for comment links). \ No newline at end of file diff --git a/guide/2.0.2-Palette.md b/guide/2.0.2-Palette.md deleted file mode 100644 index 6369b28b60..0000000000 --- a/guide/2.0.2-Palette.md +++ /dev/null @@ -1,40 +0,0 @@ -## Introduction -By default, common-canvas includes a palette which appears in the left flyout panel. The palette displays a set of node templates split into different categories. The user can drag any of the node templates from the palette onto the canvas to create a new instance of a node on the canvas. The user can then join nodes together by creating link lines. - -## Populating the palette -The host application must tell common-canvas what node templates and categories it wants the user to see in the palette. This is done by providing common-canvas with a palette (JavaScript) object by calling the canvas-controller `setPipelineFlowPalette(palette)` method. The palette object is often read from a JSON document stored in the host application's repository or it can be automatically generated. - -The palette object should conform to the [palette schema](https://github.com/elyra-ai/pipeline-schemas/blob/412d70176953ed9ac2e6a03f7135b09b7565fc5d/common-canvas/palette/palette-v3-schema.json). The host application can ensure that palette conforms to the schema by switching on [schema validation](/2.1-Config-Objects#schemavalidation) in the canvas configuration. - -## Auto-join -Instead of dragging node templates from the palette, the user can double click node templates to add, and automatically join, them to the current flow. When a node template is double clicked, common-canvas will look for the node at the end of the current flow of nodes and will add the node to the canvas to the right of the end node in the flow. Common-canvas will also automatically join the nodes together by creating a new link line. - -## Palette configuration -There are a number of configuration options that control the palette that are specified in the canvas config object: - -* [enablePaletteLayout](/2.1-Config-Objects#enablepalettelayout) -* [enableNarrowPalette](/2.1-Config-Objects#enablenarrowpalette) -* [enableAutoLinkOnlyFromSelNodes](/2.1-Config-Objects#enableautolinkonlyfromselnodes) -* Deprecated - [paletteInitialState](/2.1-Config-Objects#paletteinitialstate) - -## Palette operation -The palette contents can be manipulated calling these canvas-controller [palette methods](/2.4-Canvas-Controller-API#palette-methods) - -The palette can be opened and closed using these canvas-controller [operational methods](/2.4-Canvas-Controller-API#palette-methods-1) - -## Search -The user can enter a search string into the Search field at the top of the palette. The behavior is as follows: - -1. When the search field is empty, the palette shows categories which can be expanded to show the node templates within the expanded category. -2. As the user enters characters into the search field, common-canvas immediately searches through the node template labels, node template descriptions and category labels for the characters entered and finds a subset of the node templates that match the search string. Common-canvas then replaces the category-based view of the palette with a list of node templates that match the search criteria. In this view the node templates also include the node description under the node label. -3. The search is case insensitive. -4. The search text is highlighted wherever it appears in the labels, descriptions or category labels. -5. Common-canvas uses a ranking algorithm to order the display of node templates so those most relevant to the search text are positioned at the top of the list. The ranking algorithm puts more weight on those node templates where the search text appears in the label than if the text appears in the description or the category label. -6. If the user enters words into the search field (separated by spaces), common-canvas searches for each word separately. Therefore, if say the user entered "data import" into the search field, common-canvas would find a node with "`Import` `Data`" as the label or even a node with a description that said "This node does lots of things and also `data` can be `import`ed." -7. Nodes that have text which have hits on multiple words are ranked more highly than node templates whose text only contains one search word. -8. Common-canvas uses a debounce function so that, if the user types the search string very quickly, common-canvas does not perform multiple searches for each key press but only runs a full search when rapid typing has ended. - -## Recommendation -According to the schema, node template descriptions are not mandatory in the palette object. However, it is recommended you provide descriptions for each of your node templates. The reason for this is that, the search function searches through node template descriptions, as well as node template labels and category labels. This means you can write your node template descriptions to contain appropriate keywords that a user might search for when looking for a node. - -For example, if there is a node template called ‘Import Data’ and that node could import comma-separated files you could add ‘comma-separated’ and ‘csv’ into your description for that node template. If the user entered `comma` in the search field the ‘Import Data’ node template would be shown in the search results even though `comma` does not appear in the node template label. \ No newline at end of file diff --git a/guide/2.0.3-Context-Menu.md b/guide/2.0.3-Context-Menu.md deleted file mode 100644 index 993829a9a4..0000000000 --- a/guide/2.0.3-Context-Menu.md +++ /dev/null @@ -1,5 +0,0 @@ -A context menu is a small window containing a list of options applicable to an object or set of selected objects. - -When [`enableContextToolbar`](/2.1-Config-Objects#enablecontexttoolbar) is set to `false` (or omitted) from the canvas config, and a right-click is performed on a node, link, comment or the canvas background, a traditional context menu is displayed like this: - -image \ No newline at end of file diff --git a/guide/2.0.4-Context-Toolbar.md b/guide/2.0.4-Context-Toolbar.md deleted file mode 100644 index 89279bf163..0000000000 --- a/guide/2.0.4-Context-Toolbar.md +++ /dev/null @@ -1,37 +0,0 @@ -Context toolbars can be enabled in common-canvas as an alternative to traditional context menus. - -A context toolbar is a small toolbar that appears above nodes, links and comments as the mouse cursor is hovered over them. A context toolbar for the canvas background can also be displayed by right-clicking on the canvas background. - -The context toolbar displays a set of icons that represent the most likely actions the user would want to perform on the object under the mouse cursor. If necessary, the toolbar can also show an overflow (vertical ellipsis) icon that, when clicked, reveals additional actions that can be performed on the object. - - -For a "vertical" style node the context toolbar looks like this: - -image - -For a “horizontal” style node it looks like this: - -image - -when the user clicks the overflow icon it looks like this: - -image - -Note: Since the mouse cursor can be hovered over a node, comment or link that is NOT currently selected, the actions shown in the context toolbar will apply to just that object, even if there is one or more currently selected objects. - -If the mouse cursor is hovered over a selected object when there are other selected objects, the actions in the context toolbar will be applicable to all the selected objects. This is the same as how a traditional content menu shows actions that are applicable to the set of selected objects. - - -The context toolbar behavior can be switched on by setting the [`enableContextToolbar`](/2.1-Config-Objects#enablecontexttoolbar) canvas configuration field to true. - -``` - const config = { - enableContextToolbar: true - }; - - ... - ... - -``` - - diff --git a/guide/2.1-Config-Objects.md b/guide/2.1-Config-Objects.md deleted file mode 100644 index 5c3fffbe99..0000000000 --- a/guide/2.1-Config-Objects.md +++ /dev/null @@ -1,627 +0,0 @@ -# Canvas Config object - -The canvas config object is optional. If it is not provided, or any of the properties within it are not provided, common-canvas will use reasonable defaults. Here's an example of a canvas config object: -```js - const commonCanvasConfig = { - "enableNodeFormatType": "Vertical", - "enableLinkType": "Straight" - } - }; -``` -and this is how it is specified to common-canvas: -```js - render() { - return ( - - ); - } - -``` - -## Canvas Config fields - -#### **enableInteractionType** -This can be "Mouse", "Carbon" or "Trackpad". The default is "Mouse". -***"Trackpad" has been deprecated and will be removed in the future.*** - -* With this set to "Mouse" the following interaction is enabled: - * Zoom canvas = Rotate mouse wheel. -(Can be simulated with a trackpad with two finger up and down scroll) - * Pan canvas = Left mouse key down on canvas background + drag. -(Can be simulated with a trackpad with press down on trackpad and drag.) - * Region select on canvas = Shift key + left mouse key down on canvas background + drag. -(Can be simulated with a trackpad with Shift + finger down on trackpad + drag across canvas background) - -* With this set to "Carbon" the following interaction is enabled: - * Zoom canvas = Rotate mouse wheel. -(Can be simulated with a trackpad with two finger up and down scroll) - * Pan canvas = Press and hold space bar then left mouse key down on canvas background + drag. -(Can be simulated with a trackpad by press and hold space bar then press down on trackpad and drag.) - * Region select on canvas = Left mouse key down on canvas background + drag. -(Can be simulated with a trackpad with press down on trackpad and drag.) - -* **This setting is now deprecated** With this set to "Trackpad" the following interactions are enabled: - * Zoom canvas = Two finger pinch or two finger spread gesture. -(Can be simulated with a mouse as follows: Ctrl + rotate mouse wheel.) - * Pan canvas = Two finger horizontal or vertical scroll gesture. -(Can be simulated with a mouse as follows: Vertical pan is rotate mouse wheel; Horizontal pan is Shift + rotate mouse wheel) - * Region select on canvas = Finger down + drag. -(Can be simulated with a mouse as follows: Left button down + drag on canvas background) - -#### **enableNodeFormatType** -This can be "Horizontal" or "Vertical". "Horizontal" is the default. "Horizontal" will display a node with an image and the label to the right of the image. "Vertical" will display the node with the label underneath the image.See the section called [Customizing Node Layout Properties](/2.7-Customizing-Node-Layout-Properties) for details on what this will do. - -#### **enableLinkType** -This can be "Curve", "Elbow", or "Straight". "Curve" is the default. This will set the link style used to connect nodes. - -#### **enableLinkDirection** -This can be "LeftRight", "TopBottom", or "BottomTop". "LeftRight" is the default. This will set the input and output port positions on nodes to facilitate links being drawn in the direction specified. - -* For "LeftRight" output ports will be on the right and input ports will be on the left of the nodes -* For "TopBottom" output ports will be on the bottom and input ports will be on the top of the nodes -* For "BottomTop" output ports will be on the top and input ports will be on the bottom of the nodes - -#### **enableLinkSelection** -This can be: "None", "LinkOnly", "Handles" or "Detachable". The default is "None". These have the following affect on the canvas: - -* "None" - no selection of links is possible however user can right click on a link to get a context menu. -* "LinkOnly" - a link may be selected and added to the set of currently selected objects (nodes and/or comments). -* "Handles" - This includes the "LinkOnly" function. In addition, when a link is selected a handle (either a circle or an image) is displayed at the start and end of the link. The link handle can be dragged to a new node/port position to rewire the flow. -* "Detachable" - This includes the "LinkOnly" and "Handles" function. In addition, this option enables detachable links for the canvas. This means a link can exist either: - * between a source node and an arbitrary point on the canvas (semi-detached) OR - * between an arbitrary point on the canvas and a target node (semi-detached) OR - * between two arbitrary points on the canvas (detached) - - Additionally, "Detachable" mode, allows: - - - semi-detached or fully-detached links to be stored in and retrieved from the pipeline flow document. - - semi-detached or fully-detached links to be manipulated with link handles. The link handles can be used to drag the end of the link away from its connecting source or target nodes and onto the canvas. Or semi-detached or fully detached links can be reattached to nodes/ports. - - a new detached link to be created by drawing out a new link from a node and dropping it onto the canvas. - - palette and canvas nodes, when they are dragged, to be dropped onto the ends of detached links to automatically attach them to the node being dragged. - -#### **enableLinkReplaceOnNewConnection** -This can be true or false. The default is false. If set to true, the user can drag a new connection to a target node, and if the input port on the target node has a maximum cardinality of one AND there is currently a connection to that port, the existing connection will be removed and the new connection is created; essentially this gesture replaces the existing link with the new one. If set to false the new connection will not be completed and the existing link will remain in place. - -When set to true and a link is replaced, common-canvas will call the `beforeEditActionHandler` the `editActionHandler` callback functions, if either are provided by the host application, with a `data` object parameter with the `editType` field set to `"linkNodesAndReplace"`. - -#### **enableParentClass** -This is a string which is a class name. The default is empty string. If a class name is provided it is applied to the top-most DOM element for common-canvas. This can be used to make you CSS override rules more specific which means they will be used in preference to any default styles. For example, if you specify "my-app-styles" for this field then CSS like this: -```css - .my-app-styles .d3-node-body-outline { - fill: orange; - } -``` -will override the style from the common-canvas CSS -```css - .d3-node-body-outline { - fill: white; - } -``` - -## enableImageDisplay - -This can be set to: "SVGInline", "LoadSVGToDefs" or "SVGAsImage". The default is "SVGInline". This field controls the display of SVG image files (that is, files with a `.svg` extension) on the canvas, such as those displayed for node icons or decoration images. This option can be useful to improve performance when images are repeated a large number of times on the canvas and particularly when the browser cache is disabled. Note: this does not affect the display behavior of non-SVG files which are always displayed inside an `` tag. The behavior for SVG image files is as follows: - -* "SVGInline" - This is the default. With this setting, the image file is read in -- from the server or cache (if available) -- and the SVG tags within the file displayed in-line in the DOM. This means elements within the SVG can be customized using CSS on a node-by-node basis. -* "LoadSVGToDefs" - With this option, each unique SVG file is read from the server (or cache) and written into a `` element within the `` element of the canvas SVG area. A `` element is then written to the place in the DOM for each place where the image should be displayed. Using this option means the SVG file for each image is only read once which should improve performance if images are repeated a lot on the canvas. However, it does limit the customization possibilities for the images on a node-by-node basis. Customization colors can be passed into the images using CSS inheritance, or the `currentColor` keyword, provided there are no internal classes applied to the elements in the SVG. -* "SVGAsImage" - This option causes the SVG file to be displayed within an `` element in the DOM. The file loading is handled internally by the browser. Again, with this option customization capabilities on a node-by-node basis are limited. Customization colors can be passed into the images using CSS inheritance, or the `currentColor` keyword, provided there are no internal classes applied to the elements in the SVG. - -#### **enableInternalObjectModel** -This is a boolean. The default is `true`. You should use `true` for this all the time. If you set this to `false` your code will be responsible for handling the object model, which is NOT recommended. When `false`, changes are not set into the object model, and consumers are expected to listen to events and update the internal object model themselves (again, *not* recommended). - -#### **enablePaletteLayout** -This can be: "Modal" or "Flyout" or "None". The default is "Flyout". "Flyout" displays a panel on the left side of the canvas containing the palette icons and "Modal" shows the palette icons in a dialog window. "None" stops the palette from appearing. - -#### **enableToolbarLayout** -This can be: "Top" or "None". The default is "Top". "Top" displays a toolbar at the top of the canvas area. See the [toolbar configuration object docs](/2.1-Config-Objects#toolbar-config-object) for details on how to customize the toolbar. "None" stops the toolbar from appearing. - -#### **enableResizableNodes** -This can be true or false. The default is false. If set to true, the user can resize nodes by dragging the edges of the node to increase or decrease the width and/or height of the node. When hovering the mouse cursor over the edge of the node the user will see a sizing cursor to indicate the resize function is available. This option works best when the node has a background rectangle that shows the extent of the sizing area. - -#### **enableInsertNodeDroppedOnLink** -This can be true or false. The default is false. If set to true, the user can drag nodes from the palette or from the canvas and drop them onto existing links in the flow. This causes the dropped node to be inserted between the two nodes joined by the link, meaning new links are created that join the new node to the previously joined nodes and the old link is removed. When the user performs the drop common-canvas will call the editActionHandler with one of two possible commands: - -* "createNodeOnLink" - when a node is being dragged from the palette leading to node creation & insertion -* "insertNodeIntoLink" - when an existing node is dragged from the canvas leading to insertion of the existing node into the link - -#### **enableRightFlyoutUnderToolbar** -This can be true or false. The default is false. If set to true the right flyout panel, when opened, will appear below the toolbar and will not cause the toolbar to compress. The default behavior is that the right flyout panel, when opened, will appear at the side of the toolbar and will compress the space available for the toolbar to be displayed. Warning: the notifications panel which is tied to the notifications icon in the toolbar will appear over the top of the right-side flyout with this option set to true. - -#### **enablePositionNodeOnRightFlyoutOpen** -This can be a boolean or an object. The default is false. If set to true, when the right-side flyout is open the currently selected node (assuming there is one) will be automatically positioned in the center of the viewport (canvas area). Instead of true this field can also be set to a simple JavaScript object like this `{ x: 30, y: 40 }` where x and y indicate the position where the node will be positioned as a percentage of the width and height of the viewport respectively. - -#### **enableHighlightNodeOnNewLinkDrag** -This can be true or false. The default is false. If set to true common-canvas will add the "data-new-link-over" attribute to the node's group `` element, when the end of a new link is dragged to be close to and over a target node. This allows applications to alter the appearance of the target node as a new link is dragged towards it. - -#### **enableHighlightUnavailableNodes** -This can be true or false. The default is false. If set to true, when the user begins to drag a new link line, common-canvas will add a new class called `d3-node-unavailable` to all nodes which cannot accept the link as input. The class will be applied to each node's group `` element in the DOM. This class can be used for styling the unavailable nodes as desired using CSS. The default styling will 'gray out' the node label, node outline rectangle (if there is one) and the node icon (provided it is an SVG image). These styles can be overridden in the applications CSS if different styling is needed. This behavior also applies if the end of a partially or fully detached link is dragged. - -#### **enableRaiseNodesToTopOnHover** -This can be true or false. The default is true. If set to false the nodes will be left in their original place in the DOM. If set to true, when the user moves the mouse cursor over a node, that node will be moved in the DOM so that the node appears on top of all other nodes. This is only really noticeable if nodes, or parts of nodes, overlap other nodes. It can be useful if your nodes have protruding ports or decorations and your users sometimes position nodes very close to one another. Note: the 'true' setting can adversely affect the behavior of scroll areas in a node that are displayed using a React object (using the `nodeExternalObject` node layout option) because when the node is moved in the DOM the scroll area gets reset to its initial position. Set this to false if you are displaying nodes using React objects. - - -#### **enableAutoLinkOnlyFromSelNodes** -This can be true or false. The default is false. When set to true the auto-add function (where double clicking a node in the palette automatically adds it to the canvas) will only link up nodes when a node is already selected on the canvas and then, only if the selected node can be linked to the node that was double clicked. If false, the auto-add function will make a best guess at which node the double-clicked node should be added to. - -#### **enableMoveNodesOnSupernodeResize** -This can be true or false. The default is true. If true, nodes surrounding a supernode will be moved when the supernode is expanded or manually resized so that the supernode does not overlay them. When set to false, the nodes surrounding a supernode will stay in their current positions when the supernode is expanded or manually resized. This may result in the nodes being overlaid by the supernode. - -#### **enableExternalPipelineFlows** -This can be true or false. The default is false. If true, the context menu will include a `Create External Supernode` option when a set of objects are selected from which a supernode can be created. - -Waring: The host application must implement some of the common-canvas callbacks for external pipeline flow support to work correctly. See the Wiki section on [external pipeline flow support](/2.9-External-Subflows-support) for more details. - -#### **enableDisplayFullLabelOnHover** -This can be true or false. The default is false. If set to true, any abbreviated node label will be displayed in full when the pointer hovers over the label. If set to false, abbreviated node labels will remain the same when the pointer hovers over them. - -#### **enableSingleOutputPortDisplay** -This can be true or false. The default is false. If set to true, only the last of the ports from the array of output ports will be displayed for each node. This config property is only applicable to applications with very specialized styling and handling of ports. If set to true with regular applications, it may result in a confusing display to the user. The single port is displayed at a position specified by outputPortRightPosX and outputPortRightPosY layout properties. For exmaple: -```js -config = { - enableSingleOutputPortDisplay: true, - enableNodeLayout: { - outputPortRightPosX: 0, - outputPortRightPosY: 20 -}; -``` -#### **enableDragWithoutSelect** -This can be either true or false. The default is false. If set to true, the user can drag and drop a single node or a single comment without that gesture removing selection on any other nodes or comments. If the node being dragged was selected prior to the drag gesture then it and any other objects that are currently selected will be moved. With this parameter set to false (or missing) a drag and drop gesture will select the node or comment being dragged and will deselect any currently selected objects. - -#### **enableMarkdownInComments** -This can be true or false. The default is false. When set to true the user may enter markdown syntax into comments on the canvas when in edit mode for the comment. When the editing ends, the comment is shown in presentation mode and the markdown syntax is converted to HTML which is displayed in the comment and is styled by CSS. - -#### **enableStateTag** -This can be either "None", "Locked" or "ReadOnly". The default is "None". When set to either "Locked" or "ReadOnly", a 'state tag' object will be shown permanently over the top of the canvas. The state tag will be positioned in the center and towards the top of the canvas. The state tag consists of a black background rectangle with rounded corners overlaid with an icon and a text label. A tooltip is displayed when the mouse pointer is hovered over the state tag. The icon, label and default tooltip will be set appropriately based on the value ("Locked" or "ReadOnly") for this setting. The host application can override the tooltip by implementing the [tipHandler callback](/2.2-Common-Canvas-callbacks#tiphandler). - -#### **enableEditingActions** -This can be true or false. The default is true. If set to false, various editing actions on the canvas will be prevented, as follows: - -1. Nodes cannot be created on the canvas using any of the following: - - (a) dragging and dropping a node template from the palette onto the canvas or - - (b) dragging and dropping an object onto the canvas from outside the canvas area, such as a file being dragged from the computer desktop onto the canvas (see note below), or - - (c) double clicking a node in the palette to create a node - - Note: It is not possible for common-canvas to prevent an object being dragged from the computer desktop to the canvas so it is recommended the drop zone (which provides visual feedback about the drop) should be switched off by setting the [enableDropZoneOnExternalDrag](/2.1-Config-Objects#enabledropzoneonexternaldrag) config field to `false`. - -2. Nodes and comments cannot be dragged and moved. -3. The end points of Links, when [enableLinkSelection](/2.1-Config-Objects#enablelinkselection) is set to `"Detachable"` or `"Handles"`, cannot be dragged and moved. -4. Links from nodes and comments cannot be created by dragging from the port object on the source node or comment to the target node. -5. Comments, node labels and text decorations cannot be edited, neither by clicking the edit icon (which does not appear) nor by double clicking the text. -6. Context menu options that alter the canvas objects will be removed from the context menu before it is displayed by common-canvas. The options that will be removed are: - - |Option Text|Action Identifier| - |---|---| - |New Comment|createComment| - |Disconnect|disconnectNode| - |Edit->Cut|cut| - |Edit->Copy|copy| - |Edit-Paste|paste| - |Undo|undo| - |Redo|redo| - |Delete|deleteSelectedObjects| - |Create supernode|createSuperNode| - |Create external supernode|createSuperNodeExternal| - |Deconstruct supernode|deconstructSuperNode| - |Collapse supernode|collapseSuperNodeInPlace| - |Expand supernode|expandSuperNodeInPlace| - |Convert external to local|convertSuperNodeExternalToLocal| - |Convert local to external |convertSupernodeLocalToExternal| - |Delete|deleteLink| - |Save to palette|saveToPalette| - - If your application adds its own editing actions to the context menu your code must remove them if they are not needed in some situations (e.g. you are displaying a read-only canvas). - -7. Any default toolbar actions (tools) that alter the canvas objects will be disabled regardless of their specified enablement status. These actions are: - - |Default Tooltip|Action| - |---|---| - |Undo|undo| - |Redo|redo| - |Cut|cut| - |Copy|copy| - |Paste|paste| - |Delete|deleteSelectedObjects| - |New comment|createAutoComment| - |Arrange Horizontally|arrangeHorizontally| - |Arrange Vertically|arrangeVertically| - -8. Keyboard shortcuts that alter the canvas will not work. These are: - - |Shortcut|Action| - |---|---| - |delete|delete| - |Ctrl/Cmd + x|cut| - |Ctrl/Cmd + c|copy| - |Ctrl/Cmd + v|paste| - |Ctrl/Cmd + z|undo| - |Ctrl/Cmd + Shift + z|redo| - |Ctrl/Cmd + y|redo| - -9. The browser's Edit menu options (cut, copy, paste) will not work with the canvas objects regardless of the setting for [enableBrowserEditMenu](/2.1-Config-Objects#enablebrowsereditmenu). - -#### **enableDropZoneOnExternalDrag** -This can be true or false. The default is false. If set to true a graphic overlay will be displayed over the canvas when a data object icon is dragged from the desktop over the canvas. The default graphic overlay will be an image and a message saying: "Drop to add to canvas and project" unless the `dropZoneCanvasContent` configuration parameter is provided. - -See the [Dragging an object from the desktop](/2.3-Enabling-node-creation-from-external-object#dragging-object-from-the-desktop-or-another-application) section of the Wiki for details on how to handle the drop of an external object onto the canvas. - -#### **enableNodeLayout** -This is a simple Javascript object, the properties of which override the default node layout properties. For more details see: [Customizing Node Layout Properties](/2.7-Customizing-Node-Layout-Properties) - -#### **enableSaveZoom** -This can be: "None", "LocalStorage" or "Pipelineflow". The default is "None". - -* "None" - When the canvas is zoomed, the zoom (scale and x/y pan) are not saved anywhere so if the canvas is closed and reopened it reopens with the default zoom which is a scale of 1 and x/y pan values of 0. -* "LocalStorage" - The zoom for the canvas is stored in the browser's local storage and will be reapplied to the canvas each time that canvas is shown in that browser. This applies to sub-flows, when the user displays them full-screen, as well as the primary flow. Sub-flows and the primary flow each have their own zoom amounts stored in local storage. Note: Zoom amounts stored in local storage can be cleared from storage by calling the `canvasController.clearSavedZoomValues()` API method. -* "Pipelineflow" - The zoom is serialized into the pipeline flow document and when a pipeline flow document is provided to common canvas through the API the zoom will be applied to the canvas display. Zoom amounts can be stored for both primary and sub pipelines. (See the pipelineFlow schema specification). - -#### **enablePanIntoViewOnOpen** -This can be either true or false. The default is false. If set to true, the canvas will be panned so as much of the canvas area (the area containing the nodes and comments) is visible in the viewport as possible. This will only happen when enableSaveZoom === "None" or if there is no saved zoom available either in local storage (when enableSaveZoom === "LocalStorage") or in the pipelineFlow (when enableSaveZoom === "Pipelineflow"). - -#### **enableZoomIntoSubFlows** -This is a boolean. The default is false. When set to true, common-canvas will override the maximum zoom extent value which, by default is used for the entire canvas, to allow the user to zoom in on in-place sub-flows further than they can do on containing flows. This means the user can zoom in on multi-nested sub-flows so they are easier to view. To see this effect, the user must position the mouse pointer over the sub-flow before performing the zoom gesture. - -#### **enableContextToolbar** -This is a boolean. The default is false. When set to true, common-canvas will display a context toolbar instead of a context menu for performing actions on canvas objects. A context toolbar is a small toolbar that appears above nodes, links and comments as the mouse cursor is hovered over them. The toolbar shows icons for actions the user is most likely to want to perform on the object. An overflow icon is displayed which, when clicked, shows a menu of additional actions. A context toolbar for the canvas background can also be displayed by right-clicking on the background. Common-canvas will display default context toolbars for nodes, links comments and the canvas background however the default actions can be customized by implementing the [`contextMenuHanlder`](/2.2-Common-Canvas-callbacks#contextmenuhandler) callback. - -#### **enableSnapToGridType** -This can be: "None", "During" or "After". The default is "None". - -* "None" - there is no snap to grid and objects can be moved to any position on the canvas. -* "During" - when nodes or comments are moved or sized, the objects snap to an imaginary grid while the objects are being dragged or sized. This gives a somewhat jerky effect as the move or size is happening but has the advantage of telling the user exactly where the object will be when they release the mouse button to end the action. -* "After" - nodes or comments snap to a grid when the drag or size event ends. This gives a smooth dragging and sizing effect but the user does not see the final position until they release the mouse button at the end of the action. By default the canvas uses reasonable values for the grid increments. - -#### **enableSnapToGridX** -This optional value overrides the default horizontal increment of the snap-to-grid grid. It can be either a numeric value which is a number of pixels or it can be a numeric value followed by a % sign (e.g. "25%") which indicates the grid will be a percentage of the default node width. Its default is dependent on whatever is set for enableNodeFormatType. That is for "Horizontal" it will be "20%" and for "Vertical" it will be "25%". - -#### **enableSnapToGridY** -This optional value overrides the default vertical increment of the snap-to-grid grid. It can be either a numeric value which is a number of pixels or it can be a numeric value followed by a % sign (e.g. "25%") which indicates the grid will be a percentage of the default node height. Its default is dependent on whatever is set for enableNodeFormatType. That is for "Horizontal" it will be "33.33%" and for "Vertical" it will be "20%". - -#### **enableAutoLayoutVerticalSpacing** -This is the spacing in pixels which is used to separate nodes vertically when either the vertical or horizontal auto layout action is used. - -#### **enableAutoLayoutHorizontalSpacing** -This is the spacing in pixels which is used to separate nodes horizontally when either the vertical or horizontal auto layout action is used. For horizontal auto layout, common-canvas may override this value if it decides that more space is needed to prevent connecting lines from doubling back on themselves. - -#### **enableAssocLinkCreation** -This is a Boolean. The default is `false`. If set to `true` it changes the nature of links that are created between nodes as follows: - -- The user is able to pull out a link from either port on the node and drag it to another node -- When a link is completed an `association` link is created rather than the regular data flow link that is created when this field is set to `true`. Association links describe an association between pairs of nodes and do not indicate any kind of data flow between those nodes. - -#### **enableAssocLinkType** -This can be "Straight" or "RightSideCurve". The default it "Straight". This field changes the way association links are drawn on the canvas. - -#### **enableBrowserEditMenu** -This can be true or false. true is the default. If true, the Cut/Copy/Paste items in the Browser's `Edit` menu, including keyboard input for those actions, can be used for performing those actions on objects (e.g. Nodes) in the canvas. When false, those items in the Browser's edit menu, including keyboard input for those actions, will not work for objects in the canvas. This will not prevent those actions working in the canvas when, say, invoked with the toolbar or canvas context menus, but this property can be used if the keyboard input for those actions into the canvas is disabled for common-canvas using the [keyboard config](/2.1-Config-Objects#keyboard-config-object) object. - -#### **enableNarrowPalette** -This can be true or false. true is the default. If true when the palette is closed the narrow palette will be shown. When false the palette completely closes. - -#### **paletteInitialState** -Deprecated -- This option is deprecated and will be removed soon. Use `CanvasController.openPalette()` to display an opened palette at start-up. This `openPalette()` can be called immediately after creating the canvas controller. - -paletteInitialState can be true or false. false is the default. If set to true the palette will be opened when common canvas first appears to its full (non-narrow) state. - -#### **emptyCanvasContent** -This is a JSX or HTML snippet that contains some text or any elements (such as an image) that you want to display when the canvas is empty, that is, when it doesn't have any nodes or comments. The default behavior if this config parameter is not provided is that common canvas will display an image and message saying: "Your flow is empty!". - -#### **dropZoneCanvasContent** -This is a JSX or HTML snippet that contains some text or any elements (such as an image) that you want to display when a data object is dragged from the desktop over the canvas. The default behavior if this config parameter is not provided is that common canvas will display an image and a message saying: "Drop to add to canvas and project". The content will not be displayed unless the `enableDropZoneOnExternalDrag` configuration parameter (see above) is set to true. - -#### **schemaValidation** -This can be true or false. false is the default. It tells common canvas whether you want pipleineFlow and palette objects to be validated against the schema files when they are submitted to the canvas controller, using the `setPipelineFlow(pFlow)` or `setPipelineFlowPalette(palette)` methods. If any validation errors are found messages are displayed in the browser console. It is recommended this option be set to true during development and testing but switched off in production since schema validation can be somewhat slow for large objects. - -#### **tipConfig** -This is a simple JavaScript object that configures whether tips for palette items, nodes, ports, links, decorations or the state tag are enabled (value set to true) or disabled (value set to false). By default, all tips are enabled. The following would switch off tips for ports and links. -```js - "tipConfig": { - "palette": true, - "nodes": true, - "ports": false, - "links": false, - "decorations": true, - "stateTag": true - } -``` -The tips displayed by the palette can be further refined. For example, this would prevent tips for palette categories from being displayed, but would still display tips for node templates in the categories: -```js - "tipConfig": { - "palette": { - "categories": false, - "nodeTemplates": true - }, - "nodes": true, - "ports": false, - "links": false, - "decorations": true, - "stateTag": true - } -``` - -Note: The default content of tips can be overwritten by implementing the [tipHandler callback](/2.2-Common-Canvas-callbacks#tiphandler). - -# Toolbar Config object - -The toolbar config object is optional. If it is not provided common-canvas will display a reasonable default toolbar. If provided, it configures which action items (tools) and dividers are shown in the canvas toolbar. A toolbar will only be displayed for common-canvas if the canvas configuration field [`enableToolbarLayout`](/2.1-Config-Objects#enabletoolbarlayout) is set to "Top" (which is the default). - -If you do specify a toolbar config object, you can specify actions for the left and right side of the toolbar to override the default toolbar. You can also optionally tell the toolbar not to handle the enable/disable state for the standard toolbar buttons using `overrideAutoEnableDisable`. The `leftBar` and `rightBar` fields contain an array of objects: one element for each toolbar item. Here is an example, toolbar configuration object: - -```js - const toolbarConfig = { - leftBar: [ - { action: "undo", label: "Undo", enable: true }, - { action: "redo", label: "Redo", enable: true }, - { divider: true }, - { action: "cut", label: "Cut", enable: false }, - { action: "copy", label: "Copy", enable: false }, - { action: "paste", label: "Paste", enable: false }, - { divider: true }, - { action: "createAutoComment", label: "Add Comment", enable: true }, - { action: "deleteSelectedObjects", label: "Delete", enable: true }, - { action: "arrangeHorizontally", label: "Arrange Horizontally", enable: true } - { divider: true }, - { action: "insaneMode", label: "Switch on insane mode", enable: true, isSelected: true } - ], - rightBar: [ - { action: "stop", label: "Stop Execution", enable: false }, - { divider: true }, - { action: "run", label: "Run Pipeline", enable: false } - ], - overrideAutoEnableDisable: false - }; -``` -Where: - -* **leftBar** - an array of action items to specify what is displayed on the left side of the toolbar. - -* **rightBar** - an array of action items to specify what is displayed on the right side of the toolbar. If this is omitted, common-canvas will automatically populate the right side of the toolbar with zoom-in, zoom-out, and zoom-to-fit actions. To suppress these right side actions, specify the `rightBar` field as an empty array or an array containing the actions you want on the right. - -* **overrideAutoEnableDisable** - a boolean. The default is false. By default common-canvas has an auto-enablement feature that controls the enablement of common tools in the toolbar based on user actions (e.g enable the `Delete` icon when items are selected). If `overrideAutoEnableDisable` set to true it will switch off the auto-enablement feature. This is useful if the host application wants to disable all the nodes under certain circumstances. If set to true, the `enable` property in the action items for each tool is used to decide whether to display the icon as enabled or disabled. If set to false or omitted, common-canvas will handle the auto-enablement of common actions. (See the `action`section below for more details.) - -Two toolbar items are automatically added to the toolbar: - -- A palette action which is used for opening and closing the node palette. This is added to the left side of the left side of the toolbar if the [`enablePaletteLayout`](/2.1-Config-Objects#enablepalettelayout) field is set to either "Flyout" (the default) or "Modal" in the canvas configuration. -- A notification panel action which is used to open and close the notifications panel. This will be added to the right side of the toolbar if a [notification configuration](/2.1-Config-Objects#notification-config-object) object is specified to the `` react object. - -The toolbar will display the objects in the same order they are defined in the arrays. - -Here is an example of an action object which must contain a unique `action` field as a minimum. -```js - { - action: "run", - label: "Run", - enable: true, - iconEnabled: "/image/myOwnEnabledIcon.svg", - iconDisabled: "/image/myOwnDisabledIcon.svg", - incLabelWithIcon: "before", - kind: "primary", - tooltip: "Run the flow", - isSelected: false - } -``` - -* **action** - a unique identifier and the name of the action to be performed. This action name will be passed in the `data` parameter of the [editActionHandler](/2.2-Common-Canvas-callbacks#editactionhandler) callback method so you can detect when the user clicks an action in the toolbar. - - If you are using the recommended (and default) [internal object model](/2.1-Config-Objects#enableinternalobjectmodel), the following built in actions will be automatically handled by common-canvas: `undo`, `redo`, `cut`, `copy`, `paste`, `createAutoComment`, `deleteSelectedObjects`, `arrangeHorizontally`, `arrangeVertically`, `zoomIn`, `zoomOut`, and `zoomToFit`. So for example, if the `deleteSelectedObjects` action (shown as a trash can) is clicked, any selected objects will be deleted from the internal object model. - - Disablement of some of these built in actions is also handled by common-canvas so, for example, when no canvas objects are selected the `deleteSelectedObjects` action (trash can icon) will be automatically disabled. You can switch off this automatic enable/disable function by setting `overrideAutoEnableDisable` field in the toolbar config to `true`. When set to true, the `enable` field in the action objects will be used to set the enablement appearance of the toolbar item. - -* **label** - the Tooltip label to display (and optionally the text to display next to the icon if `incLabelWithIcon` is specified). - -* **enable** - Icon will have hover effect and is clickable when set to true. If false, icon will be disabled and unclickable. If not set, it will default to disabled (false). If `overrideAutoEnableDisable` is set to false, or omitted, this field is ignored for the standard action items (like cut, copy, paste) because common canvas handles their enable/disable appearance. If `overrideAutoEnableDisable` is set to true, this field will be used for standard action items. - -* **iconEnabled** - specifies the icon to display when `enable` is true. Common-canvas will provide icons for the following actions so you don't need to specify `iconEnabled` or `iconDisabled` for them: `stop`, `run`, `undo`, `redo`, `cut`, `copy`, `paste`, `createAutoComment`, `deleteSelectedObjects`, `arrangeHorizontally`, `arrangeVertically`, `commentsShow`, `commentsHide`, `zoomIn`, `zoomOut`, and `zoomToFit`. - - It can be either: - - - a string containing the path to a custom SVG file to display or - - a JSX expression, for example `()` where Edit32 is an icon imported from carbon icons. It is recommended to only pass very simple JSX expressions. - -* **iconDisabled** - specifies the icon to display when `enable` is false. If `iconDisabled` is *not* specified `iconEnabled` will be used instead. It can be omitted for any of the standard actions (see `iconEnabled` above). - - It can be either: - - - a string containing the path to a custom SVG file to display or - - a JSX expression, for example `()` where Edit32 is an icon imported from carbon icons. It is recommended to only pass very simple JSX expressions. - -* **incLabelWithIcon** - can be set to "no", "before" or "after". The default is "no". This field specifies whether the label should be displayed in the toolbar with the icon and if so, where it is displayed with respect to the icon. - -* **kind** - can be set to "default", "primary", "danger", "secondary", "tertiary" or "ghost". The default it "default". These give the action the same styling as the equivalent kind's of [buttons in the carbon library](https://carbondesignsystem.com/components/button/usage#button-types). - -* **tooltip** - A string or JSX object. The tooltip that will be displayed for the action. If this is not provided the label will be displayed as the tooltip instead. - -* **isSelected** - A boolean. When set to true the toolbar button displays a selection highlight (which is a blue bar along the bottom border of the toolbar item). This is useful if you have a button that switches on and off a mode in your interface, as opposed to a regular button, which does not have any state, that would typically execute a command of some sort. For example, if your product has a 'Turbo boost' setting, which can be on or off, you could add a 'Turbo Boost' button to the toolbar and use `isSelected` to indicate when the option is active. When the user clicks the button it would switch `isSelected` for the 'Turbo Boost' button to true or false as appropriate. (This would give behavior like a checkbox.) - - You can also use this property to indicate a current state between a number of mutually exclusive settings. In this case, you would add one button to the toolbar for each setting and then set the `isSelected` property to true for the setting that is currently active. Then, when the user clicks a different option in the set, your code would set `isSelected` to true for that button and set it to false for the previously selected button. (This would give behavior like a radio button set.) - - -You can add dividers to separate groups of actions from other actions. This is displayed as a thin gray line. The divider object has one attribute: -```js - { - divider: true - } -``` - -* **divider** - To show a divider in the toolbar, add an object with `divider` attribute set to true. - -### Deprecated toolbar config - - The old toolbar configuration is still supported for now (but is deprecated). This allows the config to be provided as an array that defines just the left side of the toolbar. The right side will always show the zoom actions (zoomIn, zoomOut, zoomToFit) and a notifications panel icon (if a notification configuration object is provided in the CommonCanvas react object). These right side actions will always show on the right-hand side of the toolbar and are handled internally by the canvas. The entries in the array follow the same definition as described above. Note: there is no need to provide a `palette` action in the array because a palette icon and following divider will automatically be added to the toolbar when a palette is specified for the canvas. - -An example of the toolbar config array should look like this: -```js - const toolbarConfig = [ - { action: "stop", label: "Stop Execution", enable: false }, - { action: "run", label: "Run Pipeline", enable: false }, - { action: "undo", label: "Undo", enable: true }, - { action: "redo", label: "Redo", enable: true }, - { action: "cut", label: "Cut", enable: false }, - { action: "copy", label: "Copy", enable: false }, - { action: "paste", label: "Paste", enable: false }, - { action: "createAutoComment", label: "Add Comment", enable: true }, - { action: "deleteSelectedObjects", label: "Delete", enable: true }, - { action: "arrangeHorizontally", label: "Arrange Horizontally", enable: true } - ]; -``` - -### Advanced: JSX actions -Regular toolbar buttons, explained above, are displayed as set of Carbon `Button`s. If you _don't_ want your content wrappered in a button, you can provide your own JSX to display as an action in the toolbar. Be aware however that, because of the way the toolbar is designed, there are restrictions on what the toolbar can do to display your JSX. For example, it cannot display anything with a height greater than the toolbar height. - -If you provide your own JSX object it is displayed in a simple `div` in the toolbar. Some attributes are applied to the `div` to allow the action to work correctly within the toolbar - these cannot be changed. You are responsible for styling your JSX object to get it to appear the way you want. - -Also be aware that, if the width of the toolbar reduces (maybe by the user sizing the page) your action may get moved into the overflow menu. It is also your responsibility to style the button so it appears as you want in the overflow menu as well as the toolbar. - -The JSX can be provided in the `jsx` field. Here is an example. The only other fields that are recognized with the `jsx` field are `action` and `tooltip`, all other fields will be ignored. - -```js - { - action: "custom-loading", - jsx: (
), - tooltip: "Loading the thing you wanted." - } -``` - -* **action** - a unique identifier and the name of the action to be performed. - -* **jsx** - A JSX object. This will be displayed as the action in the toolbar. - -* **tooltip** - A string or JSX object. This will be displayed as the tooltip for the action in the toolbar. If `tooltip` is omitted no tooltip will be added to your action. If `tooltip` is specified the `jsx` will be inside a tooltip `div` which is in the toolbar `div` mentioned above. - -Here's an example toolbar that includes some Carbon React components -```js - toolbarConfig = { - leftBar: [ - { action: "custom-loading", - jsx: ( -
- -
- ) - }, - { divider: true }, - { action: "custom-checkbox", - jsx: ( -
- -
- ) - }, - { divider: true }, - { action: "custom-button", - tooltip: "A custom button of type primary!", - jsx: ( -
- -
- ) - }, - { divider: true }, - { action: "custom-dropdown", - tooltip: "A drop down using the overflow menu!", - jsx: ( -
- - - - - -
) }, - { divider: true } - ] - }; -``` - -# Notification Config object - -The notification config object configures whether or not the notification icon will be shown in the canvas toolbar. It will appear to the far right of the zoom actions in the toolbar. -Similar to a toolbar action object, the notificationConfig object looks like this: -```js - const notificationConfig = { - action: "notification", - label: "Notifications", - enable: true, - notificationHeader: "Notification Messages", - notificationSubtitle: "subtitle", - emptyMessage: "You don't have any notifications right now.", - clearAllMessage: "Clear all", - keepOpen: true, - clearAllCallback: () => { console.log("Clear All clicked"); } - }; -``` - -* **action** - "notification" enables the notifications icon to appear in the far right of the toolbar. - -* **label** - the Tooltip label to display for the notifications icon in the toolbar. - -* **enable** - Icon will have hover effect and is clickable when set to true. If false, icon will be disabled and unclickable. If not set, it will default to disabled (enable: false) - -* **notificationHeader** - String to display in the notification panel header. If not set, it will default to "Notifications". - -* **notificationSubtitle** - String to be displayed as a sub-title in the panel header. If not set panel header will be sized to only contain the `notificationHeader` string. - -* **emptyMessage** - String to be displayed when there are no notification messages to display. - -* **clearAllMessage** - String to be displayed on a button displayed at the bottom of the panel. The button can be clicked to clear all the messages from the panel. If omitted the button, and the footer area of the panel it appears in, will not be displayed. - -* **keepOpen** - A boolean which indicates when the panel will close. The default is false. If set to false, the panel will close when the user clicks on the page somewhere outside the panel. If set to true the panel will remain open when the user clicks somewhere on the page outside of the panel. With the option the user must click the `x` icon in the top right of the panel, or click the notification toolbar icon, to close the panel. - -* **clearAllCallback** - An optional callback function that will be called every time the "clear all" button is clicked. - -* **secondaryButtonLabel** - Label for the optional secondary button to be displayed in the notification panel. Both `secondaryButtonLabel` and `secondaryButtonCallback` must be specified for the button to appear. -* **secondaryButtonCallback** - A callback function that will be called when the secondary button is clicked. -* **secondaryButtonDisabled** - Specify whether the secondary button is disabled or not. - - -The notification icon state is determined by the type of messages in the notification message array. By default, a notifications icon in ready state will be shown if there are messages in the notification message array. If any message in the array is of type 'warning', a notifications icon in warning state will be shown. If any message in the array is of type 'error', a notifications icon in error state will be shown. A number will be shown within the notifications icon to indicate the number of messages. - -For information about the structure of notification messages, refer to the [message specification documentation](/2.4.4-Notification-Message-Specification). Notification messages can be added and removed from the notification panel by calling the canvas controller API. Refer to the canvas controller API documentation for information on how to [add/set messages in the notification message array](/2.4-Canvas-Controller-API#notification-messages-methods). - -# Context Menu Config object - -The context menu config object configures whether certain actions are available in the default context menu. - -```js - const contextMenuConfig = { - enableCreateSupernodeNonContiguous: false, - defaultMenuEntries: { - saveToPalette: true, - createSupernode: false, - displaySupernodeFullPage: true, - colorBackground: false - } - }; -``` - -* **enableCreateSupernodeNonContiguous** - Allows the creation of supernodes from non-contiguous nodes. When set to `true`, the "Create supernode" menu item will be added to the default context menu when the currently selected nodes are contiguous or non-contiguous. When set to `false`, the "Create supernode" menu item is only added to the default context menu when the selected nodes are contiguous. The default value is `false`. - -* **defaultMenuEntries** - Controls what entries are generated in the default context menu generated by common canvas. This has the following properties: - * 'saveToPalette' - This is a boolean. The default is false. If set to true, common canvas will add a 'Save to palette' option to the default node context menu. - * 'createSupernode' - This is a boolean. The default is true. If set to false, common canvas will not show the 'Create Supernode' option in the default context menu for nodes. - * 'displaySupernodeFullPage' - This is a boolean. The default is true. If set to false, common canvas will not show the 'Display full page' option in the default context menu for supernodes. When true, the option will be displayed. Clicking that option navigates the user to the full page view of the supernode's pipeline as if the user had clicked the expansion icon of the expanded in-place supernode view. - * 'colorBackground' - This is a boolean. The default is true. If set to false, common canvas will not show the 'Color background' option in the default context menu for comments. When true, the option will be displayed. - -[Note: If any host app wants more control over the default context menu here, please open an issue.] - -# Keyboard Config object - -The keyboard config object configures whether certain actions are available from the keyboard. -See this section for what [key combinations are supported](/2.0-Common-Canvas-Documentation#keyboard-support) -```js - const keyboardConfig = { - actions: { - delete: false, - undo: false, - redo: false, - selectAll: false, - cutToClipboard: false, - copyToClipboard: false, - pasteFromClipboard: false - }; -``` -All actions are `true` by default so it is only necessary to specify those actions you don't want as `false`. \ No newline at end of file diff --git a/guide/2.2-Common-Canvas-callbacks.md b/guide/2.2-Common-Canvas-callbacks.md deleted file mode 100644 index e957901eca..0000000000 --- a/guide/2.2-Common-Canvas-callbacks.md +++ /dev/null @@ -1,704 +0,0 @@ -# Event listener callbacks - -You can *optionally* provide callback listeners. These will be called when the user interacts with the canvas. - -These listeners are as follows: - -## contextMenuHandler -```js - contextMenuHandler(source, defaultMenu) -``` -This callback is used for both 'context menus' and, if the [`enableContextToolbar`](/2.1-Config-Objects#enablecontexttoolbar) canvas config option is set to `true`, for 'context toolbars'. - -If this callback is not provided common canvas will handle context menu/toolbars, and their actions, internally. You only need to implement this callback if you want to add or remove options to/from the context menu/toolbar. - -The job of this callback is to tell common canvas what items to display in the context menu/toolbar. - -### For Context Menu - -For context menus this will be dependent on what object or set of objects the context menu was requested for by the user. - -This callback will be called if the user performs a context menu gesture (such as mouse 'right click') on a: - -* node -* link -* comment -* port -* on the canvas background or -* if a number of objects are selected, the combination of objects. - -This callback must return an array that defines the menu to be displayed. If the callback is *not* provided, a default context menu (the defaultMenu passed into the handler) will be displayed by the common canvas. - -The source object passed in looks like this: -```js - { - type: "node", - targetObject: {}, - selectedObjectIds: ["node_1", "node_2"], - mousePos: {x: "10", y:"20"} - } -``` -**type** - Indicates type of object for which the context menu was selected. Can be "node", "port", "link", "canvas" or "comment" - -**targetObject** - The object for which the context menu was requested. Only provided when type is "node" or "comment" - -**selectedObjectIds** - An array containing the IDs of all currently selected nodes and/or comments - -**mousePos** - An object containing the coords of the mouse when the context menu was requested - -The callback would need to return an array, that describes the context menu to be displayed, that looks something like this: -```js - [ - {action: "deleteSelectedObjects", label: "Delete"}, - {divider: true}, - {action: "myAction", label: "My Action"} - {action: "myUnavailableAction", label: "A test disabled item", enable: false} - ] -``` -There is one element in the array for each entry in the context menu. An entry can be either a context menu item, which consists of a label and an action, or a divider, whose field would need to be set to true. - -Actions can be either internal (implemented inside the common canvas, like "deleteSelectedObjects" above) or external (like "myAction"). - -Existing internal actions are: - -* selectAll -* cut -* copy -* paste -* undo -* redo -* createSupernode -* expandSupernode -* collapseSupernode -* deleteSelectedObjects -* createComment -* deleteLink -* disconnectNode -* highlightBranch -* highlightDownstream -* highlightUpstream -* unhighlight - -External actions are custom actions you want common canvas to display for your application. To get common canvas to display your action you would need to return an array from the callback that includes a menu item for the action. - -When the user clicks the option in the context menu matching your action common canvas will call the [editActionHandler](#editactionhandler) callback so you'll need to implement some code in that callback to execute the intended action. If you want to simply add your action to the default context menu provided by common canvas you can take the defaultMenu parameter provided to the callback and add your menu item to it. Alternatively, you can provide a complete new context menu of your own. - -Here is a sample implementation of contextMenuHandler, which takes a source object (described above) and the defaultMenu as parameters, and adds a custom action to the default menu when the user 'right clicks' the canvas background. - -```js - contextMenuHandler(source, defaultMenu) { - let customMenu = defaultMenu; - if (source.type === "canvas") { - customMenu = customMenu.concat({ action: "myAction", label: "My Action" }); - } - return customMenu; - } -``` -In addition to adding the context menu item, you would also need to implement the editActionHandler callback to execute the action, like this: -```js - editActionHandler(data) { - if (data.editType === "myAction") { - // Execute my action code here. - } - } -``` -Tip: To avoid any future name clashes with internal actions you should make sure you action names are unique. For example, you could add a prefix to your action names eg. `$MyApp_action` where `$MayApp_` is the prefix for all your actions. - -### For Context Toolbar - -For context toolbars, this will be dependent on which object the mouse cursor is currently hovering over (which may be different to any of the currently selected objects). - - -## editActionHandler -```js - editActionHandler(data, command) -``` -This callback is optional. You don't *need* to implement anything for it and it doesn't return anything. It is called whenever the user does the following types of action on the canvas: - -* Clicks a tool in the toolbar. -* Clicks an option in the context menu. -* Presses a [key combination](/2.0-Common-Canvas-Documentation#keyboard-support) on the keyboard to cause the canvas to change. -* Performs some direct manipulation on the canvas such as: - * Creates a node (createNode) - * Moves one or a set of nodes/comments (moveObjects) - * Edits a comment (editComment) - * Links two nodes together (linkNodes) - * Links a comment to a node (linkComment) - * Resizes a supernode (resizeObjects) - * Resizes a comment (editComment) - * Expands a supernode in place (expandSuperNodeInPlace) - * Navigates into a sub-flow in a supernode (displaySubPipeline) - * Navigates out of a sub-flow in a supernode (displayPreviousPipeline) - - -This callback is called *after* the common-canvas internal object model has been updated. This callback is provided with two parameters: `data` and `command`. - -1. **data parameter** - that looks like this. The data provided can vary depending on the action the user performed. -```js - { - editType: "createComment", - editSource: "contextmenu", - selectedObjects: [], - selectedObjectIds: [], - offsetX: 100, - offsetY: 42 - } -``` - - + ***editType*** - This is the action that originates from either the toolbar, context menu, keyboard action or direct manipulation on the canvas. If you specified your own action in the context menu or in the toolbar this field will be your action's name. - - + ***editSource*** - This is the source of the action. It can be set to "toolbar", "contextmenu", "keyboard" or "canvas" (for an action caused by direct manipulation on the canvas). - - + ***selectedObjects*** - An array of the currently selected objects. - - + ***selectedObjectIds*** - An array of the IDs of currently selected objects. Included for backward compatibility. - - + ***Other fields*** - Numerous other fields which vary based on the action and the source of the action. - -2. **command parameter** - This is a Javascript class which is the command object that was added to the command stack and executed to run the action 'requested' by the user. If the user performed an `undo` action this will be the command that has been undone. If the user performed a `redo` action this will be the command that was redone. The command object may contain fields which are connected with the execution of the command. - -## beforeEditActionHandler -```js - beforeEditActionHandler(data, command) -``` -This callback is optional. You don't *need* to implement anything for it but if you do implement it you **must** return either a data object or null. This callback is called in all the same instances where `editActionHandler` is called. The difference is that this callback is called *before* the internal object model is updated. This gives your application the opportunity to examine the action that is about to be performed and either: let it continue; modify it and let it continue; or cancel it. - - This callback is provided with two parameters: `data` and `command`. - -1. **data parameter** - this is the same as the data object described for `editActionHandler` (see above) -2. **command parameter** - typically this will be null but for `undo` operations (that is where data.editType === "undo") this will be the command that is about to be undone. For `redo` operations (that is where data.editType === "redo") this will be the command that is about to be redone. - -This callback *must* return either the data object that was passed in or null. `beforeEditActionHandler` will behave as follows based on what is returned: - -* If the data object is returned unmodified: the action will be performed as normal. -* If the data object is returned modified: the action will be performed based on the modified data object. This means your application can alter the behavior of the action that will be performed. For example, you could intercept a `createNode` command and change the label for the new node in the nodeTemplate to something different. Then when the node is created the new label will be used. It is recommended you be **very** **very** careful when updating this object since there is no error checking in common-canvas to ensure you modified the object correctly. -* If `null` is returned: the action will be cancelled and not performed on the internal object model nor will `editActionHandler` be called. - -If you need to do any asynchronous activity in the beforeEditActionHandler callback you can: - -* Return null from the callback - which will cancel the current action -* Do your asynchronous activity. While this is happening, the user ought to be prevented from modifying the canvas so you should display some sort of progress indicator or modal dialog to inform the user that some activity is occurring. -* Then call `CanvasController.editActionHandler(data)` passing in the `data` object as a parameter with the modified properties. This will then execute the action as before. Note: This means the `beforeEditActionHandler` will be called a second time so be sure you put in a check to make sure you don't get into a loop. - -## clickActionHandler -```js - clickActionHandler(source) -``` -This callback is provided for your information. You don't need to implement anything for it and it doesn't need to return anything to common canvas. It is called whenever the user clicks or double clicks on something on the canvas. You could use this callback to implement opening a properties dialog when the user double clicks a node. - -Note: When handling selections, it is recommended the selectionChangeHandler be used in preference to this handler when possible. selectionChangeHandler will notify you of all selection changes regardless of how they occur, such as when the user presses Ctrl+A on the keyboard to select all objects. - -At the moment only click/double-click on nodes and the canvas background are returned. It is provided with one parameter that looks like this: -```js - { - clickType: "DOUBLE_CLICK" - id: "node_1", - objectType: "node", - selectedObjectIds: ["node_1", "node_2"] - } -``` -The fields can be: - -* clickType - This can be either "SINGLE_CLICK", "SINGLE_CLICK_CONTEXTMENU" or "DOUBLE_CLICK" -* objectType - Can be either "node", "comment", "canvas" or "region". "region" is specified when the user pulls out a selection rectangle around a set of objects that might include nodes and comments. -* id - The ID of the node or comment clicked. Only provided when objectType is "node" or "comment" -* selectedObjectIds - An array of the selected objects (after the click action was performed). - -Note: "SINGLE_CLICK_CONTEXTMENU" indicates that the user performed a contextmenu gesture when doing the click such as pressing the right-side mouse button or a two finger tap on a trackpad. - -## decorationActionHandler -```js - decorationActionHandler(object, id, pipelineId) -``` -Decorations are small images that can be displayed on or near to your nodes and links. They can be for display only or actionable (so the user can click on them). See the canvas JSON schema for information on how to define decorations for your nodes. - -This callback is called when the user clicks on an actionable decoration. You don't need to implement anything for this callback unless you added actionable decorations to your nodes. It doesn't return anything. It is called whenever the user clicks on a decoration that you added to a node in the canvas JSON. - -It is provided with two parameters: - -* object -- the node or link with which the decoration is associated. -* id -- the ID of the decoration that you provided in the canvas JSON -* pipelineId -- the ID of the pipeline for the node. - -## tipHandler -```js - tipHandler(tipType, data) -``` -Note: The display of tooltips (or not) can be controlled using the [`tipConfig`](/2.1-Config-Objects#tipconfig) field of the canvas config object. - -This optional callback can be implemented to override the tooltip content that is displayed by default for each canvas object. It is called before tips are shown for: palette categories, palette node templates, node, ports, links, decorations and the state tag. Common-canvas provides default implementations for all of the tips except for links and decorations, as follows: - -|Object | Default tip behavior | -|:--------|:----------------------| -| Palette category | Contains the category name and the category description. | -| Palette node template | Contains the category name, the node type and node description. | -| Node | Contains the name, description and status icon and optionally, if the name was modified from the original name, the original node type. | -| Port | The port label is shown | -| Link | No tip is shown by default | -| Decoration | No tip is shown by default | -| State tag | An appropriate explanation for the state displayed by the tag| - -To override the content, you can return either a string or JSX object. If your code returns `null` for a particular type of tip, common-canvas will display the default tip for that object. For an example of an implementation for a `tipHandler`, see App.js in the test harness code (https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/client/App.js). - -Common-canvas calls the `tipHandler` callback with two parameters: - -- tipType - the type of the tip -- data - an object that describes the canvas element for which the tip was requested - -Here are some specific examples: - -#### Palette categories: - - - tipType: "tipTypePaletteCategory" - - data: An object with category information, like this: - -```js -{ - category: { - id: "1234", - label: "Import", - description: "Category for import nodes", - image: "/images/import.svg" - } -} -``` - -#### Palette nodes templates: - - - tipType: "tipTypePaletteItem" - - data: An object with node template information: -```js -{ - nodeTemplate: { - label: "C50", - description: "C50 Model", - operator_id_ref: "com.ibm.commonicons.models.c50", - type: "model_node", - image: "/images/common_node_icons/models/model_c50.svg", - input_ports: [{...}], - output_ports: [] - } -} -``` -#### Nodes: - - tipType: "tipTypeNode" - - data: An object with pipelineId and node information: -```js -{ - pipelineId: "153651d6-9b88-423c-b01b-861f12d01489", - node: { - id: "idGWRVT47XDV", - type: "execution_node", - operator_id_ref: "type", - output_ports: [...], - input_ports: [...], - label: "Define Types", - description: "", - image: "", - x_pos: 445, - y_pos: 219 - } -} -``` - -#### Ports: - - - tipType: "tipTypePort" - - data: An object with pipelineId, node and port information: -```js -{ - pipelineId: "153651d6-9b88-423c-b01b-861f12d01489", - node: { - id: "idGWRVT47XDV", - type: "execution_node", - operator_id_ref: "type", - output_ports: [{...}], - input_ports: [{...}], - label: "Define Types", - description: "", - image: "", - x_pos: 445, - y_pos: 219 - }, - port: { - id: "outPort", - label: "Output Port" - } -} -``` - -#### Links - - tipType: "tipTypeLink" - - data: An object with pipelineId and link information. -```js -{ - pipelineId: "153651d6-9b88-423c-b01b-861f12d01489", - link: { - id: "canvas_link_3", - x1: 515, - y1: 248, - x2: 611, - y2: 180, - class_name: "canvas-data-link", - type: "nodeLink", - src: { - id: "idGWRVT47XDV", - type: "execution_node", - operator_id_ref: "type", - output_ports: [{...}], - input_ports: [{...}], - label: "Define Types", - description: "", - image: "", - x_pos: 445, - y_pos: 219 - }, - srcPortId: "outPort", - trg: { - id: "id8I6RH2V91XW", - type: "binding", - operator_id_ref: "c50", - output_ports: [], - input_ports: [{...}], - label: "C5.0", - description: "", - image: "", - x_pos: 611, - y_pos: 151 - }, - trgPortId: "inPort" - } -} -``` - -#### Decorations - - tipType: "tipTypeDec" - - data: An object with pipelineId and decoration information. -```js -{ - pipelineId: "153651d6-9b88-423c-b01b-861f12d01489", - decoration: { - "id": "2016", - "position": "topRight", - "label": "LCFC", - "tooltip": "Foxes never quit" - } -} -``` - -#### State tag - - tipType: "tipTypeStateTag" - - data: An object with pipelineId and decoration information. -```js -{ - stateTagText: "This flow is locked and cannot be edited.", - stateTagType: "Locked" -} -``` - - - -## idGeneratorHandler -```js - idGeneratorHandler(action, data) -``` -This callback is called when new objects are created in the canvas and allows the user to provide their own method to generate a unique id for the object. If no idGeneratorHandler is set or the method returns null, a UUID is generated by common-canvas. The method is called with a string for the action that was performed (create node/comment/link, clone node/comment/link) and a JSON object with additional data. - -* create node: - * action: create_node - * data: - - -```js -nodeType: -{ - "label":"C50", - "description":"C50 Model", - "operator_id_ref":"com.ibm.commonicons.models.c50", - "type":"model_node", - "image":"/images/common_node_icons/models/model_c50.svg", - "input_ports":[ - { - "id":"inPort", - "label":"Input Port", - "cardinality":{ - "min":0, - "max":1 - } - } - ], - "output_ports":[ - - ] -} -``` - -* create comment: - - * action: create_comment - * data: n/a - -* create node link: - * action: create_node_link - * data: - -```js -sourceNode: { - "id":"6a547456-f1ea-48a6-9721-45d6ae70dd6b", - "label":"Aggregate", - "type":"execution_node", - "operator_id_ref":"com.ibm.commonicons.operations.aggregate", - "image":"/images/common_node_icons/operations/operation_aggregate.svg", - "class_name":"d3-node-body", - "input_ports":[...], - "output_ports":[...], - "x_pos":55, - "y_pos":97.5, - "inputPortsHeight":20, - "outputPortsHeight":20, - "height":75, - "width":70 -}, -targetNode: { - "id":"71c96629-be46-418b-be63-0a02ef2fe2e0", - "label":"Append", - "type":"execution_node", - "operator_id_ref":"com.ibm.commonicons.operations.append", - "image":"/images/common_node_icons/operations/operation_append.svg", - "class_name":"d3-node-body", - "input_ports":[...], - "output_ports":[...], - "x_pos":264, - "y_pos":83.5, - "inputPortsHeight":20, - "outputPortsHeight":20, - "height":75, - "width":70 -} -``` - -- create comment link: - * action: create_comment_link - * data: - -```js -comment: { - "id":"8c81aac7-ebe5-4f96-9d63-eabc22b09635", - "class_name":"d3-comment-rect", - "content":"", - "height":42, - "width":175, - "x_pos":50, - "y_pos":50 -}, -targetNode: { - "id":"71c96629-be46-418b-be63-0a02ef2fe2e0", - "label":"Append", - "type":"execution_node", - "operator_id_ref":"com.ibm.commonicons.operations.append", - "image":"/images/common_node_icons/operations/operation_append.svg", - "class_name":"d3-node-body", - "input_ports":[...], - "output_ports":[...], - "x_pos":264, - "y_pos":83.5, - "inputPortsHeight":20, - "outputPortsHeight":20, - "height":75, - "width":70 -} -``` - -- clone node: triggered when copying&pasting a node - * action: clone_node - * data: - -```js -node: { - "id":"56d30c83-3a08-4147-933e-b01d3c348ac1", - "label":"Append", - "type":"execution_node", - "operator_id_ref":"com.ibm.commonicons.operations.append", - "image":"/images/common_node_icons/operations/operation_append.svg", - "class_name":"d3-node-body", - "input_ports":[...], - "output_ports":[...], - "x_pos":265, - "y_pos":177.5, - "inputPortsHeight":20, - "outputPortsHeight":20, - "height":75, - "width":70 -} -``` - -- clone comment: triggered when copying&pasting a comment - * action: clone_comment - * data: - -```js -comment: { - "id":"8c81aac7-ebe5-4f96-9d63-eabc22b09635", - "class_name":"d3-comment-rect", - "content":"", - "height":42, - "width":175, - "x_pos":50, - "y_pos":50 -} -``` - -- clone node link: triggered when copying&pasting two connected nodes - * action: clone_node_link - * data: - -```js -link: { - "id":"12c4308e-f572-402a-8dd3-604d438539d4", - "class_name":"d3-data-link", - "srcNodeId":"2b1af6c2-f98b-4728-97b3-416d40224bce", - "trgNodeId":"b43fffe6-dc01-4d30-8b6d-abd977850a2e", - "type":"nodeLink" -}, -sourceNodeId: "56d30c83-3a08-4147-933e-b01d3c348ac1", -targetNodeId: "815271f0-f4da-4793-ab8f-c4c32d3dd7e0" -``` -Note that the link to be cloned has references to the original source and target nodes, while the sourceNodeId and targetNodeId are the new node ids for the copied nodes. The new nodes are not part of the model yet. - -- clone comment link: triggered when copying&pasting a comment and a node that are connected - * action: clone_comment_link - * data: - -```js -link: { - "id":"12c4308e-f572-402a-8dd3-604d438539d4", - "class_name":"d3-comment-link", - "srcNodeId":"2b1af6c2-f98b-4728-97b3-416d40224bce", - "trgNodeId":"b43fffe6-dc01-4d30-8b6d-abd977850a2e", - "type":"commentLink" -}, -sourceNodeId: "56d30c83-3a08-4147-933e-b01d3c348ac1", -targetNodeId: "815271f0-f4da-4793-ab8f-c4c32d3dd7e0" -``` -Note that the link to be cloned has references to the original comment and target node, while the sourceNodeId and targetNodeId are the new ids for the copied comment and node. The new node and comment are not part of the model yet. - -## selectionChangeHandler -```js - selectionChangeHandler(data) -``` -The selectionChangeHandler callback is triggered whenever the selection in the canvas changes. The callback contains a JSON object with the following format: -``` -{ - "selection": [ - "id6PXRG57DGIV" - ], - "selectedNodes": [ - { - "id": "id6PXRG57DGIV", - "type": "binding", - "operator_id_ref": "variablefile", - "output_ports": [...], - "input_ports": [], - "label": "DRUG1n", - "description": "", - "image": "", - "x_pos": 96, - "y_pos": 219, - "class_name": "canvas-node", - "decorations": [], - "parameters": [], - "messages": [], - "inputPortsHeight": 0, - "outputPortsHeight": 20, - "height": 75, - "width": 70 - } - ], - "selectedComments": [], - "addedNodes": [ - { - "id": "id6PXRG57DGIV", - "type": "binding", - "operator_id_ref": "variablefile", - "output_ports": [...], - "input_ports": [], - "label": "DRUG1n", - "description": "", - "image": "", - "x_pos": 96, - "y_pos": 219, - "class_name": "canvas-node", - "decorations": [], - "parameters": [], - "messages": [], - "inputPortsHeight": 0, - "outputPortsHeight": 20, - "height": 75, - "width": 70 - } - ], - "addedComments": [], - "deselectedNodes": [ - { - "id": "id2PZSCTRPRIJ", - "type": "execution_node", - "operator_id_ref": "derive", - "output_ports": [...], - "input_ports": [...], - "label": "Na_to_K", - "description": "", - "image": "", - "x_pos": 219.01116943359375, - "y_pos": 162.3754425048828, - "class_name": "canvas-node", - "decorations": [], - "parameters": [], - "messages": [...], - "inputPortsHeight": 20, - "outputPortsHeight": 20, - "height": 75, - "width": 70 - } - ], - "deselectedComments": [ - { - "id": "id42ESQA3VPXB", - "content": " comment 1", - "height": 34, - "width": 128, - "x_pos": 132, - "y_pos": 103, - "class_name": "canvas-comment-1" - } - ], - previousPipelineId: "123-456", - selectedPipelineId: "789-012" -} -``` - -- selection: Array with ids of selected nodes and comments -- selectedNodes: Array of selected node objects -- selectedComments: Array of selected comment objects -- addedNodes: Array with node objects that were added to the selection -- addedComments: Array with comment objects that were added to the selection -- deselectedNodes: Array with node objects that were removed from the selection -- deselectedComments: Array with comment objects that were removed from the selection -- previousPipelineId: The ID of the Pipeline for the selected objects prior to the selection action -- selectedPipelineId: The ID of the Pipeline for the newly selected objects - - -## layoutHandler -```js - layoutHandler(data) -``` -This is an optional handler you don't need to implement anything for it unless you want to. The layoutHandler callback, when provided, is called for each node on the canvas. The callback should return a Javascript object whose properties will override the default properties for node layout. The callback is provided with a parameter `data` which is the node object. Your code can look at the node properties and decide which properties it needs to override. This can be used to change the node shape, styling and position and size of node elements like the image, main label etc. - -For more details see: [Customizing Node Layout Properties](/2.7-Customizing-Node-Layout-Properties) - -## actionLabelHandler -```js - actionLabelHandler(action) -``` -This is an optional handler you don't need to implement anything for it unless you want to. This callback allows your code to override the default tooltip text for the `Undo` and `Redo` buttons. - -The `actionLabelHandler` callback, when provided, is called for each action that is performed in common-canvas. The `action` object parameter, passed in to the callback, contains details of the action being performed. This callback should return either a string or null. If a string is returned it will be shown in the tooltip for the `Undo` button in the toolbar preceded by "Undo:" and the string will also appear in the tooltip for the `Redo` button (when appropriate) preceded by "Redo:". If null is returned, common-canvas will display the default text for the `Undo` and `Redo` buttons. \ No newline at end of file diff --git a/guide/2.3-Enabling-node-creation-from-external-object.md b/guide/2.3-Enabling-node-creation-from-external-object.md deleted file mode 100644 index 146b622591..0000000000 --- a/guide/2.3-Enabling-node-creation-from-external-object.md +++ /dev/null @@ -1,77 +0,0 @@ -## Dragging object from within the browser -Common canvas supports the ability for an object from the your browser page to be dragged onto the canvas to initiate the creation of a node on the canvas. To do this you need to set the object you want to drag into the canvas to be draggable: - -```html -
- .... - .... -
-``` -and then specify the on drag behavior like this -```js - onDragStart(ev) { - const evData = { - operation: "addToCanvas", - data: { - editType: "createExternalNode", - field1: "field_val_1", - field2: "field_val_2" - .... - .... - } - }; - ev.dataTransfer.setData("text", JSON.stringify(evData)); - } -``` -where - -* operation - is always set to "addToCanvas" -* data - is the object that will be passed to the editActionHandler callback -* editType - this is the type of editing operation. You can set it to anything except any of the reserved settings which are: 'createNode', 'createNodeOnLink', 'createAutoNode' and 'createFromExternalObject'. -* fields - an optional number of fields can be provided that describe the object you are dragging onto the canvas. For example, if it is a data object the fields might describe the data source details. - -After the object has been dropped on the canvas your editActionHandler() callback method will be called with a parameter data object that contains the fields you specified in `data` in the drag data along with three additional fields, called pipelineId, offsetX and offsetY, containing the x,y co-ordinates of where the drop occurred. In your editActionHandler() method you can use the CanvasController API to add a node to the pipeline flow and get common canvas to display it. - -## Dragging object from the desktop or another application -If an object from the desktop or another application is dropped on the canvas your editActionHandler(data) method will be called with the `data` parameter set to an object like this: -```js - { - dataTransfer: , - editType: "createFromExternalObject", - editSource: "canvas", - offsetX: 200, - offsetY: 100, - pipelineId: "1234-5678" - } -``` -Your code can examine the `dataTransfer` object to see what object was dragged onto the canvas and then take appropriate action. - -If you want a new node to appear on the canvas as a result of the object being dropped your code will need to create that node at the point where the drop occurred, using the Canvas Controller API. Here is some sample code that will - -* create a new node template based on the "variablefile" node in the palette data -* set the label of the node to be created to the name of the file being dropped -* create a new node on the canvas at the offsetX, offsetY position -* the command will be added to the command-stack so the user can click undo to undo the addition of the node - -`data` is the parameter passed into your `editActionHandler` method. -```js - if (data.editType === "createFromExternalObject") { - const nodeTemplate = canvasController.getPaletteNode("variablefile"); - if (nodeTemplate) { - const convertedTemplate = canvasController.convertNodeTemplate(nodeTemplate); - convertedTemplate.label = data.dataTransfer.files[0].name; - const action = { - editType: "createNode", - nodeTemplate: convertedTemplate, - pipelineId: data.pipelineId, - offsetX: data.offsetX, - offsetY: data.offsetY - }; - canvasController.editActionHandler(action); - } -``` - -Tip: You can optionally instruct common canvas to display a graphic over the canvas as the external object is being dragged over it. To do this you need to specify the [`enableDropZoneOnExternalDrag`](/2.1-Config-Objects#enabledropzoneonexternaldrag) configuration parameter. \ No newline at end of file diff --git a/guide/2.4-Canvas-Controller-API.md b/guide/2.4-Canvas-Controller-API.md deleted file mode 100644 index ce8cd4626a..0000000000 --- a/guide/2.4-Canvas-Controller-API.md +++ /dev/null @@ -1,945 +0,0 @@ -# Canvas Controller API - -Your application code can programmatically perform many of the actions that the user can do in the common canvas using the Canvas Controller API. -Note: See this section for differences between [the structure of objects in the API and the schema.](/2.4.3-Object-structure-used-by-API#api-differences-with-schema) - -Also, this section discusses different [techniques for calling the canvas controller API](/2.4.0-Calling-the-Canvas-Controller-API). - -In most cases within the API, the pipelineId parameter is optional. If pipelineId is omitted, the method will default to the pipeline that is currently displayed in the main canvas viewport. - -Warning 1: Do not alter the IDs of objects that currently exist on the canvas. Changing object IDs can cause internal problems, in particular with the command stack. - -Warning 2: When using external pipeline flows, Pipeline IDs must be globally unique identifiers. - -The API provides the following: -## Pipeline Flow methods -```js -// Loads the pipelineFlow document provided into common-canvas and displays it. -// The document must conform to the pipelineFlow schema as documented in the -// elyra-ai pipeline-schemas repo. Documents conforming to older versions may be -// provided but they will be upgraded to the most recent version. -setPipelineFlow(flow) - -// Clears the pipleine flow and displays an empty canvas. -clearPipelineFlow() - -// Returns the current pipelineFlow document in the latest version of the -// pipelineFlow schema as documented in the elyra-ai pipeline-schemas repo. -getPipelineFlow() - -// Returns the current pipelineFlow document ID. -getPipelineFlowId() - -// Returns the ID of the primary pipeline from the pipelineFlow. -getPrimaryPipelineId() - -// Returns the external pipeline flow for the url passed in. The external -// flow must have been loaded through some common canvas action for this -// method to be able to return anything. -getExternalPipelineFlow(url) - -// Returns the internal format of all canvas data stored in memory by -// common-canvas. Nodes, comments and links are returned in the internal -// format. -getCanvasInfo() - -// Returns the IDs of the ancestor pipleline of the pipeline ID passed in. -getAncestorPipelineIds(pipelineId) - -// Removes all styles from nodes, comments and links. See the setObjectsStyle -// and setLinkStyle methods for details on setting styles. -// temporary - is a boolean that indicates whether temporary or permanent -// styles should be removed. -removeAllStyles(temporary) - -// Specifies the new styles for objects that are not highlighted during -// branch highlighting. -// newStyle - is a style specification object. See wiki for details. -setSubdueStyle(newStyle) - -``` - -## Pipeline methods -```js -// Returns the pipeline object for the pipeline Id passed in. -getPipeline(pipelineId) - -// Returns the ID of the pipeline object which is currently on display -// in the canvas. Typically, this is the primary pipeline but will be -// different if the user has navigated into one or more supernodes; in -// which case it will be the ID of the pipeline at the level in the -// supernode hierarchy that is currently on display. -getCurrentPipelineId() - -// Returns truty if the pipeline is external (that is it is part of an -// external pipeline flow). Otherwise, return falsy to indicate the pipeline -// is local. -isPipelineExternal(pipelineId) - -// Returns the flow validation messages for the pipeline ID passed in. -getFlowMessages(pipelineId) - -// Returns a boolean to indicate whether there are any messages of -// includeMsgsType in the pipeline identified by the pipeline ID passed in. -// includeMsgsType - can be either "error" or "warning" -isFlowValid(includeMsgTypes, pipelineId) - -// Rearranges the nodes in the canvas in the direction specified for the -// pipeline ID passed in. -// layoutDirection - can be "horizontal" or "vertical" -autoLayout(layoutDirection, pipelineId) -``` - -## Palette methods -```js -// Loads the palette data as described in the palette schema in -// elyra-ai pipeline-schemas repo. Any version can be loaded and it will be -// upgraded to the latest version. -setPipelineFlowPalette(palette) - -// Clears the palette data from common-canvas. -clearPaletteData() - -// Sets the loading text of the category. If set to a non-empty string the -// category will show an InlineLoading control in the palette category div -// with this text as the label. If set to falsey the palette category -// will display as normal. -setCategoryLoadingText(categoryId, loadingText) - -// Sets the empty text of the category. If set to a non-empty string and the -// category does not have any nodes, the palette will show a warning icon with -// this text as a message under the category title when the category is opened. -// This message will not be displayed if the field is set to falsey or if -// nodetypes are added to the category. -setCategoryEmptyText(categoryId, emptyText) - -// Adds a new node into the palette: -// nodeTypeObj - must conform to the style of node used by the palette as -// described in the palette schema. See objects in nodeTypes array in the -// palette schema: -// https://github.com/elyra-ai/pipeline-schemas/blob/master/common-canvas/palette/palette-v3-schema.json -// category - is the name of the palette category where the node will be -// added. If the category doesn't exist it will be created. -// categoryLabel - Is an optional param. If a new category is created it will -// be displayed with this label. -// categoryDescription - Is an optional param. If a new category is created -// it will be displayed with this description. -// categoryImage - Is an optional param. The image displayed for the category provided as a -// reference to an image or the image itself. -addNodeTypeToPalette(nodeTypeObj, categoryId, categoryLabel, categoryDescription, categoryImage) - -// Adds an array of new node into the palette: -// nodeTypeObjs - an array of nodetypes that must conform to the style of -// nodes used by the palette as described in the palette schema. See objects -// in nodeTypes array in the palette schema: -// https://github.com/elyra-ai/pipeline-schemas/blob/master/common-canvas/palette/palette-v3-schema.json -// category - is the name of the palette category where the node will be -// added. If the category doesn't exist it will be created. -// categoryLabel - is an optional param. If a new category is created it will -// be displayed with this label. -// categoryImage - the image displayed for the category provided as a -// reference to an image or the image itself. -// categoryDescription - Is an optional param. If a new category is created -// it will be displayed with this description. -// categoryImage - Is an optional param. The image displayed for the category provided as a -// reference to an image or the image itself. -addNodeTypesToPalette(nodeTypeObjs, categoryId, categoryLabel, categoryDescription, categoryImage) - -// Removes nodetypes from a palette category -// selObjectIds - an array of object IDs to identify the nodetypes to be -// removed -// categoryId - the ID of teh category from which the nodes will be removed -removeNodesFromPalette(selObjectIds, categoryId) - -// Returns the palette data document which will conform to the latest version -// of the palette schema. -getPaletteData() - -// Returns the palette node identified by the operator ID passed in. -getPaletteNode(operatorId) - -// Returns the palette node identified by the node ID passed in. -getPaletteNodeById(nodeId) - -// Returns the category of the palette node identified by the operator passed in -getCategoryForNode(nodeOpIdRef) - -// Converts a node template from the format use in the palette (that conforms -// to the schema) to the internal node format. -convertNodeTemplate(nodeTemplate) - -// Opens the palette category identified by the category ID passed in. -openPaletteCategory(categoryId) - -// Closes the palette category idetified by the category ID passed in. -closePaletteCategory(categoryId) - -// Opens all the palette categories. -openAllPaletteCategories() - -// Closes all the palette categories. -closeAllPaletteCategories() - -// Returns true or false to indicate whether a palette category is open or not. -isPaletteCategoryOpen(categoryId) -``` - -## Selections methods -```js -// Sets the currently selected objects replacing any current selections. -// newSelection - An array of object IDs for nodes and/or comments -// pipelineId - Optional. The ID of the pipeline where the objects exist. -// Selected objects can only be in one pipeline. If this parameter is omitted -// it is assumed the selections will be for objects in the 'top-level' pipeline -// being displayed. -setSelections(newSelection, pipelineId) - -// Clears all the current selections from the canvas. -clearSelections() - -// Selects all the objects on the canvas. -selectAll() - -// Returns an array of the IDs of the currently selected objects. -getSelectedObjectIds() - -// Returns the currently selected Nodes. -getSelectedNodes() - -// Returns the currently selected Comments. -getSelectedComments() - -// Returns the ID of the pipeline in which the currently selected objects -// exist. Only one pipeline may contain selected objects. -getSelectedPipelineId() - -// Deletes all currently selected objects. -deleteSelectedObjects() - -// Returns true if the currently selected objects are all linked together. -// This is used when deciding to creating a supernode. -areSelectedNodesContiguous() -``` - -## Notification messages methods - -The notification panel is displayed by the user by clicking the notifications icon in the toolbar. Your application can display whatever messages it wants in the notification panel. See the [Notification Messages Specification](/2.4.4-Notification-Message-Specification) documentation for the structure of message objects. The contents of the notification panel can be managed using the methods below: -```js -// Overwrites the array of notification messages shown in the notification -// panel. -// newMessage - An array of messages (see getNotificationMessages) -setNotificationMessages(newMessages) - -// Deletes all notification messages shown in the notification panel. -clearNotificationMessages() - -// Removes the notification messages from the given array of ids -deleteNotificationMessages(ids) - -// Returns the array of current notification messages. If the messageType is -// provided only messages of that type will be returned. If messageType is -// not provided, all messages will be returned. The format of a notification -// message is an object with these fields: -// { -// "id": string (Required), -// "type" : enum, oneOf ["info", "success", "warning", "error"] (Required), -// "callback": function, the callback function when a message is clicked (Required), -// "title": string (Optional), -// "content": string, html, JSX Object (Optional), -// "timestamp": string (Optional), -// "closeMessage": string (Optional) -// } -getNotificationMessages(messageType) - -// Returns the maximum notification message type present in the current set -// of notification messages. For this: ("error" > "warning" > "success" > "info") -getNotificationMessagesMaxType() -``` - -## Node AND comment methods -In common-canvas nodes and comments are collectively known as objects. The following methods may be used to manage either collections of comments or nodes or a mixture of both. -Note: - -* See this sections if you are working with [styles.](/2.4.1-Style-Specification) -* See this section if you are working with [decorations.](/2.4.2-Decoration-Specification) -* See this section for differences between [the structure of objects in the API and the schema.](/2.4.3-Object-structure-used-by-API#api-differences-with-schema) -```js -// Moves the objects identified in the data object which must be in the -// pipeline identified by the pipeline ID. -// data - A javascript object like this: -// { -// nodes: [] // An array of node and comment IDs -// offsetX: number // Offset in pixels the objects will move in the X dir -// offsetY: number // Offset in pixels the objects will move in the Y dir -// } -moveObjects(data, pipelineId) - -// Deletes the objects specified in objectIds array. -// objectIds - An array of node and comment IDs -deleteObjects(objectIds, pipelineId) - -// Removes the links to and from the objects specified in the objectIds array. -// objectIds - An array of node and comment IDs -disconnectObjects(objectIds, pipelineId) - -// Deletes the object specified by the id in the pipleine specified by -// pipeline ID. -// @Deprecated Use deleteNode or deleteComment as appropriate instead. -deleteObject(id, pipelineId) - -// Sets the style of the objects specified by pipelineObjectIds to be -// the newStyle which will be either temporary or permanent. -// pipelineObjectIds: This identified the objects to be styles. It is a -// javascript object like this: -// { -// : [ -// , -// -// ], -// : [ -// , -// -// ] -// } -// newStyles - This is a style specification. See the wiki for details. -// temporary - A boolean to indicate if the style is serialized when -// getPipelineFlow() method is called or not. -setObjectsStyle(pipelineObjectIds, newStyle, temporary) - -// Sets the styles of multiple objects at once. -// pipelineObjStyles - Specified the objects and the styles each should be -// set to. It is a javascript array like this: -// [ -// { pipelineId: , objId: , style: }, -// { pipelineId: , objId: , style: }, -// { pipelineId: , objId: , style: } -// ] -// temporary - A boolean to indicate if the styles are serialized when -// getPipelineFlow() method is called or not. -setObjectsMultiStyle(pipelineObjStyles, temporary) -``` -## Node methods -```js -// Retuns an array of nodes for the pipeline specified by the pipelineId. -getNodes(pipelineId) - -// Returns a new node created from the data parameter in the pipeline -// identified by the pipelineId. -// The data parameter must contain: -// nodeTemplate - a node template from the palette. The nodeTemplate -// can be retrieved from the palette using with Canvas -// Controller methods: getPaletteNode or getPaletteNodeById. -// offsetX - the x coordinate of the new node -// offsetY - the y coordinate of the new node -createNode(data, pipelineId) - -// Adds a new node into the pipeline specified by the pipelineId. -addNode(node, pipelineId) - -// Creates a node using the data parameter provided in the pipeline specified -// by pipelineId and adds the command to the command stack (so the user can -// undo/redo the command). This will also cause the beforeEditActionHandler -// and editActionHandler callbacks to be called. -// The data parameter must contain: -// nodeTemplate - a node template from the palette. The nodeTemplate -// can be retrieved from the palette using with Canvas -// Controller methods: getPaletteNode or getPaletteNodeById. -// offsetX - the x coordinate of the new node -// offsetY - the y coordinate of the new node -// -// If pipelineId is omitted the node will be created in the current -// "top-level" pipeline. -createNodeCommand(data, pipelineId) - -// Deletes the node specified. -// nodeId - The ID of the node -// pipelineId - The ID of the pipeline -deleteNode(nodeId, pipelineId) - -// Sets the node properties -// nodeId - The ID of the node -// properties - An object containing properties to be overriden in the node -// pipelineId - The ID of the pipeline -setNodeProperties(nodeId, properties, pipelineId) - -// Sets the node parameters -// nodeId - The ID of the node -// parameters - An array of parameters -// pipelineId - The ID of the pipeline -setNodeParameters(nodeId, parameters, pipelineId) - -// Sets the node UI parameters -// nodeId - The ID of the node -// parameters - An array of UI parameters -// pipelineId - The ID of the pipeline -setNodeUiParameters(nodeId, uiParameters, pipelineId) - -// Sets the node messages -// nodeId - The ID of the node -// messages - An array of messages -// pipelineId - The ID of the pipeline -setNodeMessages(nodeId, messages, pipelineId) - -// Sets a single message on a node -// nodeId - The ID of the node -// message - A message -// pipelineId - The ID of the pipeline -setNodeMessage(nodeId, message, pipelineId) - -// Sets the lable for a node -// nodeId - The ID of the node -// ndeLabel - The label -// pipelineId - The ID of the pipeline -setNodeLabel(nodeId, newLabel, pipelineId) - -// Sets the class name to newClassName of the nodes identified by nodeIds -// array in the pipleine specified by pipeline ID. The class name will be -// applied to the node body path. -setNodesClassName(nodeIds, newClassName, pipelineId) - -// Sets the decorations on a node. The decorations array passed in -// will replace any decorations currently applied to the node. -// nodeId - The ID of the node -// newDecorations - An array of decorations. See Wiki for details. -// pipelineId - The ID of the pipeline -setNodeDecorations(nodeId, newDecorations, pipelineId) - -// Sets the input ports on a node. The inputs array of ports provided will -// replace any input ports for a node. -// nodeId - The ID of the node -// inputs - An array of input port objects. -// pipelineId - The ID of the pipeline -setNodeInputPorts(nodeId, inputs, pipelineId) - -// Sets the output ports on a node. The outputs array of ports provided will -// replace any output ports for a node. -// nodeId - The ID of the node -// outputs - An array of output port objects. -// pipelineId - The ID of the pipeline -setNodeOutputPorts(nodeId, outputs, pipelineId) - -// Sets the decorations of multiple nodes at once. The decorations array -// passed in will replace any decorations currently applied to the nodes. -// pipelineNodeDecorations - Specifies the nodes and their decorations. -// It is a JavaScript array like this: -// [ -// { pipelineId: , nodeId: , decorations: }, -// { pipelineId: , nodeId: , decorations: }, -// { pipelineId: , nodeId: , decorations: } -// ] -setNodesMultiDecorations(pipelineNodeDecorations) - -// Sets the input port label on a node -// nodeId - The ID of the node -// portId - The ID of the input port -// newLabel - The label -// pipelineId - The ID of the pipeline -setInputPortLabel(nodeId, portId, newLabel, pipelineId) - -// Sets the output port label on a node -// nodeId - The ID of the node -// portId - The ID of the output port -// newLabel - The label -// pipelineId - The ID of the pipeline -setOutputPortLabel(nodeId, portId, newLabel, pipelineId) - -// Gets a node -// nodeId - The ID of the node -// pipelineId - The ID of the pipeline -getNode(nodeId, pipelineId) - -// Gets the UI parameters for a node -// nodeId - The ID of the node -// pipelineId - The ID of the pipeline -getNodeUiParameters(nodeId, pipelineId) - -// Gets the supernodes for a pipeline. -// pipelineId - The ID of the pipeline -getSupernodes(pipelineId) - -// Returns supernode ID that has a subflow_ref to the given pipelineId. -getSupernodeObjReferencing(pipelineId) - -// Gets the messages for a node -// nodeId - The ID of the node -// pipelineId - The ID of the pipeline -getNodeMessages(nodeId, pipelineId) - -// Gets the array of input ports for the node or null if the node ID is -// not recognized. -// nodeId - The ID of the node -// pipelineId - The ID of the pipeline -getNodeInputPorts(nodeId, pipelineId) - -// Gets the array of output ports for the node or null if the node ID is -// not recognized. -// nodeId - The ID of the node -// pipelineId - The ID of the pipeline -getNodeOutputPorts(nodeId, pipelineId) - -// Gets a message for a specific control for a node -// nodeId - The ID of the node -// controlName - The control name -// pipelineId - The ID of the pipeline -getNodeMessage(nodeId, controlName, pipelineId) - -// Gets an array of decorations for a node -// nodeId - The ID of the node -// pipelineId - The ID of the pipeline -getNodeDecorations(nodeId, pipelineId) - -// Gets the class name associated with the node specified by nodeId in the -// pipeline specified by pipelineId. -getNodeClassName(nodeId, pipelineId) - -// Gets the style spcification (see Wiki) for a node -// nodeId - The ID of the node -// temporary - A boolean to indicate if the style is serialized when -// getPipelineFlow() method is called or not. -// pipelineId - The ID of the pipeline -getNodeStyle(nodeId, temporary, pipelineId) - -// Returns an array of nodes that are for the branch(es) that the nodes, -// identified by the node IDs passed in, are within. -// nodeIds - An array of node Ids -// pipelineId - The ID of the pipeline where the nodes exist -getBranchNodes(nodeIds, pipelineId) - -// Returns an array of nodes that are upstream from the nodes -// identified by the node IDs passed in. -// nodeIds - An array of node Ids -// pipelineId - The ID of the pipeline where the nodes exist -getUpstreamNodes(nodeIds, pipelineId) - -// Returns an array of nodes that are downstream from the nodes -// identified by the node IDs passed in. -// nodeIds - An array of node Ids -// pipelineId - The ID of the pipeline where the nodes exist -getDownstreamNodes(nodeIds, pipelineId) - -// Returns a boolean to indicate whether the supernode is expanded in place. -// nodeId - The ID of the node -// pipelineId - The ID of the pipeline -isSuperNodeExpandedInPlace(nodeId, pipelineId) - -// Sets the label, for the node identified, to edit mode, provided the node -// label is editable. This allows the user to edite the label text. -setNodeLabelEditingMode(nodeId, pipelineId) - -// Sets the decoration label, for the decoration in the node identified, to edit -// mode, provided the node label is editable. This allows the user to edit the -// label text. -setNodeDecorationLabelEditingMode(decId, nodeId, pipelineId) -``` -The format of the message object is described in [Pipeline Flow UI schema](https://github.com/elyra-ai/pipeline-schemas/blob/master/common-pipeline/pipeline-flow/pipeline-flow-ui-v1-schema.json) -## Comment methods -```js -// Returns the comments from the pipeline. -// pipelineId - The ID of the pipeline -getComments(pipelineId) - -// Returns a comment from the pipeline. -// comId - The ID of the comment -// pipelineId - The ID of the pipeline -getComment(comId, pipelineId) - -// Returns a position object which indicates the position of where a new -// comment should be placed in a situation where the mouse position cannot be -// used (e.g. the toolbar button was clicked). -// pipelineId - The ID of the pipeline -getNewCommentPosition(pipelineId) - -// Creates a comment for the pipeline. -// source - Input data -// pipelineId - The ID of the pipeline -createComment(source, pipelineId) - -// Adds a comment to the pipeline. -// data - the data describing the comment -// pipelineId - The ID of the pipeline -addComment(data, pipelineId) - -// Edits a comment with the data. -// data - the comment -// pipelineId - The ID of the pipeline -editComment(data, pipelineId) - -// Sets the properties in the comment identified by the commentId. The -// commentProperties is an object containing one or more properties that will -// replace the corresponding properties in the comment. For example: if -// commentProperties is { x_pos: 50, y_pos: 70 } the comment -// will be set to that position. -setCommentProperties(commentId, commentProperties, pipelineId) - -// Sets the class name to newClassName of the comments identified by commentIds -// array in the pipleine specified by pipeline ID. The class name will be -// applied to the comment body path. -setCommentsClassName(commentIds, newClassName, pipelineId) - -// Deletes a comment -// comId - The ID of the comment -// pipelineId - The ID of the pipeline -deleteComment(comId, pipelineId) - -// Gets the class name associated with the comment specified by commentId in the -// pipeline specified by pipelineId. -getCommentClassName(commentId, pipelineId) - -// Gets the style spcification (see Wiki) for a comment -// commentId - The ID of the node -// temporary - A boolean to indicate if the style is serialized when -// getPipelineFlow() method is called or not. -// pipelineId - The ID of the pipeline -getCommentStyle(commentId, temporary, pipelineId) - -// Hides all comments on the canvas. -hideComments() - -// Shows all comments on the canvas - if they were previously hiding. -showComments() - -// Returns true if comments are currently hiding. -isHidingComments() - -// Sets the comment identified, to edit mode so the user can -// edit the comment. -setCommentEditingMode(commentId, pipelineId) - -``` -## Link methods -```js -// Gets a link -// linkId - The ID of the link -// pipelineId - The ID of the pipeline -getLink(linkId, pipelineId) - -// Returns an array of link objects for the pipelineId passed in. -// pipelineId - The ID of the pipeline -getLinks(pipelineId) - -// Sets the properties in the link identified by the linkId. The -// linkProperties is an object containing one or more properties that will -// replace the corresponding properties in the link. For exam`ple: if -// linkProperties is { trgNodeId: "123", trgNodePortId: "789" } the target -// node ID will be set to "123" and the target port ID set to "789". -setLinkProperties(linkId, linkProperties, pipelineId) - -// Sets the source properties in the data link identified by the linkId. The -// srcNodeId and srcNodePortId will be set to the values provided. If -// srcNodePortId is set to null the current srcNodePortId will be removed -// from the link. Also, if the link has a srcPos property (because its -// source end is detached) that will be removed. -setNodeDataLinkSrcInfo(linkId, srcNodeId, srcNodePortId, pipelineId) - -// Sets the target properties in the data link identified by the linkId. The -// trgNodeId and trgNodePortId will be set to the values provided. If -// trgNodePortId is set to null the current trgNodePortId will be removed -// from the link. Also, if the link has a trgPos property (because its -// target end is detached) that will be removed. -setNodeDataLinkTrgInfo(linkId, trgNodeId, trgNodePortId, pipelineId) - -// Gets a node to node data link -// srcNodeId - The ID of the source node -// srcNodePortId - The ID of the source node port -// trgNodeId - The ID of the target node -// trgNodePortId - The ID of the target node port -// pipelineId - The ID of the pipeline -getNodeDataLinkFromInfo(srcNodeId, srcNodePortId, trgNodeId, trgNodePortId, pipelineId) - -// Gets a comment to node link -// id1 - The ID of the comment -// id2 - The ID of the node -// pipelineId - The ID of the pipeline -getCommentLinkFromInfo(id1, id2, pipelineId) - -// Gets a node to node association link -// id1 - The ID of one of the node -// id2 - The ID of one of the node -// pipelineId - The ID of the pipeline -getNodeAssocLinkFromInfo(id1, id2, pipelineId) - -// Adds links to a pipeline -// linkList - An array of links -// pipelineId - The ID of the pipeline -addLinks(linkList, pipelineId) - -// Deletes a link -// source - An array of links -// pipelineId - The ID of the pipeline -deleteLink(link, pipelineId) - -// Creates node to node links -// data - Data describing the links -// pipelineId - The ID of the pipeline -createNodeLinks(data, pipelineId) - -// Creates comment links -// data - Data describing the links -// pipelineId - The ID of the pipeline -createCommentLinks(data, pipelineId) - -// Sets the class name to newClassName of the links identified by linkIds -// array in the pipleine specified by pipeline ID. The class name will be -// applied to the link line path. -setLinksClassName(linkIds, newClassName, pipelineId) - -// Sets the style of the links specified by pipelineLinkIds to be -// the newStyle which will be either temporary or permanent. -// pipelineLinkIds - This identifies the objects to be styles. It is a -// javascript object like this: -// { -// : [ -// , -// -// ], -// : [ -// , -// -// ] -// } -// newStyle - This is a style specification. See the wiki for details. -// temporary - A boolean to indicate if the style is serialized when -// getPipelineFlow() method is called or not. -setLinksStyle(pipelineLinkIds, newStyle, temporary) - -// Sets the styles of multiple links at once. -// pipelineObjStyles - Specified the links and the styles each should be -// set to. It is a javascript array like this: -// [ -// { pipelineId: , objId: , style: }, -// { pipelineId: , objId: , style: }, -// { pipelineId: , objId: , style: } -// ] -// temporary - A boolean to indicate if the styles are serialized when -// getPipelineFlow() method is called or not. -setLinksMultiStyle(pipelineObjStyles, temporary) - -// Gets the class name associated with the link specified by linkId in the -// pipeline specified by pipelineId. -getLinkClassName(linkId, pipelineId) - -// Returns the style specification for a link. -// linkIds - An array of links -// temporary - A boolean to indicate if the style is serialized when -// getPipelineFlow() method is called or not. -// pipelineId - The ID of the pipeline -getLinkStyle(linkId, temporary, pipelineId) - -// Sets the decorations on a link. The decorations array passed in -// will replace any decorations currently applied to the link. -// linkId - The ID of the link -// newDecorations - An array of decorations. See Wiki for details. -// pipelineId - The ID of the pipeline -setLinkDecorations(linkId, newDecorations, pipelineId) - -// Sets the decorations of multiple links at once. The decorations array -// passed in will replace any decorations currently applied to the links. -// pipelineLinkDecorations - Specifies the links and their decorations. -// It is a javascript array like this: -// [ -// { pipelineId: , linkId: , decorations: }, -// { pipelineId: , linkId: , decorations: }, -// { pipelineId: , linkId: , decorations: } -// ] -setLinksMultiDecorations(pipelineLinkDecorations) - -// Gets an array of decorations for a link -// linkId - The ID of the link -// pipelineId - The ID of the pipeline -getLinkDecorations(linkId, pipelineId) - -// Sets the decoration label, for the decoration in the link identified, to edit -// mode provided the link label is editable. This allows the user to edit the -// label text. -setLinkDecorationLabelEditingMode(decId, linkId, pipelineId) -``` - -## Breadcrumbs methods -```js -// Returns the current array of breadcrumbs. There will one breadcrumb object -// for each level of supernode that the user has navigated into. This array -// can be used to display breadcrumbs to the user to show where they are -// within the navigation hierarchy within common canvas. -getBreadcrumbs() - -// Returns the last breadcrumb which represents the level with supernode -// hierarchy that the user has currently navigated to. -getCurrentBreadcrumb() -``` - -## Branch Highlight methods -```js -// Highlights the branch(s) (both upstream and downstream) from the node -// IDs passed in and returns the highlighted object Ids. -// nodeIds - An array of node Ids -// pipelineId - The ID of the pipeline -highlightBranch(nodeIds, pipelineId) - -// Highlights the upstream nodes from the node IDs passed in -// and returns the returns the highlighted object Ids. -// nodeIds - An array of node Ids -// pipelineId - The ID of the pipeline -highlightUpstream(nodeIds, pipelineId) - -// Highlights the downstream nodes from the node IDs passed in -// and returns highlighted object Ids. -// nodeIds - An array of node Ids -// pipelineId - The ID of the pipeline -highlightDownstream(nodeIds, pipelineId) -``` -## Operational methods -These are general purpose methods for operation of the common-canvas components: - -### Logging methods -```js -// Returns a Boolean to indicate whether canvas logging is switched on or off. -getLoggingState() - -// Sets canvas logging based on the Boolean passed in. -setLoggingState(state) -``` - -### Palette methods -```js -// Opens the palette -openPalette() - -// Closes the palette -closePalette() - -// Returns true if the palette is currently open -isPaletteOpen() -``` - -### Context menu methods -```js -// Opens the context menu -openContextMenu(menuDef) - -// Closes the context menu -closeContextMenu() -``` - -### Notification Panel methods -```js -// Opens the notification panel -openNotificationPanel() - -// Closes the notification panel -closeNotificationPanel() - -// Either opens or closes the notifictaion panel based on its current status -toggleNotificationPanel() -``` - -### Right Flyout methods -```js -// Returns a boolean to indicate if the right flyout is open or not -isRightFlyoutOpen() -``` - -### Top panel methods -```js -// Returns a boolean to indicate if the top pnel is open or not -isTopPanelOpen() -``` - -### Bottom panel methods -```js -// Returns a boolean to indicate if the bottom panel is open or not -isBottomPanelOpen() - -// Sets the height of the bottom panel in pixels. This can be called -// immediately after the CanvasController has been created, if the bottom -// panel should be displayed at a specific height when it first opens. -setBottomPanelHeight(height) -``` - -### Canvas/pipeline navigation methods -```js -// Displays a pipeline (identified by the pipelineId passed in). This must be -// one of the pipelines referenced by the current set of breadcrumbs. It -// cannot be used to open a new pipeline outside the current set of breadcruumbs. -displaySubPipeline(pipelineId) - -// Displays a pipeline for the supernode (identifid by the supernodeId -// parameter) in the pipeline (identifid by the pipelineId parameter). For -// correct breadcrumb generation this pipeline should be the one in the last -// of the current set of breadcrumbs. That is, the pipeline currently shown -// "full page" in the canvas. -displaySubPipelineForSupernode(supernodeId, pipelineId) - -// Displays full-page the previous pipeline from the one currently being displayed -displayPreviousPipeline() -``` - -### Zoom methods -```js -// Centers the canvas contents and zooms in -zoomIn() - -// Centers the canvas contents and zooms out -zoomOut() - -// Zooms the canvas contents to fit within the viewport -zoomToFit() - -// Changes the zoom amounts for the canvas. This method does not alter the -// pipelineFlow document. zoomObject is an object with three fields: -// x: Is the horizontal translate amount which is a number indicating the -// pixel amount to move. Negative left and positive right -// y: Is the vertical translate amount which is a number indicating the -// pixel amount to move. Negative up and positive down. -// k: is the scale amount which is a number greater than 0 where 1 is the -// default scale size. -zoomTo(zoomObject) - -// Increments the translation of the canvas by the x and y increment -// amounts. The optional animateTime parameter can be provided to animate the -// movement of the canvas. It is a time for the animation in milliseconds. -// If omitted the movement happens immediately. -translateBy(x, y, animateTime) - -// Returns the current zoom object for the currently displayed canvas or null -// if the canvas is not yet rendered for the first time. -getZoom() - -// Returns a zoom object required to pan the objects (nodes and/or comments -// and/or links) identified by the objectIds array to 'reveal' the objects -// in the viewport. Returns null if no nodes, comments or links can be found -// using the IDs passed in. Note: node, comment and link IDs must be unique. -// The zoom object returned can be provided to the CanvasController.zoomTo() -// method to perform the zoom/pan action. -// If the xPos and yPos parameters are provided it will return a zoom object -// to pan the center of the objects specified, to a location where, xPos -// is the percentage of the viewport width and yPos is the percentage of the -// viewport height. So if you want the center of the objects specified to be -// in the center of the viewport set xPos to 50 and yPos to 50. -// If the xPos and yPos parameters are undefined (omitted) and all the -// objects are currently fully within the canvas viewport, this method will -// return null. This can be used to detect whether the objects are fully -// visible or not. -// If the xPos and yPos parameters are undefined and the objects are outside -// the viewport, a zoom object will be returned that can be used to zoom them -// so they appear at the nearest side of the viewport to where they are -// currently positioned. -// The zoom object retuurned has three fields: -// x: Is the horizontal translate amount which is a number indicating the -// pixel amount to move. Negative left and positive right -// y: Is the vertical translate amount which is a number indicating the -// pixel amount to move. Negative up and positive down. -// k: is the scale amount which is a number greater than 0 where 1 is the -// default scale size. -// Parameters: -// objectIds - An array of nodes and/or comment IDs. -// xPos - Optional. Can be set to percentage offset of the viewport width. -// yPos - Optional. Can be set to percentage offset of the viewport height. -getZoomToReveal(objectIds, xPos, yPos) - -// Clears any saved zoom values stored in local storage. This means -// newly opened flows will appear with the default zoom. This method -// is only applicable when the `enableSaveZoom` config parameter is -// set to "LocalStorage". -clearSavedZoomValues() - -``` diff --git a/guide/2.4.0-Calling-the-Canvas-Controller-API.md b/guide/2.4.0-Calling-the-Canvas-Controller-API.md deleted file mode 100644 index cebad931a4..0000000000 --- a/guide/2.4.0-Calling-the-Canvas-Controller-API.md +++ /dev/null @@ -1,39 +0,0 @@ - -## Techniques for calling Canvas Controller API - -There are a couple of techniques you can use to update the object model using the Canvas Controller. - -### Incremental Updates -Once the pipeline flow is loaded into common-canvas using: -``` -canvasController.setPipelineFlow(pFlow) -``` -the pipeline flow is held in memory “inside” the object model of common-canvas. Thereafter, you can update that in-memory pipeline flow by calling canvas controller API such as: `deleteComment` or `createNode`, etc. The canvas controller will directly update the in-memory object model based on these calls, and it will cause the canvas view to refresh to reflect the change your code requested with the API call. - -It’s best to use the above technique when making small incremental changes to the object model often based on user requests. - -### Extensive Updates - -An alternative to making these individual API calls is to use `canvasController.getPipelineFlow(pFlow)` -which will return the full contents of the current state of the object model into a variable e.g. -``` -const currentPF = this.canvasController.getPipelineFlow(); -``` -You can then make changes to the pipeline flow using you own code. -For example: - -``` -// Wipe out all the comments in the zeroth pipeline -currentPF.pipelines[0].comments = []; -``` - -and then set the pipeline flow back into common canvas with this: - -``` -this.canvasController.setPipelineFlow(currentPF); -``` - -Note: the updating of the pipeline flow (currentPF) is entirely done by your code — there is no API to help you — so you have to understand the [pipeline flow schema](https://github.com/elyra-ai/pipeline-schemas/blob/main/common-pipeline/pipeline-flow/pipeline-flow-v3-schema.json) to understand what to do. - -This technique is probably most useful when doing extensive changes to the pipeline flow where you don’t want each change to cause a refresh of the canvas. This is because the only refresh of the canvas will be when you do the final `setPipelineFlow()` call. - diff --git a/guide/2.4.1-Style-Specification.md b/guide/2.4.1-Style-Specification.md deleted file mode 100644 index 3a91c893bf..0000000000 --- a/guide/2.4.1-Style-Specification.md +++ /dev/null @@ -1,69 +0,0 @@ -There are multiple was to specify the styles for the objects common-canvas displays: - -* A class name can be provided for nodes either within the pipelineFlow document or -* The common-canvas default styes can be overriden within your CSS or SCSS file - -For more precise styling of objects the style specification object can be used to provide a number of styles to common canvas to set the inline styles on numerous elements of an object. For example, a node is made up of: a selection outline; a node body (rectangle); an image, a label etc. - -Style specifications may be applied to common-canvas objects using the following [Canvas Controller](/2.4-Canvas-Controller-API) methods: -```js -setObjectsStyle() -setObjectsMultiStyle() -setLinksStyle() -setLinksMultiStyle() -setSubdueStyle() -``` -and may be retrieved for objects using: -```js -getNodeStyle() -getCommentStyle() -getLinkStyle() -``` - -The style spec for a node can set the styles for all these elements in one shot. Here is a template of a style spec for a node: -```js -{ - body: { default: , hover: }, - image: { default: }, - label: { default: }, - selection_outline: { default: } -} - ``` -And here is a real example: -```js -{ - body: { - default: "fill: coral; stroke: red;", - hover: "fill: cornflowerblue; stroke: blue;" - } -}; -``` - -Here is a template for styling a comment: - -```js -{ - body: { default: , hover: }, - text: { default: }, - selection_outline: { default: }, -} -``` - -And here is a template for styling a link: -```js -{ - line: { default: , hover: } -} -``` - -* **``** - is a string containing any CSS code that can be added inline to an SVG object. That means, for example, you need to use fill and stroke for colors etc It is recommended NOT to change the sizes of text fonts. - -The CSS will be applied to the element of the object specified, either as the default inline style or as the style when the pointer hovers over the object. - -When a hover style is applied to a graphical element it is applied in addition to the default style so there is no need to repeat styles in the hover `` because they will augment the default style. - -Because styles are applied as in-line styles they will override any styles provided in your application's CSS and specified to common-canvas through the class_name field of canvas objects. - -If the `` is specified as null the current style will be removed from the specified element of the object. - -Finally, styles can be applied to your nodes, comments and links as either temporary or permanent styles by specifying the `temporary` boolean in the API methods. A temporary style is just applied for the duration of the session and are not persisted. You should use `temporary=true` styles that represent transient attributes of an object that should not be persisted in the pipelineFlow document. Use `temporary=false` styles for styles that you want to persist in the pipelineFlow document. diff --git a/guide/2.4.2-Decoration-Specification.md b/guide/2.4.2-Decoration-Specification.md deleted file mode 100644 index cd096cf8c5..0000000000 --- a/guide/2.4.2-Decoration-Specification.md +++ /dev/null @@ -1,195 +0,0 @@ -## Decorations -Your application can add Decorations -- additional icons, text labels, shapes or JSX objects -- to nodes or links in the canvas to indicate special status or attributes of the node or link. Decorations can be static (for display only) or interactive (a hotspot) so the user can click them to initiate some action. - -## Adding Decorations -Decorations can be added to the nodes and/or links in four different ways: - -1. By using the following `CanvasController` methods: - ```js - setNodeDecorations(nodeId, newDecorations, pipelineId) - setNodesMultiDecorations(pipelineNodeDecorations) - setLinkDecorations(linkId, newDecorations, pipelineId) - setLinksMultiDecorations(pipelineLinkDecorations) - ``` - and can be retrieved using these `CanvasController` methods: - ```js - getNodeDecorations(nodeId, pipelineId) - getLinkDecorations(linkId, pipelineId) - ``` - See the [CanvasController API documentation](/2.4-Canvas-Controller-API) for more details. - -2. Node decorations can be specified in the [nodeLayout object](/2.1-Config-Objects#enablenodelayout) in the canvas config. Decorations specified in this way are applied to all nodes on the canvas. - -3. Decorations can be applied to, and retrieved from, nodes or links in the pipelineFlow in the `app_data.ui_data` section for the node or link. (Note: JSX objects are not supported in the pipelineFlow document). - -4. Decorations can be returned in the layout information returned from the [layoutHandler](/2.2-Common-Canvas-callbacks#layouthandler) CommonCanvas callback method. - -# Specification - -The decoration specification used by these methods and the pipelineFlow is a JavaScript object with these possible properties: - -These properties are applicable to an image decoration: -```js - { - id: , - image: , - position: , - distance: - x_pos: , - y_pos: , - width: , - height: , - hotspot: , - class_name: , - outline: , - tooltip: , - temporary: - } -``` -These properties are applicable to a label decoration: -```js - { - id: , - label: , - label_editable: , - label_align: , - label_single_line: , - label_max_characters: , - label_allow_return_key: , - position: , - distance: - x_pos: , - y_pos: , - width: , - height: , - hotspot: , - class_name: , - tooltip: , - temporary: - } -``` -These properties are applicable to a shape decoration: -```js - { - id: , - path: , - position: , - distance: - x_pos: , - y_pos: , - width: , - height: , - hotspot: , - class_name: , - tooltip: , - temporary: - } -``` -These properties are applicable to a JSX decoration: -```js - { - id: , - jsx: , - position: , - distance: - x_pos: , - y_pos: , - width: , - height: , - hotspot: , - class_name: , - tooltip: , - } -``` - -where: - -#### **id** -A unique ID for the decoration within the context of the node or link to which the decorator is attached. - -#### **image** -A reference to an image to display for the decoration. If an image is specified the image is displayed within an outline rectangle unless `outline` is set to false. The image should be a reference to your image like: "/images/decorations/zoom-in_32.svg". Do not set label or path or jsx when this field is set. - -#### **path** -An SVG shape that is displayed using this string as it's SVG path. eg. "M 0 0 L 10 10 -10 10 Z" could be specified to draw a triangle. Do not set image or label or jsx when this field is set. - -#### **jsx** -A JSX object that is is displayed at the specified decoration location. Do not set image or path or label when this field is set. Note JSX decorations are not supported in the pipelineFlow document. - -#### **label** -A text string that is displayed at the specified decoration location. Do not set image or path or jsx when this field is set. - -#### **label_editable** -A boolean that defaults to `false`. When set to `true`, if the mouse pointer is hovered over the label an edit icon is displayed next to the label which, when clicked, opens the label for editing. The label can also for double clicked to go to edit mode. - -When editing is completed (by clicking outside the text area) an `editDecorationLabel` action is executed which results in calls to first the `beforeEditActionHandler` and then the `editActionHandler` callbacks. - -#### **label_align** -Can be either "center" or "left". When set to center the label will be centered on the point defined by the `position`, `distance`, `x_pos` and `y_pos` properties. - -#### **label_single_line** -A boolean that defaults to `false`. When set to `true` the label is displayed on a single line and is truncated at the width of the label (specified in the `width` property for the decoration) and does not word wrap. If it is truncated an ellipsis (...) is displayed at the end of the truncated text. - -If this property is set to `false`, long label text is displayed over a number of lines with word wrapping being controlled by the `width` set for the decoration. If the text extends beyond a second line an ellipsis (..) is displayed at the end of the second line. This is controlled by the `-webkit-line-clamp: 2;` CSS property. You can override this if you want the ellipsis to be displayed on a different line. - -Note: For both single and multi-line labels you may need to set the `height` property for the decoration to show the text fully. - -#### **label_max_characters** -A number or null. Defaults to null. If set to a number the label will be restricted to that number of characters. If the label in the pipeline flow document is longer than the max number it will be displayed but when it is edited the user will not be able to do anything except delete characters until the label is shorter than the max number. If this property is set to `null` or omitted an unlimited number of characters may be entered by the user. - -#### **label_allow_return_key** -A boolean that defaults to `false`. When `false`, if the user presses the return key nothing will happen. This means multi-line labels will only word-wrap at the `width` of the decorator. Preventing newline insertion is useful if the label text appears elsewhere in the UI which is not able to show text with newline characters. When set to `"save"`, if the user presses the return key, the editing will be completed and the label saved -- this is the equivalent of clicking on the canvas background to complete the edit. If set to `true`, a new line character will be inserted in the label when the user presses return. - -#### **position** -This is the anchor point to which the decoration is attached. For a node, this can be one of these 9 enumerated values: -``` - "topLeft", "topCenter", "topRight", - "middleLeft", "middleCenter", "middleRight", - "bottomLeft", "bottomCenter", "bottomRight". -``` -If omitted it will default to "topLeft". - -For a link, this can be one of these 3 enumerated values: -``` - "source" - "middle" - "target" -``` -`source` will position the decoration at the start point of the line and `target` will position it at the end point of the line. If omitted it will default to `middle`. - -#### **distance** -A number of pixels. This is only applicable when the decoration is for a link line and then, only with straight connecting lines. That is, for node to node connections when the config property `enableLinkType` is set to `"straight"`. When specified, it will move the anchor point for the decoration to a new position along the connecting line relative to the initial position specified in the decoration's `position` property. A positive number moves the decoration along the line from the starting position towards the target of the link and a negative number backwards towards the source of the link. For example, if a straight link decoration has `position` of `source` and a `distance` of `20` the decoration's anchor point will be 20 pixels along the link line from the source (start) point of the line. After the `distance` value has been applied to the anchor point of the decoration, any `x_pos` and `y_pos` adjustment will be applied to fine tune the decoration's final position. - -#### **x_pos** -This is the number of pixels horizontally from the anchor point that the decoration is positioned. It can be positive or negative. If omitted it takes a default value from the [node layout properties](/2.7-Customizing-Node-Layout-Properties#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default). x_pos is not applicable if you specify an SVG path using the `path` field, because the SVG path can be used to position the shape. - -#### **y_pos** -This is the number of pixels vertically from the anchor point that the decoration is positioned. It can be positive or negative. If omitted it takes a default value from the [node layout properties](/2.7-Customizing-Node-Layout-Properties#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default). y_pos is not applicable if you specify an SVG path using the `path` field, because the SVG path can be used to position the shape. - -#### **width** -This is the width for the decorator in pixels. For an image decorator, it is the width of the rectangle surrounding the image. For a label decorator it is the width allowed for display of the label text. If omitted it takes a default value from the [node layout properties](/2.7-Customizing-Node-Layout-Properties#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default) for Node decorations and from the canvas layout properties for Link properties. - -#### **height** -This is the height for the decorator in pixels. For an image decorator, it is the height of the rectangle surrounding the image. For a label decorator it is the height allowed for display of the label text. If omitted it takes a default value from the [node layout properties](/2.7-Customizing-Node-Layout-Properties#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default) for Node decorations and from the canvas layout properties for Link properties. - -#### **hotspot** -A Boolean. It defaults to false. When set to true the decoration becomes clickable and when it is clicked the [decorationCallbackHandler](/2.2-Common-Canvas-callbacks#decorationactionhandler) is called with the ID of the decoration passed as a parameter. - -#### **class_name** -An optional class that will be applied to the decoration. You can add a style rule that references that class in your CSS to style the decoration and override the default styles. - -#### **outline** -A Boolean. It defaults to true. When a decoration is specified with an image field the image is typically displayed with a outline rectangle around it and with an offset within the rectangle to improve presentation. If `outline` is set to `false` the outline rectangle is **not** displayed and the image is displayed without any offset from its specified `x_pos` and `y_pos`. - -#### **tooltip** -A String. When specified, the string will be shown in a tooltip when the pointer is hovered over the decoration. No tip will be displayed if the `tooltip` property is omitted. Note: for decoration tooltips to be displayed on the canvas, the `decorations` property of the `tipConfig` object in the canvas config must be set to true (which is its default setting). - -#### **temporary** -A Boolean. It defaults to false. When set to true the decoration object will _not_ be saved in the pipelineFlow document returned by the `CanvasController.getPipelineFlow()` method. Typically, this should be set to `true` when adding decorations programmatically to the nodes and links on the canvas. - -### Notes: - -1. Using `x_pos` and `y_pos`, decorations can be displayed outside the node boundary. -2. If no image or label or path is provided, the default decoration is a rectangle displayed with the class_name provided. -3. You can specify as many decorations as you want by providing extra entries in the decorations array. -4. Images and labels are positioned differently. For images, the position defined for the decoration is the top left corner of the image. For labels it is anchor point for the label which is the base line of the string in the vertical direction and is dependent on the text-anchor CSS property applied to the text. So if you apply the `text-anchor: middle` CSS property to the label in the style related to class_name the label will be centered on the point calculated for the position of the decoration. \ No newline at end of file diff --git a/guide/2.4.3-Object-structure-used-by-API.md b/guide/2.4.3-Object-structure-used-by-API.md deleted file mode 100644 index 48828c0c70..0000000000 --- a/guide/2.4.3-Object-structure-used-by-API.md +++ /dev/null @@ -1,49 +0,0 @@ -# API differences with schema -Because historically common-canvas has had to deal with different external flow definitions, there are some differences between the nodes, comments and links that the CanvasController API handles internally and those specified in the pipelineFlow schema. As follows: - -## Object structure - For the API methods that involve nodes, comments and links, those objects are passed in and out by the API in their internal formats rather than the formats defined in the schema files. - -The internal structure is a somewhat flattened version of that in the schema definition. That means, properties that are in `.app_data.ui_data` are flattened out and appear as properties in the `` itself. So for example a node that conforms to the schema might look like this: -```js - { - id: "1234", - op: "select", - ... - app_data : { - ui_data: { - label: "Selection node", - image: "/images/select.svg", - description: "A node for selection" - ... - }, - other_data: { - prop1: "Something interesting" - } - } - } -``` -whereas when it is passed through the API it looks like this: -```js - { - id: "1234", - op: "select", - label: "Selection node", - image: "/images/select.svg", - description: "A node for selection" - ... - app_data : { - other_data: { - prop1: "Something interesting" - } - } - } -``` -Note that, any properties in `app_data`, other than `ui_data`, are preserved in the internal format. So in the example, `app_data.other_data` in the schema format is preserved in the internal format. - -## Links handing in the API -The other difference between the API and the schema formats is with links. - -In the pipeline flow schema, links are typically defined as properties within another object, for example, a node to node link is defined within a `links` array inside the `inputs` field of the target node and contains references to the `node id` and `port` of the source node. Also, links from comments to nodes are stored as an array in the comment object. - -However, in the API and internally in common-canvas, links are treated as a top level object; that is, there is an array of links stored internally which can be manipulated using the API methods. Each link has a unique ID. Consequently, links can be retrieved from the API by their ID field and properties of the links can be updated again by identifying the links using their ID. If you do not specify an ID for links in your pipelineFlow document a unique global ID will be generated for each link when the pipeline flow is loaded. \ No newline at end of file diff --git a/guide/2.4.4-Notification-Message-Specification.md b/guide/2.4.4-Notification-Message-Specification.md deleted file mode 100644 index b7e1b9ccb7..0000000000 --- a/guide/2.4.4-Notification-Message-Specification.md +++ /dev/null @@ -1,31 +0,0 @@ -### Notification Message structure. - -Notification messages are displayed in the notification panel which the user can access by clicking the Notifications icon in the toolbar. Each notification message is described by a simple JavaScript object like this: -```js - { - id: , - type: , - title: , - content: , - timestamp: , - callback: , - closeMessage: -} -``` -where: - - * **id** (string, required): this is a unique ID assigned to the notification message. This is passed as a parameter in the callback (see below) and is used to reference messages when deleting them through the `CanvasController` API. - -* **type** (string, required): this must be one of four values: "info", "success", "warning", or "error". If `type` is null, empty string, or undefined, the message type will be "unspecified". - -* **title** (string or JSX object): the title of the notification message - -* **content** (string or JSX object): the body of the notification message - -* **callback** (function): an optional callback function that will be called when the notification message is clicked. Callback function is called with one parameter, `id` - -* **timestamp** (string or JSX object): an optional timestamp that will be rendered in a separate section with different formatting, if passed in - -* **closeMessage** (string or React object): an optional message that, if passed in, will display as clickable. Clicking on this will delete this individual message. If none is passed in, no delete option will be shown. - - diff --git a/guide/2.4.5-Programmatically-creating-new-canvas-nodes.md b/guide/2.4.5-Programmatically-creating-new-canvas-nodes.md deleted file mode 100644 index 89dc8a5928..0000000000 --- a/guide/2.4.5-Programmatically-creating-new-canvas-nodes.md +++ /dev/null @@ -1,64 +0,0 @@ -## Introduction - -The host application code can programmatically create nodes on the canvas in two ways: - -* By calling CanvasController API methods to create and add the node to the canvas. - -* Creating and adding a node to the Pipeline Flow document - - -## Creating and adding a node to the Canvas Controller API - -The following code will programmatically add a node to the canvas. These commands will update the common-canvas object model directly and will not be added to the command stack so the user will not be able to `undo` / `redo` these actions. Also, the `beforeEditActionHandler` and `editActionHandler` callbacks will not be called for these actions. - -First you can get a node template from the canvas by calling -```js - const template = canvasController.getPaletteNode("sort"); -``` -where the parameter is the operation (`op` field) for the palette node. Alternatively, you can retrieve a node template using this method: -```js - const template = canvasController.getPaletteNodeById(nodeId) -``` -which returns the node template based on the node ID. This can be useful if you have supernodes in your palette because supernodes do not have an `op` field. After creating the node template your code can alter fields (for example, the label) within the template. If you do change any fields be careful because common-canvas doesn't do any error checking on your fields. - -Next you create the node: -```js - const newNode = canvasController.createNode({ - nodeTemplate: template, - offsetX: 200, - offsetY: 400 -}); -``` -This will work correctly for regular nodes, and also supernodes, that have been pulled from the palette. - -Next you add the node object to the canvas. -```js - canvasController.addNode(newNode); -``` -The node will appear at the offsetX, offseY position within the coordinate system for the canvas. - -### If command stack is needed - -This method allows the host application to create a node, or supernode, from a palette template object by creating and executing a command which will be added to the command stack (so the user can `undo` / `redo` it) and will also cause the `beforeEditActionHandler` and `editActionHandler` callbacks to be called. - - -First your code retrieves a node template from the palette as described above and then calls this method: -```js - const data = { - nodeTemplate: template, - offsetX: 200, - offsetY: 400 - }; - - canvasController.createNodeCommand(data, pipelineId) -``` - -Note: If `pipelineId` is omitted the node will be created in the current "top-level" pipeline. - -## Creating and adding a node using Pipeline Flow document - -This approach works by your code adding one or more JSON objects directly to the pipeline flow object, either before the pipeline flow document is loaded into common-canvas using `CanvasController.setPipelineFlow(pFlow)`, or afterwards by retrieving the pipeline flow object from common-canvas using `CanvasController.getPipelineFlow()` and then updating the nodes array of whichever pipeline you want to modify. This would require your code to navigate to the `pipeline` object (that you want to update) in the `pipelines` array of the pipeline flow and then add the node object to the `nodes` array in the pipeline object. - -After updating the pipeline flow object your code would need to reload it into common-canvas using `CanvasController.setPipelineFlow(pFlow)`. - -To use this approach you would need a good understanding of the [pipeline flow schema](https://github.com/elyra-ai/pipeline-schemas/blob/412d70176953ed9ac2e6a03f7135b09b7565fc5d/common-pipeline/pipeline-flow/pipeline-flow-v3-schema.json) and [pipeline flow UI schema](https://github.com/elyra-ai/pipeline-schemas/blob/412d70176953ed9ac2e6a03f7135b09b7565fc5d/common-pipeline/pipeline-flow/pipeline-flow-ui-v3-schema.json). diff --git a/guide/2.4.6-Constructing-a-read-only-or-locked-canvas.md b/guide/2.4.6-Constructing-a-read-only-or-locked-canvas.md deleted file mode 100644 index 7043437621..0000000000 --- a/guide/2.4.6-Constructing-a-read-only-or-locked-canvas.md +++ /dev/null @@ -1,57 +0,0 @@ -## Introduction - -Some host applications need to display flows that cannot be edited by the user. This might be because the flow artifact is currently being edited by another user (locked) or because the user does not have authority to edit the flow (read-only) or some other reason. We'll use the term 'read-only' below to refer to both locked and read-only canvases. - -There are many aspects of common-canvas components that need to considered for a read-only canvas. Since common-canvas is highly customizable it is not possible for the common-canvas code to manage components of the canvas that have been customized by the host application. For example, if the host app code added tools to the toolbar, common-canvas does not know whether those tools should be disabled when displaying a read-only canvas or not. So the host application code will need to manage that. Let's look at each element of common-canvas and see what needs to be done. - -# General Config -There is one main canvas configuration property that will change the common-canvas behavior to implement a read-only canvas. This is [`enableEditingActions`](/2.1-Config-Objects#enableeditingactions) which defaults to true and needs to be set to `false` for read-only canvases. The sections below will cover what effect this will have on the different components of common-canvas and what you need to do for any customizations you have made. - -# Canvas -Setting `enableEditingActions` to false will prevent nodes and comments (and detachable links) from being moved relative to one another. It will also prevent new links from being created and prevent text (like comments or node labels) from being edited. - -With `enableEditingActions` set to false, the canvas can still be panned (left/right and up/down) and also zoomed in and out. Nodes, comments and links can still be clicked (to select) and right clicked (to display a context menu) and double clicked (usually to show properties). If you implemented any behavior for these interactions, using the [`clickActionHandler`](/2.2-Common-Canvas-callbacks#clickactionhandler), you'll need to review what your code is doing and make sure it is appropriate when a read-only canvas is being displayed. - -Common-canvas allows objects from outside the canvas to be dropped onto the canvas to create a new node. For example, a file can be dragged from the operating system desktop onto the canvas to create a data node. With `enableEditingActions` set to false, the drag/drop gesture (which common-canvas cannot prevent) will prevent a new node from being created. It is recommended you switch the [`enableDropZoneOnExternalDrag`](/2.1-Config-Objects#enabledropzoneonexternaldrag) config property to false when displaying a read-only canvas. This will prevent a 'drop zone' graphic from appearing over the canvas when the object is dragged over the top of the canvas. - -Some applications need to show a tag (called a 'state tag') over the canvas to emphasize the 'read-only' or 'locked' state of the canvas. This can be displayed using the [`enableStateTag`](/2.1-Config-Objects#enablestatetag) canvas config property. The tooltip of the 'state tag' can be provided by implementing the [`tipHandler`](/2.2-Common-Canvas-callbacks#tiphandler) callback function. - -Since there are numerous possible styles for nodes and links when displaying a read-only canvas, it isn't possible for common-canvas to style the canvas objects appropriately for all different designs. You will need to override any styles for nodes and links to fit your design. To help with this common-canvas sets a class called `config-edit-actions-false` on the top-level div that contains the common-canvas components. You can use this to build specific selectors in your CSS/SCSS that will override the styles applied to nodes and links by default. For example, to override node icon and label colors you could specify the following in your SCSS file: -``` - .editing-actions-false { - .d3-node-group { - & .d3-node-label, - & svg path { - color: $disabled-02; - stroke: $disabled-02; - fill: $disabled-03; - } - } - } -``` - -# Context menu -Setting `enableEditingActions` to false will prevent any options, that would edit the canvas objects, from being displayed in the common-canvas default context menu. For example, `Delete` will not show up in the context menu. See the [`enableEditingActions` documentation](/2.1-Config-Objects#enableeditingactions) for a list of options that are disabled. - -Your application code can add your own options to the context menu by implementing the [`contextMenuHandler`](/2.2-Common-Canvas-callbacks#contextmenuhandler) callback function. If you have added your own options, you should review your code and ensure options that might change the canvas objects are not added to the context menu when you are displaying a read-only canvas. - -Note: The common-canvas default menu, passed as the second parameter to the `contextMenuHandler` callback, will still contain editing options. This means, if your code relies on them for some reason, (for example for calculating the position of your added options) your application code will still work OK. The editing options will be removed after your code returns the array of items that describe the desired menu from the `contextMenuHandler` callback. - -# Toolbar -The toolbar can display buttons for standard common-canvas actions and also buttons for any application-specific actions added by your code. Setting `enableEditingActions` to false will cause buttons for any standard common-canvas actions, that edit the canvas objects, to be disabled regardless of the setting for the `enable` property for each action. See the [`enableEditingActions` documentation](/2.1-Config-Objects#enableeditingactions) for a list of actions that are disabled. - -You should review any application-specific action buttons you have added to the toolbar and decide if they need to be disabled or removed from the toolbar when displaying a read-only canvas. - -# Keyboard -Common-canvas supports a number of keyboard shortcuts. Setting `enableEditingActions` to false, disables any keyboard shortcuts that edit the canvas objects (such as Delete). See the [`enableEditingActions` documentation](/2.1-Config-Objects#enableeditingactions) for a list of keyboard shortcuts that are disabled. - -# Palette -Setting `enableEditingActions` to false: - -* prevents node templates from being dragged from the palette and -* disables the double-click action on node templates which automatically adds a node to the canvas. - -You should decide if your application should display the palette when displaying a read-only canvas or not. The palette can be hidden by setting the canvas config property [`enablePaletteLayout`](/2.1-Config-Objects#enablepalettelayout) to "None". - -# Test Harness: Sample Read-Only application -The test harness contains a sample application called "Read-Only" which shows how a read-only canvas can be built using the `enableEditingActions` config option. In the application there are three toolbar buttons which can be used to navigate between Editable state, Read-Only state and Locked state. You can review the `.jsx` and `.scss` files in the [application code](https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/src/client/components/custom-canvases/read-only) to see how the application is implemented and styled. diff --git a/guide/2.5-Command-Stack-API.md b/guide/2.5-Command-Stack-API.md deleted file mode 100644 index 1e6998d6ab..0000000000 --- a/guide/2.5-Command-Stack-API.md +++ /dev/null @@ -1,79 +0,0 @@ -# Command Stack API - - The CommandStack is a JavaScript class that provides the functionality to support do/undo/redo of commands. It maintains an internal stack of commands with a cursor that moves up and down when commands are undone or redone. Commands are also Javascript classes that implement a simple interface. - - The canvas-controller creates an instance of the command stack. Common-canvas provides command objects for each of the commands that are performed by the user, such as: create node, delete comment, link nodes together, etc. - - To activate the undo and redo actions, common-canvas provides undo/redo options in its default context menu, on the default toolbar and via keystrokes ctrl+z (undo) and ctrl+shift+z (redo). You can implement your own undo and redo UI if required using the API. - - The CommandStack API allows application code to programmatically add commands to the command stack. You can get the Command Stack by calling the canvas-controller's `getCommandStack()` method. The CommandStack API provides the following methods: - -```js - do(command) - push the command onto the command stack and then invoke command.do() - undo() - pop a command from the command stack and then invoke command.undo() - redo() - push last undo command onto the command stack and then invoke command.redo() - canUndo() - returns true if there is a command on the command stack. - canRedo() - returns true if there is an undo command that can be redo. - clearCommandStack() - getUndoCommand() - returns the next command to be undone or null. - getRedoCommand() - returns the next command to be redone or null. -``` - -Many of these have equivalent methods in the canvas-controller. - -Each command that is added to the command stack is a Javascript class that needs to implement these methods: - - -```js - constructor() - do() - undo() - redo() -``` - -constructor() - Initial setup - -do() - Performs all actions necessary to execute the command - -undo() - Performs all actions necessary to reverse the actions performed in do() - -redo() - Performs all actions necessary to re-execute the command. For some commands this is the same as do() but others it is different. - - - Here is some sample code that shows how a create-node command might be written: - -```js - export default class CreateNodeAction extends Action { - constructor(data) { - super(data); - this.newNode = createNode(data); - } - - do() { - ObjectModel.addNode(this.newNode); - } - - undo() { - ObjectModel.removeNode(this.newNode.id); - } - - redo() { - ObjectModel.addNode(this.newNode); - } - - getLabel() { - return "Add 1 node" - } - - } -``` - - Here is an example of using the CommandStack API to create a command action and push it on the stack: - -```js - const command = new CreateNodeAction(data); - this.canvasController.getCommandStack().do(command); -``` - - - diff --git a/guide/2.6-Flow-Validation-API.md b/guide/2.6-Flow-Validation-API.md deleted file mode 100644 index 159fdda93f..0000000000 --- a/guide/2.6-Flow-Validation-API.md +++ /dev/null @@ -1,62 +0,0 @@ -# Flow Validation API - - The Flow Validation API allows application code to programmatically validate the nodes in the flow against it's property values. The API can be invoked after setting the Canvas Controller pipeline flow, when opening a new flow, or associated with a canvas context menu item. To use the Flow Validation API import the FlowValidation object fro common-canvas: -``` -import { FlowValidation } from "@elyra/canvas"; -``` -then call the API on the object, for example: -``` -FlowValidation.validateFlow( ... ); -``` - -The Flow Validation object provides the following API: - -``` -validateFlow(canvasController, parameterDataCallback, setNodeMessagesCallback, includeMsgTypes) - canvasController - an instance of the canvas controller - parameterDataCallback – function to get the parameter data or form data for a node - setNodeMessagesCallback – function to set the validation messages for a node. (optional) - includeMsgTypes - array[strings] Return invalid only if messages are found of types contained - in the array. If not specified then any message type causes invalid return. (optional) - return - boolean If flow is valid returns true, otherwise returns false. -``` -where the two callbacks are defined as follows: -``` -parameterDataCallback(nodeId) - nodeId – string node Id. - function must return this object: - { - type: “parameterDef” | “form”, - data: Json_object - } - -/* The setNodeMessagesCallback is optional and only useful if not using internal object model. -setNodeMessagesCallback(nodeId, messages) - nodeId – string node Id. - an array of message objects generated from the validation of the node. -``` - -The validateFlow() API will traverse the current flow and for each node invoke the parameterDataCallback() to get with a form data JSON or a parameterDef JSON. It will validate the JSON for the node and store any messages in the node objects within the model. The setNodeMessagesCallback() function will be called with all the messages generated for the node. This is only useful if the application is not using the internal object model. -The format of the message object is described in [Pipeline Flow UI schema](https://github.com/elyra-ai/wdp-pipeline-schemas/blob/master/common-pipeline/pipeline-flow/pipeline-flow-ui-v1-schema.json) - -Here is an example of using the FlowValidation API to validate a flow on opening: - -``` -import { CanvasController, FlowValidation } from "@elyra/canvas"; - -getNodeForm(nodeId) { - const parameterDef = getParameterDefJSON(nodeId); - return { type: "parameterDef", data: parameterDef }; -} - -setNodeMessages(nodeId, messages) { - // code to persist messages in a store in addition to the internal model. -} - -openCanvas(canvasJson) { - const canvasController = new CanvasController(); - canvasController.setPipelineFlow(canvasJson); - FlowValidation.validateFlow(canvasController, this.getNodeForm, this.setNodeMessages); -} - -``` diff --git a/guide/2.7-Customizing-Node-Layout-Properties.md b/guide/2.7-Customizing-Node-Layout-Properties.md deleted file mode 100644 index 64c033441b..0000000000 --- a/guide/2.7-Customizing-Node-Layout-Properties.md +++ /dev/null @@ -1,392 +0,0 @@ -## Node layout properties -Node layout properties define how all the elements of a node are displayed such as: the position and size of the icon image; the position of the main label; even the shape of the node itself! You can change just about anything to do with the way the nodes appear in your canvas. So you can get a very different looking canvas to suit your needs. - -There are two possible sets of node layout properties provided by common-canvas, these are controlled by the `enableNodeFormatType` canvas configuration property which can be set to either "Horizontal" or "Vertical". "Horizontal" will display a node with an image and the label to the right of the image. "Vertical" will display the node with the label underneath the image. - -## Default values for node layout properties -The possible node layout properties are shown below with the values they have when `enableNodeFormatType = "Horizontal"`. You can see the values for both sets of properties by looking at the [layout-dimensions.js program](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/common-canvas/src/object-model/layout-dimensions.js) - -``` -// Default node sizes. The height might be overridden for nodes with more ports -// than will fit in the default size. -defaultNodeWidth: 160, -defaultNodeHeight: 40, - -// A space separated list of classes that will be added to the group -// DOM element for the node. -className: "", - -// Displays the node outline shape underneath the image and label. -nodeShapeDisplay: true, - -// Default node shape. Can be "rectangle" or "port-arcs". Used when nodeOutlineDisplay is true. -nodeShape: "port-arcs", - -// SVG path strings to define the shape of your node and its -// selection highlighting. If set to null the paths will be set by default -// based on the nodeShape setting. -bodyPath: null, -selectionPath: null, - -// Displays the external object specified, as the body of the node -nodeExternalObject: false, - -// Display image -imageDisplay: true, - -// Image dimensions -imageWidth: 26, -imageHeight: 26, - -// Image position -imagePosition: "topLeft", -imagePosX: 6, -imagePosY: 7, - -// Display label -labelDisplay: true, - -// Label dimensions -labelWidth: 112, -labelHeight: 19, - -// Label position -labelPosition: "topLeft", -labelPosX: 36, -labelPosY: 12, - -// Label appearance -labelEditable: false, -labelAlign: "left", // can be "left" or "center" -labelSingleLine: true, // false allow multi-line labels -labelOutline: false, -labelMaxCharacters: null, // null allows unlimited characters -labelAllowReturnKey: false, // true allows line feed to be inserted into label, "save" to make the return key save the label. - -// An array of decorations to be applied to the node. For details see: -// https://github.com/elyra-ai/canvas/wiki/2.4.2-Decoration-Specification -// These are added to the node at run time and will not be saved into -// the pipeline flow. -decorations: [], - -// Positions and dimensions for 9 enumerated default decorator positions. -// decoratorWidth and decoratorHeight are the dimensions of the outline -// rectangle and decoratorPadding is the padding for the image within the -// outline rectangle. -decoratorTopY: 2, -decoratorMiddleY: -8, -decoratorBottomY: -18, - -decoratorLeftX: 2, -decoratorCenterX: -8, -decoratorRightX: -30, - -// Width, height and padding for image decorators -decoratorWidth: 16, -decoratorHeight: 16, -decoratorPadding: 2, - -// Width and height for label decorators -decoratorLabelWidth: 80, -decoratorLabelHeight: 30, - -// Display drop shadow under and round the nodes -dropShadow: true, - -// The gap between a node and its selection highlight rectangle -nodeHighlightGap: 1, - -// The size of the node sizing area that extends around the node, over -// which the mouse pointer will change to the sizing arrows. -nodeSizingArea: 10, - -// Error indicator dimensions -errorPosition: "topLeft", -errorXPos: 24, -errorYPos: 5, -errorWidth: 10.5, -errorHeight: 10.5, - -// When sizing a supernode this decides the size of the corner area for -// diagonal sizing. -nodeCornerResizeArea: 10, - -// What point to draw the data links from and to when enableLinkType is set -// to "Straight". Possible values are "image_center" or "node_center". -drawNodeLinkLineFromTo: "node_center", - -// What point to draw the comment to node link line to. Possible values -// are "image_center" or "node_center". -drawCommentLinkLineTo: "node_center", - -// This is the size of the horizontal line protruding from the -// port on the source node when drawing an elbow or straight connection line. -minInitialLine: 30, - -// For the elbow connection type with nodes with multiple output ports, -// this is used to increment the minInitialLine so that connection lines -// do not overlap each other when they turn up or down after the elbow. -minInitialLineIncrement: 8, - -// This is the minimum size of the horizontal line entering the -// target port on the target node when drawing an Elbow connection line. -minFinalLine: 30, - -// Display input ports. -inputPortDisplay: true, - -// Object for input port can be "circle" or "image". -inputPortObject: "circle", - -// If input port object is "image" use this image. -inputPortImage: "", - -// If input port dimensions for "image". -inputPortWidth: 12, -inputPortHeight: 12, - -// Position of left single input port. Multiple input ports will be -// automatically positioned with the Y coordinate being overriden. These -// values are an offset from the top left corner of the node outline. -// Used when linkDirection is "LeftRight". -inputPortLeftPosX: 0, -inputPortLeftPosY: 20, - -// Position of top single input port. Multiple input ports will be -// automatically positioned with the X coordinate being overriden. These -// values are an offset from the top left corner of the node outline. -// Used when linkDirection is "TopBottom". -inputPortTopPosX: 80, -inputPortTopPosY: 0, - -// Position of bottom single input port. Multiple input ports will be -// automatically positioned with the X coordinate being overriden. These -// values are an offset from the bottom left corner of the node outline. -// Used when linkDirection is "BottomTop". -inputPortBottomPosX: 80, -inputPortBottomPosY: 0, - -// The 'guide' is the object drawn at the mouse position as a new line -// is being dragged outwards. -// Object for input port guide can be "circle" or "image". -inputPortGuideObject: "circle", - -// If input port guide object is "image" use this image. -inputPortGuideImage: "", - -// Display output ports. -outputPortDisplay: true, - -// Object for output port can be "circle" or "image". -outputPortObject: "circle", - -// If output port object is "image" use this image. -outputPortImage: "", - -// Output port dimensions for "image". -outputPortWidth: 12, -outputPortHeight: 12, - -// Position of right single output port. Multiple input ports will be -// automatically positioned with the Y coordinate being overriden. These -// values are an offset from the top right corner of the node outline. -// Used when linkDirection is "LeftRight". -outputPortRightPosition: "topRight", -outputPortRightPosX: 0, -outputPortRightPosY: 20, - -// Position of top single output port. Multiple input ports will be -// automatically positioned with the X coordinate being overriden. These -// values are an offset from the top left corner of the node outline. -// Used when linkDirection is "BottomTop". -outputPortTopPosX: 80, -outputPortTopPosY: 0, - -// Position of bottom single output port. Multiple input ports will be -// automatically positioned with the X coordinate being overriden. These -// values are an offset from the bottom left corner of the node outline. -// Used when linkDirection is "TopBottom". -outputPortBottomPosX: 80, -outputPortBottomPosY: 0, - -// The 'guide' is the object drawn at the mouse position as a new line -// is being dragged outwards. -// Object for output port guide can be "circle" or "image". -outputPortGuideObject: "circle", - -// If output port guide object is "image" use this image. -outputPortGuideImage: "", - -// Automatically increases the node size to accommodate its ports so both -// input and output ports can be shown within the dimensions of -// the node. -autoSizeNode: true, - -// Radius of the either the input or output ports when they are set to "circle" -portRadius: 3, - -// Size of an offset above and below the set of port arcs. -portArcOffset: 3, - -// Radius of an imaginary circle around the port. This controls the -// spacing of ports and the size of port arcs when nodeShape is set to -// port-arcs. -portArcRadius: 6, - -// Spacing between the port arcs around the ports. -portArcSpacing: 3, - -// Position of the context toolbar realtive to the node. Some adjustment -// will be made to account for the width of the toolbar. -contextToolbarPosition: "topRight", - -// Display of vertical ellipsis to show context menu -ellipsisDisplay: true, -ellipsisPosition: "topLeft", -ellipsisWidth: 10, -ellipsisHeight: 22, -ellipsisPosX: 145, -ellipsisPosY: 9, -ellipsisHoverAreaPadding: 2 - -``` -### Positioning objects -If you have nodes of varying sizes or if you have enabled re-sizeable nodes, by setting the canvas config property `enableResizableNodes` to true, it is important to note the following. - -All coordinate positions for elements are based on one of nine anchor positions around the node: -``` - "topLeft", "topCenter", "topRight", - "middleLeft", "middleCenter", "middleRight", - "bottomLeft", "bottomCenter", "bottomRight". -``` - -The PosX and PosY properties for each element is an offset from the associated anchor position where PosX is the number of pixels **to the right** of the anchor position and PosY is a number of pixels **down from** the anchor position. Negative values can be provided to specify an offset **to the left** and **up from** the anchor position. The default anchor position for all elements is `topLeft`. By the way, the top left corner of the node is also the point that the node will be positioned at based on its `x_pos` and `y_pos` fields in the pipelineFlow document. - -For example, these settings: -``` - { - imagePosition: "middleCenter", - imagePosX: -10, - imagePosY: -10, - imageWidth: 20, - imageHeight: 20 - } -}; -``` -would position the image 10 pixels left and 10 pixels above the very center of the node. Since the image is 20 x 20 pixels this would position the center of the image at the center of the node. If you have enabled re-sizeable nodes, this would keep the image centrally positioned while the node is being resized by the user. - -Elements like the node image and vertical ellipsis are positioned based on the top left corner of that element. Text is positioned based on the top left corner of its containing `
`. - -The values for `bodyPath` and `selectionPath` must be [SVG path strings](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths) which describe how to draw the node body shape and its selection highlight shape. For example, the following would draw a triangular node body and a triangular selection outline 5 pixels away from it: - -```js - bodyPath: " M 0 0 L 70 35 0 70 Z", - selectionPath: "M -5 -5 L 75 35 -5 75 Z", -``` - -## Overriding the default node layout properties -There are a couple of ways to do this depending on your needs. First, if you just want to change the appearance of **all** nodes on your canvas you can specify the `enableNodeLayout` configuration parameter in the [main canvas configuration object](/2.1-Config-Objects#config-object). The properties from this object will replace any properties in the default set, which was chosen based on the settings of `enableNodeFormatType`. So you don't need to provide all of the properties; just the ones you want to replace. - -Let's say you want your nodes to be displayed as ellipses. You could provide the following settings in `enableNodeLayout` in the canvas config: -```js -const canvasConfig = { - enableNodeLayout: { - bodyPath: " M 0 30 Q 0 0 60 0 Q 120 0 120 30 Q 120 60 60 60 Q 0 60 0 30 Z", - selectionPath: "M -5 30 Q -5 -5 60 -5 Q 125 -5 125 30 Q 125 65 60 65 Q -5 65 -5 30 Z", - defaultNodeWidth: 120, - defaultNodeHeight: 60, - imageWidth: 30, - imageHeight: 30, - imagePosX: 20, - imagePosY: 10, - labelEditable: true, - labelPosX: 60, - labelPosY: 37, - labelWidth: 90, - labelHeight: 17, // Should match the font size specified in css + padding - ellipsisDisplay: true, - ellipsisPosX: 100, - ellipsisPosY: 20, - portPosY: 30 - } -}; -``` - -## Customizing individual nodes or categories of nodes -If you want each node, or category of nodes, to have a different layout based on some criteria you can use the second method for overriding the node layout properties. This uses the [layoutHandler callback method](/2.2-Common-Canvas-callbacks#layouthandler). When you specify this callback method to common canvas, it will be called for each node on the canvas, during initialization and, occasionally, at other times. - -The method should return a simple JavaScript object that contains any node layout properties you want to override from the defaults and the ones specified in the `enableNodeLayout` field in the canvas config. This is an important point: there are three levels of properties provided where each overrides the previous set: - -1. First we take the full default set of node layout properties based on the value for `enableNodeFormatType`. -2. Then we override these with the properties from the `enableNodeLayout` field in the canvas config object, if any are provided. -3. Finally we override the combined set with any properties from the object returned from the `layoutHandler` method if one is specified. - -The callback is provided with a `data` parameter which is the node object from the pipelineFlow so your code can examine the node object and return node layout properties as appropriate. - -Note: The `layoutHandler` callback is called while the canvas is being displayed, therefore it must return very quickly each time it is called otherwise your canvas display speed will be slowed down. - -Here is a simple example of a `layoutHandler` callback method which will override the width of the node based on the width of the main label for any node where the node's `op` field is set to `Sort`: -```js -layoutHandler(data) { - let customNodeLayout = {}; - if (data.op === "Sort") { - const labLen = data.label ? data.label.length : 0; - const width = (labLen * 9) + 30; // Allow 9 pixels for each character and a bit extra for padding - customNodeLayout = { - defaultNodeWidth: width // Override default width with calculated width - }; - } - return customNodeLayout; -``` -OK, it's not a very complicated example but hopefully you get the message :) - -In the test harness, you can see an example application that use the [layoutHandler callback method](/2.2-Common-Canvas-callbacks#layouthandler). In the test harness: - -1. Open the Common Canvas side panel (click the hamburger icon) -2. Select the `Explain` sample application - -You will see the nodes have different shapes and colors based on their type. -You can examine the [Explain sample app code](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/client/components/custom-canvases/explain/explain-canvas.jsx) to see how it works. This involves these parts: - -1. [This line](https://github.com/elyra-ai/canvas/blob/64af90b1f8a1179478f3ea32749681b851d897a4/canvas_modules/harness/src/client/components/custom-canvases/explain/explain-canvas.jsx#L36) sets the `enableNodeFormatType` in the canvas config to "Vertical". This will set all of the node layout properties to their defaults for "Vertical" nodes. -2. [This line](https://github.com/elyra-ai/canvas/blob/64af90b1f8a1179478f3ea32749681b851d897a4/canvas_modules/harness/src/client/components/custom-canvases/explain/explain-canvas.jsx#L37) will override the default node layout properties with a few different values which apply to all nodes. -3. [The layout handler](https://github.com/elyra-ai/canvas/blob/64af90b1f8a1179478f3ea32749681b851d897a4/canvas_modules/harness/src/client/components/custom-canvases/explain/explain-canvas.jsx#L145) will override layout properties on a node by node basis. It calls some utility functions to translate data retrieved from the node to the appropriate layout properties. The returned node layout properties contains an array of decorations that are used to display data values from the node. -4. [This line](https://github.com/elyra-ai/canvas/blob/64af90b1f8a1179478f3ea32749681b851d897a4/canvas_modules/harness/src/client/components/custom-canvases/explain/explain-canvas.jsx#L192) specifies the `layoutHandler` to the `` object. - -## Customizing node colors and styles - -The DOM elements that make up a node can be customized using CSS styles. This is done by assigning a class name to the group `` element that is the container for all the node elements. The class can be applied to the group object is a number of different ways: - -1. By specifying it in the `app_data.ui_data.class_name` field of the node in the pipeline flow document that is provided to common-canvas using `CanvasController.setPipelineFlow(pFlow)` -2. By specifying it using the following API methods: - * CanvasController.setNodeProperties(nodeId, properties, pipelineId) - * CanvasController.setNodesClassName(nodeIds, newClassName, pipelineId) -3. By specifying a class name in the `className` field of the node layout properties in the canvas config. Like this -``` -const canvasConfig = { - enableNodeLayout: { - className: "my-node-class" - } -}; -``` -4. By specifying a class name in the `className` field of the node layout properties returned from the `layoutHandler`. - - -You can see the [svg-canvas-d3.scss file](https://github.com/elyra-ai/canvas/blob/main/canvas_modules/common-canvas/src/common-canvas/svg-canvas-d3.scss) for full details about what elements in the node can be styled but here are a list of some basic parts of the node: - -| Element | DOM Element | Class Name | -|-----------------------|-------------------|------------------------------| -| Group | `` | d3-node-group | -| --> Body Shape | `` | d3-node-body-outline | -| --> Selection Outline | `` | d3-node-selection-highlight | -| --> Label Container | `` | d3-foreign-object-node-label | -| -----> Label | `
` | d3-node-label | - -So for example if you want the node body (the rectangle) to be colored orange you would provide a class name to the group element using one of the techniques mentioned above and then put this in you CSS: - -``` -.my-node-class .d3-node-body-outline { - fill: orange; -} -``` -Note: You can use the [`enableParentClass`](/2.1-Config-Objects#enableparentclass) canvas config field to make you CSS rulesets specific so your styles are picked up in preference to the common-canvas default styles. diff --git a/guide/2.8-Context-Menu-Wrapper-Documentation.md b/guide/2.8-Context-Menu-Wrapper-Documentation.md deleted file mode 100644 index a5c55ce237..0000000000 --- a/guide/2.8-Context-Menu-Wrapper-Documentation.md +++ /dev/null @@ -1,67 +0,0 @@ -## Context Menu Wrapper - -Context Menu Wrapper is now deprecated. Carbon 11 supports a context menu component - -The context menu in common-canvas can be used in your application by importing the `ContextMenuWrapper` React component. Aside from providing a standard context menu to allow users to select different actions, this context menu also allows for configuration of submenus as a menu item, as well as a visual dividers. - -# Getting started with Context Menu -## Step 1: Import Context Menu Wrapper -To use Context Menu Wrapper in your React application you need to import the `ContextMenuWrapper` React component from the common-canvas library. It's recommended to use All Components if common-canvas is also being imported, otherwise use ContextMenuWrapper only option. - -**All Components** -```js - import {ContextMenuWrapper} from "@elyra/canvas"; -``` - -**ContextMenuWrapper only** -```js - import ContextMenuWrapper from "@elyra/canvas/dist/lib/context-menu"; -``` - -## Step 2: Pass in the correct props -* **contextMenuDef** `array` (required): an array of menu item objects consisting of action and label. You can also pass in a divider item. - -```js - const menuDef = [ - { action: ACTION.BUILD, label: "Build" }, - { action: ACTION.EXTEND, label: "Extend" }, - { action: ACTION.CLEAR, label: "Clear" }, - { divider: true }, - { action: ACTION.SCORE, label: "Score" }, - ]; - -``` - -* **containingDivId** `string` (required): the id of the element that the context menu will be absolutely positioned inside. typically, the page element is used. -* **contextMenuPos** `object` (required): the position of the context menu within the containing div. -```js - const menuPos = { x: 500 , y: 300 }; -``` - -* **contextMenuActionHandler** `func` (required): this handler is where context menu actions are defined. -```js - contextMenuActionHandler(action) { - switch (action) { - case "BUILD": - break; - case "EXTEND": - break; - default: - } - } -``` -* **closeContextMenu** `func` (required): this handler will be called when the context menu is closed. -* **stopPropagation** `bool` (optional): this is optional and only for very specific, uncommon use cases. When this flag is set, if a user clicks outside the context menu, the event will not bubble to parent elements, preventing parent event handlers from being called. - -## Example -```js - const contextMenuWrapper = ( - - ); -``` diff --git a/guide/2.9-External-Subflows-support.md b/guide/2.9-External-Subflows-support.md deleted file mode 100644 index 45b62557f0..0000000000 --- a/guide/2.9-External-Subflows-support.md +++ /dev/null @@ -1,75 +0,0 @@ -# Introduction - -The pipeline flow schema describes two ways of storing a sub-flow pipelines for a supernode: local or external. Local sub-flows are stored within the pipeline flow document whereas external pipelines are stored in a separate pipeline flow document (usually as the primary pipeline in that pipeline flow). The supernode that references an external pipeline contains a `url` property (in `.subflow_ref.url`) and a `pipeline ID` property (in `.subflow_ref.pipeline_id_ref`) to identify the external pipeline flow and the pipeline within it. - -Common-canvas supports external pipelines but the host application UI code needs to manage the storage and retrieval of any external pipeline flows. To do this the app UI code needs to: - -* Manage the storage of newly created external pipeline flows. -* Respond to calls from common-canvas to provide the external pipeline flow(s) when requested. -* Respond to call from common-canvas when a local pipeline is changed to external or an external is changed to local. - -Common-canvas supports lazy loading of external pipeline flows so they will only be requested from your code when the user performs some gesture that requires the pipeline (from within the external pipeline flow) to be displayed. - -## Creating an external sub-flow -When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true (the default) and, when a set of objects are selected from which a super node can be created, the default common-canvas context menu will include a `Create External Supernode` option. - -When the `Create External Supernode` option is clicked the `createSuperNodeExternal` action is executed. - -If your application doesn't use the default context menu you can define your own context menu (returned from `contextMenuHandler`) to contain an option which maps to the `createSuperNodeExternal` action. See the section on the [contextMenuHandler](/2.2-Common-Canvas-callbacks#contextmenuhandler) for details on how to do this. - -When the `createSuperNodeExternal` action is executed, the `beforeEditActionHandler` callback is called before the external sub-flow is created. The `beforeEditActionHandler` is called where the first parameter `data` has two properties `externalUrl` and `externalPipelineFlowId` which will both be set to empty string. Your code must set these to whatever values you want for the url and pipeline flow ID. The url will be assigned to the `subflow_ref.url` property of the supernode that is being created. The pipeline flow ID will be assigned to the newly created pipeline flow. - -Your code must return the `data` parameter from the `beforeEditActionHandler` callback if you want the action to proceed and create the sub-flow. If you need to do any asynchronous activity at this point see the documentation on the [beforeEditActionHanlder](/2.2-Common-Canvas-callbacks#beforeeditactionhandler) for details on how to do that. - - -When the sub-flow has been created common-canvas will call the `editActionHandler` callback with the `createSuperNodeExternal` action. In this callback you can, if you wish, retrieve the pipeline flow document that has been created internally in common-canvas using `CanvasController.getExternalPipelineFlow(url)`. Your code can then save it to your repository. Alternatively, you can wait until some later time, like perhaps during an auto-save, to retrieve and store the pipeline flow externally in your repository. - - -## Loading an external sub-flow -When the main pipeline flow, displayed by common-canvas, contains a super node that references an external sub-flow it will need to be loaded whenever the user performs a gesture that causes it to be displayed or processed in some way - for example displaying it 'in-place' or converting it from an external to a local supernode. An external sub-flow will also need to be loaded if the top-level pipeline being displayed has a supernode, that refers to an external pipeline, that is already expanded in-place in the saved pipeline flow JSON document being displayed. So, actions that can cause the external pipeline to be loaded are: - -* loadPipelineFlow -* expandSuperNodeInPlace -* displaySubPipeline -* convertSuperNodeExternalToLocal -* deconstructSuperNode - -When any of these actions are performed common-canvas will call the `beforeEditActionHandler` callback with the data parameter as the first parameter. The data object will have the following properties: - -* editType - The name of the action being performed. -* externalPipelineFlowLoad - This is a boolean which indicates whether the pipeline flow needs to be provided by your code. -* externalUrl - This is the string which identifies the external pipeline flow document. -* externalPipelineId - This is the ID of the pipeline being loaded -* externalPipelineFlow - If `externalPipelineFlowLoad` if true this will be undefined. Otherwise it will be contain the previously loaded external pipeline flow. - -You need to implement the `beforeEditActionHandler` so that: - -* when the actions above are being performed and externalPipelineFlowLoad is true, you retrieve the external pipeline flow from your repository -* you then assign it to the `externalPipelineFlow` property of the data object -* you then return the data object from the callback. - -Your code must return the `data` parameter from the `beforeEditActionHandler` callback if you want the action to proceed and load the external pipeline flow. If you need to do any asynchronous activity at this point see the documentation on the [beforeEditActionHanlder](/2.2-Common-Canvas-callbacks#beforeeditactionhandler) for details on how to do that. - -## Converting a local supernode to an external supernode -When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true, and a local supernode's is right clicked, the default common-canvas context menu will include a `Convert local to external` option. This will execute the `convertSuperNodeLocalToExternal` action. - -The `convertSuperNodeLocalToExternal` action is similar to the `createSuperNodeExternal` action in that a new external pipeline flow is being created. Consequently, you can follow the instructions in the [Creating an external sub-flow](/2.9-External-Subflows-support#creating-an-external-sub-flow) section for providing the appropriate properties of the `data` object in the `beforeEditActionHandler` and `editActionHandler` callbacks. - -## Converting an external supernode to a local supernode -When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true, and an external supernode's is right clicked, the default common-canvas context menu will include a `Convert external to local` option. This will execute the `convertSuperNodeExternalToLocal` action. - -The `convertSuperNodeExternalToLocal` action is similar to the `expandSuperNodeInPlace` action in that an external pipeline flow may need to be retrieved from your repository. Consequently, you can follow the instructions in the [Loading an external sub-flow](/2.9-External-Subflows-support#loading-an-external-sub-flow) section for providing the appropriate properties of the `data` object in the `beforeEditActionHandler` callback. - -## Deleting an external supernode/sub-flow -When the user deletes an external supernode/sub-flow the supernode will be removed from the canvas. You code does not need to do anything unless you want to also remove the external pipeline flow from your repository. - -## Clipboard support -When a supernode, that refers to an external pipeline, is cut/copied and pasted, the pasted supernode refers to the same external pipeline as the supernode that was cut or copied. This means that if an external supernode is copied to the clipboard and then pasted into the same canvas the result will be two supernodes that refer to the same external pipeline.   - -The same situation can occur if a supernode, that refers to an external pipeline, is in the palette and that node is dragged multiple times from the palette onto the canvas. - -## Manipulating objects in external pipelines using the Canvas Controller API -Objects (nodes, links comments, etc.) in an external pipeline can be updated by the host application calling the `CanvasController` API. However, such changes are only effective within common-canvas. It is the host application's responsibility to make sure these changes are persisted in the external pipeline flow document (if that is the behavior that is required). This can be done by the host application calling `CanvasController.getExternalPipelineFlow(url)` and then saving the returned document to the appropriate repository. - -## External pipelines in the Elyra Canvas Test Harness -The Test Harness supports external pipeline flows but will only persist any saved flows for the current session. (It just stores them in memory). You can examine the `beforeEditActionHandler` and `editActionHandler` in App.js in the test harness to see how it handles the different actions for managing external pipeline flows. \ No newline at end of file diff --git a/guide/3.0-Common-Properties-documentation.md b/guide/3.0-Common-Properties-documentation.md deleted file mode 100644 index cd8397502f..0000000000 --- a/guide/3.0-Common-Properties-documentation.md +++ /dev/null @@ -1,315 +0,0 @@ -## Introduction -Common properties displays controls to view and set property values. - -You can look at the harness/src/client/App.js file of this repo to see examples of code that uses the common properties component. - - -# Getting started with Common Properties programming - -_Note: There are two ways one can use the Common Properties tooling: Either by allowing the form to be built dynamically from a parameterDef JSON (which is comprised of the base property set, ui-hints, conditions, and resources), or by explicitly providing the dialog form for rendering (deprecated). The first approach is recommended as an easier and clearer interface_ - - This takes 3 easy steps: - -## Step 1 : Import -To use Common Properties in your React application you need to do the following. First import the CommonProperties React component from the common-canvas library. Elyra Canvas produces both esm and cjs outputs. By default esm will be used when webpack is used to build the consuming application. - -```js - import { CommonProperties } from "@elyra/canvas"; -``` -**Properties Only** - -To import only common properties functionality in `cjs` format use: - -```js - import { CommonProperties } from "@elyra/canvas/dist/lib/properties"; -``` - - -## Step 2 : Set the data -Next you'll need to populate propertiesInfo with: - -```js -propertiesInfo: { - parameterDef: this.parameterDef, // Parameter definitions/hints/conditions - appData: "{user-defined}", // User data returned in applyPropertyChanges [optional] - additionalComponents: "{components}", // Additional component(s) to display [optional] - messages: "[node_messages]", // Node messages array [optional] - expressionInfo: this.expressionInfo, // Information for expression builder [optional], - initialEditorSize: "{size}", // This value will override the value of editor_size in uiHints. This can have a value of "small", "medium", "large", or null [optional] - id: "{id}" // Unique parameter definition ID [Optional] -} -``` -[parameterDef schema and examples](https://github.com/elyra-ai/pipeline-schemas/tree/master/common-canvas/parameter-defs) -[3.1 Common Properties Parameter Definition](/3.1-Common-Properties-Parameter-Definition) -[`expressionInfo` schema and examples](https://github.com/elyra-ai/pipeline-schemas/tree/master) - -or... - -(Deprecated) -```js -propertiesInfo: { - formData: this.formData, - appData: "{user data returned back in applyPropertyChanges}", //optional - additionalComponents: "{additional control(s) to display}", //optional - messages: "[node_messages]", // Node messages array [optional] - expressionInfo: this.expressionInfo, // Information for expression builder [optional] - initialEditorSize: "{size}", // This value will override the value of editor_size in uiHints. This can have a value of "small", "medium", "large", or null [optional] - id: "{id}" // Unique parameter definition ID [Optional] -} -``` -formData [schema](https://github.com/elyra-ai/pipeline-schemas/tree/master/common-canvas/form) -form information [wiki](https://github.com/elyra-ai/wml-canvas-service/wiki/2.-Runtimes-And-Operators) - -The optional messages attribute can be used to set validation messages associated with a node. The format of the message objects is defined in [Pipelin Flow UI schema](https://github.com/elyra-ai/pipeline-schemas/blob/master/common-pipeline/pipeline-flow/pipeline-flow-ui-v1-schema.json) - -## Step 3 : Display the properties editor - -Finally you'll need to display the editor. Inside your render code, add the following: -```html -import { IntlProvider } from "react-intl"; -var i18nData = require("../intl/en.js"); - -var locale = "en"; -var messages = i18nData.messages; - - { - this.CommonProperties = instance; - }} - propertiesInfo={this.propertiesInfo} // required - propertiesConfig={this.propertiesConfig} // optional - callbacks={this.callbacks} // required - customPanels={[CustomSliderPanel, CustomTogglePanel]} //optional - customControls={[CustomSliderControl]} // optional - light // optional - /> - -``` -**Properties** - -- propertiesInfo `object`: See above -- propertiesConfig `object`: - - containerType `string`: type of container to display the properties, can be "Modal", "Tearsheet", or "Custom". default: `"Custom"` - - rightFlyout `boolean`: If set to true, groups will be displayed as an accordion. If false, groups are displayed as tabs. default: `false` - - applyOnBlur `boolean`: calls applyPropertyChanges when focus leave common-properties. default: `false` - - disableSaveOnRequiredErrors `boolean`: Disable the properties editor "save" button if there are required errors - - enableResize `boolean`: adds a button that allows the right-side fly-out editor to expand/collapse between small and medium sizes. default: `true` - - conditionReturnValueHandling `string`: used to determine how hidden or disabled control values are returned in applyPropertyChanges callback. Current options are "value" or "null". default: `"value"` - - buttonLabels `object`: - - primary `string`: Label to use for the primary button of the properties dialog - - secondary `string`: Label to use for the secondary button of the properties dialog - - heading `boolean`: show heading and heading icon in right-side fly-out panels. default: `false` - - schemaValidation `boolean`: If set to true, schema validation will be enabled when a parameter definition has been set in CommonProperties. Any errors found will be reported on the browser dev console. It is recommended you run with schema validation switched on while in development mode. - - applyPropertiesWithoutEdit `boolean`: When true, will always call `applyPropertyChanges` even if no changes were made. default: `false` - - maxLengthForMultiLineControls `number` - maximum characters allowed for multi-line string controls like textarea. default: 1024 - - maxLengthForSingleLineControls `number` - maximum characters allowed for single-line string controls like textfield. default: 128 - - convertValueDataTypes `boolean` - Default false. If set to true, currentParameter values whose data type does not match what is defined in the parameter definitions will be converted to the specified data type. - - trimSpaces `boolean` - Default true. If set to false, condition ops(`isEmpty`, `isNotEmpty`) and `required` fields are allowed to only contain spaces without triggering condition errors. - - showRequiredIndicator `boolean` - Default true to show `(required)` indicator. If set to false, show `(optional)` indicator next to properties label. - - showAlertsTab `boolean` - Default true to show "Alerts" tab whenever there are error or warning messages. If set to false, Alerts tab won't be displayed. - - returnValueFiltering `array` - Default []. When set this will filter out any values in the array in the parameters returned when `applyPropertyChanges` is call. Only primitive data types are currently supported. - - categoryView `string` - View categories in right-flyout. Can be `"accordions"` or `"tabs"`. default: `"accordions"`. -- callbacks object - See [callbacks](#callbacks) section for more details on each callback method. -- customPanels `array`: array of custom panels. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-panels) for more details. -- customControls `array`: array of custom controls. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-controls) for more details. -- customConditionOps `array`: array of custom condition operators. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-condition-operators) -- light `boolean`: Carbon controls in common-properties will use light mode. When the `light` option is disabled, the background color will be the same as the Carbon theme background. When the `light` option is enabled, the background color is set to $ui-01. Defaults to `true` - -**Internationalization and override of labels in CommonProperties** -The CommonProperties dialogs have a set of labels that can have customized and internationalized values. CommonProperties uses the react-intl package to provide internationalization of these labels. This requires the `IntlProvider` element to wrap the `CommonProperties` element. -You can look at the **harness/src/intl/en.js** file of this repo to see the list of labels and the default values. - -**Reference methods** -```js -/* -* @closeEditor (boolean) - determines if closePropertiesDialog is called or not -*/ -applyPropertiesEditing(closeEditor) -``` - - -### Using CommonProperties in CommonCanvas right-flyout panel - -[Common Canvas](/2.0-Common-Canvas-Documentation#step-3--display-the-canvas) has a right-flyout panel that can render a React object. It can be used to render Common Properties in a flyout panel. - -Create a CommonProperties object with containerType set to "Custom" and rightFlyout set to true. -```html - const rightFlyoutContent =(); -``` -Pass the CommonProperties object into CommonCanvas's rightFlyoutContent props. Also set the showRightFlyout boolean to tell CommonCanvas when to show the rightFlyout. -```html - -``` - -# Callbacks - -### applyPropertyChanges(propertySet, appData, additionalInfo, undoInfo, uiProperties) -Executes when the user clicks `OK` in the property dialog. This callback allows users to save the current property values. - -- propertySet: The set of current property values -- appData: (optional) application data that was passed in to `propertiesInfo` -- additionalInfo: Object with additional information returned: - - messages: (optional) An array of messages associated with the nodes current property values. - - title: The title of the properties editor -- undoInfo: Object with information needed to undo this apply: - - properties: Set of property values; - - messages: (optional) An array of messages associated with the nodes property values. - - uiProperties: (optional) Set of UI only properties values -- uiProperties: The set of UI only property values (optional) - -```js -applyPropertyChanges(propertySet, appData, additionalInfo, undoInfo, uiProperties) { - var data = { - propertySet: propertySet, - appData: appData, - additionalInfo: { - messages: messages, - title: title - } - }; -} -``` - -### closePropertiesDialog(closeSource) -Executes when user clicks `Save` or `Cancel` in the property editor dialog. This callback is used to control the visibility of the property editor dialog. `closeSource` identifies where this call was initiated from. It will equal "apply" if the user clicked on "Save" when no changes were made, or "cancel" if the user clicked on "Cancel" - -```js -closePropertiesDialog() { - this.setState({ showPropertiesDialog: false, propertiesInfo: {} }); -} -``` - -### propertyListener() -Executes when a user property values are updated. - -```js -propertyListener(data) { - -} -``` - -### controllerHandler() -Executes when the property controller is created. Returns the property controller. See [here](/3.6-Common-Properties-Controller) for APIs - -```js -controllerHandler(propertyController) { - -} -``` - -### actionHandler() -Called whenever an action is ran. `id` and `data` come from uihints and appData is passed in with propertiesInfo. - -```js -actionHandler(id, appData, data) { - -} -``` - -### buttonHandler() -Called when the edit button is clicked on in a `readonlyTable` control, or if a custom table button is clicked. The callback provides the following data: - -- data: an object that consists of - - type: of button the click was invoked from. - - `edit` is returned from the edit button click of a `readonlyTable` control. - - `custom_button` is returned from the custom button click of a complex type control. - - propertyId: of the control that was clicked. - - buttonId: of the button that was clicked from a custom table button. - -```js -buttonHandler(data) { - -} -``` - -### buttonIconHandler() -Called when there is a `buttons` uihints set in the `complex_type_info` section of the parameter definition. This buttonIconHandler expects a Carbon Icon jsx object as the return value from the callback. This is used to display the Carbon icon in the custom table button. The buttonIconHandler provides the following data: - -- data: an object that consists of - - type: `customButtonIcon` - - propertyId: of the control that was clicked. - - buttonId: of the button that was clicked from a custom table button. - - carbonIcon: The name of the Carbon icon specified in the uihints. The corresponding jsx object is expected to be returned in the callback. - -```js -buttonIconHandler(data, callbackIcon) { - if (data.type === "customButtonIcon" && data.carbonIcon === "Edit32") { - callbackIcon(); - } -} -``` - -### helpClickHandler() -Executes when user clicks the help icon in the property editor dialog. The callback provides the following data: - -- nodeTypeId: in case of parameterDef, id property of uihints; in case formData, the componentId. -- helpData: Optional helpData specified in paramDef/formData (see below). -- appData: Optional application data that was passed in to `propertiesInfo` -```js -helpClickHandler(nodeTypeId, helpData, appData) { - -} -``` -To control whether a node shows the help icon in the right fly-out, a help object with optional helpData needs to be provided in the paramDef or formData: -- paramDef: Provide help object in operator's uihints. If help object exists, the icon will be shown. Optionally, provide a helpData object within the help object, which will be passed in the helpClickHandler callback. -https://github.com/elyra-ai/pipeline-schemas/blob/master/common-pipeline/operators/uihints-v2-schema.json#L64 -- formData: add help object to form definition. The -https://github.com/elyra-ai/pipeline-schemas/blob/master/common-canvas/form/form-v2-schema.json#L51 - -If no help object is found, no help link will be shown. - - -### titleChangeHandler() -Called on properties title change. This callback can be used to validate the new title and return warning or error message if the new title is invalid. This callback is optional. - -In case of error or warning, titleChangeHandler should call callbackFunction with an object having type and message. If the new title is valid, no need to call the callbackFunction. -```js -titleChangeHandler(title, callbackFunction) { - // If Title is valid. No need to send anything in callbackFunction - if (title.length > 15) { - callbackFunction({ - type: "error", - message: "Only 15 characters are allowed in title." - }); - } -} -``` -where: - -- type (string, required): This must be one of two values: "warning" or "error". -- message(string, required): Error or warning message. There is no restriction on length of the message. - - - -### propertiesActionLabelHandler() -```js -propertiesActionLabelHandler() -``` -This is an optional handler you don't need to implement anything for it unless you want to. This callback allows your code to override the default tooltip text for the `Undo` and `Redo` buttons. -The `propertiesActionLabelHandler` callback, when provided, is called for the save properties action that is performed in common-properties. This callback should return a string or null. If a string is returned it will be shown in the tooltip for the `Undo` button in the toolbar preceded by "Undo:" and the string will also appear in the tooltip for the `Redo` button (when appropriate) preceded by "Redo:". If null is returned, common-properties will display the default text `Save {node_name} node properties` for the Undo and Redo buttons. - -### tooltipLinkHandler() -Optional callback used for adding a link in properties tooltips. link object must be defined under description in uiHints parameter info. Common-properties internally pass the link object to tooltipLinkHandler callback. -This callback must return an object having url and label. - -```js -tooltipLinkHandler(link) { - return { url: "https://www.google.com/", label: "More info" }; -} -``` - diff --git a/guide/3.1-Common-Properties-Parameter-Definition.md b/guide/3.1-Common-Properties-Parameter-Definition.md deleted file mode 100644 index 31ec395383..0000000000 --- a/guide/3.1-Common-Properties-Parameter-Definition.md +++ /dev/null @@ -1,261 +0,0 @@ -# Parameter Definitions -The parameter definition json files is an easy way to provide input for controlling the common properties dialog. It consists of information that is available in the operator json combined with UI hints, information on data sets, and resources. - -The parameter definition has a defined schema and set of examples located here: -[schema and examples](https://github.com/elyra-ai/wdp-pipeline-schemas/tree/master/common-canvas/parameter-defs) - -The parameter definition consists of eight sections. - -## Title Definition - -The title of the properties editor. If `editable` is set to true (default), the title can be edited. If set to false, the title will be readonly. - -```js -"titleDefinition": { - "title": "Properties Title", - "editable": true - } -``` - -## Current Parameters - -A list of input parameters and initial values upon input. The list is a set of key/value pairs with the key being the field name and the value is the initial value. - -Example -```js -"current_parameters": { - "targetField": [], - "inputFieldList": [], - "elasticNetParam": 0.0, - "fitIntercept": false, - "maxIter": 75, - "regParam": 0.1, - "standardization": true, - "threshold": 0.5, - "tol": 0.0000010 - } -``` - -## Parameter Definitions -The list of parameters definitions for this property dialog. The list contains the name of the parameter, the data type of the parameter, the role and the default value. The information provided is as needed by the backend engine, i.e. the parameter name should be the name of the parameter that is expected for the backend engine. - -The list of parameter definitions has the following attributes. -* `id` (*string*) **Required** Parameter identifier as consumed by the backend engine. -* `default` (*any*) The default value of the parameter. -* `enum` (*array[string]*) A restricted list of string values that are valid for the field. -* `type` (*string*) Parameter type as consumed by the backend engine. -* `role` (*string*) Parameter role, which is an optional specialization of the type. -* `required` (*boolean*) Indication whether parameter is required or optional. - - -Parameter types have one of a fixed set of basic types. These are: - -* `integer` -* `double` -* `string` -* `date` -* `time` -* `timestamp` -* `custom` - -These can be used as maps or arrays e.g.: - - array[]: a sequence or list of values - -Parameter roles defined by the role attribute can be one of: - -* `expression`: an expression assumed to be in the expression language for the run time -* `column`: value represents one or more columns from the data model visible to this operator -* `new_column`: value represents the name of a new column to be added to the data model and must therefore not match an existing column and conform to existing syntactic restrictions. - - -Example -```js -"parameters": [ - { - "id":"targetField", - "type":"string", - "default":"", - "role":"column" - }, - { - "id":"inputFieldList", - "type":"array[string]", - "default":[], - "role":"column" - }, - { - "id": "impurity", - "enum": [ - "gini", - "entropy" - ], - "default": "gini" - }, - { - "id":"elasticNetParam", - "type":"double", - "default":0.0 - } -] -``` -## UI-only Parameters -A list of input parameters and initial values upon input. This set of parameters are separated from the backend parameters (current parameters). The idea is that these parameters are not passed into the backend engine by the common properties consumer. - -Example -```js -"current_ui_parameters": { - "databaseResource": true, - "tol": 0.0000010 - } -``` - -UI-only parameters require information about the parameters same as the parameter definition information used for the backend parameters. The UI-only parameter definition information is stored in the UI-hints section in the sub-section named `ui_parameters`. A description of the UI hints specifications can be found here: [3.2 Common Properties UI Hints](/3.2-Common-Properties--UI-Hints) - - -UI-only properties are returned to the consuming application via a separate parameter on the applyPropertiesChanges callback. See the `Callbacks` section of [3.1 Common Properties Documentation section.](/3.0-Common-Properties-documentation) - - -## Complex Types -The complex types section is an array of - -The complex types have the following attributes. -* `id` (*string*) **Required** Identifier of complex type, can be referenced in other places. -* `type` (*string*) If `object` is specified, common properties will return the values as an array of objects consisting of key value pairs. This defaults to `array`. -* `key_definition` (*object*) A parameter definition attribute on the key parameter field. -* `parameters` (*object*) **Required** List of parameters fields. Each parameter can be defined as a parameter definition attribute or a complex type attribute. - - -Example of complex types -```js -"complex_types": [ - { - "id": "SortEntry", - "type": "object", - "key_definition": { - "id": "field", - "type": "string", - "role": "column", - "default": "" - }, - "parameters": [ - { - "id": "sort_order", - "enum": [ - "Ascending", - "Descending" - ], - "default": "Ascending" - } - ] - } - ] -``` - -### A Note on Parameters and Complex Types: -Note that both parameter and complex type definitions are in the exact same format as defined in the operator schema. Therefore the contents of operator JSON files can be used for these two sections. - - -## UI Hints -A set of specifications for controlling the layout and flow of the common properties. A description of the UI hints specifications can be found here: [3.2 Common Properties UI Hints](/3.2-Common-Properties--UI-Hints) - -## Conditions -A set of specifications for controlling validation checking of parameters during the common properties dialog. A description of the Conditions specifications can be found here: -[3.4 Common Properties Conditions](/3.4-Common-Properties-Conditions) - -## Data Set Metadata -The data set metadata is an array of datarecord-metadata objects as defined in the datarecord-metadata JSON schema. Each datarecord-metadata object contains and array of fields that provide column information on the input data set. [schema and examples](https://github.com/elyra-ai/pipeline-schemas/tree/main/common-pipeline/datarecord-metadata) - -The fields have the following attributes. -* `name` (*string*) **Required** Field name. Must be unique within the dataset. -* `type` (*string*) **Required** Field type. Can be a primitive type (string, integer, double, date, time, timestamp), or a vector, map, or struct containing those types. Required. -* `nullable` (*boolean*) Indicates whether or not one can place null values into the field. Default: False. -* `metadata` (*object*) A set of additional metadata attributes. - -The additional metadata attributes are as follows. -* `description` (*string*) A description of the field. -* `measure` (*string*) The field measurement type. The value can be one of the following. `range, discrete, flag, set, ordered-set, typeless, collection, geospatial, default` -* `role` (*string*) Field role for modeling. The value can be one of the following. -`input, -target, -both, -none, -partition, -split, -frequency, -record-id` -* `max_string_length` (*number*) Maximum character length for string fields. Length is unlimited when not present. -* `values` (*array[string]*) Array of unique categorical values for the column. -* `ranges` (*object*) Minimum and maximum discovered values for scalar data. - -Example -```js -"dataset_metadata": [ - { - "name": "Schema-1", - "fields": [ - { - "name": "Age", - "type": "integer", - "metadata": { - "description": "", - "measure": "range", - "role": "input" - } - }, - { - "name": "Sex", - "type": "string", - "metadata": { - "description": "", - "measure": "discrete", - "role": "input" - } - }, - { - "name": "BP", - "type": "string", - "metadata": { - "description": "", - "measure": "discrete", - "role": "input" - } - } - ] - }, - { - "name": "Schema-2", - "fields": [ - { - "name": "Birthdate", - "type": "date", - "metadata": { - "description": "Date of birth", - "measure": "range", - "role": "input" - } - } - ] - } -] - -``` - -## Resources -This is a map of string resources. - -Example: -```js -"resources":{ - "org.apache.spark.ml.classification.DecisionTreeClassifier.label":"Random Forest Classifier", - "org.apache.spark.ml.classification.DecisionTreeClassifier.desc":"Fitted Random Forest Classification Model", - "inputFieldList.label":"Input columns", - "inputFieldList.desc":"Select one or more input columns", - "targetField.label":"Target column", - "targetField.desc":"Select a target column", - "max_depth_not_valid":"The max depth parameter must be greater than or equal to zero", - "max_iter_not_valid": "The max iterations parameter must be greater than or equal to zero", - "min_instances_per_node_not_valid": "The minimum instances per node value must be >= 1", - "subsampling_rate_not_valid": "The subsampling rate value must be > 0 and <= 1" -} -``` \ No newline at end of file diff --git a/guide/3.2-Common-Properties-UI-Hints.md b/guide/3.2-Common-Properties-UI-Hints.md deleted file mode 100644 index 014d2a617e..0000000000 --- a/guide/3.2-Common-Properties-UI-Hints.md +++ /dev/null @@ -1,348 +0,0 @@ -# UI Hints -UI hints is a section of the property definition json and contains specifications to assist in the presentation and flow of the property dialog. The specifications indicate which controls to use to display and gather input on the fields. -[uihints schema](https://github.com/elyra-ai/wdp-pipeline-schemas/blob/master/common-pipeline/operators/uihints-v1-schema.json) - -The UI Hints section consists a set of simple and complex attributes. - -**The simple attributes are:** - -* `id` (*string*) Dialog id. -* `label` (*object*) External name of dialog. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) -* `description` (*object*) Description of dialog. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) -* `editor_size` (*string*) The width of the properties editor panel. This can have a value of `"small"`, `"medium"`, `"large"` or `"max"`. The default is `"small"`. - - When `"small"` is specified the properties panel is displayed with a default width of 320px and with a resize button that allows the panel to be increased in size up to the `"medium"` size which is 480px. - - When `"medium"` is specified the properties panel has a width of 480px and with a resize button that allows the panel to be increased in size up to the `"large"` size which is 640px. - - When `"large"` is specified the properties panel has a width of 640px and with a resize button that allows the panel to be increased in size up to the `"max"` size which is 900px. - - When `"max"` is specified the properties panel has a width of 900px and no resize button is displayed. -* `pixel_width` (*object*) This optional property gives finer control over the minimum and maximum sizes of the properties editor panel. If this is omitted the properties editor width is controlled by the `editor_size` property. `pixel_width` is an object with two properties `min` and `max` which are both numbers. - - If `min` is specified it overrides the default size of the shrunken panel and `max` is based on the `editor_size` value. - - If `max` is specified it overrides the default size of the expanded panel and `min` is based on the `editor_size` value. - - If `editor_size` is set to `"large"` only the `max` value will be used to specify the size of the panel and no resize button will be displayed. - - A warning will be displayed in the console if you specify an invalid value for either `min` or `max` such as making `min` greater than `max`. - -Example of the simple attributes: -```js -"uihints": { - "id":"org.apache.spark.ml.ibm.transformers.Distinct", - "icon": "images/transformationspark.svg", - "label": { - "default": "Distinct" - }, - "editor_size": "medium", - "pixel_width": { - "min": 400, - "max": 800 - }, - "description": { - "default": "Remove rows to leave only rows with distinct combinations of rows" -} -``` - - - -**The complex attributes of the UI hints section are:** -## Group-info - -Group info attributes. - -* `id` (*string*) **Required** Panel id -* `type` (*string*) The group type to be displayed. see Group/Panel Controls in [3.3 Common Properties Controls](/3.3-Common-Properties-Controls). -* `depends_on_ref` (*string*) Property name this group depends upon. Valid for panelSelector groups only. -* `label` (*object*) Group label. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) -* `description` (*object*) Group description. Only used with `textPanel` and `actionPanel`. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) - + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) - + `link` (object) Optional link in the description. [tooltipLinkHandler callback](/3.0-Common-Properties-documentation#tooltiplinkhandler) must be defined whenever link object is added in uiHints.. - + `id` (string) Required unique link id. - + `data` (object) Data passed to the tooltipLinkHandler callback. -* `parameter_refs` (*array[string]*) List of parameter to be displayed. -* `action_refs` (*array[string]*) List of action to be displayed. Used with `actionPanel` only. -* `group_info` (*object*) List of additional group information. -* `data` (*any*) Returned in custom panel constructor without any changes. -* `insert_panels` (*boolean*) Indicates whether panels, contained with a panelSelector, should be inserted between the radio buttons of a radio button set indicated by the depends_on_ref parameter. -* `nested_panel` (*boolean*) Indicate whether panel should be nested. Nested panels are indented by 16px from the left and display left border. Default is false. -* `class_name` (*string*) Optional classname for this group -* `open` (*boolean*) Optional used to determine if a panel should be open or not by default. Used with `twistyPanel` only. Default is `false`. - - -Example group info section: -```js -"group_info": [ - { - "id": "settings", - "label": { - "default": "Settings" - }, - "type": "columnSelection", - "parameter_refs": [ - "keys" - ] - } - ] -``` - -## UI-only Parameters -UI-only parameters require information about the parameters same as the parameter definition information used for the backend parameters. The UI-only parameter definition information is stored in the UI-hints section in the sub-section named `ui_parameters`. The format of the information in the `ui_parameters` sub-section is documented in the `Parameter Definition` section of [Common Properties Parameter Definition](/3.1-Common-Properties-Parameter-Definition/). - -Example -```js -"ui_parameters": [ - { - "id":"databaseResource", - "type":"boolean", - "default":true - }, - { - "id":"toi", - "type":"double", - "default":0.0 - } -] -``` - -The UI-only parameters need to be added to other UI Hints sections (for example `Group Info` and canbe refered to by the `parameter_ref` field just like backend parameters. - -## Parameter Info -The parameter info section contains the list of parameters to gather values on through the property dialogs and UI hints about each parameter. The UI hints provide information to facilitate the UI controls used to display the parameter in the property dialogs. - -Parameter info attributes. - -* `parameter_ref` (*string*) **Required** Parameter name. -* `label` (*object*) External name for parameter. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) -* `label_visible` (*boolean*) Determines whether to display the label for a control. -* `description` (*object*) Description of parameter with optional placement context. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) - + `placement` (*string*) Placement context for the text. Valid values are `as_tooltip, on_panel`. - + `link` (*object*) Optional link in the description. [tooltipLinkHandler callback](/3.0-Common-Properties-documentation#tooltiplinkhandler) must be defined whenever link object is added in uiHints.. - + `id` (*string*) Required unique link id. - + `data` (*object*) Data passed to the tooltipLinkHandler callback. -* `control` (*string*) Which control to use. see Parameter Controls in [3.3 Common Properties Controls](/3.3-Common-Properties-Controls). -* `increment` (*number*) Determines the increment/decrement value for the spinner control only. The default value is `1`. -* `orientation` (*string*) Determines how the control is displayed. Valid values are `vertical, horizontal`. -* `width` (*number*) Column width for tables. The widths provided for table columns are used to calculate relative widths for each table column. So for example a 3 column table with widths of 20, 30, and 50 would use 20%, 30%, and 50% of the overall table width, respectively. -* `char_limit` (*number*) Limits the number of characters a user can enter into the control for string parameters only. -* `display_chars` (*number*) This has been deprecated and is subject to removal. Limits the number of characters displayed for a text field in a column in a table. The text will have an ellipsis appended at this limit. Defaults to 64 characters. -* `separator` (*string*) Determines where to put a separator relative to the current control. Valid values are ` after, before`. -* `visible` (*boolean*) Determines whether to display control in a table cell. Used in complex types only. -* `place_holder_text` (*object*) Text hint for the user displayed input controls. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) -* `resource_key` (*string*) Used as a key for enum value labels in the resources section of property definition. -* `edit_style` (*string*) Editing style of elements in a table. Valid values are `subpanel, inline, on_panel`. -* `value_icons` (*array[string]*) For enumerated types, this defines the set of icons for the valid values. The ordering must be consistent with the order in the parameter enum attribute. -* `filterable` (*boolean*) Determines if this column values can be filtered so that only rows that match the filter in column values are shown in the table. Applies to complex parameters only. -* `sortable` (*boolean*) Determines if this column values can be sorted into ascending/descending order in a table. Applies to complex parameters only. -* `number_generator` (*object*) Describes a number generator button beside numeric control. The 'label' element is a standard resource item, and the 'range' element contains 'min' and 'max' attributes to constrain the range of generated numbers. -* `dm_default` (*string*) Data record metadata field to be used for default values in table cell columns. Typically this is used with parameters in complex structures in which the key field is a column name. Valid values are `type`, `description`, `measure`, and `modeling_role`. -* `dm_image` (*string*) This can be set to display an icon of the corresponding dm type in the `role`:`column` field of a table. Valid values are `measure`, `type`, `none` -* `summary` (*boolean*) Determines if parameter should be shown in the summary when using a `summaryPanel`. -* `text_before` (*object*) Text to be displayed before the control - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) - + `type` (*string*) Adds a icon and additional formatting to the text. Only `info` is support at this time. - + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) -* `text_after` (*object*) Text to be displayed after the control - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) - + `type` (*string*) Adds a icon and additional formatting to the text. Only `info` is support at this time. - + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) -* `custom_control_id` (*string*) Id that is used to determine which custom control to use when `control=custom` -* `data` (*any*) Returned in custom control constructor without any changes. -* `rows` (*integer*) Number of rows to show in a table before scrolling starts. If one table in a panel is set to -1, that table will use the remaining available vertical space, down to a minimum of 2 rows. Used in expression and code controls to determine the number of rows to show for those controls. -* `moveable_rows` (*boolean*) Determines if rows can be moved up or down in a table or array of strings. -* `action_ref` (*string*) An action to be displayed. -* `date_format` (*string*) A format string such as YYYY-MM-DD which describes the display and entry format for a date field. -* `time_format` (*string*) A format string such as HH:mm:ss which describes the display and entry format for a time field. -* `custom_value_allowed` (*boolean*) Determines if a dropdown, outside of a table, can allow a custom value to be entered. -* `class_name` (*string*) Optional classname for this parameter -* `resizable` (*boolean*) Determines if this column can be resized in a table. When a column is resized, width of all the columns to the right of resized column is adjusted. Applies to structure parameters only. Default is `false`. - -Example parameter info section: -```js - "parameter_info": [ - { - "parameter_ref": "keys", - "label": { - "resource_key": "sort.keys.label" - }, - "description": { - "resource_key": "sort.keys.desc", - "placement": "on_panel" - }, - "rows": -1 - } - ] -``` - -## Complex Type Info -The complex_type_info section defines complex data types. This section is needed if in the `parameters` section of the parameter definition, one of the parameters has a type that is not the base type (i.e. an array or map of base types). The type of control used for this definition depends on the group info type value. - -Complex Type info attributes. - -* `complex_type_ref` (*string*) **Required** Name of complex type, can be referenced in other places. -* `key_definition` (*string*) A set of parameter info attributes about the key parameter. -* `label` (*object*) External name of subpanel. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) -* `parameters` (*object*) **Required** List of parameters that are part of this complex parameter. This parameter can either have a set of parameter_info attributes or other nested complex_type_info attributes. -* `header` (*boolean*) If `true` then the table has a header row with column names. Defaults to `true`. -* `add_remove_rows` (*boolean*) If `true` then the table can have rows added and removed. Defaults to `true`. -* `include_all_fields` (*boolean*) When `true` and `add_remove_rows` is `false`, ensures that all fields are included in the control at all times. -* `row_selection` (*string enum*) How many rows in a table can be selected at a time. - + `single`: only one row at a time is able to be selected. - + `multiple`: multiple rows at a time are able to be selected. - + `multiple-edit`: select multiple rows and allow the editing of column values of all selected rows. -* `buttons` (*array*) An array of objects that define custom buttons to be displayed in this complex structure, overriding any default buttons. Each button object contains the following properties: - + `id` (*string*) **Required**: Unique identifier used to identify the button in the callback function. - + `label` (*object*): Button label to display. If an icon is specified as well, the icon will be shown to the right of the label. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) - + `description` (*object*): Tooltip text to display when the button is hovered. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) - + `icon` (*string*): URL to .svg image to display. - + `carbon_icon` (*string*): Host provided name of Carbon icon to display. A callback function is required for the host application to return the jsx icon object imported from @carbon/icons-react library. - + `enabled` (*boolean*): Button will be enabled if true, disabled if false. - + `divider` (*string enum*): Display a divider before or after this button. Defaults to `after` - + `before` Display divider before this button - + `after` Display divider after this button - -Example complex_type_info section: -```js - "complex_type_info": [ - { - "complex_type_ref": "SortEntry", - "row_selection": "multiple", - "moveable_rows": true, - "add_remove_rows": false, - "include_all_fields": true, - "key_definition": { - "parameter_ref": "field", - "width": 28, - "label": { - "resource_key": "SortEntry.field.label" - } - }, - "parameters": [ - { - "parameter_ref": "sort_order", - "width": 16, - "resource_key": "SortEntry.sort_order", - "label": { - "resource_key": "SortEntry.sort_order.label" - }, - "control": "toggletext", - "value_icons": [ - "/images/up-triangle.svg", - "/images/down-triangle.svg" - ] - } - ] - }, - { - "complex_type_ref": "FieldStorageEntry", - "key_definition": { - "parameter_ref": "field", - "label": { - "default": "", - "resource_key": "FieldStorageEntry.field" - }, - "width": 26, - "sortable": true, - "filterable": true - }, - "parameters": [ - { - "parameter_ref": "override", - "label": { - "default": "", - "resource_key": "FieldStorageEntry.override" - }, - "width": 16, - "edit_style": "inline", - "sortable": true - }, - { - "parameter_ref": "storage", - "label": { - "default": "", - "resource_key": "FieldStorageEntry.storage" - }, - "width": 26, - "edit_style": "inline", - "dm_default": "type" - } - ], - "buttons": [ - { - "id": "icon_button_1", - "carbon_icon": "Edit32", - "label": { - "resource_key": "table.somekey.label" - }, - "description": { - "default": "This renders a button that has a label and Carbon icon to the right of the label. - }, - "enabled": true - } - ] - } - ] -``` -## Action Info -The action_info section defines an action. Actions are used to callback to the application to perform an operation. - -Action info attributes. - -* `id` (*string*) **Required** Id of the action. -* `label` (*object*) **Required** External name of action. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) -* `control` (*string*) **Required** The type of action. Currently `button` and `image` are supported. -* `class_name` (*string*) Optional classname for this action -* `image` (*object*) Properties associate with an `image` action. - * `url` (*string*) Location of the image to display. - * `placement` (*string*) Placement of image relative to a property. Values are `right` or `left`. - * `size` (*object*) Pixel size of the image. - * `height` (*number*) Image height in pixels. - * `width` (*number*) Image width in pixels. - * `tooltip_direction` (*string*) Set tooltip direction for action image. Values are `right`, `left`, `top`, or `bottom`. Default is `bottom`. -* `button` (*object*) Properties associated with action button. - * `kind` (*string*) Button kind. Values are same as carbon button kind values. Default is `tertiary`. - * `size` (*string*) Button size. Values are sm, md, lg, xl. Default is `sm`. -* `data` (*any*) Returned back in action callback. - -```js -{ - "id": "increment", - "label": { - "default": "Increment" - }, - "control": "button", - "data": { - "parameter_ref": "number" - } -} -``` - -## Resource Definition -Used for user facing text. Allows for default values if no translations are provided. - -* `default` (*string*) Default value if `resource_key` not defined. -* `resource_key` (*string*) Used as a key for enum value labels in the resources section of property definition. - -## Dynamic text expressions -Used to dynamically set text based on a parameter value change. If parameter id is used then then current value for that parameter will be passed into the function. - -* `percent(, )` Return the percent of the 1st parameter. The optional 2nd parameter determines the number of decimal places. -* `sum(, , ...)` Returns the sum of all parameters - -```js -{ - "parameter_ref": "numberfield", - "label": { - "default": "Number" - }, - "text_after": { - "default": "Sum: ${sum(numberfield, 2)} with (numberfield, 2, numberfield). Percent: ${percent(numberfield,2)}" - } -} -``` diff --git a/guide/3.3-Common-Properties-Controls.md b/guide/3.3-Common-Properties-Controls.md deleted file mode 100644 index 37123d60f7..0000000000 --- a/guide/3.3-Common-Properties-Controls.md +++ /dev/null @@ -1,111 +0,0 @@ -# Common Properties Element Types -The editor determines the most appropriate control and panel type for each parameter based on the context (parameter type, role, group type, etc.). Although an author can specify a desired control for a given parameter via its `uihints`, this should be used sparingly and carefully - specifying an inappropriate control for a parameter will lead to undefined behavior. - -A visual documentation containing examples of the following group/panels and control types are available at https://wdp-common-canvas-dev.stage1.mybluemix.net/#/properties. - -## Group/Panel Controls -Controls are grouped and arranged on panels and sub-panels within the "group_info" section of operator uihints. Some panels appear as tab controls, others are for managing shared dataset metadata, while still others contain nested sub-panels. - -### Group Types -* `controls` A general panel type containing parameter controls. -* `tabs` A tabbed control, each tab containing sub-panels and controls. -* `subTabs` A horizontal sub-tabbed control, each tab containing sub-panels and controls. If displayed within a Tearsheet container, subtabs will be displayed vertically. -* `panels` A panel type that contains sub-panels. -* `panelSelector` A panel containing sub-panels that are shown or hidden based upon a controlling radio selection. -* `columnSelection` A panel type containing field-selection controls that share a common set of fields. -* `customPanel` A custom panel for displaying user defined control. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-panels) for more details. -* `summaryPanel` A panel used in the flyout editor that will provide a link to open a wide flyout that can contain panels and parameter. -* `actionPanel` A panel used for containing action controls. -* `textPanel` A panel used to display static label and/or description. -* `twistyPanel` A panel used to display a panel title that expands to the panel content when clicked. -* `columnPanel` A panel used to display children side by side. -* `tearsheetPanel` A tearsheet panel. The panel can be opened/closed using the propertyController methods `setActiveTearsheet(groupId)` and `clearActiveTearsheet()` - -## Parameter Controls -The following controls are supported in the Common Properties editor. Control types are intended for use with particular parameter types: - -### Control Types -* `readonly` A read only text field. Used for fields users shouldn't edit. -* `hidden` A control that has no UI to display. -* `textfield` A single line editable text field. -* `passwordfield` A masked single line text field with tooltip. The tooltip text can be customized by setting `[parameter_id].passwordHide.tooltip` and `[parameter_id].passwordShow.tooltip` in resources section. -* `textarea` A multi-line text area. -* `list` A single column table for editing a list of values. -* `expression` An expression editing field that provides language specific syntax highlighting and text auto complete. An expression builder addon is available with the expression control. You must provide the `expressionInfo` field for the `propertiesInfo` config. See [3.0 Common Properties Documentation](/3.0-Common-Properties-documentation) for more details. To maximize in a tearsheet add this attribute and define a `tearsheetPanel` in `group_info`. - ``` - "data": { - "tearsheet_ref": "" - } - ``` -* `code` An code editing field that provides language specific syntax highlighting and text auto complete. To maximize in a tearsheet add this attribute and define a `tearsheetPanel` in `group_info`. - ``` - "data": { - "tearsheet_ref": "" - } - ``` -* `numberfield` A numeric text field. Number fields can also optionally display a random number generator button beside the control. See the uihints schema for details. -* `datefield` A date input control whose date format tokens follow [date-fns](https://date-fns.org/v2.29.3/docs/format). Defaults to `yyyy-mm-dd` -* `timefield` A time input control whose time format tokens follow [date-fns](https://date-fns.org/v2.29.3/docs/format). Defautls to `H:m:s` -* `datepicker` A date input control with calendar picker whose date format tokens follow [Flatpickr](https://flatpickr.js.org/formatting/#date-formatting-tokens). Defaults to `Y-m-d`. Helper text can be included by adding `[parameter_id].helper` in the resources section. -* `datepickerRange` A date input control with calendar picker for a range of dates. This follow the same rules as the `datepicker` control. Start and end labels defaults to `Start` and `End` respectively. Start, end, and helper labels can be customized by adding the following in the resources section: - ``` - "resources": { - [parameter_id].range.start.label: "Custom start label", - [parameter_id].range.start.desc: "Custom start description that will appear as tooltip next to the label", - [parameter_id].range.start.helper: "Custom start helper that will appear as text below the input", - [parameter_id].range.end.label: "Custom end label", - [parameter_id].range.end.desc: "Custom end description that will appear as tooltip next to the label", - [parameter_id].range.end.helper: "Custom end helper that will appear as text below the input"` - } - ``` -* `spinner` A standard spinner control to increment/decrement the number value. -* `checkbox` A standard checkbox control. -* `radioset` A radio set where a parameter value is selected from a small range of options. See the Conditions wiki page for special radio button disabling options. -* `checkboxset` A checkbox set for list type parameters with enumerated options where the count is less than 5. -* `oneofselect` A standard dropdown list control. -* `multiselect` A standard dropdown list control that allows for multiple selection. -* `someofselect` A multi-selection control for enumerated list parameters where the count is greater than 4. -* `selectcolumn` A dropdown list control that selects from available column names. When dropdown list is empty, `selectcolumn` control will display default placeholder text `"..."`. This placeholder text can be customized by setting `[parameter_id].emptyList.placeholder` in resources section. When custom empty list placeholder text is provided, common-properties will disable the empty list control. -* `selectcolumns` A multi-select control for column selections. -* `selectschema` A dropdown control that contains the available schemas in `dataset_metadata`. The `name` of the schema will be displayed if provided. If `name` is not provided, the index (zero-based) of the schema will be used instead. When dropdown list is empty, `selectschema` control will display default placeholder text `"..."`. This placeholder text can be customized by setting `[parameter_id].emptyList.placeholder` in resources section. When custom empty list placeholder text is provided, common-properties will disable the empty list control. -* `toggle` A standard toggle control with default On/Off states. This text can be customized by setting `[parameter_id].toggle.on.label` and `[parameter_id].toggle.off.label` in resources section. -* `toggletext` A two-state control with optional icons that can exist on its own or within table cells. -* `structuretable` Table control for editing lists or maps of complex types that have field names in the first column. -* `structurelisteditor` For lists or maps of complex types that are *not* field-oriented parameters. -* `structureeditor` Allows one to define a structure and use it directly on a panel. Each structure member is surfaced as an individual control. Supports a `layout` setting that allows one to position structureeditor controls in a grid (see below). -* `readonlyTable` A read only table. Used for tables to display fields that users shouldn't edit. -* `custom` A custom control for displaying a user defined control. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-controls) for more details. - - -### A Note on Field Name Storage -When a given node can accept more than a single datarecord-metadata object as input, it becomes necessary to store the schema name (a.k.a. 'link_name') along with each field name that is stored in parameter sets. In those cases, instead of using strings to store field names, they are represented in parameter sets as compound objects containing both 'link_ref' and 'field_name' elements: - - "current_parameters": { - "field": { "link_ref": "Schema-1", "field_name": "Age" }, - ... - -In order to indicate that a given node can potentially accept multiple input data links and would thus require compound field name storage, all parameter definitions within the node that contain `"role": "column"`, whether located at the top level or within complex types, should declare their data types as "object" instead of "string": - - "parameters": [ - { - "id": "fields", - "type": "array[object]", - "role": "column", - "required": true - }, - ... - -### edit_style -When editing complex type values in tables one can either edit cell values inline or in a sub panel: - -* `subpanel` A small sub-dialog is launched to edit cell values. -* `inline` Controls appear inline within table cells for editing values. -* `on_panel` Control appears below the table when the row is selected. - -### Miscellaneous -* `moveable_rows` *boolean* A value that appears in "complex_type_definition" sections. If set to `true` allows rows in the table to be moved up and down for reordering. -* `row_selection` *enum ["single", "multiple"]* Determines how many rows can be selected in a table at one time. Defaults to *multiple*. -* `sortable` *boolean* Both sortable and filterable apply to table columns. When set within the "key_definition" or the "parameters" sections of a structure definition, those columns are sortable and/or can be filtered upon. -* `filterable` *boolean* _(see sortable above)_ -* `language` *enum ["CLEM", "text/x-hive"]* The language for the expression control syntax highlight and text auto complete feature. If not specified, the expression control does not have syntax highlighting or text auto complete. -* `layout` A two-dimensional string array value that appears in "complex_type_definition" sections and allows one to layout structureeditor controls in a two dimensional grid. diff --git a/guide/3.4-Common-Properties-Conditions.md b/guide/3.4-Common-Properties-Conditions.md deleted file mode 100644 index bccd0f01b8..0000000000 --- a/guide/3.4-Common-Properties-Conditions.md +++ /dev/null @@ -1,361 +0,0 @@ -# Conditions -Conditions define a set of specifications for evaluating parameter values. The specifications support complex interdependency checking such as relationships between multiple parameters (i.e. Valid values for parameter one depend upon the value of parameter two). -[conditions schema](https://github.com/elyra-ai/wdp-pipeline-schemas/blob/master/common-pipeline/operators/conditions-v1-schema.json) - -Visual documentation containing examples of the following conditions for the different controls we support are available at https://wdp-common-canvas-dev.stage1.mybluemix.net/#/conditions - - -A conditions file contains an array of conditions. Each condition takes one of the following forms: - -## Validation definition -A single validation. The fail_message is displayed upon validation failure. - -The attributes for the validation definition are: - -* `id` (*string*) A unique identifier for the validation. This is required if multiple validations have the same `focus_parameter_ref` value. -* `fail_message` (*object*) **Required** The message to display if the validation fails. Each fail_message consist of the following attributes - + `message` (*object*) **Required** The message to display. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) - + `focus_parameter_ref` (*string*) **Required** The parameter control to get focus after displaying the error/warning. If the validation refers to a table cell, then control must have the column indicator. For example if the validation is for `MyTable` cell column 2 then `MyTable[2]`. - + `type` (*string*) Type of messages. Valid values are `error, warning, info`. - -* `evaluate` (*object*) Specification for how to evaluate the validity of the parameter. The evaluate attribute can be one of the following structures. - + `condition` (*object*) This is a single condition that evaluates to true or false. - - `op` (*string*) **Required** A single operator for the properties of the condition. Valid values are: -`isEmpty`, -`isNotEmpty`, -`greaterThan`, -`lessThan`, -`equals`, -`notEquals`, -`matches`, -`notMatches`, -`contains`, -`notContains`, -`colNotExists`, -`isDateTime`, -`dmTypeEquals`, -`dmTypeNotEquals`, -`dmMeasurementEquals`, -`dmMeasurementNotEquals`, -`dmRoleEquals`, -`dmRoleNotEquals` -`lengthEquals`, -`lengthGreaterThan`, -`lengthLessThan`. - - `parameter_ref` (*string*) **Required** The primary parameter. - - `parameter_2_ref` (*string*) Second parameter for multi-parameter validation. - - `value` (*string, boolean, number*) Value against which to compare the primary parameter value. - - `values` (*array[string]*) Values against which to compare the primary parameter value is in. Used only in `filter` conditions. - + `or` (*object*) This is a container of 'or' conditions. Evaluates to true if ANY sub-condition evaluates to true. Can nest any number of additional conditional types. - + `and` (*object*) This is a container of 'and' conditions. Evaluates to true if ALL sub-condition evaluates to true. Can nest any number of additional conditional types. - -## Enabled definition -Enablement test. Disables controls if evaluate is false. - -The attributes for the enabled definition are: - -* `parameter_refs` (*array[string]*) Array of parameter names affected by this operation. If evaluate is false, then the controls associated with these parameters are disabled. Note that individual radio buttons can be disabled by using the radio button value name instead of the overall property name in the parameter_refs array. -* `action_refs` (*array[string]*) Array of action names affected by this operation. If evaluate is false, then the action button or image associated with these action names are disabled. -* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. - -## Visible definition -Visibility test. Hides controls if evaluate is false. - -The attributes for the visible definition are: - -* `parameter_refs` (*array[string]*) Array of parameter names affected by this operation. If evaluate is false, then hide the controls associated with these parameters. -* `action_refs` (*array[string]*) Array of action names affected by this operation. If evaluate is false, then the action button or image associated with these action names are disabled. -* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. - -## Filter definition -Filter test. The filter will determine which data record fields to include in a control. - -The attributes for the filter definition are: - -* `parameter_ref` (*string*) Parameter id affected by this operation. This must be a parameter that operates upon datarecord-metadata columns. -* `parameter_refs` (*string*) Exclusive with `parameter_ref` and used with `dmSharedFields`. Parameter ids affected by this operation. They must be parameters that operate upon datarecord-metadata columns. -* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. - -Supported operations (`op`): - -* `dmType` - filters `type` value from schema. -* `dmMeasurement` - filters `measurement` value from schema. -* `dmModelingRole` - filters `modeling_role` value from schema. -* `dmSharedFields` - shares source fields with all field chooser property names found in the `parameter_refs` array. - -**Examples**: -```js -{ - "filter": { - "parameter_ref": "fields_filter_measurement", - "evaluate": { - "condition": { - "op": "dmMeasurement", - "value": "discrete" - } - } - } -} -``` -```js -{ - "filter": { - "parameter_ref": "fields_filter_type", - "evaluate": { - "condition": { - "op": "dmType", - "values": ["integer", "double"] - } - } - } -} -``` -```js -{ - "filter": { - "parameter_refs": [ - "fields_filter_type", - "multi_field_chooser_table", - "field_chooser_in_another_panel" - ], - "evaluate": { - "condition": { - "op": "dmSharedFields" - } - } - } -} -``` - -## Enum Filter definition -Filters the available options for enumeration parameters. Reduces the available enumeration items if evaluate is true. - -The attributes for the enum_filter definition are: - -* `target` (*object*) Contains a target *parameter_ref* reference and a replacement *values* array. -* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. - -**Example**: -```js -{ - "enum_filter": { - "target": { - "parameter_ref": "radioset_filtered", - "values": [ - "red", - "yellow", - "green" - ] - }, - "evaluate": { - "condition": { - "parameter_ref": "filter_radios", - "op": "equals", - "value": true - } - } -} -``` - -## Allow Change definition -Allow change validates that a change is allowed on a property. If it evaluates to true then the value for the property is changed. This is typically used to restrict values that are invalid in one property based on the value in another property. For example, if the property represents a storage type with a value of `string`, then a property that represents a measurement type should not be allowed to be set to `continuous`. - -The attributes for the allow_change definition are: - -* `parameter_refs` (*array[string]*) Array of parameter names affected by this operation. -* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. - -**Example**: -```js -{ - "allow_change": { - "parameter_refs": [ - "ST_mse_table[2]" - ], - "evaluate": { - "or": [ - { - "condition": { - "parameter_ref": "ST_mse_table[2]", - "op": "notEquals", - "value": "Football" - } - }, - { - "condition": { - "parameter_ref": "ST_mse_table[5]", - "op": "notEquals", - "value": "European" - } - } - ] - } - } - } -``` - -## Default value definition -Sets the default value on the `parameter_ref` property if condition evaluates to true. If multiple conditions evaluate to true only the first condition is used. Default value condition is evaluated only once when loading properties. If user updates the value of `parameter_ref`, default value will be overwritten by the new value. - -The attributes for the default_value definition are: - -* `parameter_ref` (*string*) Parameter whose default value is to be set. -* `value` (*string, boolean, number, object, array*) This will be the default value of parameter_ref if condition evaluates to true. -* `evaluate` (*object*) see the `evaluate` attribute in `validation definition`. - -**Example**: -```js -{ - "default_value": { - "parameter_ref": "conditional_default", - "value": "Value defined in default_value condition. You will see this sentence when default value of mode equals Include.", - "evaluate": { - "condition": { - "parameter_ref": "mode", - "op": "equals", - "value": "Include" - } - } - } -}, -{ - "default_value": { - "parameter_ref": "conditional_default", - "value": ["This is a second condition for conditional_default. You should never see this value."], - "evaluate": { - "condition": { - "parameter_ref": "mode", - "op": "equals", - "value": "Include" - } - } - } -} -``` - - -## A note on table cell conditions -Support for table cell conditions is achieved via the use of the array subscript operator, `[]`. When evaluating table cells, one uses the table identifier with an array subscript indicating the zero-based table column being operated upon (which also corresponds to the sub-control index as defined in `complex_types`). - -So for example if one has a StructureTable property named _myTable_, column conditions on that table are referred to using `myTable[1]`, `myTable[3]`, etc. - -## Example - -Example of a condition section. -```js - "conditions": [ - { - "validation": { - "fail_message": { - "type": "error", - "focus_parameter_ref": "inputFieldList", - "message": { - "resource_key": "input_field_list_not_empty" - } - }, - "evaluate": { - "condition": { - "parameter_ref": "inputFieldList", - "op": "isNotEmpty" - } - } - } - }, - { - "visible": { - "parameter_refs": [ - "oneofselectPets" - ], - "evaluate": { - "condition": { - "parameter_ref": "oneofselectAnimals", - "op": "notContains", - "value": "lion" - } - } - } - }, - { - "visible": { - "action_refs": [ - "action_button" - ], - "evaluate": { - "condition": { - "parameter_ref": "button_hide_checkbox", - "op": "equals", - "value": false - } - } - } - }, - { - "enabled": { - "parameter_refs": [ - "radiosetColor" - ], - "evaluate": { - "condition": { - "parameter_ref": "checkboxEnable", - "op": "checked" - } - } - } - }, - { - "validation": { - "fail_message": { - "type": "error", - "focus_parameter_ref": "subsamplingRate", - "message": { - "resource_key": "subsampling_rate_not_valid" - } - }, - "evaluate": { - "and": [ - { - "condition": { - "parameter_ref": "subsamplingRate", - "op": "greaterThan", - "value": 0 - } - }, - { - "or": [ - { - "condition": { - "parameter_ref": "subsamplingRate", - "op": "lessThan", - "value": 1 - } - }, - { - "condition": { - "parameter_ref": "subsamplingRate", - "op": "equals", - "value": 1 - } - } - ] - } - ] - } - } - }, - { - "enabled": { - "parameter_refs": [ - "field_types[2]" - ], - "evaluate": { - "condition": { - "parameter_ref": "field_types[1]", - "op": "checked" - } - } - } - } - } - ] -``` \ No newline at end of file diff --git a/guide/3.5-Common-Properties-Custom-Components.md b/guide/3.5-Common-Properties-Custom-Components.md deleted file mode 100644 index cf2dcd29fc..0000000000 --- a/guide/3.5-Common-Properties-Custom-Components.md +++ /dev/null @@ -1,180 +0,0 @@ -# Custom Components Overview -Custom components allows applications to use custom code to drive different parts of the common-properties user interface. For some panels and controls it might be necessary to listen to different types of redux state changes to cause the panel/control to rerender. -Here is an example of a textfield listening to 3 state changes: -```js -import { connect } from "react-redux"; - -// ... application code - -render() { - const value = this.props.value; // value passed by redux as a property - - // ... rest of component render code - -} - -TextfieldControl.propTypes = { - // ... application props - state: PropTypes.string, // pass in by redux - value: PropTypes.string, // pass in by redux - messageInfo: PropTypes.object // pass in by redux -}; - -const mapStateToProps = (state, ownProps) => ({ - value: ownProps.controller.getPropertyValue(ownProps.propertyId), - state: ownProps.controller.getControlState(ownProps.propertyId), - messageInfo: ownProps.controller.getErrorMessage(ownProps.propertyId) -}); -export default connect(mapStateToProps, null)(TextfieldControl); -``` - - -## Custom Panels -Custom panels allow applications to create their own panels and controls that can live in the same dialogs as common-property panels and controls. - -### Custom panel interface -```js -// Returns the 'id' for the group defined in uihints -static id() - -constructor(parameters, controller, data) - -// Returns the content users want to display -renderPanel() -``` - -- **parameters** - String array of parameters set under the customPanel group in uihints -- **controller** - See [here](/3.6-Common-Properties-Controller) for API information. -- **data** - Optional parameter. Returns values stored in `data` attribute of a group `customPanel`. -- **renderPanel()** - Called on all Redux store changes: - - property value changes ([property APIs](/3.6-Common-Properties-Controller#property-methods)) - - state changes ([state APIs](/3.6-Common-Properties-Controller#state-methods-disableenabled--hiddenvisible)) - - schema changes ([schema APIs](/3.6-Common-Properties-Controller#datasetmetadata-methods)) - - row selection changes ([selection APIs](/3.6-Common-Properties-Controller#row-selection-methods)) - - messages changes ([message APIs](/3.6-Common-Properties-Controller#message-methods)) - -### Custom react components - -Example -```js -renderPanel() { - const controlId = this.parameters[0]; - return ( - - ); -} -``` - -### Examples -https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/src/client/components/custom-panels - - -## Custom Controls -Custom controls allow applications to create their own controls that can live in the same dialogs as common-property panels and controls. - -### Custom control interface -```js -// Returns the 'custom_control_id' for the parameter defined in uihints -static id() - -constructor(propertyId, controller, data, tableInfo) - -// Returns the content users want to display -renderControl() -``` - -- **propertyId** - See [propertyId](/3.6-Common-Properties-Controller#common-properties-controller-api) for definition. -- **controller** - See [here](/3.6-Common-Properties-Controller) for API information. -- **data** - Returns values stored in `data` attribute of a parameter in uihints. -- **tableInfo** - Set when custom control is a cell in a table. - - table (boolean) Set to true when in a table cell - - editStyle (string) Valid values are "summary" and "inline". "summary" is set when the control will display either below the table ("on_panel") or in a "subpanel". This allows the custom control to display a summary value in the cell and something else for the custom control. -- **renderControl()** - Called on all Redux store changes: - - property value changes ([property APIs](/3.6-Common-Properties-Controller#property-methods)) - - state changes ([state APIs](/3.6-Common-Properties-Controller#state-methods-disableenabled--hiddenvisible)) - - schema changes ([schema APIs](/3.6-Common-Properties-Controller#datasetmetadata-methods)) - - row selection changes ([selection APIs](/3.6-Common-Properties-Controller#row-selection-methods)) - - messages changes ([message APIs](/3.6-Common-Properties-Controller#message-methods)) - -### Custom react components - -Example -```js -renderControl() { - return ( - - ); -} -``` - -### Examples -https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/src/client/components/custom-controls - -## Custom Condition Operators -Custom condition operators allow users to create their own operators that can then be used for enablement, visibility, validation, and enum filtering. The condition operators should always return a `boolean` value. - -### Custom operator interface - -```js -/** -* This is the key used to determine if the operator should be ran. Maps to the `op` defined in the -* `condition` in uihints -* @return string -*/ -function op() - -/** -* @param see below -* @return boolean -*/ -function evaluate(paramInfo, param2Info, value, controller) -``` - -- paramInfo (object) - `parameter_ref` set in the `condition` in uihints - - control (object) - contains information about the control. - - value (any) - current property value -- param2Info (object) - `parameter_2_ref` set in the `condition` in uihints. See `paramInfo` for object info -- value - `value` set in the `condition` in uihints. If no value specific this will be `undefined` -- **controller** - See [here](/3.6-Common-Properties-Controller) for API information. - -Example -```js -function op() { - return "customMax"; -} - -function evaluate(paramInfo, param2Info, value, controller) { - const supportedControls = ["numberfield"]; - if (supportedControls.indexOf(paramInfo.control.controlType) >= 0) { - return paramInfo.value < value; - } - return true; -} - -module.exports.op = op; -module.exports.evaluate = evaluate; -``` -```json -{ - "evaluate": { - "condition": { - "parameter_ref": "custom_op_num", - "op": "customMax", - "value": 100 - } - } -} -``` - -### Examples -https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/src/client/custom/condition-ops -https://github.com/elyra-ai/canvas/tree/master/canvas_modules/common-canvas/src/common-properties/ui-conditions/condition-ops - diff --git a/guide/3.6-Common-Properties-Controller.md b/guide/3.6-Common-Properties-Controller.md deleted file mode 100644 index c2ce85b539..0000000000 --- a/guide/3.6-Common-Properties-Controller.md +++ /dev/null @@ -1,351 +0,0 @@ -## Common Properties Controller API - -**propertyId** -```js -const propertyId = { - name: {parameter name defined in operator definition}, - row: {row in table/array}, // optional when col not set - col: {col in table}, // optional - propertyId: {propertyId of the nested structure} // optional -} -``` -### Property methods -```js -/* - * options - optional object of config options where - * setDefaultValues (boolean): when set to true, set default values from parameter definition -*/ -setPropertyValues(values, options) -updatePropertyValue(propertyId, value) -/* - * options - optional object of config options where - * filterHiddenDisabled (boolean): when set to true, filter out data values with a state of disabled or hidden - * filterHiddenControls (boolean): when set to true, filter out data values having control type hidden - * applyProperties (boolean): when set to true, will return data values in the format expected by the `applyPropertyChanges` callback. If unset or false, will return the internal format used by common properties. -*/ -getPropertyValue(propertyId, options) -/* - * options - optional object of config options where - * filterHiddenDisabled (boolean): when set to true, filter out data values with a state of disabled or hidden - * filterHiddenControls (boolean): when set to true, filter out data values having control type hidden - * applyProperties (boolean): when set to true, will return data values in the format expected by the `applyPropertyChanges` callback. If unset or false, will return the internal format used by common properties. -*/ -getPropertyValues(options) -``` -### Message methods -```js -/* - * Returns current list of error messages - * @filteredPipeline (boolean) optional - * @filterHiddenDisable (boolean) optional. If true, will not return error messages from controls that are hidden or disabled - * @filterDisplayError (boolean) optional. If true, will not return error messages that are not displayed in the editor - * when filteredPipeline=true returns enabled/visible control messages and only 1 per control. - */ -getAllErrorMessages() -getErrorMessages(filteredPipeline, filterHiddenDisable, filterSuccess, filterDisplayError = true) -getErrorMessage(propertyId, filterHiddenDisable = false, filterSuccess = false, filterDisplayError = true) -getRequiredErrorMessages() -setErrorMessages(messages) -updateErrorMessage(propertyId, message) - - -``` -### State methods (disable/enabled & hidden/visible) -```js -getControlState(propertyId) -getControlStates() -setControlStates(states) - -/* - * @propertyId - see above - * @state - valid values are "enabled", "disabled", "visible", "hidden" - */ -updateControlState(propertyId, state) -``` -### DatasetMetadata methods -```js -getDatasetMetadata() - -/* - * @datasetMetadata - see [schema](https://github.com/elyra-ai/pipeline-schemas/blob/master/common-pipeline/datarecord-metadata/datarecord-metadata-v1-schema.json) - */ -setDatasetMetadata(datasetMetadata) -``` - -### Row selection methods -```js -/* - * Returns table row selection indices as an array of integers. - * @propertyId - see above - */ -getSelectedRows(propertyId) - -/* - * Updates table row selections for the given table control. - * @propertyId - see above - * @selection - A zero-based array of integer selection indices - */ -updateSelectedRows(propertyId, selection) - -/* - * Clears selected table rows for the given table. - * @propertyId - see above - * If the propertyId is omitted all table row selections are cleared - */ -clearSelectedRows(propertyId) - -/* - * Adds a row selection listener for a table or list. - * @propertyId - see above - * @listener - callback function for when a selection is made in the table or list - */ -addRowSelectionListener(propertyId, listener) - -/* - * Removes the row selection listener from a table or list. - * @propertyId - see above - */ -removeRowSelectionListener(propertyId) -``` - -### Validation methods - -```js -/* - * Runs validation conditions on all controls - */ -validatePropertiesValues() - - - -/* - * Validates a specific propertyId - * @propertyId - see above - */ -validateInput(propertyId) -``` - -### Control methods -```js -/* - * Update the enum values for a given control. Used when enum values aren't static - * @propertyId - see above - * @valuesObj (array) [{ value: , label: "" }] - */ -updateControlEnumValues(propertyId, valuesObj) -``` - -### General methods -```js -/* -* Returns the current size of the RHS flyout. -*/ -getEditorSize() - -/* -* Sets default property values from parameter definition in the propertiesController. -* Note - These values won't be displayed on the UI. Host applications can call getPropertyValues() to retrieve the values. -* @paramDef - Follows the format of https://github.com/elyra-ai/pipeline-schemas/blob/master/common-canvas/parameter-defs/parameter-defs-v3-schema.json -*/ -setParamDef(paramDef) - -/* -* Returns the id of top-level active tab or accordion -*/ -getTopLevelActiveGroupId() - - -/* -* Makes the passed in groupId active. Only works for top-level groups -*/ -setTopLevelActiveGroupId(groupId) -``` - -### Disable move row buttons methods -```js -/** - * Disable table row move buttons for all propertyIds in given array - * @param propertyIds Array of propertyIds - * - */ -setDisableRowMoveButtons(propertyIds) -/** -* Returns array of propertyIds for which row move buttons will be disabled -* @return Array of propertyIds -*/ -getDisableRowMoveButtons() -/** -* Check if row move buttons should be disabled for given propertyId -* @param propertyId The unique property identifier -* @return boolean -*/ -isDisableRowMoveButtons(propertyId) -``` - - -### Custom panel and control methods -```js -/* - * Only used in custom panel to allow for custom property summary values to be displayed - * Displays the value set in propertiesReducer for that parameter - * @propertyId - see above - * @label (string) - * @inSummary (boolean) - */ -setControlInSummary(propertyId, label, inSummary) - -/* - * Sets the content to be displayed in the summaryPanel for a customPanel property. - * The summary panel will directly display the content. - * @propertyId - see above - * @content = { value: , label: "" } - */ -updateCustPropSumPanelValue(propertyId, content) - -/* - * Returns a standard control that can then be used in a customPanel. - * @propertyId - See above - * @paramDef - Follows the format of https://github.com/elyra-ai/pipeline-schemas/blob/master/common-canvas/parameter-defs/parameter-defs-v1-schema.json). titleDefinition, current_parameters, conditions, dataset_metadata are ignored and are optional. - * @parameter - This is the parameter from the paramDef to create the control for. - */ -createControl(propertyId, paramDef, parameter) - -/* - * Returns the translated text for a control given a resource key. - * Users should be able to use the values from resources that has been uploaded as part of paramDef. - * @key - Resource key - * @value - Default value returned when no resource or key has been found. - */ -getResource(key, value) - -``` - -### maxLength for single-line and multi-line control methods -```js -/* - * Returns the maximum characters allowed for multi-line string controls - * Default value is 1024 - */ -getMaxLengthForMultiLineControls() - -/* - * Returns the maximum characters allowed for single-line string controls - * Default value is 128 - */ -getMaxLengthForSingleLineControls() -``` - -### Enabling/disabling addRemoveRows methods -```js -/* - * Set the addRemoveRows attribute to 'enabled' for the given propertyId - * @param propertyId The unique property identifier - * @param enabled boolean value to enable or disable addRemoveRows - */ -setAddRemoveRows(propertyId, enabled) - -/* - * Returns the true if addRemoveRows is enabled for the given propertyID - * @param propertyId The unique property identifier - * @return boolean - */ -getAddRemoveRows(propertyId) -``` - -### Enabling/disabling properties editor "save" button methods -```js -/* - * Set the main "save" button to disabled(true) or enabled(false) - * @param saveDisable (boolean) - */ -setSaveButtonDisable(saveDisable) - -/* - * Returns the true if the main "save" button is disabled, false otherwise - * @return boolean - */ -getSaveButtonDisable() -``` - - -### Add static rows for table controls which will disable the re-ordering of the rows that are set as static for the given propertyId -```js -/* - * Set static rows for the given propertyId - * @param propertyId The unique property identifier - * @param staticRowsArr Array of first n row indexes or last n row indexes - */ -updateStaticRows(propertyId, staticRowsArr) - -/* - * Returns the static rows set for the given propertyId - * @param propertyId The unique property identifier - */ -getStaticRows(propertyId) - -/* - * Removes the static rows set for the given propertyId - * @param propertyId The unique property identifier - */ -clearStaticRows(propertyId) -``` - -### Enabling/disabling custom table buttons -```js -/* - * Set the table button to 'enabled' for the given propertyId - * @param propertyId The unique property identifier - * @param buttonId The unique button identifier - * @param enabled boolean value to enable or disable the button - */ -setTableButtonEnabled(propertyId, buttonId, enabled) - -/* - * Returns the table button states for the given propertyID - * @param propertyId The unique property identifier - * @return object An object of buttonIds mapped to their enabled state - */ -getTableButtons(propertyId) - -/* - * Returns the true if the table button is enabled for the given propertyID and buttonId - * @param propertyId The unique property identifier - * @param buttonId The unique button identifier - * @return boolean - */ -getTableButtonEnabled(propertyId, buttonId) -``` - - -### Column visibility methods -```js -/* - * Check if given column is visible in the table - * @param propertyId The unique property identifier - * @param columnIndex Column index in the table - */ -getColumnVisibility(propertyId, columnIndex) - -/* - * Set column visibility - * @param propertyId The unique property identifier - * @param columnIndex Column index in the table - * @param value Boolean value to set column visible/invisible - */ -toggleColumnVisibility(propertyId, columnIndex, value) -``` - -### Enabling/disabling wide flyout "OK" button methods -```js -/** -* Set the "OK" button in Wide Flyout to disabled(true) or enabled(false) for given summary panel -* @param panelId {name: panel.id} -* @param wideFlyoutPrimaryButtonDisable boolean -*/ -setWideFlyoutPrimaryButtonDisabled(panelId, wideFlyoutPrimaryButtonDisable) - -/** -* @param panelId {name: panel.id} -*/ -getWideFlyoutPrimaryButtonDisabled(panelId) -``` \ No newline at end of file diff --git a/guide/4.0-Styling.md b/guide/4.0-Styling.md deleted file mode 100644 index d106a33aed..0000000000 --- a/guide/4.0-Styling.md +++ /dev/null @@ -1,56 +0,0 @@ -## Overriding Styles and Color Themes - -### CSS styling for quick start - -If you just want to get up and running and don't care about scss then import these regular css files: - - - carbon-components/css/carbon-components.min.css - - @elyra/canvas/dist/styles/common-canvas.min.css - - version 8.x and older @elyra/canvas/dist/common-canvas.min.css - -More information about carbon components can be found here http://www.carbondesignsystem.com/getting-started/developers - - -### SCSS styling (recommended) - -If you want to use the full power of scss styling with variable overrides etc then include these imports in your main scss file: -```sass -@import "carbon-components/scss/globals/scss/styles"; -@import "@elyra/canvas/src/index.scss"; -``` - - - use `autoprefixer` when building - - if using webpack under the `sass-loader` and make sure to include - -```js -options: { includePaths: ["node_modules"] } -``` - -Again, you can refer to the test harness [index.scss file](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/styles/index.scss) for sample code. - - -### Loading Fonts -You may find that there is a pause in common canvas behavior, such as when the context menu is first displayed, which is caused by fonts being loaded. This can be fixed by adding the following to the `.scss` file for your application: -``` -$font-path: "/fonts"; -@import "carbon-components/scss/globals/scss/styles"; -``` -The fonts will need to be imported from carbon before carbon styles and placed in a public `/fonts` directory. -You can see an example of this in the common-canvas test harness (which is the equivalent of a host application) in this repo. That is, the [index.scss file](https://github.com/elyra-ai/canvas/blob/master/canvas_modules/harness/src/styles/index.scss) contains the lines above and the grunt build files ensures the fonts are copied from`node_modules/carbon-components/src/globals/` to the `` directory. - - -### 3rd party styling - - -If you are using common-properties then also include the react-virtualized styles: - - - react-virtualized/styles.css - -## Elyra Canvas styling guidelines -- Used the `data-id` attribute on inputs to be used for automated tests. Format for common properties should be `properties-` -- **className** format format for common-properties should be `properties-` -- Limit the use of html(DOM) ids -- Minimum inline styling. This allows for consumers to easily override styling. -- scss/sass styling should be added to the component's folder -- No `important!` in styling -- Use variables for all colors(preferably from carbon) diff --git a/guide/5.0-Testing-Guidelines-for-Development.md b/guide/5.0-Testing-Guidelines-for-Development.md deleted file mode 100644 index 9f0866c268..0000000000 --- a/guide/5.0-Testing-Guidelines-for-Development.md +++ /dev/null @@ -1,53 +0,0 @@ -# Testing Guidelines for Development -## Unit Testing -The Canvas unit tests are automated with the primary purpose of providing rapid feedback to the developers. The test cases are run during every development build. Unit test cases are written using Jest [Jest Tutorial](https://facebook.github.io/jest/docs/en/tutorial-react.html). The test cases should be written and delivered at the time that a feature or enhancement is delivered. - -Unit test cases should focus on good coverage of a function/service. We are current investigating code coverage analysis tools and will update this doc when it is implemented. - -Unit test case coverage should focus on these areas: - - * All APIs and all UI elements. - * All component properties. - * A variety of input data. - -Here is a good blog on [JavaScript Unit Testing](https://medium.com/javascript-scene/what-every-unit-test-needs-f6cd34d9836d) - - -## Functional Testing -The Canvas Functional Test cases will be automated and run during code delivery. The function test case will be automated and written using [Cypress](https://docs.cypress.io). - -Functional Testing coverage includes the following types of tests. - -* Core functionality -* Inter-operate with other Canvas elements. -* Need to test both forward and backwards compatibility -* Negative / bounds -* Globalization / Localization - * Handling of all strings using UTF-8 - * Verifying non-English unicode data is handled appropriately - * Externalizing all strings that may be presented for the user (e.g., error messages, UI labels, etc.) -* Access control security (roles / permissions / tenant management) -* Malicious and security (code scans such as AppScan, ethical hacking) -* Accessibility for UI - -## Debugging Tests - -### Jest tests (unit) -https://facebook.github.io/jest/docs/troubleshooting.html - -**With node 8 or newer** - -- Add `debugger;` statement to your Jest test suite program where you want to stop and begin debugging. -- If you want to run just a single test within your test program (rather than all of them) temporarily change the it() method for the test to be it.only(). For example, change: - - `it("should add a node", () => { ... })` - - to be: - - `it.only("should add a node", () => { ... })` - -- In the console enter: `npm run debug` or `npm run debug ` -- Open Chrome debugging tools by pasting this into the Chrome address field: [chrome://inspect/](chrome://inspect/#devices) -- You should see a 'remote' target for `node_modules/.bin/jest`. Click on the `inspect` link below it. -- Click on sources and then click the play button (right pointing blue triangle icon). -- The code should run to the point where your debugger statement was added. diff --git a/guide/css/styles.css b/guide/css/styles.css deleted file mode 100644 index 675155171d..0000000000 --- a/guide/css/styles.css +++ /dev/null @@ -1,7 +0,0 @@ -th { - font-weight: bold; -} - -.md-grid { - max-width: initial; -} \ No newline at end of file diff --git a/guide/images/DELETEME b/guide/images/DELETEME deleted file mode 100644 index 0fa15e4e80..0000000000 --- a/guide/images/DELETEME +++ /dev/null @@ -1 +0,0 @@ -Images for the guide go here. \ No newline at end of file diff --git a/guide/index.md b/guide/index.md deleted file mode 100644 index 8d5dea28c3..0000000000 --- a/guide/index.md +++ /dev/null @@ -1,90 +0,0 @@ -# Welcome to the Elyra Canvas Documentation - -The elyra-ai/canvas repo contains three main components: - -* [Common Canvas](/2.0-Common-Canvas-Documentation/) - This contains canvas functionality which is packaged into the [elyra/canvas NPM module](https://www.npmjs.com/package/@elyra/canvas) and deployed on the NPM registry. It provides a way for an application to display a flow of data operations (shown as a set of nodes connected with links) defined in a pipeline flow JSON document, to the user and to allows the user to interact with the display to modify the flow. Common canvas is a react component which can be imported, and is assisted by a regular JavaScript class called `CanvasController` which provides an API and handles the internal data model of the flow. Common canvas is highly customizable where node shape and appearance, colors, styles layout etc can all be customized by your application code. - -* [Common Properties](/3.0-Common-Properties-documentation/) - This contains properties functionality which is packaged into the [elyra/canvas NPM module](https://www.npmjs.com/package/@elyra/canvas) and deployed on the NPM registry. It provides a way to translate a JSON document, which describes a set of properties with UI hints, into working properties dialog panel. Common properties is a react component and has an associated properties controller object. - -* [Test Harness](https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness#test-harness) - This provides a node.js app which displays a UI which allows you to try out various features of the common canvas and common properties components. Bear in mind this is not supposed to be a fully functional app but is, as the name suggests, a framework for testing. To get select one of the sample applications or select `None` as the sample app and then select a test canvas file from the `Canvas Diagram` drop down list and a test palette from the `Canvas palette` drop down list. - -## Installation - -You'll need to build your application with Elyra Canvas. - -* Elyra Canvas requires react, react-dom, react-intl, and react-redux libraries to be installed. See peerDependencies in package.json for versions requirements. - -Use the command: -```sh -npm install @elyra/canvas --save-dev -``` -or add this to your package.json file: - -``` - "@elyra/canvas": "x.x.x" -``` -where x.x.x is the latest build and then run: -```sh -npm install -``` - -## Localization -You must wrapper `` and `` in an `` object. - -If you want to display translated text, the sample code below shows how `` should be initialized. Your code can set `this.locale` to indicate which language should override the default which, in this sample code, is set to English `en`. The default locale will be used if `this.locale` is set to a language which is not currently supported. - -If you want to provide translations for your own application's text you can import your own bundles and load them into the `this.messages` object along with the common canvas and common properties text. If you do this you will have to move `` so that it wrappers your React objects as well as `` and/or ``. - -```js -import { IntlProvider } from "react-intl"; -import CommandActionsBundles from "@elyra/canvas/locales/command-actions/locales"; -import CommonCanvasBundles from "@elyra/canvas/locales/common-canvas/locales"; -import CommonPropsBundles from "@elyra/canvas/locales/common-properties/locales"; -import PaletteBundles from "@elyra/canvas/locales/palette/locales"; -import ToolbarBundles from "@elyra/canvas/locales/toolbar/locales"; - -class App extends React.Component { - -constructor() { - this.locale = "en"; - // Create messages object once (here in constructor) - do not create messages - // in the render method, otherwise unnecessary renders inside - // common-canvas/common-properties will be performed. - this.messages = this._getMessages( - this.locale, - [CommandActionsBundles, CommonCanvasBundles, CommonPropsBundles, - PaletteBundles, ToolbarBundles] - ); -} - -_getMessages(locale, bundles) { - const messages = {}; - for (const bundle of bundles) { - Object.assign(messages, bundle[locale]); - } - return messages; -} - -render() { - - {Add your or element here.} - -} -``` - -## Notes -When building your application you will need to load fonts and override styles can be found here: -[Styling](./4.0-Styling) - -## Testing -When testing your application with Jest, this error might show up: `crypto.getRandomValues() not supported`. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported for details. - -To fix, added this to your jest setup file: -```js -const cryptoJest = require("crypto"); -Object.defineProperty(global.self, "crypto", { - value: { - getRandomValues: (arr) => cryptoJest.randomBytes(arr.length) - } -}); -``` diff --git a/guide/js/links-in-new-tabs.js b/guide/js/links-in-new-tabs.js deleted file mode 100644 index f269f65134..0000000000 --- a/guide/js/links-in-new-tabs.js +++ /dev/null @@ -1,10 +0,0 @@ -// This takes any external links and adds _blank to make sure they open in a new tab. Links to other -// pages within the documentation will remain in the same tab -// Source: https://stackoverflow.com/questions/4425198/can-i-create-links-with-target-blank-in-markdown#answer-4425214 - -var links = document.links; -for (var i = 0, linksLength = links.length; i < linksLength; i++) { - if (links[i].hostname != window.location.hostname) { - links[i].target = '_blank'; - } -} diff --git a/mkdocs.yml b/mkdocs.yml index 8128fccdf8..de8b1fa8d0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -2,8 +2,14 @@ site_name: Elyra Canvas Documentation repo_url: https://github.com/elyra-ai/canvas docs_dir: docs -theme: readthedocs - +theme: + name: material + highlightjs: true + palette: + scheme: default + features: + - content.code.copy + - content.action.edit plugins: - search From 5c85847d027549679868b82cf1ae2b38ee73827f Mon Sep 17 00:00:00 2001 From: srikant Date: Fri, 23 Feb 2024 15:20:29 +0530 Subject: [PATCH 11/20] Include links js file Signed-off-by: srikant --- docs/images/DELETEME | 1 + docs/js/links-in-new-tabs.js | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 docs/images/DELETEME create mode 100644 docs/js/links-in-new-tabs.js diff --git a/docs/images/DELETEME b/docs/images/DELETEME new file mode 100644 index 0000000000..0fa15e4e80 --- /dev/null +++ b/docs/images/DELETEME @@ -0,0 +1 @@ +Images for the guide go here. \ No newline at end of file diff --git a/docs/js/links-in-new-tabs.js b/docs/js/links-in-new-tabs.js new file mode 100644 index 0000000000..f269f65134 --- /dev/null +++ b/docs/js/links-in-new-tabs.js @@ -0,0 +1,10 @@ +// This takes any external links and adds _blank to make sure they open in a new tab. Links to other +// pages within the documentation will remain in the same tab +// Source: https://stackoverflow.com/questions/4425198/can-i-create-links-with-target-blank-in-markdown#answer-4425214 + +var links = document.links; +for (var i = 0, linksLength = links.length; i < linksLength; i++) { + if (links[i].hostname != window.location.hostname) { + links[i].target = '_blank'; + } +} From e9755ffd0775538539fb73164793eb18ba56dafe Mon Sep 17 00:00:00 2001 From: srikant Date: Mon, 26 Feb 2024 15:16:20 +0530 Subject: [PATCH 12/20] Remove awesome-pages to test deployment Signed-off-by: srikant --- mkdocs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index de8b1fa8d0..9111406427 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -13,7 +13,6 @@ theme: plugins: - search - - awesome-pages extra_css: - css/styles.css From 8e18c5cd71d75d564d6e4066958c36a652a5afde Mon Sep 17 00:00:00 2001 From: srikant Date: Mon, 26 Feb 2024 21:42:57 +0530 Subject: [PATCH 13/20] Deploy docs to gh-pages and fix link navigation in docs Signed-off-by: srikant --- .gitignore | 3 ++ docs/2.0-Common-Canvas-Documentation.md | 26 ++++++------ docs/2.0.2-Palette.md | 14 +++---- docs/2.0.3-Context-Menu.md | 2 +- docs/2.0.4-Context-Toolbar.md | 2 +- docs/2.1-Config-Objects.md | 38 ++++++++--------- docs/2.2-Common-Canvas-callbacks.md | 8 ++-- ...ling-node-creation-from-external-object.md | 2 +- docs/2.4-Canvas-Controller-API.md | 12 +++--- docs/2.4.1-Style-Specification.md | 2 +- docs/2.4.2-Decoration-Specification.md | 16 +++---- ...nstructing-a-read-only-or-locked-canvas.md | 18 ++++---- .../2.7-Customizing-Node-Layout-Properties.md | 8 ++-- docs/2.9-External-Subflows-support.md | 16 +++---- docs/3.0-Common-Properties-documentation.md | 12 +++--- ...-Common-Properties-Parameter-Definition.md | 8 ++-- docs/3.2-Common-Properties-UI-Hints.md | 42 +++++++++---------- docs/3.3-Common-Properties-Controls.md | 6 +-- docs/3.4-Common-Properties-Conditions.md | 2 +- ...3.5-Common-Properties-Custom-Components.md | 28 ++++++------- docs/index.md | 6 +-- mkdocs.yml | 2 +- 22 files changed, 138 insertions(+), 135 deletions(-) diff --git a/.gitignore b/.gitignore index 2300d285ab..3754e37487 100644 --- a/.gitignore +++ b/.gitignore @@ -47,6 +47,9 @@ build/Release # Dependency directory node_modules +# Site folder generated by mkdocs-deploy +site + config/app-local.json /public/build/* diff --git a/docs/2.0-Common-Canvas-Documentation.md b/docs/2.0-Common-Canvas-Documentation.md index 04d984121b..119573587b 100644 --- a/docs/2.0-Common-Canvas-Documentation.md +++ b/docs/2.0-Common-Canvas-Documentation.md @@ -19,10 +19,10 @@ Within common canvas the user can perform operations such as: Common-canvas has these constituent parts that are visible to the user: -* [Canvas editor](/2.0.1-Canvas-Editor/) - the main area of the UI where the flow is displayed and edited -* [Palette](/2.0.2-Palette/) - a set of node templates that can be dragged to the canvas to create new nodes -* [Context menu](/2.0.3-Context-Menu/) - a menu of options for nodes, comments, etc -* [Context toolbar](/2.0.4-Context-Toolbar/) - a menu of options for nodes, comments, etc presented as a small toolbar +* [Canvas editor](2.0.1-Canvas-Editor.md) - the main area of the UI where the flow is displayed and edited +* [Palette](2.0.2-Palette.md) - a set of node templates that can be dragged to the canvas to create new nodes +* [Context menu](2.0.3-Context-Menu.md) - a menu of options for nodes, comments, etc +* [Context toolbar](2.0.4-Context-Toolbar.md) - a menu of options for nodes, comments, etc presented as a small toolbar * Toolbar - a set of tools across the top of the UI * Notification panel - a panel for displaying runtime and other messages to your user * Right side flyout - a panel, often used to display node properties @@ -40,7 +40,7 @@ and it handles: ## Canvas Controller -The only mandatory parameter for the `` component is a regular JavaScript object called the [CanvasController](/2.4-Canvas-Controller-API/). +The only mandatory parameter for the `` component is a regular JavaScript object called the [CanvasController](2.4-Canvas-Controller-API.md). The CanvasController routes handles calls from the host application and actions performed by the user. It then updates the internal object model which stores: @@ -51,7 +51,7 @@ The only mandatory parameter for the `` component is a regular Jav 5. breadcrumbs that indicate which sub-flow is being viewed 6. layout information - The [CanvasController](/2.4-Canvas-Controller-API/) provides an API which allows your code to: + The [CanvasController](2.4-Canvas-Controller-API.md) provides an API which allows your code to: 1. set a new pipelineFlow; 2. get the current pipelineFlow (after the user has edited it); @@ -128,7 +128,7 @@ Some examples of pipeline flow JSON files can be found here: https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/test_resources/diagrams ## Step 6 : Pull in the CSS -Check this section to find info on what CSS to include in your application's CSS. [Styling](./4.0-Styling.md). +Check this section to find info on what CSS to include in your application's CSS. [Styling](4.0-Styling.md). ## Step 7 : Display the canvas @@ -182,11 +182,11 @@ If you want to customize the behavior of common canvas you can specify any combi ### Config objects Common canvas has five **optional** configuration objects: config, toolbarConfig, notificationConfig, contextMenuConfig and keyboardConfig. They are documented here: -[Config Objects](/2.1-Config-Objects) +[Config Objects](2.1-Config-Objects.md) ### Handlers There are several **optional** handlers implemented as callback functions. They are contextMenuHandler, editActionHandler, beforeEditActionHandler, clickActionHandler, decorationActionHandler, layoutHandler, tipHandler, idGeneratorHandler, selectionChangeHandler and actionLabelHandler. They are documented here: -[Common Canvas Callback](/2.2-Common-Canvas-callbacks) +[Common Canvas Callback](2.2-Common-Canvas-callbacks.md) ### Right-flyout panel parameters The right flyout panel appears on the right of the canvas area. You can add whatever content you like to this panel. Typically, it is used to display properties of nodes on the canvas. There are two **optional** parameters to let you manage the right flyout panel These are: @@ -207,7 +207,7 @@ The top panel appears below the toolbar and between the palette and the right fl - topPanelContent: content to display in the top panel which is a JSX object. Nothing is displayed by default. ### Localization -You can customize `` using the `` object to [display translated test](/#localization) +You can customize `` using the `` object to [display translated test](#localization) ## Creating nodes on the canvas @@ -217,7 +217,7 @@ Nodes can be created on the canvas by the user in two ways: * By dragging a node from outside the canvas The first technique is provided by Common canvas. The second requires some development work which is documented here: -[Enabling node creation from external object](/2.3-Enabling-node-creation-from-external-object) +[Enabling node creation from external object](2.3-Enabling-node-creation-from-external-object.md) ## Keyboard support @@ -236,6 +236,6 @@ Common canvas supports a number of keyboard interactions as follows: |Ctrl/Cmnd + y|redo|Redo last undone command| -Your application can disable any or all of these actions by providing the [keyboard config object](/2.1-Config-Objects#keyboard-config-object) to the CommonCanvas react component. +Your application can disable any or all of these actions by providing the [keyboard config object](2.1-Config-Objects.md#keyboard-config-object) to the CommonCanvas react component. -When any of the shortcut keys are pressed the common-canvas object model will be updated and then the [editActionHandler](/2.2-Common-Canvas-callbacks#editactionhandler) callback will be called with the `data.editType` parameter set to the action above and the `data.editSource` parameter set to "keyboard". +When any of the shortcut keys are pressed the common-canvas object model will be updated and then the [editActionHandler](2.2-Common-Canvas-callbacks.md#editactionhandler) callback will be called with the `data.editType` parameter set to the action above and the `data.editSource` parameter set to "keyboard". diff --git a/docs/2.0.2-Palette.md b/docs/2.0.2-Palette.md index 6369b28b60..ff974ad0a1 100644 --- a/docs/2.0.2-Palette.md +++ b/docs/2.0.2-Palette.md @@ -4,7 +4,7 @@ By default, common-canvas includes a palette which appears in the left flyout pa ## Populating the palette The host application must tell common-canvas what node templates and categories it wants the user to see in the palette. This is done by providing common-canvas with a palette (JavaScript) object by calling the canvas-controller `setPipelineFlowPalette(palette)` method. The palette object is often read from a JSON document stored in the host application's repository or it can be automatically generated. -The palette object should conform to the [palette schema](https://github.com/elyra-ai/pipeline-schemas/blob/412d70176953ed9ac2e6a03f7135b09b7565fc5d/common-canvas/palette/palette-v3-schema.json). The host application can ensure that palette conforms to the schema by switching on [schema validation](/2.1-Config-Objects#schemavalidation) in the canvas configuration. +The palette object should conform to the [palette schema](https://github.com/elyra-ai/pipeline-schemas/blob/412d70176953ed9ac2e6a03f7135b09b7565fc5d/common-canvas/palette/palette-v3-schema.json). The host application can ensure that palette conforms to the schema by switching on [schema validation](2.1-Config-Objects.md#schemavalidation) in the canvas configuration. ## Auto-join Instead of dragging node templates from the palette, the user can double click node templates to add, and automatically join, them to the current flow. When a node template is double clicked, common-canvas will look for the node at the end of the current flow of nodes and will add the node to the canvas to the right of the end node in the flow. Common-canvas will also automatically join the nodes together by creating a new link line. @@ -12,15 +12,15 @@ Instead of dragging node templates from the palette, the user can double click n ## Palette configuration There are a number of configuration options that control the palette that are specified in the canvas config object: -* [enablePaletteLayout](/2.1-Config-Objects#enablepalettelayout) -* [enableNarrowPalette](/2.1-Config-Objects#enablenarrowpalette) -* [enableAutoLinkOnlyFromSelNodes](/2.1-Config-Objects#enableautolinkonlyfromselnodes) -* Deprecated - [paletteInitialState](/2.1-Config-Objects#paletteinitialstate) +* [enablePaletteLayout](2.1-Config-Objects.md#enablepalettelayout) +* [enableNarrowPalette](2.1-Config-Objects.md#enablenarrowpalette) +* [enableAutoLinkOnlyFromSelNodes](2.1-Config-Objects.md#enableautolinkonlyfromselnodes) +* Deprecated - [paletteInitialState](2.1-Config-Objects.md#paletteinitialstate) ## Palette operation -The palette contents can be manipulated calling these canvas-controller [palette methods](/2.4-Canvas-Controller-API#palette-methods) +The palette contents can be manipulated calling these canvas-controller [palette methods](2.4-Canvas-Controller-API.md#palette-methods) -The palette can be opened and closed using these canvas-controller [operational methods](/2.4-Canvas-Controller-API#palette-methods-1) +The palette can be opened and closed using these canvas-controller [operational methods](2.4-Canvas-Controller-API.md#palette-methods-1) ## Search The user can enter a search string into the Search field at the top of the palette. The behavior is as follows: diff --git a/docs/2.0.3-Context-Menu.md b/docs/2.0.3-Context-Menu.md index 993829a9a4..49eeea0b5a 100644 --- a/docs/2.0.3-Context-Menu.md +++ b/docs/2.0.3-Context-Menu.md @@ -1,5 +1,5 @@ A context menu is a small window containing a list of options applicable to an object or set of selected objects. -When [`enableContextToolbar`](/2.1-Config-Objects#enablecontexttoolbar) is set to `false` (or omitted) from the canvas config, and a right-click is performed on a node, link, comment or the canvas background, a traditional context menu is displayed like this: +When [`enableContextToolbar`](2.1-Config-Objects.md#enablecontexttoolbar) is set to `false` (or omitted) from the canvas config, and a right-click is performed on a node, link, comment or the canvas background, a traditional context menu is displayed like this: image \ No newline at end of file diff --git a/docs/2.0.4-Context-Toolbar.md b/docs/2.0.4-Context-Toolbar.md index 89279bf163..dc16c3237f 100644 --- a/docs/2.0.4-Context-Toolbar.md +++ b/docs/2.0.4-Context-Toolbar.md @@ -22,7 +22,7 @@ Note: Since the mouse cursor can be hovered over a node, comment or link that is If the mouse cursor is hovered over a selected object when there are other selected objects, the actions in the context toolbar will be applicable to all the selected objects. This is the same as how a traditional content menu shows actions that are applicable to the set of selected objects. -The context toolbar behavior can be switched on by setting the [`enableContextToolbar`](/2.1-Config-Objects#enablecontexttoolbar) canvas configuration field to true. +The context toolbar behavior can be switched on by setting the [`enableContextToolbar`](2.1-Config-Objects.md#enablecontexttoolbar) canvas configuration field to true. ``` const config = { diff --git a/docs/2.1-Config-Objects.md b/docs/2.1-Config-Objects.md index 5c3fffbe99..0246bddc8e 100644 --- a/docs/2.1-Config-Objects.md +++ b/docs/2.1-Config-Objects.md @@ -52,7 +52,7 @@ This can be "Mouse", "Carbon" or "Trackpad". The default is "Mouse". (Can be simulated with a mouse as follows: Left button down + drag on canvas background) #### **enableNodeFormatType** -This can be "Horizontal" or "Vertical". "Horizontal" is the default. "Horizontal" will display a node with an image and the label to the right of the image. "Vertical" will display the node with the label underneath the image.See the section called [Customizing Node Layout Properties](/2.7-Customizing-Node-Layout-Properties) for details on what this will do. +This can be "Horizontal" or "Vertical". "Horizontal" is the default. "Horizontal" will display a node with an image and the label to the right of the image. "Vertical" will display the node with the label underneath the image.See the section called [Customizing Node Layout Properties](2.7-Customizing-Node-Layout-Properties.md) for details on what this will do. #### **enableLinkType** This can be "Curve", "Elbow", or "Straight". "Curve" is the default. This will set the link style used to connect nodes. @@ -116,7 +116,7 @@ This is a boolean. The default is `true`. You should use `true` for this all the This can be: "Modal" or "Flyout" or "None". The default is "Flyout". "Flyout" displays a panel on the left side of the canvas containing the palette icons and "Modal" shows the palette icons in a dialog window. "None" stops the palette from appearing. #### **enableToolbarLayout** -This can be: "Top" or "None". The default is "Top". "Top" displays a toolbar at the top of the canvas area. See the [toolbar configuration object docs](/2.1-Config-Objects#toolbar-config-object) for details on how to customize the toolbar. "None" stops the toolbar from appearing. +This can be: "Top" or "None". The default is "Top". "Top" displays a toolbar at the top of the canvas area. See the [toolbar configuration object docs](2.1-Config-Objects.md#toolbar-config-object) for details on how to customize the toolbar. "None" stops the toolbar from appearing. #### **enableResizableNodes** This can be true or false. The default is false. If set to true, the user can resize nodes by dragging the edges of the node to increase or decrease the width and/or height of the node. When hovering the mouse cursor over the edge of the node the user will see a sizing cursor to indicate the resize function is available. This option works best when the node has a background rectangle that shows the extent of the sizing area. @@ -152,7 +152,7 @@ This can be true or false. The default is true. If true, nodes surrounding a sup #### **enableExternalPipelineFlows** This can be true or false. The default is false. If true, the context menu will include a `Create External Supernode` option when a set of objects are selected from which a supernode can be created. -Waring: The host application must implement some of the common-canvas callbacks for external pipeline flow support to work correctly. See the Wiki section on [external pipeline flow support](/2.9-External-Subflows-support) for more details. +Waring: The host application must implement some of the common-canvas callbacks for external pipeline flow support to work correctly. See the Wiki section on [external pipeline flow support](2.9-External-Subflows-support.md) for more details. #### **enableDisplayFullLabelOnHover** This can be true or false. The default is false. If set to true, any abbreviated node label will be displayed in full when the pointer hovers over the label. If set to false, abbreviated node labels will remain the same when the pointer hovers over them. @@ -174,7 +174,7 @@ This can be either true or false. The default is false. If set to true, the user This can be true or false. The default is false. When set to true the user may enter markdown syntax into comments on the canvas when in edit mode for the comment. When the editing ends, the comment is shown in presentation mode and the markdown syntax is converted to HTML which is displayed in the comment and is styled by CSS. #### **enableStateTag** -This can be either "None", "Locked" or "ReadOnly". The default is "None". When set to either "Locked" or "ReadOnly", a 'state tag' object will be shown permanently over the top of the canvas. The state tag will be positioned in the center and towards the top of the canvas. The state tag consists of a black background rectangle with rounded corners overlaid with an icon and a text label. A tooltip is displayed when the mouse pointer is hovered over the state tag. The icon, label and default tooltip will be set appropriately based on the value ("Locked" or "ReadOnly") for this setting. The host application can override the tooltip by implementing the [tipHandler callback](/2.2-Common-Canvas-callbacks#tiphandler). +This can be either "None", "Locked" or "ReadOnly". The default is "None". When set to either "Locked" or "ReadOnly", a 'state tag' object will be shown permanently over the top of the canvas. The state tag will be positioned in the center and towards the top of the canvas. The state tag consists of a black background rectangle with rounded corners overlaid with an icon and a text label. A tooltip is displayed when the mouse pointer is hovered over the state tag. The icon, label and default tooltip will be set appropriately based on the value ("Locked" or "ReadOnly") for this setting. The host application can override the tooltip by implementing the [tipHandler callback](2.2-Common-Canvas-callbacks.md#tiphandler). #### **enableEditingActions** This can be true or false. The default is true. If set to false, various editing actions on the canvas will be prevented, as follows: @@ -187,10 +187,10 @@ This can be true or false. The default is true. If set to false, various editing (c) double clicking a node in the palette to create a node - Note: It is not possible for common-canvas to prevent an object being dragged from the computer desktop to the canvas so it is recommended the drop zone (which provides visual feedback about the drop) should be switched off by setting the [enableDropZoneOnExternalDrag](/2.1-Config-Objects#enabledropzoneonexternaldrag) config field to `false`. + Note: It is not possible for common-canvas to prevent an object being dragged from the computer desktop to the canvas so it is recommended the drop zone (which provides visual feedback about the drop) should be switched off by setting the [enableDropZoneOnExternalDrag](2.1-Config-Objects.md#enabledropzoneonexternaldrag) config field to `false`. 2. Nodes and comments cannot be dragged and moved. -3. The end points of Links, when [enableLinkSelection](/2.1-Config-Objects#enablelinkselection) is set to `"Detachable"` or `"Handles"`, cannot be dragged and moved. +3. The end points of Links, when [enableLinkSelection](2.1-Config-Objects.md#enablelinkselection) is set to `"Detachable"` or `"Handles"`, cannot be dragged and moved. 4. Links from nodes and comments cannot be created by dragging from the port object on the source node or comment to the target node. 5. Comments, node labels and text decorations cannot be edited, neither by clicking the edit icon (which does not appear) nor by double clicking the text. 6. Context menu options that alter the canvas objects will be removed from the context menu before it is displayed by common-canvas. The options that will be removed are: @@ -243,15 +243,15 @@ This can be true or false. The default is true. If set to false, various editing |Ctrl/Cmd + Shift + z|redo| |Ctrl/Cmd + y|redo| -9. The browser's Edit menu options (cut, copy, paste) will not work with the canvas objects regardless of the setting for [enableBrowserEditMenu](/2.1-Config-Objects#enablebrowsereditmenu). +9. The browser's Edit menu options (cut, copy, paste) will not work with the canvas objects regardless of the setting for [enableBrowserEditMenu](2.1-Config-Objects.md#enablebrowsereditmenu). #### **enableDropZoneOnExternalDrag** This can be true or false. The default is false. If set to true a graphic overlay will be displayed over the canvas when a data object icon is dragged from the desktop over the canvas. The default graphic overlay will be an image and a message saying: "Drop to add to canvas and project" unless the `dropZoneCanvasContent` configuration parameter is provided. -See the [Dragging an object from the desktop](/2.3-Enabling-node-creation-from-external-object#dragging-object-from-the-desktop-or-another-application) section of the Wiki for details on how to handle the drop of an external object onto the canvas. +See the [Dragging an object from the desktop](2.3-Enabling-node-creation-from-external-object.md#dragging-object-from-the-desktop-or-another-application) section of the Wiki for details on how to handle the drop of an external object onto the canvas. #### **enableNodeLayout** -This is a simple Javascript object, the properties of which override the default node layout properties. For more details see: [Customizing Node Layout Properties](/2.7-Customizing-Node-Layout-Properties) +This is a simple Javascript object, the properties of which override the default node layout properties. For more details see: [Customizing Node Layout Properties](2.7-Customizing-Node-Layout-Properties.md) #### **enableSaveZoom** This can be: "None", "LocalStorage" or "Pipelineflow". The default is "None". @@ -267,7 +267,7 @@ This can be either true or false. The default is false. If set to true, the canv This is a boolean. The default is false. When set to true, common-canvas will override the maximum zoom extent value which, by default is used for the entire canvas, to allow the user to zoom in on in-place sub-flows further than they can do on containing flows. This means the user can zoom in on multi-nested sub-flows so they are easier to view. To see this effect, the user must position the mouse pointer over the sub-flow before performing the zoom gesture. #### **enableContextToolbar** -This is a boolean. The default is false. When set to true, common-canvas will display a context toolbar instead of a context menu for performing actions on canvas objects. A context toolbar is a small toolbar that appears above nodes, links and comments as the mouse cursor is hovered over them. The toolbar shows icons for actions the user is most likely to want to perform on the object. An overflow icon is displayed which, when clicked, shows a menu of additional actions. A context toolbar for the canvas background can also be displayed by right-clicking on the background. Common-canvas will display default context toolbars for nodes, links comments and the canvas background however the default actions can be customized by implementing the [`contextMenuHanlder`](/2.2-Common-Canvas-callbacks#contextmenuhandler) callback. +This is a boolean. The default is false. When set to true, common-canvas will display a context toolbar instead of a context menu for performing actions on canvas objects. A context toolbar is a small toolbar that appears above nodes, links and comments as the mouse cursor is hovered over them. The toolbar shows icons for actions the user is most likely to want to perform on the object. An overflow icon is displayed which, when clicked, shows a menu of additional actions. A context toolbar for the canvas background can also be displayed by right-clicking on the background. Common-canvas will display default context toolbars for nodes, links comments and the canvas background however the default actions can be customized by implementing the [`contextMenuHanlder`](2.2-Common-Canvas-callbacks.md#contextmenuhandler) callback. #### **enableSnapToGridType** This can be: "None", "During" or "After". The default is "None". @@ -298,7 +298,7 @@ This is a Boolean. The default is `false`. If set to `true` it changes the natur This can be "Straight" or "RightSideCurve". The default it "Straight". This field changes the way association links are drawn on the canvas. #### **enableBrowserEditMenu** -This can be true or false. true is the default. If true, the Cut/Copy/Paste items in the Browser's `Edit` menu, including keyboard input for those actions, can be used for performing those actions on objects (e.g. Nodes) in the canvas. When false, those items in the Browser's edit menu, including keyboard input for those actions, will not work for objects in the canvas. This will not prevent those actions working in the canvas when, say, invoked with the toolbar or canvas context menus, but this property can be used if the keyboard input for those actions into the canvas is disabled for common-canvas using the [keyboard config](/2.1-Config-Objects#keyboard-config-object) object. +This can be true or false. true is the default. If true, the Cut/Copy/Paste items in the Browser's `Edit` menu, including keyboard input for those actions, can be used for performing those actions on objects (e.g. Nodes) in the canvas. When false, those items in the Browser's edit menu, including keyboard input for those actions, will not work for objects in the canvas. This will not prevent those actions working in the canvas when, say, invoked with the toolbar or canvas context menus, but this property can be used if the keyboard input for those actions into the canvas is disabled for common-canvas using the [keyboard config](2.1-Config-Objects.md#keyboard-config-object) object. #### **enableNarrowPalette** This can be true or false. true is the default. If true when the palette is closed the narrow palette will be shown. When false the palette completely closes. @@ -344,11 +344,11 @@ The tips displayed by the palette can be further refined. For example, this woul } ``` -Note: The default content of tips can be overwritten by implementing the [tipHandler callback](/2.2-Common-Canvas-callbacks#tiphandler). +Note: The default content of tips can be overwritten by implementing the [tipHandler callback](2.2-Common-Canvas-callbacks.md#tiphandler). # Toolbar Config object -The toolbar config object is optional. If it is not provided common-canvas will display a reasonable default toolbar. If provided, it configures which action items (tools) and dividers are shown in the canvas toolbar. A toolbar will only be displayed for common-canvas if the canvas configuration field [`enableToolbarLayout`](/2.1-Config-Objects#enabletoolbarlayout) is set to "Top" (which is the default). +The toolbar config object is optional. If it is not provided common-canvas will display a reasonable default toolbar. If provided, it configures which action items (tools) and dividers are shown in the canvas toolbar. A toolbar will only be displayed for common-canvas if the canvas configuration field [`enableToolbarLayout`](2.1-Config-Objects.md#enabletoolbarlayout) is set to "Top" (which is the default). If you do specify a toolbar config object, you can specify actions for the left and right side of the toolbar to override the default toolbar. You can also optionally tell the toolbar not to handle the enable/disable state for the standard toolbar buttons using `overrideAutoEnableDisable`. The `leftBar` and `rightBar` fields contain an array of objects: one element for each toolbar item. Here is an example, toolbar configuration object: @@ -386,8 +386,8 @@ Where: Two toolbar items are automatically added to the toolbar: -- A palette action which is used for opening and closing the node palette. This is added to the left side of the left side of the toolbar if the [`enablePaletteLayout`](/2.1-Config-Objects#enablepalettelayout) field is set to either "Flyout" (the default) or "Modal" in the canvas configuration. -- A notification panel action which is used to open and close the notifications panel. This will be added to the right side of the toolbar if a [notification configuration](/2.1-Config-Objects#notification-config-object) object is specified to the `` react object. +- A palette action which is used for opening and closing the node palette. This is added to the left side of the left side of the toolbar if the [`enablePaletteLayout`](2.1-Config-Objects.md#enablepalettelayout) field is set to either "Flyout" (the default) or "Modal" in the canvas configuration. +- A notification panel action which is used to open and close the notifications panel. This will be added to the right side of the toolbar if a [notification configuration](2.1-Config-Objects.md#notification-config-object) object is specified to the `` react object. The toolbar will display the objects in the same order they are defined in the arrays. @@ -406,9 +406,9 @@ Here is an example of an action object which must contain a unique `action` fiel } ``` -* **action** - a unique identifier and the name of the action to be performed. This action name will be passed in the `data` parameter of the [editActionHandler](/2.2-Common-Canvas-callbacks#editactionhandler) callback method so you can detect when the user clicks an action in the toolbar. +* **action** - a unique identifier and the name of the action to be performed. This action name will be passed in the `data` parameter of the [editActionHandler](2.2-Common-Canvas-callbacks.md#editactionhandler) callback method so you can detect when the user clicks an action in the toolbar. - If you are using the recommended (and default) [internal object model](/2.1-Config-Objects#enableinternalobjectmodel), the following built in actions will be automatically handled by common-canvas: `undo`, `redo`, `cut`, `copy`, `paste`, `createAutoComment`, `deleteSelectedObjects`, `arrangeHorizontally`, `arrangeVertically`, `zoomIn`, `zoomOut`, and `zoomToFit`. So for example, if the `deleteSelectedObjects` action (shown as a trash can) is clicked, any selected objects will be deleted from the internal object model. + If you are using the recommended (and default) [internal object model](2.1-Config-Objects.md#enableinternalobjectmodel), the following built in actions will be automatically handled by common-canvas: `undo`, `redo`, `cut`, `copy`, `paste`, `createAutoComment`, `deleteSelectedObjects`, `arrangeHorizontally`, `arrangeVertically`, `zoomIn`, `zoomOut`, and `zoomToFit`. So for example, if the `deleteSelectedObjects` action (shown as a trash can) is clicked, any selected objects will be deleted from the internal object model. Disablement of some of these built in actions is also handled by common-canvas so, for example, when no canvas objects are selected the `deleteSelectedObjects` action (trash can icon) will be automatically disabled. You can switch off this automatic enable/disable function by setting `overrideAutoEnableDisable` field in the toolbar config to `true`. When set to true, the `enable` field in the action objects will be used to set the enablement appearance of the toolbar item. @@ -580,7 +580,7 @@ Similar to a toolbar action object, the notificationConfig object looks like thi The notification icon state is determined by the type of messages in the notification message array. By default, a notifications icon in ready state will be shown if there are messages in the notification message array. If any message in the array is of type 'warning', a notifications icon in warning state will be shown. If any message in the array is of type 'error', a notifications icon in error state will be shown. A number will be shown within the notifications icon to indicate the number of messages. -For information about the structure of notification messages, refer to the [message specification documentation](/2.4.4-Notification-Message-Specification). Notification messages can be added and removed from the notification panel by calling the canvas controller API. Refer to the canvas controller API documentation for information on how to [add/set messages in the notification message array](/2.4-Canvas-Controller-API#notification-messages-methods). +For information about the structure of notification messages, refer to the [message specification documentation](2.4.4-Notification-Message-Specification.md). Notification messages can be added and removed from the notification panel by calling the canvas controller API. Refer to the canvas controller API documentation for information on how to [add/set messages in the notification message array](2.4-Canvas-Controller-API.md#notification-messages-methods). # Context Menu Config object @@ -611,7 +611,7 @@ The context menu config object configures whether certain actions are available # Keyboard Config object The keyboard config object configures whether certain actions are available from the keyboard. -See this section for what [key combinations are supported](/2.0-Common-Canvas-Documentation#keyboard-support) +See this section for what [key combinations are supported](2.0-Common-Canvas-Documentation.md#keyboard-support) ```js const keyboardConfig = { actions: { diff --git a/docs/2.2-Common-Canvas-callbacks.md b/docs/2.2-Common-Canvas-callbacks.md index e957901eca..22a0aba8e5 100644 --- a/docs/2.2-Common-Canvas-callbacks.md +++ b/docs/2.2-Common-Canvas-callbacks.md @@ -8,7 +8,7 @@ These listeners are as follows: ```js contextMenuHandler(source, defaultMenu) ``` -This callback is used for both 'context menus' and, if the [`enableContextToolbar`](/2.1-Config-Objects#enablecontexttoolbar) canvas config option is set to `true`, for 'context toolbars'. +This callback is used for both 'context menus' and, if the [`enableContextToolbar`](2.1-Config-Objects.md#enablecontexttoolbar) canvas config option is set to `true`, for 'context toolbars'. If this callback is not provided common canvas will handle context menu/toolbars, and their actions, internally. You only need to implement this callback if you want to add or remove options to/from the context menu/toolbar. @@ -117,7 +117,7 @@ This callback is optional. You don't *need* to implement anything for it and it * Clicks a tool in the toolbar. * Clicks an option in the context menu. -* Presses a [key combination](/2.0-Common-Canvas-Documentation#keyboard-support) on the keyboard to cause the canvas to change. +* Presses a [key combination](2.0-Common-Canvas-Documentation.md#keyboard-support) on the keyboard to cause the canvas to change. * Performs some direct manipulation on the canvas such as: * Creates a node (createNode) * Moves one or a set of nodes/comments (moveObjects) @@ -224,7 +224,7 @@ It is provided with two parameters: ```js tipHandler(tipType, data) ``` -Note: The display of tooltips (or not) can be controlled using the [`tipConfig`](/2.1-Config-Objects#tipconfig) field of the canvas config object. +Note: The display of tooltips (or not) can be controlled using the [`tipConfig`](2.1-Config-Objects.md#tipconfig) field of the canvas config object. This optional callback can be implemented to override the tooltip content that is displayed by default for each canvas object. It is called before tips are shown for: palette categories, palette node templates, node, ports, links, decorations and the state tag. Common-canvas provides default implementations for all of the tips except for links and decorations, as follows: @@ -693,7 +693,7 @@ The selectionChangeHandler callback is triggered whenever the selection in the c ``` This is an optional handler you don't need to implement anything for it unless you want to. The layoutHandler callback, when provided, is called for each node on the canvas. The callback should return a Javascript object whose properties will override the default properties for node layout. The callback is provided with a parameter `data` which is the node object. Your code can look at the node properties and decide which properties it needs to override. This can be used to change the node shape, styling and position and size of node elements like the image, main label etc. -For more details see: [Customizing Node Layout Properties](/2.7-Customizing-Node-Layout-Properties) +For more details see: [Customizing Node Layout Properties](2.7-Customizing-Node-Layout-Properties.md) ## actionLabelHandler ```js diff --git a/docs/2.3-Enabling-node-creation-from-external-object.md b/docs/2.3-Enabling-node-creation-from-external-object.md index 146b622591..4e5595856e 100644 --- a/docs/2.3-Enabling-node-creation-from-external-object.md +++ b/docs/2.3-Enabling-node-creation-from-external-object.md @@ -74,4 +74,4 @@ If you want a new node to appear on the canvas as a result of the object being d } ``` -Tip: You can optionally instruct common canvas to display a graphic over the canvas as the external object is being dragged over it. To do this you need to specify the [`enableDropZoneOnExternalDrag`](/2.1-Config-Objects#enabledropzoneonexternaldrag) configuration parameter. \ No newline at end of file +Tip: You can optionally instruct common canvas to display a graphic over the canvas as the external object is being dragged over it. To do this you need to specify the [`enableDropZoneOnExternalDrag`](2.1-Config-Objects.md#enabledropzoneonexternaldrag) configuration parameter. \ No newline at end of file diff --git a/docs/2.4-Canvas-Controller-API.md b/docs/2.4-Canvas-Controller-API.md index ce8cd4626a..254ceee76f 100644 --- a/docs/2.4-Canvas-Controller-API.md +++ b/docs/2.4-Canvas-Controller-API.md @@ -1,9 +1,9 @@ # Canvas Controller API Your application code can programmatically perform many of the actions that the user can do in the common canvas using the Canvas Controller API. -Note: See this section for differences between [the structure of objects in the API and the schema.](/2.4.3-Object-structure-used-by-API#api-differences-with-schema) +Note: See this section for differences between [the structure of objects in the API and the schema.](2.4.3-Object-structure-used-by-API.md#api-differences-with-schema) -Also, this section discusses different [techniques for calling the canvas controller API](/2.4.0-Calling-the-Canvas-Controller-API). +Also, this section discusses different [techniques for calling the canvas controller API](2.4.0-Calling-the-Canvas-Controller-API.md). In most cases within the API, the pipelineId parameter is optional. If pipelineId is omitted, the method will default to the pipeline that is currently displayed in the main canvas viewport. @@ -223,7 +223,7 @@ areSelectedNodesContiguous() ## Notification messages methods -The notification panel is displayed by the user by clicking the notifications icon in the toolbar. Your application can display whatever messages it wants in the notification panel. See the [Notification Messages Specification](/2.4.4-Notification-Message-Specification) documentation for the structure of message objects. The contents of the notification panel can be managed using the methods below: +The notification panel is displayed by the user by clicking the notifications icon in the toolbar. Your application can display whatever messages it wants in the notification panel. See the [Notification Messages Specification](2.4.4-Notification-Message-Specification.md) documentation for the structure of message objects. The contents of the notification panel can be managed using the methods below: ```js // Overwrites the array of notification messages shown in the notification // panel. @@ -260,9 +260,9 @@ getNotificationMessagesMaxType() In common-canvas nodes and comments are collectively known as objects. The following methods may be used to manage either collections of comments or nodes or a mixture of both. Note: -* See this sections if you are working with [styles.](/2.4.1-Style-Specification) -* See this section if you are working with [decorations.](/2.4.2-Decoration-Specification) -* See this section for differences between [the structure of objects in the API and the schema.](/2.4.3-Object-structure-used-by-API#api-differences-with-schema) +* See this sections if you are working with [styles.](2.4.1-Style-Specification.md) +* See this section if you are working with [decorations.](2.4.2-Decoration-Specification.md) +* See this section for differences between [the structure of objects in the API and the schema.](2.4.3-Object-structure-used-by-API.md#api-differences-with-schema) ```js // Moves the objects identified in the data object which must be in the // pipeline identified by the pipeline ID. diff --git a/docs/2.4.1-Style-Specification.md b/docs/2.4.1-Style-Specification.md index 3a91c893bf..07f13cd824 100644 --- a/docs/2.4.1-Style-Specification.md +++ b/docs/2.4.1-Style-Specification.md @@ -5,7 +5,7 @@ There are multiple was to specify the styles for the objects common-canvas displ For more precise styling of objects the style specification object can be used to provide a number of styles to common canvas to set the inline styles on numerous elements of an object. For example, a node is made up of: a selection outline; a node body (rectangle); an image, a label etc. -Style specifications may be applied to common-canvas objects using the following [Canvas Controller](/2.4-Canvas-Controller-API) methods: +Style specifications may be applied to common-canvas objects using the following [Canvas Controller](2.4-Canvas-Controller-API.md) methods: ```js setObjectsStyle() setObjectsMultiStyle() diff --git a/docs/2.4.2-Decoration-Specification.md b/docs/2.4.2-Decoration-Specification.md index cd096cf8c5..cab5187c9f 100644 --- a/docs/2.4.2-Decoration-Specification.md +++ b/docs/2.4.2-Decoration-Specification.md @@ -16,13 +16,13 @@ Decorations can be added to the nodes and/or links in four different ways: getNodeDecorations(nodeId, pipelineId) getLinkDecorations(linkId, pipelineId) ``` - See the [CanvasController API documentation](/2.4-Canvas-Controller-API) for more details. + See the [CanvasController API documentation](2.4-Canvas-Controller-API.md) for more details. -2. Node decorations can be specified in the [nodeLayout object](/2.1-Config-Objects#enablenodelayout) in the canvas config. Decorations specified in this way are applied to all nodes on the canvas. +2. Node decorations can be specified in the [nodeLayout object](2.1-Config-Objects.md#enablenodelayout) in the canvas config. Decorations specified in this way are applied to all nodes on the canvas. 3. Decorations can be applied to, and retrieved from, nodes or links in the pipelineFlow in the `app_data.ui_data` section for the node or link. (Note: JSX objects are not supported in the pipelineFlow document). -4. Decorations can be returned in the layout information returned from the [layoutHandler](/2.2-Common-Canvas-callbacks#layouthandler) CommonCanvas callback method. +4. Decorations can be returned in the layout information returned from the [layoutHandler](2.2-Common-Canvas-callbacks.md#layouthandler) CommonCanvas callback method. # Specification @@ -161,19 +161,19 @@ For a link, this can be one of these 3 enumerated values: A number of pixels. This is only applicable when the decoration is for a link line and then, only with straight connecting lines. That is, for node to node connections when the config property `enableLinkType` is set to `"straight"`. When specified, it will move the anchor point for the decoration to a new position along the connecting line relative to the initial position specified in the decoration's `position` property. A positive number moves the decoration along the line from the starting position towards the target of the link and a negative number backwards towards the source of the link. For example, if a straight link decoration has `position` of `source` and a `distance` of `20` the decoration's anchor point will be 20 pixels along the link line from the source (start) point of the line. After the `distance` value has been applied to the anchor point of the decoration, any `x_pos` and `y_pos` adjustment will be applied to fine tune the decoration's final position. #### **x_pos** -This is the number of pixels horizontally from the anchor point that the decoration is positioned. It can be positive or negative. If omitted it takes a default value from the [node layout properties](/2.7-Customizing-Node-Layout-Properties#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default). x_pos is not applicable if you specify an SVG path using the `path` field, because the SVG path can be used to position the shape. +This is the number of pixels horizontally from the anchor point that the decoration is positioned. It can be positive or negative. If omitted it takes a default value from the [node layout properties](2.7-Customizing-Node-Layout-Properties.md#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default). x_pos is not applicable if you specify an SVG path using the `path` field, because the SVG path can be used to position the shape. #### **y_pos** -This is the number of pixels vertically from the anchor point that the decoration is positioned. It can be positive or negative. If omitted it takes a default value from the [node layout properties](/2.7-Customizing-Node-Layout-Properties#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default). y_pos is not applicable if you specify an SVG path using the `path` field, because the SVG path can be used to position the shape. +This is the number of pixels vertically from the anchor point that the decoration is positioned. It can be positive or negative. If omitted it takes a default value from the [node layout properties](2.7-Customizing-Node-Layout-Properties.md#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default). y_pos is not applicable if you specify an SVG path using the `path` field, because the SVG path can be used to position the shape. #### **width** -This is the width for the decorator in pixels. For an image decorator, it is the width of the rectangle surrounding the image. For a label decorator it is the width allowed for display of the label text. If omitted it takes a default value from the [node layout properties](/2.7-Customizing-Node-Layout-Properties#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default) for Node decorations and from the canvas layout properties for Link properties. +This is the width for the decorator in pixels. For an image decorator, it is the width of the rectangle surrounding the image. For a label decorator it is the width allowed for display of the label text. If omitted it takes a default value from the [node layout properties](2.7-Customizing-Node-Layout-Properties.md#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default) for Node decorations and from the canvas layout properties for Link properties. #### **height** -This is the height for the decorator in pixels. For an image decorator, it is the height of the rectangle surrounding the image. For a label decorator it is the height allowed for display of the label text. If omitted it takes a default value from the [node layout properties](/2.7-Customizing-Node-Layout-Properties#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default) for Node decorations and from the canvas layout properties for Link properties. +This is the height for the decorator in pixels. For an image decorator, it is the height of the rectangle surrounding the image. For a label decorator it is the height allowed for display of the label text. If omitted it takes a default value from the [node layout properties](2.7-Customizing-Node-Layout-Properties.md#what-are-the-node-layout-properties-and-what-are-they-set-to-by-default) for Node decorations and from the canvas layout properties for Link properties. #### **hotspot** -A Boolean. It defaults to false. When set to true the decoration becomes clickable and when it is clicked the [decorationCallbackHandler](/2.2-Common-Canvas-callbacks#decorationactionhandler) is called with the ID of the decoration passed as a parameter. +A Boolean. It defaults to false. When set to true the decoration becomes clickable and when it is clicked the [decorationCallbackHandler](2.2-Common-Canvas-callbacks.md#decorationactionhandler) is called with the ID of the decoration passed as a parameter. #### **class_name** An optional class that will be applied to the decoration. You can add a style rule that references that class in your CSS to style the decoration and override the default styles. diff --git a/docs/2.4.6-Constructing-a-read-only-or-locked-canvas.md b/docs/2.4.6-Constructing-a-read-only-or-locked-canvas.md index 7043437621..3fced7b7ca 100644 --- a/docs/2.4.6-Constructing-a-read-only-or-locked-canvas.md +++ b/docs/2.4.6-Constructing-a-read-only-or-locked-canvas.md @@ -5,16 +5,16 @@ Some host applications need to display flows that cannot be edited by the user. There are many aspects of common-canvas components that need to considered for a read-only canvas. Since common-canvas is highly customizable it is not possible for the common-canvas code to manage components of the canvas that have been customized by the host application. For example, if the host app code added tools to the toolbar, common-canvas does not know whether those tools should be disabled when displaying a read-only canvas or not. So the host application code will need to manage that. Let's look at each element of common-canvas and see what needs to be done. # General Config -There is one main canvas configuration property that will change the common-canvas behavior to implement a read-only canvas. This is [`enableEditingActions`](/2.1-Config-Objects#enableeditingactions) which defaults to true and needs to be set to `false` for read-only canvases. The sections below will cover what effect this will have on the different components of common-canvas and what you need to do for any customizations you have made. +There is one main canvas configuration property that will change the common-canvas behavior to implement a read-only canvas. This is [`enableEditingActions`](2.1-Config-Objects#enableeditingactions) which defaults to true and needs to be set to `false` for read-only canvases. The sections below will cover what effect this will have on the different components of common-canvas and what you need to do for any customizations you have made. # Canvas Setting `enableEditingActions` to false will prevent nodes and comments (and detachable links) from being moved relative to one another. It will also prevent new links from being created and prevent text (like comments or node labels) from being edited. -With `enableEditingActions` set to false, the canvas can still be panned (left/right and up/down) and also zoomed in and out. Nodes, comments and links can still be clicked (to select) and right clicked (to display a context menu) and double clicked (usually to show properties). If you implemented any behavior for these interactions, using the [`clickActionHandler`](/2.2-Common-Canvas-callbacks#clickactionhandler), you'll need to review what your code is doing and make sure it is appropriate when a read-only canvas is being displayed. +With `enableEditingActions` set to false, the canvas can still be panned (left/right and up/down) and also zoomed in and out. Nodes, comments and links can still be clicked (to select) and right clicked (to display a context menu) and double clicked (usually to show properties). If you implemented any behavior for these interactions, using the [`clickActionHandler`](2.2-Common-Canvas-callbacks.md#clickactionhandler), you'll need to review what your code is doing and make sure it is appropriate when a read-only canvas is being displayed. -Common-canvas allows objects from outside the canvas to be dropped onto the canvas to create a new node. For example, a file can be dragged from the operating system desktop onto the canvas to create a data node. With `enableEditingActions` set to false, the drag/drop gesture (which common-canvas cannot prevent) will prevent a new node from being created. It is recommended you switch the [`enableDropZoneOnExternalDrag`](/2.1-Config-Objects#enabledropzoneonexternaldrag) config property to false when displaying a read-only canvas. This will prevent a 'drop zone' graphic from appearing over the canvas when the object is dragged over the top of the canvas. +Common-canvas allows objects from outside the canvas to be dropped onto the canvas to create a new node. For example, a file can be dragged from the operating system desktop onto the canvas to create a data node. With `enableEditingActions` set to false, the drag/drop gesture (which common-canvas cannot prevent) will prevent a new node from being created. It is recommended you switch the [`enableDropZoneOnExternalDrag`](2.1-Config-Objects.md#enabledropzoneonexternaldrag) config property to false when displaying a read-only canvas. This will prevent a 'drop zone' graphic from appearing over the canvas when the object is dragged over the top of the canvas. -Some applications need to show a tag (called a 'state tag') over the canvas to emphasize the 'read-only' or 'locked' state of the canvas. This can be displayed using the [`enableStateTag`](/2.1-Config-Objects#enablestatetag) canvas config property. The tooltip of the 'state tag' can be provided by implementing the [`tipHandler`](/2.2-Common-Canvas-callbacks#tiphandler) callback function. +Some applications need to show a tag (called a 'state tag') over the canvas to emphasize the 'read-only' or 'locked' state of the canvas. This can be displayed using the [`enableStateTag`](2.1-Config-Objects.md#enablestatetag) canvas config property. The tooltip of the 'state tag' can be provided by implementing the [`tipHandler`](2.2-Common-Canvas-callbacks.md#tiphandler) callback function. Since there are numerous possible styles for nodes and links when displaying a read-only canvas, it isn't possible for common-canvas to style the canvas objects appropriately for all different designs. You will need to override any styles for nodes and links to fit your design. To help with this common-canvas sets a class called `config-edit-actions-false` on the top-level div that contains the common-canvas components. You can use this to build specific selectors in your CSS/SCSS that will override the styles applied to nodes and links by default. For example, to override node icon and label colors you could specify the following in your SCSS file: ``` @@ -31,19 +31,19 @@ Since there are numerous possible styles for nodes and links when displaying a r ``` # Context menu -Setting `enableEditingActions` to false will prevent any options, that would edit the canvas objects, from being displayed in the common-canvas default context menu. For example, `Delete` will not show up in the context menu. See the [`enableEditingActions` documentation](/2.1-Config-Objects#enableeditingactions) for a list of options that are disabled. +Setting `enableEditingActions` to false will prevent any options, that would edit the canvas objects, from being displayed in the common-canvas default context menu. For example, `Delete` will not show up in the context menu. See the [`enableEditingActions` documentation](2.1-Config-Objects.md#enableeditingactions) for a list of options that are disabled. -Your application code can add your own options to the context menu by implementing the [`contextMenuHandler`](/2.2-Common-Canvas-callbacks#contextmenuhandler) callback function. If you have added your own options, you should review your code and ensure options that might change the canvas objects are not added to the context menu when you are displaying a read-only canvas. +Your application code can add your own options to the context menu by implementing the [`contextMenuHandler`](2.2-Common-Canvas-callbacks.md#contextmenuhandler) callback function. If you have added your own options, you should review your code and ensure options that might change the canvas objects are not added to the context menu when you are displaying a read-only canvas. Note: The common-canvas default menu, passed as the second parameter to the `contextMenuHandler` callback, will still contain editing options. This means, if your code relies on them for some reason, (for example for calculating the position of your added options) your application code will still work OK. The editing options will be removed after your code returns the array of items that describe the desired menu from the `contextMenuHandler` callback. # Toolbar -The toolbar can display buttons for standard common-canvas actions and also buttons for any application-specific actions added by your code. Setting `enableEditingActions` to false will cause buttons for any standard common-canvas actions, that edit the canvas objects, to be disabled regardless of the setting for the `enable` property for each action. See the [`enableEditingActions` documentation](/2.1-Config-Objects#enableeditingactions) for a list of actions that are disabled. +The toolbar can display buttons for standard common-canvas actions and also buttons for any application-specific actions added by your code. Setting `enableEditingActions` to false will cause buttons for any standard common-canvas actions, that edit the canvas objects, to be disabled regardless of the setting for the `enable` property for each action. See the [`enableEditingActions` documentation](2.1-Config-Objects.md#enableeditingactions) for a list of actions that are disabled. You should review any application-specific action buttons you have added to the toolbar and decide if they need to be disabled or removed from the toolbar when displaying a read-only canvas. # Keyboard -Common-canvas supports a number of keyboard shortcuts. Setting `enableEditingActions` to false, disables any keyboard shortcuts that edit the canvas objects (such as Delete). See the [`enableEditingActions` documentation](/2.1-Config-Objects#enableeditingactions) for a list of keyboard shortcuts that are disabled. +Common-canvas supports a number of keyboard shortcuts. Setting `enableEditingActions` to false, disables any keyboard shortcuts that edit the canvas objects (such as Delete). See the [`enableEditingActions` documentation](2.1-Config-Objects.md#enableeditingactions) for a list of keyboard shortcuts that are disabled. # Palette Setting `enableEditingActions` to false: @@ -51,7 +51,7 @@ Setting `enableEditingActions` to false: * prevents node templates from being dragged from the palette and * disables the double-click action on node templates which automatically adds a node to the canvas. -You should decide if your application should display the palette when displaying a read-only canvas or not. The palette can be hidden by setting the canvas config property [`enablePaletteLayout`](/2.1-Config-Objects#enablepalettelayout) to "None". +You should decide if your application should display the palette when displaying a read-only canvas or not. The palette can be hidden by setting the canvas config property [`enablePaletteLayout`](2.1-Config-Objects.md#enablepalettelayout) to "None". # Test Harness: Sample Read-Only application The test harness contains a sample application called "Read-Only" which shows how a read-only canvas can be built using the `enableEditingActions` config option. In the application there are three toolbar buttons which can be used to navigate between Editable state, Read-Only state and Locked state. You can review the `.jsx` and `.scss` files in the [application code](https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness/src/client/components/custom-canvases/read-only) to see how the application is implemented and styled. diff --git a/docs/2.7-Customizing-Node-Layout-Properties.md b/docs/2.7-Customizing-Node-Layout-Properties.md index 64c033441b..9ca915f660 100644 --- a/docs/2.7-Customizing-Node-Layout-Properties.md +++ b/docs/2.7-Customizing-Node-Layout-Properties.md @@ -285,7 +285,7 @@ The values for `bodyPath` and `selectionPath` must be [SVG path strings](https:/ ``` ## Overriding the default node layout properties -There are a couple of ways to do this depending on your needs. First, if you just want to change the appearance of **all** nodes on your canvas you can specify the `enableNodeLayout` configuration parameter in the [main canvas configuration object](/2.1-Config-Objects#config-object). The properties from this object will replace any properties in the default set, which was chosen based on the settings of `enableNodeFormatType`. So you don't need to provide all of the properties; just the ones you want to replace. +There are a couple of ways to do this depending on your needs. First, if you just want to change the appearance of **all** nodes on your canvas you can specify the `enableNodeLayout` configuration parameter in the [main canvas configuration object](2.1-Config-Objects.md#config-object). The properties from this object will replace any properties in the default set, which was chosen based on the settings of `enableNodeFormatType`. So you don't need to provide all of the properties; just the ones you want to replace. Let's say you want your nodes to be displayed as ellipses. You could provide the following settings in `enableNodeLayout` in the canvas config: ```js @@ -313,7 +313,7 @@ const canvasConfig = { ``` ## Customizing individual nodes or categories of nodes -If you want each node, or category of nodes, to have a different layout based on some criteria you can use the second method for overriding the node layout properties. This uses the [layoutHandler callback method](/2.2-Common-Canvas-callbacks#layouthandler). When you specify this callback method to common canvas, it will be called for each node on the canvas, during initialization and, occasionally, at other times. +If you want each node, or category of nodes, to have a different layout based on some criteria you can use the second method for overriding the node layout properties. This uses the [layoutHandler callback method](2.2-Common-Canvas-callbacks.md#layouthandler). When you specify this callback method to common canvas, it will be called for each node on the canvas, during initialization and, occasionally, at other times. The method should return a simple JavaScript object that contains any node layout properties you want to override from the defaults and the ones specified in the `enableNodeLayout` field in the canvas config. This is an important point: there are three levels of properties provided where each overrides the previous set: @@ -340,7 +340,7 @@ layoutHandler(data) { ``` OK, it's not a very complicated example but hopefully you get the message :) -In the test harness, you can see an example application that use the [layoutHandler callback method](/2.2-Common-Canvas-callbacks#layouthandler). In the test harness: +In the test harness, you can see an example application that use the [layoutHandler callback method](2.2-Common-Canvas-callbacks.md#layouthandler). In the test harness: 1. Open the Common Canvas side panel (click the hamburger icon) 2. Select the `Explain` sample application @@ -389,4 +389,4 @@ So for example if you want the node body (the rectangle) to be colored orange yo fill: orange; } ``` -Note: You can use the [`enableParentClass`](/2.1-Config-Objects#enableparentclass) canvas config field to make you CSS rulesets specific so your styles are picked up in preference to the common-canvas default styles. +Note: You can use the [`enableParentClass`](2.1-Config-Objects.md#enableparentclass) canvas config field to make you CSS rulesets specific so your styles are picked up in preference to the common-canvas default styles. diff --git a/docs/2.9-External-Subflows-support.md b/docs/2.9-External-Subflows-support.md index 45b62557f0..c0e891ff51 100644 --- a/docs/2.9-External-Subflows-support.md +++ b/docs/2.9-External-Subflows-support.md @@ -11,15 +11,15 @@ Common-canvas supports external pipelines but the host application UI code needs Common-canvas supports lazy loading of external pipeline flows so they will only be requested from your code when the user performs some gesture that requires the pipeline (from within the external pipeline flow) to be displayed. ## Creating an external sub-flow -When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true (the default) and, when a set of objects are selected from which a super node can be created, the default common-canvas context menu will include a `Create External Supernode` option. +When the common-canvas config property [enableExternalPipelineFlows](2.1-Config-Objects.md#enableexternalpipelineflows) is set to true (the default) and, when a set of objects are selected from which a super node can be created, the default common-canvas context menu will include a `Create External Supernode` option. When the `Create External Supernode` option is clicked the `createSuperNodeExternal` action is executed. -If your application doesn't use the default context menu you can define your own context menu (returned from `contextMenuHandler`) to contain an option which maps to the `createSuperNodeExternal` action. See the section on the [contextMenuHandler](/2.2-Common-Canvas-callbacks#contextmenuhandler) for details on how to do this. +If your application doesn't use the default context menu you can define your own context menu (returned from `contextMenuHandler`) to contain an option which maps to the `createSuperNodeExternal` action. See the section on the [contextMenuHandler](2.2-Common-Canvas-callbacks.md#contextmenuhandler) for details on how to do this. When the `createSuperNodeExternal` action is executed, the `beforeEditActionHandler` callback is called before the external sub-flow is created. The `beforeEditActionHandler` is called where the first parameter `data` has two properties `externalUrl` and `externalPipelineFlowId` which will both be set to empty string. Your code must set these to whatever values you want for the url and pipeline flow ID. The url will be assigned to the `subflow_ref.url` property of the supernode that is being created. The pipeline flow ID will be assigned to the newly created pipeline flow. -Your code must return the `data` parameter from the `beforeEditActionHandler` callback if you want the action to proceed and create the sub-flow. If you need to do any asynchronous activity at this point see the documentation on the [beforeEditActionHanlder](/2.2-Common-Canvas-callbacks#beforeeditactionhandler) for details on how to do that. +Your code must return the `data` parameter from the `beforeEditActionHandler` callback if you want the action to proceed and create the sub-flow. If you need to do any asynchronous activity at this point see the documentation on the [beforeEditActionHanlder](2.2-Common-Canvas-callbacks.md#beforeeditactionhandler) for details on how to do that. When the sub-flow has been created common-canvas will call the `editActionHandler` callback with the `createSuperNodeExternal` action. In this callback you can, if you wish, retrieve the pipeline flow document that has been created internally in common-canvas using `CanvasController.getExternalPipelineFlow(url)`. Your code can then save it to your repository. Alternatively, you can wait until some later time, like perhaps during an auto-save, to retrieve and store the pipeline flow externally in your repository. @@ -48,17 +48,17 @@ You need to implement the `beforeEditActionHandler` so that: * you then assign it to the `externalPipelineFlow` property of the data object * you then return the data object from the callback. -Your code must return the `data` parameter from the `beforeEditActionHandler` callback if you want the action to proceed and load the external pipeline flow. If you need to do any asynchronous activity at this point see the documentation on the [beforeEditActionHanlder](/2.2-Common-Canvas-callbacks#beforeeditactionhandler) for details on how to do that. +Your code must return the `data` parameter from the `beforeEditActionHandler` callback if you want the action to proceed and load the external pipeline flow. If you need to do any asynchronous activity at this point see the documentation on the [beforeEditActionHanlder](2.2-Common-Canvas-callbacks.md#beforeeditactionhandler) for details on how to do that. ## Converting a local supernode to an external supernode -When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true, and a local supernode's is right clicked, the default common-canvas context menu will include a `Convert local to external` option. This will execute the `convertSuperNodeLocalToExternal` action. +When the common-canvas config property [enableExternalPipelineFlows](2.1-Config-Objects.md#enableexternalpipelineflows) is set to true, and a local supernode's is right clicked, the default common-canvas context menu will include a `Convert local to external` option. This will execute the `convertSuperNodeLocalToExternal` action. -The `convertSuperNodeLocalToExternal` action is similar to the `createSuperNodeExternal` action in that a new external pipeline flow is being created. Consequently, you can follow the instructions in the [Creating an external sub-flow](/2.9-External-Subflows-support#creating-an-external-sub-flow) section for providing the appropriate properties of the `data` object in the `beforeEditActionHandler` and `editActionHandler` callbacks. +The `convertSuperNodeLocalToExternal` action is similar to the `createSuperNodeExternal` action in that a new external pipeline flow is being created. Consequently, you can follow the instructions in the [Creating an external sub-flow](2.9-External-Subflows-support.md#creating-an-external-sub-flow) section for providing the appropriate properties of the `data` object in the `beforeEditActionHandler` and `editActionHandler` callbacks. ## Converting an external supernode to a local supernode -When the common-canvas config property [enableExternalPipelineFlows](/2.1-Config-Objects#enableexternalpipelineflows) is set to true, and an external supernode's is right clicked, the default common-canvas context menu will include a `Convert external to local` option. This will execute the `convertSuperNodeExternalToLocal` action. +When the common-canvas config property [enableExternalPipelineFlows](2.1-Config-Objects.md#enableexternalpipelineflows) is set to true, and an external supernode's is right clicked, the default common-canvas context menu will include a `Convert external to local` option. This will execute the `convertSuperNodeExternalToLocal` action. -The `convertSuperNodeExternalToLocal` action is similar to the `expandSuperNodeInPlace` action in that an external pipeline flow may need to be retrieved from your repository. Consequently, you can follow the instructions in the [Loading an external sub-flow](/2.9-External-Subflows-support#loading-an-external-sub-flow) section for providing the appropriate properties of the `data` object in the `beforeEditActionHandler` callback. +The `convertSuperNodeExternalToLocal` action is similar to the `expandSuperNodeInPlace` action in that an external pipeline flow may need to be retrieved from your repository. Consequently, you can follow the instructions in the [Loading an external sub-flow](2.9-External-Subflows-support.md#loading-an-external-sub-flow) section for providing the appropriate properties of the `data` object in the `beforeEditActionHandler` callback. ## Deleting an external supernode/sub-flow When the user deletes an external supernode/sub-flow the supernode will be removed from the canvas. You code does not need to do anything unless you want to also remove the external pipeline flow from your repository. diff --git a/docs/3.0-Common-Properties-documentation.md b/docs/3.0-Common-Properties-documentation.md index cd8397502f..77e4e2a97a 100644 --- a/docs/3.0-Common-Properties-documentation.md +++ b/docs/3.0-Common-Properties-documentation.md @@ -40,7 +40,7 @@ propertiesInfo: { } ``` [parameterDef schema and examples](https://github.com/elyra-ai/pipeline-schemas/tree/master/common-canvas/parameter-defs) -[3.1 Common Properties Parameter Definition](/3.1-Common-Properties-Parameter-Definition) +[3.1 Common Properties Parameter Definition](3.1-Common-Properties-Parameter-Definition.md) [`expressionInfo` schema and examples](https://github.com/elyra-ai/pipeline-schemas/tree/master) or... @@ -110,9 +110,9 @@ var messages = i18nData.messages; - returnValueFiltering `array` - Default []. When set this will filter out any values in the array in the parameters returned when `applyPropertyChanges` is call. Only primitive data types are currently supported. - categoryView `string` - View categories in right-flyout. Can be `"accordions"` or `"tabs"`. default: `"accordions"`. - callbacks object - See [callbacks](#callbacks) section for more details on each callback method. -- customPanels `array`: array of custom panels. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-panels) for more details. -- customControls `array`: array of custom controls. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-controls) for more details. -- customConditionOps `array`: array of custom condition operators. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-condition-operators) +- customPanels `array`: array of custom panels. See [3.5 Common Properties Custom Components](3.5-Common-Properties-Custom-Components.md#custom-panels) for more details. +- customControls `array`: array of custom controls. See [3.5 Common Properties Custom Components](3.5-Common-Properties-Custom-Components.md#custom-controls) for more details. +- customConditionOps `array`: array of custom condition operators. See [3.5 Common Properties Custom Components](3.5-Common-Properties-Custom-Components.md#custom-condition-operators) - light `boolean`: Carbon controls in common-properties will use light mode. When the `light` option is disabled, the background color will be the same as the Carbon theme background. When the `light` option is enabled, the background color is set to $ui-01. Defaults to `true` **Internationalization and override of labels in CommonProperties** @@ -130,7 +130,7 @@ applyPropertiesEditing(closeEditor) ### Using CommonProperties in CommonCanvas right-flyout panel -[Common Canvas](/2.0-Common-Canvas-Documentation#step-3--display-the-canvas) has a right-flyout panel that can render a React object. It can be used to render Common Properties in a flyout panel. +[Common Canvas](2.0-Common-Canvas-Documentation.md#step-3--display-the-canvas) has a right-flyout panel that can render a React object. It can be used to render Common Properties in a flyout panel. Create a CommonProperties object with containerType set to "Custom" and rightFlyout set to true. ```html @@ -204,7 +204,7 @@ propertyListener(data) { ``` ### controllerHandler() -Executes when the property controller is created. Returns the property controller. See [here](/3.6-Common-Properties-Controller) for APIs +Executes when the property controller is created. Returns the property controller. See [here](3.6-Common-Properties-Controller.md) for APIs ```js controllerHandler(propertyController) { diff --git a/docs/3.1-Common-Properties-Parameter-Definition.md b/docs/3.1-Common-Properties-Parameter-Definition.md index 31ec395383..7119805924 100644 --- a/docs/3.1-Common-Properties-Parameter-Definition.md +++ b/docs/3.1-Common-Properties-Parameter-Definition.md @@ -110,10 +110,10 @@ Example } ``` -UI-only parameters require information about the parameters same as the parameter definition information used for the backend parameters. The UI-only parameter definition information is stored in the UI-hints section in the sub-section named `ui_parameters`. A description of the UI hints specifications can be found here: [3.2 Common Properties UI Hints](/3.2-Common-Properties--UI-Hints) +UI-only parameters require information about the parameters same as the parameter definition information used for the backend parameters. The UI-only parameter definition information is stored in the UI-hints section in the sub-section named `ui_parameters`. A description of the UI hints specifications can be found here: [3.2 Common Properties UI Hints](3.2-Common-Properties--UI-Hints.md) -UI-only properties are returned to the consuming application via a separate parameter on the applyPropertiesChanges callback. See the `Callbacks` section of [3.1 Common Properties Documentation section.](/3.0-Common-Properties-documentation) +UI-only properties are returned to the consuming application via a separate parameter on the applyPropertiesChanges callback. See the `Callbacks` section of [3.1 Common Properties Documentation section.](3.0-Common-Properties-documentation.md) ## Complex Types @@ -157,11 +157,11 @@ Note that both parameter and complex type definitions are in the exact same form ## UI Hints -A set of specifications for controlling the layout and flow of the common properties. A description of the UI hints specifications can be found here: [3.2 Common Properties UI Hints](/3.2-Common-Properties--UI-Hints) +A set of specifications for controlling the layout and flow of the common properties. A description of the UI hints specifications can be found here: [3.2 Common Properties UI Hints](3.2-Common-Properties--UI-Hints.md) ## Conditions A set of specifications for controlling validation checking of parameters during the common properties dialog. A description of the Conditions specifications can be found here: -[3.4 Common Properties Conditions](/3.4-Common-Properties-Conditions) +[3.4 Common Properties Conditions](3.4-Common-Properties-Conditions.md) ## Data Set Metadata The data set metadata is an array of datarecord-metadata objects as defined in the datarecord-metadata JSON schema. Each datarecord-metadata object contains and array of fields that provide column information on the input data set. [schema and examples](https://github.com/elyra-ai/pipeline-schemas/tree/main/common-pipeline/datarecord-metadata) diff --git a/docs/3.2-Common-Properties-UI-Hints.md b/docs/3.2-Common-Properties-UI-Hints.md index 014d2a617e..ea8b03d7ea 100644 --- a/docs/3.2-Common-Properties-UI-Hints.md +++ b/docs/3.2-Common-Properties-UI-Hints.md @@ -8,9 +8,9 @@ The UI Hints section consists a set of simple and complex attributes. * `id` (*string*) Dialog id. * `label` (*object*) External name of dialog. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](3.2-Common-Properties--UI-Hint.md#resource-definition) * `description` (*object*) Description of dialog. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) * `editor_size` (*string*) The width of the properties editor panel. This can have a value of `"small"`, `"medium"`, `"large"` or `"max"`. The default is `"small"`. - When `"small"` is specified the properties panel is displayed with a default width of 320px and with a resize button that allows the panel to be increased in size up to the `"medium"` size which is 480px. - When `"medium"` is specified the properties panel has a width of 480px and with a resize button that allows the panel to be increased in size up to the `"large"` size which is 640px. @@ -49,14 +49,14 @@ Example of the simple attributes: Group info attributes. * `id` (*string*) **Required** Panel id -* `type` (*string*) The group type to be displayed. see Group/Panel Controls in [3.3 Common Properties Controls](/3.3-Common-Properties-Controls). +* `type` (*string*) The group type to be displayed. see Group/Panel Controls in [3.3 Common Properties Controls](3.3-Common-Properties-Controls.md). * `depends_on_ref` (*string*) Property name this group depends upon. Valid for panelSelector groups only. * `label` (*object*) Group label. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) * `description` (*object*) Group description. Only used with `textPanel` and `actionPanel`. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) - + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) - + `link` (object) Optional link in the description. [tooltipLinkHandler callback](/3.0-Common-Properties-documentation#tooltiplinkhandler) must be defined whenever link object is added in uiHints.. + + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + + See [Dynamic Text Expressions](3.2-Common-Properties--UI-Hints.md#dynamic-text-expressions) + + `link` (object) Optional link in the description. [tooltipLinkHandler callback](3.0-Common-Properties-documentation.md#tooltiplinkhandler) must be defined whenever link object is added in uiHints.. + `id` (string) Required unique link id. + `data` (object) Data passed to the tooltipLinkHandler callback. * `parameter_refs` (*array[string]*) List of parameter to be displayed. @@ -86,7 +86,7 @@ Example group info section: ``` ## UI-only Parameters -UI-only parameters require information about the parameters same as the parameter definition information used for the backend parameters. The UI-only parameter definition information is stored in the UI-hints section in the sub-section named `ui_parameters`. The format of the information in the `ui_parameters` sub-section is documented in the `Parameter Definition` section of [Common Properties Parameter Definition](/3.1-Common-Properties-Parameter-Definition/). +UI-only parameters require information about the parameters same as the parameter definition information used for the backend parameters. The UI-only parameter definition information is stored in the UI-hints section in the sub-section named `ui_parameters`. The format of the information in the `ui_parameters` sub-section is documented in the `Parameter Definition` section of [Common Properties Parameter Definition](3.1-Common-Properties-Parameter-Definition.md). Example ```js @@ -113,15 +113,15 @@ Parameter info attributes. * `parameter_ref` (*string*) **Required** Parameter name. * `label` (*object*) External name for parameter. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) * `label_visible` (*boolean*) Determines whether to display the label for a control. * `description` (*object*) Description of parameter with optional placement context. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + `placement` (*string*) Placement context for the text. Valid values are `as_tooltip, on_panel`. - + `link` (*object*) Optional link in the description. [tooltipLinkHandler callback](/3.0-Common-Properties-documentation#tooltiplinkhandler) must be defined whenever link object is added in uiHints.. + + `link` (*object*) Optional link in the description. [tooltipLinkHandler callback](3.0-Common-Properties-documentation.md#tooltiplinkhandler) must be defined whenever link object is added in uiHints.. + `id` (*string*) Required unique link id. + `data` (*object*) Data passed to the tooltipLinkHandler callback. -* `control` (*string*) Which control to use. see Parameter Controls in [3.3 Common Properties Controls](/3.3-Common-Properties-Controls). +* `control` (*string*) Which control to use. see Parameter Controls in [3.3 Common Properties Controls](3.3-Common-Properties-Controls.md). * `increment` (*number*) Determines the increment/decrement value for the spinner control only. The default value is `1`. * `orientation` (*string*) Determines how the control is displayed. Valid values are `vertical, horizontal`. * `width` (*number*) Column width for tables. The widths provided for table columns are used to calculate relative widths for each table column. So for example a 3 column table with widths of 20, 30, and 50 would use 20%, 30%, and 50% of the overall table width, respectively. @@ -130,7 +130,7 @@ Parameter info attributes. * `separator` (*string*) Determines where to put a separator relative to the current control. Valid values are ` after, before`. * `visible` (*boolean*) Determines whether to display control in a table cell. Used in complex types only. * `place_holder_text` (*object*) Text hint for the user displayed input controls. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) * `resource_key` (*string*) Used as a key for enum value labels in the resources section of property definition. * `edit_style` (*string*) Editing style of elements in a table. Valid values are `subpanel, inline, on_panel`. * `value_icons` (*array[string]*) For enumerated types, this defines the set of icons for the valid values. The ordering must be consistent with the order in the parameter enum attribute. @@ -141,13 +141,13 @@ Parameter info attributes. * `dm_image` (*string*) This can be set to display an icon of the corresponding dm type in the `role`:`column` field of a table. Valid values are `measure`, `type`, `none` * `summary` (*boolean*) Determines if parameter should be shown in the summary when using a `summaryPanel`. * `text_before` (*object*) Text to be displayed before the control - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + `type` (*string*) Adds a icon and additional formatting to the text. Only `info` is support at this time. - + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) + + See [Dynamic Text Expressions](3.2-Common-Properties--UI-Hints.md#dynamic-text-expressions) * `text_after` (*object*) Text to be displayed after the control - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + `type` (*string*) Adds a icon and additional formatting to the text. Only `info` is support at this time. - + See [Dynamic Text Expressions](/3.2-Common-Properties--UI-Hints#dynamic-text-expressions) + + See [Dynamic Text Expressions](3.2-Common-Properties--UI-Hints.md#dynamic-text-expressions) * `custom_control_id` (*string*) Id that is used to determine which custom control to use when `control=custom` * `data` (*any*) Returned in custom control constructor without any changes. * `rows` (*integer*) Number of rows to show in a table before scrolling starts. If one table in a panel is set to -1, that table will use the remaining available vertical space, down to a minimum of 2 rows. Used in expression and code controls to determine the number of rows to show for those controls. @@ -184,7 +184,7 @@ Complex Type info attributes. * `complex_type_ref` (*string*) **Required** Name of complex type, can be referenced in other places. * `key_definition` (*string*) A set of parameter info attributes about the key parameter. * `label` (*object*) External name of subpanel. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) * `parameters` (*object*) **Required** List of parameters that are part of this complex parameter. This parameter can either have a set of parameter_info attributes or other nested complex_type_info attributes. * `header` (*boolean*) If `true` then the table has a header row with column names. Defaults to `true`. * `add_remove_rows` (*boolean*) If `true` then the table can have rows added and removed. Defaults to `true`. @@ -196,9 +196,9 @@ Complex Type info attributes. * `buttons` (*array*) An array of objects that define custom buttons to be displayed in this complex structure, overriding any default buttons. Each button object contains the following properties: + `id` (*string*) **Required**: Unique identifier used to identify the button in the callback function. + `label` (*object*): Button label to display. If an icon is specified as well, the icon will be shown to the right of the label. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + `description` (*object*): Tooltip text to display when the button is hovered. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + `icon` (*string*): URL to .svg image to display. + `carbon_icon` (*string*): Host provided name of Carbon icon to display. A callback function is required for the host application to return the jsx icon object imported from @carbon/icons-react library. + `enabled` (*boolean*): Button will be enabled if true, disabled if false. @@ -295,7 +295,7 @@ Action info attributes. * `id` (*string*) **Required** Id of the action. * `label` (*object*) **Required** External name of action. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) * `control` (*string*) **Required** The type of action. Currently `button` and `image` are supported. * `class_name` (*string*) Optional classname for this action * `image` (*object*) Properties associate with an `image` action. diff --git a/docs/3.3-Common-Properties-Controls.md b/docs/3.3-Common-Properties-Controls.md index 37123d60f7..7dcdd94fe6 100644 --- a/docs/3.3-Common-Properties-Controls.md +++ b/docs/3.3-Common-Properties-Controls.md @@ -13,7 +13,7 @@ Controls are grouped and arranged on panels and sub-panels within the "group_inf * `panels` A panel type that contains sub-panels. * `panelSelector` A panel containing sub-panels that are shown or hidden based upon a controlling radio selection. * `columnSelection` A panel type containing field-selection controls that share a common set of fields. -* `customPanel` A custom panel for displaying user defined control. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-panels) for more details. +* `customPanel` A custom panel for displaying user defined control. See [3.5 Common Properties Custom Components](3.5-Common-Properties-Custom-Components.md#custom-panels) for more details. * `summaryPanel` A panel used in the flyout editor that will provide a link to open a wide flyout that can contain panels and parameter. * `actionPanel` A panel used for containing action controls. * `textPanel` A panel used to display static label and/or description. @@ -31,7 +31,7 @@ The following controls are supported in the Common Properties editor. Control ty * `passwordfield` A masked single line text field with tooltip. The tooltip text can be customized by setting `[parameter_id].passwordHide.tooltip` and `[parameter_id].passwordShow.tooltip` in resources section. * `textarea` A multi-line text area. * `list` A single column table for editing a list of values. -* `expression` An expression editing field that provides language specific syntax highlighting and text auto complete. An expression builder addon is available with the expression control. You must provide the `expressionInfo` field for the `propertiesInfo` config. See [3.0 Common Properties Documentation](/3.0-Common-Properties-documentation) for more details. To maximize in a tearsheet add this attribute and define a `tearsheetPanel` in `group_info`. +* `expression` An expression editing field that provides language specific syntax highlighting and text auto complete. An expression builder addon is available with the expression control. You must provide the `expressionInfo` field for the `propertiesInfo` config. See [3.0 Common Properties Documentation](3.0-Common-Properties-documentation.md) for more details. To maximize in a tearsheet add this attribute and define a `tearsheetPanel` in `group_info`. ``` "data": { "tearsheet_ref": "" @@ -74,7 +74,7 @@ The following controls are supported in the Common Properties editor. Control ty * `structurelisteditor` For lists or maps of complex types that are *not* field-oriented parameters. * `structureeditor` Allows one to define a structure and use it directly on a panel. Each structure member is surfaced as an individual control. Supports a `layout` setting that allows one to position structureeditor controls in a grid (see below). * `readonlyTable` A read only table. Used for tables to display fields that users shouldn't edit. -* `custom` A custom control for displaying a user defined control. See [3.5 Common Properties Custom Components](/3.5-Common-Properties-Custom-Components#custom-controls) for more details. +* `custom` A custom control for displaying a user defined control. See [3.5 Common Properties Custom Components](3.5-Common-Properties-Custom-Components.md#custom-controls) for more details. ### A Note on Field Name Storage diff --git a/docs/3.4-Common-Properties-Conditions.md b/docs/3.4-Common-Properties-Conditions.md index bccd0f01b8..2ae1cd76d3 100644 --- a/docs/3.4-Common-Properties-Conditions.md +++ b/docs/3.4-Common-Properties-Conditions.md @@ -15,7 +15,7 @@ The attributes for the validation definition are: * `id` (*string*) A unique identifier for the validation. This is required if multiple validations have the same `focus_parameter_ref` value. * `fail_message` (*object*) **Required** The message to display if the validation fails. Each fail_message consist of the following attributes + `message` (*object*) **Required** The message to display. - + See [Resource Definition](/3.2-Common-Properties--UI-Hints#resource-definition) + + See [Resource Definition](3.2-Common-Properties-UI-Hints.md#resource-definition) + `focus_parameter_ref` (*string*) **Required** The parameter control to get focus after displaying the error/warning. If the validation refers to a table cell, then control must have the column indicator. For example if the validation is for `MyTable` cell column 2 then `MyTable[2]`. + `type` (*string*) Type of messages. Valid values are `error, warning, info`. diff --git a/docs/3.5-Common-Properties-Custom-Components.md b/docs/3.5-Common-Properties-Custom-Components.md index cf2dcd29fc..0a058bfb54 100644 --- a/docs/3.5-Common-Properties-Custom-Components.md +++ b/docs/3.5-Common-Properties-Custom-Components.md @@ -44,14 +44,14 @@ renderPanel() ``` - **parameters** - String array of parameters set under the customPanel group in uihints -- **controller** - See [here](/3.6-Common-Properties-Controller) for API information. +- **controller** - See [here](3.6-Common-Properties-Controller.md) for API information. - **data** - Optional parameter. Returns values stored in `data` attribute of a group `customPanel`. - **renderPanel()** - Called on all Redux store changes: - - property value changes ([property APIs](/3.6-Common-Properties-Controller#property-methods)) - - state changes ([state APIs](/3.6-Common-Properties-Controller#state-methods-disableenabled--hiddenvisible)) - - schema changes ([schema APIs](/3.6-Common-Properties-Controller#datasetmetadata-methods)) - - row selection changes ([selection APIs](/3.6-Common-Properties-Controller#row-selection-methods)) - - messages changes ([message APIs](/3.6-Common-Properties-Controller#message-methods)) + - property value changes ([property APIs](3.6-Common-Properties-Controller.md#property-methods)) + - state changes ([state APIs](3.6-Common-Properties-Controller.md#state-methods-disableenabled--hiddenvisible)) + - schema changes ([schema APIs](3.6-Common-Properties-Controller.md#datasetmetadata-methods)) + - row selection changes ([selection APIs](3.6-Common-Properties-Controller.md#row-selection-methods)) + - messages changes ([message APIs](3.6-Common-Properties-Controller.md#message-methods)) ### Custom react components @@ -87,18 +87,18 @@ constructor(propertyId, controller, data, tableInfo) renderControl() ``` -- **propertyId** - See [propertyId](/3.6-Common-Properties-Controller#common-properties-controller-api) for definition. -- **controller** - See [here](/3.6-Common-Properties-Controller) for API information. +- **propertyId** - See [propertyId](3.6-Common-Properties-Controller.md#common-properties-controller-api) for definition. +- **controller** - See [here](3.6-Common-Properties-Controller.md) for API information. - **data** - Returns values stored in `data` attribute of a parameter in uihints. - **tableInfo** - Set when custom control is a cell in a table. - table (boolean) Set to true when in a table cell - editStyle (string) Valid values are "summary" and "inline". "summary" is set when the control will display either below the table ("on_panel") or in a "subpanel". This allows the custom control to display a summary value in the cell and something else for the custom control. - **renderControl()** - Called on all Redux store changes: - - property value changes ([property APIs](/3.6-Common-Properties-Controller#property-methods)) - - state changes ([state APIs](/3.6-Common-Properties-Controller#state-methods-disableenabled--hiddenvisible)) - - schema changes ([schema APIs](/3.6-Common-Properties-Controller#datasetmetadata-methods)) - - row selection changes ([selection APIs](/3.6-Common-Properties-Controller#row-selection-methods)) - - messages changes ([message APIs](/3.6-Common-Properties-Controller#message-methods)) + - property value changes ([property APIs](3.6-Common-Properties-Controller.md#property-methods)) + - state changes ([state APIs](3.6-Common-Properties-Controller.md#state-methods-disableenabled--hiddenvisible)) + - schema changes ([schema APIs](3.6-Common-Properties-Controller.md#datasetmetadata-methods)) + - row selection changes ([selection APIs](3.6-Common-Properties-Controller.md#row-selection-methods)) + - messages changes ([message APIs](3.6-Common-Properties-Controller.md#message-methods)) ### Custom react components @@ -143,7 +143,7 @@ function evaluate(paramInfo, param2Info, value, controller) - value (any) - current property value - param2Info (object) - `parameter_2_ref` set in the `condition` in uihints. See `paramInfo` for object info - value - `value` set in the `condition` in uihints. If no value specific this will be `undefined` -- **controller** - See [here](/3.6-Common-Properties-Controller) for API information. +- **controller** - See [here](3.6-Common-Properties-Controller.md) for API information. Example ```js diff --git a/docs/index.md b/docs/index.md index 8d5dea28c3..f1f3412656 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,9 +2,9 @@ The elyra-ai/canvas repo contains three main components: -* [Common Canvas](/2.0-Common-Canvas-Documentation/) - This contains canvas functionality which is packaged into the [elyra/canvas NPM module](https://www.npmjs.com/package/@elyra/canvas) and deployed on the NPM registry. It provides a way for an application to display a flow of data operations (shown as a set of nodes connected with links) defined in a pipeline flow JSON document, to the user and to allows the user to interact with the display to modify the flow. Common canvas is a react component which can be imported, and is assisted by a regular JavaScript class called `CanvasController` which provides an API and handles the internal data model of the flow. Common canvas is highly customizable where node shape and appearance, colors, styles layout etc can all be customized by your application code. +* [Common Canvas](2.0-Common-Canvas-Documentation.md) - This contains canvas functionality which is packaged into the [elyra/canvas NPM module](https://www.npmjs.com/package/@elyra/canvas) and deployed on the NPM registry. It provides a way for an application to display a flow of data operations (shown as a set of nodes connected with links) defined in a pipeline flow JSON document, to the user and to allows the user to interact with the display to modify the flow. Common canvas is a react component which can be imported, and is assisted by a regular JavaScript class called `CanvasController` which provides an API and handles the internal data model of the flow. Common canvas is highly customizable where node shape and appearance, colors, styles layout etc can all be customized by your application code. -* [Common Properties](/3.0-Common-Properties-documentation/) - This contains properties functionality which is packaged into the [elyra/canvas NPM module](https://www.npmjs.com/package/@elyra/canvas) and deployed on the NPM registry. It provides a way to translate a JSON document, which describes a set of properties with UI hints, into working properties dialog panel. Common properties is a react component and has an associated properties controller object. +* [Common Properties](3.0-Common-Properties-documentation.md) - This contains properties functionality which is packaged into the [elyra/canvas NPM module](https://www.npmjs.com/package/@elyra/canvas) and deployed on the NPM registry. It provides a way to translate a JSON document, which describes a set of properties with UI hints, into working properties dialog panel. Common properties is a react component and has an associated properties controller object. * [Test Harness](https://github.com/elyra-ai/canvas/tree/master/canvas_modules/harness#test-harness) - This provides a node.js app which displays a UI which allows you to try out various features of the common canvas and common properties components. Bear in mind this is not supposed to be a fully functional app but is, as the name suggests, a framework for testing. To get select one of the sample applications or select `None` as the sample app and then select a test canvas file from the `Canvas Diagram` drop down list and a test palette from the `Canvas palette` drop down list. @@ -74,7 +74,7 @@ render() { ## Notes When building your application you will need to load fonts and override styles can be found here: -[Styling](./4.0-Styling) +[Styling](4.0-Styling.md) ## Testing When testing your application with Jest, this error might show up: `crypto.getRandomValues() not supported`. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported for details. diff --git a/mkdocs.yml b/mkdocs.yml index 9111406427..9c0ad9029c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,5 +1,5 @@ site_name: Elyra Canvas Documentation -repo_url: https://github.com/elyra-ai/canvas +repo_url: https://github.com/srikant-ch5/canvas docs_dir: docs theme: From 5d54fad8145c867ae6fc18f2846fb21592c0b9cb Mon Sep 17 00:00:00 2001 From: srikant Date: Mon, 26 Feb 2024 22:00:43 +0530 Subject: [PATCH 14/20] Fix Resource def links in docs link navigation Signed-off-by: srikant --- docs/3.2-Common-Properties-UI-Hints.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/3.2-Common-Properties-UI-Hints.md b/docs/3.2-Common-Properties-UI-Hints.md index ea8b03d7ea..fe87d93f95 100644 --- a/docs/3.2-Common-Properties-UI-Hints.md +++ b/docs/3.2-Common-Properties-UI-Hints.md @@ -8,9 +8,9 @@ The UI Hints section consists a set of simple and complex attributes. * `id` (*string*) Dialog id. * `label` (*object*) External name of dialog. - + See [Resource Definition](3.2-Common-Properties--UI-Hint.md#resource-definition) + + See [Resource Definition](#resource-definition) * `description` (*object*) Description of dialog. - + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + + See [Resource Definition](#resource-definition) * `editor_size` (*string*) The width of the properties editor panel. This can have a value of `"small"`, `"medium"`, `"large"` or `"max"`. The default is `"small"`. - When `"small"` is specified the properties panel is displayed with a default width of 320px and with a resize button that allows the panel to be increased in size up to the `"medium"` size which is 480px. - When `"medium"` is specified the properties panel has a width of 480px and with a resize button that allows the panel to be increased in size up to the `"large"` size which is 640px. @@ -52,9 +52,9 @@ Group info attributes. * `type` (*string*) The group type to be displayed. see Group/Panel Controls in [3.3 Common Properties Controls](3.3-Common-Properties-Controls.md). * `depends_on_ref` (*string*) Property name this group depends upon. Valid for panelSelector groups only. * `label` (*object*) Group label. - + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + + See [Resource Definition](#resource-definition) * `description` (*object*) Group description. Only used with `textPanel` and `actionPanel`. - + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + + See [Resource Definition](#resource-definition) + See [Dynamic Text Expressions](3.2-Common-Properties--UI-Hints.md#dynamic-text-expressions) + `link` (object) Optional link in the description. [tooltipLinkHandler callback](3.0-Common-Properties-documentation.md#tooltiplinkhandler) must be defined whenever link object is added in uiHints.. + `id` (string) Required unique link id. @@ -113,10 +113,10 @@ Parameter info attributes. * `parameter_ref` (*string*) **Required** Parameter name. * `label` (*object*) External name for parameter. - + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + + See [Resource Definition](#resource-definition) * `label_visible` (*boolean*) Determines whether to display the label for a control. * `description` (*object*) Description of parameter with optional placement context. - + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + + See [Resource Definition](#resource-definition) + `placement` (*string*) Placement context for the text. Valid values are `as_tooltip, on_panel`. + `link` (*object*) Optional link in the description. [tooltipLinkHandler callback](3.0-Common-Properties-documentation.md#tooltiplinkhandler) must be defined whenever link object is added in uiHints.. + `id` (*string*) Required unique link id. From 9f64d5a8a5f7dbb52a760d30475a18d8471afb30 Mon Sep 17 00:00:00 2001 From: srikant Date: Tue, 27 Feb 2024 16:16:12 +0530 Subject: [PATCH 15/20] Add slider info in Common Properties docs Signed-off-by: srikant --- docs/3.3-Common-Properties-Controls.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/3.3-Common-Properties-Controls.md b/docs/3.3-Common-Properties-Controls.md index 7dcdd94fe6..40c71fe33b 100644 --- a/docs/3.3-Common-Properties-Controls.md +++ b/docs/3.3-Common-Properties-Controls.md @@ -75,6 +75,7 @@ The following controls are supported in the Common Properties editor. Control ty * `structureeditor` Allows one to define a structure and use it directly on a panel. Each structure member is surfaced as an individual control. Supports a `layout` setting that allows one to position structureeditor controls in a grid (see below). * `readonlyTable` A read only table. Used for tables to display fields that users shouldn't edit. * `custom` A custom control for displaying a user defined control. See [3.5 Common Properties Custom Components](3.5-Common-Properties-Custom-Components.md#custom-controls) for more details. +* `slider` A standard slider which allows to enter a numeric value within the slider range and also allows to drag and adjust the slider track to a specific value within the range. The slider labels for minimum and maximum values can be customized by setting them as `[parameter_id].min.label` for minimum value label and `[parameter_id].max.label` for maximum value label in resources section. ### A Note on Field Name Storage From a0ed3975cfd6e0f8fbc7b3f6580dd24a8bf8e2db Mon Sep 17 00:00:00 2001 From: srikant Date: Wed, 28 Feb 2024 13:00:48 +0530 Subject: [PATCH 16/20] Fix link redirection in 2.4.6, 3.1 and 3.2 docs Signed-off-by: srikant --- ...nstructing-a-read-only-or-locked-canvas.md | 2 +- ...-Common-Properties-Parameter-Definition.md | 4 ++-- docs/3.2-Common-Properties-UI-Hints.md | 20 +++++++++---------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/2.4.6-Constructing-a-read-only-or-locked-canvas.md b/docs/2.4.6-Constructing-a-read-only-or-locked-canvas.md index 3fced7b7ca..01ddae449f 100644 --- a/docs/2.4.6-Constructing-a-read-only-or-locked-canvas.md +++ b/docs/2.4.6-Constructing-a-read-only-or-locked-canvas.md @@ -5,7 +5,7 @@ Some host applications need to display flows that cannot be edited by the user. There are many aspects of common-canvas components that need to considered for a read-only canvas. Since common-canvas is highly customizable it is not possible for the common-canvas code to manage components of the canvas that have been customized by the host application. For example, if the host app code added tools to the toolbar, common-canvas does not know whether those tools should be disabled when displaying a read-only canvas or not. So the host application code will need to manage that. Let's look at each element of common-canvas and see what needs to be done. # General Config -There is one main canvas configuration property that will change the common-canvas behavior to implement a read-only canvas. This is [`enableEditingActions`](2.1-Config-Objects#enableeditingactions) which defaults to true and needs to be set to `false` for read-only canvases. The sections below will cover what effect this will have on the different components of common-canvas and what you need to do for any customizations you have made. +There is one main canvas configuration property that will change the common-canvas behavior to implement a read-only canvas. This is [`enableEditingActions`](2.1-Config-Objects.md#enableeditingactions) which defaults to true and needs to be set to `false` for read-only canvases. The sections below will cover what effect this will have on the different components of common-canvas and what you need to do for any customizations you have made. # Canvas Setting `enableEditingActions` to false will prevent nodes and comments (and detachable links) from being moved relative to one another. It will also prevent new links from being created and prevent text (like comments or node labels) from being edited. diff --git a/docs/3.1-Common-Properties-Parameter-Definition.md b/docs/3.1-Common-Properties-Parameter-Definition.md index 7119805924..68b37959f6 100644 --- a/docs/3.1-Common-Properties-Parameter-Definition.md +++ b/docs/3.1-Common-Properties-Parameter-Definition.md @@ -110,7 +110,7 @@ Example } ``` -UI-only parameters require information about the parameters same as the parameter definition information used for the backend parameters. The UI-only parameter definition information is stored in the UI-hints section in the sub-section named `ui_parameters`. A description of the UI hints specifications can be found here: [3.2 Common Properties UI Hints](3.2-Common-Properties--UI-Hints.md) +UI-only parameters require information about the parameters same as the parameter definition information used for the backend parameters. The UI-only parameter definition information is stored in the UI-hints section in the sub-section named `ui_parameters`. A description of the UI hints specifications can be found here: [3.2 Common Properties UI Hints](3.2-Common-Properties-UI-Hints.md) UI-only properties are returned to the consuming application via a separate parameter on the applyPropertiesChanges callback. See the `Callbacks` section of [3.1 Common Properties Documentation section.](3.0-Common-Properties-documentation.md) @@ -157,7 +157,7 @@ Note that both parameter and complex type definitions are in the exact same form ## UI Hints -A set of specifications for controlling the layout and flow of the common properties. A description of the UI hints specifications can be found here: [3.2 Common Properties UI Hints](3.2-Common-Properties--UI-Hints.md) +A set of specifications for controlling the layout and flow of the common properties. A description of the UI hints specifications can be found here: [3.2 Common Properties UI Hints](3.2-Common-Properties-UI-Hints.md) ## Conditions A set of specifications for controlling validation checking of parameters during the common properties dialog. A description of the Conditions specifications can be found here: diff --git a/docs/3.2-Common-Properties-UI-Hints.md b/docs/3.2-Common-Properties-UI-Hints.md index fe87d93f95..43fe078112 100644 --- a/docs/3.2-Common-Properties-UI-Hints.md +++ b/docs/3.2-Common-Properties-UI-Hints.md @@ -55,7 +55,7 @@ Group info attributes. + See [Resource Definition](#resource-definition) * `description` (*object*) Group description. Only used with `textPanel` and `actionPanel`. + See [Resource Definition](#resource-definition) - + See [Dynamic Text Expressions](3.2-Common-Properties--UI-Hints.md#dynamic-text-expressions) + + See [Dynamic Text Expressions](3.2-Common-Properties-UI-Hints.md#dynamic-text-expressions) + `link` (object) Optional link in the description. [tooltipLinkHandler callback](3.0-Common-Properties-documentation.md#tooltiplinkhandler) must be defined whenever link object is added in uiHints.. + `id` (string) Required unique link id. + `data` (object) Data passed to the tooltipLinkHandler callback. @@ -130,7 +130,7 @@ Parameter info attributes. * `separator` (*string*) Determines where to put a separator relative to the current control. Valid values are ` after, before`. * `visible` (*boolean*) Determines whether to display control in a table cell. Used in complex types only. * `place_holder_text` (*object*) Text hint for the user displayed input controls. - + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + + See [Resource Definition](3.2-Common-Properties-UI-Hints.md#resource-definition) * `resource_key` (*string*) Used as a key for enum value labels in the resources section of property definition. * `edit_style` (*string*) Editing style of elements in a table. Valid values are `subpanel, inline, on_panel`. * `value_icons` (*array[string]*) For enumerated types, this defines the set of icons for the valid values. The ordering must be consistent with the order in the parameter enum attribute. @@ -141,13 +141,13 @@ Parameter info attributes. * `dm_image` (*string*) This can be set to display an icon of the corresponding dm type in the `role`:`column` field of a table. Valid values are `measure`, `type`, `none` * `summary` (*boolean*) Determines if parameter should be shown in the summary when using a `summaryPanel`. * `text_before` (*object*) Text to be displayed before the control - + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + + See [Resource Definition](3.2-Common-Properties-UI-Hints.md#resource-definition) + `type` (*string*) Adds a icon and additional formatting to the text. Only `info` is support at this time. - + See [Dynamic Text Expressions](3.2-Common-Properties--UI-Hints.md#dynamic-text-expressions) + + See [Dynamic Text Expressions](3.2-Common-Properties-UI-Hints.md#dynamic-text-expressions) * `text_after` (*object*) Text to be displayed after the control - + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + + See [Resource Definition](3.2-Common-Properties-UI-Hints.md#resource-definition) + `type` (*string*) Adds a icon and additional formatting to the text. Only `info` is support at this time. - + See [Dynamic Text Expressions](3.2-Common-Properties--UI-Hints.md#dynamic-text-expressions) + + See [Dynamic Text Expressions](3.2-Common-Properties-UI-Hints.md#dynamic-text-expressions) * `custom_control_id` (*string*) Id that is used to determine which custom control to use when `control=custom` * `data` (*any*) Returned in custom control constructor without any changes. * `rows` (*integer*) Number of rows to show in a table before scrolling starts. If one table in a panel is set to -1, that table will use the remaining available vertical space, down to a minimum of 2 rows. Used in expression and code controls to determine the number of rows to show for those controls. @@ -184,7 +184,7 @@ Complex Type info attributes. * `complex_type_ref` (*string*) **Required** Name of complex type, can be referenced in other places. * `key_definition` (*string*) A set of parameter info attributes about the key parameter. * `label` (*object*) External name of subpanel. - + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + + See [Resource Definition](3.2-Common-Properties-UI-Hints.md#resource-definition) * `parameters` (*object*) **Required** List of parameters that are part of this complex parameter. This parameter can either have a set of parameter_info attributes or other nested complex_type_info attributes. * `header` (*boolean*) If `true` then the table has a header row with column names. Defaults to `true`. * `add_remove_rows` (*boolean*) If `true` then the table can have rows added and removed. Defaults to `true`. @@ -196,9 +196,9 @@ Complex Type info attributes. * `buttons` (*array*) An array of objects that define custom buttons to be displayed in this complex structure, overriding any default buttons. Each button object contains the following properties: + `id` (*string*) **Required**: Unique identifier used to identify the button in the callback function. + `label` (*object*): Button label to display. If an icon is specified as well, the icon will be shown to the right of the label. - + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + + See [Resource Definition](3.2-Common-Properties-UI-Hints.md#resource-definition) + `description` (*object*): Tooltip text to display when the button is hovered. - + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + + See [Resource Definition](3.2-Common-Properties-UI-Hints.md#resource-definition) + `icon` (*string*): URL to .svg image to display. + `carbon_icon` (*string*): Host provided name of Carbon icon to display. A callback function is required for the host application to return the jsx icon object imported from @carbon/icons-react library. + `enabled` (*boolean*): Button will be enabled if true, disabled if false. @@ -295,7 +295,7 @@ Action info attributes. * `id` (*string*) **Required** Id of the action. * `label` (*object*) **Required** External name of action. - + See [Resource Definition](3.2-Common-Properties--UI-Hints.md#resource-definition) + + See [Resource Definition](3.2-Common-Properties-UI-Hints.md#resource-definition) * `control` (*string*) **Required** The type of action. Currently `button` and `image` are supported. * `class_name` (*string*) Optional classname for this action * `image` (*object*) Properties associate with an `image` action. From 8da981afcd20850196a9db5605ba24b122a1afbd Mon Sep 17 00:00:00 2001 From: srikant Date: Thu, 29 Feb 2024 19:02:51 +0530 Subject: [PATCH 17/20] Add Copyrights in docs file and revert links in js files to point to old docs Signed-off-by: srikant --- .../src/object-model/layout-dimensions.js | 4 ++-- .../common-properties-components.jsx | 6 +++--- .../sidepanel/api/sidepanel-api.jsx | 2 +- docs/css/styles.css | 16 +++++++++++++++ docs/images/DELETEME | 1 - docs/js/links-in-new-tabs.js | 20 +++++++++++++++++-- 6 files changed, 40 insertions(+), 9 deletions(-) delete mode 100644 docs/images/DELETEME diff --git a/canvas_modules/common-canvas/src/object-model/layout-dimensions.js b/canvas_modules/common-canvas/src/object-model/layout-dimensions.js index 73d4e37600..553198037f 100644 --- a/canvas_modules/common-canvas/src/object-model/layout-dimensions.js +++ b/canvas_modules/common-canvas/src/object-model/layout-dimensions.js @@ -73,7 +73,7 @@ const portsHorizontalDefaultLayout = { labelAllowReturnKey: false, // true allows line feed to be inserted into label, "save" to make the return key save the label. // An array of decorations to be applied to the node. For details see: - // https://github.com/elyra-ai/canvas/tree/main/guide/2.4.2-Decoration-Specification.md + // https://github.com/elyra-ai/canvas/wiki/2.4.2-Decoration-Specification // These are added to the node at run time and will not be saved into // the pipeline flow. decorations: [], @@ -488,7 +488,7 @@ const portsVerticalDefaultLayout = { labelAllowReturnKey: false, // true allows line feed to be inserted into label, "save" to make the return key save the label. // An array of decorations to be applied to the node. For details see: - // https://github.com/elyra-ai/canvas/tree/main/guide/2.4.2-Decoration-Specification.md + // https://github.com/elyra-ai/canvas/wiki/2.4.2-Decoration-Specification // These are added to the node at run time and will not be saved into // the pipeline flow. decorations: [], diff --git a/canvas_modules/harness/src/client/components/common-properties-components.jsx b/canvas_modules/harness/src/client/components/common-properties-components.jsx index be1982e023..4327663759 100644 --- a/canvas_modules/harness/src/client/components/common-properties-components.jsx +++ b/canvas_modules/harness/src/client/components/common-properties-components.jsx @@ -525,7 +525,7 @@ class CommonPropertiesComponents extends React.Component { to Custom and rightFlyout set to true. Below is the minimum specifications to render CommonProperties. More options and details are listed in the  Common Properties wiki . @@ -548,7 +548,7 @@ class CommonPropertiesComponents extends React.Component {

For more information with using CommonCanvas right-flyout for the properties editor, refer to the documentation in the  Common Properties wiki @@ -2123,7 +2123,7 @@ class CommonPropertiesComponents extends React.Component { to More than ten fields... This placeholder text can be configured through   custom labels.

diff --git a/canvas_modules/harness/src/client/components/sidepanel/api/sidepanel-api.jsx b/canvas_modules/harness/src/client/components/sidepanel/api/sidepanel-api.jsx index 033c3fe939..895a188b5a 100644 --- a/canvas_modules/harness/src/client/components/sidepanel/api/sidepanel-api.jsx +++ b/canvas_modules/harness/src/client/components/sidepanel/api/sidepanel-api.jsx @@ -476,7 +476,7 @@ export default class SidePanelAPI extends React.Component { if (this.state.appendLink) { messageLink = (); } diff --git a/docs/css/styles.css b/docs/css/styles.css index 675155171d..837e31c9c6 100644 --- a/docs/css/styles.css +++ b/docs/css/styles.css @@ -1,3 +1,19 @@ +/* + * Copyright 2017-2023 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. + */ + th { font-weight: bold; } diff --git a/docs/images/DELETEME b/docs/images/DELETEME deleted file mode 100644 index 0fa15e4e80..0000000000 --- a/docs/images/DELETEME +++ /dev/null @@ -1 +0,0 @@ -Images for the guide go here. \ No newline at end of file diff --git a/docs/js/links-in-new-tabs.js b/docs/js/links-in-new-tabs.js index f269f65134..c3cd713bd0 100644 --- a/docs/js/links-in-new-tabs.js +++ b/docs/js/links-in-new-tabs.js @@ -1,9 +1,25 @@ +/* + * Copyright 2017-2023 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. + */ + // This takes any external links and adds _blank to make sure they open in a new tab. Links to other // pages within the documentation will remain in the same tab // Source: https://stackoverflow.com/questions/4425198/can-i-create-links-with-target-blank-in-markdown#answer-4425214 -var links = document.links; -for (var i = 0, linksLength = links.length; i < linksLength; i++) { +const links = document.links; +for (let i = 0, linksLength = links.length; i < linksLength; i++) { if (links[i].hostname != window.location.hostname) { links[i].target = '_blank'; } From 547fd65ba9d9ac4f8af6fa10b9f6288b0632b2b5 Mon Sep 17 00:00:00 2001 From: srikant Date: Fri, 1 Mar 2024 11:02:53 +0530 Subject: [PATCH 18/20] Check deployment action Signed-off-by: srikant --- docs/2.4.4-Notification-Message-Specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/2.4.4-Notification-Message-Specification.md b/docs/2.4.4-Notification-Message-Specification.md index b7e1b9ccb7..78be3e0b4b 100644 --- a/docs/2.4.4-Notification-Message-Specification.md +++ b/docs/2.4.4-Notification-Message-Specification.md @@ -18,7 +18,7 @@ where: * **type** (string, required): this must be one of four values: "info", "success", "warning", or "error". If `type` is null, empty string, or undefined, the message type will be "unspecified". -* **title** (string or JSX object): the title of the notification message +* **title** (string or JSX object): the title of the notification message. * **content** (string or JSX object): the body of the notification message From 41dbda1617b109d272aeb1d9c192892ccb1503a4 Mon Sep 17 00:00:00 2001 From: srikant Date: Fri, 1 Mar 2024 15:28:27 +0530 Subject: [PATCH 19/20] Check deployment by removing git credentials from ci.yml Signed-off-by: srikant --- .github/workflows/ci.yml | 4 ---- docs/2.4.4-Notification-Message-Specification.md | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 56064889fd..ab276dc9c9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,10 +10,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Configure Git Credentials - run: | - git config user.name github-actions[bot] - git config user.email 41898282+github-actions[bot]@users.noreply.github.com - uses: actions/setup-python@v5 with: python-version: 3.x diff --git a/docs/2.4.4-Notification-Message-Specification.md b/docs/2.4.4-Notification-Message-Specification.md index 78be3e0b4b..5672d76722 100644 --- a/docs/2.4.4-Notification-Message-Specification.md +++ b/docs/2.4.4-Notification-Message-Specification.md @@ -20,7 +20,7 @@ where: * **title** (string or JSX object): the title of the notification message. -* **content** (string or JSX object): the body of the notification message +* **content** (string or JSX object): the body of the notification message. * **callback** (function): an optional callback function that will be called when the notification message is clicked. Callback function is called with one parameter, `id` From 0e589b2986ad50e833073fdc2d1075bb58499bc7 Mon Sep 17 00:00:00 2001 From: srikant Date: Fri, 1 Mar 2024 19:25:51 +0530 Subject: [PATCH 20/20] Update branch name in ci.yml Signed-off-by: srikant --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ab276dc9c9..6035aad67a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: ci on: push: branches: - - new-guide + - main permissions: contents: write jobs: