This document describes the React frontend application's overall structure, including the App component, Zustand state management stores (session, alerts, custom tool, socket), component hierarchy, and how major features like Prompt Studio integrate into the application. For routing and authentication, see Routing and Page Layouts. For navigation components and plugin architecture, see Navigation and Plugin Architecture.
The App component serves as the entry point for the entire React application, configuring global providers, theme, notifications, and rendering the routing tree.
frontend/src/App.jsx24-107 defines the main App component with the following responsibilities:
ConfigProvider from Ant Design with theme algorithm selectionBrowserRouter for client-side routingHelmetProvider for managing document head elementsSources: frontend/src/App.jsx1-107 frontend/src/routes/Router.jsx89-164
The application uses Zustand for lightweight, hook-based state management. Zustand was chosen over Redux for its simplicity and minimal boilerplate (dependency: zustand: ^4.3.8 in package.json).
Core Zustand Stores:
Sources: frontend/src/store/session-store.js frontend/src/store/alert-store.js frontend/src/store/custom-tool-store.js frontend/src/store/socket-custom-tool.js frontend/src/components/custom-tools/tool-ide/ToolIde.jsx4-15 frontend/src/components/custom-tools/prompt-card/PromptCard.jsx9-12
The useSessionStore manages authentication state and user session information across the entire application.
Store Definition:
frontend/src/store/session-store.js1-24 defines the session store with the following structure:
| State Variable | Type | Purpose |
|---|---|---|
sessionDetails | Object | Contains user info, org details, adapters, roles, CSRF token |
isLogoutLoading | Boolean | Tracks logout operation state |
Store Methods:
setSessionDetails(details): Completely replaces session detailsupdateSessionDetails(details): Merges new details with existing sessionsetLogoutLoading(loading): Sets logout loading stateUsage Pattern:
Components access the store using selector functions:
Example in frontend/src/components/navigations/top-nav-bar/TopNavBar.jsx136-137
Sources: frontend/src/store/session-store.js1-24 frontend/src/components/navigations/top-nav-bar/TopNavBar.jsx136-137
The useAlertStore manages global notifications and alert messages displayed to users.
Store Definition:
frontend/src/store/alert-store.js1-37 implements the alert store with:
| State Variable | Type | Default | Purpose |
|---|---|---|---|
alertDetails.type | String | "" | Alert type: "success", "error", "info", "warning" |
alertDetails.content | String | "" | Alert message text |
alertDetails.title | String | "" | Alert title (defaults to "Success" or "Failed") |
alertDetails.duration | Number | 6 | Display duration in seconds (0 = manual close) |
alertDetails.key | String | null | Unique identifier for the notification |
Store Methods:
frontend/src/store/alert-store.js20-34 defines setAlertDetails(details) which:
uniqueId from lodashNotification Display:
frontend/src/App.jsx50-70 uses useEffect to watch alertDetails and display notifications:
Sources: frontend/src/store/alert-store.js1-37 frontend/src/App.jsx25-70
The useCustomToolStore manages state for the Prompt Studio feature, which is the flagship feature of Unstract.
Store Definition:
frontend/src/store/custom-tool-store.js10-34 defines the default state structure:
| State Variable | Type | Purpose |
|---|---|---|
dropdownItems | Object | Cached dropdown options from API |
selectedDoc | Object | Currently selected document in PDF viewer |
listOfDocs | Array | All uploaded documents for the tool |
refreshRawView | Boolean | Triggers raw view refresh |
defaultLlmProfile | String | Default LLM profile ID |
llmProfiles | Array | Available LLM profile configurations |
details | Object | Tool metadata (tool_id, tool_name, prompts, etc.) |
disableLlmOrDocChange | Array | Locks UI during extraction |
indexDocs | Array | Documents currently being indexed |
rawIndexStatus | Array | Indexing status for raw view |
summarizeIndexStatus | Array | Indexing status for summary view |
singlePassExtractMode | Boolean | Single-pass vs multi-pass extraction |
isMultiPassExtractLoading | Boolean | Multi-pass extraction in progress |
isSinglePassExtractLoading | Boolean | Single-pass extraction in progress |
selectedHighlight | Object | Currently selected text highlight with coordinates |
hasUnsavedChanges | Boolean | Tracks unsaved prompt edits |
deploymentUsageInfo | Object | Deployment impact information for export warning |
Store Methods:
frontend/src/store/custom-tool-store.js54-158 defines key methods:
setDefaultCustomTool(): Resets to default statesetCustomTool(entireState): Replaces entire state (used on tool load)updateCustomTool(entireState): Merges partial state updatesaddNewInstance(type): Adds new prompt or note with prompt_id = unsaved_{n}deleteInstance(promptId): Removes prompt/note and marks changespushIndexDoc(docId): Adds document to indexing queuedeleteIndexDoc(docId): Removes document from indexing queuesetHasUnsavedChanges(hasChanges): Persists unsaved flag to sessionStoragemarkChangesAsExported(): Clears unsaved changes flag and updates export timestamprestoreUnsavedChangesFromSession(toolId): Restores unsaved state after page reloadUnsaved Changes Persistence:
frontend/src/store/custom-tool-store.js5-157 implements sessionStorage persistence:
This ensures that if a user refreshes the page mid-edit, the "unsaved changes" state persists and the export reminder banner will still display.
Sources: frontend/src/store/custom-tool-store.js1-161 frontend/src/components/custom-tools/tool-ide/ToolIde.jsx49-64
The useSocketCustomToolStore manages WebSocket messages specifically for Prompt Studio tool execution.
Usage in PromptCard:
frontend/src/components/custom-tools/prompt-card/PromptCard.jsx56-91 subscribes to WebSocket messages:
This allows real-time progress updates during document indexing and prompt execution, displaying status messages in the UI.
Sources: frontend/src/store/socket-custom-tool.js frontend/src/components/custom-tools/prompt-card/PromptCard.jsx56-91
frontend/src/App.jsx14 imports useSocketLogsStore for managing WebSocket log messages. The store's pushLogMessages method is called in frontend/src/App.jsx62-69 to record all notifications as log entries.
Sources: frontend/src/App.jsx14-69
The application supports optional plugin stores loaded dynamically:
select-product-store for product switchingSources: frontend/src/components/navigations/top-nav-bar/TopNavBar.jsx49-121 frontend/src/components/navigations/side-nav-bar/SideNavBar.jsx32-37
The application implements centralized error handling through the useExceptionHandler hook, which processes errors from API calls and user interactions.
frontend/src/hooks/useExceptionHandler.jsx4-127 defines useExceptionHandler, which returns a function that transforms errors into alert objects.
Function Signature:
Error Processing Flow:
Error Types:
frontend/src/hooks/useExceptionHandler.jsx37-115 handles the following error types:
| Error Type | Handling Logic |
|---|---|
validation_error | Formats validation errors from errors array, optionally calls setBackendErrors |
subscription_error | Navigates to /subscription-expired page |
client_error | Extracts errors[0].detail as message |
server_error | Extracts errors[0].detail as message |
Network error (ERR_NETWORK) | Returns "Please check your internet connection" |
Canceled (ERR_CANCELED) | Returns "Request has been canceled" |
Usage Example:
frontend/src/components/navigations/top-nav-bar/TopNavBar.jsx32-216 shows typical usage:
Sources: frontend/src/hooks/useExceptionHandler.jsx1-135 frontend/src/components/navigations/top-nav-bar/TopNavBar.jsx32-216
The application uses Ant Design's theming system with support for light and dark modes.
frontend/src/App.jsx73-87 wraps the application in ConfigProvider:
Theme Configuration:
| Property | Value | Purpose |
|---|---|---|
direction | "ltr" (default) | Text direction, supports RTL |
algorithm | darkAlgorithm or defaultAlgorithm | Theme algorithm from theme import |
components.Button.colorPrimary | "#092C4C" | Primary button color |
components.Button.colorPrimaryHover | "#0e4274" | Button hover state |
components.Button.colorPrimaryActive | "#092C4C" | Button active state |
Theme Selection:
The current theme is stored in sessionDetails.currentTheme and compared against THEME.DARK constant from frontend/src/helpers/GetStaticData.js
CSS Variables:
frontend/src/index.css1-249 imports variables.css which defines CSS custom properties for consistent styling across the application. The root element uses var(--page-bg-2) for background color (frontend/src/index.css14).
Sources: frontend/src/App.jsx1-87 frontend/src/index.css1-14
The application follows a hierarchical component structure with clear separation between layout, navigation, and feature components.
Sources: frontend/src/App.jsx24-107 frontend/src/routes/Router.jsx116-198 frontend/src/layouts/page-layout/PageLayout.jsx15-54 frontend/src/routes/useMainAppRoutes.js126-268
The Prompt Studio feature (accessed via ToolIdePage) has a complex component hierarchy:
Data Loading Flow:
frontend/src/components/helpers/custom-tools/CustomToolsHelper.js34-127 loads tool data before rendering:
GET /api/v1/unstract/{orgId}/prompt-studio/{id}GET /api/v1/unstract/{orgId}/prompt-studio/prompt-document?tool_id={id}GET /api/v1/unstract/{orgId}/prompt-studio/select_choicesGET /api/v1/unstract/{orgId}/prompt-studio/prompt-studio-profile/{id}GET /api/v1/unstract/{orgId}/adapter/useCustomToolStore with loaded dataSources: frontend/src/components/custom-tools/tool-ide/ToolIde.jsx1-415 frontend/src/components/custom-tools/tools-main/ToolsMain.jsx1-247 frontend/src/components/custom-tools/document-manager/DocumentManager.jsx1-539 frontend/src/components/helpers/custom-tools/CustomToolsHelper.js22-151
The application uses a hierarchical layout system with reusable layout components.
frontend/src/layouts/page-layout/PageLayout.jsx15-54 defines the main PageLayout component used throughout the application.
Component Structure:
Props:
| Prop | Type | Default | Purpose |
|---|---|---|---|
sideBarOptions | any | - | Options passed to SideNavBar |
topNavBarOptions | node | - | Additional elements in top bar |
showLogsAndNotifications | boolean | true | Show bottom drawer |
hideSidebar | boolean | false | Hide sidebar completely |
Collapsible Sidebar State:
frontend/src/layouts/page-layout/PageLayout.jsx21-26 manages sidebar collapse state using localStorage:
The sidebar also supports pinning (keeping it open on hover) via frontend/src/components/navigations/side-nav-bar/SideNavBar.jsx253-272:
Sources: frontend/src/layouts/page-layout/PageLayout.jsx1-55 frontend/src/components/navigations/side-nav-bar/SideNavBar.jsx248-293 frontend/src/helpers/localStorage.js13-39
frontend/src/components/navigations/top-nav-bar/TopNavBar.jsx123-491 implements the top navigation bar with:
User Menu Items:
frontend/src/components/navigations/top-nav-bar/TopNavBar.jsx249-389 builds menu items dynamically:
Organization Switching:
frontend/src/components/navigations/top-nav-bar/TopNavBar.jsx202-217 implements org switching:
Sources: frontend/src/components/navigations/top-nav-bar/TopNavBar.jsx1-457
frontend/src/components/navigations/side-nav-bar/SideNavBar.jsx248-762 renders the collapsible side navigation menu.
Menu Structure:
The menu is organized into three main sections defined in SideNavBar.jsx317-451:
| Section | Items |
|---|---|
| BUILD | Prompt Studio, Agentic Prompt Studio (plugin), Workflows |
| MANAGE | Dashboard, API Deployments, ETL Pipelines, Task Pipelines, Logs |
| REVIEW | HITL (Human-in-the-Loop) review pages with submenu |
| SETTINGS | LLMs, Vector DBs, Embedding, Text Extractor, Connectors, Platform |
Dynamic Menu Items:
frontend/src/components/navigations/side-nav-bar/SideNavBar.jsx479-492 adds Agentic Prompt Studio if the plugin is available:
Hover Menu for Settings and HITL:
frontend/src/components/navigations/side-nav-bar/SideNavBar.jsx625-684 implements a Popover submenu for Platform settings:
The settings submenu includes Platform Settings, User Management, Default Triad, and HITL Settings (if plugin enabled).
Subscription-Based Disabling:
frontend/src/components/navigations/side-nav-bar/SideNavBar.jsx525-541 disables all menu items if subscription has expired:
Sources: frontend/src/components/navigations/side-nav-bar/SideNavBar.jsx1-763 frontend/src/components/navigations/side-nav-bar/SideNavBar.css1-185
The application supports optional functionality through a plugin system that loads components dynamically.
The consistent pattern for loading plugins:
Examples:
frontend/src/components/navigations/top-nav-bar/TopNavBar.jsx49-56 shows conditional store access:
Sources: frontend/src/App.jsx16-22 frontend/src/components/navigations/top-nav-bar/TopNavBar.jsx41-121 frontend/src/components/helpers/auth/RequireAuth.js12-18
Key Steps:
sessionDetails.currentTheme in App.jsx76-79Sources: frontend/src/App.jsx24-107 frontend/src/components/helpers/auth/RequireAuth.js28-94 frontend/src/layouts/page-layout/PageLayout.jsx12-56
The logout process is handled by the useLogout hook.
frontend/src/hooks/useLogout.js11-39 defines the logout function:
Logout Steps:
isLogoutLoading to true (useLogout.js24)sessionid and csrftoken (useLogout.js27)Full Screen Loader:
frontend/src/App.jsx90-94 displays a full-screen loader during logout:
Sources: frontend/src/hooks/useLogout.js1-40 frontend/src/App.jsx27-94
Sources: frontend/src/store/session-store.js frontend/src/store/alert-store.js frontend/src/hooks/useExceptionHandler.jsx frontend/src/hooks/useLogout.js frontend/src/App.jsx
Refresh this wiki