Overview
The frontend uses Angular 18’s standalone components architecture. All components are self-contained, declare their own dependencies, and follow a consistent pattern for inputs, outputs, and lifecycle management.Component Architecture
Standalone Components
All components use the standalone pattern (no NgModules):Dependency Injection
Services are injected using the moderninject() function:
Component Communication
Components communicate through:- @Input(): Parent-to-child data flow
- @Output(): Child-to-parent events via EventEmitter
- Services: Shared state and business logic
Key Components
AppComponent
Location:src/app/app.component.ts
The root component that orchestrates the dashboard:
- Load initial data using
forkJoin()for parallel requests - Manage filters and active tab state
- Coordinate data flow between child components
- Handle loading and error states
- Clean up subscriptions on destroy
DashboardMapComponent
Location:src/app/dashboard-map/dashboard-map.component.ts
Purpose: Interactive map visualization using Leaflet
Inputs:
filters: DashboardFilters- Current filter stateassignments: StockAssignment[]- Stock assignments to displaywarehouses: Warehouse[]- Warehouse locationsstores: Store[]- Store locations
Leaflet Integration
Map Initialization
Marker Clustering
Route Visualization
- Polylines connect warehouses to stores
- Arrow decorators show direction
- Interactive hover and click states
- Popups display assignment details
DashboardTableComponent
Location:src/app/dashboard-table/dashboard-table.component.ts
Purpose: Tabular view of stock assignments with virtual scrolling
Inputs:
assignments: StockAssignment[]- Assignments to displaywarehouses: Warehouse[]- For country lookupstores: Store[]- For country lookup
Virtual Scrolling
Uses Angular CDK for performance with large datasets:Performance Optimization
DashboardMetricsComponent
Location:src/app/dashboard-metrics/dashboard-metrics.component.ts
Purpose: Display global metrics summary
Inputs:
metrics: GlobalMetrics | null- Global metrics data
FormatNumberPipe- Format large numbers (e.g., 1.2M)FormatDistancePipe- Format distances (e.g., 1,234 km)
DashboardMetricsDetailComponent
Location:src/app/dashboard-metrics-detail/dashboard-metrics-detail.component.ts
Purpose: Detailed metrics with Chart.js visualizations
Inputs:
metrics: DetailedMetrics | null- Filtered metrics data
Chart.js Integration
Chart Types
Warehouse Distribution (Horizontal Bar):DashboardFiltersComponent
Location:src/app/dashboard-filters/dashboard-filters.component.ts
Purpose: Filter controls for warehouses, stores, and products
Inputs:
warehouses: Warehouse[]- Available warehousesstores: Store[]- Available storesproducts: Product[]- Available productsfilters: DashboardFilters- Current filter state
filtersChange: EventEmitter<DashboardFilters>- Filter updates
@ng-select/ng-select for advanced dropdown functionality:
DashboardTabsComponent
Location:src/app/dashboard-tabs/dashboard-tabs.component.ts
Purpose: Tab navigation (Map, Table, Metrics)
Inputs:
activeTab: DashboardTab- Current active tab
tabChange: EventEmitter<DashboardTab>- Tab change events
Component Communication Patterns
Parent-to-Child (Input)
Child-to-Parent (Output)
Service-Based Communication
For cross-component data sharing, services provide centralized state:Lifecycle Management
Memory Leak Prevention
All components usetakeUntil() for subscription cleanup:
Change Detection
Components implementOnChanges to react to input changes:
Styling
Components use SCSS with component-scoped styles:src/styles.scss.
Next Steps
- Explore Service Layer
- Review Frontend Setup
- Learn about API Integration