diff --git a/GiftedDialog-Decomposition-Plan.md b/GiftedDialog-Decomposition-Plan.md new file mode 100644 index 00000000..367aee7f --- /dev/null +++ b/GiftedDialog-Decomposition-Plan.md @@ -0,0 +1,274 @@ +# GiftedDialog Component Decomposition Plan + +## Overview + +This document outlines a comprehensive plan to refactor the GiftedDialog component by breaking it into smaller, more manageable sub-components. This approach will improve maintainability, testability, and reusability while preparing the codebase for future Pinia integration. + +## Current State Analysis + +The GiftedDialog component (1060 lines) is a complex Vue component that handles: + +- **Two-step wizard UI**: Entity selection → Gift details +- **Multiple entity types**: Person/Project as giver/recipient +- **Complex conditional rendering**: Based on context and entity types +- **Form validation and submission**: Gift recording with API integration +- **State management**: UI flow, entity selection, form data + +### Key Challenges + +1. **Large single file**: Difficult to navigate and maintain +2. **Mixed concerns**: UI logic, business logic, and API calls in one place +3. **Complex state**: Multiple interconnected reactive properties +4. **Testing difficulty**: Hard to test individual features in isolation +5. **Reusability**: Components like entity grids could be reused elsewhere + +## Decomposition Strategy + +### Phase 1: Extract Display Components (✅ COMPLETED) + +These components handle pure presentation with minimal business logic: + +#### 1. PersonCard.vue ✅ +- **Purpose**: Display individual person entities with selection capability +- **Features**: + - Person avatar using EntityIcon + - Selection states (selectable, conflicted, disabled) + - Time icon overlay for contacts + - Click event handling +- **Props**: `person`, `selectable`, `conflicted`, `showTimeIcon` +- **Emits**: `person-selected` + +#### 2. ProjectCard.vue ✅ +- **Purpose**: Display individual project entities with selection capability +- **Features**: + - Project icon using ProjectIcon + - Project name and issuer information + - Click event handling +- **Props**: `project`, `activeDid`, `allMyDids`, `allContacts` +- **Emits**: `project-selected` + +#### 3. EntitySummaryButton.vue ✅ +- **Purpose**: Display selected entity with edit capability in step 2 +- **Features**: + - Entity avatar (person or project) + - Entity name and role label + - Editable vs locked states + - Edit button functionality +- **Props**: `entity`, `entityType`, `label`, `editable` +- **Emits**: `edit-requested` + +#### 4. AmountInput.vue ✅ +- **Purpose**: Specialized numeric input with increment/decrement controls +- **Features**: + - Increment/decrement buttons with validation + - Configurable min/max values and step size + - Input validation and formatting + - v-model compatibility +- **Props**: `value`, `min`, `max`, `step`, `inputId` +- **Emits**: `update:value` + +### Phase 2: Extract Layout Components (NEXT) + +These components handle layout and entity organization: + +#### 5. EntityGrid.vue (PLANNED) +- **Purpose**: Reusable grid for displaying people or projects +- **Features**: + - Responsive grid layout + - Entity type switching (people/projects) + - "Show All" navigation + - Empty state handling +- **Props**: `entities`, `entityType`, `gridCols`, `maxItems` +- **Emits**: `entity-selected`, `show-all-clicked` + +#### 6. SpecialEntityCard.vue (PLANNED) +- **Purpose**: Handle special entities like "You" and "Unnamed" +- **Features**: + - Special icon display (hand, question mark) + - Conflict state handling + - Click event handling +- **Props**: `entityType`, `label`, `icon`, `conflicted` +- **Emits**: `entity-selected` + +### Phase 3: Extract Step Components (FUTURE) + +These components handle major UI sections: + +#### 7. EntitySelectionStep.vue (PLANNED) +- **Purpose**: Complete step 1 entity selection interface +- **Features**: + - Dynamic step type handling (giver/recipient) + - Entity type switching (people/projects) + - Conflict detection integration + - Cancel functionality +- **Props**: `stepType`, `entityType`, `entities`, `conflicts`, `context` +- **Emits**: `entity-selected`, `cancel` + +#### 8. GiftDetailsStep.vue (PLANNED) +- **Purpose**: Complete step 2 gift details form +- **Features**: + - Entity summary display + - Gift description input + - Amount input with controls + - Form validation + - Submit functionality +- **Props**: `giver`, `receiver`, `context`, `initialValues` +- **Emits**: `submit`, `back`, `entity-edit-requested` + +### Phase 4: Refactor Main Component (FINAL) + +#### 9. GiftedDialog.vue (PLANNED REFACTOR) +- **Purpose**: Orchestrate sub-components and manage overall state +- **Responsibilities**: + - Step navigation logic + - Entity conflict detection + - API integration for gift recording + - Success/error handling + - Dialog visibility management + +## Implementation Progress + +### ✅ Completed Components + +1. **PersonCard.vue** - Individual person display with selection +2. **ProjectCard.vue** - Individual project display with selection +3. **EntitySummaryButton.vue** - Selected entity display with edit capability +4. **AmountInput.vue** - Numeric input with increment/decrement controls + +### 🔄 Next Steps + +1. **Create EntityGrid.vue** - Unified grid layout for entities +2. **Create SpecialEntityCard.vue** - Handle "You" and "Unnamed" entities +3. **Update GiftedDialog.vue** - Integrate new components incrementally +4. **Test integration** - Ensure functionality remains intact + +### 📋 Future Phases + +1. **Extract EntitySelectionStep.vue** - Complete step 1 logic +2. **Extract GiftDetailsStep.vue** - Complete step 2 logic +3. **Refactor main component** - Minimal orchestration logic +4. **Add comprehensive tests** - Unit tests for each component +5. **Prepare for Pinia** - State management migration + +## Benefits of This Approach + +### 1. Incremental Refactoring +- Each phase can be implemented and tested independently +- Reduces risk of breaking existing functionality +- Allows for gradual improvement over time + +### 2. Improved Maintainability +- Smaller, focused components are easier to understand +- Clear separation of concerns +- Easier to locate and fix bugs + +### 3. Enhanced Testability +- Individual components can be unit tested in isolation +- Easier to mock dependencies +- Better test coverage possible + +### 4. Better Reusability +- Components like EntityGrid can be used in other views +- PersonCard and ProjectCard can be used throughout the app +- AmountInput can be reused for other numeric inputs + +### 5. Pinia Preparation +- Smaller components make state management migration easier +- Clear data flow patterns emerge +- Easier to identify what state should be global vs local + +## Integration Examples + +### Using PersonCard in EntityGrid + +```vue + +``` + +### Using AmountInput in GiftDetailsStep + +```vue + +``` + +### Using EntitySummaryButton in GiftDetailsStep + +```vue + +``` + +## Migration Strategy + +### Backward Compatibility +- Maintain existing API and prop interfaces +- Ensure all existing functionality works unchanged +- Preserve all event emissions and callbacks + +### Testing Strategy +- Create unit tests for each new component +- Maintain existing integration tests +- Add visual regression tests for UI components + +### Performance Considerations +- Monitor bundle size impact +- Ensure no performance regression +- Optimize component loading if needed + +## Security Considerations + +### Input Validation +- AmountInput includes proper numeric validation +- All user inputs are validated before processing +- XSS prevention through proper Vue templating + +### Data Handling +- No sensitive data stored in component state +- Proper prop validation and type checking +- Secure API communication maintained + +## Conclusion + +This decomposition plan provides a structured approach to refactoring the GiftedDialog component while maintaining functionality and preparing for future enhancements. The incremental approach reduces risk and allows for continuous improvement of the codebase. + +The completed Phase 1 components (PersonCard, ProjectCard, EntitySummaryButton, AmountInput) provide a solid foundation for the remaining phases and demonstrate the benefits of component decomposition in terms of maintainability, testability, and reusability. + +--- + +**Author**: Matthew Raymer +**Last Updated**: 2025-01-28 +**Status**: Phase 1 Complete, Phase 2 In Progress \ No newline at end of file diff --git a/src/components/AmountInput.vue b/src/components/AmountInput.vue new file mode 100644 index 00000000..a9ffc784 --- /dev/null +++ b/src/components/AmountInput.vue @@ -0,0 +1,174 @@ +/** + * AmountInput.vue - Specialized amount input with increment/decrement controls + * + * Extracted from GiftedDialog.vue to handle numeric amount input + * with increment/decrement buttons and validation. + * + * @author Matthew Raymer + */ + + + + + \ No newline at end of file diff --git a/src/components/EntitySummaryButton.vue b/src/components/EntitySummaryButton.vue new file mode 100644 index 00000000..d7a8ee8e --- /dev/null +++ b/src/components/EntitySummaryButton.vue @@ -0,0 +1,143 @@ +/** + * EntitySummaryButton.vue - Displays selected entity with edit capability + * + * Extracted from GiftedDialog.vue to handle entity summary display + * in the gift details step with edit functionality. + * + * @author Matthew Raymer + */ + + + + + \ No newline at end of file diff --git a/src/components/PersonCard.vue b/src/components/PersonCard.vue new file mode 100644 index 00000000..d0d25c50 --- /dev/null +++ b/src/components/PersonCard.vue @@ -0,0 +1,119 @@ +/** + * PersonCard.vue - Individual person display component + * + * Extracted from GiftedDialog.vue to handle person entity display + * with selection states and conflict detection. + * + * @author Matthew Raymer + */ + + + + + \ No newline at end of file diff --git a/src/components/ProjectCard.vue b/src/components/ProjectCard.vue new file mode 100644 index 00000000..cef10d3a --- /dev/null +++ b/src/components/ProjectCard.vue @@ -0,0 +1,95 @@ +/** + * ProjectCard.vue - Individual project display component + * + * Extracted from GiftedDialog.vue to handle project entity display + * with selection states and issuer information. + * + * @author Matthew Raymer + */ + + + + + \ No newline at end of file