react-conversation-flow-designer v0.1.6
React Conversation Flow Designer (CFD)
The react conversation flow designer is designed and developed for the purpose of constructing a multi-level state conversation for use with bots or Interactive Voice Response (IVR) systems.
Installation
Using npm:
npm install --save react-conversation-flow-designer
Usage
Step 1 - Import the Component
With ES6 modules, import the Component and use it in your App.js.
import React, { useState } from 'react';
import Designer from 'react-conversation-flow-designer';
export default (props) => {
  return (
    <Designer />
  );
}Step 2 - Setup the Configuration
You will now need to setup the configuration to allow of the customized flow designer.
The default designer does not come with any nodes other thatn start or end.
For a start, please use the Sample Configuration in the section below as a starting point and edit according to the needs of your projects.
The Sample Configuration will provide you with:
- 1 button in the Flow Management Panel (key = new)
- 2 custom node templates in the Node Picker Panel (talkandinput)
Please read up the following sections for documentations on the flow management template and node templates.
Step 3 - Providing the Configuration to the Designer
You will need to pass the config that you have created earlier to the Designer component.
Your Designer component should now look similar to this:
import React, { useState } from 'react';
import Designer from 'react-conversation-flow-designer';
import config from './config.json';
export default (props) => {
  return (
    <Designer 
      config={config} />
  );
}Step 4 - Providing the Flow to the Designer
The CFD works by performing manipulation to a flow. State of the flow will be managed by you, the developer instead of the Designer Component.
In the Designer Component, the flow property will take in the up-to-date flow object, while the onFlowChange property will take in a callback function with the updated flow as the first parameter of the callback.
Using the useState hook in React Hooks to create a state for the flow object.
Initialize the flow to null will setup the Designer to use the empty flow that contains only:
- 1 Start Node
- 1 End Node
Your code should look similar to the following:
import React, { useState } from 'react';
import Designer from 'react-conversation-flow-designer';
import config from './config.json';
// Set a State for the current flow
const [flow, setFlow] = useState(null);
export default (props) => {
  return (
    <Designer
      config={config}
      flow={flow}
      onFlowChange={(updatedFlow) => setFlow(updatedFlow)} />
  );
}Step 5 - Providing Handler for Flow Management Callbacks
Flow Management works by providing callbacks with identifier key configured in the configuration.
In the Designer Component, the onFlowManagementClick property will take in a callback function with the identifier key as the first parameter of the callback.
In this example, we will set the flow to a new flow by setting it to null.
Your code should look similar to the following:
import React, { useState } from 'react';
import Designer from 'react-conversation-flow-designer';
import config from './config.json';
// Set a State for the current flow
const [flow, setFlow] = useState(null);
// Conditional check for key, and handle appropriately
const handleClick = (key) => {
  if (key === 'new') {
    setFlow(null);
  }
}
export default (props) => {
  return (
    <Designer
      config={config}
      flow={flow}
      onFlowChange={(updatedFlow) => setFlow(updatedFlow)}
      onFlowManagementClick={(key) => handleClick(key)} />
  );
}Step 6 - Running your Application
Now that we have setup the Designer, we can start running the react application using your start script. Voila, now we have a working Conversation Flow Designer application.
Configuration: Flow Management Template
The Flow Management Panel comes with 2 types of view which you can use to customize the panel:
- Button
- Vertical Spacing
To setup a Button in the Flow Management Panel, add the following to the flowManagement array of your Configuration.
{
  "type": "button",
  "key": "new",
  "text": "New",
  "bootstrapVariant": "primary"
}To setup of Vertical Spacing in the Flow Management Panel, add the following to the flowManagement array of your Configuration.
{
  "type": "verticalSpacing"
}Explanation
- type: Type of View (- buttonor- verticalSpacing)
- key: Identifier Key which will be used on the onClick callbacks. Only for- button
- text: Display Text on the view. Only for- button
- bootstrapVariant: Variant of Bootstrap Color to be used with the view (- primary,- secondary,- success,- warning,- danger,- info,- light,- dark). Only for- button
For More Bootstrap Variants, please refer to: https://react-bootstrap.github.io/components/buttons/
Configuration: Node Template
In the CFD, a custom node can be made by adding the following to the nodes object in your Configuration with the object key as the custom type of node you prefer.
"talk": {
  "type": "talk",
  "displayText": "Talk",
  "displayIcon": null,
  "color: "#c6c6c6",
  "portsCount": {
    "in": 1,
    "out: 1,
  },
  "content": {
    "initial": {},
    "views": []
  }
}This creates a node template of type talk (note that the key of the template and the type of the template have to be the same value).
Explanation
- type: Type of Node Template (used for internal display rendering as well as for reference when using the exported flow in your application)
- displayText: Display Text to be shown on the node's body in the Node Picker as well as the Canvas
- displayIcon: URL to an Image used for the node's icon, placed on the left of the Display Text. Use- nullif no icon is needed
- color: Hex color of the body of the node
- portsCount: Defines the number of ports going in (left) and out (right) of the node. As refernce, use 1 in-port and 1 out-port unless you are creating a Conditional node
- content: Defines the- initialdata value when creating a new node, as well as the customizable data values and views on the Editing Modal.
Node Template View Types
In the current version of the CFD, there are 4 types of views that can be supported:
- textbox
- checkbox
- dropdown
- condition
Node Template Initial Value
The following is an example of an initial value for a node with:
- 1 textbox (key = text)
- 1 checkbox (key = repeat)
- 1 dropdown (key = language)
{
  "text": "This is a sample text",
  "repeat": false,
  "language": "english"
}The following is an example of an initial view for a not with:
- 1 condition (key = inputText)
For a node with condition view, the initial value would be an array.
{
  "inputText": [
    {
      "id": "condition_1",
      "type: "if",
      "value": "condition_1"
    },
    {
      "id": "condition_2",
      "type": "else",
      "value": "condition_2"
    }
  ]
}This is the starting value with 2 items setup for the condition, and should use a 1-in, 2-out portCounts configuration.
The output port will be used in the order of the array, mapping first item to first (top) port, second item to second port and so on.
Node Template View
Each type of views will have a different view content, so as to enable a different rendering on the CFD Editing Modal for the node.
The key in each view, maps to the key of the node's data.
For example, a dropdown with a language key would set the value of the dropdown to data.language.
Textbox
A textbox contains a label and an editable textbox.
{
  "type": "textbox",
  "key": "text",
  "label": "Text"
}Checkbox
A checkbox contains a label and an checkable checkbox.
{
  "type": "checkbox",
  "key": "repeat",
  "label": "Repeat One More"
}Dropdown
A dropdown contains a label and an array of selectable items.
{
  "type": "dropdown",
  "key": "language",
  "label": "Language",
  "items": [
    { "text": "English", "value": "english" },
    { "text": "Chinese", "value": "chinese" }
  ]
}Condition
A condition view is a dynamically editable list of conditions.
{
  "type": "condition",
  "key": "options",
  "label": "Conditions",
  "defaultType": "if",
  "defaultValue": null,
  "items": [
    { "typeText": "If", "typeValue": "if", "hasContentValue": true },
    { "typeText": "Else", "typeValue": "else", "hasContentValue": false }
  ]
}Explanation
- defaultType- Default condition dropdown item value to use when a new condition is added
- defaultValue- Default condition textbox value to use when a new condition is added
- typeText- Display Text to be used in the condition dropdown item
- typeValue- type value of the condition dropdown item value
- hasContentValue- Defines whether the condition textbox should be enabled or disabled
Configuration: Sample
{
  "flowManagement": [
    {
      "type": "button",
      "key": "new",
      "text": "New",
      "bootstrapVariant": "primary"
    }
  ],
  "nodes": {
    "talk": {
      "type": "talk",
      "displayText": "Talk",
      "displayIcon": null,
      "color": "#ffb477",
      "portsCount": {
        "in": 1,
        "out": 1
      },
      "content": {
        "initial": {
          "text": "This is a sample text",
          "repeat": true,
          "language": "english"
        },
        "views": [
          {
            "type": "textbox",
            "key": "text",
            "label": "Text"
          },
          {
            "type": "checkbox",
            "key": "repeat",
            "label": "Enable repeat"
          },
          {
            "type": "dropdown",
            "key": "language",
            "label": "Language",
            "items": [
              { "text": "English", "value": "english" },
              { "text": "Chinese", "value": "chinese" }
            ]
          }
        ]
      }
    },
    "input": {
      "type": "input",
      "displayText": "Input",
      "displayIcon": null,
      "color": "#d8b2ff",
      "portsCount": {
        "in": 1,
        "out": 3
      },
      "content": {
        "initial": {
          "options": [
            {
              "id": "condition1",
              "type": "if",
              "value": "condition_1"
            },
            {
              "id": "condition2",
              "type": "if",
              "value": "condition_2"
            },
            {
              "id": "condition3",
              "type": "else"
            }
          ]
        },
        "views": [
          {
            "type": "condition",
            "key": "options",
            "label": "Conditions",
            "defaultType": "if",
            "defaultValue": null,
            "items": [
              { "typeText": "If", "typeValue": "if", "hasContentValue": true },
              { "typeText": "Else", "typeValue": "else", "hasContentValue": false }
            ]
          }
        ]
      }
    }
  }  
}