You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.8 KiB
6.8 KiB
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
- User opens dialog → GiftedDialog renders EntitySelectionStep
- EntitySelectionStep renders EntityGrid with entities and configuration
- EntityGrid renders PersonCard/ProjectCard/SpecialEntityCard components
- User clicks entity → Card emits to Grid → Grid emits to Step → Step emits to Dialog
- GiftedDialog updates state and advances to step 2
Step 2: Gift Details
- GiftedDialog renders GiftDetailsStep with selected entities
- GiftDetailsStep renders EntitySummaryButton and AmountInput components
- User fills form and clicks submit → Step emits to Dialog
- GiftedDialog processes submission via API and handles success/error
Key Props and Configuration
GiftedDialog Props
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
// 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
<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
// 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
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
<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