EPANET Forms Dropdown Implementation Plan
Overview
This document outlines the planned approach for implementing dropdown selectors in the EPANET forms system. The implementation leverages the existing form architecture while enhancing user experience for fields with constrained, predefined values.
Current Implementation Analysis
Form Architecture
- Schema-driven forms using
constants_schemas.jsx - Dynamic form generation via
FormGenerator.jsxandFormField.jsx - Multi-form support with separate states for asset + EPANET parameters
- Field types: Currently supports
text,number, andselect(already implemented!)
Key Finding: FormField Already Supports Dropdowns
The FormField.jsx component already has complete dropdown support:
- Lines 53-68 show a complete
selectcase - Uses MUI
SelectandMenuItemcomponents - Supports
optionsarray withvalueandlabelproperties - Includes proper accessibility features
Fields Requiring Dropdown Selectors
Category A: Enum Fields (Immediate Implementation)
Based on backend model analysis and EPANET specifications, the following fields should be converted to dropdowns:
1. Tank Mixing Model (TankMixing form)
- Current:
type: 'number'with validationmin: 0, max: 2 - Backend: Uses
EN_MixingModelenum with values:EN_MIX1(0) - Complete mixEN_MIX2(1) - Two-compartment modelEN_FIFO(2) - First-in-first-outEN_LIFO(3) - Last-in-first-out
2. Source Type (Source form)
- Current:
type: 'text' - Backend: Valid types are
CONCEN,MASS,FLOWPACED,SETPOINT
3. Valve Type (Valve form)
- Current:
type: 'text' - Backend: Uses
ValveTypeenum with values:PRV(0) - Pressure Reducing ValvePSV(1) - Pressure Sustaining ValveFCV(2) - Flow Control ValveTCV(3) - Throttle Control ValvePBV(4) - Pressure Breaker ValveGPV(5) - General Purpose Valve
4. Status Values (Status form)
- Current:
type: 'text' - Backend: Standard values are
OPEN,CLOSED
Category B: Foreign Key Relationships (Requires Validation)
The following fields reference other entities and should be converted to dropdowns, but require validation of relationships:
1. Pattern References
Fields that reference Pattern table:
- Junction Pattern (
apiField: 'pattern') - Number input - Demand Pattern ID (
apiField: 'patternId',epanetField: 'demand') - Text input - Reservoir Pattern (
apiField: 'pattern') - Number input - Source Pattern (
apiField: 'patternId',epanetField: 'source') - Text input - Pump Pattern (
apiField: 'Pattern') - Number input - Energy Pattern (
apiField: 'EPattern') - Number input
Backend Model: Pattern class with Id (string) as primary key
Implementation: Dropdown populated from existing patterns in database
2. Curve References
Fields that reference Curve table:
- Volume Curve (
apiField: 'volCurve') - Number input - Head Curve (
apiField: 'HCurve') - Number input - Energy Curve (
apiField: 'ECurve') - Number input
Backend Model: Curve class with Id (int) as primary key and Name (string)
Implementation: Dropdown populated from existing curves in database
3. Potential Additional References
Fields that may reference other entities (require investigation):
- Category (
apiField: 'category',epanetField: 'demand') - Text input- May reference a predefined list of demand categories
- Pattern ID fields with different casing suggest different data types
- Some are
numbertype (suggesting integer IDs) - Some are
texttype (suggesting string IDs)
- Some are
Implementation Plan
Phase 1: Enum Fields (Immediate Implementation)
Update constants_schemas.jsx to convert specific fields to dropdowns:
1. Mixing Model (TankMixing form)
{
name: 'Mixing Model',
type: 'select',
required: false,
options: [
{ value: 0, label: 'Complete Mix (MIX1)' },
{ value: 1, label: 'Two-Compartment (MIX2)' },
{ value: 2, label: 'FIFO - First In, First Out' },
{ value: 3, label: 'LIFO - Last In, First Out' }
],
description: 'Tank mixing model (0=Mixed, 1=2-Comp, 2=FIFO, 3=LIFO)',
apiField: 'mixingModel',
epanetField: 'tankMixing'
}
2. Source Type (Source form)
{
name: 'Source Type',
type: 'select',
required: false,
options: [
{ value: 'CONCEN', label: 'CONCEN - Concentration Source' },
{ value: 'MASS', label: 'MASS - Mass Booster Source' },
{ value: 'FLOWPACED', label: 'FLOWPACED - Flow-Paced Source' },
{ value: 'SETPOINT', label: 'SETPOINT - Setpoint Source' }
],
description: 'Type of water source',
apiField: 'sourceType',
epanetField: 'source'
}
3. Valve Type (Valve form)
{
name: 'Valve Type',
type: 'select',
required: true,
options: [
{ value: 'PRV', label: 'PRV - Pressure Reducing Valve' },
{ value: 'PSV', label: 'PSV - Pressure Sustaining Valve' },
{ value: 'FCV', label: 'FCV - Flow Control Valve' },
{ value: 'TCV', label: 'TCV - Throttle Control Valve' },
{ value: 'PBV', label: 'PBV - Pressure Breaker Valve' },
{ value: 'GPV', label: 'GPV - General Purpose Valve' }
],
description: 'Valve type (e.g., PRV - Pressure Reducing Valve)',
apiField: 'ValveType'
}
4. Status Values (Status form)
{
name: 'Status Value',
type: 'select',
required: false,
options: [
{ value: 'OPEN', label: 'OPEN' },
{ value: 'CLOSED', label: 'CLOSED' }
],
description: 'Status value for the link (e.g., OPEN, CLOSED)',
apiField: 'statusValue',
epanetField: 'status'
}
Phase 2: Foreign Key Relationships (Requires Investigation)
2.1 Pattern References
Implementation Strategy:
{
name: 'Pattern',
type: 'select',
required: false,
options: [], // Populated from API
apiEndpoint: '/api/patterns', // API endpoint to fetch patterns
description: 'Pattern ID',
apiField: 'pattern'
}
Required API Endpoints:
GET /api/patterns- Fetch all available patterns- Response format:
[{id: "PATTERN1", description: "Pattern 1"}, ...]
2.2 Curve References
Implementation Strategy:
{
name: 'Head Curve',
type: 'select',
required: false,
options: [], // Populated from API
apiEndpoint: '/api/curves', // API endpoint to fetch curves
description: 'Head curve ID',
apiField: 'HCurve'
}
Required API Endpoints:
GET /api/curves- Fetch all available curves- Response format:
[{id: 1, name: "Curve 1"}, ...]
2.3 Category References
Implementation Strategy:
{
name: 'Category',
type: 'select',
required: false,
options: [
{ value: 'Domestic', label: 'Domestic' },
{ value: 'Industrial', label: 'Industrial' },
{ value: 'School', label: 'School' },
{ value: 'Fire', label: 'Fire' }
],
description: 'Demand category classification',
apiField: 'category',
epanetField: 'demand'
}
Phase 3: FormField Enhancement (Already Complete!)
The FormField.jsx component already supports dropdowns perfectly:
- Complete
selectcase implementation (lines 53-68) - MUI
SelectandMenuItemcomponents - Proper accessibility support
- Error handling integration
- No changes needed
Phase 4: API Integration for Foreign Keys
4.1 Dynamic Option Loading
Enhancement to FormField.jsx:
// Add support for dynamic option loading
const [options, setOptions] = useState(field.options || []);
useEffect(() => {
if (field.apiEndpoint && !field.options) {
// Fetch options from API
fetchOptions(field.apiEndpoint).then(setOptions);
}
}, [field.apiEndpoint, field.options]);
4.2 Caching Strategy
- Cache API responses to avoid repeated requests
- Implement cache invalidation for data consistency
- Fallback to hardcoded options if API fails
Phase 5: Testing Strategy
Unit Testing
- Verify dropdown rendering works correctly
- Test option selection and value handling
- Validate form state updates
- Test API integration for foreign keys
Integration Testing
- Test form submission with dropdown values
- Verify API integration with enum values
- Test multi-tab editing with dropdown fields
- Test foreign key validation
User Experience Testing
- Ensure dropdowns are intuitive and accessible
- Verify proper labeling and descriptions
- Test keyboard navigation
- Test loading states for dynamic options
Implementation Benefits
User Experience
- Clear Choices: Constrained options prevent invalid inputs
- Intuitive Interface: Dropdowns are familiar UI patterns
- Accessibility: MUI Select components provide proper ARIA support
- Data Integrity: Foreign key validation prevents invalid references
Data Integrity
- Enum Validation: Ensures only valid values are submitted
- Type Safety: Prevents typos and invalid enum values
- Referential Integrity: Foreign key validation ensures valid references
- Consistency: Standardized enum values across the application
Maintainability
- Centralized Definitions: Enum options defined in schema
- Easy Updates: Changes to enum options only require schema updates
- API Integration: Dynamic loading of foreign key options
- Documentation: Self-documenting enum values with descriptions
Performance
- Caching: API responses cached for performance
- Lazy Loading: Options loaded only when needed
- Minimal Bundle Impact: Leverages existing MUI components
Technical Considerations
Backend Model Alignment
- Enum values match backend model definitions exactly
- Proper type conversion between frontend and backend
- Validation rules align with backend constraints
- Foreign key relationships properly validated
Form State Management
- Dropdown values integrate with existing form state
- Multi-tab editing preserves dropdown selections
- Error handling works with dropdown validation
- Dynamic option loading doesn't interfere with form state
Accessibility
- Proper ARIA labels and roles
- Keyboard navigation support
- Screen reader compatibility
- Focus management
- Loading state announcements
API Integration
- Error handling for failed API requests
- Loading states for dynamic options
- Caching strategy for performance
- Fallback options for offline scenarios
Files to Modify
Primary Files
src/constants_schemas.jsx- Update field definitions for enum fields
- Add
type: 'select'andoptionsproperties - Convert text/number fields to dropdowns
- Add API endpoint references for foreign keys
Secondary Files
src/components/forms/FormField.jsx- May need enhancement for dynamic loadingsrc/components/forms/FormGenerator.jsx- Works with existing architecturesrc/components/AssetEditDialog.jsx- Form state management already handles all field types
New Files (Future)
src/utils/fetchPatterns.jsx- API utility for fetching patternssrc/utils/fetchCurves.jsx- API utility for fetching curvessrc/hooks/useOptions.jsx- Custom hook for dynamic option loading
Success Criteria
Functional Requirements
- ✅ Dropdown fields render correctly
- ✅ Enum values are validated
- ✅ Form submission works with dropdown values
- ✅ Multi-tab editing preserves dropdown selections
- ✅ API integration handles enum values correctly
- ✅ Foreign key validation works properly
- ✅ Dynamic option loading functions correctly
Technical Requirements
- ✅ Schema-driven dropdown configuration
- ✅ Consistent with existing form architecture
- ✅ Proper error handling for invalid enum values
- ✅ Performance optimized for large option lists
- ✅ API integration for foreign keys
- ✅ Caching strategy implemented
User Experience Requirements
- ✅ Intuitive dropdown interaction
- ✅ Clear option labeling
- ✅ Consistent styling with existing forms
- ✅ Helpful validation messages
- ✅ Loading states for dynamic options
- ✅ Accessible interface
Validation Required
Foreign Key Relationships to Verify
- Pattern References: Validate that all pattern fields reference the same Pattern table
- Curve References: Confirm curve field relationships and data types
- Category References: Determine if categories are predefined or free-form
- Data Type Consistency: Verify whether IDs are strings or integers
- API Endpoints: Confirm available endpoints for fetching reference data
Investigation Tasks
- Backend API: Check available endpoints for patterns and curves
- Data Types: Verify whether pattern/curve IDs are strings or integers
- Relationships: Confirm foreign key relationships in database
- Validation Rules: Understand validation requirements for foreign keys
- Performance: Assess impact of dynamic option loading
Next Steps
- Phase 1: Implement enum field dropdowns (immediate)
- Investigation: Validate foreign key relationships and API endpoints
- Phase 2: Implement foreign key dropdowns after validation
- Testing: Comprehensive testing of all dropdown implementations
- Documentation: Update form documentation with dropdown examples
Conclusion
The dropdown implementation leverages the existing form architecture while providing significant improvements to user experience and data integrity. The implementation is straightforward for enum fields since the infrastructure already exists, requiring only schema updates.
Foreign key relationships require careful investigation to ensure proper implementation and validation. The approach maintains consistency with the existing codebase while providing a much better user experience for fields that have constrained, predefined values.
Status: Ready for Phase 1 Implementation, Phase 2 Requires Investigation Last Updated: Current session Next Milestone: Enum Field Implementation and Foreign Key Investigation