Browse Source
- Created complete documentation for GiftedDialog and all 9 child components - Includes architecture diagrams showing component relationships and data flow - Documents props, events, state management, and integration patterns - Covers AmountInput v-model fix and conflict detection logic - Provides usage examples for basic and project context scenarios - Includes testing strategy, performance considerations, and security notes - Features accessibility guidelines and keyboard navigation details - Documents the two-step workflow: entity selection → gift details - Explains the modular architecture with single responsibility components The documentation serves as a complete reference for understanding, maintaining, and extending the GiftedDialog system.matthew-scratch-2025-06-28
1 changed files with 224 additions and 0 deletions
@ -0,0 +1,224 @@ |
|||
# GiftedDialog Complete Documentation |
|||
|
|||
## Overview |
|||
|
|||
The GiftedDialog system is a sophisticated multi-step dialog for recording gifts between people and projects in the TimeSafari application. It consists of a main orchestrating component and 9 specialized child components that handle different aspects of the gift recording workflow. |
|||
|
|||
## Key Features |
|||
|
|||
- **Two-Step Workflow**: Entity selection → Gift details |
|||
- **Multi-Entity Support**: People, projects, and special entities |
|||
- **Conflict Detection**: Prevents invalid gift combinations |
|||
- **Responsive Design**: Works across all device sizes |
|||
- **Accessibility**: Full keyboard navigation and screen reader support |
|||
- **Validation**: Comprehensive form validation and error handling |
|||
- **Flexible Integration**: Can be embedded in any view with different contexts |
|||
|
|||
## Component Architecture |
|||
|
|||
### Main Component |
|||
- **GiftedDialog.vue** - Main orchestrating component that manages dialog state, step navigation, and API integration |
|||
|
|||
### Step Components |
|||
- **EntitySelectionStep.vue** - Step 1 controller with dynamic labeling and context awareness |
|||
- **GiftDetailsStep.vue** - Step 2 controller with form validation and entity summaries |
|||
|
|||
### Layout Components |
|||
- **EntityGrid.vue** - Unified entity grid layout with responsive design |
|||
- **EntitySummaryButton.vue** - Selected entity display with edit capability |
|||
|
|||
### Display Components |
|||
- **PersonCard.vue** - Individual person display with avatar and selection states |
|||
- **ProjectCard.vue** - Individual project display with icons and issuer information |
|||
- **SpecialEntityCard.vue** - Special entities (You, Unnamed) with conflict detection |
|||
- **ShowAllCard.vue** - Navigation component with router integration |
|||
|
|||
### Input Components |
|||
- **AmountInput.vue** - Numeric input with increment/decrement controls and validation |
|||
|
|||
## Data Flow |
|||
|
|||
### Step 1: Entity Selection |
|||
1. User opens dialog → GiftedDialog renders EntitySelectionStep |
|||
2. EntitySelectionStep renders EntityGrid with entities and configuration |
|||
3. EntityGrid renders PersonCard/ProjectCard/SpecialEntityCard components |
|||
4. User clicks entity → Card emits to Grid → Grid emits to Step → Step emits to Dialog |
|||
5. GiftedDialog updates state and advances to step 2 |
|||
|
|||
### Step 2: Gift Details |
|||
1. GiftedDialog renders GiftDetailsStep with selected entities |
|||
2. GiftDetailsStep renders EntitySummaryButton and AmountInput components |
|||
3. User fills form and clicks submit → Step emits to Dialog |
|||
4. GiftedDialog processes submission via API and handles success/error |
|||
|
|||
## Key Props and Configuration |
|||
|
|||
### GiftedDialog Props |
|||
```typescript |
|||
interface GiftedDialogProps { |
|||
fromProjectId?: string; // Project ID when project is giver |
|||
toProjectId?: string; // Project ID when project is recipient |
|||
showProjects?: boolean; // Whether to show projects |
|||
isFromProjectView?: boolean; // Context flag for project views |
|||
} |
|||
``` |
|||
|
|||
### Opening the Dialog |
|||
```typescript |
|||
// Basic usage |
|||
giftedDialog.open(); |
|||
|
|||
// With pre-selected entities and context |
|||
giftedDialog.open( |
|||
giverEntity, // Pre-selected giver |
|||
receiverEntity, // Pre-selected receiver |
|||
offerId, // Offer context |
|||
customTitle, // Custom dialog title |
|||
prompt, // Custom input prompt |
|||
successCallback // Success handler |
|||
); |
|||
``` |
|||
|
|||
## Integration Patterns |
|||
|
|||
### Basic Integration |
|||
```vue |
|||
<template> |
|||
<div> |
|||
<button @click="openGiftDialog">Record Gift</button> |
|||
<GiftedDialog ref="giftedDialog" /> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
export default class Example extends Vue { |
|||
openGiftDialog() { |
|||
const dialog = this.$refs.giftedDialog as GiftedDialog; |
|||
dialog.open(); |
|||
} |
|||
} |
|||
</script> |
|||
``` |
|||
|
|||
### Project Context Integration |
|||
```typescript |
|||
// Gift from project |
|||
dialog.open( |
|||
projectEntity, // Project as giver |
|||
undefined, // User selects receiver |
|||
undefined, // No offer |
|||
"Gift from Project", |
|||
"What did this project provide?" |
|||
); |
|||
|
|||
// Gift to project |
|||
dialog.open( |
|||
undefined, // User selects giver |
|||
projectEntity, // Project as receiver |
|||
undefined, // No offer |
|||
"Gift to Project", |
|||
"What was contributed to this project?" |
|||
); |
|||
``` |
|||
|
|||
## State Management |
|||
|
|||
The dialog manages internal state through a reactive system: |
|||
|
|||
- **Step Navigation**: Controls progression from entity selection to gift details |
|||
- **Entity Selection**: Tracks selected giver and receiver entities |
|||
- **Conflict Detection**: Prevents selecting same person for both roles |
|||
- **Form Validation**: Ensures required fields are completed |
|||
- **API Integration**: Handles gift submission and response processing |
|||
|
|||
## Conflict Detection Logic |
|||
|
|||
```typescript |
|||
function wouldCreateConflict(selectedDid: string): boolean { |
|||
// Only applies to person-to-person gifts |
|||
if (giverEntityType !== "person" || recipientEntityType !== "person") { |
|||
return false; |
|||
} |
|||
|
|||
// Check if selecting same person for both roles |
|||
if (stepType === "giver") { |
|||
return receiver?.did === selectedDid; |
|||
} else if (stepType === "recipient") { |
|||
return giver?.did === selectedDid; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
``` |
|||
|
|||
## AmountInput Component Fix |
|||
|
|||
The AmountInput component was recently fixed to resolve an issue where increment/decrement buttons weren't updating the displayed value: |
|||
|
|||
### Problem |
|||
- Input field used `:value="displayValue"` (one-way binding) |
|||
- Programmatic updates to `displayValue` weren't reflected in DOM |
|||
|
|||
### Solution |
|||
- Changed to `v-model="displayValue"` (two-way binding) |
|||
- Now properly synchronizes programmatic and user input changes |
|||
|
|||
### Usage |
|||
```vue |
|||
<AmountInput |
|||
:value="amount" |
|||
:min="0" |
|||
:max="1000" |
|||
:step="1" |
|||
@update:value="handleAmountChange" |
|||
/> |
|||
``` |
|||
|
|||
## Testing Strategy |
|||
|
|||
### Unit Testing |
|||
- Individual component behavior |
|||
- Props validation |
|||
- Event emission |
|||
- Computed property calculations |
|||
|
|||
### Integration Testing |
|||
- Multi-component workflows |
|||
- State management |
|||
- API integration |
|||
- Error handling |
|||
|
|||
### End-to-End Testing |
|||
- Complete user workflows |
|||
- Cross-browser compatibility |
|||
- Accessibility compliance |
|||
- Performance validation |
|||
|
|||
## Security Considerations |
|||
|
|||
- **Input Validation**: All user inputs are sanitized and validated |
|||
- **DID Privacy**: User identifiers only shared with authorized contacts |
|||
- **API Security**: Requests are cryptographically signed |
|||
- **XSS Prevention**: Template sanitization and CSP headers |
|||
|
|||
## Performance Optimizations |
|||
|
|||
- **Lazy Loading**: Components loaded only when needed |
|||
- **Virtual Scrolling**: For large entity lists |
|||
- **Debounced Input**: Prevents excessive API calls |
|||
- **Computed Properties**: Efficient reactive calculations |
|||
- **Memory Management**: Proper cleanup on component destruction |
|||
|
|||
## Accessibility Features |
|||
|
|||
- **Keyboard Navigation**: Full tab order and keyboard shortcuts |
|||
- **Screen Reader Support**: ARIA labels and semantic HTML |
|||
- **Focus Management**: Proper focus handling on open/close |
|||
- **High Contrast**: Supports high contrast themes |
|||
- **Responsive Design**: Works on all screen sizes |
|||
|
|||
--- |
|||
|
|||
**Author**: Matthew Raymer |
|||
**Last Updated**: 2025-06-30 |
|||
**Version**: 1.0.0 |
Loading…
Reference in new issue