UI State Management
Relevant source files
The following files were used as context for generating this wiki page:
- apps/web/src/features/react-flow-visualization/store/app-store.ts
- apps/web/src/stores/workflow-store.ts
- apps/web/src/stores/evolution-runs-store.ts
- apps/web/src/app/(protected)/workflows/page.tsx
- apps/web/src/app/components/agent-dialog/purpose-section.tsx
- apps/web/src/app/(protected)/(editor)/edit/components/JSONEditor.tsx
The UI state management in the lucky web application is built upon the Zustand library. It employs a modular approach, separating concerns into distinct stores that manage specific domains of the application state. This system is responsible for handling the state of the workflow editor, lists of workflows and evolution runs, and persisting user interface settings to localStorage.
The core of the state management is divided into three primary stores:
AppStore: Manages the complex state of the interactive workflow editor, including nodes, edges, and UI panels.WorkflowStore: Manages the collection of user-created workflows displayed on the main workflows page.EvolutionRunsStore: Manages the state for fetching and displaying evolution run data.
This diagram shows the high-level relationship between the stores and the UI components they serve.
AppStore: Workflow Editor State
The AppStore is the most comprehensive store, responsible for managing the entire state of the workflow visualization and editing interface powered by React Flow. It handles everything from the graph's nodes and edges to UI panel visibility and data synchronization with the backend.
Sources: apps/web/src/features/react-flow-visualization/store/app-store.ts
State (AppState)
The AppState interface defines the shape of the editor's state.
| Property | Type | Description |
|---|---|---|
nodes | AppNode[] | An array of nodes to be rendered on the canvas. |
edges | AppEdge[] | An array of edges connecting the nodes. |
colorMode | "light" | "dark" | The current theme of the UI. |
layout | "fixed" | "free" | The layout mode for the graph. fixed implies auto-layout. |
workflowLoading | boolean | A flag indicating if a workflow is currently being loaded. |
workflowJSON | string | The stringified JSON representation of the current workflow. |
currentWorkflowId | string | The ID of the workflow currently being edited. |
workflowValidationErrors | WorkflowValidationError[] | A list of validation errors for the current workflow. |
nodeDetailsOpen | boolean | A flag to control the visibility of the node details panel. |
selectedNodeId | string | The ID of the currently selected node. |
chatMessages | object[] | An array of messages for the chat/assistant panel. |
logPanelOpen | boolean | A flag to control the visibility of the execution logs panel. |
_hasHydrated | boolean | A flag indicating if the state has been rehydrated from localStorage. |
Sources: apps/web/src/features/react-flow-visualization/store/app-store.ts:40-78
Actions (AppActions)
The store provides a rich set of actions to manipulate the state. Key actions include:
| Action | Description |
|---|---|
onNodesChange / onEdgesChange | Handlers for changes from the React Flow canvas (e.g., dragging, selection). |
addNodeByType | Adds a new node of a specific type to the canvas at a given position. |
addNodeInBetween | Inserts a new node between two existing connected nodes. |
loadWorkflowConfig | Fetches a workflow configuration from the /api/workflow/config endpoint and populates the store. |
loadWorkflowVersion | Fetches a specific workflow version from /api/workflow/version/[id] and populates the store. |
loadWorkflowFromData | Populates the store from a provided WorkflowConfig object, used for syncing from the JSON editor. |
exportToJSON | Serializes the current graph state (nodes and edges) into a WorkflowConfig JSON string, including UI layout data. |
syncJSONToGraph | Parses the workflowJSON string and updates the visual graph to match it. |
organizeLayout | Triggers an automatic layout of the graph nodes and edges using layoutGraph. |
updateNode | Updates the data of a specific node and triggers a background save to the /api/workflow/save endpoint. |
openNodeDetails / closeNodeDetails | Manages the visibility of the node details panel. |
addValidationError / clearValidationErrors | Manages workflow validation errors. |
Sources: apps/web/src/features/react-flow-visualization/store/app-store.ts:98-119
Workflow Loading and Layout
The process of loading a workflow into the editor involves fetching data, converting it to the frontend format, and applying a layout.
This diagram illustrates the sequence for loading a workflow. The store first fetches the configuration, then checks if it contains pre-saved UI layout information. If so, it restores the positions; otherwise, it computes a new layout automatically.
Sources: apps/web/src/features/react-flow-visualization/store/app-store.ts:401-464, apps/web/src/features/react-flow-visualization/store/app-store.ts:548-597
State Persistence
The AppStore uses the persist middleware from Zustand to save a subset of its state to the browser's localStorage. This ensures that the user's work in the editor is not lost between sessions.
- Storage Key:
workflow-editor-state - Persisted State:
nodesedgesworkflowJSONcurrentWorkflowIdlayoutcolorMode
The store includes an onRehydrateStorage callback to log the hydration process from localStorage and set the _hasHydrated flag upon completion. Drafts are also saved to local storage on a per-workflow basis (workflow_draft_[id]) and restored on mount.
Sources: apps/web/src/features/react-flow-visualization/store/app-store.ts:741-768, apps/web/src/app/(protected)/(editor)/edit/components/JSONEditor.tsx:112-123
WorkflowStore: Workflow List Management
This store is responsible for managing the list of workflows displayed on the /workflows page. It handles fetching the data, managing loading and error states, and supports optimistic updates.
Sources: apps/web/src/stores/workflow-store.ts, apps/web/src/app/(protected)/workflows/page.tsx
State and Actions
| State Property | Type | Description |
|---|---|---|
workflows | WorkflowWithVersions[] | An array of workflow objects, including version information. |
loading | boolean | A flag indicating if the workflows are being loaded. |
error | string | null | Stores any error message that occurred during loading. |
| Action | Description |
|---|---|
loadWorkflows | Fetches the list of workflows from the /api/workflows endpoint. |
removeWorkflow | Optimistically removes a workflow from the local workflows array. This is typically called before the delete API request is confirmed. |
Sources: apps/web/src/stores/workflow-store.ts:11-20
Data Flow
The WorkflowsPage component uses this store to display and manage workflows.
This flow shows how the page loads data via the store and how optimistic updates work. When a user deletes a workflow, the UI updates instantly by removing the item from the store's state, even before the backend confirms the deletion.
Sources: apps/web/src/app/(protected)/workflows/page.tsx:115-120, apps/web/src/app/(protected)/workflows/page.tsx:188-192, apps/web/src/stores/workflow-store.ts:22-38
EvolutionRunsStore: Evolution Run Data
This store is simpler and is dedicated to fetching and holding the state for a list of evolution runs.
Sources: apps/web/src/stores/evolution-runs-store.ts
State and Actions
| State Property | Type | Description |
|---|---|---|
runs | EvolutionRun[] | An array of evolution run objects. |
loading | boolean | A flag indicating if the runs are being loaded. |
error | string | null | Stores any error message that occurred during loading. |
| Action | Description |
|---|---|
loadRuns | Fetches the list of evolution runs from the /api/evolution-runs endpoint. |
Sources: apps/web/src/stores/evolution-runs-store.ts:8-17
The data flow is a straightforward fetch-and-display pattern, similar to the initial load in WorkflowStore.
Summary
The application's UI state is managed through a set of domain-specific Zustand stores. AppStore handles the complex, interactive state of the workflow editor with local storage persistence for a seamless user experience. WorkflowStore and EvolutionRunsStore serve as data caches for their respective domains, handling data fetching, loading states, and enabling features like optimistic UI updates. This modular architecture effectively separates concerns and provides a clear, organized structure for managing frontend state.