18 KiB
HMI Editing System Cleanup Plan
Overview
The HMI (Human Machine Interface) editing system currently has architectural inconsistencies, duplicate code, and legacy patterns that need cleanup. This document outlines a comprehensive plan to refactor and modernize the codebase.
Current Architecture Issues
1. Duplicate Layout Systems
- Problem: Multiple layout systems exist with overlapping functionality
unifiedLayoutManager.ts- New grid-based container systemlayoutContainer.ts- Duplicate container system with similar interfaceswidgetLayout.ts- Legacy absolute positioning system
- Impact: Code duplication, confusion, maintenance overhead
2. Inconsistent Component Interfaces
- Problem: Similar components with different interfaces
GenericCanvas.tsx- Uses UnifiedLayoutManager (new)ContainerCanvas.tsx- Uses LayoutContainerManager (old)
- Impact: Inconsistent behavior, harder to maintain
3. Mixed Storage Patterns
- Problem: Different storage approaches across components
- New: API-first with localStorage fallback
- Old: Direct localStorage only
- Impact: Data consistency issues, performance problems
4. Legacy Code Dependencies
- Problem: Old components still referenced but not actively used
- Impact: Bundle size, confusion, maintenance burden
Cleanup Plan
Phase 1: Architecture Consolidation (Priority: High)
1.1 Consolidate Layout Systems
Target: Single source of truth for layout management
Timeline: 2-3 days
Tasks:
□ Remove layoutContainer.ts (duplicate of unifiedLayoutManager.ts)
□ Remove widgetLayout.ts (legacy absolute positioning)
□ Update imports to use unifiedLayoutManager.ts only
□ Migrate any unique functionality from old systems
1.2 Standardize Component Interfaces
Target: Consistent props and behavior across HMI components
Timeline: 1-2 days
Tasks:
□ Remove ContainerCanvas.tsx (replaced by GenericCanvas.tsx)
□ Update all references to use GenericCanvas
□ Standardize prop interfaces across HMI components
□ Create shared TypeScript interfaces in types/hmi.ts
1.3 Unify Storage Layer
Target: All HMI components use the same storage service
Timeline: 1 day
Tasks:
□ Remove legacy localStorage direct access
□ Ensure all components use layoutStorage.ts
□ Add migration logic for old data formats
□ Test data consistency across reload/refresh
Phase 2: Code Organization (Priority: Medium)
2.1 File Structure Reorganization
Current Structure:
src/
├── components/hmi/ # Mixed old/new components
├── lib/ # Mixed utilities and managers
└── contexts/ # Layout context
Proposed Structure:
src/
├── components/
│ └── hmi/
│ ├── canvas/ # Canvas components
│ ├── containers/ # Container components
│ ├── widgets/ # Widget components
│ └── palette/ # Widget palette
├── lib/
│ └── hmi/
│ ├── layout/ # Layout management
│ ├── storage/ # Storage services
│ ├── registry/ # Widget registry
│ └── types/ # TypeScript interfaces
└── contexts/
└── hmi/ # HMI-specific contexts
2.2 Create Shared Types Module
File: src/lib/hmi/types/index.ts
Content:
- WidgetInstance interface
- LayoutContainer interface
- PageLayout interface
- HMI component prop types
- Event handler types
2.3 Separate Concerns
Current: Mixed responsibilities in components
Target: Clear separation of concerns
Layout Management:
□ Move layout logic out of components
□ Create dedicated layout service layer
□ Implement proper event handling
State Management:
□ Centralize HMI state in context
□ Remove component-level state for shared data
□ Implement proper state synchronization
Phase 3: Performance Optimization (Priority: Medium)
3.1 Implement Proper Memoization
Target: Reduce unnecessary re-renders by 50%+
Timeline: 1-2 days
**High-Priority Components for React.memo:**
□ GenericCanvas - Wrap with React.memo, custom comparison for layout prop
□ LayoutContainer - Memoize with container and isEditMode comparison
□ WidgetSettingsManager - Prevent re-renders when modal is closed
□ WidgetPalette - Only re-render when palette visibility changes
**useMemo Implementations:**
□ Widget count calculations in GenericCanvas (expensive reduce operations)
□ Grouped widget items in WidgetSettingsManager (complex filtering/sorting)
□ Grid classes generation in LayoutContainer (responsive class calculations)
□ Container hierarchy flattening for drag-drop operations
**useCallback for Event Handlers:**
□ Layout operation handlers (add/remove/move widgets)
□ Container management handlers (add/remove containers)
□ Widget configuration handlers (settings save/cancel)
□ Import/export handlers with file operations
**Performance Measurement:**
□ Use React DevTools Profiler before/after memoization
□ Measure render count reduction during typical editing session
□ Profile memory usage with React DevTools Memory tab
□ Set up performance monitoring hooks in development mode
3.2 Optimize Bundle Size
Target: Reduce HMI bundle size by 20-30%
Timeline: 1 day
**Bundle Analysis:**
□ Run webpack-bundle-analyzer on current build
□ Identify largest dependencies and unused imports
□ Document current bundle size as baseline
□ Create bundle size budget and monitoring
**Code Splitting Implementation:**
□ Lazy load WidgetSettingsManager (only when editing widgets)
□ Lazy load ContainerSettingsManager (only when configuring containers)
□ Dynamic import for widget palette components
□ Separate chunk for import/export functionality
**Tree Shaking Optimization:**
□ Remove unused utility functions from lib/
□ Eliminate dead code from widget registry
□ Clean up unused icon imports from lucide-react
□ Remove unused TypeScript interfaces and types
**Dependency Optimization:**
□ Audit and replace heavy dependencies with lighter alternatives
□ Use bundle-analyzer to identify duplicate dependencies
□ Implement proper side-effects configuration in package.json
□ Consider replacing moment.js with date-fns (if used)
3.3 Cache Management
Target: Efficient data caching and invalidation
Timeline: 1 day
**Cache Strategy Implementation:**
□ Implement LRU cache for layout data with size limits (max 10MB)
□ Add cache versioning to handle schema migrations
□ Implement cache warming on app initialization
□ Add cache health monitoring and cleanup routines
**localStorage Optimization:**
□ Compress layout data before storing (use LZ-string or similar)
□ Implement incremental saves (only save changed data)
□ Add cache expiration based on last modified timestamps
□ Monitor localStorage usage and implement cleanup policies
**Memory Cache Management:**
□ Implement weak references for widget instances
□ Add memory pressure detection and cleanup
□ Cache frequently accessed layout calculations
□ Implement cache invalidation on layout structure changes
**Performance Monitoring:**
□ Add cache hit/miss ratio tracking
□ Monitor cache size growth over time
□ Track cache operation performance (read/write times)
□ Implement cache performance alerts in development mode
Phase 4: Developer Experience - Action Items
4.1 Documentation (Immediate Priority)
4.1.1 Component Documentation
- Create JSDoc comments for all HMI components
GenericCanvas.tsx- Document props, usage patterns, examplesLayoutContainer.tsx- Document container behavior, nesting rulesWidgetPalette.tsx- Document widget registration, custom widgetsWidgetSettingsManager.tsx- Document config schema, validation
4.1.2 Architecture Documentation
- Document layout system architecture in
docs/hmi-architecture.md- Data flow diagrams (layout loading → editing → saving)
- Component hierarchy and relationships
- Storage layer (API → localStorage → memory)
- Widget lifecycle (registration → instantiation → rendering)
- Create troubleshooting guide in
docs/hmi-troubleshooting.md- Common issues and solutions
- Debug console commands
- Performance debugging steps
4.1.3 API Documentation
- Document
UnifiedLayoutManagerpublic methods with examples - Document
LayoutContexthook usage patterns - Create widget development guide with examples
- Document storage service interfaces and usage
4.2 Testing Infrastructure (High Priority)
4.2.1 Unit Tests
UnifiedLayoutManager.test.ts- Test
addWidgetToContainerInMemory()with different scenarios - Test
removeWidgetFromContainerInMemory()edge cases - Test
moveWidgetInContainerInMemory()boundary conditions - Test container nesting limits and validation
- Test
layoutStorage.test.ts- Test API-first storage with fallback scenarios
- Test localStorage migration from old formats
- Test error handling and recovery
LayoutContext.test.tsx- Test hook methods with mocked dependencies
- Test state updates and re-renders
- Test error handling and propagation
4.2.2 Integration Tests
hmi-editing-flow.test.tsx- Test complete widget add → configure → save flow
- Test container creation → widget addition → layout persistence
- Test import/export functionality with real data
- Test edit mode toggle and state preservation
storage-integration.test.ts- Test API failure → localStorage fallback scenario
- Test manual save button functionality
- Test data consistency across page reloads
4.2.3 Visual Regression Tests
- Set up Playwright for visual testing
- Create baseline screenshots for HMI components
- Test layout rendering across different screen sizes
- Test widget palette appearance and interactions
4.3 Development Tools (Medium Priority)
4.3.1 Debug Tools
- Create HMI Debug Panel component
- Show current layout structure in tree view
- Display widget instance details
- Show storage state (API vs localStorage)
- Add manual cache clear buttons
- Add debug console commands
window.hmiDebug.dumpLayout()- Export current layoutwindow.hmiDebug.clearCache()- Clear localStoragewindow.hmiDebug.validateLayout()- Check layout integritywindow.hmiDebug.performanceStats()- Show render stats
4.3.2 Layout Validation
- Create layout validation utility
- Check for orphaned widgets
- Validate container nesting depth
- Check for duplicate widget IDs
- Validate widget configuration schemas
- Add runtime validation in development mode
- Warn about performance issues (too many re-renders)
- Detect memory leaks in widget instances
- Validate prop types and required fields
4.3.3 Widget Development Tools
- Create widget development template generator
- CLI command:
npm run create-widget <name> - Generate widget component, config schema, tests
- Auto-register in widget registry
- CLI command:
- Add widget hot reload support
- Detect widget file changes
- Re-register widgets without page reload
- Preserve widget instances during development
4.3.4 Performance Monitoring
- Add performance hooks to HMI components
- Track render times for layout operations
- Monitor memory usage of widget instances
- Detect expensive re-renders
- Create performance dashboard
- Show real-time performance metrics
- Alert on performance regressions
- Export performance reports
4.4 Immediate Action Items (This Week)
Priority 1: Critical Documentation
- Add JSDoc to
UnifiedLayoutManagerpublic methods (2 hours) - Document
LayoutContexthook usage with examples (1 hour) - Create basic troubleshooting guide (1 hour)
Priority 2: Essential Testing
- Write unit tests for
UnifiedLayoutManagercore methods (4 hours) - Create integration test for add/remove widget flow (2 hours)
- Set up test coverage reporting (1 hour)
Priority 3: Debug Tools
- Add basic debug console commands (2 hours)
- Create simple layout validation utility (2 hours)
- Add development mode warnings (1 hour)
4.5 Success Criteria
Documentation
- All public APIs have JSDoc comments
- Architecture documentation covers 100% of HMI components
- Troubleshooting guide addresses common issues
- Widget development guide with working examples
Testing
- >80% test coverage for HMI core functionality
- Integration tests for all major user flows
- Visual regression tests prevent UI breakage
- Automated testing runs on every PR
Development Tools
- Debug panel accessible in development mode
- Layout validation catches common errors
- Performance monitoring shows actionable metrics
- Widget development workflow is streamlined
Timeline: 2 weeks for Phase 4 completion
Implementation Strategy
Phase 1 Execution Plan
Week 1: Layout System Consolidation
Day 1-2: Remove layoutContainer.ts and widgetLayout.ts
- Audit usage across codebase
- Create migration utilities
- Update imports and references
- Test functionality preservation
Day 3: Standardize component interfaces
- Remove ContainerCanvas.tsx
- Update component props
- Create shared interface types
- Update documentation
Week 2: Storage and Performance
Day 1: Unify storage layer
- Remove direct localStorage access
- Test data migration
- Verify consistency
Day 2-3: Performance optimization
**React Performance Optimization:**
- Add React.memo to expensive HMI components (GenericCanvas, LayoutContainer)
- Implement useMemo for complex layout calculations and widget counts
- Use useCallback for event handlers to prevent unnecessary re-renders
- Optimize context providers to prevent cascading re-renders
**Component Profiling & Analysis:**
- Use React DevTools Profiler to identify performance bottlenecks
- Measure render times for layout operations (add/remove/move widgets)
- Profile memory usage during intensive editing sessions
- Identify components with excessive re-render frequency
**Re-render Optimization:**
- Implement proper dependency arrays in useEffect hooks
- Split large contexts into smaller, focused contexts
- Use React.memo with custom comparison functions for complex props
- Optimize widget instance updates to prevent parent re-renders
**Bundle Size Optimization:**
- Analyze bundle with webpack-bundle-analyzer
- Implement code splitting for non-critical HMI components
- Tree-shake unused utility functions and legacy code
- Lazy load widget palette and settings components
Risk Mitigation
1. Breaking Changes
- Risk: Removing legacy components may break existing features
- Mitigation: Comprehensive testing, feature flags, gradual rollout
2. Data Loss
- Risk: Storage migration could lose user layouts
- Mitigation: Backup existing data, rollback plan, validation checks
3. Performance Regression
- Risk: Changes could negatively impact performance
- Mitigation: Before/after benchmarks, performance monitoring, rollback plan
Success Metrics
Code Quality
- Reduce HMI-related files by 30%
- Eliminate duplicate interfaces and types
- Achieve 90%+ TypeScript coverage
- Zero ESLint warnings in HMI code
Performance
- 50% reduction in unnecessary re-renders
- 20% smaller bundle size
- Sub-100ms layout operations
- Zero memory leaks in HMI components
Developer Experience
- Single source of truth for layout logic
- Consistent component interfaces
- Comprehensive documentation
- Automated testing coverage >80%
Timeline Summary
| Phase | Duration | Priority | Dependencies |
|---|---|---|---|
| Phase 1: Architecture | 1 week | High | None |
| Phase 2: Organization | 3-4 days | Medium | Phase 1 |
| Phase 3: Performance | 2-3 days | Medium | Phase 1 |
| Phase 4: Developer UX | 1 week | Low | Phase 1-3 |
Total Estimated Time: 2.5-3 weeks
Files to be Removed/Consolidated
Files to Remove
src/lib/layoutContainer.ts(duplicate of unifiedLayoutManager.ts)src/lib/widgetLayout.ts(legacy absolute positioning)src/components/hmi/ContainerCanvas.tsx(replaced by GenericCanvas.tsx)
Files to Refactor
src/components/hmi/GenericCanvas.tsx(optimize and clean up)src/components/hmi/LayoutContainer.tsx(simplify interface)src/contexts/LayoutContext.tsx(add proper error handling)src/lib/unifiedLayoutManager.ts(remove legacy compatibility methods)
Files to Create
src/lib/hmi/types/index.ts(shared type definitions)src/lib/hmi/layout/index.ts(consolidated layout utilities)src/lib/hmi/storage/index.ts(storage service exports)
Conclusion
This cleanup plan will modernize the HMI editing system, eliminate technical debt, and create a maintainable foundation for future development. The phased approach ensures minimal disruption while delivering immediate benefits.
The key success factors are:
- Thorough testing at each phase
- Gradual migration to avoid breaking changes
- Clear documentation for developers
- Performance monitoring throughout the process
After completion, the HMI system will have:
- Single source of truth for layout management
- Consistent and predictable APIs
- Optimized performance characteristics
- Comprehensive documentation and testing