Architecture Guide
This guide covers the application architecture, design patterns, and organizational structure of Waldur HomePort.
Frontend Stack
- React with TypeScript for component development
- Vite for build tooling and development server
- Redux with Redux Saga for legacy state management
- UI Router React for navigation (state-based routing)
- React Bootstrap (Bootstrap 5) for UI components
- React Final Form for modern form handling
- ECharts for data visualization
- Leaflet with React Leaflet for mapping
- TanStack React Query for server state management
Check Current Versions
Check all major dependencies
yarn list react typescript vite redux @uirouter/react react-bootstrap react-final-form echarts leaflet @tanstack/react-query
Check specific package version
yarn info
Key Architectural Patterns
Module Organization
The codebase follows a feature-based folder structure under src/:
- Each domain (customer, project, marketplace, etc.) has its own folder
- Components are co-located with their specific business logic
- Shared utilities are in
core/andtable/ - API interactions use Redux patterns with sagas
State Management
Modern Patterns (Use for New Development)
- TanStack React Query: Server state management and caching for API calls
- React Final Form: Local form state management
- Local Component State: useState and useReducer for UI state
- Custom Hooks: Reusable state logic and business operations
Legacy Patterns (Maintenance Only - Do Not Extend)
- Redux Store: Global state with dynamic reducer injection (legacy - avoid for new features)
- Redux Saga: Async operations and side effects (legacy - use React Query instead)
- Table Store: Specialized table data management in
src/table/(legacy pattern)
Navigation & Routing
The application uses UI-Router for React with state-based routing. Routes are defined in module-specific routes.ts files.
Route Definition Structure
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Dynamic Parameters (Preventing Full Reloads)
When a query parameter controls nested tabs or filters within a page, mark it as dynamic: true to prevent full component reloads:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
Nested Tabs Pattern
For tabs within a page section that need URL synchronization:
- Add the parameter to the route URL with
dynamic: true:
1 2 3 4 5 6 7 | |
- Use router hooks in the component:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
Main Page Tabs (usePageTabsTransmitter)
For main page-level tabs, use the usePageTabsTransmitter hook which automatically handles URL synchronization:
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Route Best Practices
- Use
dynamic: truefor any parameter that controls UI state within a page (subtabs, filters, panel states) - Keep routes hierarchical - child routes inherit parent's URL prefix
- Use abstract routes for shared layouts and data fetching
- Lazy load components with
lazyComponent()for code splitting - Define query params in URL - e.g.,
url: 'page/?tab&filter'makes params explicit
Data Fetching
Modern Approach (Use for New Development)
- TanStack React Query: Preferred for server state management and caching
- Custom Hooks: Reusable data fetching logic with React Query
- Waldur JS Client: TypeScript API client integration
- Automatic Caching: 5-minute stale time with background refetching
Legacy Approach (Maintenance Only)
- Redux Actions/Sagas: Centralized API calls (legacy - use React Query instead)
- Table Store: Standardized data loading patterns (legacy pattern)
- Periodic Polling: Real-time updates through sagas (use React Query polling instead)
Component Architecture
- Container Components: Handle data fetching and state management
- Presentation Components: Pure UI components with props
- Form Components: Specialized forms using React Final Form
- Table Components: Reusable table infrastructure with filtering, sorting, pagination
- Button Components: Unified button system wrapping Bootstrap for consistent UX
Button Component Architecture
The application uses a unified button system that wraps Bootstrap Button to ensure consistent styling, behavior, and accessibility. Direct Bootstrap Button imports are forbidden - use the appropriate Waldur wrapper component instead.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
Button Selection Guide
| Use Case | Component |
|---|---|
| Form submit | SubmitButton |
| Form submit in popover/compact form | CompactSubmitButton |
| Table row action | ActionButton or RowActionButton |
| Inline action (small) | CompactActionButton |
| Modal cancel/close | CloseDialogButton |
| Icon-only button with tooltip | IconButton |
| Table toolbar (refresh, export, filter) | ToolbarButton or IconButton |
| Edit field in settings row | CompactEditButton |
| Edit in card header | EditButton |
| Create with dialog | CreateModalButton |
| Delete with confirmation | DeleteButton |
ESLint Enforcement
The no-direct-bootstrap-button ESLint rule prevents direct Bootstrap Button imports. Allowed wrapper files:
src/core/buttons/BaseButton.tsxsrc/table/ActionButton.tsxsrc/form/SubmitButton.tsxsrc/modal/CloseDialogButton.tsx
Key Directories
src/core/- Shared utilities, API clients, and base componentssrc/table/- Reusable table components and data managementsrc/form/- Form components and field implementationssrc/marketplace/- Service marketplace and offering management (largest module)src/customer/- Organization management and billingsrc/project/- Project management and resourcessrc/auth/- Authentication and identity provider integrationsrc/administration/- Admin panel functionalitysrc/azure/- Azure cloud integrationsrc/booking/- Resource booking systemsrc/broadcasts/- System announcementssrc/dashboard/- Dashboard componentssrc/navigation/- Navigation and layout componentssrc/proposals/- Proposal managementsrc/quotas/- Resource quotas managementsrc/theme/- Theme management (dark/light mode)src/user/- User managementsrc/metronic/- UI framework integration
Backend Integration
Integrates with Waldur MasterMind REST API requiring CORS configuration on the backend for local development.
API Client
- Waldur JS Client - Custom API client for Waldur MasterMind
- Auto-generated client with TypeScript support
- Request/response interceptors for authentication and error handling
- Token-based authentication with auto-refresh capabilities
Version Management
Check current version
grep "waldur-js-client" package.json
Check latest available version
yarn info waldur-js-client version
Update to latest version in package.json, then install
yarn install
Build System & Performance
Modern Build Configuration
- Vite 7.0 with ES modules support
- Node.js v23.7.0 (latest LTS) compatibility
- Code splitting with lazy loading for all major features
- Optimized bundle sizes and asset processing
- Source maps for development and production debugging
Performance Optimizations
- Lazy component loading with
lazyComponentutility - Dynamic reducer injection for Redux store
- Automatic code splitting by route and feature
- Optimized asset loading (images, fonts, SVG)
- Bundle analysis and optimization tools
Asset Management
- SVG files processed through SVGR 8.1.0 plugin for React components
- Images and static assets in
src/images/ - Font files managed through Vite's asset pipeline
- Markdown content processed through vite-plugin-markdown
- Monaco Editor 0.52.2 for code editing capabilities
- Sass 1.85.0 for SCSS preprocessing
Environment Variables
VITE_API_URL- Backend API endpoint (defaults to http://localhost:8000/)
Project Overview
Waldur HomePort is a React-based web frontend for the Waldur MasterMind cloud orchestrator. It's a TypeScript application built with Vite that provides a comprehensive management interface for cloud resources, organizations, projects, and marketplace offerings.