Files

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 system
    • layoutContainer.ts - Duplicate container system with similar interfaces
    • widgetLayout.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, examples
    • LayoutContainer.tsx - Document container behavior, nesting rules
    • WidgetPalette.tsx - Document widget registration, custom widgets
    • WidgetSettingsManager.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 UnifiedLayoutManager public methods with examples
  • Document LayoutContext hook 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
  • 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 layout
    • window.hmiDebug.clearCache() - Clear localStorage
    • window.hmiDebug.validateLayout() - Check layout integrity
    • window.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
  • 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 UnifiedLayoutManager public methods (2 hours)
  • Document LayoutContext hook usage with examples (1 hour)
  • Create basic troubleshooting guide (1 hour)

Priority 2: Essential Testing

  • Write unit tests for UnifiedLayoutManager core 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:

  1. Thorough testing at each phase
  2. Gradual migration to avoid breaking changes
  3. Clear documentation for developers
  4. 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