Skip to content

JavaScript Modules

Overview

The FlowBuilder frontend is built using a modular JavaScript architecture that allows for better maintainability and code organization. Instead of having one large monolithic JavaScript file, the functionality is split into focused modules that are dynamically combined at runtime.

How JavaScript Modules Work

Module Structure

Each JavaScript module is a separate .js file that exports a default object containing methods and properties:

javascript
// Example module structure
export default {
    methodName() {
        // Method implementation
        // Has access to all FlowBuilder component properties via 'this'
    },

    anotherMethod() {
        // Another method
    },
};

JavaScript Module Integration

The ScriptManager automatically combines all modules into a single Alpine.js component. The service:

  1. Reads each JavaScript module file
  2. Extracts the exported object content
  3. Combines all methods into the main FlowBuilder component
  4. Injects the combined code into the Blade template

Available Component Properties

When writing module methods, you have access to all FlowBuilder component properties through this:

Core Data Properties

  • this.nodes - Object containing all available node definitions
  • this.flows - Array of all flows in the system
  • this.currentFlow - The currently selected flow object
  • this.drawflowData - JSON string of the current flow's visual data
  • this.variables - Object containing available system variables

Editor Properties

  • this.editor - The Drawflow editor instance
  • this.mobileItemSelected - Currently selected item on mobile
  • this.mobileLastMove - Last touch move event on mobile
  • this.locked - Whether the editor is in locked mode
  • this.nodeSelectedTime - Timestamp of last node selection

UI State Properties

  • this.unsavedChanges - Boolean indicating unsaved changes
  • this.onSaving - Boolean indicating save operation in progress
  • this.moreOptionsMenuOpen - Boolean for more options menu state
  • this.creatingFlow - Boolean indicating flow creation in progress
  • this.deleteFlowId - ID of flow being deleted (null if none)
  • this.showStartFlowButton - Boolean to show/hide start flow button

Validation Properties

  • this.flowValidationErrors - Array of flow-level validation errors
  • this.nodesWithErrors - Array of node IDs that have validation errors

Available Modules

Core Modules

editor-core.js

Contains the main initialization logic and core editor functionality:

  • initFlowBuilder() - Main initialization method
  • initEditor() - Drawflow editor setup
  • setupEventListeners() - DOM event listener setup
  • initGlobalVariables() - Variable system initialization

event-handlers.js

Handles all Drawflow editor events:

  • registerEvents() - Register all editor event listeners
  • nodeCreated(), nodeRemoved(), nodeSelected() - Node lifecycle events
  • connectionCreated(), connectionRemoved() - Connection events
  • handleDuplicateConnections() - Prevent duplicate connections

flow-management.js

Manages flow operations:

  • save() - Save current flow data
  • createFlow() - Create new flow
  • changeFlow() - Switch between flows
  • confirmDeleteFlow() - Delete flow confirmation
  • startFlow() - Execute flow manually
  • verifyIfHasTrigger() - Check if flow has trigger nodes

node-operations.js

Handles node drag & drop and positioning:

  • setupTouchListeners() - Mobile touch event setup
  • drag(), drop() - Drag and drop functionality
  • addNodeToDrawFlow() - Add nodes to the canvas
  • calculateAdjustedPosition() - Position calculation for different zoom levels

validation.js

Flow and node validation logic:

  • validateFlow() - Validate entire flow
  • processValidationErrors() - Process and display validation errors
  • highlightNodeErrors() - Visual error highlighting
  • clearValidationErrors() - Clear error highlights

ui-controls.js

User interface controls:

  • toggleLock() - Toggle editor lock mode
  • zoomIn(), zoomOut(), zoomReset() - Zoom controls
  • clear() - Clear current flow
  • openHelpModal() - Open help modal

key-bindings.js

Keyboard shortcuts and hotkeys:

  • registerKeyBindings() - Register all keyboard shortcuts
  • shouldHandleKeyEvent() - Determine if key event should be handled

mobile-touch.js

Mobile device support and touch handling:

  • initMobileSupport() - Initialize mobile-specific features
  • setupMobileSpecificBehaviors() - Mobile behavior adjustments
  • handleViewportChanges() - Handle mobile keyboard appearance

Using the ScriptManager

The ScriptManager is automatically used by the FlowBuilder component. All default modules are included by default.

Adding Custom Modules

You can add additional modules to extend FlowBuilder functionality:

php
use Modules\FlowBuilder\Facades\ScriptManager;

// Add a custom module
ScriptManager::push('resources/js/mymodule/my-custom-module.js');

Creating Custom Modules

  1. Create a new .js file
  2. Export a default object with your methods:
javascript
export default {
    myCustomMethod() {
        // Access FlowBuilder data via this
        console.log('Current flow:', this.currentFlow);
        console.log('Available nodes:', this.nodes);

        // Use Core FlowBuilder methods
        this.setUnsavedChanges(true);
    },

    handleCustomEvent() {
        // Handle custom functionality
        this.$dispatch('custom-event', { data: 'example' });
    },
};
  1. Register the module path in your ServiceProvider with ScriptManager
php
use Modules\FlowBuilder\Facades\ScriptManager;

ScriptManager::push('resources/js/mymodule/my-custom-module.js');

Inject Code in component initialization

You can also inject custom code directly into the FlowBuilder component initialization, util for adding event listeners or custom logic that needs to run when the component is initialized:

php
use Modules\FlowBuilder\Facades\ScriptManager;

ScriptManager::inject('
    document.addEventListener("my-custom-event", function() {
        // Listen for a custom event for example
    });
');

Available Stores

flowBuilder

The flowBuilder Alpine store manages the main FlowBuilder state, including loaded flows, nodes, and variables.

Properties:

  • currentFlow — The currently selected flow object
  • nodes — Object containing all available node definitions
  • flows — Array of all flows in the system
  • drawflowData — JSON string of the current flow's visual data
  • variables — Array of available system variables

availableVariables

The availableVariables Alpine store manages system variables, including creation, editing, removal, and synchronization with the backend and editor.

Properties:

  • variables — Array of available variables
  • editingVariable — The variable currently being edited (or null)
  • creatingVariable — Boolean indicating if a variable is being created

Methods:

  • add(variable) — Add or update a variable in the store and dispatch an update event
  • createVariable(name, id, value, nodeId = null) — Create a new variable, save it to the backend, and update the store
  • remove(variableId) — Remove a variable by ID and dispatch an update event
  • reset() — Clear all variables and editing state
  • getAll() — Return all variables
  • getById(id) — Return a variable by ID
  • setEditingVariable(variable) — Set the variable currently being edited
  • syncNodeVariables(drawflowData, currentFlowSlug) — Synchronize variables between drawflow and the store, reflecting changes in the backend

These stores are accessible via Alpine.js and centralize FlowBuilder state and operations, ensuring reactivity and data consistency between frontend and backend.