shadcn-next-workflows

repository·main·Indexed 43 days ago

https://github.com/nobruf/shadcn-next-workflows

A sample project demonstrating how to build and visualize interactive workflows using React Flow, Next.js, and Shadcn UI. Version 0.1.0 features built-in flow validation, a modular component structure, and predefined node types including Start, Menu, Text Message, Tags, and End.

Tokens
6.5K
Snippets
25
Records
31
Agent score
54%

What's inside shadcn-next-workflows

  1. Build and validate workflows

    main

    The project provides a canvas for building interactive workflows using predefined nodes.

    Workflow Creation Steps:

    1. Add Nodes: Place nodes such as Start, Menu, Text Message, Tags, or End onto the canvas.
    2. Connect Nodes: Use drag-and-drop interactions to create connections between nodes.
    3. Validation: The system includes built-in flow validation. You must ensure all nodes are properly connected; the system will prevent incomplete workflows from being finished.
  2. Install and run shadcn-next-workflows locally

    main

    To run the workflow example on your local machine, ensure you have Node.js (v14.x or higher) and npm (v6.x or higher) installed. Follow these steps to clone, install, and start the development server:

    1. Clone the repository.
    2. Install the project dependencies.
    3. Start the development server.

    Once running, access the application at http://localhost:3000.

    git clone https://github.com/nobruf/shadcn-next-workflows.git
    npm install
    npm run dev
  3. Available workflow nodes

    main

    The project includes several predefined node types for building workflows:

    • Start: The entry point of the workflow.
    • Menu: A node used for selecting options.
    • Text Message: A node that displays a text message.
    • Tags: A node used to assign specific tags.
    • End: The final endpoint of the workflow.
  4. Configure StartNodeData

    main

    When creating or updating a StartNode, you can provide a StartNodeData object. This object extends BaseNodeData and allows for custom labeling.

    Properties:

    • label (optional): A string to override the default node title. If not provided, the node defaults to the title defined in its metadata ("Start").
    • deletable (inherited from BaseNodeData): Controls whether the node can be removed from the canvas. Defaults to false for Start nodes.
    import { type StartNodeData } from "./path-to/start.node";
    
    const myStartNodeData: StartNodeData = {
      label: "User Input Trigger",
      deletable: false
    };
  5. Define data for a MenuNode

    main

    When creating or managing a MenuNode in the workflow builder, the node's data must conform to the MenuNodeData interface. This interface defines the question presented to the user and the list of selectable options.

    • question: A string or null representing the text shown to the user.
    • options: An array of objects where each object contains:
      • id: A unique string identifier for the option entry.
      • option: An object containing:
        • id: A number identifier for the specific option.
        • value: The string text of the option.
    export interface MenuNodeData extends BaseNodeData {
      question: string | null;
      options: { id: string; option: { id: number; value: string } }[];
    }
  6. Get a list of nodes for the UI selection menu

    main

    The AVAILABLE_NODES array provides a simplified, UI-ready list of nodes. It automatically filters out any nodes where available is explicitly set to false. Each entry in this array is stripped down to only the essential properties needed for a selection menu: type, icon, title, description, and gradientColor.

    import { AVAILABLE_NODES } from "./components/blocks";
    
    // Use this to populate a sidebar or a node picker component
    AVAILABLE_NODES.map(node => (
      <div key={node.type}>
        <Icon name={node.icon} />
        <span>{node.title}</span>
      </div>
    ));
  7. Use NODES_METADATA for detailed node information

    main

    The NODES_METADATA object provides an enhanced version of the node registry. It maps BuilderNodeType keys to metadata objects that include a __details field. This field merges the node's type and its detail properties into a single object, making it easier to access all descriptive properties at once.

    import { NODES_METADATA } from "./components/blocks";
    
    const details = NODES_METADATA["text-message"];
    console.log(details.__details.title);
  8. Use the Check component for conditional workflow rendering

    main

    The Check component allows you to implement conditional logic within your workflow UI. It evaluates a set of Check.When components and renders the first one whose condition is met. If no conditions are met, it renders the Check.Else component if provided.

    Behavior Rules:

    • Priority: If multiple Check.When conditions are true, only the first one encountered in the children array will be rendered.
    • Fallback: If no Check.When condition evaluates to true, the Check.Else component is rendered.
    • Default: If no conditions match and no Check.Else is provided, nothing is rendered.
    <Check>
      <Check.When condition={true}>
        <div>When condition is true</div>
      </Check.When>
    
      <Check.When condition={false}>
        <div>When condition is false</div>
      </Check.When>
    
      <Check.Else>
        <div>Else case</div>
      </Check.Else>
    </Check>
  9. Use the Switch component for conditional rendering

    main

    The Switch component allows for declarative conditional rendering based on a match value. It iterates through its children to find the first <Switch.Case> whose value matches the provided match prop. If no match is found, it renders the content within <Switch.Default>.

    Key features:

    • Single or Multiple Values: A <Switch.Case> can accept a single value or an array of values to match against.
    • First Match Wins: The component returns the first matched case it encounters.
    • Fallback: Use <Switch.Default> to provide a fallback UI when no cases match.
    <Switch match={match}>
      <Switch.Case value="one">
        <div>case one</div>
      </Switch.Case>
      <Switch.Case value={["two", "three"]}>
         <div>case two or three</div>
      </Switch.Case>
      <Switch.Default>
         <div>default case</div>
      </Switch.Default>
    </Switch>
  10. Use NODE_TYPES to look up node definitions by type

    main

    The NODE_TYPES object is a dictionary that allows you to quickly retrieve a node's configuration using its unique string identifier as the key. This is useful for mapping node types to their specific implementation details during flow rendering or processing.

    import { NODE_TYPES } from "./components/blocks";
    
    // Access a specific node's metadata by its type string
    const nodeConfig = NODE_TYPES["start"];